diff options
Diffstat (limited to 'drivers/usb')
-rw-r--r-- | drivers/usb/core/devio.c | 16 | ||||
-rw-r--r-- | drivers/usb/core/hcd-pci.c | 9 | ||||
-rw-r--r-- | drivers/usb/core/inode.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/message.c | 2 | ||||
-rw-r--r-- | drivers/usb/core/usb.c | 6 | ||||
-rw-r--r-- | drivers/usb/core/usb.h | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/pxa2xx_udc.c | 4 | ||||
-rw-r--r-- | drivers/usb/gadget/pxa2xx_udc.h | 8 | ||||
-rw-r--r-- | drivers/usb/host/isp116x-hcd.c | 3 | ||||
-rw-r--r-- | drivers/usb/host/ohci-lh7a404.c | 2 | ||||
-rw-r--r-- | drivers/usb/host/ohci-omap.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/ohci-s3c2410.c | 1 | ||||
-rw-r--r-- | drivers/usb/host/sl811-hcd.c | 16 | ||||
-rw-r--r-- | drivers/usb/input/hid-core.c | 3 | ||||
-rw-r--r-- | drivers/usb/media/vicam.c | 4 | ||||
-rw-r--r-- | drivers/usb/net/pegasus.c | 29 | ||||
-rw-r--r-- | drivers/usb/serial/airprime.c | 3 | ||||
-rw-r--r-- | drivers/usb/serial/ftdi_sio.c | 8 | ||||
-rw-r--r-- | drivers/usb/serial/generic.c | 2 | ||||
-rw-r--r-- | drivers/usb/serial/option.c | 11 |
20 files changed, 81 insertions, 52 deletions
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index b4265aa7d45e..487ff672b104 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -30,6 +30,8 @@ * Revision history * 22.12.1999 0.1 Initial release (split from proc_usb.c) * 04.01.2000 0.2 Turned into its own filesystem + * 30.09.2005 0.3 Fix user-triggerable oops in async URB delivery + * (CAN-2005-3055) */ /*****************************************************************************/ @@ -58,7 +60,8 @@ static struct class *usb_device_class; struct async { struct list_head asynclist; struct dev_state *ps; - struct task_struct *task; + pid_t pid; + uid_t uid, euid; unsigned int signr; unsigned int ifnum; void __user *userbuffer; @@ -290,7 +293,8 @@ static void async_completed(struct urb *urb, struct pt_regs *regs) sinfo.si_errno = as->urb->status; sinfo.si_code = SI_ASYNCIO; sinfo.si_addr = as->userurb; - send_sig_info(as->signr, &sinfo, as->task); + kill_proc_info_as_uid(as->signr, &sinfo, as->pid, as->uid, + as->euid); } wake_up(&ps->wait); } @@ -526,7 +530,9 @@ static int usbdev_open(struct inode *inode, struct file *file) INIT_LIST_HEAD(&ps->async_completed); init_waitqueue_head(&ps->wait); ps->discsignr = 0; - ps->disctask = current; + ps->disc_pid = current->pid; + ps->disc_uid = current->uid; + ps->disc_euid = current->euid; ps->disccontext = NULL; ps->ifclaimed = 0; wmb(); @@ -988,7 +994,9 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, as->userbuffer = NULL; as->signr = uurb->signr; as->ifnum = ifnum; - as->task = current; + as->pid = current->pid; + as->uid = current->uid; + as->euid = current->euid; if (!(uurb->endpoint & USB_DIR_IN)) { if (copy_from_user(as->urb->transfer_buffer, uurb->buffer, as->urb->transfer_buffer_length)) { free_async(as); diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c index cbb451d227d2..6385d1a99b60 100644 --- a/drivers/usb/core/hcd-pci.c +++ b/drivers/usb/core/hcd-pci.c @@ -242,7 +242,6 @@ int usb_hcd_pci_suspend (struct pci_dev *dev, pm_message_t message) case HC_STATE_SUSPENDED: /* 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); } @@ -374,14 +373,6 @@ int usb_hcd_pci_resume (struct pci_dev *dev) hcd->state = HC_STATE_RESUMING; hcd->saw_irq = 0; - retval = request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, - 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; - } retval = hcd->driver->resume (hcd); if (!HC_IS_RUNNING (hcd->state)) { diff --git a/drivers/usb/core/inode.c b/drivers/usb/core/inode.c index 640f41e47029..d07bba01995b 100644 --- a/drivers/usb/core/inode.c +++ b/drivers/usb/core/inode.c @@ -713,7 +713,7 @@ void usbfs_remove_device(struct usb_device *dev) sinfo.si_errno = EPIPE; sinfo.si_code = SI_ASYNCIO; sinfo.si_addr = ds->disccontext; - send_sig_info(ds->discsignr, &sinfo, ds->disctask); + kill_proc_info_as_uid(ds->discsignr, &sinfo, ds->disc_pid, ds->disc_uid, ds->disc_euid); } } usbfs_update_special(); diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c index c47c8052b486..f1fb67fe22a8 100644 --- a/drivers/usb/core/message.c +++ b/drivers/usb/core/message.c @@ -987,7 +987,7 @@ void usb_disable_device(struct usb_device *dev, int skip_ep0) /* remove this interface if it has been registered */ interface = dev->actconfig->interface[i]; - if (!klist_node_attached(&interface->dev.knode_bus)) + if (!device_is_registered(&interface->dev)) continue; dev_dbg (&dev->dev, "unregistering interface %s\n", interface->dev.bus_id); diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 087af73a59dd..7d131509e419 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -303,7 +303,7 @@ int usb_driver_claim_interface(struct usb_driver *driver, /* if interface was already added, bind now; else let * the future device_add() bind it, bypassing probe() */ - if (klist_node_attached(&dev->knode_bus)) + if (device_is_registered(dev)) device_bind_driver(dev); return 0; @@ -336,8 +336,8 @@ void usb_driver_release_interface(struct usb_driver *driver, if (iface->condition != USB_INTERFACE_BOUND) return; - /* release only after device_add() */ - if (klist_node_attached(&dev->knode_bus)) { + /* don't release if the interface hasn't been added yet */ + if (device_is_registered(dev)) { iface->condition = USB_INTERFACE_UNBINDING; device_release_driver(dev); } diff --git a/drivers/usb/core/usb.h b/drivers/usb/core/usb.h index 83d48c8133af..e6504f3370ad 100644 --- a/drivers/usb/core/usb.h +++ b/drivers/usb/core/usb.h @@ -52,7 +52,8 @@ struct dev_state { struct list_head async_completed; wait_queue_head_t wait; /* wake up if a request completed */ unsigned int discsignr; - struct task_struct *disctask; + pid_t disc_pid; + uid_t disc_uid, disc_euid; void __user *disccontext; unsigned long ifclaimed; }; diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c index 1507738337c4..73f8c9404156 100644 --- a/drivers/usb/gadget/pxa2xx_udc.c +++ b/drivers/usb/gadget/pxa2xx_udc.c @@ -422,7 +422,7 @@ static inline void ep0_idle (struct pxa2xx_udc *dev) } static int -write_packet(volatile u32 *uddr, struct pxa2xx_request *req, unsigned max) +write_packet(volatile unsigned long *uddr, struct pxa2xx_request *req, unsigned max) { u8 *buf; unsigned length, count; @@ -2602,7 +2602,7 @@ static int __exit pxa2xx_udc_remove(struct device *_dev) * VBUS IRQs should probably be ignored so that the PXA device just acts * "dead" to USB hosts until system resume. */ -static int pxa2xx_udc_suspend(struct device *dev, u32 state, u32 level) +static int pxa2xx_udc_suspend(struct device *dev, pm_message_t state, u32 level) { struct pxa2xx_udc *udc = dev_get_drvdata(dev); diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h index d0bc396a85d5..a58f3e6e71f1 100644 --- a/drivers/usb/gadget/pxa2xx_udc.h +++ b/drivers/usb/gadget/pxa2xx_udc.h @@ -69,11 +69,11 @@ struct pxa2xx_ep { * UDDR = UDC Endpoint Data Register (the fifo) * DRCM = DMA Request Channel Map */ - volatile u32 *reg_udccs; - volatile u32 *reg_ubcr; - volatile u32 *reg_uddr; + volatile unsigned long *reg_udccs; + volatile unsigned long *reg_ubcr; + volatile unsigned long *reg_uddr; #ifdef USE_DMA - volatile u32 *reg_drcmr; + volatile unsigned long *reg_drcmr; #define drcmr(n) .reg_drcmr = & DRCMR ## n , #else #define drcmr(n) diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c index 41bbae83fc71..e142056b0d2c 100644 --- a/drivers/usb/host/isp116x-hcd.c +++ b/drivers/usb/host/isp116x-hcd.c @@ -326,7 +326,8 @@ static void postproc_atl_queue(struct isp116x *isp116x) usb_settoggle(udev, ep->epnum, ep->nextpid == USB_PID_OUT, - PTD_GET_TOGGLE(ptd) ^ 1); + PTD_GET_TOGGLE(ptd)); + urb->actual_length += PTD_GET_COUNT(ptd); urb->status = cc_to_error[TD_DATAUNDERRUN]; spin_unlock(&urb->lock); continue; diff --git a/drivers/usb/host/ohci-lh7a404.c b/drivers/usb/host/ohci-lh7a404.c index 817620d73841..859aca7be753 100644 --- a/drivers/usb/host/ohci-lh7a404.c +++ b/drivers/usb/host/ohci-lh7a404.c @@ -17,8 +17,6 @@ */ #include <asm/hardware.h> -#include <asm/mach-types.h> -#include <asm/arch/hardware.h> extern int usb_disabled(void); diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index 5cde76faab93..d8f3ba7ad52e 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c @@ -18,7 +18,6 @@ #include <asm/io.h> #include <asm/mach-types.h> -#include <asm/arch/hardware.h> #include <asm/arch/mux.h> #include <asm/arch/irqs.h> #include <asm/arch/gpio.h> diff --git a/drivers/usb/host/ohci-s3c2410.c b/drivers/usb/host/ohci-s3c2410.c index 3d9bcf78a9a4..da7d5478f74d 100644 --- a/drivers/usb/host/ohci-s3c2410.c +++ b/drivers/usb/host/ohci-s3c2410.c @@ -20,7 +20,6 @@ */ #include <asm/hardware.h> -#include <asm/mach-types.h> #include <asm/hardware/clock.h> #include <asm/arch/usb-control.h> diff --git a/drivers/usb/host/sl811-hcd.c b/drivers/usb/host/sl811-hcd.c index d2a1fd40dfcb..d42a15d10a46 100644 --- a/drivers/usb/host/sl811-hcd.c +++ b/drivers/usb/host/sl811-hcd.c @@ -782,6 +782,9 @@ retry: /* usb 1.1 says max 90% of a frame is available for periodic transfers. * this driver doesn't promise that much since it's got to handle an * IRQ per packet; irq handling latencies also use up that time. + * + * NOTE: the periodic schedule is a sparse tree, with the load for + * each branch minimized. see fig 3.5 in the OHCI spec for example. */ #define MAX_PERIODIC_LOAD 500 /* out of 1000 usec */ @@ -843,6 +846,7 @@ static int sl811h_urb_enqueue( if (!(sl811->port1 & (1 << USB_PORT_FEAT_ENABLE)) || !HC_IS_RUNNING(hcd->state)) { retval = -ENODEV; + kfree(ep); goto fail; } @@ -911,8 +915,16 @@ static int sl811h_urb_enqueue( case PIPE_ISOCHRONOUS: case PIPE_INTERRUPT: urb->interval = ep->period; - if (ep->branch < PERIODIC_SIZE) + if (ep->branch < PERIODIC_SIZE) { + /* NOTE: the phase is correct here, but the value + * needs offsetting by the transfer queue depth. + * All current drivers ignore start_frame, so this + * is unlikely to ever matter... + */ + urb->start_frame = (sl811->frame & (PERIODIC_SIZE - 1)) + + ep->branch; break; + } retval = balance(sl811, ep->period, ep->load); if (retval < 0) @@ -1122,7 +1134,7 @@ sl811h_hub_descriptor ( desc->wHubCharacteristics = (__force __u16)cpu_to_le16(temp); /* two bitmaps: ports removable, and legacy PortPwrCtrlMask */ - desc->bitmap[0] = 1 << 1; + desc->bitmap[0] = 0 << 1; desc->bitmap[1] = ~0; } diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c index a99865c689c5..41f92b924761 100644 --- a/drivers/usb/input/hid-core.c +++ b/drivers/usb/input/hid-core.c @@ -1702,10 +1702,7 @@ static struct hid_device *usb_hid_configure(struct usb_interface *intf) if ((endpoint->bmAttributes & 3) != 3) /* Not an interrupt endpoint */ continue; - /* handle potential highspeed HID correctly */ interval = endpoint->bInterval; - if (dev->speed == USB_SPEED_HIGH) - interval = 1 << (interval - 1); /* Change the polling interval of mice. */ if (hid->collection->usage == HID_GD_MOUSE && hid_mousepoll_interval > 0) diff --git a/drivers/usb/media/vicam.c b/drivers/usb/media/vicam.c index 4a5857c53f11..0bc0b1247a6b 100644 --- a/drivers/usb/media/vicam.c +++ b/drivers/usb/media/vicam.c @@ -1148,7 +1148,7 @@ vicam_write_proc_gain(struct file *file, const char *buffer, static void vicam_create_proc_root(void) { - vicam_proc_root = create_proc_entry("video/vicam", S_IFDIR, 0); + vicam_proc_root = proc_mkdir("video/vicam", NULL); if (vicam_proc_root) vicam_proc_root->owner = THIS_MODULE; @@ -1181,7 +1181,7 @@ vicam_create_proc_entry(struct vicam_camera *cam) sprintf(name, "video%d", cam->vdev.minor); - cam->proc_dir = create_proc_entry(name, S_IFDIR, vicam_proc_root); + cam->proc_dir = proc_mkdir(name, vicam_proc_root); if ( !cam->proc_dir ) return; // FIXME: We should probably return an error here diff --git a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c index 7484d34780fc..6a4ffe6c3977 100644 --- a/drivers/usb/net/pegasus.c +++ b/drivers/usb/net/pegasus.c @@ -648,6 +648,13 @@ static void read_bulk_callback(struct urb *urb, struct pt_regs *regs) } /* + * If the packet is unreasonably long, quietly drop it rather than + * kernel panicing by calling skb_put. + */ + if (pkt_len > PEGASUS_MTU) + goto goon; + + /* * at this point we are sure pegasus->rx_skb != NULL * so we go ahead and pass up the packet. */ @@ -886,15 +893,17 @@ static inline void get_interrupt_interval(pegasus_t * pegasus) __u8 data[2]; read_eprom_word(pegasus, 4, (__u16 *) data); - if (data[1] < 0x80) { - if (netif_msg_timer(pegasus)) - dev_info(&pegasus->intf->dev, - "intr interval changed from %ums to %ums\n", - data[1], 0x80); - data[1] = 0x80; -#ifdef PEGASUS_WRITE_EEPROM - write_eprom_word(pegasus, 4, *(__u16 *) data); + if (pegasus->usb->speed != USB_SPEED_HIGH) { + if (data[1] < 0x80) { + if (netif_msg_timer(pegasus)) + dev_info(&pegasus->intf->dev, "intr interval " + "changed from %ums to %ums\n", + data[1], 0x80); + data[1] = 0x80; +#ifdef PEGASUS_WRITE_EEPROM + write_eprom_word(pegasus, 4, *(__u16 *) data); #endif + } } pegasus->intr_interval = data[1]; } @@ -904,8 +913,9 @@ static void set_carrier(struct net_device *net) pegasus_t *pegasus = netdev_priv(net); u16 tmp; - if (read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp)) + if (!read_mii_word(pegasus, pegasus->phy, MII_BMSR, &tmp)) return; + if (tmp & BMSR_LSTATUS) netif_carrier_on(net); else @@ -1355,6 +1365,7 @@ static void pegasus_disconnect(struct usb_interface *intf) cancel_delayed_work(&pegasus->carrier_check); unregister_netdev(pegasus->net); usb_put_dev(interface_to_usbdev(intf)); + unlink_all_urbs(pegasus); free_all_urbs(pegasus); free_skb_pool(pegasus); if (pegasus->rx_skb) diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c index a4ce0008d69b..926d4c2c1600 100644 --- a/drivers/usb/serial/airprime.c +++ b/drivers/usb/serial/airprime.c @@ -16,7 +16,8 @@ #include "usb-serial.h" static struct usb_device_id id_table [] = { - { USB_DEVICE(0xf3d, 0x0112) }, + { USB_DEVICE(0xf3d, 0x0112) }, /* AirPrime CDMA Wireless PC Card */ + { USB_DEVICE(0x1410, 0x1110) }, /* Novatel Wireless Merlin CDMA */ { }, }; MODULE_DEVICE_TABLE(usb, id_table); diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index 4e434cb10bb1..5a8631c8a4a7 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c @@ -1846,10 +1846,12 @@ static void ftdi_set_termios (struct usb_serial_port *port, struct termios *old_ } else { /* set the baudrate determined before */ if (change_speed(port)) { - err("%s urb failed to set baurdrate", __FUNCTION__); + err("%s urb failed to set baudrate", __FUNCTION__); + } + /* Ensure RTS and DTR are raised when baudrate changed from 0 */ + if ((old_termios->c_cflag & CBAUD) == B0) { + set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } - /* Ensure RTS and DTR are raised */ - set_mctrl(port, TIOCM_DTR | TIOCM_RTS); } /* Set flow control */ diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c index ddde5fb13f6b..5f7d3193d355 100644 --- a/drivers/usb/serial/generic.c +++ b/drivers/usb/serial/generic.c @@ -223,7 +223,7 @@ int usb_serial_generic_write_room (struct usb_serial_port *port) dbg("%s - port %d", __FUNCTION__, port->number); if (serial->num_bulk_out) { - if (port->write_urb_busy) + if (!(port->write_urb_busy)) room = port->bulk_out_size; } diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 92d0f925d053..4989e5740d18 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -25,6 +25,9 @@ 2005-06-20 v0.4.1 add missing braces :-/ killed end-of-line whitespace 2005-07-15 v0.4.2 rename WLAN product to FUSION, add FUSION2 + 2005-09-10 v0.4.3 added HUAWEI E600 card and Audiovox AirCard + 2005-09-20 v0.4.4 increased recv buffer size: the card sometimes + wants to send >2000 bytes. Work sponsored by: Sigos GmbH, Germany <info@sigos.de> @@ -71,15 +74,21 @@ static int option_send_setup(struct usb_serial_port *port); /* Vendor and product IDs */ #define OPTION_VENDOR_ID 0x0AF0 +#define HUAWEI_VENDOR_ID 0x12D1 +#define AUDIOVOX_VENDOR_ID 0x0F3D #define OPTION_PRODUCT_OLD 0x5000 #define OPTION_PRODUCT_FUSION 0x6000 #define OPTION_PRODUCT_FUSION2 0x6300 +#define HUAWEI_PRODUCT_E600 0x1001 +#define AUDIOVOX_PRODUCT_AIRCARD 0x0112 static struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_OLD) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_FUSION2) }, + { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, + { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) }, { } /* Terminating entry */ }; @@ -132,7 +141,7 @@ static int debug; #define N_IN_URB 4 #define N_OUT_URB 1 -#define IN_BUFLEN 1024 +#define IN_BUFLEN 4096 #define OUT_BUFLEN 128 struct option_port_private { |