提交 42bf3e27 编写于 作者: L Linus Torvalds

Merge tag 'usb-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb

Pull USB fixes from Greg Kroah-Hartman:
 "Here are the USB patches against your 3.7-rc1 tree.

  There are the usual UABI header file movements, and we finally are now
  able to remove the dbg() macro that is over 15 years old (that had to
  wait for after some other trees got merged into yours during the big
  3.7-rc1 merge window.)

  Other than that, nothing major, just a number of bugfixes and new
  device ids.  It turns out that almost all of the usb-serial drivers
  had bugs in how they were handling their internal data, leaking
  memory, hence all of those fixups.

  Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>"

* tag 'usb-3.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb: (42 commits)
  USB: option: add more ZTE devices
  USB: option: blacklist net interface on ZTE devices
  usb: host: xhci: New system added for Compliance Mode Patch on SN65LVPE502CP
  USB: io_ti: fix sysfs-attribute creation
  USB: iuu_phoenix: fix sysfs-attribute creation
  USB: spcp8x5: fix port-data memory leak
  USB: ssu100: fix port-data memory leak
  USB: ti_usb_3410_5052: fix port-data memory leak
  USB: oti6858: fix port-data memory leak
  USB: iuu_phoenix: fix port-data memory leak
  USB: kl5kusb105: fix port-data memory leak
  USB: io_ti: fix port-data memory leak
  USB: keyspan_pda: fix port-data memory leak
  USB: f81232: fix port-data memory leak
  USB: io_edgeport: fix port-data memory leak
  USB: kobil_sct: fix port-data memory leak
  USB: cypress_m8: fix port-data memory leak
  usb: acm: fix the computation of the number of data bits
  usb: Missing dma_mask in ehci-vt8500.c when probed from device-tree
  usb: Missing dma_mask in uhci-platform.c when probed from device-tree
  ...
...@@ -7746,6 +7746,13 @@ W: http://www.ideasonboard.org/uvc/ ...@@ -7746,6 +7746,13 @@ W: http://www.ideasonboard.org/uvc/
S: Maintained S: Maintained
F: drivers/media/usb/uvc/ F: drivers/media/usb/uvc/
USB WEBCAM GADGET
M: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
L: linux-usb@vger.kernel.org
S: Maintained
F: drivers/usb/gadget/*uvc*.c
F: drivers/usb/gadget/webcam.c
USB WIRELESS RNDIS DRIVER (rndis_wlan) USB WIRELESS RNDIS DRIVER (rndis_wlan)
M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi> M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
L: linux-wireless@vger.kernel.org L: linux-wireless@vger.kernel.org
......
...@@ -817,10 +817,6 @@ static const __u32 acm_tty_speed[] = { ...@@ -817,10 +817,6 @@ static const __u32 acm_tty_speed[] = {
2500000, 3000000, 3500000, 4000000 2500000, 3000000, 3500000, 4000000
}; };
static const __u8 acm_tty_size[] = {
5, 6, 7, 8
};
static void acm_tty_set_termios(struct tty_struct *tty, static void acm_tty_set_termios(struct tty_struct *tty,
struct ktermios *termios_old) struct ktermios *termios_old)
{ {
...@@ -834,7 +830,21 @@ static void acm_tty_set_termios(struct tty_struct *tty, ...@@ -834,7 +830,21 @@ static void acm_tty_set_termios(struct tty_struct *tty,
newline.bParityType = termios->c_cflag & PARENB ? newline.bParityType = termios->c_cflag & PARENB ?
(termios->c_cflag & PARODD ? 1 : 2) + (termios->c_cflag & PARODD ? 1 : 2) +
(termios->c_cflag & CMSPAR ? 2 : 0) : 0; (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 */ /* FIXME: Needs to clear unsupported bits in the termios */
acm->clocal = ((termios->c_cflag & CLOCAL) != 0); acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
...@@ -1233,7 +1243,7 @@ static int acm_probe(struct usb_interface *intf, ...@@ -1233,7 +1243,7 @@ static int acm_probe(struct usb_interface *intf,
if (usb_endpoint_xfer_int(epwrite)) if (usb_endpoint_xfer_int(epwrite))
usb_fill_int_urb(snd->urb, usb_dev, 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); NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
else else
usb_fill_bulk_urb(snd->urb, usb_dev, usb_fill_bulk_urb(snd->urb, usb_dev,
......
...@@ -1348,6 +1348,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb, ...@@ -1348,6 +1348,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
ret = -EFAULT; ret = -EFAULT;
goto error; goto error;
} }
uurb->buffer += u;
} }
totlen -= u; totlen -= u;
} }
......
...@@ -367,6 +367,10 @@ static int usb_probe_interface(struct device *dev) ...@@ -367,6 +367,10 @@ static int usb_probe_interface(struct device *dev)
intf->condition = USB_INTERFACE_UNBOUND; intf->condition = USB_INTERFACE_UNBOUND;
usb_cancel_queued_reset(intf); 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 */ /* Unbound interfaces are always runtime-PM-disabled and -suspended */
if (driver->supports_autosuspend) if (driver->supports_autosuspend)
pm_runtime_disable(dev); pm_runtime_disable(dev);
......
...@@ -3241,8 +3241,7 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state) ...@@ -3241,8 +3241,7 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state)
(state == USB3_LPM_U2 && (state == USB3_LPM_U2 &&
(u2_sel > USB3_LPM_MAX_U2_SEL_PEL || (u2_sel > USB3_LPM_MAX_U2_SEL_PEL ||
u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) { u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) {
dev_dbg(&udev->dev, "Device-initiated %s disabled due " dev_dbg(&udev->dev, "Device-initiated %s disabled due to long SEL %llu us or PEL %llu us\n",
"to long SEL %llu ms or PEL %llu ms\n",
usb3_lpm_names[state], u1_sel, u1_pel); usb3_lpm_names[state], u1_sel, u1_pel);
return -EINVAL; return -EINVAL;
} }
...@@ -3319,16 +3318,6 @@ static int usb_set_device_initiated_lpm(struct usb_device *udev, ...@@ -3319,16 +3318,6 @@ static int usb_set_device_initiated_lpm(struct usb_device *udev,
} }
if (enable) { 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 * Now send the control transfer to enable device-initiated LPM
* for either U1 or U2. * for either U1 or U2.
...@@ -3414,7 +3403,28 @@ static int usb_set_lpm_timeout(struct usb_device *udev, ...@@ -3414,7 +3403,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, static void usb_enable_link_state(struct usb_hcd *hcd, struct usb_device *udev,
enum usb3_link_state state) 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 /* We allow the host controller to set the U1/U2 timeout internally
* first, so that it can change its schedule to account for the * first, so that it can change its schedule to account for the
......
...@@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc) ...@@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc)
{ {
dwc3_event_buffers_cleanup(dwc); dwc3_event_buffers_cleanup(dwc);
dwc3_free_event_buffers(dwc); dwc3_free_event_buffers(dwc);
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
} }
#define DWC3_ALIGN_MASK (16 - 1) #define DWC3_ALIGN_MASK (16 - 1)
......
...@@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum) ...@@ -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); ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
WARN_ON_ONCE(ret); WARN_ON_ONCE(ret);
dep->resource_index = 0; dep->resource_index = 0;
dep->flags &= ~DWC3_EP_BUSY;
udelay(100); udelay(100);
} }
......
...@@ -952,6 +952,7 @@ endif ...@@ -952,6 +952,7 @@ endif
config USB_G_WEBCAM config USB_G_WEBCAM
tristate "USB Webcam Gadget" tristate "USB Webcam Gadget"
depends on VIDEO_DEV depends on VIDEO_DEV
select USB_LIBCOMPOSITE
help help
The Webcam Gadget acts as a composite USB Audio and Video Class The Webcam Gadget acts as a composite USB Audio and Video Class
device. It provides a userspace API to process UVC control requests device. It provides a userspace API to process UVC control requests
......
...@@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work) ...@@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work)
/* Get the VBUS status from the transceiver */ /* Get the VBUS status from the transceiver */
value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client, value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_OTG_CONTROL_2); ISP1301_I2C_INTERRUPT_SOURCE);
/* VBUS on or off? */ /* VBUS on or off? */
if (value & OTG_B_SESS_VLD) if (value & INT_SESS_VLD)
udc->vbus = 1; udc->vbus = 1;
else else
udc->vbus = 0; udc->vbus = 0;
......
...@@ -85,6 +85,8 @@ static const struct hc_driver vt8500_ehci_hc_driver = { ...@@ -85,6 +85,8 @@ static const struct hc_driver vt8500_ehci_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete, .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) static int vt8500_ehci_drv_probe(struct platform_device *pdev)
{ {
struct usb_hcd *hcd; struct usb_hcd *hcd;
...@@ -95,6 +97,14 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev) ...@@ -95,6 +97,14 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev)
if (usb_disabled()) if (usb_disabled())
return -ENODEV; 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) { if (pdev->resource[1].flags != IORESOURCE_IRQ) {
pr_debug("resource[1] is not IORESOURCE_IRQ"); pr_debug("resource[1] is not IORESOURCE_IRQ");
return -ENOMEM; return -ENOMEM;
......
...@@ -60,6 +60,7 @@ static const struct hc_driver uhci_platform_hc_driver = { ...@@ -60,6 +60,7 @@ static const struct hc_driver uhci_platform_hc_driver = {
.hub_control = uhci_hub_control, .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) 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) ...@@ -71,6 +72,14 @@ static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
if (usb_disabled()) if (usb_disabled())
return -ENODEV; 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, hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
pdev->name); pdev->name);
if (!hcd) if (!hcd)
......
...@@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void) ...@@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
if (strstr(dmi_product_name, "Z420") || if (strstr(dmi_product_name, "Z420") ||
strstr(dmi_product_name, "Z620") || strstr(dmi_product_name, "Z620") ||
strstr(dmi_product_name, "Z820")) strstr(dmi_product_name, "Z820") ||
strstr(dmi_product_name, "Z1"))
return true; return true;
return false; return false;
......
...@@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci) ...@@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
ret = IRQ_HANDLED; 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) if (musb->int_tx || musb->int_rx || musb->int_usb)
ret |= musb_interrupt(musb); ret |= musb_interrupt(musb);
......
...@@ -273,9 +273,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data) ...@@ -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, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC); usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
usbhs_write(priv, BRDYSTS, 0); usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
usbhs_write(priv, NRDYSTS, 0); usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts);
usbhs_write(priv, BEMPSTS, 0); usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
/* /*
* call irq callback functions * call irq callback functions
......
...@@ -54,7 +54,7 @@ struct usbhs_pipe_info { ...@@ -54,7 +54,7 @@ struct usbhs_pipe_info {
* pipe list * pipe list
*/ */
#define __usbhs_for_each_pipe(start, pos, info, i) \ #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 < (info)->size; \
i++, pos = (info)->pipe + i) i++, pos = (info)->pipe + i)
......
...@@ -125,9 +125,6 @@ static inline int calc_divisor(int bps) ...@@ -125,9 +125,6 @@ static inline int calc_divisor(int bps)
static int ark3116_attach(struct usb_serial *serial) 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 */ /* make sure we have our end-points */
if ((serial->num_bulk_in == 0) || if ((serial->num_bulk_in == 0) ||
(serial->num_bulk_out == 0) || (serial->num_bulk_out == 0) ||
...@@ -142,8 +139,15 @@ static int ark3116_attach(struct usb_serial *serial) ...@@ -142,8 +139,15 @@ static int ark3116_attach(struct usb_serial *serial)
return -EINVAL; return -EINVAL;
} }
priv = kzalloc(sizeof(struct ark3116_private), return 0;
GFP_KERNEL); }
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) if (!priv)
return -ENOMEM; return -ENOMEM;
...@@ -198,18 +202,15 @@ static int ark3116_attach(struct usb_serial *serial) ...@@ -198,18 +202,15 @@ static int ark3116_attach(struct usb_serial *serial)
return 0; 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); struct ark3116_private *priv = usb_get_serial_port_data(port);
/* device is closed, so URBs and DMA should be down */ /* device is closed, so URBs and DMA should be down */
usb_set_serial_port_data(port, NULL);
mutex_destroy(&priv->hw_lock); mutex_destroy(&priv->hw_lock);
kfree(priv); kfree(priv);
return 0;
} }
static void ark3116_init_termios(struct tty_struct *tty) static void ark3116_init_termios(struct tty_struct *tty)
...@@ -723,7 +724,8 @@ static struct usb_serial_driver ark3116_device = { ...@@ -723,7 +724,8 @@ static struct usb_serial_driver ark3116_device = {
.id_table = id_table, .id_table = id_table,
.num_ports = 1, .num_ports = 1,
.attach = ark3116_attach, .attach = ark3116_attach,
.release = ark3116_release, .port_probe = ark3116_port_probe,
.port_remove = ark3116_port_remove,
.set_termios = ark3116_set_termios, .set_termios = ark3116_set_termios,
.init_termios = ark3116_init_termios, .init_termios = ark3116_init_termios,
.ioctl = ark3116_ioctl, .ioctl = ark3116_ioctl,
......
...@@ -45,8 +45,8 @@ ...@@ -45,8 +45,8 @@
#define DRIVER_DESC "USB Belkin Serial converter driver" #define DRIVER_DESC "USB Belkin Serial converter driver"
/* function prototypes for a Belkin USB Serial Adapter F5U103 */ /* function prototypes for a Belkin USB Serial Adapter F5U103 */
static int belkin_sa_startup(struct usb_serial *serial); static int belkin_sa_port_probe(struct usb_serial_port *port);
static void belkin_sa_release(struct usb_serial *serial); static int belkin_sa_port_remove(struct usb_serial_port *port);
static int belkin_sa_open(struct tty_struct *tty, static int belkin_sa_open(struct tty_struct *tty,
struct usb_serial_port *port); struct usb_serial_port *port);
static void belkin_sa_close(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 = { ...@@ -88,8 +88,8 @@ static struct usb_serial_driver belkin_device = {
.break_ctl = belkin_sa_break_ctl, .break_ctl = belkin_sa_break_ctl,
.tiocmget = belkin_sa_tiocmget, .tiocmget = belkin_sa_tiocmget,
.tiocmset = belkin_sa_tiocmset, .tiocmset = belkin_sa_tiocmset,
.attach = belkin_sa_startup, .port_probe = belkin_sa_port_probe,
.release = belkin_sa_release, .port_remove = belkin_sa_port_remove,
}; };
static struct usb_serial_driver * const serial_drivers[] = { static struct usb_serial_driver * const serial_drivers[] = {
...@@ -118,17 +118,15 @@ struct belkin_sa_private { ...@@ -118,17 +118,15 @@ struct belkin_sa_private {
(c), BELKIN_SA_SET_REQUEST_TYPE, \ (c), BELKIN_SA_SET_REQUEST_TYPE, \
(v), 0, NULL, 0, WDR_TIMEOUT) (v), 0, NULL, 0, WDR_TIMEOUT)
/* do some startup allocations not currently performed by usb_serial_probe() */ static int belkin_sa_port_probe(struct usb_serial_port *port)
static int belkin_sa_startup(struct usb_serial *serial)
{ {
struct usb_device *dev = serial->dev; struct usb_device *dev = port->serial->dev;
struct belkin_sa_private *priv; struct belkin_sa_private *priv;
/* allocate the private data structure */
priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL); priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
if (!priv) if (!priv)
return -1; /* error */ return -ENOMEM;
/* set initial values for control structures */
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
priv->control_state = 0; priv->control_state = 0;
priv->last_lsr = 0; priv->last_lsr = 0;
...@@ -140,18 +138,19 @@ static int belkin_sa_startup(struct usb_serial *serial) ...@@ -140,18 +138,19 @@ static int belkin_sa_startup(struct usb_serial *serial)
le16_to_cpu(dev->descriptor.bcdDevice), le16_to_cpu(dev->descriptor.bcdDevice),
priv->bad_flow_control); priv->bad_flow_control);
init_waitqueue_head(&serial->port[0]->write_wait); usb_set_serial_port_data(port, priv);
usb_set_serial_port_data(serial->port[0], priv);
return 0; 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) priv = usb_get_serial_port_data(port);
kfree(usb_get_serial_port_data(serial->port[i])); kfree(priv);
return 0;
} }
static int belkin_sa_open(struct tty_struct *tty, static int belkin_sa_open(struct tty_struct *tty,
......
...@@ -162,7 +162,7 @@ static const struct usb_device_id id_table[] = { ...@@ -162,7 +162,7 @@ static const struct usb_device_id id_table[] = {
MODULE_DEVICE_TABLE(usb, id_table); MODULE_DEVICE_TABLE(usb, id_table);
struct cp210x_port_private { struct cp210x_serial_private {
__u8 bInterfaceNumber; __u8 bInterfaceNumber;
}; };
...@@ -276,7 +276,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, ...@@ -276,7 +276,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
unsigned int *data, int size) unsigned int *data, int size)
{ {
struct usb_serial *serial = port->serial; 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; __le32 *buf;
int result, i, length; int result, i, length;
...@@ -292,7 +292,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request, ...@@ -292,7 +292,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
/* Issue the request, attempting to read 'size' bytes */ /* Issue the request, attempting to read 'size' bytes */
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0), result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
request, REQTYPE_INTERFACE_TO_HOST, 0x0000, request, REQTYPE_INTERFACE_TO_HOST, 0x0000,
port_priv->bInterfaceNumber, buf, size, spriv->bInterfaceNumber, buf, size,
USB_CTRL_GET_TIMEOUT); USB_CTRL_GET_TIMEOUT);
/* Convert data into an array of integers */ /* Convert data into an array of integers */
...@@ -323,7 +323,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, ...@@ -323,7 +323,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
unsigned int *data, int size) unsigned int *data, int size)
{ {
struct usb_serial *serial = port->serial; 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; __le32 *buf;
int result, i, length; int result, i, length;
...@@ -345,13 +345,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request, ...@@ -345,13 +345,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
result = usb_control_msg(serial->dev, result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0), usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_INTERFACE, 0x0000, request, REQTYPE_HOST_TO_INTERFACE, 0x0000,
port_priv->bInterfaceNumber, buf, size, spriv->bInterfaceNumber, buf, size,
USB_CTRL_SET_TIMEOUT); USB_CTRL_SET_TIMEOUT);
} else { } else {
result = usb_control_msg(serial->dev, result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0), usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_INTERFACE, data[0], request, REQTYPE_HOST_TO_INTERFACE, data[0],
port_priv->bInterfaceNumber, NULL, 0, spriv->bInterfaceNumber, NULL, 0,
USB_CTRL_SET_TIMEOUT); USB_CTRL_SET_TIMEOUT);
} }
...@@ -845,36 +845,30 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state) ...@@ -845,36 +845,30 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
static int cp210x_startup(struct usb_serial *serial) static int cp210x_startup(struct usb_serial *serial)
{ {
struct cp210x_port_private *port_priv; struct usb_host_interface *cur_altsetting;
int i; struct cp210x_serial_private *spriv;
/* cp210x buffers behave strangely unless device is reset */ /* cp210x buffers behave strangely unless device is reset */
usb_reset_device(serial->dev); usb_reset_device(serial->dev);
for (i = 0; i < serial->num_ports; i++) { spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL); if (!spriv)
if (!port_priv) return -ENOMEM;
return -ENOMEM;
port_priv->bInterfaceNumber = cur_altsetting = serial->interface->cur_altsetting;
serial->interface->cur_altsetting->desc.bInterfaceNumber; spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber;
usb_set_serial_port_data(serial->port[i], port_priv); usb_set_serial_data(serial, spriv);
}
return 0; return 0;
} }
static void cp210x_release(struct usb_serial *serial) static void cp210x_release(struct usb_serial *serial)
{ {
struct cp210x_port_private *port_priv; struct cp210x_serial_private *spriv;
int i;
for (i = 0; i < serial->num_ports; i++) { spriv = usb_get_serial_data(serial);
port_priv = usb_get_serial_port_data(serial->port[i]); kfree(spriv);
kfree(port_priv);
usb_set_serial_port_data(serial->port[i], NULL);
}
} }
module_usb_serial_driver(serial_drivers, id_table); module_usb_serial_driver(serial_drivers, id_table);
......
...@@ -55,9 +55,9 @@ ...@@ -55,9 +55,9 @@
#define CYBERJACK_PRODUCT_ID 0x0100 #define CYBERJACK_PRODUCT_ID 0x0100
/* Function prototypes */ /* Function prototypes */
static int cyberjack_startup(struct usb_serial *serial);
static void cyberjack_disconnect(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, static int cyberjack_open(struct tty_struct *tty,
struct usb_serial_port *port); struct usb_serial_port *port);
static void cyberjack_close(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 = { ...@@ -83,9 +83,9 @@ static struct usb_serial_driver cyberjack_device = {
.description = "Reiner SCT Cyberjack USB card reader", .description = "Reiner SCT Cyberjack USB card reader",
.id_table = id_table, .id_table = id_table,
.num_ports = 1, .num_ports = 1,
.attach = cyberjack_startup,
.disconnect = cyberjack_disconnect, .disconnect = cyberjack_disconnect,
.release = cyberjack_release, .port_probe = cyberjack_port_probe,
.port_remove = cyberjack_port_remove,
.open = cyberjack_open, .open = cyberjack_open,
.close = cyberjack_close, .close = cyberjack_close,
.write = cyberjack_write, .write = cyberjack_write,
...@@ -107,56 +107,45 @@ struct cyberjack_private { ...@@ -107,56 +107,45 @@ struct cyberjack_private {
short wrsent; /* Data already sent */ short wrsent; /* Data already sent */
}; };
/* do some startup allocations not currently performed by usb_serial_probe() */ static int cyberjack_port_probe(struct usb_serial_port *port)
static int cyberjack_startup(struct usb_serial *serial)
{ {
struct cyberjack_private *priv; struct cyberjack_private *priv;
int i; int result;
/* allocate the private data structure */
priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL); priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
if (!priv) if (!priv)
return -ENOMEM; return -ENOMEM;
/* set initial values */
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
priv->rdtodo = 0; priv->rdtodo = 0;
priv->wrfilled = 0; priv->wrfilled = 0;
priv->wrsent = 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) { result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
int result; if (result)
result = usb_submit_urb(serial->port[i]->interrupt_in_urb, dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
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__);
}
return 0; return 0;
} }
static void cyberjack_disconnect(struct usb_serial *serial) static int cyberjack_port_remove(struct usb_serial_port *port)
{ {
int i; struct cyberjack_private *priv;
for (i = 0; i < serial->num_ports; ++i) priv = usb_get_serial_port_data(port);
usb_kill_urb(serial->port[i]->interrupt_in_urb); kfree(priv);
return 0;
} }
static void cyberjack_release(struct usb_serial *serial) static void cyberjack_disconnect(struct usb_serial *serial)
{ {
int i; int i;
for (i = 0; i < serial->num_ports; ++i) { for (i = 0; i < serial->num_ports; ++i)
/* My special items, the standard routines free my urbs */ usb_kill_urb(serial->port[i]->interrupt_in_urb);
kfree(usb_get_serial_port_data(serial->port[i]));
}
} }
static int cyberjack_open(struct tty_struct *tty, static int cyberjack_open(struct tty_struct *tty,
......
...@@ -123,10 +123,10 @@ struct cypress_private { ...@@ -123,10 +123,10 @@ struct cypress_private {
}; };
/* function prototypes for the Cypress USB to serial device */ /* function prototypes for the Cypress USB to serial device */
static int cypress_earthmate_startup(struct usb_serial *serial); static int cypress_earthmate_port_probe(struct usb_serial_port *port);
static int cypress_hidcom_startup(struct usb_serial *serial); static int cypress_hidcom_port_probe(struct usb_serial_port *port);
static int cypress_ca42v2_startup(struct usb_serial *serial); static int cypress_ca42v2_port_probe(struct usb_serial_port *port);
static void cypress_release(struct usb_serial *serial); static int cypress_port_remove(struct usb_serial_port *port);
static int cypress_open(struct tty_struct *tty, 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_close(struct usb_serial_port *port);
static void cypress_dtr_rts(struct usb_serial_port *port, int on); static void cypress_dtr_rts(struct usb_serial_port *port, int on);
...@@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = { ...@@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = {
.description = "DeLorme Earthmate USB", .description = "DeLorme Earthmate USB",
.id_table = id_table_earthmate, .id_table = id_table_earthmate,
.num_ports = 1, .num_ports = 1,
.attach = cypress_earthmate_startup, .port_probe = cypress_earthmate_port_probe,
.release = cypress_release, .port_remove = cypress_port_remove,
.open = cypress_open, .open = cypress_open,
.close = cypress_close, .close = cypress_close,
.dtr_rts = cypress_dtr_rts, .dtr_rts = cypress_dtr_rts,
...@@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = { ...@@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = {
.description = "HID->COM RS232 Adapter", .description = "HID->COM RS232 Adapter",
.id_table = id_table_cyphidcomrs232, .id_table = id_table_cyphidcomrs232,
.num_ports = 1, .num_ports = 1,
.attach = cypress_hidcom_startup, .port_probe = cypress_hidcom_port_probe,
.release = cypress_release, .port_remove = cypress_port_remove,
.open = cypress_open, .open = cypress_open,
.close = cypress_close, .close = cypress_close,
.dtr_rts = cypress_dtr_rts, .dtr_rts = cypress_dtr_rts,
...@@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = { ...@@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = {
.description = "Nokia CA-42 V2 Adapter", .description = "Nokia CA-42 V2 Adapter",
.id_table = id_table_nokiaca42v2, .id_table = id_table_nokiaca42v2,
.num_ports = 1, .num_ports = 1,
.attach = cypress_ca42v2_startup, .port_probe = cypress_ca42v2_port_probe,
.release = cypress_release, .port_remove = cypress_port_remove,
.open = cypress_open, .open = cypress_open,
.close = cypress_close, .close = cypress_close,
.dtr_rts = cypress_dtr_rts, .dtr_rts = cypress_dtr_rts,
...@@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port) ...@@ -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 cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL); priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
if (!priv) if (!priv)
...@@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial) ...@@ -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 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__); dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1; return ret;
} }
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
...@@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial) ...@@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial)
} }
return 0; 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 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__); dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1; return ret;
} }
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
priv->chiptype = CT_CYPHIDCOM; priv->chiptype = CT_CYPHIDCOM;
return 0; 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 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__); dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1; return ret;
} }
priv = usb_get_serial_port_data(port); priv = usb_get_serial_port_data(port);
priv->chiptype = CT_CA42V2; priv->chiptype = CT_CA42V2;
return 0; 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; struct cypress_private *priv;
/* all open ports are closed at this point */ priv = usb_get_serial_port_data(port);
priv = usb_get_serial_port_data(serial->port[0]);
if (priv) { kfifo_free(&priv->write_fifo);
kfifo_free(&priv->write_fifo); kfree(priv);
kfree(priv);
}
}
return 0;
}
static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port) static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
......
...@@ -318,39 +318,30 @@ static int f81232_ioctl(struct tty_struct *tty, ...@@ -318,39 +318,30 @@ static int f81232_ioctl(struct tty_struct *tty,
return -ENOIOCTLCMD; return -ENOIOCTLCMD;
} }
static int f81232_startup(struct usb_serial *serial) static int f81232_port_probe(struct usb_serial_port *port)
{ {
struct f81232_private *priv; struct f81232_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) { priv = kzalloc(sizeof(*priv), GFP_KERNEL);
priv = kzalloc(sizeof(struct f81232_private), GFP_KERNEL); if (!priv)
if (!priv) return -ENOMEM;
goto cleanup;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(serial->port[i], priv);
}
return 0;
cleanup: spin_lock_init(&priv->lock);
for (--i; i >= 0; --i) { init_waitqueue_head(&priv->delta_msr_wait);
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv); usb_set_serial_port_data(port, priv);
usb_set_serial_port_data(serial->port[i], NULL);
} return 0;
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; struct f81232_private *priv;
for (i = 0; i < serial->num_ports; ++i) { priv = usb_get_serial_port_data(port);
priv = usb_get_serial_port_data(serial->port[i]); kfree(priv);
kfree(priv);
} return 0;
} }
static struct usb_serial_driver f81232_device = { static struct usb_serial_driver f81232_device = {
...@@ -373,8 +364,8 @@ static struct usb_serial_driver f81232_device = { ...@@ -373,8 +364,8 @@ static struct usb_serial_driver f81232_device = {
.tiocmset = f81232_tiocmset, .tiocmset = f81232_tiocmset,
.process_read_urb = f81232_process_read_urb, .process_read_urb = f81232_process_read_urb,
.read_int_callback = f81232_read_int_callback, .read_int_callback = f81232_read_int_callback,
.attach = f81232_startup, .port_probe = f81232_port_probe,
.release = f81232_release, .port_remove = f81232_port_remove,
}; };
static struct usb_serial_driver * const serial_drivers[] = { static struct usb_serial_driver * const serial_drivers[] = {
......
...@@ -1405,11 +1405,10 @@ static void timeout_handler(unsigned long data) ...@@ -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; int status;
struct usb_serial_port *port = serial->port[0]; struct garmin_data *garmin_data_p;
struct garmin_data *garmin_data_p = NULL;
garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL); garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL);
if (garmin_data_p == NULL) { if (garmin_data_p == NULL) {
...@@ -1434,22 +1433,14 @@ static int garmin_attach(struct usb_serial *serial) ...@@ -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); struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
usb_kill_urb(port->interrupt_in_urb); usb_kill_urb(port->interrupt_in_urb);
del_timer_sync(&garmin_data_p->timer); 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); kfree(garmin_data_p);
return 0;
} }
...@@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = { ...@@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = {
.close = garmin_close, .close = garmin_close,
.throttle = garmin_throttle, .throttle = garmin_throttle,
.unthrottle = garmin_unthrottle, .unthrottle = garmin_unthrottle,
.attach = garmin_attach, .port_probe = garmin_port_probe,
.disconnect = garmin_disconnect, .port_remove = garmin_port_remove,
.release = garmin_release,
.write = garmin_write, .write = garmin_write,
.write_room = garmin_write_room, .write_room = garmin_write_room,
.write_bulk_callback = garmin_write_bulk_callback, .write_bulk_callback = garmin_write_bulk_callback,
......
...@@ -225,6 +225,8 @@ static int edge_get_icount(struct tty_struct *tty, ...@@ -225,6 +225,8 @@ static int edge_get_icount(struct tty_struct *tty,
static int edge_startup(struct usb_serial *serial); static int edge_startup(struct usb_serial *serial);
static void edge_disconnect(struct usb_serial *serial); static void edge_disconnect(struct usb_serial *serial);
static void edge_release(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 */ #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) ...@@ -2875,10 +2877,9 @@ static void load_application_firmware(struct edgeport_serial *edge_serial)
static int edge_startup(struct usb_serial *serial) static int edge_startup(struct usb_serial *serial)
{ {
struct edgeport_serial *edge_serial; struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
struct usb_device *dev; struct usb_device *dev;
struct device *ddev = &serial->dev->dev; struct device *ddev = &serial->dev->dev;
int i, j; int i;
int response; int response;
bool interrupt_in_found; bool interrupt_in_found;
bool bulk_in_found; bool bulk_in_found;
...@@ -2961,25 +2962,6 @@ static int edge_startup(struct usb_serial *serial) ...@@ -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, /* we set up the pointers to the endpoints in the edge_open function,
* as the structures aren't created yet. */ * 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; response = 0;
if (edge_serial->is_epic) { if (edge_serial->is_epic) {
...@@ -3120,14 +3102,36 @@ static void edge_disconnect(struct usb_serial *serial) ...@@ -3120,14 +3102,36 @@ static void edge_disconnect(struct usb_serial *serial)
static void edge_release(struct usb_serial *serial) static void edge_release(struct usb_serial *serial)
{ {
struct edgeport_serial *edge_serial = usb_get_serial_data(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); 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_usb_serial_driver(serial_drivers, id_table_combined);
MODULE_AUTHOR(DRIVER_AUTHOR); MODULE_AUTHOR(DRIVER_AUTHOR);
......
...@@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport_2port_device = { ...@@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport_2port_device = {
.attach = edge_startup, .attach = edge_startup,
.disconnect = edge_disconnect, .disconnect = edge_disconnect,
.release = edge_release, .release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget, .tiocmget = edge_tiocmget,
...@@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport_4port_device = { ...@@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport_4port_device = {
.attach = edge_startup, .attach = edge_startup,
.disconnect = edge_disconnect, .disconnect = edge_disconnect,
.release = edge_release, .release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget, .tiocmget = edge_tiocmget,
...@@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport_8port_device = { ...@@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport_8port_device = {
.attach = edge_startup, .attach = edge_startup,
.disconnect = edge_disconnect, .disconnect = edge_disconnect,
.release = edge_release, .release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget, .tiocmget = edge_tiocmget,
...@@ -197,6 +203,8 @@ static struct usb_serial_driver epic_device = { ...@@ -197,6 +203,8 @@ static struct usb_serial_driver epic_device = {
.attach = edge_startup, .attach = edge_startup,
.disconnect = edge_disconnect, .disconnect = edge_disconnect,
.release = edge_release, .release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget, .tiocmget = edge_tiocmget,
......
...@@ -2532,12 +2532,7 @@ static void edge_break(struct tty_struct *tty, int break_state) ...@@ -2532,12 +2532,7 @@ static void edge_break(struct tty_struct *tty, int break_state)
static int edge_startup(struct usb_serial *serial) static int edge_startup(struct usb_serial *serial)
{ {
struct edgeport_serial *edge_serial; struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
struct usb_device *dev;
int status; int status;
int i;
dev = serial->dev;
/* create our private serial structure */ /* create our private serial structure */
edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL); edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
...@@ -2555,40 +2550,7 @@ static int edge_startup(struct usb_serial *serial) ...@@ -2555,40 +2550,7 @@ static int edge_startup(struct usb_serial *serial)
return status; 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; 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) static void edge_disconnect(struct usb_serial *serial)
...@@ -2597,17 +2559,54 @@ 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) static void edge_release(struct usb_serial *serial)
{ {
int i; kfree(usb_get_serial_data(serial));
}
static int edge_port_probe(struct usb_serial_port *port)
{
struct edgeport_port *edge_port; struct edgeport_port *edge_port;
int ret;
for (i = 0; i < serial->num_ports; ++i) { edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL);
edge_port = usb_get_serial_port_data(serial->port[i]); 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); kfifo_free(&edge_port->write_fifo);
kfree(edge_port); kfree(edge_port);
return ret;
} }
kfree(usb_get_serial_data(serial));
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 */ /* Sysfs Attributes */
...@@ -2667,8 +2666,8 @@ static struct usb_serial_driver edgeport_1port_device = { ...@@ -2667,8 +2666,8 @@ static struct usb_serial_driver edgeport_1port_device = {
.attach = edge_startup, .attach = edge_startup,
.disconnect = edge_disconnect, .disconnect = edge_disconnect,
.release = edge_release, .release = edge_release,
.port_probe = edge_create_sysfs_attrs, .port_probe = edge_port_probe,
.port_remove = edge_remove_sysfs_attrs, .port_remove = edge_port_remove,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget, .tiocmget = edge_tiocmget,
...@@ -2698,8 +2697,8 @@ static struct usb_serial_driver edgeport_2port_device = { ...@@ -2698,8 +2697,8 @@ static struct usb_serial_driver edgeport_2port_device = {
.attach = edge_startup, .attach = edge_startup,
.disconnect = edge_disconnect, .disconnect = edge_disconnect,
.release = edge_release, .release = edge_release,
.port_probe = edge_create_sysfs_attrs, .port_probe = edge_port_probe,
.port_remove = edge_remove_sysfs_attrs, .port_remove = edge_port_remove,
.ioctl = edge_ioctl, .ioctl = edge_ioctl,
.set_termios = edge_set_termios, .set_termios = edge_set_termios,
.tiocmget = edge_tiocmget, .tiocmget = edge_tiocmget,
......
...@@ -53,6 +53,8 @@ static int iuu_cardout; ...@@ -53,6 +53,8 @@ static int iuu_cardout;
static bool xmas; static bool xmas;
static int vcc_default = 5; 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); static void read_rxcmd_callback(struct urb *urb);
struct iuu_private { struct iuu_private {
...@@ -72,63 +74,55 @@ struct iuu_private { ...@@ -72,63 +74,55 @@ struct iuu_private {
u32 clk; u32 clk;
}; };
static int iuu_port_probe(struct usb_serial_port *port)
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)
{ {
struct iuu_private *priv; struct iuu_private *priv;
int ret;
priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL); priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL);
dev_dbg(&serial->dev->dev, "%s- priv allocation success\n", __func__);
if (!priv) if (!priv)
return -ENOMEM; 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); kfree(priv);
return -ENOMEM; return -ENOMEM;
} }
priv->vcc = vcc_default; priv->vcc = vcc_default;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait); 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; return 0;
} }
/* Release function */ static int iuu_port_remove(struct usb_serial_port *port)
static void iuu_release(struct usb_serial *serial)
{ {
struct usb_serial_port *port = serial->port[0];
struct iuu_private *priv = usb_get_serial_port_data(port); struct iuu_private *priv = usb_get_serial_port_data(port);
if (!port)
return;
if (priv) { iuu_remove_sysfs_attrs(port);
iuu_free_buf(priv); kfree(priv->writebuf);
dev_dbg(&port->dev, "%s - I will free all\n", __func__); kfree(priv->buf);
usb_set_serial_port_data(port, NULL); 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, static int iuu_tiocmset(struct tty_struct *tty,
...@@ -1215,8 +1209,6 @@ static struct usb_serial_driver iuu_device = { ...@@ -1215,8 +1209,6 @@ static struct usb_serial_driver iuu_device = {
.num_ports = 1, .num_ports = 1,
.bulk_in_size = 512, .bulk_in_size = 512,
.bulk_out_size = 512, .bulk_out_size = 512,
.port_probe = iuu_create_sysfs_attrs,
.port_remove = iuu_remove_sysfs_attrs,
.open = iuu_open, .open = iuu_open,
.close = iuu_close, .close = iuu_close,
.write = iuu_uart_write, .write = iuu_uart_write,
...@@ -1225,8 +1217,8 @@ static struct usb_serial_driver iuu_device = { ...@@ -1225,8 +1217,8 @@ static struct usb_serial_driver iuu_device = {
.tiocmset = iuu_tiocmset, .tiocmset = iuu_tiocmset,
.set_termios = iuu_set_termios, .set_termios = iuu_set_termios,
.init_termios = iuu_init_termios, .init_termios = iuu_init_termios,
.attach = iuu_startup, .port_probe = iuu_port_probe,
.release = iuu_release, .port_remove = iuu_port_remove,
}; };
static struct usb_serial_driver * const serial_drivers[] = { static struct usb_serial_driver * const serial_drivers[] = {
......
...@@ -713,29 +713,33 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw"); ...@@ -713,29 +713,33 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw"); MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
#endif #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; 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); priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
if (!priv) if (!priv)
return 1; /* error */ return -ENOMEM;
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write); INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle); INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
priv->serial = serial; priv->serial = port->serial;
priv->port = serial->port[0]; priv->port = port;
usb_set_serial_port_data(port, priv);
return 0; 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 #ifdef KEYSPAN
...@@ -786,8 +790,8 @@ static struct usb_serial_driver keyspan_pda_device = { ...@@ -786,8 +790,8 @@ static struct usb_serial_driver keyspan_pda_device = {
.break_ctl = keyspan_pda_break_ctl, .break_ctl = keyspan_pda_break_ctl,
.tiocmget = keyspan_pda_tiocmget, .tiocmget = keyspan_pda_tiocmget,
.tiocmset = keyspan_pda_tiocmset, .tiocmset = keyspan_pda_tiocmset,
.attach = keyspan_pda_startup, .port_probe = keyspan_pda_port_probe,
.release = keyspan_pda_release, .port_remove = keyspan_pda_port_remove,
}; };
static struct usb_serial_driver * const serial_drivers[] = { static struct usb_serial_driver * const serial_drivers[] = {
......
...@@ -60,8 +60,8 @@ ...@@ -60,8 +60,8 @@
/* /*
* Function prototypes * Function prototypes
*/ */
static int klsi_105_startup(struct usb_serial *serial); static int klsi_105_port_probe(struct usb_serial_port *port);
static void klsi_105_release(struct usb_serial *serial); 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 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_close(struct usb_serial_port *port);
static void klsi_105_set_termios(struct tty_struct *tty, static void klsi_105_set_termios(struct tty_struct *tty,
...@@ -99,8 +99,8 @@ static struct usb_serial_driver kl5kusb105d_device = { ...@@ -99,8 +99,8 @@ static struct usb_serial_driver kl5kusb105d_device = {
/*.break_ctl = klsi_105_break_ctl,*/ /*.break_ctl = klsi_105_break_ctl,*/
.tiocmget = klsi_105_tiocmget, .tiocmget = klsi_105_tiocmget,
.tiocmset = klsi_105_tiocmset, .tiocmset = klsi_105_tiocmset,
.attach = klsi_105_startup, .port_probe = klsi_105_port_probe,
.release = klsi_105_release, .port_remove = klsi_105_port_remove,
.throttle = usb_serial_generic_throttle, .throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle, .unthrottle = usb_serial_generic_unthrottle,
.process_read_urb = klsi_105_process_read_urb, .process_read_urb = klsi_105_process_read_urb,
...@@ -223,60 +223,40 @@ static int klsi_105_get_line_state(struct usb_serial_port *port, ...@@ -223,60 +223,40 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
* Driver's tty interface functions * 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; struct klsi_105_private *priv;
int i;
/* check if we support the product id (see keyspan.c) priv = kmalloc(sizeof(*priv), GFP_KERNEL);
* FIXME if (!priv)
*/ return -ENOMEM;
/* allocate the private data structure */ /* set initial values for control structures */
for (i = 0; i < serial->num_ports; i++) { priv->cfg.pktlen = 5;
priv = kmalloc(sizeof(struct klsi_105_private), priv->cfg.baudrate = kl5kusb105a_sio_b9600;
GFP_KERNEL); priv->cfg.databits = kl5kusb105a_dtb_8;
if (!priv) { priv->cfg.unknown1 = 0;
dev_dbg(&serial->interface->dev, priv->cfg.unknown2 = 1;
"%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;
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 */ usb_set_serial_port_data(port, priv);
init_waitqueue_head(&serial->port[i]->write_wait);
}
return 0; 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;
priv = usb_get_serial_port_data(port);
kfree(priv);
for (i = 0; i < serial->num_ports; ++i) return 0;
kfree(usb_get_serial_port_data(serial->port[i]));
} }
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port) static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
......
...@@ -54,8 +54,8 @@ ...@@ -54,8 +54,8 @@
/* Function prototypes */ /* Function prototypes */
static int kobil_startup(struct usb_serial *serial); static int kobil_port_probe(struct usb_serial_port *probe);
static void kobil_release(struct usb_serial *serial); static int kobil_port_remove(struct usb_serial_port *probe);
static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port); static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
static void kobil_close(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, static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
...@@ -89,8 +89,8 @@ static struct usb_serial_driver kobil_device = { ...@@ -89,8 +89,8 @@ static struct usb_serial_driver kobil_device = {
.description = "KOBIL USB smart card terminal", .description = "KOBIL USB smart card terminal",
.id_table = id_table, .id_table = id_table,
.num_ports = 1, .num_ports = 1,
.attach = kobil_startup, .port_probe = kobil_port_probe,
.release = kobil_release, .port_remove = kobil_port_remove,
.ioctl = kobil_ioctl, .ioctl = kobil_ioctl,
.set_termios = kobil_set_termios, .set_termios = kobil_set_termios,
.init_termios = kobil_init_termios, .init_termios = kobil_init_termios,
...@@ -117,9 +117,10 @@ struct kobil_private { ...@@ -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; int i;
struct usb_serial *serial = port->serial;
struct kobil_private *priv; struct kobil_private *priv;
struct usb_device *pdev; struct usb_device *pdev;
struct usb_host_config *actconfig; struct usb_host_config *actconfig;
...@@ -149,7 +150,7 @@ static int kobil_startup(struct usb_serial *serial) ...@@ -149,7 +150,7 @@ static int kobil_startup(struct usb_serial *serial)
dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n"); dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n");
break; break;
} }
usb_set_serial_port_data(serial->port[0], priv); usb_set_serial_port_data(port, priv);
/* search for the necessary endpoints */ /* search for the necessary endpoints */
pdev = serial->dev; pdev = serial->dev;
...@@ -179,12 +180,14 @@ static int kobil_startup(struct usb_serial *serial) ...@@ -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) priv = usb_get_serial_port_data(port);
kfree(usb_get_serial_port_data(serial->port[i])); kfree(priv);
return 0;
} }
static void kobil_init_termios(struct tty_struct *tty) static void kobil_init_termios(struct tty_struct *tty)
......
...@@ -503,11 +503,19 @@ static const struct option_blacklist_info net_intf5_blacklist = { ...@@ -503,11 +503,19 @@ static const struct option_blacklist_info net_intf5_blacklist = {
.reserved = BIT(5), .reserved = BIT(5),
}; };
static const struct option_blacklist_info net_intf6_blacklist = {
.reserved = BIT(6),
};
static const struct option_blacklist_info zte_mf626_blacklist = { static const struct option_blacklist_info zte_mf626_blacklist = {
.sendsetup = BIT(0) | BIT(1), .sendsetup = BIT(0) | BIT(1),
.reserved = BIT(4), .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[] = { static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_COLT) },
{ USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) }, { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_RICOLA) },
...@@ -853,13 +861,19 @@ static const struct usb_device_id option_ids[] = { ...@@ -853,13 +861,19 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0113, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf5_blacklist }, .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, 0x0117, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0118, 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) }, .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, 0x0122, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0123, 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) }, .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0125, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0124, 0xff, 0xff, 0xff),
{ 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, 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, 0x0128, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0142, 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) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0143, 0xff, 0xff, 0xff) },
...@@ -872,7 +886,8 @@ static const struct usb_device_id option_ids[] = { ...@@ -872,7 +886,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, 0x0156, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0157, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf5_blacklist }, .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, 0x0159, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0161, 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) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0162, 0xff, 0xff, 0xff) },
...@@ -880,13 +895,22 @@ static const struct usb_device_id option_ids[] = { ...@@ -880,13 +895,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, 0x0165, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0167, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist }, .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), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0326, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist }, .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1008, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist }, .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf4_blacklist }, .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, 0x1057, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 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) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) },
...@@ -1002,18 +1026,24 @@ static const struct usb_device_id option_ids[] = { ...@@ -1002,18 +1026,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, 0x1169, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1170, 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, 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, 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, 0x1248, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1249, 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, 0x1250, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1251, 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, 0x1253, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1254, 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) }, .driver_info = (kernel_ulong_t)&net_intf4_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1256, 0xff, 0xff, 0xff) }, { 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, 0x1257, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1258, 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) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1259, 0xff, 0xff, 0xff) },
...@@ -1058,8 +1088,16 @@ static const struct usb_device_id option_ids[] = { ...@@ -1058,8 +1088,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, 0x1298, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1299, 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, 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), { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1402, 0xff, 0xff, 0xff),
.driver_info = (kernel_ulong_t)&net_intf2_blacklist }, .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, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2002, 0xff,
0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist }, 0xff, 0xff), .driver_info = (kernel_ulong_t)&zte_k3765_z_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x2003, 0xff, 0xff, 0xff) },
...@@ -1071,15 +1109,21 @@ static const struct usb_device_id option_ids[] = { ...@@ -1071,15 +1109,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, 0x0070, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0073, 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, 0x0094, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0130, 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) }, .driver_info = (kernel_ulong_t)&net_intf1_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0141, 0xff, 0xff, 0xff) }, { 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, 0x0147, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0152, 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, 0x0170, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x0176, 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) }, .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_CDMA_TECH, 0xff, 0xff, 0xff) },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) }, { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_AC8710, 0xff, 0xff, 0xff) },
......
...@@ -137,8 +137,8 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty); ...@@ -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_tiocmget(struct tty_struct *tty);
static int oti6858_tiocmset(struct tty_struct *tty, static int oti6858_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear); unsigned int set, unsigned int clear);
static int oti6858_startup(struct usb_serial *serial); static int oti6858_port_probe(struct usb_serial_port *port);
static void oti6858_release(struct usb_serial *serial); static int oti6858_port_remove(struct usb_serial_port *port);
/* device info */ /* device info */
static struct usb_serial_driver oti6858_device = { static struct usb_serial_driver oti6858_device = {
...@@ -161,8 +161,8 @@ 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_bulk_callback = oti6858_write_bulk_callback,
.write_room = oti6858_write_room, .write_room = oti6858_write_room,
.chars_in_buffer = oti6858_chars_in_buffer, .chars_in_buffer = oti6858_chars_in_buffer,
.attach = oti6858_startup, .port_probe = oti6858_port_probe,
.release = oti6858_release, .port_remove = oti6858_port_remove,
}; };
static struct usb_serial_driver * const serial_drivers[] = { static struct usb_serial_driver * const serial_drivers[] = {
...@@ -331,36 +331,33 @@ static void send_data(struct work_struct *work) ...@@ -331,36 +331,33 @@ static void send_data(struct work_struct *work)
usb_serial_port_softint(port); 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; 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;
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);
usb_set_serial_port_data(serial->port[i], priv);
}
if (i == serial->num_ports)
return 0;
for (--i; i >= 0; --i) { priv = kzalloc(sizeof(*priv), GFP_KERNEL);
priv = usb_get_serial_port_data(serial->port[i]); if (!priv)
kfree(priv); return -ENOMEM;
usb_set_serial_port_data(serial->port[i], NULL);
} spin_lock_init(&priv->lock);
return -ENOMEM; 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(port, priv);
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, 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, ...@@ -709,15 +706,6 @@ static int oti6858_ioctl(struct tty_struct *tty,
return -ENOIOCTLCMD; 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) static void oti6858_read_int_callback(struct urb *urb)
{ {
struct usb_serial_port *port = urb->context; struct usb_serial_port *port = urb->context;
......
...@@ -133,12 +133,15 @@ enum pl2303_type { ...@@ -133,12 +133,15 @@ enum pl2303_type {
HX, /* HX version of the pl2303 chip */ HX, /* HX version of the pl2303 chip */
}; };
struct pl2303_serial_private {
enum pl2303_type type;
};
struct pl2303_private { struct pl2303_private {
spinlock_t lock; spinlock_t lock;
wait_queue_head_t delta_msr_wait; wait_queue_head_t delta_msr_wait;
u8 line_control; u8 line_control;
u8 line_status; u8 line_status;
enum pl2303_type type;
}; };
static int pl2303_vendor_read(__u16 value, __u16 index, static int pl2303_vendor_read(__u16 value, __u16 index,
...@@ -167,14 +170,19 @@ static int pl2303_vendor_write(__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) static int pl2303_startup(struct usb_serial *serial)
{ {
struct pl2303_private *priv; struct pl2303_serial_private *spriv;
enum pl2303_type type = type_0; enum pl2303_type type = type_0;
unsigned char *buf; unsigned char *buf;
int i;
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
if (!spriv)
return -ENOMEM;
buf = kmalloc(10, GFP_KERNEL); buf = kmalloc(10, GFP_KERNEL);
if (buf == NULL) if (!buf) {
kfree(spriv);
return -ENOMEM; return -ENOMEM;
}
if (serial->dev->descriptor.bDeviceClass == 0x02) if (serial->dev->descriptor.bDeviceClass == 0x02)
type = type_0; type = type_0;
...@@ -186,15 +194,8 @@ static int pl2303_startup(struct usb_serial *serial) ...@@ -186,15 +194,8 @@ static int pl2303_startup(struct usb_serial *serial)
type = type_1; type = type_1;
dev_dbg(&serial->interface->dev, "device type: %d\n", type); dev_dbg(&serial->interface->dev, "device type: %d\n", type);
for (i = 0; i < serial->num_ports; ++i) { spriv->type = type;
priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL); usb_set_serial_data(serial, spriv);
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);
}
pl2303_vendor_read(0x8484, 0, serial, buf); pl2303_vendor_read(0x8484, 0, serial, buf);
pl2303_vendor_write(0x0404, 0, serial); pl2303_vendor_write(0x0404, 0, serial);
...@@ -213,15 +214,40 @@ static int pl2303_startup(struct usb_serial *serial) ...@@ -213,15 +214,40 @@ static int pl2303_startup(struct usb_serial *serial)
kfree(buf); kfree(buf);
return 0; return 0;
}
cleanup: static void pl2303_release(struct usb_serial *serial)
kfree(buf); {
for (--i; i >= 0; --i) { struct pl2303_serial_private *spriv;
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv); spriv = usb_get_serial_data(serial);
usb_set_serial_port_data(serial->port[i], NULL); kfree(spriv);
} }
return -ENOMEM;
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) static int set_control_lines(struct usb_device *dev, u8 value)
...@@ -240,6 +266,7 @@ static void pl2303_set_termios(struct tty_struct *tty, ...@@ -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_port *port, struct ktermios *old_termios)
{ {
struct usb_serial *serial = port->serial; 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); struct pl2303_private *priv = usb_get_serial_port_data(port);
unsigned long flags; unsigned long flags;
unsigned int cflag; unsigned int cflag;
...@@ -323,7 +350,7 @@ static void pl2303_set_termios(struct tty_struct *tty, ...@@ -323,7 +350,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
} }
if (baud > 1228800) { if (baud > 1228800) {
/* type_0, type_1 only support up to 1228800 baud */ /* type_0, type_1 only support up to 1228800 baud */
if (priv->type != HX) if (spriv->type != HX)
baud = 1228800; baud = 1228800;
else if (baud > 6000000) else if (baud > 6000000)
baud = 6000000; baud = 6000000;
...@@ -426,7 +453,7 @@ static void pl2303_set_termios(struct tty_struct *tty, ...@@ -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]); buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
if (cflag & CRTSCTS) { if (cflag & CRTSCTS) {
if (priv->type == HX) if (spriv->type == HX)
pl2303_vendor_write(0x0, 0x61, serial); pl2303_vendor_write(0x0, 0x61, serial);
else else
pl2303_vendor_write(0x0, 0x41, serial); pl2303_vendor_write(0x0, 0x41, serial);
...@@ -468,10 +495,10 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port) ...@@ -468,10 +495,10 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
struct ktermios tmp_termios; struct ktermios tmp_termios;
struct usb_serial *serial = port->serial; 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; 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->write_urb->pipe);
usb_clear_halt(serial->dev, port->read_urb->pipe); usb_clear_halt(serial->dev, port->read_urb->pipe);
} else { } else {
...@@ -655,17 +682,6 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state) ...@@ -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); 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, static void pl2303_update_line_status(struct usb_serial_port *port,
unsigned char *data, unsigned char *data,
unsigned int actual_length) unsigned int actual_length)
...@@ -827,6 +843,8 @@ static struct usb_serial_driver pl2303_device = { ...@@ -827,6 +843,8 @@ static struct usb_serial_driver pl2303_device = {
.read_int_callback = pl2303_read_int_callback, .read_int_callback = pl2303_read_int_callback,
.attach = pl2303_startup, .attach = pl2303_startup,
.release = pl2303_release, .release = pl2303_release,
.port_probe = pl2303_port_probe,
.port_remove = pl2303_port_remove,
}; };
static struct usb_serial_driver * const serial_drivers[] = { static struct usb_serial_driver * const serial_drivers[] = {
......
...@@ -157,13 +157,10 @@ struct spcp8x5_private { ...@@ -157,13 +157,10 @@ struct spcp8x5_private {
u8 line_status; u8 line_status;
}; };
/* desc : when device plug in,this function would be called. static int spcp8x5_port_probe(struct usb_serial_port *port)
* 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)
{ {
struct usb_serial *serial = port->serial;
struct spcp8x5_private *priv; struct spcp8x5_private *priv;
int i;
enum spcp8x5_type type = SPCP825_007_TYPE; enum spcp8x5_type type = SPCP825_007_TYPE;
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct); u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
...@@ -180,34 +177,27 @@ static int spcp8x5_startup(struct usb_serial *serial) ...@@ -180,34 +177,27 @@ static int spcp8x5_startup(struct usb_serial *serial)
type = SPCP825_PHILIP_TYPE; type = SPCP825_PHILIP_TYPE;
dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type); dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type);
for (i = 0; i < serial->num_ports; ++i) { priv = kzalloc(sizeof(*priv), GFP_KERNEL);
priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL); if (!priv)
if (!priv) return -ENOMEM;
goto cleanup;
spin_lock_init(&priv->lock); spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait); init_waitqueue_head(&priv->delta_msr_wait);
priv->type = type; priv->type = type;
usb_set_serial_port_data(serial->port[i] , priv);
} usb_set_serial_port_data(port , priv);
return 0; 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 int spcp8x5_port_remove(struct usb_serial_port *port)
static void spcp8x5_release(struct usb_serial *serial)
{ {
int i; struct spcp8x5_private *priv;
for (i = 0; i < serial->num_ports; i++) priv = usb_get_serial_port_data(port);
kfree(usb_get_serial_port_data(serial->port[i])); kfree(priv);
return 0;
} }
/* set the modem control line of the device. /* set the modem control line of the device.
...@@ -649,8 +639,8 @@ static struct usb_serial_driver spcp8x5_device = { ...@@ -649,8 +639,8 @@ static struct usb_serial_driver spcp8x5_device = {
.ioctl = spcp8x5_ioctl, .ioctl = spcp8x5_ioctl,
.tiocmget = spcp8x5_tiocmget, .tiocmget = spcp8x5_tiocmget,
.tiocmset = spcp8x5_tiocmset, .tiocmset = spcp8x5_tiocmset,
.attach = spcp8x5_startup, .port_probe = spcp8x5_port_probe,
.release = spcp8x5_release, .port_remove = spcp8x5_port_remove,
.process_read_urb = spcp8x5_process_read_urb, .process_read_urb = spcp8x5_process_read_urb,
}; };
......
...@@ -67,13 +67,6 @@ struct ssu100_port_private { ...@@ -67,13 +67,6 @@ struct ssu100_port_private {
struct async_icount icount; 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, static inline int ssu100_control_msg(struct usb_device *dev,
u8 request, u16 data, u16 index) u8 request, u16 data, u16 index)
{ {
...@@ -441,22 +434,34 @@ static int ssu100_ioctl(struct tty_struct *tty, ...@@ -441,22 +434,34 @@ static int ssu100_ioctl(struct tty_struct *tty,
} }
static int ssu100_attach(struct usb_serial *serial) 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 ssu100_port_private *priv;
struct usb_serial_port *port = *serial->port;
priv = kzalloc(sizeof(*priv), GFP_KERNEL); priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) { if (!priv)
dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
sizeof(*priv));
return -ENOMEM; return -ENOMEM;
}
spin_lock_init(&priv->status_lock); spin_lock_init(&priv->status_lock);
init_waitqueue_head(&priv->delta_msr_wait); init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv); 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) static int ssu100_tiocmget(struct tty_struct *tty)
...@@ -647,7 +652,8 @@ static struct usb_serial_driver ssu100_device = { ...@@ -647,7 +652,8 @@ static struct usb_serial_driver ssu100_device = {
.open = ssu100_open, .open = ssu100_open,
.close = ssu100_close, .close = ssu100_close,
.attach = ssu100_attach, .attach = ssu100_attach,
.release = ssu100_release, .port_probe = ssu100_port_probe,
.port_remove = ssu100_port_remove,
.dtr_rts = ssu100_dtr_rts, .dtr_rts = ssu100_dtr_rts,
.process_read_urb = ssu100_process_read_urb, .process_read_urb = ssu100_process_read_urb,
.tiocmget = ssu100_tiocmget, .tiocmget = ssu100_tiocmget,
......
...@@ -97,6 +97,8 @@ struct ti_device { ...@@ -97,6 +97,8 @@ struct ti_device {
static int ti_startup(struct usb_serial *serial); static int ti_startup(struct usb_serial *serial);
static void ti_release(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 int ti_open(struct tty_struct *tty, struct usb_serial_port *port);
static void ti_close(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, 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 = { ...@@ -221,6 +223,8 @@ static struct usb_serial_driver ti_1port_device = {
.num_ports = 1, .num_ports = 1,
.attach = ti_startup, .attach = ti_startup,
.release = ti_release, .release = ti_release,
.port_probe = ti_port_probe,
.port_remove = ti_port_remove,
.open = ti_open, .open = ti_open,
.close = ti_close, .close = ti_close,
.write = ti_write, .write = ti_write,
...@@ -249,6 +253,8 @@ static struct usb_serial_driver ti_2port_device = { ...@@ -249,6 +253,8 @@ static struct usb_serial_driver ti_2port_device = {
.num_ports = 2, .num_ports = 2,
.attach = ti_startup, .attach = ti_startup,
.release = ti_release, .release = ti_release,
.port_probe = ti_port_probe,
.port_remove = ti_port_remove,
.open = ti_open, .open = ti_open,
.close = ti_close, .close = ti_close,
.write = ti_write, .write = ti_write,
...@@ -347,11 +353,8 @@ module_exit(ti_exit); ...@@ -347,11 +353,8 @@ module_exit(ti_exit);
static int ti_startup(struct usb_serial *serial) static int ti_startup(struct usb_serial *serial)
{ {
struct ti_device *tdev; struct ti_device *tdev;
struct ti_port *tport;
struct usb_device *dev = serial->dev; struct usb_device *dev = serial->dev;
int status; int status;
int i;
dev_dbg(&dev->dev, dev_dbg(&dev->dev,
"%s - product 0x%4X, num configurations %d, configuration value %d", "%s - product 0x%4X, num configurations %d, configuration value %d",
...@@ -399,42 +402,8 @@ static int ti_startup(struct usb_serial *serial) ...@@ -399,42 +402,8 @@ static int ti_startup(struct usb_serial *serial)
goto free_tdev; 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; 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: free_tdev:
kfree(tdev); kfree(tdev);
usb_set_serial_data(serial, NULL); usb_set_serial_data(serial, NULL);
...@@ -444,21 +413,50 @@ static int ti_startup(struct usb_serial *serial) ...@@ -444,21 +413,50 @@ static int ti_startup(struct usb_serial *serial)
static void ti_release(struct usb_serial *serial) static void ti_release(struct usb_serial *serial)
{ {
int i;
struct ti_device *tdev = usb_get_serial_data(serial); struct ti_device *tdev = usb_get_serial_data(serial);
kfree(tdev);
}
static int ti_port_probe(struct usb_serial_port *port)
{
struct ti_port *tport; struct ti_port *tport;
for (i = 0; i < serial->num_ports; ++i) { tport = kzalloc(sizeof(*tport), GFP_KERNEL);
tport = usb_get_serial_port_data(serial->port[i]); if (!tport)
if (tport) { return -ENOMEM;
kfifo_free(&tport->write_fifo);
kfree(tport); 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 */
kfree(tdev); 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) static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)
{ {
......
...@@ -1778,17 +1778,6 @@ static inline int usb_translate_errors(int error_code) ...@@ -1778,17 +1778,6 @@ static inline int usb_translate_errors(int error_code)
extern void usb_register_notify(struct notifier_block *nb); extern void usb_register_notify(struct notifier_block *nb);
extern void usb_unregister_notify(struct notifier_block *nb); extern void usb_unregister_notify(struct notifier_block *nb);
#ifdef DEBUG
#define dbg(format, arg...) \
printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg)
#else
#define dbg(format, arg...) \
do { \
if (0) \
printk(KERN_DEBUG "%s: " format "\n", __FILE__, ##arg); \
} while (0)
#endif
/* debugfs stuff */ /* debugfs stuff */
extern struct dentry *usb_debug_root; extern struct dentry *usb_debug_root;
......
header-y += audio.h
header-y += cdc.h
header-y += ch9.h
header-y += ch11.h
header-y += functionfs.h
header-y += gadgetfs.h
header-y += midi.h
header-y += g_printer.h
header-y += tmc.h
header-y += video.h
...@@ -17,531 +17,11 @@ ...@@ -17,531 +17,11 @@
* Types and defines in this file are either specific to version 1.0 of * Types and defines in this file are either specific to version 1.0 of
* this standard or common for newer versions. * this standard or common for newer versions.
*/ */
#ifndef __LINUX_USB_AUDIO_H #ifndef __LINUX_USB_AUDIO_H
#define __LINUX_USB_AUDIO_H #define __LINUX_USB_AUDIO_H
#include <linux/types.h> #include <uapi/linux/usb/audio.h>
/* bInterfaceProtocol values to denote the version of the standard used */
#define UAC_VERSION_1 0x00
#define UAC_VERSION_2 0x20
/* A.2 Audio Interface Subclass Codes */
#define USB_SUBCLASS_AUDIOCONTROL 0x01
#define USB_SUBCLASS_AUDIOSTREAMING 0x02
#define USB_SUBCLASS_MIDISTREAMING 0x03
/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
#define UAC_HEADER 0x01
#define UAC_INPUT_TERMINAL 0x02
#define UAC_OUTPUT_TERMINAL 0x03
#define UAC_MIXER_UNIT 0x04
#define UAC_SELECTOR_UNIT 0x05
#define UAC_FEATURE_UNIT 0x06
#define UAC1_PROCESSING_UNIT 0x07
#define UAC1_EXTENSION_UNIT 0x08
/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
#define UAC_AS_GENERAL 0x01
#define UAC_FORMAT_TYPE 0x02
#define UAC_FORMAT_SPECIFIC 0x03
/* A.7 Processing Unit Process Types */
#define UAC_PROCESS_UNDEFINED 0x00
#define UAC_PROCESS_UP_DOWNMIX 0x01
#define UAC_PROCESS_DOLBY_PROLOGIC 0x02
#define UAC_PROCESS_STEREO_EXTENDER 0x03
#define UAC_PROCESS_REVERB 0x04
#define UAC_PROCESS_CHORUS 0x05
#define UAC_PROCESS_DYN_RANGE_COMP 0x06
/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */
#define UAC_EP_GENERAL 0x01
/* A.9 Audio Class-Specific Request Codes */
#define UAC_SET_ 0x00
#define UAC_GET_ 0x80
#define UAC__CUR 0x1
#define UAC__MIN 0x2
#define UAC__MAX 0x3
#define UAC__RES 0x4
#define UAC__MEM 0x5
#define UAC_SET_CUR (UAC_SET_ | UAC__CUR)
#define UAC_GET_CUR (UAC_GET_ | UAC__CUR)
#define UAC_SET_MIN (UAC_SET_ | UAC__MIN)
#define UAC_GET_MIN (UAC_GET_ | UAC__MIN)
#define UAC_SET_MAX (UAC_SET_ | UAC__MAX)
#define UAC_GET_MAX (UAC_GET_ | UAC__MAX)
#define UAC_SET_RES (UAC_SET_ | UAC__RES)
#define UAC_GET_RES (UAC_GET_ | UAC__RES)
#define UAC_SET_MEM (UAC_SET_ | UAC__MEM)
#define UAC_GET_MEM (UAC_GET_ | UAC__MEM)
#define UAC_GET_STAT 0xff
/* A.10 Control Selector Codes */
/* A.10.1 Terminal Control Selectors */
#define UAC_TERM_COPY_PROTECT 0x01
/* A.10.2 Feature Unit Control Selectors */
#define UAC_FU_MUTE 0x01
#define UAC_FU_VOLUME 0x02
#define UAC_FU_BASS 0x03
#define UAC_FU_MID 0x04
#define UAC_FU_TREBLE 0x05
#define UAC_FU_GRAPHIC_EQUALIZER 0x06
#define UAC_FU_AUTOMATIC_GAIN 0x07
#define UAC_FU_DELAY 0x08
#define UAC_FU_BASS_BOOST 0x09
#define UAC_FU_LOUDNESS 0x0a
#define UAC_CONTROL_BIT(CS) (1 << ((CS) - 1))
/* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */
#define UAC_UD_ENABLE 0x01
#define UAC_UD_MODE_SELECT 0x02
/* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */
#define UAC_DP_ENABLE 0x01
#define UAC_DP_MODE_SELECT 0x02
/* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */
#define UAC_3D_ENABLE 0x01
#define UAC_3D_SPACE 0x02
/* A.10.3.4 Reverberation Processing Unit Control Selectors */
#define UAC_REVERB_ENABLE 0x01
#define UAC_REVERB_LEVEL 0x02
#define UAC_REVERB_TIME 0x03
#define UAC_REVERB_FEEDBACK 0x04
/* A.10.3.5 Chorus Processing Unit Control Selectors */
#define UAC_CHORUS_ENABLE 0x01
#define UAC_CHORUS_LEVEL 0x02
#define UAC_CHORUS_RATE 0x03
#define UAC_CHORUS_DEPTH 0x04
/* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */
#define UAC_DCR_ENABLE 0x01
#define UAC_DCR_RATE 0x02
#define UAC_DCR_MAXAMPL 0x03
#define UAC_DCR_THRESHOLD 0x04
#define UAC_DCR_ATTACK_TIME 0x05
#define UAC_DCR_RELEASE_TIME 0x06
/* A.10.4 Extension Unit Control Selectors */
#define UAC_XU_ENABLE 0x01
/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
#define UAC_MS_HEADER 0x01
#define UAC_MIDI_IN_JACK 0x02
#define UAC_MIDI_OUT_JACK 0x03
/* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */
#define UAC_MS_GENERAL 0x01
/* Terminals - 2.1 USB Terminal Types */
#define UAC_TERMINAL_UNDEFINED 0x100
#define UAC_TERMINAL_STREAMING 0x101
#define UAC_TERMINAL_VENDOR_SPEC 0x1FF
/* Terminal Control Selectors */
/* 4.3.2 Class-Specific AC Interface Descriptor */
struct uac1_ac_header_descriptor {
__u8 bLength; /* 8 + n */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* UAC_MS_HEADER */
__le16 bcdADC; /* 0x0100 */
__le16 wTotalLength; /* includes Unit and Terminal desc. */
__u8 bInCollection; /* n */
__u8 baInterfaceNr[]; /* [n] */
} __attribute__ ((packed));
#define UAC_DT_AC_HEADER_SIZE(n) (8 + (n))
/* As above, but more useful for defining your own descriptors: */
#define DECLARE_UAC_AC_HEADER_DESCRIPTOR(n) \
struct uac1_ac_header_descriptor_##n { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubtype; \
__le16 bcdADC; \
__le16 wTotalLength; \
__u8 bInCollection; \
__u8 baInterfaceNr[n]; \
} __attribute__ ((packed))
/* 4.3.2.1 Input Terminal Descriptor */
struct uac_input_terminal_descriptor {
__u8 bLength; /* in bytes: 12 */
__u8 bDescriptorType; /* CS_INTERFACE descriptor type */
__u8 bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */
__u8 bTerminalID; /* Constant uniquely terminal ID */
__le16 wTerminalType; /* USB Audio Terminal Types */
__u8 bAssocTerminal; /* ID of the Output Terminal associated */
__u8 bNrChannels; /* Number of logical output channels */
__le16 wChannelConfig;
__u8 iChannelNames;
__u8 iTerminal;
} __attribute__ ((packed));
#define UAC_DT_INPUT_TERMINAL_SIZE 12
/* Terminals - 2.2 Input Terminal Types */
#define UAC_INPUT_TERMINAL_UNDEFINED 0x200
#define UAC_INPUT_TERMINAL_MICROPHONE 0x201
#define UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE 0x202
#define UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE 0x203
#define UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE 0x204
#define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY 0x205
#define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 0x206
/* Terminals - control selectors */
#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL 0x01
/* 4.3.2.2 Output Terminal Descriptor */
struct uac1_output_terminal_descriptor {
__u8 bLength; /* in bytes: 9 */
__u8 bDescriptorType; /* CS_INTERFACE descriptor type */
__u8 bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */
__u8 bTerminalID; /* Constant uniquely terminal ID */
__le16 wTerminalType; /* USB Audio Terminal Types */
__u8 bAssocTerminal; /* ID of the Input Terminal associated */
__u8 bSourceID; /* ID of the connected Unit or Terminal*/
__u8 iTerminal;
} __attribute__ ((packed));
#define UAC_DT_OUTPUT_TERMINAL_SIZE 9
/* Terminals - 2.3 Output Terminal Types */
#define UAC_OUTPUT_TERMINAL_UNDEFINED 0x300
#define UAC_OUTPUT_TERMINAL_SPEAKER 0x301
#define UAC_OUTPUT_TERMINAL_HEADPHONES 0x302
#define UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x303
#define UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER 0x304
#define UAC_OUTPUT_TERMINAL_ROOM_SPEAKER 0x305
#define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306
#define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307
/* Set bControlSize = 2 as default setting */
#define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2)
/* As above, but more useful for defining your own descriptors: */
#define DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(ch) \
struct uac_feature_unit_descriptor_##ch { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubtype; \
__u8 bUnitID; \
__u8 bSourceID; \
__u8 bControlSize; \
__le16 bmaControls[ch + 1]; \
__u8 iFeature; \
} __attribute__ ((packed))
/* 4.3.2.3 Mixer Unit Descriptor */
struct uac_mixer_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
{
return desc->baSourceID[desc->bNrInPins];
}
static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
if (protocol == UAC_VERSION_1)
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
desc->baSourceID[desc->bNrInPins + 1];
else
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
(desc->baSourceID[desc->bNrInPins + 1]);
}
static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 3] :
desc->baSourceID[desc->bNrInPins + 5];
}
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
&desc->baSourceID[desc->bNrInPins + 4] :
&desc->baSourceID[desc->bNrInPins + 6];
}
static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.4 Selector Unit Descriptor */
struct uac_selector_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUintID;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.5 Feature Unit Descriptor */
struct uac_feature_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u8 bSourceID;
__u8 bControlSize;
__u8 bmaControls[0]; /* variable length */
} __attribute__((packed));
static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.6 Processing Unit Descriptors */
struct uac_processing_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u16 wProcessType;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
{
return desc->baSourceID[desc->bNrInPins];
}
static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
int protocol)
{
if (protocol == UAC_VERSION_1)
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
desc->baSourceID[desc->bNrInPins + 1];
else
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
(desc->baSourceID[desc->bNrInPins + 1]);
}
static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 3] :
desc->baSourceID[desc->bNrInPins + 5];
}
static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 4] :
desc->baSourceID[desc->bNrInPins + 6];
}
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
&desc->baSourceID[desc->bNrInPins + 5] :
&desc->baSourceID[desc->bNrInPins + 7];
}
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
int protocol)
{
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
return desc->baSourceID[desc->bNrInPins + control_size];
}
static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
int protocol)
{
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
return &desc->baSourceID[desc->bNrInPins + control_size + 1];
}
/* 4.5.2 Class-Specific AS Interface Descriptor */
struct uac1_as_header_descriptor {
__u8 bLength; /* in bytes: 7 */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* AS_GENERAL */
__u8 bTerminalLink; /* Terminal ID of connected Terminal */
__u8 bDelay; /* Delay introduced by the data path */
__le16 wFormatTag; /* The Audio Data Format */
} __attribute__ ((packed));
#define UAC_DT_AS_HEADER_SIZE 7
/* Formats - A.1.1 Audio Data Format Type I Codes */
#define UAC_FORMAT_TYPE_I_UNDEFINED 0x0
#define UAC_FORMAT_TYPE_I_PCM 0x1
#define UAC_FORMAT_TYPE_I_PCM8 0x2
#define UAC_FORMAT_TYPE_I_IEEE_FLOAT 0x3
#define UAC_FORMAT_TYPE_I_ALAW 0x4
#define UAC_FORMAT_TYPE_I_MULAW 0x5
struct uac_format_type_i_continuous_descriptor {
__u8 bLength; /* in bytes: 8 + (ns * 3) */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* FORMAT_TYPE */
__u8 bFormatType; /* FORMAT_TYPE_1 */
__u8 bNrChannels; /* physical channels in the stream */
__u8 bSubframeSize; /* */
__u8 bBitResolution;
__u8 bSamFreqType;
__u8 tLowerSamFreq[3];
__u8 tUpperSamFreq[3];
} __attribute__ ((packed));
#define UAC_FORMAT_TYPE_I_CONTINUOUS_DESC_SIZE 14
struct uac_format_type_i_discrete_descriptor {
__u8 bLength; /* in bytes: 8 + (ns * 3) */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* FORMAT_TYPE */
__u8 bFormatType; /* FORMAT_TYPE_1 */
__u8 bNrChannels; /* physical channels in the stream */
__u8 bSubframeSize; /* */
__u8 bBitResolution;
__u8 bSamFreqType;
__u8 tSamFreq[][3];
} __attribute__ ((packed));
#define DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(n) \
struct uac_format_type_i_discrete_descriptor_##n { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubtype; \
__u8 bFormatType; \
__u8 bNrChannels; \
__u8 bSubframeSize; \
__u8 bBitResolution; \
__u8 bSamFreqType; \
__u8 tSamFreq[n][3]; \
} __attribute__ ((packed))
#define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3))
struct uac_format_type_i_ext_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
__u8 bSubslotSize;
__u8 bBitResolution;
__u8 bHeaderLength;
__u8 bControlSize;
__u8 bSideBandProtocol;
} __attribute__((packed));
/* Formats - Audio Data Format Type I Codes */
#define UAC_FORMAT_TYPE_II_MPEG 0x1001
#define UAC_FORMAT_TYPE_II_AC3 0x1002
struct uac_format_type_ii_discrete_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
__le16 wMaxBitRate;
__le16 wSamplesPerFrame;
__u8 bSamFreqType;
__u8 tSamFreq[][3];
} __attribute__((packed));
struct uac_format_type_ii_ext_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
__u16 wMaxBitRate;
__u16 wSamplesPerFrame;
__u8 bHeaderLength;
__u8 bSideBandProtocol;
} __attribute__((packed));
/* type III */
#define UAC_FORMAT_TYPE_III_IEC1937_AC3 0x2001
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG1_LAYER1 0x2002
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_NOEXT 0x2003
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_EXT 0x2004
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER1_LS 0x2005
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER23_LS 0x2006
/* Formats - A.2 Format Type Codes */
#define UAC_FORMAT_TYPE_UNDEFINED 0x0
#define UAC_FORMAT_TYPE_I 0x1
#define UAC_FORMAT_TYPE_II 0x2
#define UAC_FORMAT_TYPE_III 0x3
#define UAC_EXT_FORMAT_TYPE_I 0x81
#define UAC_EXT_FORMAT_TYPE_II 0x82
#define UAC_EXT_FORMAT_TYPE_III 0x83
struct uac_iso_endpoint_descriptor {
__u8 bLength; /* in bytes: 7 */
__u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */
__u8 bDescriptorSubtype; /* EP_GENERAL */
__u8 bmAttributes;
__u8 bLockDelayUnits;
__le16 wLockDelay;
} __attribute__((packed));
#define UAC_ISO_ENDPOINT_DESC_SIZE 7
#define UAC_EP_CS_ATTR_SAMPLE_RATE 0x01
#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
#define UAC_EP_CS_ATTR_FILL_MAX 0x80
/* status word format (3.7.1.1) */
#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f
#define UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF 0x0
#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_IF 0x1
#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_EP 0x2
#define UAC1_STATUS_TYPE_IRQ_PENDING (1 << 7)
#define UAC1_STATUS_TYPE_MEM_CHANGED (1 << 6)
struct uac1_status_word {
__u8 bStatusType;
__u8 bOriginator;
} __attribute__((packed));
#ifdef __KERNEL__
struct usb_audio_control { struct usb_audio_control {
struct list_head list; struct list_head list;
...@@ -561,6 +41,4 @@ struct usb_audio_control_selector { ...@@ -561,6 +41,4 @@ struct usb_audio_control_selector {
struct usb_descriptor_header *desc; struct usb_descriptor_header *desc;
}; };
#endif /* __KERNEL__ */
#endif /* __LINUX_USB_AUDIO_H */ #endif /* __LINUX_USB_AUDIO_H */
此差异已折叠。
#ifndef __LINUX_FUNCTIONFS_H__ #ifndef __LINUX_FUNCTIONFS_H__
#define __LINUX_FUNCTIONFS_H__ 1 #define __LINUX_FUNCTIONFS_H__ 1
#include <uapi/linux/usb/functionfs.h>
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/usb/ch9.h>
enum {
FUNCTIONFS_DESCRIPTORS_MAGIC = 1,
FUNCTIONFS_STRINGS_MAGIC = 2
};
#ifndef __KERNEL__
/* Descriptor of an non-audio endpoint */
struct usb_endpoint_descriptor_no_audio {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
} __attribute__((packed));
/*
* All numbers must be in little endian order.
*/
struct usb_functionfs_descs_head {
__le32 magic;
__le32 length;
__le32 fs_count;
__le32 hs_count;
} __attribute__((packed));
/*
* Descriptors format:
*
* | off | name | type | description |
* |-----+-----------+--------------+--------------------------------------|
* | 0 | magic | LE32 | FUNCTIONFS_{FS,HS}_DESCRIPTORS_MAGIC |
* | 4 | length | LE32 | length of the whole data chunk |
* | 8 | fs_count | LE32 | number of full-speed descriptors |
* | 12 | hs_count | LE32 | number of high-speed descriptors |
* | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors |
* | | hs_descrs | Descriptor[] | list of high-speed descriptors |
*
* descs are just valid USB descriptors and have the following format:
*
* | off | name | type | description |
* |-----+-----------------+------+--------------------------|
* | 0 | bLength | U8 | length of the descriptor |
* | 1 | bDescriptorType | U8 | descriptor type |
* | 2 | payload | | descriptor's payload |
*/
struct usb_functionfs_strings_head {
__le32 magic;
__le32 length;
__le32 str_count;
__le32 lang_count;
} __attribute__((packed));
/*
* Strings format:
*
* | off | name | type | description |
* |-----+------------+-----------------------+----------------------------|
* | 0 | magic | LE32 | FUNCTIONFS_STRINGS_MAGIC |
* | 4 | length | LE32 | length of the data chunk |
* | 8 | str_count | LE32 | number of strings |
* | 12 | lang_count | LE32 | number of languages |
* | 16 | stringtab | StringTab[lang_count] | table of strings per lang |
*
* For each language there is one stringtab entry (ie. there are lang_count
* stringtab entires). Each StringTab has following format:
*
* | off | name | type | description |
* |-----+---------+-------------------+------------------------------------|
* | 0 | lang | LE16 | language code |
* | 2 | strings | String[str_count] | array of strings in given language |
*
* For each string there is one strings entry (ie. there are str_count
* string entries). Each String is a NUL terminated string encoded in
* UTF-8.
*/
#endif
/*
* Events are delivered on the ep0 file descriptor, when the user mode driver
* reads from this file descriptor after writing the descriptors. Don't
* stop polling this descriptor.
*/
enum usb_functionfs_event_type {
FUNCTIONFS_BIND,
FUNCTIONFS_UNBIND,
FUNCTIONFS_ENABLE,
FUNCTIONFS_DISABLE,
FUNCTIONFS_SETUP,
FUNCTIONFS_SUSPEND,
FUNCTIONFS_RESUME
};
/* NOTE: this structure must stay the same size and layout on
* both 32-bit and 64-bit kernels.
*/
struct usb_functionfs_event {
union {
/* SETUP: packet; DATA phase i/o precedes next event
*(setup.bmRequestType & USB_DIR_IN) flags direction */
struct usb_ctrlrequest setup;
} __attribute__((packed)) u;
/* enum usb_functionfs_event_type */
__u8 type;
__u8 _pad[3];
} __attribute__((packed));
/* Endpoint ioctls */
/* The same as in gadgetfs */
/* IN transfers may be reported to the gadget driver as complete
* when the fifo is loaded, before the host reads the data;
* OUT transfers may be reported to the host's "client" driver as
* complete when they're sitting in the FIFO unread.
* THIS returns how many bytes are "unclaimed" in the endpoint fifo
* (needed for precise fault handling, when the hardware allows it)
*/
#define FUNCTIONFS_FIFO_STATUS _IO('g', 1)
/* discards any unclaimed data in the fifo. */
#define FUNCTIONFS_FIFO_FLUSH _IO('g', 2)
/* resets endpoint halt+toggle; used to implement set_interface.
* some hardware (like pxa2xx) can't support this.
*/
#define FUNCTIONFS_CLEAR_HALT _IO('g', 3)
/* Specific for functionfs */
/*
* Returns reverse mapping of an interface. Called on EP0. If there
* is no such interface returns -EDOM. If function is not active
* returns -ENODEV.
*/
#define FUNCTIONFS_INTERFACE_REVMAP _IO('g', 128)
/*
* Returns real bEndpointAddress of an endpoint. If function is not
* active returns -ENODEV.
*/
#define FUNCTIONFS_ENDPOINT_REVMAP _IO('g', 129)
#ifdef __KERNEL__
struct ffs_data; struct ffs_data;
struct usb_composite_dev; struct usb_composite_dev;
...@@ -197,5 +34,3 @@ static void functionfs_release_dev_callback(struct ffs_data *ffs_data) ...@@ -197,5 +34,3 @@ static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
#endif #endif
#endif
# UAPI Header export list # UAPI Header export list
header-y += audio.h
header-y += cdc.h
header-y += ch11.h
header-y += ch9.h
header-y += functionfs.h
header-y += g_printer.h
header-y += gadgetfs.h
header-y += midi.h
header-y += tmc.h
header-y += video.h
/*
* <linux/usb/audio.h> -- USB Audio definitions.
*
* Copyright (C) 2006 Thumtronics Pty Ltd.
* Developed for Thumtronics by Grey Innovation
* Ben Williamson <ben.williamson@greyinnovation.com>
*
* This software is distributed under the terms of the GNU General Public
* License ("GPL") version 2, as published by the Free Software Foundation.
*
* This file holds USB constants and structures defined
* by the USB Device Class Definition for Audio Devices.
* Comments below reference relevant sections of that document:
*
* http://www.usb.org/developers/devclass_docs/audio10.pdf
*
* Types and defines in this file are either specific to version 1.0 of
* this standard or common for newer versions.
*/
#ifndef _UAPI__LINUX_USB_AUDIO_H
#define _UAPI__LINUX_USB_AUDIO_H
#include <linux/types.h>
/* bInterfaceProtocol values to denote the version of the standard used */
#define UAC_VERSION_1 0x00
#define UAC_VERSION_2 0x20
/* A.2 Audio Interface Subclass Codes */
#define USB_SUBCLASS_AUDIOCONTROL 0x01
#define USB_SUBCLASS_AUDIOSTREAMING 0x02
#define USB_SUBCLASS_MIDISTREAMING 0x03
/* A.5 Audio Class-Specific AC Interface Descriptor Subtypes */
#define UAC_HEADER 0x01
#define UAC_INPUT_TERMINAL 0x02
#define UAC_OUTPUT_TERMINAL 0x03
#define UAC_MIXER_UNIT 0x04
#define UAC_SELECTOR_UNIT 0x05
#define UAC_FEATURE_UNIT 0x06
#define UAC1_PROCESSING_UNIT 0x07
#define UAC1_EXTENSION_UNIT 0x08
/* A.6 Audio Class-Specific AS Interface Descriptor Subtypes */
#define UAC_AS_GENERAL 0x01
#define UAC_FORMAT_TYPE 0x02
#define UAC_FORMAT_SPECIFIC 0x03
/* A.7 Processing Unit Process Types */
#define UAC_PROCESS_UNDEFINED 0x00
#define UAC_PROCESS_UP_DOWNMIX 0x01
#define UAC_PROCESS_DOLBY_PROLOGIC 0x02
#define UAC_PROCESS_STEREO_EXTENDER 0x03
#define UAC_PROCESS_REVERB 0x04
#define UAC_PROCESS_CHORUS 0x05
#define UAC_PROCESS_DYN_RANGE_COMP 0x06
/* A.8 Audio Class-Specific Endpoint Descriptor Subtypes */
#define UAC_EP_GENERAL 0x01
/* A.9 Audio Class-Specific Request Codes */
#define UAC_SET_ 0x00
#define UAC_GET_ 0x80
#define UAC__CUR 0x1
#define UAC__MIN 0x2
#define UAC__MAX 0x3
#define UAC__RES 0x4
#define UAC__MEM 0x5
#define UAC_SET_CUR (UAC_SET_ | UAC__CUR)
#define UAC_GET_CUR (UAC_GET_ | UAC__CUR)
#define UAC_SET_MIN (UAC_SET_ | UAC__MIN)
#define UAC_GET_MIN (UAC_GET_ | UAC__MIN)
#define UAC_SET_MAX (UAC_SET_ | UAC__MAX)
#define UAC_GET_MAX (UAC_GET_ | UAC__MAX)
#define UAC_SET_RES (UAC_SET_ | UAC__RES)
#define UAC_GET_RES (UAC_GET_ | UAC__RES)
#define UAC_SET_MEM (UAC_SET_ | UAC__MEM)
#define UAC_GET_MEM (UAC_GET_ | UAC__MEM)
#define UAC_GET_STAT 0xff
/* A.10 Control Selector Codes */
/* A.10.1 Terminal Control Selectors */
#define UAC_TERM_COPY_PROTECT 0x01
/* A.10.2 Feature Unit Control Selectors */
#define UAC_FU_MUTE 0x01
#define UAC_FU_VOLUME 0x02
#define UAC_FU_BASS 0x03
#define UAC_FU_MID 0x04
#define UAC_FU_TREBLE 0x05
#define UAC_FU_GRAPHIC_EQUALIZER 0x06
#define UAC_FU_AUTOMATIC_GAIN 0x07
#define UAC_FU_DELAY 0x08
#define UAC_FU_BASS_BOOST 0x09
#define UAC_FU_LOUDNESS 0x0a
#define UAC_CONTROL_BIT(CS) (1 << ((CS) - 1))
/* A.10.3.1 Up/Down-mix Processing Unit Controls Selectors */
#define UAC_UD_ENABLE 0x01
#define UAC_UD_MODE_SELECT 0x02
/* A.10.3.2 Dolby Prologic (tm) Processing Unit Controls Selectors */
#define UAC_DP_ENABLE 0x01
#define UAC_DP_MODE_SELECT 0x02
/* A.10.3.3 3D Stereo Extender Processing Unit Control Selectors */
#define UAC_3D_ENABLE 0x01
#define UAC_3D_SPACE 0x02
/* A.10.3.4 Reverberation Processing Unit Control Selectors */
#define UAC_REVERB_ENABLE 0x01
#define UAC_REVERB_LEVEL 0x02
#define UAC_REVERB_TIME 0x03
#define UAC_REVERB_FEEDBACK 0x04
/* A.10.3.5 Chorus Processing Unit Control Selectors */
#define UAC_CHORUS_ENABLE 0x01
#define UAC_CHORUS_LEVEL 0x02
#define UAC_CHORUS_RATE 0x03
#define UAC_CHORUS_DEPTH 0x04
/* A.10.3.6 Dynamic Range Compressor Unit Control Selectors */
#define UAC_DCR_ENABLE 0x01
#define UAC_DCR_RATE 0x02
#define UAC_DCR_MAXAMPL 0x03
#define UAC_DCR_THRESHOLD 0x04
#define UAC_DCR_ATTACK_TIME 0x05
#define UAC_DCR_RELEASE_TIME 0x06
/* A.10.4 Extension Unit Control Selectors */
#define UAC_XU_ENABLE 0x01
/* MIDI - A.1 MS Class-Specific Interface Descriptor Subtypes */
#define UAC_MS_HEADER 0x01
#define UAC_MIDI_IN_JACK 0x02
#define UAC_MIDI_OUT_JACK 0x03
/* MIDI - A.1 MS Class-Specific Endpoint Descriptor Subtypes */
#define UAC_MS_GENERAL 0x01
/* Terminals - 2.1 USB Terminal Types */
#define UAC_TERMINAL_UNDEFINED 0x100
#define UAC_TERMINAL_STREAMING 0x101
#define UAC_TERMINAL_VENDOR_SPEC 0x1FF
/* Terminal Control Selectors */
/* 4.3.2 Class-Specific AC Interface Descriptor */
struct uac1_ac_header_descriptor {
__u8 bLength; /* 8 + n */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* UAC_MS_HEADER */
__le16 bcdADC; /* 0x0100 */
__le16 wTotalLength; /* includes Unit and Terminal desc. */
__u8 bInCollection; /* n */
__u8 baInterfaceNr[]; /* [n] */
} __attribute__ ((packed));
#define UAC_DT_AC_HEADER_SIZE(n) (8 + (n))
/* As above, but more useful for defining your own descriptors: */
#define DECLARE_UAC_AC_HEADER_DESCRIPTOR(n) \
struct uac1_ac_header_descriptor_##n { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubtype; \
__le16 bcdADC; \
__le16 wTotalLength; \
__u8 bInCollection; \
__u8 baInterfaceNr[n]; \
} __attribute__ ((packed))
/* 4.3.2.1 Input Terminal Descriptor */
struct uac_input_terminal_descriptor {
__u8 bLength; /* in bytes: 12 */
__u8 bDescriptorType; /* CS_INTERFACE descriptor type */
__u8 bDescriptorSubtype; /* INPUT_TERMINAL descriptor subtype */
__u8 bTerminalID; /* Constant uniquely terminal ID */
__le16 wTerminalType; /* USB Audio Terminal Types */
__u8 bAssocTerminal; /* ID of the Output Terminal associated */
__u8 bNrChannels; /* Number of logical output channels */
__le16 wChannelConfig;
__u8 iChannelNames;
__u8 iTerminal;
} __attribute__ ((packed));
#define UAC_DT_INPUT_TERMINAL_SIZE 12
/* Terminals - 2.2 Input Terminal Types */
#define UAC_INPUT_TERMINAL_UNDEFINED 0x200
#define UAC_INPUT_TERMINAL_MICROPHONE 0x201
#define UAC_INPUT_TERMINAL_DESKTOP_MICROPHONE 0x202
#define UAC_INPUT_TERMINAL_PERSONAL_MICROPHONE 0x203
#define UAC_INPUT_TERMINAL_OMNI_DIR_MICROPHONE 0x204
#define UAC_INPUT_TERMINAL_MICROPHONE_ARRAY 0x205
#define UAC_INPUT_TERMINAL_PROC_MICROPHONE_ARRAY 0x206
/* Terminals - control selectors */
#define UAC_TERMINAL_CS_COPY_PROTECT_CONTROL 0x01
/* 4.3.2.2 Output Terminal Descriptor */
struct uac1_output_terminal_descriptor {
__u8 bLength; /* in bytes: 9 */
__u8 bDescriptorType; /* CS_INTERFACE descriptor type */
__u8 bDescriptorSubtype; /* OUTPUT_TERMINAL descriptor subtype */
__u8 bTerminalID; /* Constant uniquely terminal ID */
__le16 wTerminalType; /* USB Audio Terminal Types */
__u8 bAssocTerminal; /* ID of the Input Terminal associated */
__u8 bSourceID; /* ID of the connected Unit or Terminal*/
__u8 iTerminal;
} __attribute__ ((packed));
#define UAC_DT_OUTPUT_TERMINAL_SIZE 9
/* Terminals - 2.3 Output Terminal Types */
#define UAC_OUTPUT_TERMINAL_UNDEFINED 0x300
#define UAC_OUTPUT_TERMINAL_SPEAKER 0x301
#define UAC_OUTPUT_TERMINAL_HEADPHONES 0x302
#define UAC_OUTPUT_TERMINAL_HEAD_MOUNTED_DISPLAY_AUDIO 0x303
#define UAC_OUTPUT_TERMINAL_DESKTOP_SPEAKER 0x304
#define UAC_OUTPUT_TERMINAL_ROOM_SPEAKER 0x305
#define UAC_OUTPUT_TERMINAL_COMMUNICATION_SPEAKER 0x306
#define UAC_OUTPUT_TERMINAL_LOW_FREQ_EFFECTS_SPEAKER 0x307
/* Set bControlSize = 2 as default setting */
#define UAC_DT_FEATURE_UNIT_SIZE(ch) (7 + ((ch) + 1) * 2)
/* As above, but more useful for defining your own descriptors: */
#define DECLARE_UAC_FEATURE_UNIT_DESCRIPTOR(ch) \
struct uac_feature_unit_descriptor_##ch { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubtype; \
__u8 bUnitID; \
__u8 bSourceID; \
__u8 bControlSize; \
__le16 bmaControls[ch + 1]; \
__u8 iFeature; \
} __attribute__ ((packed))
/* 4.3.2.3 Mixer Unit Descriptor */
struct uac_mixer_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_mixer_unit_bNrChannels(struct uac_mixer_unit_descriptor *desc)
{
return desc->baSourceID[desc->bNrInPins];
}
static inline __u32 uac_mixer_unit_wChannelConfig(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
if (protocol == UAC_VERSION_1)
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
desc->baSourceID[desc->bNrInPins + 1];
else
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
(desc->baSourceID[desc->bNrInPins + 1]);
}
static inline __u8 uac_mixer_unit_iChannelNames(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 3] :
desc->baSourceID[desc->bNrInPins + 5];
}
static inline __u8 *uac_mixer_unit_bmControls(struct uac_mixer_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
&desc->baSourceID[desc->bNrInPins + 4] :
&desc->baSourceID[desc->bNrInPins + 6];
}
static inline __u8 uac_mixer_unit_iMixer(struct uac_mixer_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.4 Selector Unit Descriptor */
struct uac_selector_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUintID;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_selector_unit_iSelector(struct uac_selector_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.5 Feature Unit Descriptor */
struct uac_feature_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u8 bSourceID;
__u8 bControlSize;
__u8 bmaControls[0]; /* variable length */
} __attribute__((packed));
static inline __u8 uac_feature_unit_iFeature(struct uac_feature_unit_descriptor *desc)
{
__u8 *raw = (__u8 *) desc;
return raw[desc->bLength - 1];
}
/* 4.3.2.6 Processing Unit Descriptors */
struct uac_processing_unit_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bUnitID;
__u16 wProcessType;
__u8 bNrInPins;
__u8 baSourceID[];
} __attribute__ ((packed));
static inline __u8 uac_processing_unit_bNrChannels(struct uac_processing_unit_descriptor *desc)
{
return desc->baSourceID[desc->bNrInPins];
}
static inline __u32 uac_processing_unit_wChannelConfig(struct uac_processing_unit_descriptor *desc,
int protocol)
{
if (protocol == UAC_VERSION_1)
return (desc->baSourceID[desc->bNrInPins + 2] << 8) |
desc->baSourceID[desc->bNrInPins + 1];
else
return (desc->baSourceID[desc->bNrInPins + 4] << 24) |
(desc->baSourceID[desc->bNrInPins + 3] << 16) |
(desc->baSourceID[desc->bNrInPins + 2] << 8) |
(desc->baSourceID[desc->bNrInPins + 1]);
}
static inline __u8 uac_processing_unit_iChannelNames(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 3] :
desc->baSourceID[desc->bNrInPins + 5];
}
static inline __u8 uac_processing_unit_bControlSize(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
desc->baSourceID[desc->bNrInPins + 4] :
desc->baSourceID[desc->bNrInPins + 6];
}
static inline __u8 *uac_processing_unit_bmControls(struct uac_processing_unit_descriptor *desc,
int protocol)
{
return (protocol == UAC_VERSION_1) ?
&desc->baSourceID[desc->bNrInPins + 5] :
&desc->baSourceID[desc->bNrInPins + 7];
}
static inline __u8 uac_processing_unit_iProcessing(struct uac_processing_unit_descriptor *desc,
int protocol)
{
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
return desc->baSourceID[desc->bNrInPins + control_size];
}
static inline __u8 *uac_processing_unit_specific(struct uac_processing_unit_descriptor *desc,
int protocol)
{
__u8 control_size = uac_processing_unit_bControlSize(desc, protocol);
return &desc->baSourceID[desc->bNrInPins + control_size + 1];
}
/* 4.5.2 Class-Specific AS Interface Descriptor */
struct uac1_as_header_descriptor {
__u8 bLength; /* in bytes: 7 */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* AS_GENERAL */
__u8 bTerminalLink; /* Terminal ID of connected Terminal */
__u8 bDelay; /* Delay introduced by the data path */
__le16 wFormatTag; /* The Audio Data Format */
} __attribute__ ((packed));
#define UAC_DT_AS_HEADER_SIZE 7
/* Formats - A.1.1 Audio Data Format Type I Codes */
#define UAC_FORMAT_TYPE_I_UNDEFINED 0x0
#define UAC_FORMAT_TYPE_I_PCM 0x1
#define UAC_FORMAT_TYPE_I_PCM8 0x2
#define UAC_FORMAT_TYPE_I_IEEE_FLOAT 0x3
#define UAC_FORMAT_TYPE_I_ALAW 0x4
#define UAC_FORMAT_TYPE_I_MULAW 0x5
struct uac_format_type_i_continuous_descriptor {
__u8 bLength; /* in bytes: 8 + (ns * 3) */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* FORMAT_TYPE */
__u8 bFormatType; /* FORMAT_TYPE_1 */
__u8 bNrChannels; /* physical channels in the stream */
__u8 bSubframeSize; /* */
__u8 bBitResolution;
__u8 bSamFreqType;
__u8 tLowerSamFreq[3];
__u8 tUpperSamFreq[3];
} __attribute__ ((packed));
#define UAC_FORMAT_TYPE_I_CONTINUOUS_DESC_SIZE 14
struct uac_format_type_i_discrete_descriptor {
__u8 bLength; /* in bytes: 8 + (ns * 3) */
__u8 bDescriptorType; /* USB_DT_CS_INTERFACE */
__u8 bDescriptorSubtype; /* FORMAT_TYPE */
__u8 bFormatType; /* FORMAT_TYPE_1 */
__u8 bNrChannels; /* physical channels in the stream */
__u8 bSubframeSize; /* */
__u8 bBitResolution;
__u8 bSamFreqType;
__u8 tSamFreq[][3];
} __attribute__ ((packed));
#define DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(n) \
struct uac_format_type_i_discrete_descriptor_##n { \
__u8 bLength; \
__u8 bDescriptorType; \
__u8 bDescriptorSubtype; \
__u8 bFormatType; \
__u8 bNrChannels; \
__u8 bSubframeSize; \
__u8 bBitResolution; \
__u8 bSamFreqType; \
__u8 tSamFreq[n][3]; \
} __attribute__ ((packed))
#define UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(n) (8 + (n * 3))
struct uac_format_type_i_ext_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
__u8 bSubslotSize;
__u8 bBitResolution;
__u8 bHeaderLength;
__u8 bControlSize;
__u8 bSideBandProtocol;
} __attribute__((packed));
/* Formats - Audio Data Format Type I Codes */
#define UAC_FORMAT_TYPE_II_MPEG 0x1001
#define UAC_FORMAT_TYPE_II_AC3 0x1002
struct uac_format_type_ii_discrete_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
__le16 wMaxBitRate;
__le16 wSamplesPerFrame;
__u8 bSamFreqType;
__u8 tSamFreq[][3];
} __attribute__((packed));
struct uac_format_type_ii_ext_descriptor {
__u8 bLength;
__u8 bDescriptorType;
__u8 bDescriptorSubtype;
__u8 bFormatType;
__u16 wMaxBitRate;
__u16 wSamplesPerFrame;
__u8 bHeaderLength;
__u8 bSideBandProtocol;
} __attribute__((packed));
/* type III */
#define UAC_FORMAT_TYPE_III_IEC1937_AC3 0x2001
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG1_LAYER1 0x2002
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_NOEXT 0x2003
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_EXT 0x2004
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER1_LS 0x2005
#define UAC_FORMAT_TYPE_III_IEC1937_MPEG2_LAYER23_LS 0x2006
/* Formats - A.2 Format Type Codes */
#define UAC_FORMAT_TYPE_UNDEFINED 0x0
#define UAC_FORMAT_TYPE_I 0x1
#define UAC_FORMAT_TYPE_II 0x2
#define UAC_FORMAT_TYPE_III 0x3
#define UAC_EXT_FORMAT_TYPE_I 0x81
#define UAC_EXT_FORMAT_TYPE_II 0x82
#define UAC_EXT_FORMAT_TYPE_III 0x83
struct uac_iso_endpoint_descriptor {
__u8 bLength; /* in bytes: 7 */
__u8 bDescriptorType; /* USB_DT_CS_ENDPOINT */
__u8 bDescriptorSubtype; /* EP_GENERAL */
__u8 bmAttributes;
__u8 bLockDelayUnits;
__le16 wLockDelay;
} __attribute__((packed));
#define UAC_ISO_ENDPOINT_DESC_SIZE 7
#define UAC_EP_CS_ATTR_SAMPLE_RATE 0x01
#define UAC_EP_CS_ATTR_PITCH_CONTROL 0x02
#define UAC_EP_CS_ATTR_FILL_MAX 0x80
/* status word format (3.7.1.1) */
#define UAC1_STATUS_TYPE_ORIG_MASK 0x0f
#define UAC1_STATUS_TYPE_ORIG_AUDIO_CONTROL_IF 0x0
#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_IF 0x1
#define UAC1_STATUS_TYPE_ORIG_AUDIO_STREAM_EP 0x2
#define UAC1_STATUS_TYPE_IRQ_PENDING (1 << 7)
#define UAC1_STATUS_TYPE_MEM_CHANGED (1 << 6)
struct uac1_status_word {
__u8 bStatusType;
__u8 bOriginator;
} __attribute__((packed));
#endif /* _UAPI__LINUX_USB_AUDIO_H */
此差异已折叠。
#ifndef _UAPI__LINUX_FUNCTIONFS_H__
#define _UAPI__LINUX_FUNCTIONFS_H__
#include <linux/types.h>
#include <linux/ioctl.h>
#include <linux/usb/ch9.h>
enum {
FUNCTIONFS_DESCRIPTORS_MAGIC = 1,
FUNCTIONFS_STRINGS_MAGIC = 2
};
#ifndef __KERNEL__
/* Descriptor of an non-audio endpoint */
struct usb_endpoint_descriptor_no_audio {
__u8 bLength;
__u8 bDescriptorType;
__u8 bEndpointAddress;
__u8 bmAttributes;
__le16 wMaxPacketSize;
__u8 bInterval;
} __attribute__((packed));
/*
* All numbers must be in little endian order.
*/
struct usb_functionfs_descs_head {
__le32 magic;
__le32 length;
__le32 fs_count;
__le32 hs_count;
} __attribute__((packed));
/*
* Descriptors format:
*
* | off | name | type | description |
* |-----+-----------+--------------+--------------------------------------|
* | 0 | magic | LE32 | FUNCTIONFS_{FS,HS}_DESCRIPTORS_MAGIC |
* | 4 | length | LE32 | length of the whole data chunk |
* | 8 | fs_count | LE32 | number of full-speed descriptors |
* | 12 | hs_count | LE32 | number of high-speed descriptors |
* | 16 | fs_descrs | Descriptor[] | list of full-speed descriptors |
* | | hs_descrs | Descriptor[] | list of high-speed descriptors |
*
* descs are just valid USB descriptors and have the following format:
*
* | off | name | type | description |
* |-----+-----------------+------+--------------------------|
* | 0 | bLength | U8 | length of the descriptor |
* | 1 | bDescriptorType | U8 | descriptor type |
* | 2 | payload | | descriptor's payload |
*/
struct usb_functionfs_strings_head {
__le32 magic;
__le32 length;
__le32 str_count;
__le32 lang_count;
} __attribute__((packed));
/*
* Strings format:
*
* | off | name | type | description |
* |-----+------------+-----------------------+----------------------------|
* | 0 | magic | LE32 | FUNCTIONFS_STRINGS_MAGIC |
* | 4 | length | LE32 | length of the data chunk |
* | 8 | str_count | LE32 | number of strings |
* | 12 | lang_count | LE32 | number of languages |
* | 16 | stringtab | StringTab[lang_count] | table of strings per lang |
*
* For each language there is one stringtab entry (ie. there are lang_count
* stringtab entires). Each StringTab has following format:
*
* | off | name | type | description |
* |-----+---------+-------------------+------------------------------------|
* | 0 | lang | LE16 | language code |
* | 2 | strings | String[str_count] | array of strings in given language |
*
* For each string there is one strings entry (ie. there are str_count
* string entries). Each String is a NUL terminated string encoded in
* UTF-8.
*/
#endif
/*
* Events are delivered on the ep0 file descriptor, when the user mode driver
* reads from this file descriptor after writing the descriptors. Don't
* stop polling this descriptor.
*/
enum usb_functionfs_event_type {
FUNCTIONFS_BIND,
FUNCTIONFS_UNBIND,
FUNCTIONFS_ENABLE,
FUNCTIONFS_DISABLE,
FUNCTIONFS_SETUP,
FUNCTIONFS_SUSPEND,
FUNCTIONFS_RESUME
};
/* NOTE: this structure must stay the same size and layout on
* both 32-bit and 64-bit kernels.
*/
struct usb_functionfs_event {
union {
/* SETUP: packet; DATA phase i/o precedes next event
*(setup.bmRequestType & USB_DIR_IN) flags direction */
struct usb_ctrlrequest setup;
} __attribute__((packed)) u;
/* enum usb_functionfs_event_type */
__u8 type;
__u8 _pad[3];
} __attribute__((packed));
/* Endpoint ioctls */
/* The same as in gadgetfs */
/* IN transfers may be reported to the gadget driver as complete
* when the fifo is loaded, before the host reads the data;
* OUT transfers may be reported to the host's "client" driver as
* complete when they're sitting in the FIFO unread.
* THIS returns how many bytes are "unclaimed" in the endpoint fifo
* (needed for precise fault handling, when the hardware allows it)
*/
#define FUNCTIONFS_FIFO_STATUS _IO('g', 1)
/* discards any unclaimed data in the fifo. */
#define FUNCTIONFS_FIFO_FLUSH _IO('g', 2)
/* resets endpoint halt+toggle; used to implement set_interface.
* some hardware (like pxa2xx) can't support this.
*/
#define FUNCTIONFS_CLEAR_HALT _IO('g', 3)
/* Specific for functionfs */
/*
* Returns reverse mapping of an interface. Called on EP0. If there
* is no such interface returns -EDOM. If function is not active
* returns -ENODEV.
*/
#define FUNCTIONFS_INTERFACE_REVMAP _IO('g', 128)
/*
* Returns real bEndpointAddress of an endpoint. If function is not
* active returns -ENODEV.
*/
#define FUNCTIONFS_ENDPOINT_REVMAP _IO('g', 129)
#endif /* _UAPI__LINUX_FUNCTIONFS_H__ */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册