Commit 460223d2 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (39 commits)
  USB: at91-ohci, handle extra at91sam9261 ahb clock
  USB: another id for cp2101 driver
  USB: ueagle-atm.c needs sched.h
  USB: at91_udc, shrink runtime footprint
  usbnet: add missing Kconfig for KC2190 cables
  usbnet: init fault (oops) cleanup, whitespace fixes
  usbnet: recognize SiteCom CN-124
  usb: Remove Airprime device from option.c
  USB: change __init to __devinit for isp116x_probe
  USB: ps3: don't call ps3_system_bus_driver_register on other platforms
  USB: hid-core.c: Removes GTCO CalComp Interwrite IPanel PIDs from blacklist
  USB: kernel-doc fixes
  USB: quirky device for cdc-acm
  USB: cdc-acm: fix incorrect throtteling, make set_control optional
  USB: unconfigure devices which have config 0
  USB: make usb_iso_packet_descriptor.status signed
  USB: fix g_serial small error
  USB: use __u32 rather than u32 in userspace ioctls in usbdevice_fs.h
  USB Storage: US_FL_IGNORE_RESIDUE needed for Aiptek MP3 Player
  USB: Fix misspelled "USBNET_MII" kernel config option.
  ...
parents 255f0385 ed077bb7
...@@ -1269,9 +1269,18 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname, ...@@ -1269,9 +1269,18 @@ sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
/* Some devices return the total number of sectors, not the /* Some devices return the total number of sectors, not the
* highest sector number. Make the necessary adjustment. */ * highest sector number. Make the necessary adjustment. */
if (sdp->fix_capacity) if (sdp->fix_capacity) {
--sdkp->capacity; --sdkp->capacity;
/* Some devices have version which report the correct sizes
* and others which do not. We guess size according to a heuristic
* and err on the side of lowering the capacity. */
} else {
if (sdp->guess_capacity)
if (sdkp->capacity & 0x01) /* odd sizes are odd */
--sdkp->capacity;
}
got_data: got_data:
if (sector_size == 0) { if (sector_size == 0) {
sector_size = 512; sector_size = 512;
......
...@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_SERIAL) += serial/ ...@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_SERIAL) += serial/
obj-$(CONFIG_USB_ADUTUX) += misc/ obj-$(CONFIG_USB_ADUTUX) += misc/
obj-$(CONFIG_USB_APPLEDISPLAY) += misc/ obj-$(CONFIG_USB_APPLEDISPLAY) += misc/
obj-$(CONFIG_USB_AUERSWALD) += misc/ obj-$(CONFIG_USB_AUERSWALD) += misc/
obj-$(CONFIG_USB_BERRY_CHARGE) += misc/
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/ obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
obj-$(CONFIG_USB_CYTHERM) += misc/ obj-$(CONFIG_USB_CYTHERM) += misc/
obj-$(CONFIG_USB_EMI26) += misc/ obj-$(CONFIG_USB_EMI26) += misc/
......
...@@ -61,6 +61,7 @@ ...@@ -61,6 +61,7 @@
#include <linux/usb.h> #include <linux/usb.h>
#include <linux/firmware.h> #include <linux/firmware.h>
#include <linux/ctype.h> #include <linux/ctype.h>
#include <linux/sched.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/version.h> #include <linux/version.h>
#include <linux/mutex.h> #include <linux/mutex.h>
......
...@@ -326,10 +326,16 @@ static void acm_rx_tasklet(unsigned long _acm) ...@@ -326,10 +326,16 @@ static void acm_rx_tasklet(unsigned long _acm)
struct tty_struct *tty = acm->tty; struct tty_struct *tty = acm->tty;
struct acm_ru *rcv; struct acm_ru *rcv;
unsigned long flags; unsigned long flags;
int i = 0; unsigned char throttled;
dbg("Entering acm_rx_tasklet"); dbg("Entering acm_rx_tasklet");
if (!ACM_READY(acm) || acm->throttle) if (!ACM_READY(acm))
return;
spin_lock(&acm->throttle_lock);
throttled = acm->throttle;
spin_unlock(&acm->throttle_lock);
if (throttled)
return; return;
next_buffer: next_buffer:
...@@ -346,22 +352,20 @@ static void acm_rx_tasklet(unsigned long _acm) ...@@ -346,22 +352,20 @@ static void acm_rx_tasklet(unsigned long _acm)
dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
tty_buffer_request_room(tty, buf->size); tty_buffer_request_room(tty, buf->size);
if (!acm->throttle) spin_lock(&acm->throttle_lock);
throttled = acm->throttle;
spin_unlock(&acm->throttle_lock);
if (!throttled)
tty_insert_flip_string(tty, buf->base, buf->size); tty_insert_flip_string(tty, buf->base, buf->size);
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty);
spin_lock(&acm->throttle_lock); if (throttled) {
if (acm->throttle) { dbg("Throttling noticed");
dbg("Throtteling noticed");
memmove(buf->base, buf->base + i, buf->size - i);
buf->size -= i;
spin_unlock(&acm->throttle_lock);
spin_lock_irqsave(&acm->read_lock, flags); spin_lock_irqsave(&acm->read_lock, flags);
list_add(&buf->list, &acm->filled_read_bufs); list_add(&buf->list, &acm->filled_read_bufs);
spin_unlock_irqrestore(&acm->read_lock, flags); spin_unlock_irqrestore(&acm->read_lock, flags);
return; return;
} }
spin_unlock(&acm->throttle_lock);
spin_lock_irqsave(&acm->read_lock, flags); spin_lock_irqsave(&acm->read_lock, flags);
list_add(&buf->list, &acm->spare_read_bufs); list_add(&buf->list, &acm->spare_read_bufs);
...@@ -467,7 +471,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -467,7 +471,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
goto bail_out; goto bail_out;
} }
if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
(acm->ctrl_caps & USB_CDC_CAP_LINE))
goto full_bailout; goto full_bailout;
INIT_LIST_HEAD(&acm->spare_read_urbs); INIT_LIST_HEAD(&acm->spare_read_urbs);
...@@ -480,6 +485,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp) ...@@ -480,6 +485,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
list_add(&(acm->rb[i].list), &acm->spare_read_bufs); list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
} }
acm->throttle = 0;
tasklet_schedule(&acm->urb_task); tasklet_schedule(&acm->urb_task);
done: done:
...@@ -1092,6 +1099,10 @@ static struct usb_device_id acm_ids[] = { ...@@ -1092,6 +1099,10 @@ static struct usb_device_id acm_ids[] = {
{ USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */ { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
.driver_info = SINGLE_RX_URB, /* firmware bug */ .driver_info = SINGLE_RX_URB, /* firmware bug */
}, },
{ USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
.driver_info = NO_UNION_NORMAL, /* has no union descriptor */
},
/* control interfaces with various AT-command sets */ /* control interfaces with various AT-command sets */
{ USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
USB_CDC_ACM_PROTO_AT_V25TER) }, USB_CDC_ACM_PROTO_AT_V25TER) },
......
...@@ -604,10 +604,6 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct ...@@ -604,10 +604,6 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
lock_kernel(); lock_kernel();
if (!st) { if (!st) {
st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL); st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
if (!st) {
unlock_kernel();
return POLLIN;
}
/* we may have dropped BKL - need to check for having lost the race */ /* we may have dropped BKL - need to check for having lost the race */
if (file->private_data) { if (file->private_data) {
...@@ -615,6 +611,11 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct ...@@ -615,6 +611,11 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
st = file->private_data; st = file->private_data;
goto lost_race; goto lost_race;
} }
/* we haven't lost - check for allocation failure now */
if (!st) {
unlock_kernel();
return POLLIN;
}
/* /*
* need to prevent the module from being unloaded, since * need to prevent the module from being unloaded, since
......
...@@ -857,11 +857,11 @@ static int proc_setintf(struct dev_state *ps, void __user *arg) ...@@ -857,11 +857,11 @@ static int proc_setintf(struct dev_state *ps, void __user *arg)
static int proc_setconfig(struct dev_state *ps, void __user *arg) static int proc_setconfig(struct dev_state *ps, void __user *arg)
{ {
unsigned int u; int u;
int status = 0; int status = 0;
struct usb_host_config *actconfig; struct usb_host_config *actconfig;
if (get_user(u, (unsigned int __user *)arg)) if (get_user(u, (int __user *)arg))
return -EFAULT; return -EFAULT;
actconfig = ps->dev->actconfig; actconfig = ps->dev->actconfig;
......
...@@ -743,6 +743,7 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver); ...@@ -743,6 +743,7 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver);
* usb_register_driver - register a USB interface driver * usb_register_driver - register a USB interface driver
* @new_driver: USB operations for the interface driver * @new_driver: USB operations for the interface driver
* @owner: module owner of this driver. * @owner: module owner of this driver.
* @mod_name: module name string
* *
* Registers a USB interface driver with the USB core. The list of * Registers a USB interface driver with the USB core. The list of
* unattached interfaces will be rescanned whenever a new driver is * unattached interfaces will be rescanned whenever a new driver is
......
...@@ -229,7 +229,7 @@ static int init_endpoint_class(void) ...@@ -229,7 +229,7 @@ static int init_endpoint_class(void)
kref_init(&ep_class->kref); kref_init(&ep_class->kref);
ep_class->class = class_create(THIS_MODULE, "usb_endpoint"); ep_class->class = class_create(THIS_MODULE, "usb_endpoint");
if (IS_ERR(ep_class->class)) { if (IS_ERR(ep_class->class)) {
result = IS_ERR(ep_class->class); result = PTR_ERR(ep_class->class);
goto class_create_error; goto class_create_error;
} }
......
...@@ -184,7 +184,7 @@ static void generic_disconnect(struct usb_device *udev) ...@@ -184,7 +184,7 @@ static void generic_disconnect(struct usb_device *udev)
/* if this is only an unbind, not a physical disconnect, then /* if this is only an unbind, not a physical disconnect, then
* unconfigure the device */ * unconfigure the device */
if (udev->actconfig) if (udev->actconfig)
usb_set_configuration(udev, 0); usb_set_configuration(udev, -1);
usb_remove_sysfs_dev_files(udev); usb_remove_sysfs_dev_files(udev);
} }
......
...@@ -44,6 +44,7 @@ struct usb_hub { ...@@ -44,6 +44,7 @@ struct usb_hub {
struct usb_hub_status hub; struct usb_hub_status hub;
struct usb_port_status port; struct usb_port_status port;
} *status; /* buffer for status reports */ } *status; /* buffer for status reports */
struct mutex status_mutex; /* for the status buffer */
int error; /* last reported error */ int error; /* last reported error */
int nerrors; /* track consecutive errors */ int nerrors; /* track consecutive errors */
...@@ -535,6 +536,7 @@ static int hub_hub_status(struct usb_hub *hub, ...@@ -535,6 +536,7 @@ static int hub_hub_status(struct usb_hub *hub,
{ {
int ret; int ret;
mutex_lock(&hub->status_mutex);
ret = get_hub_status(hub->hdev, &hub->status->hub); ret = get_hub_status(hub->hdev, &hub->status->hub);
if (ret < 0) if (ret < 0)
dev_err (hub->intfdev, dev_err (hub->intfdev,
...@@ -544,6 +546,7 @@ static int hub_hub_status(struct usb_hub *hub, ...@@ -544,6 +546,7 @@ static int hub_hub_status(struct usb_hub *hub,
*change = le16_to_cpu(hub->status->hub.wHubChange); *change = le16_to_cpu(hub->status->hub.wHubChange);
ret = 0; ret = 0;
} }
mutex_unlock(&hub->status_mutex);
return ret; return ret;
} }
...@@ -617,6 +620,7 @@ static int hub_configure(struct usb_hub *hub, ...@@ -617,6 +620,7 @@ static int hub_configure(struct usb_hub *hub,
ret = -ENOMEM; ret = -ENOMEM;
goto fail; goto fail;
} }
mutex_init(&hub->status_mutex);
hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
if (!hub->descriptor) { if (!hub->descriptor) {
...@@ -1396,6 +1400,7 @@ static int hub_port_status(struct usb_hub *hub, int port1, ...@@ -1396,6 +1400,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
{ {
int ret; int ret;
mutex_lock(&hub->status_mutex);
ret = get_port_status(hub->hdev, port1, &hub->status->port); ret = get_port_status(hub->hdev, port1, &hub->status->port);
if (ret < 4) { if (ret < 4) {
dev_err (hub->intfdev, dev_err (hub->intfdev,
...@@ -1407,6 +1412,7 @@ static int hub_port_status(struct usb_hub *hub, int port1, ...@@ -1407,6 +1412,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
*change = le16_to_cpu(hub->status->port.wPortChange); *change = le16_to_cpu(hub->status->port.wPortChange);
ret = 0; ret = 0;
} }
mutex_unlock(&hub->status_mutex);
return ret; return ret;
} }
...@@ -1904,6 +1910,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) ...@@ -1904,6 +1910,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
struct usb_hub *hub = usb_get_intfdata (intf); struct usb_hub *hub = usb_get_intfdata (intf);
struct usb_device *hdev = hub->hdev; struct usb_device *hdev = hub->hdev;
unsigned port1; unsigned port1;
int status = 0;
/* fail if children aren't already suspended */ /* fail if children aren't already suspended */
for (port1 = 1; port1 <= hdev->maxchild; port1++) { for (port1 = 1; port1 <= hdev->maxchild; port1++) {
...@@ -1927,24 +1934,18 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg) ...@@ -1927,24 +1934,18 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
dev_dbg(&intf->dev, "%s\n", __FUNCTION__); dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
/* stop khubd and related activity */
hub_quiesce(hub);
/* "global suspend" of the downstream HC-to-USB interface */ /* "global suspend" of the downstream HC-to-USB interface */
if (!hdev->parent) { if (!hdev->parent) {
struct usb_bus *bus = hdev->bus; status = hcd_bus_suspend(hdev->bus);
if (bus) {
int status = hcd_bus_suspend (bus);
if (status != 0) { if (status != 0) {
dev_dbg(&hdev->dev, "'global' suspend %d\n", dev_dbg(&hdev->dev, "'global' suspend %d\n", status);
status); hub_activate(hub);
return status;
} }
} else
return -EOPNOTSUPP;
} }
return status;
/* stop khubd and related activity */
hub_quiesce(hub);
return 0;
} }
static int hub_resume(struct usb_interface *intf) static int hub_resume(struct usb_interface *intf)
......
...@@ -1316,6 +1316,14 @@ static void release_interface(struct device *dev) ...@@ -1316,6 +1316,14 @@ static void release_interface(struct device *dev)
* use this kind of configurability; many devices only have one * use this kind of configurability; many devices only have one
* configuration. * configuration.
* *
* @configuration is the value of the configuration to be installed.
* According to the USB spec (e.g. section 9.1.1.5), configuration values
* must be non-zero; a value of zero indicates that the device in
* unconfigured. However some devices erroneously use 0 as one of their
* configuration values. To help manage such devices, this routine will
* accept @configuration = -1 as indicating the device should be put in
* an unconfigured state.
*
* USB device configurations may affect Linux interoperability, * USB device configurations may affect Linux interoperability,
* power consumption and the functionality available. For example, * power consumption and the functionality available. For example,
* the default configuration is limited to using 100mA of bus power, * the default configuration is limited to using 100mA of bus power,
...@@ -1347,18 +1355,24 @@ int usb_set_configuration(struct usb_device *dev, int configuration) ...@@ -1347,18 +1355,24 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
struct usb_interface **new_interfaces = NULL; struct usb_interface **new_interfaces = NULL;
int n, nintf; int n, nintf;
if (configuration == -1)
configuration = 0;
else {
for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
if (dev->config[i].desc.bConfigurationValue == configuration) { if (dev->config[i].desc.bConfigurationValue ==
configuration) {
cp = &dev->config[i]; cp = &dev->config[i];
break; break;
} }
} }
}
if ((!cp && configuration != 0)) if ((!cp && configuration != 0))
return -EINVAL; return -EINVAL;
/* The USB spec says configuration 0 means unconfigured. /* The USB spec says configuration 0 means unconfigured.
* But if a device includes a configuration numbered 0, * But if a device includes a configuration numbered 0,
* we will accept it as a correctly configured state. * we will accept it as a correctly configured state.
* Use -1 if you really want to unconfigure the device.
*/ */
if (cp && configuration == 0) if (cp && configuration == 0)
dev_warn(&dev->dev, "config 0 descriptor??\n"); dev_warn(&dev->dev, "config 0 descriptor??\n");
......
...@@ -31,7 +31,7 @@ static struct usb_device_id whitelist_table [] = { ...@@ -31,7 +31,7 @@ static struct usb_device_id whitelist_table [] = {
{ USB_DEVICE_INFO(7, 1, 3) }, { USB_DEVICE_INFO(7, 1, 3) },
#endif #endif
#ifdef CONFIG_USB_CDCETHER #ifdef CONFIG_USB_NET_CDCETHER
/* Linux-USB CDC Ethernet gadget */ /* Linux-USB CDC Ethernet gadget */
{ USB_DEVICE(0x0525, 0xa4a1), }, { USB_DEVICE(0x0525, 0xa4a1), },
/* Linux-USB CDC Ethernet + RNDIS gadget */ /* Linux-USB CDC Ethernet + RNDIS gadget */
......
...@@ -63,7 +63,7 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr, ...@@ -63,7 +63,7 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr,
struct usb_device *udev = to_usb_device(dev); struct usb_device *udev = to_usb_device(dev);
int config, value; int config, value;
if (sscanf(buf, "%u", &config) != 1 || config > 255) if (sscanf(buf, "%d", &config) != 1 || config < -1 || config > 255)
return -EINVAL; return -EINVAL;
usb_lock_device(udev); usb_lock_device(udev);
value = usb_set_configuration(udev, config); value = usb_set_configuration(udev, config);
......
...@@ -784,7 +784,7 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value) ...@@ -784,7 +784,7 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value)
return status; return status;
} }
static struct usb_ep_ops at91_ep_ops = { static const struct usb_ep_ops at91_ep_ops = {
.enable = at91_ep_enable, .enable = at91_ep_enable,
.disable = at91_ep_disable, .disable = at91_ep_disable,
.alloc_request = at91_ep_alloc_request, .alloc_request = at91_ep_alloc_request,
...@@ -1651,7 +1651,7 @@ static void at91udc_shutdown(struct platform_device *dev) ...@@ -1651,7 +1651,7 @@ static void at91udc_shutdown(struct platform_device *dev)
pullup(platform_get_drvdata(dev), 0); pullup(platform_get_drvdata(dev), 0);
} }
static int __devinit at91udc_probe(struct platform_device *pdev) static int __init at91udc_probe(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct at91_udc *udc; struct at91_udc *udc;
...@@ -1762,7 +1762,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev) ...@@ -1762,7 +1762,7 @@ static int __devinit at91udc_probe(struct platform_device *pdev)
return retval; return retval;
} }
static int __devexit at91udc_remove(struct platform_device *pdev) static int __exit at91udc_remove(struct platform_device *pdev)
{ {
struct at91_udc *udc = platform_get_drvdata(pdev); struct at91_udc *udc = platform_get_drvdata(pdev);
struct resource *res; struct resource *res;
...@@ -1836,8 +1836,7 @@ static int at91udc_resume(struct platform_device *pdev) ...@@ -1836,8 +1836,7 @@ static int at91udc_resume(struct platform_device *pdev)
#endif #endif
static struct platform_driver at91_udc = { static struct platform_driver at91_udc = {
.probe = at91udc_probe, .remove = __exit_p(at91udc_remove),
.remove = __devexit_p(at91udc_remove),
.shutdown = at91udc_shutdown, .shutdown = at91udc_shutdown,
.suspend = at91udc_suspend, .suspend = at91udc_suspend,
.resume = at91udc_resume, .resume = at91udc_resume,
...@@ -1847,13 +1846,13 @@ static struct platform_driver at91_udc = { ...@@ -1847,13 +1846,13 @@ static struct platform_driver at91_udc = {
}, },
}; };
static int __devinit udc_init_module(void) static int __init udc_init_module(void)
{ {
return platform_driver_register(&at91_udc); return platform_driver_probe(&at91_udc, at91udc_probe);
} }
module_init(udc_init_module); module_init(udc_init_module);
static void __devexit udc_exit_module(void) static void __exit udc_exit_module(void)
{ {
platform_driver_unregister(&at91_udc); platform_driver_unregister(&at91_udc);
} }
......
...@@ -1699,6 +1699,7 @@ static int gs_setup_class(struct usb_gadget *gadget, ...@@ -1699,6 +1699,7 @@ static int gs_setup_class(struct usb_gadget *gadget,
memcpy(&port->port_line_coding, req->buf, ret); memcpy(&port->port_line_coding, req->buf, ret);
spin_unlock(&port->port_lock); spin_unlock(&port->port_lock);
} }
ret = 0;
break; break;
case USB_CDC_REQ_GET_LINE_CODING: case USB_CDC_REQ_GET_LINE_CODING:
......
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/system.h> #include <asm/system.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#ifdef CONFIG_PPC_PS3
#include <asm/firmware.h>
#endif
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -299,6 +302,19 @@ static void ehci_watchdog (unsigned long param) ...@@ -299,6 +302,19 @@ static void ehci_watchdog (unsigned long param)
spin_unlock_irqrestore (&ehci->lock, flags); spin_unlock_irqrestore (&ehci->lock, flags);
} }
/* On some systems, leaving remote wakeup enabled prevents system shutdown.
* The firmware seems to think that powering off is a wakeup event!
* This routine turns off remote wakeup and everything else, on all ports.
*/
static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
{
int port = HCS_N_PORTS(ehci->hcs_params);
while (port--)
ehci_writel(ehci, PORT_RWC_BITS,
&ehci->regs->port_status[port]);
}
/* ehci_shutdown kick in for silicon on any bus (not just pci, etc). /* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
* This forcibly disables dma and IRQs, helping kexec and other cases * This forcibly disables dma and IRQs, helping kexec and other cases
* where the next system software may expect clean state. * where the next system software may expect clean state.
...@@ -310,9 +326,13 @@ ehci_shutdown (struct usb_hcd *hcd) ...@@ -310,9 +326,13 @@ ehci_shutdown (struct usb_hcd *hcd)
ehci = hcd_to_ehci (hcd); ehci = hcd_to_ehci (hcd);
(void) ehci_halt (ehci); (void) ehci_halt (ehci);
ehci_turn_off_all_ports(ehci);
/* make BIOS/etc use companion controller during reboot */ /* make BIOS/etc use companion controller during reboot */
ehci_writel(ehci, 0, &ehci->regs->configured_flag); ehci_writel(ehci, 0, &ehci->regs->configured_flag);
/* unblock posted writes */
ehci_readl(ehci, &ehci->regs->configured_flag);
} }
static void ehci_port_power (struct ehci_hcd *ehci, int is_on) static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
...@@ -951,7 +971,9 @@ static int __init ehci_hcd_init(void) ...@@ -951,7 +971,9 @@ static int __init ehci_hcd_init(void)
#endif #endif
#ifdef PS3_SYSTEM_BUS_DRIVER #ifdef PS3_SYSTEM_BUS_DRIVER
retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
retval = ps3_system_bus_driver_register(
&PS3_SYSTEM_BUS_DRIVER);
if (retval < 0) { if (retval < 0) {
#ifdef PLATFORM_DRIVER #ifdef PLATFORM_DRIVER
platform_driver_unregister(&PLATFORM_DRIVER); platform_driver_unregister(&PLATFORM_DRIVER);
...@@ -961,6 +983,7 @@ static int __init ehci_hcd_init(void) ...@@ -961,6 +983,7 @@ static int __init ehci_hcd_init(void)
#endif #endif
return retval; return retval;
} }
}
#endif #endif
return retval; return retval;
...@@ -976,6 +999,7 @@ static void __exit ehci_hcd_cleanup(void) ...@@ -976,6 +999,7 @@ static void __exit ehci_hcd_cleanup(void)
pci_unregister_driver(&PCI_DRIVER); pci_unregister_driver(&PCI_DRIVER);
#endif #endif
#ifdef PS3_SYSTEM_BUS_DRIVER #ifdef PS3_SYSTEM_BUS_DRIVER
if (firmware_has_feature(FW_FEATURE_PS3_LV1))
ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
#endif #endif
} }
......
...@@ -36,6 +36,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd) ...@@ -36,6 +36,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
int port; int port;
int mask; int mask;
ehci_dbg(ehci, "suspend root hub\n");
if (time_before (jiffies, ehci->next_statechange)) if (time_before (jiffies, ehci->next_statechange))
msleep(5); msleep(5);
......
...@@ -1577,7 +1577,7 @@ static int isp116x_remove(struct platform_device *pdev) ...@@ -1577,7 +1577,7 @@ static int isp116x_remove(struct platform_device *pdev)
#define resource_len(r) (((r)->end - (r)->start) + 1) #define resource_len(r) (((r)->end - (r)->start) + 1)
static int __init isp116x_probe(struct platform_device *pdev) static int __devinit isp116x_probe(struct platform_device *pdev)
{ {
struct usb_hcd *hcd; struct usb_hcd *hcd;
struct isp116x *isp116x; struct isp116x *isp116x;
......
...@@ -18,19 +18,38 @@ ...@@ -18,19 +18,38 @@
#include <asm/mach-types.h> #include <asm/mach-types.h>
#include <asm/hardware.h> #include <asm/hardware.h>
#include <asm/arch/board.h> #include <asm/arch/board.h>
#include <asm/arch/cpu.h>
#ifndef CONFIG_ARCH_AT91 #ifndef CONFIG_ARCH_AT91
#error "CONFIG_ARCH_AT91 must be defined." #error "CONFIG_ARCH_AT91 must be defined."
#endif #endif
/* interface and function clocks */ /* interface and function clocks; sometimes also an AHB clock */
static struct clk *iclk, *fclk; static struct clk *iclk, *fclk, *hclk;
static int clocked; static int clocked;
extern int usb_disabled(void); extern int usb_disabled(void);
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
static void at91_start_clock(void)
{
if (cpu_is_at91sam9261())
clk_enable(hclk);
clk_enable(iclk);
clk_enable(fclk);
clocked = 1;
}
static void at91_stop_clock(void)
{
clk_disable(fclk);
clk_disable(iclk);
if (cpu_is_at91sam9261())
clk_disable(hclk);
clocked = 0;
}
static void at91_start_hc(struct platform_device *pdev) static void at91_start_hc(struct platform_device *pdev)
{ {
struct usb_hcd *hcd = platform_get_drvdata(pdev); struct usb_hcd *hcd = platform_get_drvdata(pdev);
...@@ -41,9 +60,7 @@ static void at91_start_hc(struct platform_device *pdev) ...@@ -41,9 +60,7 @@ static void at91_start_hc(struct platform_device *pdev)
/* /*
* Start the USB clocks. * Start the USB clocks.
*/ */
clk_enable(iclk); at91_start_clock();
clk_enable(fclk);
clocked = 1;
/* /*
* The USB host controller must remain in reset. * The USB host controller must remain in reset.
...@@ -66,9 +83,7 @@ static void at91_stop_hc(struct platform_device *pdev) ...@@ -66,9 +83,7 @@ static void at91_stop_hc(struct platform_device *pdev)
/* /*
* Stop the USB clocks. * Stop the USB clocks.
*/ */
clk_disable(fclk); at91_stop_clock();
clk_disable(iclk);
clocked = 0;
} }
...@@ -126,6 +141,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, ...@@ -126,6 +141,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
iclk = clk_get(&pdev->dev, "ohci_clk"); iclk = clk_get(&pdev->dev, "ohci_clk");
fclk = clk_get(&pdev->dev, "uhpck"); fclk = clk_get(&pdev->dev, "uhpck");
if (cpu_is_at91sam9261())
hclk = clk_get(&pdev->dev, "hck0");
at91_start_hc(pdev); at91_start_hc(pdev);
ohci_hcd_init(hcd_to_ohci(hcd)); ohci_hcd_init(hcd_to_ohci(hcd));
...@@ -137,6 +154,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver, ...@@ -137,6 +154,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
/* Error handling */ /* Error handling */
at91_stop_hc(pdev); at91_stop_hc(pdev);
if (cpu_is_at91sam9261())
clk_put(hclk);
clk_put(fclk); clk_put(fclk);
clk_put(iclk); clk_put(iclk);
...@@ -171,9 +190,11 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd, ...@@ -171,9 +190,11 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd,
iounmap(hcd->regs); iounmap(hcd->regs);
release_mem_region(hcd->rsrc_start, hcd->rsrc_len); release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
if (cpu_is_at91sam9261())
clk_put(hclk);
clk_put(fclk); clk_put(fclk);
clk_put(iclk); clk_put(iclk);
fclk = iclk = NULL; fclk = iclk = hclk = NULL;
dev_set_drvdata(&pdev->dev, NULL); dev_set_drvdata(&pdev->dev, NULL);
return 0; return 0;
...@@ -280,9 +301,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg) ...@@ -280,9 +301,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
*/ */
if (at91_suspend_entering_slow_clock()) { if (at91_suspend_entering_slow_clock()) {
ohci_usb_reset (ohci); ohci_usb_reset (ohci);
clk_disable(fclk); at91_stop_clock();
clk_disable(iclk);
clocked = 0;
} }
return 0; return 0;
...@@ -295,11 +314,8 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev) ...@@ -295,11 +314,8 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
if (device_may_wakeup(&pdev->dev)) if (device_may_wakeup(&pdev->dev))
disable_irq_wake(hcd->irq); disable_irq_wake(hcd->irq);
if (!clocked) { if (!clocked)
clk_enable(iclk); at91_start_clock();
clk_enable(fclk);
clocked = 1;
}
return 0; return 0;
} }
......
...@@ -42,6 +42,9 @@ ...@@ -42,6 +42,9 @@
#include <asm/system.h> #include <asm/system.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#include <asm/byteorder.h> #include <asm/byteorder.h>
#ifdef CONFIG_PPC_PS3
#include <asm/firmware.h>
#endif
#include "../core/hcd.h" #include "../core/hcd.h"
...@@ -944,9 +947,12 @@ static int __init ohci_hcd_mod_init(void) ...@@ -944,9 +947,12 @@ static int __init ohci_hcd_mod_init(void)
sizeof (struct ed), sizeof (struct td)); sizeof (struct ed), sizeof (struct td));
#ifdef PS3_SYSTEM_BUS_DRIVER #ifdef PS3_SYSTEM_BUS_DRIVER
retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
retval = ps3_system_bus_driver_register(
&PS3_SYSTEM_BUS_DRIVER);
if (retval < 0) if (retval < 0)
goto error_ps3; goto error_ps3;
}
#endif #endif
#ifdef PLATFORM_DRIVER #ifdef PLATFORM_DRIVER
...@@ -992,6 +998,7 @@ static int __init ohci_hcd_mod_init(void) ...@@ -992,6 +998,7 @@ static int __init ohci_hcd_mod_init(void)
error_platform: error_platform:
#endif #endif
#ifdef PS3_SYSTEM_BUS_DRIVER #ifdef PS3_SYSTEM_BUS_DRIVER
if (firmware_has_feature(FW_FEATURE_PS3_LV1))
ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
error_ps3: error_ps3:
#endif #endif
...@@ -1014,6 +1021,7 @@ static void __exit ohci_hcd_mod_exit(void) ...@@ -1014,6 +1021,7 @@ static void __exit ohci_hcd_mod_exit(void)
platform_driver_unregister(&PLATFORM_DRIVER); platform_driver_unregister(&PLATFORM_DRIVER);
#endif #endif
#ifdef PS3_SYSTEM_BUS_DRIVER #ifdef PS3_SYSTEM_BUS_DRIVER
if (firmware_has_feature(FW_FEATURE_PS3_LV1))
ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
#endif #endif
} }
......
...@@ -515,6 +515,7 @@ void usbhid_close(struct hid_device *hid) ...@@ -515,6 +515,7 @@ void usbhid_close(struct hid_device *hid)
#define USB_VENDOR_ID_TURBOX 0x062a #define USB_VENDOR_ID_TURBOX 0x062a
#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 #define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
#define USB_VENDOR_ID_CIDC 0x1677
/* /*
* Initialize all reports * Initialize all reports
...@@ -548,7 +549,6 @@ void usbhid_init_reports(struct hid_device *hid) ...@@ -548,7 +549,6 @@ void usbhid_init_reports(struct hid_device *hid)
} }
#define USB_VENDOR_ID_GTCO 0x078c #define USB_VENDOR_ID_GTCO 0x078c
#define USB_VENDOR_ID_GTCO_IPANEL_2 0x5543
#define USB_DEVICE_ID_GTCO_90 0x0090 #define USB_DEVICE_ID_GTCO_90 0x0090
#define USB_DEVICE_ID_GTCO_100 0x0100 #define USB_DEVICE_ID_GTCO_100 0x0100
#define USB_DEVICE_ID_GTCO_101 0x0101 #define USB_DEVICE_ID_GTCO_101 0x0101
...@@ -594,8 +594,6 @@ void usbhid_init_reports(struct hid_device *hid) ...@@ -594,8 +594,6 @@ void usbhid_init_reports(struct hid_device *hid)
#define USB_DEVICE_ID_GTCO_1004 0x1004 #define USB_DEVICE_ID_GTCO_1004 0x1004
#define USB_DEVICE_ID_GTCO_1005 0x1005 #define USB_DEVICE_ID_GTCO_1005 0x1005
#define USB_DEVICE_ID_GTCO_1006 0x1006 #define USB_DEVICE_ID_GTCO_1006 0x1006
#define USB_DEVICE_ID_GTCO_8 0x0008
#define USB_DEVICE_ID_GTCO_d 0x000d
#define USB_VENDOR_ID_WACOM 0x056a #define USB_VENDOR_ID_WACOM 0x056a
...@@ -854,8 +852,6 @@ static const struct hid_blacklist { ...@@ -854,8 +852,6 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_8, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_d, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
{ USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE },
...@@ -953,6 +949,8 @@ static const struct hid_blacklist { ...@@ -953,6 +949,8 @@ static const struct hid_blacklist {
{ USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER },
{ USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE },
{ 0, 0 } { 0, 0 }
}; };
......
...@@ -88,6 +88,17 @@ config USB_LCD ...@@ -88,6 +88,17 @@ config USB_LCD
To compile this driver as a module, choose M here: the To compile this driver as a module, choose M here: the
module will be called usblcd. module will be called usblcd.
config USB_BERRY_CHARGE
tristate "USB BlackBerry recharge support"
depends on USB
help
Say Y here if you want to connect a BlackBerry device to your
computer's USB port and have it automatically switch to "recharge"
mode.
To compile this driver as a module, choose M here: the
module will be called berry_charge.
config USB_LED config USB_LED
tristate "USB LED driver support" tristate "USB LED driver support"
depends on USB depends on USB
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
obj-$(CONFIG_USB_ADUTUX) += adutux.o obj-$(CONFIG_USB_ADUTUX) += adutux.o
obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
obj-$(CONFIG_USB_AUERSWALD) += auerswald.o obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o
obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
obj-$(CONFIG_USB_CYTHERM) += cytherm.o obj-$(CONFIG_USB_CYTHERM) += cytherm.o
obj-$(CONFIG_USB_EMI26) += emi26.o obj-$(CONFIG_USB_EMI26) += emi26.o
......
/*
* USB BlackBerry charging module
*
* Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation, version 2.
*
* Information on how to switch configs was taken by the bcharge.cc file
* created by the barry.sf.net project.
*
* bcharge.cc has the following copyright:
* Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
* and is released under the GPLv2.
*
*
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/usb.h>
#define RIM_VENDOR 0x0fca
#define BLACKBERRY 0x0001
static int debug;
#ifdef dbg
#undef dbg
#endif
#define dbg(dev, format, arg...) \
if (debug) \
dev_printk(KERN_DEBUG , dev , format , ## arg)
static struct usb_device_id id_table [] = {
{ USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
{ }, /* Terminating entry */
};
MODULE_DEVICE_TABLE(usb, id_table);
static int magic_charge(struct usb_device *udev)
{
char *dummy_buffer = kzalloc(2, GFP_KERNEL);
int retval;
if (!dummy_buffer)
return -ENOMEM;
/* send two magic commands and then set the configuration. The device
* will then reset itself with the new power usage and should start
* charging. */
/* Note, with testing, it only seems that the first message is really
* needed (at least for the 8700c), but to be safe, we emulate what
* other operating systems seem to be sending to their device. We
* really need to get some specs for this device to be sure about what
* is going on here.
*/
dbg(&udev->dev, "Sending first magic command\n");
retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
if (retval != 2) {
dev_err(&udev->dev, "First magic command failed: %d.\n",
retval);
return retval;
}
dbg(&udev->dev, "Sending first magic command\n");
retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
if (retval != 0) {
dev_err(&udev->dev, "Second magic command failed: %d.\n",
retval);
return retval;
}
dbg(&udev->dev, "Calling set_configuration\n");
retval = usb_driver_set_configuration(udev, 1);
if (retval)
dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
return retval;
}
static int berry_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
struct usb_device *udev = interface_to_usbdev(intf);
dbg(&udev->dev, "Power is set to %dmA\n",
udev->actconfig->desc.bMaxPower * 2);
/* check the power usage so we don't try to enable something that is
* already enabled */
if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
dbg(&udev->dev, "device is already charging, power is "
"set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
return -ENODEV;
}
/* turn the power on */
magic_charge(udev);
/* we don't really want to bind to the device, userspace programs can
* handle the syncing just fine, so get outta here. */
return -ENODEV;
}
static void berry_disconnect(struct usb_interface *intf)
{
}
static struct usb_driver berry_driver = {
.name = "berry_charge",
.probe = berry_probe,
.disconnect = berry_disconnect,
.id_table = id_table,
};
static int __init berry_init(void)
{
return usb_register(&berry_driver);
}
static void __exit berry_exit(void)
{
usb_deregister(&berry_driver);
}
module_init(berry_init);
module_exit(berry_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
module_param(debug, bool, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(debug, "Debug enabled or not");
...@@ -84,6 +84,7 @@ config USB_PEGASUS ...@@ -84,6 +84,7 @@ config USB_PEGASUS
config USB_RTL8150 config USB_RTL8150
tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)" tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)"
depends on EXPERIMENTAL depends on EXPERIMENTAL
select MII
help help
Say Y here if you have RTL8150 based usb-ethernet adapter. Say Y here if you have RTL8150 based usb-ethernet adapter.
Send me <petkan@users.sourceforge.net> any comments you may have. Send me <petkan@users.sourceforge.net> any comments you may have.
...@@ -98,7 +99,7 @@ config USB_USBNET_MII ...@@ -98,7 +99,7 @@ config USB_USBNET_MII
config USB_USBNET config USB_USBNET
tristate "Multi-purpose USB Networking Framework" tristate "Multi-purpose USB Networking Framework"
select MII if USBNET_MII != n select MII if USB_USBNET_MII != n
---help--- ---help---
This driver supports several kinds of network links over USB, This driver supports several kinds of network links over USB,
with "minidrivers" built around a common network driver core with "minidrivers" built around a common network driver core
...@@ -239,6 +240,7 @@ config USB_NET_RNDIS_HOST ...@@ -239,6 +240,7 @@ config USB_NET_RNDIS_HOST
config USB_NET_CDC_SUBSET config USB_NET_CDC_SUBSET
tristate "Simple USB Network Links (CDC Ethernet subset)" tristate "Simple USB Network Links (CDC Ethernet subset)"
depends on USB_USBNET depends on USB_USBNET
default y
help help
This driver module supports USB network devices that can work This driver module supports USB network devices that can work
without any device-specific information. Select it if you have without any device-specific information. Select it if you have
...@@ -298,6 +300,13 @@ config USB_EPSON2888 ...@@ -298,6 +300,13 @@ config USB_EPSON2888
Choose this option to support the usb networking links used Choose this option to support the usb networking links used
by some sample firmware from Epson. by some sample firmware from Epson.
config USB_KC2190
boolean "KT Technology KC2190 based cables (InstaNet)"
depends on USB_NET_CDC_SUBSET && EXPERIMENTAL
help
 Choose this option if you're using a host-to-host cable
 with one of these chips.
config USB_NET_ZAURUS config USB_NET_ZAURUS
tristate "Sharp Zaurus (stock ROMs) and compatible" tristate "Sharp Zaurus (stock ROMs) and compatible"
depends on USB_USBNET depends on USB_USBNET
......
...@@ -351,9 +351,11 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb, ...@@ -351,9 +351,11 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
skb_push(skb, 4); skb_push(skb, 4);
packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
cpu_to_le32s(&packet_len);
memcpy(skb->data, &packet_len, sizeof(packet_len)); memcpy(skb->data, &packet_len, sizeof(packet_len));
if ((skb->len % 512) == 0) { if ((skb->len % 512) == 0) {
cpu_to_le32s(&padbytes);
memcpy( skb->tail, &padbytes, sizeof(padbytes)); memcpy( skb->tail, &padbytes, sizeof(padbytes));
skb_put(skb, sizeof(padbytes)); skb_put(skb, sizeof(padbytes));
} }
......
...@@ -79,13 +79,19 @@ static int always_connected (struct usbnet *dev) ...@@ -79,13 +79,19 @@ static int always_connected (struct usbnet *dev)
* *
* ALi M5632 driver ... does high speed * ALi M5632 driver ... does high speed
* *
* NOTE that the MS-Windows drivers for this chip use some funky and
* (naturally) undocumented 7-byte prefix to each packet, so this is a
* case where we don't currently interoperate. Also, once you unplug
* one end of the cable, you need to replug the other end too ... since
* chip docs are unavailable, there's no way to reset the relevant state
* short of a power cycle.
*
*-------------------------------------------------------------------------*/ *-------------------------------------------------------------------------*/
static const struct driver_info ali_m5632_info = { static const struct driver_info ali_m5632_info = {
.description = "ALi M5632", .description = "ALi M5632",
}; };
#endif #endif
...@@ -159,6 +165,11 @@ static const struct driver_info epson2888_info = { ...@@ -159,6 +165,11 @@ static const struct driver_info epson2888_info = {
#endif /* CONFIG_USB_EPSON2888 */ #endif /* CONFIG_USB_EPSON2888 */
/*-------------------------------------------------------------------------
*
* info from Jonathan McDowell <noodles@earth.li>
*
*-------------------------------------------------------------------------*/
#ifdef CONFIG_USB_KC2190 #ifdef CONFIG_USB_KC2190
#define HAVE_HARDWARE #define HAVE_HARDWARE
static const struct driver_info kc2190_info = { static const struct driver_info kc2190_info = {
...@@ -223,6 +234,10 @@ static const struct usb_device_id products [] = { ...@@ -223,6 +234,10 @@ static const struct usb_device_id products [] = {
USB_DEVICE (0x0402, 0x5632), // ALi defaults USB_DEVICE (0x0402, 0x5632), // ALi defaults
.driver_info = (unsigned long) &ali_m5632_info, .driver_info = (unsigned long) &ali_m5632_info,
}, },
{
USB_DEVICE (0x182d,0x207c), // SiteCom CN-124
.driver_info = (unsigned long) &ali_m5632_info,
},
#endif #endif
#ifdef CONFIG_USB_AN2720 #ifdef CONFIG_USB_AN2720
......
...@@ -1181,6 +1181,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) ...@@ -1181,6 +1181,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
// NOTE net->name still not usable ... // NOTE net->name still not usable ...
if (info->bind) { if (info->bind) {
status = info->bind (dev, udev); status = info->bind (dev, udev);
if (status < 0)
goto out1;
// heuristic: "usb%d" for links we know are two-host, // heuristic: "usb%d" for links we know are two-host,
// else "eth%d" when there's reasonable doubt. userspace // else "eth%d" when there's reasonable doubt. userspace
// can rename the link if it knows better. // can rename the link if it knows better.
...@@ -1207,7 +1210,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) ...@@ -1207,7 +1210,7 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
if (status == 0 && dev->status) if (status == 0 && dev->status)
status = init_status (dev, udev); status = init_status (dev, udev);
if (status < 0) if (status < 0)
goto out1; goto out3;
if (!dev->rx_urb_size) if (!dev->rx_urb_size)
dev->rx_urb_size = dev->hard_mtu; dev->rx_urb_size = dev->hard_mtu;
......
...@@ -58,11 +58,6 @@ static void airprime_read_bulk_callback(struct urb *urb) ...@@ -58,11 +58,6 @@ static void airprime_read_bulk_callback(struct urb *urb)
if (urb->status) { if (urb->status) {
dbg("%s - nonzero read bulk status received: %d", dbg("%s - nonzero read bulk status received: %d",
__FUNCTION__, urb->status); __FUNCTION__, urb->status);
/* something happened, so free up the memory for this urb */
if (urb->transfer_buffer) {
kfree (urb->transfer_buffer);
urb->transfer_buffer = NULL;
}
return; return;
} }
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
...@@ -146,6 +141,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) ...@@ -146,6 +141,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
airprime_read_bulk_callback, port); airprime_read_bulk_callback, port);
result = usb_submit_urb(urb, GFP_KERNEL); result = usb_submit_urb(urb, GFP_KERNEL);
if (result) { if (result) {
usb_free_urb(urb);
kfree(buffer);
dev_err(&port->dev, dev_err(&port->dev,
"%s - failed submitting read urb %d for port %d, error %d\n", "%s - failed submitting read urb %d for port %d, error %d\n",
__FUNCTION__, i, port->number, result); __FUNCTION__, i, port->number, result);
...@@ -160,27 +157,12 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp) ...@@ -160,27 +157,12 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
/* some error happened, cancel any submitted urbs and clean up anything that /* some error happened, cancel any submitted urbs and clean up anything that
got allocated successfully */ got allocated successfully */
for ( ; i >= 0; --i) { while (i-- != 0) {
urb = priv->read_urbp[i]; urb = priv->read_urbp[i];
if (urb) { buffer = urb->transfer_buffer;
/* This urb was submitted successfully. So we have to usb_kill_urb (urb);
cancel it.
Unlinking the urb will invoke read_bulk_callback()
with an error status, so its transfer buffer will
be freed there */
if (usb_unlink_urb (urb) != -EINPROGRESS) {
/* comments in drivers/usb/core/urb.c say this
can only happen if the urb was never submitted,
or has completed already.
Either way we may have to free the transfer
buffer here. */
if (urb->transfer_buffer) {
kfree (urb->transfer_buffer);
urb->transfer_buffer = NULL;
}
}
usb_free_urb (urb); usb_free_urb (urb);
} kfree (buffer);
} }
out: out:
...@@ -194,10 +176,9 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp) ...@@ -194,10 +176,9 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
/* killing the urb will invoke read_bulk_callback() with an error status,
so the transfer buffer will be freed there */
for (i = 0; i < NUM_READ_URBS; ++i) { for (i = 0; i < NUM_READ_URBS; ++i) {
usb_kill_urb (priv->read_urbp[i]); usb_kill_urb (priv->read_urbp[i]);
kfree (priv->read_urbp[i]->transfer_buffer);
usb_free_urb (priv->read_urbp[i]); usb_free_urb (priv->read_urbp[i]);
} }
......
...@@ -69,6 +69,7 @@ static struct usb_device_id id_table [] = { ...@@ -69,6 +69,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
{ USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
{ USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
{ USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
{ USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
{ } /* Terminating Entry */ { } /* Terminating Entry */
......
...@@ -66,6 +66,8 @@ struct usb_serial_driver usb_serial_generic_device = { ...@@ -66,6 +66,8 @@ struct usb_serial_driver usb_serial_generic_device = {
.num_bulk_out = NUM_DONT_CARE, .num_bulk_out = NUM_DONT_CARE,
.num_ports = 1, .num_ports = 1,
.shutdown = usb_serial_generic_shutdown, .shutdown = usb_serial_generic_shutdown,
.throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle,
}; };
static int generic_probe(struct usb_interface *interface, static int generic_probe(struct usb_interface *interface,
...@@ -115,6 +117,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) ...@@ -115,6 +117,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
{ {
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
int result = 0; int result = 0;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number); dbg("%s - port %d", __FUNCTION__, port->number);
...@@ -124,7 +127,13 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp) ...@@ -124,7 +127,13 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
if (port->tty) if (port->tty)
port->tty->low_latency = 1; port->tty->low_latency = 1;
/* if we have a bulk interrupt, start reading from it */ /* clear the throttle flags */
spin_lock_irqsave(&port->lock, flags);
port->throttled = 0;
port->throttle_req = 0;
spin_unlock_irqrestore(&port->lock, flags);
/* if we have a bulk endpoint, start reading from it */
if (serial->num_bulk_in) { if (serial->num_bulk_in) {
/* Start reading from the device */ /* Start reading from the device */
usb_fill_bulk_urb (port->read_urb, serial->dev, usb_fill_bulk_urb (port->read_urb, serial->dev,
...@@ -253,31 +262,22 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port) ...@@ -253,31 +262,22 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
return (chars); return (chars);
} }
void usb_serial_generic_read_bulk_callback (struct urb *urb) /* Push data to tty layer and resubmit the bulk read URB */
static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
{ {
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
struct usb_serial *serial = port->serial; struct usb_serial *serial = port->serial;
struct tty_struct *tty; struct urb *urb = port->read_urb;
unsigned char *data = urb->transfer_buffer; struct tty_struct *tty = port->tty;
int result; int result;
dbg("%s - port %d", __FUNCTION__, port->number); /* Push data to tty */
if (urb->status) {
dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
return;
}
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
tty = port->tty;
if (tty && urb->actual_length) { if (tty && urb->actual_length) {
tty_buffer_request_room(tty, urb->actual_length); tty_buffer_request_room(tty, urb->actual_length);
tty_insert_flip_string(tty, data, urb->actual_length); tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
tty_flip_buffer_push(tty); tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
} }
/* Continue trying to always read */ /* Continue reading from device */
usb_fill_bulk_urb (port->read_urb, serial->dev, usb_fill_bulk_urb (port->read_urb, serial->dev,
usb_rcvbulkpipe (serial->dev, usb_rcvbulkpipe (serial->dev,
port->bulk_in_endpointAddress), port->bulk_in_endpointAddress),
...@@ -290,6 +290,40 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb) ...@@ -290,6 +290,40 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
if (result) if (result)
dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
} }
void usb_serial_generic_read_bulk_callback (struct urb *urb)
{
struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
unsigned char *data = urb->transfer_buffer;
int is_throttled;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number);
if (urb->status) {
dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
return;
}
usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
/* Throttle the device if requested by tty */
if (urb->actual_length) {
spin_lock_irqsave(&port->lock, flags);
is_throttled = port->throttled = port->throttle_req;
spin_unlock_irqrestore(&port->lock, flags);
if (is_throttled) {
/* Let the received data linger in the read URB;
* usb_serial_generic_unthrottle() will pick it
* up later. */
dbg("%s - throttling device", __FUNCTION__);
return;
}
}
/* Handle data and continue reading from device */
flush_and_resubmit_read_urb(port);
}
EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
void usb_serial_generic_write_bulk_callback (struct urb *urb) void usb_serial_generic_write_bulk_callback (struct urb *urb)
...@@ -308,6 +342,38 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb) ...@@ -308,6 +342,38 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb)
} }
EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
void usb_serial_generic_throttle (struct usb_serial_port *port)
{
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number);
/* Set the throttle request flag. It will be picked up
* by usb_serial_generic_read_bulk_callback(). */
spin_lock_irqsave(&port->lock, flags);
port->throttle_req = 1;
spin_unlock_irqrestore(&port->lock, flags);
}
void usb_serial_generic_unthrottle (struct usb_serial_port *port)
{
int was_throttled;
unsigned long flags;
dbg("%s - port %d", __FUNCTION__, port->number);
/* Clear the throttle flags */
spin_lock_irqsave(&port->lock, flags);
was_throttled = port->throttled;
port->throttled = port->throttle_req = 0;
spin_unlock_irqrestore(&port->lock, flags);
if (was_throttled) {
/* Handle pending data and resume reading from device */
flush_and_resubmit_read_urb(port);
}
}
void usb_serial_generic_shutdown (struct usb_serial *serial) void usb_serial_generic_shutdown (struct usb_serial *serial)
{ {
int i; int i;
......
...@@ -69,7 +69,6 @@ static int option_send_setup(struct usb_serial_port *port); ...@@ -69,7 +69,6 @@ static int option_send_setup(struct usb_serial_port *port);
/* Vendor and product IDs */ /* Vendor and product IDs */
#define OPTION_VENDOR_ID 0x0AF0 #define OPTION_VENDOR_ID 0x0AF0
#define HUAWEI_VENDOR_ID 0x12D1 #define HUAWEI_VENDOR_ID 0x12D1
#define AUDIOVOX_VENDOR_ID 0x0F3D
#define NOVATELWIRELESS_VENDOR_ID 0x1410 #define NOVATELWIRELESS_VENDOR_ID 0x1410
#define ANYDATA_VENDOR_ID 0x16d5 #define ANYDATA_VENDOR_ID 0x16d5
...@@ -81,7 +80,6 @@ static int option_send_setup(struct usb_serial_port *port); ...@@ -81,7 +80,6 @@ static int option_send_setup(struct usb_serial_port *port);
#define OPTION_PRODUCT_GTMAX36 0x6701 #define OPTION_PRODUCT_GTMAX36 0x6701
#define HUAWEI_PRODUCT_E600 0x1001 #define HUAWEI_PRODUCT_E600 0x1001
#define HUAWEI_PRODUCT_E220 0x1003 #define HUAWEI_PRODUCT_E220 0x1003
#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
#define NOVATELWIRELESS_PRODUCT_U740 0x1400 #define NOVATELWIRELESS_PRODUCT_U740 0x1400
#define ANYDATA_PRODUCT_ID 0x6501 #define ANYDATA_PRODUCT_ID 0x6501
...@@ -94,7 +92,6 @@ static struct usb_device_id option_ids[] = { ...@@ -94,7 +92,6 @@ static struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
...@@ -109,7 +106,6 @@ static struct usb_device_id option_ids1[] = { ...@@ -109,7 +106,6 @@ static struct usb_device_id option_ids1[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
{ USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
......
...@@ -83,6 +83,7 @@ static struct usb_device_id id_table [] = { ...@@ -83,6 +83,7 @@ static struct usb_device_id id_table [] = {
{ USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
{ USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
{ USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) }, { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
{ USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
{ } /* Terminating entry */ { } /* Terminating entry */
}; };
......
...@@ -97,3 +97,8 @@ ...@@ -97,3 +97,8 @@
/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */ /* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
#define HUAWEI_VENDOR_ID 0x12d1 #define HUAWEI_VENDOR_ID 0x12d1
#define HUAWEI_PRODUCT_ID 0x1001 #define HUAWEI_PRODUCT_ID 0x1001
/* Willcom WS002IN Data Driver (by NetIndex Inc.) */
#define WS002IN_VENDOR_ID 0x11f6
#define WS002IN_PRODUCT_ID 0x2001
...@@ -153,6 +153,12 @@ static int slave_configure(struct scsi_device *sdev) ...@@ -153,6 +153,12 @@ static int slave_configure(struct scsi_device *sdev)
if (us->flags & US_FL_FIX_CAPACITY) if (us->flags & US_FL_FIX_CAPACITY)
sdev->fix_capacity = 1; sdev->fix_capacity = 1;
/* A few disks have two indistinguishable version, one of
* which reports the correct capacity and the other does not.
* The sd driver has to guess which is the case. */
if (us->flags & US_FL_CAPACITY_HEURISTICS)
sdev->guess_capacity = 1;
/* Some devices report a SCSI revision level above 2 but are /* Some devices report a SCSI revision level above 2 but are
* unable to handle the REPORT LUNS command (for which * unable to handle the REPORT LUNS command (for which
* support is mandatory at level 3). Since we already have * support is mandatory at level 3). Since we already have
......
...@@ -1101,6 +1101,15 @@ UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000, ...@@ -1101,6 +1101,15 @@ UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_SINGLE_LUN), US_FL_SINGLE_LUN),
/* Submitted by Dylan Taft <d13f00l@gmail.com>
* US_FL_IGNORE_RESIDUE Needed
*/
UNUSUAL_DEV( 0x08ca, 0x3103, 0x0100, 0x0100,
"AIPTEK",
"Aiptek USB Keychain MP3 Player",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE),
/* Entry needed for flags. Moreover, all devices with this ID use /* Entry needed for flags. Moreover, all devices with this ID use
* bulk-only transport, but _some_ falsely report Control/Bulk instead. * bulk-only transport, but _some_ falsely report Control/Bulk instead.
* One example is "Trumpion Digital Research MYMP3". * One example is "Trumpion Digital Research MYMP3".
...@@ -1311,12 +1320,13 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000, ...@@ -1311,12 +1320,13 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_NO_WP_DETECT ), US_FL_NO_WP_DETECT ),
/* Reported by Jan Mate <mate@fiit.stuba.sk> */ /* Reported by Jan Mate <mate@fiit.stuba.sk>
* and by Soeren Sonnenburg <kernel@nn7.de> */
UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000,
"Sony Ericsson", "Sony Ericsson",
"P990i", "P990i",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY ), US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
/* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */ /* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */
UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000,
...@@ -1385,6 +1395,16 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201, ...@@ -1385,6 +1395,16 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE ), US_FL_IGNORE_RESIDUE ),
/* Reported by Thomas Baechler <thomas@archlinux.org>
* Fixes I/O errors with Teac HD-35PU devices
*/
UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
"Super Top",
"USB 2.0 IDE DEVICE",
US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_IGNORE_RESIDUE),
/* patch submitted by Davide Perini <perini.davide@dpsoftware.org> /* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
* and Renato Perini <rperini@email.it> * and Renato Perini <rperini@email.it>
*/ */
...@@ -1423,7 +1443,7 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001, ...@@ -1423,7 +1443,7 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
"DataStor", "DataStor",
"USB4500 FW1.04", "USB4500 FW1.04",
US_SC_DEVICE, US_PR_DEVICE, NULL, US_SC_DEVICE, US_PR_DEVICE, NULL,
US_FL_FIX_CAPACITY), US_FL_CAPACITY_HEURISTICS),
/* Control/Bulk transport for all SubClass values */ /* Control/Bulk transport for all SubClass values */
USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
......
...@@ -90,13 +90,15 @@ static int skel_open(struct inode *inode, struct file *file) ...@@ -90,13 +90,15 @@ static int skel_open(struct inode *inode, struct file *file)
goto exit; goto exit;
} }
/* increment our usage count for the device */
kref_get(&dev->kref);
/* prevent the device from being autosuspended */ /* prevent the device from being autosuspended */
retval = usb_autopm_get_interface(interface); retval = usb_autopm_get_interface(interface);
if (retval) if (retval) {
kref_put(&dev->kref, skel_delete);
goto exit; goto exit;
}
/* increment our usage count for the device */
kref_get(&dev->kref);
/* save our object in the file's private structure */ /* save our object in the file's private structure */
file->private_data = dev; file->private_data = dev;
......
...@@ -935,7 +935,7 @@ struct usb_iso_packet_descriptor { ...@@ -935,7 +935,7 @@ struct usb_iso_packet_descriptor {
unsigned int offset; unsigned int offset;
unsigned int length; /* expected length */ unsigned int length; /* expected length */
unsigned int actual_length; unsigned int actual_length;
unsigned int status; int status;
}; };
struct urb; struct urb;
......
...@@ -73,6 +73,13 @@ struct usb_cdc_acm_descriptor { ...@@ -73,6 +73,13 @@ struct usb_cdc_acm_descriptor {
__u8 bmCapabilities; __u8 bmCapabilities;
} __attribute__ ((packed)); } __attribute__ ((packed));
/* capabilities from 5.2.3.3 */
#define USB_CDC_COMM_FEATURE 0x01
#define USB_CDC_CAP_LINE 0x02
#define USB_CDC_CAP_BRK 0x04
#define USB_CDC_CAP_NOTIFY 0x08
/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ /* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
struct usb_cdc_union_desc { struct usb_cdc_union_desc {
__u8 bLength; __u8 bLength;
......
...@@ -367,7 +367,7 @@ struct usb_debug_descriptor { ...@@ -367,7 +367,7 @@ struct usb_debug_descriptor {
/* bulk endpoints with 8 byte maxpacket */ /* bulk endpoints with 8 byte maxpacket */
__u8 bDebugInEndpoint; __u8 bDebugInEndpoint;
__u8 bDebugOutEndpoint; __u8 bDebugOutEndpoint;
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -396,7 +396,7 @@ struct usb_security_descriptor { ...@@ -396,7 +396,7 @@ struct usb_security_descriptor {
__le16 wTotalLength; __le16 wTotalLength;
__u8 bNumEncryptionTypes; __u8 bNumEncryptionTypes;
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -410,7 +410,7 @@ struct usb_key_descriptor { ...@@ -410,7 +410,7 @@ struct usb_key_descriptor {
__u8 tTKID[3]; __u8 tTKID[3];
__u8 bReserved; __u8 bReserved;
__u8 bKeyData[0]; __u8 bKeyData[0];
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -426,7 +426,7 @@ struct usb_encryption_descriptor { ...@@ -426,7 +426,7 @@ struct usb_encryption_descriptor {
#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */ #define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */
__u8 bEncryptionValue; /* use in SET_ENCRYPTION */ __u8 bEncryptionValue; /* use in SET_ENCRYPTION */
__u8 bAuthKeyIndex; __u8 bAuthKeyIndex;
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -438,7 +438,7 @@ struct usb_bos_descriptor { ...@@ -438,7 +438,7 @@ struct usb_bos_descriptor {
__le16 wTotalLength; __le16 wTotalLength;
__u8 bNumDeviceCaps; __u8 bNumDeviceCaps;
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -447,7 +447,7 @@ struct usb_dev_cap_header { ...@@ -447,7 +447,7 @@ struct usb_dev_cap_header {
__u8 bLength; __u8 bLength;
__u8 bDescriptorType; __u8 bDescriptorType;
__u8 bDevCapabilityType; __u8 bDevCapabilityType;
}; } __attribute__((packed));
#define USB_CAP_TYPE_WIRELESS_USB 1 #define USB_CAP_TYPE_WIRELESS_USB 1
...@@ -475,7 +475,7 @@ struct usb_wireless_cap_descriptor { /* Ultra Wide Band */ ...@@ -475,7 +475,7 @@ struct usb_wireless_cap_descriptor { /* Ultra Wide Band */
__u8 bmFFITXPowerInfo; /* FFI power levels */ __u8 bmFFITXPowerInfo; /* FFI power levels */
__le16 bmBandGroup; __le16 bmBandGroup;
__u8 bReserved; __u8 bReserved;
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -496,7 +496,7 @@ struct usb_wireless_ep_comp_descriptor { ...@@ -496,7 +496,7 @@ struct usb_wireless_ep_comp_descriptor {
#define USB_ENDPOINT_SWITCH_NO 0 #define USB_ENDPOINT_SWITCH_NO 0
#define USB_ENDPOINT_SWITCH_SWITCH 1 #define USB_ENDPOINT_SWITCH_SWITCH 1
#define USB_ENDPOINT_SWITCH_SCALE 2 #define USB_ENDPOINT_SWITCH_SCALE 2
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -512,7 +512,7 @@ struct usb_handshake { ...@@ -512,7 +512,7 @@ struct usb_handshake {
__u8 CDID[16]; __u8 CDID[16];
__u8 nonce[16]; __u8 nonce[16];
__u8 MIC[8]; __u8 MIC[8];
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
...@@ -524,7 +524,7 @@ struct usb_connection_context { ...@@ -524,7 +524,7 @@ struct usb_connection_context {
__u8 CHID[16]; /* persistent host id */ __u8 CHID[16]; /* persistent host id */
__u8 CDID[16]; /* device id (unique w/in host context) */ __u8 CDID[16]; /* device id (unique w/in host context) */
__u8 CK[16]; /* connection key */ __u8 CK[16]; /* connection key */
}; } __attribute__((packed));
/*-------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------*/
......
...@@ -54,6 +54,8 @@ ...@@ -54,6 +54,8 @@
* @write_wait: a wait_queue_head_t used by the port. * @write_wait: a wait_queue_head_t used by the port.
* @work: work queue entry for the line discipline waking up. * @work: work queue entry for the line discipline waking up.
* @open_count: number of times this port has been opened. * @open_count: number of times this port has been opened.
* @throttled: nonzero if the read urb is inactive to throttle the device
* @throttle_req: nonzero if the tty wants to throttle us
* *
* This structure is used by the usb-serial core and drivers for the specific * This structure is used by the usb-serial core and drivers for the specific
* ports of a device. * ports of a device.
...@@ -88,6 +90,8 @@ struct usb_serial_port { ...@@ -88,6 +90,8 @@ struct usb_serial_port {
wait_queue_head_t write_wait; wait_queue_head_t write_wait;
struct work_struct work; struct work_struct work;
int open_count; int open_count;
char throttled;
char throttle_req;
struct device dev; struct device dev;
}; };
#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) #define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
...@@ -269,6 +273,8 @@ extern int usb_serial_generic_write_room (struct usb_serial_port *port); ...@@ -269,6 +273,8 @@ extern int usb_serial_generic_write_room (struct usb_serial_port *port);
extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port); extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
extern void usb_serial_generic_read_bulk_callback (struct urb *urb); extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
extern void usb_serial_generic_write_bulk_callback (struct urb *urb); extern void usb_serial_generic_write_bulk_callback (struct urb *urb);
extern void usb_serial_generic_throttle (struct usb_serial_port *port);
extern void usb_serial_generic_unthrottle (struct usb_serial_port *port);
extern void usb_serial_generic_shutdown (struct usb_serial *serial); extern void usb_serial_generic_shutdown (struct usb_serial *serial);
extern int usb_serial_generic_register (int debug); extern int usb_serial_generic_register (int debug);
extern void usb_serial_generic_deregister (void); extern void usb_serial_generic_deregister (void);
......
...@@ -46,7 +46,9 @@ ...@@ -46,7 +46,9 @@
US_FLAG(MAX_SECTORS_64, 0x00000400) \ US_FLAG(MAX_SECTORS_64, 0x00000400) \
/* Sets max_sectors to 64 */ \ /* Sets max_sectors to 64 */ \
US_FLAG(IGNORE_DEVICE, 0x00000800) \ US_FLAG(IGNORE_DEVICE, 0x00000800) \
/* Don't claim device */ /* Don't claim device */ \
US_FLAG(CAPACITY_HEURISTICS, 0x00001000) \
/* sometimes sizes is too big */
#define US_FLAG(name, value) US_FL_##name = value , #define US_FLAG(name, value) US_FL_##name = value ,
enum { US_DO_ALL_FLAGS }; enum { US_DO_ALL_FLAGS };
......
...@@ -159,9 +159,9 @@ struct usbdevfs_ioctl32 { ...@@ -159,9 +159,9 @@ struct usbdevfs_ioctl32 {
#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32) #define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
#define USBDEVFS_DISCARDURB _IO('U', 11) #define USBDEVFS_DISCARDURB _IO('U', 11)
#define USBDEVFS_REAPURB _IOW('U', 12, void *) #define USBDEVFS_REAPURB _IOW('U', 12, void *)
#define USBDEVFS_REAPURB32 _IOW('U', 12, u32) #define USBDEVFS_REAPURB32 _IOW('U', 12, __u32)
#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *) #define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, u32) #define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32)
#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal) #define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal)
#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int) #define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) #define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
......
...@@ -122,6 +122,7 @@ struct scsi_device { ...@@ -122,6 +122,7 @@ struct scsi_device {
unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
unsigned select_no_atn:1; unsigned select_no_atn:1;
unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */
unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
unsigned int device_blocked; /* Device returned QUEUE_FULL. */ unsigned int device_blocked; /* Device returned QUEUE_FULL. */
......
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