mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-30 11:41:38 -04:00
Merge branches 'cache-l2x0', 'fixes', 'hdrs', 'misc', 'mmci', 'vic' and 'warnings' into for-next
This commit is contained in:
commit
0b99cb7310
1701 changed files with 22594 additions and 16325 deletions
|
|
@ -817,10 +817,6 @@ static const __u32 acm_tty_speed[] = {
|
|||
2500000, 3000000, 3500000, 4000000
|
||||
};
|
||||
|
||||
static const __u8 acm_tty_size[] = {
|
||||
5, 6, 7, 8
|
||||
};
|
||||
|
||||
static void acm_tty_set_termios(struct tty_struct *tty,
|
||||
struct ktermios *termios_old)
|
||||
{
|
||||
|
|
@ -834,7 +830,21 @@ static void acm_tty_set_termios(struct tty_struct *tty,
|
|||
newline.bParityType = termios->c_cflag & PARENB ?
|
||||
(termios->c_cflag & PARODD ? 1 : 2) +
|
||||
(termios->c_cflag & CMSPAR ? 2 : 0) : 0;
|
||||
newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4];
|
||||
switch (termios->c_cflag & CSIZE) {
|
||||
case CS5:
|
||||
newline.bDataBits = 5;
|
||||
break;
|
||||
case CS6:
|
||||
newline.bDataBits = 6;
|
||||
break;
|
||||
case CS7:
|
||||
newline.bDataBits = 7;
|
||||
break;
|
||||
case CS8:
|
||||
default:
|
||||
newline.bDataBits = 8;
|
||||
break;
|
||||
}
|
||||
/* FIXME: Needs to clear unsupported bits in the termios */
|
||||
acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
|
||||
|
||||
|
|
@ -1233,7 +1243,7 @@ made_compressed_probe:
|
|||
|
||||
if (usb_endpoint_xfer_int(epwrite))
|
||||
usb_fill_int_urb(snd->urb, usb_dev,
|
||||
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
|
||||
usb_sndintpipe(usb_dev, epwrite->bEndpointAddress),
|
||||
NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
|
||||
else
|
||||
usb_fill_bulk_urb(snd->urb, usb_dev,
|
||||
|
|
|
|||
|
|
@ -1348,6 +1348,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
|
|||
ret = -EFAULT;
|
||||
goto error;
|
||||
}
|
||||
uurb->buffer += u;
|
||||
}
|
||||
totlen -= u;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -367,6 +367,10 @@ static int usb_probe_interface(struct device *dev)
|
|||
intf->condition = USB_INTERFACE_UNBOUND;
|
||||
usb_cancel_queued_reset(intf);
|
||||
|
||||
/* If the LPM disable succeeded, balance the ref counts. */
|
||||
if (!lpm_disable_error)
|
||||
usb_unlocked_enable_lpm(udev);
|
||||
|
||||
/* Unbound interfaces are always runtime-PM-disabled and -suspended */
|
||||
if (driver->supports_autosuspend)
|
||||
pm_runtime_disable(dev);
|
||||
|
|
|
|||
|
|
@ -2151,8 +2151,15 @@ EXPORT_SYMBOL_GPL(usb_bus_start_enum);
|
|||
irqreturn_t usb_hcd_irq (int irq, void *__hcd)
|
||||
{
|
||||
struct usb_hcd *hcd = __hcd;
|
||||
unsigned long flags;
|
||||
irqreturn_t rc;
|
||||
|
||||
/* IRQF_DISABLED doesn't work correctly with shared IRQs
|
||||
* when the first handler doesn't use it. So let's just
|
||||
* assume it's never used.
|
||||
*/
|
||||
local_irq_save(flags);
|
||||
|
||||
if (unlikely(HCD_DEAD(hcd) || !HCD_HW_ACCESSIBLE(hcd)))
|
||||
rc = IRQ_NONE;
|
||||
else if (hcd->driver->irq(hcd) == IRQ_NONE)
|
||||
|
|
@ -2160,6 +2167,7 @@ irqreturn_t usb_hcd_irq (int irq, void *__hcd)
|
|||
else
|
||||
rc = IRQ_HANDLED;
|
||||
|
||||
local_irq_restore(flags);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(usb_hcd_irq);
|
||||
|
|
@ -2347,6 +2355,14 @@ static int usb_hcd_request_irqs(struct usb_hcd *hcd,
|
|||
int retval;
|
||||
|
||||
if (hcd->driver->irq) {
|
||||
|
||||
/* IRQF_DISABLED doesn't work as advertised when used together
|
||||
* with IRQF_SHARED. As usb_hcd_irq() will always disable
|
||||
* interrupts we can remove it here.
|
||||
*/
|
||||
if (irqflags & IRQF_SHARED)
|
||||
irqflags &= ~IRQF_DISABLED;
|
||||
|
||||
snprintf(hcd->irq_descr, sizeof(hcd->irq_descr), "%s:usb%d",
|
||||
hcd->driver->description, hcd->self.busnum);
|
||||
retval = request_irq(irqnum, &usb_hcd_irq, irqflags,
|
||||
|
|
|
|||
|
|
@ -739,13 +739,16 @@ static void hub_tt_work(struct work_struct *work)
|
|||
int limit = 100;
|
||||
|
||||
spin_lock_irqsave (&hub->tt.lock, flags);
|
||||
while (--limit && !list_empty (&hub->tt.clear_list)) {
|
||||
while (!list_empty(&hub->tt.clear_list)) {
|
||||
struct list_head *next;
|
||||
struct usb_tt_clear *clear;
|
||||
struct usb_device *hdev = hub->hdev;
|
||||
const struct hc_driver *drv;
|
||||
int status;
|
||||
|
||||
if (!hub->quiescing && --limit < 0)
|
||||
break;
|
||||
|
||||
next = hub->tt.clear_list.next;
|
||||
clear = list_entry (next, struct usb_tt_clear, clear_list);
|
||||
list_del (&clear->clear_list);
|
||||
|
|
@ -1210,7 +1213,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type)
|
|||
if (hub->has_indicators)
|
||||
cancel_delayed_work_sync(&hub->leds);
|
||||
if (hub->tt.hub)
|
||||
cancel_work_sync(&hub->tt.clear_work);
|
||||
flush_work(&hub->tt.clear_work);
|
||||
}
|
||||
|
||||
/* caller has locked the hub device */
|
||||
|
|
@ -3241,8 +3244,7 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state)
|
|||
(state == USB3_LPM_U2 &&
|
||||
(u2_sel > USB3_LPM_MAX_U2_SEL_PEL ||
|
||||
u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) {
|
||||
dev_dbg(&udev->dev, "Device-initiated %s disabled due "
|
||||
"to long SEL %llu ms or PEL %llu ms\n",
|
||||
dev_dbg(&udev->dev, "Device-initiated %s disabled due to long SEL %llu us or PEL %llu us\n",
|
||||
usb3_lpm_names[state], u1_sel, u1_pel);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
@ -3319,16 +3321,6 @@ static int usb_set_device_initiated_lpm(struct usb_device *udev,
|
|||
}
|
||||
|
||||
if (enable) {
|
||||
/*
|
||||
* First, let the device know about the exit latencies
|
||||
* associated with the link state we're about to enable.
|
||||
*/
|
||||
ret = usb_req_set_sel(udev, state);
|
||||
if (ret < 0) {
|
||||
dev_warn(&udev->dev, "Set SEL for device-initiated "
|
||||
"%s failed.\n", usb3_lpm_names[state]);
|
||||
return -EBUSY;
|
||||
}
|
||||
/*
|
||||
* Now send the control transfer to enable device-initiated LPM
|
||||
* for either U1 or U2.
|
||||
|
|
@ -3414,7 +3406,28 @@ static int usb_set_lpm_timeout(struct usb_device *udev,
|
|||
static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev,
|
||||
enum usb3_link_state state)
|
||||
{
|
||||
int timeout;
|
||||
int timeout, ret;
|
||||
__u8 u1_mel = udev->bos->ss_cap->bU1devExitLat;
|
||||
__le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat;
|
||||
|
||||
/* If the device says it doesn't have *any* exit latency to come out of
|
||||
* U1 or U2, it's probably lying. Assume it doesn't implement that link
|
||||
* state.
|
||||
*/
|
||||
if ((state == USB3_LPM_U1 && u1_mel == 0) ||
|
||||
(state == USB3_LPM_U2 && u2_mel == 0))
|
||||
return;
|
||||
|
||||
/*
|
||||
* First, let the device know about the exit latencies
|
||||
* associated with the link state we're about to enable.
|
||||
*/
|
||||
ret = usb_req_set_sel(udev, state);
|
||||
if (ret < 0) {
|
||||
dev_warn(&udev->dev, "Set SEL for device-initiated %s failed.\n",
|
||||
usb3_lpm_names[state]);
|
||||
return;
|
||||
}
|
||||
|
||||
/* We allow the host controller to set the U1/U2 timeout internally
|
||||
* first, so that it can change its schedule to account for the
|
||||
|
|
|
|||
|
|
@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc)
|
|||
{
|
||||
dwc3_event_buffers_cleanup(dwc);
|
||||
dwc3_free_event_buffers(dwc);
|
||||
|
||||
usb_phy_shutdown(dwc->usb2_phy);
|
||||
usb_phy_shutdown(dwc->usb3_phy);
|
||||
|
||||
}
|
||||
|
||||
#define DWC3_ALIGN_MASK (16 - 1)
|
||||
|
|
|
|||
|
|
@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)
|
|||
ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, ¶ms);
|
||||
WARN_ON_ONCE(ret);
|
||||
dep->resource_index = 0;
|
||||
|
||||
dep->flags &= ~DWC3_EP_BUSY;
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/usb/ehci_def.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/serial_core.h>
|
||||
#include <linux/kconfig.h>
|
||||
#include <linux/kgdb.h>
|
||||
#include <linux/kthread.h>
|
||||
#include <asm/io.h>
|
||||
|
|
@ -614,12 +615,6 @@ err:
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
int dbgp_external_startup(struct usb_hcd *hcd)
|
||||
{
|
||||
return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dbgp_external_startup);
|
||||
|
||||
static int ehci_reset_port(int port)
|
||||
{
|
||||
u32 portsc;
|
||||
|
|
@ -979,6 +974,7 @@ struct console early_dbgp_console = {
|
|||
.index = -1,
|
||||
};
|
||||
|
||||
#if IS_ENABLED(CONFIG_USB_EHCI_HCD)
|
||||
int dbgp_reset_prep(struct usb_hcd *hcd)
|
||||
{
|
||||
int ret = xen_dbgp_reset_prep(hcd);
|
||||
|
|
@ -1007,6 +1003,13 @@ int dbgp_reset_prep(struct usb_hcd *hcd)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(dbgp_reset_prep);
|
||||
|
||||
int dbgp_external_startup(struct usb_hcd *hcd)
|
||||
{
|
||||
return xen_dbgp_external_startup(hcd) ?: _dbgp_external_startup();
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(dbgp_external_startup);
|
||||
#endif /* USB_EHCI_HCD */
|
||||
|
||||
#ifdef CONFIG_KGDB
|
||||
|
||||
static char kgdbdbgp_buf[DBGP_MAX_PACKET];
|
||||
|
|
|
|||
|
|
@ -952,6 +952,7 @@ endif
|
|||
config USB_G_WEBCAM
|
||||
tristate "USB Webcam Gadget"
|
||||
depends on VIDEO_DEV
|
||||
select USB_LIBCOMPOSITE
|
||||
help
|
||||
The Webcam Gadget acts as a composite USB Audio and Video Class
|
||||
device. It provides a userspace API to process UVC control requests
|
||||
|
|
|
|||
|
|
@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work)
|
|||
|
||||
/* Get the VBUS status from the transceiver */
|
||||
value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client,
|
||||
ISP1301_I2C_OTG_CONTROL_2);
|
||||
ISP1301_I2C_INTERRUPT_SOURCE);
|
||||
|
||||
/* VBUS on or off? */
|
||||
if (value & OTG_B_SESS_VLD)
|
||||
if (value & INT_SESS_VLD)
|
||||
udc->vbus = 1;
|
||||
else
|
||||
udc->vbus = 0;
|
||||
|
|
|
|||
|
|
@ -2069,8 +2069,10 @@ static irqreturn_t net2272_irq(int irq, void *_dev)
|
|||
#if defined(PLX_PCI_RDK2)
|
||||
/* see if PCI int for us by checking irqstat */
|
||||
intcsr = readl(dev->rdk2.fpga_base_addr + RDK2_IRQSTAT);
|
||||
if (!intcsr & (1 << NET2272_PCI_IRQ))
|
||||
if (!intcsr & (1 << NET2272_PCI_IRQ)) {
|
||||
spin_unlock(&dev->lock);
|
||||
return IRQ_NONE;
|
||||
}
|
||||
/* check dma interrupts */
|
||||
#endif
|
||||
/* Platform/devcice interrupt handler */
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
#include <linux/list.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/platform_data/pxa2xx_udc.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/irq.h>
|
||||
|
|
@ -59,9 +60,6 @@
|
|||
#include <mach/lubbock.h>
|
||||
#endif
|
||||
|
||||
#include <asm/mach/udc_pxa2xx.h>
|
||||
|
||||
|
||||
/*
|
||||
* This driver handles the USB Device Controller (UDC) in Intel's PXA 25x
|
||||
* series processors. The UDC for the IXP 4xx series is very similar.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include <linux/ctype.h>
|
||||
#include <linux/etherdevice.h>
|
||||
#include <linux/ethtool.h>
|
||||
#include <linux/if_vlan.h>
|
||||
|
||||
#include "u_ether.h"
|
||||
|
||||
|
|
@ -295,7 +296,7 @@ static void rx_complete(struct usb_ep *ep, struct usb_request *req)
|
|||
while (skb2) {
|
||||
if (status < 0
|
||||
|| ETH_HLEN > skb2->len
|
||||
|| skb2->len > ETH_FRAME_LEN) {
|
||||
|| skb2->len > VLAN_ETH_FRAME_LEN) {
|
||||
dev->net->stats.rx_errors++;
|
||||
dev->net->stats.rx_length_errors++;
|
||||
DBG(dev, "rx length %d\n", skb2->len);
|
||||
|
|
|
|||
|
|
@ -222,7 +222,7 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd,
|
|||
|
||||
if (pdata->controller_ver < 0) {
|
||||
dev_warn(hcd->self.controller, "Could not get controller version\n");
|
||||
return;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
portsc = ehci_readl(ehci, &ehci->regs->port_status[port_offset]);
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ static int ehci_hcd_ls1x_probe(struct platform_device *pdev)
|
|||
goto err_put_hcd;
|
||||
}
|
||||
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||
ret = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
|
||||
if (ret)
|
||||
goto err_put_hcd;
|
||||
|
||||
|
|
|
|||
|
|
@ -160,7 +160,7 @@ static const struct hc_driver ehci_orion_hc_driver = {
|
|||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
static void __init
|
||||
static void __devinit
|
||||
ehci_orion_conf_mbus_windows(struct usb_hcd *hcd,
|
||||
const struct mbus_dram_target_info *dram)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -85,6 +85,8 @@ static const struct hc_driver vt8500_ehci_hc_driver = {
|
|||
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
|
||||
};
|
||||
|
||||
static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int vt8500_ehci_drv_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct usb_hcd *hcd;
|
||||
|
|
@ -95,6 +97,14 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev)
|
|||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Right now device-tree probed devices don't get dma_mask set.
|
||||
* Since shared usb code relies on it, set it here for now.
|
||||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &vt8500_ehci_dma_mask;
|
||||
|
||||
if (pdev->resource[1].flags != IORESOURCE_IRQ) {
|
||||
pr_debug("resource[1] is not IORESOURCE_IRQ");
|
||||
return -ENOMEM;
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ static int ohci_xls_probe_internal(const struct hc_driver *driver,
|
|||
goto err3;
|
||||
}
|
||||
|
||||
retval = usb_add_hcd(hcd, irq, IRQF_SHARED);
|
||||
retval = usb_add_hcd(hcd, irq, IRQF_DISABLED | IRQF_SHARED);
|
||||
if (retval != 0)
|
||||
goto err4;
|
||||
return retval;
|
||||
|
|
|
|||
|
|
@ -545,7 +545,14 @@ static const struct dmi_system_id __devinitconst ehci_dmi_nohandoff_table[] = {
|
|||
/* Pegatron Lucid (Ordissimo AIRIS) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "M11JB"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "Lucid-GE-133"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
|
||||
},
|
||||
},
|
||||
{
|
||||
/* Pegatron Lucid (Ordissimo) */
|
||||
.matches = {
|
||||
DMI_MATCH(DMI_BOARD_NAME, "Ordissimo"),
|
||||
DMI_MATCH(DMI_BIOS_VERSION, "Lucid-"),
|
||||
},
|
||||
},
|
||||
{ }
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ static const struct hc_driver uhci_platform_hc_driver = {
|
|||
.hub_control = uhci_hub_control,
|
||||
};
|
||||
|
||||
static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
|
||||
|
||||
static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
|
||||
{
|
||||
|
|
@ -71,6 +72,14 @@ static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
|
|||
if (usb_disabled())
|
||||
return -ENODEV;
|
||||
|
||||
/*
|
||||
* Right now device-tree probed devices don't get dma_mask set.
|
||||
* Since shared usb code relies on it, set it here for now.
|
||||
* Once we have dma capability bindings this can go away.
|
||||
*/
|
||||
if (!pdev->dev.dma_mask)
|
||||
pdev->dev.dma_mask = &platform_uhci_dma_mask;
|
||||
|
||||
hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
|
||||
pdev->name);
|
||||
if (!hcd)
|
||||
|
|
|
|||
|
|
@ -544,7 +544,6 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci,
|
|||
int i;
|
||||
/* Fields are 32 bits wide, DMA addresses are in bytes */
|
||||
int field_size = 32 / 8;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
dma_addr_t dma = ctx->dma;
|
||||
int csz = HCC_64BYTE_CONTEXT(xhci->hcc_params);
|
||||
|
||||
|
|
@ -570,7 +569,6 @@ void xhci_dbg_ctx(struct xhci_hcd *xhci,
|
|||
dbg_rsvd64(xhci, (u64 *)ctrl_ctx, dma);
|
||||
}
|
||||
|
||||
slot_ctx = xhci_get_slot_ctx(xhci, ctx);
|
||||
xhci_dbg_slot_ctx(xhci, ctx);
|
||||
xhci_dbg_ep_ctx(xhci, ctx, last_ep);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,9 +151,8 @@ static void xhci_usb3_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
|
|||
if (portsc & PORT_DEV_REMOVE)
|
||||
port_removable |= 1 << (i + 1);
|
||||
}
|
||||
memset(&desc->u.ss.DeviceRemovable,
|
||||
(__force __u16) cpu_to_le16(port_removable),
|
||||
sizeof(__u16));
|
||||
|
||||
desc->u.ss.DeviceRemovable = cpu_to_le16(port_removable);
|
||||
}
|
||||
|
||||
static void xhci_hub_descriptor(struct usb_hcd *hcd, struct xhci_hcd *xhci,
|
||||
|
|
@ -809,11 +808,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|||
temp = xhci_readl(xhci, port_array[wIndex]);
|
||||
xhci_dbg(xhci, "set port power, actual port %d status = 0x%x\n", wIndex, temp);
|
||||
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
temp = usb_acpi_power_manageable(hcd->self.root_hub,
|
||||
wIndex);
|
||||
if (temp)
|
||||
usb_acpi_set_power_state(hcd->self.root_hub,
|
||||
wIndex, true);
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
break;
|
||||
case USB_PORT_FEAT_RESET:
|
||||
temp = (temp | PORT_RESET);
|
||||
|
|
@ -917,11 +918,13 @@ int xhci_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
|
|||
xhci_writel(xhci, temp & ~PORT_POWER,
|
||||
port_array[wIndex]);
|
||||
|
||||
spin_unlock_irqrestore(&xhci->lock, flags);
|
||||
temp = usb_acpi_power_manageable(hcd->self.root_hub,
|
||||
wIndex);
|
||||
if (temp)
|
||||
usb_acpi_set_power_state(hcd->self.root_hub,
|
||||
wIndex, false);
|
||||
spin_lock_irqsave(&xhci->lock, flags);
|
||||
break;
|
||||
default:
|
||||
goto error;
|
||||
|
|
|
|||
|
|
@ -1228,6 +1228,17 @@ static void xhci_cmd_to_noop(struct xhci_hcd *xhci, struct xhci_cd *cur_cd)
|
|||
cur_seg = find_trb_seg(xhci->cmd_ring->first_seg,
|
||||
xhci->cmd_ring->dequeue, &cycle_state);
|
||||
|
||||
if (!cur_seg) {
|
||||
xhci_warn(xhci, "Command ring mismatch, dequeue = %p %llx (dma)\n",
|
||||
xhci->cmd_ring->dequeue,
|
||||
(unsigned long long)
|
||||
xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg,
|
||||
xhci->cmd_ring->dequeue));
|
||||
xhci_debug_ring(xhci, xhci->cmd_ring);
|
||||
xhci_dbg_ring_ptrs(xhci, xhci->cmd_ring);
|
||||
return;
|
||||
}
|
||||
|
||||
/* find the command trb matched by cd from command ring */
|
||||
for (cmd_trb = xhci->cmd_ring->dequeue;
|
||||
cmd_trb != xhci->cmd_ring->enqueue;
|
||||
|
|
|
|||
|
|
@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
|
|||
|
||||
if (strstr(dmi_product_name, "Z420") ||
|
||||
strstr(dmi_product_name, "Z620") ||
|
||||
strstr(dmi_product_name, "Z820"))
|
||||
strstr(dmi_product_name, "Z820") ||
|
||||
strstr(dmi_product_name, "Z1"))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
|
@ -1626,7 +1627,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
struct xhci_hcd *xhci;
|
||||
struct xhci_container_ctx *in_ctx, *out_ctx;
|
||||
unsigned int ep_index;
|
||||
struct xhci_ep_ctx *ep_ctx;
|
||||
struct xhci_slot_ctx *slot_ctx;
|
||||
struct xhci_input_control_ctx *ctrl_ctx;
|
||||
u32 added_ctxs;
|
||||
|
|
@ -1662,7 +1662,6 @@ int xhci_add_endpoint(struct usb_hcd *hcd, struct usb_device *udev,
|
|||
out_ctx = virt_dev->out_ctx;
|
||||
ctrl_ctx = xhci_get_input_control_ctx(xhci, in_ctx);
|
||||
ep_index = xhci_get_endpoint_index(&ep->desc);
|
||||
ep_ctx = xhci_get_ep_ctx(xhci, out_ctx, ep_index);
|
||||
|
||||
/* If this endpoint is already in use, and the upper layers are trying
|
||||
* to add it again without dropping it, reject the addition.
|
||||
|
|
@ -1816,6 +1815,8 @@ static int xhci_evaluate_context_result(struct xhci_hcd *xhci,
|
|||
case COMP_EBADSLT:
|
||||
dev_warn(&udev->dev, "WARN: slot not enabled for"
|
||||
"evaluate context command.\n");
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
case COMP_CTX_STATE:
|
||||
dev_warn(&udev->dev, "WARN: invalid context state for "
|
||||
"evaluate context command.\n");
|
||||
|
|
@ -4020,7 +4021,7 @@ int xhci_update_device(struct usb_hcd *hcd, struct usb_device *udev)
|
|||
static unsigned long long xhci_service_interval_to_ns(
|
||||
struct usb_endpoint_descriptor *desc)
|
||||
{
|
||||
return (1 << (desc->bInterval - 1)) * 125 * 1000;
|
||||
return (1ULL << (desc->bInterval - 1)) * 125 * 1000;
|
||||
}
|
||||
|
||||
static u16 xhci_get_timeout_no_hub_lpm(struct usb_device *udev,
|
||||
|
|
@ -4141,7 +4142,7 @@ static u16 xhci_calculate_intel_u2_timeout(struct usb_device *udev,
|
|||
(xhci_service_interval_to_ns(desc) > timeout_ns))
|
||||
timeout_ns = xhci_service_interval_to_ns(desc);
|
||||
|
||||
u2_del_ns = udev->bos->ss_cap->bU2DevExitLat * 1000;
|
||||
u2_del_ns = le16_to_cpu(udev->bos->ss_cap->bU2DevExitLat) * 1000ULL;
|
||||
if (u2_del_ns > timeout_ns)
|
||||
timeout_ns = u2_del_ns;
|
||||
|
||||
|
|
|
|||
|
|
@ -158,3 +158,4 @@ int ezusb_fx2_ihex_firmware_download(struct usb_device *dev,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
|
|||
|
|
@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
|
|||
ret = IRQ_HANDLED;
|
||||
}
|
||||
|
||||
/* Drop spurious RX and TX if device is disconnected */
|
||||
if (musb->int_usb & MUSB_INTR_DISCONNECT) {
|
||||
musb->int_tx = 0;
|
||||
musb->int_rx = 0;
|
||||
}
|
||||
|
||||
if (musb->int_tx || musb->int_rx || musb->int_usb)
|
||||
ret |= musb_interrupt(musb);
|
||||
|
||||
|
|
|
|||
|
|
@ -458,11 +458,11 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
|
|||
struct platform_device *musb;
|
||||
struct resource *res;
|
||||
struct resource resources[2];
|
||||
char res_name[10];
|
||||
char res_name[11];
|
||||
int ret, musbid;
|
||||
|
||||
/* get memory resource */
|
||||
sprintf(res_name, "musb%d", id);
|
||||
snprintf(res_name, sizeof(res_name), "musb%d", id);
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, res_name);
|
||||
if (!res) {
|
||||
dev_err(dev, "%s get mem resource failed\n", res_name);
|
||||
|
|
@ -473,7 +473,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
|
|||
resources[0] = *res;
|
||||
|
||||
/* get irq resource */
|
||||
sprintf(res_name, "musb%d-irq", id);
|
||||
snprintf(res_name, sizeof(res_name), "musb%d-irq", id);
|
||||
res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, res_name);
|
||||
if (!res) {
|
||||
dev_err(dev, "%s get irq resource failed\n", res_name);
|
||||
|
|
@ -530,7 +530,7 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id)
|
|||
|
||||
of_property_read_u32(np, "num-eps", (u32 *)&config->num_eps);
|
||||
of_property_read_u32(np, "ram-bits", (u32 *)&config->ram_bits);
|
||||
sprintf(res_name, "port%d-mode", id);
|
||||
snprintf(res_name, sizeof(res_name), "port%d-mode", id);
|
||||
of_property_read_u32(np, res_name, (u32 *)&pdata->mode);
|
||||
of_property_read_u32(np, "power", (u32 *)&pdata->power);
|
||||
config->multipoint = of_property_read_bool(np, "multipoint");
|
||||
|
|
|
|||
|
|
@ -707,11 +707,12 @@ static void rxstate(struct musb *musb, struct musb_request *req)
|
|||
fifo_count = musb_readw(epio, MUSB_RXCOUNT);
|
||||
|
||||
/*
|
||||
* use mode 1 only if we expect data of at least ep packet_sz
|
||||
* and have not yet received a short packet
|
||||
* Enable Mode 1 on RX transfers only when short_not_ok flag
|
||||
* is set. Currently short_not_ok flag is set only from
|
||||
* file_storage and f_mass_storage drivers
|
||||
*/
|
||||
if ((request->length - request->actual >= musb_ep->packet_sz) &&
|
||||
(fifo_count >= musb_ep->packet_sz))
|
||||
|
||||
if (request->short_not_ok && fifo_count == musb_ep->packet_sz)
|
||||
use_mode_1 = 1;
|
||||
else
|
||||
use_mode_1 = 0;
|
||||
|
|
@ -727,6 +728,27 @@ static void rxstate(struct musb *musb, struct musb_request *req)
|
|||
c = musb->dma_controller;
|
||||
channel = musb_ep->dma;
|
||||
|
||||
/* We use DMA Req mode 0 in rx_csr, and DMA controller operates in
|
||||
* mode 0 only. So we do not get endpoint interrupts due to DMA
|
||||
* completion. We only get interrupts from DMA controller.
|
||||
*
|
||||
* We could operate in DMA mode 1 if we knew the size of the tranfer
|
||||
* in advance. For mass storage class, request->length = what the host
|
||||
* sends, so that'd work. But for pretty much everything else,
|
||||
* request->length is routinely more than what the host sends. For
|
||||
* most these gadgets, end of is signified either by a short packet,
|
||||
* or filling the last byte of the buffer. (Sending extra data in
|
||||
* that last pckate should trigger an overflow fault.) But in mode 1,
|
||||
* we don't get DMA completion interrupt for short packets.
|
||||
*
|
||||
* Theoretically, we could enable DMAReq irq (MUSB_RXCSR_DMAMODE = 1),
|
||||
* to get endpoint interrupt on every DMA req, but that didn't seem
|
||||
* to work reliably.
|
||||
*
|
||||
* REVISIT an updated g_file_storage can set req->short_not_ok, which
|
||||
* then becomes usable as a runtime "use mode 1" hint...
|
||||
*/
|
||||
|
||||
/* Experimental: Mode1 works with mass storage use cases */
|
||||
if (use_mode_1) {
|
||||
csr |= MUSB_RXCSR_AUTOCLEAR;
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ static int __devinit ux500_probe(struct platform_device *pdev)
|
|||
struct platform_device *musb;
|
||||
struct ux500_glue *glue;
|
||||
struct clk *clk;
|
||||
|
||||
int musbid;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
glue = kzalloc(sizeof(*glue), GFP_KERNEL);
|
||||
|
|
|
|||
|
|
@ -58,7 +58,7 @@ config USB_ULPI_VIEWPORT
|
|||
|
||||
config TWL4030_USB
|
||||
tristate "TWL4030 USB Transceiver Driver"
|
||||
depends on TWL4030_CORE && REGULATOR_TWL4030
|
||||
depends on TWL4030_CORE && REGULATOR_TWL4030 && USB_MUSB_OMAP2PLUS
|
||||
select USB_OTG_UTILS
|
||||
help
|
||||
Enable this to support the USB OTG transceiver on TWL4030
|
||||
|
|
@ -68,7 +68,7 @@ config TWL4030_USB
|
|||
|
||||
config TWL6030_USB
|
||||
tristate "TWL6030 USB Transceiver Driver"
|
||||
depends on TWL4030_CORE && OMAP_USB2
|
||||
depends on TWL4030_CORE && OMAP_USB2 && USB_MUSB_OMAP2PLUS
|
||||
select USB_OTG_UTILS
|
||||
help
|
||||
Enable this to support the USB OTG transceiver on TWL6030
|
||||
|
|
|
|||
|
|
@ -795,6 +795,7 @@ static void xfer_work(struct work_struct *work)
|
|||
dev_dbg(dev, " %s %d (%d/ %d)\n",
|
||||
fifo->name, usbhs_pipe_number(pipe), pkt->length, pkt->zero);
|
||||
|
||||
usbhs_pipe_enable(pipe);
|
||||
usbhsf_dma_start(pipe, fifo);
|
||||
dma_async_issue_pending(chan);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -273,9 +273,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data)
|
|||
usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
|
||||
usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
|
||||
|
||||
usbhs_write(priv, BRDYSTS, 0);
|
||||
usbhs_write(priv, NRDYSTS, 0);
|
||||
usbhs_write(priv, BEMPSTS, 0);
|
||||
usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
|
||||
usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts);
|
||||
usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
|
||||
|
||||
/*
|
||||
* call irq callback functions
|
||||
|
|
|
|||
|
|
@ -334,6 +334,11 @@ static void usbhsh_pipe_detach(struct usbhsh_hpriv *hpriv,
|
|||
struct device *dev = usbhs_priv_to_dev(priv);
|
||||
unsigned long flags;
|
||||
|
||||
if (unlikely(!uep)) {
|
||||
dev_err(dev, "no uep\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/******************** spin lock ********************/
|
||||
usbhs_lock(priv, flags);
|
||||
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ struct usbhs_pipe_info {
|
|||
* pipe list
|
||||
*/
|
||||
#define __usbhs_for_each_pipe(start, pos, info, i) \
|
||||
for (i = start, pos = (info)->pipe; \
|
||||
for (i = start, pos = (info)->pipe + i; \
|
||||
i < (info)->size; \
|
||||
i++, pos = (info)->pipe + i)
|
||||
|
||||
|
|
|
|||
|
|
@ -125,9 +125,6 @@ static inline int calc_divisor(int bps)
|
|||
|
||||
static int ark3116_attach(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct ark3116_private *priv;
|
||||
|
||||
/* make sure we have our end-points */
|
||||
if ((serial->num_bulk_in == 0) ||
|
||||
(serial->num_bulk_out == 0) ||
|
||||
|
|
@ -142,8 +139,15 @@ static int ark3116_attach(struct usb_serial *serial)
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv = kzalloc(sizeof(struct ark3116_private),
|
||||
GFP_KERNEL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ark3116_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct ark3116_private *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
@ -198,18 +202,15 @@ static int ark3116_attach(struct usb_serial *serial)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ark3116_release(struct usb_serial *serial)
|
||||
static int ark3116_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct ark3116_private *priv = usb_get_serial_port_data(port);
|
||||
|
||||
/* device is closed, so URBs and DMA should be down */
|
||||
|
||||
usb_set_serial_port_data(port, NULL);
|
||||
|
||||
mutex_destroy(&priv->hw_lock);
|
||||
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void ark3116_init_termios(struct tty_struct *tty)
|
||||
|
|
@ -723,7 +724,8 @@ static struct usb_serial_driver ark3116_device = {
|
|||
.id_table = id_table,
|
||||
.num_ports = 1,
|
||||
.attach = ark3116_attach,
|
||||
.release = ark3116_release,
|
||||
.port_probe = ark3116_port_probe,
|
||||
.port_remove = ark3116_port_remove,
|
||||
.set_termios = ark3116_set_termios,
|
||||
.init_termios = ark3116_init_termios,
|
||||
.ioctl = ark3116_ioctl,
|
||||
|
|
|
|||
|
|
@ -45,8 +45,8 @@
|
|||
#define DRIVER_DESC "USB Belkin Serial converter driver"
|
||||
|
||||
/* function prototypes for a Belkin USB Serial Adapter F5U103 */
|
||||
static int belkin_sa_startup(struct usb_serial *serial);
|
||||
static void belkin_sa_release(struct usb_serial *serial);
|
||||
static int belkin_sa_port_probe(struct usb_serial_port *port);
|
||||
static int belkin_sa_port_remove(struct usb_serial_port *port);
|
||||
static int belkin_sa_open(struct tty_struct *tty,
|
||||
struct usb_serial_port *port);
|
||||
static void belkin_sa_close(struct usb_serial_port *port);
|
||||
|
|
@ -88,8 +88,8 @@ static struct usb_serial_driver belkin_device = {
|
|||
.break_ctl = belkin_sa_break_ctl,
|
||||
.tiocmget = belkin_sa_tiocmget,
|
||||
.tiocmset = belkin_sa_tiocmset,
|
||||
.attach = belkin_sa_startup,
|
||||
.release = belkin_sa_release,
|
||||
.port_probe = belkin_sa_port_probe,
|
||||
.port_remove = belkin_sa_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
@ -118,17 +118,15 @@ struct belkin_sa_private {
|
|||
(c), BELKIN_SA_SET_REQUEST_TYPE, \
|
||||
(v), 0, NULL, 0, WDR_TIMEOUT)
|
||||
|
||||
/* do some startup allocations not currently performed by usb_serial_probe() */
|
||||
static int belkin_sa_startup(struct usb_serial *serial)
|
||||
static int belkin_sa_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_device *dev = serial->dev;
|
||||
struct usb_device *dev = port->serial->dev;
|
||||
struct belkin_sa_private *priv;
|
||||
|
||||
/* allocate the private data structure */
|
||||
priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -1; /* error */
|
||||
/* set initial values for control structures */
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
priv->control_state = 0;
|
||||
priv->last_lsr = 0;
|
||||
|
|
@ -140,18 +138,19 @@ static int belkin_sa_startup(struct usb_serial *serial)
|
|||
le16_to_cpu(dev->descriptor.bcdDevice),
|
||||
priv->bad_flow_control);
|
||||
|
||||
init_waitqueue_head(&serial->port[0]->write_wait);
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void belkin_sa_release(struct usb_serial *serial)
|
||||
static int belkin_sa_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
int i;
|
||||
struct belkin_sa_private *priv;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int belkin_sa_open(struct tty_struct *tty,
|
||||
|
|
|
|||
|
|
@ -242,13 +242,11 @@ out: kfree(buffer);
|
|||
return r;
|
||||
}
|
||||
|
||||
/* allocate private data */
|
||||
static int ch341_attach(struct usb_serial *serial)
|
||||
static int ch341_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct ch341_private *priv;
|
||||
int r;
|
||||
|
||||
/* private data */
|
||||
priv = kzalloc(sizeof(struct ch341_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
|
@ -258,17 +256,27 @@ static int ch341_attach(struct usb_serial *serial)
|
|||
priv->baud_rate = DEFAULT_BAUD_RATE;
|
||||
priv->line_control = CH341_BIT_RTS | CH341_BIT_DTR;
|
||||
|
||||
r = ch341_configure(serial->dev, priv);
|
||||
r = ch341_configure(port->serial->dev, priv);
|
||||
if (r < 0)
|
||||
goto error;
|
||||
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
usb_set_serial_port_data(port, priv);
|
||||
return 0;
|
||||
|
||||
error: kfree(priv);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int ch341_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct ch341_private *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ch341_carrier_raised(struct usb_serial_port *port)
|
||||
{
|
||||
struct ch341_private *priv = usb_get_serial_port_data(port);
|
||||
|
|
@ -304,7 +312,7 @@ static void ch341_close(struct usb_serial_port *port)
|
|||
static int ch341_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct ch341_private *priv = usb_get_serial_port_data(serial->port[0]);
|
||||
struct ch341_private *priv = usb_get_serial_port_data(port);
|
||||
int r;
|
||||
|
||||
priv->baud_rate = DEFAULT_BAUD_RATE;
|
||||
|
|
@ -608,7 +616,8 @@ static struct usb_serial_driver ch341_device = {
|
|||
.tiocmget = ch341_tiocmget,
|
||||
.tiocmset = ch341_tiocmset,
|
||||
.read_int_callback = ch341_read_int_callback,
|
||||
.attach = ch341_attach,
|
||||
.port_probe = ch341_port_probe,
|
||||
.port_remove = ch341_port_remove,
|
||||
.reset_resume = ch341_reset_resume,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -162,7 +162,7 @@ static const struct usb_device_id id_table[] = {
|
|||
|
||||
MODULE_DEVICE_TABLE(usb, id_table);
|
||||
|
||||
struct cp210x_port_private {
|
||||
struct cp210x_serial_private {
|
||||
__u8 bInterfaceNumber;
|
||||
};
|
||||
|
||||
|
|
@ -276,7 +276,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
|
|||
unsigned int *data, int size)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
|
||||
struct cp210x_serial_private *spriv = usb_get_serial_data(serial);
|
||||
__le32 *buf;
|
||||
int result, i, length;
|
||||
|
||||
|
|
@ -292,7 +292,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
|
|||
/* Issue the request, attempting to read 'size' bytes */
|
||||
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
request, REQTYPE_INTERFACE_TO_HOST, 0x0000,
|
||||
port_priv->bInterfaceNumber, buf, size,
|
||||
spriv->bInterfaceNumber, buf, size,
|
||||
USB_CTRL_GET_TIMEOUT);
|
||||
|
||||
/* Convert data into an array of integers */
|
||||
|
|
@ -323,7 +323,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
|
|||
unsigned int *data, int size)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
|
||||
struct cp210x_serial_private *spriv = usb_get_serial_data(serial);
|
||||
__le32 *buf;
|
||||
int result, i, length;
|
||||
|
||||
|
|
@ -345,13 +345,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
|
|||
result = usb_control_msg(serial->dev,
|
||||
usb_sndctrlpipe(serial->dev, 0),
|
||||
request, REQTYPE_HOST_TO_INTERFACE, 0x0000,
|
||||
port_priv->bInterfaceNumber, buf, size,
|
||||
spriv->bInterfaceNumber, buf, size,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
} else {
|
||||
result = usb_control_msg(serial->dev,
|
||||
usb_sndctrlpipe(serial->dev, 0),
|
||||
request, REQTYPE_HOST_TO_INTERFACE, data[0],
|
||||
port_priv->bInterfaceNumber, NULL, 0,
|
||||
spriv->bInterfaceNumber, NULL, 0,
|
||||
USB_CTRL_SET_TIMEOUT);
|
||||
}
|
||||
|
||||
|
|
@ -845,36 +845,30 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
|
|||
|
||||
static int cp210x_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct cp210x_port_private *port_priv;
|
||||
int i;
|
||||
struct usb_host_interface *cur_altsetting;
|
||||
struct cp210x_serial_private *spriv;
|
||||
|
||||
/* cp210x buffers behave strangely unless device is reset */
|
||||
usb_reset_device(serial->dev);
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
|
||||
if (!port_priv)
|
||||
return -ENOMEM;
|
||||
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
|
||||
if (!spriv)
|
||||
return -ENOMEM;
|
||||
|
||||
port_priv->bInterfaceNumber =
|
||||
serial->interface->cur_altsetting->desc.bInterfaceNumber;
|
||||
cur_altsetting = serial->interface->cur_altsetting;
|
||||
spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber;
|
||||
|
||||
usb_set_serial_port_data(serial->port[i], port_priv);
|
||||
}
|
||||
usb_set_serial_data(serial, spriv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cp210x_release(struct usb_serial *serial)
|
||||
{
|
||||
struct cp210x_port_private *port_priv;
|
||||
int i;
|
||||
struct cp210x_serial_private *spriv;
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port_priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(port_priv);
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
}
|
||||
spriv = usb_get_serial_data(serial);
|
||||
kfree(spriv);
|
||||
}
|
||||
|
||||
module_usb_serial_driver(serial_drivers, id_table);
|
||||
|
|
|
|||
|
|
@ -55,9 +55,9 @@
|
|||
#define CYBERJACK_PRODUCT_ID 0x0100
|
||||
|
||||
/* Function prototypes */
|
||||
static int cyberjack_startup(struct usb_serial *serial);
|
||||
static void cyberjack_disconnect(struct usb_serial *serial);
|
||||
static void cyberjack_release(struct usb_serial *serial);
|
||||
static int cyberjack_port_probe(struct usb_serial_port *port);
|
||||
static int cyberjack_port_remove(struct usb_serial_port *port);
|
||||
static int cyberjack_open(struct tty_struct *tty,
|
||||
struct usb_serial_port *port);
|
||||
static void cyberjack_close(struct usb_serial_port *port);
|
||||
|
|
@ -83,9 +83,9 @@ static struct usb_serial_driver cyberjack_device = {
|
|||
.description = "Reiner SCT Cyberjack USB card reader",
|
||||
.id_table = id_table,
|
||||
.num_ports = 1,
|
||||
.attach = cyberjack_startup,
|
||||
.disconnect = cyberjack_disconnect,
|
||||
.release = cyberjack_release,
|
||||
.port_probe = cyberjack_port_probe,
|
||||
.port_remove = cyberjack_port_remove,
|
||||
.open = cyberjack_open,
|
||||
.close = cyberjack_close,
|
||||
.write = cyberjack_write,
|
||||
|
|
@ -107,36 +107,35 @@ struct cyberjack_private {
|
|||
short wrsent; /* Data already sent */
|
||||
};
|
||||
|
||||
/* do some startup allocations not currently performed by usb_serial_probe() */
|
||||
static int cyberjack_startup(struct usb_serial *serial)
|
||||
static int cyberjack_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct cyberjack_private *priv;
|
||||
int i;
|
||||
int result;
|
||||
|
||||
/* allocate the private data structure */
|
||||
priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* set initial values */
|
||||
spin_lock_init(&priv->lock);
|
||||
priv->rdtodo = 0;
|
||||
priv->wrfilled = 0;
|
||||
priv->wrsent = 0;
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
|
||||
init_waitqueue_head(&serial->port[0]->write_wait);
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
int result;
|
||||
result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
|
||||
GFP_KERNEL);
|
||||
if (result)
|
||||
dev_err(&serial->dev->dev,
|
||||
"usb_submit_urb(read int) failed\n");
|
||||
dev_dbg(&serial->dev->dev, "%s - usb_submit_urb(int urb)\n",
|
||||
__func__);
|
||||
}
|
||||
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
|
||||
if (result)
|
||||
dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cyberjack_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct cyberjack_private *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -149,16 +148,6 @@ static void cyberjack_disconnect(struct usb_serial *serial)
|
|||
usb_kill_urb(serial->port[i]->interrupt_in_urb);
|
||||
}
|
||||
|
||||
static void cyberjack_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
/* My special items, the standard routines free my urbs */
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
}
|
||||
}
|
||||
|
||||
static int cyberjack_open(struct tty_struct *tty,
|
||||
struct usb_serial_port *port)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -123,10 +123,10 @@ struct cypress_private {
|
|||
};
|
||||
|
||||
/* function prototypes for the Cypress USB to serial device */
|
||||
static int cypress_earthmate_startup(struct usb_serial *serial);
|
||||
static int cypress_hidcom_startup(struct usb_serial *serial);
|
||||
static int cypress_ca42v2_startup(struct usb_serial *serial);
|
||||
static void cypress_release(struct usb_serial *serial);
|
||||
static int cypress_earthmate_port_probe(struct usb_serial_port *port);
|
||||
static int cypress_hidcom_port_probe(struct usb_serial_port *port);
|
||||
static int cypress_ca42v2_port_probe(struct usb_serial_port *port);
|
||||
static int cypress_port_remove(struct usb_serial_port *port);
|
||||
static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
static void cypress_close(struct usb_serial_port *port);
|
||||
static void cypress_dtr_rts(struct usb_serial_port *port, int on);
|
||||
|
|
@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = {
|
|||
.description = "DeLorme Earthmate USB",
|
||||
.id_table = id_table_earthmate,
|
||||
.num_ports = 1,
|
||||
.attach = cypress_earthmate_startup,
|
||||
.release = cypress_release,
|
||||
.port_probe = cypress_earthmate_port_probe,
|
||||
.port_remove = cypress_port_remove,
|
||||
.open = cypress_open,
|
||||
.close = cypress_close,
|
||||
.dtr_rts = cypress_dtr_rts,
|
||||
|
|
@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = {
|
|||
.description = "HID->COM RS232 Adapter",
|
||||
.id_table = id_table_cyphidcomrs232,
|
||||
.num_ports = 1,
|
||||
.attach = cypress_hidcom_startup,
|
||||
.release = cypress_release,
|
||||
.port_probe = cypress_hidcom_port_probe,
|
||||
.port_remove = cypress_port_remove,
|
||||
.open = cypress_open,
|
||||
.close = cypress_close,
|
||||
.dtr_rts = cypress_dtr_rts,
|
||||
|
|
@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = {
|
|||
.description = "Nokia CA-42 V2 Adapter",
|
||||
.id_table = id_table_nokiaca42v2,
|
||||
.num_ports = 1,
|
||||
.attach = cypress_ca42v2_startup,
|
||||
.release = cypress_release,
|
||||
.port_probe = cypress_ca42v2_port_probe,
|
||||
.port_remove = cypress_port_remove,
|
||||
.open = cypress_open,
|
||||
.close = cypress_close,
|
||||
.dtr_rts = cypress_dtr_rts,
|
||||
|
|
@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port)
|
|||
*****************************************************************************/
|
||||
|
||||
|
||||
static int generic_startup(struct usb_serial *serial)
|
||||
static int cypress_generic_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct cypress_private *priv;
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
|
||||
priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
|
|
@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial)
|
|||
}
|
||||
|
||||
|
||||
static int cypress_earthmate_startup(struct usb_serial *serial)
|
||||
static int cypress_earthmate_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct cypress_private *priv;
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
int ret;
|
||||
|
||||
if (generic_startup(serial)) {
|
||||
ret = cypress_generic_port_probe(port);
|
||||
if (ret) {
|
||||
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
|
|
@ -518,57 +520,54 @@ static int cypress_earthmate_startup(struct usb_serial *serial)
|
|||
}
|
||||
|
||||
return 0;
|
||||
} /* cypress_earthmate_startup */
|
||||
}
|
||||
|
||||
|
||||
static int cypress_hidcom_startup(struct usb_serial *serial)
|
||||
static int cypress_hidcom_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct cypress_private *priv;
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
int ret;
|
||||
|
||||
if (generic_startup(serial)) {
|
||||
ret = cypress_generic_port_probe(port);
|
||||
if (ret) {
|
||||
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
priv->chiptype = CT_CYPHIDCOM;
|
||||
|
||||
return 0;
|
||||
} /* cypress_hidcom_startup */
|
||||
}
|
||||
|
||||
|
||||
static int cypress_ca42v2_startup(struct usb_serial *serial)
|
||||
static int cypress_ca42v2_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct cypress_private *priv;
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
int ret;
|
||||
|
||||
if (generic_startup(serial)) {
|
||||
ret = cypress_generic_port_probe(port);
|
||||
if (ret) {
|
||||
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
|
||||
return 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
priv->chiptype = CT_CA42V2;
|
||||
|
||||
return 0;
|
||||
} /* cypress_ca42v2_startup */
|
||||
}
|
||||
|
||||
|
||||
static void cypress_release(struct usb_serial *serial)
|
||||
static int cypress_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct cypress_private *priv;
|
||||
|
||||
/* all open ports are closed at this point */
|
||||
priv = usb_get_serial_port_data(serial->port[0]);
|
||||
priv = usb_get_serial_port_data(port);
|
||||
|
||||
if (priv) {
|
||||
kfifo_free(&priv->write_fifo);
|
||||
kfree(priv);
|
||||
}
|
||||
kfifo_free(&priv->write_fifo);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
{
|
||||
struct cypress_private *priv = usb_get_serial_port_data(port);
|
||||
|
|
|
|||
|
|
@ -244,6 +244,8 @@ static int digi_startup_device(struct usb_serial *serial);
|
|||
static int digi_startup(struct usb_serial *serial);
|
||||
static void digi_disconnect(struct usb_serial *serial);
|
||||
static void digi_release(struct usb_serial *serial);
|
||||
static int digi_port_probe(struct usb_serial_port *port);
|
||||
static int digi_port_remove(struct usb_serial_port *port);
|
||||
static void digi_read_bulk_callback(struct urb *urb);
|
||||
static int digi_read_inb_callback(struct urb *urb);
|
||||
static int digi_read_oob_callback(struct urb *urb);
|
||||
|
|
@ -294,6 +296,8 @@ static struct usb_serial_driver digi_acceleport_2_device = {
|
|||
.attach = digi_startup,
|
||||
.disconnect = digi_disconnect,
|
||||
.release = digi_release,
|
||||
.port_probe = digi_port_probe,
|
||||
.port_remove = digi_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver digi_acceleport_4_device = {
|
||||
|
|
@ -320,6 +324,8 @@ static struct usb_serial_driver digi_acceleport_4_device = {
|
|||
.attach = digi_startup,
|
||||
.disconnect = digi_disconnect,
|
||||
.release = digi_release,
|
||||
.port_probe = digi_port_probe,
|
||||
.port_remove = digi_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
@ -1240,59 +1246,50 @@ static int digi_startup_device(struct usb_serial *serial)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int digi_port_init(struct usb_serial_port *port, unsigned port_num)
|
||||
{
|
||||
struct digi_port *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->dp_port_lock);
|
||||
priv->dp_port_num = port_num;
|
||||
init_waitqueue_head(&priv->dp_modem_change_wait);
|
||||
init_waitqueue_head(&priv->dp_transmit_idle_wait);
|
||||
init_waitqueue_head(&priv->dp_flush_wait);
|
||||
init_waitqueue_head(&priv->dp_close_wait);
|
||||
INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
|
||||
priv->dp_port = port;
|
||||
|
||||
init_waitqueue_head(&port->write_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int digi_startup(struct usb_serial *serial)
|
||||
{
|
||||
|
||||
int i;
|
||||
struct digi_port *priv;
|
||||
struct digi_serial *serial_priv;
|
||||
int ret;
|
||||
|
||||
/* allocate the private data structures for all ports */
|
||||
/* number of regular ports + 1 for the out-of-band port */
|
||||
for (i = 0; i < serial->type->num_ports + 1; i++) {
|
||||
/* allocate port private structure */
|
||||
priv = kmalloc(sizeof(struct digi_port), GFP_KERNEL);
|
||||
if (priv == NULL) {
|
||||
while (--i >= 0)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
return 1; /* error */
|
||||
}
|
||||
serial_priv = kzalloc(sizeof(*serial_priv), GFP_KERNEL);
|
||||
if (!serial_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* initialize port private structure */
|
||||
spin_lock_init(&priv->dp_port_lock);
|
||||
priv->dp_port_num = i;
|
||||
priv->dp_out_buf_len = 0;
|
||||
priv->dp_write_urb_in_use = 0;
|
||||
priv->dp_modem_signals = 0;
|
||||
init_waitqueue_head(&priv->dp_modem_change_wait);
|
||||
priv->dp_transmit_idle = 0;
|
||||
init_waitqueue_head(&priv->dp_transmit_idle_wait);
|
||||
priv->dp_throttled = 0;
|
||||
priv->dp_throttle_restart = 0;
|
||||
init_waitqueue_head(&priv->dp_flush_wait);
|
||||
init_waitqueue_head(&priv->dp_close_wait);
|
||||
INIT_WORK(&priv->dp_wakeup_work, digi_wakeup_write_lock);
|
||||
priv->dp_port = serial->port[i];
|
||||
/* initialize write wait queue for this port */
|
||||
init_waitqueue_head(&serial->port[i]->write_wait);
|
||||
|
||||
usb_set_serial_port_data(serial->port[i], priv);
|
||||
}
|
||||
|
||||
/* allocate serial private structure */
|
||||
serial_priv = kmalloc(sizeof(struct digi_serial), GFP_KERNEL);
|
||||
if (serial_priv == NULL) {
|
||||
for (i = 0; i < serial->type->num_ports + 1; i++)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
return 1; /* error */
|
||||
}
|
||||
|
||||
/* initialize serial private structure */
|
||||
spin_lock_init(&serial_priv->ds_serial_lock);
|
||||
serial_priv->ds_oob_port_num = serial->type->num_ports;
|
||||
serial_priv->ds_oob_port = serial->port[serial_priv->ds_oob_port_num];
|
||||
serial_priv->ds_device_started = 0;
|
||||
|
||||
ret = digi_port_init(serial_priv->ds_oob_port,
|
||||
serial_priv->ds_oob_port_num);
|
||||
if (ret) {
|
||||
kfree(serial_priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
usb_set_serial_data(serial, serial_priv);
|
||||
|
||||
return 0;
|
||||
|
|
@ -1313,15 +1310,35 @@ static void digi_disconnect(struct usb_serial *serial)
|
|||
|
||||
static void digi_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct digi_serial *serial_priv;
|
||||
struct digi_port *priv;
|
||||
|
||||
/* free the private data structures for all ports */
|
||||
/* number of regular ports + 1 for the out-of-band port */
|
||||
for (i = 0; i < serial->type->num_ports + 1; i++)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
kfree(usb_get_serial_data(serial));
|
||||
serial_priv = usb_get_serial_data(serial);
|
||||
|
||||
priv = usb_get_serial_port_data(serial_priv->ds_oob_port);
|
||||
kfree(priv);
|
||||
|
||||
kfree(serial_priv);
|
||||
}
|
||||
|
||||
static int digi_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
unsigned port_num;
|
||||
|
||||
port_num = port->number - port->serial->minor;
|
||||
|
||||
return digi_port_init(port, port_num);
|
||||
}
|
||||
|
||||
static int digi_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct digi_port *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void digi_read_bulk_callback(struct urb *urb)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -318,39 +318,30 @@ static int f81232_ioctl(struct tty_struct *tty,
|
|||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
static int f81232_startup(struct usb_serial *serial)
|
||||
static int f81232_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct f81232_private *priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
priv = kzalloc(sizeof(struct f81232_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
goto cleanup;
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
usb_set_serial_port_data(serial->port[i], priv);
|
||||
}
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
for (--i; i >= 0; --i) {
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void f81232_release(struct usb_serial *serial)
|
||||
static int f81232_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
int i;
|
||||
struct f81232_private *priv;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
}
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_serial_driver f81232_device = {
|
||||
|
|
@ -373,8 +364,8 @@ static struct usb_serial_driver f81232_device = {
|
|||
.tiocmset = f81232_tiocmset,
|
||||
.process_read_urb = f81232_process_read_urb,
|
||||
.read_int_callback = f81232_read_int_callback,
|
||||
.attach = f81232_startup,
|
||||
.release = f81232_release,
|
||||
.port_probe = f81232_port_probe,
|
||||
.port_remove = f81232_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
|
|||
|
|
@ -1405,11 +1405,10 @@ static void timeout_handler(unsigned long data)
|
|||
|
||||
|
||||
|
||||
static int garmin_attach(struct usb_serial *serial)
|
||||
static int garmin_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
int status = 0;
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct garmin_data *garmin_data_p = NULL;
|
||||
int status;
|
||||
struct garmin_data *garmin_data_p;
|
||||
|
||||
garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL);
|
||||
if (garmin_data_p == NULL) {
|
||||
|
|
@ -1434,22 +1433,14 @@ static int garmin_attach(struct usb_serial *serial)
|
|||
}
|
||||
|
||||
|
||||
static void garmin_disconnect(struct usb_serial *serial)
|
||||
static int garmin_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
|
||||
|
||||
usb_kill_urb(port->interrupt_in_urb);
|
||||
del_timer_sync(&garmin_data_p->timer);
|
||||
}
|
||||
|
||||
|
||||
static void garmin_release(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
|
||||
|
||||
kfree(garmin_data_p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = {
|
|||
.close = garmin_close,
|
||||
.throttle = garmin_throttle,
|
||||
.unthrottle = garmin_unthrottle,
|
||||
.attach = garmin_attach,
|
||||
.disconnect = garmin_disconnect,
|
||||
.release = garmin_release,
|
||||
.port_probe = garmin_port_probe,
|
||||
.port_remove = garmin_port_remove,
|
||||
.write = garmin_write,
|
||||
.write_room = garmin_write_room,
|
||||
.write_bulk_callback = garmin_write_bulk_callback,
|
||||
|
|
|
|||
|
|
@ -225,6 +225,8 @@ static int edge_get_icount(struct tty_struct *tty,
|
|||
static int edge_startup(struct usb_serial *serial);
|
||||
static void edge_disconnect(struct usb_serial *serial);
|
||||
static void edge_release(struct usb_serial *serial);
|
||||
static int edge_port_probe(struct usb_serial_port *port);
|
||||
static int edge_port_remove(struct usb_serial_port *port);
|
||||
|
||||
#include "io_tables.h" /* all of the devices that this driver supports */
|
||||
|
||||
|
|
@ -2875,10 +2877,9 @@ static void load_application_firmware(struct edgeport_serial *edge_serial)
|
|||
static int edge_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct edgeport_serial *edge_serial;
|
||||
struct edgeport_port *edge_port;
|
||||
struct usb_device *dev;
|
||||
struct device *ddev = &serial->dev->dev;
|
||||
int i, j;
|
||||
int i;
|
||||
int response;
|
||||
bool interrupt_in_found;
|
||||
bool bulk_in_found;
|
||||
|
|
@ -2961,25 +2962,6 @@ static int edge_startup(struct usb_serial *serial)
|
|||
/* we set up the pointers to the endpoints in the edge_open function,
|
||||
* as the structures aren't created yet. */
|
||||
|
||||
/* set up our port private structures */
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL);
|
||||
if (edge_port == NULL) {
|
||||
dev_err(ddev, "%s - Out of memory\n", __func__);
|
||||
for (j = 0; j < i; ++j) {
|
||||
kfree(usb_get_serial_port_data(serial->port[j]));
|
||||
usb_set_serial_port_data(serial->port[j],
|
||||
NULL);
|
||||
}
|
||||
usb_set_serial_data(serial, NULL);
|
||||
kfree(edge_serial);
|
||||
return -ENOMEM;
|
||||
}
|
||||
spin_lock_init(&edge_port->ep_lock);
|
||||
edge_port->port = serial->port[i];
|
||||
usb_set_serial_port_data(serial->port[i], edge_port);
|
||||
}
|
||||
|
||||
response = 0;
|
||||
|
||||
if (edge_serial->is_epic) {
|
||||
|
|
@ -3120,14 +3102,36 @@ static void edge_disconnect(struct usb_serial *serial)
|
|||
static void edge_release(struct usb_serial *serial)
|
||||
{
|
||||
struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
|
||||
kfree(edge_serial);
|
||||
}
|
||||
|
||||
static int edge_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct edgeport_port *edge_port;
|
||||
|
||||
edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL);
|
||||
if (!edge_port)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&edge_port->ep_lock);
|
||||
edge_port->port = port;
|
||||
|
||||
usb_set_serial_port_data(port, edge_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int edge_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct edgeport_port *edge_port;
|
||||
|
||||
edge_port = usb_get_serial_port_data(port);
|
||||
kfree(edge_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
module_usb_serial_driver(serial_drivers, id_table_combined);
|
||||
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
|
|
|
|||
|
|
@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport_2port_device = {
|
|||
.attach = edge_startup,
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_port_probe,
|
||||
.port_remove = edge_port_remove,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
|
|
@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport_4port_device = {
|
|||
.attach = edge_startup,
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_port_probe,
|
||||
.port_remove = edge_port_remove,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
|
|
@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport_8port_device = {
|
|||
.attach = edge_startup,
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_port_probe,
|
||||
.port_remove = edge_port_remove,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
|
|
@ -197,6 +203,8 @@ static struct usb_serial_driver epic_device = {
|
|||
.attach = edge_startup,
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_port_probe,
|
||||
.port_remove = edge_port_remove,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
|
|
|
|||
|
|
@ -2532,12 +2532,7 @@ static void edge_break(struct tty_struct *tty, int break_state)
|
|||
static int edge_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct edgeport_serial *edge_serial;
|
||||
struct edgeport_port *edge_port;
|
||||
struct usb_device *dev;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
dev = serial->dev;
|
||||
|
||||
/* create our private serial structure */
|
||||
edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
|
||||
|
|
@ -2555,40 +2550,7 @@ static int edge_startup(struct usb_serial *serial)
|
|||
return status;
|
||||
}
|
||||
|
||||
/* set up our port private structures */
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL);
|
||||
if (edge_port == NULL) {
|
||||
dev_err(&serial->dev->dev, "%s - Out of memory\n",
|
||||
__func__);
|
||||
goto cleanup;
|
||||
}
|
||||
spin_lock_init(&edge_port->ep_lock);
|
||||
if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE,
|
||||
GFP_KERNEL)) {
|
||||
dev_err(&serial->dev->dev, "%s - Out of memory\n",
|
||||
__func__);
|
||||
kfree(edge_port);
|
||||
goto cleanup;
|
||||
}
|
||||
edge_port->port = serial->port[i];
|
||||
edge_port->edge_serial = edge_serial;
|
||||
usb_set_serial_port_data(serial->port[i], edge_port);
|
||||
edge_port->bUartMode = default_uart_mode;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
cleanup:
|
||||
for (--i; i >= 0; --i) {
|
||||
edge_port = usb_get_serial_port_data(serial->port[i]);
|
||||
kfifo_free(&edge_port->write_fifo);
|
||||
kfree(edge_port);
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
}
|
||||
kfree(edge_serial);
|
||||
usb_set_serial_data(serial, NULL);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void edge_disconnect(struct usb_serial *serial)
|
||||
|
|
@ -2597,17 +2559,54 @@ static void edge_disconnect(struct usb_serial *serial)
|
|||
|
||||
static void edge_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct edgeport_port *edge_port;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
edge_port = usb_get_serial_port_data(serial->port[i]);
|
||||
kfifo_free(&edge_port->write_fifo);
|
||||
kfree(edge_port);
|
||||
}
|
||||
kfree(usb_get_serial_data(serial));
|
||||
}
|
||||
|
||||
static int edge_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct edgeport_port *edge_port;
|
||||
int ret;
|
||||
|
||||
edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL);
|
||||
if (!edge_port)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE,
|
||||
GFP_KERNEL);
|
||||
if (ret) {
|
||||
kfree(edge_port);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_init(&edge_port->ep_lock);
|
||||
edge_port->port = port;
|
||||
edge_port->edge_serial = usb_get_serial_data(port->serial);
|
||||
edge_port->bUartMode = default_uart_mode;
|
||||
|
||||
usb_set_serial_port_data(port, edge_port);
|
||||
|
||||
ret = edge_create_sysfs_attrs(port);
|
||||
if (ret) {
|
||||
kfifo_free(&edge_port->write_fifo);
|
||||
kfree(edge_port);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int edge_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct edgeport_port *edge_port;
|
||||
|
||||
edge_port = usb_get_serial_port_data(port);
|
||||
|
||||
edge_remove_sysfs_attrs(port);
|
||||
kfifo_free(&edge_port->write_fifo);
|
||||
kfree(edge_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sysfs Attributes */
|
||||
|
||||
|
|
@ -2667,8 +2666,8 @@ static struct usb_serial_driver edgeport_1port_device = {
|
|||
.attach = edge_startup,
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_create_sysfs_attrs,
|
||||
.port_remove = edge_remove_sysfs_attrs,
|
||||
.port_probe = edge_port_probe,
|
||||
.port_remove = edge_port_remove,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
|
|
@ -2698,8 +2697,8 @@ static struct usb_serial_driver edgeport_2port_device = {
|
|||
.attach = edge_startup,
|
||||
.disconnect = edge_disconnect,
|
||||
.release = edge_release,
|
||||
.port_probe = edge_create_sysfs_attrs,
|
||||
.port_remove = edge_remove_sysfs_attrs,
|
||||
.port_probe = edge_port_probe,
|
||||
.port_remove = edge_port_remove,
|
||||
.ioctl = edge_ioctl,
|
||||
.set_termios = edge_set_termios,
|
||||
.tiocmget = edge_tiocmget,
|
||||
|
|
|
|||
|
|
@ -203,8 +203,7 @@ static int ipw_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* fake probe - only to allocate data structures */
|
||||
static int ipw_probe(struct usb_serial *serial, const struct usb_device_id *id)
|
||||
static int ipw_attach(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_wwan_intf_private *data;
|
||||
|
||||
|
|
@ -303,9 +302,9 @@ static struct usb_serial_driver ipw_device = {
|
|||
.num_ports = 1,
|
||||
.open = ipw_open,
|
||||
.close = ipw_close,
|
||||
.probe = ipw_probe,
|
||||
.attach = usb_wwan_startup,
|
||||
.attach = ipw_attach,
|
||||
.release = ipw_release,
|
||||
.port_probe = usb_wwan_port_probe,
|
||||
.port_remove = usb_wwan_port_remove,
|
||||
.dtr_rts = ipw_dtr_rts,
|
||||
.write = usb_wwan_write,
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ static int iuu_cardout;
|
|||
static bool xmas;
|
||||
static int vcc_default = 5;
|
||||
|
||||
static int iuu_create_sysfs_attrs(struct usb_serial_port *port);
|
||||
static int iuu_remove_sysfs_attrs(struct usb_serial_port *port);
|
||||
static void read_rxcmd_callback(struct urb *urb);
|
||||
|
||||
struct iuu_private {
|
||||
|
|
@ -72,63 +74,55 @@ struct iuu_private {
|
|||
u32 clk;
|
||||
};
|
||||
|
||||
|
||||
static void iuu_free_buf(struct iuu_private *priv)
|
||||
{
|
||||
kfree(priv->buf);
|
||||
kfree(priv->writebuf);
|
||||
}
|
||||
|
||||
static int iuu_alloc_buf(struct usb_serial *serial, struct iuu_private *priv)
|
||||
{
|
||||
priv->buf = kzalloc(256, GFP_KERNEL);
|
||||
priv->writebuf = kzalloc(256, GFP_KERNEL);
|
||||
if (!priv->buf || !priv->writebuf) {
|
||||
iuu_free_buf(priv);
|
||||
dev_dbg(&serial->dev->dev, "%s problem allocation buffer\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
dev_dbg(&serial->dev->dev, "%s - Privates buffers allocation success\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iuu_startup(struct usb_serial *serial)
|
||||
static int iuu_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct iuu_private *priv;
|
||||
int ret;
|
||||
|
||||
priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL);
|
||||
dev_dbg(&serial->dev->dev, "%s- priv allocation success\n", __func__);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
if (iuu_alloc_buf(serial, priv)) {
|
||||
|
||||
priv->buf = kzalloc(256, GFP_KERNEL);
|
||||
if (!priv->buf) {
|
||||
kfree(priv);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->writebuf = kzalloc(256, GFP_KERNEL);
|
||||
if (!priv->writebuf) {
|
||||
kfree(priv->buf);
|
||||
kfree(priv);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
priv->vcc = vcc_default;
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
ret = iuu_create_sysfs_attrs(port);
|
||||
if (ret) {
|
||||
kfree(priv->writebuf);
|
||||
kfree(priv->buf);
|
||||
kfree(priv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Release function */
|
||||
static void iuu_release(struct usb_serial *serial)
|
||||
static int iuu_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct iuu_private *priv = usb_get_serial_port_data(port);
|
||||
if (!port)
|
||||
return;
|
||||
|
||||
if (priv) {
|
||||
iuu_free_buf(priv);
|
||||
dev_dbg(&port->dev, "%s - I will free all\n", __func__);
|
||||
usb_set_serial_port_data(port, NULL);
|
||||
iuu_remove_sysfs_attrs(port);
|
||||
kfree(priv->writebuf);
|
||||
kfree(priv->buf);
|
||||
kfree(priv);
|
||||
|
||||
dev_dbg(&port->dev, "%s - priv is not anymore in port structure\n", __func__);
|
||||
kfree(priv);
|
||||
|
||||
dev_dbg(&port->dev, "%s priv is now kfree\n", __func__);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int iuu_tiocmset(struct tty_struct *tty,
|
||||
|
|
@ -1215,8 +1209,6 @@ static struct usb_serial_driver iuu_device = {
|
|||
.num_ports = 1,
|
||||
.bulk_in_size = 512,
|
||||
.bulk_out_size = 512,
|
||||
.port_probe = iuu_create_sysfs_attrs,
|
||||
.port_remove = iuu_remove_sysfs_attrs,
|
||||
.open = iuu_open,
|
||||
.close = iuu_close,
|
||||
.write = iuu_uart_write,
|
||||
|
|
@ -1225,8 +1217,8 @@ static struct usb_serial_driver iuu_device = {
|
|||
.tiocmset = iuu_tiocmset,
|
||||
.set_termios = iuu_set_termios,
|
||||
.init_termios = iuu_init_termios,
|
||||
.attach = iuu_startup,
|
||||
.release = iuu_release,
|
||||
.port_probe = iuu_port_probe,
|
||||
.port_remove = iuu_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
|
|||
|
|
@ -1374,13 +1374,9 @@ static struct callbacks {
|
|||
data in device_details */
|
||||
static void keyspan_setup_urbs(struct usb_serial *serial)
|
||||
{
|
||||
int i, j;
|
||||
struct keyspan_serial_private *s_priv;
|
||||
const struct keyspan_device_details *d_details;
|
||||
struct usb_serial_port *port;
|
||||
struct keyspan_port_private *p_priv;
|
||||
struct callbacks *cback;
|
||||
int endp;
|
||||
|
||||
s_priv = usb_get_serial_data(serial);
|
||||
d_details = s_priv->device_details;
|
||||
|
|
@ -1404,45 +1400,6 @@ static void keyspan_setup_urbs(struct usb_serial *serial)
|
|||
(serial, d_details->glocont_endpoint, USB_DIR_OUT,
|
||||
serial, s_priv->glocont_buf, GLOCONT_BUFLEN,
|
||||
cback->glocont_callback);
|
||||
|
||||
/* Setup endpoints for each port specific thing */
|
||||
for (i = 0; i < d_details->num_ports; i++) {
|
||||
port = serial->port[i];
|
||||
p_priv = usb_get_serial_port_data(port);
|
||||
|
||||
/* Do indat endpoints first, once for each flip */
|
||||
endp = d_details->indat_endpoints[i];
|
||||
for (j = 0; j <= d_details->indat_endp_flip; ++j, ++endp) {
|
||||
p_priv->in_urbs[j] = keyspan_setup_urb
|
||||
(serial, endp, USB_DIR_IN, port,
|
||||
p_priv->in_buffer[j], 64,
|
||||
cback->indat_callback);
|
||||
}
|
||||
for (; j < 2; ++j)
|
||||
p_priv->in_urbs[j] = NULL;
|
||||
|
||||
/* outdat endpoints also have flip */
|
||||
endp = d_details->outdat_endpoints[i];
|
||||
for (j = 0; j <= d_details->outdat_endp_flip; ++j, ++endp) {
|
||||
p_priv->out_urbs[j] = keyspan_setup_urb
|
||||
(serial, endp, USB_DIR_OUT, port,
|
||||
p_priv->out_buffer[j], 64,
|
||||
cback->outdat_callback);
|
||||
}
|
||||
for (; j < 2; ++j)
|
||||
p_priv->out_urbs[j] = NULL;
|
||||
|
||||
/* inack endpoint */
|
||||
p_priv->inack_urb = keyspan_setup_urb
|
||||
(serial, d_details->inack_endpoints[i], USB_DIR_IN,
|
||||
port, p_priv->inack_buffer, 1, cback->inack_callback);
|
||||
|
||||
/* outcont endpoint */
|
||||
p_priv->outcont_urb = keyspan_setup_urb
|
||||
(serial, d_details->outcont_endpoints[i], USB_DIR_OUT,
|
||||
port, p_priv->outcont_buffer, 64,
|
||||
cback->outcont_callback);
|
||||
}
|
||||
}
|
||||
|
||||
/* usa19 function doesn't require prescaler */
|
||||
|
|
@ -2407,9 +2364,7 @@ static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
|
|||
static int keyspan_startup(struct usb_serial *serial)
|
||||
{
|
||||
int i, err;
|
||||
struct usb_serial_port *port;
|
||||
struct keyspan_serial_private *s_priv;
|
||||
struct keyspan_port_private *p_priv;
|
||||
const struct keyspan_device_details *d_details;
|
||||
|
||||
for (i = 0; (d_details = keyspan_devices[i]) != NULL; ++i)
|
||||
|
|
@ -2432,19 +2387,6 @@ static int keyspan_startup(struct usb_serial *serial)
|
|||
s_priv->device_details = d_details;
|
||||
usb_set_serial_data(serial, s_priv);
|
||||
|
||||
/* Now setup per port private data */
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port = serial->port[i];
|
||||
p_priv = kzalloc(sizeof(struct keyspan_port_private),
|
||||
GFP_KERNEL);
|
||||
if (!p_priv) {
|
||||
dev_dbg(&port->dev, "%s - kmalloc for keyspan_port_private (%d) failed!.\n", __func__, i);
|
||||
return 1;
|
||||
}
|
||||
p_priv->device_details = d_details;
|
||||
usb_set_serial_port_data(port, p_priv);
|
||||
}
|
||||
|
||||
keyspan_setup_urbs(serial);
|
||||
|
||||
if (s_priv->instat_urb != NULL) {
|
||||
|
|
@ -2463,59 +2405,111 @@ static int keyspan_startup(struct usb_serial *serial)
|
|||
|
||||
static void keyspan_disconnect(struct usb_serial *serial)
|
||||
{
|
||||
int i, j;
|
||||
struct usb_serial_port *port;
|
||||
struct keyspan_serial_private *s_priv;
|
||||
struct keyspan_port_private *p_priv;
|
||||
struct keyspan_serial_private *s_priv;
|
||||
|
||||
s_priv = usb_get_serial_data(serial);
|
||||
|
||||
/* Stop reading/writing urbs */
|
||||
stop_urb(s_priv->instat_urb);
|
||||
stop_urb(s_priv->glocont_urb);
|
||||
stop_urb(s_priv->indat_urb);
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
port = serial->port[i];
|
||||
p_priv = usb_get_serial_port_data(port);
|
||||
stop_urb(p_priv->inack_urb);
|
||||
stop_urb(p_priv->outcont_urb);
|
||||
for (j = 0; j < 2; j++) {
|
||||
stop_urb(p_priv->in_urbs[j]);
|
||||
stop_urb(p_priv->out_urbs[j]);
|
||||
}
|
||||
}
|
||||
|
||||
/* Now free them */
|
||||
usb_free_urb(s_priv->instat_urb);
|
||||
usb_free_urb(s_priv->indat_urb);
|
||||
usb_free_urb(s_priv->glocont_urb);
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
port = serial->port[i];
|
||||
p_priv = usb_get_serial_port_data(port);
|
||||
usb_free_urb(p_priv->inack_urb);
|
||||
usb_free_urb(p_priv->outcont_urb);
|
||||
for (j = 0; j < 2; j++) {
|
||||
usb_free_urb(p_priv->in_urbs[j]);
|
||||
usb_free_urb(p_priv->out_urbs[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void keyspan_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct usb_serial_port *port;
|
||||
struct keyspan_serial_private *s_priv;
|
||||
struct keyspan_serial_private *s_priv;
|
||||
|
||||
s_priv = usb_get_serial_data(serial);
|
||||
|
||||
kfree(s_priv);
|
||||
usb_free_urb(s_priv->instat_urb);
|
||||
usb_free_urb(s_priv->indat_urb);
|
||||
usb_free_urb(s_priv->glocont_urb);
|
||||
|
||||
/* Now free per port private data */
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port = serial->port[i];
|
||||
kfree(usb_get_serial_port_data(port));
|
||||
kfree(s_priv);
|
||||
}
|
||||
|
||||
static int keyspan_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct keyspan_serial_private *s_priv;
|
||||
struct keyspan_port_private *p_priv;
|
||||
const struct keyspan_device_details *d_details;
|
||||
struct callbacks *cback;
|
||||
int endp;
|
||||
int port_num;
|
||||
int i;
|
||||
|
||||
s_priv = usb_get_serial_data(serial);
|
||||
d_details = s_priv->device_details;
|
||||
|
||||
p_priv = kzalloc(sizeof(*p_priv), GFP_KERNEL);
|
||||
if (!p_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
p_priv->device_details = d_details;
|
||||
|
||||
/* Setup values for the various callback routines */
|
||||
cback = &keyspan_callbacks[d_details->msg_format];
|
||||
|
||||
port_num = port->number - port->serial->minor;
|
||||
|
||||
/* Do indat endpoints first, once for each flip */
|
||||
endp = d_details->indat_endpoints[port_num];
|
||||
for (i = 0; i <= d_details->indat_endp_flip; ++i, ++endp) {
|
||||
p_priv->in_urbs[i] = keyspan_setup_urb(serial, endp,
|
||||
USB_DIR_IN, port,
|
||||
p_priv->in_buffer[i], 64,
|
||||
cback->indat_callback);
|
||||
}
|
||||
/* outdat endpoints also have flip */
|
||||
endp = d_details->outdat_endpoints[port_num];
|
||||
for (i = 0; i <= d_details->outdat_endp_flip; ++i, ++endp) {
|
||||
p_priv->out_urbs[i] = keyspan_setup_urb(serial, endp,
|
||||
USB_DIR_OUT, port,
|
||||
p_priv->out_buffer[i], 64,
|
||||
cback->outdat_callback);
|
||||
}
|
||||
/* inack endpoint */
|
||||
p_priv->inack_urb = keyspan_setup_urb(serial,
|
||||
d_details->inack_endpoints[port_num],
|
||||
USB_DIR_IN, port,
|
||||
p_priv->inack_buffer, 1,
|
||||
cback->inack_callback);
|
||||
/* outcont endpoint */
|
||||
p_priv->outcont_urb = keyspan_setup_urb(serial,
|
||||
d_details->outcont_endpoints[port_num],
|
||||
USB_DIR_OUT, port,
|
||||
p_priv->outcont_buffer, 64,
|
||||
cback->outcont_callback);
|
||||
|
||||
usb_set_serial_port_data(port, p_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int keyspan_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct keyspan_port_private *p_priv;
|
||||
int i;
|
||||
|
||||
p_priv = usb_get_serial_port_data(port);
|
||||
|
||||
stop_urb(p_priv->inack_urb);
|
||||
stop_urb(p_priv->outcont_urb);
|
||||
for (i = 0; i < 2; i++) {
|
||||
stop_urb(p_priv->in_urbs[i]);
|
||||
stop_urb(p_priv->out_urbs[i]);
|
||||
}
|
||||
|
||||
usb_free_urb(p_priv->inack_urb);
|
||||
usb_free_urb(p_priv->outcont_urb);
|
||||
for (i = 0; i < 2; i++) {
|
||||
usb_free_urb(p_priv->in_urbs[i]);
|
||||
usb_free_urb(p_priv->out_urbs[i]);
|
||||
}
|
||||
|
||||
kfree(p_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ static void keyspan_dtr_rts (struct usb_serial_port *port, int on);
|
|||
static int keyspan_startup (struct usb_serial *serial);
|
||||
static void keyspan_disconnect (struct usb_serial *serial);
|
||||
static void keyspan_release (struct usb_serial *serial);
|
||||
static int keyspan_port_probe(struct usb_serial_port *port);
|
||||
static int keyspan_port_remove(struct usb_serial_port *port);
|
||||
static int keyspan_write_room (struct tty_struct *tty);
|
||||
|
||||
static int keyspan_write (struct tty_struct *tty,
|
||||
|
|
@ -567,6 +569,8 @@ static struct usb_serial_driver keyspan_1port_device = {
|
|||
.attach = keyspan_startup,
|
||||
.disconnect = keyspan_disconnect,
|
||||
.release = keyspan_release,
|
||||
.port_probe = keyspan_port_probe,
|
||||
.port_remove = keyspan_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver keyspan_2port_device = {
|
||||
|
|
@ -589,6 +593,8 @@ static struct usb_serial_driver keyspan_2port_device = {
|
|||
.attach = keyspan_startup,
|
||||
.disconnect = keyspan_disconnect,
|
||||
.release = keyspan_release,
|
||||
.port_probe = keyspan_port_probe,
|
||||
.port_remove = keyspan_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver keyspan_4port_device = {
|
||||
|
|
@ -611,6 +617,8 @@ static struct usb_serial_driver keyspan_4port_device = {
|
|||
.attach = keyspan_startup,
|
||||
.disconnect = keyspan_disconnect,
|
||||
.release = keyspan_release,
|
||||
.port_probe = keyspan_port_probe,
|
||||
.port_remove = keyspan_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
|
|||
|
|
@ -713,29 +713,33 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
|
|||
MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
|
||||
#endif
|
||||
|
||||
static int keyspan_pda_startup(struct usb_serial *serial)
|
||||
static int keyspan_pda_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
|
||||
struct keyspan_pda_private *priv;
|
||||
|
||||
/* allocate the private data structures for all ports. Well, for all
|
||||
one ports. */
|
||||
|
||||
priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return 1; /* error */
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
init_waitqueue_head(&serial->port[0]->write_wait);
|
||||
return -ENOMEM;
|
||||
|
||||
INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
|
||||
INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
|
||||
priv->serial = serial;
|
||||
priv->port = serial->port[0];
|
||||
priv->serial = port->serial;
|
||||
priv->port = port;
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void keyspan_pda_release(struct usb_serial *serial)
|
||||
static int keyspan_pda_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
kfree(usb_get_serial_port_data(serial->port[0]));
|
||||
struct keyspan_pda_private *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef KEYSPAN
|
||||
|
|
@ -786,8 +790,8 @@ static struct usb_serial_driver keyspan_pda_device = {
|
|||
.break_ctl = keyspan_pda_break_ctl,
|
||||
.tiocmget = keyspan_pda_tiocmget,
|
||||
.tiocmset = keyspan_pda_tiocmset,
|
||||
.attach = keyspan_pda_startup,
|
||||
.release = keyspan_pda_release,
|
||||
.port_probe = keyspan_pda_port_probe,
|
||||
.port_remove = keyspan_pda_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
|
|||
|
|
@ -60,8 +60,8 @@
|
|||
/*
|
||||
* Function prototypes
|
||||
*/
|
||||
static int klsi_105_startup(struct usb_serial *serial);
|
||||
static void klsi_105_release(struct usb_serial *serial);
|
||||
static int klsi_105_port_probe(struct usb_serial_port *port);
|
||||
static int klsi_105_port_remove(struct usb_serial_port *port);
|
||||
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
static void klsi_105_close(struct usb_serial_port *port);
|
||||
static void klsi_105_set_termios(struct tty_struct *tty,
|
||||
|
|
@ -99,8 +99,8 @@ static struct usb_serial_driver kl5kusb105d_device = {
|
|||
/*.break_ctl = klsi_105_break_ctl,*/
|
||||
.tiocmget = klsi_105_tiocmget,
|
||||
.tiocmset = klsi_105_tiocmset,
|
||||
.attach = klsi_105_startup,
|
||||
.release = klsi_105_release,
|
||||
.port_probe = klsi_105_port_probe,
|
||||
.port_remove = klsi_105_port_remove,
|
||||
.throttle = usb_serial_generic_throttle,
|
||||
.unthrottle = usb_serial_generic_unthrottle,
|
||||
.process_read_urb = klsi_105_process_read_urb,
|
||||
|
|
@ -223,60 +223,40 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
|
|||
* Driver's tty interface functions
|
||||
*/
|
||||
|
||||
static int klsi_105_startup(struct usb_serial *serial)
|
||||
static int klsi_105_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct klsi_105_private *priv;
|
||||
int i;
|
||||
|
||||
/* check if we support the product id (see keyspan.c)
|
||||
* FIXME
|
||||
*/
|
||||
priv = kmalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* allocate the private data structure */
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
priv = kmalloc(sizeof(struct klsi_105_private),
|
||||
GFP_KERNEL);
|
||||
if (!priv) {
|
||||
dev_dbg(&serial->interface->dev,
|
||||
"%s - kmalloc for klsi_105_private failed.\n",
|
||||
__func__);
|
||||
i--;
|
||||
goto err_cleanup;
|
||||
}
|
||||
/* set initial values for control structures */
|
||||
priv->cfg.pktlen = 5;
|
||||
priv->cfg.baudrate = kl5kusb105a_sio_b9600;
|
||||
priv->cfg.databits = kl5kusb105a_dtb_8;
|
||||
priv->cfg.unknown1 = 0;
|
||||
priv->cfg.unknown2 = 1;
|
||||
/* set initial values for control structures */
|
||||
priv->cfg.pktlen = 5;
|
||||
priv->cfg.baudrate = kl5kusb105a_sio_b9600;
|
||||
priv->cfg.databits = kl5kusb105a_dtb_8;
|
||||
priv->cfg.unknown1 = 0;
|
||||
priv->cfg.unknown2 = 1;
|
||||
|
||||
priv->line_state = 0;
|
||||
priv->line_state = 0;
|
||||
|
||||
usb_set_serial_port_data(serial->port[i], priv);
|
||||
spin_lock_init(&priv->lock);
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
/* priv->termios is left uninitialized until port opening */
|
||||
|
||||
/* priv->termios is left uninitialized until port opening */
|
||||
init_waitqueue_head(&serial->port[i]->write_wait);
|
||||
}
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return 0;
|
||||
|
||||
err_cleanup:
|
||||
for (; i >= 0; i--) {
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
static void klsi_105_release(struct usb_serial *serial)
|
||||
static int klsi_105_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
int i;
|
||||
struct klsi_105_private *priv;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
|
|
|
|||
|
|
@ -54,8 +54,8 @@
|
|||
|
||||
|
||||
/* Function prototypes */
|
||||
static int kobil_startup(struct usb_serial *serial);
|
||||
static void kobil_release(struct usb_serial *serial);
|
||||
static int kobil_port_probe(struct usb_serial_port *probe);
|
||||
static int kobil_port_remove(struct usb_serial_port *probe);
|
||||
static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
static void kobil_close(struct usb_serial_port *port);
|
||||
static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
|
|
@ -89,8 +89,8 @@ static struct usb_serial_driver kobil_device = {
|
|||
.description = "KOBIL USB smart card terminal",
|
||||
.id_table = id_table,
|
||||
.num_ports = 1,
|
||||
.attach = kobil_startup,
|
||||
.release = kobil_release,
|
||||
.port_probe = kobil_port_probe,
|
||||
.port_remove = kobil_port_remove,
|
||||
.ioctl = kobil_ioctl,
|
||||
.set_termios = kobil_set_termios,
|
||||
.init_termios = kobil_init_termios,
|
||||
|
|
@ -117,9 +117,10 @@ struct kobil_private {
|
|||
};
|
||||
|
||||
|
||||
static int kobil_startup(struct usb_serial *serial)
|
||||
static int kobil_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
int i;
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct kobil_private *priv;
|
||||
struct usb_device *pdev;
|
||||
struct usb_host_config *actconfig;
|
||||
|
|
@ -149,7 +150,7 @@ static int kobil_startup(struct usb_serial *serial)
|
|||
dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n");
|
||||
break;
|
||||
}
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
/* search for the necessary endpoints */
|
||||
pdev = serial->dev;
|
||||
|
|
@ -179,12 +180,14 @@ static int kobil_startup(struct usb_serial *serial)
|
|||
}
|
||||
|
||||
|
||||
static void kobil_release(struct usb_serial *serial)
|
||||
static int kobil_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
int i;
|
||||
struct kobil_private *priv;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void kobil_init_termios(struct tty_struct *tty)
|
||||
|
|
|
|||
|
|
@ -49,7 +49,8 @@
|
|||
* Function prototypes
|
||||
*/
|
||||
static int mct_u232_startup(struct usb_serial *serial);
|
||||
static void mct_u232_release(struct usb_serial *serial);
|
||||
static int mct_u232_port_probe(struct usb_serial_port *port);
|
||||
static int mct_u232_port_remove(struct usb_serial_port *remove);
|
||||
static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
static void mct_u232_close(struct usb_serial_port *port);
|
||||
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 = {
|
|||
.tiocmget = mct_u232_tiocmget,
|
||||
.tiocmset = mct_u232_tiocmset,
|
||||
.attach = mct_u232_startup,
|
||||
.release = mct_u232_release,
|
||||
.port_probe = mct_u232_port_probe,
|
||||
.port_remove = mct_u232_port_remove,
|
||||
.ioctl = mct_u232_ioctl,
|
||||
.get_icount = mct_u232_get_icount,
|
||||
};
|
||||
|
|
@ -388,18 +390,8 @@ static void mct_u232_msr_to_state(struct usb_serial_port *port,
|
|||
|
||||
static int mct_u232_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct mct_u232_private *priv;
|
||||
struct usb_serial_port *port, *rport;
|
||||
|
||||
priv = kzalloc(sizeof(struct mct_u232_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->msr_wait);
|
||||
usb_set_serial_port_data(serial->port[0], priv);
|
||||
|
||||
init_waitqueue_head(&serial->port[0]->write_wait);
|
||||
|
||||
/* Puh, that's dirty */
|
||||
port = serial->port[0];
|
||||
rport = serial->port[1];
|
||||
|
|
@ -412,18 +404,31 @@ static int mct_u232_startup(struct usb_serial *serial)
|
|||
return 0;
|
||||
} /* mct_u232_startup */
|
||||
|
||||
|
||||
static void mct_u232_release(struct usb_serial *serial)
|
||||
static int mct_u232_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct mct_u232_private *priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
/* My special items, the standard routines free my urbs */
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
}
|
||||
} /* mct_u232_release */
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mct_u232_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct mct_u232_private *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
{
|
||||
|
|
@ -515,12 +520,14 @@ static void mct_u232_dtr_rts(struct usb_serial_port *port, int on)
|
|||
|
||||
static void mct_u232_close(struct usb_serial_port *port)
|
||||
{
|
||||
if (port->serial->dev) {
|
||||
/* shutdown our urbs */
|
||||
usb_kill_urb(port->write_urb);
|
||||
usb_kill_urb(port->read_urb);
|
||||
usb_kill_urb(port->interrupt_in_urb);
|
||||
}
|
||||
/*
|
||||
* Must kill the read urb as it is actually an interrupt urb, which
|
||||
* generic close thus fails to kill.
|
||||
*/
|
||||
usb_kill_urb(port->read_urb);
|
||||
usb_kill_urb(port->interrupt_in_urb);
|
||||
|
||||
usb_serial_generic_close(port);
|
||||
} /* mct_u232_close */
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -179,16 +179,13 @@ static void metrousb_cleanup(struct usb_serial_port *port)
|
|||
{
|
||||
dev_dbg(&port->dev, "%s\n", __func__);
|
||||
|
||||
if (port->serial->dev) {
|
||||
/* Shutdown any interrupt in urbs. */
|
||||
if (port->interrupt_in_urb) {
|
||||
usb_unlink_urb(port->interrupt_in_urb);
|
||||
usb_kill_urb(port->interrupt_in_urb);
|
||||
}
|
||||
usb_unlink_urb(port->interrupt_in_urb);
|
||||
usb_kill_urb(port->interrupt_in_urb);
|
||||
|
||||
/* Send deactivate cmd to device */
|
||||
mutex_lock(&port->serial->disc_mutex);
|
||||
if (!port->serial->disconnected)
|
||||
metrousb_send_unidirectional_cmd(UNI_CMD_CLOSE, port);
|
||||
}
|
||||
mutex_unlock(&port->serial->disc_mutex);
|
||||
}
|
||||
|
||||
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
|
|||
return retval;
|
||||
}
|
||||
|
||||
static void metrousb_shutdown(struct usb_serial *serial)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
dev_dbg(&serial->dev->dev, "%s\n", __func__);
|
||||
|
||||
/* Stop reading and writing on all ports. */
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
/* Close any open urbs. */
|
||||
metrousb_cleanup(serial->port[i]);
|
||||
|
||||
/* Free memory. */
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
|
||||
dev_dbg(&serial->dev->dev, "%s - freed port number=%d\n",
|
||||
__func__, serial->port[i]->number);
|
||||
}
|
||||
}
|
||||
|
||||
static int metrousb_startup(struct usb_serial *serial)
|
||||
static int metrousb_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct metrousb_private *metro_priv;
|
||||
struct usb_serial_port *port;
|
||||
int i = 0;
|
||||
|
||||
dev_dbg(&serial->dev->dev, "%s\n", __func__);
|
||||
metro_priv = kzalloc(sizeof(*metro_priv), GFP_KERNEL);
|
||||
if (!metro_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Loop through the serial ports setting up the private structures.
|
||||
* Currently we only use one port. */
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
port = serial->port[i];
|
||||
spin_lock_init(&metro_priv->lock);
|
||||
|
||||
/* Declare memory. */
|
||||
metro_priv = kzalloc(sizeof(struct metrousb_private), GFP_KERNEL);
|
||||
if (!metro_priv)
|
||||
return -ENOMEM;
|
||||
usb_set_serial_port_data(port, metro_priv);
|
||||
|
||||
/* Initialize memory. */
|
||||
spin_lock_init(&metro_priv->lock);
|
||||
usb_set_serial_port_data(port, metro_priv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dev_dbg(&serial->dev->dev, "%s - port number=%d\n ",
|
||||
__func__, port->number);
|
||||
}
|
||||
static int metrousb_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct metrousb_private *metro_priv;
|
||||
|
||||
metro_priv = usb_get_serial_port_data(port);
|
||||
kfree(metro_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -414,8 +387,8 @@ static struct usb_serial_driver metrousb_device = {
|
|||
.close = metrousb_cleanup,
|
||||
.read_int_callback = metrousb_read_int_callback,
|
||||
.write_int_callback = metrousb_write_int_callback,
|
||||
.attach = metrousb_startup,
|
||||
.release = metrousb_shutdown,
|
||||
.port_probe = metrousb_port_probe,
|
||||
.port_remove = metrousb_port_remove,
|
||||
.throttle = metrousb_throttle,
|
||||
.unthrottle = metrousb_unthrottle,
|
||||
.tiocmget = metrousb_tiocmget,
|
||||
|
|
|
|||
|
|
@ -1966,9 +1966,7 @@ static int mos7720_ioctl(struct tty_struct *tty,
|
|||
|
||||
static int mos7720_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct moschip_port *mos7720_port;
|
||||
struct usb_device *dev;
|
||||
int i;
|
||||
char data;
|
||||
u16 product;
|
||||
int ret_val;
|
||||
|
|
@ -1999,29 +1997,6 @@ static int mos7720_startup(struct usb_serial *serial)
|
|||
serial->port[1]->interrupt_in_buffer = NULL;
|
||||
}
|
||||
|
||||
|
||||
/* set up serial port private structures */
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
mos7720_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
|
||||
if (mos7720_port == NULL) {
|
||||
dev_err(&dev->dev, "%s - Out of memory\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Initialize all port interrupt end point to port 0 int
|
||||
* endpoint. Our device has only one interrupt endpoint
|
||||
* common to all ports */
|
||||
serial->port[i]->interrupt_in_endpointAddress =
|
||||
serial->port[0]->interrupt_in_endpointAddress;
|
||||
|
||||
mos7720_port->port = serial->port[i];
|
||||
usb_set_serial_port_data(serial->port[i], mos7720_port);
|
||||
|
||||
dev_dbg(&dev->dev, "port number is %d\n", serial->port[i]->number);
|
||||
dev_dbg(&dev->dev, "serial number is %d\n", serial->minor);
|
||||
}
|
||||
|
||||
|
||||
/* setting configuration feature to one */
|
||||
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||
(__u8)0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5*HZ);
|
||||
|
|
@ -2049,8 +2024,6 @@ static int mos7720_startup(struct usb_serial *serial)
|
|||
|
||||
static void mos7720_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
|
||||
#ifdef CONFIG_USB_SERIAL_MOS7715_PARPORT
|
||||
/* close the parallel port */
|
||||
|
||||
|
|
@ -2089,9 +2062,36 @@ static void mos7720_release(struct usb_serial *serial)
|
|||
kref_put(&mos_parport->ref_count, destroy_mos_parport);
|
||||
}
|
||||
#endif
|
||||
/* free private structure allocated for serial port */
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
}
|
||||
|
||||
static int mos7720_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct moschip_port *mos7720_port;
|
||||
|
||||
mos7720_port = kzalloc(sizeof(*mos7720_port), GFP_KERNEL);
|
||||
if (!mos7720_port)
|
||||
return -ENOMEM;
|
||||
|
||||
/* Initialize all port interrupt end point to port 0 int endpoint.
|
||||
* Our device has only one interrupt endpoint common to all ports.
|
||||
*/
|
||||
port->interrupt_in_endpointAddress =
|
||||
port->serial->port[0]->interrupt_in_endpointAddress;
|
||||
mos7720_port->port = port;
|
||||
|
||||
usb_set_serial_port_data(port, mos7720_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mos7720_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct moschip_port *mos7720_port;
|
||||
|
||||
mos7720_port = usb_get_serial_port_data(port);
|
||||
kfree(mos7720_port);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_serial_driver moschip7720_2port_driver = {
|
||||
|
|
@ -2109,6 +2109,8 @@ static struct usb_serial_driver moschip7720_2port_driver = {
|
|||
.probe = mos77xx_probe,
|
||||
.attach = mos7720_startup,
|
||||
.release = mos7720_release,
|
||||
.port_probe = mos7720_port_probe,
|
||||
.port_remove = mos7720_port_remove,
|
||||
.ioctl = mos7720_ioctl,
|
||||
.tiocmget = mos7720_tiocmget,
|
||||
.tiocmset = mos7720_tiocmset,
|
||||
|
|
|
|||
|
|
@ -218,12 +218,10 @@ struct moschip_port {
|
|||
int port_num; /*Actual port number in the device(1,2,etc) */
|
||||
struct urb *write_urb; /* write URB for this port */
|
||||
struct urb *read_urb; /* read URB for this port */
|
||||
struct urb *int_urb;
|
||||
__u8 shadowLCR; /* last LCR value received */
|
||||
__u8 shadowMCR; /* last MCR value received */
|
||||
char open;
|
||||
char open_ports;
|
||||
char zombie;
|
||||
wait_queue_head_t wait_chase; /* for handling sleeping while waiting for chase to finish */
|
||||
wait_queue_head_t delta_msr_wait; /* for handling sleeping while waiting for msr change to happen */
|
||||
int delta_msr_cond;
|
||||
|
|
@ -478,7 +476,6 @@ static void mos7840_control_callback(struct urb *urb)
|
|||
struct moschip_port *mos7840_port;
|
||||
struct device *dev = &urb->dev->dev;
|
||||
__u8 regval = 0x0;
|
||||
int result = 0;
|
||||
int status = urb->status;
|
||||
|
||||
mos7840_port = urb->context;
|
||||
|
|
@ -495,7 +492,7 @@ static void mos7840_control_callback(struct urb *urb)
|
|||
return;
|
||||
default:
|
||||
dev_dbg(dev, "%s - nonzero urb status received: %d\n", __func__, status);
|
||||
goto exit;
|
||||
return;
|
||||
}
|
||||
|
||||
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)
|
|||
mos7840_handle_new_msr(mos7840_port, regval);
|
||||
else if (mos7840_port->MsrLsr == 1)
|
||||
mos7840_handle_new_lsr(mos7840_port, regval);
|
||||
|
||||
exit:
|
||||
spin_lock(&mos7840_port->pool_lock);
|
||||
if (!mos7840_port->zombie)
|
||||
result = usb_submit_urb(mos7840_port->int_urb, GFP_ATOMIC);
|
||||
spin_unlock(&mos7840_port->pool_lock);
|
||||
if (result) {
|
||||
dev_err(dev, "%s - Error %d submitting interrupt urb\n",
|
||||
__func__, result);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
|||
wreg = MODEM_STATUS_REGISTER;
|
||||
break;
|
||||
}
|
||||
spin_lock(&mos7840_port->pool_lock);
|
||||
if (!mos7840_port->zombie) {
|
||||
rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);
|
||||
} else {
|
||||
spin_unlock(&mos7840_port->pool_lock);
|
||||
return;
|
||||
}
|
||||
spin_unlock(&mos7840_port->pool_lock);
|
||||
rv = mos7840_get_reg(mos7840_port, wval, wreg, &Data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2347,309 +2327,249 @@ static int mos7840_calc_num_ports(struct usb_serial *serial)
|
|||
return mos7840_num_ports;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* mos7840_startup
|
||||
****************************************************************************/
|
||||
|
||||
static int mos7840_startup(struct usb_serial *serial)
|
||||
static int mos7840_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct moschip_port *mos7840_port;
|
||||
struct usb_device *dev;
|
||||
int i, status;
|
||||
int status;
|
||||
int pnum;
|
||||
__u16 Data;
|
||||
|
||||
dev = serial->dev;
|
||||
|
||||
/* we set up the pointers to the endpoints in the mos7840_open *
|
||||
* function, as the structures aren't created yet. */
|
||||
|
||||
/* set up port private structures */
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
dev_dbg(&dev->dev, "mos7840_startup: configuring port %d............\n", i);
|
||||
mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
|
||||
if (mos7840_port == NULL) {
|
||||
dev_err(&dev->dev, "%s - Out of memory\n", __func__);
|
||||
status = -ENOMEM;
|
||||
i--; /* don't follow NULL pointer cleaning up */
|
||||
goto error;
|
||||
}
|
||||
pnum = port->number - serial->minor;
|
||||
|
||||
/* Initialize all port interrupt end point to port 0 int
|
||||
* endpoint. Our device has only one interrupt end point
|
||||
* common to all port */
|
||||
|
||||
mos7840_port->port = serial->port[i];
|
||||
mos7840_set_port_private(serial->port[i], mos7840_port);
|
||||
spin_lock_init(&mos7840_port->pool_lock);
|
||||
|
||||
/* minor is not initialised until later by
|
||||
* usb-serial.c:get_free_serial() and cannot therefore be used
|
||||
* to index device instances */
|
||||
mos7840_port->port_num = i + 1;
|
||||
dev_dbg(&dev->dev, "serial->port[i]->number = %d\n", serial->port[i]->number);
|
||||
dev_dbg(&dev->dev, "serial->port[i]->serial->minor = %d\n", serial->port[i]->serial->minor);
|
||||
dev_dbg(&dev->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num);
|
||||
dev_dbg(&dev->dev, "serial->minor = %d\n", serial->minor);
|
||||
|
||||
if (mos7840_port->port_num == 1) {
|
||||
mos7840_port->SpRegOffset = 0x0;
|
||||
mos7840_port->ControlRegOffset = 0x1;
|
||||
mos7840_port->DcrRegOffset = 0x4;
|
||||
} else if ((mos7840_port->port_num == 2)
|
||||
&& (serial->num_ports == 4)) {
|
||||
mos7840_port->SpRegOffset = 0x8;
|
||||
mos7840_port->ControlRegOffset = 0x9;
|
||||
mos7840_port->DcrRegOffset = 0x16;
|
||||
} else if ((mos7840_port->port_num == 2)
|
||||
&& (serial->num_ports == 2)) {
|
||||
mos7840_port->SpRegOffset = 0xa;
|
||||
mos7840_port->ControlRegOffset = 0xb;
|
||||
mos7840_port->DcrRegOffset = 0x19;
|
||||
} else if ((mos7840_port->port_num == 3)
|
||||
&& (serial->num_ports == 4)) {
|
||||
mos7840_port->SpRegOffset = 0xa;
|
||||
mos7840_port->ControlRegOffset = 0xb;
|
||||
mos7840_port->DcrRegOffset = 0x19;
|
||||
} else if ((mos7840_port->port_num == 4)
|
||||
&& (serial->num_ports == 4)) {
|
||||
mos7840_port->SpRegOffset = 0xc;
|
||||
mos7840_port->ControlRegOffset = 0xd;
|
||||
mos7840_port->DcrRegOffset = 0x1c;
|
||||
}
|
||||
mos7840_dump_serial_port(serial->port[i], mos7840_port);
|
||||
mos7840_set_port_private(serial->port[i], mos7840_port);
|
||||
|
||||
/* enable rx_disable bit in control register */
|
||||
status = mos7840_get_reg_sync(serial->port[i],
|
||||
mos7840_port->ControlRegOffset, &Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Reading ControlReg failed status-0x%x\n", status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "ControlReg Reading success val is %x, status%d\n", Data, status);
|
||||
Data |= 0x08; /* setting driver done bit */
|
||||
Data |= 0x04; /* sp1_bit to have cts change reflect in
|
||||
modem status reg */
|
||||
|
||||
/* Data |= 0x20; //rx_disable bit */
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
mos7840_port->ControlRegOffset, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "ControlReg Writing success(rx_disable) status%d\n", status);
|
||||
|
||||
/* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
|
||||
and 0x24 in DCR3 */
|
||||
Data = 0x01;
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
(__u16) (mos7840_port->DcrRegOffset + 0), Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing DCR0 failed status-0x%x\n", status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "DCR0 Writing success status%d\n", status);
|
||||
|
||||
Data = 0x05;
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
(__u16) (mos7840_port->DcrRegOffset + 1), Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing DCR1 failed status-0x%x\n", status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "DCR1 Writing success status%d\n", status);
|
||||
|
||||
Data = 0x24;
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
(__u16) (mos7840_port->DcrRegOffset + 2), Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing DCR2 failed status-0x%x\n", status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "DCR2 Writing success status%d\n", status);
|
||||
|
||||
/* write values in clkstart0x0 and clkmulti 0x20 */
|
||||
Data = 0x0;
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
CLK_START_VALUE_REGISTER, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status);
|
||||
|
||||
Data = 0x20;
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
CLK_MULTI_REGISTER, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status);
|
||||
goto error;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status);
|
||||
|
||||
/* write value 0x0 to scratchpad register */
|
||||
Data = 0x00;
|
||||
status = mos7840_set_uart_reg(serial->port[i],
|
||||
SCRATCH_PAD_REGISTER, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status);
|
||||
|
||||
/* Zero Length flag register */
|
||||
if ((mos7840_port->port_num != 1)
|
||||
&& (serial->num_ports == 2)) {
|
||||
|
||||
Data = 0xff;
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
(__u16) (ZLP_REG1 +
|
||||
((__u16)mos7840_port->port_num)), Data);
|
||||
dev_dbg(&dev->dev, "ZLIP offset %x\n",
|
||||
(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num)));
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 2, status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 2, status);
|
||||
} else {
|
||||
Data = 0xff;
|
||||
status = mos7840_set_reg_sync(serial->port[i],
|
||||
(__u16) (ZLP_REG1 +
|
||||
((__u16)mos7840_port->port_num) - 0x1), Data);
|
||||
dev_dbg(&dev->dev, "ZLIP offset %x\n",
|
||||
(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1));
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing ZLP_REG%d failed status-0x%x\n", i + 1, status);
|
||||
break;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "ZLP_REG%d Writing success status%d\n", i + 1, status);
|
||||
|
||||
}
|
||||
mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
|
||||
mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
|
||||
GFP_KERNEL);
|
||||
if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
|
||||
!mos7840_port->dr) {
|
||||
status = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
mos7840_port->has_led = false;
|
||||
|
||||
/* Initialize LED timers */
|
||||
if (device_type == MOSCHIP_DEVICE_ID_7810) {
|
||||
mos7840_port->has_led = true;
|
||||
|
||||
init_timer(&mos7840_port->led_timer1);
|
||||
mos7840_port->led_timer1.function = mos7840_led_off;
|
||||
mos7840_port->led_timer1.expires =
|
||||
jiffies + msecs_to_jiffies(LED_ON_MS);
|
||||
mos7840_port->led_timer1.data =
|
||||
(unsigned long)mos7840_port;
|
||||
|
||||
init_timer(&mos7840_port->led_timer2);
|
||||
mos7840_port->led_timer2.function =
|
||||
mos7840_led_flag_off;
|
||||
mos7840_port->led_timer2.expires =
|
||||
jiffies + msecs_to_jiffies(LED_OFF_MS);
|
||||
mos7840_port->led_timer2.data =
|
||||
(unsigned long)mos7840_port;
|
||||
|
||||
mos7840_port->led_flag = false;
|
||||
|
||||
/* Turn off LED */
|
||||
mos7840_set_led_sync(serial->port[i],
|
||||
MODEM_CONTROL_REGISTER, 0x0300);
|
||||
}
|
||||
dev_dbg(&port->dev, "mos7840_startup: configuring port %d\n", pnum);
|
||||
mos7840_port = kzalloc(sizeof(struct moschip_port), GFP_KERNEL);
|
||||
if (mos7840_port == NULL) {
|
||||
dev_err(&port->dev, "%s - Out of memory\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Zero Length flag enable */
|
||||
Data = 0x0f;
|
||||
status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
|
||||
/* Initialize all port interrupt end point to port 0 int
|
||||
* endpoint. Our device has only one interrupt end point
|
||||
* common to all port */
|
||||
|
||||
mos7840_port->port = port;
|
||||
mos7840_set_port_private(port, mos7840_port);
|
||||
spin_lock_init(&mos7840_port->pool_lock);
|
||||
|
||||
/* minor is not initialised until later by
|
||||
* usb-serial.c:get_free_serial() and cannot therefore be used
|
||||
* to index device instances */
|
||||
mos7840_port->port_num = pnum + 1;
|
||||
dev_dbg(&port->dev, "port->number = %d\n", port->number);
|
||||
dev_dbg(&port->dev, "port->serial->minor = %d\n", port->serial->minor);
|
||||
dev_dbg(&port->dev, "mos7840_port->port_num = %d\n", mos7840_port->port_num);
|
||||
dev_dbg(&port->dev, "serial->minor = %d\n", serial->minor);
|
||||
|
||||
if (mos7840_port->port_num == 1) {
|
||||
mos7840_port->SpRegOffset = 0x0;
|
||||
mos7840_port->ControlRegOffset = 0x1;
|
||||
mos7840_port->DcrRegOffset = 0x4;
|
||||
} else if ((mos7840_port->port_num == 2) && (serial->num_ports == 4)) {
|
||||
mos7840_port->SpRegOffset = 0x8;
|
||||
mos7840_port->ControlRegOffset = 0x9;
|
||||
mos7840_port->DcrRegOffset = 0x16;
|
||||
} else if ((mos7840_port->port_num == 2) && (serial->num_ports == 2)) {
|
||||
mos7840_port->SpRegOffset = 0xa;
|
||||
mos7840_port->ControlRegOffset = 0xb;
|
||||
mos7840_port->DcrRegOffset = 0x19;
|
||||
} else if ((mos7840_port->port_num == 3) && (serial->num_ports == 4)) {
|
||||
mos7840_port->SpRegOffset = 0xa;
|
||||
mos7840_port->ControlRegOffset = 0xb;
|
||||
mos7840_port->DcrRegOffset = 0x19;
|
||||
} else if ((mos7840_port->port_num == 4) && (serial->num_ports == 4)) {
|
||||
mos7840_port->SpRegOffset = 0xc;
|
||||
mos7840_port->ControlRegOffset = 0xd;
|
||||
mos7840_port->DcrRegOffset = 0x1c;
|
||||
}
|
||||
mos7840_dump_serial_port(port, mos7840_port);
|
||||
mos7840_set_port_private(port, mos7840_port);
|
||||
|
||||
/* enable rx_disable bit in control register */
|
||||
status = mos7840_get_reg_sync(port,
|
||||
mos7840_port->ControlRegOffset, &Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&dev->dev, "Writing ZLP_REG5 failed status-0x%x\n", status);
|
||||
dev_dbg(&port->dev, "Reading ControlReg failed status-0x%x\n", status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "ControlReg Reading success val is %x, status%d\n", Data, status);
|
||||
Data |= 0x08; /* setting driver done bit */
|
||||
Data |= 0x04; /* sp1_bit to have cts change reflect in
|
||||
modem status reg */
|
||||
|
||||
/* Data |= 0x20; //rx_disable bit */
|
||||
status = mos7840_set_reg_sync(port,
|
||||
mos7840_port->ControlRegOffset, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing ControlReg failed(rx_disable) status-0x%x\n", status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "ControlReg Writing success(rx_disable) status%d\n", status);
|
||||
|
||||
/* Write default values in DCR (i.e 0x01 in DCR0, 0x05 in DCR2
|
||||
and 0x24 in DCR3 */
|
||||
Data = 0x01;
|
||||
status = mos7840_set_reg_sync(port,
|
||||
(__u16) (mos7840_port->DcrRegOffset + 0), Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing DCR0 failed status-0x%x\n", status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "DCR0 Writing success status%d\n", status);
|
||||
|
||||
Data = 0x05;
|
||||
status = mos7840_set_reg_sync(port,
|
||||
(__u16) (mos7840_port->DcrRegOffset + 1), Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing DCR1 failed status-0x%x\n", status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "DCR1 Writing success status%d\n", status);
|
||||
|
||||
Data = 0x24;
|
||||
status = mos7840_set_reg_sync(port,
|
||||
(__u16) (mos7840_port->DcrRegOffset + 2), Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing DCR2 failed status-0x%x\n", status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "DCR2 Writing success status%d\n", status);
|
||||
|
||||
/* write values in clkstart0x0 and clkmulti 0x20 */
|
||||
Data = 0x0;
|
||||
status = mos7840_set_reg_sync(port, CLK_START_VALUE_REGISTER, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing CLK_START_VALUE_REGISTER failed status-0x%x\n", status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "CLK_START_VALUE_REGISTER Writing success status%d\n", status);
|
||||
|
||||
Data = 0x20;
|
||||
status = mos7840_set_reg_sync(port, CLK_MULTI_REGISTER, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing CLK_MULTI_REGISTER failed status-0x%x\n", status);
|
||||
goto error;
|
||||
} else
|
||||
dev_dbg(&dev->dev, "ZLP_REG5 Writing success status%d\n", status);
|
||||
dev_dbg(&port->dev, "CLK_MULTI_REGISTER Writing success status%d\n", status);
|
||||
|
||||
/* setting configuration feature to one */
|
||||
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||
(__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT);
|
||||
/* write value 0x0 to scratchpad register */
|
||||
Data = 0x00;
|
||||
status = mos7840_set_uart_reg(port, SCRATCH_PAD_REGISTER, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing SCRATCH_PAD_REGISTER failed status-0x%x\n", status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "SCRATCH_PAD_REGISTER Writing success status%d\n", status);
|
||||
|
||||
/* Zero Length flag register */
|
||||
if ((mos7840_port->port_num != 1) && (serial->num_ports == 2)) {
|
||||
Data = 0xff;
|
||||
status = mos7840_set_reg_sync(port,
|
||||
(__u16) (ZLP_REG1 +
|
||||
((__u16)mos7840_port->port_num)), Data);
|
||||
dev_dbg(&port->dev, "ZLIP offset %x\n",
|
||||
(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num)));
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 2, status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 2, status);
|
||||
} else {
|
||||
Data = 0xff;
|
||||
status = mos7840_set_reg_sync(port,
|
||||
(__u16) (ZLP_REG1 +
|
||||
((__u16)mos7840_port->port_num) - 0x1), Data);
|
||||
dev_dbg(&port->dev, "ZLIP offset %x\n",
|
||||
(__u16)(ZLP_REG1 + ((__u16) mos7840_port->port_num) - 0x1));
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing ZLP_REG%d failed status-0x%x\n", pnum + 1, status);
|
||||
goto out;
|
||||
} else
|
||||
dev_dbg(&port->dev, "ZLP_REG%d Writing success status%d\n", pnum + 1, status);
|
||||
|
||||
}
|
||||
mos7840_port->control_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
mos7840_port->ctrl_buf = kmalloc(16, GFP_KERNEL);
|
||||
mos7840_port->dr = kmalloc(sizeof(struct usb_ctrlrequest),
|
||||
GFP_KERNEL);
|
||||
if (!mos7840_port->control_urb || !mos7840_port->ctrl_buf ||
|
||||
!mos7840_port->dr) {
|
||||
status = -ENOMEM;
|
||||
goto error;
|
||||
}
|
||||
|
||||
mos7840_port->has_led = false;
|
||||
|
||||
/* Initialize LED timers */
|
||||
if (device_type == MOSCHIP_DEVICE_ID_7810) {
|
||||
mos7840_port->has_led = true;
|
||||
|
||||
init_timer(&mos7840_port->led_timer1);
|
||||
mos7840_port->led_timer1.function = mos7840_led_off;
|
||||
mos7840_port->led_timer1.expires =
|
||||
jiffies + msecs_to_jiffies(LED_ON_MS);
|
||||
mos7840_port->led_timer1.data = (unsigned long)mos7840_port;
|
||||
|
||||
init_timer(&mos7840_port->led_timer2);
|
||||
mos7840_port->led_timer2.function = mos7840_led_flag_off;
|
||||
mos7840_port->led_timer2.expires =
|
||||
jiffies + msecs_to_jiffies(LED_OFF_MS);
|
||||
mos7840_port->led_timer2.data = (unsigned long)mos7840_port;
|
||||
|
||||
mos7840_port->led_flag = false;
|
||||
|
||||
/* Turn off LED */
|
||||
mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
|
||||
}
|
||||
out:
|
||||
if (pnum == serial->num_ports - 1) {
|
||||
/* Zero Length flag enable */
|
||||
Data = 0x0f;
|
||||
status = mos7840_set_reg_sync(serial->port[0], ZLP_REG5, Data);
|
||||
if (status < 0) {
|
||||
dev_dbg(&port->dev, "Writing ZLP_REG5 failed status-0x%x\n", status);
|
||||
goto error;
|
||||
} else
|
||||
dev_dbg(&port->dev, "ZLP_REG5 Writing success status%d\n", status);
|
||||
|
||||
/* setting configuration feature to one */
|
||||
usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0),
|
||||
0x03, 0x00, 0x01, 0x00, NULL, 0x00,
|
||||
MOS_WDR_TIMEOUT);
|
||||
}
|
||||
return 0;
|
||||
error:
|
||||
for (/* nothing */; i >= 0; i--) {
|
||||
mos7840_port = mos7840_get_port_private(serial->port[i]);
|
||||
kfree(mos7840_port->dr);
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
usb_free_urb(mos7840_port->control_urb);
|
||||
kfree(mos7840_port);
|
||||
|
||||
kfree(mos7840_port->dr);
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
usb_free_urb(mos7840_port->control_urb);
|
||||
kfree(mos7840_port);
|
||||
serial->port[i] = NULL;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* mos7840_disconnect
|
||||
* This function is called whenever the device is removed from the usb bus.
|
||||
****************************************************************************/
|
||||
|
||||
static void mos7840_disconnect(struct usb_serial *serial)
|
||||
static int mos7840_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
int i;
|
||||
unsigned long flags;
|
||||
struct moschip_port *mos7840_port;
|
||||
|
||||
/* check for the ports to be closed,close the ports and disconnect */
|
||||
mos7840_port = mos7840_get_port_private(port);
|
||||
|
||||
/* free private structure allocated for serial port *
|
||||
* stop reads and writes on all ports */
|
||||
if (mos7840_port->has_led) {
|
||||
/* Turn off LED */
|
||||
mos7840_set_led_sync(port, MODEM_CONTROL_REGISTER, 0x0300);
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
mos7840_port = mos7840_get_port_private(serial->port[i]);
|
||||
if (mos7840_port) {
|
||||
spin_lock_irqsave(&mos7840_port->pool_lock, flags);
|
||||
mos7840_port->zombie = 1;
|
||||
spin_unlock_irqrestore(&mos7840_port->pool_lock, flags);
|
||||
usb_kill_urb(mos7840_port->control_urb);
|
||||
}
|
||||
del_timer_sync(&mos7840_port->led_timer1);
|
||||
del_timer_sync(&mos7840_port->led_timer2);
|
||||
}
|
||||
}
|
||||
usb_kill_urb(mos7840_port->control_urb);
|
||||
usb_free_urb(mos7840_port->control_urb);
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
kfree(mos7840_port->dr);
|
||||
kfree(mos7840_port);
|
||||
|
||||
/****************************************************************************
|
||||
* mos7840_release
|
||||
* This function is called when the usb_serial structure is freed.
|
||||
****************************************************************************/
|
||||
|
||||
static void mos7840_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct moschip_port *mos7840_port;
|
||||
|
||||
/* check for the ports to be closed,close the ports and disconnect */
|
||||
|
||||
/* free private structure allocated for serial port *
|
||||
* stop reads and writes on all ports */
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
mos7840_port = mos7840_get_port_private(serial->port[i]);
|
||||
if (mos7840_port) {
|
||||
if (mos7840_port->has_led) {
|
||||
/* Turn off LED */
|
||||
mos7840_set_led_sync(mos7840_port->port,
|
||||
MODEM_CONTROL_REGISTER, 0x0300);
|
||||
|
||||
del_timer_sync(&mos7840_port->led_timer1);
|
||||
del_timer_sync(&mos7840_port->led_timer2);
|
||||
}
|
||||
kfree(mos7840_port->ctrl_buf);
|
||||
kfree(mos7840_port->dr);
|
||||
kfree(mos7840_port);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct usb_serial_driver moschip7840_4port_device = {
|
||||
|
|
@ -2677,9 +2597,8 @@ static struct usb_serial_driver moschip7840_4port_device = {
|
|||
.tiocmget = mos7840_tiocmget,
|
||||
.tiocmset = mos7840_tiocmset,
|
||||
.get_icount = mos7840_get_icount,
|
||||
.attach = mos7840_startup,
|
||||
.disconnect = mos7840_disconnect,
|
||||
.release = mos7840_release,
|
||||
.port_probe = mos7840_port_probe,
|
||||
.port_remove = mos7840_port_remove,
|
||||
.read_bulk_callback = mos7840_bulk_in_callback,
|
||||
.read_int_callback = mos7840_interrupt_callback,
|
||||
};
|
||||
|
|
|
|||
|
|
@ -44,8 +44,8 @@ static int omninet_write(struct tty_struct *tty, struct usb_serial_port *port,
|
|||
const unsigned char *buf, int count);
|
||||
static int omninet_write_room(struct tty_struct *tty);
|
||||
static void omninet_disconnect(struct usb_serial *serial);
|
||||
static void omninet_release(struct usb_serial *serial);
|
||||
static int omninet_attach(struct usb_serial *serial);
|
||||
static int omninet_port_probe(struct usb_serial_port *port);
|
||||
static int omninet_port_remove(struct usb_serial_port *port);
|
||||
|
||||
static const struct usb_device_id id_table[] = {
|
||||
{ USB_DEVICE(ZYXEL_VENDOR_ID, ZYXEL_OMNINET_ID) },
|
||||
|
|
@ -62,7 +62,8 @@ static struct usb_serial_driver zyxel_omninet_device = {
|
|||
.description = "ZyXEL - omni.net lcd plus usb",
|
||||
.id_table = id_table,
|
||||
.num_ports = 1,
|
||||
.attach = omninet_attach,
|
||||
.port_probe = omninet_port_probe,
|
||||
.port_remove = omninet_port_remove,
|
||||
.open = omninet_open,
|
||||
.close = omninet_close,
|
||||
.write = omninet_write,
|
||||
|
|
@ -70,7 +71,6 @@ static struct usb_serial_driver zyxel_omninet_device = {
|
|||
.read_bulk_callback = omninet_read_bulk_callback,
|
||||
.write_bulk_callback = omninet_write_bulk_callback,
|
||||
.disconnect = omninet_disconnect,
|
||||
.release = omninet_release,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
@ -112,18 +112,26 @@ struct omninet_data {
|
|||
__u8 od_outseq; /* Sequence number for bulk_out URBs */
|
||||
};
|
||||
|
||||
static int omninet_attach(struct usb_serial *serial)
|
||||
static int omninet_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct omninet_data *od;
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
|
||||
od = kmalloc(sizeof(struct omninet_data), GFP_KERNEL);
|
||||
if (!od) {
|
||||
dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n",
|
||||
__func__, sizeof(struct omninet_data));
|
||||
if (!od)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
usb_set_serial_port_data(port, od);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int omninet_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct omninet_data *od;
|
||||
|
||||
od = usb_get_serial_port_data(port);
|
||||
kfree(od);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -279,14 +287,6 @@ static void omninet_disconnect(struct usb_serial *serial)
|
|||
usb_kill_urb(wport->write_urb);
|
||||
}
|
||||
|
||||
|
||||
static void omninet_release(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
|
||||
kfree(usb_get_serial_port_data(port));
|
||||
}
|
||||
|
||||
module_usb_serial_driver(serial_drivers, id_table);
|
||||
|
||||
MODULE_AUTHOR(DRIVER_AUTHOR);
|
||||
|
|
|
|||
|
|
@ -155,7 +155,11 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
|
|||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
int retval;
|
||||
u8 buffer[2];
|
||||
u8 *buffer;
|
||||
|
||||
buffer = kzalloc(1, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
return -ENOMEM;
|
||||
|
||||
buffer[0] = val;
|
||||
/* Send the message to the vendor control endpoint
|
||||
|
|
@ -164,6 +168,7 @@ static int send_control_msg(struct usb_serial_port *port, u8 requesttype,
|
|||
requesttype,
|
||||
USB_DIR_OUT|USB_TYPE_VENDOR|USB_RECIP_INTERFACE,
|
||||
0, 0, buffer, 1, 0);
|
||||
kfree(buffer);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
|
@ -281,7 +286,7 @@ static int opticon_write(struct tty_struct *tty, struct usb_serial_port *port,
|
|||
if (!dr) {
|
||||
dev_err(&port->dev, "out of memory\n");
|
||||
count = -ENOMEM;
|
||||
goto error;
|
||||
goto error_no_dr;
|
||||
}
|
||||
|
||||
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,
|
|||
|
||||
return count;
|
||||
error:
|
||||
kfree(dr);
|
||||
error_no_dr:
|
||||
usb_free_urb(urb);
|
||||
error_no_urb:
|
||||
kfree(buffer);
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@
|
|||
/* Function prototypes */
|
||||
static int option_probe(struct usb_serial *serial,
|
||||
const struct usb_device_id *id);
|
||||
static int option_attach(struct usb_serial *serial);
|
||||
static void option_release(struct usb_serial *serial);
|
||||
static int option_send_setup(struct usb_serial_port *port);
|
||||
static void option_instat_callback(struct urb *urb);
|
||||
|
|
@ -157,6 +158,7 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define NOVATELWIRELESS_PRODUCT_EVDO_EMBEDDED_HIGHSPEED 0x8001
|
||||
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_FULLSPEED 0x9000
|
||||
#define NOVATELWIRELESS_PRODUCT_HSPA_EMBEDDED_HIGHSPEED 0x9001
|
||||
#define NOVATELWIRELESS_PRODUCT_E362 0x9010
|
||||
#define NOVATELWIRELESS_PRODUCT_G1 0xA001
|
||||
#define NOVATELWIRELESS_PRODUCT_G1_M 0xA002
|
||||
#define NOVATELWIRELESS_PRODUCT_G2 0xA010
|
||||
|
|
@ -192,6 +194,9 @@ static void option_instat_callback(struct urb *urb);
|
|||
#define DELL_PRODUCT_5730_MINICARD_TELUS 0x8181
|
||||
#define DELL_PRODUCT_5730_MINICARD_VZW 0x8182
|
||||
|
||||
#define DELL_PRODUCT_5800_MINICARD_VZW 0x8195 /* Novatel E362 */
|
||||
#define DELL_PRODUCT_5800_V2_MINICARD_VZW 0x8196 /* Novatel E362 */
|
||||
|
||||
#define KYOCERA_VENDOR_ID 0x0c88
|
||||
#define KYOCERA_PRODUCT_KPC650 0x17da
|
||||
#define KYOCERA_PRODUCT_KPC680 0x180a
|
||||
|
|
@ -282,6 +287,7 @@ static void option_instat_callback(struct urb *urb);
|
|||
/* ALCATEL PRODUCTS */
|
||||
#define ALCATEL_VENDOR_ID 0x1bbb
|
||||
#define ALCATEL_PRODUCT_X060S_X200 0x0000
|
||||
#define ALCATEL_PRODUCT_X220_X500D 0x0017
|
||||
|
||||
#define PIRELLI_VENDOR_ID 0x1266
|
||||
#define PIRELLI_PRODUCT_C100_1 0x1002
|
||||
|
|
@ -503,11 +509,19 @@ static const struct option_blacklist_info net_intf5_blacklist = {
|
|||
.reserved = BIT(5),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info net_intf6_blacklist = {
|
||||
.reserved = BIT(6),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_mf626_blacklist = {
|
||||
.sendsetup = BIT(0) | BIT(1),
|
||||
.reserved = BIT(4),
|
||||
};
|
||||
|
||||
static const struct option_blacklist_info zte_1255_blacklist = {
|
||||
.reserved = BIT(3) | BIT(4),
|
||||
};
|
||||
|
||||
static const struct usb_device_id option_ids[] = {
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
|
||||
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
|
||||
|
|
@ -697,6 +711,7 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_G2) },
|
||||
/* Novatel Ovation MC551 a.k.a. Verizon USB551L */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_MC551, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_E362, 0xff, 0xff, 0xff) },
|
||||
|
||||
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01) },
|
||||
{ USB_DEVICE(AMOI_VENDOR_ID, AMOI_PRODUCT_H01A) },
|
||||
|
|
@ -719,6 +734,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_SPRINT) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
|
||||
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_TELUS) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
|
||||
{ USB_DEVICE(DELL_VENDOR_ID, DELL_PRODUCT_5730_MINICARD_VZW) }, /* Dell Wireless 5730 Mobile Broadband EVDO/HSPA Mini-Card */
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_MINICARD_VZW, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(DELL_VENDOR_ID, DELL_PRODUCT_5800_V2_MINICARD_VZW, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_E100A) }, /* ADU-E100, ADU-310 */
|
||||
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_500A) },
|
||||
{ USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ADU_620UW) },
|
||||
|
|
@ -853,13 +870,19 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0117, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0121, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0122, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf6_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0126, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0128, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
|
||||
|
|
@ -872,7 +895,8 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0156, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0158, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0159, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
|
||||
|
|
@ -880,13 +904,22 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0165, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0191, 0xff, 0xff, 0xff), /* ZTE EuFi890 */
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0199, 0xff, 0xff, 0xff), /* ZTE MF820S */
|
||||
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0257, 0xff, 0xff, 0xff), /* ZTE MF821 */
|
||||
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1021, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) },
|
||||
|
|
@ -1002,18 +1035,24 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1169, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1244, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1245, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1246, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1247, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1248, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1250, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1252, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1253, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1255, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&zte_1255_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1257, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) },
|
||||
|
|
@ -1058,8 +1097,16 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1298, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1300, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1401, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1424, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1425, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1426, 0xff, 0xff, 0xff), /* ZTE MF91 */
|
||||
.driver_info = (kernel_ulong_t)&net_intf2_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
|
||||
0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
|
||||
|
|
@ -1071,15 +1118,21 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0070, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0094, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf1_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0133, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf5_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0147, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0168, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf4_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0170, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0178, 0xff, 0xff, 0xff),
|
||||
.driver_info = (kernel_ulong_t)&net_intf3_blacklist },
|
||||
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_CDMA_TECH, 0xff, 0xff, 0xff) },
|
||||
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
|
||||
|
|
@ -1112,6 +1165,7 @@ static const struct usb_device_id option_ids[] = {
|
|||
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X060S_X200),
|
||||
.driver_info = (kernel_ulong_t)&alcatel_x200_blacklist
|
||||
},
|
||||
{ USB_DEVICE(ALCATEL_VENDOR_ID, ALCATEL_PRODUCT_X220_X500D) },
|
||||
{ USB_DEVICE(AIRPLUS_VENDOR_ID, AIRPLUS_PRODUCT_MCD650) },
|
||||
{ USB_DEVICE(TLAYTECH_VENDOR_ID, TLAYTECH_PRODUCT_TEU800) },
|
||||
{ USB_DEVICE(LONGCHEER_VENDOR_ID, FOUR_G_SYSTEMS_PRODUCT_W14),
|
||||
|
|
@ -1244,8 +1298,9 @@ static struct usb_serial_driver option_1port_device = {
|
|||
.tiocmget = usb_wwan_tiocmget,
|
||||
.tiocmset = usb_wwan_tiocmset,
|
||||
.ioctl = usb_wwan_ioctl,
|
||||
.attach = usb_wwan_startup,
|
||||
.attach = option_attach,
|
||||
.release = option_release,
|
||||
.port_probe = usb_wwan_port_probe,
|
||||
.port_remove = usb_wwan_port_remove,
|
||||
.read_int_callback = option_instat_callback,
|
||||
#ifdef CONFIG_PM
|
||||
|
|
@ -1291,8 +1346,6 @@ static bool is_blacklisted(const u8 ifnum, enum option_blacklist_reason reason,
|
|||
static int option_probe(struct usb_serial *serial,
|
||||
const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_wwan_intf_private *data;
|
||||
struct option_private *priv;
|
||||
struct usb_interface_descriptor *iface_desc =
|
||||
&serial->interface->cur_altsetting->desc;
|
||||
struct usb_device_descriptor *dev_desc = &serial->dev->descriptor;
|
||||
|
|
@ -1330,6 +1383,19 @@ static int option_probe(struct usb_serial *serial,
|
|||
iface_desc->bInterfaceClass != USB_CLASS_CDC_DATA)
|
||||
return -ENODEV;
|
||||
|
||||
/* Store device id so we can use it during attach. */
|
||||
usb_set_serial_data(serial, (void *)id);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int option_attach(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_interface_descriptor *iface_desc;
|
||||
const struct usb_device_id *id;
|
||||
struct usb_wwan_intf_private *data;
|
||||
struct option_private *priv;
|
||||
|
||||
data = kzalloc(sizeof(struct usb_wwan_intf_private), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
|
@ -1340,6 +1406,10 @@ static int option_probe(struct usb_serial *serial,
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Retrieve device id stored at probe. */
|
||||
id = usb_get_serial_data(serial);
|
||||
iface_desc = &serial->interface->cur_altsetting->desc;
|
||||
|
||||
priv->bInterfaceNumber = iface_desc->bInterfaceNumber;
|
||||
data->private = priv;
|
||||
|
||||
|
|
|
|||
|
|
@ -137,8 +137,8 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty);
|
|||
static int oti6858_tiocmget(struct tty_struct *tty);
|
||||
static int oti6858_tiocmset(struct tty_struct *tty,
|
||||
unsigned int set, unsigned int clear);
|
||||
static int oti6858_startup(struct usb_serial *serial);
|
||||
static void oti6858_release(struct usb_serial *serial);
|
||||
static int oti6858_port_probe(struct usb_serial_port *port);
|
||||
static int oti6858_port_remove(struct usb_serial_port *port);
|
||||
|
||||
/* device info */
|
||||
static struct usb_serial_driver oti6858_device = {
|
||||
|
|
@ -161,8 +161,8 @@ static struct usb_serial_driver oti6858_device = {
|
|||
.write_bulk_callback = oti6858_write_bulk_callback,
|
||||
.write_room = oti6858_write_room,
|
||||
.chars_in_buffer = oti6858_chars_in_buffer,
|
||||
.attach = oti6858_startup,
|
||||
.release = oti6858_release,
|
||||
.port_probe = oti6858_port_probe,
|
||||
.port_remove = oti6858_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
@ -331,36 +331,33 @@ static void send_data(struct work_struct *work)
|
|||
usb_serial_port_softint(port);
|
||||
}
|
||||
|
||||
static int oti6858_startup(struct usb_serial *serial)
|
||||
static int oti6858_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial_port *port = serial->port[0];
|
||||
struct oti6858_private *priv;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
break;
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->intr_wait);
|
||||
/* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
|
||||
/* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
|
||||
priv->port = port;
|
||||
INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
|
||||
INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->intr_wait);
|
||||
priv->port = port;
|
||||
INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
|
||||
INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
|
||||
|
||||
usb_set_serial_port_data(serial->port[i], priv);
|
||||
}
|
||||
if (i == serial->num_ports)
|
||||
return 0;
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
for (--i; i >= 0; --i) {
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
}
|
||||
return -ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oti6858_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct oti6858_private *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
|
|
@ -709,15 +706,6 @@ static int oti6858_ioctl(struct tty_struct *tty,
|
|||
return -ENOIOCTLCMD;
|
||||
}
|
||||
|
||||
|
||||
static void oti6858_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
}
|
||||
|
||||
static void oti6858_read_int_callback(struct urb *urb)
|
||||
{
|
||||
struct usb_serial_port *port = urb->context;
|
||||
|
|
|
|||
|
|
@ -133,12 +133,15 @@ enum pl2303_type {
|
|||
HX, /* HX version of the pl2303 chip */
|
||||
};
|
||||
|
||||
struct pl2303_serial_private {
|
||||
enum pl2303_type type;
|
||||
};
|
||||
|
||||
struct pl2303_private {
|
||||
spinlock_t lock;
|
||||
wait_queue_head_t delta_msr_wait;
|
||||
u8 line_control;
|
||||
u8 line_status;
|
||||
enum pl2303_type type;
|
||||
};
|
||||
|
||||
static int pl2303_vendor_read(__u16 value, __u16 index,
|
||||
|
|
@ -167,14 +170,19 @@ static int pl2303_vendor_write(__u16 value, __u16 index,
|
|||
|
||||
static int pl2303_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct pl2303_private *priv;
|
||||
struct pl2303_serial_private *spriv;
|
||||
enum pl2303_type type = type_0;
|
||||
unsigned char *buf;
|
||||
int i;
|
||||
|
||||
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
|
||||
if (!spriv)
|
||||
return -ENOMEM;
|
||||
|
||||
buf = kmalloc(10, GFP_KERNEL);
|
||||
if (buf == NULL)
|
||||
if (!buf) {
|
||||
kfree(spriv);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (serial->dev->descriptor.bDeviceClass == 0x02)
|
||||
type = type_0;
|
||||
|
|
@ -186,15 +194,8 @@ static int pl2303_startup(struct usb_serial *serial)
|
|||
type = type_1;
|
||||
dev_dbg(&serial->interface->dev, "device type: %d\n", type);
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
goto cleanup;
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
priv->type = type;
|
||||
usb_set_serial_port_data(serial->port[i], priv);
|
||||
}
|
||||
spriv->type = type;
|
||||
usb_set_serial_data(serial, spriv);
|
||||
|
||||
pl2303_vendor_read(0x8484, 0, serial, buf);
|
||||
pl2303_vendor_write(0x0404, 0, serial);
|
||||
|
|
@ -213,15 +214,40 @@ static int pl2303_startup(struct usb_serial *serial)
|
|||
|
||||
kfree(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
cleanup:
|
||||
kfree(buf);
|
||||
for (--i; i >= 0; --i) {
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
}
|
||||
return -ENOMEM;
|
||||
static void pl2303_release(struct usb_serial *serial)
|
||||
{
|
||||
struct pl2303_serial_private *spriv;
|
||||
|
||||
spriv = usb_get_serial_data(serial);
|
||||
kfree(spriv);
|
||||
}
|
||||
|
||||
static int pl2303_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct pl2303_private *priv;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pl2303_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct pl2303_private *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_control_lines(struct usb_device *dev, u8 value)
|
||||
|
|
@ -240,6 +266,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
|
|||
struct usb_serial_port *port, struct ktermios *old_termios)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
|
||||
struct pl2303_private *priv = usb_get_serial_port_data(port);
|
||||
unsigned long flags;
|
||||
unsigned int cflag;
|
||||
|
|
@ -323,7 +350,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
|
|||
}
|
||||
if (baud > 1228800) {
|
||||
/* type_0, type_1 only support up to 1228800 baud */
|
||||
if (priv->type != HX)
|
||||
if (spriv->type != HX)
|
||||
baud = 1228800;
|
||||
else if (baud > 6000000)
|
||||
baud = 6000000;
|
||||
|
|
@ -426,7 +453,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
|
|||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
|
||||
|
||||
if (cflag & CRTSCTS) {
|
||||
if (priv->type == HX)
|
||||
if (spriv->type == HX)
|
||||
pl2303_vendor_write(0x0, 0x61, serial);
|
||||
else
|
||||
pl2303_vendor_write(0x0, 0x41, serial);
|
||||
|
|
@ -468,10 +495,10 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
|
|||
{
|
||||
struct ktermios tmp_termios;
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct pl2303_private *priv = usb_get_serial_port_data(port);
|
||||
struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
|
||||
int result;
|
||||
|
||||
if (priv->type != HX) {
|
||||
if (spriv->type != HX) {
|
||||
usb_clear_halt(serial->dev, port->write_urb->pipe);
|
||||
usb_clear_halt(serial->dev, port->read_urb->pipe);
|
||||
} else {
|
||||
|
|
@ -655,17 +682,6 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
|
|||
dev_err(&port->dev, "error sending break = %d\n", result);
|
||||
}
|
||||
|
||||
static void pl2303_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct pl2303_private *priv;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
}
|
||||
}
|
||||
|
||||
static void pl2303_update_line_status(struct usb_serial_port *port,
|
||||
unsigned char *data,
|
||||
unsigned int actual_length)
|
||||
|
|
@ -827,6 +843,8 @@ static struct usb_serial_driver pl2303_device = {
|
|||
.read_int_callback = pl2303_read_int_callback,
|
||||
.attach = pl2303_startup,
|
||||
.release = pl2303_release,
|
||||
.port_probe = pl2303_port_probe,
|
||||
.port_remove = pl2303_port_remove,
|
||||
};
|
||||
|
||||
static struct usb_serial_driver * const serial_drivers[] = {
|
||||
|
|
|
|||
|
|
@ -138,7 +138,6 @@ MODULE_DEVICE_TABLE(usb, id_table);
|
|||
|
||||
static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
|
||||
{
|
||||
struct usb_wwan_intf_private *data;
|
||||
struct usb_host_interface *intf = serial->interface->cur_altsetting;
|
||||
struct device *dev = &serial->dev->dev;
|
||||
int retval = -ENODEV;
|
||||
|
|
@ -154,13 +153,6 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id)
|
|||
ifnum = intf->desc.bInterfaceNumber;
|
||||
dev_dbg(dev, "This Interface = %d\n", ifnum);
|
||||
|
||||
data = kzalloc(sizeof(struct usb_wwan_intf_private),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&data->susp_lock);
|
||||
|
||||
if (nintf == 1) {
|
||||
/* QDL mode */
|
||||
/* Gobi 2000 has a single altsetting, older ones have two */
|
||||
|
|
@ -253,20 +245,28 @@ done:
|
|||
}
|
||||
}
|
||||
|
||||
/* Set serial->private if not returning error */
|
||||
if (retval == 0)
|
||||
usb_set_serial_data(serial, data);
|
||||
else
|
||||
kfree(data);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int qc_attach(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_wwan_intf_private *data;
|
||||
|
||||
data = kzalloc(sizeof(*data), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&data->susp_lock);
|
||||
|
||||
usb_set_serial_data(serial, data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void qc_release(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_wwan_intf_private *priv = usb_get_serial_data(serial);
|
||||
|
||||
/* Free the private data allocated in qcprobe */
|
||||
usb_set_serial_data(serial, NULL);
|
||||
kfree(priv);
|
||||
}
|
||||
|
|
@ -285,8 +285,9 @@ static struct usb_serial_driver qcdevice = {
|
|||
.write = usb_wwan_write,
|
||||
.write_room = usb_wwan_write_room,
|
||||
.chars_in_buffer = usb_wwan_chars_in_buffer,
|
||||
.attach = usb_wwan_startup,
|
||||
.attach = qc_attach,
|
||||
.release = qc_release,
|
||||
.port_probe = usb_wwan_port_probe,
|
||||
.port_remove = usb_wwan_port_remove,
|
||||
#ifdef CONFIG_PM
|
||||
.suspend = usb_wwan_suspend,
|
||||
|
|
|
|||
|
|
@ -143,12 +143,12 @@ static void qt2_read_bulk_callback(struct urb *urb);
|
|||
|
||||
static void qt2_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct qt2_serial_private *serial_priv;
|
||||
|
||||
kfree(usb_get_serial_data(serial));
|
||||
serial_priv = usb_get_serial_data(serial);
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
usb_free_urb(serial_priv->read_urb);
|
||||
kfree(serial_priv);
|
||||
}
|
||||
|
||||
static inline int calc_baud_divisor(int baudrate)
|
||||
|
|
@ -423,11 +423,16 @@ static void qt2_close(struct usb_serial_port *port)
|
|||
port_priv->is_open = false;
|
||||
|
||||
spin_lock_irqsave(&port_priv->urb_lock, flags);
|
||||
if (port_priv->write_urb->status == -EINPROGRESS)
|
||||
usb_kill_urb(port_priv->write_urb);
|
||||
usb_kill_urb(port_priv->write_urb);
|
||||
port_priv->urb_in_use = false;
|
||||
spin_unlock_irqrestore(&port_priv->urb_lock, flags);
|
||||
|
||||
mutex_lock(&port->serial->disc_mutex);
|
||||
if (port->serial->disconnected) {
|
||||
mutex_unlock(&port->serial->disc_mutex);
|
||||
return;
|
||||
}
|
||||
|
||||
/* flush the port transmit buffer */
|
||||
i = usb_control_msg(serial->dev,
|
||||
usb_rcvctrlpipe(serial->dev, 0),
|
||||
|
|
@ -459,26 +464,14 @@ static void qt2_close(struct usb_serial_port *port)
|
|||
dev_err(&port->dev, "%s - close port failed %i\n",
|
||||
__func__, i);
|
||||
|
||||
mutex_unlock(&port->serial->disc_mutex);
|
||||
}
|
||||
|
||||
static void qt2_disconnect(struct usb_serial *serial)
|
||||
{
|
||||
struct qt2_serial_private *serial_priv = usb_get_serial_data(serial);
|
||||
struct qt2_port_private *port_priv;
|
||||
int i;
|
||||
|
||||
if (serial_priv->read_urb->status == -EINPROGRESS)
|
||||
usb_kill_urb(serial_priv->read_urb);
|
||||
|
||||
usb_free_urb(serial_priv->read_urb);
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port_priv = usb_get_serial_port_data(serial->port[i]);
|
||||
|
||||
if (port_priv->write_urb->status == -EINPROGRESS)
|
||||
usb_kill_urb(port_priv->write_urb);
|
||||
usb_free_urb(port_priv->write_urb);
|
||||
}
|
||||
usb_kill_urb(serial_priv->read_urb);
|
||||
}
|
||||
|
||||
static int get_serial_info(struct usb_serial_port *port,
|
||||
|
|
@ -773,11 +766,9 @@ static void qt2_read_bulk_callback(struct urb *urb)
|
|||
|
||||
static int qt2_setup_urbs(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *port;
|
||||
struct usb_serial_port *port0;
|
||||
struct qt2_serial_private *serial_priv;
|
||||
struct qt2_port_private *port_priv;
|
||||
int pcount, status;
|
||||
int status;
|
||||
|
||||
port0 = serial->port[0];
|
||||
|
||||
|
|
@ -795,46 +786,21 @@ static int qt2_setup_urbs(struct usb_serial *serial)
|
|||
sizeof(serial_priv->read_buffer),
|
||||
qt2_read_bulk_callback, serial);
|
||||
|
||||
/* setup write_urb for each port */
|
||||
for (pcount = 0; pcount < serial->num_ports; pcount++) {
|
||||
|
||||
port = serial->port[pcount];
|
||||
port_priv = usb_get_serial_port_data(port);
|
||||
|
||||
port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!port_priv->write_urb) {
|
||||
dev_err(&serial->dev->dev,
|
||||
"failed to alloc write_urb for port %i\n",
|
||||
pcount);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
usb_fill_bulk_urb(port_priv->write_urb,
|
||||
serial->dev,
|
||||
usb_sndbulkpipe(serial->dev,
|
||||
port0->
|
||||
bulk_out_endpointAddress),
|
||||
port_priv->write_buffer,
|
||||
sizeof(port_priv->write_buffer),
|
||||
qt2_write_bulk_callback, port);
|
||||
}
|
||||
|
||||
status = usb_submit_urb(serial_priv->read_urb, GFP_KERNEL);
|
||||
if (status != 0) {
|
||||
dev_err(&serial->dev->dev,
|
||||
"%s - submit read urb failed %i\n", __func__, status);
|
||||
usb_free_urb(serial_priv->read_urb);
|
||||
return status;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
static int qt2_attach(struct usb_serial *serial)
|
||||
{
|
||||
struct qt2_serial_private *serial_priv;
|
||||
struct qt2_port_private *port_priv;
|
||||
int status, pcount;
|
||||
int status;
|
||||
|
||||
/* power on unit */
|
||||
status = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
|
||||
|
|
@ -854,26 +820,6 @@ static int qt2_attach(struct usb_serial *serial)
|
|||
|
||||
usb_set_serial_data(serial, serial_priv);
|
||||
|
||||
for (pcount = 0; pcount < serial->num_ports; pcount++) {
|
||||
port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
|
||||
if (!port_priv) {
|
||||
dev_err(&serial->dev->dev,
|
||||
"%s- kmalloc(%Zd) failed.\n", __func__,
|
||||
sizeof(*port_priv));
|
||||
pcount--;
|
||||
status = -ENOMEM;
|
||||
goto attach_failed;
|
||||
}
|
||||
|
||||
spin_lock_init(&port_priv->lock);
|
||||
spin_lock_init(&port_priv->urb_lock);
|
||||
init_waitqueue_head(&port_priv->delta_msr_wait);
|
||||
|
||||
port_priv->port = serial->port[pcount];
|
||||
|
||||
usb_set_serial_port_data(serial->port[pcount], port_priv);
|
||||
}
|
||||
|
||||
status = qt2_setup_urbs(serial);
|
||||
if (status != 0)
|
||||
goto attach_failed;
|
||||
|
|
@ -881,14 +827,53 @@ static int qt2_attach(struct usb_serial *serial)
|
|||
return 0;
|
||||
|
||||
attach_failed:
|
||||
for (/* empty */; pcount >= 0; pcount--) {
|
||||
port_priv = usb_get_serial_port_data(serial->port[pcount]);
|
||||
kfree(port_priv);
|
||||
}
|
||||
kfree(serial_priv);
|
||||
return status;
|
||||
}
|
||||
|
||||
static int qt2_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct qt2_port_private *port_priv;
|
||||
u8 bEndpointAddress;
|
||||
|
||||
port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
|
||||
if (!port_priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&port_priv->lock);
|
||||
spin_lock_init(&port_priv->urb_lock);
|
||||
init_waitqueue_head(&port_priv->delta_msr_wait);
|
||||
port_priv->port = port;
|
||||
|
||||
port_priv->write_urb = usb_alloc_urb(0, GFP_KERNEL);
|
||||
if (!port_priv->write_urb) {
|
||||
kfree(port_priv);
|
||||
return -ENOMEM;
|
||||
}
|
||||
bEndpointAddress = serial->port[0]->bulk_out_endpointAddress;
|
||||
usb_fill_bulk_urb(port_priv->write_urb, serial->dev,
|
||||
usb_sndbulkpipe(serial->dev, bEndpointAddress),
|
||||
port_priv->write_buffer,
|
||||
sizeof(port_priv->write_buffer),
|
||||
qt2_write_bulk_callback, port);
|
||||
|
||||
usb_set_serial_port_data(port, port_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qt2_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct qt2_port_private *port_priv;
|
||||
|
||||
port_priv = usb_get_serial_port_data(port);
|
||||
usb_free_urb(port_priv->write_urb);
|
||||
kfree(port_priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int qt2_tiocmget(struct tty_struct *tty)
|
||||
{
|
||||
struct usb_serial_port *port = tty->driver_data;
|
||||
|
|
@ -1127,6 +1112,8 @@ static struct usb_serial_driver qt2_device = {
|
|||
.attach = qt2_attach,
|
||||
.release = qt2_release,
|
||||
.disconnect = qt2_disconnect,
|
||||
.port_probe = qt2_port_probe,
|
||||
.port_remove = qt2_port_remove,
|
||||
.dtr_rts = qt2_dtr_rts,
|
||||
.break_ctl = qt2_break_ctl,
|
||||
.tiocmget = qt2_tiocmget,
|
||||
|
|
|
|||
|
|
@ -161,7 +161,6 @@ static int sierra_probe(struct usb_serial *serial,
|
|||
{
|
||||
int result = 0;
|
||||
struct usb_device *udev;
|
||||
struct sierra_intf_private *data;
|
||||
u8 ifnum;
|
||||
|
||||
udev = serial->dev;
|
||||
|
|
@ -188,11 +187,6 @@ static int sierra_probe(struct usb_serial *serial,
|
|||
return -ENODEV;
|
||||
}
|
||||
|
||||
data = serial->private = kzalloc(sizeof(struct sierra_intf_private), GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
spin_lock_init(&data->susp_lock);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
@ -884,11 +878,15 @@ static void sierra_dtr_rts(struct usb_serial_port *port, int on)
|
|||
|
||||
static int sierra_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *port;
|
||||
struct sierra_port_private *portdata;
|
||||
struct sierra_iface_info *himemoryp = NULL;
|
||||
int i;
|
||||
u8 ifnum;
|
||||
struct sierra_intf_private *intfdata;
|
||||
|
||||
intfdata = kzalloc(sizeof(*intfdata), GFP_KERNEL);
|
||||
if (!intfdata)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&intfdata->susp_lock);
|
||||
|
||||
usb_set_serial_data(serial, intfdata);
|
||||
|
||||
/* Set Device mode to D0 */
|
||||
sierra_set_power_state(serial->dev, 0x0000);
|
||||
|
|
@ -897,68 +895,71 @@ static int sierra_startup(struct usb_serial *serial)
|
|||
if (nmea)
|
||||
sierra_vsc_set_nmea(serial->dev, 1);
|
||||
|
||||
/* Now setup per port private data */
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port = serial->port[i];
|
||||
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
|
||||
if (!portdata) {
|
||||
dev_dbg(&port->dev, "%s: kmalloc for "
|
||||
"sierra_port_private (%d) failed!\n",
|
||||
__func__, i);
|
||||
return -ENOMEM;
|
||||
}
|
||||
spin_lock_init(&portdata->lock);
|
||||
init_usb_anchor(&portdata->active);
|
||||
init_usb_anchor(&portdata->delayed);
|
||||
ifnum = i;
|
||||
/* Assume low memory requirements */
|
||||
portdata->num_out_urbs = N_OUT_URB;
|
||||
portdata->num_in_urbs = N_IN_URB;
|
||||
|
||||
/* Determine actual memory requirements */
|
||||
if (serial->num_ports == 1) {
|
||||
/* Get interface number for composite device */
|
||||
ifnum = sierra_calc_interface(serial);
|
||||
himemoryp =
|
||||
(struct sierra_iface_info *)&typeB_interface_list;
|
||||
if (is_himemory(ifnum, himemoryp)) {
|
||||
portdata->num_out_urbs = N_OUT_URB_HM;
|
||||
portdata->num_in_urbs = N_IN_URB_HM;
|
||||
}
|
||||
}
|
||||
else {
|
||||
himemoryp =
|
||||
(struct sierra_iface_info *)&typeA_interface_list;
|
||||
if (is_himemory(i, himemoryp)) {
|
||||
portdata->num_out_urbs = N_OUT_URB_HM;
|
||||
portdata->num_in_urbs = N_IN_URB_HM;
|
||||
}
|
||||
}
|
||||
dev_dbg(&serial->dev->dev,
|
||||
"Memory usage (urbs) interface #%d, in=%d, out=%d\n",
|
||||
ifnum,portdata->num_in_urbs, portdata->num_out_urbs );
|
||||
/* Set the port private data pointer */
|
||||
usb_set_serial_port_data(port, portdata);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sierra_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct usb_serial_port *port;
|
||||
struct sierra_intf_private *intfdata;
|
||||
|
||||
intfdata = usb_get_serial_data(serial);
|
||||
kfree(intfdata);
|
||||
}
|
||||
|
||||
static int sierra_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct sierra_port_private *portdata;
|
||||
const struct sierra_iface_info *himemoryp;
|
||||
u8 ifnum;
|
||||
|
||||
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
|
||||
if (!portdata)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&portdata->lock);
|
||||
init_usb_anchor(&portdata->active);
|
||||
init_usb_anchor(&portdata->delayed);
|
||||
|
||||
/* Assume low memory requirements */
|
||||
portdata->num_out_urbs = N_OUT_URB;
|
||||
portdata->num_in_urbs = N_IN_URB;
|
||||
|
||||
/* Determine actual memory requirements */
|
||||
if (serial->num_ports == 1) {
|
||||
/* Get interface number for composite device */
|
||||
ifnum = sierra_calc_interface(serial);
|
||||
himemoryp = &typeB_interface_list;
|
||||
} else {
|
||||
/* This is really the usb-serial port number of the interface
|
||||
* rather than the interface number.
|
||||
*/
|
||||
ifnum = port->number - serial->minor;
|
||||
himemoryp = &typeA_interface_list;
|
||||
}
|
||||
|
||||
if (is_himemory(ifnum, himemoryp)) {
|
||||
portdata->num_out_urbs = N_OUT_URB_HM;
|
||||
portdata->num_in_urbs = N_IN_URB_HM;
|
||||
}
|
||||
|
||||
dev_dbg(&port->dev,
|
||||
"Memory usage (urbs) interface #%d, in=%d, out=%d\n",
|
||||
ifnum, portdata->num_in_urbs, portdata->num_out_urbs);
|
||||
|
||||
usb_set_serial_port_data(port, portdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sierra_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct sierra_port_private *portdata;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
port = serial->port[i];
|
||||
if (!port)
|
||||
continue;
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
if (!portdata)
|
||||
continue;
|
||||
kfree(portdata);
|
||||
}
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
kfree(portdata);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
|
@ -1062,6 +1063,8 @@ static struct usb_serial_driver sierra_device = {
|
|||
.tiocmset = sierra_tiocmset,
|
||||
.attach = sierra_startup,
|
||||
.release = sierra_release,
|
||||
.port_probe = sierra_port_probe,
|
||||
.port_remove = sierra_port_remove,
|
||||
.suspend = sierra_suspend,
|
||||
.resume = sierra_resume,
|
||||
.read_int_callback = sierra_instat_callback,
|
||||
|
|
|
|||
|
|
@ -157,13 +157,10 @@ struct spcp8x5_private {
|
|||
u8 line_status;
|
||||
};
|
||||
|
||||
/* desc : when device plug in,this function would be called.
|
||||
* thanks to usb_serial subsystem,then do almost every things for us. And what
|
||||
* we should do just alloc the buffer */
|
||||
static int spcp8x5_startup(struct usb_serial *serial)
|
||||
static int spcp8x5_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct spcp8x5_private *priv;
|
||||
int i;
|
||||
enum spcp8x5_type type = SPCP825_007_TYPE;
|
||||
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
|
||||
|
||||
|
|
@ -180,34 +177,27 @@ static int spcp8x5_startup(struct usb_serial *serial)
|
|||
type = SPCP825_PHILIP_TYPE;
|
||||
dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type);
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL);
|
||||
if (!priv)
|
||||
goto cleanup;
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
priv->type = type;
|
||||
usb_set_serial_port_data(serial->port[i] , priv);
|
||||
}
|
||||
spin_lock_init(&priv->lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
priv->type = type;
|
||||
|
||||
usb_set_serial_port_data(port , priv);
|
||||
|
||||
return 0;
|
||||
cleanup:
|
||||
for (--i; i >= 0; --i) {
|
||||
priv = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(priv);
|
||||
usb_set_serial_port_data(serial->port[i] , NULL);
|
||||
}
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* call when the device plug out. free all the memory alloced by probe */
|
||||
static void spcp8x5_release(struct usb_serial *serial)
|
||||
static int spcp8x5_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
int i;
|
||||
struct spcp8x5_private *priv;
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++)
|
||||
kfree(usb_get_serial_port_data(serial->port[i]));
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* set the modem control line of the device.
|
||||
|
|
@ -649,8 +639,8 @@ static struct usb_serial_driver spcp8x5_device = {
|
|||
.ioctl = spcp8x5_ioctl,
|
||||
.tiocmget = spcp8x5_tiocmget,
|
||||
.tiocmset = spcp8x5_tiocmset,
|
||||
.attach = spcp8x5_startup,
|
||||
.release = spcp8x5_release,
|
||||
.port_probe = spcp8x5_port_probe,
|
||||
.port_remove = spcp8x5_port_remove,
|
||||
.process_read_urb = spcp8x5_process_read_urb,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -67,13 +67,6 @@ struct ssu100_port_private {
|
|||
struct async_icount icount;
|
||||
};
|
||||
|
||||
static void ssu100_release(struct usb_serial *serial)
|
||||
{
|
||||
struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port);
|
||||
|
||||
kfree(priv);
|
||||
}
|
||||
|
||||
static inline int ssu100_control_msg(struct usb_device *dev,
|
||||
u8 request, u16 data, u16 index)
|
||||
{
|
||||
|
|
@ -441,22 +434,34 @@ static int ssu100_ioctl(struct tty_struct *tty,
|
|||
}
|
||||
|
||||
static int ssu100_attach(struct usb_serial *serial)
|
||||
{
|
||||
return ssu100_initdevice(serial->dev);
|
||||
}
|
||||
|
||||
static int ssu100_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct ssu100_port_private *priv;
|
||||
struct usb_serial_port *port = *serial->port;
|
||||
|
||||
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv) {
|
||||
dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
|
||||
sizeof(*priv));
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
spin_lock_init(&priv->status_lock);
|
||||
init_waitqueue_head(&priv->delta_msr_wait);
|
||||
|
||||
usb_set_serial_port_data(port, priv);
|
||||
|
||||
return ssu100_initdevice(serial->dev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssu100_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct ssu100_port_private *priv;
|
||||
|
||||
priv = usb_get_serial_port_data(port);
|
||||
kfree(priv);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ssu100_tiocmget(struct tty_struct *tty)
|
||||
|
|
@ -647,7 +652,8 @@ static struct usb_serial_driver ssu100_device = {
|
|||
.open = ssu100_open,
|
||||
.close = ssu100_close,
|
||||
.attach = ssu100_attach,
|
||||
.release = ssu100_release,
|
||||
.port_probe = ssu100_port_probe,
|
||||
.port_remove = ssu100_port_remove,
|
||||
.dtr_rts = ssu100_dtr_rts,
|
||||
.process_read_urb = ssu100_process_read_urb,
|
||||
.tiocmget = ssu100_tiocmget,
|
||||
|
|
|
|||
|
|
@ -97,6 +97,8 @@ struct ti_device {
|
|||
|
||||
static int ti_startup(struct usb_serial *serial);
|
||||
static void ti_release(struct usb_serial *serial);
|
||||
static int ti_port_probe(struct usb_serial_port *port);
|
||||
static int ti_port_remove(struct usb_serial_port *port);
|
||||
static int ti_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
static void ti_close(struct usb_serial_port *port);
|
||||
static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
|
||||
|
|
@ -221,6 +223,8 @@ static struct usb_serial_driver ti_1port_device = {
|
|||
.num_ports = 1,
|
||||
.attach = ti_startup,
|
||||
.release = ti_release,
|
||||
.port_probe = ti_port_probe,
|
||||
.port_remove = ti_port_remove,
|
||||
.open = ti_open,
|
||||
.close = ti_close,
|
||||
.write = ti_write,
|
||||
|
|
@ -249,6 +253,8 @@ static struct usb_serial_driver ti_2port_device = {
|
|||
.num_ports = 2,
|
||||
.attach = ti_startup,
|
||||
.release = ti_release,
|
||||
.port_probe = ti_port_probe,
|
||||
.port_remove = ti_port_remove,
|
||||
.open = ti_open,
|
||||
.close = ti_close,
|
||||
.write = ti_write,
|
||||
|
|
@ -347,11 +353,8 @@ module_exit(ti_exit);
|
|||
static int ti_startup(struct usb_serial *serial)
|
||||
{
|
||||
struct ti_device *tdev;
|
||||
struct ti_port *tport;
|
||||
struct usb_device *dev = serial->dev;
|
||||
int status;
|
||||
int i;
|
||||
|
||||
|
||||
dev_dbg(&dev->dev,
|
||||
"%s - product 0x%4X, num configurations %d, configuration value %d",
|
||||
|
|
@ -399,42 +402,8 @@ static int ti_startup(struct usb_serial *serial)
|
|||
goto free_tdev;
|
||||
}
|
||||
|
||||
/* set up port structures */
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL);
|
||||
if (tport == NULL) {
|
||||
dev_err(&dev->dev, "%s - out of memory\n", __func__);
|
||||
status = -ENOMEM;
|
||||
goto free_tports;
|
||||
}
|
||||
spin_lock_init(&tport->tp_lock);
|
||||
tport->tp_uart_base_addr = (i == 0 ?
|
||||
TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
|
||||
tport->tp_closing_wait = closing_wait;
|
||||
init_waitqueue_head(&tport->tp_msr_wait);
|
||||
init_waitqueue_head(&tport->tp_write_wait);
|
||||
if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE,
|
||||
GFP_KERNEL)) {
|
||||
dev_err(&dev->dev, "%s - out of memory\n", __func__);
|
||||
kfree(tport);
|
||||
status = -ENOMEM;
|
||||
goto free_tports;
|
||||
}
|
||||
tport->tp_port = serial->port[i];
|
||||
tport->tp_tdev = tdev;
|
||||
usb_set_serial_port_data(serial->port[i], tport);
|
||||
tport->tp_uart_mode = 0; /* default is RS232 */
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
free_tports:
|
||||
for (--i; i >= 0; --i) {
|
||||
tport = usb_get_serial_port_data(serial->port[i]);
|
||||
kfifo_free(&tport->write_fifo);
|
||||
kfree(tport);
|
||||
usb_set_serial_port_data(serial->port[i], NULL);
|
||||
}
|
||||
free_tdev:
|
||||
kfree(tdev);
|
||||
usb_set_serial_data(serial, NULL);
|
||||
|
|
@ -444,21 +413,50 @@ free_tdev:
|
|||
|
||||
static void ti_release(struct usb_serial *serial)
|
||||
{
|
||||
int i;
|
||||
struct ti_device *tdev = usb_get_serial_data(serial);
|
||||
struct ti_port *tport;
|
||||
|
||||
for (i = 0; i < serial->num_ports; ++i) {
|
||||
tport = usb_get_serial_port_data(serial->port[i]);
|
||||
if (tport) {
|
||||
kfifo_free(&tport->write_fifo);
|
||||
kfree(tport);
|
||||
}
|
||||
}
|
||||
|
||||
kfree(tdev);
|
||||
}
|
||||
|
||||
static int ti_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct ti_port *tport;
|
||||
|
||||
tport = kzalloc(sizeof(*tport), GFP_KERNEL);
|
||||
if (!tport)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_init(&tport->tp_lock);
|
||||
if (port == port->serial->port[0])
|
||||
tport->tp_uart_base_addr = TI_UART1_BASE_ADDR;
|
||||
else
|
||||
tport->tp_uart_base_addr = TI_UART2_BASE_ADDR;
|
||||
tport->tp_closing_wait = closing_wait;
|
||||
init_waitqueue_head(&tport->tp_msr_wait);
|
||||
init_waitqueue_head(&tport->tp_write_wait);
|
||||
if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) {
|
||||
kfree(tport);
|
||||
return -ENOMEM;
|
||||
}
|
||||
tport->tp_port = port;
|
||||
tport->tp_tdev = usb_get_serial_data(port->serial);
|
||||
tport->tp_uart_mode = 0; /* default is RS232 */
|
||||
|
||||
usb_set_serial_port_data(port, tport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ti_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct ti_port *tport;
|
||||
|
||||
tport = usb_get_serial_port_data(port);
|
||||
kfifo_free(&tport->write_fifo);
|
||||
kfree(tport);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on);
|
||||
extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port);
|
||||
extern void usb_wwan_close(struct usb_serial_port *port);
|
||||
extern int usb_wwan_startup(struct usb_serial *serial);
|
||||
extern int usb_wwan_port_probe(struct usb_serial_port *port);
|
||||
extern int usb_wwan_port_remove(struct usb_serial_port *port);
|
||||
extern int usb_wwan_write_room(struct tty_struct *tty);
|
||||
extern void usb_wwan_set_termios(struct tty_struct *tty,
|
||||
|
|
|
|||
|
|
@ -447,15 +447,14 @@ void usb_wwan_close(struct usb_serial_port *port)
|
|||
EXPORT_SYMBOL(usb_wwan_close);
|
||||
|
||||
/* Helper functions used by usb_wwan_setup_urbs */
|
||||
static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint,
|
||||
static struct urb *usb_wwan_setup_urb(struct usb_serial_port *port,
|
||||
int endpoint,
|
||||
int dir, void *ctx, char *buf, int len,
|
||||
void (*callback) (struct urb *))
|
||||
{
|
||||
struct usb_serial *serial = port->serial;
|
||||
struct urb *urb;
|
||||
|
||||
if (endpoint == -1)
|
||||
return NULL; /* endpoint not needed */
|
||||
|
||||
urb = usb_alloc_urb(0, GFP_KERNEL); /* No ISO */
|
||||
if (urb == NULL) {
|
||||
dev_dbg(&serial->interface->dev,
|
||||
|
|
@ -472,101 +471,78 @@ static struct urb *usb_wwan_setup_urb(struct usb_serial *serial, int endpoint,
|
|||
return urb;
|
||||
}
|
||||
|
||||
/* Setup urbs */
|
||||
static void usb_wwan_setup_urbs(struct usb_serial *serial)
|
||||
int usb_wwan_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
int i, j;
|
||||
struct usb_serial_port *port;
|
||||
struct usb_wwan_port_private *portdata;
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port = serial->port[i];
|
||||
portdata = usb_get_serial_port_data(port);
|
||||
|
||||
/* Do indat endpoints first */
|
||||
for (j = 0; j < N_IN_URB; ++j) {
|
||||
portdata->in_urbs[j] = usb_wwan_setup_urb(serial,
|
||||
port->
|
||||
bulk_in_endpointAddress,
|
||||
USB_DIR_IN,
|
||||
port,
|
||||
portdata->
|
||||
in_buffer[j],
|
||||
IN_BUFLEN,
|
||||
usb_wwan_indat_callback);
|
||||
}
|
||||
|
||||
/* outdat endpoints */
|
||||
for (j = 0; j < N_OUT_URB; ++j) {
|
||||
portdata->out_urbs[j] = usb_wwan_setup_urb(serial,
|
||||
port->
|
||||
bulk_out_endpointAddress,
|
||||
USB_DIR_OUT,
|
||||
port,
|
||||
portdata->
|
||||
out_buffer
|
||||
[j],
|
||||
OUT_BUFLEN,
|
||||
usb_wwan_outdat_callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int usb_wwan_startup(struct usb_serial *serial)
|
||||
{
|
||||
int i, j, err;
|
||||
struct usb_serial_port *port;
|
||||
struct usb_wwan_port_private *portdata;
|
||||
struct urb *urb;
|
||||
u8 *buffer;
|
||||
int err;
|
||||
int i;
|
||||
|
||||
/* Now setup per port private data */
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port = serial->port[i];
|
||||
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
|
||||
if (!portdata) {
|
||||
dev_dbg(&port->dev, "%s: kmalloc for usb_wwan_port_private (%d) failed!.\n",
|
||||
__func__, i);
|
||||
return 1;
|
||||
}
|
||||
init_usb_anchor(&portdata->delayed);
|
||||
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
|
||||
if (!portdata)
|
||||
return -ENOMEM;
|
||||
|
||||
for (j = 0; j < N_IN_URB; j++) {
|
||||
buffer = (u8 *) __get_free_page(GFP_KERNEL);
|
||||
if (!buffer)
|
||||
goto bail_out_error;
|
||||
portdata->in_buffer[j] = buffer;
|
||||
}
|
||||
init_usb_anchor(&portdata->delayed);
|
||||
|
||||
for (j = 0; j < N_OUT_URB; j++) {
|
||||
buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
goto bail_out_error2;
|
||||
portdata->out_buffer[j] = buffer;
|
||||
}
|
||||
for (i = 0; i < N_IN_URB; i++) {
|
||||
if (!port->bulk_in_size)
|
||||
break;
|
||||
|
||||
usb_set_serial_port_data(port, portdata);
|
||||
buffer = (u8 *)__get_free_page(GFP_KERNEL);
|
||||
if (!buffer)
|
||||
goto bail_out_error;
|
||||
portdata->in_buffer[i] = buffer;
|
||||
|
||||
if (!port->interrupt_in_urb)
|
||||
continue;
|
||||
urb = usb_wwan_setup_urb(port, port->bulk_in_endpointAddress,
|
||||
USB_DIR_IN, port,
|
||||
buffer, IN_BUFLEN,
|
||||
usb_wwan_indat_callback);
|
||||
portdata->in_urbs[i] = urb;
|
||||
}
|
||||
|
||||
for (i = 0; i < N_OUT_URB; i++) {
|
||||
if (!port->bulk_out_size)
|
||||
break;
|
||||
|
||||
buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
|
||||
if (!buffer)
|
||||
goto bail_out_error2;
|
||||
portdata->out_buffer[i] = buffer;
|
||||
|
||||
urb = usb_wwan_setup_urb(port, port->bulk_out_endpointAddress,
|
||||
USB_DIR_OUT, port,
|
||||
buffer, OUT_BUFLEN,
|
||||
usb_wwan_outdat_callback);
|
||||
portdata->out_urbs[i] = urb;
|
||||
}
|
||||
|
||||
usb_set_serial_port_data(port, portdata);
|
||||
|
||||
if (port->interrupt_in_urb) {
|
||||
err = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
|
||||
if (err)
|
||||
dev_dbg(&port->dev, "%s: submit irq_in urb failed %d\n",
|
||||
__func__, err);
|
||||
}
|
||||
usb_wwan_setup_urbs(serial);
|
||||
|
||||
return 0;
|
||||
|
||||
bail_out_error2:
|
||||
for (j = 0; j < N_OUT_URB; j++)
|
||||
kfree(portdata->out_buffer[j]);
|
||||
for (i = 0; i < N_OUT_URB; i++) {
|
||||
usb_free_urb(portdata->out_urbs[i]);
|
||||
kfree(portdata->out_buffer[i]);
|
||||
}
|
||||
bail_out_error:
|
||||
for (j = 0; j < N_IN_URB; j++)
|
||||
if (portdata->in_buffer[j])
|
||||
free_page((unsigned long)portdata->in_buffer[j]);
|
||||
for (i = 0; i < N_IN_URB; i++) {
|
||||
usb_free_urb(portdata->in_urbs[i]);
|
||||
free_page((unsigned long)portdata->in_buffer[i]);
|
||||
}
|
||||
kfree(portdata);
|
||||
return 1;
|
||||
|
||||
return -ENOMEM;
|
||||
}
|
||||
EXPORT_SYMBOL(usb_wwan_startup);
|
||||
EXPORT_SYMBOL_GPL(usb_wwan_port_probe);
|
||||
|
||||
int usb_wwan_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -83,6 +83,8 @@ static int whiteheat_firmware_attach(struct usb_serial *serial);
|
|||
/* function prototypes for the Connect Tech WhiteHEAT serial converter */
|
||||
static int whiteheat_attach(struct usb_serial *serial);
|
||||
static void whiteheat_release(struct usb_serial *serial);
|
||||
static int whiteheat_port_probe(struct usb_serial_port *port);
|
||||
static int whiteheat_port_remove(struct usb_serial_port *port);
|
||||
static int whiteheat_open(struct tty_struct *tty,
|
||||
struct usb_serial_port *port);
|
||||
static void whiteheat_close(struct usb_serial_port *port);
|
||||
|
|
@ -117,6 +119,8 @@ static struct usb_serial_driver whiteheat_device = {
|
|||
.num_ports = 4,
|
||||
.attach = whiteheat_attach,
|
||||
.release = whiteheat_release,
|
||||
.port_probe = whiteheat_port_probe,
|
||||
.port_remove = whiteheat_port_remove,
|
||||
.open = whiteheat_open,
|
||||
.close = whiteheat_close,
|
||||
.ioctl = whiteheat_ioctl,
|
||||
|
|
@ -218,15 +222,12 @@ static int whiteheat_attach(struct usb_serial *serial)
|
|||
{
|
||||
struct usb_serial_port *command_port;
|
||||
struct whiteheat_command_private *command_info;
|
||||
struct usb_serial_port *port;
|
||||
struct whiteheat_private *info;
|
||||
struct whiteheat_hw_info *hw_info;
|
||||
int pipe;
|
||||
int ret;
|
||||
int alen;
|
||||
__u8 *command;
|
||||
__u8 *result;
|
||||
int i;
|
||||
|
||||
command_port = serial->port[COMMAND_PORT];
|
||||
|
||||
|
|
@ -285,22 +286,6 @@ static int whiteheat_attach(struct usb_serial *serial)
|
|||
serial->type->description,
|
||||
hw_info->sw_major_rev, hw_info->sw_minor_rev);
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
port = serial->port[i];
|
||||
|
||||
info = kmalloc(sizeof(struct whiteheat_private), GFP_KERNEL);
|
||||
if (info == NULL) {
|
||||
dev_err(&port->dev,
|
||||
"%s: Out of memory for port structures\n",
|
||||
serial->type->description);
|
||||
goto no_private;
|
||||
}
|
||||
|
||||
info->mcr = 0;
|
||||
|
||||
usb_set_serial_port_data(port, info);
|
||||
}
|
||||
|
||||
command_info = kmalloc(sizeof(struct whiteheat_command_private),
|
||||
GFP_KERNEL);
|
||||
if (command_info == NULL) {
|
||||
|
|
@ -333,16 +318,10 @@ no_firmware:
|
|||
"%s: please contact [email protected]\n",
|
||||
serial->type->description);
|
||||
kfree(result);
|
||||
kfree(command);
|
||||
return -ENODEV;
|
||||
|
||||
no_command_private:
|
||||
for (i = serial->num_ports - 1; i >= 0; i--) {
|
||||
port = serial->port[i];
|
||||
info = usb_get_serial_port_data(port);
|
||||
kfree(info);
|
||||
no_private:
|
||||
;
|
||||
}
|
||||
kfree(result);
|
||||
no_result_buffer:
|
||||
kfree(command);
|
||||
|
|
@ -350,21 +329,36 @@ no_command_buffer:
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
|
||||
static void whiteheat_release(struct usb_serial *serial)
|
||||
{
|
||||
struct usb_serial_port *command_port;
|
||||
struct whiteheat_private *info;
|
||||
int i;
|
||||
|
||||
/* free up our private data for our command port */
|
||||
command_port = serial->port[COMMAND_PORT];
|
||||
kfree(usb_get_serial_port_data(command_port));
|
||||
}
|
||||
|
||||
for (i = 0; i < serial->num_ports; i++) {
|
||||
info = usb_get_serial_port_data(serial->port[i]);
|
||||
kfree(info);
|
||||
}
|
||||
static int whiteheat_port_probe(struct usb_serial_port *port)
|
||||
{
|
||||
struct whiteheat_private *info;
|
||||
|
||||
info = kzalloc(sizeof(*info), GFP_KERNEL);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
usb_set_serial_port_data(port, info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int whiteheat_port_remove(struct usb_serial_port *port)
|
||||
{
|
||||
struct whiteheat_private *info;
|
||||
|
||||
info = usb_get_serial_port_data(port);
|
||||
kfree(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int whiteheat_open(struct tty_struct *tty, struct usb_serial_port *port)
|
||||
|
|
|
|||
|
|
@ -186,6 +186,12 @@ static int slave_configure(struct scsi_device *sdev)
|
|||
/* Some devices don't handle VPD pages correctly */
|
||||
sdev->skip_vpd_pages = 1;
|
||||
|
||||
/* Do not attempt to use REPORT SUPPORTED OPERATION CODES */
|
||||
sdev->no_report_opcodes = 1;
|
||||
|
||||
/* Do not attempt to use WRITE SAME */
|
||||
sdev->no_write_same = 1;
|
||||
|
||||
/* Some disks return the total number of blocks in response
|
||||
* to READ CAPACITY rather than the highest block number.
|
||||
* If this device makes that mistake, tell the sd driver. */
|
||||
|
|
|
|||
|
|
@ -1004,6 +1004,12 @@ UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9999,
|
|||
USB_SC_8070, USB_PR_CB, NULL,
|
||||
US_FL_NEED_OVERRIDE | US_FL_FIX_INQUIRY ),
|
||||
|
||||
/* Submitted by Oleksandr Chumachenko <[email protected]> */
|
||||
UNUSUAL_DEV( 0x07cf, 0x1167, 0x0100, 0x0100,
|
||||
"Casio",
|
||||
"EX-N1 DigitalCamera",
|
||||
USB_SC_8070, USB_PR_DEVICE, NULL, 0),
|
||||
|
||||
/* Submitted by Hartmut Wahl <[email protected]>*/
|
||||
UNUSUAL_DEV( 0x0839, 0x000a, 0x0001, 0x0001,
|
||||
"Samsung",
|
||||
|
|
|
|||
Loading…
Reference in a new issue