From: FUJITA Tomonori Date: Sat, 26 May 2007 05:04:03 +0000 (+0900) Subject: [SCSI] scsi_lib: add scatter/gather data buffer accessors X-Git-Tag: v2.6.23-rc1~1053^2~142 X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=824d7b570b4dec49e868c251d670941b02a1e489;p=linux-2.6 [SCSI] scsi_lib: add scatter/gather data buffer accessors This adds a set of accessors for the scsi data buffer. This is in preparation for chaining sg lists and bidirectional requests (and possibly, the mid-layer dma mapping). Signed-off-by: FUJITA Tomonori Signed-off-by: James Bottomley --- diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 1f5a07bf2a..70454b4e84 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2290,3 +2290,41 @@ void scsi_kunmap_atomic_sg(void *virt) kunmap_atomic(virt, KM_BIO_SRC_IRQ); } EXPORT_SYMBOL(scsi_kunmap_atomic_sg); + +/** + * scsi_dma_map - perform DMA mapping against command's sg lists + * @cmd: scsi command + * + * Returns the number of sg lists actually used, zero if the sg lists + * is NULL, or -ENOMEM if the mapping failed. + */ +int scsi_dma_map(struct scsi_cmnd *cmd) +{ + int nseg = 0; + + if (scsi_sg_count(cmd)) { + struct device *dev = cmd->device->host->shost_gendev.parent; + + nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), + cmd->sc_data_direction); + if (unlikely(!nseg)) + return -ENOMEM; + } + return nseg; +} +EXPORT_SYMBOL(scsi_dma_map); + +/** + * scsi_dma_unmap - unmap command's sg lists mapped by scsi_dma_map + * @cmd: scsi command + */ +void scsi_dma_unmap(struct scsi_cmnd *cmd) +{ + if (scsi_sg_count(cmd)) { + struct device *dev = cmd->device->host->shost_gendev.parent; + + dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), + cmd->sc_data_direction); + } +} +EXPORT_SYMBOL(scsi_dma_unmap); diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index a2e0c10324..53e170586c 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -135,4 +135,24 @@ extern void scsi_kunmap_atomic_sg(void *virt); extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t); extern void scsi_free_sgtable(struct scatterlist *, int); +extern int scsi_dma_map(struct scsi_cmnd *cmd); +extern void scsi_dma_unmap(struct scsi_cmnd *cmd); + +#define scsi_sg_count(cmd) ((cmd)->use_sg) +#define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer) +#define scsi_bufflen(cmd) ((cmd)->request_bufflen) + +static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) +{ + cmd->resid = resid; +} + +static inline int scsi_get_resid(struct scsi_cmnd *cmd) +{ + return cmd->resid; +} + +#define scsi_for_each_sg(cmd, sg, nseg, __i) \ + for (__i = 0, sg = scsi_sglist(cmd); __i < (nseg); __i++, (sg)++) + #endif /* _SCSI_SCSI_CMND_H */