Commit 42bf3e27 authored by Linus Torvalds's avatar 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
  ...
parents fb06de04 4b35f1c5
......@@ -7746,6 +7746,13 @@ W: http://www.ideasonboard.org/uvc/
S: Maintained
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)
M: Jussi Kivilinna <jussi.kivilinna@mbnet.fi>
L: linux-wireless@vger.kernel.org
......
......@@ -817,10 +817,6 @@ static const __u32 acm_tty_speed[] = {
2500000, 3000000, 3500000, 4000000
};
static const __u8 acm_tty_size[] = {
5, 6, 7, 8
};
static void acm_tty_set_termios(struct tty_struct *tty,
struct ktermios *termios_old)
{
......@@ -834,7 +830,21 @@ static void acm_tty_set_termios(struct tty_struct *tty,
newline.bParityType = termios->c_cflag & PARENB ?
(termios->c_cflag & PARODD ? 1 : 2) +
(termios->c_cflag & CMSPAR ? 2 : 0) : 0;
newline.bDataBits = acm_tty_size[(termios->c_cflag & CSIZE) >> 4];
switch (termios->c_cflag & CSIZE) {
case CS5:
newline.bDataBits = 5;
break;
case CS6:
newline.bDataBits = 6;
break;
case CS7:
newline.bDataBits = 7;
break;
case CS8:
default:
newline.bDataBits = 8;
break;
}
/* FIXME: Needs to clear unsupported bits in the termios */
acm->clocal = ((termios->c_cflag & CLOCAL) != 0);
......@@ -1233,7 +1243,7 @@ static int acm_probe(struct usb_interface *intf,
if (usb_endpoint_xfer_int(epwrite))
usb_fill_int_urb(snd->urb, usb_dev,
usb_sndbulkpipe(usb_dev, epwrite->bEndpointAddress),
usb_sndintpipe(usb_dev, epwrite->bEndpointAddress),
NULL, acm->writesize, acm_write_bulk, snd, epwrite->bInterval);
else
usb_fill_bulk_urb(snd->urb, usb_dev,
......
......@@ -1348,6 +1348,7 @@ static int proc_do_submiturb(struct dev_state *ps, struct usbdevfs_urb *uurb,
ret = -EFAULT;
goto error;
}
uurb->buffer += u;
}
totlen -= u;
}
......
......@@ -367,6 +367,10 @@ static int usb_probe_interface(struct device *dev)
intf->condition = USB_INTERFACE_UNBOUND;
usb_cancel_queued_reset(intf);
/* If the LPM disable succeeded, balance the ref counts. */
if (!lpm_disable_error)
usb_unlocked_enable_lpm(udev);
/* Unbound interfaces are always runtime-PM-disabled and -suspended */
if (driver->supports_autosuspend)
pm_runtime_disable(dev);
......
......@@ -3241,8 +3241,7 @@ static int usb_req_set_sel(struct usb_device *udev, enum usb3_link_state state)
(state == USB3_LPM_U2 &&
(u2_sel > USB3_LPM_MAX_U2_SEL_PEL ||
u2_pel > USB3_LPM_MAX_U2_SEL_PEL))) {
dev_dbg(&udev->dev, "Device-initiated %s disabled due "
"to long SEL %llu ms or PEL %llu ms\n",
dev_dbg(&udev->dev, "Device-initiated %s disabled due to long SEL %llu us or PEL %llu us\n",
usb3_lpm_names[state], u1_sel, u1_pel);
return -EINVAL;
}
......@@ -3319,16 +3318,6 @@ static int usb_set_device_initiated_lpm(struct usb_device *udev,
}
if (enable) {
/*
* First, let the device know about the exit latencies
* associated with the link state we're about to enable.
*/
ret = usb_req_set_sel(udev, state);
if (ret < 0) {
dev_warn(&udev->dev, "Set SEL for device-initiated "
"%s failed.\n", usb3_lpm_names[state]);
return -EBUSY;
}
/*
* Now send the control transfer to enable device-initiated LPM
* for either U1 or U2.
......@@ -3414,7 +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,
enum usb3_link_state state)
{
int timeout;
int timeout, ret;
__u8 u1_mel = udev->bos->ss_cap->bU1devExitLat;
__le16 u2_mel = udev->bos->ss_cap->bU2DevExitLat;
/* If the device says it doesn't have *any* exit latency to come out of
* U1 or U2, it's probably lying. Assume it doesn't implement that link
* state.
*/
if ((state == USB3_LPM_U1 && u1_mel == 0) ||
(state == USB3_LPM_U2 && u2_mel == 0))
return;
/*
* First, let the device know about the exit latencies
* associated with the link state we're about to enable.
*/
ret = usb_req_set_sel(udev, state);
if (ret < 0) {
dev_warn(&udev->dev, "Set SEL for device-initiated %s failed.\n",
usb3_lpm_names[state]);
return;
}
/* We allow the host controller to set the U1/U2 timeout internally
* first, so that it can change its schedule to account for the
......
......@@ -409,6 +409,10 @@ static void dwc3_core_exit(struct dwc3 *dwc)
{
dwc3_event_buffers_cleanup(dwc);
dwc3_free_event_buffers(dwc);
usb_phy_shutdown(dwc->usb2_phy);
usb_phy_shutdown(dwc->usb3_phy);
}
#define DWC3_ALIGN_MASK (16 - 1)
......
......@@ -1904,7 +1904,7 @@ static void dwc3_stop_active_transfer(struct dwc3 *dwc, u32 epnum)
ret = dwc3_send_gadget_ep_cmd(dwc, dep->number, cmd, &params);
WARN_ON_ONCE(ret);
dep->resource_index = 0;
dep->flags &= ~DWC3_EP_BUSY;
udelay(100);
}
......
......@@ -952,6 +952,7 @@ endif
config USB_G_WEBCAM
tristate "USB Webcam Gadget"
depends on VIDEO_DEV
select USB_LIBCOMPOSITE
help
The Webcam Gadget acts as a composite USB Audio and Video Class
device. It provides a userspace API to process UVC control requests
......
......@@ -2930,10 +2930,10 @@ static void vbus_work(struct work_struct *work)
/* Get the VBUS status from the transceiver */
value = i2c_smbus_read_byte_data(udc->isp1301_i2c_client,
ISP1301_I2C_OTG_CONTROL_2);
ISP1301_I2C_INTERRUPT_SOURCE);
/* VBUS on or off? */
if (value & OTG_B_SESS_VLD)
if (value & INT_SESS_VLD)
udc->vbus = 1;
else
udc->vbus = 0;
......
......@@ -85,6 +85,8 @@ static const struct hc_driver vt8500_ehci_hc_driver = {
.clear_tt_buffer_complete = ehci_clear_tt_buffer_complete,
};
static u64 vt8500_ehci_dma_mask = DMA_BIT_MASK(32);
static int vt8500_ehci_drv_probe(struct platform_device *pdev)
{
struct usb_hcd *hcd;
......@@ -95,6 +97,14 @@ static int vt8500_ehci_drv_probe(struct platform_device *pdev)
if (usb_disabled())
return -ENODEV;
/*
* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &vt8500_ehci_dma_mask;
if (pdev->resource[1].flags != IORESOURCE_IRQ) {
pr_debug("resource[1] is not IORESOURCE_IRQ");
return -ENOMEM;
......
......@@ -60,6 +60,7 @@ static const struct hc_driver uhci_platform_hc_driver = {
.hub_control = uhci_hub_control,
};
static u64 platform_uhci_dma_mask = DMA_BIT_MASK(32);
static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
{
......@@ -71,6 +72,14 @@ static int __devinit uhci_hcd_platform_probe(struct platform_device *pdev)
if (usb_disabled())
return -ENODEV;
/*
* Right now device-tree probed devices don't get dma_mask set.
* Since shared usb code relies on it, set it here for now.
* Once we have dma capability bindings this can go away.
*/
if (!pdev->dev.dma_mask)
pdev->dev.dma_mask = &platform_uhci_dma_mask;
hcd = usb_create_hcd(&uhci_platform_hc_driver, &pdev->dev,
pdev->name);
if (!hcd)
......
......@@ -479,7 +479,8 @@ static bool compliance_mode_recovery_timer_quirk_check(void)
if (strstr(dmi_product_name, "Z420") ||
strstr(dmi_product_name, "Z620") ||
strstr(dmi_product_name, "Z820"))
strstr(dmi_product_name, "Z820") ||
strstr(dmi_product_name, "Z1"))
return true;
return false;
......
......@@ -305,6 +305,12 @@ static irqreturn_t am35x_musb_interrupt(int irq, void *hci)
ret = IRQ_HANDLED;
}
/* Drop spurious RX and TX if device is disconnected */
if (musb->int_usb & MUSB_INTR_DISCONNECT) {
musb->int_tx = 0;
musb->int_rx = 0;
}
if (musb->int_tx || musb->int_rx || musb->int_usb)
ret |= musb_interrupt(musb);
......
......@@ -273,9 +273,9 @@ static irqreturn_t usbhs_interrupt(int irq, void *data)
usbhs_write(priv, INTSTS0, ~irq_state.intsts0 & INTSTS0_MAGIC);
usbhs_write(priv, INTSTS1, ~irq_state.intsts1 & INTSTS1_MAGIC);
usbhs_write(priv, BRDYSTS, 0);
usbhs_write(priv, NRDYSTS, 0);
usbhs_write(priv, BEMPSTS, 0);
usbhs_write(priv, BRDYSTS, ~irq_state.brdysts);
usbhs_write(priv, NRDYSTS, ~irq_state.nrdysts);
usbhs_write(priv, BEMPSTS, ~irq_state.bempsts);
/*
* call irq callback functions
......
......@@ -54,7 +54,7 @@ struct usbhs_pipe_info {
* pipe list
*/
#define __usbhs_for_each_pipe(start, pos, info, i) \
for (i = start, pos = (info)->pipe; \
for (i = start, pos = (info)->pipe + i; \
i < (info)->size; \
i++, pos = (info)->pipe + i)
......
......@@ -125,9 +125,6 @@ static inline int calc_divisor(int bps)
static int ark3116_attach(struct usb_serial *serial)
{
struct usb_serial_port *port = serial->port[0];
struct ark3116_private *priv;
/* make sure we have our end-points */
if ((serial->num_bulk_in == 0) ||
(serial->num_bulk_out == 0) ||
......@@ -142,8 +139,15 @@ static int ark3116_attach(struct usb_serial *serial)
return -EINVAL;
}
priv = kzalloc(sizeof(struct ark3116_private),
GFP_KERNEL);
return 0;
}
static int ark3116_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct ark3116_private *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
......@@ -198,18 +202,15 @@ static int ark3116_attach(struct usb_serial *serial)
return 0;
}
static void ark3116_release(struct usb_serial *serial)
static int ark3116_port_remove(struct usb_serial_port *port)
{
struct usb_serial_port *port = serial->port[0];
struct ark3116_private *priv = usb_get_serial_port_data(port);
/* device is closed, so URBs and DMA should be down */
usb_set_serial_port_data(port, NULL);
mutex_destroy(&priv->hw_lock);
kfree(priv);
return 0;
}
static void ark3116_init_termios(struct tty_struct *tty)
......@@ -723,7 +724,8 @@ static struct usb_serial_driver ark3116_device = {
.id_table = id_table,
.num_ports = 1,
.attach = ark3116_attach,
.release = ark3116_release,
.port_probe = ark3116_port_probe,
.port_remove = ark3116_port_remove,
.set_termios = ark3116_set_termios,
.init_termios = ark3116_init_termios,
.ioctl = ark3116_ioctl,
......
......@@ -45,8 +45,8 @@
#define DRIVER_DESC "USB Belkin Serial converter driver"
/* function prototypes for a Belkin USB Serial Adapter F5U103 */
static int belkin_sa_startup(struct usb_serial *serial);
static void belkin_sa_release(struct usb_serial *serial);
static int belkin_sa_port_probe(struct usb_serial_port *port);
static int belkin_sa_port_remove(struct usb_serial_port *port);
static int belkin_sa_open(struct tty_struct *tty,
struct usb_serial_port *port);
static void belkin_sa_close(struct usb_serial_port *port);
......@@ -88,8 +88,8 @@ static struct usb_serial_driver belkin_device = {
.break_ctl = belkin_sa_break_ctl,
.tiocmget = belkin_sa_tiocmget,
.tiocmset = belkin_sa_tiocmset,
.attach = belkin_sa_startup,
.release = belkin_sa_release,
.port_probe = belkin_sa_port_probe,
.port_remove = belkin_sa_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
......@@ -118,17 +118,15 @@ struct belkin_sa_private {
(c), BELKIN_SA_SET_REQUEST_TYPE, \
(v), 0, NULL, 0, WDR_TIMEOUT)
/* do some startup allocations not currently performed by usb_serial_probe() */
static int belkin_sa_startup(struct usb_serial *serial)
static int belkin_sa_port_probe(struct usb_serial_port *port)
{
struct usb_device *dev = serial->dev;
struct usb_device *dev = port->serial->dev;
struct belkin_sa_private *priv;
/* allocate the private data structure */
priv = kmalloc(sizeof(struct belkin_sa_private), GFP_KERNEL);
if (!priv)
return -1; /* error */
/* set initial values for control structures */
return -ENOMEM;
spin_lock_init(&priv->lock);
priv->control_state = 0;
priv->last_lsr = 0;
......@@ -140,18 +138,19 @@ static int belkin_sa_startup(struct usb_serial *serial)
le16_to_cpu(dev->descriptor.bcdDevice),
priv->bad_flow_control);
init_waitqueue_head(&serial->port[0]->write_wait);
usb_set_serial_port_data(serial->port[0], priv);
usb_set_serial_port_data(port, priv);
return 0;
}
static void belkin_sa_release(struct usb_serial *serial)
static int belkin_sa_port_remove(struct usb_serial_port *port)
{
int i;
struct belkin_sa_private *priv;
for (i = 0; i < serial->num_ports; ++i)
kfree(usb_get_serial_port_data(serial->port[i]));
priv = usb_get_serial_port_data(port);
kfree(priv);
return 0;
}
static int belkin_sa_open(struct tty_struct *tty,
......
......@@ -162,7 +162,7 @@ static const struct usb_device_id id_table[] = {
MODULE_DEVICE_TABLE(usb, id_table);
struct cp210x_port_private {
struct cp210x_serial_private {
__u8 bInterfaceNumber;
};
......@@ -276,7 +276,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
unsigned int *data, int size)
{
struct usb_serial *serial = port->serial;
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
struct cp210x_serial_private *spriv = usb_get_serial_data(serial);
__le32 *buf;
int result, i, length;
......@@ -292,7 +292,7 @@ static int cp210x_get_config(struct usb_serial_port *port, u8 request,
/* Issue the request, attempting to read 'size' bytes */
result = usb_control_msg(serial->dev, usb_rcvctrlpipe(serial->dev, 0),
request, REQTYPE_INTERFACE_TO_HOST, 0x0000,
port_priv->bInterfaceNumber, buf, size,
spriv->bInterfaceNumber, buf, size,
USB_CTRL_GET_TIMEOUT);
/* Convert data into an array of integers */
......@@ -323,7 +323,7 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
unsigned int *data, int size)
{
struct usb_serial *serial = port->serial;
struct cp210x_port_private *port_priv = usb_get_serial_port_data(port);
struct cp210x_serial_private *spriv = usb_get_serial_data(serial);
__le32 *buf;
int result, i, length;
......@@ -345,13 +345,13 @@ static int cp210x_set_config(struct usb_serial_port *port, u8 request,
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_INTERFACE, 0x0000,
port_priv->bInterfaceNumber, buf, size,
spriv->bInterfaceNumber, buf, size,
USB_CTRL_SET_TIMEOUT);
} else {
result = usb_control_msg(serial->dev,
usb_sndctrlpipe(serial->dev, 0),
request, REQTYPE_HOST_TO_INTERFACE, data[0],
port_priv->bInterfaceNumber, NULL, 0,
spriv->bInterfaceNumber, NULL, 0,
USB_CTRL_SET_TIMEOUT);
}
......@@ -845,36 +845,30 @@ static void cp210x_break_ctl (struct tty_struct *tty, int break_state)
static int cp210x_startup(struct usb_serial *serial)
{
struct cp210x_port_private *port_priv;
int i;
struct usb_host_interface *cur_altsetting;
struct cp210x_serial_private *spriv;
/* cp210x buffers behave strangely unless device is reset */
usb_reset_device(serial->dev);
for (i = 0; i < serial->num_ports; i++) {
port_priv = kzalloc(sizeof(*port_priv), GFP_KERNEL);
if (!port_priv)
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
if (!spriv)
return -ENOMEM;
port_priv->bInterfaceNumber =
serial->interface->cur_altsetting->desc.bInterfaceNumber;
cur_altsetting = serial->interface->cur_altsetting;
spriv->bInterfaceNumber = cur_altsetting->desc.bInterfaceNumber;
usb_set_serial_port_data(serial->port[i], port_priv);
}
usb_set_serial_data(serial, spriv);
return 0;
}
static void cp210x_release(struct usb_serial *serial)
{
struct cp210x_port_private *port_priv;
int i;
struct cp210x_serial_private *spriv;
for (i = 0; i < serial->num_ports; i++) {
port_priv = usb_get_serial_port_data(serial->port[i]);
kfree(port_priv);
usb_set_serial_port_data(serial->port[i], NULL);
}
spriv = usb_get_serial_data(serial);
kfree(spriv);
}
module_usb_serial_driver(serial_drivers, id_table);
......
......@@ -55,9 +55,9 @@
#define CYBERJACK_PRODUCT_ID 0x0100
/* Function prototypes */
static int cyberjack_startup(struct usb_serial *serial);
static void cyberjack_disconnect(struct usb_serial *serial);
static void cyberjack_release(struct usb_serial *serial);
static int cyberjack_port_probe(struct usb_serial_port *port);
static int cyberjack_port_remove(struct usb_serial_port *port);
static int cyberjack_open(struct tty_struct *tty,
struct usb_serial_port *port);
static void cyberjack_close(struct usb_serial_port *port);
......@@ -83,9 +83,9 @@ static struct usb_serial_driver cyberjack_device = {
.description = "Reiner SCT Cyberjack USB card reader",
.id_table = id_table,
.num_ports = 1,
.attach = cyberjack_startup,
.disconnect = cyberjack_disconnect,
.release = cyberjack_release,
.port_probe = cyberjack_port_probe,
.port_remove = cyberjack_port_remove,
.open = cyberjack_open,
.close = cyberjack_close,
.write = cyberjack_write,
......@@ -107,56 +107,45 @@ struct cyberjack_private {
short wrsent; /* Data already sent */
};
/* do some startup allocations not currently performed by usb_serial_probe() */
static int cyberjack_startup(struct usb_serial *serial)
static int cyberjack_port_probe(struct usb_serial_port *port)
{
struct cyberjack_private *priv;
int i;
int result;
/* allocate the private data structure */
priv = kmalloc(sizeof(struct cyberjack_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* set initial values */
spin_lock_init(&priv->lock);
priv->rdtodo = 0;
priv->wrfilled = 0;
priv->wrsent = 0;
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
usb_set_serial_port_data(port, priv);
for (i = 0; i < serial->num_ports; ++i) {
int result;
result = usb_submit_urb(serial->port[i]->interrupt_in_urb,
GFP_KERNEL);
result = usb_submit_urb(port->interrupt_in_urb, GFP_KERNEL);
if (result)
dev_err(&serial->dev->dev,
"usb_submit_urb(read int) failed\n");
dev_dbg(&serial->dev->dev, "%s - usb_submit_urb(int urb)\n",
__func__);
}
dev_err(&port->dev, "usb_submit_urb(read int) failed\n");
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)
usb_kill_urb(serial->port[i]->interrupt_in_urb);
priv = usb_get_serial_port_data(port);
kfree(priv);
return 0;
}
static void cyberjack_release(struct usb_serial *serial)
static void cyberjack_disconnect(struct usb_serial *serial)
{
int i;
for (i = 0; i < serial->num_ports; ++i) {
/* My special items, the standard routines free my urbs */
kfree(usb_get_serial_port_data(serial->port[i]));
}
for (i = 0; i < serial->num_ports; ++i)
usb_kill_urb(serial->port[i]->interrupt_in_urb);
}
static int cyberjack_open(struct tty_struct *tty,
......
......@@ -123,10 +123,10 @@ struct cypress_private {
};
/* function prototypes for the Cypress USB to serial device */
static int cypress_earthmate_startup(struct usb_serial *serial);
static int cypress_hidcom_startup(struct usb_serial *serial);
static int cypress_ca42v2_startup(struct usb_serial *serial);
static void cypress_release(struct usb_serial *serial);
static int cypress_earthmate_port_probe(struct usb_serial_port *port);
static int cypress_hidcom_port_probe(struct usb_serial_port *port);
static int cypress_ca42v2_port_probe(struct usb_serial_port *port);
static int cypress_port_remove(struct usb_serial_port *port);
static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port);
static void cypress_close(struct usb_serial_port *port);
static void cypress_dtr_rts(struct usb_serial_port *port, int on);
......@@ -156,8 +156,8 @@ static struct usb_serial_driver cypress_earthmate_device = {
.description = "DeLorme Earthmate USB",
.id_table = id_table_earthmate,
.num_ports = 1,
.attach = cypress_earthmate_startup,
.release = cypress_release,
.port_probe = cypress_earthmate_port_probe,
.port_remove = cypress_port_remove,
.open = cypress_open,
.close = cypress_close,
.dtr_rts = cypress_dtr_rts,
......@@ -182,8 +182,8 @@ static struct usb_serial_driver cypress_hidcom_device = {
.description = "HID->COM RS232 Adapter",
.id_table = id_table_cyphidcomrs232,
.num_ports = 1,
.attach = cypress_hidcom_startup,
.release = cypress_release,
.port_probe = cypress_hidcom_port_probe,
.port_remove = cypress_port_remove,
.open = cypress_open,
.close = cypress_close,
.dtr_rts = cypress_dtr_rts,
......@@ -208,8 +208,8 @@ static struct usb_serial_driver cypress_ca42v2_device = {
.description = "Nokia CA-42 V2 Adapter",
.id_table = id_table_nokiaca42v2,
.num_ports = 1,
.attach = cypress_ca42v2_startup,
.release = cypress_release,
.port_probe = cypress_ca42v2_port_probe,
.port_remove = cypress_port_remove,
.open = cypress_open,
.close = cypress_close,
.dtr_rts = cypress_dtr_rts,
......@@ -438,10 +438,10 @@ static void cypress_set_dead(struct usb_serial_port *port)
*****************************************************************************/
static int generic_startup(struct usb_serial *serial)
static int cypress_generic_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
if (!priv)
......@@ -490,14 +490,16 @@ static int generic_startup(struct usb_serial *serial)
}
static int cypress_earthmate_startup(struct usb_serial *serial)
static int cypress_earthmate_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
int ret;
if (generic_startup(serial)) {
ret = cypress_generic_port_probe(port);
if (ret) {
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1;
return ret;
}
priv = usb_get_serial_port_data(port);
......@@ -518,56 +520,53 @@ static int cypress_earthmate_startup(struct usb_serial *serial)
}
return 0;
} /* cypress_earthmate_startup */
}
static int cypress_hidcom_startup(struct usb_serial *serial)
static int cypress_hidcom_port_probe(struct usb_serial_port *port)
{
struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
int ret;
if (generic_startup(serial)) {
ret = cypress_generic_port_probe(port);
if (ret) {
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1;
return ret;
}
priv = usb_get_serial_port_data(port);
priv->chiptype = CT_CYPHIDCOM;
return 0;
} /* cypress_hidcom_startup */
}
static int cypress_ca42v2_startup(struct usb_serial *serial)
static int cypress_ca42v2_port_probe(struct usb_serial_port *port)
{
struct cypress_private *priv;
struct usb_serial_port *port = serial->port[0];
int ret;
if (generic_startup(serial)) {
ret = cypress_generic_port_probe(port);
if (ret) {
dev_dbg(&port->dev, "%s - Failed setting up port\n", __func__);
return 1;
return ret;
}
priv = usb_get_serial_port_data(port);
priv->chiptype = CT_CA42V2;
return 0;
} /* cypress_ca42v2_startup */
}
static void cypress_release(struct usb_serial *serial)
static int cypress_port_remove(struct usb_serial_port *port)
{
struct cypress_private *priv;
/* all open ports are closed at this point */
priv = usb_get_serial_port_data(serial->port[0]);
priv = usb_get_serial_port_data(port);
if (priv) {
kfifo_free(&priv->write_fifo);
kfree(priv);
}
}
return 0;
}
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,
return -ENOIOCTLCMD;
}
static int f81232_startup(struct usb_serial *serial)
static int f81232_port_probe(struct usb_serial_port *port)
{
struct f81232_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) {
priv = kzalloc(sizeof(struct f81232_private), GFP_KERNEL);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
goto cleanup;
return -ENOMEM;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(serial->port[i], priv);
}
return 0;
cleanup:
for (--i; i >= 0; --i) {
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv);
usb_set_serial_port_data(serial->port[i], NULL);
}
return -ENOMEM;
usb_set_serial_port_data(port, priv);
return 0;
}
static void f81232_release(struct usb_serial *serial)
static int f81232_port_remove(struct usb_serial_port *port)
{
int i;
struct f81232_private *priv;
for (i = 0; i < serial->num_ports; ++i) {
priv = usb_get_serial_port_data(serial->port[i]);
priv = usb_get_serial_port_data(port);
kfree(priv);
}
return 0;
}
static struct usb_serial_driver f81232_device = {
......@@ -373,8 +364,8 @@ static struct usb_serial_driver f81232_device = {
.tiocmset = f81232_tiocmset,
.process_read_urb = f81232_process_read_urb,
.read_int_callback = f81232_read_int_callback,
.attach = f81232_startup,
.release = f81232_release,
.port_probe = f81232_port_probe,
.port_remove = f81232_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
......
......@@ -1405,11 +1405,10 @@ static void timeout_handler(unsigned long data)
static int garmin_attach(struct usb_serial *serial)
static int garmin_port_probe(struct usb_serial_port *port)
{
int status = 0;
struct usb_serial_port *port = serial->port[0];
struct garmin_data *garmin_data_p = NULL;
int status;
struct garmin_data *garmin_data_p;
garmin_data_p = kzalloc(sizeof(struct garmin_data), GFP_KERNEL);
if (garmin_data_p == NULL) {
......@@ -1434,22 +1433,14 @@ static int garmin_attach(struct usb_serial *serial)
}
static void garmin_disconnect(struct usb_serial *serial)
static int garmin_port_remove(struct usb_serial_port *port)
{
struct usb_serial_port *port = serial->port[0];
struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
usb_kill_urb(port->interrupt_in_urb);
del_timer_sync(&garmin_data_p->timer);
}
static void garmin_release(struct usb_serial *serial)
{
struct usb_serial_port *port = serial->port[0];
struct garmin_data *garmin_data_p = usb_get_serial_port_data(port);
kfree(garmin_data_p);
return 0;
}
......@@ -1466,9 +1457,8 @@ static struct usb_serial_driver garmin_device = {
.close = garmin_close,
.throttle = garmin_throttle,
.unthrottle = garmin_unthrottle,
.attach = garmin_attach,
.disconnect = garmin_disconnect,
.release = garmin_release,
.port_probe = garmin_port_probe,
.port_remove = garmin_port_remove,
.write = garmin_write,
.write_room = garmin_write_room,
.write_bulk_callback = garmin_write_bulk_callback,
......
......@@ -225,6 +225,8 @@ static int edge_get_icount(struct tty_struct *tty,
static int edge_startup(struct usb_serial *serial);
static void edge_disconnect(struct usb_serial *serial);
static void edge_release(struct usb_serial *serial);
static int edge_port_probe(struct usb_serial_port *port);
static int edge_port_remove(struct usb_serial_port *port);
#include "io_tables.h" /* all of the devices that this driver supports */
......@@ -2875,10 +2877,9 @@ static void load_application_firmware(struct edgeport_serial *edge_serial)
static int edge_startup(struct usb_serial *serial)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
struct usb_device *dev;
struct device *ddev = &serial->dev->dev;
int i, j;
int i;
int response;
bool interrupt_in_found;
bool bulk_in_found;
......@@ -2961,25 +2962,6 @@ static int edge_startup(struct usb_serial *serial)
/* we set up the pointers to the endpoints in the edge_open function,
* as the structures aren't created yet. */
/* set up our port private structures */
for (i = 0; i < serial->num_ports; ++i) {
edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL);
if (edge_port == NULL) {
dev_err(ddev, "%s - Out of memory\n", __func__);
for (j = 0; j < i; ++j) {
kfree(usb_get_serial_port_data(serial->port[j]));
usb_set_serial_port_data(serial->port[j],
NULL);
}
usb_set_serial_data(serial, NULL);
kfree(edge_serial);
return -ENOMEM;
}
spin_lock_init(&edge_port->ep_lock);
edge_port->port = serial->port[i];
usb_set_serial_port_data(serial->port[i], edge_port);
}
response = 0;
if (edge_serial->is_epic) {
......@@ -3120,14 +3102,36 @@ static void edge_disconnect(struct usb_serial *serial)
static void edge_release(struct usb_serial *serial)
{
struct edgeport_serial *edge_serial = usb_get_serial_data(serial);
int i;
for (i = 0; i < serial->num_ports; ++i)
kfree(usb_get_serial_port_data(serial->port[i]));
kfree(edge_serial);
}
static int edge_port_probe(struct usb_serial_port *port)
{
struct edgeport_port *edge_port;
edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL);
if (!edge_port)
return -ENOMEM;
spin_lock_init(&edge_port->ep_lock);
edge_port->port = port;
usb_set_serial_port_data(port, edge_port);
return 0;
}
static int edge_port_remove(struct usb_serial_port *port)
{
struct edgeport_port *edge_port;
edge_port = usb_get_serial_port_data(port);
kfree(edge_port);
return 0;
}
module_usb_serial_driver(serial_drivers, id_table_combined);
MODULE_AUTHOR(DRIVER_AUTHOR);
......
......@@ -110,6 +110,8 @@ static struct usb_serial_driver edgeport_2port_device = {
.attach = edge_startup,
.disconnect = edge_disconnect,
.release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl,
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
......@@ -139,6 +141,8 @@ static struct usb_serial_driver edgeport_4port_device = {
.attach = edge_startup,
.disconnect = edge_disconnect,
.release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl,
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
......@@ -168,6 +172,8 @@ static struct usb_serial_driver edgeport_8port_device = {
.attach = edge_startup,
.disconnect = edge_disconnect,
.release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl,
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
......@@ -197,6 +203,8 @@ static struct usb_serial_driver epic_device = {
.attach = edge_startup,
.disconnect = edge_disconnect,
.release = edge_release,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl,
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
......
......@@ -2532,12 +2532,7 @@ static void edge_break(struct tty_struct *tty, int break_state)
static int edge_startup(struct usb_serial *serial)
{
struct edgeport_serial *edge_serial;
struct edgeport_port *edge_port;
struct usb_device *dev;
int status;
int i;
dev = serial->dev;
/* create our private serial structure */
edge_serial = kzalloc(sizeof(struct edgeport_serial), GFP_KERNEL);
......@@ -2555,59 +2550,63 @@ static int edge_startup(struct usb_serial *serial)
return status;
}
/* set up our port private structures */
for (i = 0; i < serial->num_ports; ++i) {
edge_port = kzalloc(sizeof(struct edgeport_port), GFP_KERNEL);
if (edge_port == NULL) {
dev_err(&serial->dev->dev, "%s - Out of memory\n",
__func__);
goto cleanup;
}
spin_lock_init(&edge_port->ep_lock);
if (kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE,
GFP_KERNEL)) {
dev_err(&serial->dev->dev, "%s - Out of memory\n",
__func__);
return 0;
}
static void edge_disconnect(struct usb_serial *serial)
{
}
static void edge_release(struct usb_serial *serial)
{
kfree(usb_get_serial_data(serial));
}
static int edge_port_probe(struct usb_serial_port *port)
{
struct edgeport_port *edge_port;
int ret;
edge_port = kzalloc(sizeof(*edge_port), GFP_KERNEL);
if (!edge_port)
return -ENOMEM;
ret = kfifo_alloc(&edge_port->write_fifo, EDGE_OUT_BUF_SIZE,
GFP_KERNEL);
if (ret) {
kfree(edge_port);
goto cleanup;
return -ENOMEM;
}
edge_port->port = serial->port[i];
edge_port->edge_serial = edge_serial;
usb_set_serial_port_data(serial->port[i], edge_port);
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;
}
return 0;
usb_set_serial_port_data(port, edge_port);
cleanup:
for (--i; i >= 0; --i) {
edge_port = usb_get_serial_port_data(serial->port[i]);
ret = edge_create_sysfs_attrs(port);
if (ret) {
kfifo_free(&edge_port->write_fifo);
kfree(edge_port);
usb_set_serial_port_data(serial->port[i], NULL);
return ret;
}
kfree(edge_serial);
usb_set_serial_data(serial, NULL);
return -ENOMEM;
}
static void edge_disconnect(struct usb_serial *serial)
{
return 0;
}
static void edge_release(struct usb_serial *serial)
static int edge_port_remove(struct usb_serial_port *port)
{
int i;
struct edgeport_port *edge_port;
for (i = 0; i < serial->num_ports; ++i) {
edge_port = usb_get_serial_port_data(serial->port[i]);
edge_port = usb_get_serial_port_data(port);
edge_remove_sysfs_attrs(port);
kfifo_free(&edge_port->write_fifo);
kfree(edge_port);
}
kfree(usb_get_serial_data(serial));
}
return 0;
}
/* Sysfs Attributes */
......@@ -2667,8 +2666,8 @@ static struct usb_serial_driver edgeport_1port_device = {
.attach = edge_startup,
.disconnect = edge_disconnect,
.release = edge_release,
.port_probe = edge_create_sysfs_attrs,
.port_remove = edge_remove_sysfs_attrs,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl,
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
......@@ -2698,8 +2697,8 @@ static struct usb_serial_driver edgeport_2port_device = {
.attach = edge_startup,
.disconnect = edge_disconnect,
.release = edge_release,
.port_probe = edge_create_sysfs_attrs,
.port_remove = edge_remove_sysfs_attrs,
.port_probe = edge_port_probe,
.port_remove = edge_port_remove,
.ioctl = edge_ioctl,
.set_termios = edge_set_termios,
.tiocmget = edge_tiocmget,
......
......@@ -53,6 +53,8 @@ static int iuu_cardout;
static bool xmas;
static int vcc_default = 5;
static int iuu_create_sysfs_attrs(struct usb_serial_port *port);
static int iuu_remove_sysfs_attrs(struct usb_serial_port *port);
static void read_rxcmd_callback(struct urb *urb);
struct iuu_private {
......@@ -72,63 +74,55 @@ struct iuu_private {
u32 clk;
};
static void iuu_free_buf(struct iuu_private *priv)
{
kfree(priv->buf);
kfree(priv->writebuf);
}
static int iuu_alloc_buf(struct usb_serial *serial, struct iuu_private *priv)
{
priv->buf = kzalloc(256, GFP_KERNEL);
priv->writebuf = kzalloc(256, GFP_KERNEL);
if (!priv->buf || !priv->writebuf) {
iuu_free_buf(priv);
dev_dbg(&serial->dev->dev, "%s problem allocation buffer\n", __func__);
return -ENOMEM;
}
dev_dbg(&serial->dev->dev, "%s - Privates buffers allocation success\n", __func__);
return 0;
}
static int iuu_startup(struct usb_serial *serial)
static int iuu_port_probe(struct usb_serial_port *port)
{
struct iuu_private *priv;
int ret;
priv = kzalloc(sizeof(struct iuu_private), GFP_KERNEL);
dev_dbg(&serial->dev->dev, "%s- priv allocation success\n", __func__);
if (!priv)
return -ENOMEM;
if (iuu_alloc_buf(serial, priv)) {
priv->buf = kzalloc(256, GFP_KERNEL);
if (!priv->buf) {
kfree(priv);
return -ENOMEM;
}
priv->writebuf = kzalloc(256, GFP_KERNEL);
if (!priv->writebuf) {
kfree(priv->buf);
kfree(priv);
return -ENOMEM;
}
priv->vcc = vcc_default;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(serial->port[0], priv);
usb_set_serial_port_data(port, priv);
ret = iuu_create_sysfs_attrs(port);
if (ret) {
kfree(priv->writebuf);
kfree(priv->buf);
kfree(priv);
return ret;
}
return 0;
}
/* Release function */
static void iuu_release(struct usb_serial *serial)
static int iuu_port_remove(struct usb_serial_port *port)
{
struct usb_serial_port *port = serial->port[0];
struct iuu_private *priv = usb_get_serial_port_data(port);
if (!port)
return;
if (priv) {
iuu_free_buf(priv);
dev_dbg(&port->dev, "%s - I will free all\n", __func__);
usb_set_serial_port_data(port, NULL);
dev_dbg(&port->dev, "%s - priv is not anymore in port structure\n", __func__);
iuu_remove_sysfs_attrs(port);
kfree(priv->writebuf);
kfree(priv->buf);
kfree(priv);
dev_dbg(&port->dev, "%s priv is now kfree\n", __func__);
}
return 0;
}
static int iuu_tiocmset(struct tty_struct *tty,
......@@ -1215,8 +1209,6 @@ static struct usb_serial_driver iuu_device = {
.num_ports = 1,
.bulk_in_size = 512,
.bulk_out_size = 512,
.port_probe = iuu_create_sysfs_attrs,
.port_remove = iuu_remove_sysfs_attrs,
.open = iuu_open,
.close = iuu_close,
.write = iuu_uart_write,
......@@ -1225,8 +1217,8 @@ static struct usb_serial_driver iuu_device = {
.tiocmset = iuu_tiocmset,
.set_termios = iuu_set_termios,
.init_termios = iuu_init_termios,
.attach = iuu_startup,
.release = iuu_release,
.port_probe = iuu_port_probe,
.port_remove = iuu_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
......
......@@ -713,29 +713,33 @@ MODULE_FIRMWARE("keyspan_pda/keyspan_pda.fw");
MODULE_FIRMWARE("keyspan_pda/xircom_pgs.fw");
#endif
static int keyspan_pda_startup(struct usb_serial *serial)
static int keyspan_pda_port_probe(struct usb_serial_port *port)
{
struct keyspan_pda_private *priv;
/* allocate the private data structures for all ports. Well, for all
one ports. */
priv = kmalloc(sizeof(struct keyspan_pda_private), GFP_KERNEL);
if (!priv)
return 1; /* error */
usb_set_serial_port_data(serial->port[0], priv);
init_waitqueue_head(&serial->port[0]->write_wait);
return -ENOMEM;
INIT_WORK(&priv->wakeup_work, keyspan_pda_wakeup_write);
INIT_WORK(&priv->unthrottle_work, keyspan_pda_request_unthrottle);
priv->serial = serial;
priv->port = serial->port[0];
priv->serial = port->serial;
priv->port = port;
usb_set_serial_port_data(port, priv);
return 0;
}
static void keyspan_pda_release(struct usb_serial *serial)
static int keyspan_pda_port_remove(struct usb_serial_port *port)
{
kfree(usb_get_serial_port_data(serial->port[0]));
struct keyspan_pda_private *priv;
priv = usb_get_serial_port_data(port);
kfree(priv);
return 0;
}
#ifdef KEYSPAN
......@@ -786,8 +790,8 @@ static struct usb_serial_driver keyspan_pda_device = {
.break_ctl = keyspan_pda_break_ctl,
.tiocmget = keyspan_pda_tiocmget,
.tiocmset = keyspan_pda_tiocmset,
.attach = keyspan_pda_startup,
.release = keyspan_pda_release,
.port_probe = keyspan_pda_port_probe,
.port_remove = keyspan_pda_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
......
......@@ -60,8 +60,8 @@
/*
* Function prototypes
*/
static int klsi_105_startup(struct usb_serial *serial);
static void klsi_105_release(struct usb_serial *serial);
static int klsi_105_port_probe(struct usb_serial_port *port);
static int klsi_105_port_remove(struct usb_serial_port *port);
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port);
static void klsi_105_close(struct usb_serial_port *port);
static void klsi_105_set_termios(struct tty_struct *tty,
......@@ -99,8 +99,8 @@ static struct usb_serial_driver kl5kusb105d_device = {
/*.break_ctl = klsi_105_break_ctl,*/
.tiocmget = klsi_105_tiocmget,
.tiocmset = klsi_105_tiocmset,
.attach = klsi_105_startup,
.release = klsi_105_release,
.port_probe = klsi_105_port_probe,
.port_remove = klsi_105_port_remove,
.throttle = usb_serial_generic_throttle,
.unthrottle = usb_serial_generic_unthrottle,
.process_read_urb = klsi_105_process_read_urb,
......@@ -223,26 +223,14 @@ static int klsi_105_get_line_state(struct usb_serial_port *port,
* Driver's tty interface functions
*/
static int klsi_105_startup(struct usb_serial *serial)
static int klsi_105_port_probe(struct usb_serial_port *port)
{
struct klsi_105_private *priv;
int i;
/* check if we support the product id (see keyspan.c)
* FIXME
*/
priv = kmalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
/* allocate the private data structure */
for (i = 0; i < serial->num_ports; i++) {
priv = kmalloc(sizeof(struct klsi_105_private),
GFP_KERNEL);
if (!priv) {
dev_dbg(&serial->interface->dev,
"%s - kmalloc for klsi_105_private failed.\n",
__func__);
i--;
goto err_cleanup;
}
/* set initial values for control structures */
priv->cfg.pktlen = 5;
priv->cfg.baudrate = kl5kusb105a_sio_b9600;
......@@ -252,31 +240,23 @@ static int klsi_105_startup(struct usb_serial *serial)
priv->line_state = 0;
usb_set_serial_port_data(serial->port[i], priv);
spin_lock_init(&priv->lock);
/* priv->termios is left uninitialized until port opening */
init_waitqueue_head(&serial->port[i]->write_wait);
}
return 0;
usb_set_serial_port_data(port, priv);
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;
return 0;
}
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)
kfree(usb_get_serial_port_data(serial->port[i]));
return 0;
}
static int klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
......
......@@ -54,8 +54,8 @@
/* Function prototypes */
static int kobil_startup(struct usb_serial *serial);
static void kobil_release(struct usb_serial *serial);
static int kobil_port_probe(struct usb_serial_port *probe);
static int kobil_port_remove(struct usb_serial_port *probe);
static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port);
static void kobil_close(struct usb_serial_port *port);
static int kobil_write(struct tty_struct *tty, struct usb_serial_port *port,
......@@ -89,8 +89,8 @@ static struct usb_serial_driver kobil_device = {
.description = "KOBIL USB smart card terminal",
.id_table = id_table,
.num_ports = 1,
.attach = kobil_startup,
.release = kobil_release,
.port_probe = kobil_port_probe,
.port_remove = kobil_port_remove,
.ioctl = kobil_ioctl,
.set_termios = kobil_set_termios,
.init_termios = kobil_init_termios,
......@@ -117,9 +117,10 @@ struct kobil_private {
};
static int kobil_startup(struct usb_serial *serial)
static int kobil_port_probe(struct usb_serial_port *port)
{
int i;
struct usb_serial *serial = port->serial;
struct kobil_private *priv;
struct usb_device *pdev;
struct usb_host_config *actconfig;
......@@ -149,7 +150,7 @@ static int kobil_startup(struct usb_serial *serial)
dev_dbg(&serial->dev->dev, "KOBIL KAAN SIM detected\n");
break;
}
usb_set_serial_port_data(serial->port[0], priv);
usb_set_serial_port_data(port, priv);
/* search for the necessary endpoints */
pdev = serial->dev;
......@@ -179,12 +180,14 @@ static int kobil_startup(struct usb_serial *serial)
}
static void kobil_release(struct usb_serial *serial)
static int kobil_port_remove(struct usb_serial_port *port)
{
int i;
struct kobil_private *priv;
for (i = 0; i < serial->num_ports; ++i)
kfree(usb_get_serial_port_data(serial->port[i]));
priv = usb_get_serial_port_data(port);
kfree(priv);
return 0;
}
static void kobil_init_termios(struct tty_struct *tty)
......
This diff is collapsed.
......@@ -137,8 +137,8 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty);
static int oti6858_tiocmget(struct tty_struct *tty);
static int oti6858_tiocmset(struct tty_struct *tty,
unsigned int set, unsigned int clear);
static int oti6858_startup(struct usb_serial *serial);
static void oti6858_release(struct usb_serial *serial);
static int oti6858_port_probe(struct usb_serial_port *port);
static int oti6858_port_remove(struct usb_serial_port *port);
/* device info */
static struct usb_serial_driver oti6858_device = {
......@@ -161,8 +161,8 @@ static struct usb_serial_driver oti6858_device = {
.write_bulk_callback = oti6858_write_bulk_callback,
.write_room = oti6858_write_room,
.chars_in_buffer = oti6858_chars_in_buffer,
.attach = oti6858_startup,
.release = oti6858_release,
.port_probe = oti6858_port_probe,
.port_remove = oti6858_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
......@@ -331,36 +331,33 @@ static void send_data(struct work_struct *work)
usb_serial_port_softint(port);
}
static int oti6858_startup(struct usb_serial *serial)
static int oti6858_port_probe(struct usb_serial_port *port)
{
struct usb_serial_port *port = serial->port[0];
struct oti6858_private *priv;
int i;
for (i = 0; i < serial->num_ports; ++i) {
priv = kzalloc(sizeof(struct oti6858_private), GFP_KERNEL);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
break;
return -ENOMEM;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->intr_wait);
/* INIT_WORK(&priv->setup_work, setup_line, serial->port[i]); */
/* INIT_WORK(&priv->write_work, send_data, serial->port[i]); */
priv->port = port;
INIT_DELAYED_WORK(&priv->delayed_setup_work, setup_line);
INIT_DELAYED_WORK(&priv->delayed_write_work, send_data);
usb_set_serial_port_data(serial->port[i], priv);
}
if (i == serial->num_ports)
usb_set_serial_port_data(port, priv);
return 0;
}
for (--i; i >= 0; --i) {
priv = usb_get_serial_port_data(serial->port[i]);
static int oti6858_port_remove(struct usb_serial_port *port)
{
struct oti6858_private *priv;
priv = usb_get_serial_port_data(port);
kfree(priv);
usb_set_serial_port_data(serial->port[i], NULL);
}
return -ENOMEM;
return 0;
}
static int oti6858_write(struct tty_struct *tty, struct usb_serial_port *port,
......@@ -709,15 +706,6 @@ static int oti6858_ioctl(struct tty_struct *tty,
return -ENOIOCTLCMD;
}
static void oti6858_release(struct usb_serial *serial)
{
int i;
for (i = 0; i < serial->num_ports; ++i)
kfree(usb_get_serial_port_data(serial->port[i]));
}
static void oti6858_read_int_callback(struct urb *urb)
{
struct usb_serial_port *port = urb->context;
......
......@@ -133,12 +133,15 @@ enum pl2303_type {
HX, /* HX version of the pl2303 chip */
};
struct pl2303_serial_private {
enum pl2303_type type;
};
struct pl2303_private {
spinlock_t lock;
wait_queue_head_t delta_msr_wait;
u8 line_control;
u8 line_status;
enum pl2303_type type;
};
static int pl2303_vendor_read(__u16 value, __u16 index,
......@@ -167,14 +170,19 @@ static int pl2303_vendor_write(__u16 value, __u16 index,
static int pl2303_startup(struct usb_serial *serial)
{
struct pl2303_private *priv;
struct pl2303_serial_private *spriv;
enum pl2303_type type = type_0;
unsigned char *buf;
int i;
spriv = kzalloc(sizeof(*spriv), GFP_KERNEL);
if (!spriv)
return -ENOMEM;
buf = kmalloc(10, GFP_KERNEL);
if (buf == NULL)
if (!buf) {
kfree(spriv);
return -ENOMEM;
}
if (serial->dev->descriptor.bDeviceClass == 0x02)
type = type_0;
......@@ -186,15 +194,8 @@ static int pl2303_startup(struct usb_serial *serial)
type = type_1;
dev_dbg(&serial->interface->dev, "device type: %d\n", type);
for (i = 0; i < serial->num_ports; ++i) {
priv = kzalloc(sizeof(struct pl2303_private), GFP_KERNEL);
if (!priv)
goto cleanup;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait);
priv->type = type;
usb_set_serial_port_data(serial->port[i], priv);
}
spriv->type = type;
usb_set_serial_data(serial, spriv);
pl2303_vendor_read(0x8484, 0, serial, buf);
pl2303_vendor_write(0x0404, 0, serial);
......@@ -213,15 +214,40 @@ static int pl2303_startup(struct usb_serial *serial)
kfree(buf);
return 0;
}
cleanup:
kfree(buf);
for (--i; i >= 0; --i) {
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv);
usb_set_serial_port_data(serial->port[i], NULL);
}
static void pl2303_release(struct usb_serial *serial)
{
struct pl2303_serial_private *spriv;
spriv = usb_get_serial_data(serial);
kfree(spriv);
}
static int pl2303_port_probe(struct usb_serial_port *port)
{
struct pl2303_private *priv;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);
return 0;
}
static int pl2303_port_remove(struct usb_serial_port *port)
{
struct pl2303_private *priv;
priv = usb_get_serial_port_data(port);
kfree(priv);
return 0;
}
static int set_control_lines(struct usb_device *dev, u8 value)
......@@ -240,6 +266,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
struct usb_serial_port *port, struct ktermios *old_termios)
{
struct usb_serial *serial = port->serial;
struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
struct pl2303_private *priv = usb_get_serial_port_data(port);
unsigned long flags;
unsigned int cflag;
......@@ -323,7 +350,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
}
if (baud > 1228800) {
/* type_0, type_1 only support up to 1228800 baud */
if (priv->type != HX)
if (spriv->type != HX)
baud = 1228800;
else if (baud > 6000000)
baud = 6000000;
......@@ -426,7 +453,7 @@ static void pl2303_set_termios(struct tty_struct *tty,
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6]);
if (cflag & CRTSCTS) {
if (priv->type == HX)
if (spriv->type == HX)
pl2303_vendor_write(0x0, 0x61, serial);
else
pl2303_vendor_write(0x0, 0x41, serial);
......@@ -468,10 +495,10 @@ static int pl2303_open(struct tty_struct *tty, struct usb_serial_port *port)
{
struct ktermios tmp_termios;
struct usb_serial *serial = port->serial;
struct pl2303_private *priv = usb_get_serial_port_data(port);
struct pl2303_serial_private *spriv = usb_get_serial_data(serial);
int result;
if (priv->type != HX) {
if (spriv->type != HX) {
usb_clear_halt(serial->dev, port->write_urb->pipe);
usb_clear_halt(serial->dev, port->read_urb->pipe);
} else {
......@@ -655,17 +682,6 @@ static void pl2303_break_ctl(struct tty_struct *tty, int break_state)
dev_err(&port->dev, "error sending break = %d\n", result);
}
static void pl2303_release(struct usb_serial *serial)
{
int i;
struct pl2303_private *priv;
for (i = 0; i < serial->num_ports; ++i) {
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv);
}
}
static void pl2303_update_line_status(struct usb_serial_port *port,
unsigned char *data,
unsigned int actual_length)
......@@ -827,6 +843,8 @@ static struct usb_serial_driver pl2303_device = {
.read_int_callback = pl2303_read_int_callback,
.attach = pl2303_startup,
.release = pl2303_release,
.port_probe = pl2303_port_probe,
.port_remove = pl2303_port_remove,
};
static struct usb_serial_driver * const serial_drivers[] = {
......
......@@ -157,13 +157,10 @@ struct spcp8x5_private {
u8 line_status;
};
/* desc : when device plug in,this function would be called.
* thanks to usb_serial subsystem,then do almost every things for us. And what
* we should do just alloc the buffer */
static int spcp8x5_startup(struct usb_serial *serial)
static int spcp8x5_port_probe(struct usb_serial_port *port)
{
struct usb_serial *serial = port->serial;
struct spcp8x5_private *priv;
int i;
enum spcp8x5_type type = SPCP825_007_TYPE;
u16 product = le16_to_cpu(serial->dev->descriptor.idProduct);
......@@ -180,34 +177,27 @@ static int spcp8x5_startup(struct usb_serial *serial)
type = SPCP825_PHILIP_TYPE;
dev_dbg(&serial->dev->dev, "device type = %d\n", (int)type);
for (i = 0; i < serial->num_ports; ++i) {
priv = kzalloc(sizeof(struct spcp8x5_private), GFP_KERNEL);
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
goto cleanup;
return -ENOMEM;
spin_lock_init(&priv->lock);
init_waitqueue_head(&priv->delta_msr_wait);
priv->type = type;
usb_set_serial_port_data(serial->port[i] , priv);
}
usb_set_serial_port_data(port , priv);
return 0;
cleanup:
for (--i; i >= 0; --i) {
priv = usb_get_serial_port_data(serial->port[i]);
kfree(priv);
usb_set_serial_port_data(serial->port[i] , NULL);
}
return -ENOMEM;
}
/* call when the device plug out. free all the memory alloced by probe */
static void spcp8x5_release(struct usb_serial *serial)
static int spcp8x5_port_remove(struct usb_serial_port *port)
{
int i;
struct spcp8x5_private *priv;
for (i = 0; i < serial->num_ports; i++)
kfree(usb_get_serial_port_data(serial->port[i]));
priv = usb_get_serial_port_data(port);
kfree(priv);
return 0;
}
/* set the modem control line of the device.
......@@ -649,8 +639,8 @@ static struct usb_serial_driver spcp8x5_device = {
.ioctl = spcp8x5_ioctl,
.tiocmget = spcp8x5_tiocmget,
.tiocmset = spcp8x5_tiocmset,
.attach = spcp8x5_startup,
.release = spcp8x5_release,
.port_probe = spcp8x5_port_probe,
.port_remove = spcp8x5_port_remove,
.process_read_urb = spcp8x5_process_read_urb,
};
......
......@@ -67,13 +67,6 @@ struct ssu100_port_private {
struct async_icount icount;
};
static void ssu100_release(struct usb_serial *serial)
{
struct ssu100_port_private *priv = usb_get_serial_port_data(*serial->port);
kfree(priv);
}
static inline int ssu100_control_msg(struct usb_device *dev,
u8 request, u16 data, u16 index)
{
......@@ -441,22 +434,34 @@ static int ssu100_ioctl(struct tty_struct *tty,
}
static int ssu100_attach(struct usb_serial *serial)
{
return ssu100_initdevice(serial->dev);
}
static int ssu100_port_probe(struct usb_serial_port *port)
{
struct ssu100_port_private *priv;
struct usb_serial_port *port = *serial->port;
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv) {
dev_err(&port->dev, "%s- kmalloc(%Zd) failed.\n", __func__,
sizeof(*priv));
if (!priv)
return -ENOMEM;
}
spin_lock_init(&priv->status_lock);
init_waitqueue_head(&priv->delta_msr_wait);
usb_set_serial_port_data(port, priv);
return ssu100_initdevice(serial->dev);
return 0;
}
static int ssu100_port_remove(struct usb_serial_port *port)
{
struct ssu100_port_private *priv;
priv = usb_get_serial_port_data(port);
kfree(priv);
return 0;
}
static int ssu100_tiocmget(struct tty_struct *tty)
......@@ -647,7 +652,8 @@ static struct usb_serial_driver ssu100_device = {
.open = ssu100_open,
.close = ssu100_close,
.attach = ssu100_attach,
.release = ssu100_release,
.port_probe = ssu100_port_probe,
.port_remove = ssu100_port_remove,
.dtr_rts = ssu100_dtr_rts,
.process_read_urb = ssu100_process_read_urb,
.tiocmget = ssu100_tiocmget,
......
......@@ -97,6 +97,8 @@ struct ti_device {
static int ti_startup(struct usb_serial *serial);
static void ti_release(struct usb_serial *serial);
static int ti_port_probe(struct usb_serial_port *port);
static int ti_port_remove(struct usb_serial_port *port);
static int ti_open(struct tty_struct *tty, struct usb_serial_port *port);
static void ti_close(struct usb_serial_port *port);
static int ti_write(struct tty_struct *tty, struct usb_serial_port *port,
......@@ -221,6 +223,8 @@ static struct usb_serial_driver ti_1port_device = {
.num_ports = 1,
.attach = ti_startup,
.release = ti_release,
.port_probe = ti_port_probe,
.port_remove = ti_port_remove,
.open = ti_open,
.close = ti_close,
.write = ti_write,
......@@ -249,6 +253,8 @@ static struct usb_serial_driver ti_2port_device = {
.num_ports = 2,
.attach = ti_startup,
.release = ti_release,
.port_probe = ti_port_probe,
.port_remove = ti_port_remove,
.open = ti_open,
.close = ti_close,
.write = ti_write,
......@@ -347,11 +353,8 @@ module_exit(ti_exit);
static int ti_startup(struct usb_serial *serial)
{
struct ti_device *tdev;
struct ti_port *tport;
struct usb_device *dev = serial->dev;
int status;
int i;
dev_dbg(&dev->dev,
"%s - product 0x%4X, num configurations %d, configuration value %d",
......@@ -399,42 +402,8 @@ static int ti_startup(struct usb_serial *serial)
goto free_tdev;
}
/* set up port structures */
for (i = 0; i < serial->num_ports; ++i) {
tport = kzalloc(sizeof(struct ti_port), GFP_KERNEL);
if (tport == NULL) {
dev_err(&dev->dev, "%s - out of memory\n", __func__);
status = -ENOMEM;
goto free_tports;
}
spin_lock_init(&tport->tp_lock);
tport->tp_uart_base_addr = (i == 0 ?
TI_UART1_BASE_ADDR : TI_UART2_BASE_ADDR);
tport->tp_closing_wait = closing_wait;
init_waitqueue_head(&tport->tp_msr_wait);
init_waitqueue_head(&tport->tp_write_wait);
if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE,
GFP_KERNEL)) {
dev_err(&dev->dev, "%s - out of memory\n", __func__);
kfree(tport);
status = -ENOMEM;
goto free_tports;
}
tport->tp_port = serial->port[i];
tport->tp_tdev = tdev;
usb_set_serial_port_data(serial->port[i], tport);
tport->tp_uart_mode = 0; /* default is RS232 */
}
return 0;
free_tports:
for (--i; i >= 0; --i) {
tport = usb_get_serial_port_data(serial->port[i]);
kfifo_free(&tport->write_fifo);
kfree(tport);
usb_set_serial_port_data(serial->port[i], NULL);
}
free_tdev:
kfree(tdev);
usb_set_serial_data(serial, NULL);
......@@ -444,21 +413,50 @@ static int ti_startup(struct usb_serial *serial)
static void ti_release(struct usb_serial *serial)
{
int i;
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;
for (i = 0; i < serial->num_ports; ++i) {
tport = usb_get_serial_port_data(serial->port[i]);
if (tport) {
kfifo_free(&tport->write_fifo);
tport = kzalloc(sizeof(*tport), GFP_KERNEL);
if (!tport)
return -ENOMEM;
spin_lock_init(&tport->tp_lock);
if (port == port->serial->port[0])
tport->tp_uart_base_addr = TI_UART1_BASE_ADDR;
else
tport->tp_uart_base_addr = TI_UART2_BASE_ADDR;
tport->tp_closing_wait = closing_wait;
init_waitqueue_head(&tport->tp_msr_wait);
init_waitqueue_head(&tport->tp_write_wait);
if (kfifo_alloc(&tport->write_fifo, TI_WRITE_BUF_SIZE, GFP_KERNEL)) {
kfree(tport);
return -ENOMEM;
}
}
tport->tp_port = port;
tport->tp_tdev = usb_get_serial_data(port->serial);
tport->tp_uart_mode = 0; /* default is RS232 */
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)
{
......
......@@ -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_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 */
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
This diff is collapsed.
This diff is collapsed.
#ifndef __LINUX_FUNCTIONFS_H__
#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 usb_composite_dev;
......@@ -197,5 +34,3 @@ static void functionfs_release_dev_callback(struct ffs_data *ffs_data)
#endif
#endif
# 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
This diff is collapsed.
This diff is collapsed.
#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%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment