It's more intuitive to go straight to the struct device for the
sector_size, when that's what we want, rather than using transfersize
as a replacement.
Also fix a bug in handling of GPCMD_READ_CD where we were pulling the
wrong bytes out of the packet to calculate the length. I checked this
against MMC5r04.
Signed-off-by: Matthew Wilcox <[EMAIL PROTECTED]>
---
drivers/usb/storage/shuttle_usbat.c | 46 +++++++++++++++++++---------------
1 files changed, 26 insertions(+), 20 deletions(-)
diff --git a/drivers/usb/storage/shuttle_usbat.c
b/drivers/usb/storage/shuttle_usbat.c
index 570c125..a172e98 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -49,6 +49,7 @@
#include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
#include "usb.h"
#include "transport.h"
@@ -1164,12 +1165,10 @@ static int usbat_hp8200e_handle_read10(struct us_data
*us,
unsigned char *buffer;
unsigned int len;
unsigned int sector;
+ unsigned int sector_size;
unsigned int sg_offset = 0;
struct scatterlist *sg = NULL;
- US_DEBUGP("handle_read10: transfersize %d\n",
- srb->transfersize);
-
if (scsi_bufflen(srb) < 0x10000) {
result = usbat_hp8200e_rw_block_test(us, USBAT_ATA,
@@ -1184,25 +1183,32 @@ static int usbat_hp8200e_handle_read10(struct us_data
*us,
}
/*
- * Since we're requesting more data than we can handle in
- * a single read command (max is 64k-1), we will perform
- * multiple reads, but each read must be in multiples of
- * a sector. Luckily the sector size is in srb->transfersize
- * (see linux/drivers/scsi/sr.c).
+ * Since we're requesting more data than we can handle in a
+ * single read command (max is 64k-1), we will perform multiple
+ * reads, but each read must be in multiples of a sector.
+ *
+ * For ordinary READ_10 commands, we're reading at the current
+ * sector size, so use the device's sector size. If the command
+ * is a READ_CD, we might be reading different sector sizes.
+ * Fortunately, we can calculate the sector size from the
+ * contents of the command.
*/
if (data[7+0] == GPCMD_READ_CD) {
- len = short_pack(data[7+9], data[7+8]);
- len <<= 16;
- len |= data[7+7];
+ len = data[7+8] | ((u32)data[7+7] << 8) |
+ ((u32)data[7+6] << 16);
US_DEBUGP("handle_read10: GPCMD_READ_CD: len %d\n", len);
- srb->transfersize = scsi_bufflen(srb)/len;
+ sector_size = scsi_bufflen(srb) / len;
+ } else {
+ sector_size = srb->device->sector_size;
}
- if (!srb->transfersize) {
- srb->transfersize = 2048; /* A guess */
- US_DEBUGP("handle_read10: transfersize 0, forcing %d\n",
- srb->transfersize);
+ US_DEBUGP("handle_read10: sector_size %d\n", sector_size);
+
+ if (!sector_size) {
+ sector_size = 2048; /* A guess */
+ US_DEBUGP("handle_read10: sector_size 0, forcing %d\n",
+ sector_size);
}
/*
@@ -1211,7 +1217,7 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
* bounce buffer and the actual transfer buffer.
*/
- len = (65535/srb->transfersize) * srb->transfersize;
+ len = (65535/sector_size) * sector_size;
US_DEBUGP("Max read is %d bytes\n", len);
len = min(len, scsi_bufflen(srb));
buffer = kmalloc(len, GFP_NOIO);
@@ -1238,8 +1244,8 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
data[7+5] = LSB_of(sector&0xFFFF);
if (data[7+0] == GPCMD_READ_CD)
data[7+6] = 0;
- data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */
- data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */
+ data[7+7] = MSB_of(len / sector_size); /* SCSI command */
+ data[7+8] = LSB_of(len / sector_size); /* num sectors */
result = usbat_hp8200e_rw_block_test(us, USBAT_ATA,
registers, data, 19,
@@ -1259,7 +1265,7 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
/* Update the amount transferred and the sector number */
transferred += len;
- sector += len / srb->transfersize;
+ sector += len / sector_size;
} /* while transferred != scsi_bufflen(srb) */
--
1.4.4.2
-
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html