summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@home.transmeta.com>2002-11-05 03:52:21 -0800
committerLinus Torvalds <torvalds@home.transmeta.com>2002-11-05 03:52:21 -0800
commit420036649ed2e9d300688f5da286ccf7abefc4af (patch)
tree625bed8f93453d4199b091a2acd6c375d58a302f
parent078349259f28737fa07e55d05f481b8eba160451 (diff)
parent039a0ac477bdbfd02b75aa442c779573cf3d6afc (diff)
Merge bk://linuxusb.bkbits.net/linus-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
-rw-r--r--drivers/net/irda/irda-usb.c2
-rw-r--r--drivers/usb/class/Kconfig2
-rw-r--r--drivers/usb/core/devio.c6
-rw-r--r--drivers/usb/core/hcd.h1
-rw-r--r--drivers/usb/host/ohci-dbg.c17
-rw-r--r--drivers/usb/host/ohci-pci.c11
-rw-r--r--drivers/usb/host/ohci-q.c6
-rw-r--r--drivers/usb/host/ohci-sa1111.c10
-rw-r--r--drivers/usb/host/ohci.h1
-rw-r--r--drivers/usb/image/scanner.c4
-rw-r--r--drivers/usb/image/scanner.h8
-rw-r--r--drivers/usb/media/vicam.c40
-rw-r--r--drivers/usb/misc/Kconfig7
-rw-r--r--drivers/usb/misc/usbtest.c37
-rw-r--r--drivers/usb/serial/visor.c2
-rw-r--r--drivers/usb/serial/visor.h1
-rw-r--r--drivers/usb/storage/datafab.c1
-rw-r--r--drivers/usb/storage/freecom.c27
-rw-r--r--drivers/usb/storage/isd200.c236
-rw-r--r--drivers/usb/storage/jumpshot.c1
-rw-r--r--drivers/usb/storage/sddr09.c1
-rw-r--r--drivers/usb/storage/sddr55.c1
-rw-r--r--drivers/usb/storage/shuttle_usbat.c4
-rw-r--r--drivers/usb/storage/transport.c71
-rw-r--r--sound/usb/usbaudio.c2
25 files changed, 177 insertions, 322 deletions
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 058f8024384b..da5af39db508 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1487,7 +1487,7 @@ static int irda_usb_probe(struct usb_interface *intf,
* specify an alternate, but very few driver do like this.
* Jean II */
ret = usb_set_interface(dev, intf->altsetting->desc.bInterfaceNumber, 0);
- IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->bInterfaceNumber, ret);
+ IRDA_DEBUG(1, "usb-irda: set interface %d result %d\n", intf->altsetting->desc.bInterfaceNumber, ret);
switch (ret) {
case 0:
break;
diff --git a/drivers/usb/class/Kconfig b/drivers/usb/class/Kconfig
index af8254e60092..059cbac1b74e 100644
--- a/drivers/usb/class/Kconfig
+++ b/drivers/usb/class/Kconfig
@@ -38,7 +38,7 @@ config USB_BLUETOOTH_TTY
config USB_MIDI
tristate "USB MIDI support"
- depends on USB
+ depends on USB && SOUND
---help---
Say Y here if you want to connect a USB MIDI device to your
computer's USB port. This driver is for devices that comply with
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 3770a6a0d270..8b0bebe8d62e 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -751,7 +751,7 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
struct async *as;
struct usb_ctrlrequest *dr = NULL;
unsigned int u, totlen, isofrmlen;
- int ret;
+ int ret, interval = 0;
if (copy_from_user(&uurb, arg, sizeof(uurb)))
return -EFAULT;
@@ -838,6 +838,9 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
case USBDEVFS_URB_TYPE_INTERRUPT:
uurb.number_of_packets = 0;
+ if (!(ep_desc = usb_epnum_to_ep_desc(ps->dev, uurb.endpoint)))
+ return -ENOENT;
+ interval = ep_desc->bInterval;
if (uurb.buffer_length > 16384)
return -EINVAL;
if (!access_ok((uurb.endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb.buffer, uurb.buffer_length))
@@ -869,6 +872,7 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
as->urb->setup_packet = (unsigned char*)dr;
as->urb->start_frame = uurb.start_frame;
as->urb->number_of_packets = uurb.number_of_packets;
+ as->urb->interval = interval;
as->urb->context = as;
as->urb->complete = async_completed;
for (totlen = u = 0; u < uurb.number_of_packets; u++) {
diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h
index 099c7c80a64d..4017268c36e6 100644
--- a/drivers/usb/core/hcd.h
+++ b/drivers/usb/core/hcd.h
@@ -77,6 +77,7 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
/* a few non-PCI controllers exist, mostly for OHCI */
struct pci_dev *pdev; /* pci is typical */
+ struct device *parent; /* parent device driver */
#ifdef CONFIG_PCI
int region; /* pci region for regs */
u32 pci_state [16]; /* for PM state save */
diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c
index b338d3a6328a..b3f2ff97cd30 100644
--- a/drivers/usb/host/ohci-dbg.c
+++ b/drivers/usb/host/ohci-dbg.c
@@ -394,15 +394,14 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
static ssize_t
show_async (struct device *dev, char *buf, size_t count, loff_t off)
{
- struct pci_dev *pdev;
struct ohci_hcd *ohci;
size_t temp;
unsigned long flags;
if (off != 0)
return 0;
- pdev = container_of (dev, struct pci_dev, dev);
- ohci = container_of (pci_get_drvdata (pdev), struct ohci_hcd, hcd);
+
+ ohci = dev_to_ohci(dev);
/* display control and bulk lists together, for simplicity */
spin_lock_irqsave (&ohci->lock, flags);
@@ -420,7 +419,6 @@ static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
static ssize_t
show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
{
- struct pci_dev *pdev;
struct ohci_hcd *ohci;
struct ed **seen, *ed;
unsigned long flags;
@@ -434,8 +432,7 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
return 0;
seen_count = 0;
- pdev = container_of (dev, struct pci_dev, dev);
- ohci = container_of (pci_get_drvdata (pdev), struct ohci_hcd, hcd);
+ ohci = dev_to_ohci(dev);
next = buf;
size = count;
@@ -513,16 +510,16 @@ static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
static inline void create_debug_files (struct ohci_hcd *bus)
{
- device_create_file (&bus->hcd.pdev->dev, &dev_attr_async);
- device_create_file (&bus->hcd.pdev->dev, &dev_attr_periodic);
+ device_create_file (bus->hcd.parent, &dev_attr_async);
+ device_create_file (bus->hcd.parent, &dev_attr_periodic);
// registers
dbg ("%s: created debug files", bus->hcd.self.bus_name);
}
static inline void remove_debug_files (struct ohci_hcd *bus)
{
- device_remove_file (&bus->hcd.pdev->dev, &dev_attr_async);
- device_remove_file (&bus->hcd.pdev->dev, &dev_attr_periodic);
+ device_remove_file (bus->hcd.parent, &dev_attr_async);
+ device_remove_file (bus->hcd.parent, &dev_attr_periodic);
}
#else /* empty stubs for creating those files */
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c
index 29b767ec52b7..d16dda4511b8 100644
--- a/drivers/usb/host/ohci-pci.c
+++ b/drivers/usb/host/ohci-pci.c
@@ -29,6 +29,17 @@
/*-------------------------------------------------------------------------*/
+struct ohci_hcd *dev_to_ohci(struct device *dev) {
+ struct pci_dev *pdev =
+ container_of (dev, struct pci_dev, dev);
+ struct ohci_hcd *ohci =
+ container_of (pci_get_drvdata (pdev), struct ohci_hcd, hcd);
+
+ return ohci;
+}
+
+/*-------------------------------------------------------------------------*/
+
static int __devinit
ohci_pci_start (struct usb_hcd *hcd)
{
diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c
index 621841baef5f..83d1314445cb 100644
--- a/drivers/usb/host/ohci-q.c
+++ b/drivers/usb/host/ohci-q.c
@@ -83,7 +83,7 @@ static int balance (struct ohci_hcd *ohci, int interval, int load)
*/
for (i = 0; i < interval ; i++) {
if (branch < 0 || ohci->load [branch] > ohci->load [i]) {
-#ifdef CONFIG_USB_BANDWIDTH
+#if 1 /* CONFIG_USB_BANDWIDTH */
int j;
/* usb 1.1 says 90% of one frame */
@@ -276,7 +276,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
ohci->ed_controltail = ed->ed_prev;
if (ohci->ed_controltail)
ohci->ed_controltail->ed_next = 0;
- } else {
+ } else if (ed->ed_next) {
ed->ed_next->ed_prev = ed->ed_prev;
}
break;
@@ -297,7 +297,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
ohci->ed_bulktail = ed->ed_prev;
if (ohci->ed_bulktail)
ohci->ed_bulktail->ed_next = 0;
- } else {
+ } else if (ed->ed_next) {
ed->ed_next->ed_prev = ed->ed_prev;
}
break;
diff --git a/drivers/usb/host/ohci-sa1111.c b/drivers/usb/host/ohci-sa1111.c
index e5b729e5ad39..93adc1b914a4 100644
--- a/drivers/usb/host/ohci-sa1111.c
+++ b/drivers/usb/host/ohci-sa1111.c
@@ -27,6 +27,14 @@ extern int usb_disabled(void);
/*-------------------------------------------------------------------------*/
+struct ohci_hcd *dev_to_ohci(struct device *dev) {
+ struct usb_hcd *hcd = dev->driver_data;
+
+ return hcd_to_ohci(hcd);
+}
+
+/*-------------------------------------------------------------------------*/
+
static void sa1111_start_hc(struct sa1111_dev *dev)
{
unsigned int usb_rst = 0;
@@ -120,7 +128,7 @@ static void usb_hcd_sa1111_hcim_irq (int irq, void *__hcd, struct pt_regs * r)
}
#endif
- usb_hcd_irq(irq, __hcd, r);
+ usb_hcd_irq(irq, hcd, r);
}
/*-------------------------------------------------------------------------*/
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h
index d2cfdc659e24..ae963d3acca0 100644
--- a/drivers/usb/host/ohci.h
+++ b/drivers/usb/host/ohci.h
@@ -400,3 +400,4 @@ struct ohci_hcd {
#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
+struct ohci_hcd *dev_to_ohci(struct device *);
diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c
index bc7affeedff6..aa54c8f3d0ee 100644
--- a/drivers/usb/image/scanner.c
+++ b/drivers/usb/image/scanner.c
@@ -840,7 +840,7 @@ probe_scanner(struct usb_interface *intf,
struct usb_device *dev = interface_to_usbdev (intf);
struct scn_usb_data *scn;
struct usb_host_interface *interface;
- struct usb_endpoint_descriptor *endpoint;
+ struct usb_host_endpoint *endpoint;
int ep_cnt;
int ix;
@@ -911,7 +911,7 @@ probe_scanner(struct usb_interface *intf,
}
interface = intf->altsetting;
- endpoint = &interface->endpoint[0].desc;
+ endpoint = &interface->endpoint[0];
/*
* Start checking for two bulk endpoints OR two bulk endpoints *and* one
diff --git a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h
index a4bf8d514d92..7ba3a39766fc 100644
--- a/drivers/usb/image/scanner.h
+++ b/drivers/usb/image/scanner.h
@@ -211,10 +211,10 @@ static struct usb_device_id scanner_device_ids [] = {
MODULE_DEVICE_TABLE (usb, scanner_device_ids);
-#define IS_EP_BULK(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)
-#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
-#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
-#define IS_EP_INTR(ep) ((ep).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)
+#define IS_EP_BULK(ep) ((ep).desc.bmAttributes == USB_ENDPOINT_XFER_BULK ? 1 : 0)
+#define IS_EP_BULK_IN(ep) (IS_EP_BULK(ep) && ((ep).desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_IN)
+#define IS_EP_BULK_OUT(ep) (IS_EP_BULK(ep) && ((ep).desc.bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT)
+#define IS_EP_INTR(ep) ((ep).desc.bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0)
#define USB_SCN_MINOR(X) minor((X)->i_rdev) - SCN_BASE_MNR
diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c
index 178228860c7f..a99d8cf4f30f 100644
--- a/drivers/usb/media/vicam.c
+++ b/drivers/usb/media/vicam.c
@@ -761,23 +761,19 @@ vicam_open(struct inode *inode, struct file *file)
return -EBUSY;
}
+ cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
if (!cam->raw_image) {
- cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
- if (!cam->raw_image) {
- up(&cam->busy_lock);
- return -ENOMEM;
- }
+ up(&cam->busy_lock);
+ return -ENOMEM;
}
+ cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
if (!cam->framebuf) {
- cam->framebuf =
- rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
- if (!cam->framebuf) {
- kfree(cam->raw_image);
- up(&cam->busy_lock);
- return -ENOMEM;
- }
+ kfree(cam->raw_image);
+ up(&cam->busy_lock);
+ return -ENOMEM;
}
+
// First upload firmware, then turn the camera on
if (!cam->is_initialized) {
@@ -805,6 +801,9 @@ vicam_close(struct inode *inode, struct file *file)
DBG("close\n");
set_camera_power(cam, 0);
+ kfree(cam->raw_image);
+ rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
+
cam->open_count--;
return 0;
@@ -989,6 +988,7 @@ vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos )
if (*ppos >= VICAM_MAX_FRAME_SIZE) {
*ppos = 0;
+ up(&cam->busy_lock);
return 0;
}
@@ -1038,15 +1038,6 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma)
if (down_interruptible(&cam->busy_lock))
return -EINTR;
- if (!cam->framebuf) { /* we do lazy allocation */
- cam->framebuf =
- rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
- if (!cam->framebuf) {
- up(&cam->busy_lock);
- return -ENOMEM;
- }
- }
-
pos = (unsigned long)cam->framebuf;
while (size > 0) {
page = kvirt_to_pa(pos);
@@ -1319,7 +1310,6 @@ vicam_disconnect(struct usb_interface *intf)
struct vicam_camera *cam = dev_get_drvdata(&intf->dev);
dev_set_drvdata ( &intf->dev, NULL );
- usb_put_dev(cam->udev);
cam->udev = NULL;
@@ -1329,12 +1319,6 @@ vicam_disconnect(struct usb_interface *intf)
vicam_destroy_proc_entry(cam);
#endif
- if (cam->raw_image)
- kfree(cam->raw_image);
- if (cam->framebuf)
- rvfree(cam->framebuf,
- VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
-
kfree(cam);
printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index e7a6a4ce009f..15c4fa06f264 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -99,10 +99,13 @@ config USB_SPEEDTOUCH
config USB_TEST
tristate "USB testing driver (DEVELOPMENT)"
- depends on USB_DEVICEFS && EXPERIMENTAL
+ depends on USB && USB_DEVICEFS && EXPERIMENTAL
help
This driver is for testing host controller software. It is used
with specialized device firmware for regression and stress testing,
- to help prevent problems from cropping up with 'real" drivers.
+ to help prevent problems from cropping up with "real" drivers.
+
+ See <http://www.linux-usb.org/usbtest> for more information,
+ including sample test device firmware and "how to use it".
diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
index faa2ee6d40bb..6747d847eeab 100644
--- a/drivers/usb/misc/usbtest.c
+++ b/drivers/usb/misc/usbtest.c
@@ -51,14 +51,10 @@ struct usbtest_info {
};
/* this is accessed only through usbfs ioctl calls.
- * one ioctl to issue a test ... no locking needed!!!
+ * one ioctl to issue a test ... one lock per device.
* tests create other threads if they need them.
* urbs and buffers are allocated dynamically,
* and data generated deterministically.
- *
- * there's a minor complication on rmmod, since
- * usbfs.disconnect() waits till our ioctl completes.
- * unplug works fine since we'll see real i/o errors.
*/
struct usbtest_dev {
struct usb_interface *intf;
@@ -66,6 +62,7 @@ struct usbtest_dev {
char id [32];
int in_pipe;
int out_pipe;
+ struct semaphore sem;
#define TBUF_SIZE 256
u8 *buf;
@@ -282,6 +279,10 @@ static int perform_sglist (
* or remote wakeup (which needs human interaction).
*/
+static int realworld = 1;
+MODULE_PARM (realworld, "i");
+MODULE_PARM_DESC (realworld, "clear to demand stricter ch9 compliance");
+
static int get_altsetting (struct usbtest_dev *dev)
{
struct usb_interface *iface = dev->intf;
@@ -366,13 +367,11 @@ static int is_good_config (char *buf, int len)
case USB_DT_OTHER_SPEED_CONFIG:
if (config->bLength != 9)
return 0;
-#if 0
/* this bit 'must be 1' but often isn't */
- if (!(config->bmAttributes & 0x80)) {
+ if (!realworld && !(config->bmAttributes & 0x80)) {
dbg ("high bit of config attributes not set");
return 0;
}
-#endif
if (config->bmAttributes & 0x1f) /* reserved == 0 */
return 0;
break;
@@ -424,7 +423,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
}
/* [real world] get/set unimplemented if there's only one */
- if (iface->num_altsetting == 1)
+ if (realworld && iface->num_altsetting == 1)
continue;
/* [9.4.10] set_interface */
@@ -446,7 +445,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
}
/* [real world] get_config unimplemented if there's only one */
- if (udev->descriptor.bNumConfigurations != 1) {
+ if (!realworld || udev->descriptor.bNumConfigurations != 1) {
int expected = udev->actconfig->desc.bConfigurationValue;
/* [9.4.2] get_configuration always works
@@ -454,7 +453,8 @@ static int ch9_postconfig (struct usbtest_dev *dev)
* won't return config descriptors except before set_config.
*/
retval = usb_control_msg (udev, usb_rcvctrlpipe (udev, 0),
- USB_REQ_GET_CONFIGURATION, USB_RECIP_DEVICE,
+ USB_REQ_GET_CONFIGURATION,
+ USB_DIR_IN | USB_RECIP_DEVICE,
0, 0, dev->buf, 1, HZ * USB_CTRL_GET_TIMEOUT);
if (retval != 1 || dev->buf [0] != expected) {
dbg ("%s get config --> %d (%d)", dev->id, retval,
@@ -563,7 +563,8 @@ static int ch9_postconfig (struct usbtest_dev *dev)
* threads and request completion.
*/
-static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
+static int
+usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *buf)
{
struct usbtest_dev *dev = dev_get_drvdata (&intf->dev);
struct usb_device *udev = testdev_to_usbdev (dev);
@@ -584,6 +585,9 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
|| param->sglen < 0 || param->vary < 0)
return -EINVAL;
+ if (down_interruptible (&dev->sem))
+ return -ERESTARTSYS;
+
/* some devices, like ez-usb default devices, need a non-default
* altsetting to have any active endpoints. some tests change
* altsettings; force a default so most tests don't need to check.
@@ -591,12 +595,15 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
if (dev->info->alt >= 0) {
int res;
- if (intf->altsetting->desc.bInterfaceNumber)
+ if (intf->altsetting->desc.bInterfaceNumber) {
+ up (&dev->sem);
return -ENODEV;
+ }
res = set_altsetting (dev, dev->info->alt);
if (res) {
err ("%s: set altsetting to %d failed, %d",
dev->id, dev->info->alt, res);
+ up (&dev->sem);
return res;
}
}
@@ -770,6 +777,7 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
param->duration.tv_usec += 1000 * 1000;
param->duration.tv_sec -= 1;
}
+ up (&dev->sem);
return retval;
}
@@ -819,6 +827,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
memset (dev, 0, sizeof *dev);
info = (struct usbtest_info *) id->driver_info;
dev->info = info;
+ init_MUTEX (&dev->sem);
/* use the same kind of id the hid driver shows */
snprintf (dev->id, sizeof dev->id, "%s-%s:%d",
@@ -874,6 +883,8 @@ static void usbtest_disconnect (struct usb_interface *intf)
{
struct usbtest_dev *dev = dev_get_drvdata (&intf->dev);
+ down (&dev->sem);
+
dev_set_drvdata (&intf->dev, 0);
info ("unbound %s", dev->id);
kfree (intf->private_data);
diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c
index ec2ff85f5b59..9c4ba970eb35 100644
--- a/drivers/usb/serial/visor.c
+++ b/drivers/usb/serial/visor.c
@@ -185,6 +185,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
+ { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
@@ -207,6 +208,7 @@ static struct usb_device_id id_table_combined [] = {
{ USB_DEVICE(PALM_VENDOR_ID, PALM_I705_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) },
+ { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
diff --git a/drivers/usb/serial/visor.h b/drivers/usb/serial/visor.h
index 4213a7041d8a..a06f1e8070b2 100644
--- a/drivers/usb/serial/visor.h
+++ b/drivers/usb/serial/visor.h
@@ -27,6 +27,7 @@
#define PALM_I705_ID 0x0020
#define PALM_M125_ID 0x0040
#define PALM_M130_ID 0x0050
+#define PALM_TUNGSTEN_T_ID 0x0060
#define PALM_ZIRE_ID 0x0070
#define SONY_VENDOR_ID 0x054C
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index 980253839108..912639eb8e38 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -520,7 +520,6 @@ int datafab_transport(Scsi_Cmnd * srb, struct us_data *us)
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
};
- srb->resid = 0;
if (!us->extra) {
us->extra = kmalloc(sizeof(struct datafab_info), GFP_NOIO);
if (!us->extra) {
diff --git a/drivers/usb/storage/freecom.c b/drivers/usb/storage/freecom.c
index 72112d97487a..e46b21e561c0 100644
--- a/drivers/usb/storage/freecom.c
+++ b/drivers/usb/storage/freecom.c
@@ -127,7 +127,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
/* Issue the transfer command. */
result = usb_stor_bulk_msg (us, fxfr, opipe,
FCM_PACKET_LENGTH, &partial);
- if (result != 0) {
+ if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("Freecom readdata xpot failure: r=%d, p=%d\n",
result, partial);
@@ -146,7 +146,9 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
result = usb_stor_bulk_transfer_srb(us, ipipe, srb, count);
US_DEBUGP("freecom_readdata done!\n");
- return result;
+ if (result > USB_STOR_XFER_SHORT)
+ return USB_STOR_TRANSPORT_ERROR;
+ return USB_STOR_TRANSPORT_GOOD;
}
static int
@@ -168,7 +170,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
/* Issue the transfer command. */
result = usb_stor_bulk_msg (us, fxfr, opipe,
FCM_PACKET_LENGTH, &partial);
- if (result != 0) {
+ if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("Freecom writedata xpot failure: r=%d, p=%d\n",
result, partial);
@@ -188,7 +190,9 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
result = usb_stor_bulk_transfer_srb(us, opipe, srb, count);
US_DEBUGP("freecom_writedata done!\n");
- return result;
+ if (result > USB_STOR_XFER_SHORT)
+ return USB_STOR_TRANSPORT_ERROR;
+ return USB_STOR_TRANSPORT_GOOD;
}
/*
@@ -231,7 +235,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
/* The Freecom device will only fail if there is something wrong in
* USB land. It returns the status in its own registers, which
* come back in the bulk pipe. */
- if (result != 0) {
+ if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("freecom xport failure: r=%d, p=%d\n",
result, partial);
@@ -255,6 +259,8 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("freecom_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED;
}
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
US_DEBUG(pdump ((void *) fst, partial));
@@ -284,7 +290,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
* wrong in USB land. It returns the status in its own
* registers, which come back in the bulk pipe.
*/
- if (result != 0) {
+ if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("freecom xport failure: r=%d, p=%d\n",
result, partial);
@@ -308,13 +314,14 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("freecom_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED;
}
+ if (result > USB_STOR_XFER_SHORT)
+ return USB_STOR_TRANSPORT_ERROR;
US_DEBUG(pdump ((void *) fst, partial));
}
- if (partial != 4 || result != 0) {
+ if (partial != 4)
return USB_STOR_TRANSPORT_ERROR;
- }
if ((fst->Status & 1) != 0) {
US_DEBUGP("operation failed\n");
return USB_STOR_TRANSPORT_FAILED;
@@ -369,7 +376,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP ("freecom_transport: transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED;
}
- if (partial != 4 || result != 0)
+ if (partial != 4 || result > USB_STOR_XFER_SHORT)
return USB_STOR_TRANSPORT_ERROR;
if ((fst->Status & ERR_STAT) != 0) {
US_DEBUGP("operation failed\n");
@@ -398,7 +405,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP ("freecom_transport: transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED;
}
- if (partial != 4 || result != 0)
+ if (partial != 4 || result > USB_STOR_XFER_SHORT)
return USB_STOR_TRANSPORT_ERROR;
if ((fst->Status & ERR_STAT) != 0) {
US_DEBUGP("operation failed\n");
diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
index 5fb82bfaa294..50ac93a1df34 100644
--- a/drivers/usb/storage/isd200.c
+++ b/drivers/usb/storage/isd200.c
@@ -31,6 +31,8 @@
*
* History:
*
+ * 2002-10-19: Removed the specialized transfer routines.
+ * (Alan Stern <stern@rowland.harvard.edu>)
* 2001-02-24: Removed lots of duplicate code and simplified the structure.
* (bjorn@haxx.se)
* 2002-01-16: Fixed endianness bug so it works on the ppc arch.
@@ -386,147 +388,6 @@ void isd200_build_sense(struct us_data *us, Scsi_Cmnd *srb)
}
}
-/***********************************************************************
- * Data transfer routines
- ***********************************************************************/
-
-
-/**************************************************************************
- * Transfer one SCSI scatter-gather buffer via bulk transfer
- *
- * Note that this function is necessary because we want the ability to
- * use scatter-gather memory. Good performance is achieved by a combination
- * of scatter-gather and clustering (which makes each chunk bigger).
- *
- * Note that the lower layer will always retry when a NAK occurs, up to the
- * timeout limit. Thus we don't have to worry about it for individual
- * packets.
- */
-static int isd200_transfer_partial( struct us_data *us,
- unsigned char dataDirection,
- char *buf, int length )
-{
- int result;
- int partial;
- unsigned int pipe;
-
- /* calculate the appropriate pipe information */
- if (dataDirection == SCSI_DATA_READ)
- pipe = us->recv_bulk_pipe;
- else
- pipe = us->send_bulk_pipe;
-
- /* transfer the data */
- US_DEBUGP("isd200_transfer_partial(): xfer %d bytes\n", length);
- result = usb_stor_bulk_msg(us, buf, pipe, length, &partial);
- US_DEBUGP("usb_stor_bulk_msg() returned %d xferred %d/%d\n",
- result, partial, length);
-
- /* if we stall, we need to clear it before we go on */
- if (result == -EPIPE) {
- US_DEBUGP("clearing endpoint halt for pipe 0x%x\n", pipe);
- if (usb_stor_clear_halt(us, pipe) < 0)
- return ISD200_TRANSPORT_FAILED;
- }
-
- /* did we send all the data? */
- if (partial == length) {
- US_DEBUGP("isd200_transfer_partial(): transfer complete\n");
- return ISD200_TRANSPORT_GOOD;
- }
-
- /* did we abort this command? */
- if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
- US_DEBUGP("isd200_transfer_partial(): transfer aborted\n");
- return ISD200_TRANSPORT_ABORTED;
- }
-
- /* uh oh... we have an error code, so something went wrong. */
- if (result) {
- /* NAK - that means we've retried a few times already */
- if (result == -ETIMEDOUT) {
- US_DEBUGP("isd200_transfer_partial(): device NAKed\n");
- return ISD200_TRANSPORT_FAILED;
- }
-
- /* the catch-all case */
- US_DEBUGP("isd200_transfer_partial(): unknown error\n");
- return ISD200_TRANSPORT_FAILED;
- }
-
- /* no error code, so we must have transferred some data,
- * just not all of it */
- return ISD200_TRANSPORT_SHORT;
-}
-
-
-/**************************************************************************
- * Transfer an entire SCSI command's worth of data payload over the bulk
- * pipe.
- *
- * Note that this uses us_transfer_partial to achieve it's goals -- this
- * function simply determines if we're going to use scatter-gather or not,
- * and acts appropriately. For now, it also re-interprets the error codes.
- */
-static void isd200_transfer( struct us_data *us, Scsi_Cmnd *srb )
-{
- int i;
- int result = -1;
- struct scatterlist *sg;
- unsigned int total_transferred = 0;
- unsigned int transfer_amount;
-
- /* calculate how much we want to transfer */
- int dir = srb->sc_data_direction;
- srb->sc_data_direction = SCSI_DATA_WRITE;
- transfer_amount = usb_stor_transfer_length(srb);
- srb->sc_data_direction = dir;
-
- /* was someone foolish enough to request more data than available
- * buffer space? */
- if (transfer_amount > srb->request_bufflen)
- transfer_amount = srb->request_bufflen;
-
- /* are we scatter-gathering? */
- if (srb->use_sg) {
-
- /* loop over all the scatter gather structures and
- * make the appropriate requests for each, until done
- */
- sg = (struct scatterlist *) srb->request_buffer;
- for (i = 0; i < srb->use_sg; i++) {
-
- /* transfer the lesser of the next buffer or the
- * remaining data */
- if (transfer_amount - total_transferred >=
- sg[i].length) {
- result = isd200_transfer_partial(us,
- srb->sc_data_direction,
- sg_address(sg[i]),
- sg[i].length);
- total_transferred += sg[i].length;
- } else
- result = isd200_transfer_partial(us,
- srb->sc_data_direction,
- sg_address(sg[i]),
- transfer_amount - total_transferred);
-
- /* if we get an error, end the loop here */
- if (result)
- break;
- }
- }
- else
- /* no scatter-gather, just make the request */
- result = isd200_transfer_partial(us,
- srb->sc_data_direction,
- srb->request_buffer,
- transfer_amount);
-
- /* return the result in the data structure itself */
- srb->result = result;
-}
-
/***********************************************************************
* Transport routines
@@ -546,23 +407,21 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
struct bulk_cb_wrap bcb;
struct bulk_cs_wrap bcs;
int result;
- int partial;
- unsigned int transfer_amount;
+ unsigned int transfer_length;
int dir = srb->sc_data_direction;
srb->sc_data_direction = SCSI_DATA_WRITE;
- transfer_amount = usb_stor_transfer_length(srb);
+ transfer_length = usb_stor_transfer_length(srb);
srb->sc_data_direction = dir;
/* set up the command wrapper */
bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
- bcb.DataTransferLength = cpu_to_le32(transfer_amount);
+ bcb.DataTransferLength = cpu_to_le32(transfer_length);
bcb.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
bcb.Tag = srb->serial_number;
bcb.Lun = srb->cmnd[1] >> 5;
if (us->flags & US_FL_SCM_MULT_TARG)
bcb.Lun |= srb->target << 4;
-
bcb.Length = AtaCdbLength;
/* copy the command payload */
@@ -572,33 +431,32 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
/* send it to out endpoint */
US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
le32_to_cpu(bcb.Signature), bcb.Tag,
- (bcb.Lun >> 4), (bcb.Lun & 0xFF),
+ (bcb.Lun >> 4), (bcb.Lun & 0x0F),
le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
- result = usb_stor_bulk_msg(us, &bcb, us->send_bulk_pipe,
- US_BULK_CB_WRAP_LEN, &partial);
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+ (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL);
US_DEBUGP("Bulk command transfer result=%d\n", result);
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
return ISD200_TRANSPORT_ABORTED;
}
-
- else if (result == -EPIPE) {
- /* if we stall, we need to clear it before we go on */
- US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
- us->send_bulk_pipe);
- if (usb_stor_clear_halt(us, us->send_bulk_pipe) < 0)
- return ISD200_TRANSPORT_ERROR;
- } else if (result)
+ if (result != USB_STOR_XFER_GOOD)
return ISD200_TRANSPORT_ERROR;
/* if the command transfered well, then we go to the data stage */
- if (!result && bcb.DataTransferLength) {
- isd200_transfer(us, srb);
- US_DEBUGP("Bulk data transfer result 0x%x\n", srb->result);
-
- if (srb->result == ISD200_TRANSPORT_ABORTED)
+ if (transfer_length) {
+ unsigned int pipe = srb->sc_data_direction == SCSI_DATA_READ ?
+ us->recv_bulk_pipe : us->send_bulk_pipe;
+ result = usb_stor_bulk_transfer_srb(us, pipe, srb,
+ transfer_length);
+ US_DEBUGP("Bulk data transfer result 0x%x\n", result);
+
+ /* if it was aborted, we need to indicate that */
+ if (result == USB_STOR_XFER_ABORTED)
return ISD200_TRANSPORT_ABORTED;
+ if (result == USB_STOR_XFER_ERROR)
+ return ISD200_TRANSPORT_ERROR;
}
/* See flow chart on pg 15 of the Bulk Only Transport spec for
@@ -607,42 +465,31 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
/* get CSW for device status */
US_DEBUGP("Attempting to get CSW...\n");
- result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
- US_BULK_CS_WRAP_LEN, &partial);
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+ (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
+
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
return ISD200_TRANSPORT_ABORTED;
}
/* did the attempt to read the CSW fail? */
- if (result == -EPIPE) {
- US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
- us->recv_bulk_pipe);
- if (usb_stor_clear_halt(us, us->recv_bulk_pipe) < 0)
- return ISD200_TRANSPORT_ERROR;
+ if (result == USB_STOR_XFER_STALLED) {
/* get the status again */
US_DEBUGP("Attempting to get CSW (2nd try)...\n");
- result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
- US_BULK_CS_WRAP_LEN, &partial);
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+ (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
/* if the command was aborted, indicate that */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
return ISD200_TRANSPORT_ABORTED;
}
-
- /* if it fails again, we need a reset and return an error*/
- if (result == -EPIPE) {
- US_DEBUGP("clearing halt for pipe 0x%x\n",
- us->recv_bulk_pipe);
- usb_stor_clear_halt(us, us->recv_bulk_pipe);
- return ISD200_TRANSPORT_ERROR;
- }
}
/* if we still have a failure at this point, we're in trouble */
US_DEBUGP("Bulk status result = %d\n", result);
- if (result)
+ if (result != USB_STOR_XFER_GOOD)
return ISD200_TRANSPORT_ERROR;
/* check bulk status */
@@ -651,7 +498,7 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
bcs.Residue, bcs.Status);
if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) ||
bcs.Tag != bcb.Tag ||
- bcs.Status > US_BULK_STAT_PHASE || partial != 13) {
+ bcs.Status > US_BULK_STAT_PHASE) {
US_DEBUGP("Bulk logical error\n");
return ISD200_TRANSPORT_ERROR;
}
@@ -660,6 +507,8 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
switch (bcs.Status) {
case US_BULK_STAT_OK:
/* command good -- note that we could be short on data */
+ if (srb->resid > 0)
+ return ISD200_TRANSPORT_SHORT;
return ISD200_TRANSPORT_GOOD;
case US_BULK_STAT_FAIL:
@@ -764,7 +613,8 @@ static int isd200_action( struct us_data *us, int action,
}
status = isd200_Bulk_transport(us, &srb, &ata, sizeof(ata.generic));
- if (status != ISD200_TRANSPORT_GOOD) {
+ if (status != ISD200_TRANSPORT_GOOD &&
+ status != ISD200_TRANSPORT_SHORT) {
US_DEBUGP(" isd200_action(0x%02x) error: %d\n",action,status);
status = ISD200_ERROR;
/* need to reset device here */
@@ -815,10 +665,22 @@ void isd200_invoke_transport( struct us_data *us,
{
int need_auto_sense = 0;
int transferStatus;
+ int result;
/* send the command to the transport layer */
+ srb->resid = 0;
transferStatus = isd200_Bulk_transport(us, srb, ataCdb,
sizeof(ataCdb->generic));
+
+ /* if the command gets aborted by the higher layers, we need to
+ * short-circuit all other processing
+ */
+ if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+ US_DEBUGP("-- transport indicates command was aborted\n");
+ srb->result = DID_ABORT << 16;
+ return;
+ }
+
switch (transferStatus) {
case ISD200_TRANSPORT_GOOD:
@@ -845,6 +707,7 @@ void isd200_invoke_transport( struct us_data *us,
break;
case ISD200_TRANSPORT_SHORT:
+ srb->result = GOOD << 1;
if (!((srb->cmnd[0] == REQUEST_SENSE) ||
(srb->cmnd[0] == INQUIRY) ||
(srb->cmnd[0] == MODE_SENSE) ||
@@ -861,9 +724,14 @@ void isd200_invoke_transport( struct us_data *us,
}
- if (need_auto_sense)
- if (isd200_read_regs(us) == ISD200_GOOD)
+ if (need_auto_sense) {
+ result = isd200_read_regs(us);
+ if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+ US_DEBUGP("-- auto-sense aborted\n");
+ srb->result = DID_ABORT << 16;
+ } else if (result == ISD200_GOOD)
isd200_build_sense(us, srb);
+ }
/* Regardless of auto-sense, if we _know_ we have an error
* condition, show that in the result code
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index e599c83fbc31..455e865ee1c2 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -464,7 +464,6 @@ int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us)
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
};
- srb->resid = 0;
if (!us->extra) {
us->extra = kmalloc(sizeof(struct jumpshot_info), GFP_NOIO);
if (!us->extra) {
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index 79ca7238af77..660b090248bc 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -1372,7 +1372,6 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
};
- srb->resid = 0;
info = (struct sddr09_card_info *)us->extra;
if (!info) {
nand_init_ecc();
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index 484576cc3c90..62876ea3663d 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -746,7 +746,6 @@ int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us)
unsigned short pages;
struct sddr55_card_info *info;
- srb->resid = 0;
if (!us->extra) {
us->extra = kmalloc(
sizeof(struct sddr55_card_info), GFP_NOIO);
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 1ecc38726ac6..887c97216db3 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -775,7 +775,6 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
int i;
char string[64];
- srb->resid = 0;
len = srb->request_bufflen;
/* Send A0 (ATA PACKET COMMAND).
@@ -805,7 +804,8 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
result = usbat_read(us, USBAT_ATA, 0x17, &status);
US_DEBUGP("Status = %02X\n", status);
-
+ if (result != USB_STOR_XFER_GOOD)
+ return USB_STOR_TRANSPORT_ERROR;
if (srb->cmnd[0] == TEST_UNIT_READY)
transferred = 0;
diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
index b216f61e7919..c0bfd3886feb 100644
--- a/drivers/usb/storage/transport.c
+++ b/drivers/usb/storage/transport.c
@@ -784,18 +784,20 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
int result;
/* send the command to the transport layer */
+ srb->resid = 0;
result = us->transport(srb, us);
/* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing
*/
- if (result == USB_STOR_TRANSPORT_ABORTED) {
+ if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("-- transport indicates command was aborted\n");
srb->result = DID_ABORT << 16;
return;
}
/* if there is a transport error, reset and don't auto-sense */
+ /* What if we want to abort during the reset? */
if (result == USB_STOR_TRANSPORT_ERROR) {
US_DEBUGP("-- transport indicates error, resetting\n");
us->transport_reset(us);
@@ -903,7 +905,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
srb->sc_data_direction = old_sc_data_direction;
memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
- if (temp_result == USB_STOR_TRANSPORT_ABORTED) {
+ if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("-- auto-sense aborted\n");
srb->result = DID_ABORT << 16;
return;
@@ -916,6 +918,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
* auto-sense is perfectly valid
*/
if (!(us->flags & US_FL_SCM_MULT_TARG)) {
+ /* What if we try to abort during the reset? */
us->transport_reset(us);
}
srb->result = DID_ERROR << 16;
@@ -1293,7 +1296,6 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
struct bulk_cs_wrap bcs;
unsigned int transfer_length = usb_stor_transfer_length(srb);
int result;
- int partial;
/* set up the command wrapper */
bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN);
@@ -1313,9 +1315,9 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("Bulk command S 0x%x T 0x%x Trg %d LUN %d L %d F %d CL %d\n",
le32_to_cpu(bcb.Signature), bcb.Tag,
(bcb.Lun >> 4), (bcb.Lun & 0x0F),
- bcb.DataTransferLength, bcb.Flags, bcb.Length);
- result = usb_stor_bulk_msg(us, &bcb, us->send_bulk_pipe,
- US_BULK_CB_WRAP_LEN, &partial);
+ le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
+ result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
+ (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL);
US_DEBUGP("Bulk command transfer result=%d\n", result);
/* did we abort this command? */
@@ -1323,23 +1325,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED;
}
-
- /* if we stall, we need to clear it before we go on */
- if (result == -EPIPE) {
- US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
- us->send_bulk_pipe);
- result = usb_stor_clear_halt(us, us->send_bulk_pipe);
-
- /* did we abort this command? */
- if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
- US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
- return USB_STOR_TRANSPORT_ABORTED;
- }
+ if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- } else if (result) {
- /* unknown error -- we've got a problem */
- return USB_STOR_TRANSPORT_ERROR;
- }
/* DATA STAGE */
/* send/receive data payload, if there is any */
@@ -1363,8 +1350,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get CSW for device status */
US_DEBUGP("Attempting to get CSW...\n");
- result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
- US_BULK_CS_WRAP_LEN, &partial);
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+ (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
@@ -1373,50 +1360,24 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
}
/* did the attempt to read the CSW fail? */
- if (result == -EPIPE) {
- US_DEBUGP("clearing endpoint halt for pipe 0x%x\n",
- us->recv_bulk_pipe);
- result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
-
- /* did we abort this command? */
- if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
- US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
- return USB_STOR_TRANSPORT_ABORTED;
- }
- if (result < 0)
- return USB_STOR_TRANSPORT_ERROR;
+ if (result == USB_STOR_XFER_STALLED) {
/* get the status again */
US_DEBUGP("Attempting to get CSW (2nd try)...\n");
- result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe,
- US_BULK_CS_WRAP_LEN, &partial);
+ result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
+ (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
/* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED;
}
-
- /* if it fails again, we need a reset and return an error*/
- if (result == -EPIPE) {
- US_DEBUGP("clearing halt for pipe 0x%x\n",
- us->recv_bulk_pipe);
- result = usb_stor_clear_halt(us, us->recv_bulk_pipe);
-
- /* did we abort this command? */
- if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
- US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
- return USB_STOR_TRANSPORT_ABORTED;
- }
- return USB_STOR_TRANSPORT_ERROR;
- }
}
/* if we still have a failure at this point, we're in trouble */
US_DEBUGP("Bulk status result = %d\n", result);
- if (result) {
+ if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
- }
/* check bulk status */
US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n",
@@ -1424,7 +1385,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
bcs.Residue, bcs.Status);
if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) ||
bcs.Tag != bcb.Tag ||
- bcs.Status > US_BULK_STAT_PHASE || partial != 13) {
+ bcs.Status > US_BULK_STAT_PHASE) {
US_DEBUGP("Bulk logical error\n");
return USB_STOR_TRANSPORT_ERROR;
}
diff --git a/sound/usb/usbaudio.c b/sound/usb/usbaudio.c
index 93c5c240cbfc..24c693642b65 100644
--- a/sound/usb/usbaudio.c
+++ b/sound/usb/usbaudio.c
@@ -1879,7 +1879,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif,
}
if (iface->altsetting[0].desc.bInterfaceClass != USB_CLASS_AUDIO ||
iface->altsetting[0].desc.bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) {
- snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, iface->altsetting[0].bInterfaceClass);
+ snd_printdd(KERN_ERR "%d:%u:%d: skipping non-supported interface %d\n", dev->devnum, ctrlif, j, iface->altsetting[0].desc.bInterfaceClass);
/* skip non-supported classes */
continue;
}