diff options
Diffstat (limited to 'drivers')
40 files changed, 719 insertions, 1023 deletions
diff --git a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c index 9fc03736202a..435a79216eca 100644 --- a/drivers/usb/class/bluetty.c +++ b/drivers/usb/class/bluetty.c @@ -1320,7 +1320,8 @@ int usb_bluetooth_init(void) bluetooth_tty_driver->owner = THIS_MODULE; bluetooth_tty_driver->driver_name = "usb-bluetooth"; - bluetooth_tty_driver->name = "usb/ttub/"; + bluetooth_tty_driver->name = "ttyUB"; + bluetooth_tty_driver->devfs_name = "usb/ttub/"; bluetooth_tty_driver->major = BLUETOOTH_TTY_MAJOR; bluetooth_tty_driver->minor_start = 0; bluetooth_tty_driver->type = TTY_DRIVER_TYPE_SERIAL; diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 8c0c35eb0413..6f5c820cd57c 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -765,7 +765,8 @@ static int __init acm_init(void) return -ENOMEM; acm_tty_driver->owner = THIS_MODULE, acm_tty_driver->driver_name = "acm", - acm_tty_driver->name = "usb/acm/", + acm_tty_driver->name = "ttyACM", + acm_tty_driver->devfs_name = "usb/acm/", acm_tty_driver->major = ACM_TTY_MAJOR, acm_tty_driver->minor_start = 0, acm_tty_driver->type = TTY_DRIVER_TYPE_SERIAL, diff --git a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c index 6a29530146da..989325fbc736 100644 --- a/drivers/usb/class/usblp.c +++ b/drivers/usb/class/usblp.c @@ -359,7 +359,6 @@ static int usblp_open(struct inode *inode, struct file *file) file->private_data = usblp; usblp->writeurb->transfer_buffer_length = 0; - usblp->writeurb->status = 0; usblp->wcomplete = 1; /* we begin writeable */ usblp->rcomplete = 0; @@ -833,22 +832,15 @@ static int usblp_probe(struct usb_interface *intf, init_waitqueue_head(&usblp->wait); usblp->ifnum = intf->altsetting->desc.bInterfaceNumber; - retval = usb_register_dev(intf, &usblp_class); - if (retval) { - err("Not able to get a minor for this device."); - goto abort; - } - usblp->minor = intf->minor; - usblp->writeurb = usb_alloc_urb(0, GFP_KERNEL); if (!usblp->writeurb) { err("out of memory"); - goto abort_minor; + goto abort; } usblp->readurb = usb_alloc_urb(0, GFP_KERNEL); if (!usblp->readurb) { err("out of memory"); - goto abort_minor; + goto abort; } /* Malloc device ID string buffer to the largest expected length, @@ -856,7 +848,7 @@ static int usblp_probe(struct usb_interface *intf, * could change in length. */ if (!(usblp->device_id_string = kmalloc(USBLP_DEVICE_ID_SIZE, GFP_KERNEL))) { err("out of memory for device_id_string"); - goto abort_minor; + goto abort; } usblp->writebuf = usblp->readbuf = NULL; @@ -868,19 +860,19 @@ static int usblp_probe(struct usb_interface *intf, if (!(usblp->writebuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE, GFP_KERNEL, &usblp->writeurb->transfer_dma))) { err("out of memory for write buf"); - goto abort_minor; + goto abort; } if (!(usblp->readbuf = usb_buffer_alloc(dev, USBLP_BUF_SIZE, GFP_KERNEL, &usblp->readurb->transfer_dma))) { err("out of memory for read buf"); - goto abort_minor; + goto abort; } /* Allocate buffer for printer status */ usblp->statusbuf = kmalloc(STATUS_BUF_SIZE, GFP_KERNEL); if (!usblp->statusbuf) { err("out of memory for statusbuf"); - goto abort_minor; + goto abort; } /* Lookup quirks for this printer. */ @@ -894,12 +886,12 @@ static int usblp_probe(struct usb_interface *intf, dbg("incompatible printer-class device 0x%4.4X/0x%4.4X", dev->descriptor.idVendor, dev->descriptor.idProduct); - goto abort_minor; + goto abort; } /* Setup the selected alternate setting and endpoints. */ if (usblp_set_protocol(usblp, protocol) < 0) - goto abort_minor; + goto abort; /* Retrieve and store the device ID string. */ usblp_cache_device_id_string(usblp); @@ -920,10 +912,17 @@ static int usblp_probe(struct usb_interface *intf, usblp->present = 1; + retval = usb_register_dev(intf, &usblp_class); + if (retval) { + err("Not able to get a minor for this device."); + goto abort_intfdata; + } + usblp->minor = intf->minor; + return 0; -abort_minor: - usb_deregister_dev(intf, &usblp_class); +abort_intfdata: + usb_set_intfdata (intf, NULL); abort: if (usblp) { if (usblp->writebuf) diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index d3fdd4df2f26..0054c7cf7a35 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -81,7 +81,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) if (!dev->irq) { err ("Found HC with no IRQ. Check BIOS/PCI %s setup!", - dev->slot_name); + pci_name(dev)); return -ENODEV; } @@ -99,7 +99,7 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id) retval = -EFAULT; clean_1: release_mem_region (resource, len); - err ("init %s fail, %d", dev->slot_name, retval); + err ("init %s fail, %d", pci_name(dev), retval); return retval; } @@ -136,7 +136,7 @@ clean_2: goto clean_1; } else { release_region (resource, len); - err ("init %s fail, %d", dev->slot_name, retval); + err ("init %s fail, %d", pci_name(dev), retval); return retval; } } @@ -144,7 +144,7 @@ clean_2: hcd->driver = driver; hcd->description = driver->description; hcd->pdev = dev; - hcd->self.bus_name = dev->slot_name; + hcd->self.bus_name = pci_name(dev); hcd->product_desc = dev->dev.name; hcd->self.controller = &dev->dev; hcd->controller = hcd->self.controller; @@ -279,6 +279,7 @@ EXPORT_SYMBOL (usb_hcd_pci_remove); /** * usb_hcd_pci_suspend - power management suspend of a PCI-based HCD * @dev: USB Host Controller being suspended + * @state: state that the controller is going into * * Store this function in the HCD's struct pci_driver as suspend(). */ diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 8b1dec33a535..4f4b91de00db 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1293,7 +1293,8 @@ rescan: } /* then kill any current requests */ - spin_lock_irqsave (&hcd_data_lock, flags); + local_irq_save (flags); + spin_lock (&hcd_data_lock); list_for_each_entry (urb, &dev->urb_list, urb_list) { int tmp = urb->pipe; @@ -1311,13 +1312,13 @@ rescan: if (urb->status != -EINPROGRESS) continue; usb_get_urb (urb); - spin_unlock_irqrestore (&hcd_data_lock, flags); + spin_unlock (&hcd_data_lock); - spin_lock_irqsave (&urb->lock, flags); + spin_lock (&urb->lock); tmp = urb->status; if (tmp == -EINPROGRESS) urb->status = -ESHUTDOWN; - spin_unlock_irqrestore (&urb->lock, flags); + spin_unlock (&urb->lock); /* kick hcd unless it's already returning this */ if (tmp == -EINPROGRESS) { @@ -1340,7 +1341,8 @@ rescan: /* list contents may have changed */ goto rescan; } - spin_unlock_irqrestore (&hcd_data_lock, flags); + spin_unlock (&hcd_data_lock); + local_irq_restore (flags); /* synchronize with the hardware, so old configuration state * clears out immediately (and will be freed). diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 2885522a971e..f359960983f9 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -80,6 +80,23 @@ static struct device_driver usb_generic_driver = { static int usb_generic_driver_data; +/* deallocate hcd/hardware state ... and nuke all pending urbs */ +static void nuke_urbs(struct usb_device *dev) +{ + void (*disable)(struct usb_device *, int); + int i; + + if (!dev || !dev->bus || !dev->bus->op || !dev->bus->op->disable) + return; + dbg("nuking urbs assigned to %s", dev->dev.bus_id); + + disable = dev->bus->op->disable; + for (i = 0; i < 15; i++) { + disable(dev, i); + disable(dev, USB_DIR_IN | i); + } +} + /* needs to be called with BKL held */ int usb_device_probe(struct device *dev) { @@ -116,6 +133,9 @@ int usb_device_remove(struct device *dev) down(&driver->serialize); + /* release all urbs for this device */ + nuke_urbs(interface_to_usbdev(intf)); + if (intf->driver && intf->driver->disconnect) intf->driver->disconnect(intf); @@ -896,6 +916,9 @@ void usb_disconnect(struct usb_device **pdev) usb_disconnect(child); } + /* deallocate hcd/hardware state ... and nuke all pending urbs */ + nuke_urbs(dev); + /* disconnect() drivers from interfaces (a key side effect) */ dev_dbg (&dev->dev, "unregistering interfaces\n"); if (dev->actconfig) { @@ -908,16 +931,6 @@ void usb_disconnect(struct usb_device **pdev) } } - /* deallocate hcd/hardware state */ - if (ops->disable) { - void (*disable)(struct usb_device *, int) = ops->disable; - - for (i = 0; i < 15; i++) { - disable (dev, i); - disable (dev, USB_DIR_IN | i); - } - } - dev_dbg (&dev->dev, "unregistering device\n"); /* Free the device number and remove the /proc/bus/usb entry */ if (dev->devnum > 0) { diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c index e6a5af58ecde..9f2cfa519ca2 100644 --- a/drivers/usb/gadget/ether.c +++ b/drivers/usb/gadget/ether.c @@ -1,5 +1,5 @@ /* - * ether.c -- CDC 1.1 Ethernet gadget driver + * ether.c -- Ethernet gadget driver, with CDC and non-CDC options * * Copyright (C) 2003 David Brownell * @@ -58,21 +58,23 @@ /*-------------------------------------------------------------------------*/ /* - * "Communications Device Class" (CDC) Ethernet class driver + * Ethernet gadget driver -- with CDC and non-CDC options * * CDC Ethernet is the standard USB solution for sending Ethernet frames * using USB. Real hardware tends to use the same framing protocol but look * different for control features. And Microsoft pushes their own approach * (RNDIS) instead of the standard. + * + * There's some hardware that can't talk CDC. We make that hardware + * implement a "minimalist" vendor-agnostic CDC core: same framing, but + * link-level setup only requires activating the configuration. */ -#define DRIVER_DESC "CDC Ethernet Gadget" -#define DRIVER_VERSION "29 April 2003" +#define DRIVER_DESC "Ethernet Gadget" +#define DRIVER_VERSION "Bastille Day 2003" static const char shortname [] = "ether"; static const char driver_desc [] = DRIVER_DESC; -static const char control_name [] = "Communications Control"; -static const char data_name [] = "CDC Ethernet Data"; #define MIN_PACKET sizeof(struct ethhdr) #define MAX_PACKET ETH_DATA_LEN /* biggest packet we'll rx/tx */ @@ -92,8 +94,7 @@ struct eth_dev { const struct usb_endpoint_descriptor *in, *out, *status; - struct semaphore mutex; - struct net_device net; + struct net_device *net; struct net_device_stats stats; atomic_t tx_qlen; @@ -112,7 +113,7 @@ struct eth_dev { static unsigned qmult = 4; -#define HS_FACTOR 15 +#define HS_FACTOR 5 #define qlen(gadget) \ (qmult*((gadget->speed == USB_SPEED_HIGH) ? HS_FACTOR : 1)) @@ -128,7 +129,7 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR); /* Thanks to NetChip Technologies for donating this product ID. * - * DO NOT REUSE THESE IDs with any other driver!! Ever!! + * DO NOT REUSE THESE IDs with a protocol-incompatible driver!! Ever!! * Instead: allocate your own, using normal USB-IF procedures. */ #define DRIVER_VENDOR_NUM 0x0525 /* NetChip */ @@ -158,6 +159,11 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR); * for some reason doesn't handle full speed bulk maxpacket of 64. */ +#define DEV_CONFIG_VALUE 3 /* some hardware cares */ + +/* #undef on hardware that can't implement CDC */ +#define DEV_CONFIG_CDC + /* * NetChip 2280, PCI based. * @@ -172,7 +178,7 @@ module_param (qmult, uint, S_IRUGO|S_IWUSR); #define DRIVER_VERSION_NUM 0x0101 #define EP0_MAXPACKET 64 static const char EP_OUT_NAME [] = "ep-a"; -#define EP_OUT_NUM 2 +#define EP_OUT_NUM 1 static const char EP_IN_NAME [] = "ep-b"; #define EP_IN_NUM 2 static const char EP_STATUS_NAME [] = "ep-f"; @@ -194,22 +200,21 @@ static inline void hw_optimize (struct usb_gadget *gadget) #endif /* - * PXA-250 UDC: widely used in second gen Linux-capable PDAs. + * PXA-2xx UDC: widely used in second gen Linux-capable ARM PDAs + * and other products. * - * no limitations except from set_interface: docs say "no" to a third - * interface. and the interrupt-only endpoints don't toggle, so we'll - * just use a bulk-capable one instead. + * multiple interfaces (or altsettings) aren't usable. so this hardware + * can't implement CDC, which needs both capabilities. */ -#ifdef CONFIG_USB_ETH_PXA250 -#define CHIP "pxa250" +#ifdef CONFIG_USB_ETH_PXA2XX +#undef DEV_CONFIG_CDC +#define CHIP "pxa2xx" #define DRIVER_VERSION_NUM 0x0103 #define EP0_MAXPACKET 16 -static const char EP_OUT_NAME [] = "ep12out-bulk"; -#define EP_OUT_NUM 12 -static const char EP_IN_NAME [] = "ep11in-bulk"; -#define EP_IN_NUM 11 -static const char EP_STATUS_NAME [] = "ep6in-bulk"; -#define EP_STATUS_NUM 6 +static const char EP_OUT_NAME [] = "ep2out-bulk"; +#define EP_OUT_NUM 2 +static const char EP_IN_NAME [] = "ep1in-bulk"; +#define EP_IN_NUM 1 /* doesn't support bus-powered operation */ #define SELFPOWER USB_CONFIG_ATT_SELFPOWER /* supports remote wakeup, but this driver doesn't */ @@ -247,6 +252,29 @@ static const char EP_IN_NAME [] = "ep2in-bulk"; # error Configure some USB peripheral controller driver! #endif +/* We normally expect hardware that can talk CDC. That involves + * using multiple interfaces and altsettings, and maybe a status + * interrupt. Driver binding to be done according to USB-IF class, + * though you can use different VENDOR and PRODUCT numbers if you + * want (and they're officially assigned). + * + * For hardware that can't talk CDC, we use the same vendor ID that + * ARM Linux has used for ethernet-over-usb, both with sa1100 and + * with pxa250. We're protocol-compatible, if the host-side drivers + * use the endpoint descriptors. DRIVER_VERSION_NUM is nonzero, so + * drivers that need to hard-wire endpoint numbers have a hook. + */ +#ifdef DEV_CONFIG_CDC +#define DEV_CONFIG_CLASS USB_CLASS_COMM +#else +#define DEV_CONFIG_CLASS USB_CLASS_VENDOR_SPEC +#undef EP_STATUS_NUM +#undef DRIVER_VENDOR_NUM +#undef DRIVER_PRODUCT_NUM +#define DRIVER_VENDOR_NUM 0x049f +#define DRIVER_PRODUCT_NUM 0x505a +#endif /* CONFIG_CDC_ETHER */ + /* power usage is config specific. * hardware that supports remote wakeup defaults to disabling it. */ @@ -274,7 +302,8 @@ static const char EP_IN_NAME [] = "ep2in-bulk"; /*-------------------------------------------------------------------------*/ #define xprintk(d,level,fmt,args...) \ - dev_printk(level , &(d)->gadget->dev , fmt , ## args) + printk(level "%s %s: " fmt , shortname , (d)->gadget->dev.bus_id , \ + ## args) #ifdef DEBUG #undef DEBUG @@ -309,7 +338,7 @@ static const char EP_IN_NAME [] = "ep2in-bulk"; /* * DESCRIPTORS ... most are static, but strings and (full) configuration * descriptors are built on demand. Notice how most of the cdc descriptors - * add no value to simple (typical) configurations. + * aren't needed in the "minimalist" mode. */ #define STRING_MANUFACTURER 1 @@ -323,15 +352,14 @@ static const char EP_IN_NAME [] = "ep2in-bulk"; /* * This device advertises one configuration. */ -#define CONFIG_CDC_ETHER 3 - static const struct usb_device_descriptor device_desc = { .bLength = sizeof device_desc, .bDescriptorType = USB_DT_DEVICE, .bcdUSB = __constant_cpu_to_le16 (0x0200), - .bDeviceClass = USB_CLASS_COMM, + + .bDeviceClass = DEV_CONFIG_CLASS, .bDeviceSubClass = 0, .bDeviceProtocol = 0, .bMaxPacketSize0 = EP0_MAXPACKET, @@ -350,13 +378,26 @@ eth_config = { .bDescriptorType = USB_DT_CONFIG, /* compute wTotalLength on the fly */ +#ifdef DEV_CONFIG_CDC .bNumInterfaces = 2, - .bConfigurationValue = CONFIG_CDC_ETHER, +#else + .bNumInterfaces = 1, +#endif + .bConfigurationValue = DEV_CONFIG_VALUE, .iConfiguration = STRING_PRODUCT, .bmAttributes = USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP, .bMaxPower = (MAX_USB_POWER + 1) / 2, }; +#ifdef DEV_CONFIG_CDC + +/* + * Compared to the "minimalist" non-CDC model, the CDC model adds + * three class descriptors, two interface descrioptors, and a status + * endpoint. Both have a "data" interface and two bulk endpoints. + * There are also differences in how control requests are handled. + */ + /* master comm interface optionally has a status notification endpoint */ static const struct usb_interface_descriptor @@ -446,7 +487,7 @@ static const struct ether_desc ether_desc = { * some drivers (like current Linux cdc-ether!) "need" it to exist even * if they ignore the connect/disconnect notifications that real aether * can provide. more advanced cdc configurations might want to support - * encapsulated commands. + * encapsulated commands (vendor-specific, using control-OUT). */ #define LOG2_STATUS_INTERVAL_MSEC 6 @@ -494,6 +535,29 @@ data_intf = { .bInterfaceProtocol = 0, .iInterface = STRING_DATA, }; +#else + +/* + * "Minimalist" non-CDC option is a simple vendor-neutral model that most + * full speed controllers can handle: one interface, two bulk endpoints. + */ + +static const struct usb_interface_descriptor +data_intf = { + .bLength = sizeof data_intf, + .bDescriptorType = USB_DT_INTERFACE, + + .bInterfaceNumber = 0, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_CLASS_VENDOR_SPEC, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = STRING_DATA, +}; + +#endif /* DEV_CONFIG_CDC */ + static const struct usb_endpoint_descriptor fs_source_desc = { @@ -563,12 +627,12 @@ dev_qualifier = { .bDescriptorType = USB_DT_DEVICE_QUALIFIER, .bcdUSB = __constant_cpu_to_le16 (0x0200), - .bDeviceClass = USB_CLASS_VENDOR_SPEC, + .bDeviceClass = DEV_CONFIG_CLASS, /* assumes ep0 uses the same value for both speeds ... */ .bMaxPacketSize0 = EP0_MAXPACKET, - .bNumConfigurations = 2, + .bNumConfigurations = 1, }; /* maxpacket and other transfer characteristics vary by speed. */ @@ -581,16 +645,24 @@ dev_qualifier = { #endif /* !HIGHSPEED */ +/*-------------------------------------------------------------------------*/ + +/* descriptors that are built on-demand */ + +#ifdef DEV_CONFIG_CDC /* address that the host will use ... usually assigned at random */ static char ethaddr [2 * ETH_ALEN + 1]; +#endif /* static strings, in iso 8859/1 */ static struct usb_string strings [] = { { STRING_MANUFACTURER, UTS_SYSNAME " " UTS_RELEASE "/" CHIP, }, { STRING_PRODUCT, driver_desc, }, +#ifdef DEV_CONFIG_CDC { STRING_ETHADDR, ethaddr, }, - { STRING_CONTROL, control_name, }, - { STRING_DATA, data_name, }, + { STRING_CONTROL, "CDC Communications Control", }, +#endif + { STRING_DATA, "Ethernet Data", }, { } /* end of list */ }; @@ -607,14 +679,18 @@ static int config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index) { const unsigned config_len = USB_DT_CONFIG_SIZE - + 3 * USB_DT_INTERFACE_SIZE +#ifdef DEV_CONFIG_CDC + + 2 * USB_DT_INTERFACE_SIZE + sizeof header_desc + sizeof union_desc + sizeof ether_desc #ifdef EP_STATUS_NUM + USB_DT_ENDPOINT_SIZE #endif +#endif /* DEV_CONFIG_CDC */ + + USB_DT_INTERFACE_SIZE + 2 * USB_DT_ENDPOINT_SIZE; + #ifdef HIGHSPEED int hs; #endif @@ -636,6 +712,7 @@ config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index) hs = !hs; #endif +#ifdef DEV_CONFIG_CDC /* control interface, class descriptors, optional status endpoint */ memcpy (buf, &control_intf, USB_DT_INTERFACE_SIZE); buf += USB_DT_INTERFACE_SIZE; @@ -660,6 +737,7 @@ config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index) /* default data altsetting has no endpoints */ memcpy (buf, &data_nop_intf, USB_DT_INTERFACE_SIZE); buf += USB_DT_INTERFACE_SIZE; +#endif /* DEV_CONFIG_CDC */ /* the "real" data interface has two endpoints */ memcpy (buf, &data_intf, USB_DT_INTERFACE_SIZE); @@ -684,6 +762,8 @@ config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index) /*-------------------------------------------------------------------------*/ +static void eth_start (struct eth_dev *dev, int gfp_flags); + static int set_ether_config (struct eth_dev *dev, int gfp_flags) { @@ -694,7 +774,8 @@ set_ether_config (struct eth_dev *dev, int gfp_flags) gadget_for_each_ep (ep, gadget) { const struct usb_endpoint_descriptor *d; - /* NOTE: the host isn't allowed to use these two data +#ifdef DEV_CONFIG_CDC + /* With CDC, the host isn't allowed to use these two data * endpoints in the default altsetting for the interface. * so we don't activate them yet. */ @@ -714,10 +795,11 @@ set_ether_config (struct eth_dev *dev, int gfp_flags) dev->out_ep = ep; dev->out = d; continue; + } #ifdef EP_STATUS_NUM /* optional status/notification endpoint */ - } else if (strcmp (ep->name, EP_STATUS_NAME) == 0) { + else if (strcmp (ep->name, EP_STATUS_NAME) == 0) { d = ep_desc (gadget, &hs_status_desc, &fs_status_desc); result = usb_ep_enable (ep, d); if (result == 0) { @@ -726,16 +808,57 @@ set_ether_config (struct eth_dev *dev, int gfp_flags) dev->status = d; continue; } + } #endif +#else /* !CONFIG_CDC_ETHER */ + + /* non-CDC is simpler: if the device is there, + * it's live with rx and tx endpoints. + */ + /* one endpoint writes data back IN to the host */ + if (strcmp (ep->name, EP_IN_NAME) == 0) { + d = ep_desc (gadget, &hs_source_desc, &fs_source_desc); + result = usb_ep_enable (ep, d); + if (result == 0) { + ep->driver_data = dev; + dev->in_ep = ep; + dev->in = d; + continue; + } + + /* one endpoint just reads OUT packets */ + } else if (strcmp (ep->name, EP_OUT_NAME) == 0) { + d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc); + result = usb_ep_enable (ep, d); + if (result == 0) { + ep->driver_data = dev; + dev->out_ep = ep; + dev->out = d; + continue; + } + } + +#endif /* !CONFIG_CDC_ETHER */ + /* ignore any other endpoints */ - } else + else continue; /* stop on error */ ERROR (dev, "can't enable %s, result %d\n", ep->name, result); break; } + if (!result && (!dev->in_ep || !dev->out_ep)) + result = -ENODEV; + +#ifndef DEV_CONFIG_CDC + if (result == 0) { + netif_carrier_on (dev->net); + if (netif_running (dev->net)) + eth_start (dev, GFP_ATOMIC); + } +#endif /* !CONFIG_CDC_ETHER */ if (result == 0) DEBUG (dev, "qlen %d\n", qlen (gadget)); @@ -751,8 +874,8 @@ static void eth_reset_config (struct eth_dev *dev) DEBUG (dev, "%s\n", __FUNCTION__); - netif_stop_queue (&dev->net); - netif_carrier_off (&dev->net); + netif_stop_queue (dev->net); + netif_carrier_off (dev->net); /* just disable endpoints, forcing completion of pending i/o. * all our completion handlers free their requests in this case. @@ -797,7 +920,7 @@ eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags) hw_optimize (gadget); switch (number) { - case CONFIG_CDC_ETHER: + case DEV_CONFIG_VALUE: result = set_ether_config (dev, gfp_flags); break; default: @@ -807,8 +930,6 @@ eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags) return result; } - if (!result && (!dev->in_ep || !dev->out_ep)) - result = -ENODEV; if (result) eth_reset_config (dev); else { @@ -896,6 +1017,7 @@ static void issue_start_status (struct eth_dev *dev) * FIXME ugly idiom, maybe we'd be better with just * a "cancel the whole queue" primitive since any * unlink-one primitive has way too many error modes. + * here, we "know" toggle is already clear... */ usb_ep_disable (dev->status_ep); usb_ep_enable (dev->status_ep, dev->status); @@ -953,8 +1075,6 @@ static void eth_setup_complete (struct usb_ep *ep, struct usb_request *req) */ #define CDC_SET_ETHERNET_PACKET_FILTER 0x43 /* required */ -static void eth_start (struct eth_dev *dev, int gfp_flags); - /* * The setup() callback implements all the ep0 functionality that's not * handled lower down. CDC has a number of less-common features: @@ -1018,6 +1138,17 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC); spin_unlock (&dev->lock); break; +#ifdef CONFIG_USB_ETH_PXA2XX + /* PXA UDC prevents us from using SET_INTERFACE in normal ways. + * And it hides GET_CONFIGURATION and GET_INTERFACE too. + */ + case USB_REQ_SET_INTERFACE: + spin_lock (&dev->lock); + value = eth_set_config (dev, DEV_CONFIG_VALUE, GFP_ATOMIC); + spin_unlock (&dev->lock); + break; + +#else /* hardware that that stays out of our way */ case USB_REQ_GET_CONFIGURATION: if (ctrl->bRequestType != USB_DIR_IN) break; @@ -1056,15 +1187,15 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) if (ctrl->wValue == 1) { usb_ep_enable (dev->in_ep, dev->in); usb_ep_enable (dev->out_ep, dev->out); - netif_carrier_on (&dev->net); + netif_carrier_on (dev->net); #ifdef EP_STATUS_NUM issue_start_status (dev); #endif - if (netif_running (&dev->net)) + if (netif_running (dev->net)) eth_start (dev, GFP_ATOMIC); } else { - netif_stop_queue (&dev->net); - netif_carrier_off (&dev->net); + netif_stop_queue (dev->net); + netif_carrier_off (dev->net); } value = 0; break; @@ -1079,12 +1210,14 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) /* if carrier is on, data interface is active. */ *(u8 *)req->buf = - ((ctrl->wIndex == 1) && netif_carrier_ok (&dev->net)) + ((ctrl->wIndex == 1) && netif_carrier_ok (dev->net)) ? 1 : 0, value = min (ctrl->wLength, (u16) 1); break; +#endif +#ifdef DEV_CONFIG_CDC case CDC_SET_ETHERNET_PACKET_FILTER: /* see 6.2.30: no data, wIndex = interface, * wValue = packet filter bitmap @@ -1099,6 +1232,7 @@ eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) */ value = 0; break; +#endif /* DEV_CONFIG_CDC */ default: VDEBUG (dev, @@ -1129,8 +1263,8 @@ eth_disconnect (struct usb_gadget *gadget) unsigned long flags; spin_lock_irqsave (&dev->lock, flags); - netif_stop_queue (&dev->net); - netif_carrier_off (&dev->net); + netif_stop_queue (dev->net); + netif_carrier_off (dev->net); eth_reset_config (dev); spin_unlock_irqrestore (&dev->lock, flags); @@ -1175,10 +1309,10 @@ static int eth_ethtool_ioctl (struct net_device *net, void *useraddr) memset (&info, 0, sizeof info); info.cmd = ETHTOOL_GDRVINFO; - strncpy (info.driver, shortname, sizeof info.driver); - strncpy (info.version, DRIVER_VERSION, sizeof info.version); - strncpy (info.fw_version, CHIP, sizeof info.fw_version); - strncpy (info.bus_info, dev->gadget->dev.bus_id, + strlcpy (info.driver, shortname, sizeof info.driver); + strlcpy (info.version, DRIVER_VERSION, sizeof info.version); + strlcpy (info.fw_version, CHIP, sizeof info.fw_version); + strlcpy (info.bus_info, dev->gadget->dev.bus_id, sizeof info.bus_info); if (copy_to_user (useraddr, &info, sizeof (info))) return -EFAULT; @@ -1227,7 +1361,7 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags) int retval = 0; size_t size; - size = (sizeof (struct ethhdr) + dev->net.mtu + RX_EXTRA); + size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA); if ((skb = alloc_skb (size, gfp_flags)) == 0) { DEBUG (dev, "no rx skb\n"); @@ -1241,16 +1375,9 @@ rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags) req->complete = rx_complete; req->context = skb; - if (netif_running (&dev->net)) { - retval = usb_ep_queue (dev->out_ep, req, gfp_flags); - if (retval == -ENOMEM) - defer_kevent (dev, WORK_RX_MEMORY); - if (retval) - DEBUG (dev, "%s %d\n", __FUNCTION__, retval); - } else { - DEBUG (dev, "%s stopped\n", __FUNCTION__); - retval = -ENOLINK; - } + retval = usb_ep_queue (dev->out_ep, req, gfp_flags); + if (retval == -ENOMEM) + defer_kevent (dev, WORK_RX_MEMORY); if (retval) { DEBUG (dev, "rx submit --> %d\n", retval); dev_kfree_skb_any (skb); @@ -1278,8 +1405,8 @@ static void rx_complete (struct usb_ep *ep, struct usb_request *req) break; } - skb->dev = &dev->net; - skb->protocol = eth_type_trans (skb, &dev->net); + skb->dev = dev->net; + skb->protocol = eth_type_trans (skb, dev->net); dev->stats.rx_packets++; dev->stats.rx_bytes += skb->len; @@ -1294,9 +1421,7 @@ static void rx_complete (struct usb_ep *ep, struct usb_request *req) case -ECONNRESET: // unlink case -ESHUTDOWN: // disconnect etc VDEBUG (dev, "rx shutdown, code %d\n", status); - usb_ep_free_request (dev->out_ep, req); - req = 0; - break; + goto clean; /* data overrun */ case -EOVERFLOW: @@ -1311,7 +1436,11 @@ static void rx_complete (struct usb_ep *ep, struct usb_request *req) if (skb) dev_kfree_skb_any (skb); - + if (!netif_running (dev->net)) { +clean: + usb_ep_free_request (dev->out_ep, req); + req = 0; + } if (req) rx_submit (dev, req, GFP_ATOMIC); } @@ -1323,7 +1452,7 @@ static void eth_work (void *_dev) if (test_bit (WORK_RX_MEMORY, &dev->todo)) { struct usb_request *req = 0; - if (netif_running (&dev->net)) + if (netif_running (dev->net)) req = usb_ep_alloc_request (dev->in_ep, GFP_KERNEL); else clear_bit (WORK_RX_MEMORY, &dev->todo); @@ -1342,18 +1471,25 @@ static void tx_complete (struct usb_ep *ep, struct usb_request *req) struct sk_buff *skb = req->context; struct eth_dev *dev = ep->driver_data; - if (req->status) + switch (req->status) { + default: dev->stats.tx_errors++; - else + VDEBUG (dev, "tx err %d\n", req->status); + /* FALLTHROUGH */ + case -ECONNRESET: // unlink + case -ESHUTDOWN: // disconnect etc + break; + case 0: dev->stats.tx_bytes += skb->len; + } dev->stats.tx_packets++; usb_ep_free_request (ep, req); dev_kfree_skb_any (skb); atomic_inc (&dev->tx_qlen); - if (netif_carrier_ok (&dev->net)) - netif_wake_queue (&dev->net); + if (netif_carrier_ok (dev->net)) + netif_wake_queue (dev->net); } static int eth_start_xmit (struct sk_buff *skb, struct net_device *net) @@ -1437,7 +1573,7 @@ static void eth_start (struct eth_dev *dev, int gfp_flags) /* and open the tx floodgates */ atomic_set (&dev->tx_qlen, size); - netif_wake_queue (&dev->net); + netif_wake_queue (dev->net); } static int eth_open (struct net_device *net) @@ -1445,10 +1581,8 @@ static int eth_open (struct net_device *net) struct eth_dev *dev = (struct eth_dev *) net->priv; DEBUG (dev, "%s\n", __FUNCTION__); - down (&dev->mutex); - if (netif_carrier_ok (&dev->net)) + if (netif_carrier_ok (dev->net)) eth_start (dev, GFP_KERNEL); - up (&dev->mutex); return 0; } @@ -1457,7 +1591,6 @@ static int eth_stop (struct net_device *net) struct eth_dev *dev = (struct eth_dev *) net->priv; DEBUG (dev, "%s\n", __FUNCTION__); - down (&dev->mutex); netif_stop_queue (net); DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n", @@ -1469,7 +1602,7 @@ static int eth_stop (struct net_device *net) if (dev->gadget->speed != USB_SPEED_UNKNOWN) { usb_ep_disable (dev->in_ep); usb_ep_disable (dev->out_ep); - if (netif_carrier_ok (&dev->net)) { + if (netif_carrier_ok (dev->net)) { DEBUG (dev, "host still using in/out endpoints\n"); usb_ep_enable (dev->in_ep, dev->in); usb_ep_enable (dev->out_ep, dev->out); @@ -1480,7 +1613,6 @@ static int eth_stop (struct net_device *net) #endif } - up (&dev->mutex); return 0; } @@ -1492,7 +1624,6 @@ eth_unbind (struct usb_gadget *gadget) struct eth_dev *dev = get_gadget_data (gadget); DEBUG (dev, "unbind\n"); - down (&dev->mutex); /* we've already been disconnected ... no i/o is active */ if (dev->req) { @@ -1500,15 +1631,13 @@ eth_unbind (struct usb_gadget *gadget) dev->req->buf, dev->req->dma, USB_BUFSIZ); usb_ep_free_request (gadget->ep0, dev->req); + dev->req = 0; } - unregister_netdev (&dev->net); - up (&dev->mutex); + unregister_netdev (dev->net); /* assuming we used keventd, it must quiesce too */ flush_scheduled_work (); - - kfree (dev); set_gadget_data (gadget, 0); } @@ -1517,22 +1646,24 @@ eth_bind (struct usb_gadget *gadget) { struct eth_dev *dev; struct net_device *net; + int status = -ENOMEM; +#ifdef DEV_CONFIG_CDC u8 node_id [ETH_ALEN]; /* just one upstream link at a time */ if (ethaddr [0] != 0) return -ENODEV; +#endif - dev = kmalloc (sizeof *dev, SLAB_KERNEL); - if (!dev) - return -ENOMEM; - memset (dev, 0, sizeof *dev); + net = alloc_etherdev (sizeof *dev); + if (!net) + return status; + dev = net->priv; spin_lock_init (&dev->lock); - init_MUTEX_LOCKED (&dev->mutex); INIT_WORK (&dev->work, eth_work, dev); /* network device setup */ - net = &dev->net; + dev->net = net; SET_MODULE_OWNER (net); net->priv = dev; strcpy (net->name, "usb%d"); @@ -1545,6 +1676,7 @@ eth_bind (struct usb_gadget *gadget) net->dev_addr [0] &= 0xfe; // clear multicast bit net->dev_addr [0] |= 0x02; // set local assignment bit (IEEE802) +#ifdef DEV_CONFIG_CDC /* ... another address for the host, on the other end of the * link, gets exported through CDC (see CDC spec table 41) */ @@ -1554,6 +1686,7 @@ eth_bind (struct usb_gadget *gadget) snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X", node_id [0], node_id [1], node_id [2], node_id [3], node_id [4], node_id [5]); +#endif net->change_mtu = eth_change_mtu; net->get_stats = eth_get_stats; @@ -1567,36 +1700,38 @@ eth_bind (struct usb_gadget *gadget) /* preallocate control response and buffer */ dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL); if (!dev->req) - goto enomem; + goto fail; dev->req->complete = eth_setup_complete; dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ, &dev->req->dma, GFP_KERNEL); if (!dev->req->buf) { usb_ep_free_request (gadget->ep0, dev->req); - goto enomem; + goto fail; } /* finish hookup to lower layer ... */ dev->gadget = gadget; set_gadget_data (gadget, dev); gadget->ep0->driver_data = dev; - + INFO (dev, "%s, " CHIP ", version: " DRIVER_VERSION "\n", driver_desc); +#ifdef DEV_CONFIG_CDC + INFO (dev, "CDC host enet %s\n", ethaddr); +#endif + /* two kinds of host-initiated state changes: * - iff DATA transfer is active, carrier is "on" * - tx queueing enabled if open *and* carrier is "on" */ - INFO (dev, "%s, host enet %s, version: " DRIVER_VERSION "\n", - driver_desc, ethaddr); - register_netdev (&dev->net); - netif_stop_queue (&dev->net); - netif_carrier_off (&dev->net); - - up (&dev->mutex); - return 0; - -enomem: + netif_stop_queue (dev->net); + netif_carrier_off (dev->net); + + // SET_NETDEV_DEV (dev->net, &gadget->dev); + status = register_netdev (dev->net); + if (status == 0) + return status; +fail: eth_unbind (gadget); - return -ENOMEM; + return status; } /*-------------------------------------------------------------------------*/ diff --git a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c index 15142a16cbb4..352d044e2d0c 100644 --- a/drivers/usb/gadget/net2280.c +++ b/drivers/usb/gadget/net2280.c @@ -2496,7 +2496,7 @@ static void net2280_remove (struct pci_dev *pdev) device_remove_file (&pdev->dev, &dev_attr_registers); pci_set_drvdata (pdev, 0); - INFO (dev, "unbind from pci %s\n", pdev->slot_name); + INFO (dev, "unbind from pci %s\n", pci_name(pdev)); kfree (dev); the_controller = 0; @@ -2518,7 +2518,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) * usb_gadget_driver_{register,unregister}() must change. */ if (the_controller) { - WARN (the_controller, "ignoring %s\n", pdev->slot_name); + WARN (the_controller, "ignoring %s\n", pci_name(pdev)); return -EBUSY; } @@ -2534,7 +2534,7 @@ static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id) dev->pdev = pdev; dev->gadget.ops = &net2280_ops; - strcpy (dev->gadget.dev.bus_id, pdev->slot_name); + strcpy (dev->gadget.dev.bus_id, pci_name(pdev)); strcpy (dev->gadget.dev.name, pdev->dev.name); dev->gadget.dev.parent = &pdev->dev; dev->gadget.dev.dma_mask = pdev->dev.dma_mask; diff --git a/drivers/usb/gadget/net2280.h b/drivers/usb/gadget/net2280.h index 7b9ba5c29529..34df5178b0ef 100644 --- a/drivers/usb/gadget/net2280.h +++ b/drivers/usb/gadget/net2280.h @@ -654,7 +654,7 @@ static inline void net2280_led_shutdown (struct net2280 *dev) #define xprintk(dev,level,fmt,args...) \ printk(level "%s %s: " fmt , driver_name , \ - dev->pdev->slot_name , ## args) + pci_name(dev->pdev) , ## args) #ifdef DEBUG #undef DEBUG diff --git a/drivers/usb/gadget/zero.c b/drivers/usb/gadget/zero.c index d25d52b6ff84..2d61ad56d7e5 100644 --- a/drivers/usb/gadget/zero.c +++ b/drivers/usb/gadget/zero.c @@ -92,7 +92,7 @@ /*-------------------------------------------------------------------------*/ -#define DRIVER_VERSION "19 Feb 2003" +#define DRIVER_VERSION "Bastille Day 2003" static const char shortname [] = "zero"; static const char longname [] = "Gadget Zero"; @@ -160,18 +160,18 @@ static inline void hw_optimize (struct usb_gadget *gadget) #endif /* - * PXA-250 UDC: widely used in second gen Linux-capable PDAs. + * PXA-2xx UDC: widely used in second gen Linux-capable PDAs. * * This has fifteen fixed-function full speed endpoints, and it * can support all USB transfer types. * - * It only supports three configurations (numbered 1, 2, or 3) - * with two interfaces each ... there's partial hardware support - * for set_configuration and set_interface, preventing some more - * interesting config/interface/endpoint arrangements. + * These supports three or four configurations, with fixed numbers. + * The hardware interprets SET_INTERFACE, net effect is that you + * can't use altsettings or reset the interfaces independently. + * So stick to a single interface. */ -#ifdef CONFIG_USB_ZERO_PXA250 -#define CHIP "pxa250" +#ifdef CONFIG_USB_ZERO_PXA2XX +#define CHIP "pxa2xx" #define DRIVER_VERSION_NUM 0x0103 #define EP0_MAXPACKET 16 static const char EP_OUT_NAME [] = "ep12out-bulk"; @@ -291,9 +291,12 @@ struct zero_dev { static unsigned buflen = 4096; static unsigned qlen = 32; +static unsigned pattern = 0; module_param (buflen, uint, S_IRUGO|S_IWUSR); module_param (qlen, uint, S_IRUGO|S_IWUSR); +module_param (pattern, uint, S_IRUGO|S_IWUSR); + /* * Normally the "loopback" configuration is second (index 1) so @@ -497,8 +500,8 @@ static struct usb_gadget_strings stringtab = { /* * config descriptors are also handcrafted. these must agree with code - * that sets configurations, and with code managing interface altsettings. - * other complexity may come from: + * that sets configurations, and with code managing interfaces and their + * altsettings. other complexity may come from: * * - high speed support, including "other speed config" rules * - multiple configurations @@ -506,7 +509,7 @@ static struct usb_gadget_strings stringtab = { * - embedded class or vendor-specific descriptors * * this handles high speed, and has a second config that could as easily - * have been an alternate interface setting. + * have been an alternate interface setting (on most hardware). * * NOTE: to demonstrate (and test) more USB capabilities, this driver * should include an altsetting to test interrupt transfers, including @@ -608,16 +611,29 @@ check_read_data ( struct usb_request *req ) { - int i; - - for (i = 0; i < req->actual; i++) { - if (((u8 *)req->buf) [i] != 0) { - ERROR (dev, "nonzero OUT byte from host, " - "buf [%d] = %d\n", - i, ((u8 *)req->buf) [i]); - usb_ep_set_halt (ep); - return -EINVAL; + unsigned i; + u8 *buf = req->buf; + + for (i = 0; i < req->actual; i++, buf++) { + switch (pattern) { + /* all-zeroes has no synchronization issues */ + case 0: + if (*buf == 0) + continue; + break; + /* mod63 stays in sync with short-terminated transfers, + * or otherwise when host and gadget agree on how large + * each usb transfer request should be. resync is done + * with set_interface or set_config. + */ + case 1: + if (*buf == (u8)(i % 63)) + continue; + break; } + ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf); + usb_ep_set_halt (ep); + return -EINVAL; } return 0; } @@ -629,7 +645,18 @@ reinit_write_data ( struct usb_request *req ) { - memset (req->buf, 0, req->length); + unsigned i; + u8 *buf = req->buf; + + switch (pattern) { + case 0: + memset (req->buf, 0, req->length); + break; + case 1: + for (i = 0; i < req->length; i++) + *buf++ = (u8) (i % 63); + break; + } } /* if there is only one request in the queue, there'll always be an @@ -651,10 +678,13 @@ static void source_sink_complete (struct usb_ep *ep, struct usb_request *req) break; /* this endpoint is normally active while we're configured */ + case -ECONNABORTED: /* hardware forced ep reset */ case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ VDEBUG (dev, "%s gone (%d), %d/%d\n", ep->name, status, req->actual, req->length); + if (ep == dev->out_ep) + check_read_data (dev, ep, req); free_ep_req (ep, req); return; @@ -693,6 +723,9 @@ source_sink_start_ep (struct usb_ep *ep, int gfp_flags) memset (req->buf, 0, req->length); req->complete = source_sink_complete; + if (strcmp (ep->name, EP_IN_NAME) == 0) + reinit_write_data (ep->driver_data, ep, req); + status = usb_ep_queue (ep, req, gfp_flags); if (status) { struct zero_dev *dev = ep->driver_data; @@ -801,6 +834,8 @@ static void loopback_complete (struct usb_ep *ep, struct usb_request *req) * rely on the hardware driver to clean up on disconnect or * endpoint disable. */ + case -ECONNABORTED: /* hardware forced ep reset */ + case -ECONNRESET: /* request dequeued */ case -ESHUTDOWN: /* disconnect from host */ free_ep_req (ep, req); return; @@ -905,7 +940,7 @@ static void zero_reset_config (struct zero_dev *dev) * * note that some device controller hardware will constrain what this * code can do, perhaps by disallowing more than one configuration or - * by limiting configuration choices (like the pxa250). + * by limiting configuration choices (like the pxa2xx). */ static int zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags) @@ -1046,7 +1081,8 @@ zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl) break; /* until we add altsetting support, or other interfaces, - * only 0/0 are possible. + * only 0/0 are possible. pxa2xx only supports 0/0 (poorly) + * and already killed pending endpoint I/O. */ case USB_REQ_SET_INTERFACE: if (ctrl->bRequestType != USB_RECIP_INTERFACE) diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index d00701ae90d6..8d7a0657140d 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -319,6 +319,7 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep) int epnum = ep & USB_ENDPOINT_NUMBER_MASK; unsigned long flags; struct ed *ed; + unsigned limit = 1000; /* ASSERT: any requests/urbs are being unlinked */ /* ASSERT: nobody can be submitting urbs for this any more */ @@ -337,6 +338,8 @@ rescan: ed->state = ED_IDLE; switch (ed->state) { case ED_UNLINK: /* wait for hw to finish? */ + /* major IRQ delivery trouble loses INTR_SF too... */ + WARN_ON (limit-- == 0); spin_unlock_irqrestore (&ohci->lock, flags); set_current_state (TASK_UNINTERRUPTIBLE); schedule_timeout (1); diff --git a/drivers/usb/host/ohci-q.c b/drivers/usb/host/ohci-q.c index 98116434c8e5..e44e9f931fa9 100644 --- a/drivers/usb/host/ohci-q.c +++ b/drivers/usb/host/ohci-q.c @@ -43,6 +43,16 @@ finish_urb (struct ohci_hcd *ohci, struct urb *urb, struct pt_regs *regs) spin_lock (&urb->lock); if (likely (urb->status == -EINPROGRESS)) urb->status = 0; + /* report short control reads right even though the data TD always + * has TD_R set. (much simpler, but creates the 1-td limit.) + */ + if (unlikely (urb->transfer_flags & URB_SHORT_NOT_OK) + && unlikely (usb_pipecontrol (urb->pipe)) + && urb->actual_length < urb->transfer_buffer_length + && usb_pipein (urb->pipe) + && urb->status == 0) { + urb->status = -EREMOTEIO; + } spin_unlock (&urb->lock); // what lock protects these? diff --git a/drivers/usb/host/uhci-hcd.c b/drivers/usb/host/uhci-hcd.c index 17f98168bf01..2008ce80179b 100644 --- a/drivers/usb/host/uhci-hcd.c +++ b/drivers/usb/host/uhci-hcd.c @@ -2007,19 +2007,17 @@ static int suspend_allowed(struct uhci_hcd *uhci) unsigned int io_addr = uhci->io_addr; int i; - if (!uhci->hcd.pdev || - uhci->hcd.pdev->vendor != PCI_VENDOR_ID_INTEL || - uhci->hcd.pdev->device != PCI_DEVICE_ID_INTEL_82371AB_2) + if (!uhci->hcd.pdev || uhci->hcd.pdev->vendor != PCI_VENDOR_ID_INTEL) return 1; - /* This is a 82371AB/EB/MB USB controller which has a bug that - * causes false resume indications if any port has an - * over current condition. To prevent problems, we will not - * allow a global suspend if any ports are OC. + /* Some of Intel's USB controllers have a bug that causes false + * resume indications if any port has an over current condition. + * To prevent problems, we will not allow a global suspend if + * any ports are OC. * - * Some motherboards using the 82371AB/EB/MB (but not the USB portion) - * appear to hardwire the over current inputs active to disable - * the USB ports. + * Some motherboards using Intel's chipsets (but not using all + * the USB ports) appear to hardwire the over current inputs active + * to disable the USB ports. */ /* check for over current condition on any port */ diff --git a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c index 83f8137383e4..cc1768849fcc 100644 --- a/drivers/usb/image/hpusbscsi.c +++ b/drivers/usb/image/hpusbscsi.c @@ -306,7 +306,10 @@ DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte); if(unlikely(u->status < 0)) { if (likely(hpusbscsi->state != HP_STATE_FREE)) handle_usb_error(hpusbscsi); - return; + if (u->status == -ECONNRESET || u->status == -ENOENT || u->status == -ESHUTDOWN) + return; + else + goto resub; } scsi_state = hpusbscsi->scsi_state_byte; @@ -348,6 +351,8 @@ DEBUG("Getting status byte %d \n",hpusbscsi->scsi_state_byte); TRACE_STATE; break; } +resub: + usb_submit_urb(u, GFP_ATOMIC); } static void simple_command_callback(struct urb *u, struct pt_regs *regs) @@ -427,7 +432,7 @@ static void simple_done (struct urb *u, struct pt_regs *regs) hpusbscsi->state = HP_STATE_WAIT; } else { issue_request_sense(hpusbscsi); - } + } } } else { if (likely(hpusbscsi->scallback != NULL)) diff --git a/drivers/usb/image/scanner.c b/drivers/usb/image/scanner.c index ac0546325519..d56c9ab82dc5 100644 --- a/drivers/usb/image/scanner.c +++ b/drivers/usb/image/scanner.c @@ -364,6 +364,11 @@ * Mustek, Pacific Image Electronics, Plustek, and Visioneer scanners. * Fixed names of some other scanners. * + * 0.4.14 2003-07-15 + * - Fixed race between open and probe (Oliver Neukum). + * - Added vendor/product ids for Avision, Canon, HP, Microtek and Relisys scanners. + * - Clean up irq urb when not enough memory is available. + * * TODO * - Performance * - Select/poll methods @@ -1068,6 +1073,9 @@ probe_scanner(struct usb_interface *intf, /* Ok, now initialize all the relevant values */ if (!(scn->obuf = (char *)kmalloc(OBUF_SIZE, GFP_KERNEL))) { err("probe_scanner(%d): Not enough memory for the output buffer.", intf->minor); + if (have_intr) + usb_unlink_urb(scn->scn_irq); + usb_free_urb(scn->scn_irq); kfree(scn); up(&scn_mutex); return -ENOMEM; @@ -1076,6 +1084,9 @@ probe_scanner(struct usb_interface *intf, if (!(scn->ibuf = (char *)kmalloc(IBUF_SIZE, GFP_KERNEL))) { err("probe_scanner(%d): Not enough memory for the input buffer.", intf->minor); + if (have_intr) + usb_unlink_urb(scn->scn_irq); + usb_free_urb(scn->scn_irq); kfree(scn->obuf); kfree(scn); up(&scn_mutex); @@ -1117,10 +1128,9 @@ probe_scanner(struct usb_interface *intf, info ("USB scanner device (0x%04x/0x%04x) now attached to %s", dev->descriptor.idVendor, dev->descriptor.idProduct, name); - up(&scn_mutex); - usb_set_intfdata(intf, scn); - + up(&scn_mutex); + return 0; } diff --git a/drivers/usb/image/scanner.h b/drivers/usb/image/scanner.h index 5a3db16c41b0..44a90a13f4d9 100644 --- a/drivers/usb/image/scanner.h +++ b/drivers/usb/image/scanner.h @@ -43,7 +43,7 @@ // #define DEBUG -#define DRIVER_VERSION "0.4.13" +#define DRIVER_VERSION "0.4.14" #define DRIVER_DESC "USB Scanner Driver" #include <linux/usb.h> @@ -103,6 +103,7 @@ static struct usb_device_id scanner_device_ids [] = { /* Avision */ { USB_DEVICE(0x0638, 0x0268) }, /* iVina 1200U */ { USB_DEVICE(0x0638, 0x0a10) }, /* iVina FB1600 (=Umax Astra 4500) */ + { USB_DEVICE(0x0638, 0x0a20) }, /* iVina FB1800 (=Umax Astra 4700) */ /* Benq: see Acer */ /* Brother */ { USB_DEVICE(0x04f9, 0x010f) }, /* MFC 5100C */ @@ -115,10 +116,12 @@ static struct usb_device_id scanner_device_ids [] = { { USB_DEVICE(0x04a9, 0x2206) }, /* CanoScan N650U/N656U */ { USB_DEVICE(0x04a9, 0x2207) }, /* CanoScan N1220U */ { USB_DEVICE(0x04a9, 0x2208) }, /* CanoScan D660U */ + { USB_DEVICE(0x04a9, 0x220a) }, /* CanoScan D2400UF */ { USB_DEVICE(0x04a9, 0x220b) }, /* CanoScan D646U */ { USB_DEVICE(0x04a9, 0x220c) }, /* CanoScan D1250U2 */ { USB_DEVICE(0x04a9, 0x220d) }, /* CanoScan N670U/N676U/LIDE 20 */ { USB_DEVICE(0x04a9, 0x220e) }, /* CanoScan N1240U/LIDE 30 */ + { USB_DEVICE(0x04a9, 0x220f) }, /* CanoScan 8000F */ { USB_DEVICE(0x04a9, 0x2213) }, /* LIDE 50 */ { USB_DEVICE(0x04a9, 0x3042) }, /* FS4000US */ /* Colorado -- See Primax/Colorado below */ @@ -158,6 +161,7 @@ static struct usb_device_id scanner_device_ids [] = { { USB_DEVICE(0x03f0, 0x0901) }, /* ScanJet 2300C */ { USB_DEVICE(0x03F0, 0x1005) }, /* ScanJet 5400C */ { USB_DEVICE(0x03F0, 0x1105) }, /* ScanJet 5470C */ + { USB_DEVICE(0x03f0, 0x1205) }, /* ScanJet 5550C */ { USB_DEVICE(0x03f0, 0x1305) }, /* Scanjet 4570c */ { USB_DEVICE(0x03f0, 0x1411) }, /* PSC 750 */ { USB_DEVICE(0x03f0, 0x2005) }, /* ScanJet 3570c */ @@ -173,6 +177,7 @@ static struct usb_device_id scanner_device_ids [] = { /* Memorex */ { USB_DEVICE(0x0461, 0x0346) }, /* 6136u - repackaged Primax ? */ /* Microtek */ + { USB_DEVICE(0x05da, 0x20c9) }, /* ScanMaker 6700 */ { USB_DEVICE(0x05da, 0x30ce) }, /* ScanMaker 3800 */ { USB_DEVICE(0x05da, 0x30cf) }, /* ScanMaker 4800 */ { USB_DEVICE(0x04a7, 0x0224) }, /* Scanport 3000 (actually Visioneer?)*/ @@ -250,6 +255,7 @@ static struct usb_device_id scanner_device_ids [] = { { USB_DEVICE(0x06dc, 0x0014) }, /* Winscan Pro 2448U */ /* Relisis */ // { USB_DEVICE(0x0475, 0x0103) }, /* Episode - undetected endpoint */ + { USB_DEVICE(0x0475, 0x0210) }, /* Scorpio Ultra 3 */ /* Seiko/Epson Corp. */ { USB_DEVICE(0x04b8, 0x0101) }, /* Perfection 636U and 636Photo */ { USB_DEVICE(0x04b8, 0x0102) }, /* GT-2200 */ diff --git a/drivers/usb/media/dabusb.c b/drivers/usb/media/dabusb.c index 1ba1697c6c3d..ff52028e3df5 100644 --- a/drivers/usb/media/dabusb.c +++ b/drivers/usb/media/dabusb.c @@ -721,7 +721,7 @@ static struct usb_class_driver dabusb_class = { /* --------------------------------------------------------------------- */ -static int dabusb_probe (struct usb_interface *intf, +static int dabusb_probe (struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *usbdev = interface_to_usbdev(intf); @@ -738,9 +738,7 @@ static int dabusb_probe (struct usb_interface *intf, if (intf->altsetting->desc.bInterfaceNumber != _DABUSB_IF && usbdev->descriptor.idProduct == 0x9999) return -ENODEV; - retval = usb_register_dev(intf, &dabusb_class); - if (retval) - return -ENOMEM; + s = &dabusb[intf->minor]; @@ -766,8 +764,15 @@ static int dabusb_probe (struct usb_interface *intf, } } dbg("bound to interface: %d", ifnum); - up (&s->mutex); usb_set_intfdata (intf, s); + up (&s->mutex); + + retval = usb_register_dev(intf, &dabusb_class); + if (retval) { + usb_set_intfdata (intf, NULL); + return -ENOMEM; + } + return 0; reject: diff --git a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c index 6324d7eb9e20..2d83f587e8e6 100644 --- a/drivers/usb/misc/usblcd.c +++ b/drivers/usb/misc/usblcd.c @@ -1,4 +1,4 @@ -/***************************************************************************** +/***************************************************************************** * USBLCD Kernel Driver * * See http://www.usblcd.de for Hardware and Documentation. * * Version 1.03 * @@ -18,7 +18,7 @@ #include <asm/uaccess.h> #include <linux/usb.h> -#define DRIVER_VERSION "USBLCD Driver Version 1.03" +#define DRIVER_VERSION "USBLCD Driver Version 1.04" #define USBLCD_MINOR 144 @@ -257,7 +257,7 @@ static int probe_lcd(struct usb_interface *intf, const struct usb_device_id *id) struct lcd_usb_data *lcd = &lcd_instance; int i; int retval; - + if (dev->descriptor.idProduct != 0x0001 ) { warn(KERN_INFO "USBLCD model not supported."); return -ENODEV; @@ -274,30 +274,32 @@ static int probe_lcd(struct usb_interface *intf, const struct usb_device_id *id) (i & 0xF000)>>12,(i & 0xF00)>>8,(i & 0xF0)>>4,(i & 0xF), dev->devnum); - retval = usb_register_dev(intf, &usb_lcd_class); - if (retval) { - err("Not able to get a minor for this device."); - return -ENOMEM; - } + lcd->present = 1; lcd->lcd_dev = dev; if (!(lcd->obuf = (char *) kmalloc(OBUF_SIZE, GFP_KERNEL))) { err("probe_lcd: Not enough memory for the output buffer"); - usb_deregister_dev(intf, &usb_lcd_class); return -ENOMEM; } dbg("probe_lcd: obuf address:%p", lcd->obuf); if (!(lcd->ibuf = (char *) kmalloc(IBUF_SIZE, GFP_KERNEL))) { err("probe_lcd: Not enough memory for the input buffer"); - usb_deregister_dev(intf, &usb_lcd_class); kfree(lcd->obuf); return -ENOMEM; } dbg("probe_lcd: ibuf address:%p", lcd->ibuf); + retval = usb_register_dev(intf, &usb_lcd_class); + if (retval) { + err("Not able to get a minor for this device."); + kfree(lcd->obuf); + kfree(lcd->ibuf); + return -ENOMEM; + } + usb_set_intfdata (intf, lcd); return 0; } diff --git a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c index 4d7f9a9158ea..fc8ecb6a86a7 100644 --- a/drivers/usb/misc/usbtest.c +++ b/drivers/usb/misc/usbtest.c @@ -47,6 +47,7 @@ struct usbtest_info { const char *name; u8 ep_in; /* bulk/intr source */ u8 ep_out; /* bulk/intr sink */ + unsigned autoconf : 1; int alt; }; @@ -78,6 +79,61 @@ static struct usb_device *testdev_to_usbdev (struct usbtest_dev *test) /*-------------------------------------------------------------------------*/ +static int +get_endpoints (struct usbtest_dev *dev, struct usb_interface *intf) +{ + int tmp; + struct usb_host_interface *alt; + struct usb_host_endpoint *in, *out; + struct usb_device *udev; + + for (tmp = 0; tmp < intf->max_altsetting; tmp++) { + unsigned ep; + + in = out = 0; + alt = intf->altsetting + tmp; + + /* take the first altsetting with in-bulk + out-bulk; + * ignore other endpoints and altsetttings. + */ + for (ep = 0; ep < alt->desc.bNumEndpoints; ep++) { + struct usb_host_endpoint *e; + + e = alt->endpoint + ep; + if (e->desc.bmAttributes != USB_ENDPOINT_XFER_BULK) + continue; + if (e->desc.bEndpointAddress & USB_DIR_IN) { + if (!in) + in = e; + } else { + if (!out) + out = e; + } + if (in && out) + goto found; + } + } + return -EINVAL; + +found: + udev = testdev_to_usbdev (dev); + if (alt->desc.bAlternateSetting != 0) { + tmp = usb_set_interface (udev, + alt->desc.bInterfaceNumber, + alt->desc.bAlternateSetting); + if (tmp < 0) + return tmp; + } + + dev->in_pipe = usb_rcvbulkpipe (udev, + in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + dev->out_pipe = usb_sndbulkpipe (udev, + out->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); + return 0; +} + +/*-------------------------------------------------------------------------*/ + /* Support for testing basic non-queued I/O streams. * * These just package urbs as requests that can be easily canceled. @@ -1275,14 +1331,26 @@ usbtest_probe (struct usb_interface *intf, const struct usb_device_id *id) wtest = " intr-out"; } } else { - if (info->ep_in) { - dev->in_pipe = usb_rcvbulkpipe (udev, info->ep_in); - rtest = " bulk-in"; + if (info->autoconf) { + int status; + + status = get_endpoints (dev, intf); + if (status < 0) { + dbg ("couldn't get endpoints, %d\n", status); + return status; + } + } else { + if (info->ep_in) + dev->in_pipe = usb_rcvbulkpipe (udev, + info->ep_in); + if (info->ep_out) + dev->out_pipe = usb_sndbulkpipe (udev, + info->ep_out); } - if (info->ep_out) { - dev->out_pipe = usb_sndbulkpipe (udev, info->ep_out); + if (dev->in_pipe) + rtest = " bulk-in"; + if (dev->out_pipe) wtest = " bulk-out"; - } } usb_set_intfdata (intf, dev); @@ -1336,11 +1404,6 @@ static struct usbtest_info ez2_info = { }; /* ezusb family device with dedicated usb test firmware, - * or a peripheral running Linux and 'zero.c' test firmware. - * - * FIXME usbtest should read the descriptors, since compatible - * test firmware might run on hardware (pxa250 for one) that - * can't configure an ep2in-bulk. */ static struct usbtest_info fw_info = { .name = "usb test device", @@ -1349,10 +1412,20 @@ static struct usbtest_info fw_info = { .alt = 0, }; +/* peripheral running Linux and 'zero.c' test firmware, or + * its user-mode cousin. different versions of this use + * different hardware with the same vendor/product codes. + * host side MUST rely on the endpoint descriptors. + */ +static struct usbtest_info gz_info = { + .name = "Linux gadget zero", + .autoconf = 1, + .alt = 0, +}; + static struct usbtest_info um_info = { - .name = "user mode test driver", - .ep_in = 7, - .ep_out = 3, + .name = "Linux user mode test driver", + .autoconf = 1, .alt = -1, }; @@ -1418,7 +1491,7 @@ static struct usb_device_id id_table [] = { /* "Gadget Zero" firmware runs under Linux */ { USB_DEVICE (0x0525, 0xa4a0), - .driver_info = (unsigned long) &fw_info, + .driver_info = (unsigned long) &gz_info, }, /* so does a user-mode variant */ diff --git a/drivers/usb/net/ax8817x.c b/drivers/usb/net/ax8817x.c index 574fca3d3c0c..043247446e97 100644 --- a/drivers/usb/net/ax8817x.c +++ b/drivers/usb/net/ax8817x.c @@ -1208,6 +1208,7 @@ static int ax8817x_bind(struct usb_interface *intf, net->init = ax8817x_net_init; net->priv = ax_info; + SET_NETDEV_DEV(net, &intf->dev); ret = register_netdev(net); if (ret < 0) { err("%s: Failed net init (%d)\n", __FUNCTION__, ret); diff --git a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c index d84208ebd1af..b0db6e686db6 100644 --- a/drivers/usb/net/catc.c +++ b/drivers/usb/net/catc.c @@ -936,6 +936,7 @@ static int catc_probe(struct usb_interface *intf, const struct usb_device_id *id printk("%2.2x.\n", netdev->dev_addr[i]); usb_set_intfdata(intf, catc); + SET_NETDEV_DEV(netdev, &intf->dev); if (register_netdev(netdev) != 0) { usb_set_intfdata(intf, NULL); usb_free_urb(catc->ctrl_urb); diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index f21533b6195d..a0253e49cff3 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -1123,8 +1123,9 @@ static int kaweth_probe( if (dma_supported (&intf->dev, 0xffffffffffffffffULL)) kaweth->net->features |= NETIF_F_HIGHDMA; + SET_NETDEV_DEV(netdev, &intf->dev); if (register_netdev(netdev) != 0) { - kaweth_err("Error calling init_etherdev."); + kaweth_err("Error registering netdev."); goto err_intfdata; } diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 562edd197840..b2ef52cf7522 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -1262,7 +1262,6 @@ static int pegasus_probe(struct usb_interface *intf, } set_ethernet_addr(pegasus); fill_skb_pool(pegasus); - printk("%s: %s\n", net->name, usb_dev_id[dev_index].name); if (pegasus->features & PEGASUS_II) { info("setup Pegasus II specific registers"); setup_pegasus_II(pegasus); @@ -1273,9 +1272,11 @@ static int pegasus_probe(struct usb_interface *intf, pegasus->phy = 1; } usb_set_intfdata(intf, pegasus); + SET_NETDEV_DEV(net, &intf->dev); res = register_netdev(net); if (res) goto out4; + printk("%s: %s\n", net->name, usb_dev_id[dev_index].name); return 0; out4: diff --git a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c index 5ee56eb529cf..afc88cc73d91 100644 --- a/drivers/usb/net/rtl8150.c +++ b/drivers/usb/net/rtl8150.c @@ -830,6 +830,7 @@ static int rtl8150_probe(struct usb_interface *intf, usb_set_intfdata(intf, dev); + SET_NETDEV_DEV(netdev, &intf->dev); if (register_netdev(netdev) != 0) { err("couldn't register the device"); goto out2; diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c index 6767ed2551aa..4c6479aaa40c 100644 --- a/drivers/usb/net/usbnet.c +++ b/drivers/usb/net/usbnet.c @@ -2602,7 +2602,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); - SET_NETDEV_DEV(dev->net, &dev->udev->dev); + SET_NETDEV_DEV(dev->net, &udev->dev); status = register_netdev (dev->net); if (status) goto out3; diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index c470203c26d6..693ca0850bf8 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -257,6 +257,7 @@ static struct usb_device_id id_table_8U232AM [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0, 0x3ff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0, 0x3ff) }, { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0, 0x3ff) }, @@ -321,6 +322,7 @@ static struct usb_device_id id_table_FT232BM [] = { { USB_DEVICE_VER(FTDI_VID, FTDI_XF_634_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_XF_632_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_VID, FTDI_VNHCPCUSB_D_PID, 0x400, 0xffff) }, + { USB_DEVICE_VER(FTDI_VID, FTDI_DSS20_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_1_PID, 0x400, 0xffff) }, { USB_DEVICE_VER(FTDI_MTXORB_VID, FTDI_MTXORB_2_PID, 0x400, 0xffff) }, @@ -396,6 +398,7 @@ static __devinitdata struct usb_device_id id_table_combined [] = { { USB_DEVICE(FTDI_VID, FTDI_RELAIS_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_634_PID) }, { USB_DEVICE(FTDI_VID, FTDI_XF_632_PID) }, + { USB_DEVICE(FTDI_VID, FTDI_DSS20_PID) }, { USB_DEVICE(FTDI_NF_RIC_VID, FTDI_NF_RIC_PID) }, { USB_DEVICE(FTDI_VID, FTDI_VNHCPCUSB_D_PID) }, { USB_DEVICE(FTDI_MTXORB_VID, FTDI_MTXORB_0_PID) }, diff --git a/drivers/usb/serial/ftdi_sio.h b/drivers/usb/serial/ftdi_sio.h index 9da692ce1c7f..5f09fbdcb6b8 100644 --- a/drivers/usb/serial/ftdi_sio.h +++ b/drivers/usb/serial/ftdi_sio.h @@ -105,7 +105,13 @@ #define SEALEVEL_2803_6_PID 0X2863 /* SeaLINK+8 (2803) Port 6 */ #define SEALEVEL_2803_7_PID 0X2873 /* SeaLINK+8 (2803) Port 7 */ #define SEALEVEL_2803_8_PID 0X2883 /* SeaLINK+8 (2803) Port 8 */ + +/* + * DSS-20 Sync Station for Sony Ericsson P800 + */ +#define FTDI_DSS20_PID 0xFC82 + /* * Home Electronics (www.home-electro.com) USB gadgets */ diff --git a/drivers/usb/serial/ipaq.c b/drivers/usb/serial/ipaq.c index 1e2e2b91fc30..350fb2f23b75 100644 --- a/drivers/usb/serial/ipaq.c +++ b/drivers/usb/serial/ipaq.c @@ -125,10 +125,13 @@ static struct usb_device_id ipaq_id_table [] = { { USB_DEVICE(LINKUP_VENDOR_ID, LINKUP_PRODUCT_ID) }, { USB_DEVICE(MICROSOFT_VENDOR_ID, MICROSOFT_00CE_ID) }, { USB_DEVICE(PORTATEC_VENDOR_ID, PORTATEC_PRODUCT_ID) }, + { USB_DEVICE(ROVER_VENDOR_ID, ROVER_P5_ID) }, { USB_DEVICE(SAGEM_VENDOR_ID, SAGEM_WIRELESS_ID) }, { USB_DEVICE(SOCKET_VENDOR_ID, SOCKET_PRODUCT_ID) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_PRODUCT_ID) }, + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E310_ID) }, { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E740_ID) }, + { USB_DEVICE(TOSHIBA_VENDOR_ID, TOSHIBA_E335_ID) }, { USB_DEVICE(HTC_VENDOR_ID, HTC_PRODUCT_ID) }, { USB_DEVICE(NEC_VENDOR_ID, NEC_PRODUCT_ID) }, { USB_DEVICE(ASUS_VENDOR_ID, ASUS_A600_PRODUCT_ID) }, diff --git a/drivers/usb/serial/ipaq.h b/drivers/usb/serial/ipaq.h index 79b110bef08c..c1b33d47ab7f 100644 --- a/drivers/usb/serial/ipaq.h +++ b/drivers/usb/serial/ipaq.h @@ -61,6 +61,9 @@ #define PORTATEC_VENDOR_ID 0x0961 #define PORTATEC_PRODUCT_ID 0x0010 +#define ROVER_VENDOR_ID 0x047b +#define ROVER_P5_ID 0x3000 + #define SAGEM_VENDOR_ID 0x5e04 #define SAGEM_WIRELESS_ID 0xce00 @@ -69,7 +72,9 @@ #define TOSHIBA_VENDOR_ID 0x0930 #define TOSHIBA_PRODUCT_ID 0x0700 +#define TOSHIBA_E310_ID 0x0705 #define TOSHIBA_E740_ID 0x0706 +#define TOSHIBA_E335_ID 0x0707 #define HTC_VENDOR_ID 0x0bb4 #define HTC_PRODUCT_ID 0x00ce diff --git a/drivers/usb/serial/usb-serial.c b/drivers/usb/serial/usb-serial.c index 8cc6f6fe7bb2..78b4337c86bd 100644 --- a/drivers/usb/serial/usb-serial.c +++ b/drivers/usb/serial/usb-serial.c @@ -530,7 +530,9 @@ static void serial_close(struct tty_struct *tty, struct file * filp) /* if disconnect beat us to the punch here, there's nothing to do */ if (tty && tty->driver_data) { __serial_close(port, filp); + tty->driver_data = NULL; } + port->tty = NULL; } static int serial_write (struct tty_struct * tty, int from_user, const unsigned char *buf, int count) diff --git a/drivers/usb/serial/visor.c b/drivers/usb/serial/visor.c index 71589b194762..69b53a8c6629 100644 --- a/drivers/usb/serial/visor.c +++ b/drivers/usb/serial/visor.c @@ -509,18 +509,17 @@ static void visor_write_bulk_callback (struct urb *urb, struct pt_regs *regs) { struct usb_serial_port *port = (struct usb_serial_port *)urb->context; + /* free up the transfer buffer, as usb_free_urb() does not do this */ + kfree (urb->transfer_buffer); + if (port_paranoia_check (port, __FUNCTION__)) return; dbg("%s - port %d", __FUNCTION__, port->number); - if (urb->status) { - dbg("%s - nonzero write bulk status received: %d", __FUNCTION__, urb->status); - return; - } - - /* free up the transfer buffer, as usb_free_urb() does not do this */ - kfree (urb->transfer_buffer); + if (urb->status) + dbg("%s - nonzero write bulk status received: %d", + __FUNCTION__, urb->status); schedule_work(&port->work); } diff --git a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c index 3c6e0eb49017..70b87e654e31 100644 --- a/drivers/usb/storage/isd200.c +++ b/drivers/usb/storage/isd200.c @@ -280,6 +280,7 @@ struct isd200_info { /* maximum number of LUNs supported */ unsigned char MaxLUNs; + struct scsi_cmnd srb; }; @@ -404,15 +405,15 @@ static int isd200_action( struct us_data *us, int action, void* pointer, int value ) { union ata_cdb ata; - struct scsi_cmnd srb; struct scsi_device srb_dev; struct isd200_info *info = (struct isd200_info *)us->extra; + struct scsi_cmnd *srb = &info->srb; int status; memset(&ata, 0, sizeof(ata)); - memset(&srb, 0, sizeof(srb)); memset(&srb_dev, 0, sizeof(srb_dev)); - srb.device = &srb_dev; + srb->device = &srb_dev; + ++srb->serial_number; ata.generic.SignatureByte0 = info->ConfigData.ATAMajorCommand; ata.generic.SignatureByte1 = info->ConfigData.ATAMinorCommand; @@ -425,9 +426,9 @@ static int isd200_action( struct us_data *us, int action, ata.generic.RegisterSelect = REG_CYLINDER_LOW | REG_CYLINDER_HIGH | REG_STATUS | REG_ERROR; - srb.sc_data_direction = SCSI_DATA_READ; - srb.request_buffer = pointer; - srb.request_bufflen = value; + srb->sc_data_direction = SCSI_DATA_READ; + srb->request_buffer = pointer; + srb->request_bufflen = value; break; case ACTION_ENUM: @@ -437,7 +438,7 @@ static int isd200_action( struct us_data *us, int action, ACTION_SELECT_5; ata.generic.RegisterSelect = REG_DEVICE_HEAD; ata.write.DeviceHeadByte = value; - srb.sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = SCSI_DATA_NONE; break; case ACTION_RESET: @@ -446,7 +447,7 @@ static int isd200_action( struct us_data *us, int action, ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_RESET_CONTROLLER; - srb.sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = SCSI_DATA_NONE; break; case ACTION_REENABLE: @@ -455,7 +456,7 @@ static int isd200_action( struct us_data *us, int action, ACTION_SELECT_3|ACTION_SELECT_4; ata.generic.RegisterSelect = REG_DEVICE_CONTROL; ata.write.DeviceControlByte = ATA_DC_REENABLE_CONTROLLER; - srb.sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = SCSI_DATA_NONE; break; case ACTION_SOFT_RESET: @@ -464,16 +465,16 @@ static int isd200_action( struct us_data *us, int action, ata.generic.RegisterSelect = REG_DEVICE_HEAD | REG_COMMAND; ata.write.DeviceHeadByte = info->DeviceHead; ata.write.CommandByte = WIN_SRST; - srb.sc_data_direction = SCSI_DATA_NONE; + srb->sc_data_direction = SCSI_DATA_NONE; break; case ACTION_IDENTIFY: US_DEBUGP(" isd200_action(IDENTIFY)\n"); ata.generic.RegisterSelect = REG_COMMAND; ata.write.CommandByte = WIN_IDENTIFY; - srb.sc_data_direction = SCSI_DATA_READ; - srb.request_buffer = (void *)&info->drive; - srb.request_bufflen = sizeof(struct hd_driveid); + srb->sc_data_direction = SCSI_DATA_READ; + srb->request_buffer = (void *)&info->drive; + srb->request_bufflen = sizeof(struct hd_driveid); break; default: @@ -481,9 +482,9 @@ static int isd200_action( struct us_data *us, int action, break; } - memcpy(srb.cmnd, &ata, sizeof(ata.generic)); - srb.cmd_len = sizeof(ata.generic); - status = usb_stor_Bulk_transport(&srb, us); + memcpy(srb->cmnd, &ata, sizeof(ata.generic)); + srb->cmd_len = sizeof(ata.generic); + status = usb_stor_Bulk_transport(srb, us); if (status == USB_STOR_TRANSPORT_GOOD) status = ISD200_GOOD; else { @@ -834,7 +835,7 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, int detect ) { int status = ISD200_GOOD; - unsigned char regs[8]; + unsigned char *regs = us->iobuf; unsigned long endTime; struct isd200_info *info = (struct isd200_info *)us->extra; int recheckAsMaster = FALSE; @@ -856,7 +857,7 @@ static int isd200_try_enum(struct us_data *us, unsigned char master_slave, break; status = isd200_action( us, ACTION_READ_STATUS, - regs, sizeof(regs) ); + regs, 8 ); if ( status != ISD200_GOOD ) break; diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c index e6a4a516d1b5..3b75a8a43eda 100644 --- a/drivers/usb/storage/jumpshot.c +++ b/drivers/usb/storage/jumpshot.c @@ -86,7 +86,6 @@ static inline int jumpshot_bulk_write(struct us_data *us, static int jumpshot_get_status(struct us_data *us) { - unsigned char reply; int rc; if (!us) @@ -94,14 +93,14 @@ static int jumpshot_get_status(struct us_data *us) // send the setup rc = usb_stor_ctrl_transfer(us, us->recv_ctrl_pipe, - 0, 0xA0, 0, 7, &reply, 1); + 0, 0xA0, 0, 7, us->iobuf, 1); if (rc != USB_STOR_XFER_GOOD) return USB_STOR_TRANSPORT_ERROR; - if (reply != 0x50) { + if (us->iobuf[0] != 0x50) { US_DEBUGP("jumpshot_get_status: 0x%2x\n", - (unsigned short) (reply)); + us->iobuf[0]); return USB_STOR_TRANSPORT_ERROR; } @@ -115,7 +114,7 @@ static int jumpshot_read_data(struct us_data *us, unsigned char *dest, int use_sg) { - unsigned char command[] = { 0, 0, 0, 0, 0, 0xe0, 0x20 }; + unsigned char *command = us->iobuf; unsigned char *buffer = NULL; unsigned char *ptr; unsigned char thistime; @@ -154,7 +153,8 @@ static int jumpshot_read_data(struct us_data *us, command[3] = (sector >> 8) & 0xFF; command[4] = (sector >> 16) & 0xFF; - command[5] |= (sector >> 24) & 0x0F; + command[5] = 0xE0 | ((sector >> 24) & 0x0F); + command[6] = 0x20; // send the setup + command result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, @@ -199,7 +199,7 @@ static int jumpshot_write_data(struct us_data *us, unsigned char *src, int use_sg) { - unsigned char command[7] = { 0, 0, 0, 0, 0, 0xE0, 0x30 }; + unsigned char *command = us->iobuf; unsigned char *buffer = NULL; unsigned char *ptr; unsigned char thistime; @@ -240,7 +240,8 @@ static int jumpshot_write_data(struct us_data *us, command[3] = (sector >> 8) & 0xFF; command[4] = (sector >> 16) & 0xFF; - command[5] |= (sector >> 24) & 0x0F; + command[5] = 0xE0 | ((sector >> 24) & 0x0F); + command[6] = 0x30; // send the setup + command result = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, @@ -291,13 +292,19 @@ static int jumpshot_write_data(struct us_data *us, static int jumpshot_id_device(struct us_data *us, struct jumpshot_info *info) { - unsigned char command[2] = { 0xe0, 0xec }; - unsigned char reply[512]; + unsigned char *command = us->iobuf; + unsigned char *reply; int rc; if (!us || !info) return USB_STOR_TRANSPORT_ERROR; + command[0] = 0xE0; + command[1] = 0xEC; + reply = kmalloc(512, GFP_NOIO); + if (!reply) + return USB_STOR_TRANSPORT_ERROR; + // send the setup rc = usb_stor_ctrl_transfer(us, us->send_ctrl_pipe, 0, 0x20, 0, 6, command, 2); @@ -305,20 +312,27 @@ static int jumpshot_id_device(struct us_data *us, if (rc != USB_STOR_XFER_GOOD) { US_DEBUGP("jumpshot_id_device: Gah! " "send_control for read_capacity failed\n"); - return rc; + rc = USB_STOR_TRANSPORT_ERROR; + goto leave; } // read the reply rc = jumpshot_bulk_read(us, reply, sizeof(reply)); - if (rc != USB_STOR_XFER_GOOD) - return USB_STOR_TRANSPORT_ERROR; + if (rc != USB_STOR_XFER_GOOD) { + rc = USB_STOR_TRANSPORT_ERROR; + goto leave; + } info->sectors = ((u32)(reply[117]) << 24) | ((u32)(reply[116]) << 16) | ((u32)(reply[115]) << 8) | ((u32)(reply[114]) ); - return USB_STOR_TRANSPORT_GOOD; + rc = USB_STOR_TRANSPORT_GOOD; + + leave: + kfree(reply); + return rc; } static int jumpshot_handle_mode_sense(struct us_data *us, diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c index 97476a3789b2..a6082b08fad5 100644 --- a/drivers/usb/storage/protocol.c +++ b/drivers/usb/storage/protocol.c @@ -130,8 +130,9 @@ static void fix_read_capacity(Scsi_Cmnd *srb) void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us) { /* Pad the ATAPI command with zeros + * * NOTE: This only works because a Scsi_Cmnd struct field contains - * a unsigned char cmnd[12], so we know we have storage available + * a unsigned char cmnd[16], so we know we have storage available */ for (; srb->cmd_len<12; srb->cmd_len++) srb->cmnd[srb->cmd_len] = 0; @@ -149,13 +150,10 @@ void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us) void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) { - int old_cmnd = 0; - - /* Fix some commands -- this is a form of mode translation - * ATAPI devices only accept 12 byte long commands + /* Pad the ATAPI command with zeros * * NOTE: This only works because a Scsi_Cmnd struct field contains - * a unsigned char cmnd[12], so we know we have storage available + * a unsigned char cmnd[16], so we know we have storage available */ /* Pad the ATAPI command with zeros */ @@ -165,60 +163,10 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) /* set command length to 12 bytes */ srb->cmd_len = 12; - /* determine the correct (or minimum) data length for these commands */ - switch (srb->cmnd[0]) { - - /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */ - case MODE_SENSE: - case MODE_SELECT: - /* save the command so we can tell what it was */ - old_cmnd = srb->cmnd[0]; - - srb->cmnd[11] = 0; - srb->cmnd[10] = 0; - srb->cmnd[9] = 0; - srb->cmnd[8] = srb->cmnd[4]; - srb->cmnd[7] = 0; - srb->cmnd[6] = 0; - srb->cmnd[5] = 0; - srb->cmnd[4] = 0; - srb->cmnd[3] = 0; - srb->cmnd[2] = srb->cmnd[2]; - srb->cmnd[1] = srb->cmnd[1]; - srb->cmnd[0] = srb->cmnd[0] | 0x40; - break; - - /* change READ_6/WRITE_6 to READ_10/WRITE_10, which - * are ATAPI commands */ - case WRITE_6: - case READ_6: - srb->cmnd[11] = 0; - srb->cmnd[10] = 0; - srb->cmnd[9] = 0; - srb->cmnd[8] = srb->cmnd[4]; - srb->cmnd[7] = 0; - srb->cmnd[6] = 0; - srb->cmnd[5] = srb->cmnd[3]; - srb->cmnd[4] = srb->cmnd[2]; - srb->cmnd[3] = srb->cmnd[1] & 0x1F; - srb->cmnd[2] = 0; - srb->cmnd[1] = srb->cmnd[1] & 0xE0; - srb->cmnd[0] = srb->cmnd[0] | 0x20; - break; - } /* end switch on cmnd[0] */ - - /* convert MODE_SELECT data here */ - if (old_cmnd == MODE_SELECT) - usb_stor_scsiSense6to10(srb); - /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); - if (srb->result == SAM_STAT_GOOD) { - - /* Fix the MODE_SENSE data if we translated the command */ - if (old_cmnd == MODE_SENSE) - usb_stor_scsiSense10to6(srb); + if (srb->result == SAM_STAT_GOOD) { /* fix the INQUIRY data if necessary */ fix_inquiry_data(srb); } @@ -227,19 +175,23 @@ void usb_stor_ATAPI_command(Scsi_Cmnd *srb, struct us_data *us) void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) { - int old_cmnd = 0; - /* fix some commands -- this is a form of mode translation * UFI devices only accept 12 byte long commands * * NOTE: This only works because a Scsi_Cmnd struct field contains - * a unsigned char cmnd[12], so we know we have storage available + * a unsigned char cmnd[16], so we know we have storage available */ + /* Pad the ATAPI command with zeros */ + for (; srb->cmd_len<12; srb->cmd_len++) + srb->cmnd[srb->cmd_len] = 0; + /* set command length to 12 bytes (this affects the transport layer) */ srb->cmd_len = 12; - /* determine the correct (or minimum) data length for these commands */ + /* XXX We should be constantly re-evaluating the need for these */ + + /* determine the correct data length for these commands */ switch (srb->cmnd[0]) { /* for INQUIRY, UFI devices only ever return 36 bytes */ @@ -247,33 +199,6 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) srb->cmnd[4] = 36; break; - /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */ - case MODE_SENSE: - case MODE_SELECT: - /* save the command so we can tell what it was */ - old_cmnd = srb->cmnd[0]; - - srb->cmnd[11] = 0; - srb->cmnd[10] = 0; - srb->cmnd[9] = 0; - - /* if we're sending data, we send all. If getting data, - * get the minimum */ - if (srb->cmnd[0] == MODE_SELECT) - srb->cmnd[8] = srb->cmnd[4]; - else - srb->cmnd[8] = 8; - - srb->cmnd[7] = 0; - srb->cmnd[6] = 0; - srb->cmnd[5] = 0; - srb->cmnd[4] = 0; - srb->cmnd[3] = 0; - srb->cmnd[2] = srb->cmnd[2]; - srb->cmnd[1] = srb->cmnd[1]; - srb->cmnd[0] = srb->cmnd[0] | 0x40; - break; - /* again, for MODE_SENSE_10, we get the minimum (8) */ case MODE_SENSE_10: srb->cmnd[7] = 0; @@ -284,38 +209,12 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) case REQUEST_SENSE: srb->cmnd[4] = 18; break; - - /* change READ_6/WRITE_6 to READ_10/WRITE_10, which - * are UFI commands */ - case WRITE_6: - case READ_6: - srb->cmnd[11] = 0; - srb->cmnd[10] = 0; - srb->cmnd[9] = 0; - srb->cmnd[8] = srb->cmnd[4]; - srb->cmnd[7] = 0; - srb->cmnd[6] = 0; - srb->cmnd[5] = srb->cmnd[3]; - srb->cmnd[4] = srb->cmnd[2]; - srb->cmnd[3] = srb->cmnd[1] & 0x1F; - srb->cmnd[2] = 0; - srb->cmnd[1] = srb->cmnd[1] & 0xE0; - srb->cmnd[0] = srb->cmnd[0] | 0x20; - break; } /* end switch on cmnd[0] */ - /* convert MODE_SELECT data here */ - if (old_cmnd == MODE_SELECT) - usb_stor_scsiSense6to10(srb); - /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); - if (srb->result == SAM_STAT_GOOD) { - - /* Fix the MODE_SENSE data if we translated the command */ - if (old_cmnd == MODE_SENSE) - usb_stor_scsiSense10to6(srb); + if (srb->result == SAM_STAT_GOOD) { /* Fix the data for an INQUIRY, if necessary */ fix_inquiry_data(srb); } @@ -323,68 +222,10 @@ void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us) void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us) { - int old_cmnd = 0; - - /* This code supports devices which do not support {READ|WRITE}_6 - * Apparently, neither Windows or MacOS will use these commands, - * so some devices do not support them - */ - if (us->flags & US_FL_MODE_XLATE) { - US_DEBUGP("Invoking Mode Translation\n"); - /* save the old command for later */ - old_cmnd = srb->cmnd[0]; - - switch (srb->cmnd[0]) { - /* change READ_6/WRITE_6 to READ_10/WRITE_10 */ - case WRITE_6: - case READ_6: - srb->cmd_len = 12; - srb->cmnd[11] = 0; - srb->cmnd[10] = 0; - srb->cmnd[9] = 0; - srb->cmnd[8] = srb->cmnd[4]; - srb->cmnd[7] = 0; - srb->cmnd[6] = 0; - srb->cmnd[5] = srb->cmnd[3]; - srb->cmnd[4] = srb->cmnd[2]; - srb->cmnd[3] = srb->cmnd[1] & 0x1F; - srb->cmnd[2] = 0; - srb->cmnd[1] = srb->cmnd[1] & 0xE0; - srb->cmnd[0] = srb->cmnd[0] | 0x20; - break; - - /* convert MODE_SELECT data here */ - case MODE_SENSE: - case MODE_SELECT: - srb->cmd_len = 12; - srb->cmnd[11] = 0; - srb->cmnd[10] = 0; - srb->cmnd[9] = 0; - srb->cmnd[8] = srb->cmnd[4]; - srb->cmnd[7] = 0; - srb->cmnd[6] = 0; - srb->cmnd[5] = 0; - srb->cmnd[4] = 0; - srb->cmnd[3] = 0; - srb->cmnd[2] = srb->cmnd[2]; - srb->cmnd[1] = srb->cmnd[1]; - srb->cmnd[0] = srb->cmnd[0] | 0x40; - break; - } /* switch (srb->cmnd[0]) */ - } /* if (us->flags & US_FL_MODE_XLATE) */ - - /* convert MODE_SELECT data here */ - if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SELECT)) - usb_stor_scsiSense6to10(srb); - /* send the command to the transport layer */ usb_stor_invoke_transport(srb, us); - if (srb->result == SAM_STAT_GOOD) { - - /* Fix the MODE_SENSE data if we translated the command */ - if ((us->flags & US_FL_MODE_XLATE) && (old_cmnd == MODE_SENSE)) - usb_stor_scsiSense10to6(srb); + if (srb->result == SAM_STAT_GOOD) { /* Fix the INQUIRY data if necessary */ fix_inquiry_data(srb); diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c index 2c1990b74d68..b744a2925874 100644 --- a/drivers/usb/storage/scsiglue.c +++ b/drivers/usb/storage/scsiglue.c @@ -263,7 +263,6 @@ static int proc_info (struct Scsi_Host *hostptr, char *buffer, char **start, off #define DO_FLAG(a) if (f & US_FL_##a) pos += sprintf(pos, " " #a) DO_FLAG(SINGLE_LUN); - DO_FLAG(MODE_XLATE); DO_FLAG(SCM_MULT_TARG); DO_FLAG(FIX_INQUIRY); DO_FLAG(FIX_CAPACITY); @@ -346,499 +345,3 @@ unsigned char usb_stor_sense_invalidCDB[18] = { [12] = 0x24 /* Invalid Field in CDB */ }; -#define USB_STOR_SCSI_SENSE_HDRSZ 4 -#define USB_STOR_SCSI_SENSE_10_HDRSZ 8 - -struct usb_stor_scsi_sense_hdr -{ - __u8* dataLength; - __u8* mediumType; - __u8* devSpecParms; - __u8* blkDescLength; -}; - -typedef struct usb_stor_scsi_sense_hdr Usb_Stor_Scsi_Sense_Hdr; - -union usb_stor_scsi_sense_hdr_u -{ - Usb_Stor_Scsi_Sense_Hdr hdr; - __u8* array[USB_STOR_SCSI_SENSE_HDRSZ]; -}; - -typedef union usb_stor_scsi_sense_hdr_u Usb_Stor_Scsi_Sense_Hdr_u; - -struct usb_stor_scsi_sense_hdr_10 -{ - __u8* dataLengthMSB; - __u8* dataLengthLSB; - __u8* mediumType; - __u8* devSpecParms; - __u8* reserved1; - __u8* reserved2; - __u8* blkDescLengthMSB; - __u8* blkDescLengthLSB; -}; - -typedef struct usb_stor_scsi_sense_hdr_10 Usb_Stor_Scsi_Sense_Hdr_10; - -union usb_stor_scsi_sense_hdr_10_u -{ - Usb_Stor_Scsi_Sense_Hdr_10 hdr; - __u8* array[USB_STOR_SCSI_SENSE_10_HDRSZ]; -}; - -typedef union usb_stor_scsi_sense_hdr_10_u Usb_Stor_Scsi_Sense_Hdr_10_u; - -void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* , Usb_Stor_Scsi_Sense_Hdr_u*, - Usb_Stor_Scsi_Sense_Hdr_10_u*, int* ); - -int usb_stor_scsiSense10to6( Scsi_Cmnd* the10 ) -{ - __u8 *buffer=0; - int outputBufferSize = 0; - int length=0; - struct scatterlist *sg = 0; - int i=0, j=0, element=0; - Usb_Stor_Scsi_Sense_Hdr_u the6Locations; - Usb_Stor_Scsi_Sense_Hdr_10_u the10Locations; - int sb=0,si=0,db=0,di=0; - int sgLength=0; - - US_DEBUGP("-- converting 10 byte sense data to 6 byte\n"); - the10->cmnd[0] = the10->cmnd[0] & 0xBF; - - /* Determine buffer locations */ - usb_stor_scsiSenseParseBuffer( the10, &the6Locations, &the10Locations, - &length ); - - /* Work out minimum buffer to output */ - outputBufferSize = *the10Locations.hdr.dataLengthLSB; - outputBufferSize += USB_STOR_SCSI_SENSE_HDRSZ; - - /* Check to see if we need to trucate the output */ - if ( outputBufferSize > length ) - { - printk( KERN_WARNING USB_STORAGE - "Had to truncate MODE_SENSE_10 buffer into MODE_SENSE.\n" ); - printk( KERN_WARNING USB_STORAGE - "outputBufferSize is %d and length is %d.\n", - outputBufferSize, length ); - } - outputBufferSize = length; - - /* Data length */ - if ( *the10Locations.hdr.dataLengthMSB != 0 ) /* MSB must be zero */ - { - printk( KERN_WARNING USB_STORAGE - "Command will be truncated to fit in SENSE6 buffer.\n" ); - *the6Locations.hdr.dataLength = 0xff; - } - else - { - *the6Locations.hdr.dataLength = *the10Locations.hdr.dataLengthLSB; - } - - /* Medium type and DevSpecific parms */ - *the6Locations.hdr.mediumType = *the10Locations.hdr.mediumType; - *the6Locations.hdr.devSpecParms = *the10Locations.hdr.devSpecParms; - - /* Block descriptor length */ - if ( *the10Locations.hdr.blkDescLengthMSB != 0 ) /* MSB must be zero */ - { - printk( KERN_WARNING USB_STORAGE - "Command will be truncated to fit in SENSE6 buffer.\n" ); - *the6Locations.hdr.blkDescLength = 0xff; - } - else - { - *the6Locations.hdr.blkDescLength = *the10Locations.hdr.blkDescLengthLSB; - } - - if ( the10->use_sg == 0 ) - { - buffer = the10->request_buffer; - /* Copy the rest of the data */ - memmove( &(buffer[USB_STOR_SCSI_SENSE_HDRSZ]), - &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]), - outputBufferSize - USB_STOR_SCSI_SENSE_HDRSZ ); - /* initialise last bytes left in buffer due to smaller header */ - memset( &(buffer[outputBufferSize - -(USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ)]), - 0, - USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ ); - } - else - { - sg = (struct scatterlist *) the10->request_buffer; - /* scan through this scatterlist and figure out starting positions */ - for ( i=0; i < the10->use_sg; i++) - { - sgLength = sg[i].length; - for ( j=0; j<sgLength; j++ ) - { - /* get to end of header */ - if ( element == USB_STOR_SCSI_SENSE_HDRSZ ) - { - db=i; - di=j; - } - if ( element == USB_STOR_SCSI_SENSE_10_HDRSZ ) - { - sb=i; - si=j; - /* we've found both sets now, exit loops */ - j=sgLength; - i=the10->use_sg; - } - element++; - } - } - - /* Now we know where to start the copy from */ - element = USB_STOR_SCSI_SENSE_HDRSZ; - while ( element < outputBufferSize - -(USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ) ) - { - /* check limits */ - if ( sb >= the10->use_sg || - si >= sg[sb].length || - db >= the10->use_sg || - di >= sg[db].length ) - { - printk( KERN_ERR USB_STORAGE - "Buffer overrun averted, this shouldn't happen!\n" ); - break; - } - - /* copy one byte */ - { - char *src = sg_address(sg[sb]) + si; - char *dst = sg_address(sg[db]) + di; - - *dst = *src; - } - - /* get next destination */ - if ( sg[db].length-1 == di ) - { - db++; - di=0; - } - else - { - di++; - } - - /* get next source */ - if ( sg[sb].length-1 == si ) - { - sb++; - si=0; - } - else - { - si++; - } - - element++; - } - /* zero the remaining bytes */ - while ( element < outputBufferSize ) - { - /* check limits */ - if ( db >= the10->use_sg || - di >= sg[db].length ) - { - printk( KERN_ERR USB_STORAGE - "Buffer overrun averted, this shouldn't happen!\n" ); - break; - } - - *(char*)(sg_address(sg[db])) = 0; - - /* get next destination */ - if ( sg[db].length-1 == di ) - { - db++; - di=0; - } - else - { - di++; - } - element++; - } - } - - /* All done any everything was fine */ - return 0; -} - -int usb_stor_scsiSense6to10( Scsi_Cmnd* the6 ) -{ - /* will be used to store part of buffer */ - __u8 tempBuffer[USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ], - *buffer=0; - int outputBufferSize = 0; - int length=0; - struct scatterlist *sg = 0; - int i=0, j=0, element=0; - Usb_Stor_Scsi_Sense_Hdr_u the6Locations; - Usb_Stor_Scsi_Sense_Hdr_10_u the10Locations; - int sb=0,si=0,db=0,di=0; - int lsb=0,lsi=0,ldb=0,ldi=0; - - US_DEBUGP("-- converting 6 byte sense data to 10 byte\n"); - the6->cmnd[0] = the6->cmnd[0] | 0x40; - - /* Determine buffer locations */ - usb_stor_scsiSenseParseBuffer( the6, &the6Locations, &the10Locations, - &length ); - - /* Work out minimum buffer to output */ - outputBufferSize = *the6Locations.hdr.dataLength; - outputBufferSize += USB_STOR_SCSI_SENSE_10_HDRSZ; - - /* Check to see if we need to trucate the output */ - if ( outputBufferSize > length ) - { - printk( KERN_WARNING USB_STORAGE - "Had to truncate MODE_SENSE into MODE_SENSE_10 buffer.\n" ); - printk( KERN_WARNING USB_STORAGE - "outputBufferSize is %d and length is %d.\n", - outputBufferSize, length ); - } - outputBufferSize = length; - - /* Block descriptor length - save these before overwriting */ - tempBuffer[2] = *the10Locations.hdr.blkDescLengthMSB; - tempBuffer[3] = *the10Locations.hdr.blkDescLengthLSB; - *the10Locations.hdr.blkDescLengthLSB = *the6Locations.hdr.blkDescLength; - *the10Locations.hdr.blkDescLengthMSB = 0; - - /* reserved - save these before overwriting */ - tempBuffer[0] = *the10Locations.hdr.reserved1; - tempBuffer[1] = *the10Locations.hdr.reserved2; - *the10Locations.hdr.reserved1 = *the10Locations.hdr.reserved2 = 0; - - /* Medium type and DevSpecific parms */ - *the10Locations.hdr.devSpecParms = *the6Locations.hdr.devSpecParms; - *the10Locations.hdr.mediumType = *the6Locations.hdr.mediumType; - - /* Data length */ - *the10Locations.hdr.dataLengthLSB = *the6Locations.hdr.dataLength; - *the10Locations.hdr.dataLengthMSB = 0; - - if ( !the6->use_sg ) - { - buffer = the6->request_buffer; - /* Copy the rest of the data */ - memmove( &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]), - &(buffer[USB_STOR_SCSI_SENSE_HDRSZ]), - outputBufferSize-USB_STOR_SCSI_SENSE_10_HDRSZ ); - /* Put the first four bytes (after header) in place */ - memcpy( &(buffer[USB_STOR_SCSI_SENSE_10_HDRSZ]), - tempBuffer, - USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ ); - } - else - { - sg = (struct scatterlist *) the6->request_buffer; - /* scan through this scatterlist and figure out ending positions */ - for ( i=0; i < the6->use_sg; i++) - { - for ( j=0; j<sg[i].length; j++ ) - { - /* get to end of header */ - if ( element == USB_STOR_SCSI_SENSE_HDRSZ ) - { - ldb=i; - ldi=j; - } - if ( element == USB_STOR_SCSI_SENSE_10_HDRSZ ) - { - lsb=i; - lsi=j; - /* we've found both sets now, exit loops */ - j=sg[i].length; - i=the6->use_sg; - break; - } - element++; - } - } - /* scan through this scatterlist and figure out starting positions */ - element = length-1; - /* destination is the last element */ - db=the6->use_sg-1; - di=sg[db].length-1; - for ( i=the6->use_sg-1; i >= 0; i--) - { - for ( j=sg[i].length-1; j>=0; j-- ) - { - /* get to end of header and find source for copy */ - if ( element == length - 1 - - (USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ) ) - { - sb=i; - si=j; - /* we've found both sets now, exit loops */ - j=-1; - i=-1; - } - element--; - } - } - /* Now we know where to start the copy from */ - element = length-1 - - (USB_STOR_SCSI_SENSE_10_HDRSZ-USB_STOR_SCSI_SENSE_HDRSZ); - while ( element >= USB_STOR_SCSI_SENSE_10_HDRSZ ) - { - /* check limits */ - if ( ( sb <= lsb && si < lsi ) || - ( db <= ldb && di < ldi ) ) - { - printk( KERN_ERR USB_STORAGE - "Buffer overrun averted, this shouldn't happen!\n" ); - break; - } - - /* copy one byte */ - { - char *src = sg_address(sg[sb]) + si; - char *dst = sg_address(sg[db]) + di; - - *dst = *src; - } - - /* get next destination */ - if ( di == 0 ) - { - db--; - di=sg[db].length-1; - } - else - { - di--; - } - - /* get next source */ - if ( si == 0 ) - { - sb--; - si=sg[sb].length-1; - } - else - { - si--; - } - - element--; - } - /* copy the remaining four bytes */ - while ( element >= USB_STOR_SCSI_SENSE_HDRSZ ) - { - /* check limits */ - if ( db <= ldb && di < ldi ) - { - printk( KERN_ERR USB_STORAGE - "Buffer overrun averted, this shouldn't happen!\n" ); - break; - } - - { - char *dst = sg_address(sg[db]) + di; - - *dst = tempBuffer[element-USB_STOR_SCSI_SENSE_HDRSZ]; - } - - - /* get next destination */ - if ( di == 0 ) - { - db--; - di=sg[db].length-1; - } - else - { - di--; - } - element--; - } - } - - /* All done and everything was fine */ - return 0; -} - -void usb_stor_scsiSenseParseBuffer( Scsi_Cmnd* srb, Usb_Stor_Scsi_Sense_Hdr_u* the6, - Usb_Stor_Scsi_Sense_Hdr_10_u* the10, - int* length_p ) - -{ - int i = 0, j=0, element=0; - struct scatterlist *sg = 0; - int length = 0; - __u8* buffer=0; - - /* are we scatter-gathering? */ - if ( srb->use_sg != 0 ) - { - /* loop over all the scatter gather structures and - * get pointer to the data members in the headers - * (also work out the length while we're here) - */ - sg = (struct scatterlist *) srb->request_buffer; - for (i = 0; i < srb->use_sg; i++) - { - length += sg[i].length; - /* We only do the inner loop for the headers */ - if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ ) - { - /* scan through this scatterlist */ - for ( j=0; j<sg[i].length; j++ ) - { - if ( element < USB_STOR_SCSI_SENSE_HDRSZ ) - { - /* fill in the pointers for both header types */ - the6->array[element] = sg_address(sg[i]) + j; - the10->array[element] = sg_address(sg[i]) + j; - - } - else if ( element < USB_STOR_SCSI_SENSE_10_HDRSZ ) - { - /* only the longer headers still cares now */ - the10->array[element] = sg_address(sg[i]) + j; - - } - /* increase element counter */ - element++; - } - } - } - } - else - { - length = srb->request_bufflen; - buffer = srb->request_buffer; - if ( length < USB_STOR_SCSI_SENSE_10_HDRSZ ) - printk( KERN_ERR USB_STORAGE - "Buffer length smaller than header!!" ); - for( i=0; i<USB_STOR_SCSI_SENSE_10_HDRSZ; i++ ) - { - if ( i < USB_STOR_SCSI_SENSE_HDRSZ ) - { - the6->array[i] = &(buffer[i]); - the10->array[i] = &(buffer[i]); - } - else - { - the10->array[i] = &(buffer[i]); - } - } - } - - /* Set value of length passed in */ - *length_p = length; -} - diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c index 49ba4db8617b..9139ead4a519 100644 --- a/drivers/usb/storage/sddr09.c +++ b/drivers/usb/storage/sddr09.c @@ -261,12 +261,13 @@ sddr09_send_scsi_command(struct us_data *us, */ static int sddr09_test_unit_ready(struct us_data *us) { - unsigned char command[6] = { - 0, LUNBITS, 0, 0, 0, 0 - }; + unsigned char *command = us->iobuf; int result; - result = sddr09_send_scsi_command(us, command, sizeof(command)); + memset(command, 0, 6); + command[1] = LUNBITS; + + result = sddr09_send_scsi_command(us, command, 6); US_DEBUGP("sddr09_test_unit_ready returns %d\n", result); @@ -281,12 +282,15 @@ sddr09_test_unit_ready(struct us_data *us) { */ static int sddr09_request_sense(struct us_data *us, unsigned char *sensebuf, int buflen) { - unsigned char command[12] = { - 0x03, LUNBITS, 0, 0, buflen, 0, 0, 0, 0, 0, 0, 0 - }; + unsigned char *command = us->iobuf; int result; - result = sddr09_send_scsi_command(us, command, sizeof(command)); + memset(command, 0, 12); + command[0] = 0x03; + command[1] = LUNBITS; + command[4] = buflen; + + result = sddr09_send_scsi_command(us, command, 12); if (result != USB_STOR_TRANSPORT_GOOD) { US_DEBUGP("request sense failed\n"); return result; @@ -331,20 +335,23 @@ sddr09_readX(struct us_data *us, int x, unsigned long fromaddress, int nr_of_pages, int bulklen, unsigned char *buf, int use_sg) { - unsigned char command[12] = { - 0xe8, LUNBITS | x, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; + unsigned char *command = us->iobuf; int result; + command[0] = 0xE8; + command[1] = LUNBITS | x; command[2] = MSB_of(fromaddress>>16); command[3] = LSB_of(fromaddress>>16); command[4] = MSB_of(fromaddress & 0xFFFF); command[5] = LSB_of(fromaddress & 0xFFFF); - + command[6] = 0; + command[7] = 0; + command[8] = 0; + command[9] = 0; command[10] = MSB_of(nr_of_pages); command[11] = LSB_of(nr_of_pages); - result = sddr09_send_scsi_command(us, command, sizeof(command)); + result = sddr09_send_scsi_command(us, command, 12); if (result != USB_STOR_TRANSPORT_GOOD) { US_DEBUGP("Result for send_control in sddr09_read2%d %d\n", @@ -458,17 +465,18 @@ sddr09_read23(struct us_data *us, unsigned long fromaddress, */ static int sddr09_erase(struct us_data *us, unsigned long Eaddress) { - unsigned char command[12] = { - 0xea, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; + unsigned char *command = us->iobuf; int result; + memset(command, 0, 12); + command[0] = 0xEA; + command[1] = LUNBITS; command[6] = MSB_of(Eaddress>>16); command[7] = LSB_of(Eaddress>>16); command[8] = MSB_of(Eaddress & 0xFFFF); command[9] = LSB_of(Eaddress & 0xFFFF); - result = sddr09_send_scsi_command(us, command, sizeof(command)); + result = sddr09_send_scsi_command(us, command, 12); if (result != USB_STOR_TRANSPORT_GOOD) US_DEBUGP("Result for send_control in sddr09_erase %d\n", @@ -493,11 +501,12 @@ sddr09_writeX(struct us_data *us, unsigned long Waddress, unsigned long Eaddress, int nr_of_pages, int bulklen, unsigned char *buf, int use_sg) { - unsigned char command[12] = { - 0xe9, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; + unsigned char *command = us->iobuf; int result; + command[0] = 0xE9; + command[1] = LUNBITS; + command[2] = MSB_of(Waddress>>16); command[3] = LSB_of(Waddress>>16); command[4] = MSB_of(Waddress & 0xFFFF); @@ -511,7 +520,7 @@ sddr09_writeX(struct us_data *us, command[10] = MSB_of(nr_of_pages); command[11] = LSB_of(nr_of_pages); - result = sddr09_send_scsi_command(us, command, sizeof(command)); + result = sddr09_send_scsi_command(us, command, 12); if (result != USB_STOR_TRANSPORT_GOOD) { US_DEBUGP("Result for send_control in sddr09_writeX %d\n", @@ -554,15 +563,15 @@ sddr09_write_inplace(struct us_data *us, unsigned long address, */ static int sddr09_read_sg_test_only(struct us_data *us) { - unsigned char command[15] = { - 0xe7, LUNBITS, 0 - }; + unsigned char *command = us->iobuf; int result, bulklen, nsg, ct; unsigned char *buf; unsigned long address; nsg = bulklen = 0; - + command[0] = 0xE7; + command[1] = LUNBITS; + command[2] = 0; address = 040000; ct = 1; nsg++; bulklen += (ct << 9); @@ -628,20 +637,22 @@ sddr09_read_sg_test_only(struct us_data *us) { static int sddr09_read_status(struct us_data *us, unsigned char *status) { - unsigned char command[12] = { - 0xec, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - unsigned char data[64]; + unsigned char *command = us->iobuf; + unsigned char *data = us->iobuf; int result; US_DEBUGP("Reading status...\n"); - result = sddr09_send_scsi_command(us, command, sizeof(command)); + memset(command, 0, 12); + command[0] = 0xEC; + command[1] = LUNBITS; + + result = sddr09_send_scsi_command(us, command, 12); if (result != USB_STOR_TRANSPORT_GOOD) return result; result = usb_stor_bulk_transfer_buf(us, us->recv_bulk_pipe, - data, sizeof(data), NULL); + data, 64, NULL); *status = data[0]; return (result == USB_STOR_XFER_GOOD ? USB_STOR_TRANSPORT_GOOD : USB_STOR_TRANSPORT_ERROR); @@ -953,13 +964,15 @@ sddr09_read_control(struct us_data *us, */ static int sddr09_read_deviceID(struct us_data *us, unsigned char *deviceID) { - unsigned char command[12] = { - 0xed, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; - unsigned char content[64]; + unsigned char *command = us->iobuf; + unsigned char *content = us->iobuf; int result, i; - result = sddr09_send_scsi_command(us, command, sizeof(command)); + memset(command, 0, 12); + command[0] = 0xED; + command[1] = LUNBITS; + + result = sddr09_send_scsi_command(us, command, 12); if (result != USB_STOR_TRANSPORT_GOOD) return result; @@ -1006,11 +1019,13 @@ sddr09_get_wp(struct us_data *us, struct sddr09_card_info *info) { static int sddr09_reset(struct us_data *us) { - unsigned char command[12] = { - 0xeb, LUNBITS, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 - }; + unsigned char *command = us->iobuf; + + memset(command, 0, 12); + command[0] = 0xEB; + command[1] = LUNBITS; - return sddr09_send_scsi_command(us, command, sizeof(command)); + return sddr09_send_scsi_command(us, command, 12); } #endif @@ -1313,7 +1328,7 @@ sddr09_init_card_info(struct us_data *us) { int sddr09_init(struct us_data *us) { int result; - unsigned char data[18]; + unsigned char *data = us->iobuf; result = sddr09_send_command(us, 0x01, USB_DIR_IN, data, 2); if (result != USB_STOR_TRANSPORT_GOOD) { @@ -1333,10 +1348,10 @@ sddr09_init(struct us_data *us) { US_DEBUGP("SDDR09init: %02X %02X\n", data[0], data[1]); // get 07 00 - result = sddr09_request_sense(us, data, sizeof(data)); + result = sddr09_request_sense(us, data, 18); if (result == USB_STOR_TRANSPORT_GOOD && data[2] != 0) { int j; - for (j=0; j<sizeof(data); j++) + for (j=0; j<18; j++) printk(" %02X", data[j]); printk("\n"); // get 70 00 00 00 00 00 00 * 00 00 00 00 00 00 diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c index 62876ea3663d..6d21c92ccaba 100644 --- a/drivers/usb/storage/sddr55.c +++ b/drivers/usb/storage/sddr55.c @@ -91,13 +91,14 @@ sddr55_bulk_transport(struct us_data *us, int direction, static int sddr55_status(struct us_data *us) { int result; - unsigned char command[8] = { - 0, 0, 0, 0, 0, 0xb0, 0, 0x80 - }; - unsigned char status[8]; + unsigned char *command = us->iobuf; + unsigned char *status = us->iobuf; struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; /* send command */ + memset(command, 0, 8); + command[5] = 0xB0; + command[7] = 0x80; result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8); @@ -158,10 +159,8 @@ static int sddr55_read_data(struct us_data *us, int use_sg) { int result = USB_STOR_TRANSPORT_GOOD; - unsigned char command[8] = { - 0, 0, 0, 0, 0, 0xb0, 0, 0x85 - }; - unsigned char status[8]; + unsigned char *command = us->iobuf; + unsigned char *status = us->iobuf; struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; unsigned int pba; @@ -205,11 +204,15 @@ static int sddr55_read_data(struct us_data *us, address = (pba << info->blockshift) + page; + command[0] = 0; command[1] = LSB_of(address>>16); command[2] = LSB_of(address>>8); command[3] = LSB_of(address); + command[4] = 0; + command[5] = 0xB0; command[6] = LSB_of(pages << (1 - info->smallpageshift)); + command[7] = 0x85; /* send command */ result = sddr55_bulk_transport(us, @@ -274,10 +277,8 @@ static int sddr55_write_data(struct us_data *us, int use_sg) { int result = USB_STOR_TRANSPORT_GOOD; - unsigned char command[8] = { - 0, 0, 0, 0, 0, 0xb0, 0, 0x86 - }; - unsigned char status[8]; + unsigned char *command = us->iobuf; + unsigned char *status = us->iobuf; struct sddr55_card_info *info = (struct sddr55_card_info *)us->extra; unsigned int pba; @@ -380,6 +381,8 @@ static int sddr55_write_data(struct us_data *us, command[6] = MSB_of(lba % 1000); command[4] |= LSB_of(pages >> info->smallpageshift); + command[5] = 0xB0; + command[7] = 0x86; /* send command */ result = sddr55_bulk_transport(us, @@ -473,11 +476,12 @@ static int sddr55_read_deviceID(struct us_data *us, unsigned char *deviceID) { int result; - unsigned char command[8] = { - 0, 0, 0, 0, 0, 0xb0, 0, 0x84 - }; - unsigned char content[64]; + unsigned char *command = us->iobuf; + unsigned char *content = us->iobuf; + memset(command, 0, 8); + command[5] = 0xB0; + command[7] = 0x84; result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8); US_DEBUGP("Result of send_control for device ID is %d\n", @@ -598,7 +602,7 @@ static int sddr55_read_map(struct us_data *us) { struct sddr55_card_info *info = (struct sddr55_card_info *)(us->extra); int numblocks; unsigned char *buffer; - unsigned char command[8] = { 0, 0, 0, 0, 0, 0xb0, 0, 0x8a}; + unsigned char *command = us->iobuf; int i; unsigned short lba; unsigned short max_lba; @@ -614,7 +618,10 @@ static int sddr55_read_map(struct us_data *us) { if (!buffer) return -1; + memset(command, 0, 8); + command[5] = 0xB0; command[6] = numblocks * 2 / 256; + command[7] = 0x8A; result = sddr55_bulk_transport(us, SCSI_DATA_WRITE, command, 8); diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 0f75ad0fad35..ed287d244040 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h @@ -119,7 +119,7 @@ UNUSUAL_DEV( 0x04b8, 0x0602, 0x0110, 0x0110, UNUSUAL_DEV( 0x04cb, 0x0100, 0x0000, 0x2210, "Fujifilm", "FinePix 1400Zoom", - US_SC_8070, US_PR_CBI, NULL, US_FL_FIX_INQUIRY), + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_FIX_INQUIRY), /* Reported by Peter Wächtler <pwaechtler@loewe-komp.de> * The device needs the flags only. @@ -236,7 +236,7 @@ UNUSUAL_DEV( 0x0525, 0xa140, 0x0100, 0x0100, UNUSUAL_DEV( 0x054c, 0x0010, 0x0106, 0x0450, "Sony", "DSC-S30/S70/S75/505V/F505/F707/F717/P8", - US_SC_SCSI, US_PR_CB, NULL, + US_SC_SCSI, US_PR_DEVICE, NULL, US_FL_SINGLE_LUN | US_FL_MODE_XLATE ), /* Reported by wim@geeks.nl */ @@ -555,7 +555,7 @@ UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, UNUSUAL_DEV( 0x08ca, 0x2011, 0x0000, 0x9999, "AIPTEK", "PocketCAM 3Mega", - US_SC_SCSI, US_PR_BULK, NULL, + US_SC_DEVICE, US_PR_DEVICE, NULL, US_FL_MODE_XLATE ), /* aeb */ diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 0d9f1053c6df..0a969d577ed2 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -69,11 +69,10 @@ struct us_unusual_dev { /* Flag definitions: these entries are static */ #define US_FL_SINGLE_LUN 0x00000001 /* allow access to only LUN 0 */ -#define US_FL_MODE_XLATE 0x00000002 /* translate _6 to _10 commands for - Win/MacOS compatibility */ +#define US_FL_MODE_XLATE 0 /* [no longer used] */ #define US_FL_IGNORE_SER 0 /* [no longer used] */ #define US_FL_SCM_MULT_TARG 0x00000020 /* supports multiple targets */ -#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs fixing */ +#define US_FL_FIX_INQUIRY 0x00000040 /* INQUIRY response needs faking */ #define US_FL_FIX_CAPACITY 0x00000080 /* READ CAPACITY response too big */ /* Dynamic flag definitions: used in set_bit() etc. */ diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c index a4da9e864e02..1a7c8cbf584b 100644 --- a/drivers/usb/usb-skeleton.c +++ b/drivers/usb/usb-skeleton.c @@ -507,7 +507,7 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i struct usb_endpoint_descriptor *endpoint; size_t buffer_size; int i; - int retval; + int retval = -ENOMEM; /* See if the device offered us matches what we can accept */ if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) || @@ -515,18 +515,11 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i return -ENODEV; } - retval = usb_register_dev (interface, &skel_class); - if (retval) { - /* something prevented us from registering this driver */ - err ("Not able to get a minor for this device."); - goto exit; - } - /* allocate memory for our device state and initialize it */ dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL); if (dev == NULL) { err ("Out of memory"); - goto exit_minor; + goto error; } memset (dev, 0x00, sizeof (*dev)); @@ -603,24 +596,24 @@ static int skel_probe(struct usb_interface *interface, const struct usb_device_i /* allow device read, write and ioctl */ dev->present = 1; + /* we can register the device now, as it is ready */ + usb_set_intfdata (interface, dev); + retval = usb_register_dev (interface, &skel_class); + if (retval) { + /* something prevented us from registering this driver */ + err ("Not able to get a minor for this device."); + usb_set_intfdata (interface, NULL); + goto error; + } + + /* let the user know what node this device is now attached to */ info ("USB Skeleton device now attached to USBSkel-%d", dev->minor); - - goto exit; + return 0; error: skel_delete (dev); - dev = NULL; - -exit_minor: - usb_deregister_dev (interface, &skel_class); - -exit: - if (dev) { - usb_set_intfdata (interface, dev); - return 0; - } - return -ENODEV; + return retval; } |
