diff options
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r-- | drivers/usb/storage/Kconfig | 5 | ||||
-rw-r--r-- | drivers/usb/storage/onetouch.c | 99 | ||||
-rw-r--r-- | drivers/usb/storage/shuttle_usbat.c | 316 | ||||
-rw-r--r-- | drivers/usb/storage/shuttle_usbat.h | 66 | ||||
-rw-r--r-- | drivers/usb/storage/transport.c | 6 | ||||
-rw-r--r-- | drivers/usb/storage/transport.h | 2 | ||||
-rw-r--r-- | drivers/usb/storage/unusual_devs.h | 63 | ||||
-rw-r--r-- | drivers/usb/storage/usb.c | 163 | ||||
-rw-r--r-- | drivers/usb/storage/usb.h | 5 |
9 files changed, 412 insertions, 313 deletions
diff --git a/drivers/usb/storage/Kconfig b/drivers/usb/storage/Kconfig index bb9819cc8826..c41d64dbb0f0 100644 --- a/drivers/usb/storage/Kconfig +++ b/drivers/usb/storage/Kconfig @@ -2,7 +2,8 @@ # USB Storage driver configuration # -comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' may also be needed; see USB_STORAGE Help for more information" +comment "NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'" +comment "may also be needed; see USB_STORAGE Help for more information" depends on USB config USB_STORAGE @@ -114,7 +115,7 @@ config USB_STORAGE_JUMPSHOT config USB_STORAGE_ONETOUCH bool "Support OneTouch Button on Maxtor Hard Drives (EXPERIMENTAL)" - depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL + depends on USB_STORAGE && INPUT_EVDEV && EXPERIMENTAL && !PM help Say Y here to include additional code to support the Maxtor OneTouch USB hard drive's onetouch button. diff --git a/drivers/usb/storage/onetouch.c b/drivers/usb/storage/onetouch.c index 2c9402dc702b..89401a59f952 100644 --- a/drivers/usb/storage/onetouch.c +++ b/drivers/usb/storage/onetouch.c @@ -5,7 +5,7 @@ * Copyright (c) 2005 Nick Sillik <n.sillik@temple.edu> * * Initial work by: - * Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se> + * Copyright (c) 2003 Erik Thyren <erth7411@student.uu.se> * * Based on usbmouse.c (Vojtech Pavlik) and xpad.c (Marko Friedemann) * @@ -46,7 +46,7 @@ void onetouch_release_input(void *onetouch_); struct usb_onetouch { char name[128]; char phys[64]; - struct input_dev dev; /* input device interface */ + struct input_dev *dev; /* input device interface */ struct usb_device *udev; /* usb device */ struct urb *irq; /* urb for interrupt in report */ @@ -58,7 +58,7 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) { struct usb_onetouch *onetouch = urb->context; signed char *data = onetouch->data; - struct input_dev *dev = &onetouch->dev; + struct input_dev *dev = onetouch->dev; int status; switch (urb->status) { @@ -74,11 +74,9 @@ static void usb_onetouch_irq(struct urb *urb, struct pt_regs *regs) } input_regs(dev, regs); - - input_report_key(&onetouch->dev, ONETOUCH_BUTTON, - data[0] & 0x02); - + input_report_key(dev, ONETOUCH_BUTTON, data[0] & 0x02); input_sync(dev); + resubmit: status = usb_submit_urb (urb, SLAB_ATOMIC); if (status) @@ -113,8 +111,8 @@ int onetouch_connect_input(struct us_data *ss) struct usb_host_interface *interface; struct usb_endpoint_descriptor *endpoint; struct usb_onetouch *onetouch; + struct input_dev *input_dev; int pipe, maxp; - char path[64]; interface = ss->pusb_intf->cur_altsetting; @@ -122,62 +120,62 @@ int onetouch_connect_input(struct us_data *ss) return -ENODEV; endpoint = &interface->endpoint[2].desc; - if(!(endpoint->bEndpointAddress & USB_DIR_IN)) + if (!(endpoint->bEndpointAddress & USB_DIR_IN)) return -ENODEV; - if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) + if ((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) return -ENODEV; pipe = usb_rcvintpipe(udev, endpoint->bEndpointAddress); maxp = usb_maxpacket(udev, pipe, usb_pipeout(pipe)); - if (!(onetouch = kcalloc(1, sizeof(struct usb_onetouch), GFP_KERNEL))) - return -ENOMEM; + onetouch = kzalloc(sizeof(struct usb_onetouch), GFP_KERNEL); + input_dev = input_allocate_device(); + if (!onetouch || !input_dev) + goto fail1; onetouch->data = usb_buffer_alloc(udev, ONETOUCH_PKT_LEN, SLAB_ATOMIC, &onetouch->data_dma); - if (!onetouch->data){ - kfree(onetouch); - return -ENOMEM; - } + if (!onetouch->data) + goto fail1; onetouch->irq = usb_alloc_urb(0, GFP_KERNEL); - if (!onetouch->irq){ - kfree(onetouch); - usb_buffer_free(udev, ONETOUCH_PKT_LEN, - onetouch->data, onetouch->data_dma); - return -ENODEV; - } - + if (!onetouch->irq) + goto fail2; onetouch->udev = udev; + onetouch->dev = input_dev; - set_bit(EV_KEY, onetouch->dev.evbit); - set_bit(ONETOUCH_BUTTON, onetouch->dev.keybit); - clear_bit(0, onetouch->dev.keybit); + if (udev->manufacturer) + strlcpy(onetouch->name, udev->manufacturer, + sizeof(onetouch->name)); + if (udev->product) { + if (udev->manufacturer) + strlcat(onetouch->name, " ", sizeof(onetouch->name)); + strlcat(onetouch->name, udev->product, sizeof(onetouch->name)); + } - onetouch->dev.private = onetouch; - onetouch->dev.open = usb_onetouch_open; - onetouch->dev.close = usb_onetouch_close; + if (!strlen(onetouch->name)) + snprintf(onetouch->name, sizeof(onetouch->name), + "Maxtor Onetouch %04x:%04x", + le16_to_cpu(udev->descriptor.idVendor), + le16_to_cpu(udev->descriptor.idProduct)); - usb_make_path(udev, path, sizeof(path)); - sprintf(onetouch->phys, "%s/input0", path); + usb_make_path(udev, onetouch->phys, sizeof(onetouch->phys)); + strlcat(onetouch->phys, "/input0", sizeof(onetouch->phys)); - onetouch->dev.name = onetouch->name; - onetouch->dev.phys = onetouch->phys; + input_dev->name = onetouch->name; + input_dev->phys = onetouch->phys; + usb_to_input_id(udev, &input_dev->id); + input_dev->cdev.dev = &udev->dev; - usb_to_input_id(udev, &onetouch->dev.id); + set_bit(EV_KEY, input_dev->evbit); + set_bit(ONETOUCH_BUTTON, input_dev->keybit); + clear_bit(0, input_dev->keybit); - onetouch->dev.dev = &udev->dev; - - if (udev->manufacturer) - strcat(onetouch->name, udev->manufacturer); - if (udev->product) - sprintf(onetouch->name, "%s %s", onetouch->name, - udev->product); - if (!strlen(onetouch->name)) - sprintf(onetouch->name, "Maxtor Onetouch %04x:%04x", - onetouch->dev.id.vendor, onetouch->dev.id.product); + input_dev->private = onetouch; + input_dev->open = usb_onetouch_open; + input_dev->close = usb_onetouch_close; usb_fill_int_urb(onetouch->irq, udev, pipe, onetouch->data, (maxp > 8 ? 8 : maxp), @@ -188,10 +186,15 @@ int onetouch_connect_input(struct us_data *ss) ss->extra_destructor = onetouch_release_input; ss->extra = onetouch; - input_register_device(&onetouch->dev); - printk(KERN_INFO "usb-input: %s on %s\n", onetouch->dev.name, path); + input_register_device(onetouch->dev); return 0; + + fail2: usb_buffer_free(udev, ONETOUCH_PKT_LEN, + onetouch->data, onetouch->data_dma); + fail1: kfree(onetouch); + input_free_device(input_dev); + return -ENOMEM; } void onetouch_release_input(void *onetouch_) @@ -200,11 +203,9 @@ void onetouch_release_input(void *onetouch_) if (onetouch) { usb_kill_urb(onetouch->irq); - input_unregister_device(&onetouch->dev); + input_unregister_device(onetouch->dev); usb_free_urb(onetouch->irq); usb_buffer_free(onetouch->udev, ONETOUCH_PKT_LEN, onetouch->data, onetouch->data_dma); - printk(KERN_INFO "usb-input: deregistering %s\n", - onetouch->dev.name); } } diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 356342c6e7a2..fea176d7e79a 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c @@ -1,4 +1,4 @@ -/* Driver for SCM Microsystems USB-ATAPI cable +/* Driver for SCM Microsystems (a.k.a. Shuttle) USB-ATAPI cable * * $Id: shuttle_usbat.c,v 1.17 2002/04/22 03:39:43 mdharm Exp $ * @@ -67,10 +67,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us); static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us); /* - * Convenience function to produce an ATAPI read/write sectors command + * Convenience function to produce an ATA read/write sectors command * Use cmd=0x20 for read, cmd=0x30 for write */ -static void usbat_pack_atapi_sector_cmd(unsigned char *buf, +static void usbat_pack_ata_sector_cmd(unsigned char *buf, unsigned char thistime, u32 sector, unsigned char cmd) { @@ -196,10 +196,12 @@ static int usbat_check_status(struct us_data *us) if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; - if (*reply & 0x01 && *reply != 0x51) // error/check condition (0x51 is ok) + /* error/check condition (0x51 is ok) */ + if (*reply & 0x01 && *reply != 0x51) return USB_STOR_TRANSPORT_FAILED; - if (*reply & 0x20) // device fault + /* device fault */ + if (*reply & 0x20) return USB_STOR_TRANSPORT_FAILED; return USB_STOR_TRANSPORT_GOOD; @@ -222,29 +224,39 @@ static int usbat_set_shuttle_features(struct us_data *us, command[0] = 0x40; command[1] = USBAT_CMD_SET_FEAT; - // The only bit relevant to ATA access is bit 6 - // which defines 8 bit data access (set) or 16 bit (unset) + /* + * The only bit relevant to ATA access is bit 6 + * which defines 8 bit data access (set) or 16 bit (unset) + */ command[2] = epp_control; - // If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1, - // ET1 and ET2 define an external event to be checked for on event of a - // _read_blocks or _write_blocks operation. The read/write will not take - // place unless the defined trigger signal is active. + /* + * If FCQ is set in the qualifier (defined in R/W cmd), then bits U0, U1, + * ET1 and ET2 define an external event to be checked for on event of a + * _read_blocks or _write_blocks operation. The read/write will not take + * place unless the defined trigger signal is active. + */ command[3] = external_trigger; - // The resultant byte of the mask operation (see mask_byte) is compared for - // equivalence with this test pattern. If equal, the read/write will take - // place. + /* + * The resultant byte of the mask operation (see mask_byte) is compared for + * equivalence with this test pattern. If equal, the read/write will take + * place. + */ command[4] = test_pattern; - // This value is logically ANDed with the status register field specified - // in the read/write command. + /* + * This value is logically ANDed with the status register field specified + * in the read/write command. + */ command[5] = mask_byte; - // If ALQ is set in the qualifier, this field contains the address of the - // registers where the byte count should be read for transferring the data. - // If ALQ is not set, then this field contains the number of bytes to be - // transferred. + /* + * If ALQ is set in the qualifier, this field contains the address of the + * registers where the byte count should be read for transferring the data. + * If ALQ is not set, then this field contains the number of bytes to be + * transferred. + */ command[6] = subcountL; command[7] = subcountH; @@ -273,26 +285,26 @@ static int usbat_wait_not_busy(struct us_data *us, int minutes) if (result!=USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - if (*status & 0x01) { // check condition + if (*status & 0x01) { /* check condition */ result = usbat_read(us, USBAT_ATA, 0x10, status); return USB_STOR_TRANSPORT_FAILED; } - if (*status & 0x20) // device fault + if (*status & 0x20) /* device fault */ return USB_STOR_TRANSPORT_FAILED; - if ((*status & 0x80)==0x00) { // not busy + if ((*status & 0x80)==0x00) { /* not busy */ US_DEBUGP("Waited not busy for %d steps\n", i); return USB_STOR_TRANSPORT_GOOD; } if (i<500) - msleep(10); // 5 seconds + msleep(10); /* 5 seconds */ else if (i<700) - msleep(50); // 10 seconds + msleep(50); /* 10 seconds */ else if (i<1200) - msleep(100); // 50 seconds + msleep(100); /* 50 seconds */ else - msleep(1000); // X minutes + msleep(1000); /* X minutes */ } US_DEBUGP("Waited not busy for %d minutes, timing out.\n", @@ -412,9 +424,12 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, if (i==0) { cmdlen = 16; - // Write to multiple registers - // Not really sure the 0x07, 0x17, 0xfc, 0xe7 is necessary here, - // but that's what came out of the trace every single time. + /* + * Write to multiple registers + * Not really sure the 0x07, 0x17, 0xfc, 0xe7 is + * necessary here, but that's what came out of the + * trace every single time. + */ command[0] = 0x40; command[1] = access | USBAT_CMD_WRITE_REGS; command[2] = 0x07; @@ -426,7 +441,7 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, } else cmdlen = 8; - // Conditionally read or write blocks + /* Conditionally read or write blocks */ command[cmdlen-8] = (direction==DMA_TO_DEVICE ? 0x40 : 0xC0); command[cmdlen-7] = access | (direction==DMA_TO_DEVICE ? @@ -456,11 +471,6 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, } - - //US_DEBUGP("Transfer %s %d bytes, sg buffers %d\n", - // direction == DMA_TO_DEVICE ? "out" : "in", - // len, use_sg); - result = usb_stor_bulk_transfer_sg(us, pipe, content, len, use_sg, NULL); @@ -508,9 +518,9 @@ static int usbat_hp8200e_rw_block_test(struct us_data *us, if (result!=USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - if (*status & 0x01) // check condition + if (*status & 0x01) /* check condition */ return USB_STOR_TRANSPORT_FAILED; - if (*status & 0x20) // device fault + if (*status & 0x20) /* device fault */ return USB_STOR_TRANSPORT_FAILED; US_DEBUGP("Redoing %s\n", @@ -547,32 +557,32 @@ static int usbat_multiple_write(struct us_data *us, BUG_ON(num_registers > US_IOBUF_SIZE/2); - // Write to multiple registers, ATA access + /* Write to multiple registers, ATA access */ command[0] = 0x40; command[1] = USBAT_ATA | USBAT_CMD_WRITE_REGS; - // No relevance + /* No relevance */ command[2] = 0; command[3] = 0; command[4] = 0; command[5] = 0; - // Number of bytes to be transferred (incl. addresses and data) + /* Number of bytes to be transferred (incl. addresses and data) */ command[6] = LSB_of(num_registers*2); command[7] = MSB_of(num_registers*2); - // The setup command + /* The setup command */ result = usbat_execute_command(us, command, 8); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Create the reg/data, reg/data sequence + /* Create the reg/data, reg/data sequence */ for (i=0; i<num_registers; i++) { data[i<<1] = registers[i]; data[1+(i<<1)] = data_out[i]; } - // Send the data + /* Send the data */ result = usbat_bulk_write(us, data, num_registers*2); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; @@ -606,17 +616,17 @@ static int usbat_read_blocks(struct us_data *us, command[1] = USBAT_ATA | USBAT_CMD_COND_READ_BLOCK; command[2] = USBAT_ATA_DATA; command[3] = USBAT_ATA_STATUS; - command[4] = 0xFD; // Timeout (ms); + command[4] = 0xFD; /* Timeout (ms); */ command[5] = USBAT_QUAL_FCQ; command[6] = LSB_of(len); command[7] = MSB_of(len); - // Multiple block read setup command + /* Multiple block read setup command */ result = usbat_execute_command(us, command, 8); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; - // Read the blocks we just asked for + /* Read the blocks we just asked for */ result = usbat_bulk_read(us, buffer, len); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; @@ -647,17 +657,17 @@ static int usbat_write_blocks(struct us_data *us, command[1] = USBAT_ATA | USBAT_CMD_COND_WRITE_BLOCK; command[2] = USBAT_ATA_DATA; command[3] = USBAT_ATA_STATUS; - command[4] = 0xFD; // Timeout (ms) + command[4] = 0xFD; /* Timeout (ms) */ command[5] = USBAT_QUAL_FCQ; command[6] = LSB_of(len); command[7] = MSB_of(len); - // Multiple block write setup command + /* Multiple block write setup command */ result = usbat_execute_command(us, command, 8); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; - // Write the data + /* Write the data */ result = usbat_bulk_write(us, buffer, len); if (result != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_FAILED; @@ -711,16 +721,20 @@ static int usbat_device_reset(struct us_data *us) { int rc; - // Reset peripheral, enable peripheral control signals - // (bring reset signal up) + /* + * Reset peripheral, enable peripheral control signals + * (bring reset signal up) + */ rc = usbat_write_user_io(us, USBAT_UIO_DRVRST | USBAT_UIO_OE1 | USBAT_UIO_OE0, USBAT_UIO_EPAD | USBAT_UIO_1); if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Enable peripheral control signals - // (bring reset signal down) + /* + * Enable peripheral control signals + * (bring reset signal down) + */ rc = usbat_write_user_io(us, USBAT_UIO_OE1 | USBAT_UIO_OE0, USBAT_UIO_EPAD | USBAT_UIO_1); @@ -737,7 +751,7 @@ static int usbat_device_enable_cdt(struct us_data *us) { int rc; - // Enable peripheral control signals and card detect + /* Enable peripheral control signals and card detect */ rc = usbat_write_user_io(us, USBAT_UIO_ACKD | USBAT_UIO_OE1 | USBAT_UIO_OE0, USBAT_UIO_EPAD | USBAT_UIO_1); @@ -786,7 +800,7 @@ static int usbat_flash_check_media(struct us_data *us, if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // Check for media existence + /* Check for media existence */ rc = usbat_flash_check_media_present(uio); if (rc == USBAT_FLASH_MEDIA_NONE) { info->sense_key = 0x02; @@ -795,11 +809,11 @@ static int usbat_flash_check_media(struct us_data *us, return USB_STOR_TRANSPORT_FAILED; } - // Check for media change + /* Check for media change */ rc = usbat_flash_check_media_changed(uio); if (rc == USBAT_FLASH_MEDIA_CHANGED) { - // Reset and re-enable card detect + /* Reset and re-enable card detect */ rc = usbat_device_reset(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; @@ -839,7 +853,7 @@ static int usbat_identify_device(struct us_data *us, rc = usbat_device_reset(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - msleep(25); + msleep(500); /* * In attempt to distinguish between HP CDRW's and Flash readers, we now @@ -855,15 +869,15 @@ static int usbat_identify_device(struct us_data *us, if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - // 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 + /* Check for error bit, or if the command 'fell through' */ + if (status == 0xA1 || !(status & 0x01)) { + /* 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; @@ -916,7 +930,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, if (!reply) return USB_STOR_TRANSPORT_ERROR; - // ATAPI command : IDENTIFY DEVICE + /* ATA command : IDENTIFY DEVICE */ rc = usbat_multiple_write(us, registers, command, 3); if (rc != USB_STOR_XFER_GOOD) { US_DEBUGP("usbat_flash_get_sector_count: Gah! identify_device failed\n"); @@ -924,7 +938,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, goto leave; } - // Read device status + /* Read device status */ if (usbat_get_status(us, &status) != USB_STOR_XFER_GOOD) { rc = USB_STOR_TRANSPORT_ERROR; goto leave; @@ -932,7 +946,7 @@ static int usbat_flash_get_sector_count(struct us_data *us, msleep(100); - // Read the device identification data + /* Read the device identification data */ rc = usbat_read_block(us, reply, 512); if (rc != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -977,19 +991,23 @@ static int usbat_flash_read_data(struct us_data *us, if (result != USB_STOR_TRANSPORT_GOOD) return result; - // we're working in LBA mode. according to the ATA spec, - // we can support up to 28-bit addressing. I don't know if Jumpshot - // supports beyond 24-bit addressing. It's kind of hard to test - // since it requires > 8GB CF card. + /* + * we're working in LBA mode. according to the ATA spec, + * we can support up to 28-bit addressing. I don't know if Jumpshot + * supports beyond 24-bit addressing. It's kind of hard to test + * since it requires > 8GB CF card. + */ if (sector > 0x0FFFFFFF) return USB_STOR_TRANSPORT_ERROR; totallen = sectors * info->ssize; - // Since we don't read more than 64 KB at a time, we have to create - // a bounce buffer and move the data a piece at a time between the - // bounce buffer and the actual transfer buffer. + /* + * Since we don't read more than 64 KB at a time, we have to create + * a bounce buffer and move the data a piece at a time between the + * bounce buffer and the actual transfer buffer. + */ alloclen = min(totallen, 65536u); buffer = kmalloc(alloclen, GFP_NOIO); @@ -997,27 +1015,29 @@ static int usbat_flash_read_data(struct us_data *us, return USB_STOR_TRANSPORT_ERROR; do { - // loop, never allocate or transfer more than 64k at once - // (min(128k, 255*info->ssize) is the real limit) + /* + * loop, never allocate or transfer more than 64k at once + * (min(128k, 255*info->ssize) is the real limit) + */ len = min(totallen, alloclen); thistime = (len / info->ssize) & 0xff; - // ATAPI command 0x20 (READ SECTORS) - usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x20); + /* ATA command 0x20 (READ SECTORS) */ + usbat_pack_ata_sector_cmd(command, thistime, sector, 0x20); - // Write/execute ATAPI read command + /* Write/execute ATA read command */ result = usbat_multiple_write(us, registers, command, 7); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; - // Read the data we just requested + /* Read the data we just requested */ result = usbat_read_blocks(us, buffer, len); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; US_DEBUGP("usbat_flash_read_data: %d bytes\n", len); - // Store the data in the transfer buffer + /* Store the data in the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, us->srb, &sg_idx, &sg_offset, TO_XFER_BUF); @@ -1061,19 +1081,23 @@ static int usbat_flash_write_data(struct us_data *us, if (result != USB_STOR_TRANSPORT_GOOD) return result; - // we're working in LBA mode. according to the ATA spec, - // we can support up to 28-bit addressing. I don't know if Jumpshot - // supports beyond 24-bit addressing. It's kind of hard to test - // since it requires > 8GB CF card. + /* + * we're working in LBA mode. according to the ATA spec, + * we can support up to 28-bit addressing. I don't know if the device + * supports beyond 24-bit addressing. It's kind of hard to test + * since it requires > 8GB media. + */ if (sector > 0x0FFFFFFF) return USB_STOR_TRANSPORT_ERROR; totallen = sectors * info->ssize; - // Since we don't write more than 64 KB at a time, we have to create - // a bounce buffer and move the data a piece at a time between the - // bounce buffer and the actual transfer buffer. + /* + * Since we don't write more than 64 KB at a time, we have to create + * a bounce buffer and move the data a piece at a time between the + * bounce buffer and the actual transfer buffer. + */ alloclen = min(totallen, 65536u); buffer = kmalloc(alloclen, GFP_NOIO); @@ -1081,24 +1105,26 @@ static int usbat_flash_write_data(struct us_data *us, return USB_STOR_TRANSPORT_ERROR; do { - // loop, never allocate or transfer more than 64k at once - // (min(128k, 255*info->ssize) is the real limit) + /* + * loop, never allocate or transfer more than 64k at once + * (min(128k, 255*info->ssize) is the real limit) + */ len = min(totallen, alloclen); thistime = (len / info->ssize) & 0xff; - // Get the data from the transfer buffer + /* Get the data from the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, us->srb, &sg_idx, &sg_offset, FROM_XFER_BUF); - // ATAPI command 0x30 (WRITE SECTORS) - usbat_pack_atapi_sector_cmd(command, thistime, sector, 0x30); + /* ATA command 0x30 (WRITE SECTORS) */ + usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30); - // Write/execute ATAPI write command + /* Write/execute ATA write command */ result = usbat_multiple_write(us, registers, command, 7); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; - // Write the data + /* Write the data */ result = usbat_write_blocks(us, buffer, len); if (result != USB_STOR_TRANSPORT_GOOD) goto leave; @@ -1169,42 +1195,44 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, srb->transfersize); } - // Since we only read in one block at a time, we have to create - // a bounce buffer and move the data a piece at a time between the - // bounce buffer and the actual transfer buffer. + /* + * Since we only read in one block at a time, we have to create + * a bounce buffer and move the data a piece at a time between the + * bounce buffer and the actual transfer buffer. + */ len = (65535/srb->transfersize) * srb->transfersize; US_DEBUGP("Max read is %d bytes\n", len); len = min(len, srb->request_bufflen); buffer = kmalloc(len, GFP_NOIO); - if (buffer == NULL) // bloody hell! + if (buffer == NULL) /* bloody hell! */ return USB_STOR_TRANSPORT_FAILED; sector = short_pack(data[7+3], data[7+2]); sector <<= 16; sector |= short_pack(data[7+5], data[7+4]); transferred = 0; - sg_segment = 0; // for keeping track of where we are in - sg_offset = 0; // the scatter/gather list + sg_segment = 0; /* for keeping track of where we are in */ + sg_offset = 0; /* the scatter/gather list */ while (transferred != srb->request_bufflen) { if (len > srb->request_bufflen - transferred) len = srb->request_bufflen - transferred; - data[3] = len&0xFF; // (cylL) = expected length (L) - data[4] = (len>>8)&0xFF; // (cylH) = expected length (H) + data[3] = len&0xFF; /* (cylL) = expected length (L) */ + data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */ - // Fix up the SCSI command sector and num sectors + /* Fix up the SCSI command sector and num sectors */ - data[7+2] = MSB_of(sector>>16); // SCSI command sector + data[7+2] = MSB_of(sector>>16); /* SCSI command sector */ data[7+3] = LSB_of(sector>>16); data[7+4] = MSB_of(sector&0xFFFF); data[7+5] = LSB_of(sector&0xFFFF); if (data[7+0] == GPCMD_READ_CD) data[7+6] = 0; - data[7+7] = MSB_of(len / srb->transfersize); // SCSI command - data[7+8] = LSB_of(len / srb->transfersize); // num sectors + data[7+7] = MSB_of(len / srb->transfersize); /* SCSI command */ + data[7+8] = LSB_of(len / srb->transfersize); /* num sectors */ result = usbat_hp8200e_rw_block_test(us, USBAT_ATA, registers, data, 19, @@ -1217,16 +1245,16 @@ static int usbat_hp8200e_handle_read10(struct us_data *us, if (result != USB_STOR_TRANSPORT_GOOD) break; - // Store the data in the transfer buffer + /* Store the data in the transfer buffer */ usb_stor_access_xfer_buf(buffer, len, srb, &sg_segment, &sg_offset, TO_XFER_BUF); - // Update the amount transferred and the sector number + /* Update the amount transferred and the sector number */ transferred += len; sector += len / srb->transfersize; - } // while transferred != srb->request_bufflen + } /* while transferred != srb->request_bufflen */ kfree(buffer); return result; @@ -1237,7 +1265,7 @@ static int usbat_select_and_test_registers(struct us_data *us) int selector; unsigned char *status = us->iobuf; - // try device = master, then device = slave. + /* try device = master, then device = slave. */ for (selector = 0xA0; selector <= 0xB0; selector += 0x10) { if (usbat_write(us, USBAT_ATA, USBAT_ATA_DEVICE, selector) != USB_STOR_XFER_GOOD) @@ -1298,7 +1326,7 @@ int init_usbat(struct us_data *us) memset(us->extra, 0, sizeof(struct usbat_info)); info = (struct usbat_info *) (us->extra); - // Enable peripheral control signals + /* Enable peripheral control signals */ rc = usbat_write_user_io(us, USBAT_UIO_OE1 | USBAT_UIO_OE0, USBAT_UIO_EPAD | USBAT_UIO_1); @@ -1337,7 +1365,7 @@ int init_usbat(struct us_data *us) US_DEBUGP("INIT 5\n"); - // Enable peripheral control signals and card detect + /* Enable peripheral control signals and card detect */ rc = usbat_device_enable_cdt(us); if (rc != USB_STOR_TRANSPORT_GOOD) return rc; @@ -1364,7 +1392,7 @@ int init_usbat(struct us_data *us) US_DEBUGP("INIT 9\n"); - // At this point, we need to detect which device we are using + /* At this point, we need to detect which device we are using */ if (usbat_set_transport(us, info)) return USB_STOR_TRANSPORT_ERROR; @@ -1414,10 +1442,10 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) data[0] = 0x00; data[1] = 0x00; data[2] = 0x00; - data[3] = len&0xFF; // (cylL) = expected length (L) - data[4] = (len>>8)&0xFF; // (cylH) = expected length (H) - data[5] = 0xB0; // (device sel) = slave - data[6] = 0xA0; // (command) = ATA PACKET COMMAND + data[3] = len&0xFF; /* (cylL) = expected length (L) */ + data[4] = (len>>8)&0xFF; /* (cylH) = expected length (H) */ + data[5] = 0xB0; /* (device sel) = slave */ + data[6] = 0xA0; /* (command) = ATA PACKET COMMAND */ for (i=7; i<19; i++) { registers[i] = 0x10; @@ -1466,13 +1494,15 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) return result; } - // Write the 12-byte command header. - - // If the command is BLANK then set the timer for 75 minutes. - // Otherwise set it for 10 minutes. - - // NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW - // AT SPEED 4 IS UNRELIABLE!!! + /* + * Write the 12-byte command header. + * + * If the command is BLANK then set the timer for 75 minutes. + * Otherwise set it for 10 minutes. + * + * NOTE: THE 8200 DOCUMENTATION STATES THAT BLANKING A CDRW + * AT SPEED 4 IS UNRELIABLE!!! + */ if ( (result = usbat_write_block(us, USBAT_ATA, srb->cmnd, 12, @@ -1481,19 +1511,18 @@ static int usbat_hp8200e_transport(struct scsi_cmnd *srb, struct us_data *us) return result; } - // If there is response data to be read in - // then do it here. + /* If there is response data to be read in then do it here. */ if (len != 0 && (srb->sc_data_direction == DMA_FROM_DEVICE)) { - // How many bytes to read in? Check cylL register + /* How many bytes to read in? Check cylL register */ if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_ME, status) != USB_STOR_XFER_GOOD) { return USB_STOR_TRANSPORT_ERROR; } - if (len > 0xFF) { // need to read cylH also + if (len > 0xFF) { /* need to read cylH also */ len = *status; if (usbat_read(us, USBAT_ATA, USBAT_ATA_LBA_HI, status) != USB_STOR_XFER_GOOD) { @@ -1556,13 +1585,16 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) if (rc != USB_STOR_TRANSPORT_GOOD) return rc; - info->ssize = 0x200; // hard coded 512 byte sectors as per ATA spec + /* hard coded 512 byte sectors as per ATA spec */ + info->ssize = 0x200; US_DEBUGP("usbat_flash_transport: READ_CAPACITY: %ld sectors, %ld bytes per sector\n", info->sectors, info->ssize); - // build the reply - // note: must return the sector number of the last sector, - // *not* the total number of sectors + /* + * build the reply + * note: must return the sector number of the last sector, + * *not* the total number of sectors + */ ((__be32 *) ptr)[0] = cpu_to_be32(info->sectors - 1); ((__be32 *) ptr)[1] = cpu_to_be32(info->ssize); usb_stor_set_xfer_buf(ptr, 8, srb); @@ -1586,7 +1618,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == READ_12) { - // I don't think we'll ever see a READ_12 but support it anyway... + /* + * I don't think we'll ever see a READ_12 but support it anyway + */ block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); @@ -1608,7 +1642,9 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == WRITE_12) { - // I don't think we'll ever see a WRITE_12 but support it anyway... + /* + * I don't think we'll ever see a WRITE_12 but support it anyway + */ block = ((u32)(srb->cmnd[2]) << 24) | ((u32)(srb->cmnd[3]) << 16) | ((u32)(srb->cmnd[4]) << 8) | ((u32)(srb->cmnd[5])); @@ -1645,8 +1681,10 @@ static int usbat_flash_transport(struct scsi_cmnd * srb, struct us_data *us) } if (srb->cmnd[0] == ALLOW_MEDIUM_REMOVAL) { - // sure. whatever. not like we can stop the user from popping - // the media out of the device (no locking doors, etc) + /* + * sure. whatever. not like we can stop the user from popping + * the media out of the device (no locking doors, etc) + */ return USB_STOR_TRANSPORT_GOOD; } diff --git a/drivers/usb/storage/shuttle_usbat.h b/drivers/usb/storage/shuttle_usbat.h index 5b8e867e2ae5..25e7d8b340b8 100644 --- a/drivers/usb/storage/shuttle_usbat.h +++ b/drivers/usb/storage/shuttle_usbat.h @@ -55,8 +55,8 @@ #define USBAT_UIO_WRITE 0 /* Qualifier bits */ -#define USBAT_QUAL_FCQ 0x20 // full compare -#define USBAT_QUAL_ALQ 0x10 // auto load subcount +#define USBAT_QUAL_FCQ 0x20 /* full compare */ +#define USBAT_QUAL_ALQ 0x10 /* auto load subcount */ /* USBAT Flash Media status types */ #define USBAT_FLASH_MEDIA_NONE 0 @@ -67,39 +67,39 @@ #define USBAT_FLASH_MEDIA_CHANGED 1 /* USBAT ATA registers */ -#define USBAT_ATA_DATA 0x10 // read/write data (R/W) -#define USBAT_ATA_FEATURES 0x11 // set features (W) -#define USBAT_ATA_ERROR 0x11 // error (R) -#define USBAT_ATA_SECCNT 0x12 // sector count (R/W) -#define USBAT_ATA_SECNUM 0x13 // sector number (R/W) -#define USBAT_ATA_LBA_ME 0x14 // cylinder low (R/W) -#define USBAT_ATA_LBA_HI 0x15 // cylinder high (R/W) -#define USBAT_ATA_DEVICE 0x16 // head/device selection (R/W) -#define USBAT_ATA_STATUS 0x17 // device status (R) -#define USBAT_ATA_CMD 0x17 // device command (W) -#define USBAT_ATA_ALTSTATUS 0x0E // status (no clear IRQ) (R) +#define USBAT_ATA_DATA 0x10 /* read/write data (R/W) */ +#define USBAT_ATA_FEATURES 0x11 /* set features (W) */ +#define USBAT_ATA_ERROR 0x11 /* error (R) */ +#define USBAT_ATA_SECCNT 0x12 /* sector count (R/W) */ +#define USBAT_ATA_SECNUM 0x13 /* sector number (R/W) */ +#define USBAT_ATA_LBA_ME 0x14 /* cylinder low (R/W) */ +#define USBAT_ATA_LBA_HI 0x15 /* cylinder high (R/W) */ +#define USBAT_ATA_DEVICE 0x16 /* head/device selection (R/W) */ +#define USBAT_ATA_STATUS 0x17 /* device status (R) */ +#define USBAT_ATA_CMD 0x17 /* device command (W) */ +#define USBAT_ATA_ALTSTATUS 0x0E /* status (no clear IRQ) (R) */ /* USBAT User I/O Data registers */ -#define USBAT_UIO_EPAD 0x80 // Enable Peripheral Control Signals -#define USBAT_UIO_CDT 0x40 // Card Detect (Read Only) - // CDT = ACKD & !UI1 & !UI0 -#define USBAT_UIO_1 0x20 // I/O 1 -#define USBAT_UIO_0 0x10 // I/O 0 -#define USBAT_UIO_EPP_ATA 0x08 // 1=EPP mode, 0=ATA mode -#define USBAT_UIO_UI1 0x04 // Input 1 -#define USBAT_UIO_UI0 0x02 // Input 0 -#define USBAT_UIO_INTR_ACK 0x01 // Interrupt (ATA & ISA)/Acknowledge (EPP) +#define USBAT_UIO_EPAD 0x80 /* Enable Peripheral Control Signals */ +#define USBAT_UIO_CDT 0x40 /* Card Detect (Read Only) */ + /* CDT = ACKD & !UI1 & !UI0 */ +#define USBAT_UIO_1 0x20 /* I/O 1 */ +#define USBAT_UIO_0 0x10 /* I/O 0 */ +#define USBAT_UIO_EPP_ATA 0x08 /* 1=EPP mode, 0=ATA mode */ +#define USBAT_UIO_UI1 0x04 /* Input 1 */ +#define USBAT_UIO_UI0 0x02 /* Input 0 */ +#define USBAT_UIO_INTR_ACK 0x01 /* Interrupt (ATA/ISA)/Acknowledge (EPP) */ /* USBAT User I/O Enable registers */ -#define USBAT_UIO_DRVRST 0x80 // Reset Peripheral -#define USBAT_UIO_ACKD 0x40 // Enable Card Detect -#define USBAT_UIO_OE1 0x20 // I/O 1 set=output/clr=input - // If ACKD=1, set OE1 to 1 also. -#define USBAT_UIO_OE0 0x10 // I/O 0 set=output/clr=input -#define USBAT_UIO_ADPRST 0x01 // Reset SCM chip +#define USBAT_UIO_DRVRST 0x80 /* Reset Peripheral */ +#define USBAT_UIO_ACKD 0x40 /* Enable Card Detect */ +#define USBAT_UIO_OE1 0x20 /* I/O 1 set=output/clr=input */ + /* If ACKD=1, set OE1 to 1 also. */ +#define USBAT_UIO_OE0 0x10 /* I/O 0 set=output/clr=input */ +#define USBAT_UIO_ADPRST 0x01 /* Reset SCM chip */ /* USBAT Features */ -#define USBAT_FEAT_ETEN 0x80 // External trigger enable +#define USBAT_FEAT_ETEN 0x80 /* External trigger enable */ #define USBAT_FEAT_U1 0x08 #define USBAT_FEAT_U0 0x04 #define USBAT_FEAT_ET1 0x02 @@ -112,12 +112,12 @@ struct usbat_info { int devicetype; /* Used for Flash readers only */ - unsigned long sectors; // total sector count - unsigned long ssize; // sector size in bytes + unsigned long sectors; /* total sector count */ + unsigned long ssize; /* sector size in bytes */ unsigned char sense_key; - unsigned long sense_asc; // additional sense code - unsigned long sense_ascq; // additional sense code qualifier + unsigned long sense_asc; /* additional sense code */ + unsigned long sense_ascq; /* additional sense code qualifier */ }; #endif diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index c1ba5301ebfc..7ca896a342e3 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -636,11 +636,11 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) /* use the new buffer we have */ old_request_buffer = srb->request_buffer; - srb->request_buffer = srb->sense_buffer; + srb->request_buffer = us->sensebuf; /* set the buffer length for transfer */ old_request_bufflen = srb->request_bufflen; - srb->request_bufflen = 18; + srb->request_bufflen = US_SENSE_SIZE; /* set up for no scatter-gather use */ old_sg = srb->use_sg; @@ -652,6 +652,7 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) temp_result = us->transport(us->srb, us); /* let's clean up right away */ + memcpy(srb->sense_buffer, us->sensebuf, US_SENSE_SIZE); srb->resid = old_resid; srb->request_buffer = old_request_buffer; srb->request_bufflen = old_request_bufflen; @@ -923,6 +924,7 @@ int usb_stor_Bulk_max_lun(struct us_data *us) int result; /* issue the command */ + us->iobuf[0] = 0; result = usb_stor_control_msg(us, us->recv_ctrl_pipe, US_BULK_GET_MAX_LUN, USB_DIR_IN | USB_TYPE_CLASS | diff --git a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h index 8d9e0663f8fe..0a362cc781ad 100644 --- a/drivers/usb/storage/transport.h +++ b/drivers/usb/storage/transport.h @@ -50,7 +50,7 @@ #define US_PR_CB 0x01 /* Control/Bulk w/o interrupt */ #define US_PR_BULK 0x50 /* bulk only */ #ifdef CONFIG_USB_STORAGE_USBAT -#define US_PR_SCM_ATAPI 0x80 /* SCM-ATAPI bridge */ +#define US_PR_USBAT 0x80 /* SCM-ATAPI bridge */ #endif #ifdef CONFIG_USB_STORAGE_SDDR09 #define US_PR_EUSB_SDDR09 0x81 /* SCM-SCSI bridge for SDDR-09 */ diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index b79dad1b598c..f5f47a34b168 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -71,12 +71,12 @@ UNUSUAL_DEV( 0x03f0, 0x0107, 0x0200, 0x0200, UNUSUAL_DEV( 0x03f0, 0x0207, 0x0001, 0x0001, "HP", "CD-Writer+ 8200e", - US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), + US_SC_8070, US_PR_USBAT, init_usbat, 0), UNUSUAL_DEV( 0x03f0, 0x0307, 0x0001, 0x0001, "HP", "CD-Writer+ CD-4e", - US_SC_8070, US_PR_SCM_ATAPI, init_usbat, 0), + US_SC_8070, US_PR_USBAT, init_usbat, 0), #endif /* Patch submitted by Mihnea-Costin Grigore <mihnea@zulu.ro> */ @@ -106,6 +106,13 @@ UNUSUAL_DEV( 0x0411, 0x001c, 0x0113, 0x0113, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY ), +/* Reported by Stefan Werner <dustbln@gmx.de> */ +UNUSUAL_DEV( 0x0419, 0xaaf6, 0x0100, 0x0100, + "TrekStor", + "i.Beat Joy 2.0", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_IGNORE_RESIDUE ), + /* Reported by Olaf Hering <olh@suse.de> from novell bug #105878 */ UNUSUAL_DEV( 0x0424, 0x0fdc, 0x0210, 0x0210, "SMSC", @@ -244,6 +251,13 @@ UNUSUAL_DEV( 0x04da, 0x2372, 0x0000, 0x9999, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), +/* Reported by Simeon Simeonov <simeonov_2000@yahoo.com> */ +UNUSUAL_DEV( 0x04da, 0x2373, 0x0000, 0x9999, + "LEICA", + "D-LUX Camera", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY | US_FL_NOT_LOCKABLE ), + /* Most of the following entries were developed with the help of * Shuttle/SCM directly. */ @@ -333,9 +347,9 @@ UNUSUAL_DEV( 0x04fc, 0x80c2, 0x0100, 0x0100, #ifdef CONFIG_USB_STORAGE_USBAT UNUSUAL_DEV( 0x04e6, 0x1010, 0x0000, 0x9999, - "SCM", - "SCM USBAT-02", - US_SC_SCSI, US_PR_SCM_ATAPI, init_usbat, + "Shuttle/SCM", + "USBAT-02", + US_SC_SCSI, US_PR_USBAT, init_usbat, US_FL_SINGLE_LUN), #endif @@ -598,6 +612,16 @@ UNUSUAL_DEV( 0x05ac, 0x1205, 0x0000, 0x9999, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_CAPACITY ), +/* + * Reported by Tyson Vinson <lornoss@gmail.com> + * This particular productId is the iPod Nano + */ +UNUSUAL_DEV( 0x05ac, 0x120a, 0x0000, 0x9999, + "Apple", + "iPod", + US_SC_DEVICE, US_PR_DEVICE, NULL, + US_FL_FIX_CAPACITY ), + #ifdef CONFIG_USB_STORAGE_JUMPSHOT UNUSUAL_DEV( 0x05dc, 0x0001, 0x0000, 0x0001, "Lexar", @@ -686,11 +710,6 @@ UNUSUAL_DEV( 0x0686, 0x4017, 0x0001, 0x0001, "DIMAGE E223", US_SC_SCSI, US_PR_DEVICE, NULL, 0 ), -UNUSUAL_DEV( 0x0693, 0x0002, 0x0100, 0x0100, - "Hagiwara", - "FlashGate SmartMedia", - US_SC_SCSI, US_PR_BULK, NULL, 0 ), - UNUSUAL_DEV( 0x0693, 0x0005, 0x0100, 0x0100, "Hagiwara", "Flashgate", @@ -702,6 +721,14 @@ UNUSUAL_DEV( 0x0781, 0x0001, 0x0200, 0x0200, US_SC_SCSI, US_PR_CB, NULL, US_FL_SINGLE_LUN ), +#ifdef CONFIG_USB_STORAGE_USBAT +UNUSUAL_DEV( 0x0781, 0x0005, 0x0005, 0x0005, + "Sandisk", + "ImageMate SDDR-05b", + US_SC_SCSI, US_PR_USBAT, init_usbat, + US_FL_SINGLE_LUN ), +#endif + UNUSUAL_DEV( 0x0781, 0x0100, 0x0100, 0x0100, "Sandisk", "ImageMate SDDR-12", @@ -724,7 +751,7 @@ UNUSUAL_DEV( 0x07ab, 0xfc01, 0x0000, 0x9999, #endif /* Reported by Eero Volotinen <eero@ping-viini.org> */ -UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0406, 0x0406, +UNUSUAL_DEV( 0x07ab, 0xfccd, 0x0000, 0x9999, "Freecom Technologies", "FHD-Classic", US_SC_DEVICE, US_PR_DEVICE, NULL, @@ -976,6 +1003,11 @@ UNUSUAL_DEV( 0x0c0b, 0xa109, 0x0000, 0xffff, * */ #ifdef CONFIG_USB_STORAGE_ONETOUCH + UNUSUAL_DEV( 0x0d49, 0x7000, 0x0000, 0x9999, + "Maxtor", + "OneTouch External Harddrive", + US_SC_DEVICE, US_PR_DEVICE, onetouch_connect_input, + 0), UNUSUAL_DEV( 0x0d49, 0x7010, 0x0000, 0x9999, "Maxtor", "OneTouch External Harddrive", @@ -1086,6 +1118,15 @@ UNUSUAL_DEV( 0x2735, 0x100b, 0x0000, 0x9999, US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_GO_SLOW ), +/* + * David Härdeman <david@2gen.com> + * The key makes the SCSI stack print confusing (but harmless) messages + */ +UNUSUAL_DEV( 0x4146, 0xba01, 0x0100, 0x0100, + "Iomega", + "Micro Mini 1GB", + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_NOT_LOCKABLE ), + #ifdef CONFIG_USB_STORAGE_SDDR55 UNUSUAL_DEV( 0x55aa, 0xa103, 0x0000, 0x9999, "Sandisk", diff --git a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c index f9a9bfa1aef5..3847ebed2aa4 100644 --- a/drivers/usb/storage/usb.c +++ b/drivers/usb/storage/usb.c @@ -54,6 +54,7 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/slab.h> +#include <linux/kthread.h> #include <scsi/scsi.h> #include <scsi/scsi_cmnd.h> @@ -111,11 +112,6 @@ static atomic_t total_threads = ATOMIC_INIT(0); static DECLARE_COMPLETION(threads_gone); -static int storage_probe(struct usb_interface *iface, - const struct usb_device_id *id); - -static void storage_disconnect(struct usb_interface *iface); - /* The entries in this table, except for final ones here * (USB_MASS_STORAGE_CLASS and the empty entry), correspond, * line for line with the entries of us_unsuaul_dev_list[]. @@ -233,13 +229,40 @@ static struct us_unusual_dev us_unusual_dev_list[] = { { NULL } }; -static struct usb_driver usb_storage_driver = { - .owner = THIS_MODULE, - .name = "usb-storage", - .probe = storage_probe, - .disconnect = storage_disconnect, - .id_table = storage_usb_ids, -}; + +#ifdef CONFIG_PM /* Minimal support for suspend and resume */ + +static int storage_suspend(struct usb_interface *iface, pm_message_t message) +{ + struct us_data *us = usb_get_intfdata(iface); + + /* Wait until no command is running */ + down(&us->dev_semaphore); + + US_DEBUGP("%s\n", __FUNCTION__); + iface->dev.power.power_state.event = message.event; + + /* When runtime PM is working, we'll set a flag to indicate + * whether we should autoresume when a SCSI request arrives. */ + + up(&us->dev_semaphore); + return 0; +} + +static int storage_resume(struct usb_interface *iface) +{ + struct us_data *us = usb_get_intfdata(iface); + + down(&us->dev_semaphore); + + US_DEBUGP("%s\n", __FUNCTION__); + iface->dev.power.power_state.event = PM_EVENT_ON; + + up(&us->dev_semaphore); + return 0; +} + +#endif /* CONFIG_PM */ /* * fill_inquiry_response takes an unsigned char array (which must @@ -288,22 +311,7 @@ static int usb_stor_control_thread(void * __us) struct us_data *us = (struct us_data *)__us; struct Scsi_Host *host = us_to_host(us); - lock_kernel(); - - /* - * This thread doesn't need any user-level access, - * so get rid of all our resources. - */ - daemonize("usb-storage"); current->flags |= PF_NOFREEZE; - unlock_kernel(); - - /* acquire a reference to the host, so it won't be deallocated - * until we're ready to exit */ - scsi_host_get(host); - - /* signal that we've started the thread */ - complete(&(us->notify)); for(;;) { US_DEBUGP("*** thread sleeping.\n"); @@ -467,6 +475,12 @@ static int associate_dev(struct us_data *us, struct usb_interface *intf) US_DEBUGP("I/O buffer allocation failed\n"); return -ENOMEM; } + + us->sensebuf = kmalloc(US_SENSE_SIZE, GFP_KERNEL); + if (!us->sensebuf) { + US_DEBUGP("Sense buffer allocation failed\n"); + return -ENOMEM; + } return 0; } @@ -555,8 +569,8 @@ static int get_transport(struct us_data *us) break; #ifdef CONFIG_USB_STORAGE_USBAT - case US_PR_SCM_ATAPI: - us->transport_name = "SCM/ATAPI"; + case US_PR_USBAT: + us->transport_name = "Shuttle USBAT"; us->transport = usbat_transport; us->transport_reset = usb_stor_CB_reset; us->max_lun = 1; @@ -740,6 +754,7 @@ static int get_pipes(struct us_data *us) static int usb_stor_acquire_resources(struct us_data *us) { int p; + struct task_struct *th; us->current_urb = usb_alloc_urb(0, GFP_KERNEL); if (!us->current_urb) { @@ -747,38 +762,28 @@ static int usb_stor_acquire_resources(struct us_data *us) return -ENOMEM; } - /* Lock the device while we carry out the next two operations */ - down(&us->dev_semaphore); - - /* For bulk-only devices, determine the max LUN value */ - if (us->protocol == US_PR_BULK) { - p = usb_stor_Bulk_max_lun(us); - if (p < 0) { - up(&us->dev_semaphore); - return p; - } - us->max_lun = p; - } - /* Just before we start our control thread, initialize * the device if it needs initialization */ - if (us->unusual_dev->initFunction) - us->unusual_dev->initFunction(us); - - up(&us->dev_semaphore); + if (us->unusual_dev->initFunction) { + p = us->unusual_dev->initFunction(us); + if (p) + return p; + } /* Start up our control thread */ - p = kernel_thread(usb_stor_control_thread, us, CLONE_VM); - if (p < 0) { + th = kthread_create(usb_stor_control_thread, us, "usb-storage"); + if (IS_ERR(th)) { printk(KERN_WARNING USB_STORAGE "Unable to start control thread\n"); - return p; + return PTR_ERR(th); } - us->pid = p; - atomic_inc(&total_threads); - /* Wait for the thread to start */ - wait_for_completion(&(us->notify)); + /* Take a reference to the host for the control thread and + * count it among all the threads we have launched. Then + * start it up. */ + scsi_host_get(us_to_host(us)); + atomic_inc(&total_threads); + wake_up_process(th); return 0; } @@ -812,6 +817,8 @@ static void dissociate_dev(struct us_data *us) { US_DEBUGP("-- %s\n", __FUNCTION__); + kfree(us->sensebuf); + /* Free the device-related DMA-mapped buffers */ if (us->cr) usb_buffer_free(us->pusb_dev, sizeof(*us->cr), us->cr, @@ -872,21 +879,6 @@ static int usb_stor_scan_thread(void * __us) { struct us_data *us = (struct us_data *)__us; - /* - * This thread doesn't need any user-level access, - * so get rid of all our resources. - */ - lock_kernel(); - daemonize("usb-stor-scan"); - unlock_kernel(); - - /* Acquire a reference to the host, so it won't be deallocated - * until we're ready to exit */ - scsi_host_get(us_to_host(us)); - - /* Signal that we've started the thread */ - complete(&(us->notify)); - printk(KERN_DEBUG "usb-storage: device found at %d\n", us->pusb_dev->devnum); @@ -904,6 +896,14 @@ retry: /* If the device is still connected, perform the scanning */ if (!test_bit(US_FLIDX_DISCONNECTING, &us->flags)) { + + /* For bulk-only devices, determine the max LUN value */ + if (us->protocol == US_PR_BULK && + !(us->flags & US_FL_SINGLE_LUN)) { + down(&us->dev_semaphore); + us->max_lun = usb_stor_Bulk_max_lun(us); + up(&us->dev_semaphore); + } scsi_scan_host(us_to_host(us)); printk(KERN_DEBUG "usb-storage: device scan complete\n"); @@ -923,6 +923,7 @@ static int storage_probe(struct usb_interface *intf, struct us_data *us; const int id_index = id - storage_usb_ids; int result; + struct task_struct *th; US_DEBUGP("USB Mass Storage device detected\n"); @@ -1003,17 +1004,21 @@ static int storage_probe(struct usb_interface *intf, } /* Start up the thread for delayed SCSI-device scanning */ - result = kernel_thread(usb_stor_scan_thread, us, CLONE_VM); - if (result < 0) { + th = kthread_create(usb_stor_scan_thread, us, "usb-stor-scan"); + if (IS_ERR(th)) { printk(KERN_WARNING USB_STORAGE "Unable to start the device-scanning thread\n"); quiesce_and_remove_host(us); + result = PTR_ERR(th); goto BadDevice; } - atomic_inc(&total_threads); - /* Wait for the thread to start */ - wait_for_completion(&(us->notify)); + /* Take a reference to the host for the scanning thread and + * count it among all the threads we have launched. Then + * start it up. */ + scsi_host_get(us_to_host(us)); + atomic_inc(&total_threads); + wake_up_process(th); return 0; @@ -1038,6 +1043,18 @@ static void storage_disconnect(struct usb_interface *intf) * Initialization and registration ***********************************************************************/ +static struct usb_driver usb_storage_driver = { + .owner = THIS_MODULE, + .name = "usb-storage", + .probe = storage_probe, + .disconnect = storage_disconnect, +#ifdef CONFIG_PM + .suspend = storage_suspend, + .resume = storage_resume, +#endif + .id_table = storage_usb_ids, +}; + static int __init usb_stor_init(void) { int retval; diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index a195adae57b6..98b09711a739 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -117,6 +117,7 @@ enum { US_DO_ALL_FLAGS }; */ #define US_IOBUF_SIZE 64 /* Size of the DMA-mapped I/O buffer */ +#define US_SENSE_SIZE 18 /* Size of the autosense data buffer */ typedef int (*trans_cmnd)(struct scsi_cmnd *, struct us_data*); typedef int (*trans_reset)(struct us_data*); @@ -160,14 +161,12 @@ struct us_data { struct scsi_cmnd *srb; /* current srb */ unsigned int tag; /* current dCBWTag */ - /* thread information */ - int pid; /* control thread */ - /* control and bulk communications data */ struct urb *current_urb; /* USB requests */ struct usb_ctrlrequest *cr; /* control requests */ struct usb_sg_request current_sg; /* scatter-gather req. */ unsigned char *iobuf; /* I/O buffer */ + unsigned char *sensebuf; /* sense data buffer */ dma_addr_t cr_dma; /* buffer DMA addresses */ dma_addr_t iobuf_dma; |