diff options
Diffstat (limited to 'drivers/usb')
34 files changed, 606 insertions, 552 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 981f213..6e49ec6 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c @@ -817,10 +817,6 @@ static const __u32 acm_tty_speed[] = { 2500000, 3000000, 3500000, 4000000 }; -static const __u8 acm_tty_size[] = { - 5, 6, 7, 8 -}; - static void acm_tty_set_termios(struct tty_struct *tty, struct ktermios *termios_old) { @@ -834,7 +830,21 @@ static void acm_tty_set_termios(struct tty_struct *tty, newline.bParityType = termios->c_cflag & PARENB ? (termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & CMSPAR ? 2 : 0) : 0; - newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4]; + switch (termios->c_cflag & CSIZE) { + case CS5: + newline.bDataBits = 5; + break; + case CS6: + newline.bDataBits = 6; + break; + case CS7: + newline.bDataBits = 7; + break; + case CS8: + default: + newline.bDataBits = 8; + break; + } /* FIXME: Needs to clear unsupported bits in the termios */ acm->clocal = ((termios->c_cflag & CLOCAL) != 0); @@ -1233,7 +1243,7 @@ made_compressed_probe: if (usb_endpoint_xfer_int(epwrite)) usb_fill_int_urb(snd->urb, usb_dev, - usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress), + usb_sndintpipe(usb_dev, epwrite->bEndpointAddress), NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval); else usb_fill_bulk_urb(snd->urb, usb_dev, diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index e0356cb..b78fbe2 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -1348,6 +1348,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ret = -EFAULT; goto error; } + uurb->buffer += u; } totlen -= u; } diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c index ddd820d..6056db7 100644 --- a/drivers/usb/core/driver.c +++ b/drivers/usb/core/driver.c @@ -367,6 +367,10 @@ static int usb_probe_interface(struct device *dev) intf->condition = USB_INTERFACE_UNBOUND; usb_cancel_queued_reset(intf); + /* If the LPM disable succeeded, balance the ref counts. */ + if (!lpm_disable_error) + usb_unlocked_enable_lpm(udev); + /* Unbound interfaces are always runtime-PM-disabled and -suspended */ if (driver->supports_autosuspend) pm_runtime_disable(dev); diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index 673ee46..64854d7 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -3241,8 +3241,7 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state) (state == USB3_LPM_U2 && (u2_sel > USB3_LPM_MAX_U2_SEL_PEL || u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) { - dev_dbg(&udev->dev, "Device-initiated %s disabled due " - "to long SEL %llu ms or PEL %llu ms\n", + dev_dbg(&udev->dev, "Device-initiated %s disabled due to long SEL %llu us or PEL %llu us\n", usb3_lpm_names[state], u1_sel, u1_pel); return -EINVAL; } @@ -3320,16 +3319,6 @@ static int usb_set_device_initiated_lpm(struct usb_device *udev, if (enable) { /* - * First, let the device know about the exit latencies - * associated with the link state we're about to enable. - */ - ret = usb_req_set_sel(udev, state); - if (ret < 0) { - dev_warn(&udev->dev, "Set SEL for device-initiated " - "%s failed.\n", usb3_lpm_names[state]); - return -EBUSY; - } - /* * Now send the control transfer to enable device-initiated LPM * for either U1 or U2. */ @@ -3414,7 +3403,28 @@ static int usb_set_lpm_timeout(struct usb_device *udev, static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev, enum usb3_link_state state) { - int timeout; + int timeout, ret; + __u8 u1_mel = udev->bos->ss_cap->bU1devExitLat; + __le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat; + + /* If the device says it doesn't have *any* exit latency to come out of + * U1 or U2, it's probably lying. Assume it doesn't implement that link + * state. + */ + if ((state == USB3_LPM_U1 && u1_mel == 0) || + (state == USB3_LPM_U2 && u2_mel == 0)) + return; + + /* + * First, let the device know about the exit latencies + * associated with the link state we're about to enable. + */ + ret = usb_req_set_sel(udev, state); + if (ret < 0) { + dev_warn(&udev->dev, "Set SEL for device-initiated %s failed.\n", + usb3_lpm_names[state]); + return; + } /* We allow the host controller to set the U1/U2 timeout internally * first, so that it can change its schedule to account for the diff --git a/drivers/usb/dwc3/core.c b/drivers/usb/dwc3/core.c index b415c0c..c14ebc9 100644 --- a/drivers/usb/dwc3/core.c +++ b/drivers/usb/dwc3/core.c @@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc) { dwc3_event_buffers_cleanup(dwc); dwc3_free_event_buffers(dwc); + + usb_phy_shutdown(dwc->usb2_phy); + usb_phy_shutdown(dwc->usb3_phy); + } #define DWC3_ALIGN_MASK (16 - 1) diff --git a/drivers/usb/dwc3/gadget.c b/drivers/usb/dwc3/gadget.c index c9e729a..7b7dedd 100644 --- a/drivers/usb/dwc3/gadget.c +++ b/drivers/usb/dwc3/gadget.c @@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms); WARN_ON_ONCE(ret); dep->resource_index = 0; - + dep->flags &= ~DWC3_EP_BUSY; udelay(100); } diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index dfb51a4..e0ff51b 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -952,6 +952,7 @@ endif config USB_G_WEBCAM tristate "USB Webcam Gadget" depends on VIDEO_DEV + select USB_LIBCOMPOSITE help The Webcam Gadget acts as a composite USB Audio and Video Class device. It provides a userspace API to process UVC control requests diff --git a/drivers/usb/gadget/lpc32xx_udc.c b/drivers/usb/gadget/lpc32xx_udc.c index f696fb9..21a9861 100644 --- a/drivers/usb/gadget/lpc32xx_udc.c +++ b/drivers/usb/gadget/lpc32xx_udc.c @@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work) /* Get the VBUS status from the transceiver */ value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client, - ISP1301_I2C_OTG_CONTROL_2); + ISP1301_I2C_INTERRUPT_SOURCE); /* VBUS on or off? */ - if (value & OTG_B_SESS_VLD) + if (value & INT_SESS_VLD) udc->vbus = 1; else udc->vbus = 0; diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c index 96722bf..d3c9a3e 100644 --- a/drivers/usb/host/ehci-vt8500.c +++ b/drivers/usb/host/ehci-vt8500.c @@ -85,6 +85,8 @@ static const struct hc_driver vt8500_ehci_hc_driver = { .clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, }; +static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32); + static int vt8500_ehci_drv_probe(struct platform_device *pdev) { struct usb_hcd *hcd; @@ -95,6 +97,14 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &vt8500_ehci_dma_mask; + if (pdev->resource[1].flags != IORESOURCE_IRQ) { pr_debug("resource[1] is not IORESOURCE_IRQ"); return -ENOMEM; diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c index e478049..68ebf20 100644 --- a/drivers/usb/host/uhci-platform.c +++ b/drivers/usb/host/uhci-platform.c @@ -60,6 +60,7 @@ static const struct hc_driver uhci_platform_hc_driver = { .hub_control = uhci_hub_control, }; +static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32); static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) { @@ -71,6 +72,14 @@ static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev) if (usb_disabled()) return -ENODEV; + /* + * Right now device-tree probed devices don't get dma_mask set. + * Since shared usb code relies on it, set it here for now. + * Once we have dma capability bindings this can go away. + */ + if (!pdev->dev.dma_mask) + pdev->dev.dma_mask = &platform_uhci_dma_mask; + hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev, pdev->name); if (!hcd) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 8d7fcbb..7d462bf 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void) if (strstr(dmi_product_name, "Z420") || strstr(dmi_product_name, "Z620") || - strstr(dmi_product_name, "Z820")) + strstr(dmi_product_name, "Z820") || + strstr(dmi_product_name, "Z1")) return true; return false; diff --git a/drivers/usb/musb/am35x.c b/drivers/usb/musb/am35x.c index 457f25e..c964d6a 100644 --- a/drivers/usb/musb/am35x.c +++ b/drivers/usb/musb/am35x.c @@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) ret = IRQ_HANDLED; } + /* Drop spurious RX and TX if device is disconnected */ + if (musb->int_usb & MUSB_INTR_DISCONNECT) { + musb->int_tx = 0; + musb->int_rx = 0; + } + if (musb->int_tx || musb->int_rx || musb->int_usb) ret |= musb_interrupt(musb); diff --git a/drivers/usb/renesas_usbhs/mod.c b/drivers/usb/renesas_usbhs/mod.c index 35c5208..61933a9 100644 --- a/drivers/usb/renesas_usbhs/mod.c +++ b/drivers/usb/renesas_usbhs/mod.c @@ -273,9 +273,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC); usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); - usbhs_write(priv, BRDYSTS, 0); - usbhs_write(priv, NRDYSTS, 0); - usbhs_write(priv, BEMPSTS, 0); + usbhs_write(priv, BRDYSTS, ~irq_state.brdysts); + usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts); + usbhs_write(priv, BEMPSTS, ~irq_state.bempsts); /* * call irq callback functions diff --git a/drivers/usb/renesas_usbhs/pipe.h b/drivers/usb/renesas_usbhs/pipe.h index 08786c0..3d80c7b 100644 --- a/drivers/usb/renesas_usbhs/pipe.h +++ b/drivers/usb/renesas_usbhs/pipe.h @@ -54,7 +54,7 @@ struct usbhs_pipe_info { * pipe list */ #define __usbhs_for_each_pipe(start, pos, info, i) \ - for (i = start, pos = (info)->pipe; \ + for (i = start, pos = (info)->pipe + i; \ i < (info)->size; \ i++, pos = (info)->pipe + i) diff --git a/drivers/usb/serial/ark3116.c b/drivers/usb/serial/ark3116.c index cf2522c..bd50a8a4 100644 --- a/drivers/usb/serial/ark3116.c +++ b/drivers/usb/serial/ark3116.c @@ -125,9 +125,6 @@ static inline int calc_divisor(int bps) static int ark3116_attach(struct usb_serial *serial) { - struct usb_serial_port *port = serial->port[0]; - struct ark3116_private *priv; - /* make sure we have our end-points */ if ((serial->num_bulk_in == 0) || (serial->num_bulk_out == 0) || @@ -142,8 +139,15 @@ static int ark3116_attach(struct usb_serial *serial) return -EINVAL; } - priv = kzalloc(sizeof(struct ark3116_private), - GFP_KERNEL); + return 0; +} + +static int ark3116_port_probe(struct usb_serial_port *port) +{ + struct usb_serial *serial = port->serial; + struct ark3116_private *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -198,18 +202,15 @@ static int ark3116_attach(struct usb_serial *serial) return 0; } -static void ark3116_release(struct usb_serial *serial) +static int ark3116_port_remove(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct ark3116_private *priv = usb_get_serial_port_data(port); /* device is closed, so URBs and DMA should be down */ - - usb_set_serial_port_data(port, NULL); - mutex_destroy(&priv->hw_lock); - kfree(priv); + + return 0; } static void ark3116_init_termios(struct tty_struct *tty) @@ -723,7 +724,8 @@ static struct usb_serial_driver ark3116_device = { .id_table = id_table, .num_ports = 1, .attach = ark3116_attach, - .release = ark3116_release, + .port_probe = ark3116_port_probe, + .port_remove = ark3116_port_remove, .set_termios = ark3116_set_termios, .init_termios = ark3116_init_termios, .ioctl = ark3116_ioctl, diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c index 9944942..ea29556 100644 --- a/drivers/usb/serial/belkin_sa.c +++ b/drivers/usb/serial/belkin_sa.c @@ -45,8 +45,8 @@ #define DRIVER_DESC "USB Belkin Serial converter driver" /* function prototypes for a Belkin USB Serial Adapter F5U103 */ -static int belkin_sa_startup(struct usb_serial *serial); -static void belkin_sa_release(struct usb_serial *serial); +static int belkin_sa_port_probe(struct usb_serial_port *port); +static int belkin_sa_port_remove(struct usb_serial_port *port); static int belkin_sa_open(struct tty_struct *tty, struct usb_serial_port *port); static void belkin_sa_close(struct usb_serial_port *port); @@ -88,8 +88,8 @@ static struct usb_serial_driver belkin_device = { .break_ctl = belkin_sa_break_ctl, .tiocmget = belkin_sa_tiocmget, .tiocmset = belkin_sa_tiocmset, - .attach = belkin_sa_startup, - .release = belkin_sa_release, + .port_probe = belkin_sa_port_probe, + .port_remove = belkin_sa_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -118,17 +118,15 @@ struct belkin_sa_private { (c), BELKIN_SA_SET_REQUEST_TYPE, \ (v), 0, NULL, 0, WDR_TIMEOUT) -/* do some startup allocations not currently performed by usb_serial_probe() */ -static int belkin_sa_startup(struct usb_serial *serial) +static int belkin_sa_port_probe(struct usb_serial_port *port) { - struct usb_device *dev = serial->dev; + struct usb_device *dev = port->serial->dev; struct belkin_sa_private *priv; - /* allocate the private data structure */ priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); if (!priv) - return -1; /* error */ - /* set initial values for control structures */ + return -ENOMEM; + spin_lock_init(&priv->lock); priv->control_state = 0; priv->last_lsr = 0; @@ -140,18 +138,19 @@ static int belkin_sa_startup(struct usb_serial *serial) le16_to_cpu(dev->descriptor.bcdDevice), priv->bad_flow_control); - init_waitqueue_head(&serial->port[0]->write_wait); - usb_set_serial_port_data(serial->port[0], priv); + usb_set_serial_port_data(port, priv); return 0; } -static void belkin_sa_release(struct usb_serial *serial) +static int belkin_sa_port_remove(struct usb_serial_port *port) { - int i; + struct belkin_sa_private *priv; - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int belkin_sa_open(struct tty_struct *tty, diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c index 28af5ac..eb033fc 100644 --- a/drivers/usb/serial/cp210x.c +++ b/drivers/usb/serial/cp210x.c @@ -162,7 +162,7 @@ static const struct usb_device_id id_table[] = { MODULE_DEVICE_TABLE(usb, id_table); -struct cp210x_port_private { +struct cp210x_serial_private { __u8 bInterfaceNumber; }; @@ -276,7 +276,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + struct cp210x_serial_private *spriv = usb_get_serial_data(serial); __le32 *buf; int result, i, length; @@ -292,7 +292,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, /* Issue the request, attempting to read 'size' bytes */ result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), request, REQTYPE_INTERFACE_TO_HOST, 0x0000, - port_priv->bInterfaceNumber, buf, size, + spriv->bInterfaceNumber, buf, size, USB_CTRL_GET_TIMEOUT); /* Convert data into an array of integers */ @@ -323,7 +323,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, unsigned int *data, int size) { struct usb_serial *serial = port->serial; - struct cp210x_port_private *port_priv = usb_get_serial_port_data(port); + struct cp210x_serial_private *spriv = usb_get_serial_data(serial); __le32 *buf; int result, i, length; @@ -345,13 +345,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_INTERFACE, 0x0000, - port_priv->bInterfaceNumber, buf, size, + spriv->bInterfaceNumber, buf, size, USB_CTRL_SET_TIMEOUT); } else { result = usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), request, REQTYPE_HOST_TO_INTERFACE, data[0], - port_priv->bInterfaceNumber, NULL, 0, + spriv->bInterfaceNumber, NULL, 0, USB_CTRL_SET_TIMEOUT); } @@ -845,36 +845,30 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state) static int cp210x_startup(struct usb_serial *serial) { - struct cp210x_port_private *port_priv; - int i; + struct usb_host_interface *cur_altsetting; + struct cp210x_serial_private *spriv; /* cp210x buffers behave strangely unless device is reset */ usb_reset_device(serial->dev); - for (i = 0; i < serial->num_ports; i++) { - port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); - if (!port_priv) - return -ENOMEM; + spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); + if (!spriv) + return -ENOMEM; - port_priv->bInterfaceNumber = - serial->interface->cur_altsetting->desc.bInterfaceNumber; + cur_altsetting = serial->interface->cur_altsetting; + spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber; - usb_set_serial_port_data(serial->port[i], port_priv); - } + usb_set_serial_data(serial, spriv); return 0; } static void cp210x_release(struct usb_serial *serial) { - struct cp210x_port_private *port_priv; - int i; + struct cp210x_serial_private *spriv; - for (i = 0; i < serial->num_ports; i++) { - port_priv = usb_get_serial_port_data(serial->port[i]); - kfree(port_priv); - usb_set_serial_port_data(serial->port[i], NULL); - } + spriv = usb_get_serial_data(serial); + kfree(spriv); } module_usb_serial_driver(serial_drivers, id_table); diff --git a/drivers/usb/serial/cyberjack.c b/drivers/usb/serial/cyberjack.c index 2a7aecc..4ee77dc 100644 --- a/drivers/usb/serial/cyberjack.c +++ b/drivers/usb/serial/cyberjack.c @@ -55,9 +55,9 @@ #define CYBERJACK_PRODUCT_ID 0x0100 /* Function prototypes */ -static int cyberjack_startup(struct usb_serial *serial); static void cyberjack_disconnect(struct usb_serial *serial); -static void cyberjack_release(struct usb_serial *serial); +static int cyberjack_port_probe(struct usb_serial_port *port); +static int cyberjack_port_remove(struct usb_serial_port *port); static int cyberjack_open(struct tty_struct *tty, struct usb_serial_port *port); static void cyberjack_close(struct usb_serial_port *port); @@ -83,9 +83,9 @@ static struct usb_serial_driver cyberjack_device = { .description = "Reiner SCT Cyberjack USB card reader", .id_table = id_table, .num_ports = 1, - .attach = cyberjack_startup, .disconnect = cyberjack_disconnect, - .release = cyberjack_release, + .port_probe = cyberjack_port_probe, + .port_remove = cyberjack_port_remove, .open = cyberjack_open, .close = cyberjack_close, .write = cyberjack_write, @@ -107,56 +107,45 @@ struct cyberjack_private { short wrsent; /* Data already sent */ }; -/* do some startup allocations not currently performed by usb_serial_probe() */ -static int cyberjack_startup(struct usb_serial *serial) +static int cyberjack_port_probe(struct usb_serial_port *port) { struct cyberjack_private *priv; - int i; + int result; - /* allocate the private data structure */ priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); if (!priv) return -ENOMEM; - /* set initial values */ spin_lock_init(&priv->lock); priv->rdtodo = 0; priv->wrfilled = 0; priv->wrsent = 0; - usb_set_serial_port_data(serial->port[0], priv); - init_waitqueue_head(&serial->port[0]->write_wait); + usb_set_serial_port_data(port, priv); - for (i = 0; i < serial->num_ports; ++i) { - int result; - result = usb_submit_urb(serial->port[i]->interrupt_in_urb, - GFP_KERNEL); - if (result) - dev_err(&serial->dev->dev, - "usb_submit_urb(read int) failed\n"); - dev_dbg(&serial->dev->dev, "%s - usb_submit_urb(int urb)\n", - __func__); - } + result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); + if (result) + dev_err(&port->dev, "usb_submit_urb(read int) failed\n"); return 0; } -static void cyberjack_disconnect(struct usb_serial *serial) +static int cyberjack_port_remove(struct usb_serial_port *port) { - int i; + struct cyberjack_private *priv; - for (i = 0; i < serial->num_ports; ++i) - usb_kill_urb(serial->port[i]->interrupt_in_urb); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } -static void cyberjack_release(struct usb_serial *serial) +static void cyberjack_disconnect(struct usb_serial *serial) { int i; - for (i = 0; i < serial->num_ports; ++i) { - /* My special items, the standard routines free my urbs */ - kfree(usb_get_serial_port_data(serial->port[i])); - } + for (i = 0; i < serial->num_ports; ++i) + usb_kill_urb(serial->port[i]->interrupt_in_urb); } static int cyberjack_open(struct tty_struct *tty, diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c index 1befce2..f0da127 100644 --- a/drivers/usb/serial/cypress_m8.c +++ b/drivers/usb/serial/cypress_m8.c @@ -123,10 +123,10 @@ struct cypress_private { }; /* function prototypes for the Cypress USB to serial device */ -static int cypress_earthmate_startup(struct usb_serial *serial); -static int cypress_hidcom_startup(struct usb_serial *serial); -static int cypress_ca42v2_startup(struct usb_serial *serial); -static void cypress_release(struct usb_serial *serial); +static int cypress_earthmate_port_probe(struct usb_serial_port *port); +static int cypress_hidcom_port_probe(struct usb_serial_port *port); +static int cypress_ca42v2_port_probe(struct usb_serial_port *port); +static int cypress_port_remove(struct usb_serial_port *port); static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port); static void cypress_close(struct usb_serial_port *port); static void cypress_dtr_rts(struct usb_serial_port *port, int on); @@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = { .description = "DeLorme Earthmate USB", .id_table = id_table_earthmate, .num_ports = 1, - .attach = cypress_earthmate_startup, - .release = cypress_release, + .port_probe = cypress_earthmate_port_probe, + .port_remove = cypress_port_remove, .open = cypress_open, .close = cypress_close, .dtr_rts = cypress_dtr_rts, @@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = { .description = "HID->COM RS232 Adapter", .id_table = id_table_cyphidcomrs232, .num_ports = 1, - .attach = cypress_hidcom_startup, - .release = cypress_release, + .port_probe = cypress_hidcom_port_probe, + .port_remove = cypress_port_remove, .open = cypress_open, .close = cypress_close, .dtr_rts = cypress_dtr_rts, @@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = { .description = "Nokia CA-42 V2 Adapter", .id_table = id_table_nokiaca42v2, .num_ports = 1, - .attach = cypress_ca42v2_startup, - .release = cypress_release, + .port_probe = cypress_ca42v2_port_probe, + .port_remove = cypress_port_remove, .open = cypress_open, .close = cypress_close, .dtr_rts = cypress_dtr_rts, @@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port) *****************************************************************************/ -static int generic_startup(struct usb_serial *serial) +static int cypress_generic_port_probe(struct usb_serial_port *port) { + struct usb_serial *serial = port->serial; struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); if (!priv) @@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial) } -static int cypress_earthmate_startup(struct usb_serial *serial) +static int cypress_earthmate_port_probe(struct usb_serial_port *port) { + struct usb_serial *serial = port->serial; struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; + int ret; - if (generic_startup(serial)) { + ret = cypress_generic_port_probe(port); + if (ret) { dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); - return 1; + return ret; } priv = usb_get_serial_port_data(port); @@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial) } return 0; -} /* cypress_earthmate_startup */ - +} -static int cypress_hidcom_startup(struct usb_serial *serial) +static int cypress_hidcom_port_probe(struct usb_serial_port *port) { struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; + int ret; - if (generic_startup(serial)) { + ret = cypress_generic_port_probe(port); + if (ret) { dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); - return 1; + return ret; } priv = usb_get_serial_port_data(port); priv->chiptype = CT_CYPHIDCOM; return 0; -} /* cypress_hidcom_startup */ - +} -static int cypress_ca42v2_startup(struct usb_serial *serial) +static int cypress_ca42v2_port_probe(struct usb_serial_port *port) { struct cypress_private *priv; - struct usb_serial_port *port = serial->port[0]; + int ret; - if (generic_startup(serial)) { + ret = cypress_generic_port_probe(port); + if (ret) { dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__); - return 1; + return ret; } priv = usb_get_serial_port_data(port); priv->chiptype = CT_CA42V2; return 0; -} /* cypress_ca42v2_startup */ - +} -static void cypress_release(struct usb_serial *serial) +static int cypress_port_remove(struct usb_serial_port *port) { struct cypress_private *priv; - /* all open ports are closed at this point */ - priv = usb_get_serial_port_data(serial->port[0]); + priv = usb_get_serial_port_data(port); - if (priv) { - kfifo_free(&priv->write_fifo); - kfree(priv); - } -} + kfifo_free(&priv->write_fifo); + kfree(priv); + return 0; +} static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) { diff --git a/drivers/usb/serial/f81232.c b/drivers/usb/serial/f81232.c index 2444771..6e4eb57 100644 --- a/drivers/usb/serial/f81232.c +++ b/drivers/usb/serial/f81232.c @@ -318,39 +318,30 @@ static int f81232_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } -static int f81232_startup(struct usb_serial *serial) +static int f81232_port_probe(struct usb_serial_port *port) { struct f81232_private *priv; - int i; - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct f81232_private), GFP_KERNEL); - if (!priv) - goto cleanup; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - usb_set_serial_port_data(serial->port[i], priv); - } - return 0; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; -cleanup: - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); + + usb_set_serial_port_data(port, priv); + + return 0; } -static void f81232_release(struct usb_serial *serial) +static int f81232_port_remove(struct usb_serial_port *port) { - int i; struct f81232_private *priv; - for (i = 0; i < serial->num_ports; ++i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - } + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static struct usb_serial_driver f81232_device = { @@ -373,8 +364,8 @@ static struct usb_serial_driver f81232_device = { .tiocmset = f81232_tiocmset, .process_read_urb = f81232_process_read_urb, .read_int_callback = f81232_read_int_callback, - .attach = f81232_startup, - .release = f81232_release, + .port_probe = f81232_port_probe, + .port_remove = f81232_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { diff --git a/drivers/usb/serial/garmin_gps.c b/drivers/usb/serial/garmin_gps.c index 3ee9264..203358d 100644 --- a/drivers/usb/serial/garmin_gps.c +++ b/drivers/usb/serial/garmin_gps.c @@ -1405,11 +1405,10 @@ static void timeout_handler(unsigned long data) -static int garmin_attach(struct usb_serial *serial) +static int garmin_port_probe(struct usb_serial_port *port) { - int status = 0; - struct usb_serial_port *port = serial->port[0]; - struct garmin_data *garmin_data_p = NULL; + int status; + struct garmin_data *garmin_data_p; garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); if (garmin_data_p == NULL) { @@ -1434,22 +1433,14 @@ static int garmin_attach(struct usb_serial *serial) } -static void garmin_disconnect(struct usb_serial *serial) +static int garmin_port_remove(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); usb_kill_urb(port->interrupt_in_urb); del_timer_sync(&garmin_data_p->timer); -} - - -static void garmin_release(struct usb_serial *serial) -{ - struct usb_serial_port *port = serial->port[0]; - struct garmin_data *garmin_data_p = usb_get_serial_port_data(port); - kfree(garmin_data_p); + return 0; } @@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = { .close = garmin_close, .throttle = garmin_throttle, .unthrottle = garmin_unthrottle, - .attach = garmin_attach, - .disconnect = garmin_disconnect, - .release = garmin_release, + .port_probe = garmin_port_probe, + .port_remove = garmin_port_remove, .write = garmin_write, .write_room = garmin_write_room, .write_bulk_callback = garmin_write_bulk_callback, diff --git a/drivers/usb/serial/io_edgeport.c b/drivers/usb/serial/io_edgeport.c index 8e6faaf..5acc0d1 100644 --- a/drivers/usb/serial/io_edgeport.c +++ b/drivers/usb/serial/io_edgeport.c @@ -225,6 +225,8 @@ static int edge_get_icount(struct tty_struct *tty, static int edge_startup(struct usb_serial *serial); static void edge_disconnect(struct usb_serial *serial); static void edge_release(struct usb_serial *serial); +static int edge_port_probe(struct usb_serial_port *port); +static int edge_port_remove(struct usb_serial_port *port); #include "io_tables.h" /* all of the devices that this driver supports */ @@ -2875,10 +2877,9 @@ static void load_application_firmware(struct edgeport_serial *edge_serial) static int edge_startup(struct usb_serial *serial) { struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; struct usb_device *dev; struct device *ddev = &serial->dev->dev; - int i, j; + int i; int response; bool interrupt_in_found; bool bulk_in_found; @@ -2961,25 +2962,6 @@ static int edge_startup(struct usb_serial *serial) /* we set up the pointers to the endpoints in the edge_open function, * as the structures aren't created yet. */ - /* set up our port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); - if (edge_port == NULL) { - dev_err(ddev, "%s - Out of memory\n", __func__); - for (j = 0; j < i; ++j) { - kfree(usb_get_serial_port_data(serial->port[j])); - usb_set_serial_port_data(serial->port[j], - NULL); - } - usb_set_serial_data(serial, NULL); - kfree(edge_serial); - return -ENOMEM; - } - spin_lock_init(&edge_port->ep_lock); - edge_port->port = serial->port[i]; - usb_set_serial_port_data(serial->port[i], edge_port); - } - response = 0; if (edge_serial->is_epic) { @@ -3120,14 +3102,36 @@ static void edge_disconnect(struct usb_serial *serial) static void edge_release(struct usb_serial *serial) { struct edgeport_serial *edge_serial = usb_get_serial_data(serial); - int i; - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); kfree(edge_serial); } +static int edge_port_probe(struct usb_serial_port *port) +{ + struct edgeport_port *edge_port; + + edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); + if (!edge_port) + return -ENOMEM; + + spin_lock_init(&edge_port->ep_lock); + edge_port->port = port; + + usb_set_serial_port_data(port, edge_port); + + return 0; +} + +static int edge_port_remove(struct usb_serial_port *port) +{ + struct edgeport_port *edge_port; + + edge_port = usb_get_serial_port_data(port); + kfree(edge_port); + + return 0; +} + module_usb_serial_driver(serial_drivers, id_table_combined); MODULE_AUTHOR(DRIVER_AUTHOR); diff --git a/drivers/usb/serial/io_tables.h b/drivers/usb/serial/io_tables.h index 350afdd..1511dd0 100644 --- a/drivers/usb/serial/io_tables.h +++ b/drivers/usb/serial/io_tables.h @@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport_2port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport_4port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport_8port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -197,6 +203,8 @@ static struct usb_serial_driver epic_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c index a2209cd..60023c2 100644 --- a/drivers/usb/serial/io_ti.c +++ b/drivers/usb/serial/io_ti.c @@ -2532,12 +2532,7 @@ static void edge_break(struct tty_struct *tty, int break_state) static int edge_startup(struct usb_serial *serial) { struct edgeport_serial *edge_serial; - struct edgeport_port *edge_port; - struct usb_device *dev; int status; - int i; - - dev = serial->dev; /* create our private serial structure */ edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); @@ -2555,40 +2550,7 @@ static int edge_startup(struct usb_serial *serial) return status; } - /* set up our port private structures */ - for (i = 0; i < serial->num_ports; ++i) { - edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL); - if (edge_port == NULL) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", - __func__); - goto cleanup; - } - spin_lock_init(&edge_port->ep_lock); - if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, - GFP_KERNEL)) { - dev_err(&serial->dev->dev, "%s - Out of memory\n", - __func__); - kfree(edge_port); - goto cleanup; - } - edge_port->port = serial->port[i]; - edge_port->edge_serial = edge_serial; - usb_set_serial_port_data(serial->port[i], edge_port); - edge_port->bUartMode = default_uart_mode; - } - return 0; - -cleanup: - for (--i; i >= 0; --i) { - edge_port = usb_get_serial_port_data(serial->port[i]); - kfifo_free(&edge_port->write_fifo); - kfree(edge_port); - usb_set_serial_port_data(serial->port[i], NULL); - } - kfree(edge_serial); - usb_set_serial_data(serial, NULL); - return -ENOMEM; } static void edge_disconnect(struct usb_serial *serial) @@ -2597,17 +2559,54 @@ static void edge_disconnect(struct usb_serial *serial) static void edge_release(struct usb_serial *serial) { - int i; + kfree(usb_get_serial_data(serial)); +} + +static int edge_port_probe(struct usb_serial_port *port) +{ struct edgeport_port *edge_port; + int ret; - for (i = 0; i < serial->num_ports; ++i) { - edge_port = usb_get_serial_port_data(serial->port[i]); + edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL); + if (!edge_port) + return -ENOMEM; + + ret = kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE, + GFP_KERNEL); + if (ret) { + kfree(edge_port); + return -ENOMEM; + } + + spin_lock_init(&edge_port->ep_lock); + edge_port->port = port; + edge_port->edge_serial = usb_get_serial_data(port->serial); + edge_port->bUartMode = default_uart_mode; + + usb_set_serial_port_data(port, edge_port); + + ret = edge_create_sysfs_attrs(port); + if (ret) { kfifo_free(&edge_port->write_fifo); kfree(edge_port); + return ret; } - kfree(usb_get_serial_data(serial)); + + return 0; } +static int edge_port_remove(struct usb_serial_port *port) +{ + struct edgeport_port *edge_port; + + edge_port = usb_get_serial_port_data(port); + + edge_remove_sysfs_attrs(port); + kfifo_free(&edge_port->write_fifo); + kfree(edge_port); + + return 0; +} /* Sysfs Attributes */ @@ -2667,8 +2666,8 @@ static struct usb_serial_driver edgeport_1port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, - .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, @@ -2698,8 +2697,8 @@ static struct usb_serial_driver edgeport_2port_device = { .attach = edge_startup, .disconnect = edge_disconnect, .release = edge_release, - .port_probe = edge_create_sysfs_attrs, - .port_remove = edge_remove_sysfs_attrs, + .port_probe = edge_port_probe, + .port_remove = edge_port_remove, .ioctl = edge_ioctl, .set_termios = edge_set_termios, .tiocmget = edge_tiocmget, diff --git a/drivers/usb/serial/iuu_phoenix.c b/drivers/usb/serial/iuu_phoenix.c index 01da3ea..cd5533e 100644 --- a/drivers/usb/serial/iuu_phoenix.c +++ b/drivers/usb/serial/iuu_phoenix.c @@ -53,6 +53,8 @@ static int iuu_cardout; static bool xmas; static int vcc_default = 5; +static int iuu_create_sysfs_attrs(struct usb_serial_port *port); +static int iuu_remove_sysfs_attrs(struct usb_serial_port *port); static void read_rxcmd_callback(struct urb *urb); struct iuu_private { @@ -72,63 +74,55 @@ struct iuu_private { u32 clk; }; - -static void iuu_free_buf(struct iuu_private *priv) -{ - kfree(priv->buf); - kfree(priv->writebuf); -} - -static int iuu_alloc_buf(struct usb_serial *serial, struct iuu_private *priv) -{ - priv->buf = kzalloc(256, GFP_KERNEL); - priv->writebuf = kzalloc(256, GFP_KERNEL); - if (!priv->buf || !priv->writebuf) { - iuu_free_buf(priv); - dev_dbg(&serial->dev->dev, "%s problem allocation buffer\n", __func__); - return -ENOMEM; - } - dev_dbg(&serial->dev->dev, "%s - Privates buffers allocation success\n", __func__); - return 0; -} - -static int iuu_startup(struct usb_serial *serial) +static int iuu_port_probe(struct usb_serial_port *port) { struct iuu_private *priv; + int ret; priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); - dev_dbg(&serial->dev->dev, "%s- priv allocation success\n", __func__); if (!priv) return -ENOMEM; - if (iuu_alloc_buf(serial, priv)) { + + priv->buf = kzalloc(256, GFP_KERNEL); + if (!priv->buf) { + kfree(priv); + return -ENOMEM; + } + + priv->writebuf = kzalloc(256, GFP_KERNEL); + if (!priv->writebuf) { + kfree(priv->buf); kfree(priv); return -ENOMEM; } + priv->vcc = vcc_default; spin_lock_init(&priv->lock); init_waitqueue_head(&priv->delta_msr_wait); - usb_set_serial_port_data(serial->port[0], priv); + + usb_set_serial_port_data(port, priv); + + ret = iuu_create_sysfs_attrs(port); + if (ret) { + kfree(priv->writebuf); + kfree(priv->buf); + kfree(priv); + return ret; + } + return 0; } -/* Release function */ -static void iuu_release(struct usb_serial *serial) +static int iuu_port_remove(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct iuu_private *priv = usb_get_serial_port_data(port); - if (!port) - return; - if (priv) { - iuu_free_buf(priv); - dev_dbg(&port->dev, "%s - I will free all\n", __func__); - usb_set_serial_port_data(port, NULL); - - dev_dbg(&port->dev, "%s - priv is not anymore in port structure\n", __func__); - kfree(priv); + iuu_remove_sysfs_attrs(port); + kfree(priv->writebuf); + kfree(priv->buf); + kfree(priv); - dev_dbg(&port->dev, "%s priv is now kfree\n", __func__); - } + return 0; } static int iuu_tiocmset(struct tty_struct *tty, @@ -1215,8 +1209,6 @@ static struct usb_serial_driver iuu_device = { .num_ports = 1, .bulk_in_size = 512, .bulk_out_size = 512, - .port_probe = iuu_create_sysfs_attrs, - .port_remove = iuu_remove_sysfs_attrs, .open = iuu_open, .close = iuu_close, .write = iuu_uart_write, @@ -1225,8 +1217,8 @@ static struct usb_serial_driver iuu_device = { .tiocmset = iuu_tiocmset, .set_termios = iuu_set_termios, .init_termios = iuu_init_termios, - .attach = iuu_startup, - .release = iuu_release, + .port_probe = iuu_port_probe, + .port_remove = iuu_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { diff --git a/drivers/usb/serial/keyspan_pda.c b/drivers/usb/serial/keyspan_pda.c index ca43ecb4..bb87e29 100644 --- a/drivers/usb/serial/keyspan_pda.c +++ b/drivers/usb/serial/keyspan_pda.c @@ -713,29 +713,33 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); #endif -static int keyspan_pda_startup(struct usb_serial *serial) +static int keyspan_pda_port_probe(struct usb_serial_port *port) { struct keyspan_pda_private *priv; - /* allocate the private data structures for all ports. Well, for all - one ports. */ - priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL); if (!priv) - return 1; /* error */ - usb_set_serial_port_data(serial->port[0], priv); - init_waitqueue_head(&serial->port[0]->write_wait); + return -ENOMEM; + INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); - priv->serial = serial; - priv->port = serial->port[0]; + priv->serial = port->serial; + priv->port = port; + + usb_set_serial_port_data(port, priv); + return 0; } -static void keyspan_pda_release(struct usb_serial *serial) +static int keyspan_pda_port_remove(struct usb_serial_port *port) { - kfree(usb_get_serial_port_data(serial->port[0])); + struct keyspan_pda_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } #ifdef KEYSPAN @@ -786,8 +790,8 @@ static struct usb_serial_driver keyspan_pda_device = { .break_ctl = keyspan_pda_break_ctl, .tiocmget = keyspan_pda_tiocmget, .tiocmset = keyspan_pda_tiocmset, - .attach = keyspan_pda_startup, - .release = keyspan_pda_release, + .port_probe = keyspan_pda_port_probe, + .port_remove = keyspan_pda_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { diff --git a/drivers/usb/serial/kl5kusb105.c b/drivers/usb/serial/kl5kusb105.c index 3f6d737..1f45178 100644 --- a/drivers/usb/serial/kl5kusb105.c +++ b/drivers/usb/serial/kl5kusb105.c @@ -60,8 +60,8 @@ /* * Function prototypes */ -static int klsi_105_startup(struct usb_serial *serial); -static void klsi_105_release(struct usb_serial *serial); +static int klsi_105_port_probe(struct usb_serial_port *port); +static int klsi_105_port_remove(struct usb_serial_port *port); static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port); static void klsi_105_close(struct usb_serial_port *port); static void klsi_105_set_termios(struct tty_struct *tty, @@ -99,8 +99,8 @@ static struct usb_serial_driver kl5kusb105d_device = { /*.break_ctl = klsi_105_break_ctl,*/ .tiocmget = klsi_105_tiocmget, .tiocmset = klsi_105_tiocmset, - .attach = klsi_105_startup, - .release = klsi_105_release, + .port_probe = klsi_105_port_probe, + .port_remove = klsi_105_port_remove, .throttle = usb_serial_generic_throttle, .unthrottle = usb_serial_generic_unthrottle, .process_read_urb = klsi_105_process_read_urb, @@ -223,60 +223,40 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, * Driver's tty interface functions */ -static int klsi_105_startup(struct usb_serial *serial) +static int klsi_105_port_probe(struct usb_serial_port *port) { struct klsi_105_private *priv; - int i; - /* check if we support the product id (see keyspan.c) - * FIXME - */ + priv = kmalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; - /* allocate the private data structure */ - for (i = 0; i < serial->num_ports; i++) { - priv = kmalloc(sizeof(struct klsi_105_private), - GFP_KERNEL); - if (!priv) { - dev_dbg(&serial->interface->dev, - "%s - kmalloc for klsi_105_private failed.\n", - __func__); - i--; - goto err_cleanup; - } - /* set initial values for control structures */ - priv->cfg.pktlen = 5; - priv->cfg.baudrate = kl5kusb105a_sio_b9600; - priv->cfg.databits = kl5kusb105a_dtb_8; - priv->cfg.unknown1 = 0; - priv->cfg.unknown2 = 1; + /* set initial values for control structures */ + priv->cfg.pktlen = 5; + priv->cfg.baudrate = kl5kusb105a_sio_b9600; + priv->cfg.databits = kl5kusb105a_dtb_8; + priv->cfg.unknown1 = 0; + priv->cfg.unknown2 = 1; - priv->line_state = 0; + priv->line_state = 0; - usb_set_serial_port_data(serial->port[i], priv); + spin_lock_init(&priv->lock); - spin_lock_init(&priv->lock); + /* priv->termios is left uninitialized until port opening */ - /* priv->termios is left uninitialized until port opening */ - init_waitqueue_head(&serial->port[i]->write_wait); - } + usb_set_serial_port_data(port, priv); return 0; - -err_cleanup: - for (; i >= 0; i--) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; } -static void klsi_105_release(struct usb_serial *serial) +static int klsi_105_port_remove(struct usb_serial_port *port) { - int i; + struct klsi_105_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); + return 0; } static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) diff --git a/drivers/usb/serial/kobil_sct.c b/drivers/usb/serial/kobil_sct.c index 5c4d2fb..c9ca7a5 100644 --- a/drivers/usb/serial/kobil_sct.c +++ b/drivers/usb/serial/kobil_sct.c @@ -54,8 +54,8 @@ /* Function prototypes */ -static int kobil_startup(struct usb_serial *serial); -static void kobil_release(struct usb_serial *serial); +static int kobil_port_probe(struct usb_serial_port *probe); +static int kobil_port_remove(struct usb_serial_port *probe); static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); static void kobil_close(struct usb_serial_port *port); static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -89,8 +89,8 @@ static struct usb_serial_driver kobil_device = { .description = "KOBIL USB smart card terminal", .id_table = id_table, .num_ports = 1, - .attach = kobil_startup, - .release = kobil_release, + .port_probe = kobil_port_probe, + .port_remove = kobil_port_remove, .ioctl = kobil_ioctl, .set_termios = kobil_set_termios, .init_termios = kobil_init_termios, @@ -117,9 +117,10 @@ struct kobil_private { }; -static int kobil_startup(struct usb_serial *serial) +static int kobil_port_probe(struct usb_serial_port *port) { int i; + struct usb_serial *serial = port->serial; struct kobil_private *priv; struct usb_device *pdev; struct usb_host_config *actconfig; @@ -149,7 +150,7 @@ static int kobil_startup(struct usb_serial *serial) dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n"); break; } - usb_set_serial_port_data(serial->port[0], priv); + usb_set_serial_port_data(port, priv); /* search for the necessary endpoints */ pdev = serial->dev; @@ -179,12 +180,14 @@ static int kobil_startup(struct usb_serial *serial) } -static void kobil_release(struct usb_serial *serial) +static int kobil_port_remove(struct usb_serial_port *port) { - int i; + struct kobil_private *priv; - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static void kobil_init_termios(struct tty_struct *tty) diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 30cff03..54d4148 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c @@ -503,11 +503,19 @@ static const struct option_blacklist_info net_intf5_blacklist = { .reserved = BIT(5), }; +static const struct option_blacklist_info net_intf6_blacklist = { + .reserved = BIT(6), +}; + static const struct option_blacklist_info zte_mf626_blacklist = { .sendsetup = BIT(0) | BIT(1), .reserved = BIT(4), }; +static const struct option_blacklist_info zte_1255_blacklist = { + .reserved = BIT(3) | BIT(4), +}; + static const struct usb_device_id option_ids[] = { { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, @@ -853,13 +861,19 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf6_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) }, @@ -872,7 +886,8 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) }, @@ -880,13 +895,22 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */ + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */ + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */ + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, @@ -1002,18 +1026,24 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&zte_1255_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) }, @@ -1058,8 +1088,16 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */ + .driver_info = (kernel_ulong_t)&net_intf2_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, @@ -1071,15 +1109,21 @@ static const struct usb_device_id option_ids[] = { { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf1_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf5_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) }, - { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, + { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff), + .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, diff --git a/drivers/usb/serial/oti6858.c b/drivers/usb/serial/oti6858.c index 933241f..cee9a52 100644 --- a/drivers/usb/serial/oti6858.c +++ b/drivers/usb/serial/oti6858.c @@ -137,8 +137,8 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty); static int oti6858_tiocmget(struct tty_struct *tty); static int oti6858_tiocmset(struct tty_struct *tty, unsigned int set, unsigned int clear); -static int oti6858_startup(struct usb_serial *serial); -static void oti6858_release(struct usb_serial *serial); +static int oti6858_port_probe(struct usb_serial_port *port); +static int oti6858_port_remove(struct usb_serial_port *port); /* device info */ static struct usb_serial_driver oti6858_device = { @@ -161,8 +161,8 @@ static struct usb_serial_driver oti6858_device = { .write_bulk_callback = oti6858_write_bulk_callback, .write_room = oti6858_write_room, .chars_in_buffer = oti6858_chars_in_buffer, - .attach = oti6858_startup, - .release = oti6858_release, + .port_probe = oti6858_port_probe, + .port_remove = oti6858_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { @@ -331,36 +331,33 @@ static void send_data(struct work_struct *work) usb_serial_port_softint(port); } -static int oti6858_startup(struct usb_serial *serial) +static int oti6858_port_probe(struct usb_serial_port *port) { - struct usb_serial_port *port = serial->port[0]; struct oti6858_private *priv; - int i; - - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL); - if (!priv) - break; - - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->intr_wait); -/* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */ -/* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */ - priv->port = port; - INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); - INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); - - usb_set_serial_port_data(serial->port[i], priv); - } - if (i == serial->num_ports) - return 0; - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->intr_wait); + priv->port = port; + INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line); + INIT_DELAYED_WORK(&priv->delayed_write_work, send_data); + + usb_set_serial_port_data(port, priv); + + return 0; +} + +static int oti6858_port_remove(struct usb_serial_port *port) +{ + struct oti6858_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -709,15 +706,6 @@ static int oti6858_ioctl(struct tty_struct *tty, return -ENOIOCTLCMD; } - -static void oti6858_release(struct usb_serial *serial) -{ - int i; - - for (i = 0; i < serial->num_ports; ++i) - kfree(usb_get_serial_port_data(serial->port[i])); -} - static void oti6858_read_int_callback(struct urb *urb) { struct usb_serial_port *port = urb->context; diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c index 892ebdc7..6002419 100644 --- a/drivers/usb/serial/pl2303.c +++ b/drivers/usb/serial/pl2303.c @@ -133,12 +133,15 @@ enum pl2303_type { HX, /* HX version of the pl2303 chip */ }; +struct pl2303_serial_private { + enum pl2303_type type; +}; + struct pl2303_private { spinlock_t lock; wait_queue_head_t delta_msr_wait; u8 line_control; u8 line_status; - enum pl2303_type type; }; static int pl2303_vendor_read(__u16 value, __u16 index, @@ -167,14 +170,19 @@ static int pl2303_vendor_write(__u16 value, __u16 index, static int pl2303_startup(struct usb_serial *serial) { - struct pl2303_private *priv; + struct pl2303_serial_private *spriv; enum pl2303_type type = type_0; unsigned char *buf; - int i; + + spriv = kzalloc(sizeof(*spriv), GFP_KERNEL); + if (!spriv) + return -ENOMEM; buf = kmalloc(10, GFP_KERNEL); - if (buf == NULL) + if (!buf) { + kfree(spriv); return -ENOMEM; + } if (serial->dev->descriptor.bDeviceClass == 0x02) type = type_0; @@ -186,15 +194,8 @@ static int pl2303_startup(struct usb_serial *serial) type = type_1; dev_dbg(&serial->interface->dev, "device type: %d\n", type); - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL); - if (!priv) - goto cleanup; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - priv->type = type; - usb_set_serial_port_data(serial->port[i], priv); - } + spriv->type = type; + usb_set_serial_data(serial, spriv); pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_write(0x0404, 0, serial); @@ -213,15 +214,40 @@ static int pl2303_startup(struct usb_serial *serial) kfree(buf); return 0; +} -cleanup: - kfree(buf); - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i], NULL); - } - return -ENOMEM; +static void pl2303_release(struct usb_serial *serial) +{ + struct pl2303_serial_private *spriv; + + spriv = usb_get_serial_data(serial); + kfree(spriv); +} + +static int pl2303_port_probe(struct usb_serial_port *port) +{ + struct pl2303_private *priv; + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); + + usb_set_serial_port_data(port, priv); + + return 0; +} + +static int pl2303_port_remove(struct usb_serial_port *port) +{ + struct pl2303_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int set_control_lines(struct usb_device *dev, u8 value) @@ -240,6 +266,7 @@ static void pl2303_set_termios(struct tty_struct *tty, struct usb_serial_port *port, struct ktermios *old_termios) { struct usb_serial *serial = port->serial; + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); struct pl2303_private *priv = usb_get_serial_port_data(port); unsigned long flags; unsigned int cflag; @@ -323,7 +350,7 @@ static void pl2303_set_termios(struct tty_struct *tty, } if (baud > 1228800) { /* type_0, type_1 only support up to 1228800 baud */ - if (priv->type != HX) + if (spriv->type != HX) baud = 1228800; else if (baud > 6000000) baud = 6000000; @@ -426,7 +453,7 @@ static void pl2303_set_termios(struct tty_struct *tty, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]); if (cflag & CRTSCTS) { - if (priv->type == HX) + if (spriv->type == HX) pl2303_vendor_write(0x0, 0x61, serial); else pl2303_vendor_write(0x0, 0x41, serial); @@ -468,10 +495,10 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) { struct ktermios tmp_termios; struct usb_serial *serial = port->serial; - struct pl2303_private *priv = usb_get_serial_port_data(port); + struct pl2303_serial_private *spriv = usb_get_serial_data(serial); int result; - if (priv->type != HX) { + if (spriv->type != HX) { usb_clear_halt(serial->dev, port->write_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe); } else { @@ -655,17 +682,6 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) dev_err(&port->dev, "error sending break = %d\n", result); } -static void pl2303_release(struct usb_serial *serial) -{ - int i; - struct pl2303_private *priv; - - for (i = 0; i < serial->num_ports; ++i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - } -} - static void pl2303_update_line_status(struct usb_serial_port *port, unsigned char *data, unsigned int actual_length) @@ -827,6 +843,8 @@ static struct usb_serial_driver pl2303_device = { .read_int_callback = pl2303_read_int_callback, .attach = pl2303_startup, .release = pl2303_release, + .port_probe = pl2303_port_probe, + .port_remove = pl2303_port_remove, }; static struct usb_serial_driver * const serial_drivers[] = { diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c index 9716efe..769c137 100644 --- a/drivers/usb/serial/spcp8x5.c +++ b/drivers/usb/serial/spcp8x5.c @@ -157,13 +157,10 @@ struct spcp8x5_private { u8 line_status; }; -/* desc : when device plug in,this function would be called. - * thanks to usb_serial subsystem,then do almost every things for us. And what - * we should do just alloc the buffer */ -static int spcp8x5_startup(struct usb_serial *serial) +static int spcp8x5_port_probe(struct usb_serial_port *port) { + struct usb_serial *serial = port->serial; struct spcp8x5_private *priv; - int i; enum spcp8x5_type type = SPCP825_007_TYPE; u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); @@ -180,34 +177,27 @@ static int spcp8x5_startup(struct usb_serial *serial) type = SPCP825_PHILIP_TYPE; dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type); - for (i = 0; i < serial->num_ports; ++i) { - priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL); - if (!priv) - goto cleanup; + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; - spin_lock_init(&priv->lock); - init_waitqueue_head(&priv->delta_msr_wait); - priv->type = type; - usb_set_serial_port_data(serial->port[i] , priv); - } + spin_lock_init(&priv->lock); + init_waitqueue_head(&priv->delta_msr_wait); + priv->type = type; + + usb_set_serial_port_data(port , priv); return 0; -cleanup: - for (--i; i >= 0; --i) { - priv = usb_get_serial_port_data(serial->port[i]); - kfree(priv); - usb_set_serial_port_data(serial->port[i] , NULL); - } - return -ENOMEM; } -/* call when the device plug out. free all the memory alloced by probe */ -static void spcp8x5_release(struct usb_serial *serial) +static int spcp8x5_port_remove(struct usb_serial_port *port) { - int i; + struct spcp8x5_private *priv; - for (i = 0; i < serial->num_ports; i++) - kfree(usb_get_serial_port_data(serial->port[i])); + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } /* set the modem control line of the device. @@ -649,8 +639,8 @@ static struct usb_serial_driver spcp8x5_device = { .ioctl = spcp8x5_ioctl, .tiocmget = spcp8x5_tiocmget, .tiocmset = spcp8x5_tiocmset, - .attach = spcp8x5_startup, - .release = spcp8x5_release, + .port_probe = spcp8x5_port_probe, + .port_remove = spcp8x5_port_remove, .process_read_urb = spcp8x5_process_read_urb, }; diff --git a/drivers/usb/serial/ssu100.c b/drivers/usb/serial/ssu100.c index 015810b..868d1e6 100644 --- a/drivers/usb/serial/ssu100.c +++ b/drivers/usb/serial/ssu100.c @@ -67,13 +67,6 @@ struct ssu100_port_private { struct async_icount icount; }; -static void ssu100_release(struct usb_serial *serial) -{ - struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port); - - kfree(priv); -} - static inline int ssu100_control_msg(struct usb_device *dev, u8 request, u16 data, u16 index) { @@ -442,21 +435,33 @@ static int ssu100_ioctl(struct tty_struct *tty, static int ssu100_attach(struct usb_serial *serial) { + return ssu100_initdevice(serial->dev); +} + +static int ssu100_port_probe(struct usb_serial_port *port) +{ struct ssu100_port_private *priv; - struct usb_serial_port *port = *serial->port; priv = kzalloc(sizeof(*priv), GFP_KERNEL); - if (!priv) { - dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__, - sizeof(*priv)); + if (!priv) return -ENOMEM; - } spin_lock_init(&priv->status_lock); init_waitqueue_head(&priv->delta_msr_wait); + usb_set_serial_port_data(port, priv); - return ssu100_initdevice(serial->dev); + return 0; +} + +static int ssu100_port_remove(struct usb_serial_port *port) +{ + struct ssu100_port_private *priv; + + priv = usb_get_serial_port_data(port); + kfree(priv); + + return 0; } static int ssu100_tiocmget(struct tty_struct *tty) @@ -647,7 +652,8 @@ static struct usb_serial_driver ssu100_device = { .open = ssu100_open, .close = ssu100_close, .attach = ssu100_attach, - .release = ssu100_release, + .port_probe = ssu100_port_probe, + .port_remove = ssu100_port_remove, .dtr_rts = ssu100_dtr_rts, .process_read_urb = ssu100_process_read_urb, .tiocmget = ssu100_tiocmget, diff --git a/drivers/usb/serial/ti_usb_3410_5052.c b/drivers/usb/serial/ti_usb_3410_5052.c index 6f49392..f2530d2 100644 --- a/drivers/usb/serial/ti_usb_3410_5052.c +++ b/drivers/usb/serial/ti_usb_3410_5052.c @@ -97,6 +97,8 @@ struct ti_device { static int ti_startup(struct usb_serial *serial); static void ti_release(struct usb_serial *serial); +static int ti_port_probe(struct usb_serial_port *port); +static int ti_port_remove(struct usb_serial_port *port); static int ti_open(struct tty_struct *tty, struct usb_serial_port *port); static void ti_close(struct usb_serial_port *port); static int ti_write(struct tty_struct *tty, struct usb_serial_port *port, @@ -221,6 +223,8 @@ static struct usb_serial_driver ti_1port_device = { .num_ports = 1, .attach = ti_startup, .release = ti_release, + .port_probe = ti_port_probe, + .port_remove = ti_port_remove, .open = ti_open, .close = ti_close, .write = ti_write, @@ -249,6 +253,8 @@ static struct usb_serial_driver ti_2port_device = { .num_ports = 2, .attach = ti_startup, .release = ti_release, + .port_probe = ti_port_probe, + .port_remove = ti_port_remove, .open = ti_open, .close = ti_close, .write = ti_write, @@ -347,11 +353,8 @@ module_exit(ti_exit); static int ti_startup(struct usb_serial *serial) { struct ti_device *tdev; - struct ti_port *tport; struct usb_device *dev = serial->dev; int status; - int i; - dev_dbg(&dev->dev, "%s - product 0x%4X, num configurations %d, configuration value %d", @@ -399,42 +402,8 @@ static int ti_startup(struct usb_serial *serial) goto free_tdev; } - /* set up port structures */ - for (i = 0; i < serial->num_ports; ++i) { - tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL); - if (tport == NULL) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - status = -ENOMEM; - goto free_tports; - } - spin_lock_init(&tport->tp_lock); - tport->tp_uart_base_addr = (i == 0 ? - TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR); - tport->tp_closing_wait = closing_wait; - init_waitqueue_head(&tport->tp_msr_wait); - init_waitqueue_head(&tport->tp_write_wait); - if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, - GFP_KERNEL)) { - dev_err(&dev->dev, "%s - out of memory\n", __func__); - kfree(tport); - status = -ENOMEM; - goto free_tports; - } - tport->tp_port = serial->port[i]; - tport->tp_tdev = tdev; - usb_set_serial_port_data(serial->port[i], tport); - tport->tp_uart_mode = 0; /* default is RS232 */ - } - return 0; -free_tports: - for (--i; i >= 0; --i) { - tport = usb_get_serial_port_data(serial->port[i]); - kfifo_free(&tport->write_fifo); - kfree(tport); - usb_set_serial_port_data(serial->port[i], NULL); - } free_tdev: kfree(tdev); usb_set_serial_data(serial, NULL); @@ -444,21 +413,50 @@ free_tdev: static void ti_release(struct usb_serial *serial) { - int i; struct ti_device *tdev = usb_get_serial_data(serial); + + kfree(tdev); +} + +static int ti_port_probe(struct usb_serial_port *port) +{ struct ti_port *tport; - for (i = 0; i < serial->num_ports; ++i) { - tport = usb_get_serial_port_data(serial->port[i]); - if (tport) { - kfifo_free(&tport->write_fifo); - kfree(tport); - } + tport = kzalloc(sizeof(*tport), GFP_KERNEL); + if (!tport) + return -ENOMEM; + + spin_lock_init(&tport->tp_lock); + if (port == port->serial->port[0]) + tport->tp_uart_base_addr = TI_UART1_BASE_ADDR; + else + tport->tp_uart_base_addr = TI_UART2_BASE_ADDR; + tport->tp_closing_wait = closing_wait; + init_waitqueue_head(&tport->tp_msr_wait); + init_waitqueue_head(&tport->tp_write_wait); + if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) { + kfree(tport); + return -ENOMEM; } + tport->tp_port = port; + tport->tp_tdev = usb_get_serial_data(port->serial); + tport->tp_uart_mode = 0; /* default is RS232 */ - kfree(tdev); + usb_set_serial_port_data(port, tport); + + return 0; } +static int ti_port_remove(struct usb_serial_port *port) +{ + struct ti_port *tport; + + tport = usb_get_serial_port_data(port); + kfifo_free(&tport->write_fifo); + kfree(tport); + + return 0; +} static int ti_open(struct tty_struct *tty, struct usb_serial_port *port) { |