From 68a6457edb8a64fdcc231a4fc5406f6e3f6c9b33 Mon Sep 17 00:00:00 2001 From: Daniel Drake Date: Wed, 10 Aug 2005 18:30:04 +0100 Subject: [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 Signed-off-by: Greg Kroah-Hartman --- drivers/usb/storage/shuttle_usbat.c | 97 ++++++++++++------------------------- 1 file changed, 32 insertions(+), 65 deletions(-) (limited to 'drivers/usb/storage/shuttle_usbat.c') diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index f3b60288696..356342c6e7a 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, rc = usbat_device_reset(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; + msleep(25); /* - * By examining the device signature after a reset, we can identify - * whether the device supports the ATAPI packet interface. - * The flash-devices do not support this, whereas the HP CDRW's obviously - * do. - * - * This method is not ideal, but works because no other devices have been - * produced based on the USBAT/USBAT02. - * - * Section 9.1 of the ATAPI-4 spec states (amongst other things) that - * after a device reset, a Cylinder low of 0x14 indicates that the device - * does support packet commands. + * In attempt to distinguish between HP CDRW's and Flash readers, we now + * execute the IDENTIFY PACKET DEVICE command. On ATA devices (i.e. flash + * readers), this command should fail with error. On ATAPI devices (i.e. + * CDROM drives), it should succeed. */ - rc = usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, &status); - if (rc != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; + rc = usbat_write(us, USBAT_ATA, USBAT_ATA_CMD, 0xA1); + if (rc != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("usbat_identify_device: Cylinder low is %02X\n", status); + rc = usbat_get_status(us, &status); + if (rc != USB_STOR_XFER_GOOD) + return USB_STOR_TRANSPORT_ERROR; - if (status == 0x14) { + // Check for error bit + if (status & 0x01) { + // Device is a CompactFlash reader/writer + US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); + info->devicetype = USBAT_DEV_FLASH; + } else { // Device is HP 8200 US_DEBUGP("usbat_identify_device: Detected HP8200 CDRW\n"); info->devicetype = USBAT_DEV_HP8200; - } else { - // Device is a CompactFlash reader/writer - US_DEBUGP("usbat_identify_device: Detected Flash reader/writer\n"); - info->devicetype = USBAT_DEV_FLASH; } return USB_STOR_TRANSPORT_GOOD; @@ -1239,16 +1236,10 @@ static int usbat_select_and_test_registers(struct us_data *us) { int selector; unsigned char *status = us->iobuf; - unsigned char max_selector = 0xB0; - if (usbat_get_device_type(us) == USBAT_DEV_FLASH) - max_selector = 0xA0; // try device = master, then device = slave. - - for (selector = 0xA0; selector <= max_selector; selector += 0x10) { - - if (usbat_get_device_type(us) == USBAT_DEV_HP8200 && - usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != + for (selector = 0xA0; selector <= 0xB0; selector += 0x10) { + if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -1334,60 +1325,30 @@ int init_usbat(struct us_data *us) US_DEBUGP("INIT 3\n"); - // At this point, we need to detect which device we are using - if (usbat_set_transport(us, info)) - return USB_STOR_TRANSPORT_ERROR; - - US_DEBUGP("INIT 4\n"); - - if (usbat_get_device_type(us) == USBAT_DEV_HP8200) { - msleep(250); - - // Write 0x80 to ISA port 0x3F - rc = usbat_write(us, USBAT_ISA, 0x3F, 0x80); - if (rc != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - US_DEBUGP("INIT 5\n"); - - // Read ISA port 0x27 - rc = usbat_read(us, USBAT_ISA, 0x27, status); - if (rc != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - US_DEBUGP("INIT 6\n"); - - rc = usbat_read_user_io(us, status); - if (rc != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; - - US_DEBUGP("INIT 7\n"); - } - rc = usbat_select_and_test_registers(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("INIT 8\n"); + US_DEBUGP("INIT 4\n"); rc = usbat_read_user_io(us, status); if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 9\n"); + US_DEBUGP("INIT 5\n"); // Enable peripheral control signals and card detect rc = usbat_device_enable_cdt(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("INIT 10\n"); + US_DEBUGP("INIT 6\n"); rc = usbat_read_user_io(us, status); if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 11\n"); + US_DEBUGP("INIT 7\n"); msleep(1400); @@ -1395,13 +1356,19 @@ int init_usbat(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 12\n"); + US_DEBUGP("INIT 8\n"); rc = usbat_select_and_test_registers(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - US_DEBUGP("INIT 13\n"); + US_DEBUGP("INIT 9\n"); + + // At this point, we need to detect which device we are using + if (usbat_set_transport(us, info)) + return USB_STOR_TRANSPORT_ERROR; + + US_DEBUGP("INIT 10\n"); if (usbat_get_device_type(us) == USBAT_DEV_FLASH) { subcountH = 0x02; @@ -1412,7 +1379,7 @@ int init_usbat(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - US_DEBUGP("INIT 14\n"); + US_DEBUGP("INIT 11\n"); return USB_STOR_TRANSPORT_GOOD; } -- cgit v1.2.3