diff options
author | Daniel Drake <dsd@gentoo.org> | 2005-08-10 13:30:04 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2005-09-08 19:28:18 -0400 |
commit | 68a6457edb8a64fdcc231a4fc5406f6e3f6c9b33 (patch) | |
tree | 4bef1b4ab18a23e7d14dc96577c95310d0e2b3d7 | |
parent | 242cf670c09c05504ce53dfc27f8331a072f169d (diff) |
[PATCH] USB: Fix HP8200 detection in shuttle_usbat
Adding flash-device support to the shuttle_usbat driver in 2.6.11
introduced the need to detect which type of device we are dealing with:
CDRW drive, or flash media reader.
The detection routine used turned out to not work for HP8200 CDRW users,
who saw their devices being detected as a flash disk.
This patch (which has been tested on both flash and cdrom) removes some
unnecessary code, moves device detection to much later during
initialization, and introduces a new detection routine which appears to
work.
Signed-off-by: Daniel Drake <dsd@gentoo.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r-- | drivers/usb/storage/shuttle_usbat.c | 97 |
1 files changed, 32 insertions, 65 deletions
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index f3b60288696c..356342c6e7a2 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -839,34 +839,31 @@ static int usbat_identify_device(struct us_data *us, | |||
839 | rc = usbat_device_reset(us); | 839 | rc = usbat_device_reset(us); |
840 | if (rc != USB_STOR_TRANSPORT_GOOD) | 840 | if (rc != USB_STOR_TRANSPORT_GOOD) |
841 | return rc; | 841 | return rc; |
842 | msleep(25); | ||
842 | 843 | ||
843 | /* | 844 | /* |
844 | * By examining the device signature after a reset, we can identify | 845 | * In attempt to distinguish between HP CDRW's and Flash readers, we now |
845 | * whether the device supports the ATAPI packet interface. | 846 | * execute the IDENTIFY PACKET DEVICE command. On ATA devices (i.e. flash |
846 | * The flash-devices do not support this, whereas the HP CDRW's obviously | 847 | * readers), this command should fail with error. On ATAPI devices (i.e. |
847 | * do. | 848 | * CDROM drives), it should succeed. |
848 | * | ||
849 | * This method is not ideal, but works because no other devices have been | ||
850 | * produced based on the USBAT/USBAT02. | ||
851 | * | ||
852 | * Section 9.1 of the ATAPI-4 spec states (amongst other things) that | ||
853 | * after a device reset, a Cylinder low of 0x14 indicates that the device | ||
854 | * does support packet commands. | ||
855 | */ | 849 | */ |
856 | rc = usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, &status); | 850 | rc = usbat_write(us, USBAT_ATA, USBAT_ATA_CMD, 0xA1); |
857 | if (rc != USB_STOR_XFER_GOOD) | 851 | if (rc != USB_STOR_XFER_GOOD) |
858 | return USB_STOR_TRANSPORT_ERROR; | 852 | return USB_STOR_TRANSPORT_ERROR; |
859 | 853 | ||
860 | US_DEBUGP("usbat_identify_device: Cylinder low is %02X\n", status); | 854 | rc = usbat_get_status(us, &status); |
855 | if (rc != USB_STOR_XFER_GOOD) | ||
856 | return USB_STOR_TRANSPORT_ERROR; | ||
861 | 857 | ||
862 | if (status == 0x14) { | 858 | // Check for error bit |
859 | if (status & 0x01) { | ||
860 | // Device is a CompactFlash reader/writer | ||
861 | US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); | ||
862 | info->devicetype = USBAT_DEV_FLASH; | ||
863 | } else { | ||
863 | // Device is HP 8200 | 864 | // Device is HP 8200 |
864 | US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); | 865 | US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); |
865 | info->devicetype = USBAT_DEV_HP8200; | 866 | info->devicetype = USBAT_DEV_HP8200; |
866 | } else { | ||
867 | // Device is a CompactFlash reader/writer | ||
868 | US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); | ||
869 | info->devicetype = USBAT_DEV_FLASH; | ||
870 | } | 867 | } |
871 | 868 | ||
872 | return USB_STOR_TRANSPORT_GOOD; | 869 | return USB_STOR_TRANSPORT_GOOD; |
@@ -1239,16 +1236,10 @@ static int usbat_select_and_test_registers(struct us_data *us) | |||
1239 | { | 1236 | { |
1240 | int selector; | 1237 | int selector; |
1241 | unsigned char *status = us->iobuf; | 1238 | unsigned char *status = us->iobuf; |
1242 | unsigned char max_selector = 0xB0; | ||
1243 | if (usbat_get_device_type(us) == USBAT_DEV_FLASH) | ||
1244 | max_selector = 0xA0; | ||
1245 | 1239 | ||
1246 | // try device = master, then device = slave. | 1240 | // try device = master, then device = slave. |
1247 | 1241 | for (selector = 0xA0; selector <= 0xB0; selector += 0x10) { | |
1248 | for (selector = 0xA0; selector <= max_selector; selector += 0x10) { | 1242 | if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != |
1249 | |||
1250 | if (usbat_get_device_type(us) == USBAT_DEV_HP8200 && | ||
1251 | usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != | ||
1252 | USB_STOR_XFER_GOOD) | 1243 | USB_STOR_XFER_GOOD) |
1253 | return USB_STOR_TRANSPORT_ERROR; | 1244 | return USB_STOR_TRANSPORT_ERROR; |
1254 | 1245 | ||
@@ -1334,60 +1325,30 @@ int init_usbat(struct us_data *us) | |||
1334 | 1325 | ||
1335 | US_DEBUGP("INIT 3\n"); | 1326 | US_DEBUGP("INIT 3\n"); |
1336 | 1327 | ||
1337 | // At this point, we need to detect which device we are using | ||
1338 | if (usbat_set_transport(us, info)) | ||
1339 | return USB_STOR_TRANSPORT_ERROR; | ||
1340 | |||
1341 | US_DEBUGP("INIT 4\n"); | ||
1342 | |||
1343 | if (usbat_get_device_type(us) == USBAT_DEV_HP8200) { | ||
1344 | msleep(250); | ||
1345 | |||
1346 | // Write 0x80 to ISA port 0x3F | ||
1347 | rc = usbat_write(us, USBAT_ISA, 0x3F, 0x80); | ||
1348 | if (rc != USB_STOR_XFER_GOOD) | ||
1349 | return USB_STOR_TRANSPORT_ERROR; | ||
1350 | |||
1351 | US_DEBUGP("INIT 5\n"); | ||
1352 | |||
1353 | // Read ISA port 0x27 | ||
1354 | rc = usbat_read(us, USBAT_ISA, 0x27, status); | ||
1355 | if (rc != USB_STOR_XFER_GOOD) | ||
1356 | return USB_STOR_TRANSPORT_ERROR; | ||
1357 | |||
1358 | US_DEBUGP("INIT 6\n"); | ||
1359 | |||
1360 | rc = usbat_read_user_io(us, status); | ||
1361 | if (rc != USB_STOR_XFER_GOOD) | ||
1362 | return USB_STOR_TRANSPORT_ERROR; | ||
1363 | |||
1364 | US_DEBUGP("INIT 7\n"); | ||
1365 | } | ||
1366 | |||
1367 | rc = usbat_select_and_test_registers(us); | 1328 | rc = usbat_select_and_test_registers(us); |
1368 | if (rc != USB_STOR_TRANSPORT_GOOD) | 1329 | if (rc != USB_STOR_TRANSPORT_GOOD) |
1369 | return rc; | 1330 | return rc; |
1370 | 1331 | ||
1371 | US_DEBUGP("INIT 8\n"); | 1332 | US_DEBUGP("INIT 4\n"); |
1372 | 1333 | ||
1373 | rc = usbat_read_user_io(us, status); | 1334 | rc = usbat_read_user_io(us, status); |
1374 | if (rc != USB_STOR_XFER_GOOD) | 1335 | if (rc != USB_STOR_XFER_GOOD) |
1375 | return USB_STOR_TRANSPORT_ERROR; | 1336 | return USB_STOR_TRANSPORT_ERROR; |
1376 | 1337 | ||
1377 | US_DEBUGP("INIT 9\n"); | 1338 | US_DEBUGP("INIT 5\n"); |
1378 | 1339 | ||
1379 | // Enable peripheral control signals and card detect | 1340 | // Enable peripheral control signals and card detect |
1380 | rc = usbat_device_enable_cdt(us); | 1341 | rc = usbat_device_enable_cdt(us); |
1381 | if (rc != USB_STOR_TRANSPORT_GOOD) | 1342 | if (rc != USB_STOR_TRANSPORT_GOOD) |
1382 | return rc; | 1343 | return rc; |
1383 | 1344 | ||
1384 | US_DEBUGP("INIT 10\n"); | 1345 | US_DEBUGP("INIT 6\n"); |
1385 | 1346 | ||
1386 | rc = usbat_read_user_io(us, status); | 1347 | rc = usbat_read_user_io(us, status); |
1387 | if (rc != USB_STOR_XFER_GOOD) | 1348 | if (rc != USB_STOR_XFER_GOOD) |
1388 | return USB_STOR_TRANSPORT_ERROR; | 1349 | return USB_STOR_TRANSPORT_ERROR; |
1389 | 1350 | ||
1390 | US_DEBUGP("INIT 11\n"); | 1351 | US_DEBUGP("INIT 7\n"); |
1391 | 1352 | ||
1392 | msleep(1400); | 1353 | msleep(1400); |
1393 | 1354 | ||
@@ -1395,13 +1356,19 @@ int init_usbat(struct us_data *us) | |||
1395 | if (rc != USB_STOR_XFER_GOOD) | 1356 | if (rc != USB_STOR_XFER_GOOD) |
1396 | return USB_STOR_TRANSPORT_ERROR; | 1357 | return USB_STOR_TRANSPORT_ERROR; |
1397 | 1358 | ||
1398 | US_DEBUGP("INIT 12\n"); | 1359 | US_DEBUGP("INIT 8\n"); |
1399 | 1360 | ||
1400 | rc = usbat_select_and_test_registers(us); | 1361 | rc = usbat_select_and_test_registers(us); |
1401 | if (rc != USB_STOR_TRANSPORT_GOOD) | 1362 | if (rc != USB_STOR_TRANSPORT_GOOD) |
1402 | return rc; | 1363 | return rc; |
1403 | 1364 | ||
1404 | US_DEBUGP("INIT 13\n"); | 1365 | US_DEBUGP("INIT 9\n"); |
1366 | |||
1367 | // At this point, we need to detect which device we are using | ||
1368 | if (usbat_set_transport(us, info)) | ||
1369 | return USB_STOR_TRANSPORT_ERROR; | ||
1370 | |||
1371 | US_DEBUGP("INIT 10\n"); | ||
1405 | 1372 | ||
1406 | if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { | 1373 | if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { |
1407 | subcountH = 0x02; | 1374 | subcountH = 0x02; |
@@ -1412,7 +1379,7 @@ int init_usbat(struct us_data *us) | |||
1412 | if (rc != USB_STOR_XFER_GOOD) | 1379 | if (rc != USB_STOR_XFER_GOOD) |
1413 | return USB_STOR_TRANSPORT_ERROR; | 1380 | return USB_STOR_TRANSPORT_ERROR; |
1414 | 1381 | ||
1415 | US_DEBUGP("INIT 14\n"); | 1382 | US_DEBUGP("INIT 11\n"); |
1416 | 1383 | ||
1417 | return USB_STOR_TRANSPORT_GOOD; | 1384 | return USB_STOR_TRANSPORT_GOOD; |
1418 | } | 1385 | } |