In theory, this is the fix we need to make Genesys Logic devices work.
This patch started life as as343, which was created based on some
information which a user finally coaxed out of Genesys Logic.  Limited
end-user testing gives good results.

As we expected, it's a bug in their device.  This is really a workaround
for what is almost certainly a timing problem.  Apparently, the 'popular'
OSes don't push the device as hard as Linux does.

Although it is likely that this workaround is not needed for all Genesys
devices, Genesys was unable/unwilling to provide us with the explicit list
of VID/PIDs which required this -- thus we apply it to all Genesys devices.

We have lots of good reports with max_sectors set to 128 with these
devices, but the official recommendation is to set that to 64.  End-users
can experiment with higher values (for higher performance) via the runtime
sysfs interface to that parameter.

I would like to give special thanks to the users who hounded Genesys into
giving up this information, and to Alan Stern for not giving up on this
vendor long after I had.

Signed-off-by: Matthew Dharm <[EMAIL PROTECTED]>
Signed-off-by: Alan Stern <[EMAIL PROTECTED]>

Greg, please apply.

Matt

# This is a BitKeeper generated diff -Nru style patch.
#
# ChangeSet
#   2004/08/01 17:32:05-07:00 [EMAIL PROTECTED] 
#   as343
# 
# drivers/usb/storage/usb.h
#   2004/08/01 17:31:47-07:00 [EMAIL PROTECTED] +4 -0
#   as343
# 
# drivers/usb/storage/transport.c
#   2004/08/01 17:31:47-07:00 [EMAIL PROTECTED] +6 -0
#   as343
# 
# drivers/usb/storage/scsiglue.c
#   2004/08/01 17:31:47-07:00 [EMAIL PROTECTED] +8 -10
#   as343
# 
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c    Sun Aug  1 17:32:35 2004
+++ b/drivers/usb/storage/scsiglue.c    Sun Aug  1 17:32:35 2004
@@ -98,17 +98,15 @@
         * the end, scatter-gather buffers follow page boundaries. */
        blk_queue_dma_alignment(sdev->request_queue, (512 - 1));
 
-       /* Devices using Genesys Logic chips cause a lot of trouble for
-        * high-speed transfers; they die unpredictably when given more
-        * than 64 KB of data at a time.  If we detect such a device,
-        * reduce the maximum transfer size to 64 KB = 128 sectors. */
-
-#define USB_VENDOR_ID_GENESYS  0x05e3          // Needs a standard location
-
+       /* According to the technical support people at Genesys Logic,
+        * devices using their chips have problems transferring more than
+        * 32 KB at a time.  In practice people have found that 64 KB
+        * works okay and that's what Windows does.  But we'll be
+        * conservative; people can always use the sysfs interface to
+        * increase max_sectors. */
        if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS &&
-                       us->pusb_dev->speed == USB_SPEED_HIGH &&
-                       sdev->request_queue->max_sectors > 128)
-               blk_queue_max_sectors(sdev->request_queue, 128);
+                       sdev->request_queue->max_sectors > 64)
+               blk_queue_max_sectors(sdev->request_queue, 64);
 
        /* We can't put these settings in slave_alloc() because that gets
         * called before the device type is known.  Consequently these
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c   Sun Aug  1 17:32:35 2004
+++ b/drivers/usb/storage/transport.c   Sun Aug  1 17:32:35 2004
@@ -982,6 +982,12 @@
 
        /* DATA STAGE */
        /* send/receive data payload, if there is any */
+
+       /* Genesys Logic interface chips need a 100us delay between the
+        * command phase and the data phase */
+       if (us->pusb_dev->descriptor.idVendor == USB_VENDOR_ID_GENESYS)
+               udelay(100);
+
        if (transfer_length) {
                unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? 
                                us->recv_bulk_pipe : us->send_bulk_pipe;
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h Sun Aug  1 17:32:35 2004
+++ b/drivers/usb/storage/usb.h Sun Aug  1 17:32:35 2004
@@ -179,4 +179,8 @@
 #define scsi_unlock(host)      spin_unlock_irq(host->host_lock)
 #define scsi_lock(host)                spin_lock_irq(host->host_lock)
 
+
+/* Vendor ID list for devices that require special handling */
+#define USB_VENDOR_ID_GENESYS          0x05e3  /* Genesys Logic */
+
 #endif

-- 
Matthew Dharm                              Home: [EMAIL PROTECTED] 
Maintainer, Linux USB Mass Storage Driver

E:  You run this ship with Windows?!  YOU IDIOT!
L:  Give me a break, it came bundled with the computer!
                                        -- ESR and Lan Solaris
User Friendly, 12/8/1998

Attachment: pgpR8zUsi9MqK.pgp
Description: PGP signature

Reply via email to