diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2007-05-26 01:04:03 -0400 |
---|---|---|
committer | James Bottomley <jejb@mulgrave.il.steeleye.com> | 2007-05-26 17:29:59 -0400 |
commit | 824d7b570b4dec49e868c251d670941b02a1e489 (patch) | |
tree | 1590c87323c9f9235945ba03627fd1ce0b731a1f | |
parent | 9ef3e4a4527e1f65b8776287c6d4fd1fca5ba98f (diff) |
[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 <fujita.tomonori@lab.ntt.co.jp>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r-- | drivers/scsi/scsi_lib.c | 38 | ||||
-rw-r--r-- | include/scsi/scsi_cmnd.h | 20 |
2 files changed, 58 insertions, 0 deletions
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 1f5a07bf2a75..70454b4e8485 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -2290,3 +2290,41 @@ void scsi_kunmap_atomic_sg(void *virt) | |||
2290 | kunmap_atomic(virt, KM_BIO_SRC_IRQ); | 2290 | kunmap_atomic(virt, KM_BIO_SRC_IRQ); |
2291 | } | 2291 | } |
2292 | EXPORT_SYMBOL(scsi_kunmap_atomic_sg); | 2292 | EXPORT_SYMBOL(scsi_kunmap_atomic_sg); |
2293 | |||
2294 | /** | ||
2295 | * scsi_dma_map - perform DMA mapping against command's sg lists | ||
2296 | * @cmd: scsi command | ||
2297 | * | ||
2298 | * Returns the number of sg lists actually used, zero if the sg lists | ||
2299 | * is NULL, or -ENOMEM if the mapping failed. | ||
2300 | */ | ||
2301 | int scsi_dma_map(struct scsi_cmnd *cmd) | ||
2302 | { | ||
2303 | int nseg = 0; | ||
2304 | |||
2305 | if (scsi_sg_count(cmd)) { | ||
2306 | struct device *dev = cmd->device->host->shost_gendev.parent; | ||
2307 | |||
2308 | nseg = dma_map_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), | ||
2309 | cmd->sc_data_direction); | ||
2310 | if (unlikely(!nseg)) | ||
2311 | return -ENOMEM; | ||
2312 | } | ||
2313 | return nseg; | ||
2314 | } | ||
2315 | EXPORT_SYMBOL(scsi_dma_map); | ||
2316 | |||
2317 | /** | ||
2318 | * scsi_dma_unmap - unmap command's sg lists mapped by scsi_dma_map | ||
2319 | * @cmd: scsi command | ||
2320 | */ | ||
2321 | void scsi_dma_unmap(struct scsi_cmnd *cmd) | ||
2322 | { | ||
2323 | if (scsi_sg_count(cmd)) { | ||
2324 | struct device *dev = cmd->device->host->shost_gendev.parent; | ||
2325 | |||
2326 | dma_unmap_sg(dev, scsi_sglist(cmd), scsi_sg_count(cmd), | ||
2327 | cmd->sc_data_direction); | ||
2328 | } | ||
2329 | } | ||
2330 | EXPORT_SYMBOL(scsi_dma_unmap); | ||
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index a2e0c1032491..53e170586c26 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); | |||
135 | extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t); | 135 | extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t); |
136 | extern void scsi_free_sgtable(struct scatterlist *, int); | 136 | extern void scsi_free_sgtable(struct scatterlist *, int); |
137 | 137 | ||
138 | extern int scsi_dma_map(struct scsi_cmnd *cmd); | ||
139 | extern void scsi_dma_unmap(struct scsi_cmnd *cmd); | ||
140 | |||
141 | #define scsi_sg_count(cmd) ((cmd)->use_sg) | ||
142 | #define scsi_sglist(cmd) ((struct scatterlist *)(cmd)->request_buffer) | ||
143 | #define scsi_bufflen(cmd) ((cmd)->request_bufflen) | ||
144 | |||
145 | static inline void scsi_set_resid(struct scsi_cmnd *cmd, int resid) | ||
146 | { | ||
147 | cmd->resid = resid; | ||
148 | } | ||
149 | |||
150 | static inline int scsi_get_resid(struct scsi_cmnd *cmd) | ||
151 | { | ||
152 | return cmd->resid; | ||
153 | } | ||
154 | |||
155 | #define scsi_for_each_sg(cmd, sg, nseg, __i) \ | ||
156 | for (__i = 0, sg = scsi_sglist(cmd); __i < (nseg); __i++, (sg)++) | ||
157 | |||
138 | #endif /* _SCSI_SCSI_CMND_H */ | 158 | #endif /* _SCSI_SCSI_CMND_H */ |