]>
Commit | Line | Data |
---|---|---|
9920374a GKH |
1 | From 671b4b2ba9266cbcfe7210a704e9ea487dcaa988 Mon Sep 17 00:00:00 2001 |
2 | From: Tormod Volden <debian.tormod@gmail.com> | |
3 | Date: Sat, 20 Apr 2013 14:24:04 +0200 | |
4 | Subject: usb-storage: CY7C68300A chips do not support Cypress ATACB | |
5 | ||
6 | From: Tormod Volden <debian.tormod@gmail.com> | |
7 | ||
8 | commit 671b4b2ba9266cbcfe7210a704e9ea487dcaa988 upstream. | |
9 | ||
10 | Many cards based on CY7C68300A/B/C use the USB ID 04b4:6830 but only the | |
11 | B and C variants (EZ-USB AT2LP) support the ATA Command Block | |
12 | functionality, according to the data sheets. The A variant (EZ-USB AT2) | |
13 | locks up if ATACB is attempted, until a typical 30 seconds timeout runs | |
14 | out and a USB reset is performed. | |
15 | ||
16 | https://bugs.launchpad.net/bugs/428469 | |
17 | ||
18 | It seems that one way to spot a CY7C68300A (at least where the card | |
19 | manufacturer left Cypress' EEPROM default vaules, against Cypress' | |
20 | recommendations) is to look at the USB string descriptor indices. | |
21 | ||
22 | A http://media.digikey.com/pdf/Data%20Sheets/Cypress%20PDFs/CY7C68300A.pdf | |
23 | B http://www.farnell.com/datasheets/43456.pdf | |
24 | C http://www.cypress.com/?rID=14189 | |
25 | ||
26 | Note that a CY7C68300B/C chip appears as CY7C68300A if it is running | |
27 | in Backward Compatibility Mode, and if ATACB would be supported in this | |
28 | case there is anyway no way to tell which chip it really is. | |
29 | ||
30 | For 5 years my external USB drive has been locking up for half a minute | |
31 | when plugged in and ata_id is run by udev, or anytime hdparm or similar | |
32 | is run on it. | |
33 | ||
34 | Finally looking at the /correct/ datasheet I think I found the reason. I | |
35 | am aware the quirk in this patch is a bit hacky, but the hardware | |
36 | manufacturers haven't made it easy for us. | |
37 | ||
38 | Signed-off-by: Tormod Volden <debian.tormod@gmail.com> | |
39 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
40 | ||
41 | --- | |
42 | drivers/usb/storage/cypress_atacb.c | 16 ++++++++++++++-- | |
43 | 1 file changed, 14 insertions(+), 2 deletions(-) | |
44 | ||
45 | --- a/drivers/usb/storage/cypress_atacb.c | |
46 | +++ b/drivers/usb/storage/cypress_atacb.c | |
47 | @@ -248,14 +248,26 @@ static int cypress_probe(struct usb_inte | |
48 | { | |
49 | struct us_data *us; | |
50 | int result; | |
51 | + struct usb_device *device; | |
52 | ||
53 | result = usb_stor_probe1(&us, intf, id, | |
54 | (id - cypress_usb_ids) + cypress_unusual_dev_list); | |
55 | if (result) | |
56 | return result; | |
57 | ||
58 | - us->protocol_name = "Transparent SCSI with Cypress ATACB"; | |
59 | - us->proto_handler = cypress_atacb_passthrough; | |
60 | + /* Among CY7C68300 chips, the A revision does not support Cypress ATACB | |
61 | + * Filter out this revision from EEPROM default descriptor values | |
62 | + */ | |
63 | + device = interface_to_usbdev(intf); | |
64 | + if (device->descriptor.iManufacturer != 0x38 || | |
65 | + device->descriptor.iProduct != 0x4e || | |
66 | + device->descriptor.iSerialNumber != 0x64) { | |
67 | + us->protocol_name = "Transparent SCSI with Cypress ATACB"; | |
68 | + us->proto_handler = cypress_atacb_passthrough; | |
69 | + } else { | |
70 | + us->protocol_name = "Transparent SCSI"; | |
71 | + us->proto_handler = usb_stor_transparent_scsi_command; | |
72 | + } | |
73 | ||
74 | result = usb_stor_probe2(us); | |
75 | return result; |