aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage/protocol.c
diff options
context:
space:
mode:
authorJens Axboe <jens.axboe@oracle.com>2007-05-11 06:33:09 -0400
committerJens Axboe <jens.axboe@oracle.com>2007-10-16 05:20:59 -0400
commit1f6f31a03e3aed0854a6aa3ab763c3d3b2ff42ff (patch)
treebdb94c08e0bce7c17f686aabc274a7554718407b /drivers/usb/storage/protocol.c
parent53d412fce05e73dd0b25b0ebfa83c7ee94f16451 (diff)
USB storage: sg chaining support
[PATCH] USB storage: sg chaining support Modify usb_stor_access_xfer_buf() to take a pointer to an sg entry pointer, so we can keep track of that instead of passing around an integer index (which we can't use when dealing with multiple scatterlist arrays). Signed-off-by: Jens Axboe <jens.axboe@oracle.com>
Diffstat (limited to 'drivers/usb/storage/protocol.c')
-rw-r--r--drivers/usb/storage/protocol.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 9ad30428d2dd..cc8f7c52c729 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -157,7 +157,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
157 * pick up from where this one left off. */ 157 * pick up from where this one left off. */
158 158
159unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, 159unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
160 unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, 160 unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
161 unsigned int *offset, enum xfer_buf_dir dir) 161 unsigned int *offset, enum xfer_buf_dir dir)
162{ 162{
163 unsigned int cnt; 163 unsigned int cnt;
@@ -184,16 +184,17 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
184 * located in high memory -- then kmap() will map it to a temporary 184 * located in high memory -- then kmap() will map it to a temporary
185 * position in the kernel's virtual address space. */ 185 * position in the kernel's virtual address space. */
186 } else { 186 } else {
187 struct scatterlist *sg = 187 struct scatterlist *sg = *sgptr;
188 (struct scatterlist *) srb->request_buffer 188
189 + *index; 189 if (!sg)
190 sg = (struct scatterlist *) srb->request_buffer;
190 191
191 /* This loop handles a single s-g list entry, which may 192 /* This loop handles a single s-g list entry, which may
192 * include multiple pages. Find the initial page structure 193 * include multiple pages. Find the initial page structure
193 * and the starting offset within the page, and update 194 * and the starting offset within the page, and update
194 * the *offset and *index values for the next loop. */ 195 * the *offset and *index values for the next loop. */
195 cnt = 0; 196 cnt = 0;
196 while (cnt < buflen && *index < srb->use_sg) { 197 while (cnt < buflen) {
197 struct page *page = sg->page + 198 struct page *page = sg->page +
198 ((sg->offset + *offset) >> PAGE_SHIFT); 199 ((sg->offset + *offset) >> PAGE_SHIFT);
199 unsigned int poff = 200 unsigned int poff =
@@ -209,8 +210,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
209 210
210 /* Transfer continues to next s-g entry */ 211 /* Transfer continues to next s-g entry */
211 *offset = 0; 212 *offset = 0;
212 ++*index; 213 sg = sg_next(sg);
213 ++sg;
214 } 214 }
215 215
216 /* Transfer the data for all the pages in this 216 /* Transfer the data for all the pages in this
@@ -234,6 +234,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
234 sglen -= plen; 234 sglen -= plen;
235 } 235 }
236 } 236 }
237 *sgptr = sg;
237 } 238 }
238 239
239 /* Return the amount actually transferred */ 240 /* Return the amount actually transferred */
@@ -245,9 +246,10 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
245void usb_stor_set_xfer_buf(unsigned char *buffer, 246void usb_stor_set_xfer_buf(unsigned char *buffer,
246 unsigned int buflen, struct scsi_cmnd *srb) 247 unsigned int buflen, struct scsi_cmnd *srb)
247{ 248{
248 unsigned int index = 0, offset = 0; 249 unsigned int offset = 0;
250 struct scatterlist *sg = NULL;
249 251
250 usb_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, 252 usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
251 TO_XFER_BUF); 253 TO_XFER_BUF);
252 if (buflen < srb->request_bufflen) 254 if (buflen < srb->request_bufflen)
253 srb->resid = srb->request_bufflen - buflen; 255 srb->resid = srb->request_bufflen - buflen;