[SCSI] usb: protocol - convert to accessors and !use_sg code path removal
- Use scsi data accessors and remove of !use_sg code path Signed-off-by: Boaz Harrosh <bharrosh@panasas.com> Acked-by: Matthew Dharm <mdharm-scsi@one-eyed-alien.net> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
This commit is contained in:
committed by
James Bottomley
parent
caa1e8c321
commit
dd829d2302
@@ -149,11 +149,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
|
|||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
/* Copy a buffer of length buflen to/from the srb's transfer buffer.
|
/* Copy a buffer of length buflen to/from the srb's transfer buffer.
|
||||||
* (Note: for scatter-gather transfers (srb->use_sg > 0), srb->request_buffer
|
* Update the **sgptr and *offset variables so that the next copy will
|
||||||
* points to a list of s-g entries and we ignore srb->request_bufflen.
|
|
||||||
* For non-scatter-gather transfers, srb->request_buffer points to the
|
|
||||||
* transfer buffer itself and srb->request_bufflen is the buffer's length.)
|
|
||||||
* Update the *index and *offset variables so that the next copy will
|
|
||||||
* pick up from where this one left off. */
|
* pick up from where this one left off. */
|
||||||
|
|
||||||
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
|
unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
|
||||||
@@ -162,80 +158,64 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
|
|||||||
{
|
{
|
||||||
unsigned int cnt;
|
unsigned int cnt;
|
||||||
|
|
||||||
/* If not using scatter-gather, just transfer the data directly.
|
/* We have to go through the list one entry
|
||||||
* Make certain it will fit in the available buffer space. */
|
|
||||||
if (srb->use_sg == 0) {
|
|
||||||
if (*offset >= srb->request_bufflen)
|
|
||||||
return 0;
|
|
||||||
cnt = min(buflen, srb->request_bufflen - *offset);
|
|
||||||
if (dir == TO_XFER_BUF)
|
|
||||||
memcpy((unsigned char *) srb->request_buffer + *offset,
|
|
||||||
buffer, cnt);
|
|
||||||
else
|
|
||||||
memcpy(buffer, (unsigned char *) srb->request_buffer +
|
|
||||||
*offset, cnt);
|
|
||||||
*offset += cnt;
|
|
||||||
|
|
||||||
/* Using scatter-gather. We have to go through the list one entry
|
|
||||||
* at a time. Each s-g entry contains some number of pages, and
|
* at a time. Each s-g entry contains some number of pages, and
|
||||||
* each page has to be kmap()'ed separately. If the page is already
|
* each page has to be kmap()'ed separately. If the page is already
|
||||||
* in kernel-addressable memory then kmap() will return its address.
|
* in kernel-addressable memory then kmap() will return its address.
|
||||||
* If the page is not directly accessible -- such as a user buffer
|
* If the page is not directly accessible -- such as a user buffer
|
||||||
* located in high memory -- then kmap() will map it to a temporary
|
* located in high memory -- then kmap() will map it to a temporary
|
||||||
* position in the kernel's virtual address space. */
|
* position in the kernel's virtual address space. */
|
||||||
} else {
|
struct scatterlist *sg = *sgptr;
|
||||||
struct scatterlist *sg = *sgptr;
|
|
||||||
|
|
||||||
if (!sg)
|
if (!sg)
|
||||||
sg = (struct scatterlist *) srb->request_buffer;
|
sg = scsi_sglist(srb);
|
||||||
|
|
||||||
/* This loop handles a single s-g list entry, which may
|
/* This loop handles a single s-g list entry, which may
|
||||||
* include multiple pages. Find the initial page structure
|
* include multiple pages. Find the initial page structure
|
||||||
* and the starting offset within the page, and update
|
* and the starting offset within the page, and update
|
||||||
* the *offset and *index values for the next loop. */
|
* the *offset and **sgptr values for the next loop. */
|
||||||
cnt = 0;
|
cnt = 0;
|
||||||
while (cnt < buflen) {
|
while (cnt < buflen) {
|
||||||
struct page *page = sg_page(sg) +
|
struct page *page = sg_page(sg) +
|
||||||
((sg->offset + *offset) >> PAGE_SHIFT);
|
((sg->offset + *offset) >> PAGE_SHIFT);
|
||||||
unsigned int poff =
|
unsigned int poff =
|
||||||
(sg->offset + *offset) & (PAGE_SIZE-1);
|
(sg->offset + *offset) & (PAGE_SIZE-1);
|
||||||
unsigned int sglen = sg->length - *offset;
|
unsigned int sglen = sg->length - *offset;
|
||||||
|
|
||||||
if (sglen > buflen - cnt) {
|
if (sglen > buflen - cnt) {
|
||||||
|
|
||||||
/* Transfer ends within this s-g entry */
|
/* Transfer ends within this s-g entry */
|
||||||
sglen = buflen - cnt;
|
sglen = buflen - cnt;
|
||||||
*offset += sglen;
|
*offset += sglen;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Transfer continues to next s-g entry */
|
/* Transfer continues to next s-g entry */
|
||||||
*offset = 0;
|
*offset = 0;
|
||||||
sg = sg_next(sg);
|
sg = sg_next(sg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Transfer the data for all the pages in this
|
/* Transfer the data for all the pages in this
|
||||||
* s-g entry. For each page: call kmap(), do the
|
* s-g entry. For each page: call kmap(), do the
|
||||||
* transfer, and call kunmap() immediately after. */
|
* transfer, and call kunmap() immediately after. */
|
||||||
while (sglen > 0) {
|
while (sglen > 0) {
|
||||||
unsigned int plen = min(sglen, (unsigned int)
|
unsigned int plen = min(sglen, (unsigned int)
|
||||||
PAGE_SIZE - poff);
|
PAGE_SIZE - poff);
|
||||||
unsigned char *ptr = kmap(page);
|
unsigned char *ptr = kmap(page);
|
||||||
|
|
||||||
if (dir == TO_XFER_BUF)
|
if (dir == TO_XFER_BUF)
|
||||||
memcpy(ptr + poff, buffer + cnt, plen);
|
memcpy(ptr + poff, buffer + cnt, plen);
|
||||||
else
|
else
|
||||||
memcpy(buffer + cnt, ptr + poff, plen);
|
memcpy(buffer + cnt, ptr + poff, plen);
|
||||||
kunmap(page);
|
kunmap(page);
|
||||||
|
|
||||||
/* Start at the beginning of the next page */
|
/* Start at the beginning of the next page */
|
||||||
poff = 0;
|
poff = 0;
|
||||||
++page;
|
++page;
|
||||||
cnt += plen;
|
cnt += plen;
|
||||||
sglen -= plen;
|
sglen -= plen;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*sgptr = sg;
|
|
||||||
}
|
}
|
||||||
|
*sgptr = sg;
|
||||||
|
|
||||||
/* Return the amount actually transferred */
|
/* Return the amount actually transferred */
|
||||||
return cnt;
|
return cnt;
|
||||||
@@ -251,6 +231,6 @@ void usb_stor_set_xfer_buf(unsigned char *buffer,
|
|||||||
|
|
||||||
usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
|
usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
|
||||||
TO_XFER_BUF);
|
TO_XFER_BUF);
|
||||||
if (buflen < srb->request_bufflen)
|
if (buflen < scsi_bufflen(srb))
|
||||||
srb->resid = srb->request_bufflen - buflen;
|
scsi_set_resid(srb, scsi_bufflen(srb) - buflen);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user