Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0dffb486 authored by Bjørn Mork's avatar Bjørn Mork Committed by Greg Kroah-Hartman
Browse files

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: default avatarBjørn Mork <bjorn@mork.no>
Acked-by: default avatarOliver Neukum <oneukum@suse.de>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c1cee1d8
Loading
Loading
Loading
Loading
+54 −51
Original line number Original line Diff line number Diff line
@@ -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 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
	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 @@ static int wdm_probe(struct usb_interface *intf, const struct usb_device_id *id)
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;
}
}