4 * (C) Copyright 1999 Linus Torvalds
5 * (C) Copyright 1999 Johannes Erdfelt
6 * (C) Copyright 1999 Gregory P. Smith
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/list.h>
12 #include <linux/malloc.h>
13 #include <linux/smp_lock.h>
14 #include <linux/module.h>
15 #include <linux/spinlock.h>
17 #include <asm/uaccess.h>
23 static spinlock_t hub_event_lock
= SPIN_LOCK_UNLOCKED
;
24 static spinlock_t hub_list_lock
= SPIN_LOCK_UNLOCKED
;
26 static LIST_HEAD(hub_event_list
); /* List of hubs needing servicing */
27 static LIST_HEAD(hub_list
); /* List containing all of the hubs (for cleanup) */
29 static DECLARE_WAIT_QUEUE_HEAD(khubd_wait
);
30 static int khubd_pid
= 0; /* PID of khubd */
31 static int khubd_running
= 0;
33 static int usb_get_hub_descriptor(struct usb_device
*dev
, void *data
, int size
)
35 return usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
36 USB_REQ_GET_DESCRIPTOR
, USB_DIR_IN
| USB_RT_HUB
,
37 USB_DT_HUB
<< 8, 0, data
, size
);
40 static int usb_clear_port_feature(struct usb_device
*dev
, int port
, int feature
)
42 return usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
43 USB_REQ_CLEAR_FEATURE
, USB_RT_PORT
, feature
, port
, NULL
, 0);
46 static int usb_set_port_feature(struct usb_device
*dev
, int port
, int feature
)
48 return usb_control_msg(dev
, usb_sndctrlpipe(dev
, 0),
49 USB_REQ_SET_FEATURE
, USB_RT_PORT
, feature
, port
, NULL
, 0);
52 static int usb_get_hub_status(struct usb_device
*dev
, void *data
)
54 /* FIXME: Don't hardcode 4 */
55 return usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
56 USB_REQ_GET_STATUS
, USB_DIR_IN
| USB_RT_HUB
, 0, 0, data
, 4);
59 static int usb_get_port_status(struct usb_device
*dev
, int port
, void *data
)
61 /* FIXME: Don't hardcode 4 */
62 return usb_control_msg(dev
, usb_rcvctrlpipe(dev
, 0),
63 USB_REQ_GET_STATUS
, USB_DIR_IN
| USB_RT_PORT
, 0, port
, data
, 4);
67 * A irq handler returns non-zero to indicate to
68 * the low-level driver that it wants to be re-activated,
69 * or zero to say "I'm done".
71 static int hub_irq(int status
, void *__buffer
, int len
, void *dev_id
)
73 struct usb_hub
*hub
= dev_id
;
81 /* Something happened, let khubd figure it out */
82 if (waitqueue_active(&khubd_wait
)) {
83 /* Add the hub to the event queue */
84 spin_lock_irqsave(&hub_event_lock
, flags
);
85 if (hub
->event_list
.next
== &hub
->event_list
) {
86 list_add(&hub
->event_list
, &hub_event_list
);
90 spin_unlock_irqrestore(&hub_event_lock
, flags
);
98 static int usb_hub_configure(struct usb_hub
*hub
)
100 struct usb_device
*dev
= hub
->dev
;
101 unsigned char buffer
[4], *bitmap
;
102 struct usb_hub_descriptor
*descriptor
;
103 struct usb_descriptor_header
*header
;
106 /* Set it to the first configuration */
107 usb_set_configuration(dev
, dev
->config
[0].bConfigurationValue
);
109 /* Get the length first */
110 if (usb_get_hub_descriptor(dev
, buffer
, 4))
113 header
= (struct usb_descriptor_header
*)buffer
;
114 bitmap
= kmalloc(header
->bLength
, GFP_KERNEL
);
118 if (usb_get_hub_descriptor(dev
, bitmap
, header
->bLength
))
121 descriptor
= (struct usb_hub_descriptor
*)bitmap
;
123 hub
->nports
= dev
->maxchild
= descriptor
->bNbrPorts
;
124 printk(KERN_INFO
"hub: %d-port%s detected\n", hub
->nports
,
125 (hub
->nports
== 1) ? "" : "s");
127 switch (descriptor
->wHubCharacteristics
& HUB_CHAR_LPSM
) {
129 printk(KERN_INFO
"hub: ganged power switching\n");
132 printk(KERN_INFO
"hub: individual port power switching\n");
136 printk(KERN_INFO
"hub: unknown reserved power switching mode\n");
140 if (descriptor
->wHubCharacteristics
& HUB_CHAR_COMPOUND
)
141 printk(KERN_INFO
"hub: part of a compound device\n");
143 printk(KERN_INFO
"hub: standalone hub\n");
145 switch (descriptor
->wHubCharacteristics
& HUB_CHAR_OCPM
) {
147 printk(KERN_INFO
"hub: global over current protection\n");
150 printk(KERN_INFO
"hub: individual port over current protection\n");
154 printk(KERN_INFO
"hub: no over current protection\n");
158 printk(KERN_INFO
"hub: power on to power good time: %dms\n",
159 descriptor
->bPwrOn2PwrGood
* 2);
161 printk(KERN_INFO
"hub: hub controller current requirement: %dmA\n",
162 descriptor
->bHubContrCurrent
);
164 for (i
= 0; i
< dev
->maxchild
; i
++)
165 printk(KERN_INFO
"hub: port %d is%s removable\n", i
+ 1,
166 bitmap
[7 + ((i
+ 1)/8)] & (1 << ((i
+ 1) % 8))
171 if (usb_get_hub_status(dev
, buffer
))
174 printk(KERN_INFO
"hub: local power source is %s\n",
175 (buffer
[0] & 1) ? "lost (inactive)" : "good");
177 printk(KERN_INFO
"hub: %sover current condition exists\n",
178 (buffer
[0] & 2) ? "" : "no ");
180 /* Enable power to the ports */
181 printk(KERN_INFO
"hub: enabling power on all ports\n");
182 for (i
= 0; i
< hub
->nports
; i
++)
183 usb_set_port_feature(dev
, i
+ 1, USB_PORT_FEAT_POWER
);
188 static int hub_probe(struct usb_device
*dev
)
190 struct usb_interface_descriptor
*interface
;
191 struct usb_endpoint_descriptor
*endpoint
;
195 /* We don't handle multi-config hubs */
196 if (dev
->descriptor
.bNumConfigurations
!= 1)
199 /* We don't handle multi-interface hubs */
200 if (dev
->config
[0].bNumInterfaces
!= 1)
203 interface
= &dev
->config
[0].interface
[0].altsetting
[0];
206 if (interface
->bInterfaceClass
!= USB_CLASS_HUB
)
209 /* Some hubs have a subclass of 1, which AFAICT according to the */
210 /* specs is not defined, but it works */
211 if ((interface
->bInterfaceSubClass
!= 0) &&
212 (interface
->bInterfaceSubClass
!= 1))
215 /* Multiple endpoints? What kind of mutant ninja-hub is this? */
216 if (interface
->bNumEndpoints
!= 1)
219 endpoint
= &interface
->endpoint
[0];
221 /* Output endpoint? Curiousier and curiousier.. */
222 if (!(endpoint
->bEndpointAddress
& USB_DIR_IN
))
225 /* If it's not an interrupt endpoint, we'd better punt! */
226 if ((endpoint
->bmAttributes
& 3) != 3)
230 printk(KERN_INFO
"USB hub found\n");
232 if ((hub
= kmalloc(sizeof(*hub
), GFP_KERNEL
)) == NULL
) {
233 printk(KERN_ERR
"couldn't kmalloc hub struct\n");
237 memset(hub
, 0, sizeof(*hub
));
241 INIT_LIST_HEAD(&hub
->event_list
);
244 /* Record the new hub's existence */
245 spin_lock_irqsave(&hub_list_lock
, flags
);
246 INIT_LIST_HEAD(&hub
->hub_list
);
247 list_add(&hub
->hub_list
, &hub_list
);
248 spin_unlock_irqrestore(&hub_list_lock
, flags
);
250 if (usb_hub_configure(hub
) >= 0) {
251 hub
->irq_handle
= usb_request_irq(dev
, usb_rcvctrlpipe(dev
,
252 endpoint
->bEndpointAddress
), hub_irq
, endpoint
->bInterval
, hub
);
255 wake_up(&khubd_wait
);
261 static void hub_disconnect(struct usb_device
*dev
)
263 struct usb_hub
*hub
= dev
->private;
266 spin_lock_irqsave(&hub_event_lock
, flags
);
268 /* Delete it and then reset it */
269 list_del(&hub
->event_list
);
270 INIT_LIST_HEAD(&hub
->event_list
);
271 list_del(&hub
->hub_list
);
272 INIT_LIST_HEAD(&hub
->hub_list
);
274 spin_unlock_irqrestore(&hub_event_lock
, flags
);
276 if (hub
->irq_handle
) {
277 usb_release_irq(hub
->dev
, hub
->irq_handle
);
278 hub
->irq_handle
= NULL
;
281 /* Free the memory */
285 static void usb_hub_port_connect_change(struct usb_device
*hub
, int port
)
287 struct usb_device
*usb
;
288 unsigned char buf
[4];
289 unsigned short portstatus
, portchange
;
291 /* Disconnect anything that may have been there */
292 usb_disconnect(&hub
->children
[port
]);
295 usb_set_port_feature(hub
, port
+ 1, USB_PORT_FEAT_RESET
);
297 wait_ms(50); /* FIXME: This is from the *BSD stack, thanks! :) */
300 if (usb_get_port_status(hub
, port
+ 1, buf
)) {
301 printk(KERN_ERR
"get_port_status failed\n");
305 portstatus
= le16_to_cpup((unsigned short *)buf
+ 0);
306 portchange
= le16_to_cpup((unsigned short *)buf
+ 1);
308 /* If it's not in CONNECT and ENABLE state, we're done */
309 if ((!(portstatus
& USB_PORT_STAT_CONNECTION
)) &&
310 (!(portstatus
& USB_PORT_STAT_ENABLE
)))
311 /* We're done now, we already disconnected the device */
314 /* Allocate a new device struct for it */
315 usb
= usb_alloc_dev(hub
, hub
->bus
);
317 printk(KERN_ERR
"couldn't allocate usb_device\n");
321 usb
->slow
= (portstatus
& USB_PORT_STAT_LOW_SPEED
) ? 1 : 0;
323 hub
->children
[port
] = usb
;
325 /* Find a new device ID for it */
328 /* Run it through the hoops (find a driver, etc) */
329 if (usb_new_device(usb
)) {
330 /* Woops, disable the port */
331 printk(KERN_DEBUG
"hub: disabling port %d\n",
333 usb_clear_port_feature(hub
, port
+ 1, USB_PORT_FEAT_ENABLE
);
337 static void usb_hub_events(void)
341 struct list_head
*tmp
;
342 struct usb_device
*dev
;
346 * We restart the list everytime to avoid a deadlock with
347 * deleting hubs downstream from this one. This should be
348 * safe since we delete the hub from the event list.
349 * Not the most efficient, but avoids deadlocks.
352 spin_lock_irqsave(&hub_event_lock
, flags
);
354 if (list_empty(&hub_event_list
))
357 /* Grab the next entry from the beginning of the list */
358 tmp
= hub_event_list
.next
;
360 hub
= list_entry(tmp
, struct usb_hub
, event_list
);
366 spin_unlock_irqrestore(&hub_event_lock
, flags
);
368 for (i
= 0; i
< hub
->nports
; i
++) {
369 unsigned char buf
[4];
370 unsigned short portstatus
, portchange
;
372 if (usb_get_port_status(dev
, i
+ 1, buf
)) {
373 printk(KERN_ERR
"get_port_status failed\n");
377 portstatus
= le16_to_cpup((unsigned short *)buf
+ 0);
378 portchange
= le16_to_cpup((unsigned short *)buf
+ 1);
380 if (portchange
& USB_PORT_STAT_C_CONNECTION
) {
381 printk(KERN_INFO
"hub: port %d connection change\n",
384 usb_clear_port_feature(dev
, i
+ 1,
385 USB_PORT_FEAT_C_CONNECTION
);
387 usb_hub_port_connect_change(dev
, i
);
390 if (portchange
& USB_PORT_STAT_C_ENABLE
) {
391 printk(KERN_INFO
"hub: port %d enable change\n",
393 usb_clear_port_feature(dev
, i
+ 1,
394 USB_PORT_FEAT_C_ENABLE
);
397 if (portchange
& USB_PORT_STAT_C_SUSPEND
)
398 printk(KERN_INFO
"hub: port %d suspend change\n",
401 if (portchange
& USB_PORT_STAT_C_OVERCURRENT
)
402 printk(KERN_INFO
"hub: port %d over-current change\n",
405 if (portchange
& USB_PORT_STAT_C_RESET
) {
406 printk(KERN_INFO
"hub: port %d reset change\n",
408 usb_clear_port_feature(dev
, i
+ 1,
409 USB_PORT_FEAT_C_RESET
);
416 spin_unlock_irqrestore(&hub_event_lock
, flags
);
419 static int usb_hub_thread(void *__hub
)
430 * This thread doesn't need any user-level access,
431 * so get rid of all our resources
437 /* Setup a nice name */
438 strcpy(current
->comm
, "khubd");
440 /* Send me a signal to get me die (for debugging) */
443 interruptible_sleep_on(&khubd_wait
);
444 } while (!signal_pending(current
));
450 printk("usb_hub_thread exiting\n");
456 static struct usb_driver hub_driver
= {
464 * This should be a separate module.
466 int usb_hub_init(void)
470 usb_register(&hub_driver
);
472 pid
= kernel_thread(usb_hub_thread
, NULL
,
473 CLONE_FS
| CLONE_FILES
| CLONE_SIGHAND
);
480 /* Fall through if kernel_thread failed */
481 usb_deregister(&hub_driver
);
486 void usb_hub_cleanup(void)
490 /* Kill the thread */
491 ret
= kill_proc(khubd_pid
, SIGTERM
, 1);
493 /* Wait 10 seconds */
494 int count
= 10 * 100;
496 while (khubd_running
&& --count
) {
497 current
->state
= TASK_INTERRUPTIBLE
;
502 printk(KERN_ERR
"hub: giving up on killing khubd\n");
506 * Hub resources are freed for us by usb_deregister. It
507 * usb_driver_purge on every device which in turn calls that
508 * devices disconnect function if it is using this driver.
509 * The hub_disconnect function takes care of releasing the
510 * individual hub resources. -greg
512 usb_deregister(&hub_driver
);
513 } /* usb_hub_cleanup() */
516 int init_module(void)
518 return usb_hub_init();
521 void cleanup_module(void)