summaryrefslogtreecommitdiff
path: root/drivers/usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb')
-rw-r--r--drivers/usb/class/cdc-acm.c22
-rw-r--r--drivers/usb/core/devio.c1
-rw-r--r--drivers/usb/core/driver.c4
-rw-r--r--drivers/usb/core/hub.c36
-rw-r--r--drivers/usb/dwc3/core.c4
-rw-r--r--drivers/usb/dwc3/gadget.c2
-rw-r--r--drivers/usb/gadget/Kconfig1
-rw-r--r--drivers/usb/gadget/lpc32xx_udc.c4
-rw-r--r--drivers/usb/host/ehci-fsl.c2
-rw-r--r--drivers/usb/host/ehci-orion.c2
-rw-r--r--drivers/usb/host/ehci-vt8500.c10
-rw-r--r--drivers/usb/host/uhci-platform.c9
-rw-r--r--drivers/usb/host/xhci.c3
-rw-r--r--drivers/usb/musb/am35x.c6
-rw-r--r--drivers/usb/renesas_usbhs/mod.c6
-rw-r--r--drivers/usb/renesas_usbhs/pipe.h2
-rw-r--r--drivers/usb/serial/ark3116.c26
-rw-r--r--drivers/usb/serial/belkin_sa.c31
-rw-r--r--drivers/usb/serial/cp210x.c40
-rw-r--r--drivers/usb/serial/cyberjack.c49
-rw-r--r--drivers/usb/serial/cypress_m8.c75
-rw-r--r--drivers/usb/serial/f81232.c43
-rw-r--r--drivers/usb/serial/garmin_gps.c24
-rw-r--r--drivers/usb/serial/io_edgeport.c54
-rw-r--r--drivers/usb/serial/io_tables.h8
-rw-r--r--drivers/usb/serial/io_ti.c91
-rw-r--r--drivers/usb/serial/iuu_phoenix.c76
-rw-r--r--drivers/usb/serial/keyspan_pda.c30
-rw-r--r--drivers/usb/serial/kl5kusb105.c68
-rw-r--r--drivers/usb/serial/kobil_sct.c23
-rw-r--r--drivers/usb/serial/option.c84
-rw-r--r--drivers/usb/serial/oti6858.c68
-rw-r--r--drivers/usb/serial/pl2303.c90
-rw-r--r--drivers/usb/serial/spcp8x5.c46
-rw-r--r--drivers/usb/serial/ssu100.c34
-rw-r--r--drivers/usb/serial/ti_usb_3410_5052.c88
36 files changed, 608 insertions, 554 deletions
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 981f2132d128..6e49ec6f3adc 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 e0356cb859b5..b78fbe222b72 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 ddd820d25288..6056db7af410 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 673ee4696262..64854d76f529 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 b415c0c859d3..c14ebc975ba4 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 c9e729a4bf65..7b7deddf6a52 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, &params);
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 dfb51a45496c..e0ff51b89529 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 f696fb9b136d..21a9861dabf0 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-fsl.c b/drivers/usb/host/ehci-fsl.c
index 9bfde82078ec..0d2f35ca93f1 100644
--- a/drivers/usb/host/ehci-fsl.c
+++ b/drivers/usb/host/ehci-fsl.c
@@ -222,7 +222,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
if (pdata->controller_ver < 0) {
dev_warn(hcd->self.controller, "Could not get controller version\n");
- return;
+ return -ENODEV;
}
portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
diff --git a/drivers/usb/host/ehci-orion.c b/drivers/usb/host/ehci-orion.c
index 8e7eca62f169..9c2717d66730 100644
--- a/drivers/usb/host/ehci-orion.c
+++ b/drivers/usb/host/ehci-orion.c
@@ -160,7 +160,7 @@ static const struct hc_driver ehci_orion_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
-static void __init
+static void __devinit
ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
const struct mbus_dram_target_info *dram)
{
diff --git a/drivers/usb/host/ehci-vt8500.c b/drivers/usb/host/ehci-vt8500.c
index 96722bfebc84..d3c9a3e397b9 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 e4780491df4a..68ebf20e1519 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 8d7fcbbe6ade..7d462bf20092 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 457f25e62c51..c964d6af178b 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 35c5208f3249..61933a90e5bf 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 08786c06dcf1..3d80c7b1fd1b 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 cf2522c397d3..bd50a8a41a0f 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 99449424193f..ea29556f0d72 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 28af5acc3360..eb033fc92a15 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 2a7aecc72237..4ee77dcbe690 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 1befce21e173..f0da1279c114 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 244477107e2f..6e4eb57d0177 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 3ee92648c02d..203358d7e7bc 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 8e6faaf3580c..5acc0d13864a 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 350afddb55ba..1511dd0ad324 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 a2209cd45093..60023c2d2a31 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 01da3ea36e89..cd5533e81de7 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 ca43ecb4a2bd..bb87e29c4ac2 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 3f6d7376c02d..1f4517864cd2 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 5c4d2fbd4e11..c9ca7a5b12e0 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 30cff03e9f01..54d4148d01d1 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 933241f03fd8..cee9a52ca891 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 892ebdc7a364..600241901361 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 9716efe92955..769c137f8975 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 015810b3785b..868d1e6852e2 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 6f49392cda5b..f2530d2ef3c4 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)
{