aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/serial/bus.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/serial/bus.c')
-rw-r--r--drivers/usb/serial/bus.c45
1 files changed, 45 insertions, 0 deletions
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c
index 6542f220468f..c08a38402b93 100644
--- a/drivers/usb/serial/bus.c
+++ b/drivers/usb/serial/bus.c
@@ -103,11 +103,52 @@ exit:
103 return retval; 103 return retval;
104} 104}
105 105
106#ifdef CONFIG_HOTPLUG
107static ssize_t store_new_id(struct device_driver *driver,
108 const char *buf, size_t count)
109{
110 struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver);
111 ssize_t retval = usb_store_new_id(&usb_drv->dynids, driver, buf, count);
112
113 if (retval >= 0 && usb_drv->usb_driver != NULL)
114 retval = usb_store_new_id(&usb_drv->usb_driver->dynids,
115 &usb_drv->usb_driver->drvwrap.driver,
116 buf, count);
117 return retval;
118}
119
120static struct driver_attribute drv_attrs[] = {
121 __ATTR(new_id, S_IWUSR, NULL, store_new_id),
122 __ATTR_NULL,
123};
124
125static void free_dynids(struct usb_serial_driver *drv)
126{
127 struct usb_dynid *dynid, *n;
128
129 spin_lock(&drv->dynids.lock);
130 list_for_each_entry_safe(dynid, n, &drv->dynids.list, node) {
131 list_del(&dynid->node);
132 kfree(dynid);
133 }
134 spin_unlock(&drv->dynids.lock);
135}
136
137#else
138static struct driver_attribute drv_attrs[] = {
139 __ATTR_NULL,
140};
141static inline void free_dynids(struct usb_driver *drv)
142{
143}
144#endif
145
106struct bus_type usb_serial_bus_type = { 146struct bus_type usb_serial_bus_type = {
107 .name = "usb-serial", 147 .name = "usb-serial",
108 .match = usb_serial_device_match, 148 .match = usb_serial_device_match,
109 .probe = usb_serial_device_probe, 149 .probe = usb_serial_device_probe,
110 .remove = usb_serial_device_remove, 150 .remove = usb_serial_device_remove,
151 .drv_attrs = drv_attrs,
111}; 152};
112 153
113int usb_serial_bus_register(struct usb_serial_driver *driver) 154int usb_serial_bus_register(struct usb_serial_driver *driver)
@@ -115,6 +156,9 @@ int usb_serial_bus_register(struct usb_serial_driver *driver)
115 int retval; 156 int retval;
116 157
117 driver->driver.bus = &usb_serial_bus_type; 158 driver->driver.bus = &usb_serial_bus_type;
159 spin_lock_init(&driver->dynids.lock);
160 INIT_LIST_HEAD(&driver->dynids.list);
161
118 retval = driver_register(&driver->driver); 162 retval = driver_register(&driver->driver);
119 163
120 return retval; 164 return retval;
@@ -122,6 +166,7 @@ int usb_serial_bus_register(struct usb_serial_driver *driver)
122 166
123void usb_serial_bus_deregister(struct usb_serial_driver *driver) 167void usb_serial_bus_deregister(struct usb_serial_driver *driver)
124{ 168{
169 free_dynids(driver);
125 driver_unregister(&driver->driver); 170 driver_unregister(&driver->driver);
126} 171}
127 172