diff -u --recursive --new-file -X /linux/dontdiff a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c --- a/drivers/usb/storage/protocol.c Sun Jun 9 07:26:30 2002 +++ b/drivers/usb/storage/protocol.c Sun Sep 1 00:23:37 2002 @@ -54,10 +54,27 @@ * Helper routines ***********************************************************************/ -/* Fix-up the return data from an INQUIRY command to show +static void * +find_data_location(Scsi_Cmnd *srb) { + if (srb->use_sg) { + /* + * This piece of code only works if the first page is + * big enough to hold more than 3 bytes -- which is + * _very_ likely. + */ + struct scatterlist *sg; + + sg = (struct scatterlist *) srb->request_buffer; + return (void *) page_address(sg[0].page) + sg[0].offset; + } else + return (void *) srb->request_buffer; +} + +/* + * Fix-up the return data from an INQUIRY command to show * ANSI SCSI rev 2 so we don't confuse the SCSI layers above us */ -void fix_inquiry_data(Scsi_Cmnd *srb) +static void fix_inquiry_data(Scsi_Cmnd *srb) { unsigned char *data_ptr; @@ -65,24 +82,43 @@ if (srb->cmnd[0] != INQUIRY) return; - US_DEBUGP("Fixing INQUIRY data to show SCSI rev 2\n"); + data_ptr = find_data_location(srb); - /* find the location of the data */ - if (srb->use_sg) { - /* this piece of code only works if the first page is big enough to - * hold more than 3 bytes -- which is _very_ likely - */ - struct scatterlist *sg; + if ((data_ptr[2] & 7) == 2) + return; - sg = (struct scatterlist *) srb->request_buffer; - data_ptr = (unsigned char *) page_address(sg[0].page) + sg[0].offset; - } else - data_ptr = (unsigned char *)srb->request_buffer; + US_DEBUGP("Fixing INQUIRY data to show SCSI rev 2 - was %d\n", + data_ptr[2] & 7); /* Change the SCSI revision number */ data_ptr[2] = (data_ptr[2] & ~7) | 2; } +/* + * Fix-up the return data from a READ CAPACITY command. My Feiya reader + * returns a value that is 1 too large. + */ +static void fix_read_capacity(Scsi_Cmnd *srb) +{ + unsigned char *dp; + unsigned long capacity; + + /* verify that it's a READ CAPACITY command */ + if (srb->cmnd[0] != READ_CAPACITY) + return; + + dp = find_data_location(srb); + + capacity = (dp[0]<<24) + (dp[1]<<16) + (dp[2]<<8) + (dp[3]); + US_DEBUGP("US: Fixing capacity: from %ld to %ld\n", + capacity+1, capacity); + capacity--; + dp[0] = (capacity >> 24); + dp[1] = (capacity >> 16); + dp[2] = (capacity >> 8); + dp[3] = (capacity); +} + /*********************************************************************** * Protocol routines ***********************************************************************/ @@ -346,8 +382,11 @@ if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE)) usb_stor_scsiSense10to6(srb); - /* fix the INQUIRY data if necessary */ + /* Fix the INQUIRY data if necessary */ fix_inquiry_data(srb); + + /* Fix the READ CAPACITY result if necessary */ + if (us->flags & US_FL_FIX_CAPACITY) + fix_read_capacity(srb); } } - diff -u --recursive --new-file -X /linux/dontdiff a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h --- a/drivers/usb/storage/unusual_devs.h Tue Aug 27 23:58:37 2002 +++ b/drivers/usb/storage/unusual_devs.h Sun Sep 1 00:30:30 2002 @@ -507,6 +507,13 @@ US_SC_8070, US_PR_CB, NULL, US_FL_FIX_INQUIRY ), +/* aeb */ +UNUSUAL_DEV( 0x090c, 0x1132, 0x0000, 0xffff, + "Feiya", + "5-in-1 Card Reader", + US_SC_SCSI, US_PR_BULK, NULL, + US_FL_FIX_CAPACITY ), + UNUSUAL_DEV( 0x097a, 0x0001, 0x0000, 0x0001, "Minds@Work", "Digital Wallet", diff -u --recursive --new-file -X /linux/dontdiff a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h --- a/drivers/usb/storage/usb.h Tue Aug 27 23:58:37 2002 +++ b/drivers/usb/storage/usb.h Sun Sep 1 00:18:31 2002 @@ -102,6 +102,7 @@ #define US_FL_IGNORE_SER 0x00000010 /* Ignore the serial number given */ #define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */ #define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */ +#define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */ #define US_FL_DEV_ATTACHED 0x00010000 /* is the device attached? */ #define US_FLIDX_IP_WANTED 17 /* 0x00020000 is an IRQ expected? */