From 719df469cb51199316ae2a11c75a8046be34b899 Mon Sep 17 00:00:00 2001 From: Roman Kagan Date: Fri, 6 May 2005 00:55:56 +0400 Subject: [PATCH] USB: update urb documentation On Wed, May 04, 2005 at 01:37:30PM -0700, David Brownell wrote: > On Wednesday 04 May 2005 12:19 pm, Roman Kagan wrote: > > struct urb { > > /* private, usb core and host controller only fields in the urb */ > > ... > > struct list_head urb_list; /* list pointer to all active urbs */ > > ... > > }; > > > > Is it safe to use it for driver's purposes when the driver owns the urb, > > that is, starting from the completion routine until the urb is submitted > > with usb_submit_urb()? > > Right now, it should be. Great! FWIW I've briefly tested a modified version of usbatm using the list head in struct urb instead of creating a wrapper struct, and I haven't seen any failures yet. So I tend to believe that your "should be" actually means "is" :) > > If it is, can it be guaranteed in future, e.g. > > by moving the list head into the public section of struct urb? > > In fact I'm not sure why it ever got called "private" to usbcore/hcds. > I thought the idea was that it should be like urb->status, reserved for > whoever controls the URB. OK then how about the following (essentially documentation) patch? Signed-off-by: Roman Kagan Acked-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- include/linux/usb.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'include/linux/usb.h') diff --git a/include/linux/usb.h b/include/linux/usb.h index 41d1a644c9d4..2d1ac5058534 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -796,6 +796,10 @@ typedef void (*usb_complete_t)(struct urb *, struct pt_regs *); * of the iso_frame_desc array, and the number of errors is reported in * error_count. Completion callbacks for ISO transfers will normally * (re)submit URBs to ensure a constant transfer rate. + * + * Note that even fields marked "public" should not be touched by the driver + * when the urb is owned by the hcd, that is, since the call to + * usb_submit_urb() till the entry into the completion routine. */ struct urb { @@ -803,12 +807,12 @@ struct urb struct kref kref; /* reference count of the URB */ spinlock_t lock; /* lock for the URB */ void *hcpriv; /* private data for host controller */ - struct list_head urb_list; /* list pointer to all active urbs */ int bandwidth; /* bandwidth for INT/ISO request */ atomic_t use_count; /* concurrent submissions counter */ u8 reject; /* submissions will fail */ /* public, documented fields in the urb that can be used by drivers */ + struct list_head urb_list; /* list head for use by the urb owner */ struct usb_device *dev; /* (in) pointer to associated device */ unsigned int pipe; /* (in) pipe information */ int status; /* (return) non-ISO status */ -- cgit v1.2.3 From 8561b10f6e7ef0a085709ffc844f74130a067abe Mon Sep 17 00:00:00 2001 From: "gregkh@suse.de" Date: Tue, 15 Mar 2005 15:10:13 -0800 Subject: [PATCH] USB: move the usb hcd code to use the new class code. This moves a kref into the main hcd structure, which detaches it from the class device structure. Signed-off-by: Greg Kroah-Hartman --- drivers/usb/core/hcd.c | 61 ++++++++++++++++++++------------------------- drivers/usb/host/ehci-dbg.c | 10 ++++---- drivers/usb/host/ohci-dbg.c | 10 ++++---- include/linux/usb.h | 5 ++-- 4 files changed, 39 insertions(+), 47 deletions(-) (limited to 'include/linux/usb.h') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 266e9e06a9f5..d041782e0c8b 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -651,50 +651,45 @@ static int usb_rh_urb_dequeue (struct usb_hcd *hcd, struct urb *urb) /*-------------------------------------------------------------------------*/ /* exported only within usbcore */ -struct usb_bus *usb_bus_get (struct usb_bus *bus) +struct usb_bus *usb_bus_get(struct usb_bus *bus) { - struct class_device *tmp; + if (bus) + kref_get(&bus->kref); + return bus; +} - if (!bus) - return NULL; +static void usb_host_release(struct kref *kref) +{ + struct usb_bus *bus = container_of(kref, struct usb_bus, kref); - tmp = class_device_get(&bus->class_dev); - if (tmp) - return to_usb_bus(tmp); - else - return NULL; + if (bus->release) + bus->release(bus); } /* exported only within usbcore */ -void usb_bus_put (struct usb_bus *bus) +void usb_bus_put(struct usb_bus *bus) { if (bus) - class_device_put(&bus->class_dev); + kref_put(&bus->kref, usb_host_release); } /*-------------------------------------------------------------------------*/ -static void usb_host_release(struct class_device *class_dev) -{ - struct usb_bus *bus = to_usb_bus(class_dev); - - if (bus->release) - bus->release(bus); -} - -static struct class usb_host_class = { - .name = "usb_host", - .release = &usb_host_release, -}; +static struct class *usb_host_class; int usb_host_init(void) { - return class_register(&usb_host_class); + int retval = 0; + + usb_host_class = class_create(THIS_MODULE, "usb_host"); + if (IS_ERR(usb_host_class)) + retval = PTR_ERR(usb_host_class); + return retval; } void usb_host_cleanup(void) { - class_unregister(&usb_host_class); + class_destroy(usb_host_class); } /** @@ -719,8 +714,7 @@ static void usb_bus_init (struct usb_bus *bus) INIT_LIST_HEAD (&bus->bus_list); - class_device_initialize(&bus->class_dev); - bus->class_dev.class = &usb_host_class; + kref_init(&bus->kref); } /** @@ -761,7 +755,6 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op) static int usb_register_bus(struct usb_bus *bus) { int busnum; - int retval; down (&usb_bus_list_lock); busnum = find_next_zero_bit (busmap.busmap, USB_MAXBUS, 1); @@ -774,15 +767,15 @@ static int usb_register_bus(struct usb_bus *bus) return -E2BIG; } - snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum); - bus->class_dev.dev = bus->controller; - retval = class_device_add(&bus->class_dev); - if (retval) { + bus->class_dev = class_device_create(usb_host_class, MKDEV(0,0), bus->controller, "usb%d", busnum); + if (IS_ERR(bus->class_dev)) { clear_bit(busnum, busmap.busmap); up(&usb_bus_list_lock); - return retval; + return PTR_ERR(bus->class_dev); } + class_set_devdata(bus->class_dev, bus); + /* Add it to the local list of buses */ list_add (&bus->bus_list, &usb_bus_list); up (&usb_bus_list_lock); @@ -820,7 +813,7 @@ static void usb_deregister_bus (struct usb_bus *bus) clear_bit (bus->busnum, busmap.busmap); - class_device_del(&bus->class_dev); + class_device_unregister(bus->class_dev); } /** diff --git a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c index 9b347d765383..2ff11d53567b 100644 --- a/drivers/usb/host/ehci-dbg.c +++ b/drivers/usb/host/ehci-dbg.c @@ -450,7 +450,7 @@ show_async (struct class_device *class_dev, char *buf) *buf = 0; - bus = to_usb_bus(class_dev); + bus = class_get_devdata(class_dev); hcd = bus->hcpriv; ehci = hcd_to_ehci (hcd); next = buf; @@ -496,7 +496,7 @@ show_periodic (struct class_device *class_dev, char *buf) return 0; seen_count = 0; - bus = to_usb_bus(class_dev); + bus = class_get_devdata(class_dev); hcd = bus->hcpriv; ehci = hcd_to_ehci (hcd); next = buf; @@ -633,7 +633,7 @@ show_registers (struct class_device *class_dev, char *buf) static char fmt [] = "%*s\n"; static char label [] = ""; - bus = to_usb_bus(class_dev); + bus = class_get_devdata(class_dev); hcd = bus->hcpriv; ehci = hcd_to_ehci (hcd); next = buf; @@ -735,7 +735,7 @@ static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); static inline void create_debug_files (struct ehci_hcd *ehci) { - struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev; + struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev; class_device_create_file(cldev, &class_device_attr_async); class_device_create_file(cldev, &class_device_attr_periodic); @@ -744,7 +744,7 @@ static inline void create_debug_files (struct ehci_hcd *ehci) static inline void remove_debug_files (struct ehci_hcd *ehci) { - struct class_device *cldev = &ehci_to_hcd(ehci)->self.class_dev; + struct class_device *cldev = ehci_to_hcd(ehci)->self.class_dev; class_device_remove_file(cldev, &class_device_attr_async); class_device_remove_file(cldev, &class_device_attr_periodic); diff --git a/drivers/usb/host/ohci-dbg.c b/drivers/usb/host/ohci-dbg.c index 62f53a213808..c58408c95c3d 100644 --- a/drivers/usb/host/ohci-dbg.c +++ b/drivers/usb/host/ohci-dbg.c @@ -481,7 +481,7 @@ show_async (struct class_device *class_dev, char *buf) size_t temp; unsigned long flags; - bus = to_usb_bus(class_dev); + bus = class_get_devdata(class_dev); hcd = bus->hcpriv; ohci = hcd_to_ohci(hcd); @@ -514,7 +514,7 @@ show_periodic (struct class_device *class_dev, char *buf) return 0; seen_count = 0; - bus = to_usb_bus(class_dev); + bus = class_get_devdata(class_dev); hcd = bus->hcpriv; ohci = hcd_to_ohci(hcd); next = buf; @@ -611,7 +611,7 @@ show_registers (struct class_device *class_dev, char *buf) char *next; u32 rdata; - bus = to_usb_bus(class_dev); + bus = class_get_devdata(class_dev); hcd = bus->hcpriv; ohci = hcd_to_ohci(hcd); regs = ohci->regs; @@ -684,7 +684,7 @@ static CLASS_DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL); static inline void create_debug_files (struct ohci_hcd *ohci) { - struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev; + struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev; class_device_create_file(cldev, &class_device_attr_async); class_device_create_file(cldev, &class_device_attr_periodic); @@ -694,7 +694,7 @@ static inline void create_debug_files (struct ohci_hcd *ohci) static inline void remove_debug_files (struct ohci_hcd *ohci) { - struct class_device *cldev = &ohci_to_hcd(ohci)->self.class_dev; + struct class_device *cldev = ohci_to_hcd(ohci)->self.class_dev; class_device_remove_file(cldev, &class_device_attr_async); class_device_remove_file(cldev, &class_device_attr_periodic); diff --git a/include/linux/usb.h b/include/linux/usb.h index 2d1ac5058534..3d508bf08402 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -287,15 +287,14 @@ struct usb_bus { struct dentry *usbfs_dentry; /* usbfs dentry entry for the bus */ - struct class_device class_dev; /* class device for this bus */ + struct class_device *class_dev; /* class device for this bus */ + struct kref kref; /* handles reference counting this bus */ void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */ #if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) struct mon_bus *mon_bus; /* non-null when associated */ int monitored; /* non-zero when monitored */ #endif }; -#define to_usb_bus(d) container_of(d, struct usb_bus, class_dev) - /* -------------------------------------------------------------------------- */ -- cgit v1.2.3 From 4749f32da939d4e4160541b2cadc22492bb507ec Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Thu, 23 Jun 2005 11:36:56 +0200 Subject: [PATCH] better USB_MON dependencies This makes the USB_MON less confusing. Signed-off-by: Adrian Bunk Signed-off-by: Linus Torvalds --- drivers/usb/core/hcd.c | 2 +- drivers/usb/core/hcd.h | 2 +- drivers/usb/mon/Kconfig | 13 ++++--------- drivers/usb/mon/Makefile | 2 +- include/linux/usb.h | 2 +- 5 files changed, 8 insertions(+), 13 deletions(-) (limited to 'include/linux/usb.h') diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index d041782e0c8b..0da23732e807 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -1794,7 +1794,7 @@ EXPORT_SYMBOL (usb_remove_hcd); /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) +#if defined(CONFIG_USB_MON) struct usb_mon_operations *mon_ops; diff --git a/drivers/usb/core/hcd.h b/drivers/usb/core/hcd.h index f67cf1e634fc..325a51656c3f 100644 --- a/drivers/usb/core/hcd.h +++ b/drivers/usb/core/hcd.h @@ -399,7 +399,7 @@ static inline void usbfs_cleanup(void) { } /*-------------------------------------------------------------------------*/ -#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) +#if defined(CONFIG_USB_MON) struct usb_mon_operations { void (*urb_submit)(struct usb_bus *bus, struct urb *urb); diff --git a/drivers/usb/mon/Kconfig b/drivers/usb/mon/Kconfig index 4e6152aa5f19..777642e26b9a 100644 --- a/drivers/usb/mon/Kconfig +++ b/drivers/usb/mon/Kconfig @@ -2,13 +2,9 @@ # USB Monitor configuration # -# In normal life, it makes little sense to have usbmon as a module, and in fact -# it is harmful, because there is no way to autoload the module. -# The 'm' option is allowed for hackers who debug the usbmon itself, -# and for those who have usbcore as a module. config USB_MON - tristate "USB Monitor" - depends on USB + bool "USB Monitor" + depends on USB!=n default y help If you say Y here, a component which captures the USB traffic @@ -17,6 +13,5 @@ config USB_MON Harding's USBMon. This is somewhat experimental at this time, but it should be safe, - as long as you aren't building this as a module and then removing it. - - If unsure, say Y. Do not say M. + as long as you aren't using modular USB and try to remove this + module. diff --git a/drivers/usb/mon/Makefile b/drivers/usb/mon/Makefile index 3cff8d444bb1..f18d10ce91f9 100644 --- a/drivers/usb/mon/Makefile +++ b/drivers/usb/mon/Makefile @@ -4,4 +4,4 @@ usbmon-objs := mon_main.o mon_stat.o mon_text.o -obj-$(CONFIG_USB_MON) += usbmon.o +obj-$(CONFIG_USB) += usbmon.o diff --git a/include/linux/usb.h b/include/linux/usb.h index 3d508bf08402..eb282b581546 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -290,7 +290,7 @@ struct usb_bus { struct class_device *class_dev; /* class device for this bus */ struct kref kref; /* handles reference counting this bus */ void (*release)(struct usb_bus *bus); /* function to destroy this bus's memory */ -#if defined(CONFIG_USB_MON) || defined(CONFIG_USB_MON_MODULE) +#if defined(CONFIG_USB_MON) struct mon_bus *mon_bus; /* non-null when associated */ int monitored; /* non-zero when monitored */ #endif -- cgit v1.2.3