diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/net/irda/stir4200.c linux-2.6.12-rc2-usb/drivers/net/irda/stir4200.c --- linux-2.6.12-rc2/drivers/net/irda/stir4200.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/net/irda/stir4200.c 2005-04-09 08:57:12.000000000 -0700 @@ -1128,8 +1128,8 @@ } #ifdef CONFIG_PM -/* Power management suspend, so power off the transmitter/receiver */ -static int stir_suspend(struct usb_interface *intf, u32 state) +/* USB suspend, so power off the transmitter/receiver */ +static int stir_suspend(struct usb_interface *intf, pm_message_t message) { struct stir_cb *stir = usb_get_intfdata(intf); diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/config.c linux-2.6.12-rc2-usb/drivers/usb/core/config.c --- linux-2.6.12-rc2/drivers/usb/core/config.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/config.c 2005-04-09 08:57:13.000000000 -0700 @@ -10,7 +10,8 @@ #include #include #include - +#include "usb.h" +#include "hcd.h" #define USB_MAXALTSETTING 128 /* Hard limit */ #define USB_MAXENDPOINTS 30 /* Hard limit */ diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/devices.c linux-2.6.12-rc2-usb/drivers/usb/core/devices.c --- linux-2.6.12-rc2/drivers/usb/core/devices.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/devices.c 2005-04-09 08:57:13.000000000 -0700 @@ -59,6 +59,7 @@ #include #include +#include "usb.h" #include "hcd.h" #define MAX_TOPO_LEVEL 6 diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/devio.c linux-2.6.12-rc2-usb/drivers/usb/core/devio.c --- linux-2.6.12-rc2/drivers/usb/core/devio.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/devio.c 2005-04-09 08:57:13.000000000 -0700 @@ -1032,15 +1032,15 @@ if (put_user(urb->error_count, &userurb->error_count)) return -EFAULT; - if (!(usb_pipeisoc(urb->pipe))) - return 0; - for (i = 0; i < urb->number_of_packets; i++) { - if (put_user(urb->iso_frame_desc[i].actual_length, - &userurb->iso_frame_desc[i].actual_length)) - return -EFAULT; - if (put_user(urb->iso_frame_desc[i].status, - &userurb->iso_frame_desc[i].status)) - return -EFAULT; + if (usb_pipeisoc(urb->pipe)) { + for (i = 0; i < urb->number_of_packets; i++) { + if (put_user(urb->iso_frame_desc[i].actual_length, + &userurb->iso_frame_desc[i].actual_length)) + return -EFAULT; + if (put_user(urb->iso_frame_desc[i].status, + &userurb->iso_frame_desc[i].status)) + return -EFAULT; + } } free_async(as); @@ -1126,7 +1126,7 @@ if (get_urb32(&uurb,(struct usbdevfs_urb32 *)arg)) return -EFAULT; - return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb __user *)arg)->iso_frame_desc, arg); + return proc_do_submiturb(ps, &uurb, ((struct usbdevfs_urb32 __user *)arg)->iso_frame_desc, arg); } static int processcompl_compat(struct async *as, void __user * __user *arg) @@ -1146,15 +1146,15 @@ if (put_user(urb->error_count, &userurb->error_count)) return -EFAULT; - if (!(usb_pipeisoc(urb->pipe))) - return 0; - for (i = 0; i < urb->number_of_packets; i++) { - if (put_user(urb->iso_frame_desc[i].actual_length, - &userurb->iso_frame_desc[i].actual_length)) - return -EFAULT; - if (put_user(urb->iso_frame_desc[i].status, - &userurb->iso_frame_desc[i].status)) - return -EFAULT; + if (usb_pipeisoc(urb->pipe)) { + for (i = 0; i < urb->number_of_packets; i++) { + if (put_user(urb->iso_frame_desc[i].actual_length, + &userurb->iso_frame_desc[i].actual_length)) + return -EFAULT; + if (put_user(urb->iso_frame_desc[i].status, + &userurb->iso_frame_desc[i].status)) + return -EFAULT; + } } free_async(as); @@ -1177,10 +1177,8 @@ { struct async *as; - printk("reapurbnblock\n"); if (!(as = async_getcompleted(ps))) return -EAGAIN; - printk("reap got as %p\n", as); return processcompl_compat(as, (void __user * __user *)arg); } diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/file.c linux-2.6.12-rc2-usb/drivers/usb/core/file.c --- linux-2.6.12-rc2/drivers/usb/core/file.c 2005-04-07 00:36:34.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/file.c 2005-04-09 08:57:13.000000000 -0700 @@ -28,6 +28,8 @@ #endif #include +#include "usb.h" + #define MAX_USB_MINORS 256 static struct file_operations *usb_minors[MAX_USB_MINORS]; static DEFINE_SPINLOCK(minor_lock); diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/hcd-pci.c linux-2.6.12-rc2-usb/drivers/usb/core/hcd-pci.c --- linux-2.6.12-rc2/drivers/usb/core/hcd-pci.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/hcd-pci.c 2005-04-09 08:57:12.000000000 -0700 @@ -33,7 +33,7 @@ #include "hcd.h" -/* PCI-based HCs are normal, but custom bus glue should be ok */ +/* PCI-based HCs are common, but plenty of non-PCI HCs are used too */ /*-------------------------------------------------------------------------*/ @@ -67,8 +67,8 @@ if (pci_enable_device (dev) < 0) return -ENODEV; - dev->current_state = 0; - dev->dev.power.power_state = 0; + dev->current_state = PCI_D0; + dev->dev.power.power_state = PMSG_ON; if (!dev->irq) { dev_err (&dev->dev, @@ -186,26 +186,14 @@ #ifdef CONFIG_PM -static char __attribute_used__ *pci_state(u32 state) -{ - switch (state) { - case 0: return "D0"; - case 1: return "D1"; - case 2: return "D2"; - case 3: return "D3hot"; - case 4: return "D3cold"; - } - return NULL; -} - /** * 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 + * @message: semantics in flux * * Store this function in the HCD's struct pci_driver as suspend(). */ -int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state) +int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) { struct usb_hcd *hcd; int retval = 0; @@ -213,13 +201,23 @@ hcd = pci_get_drvdata(dev); + /* FIXME until the generic PM interfaces change a lot more, this + * can't use PCI D1 and D2 states. For example, the confusion + * between messages and states will need to vanish, and messages + * will need to provide a target system state again. + * + * It'll be important to learn characteristics of the target state, + * especially on embedded hardware where the HCD will often be in + * charge of an external VBUS power supply and one or more clocks. + * Some target system states will leave them active; others won't. + * (With PCI, that's often handled by platform BIOS code.) + */ + /* even when the PCI layer rejects some of the PCI calls * below, HCs can try global suspend and reduce DMA traffic. * PM-sensitive HCDs may already have done this. */ has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); - if (state > 4) - state = 4; switch (hcd->state) { @@ -228,7 +226,7 @@ */ case HC_STATE_RUNNING: hcd->state = HC_STATE_QUIESCING; - retval = hcd->driver->suspend (hcd, state); + retval = hcd->driver->suspend (hcd, message); if (retval) { dev_dbg (hcd->self.controller, "suspend fail, retval %d\n", @@ -246,14 +244,11 @@ * have been called, otherwise root hub timers still run ... */ case HC_STATE_SUSPENDED: - if (state <= dev->current_state) - break; - - /* no DMA or IRQs except in D0 */ - if (!dev->current_state) { + /* no DMA or IRQs except when HC is active */ + if (dev->current_state == PCI_D0) { + free_irq (hcd->irq, hcd); pci_save_state (dev); pci_disable_device (dev); - free_irq (hcd->irq, hcd); } if (!has_pci_pm) { @@ -261,25 +256,19 @@ break; } - /* POLICY: ignore D1/D2/D3hot differences; - * we know D3hot will always work. + /* NOTE: dev->current_state becomes nonzero only here, and + * only for devices that support PCI PM. Also, exiting + * PCI_D3 (but not PCI_D1 or PCI_D2) is allowed to reset + * some device state (e.g. as part of clock reinit). */ - retval = pci_set_power_state (dev, state); - if (retval < 0 && state < 3) { - retval = pci_set_power_state (dev, 3); - if (retval == 0) - state = 3; - } + retval = pci_set_power_state (dev, PCI_D3hot); if (retval == 0) { - dev_dbg (hcd->self.controller, "--> PCI %s\n", - pci_state(dev->current_state)); -#ifdef CONFIG_USB_SUSPEND - pci_enable_wake (dev, state, hcd->remote_wakeup); - pci_enable_wake (dev, 4, hcd->remote_wakeup); -#endif + dev_dbg (hcd->self.controller, "--> PCI D3\n"); + pci_enable_wake (dev, PCI_D3hot, hcd->remote_wakeup); + pci_enable_wake (dev, PCI_D3cold, hcd->remote_wakeup); } else if (retval < 0) { - dev_dbg (&dev->dev, "PCI %s suspend fail, %d\n", - pci_state(state), retval); + dev_dbg (&dev->dev, "PCI D3 suspend fail, %d\n", + retval); (void) usb_hcd_pci_resume (dev); break; } @@ -287,13 +276,14 @@ default: dev_dbg (hcd->self.controller, "hcd state %d; not suspended\n", hcd->state); + WARN_ON(1); retval = -EINVAL; break; } /* update power_state **ONLY** to make sysfs happier */ if (retval == 0) - dev->dev.power.power_state = state; + dev->dev.power.power_state = message; return retval; } EXPORT_SYMBOL (usb_hcd_pci_suspend); @@ -308,7 +298,6 @@ { struct usb_hcd *hcd; int retval; - int has_pci_pm; hcd = pci_get_drvdata(dev); if (hcd->state != HC_STATE_SUSPENDED) { @@ -316,31 +305,73 @@ "can't resume, not suspended!\n"); return 0; } - has_pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); - /* D3cold resume isn't usually reported this way... */ - dev_dbg(hcd->self.controller, "resume from PCI %s%s\n", - pci_state(dev->current_state), - has_pci_pm ? "" : " (legacy)"); + /* NOTE: chip docs cover clean "real suspend" cases (what Linux + * calls "standby", "suspend to RAM", and so on). There are also + * dirty cases when swsusp fakes a suspend in "shutdown" mode. + */ + if (dev->current_state != PCI_D0) { +#ifdef DEBUG + int pci_pm; + u16 pmcr; + + pci_pm = pci_find_capability(dev, PCI_CAP_ID_PM); + pci_read_config_word(dev, pci_pm + PCI_PM_CTRL, &pmcr); + pmcr &= PCI_PM_CTRL_STATE_MASK; + if (pmcr) { + /* Clean case: power to USB and to HC registers was + * maintained; remote wakeup is easy. + */ + dev_dbg(hcd->self.controller, "resume from PCI D%d\n", + pmcr); + } else { + /* Clean: HC lost Vcc power, D0 uninitialized + * + Vaux may have preserved port and transceiver + * state ... for remote wakeup from D3cold + * + or not; HCD must reinit + re-enumerate + * + * Dirty: D0 semi-initialized cases with swsusp + * + after BIOS init + * + after Linux init (HCD statically linked) + */ + dev_dbg(hcd->self.controller, + "PCI D0, from previous PCI D%d\n", + dev->current_state); + } +#endif + pci_enable_wake (dev, dev->current_state, 0); + pci_enable_wake (dev, PCI_D3cold, 0); + } else { + /* Same basic cases: clean (powered/not), dirty */ + dev_dbg(hcd->self.controller, "PCI legacy resume\n"); + } + + /* NOTE: the PCI API itself is asymmetric here. We don't need to + * pci_set_power_state(PCI_D0) since that's part of re-enabling; + * but that won't re-enable bus mastering. Yet pci_disable_device() + * explicitly disables bus mastering... + */ + retval = pci_enable_device (dev); + if (retval < 0) { + dev_err (hcd->self.controller, + "can't re-enable after resume, %d!\n", retval); + return retval; + } + pci_set_master (dev); + pci_restore_state (dev); + + dev->dev.power.power_state = PMSG_ON; hcd->state = HC_STATE_RESUMING; - - if (has_pci_pm) - pci_set_power_state (dev, 0); - dev->dev.power.power_state = 0; + hcd->saw_irq = 0; retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, - hcd->driver->description, hcd); + hcd->irq_descr, hcd); if (retval < 0) { dev_err (hcd->self.controller, "can't restore IRQ after resume!\n"); + usb_hc_died (hcd); return retval; } - hcd->saw_irq = 0; - pci_restore_state (dev); -#ifdef CONFIG_USB_SUSPEND - pci_enable_wake (dev, dev->current_state, 0); - pci_enable_wake (dev, 4, 0); -#endif retval = hcd->driver->resume (hcd); if (!HC_IS_RUNNING (hcd->state)) { diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/hcd.h linux-2.6.12-rc2-usb/drivers/usb/core/hcd.h --- linux-2.6.12-rc2/drivers/usb/core/hcd.h 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/hcd.h 2005-04-09 08:57:12.000000000 -0700 @@ -177,7 +177,7 @@ * a whole, not just the root hub; they're for bus glue. */ /* called after all devices were suspended */ - int (*suspend) (struct usb_hcd *hcd, u32 state); + int (*suspend) (struct usb_hcd *hcd, pm_message_t message); /* called before any devices get resumed */ int (*resume) (struct usb_hcd *hcd); @@ -226,7 +226,7 @@ extern void usb_hcd_pci_remove (struct pci_dev *dev); #ifdef CONFIG_PM -extern int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state); +extern int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t state); extern int usb_hcd_pci_resume (struct pci_dev *dev); #endif /* CONFIG_PM */ diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/hub.c linux-2.6.12-rc2-usb/drivers/usb/core/hub.c --- linux-2.6.12-rc2/drivers/usb/core/hub.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/hub.c 2005-04-09 08:57:12.000000000 -0700 @@ -1731,7 +1731,7 @@ struct usb_driver *driver; intf = udev->actconfig->interface[i]; - if (intf->dev.power.power_state == PM_SUSPEND_ON) + if (intf->dev.power.power_state == PMSG_SUSPEND) continue; if (!intf->dev.driver) { /* FIXME maybe force to alt 0 */ @@ -1745,7 +1745,7 @@ /* can we do better than just logging errors? */ status = driver->resume(intf); - if (intf->dev.power.power_state != PM_SUSPEND_ON + if (intf->dev.power.power_state != PMSG_ON || status) dev_dbg(&intf->dev, "resume fail, state %d code %d\n", diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/inode.c linux-2.6.12-rc2-usb/drivers/usb/core/inode.c --- linux-2.6.12-rc2/drivers/usb/core/inode.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/inode.c 2005-04-09 08:57:13.000000000 -0700 @@ -41,6 +41,7 @@ #include #include #include "usb.h" +#include "hcd.h" static struct super_operations usbfs_ops; static struct file_operations default_file_operations; diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/message.c linux-2.6.12-rc2-usb/drivers/usb/core/message.c --- linux-2.6.12-rc2/drivers/usb/core/message.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/message.c 2005-04-09 08:57:13.000000000 -0700 @@ -1133,29 +1133,10 @@ /* prevent submissions using previous endpoint settings */ usb_disable_interface(dev, iface); - /* 9.1.1.5 says: - * - * Configuring a device or changing an alternate setting - * causes all of the status and configuration values - * associated with endpoints in the affected interfaces to - * be set to their default values. This includes setting - * the data toggle of any endpoint using data toggles to - * the value DATA0. - * - * Some devices take this too literally and don't reset the data - * toggles if the new altsetting is the same as the old one (the - * command isn't "changing" an alternate setting). We will manually - * reset the toggles when the new and old altsettings are the same. - * Most devices won't need this, but fortunately it doesn't happen - * often. - */ - if (iface->cur_altsetting == alt) - manual = 1; iface->cur_altsetting = alt; /* If the interface only has one altsetting and the device didn't - * accept the request (or whenever the old altsetting is the same - * as the new one), we attempt to carry out the equivalent action + * accept the request, we attempt to carry out the equivalent action * by manually clearing the HALT feature for each endpoint in the * new altsetting. */ @@ -1202,7 +1183,9 @@ * * Because this affects multiple interfaces, avoid using this with composite * (multi-interface) devices. Instead, the driver for each interface may - * use usb_set_interface() on the interfaces it claims. Resetting the whole + * use usb_set_interface() on the interfaces it claims. Be careful though; + * some devices don't support the SET_INTERFACE request, and others won't + * reset all the interface state (notably data toggles). Resetting the whole * configuration would affect other drivers' interfaces. * * The caller must own the device lock. diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/urb.c linux-2.6.12-rc2-usb/drivers/usb/core/urb.c --- linux-2.6.12-rc2/drivers/usb/core/urb.c 2005-03-01 23:38:10.000000000 -0800 +++ linux-2.6.12-rc2-usb/drivers/usb/core/urb.c 2005-04-09 08:57:14.000000000 -0700 @@ -420,12 +420,16 @@ * * Host Controller Drivers (HCDs) place all the URBs for a particular * endpoint in a queue. Normally the queue advances as the controller - * hardware processes each request. But when an URB terminates with any - * fault (such as an error, or being unlinked) its queue stops, at least - * until that URB's completion routine returns. It is guaranteed that - * the queue will not restart until all its unlinked URBs have been fully - * retired, with their completion routines run, even if that's not until - * some time after the original completion handler returns. + * hardware processes each request. But when an URB terminates with an + * error its queue stops, at least until that URB's completion routine + * returns. It is guaranteed that the queue will not restart until all + * its unlinked URBs have been fully retired, with their completion + * routines run, even if that's not until some time after the original + * completion handler returns. Normally the same behavior and guarantees + * apply when an URB terminates because it was unlinked; however if an + * URB is unlinked before the hardware has started to execute it, then + * its queue is not guaranteed to stop until all the preceding URBs have + * completed. * * This means that USB device drivers can safely build deep queues for * large or complex transfers, and clean them up reliably after any sort diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/usb.c linux-2.6.12-rc2-usb/drivers/usb/core/usb.c --- linux-2.6.12-rc2/drivers/usb/core/usb.c 2005-04-07 00:36:33.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/usb.c 2005-04-09 08:57:13.000000000 -0700 @@ -50,13 +50,6 @@ #include "hcd.h" #include "usb.h" -extern int usb_hub_init(void); -extern void usb_hub_cleanup(void); -extern int usb_major_init(void); -extern void usb_major_cleanup(void); -extern int usb_host_init(void); -extern void usb_host_cleanup(void); - const char *usbcore_name = "usbcore"; @@ -1382,13 +1375,13 @@ usb_pipein (pipe) ? DMA_FROM_DEVICE : DMA_TO_DEVICE); } -static int usb_generic_suspend(struct device *dev, u32 state) +static int usb_generic_suspend(struct device *dev, pm_message_t message) { struct usb_interface *intf; struct usb_driver *driver; if (dev->driver == &usb_generic_driver) - return usb_suspend_device (to_usb_device(dev), state); + return usb_suspend_device (to_usb_device(dev), message); if ((dev->driver == NULL) || (dev->driver_data == &usb_generic_driver_data)) @@ -1402,7 +1395,7 @@ return 0; if (driver->suspend) - return driver->suspend(intf, state); + return driver->suspend(intf, message); return 0; } diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/core/usb.h linux-2.6.12-rc2-usb/drivers/usb/core/usb.h --- linux-2.6.12-rc2/drivers/usb/core/usb.h 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/core/usb.h 2005-04-09 08:57:13.000000000 -0700 @@ -21,6 +21,13 @@ extern void usb_kick_khubd(struct usb_device *dev); extern void usb_resume_root_hub(struct usb_device *dev); +extern int usb_hub_init(void); +extern void usb_hub_cleanup(void); +extern int usb_major_init(void); +extern void usb_major_cleanup(void); +extern int usb_host_init(void); +extern void usb_host_cleanup(void); + /* for labeling diagnostics */ extern const char *usbcore_name; @@ -30,6 +37,7 @@ extern struct file_operations usbfs_device_file_operations; extern void usbfs_conn_disc_event(void); + struct dev_state { struct list_head list; /* state list */ struct usb_device *dev; diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/gadget/ether.c linux-2.6.12-rc2-usb/drivers/usb/gadget/ether.c --- linux-2.6.12-rc2/drivers/usb/gadget/ether.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/gadget/ether.c 2005-04-09 08:57:14.000000000 -0700 @@ -100,6 +100,8 @@ /* CDC and RNDIS support the same host-chosen outgoing packet filters. */ #define DEFAULT_FILTER (USB_CDC_PACKET_TYPE_BROADCAST \ + |USB_CDC_PACKET_TYPE_ALL_MULTICAST \ + |USB_CDC_PACKET_TYPE_PROMISCUOUS \ |USB_CDC_PACKET_TYPE_DIRECTED) @@ -322,12 +324,18 @@ /* also defer IRQs on highspeed TX */ #define TX_DELAY qmult -#define BITRATE(g) (((g)->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS) +static inline int BITRATE(struct usb_gadget *g) +{ + return (g->speed == USB_SPEED_HIGH) ? HS_BPS : FS_BPS; +} #else /* full speed (low speed doesn't do bulk) */ #define qlen(gadget) DEFAULT_QLEN -#define BITRATE(g) FS_BPS +static inline int BITRATE(struct usb_gadget *g) +{ + return FS_BPS; +} #endif @@ -1167,7 +1175,7 @@ eth_reset_config (dev); /* default: pass all packets, no multicast filtering */ - dev->cdc_filter = 0x000f; + dev->cdc_filter = DEFAULT_FILTER; switch (number) { case DEV_CONFIG_VALUE: @@ -1343,9 +1351,9 @@ struct eth_dev *dev = get_gadget_data (gadget); struct usb_request *req = dev->req; int value = -EOPNOTSUPP; - u16 wIndex = ctrl->wIndex; - u16 wValue = ctrl->wValue; - u16 wLength = ctrl->wLength; + u16 wIndex = (__force u16) ctrl->wIndex; + u16 wValue = (__force u16) ctrl->wValue; + u16 wLength = (__force u16) ctrl->wLength; /* descriptors just go into the pre-allocated ep0 buffer, * while config change events may enable network traffic. @@ -1693,7 +1701,7 @@ /* Some platforms perform better when IP packets are aligned, * but on at least one, checksumming fails otherwise. Note: - * this doesn't account for variable-sized RNDIS headers. + * RNDIS headers involve variable numbers of LE32 values. */ skb_reserve(skb, NET_IP_ALIGN); @@ -1730,9 +1738,11 @@ #ifdef CONFIG_USB_ETH_RNDIS /* we know MaxPacketsPerTransfer == 1 here */ if (dev->rndis) - rndis_rm_hdr (req->buf, &(skb->len)); + status = rndis_rm_hdr (skb); #endif - if (ETH_HLEN > skb->len || skb->len > ETH_FRAME_LEN) { + if (status < 0 + || ETH_HLEN > skb->len + || skb->len > ETH_FRAME_LEN) { dev->stats.rx_errors++; dev->stats.rx_length_errors++; DEBUG (dev, "rx length %d\n", skb->len); @@ -2047,38 +2057,20 @@ DEBUG ((struct eth_dev *) ep->driver_data, "rndis control ack complete --> %d, %d/%d\n", req->status, req->actual, req->length); - - usb_ep_free_buffer(ep, req->buf, req->dma, 8); - usb_ep_free_request(ep, req); } static int rndis_control_ack (struct net_device *net) { struct eth_dev *dev = netdev_priv(net); u32 length; - struct usb_request *resp; + struct usb_request *resp = dev->stat_req; /* in case RNDIS calls this after disconnect */ - if (!dev->status_ep) { + if (!dev->status) { DEBUG (dev, "status ENODEV\n"); return -ENODEV; } - /* Allocate memory for notification ie. ACK */ - resp = usb_ep_alloc_request (dev->status_ep, GFP_ATOMIC); - if (!resp) { - DEBUG (dev, "status ENOMEM\n"); - return -ENOMEM; - } - - resp->buf = usb_ep_alloc_buffer (dev->status_ep, 8, - &resp->dma, GFP_ATOMIC); - if (!resp->buf) { - DEBUG (dev, "status buf ENOMEM\n"); - usb_ep_free_request (dev->status_ep, resp); - return -ENOMEM; - } - /* Send RNDIS RESPONSE_AVAILABLE notification; * USB_CDC_NOTIFY_RESPONSE_AVAILABLE should work too */ @@ -2113,7 +2105,7 @@ if (dev->rndis) { rndis_set_param_medium (dev->rndis_config, NDIS_MEDIUM_802_3, - BITRATE(dev->gadget)); + BITRATE(dev->gadget)/100); rndis_send_media_state (dev, 1); } #endif @@ -2307,8 +2299,8 @@ device_desc.bcdDevice = __constant_cpu_to_le16 (0x0210); } else if (gadget_is_pxa27x(gadget)) { device_desc.bcdDevice = __constant_cpu_to_le16 (0x0211); - } else if (gadget_is_s3c2410(gadget)) { - device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212); + } else if (gadget_is_s3c2410(gadget)) { + device_desc.bcdDevice = __constant_cpu_to_le16 (0x0212); } else if (gadget_is_at91(gadget)) { device_desc.bcdDevice = __constant_cpu_to_le16 (0x0213); } else { diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/gadget/file_storage.c linux-2.6.12-rc2-usb/drivers/usb/gadget/file_storage.c --- linux-2.6.12-rc2/drivers/usb/gadget/file_storage.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/gadget/file_storage.c 2005-04-09 08:57:13.000000000 -0700 @@ -1312,7 +1312,7 @@ } VDBG(fsg, "get max LUN\n"); *(u8 *) req->buf = fsg->nluns - 1; - value = min(w_length, (u16) 1); + value = 1; break; } } @@ -1360,7 +1360,6 @@ int value = -EOPNOTSUPP; u16 w_index = ctrl->wIndex; u16 w_value = ctrl->wValue; - u16 w_length = ctrl->wLength; /* Usually this just stores reply data in the pre-allocated ep0 buffer, * but config change events will also reconfigure hardware. */ @@ -1374,7 +1373,7 @@ case USB_DT_DEVICE: VDBG(fsg, "get device descriptor\n"); - value = min(w_length, (u16) sizeof device_desc); + value = sizeof device_desc; memcpy(req->buf, &device_desc, value); break; #ifdef CONFIG_USB_GADGET_DUALSPEED @@ -1382,7 +1381,7 @@ VDBG(fsg, "get device qualifier\n"); if (!fsg->gadget->is_dualspeed) break; - value = min(w_length, (u16) sizeof dev_qualifier); + value = sizeof dev_qualifier; memcpy(req->buf, &dev_qualifier, value); break; @@ -1401,8 +1400,6 @@ req->buf, w_value >> 8, w_value & 0xff); - if (value >= 0) - value = min(w_length, (u16) value); break; case USB_DT_STRING: @@ -1411,8 +1408,6 @@ /* wIndex == language code */ value = usb_gadget_get_string(&stringtab, w_value & 0xff, req->buf); - if (value >= 0) - value = min(w_length, (u16) value); break; } break; @@ -1438,7 +1433,7 @@ break; VDBG(fsg, "get configuration\n"); *(u8 *) req->buf = fsg->config; - value = min(w_length, (u16) 1); + value = 1; break; case USB_REQ_SET_INTERFACE: @@ -1466,14 +1461,14 @@ } VDBG(fsg, "get interface\n"); *(u8 *) req->buf = 0; - value = min(w_length, (u16) 1); + value = 1; break; default: VDBG(fsg, "unknown control req %02x.%02x v%04x i%04x l%u\n", ctrl->bRequestType, ctrl->bRequest, - w_value, w_index, w_length); + w_value, w_index, ctrl->wLength); } return value; @@ -1485,6 +1480,7 @@ { struct fsg_dev *fsg = get_gadget_data(gadget); int rc; + int w_length = ctrl->wLength; ++fsg->ep0_req_tag; // Record arrival of a new request fsg->ep0req->context = NULL; @@ -1498,8 +1494,9 @@ /* Respond with data/status or defer until later? */ if (rc >= 0 && rc != DELAYED_STATUS) { + rc = min(rc, w_length); fsg->ep0req->length = rc; - fsg->ep0req->zero = (rc < ctrl->wLength && + fsg->ep0req->zero = (rc < w_length && (rc % gadget->ep0->maxpacket) == 0); fsg->ep0req_name = (ctrl->bRequestType & USB_DIR_IN ? "ep0-in" : "ep0-out"); diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/gadget/rndis.c linux-2.6.12-rc2-usb/drivers/usb/gadget/rndis.c --- linux-2.6.12-rc2/drivers/usb/gadget/rndis.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/gadget/rndis.c 2005-04-09 08:57:14.000000000 -0700 @@ -37,6 +37,7 @@ #include #include #include +#include #undef RNDIS_PM @@ -165,7 +166,7 @@ /* mandatory */ case OID_GEN_LINK_SPEED: - DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); +// DEBUG("%s: OID_GEN_LINK_SPEED\n", __FUNCTION__); length = 4; if (rndis_per_dev_params [configNr].media_state == NDIS_MEDIA_STATE_DISCONNECTED) @@ -729,7 +730,7 @@ retval = 0; /* FIXME use these NDIS_PACKET_TYPE_* bitflags to - * filter packets in hard_start_xmit() + * set the cdc_filter; it's not RNDIS-specific * NDIS_PACKET_TYPE_x == USB_CDC_PACKET_TYPE_x for x in: * PROMISCUOUS, DIRECTED, * MULTICAST, ALL_MULTICAST, BROADCAST @@ -1194,10 +1195,10 @@ return; header = (void *) skb_push (skb, sizeof *header); memset (header, 0, sizeof *header); - header->MessageType = __constant_cpu_to_le32 (1); + header->MessageType = __constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG); header->MessageLength = cpu_to_le32(skb->len); header->DataOffset = __constant_cpu_to_le32 (36); - header->OOBDataOffset = cpu_to_le32(skb->len - 44); + header->DataLength = cpu_to_le32(skb->len - sizeof *header); } void rndis_free_response (int configNr, u8 *buf) @@ -1253,26 +1254,23 @@ return r; } -int rndis_rm_hdr (u8 *buf, u32 *length) +int rndis_rm_hdr(struct sk_buff *skb) { - u32 i, messageLen, dataOffset; - __le32 *tmp; - - tmp = (__le32 *) buf; + /* tmp points to a struct rndis_packet_msg_type */ + __le32 *tmp = (void *) skb->data; - if (!buf || !length) return -1; - if (le32_to_cpup(tmp++) != 1) return -1; - - messageLen = le32_to_cpup(tmp++); - dataOffset = le32_to_cpup(tmp++) + 8; + /* MessageType, MessageLength */ + if (__constant_cpu_to_le32(REMOTE_NDIS_PACKET_MSG) + != get_unaligned(tmp++)) + return -EINVAL; + tmp++; + + /* DataOffset, DataLength */ + if (!skb_pull(skb, le32_to_cpu(get_unaligned(tmp++)) + + 8 /* offset of DataOffset */)) + return -EOVERFLOW; + skb_trim(skb, le32_to_cpu(get_unaligned(tmp++))); - if (messageLen < dataOffset || messageLen > *length) return -1; - - for (i = dataOffset; i < messageLen; i++) - buf [i - dataOffset] = buf [i]; - - *length = messageLen - dataOffset; - return 0; } diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/gadget/rndis.h linux-2.6.12-rc2-usb/drivers/usb/gadget/rndis.h --- linux-2.6.12-rc2/drivers/usb/gadget/rndis.h 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/gadget/rndis.h 2005-04-09 08:57:14.000000000 -0700 @@ -38,6 +38,7 @@ */ /* Message Set for Connectionless (802.3) Devices */ +#define REMOTE_NDIS_PACKET_MSG 0x00000001U #define REMOTE_NDIS_INITIALIZE_MSG 0x00000002U /* Initialize device */ #define REMOTE_NDIS_HALT_MSG 0x00000003U #define REMOTE_NDIS_QUERY_MSG 0x00000004U @@ -333,7 +334,7 @@ const char *vendorDescr); int rndis_set_param_medium (u8 configNr, u32 medium, u32 speed); void rndis_add_hdr (struct sk_buff *skb); -int rndis_rm_hdr (u8 *buf, u32 *length); +int rndis_rm_hdr (struct sk_buff *skb); u8 *rndis_get_next_response (int configNr, u32 *length); void rndis_free_response (int configNr, u8 *buf); diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/ehci-dbg.c linux-2.6.12-rc2-usb/drivers/usb/host/ehci-dbg.c --- linux-2.6.12-rc2/drivers/usb/host/ehci-dbg.c 2005-04-07 00:36:34.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/ehci-dbg.c 2005-04-09 08:57:13.000000000 -0700 @@ -394,7 +394,7 @@ mark = ' '; if (hw_curr == td->qtd_dma) mark = '*'; - else if (qh->hw_qtd_next == td->qtd_dma) + else if (qh->hw_qtd_next == cpu_to_le32(td->qtd_dma)) mark = '+'; else if (QTD_LENGTH (scratch)) { if (td->hw_alt_next == ehci->async->hw_alt_next) diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/ehci-hcd.c linux-2.6.12-rc2-usb/drivers/usb/host/ehci-hcd.c --- linux-2.6.12-rc2/drivers/usb/host/ehci-hcd.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/ehci-hcd.c 2005-04-09 08:57:13.000000000 -0700 @@ -721,7 +721,7 @@ * the right sort of wakeup. */ -static int ehci_suspend (struct usb_hcd *hcd, u32 state) +static int ehci_suspend (struct usb_hcd *hcd, pm_message_t message) { struct ehci_hcd *ehci = hcd_to_ehci (hcd); @@ -729,7 +729,7 @@ msleep (100); #ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub, state); + (void) usb_suspend_device (hcd->self.root_hub, message); #else usb_lock_device (hcd->self.root_hub); (void) ehci_hub_suspend (hcd); diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/ehci-sched.c linux-2.6.12-rc2-usb/drivers/usb/host/ehci-sched.c --- linux-2.6.12-rc2/drivers/usb/host/ehci-sched.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/ehci-sched.c 2005-04-09 08:57:13.000000000 -0700 @@ -310,9 +310,9 @@ for (i = qh->start; i < ehci->periodic_size; i += period) { union ehci_shadow *prev = &ehci->pshadow [i]; - u32 *hw_p = &ehci->periodic [i]; + __le32 *hw_p = &ehci->periodic [i]; union ehci_shadow here = *prev; - u32 type = 0; + __le32 type = 0; /* skip the iso nodes at list head */ while (here.ptr) { diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/ehci.h linux-2.6.12-rc2-usb/drivers/usb/host/ehci.h --- linux-2.6.12-rc2/drivers/usb/host/ehci.h 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/ehci.h 2005-04-09 08:57:13.000000000 -0700 @@ -364,7 +364,7 @@ struct ehci_itd *itd; /* Q_TYPE_ITD */ struct ehci_sitd *sitd; /* Q_TYPE_SITD */ struct ehci_fstn *fstn; /* Q_TYPE_FSTN */ - u32 *hw_next; /* (all types) */ + __le32 *hw_next; /* (all types) */ void *ptr; }; diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/ohci-pci.c linux-2.6.12-rc2-usb/drivers/usb/host/ohci-pci.c --- linux-2.6.12-rc2/drivers/usb/host/ohci-pci.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/ohci-pci.c 2005-04-09 08:57:13.000000000 -0700 @@ -54,7 +54,7 @@ if (pdev->vendor == PCI_VENDOR_ID_AMD && pdev->device == 0x740c) { ohci->flags = OHCI_QUIRK_AMD756; - ohci_info (ohci, "AMD756 erratum 4 workaround\n"); + ohci_dbg (ohci, "AMD756 erratum 4 workaround\n"); // also somewhat erratum 10 (suspend/resume issues) } @@ -68,7 +68,7 @@ */ else if (pdev->vendor == PCI_VENDOR_ID_OPTI && pdev->device == 0xc861) { - ohci_info (ohci, + ohci_dbg (ohci, "WARNING: OPTi workarounds unavailable\n"); } @@ -84,9 +84,20 @@ if (b && b->device == PCI_DEVICE_ID_NS_87560_LIO && b->vendor == PCI_VENDOR_ID_NS) { ohci->flags |= OHCI_QUIRK_SUPERIO; - ohci_info (ohci, "Using NSC SuperIO setup\n"); + ohci_dbg (ohci, "Using NSC SuperIO setup\n"); } } + + /* Check for Compaq's ZFMicro chipset, which needs short + * delays before control or bulk queues get re-activated + * in finish_unlinks() + */ + else if (pdev->vendor == PCI_VENDOR_ID_COMPAQ + && pdev->device == 0xa0f8) { + ohci->flags |= OHCI_QUIRK_ZFMICRO; + ohci_dbg (ohci, + "enabled Compaq ZFMicro chipset quirk\n"); + } } /* NOTE: there may have already been a first reset, to @@ -102,7 +113,7 @@ #ifdef CONFIG_PM -static int ohci_pci_suspend (struct usb_hcd *hcd, u32 state) +static int ohci_pci_suspend (struct usb_hcd *hcd, pm_message_t message) { struct ohci_hcd *ohci = hcd_to_ohci (hcd); @@ -111,7 +122,7 @@ msleep (100); #ifdef CONFIG_USB_SUSPEND - (void) usb_suspend_device (hcd->self.root_hub, state); + (void) usb_suspend_device (hcd->self.root_hub, message); #else usb_lock_device (hcd->self.root_hub); (void) ohci_hub_suspend (hcd); diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/ohci-q.c linux-2.6.12-rc2-usb/drivers/usb/host/ohci-q.c --- linux-2.6.12-rc2/drivers/usb/host/ohci-q.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/ohci-q.c 2005-04-09 08:57:13.000000000 -0700 @@ -1021,6 +1021,8 @@ if (ohci->ed_controltail) { command |= OHCI_CLF; + if (ohci->flags & OHCI_QUIRK_ZFMICRO) + mdelay(1); if (!(ohci->hc_control & OHCI_CTRL_CLE)) { control |= OHCI_CTRL_CLE; ohci_writel (ohci, 0, @@ -1029,6 +1031,8 @@ } if (ohci->ed_bulktail) { command |= OHCI_BLF; + if (ohci->flags & OHCI_QUIRK_ZFMICRO) + mdelay(1); if (!(ohci->hc_control & OHCI_CTRL_BLE)) { control |= OHCI_CTRL_BLE; ohci_writel (ohci, 0, @@ -1039,12 +1043,17 @@ /* CLE/BLE to enable, CLF/BLF to (maybe) kickstart */ if (control) { ohci->hc_control |= control; + if (ohci->flags & OHCI_QUIRK_ZFMICRO) + mdelay(1); ohci_writel (ohci, ohci->hc_control, &ohci->regs->control); } - if (command) + if (command) { + if (ohci->flags & OHCI_QUIRK_ZFMICRO) + mdelay(1); ohci_writel (ohci, command, &ohci->regs->cmdstatus); - } + } + } } diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/ohci.h linux-2.6.12-rc2-usb/drivers/usb/host/ohci.h --- linux-2.6.12-rc2/drivers/usb/host/ohci.h 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/ohci.h 2005-04-09 08:57:13.000000000 -0700 @@ -396,6 +396,7 @@ #define OHCI_QUIRK_SUPERIO 0x02 /* natsemi */ #define OHCI_QUIRK_INITRESET 0x04 /* SiS, OPTi, ... */ #define OHCI_BIG_ENDIAN 0x08 /* big endian HC */ +#define OHCI_QUIRK_ZFMICRO 0x10 /* Compaq ZFMicro chipset*/ // there are also chip quirks/bugs in init logic }; diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/host/uhci-hcd.c linux-2.6.12-rc2-usb/drivers/usb/host/uhci-hcd.c --- linux-2.6.12-rc2/drivers/usb/host/uhci-hcd.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/host/uhci-hcd.c 2005-04-09 08:57:13.000000000 -0700 @@ -716,7 +716,7 @@ } #ifdef CONFIG_PM -static int uhci_suspend(struct usb_hcd *hcd, u32 state) +static int uhci_suspend(struct usb_hcd *hcd, pm_message_t message) { struct uhci_hcd *uhci = hcd_to_uhci(hcd); diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/input/hid-core.c linux-2.6.12-rc2-usb/drivers/usb/input/hid-core.c --- linux-2.6.12-rc2/drivers/usb/input/hid-core.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/input/hid-core.c 2005-04-09 08:57:12.000000000 -0700 @@ -1790,12 +1790,12 @@ return 0; } -static int hid_suspend(struct usb_interface *intf, u32 state) +static int hid_suspend(struct usb_interface *intf, pm_message_t message) { struct hid_device *hid = usb_get_intfdata (intf); usb_kill_urb(hid->urbin); - intf->dev.power.power_state = state; + intf->dev.power.power_state = PMSG_SUSPEND; dev_dbg(&intf->dev, "suspend\n"); return 0; } @@ -1805,7 +1805,7 @@ struct hid_device *hid = usb_get_intfdata (intf); int status; - intf->dev.power.power_state = PM_SUSPEND_ON; + intf->dev.power.power_state = PMSG_ON; if (hid->open) status = usb_submit_urb(hid->urbin, GFP_NOIO); else diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/misc/sisusbvga/sisusb.c linux-2.6.12-rc2-usb/drivers/usb/misc/sisusbvga/sisusb.c --- linux-2.6.12-rc2/drivers/usb/misc/sisusbvga/sisusb.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/misc/sisusbvga/sisusb.c 2005-04-09 08:57:13.000000000 -0700 @@ -3104,6 +3104,7 @@ static struct usb_device_id sisusb_table [] = { { USB_DEVICE(0x0711, 0x0900) }, + { USB_DEVICE(0x182d, 0x021c) }, { } }; @@ -3114,7 +3115,7 @@ .name = "sisusb", .probe = sisusb_probe, .disconnect = sisusb_disconnect, - .id_table = sisusb_table + .id_table = sisusb_table, }; static int __init usb_sisusb_init(void) diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/net/pegasus.c linux-2.6.12-rc2-usb/drivers/usb/net/pegasus.c --- linux-2.6.12-rc2/drivers/usb/net/pegasus.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/net/pegasus.c 2005-04-09 08:57:12.000000000 -0700 @@ -1364,11 +1364,18 @@ free_netdev(pegasus->net); } -static int pegasus_suspend (struct usb_interface *intf, pm_message_t state) +static int pegasus_suspend (struct usb_interface *intf, pm_message_t message) { struct pegasus *pegasus = usb_get_intfdata(intf); netif_device_detach (pegasus->net); + if (netif_running(pegasus->net)) { + cancel_delayed_work(&pegasus->carrier_check); + + usb_kill_urb(pegasus->rx_urb); + usb_kill_urb(pegasus->intr_urb); + } + intf->dev.power.power_state = PMSG_SUSPEND; return 0; } @@ -1376,7 +1383,20 @@ { struct pegasus *pegasus = usb_get_intfdata(intf); + intf->dev.power.power_state = PMSG_ON; netif_device_attach (pegasus->net); + if (netif_running(pegasus->net)) { + pegasus->rx_urb->status = 0; + pegasus->rx_urb->actual_length = 0; + read_bulk_callback(pegasus->rx_urb, 0); + + pegasus->intr_urb->status = 0; + pegasus->intr_urb->actual_length = 0; + intr_callback(pegasus->intr_urb, 0); + + queue_delayed_work(pegasus_workqueue, &pegasus->carrier_check, + CARRIER_CHECK_DELAY); + } return 0; } diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/net/usbnet.c linux-2.6.12-rc2-usb/drivers/usb/net/usbnet.c --- linux-2.6.12-rc2/drivers/usb/net/usbnet.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/net/usbnet.c 2005-04-09 08:57:13.000000000 -0700 @@ -426,7 +426,7 @@ dev->stats.rx_bytes += skb->len; if (netif_msg_rx_status (dev)) - devdbg (dev, "< rx, len %d, type 0x%x", + devdbg (dev, "< rx, len %zd, type 0x%x", skb->len + sizeof (struct ethhdr), skb->protocol); memset (skb->cb, 0, sizeof (struct skb_data)); status = netif_rx (skb); @@ -3732,11 +3732,17 @@ #ifdef CONFIG_PM -static int usbnet_suspend (struct usb_interface *intf, u32 state) +static int usbnet_suspend (struct usb_interface *intf, pm_message_t message) { struct usbnet *dev = usb_get_intfdata(intf); + /* accelerate emptying of the rx and queues, to avoid + * having everything error out. + */ netif_device_detach (dev->net); + (void) unlink_urbs (dev, &dev->rxq); + (void) unlink_urbs (dev, &dev->txq); + intf->dev.power.power_state = PMSG_SUSPEND; return 0; } @@ -3744,7 +3750,9 @@ { struct usbnet *dev = usb_get_intfdata(intf); + intf->dev.power.power_state = PMSG_ON; netif_device_attach (dev->net); + tasklet_schedule (&dev->bh); return 0; } @@ -4009,10 +4017,23 @@ .idProduct = 0x9050, /* C-860 */ ZAURUS_MASTER_INTERFACE, .driver_info = ZAURUS_PXA_INFO, +}, + #ifdef CONFIG_USB_ZAURUS - /* at least some (reports vary) C-860 units have very different - * lies about their standards support. + /* at least some (reports vary) PXA units have very different + * lies about their standards support: they claim to be cell + * phones giving direct radio access (which they aren't). */ +{ + .match_flags = USB_DEVICE_ID_MATCH_INT_INFO + | USB_DEVICE_ID_MATCH_DEVICE, + .idVendor = 0x04DD, + /* Sharp ROM v1.32 */ + .idProduct = 0x8006, /* SL-5600 */ + .bInterfaceClass = USB_CLASS_COMM, + .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, + .bInterfaceProtocol = USB_CDC_PROTO_NONE, + .driver_info = (unsigned long) &zaurus_pxa_mdlm_info, }, { .match_flags = USB_DEVICE_ID_MATCH_INT_INFO | USB_DEVICE_ID_MATCH_DEVICE, @@ -4023,8 +4044,8 @@ .bInterfaceSubClass = USB_CDC_SUBCLASS_MDLM, .bInterfaceProtocol = USB_CDC_PROTO_NONE, .driver_info = (unsigned long) &zaurus_pxa_mdlm_info, -#endif }, +#endif /* Olympus has some models with a Zaurus-compatible option. * R-1000 uses a FreeScale i.MXL cpu (ARMv4T) diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/serial/digi_acceleport.c linux-2.6.12-rc2-usb/drivers/usb/serial/digi_acceleport.c --- linux-2.6.12-rc2/drivers/usb/serial/digi_acceleport.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/serial/digi_acceleport.c 2005-04-09 08:57:13.000000000 -0700 @@ -568,6 +568,9 @@ * and the sleep. In other words, spin_unlock_irqrestore and * interruptible_sleep_on_timeout are "atomic" with respect to * wake ups. This is used to implement condition variables. +* +* interruptible_sleep_on_timeout is deprecated and has been replaced +* with the equivalent code. */ static inline long cond_wait_interruptible_timeout_irqrestore( @@ -576,13 +579,12 @@ { DEFINE_WAIT(wait); - prepare_to_wait(q, &wait, TASK_UNINTERRUPTIBLE); + prepare_to_wait(q, &wait, TASK_INTERRUPTIBLE); spin_unlock_irqrestore(lock, flags); timeout = schedule_timeout(timeout); finish_wait(q, &wait); return timeout; - } @@ -1596,7 +1598,7 @@ dbg( "digi_close: write oob failed, ret=%d", ret ); /* wait for final commands on oob port to complete */ - prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_UNINTERRUPTIBLE); + prepare_to_wait(&priv->dp_flush_wait, &wait, TASK_INTERRUPTIBLE); schedule_timeout(DIGI_CLOSE_TIMEOUT); finish_wait(&priv->dp_flush_wait, &wait); @@ -1995,7 +1997,7 @@ } else if( opcode == DIGI_CMD_IFLUSH_FIFO ) { - wake_up( &priv->dp_flush_wait ); + wake_up_interruptible( &priv->dp_flush_wait ); } diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/serial/visor.c linux-2.6.12-rc2-usb/drivers/usb/serial/visor.c --- linux-2.6.12-rc2/drivers/usb/serial/visor.c 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/serial/visor.c 2005-04-09 08:57:13.000000000 -0700 @@ -215,6 +215,8 @@ .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID), @@ -237,6 +239,8 @@ .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, + { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID), + .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID), .driver_info = (kernel_ulong_t)&palm_os_4_probe }, { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID), @@ -273,6 +277,7 @@ { USB_DEVICE(PALM_VENDOR_ID, PALM_M125_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_M130_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_T_ID) }, + { USB_DEVICE(PALM_VENDOR_ID, PALM_TREO_650) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_TUNGSTEN_Z_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE31_ID) }, { USB_DEVICE(PALM_VENDOR_ID, PALM_ZIRE_ID) }, @@ -286,6 +291,7 @@ { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID) }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID) }, { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID) }, + { USB_DEVICE(TAPWAVE_VENDOR_ID, TAPWAVE_ZODIAC_ID) }, { USB_DEVICE(GARMIN_VENDOR_ID, GARMIN_IQUE_3600_ID) }, { USB_DEVICE(ACEECA_VENDOR_ID, ACEECA_MEZ1000_ID) }, { USB_DEVICE(KYOCERA_VENDOR_ID, KYOCERA_7135_ID) }, diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/serial/visor.h linux-2.6.12-rc2-usb/drivers/usb/serial/visor.h --- linux-2.6.12-rc2/drivers/usb/serial/visor.h 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/serial/visor.h 2005-04-09 08:57:13.000000000 -0700 @@ -30,6 +30,7 @@ #define PALM_M125_ID 0x0040 #define PALM_M130_ID 0x0050 #define PALM_TUNGSTEN_T_ID 0x0060 +#define PALM_TREO_650 0x0061 #define PALM_TUNGSTEN_Z_ID 0x0031 #define PALM_ZIRE31_ID 0x0061 #define PALM_ZIRE_ID 0x0070 @@ -49,6 +50,9 @@ #define SAMSUNG_SCH_I330_ID 0x8001 #define SAMSUNG_SPH_I500_ID 0x6601 +#define TAPWAVE_VENDOR_ID 0x12EF +#define TAPWAVE_ZODIAC_ID 0x0100 + #define GARMIN_VENDOR_ID 0x091E #define GARMIN_IQUE_3600_ID 0x0004 diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/storage/transport.c linux-2.6.12-rc2-usb/drivers/usb/storage/transport.c --- linux-2.6.12-rc2/drivers/usb/storage/transport.c 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/storage/transport.c 2005-04-09 08:57:13.000000000 -0700 @@ -996,7 +996,7 @@ * command phase and the data phase. Some devices need a little * more than that, probably because of clock rate inaccuracies. */ if (unlikely(us->flags & US_FL_GO_SLOW)) - udelay(110); + udelay(125); if (transfer_length) { unsigned int pipe = srb->sc_data_direction == DMA_FROM_DEVICE ? diff -Naur -X ../dontdiff linux-2.6.12-rc2/drivers/usb/storage/unusual_devs.h linux-2.6.12-rc2-usb/drivers/usb/storage/unusual_devs.h --- linux-2.6.12-rc2/drivers/usb/storage/unusual_devs.h 2005-04-07 00:35:55.000000000 -0700 +++ linux-2.6.12-rc2-usb/drivers/usb/storage/unusual_devs.h 2005-04-09 08:57:13.000000000 -0700 @@ -763,6 +763,19 @@ US_FL_SINGLE_LUN ), #endif +#ifdef CONFIG_USB_STORAGE_DATAFAB +/* Reported by Felix Moeller + * in Germany this is sold by Hama with the productnumber 46952 + * as "DualSlot CompactFlash(TM) & MStick Drive USB" + */ +UNUSUAL_DEV( 0x07c4, 0xa10b, 0x0000, 0xffff, + "DataFab Systems Inc.", + "USB CF+MS", + US_SC_SCSI, US_PR_DATAFAB, NULL, + 0 ), + +#endif + /* Datafab KECF-USB / Sagatek DCS-CF / Simpletech Flashlink UCF-100 * Only revision 1.13 tested (same for all of the above devices, * based on the Datafab DF-UG-07 chip). Needed for US_FL_FIX_INQUIRY. diff -Naur -X ../dontdiff linux-2.6.12-rc2/include/linux/usb.h linux-2.6.12-rc2-usb/include/linux/usb.h --- linux-2.6.12-rc2/include/linux/usb.h 2005-04-07 00:36:34.000000000 -0700 +++ linux-2.6.12-rc2-usb/include/linux/usb.h 2005-04-09 08:57:12.000000000 -0700 @@ -558,7 +558,7 @@ int (*ioctl) (struct usb_interface *intf, unsigned int code, void *buf); - int (*suspend) (struct usb_interface *intf, u32 state); + int (*suspend) (struct usb_interface *intf, pm_message_t message); int (*resume) (struct usb_interface *intf); const struct usb_device_id *id_table; @@ -977,7 +977,7 @@ int timeout); /* selective suspend/resume */ -extern int usb_suspend_device(struct usb_device *dev, u32 state); +extern int usb_suspend_device(struct usb_device *dev, pm_message_t message); extern int usb_resume_device(struct usb_device *dev); diff -Naur -X ../dontdiff linux-2.6.12-rc2/include/linux/usb_cdc.h linux-2.6.12-rc2-usb/include/linux/usb_cdc.h --- linux-2.6.12-rc2/include/linux/usb_cdc.h 2005-04-07 00:36:31.000000000 -0700 +++ linux-2.6.12-rc2-usb/include/linux/usb_cdc.h 2005-04-09 08:57:12.000000000 -0700 @@ -114,7 +114,7 @@ /* type is associated with mdlm_desc.bGUID */ __u8 bGuidDescriptorType; - __u8 bDetailData[]; + __u8 bDetailData[0]; } __attribute__ ((packed)); /*-------------------------------------------------------------------------*/