summaryrefslogtreecommitdiffstats
path: root/drivers/usb/storage
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/storage')
-rw-r--r--drivers/usb/storage/Kconfig5
-rw-r--r--drivers/usb/storage/onetouch.c99
-rw-r--r--drivers/usb/storage/shuttle_usbat.c316
-rw-r--r--drivers/usb/storage/shuttle_usbat.h66
-rw-r--r--drivers/usb/storage/transport.c6
-rw-r--r--drivers/usb/storage/transport.h2
-rw-r--r--drivers/usb/storage/unusual_devs.h63
-rw-r--r--drivers/usb/storage/usb.c163
-rw-r--r--drivers/usb/storage/usb.h5
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;