Ok. I didn't make 2.4.0 in 2000. Tough. I tried, but we had some
[davej-history.git] / drivers / usb / hub.c
blob8ecc1221bb663efffbc019171bd56512c838728a
1 /*
2 * USB hub driver.
4 * (C) Copyright 1999 Linus Torvalds
5 * (C) Copyright 1999 Johannes Erdfelt
6 * (C) Copyright 1999 Gregory P. Smith
7 */
9 #include <linux/config.h>
10 #include <linux/kernel.h>
11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/list.h>
14 #include <linux/malloc.h>
15 #include <linux/smp_lock.h>
16 #ifdef CONFIG_USB_DEBUG
17 #define DEBUG
18 #else
19 #undef DEBUG
20 #endif
21 #include <linux/usb.h>
22 #include <linux/usbdevice_fs.h>
24 #include <asm/semaphore.h>
25 #include <asm/uaccess.h>
26 #include <asm/byteorder.h>
28 #include"hub.h"
30 /* Wakes up khubd */
31 static spinlock_t hub_event_lock = SPIN_LOCK_UNLOCKED;
32 staticDECLARE_MUTEX(usb_address0_sem);
34 staticLIST_HEAD(hub_event_list);/* List of hubs needing servicing */
35 staticLIST_HEAD(hub_list);/* List containing all of the hubs (for cleanup) */
37 staticDECLARE_WAIT_QUEUE_HEAD(khubd_wait);
38 static int khubd_pid =0;/* PID of khubd */
39 staticDECLARE_MUTEX_LOCKED(khubd_exited);
41 static intusb_get_hub_descriptor(struct usb_device *dev,void*data,int size)
43 returnusb_control_msg(dev,usb_rcvctrlpipe(dev,0),
44 USB_REQ_GET_DESCRIPTOR, USB_DIR_IN | USB_RT_HUB,
45 USB_DT_HUB <<8,0, data, size, HZ);
48 static intusb_clear_hub_feature(struct usb_device *dev,int feature)
50 returnusb_control_msg(dev,usb_sndctrlpipe(dev,0),
51 USB_REQ_CLEAR_FEATURE, USB_RT_HUB, feature,0, NULL,0, HZ);
54 static intusb_clear_port_feature(struct usb_device *dev,int port,int feature)
56 returnusb_control_msg(dev,usb_sndctrlpipe(dev,0),
57 USB_REQ_CLEAR_FEATURE, USB_RT_PORT, feature, port, NULL,0, HZ);
60 static intusb_set_port_feature(struct usb_device *dev,int port,int feature)
62 returnusb_control_msg(dev,usb_sndctrlpipe(dev,0),
63 USB_REQ_SET_FEATURE, USB_RT_PORT, feature, port, NULL,0, HZ);
66 static intusb_get_hub_status(struct usb_device *dev,void*data)
68 returnusb_control_msg(dev,usb_rcvctrlpipe(dev,0),
69 USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_HUB,0,0,
70 data,sizeof(struct usb_hub_status), HZ);
73 static intusb_get_port_status(struct usb_device *dev,int port,void*data)
75 returnusb_control_msg(dev,usb_rcvctrlpipe(dev,0),
76 USB_REQ_GET_STATUS, USB_DIR_IN | USB_RT_PORT,0, port,
77 data,sizeof(struct usb_hub_status), HZ);
80 static voidhub_irq(struct urb *urb)
82 struct usb_hub *hub = (struct usb_hub *)urb->context;
83 unsigned long flags;
85 /* Cause a hub reset after 10 consecutive errors */
86 if(urb->status) {
87 if(urb->status == -ENOENT)
88 return;
90 dbg("nonzero status in irq %d", urb->status);
92 if((++hub->nerrors <10) || hub->error)
93 return;
95 hub->error = urb->status;
98 hub->nerrors =0;
100 /* Something happened, let khubd figure it out */
101 if(waitqueue_active(&khubd_wait)) {
102 /* Add the hub to the event queue */
103 spin_lock_irqsave(&hub_event_lock, flags);
104 if(list_empty(&hub->event_list)) {
105 list_add(&hub->event_list, &hub_event_list);
106 wake_up(&khubd_wait);
108 spin_unlock_irqrestore(&hub_event_lock, flags);
112 static voidusb_hub_power_on(struct usb_hub *hub)
114 int i;
116 /* Enable power to the ports */
117 dbg("enabling power on all ports");
118 for(i =0; i < hub->nports; i++)
119 usb_set_port_feature(hub->dev, i +1, USB_PORT_FEAT_POWER);
121 /* Wait for power to be enabled */
122 wait_ms(hub->descriptor->bPwrOn2PwrGood *2);
125 static intusb_hub_configure(struct usb_hub *hub,struct usb_endpoint_descriptor *endpoint)
127 struct usb_device *dev = hub->dev;
128 struct usb_hub_status hubstatus;
129 char portstr[USB_MAXCHILDREN +1];
130 unsigned int pipe;
131 int i, maxp, ret;
133 hub->descriptor =kmalloc(HUB_DESCRIPTOR_MAX_SIZE, GFP_KERNEL);
134 if(!hub->descriptor) {
135 err("Unable to kmalloc %d bytes for hub descriptor", HUB_DESCRIPTOR_MAX_SIZE);
136 return-1;
139 /* Request the entire hub descriptor. */
140 ret =usb_get_hub_descriptor(dev, hub->descriptor, HUB_DESCRIPTOR_MAX_SIZE);
141 /* <hub->descriptor> is large enough for a hub with 127 ports;
142 * the hub can/will return fewer bytes here. */
143 if(ret <0) {
144 err("Unable to get hub descriptor (err = %d)", ret);
145 kfree(hub->descriptor);
146 return-1;
149 hub->nports = dev->maxchild = hub->descriptor->bNbrPorts;
150 info("%d port%s detected", hub->nports, (hub->nports ==1) ?"":"s");
152 if(hub->descriptor->wHubCharacteristics & HUB_CHAR_COMPOUND)
153 dbg("part of a compound device");
154 else
155 dbg("standalone hub");
157 switch(hub->descriptor->wHubCharacteristics & HUB_CHAR_LPSM) {
158 case0x00:
159 dbg("ganged power switching");
160 break;
161 case0x01:
162 dbg("individual port power switching");
163 break;
164 case0x02:
165 case0x03:
166 dbg("unknown reserved power switching mode");
167 break;
170 switch(hub->descriptor->wHubCharacteristics & HUB_CHAR_OCPM) {
171 case0x00:
172 dbg("global over-current protection");
173 break;
174 case0x08:
175 dbg("individual port over-current protection");
176 break;
177 case0x10:
178 case0x18:
179 dbg("no over-current protection");
180 break;
183 dbg("power on to power good time: %dms", hub->descriptor->bPwrOn2PwrGood *2);
184 dbg("hub controller current requirement: %dmA", hub->descriptor->bHubContrCurrent);
186 for(i =0; i < dev->maxchild; i++)
187 portstr[i] = hub->descriptor->bitmap[((i +1) /8)] & (1<< ((i +1) %8)) ?'F':'R';
188 portstr[dev->maxchild] =0;
190 dbg("port removable status: %s", portstr);
192 ret =usb_get_hub_status(dev, &hubstatus);
193 if(ret <0) {
194 err("Unable to get hub status (err = %d)", ret);
195 kfree(hub->descriptor);
196 return-1;
199 le16_to_cpus(&hubstatus.wHubStatus);
201 dbg("local power source is %s",
202 (hubstatus.wHubStatus & HUB_STATUS_LOCAL_POWER) ?"lost (inactive)":"good");
204 dbg("%sover-current condition exists",
205 (hubstatus.wHubStatus & HUB_STATUS_OVERCURRENT) ?"":"no ");
207 /* Start the interrupt endpoint */
208 pipe =usb_rcvintpipe(dev, endpoint->bEndpointAddress);
209 maxp =usb_maxpacket(dev, pipe,usb_pipeout(pipe));
211 if(maxp >sizeof(hub->buffer))
212 maxp =sizeof(hub->buffer);
214 hub->urb =usb_alloc_urb(0);
215 if(!hub->urb) {
216 err("couldn't allocate interrupt urb");
217 kfree(hub->descriptor);
218 return-1;
221 FILL_INT_URB(hub->urb, dev, pipe, hub->buffer, maxp, hub_irq,
222 hub, endpoint->bInterval);
223 ret =usb_submit_urb(hub->urb);
224 if(ret) {
225 err("usb_submit_urb failed (%d)", ret);
226 kfree(hub->descriptor);
227 return-1;
230 /* Wake up khubd */
231 wake_up(&khubd_wait);
233 usb_hub_power_on(hub);
235 return0;
238 static void*hub_probe(struct usb_device *dev,unsigned int i,
239 const struct usb_device_id *id)
242 struct usb_interface_descriptor *interface;
243 struct usb_endpoint_descriptor *endpoint;
244 struct usb_hub *hub;
245 unsigned long flags;
247 interface = &dev->actconfig->interface[i].altsetting[0];
249 /* Some hubs have a subclass of 1, which AFAICT according to the */
250 /* specs is not defined, but it works */
251 if((interface->bInterfaceSubClass !=0) &&
252 (interface->bInterfaceSubClass !=1)) {
253 err("invalid subclass (%d) for USB hub device #%d",
254 interface->bInterfaceSubClass, dev->devnum);
255 return NULL;
258 /* Multiple endpoints? What kind of mutant ninja-hub is this? */
259 if(interface->bNumEndpoints !=1) {
260 err("invalid bNumEndpoints (%d) for USB hub device #%d",
261 interface->bNumEndpoints, dev->devnum);
262 return NULL;
265 endpoint = &interface->endpoint[0];
267 /* Output endpoint? Curiousier and curiousier.. */
268 if(!(endpoint->bEndpointAddress & USB_DIR_IN)) {
269 err("Device #%d is hub class, but has output endpoint?",
270 dev->devnum);
271 return NULL;
274 /* If it's not an interrupt endpoint, we'd better punt! */
275 if((endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_INT) {
276 err("Device #%d is hub class, but has endpoint other than interrupt?",
277 dev->devnum);
278 return NULL;
281 /* We found a hub */
282 info("USB hub found");
284 hub =kmalloc(sizeof(*hub), GFP_KERNEL);
285 if(!hub) {
286 err("couldn't kmalloc hub struct");
287 return NULL;
290 memset(hub,0,sizeof(*hub));
292 INIT_LIST_HEAD(&hub->event_list);
293 hub->dev = dev;
295 /* Record the new hub's existence */
296 spin_lock_irqsave(&hub_event_lock, flags);
297 INIT_LIST_HEAD(&hub->hub_list);
298 list_add(&hub->hub_list, &hub_list);
299 spin_unlock_irqrestore(&hub_event_lock, flags);
301 if(usb_hub_configure(hub, endpoint) >=0)
302 return hub;
304 err("hub configuration failed for device #%d", dev->devnum);
306 /* free hub, but first clean up its list. */
307 spin_lock_irqsave(&hub_event_lock, flags);
309 /* Delete it and then reset it */
310 list_del(&hub->event_list);
311 INIT_LIST_HEAD(&hub->event_list);
312 list_del(&hub->hub_list);
313 INIT_LIST_HEAD(&hub->hub_list);
315 spin_unlock_irqrestore(&hub_event_lock, flags);
317 kfree(hub);
319 return NULL;
322 static voidhub_disconnect(struct usb_device *dev,void*ptr)
324 struct usb_hub *hub = (struct usb_hub *)ptr;
325 unsigned long flags;
327 spin_lock_irqsave(&hub_event_lock, flags);
329 /* Delete it and then reset it */
330 list_del(&hub->event_list);
331 INIT_LIST_HEAD(&hub->event_list);
332 list_del(&hub->hub_list);
333 INIT_LIST_HEAD(&hub->hub_list);
335 spin_unlock_irqrestore(&hub_event_lock, flags);
337 if(hub->urb) {
338 usb_unlink_urb(hub->urb);
339 usb_free_urb(hub->urb);
340 hub->urb = NULL;
343 if(hub->descriptor) {
344 kfree(hub->descriptor);
345 hub->descriptor = NULL;
348 /* Free the memory */
349 kfree(hub);
352 static inthub_ioctl(struct usb_device *hub,unsigned int code,void*user_data)
354 /* assert ifno == 0 (part of hub spec) */
355 switch(code) {
356 case USBDEVFS_HUB_PORTINFO: {
357 struct usbdevfs_hub_portinfo *info = user_data;
358 unsigned long flags;
359 int i;
361 spin_lock_irqsave(&hub_event_lock, flags);
362 if(hub->devnum <=0)
363 info->nports =0;
364 else{
365 info->nports = hub->maxchild;
366 for(i =0; i < info->nports; i++) {
367 if(hub->children[i] == NULL)
368 info->port[i] =0;
369 else
370 info->port[i] = hub->children[i]->devnum;
373 spin_unlock_irqrestore(&hub_event_lock, flags);
375 return info->nports +1;
378 default:
379 return-ENOSYS;
383 static intusb_hub_reset(struct usb_hub *hub)
385 struct usb_device *dev = hub->dev;
386 int i;
388 /* Disconnect any attached devices */
389 for(i =0; i < hub->nports; i++) {
390 if(dev->children[i])
391 usb_disconnect(&dev->children[i]);
394 /* Attempt to reset the hub */
395 if(hub->urb)
396 usb_unlink_urb(hub->urb);
397 else
398 return-1;
400 if(usb_reset_device(dev))
401 return-1;
403 if(usb_submit_urb(hub->urb))
404 return-1;
406 usb_hub_power_on(hub);
408 return0;
411 static voidusb_hub_disconnect(struct usb_device *dev)
413 struct usb_device *parent = dev->parent;
414 int i;
416 /* Find the device pointer to disconnect */
417 if(parent) {
418 for(i =0; i < parent->maxchild; i++) {
419 if(parent->children[i] == dev) {
420 usb_disconnect(&parent->children[i]);
421 return;
426 err("cannot disconnect hub %d", dev->devnum);
429 #define HUB_RESET_TRIES 5
430 #define HUB_PROBE_TRIES 2
431 #define HUB_SHORT_RESET_TIME 10
432 #define HUB_LONG_RESET_TIME 200
433 #define HUB_RESET_TIMEOUT 500
435 static intusb_hub_port_wait_reset(struct usb_device *hub,int port,
436 struct usb_device *dev,unsigned int delay)
438 int delay_time, ret;
439 struct usb_port_status portsts;
440 unsigned short portchange, portstatus;
442 for(delay_time =0; delay_time < HUB_RESET_TIMEOUT; delay_time += delay) {
443 /* wait to give the device a chance to reset */
444 wait_ms(delay);
446 /* read and decode port status */
447 ret =usb_get_port_status(hub, port +1, &portsts);
448 if(ret <0) {
449 err("get_port_status(%d) failed (err = %d)", port +1, ret);
450 return-1;
453 portstatus =le16_to_cpu(portsts.wPortStatus);
454 portchange =le16_to_cpu(portsts.wPortChange);
455 dbg("port %d, portstatus %x, change %x, %s", port +1,
456 portstatus, portchange,
457 portstatus & (1<< USB_PORT_FEAT_LOWSPEED) ?"1.5 Mb/s":"12 Mb/s");
459 /* bomb out completely if something weird happened */
460 if((portchange & USB_PORT_STAT_C_CONNECTION) ||
461 !(portstatus & USB_PORT_STAT_CONNECTION))
462 return-1;
464 /* if we`ve finished resetting, then break out of the loop */
465 if(!(portstatus & USB_PORT_STAT_RESET) &&
466 (portstatus & USB_PORT_STAT_ENABLE)) {
467 dev->slow = (portstatus & USB_PORT_STAT_LOW_SPEED) ?1:0;
468 return0;
471 /* switch to the long delay after two short delay failures */
472 if(delay_time >=2* HUB_SHORT_RESET_TIME)
473 delay = HUB_LONG_RESET_TIME;
475 dbg("port %d of hub %d not reset yet, waiting %dms", port +1,
476 hub->devnum, delay);
479 return-1;
482 static intusb_hub_port_reset(struct usb_device *hub,int port,
483 struct usb_device *dev,unsigned int delay)
485 int i;
487 /* Reset the port */
488 for(i =0; i < HUB_RESET_TRIES; i++) {
489 usb_set_port_feature(hub, port +1, USB_PORT_FEAT_RESET);
491 /* return success if the port reset OK */
492 if(!usb_hub_port_wait_reset(hub, port, dev, delay)) {
493 usb_clear_port_feature(hub, port +1, USB_PORT_FEAT_C_RESET);
494 return0;
497 dbg("port %d of hub %d not enabled, trying reset again...",
498 port +1, hub->devnum);
499 delay = HUB_LONG_RESET_TIME;
502 err("Cannot enable port %i of hub %d, disabling port.",
503 port +1, hub->devnum);
504 err("Maybe the USB cable is bad?");
506 return-1;
509 voidusb_hub_port_disable(struct usb_device *hub,int port)
511 int ret;
513 ret =usb_clear_port_feature(hub, port +1, USB_PORT_FEAT_ENABLE);
514 if(ret)
515 err("cannot disable port %d of hub %d (err = %d)",
516 port +1, hub->devnum, ret);
519 static voidusb_hub_port_connect_change(struct usb_device *hub,int port,
520 struct usb_port_status *portsts)
522 struct usb_device *dev;
523 unsigned short portstatus, portchange;
524 unsigned int delay = HUB_SHORT_RESET_TIME;
525 int i;
526 char*portstr, *tempstr;
528 portstatus =le16_to_cpu(portsts->wPortStatus);
529 portchange =le16_to_cpu(portsts->wPortChange);
530 dbg("port %d, portstatus %x, change %x, %s", port +1, portstatus,
531 portchange, portstatus & (1<< USB_PORT_FEAT_LOWSPEED) ?"1.5 Mb/s":"12 Mb/s");
533 /* Clear the connection change status */
534 usb_clear_port_feature(hub, port +1, USB_PORT_FEAT_C_CONNECTION);
536 /* Disconnect any existing devices under this port */
537 if(hub->children[port])
538 usb_disconnect(&hub->children[port]);
540 /* Return now if nothing is connected */
541 if(!(portstatus & USB_PORT_STAT_CONNECTION)) {
542 if(portstatus & USB_PORT_STAT_ENABLE)
543 usb_hub_port_disable(hub, port);
545 return;
548 down(&usb_address0_sem);
550 tempstr =kmalloc(1024, GFP_KERNEL);
551 portstr =kmalloc(1024, GFP_KERNEL);
553 for(i =0; i < HUB_PROBE_TRIES; i++) {
554 struct usb_device *pdev, *cdev;
556 /* Allocate a new device struct */
557 dev =usb_alloc_dev(hub, hub->bus);
558 if(!dev) {
559 err("couldn't allocate usb_device");
560 break;
563 hub->children[port] = dev;
565 /* Reset the device */
566 if(usb_hub_port_reset(hub, port, dev, delay)) {
567 usb_free_dev(dev);
568 break;
571 /* Find a new device ID for it */
572 usb_connect(dev);
574 /* Create a readable topology string */
575 cdev = dev;
576 pdev = dev->parent;
577 if(portstr && tempstr) {
578 portstr[0] =0;
579 while(pdev) {
580 int port;
582 for(port =0; port < pdev->maxchild; port++)
583 if(pdev->children[port] == cdev)
584 break;
586 strcpy(tempstr, portstr);
587 if(!strlen(tempstr))
588 sprintf(portstr,"%d", port +1);
589 else
590 sprintf(portstr,"%d/%s", port +1, tempstr);
592 cdev = pdev;
593 pdev = pdev->parent;
595 info("USB new device connect on bus%d/%s, assigned device number %d",
596 dev->bus->busnum, portstr, dev->devnum);
597 }else
598 info("USB new device connect on bus%d, assigned device number %d",
599 dev->bus->busnum, dev->devnum);
601 /* Run it through the hoops (find a driver, etc) */
602 if(!usb_new_device(dev))
603 goto done;
605 /* Free the configuration if there was an error */
606 usb_free_dev(dev);
608 /* Switch to a long reset time */
609 delay = HUB_LONG_RESET_TIME;
612 hub->children[port] = NULL;
613 usb_hub_port_disable(hub, port);
614 done:
615 up(&usb_address0_sem);
616 if(portstr)
617 kfree(portstr);
618 if(tempstr)
619 kfree(tempstr);
622 static voidusb_hub_events(void)
624 unsigned long flags;
625 struct list_head *tmp;
626 struct usb_device *dev;
627 struct usb_hub *hub;
628 struct usb_hub_status hubsts;
629 unsigned short hubstatus, hubchange;
630 int i, ret;
633 * We restart the list everytime to avoid a deadlock with
634 * deleting hubs downstream from this one. This should be
635 * safe since we delete the hub from the event list.
636 * Not the most efficient, but avoids deadlocks.
638 while(1) {
639 spin_lock_irqsave(&hub_event_lock, flags);
641 if(list_empty(&hub_event_list))
642 goto he_unlock;
644 /* Grab the next entry from the beginning of the list */
645 tmp = hub_event_list.next;
647 hub =list_entry(tmp,struct usb_hub, event_list);
648 dev = hub->dev;
650 list_del(tmp);
651 INIT_LIST_HEAD(tmp);
653 spin_unlock_irqrestore(&hub_event_lock, flags);
655 if(hub->error) {
656 dbg("resetting hub %d for error %d", dev->devnum, hub->error);
658 if(usb_hub_reset(hub)) {
659 err("error resetting hub %d - disconnecting", dev->devnum);
660 usb_hub_disconnect(dev);
661 continue;
664 hub->nerrors =0;
665 hub->error =0;
668 for(i =0; i < hub->nports; i++) {
669 struct usb_port_status portsts;
670 unsigned short portstatus, portchange;
672 ret =usb_get_port_status(dev, i +1, &portsts);
673 if(ret <0) {
674 err("get_port_status failed (err = %d)", ret);
675 continue;
678 portstatus =le16_to_cpu(portsts.wPortStatus);
679 portchange =le16_to_cpu(portsts.wPortChange);
681 if(portchange & USB_PORT_STAT_C_CONNECTION) {
682 dbg("port %d connection change", i +1);
684 usb_hub_port_connect_change(dev, i, &portsts);
685 }else if(portchange & USB_PORT_STAT_C_ENABLE) {
686 dbg("port %d enable change, status %x", i +1, portstatus);
687 usb_clear_port_feature(dev, i +1, USB_PORT_FEAT_C_ENABLE);
690 * EM interference sometimes causes bad shielded USB devices to
691 * be shutdown by the hub, this hack enables them again.
692 * Works at least with mouse driver.
694 if(!(portstatus & USB_PORT_STAT_ENABLE) &&
695 (portstatus & USB_PORT_STAT_CONNECTION) && (dev->children[i])) {
696 err("already running port %i disabled by hub (EMI?), re-enabling...",
697 i +1);
698 usb_hub_port_connect_change(dev, i, &portsts);
702 if(portchange & USB_PORT_STAT_C_SUSPEND) {
703 dbg("port %d suspend change", i +1);
704 usb_clear_port_feature(dev, i +1, USB_PORT_FEAT_C_SUSPEND);
707 if(portchange & USB_PORT_STAT_C_OVERCURRENT) {
708 err("port %d over-current change", i +1);
709 usb_clear_port_feature(dev, i +1, USB_PORT_FEAT_C_OVER_CURRENT);
710 usb_hub_power_on(hub);
713 if(portchange & USB_PORT_STAT_C_RESET) {
714 dbg("port %d reset change", i +1);
715 usb_clear_port_feature(dev, i +1, USB_PORT_FEAT_C_RESET);
717 }/* end for i */
719 /* deal with hub status changes */
720 if(usb_get_hub_status(dev, &hubsts) <0)
721 err("get_hub_status failed");
722 else{
723 hubstatus =le16_to_cpup(&hubsts.wHubStatus);
724 hubchange =le16_to_cpup(&hubsts.wHubChange);
725 if(hubchange & HUB_CHANGE_LOCAL_POWER) {
726 dbg("hub power change");
727 usb_clear_hub_feature(dev, C_HUB_LOCAL_POWER);
729 if(hubchange & HUB_CHANGE_OVERCURRENT) {
730 dbg("hub overcurrent change");
731 wait_ms(500);/* Cool down */
732 usb_clear_hub_feature(dev, C_HUB_OVER_CURRENT);
733 usb_hub_power_on(hub);
736 }/* end while (1) */
738 he_unlock:
739 spin_unlock_irqrestore(&hub_event_lock, flags);
742 static intusb_hub_thread(void*__hub)
744 lock_kernel();
747 * This thread doesn't need any user-level access,
748 * so get rid of all our resources
751 daemonize();
753 /* Setup a nice name */
754 strcpy(current->comm,"khubd");
756 /* Send me a signal to get me die (for debugging) */
758 usb_hub_events();
759 interruptible_sleep_on(&khubd_wait);
760 }while(!signal_pending(current));
762 dbg("usb_hub_thread exiting");
764 up_and_exit(&khubd_exited,0);
767 static struct usb_device_id hub_id_table [] = {
768 { bInterfaceClass: USB_CLASS_HUB},
769 { }/* Terminating entry */
772 MODULE_DEVICE_TABLE(usb, hub_id_table);
774 static struct usb_driver hub_driver = {
775 name:"hub",
776 probe: hub_probe,
777 ioctl: hub_ioctl,
778 disconnect: hub_disconnect,
779 id_table: hub_id_table,
783 * This should be a separate module.
785 intusb_hub_init(void)
787 int pid;
789 if(usb_register(&hub_driver) <0) {
790 err("Unable to register USB hub driver");
791 return-1;
794 pid =kernel_thread(usb_hub_thread, NULL,
795 CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
796 if(pid >=0) {
797 khubd_pid = pid;
799 return0;
802 /* Fall through if kernel_thread failed */
803 usb_deregister(&hub_driver);
804 err("failed to start usb_hub_thread");
806 return-1;
809 voidusb_hub_cleanup(void)
811 int ret;
813 /* Kill the thread */
814 ret =kill_proc(khubd_pid, SIGTERM,1);
816 down(&khubd_exited);
819 * Hub resources are freed for us by usb_deregister. It calls
820 * usb_driver_purge on every device which in turn calls that
821 * devices disconnect function if it is using this driver.
822 * The hub_disconnect function takes care of releasing the
823 * individual hub resources. -greg
825 usb_deregister(&hub_driver);
826 }/* usb_hub_cleanup() */
829 * WARNING - If a driver calls usb_reset_device, you should simulate a
830 * disconnect() and probe() for other interfaces you doesn't claim. This
831 * is left up to the driver writer right now. This insures other drivers
832 * have a chance to re-setup their interface.
834 * Take a look at proc_resetdevice in devio.c for some sample code to
835 * do this.
837 intusb_reset_device(struct usb_device *dev)
839 struct usb_device *parent = dev->parent;
840 struct usb_device_descriptor descriptor;
841 int i, ret, port = -1;
843 if(!parent) {
844 err("attempting to reset root hub!");
845 return-EINVAL;
848 for(i =0; i < parent->maxchild; i++)
849 if(parent->children[i] == dev) {
850 port = i;
851 break;
854 if(port <0)
855 return-ENOENT;
857 down(&usb_address0_sem);
859 /* Send a reset to the device */
860 if(usb_hub_port_reset(parent, port, dev, HUB_SHORT_RESET_TIME)) {
861 usb_hub_port_disable(parent, port);
862 up(&usb_address0_sem);
863 return(-ENODEV);
866 /* Reprogram the Address */
867 ret =usb_set_address(dev);
868 if(ret <0) {
869 err("USB device not accepting new address (error=%d)", ret);
870 usb_hub_port_disable(parent, port);
871 up(&usb_address0_sem);
872 return ret;
875 /* Let the SET_ADDRESS settle */
876 wait_ms(10);
878 up(&usb_address0_sem);
881 * Now we fetch the configuration descriptors for the device and
882 * see if anything has changed. If it has, we dump the current
883 * parsed descriptors and reparse from scratch. Then we leave
884 * the device alone for the caller to finish setting up.
886 * If nothing changed, we reprogram the configuration and then
887 * the alternate settings.
889 ret =usb_get_descriptor(dev, USB_DT_DEVICE,0, &descriptor,
890 sizeof(descriptor));
891 if(ret <0)
892 return ret;
894 le16_to_cpus(&descriptor.bcdUSB);
895 le16_to_cpus(&descriptor.idVendor);
896 le16_to_cpus(&descriptor.idProduct);
897 le16_to_cpus(&descriptor.bcdDevice);
899 if(memcmp(&dev->descriptor, &descriptor,sizeof(descriptor))) {
900 usb_destroy_configuration(dev);
902 ret =usb_get_device_descriptor(dev);
903 if(ret <sizeof(dev->descriptor)) {
904 if(ret <0)
905 err("unable to get device descriptor (error=%d)", ret);
906 else
907 err("USB device descriptor short read (expected %i, got %i)",sizeof(dev->descriptor), ret);
909 clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
910 dev->devnum = -1;
911 return-EIO;
914 ret =usb_get_configuration(dev);
915 if(ret <0) {
916 err("unable to get configuration (error=%d)", ret);
917 usb_destroy_configuration(dev);
918 clear_bit(dev->devnum, &dev->bus->devmap.devicemap);
919 dev->devnum = -1;
920 return1;
923 dev->actconfig = dev->config;
924 usb_set_maxpacket(dev);
926 return1;
929 ret =usb_set_configuration(dev, dev->actconfig->bConfigurationValue);
930 if(ret <0) {
931 err("failed to set active configuration (error=%d)", ret);
932 return ret;
935 for(i =0; i < dev->actconfig->bNumInterfaces; i++) {
936 struct usb_interface *intf = &dev->actconfig->interface[i];
937 struct usb_interface_descriptor *as = &intf->altsetting[intf->act_altsetting];
939 ret =usb_set_interface(dev, as->bInterfaceNumber, as->bAlternateSetting);
940 if(ret <0) {
941 err("failed to set active alternate setting for interface %d (error=%d)", i, ret);
942 return ret;
946 return0;
close