usb: cdc-wdm: split out reusable parts of probe
Preparing for the addition of subdriver registering as an alternative to probe for interface-less usage. This should not change anything apart from minor code reordering. Signed-off-by: Bjørn Mork <bjorn@mork.no> Acked-by: Oliver Neukum <oneukum@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
c1cee1d840
commit
0dffb4862a
1 changed files with 54 additions and 51 deletions
|
@ -631,47 +631,11 @@ static void wdm_rxwork(struct work_struct *work)
|
||||||
|
|
||||||
/* --- hotplug --- */
|
/* --- hotplug --- */
|
||||||
|
|
||||||
static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
static int wdm_create(struct usb_interface *intf, struct usb_endpoint_descriptor *ep, u16 bufsize)
|
||||||
{
|
{
|
||||||
int rv = -EINVAL;
|
int rv = -ENOMEM;
|
||||||
struct wdm_device *desc;
|
struct wdm_device *desc;
|
||||||
struct usb_host_interface *iface;
|
|
||||||
struct usb_endpoint_descriptor *ep;
|
|
||||||
struct usb_cdc_dmm_desc *dmhd;
|
|
||||||
u8 *buffer = intf->altsetting->extra;
|
|
||||||
int buflen = intf->altsetting->extralen;
|
|
||||||
u16 maxcom = WDM_DEFAULT_BUFSIZE;
|
|
||||||
|
|
||||||
if (!buffer)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
while (buflen > 2) {
|
|
||||||
if (buffer [1] != USB_DT_CS_INTERFACE) {
|
|
||||||
dev_err(&intf->dev, "skipping garbage\n");
|
|
||||||
goto next_desc;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (buffer [2]) {
|
|
||||||
case USB_CDC_HEADER_TYPE:
|
|
||||||
break;
|
|
||||||
case USB_CDC_DMM_TYPE:
|
|
||||||
dmhd = (struct usb_cdc_dmm_desc *)buffer;
|
|
||||||
maxcom = le16_to_cpu(dmhd->wMaxCommand);
|
|
||||||
dev_dbg(&intf->dev,
|
|
||||||
"Finding maximum buffer length: %d", maxcom);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
dev_err(&intf->dev,
|
|
||||||
"Ignoring extra header, type %d, length %d\n",
|
|
||||||
buffer[2], buffer[0]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
next_desc:
|
|
||||||
buflen -= buffer[0];
|
|
||||||
buffer += buffer[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
rv = -ENOMEM;
|
|
||||||
desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
|
desc = kzalloc(sizeof(struct wdm_device), GFP_KERNEL);
|
||||||
if (!desc)
|
if (!desc)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -679,18 +643,14 @@ next_desc:
|
||||||
mutex_init(&desc->wlock);
|
mutex_init(&desc->wlock);
|
||||||
spin_lock_init(&desc->iuspin);
|
spin_lock_init(&desc->iuspin);
|
||||||
init_waitqueue_head(&desc->wait);
|
init_waitqueue_head(&desc->wait);
|
||||||
desc->wMaxCommand = maxcom;
|
desc->wMaxCommand = bufsize;
|
||||||
/* this will be expanded and needed in hardware endianness */
|
/* this will be expanded and needed in hardware endianness */
|
||||||
desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
|
desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
|
||||||
desc->intf = intf;
|
desc->intf = intf;
|
||||||
INIT_WORK(&desc->rxwork, wdm_rxwork);
|
INIT_WORK(&desc->rxwork, wdm_rxwork);
|
||||||
|
|
||||||
rv = -EINVAL;
|
rv = -EINVAL;
|
||||||
iface = intf->cur_altsetting;
|
if (!usb_endpoint_is_int_in(ep))
|
||||||
if (iface->desc.bNumEndpoints != 1)
|
|
||||||
goto err;
|
|
||||||
ep = &iface->endpoint[0].desc;
|
|
||||||
if (!ep || !usb_endpoint_is_int_in(ep))
|
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
desc->wMaxPacketSize = usb_endpoint_maxp(ep);
|
desc->wMaxPacketSize = usb_endpoint_maxp(ep);
|
||||||
|
@ -766,13 +726,56 @@ out:
|
||||||
err2:
|
err2:
|
||||||
usb_set_intfdata(intf, NULL);
|
usb_set_intfdata(intf, NULL);
|
||||||
err:
|
err:
|
||||||
free_urbs(desc);
|
cleanup(desc);
|
||||||
kfree(desc->inbuf);
|
return rv;
|
||||||
kfree(desc->sbuf);
|
}
|
||||||
kfree(desc->ubuf);
|
|
||||||
kfree(desc->orq);
|
static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
|
||||||
kfree(desc->irq);
|
{
|
||||||
kfree(desc);
|
int rv = -EINVAL;
|
||||||
|
struct usb_host_interface *iface;
|
||||||
|
struct usb_endpoint_descriptor *ep;
|
||||||
|
struct usb_cdc_dmm_desc *dmhd;
|
||||||
|
u8 *buffer = intf->altsetting->extra;
|
||||||
|
int buflen = intf->altsetting->extralen;
|
||||||
|
u16 maxcom = WDM_DEFAULT_BUFSIZE;
|
||||||
|
|
||||||
|
if (!buffer)
|
||||||
|
goto err;
|
||||||
|
while (buflen > 2) {
|
||||||
|
if (buffer[1] != USB_DT_CS_INTERFACE) {
|
||||||
|
dev_err(&intf->dev, "skipping garbage\n");
|
||||||
|
goto next_desc;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (buffer[2]) {
|
||||||
|
case USB_CDC_HEADER_TYPE:
|
||||||
|
break;
|
||||||
|
case USB_CDC_DMM_TYPE:
|
||||||
|
dmhd = (struct usb_cdc_dmm_desc *)buffer;
|
||||||
|
maxcom = le16_to_cpu(dmhd->wMaxCommand);
|
||||||
|
dev_dbg(&intf->dev,
|
||||||
|
"Finding maximum buffer length: %d", maxcom);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
dev_err(&intf->dev,
|
||||||
|
"Ignoring extra header, type %d, length %d\n",
|
||||||
|
buffer[2], buffer[0]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
next_desc:
|
||||||
|
buflen -= buffer[0];
|
||||||
|
buffer += buffer[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
iface = intf->cur_altsetting;
|
||||||
|
if (iface->desc.bNumEndpoints != 1)
|
||||||
|
goto err;
|
||||||
|
ep = &iface->endpoint[0].desc;
|
||||||
|
|
||||||
|
rv = wdm_create(intf, ep, maxcom);
|
||||||
|
|
||||||
|
err:
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue