Commit 039a0ac4 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge kroah.com:/home/greg/linux/BK/bleeding_edge-2.5

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 9d1f716f 2dc4da94
...@@ -1487,7 +1487,7 @@ static int irda_usb_probe(struct usb_interface *intf, ...@@ -1487,7 +1487,7 @@ static int irda_usb_probe(struct usb_interface *intf,
* specify an alternate, but very few driver do like this. * specify an alternate, but very few driver do like this.
* Jean II */ * Jean II */
ret = usb_set_interface(dev, intf->altsetting->desc.bInterfaceNumber, 0); 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) { switch (ret) {
case 0: case 0:
break; break;
......
...@@ -38,7 +38,7 @@ config USB_BLUETOOTH_TTY ...@@ -38,7 +38,7 @@ config USB_BLUETOOTH_TTY
config USB_MIDI config USB_MIDI
tristate "USB MIDI support" tristate "USB MIDI support"
depends on USB depends on USB && SOUND
---help--- ---help---
Say Y here if you want to connect a USB MIDI device to your 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 computer's USB port. This driver is for devices that comply with
......
...@@ -751,7 +751,7 @@ static int proc_submiturb(struct dev_state *ps, void *arg) ...@@ -751,7 +751,7 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
struct async *as; struct async *as;
struct usb_ctrlrequest *dr = NULL; struct usb_ctrlrequest *dr = NULL;
unsigned int u, totlen, isofrmlen; unsigned int u, totlen, isofrmlen;
int ret; int ret, interval = 0;
if (copy_from_user(&uurb, arg, sizeof(uurb))) if (copy_from_user(&uurb, arg, sizeof(uurb)))
return -EFAULT; return -EFAULT;
...@@ -838,6 +838,9 @@ static int proc_submiturb(struct dev_state *ps, void *arg) ...@@ -838,6 +838,9 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
case USBDEVFS_URB_TYPE_INTERRUPT: case USBDEVFS_URB_TYPE_INTERRUPT:
uurb.number_of_packets = 0; 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) if (uurb.buffer_length > 16384)
return -EINVAL; return -EINVAL;
if (!access_ok((uurb.endpoint & USB_DIR_IN) ? VERIFY_WRITE : VERIFY_READ, uurb.buffer, uurb.buffer_length)) 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) ...@@ -869,6 +872,7 @@ static int proc_submiturb(struct dev_state *ps, void *arg)
as->urb->setup_packet = (unsigned char*)dr; as->urb->setup_packet = (unsigned char*)dr;
as->urb->start_frame = uurb.start_frame; as->urb->start_frame = uurb.start_frame;
as->urb->number_of_packets = uurb.number_of_packets; as->urb->number_of_packets = uurb.number_of_packets;
as->urb->interval = interval;
as->urb->context = as; as->urb->context = as;
as->urb->complete = async_completed; as->urb->complete = async_completed;
for (totlen = u = 0; u < uurb.number_of_packets; u++) { for (totlen = u = 0; u < uurb.number_of_packets; u++) {
......
...@@ -77,6 +77,7 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */ ...@@ -77,6 +77,7 @@ struct usb_hcd { /* usb_bus.hcpriv points to this */
/* a few non-PCI controllers exist, mostly for OHCI */ /* a few non-PCI controllers exist, mostly for OHCI */
struct pci_dev *pdev; /* pci is typical */ struct pci_dev *pdev; /* pci is typical */
struct device *parent; /* parent device driver */
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
int region; /* pci region for regs */ int region; /* pci region for regs */
u32 pci_state [16]; /* for PM state save */ u32 pci_state [16]; /* for PM state save */
......
...@@ -394,15 +394,14 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed) ...@@ -394,15 +394,14 @@ show_list (struct ohci_hcd *ohci, char *buf, size_t count, struct ed *ed)
static ssize_t static ssize_t
show_async (struct device *dev, char *buf, size_t count, loff_t off) show_async (struct device *dev, char *buf, size_t count, loff_t off)
{ {
struct pci_dev *pdev;
struct ohci_hcd *ohci; struct ohci_hcd *ohci;
size_t temp; size_t temp;
unsigned long flags; unsigned long flags;
if (off != 0) if (off != 0)
return 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 */ /* display control and bulk lists together, for simplicity */
spin_lock_irqsave (&ohci->lock, flags); spin_lock_irqsave (&ohci->lock, flags);
...@@ -420,7 +419,6 @@ static DEVICE_ATTR (async, S_IRUGO, show_async, NULL); ...@@ -420,7 +419,6 @@ static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
static ssize_t static ssize_t
show_periodic (struct device *dev, char *buf, size_t count, loff_t off) show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
{ {
struct pci_dev *pdev;
struct ohci_hcd *ohci; struct ohci_hcd *ohci;
struct ed **seen, *ed; struct ed **seen, *ed;
unsigned long flags; unsigned long flags;
...@@ -434,8 +432,7 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off) ...@@ -434,8 +432,7 @@ show_periodic (struct device *dev, char *buf, size_t count, loff_t off)
return 0; return 0;
seen_count = 0; seen_count = 0;
pdev = container_of (dev, struct pci_dev, dev); ohci = dev_to_ohci(dev);
ohci = container_of (pci_get_drvdata (pdev), struct ohci_hcd, hcd);
next = buf; next = buf;
size = count; size = count;
...@@ -513,16 +510,16 @@ static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL); ...@@ -513,16 +510,16 @@ static DEVICE_ATTR (periodic, S_IRUGO, show_periodic, NULL);
static inline void create_debug_files (struct ohci_hcd *bus) 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.parent, &dev_attr_async);
device_create_file (&bus->hcd.pdev->dev, &dev_attr_periodic); device_create_file (bus->hcd.parent, &dev_attr_periodic);
// registers // registers
dbg ("%s: created debug files", bus->hcd.self.bus_name); dbg ("%s: created debug files", bus->hcd.self.bus_name);
} }
static inline void remove_debug_files (struct ohci_hcd *bus) 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.parent, &dev_attr_async);
device_remove_file (&bus->hcd.pdev->dev, &dev_attr_periodic); device_remove_file (bus->hcd.parent, &dev_attr_periodic);
} }
#else /* empty stubs for creating those files */ #else /* empty stubs for creating those files */
......
...@@ -29,6 +29,17 @@ ...@@ -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 static int __devinit
ohci_pci_start (struct usb_hcd *hcd) ohci_pci_start (struct usb_hcd *hcd)
{ {
......
...@@ -83,7 +83,7 @@ static int balance (struct ohci_hcd *ohci, int interval, int load) ...@@ -83,7 +83,7 @@ static int balance (struct ohci_hcd *ohci, int interval, int load)
*/ */
for (i = 0; i < interval ; i++) { for (i = 0; i < interval ; i++) {
if (branch < 0 || ohci->load [branch] > ohci->load [i]) { if (branch < 0 || ohci->load [branch] > ohci->load [i]) {
#ifdef CONFIG_USB_BANDWIDTH #if 1 /* CONFIG_USB_BANDWIDTH */
int j; int j;
/* usb 1.1 says 90% of one frame */ /* usb 1.1 says 90% of one frame */
...@@ -276,7 +276,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) ...@@ -276,7 +276,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
ohci->ed_controltail = ed->ed_prev; ohci->ed_controltail = ed->ed_prev;
if (ohci->ed_controltail) if (ohci->ed_controltail)
ohci->ed_controltail->ed_next = 0; ohci->ed_controltail->ed_next = 0;
} else { } else if (ed->ed_next) {
ed->ed_next->ed_prev = ed->ed_prev; ed->ed_next->ed_prev = ed->ed_prev;
} }
break; break;
...@@ -297,7 +297,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed) ...@@ -297,7 +297,7 @@ static void ed_deschedule (struct ohci_hcd *ohci, struct ed *ed)
ohci->ed_bulktail = ed->ed_prev; ohci->ed_bulktail = ed->ed_prev;
if (ohci->ed_bulktail) if (ohci->ed_bulktail)
ohci->ed_bulktail->ed_next = 0; ohci->ed_bulktail->ed_next = 0;
} else { } else if (ed->ed_next) {
ed->ed_next->ed_prev = ed->ed_prev; ed->ed_next->ed_prev = ed->ed_prev;
} }
break; break;
......
...@@ -27,6 +27,14 @@ extern int usb_disabled(void); ...@@ -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) static void sa1111_start_hc(struct sa1111_dev *dev)
{ {
unsigned int usb_rst = 0; unsigned int usb_rst = 0;
...@@ -120,7 +128,7 @@ static void usb_hcd_sa1111_hcim_irq (int irq, void *__hcd, struct pt_regs * r) ...@@ -120,7 +128,7 @@ static void usb_hcd_sa1111_hcim_irq (int irq, void *__hcd, struct pt_regs * r)
} }
#endif #endif
usb_hcd_irq(irq, __hcd, r); usb_hcd_irq(irq, hcd, r);
} }
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -400,3 +400,4 @@ struct ohci_hcd { ...@@ -400,3 +400,4 @@ struct ohci_hcd {
#define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd) #define hcd_to_ohci(hcd_ptr) container_of(hcd_ptr, struct ohci_hcd, hcd)
struct ohci_hcd *dev_to_ohci(struct device *);
...@@ -840,7 +840,7 @@ probe_scanner(struct usb_interface *intf, ...@@ -840,7 +840,7 @@ probe_scanner(struct usb_interface *intf,
struct usb_device *dev = interface_to_usbdev (intf); struct usb_device *dev = interface_to_usbdev (intf);
struct scn_usb_data *scn; struct scn_usb_data *scn;
struct usb_host_interface *interface; struct usb_host_interface *interface;
struct usb_endpoint_descriptor *endpoint; struct usb_host_endpoint *endpoint;
int ep_cnt; int ep_cnt;
int ix; int ix;
...@@ -911,7 +911,7 @@ probe_scanner(struct usb_interface *intf, ...@@ -911,7 +911,7 @@ probe_scanner(struct usb_interface *intf,
} }
interface = intf->altsetting; interface = intf->altsetting;
endpoint = &interface->endpoint[0].desc; endpoint = &interface->endpoint[0];
/* /*
* Start checking for two bulk endpoints OR two bulk endpoints *and* one * Start checking for two bulk endpoints OR two bulk endpoints *and* one
......
...@@ -211,10 +211,10 @@ static struct usb_device_id scanner_device_ids [] = { ...@@ -211,10 +211,10 @@ static struct usb_device_id scanner_device_ids [] = {
MODULE_DEVICE_TABLE (usb, 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(ep) ((ep).desc.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_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).bEndpointAddress & USB_ENDPOINT_DIR_MASK) == USB_DIR_OUT) #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).bmAttributes == USB_ENDPOINT_XFER_INT ? 1 : 0) #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 #define USB_SCN_MINOR(X) minor((X)->i_rdev) - SCN_BASE_MNR
......
...@@ -761,23 +761,19 @@ vicam_open(struct inode *inode, struct file *file) ...@@ -761,23 +761,19 @@ vicam_open(struct inode *inode, struct file *file)
return -EBUSY; return -EBUSY;
} }
if (!cam->raw_image) {
cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL); cam->raw_image = kmalloc(VICAM_MAX_READ_SIZE, GFP_KERNEL);
if (!cam->raw_image) { if (!cam->raw_image) {
up(&cam->busy_lock); up(&cam->busy_lock);
return -ENOMEM; return -ENOMEM;
} }
}
if (!cam->framebuf) { cam->framebuf = rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
cam->framebuf =
rvmalloc(VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
if (!cam->framebuf) { if (!cam->framebuf) {
kfree(cam->raw_image); kfree(cam->raw_image);
up(&cam->busy_lock); up(&cam->busy_lock);
return -ENOMEM; return -ENOMEM;
} }
}
// First upload firmware, then turn the camera on // First upload firmware, then turn the camera on
if (!cam->is_initialized) { if (!cam->is_initialized) {
...@@ -805,6 +801,9 @@ vicam_close(struct inode *inode, struct file *file) ...@@ -805,6 +801,9 @@ vicam_close(struct inode *inode, struct file *file)
DBG("close\n"); DBG("close\n");
set_camera_power(cam, 0); set_camera_power(cam, 0);
kfree(cam->raw_image);
rvfree(cam->framebuf, VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
cam->open_count--; cam->open_count--;
return 0; return 0;
...@@ -989,6 +988,7 @@ vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos ) ...@@ -989,6 +988,7 @@ vicam_read( struct file *file, char *buf, size_t count, loff_t *ppos )
if (*ppos >= VICAM_MAX_FRAME_SIZE) { if (*ppos >= VICAM_MAX_FRAME_SIZE) {
*ppos = 0; *ppos = 0;
up(&cam->busy_lock);
return 0; return 0;
} }
...@@ -1038,15 +1038,6 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma) ...@@ -1038,15 +1038,6 @@ vicam_mmap(struct file *file, struct vm_area_struct *vma)
if (down_interruptible(&cam->busy_lock)) if (down_interruptible(&cam->busy_lock))
return -EINTR; 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; pos = (unsigned long)cam->framebuf;
while (size > 0) { while (size > 0) {
page = kvirt_to_pa(pos); page = kvirt_to_pa(pos);
...@@ -1319,7 +1310,6 @@ vicam_disconnect(struct usb_interface *intf) ...@@ -1319,7 +1310,6 @@ vicam_disconnect(struct usb_interface *intf)
struct vicam_camera *cam = dev_get_drvdata(&intf->dev); struct vicam_camera *cam = dev_get_drvdata(&intf->dev);
dev_set_drvdata ( &intf->dev, NULL ); dev_set_drvdata ( &intf->dev, NULL );
usb_put_dev(cam->udev);
cam->udev = NULL; cam->udev = NULL;
...@@ -1329,12 +1319,6 @@ vicam_disconnect(struct usb_interface *intf) ...@@ -1329,12 +1319,6 @@ vicam_disconnect(struct usb_interface *intf)
vicam_destroy_proc_entry(cam); vicam_destroy_proc_entry(cam);
#endif #endif
if (cam->raw_image)
kfree(cam->raw_image);
if (cam->framebuf)
rvfree(cam->framebuf,
VICAM_MAX_FRAME_SIZE * VICAM_FRAMES);
kfree(cam); kfree(cam);
printk(KERN_DEBUG "ViCam-based WebCam disconnected\n"); printk(KERN_DEBUG "ViCam-based WebCam disconnected\n");
......
...@@ -99,10 +99,13 @@ config USB_SPEEDTOUCH ...@@ -99,10 +99,13 @@ config USB_SPEEDTOUCH
config USB_TEST config USB_TEST
tristate "USB testing driver (DEVELOPMENT)" tristate "USB testing driver (DEVELOPMENT)"
depends on USB_DEVICEFS && EXPERIMENTAL depends on USB && USB_DEVICEFS && EXPERIMENTAL
help help
This driver is for testing host controller software. It is used This driver is for testing host controller software. It is used
with specialized device firmware for regression and stress testing, 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".
...@@ -51,14 +51,10 @@ struct usbtest_info { ...@@ -51,14 +51,10 @@ struct usbtest_info {
}; };
/* this is accessed only through usbfs ioctl calls. /* 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. * tests create other threads if they need them.
* urbs and buffers are allocated dynamically, * urbs and buffers are allocated dynamically,
* and data generated deterministically. * 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 usbtest_dev {
struct usb_interface *intf; struct usb_interface *intf;
...@@ -66,6 +62,7 @@ struct usbtest_dev { ...@@ -66,6 +62,7 @@ struct usbtest_dev {
char id [32]; char id [32];
int in_pipe; int in_pipe;
int out_pipe; int out_pipe;
struct semaphore sem;
#define TBUF_SIZE 256 #define TBUF_SIZE 256
u8 *buf; u8 *buf;
...@@ -282,6 +279,10 @@ static int perform_sglist ( ...@@ -282,6 +279,10 @@ static int perform_sglist (
* or remote wakeup (which needs human interaction). * 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) static int get_altsetting (struct usbtest_dev *dev)
{ {
struct usb_interface *iface = dev->intf; struct usb_interface *iface = dev->intf;
...@@ -366,13 +367,11 @@ static int is_good_config (char *buf, int len) ...@@ -366,13 +367,11 @@ static int is_good_config (char *buf, int len)
case USB_DT_OTHER_SPEED_CONFIG: case USB_DT_OTHER_SPEED_CONFIG:
if (config->bLength != 9) if (config->bLength != 9)
return 0; return 0;
#if 0
/* this bit 'must be 1' but often isn't */ /* 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"); dbg ("high bit of config attributes not set");
return 0; return 0;
} }
#endif
if (config->bmAttributes & 0x1f) /* reserved == 0 */ if (config->bmAttributes & 0x1f) /* reserved == 0 */
return 0; return 0;
break; break;
...@@ -424,7 +423,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) ...@@ -424,7 +423,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
} }
/* [real world] get/set unimplemented if there's only one */ /* [real world] get/set unimplemented if there's only one */
if (iface->num_altsetting == 1) if (realworld && iface->num_altsetting == 1)
continue; continue;
/* [9.4.10] set_interface */ /* [9.4.10] set_interface */
...@@ -446,7 +445,7 @@ static int ch9_postconfig (struct usbtest_dev *dev) ...@@ -446,7 +445,7 @@ static int ch9_postconfig (struct usbtest_dev *dev)
} }
/* [real world] get_config unimplemented if there's only one */ /* [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; int expected = udev->actconfig->desc.bConfigurationValue;
/* [9.4.2] get_configuration always works /* [9.4.2] get_configuration always works
...@@ -454,7 +453,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) ...@@ -454,7 +453,8 @@ static int ch9_postconfig (struct usbtest_dev *dev)
* won't return config descriptors except before set_config. * won't return config descriptors except before set_config.
*/ */
retval = usb_control_msg (udev, usb_rcvctrlpipe (udev, 0), 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); 0, 0, dev->buf, 1, HZ * USB_CTRL_GET_TIMEOUT);
if (retval != 1 || dev->buf [0] != expected) { if (retval != 1 || dev->buf [0] != expected) {
dbg ("%s get config --> %d (%d)", dev->id, retval, dbg ("%s get config --> %d (%d)", dev->id, retval,
...@@ -563,7 +563,8 @@ static int ch9_postconfig (struct usbtest_dev *dev) ...@@ -563,7 +563,8 @@ static int ch9_postconfig (struct usbtest_dev *dev)
* threads and request completion. * 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 usbtest_dev *dev = dev_get_drvdata (&intf->dev);
struct usb_device *udev = testdev_to_usbdev (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 ...@@ -584,6 +585,9 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
|| param->sglen < 0 || param->vary < 0) || param->sglen < 0 || param->vary < 0)
return -EINVAL; return -EINVAL;
if (down_interruptible (&dev->sem))
return -ERESTARTSYS;
/* some devices, like ez-usb default devices, need a non-default /* some devices, like ez-usb default devices, need a non-default
* altsetting to have any active endpoints. some tests change * altsetting to have any active endpoints. some tests change
* altsettings; force a default so most tests don't need to check. * 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 ...@@ -591,12 +595,15 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b
if (dev->info->alt >= 0) { if (dev->info->alt >= 0) {
int res; int res;
if (intf->altsetting->desc.bInterfaceNumber) if (intf->altsetting->desc.bInterfaceNumber) {
up (&dev->sem);
return -ENODEV; return -ENODEV;
}
res = set_altsetting (dev, dev->info->alt); res = set_altsetting (dev, dev->info->alt);
if (res) { if (res) {
err ("%s: set altsetting to %d failed, %d", err ("%s: set altsetting to %d failed, %d",
dev->id, dev->info->alt, res); dev->id, dev->info->alt, res);
up (&dev->sem);
return res; return res;
} }
} }
...@@ -770,6 +777,7 @@ static int usbtest_ioctl (struct usb_interface *intf, unsigned int code, void *b ...@@ -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_usec += 1000 * 1000;
param->duration.tv_sec -= 1; param->duration.tv_sec -= 1;
} }
up (&dev->sem);
return retval; return retval;
} }
...@@ -819,6 +827,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) ...@@ -819,6 +827,7 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id)
memset (dev, 0, sizeof *dev); memset (dev, 0, sizeof *dev);
info = (struct usbtest_info *) id->driver_info; info = (struct usbtest_info *) id->driver_info;
dev->info = info; dev->info = info;
init_MUTEX (&dev->sem);
/* use the same kind of id the hid driver shows */ /* use the same kind of id the hid driver shows */
snprintf (dev->id, sizeof dev->id, "%s-%s:%d", snprintf (dev->id, sizeof dev->id, "%s-%s:%d",
...@@ -874,6 +883,8 @@ static void usbtest_disconnect (struct usb_interface *intf) ...@@ -874,6 +883,8 @@ static void usbtest_disconnect (struct usb_interface *intf)
{ {
struct usbtest_dev *dev = dev_get_drvdata (&intf->dev); struct usbtest_dev *dev = dev_get_drvdata (&intf->dev);
down (&dev->sem);
dev_set_drvdata (&intf->dev, 0); dev_set_drvdata (&intf->dev, 0);
info ("unbound %s", dev->id); info ("unbound %s", dev->id);
kfree (intf->private_data); kfree (intf->private_data);
......
...@@ -185,6 +185,7 @@ static struct usb_device_id id_table [] = { ...@@ -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_I705_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_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(PALM_VENDOR_ID, PALM_ZIRE_ID) },
{ USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) }, { USB_DEVICE(HANDSPRING_VENDOR_ID, HANDSPRING_VISOR_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
...@@ -207,6 +208,7 @@ static struct usb_device_id id_table_combined [] = { ...@@ -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_I705_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) },
{ USB_DEVICE(PALM_VENDOR_ID, PALM_M130_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(PALM_VENDOR_ID, PALM_ZIRE_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_3_5_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) }, { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_4_0_ID) },
......
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#define PALM_I705_ID 0x0020 #define PALM_I705_ID 0x0020
#define PALM_M125_ID 0x0040 #define PALM_M125_ID 0x0040
#define PALM_M130_ID 0x0050 #define PALM_M130_ID 0x0050
#define PALM_TUNGSTEN_T_ID 0x0060
#define PALM_ZIRE_ID 0x0070 #define PALM_ZIRE_ID 0x0070
#define SONY_VENDOR_ID 0x054C #define SONY_VENDOR_ID 0x054C
......
...@@ -520,7 +520,6 @@ int datafab_transport(Scsi_Cmnd * srb, struct us_data *us) ...@@ -520,7 +520,6 @@ int datafab_transport(Scsi_Cmnd * srb, struct us_data *us)
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
}; };
srb->resid = 0;
if (!us->extra) { if (!us->extra) {
us->extra = kmalloc(sizeof(struct datafab_info), GFP_NOIO); us->extra = kmalloc(sizeof(struct datafab_info), GFP_NOIO);
if (!us->extra) { if (!us->extra) {
......
...@@ -127,7 +127,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, ...@@ -127,7 +127,7 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
/* Issue the transfer command. */ /* Issue the transfer command. */
result = usb_stor_bulk_msg (us, fxfr, opipe, result = usb_stor_bulk_msg (us, fxfr, opipe,
FCM_PACKET_LENGTH, &partial); FCM_PACKET_LENGTH, &partial);
if (result != 0) { if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("Freecom readdata xpot failure: r=%d, p=%d\n", US_DEBUGP ("Freecom readdata xpot failure: r=%d, p=%d\n",
result, partial); result, partial);
...@@ -146,7 +146,9 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us, ...@@ -146,7 +146,9 @@ freecom_readdata (Scsi_Cmnd *srb, struct us_data *us,
result = usb_stor_bulk_transfer_srb(us, ipipe, srb, count); result = usb_stor_bulk_transfer_srb(us, ipipe, srb, count);
US_DEBUGP("freecom_readdata done!\n"); 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 static int
...@@ -168,7 +170,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, ...@@ -168,7 +170,7 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
/* Issue the transfer command. */ /* Issue the transfer command. */
result = usb_stor_bulk_msg (us, fxfr, opipe, result = usb_stor_bulk_msg (us, fxfr, opipe,
FCM_PACKET_LENGTH, &partial); FCM_PACKET_LENGTH, &partial);
if (result != 0) { if (result != USB_STOR_XFER_GOOD) {
US_DEBUGP ("Freecom writedata xpot failure: r=%d, p=%d\n", US_DEBUGP ("Freecom writedata xpot failure: r=%d, p=%d\n",
result, partial); result, partial);
...@@ -188,7 +190,9 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us, ...@@ -188,7 +190,9 @@ freecom_writedata (Scsi_Cmnd *srb, struct us_data *us,
result = usb_stor_bulk_transfer_srb(us, opipe, srb, count); result = usb_stor_bulk_transfer_srb(us, opipe, srb, count);
US_DEBUGP("freecom_writedata done!\n"); 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) ...@@ -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 /* The Freecom device will only fail if there is something wrong in
* USB land. It returns the status in its own registers, which * USB land. It returns the status in its own registers, which
* come back in the bulk pipe. */ * 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", US_DEBUGP ("freecom xport failure: r=%d, p=%d\n",
result, partial); result, partial);
...@@ -255,6 +259,8 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -255,6 +259,8 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("freecom_transport(): transfer aborted\n"); US_DEBUGP("freecom_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED; return USB_STOR_TRANSPORT_ABORTED;
} }
if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR;
US_DEBUG(pdump ((void *) fst, partial)); US_DEBUG(pdump ((void *) fst, partial));
...@@ -284,7 +290,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -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 * wrong in USB land. It returns the status in its own
* registers, which come back in the bulk pipe. * 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", US_DEBUGP ("freecom xport failure: r=%d, p=%d\n",
result, partial); result, partial);
...@@ -308,13 +314,14 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -308,13 +314,14 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP("freecom_transport(): transfer aborted\n"); US_DEBUGP("freecom_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED; return USB_STOR_TRANSPORT_ABORTED;
} }
if (result > USB_STOR_XFER_SHORT)
return USB_STOR_TRANSPORT_ERROR;
US_DEBUG(pdump ((void *) fst, partial)); US_DEBUG(pdump ((void *) fst, partial));
} }
if (partial != 4 || result != 0) { if (partial != 4)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
}
if ((fst->Status & 1) != 0) { if ((fst->Status & 1) != 0) {
US_DEBUGP("operation failed\n"); US_DEBUGP("operation failed\n");
return USB_STOR_TRANSPORT_FAILED; return USB_STOR_TRANSPORT_FAILED;
...@@ -369,7 +376,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -369,7 +376,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP ("freecom_transport: transfer aborted\n"); US_DEBUGP ("freecom_transport: transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED; return USB_STOR_TRANSPORT_ABORTED;
} }
if (partial != 4 || result != 0) if (partial != 4 || result > USB_STOR_XFER_SHORT)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
if ((fst->Status & ERR_STAT) != 0) { if ((fst->Status & ERR_STAT) != 0) {
US_DEBUGP("operation failed\n"); US_DEBUGP("operation failed\n");
...@@ -398,7 +405,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -398,7 +405,7 @@ int freecom_transport(Scsi_Cmnd *srb, struct us_data *us)
US_DEBUGP ("freecom_transport: transfer aborted\n"); US_DEBUGP ("freecom_transport: transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED; return USB_STOR_TRANSPORT_ABORTED;
} }
if (partial != 4 || result != 0) if (partial != 4 || result > USB_STOR_XFER_SHORT)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
if ((fst->Status & ERR_STAT) != 0) { if ((fst->Status & ERR_STAT) != 0) {
US_DEBUGP("operation failed\n"); US_DEBUGP("operation failed\n");
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
* *
* History: * 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. * 2001-02-24: Removed lots of duplicate code and simplified the structure.
* (bjorn@haxx.se) * (bjorn@haxx.se)
* 2002-01-16: Fixed endianness bug so it works on the ppc arch. * 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) ...@@ -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 * Transport routines
...@@ -546,23 +407,21 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb, ...@@ -546,23 +407,21 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
struct bulk_cb_wrap bcb; struct bulk_cb_wrap bcb;
struct bulk_cs_wrap bcs; struct bulk_cs_wrap bcs;
int result; int result;
int partial; unsigned int transfer_length;
unsigned int transfer_amount;
int dir = srb->sc_data_direction; int dir = srb->sc_data_direction;
srb->sc_data_direction = SCSI_DATA_WRITE; 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; srb->sc_data_direction = dir;
/* set up the command wrapper */ /* set up the command wrapper */
bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN); 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.Flags = srb->sc_data_direction == SCSI_DATA_READ ? 1 << 7 : 0;
bcb.Tag = srb->serial_number; bcb.Tag = srb->serial_number;
bcb.Lun = srb->cmnd[1] >> 5; bcb.Lun = srb->cmnd[1] >> 5;
if (us->flags & US_FL_SCM_MULT_TARG) if (us->flags & US_FL_SCM_MULT_TARG)
bcb.Lun |= srb->target << 4; bcb.Lun |= srb->target << 4;
bcb.Length = AtaCdbLength; bcb.Length = AtaCdbLength;
/* copy the command payload */ /* copy the command payload */
...@@ -572,33 +431,32 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb, ...@@ -572,33 +431,32 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
/* send it to out endpoint */ /* 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", 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, 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); le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
result = usb_stor_bulk_msg(us, &bcb, us->send_bulk_pipe, result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
US_BULK_CB_WRAP_LEN, &partial); (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL);
US_DEBUGP("Bulk command transfer result=%d\n", result); US_DEBUGP("Bulk command transfer result=%d\n", result);
/* did we abort this command? */ /* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
return ISD200_TRANSPORT_ABORTED; return ISD200_TRANSPORT_ABORTED;
} }
if (result != USB_STOR_XFER_GOOD)
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)
return ISD200_TRANSPORT_ERROR; return ISD200_TRANSPORT_ERROR;
/* if the command transfered well, then we go to the data stage */ /* if the command transfered well, then we go to the data stage */
if (!result && bcb.DataTransferLength) { if (transfer_length) {
isd200_transfer(us, srb); unsigned int pipe = srb->sc_data_direction == SCSI_DATA_READ ?
US_DEBUGP("Bulk data transfer result 0x%x\n", srb->result); us->recv_bulk_pipe : us->send_bulk_pipe;
result = usb_stor_bulk_transfer_srb(us, pipe, srb,
if (srb->result == ISD200_TRANSPORT_ABORTED) 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; 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 /* 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, ...@@ -607,42 +465,31 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
/* get CSW for device status */ /* get CSW for device status */
US_DEBUGP("Attempting to get CSW...\n"); US_DEBUGP("Attempting to get CSW...\n");
result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe, result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
US_BULK_CS_WRAP_LEN, &partial); (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
/* did we abort this command? */ /* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
return ISD200_TRANSPORT_ABORTED; return ISD200_TRANSPORT_ABORTED;
} }
/* did the attempt to read the CSW fail? */ /* did the attempt to read the CSW fail? */
if (result == -EPIPE) { if (result == USB_STOR_XFER_STALLED) {
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;
/* get the status again */ /* get the status again */
US_DEBUGP("Attempting to get CSW (2nd try)...\n"); US_DEBUGP("Attempting to get CSW (2nd try)...\n");
result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe, result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
US_BULK_CS_WRAP_LEN, &partial); (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
/* if the command was aborted, indicate that */ /* if the command was aborted, indicate that */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
return ISD200_TRANSPORT_ABORTED; 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 */ /* if we still have a failure at this point, we're in trouble */
US_DEBUGP("Bulk status result = %d\n", result); US_DEBUGP("Bulk status result = %d\n", result);
if (result) if (result != USB_STOR_XFER_GOOD)
return ISD200_TRANSPORT_ERROR; return ISD200_TRANSPORT_ERROR;
/* check bulk status */ /* check bulk status */
...@@ -651,7 +498,7 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb, ...@@ -651,7 +498,7 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
bcs.Residue, bcs.Status); bcs.Residue, bcs.Status);
if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) || if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) ||
bcs.Tag != bcb.Tag || bcs.Tag != bcb.Tag ||
bcs.Status > US_BULK_STAT_PHASE || partial != 13) { bcs.Status > US_BULK_STAT_PHASE) {
US_DEBUGP("Bulk logical error\n"); US_DEBUGP("Bulk logical error\n");
return ISD200_TRANSPORT_ERROR; return ISD200_TRANSPORT_ERROR;
} }
...@@ -660,6 +507,8 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb, ...@@ -660,6 +507,8 @@ int isd200_Bulk_transport( struct us_data *us, Scsi_Cmnd *srb,
switch (bcs.Status) { switch (bcs.Status) {
case US_BULK_STAT_OK: case US_BULK_STAT_OK:
/* command good -- note that we could be short on data */ /* command good -- note that we could be short on data */
if (srb->resid > 0)
return ISD200_TRANSPORT_SHORT;
return ISD200_TRANSPORT_GOOD; return ISD200_TRANSPORT_GOOD;
case US_BULK_STAT_FAIL: case US_BULK_STAT_FAIL:
...@@ -764,7 +613,8 @@ static int isd200_action( struct us_data *us, int action, ...@@ -764,7 +613,8 @@ static int isd200_action( struct us_data *us, int action,
} }
status = isd200_Bulk_transport(us, &srb, &ata, sizeof(ata.generic)); 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); US_DEBUGP(" isd200_action(0x%02x) error: %d\n",action,status);
status = ISD200_ERROR; status = ISD200_ERROR;
/* need to reset device here */ /* need to reset device here */
...@@ -815,10 +665,22 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -815,10 +665,22 @@ void isd200_invoke_transport( struct us_data *us,
{ {
int need_auto_sense = 0; int need_auto_sense = 0;
int transferStatus; int transferStatus;
int result;
/* send the command to the transport layer */ /* send the command to the transport layer */
srb->resid = 0;
transferStatus = isd200_Bulk_transport(us, srb, ataCdb, transferStatus = isd200_Bulk_transport(us, srb, ataCdb,
sizeof(ataCdb->generic)); 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) { switch (transferStatus) {
case ISD200_TRANSPORT_GOOD: case ISD200_TRANSPORT_GOOD:
...@@ -845,6 +707,7 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -845,6 +707,7 @@ void isd200_invoke_transport( struct us_data *us,
break; break;
case ISD200_TRANSPORT_SHORT: case ISD200_TRANSPORT_SHORT:
srb->result = GOOD << 1;
if (!((srb->cmnd[0] == REQUEST_SENSE) || if (!((srb->cmnd[0] == REQUEST_SENSE) ||
(srb->cmnd[0] == INQUIRY) || (srb->cmnd[0] == INQUIRY) ||
(srb->cmnd[0] == MODE_SENSE) || (srb->cmnd[0] == MODE_SENSE) ||
...@@ -861,9 +724,14 @@ void isd200_invoke_transport( struct us_data *us, ...@@ -861,9 +724,14 @@ void isd200_invoke_transport( struct us_data *us,
} }
if (need_auto_sense) if (need_auto_sense) {
if (isd200_read_regs(us) == ISD200_GOOD) 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); isd200_build_sense(us, srb);
}
/* Regardless of auto-sense, if we _know_ we have an error /* Regardless of auto-sense, if we _know_ we have an error
* condition, show that in the result code * condition, show that in the result code
......
...@@ -464,7 +464,6 @@ int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us) ...@@ -464,7 +464,6 @@ int jumpshot_transport(Scsi_Cmnd * srb, struct us_data *us)
0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00 0x00, 0x80, 0x00, 0x01, 0x1F, 0x00, 0x00, 0x00
}; };
srb->resid = 0;
if (!us->extra) { if (!us->extra) {
us->extra = kmalloc(sizeof(struct jumpshot_info), GFP_NOIO); us->extra = kmalloc(sizeof(struct jumpshot_info), GFP_NOIO);
if (!us->extra) { if (!us->extra) {
......
...@@ -1372,7 +1372,6 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -1372,7 +1372,6 @@ int sddr09_transport(Scsi_Cmnd *srb, struct us_data *us)
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
}; };
srb->resid = 0;
info = (struct sddr09_card_info *)us->extra; info = (struct sddr09_card_info *)us->extra;
if (!info) { if (!info) {
nand_init_ecc(); nand_init_ecc();
......
...@@ -746,7 +746,6 @@ int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -746,7 +746,6 @@ int sddr55_transport(Scsi_Cmnd *srb, struct us_data *us)
unsigned short pages; unsigned short pages;
struct sddr55_card_info *info; struct sddr55_card_info *info;
srb->resid = 0;
if (!us->extra) { if (!us->extra) {
us->extra = kmalloc( us->extra = kmalloc(
sizeof(struct sddr55_card_info), GFP_NOIO); sizeof(struct sddr55_card_info), GFP_NOIO);
......
...@@ -775,7 +775,6 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -775,7 +775,6 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
int i; int i;
char string[64]; char string[64];
srb->resid = 0;
len = srb->request_bufflen; len = srb->request_bufflen;
/* Send A0 (ATA PACKET COMMAND). /* Send A0 (ATA PACKET COMMAND).
...@@ -805,7 +804,8 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -805,7 +804,8 @@ int hp8200e_transport(Scsi_Cmnd *srb, struct us_data *us)
result = usbat_read(us, USBAT_ATA, 0x17, &status); result = usbat_read(us, USBAT_ATA, 0x17, &status);
US_DEBUGP("Status = %02X\n", 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) if (srb->cmnd[0] == TEST_UNIT_READY)
transferred = 0; transferred = 0;
......
...@@ -784,18 +784,20 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -784,18 +784,20 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
int result; int result;
/* send the command to the transport layer */ /* send the command to the transport layer */
srb->resid = 0;
result = us->transport(srb, us); result = us->transport(srb, us);
/* if the command gets aborted by the higher layers, we need to /* if the command gets aborted by the higher layers, we need to
* short-circuit all other processing * 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"); US_DEBUGP("-- transport indicates command was aborted\n");
srb->result = DID_ABORT << 16; srb->result = DID_ABORT << 16;
return; return;
} }
/* if there is a transport error, reset and don't auto-sense */ /* 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) { if (result == USB_STOR_TRANSPORT_ERROR) {
US_DEBUGP("-- transport indicates error, resetting\n"); US_DEBUGP("-- transport indicates error, resetting\n");
us->transport_reset(us); us->transport_reset(us);
...@@ -903,7 +905,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *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; srb->sc_data_direction = old_sc_data_direction;
memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE); 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"); US_DEBUGP("-- auto-sense aborted\n");
srb->result = DID_ABORT << 16; srb->result = DID_ABORT << 16;
return; return;
...@@ -916,6 +918,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -916,6 +918,7 @@ void usb_stor_invoke_transport(Scsi_Cmnd *srb, struct us_data *us)
* auto-sense is perfectly valid * auto-sense is perfectly valid
*/ */
if (!(us->flags & US_FL_SCM_MULT_TARG)) { if (!(us->flags & US_FL_SCM_MULT_TARG)) {
/* What if we try to abort during the reset? */
us->transport_reset(us); us->transport_reset(us);
} }
srb->result = DID_ERROR << 16; srb->result = DID_ERROR << 16;
...@@ -1293,7 +1296,6 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -1293,7 +1296,6 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
struct bulk_cs_wrap bcs; struct bulk_cs_wrap bcs;
unsigned int transfer_length = usb_stor_transfer_length(srb); unsigned int transfer_length = usb_stor_transfer_length(srb);
int result; int result;
int partial;
/* set up the command wrapper */ /* set up the command wrapper */
bcb.Signature = cpu_to_le32(US_BULK_CB_SIGN); 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) ...@@ -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", 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, le32_to_cpu(bcb.Signature), bcb.Tag,
(bcb.Lun >> 4), (bcb.Lun & 0x0F), (bcb.Lun >> 4), (bcb.Lun & 0x0F),
bcb.DataTransferLength, bcb.Flags, bcb.Length); le32_to_cpu(bcb.DataTransferLength), bcb.Flags, bcb.Length);
result = usb_stor_bulk_msg(us, &bcb, us->send_bulk_pipe, result = usb_stor_bulk_transfer_buf(us, us->send_bulk_pipe,
US_BULK_CB_WRAP_LEN, &partial); (char *) &bcb, US_BULK_CB_WRAP_LEN, NULL);
US_DEBUGP("Bulk command transfer result=%d\n", result); US_DEBUGP("Bulk command transfer result=%d\n", result);
/* did we abort this command? */ /* did we abort this command? */
...@@ -1323,23 +1325,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -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"); US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED; return USB_STOR_TRANSPORT_ABORTED;
} }
if (result != USB_STOR_XFER_GOOD)
/* 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;
}
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
} else if (result) {
/* unknown error -- we've got a problem */
return USB_STOR_TRANSPORT_ERROR;
}
/* DATA STAGE */ /* DATA STAGE */
/* send/receive data payload, if there is any */ /* send/receive data payload, if there is any */
...@@ -1363,8 +1350,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us) ...@@ -1363,8 +1350,8 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
/* get CSW for device status */ /* get CSW for device status */
US_DEBUGP("Attempting to get CSW...\n"); US_DEBUGP("Attempting to get CSW...\n");
result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe, result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
US_BULK_CS_WRAP_LEN, &partial); (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
/* did we abort this command? */ /* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { 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) ...@@ -1373,50 +1360,24 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
} }
/* did the attempt to read the CSW fail? */ /* did the attempt to read the CSW fail? */
if (result == -EPIPE) { if (result == USB_STOR_XFER_STALLED) {
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;
/* get the status again */ /* get the status again */
US_DEBUGP("Attempting to get CSW (2nd try)...\n"); US_DEBUGP("Attempting to get CSW (2nd try)...\n");
result = usb_stor_bulk_msg(us, &bcs, us->recv_bulk_pipe, result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe,
US_BULK_CS_WRAP_LEN, &partial); (char *) &bcs, US_BULK_CS_WRAP_LEN, NULL);
/* did we abort this command? */ /* did we abort this command? */
if (atomic_read(&us->sm_state) == US_STATE_ABORTING) { if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n"); US_DEBUGP("usb_stor_Bulk_transport(): transfer aborted\n");
return USB_STOR_TRANSPORT_ABORTED; 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 */ /* if we still have a failure at this point, we're in trouble */
US_DEBUGP("Bulk status result = %d\n", result); US_DEBUGP("Bulk status result = %d\n", result);
if (result) { if (result != USB_STOR_XFER_GOOD)
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
}
/* check bulk status */ /* check bulk status */
US_DEBUGP("Bulk status Sig 0x%x T 0x%x R %d Stat 0x%x\n", 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) ...@@ -1424,7 +1385,7 @@ int usb_stor_Bulk_transport(Scsi_Cmnd *srb, struct us_data *us)
bcs.Residue, bcs.Status); bcs.Residue, bcs.Status);
if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) || if (bcs.Signature != cpu_to_le32(US_BULK_CS_SIGN) ||
bcs.Tag != bcb.Tag || bcs.Tag != bcb.Tag ||
bcs.Status > US_BULK_STAT_PHASE || partial != 13) { bcs.Status > US_BULK_STAT_PHASE) {
US_DEBUGP("Bulk logical error\n"); US_DEBUGP("Bulk logical error\n");
return USB_STOR_TRANSPORT_ERROR; return USB_STOR_TRANSPORT_ERROR;
} }
......
...@@ -1879,7 +1879,7 @@ static int snd_usb_create_streams(snd_usb_audio_t *chip, int ctrlif, ...@@ -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 || if (iface->altsetting[0].desc.bInterfaceClass != USB_CLASS_AUDIO ||
iface->altsetting[0].desc.bInterfaceSubClass != USB_SUBCLASS_AUDIO_STREAMING) { 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 */ /* skip non-supported classes */
continue; continue;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment