Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6
authorLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 24 Aug 2007 04:35:04 +0000 (21:35 -0700)
committerLinus Torvalds <torvalds@woody.linux-foundation.org>
Fri, 24 Aug 2007 04:35:04 +0000 (21:35 -0700)
* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/usb-2.6: (35 commits)
  usb: add PRODUCT, TYPE to usb-interface events
  USB: resubmission unusual_devs modification for Nikon D80
  usb quirks: Add Canon EOS 5D (PC Connection mode) to the autosuspend blacklist
  USB: make EHCI initialize properly on PPC SOCs
  UEAGLE: Remove sysfs files on error case
  USB: fsl_usb2_udc: fix bug in processing setup requests
  USB: g_file_storage: fix bug in DMA buffer handling
  USB: update last_busy field correctly
  USB: fix DoS in pwc USB video driver
  USB: allow retry on descriptor fetch errors
  USB: unkill cxacru atm driver
  USB: Adding support for HTC Smartphones to ipaq
  USB: another quirky device
  USB: quirky mass storage device
  USB: ohci, fix oddball gcc warning
  usb-storage: fix bugs in the disconnect pathway
  usb: typo in usb R8A66597 HCD config
  USB: accept 1-byte Device Status replies, fixing some b0rken devices
  USB: blacklist Samsung ML-2010 printer
  usb-serial: fix oti6858.c segfault in termios handling
  ...

35 files changed:
drivers/media/video/em28xx/em28xx-video.c
drivers/media/video/pwc/pwc-if.c
drivers/media/video/pwc/pwc.h
drivers/usb/Kconfig
drivers/usb/atm/cxacru.c
drivers/usb/atm/ueagle-atm.c
drivers/usb/class/cdc-acm.c
drivers/usb/core/driver.c
drivers/usb/core/hub.c
drivers/usb/core/message.c
drivers/usb/core/quirks.c
drivers/usb/gadget/dummy_hcd.c
drivers/usb/gadget/file_storage.c
drivers/usb/gadget/fsl_usb2_udc.c
drivers/usb/gadget/pxa2xx_udc.c
drivers/usb/host/Kconfig
drivers/usb/host/ehci-au1xxx.c
drivers/usb/host/ehci-ppc-soc.c
drivers/usb/host/ohci-dbg.c
drivers/usb/host/r8a66597-hcd.c
drivers/usb/host/u132-hcd.c
drivers/usb/serial/airprime.c
drivers/usb/serial/belkin_sa.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/ftdi_sio.h
drivers/usb/serial/garmin_gps.c
drivers/usb/serial/ipaq.c
drivers/usb/serial/option.c
drivers/usb/serial/oti6858.c
drivers/usb/serial/safe_serial.c
drivers/usb/serial/visor.c
drivers/usb/serial/visor.h
drivers/usb/storage/unusual_devs.h
drivers/usb/storage/usb.c
drivers/usb/storage/usb.h

index 2c7b158ce7e1bdbf9af1826701a9780ba6a3aa58..40307f3f6fe31118be769ecf2103873c86ead2ec 100644 (file)
@@ -1772,6 +1772,7 @@ static int em28xx_usb_probe(struct usb_interface *interface,
        if (dev->alt_max_pkt_size == NULL) {
                em28xx_errdev("out of memory!\n");
                em28xx_devused&=~(1<<nr);
+               kfree(dev);
                return -ENOMEM;
        }
 
index 9c0e8d18c2f6085e7bcb9a39c53dcb6212283179..3d81966d8c421eda17a483059dae48bb0f443471 100644 (file)
@@ -1196,12 +1196,19 @@ static int pwc_video_open(struct inode *inode, struct file *file)
        return 0;
 }
 
+
+static void pwc_cleanup(struct pwc_device *pdev)
+{
+       pwc_remove_sysfs_files(pdev->vdev);
+       video_unregister_device(pdev->vdev);
+}
+
 /* Note that all cleanup is done in the reverse order as in _open */
 static int pwc_video_close(struct inode *inode, struct file *file)
 {
        struct video_device *vdev = file->private_data;
        struct pwc_device *pdev;
-       int i;
+       int i, hint;
 
        PWC_DEBUG_OPEN(">> video_close called(vdev = 0x%p).\n", vdev);
 
@@ -1224,8 +1231,9 @@ static int pwc_video_close(struct inode *inode, struct file *file)
        pwc_isoc_cleanup(pdev);
        pwc_free_buffers(pdev);
 
+       lock_kernel();
        /* Turn off LEDS and power down camera, but only when not unplugged */
-       if (pdev->error_status != EPIPE) {
+       if (!pdev->unplugged) {
                /* Turn LEDs off */
                if (pwc_set_leds(pdev, 0, 0) < 0)
                        PWC_DEBUG_MODULE("Failed to set LED on/off time.\n");
@@ -1234,9 +1242,19 @@ static int pwc_video_close(struct inode *inode, struct file *file)
                        if (i < 0)
                                PWC_ERROR("Failed to power down camera (%d)\n", i);
                }
+               pdev->vopen--;
+               PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", i);
+       } else {
+               pwc_cleanup(pdev);
+               /* Free memory (don't set pdev to 0 just yet) */
+               kfree(pdev);
+               /* search device_hint[] table if we occupy a slot, by any chance */
+               for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+                       if (device_hint[hint].pdev == pdev)
+                               device_hint[hint].pdev = NULL;
        }
-       pdev->vopen--;
-       PWC_DEBUG_OPEN("<< video_close() vopen=%d\n", pdev->vopen);
+       unlock_kernel();
+
        return 0;
 }
 
@@ -1791,21 +1809,21 @@ static void usb_pwc_disconnect(struct usb_interface *intf)
        /* Alert waiting processes */
        wake_up_interruptible(&pdev->frameq);
        /* Wait until device is closed */
-       while (pdev->vopen)
-               schedule();
-       /* Device is now closed, so we can safely unregister it */
-       PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
-       pwc_remove_sysfs_files(pdev->vdev);
-       video_unregister_device(pdev->vdev);
-
-       /* Free memory (don't set pdev to 0 just yet) */
-       kfree(pdev);
+       if(pdev->vopen) {
+               pdev->unplugged = 1;
+       } else {
+               /* Device is closed, so we can safely unregister it */
+               PWC_DEBUG_PROBE("Unregistering video device in disconnect().\n");
+               pwc_cleanup(pdev);
+               /* Free memory (don't set pdev to 0 just yet) */
+               kfree(pdev);
 
 disconnect_out:
-       /* search device_hint[] table if we occupy a slot, by any chance */
-       for (hint = 0; hint < MAX_DEV_HINTS; hint++)
-               if (device_hint[hint].pdev == pdev)
-                       device_hint[hint].pdev = NULL;
+               /* search device_hint[] table if we occupy a slot, by any chance */
+               for (hint = 0; hint < MAX_DEV_HINTS; hint++)
+                       if (device_hint[hint].pdev == pdev)
+                               device_hint[hint].pdev = NULL;
+       }
 
        unlock_kernel();
 }
index 910a04f539202a2d6a5f3b2adb879c7c551a69b1..8e8e5b27e77ea2f9c77edd549bc696b7b7c1000e 100644 (file)
@@ -193,6 +193,7 @@ struct pwc_device
    char vsnapshot;             /* snapshot mode */
    char vsync;                 /* used by isoc handler */
    char vmirror;               /* for ToUCaM series */
+       char unplugged;
 
    int cmd_len;
    unsigned char cmd_buf[13];
index 63436892688c04ca070d8e4574337d2babbedc80..7580aa5da0f866ba72705eb00cdee6b5b3af355c 100644 (file)
@@ -21,6 +21,7 @@ config USB_ARCH_HAS_HCD
        default y if USB_ARCH_HAS_EHCI
        default y if PCMCIA && !M32R                    # sl811_cs
        default y if ARM                                # SL-811
+       default y if SUPERH                             # r8a66597-hcd
        default PCI
 
 # many non-PCI SOC chips embed OHCI
index 02c52f8d5dbf2b097af0b5f9e6b0a389afa7af6a..a73e714288e51fa11dbfb86cc71e71039e3f4ae1 100644 (file)
@@ -456,7 +456,6 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
                                 int* actual_length)
 {
        struct timer_list timer;
-       int status = urb->status;
 
        init_timer(&timer);
        timer.expires = jiffies + msecs_to_jiffies(CMD_TIMEOUT);
@@ -468,7 +467,7 @@ static int cxacru_start_wait_urb(struct urb *urb, struct completion *done,
 
        if (actual_length)
                *actual_length = urb->actual_length;
-       return status;
+       return urb->status; /* must read status after completion */
 }
 
 static int cxacru_cm(struct cxacru_data *instance, enum cxacru_cm_request cm,
index a1a1c9d467e028157c84289a9d92ccd0fe97c4b9..29807d048b0413ee0c83b2654dbdda560cf3a741 100644 (file)
@@ -1721,9 +1721,12 @@ static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,
 
        ret = uea_boot(sc);
        if (ret < 0)
-               goto error;
+               goto error_rm_grp;
 
        return 0;
+
+error_rm_grp:
+       sysfs_remove_group(&intf->dev.kobj, &attr_grp);
 error:
        kfree(sc);
        return ret;
index fe940e0536e03488016d1171da3866ce8bb6dd00..f51e22490edfaccae55b641723c939ce0019087b 100644 (file)
@@ -921,6 +921,10 @@ skip_normal_probe:
                        return -EINVAL;
                }
        }
+
+       /* Accept probe requests only for the control interface */
+       if (intf != control_interface)
+               return -ENODEV;
        
        if (usb_interface_claimed(data_interface)) { /* valid in this context */
                dev_dbg(&intf->dev,"The data interface isn't available");
@@ -1109,10 +1113,12 @@ static void acm_disconnect(struct usb_interface *intf)
                return;
        }
        if (acm->country_codes){
-               device_remove_file(&intf->dev, &dev_attr_wCountryCodes);
-               device_remove_file(&intf->dev, &dev_attr_iCountryCodeRelDate);
+               device_remove_file(&acm->control->dev,
+                               &dev_attr_wCountryCodes);
+               device_remove_file(&acm->control->dev,
+                               &dev_attr_iCountryCodeRelDate);
        }
-       device_remove_file(&intf->dev, &dev_attr_bmCapabilities);
+       device_remove_file(&acm->control->dev, &dev_attr_bmCapabilities);
        acm->dev = NULL;
        usb_set_intfdata(acm->control, NULL);
        usb_set_intfdata(acm->data, NULL);
index 654857493a82e35e0837e840e3942b46b43c1251..a1ad11d0c47cacaa2b5b2a3fdd4ff7c0a62d563f 100644 (file)
@@ -1224,6 +1224,8 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
        udev->auto_pm = 1;
        udev->pm_usage_cnt += inc_usage_cnt;
        WARN_ON(udev->pm_usage_cnt < 0);
+       if (inc_usage_cnt)
+               udev->last_busy = jiffies;
        if (inc_usage_cnt >= 0 && udev->pm_usage_cnt > 0) {
                if (udev->state == USB_STATE_SUSPENDED)
                        status = usb_resume_both(udev);
@@ -1232,8 +1234,6 @@ static int usb_autopm_do_device(struct usb_device *udev, int inc_usage_cnt)
                else if (inc_usage_cnt)
                        udev->last_busy = jiffies;
        } else if (inc_usage_cnt <= 0 && udev->pm_usage_cnt <= 0) {
-               if (inc_usage_cnt)
-                       udev->last_busy = jiffies;
                status = usb_suspend_both(udev, PMSG_SUSPEND);
        }
        usb_pm_unlock(udev);
@@ -1342,16 +1342,15 @@ static int usb_autopm_do_interface(struct usb_interface *intf,
        else {
                udev->auto_pm = 1;
                intf->pm_usage_cnt += inc_usage_cnt;
+               udev->last_busy = jiffies;
                if (inc_usage_cnt >= 0 && intf->pm_usage_cnt > 0) {
                        if (udev->state == USB_STATE_SUSPENDED)
                                status = usb_resume_both(udev);
                        if (status != 0)
                                intf->pm_usage_cnt -= inc_usage_cnt;
-                       else if (inc_usage_cnt)
+                       else
                                udev->last_busy = jiffies;
                } else if (inc_usage_cnt <= 0 && intf->pm_usage_cnt <= 0) {
-                       if (inc_usage_cnt)
-                               udev->last_busy = jiffies;
                        status = usb_suspend_both(udev, PMSG_SUSPEND);
                }
        }
index e341a1da517fe8589c7153b0bf7811f84c435e51..f7b337feb3eac28ddcc997069b81fe16243fde8a 100644 (file)
@@ -1644,9 +1644,10 @@ static int finish_port_resume(struct usb_device *udev)
         * and device drivers will know about any resume quirks.
         */
        if (status == 0) {
+               devstatus = 0;
                status = usb_get_status(udev, USB_RECIP_DEVICE, 0, &devstatus);
                if (status >= 0)
-                       status = (status == 2 ? 0 : -ENODEV);
+                       status = (status > 0 ? 0 : -ENODEV);
        }
 
        if (status) {
index b6bd05e3d439eb41f6c87633d9bba10960d45498..d8f7b089a8f0ad243f3218cbb50c78deed02301b 100644 (file)
@@ -637,12 +637,12 @@ int usb_get_descriptor(struct usb_device *dev, unsigned char type, unsigned char
        memset(buf,0,size);     // Make sure we parse really received data
 
        for (i = 0; i < 3; ++i) {
-               /* retry on length 0 or stall; some devices are flakey */
+               /* retry on length 0 or error; some devices are flakey */
                result = usb_control_msg(dev, usb_rcvctrlpipe(dev, 0),
                                USB_REQ_GET_DESCRIPTOR, USB_DIR_IN,
                                (type << 8) + index, 0, buf, size,
                                USB_CTRL_GET_TIMEOUT);
-               if (result == 0 || result == -EPIPE)
+               if (result <= 0 && result != -ETIMEDOUT)
                        continue;
                if (result > 1 && ((u8 *)buf)[1] != type) {
                        result = -EPROTO;
@@ -1358,6 +1358,30 @@ static int usb_if_uevent(struct device *dev, char **envp, int num_envp,
        usb_dev = interface_to_usbdev(intf);
        alt = intf->cur_altsetting;
 
+#ifdef CONFIG_USB_DEVICEFS
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "DEVICE=/proc/bus/usb/%03d/%03d",
+                          usb_dev->bus->busnum, usb_dev->devnum))
+               return -ENOMEM;
+#endif
+
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "PRODUCT=%x/%x/%x",
+                          le16_to_cpu(usb_dev->descriptor.idVendor),
+                          le16_to_cpu(usb_dev->descriptor.idProduct),
+                          le16_to_cpu(usb_dev->descriptor.bcdDevice)))
+               return -ENOMEM;
+
+       if (add_uevent_var(envp, num_envp, &i,
+                          buffer, buffer_size, &length,
+                          "TYPE=%d/%d/%d",
+                          usb_dev->descriptor.bDeviceClass,
+                          usb_dev->descriptor.bDeviceSubClass,
+                          usb_dev->descriptor.bDeviceProtocol))
+               return -ENOMEM;
+
        if (add_uevent_var(envp, num_envp, &i,
                   buffer, buffer_size, &length,
                   "INTERFACE=%d/%d/%d",
index b7917c5a3c6f4182f6f085e8186790b17577f8d1..9e467118dc946cf1b8a3f46240c5c5f9f645dcac 100644 (file)
@@ -30,6 +30,8 @@
 static const struct usb_device_id usb_quirk_list[] = {
        /* HP 5300/5370C scanner */
        { USB_DEVICE(0x03f0, 0x0701), .driver_info = USB_QUIRK_STRING_FETCH_255 },
+       /* Hewlett-Packard PhotoSmart 720 / PhotoSmart 935 (storage) */
+       { USB_DEVICE(0x03f0, 0x4002), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Acer Peripherals Inc. (now BenQ Corp.) Prisa 640BU */
        { USB_DEVICE(0x04a5, 0x207e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Benq S2W 3300U */
@@ -56,6 +58,8 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x04b8, 0x0121), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Seiko Epson Corp.*/
        { USB_DEVICE(0x04b8, 0x0122), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       /* Samsung ML-2010 printer */
+       { USB_DEVICE(0x04e8, 0x326c), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Samsung ML-2510 Series printer */
        { USB_DEVICE(0x04e8, 0x327e), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Elsa MicroLink 56k (V.250) */
@@ -64,12 +68,20 @@ static const struct usb_device_id usb_quirk_list[] = {
        { USB_DEVICE(0x05d8, 0x4005), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Agfa Snapscan1212u */
        { USB_DEVICE(0x06bd, 0x2061), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+       /* Seagate RSS LLC */
+       { USB_DEVICE(0x0bc2, 0x3000), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        /* Umax [hex] Astra 3400U */
        { USB_DEVICE(0x1606, 0x0060), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
 
        /* Philips PSC805 audio device */
        { USB_DEVICE(0x0471, 0x0155), .driver_info = USB_QUIRK_RESET_RESUME },
 
+       /* Alcor multi-card reader */
+       { USB_DEVICE(0x058f, 0x6366), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
+       /* Canon EOS 5D in PC Connection mode */
+       { USB_DEVICE(0x04a9, 0x3101), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
+
        /* RIM Blackberry */
        { USB_DEVICE(0x0fca, 0x0001), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
        { USB_DEVICE(0x0fca, 0x0004), .driver_info = USB_QUIRK_NO_AUTOSUSPEND },
index f2fbdc7fe376ddf7397f056ab78eee74bc19f427..d008d1360a7aea6abf391da60a9a8eb0d5c8f5f2 100644 (file)
@@ -34,8 +34,6 @@
  * bypassing some hardware (and driver) issues.  UML could help too.
  */
 
-#define DEBUG
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
index be7a1bd2823b865ed777e0562ac774417057fa74..965ad7bec7b7a2f19b3e9ad9757aae2ff5b8a9c3 100644 (file)
@@ -599,7 +599,6 @@ enum fsg_buffer_state {
 
 struct fsg_buffhd {
        void                            *buf;
-       dma_addr_t                      dma;
        enum fsg_buffer_state           state;
        struct fsg_buffhd               *next;
 
@@ -1295,6 +1294,7 @@ static int class_setup_req(struct fsg_dev *fsg,
        struct usb_request      *req = fsg->ep0req;
        int                     value = -EOPNOTSUPP;
        u16                     w_index = le16_to_cpu(ctrl->wIndex);
+       u16                     w_value = le16_to_cpu(ctrl->wValue);
        u16                     w_length = le16_to_cpu(ctrl->wLength);
 
        if (!fsg->config)
@@ -1308,7 +1308,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0) {
+                       if (w_index != 0 || w_value != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -1324,7 +1324,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_IN |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0) {
+                       if (w_index != 0 || w_value != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -1343,7 +1343,7 @@ static int class_setup_req(struct fsg_dev *fsg,
                        if (ctrl->bRequestType != (USB_DIR_OUT |
                                        USB_TYPE_CLASS | USB_RECIP_INTERFACE))
                                break;
-                       if (w_index != 0) {
+                       if (w_index != 0 || w_value != 0) {
                                value = -EDOM;
                                break;
                        }
@@ -2611,7 +2611,6 @@ static int send_status(struct fsg_dev *fsg)
 
                fsg->intr_buffhd = bh;          // Point to the right buffhd
                fsg->intreq->buf = bh->inreq->buf;
-               fsg->intreq->dma = bh->inreq->dma;
                fsg->intreq->context = bh;
                start_transfer(fsg, fsg->intr_in, fsg->intreq,
                                &fsg->intreq_busy, &bh->state);
@@ -3200,7 +3199,6 @@ reset:
                if ((rc = alloc_request(fsg, fsg->bulk_out, &bh->outreq)) != 0)
                        goto reset;
                bh->inreq->buf = bh->outreq->buf = bh->buf;
-               bh->inreq->dma = bh->outreq->dma = bh->dma;
                bh->inreq->context = bh->outreq->context = bh;
                bh->inreq->complete = bulk_in_complete;
                bh->outreq->complete = bulk_out_complete;
index 10b2b33b8698e54c48b3f2ce701cfa3c09c0406a..d57bcfbc08a530b31cdb5e6c75871057c6a794ae 100644 (file)
@@ -1277,31 +1277,32 @@ static void setup_received_irq(struct fsl_udc *udc,
 
        udc_reset_ep_queue(udc, 0);
 
+       /* We process some stardard setup requests here */
        switch (setup->bRequest) {
-               /* Request that need Data+Status phase from udc */
        case USB_REQ_GET_STATUS:
-               if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_STANDARD))
+               /* Data+Status phase from udc */
+               if ((setup->bRequestType & (USB_DIR_IN | USB_TYPE_MASK))
                                        != (USB_DIR_IN | USB_TYPE_STANDARD))
                        break;
                ch9getstatus(udc, setup->bRequestType, wValue, wIndex, wLength);
-               break;
+               return;
 
-               /* Requests that need Status phase from udc */
        case USB_REQ_SET_ADDRESS:
+               /* Status phase from udc */
                if (setup->bRequestType != (USB_DIR_OUT | USB_TYPE_STANDARD
                                                | USB_RECIP_DEVICE))
                        break;
                ch9setaddress(udc, wValue, wIndex, wLength);
-               break;
+               return;
 
-               /* Handled by udc, no data, status by udc */
        case USB_REQ_CLEAR_FEATURE:
        case USB_REQ_SET_FEATURE:
-       {       /* status transaction */
+               /* Status phase from udc */
+       {
                int rc = -EOPNOTSUPP;
 
-               if ((setup->bRequestType & USB_RECIP_MASK)
-                               == USB_RECIP_ENDPOINT) {
+               if ((setup->bRequestType & (USB_RECIP_MASK | USB_TYPE_MASK))
+                               == (USB_RECIP_ENDPOINT | USB_TYPE_STANDARD)) {
                        int pipe = get_pipe_by_windex(wIndex);
                        struct fsl_ep *ep;
 
@@ -1315,8 +1316,9 @@ static void setup_received_irq(struct fsl_udc *udc,
                                                ? 1 : 0);
                        spin_lock(&udc->lock);
 
-               } else if ((setup->bRequestType & USB_RECIP_MASK)
-                               == USB_RECIP_DEVICE) {
+               } else if ((setup->bRequestType & (USB_RECIP_MASK
+                               | USB_TYPE_MASK)) == (USB_RECIP_DEVICE
+                               | USB_TYPE_STANDARD)) {
                        /* Note: The driver has not include OTG support yet.
                         * This will be set when OTG support is added */
                        if (!udc->gadget.is_otg)
@@ -1329,39 +1331,42 @@ static void setup_received_irq(struct fsl_udc *udc,
                                        USB_DEVICE_A_ALT_HNP_SUPPORT)
                                udc->gadget.a_alt_hnp_support = 1;
                        rc = 0;
-               }
+               } else
+                       break;
+
                if (rc == 0) {
                        if (ep0_prime_status(udc, EP_DIR_IN))
                                ep0stall(udc);
                }
-               break;
+               return;
        }
-               /* Requests handled by gadget */
-       default:
-               if (wLength) {
-                       /* Data phase from gadget, status phase from udc */
-                       udc->ep0_dir = (setup->bRequestType & USB_DIR_IN)
-                                       ?  USB_DIR_IN : USB_DIR_OUT;
-                       spin_unlock(&udc->lock);
-                       if (udc->driver->setup(&udc->gadget,
-                                       &udc->local_setup_buff) < 0)
-                               ep0stall(udc);
-                       spin_lock(&udc->lock);
-                       udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
-                                       ?  DATA_STATE_XMIT : DATA_STATE_RECV;
 
-               } else {
-                       /* No data phase, IN status from gadget */
-                       udc->ep0_dir = USB_DIR_IN;
-                       spin_unlock(&udc->lock);
-                       if (udc->driver->setup(&udc->gadget,
-                                       &udc->local_setup_buff) < 0)
-                               ep0stall(udc);
-                       spin_lock(&udc->lock);
-                       udc->ep0_state = WAIT_FOR_OUT_STATUS;
-               }
+       default:
                break;
        }
+
+       /* Requests handled by gadget */
+       if (wLength) {
+               /* Data phase from gadget, status phase from udc */
+               udc->ep0_dir = (setup->bRequestType & USB_DIR_IN)
+                               ?  USB_DIR_IN : USB_DIR_OUT;
+               spin_unlock(&udc->lock);
+               if (udc->driver->setup(&udc->gadget,
+                               &udc->local_setup_buff) < 0)
+                       ep0stall(udc);
+               spin_lock(&udc->lock);
+               udc->ep0_state = (setup->bRequestType & USB_DIR_IN)
+                               ?  DATA_STATE_XMIT : DATA_STATE_RECV;
+       } else {
+               /* No data phase, IN status from gadget */
+               udc->ep0_dir = USB_DIR_IN;
+               spin_unlock(&udc->lock);
+               if (udc->driver->setup(&udc->gadget,
+                               &udc->local_setup_buff) < 0)
+                       ep0stall(udc);
+               spin_lock(&udc->lock);
+               udc->ep0_state = WAIT_FOR_OUT_STATUS;
+       }
 }
 
 /* Process request for Data or Status phase of ep0
index 72b4ebbf132d1ed636b2ebc60953f97b23fe99cc..1407ad1c81288bdfa1343e871bcd5be36d4622bf 100644 (file)
@@ -967,7 +967,7 @@ static int pxa2xx_udc_pullup(struct usb_gadget *_gadget, int is_active)
        udc = container_of(_gadget, struct pxa2xx_udc, gadget);
 
        /* not all boards support pullup control */
-       if (!udc->mach->udc_command)
+       if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
                return -EOPNOTSUPP;
 
        is_active = (is_active != 0);
@@ -2309,7 +2309,7 @@ static int pxa2xx_udc_suspend(struct platform_device *dev, pm_message_t state)
 {
        struct pxa2xx_udc       *udc = platform_get_drvdata(dev);
 
-       if (!udc->mach->udc_command)
+       if (!udc->mach->gpio_pullup && !udc->mach->udc_command)
                WARN("USB host won't detect disconnect!\n");
        pullup(udc, 0);
 
index 2f529828c74d23232a0d060b8d00108e6834ccea..565d6ef4c4cf5befc157aba3639c83cafa4adabe 100644 (file)
@@ -237,7 +237,7 @@ config USB_SL811_CS
          module will be called "sl811_cs".
 
 config USB_R8A66597_HCD
-       tristate "R8A66597 HCD suppoort"
+       tristate "R8A66597 HCD support"
        depends on USB
        help
          The R8A66597 is a USB 2.0 host and peripheral controller.
index 5d1b12aad7766acc39d338c9200dfc4ca6b86601..b1d19268cb23df9688be260794ef475bddbe0340 100644 (file)
@@ -1,8 +1,6 @@
 /*
  * EHCI HCD (Host Controller Driver) for USB.
  *
- * (C) Copyright 2000-2004 David Brownell <dbrownell@users.sourceforge.net>
- *
  * Bus Glue for AMD Alchemy Au1xxx
  *
  * Based on "ohci-au1xxx.c" by Matt Porter <mporter@kernel.crashing.org>
@@ -196,6 +194,9 @@ static const struct hc_driver ehci_au1xxx_hc_driver = {
 
        /*
         * basic lifecycle operations
+        *
+        * FIXME -- ehci_init() doesn't do enough here.
+        * See ehci-ppc-soc for a complete implementation.
         */
        .reset = ehci_init,
        .start = ehci_run,
index c2cedb09ed8bf02699aff32c0010e8d81ab0d841..4f99b0eb27bc2bdaea9729897b46c44dae4c763b 100644 (file)
@@ -6,7 +6,7 @@
  * Bus Glue for PPC On-Chip EHCI driver
  * Tested on AMCC 440EPx
  *
- * Based on "ehci-au12xx.c" by David Brownell <dbrownell@users.sourceforge.net>
+ * Based on "ehci-au1xxx.c" by K.Boge <karsten.boge@amd.com>
  *
  * This file is licenced under the GPL.
  */
 
 extern int usb_disabled(void);
 
+/* called during probe() after chip reset completes */
+static int ehci_ppc_soc_setup(struct usb_hcd *hcd)
+{
+       struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+       int             retval;
+
+       retval = ehci_halt(ehci);
+       if (retval)
+               return retval;
+
+       retval = ehci_init(hcd);
+       if (retval)
+               return retval;
+
+       ehci->sbrn = 0x20;
+       return ehci_reset(ehci);
+}
+
 /**
  * usb_ehci_ppc_soc_probe - initialize PPC-SoC-based HCDs
  * Context: !in_interrupt()
@@ -120,7 +138,7 @@ static const struct hc_driver ehci_ppc_soc_hc_driver = {
        /*
         * basic lifecycle operations
         */
-       .reset = ehci_init,
+       .reset = ehci_ppc_soc_setup,
        .start = ehci_run,
        .stop = ehci_stop,
        .shutdown = ehci_shutdown,
index 6f9e43e9a6cab69072fe420a460d74074f77e6b7..f61c6cdd06f2443ecbc0ed333df7a92cee618494 100644 (file)
@@ -74,7 +74,7 @@ urb_print (struct urb * urb, char * str, int small)
 
 #define ohci_dbg_sw(ohci, next, size, format, arg...) \
        do { \
-       if (next) { \
+       if (next != NULL) { \
                unsigned s_len; \
                s_len = scnprintf (*next, *size, format, ## arg ); \
                *size -= s_len; *next += s_len; \
index d60f1985320cfc630e107e81bd3c406a4229a083..40a1de4c256efafabc5ca528d97b6f6361413def 100644 (file)
@@ -2208,8 +2208,6 @@ static int __init r8a66597_probe(struct platform_device *pdev)
 clean_up:
        if (reg)
                iounmap(reg);
-       if (res)
-               release_mem_region(res->start, 1);
 
        return ret;
 }
index 7f765ec038cd4eb3846276c3c1f88879851260c0..b88eb3c62c0254b2358b693926b836bffa9d1df5 100644 (file)
@@ -1520,12 +1520,15 @@ static void u132_hcd_endp_work_scheduler(struct work_struct *work)
                 }
         }
 }
+#ifdef CONFIG_PM
 
 static void port_power(struct u132 *u132, int pn, int is_on)
 {
         u132->port[pn].power = is_on;
 }
 
+#endif
+
 static void u132_power(struct u132 *u132, int is_on)
 {
         struct usb_hcd *hcd = u132_to_hcd(u132)
index cff6fd190a28273869c4f9b1203e75ccee1ccc85..77bb893bf2e922c51bb51ef4e2ac69f6d2cd2a86 100644 (file)
@@ -18,7 +18,6 @@
 
 static struct usb_device_id id_table [] = {
        { USB_DEVICE(0x0c88, 0x17da) }, /* Kyocera Wireless KPC650/Passport */
-       { USB_DEVICE(0x413c, 0x8115) }, /* Dell Wireless HSDPA 5500 */
        { },
 };
 MODULE_DEVICE_TABLE(usb, id_table);
index e67ce25f7512627dad57bf4930d2ca26c6bc413a..86724e885704b01dcfb77d9291d3958690f32932 100644 (file)
@@ -383,6 +383,10 @@ static void belkin_sa_set_termios (struct usb_serial_port *port, struct ktermios
        }
 
        baud = tty_get_baud_rate(port->tty);
+       if (baud == 0) {
+               dbg("%s - tty_get_baud_rate says 0 baud", __FUNCTION__);
+               return;
+       }
        urb_value = BELKIN_SA_BAUD(baud);
        /* Clip to maximum speed */
        if (urb_value == 0)
index 7b1673a440775aaef3673915432cbed74c508051..1370c423d7c28bbfb967d1d42262a2628d33e616 100644 (file)
@@ -538,6 +538,8 @@ static struct usb_device_id id_table_combined [] = {
        { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_VCP_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_TERATRONIK_D2XX_PID) },
        { USB_DEVICE(EVOLUTION_VID, EVOLUTION_ER1_PID) },
+       { USB_DEVICE(EVOLUTION_VID, EVO_HYBRID_PID) },
+       { USB_DEVICE(EVOLUTION_VID, EVO_RCM4_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ARTEMIS_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16_PID) },
        { USB_DEVICE(FTDI_VID, FTDI_ATIK_ATK16C_PID) },
index d9e49716db13584eff75ddbe8307929738b0b957..c70e1de6389ee046d5ee1170c2445fabf9721436 100644 (file)
  */
 #define EVOLUTION_VID          0xDEEE  /* Vendor ID */
 #define EVOLUTION_ER1_PID      0x0300  /* ER1 Control Module */
+#define EVO_8U232AM_PID        0x02FF  /* Evolution robotics RCM2 (FT232AM)*/
+#define EVO_HYBRID_PID         0x0302  /* Evolution robotics RCM4 PID (FT232BM)*/
+#define EVO_RCM4_PID           0x0303  /* Evolution robotics RCM4 PID */
 
 /* Pyramid Computer GmbH */
 #define FTDI_PYRAMID_PID       0xE6C8  /* Pyramid Appliance Display */
index 04bd3b7a298516a4f4409033df182ddfaf54ea80..f1c90cfe72515365236c9ddf61e1c41ee90fe82a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * Garmin GPS driver
  *
- * Copyright (C) 2006 Hermann Kneissel herkne@users.sourceforge.net
+ * Copyright (C) 2006,2007 Hermann Kneissel herkne@users.sourceforge.net
  *
  * The latest version of the driver can be found at
  * http://sourceforge.net/projects/garmin-gps/
@@ -34,6 +34,7 @@
 #include <linux/module.h>
 #include <linux/spinlock.h>
 #include <asm/uaccess.h>
+#include <asm/atomic.h>
 #include <linux/usb.h>
 #include <linux/usb/serial.h>
 
@@ -52,7 +53,7 @@ static int debug = 0;
  */
 
 #define VERSION_MAJOR  0
-#define VERSION_MINOR  28
+#define VERSION_MINOR  31
 
 #define _STR(s) #s
 #define _DRIVER_VERSION(a,b) "v" _STR(a) "." _STR(b)
@@ -141,6 +142,8 @@ struct garmin_data {
        __u8   inbuffer [GPS_IN_BUFSIZ];  /* tty -> usb */
        __u8   outbuffer[GPS_OUT_BUFSIZ]; /* usb -> tty */
        __u8   privpkt[4*6];
+       atomic_t req_count;
+       atomic_t resp_count;
        spinlock_t lock;
        struct list_head pktlist;
 };
@@ -171,8 +174,6 @@ struct garmin_data {
 #define CLEAR_HALT_REQUIRED       0x0001
 
 #define FLAGS_QUEUING             0x0100
-#define FLAGS_APP_RESP_SEEN       0x0200
-#define FLAGS_APP_REQ_SEEN        0x0400
 #define FLAGS_DROP_DATA           0x0800
 
 #define FLAGS_GSP_SKIP            0x1000
@@ -186,7 +187,8 @@ struct garmin_data {
 /* function prototypes */
 static void gsp_next_packet(struct garmin_data * garmin_data_p);
 static int  garmin_write_bulk(struct usb_serial_port *port,
-                            const unsigned char *buf, int count);
+                            const unsigned char *buf, int count,
+                            int dismiss_ack);
 
 /* some special packets to be send or received */
 static unsigned char const GARMIN_START_SESSION_REQ[]
@@ -233,9 +235,7 @@ static struct usb_driver garmin_driver = {
 
 static inline int noResponseFromAppLayer(struct garmin_data * garmin_data_p)
 {
-       return ((garmin_data_p->flags
-                               & (FLAGS_APP_REQ_SEEN|FLAGS_APP_RESP_SEEN))
-               == FLAGS_APP_REQ_SEEN);
+       return atomic_read(&garmin_data_p->req_count) == atomic_read(&garmin_data_p->resp_count);
 }
 
 
@@ -463,7 +463,7 @@ static int gsp_rec_packet(struct garmin_data * garmin_data_p, int count)
        usbdata[2] = __cpu_to_le32(size);
 
        garmin_write_bulk (garmin_data_p->port, garmin_data_p->inbuffer,
-                          GARMIN_PKTHDR_LENGTH+size);
+                          GARMIN_PKTHDR_LENGTH+size, 0);
 
        /* if this was an abort-transfer command, flush all
           queued data. */
@@ -818,7 +818,7 @@ static int nat_receive(struct garmin_data * garmin_data_p,
                        if (garmin_data_p->insize >= len) {
                                garmin_write_bulk (garmin_data_p->port,
                                                   garmin_data_p->inbuffer,
-                                                  len);
+                                                  len, 0);
                                garmin_data_p->insize = 0;
 
                                /* if this was an abort-transfer command,
@@ -893,10 +893,11 @@ static int garmin_clear(struct garmin_data * garmin_data_p)
 
        struct usb_serial_port *port = garmin_data_p->port;
 
-       if (port != NULL && garmin_data_p->flags & FLAGS_APP_RESP_SEEN) {
+       if (port != NULL && atomic_read(&garmin_data_p->resp_count)) {
                /* send a terminate command */
                status = garmin_write_bulk(port, GARMIN_STOP_TRANSFER_REQ,
-                                          sizeof(GARMIN_STOP_TRANSFER_REQ));
+                                          sizeof(GARMIN_STOP_TRANSFER_REQ),
+                                          1);
        }
 
        /* flush all queued data */
@@ -939,7 +940,8 @@ static int garmin_init_session(struct usb_serial_port *port)
                dbg("%s - starting session ...", __FUNCTION__);
                garmin_data_p->state = STATE_ACTIVE;
                status = garmin_write_bulk(port, GARMIN_START_SESSION_REQ,
-                                          sizeof(GARMIN_START_SESSION_REQ));
+                                          sizeof(GARMIN_START_SESSION_REQ),
+                                          0);
 
                if (status >= 0) {
 
@@ -950,7 +952,8 @@ static int garmin_init_session(struct usb_serial_port *port)
                        /* not needed, but the win32 driver does it too ... */
                        status = garmin_write_bulk(port,
                                                   GARMIN_START_SESSION_REQ2,
-                                                  sizeof(GARMIN_START_SESSION_REQ2));
+                                                  sizeof(GARMIN_START_SESSION_REQ2),
+                                                  0);
                        if (status >= 0) {
                                status = 0;
                                spin_lock_irqsave(&garmin_data_p->lock, flags);
@@ -987,6 +990,8 @@ static int garmin_open (struct usb_serial_port *port, struct file *filp)
        garmin_data_p->mode  = initial_mode;
        garmin_data_p->count = 0;
        garmin_data_p->flags = 0;
+       atomic_set(&garmin_data_p->req_count, 0);
+       atomic_set(&garmin_data_p->resp_count, 0);
        spin_unlock_irqrestore(&garmin_data_p->lock, flags);
 
        /* shutdown any bulk reads that might be going on */
@@ -1035,28 +1040,39 @@ static void garmin_write_bulk_callback (struct urb *urb)
 {
        unsigned long flags;
        struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
-       struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
        int status = urb->status;
 
-       /* free up the transfer buffer, as usb_free_urb() does not do this */
-       kfree (urb->transfer_buffer);
+       if (port) {
+               struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
 
-       dbg("%s - port %d", __FUNCTION__, port->number);
+               dbg("%s - port %d", __FUNCTION__, port->number);
 
-       if (status) {
-               dbg("%s - nonzero write bulk status received: %d",
-                       __FUNCTION__, status);
-               spin_lock_irqsave(&garmin_data_p->lock, flags);
-               garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
-               spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+               if (GARMIN_LAYERID_APPL == getLayerId(urb->transfer_buffer)
+                   && (garmin_data_p->mode == MODE_GARMIN_SERIAL))  {
+                       gsp_send_ack(garmin_data_p, ((__u8 *)urb->transfer_buffer)[4]);
+               }
+
+               if (status) {
+                       dbg("%s - nonzero write bulk status received: %d",
+                           __FUNCTION__, urb->status);
+                       spin_lock_irqsave(&garmin_data_p->lock, flags);
+                       garmin_data_p->flags |= CLEAR_HALT_REQUIRED;
+                       spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+               }
+
+               usb_serial_port_softint(port);
        }
 
-       usb_serial_port_softint(port);
+       /* Ignore errors that resulted from garmin_write_bulk with dismiss_ack=1 */
+
+       /* free up the transfer buffer, as usb_free_urb() does not do this */
+       kfree (urb->transfer_buffer);
 }
 
 
 static int garmin_write_bulk (struct usb_serial_port *port,
-                             const unsigned char *buf, int count)
+                             const unsigned char *buf, int count,
+                             int dismiss_ack)
 {
        unsigned long flags;
        struct usb_serial *serial = port->serial;
@@ -1093,13 +1109,12 @@ static int garmin_write_bulk (struct usb_serial_port *port,
                                usb_sndbulkpipe (serial->dev,
                                port->bulk_out_endpointAddress),
                                buffer, count,
-                               garmin_write_bulk_callback, port);
+                               garmin_write_bulk_callback,
+                               dismiss_ack ? NULL : port);
        urb->transfer_flags |= URB_ZERO_PACKET;
 
        if (GARMIN_LAYERID_APPL == getLayerId(buffer)) {
-               spin_lock_irqsave(&garmin_data_p->lock, flags);
-               garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
-               spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+               atomic_inc(&garmin_data_p->req_count);
                if (garmin_data_p->mode == MODE_GARMIN_SERIAL)  {
                        pkt_clear(garmin_data_p);
                        garmin_data_p->state = STATE_GSP_WAIT_DATA;
@@ -1114,13 +1129,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
                        "failed with status = %d\n",
                                __FUNCTION__, status);
                count = status;
-       } else {
-
-               if (GARMIN_LAYERID_APPL == getLayerId(buffer)
-                   && (garmin_data_p->mode == MODE_GARMIN_SERIAL))  {
-
-                       gsp_send_ack(garmin_data_p, buffer[4]);
-               }
        }
 
        /* we are done with this urb, so let the host driver
@@ -1135,7 +1143,6 @@ static int garmin_write_bulk (struct usb_serial_port *port,
 static int garmin_write (struct usb_serial_port *port,
                         const unsigned char *buf, int count)
 {
-       unsigned long flags;
        int pktid, pktsiz, len;
        struct garmin_data * garmin_data_p = usb_get_serial_port_data(port);
        __le32 *privpkt = (__le32 *)garmin_data_p->privpkt;
@@ -1186,9 +1193,7 @@ static int garmin_write (struct usb_serial_port *port,
                                break;
 
                        case PRIV_PKTID_RESET_REQ:
-                               spin_lock_irqsave(&garmin_data_p->lock, flags);
-                               garmin_data_p->flags |= FLAGS_APP_REQ_SEEN;
-                               spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+                               atomic_inc(&garmin_data_p->req_count);
                                break;
 
                        case PRIV_PKTID_SET_DEF_MODE:
@@ -1241,8 +1246,6 @@ static int garmin_chars_in_buffer (struct usb_serial_port *port)
 static void garmin_read_process(struct garmin_data * garmin_data_p,
                                 unsigned char *data, unsigned data_length)
 {
-       unsigned long flags;
-
        if (garmin_data_p->flags & FLAGS_DROP_DATA) {
                /* abort-transfer cmd is actice */
                dbg("%s - pkt dropped", __FUNCTION__);
@@ -1254,9 +1257,7 @@ static void garmin_read_process(struct garmin_data * garmin_data_p,
                   the device */
                if (0 == memcmp(data, GARMIN_APP_LAYER_REPLY,
                                sizeof(GARMIN_APP_LAYER_REPLY))) {
-                       spin_lock_irqsave(&garmin_data_p->lock, flags);
-                       garmin_data_p->flags |= FLAGS_APP_RESP_SEEN;
-                       spin_unlock_irqrestore(&garmin_data_p->lock, flags);
+                       atomic_inc(&garmin_data_p->resp_count);
                }
 
                /* if throttling is active or postprecessing is required
index 0455c1552ae90e9e00dde3f8bc52bd63625c66f4..6a3a704b58498bff271b34351dd382049f7cbcd2 100644 (file)
@@ -545,6 +545,7 @@ static struct usb_device_id ipaq_id_table [] = {
        { USB_DEVICE(0x413C, 0x4009) }, /* Dell Axim USB Sync */
        { USB_DEVICE(0x4505, 0x0010) }, /* Smartphone */
        { USB_DEVICE(0x5E04, 0xCE00) }, /* SAGEM Wireless Assistant */
+       { USB_DEVICE(0x0BB4, 0x00CF) }, /* HTC smartphone modems */
        { }                             /* Terminating entry */
 };
 
index 84c12b5f12715675148551bbee25ca5be5ae2b19..4cb3c165742bbb59d2cc2be66bb6da7488700196 100644 (file)
@@ -110,6 +110,7 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define HUAWEI_PRODUCT_E220                    0x1003
 
 #define NOVATELWIRELESS_VENDOR_ID              0x1410
+#define DELL_VENDOR_ID                         0x413C
 
 #define ANYDATA_VENDOR_ID                      0x16d5
 #define ANYDATA_PRODUCT_ADU_E100A              0x6501
@@ -119,8 +120,6 @@ static int  option_send_setup(struct usb_serial_port *port);
 #define BANDRICH_PRODUCT_C100_1                        0x1002
 #define BANDRICH_PRODUCT_C100_2                        0x1003
 
-#define DELL_VENDOR_ID                         0x413C
-
 static struct usb_device_id option_ids[] = {
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
        { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
@@ -171,11 +170,16 @@ static struct usb_device_id option_ids[] = {
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2110) }, /* Novatel Merlin ES620 / Merlin ES720 / Ovation U720 */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2130) }, /* Novatel Merlin ES620 SM Bus */
        { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, 0x2410) }, /* Novatel EU740 */
+       { USB_DEVICE(DELL_VENDOR_ID, 0x8114) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite EV620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, 0x8115) }, /* Dell Wireless 5500 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+       { USB_DEVICE(DELL_VENDOR_ID, 0x8116) }, /* Dell Wireless 5505 Mobile Broadband HSDPA Mini-Card == Novatel Expedite EU740 HSDPA/3G */
+       { USB_DEVICE(DELL_VENDOR_ID, 0x8117) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO ExpressCard == Novatel Merlin XV620 CDMA/EV-DO */
+       { USB_DEVICE(DELL_VENDOR_ID, 0x8118) }, /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard == Novatel Merlin XU870 HSDPA/3G */
+       { USB_DEVICE(DELL_VENDOR_ID, 0x8128) }, /* Dell Wireless 5700 Mobile Broadband CDMA/EVDO Mini-Card == Novatel Expedite E720 CDMA/EV-DO */
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) },
        { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_1) },
        { USB_DEVICE(BANDRICH_VENDOR_ID, BANDRICH_PRODUCT_C100_2) },
-       { USB_DEVICE(DELL_VENDOR_ID, 0x8118) },         /* Dell Wireless 5510 Mobile Broadband HSDPA ExpressCard */
        { } /* Terminating entry */
 };
 MODULE_DEVICE_TABLE(usb, option_ids);
index d7db71eca5209bf386a8edc2286f232c0c8ed886..833ada47fc5429938af9045baa7e9fb68dda4b1a 100644 (file)
@@ -818,19 +818,17 @@ static int oti6858_ioctl(struct usb_serial_port *port, struct file *file,
 
        switch (cmd) {
                case TCGETS:
-                       if (copy_to_user(user_arg, port->tty->termios,
-                                               sizeof(struct ktermios))) {
+                       if (kernel_termios_to_user_termios((struct ktermios __user *)arg,
+                                                          port->tty->termios))
                                return -EFAULT;
-                       }
                        return 0;
 
                case TCSETS:
                case TCSETSW:   /* FIXME: this is not the same! */
                case TCSETSF:   /* FIXME: this is not the same! */
-                       if (copy_from_user(port->tty->termios, user_arg,
-                                               sizeof(struct ktermios))) {
+                       if (user_termios_to_kernel_termios(port->tty->termios,
+                                               (struct ktermios __user *)arg))
                                return -EFAULT;
-                       }
                        oti6858_set_termios(port, NULL);
                        return 0;
 
index 86899d55d8d818fcc0b81e7cd0a67c2d7ec19c0b..51669b7622bb8fdeaf80bdfd29017603d58ec5cb 100644 (file)
 #include <linux/usb/serial.h>
 
 
-#ifndef CONFIG_USB_SAFE_PADDED
-#define CONFIG_USB_SAFE_PADDED 0
+#ifndef CONFIG_USB_SERIAL_SAFE_PADDED
+#define CONFIG_USB_SERIAL_SAFE_PADDED 0
 #endif
 
 static int debug;
 static int safe = 1;
-static int padded = CONFIG_USB_SAFE_PADDED;
+static int padded = CONFIG_USB_SERIAL_SAFE_PADDED;
 
 #define DRIVER_VERSION "v0.0b"
 #define DRIVER_AUTHOR "sl@lineo.com, tbr@lineo.com"
index 7d84a7647e81efeec0c025df2ecf783ade3b16aa..30e08c0bcdc2d3c26311f17f2088e45ed35b10a6 100644 (file)
@@ -104,6 +104,8 @@ static struct usb_device_id id_table [] = {
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SONY_VENDOR_ID, SONY_CLIE_TJ25_ID),
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
+       { USB_DEVICE(ACER_VENDOR_ID, ACER_S10_ID),
+               .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SCH_I330_ID), 
                .driver_info = (kernel_ulong_t)&palm_os_4_probe },
        { USB_DEVICE(SAMSUNG_VENDOR_ID, SAMSUNG_SPH_I500_ID), 
index 4ce6f62a6f398f69caaa60ab7ab3c4a50506081f..57229cf66477b10f444f4326da1cef4c4409d620 100644 (file)
@@ -48,6 +48,9 @@
 #define SONY_CLIE_UX50_ID              0x0144
 #define SONY_CLIE_TJ25_ID              0x0169
 
+#define ACER_VENDOR_ID                 0x0502
+#define ACER_S10_ID                    0x0001
+
 #define SAMSUNG_VENDOR_ID              0x04E8
 #define SAMSUNG_SCH_I330_ID            0x8001
 #define SAMSUNG_SPH_I500_ID            0x6601
index d8d008d4294643419b52c798eea81fd941fdc1f9..2d92ce31018fff95e5769f50d12598cfb9e8aac8 100644 (file)
@@ -342,7 +342,7 @@ UNUSUAL_DEV(  0x04b0, 0x040d, 0x0100, 0x0100,
                US_FL_FIX_CAPACITY),
 
 /* Reported by Emil Larsson <emil@swip.net> */
-UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0100,
+UNUSUAL_DEV(  0x04b0, 0x0411, 0x0100, 0x0101,
                "NIKON",
                "NIKON DSC D80",
                US_SC_DEVICE, US_PR_DEVICE, NULL,
index 28842d208bb031738c8b68d79a6ac8ec91196fe7..25e557d4fe6b054f23716d7ef06b84b8e9227bb9 100644 (file)
@@ -112,13 +112,6 @@ module_param(delay_use, uint, S_IRUGO | S_IWUSR);
 MODULE_PARM_DESC(delay_use, "seconds to delay before using a new device");
 
 
-/* These are used to make sure the module doesn't unload before all the
- * threads have exited.
- */
-static atomic_t total_threads = ATOMIC_INIT(0);
-static DECLARE_COMPLETION(threads_gone);
-
-
 /*
  * The entries in this table correspond, line for line,
  * with the entries of us_unusual_dev_list[].
@@ -879,9 +872,6 @@ static void quiesce_and_remove_host(struct us_data *us)
        usb_stor_stop_transport(us);
        wake_up(&us->delay_wait);
 
-       /* It doesn't matter if the SCSI-scanning thread is still running.
-        * The thread will exit when it sees the DISCONNECTING flag. */
-
        /* queuecommand won't accept any new commands and the control
         * thread won't execute a previously-queued command.  If there
         * is such a command pending, complete it with an error. */
@@ -891,12 +881,16 @@ static void quiesce_and_remove_host(struct us_data *us)
                scsi_lock(host);
                us->srb->scsi_done(us->srb);
                us->srb = NULL;
+               complete(&us->notify);          /* in case of an abort */
                scsi_unlock(host);
        }
        mutex_unlock(&us->dev_mutex);
 
        /* Now we own no commands so it's safe to remove the SCSI host */
        scsi_remove_host(host);
+
+       /* Wait for the SCSI-scanning thread to stop */
+       wait_for_completion(&us->scanning_done);
 }
 
 /* Second stage of disconnect processing: deallocate all resources */
@@ -947,9 +941,8 @@ retry:
                /* Should we unbind if no devices were detected? */
        }
 
-       scsi_host_put(us_to_host(us));
        usb_autopm_put_interface(us->pusb_intf);
-       complete_and_exit(&threads_gone, 0);
+       complete_and_exit(&us->scanning_done, 0);
 }
 
 
@@ -984,6 +977,7 @@ static int storage_probe(struct usb_interface *intf,
        init_MUTEX_LOCKED(&(us->sema));
        init_completion(&(us->notify));
        init_waitqueue_head(&us->delay_wait);
+       init_completion(&us->scanning_done);
 
        /* Associate the us_data structure with the USB device */
        result = associate_dev(us, intf);
@@ -1033,11 +1027,6 @@ static int storage_probe(struct usb_interface *intf,
                goto BadDevice;
        }
 
-       /* Take a reference to the host for the scanning thread and
-        * count it among all the threads we have launched.  Then
-        * start it up. */
-       scsi_host_get(us_to_host(us));
-       atomic_inc(&total_threads);
        usb_autopm_get_interface(intf); /* dropped in the scanning thread */
        wake_up_process(th);
 
@@ -1104,16 +1093,6 @@ static void __exit usb_stor_exit(void)
        US_DEBUGP("-- calling usb_deregister()\n");
        usb_deregister(&usb_storage_driver) ;
 
-       /* Don't return until all of our control and scanning threads
-        * have exited.  Since each thread signals threads_gone as its
-        * last act, we have to call wait_for_completion the right number
-        * of times.
-        */
-       while (atomic_read(&total_threads) > 0) {
-               wait_for_completion(&threads_gone);
-               atomic_dec(&total_threads);
-       }
-
        usb_usual_clear_present(USB_US_TYPE_STOR);
 }
 
index 6445665b1577c258d3a722e19e9a56fac549267a..8d87503e256072efa90c16672b22db4a00fded87 100644 (file)
@@ -150,6 +150,7 @@ struct us_data {
        struct semaphore        sema;            /* to sleep thread on      */
        struct completion       notify;          /* thread begin/end        */
        wait_queue_head_t       delay_wait;      /* wait during scan, reset */
+       struct completion       scanning_done;   /* wait for scan thread    */
 
        /* subdriver information */
        void                    *extra;          /* Any extra data          */