]> git.hungrycats.org Git - linux/commitdiff
[PATCH] USB: make struct usb_bus a struct class_device
authorGreg Kroah-Hartman <greg@kroah.com>
Tue, 1 Jul 2003 06:30:15 +0000 (23:30 -0700)
committerGreg Kroah-Hartman <greg@kroah.com>
Tue, 1 Jul 2003 06:30:15 +0000 (23:30 -0700)
This creates sys/class/usb_host/ which lists all usb hosts in the system.

drivers/usb/core/hcd-pci.c
drivers/usb/core/hcd.c
drivers/usb/core/hcd.h
drivers/usb/core/usb.c
drivers/usb/host/hc_sl811.c
include/linux/usb.h

index f440563c065799a70d42493bb8c2d549d62d3f5e..d3fdd4df2f267efa56657490122b1b3491edfa1a 100644 (file)
 
 /*-------------------------------------------------------------------------*/
 
+static void hcd_pci_release(struct usb_bus *bus)
+{
+       struct usb_hcd *hcd = bus->hcpriv;
+
+       if (hcd)
+               hcd->driver->hcd_free(hcd);
+}
+
 /* configure so an HC device and id are always provided */
 /* always called with process context; sleeping is OK */
 
@@ -172,6 +180,7 @@ clean_3:
        usb_bus_init (&hcd->self);
        hcd->self.op = &usb_hcd_operations;
        hcd->self.hcpriv = (void *) hcd;
+       hcd->self.release = &hcd_pci_release;
 
        INIT_LIST_HEAD (&hcd->dev_list);
 
@@ -234,13 +243,6 @@ void usb_hcd_pci_remove (struct pci_dev *dev)
        }
 
        usb_deregister_bus (&hcd->self);
-       if (atomic_read (&hcd->self.refcnt) != 1) {
-               dev_warn (hcd->controller,
-                       "dangling refs (%d) to bus %d!\n",
-                       atomic_read (&hcd->self.refcnt) - 1,
-                       hcd->self.busnum);
-       }
-       hcd->driver->hcd_free (hcd);
 }
 EXPORT_SYMBOL (usb_hcd_pci_remove);
 
index 63cfaf5789ef9767f2f1522ebb52e9dcbe37230b..8b1dec33a535fad89e82090eebe16c18f14d58a0 100644 (file)
@@ -557,20 +557,52 @@ void usb_rh_status_dequeue (struct usb_hcd *hcd, struct urb *urb)
 /*-------------------------------------------------------------------------*/
 
 /* exported only within usbcore */
-void usb_bus_get (struct usb_bus *bus)
+struct usb_bus *usb_bus_get (struct usb_bus *bus)
 {
-       atomic_inc (&bus->refcnt);
+       struct class_device *tmp;
+
+       if (!bus)
+               return NULL;
+
+       tmp = class_device_get(&bus->class_dev);
+       if (tmp)        
+               return to_usb_bus(tmp);
+       else
+               return NULL;
 }
 
 /* exported only within usbcore */
 void usb_bus_put (struct usb_bus *bus)
 {
-       if (atomic_dec_and_test (&bus->refcnt))
-               kfree (bus);
+       if (bus)
+               class_device_put(&bus->class_dev);
 }
 
 /*-------------------------------------------------------------------------*/
 
+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,
+};
+
+void usb_host_init(void)
+{
+       class_register(&usb_host_class);
+}
+
+void usb_host_cleanup(void)
+{
+       class_unregister(&usb_host_class);
+}
+
 /**
  * usb_bus_init - shared initialization code
  * @bus: the bus structure being initialized
@@ -592,8 +624,6 @@ void usb_bus_init (struct usb_bus *bus)
        bus->bandwidth_isoc_reqs = 0;
 
        INIT_LIST_HEAD (&bus->bus_list);
-
-       atomic_set (&bus->refcnt, 1);
 }
 EXPORT_SYMBOL (usb_bus_init);
 
@@ -607,7 +637,7 @@ EXPORT_SYMBOL (usb_bus_init);
  *
  * If no memory is available, NULL is returned.
  *
- * The caller should call usb_free_bus() when it is finished with the structure.
+ * The caller should call usb_put_bus() when it is finished with the structure.
  */
 struct usb_bus *usb_alloc_bus (struct usb_operations *op)
 {
@@ -616,32 +646,13 @@ struct usb_bus *usb_alloc_bus (struct usb_operations *op)
        bus = kmalloc (sizeof *bus, GFP_KERNEL);
        if (!bus)
                return NULL;
+       memset(bus, 0, sizeof(struct usb_bus));
        usb_bus_init (bus);
        bus->op = op;
        return bus;
 }
 EXPORT_SYMBOL (usb_alloc_bus);
 
-/**
- * usb_free_bus - frees the memory used by a bus structure
- * @bus: pointer to the bus to free
- *
- * To be invoked by a HCD, only as the last step of decoupling from
- * hardware.  It is an error to call this if the reference count is
- * anything but one.  That would indicate that some system component
- * did not correctly shut down, and thought the hardware was still
- * accessible.
- */
-void usb_free_bus (struct usb_bus *bus)
-{
-       if (!bus)
-               return;
-       if (atomic_read (&bus->refcnt) != 1)
-               err ("usb_free_bus #%d, count != 1", bus->busnum);
-       usb_bus_put (bus);
-}
-EXPORT_SYMBOL (usb_free_bus);
-
 /*-------------------------------------------------------------------------*/
 
 /**
@@ -652,9 +663,10 @@ EXPORT_SYMBOL (usb_free_bus);
  * Assigns a bus number, and links the controller into usbcore data
  * structures so that it can be seen by scanning the bus list.
  */
-void usb_register_bus(struct usb_bus *bus)
+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);
@@ -664,15 +676,24 @@ void usb_register_bus(struct usb_bus *bus)
        } else
                warn ("too many buses");
 
-       usb_bus_get (bus);
+       snprintf(bus->class_dev.class_id, BUS_ID_SIZE, "usb%d", busnum);
+       bus->class_dev.class = &usb_host_class;
+       bus->class_dev.dev = bus->controller;
+       retval = class_device_register(&bus->class_dev);
+       if (retval) {
+               clear_bit(busnum, busmap.busmap);
+               up(&usb_bus_list_lock);
+               return retval;
+       }
 
-       /* Add it to the list of buses */
+       /* Add it to the local list of buses */
        list_add (&bus->bus_list, &usb_bus_list);
        up (&usb_bus_list_lock);
 
        usbfs_add_bus (bus);
 
        dev_info (bus->controller, "new USB bus registered, assigned bus number %d\n", bus->busnum);
+       return 0;
 }
 EXPORT_SYMBOL (usb_register_bus);
 
@@ -701,7 +722,7 @@ void usb_deregister_bus (struct usb_bus *bus)
 
        clear_bit (bus->busnum, busmap.busmap);
 
-       usb_bus_put (bus);
+       class_device_unregister(&bus->class_dev);
 }
 EXPORT_SYMBOL (usb_deregister_bus);
 
index f0d9f800e6aac1019395967fe1c688f4946e3b6d..e20dad898564e38e287a9fdbc29969b473d7c83a 100644 (file)
@@ -347,9 +347,8 @@ extern long usb_calc_bus_time (int speed, int is_input,
 /*-------------------------------------------------------------------------*/
 
 extern struct usb_bus *usb_alloc_bus (struct usb_operations *);
-extern void usb_free_bus (struct usb_bus *);
 
-extern void usb_register_bus (struct usb_bus *);
+extern int usb_register_bus (struct usb_bus *);
 extern void usb_deregister_bus (struct usb_bus *);
 
 extern int usb_register_root_hub (struct usb_device *usb_dev,
@@ -369,7 +368,7 @@ static inline int hcd_register_root (struct usb_hcd *hcd)
 extern struct list_head usb_bus_list;
 extern struct semaphore usb_bus_list_lock;
 
-extern void usb_bus_get (struct usb_bus *bus);
+extern struct usb_bus *usb_bus_get (struct usb_bus *bus);
 extern void usb_bus_put (struct usb_bus *bus);
 
 extern int usb_find_interface_driver (struct usb_device *dev,
index 45602065a2022ee075179861c67660770d01ba2a..2885522a971e9ec34573b190501fc141598bfaa1 100644 (file)
@@ -54,6 +54,8 @@ extern int  usb_hub_init(void);
 extern void usb_hub_cleanup(void);
 extern int usb_major_init(void);
 extern void usb_major_cleanup(void);
+extern int usb_host_init(void);
+extern void usb_host_cleanup(void);
 
 
 int nousb;             /* Disable USB when built into kernel image */
@@ -652,11 +654,15 @@ struct usb_device *usb_alloc_dev(struct usb_device *parent, struct usb_bus *bus)
 
        memset(dev, 0, sizeof(*dev));
 
+       bus = usb_bus_get(bus);
+       if (!bus) {
+               kfree(dev);
+               return NULL;
+       }
+
        device_initialize(&dev->dev);
        dev->state = USB_STATE_ATTACHED;
 
-       usb_bus_get(bus);
-
        if (!parent)
                dev->devpath [0] = '0';
        dev->bus = bus;
@@ -1531,6 +1537,7 @@ static int __init usb_init(void)
        }
 
        bus_register(&usb_bus_type);
+       usb_host_init();
        usb_major_init();
        usbfs_init();
        usb_hub_init();
@@ -1553,6 +1560,7 @@ static void __exit usb_exit(void)
        usb_major_cleanup();
        usbfs_cleanup();
        usb_hub_cleanup();
+       usb_host_cleanup();
        bus_unregister(&usb_bus_type);
 }
 
index a83f7e83ac3365cfeef4aabd93541919532504b8..5bda71207e783118c57b2b1e7ce201a976218da9 100644 (file)
@@ -1205,7 +1205,7 @@ static void hc_release_hci (hci_t * hci)
        }
 
        usb_deregister_bus (hci->bus);
-       usb_free_bus (hci->bus);
+       usb_put_bus (hci->bus);
 
        list_del_init (&hci->hci_hcd_list);
 
index 735735d663d62912d3fadc849d000cd9a24c82d2..b5eec5fc1d091bcb0207b44aa84f020c09e2a240 100644 (file)
@@ -207,8 +207,10 @@ struct usb_bus {
        struct dentry *usbfs_dentry;    /* usbfs dentry entry for the bus */
        struct dentry *usbdevfs_dentry; /* usbdevfs dentry entry for the bus */
 
-       atomic_t refcnt;
+       struct class_device class_dev;  /* class device for this bus */
+       void (*release)(struct usb_bus *bus);   /* function to destroy this bus's memory */
 };
+#define        to_usb_bus(d) container_of(d, struct usb_bus, class_dev)
 
 
 /* -------------------------------------------------------------------------- */