Merge branches 'cache-l2x0', 'fixes', 'hdrs', 'misc', 'mmci', 'vic' and 'warnings' into for-next

This commit is contained in:
Russell King 2012-12-11 00:20:18 +00:00
1701 changed files with 22594 additions and 16325 deletions

View file

@ -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,

View file

@ -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;
}

View file

@ -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);

View file

@ -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,

View file

@ -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

View file

@ -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)

View file

@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)
ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
WARN_ON_ONCE(ret);
dep->resource_index = 0;
dep->flags &= ~DWC3_EP_BUSY;
udelay(100);
}

View file

@ -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];

View file

@ -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

View file

@ -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;

View file

@ -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 */

View file

@ -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.

View file

@ -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);

View file

@ -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]);

View file

@ -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;

View file

@ -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)
{

View file

@ -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;

View file

@ -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;

View file

@ -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-"),
},
},
{ }

View file

@ -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)

View file

@ -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);
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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");

View file

@ -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);

View file

@ -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");

View file

@ -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;

View file

@ -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);

View file

@ -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

View file

@ -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);
}

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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,

View file

@ -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,

View file

@ -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,
};

View file

@ -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);

View file

@ -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)
{

View file

@ -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);

View file

@ -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)
{

View file

@ -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[] = {

View file

@ -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,

View file

@ -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);

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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[] = {

View file

@ -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);

View file

@ -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[] = {

View file

@ -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[] = {

View file

@ -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)

View file

@ -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)

View file

@ -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 */

View file

@ -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,

View file

@ -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,

View file

@ -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,
};

View file

@ -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);

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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[] = {

View file

@ -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,

View file

@ -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,

View file

@ -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,

View file

@ -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,
};

View file

@ -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,

View file

@ -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)
{

View file

@ -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,

View file

@ -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)
{

View file

@ -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)

View file

@ -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. */

View file

@ -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",