Signed-off-by: Bjørn Mork <bjorn@xxxxxxx> --- drivers/usb/class/cdc-wdm.c | 39 +++++++++++++++++++++++++++++++++++---- drivers/usb/class/cdc-wdm.h | 10 ++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 drivers/usb/class/cdc-wdm.h diff --git a/drivers/usb/class/cdc-wdm.c b/drivers/usb/class/cdc-wdm.c index af93df9..f83198d 100644 --- a/drivers/usb/class/cdc-wdm.c +++ b/drivers/usb/class/cdc-wdm.c @@ -23,6 +23,7 @@ #include <linux/usb/cdc.h> #include <asm/byteorder.h> #include <asm/unaligned.h> +#include "cdc-wdm.h" /* * Version Information @@ -126,6 +127,8 @@ static struct wdm_device *wdm_get_device(struct usb_interface *intf) pr_debug("%s: intf->dev.driver=%p, &wdm_driver=%p\n", __func__, to_usb_driver(intf->dev.driver), &wdm_driver); mutex_lock(&wdm_mutex); + + /* shortcircuit catching the normal case */ if (to_usb_driver(intf->dev.driver) == &wdm_driver) desc = usb_get_intfdata(intf); else @@ -313,6 +316,7 @@ static void free_urbs(struct wdm_device *desc) static void cleanup(struct wdm_device *desc) { + list_del(&desc->device_list); kfree(desc->sbuf); kfree(desc->inbuf); kfree(desc->orq); @@ -823,6 +827,30 @@ err: return rv; } +struct usb_driver *wdm_register(struct usb_interface *intf, int bufsize) +{ + int rv = -EINVAL; + struct wdm_device *desc; + + desc = wdm_create(intf, bufsize); + if (IS_ERR(desc)) { + rv = PTR_ERR(desc); + goto err; + } + rv = usb_register_dev(intf, &wdm_class); + if (rv < 0) + goto err2; + else + dev_info(&intf->dev, "%s: USB WDM device\n", dev_name(intf->usb_dev)); + + return &wdm_driver; +err2: + cleanup(desc); +err: + return ERR_PTR(rv); +} +EXPORT_SYMBOL(wdm_register); + static void wdm_destroy(struct wdm_device *desc) { unsigned long flags; @@ -844,12 +872,9 @@ static void wdm_destroy(struct wdm_device *desc) cancel_work_sync(&desc->rxwork); mutex_unlock(&desc->wlock); mutex_unlock(&desc->rlock); - if (!desc->count) { - list_del(&desc->device_list); + if (!desc->count) cleanup(desc); - } mutex_unlock(&wdm_mutex); - } static void wdm_disconnect(struct usb_interface *intf) @@ -860,6 +885,12 @@ static void wdm_disconnect(struct usb_interface *intf) wdm_destroy(desc); } +void wdm_deregister(struct usb_interface *intf) +{ + wdm_disconnect(intf); +} +EXPORT_SYMBOL(wdm_deregister); + #ifdef CONFIG_PM static int wdm_suspend(struct usb_interface *intf, pm_message_t message) { diff --git a/drivers/usb/class/cdc-wdm.h b/drivers/usb/class/cdc-wdm.h new file mode 100644 index 0000000..ff6a47c --- /dev/null +++ b/drivers/usb/class/cdc-wdm.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2012 Bjørn Mork <bjorn@xxxxxxx> + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * version 2 as published by the Free Software Foundation. + */ + +extern struct usb_driver *wdm_register(struct usb_interface *intf, int bufsize); +extern void wdm_deregister(struct usb_interface *intf); -- 1.7.8.3 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html