diff options
Diffstat (limited to 'drivers/usb')
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) | |||
739 | int limit = 100; | 739 | int limit = 100; |
740 | 740 | ||
741 | spin_lock_irqsave (&hub->tt.lock, flags); | 741 | spin_lock_irqsave (&hub->tt.lock, flags); |
742 | while (--limit && !list_empty (&hub->tt.clear_list)) { | 742 | while (!list_empty(&hub->tt.clear_list)) { |
743 | struct list_head *next; | 743 | struct list_head *next; |
744 | struct usb_tt_clear *clear; | 744 | struct usb_tt_clear *clear; |
745 | struct usb_device *hdev = hub->hdev; | 745 | struct usb_device *hdev = hub->hdev; |
746 | const struct hc_driver *drv; | 746 | const struct hc_driver *drv; |
747 | int status; | 747 | int status; |
748 | 748 | ||
749 | if (!hub->quiescing && --limit < 0) | ||
750 | break; | ||
751 | |||
749 | next = hub->tt.clear_list.next; | 752 | next = hub->tt.clear_list.next; |
750 | clear = list_entry (next, struct usb_tt_clear, clear_list); | 753 | clear = list_entry (next, struct usb_tt_clear, clear_list); |
751 | list_del (&clear->clear_list); | 754 | list_del (&clear->clear_list); |
@@ -1210,7 +1213,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) | |||
1210 | if (hub->has_indicators) | 1213 | if (hub->has_indicators) |
1211 | cancel_delayed_work_sync(&hub->leds); | 1214 | cancel_delayed_work_sync(&hub->leds); |
1212 | if (hub->tt.hub) | 1215 | if (hub->tt.hub) |
1213 | cancel_work_sync(&hub->tt.clear_work); | 1216 | flush_work(&hub->tt.clear_work); |
1214 | } | 1217 | } |
1215 | 1218 | ||
1216 | /* caller has locked the hub device */ | 1219 | /* 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) | |||
2069 | #if defined(PLX_PCI_RDK2) | 2069 | #if defined(PLX_PCI_RDK2) |
2070 | /* see if PCI int for us by checking irqstat */ | 2070 | /* see if PCI int for us by checking irqstat */ |
2071 | intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT); | 2071 | intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT); |
2072 | if (!intcsr & (1 << NET2272_PCI_IRQ)) | 2072 | if (!intcsr & (1 << NET2272_PCI_IRQ)) { |
2073 | spin_unlock(&dev->lock); | ||
2073 | return IRQ_NONE; | 2074 | return IRQ_NONE; |
2075 | } | ||
2074 | /* check dma interrupts */ | 2076 | /* check dma interrupts */ |
2075 | #endif | 2077 | #endif |
2076 | /* Platform/devcice interrupt handler */ | 2078 | /* 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[] = { | |||
545 | /* Pegatron Lucid (Ordissimo AIRIS) */ | 545 | /* Pegatron Lucid (Ordissimo AIRIS) */ |
546 | .matches = { | 546 | .matches = { |
547 | DMI_MATCH(DMI_BOARD_NAME, "M11JB"), | 547 | DMI_MATCH(DMI_BOARD_NAME, "M11JB"), |
548 | DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"), | 548 | DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), |
549 | }, | ||
550 | }, | ||
551 | { | ||
552 | /* Pegatron Lucid (Ordissimo) */ | ||
553 | .matches = { | ||
554 | DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"), | ||
555 | DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"), | ||
549 | }, | 556 | }, |
550 | }, | 557 | }, |
551 | { } | 558 | { } |
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, | |||
544 | int i; | 544 | int i; |
545 | /* Fields are 32 bits wide, DMA addresses are in bytes */ | 545 | /* Fields are 32 bits wide, DMA addresses are in bytes */ |
546 | int field_size = 32 / 8; | 546 | int field_size = 32 / 8; |
547 | struct xhci_slot_ctx *slot_ctx; | ||
548 | dma_addr_t dma = ctx->dma; | 547 | dma_addr_t dma = ctx->dma; |
549 | int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); | 548 | int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params); |
550 | 549 | ||
@@ -570,7 +569,6 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci, | |||
570 | dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma); | 569 | dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma); |
571 | } | 570 | } |
572 | 571 | ||
573 | slot_ctx = xhci_get_slot_ctx(xhci, ctx); | ||
574 | xhci_dbg_slot_ctx(xhci, ctx); | 572 | xhci_dbg_slot_ctx(xhci, ctx); |
575 | xhci_dbg_ep_ctx(xhci, ctx, last_ep); | 573 | xhci_dbg_ep_ctx(xhci, ctx, last_ep); |
576 | } | 574 | } |
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, | |||
151 | if (portsc & PORT_DEV_REMOVE) | 151 | if (portsc & PORT_DEV_REMOVE) |
152 | port_removable |= 1 << (i + 1); | 152 | port_removable |= 1 << (i + 1); |
153 | } | 153 | } |
154 | memset(&desc->u.ss.DeviceRemovable, | 154 | |
155 | (__force __u16) cpu_to_le16(port_removable), | 155 | desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable); |
156 | sizeof(__u16)); | ||
157 | } | 156 | } |
158 | 157 | ||
159 | static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci, | 158 | 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, | |||
809 | temp = xhci_readl(xhci, port_array[wIndex]); | 808 | temp = xhci_readl(xhci, port_array[wIndex]); |
810 | xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); | 809 | xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp); |
811 | 810 | ||
811 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
812 | temp = usb_acpi_power_manageable(hcd->self.root_hub, | 812 | temp = usb_acpi_power_manageable(hcd->self.root_hub, |
813 | wIndex); | 813 | wIndex); |
814 | if (temp) | 814 | if (temp) |
815 | usb_acpi_set_power_state(hcd->self.root_hub, | 815 | usb_acpi_set_power_state(hcd->self.root_hub, |
816 | wIndex, true); | 816 | wIndex, true); |
817 | spin_lock_irqsave(&xhci->lock, flags); | ||
817 | break; | 818 | break; |
818 | case USB_PORT_FEAT_RESET: | 819 | case USB_PORT_FEAT_RESET: |
819 | temp = (temp | PORT_RESET); | 820 | temp = (temp | PORT_RESET); |
@@ -917,11 +918,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
917 | xhci_writel(xhci, temp & ~PORT_POWER, | 918 | xhci_writel(xhci, temp & ~PORT_POWER, |
918 | port_array[wIndex]); | 919 | port_array[wIndex]); |
919 | 920 | ||
921 | spin_unlock_irqrestore(&xhci->lock, flags); | ||
920 | temp = usb_acpi_power_manageable(hcd->self.root_hub, | 922 | temp = usb_acpi_power_manageable(hcd->self.root_hub, |
921 | wIndex); | 923 | wIndex); |
922 | if (temp) | 924 | if (temp) |
923 | usb_acpi_set_power_state(hcd->self.root_hub, | 925 | usb_acpi_set_power_state(hcd->self.root_hub, |
924 | wIndex, false); | 926 | wIndex, false); |
927 | spin_lock_irqsave(&xhci->lock, flags); | ||
925 | break; | 928 | break; |
926 | default: | 929 | default: |
927 | goto error; | 930 | 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) | |||
1228 | cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, | 1228 | cur_seg = find_trb_seg(xhci->cmd_ring->first_seg, |
1229 | xhci->cmd_ring->dequeue, &cycle_state); | 1229 | xhci->cmd_ring->dequeue, &cycle_state); |
1230 | 1230 | ||
1231 | if (!cur_seg) { | ||
1232 | xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n", | ||
1233 | xhci->cmd_ring->dequeue, | ||
1234 | (unsigned long long) | ||
1235 | xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, | ||
1236 | xhci->cmd_ring->dequeue)); | ||
1237 | xhci_debug_ring(xhci, xhci->cmd_ring); | ||
1238 | xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring); | ||
1239 | return; | ||
1240 | } | ||
1241 | |||
1231 | /* find the command trb matched by cd from command ring */ | 1242 | /* find the command trb matched by cd from command ring */ |
1232 | for (cmd_trb = xhci->cmd_ring->dequeue; | 1243 | for (cmd_trb = xhci->cmd_ring->dequeue; |
1233 | cmd_trb != xhci->cmd_ring->enqueue; | 1244 | 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, | |||
1627 | struct xhci_hcd *xhci; | 1627 | struct xhci_hcd *xhci; |
1628 | struct xhci_container_ctx *in_ctx, *out_ctx; | 1628 | struct xhci_container_ctx *in_ctx, *out_ctx; |
1629 | unsigned int ep_index; | 1629 | unsigned int ep_index; |
1630 | struct xhci_ep_ctx *ep_ctx; | ||
1631 | struct xhci_slot_ctx *slot_ctx; | 1630 | struct xhci_slot_ctx *slot_ctx; |
1632 | struct xhci_input_control_ctx *ctrl_ctx; | 1631 | struct xhci_input_control_ctx *ctrl_ctx; |
1633 | u32 added_ctxs; | 1632 | u32 added_ctxs; |
@@ -1663,7 +1662,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev, | |||
1663 | out_ctx = virt_dev->out_ctx; | 1662 | out_ctx = virt_dev->out_ctx; |
1664 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); | 1663 | ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx); |
1665 | ep_index = xhci_get_endpoint_index(&ep->desc); | 1664 | ep_index = xhci_get_endpoint_index(&ep->desc); |
1666 | ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index); | ||
1667 | 1665 | ||
1668 | /* If this endpoint is already in use, and the upper layers are trying | 1666 | /* If this endpoint is already in use, and the upper layers are trying |
1669 | * to add it again without dropping it, reject the addition. | 1667 | * to add it again without dropping it, reject the addition. |
@@ -1817,6 +1815,8 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci, | |||
1817 | case COMP_EBADSLT: | 1815 | case COMP_EBADSLT: |
1818 | dev_warn(&udev->dev, "WARN: slot not enabled for" | 1816 | dev_warn(&udev->dev, "WARN: slot not enabled for" |
1819 | "evaluate context command.\n"); | 1817 | "evaluate context command.\n"); |
1818 | ret = -EINVAL; | ||
1819 | break; | ||
1820 | case COMP_CTX_STATE: | 1820 | case COMP_CTX_STATE: |
1821 | dev_warn(&udev->dev, "WARN: invalid context state for " | 1821 | dev_warn(&udev->dev, "WARN: invalid context state for " |
1822 | "evaluate context command.\n"); | 1822 | "evaluate context command.\n"); |
@@ -4021,7 +4021,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev) | |||
4021 | static unsigned long long xhci_service_interval_to_ns( | 4021 | static unsigned long long xhci_service_interval_to_ns( |
4022 | struct usb_endpoint_descriptor *desc) | 4022 | struct usb_endpoint_descriptor *desc) |
4023 | { | 4023 | { |
4024 | return (1 << (desc->bInterval - 1)) * 125 * 1000; | 4024 | return (1ULL << (desc->bInterval - 1)) * 125 * 1000; |
4025 | } | 4025 | } |
4026 | 4026 | ||
4027 | static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev, | 4027 | 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, | |||
4142 | (xhci_service_interval_to_ns(desc) > timeout_ns)) | 4142 | (xhci_service_interval_to_ns(desc) > timeout_ns)) |
4143 | timeout_ns = xhci_service_interval_to_ns(desc); | 4143 | timeout_ns = xhci_service_interval_to_ns(desc); |
4144 | 4144 | ||
4145 | u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000; | 4145 | u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL; |
4146 | if (u2_del_ns > timeout_ns) | 4146 | if (u2_del_ns > timeout_ns) |
4147 | timeout_ns = u2_del_ns; | 4147 | timeout_ns = u2_del_ns; |
4148 | 4148 | ||
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, | |||
158 | } | 158 | } |
159 | EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download); | 159 | EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download); |
160 | 160 | ||
161 | 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) | |||
458 | struct platform_device *musb; | 458 | struct platform_device *musb; |
459 | struct resource *res; | 459 | struct resource *res; |
460 | struct resource resources[2]; | 460 | struct resource resources[2]; |
461 | char res_name[10]; | 461 | char res_name[11]; |
462 | int ret, musbid; | 462 | int ret, musbid; |
463 | 463 | ||
464 | /* get memory resource */ | 464 | /* get memory resource */ |
465 | sprintf(res_name, "musb%d", id); | 465 | snprintf(res_name, sizeof(res_name), "musb%d", id); |
466 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); | 466 | res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name); |
467 | if (!res) { | 467 | if (!res) { |
468 | dev_err(dev, "%s get mem resource failed\n", res_name); | 468 | 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) | |||
473 | resources[0] = *res; | 473 | resources[0] = *res; |
474 | 474 | ||
475 | /* get irq resource */ | 475 | /* get irq resource */ |
476 | sprintf(res_name, "musb%d-irq", id); | 476 | snprintf(res_name, sizeof(res_name), "musb%d-irq", id); |
477 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); | 477 | res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name); |
478 | if (!res) { | 478 | if (!res) { |
479 | dev_err(dev, "%s get irq resource failed\n", res_name); | 479 | 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) | |||
530 | 530 | ||
531 | of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps); | 531 | of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps); |
532 | of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); | 532 | of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits); |
533 | sprintf(res_name, "port%d-mode", id); | 533 | snprintf(res_name, sizeof(res_name), "port%d-mode", id); |
534 | of_property_read_u32(np, res_name, (u32 *)&pdata->mode); | 534 | of_property_read_u32(np, res_name, (u32 *)&pdata->mode); |
535 | of_property_read_u32(np, "power", (u32 *)&pdata->power); | 535 | of_property_read_u32(np, "power", (u32 *)&pdata->power); |
536 | config->multipoint = of_property_read_bool(np, "multipoint"); | 536 | 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) | |||
795 | dev_dbg(dev, " %s %d (%d/ %d)\n", | 795 | dev_dbg(dev, " %s %d (%d/ %d)\n", |
796 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); | 796 | fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero); |
797 | 797 | ||
798 | usbhs_pipe_enable(pipe); | ||
798 | usbhsf_dma_start(pipe, fifo); | 799 | usbhsf_dma_start(pipe, fifo); |
799 | dma_async_issue_pending(chan); | 800 | dma_async_issue_pending(chan); |
800 | } | 801 | } |
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, | |||
334 | struct device *dev = usbhs_priv_to_dev(priv); | 334 | struct device *dev = usbhs_priv_to_dev(priv); |
335 | unsigned long flags; | 335 | unsigned long flags; |
336 | 336 | ||
337 | if (unlikely(!uep)) { | ||
338 | dev_err(dev, "no uep\n"); | ||
339 | return; | ||
340 | } | ||
341 | |||
337 | /******************** spin lock ********************/ | 342 | /******************** spin lock ********************/ |
338 | usbhs_lock(priv, flags); | 343 | usbhs_lock(priv, flags); |
339 | 344 | ||
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); | |||
242 | return r; | 242 | return r; |
243 | } | 243 | } |
244 | 244 | ||
245 | /* allocate private data */ | 245 | static int ch341_port_probe(struct usb_serial_port *port) |
246 | static int ch341_attach(struct usb_serial *serial) | ||
247 | { | 246 | { |
248 | struct ch341_private *priv; | 247 | struct ch341_private *priv; |
249 | int r; | 248 | int r; |
250 | 249 | ||
251 | /* private data */ | ||
252 | priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); | 250 | priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL); |
253 | if (!priv) | 251 | if (!priv) |
254 | return -ENOMEM; | 252 | return -ENOMEM; |
@@ -258,17 +256,27 @@ static int ch341_attach(struct usb_serial *serial) | |||
258 | priv->baud_rate = DEFAULT_BAUD_RATE; | 256 | priv->baud_rate = DEFAULT_BAUD_RATE; |
259 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; | 257 | priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR; |
260 | 258 | ||
261 | r = ch341_configure(serial->dev, priv); | 259 | r = ch341_configure(port->serial->dev, priv); |
262 | if (r < 0) | 260 | if (r < 0) |
263 | goto error; | 261 | goto error; |
264 | 262 | ||
265 | usb_set_serial_port_data(serial->port[0], priv); | 263 | usb_set_serial_port_data(port, priv); |
266 | return 0; | 264 | return 0; |
267 | 265 | ||
268 | error: kfree(priv); | 266 | error: kfree(priv); |
269 | return r; | 267 | return r; |
270 | } | 268 | } |
271 | 269 | ||
270 | static int ch341_port_remove(struct usb_serial_port *port) | ||
271 | { | ||
272 | struct ch341_private *priv; | ||
273 | |||
274 | priv = usb_get_serial_port_data(port); | ||
275 | kfree(priv); | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
272 | static int ch341_carrier_raised(struct usb_serial_port *port) | 280 | static int ch341_carrier_raised(struct usb_serial_port *port) |
273 | { | 281 | { |
274 | struct ch341_private *priv = usb_get_serial_port_data(port); | 282 | struct ch341_private *priv = usb_get_serial_port_data(port); |
@@ -304,7 +312,7 @@ static void ch341_close(struct usb_serial_port *port) | |||
304 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) | 312 | static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port) |
305 | { | 313 | { |
306 | struct usb_serial *serial = port->serial; | 314 | struct usb_serial *serial = port->serial; |
307 | struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]); | 315 | struct ch341_private *priv = usb_get_serial_port_data(port); |
308 | int r; | 316 | int r; |
309 | 317 | ||
310 | priv->baud_rate = DEFAULT_BAUD_RATE; | 318 | priv->baud_rate = DEFAULT_BAUD_RATE; |
@@ -608,7 +616,8 @@ static struct usb_serial_driver ch341_device = { | |||
608 | .tiocmget = ch341_tiocmget, | 616 | .tiocmget = ch341_tiocmget, |
609 | .tiocmset = ch341_tiocmset, | 617 | .tiocmset = ch341_tiocmset, |
610 | .read_int_callback = ch341_read_int_callback, | 618 | .read_int_callback = ch341_read_int_callback, |
611 | .attach = ch341_attach, | 619 | .port_probe = ch341_port_probe, |
620 | .port_remove = ch341_port_remove, | ||
612 | .reset_resume = ch341_reset_resume, | 621 | .reset_resume = ch341_reset_resume, |
613 | }; | 622 | }; |
614 | 623 | ||
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); | |||
244 | static int digi_startup(struct usb_serial *serial); | 244 | static int digi_startup(struct usb_serial *serial); |
245 | static void digi_disconnect(struct usb_serial *serial); | 245 | static void digi_disconnect(struct usb_serial *serial); |
246 | static void digi_release(struct usb_serial *serial); | 246 | static void digi_release(struct usb_serial *serial); |
247 | static int digi_port_probe(struct usb_serial_port *port); | ||
248 | static int digi_port_remove(struct usb_serial_port *port); | ||
247 | static void digi_read_bulk_callback(struct urb *urb); | 249 | static void digi_read_bulk_callback(struct urb *urb); |
248 | static int digi_read_inb_callback(struct urb *urb); | 250 | static int digi_read_inb_callback(struct urb *urb); |
249 | static int digi_read_oob_callback(struct urb *urb); | 251 | static int digi_read_oob_callback(struct urb *urb); |
@@ -294,6 +296,8 @@ static struct usb_serial_driver digi_acceleport_2_device = { | |||
294 | .attach = digi_startup, | 296 | .attach = digi_startup, |
295 | .disconnect = digi_disconnect, | 297 | .disconnect = digi_disconnect, |
296 | .release = digi_release, | 298 | .release = digi_release, |
299 | .port_probe = digi_port_probe, | ||
300 | .port_remove = digi_port_remove, | ||
297 | }; | 301 | }; |
298 | 302 | ||
299 | static struct usb_serial_driver digi_acceleport_4_device = { | 303 | static struct usb_serial_driver digi_acceleport_4_device = { |
@@ -320,6 +324,8 @@ static struct usb_serial_driver digi_acceleport_4_device = { | |||
320 | .attach = digi_startup, | 324 | .attach = digi_startup, |
321 | .disconnect = digi_disconnect, | 325 | .disconnect = digi_disconnect, |
322 | .release = digi_release, | 326 | .release = digi_release, |
327 | .port_probe = digi_port_probe, | ||
328 | .port_remove = digi_port_remove, | ||
323 | }; | 329 | }; |
324 | 330 | ||
325 | static struct usb_serial_driver * const serial_drivers[] = { | 331 | static struct usb_serial_driver * const serial_drivers[] = { |
@@ -1240,59 +1246,50 @@ static int digi_startup_device(struct usb_serial *serial) | |||
1240 | return ret; | 1246 | return ret; |
1241 | } | 1247 | } |
1242 | 1248 | ||
1243 | 1249 | static int digi_port_init(struct usb_serial_port *port, unsigned port_num) | |
1244 | static int digi_startup(struct usb_serial *serial) | ||
1245 | { | 1250 | { |
1246 | |||
1247 | int i; | ||
1248 | struct digi_port *priv; | 1251 | struct digi_port *priv; |
1249 | struct digi_serial *serial_priv; | ||
1250 | 1252 | ||
1251 | /* allocate the private data structures for all ports */ | 1253 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
1252 | /* number of regular ports + 1 for the out-of-band port */ | 1254 | if (!priv) |
1253 | for (i = 0; i < serial->type->num_ports + 1; i++) { | 1255 | return -ENOMEM; |
1254 | /* allocate port private structure */ | ||
1255 | priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL); | ||
1256 | if (priv == NULL) { | ||
1257 | while (--i >= 0) | ||
1258 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
1259 | return 1; /* error */ | ||
1260 | } | ||
1261 | 1256 | ||
1262 | /* initialize port private structure */ | 1257 | spin_lock_init(&priv->dp_port_lock); |
1263 | spin_lock_init(&priv->dp_port_lock); | 1258 | priv->dp_port_num = port_num; |
1264 | priv->dp_port_num = i; | 1259 | init_waitqueue_head(&priv->dp_modem_change_wait); |
1265 | priv->dp_out_buf_len = 0; | 1260 | init_waitqueue_head(&priv->dp_transmit_idle_wait); |
1266 | priv->dp_write_urb_in_use = 0; | 1261 | init_waitqueue_head(&priv->dp_flush_wait); |
1267 | priv->dp_modem_signals = 0; | 1262 | init_waitqueue_head(&priv->dp_close_wait); |
1268 | init_waitqueue_head(&priv->dp_modem_change_wait); | 1263 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); |
1269 | priv->dp_transmit_idle = 0; | 1264 | priv->dp_port = port; |
1270 | init_waitqueue_head(&priv->dp_transmit_idle_wait); | ||
1271 | priv->dp_throttled = 0; | ||
1272 | priv->dp_throttle_restart = 0; | ||
1273 | init_waitqueue_head(&priv->dp_flush_wait); | ||
1274 | init_waitqueue_head(&priv->dp_close_wait); | ||
1275 | INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock); | ||
1276 | priv->dp_port = serial->port[i]; | ||
1277 | /* initialize write wait queue for this port */ | ||
1278 | init_waitqueue_head(&serial->port[i]->write_wait); | ||
1279 | |||
1280 | usb_set_serial_port_data(serial->port[i], priv); | ||
1281 | } | ||
1282 | 1265 | ||
1283 | /* allocate serial private structure */ | 1266 | init_waitqueue_head(&port->write_wait); |
1284 | serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL); | 1267 | |
1285 | if (serial_priv == NULL) { | 1268 | usb_set_serial_port_data(port, priv); |
1286 | for (i = 0; i < serial->type->num_ports + 1; i++) | 1269 | |
1287 | kfree(usb_get_serial_port_data(serial->port[i])); | 1270 | return 0; |
1288 | return 1; /* error */ | 1271 | } |
1289 | } | 1272 | |
1273 | static int digi_startup(struct usb_serial *serial) | ||
1274 | { | ||
1275 | struct digi_serial *serial_priv; | ||
1276 | int ret; | ||
1277 | |||
1278 | serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL); | ||
1279 | if (!serial_priv) | ||
1280 | return -ENOMEM; | ||
1290 | 1281 | ||
1291 | /* initialize serial private structure */ | ||
1292 | spin_lock_init(&serial_priv->ds_serial_lock); | 1282 | spin_lock_init(&serial_priv->ds_serial_lock); |
1293 | serial_priv->ds_oob_port_num = serial->type->num_ports; | 1283 | serial_priv->ds_oob_port_num = serial->type->num_ports; |
1294 | serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; | 1284 | serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num]; |
1295 | serial_priv->ds_device_started = 0; | 1285 | |
1286 | ret = digi_port_init(serial_priv->ds_oob_port, | ||
1287 | serial_priv->ds_oob_port_num); | ||
1288 | if (ret) { | ||
1289 | kfree(serial_priv); | ||
1290 | return ret; | ||
1291 | } | ||
1292 | |||
1296 | usb_set_serial_data(serial, serial_priv); | 1293 | usb_set_serial_data(serial, serial_priv); |
1297 | 1294 | ||
1298 | return 0; | 1295 | return 0; |
@@ -1313,15 +1310,35 @@ static void digi_disconnect(struct usb_serial *serial) | |||
1313 | 1310 | ||
1314 | static void digi_release(struct usb_serial *serial) | 1311 | static void digi_release(struct usb_serial *serial) |
1315 | { | 1312 | { |
1316 | int i; | 1313 | struct digi_serial *serial_priv; |
1314 | struct digi_port *priv; | ||
1315 | |||
1316 | serial_priv = usb_get_serial_data(serial); | ||
1317 | |||
1318 | priv = usb_get_serial_port_data(serial_priv->ds_oob_port); | ||
1319 | kfree(priv); | ||
1317 | 1320 | ||
1318 | /* free the private data structures for all ports */ | 1321 | kfree(serial_priv); |
1319 | /* number of regular ports + 1 for the out-of-band port */ | ||
1320 | for (i = 0; i < serial->type->num_ports + 1; i++) | ||
1321 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
1322 | kfree(usb_get_serial_data(serial)); | ||
1323 | } | 1322 | } |
1324 | 1323 | ||
1324 | static int digi_port_probe(struct usb_serial_port *port) | ||
1325 | { | ||
1326 | unsigned port_num; | ||
1327 | |||
1328 | port_num = port->number - port->serial->minor; | ||
1329 | |||
1330 | return digi_port_init(port, port_num); | ||
1331 | } | ||
1332 | |||
1333 | static int digi_port_remove(struct usb_serial_port *port) | ||
1334 | { | ||
1335 | struct digi_port *priv; | ||
1336 | |||
1337 | priv = usb_get_serial_port_data(port); | ||
1338 | kfree(priv); | ||
1339 | |||
1340 | return 0; | ||
1341 | } | ||
1325 | 1342 | ||
1326 | static void digi_read_bulk_callback(struct urb *urb) | 1343 | static void digi_read_bulk_callback(struct urb *urb) |
1327 | { | 1344 | { |
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) | |||
203 | return 0; | 203 | return 0; |
204 | } | 204 | } |
205 | 205 | ||
206 | /* fake probe - only to allocate data structures */ | 206 | static int ipw_attach(struct usb_serial *serial) |
207 | static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id) | ||
208 | { | 207 | { |
209 | struct usb_wwan_intf_private *data; | 208 | struct usb_wwan_intf_private *data; |
210 | 209 | ||
@@ -303,9 +302,9 @@ static struct usb_serial_driver ipw_device = { | |||
303 | .num_ports = 1, | 302 | .num_ports = 1, |
304 | .open = ipw_open, | 303 | .open = ipw_open, |
305 | .close = ipw_close, | 304 | .close = ipw_close, |
306 | .probe = ipw_probe, | 305 | .attach = ipw_attach, |
307 | .attach = usb_wwan_startup, | ||
308 | .release = ipw_release, | 306 | .release = ipw_release, |
307 | .port_probe = usb_wwan_port_probe, | ||
309 | .port_remove = usb_wwan_port_remove, | 308 | .port_remove = usb_wwan_port_remove, |
310 | .dtr_rts = ipw_dtr_rts, | 309 | .dtr_rts = ipw_dtr_rts, |
311 | .write = usb_wwan_write, | 310 | .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 { | |||
1374 | data in device_details */ | 1374 | data in device_details */ |
1375 | static void keyspan_setup_urbs(struct usb_serial *serial) | 1375 | static void keyspan_setup_urbs(struct usb_serial *serial) |
1376 | { | 1376 | { |
1377 | int i, j; | ||
1378 | struct keyspan_serial_private *s_priv; | 1377 | struct keyspan_serial_private *s_priv; |
1379 | const struct keyspan_device_details *d_details; | 1378 | const struct keyspan_device_details *d_details; |
1380 | struct usb_serial_port *port; | ||
1381 | struct keyspan_port_private *p_priv; | ||
1382 | struct callbacks *cback; | 1379 | struct callbacks *cback; |
1383 | int endp; | ||
1384 | 1380 | ||
1385 | s_priv = usb_get_serial_data(serial); | 1381 | s_priv = usb_get_serial_data(serial); |
1386 | d_details = s_priv->device_details; | 1382 | d_details = s_priv->device_details; |
@@ -1404,45 +1400,6 @@ static void keyspan_setup_urbs(struct usb_serial *serial) | |||
1404 | (serial, d_details->glocont_endpoint, USB_DIR_OUT, | 1400 | (serial, d_details->glocont_endpoint, USB_DIR_OUT, |
1405 | serial, s_priv->glocont_buf, GLOCONT_BUFLEN, | 1401 | serial, s_priv->glocont_buf, GLOCONT_BUFLEN, |
1406 | cback->glocont_callback); | 1402 | cback->glocont_callback); |
1407 | |||
1408 | /* Setup endpoints for each port specific thing */ | ||
1409 | for (i = 0; i < d_details->num_ports; i++) { | ||
1410 | port = serial->port[i]; | ||
1411 | p_priv = usb_get_serial_port_data(port); | ||
1412 | |||
1413 | /* Do indat endpoints first, once for each flip */ | ||
1414 | endp = d_details->indat_endpoints[i]; | ||
1415 | for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) { | ||
1416 | p_priv->in_urbs[j] = keyspan_setup_urb | ||
1417 | (serial, endp, USB_DIR_IN, port, | ||
1418 | p_priv->in_buffer[j], 64, | ||
1419 | cback->indat_callback); | ||
1420 | } | ||
1421 | for (; j < 2; ++j) | ||
1422 | p_priv->in_urbs[j] = NULL; | ||
1423 | |||
1424 | /* outdat endpoints also have flip */ | ||
1425 | endp = d_details->outdat_endpoints[i]; | ||
1426 | for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) { | ||
1427 | p_priv->out_urbs[j] = keyspan_setup_urb | ||
1428 | (serial, endp, USB_DIR_OUT, port, | ||
1429 | p_priv->out_buffer[j], 64, | ||
1430 | cback->outdat_callback); | ||
1431 | } | ||
1432 | for (; j < 2; ++j) | ||
1433 | p_priv->out_urbs[j] = NULL; | ||
1434 | |||
1435 | /* inack endpoint */ | ||
1436 | p_priv->inack_urb = keyspan_setup_urb | ||
1437 | (serial, d_details->inack_endpoints[i], USB_DIR_IN, | ||
1438 | port, p_priv->inack_buffer, 1, cback->inack_callback); | ||
1439 | |||
1440 | /* outcont endpoint */ | ||
1441 | p_priv->outcont_urb = keyspan_setup_urb | ||
1442 | (serial, d_details->outcont_endpoints[i], USB_DIR_OUT, | ||
1443 | port, p_priv->outcont_buffer, 64, | ||
1444 | cback->outcont_callback); | ||
1445 | } | ||
1446 | } | 1403 | } |
1447 | 1404 | ||
1448 | /* usa19 function doesn't require prescaler */ | 1405 | /* usa19 function doesn't require prescaler */ |
@@ -2407,9 +2364,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port) | |||
2407 | static int keyspan_startup(struct usb_serial *serial) | 2364 | static int keyspan_startup(struct usb_serial *serial) |
2408 | { | 2365 | { |
2409 | int i, err; | 2366 | int i, err; |
2410 | struct usb_serial_port *port; | ||
2411 | struct keyspan_serial_private *s_priv; | 2367 | struct keyspan_serial_private *s_priv; |
2412 | struct keyspan_port_private *p_priv; | ||
2413 | const struct keyspan_device_details *d_details; | 2368 | const struct keyspan_device_details *d_details; |
2414 | 2369 | ||
2415 | for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) | 2370 | for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i) |
@@ -2432,19 +2387,6 @@ static int keyspan_startup(struct usb_serial *serial) | |||
2432 | s_priv->device_details = d_details; | 2387 | s_priv->device_details = d_details; |
2433 | usb_set_serial_data(serial, s_priv); | 2388 | usb_set_serial_data(serial, s_priv); |
2434 | 2389 | ||
2435 | /* Now setup per port private data */ | ||
2436 | for (i = 0; i < serial->num_ports; i++) { | ||
2437 | port = serial->port[i]; | ||
2438 | p_priv = kzalloc(sizeof(struct keyspan_port_private), | ||
2439 | GFP_KERNEL); | ||
2440 | if (!p_priv) { | ||
2441 | dev_dbg(&port->dev, "%s - kmalloc for keyspan_port_private (%d) failed!.\n", __func__, i); | ||
2442 | return 1; | ||
2443 | } | ||
2444 | p_priv->device_details = d_details; | ||
2445 | usb_set_serial_port_data(port, p_priv); | ||
2446 | } | ||
2447 | |||
2448 | keyspan_setup_urbs(serial); | 2390 | keyspan_setup_urbs(serial); |
2449 | 2391 | ||
2450 | if (s_priv->instat_urb != NULL) { | 2392 | if (s_priv->instat_urb != NULL) { |
@@ -2463,59 +2405,112 @@ static int keyspan_startup(struct usb_serial *serial) | |||
2463 | 2405 | ||
2464 | static void keyspan_disconnect(struct usb_serial *serial) | 2406 | static void keyspan_disconnect(struct usb_serial *serial) |
2465 | { | 2407 | { |
2466 | int i, j; | 2408 | struct keyspan_serial_private *s_priv; |
2467 | struct usb_serial_port *port; | ||
2468 | struct keyspan_serial_private *s_priv; | ||
2469 | struct keyspan_port_private *p_priv; | ||
2470 | 2409 | ||
2471 | s_priv = usb_get_serial_data(serial); | 2410 | s_priv = usb_get_serial_data(serial); |
2472 | 2411 | ||
2473 | /* Stop reading/writing urbs */ | ||
2474 | stop_urb(s_priv->instat_urb); | 2412 | stop_urb(s_priv->instat_urb); |
2475 | stop_urb(s_priv->glocont_urb); | 2413 | stop_urb(s_priv->glocont_urb); |
2476 | stop_urb(s_priv->indat_urb); | 2414 | stop_urb(s_priv->indat_urb); |
2477 | for (i = 0; i < serial->num_ports; ++i) { | 2415 | } |
2478 | port = serial->port[i]; | 2416 | |
2479 | p_priv = usb_get_serial_port_data(port); | 2417 | static void keyspan_release(struct usb_serial *serial) |
2480 | stop_urb(p_priv->inack_urb); | 2418 | { |
2481 | stop_urb(p_priv->outcont_urb); | 2419 | struct keyspan_serial_private *s_priv; |
2482 | for (j = 0; j < 2; j++) { | 2420 | |
2483 | stop_urb(p_priv->in_urbs[j]); | 2421 | s_priv = usb_get_serial_data(serial); |
2484 | stop_urb(p_priv->out_urbs[j]); | ||
2485 | } | ||
2486 | } | ||
2487 | 2422 | ||
2488 | /* Now free them */ | ||
2489 | usb_free_urb(s_priv->instat_urb); | 2423 | usb_free_urb(s_priv->instat_urb); |
2490 | usb_free_urb(s_priv->indat_urb); | 2424 | usb_free_urb(s_priv->indat_urb); |
2491 | usb_free_urb(s_priv->glocont_urb); | 2425 | usb_free_urb(s_priv->glocont_urb); |
2492 | for (i = 0; i < serial->num_ports; ++i) { | 2426 | |
2493 | port = serial->port[i]; | 2427 | kfree(s_priv); |
2494 | p_priv = usb_get_serial_port_data(port); | ||
2495 | usb_free_urb(p_priv->inack_urb); | ||
2496 | usb_free_urb(p_priv->outcont_urb); | ||
2497 | for (j = 0; j < 2; j++) { | ||
2498 | usb_free_urb(p_priv->in_urbs[j]); | ||
2499 | usb_free_urb(p_priv->out_urbs[j]); | ||
2500 | } | ||
2501 | } | ||
2502 | } | 2428 | } |
2503 | 2429 | ||
2504 | static void keyspan_release(struct usb_serial *serial) | 2430 | static int keyspan_port_probe(struct usb_serial_port *port) |
2505 | { | 2431 | { |
2506 | int i; | 2432 | struct usb_serial *serial = port->serial; |
2507 | struct usb_serial_port *port; | 2433 | struct keyspan_port_private *s_priv; |
2508 | struct keyspan_serial_private *s_priv; | 2434 | struct keyspan_port_private *p_priv; |
2435 | const struct keyspan_device_details *d_details; | ||
2436 | struct callbacks *cback; | ||
2437 | int endp; | ||
2438 | int port_num; | ||
2439 | int i; | ||
2509 | 2440 | ||
2510 | s_priv = usb_get_serial_data(serial); | 2441 | s_priv = usb_get_serial_data(serial); |
2442 | d_details = s_priv->device_details; | ||
2511 | 2443 | ||
2512 | kfree(s_priv); | 2444 | p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL); |
2445 | if (!p_priv) | ||
2446 | return -ENOMEM; | ||
2513 | 2447 | ||
2514 | /* Now free per port private data */ | 2448 | s_priv = usb_get_serial_data(port->serial); |
2515 | for (i = 0; i < serial->num_ports; i++) { | 2449 | p_priv->device_details = d_details; |
2516 | port = serial->port[i]; | 2450 | |
2517 | kfree(usb_get_serial_port_data(port)); | 2451 | /* Setup values for the various callback routines */ |
2452 | cback = &keyspan_callbacks[d_details->msg_format]; | ||
2453 | |||
2454 | port_num = port->number - port->serial->minor; | ||
2455 | |||
2456 | /* Do indat endpoints first, once for each flip */ | ||
2457 | endp = d_details->indat_endpoints[port_num]; | ||
2458 | for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) { | ||
2459 | p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp, | ||
2460 | USB_DIR_IN, port, | ||
2461 | p_priv->in_buffer[i], 64, | ||
2462 | cback->indat_callback); | ||
2463 | } | ||
2464 | /* outdat endpoints also have flip */ | ||
2465 | endp = d_details->outdat_endpoints[port_num]; | ||
2466 | for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) { | ||
2467 | p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp, | ||
2468 | USB_DIR_OUT, port, | ||
2469 | p_priv->out_buffer[i], 64, | ||
2470 | cback->outdat_callback); | ||
2471 | } | ||
2472 | /* inack endpoint */ | ||
2473 | p_priv->inack_urb = keyspan_setup_urb(serial, | ||
2474 | d_details->inack_endpoints[port_num], | ||
2475 | USB_DIR_IN, port, | ||
2476 | p_priv->inack_buffer, 1, | ||
2477 | cback->inack_callback); | ||
2478 | /* outcont endpoint */ | ||
2479 | p_priv->outcont_urb = keyspan_setup_urb(serial, | ||
2480 | d_details->outcont_endpoints[port_num], | ||
2481 | USB_DIR_OUT, port, | ||
2482 | p_priv->outcont_buffer, 64, | ||
2483 | cback->outcont_callback); | ||
2484 | |||
2485 | usb_set_serial_port_data(port, p_priv); | ||
2486 | |||
2487 | return 0; | ||
2488 | } | ||
2489 | |||
2490 | static int keyspan_port_remove(struct usb_serial_port *port) | ||
2491 | { | ||
2492 | struct keyspan_port_private *p_priv; | ||
2493 | int i; | ||
2494 | |||
2495 | p_priv = usb_get_serial_port_data(port); | ||
2496 | |||
2497 | stop_urb(p_priv->inack_urb); | ||
2498 | stop_urb(p_priv->outcont_urb); | ||
2499 | for (i = 0; i < 2; i++) { | ||
2500 | stop_urb(p_priv->in_urbs[i]); | ||
2501 | stop_urb(p_priv->out_urbs[i]); | ||
2502 | } | ||
2503 | |||
2504 | usb_free_urb(p_priv->inack_urb); | ||
2505 | usb_free_urb(p_priv->outcont_urb); | ||
2506 | for (i = 0; i < 2; i++) { | ||
2507 | usb_free_urb(p_priv->in_urbs[i]); | ||
2508 | usb_free_urb(p_priv->out_urbs[i]); | ||
2518 | } | 2509 | } |
2510 | |||
2511 | kfree(p_priv); | ||
2512 | |||
2513 | return 0; | ||
2519 | } | 2514 | } |
2520 | 2515 | ||
2521 | MODULE_AUTHOR(DRIVER_AUTHOR); | 2516 | 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); | |||
42 | static int keyspan_startup (struct usb_serial *serial); | 42 | static int keyspan_startup (struct usb_serial *serial); |
43 | static void keyspan_disconnect (struct usb_serial *serial); | 43 | static void keyspan_disconnect (struct usb_serial *serial); |
44 | static void keyspan_release (struct usb_serial *serial); | 44 | static void keyspan_release (struct usb_serial *serial); |
45 | static int keyspan_port_probe(struct usb_serial_port *port); | ||
46 | static int keyspan_port_remove(struct usb_serial_port *port); | ||
45 | static int keyspan_write_room (struct tty_struct *tty); | 47 | static int keyspan_write_room (struct tty_struct *tty); |
46 | 48 | ||
47 | static int keyspan_write (struct tty_struct *tty, | 49 | static int keyspan_write (struct tty_struct *tty, |
@@ -567,6 +569,8 @@ static struct usb_serial_driver keyspan_1port_device = { | |||
567 | .attach = keyspan_startup, | 569 | .attach = keyspan_startup, |
568 | .disconnect = keyspan_disconnect, | 570 | .disconnect = keyspan_disconnect, |
569 | .release = keyspan_release, | 571 | .release = keyspan_release, |
572 | .port_probe = keyspan_port_probe, | ||
573 | .port_remove = keyspan_port_remove, | ||
570 | }; | 574 | }; |
571 | 575 | ||
572 | static struct usb_serial_driver keyspan_2port_device = { | 576 | static struct usb_serial_driver keyspan_2port_device = { |
@@ -589,6 +593,8 @@ static struct usb_serial_driver keyspan_2port_device = { | |||
589 | .attach = keyspan_startup, | 593 | .attach = keyspan_startup, |
590 | .disconnect = keyspan_disconnect, | 594 | .disconnect = keyspan_disconnect, |
591 | .release = keyspan_release, | 595 | .release = keyspan_release, |
596 | .port_probe = keyspan_port_probe, | ||
597 | .port_remove = keyspan_port_remove, | ||
592 | }; | 598 | }; |
593 | 599 | ||
594 | static struct usb_serial_driver keyspan_4port_device = { | 600 | static struct usb_serial_driver keyspan_4port_device = { |
@@ -611,6 +617,8 @@ static struct usb_serial_driver keyspan_4port_device = { | |||
611 | .attach = keyspan_startup, | 617 | .attach = keyspan_startup, |
612 | .disconnect = keyspan_disconnect, | 618 | .disconnect = keyspan_disconnect, |
613 | .release = keyspan_release, | 619 | .release = keyspan_release, |
620 | .port_probe = keyspan_port_probe, | ||
621 | .port_remove = keyspan_port_remove, | ||
614 | }; | 622 | }; |
615 | 623 | ||
616 | static struct usb_serial_driver * const serial_drivers[] = { | 624 | 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/drivers/usb/serial/mct_u232.c +++ b/drivers/usb/serial/mct_u232.c | |||
@@ -49,7 +49,8 @@ | |||
49 | * Function prototypes | 49 | * Function prototypes |
50 | */ | 50 | */ |
51 | static int mct_u232_startup(struct usb_serial *serial); | 51 | static int mct_u232_startup(struct usb_serial *serial); |
52 | static void mct_u232_release(struct usb_serial *serial); | 52 | static int mct_u232_port_probe(struct usb_serial_port *port); |
53 | static int mct_u232_port_remove(struct usb_serial_port *remove); | ||
53 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); | 54 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port); |
54 | static void mct_u232_close(struct usb_serial_port *port); | 55 | static void mct_u232_close(struct usb_serial_port *port); |
55 | static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); | 56 | static void mct_u232_dtr_rts(struct usb_serial_port *port, int on); |
@@ -99,7 +100,8 @@ static struct usb_serial_driver mct_u232_device = { | |||
99 | .tiocmget = mct_u232_tiocmget, | 100 | .tiocmget = mct_u232_tiocmget, |
100 | .tiocmset = mct_u232_tiocmset, | 101 | .tiocmset = mct_u232_tiocmset, |
101 | .attach = mct_u232_startup, | 102 | .attach = mct_u232_startup, |
102 | .release = mct_u232_release, | 103 | .port_probe = mct_u232_port_probe, |
104 | .port_remove = mct_u232_port_remove, | ||
103 | .ioctl = mct_u232_ioctl, | 105 | .ioctl = mct_u232_ioctl, |
104 | .get_icount = mct_u232_get_icount, | 106 | .get_icount = mct_u232_get_icount, |
105 | }; | 107 | }; |
@@ -388,18 +390,8 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port, | |||
388 | 390 | ||
389 | static int mct_u232_startup(struct usb_serial *serial) | 391 | static int mct_u232_startup(struct usb_serial *serial) |
390 | { | 392 | { |
391 | struct mct_u232_private *priv; | ||
392 | struct usb_serial_port *port, *rport; | 393 | struct usb_serial_port *port, *rport; |
393 | 394 | ||
394 | priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL); | ||
395 | if (!priv) | ||
396 | return -ENOMEM; | ||
397 | spin_lock_init(&priv->lock); | ||
398 | init_waitqueue_head(&priv->msr_wait); | ||
399 | usb_set_serial_port_data(serial->port[0], priv); | ||
400 | |||
401 | init_waitqueue_head(&serial->port[0]->write_wait); | ||
402 | |||
403 | /* Puh, that's dirty */ | 395 | /* Puh, that's dirty */ |
404 | port = serial->port[0]; | 396 | port = serial->port[0]; |
405 | rport = serial->port[1]; | 397 | rport = serial->port[1]; |
@@ -412,18 +404,31 @@ static int mct_u232_startup(struct usb_serial *serial) | |||
412 | return 0; | 404 | return 0; |
413 | } /* mct_u232_startup */ | 405 | } /* mct_u232_startup */ |
414 | 406 | ||
407 | static int mct_u232_port_probe(struct usb_serial_port *port) | ||
408 | { | ||
409 | struct mct_u232_private *priv; | ||
410 | |||
411 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | ||
412 | if (!priv) | ||
413 | return -ENOMEM; | ||
414 | |||
415 | spin_lock_init(&priv->lock); | ||
416 | init_waitqueue_head(&priv->msr_wait); | ||
417 | |||
418 | usb_set_serial_port_data(port, priv); | ||
415 | 419 | ||
416 | static void mct_u232_release(struct usb_serial *serial) | 420 | return 0; |
421 | } | ||
422 | |||
423 | static int mct_u232_port_remove(struct usb_serial_port *port) | ||
417 | { | 424 | { |
418 | struct mct_u232_private *priv; | 425 | struct mct_u232_private *priv; |
419 | int i; | ||
420 | 426 | ||
421 | for (i = 0; i < serial->num_ports; ++i) { | 427 | priv = usb_get_serial_port_data(port); |
422 | /* My special items, the standard routines free my urbs */ | 428 | kfree(priv); |
423 | priv = usb_get_serial_port_data(serial->port[i]); | 429 | |
424 | kfree(priv); | 430 | return 0; |
425 | } | 431 | } |
426 | } /* mct_u232_release */ | ||
427 | 432 | ||
428 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) | 433 | static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port) |
429 | { | 434 | { |
@@ -515,12 +520,14 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on) | |||
515 | 520 | ||
516 | static void mct_u232_close(struct usb_serial_port *port) | 521 | static void mct_u232_close(struct usb_serial_port *port) |
517 | { | 522 | { |
518 | if (port->serial->dev) { | 523 | /* |
519 | /* shutdown our urbs */ | 524 | * Must kill the read urb as it is actually an interrupt urb, which |
520 | usb_kill_urb(port->write_urb); | 525 | * generic close thus fails to kill. |
521 | usb_kill_urb(port->read_urb); | 526 | */ |
522 | usb_kill_urb(port->interrupt_in_urb); | 527 | usb_kill_urb(port->read_urb); |
523 | } | 528 | usb_kill_urb(port->interrupt_in_urb); |
529 | |||
530 | usb_serial_generic_close(port); | ||
524 | } /* mct_u232_close */ | 531 | } /* mct_u232_close */ |
525 | 532 | ||
526 | 533 | ||
diff --git a/drivers/usb/serial/metro-usb.c b/drivers/usb/serial/metro-usb.c index 0b257ddffbdb..6f29c74eb769 100644 --- a/drivers/usb/serial/metro-usb.c +++ b/drivers/usb/serial/metro-usb.c | |||
@@ -179,16 +179,13 @@ static void metrousb_cleanup(struct usb_serial_port *port) | |||
179 | { | 179 | { |
180 | dev_dbg(&port->dev, "%s\n", __func__); | 180 | dev_dbg(&port->dev, "%s\n", __func__); |
181 | 181 | ||
182 | if (port->serial->dev) { | 182 | usb_unlink_urb(port->interrupt_in_urb); |
183 | /* Shutdown any interrupt in urbs. */ | 183 | usb_kill_urb(port->interrupt_in_urb); |
184 | if (port->interrupt_in_urb) { | 184 | |
185 | usb_unlink_urb(port->interrupt_in_urb); | 185 | mutex_lock(&port->serial->disc_mutex); |
186 | usb_kill_urb(port->interrupt_in_urb); | 186 | if (!port->serial->disconnected) |
187 | } | ||
188 | |||
189 | /* Send deactivate cmd to device */ | ||
190 | metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); | 187 | metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port); |
191 | } | 188 | mutex_unlock(&port->serial->disc_mutex); |
192 | } | 189 | } |
193 | 190 | ||
194 | static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) | 191 | static int metrousb_open(struct tty_struct *tty, struct usb_serial_port *port) |
@@ -271,51 +268,27 @@ static int metrousb_set_modem_ctrl(struct usb_serial *serial, unsigned int contr | |||
271 | return retval; | 268 | return retval; |
272 | } | 269 | } |
273 | 270 | ||
274 | static void metrousb_shutdown(struct usb_serial *serial) | 271 | static int metrousb_port_probe(struct usb_serial_port *port) |
275 | { | 272 | { |
276 | int i = 0; | 273 | struct metrousb_private *metro_priv; |
277 | 274 | ||
278 | dev_dbg(&serial->dev->dev, "%s\n", __func__); | 275 | metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL); |
276 | if (!metro_priv) | ||
277 | return -ENOMEM; | ||
279 | 278 | ||
280 | /* Stop reading and writing on all ports. */ | 279 | spin_lock_init(&metro_priv->lock); |
281 | for (i = 0; i < serial->num_ports; ++i) { | ||
282 | /* Close any open urbs. */ | ||
283 | metrousb_cleanup(serial->port[i]); | ||
284 | 280 | ||
285 | /* Free memory. */ | 281 | usb_set_serial_port_data(port, metro_priv); |
286 | kfree(usb_get_serial_port_data(serial->port[i])); | ||
287 | usb_set_serial_port_data(serial->port[i], NULL); | ||
288 | 282 | ||
289 | dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n", | 283 | return 0; |
290 | __func__, serial->port[i]->number); | ||
291 | } | ||
292 | } | 284 | } |
293 | 285 | ||
294 | static int metrousb_startup(struct usb_serial *serial) | 286 | static int metrousb_port_remove(struct usb_serial_port *port) |
295 | { | 287 | { |
296 | struct metrousb_private *metro_priv; | 288 | struct metrousb_private *metro_priv; |
297 | struct usb_serial_port *port; | ||
298 | int i = 0; | ||
299 | 289 | ||
300 | dev_dbg(&serial->dev->dev, "%s\n", __func__); | 290 | metro_priv = usb_get_serial_port_data(port); |
301 | 291 | kfree(metro_priv); | |
302 | /* Loop through the serial ports setting up the private structures. | ||
303 | * Currently we only use one port. */ | ||
304 | for (i = 0; i < serial->num_ports; ++i) { | ||
305 | port = serial->port[i]; | ||
306 | |||
307 | /* Declare memory. */ | ||
308 | metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL); | ||
309 | if (!metro_priv) | ||
310 | return -ENOMEM; | ||
311 | |||
312 | /* Initialize memory. */ | ||
313 | spin_lock_init(&metro_priv->lock); | ||
314 | usb_set_serial_port_data(port, metro_priv); | ||
315 | |||
316 | dev_dbg(&serial->dev->dev, "%s - port number=%d\n ", | ||
317 | __func__, port->number); | ||
318 | } | ||
319 | 292 | ||
320 | return 0; | 293 | return 0; |
321 | } | 294 | } |
@@ -414,8 +387,8 @@ static struct usb_serial_driver metrousb_device = { | |||
414 | .close = metrousb_cleanup, | 387 | .close = metrousb_cleanup, |
415 | .read_int_callback = metrousb_read_int_callback, | 388 | .read_int_callback = metrousb_read_int_callback, |
416 | .write_int_callback = metrousb_write_int_callback, | 389 | .write_int_callback = metrousb_write_int_callback, |
417 | .attach = metrousb_startup, | 390 | .port_probe = metrousb_port_probe, |
418 | .release = metrousb_shutdown, | 391 | .port_remove = metrousb_port_remove, |
419 | .throttle = metrousb_throttle, | 392 | .throttle = metrousb_throttle, |
420 | .unthrottle = metrousb_unthrottle, | 393 | .unthrottle = metrousb_unthrottle, |
421 | .tiocmget = metrousb_tiocmget, | 394 | .tiocmget = metrousb_tiocmget, |
diff --git a/drivers/usb/serial/mos7720.c b/drivers/usb/serial/mos7720.c index 1bf1ad066666..75267421aad8 100644 --- a/drivers/usb/serial/mos7720.c +++ b/drivers/usb/serial/mos7720.c | |||
@@ -1966,9 +1966,7 @@ static int mos7720_ioctl(struct tty_struct *tty, | |||
1966 | 1966 | ||
1967 | static int mos7720_startup(struct usb_serial *serial) | 1967 | static int mos7720_startup(struct usb_serial *serial) |
1968 | { | 1968 | { |
1969 | struct moschip_port *mos7720_port; | ||
1970 | struct usb_device *dev; | 1969 | struct usb_device *dev; |
1971 | int i; | ||
1972 | char data; | 1970 | char data; |
1973 | u16 product; | 1971 | u16 product; |
1974 | int ret_val; | 1972 | int ret_val; |
@@ -1999,29 +1997,6 @@ static int mos7720_startup(struct usb_serial *serial) | |||
1999 | serial->port[1]->interrupt_in_buffer = NULL; | 1997 | serial->port[1]->interrupt_in_buffer = NULL; |
2000 | } | 1998 | } |
2001 | 1999 | ||
2002 | |||
2003 | /* set up serial port private structures */ | ||
2004 | for (i = 0; i < serial->num_ports; ++i) { | ||
2005 | mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | ||
2006 | if (mos7720_port == NULL) { | ||
2007 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | ||
2008 | return -ENOMEM; | ||
2009 | } | ||
2010 | |||
2011 | /* Initialize all port interrupt end point to port 0 int | ||
2012 | * endpoint. Our device has only one interrupt endpoint | ||
2013 | * common to all ports */ | ||
2014 | serial->port[i]->interrupt_in_endpointAddress = | ||
2015 | serial->port[0]->interrupt_in_endpointAddress; | ||
2016 | |||
2017 | mos7720_port->port = serial->port[i]; | ||
2018 | usb_set_serial_port_data(serial->port[i], mos7720_port); | ||
2019 | |||
2020 | dev_dbg(&dev->dev, "port number is %d\n", serial->port[i]->number); | ||
2021 | dev_dbg(&dev->dev, "serial number is %d\n", serial->minor); | ||
2022 | } | ||
2023 | |||
2024 | |||
2025 | /* setting configuration feature to one */ | 2000 | /* setting configuration feature to one */ |
2026 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2001 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
2027 | (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); | 2002 | (__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ); |
@@ -2049,8 +2024,6 @@ static int mos7720_startup(struct usb_serial *serial) | |||
2049 | 2024 | ||
2050 | static void mos7720_release(struct usb_serial *serial) | 2025 | static void mos7720_release(struct usb_serial *serial) |
2051 | { | 2026 | { |
2052 | int i; | ||
2053 | |||
2054 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT | 2027 | #ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT |
2055 | /* close the parallel port */ | 2028 | /* close the parallel port */ |
2056 | 2029 | ||
@@ -2089,9 +2062,36 @@ static void mos7720_release(struct usb_serial *serial) | |||
2089 | kref_put(&mos_parport->ref_count, destroy_mos_parport); | 2062 | kref_put(&mos_parport->ref_count, destroy_mos_parport); |
2090 | } | 2063 | } |
2091 | #endif | 2064 | #endif |
2092 | /* free private structure allocated for serial port */ | 2065 | } |
2093 | for (i = 0; i < serial->num_ports; ++i) | 2066 | |
2094 | kfree(usb_get_serial_port_data(serial->port[i])); | 2067 | static int mos7720_port_probe(struct usb_serial_port *port) |
2068 | { | ||
2069 | struct moschip_port *mos7720_port; | ||
2070 | |||
2071 | mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL); | ||
2072 | if (!mos7720_port) | ||
2073 | return -ENOMEM; | ||
2074 | |||
2075 | /* Initialize all port interrupt end point to port 0 int endpoint. | ||
2076 | * Our device has only one interrupt endpoint common to all ports. | ||
2077 | */ | ||
2078 | port->interrupt_in_endpointAddress = | ||
2079 | port->serial->port[0]->interrupt_in_endpointAddress; | ||
2080 | mos7720_port->port = port; | ||
2081 | |||
2082 | usb_set_serial_port_data(port, mos7720_port); | ||
2083 | |||
2084 | return 0; | ||
2085 | } | ||
2086 | |||
2087 | static int mos7720_port_remove(struct usb_serial_port *port) | ||
2088 | { | ||
2089 | struct moschip_port *mos7720_port; | ||
2090 | |||
2091 | mos7720_port = usb_get_serial_port_data(port); | ||
2092 | kfree(mos7720_port); | ||
2093 | |||
2094 | return 0; | ||
2095 | } | 2095 | } |
2096 | 2096 | ||
2097 | static struct usb_serial_driver moschip7720_2port_driver = { | 2097 | static struct usb_serial_driver moschip7720_2port_driver = { |
@@ -2109,6 +2109,8 @@ static struct usb_serial_driver moschip7720_2port_driver = { | |||
2109 | .probe = mos77xx_probe, | 2109 | .probe = mos77xx_probe, |
2110 | .attach = mos7720_startup, | 2110 | .attach = mos7720_startup, |
2111 | .release = mos7720_release, | 2111 | .release = mos7720_release, |
2112 | .port_probe = mos7720_port_probe, | ||
2113 | .port_remove = mos7720_port_remove, | ||
2112 | .ioctl = mos7720_ioctl, | 2114 | .ioctl = mos7720_ioctl, |
2113 | .tiocmget = mos7720_tiocmget, | 2115 | .tiocmget = mos7720_tiocmget, |
2114 | .tiocmset = mos7720_tiocmset, | 2116 | .tiocmset = mos7720_tiocmset, |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index d6d4eeca8c68..1cf3375ec1af 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -218,12 +218,10 @@ struct moschip_port { | |||
218 | int port_num; /*Actual port number in the device(1,2,etc) */ | 218 | int port_num; /*Actual port number in the device(1,2,etc) */ |
219 | struct urb *write_urb; /* write URB for this port */ | 219 | struct urb *write_urb; /* write URB for this port */ |
220 | struct urb *read_urb; /* read URB for this port */ | 220 | struct urb *read_urb; /* read URB for this port */ |
221 | struct urb *int_urb; | ||
222 | __u8 shadowLCR; /* last LCR value received */ | 221 | __u8 shadowLCR; /* last LCR value received */ |
223 | __u8 shadowMCR; /* last MCR value received */ | 222 | __u8 shadowMCR; /* last MCR value received */ |
224 | char open; | 223 | char open; |
225 | char open_ports; | 224 | char open_ports; |
226 | char zombie; | ||
227 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ | 225 | wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */ |
228 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ | 226 | wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */ |
229 | int delta_msr_cond; | 227 | int delta_msr_cond; |
@@ -478,7 +476,6 @@ static void mos7840_control_callback(struct urb *urb) | |||
478 | struct moschip_port *mos7840_port; | 476 | struct moschip_port *mos7840_port; |
479 | struct device *dev = &urb->dev->dev; | 477 | struct device *dev = &urb->dev->dev; |
480 | __u8 regval = 0x0; | 478 | __u8 regval = 0x0; |
481 | int result = 0; | ||
482 | int status = urb->status; | 479 | int status = urb->status; |
483 | 480 | ||
484 | mos7840_port = urb->context; | 481 | mos7840_port = urb->context; |
@@ -495,7 +492,7 @@ static void mos7840_control_callback(struct urb *urb) | |||
495 | return; | 492 | return; |
496 | default: | 493 | default: |
497 | dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); | 494 | dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status); |
498 | goto exit; | 495 | return; |
499 | } | 496 | } |
500 | 497 | ||
501 | dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); | 498 | dev_dbg(dev, "%s urb buffer size is %d\n", __func__, urb->actual_length); |
@@ -508,16 +505,6 @@ static void mos7840_control_callback(struct urb *urb) | |||
508 | mos7840_handle_new_msr(mos7840_port, regval); | 505 | mos7840_handle_new_msr(mos7840_port, regval); |
509 | else if (mos7840_port->MsrLsr == 1) | 506 | else if (mos7840_port->MsrLsr == 1) |
510 | mos7840_handle_new_lsr(mos7840_port, regval); | 507 | mos7840_handle_new_lsr(mos7840_port, regval); |
511 | |||
512 | exit: | ||
513 | spin_lock(&mos7840_port->pool_lock); | ||
514 | if (!mos7840_port->zombie) | ||
515 | result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC); | ||
516 | spin_unlock(&mos7840_port->pool_lock); | ||
517 | if (result) { | ||
518 | dev_err(dev, "%s - Error %d submitting interrupt urb\n", | ||
519 | __func__, result); | ||
520 | } | ||
521 | } | 508 | } |
522 | 509 | ||
523 | static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, | 510 | static int mos7840_get_reg(struct moschip_port *mcs, __u16 Wval, __u16 reg, |
@@ -686,14 +673,7 @@ static void mos7840_interrupt_callback(struct urb *urb) | |||
686 | wreg = MODEM_STATUS_REGISTER; | 673 | wreg = MODEM_STATUS_REGISTER; |
687 | break; | 674 | break; |
688 | } | 675 | } |
689 | spin_lock(&mos7840_port->pool_lock); | 676 | rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); |
690 | if (!mos7840_port->zombie) { | ||
691 | rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data); | ||
692 | } else { | ||
693 | spin_unlock(&mos7840_port->pool_lock); | ||
694 | return; | ||
695 | } | ||
696 | spin_unlock(&mos7840_port->pool_lock); | ||
697 | } | 677 | } |
698 | } | 678 | } |
699 | } | 679 | } |
@@ -2347,309 +2327,249 @@ static int mos7840_calc_num_ports(struct usb_serial *serial) | |||
2347 | return mos7840_num_ports; | 2327 | return mos7840_num_ports; |
2348 | } | 2328 | } |
2349 | 2329 | ||
2350 | /**************************************************************************** | 2330 | static int mos7840_port_probe(struct usb_serial_port *port) |
2351 | * mos7840_startup | ||
2352 | ****************************************************************************/ | ||
2353 | |||
2354 | static int mos7840_startup(struct usb_serial *serial) | ||
2355 | { | 2331 | { |
2332 | struct usb_serial *serial = port->serial; | ||
2356 | struct moschip_port *mos7840_port; | 2333 | struct moschip_port *mos7840_port; |
2357 | struct usb_device *dev; | 2334 | int status; |
2358 | int i, status; | 2335 | int pnum; |
2359 | __u16 Data; | 2336 | __u16 Data; |
2360 | 2337 | ||
2361 | dev = serial->dev; | ||
2362 | |||
2363 | /* we set up the pointers to the endpoints in the mos7840_open * | 2338 | /* we set up the pointers to the endpoints in the mos7840_open * |
2364 | * function, as the structures aren't created yet. */ | 2339 | * function, as the structures aren't created yet. */ |
2365 | 2340 | ||
2366 | /* set up port private structures */ | 2341 | pnum = port->number - serial->minor; |
2367 | for (i = 0; i < serial->num_ports; ++i) { | ||
2368 | dev_dbg(&dev->dev, "mos7840_startup: configuring port %d............\n", i); | ||
2369 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); | ||
2370 | if (mos7840_port == NULL) { | ||
2371 | dev_err(&dev->dev, "%s - Out of memory\n", __func__); | ||
2372 | status = -ENOMEM; | ||
2373 | i--; /* don't follow NULL pointer cleaning up */ | ||
2374 | goto error; | ||
2375 | } | ||
2376 | |||
2377 | /* Initialize all port interrupt end point to port 0 int | ||
2378 | * endpoint. Our device has only one interrupt end point | ||
2379 | * common to all port */ | ||
2380 | |||
2381 | mos7840_port->port = serial->port[i]; | ||
2382 | mos7840_set_port_private(serial->port[i], mos7840_port); | ||
2383 | spin_lock_init(&mos7840_port->pool_lock); | ||
2384 | |||
2385 | /* minor is not initialised until later by | ||
2386 | * usb-serial.c:get_free_serial() and cannot therefore be used | ||
2387 | * to index device instances */ | ||
2388 | mos7840_port->port_num = i + 1; | ||
2389 | dev_dbg(&dev->dev, "serial->port[i]->number = %d\n", serial->port[i]->number); | ||
2390 | dev_dbg(&dev->dev, "serial->port[i]->serial->minor = %d\n", serial->port[i]->serial->minor); | ||
2391 | dev_dbg(&dev->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); | ||
2392 | dev_dbg(&dev->dev, "serial->minor = %d\n", serial->minor); | ||
2393 | |||
2394 | if (mos7840_port->port_num == 1) { | ||
2395 | mos7840_port->SpRegOffset = 0x0; | ||
2396 | mos7840_port->ControlRegOffset = 0x1; | ||
2397 | mos7840_port->DcrRegOffset = 0x4; | ||
2398 | } else if ((mos7840_port->port_num == 2) | ||
2399 | && (serial->num_ports == 4)) { | ||
2400 | mos7840_port->SpRegOffset = 0x8; | ||
2401 | mos7840_port->ControlRegOffset = 0x9; | ||
2402 | mos7840_port->DcrRegOffset = 0x16; | ||
2403 | } else if ((mos7840_port->port_num == 2) | ||
2404 | && (serial->num_ports == 2)) { | ||
2405 | mos7840_port->SpRegOffset = 0xa; | ||
2406 | mos7840_port->ControlRegOffset = 0xb; | ||
2407 | mos7840_port->DcrRegOffset = 0x19; | ||
2408 | } else if ((mos7840_port->port_num == 3) | ||
2409 | && (serial->num_ports == 4)) { | ||
2410 | mos7840_port->SpRegOffset = 0xa; | ||
2411 | mos7840_port->ControlRegOffset = 0xb; | ||
2412 | mos7840_port->DcrRegOffset = 0x19; | ||
2413 | } else if ((mos7840_port->port_num == 4) | ||
2414 | && (serial->num_ports == 4)) { | ||
2415 | mos7840_port->SpRegOffset = 0xc; | ||
2416 | mos7840_port->ControlRegOffset = 0xd; | ||
2417 | mos7840_port->DcrRegOffset = 0x1c; | ||
2418 | } | ||
2419 | mos7840_dump_serial_port(serial->port[i], mos7840_port); | ||
2420 | mos7840_set_port_private(serial->port[i], mos7840_port); | ||
2421 | 2342 | ||
2422 | /* enable rx_disable bit in control register */ | 2343 | dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum); |
2423 | status = mos7840_get_reg_sync(serial->port[i], | 2344 | mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL); |
2424 | mos7840_port->ControlRegOffset, &Data); | 2345 | if (mos7840_port == NULL) { |
2425 | if (status < 0) { | 2346 | dev_err(&port->dev, "%s - Out of memory\n", __func__); |
2426 | dev_dbg(&dev->dev, "Reading ControlReg failed status-0x%x\n", status); | 2347 | return -ENOMEM; |
2427 | break; | 2348 | } |
2428 | } else | ||
2429 | dev_dbg(&dev->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); | ||
2430 | Data |= 0x08; /* setting driver done bit */ | ||
2431 | Data |= 0x04; /* sp1_bit to have cts change reflect in | ||
2432 | modem status reg */ | ||
2433 | |||
2434 | /* Data |= 0x20; //rx_disable bit */ | ||
2435 | status = mos7840_set_reg_sync(serial->port[i], | ||
2436 | mos7840_port->ControlRegOffset, Data); | ||
2437 | if (status < 0) { | ||
2438 | dev_dbg(&dev->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); | ||
2439 | break; | ||
2440 | } else | ||
2441 | dev_dbg(&dev->dev, "ControlReg Writing success(rx_disable) status%d\n", status); | ||
2442 | 2349 | ||
2443 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 | 2350 | /* Initialize all port interrupt end point to port 0 int |
2444 | and 0x24 in DCR3 */ | 2351 | * endpoint. Our device has only one interrupt end point |
2445 | Data = 0x01; | 2352 | * common to all port */ |
2446 | status = mos7840_set_reg_sync(serial->port[i], | 2353 | |
2447 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); | 2354 | mos7840_port->port = port; |
2448 | if (status < 0) { | 2355 | mos7840_set_port_private(port, mos7840_port); |
2449 | dev_dbg(&dev->dev, "Writing DCR0 failed status-0x%x\n", status); | 2356 | spin_lock_init(&mos7840_port->pool_lock); |
2450 | break; | 2357 | |
2451 | } else | 2358 | /* minor is not initialised until later by |
2452 | dev_dbg(&dev->dev, "DCR0 Writing success status%d\n", status); | 2359 | * usb-serial.c:get_free_serial() and cannot therefore be used |
2360 | * to index device instances */ | ||
2361 | mos7840_port->port_num = pnum + 1; | ||
2362 | dev_dbg(&port->dev, "port->number = %d\n", port->number); | ||
2363 | dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor); | ||
2364 | dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num); | ||
2365 | dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor); | ||
2366 | |||
2367 | if (mos7840_port->port_num == 1) { | ||
2368 | mos7840_port->SpRegOffset = 0x0; | ||
2369 | mos7840_port->ControlRegOffset = 0x1; | ||
2370 | mos7840_port->DcrRegOffset = 0x4; | ||
2371 | } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) { | ||
2372 | mos7840_port->SpRegOffset = 0x8; | ||
2373 | mos7840_port->ControlRegOffset = 0x9; | ||
2374 | mos7840_port->DcrRegOffset = 0x16; | ||
2375 | } else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) { | ||
2376 | mos7840_port->SpRegOffset = 0xa; | ||
2377 | mos7840_port->ControlRegOffset = 0xb; | ||
2378 | mos7840_port->DcrRegOffset = 0x19; | ||
2379 | } else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) { | ||
2380 | mos7840_port->SpRegOffset = 0xa; | ||
2381 | mos7840_port->ControlRegOffset = 0xb; | ||
2382 | mos7840_port->DcrRegOffset = 0x19; | ||
2383 | } else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) { | ||
2384 | mos7840_port->SpRegOffset = 0xc; | ||
2385 | mos7840_port->ControlRegOffset = 0xd; | ||
2386 | mos7840_port->DcrRegOffset = 0x1c; | ||
2387 | } | ||
2388 | mos7840_dump_serial_port(port, mos7840_port); | ||
2389 | mos7840_set_port_private(port, mos7840_port); | ||
2390 | |||
2391 | /* enable rx_disable bit in control register */ | ||
2392 | status = mos7840_get_reg_sync(port, | ||
2393 | mos7840_port->ControlRegOffset, &Data); | ||
2394 | if (status < 0) { | ||
2395 | dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status); | ||
2396 | goto out; | ||
2397 | } else | ||
2398 | dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status); | ||
2399 | Data |= 0x08; /* setting driver done bit */ | ||
2400 | Data |= 0x04; /* sp1_bit to have cts change reflect in | ||
2401 | modem status reg */ | ||
2453 | 2402 | ||
2454 | Data = 0x05; | 2403 | /* Data |= 0x20; //rx_disable bit */ |
2455 | status = mos7840_set_reg_sync(serial->port[i], | 2404 | status = mos7840_set_reg_sync(port, |
2456 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); | 2405 | mos7840_port->ControlRegOffset, Data); |
2457 | if (status < 0) { | 2406 | if (status < 0) { |
2458 | dev_dbg(&dev->dev, "Writing DCR1 failed status-0x%x\n", status); | 2407 | dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status); |
2459 | break; | 2408 | goto out; |
2460 | } else | 2409 | } else |
2461 | dev_dbg(&dev->dev, "DCR1 Writing success status%d\n", status); | 2410 | dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status); |
2462 | 2411 | ||
2463 | Data = 0x24; | 2412 | /* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2 |
2464 | status = mos7840_set_reg_sync(serial->port[i], | 2413 | and 0x24 in DCR3 */ |
2465 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); | 2414 | Data = 0x01; |
2466 | if (status < 0) { | 2415 | status = mos7840_set_reg_sync(port, |
2467 | dev_dbg(&dev->dev, "Writing DCR2 failed status-0x%x\n", status); | 2416 | (__u16) (mos7840_port->DcrRegOffset + 0), Data); |
2468 | break; | 2417 | if (status < 0) { |
2469 | } else | 2418 | dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status); |
2470 | dev_dbg(&dev->dev, "DCR2 Writing success status%d\n", status); | 2419 | goto out; |
2420 | } else | ||
2421 | dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status); | ||
2471 | 2422 | ||
2472 | /* write values in clkstart0x0 and clkmulti 0x20 */ | 2423 | Data = 0x05; |
2473 | Data = 0x0; | 2424 | status = mos7840_set_reg_sync(port, |
2474 | status = mos7840_set_reg_sync(serial->port[i], | 2425 | (__u16) (mos7840_port->DcrRegOffset + 1), Data); |
2475 | CLK_START_VALUE_REGISTER, Data); | 2426 | if (status < 0) { |
2476 | if (status < 0) { | 2427 | dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status); |
2477 | dev_dbg(&dev->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); | 2428 | goto out; |
2478 | break; | 2429 | } else |
2479 | } else | 2430 | dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status); |
2480 | dev_dbg(&dev->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); | ||
2481 | 2431 | ||
2482 | Data = 0x20; | 2432 | Data = 0x24; |
2483 | status = mos7840_set_reg_sync(serial->port[i], | 2433 | status = mos7840_set_reg_sync(port, |
2484 | CLK_MULTI_REGISTER, Data); | 2434 | (__u16) (mos7840_port->DcrRegOffset + 2), Data); |
2485 | if (status < 0) { | 2435 | if (status < 0) { |
2486 | dev_dbg(&dev->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); | 2436 | dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status); |
2487 | goto error; | 2437 | goto out; |
2488 | } else | 2438 | } else |
2489 | dev_dbg(&dev->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); | 2439 | dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status); |
2490 | 2440 | ||
2491 | /* write value 0x0 to scratchpad register */ | 2441 | /* write values in clkstart0x0 and clkmulti 0x20 */ |
2492 | Data = 0x00; | 2442 | Data = 0x0; |
2493 | status = mos7840_set_uart_reg(serial->port[i], | 2443 | status = mos7840_set_reg_sync(port, CLK_START_VALUE_REGISTER, Data); |
2494 | SCRATCH_PAD_REGISTER, Data); | 2444 | if (status < 0) { |
2495 | if (status < 0) { | 2445 | dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status); |
2496 | dev_dbg(&dev->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); | 2446 | goto out; |
2497 | break; | 2447 | } else |
2498 | } else | 2448 | dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status); |
2499 | dev_dbg(&dev->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); | ||
2500 | 2449 | ||
2501 | /* Zero Length flag register */ | 2450 | Data = 0x20; |
2502 | if ((mos7840_port->port_num != 1) | 2451 | status = mos7840_set_reg_sync(port, CLK_MULTI_REGISTER, Data); |
2503 | && (serial->num_ports == 2)) { | 2452 | if (status < 0) { |
2453 | dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status); | ||
2454 | goto error; | ||
2455 | } else | ||
2456 | dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status); | ||
2504 | 2457 | ||
2505 | Data = 0xff; | 2458 | /* write value 0x0 to scratchpad register */ |
2506 | status = mos7840_set_reg_sync(serial->port[i], | 2459 | Data = 0x00; |
2507 | (__u16) (ZLP_REG1 + | 2460 | status = mos7840_set_uart_reg(port, SCRATCH_PAD_REGISTER, Data); |
2508 | ((__u16)mos7840_port->port_num)), Data); | 2461 | if (status < 0) { |
2509 | dev_dbg(&dev->dev, "ZLIP offset %x\n", | 2462 | dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status); |
2463 | goto out; | ||
2464 | } else | ||
2465 | dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status); | ||
2466 | |||
2467 | /* Zero Length flag register */ | ||
2468 | if ((mos7840_port->port_num != 1) && (serial->num_ports == 2)) { | ||
2469 | Data = 0xff; | ||
2470 | status = mos7840_set_reg_sync(port, | ||
2471 | (__u16) (ZLP_REG1 + | ||
2472 | ((__u16)mos7840_port->port_num)), Data); | ||
2473 | dev_dbg(&port->dev, "ZLIP offset %x\n", | ||
2510 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); | 2474 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num))); |
2511 | if (status < 0) { | 2475 | if (status < 0) { |
2512 | dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 2, status); | 2476 | dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status); |
2513 | break; | 2477 | goto out; |
2514 | } else | 2478 | } else |
2515 | dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 2, status); | 2479 | dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status); |
2516 | } else { | 2480 | } else { |
2517 | Data = 0xff; | 2481 | Data = 0xff; |
2518 | status = mos7840_set_reg_sync(serial->port[i], | 2482 | status = mos7840_set_reg_sync(port, |
2519 | (__u16) (ZLP_REG1 + | 2483 | (__u16) (ZLP_REG1 + |
2520 | ((__u16)mos7840_port->port_num) - 0x1), Data); | 2484 | ((__u16)mos7840_port->port_num) - 0x1), Data); |
2521 | dev_dbg(&dev->dev, "ZLIP offset %x\n", | 2485 | dev_dbg(&port->dev, "ZLIP offset %x\n", |
2522 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); | 2486 | (__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1)); |
2523 | if (status < 0) { | 2487 | if (status < 0) { |
2524 | dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 1, status); | 2488 | dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status); |
2525 | break; | 2489 | goto out; |
2526 | } else | 2490 | } else |
2527 | dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 1, status); | 2491 | dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status); |
2528 | 2492 | ||
2529 | } | 2493 | } |
2530 | mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); | 2494 | mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL); |
2531 | mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); | 2495 | mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL); |
2532 | mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), | 2496 | mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest), |
2533 | GFP_KERNEL); | 2497 | GFP_KERNEL); |
2534 | if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || | 2498 | if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf || |
2535 | !mos7840_port->dr) { | 2499 | !mos7840_port->dr) { |
2536 | status = -ENOMEM; | 2500 | status = -ENOMEM; |
2537 | goto error; | 2501 | goto error; |
2538 | } | 2502 | } |
2539 | 2503 | ||
2540 | mos7840_port->has_led = false; | 2504 | mos7840_port->has_led = false; |
2541 | 2505 | ||
2542 | /* Initialize LED timers */ | 2506 | /* Initialize LED timers */ |
2543 | if (device_type == MOSCHIP_DEVICE_ID_7810) { | 2507 | if (device_type == MOSCHIP_DEVICE_ID_7810) { |
2544 | mos7840_port->has_led = true; | 2508 | mos7840_port->has_led = true; |
2545 | 2509 | ||
2546 | init_timer(&mos7840_port->led_timer1); | 2510 | init_timer(&mos7840_port->led_timer1); |
2547 | mos7840_port->led_timer1.function = mos7840_led_off; | 2511 | mos7840_port->led_timer1.function = mos7840_led_off; |
2548 | mos7840_port->led_timer1.expires = | 2512 | mos7840_port->led_timer1.expires = |
2549 | jiffies + msecs_to_jiffies(LED_ON_MS); | 2513 | jiffies + msecs_to_jiffies(LED_ON_MS); |
2550 | mos7840_port->led_timer1.data = | 2514 | mos7840_port->led_timer1.data = (unsigned long)mos7840_port; |
2551 | (unsigned long)mos7840_port; | ||
2552 | 2515 | ||
2553 | init_timer(&mos7840_port->led_timer2); | 2516 | init_timer(&mos7840_port->led_timer2); |
2554 | mos7840_port->led_timer2.function = | 2517 | mos7840_port->led_timer2.function = mos7840_led_flag_off; |
2555 | mos7840_led_flag_off; | 2518 | mos7840_port->led_timer2.expires = |
2556 | mos7840_port->led_timer2.expires = | 2519 | jiffies + msecs_to_jiffies(LED_OFF_MS); |
2557 | jiffies + msecs_to_jiffies(LED_OFF_MS); | 2520 | mos7840_port->led_timer2.data = (unsigned long)mos7840_port; |
2558 | mos7840_port->led_timer2.data = | ||
2559 | (unsigned long)mos7840_port; | ||
2560 | 2521 | ||
2561 | mos7840_port->led_flag = false; | 2522 | mos7840_port->led_flag = false; |
2562 | 2523 | ||
2563 | /* Turn off LED */ | 2524 | /* Turn off LED */ |
2564 | mos7840_set_led_sync(serial->port[i], | 2525 | mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); |
2565 | MODEM_CONTROL_REGISTER, 0x0300); | ||
2566 | } | ||
2567 | } | 2526 | } |
2527 | out: | ||
2528 | if (pnum == serial->num_ports - 1) { | ||
2529 | /* Zero Length flag enable */ | ||
2530 | Data = 0x0f; | ||
2531 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); | ||
2532 | if (status < 0) { | ||
2533 | dev_dbg(&port->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); | ||
2534 | goto error; | ||
2535 | } else | ||
2536 | dev_dbg(&port->dev, "ZLP_REG5 Writing success status%d\n", status); | ||
2568 | 2537 | ||
2569 | /* Zero Length flag enable */ | 2538 | /* setting configuration feature to one */ |
2570 | Data = 0x0f; | 2539 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
2571 | status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data); | 2540 | 0x03, 0x00, 0x01, 0x00, NULL, 0x00, |
2572 | if (status < 0) { | 2541 | MOS_WDR_TIMEOUT); |
2573 | dev_dbg(&dev->dev, "Writing ZLP_REG5 failed status-0x%x\n", status); | 2542 | } |
2574 | goto error; | ||
2575 | } else | ||
2576 | dev_dbg(&dev->dev, "ZLP_REG5 Writing success status%d\n", status); | ||
2577 | |||
2578 | /* setting configuration feature to one */ | ||
2579 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | ||
2580 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); | ||
2581 | return 0; | 2543 | return 0; |
2582 | error: | 2544 | error: |
2583 | for (/* nothing */; i >= 0; i--) { | 2545 | kfree(mos7840_port->dr); |
2584 | mos7840_port = mos7840_get_port_private(serial->port[i]); | 2546 | kfree(mos7840_port->ctrl_buf); |
2547 | usb_free_urb(mos7840_port->control_urb); | ||
2548 | kfree(mos7840_port); | ||
2585 | 2549 | ||
2586 | kfree(mos7840_port->dr); | ||
2587 | kfree(mos7840_port->ctrl_buf); | ||
2588 | usb_free_urb(mos7840_port->control_urb); | ||
2589 | kfree(mos7840_port); | ||
2590 | serial->port[i] = NULL; | ||
2591 | } | ||
2592 | return status; | 2550 | return status; |
2593 | } | 2551 | } |
2594 | 2552 | ||
2595 | /**************************************************************************** | 2553 | static int mos7840_port_remove(struct usb_serial_port *port) |
2596 | * mos7840_disconnect | ||
2597 | * This function is called whenever the device is removed from the usb bus. | ||
2598 | ****************************************************************************/ | ||
2599 | |||
2600 | static void mos7840_disconnect(struct usb_serial *serial) | ||
2601 | { | 2554 | { |
2602 | int i; | ||
2603 | unsigned long flags; | ||
2604 | struct moschip_port *mos7840_port; | 2555 | struct moschip_port *mos7840_port; |
2605 | 2556 | ||
2606 | /* check for the ports to be closed,close the ports and disconnect */ | 2557 | mos7840_port = mos7840_get_port_private(port); |
2607 | 2558 | ||
2608 | /* free private structure allocated for serial port * | 2559 | if (mos7840_port->has_led) { |
2609 | * stop reads and writes on all ports */ | 2560 | /* Turn off LED */ |
2561 | mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300); | ||
2610 | 2562 | ||
2611 | for (i = 0; i < serial->num_ports; ++i) { | 2563 | del_timer_sync(&mos7840_port->led_timer1); |
2612 | mos7840_port = mos7840_get_port_private(serial->port[i]); | 2564 | del_timer_sync(&mos7840_port->led_timer2); |
2613 | if (mos7840_port) { | ||
2614 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); | ||
2615 | mos7840_port->zombie = 1; | ||
2616 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | ||
2617 | usb_kill_urb(mos7840_port->control_urb); | ||
2618 | } | ||
2619 | } | 2565 | } |
2620 | } | 2566 | usb_kill_urb(mos7840_port->control_urb); |
2621 | 2567 | usb_free_urb(mos7840_port->control_urb); | |
2622 | /**************************************************************************** | 2568 | kfree(mos7840_port->ctrl_buf); |
2623 | * mos7840_release | 2569 | kfree(mos7840_port->dr); |
2624 | * This function is called when the usb_serial structure is freed. | 2570 | kfree(mos7840_port); |
2625 | ****************************************************************************/ | ||
2626 | |||
2627 | static void mos7840_release(struct usb_serial *serial) | ||
2628 | { | ||
2629 | int i; | ||
2630 | struct moschip_port *mos7840_port; | ||
2631 | |||
2632 | /* check for the ports to be closed,close the ports and disconnect */ | ||
2633 | 2571 | ||
2634 | /* free private structure allocated for serial port * | 2572 | return 0; |
2635 | * stop reads and writes on all ports */ | ||
2636 | |||
2637 | for (i = 0; i < serial->num_ports; ++i) { | ||
2638 | mos7840_port = mos7840_get_port_private(serial->port[i]); | ||
2639 | if (mos7840_port) { | ||
2640 | if (mos7840_port->has_led) { | ||
2641 | /* Turn off LED */ | ||
2642 | mos7840_set_led_sync(mos7840_port->port, | ||
2643 | MODEM_CONTROL_REGISTER, 0x0300); | ||
2644 | |||
2645 | del_timer_sync(&mos7840_port->led_timer1); | ||
2646 | del_timer_sync(&mos7840_port->led_timer2); | ||
2647 | } | ||
2648 | kfree(mos7840_port->ctrl_buf); | ||
2649 | kfree(mos7840_port->dr); | ||
2650 | kfree(mos7840_port); | ||
2651 | } | ||
2652 | } | ||
2653 | } | 2573 | } |
2654 | 2574 | ||
2655 | static struct usb_serial_driver moschip7840_4port_device = { | 2575 | static struct usb_serial_driver moschip7840_4port_device = { |
@@ -2677,9 +2597,8 @@ static struct usb_serial_driver moschip7840_4port_device = { | |||
2677 | .tiocmget = mos7840_tiocmget, | 2597 | .tiocmget = mos7840_tiocmget, |
2678 | .tiocmset = mos7840_tiocmset, | 2598 | .tiocmset = mos7840_tiocmset, |
2679 | .get_icount = mos7840_get_icount, | 2599 | .get_icount = mos7840_get_icount, |
2680 | .attach = mos7840_startup, | 2600 | .port_probe = mos7840_port_probe, |
2681 | .disconnect = mos7840_disconnect, | 2601 | .port_remove = mos7840_port_remove, |
2682 | .release = mos7840_release, | ||
2683 | .read_bulk_callback = mos7840_bulk_in_callback, | 2602 | .read_bulk_callback = mos7840_bulk_in_callback, |
2684 | .read_int_callback = mos7840_interrupt_callback, | 2603 | .read_int_callback = mos7840_interrupt_callback, |
2685 | }; | 2604 | }; |
diff --git a/drivers/usb/serial/omninet.c b/drivers/usb/serial/omninet.c index 6def58b79382..9ab73d295774 100644 --- a/drivers/usb/serial/omninet.c +++ b/drivers/usb/serial/omninet.c | |||
@@ -44,8 +44,8 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
44 | const unsigned char *buf, int count); | 44 | const unsigned char *buf, int count); |
45 | static int omninet_write_room(struct tty_struct *tty); | 45 | static int omninet_write_room(struct tty_struct *tty); |
46 | static void omninet_disconnect(struct usb_serial *serial); | 46 | static void omninet_disconnect(struct usb_serial *serial); |
47 | static void omninet_release(struct usb_serial *serial); | 47 | static int omninet_port_probe(struct usb_serial_port *port); |
48 | static int omninet_attach(struct usb_serial *serial); | 48 | static int omninet_port_remove(struct usb_serial_port *port); |
49 | 49 | ||
50 | static const struct usb_device_id id_table[] = { | 50 | static const struct usb_device_id id_table[] = { |
51 | { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, | 51 | { USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) }, |
@@ -62,7 +62,8 @@ static struct usb_serial_driver zyxel_omninet_device = { | |||
62 | .description = "ZyXEL - omni.net lcd plus usb", | 62 | .description = "ZyXEL - omni.net lcd plus usb", |
63 | .id_table = id_table, | 63 | .id_table = id_table, |
64 | .num_ports = 1, | 64 | .num_ports = 1, |
65 | .attach = omninet_attach, | 65 | .port_probe = omninet_port_probe, |
66 | .port_remove = omninet_port_remove, | ||
66 | .open = omninet_open, | 67 | .open = omninet_open, |
67 | .close = omninet_close, | 68 | .close = omninet_close, |
68 | .write = omninet_write, | 69 | .write = omninet_write, |
@@ -70,7 +71,6 @@ static struct usb_serial_driver zyxel_omninet_device = { | |||
70 | .read_bulk_callback = omninet_read_bulk_callback, | 71 | .read_bulk_callback = omninet_read_bulk_callback, |
71 | .write_bulk_callback = omninet_write_bulk_callback, | 72 | .write_bulk_callback = omninet_write_bulk_callback, |
72 | .disconnect = omninet_disconnect, | 73 | .disconnect = omninet_disconnect, |
73 | .release = omninet_release, | ||
74 | }; | 74 | }; |
75 | 75 | ||
76 | static struct usb_serial_driver * const serial_drivers[] = { | 76 | static struct usb_serial_driver * const serial_drivers[] = { |
@@ -112,18 +112,26 @@ struct omninet_data { | |||
112 | __u8 od_outseq; /* Sequence number for bulk_out URBs */ | 112 | __u8 od_outseq; /* Sequence number for bulk_out URBs */ |
113 | }; | 113 | }; |
114 | 114 | ||
115 | static int omninet_attach(struct usb_serial *serial) | 115 | static int omninet_port_probe(struct usb_serial_port *port) |
116 | { | 116 | { |
117 | struct omninet_data *od; | 117 | struct omninet_data *od; |
118 | struct usb_serial_port *port = serial->port[0]; | ||
119 | 118 | ||
120 | od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); | 119 | od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL); |
121 | if (!od) { | 120 | if (!od) |
122 | dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", | ||
123 | __func__, sizeof(struct omninet_data)); | ||
124 | return -ENOMEM; | 121 | return -ENOMEM; |
125 | } | 122 | |
126 | usb_set_serial_port_data(port, od); | 123 | usb_set_serial_port_data(port, od); |
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int omninet_port_remove(struct usb_serial_port *port) | ||
129 | { | ||
130 | struct omninet_data *od; | ||
131 | |||
132 | od = usb_get_serial_port_data(port); | ||
133 | kfree(od); | ||
134 | |||
127 | return 0; | 135 | return 0; |
128 | } | 136 | } |
129 | 137 | ||
@@ -279,14 +287,6 @@ static void omninet_disconnect(struct usb_serial *serial) | |||
279 | usb_kill_urb(wport->write_urb); | 287 | usb_kill_urb(wport->write_urb); |
280 | } | 288 | } |
281 | 289 | ||
282 | |||
283 | static void omninet_release(struct usb_serial *serial) | ||
284 | { | ||
285 | struct usb_serial_port *port = serial->port[0]; | ||
286 | |||
287 | kfree(usb_get_serial_port_data(port)); | ||
288 | } | ||
289 | |||
290 | module_usb_serial_driver(serial_drivers, id_table); | 290 | module_usb_serial_driver(serial_drivers, id_table); |
291 | 291 | ||
292 | MODULE_AUTHOR(DRIVER_AUTHOR); | 292 | MODULE_AUTHOR(DRIVER_AUTHOR); |
diff --git a/drivers/usb/serial/opticon.c b/drivers/usb/serial/opticon.c index 41b1647306eb..6aba731d4864 100644 --- a/drivers/usb/serial/opticon.c +++ b/drivers/usb/serial/opticon.c | |||
@@ -155,7 +155,11 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, | |||
155 | { | 155 | { |
156 | struct usb_serial *serial = port->serial; | 156 | struct usb_serial *serial = port->serial; |
157 | int retval; | 157 | int retval; |
158 | u8 buffer[2]; | 158 | u8 *buffer; |
159 | |||
160 | buffer = kzalloc(1, GFP_KERNEL); | ||
161 | if (!buffer) | ||
162 | return -ENOMEM; | ||
159 | 163 | ||
160 | buffer[0] = val; | 164 | buffer[0] = val; |
161 | /* Send the message to the vendor control endpoint | 165 | /* Send the message to the vendor control endpoint |
@@ -164,6 +168,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype, | |||
164 | requesttype, | 168 | requesttype, |
165 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, | 169 | USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE, |
166 | 0, 0, buffer, 1, 0); | 170 | 0, 0, buffer, 1, 0); |
171 | kfree(buffer); | ||
167 | 172 | ||
168 | return retval; | 173 | return retval; |
169 | } | 174 | } |
@@ -281,7 +286,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
281 | if (!dr) { | 286 | if (!dr) { |
282 | dev_err(&port->dev, "out of memory\n"); | 287 | dev_err(&port->dev, "out of memory\n"); |
283 | count = -ENOMEM; | 288 | count = -ENOMEM; |
284 | goto error; | 289 | goto error_no_dr; |
285 | } | 290 | } |
286 | 291 | ||
287 | dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; | 292 | dr->bRequestType = USB_TYPE_VENDOR | USB_RECIP_INTERFACE | USB_DIR_OUT; |
@@ -311,6 +316,8 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port, | |||
311 | 316 | ||
312 | return count; | 317 | return count; |
313 | error: | 318 | error: |
319 | kfree(dr); | ||
320 | error_no_dr: | ||
314 | usb_free_urb(urb); | 321 | usb_free_urb(urb); |
315 | error_no_urb: | 322 | error_no_urb: |
316 | kfree(buffer); | 323 | kfree(buffer); |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 54d4148d01d1..5dee7d61241e 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -47,6 +47,7 @@ | |||
47 | /* Function prototypes */ | 47 | /* Function prototypes */ |
48 | static int option_probe(struct usb_serial *serial, | 48 | static int option_probe(struct usb_serial *serial, |
49 | const struct usb_device_id *id); | 49 | const struct usb_device_id *id); |
50 | static int option_attach(struct usb_serial *serial); | ||
50 | static void option_release(struct usb_serial *serial); | 51 | static void option_release(struct usb_serial *serial); |
51 | static int option_send_setup(struct usb_serial_port *port); | 52 | static int option_send_setup(struct usb_serial_port *port); |
52 | static void option_instat_callback(struct urb *urb); | 53 | static void option_instat_callback(struct urb *urb); |
@@ -1288,8 +1289,9 @@ static struct usb_serial_driver option_1port_device = { | |||
1288 | .tiocmget = usb_wwan_tiocmget, | 1289 | .tiocmget = usb_wwan_tiocmget, |
1289 | .tiocmset = usb_wwan_tiocmset, | 1290 | .tiocmset = usb_wwan_tiocmset, |
1290 | .ioctl = usb_wwan_ioctl, | 1291 | .ioctl = usb_wwan_ioctl, |
1291 | .attach = usb_wwan_startup, | 1292 | .attach = option_attach, |
1292 | .release = option_release, | 1293 | .release = option_release, |
1294 | .port_probe = usb_wwan_port_probe, | ||
1293 | .port_remove = usb_wwan_port_remove, | 1295 | .port_remove = usb_wwan_port_remove, |
1294 | .read_int_callback = option_instat_callback, | 1296 | .read_int_callback = option_instat_callback, |
1295 | #ifdef CONFIG_PM | 1297 | #ifdef CONFIG_PM |
@@ -1335,8 +1337,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason, | |||
1335 | static int option_probe(struct usb_serial *serial, | 1337 | static int option_probe(struct usb_serial *serial, |
1336 | const struct usb_device_id *id) | 1338 | const struct usb_device_id *id) |
1337 | { | 1339 | { |
1338 | struct usb_wwan_intf_private *data; | ||
1339 | struct option_private *priv; | ||
1340 | struct usb_interface_descriptor *iface_desc = | 1340 | struct usb_interface_descriptor *iface_desc = |
1341 | &serial->interface->cur_altsetting->desc; | 1341 | &serial->interface->cur_altsetting->desc; |
1342 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; | 1342 | struct usb_device_descriptor *dev_desc = &serial->dev->descriptor; |
@@ -1374,6 +1374,19 @@ static int option_probe(struct usb_serial *serial, | |||
1374 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) | 1374 | iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA) |
1375 | return -ENODEV; | 1375 | return -ENODEV; |
1376 | 1376 | ||
1377 | /* Store device id so we can use it during attach. */ | ||
1378 | usb_set_serial_data(serial, (void *)id); | ||
1379 | |||
1380 | return 0; | ||
1381 | } | ||
1382 | |||
1383 | static int option_attach(struct usb_serial *serial) | ||
1384 | { | ||
1385 | struct usb_interface_descriptor *iface_desc; | ||
1386 | const struct usb_device_id *id; | ||
1387 | struct usb_wwan_intf_private *data; | ||
1388 | struct option_private *priv; | ||
1389 | |||
1377 | data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); | 1390 | data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL); |
1378 | if (!data) | 1391 | if (!data) |
1379 | return -ENOMEM; | 1392 | return -ENOMEM; |
@@ -1384,6 +1397,10 @@ static int option_probe(struct usb_serial *serial, | |||
1384 | return -ENOMEM; | 1397 | return -ENOMEM; |
1385 | } | 1398 | } |
1386 | 1399 | ||
1400 | /* Retrieve device id stored at probe. */ | ||
1401 | id = usb_get_serial_data(serial); | ||
1402 | iface_desc = &serial->interface->cur_altsetting->desc; | ||
1403 | |||
1387 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; | 1404 | priv->bInterfaceNumber = iface_desc->bInterfaceNumber; |
1388 | data->private = priv; | 1405 | data->private = priv; |
1389 | 1406 | ||
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index c3ddb65c05f2..aa148c21ea40 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -138,7 +138,6 @@ MODULE_DEVICE_TABLE(usb, id_table); | |||
138 | 138 | ||
139 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | 139 | static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) |
140 | { | 140 | { |
141 | struct usb_wwan_intf_private *data; | ||
142 | struct usb_host_interface *intf = serial->interface->cur_altsetting; | 141 | struct usb_host_interface *intf = serial->interface->cur_altsetting; |
143 | struct device *dev = &serial->dev->dev; | 142 | struct device *dev = &serial->dev->dev; |
144 | int retval = -ENODEV; | 143 | int retval = -ENODEV; |
@@ -154,13 +153,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
154 | ifnum = intf->desc.bInterfaceNumber; | 153 | ifnum = intf->desc.bInterfaceNumber; |
155 | dev_dbg(dev, "This Interface = %d\n", ifnum); | 154 | dev_dbg(dev, "This Interface = %d\n", ifnum); |
156 | 155 | ||
157 | data = kzalloc(sizeof(struct usb_wwan_intf_private), | ||
158 | GFP_KERNEL); | ||
159 | if (!data) | ||
160 | return -ENOMEM; | ||
161 | |||
162 | spin_lock_init(&data->susp_lock); | ||
163 | |||
164 | if (nintf == 1) { | 156 | if (nintf == 1) { |
165 | /* QDL mode */ | 157 | /* QDL mode */ |
166 | /* Gobi 2000 has a single altsetting, older ones have two */ | 158 | /* Gobi 2000 has a single altsetting, older ones have two */ |
@@ -253,20 +245,28 @@ done: | |||
253 | } | 245 | } |
254 | } | 246 | } |
255 | 247 | ||
256 | /* Set serial->private if not returning error */ | ||
257 | if (retval == 0) | ||
258 | usb_set_serial_data(serial, data); | ||
259 | else | ||
260 | kfree(data); | ||
261 | |||
262 | return retval; | 248 | return retval; |
263 | } | 249 | } |
264 | 250 | ||
251 | static int qc_attach(struct usb_serial *serial) | ||
252 | { | ||
253 | struct usb_wwan_intf_private *data; | ||
254 | |||
255 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
256 | if (!data) | ||
257 | return -ENOMEM; | ||
258 | |||
259 | spin_lock_init(&data->susp_lock); | ||
260 | |||
261 | usb_set_serial_data(serial, data); | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
265 | static void qc_release(struct usb_serial *serial) | 266 | static void qc_release(struct usb_serial *serial) |
266 | { | 267 | { |
267 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | 268 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); |
268 | 269 | ||
269 | /* Free the private data allocated in qcprobe */ | ||
270 | usb_set_serial_data(serial, NULL); | 270 | usb_set_serial_data(serial, NULL); |
271 | kfree(priv); | 271 | kfree(priv); |
272 | } | 272 | } |
@@ -285,8 +285,9 @@ static struct usb_serial_driver qcdevice = { | |||
285 | .write = usb_wwan_write, | 285 | .write = usb_wwan_write, |
286 | .write_room = usb_wwan_write_room, | 286 | .write_room = usb_wwan_write_room, |
287 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 287 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
288 | .attach = usb_wwan_startup, | 288 | .attach = qc_attach, |
289 | .release = qc_release, | 289 | .release = qc_release, |
290 | .port_probe = usb_wwan_port_probe, | ||
290 | .port_remove = usb_wwan_port_remove, | 291 | .port_remove = usb_wwan_port_remove, |
291 | #ifdef CONFIG_PM | 292 | #ifdef CONFIG_PM |
292 | .suspend = usb_wwan_suspend, | 293 | .suspend = usb_wwan_suspend, |
diff --git a/drivers/usb/serial/quatech2.c b/drivers/usb/serial/quatech2.c index 2cdfdcc90b37..ffcfc962ab10 100644 --- a/drivers/usb/serial/quatech2.c +++ b/drivers/usb/serial/quatech2.c | |||
@@ -143,12 +143,12 @@ static void qt2_read_bulk_callback(struct urb *urb); | |||
143 | 143 | ||
144 | static void qt2_release(struct usb_serial *serial) | 144 | static void qt2_release(struct usb_serial *serial) |
145 | { | 145 | { |
146 | int i; | 146 | struct qt2_serial_private *serial_priv; |
147 | 147 | ||
148 | kfree(usb_get_serial_data(serial)); | 148 | serial_priv = usb_get_serial_data(serial); |
149 | 149 | ||
150 | for (i = 0; i < serial->num_ports; i++) | 150 | usb_free_urb(serial_priv->read_urb); |
151 | kfree(usb_get_serial_port_data(serial->port[i])); | 151 | kfree(serial_priv); |
152 | } | 152 | } |
153 | 153 | ||
154 | static inline int calc_baud_divisor(int baudrate) | 154 | static inline int calc_baud_divisor(int baudrate) |
@@ -423,11 +423,16 @@ static void qt2_close(struct usb_serial_port *port) | |||
423 | port_priv->is_open = false; | 423 | port_priv->is_open = false; |
424 | 424 | ||
425 | spin_lock_irqsave(&port_priv->urb_lock, flags); | 425 | spin_lock_irqsave(&port_priv->urb_lock, flags); |
426 | if (port_priv->write_urb->status == -EINPROGRESS) | 426 | usb_kill_urb(port_priv->write_urb); |
427 | usb_kill_urb(port_priv->write_urb); | ||
428 | port_priv->urb_in_use = false; | 427 | port_priv->urb_in_use = false; |
429 | spin_unlock_irqrestore(&port_priv->urb_lock, flags); | 428 | spin_unlock_irqrestore(&port_priv->urb_lock, flags); |
430 | 429 | ||
430 | mutex_lock(&port->serial->disc_mutex); | ||
431 | if (port->serial->disconnected) { | ||
432 | mutex_unlock(&port->serial->disc_mutex); | ||
433 | return; | ||
434 | } | ||
435 | |||
431 | /* flush the port transmit buffer */ | 436 | /* flush the port transmit buffer */ |
432 | i = usb_control_msg(serial->dev, | 437 | i = usb_control_msg(serial->dev, |
433 | usb_rcvctrlpipe(serial->dev, 0), | 438 | usb_rcvctrlpipe(serial->dev, 0), |
@@ -459,26 +464,14 @@ static void qt2_close(struct usb_serial_port *port) | |||
459 | dev_err(&port->dev, "%s - close port failed %i\n", | 464 | dev_err(&port->dev, "%s - close port failed %i\n", |
460 | __func__, i); | 465 | __func__, i); |
461 | 466 | ||
467 | mutex_unlock(&port->serial->disc_mutex); | ||
462 | } | 468 | } |
463 | 469 | ||
464 | static void qt2_disconnect(struct usb_serial *serial) | 470 | static void qt2_disconnect(struct usb_serial *serial) |
465 | { | 471 | { |
466 | struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); | 472 | struct qt2_serial_private *serial_priv = usb_get_serial_data(serial); |
467 | struct qt2_port_private *port_priv; | ||
468 | int i; | ||
469 | |||
470 | if (serial_priv->read_urb->status == -EINPROGRESS) | ||
471 | usb_kill_urb(serial_priv->read_urb); | ||
472 | |||
473 | usb_free_urb(serial_priv->read_urb); | ||
474 | 473 | ||
475 | for (i = 0; i < serial->num_ports; i++) { | 474 | usb_kill_urb(serial_priv->read_urb); |
476 | port_priv = usb_get_serial_port_data(serial->port[i]); | ||
477 | |||
478 | if (port_priv->write_urb->status == -EINPROGRESS) | ||
479 | usb_kill_urb(port_priv->write_urb); | ||
480 | usb_free_urb(port_priv->write_urb); | ||
481 | } | ||
482 | } | 475 | } |
483 | 476 | ||
484 | static int get_serial_info(struct usb_serial_port *port, | 477 | static int get_serial_info(struct usb_serial_port *port, |
@@ -773,11 +766,9 @@ static void qt2_read_bulk_callback(struct urb *urb) | |||
773 | 766 | ||
774 | static int qt2_setup_urbs(struct usb_serial *serial) | 767 | static int qt2_setup_urbs(struct usb_serial *serial) |
775 | { | 768 | { |
776 | struct usb_serial_port *port; | ||
777 | struct usb_serial_port *port0; | 769 | struct usb_serial_port *port0; |
778 | struct qt2_serial_private *serial_priv; | 770 | struct qt2_serial_private *serial_priv; |
779 | struct qt2_port_private *port_priv; | 771 | int status; |
780 | int pcount, status; | ||
781 | 772 | ||
782 | port0 = serial->port[0]; | 773 | port0 = serial->port[0]; |
783 | 774 | ||
@@ -795,46 +786,21 @@ static int qt2_setup_urbs(struct usb_serial *serial) | |||
795 | sizeof(serial_priv->read_buffer), | 786 | sizeof(serial_priv->read_buffer), |
796 | qt2_read_bulk_callback, serial); | 787 | qt2_read_bulk_callback, serial); |
797 | 788 | ||
798 | /* setup write_urb for each port */ | ||
799 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
800 | |||
801 | port = serial->port[pcount]; | ||
802 | port_priv = usb_get_serial_port_data(port); | ||
803 | |||
804 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
805 | if (!port_priv->write_urb) { | ||
806 | dev_err(&serial->dev->dev, | ||
807 | "failed to alloc write_urb for port %i\n", | ||
808 | pcount); | ||
809 | return -ENOMEM; | ||
810 | } | ||
811 | |||
812 | usb_fill_bulk_urb(port_priv->write_urb, | ||
813 | serial->dev, | ||
814 | usb_sndbulkpipe(serial->dev, | ||
815 | port0-> | ||
816 | bulk_out_endpointAddress), | ||
817 | port_priv->write_buffer, | ||
818 | sizeof(port_priv->write_buffer), | ||
819 | qt2_write_bulk_callback, port); | ||
820 | } | ||
821 | |||
822 | status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); | 789 | status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL); |
823 | if (status != 0) { | 790 | if (status != 0) { |
824 | dev_err(&serial->dev->dev, | 791 | dev_err(&serial->dev->dev, |
825 | "%s - submit read urb failed %i\n", __func__, status); | 792 | "%s - submit read urb failed %i\n", __func__, status); |
793 | usb_free_urb(serial_priv->read_urb); | ||
826 | return status; | 794 | return status; |
827 | } | 795 | } |
828 | 796 | ||
829 | return 0; | 797 | return 0; |
830 | |||
831 | } | 798 | } |
832 | 799 | ||
833 | static int qt2_attach(struct usb_serial *serial) | 800 | static int qt2_attach(struct usb_serial *serial) |
834 | { | 801 | { |
835 | struct qt2_serial_private *serial_priv; | 802 | struct qt2_serial_private *serial_priv; |
836 | struct qt2_port_private *port_priv; | 803 | int status; |
837 | int status, pcount; | ||
838 | 804 | ||
839 | /* power on unit */ | 805 | /* power on unit */ |
840 | status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), | 806 | status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), |
@@ -854,26 +820,6 @@ static int qt2_attach(struct usb_serial *serial) | |||
854 | 820 | ||
855 | usb_set_serial_data(serial, serial_priv); | 821 | usb_set_serial_data(serial, serial_priv); |
856 | 822 | ||
857 | for (pcount = 0; pcount < serial->num_ports; pcount++) { | ||
858 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | ||
859 | if (!port_priv) { | ||
860 | dev_err(&serial->dev->dev, | ||
861 | "%s- kmalloc(%Zd) failed.\n", __func__, | ||
862 | sizeof(*port_priv)); | ||
863 | pcount--; | ||
864 | status = -ENOMEM; | ||
865 | goto attach_failed; | ||
866 | } | ||
867 | |||
868 | spin_lock_init(&port_priv->lock); | ||
869 | spin_lock_init(&port_priv->urb_lock); | ||
870 | init_waitqueue_head(&port_priv->delta_msr_wait); | ||
871 | |||
872 | port_priv->port = serial->port[pcount]; | ||
873 | |||
874 | usb_set_serial_port_data(serial->port[pcount], port_priv); | ||
875 | } | ||
876 | |||
877 | status = qt2_setup_urbs(serial); | 823 | status = qt2_setup_urbs(serial); |
878 | if (status != 0) | 824 | if (status != 0) |
879 | goto attach_failed; | 825 | goto attach_failed; |
@@ -881,14 +827,53 @@ static int qt2_attach(struct usb_serial *serial) | |||
881 | return 0; | 827 | return 0; |
882 | 828 | ||
883 | attach_failed: | 829 | attach_failed: |
884 | for (/* empty */; pcount >= 0; pcount--) { | ||
885 | port_priv = usb_get_serial_port_data(serial->port[pcount]); | ||
886 | kfree(port_priv); | ||
887 | } | ||
888 | kfree(serial_priv); | 830 | kfree(serial_priv); |
889 | return status; | 831 | return status; |
890 | } | 832 | } |
891 | 833 | ||
834 | static int qt2_port_probe(struct usb_serial_port *port) | ||
835 | { | ||
836 | struct usb_serial *serial = port->serial; | ||
837 | struct qt2_port_private *port_priv; | ||
838 | u8 bEndpointAddress; | ||
839 | |||
840 | port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); | ||
841 | if (!port_priv) | ||
842 | return -ENOMEM; | ||
843 | |||
844 | spin_lock_init(&port_priv->lock); | ||
845 | spin_lock_init(&port_priv->urb_lock); | ||
846 | init_waitqueue_head(&port_priv->delta_msr_wait); | ||
847 | port_priv->port = port; | ||
848 | |||
849 | port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL); | ||
850 | if (!port_priv->write_urb) { | ||
851 | kfree(port_priv); | ||
852 | return -ENOMEM; | ||
853 | } | ||
854 | bEndpointAddress = serial->port[0]->bulk_out_endpointAddress; | ||
855 | usb_fill_bulk_urb(port_priv->write_urb, serial->dev, | ||
856 | usb_sndbulkpipe(serial->dev, bEndpointAddress), | ||
857 | port_priv->write_buffer, | ||
858 | sizeof(port_priv->write_buffer), | ||
859 | qt2_write_bulk_callback, port); | ||
860 | |||
861 | usb_set_serial_port_data(port, port_priv); | ||
862 | |||
863 | return 0; | ||
864 | } | ||
865 | |||
866 | static int qt2_port_remove(struct usb_serial_port *port) | ||
867 | { | ||
868 | struct qt2_port_private *port_priv; | ||
869 | |||
870 | port_priv = usb_get_serial_port_data(port); | ||
871 | usb_free_urb(port_priv->write_urb); | ||
872 | kfree(port_priv); | ||
873 | |||
874 | return 0; | ||
875 | } | ||
876 | |||
892 | static int qt2_tiocmget(struct tty_struct *tty) | 877 | static int qt2_tiocmget(struct tty_struct *tty) |
893 | { | 878 | { |
894 | struct usb_serial_port *port = tty->driver_data; | 879 | struct usb_serial_port *port = tty->driver_data; |
@@ -1127,6 +1112,8 @@ static struct usb_serial_driver qt2_device = { | |||
1127 | .attach = qt2_attach, | 1112 | .attach = qt2_attach, |
1128 | .release = qt2_release, | 1113 | .release = qt2_release, |
1129 | .disconnect = qt2_disconnect, | 1114 | .disconnect = qt2_disconnect, |
1115 | .port_probe = qt2_port_probe, | ||
1116 | .port_remove = qt2_port_remove, | ||
1130 | .dtr_rts = qt2_dtr_rts, | 1117 | .dtr_rts = qt2_dtr_rts, |
1131 | .break_ctl = qt2_break_ctl, | 1118 | .break_ctl = qt2_break_ctl, |
1132 | .tiocmget = qt2_tiocmget, | 1119 | .tiocmget = qt2_tiocmget, |
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c index 01d882cf3775..270860f6bb2a 100644 --- a/drivers/usb/serial/sierra.c +++ b/drivers/usb/serial/sierra.c | |||
@@ -161,7 +161,6 @@ static int sierra_probe(struct usb_serial *serial, | |||
161 | { | 161 | { |
162 | int result = 0; | 162 | int result = 0; |
163 | struct usb_device *udev; | 163 | struct usb_device *udev; |
164 | struct sierra_intf_private *data; | ||
165 | u8 ifnum; | 164 | u8 ifnum; |
166 | 165 | ||
167 | udev = serial->dev; | 166 | udev = serial->dev; |
@@ -188,11 +187,6 @@ static int sierra_probe(struct usb_serial *serial, | |||
188 | return -ENODEV; | 187 | return -ENODEV; |
189 | } | 188 | } |
190 | 189 | ||
191 | data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL); | ||
192 | if (!data) | ||
193 | return -ENOMEM; | ||
194 | spin_lock_init(&data->susp_lock); | ||
195 | |||
196 | return result; | 190 | return result; |
197 | } | 191 | } |
198 | 192 | ||
@@ -884,11 +878,15 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on) | |||
884 | 878 | ||
885 | static int sierra_startup(struct usb_serial *serial) | 879 | static int sierra_startup(struct usb_serial *serial) |
886 | { | 880 | { |
887 | struct usb_serial_port *port; | 881 | struct sierra_intf_private *intfdata; |
888 | struct sierra_port_private *portdata; | 882 | |
889 | struct sierra_iface_info *himemoryp = NULL; | 883 | intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL); |
890 | int i; | 884 | if (!intfdata) |
891 | u8 ifnum; | 885 | return -ENOMEM; |
886 | |||
887 | spin_lock_init(&intfdata->susp_lock); | ||
888 | |||
889 | usb_set_serial_data(serial, intfdata); | ||
892 | 890 | ||
893 | /* Set Device mode to D0 */ | 891 | /* Set Device mode to D0 */ |
894 | sierra_set_power_state(serial->dev, 0x0000); | 892 | sierra_set_power_state(serial->dev, 0x0000); |
@@ -897,68 +895,71 @@ static int sierra_startup(struct usb_serial *serial) | |||
897 | if (nmea) | 895 | if (nmea) |
898 | sierra_vsc_set_nmea(serial->dev, 1); | 896 | sierra_vsc_set_nmea(serial->dev, 1); |
899 | 897 | ||
900 | /* Now setup per port private data */ | ||
901 | for (i = 0; i < serial->num_ports; i++) { | ||
902 | port = serial->port[i]; | ||
903 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | ||
904 | if (!portdata) { | ||
905 | dev_dbg(&port->dev, "%s: kmalloc for " | ||
906 | "sierra_port_private (%d) failed!\n", | ||
907 | __func__, i); | ||
908 | return -ENOMEM; | ||
909 | } | ||
910 | spin_lock_init(&portdata->lock); | ||
911 | init_usb_anchor(&portdata->active); | ||
912 | init_usb_anchor(&portdata->delayed); | ||
913 | ifnum = i; | ||
914 | /* Assume low memory requirements */ | ||
915 | portdata->num_out_urbs = N_OUT_URB; | ||
916 | portdata->num_in_urbs = N_IN_URB; | ||
917 | |||
918 | /* Determine actual memory requirements */ | ||
919 | if (serial->num_ports == 1) { | ||
920 | /* Get interface number for composite device */ | ||
921 | ifnum = sierra_calc_interface(serial); | ||
922 | himemoryp = | ||
923 | (struct sierra_iface_info *)&typeB_interface_list; | ||
924 | if (is_himemory(ifnum, himemoryp)) { | ||
925 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
926 | portdata->num_in_urbs = N_IN_URB_HM; | ||
927 | } | ||
928 | } | ||
929 | else { | ||
930 | himemoryp = | ||
931 | (struct sierra_iface_info *)&typeA_interface_list; | ||
932 | if (is_himemory(i, himemoryp)) { | ||
933 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
934 | portdata->num_in_urbs = N_IN_URB_HM; | ||
935 | } | ||
936 | } | ||
937 | dev_dbg(&serial->dev->dev, | ||
938 | "Memory usage (urbs) interface #%d, in=%d, out=%d\n", | ||
939 | ifnum,portdata->num_in_urbs, portdata->num_out_urbs ); | ||
940 | /* Set the port private data pointer */ | ||
941 | usb_set_serial_port_data(port, portdata); | ||
942 | } | ||
943 | |||
944 | return 0; | 898 | return 0; |
945 | } | 899 | } |
946 | 900 | ||
947 | static void sierra_release(struct usb_serial *serial) | 901 | static void sierra_release(struct usb_serial *serial) |
948 | { | 902 | { |
949 | int i; | 903 | struct sierra_intf_private *intfdata; |
950 | struct usb_serial_port *port; | 904 | |
905 | intfdata = usb_get_serial_data(serial); | ||
906 | kfree(intfdata); | ||
907 | } | ||
908 | |||
909 | static int sierra_port_probe(struct usb_serial_port *port) | ||
910 | { | ||
911 | struct usb_serial *serial = port->serial; | ||
951 | struct sierra_port_private *portdata; | 912 | struct sierra_port_private *portdata; |
913 | const struct sierra_iface_info *himemoryp; | ||
914 | u8 ifnum; | ||
952 | 915 | ||
953 | for (i = 0; i < serial->num_ports; ++i) { | 916 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
954 | port = serial->port[i]; | 917 | if (!portdata) |
955 | if (!port) | 918 | return -ENOMEM; |
956 | continue; | 919 | |
957 | portdata = usb_get_serial_port_data(port); | 920 | spin_lock_init(&portdata->lock); |
958 | if (!portdata) | 921 | init_usb_anchor(&portdata->active); |
959 | continue; | 922 | init_usb_anchor(&portdata->delayed); |
960 | kfree(portdata); | 923 | |
924 | /* Assume low memory requirements */ | ||
925 | portdata->num_out_urbs = N_OUT_URB; | ||
926 | portdata->num_in_urbs = N_IN_URB; | ||
927 | |||
928 | /* Determine actual memory requirements */ | ||
929 | if (serial->num_ports == 1) { | ||
930 | /* Get interface number for composite device */ | ||
931 | ifnum = sierra_calc_interface(serial); | ||
932 | himemoryp = &typeB_interface_list; | ||
933 | } else { | ||
934 | /* This is really the usb-serial port number of the interface | ||
935 | * rather than the interface number. | ||
936 | */ | ||
937 | ifnum = port->number - serial->minor; | ||
938 | himemoryp = &typeA_interface_list; | ||
961 | } | 939 | } |
940 | |||
941 | if (is_himemory(ifnum, himemoryp)) { | ||
942 | portdata->num_out_urbs = N_OUT_URB_HM; | ||
943 | portdata->num_in_urbs = N_IN_URB_HM; | ||
944 | } | ||
945 | |||
946 | dev_dbg(&port->dev, | ||
947 | "Memory usage (urbs) interface #%d, in=%d, out=%d\n", | ||
948 | ifnum, portdata->num_in_urbs, portdata->num_out_urbs); | ||
949 | |||
950 | usb_set_serial_port_data(port, portdata); | ||
951 | |||
952 | return 0; | ||
953 | } | ||
954 | |||
955 | static int sierra_port_remove(struct usb_serial_port *port) | ||
956 | { | ||
957 | struct sierra_port_private *portdata; | ||
958 | |||
959 | portdata = usb_get_serial_port_data(port); | ||
960 | kfree(portdata); | ||
961 | |||
962 | return 0; | ||
962 | } | 963 | } |
963 | 964 | ||
964 | #ifdef CONFIG_PM | 965 | #ifdef CONFIG_PM |
@@ -1062,6 +1063,8 @@ static struct usb_serial_driver sierra_device = { | |||
1062 | .tiocmset = sierra_tiocmset, | 1063 | .tiocmset = sierra_tiocmset, |
1063 | .attach = sierra_startup, | 1064 | .attach = sierra_startup, |
1064 | .release = sierra_release, | 1065 | .release = sierra_release, |
1066 | .port_probe = sierra_port_probe, | ||
1067 | .port_remove = sierra_port_remove, | ||
1065 | .suspend = sierra_suspend, | 1068 | .suspend = sierra_suspend, |
1066 | .resume = sierra_resume, | 1069 | .resume = sierra_resume, |
1067 | .read_int_callback = sierra_instat_callback, | 1070 | .read_int_callback = sierra_instat_callback, |
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index 1f034d2397c6..684739b8efd0 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h | |||
@@ -8,7 +8,7 @@ | |||
8 | extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); | 8 | extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); |
9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); | 9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); |
10 | extern void usb_wwan_close(struct usb_serial_port *port); | 10 | extern void usb_wwan_close(struct usb_serial_port *port); |
11 | extern int usb_wwan_startup(struct usb_serial *serial); | 11 | extern int usb_wwan_port_probe(struct usb_serial_port *port); |
12 | extern int usb_wwan_port_remove(struct usb_serial_port *port); | 12 | extern int usb_wwan_port_remove(struct usb_serial_port *port); |
13 | extern int usb_wwan_write_room(struct tty_struct *tty); | 13 | extern int usb_wwan_write_room(struct tty_struct *tty); |
14 | extern void usb_wwan_set_termios(struct tty_struct *tty, | 14 | extern void usb_wwan_set_termios(struct tty_struct *tty, |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index e42aa398ed37..61a73ad1a187 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -447,10 +447,12 @@ void usb_wwan_close(struct usb_serial_port *port) | |||
447 | EXPORT_SYMBOL(usb_wwan_close); | 447 | EXPORT_SYMBOL(usb_wwan_close); |
448 | 448 | ||
449 | /* Helper functions used by usb_wwan_setup_urbs */ | 449 | /* Helper functions used by usb_wwan_setup_urbs */ |
450 | static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, | 450 | static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port, |
451 | int endpoint, | ||
451 | int dir, void *ctx, char *buf, int len, | 452 | int dir, void *ctx, char *buf, int len, |
452 | void (*callback) (struct urb *)) | 453 | void (*callback) (struct urb *)) |
453 | { | 454 | { |
455 | struct usb_serial *serial = port->serial; | ||
454 | struct urb *urb; | 456 | struct urb *urb; |
455 | 457 | ||
456 | if (endpoint == -1) | 458 | if (endpoint == -1) |
@@ -472,101 +474,75 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint, | |||
472 | return urb; | 474 | return urb; |
473 | } | 475 | } |
474 | 476 | ||
475 | /* Setup urbs */ | 477 | int usb_wwan_port_probe(struct usb_serial_port *port) |
476 | static void usb_wwan_setup_urbs(struct usb_serial *serial) | ||
477 | { | 478 | { |
478 | int i, j; | ||
479 | struct usb_serial_port *port; | ||
480 | struct usb_wwan_port_private *portdata; | 479 | struct usb_wwan_port_private *portdata; |
480 | struct urb *urb; | ||
481 | u8 *buffer; | ||
482 | int err; | ||
483 | int i; | ||
481 | 484 | ||
482 | for (i = 0; i < serial->num_ports; i++) { | 485 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); |
483 | port = serial->port[i]; | 486 | if (!portdata) |
484 | portdata = usb_get_serial_port_data(port); | 487 | return -ENOMEM; |
485 | 488 | ||
486 | /* Do indat endpoints first */ | 489 | init_usb_anchor(&portdata->delayed); |
487 | for (j = 0; j < N_IN_URB; ++j) { | ||
488 | portdata->in_urbs[j] = usb_wwan_setup_urb(serial, | ||
489 | port-> | ||
490 | bulk_in_endpointAddress, | ||
491 | USB_DIR_IN, | ||
492 | port, | ||
493 | portdata-> | ||
494 | in_buffer[j], | ||
495 | IN_BUFLEN, | ||
496 | usb_wwan_indat_callback); | ||
497 | } | ||
498 | 490 | ||
499 | /* outdat endpoints */ | 491 | for (i = 0; i < N_IN_URB; i++) { |
500 | for (j = 0; j < N_OUT_URB; ++j) { | 492 | buffer = (u8 *)__get_free_page(GFP_KERNEL); |
501 | portdata->out_urbs[j] = usb_wwan_setup_urb(serial, | 493 | if (!buffer) |
502 | port-> | 494 | goto bail_out_error; |
503 | bulk_out_endpointAddress, | 495 | portdata->in_buffer[i] = buffer; |
504 | USB_DIR_OUT, | 496 | |
505 | port, | 497 | urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress, |
506 | portdata-> | 498 | USB_DIR_IN, port, |
507 | out_buffer | 499 | buffer, IN_BUFLEN, |
508 | [j], | 500 | usb_wwan_indat_callback); |
509 | OUT_BUFLEN, | 501 | portdata->in_urbs[i] = urb; |
510 | usb_wwan_outdat_callback); | ||
511 | } | ||
512 | } | 502 | } |
513 | } | ||
514 | |||
515 | int usb_wwan_startup(struct usb_serial *serial) | ||
516 | { | ||
517 | int i, j, err; | ||
518 | struct usb_serial_port *port; | ||
519 | struct usb_wwan_port_private *portdata; | ||
520 | u8 *buffer; | ||
521 | 503 | ||
522 | /* Now setup per port private data */ | 504 | for (i = 0; i < N_OUT_URB; i++) { |
523 | for (i = 0; i < serial->num_ports; i++) { | 505 | if (port->bulk_out_endpointAddress == -1) |
524 | port = serial->port[i]; | 506 | continue; |
525 | portdata = kzalloc(sizeof(*portdata), GFP_KERNEL); | ||
526 | if (!portdata) { | ||
527 | dev_dbg(&port->dev, "%s: kmalloc for usb_wwan_port_private (%d) failed!.\n", | ||
528 | __func__, i); | ||
529 | return 1; | ||
530 | } | ||
531 | init_usb_anchor(&portdata->delayed); | ||
532 | 507 | ||
533 | for (j = 0; j < N_IN_URB; j++) { | 508 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); |
534 | buffer = (u8 *) __get_free_page(GFP_KERNEL); | 509 | if (!buffer) |
535 | if (!buffer) | 510 | goto bail_out_error2; |
536 | goto bail_out_error; | 511 | portdata->out_buffer[i] = buffer; |
537 | portdata->in_buffer[j] = buffer; | ||
538 | } | ||
539 | 512 | ||
540 | for (j = 0; j < N_OUT_URB; j++) { | 513 | urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress, |
541 | buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL); | 514 | USB_DIR_OUT, port, |
542 | if (!buffer) | 515 | buffer, OUT_BUFLEN, |
543 | goto bail_out_error2; | 516 | usb_wwan_outdat_callback); |
544 | portdata->out_buffer[j] = buffer; | 517 | portdata->out_urbs[i] = urb; |
545 | } | 518 | } |
546 | 519 | ||
547 | usb_set_serial_port_data(port, portdata); | 520 | usb_set_serial_port_data(port, portdata); |
548 | 521 | ||
549 | if (!port->interrupt_in_urb) | 522 | if (port->interrupt_in_urb) { |
550 | continue; | ||
551 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); | 523 | err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL); |
552 | if (err) | 524 | if (err) |
553 | dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", | 525 | dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n", |
554 | __func__, err); | 526 | __func__, err); |
555 | } | 527 | } |
556 | usb_wwan_setup_urbs(serial); | 528 | |
557 | return 0; | 529 | return 0; |
558 | 530 | ||
559 | bail_out_error2: | 531 | bail_out_error2: |
560 | for (j = 0; j < N_OUT_URB; j++) | 532 | for (i = 0; i < N_OUT_URB; i++) { |
561 | kfree(portdata->out_buffer[j]); | 533 | usb_free_urb(portdata->out_urbs[i]); |
534 | kfree(portdata->out_buffer[i]); | ||
535 | } | ||
562 | bail_out_error: | 536 | bail_out_error: |
563 | for (j = 0; j < N_IN_URB; j++) | 537 | for (i = 0; i < N_IN_URB; i++) { |
564 | if (portdata->in_buffer[j]) | 538 | usb_free_urb(portdata->in_urbs[i]); |
565 | free_page((unsigned long)portdata->in_buffer[j]); | 539 | free_page((unsigned long)portdata->in_buffer[i]); |
540 | } | ||
566 | kfree(portdata); | 541 | kfree(portdata); |
567 | return 1; | 542 | |
543 | return -ENOMEM; | ||
568 | } | 544 | } |
569 | EXPORT_SYMBOL(usb_wwan_startup); | 545 | EXPORT_SYMBOL_GPL(usb_wwan_port_probe); |
570 | 546 | ||
571 | int usb_wwan_port_remove(struct usb_serial_port *port) | 547 | int usb_wwan_port_remove(struct usb_serial_port *port) |
572 | { | 548 | { |
diff --git a/drivers/usb/serial/whiteheat.c b/drivers/usb/serial/whiteheat.c index 346c7efc20b0..b9fca3586d74 100644 --- a/drivers/usb/serial/whiteheat.c +++ b/drivers/usb/serial/whiteheat.c | |||
@@ -83,6 +83,8 @@ static int whiteheat_firmware_attach(struct usb_serial *serial); | |||
83 | /* function prototypes for the Connect Tech WhiteHEAT serial converter */ | 83 | /* function prototypes for the Connect Tech WhiteHEAT serial converter */ |
84 | static int whiteheat_attach(struct usb_serial *serial); | 84 | static int whiteheat_attach(struct usb_serial *serial); |
85 | static void whiteheat_release(struct usb_serial *serial); | 85 | static void whiteheat_release(struct usb_serial *serial); |
86 | static int whiteheat_port_probe(struct usb_serial_port *port); | ||
87 | static int whiteheat_port_remove(struct usb_serial_port *port); | ||
86 | static int whiteheat_open(struct tty_struct *tty, | 88 | static int whiteheat_open(struct tty_struct *tty, |
87 | struct usb_serial_port *port); | 89 | struct usb_serial_port *port); |
88 | static void whiteheat_close(struct usb_serial_port *port); | 90 | static void whiteheat_close(struct usb_serial_port *port); |
@@ -117,6 +119,8 @@ static struct usb_serial_driver whiteheat_device = { | |||
117 | .num_ports = 4, | 119 | .num_ports = 4, |
118 | .attach = whiteheat_attach, | 120 | .attach = whiteheat_attach, |
119 | .release = whiteheat_release, | 121 | .release = whiteheat_release, |
122 | .port_probe = whiteheat_port_probe, | ||
123 | .port_remove = whiteheat_port_remove, | ||
120 | .open = whiteheat_open, | 124 | .open = whiteheat_open, |
121 | .close = whiteheat_close, | 125 | .close = whiteheat_close, |
122 | .ioctl = whiteheat_ioctl, | 126 | .ioctl = whiteheat_ioctl, |
@@ -218,15 +222,12 @@ static int whiteheat_attach(struct usb_serial *serial) | |||
218 | { | 222 | { |
219 | struct usb_serial_port *command_port; | 223 | struct usb_serial_port *command_port; |
220 | struct whiteheat_command_private *command_info; | 224 | struct whiteheat_command_private *command_info; |
221 | struct usb_serial_port *port; | ||
222 | struct whiteheat_private *info; | ||
223 | struct whiteheat_hw_info *hw_info; | 225 | struct whiteheat_hw_info *hw_info; |
224 | int pipe; | 226 | int pipe; |
225 | int ret; | 227 | int ret; |
226 | int alen; | 228 | int alen; |
227 | __u8 *command; | 229 | __u8 *command; |
228 | __u8 *result; | 230 | __u8 *result; |
229 | int i; | ||
230 | 231 | ||
231 | command_port = serial->port[COMMAND_PORT]; | 232 | command_port = serial->port[COMMAND_PORT]; |
232 | 233 | ||
@@ -285,22 +286,6 @@ static int whiteheat_attach(struct usb_serial *serial) | |||
285 | serial->type->description, | 286 | serial->type->description, |
286 | hw_info->sw_major_rev, hw_info->sw_minor_rev); | 287 | hw_info->sw_major_rev, hw_info->sw_minor_rev); |
287 | 288 | ||
288 | for (i = 0; i < serial->num_ports; i++) { | ||
289 | port = serial->port[i]; | ||
290 | |||
291 | info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL); | ||
292 | if (info == NULL) { | ||
293 | dev_err(&port->dev, | ||
294 | "%s: Out of memory for port structures\n", | ||
295 | serial->type->description); | ||
296 | goto no_private; | ||
297 | } | ||
298 | |||
299 | info->mcr = 0; | ||
300 | |||
301 | usb_set_serial_port_data(port, info); | ||
302 | } | ||
303 | |||
304 | command_info = kmalloc(sizeof(struct whiteheat_command_private), | 289 | command_info = kmalloc(sizeof(struct whiteheat_command_private), |
305 | GFP_KERNEL); | 290 | GFP_KERNEL); |
306 | if (command_info == NULL) { | 291 | if (command_info == NULL) { |
@@ -333,16 +318,10 @@ no_firmware: | |||
333 | "%s: please contact support@connecttech.com\n", | 318 | "%s: please contact support@connecttech.com\n", |
334 | serial->type->description); | 319 | serial->type->description); |
335 | kfree(result); | 320 | kfree(result); |
321 | kfree(command); | ||
336 | return -ENODEV; | 322 | return -ENODEV; |
337 | 323 | ||
338 | no_command_private: | 324 | no_command_private: |
339 | for (i = serial->num_ports - 1; i >= 0; i--) { | ||
340 | port = serial->port[i]; | ||
341 | info = usb_get_serial_port_data(port); | ||
342 | kfree(info); | ||
343 | no_private: | ||
344 | ; | ||
345 | } | ||
346 | kfree(result); | 325 | kfree(result); |
347 | no_result_buffer: | 326 | no_result_buffer: |
348 | kfree(command); | 327 | kfree(command); |
@@ -350,21 +329,36 @@ no_command_buffer: | |||
350 | return -ENOMEM; | 329 | return -ENOMEM; |
351 | } | 330 | } |
352 | 331 | ||
353 | |||
354 | static void whiteheat_release(struct usb_serial *serial) | 332 | static void whiteheat_release(struct usb_serial *serial) |
355 | { | 333 | { |
356 | struct usb_serial_port *command_port; | 334 | struct usb_serial_port *command_port; |
357 | struct whiteheat_private *info; | ||
358 | int i; | ||
359 | 335 | ||
360 | /* free up our private data for our command port */ | 336 | /* free up our private data for our command port */ |
361 | command_port = serial->port[COMMAND_PORT]; | 337 | command_port = serial->port[COMMAND_PORT]; |
362 | kfree(usb_get_serial_port_data(command_port)); | 338 | kfree(usb_get_serial_port_data(command_port)); |
339 | } | ||
363 | 340 | ||
364 | for (i = 0; i < serial->num_ports; i++) { | 341 | static int whiteheat_port_probe(struct usb_serial_port *port) |
365 | info = usb_get_serial_port_data(serial->port[i]); | 342 | { |
366 | kfree(info); | 343 | struct whiteheat_private *info; |
367 | } | 344 | |
345 | info = kzalloc(sizeof(*info), GFP_KERNEL); | ||
346 | if (!info) | ||
347 | return -ENOMEM; | ||
348 | |||
349 | usb_set_serial_port_data(port, info); | ||
350 | |||
351 | return 0; | ||
352 | } | ||
353 | |||
354 | static int whiteheat_port_remove(struct usb_serial_port *port) | ||
355 | { | ||
356 | struct whiteheat_private *info; | ||
357 | |||
358 | info = usb_get_serial_port_data(port); | ||
359 | kfree(info); | ||
360 | |||
361 | return 0; | ||
368 | } | 362 | } |
369 | 363 | ||
370 | static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) | 364 | static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port) |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index 779cd954abcb..d305a5aa3a5d 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -1004,6 +1004,12 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999, | |||
1004 | USB_SC_8070, USB_PR_CB, NULL, | 1004 | USB_SC_8070, USB_PR_CB, NULL, |
1005 | US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), | 1005 | US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ), |
1006 | 1006 | ||
1007 | /* Submitted by Oleksandr Chumachenko <ledest@gmail.com> */ | ||
1008 | UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100, | ||
1009 | "Casio", | ||
1010 | "EX-N1 DigitalCamera", | ||
1011 | USB_SC_8070, USB_PR_DEVICE, NULL, 0), | ||
1012 | |||
1007 | /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ | 1013 | /* Submitted by Hartmut Wahl <hwahl@hwahl.de>*/ |
1008 | UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, | 1014 | UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001, |
1009 | "Samsung", | 1015 | "Samsung", |