diff options
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", |
