1
0
Fork 0

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>
hifive-unleashed-5.1
Bjørn Mork 2012-03-06 17:29:20 +01:00 committed by Greg Kroah-Hartman
parent c1cee1d840
commit 0dffb4862a
1 changed files with 54 additions and 51 deletions

View File

@ -631,47 +631,11 @@ static void wdm_rxwork(struct work_struct *work)
/* --- 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 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);
if (!desc)
goto out;
@ -679,18 +643,14 @@ next_desc:
mutex_init(&desc->wlock);
spin_lock_init(&desc->iuspin);
init_waitqueue_head(&desc->wait);
desc->wMaxCommand = maxcom;
desc->wMaxCommand = bufsize;
/* this will be expanded and needed in hardware endianness */
desc->inum = cpu_to_le16((u16)intf->cur_altsetting->desc.bInterfaceNumber);
desc->intf = intf;
INIT_WORK(&desc->rxwork, wdm_rxwork);
rv = -EINVAL;
iface = intf->cur_altsetting;
if (iface->desc.bNumEndpoints != 1)
goto err;
ep = &iface->endpoint[0].desc;
if (!ep || !usb_endpoint_is_int_in(ep))
if (!usb_endpoint_is_int_in(ep))
goto err;
desc->wMaxPacketSize = usb_endpoint_maxp(ep);
@ -766,13 +726,56 @@ out:
err2:
usb_set_intfdata(intf, NULL);
err:
free_urbs(desc);
kfree(desc->inbuf);
kfree(desc->sbuf);
kfree(desc->ubuf);
kfree(desc->orq);
kfree(desc->irq);
kfree(desc);
cleanup(desc);
return rv;
}
static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
{
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;
}