Commit 42003664 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/linus-2.5

into home.transmeta.com:/home/torvalds/v2.5/linux
parents 07834925 039a0ac4
......@@ -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;
......
......@@ -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
......
......@@ -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++) {
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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)
{
......
......@@ -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;
......
......@@ -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);
}
/*-------------------------------------------------------------------------*/
......
......@@ -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 *);
......@@ -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
......
......@@ -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
......
......@@ -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");
......
......@@ -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".
......@@ -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);
......
......@@ -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) },
......
......@@ -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
......
......@@ -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) {
......
......@@ -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");
......
......@@ -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
......
......@@ -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) {
......
......@@ -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();
......
......@@ -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);
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
}
......
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