diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2002-11-05 03:52:21 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2002-11-05 03:52:21 -0800 |
| commit | 420036649ed2e9d300688f5da286ccf7abefc4af (patch) | |
| tree | 625bed8f93453d4199b091a2acd6c375d58a302f | |
| parent | 078349259f28737fa07e55d05f481b8eba160451 (diff) | |
| parent | 039a0ac477bdbfd02b75aa442c779573cf3d6afc (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.c | 2 | ||||
| -rw-r--r-- | drivers/usb/class/Kconfig | 2 | ||||
| -rw-r--r-- | drivers/usb/core/devio.c | 6 | ||||
| -rw-r--r-- | drivers/usb/core/hcd.h | 1 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-dbg.c | 17 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-pci.c | 11 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-q.c | 6 | ||||
| -rw-r--r-- | drivers/usb/host/ohci-sa1111.c | 10 | ||||
| -rw-r--r-- | drivers/usb/host/ohci.h | 1 | ||||
| -rw-r--r-- | drivers/usb/image/scanner.c | 4 | ||||
| -rw-r--r-- | drivers/usb/image/scanner.h | 8 | ||||
| -rw-r--r-- | drivers/usb/media/vicam.c | 40 | ||||
| -rw-r--r-- | drivers/usb/misc/Kconfig | 7 | ||||
| -rw-r--r-- | drivers/usb/misc/usbtest.c | 37 | ||||
| -rw-r--r-- | drivers/usb/serial/visor.c | 2 | ||||
| -rw-r--r-- | drivers/usb/serial/visor.h | 1 | ||||
| -rw-r--r-- | drivers/usb/storage/datafab.c | 1 | ||||
| -rw-r--r-- | drivers/usb/storage/freecom.c | 27 | ||||
| -rw-r--r-- | drivers/usb/storage/isd200.c | 236 | ||||
| -rw-r--r-- | drivers/usb/storage/jumpshot.c | 1 | ||||
| -rw-r--r-- | drivers/usb/storage/sddr09.c | 1 | ||||
| -rw-r--r-- | drivers/usb/storage/sddr55.c | 1 | ||||
| -rw-r--r-- | drivers/usb/storage/shuttle_usbat.c | 4 | ||||
| -rw-r--r-- | drivers/usb/storage/transport.c | 71 | ||||
| -rw-r--r-- | sound/usb/usbaudio.c | 2 |
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; } |
