Commit 71380949 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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

into kroah.com:/home/greg/linux/BK/gregkh-2.5
parents 9892c3b0 25b365ac
......@@ -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;
......
......@@ -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,
......
......@@ -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)
......
......@@ -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 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
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 @@ int usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
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().
*/
......
......@@ -1293,7 +1293,8 @@ static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
}
/* 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 @@ static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
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 @@ static void hcd_endpoint_disable (struct usb_device *udev, int endpoint)
/* 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).
......
......@@ -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) {
......
/*
* 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;
}
/*-------------------------------------------------------------------------*/
......
......@@ -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;
......
......@@ -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
......
......@@ -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)
......
......@@ -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 @@ ohci_endpoint_disable (struct usb_hcd *hcd, struct hcd_dev *dev, int ep)
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);
......
......@@ -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?
......
......@@ -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 */
......
......@@ -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))
......
......@@ -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;
}
......
......@@ -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 */
......
......@@ -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:
......
/*****************************************************************************
/*****************************************************************************
* 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;
}
......
......@@ -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 */
......
......@@ -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);
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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:
......
......@@ -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;
......
......@@ -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;
......
......@@ -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) },
......
......@@ -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
*/
......
......@@ -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) },
......
......@@ -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
......
......@@ -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)
......
......@@ -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);
}
......
......@@ -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;
......
......@@ -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,
......
......@@ -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);
......
......@@ -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;
}
......@@ -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
......
......@@ -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);
......
......@@ -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 Wchtler <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 */
......
......@@ -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. */
......
......@@ -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;
}
......
......@@ -80,7 +80,8 @@ struct usb_host_interface {
* @act_altsetting: index of current altsetting. this number is always
* less than num_altsetting. after the device is configured, each
* interface uses its default setting of zero.
* @max_altsetting:
* @max_altsetting: the max number of altsettings for this interface.
* @driver: the USB driver that is bound to this interface.
* @minor: the minor number assigned to this interface, if this
* interface is bound to a driver that uses the USB major number.
* If this interface does not use the USB major, this field should
......@@ -409,7 +410,11 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
* do (or don't) show up otherwise in the filesystem.
* @id_table: USB drivers use ID table to support hotplugging.
* Export this with MODULE_DEVICE_TABLE(usb,...). This must be set
* or your driver's probe function will never get called.
* or your driver's probe function will never get called.
* @driver: the driver model core driver structure.
* @serialize: a semaphore used to serialize access to this driver. Used
* in the probe and disconnect functions. Only the USB core should use
* this lock.
*
* USB drivers must provide a name, probe() and disconnect() methods,
* and an id_table. Other driver fields are optional.
......@@ -575,6 +580,8 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
* it likes with the URB, including resubmitting or freeing it.
* @iso_frame_desc: Used to provide arrays of ISO transfer buffers and to
* collect the transfer status for each buffer.
* @timeout: If set to zero, the urb will never timeout. Otherwise this is
* the time in jiffies that this urb will timeout in.
*
* This structure identifies USB transfer requests. URBs must be allocated by
* calling usb_alloc_urb() and freed with a call to usb_free_urb().
......@@ -677,10 +684,14 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *);
*/
struct urb
{
/* private, usb core and host controller only fields in the urb */
spinlock_t lock; /* lock for the URB */
atomic_t count; /* reference count of the URB */
void *hcpriv; /* private data for host controller */
struct list_head urb_list; /* list pointer to all active urbs */
int bandwidth; /* bandwidth for INT/ISO request */
/* public, documented fields in the urb that can be used by drivers */
struct usb_device *dev; /* (in) pointer to associated device */
unsigned int pipe; /* (in) pipe information */
int status; /* (return) non-ISO status */
......@@ -689,7 +700,6 @@ struct urb
dma_addr_t transfer_dma; /* (in) dma addr for transfer_buffer */
int transfer_buffer_length; /* (in) data buffer length */
int actual_length; /* (return) actual transfer length */
int bandwidth; /* bandwidth for INT/ISO request */
unsigned char *setup_packet; /* (in) setup packet (control only) */
dma_addr_t setup_dma; /* (in) dma addr for setup_packet */
int start_frame; /* (modify) start frame (INT/ISO) */
......@@ -891,8 +901,10 @@ struct usb_sg_request {
int status;
size_t bytes;
// members not documented above are private to usbcore,
// and are not provided for driver access!
/*
* members below are private to usbcore,
* and are not provided for driver access!
*/
spinlock_t lock;
struct usb_device *dev;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment