summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/usb/core/hub.c7
-rw-r--r--drivers/usb/gadget/net2272.c4
-rw-r--r--drivers/usb/host/pci-quirks.c9
-rw-r--r--drivers/usb/host/xhci-dbg.c2
-rw-r--r--drivers/usb/host/xhci-hub.c9
-rw-r--r--drivers/usb/host/xhci-ring.c11
-rw-r--r--drivers/usb/host/xhci.c8
-rw-r--r--drivers/usb/misc/ezusb.c1
-rw-r--r--drivers/usb/musb/musb_dsps.c8
-rw-r--r--drivers/usb/renesas_usbhs/fifo.c1
-rw-r--r--drivers/usb/renesas_usbhs/mod_host.c5
-rw-r--r--drivers/usb/serial/ch341.c23
-rw-r--r--drivers/usb/serial/digi_acceleport.c117
-rw-r--r--drivers/usb/serial/ipw.c7
-rw-r--r--drivers/usb/serial/keyspan.c181
-rw-r--r--drivers/usb/serial/keyspan.h8
-rw-r--r--drivers/usb/serial/mct_u232.c59
-rw-r--r--drivers/usb/serial/metro-usb.c65
-rw-r--r--drivers/usb/serial/mos7720.c62
-rw-r--r--drivers/usb/serial/mos7840.c495
-rw-r--r--drivers/usb/serial/omninet.c36
-rw-r--r--drivers/usb/serial/opticon.c11
-rw-r--r--drivers/usb/serial/option.c23
-rw-r--r--drivers/usb/serial/qcserial.c33
-rw-r--r--drivers/usb/serial/quatech2.c135
-rw-r--r--drivers/usb/serial/sierra.c133
-rw-r--r--drivers/usb/serial/usb-wwan.h2
-rw-r--r--drivers/usb/serial/usb_wwan.c124
-rw-r--r--drivers/usb/serial/whiteheat.c60
-rw-r--r--drivers/usb/storage/unusual_devs.h6
30 files changed, 798 insertions, 847 deletions
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 64854d76f529..1af04bdeaf0c 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -739,13 +739,16 @@ static void hub_tt_work(struct work_struct *work)
int limit = 100;
spin_lock_irqsave (&hub->tt.lock, flags);
- while (--limit && !list_empty (&hub->tt.clear_list)) {
+ while (!list_empty(&hub->tt.clear_list)) {
struct list_head *next;
struct usb_tt_clear *clear;
struct usb_device *hdev = hub->hdev;
const struct hc_driver *drv;
int status;
+ if (!hub->quiescing && --limit < 0)
+ break;
+
next = hub->tt.clear_list.next;
clear = list_entry (next, struct usb_tt_clear, clear_list);
list_del (&clear->clear_list);
@@ -1210,7 +1213,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
if (hub->has_indicators)
cancel_delayed_work_sync(&hub->leds);
if (hub->tt.hub)
- cancel_work_sync(&hub->tt.clear_work);
+ flush_work(&hub->tt.clear_work);
}
/* caller has locked the hub device */
diff --git a/drivers/usb/gadget/net2272.c b/drivers/usb/gadget/net2272.c
index 43ac7482fa91..c009263a47e3 100644
--- a/drivers/usb/gadget/net2272.c
+++ b/drivers/usb/gadget/net2272.c
@@ -2069,8 +2069,10 @@ static irqreturn_t net2272_irq(int irq, void *_dev)
#if defined(PLX_PCI_RDK2)
/* see if PCI int for us by checking irqstat */
intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT);
- if (!intcsr & (1 << NET2272_PCI_IRQ))
+ if (!intcsr & (1 << NET2272_PCI_IRQ)) {
+ spin_unlock(&dev->lock);
return IRQ_NONE;
+ }
/* check dma interrupts */
#endif
/* Platform/devcice interrupt handler */
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c
index 966d1484ee79..39f9e4a9a2d3 100644
--- a/drivers/usb/host/pci-quirks.c
+++ b/drivers/usb/host/pci-quirks.c
@@ -545,7 +545,14 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = {
/* Pegatron Lucid (Ordissimo AIRIS) */
.matches = {
DMI_MATCH(DMI_BOARD_NAME, "M11JB"),
- DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"),
+ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
+ },
+ },
+ {
+ /* Pegatron Lucid (Ordissimo) */
+ .matches = {
+ DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"),
+ DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
},
},
{ }
diff --git a/drivers/usb/host/xhci-dbg.c b/drivers/usb/host/xhci-dbg.c
index 4b436f5a4171..5f3a7c74aa8d 100644
--- a/drivers/usb/host/xhci-dbg.c
+++ b/drivers/usb/host/xhci-dbg.c
@@ -544,7 +544,6 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci,
int i;
/* Fields are 32 bits wide, DMA addresses are in bytes */
int field_size = 32 / 8;
- struct xhci_slot_ctx *slot_ctx;
dma_addr_t dma = ctx->dma;
int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
@@ -570,7 +569,6 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci,
dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma);
}
- slot_ctx = xhci_get_slot_ctx(xhci, ctx);
xhci_dbg_slot_ctx(xhci, ctx);
xhci_dbg_ep_ctx(xhci, ctx, last_ep);
}
diff --git a/drivers/usb/host/xhci-hub.c b/drivers/usb/host/xhci-hub.c
index aa90ad4d4fd5..a686cf4905bb 100644
--- a/drivers/usb/host/xhci-hub.c
+++ b/drivers/usb/host/xhci-hub.c
@@ -151,9 +151,8 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
if (portsc & PORT_DEV_REMOVE)
port_removable |= 1 << (i + 1);
}
- memset(&desc->u.ss.DeviceRemovable,
- (__force __u16) cpu_to_le16(port_removable),
- sizeof(__u16));
+
+ desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable);
}
static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
@@ -809,11 +808,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
temp = xhci_readl(xhci, port_array[wIndex]);
xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp);
+ spin_unlock_irqrestore(&xhci->lock, flags);
temp = usb_acpi_power_manageable(hcd->self.root_hub,
wIndex);
if (temp)
usb_acpi_set_power_state(hcd->self.root_hub,
wIndex, true);
+ spin_lock_irqsave(&xhci->lock, flags);
break;
case USB_PORT_FEAT_RESET:
temp = (temp | PORT_RESET);
@@ -917,11 +918,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
xhci_writel(xhci, temp & ~PORT_POWER,
port_array[wIndex]);
+ spin_unlock_irqrestore(&xhci->lock, flags);
temp = usb_acpi_power_manageable(hcd->self.root_hub,
wIndex);
if (temp)
usb_acpi_set_power_state(hcd->self.root_hub,
wIndex, false);
+ spin_lock_irqsave(&xhci->lock, flags);
break;
default:
goto error;
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c6ebb176dc4f..4e1a8946b8d1 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -1228,6 +1228,17 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd)
cur_seg = find_trb_seg(xhci->cmd_ring->first_seg,
xhci->cmd_ring->dequeue, &cycle_state);
+ if (!cur_seg) {
+ xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n",
+ xhci->cmd_ring->dequeue,
+ (unsigned long long)
+ xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
+ xhci->cmd_ring->dequeue));
+ xhci_debug_ring(xhci, xhci->cmd_ring);
+ xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
+ return;
+ }
+
/* find the command trb matched by cd from command ring */
for (cmd_trb = xhci->cmd_ring->dequeue;
cmd_trb != xhci->cmd_ring->enqueue;
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 7d462bf20092..c9e419f29b74 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -1627,7 +1627,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
struct xhci_hcd *xhci;
struct xhci_container_ctx *in_ctx, *out_ctx;
unsigned int ep_index;
- struct xhci_ep_ctx *ep_ctx;
struct xhci_slot_ctx *slot_ctx;
struct xhci_input_control_ctx *ctrl_ctx;
u32 added_ctxs;
@@ -1663,7 +1662,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
out_ctx = virt_dev->out_ctx;
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
ep_index = xhci_get_endpoint_index(&ep->desc);
- ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
/* If this endpoint is already in use, and the upper layers are trying
* to add it again without dropping it, reject the addition.
@@ -1817,6 +1815,8 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
case COMP_EBADSLT:
dev_warn(&udev->dev, "WARN: slot not enabled for"
"evaluate context command.\n");
+ ret = -EINVAL;
+ break;
case COMP_CTX_STATE:
dev_warn(&udev->dev, "WARN: invalid context state for "
"evaluate context command.\n");
@@ -4021,7 +4021,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
static unsigned long long xhci_service_interval_to_ns(
struct usb_endpoint_descriptor *desc)
{
- return (1 << (desc->bInterval - 1)) * 125 * 1000;
+ return (1ULL << (desc->bInterval - 1)) * 125 * 1000;
}
static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev,
@@ -4142,7 +4142,7 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev,
(xhci_service_interval_to_ns(desc) > timeout_ns))
timeout_ns = xhci_service_interval_to_ns(desc);
- u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000;
+ u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL;
if (u2_del_ns > timeout_ns)
timeout_ns = u2_del_ns;
diff --git a/drivers/usb/misc/ezusb.c b/drivers/usb/misc/ezusb.c
index 4223d761223d..6589268a6515 100644
--- a/drivers/usb/misc/ezusb.c
+++ b/drivers/usb/misc/ezusb.c
@@ -158,3 +158,4 @@ int ezusb_fx2_ihex_firmware_download(struct usb_device *dev,
}
EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download);
+MODULE_LICENSE("GPL");
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 444346e1e10d..ff5f112053d2 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -458,11 +458,11 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
struct platform_device *musb;
struct resource *res;
struct resource resources[2];
- char res_name[10];
+ char res_name[11];
int ret, musbid;
/* get memory resource */
- sprintf(res_name, "musb%d", id);
+ snprintf(res_name, sizeof(res_name), "musb%d", id);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
if (!res) {
dev_err(dev, "%s get mem resource failed\n", res_name);
@@ -473,7 +473,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
resources[0] = *res;
/* get irq resource */
- sprintf(res_name, "musb%d-irq", id);
+ snprintf(res_name, sizeof(res_name), "musb%d-irq", id);
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
if (!res) {
dev_err(dev, "%s get irq resource failed\n", res_name);
@@ -530,7 +530,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
- sprintf(res_name, "port%d-mode", id);
+ snprintf(res_name, sizeof(res_name), "port%d-mode", id);
of_property_read_u32(np, res_name, (u32 *)&pdata->mode);
of_property_read_u32(np, "power", (u32 *)&pdata->power);
config->multipoint = of_property_read_bool(np, "multipoint");
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c
index 143c4e9e1be4..c021b202c0f3 100644
--- a/drivers/usb/renesas_usbhs/fifo.c
+++ b/drivers/usb/renesas_usbhs/fifo.c
@@ -795,6 +795,7 @@ static void xfer_work(struct work_struct *work)
dev_dbg(dev, " %s %d (%d/ %d)\n",
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
+ usbhs_pipe_enable(pipe);
usbhsf_dma_start(pipe, fifo);
dma_async_issue_pending(chan);
}
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c
index 9b69a1323294..069cd765400c 100644
--- a/drivers/usb/renesas_usbhs/mod_host.c
+++ b/drivers/usb/renesas_usbhs/mod_host.c
@@ -334,6 +334,11 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv,
struct device *dev = usbhs_priv_to_dev(priv);
unsigned long flags;
+ if (unlikely(!uep)) {
+ dev_err(dev, "no uep\n");
+ return;
+ }
+
/******************** spin lock ********************/
usbhs_lock(priv, flags);
diff --git a/drivers/usb/serial/ch341.c b/drivers/usb/serial/ch341.c
index e9c7046ae355..d255f66e708e 100644
--- a/drivers/usb/serial/ch341.c
+++ b/drivers/usb/serial/ch341.c
@@ -242,13 +242,11 @@ out: kfree(buffer);
return r;
}
-/* allocate private data */
-static int ch341_attach(struct usb_serial *serial)
+static int ch341_port_probe(struct usb_serial_port *port)
{
struct ch341_private *priv;
int r;
- /* private data */
priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -258,17 +256,27 @@ static int ch341_attach(struct usb_serial *serial)
priv->baud_rate = DEFAULT_BAUD_RATE;
priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
- r = ch341_configure(serial->dev, priv);
+ r = ch341_configure(port->serial->dev, priv);
if (r < 0)
goto error;
- usb_set_serial_port_data(serial->port[0], priv);
+ usb_set_serial_port_data(port, priv);
return 0;
error: kfree(priv);
return r;
}
+static int ch341_port_remove(struct usb_serial_port *port)
+{
+ struct ch341_private *priv;
+
+ priv = usb_get_serial_port_data(port);
+ kfree(priv);
+
+ return 0;
+}
+
static int ch341_carrier_raised(struct usb_serial_port *port)
{
struct ch341_private *priv = usb_get_serial_port_data(port);
@@ -304,7 +312,7 @@ static void ch341_close(struct usb_serial_port *port)
static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
- struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
+ struct ch341_private *priv = usb_get_serial_port_data(port);
int r;
priv->baud_rate = DEFAULT_BAUD_RATE;
@@ -608,7 +616,8 @@ static struct usb_serial_driver ch341_device = {
.tiocmget = ch341_tiocmget,
.tiocmset = ch341_tiocmset,
.read_int_callback = ch341_read_int_callback,
- .attach = ch341_attach,
+ .port_probe = ch341_port_probe,
+ .port_remove = ch341_port_remove,
.reset_resume = ch341_reset_resume,
};
diff --git a/drivers/usb/serial/digi_acceleport.c b/drivers/usb/serial/digi_acceleport.c
index c86f68c6b078..b50fa1c6d885 100644
--- a/drivers/usb/serial/digi_acceleport.c
+++ b/drivers/usb/serial/digi_acceleport.c
@@ -244,6 +244,8 @@ static int digi_startup_device(struct usb_serial *serial);
static int digi_startup(struct usb_serial *serial);
static void digi_disconnect(struct usb_serial *serial);
static void digi_release(struct usb_serial *serial);
+static int digi_port_probe(struct usb_serial_port *port);
+static int digi_port_remove(struct usb_serial_port *port);
static void digi_read_bulk_callback(struct urb *urb);
static int digi_read_inb_callback(struct urb *urb);
static int digi_read_oob_callback(struct urb *urb);
@@ -294,6 +296,8 @@ static struct usb_serial_driver digi_acceleport_2_device = {
.attach = digi_startup,
.disconnect = digi_disconnect,
.release = digi_release,
+ .port_probe = digi_port_probe,
+ .port_remove = digi_port_remove,
};
static struct usb_serial_driver digi_acceleport_4_device = {
@@ -320,6 +324,8 @@ static struct usb_serial_driver digi_acceleport_4_device = {
.attach = digi_startup,
.disconnect = digi_disconnect,
.release = digi_release,
+ .port_probe = digi_port_probe,
+ .port_remove = digi_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
@@ -1240,59 +1246,50 @@ static int digi_startup_device(struct usb_serial *serial)
return ret;
}
-
-static int digi_startup(struct usb_serial *serial)
+static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
{
-
- int i;
struct digi_port *priv;
- struct digi_serial *serial_priv;
- /* allocate the private data structures for all ports */
- /* number of regular ports + 1 for the out-of-band port */
- for (i = 0; i < serial->type->num_ports + 1; i++) {
- /* allocate port private structure */
- priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL);
- if (priv == NULL) {
- while (--i >= 0)
- kfree(usb_get_serial_port_data(serial->port[i]));
- return 1; /* error */
- }
+ priv = kzalloc(sizeof(*priv), GFP_KERNEL);
+ if (!priv)
+ return -ENOMEM;
- /* initialize port private structure */
- spin_lock_init(&priv->dp_port_lock);
- priv->dp_port_num = i;
- priv->dp_out_buf_len = 0;
- priv->dp_write_urb_in_use = 0;
- priv->dp_modem_signals = 0;
- init_waitqueue_head(&priv->dp_modem_change_wait);
- priv->dp_transmit_idle = 0;
- init_waitqueue_head(&priv->dp_transmit_idle_wait);
- priv->dp_throttled = 0;
- priv->dp_throttle_restart = 0;
- init_waitqueue_head(&priv->dp_flush_wait);
- init_waitqueue_head(&priv->dp_close_wait);
- INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
- priv->dp_port = serial->port[i];
- /* initialize write wait queue for this port */
- init_waitqueue_head(&serial->port[i]->write_wait);
-
- usb_set_serial_port_data(serial->port[i], priv);
- }
+ spin_lock_init(&priv->dp_port_lock);
+ priv->dp_port_num = port_num;
+ init_waitqueue_head(&priv->dp_modem_change_wait);
+ init_waitqueue_head(&priv->dp_transmit_idle_wait);
+ init_waitqueue_head(&priv->dp_flush_wait);
+ init_waitqueue_head(&priv->dp_close_wait);
+ INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
+ priv->dp_port = port;
- /* allocate serial private structure */
- serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL);
- if (serial_priv == NULL) {
- for (i = 0; i < serial->type->num_ports + 1; i++)
- kfree(usb_get_serial_port_data(serial->port[i]));
- return 1; /* error */
- }
+ init_waitqueue_head(&port->write_wait);
+
+ usb_set_serial_port_data(port, priv);
+
+ return 0;
+}
+
+static int digi_startup(struct usb_serial *serial)
+{
+ struct digi_serial *serial_priv;
+ int ret;
+
+ serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
+ if (!serial_priv)
+ return -ENOMEM;
- /* initialize serial private structure */
spin_lock_init(&serial_priv->ds_serial_lock);
serial_priv->ds_oob_port_num = serial->type->num_ports;
serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num];
- serial_priv->ds_device_started = 0;
+
+ ret = digi_port_init(serial_priv->ds_oob_port,
+ serial_priv->ds_oob_port_num);
+ if (ret) {
+ kfree(serial_priv);
+ return ret;
+ }
+
usb_set_serial_data(serial, serial_priv);
return 0;
@@ -1313,15 +1310,35 @@ static void digi_disconnect(struct usb_serial *serial)
static void digi_release(struct usb_serial *serial)
{
- int i;
+ struct digi_serial *serial_priv;
+ struct digi_port *priv;
+
+ serial_priv = usb_get_serial_data(serial);
+
+ priv = usb_get_serial_port_data(serial_priv->ds_oob_port);
+ kfree(priv);
- /* free the private data structures for all ports */
- /* number of regular ports + 1 for the out-of-band port */
- for (i = 0; i < serial->type->num_ports + 1; i++)
- kfree(usb_get_serial_port_data(serial->port[i]));
- kfree(usb_get_serial_data(serial));
+ kfree(serial_priv);
}
+static int digi_port_probe(struct usb_serial_port *port)
+{
+ unsigned port_num;
+
+ port_num = port->number - port->serial->minor;
+
+ return digi_port_init(port, port_num);
+}
+
+static int digi_port_remove(struct usb_serial_port *port)
+{
+ struct digi_port *priv;
+
+ priv = usb_get_serial_port_data(port);
+ kfree(priv);
+
+ return 0;
+}
static void digi_read_bulk_callback(struct urb *urb)
{
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c
index 20a132ec39e2..4264821a3b34 100644
--- a/drivers/usb/serial/ipw.c
+++ b/drivers/usb/serial/ipw.c
@@ -203,8 +203,7 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port)
return 0;
}
-/* fake probe - only to allocate data structures */
-static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id)
+static int ipw_attach(struct usb_serial *serial)
{
struct usb_wwan_intf_private *data;
@@ -303,9 +302,9 @@ static struct usb_serial_driver ipw_device = {
.num_ports = 1,
.open = ipw_open,
.close = ipw_close,
- .probe = ipw_probe,
- .attach = usb_wwan_startup,
+ .attach = ipw_attach,
.release = ipw_release,
+ .port_probe = usb_wwan_port_probe,
.port_remove = usb_wwan_port_remove,
.dtr_rts = ipw_dtr_rts,
.write = usb_wwan_write,
diff --git a/drivers/usb/serial/keyspan.c b/drivers/usb/serial/keyspan.c
index 29c943d737d0..7179b0c5f814 100644
--- a/drivers/usb/serial/keyspan.c
+++ b/drivers/usb/serial/keyspan.c
@@ -1374,13 +1374,9 @@ static struct callbacks {
data in device_details */
static void keyspan_setup_urbs(struct usb_serial *serial)
{
- int i, j;
struct keyspan_serial_private *s_priv;
const struct keyspan_device_details *d_details;
- struct usb_serial_port *port;
- struct keyspan_port_private *p_priv;
struct callbacks *cback;
- int endp;
s_priv = usb_get_serial_data(serial);
d_details = s_priv->device_details;
@@ -1404,45 +1400,6 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
(serial, d_details->glocont_endpoint, USB_DIR_OUT,
serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
cback->glocont_callback);
-
- /* Setup endpoints for each port specific thing */
- for (i = 0; i < d_details->num_ports; i++) {
- port = serial->port[i];
- p_priv = usb_get_serial_port_data(port);
-
- /* Do indat endpoints first, once for each flip */
- endp = d_details->indat_endpoints[i];
- for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) {
- p_priv->in_urbs[j] = keyspan_setup_urb
- (serial, endp, USB_DIR_IN, port,
- p_priv->in_buffer[j], 64,
- cback->indat_callback);
- }
- for (; j < 2; ++j)
- p_priv->in_urbs[j] = NULL;
-
- /* outdat endpoints also have flip */
- endp = d_details->outdat_endpoints[i];
- for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) {
- p_priv->out_urbs[j] = keyspan_setup_urb
- (serial, endp, USB_DIR_OUT, port,
- p_priv->out_buffer[j], 64,
- cback->outdat_callback);
- }
- for (; j < 2; ++j)
- p_priv->out_urbs[j] = NULL;
-
- /* inack endpoint */
- p_priv->inack_urb = keyspan_setup_urb
- (serial, d_details->inack_endpoints[i], USB_DIR_IN,
- port, p_priv->inack_buffer, 1, cback->inack_callback);
-
- /* outcont endpoint */
- p_priv->outcont_urb = keyspan_setup_urb
- (serial, d_details->outcont_endpoints[i], USB_DIR_OUT,
- port, p_priv->outcont_buffer, 64,
- cback->outcont_callback);
- }
}
/* usa19 function doesn't require prescaler */
@@ -2407,9 +2364,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
static int keyspan_startup(struct usb_serial *serial)
{
int i, err;
- struct usb_serial_port *port;
struct keyspan_serial_private *s_priv;
- struct keyspan_port_private *p_priv;
const struct keyspan_device_details *d_details;
for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
@@ -2432,19 +2387,6 @@ static int keyspan_startup(struct usb_serial *serial)
s_priv->device_details = d_details;
usb_set_serial_data(serial, s_priv);
- /* Now setup per port private data */
- for (i = 0; i < serial->num_ports; i++) {
- port = serial->port[i];
- p_priv = kzalloc(sizeof(struct keyspan_port_private),
- GFP_KERNEL);
- if (!p_priv) {
- dev_dbg(&port->dev, "%s - kmalloc for keyspan_port_private (%d) failed!.\n", __func__, i);
- return 1;
- }
- p_priv->device_details = d_details;
- usb_set_serial_port_data(port, p_priv);
- }
-
keyspan_setup_urbs(serial);
if (s_priv->instat_urb != NULL) {
@@ -2463,59 +2405,112 @@ static int keyspan_startup(struct usb_serial *serial)
static void keyspan_disconnect(struct usb_serial *serial)
{
- int i, j;
- struct usb_serial_port *port;
- struct keyspan_serial_private *s_priv;
- struct keyspan_port_private *p_priv;
+ struct keyspan_serial_private *s_priv;
s_priv = usb_get_serial_data(serial);
- /* Stop reading/writing urbs */
stop_urb(s_priv->instat_urb);
stop_urb(s_priv->glocont_urb);
stop_urb(s_priv->indat_urb);
- for (i = 0; i < serial->num_ports; ++i) {
- port = serial->port[i];
- p_priv = usb_get_serial_port_data(port);
- stop_urb(p_priv->inack_urb);
- stop_urb(p_priv->outcont_urb);
- for (j = 0; j < 2; j++) {
- stop_urb(p_priv->in_urbs[j]);
- stop_urb(p_priv->out_urbs[j]);
- }
- }
+}
+
+static void keyspan_release(struct usb_serial *serial)
+{
+ struct keyspan_serial_private *s_priv;
+
+ s_priv = usb_get_serial_data(serial);
- /* Now free them */
usb_free_urb(s_priv->instat_urb);
usb_free_urb(s_priv->indat_urb);
usb_free_urb(s_priv->glocont_urb);
- for (i = 0; i < serial->num_ports; ++i) {
- port = serial->port[i];
- p_priv = usb_get_serial_port_data(port);
- usb_free_urb(p_priv->inack_urb);
- usb_free_urb(p_priv->outcont_urb);
- for (j = 0; j < 2; j++) {
- usb_free_urb(p_priv->in_urbs[j]);
- usb_free_urb(p_priv->out_urbs[j]);
- }
- }
+
+ kfree(s_priv);
}
-static void keyspan_release(struct usb_serial *serial)
+static int keyspan_port_probe(struct usb_serial_port *port)
{
- int i;
- struct usb_serial_port *port;
- struct keyspan_serial_private *s_priv;
+ struct usb_serial *serial = port->serial;
+ struct keyspan_port_private *s_priv;
+ struct keyspan_port_private *p_priv;
+ const struct keyspan_device_details *d_details;
+ struct callbacks *cback;
+ int endp;
+ int port_num;
+ int i;
s_priv = usb_get_serial_data(serial);
+ d_details = s_priv->device_details;
- kfree(s_priv);
+ p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL);
+ if (!p_priv)
+ return -ENOMEM;
- /* Now free per port private data */
- for (i = 0; i < serial->num_ports; i++) {
- port = serial->port[i];
- kfree(usb_get_serial_port_data(port));
+ s_priv = usb_get_serial_data(port->serial);
+ p_priv->device_details = d_details;
+
+ /* Setup values for the various callback routines */
+ cback = &keyspan_callbacks[d_details->msg_format];
+
+ port_num = port->number - port->serial->minor;
+
+ /* Do indat endpoints first, once for each flip */
+ endp = d_details->indat_endpoints[port_num];
+ for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) {
+ p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp,
+ USB_DIR_IN, port,
+ p_priv->in_buffer[i], 64,
+ cback->indat_callback);
+ }
+ /* outdat endpoints also have flip */
+ endp = d_details->outdat_endpoints[port_num];
+ for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) {
+ p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp,
+ USB_DIR_OUT, port,
+ p_priv->out_buffer[i], 64,
+ cback->outdat_callback);
+ }
+ /* inack endpoint */
+ p_priv->inack_urb = keyspan_setup_urb(serial,
+ d_details->inack_endpoints[port_num],
+ USB_DIR_IN, port,
+ p_priv->inack_buffer, 1,
+ cback->inack_callback);
+ /* outcont endpoint */
+ p_priv->outcont_urb = keyspan_setup_urb(serial,
+ d_details->outcont_endpoints[port_num],
+ USB_DIR_OUT, port,
+ p_priv->outcont_buffer, 64,
+ cback->outcont_callback);
+
+ usb_set_serial_port_data(port, p_priv);
+
+ return 0;
+}
+
+static int keyspan_port_remove(struct usb_serial_port *port)
+{
+ struct keyspan_port_private *p_priv;
+ int i;
+
+ p_priv = usb_get_serial_port_data(port);
+
+ stop_urb(p_priv->inack_urb);
+ stop_urb(p_priv->outcont_urb);
+ for (i = 0; i < 2; i++) {
+ stop_urb(p_priv->in_urbs[i]);
+ stop_urb(p_priv->out_urbs[i]);
+ }
+
+ usb_free_urb(p_priv->inack_urb);
+ usb_free_urb(p_priv->outcont_urb);
+ for (i = 0; i < 2; i++) {
+ usb_free_urb(p_priv->in_urbs[i]);
+ usb_free_urb(p_priv->out_urbs[i]);
}
+
+ kfree(p_priv);
+
+ return 0;
}
MODULE_AUTHOR(DRIVER_AUTHOR);
diff --git a/drivers/usb/serial/keyspan.h b/drivers/usb/serial/keyspan.h
index 0a8a40b5711e..0273dda303a4 100644
--- a/drivers/usb/serial/keyspan.h
+++ b/drivers/usb/serial/keyspan.h
@@ -42,6 +42,8 @@ static void keyspan_dtr_rts (struct usb_serial_port *port, int on);
static int keyspan_startup (struct usb_serial *serial);
static void keyspan_disconnect (struct usb_serial *serial);
static void keyspan_release (struct usb_serial *serial);
+static int keyspan_port_probe(struct usb_serial_port *port);
+static int keyspan_port_remove(struct usb_serial_port *port);
static int keyspan_write_room (struct tty_struct *tty);
static int keyspan_write (struct tty_struct *tty,
@@ -567,6 +569,8 @@ static struct usb_serial_driver keyspan_1port_device = {
.attach = keyspan_startup,
.disconnect = keyspan_disconnect,
.release = keyspan_release,
+ .port_probe = keyspan_port_probe,
+ .port_remove = keyspan_port_remove,
};
static struct usb_serial_driver keyspan_2port_device = {
@@ -589,6 +593,8 @@ static struct usb_serial_driver keyspan_2port_device = {
.attach = keyspan_startup,
.disconnect = keyspan_disconnect,
.release = keyspan_release,
+ .port_probe = keyspan_port_probe,
+ .port_remove = keyspan_port_remove,
};
static struct usb_serial_driver keyspan_4port_device = {
@@ -611,6 +617,8 @@ static struct usb_serial_driver keyspan_4port_device = {
.attach = keyspan_startup,
.disconnect = keyspan_disconnect,
.release = keyspan_release,
+ .port_probe = keyspan_port_probe,
+ .port_remove = keyspan_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
diff --git a/drivers/usb/serial/mct_u232.c b/drivers/usb/serial/mct_u232.c
index f3947712e137..8a2081004107 100644
--- a/