Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[PATCH] USB: shuttle_usbat: Fix handling of scatter-gather buffers

I've worked out what's going wrong. The scsi layer is now much
more likely to pass down scatterlists instead of plain buffers. So
you have to make sure that they're handled correctly. In one of the
changes along the way, usbat_write_block and friends stopped obeying
the srb->use_sg flag.

Anyway, with the appended patch, and the one I'm putting in the next email, it
all seems to work for the HP cd4e. Of course, someone's going to have
to test it with the flash drives as well....

This patch teaches the usbat_{read,write}_block functions to
obey the use_sg flag in the scsi-request.

Signed-off-by: Peter Chubb <peterc@gelato.unsw.edu.au>
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

authored by

Peter Chubb and committed by
Greg Kroah-Hartman
141804d4 69165c29

+30 -24
+30 -24
drivers/usb/storage/shuttle_usbat.c
··· 131 131 * Convenience function to perform a bulk read 132 132 */ 133 133 static int usbat_bulk_read(struct us_data *us, 134 - unsigned char *data, 135 - unsigned int len) 134 + unsigned char *data, 135 + unsigned int len, 136 + int use_sg) 136 137 { 137 138 if (len == 0) 138 139 return USB_STOR_XFER_GOOD; 139 140 140 141 US_DEBUGP("usbat_bulk_read: len = %d\n", len); 141 - return usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, data, len, NULL); 142 + return usb_stor_bulk_transfer_sg(us, us->recv_bulk_pipe, data, len, use_sg, NULL); 142 143 } 143 144 144 145 /* 145 146 * Convenience function to perform a bulk write 146 147 */ 147 148 static int usbat_bulk_write(struct us_data *us, 148 - unsigned char *data, 149 - unsigned int len) 149 + unsigned char *data, 150 + unsigned int len, 151 + int use_sg) 150 152 { 151 153 if (len == 0) 152 154 return USB_STOR_XFER_GOOD; 153 155 154 156 US_DEBUGP("usbat_bulk_write: len = %d\n", len); 155 - return usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe, data, len, NULL); 157 + return usb_stor_bulk_transfer_sg(us, us->send_bulk_pipe, data, len, use_sg, NULL); 156 158 } 157 159 158 160 /* ··· 319 317 */ 320 318 static int usbat_read_block(struct us_data *us, 321 319 unsigned char *content, 322 - unsigned short len) 320 + unsigned short len, 321 + int use_sg) 323 322 { 324 323 int result; 325 324 unsigned char *command = us->iobuf; ··· 341 338 if (result != USB_STOR_XFER_GOOD) 342 339 return USB_STOR_TRANSPORT_ERROR; 343 340 344 - result = usbat_bulk_read(us, content, len); 341 + result = usbat_bulk_read(us, content, len, use_sg); 345 342 return (result == USB_STOR_XFER_GOOD ? 346 343 USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); 347 344 } ··· 353 350 unsigned char access, 354 351 unsigned char *content, 355 352 unsigned short len, 356 - int minutes) 353 + int minutes, 354 + int use_sg) 357 355 { 358 356 int result; 359 357 unsigned char *command = us->iobuf; ··· 376 372 if (result != USB_STOR_XFER_GOOD) 377 373 return USB_STOR_TRANSPORT_ERROR; 378 374 379 - result = usbat_bulk_write(us, content, len); 375 + result = usbat_bulk_write(us, content, len, use_sg); 380 376 if (result != USB_STOR_XFER_GOOD) 381 377 return USB_STOR_TRANSPORT_ERROR; 382 378 ··· 469 465 data[1+(j<<1)] = data_out[j]; 470 466 } 471 467 472 - result = usbat_bulk_write(us, data, num_registers*2); 468 + result = usbat_bulk_write(us, data, num_registers*2, 0); 473 469 if (result != USB_STOR_XFER_GOOD) 474 470 return USB_STOR_TRANSPORT_ERROR; 475 471 ··· 587 583 } 588 584 589 585 /* Send the data */ 590 - result = usbat_bulk_write(us, data, num_registers*2); 586 + result = usbat_bulk_write(us, data, num_registers*2, 0); 591 587 if (result != USB_STOR_XFER_GOOD) 592 588 return USB_STOR_TRANSPORT_ERROR; 593 589 ··· 610 606 * other related details) are defined beforehand with _set_shuttle_features(). 611 607 */ 612 608 static int usbat_read_blocks(struct us_data *us, 613 - unsigned char *buffer, 614 - int len) 609 + unsigned char *buffer, 610 + int len, 611 + int use_sg) 615 612 { 616 613 int result; 617 614 unsigned char *command = us->iobuf; ··· 632 627 return USB_STOR_TRANSPORT_FAILED; 633 628 634 629 /* Read the blocks we just asked for */ 635 - result = usbat_bulk_read(us, buffer, len); 630 + result = usbat_bulk_read(us, buffer, len, use_sg); 636 631 if (result != USB_STOR_XFER_GOOD) 637 632 return USB_STOR_TRANSPORT_FAILED; 638 633 ··· 653 648 */ 654 649 static int usbat_write_blocks(struct us_data *us, 655 650 unsigned char *buffer, 656 - int len) 651 + int len, 652 + int use_sg) 657 653 { 658 654 int result; 659 655 unsigned char *command = us->iobuf; ··· 674 668 return USB_STOR_TRANSPORT_FAILED; 675 669 676 670 /* Write the data */ 677 - result = usbat_bulk_write(us, buffer, len); 671 + result = usbat_bulk_write(us, buffer, len, use_sg); 678 672 if (result != USB_STOR_XFER_GOOD) 679 673 return USB_STOR_TRANSPORT_FAILED; 680 674 ··· 953 947 msleep(100); 954 948 955 949 /* Read the device identification data */ 956 - rc = usbat_read_block(us, reply, 512); 950 + rc = usbat_read_block(us, reply, 512, 0); 957 951 if (rc != USB_STOR_TRANSPORT_GOOD) 958 952 goto leave; 959 953 ··· 1037 1031 goto leave; 1038 1032 1039 1033 /* Read the data we just requested */ 1040 - result = usbat_read_blocks(us, buffer, len); 1034 + result = usbat_read_blocks(us, buffer, len, 0); 1041 1035 if (result != USB_STOR_TRANSPORT_GOOD) 1042 1036 goto leave; 1043 1037 ··· 1131 1125 goto leave; 1132 1126 1133 1127 /* Write the data */ 1134 - result = usbat_write_blocks(us, buffer, len); 1128 + result = usbat_write_blocks(us, buffer, len, 0); 1135 1129 if (result != USB_STOR_TRANSPORT_GOOD) 1136 1130 goto leave; 1137 1131 ··· 1509 1503 * AT SPEED 4 IS UNRELIABLE!!! 1510 1504 */ 1511 1505 1512 - if ( (result = usbat_write_block(us, 1506 + if ((result = usbat_write_block(us, 1513 1507 USBAT_ATA, srb->cmnd, 12, 1514 - srb->cmnd[0]==GPCMD_BLANK ? 75 : 10)) != 1515 - USB_STOR_TRANSPORT_GOOD) { 1508 + (srb->cmnd[0]==GPCMD_BLANK ? 75 : 10), 0) != 1509 + USB_STOR_TRANSPORT_GOOD)) { 1516 1510 return result; 1517 1511 } 1518 1512 ··· 1539 1533 len = *status; 1540 1534 1541 1535 1542 - result = usbat_read_block(us, srb->request_buffer, len); 1536 + result = usbat_read_block(us, srb->request_buffer, len, srb->use_sg); 1543 1537 1544 1538 /* Debug-print the first 32 bytes of the transfer */ 1545 1539