Import 2.3.1pre2
[davej-history.git] / drivers / usb / ohci-hcd.c
blob2dadb9195b08a5cccf9823bd4cc8f58126b1eccc
1 /*
2 * OHCI HCD (Host Controller Driver) for USB.
4 * (C) Copyright 1999 Roman Weissgaerber <weissg@vienna.at>
6 * The OHCI HCD layer is a simple but nearly complete implementation of what the
7 * USB people would call a HCD for the OHCI.
8 * (ISO comming soon, Bulk disabled, INT u. CTRL transfers enabled)
9 * The layer on top of it, is for interfacing to the alternate-usb device-drivers.
11 * [ This is based on Linus' UHCI code and gregs OHCI fragments (0.03c source tree). ]
12 * [ Open Host Controller Interface driver for USB. ]
13 * [ (C) Copyright 1999 Linus Torvalds (uhci.c) ]
14 * [ (C) Copyright 1999 Gregory P. Smith <greg@electricrain.com> ]
15 * [ $Log: ohci.c,v $ ]
16 * [ Revision 1.1 1999/04/05 08:32:30 greg ]
19 * v2.1 1999/05/09 ep_addr correction, code clean up
20 * v2.0 1999/05/04
21 * virtual root hub is now an option,
22 * memory allocation based on kmalloc and kfree now, Bus error handling,
23 * INT and CTRL transfers enabled, Bulk included but disabled, ISO needs completion
25 * from Linus Torvalds (uhci.c) (APM not tested; hub, usb_device, bus and related stuff)
26 * from Greg Smith (ohci.c) (reset controller handling, hub)
28 * v1.0 1999/04/27 initial release
29 * ohci-hcd.c
32 /* #define OHCI_DBG */ /* printk some debug information */
35 #include <linux/config.h>
36 #include <linux/module.h>
37 #include <linux/pci.h>
38 #include <linux/kernel.h>
39 #include <linux/delay.h>
40 #include <linux/ioport.h>
41 #include <linux/sched.h>
42 #include <linux/malloc.h>
43 #include <linux/smp_lock.h>
44 #include <linux/errno.h>
45 #include <linux/timer.h>
47 #include <asm/spinlock.h>
48 #include <asm/io.h>
49 #include <asm/irq.h>
50 #include <asm/system.h>
52 #include "usb.h"
53 #include "ohci-hcd.h"
54 #include "inits.h"
58 #ifdef CONFIG_APM
59 #include <linux/apm_bios.h>
60 static int handle_apm_event(apm_event_t event);
61 static int apm_resume = 0;
62 #endif
66 static DECLARE_WAIT_QUEUE_HEAD(control_wakeup);
67 static DECLARE_WAIT_QUEUE_HEAD(root_hub);
69 static __u8 cc_to_status[16] = { /* mapping of the OHCI CC to the UHCI status codes; first guess */
70 /* Activ, Stalled, Data Buffer Err, Babble Detected : NAK recvd, CRC/Timeout, Bitstuff, reservd */
71 /* No Error */ 0x00,
72 /* CRC Error */ 0x04,
73 /* Bit Stuff */ 0x02,
74 /* Data Togg */ 0x40,
75 /* Stall */ 0x40,
76 /* DevNotResp */ 0x04,
77 /* PIDCheck */ 0x04,
78 /* UnExpPID */ 0x40,
79 /* DataOver */ 0x20,
80 /* DataUnder */ 0x20,
81 /* reservd */ 0x40,
82 /* reservd */ 0x40,
83 /* BufferOver */ 0x20,
84 /* BuffUnder */ 0x20,
85 /* Not Access */ 0x80,
86 /* Not Access */ 0x80
90 /********
91 **** Interface functions
92 ***********************************************/
94 static int sohci_int_handler(void * ohci_in, unsigned int ep_addr, int ctrl_len, void * ctrl, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw1)
97 struct ohci * ohci = ohci_in;
98 usb_device_irq handler=(void *) lw0;
99 void *dev_id = (void *) lw1;
100 int ret;
102 OHCI_DEBUG({ int i; printk("USB HC IRQ <<<: %x: data(%d):", ep_addr, data_len);)
103 OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);)
104 OHCI_DEBUG( printk(" ret_status: %x\n", status); })
106 ret = handler(cc_to_status[status & 0xf], data, dev_id);
107 if(ret == 0) return 0; /* 0 .. do not requeue */
108 if(status > 0) return -1; /* error occured do not requeue ? */
109 ohci_trans_req(ohci, ep_addr, 0, NULL, data, 8, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id); /* requeue int request */
110 return 0;
113 static int sohci_ctrl_handler(void * ohci_in, unsigned int ep_addr, int ctrl_len, void * ctrl, void * data, int data_len, int status, __OHCI_BAG lw0, __OHCI_BAG lw)
115 *(int * )lw0 = status;
116 wake_up(&control_wakeup);
118 OHCI_DEBUG( { int i; printk("USB HC CTRL<<<: %x: ctrl(%d):", ep_addr, ctrl_len);)
119 OHCI_DEBUG( for(i=0; i < 8; i++ ) printk(" %02x", ((__u8 *) ctrl)[i]);)
120 OHCI_DEBUG( printk(" data(%d):", data_len);)
121 OHCI_DEBUG( for(i=0; i < data_len; i++ ) printk(" %02x", ((__u8 *) data)[i]);)
122 OHCI_DEBUG( printk(" ret_status: %x\n", status); })
123 return 0;
126 static int sohci_request_irq(struct usb_device *usb_dev, unsigned int pipe, usb_device_irq handler, int period, void *dev_id)
128 struct ohci * ohci = usb_dev->bus->hcpriv;
129 union ep_addr_ ep_addr;
131 ep_addr.iep = 0;
132 ep_addr.bep.ep = ((pipe >> 15) & 0x0f) /* endpoint address */
133 | (pipe & 0x80) /* direction */
134 | (1 << 5); /* type = int*/
135 ep_addr.bep.fa = ((pipe >> 8) & 0x7f); /* device address */
137 OHCI_DEBUG( printk("USB HC IRQ >>>: %x: every %d ms\n", ep_addr.iep, period);)
139 usb_ohci_add_ep(ohci, ep_addr.iep, period, 1, sohci_int_handler, 1 << ((pipe & 0x03) + 3) , (pipe >> 26) & 0x01);
141 ohci_trans_req(ohci, ep_addr.iep, 0, NULL, ((struct ohci_device *) usb_dev->hcpriv)->data, 8, (__OHCI_BAG) handler, (__OHCI_BAG) dev_id);
142 return 0;
146 static int sohci_control_msg(struct usb_device *usb_dev, unsigned int pipe, void *cmd, void *data, int len)
148 DECLARE_WAITQUEUE(wait, current);
149 struct ohci * ohci = usb_dev->bus->hcpriv;
150 int status;
151 union ep_addr_ ep_addr;
153 ep_addr.iep = 0;
154 ep_addr.bep.ep = ((pipe >> 15) & 0x0f) /* endpoint address */
155 | (pipe & 0x80) /* direction */
156 | (1 << 6); /* type = ctrl*/
157 ep_addr.bep.fa = ((pipe >> 8) & 0x7f); /* device address */
159 status = 0xf; /* CC not Accessed */
160 OHCI_DEBUG( { int i; printk("USB HC CTRL>>>: %x: ctrl(%d):", ep_addr.iep, 8);)
161 OHCI_DEBUG( for(i=0; i < 8; i++ ) printk(" %02x", ((__u8 *) cmd)[i]);)
162 OHCI_DEBUG( printk(" data(%d):", len);)
163 OHCI_DEBUG( for(i=0; i < len; i++ ) printk(" %02x", ((__u8 *) data)[i]);)
164 OHCI_DEBUG( printk("\n"); })
166 usb_ohci_add_ep(ohci, ep_addr.iep, 0, 1, sohci_ctrl_handler, 1 << ((pipe & 0x03) + 3) , (pipe >> 26) & 0x01);
168 current->state = TASK_UNINTERRUPTIBLE;
169 add_wait_queue(&control_wakeup, &wait);
171 ohci_trans_req(ohci, ep_addr.iep, 8, cmd, data, len, (__OHCI_BAG) &status, 0);
173 schedule_timeout(HZ/10);
175 remove_wait_queue(&control_wakeup, &wait);
177 OHCI_DEBUG(printk("USB HC status::: %x\n", cc_to_status[status & 0x0f]);)
179 return cc_to_status[status & 0x0f];
183 static int sohci_usb_deallocate(struct usb_device *usb_dev) {
184 struct ohci_device *dev = usb_to_ohci(usb_dev);
185 union ep_addr_ ep_addr;
187 ep_addr.iep = 0;
189 OHCI_DEBUG(printk("USB HC dealloc %x\n", usb_dev->devnum);)
191 /* wait_ms(20); */
193 if(usb_dev->devnum >=0) {
194 ep_addr.bep.fa = usb_dev->devnum;
195 usb_ohci_rm_function(((struct ohci_device *)usb_dev->hcpriv)->ohci, ep_addr.iep);
198 USB_FREE(dev);
199 USB_FREE(usb_dev);
201 return 0;
204 static struct usb_device *sohci_usb_allocate(struct usb_device *parent) {
206 struct usb_device *usb_dev;
207 struct ohci_device *dev;
210 USB_ALLOC(usb_dev, sizeof(*usb_dev));
211 if (!usb_dev)
212 return NULL;
214 memset(usb_dev, 0, sizeof(*usb_dev));
216 USB_ALLOC(dev, sizeof(*dev));
217 if (!dev) {
218 USB_FREE(usb_dev);
219 return NULL;
222 /* Initialize "dev" */
223 memset(dev, 0, sizeof(*dev));
225 usb_dev->hcpriv = dev;
226 dev->usb = usb_dev;
228 usb_dev->parent = parent;
230 if (parent) {
231 usb_dev->bus = parent->bus;
232 dev->ohci = usb_to_ohci(parent)->ohci;
234 return usb_dev;
237 struct usb_operations sohci_device_operations = {
238 sohci_usb_allocate,
239 sohci_usb_deallocate,
240 sohci_control_msg,
241 sohci_request_irq,
245 /******
246 *** ED handling functions
247 ************************************/
252 * search for the right place to insert an interrupt ed into the int tree
253 * do some load ballancing
254 * */
256 static int usb_ohci_int_ballance(struct ohci * ohci, int interval, int load) {
258 int i,j;
260 j = 0; /* search for the least loaded interrupt endpoint branch of all 32 branches */
261 for(i=0; i< 32; i++) if(ohci->ohci_int_load[j] > ohci->ohci_int_load[i]) j=i;
263 if(interval < 1) interval = 1;
264 if(interval > 32) interval = 32;
265 for(i= 0; ((interval >> i) > 1 ); interval &= (0xfffe << i++ )); /* interval = 2^int(ld(interval)) */
268 for(i=j%interval; i< 32; i+=interval) ohci->ohci_int_load[i] += load;
269 j = interval + (j % interval);
271 OHCI_DEBUG(printk("USB HC new int ed on pos : %x \n",j);)
273 return j;
276 /* get the ed from the endpoint / device adress */
278 struct usb_ohci_ed * ohci_find_ep(struct ohci *ohci, unsigned int ep_addr_in) {
280 union ep_addr_ ep_addr;
281 struct usb_ohci_ed *tmp;
282 unsigned int mask;
284 mask = 0;
285 ep_addr.iep = ep_addr_in;
287 #ifdef VROOTHUB
288 if(ep_addr.bep.fa == ohci->root_hub_funct_addr) {
289 if((ep_addr.bep.ep & 0x0f) == 0)
290 return &ohci->ed_rh_ep0; /* root hub ep0 */
291 else
292 return &ohci->ed_rh_epi; /* root hub int ep */
294 #endif
296 tmp = ohci->ed_func_ep0[ep_addr.bep.fa];
297 mask = ((((ep_addr.bep.ep >> 5) & 0x03)==2)?0x7f:0xff);
298 ep_addr.bep.ep &= mask; /* mask out direction of ctrl ep */
300 while (tmp != NULL) {
301 if (tmp->ep_addr.iep == ep_addr.iep)
302 return tmp;
303 tmp = tmp->ed_list;
305 return NULL;
308 spinlock_t usb_ed_lock = SPIN_LOCK_UNLOCKED;
309 /* add a new endpoint ep_addr */
310 struct usb_ohci_ed *usb_ohci_add_ep(struct ohci * ohci, unsigned int ep_addr_in, int interval, int load, f_handler handler, int ep_size, int speed) {
312 struct usb_ohci_ed * ed;
313 struct usb_ohci_td * td;
314 union ep_addr_ ep_addr;
317 int int_junk;
319 struct usb_ohci_ed *tmp;
321 ep_addr.iep = ep_addr_in ;
322 ep_addr.bep.ep &= ((((ep_addr.bep.ep >> 5) & 0x03)==2)?0x7f:0xff); /* mask out direction of ctrl ep */
324 spin_lock(&usb_ed_lock);
326 tmp = ohci_find_ep(ohci, ep_addr.iep);
327 if (tmp != NULL) {
329 #ifdef VROOTHUB
330 if(ep_addr.bep.fa == ohci->root_hub_funct_addr) {
331 if((ep_addr.bep.ep & 0x0f) != 0) { /* root hub int ep */
332 ohci->ed_rh_epi.handler = handler;
333 ohci_init_rh_int_timer(ohci, interval);
335 else { /* root hub ep0 */
336 ohci->ed_rh_ep0.handler = handler;
340 else
341 #endif
344 tmp->hw.info = ep_addr.bep.fa | ((ep_addr.bep.ep & 0xf) <<7)
346 | (((ep_addr.bep.ep & 0x60) == 0)? 0x8000 : 0)
347 | (speed << 13)
348 | ep_size <<16;
350 tmp->handler = handler;
352 spin_unlock(&usb_ed_lock);
353 return tmp; /* ed already in use */
357 OHCI_ALLOC(td, sizeof(td)); /* dummy td; end of td list for ed */
358 OHCI_ALLOC(ed, sizeof(ed));
359 td->prev_td = NULL;
361 ed->hw.tail_td = virt_to_bus(&td->hw);
362 ed->hw.head_td = ed->hw.tail_td;
363 ed->hw.info = ep_addr.bep.fa | ((ep_addr.bep.ep & 0xf) <<7)
364 /* | ((ep_addr.bep.port & 0x80)? 0x1000 : 0x0800 ) */
365 | (((ep_addr.bep.ep & 0x60) == 0)? 0x8000 : 0)
366 | (speed << 13)
367 | ep_size <<16;
369 ed->handler = handler;
371 switch((ep_addr.bep.ep >> 5) & 0x03) {
372 case CTRL:
373 ed->hw.next_ed = 0;
374 if(ohci->ed_controltail == NULL) {
375 writel(virt_to_bus(&ed->hw), &ohci->regs->ed_controlhead);
377 else {
378 ohci->ed_controltail->hw.next_ed = virt_to_bus(&ed->hw);
380 ed->ed_prev = ohci->ed_controltail;
381 ohci->ed_controltail = ed;
382 break;
383 case BULK:
384 ed->hw.next_ed = 0;
385 if(ohci->ed_bulktail == NULL) {
386 writel(virt_to_bus(&ed->hw), &ohci->regs->ed_bulkhead);
388 else {
389 ohci->ed_bulktail->hw.next_ed = virt_to_bus(&ed->hw);
391 ed->ed_prev = ohci->ed_bulktail;
392 ohci->ed_bulktail = ed;
393 break;
394 case INT:
395 int_junk = usb_ohci_int_ballance(ohci, interval, load);
396 ed->hw.next_ed = ohci->hc_area->ed[int_junk].next_ed;
397 ohci->hc_area->ed[int_junk].next_ed = virt_to_bus(&ed->hw);
398 ed->ed_prev = (struct usb_ohci_ed *) &ohci->hc_area->ed[int_junk];
399 break;
400 case ISO:
401 ed->hw.next_ed = 0;
402 ohci->ed_isotail->hw.next_ed = virt_to_bus(&ed->hw);
403 ed->ed_prev = ohci->ed_isotail;
404 ohci->ed_isotail = ed;
405 break;
407 ed->ep_addr = ep_addr;
409 /* Add it to the "hash"-table of known endpoint descriptors */
411 ed->ed_list = ohci->ed_func_ep0[ed->ep_addr.bep.fa];
412 ohci->ed_func_ep0[ed->ep_addr.bep.fa] = ed;
414 spin_unlock(&usb_ed_lock);
416 OHCI_DEBUG(printk("USB HC new ed %x: %x :", ep_addr.iep, (unsigned int ) ed); )
417 OHCI_DEBUG({ int i; for( i= 0; i<8 ;i++) printk(" %4x", ((unsigned int *) ed)[i]) ; printk("\n"); }; )
418 return 0;
421 /*****
422 * Request the removal of an endpoint
424 * put the ep on the rm_list and request a stop of the bulk or ctrl list
425 * real removal is done at the next start of frame hardware interrupt
427 int usb_ohci_rm_ep(struct ohci * ohci, struct usb_ohci_ed *ed)
429 unsigned int flags;
430 struct usb_ohci_ed *tmp;
432 OHCI_DEBUG(printk("USB HC remove ed %x: %x :\n", ed->ep_addr.iep, (unsigned int ) ed); )
434 spin_lock_irqsave(&usb_ed_lock, flags);
436 tmp = ohci->ed_func_ep0[ed->ep_addr.bep.fa];
437 if (tmp == NULL) {
438 spin_unlock_irqrestore(&usb_ed_lock, flags);
439 return 0;
442 if(tmp == ed) {
443 ohci->ed_func_ep0[ed->ep_addr.bep.fa] = ed->ed_list;
445 else {
446 while (tmp->ed_list != ed) {
447 if (tmp->ed_list == NULL) {
448 spin_unlock_irqrestore(&usb_ed_lock, flags);
449 return 0;
451 tmp = tmp->ed_list;
453 tmp->ed_list = ed->ed_list;
455 ed->ed_list = ohci->ed_rm_list;
456 ohci->ed_rm_list = ed;
457 ed->hw.info |= OHCI_ED_SKIP;
459 switch((ed->ep_addr.bep.ep >> 5) & 0x03) {
460 case CTRL:
461 writel_mask(~(0x01<<4), &ohci->regs->control); /* stop CTRL list */
462 break;
463 case BULK:
464 writel_mask(~(0x01<<5), &ohci->regs->control); /* stop BULK list */
465 break;
469 writel( OHCI_INTR_SF, &ohci->regs->intrenable); /* enable sof interrupt */
471 spin_unlock_irqrestore(&usb_ed_lock, flags);
473 return 1;
476 /* we have requested to stop the bulk or CTRL list,
477 * now we can remove the eds on the rm_list */
479 static int ohci_rm_eds(struct ohci * ohci) {
481 unsigned int flags;
482 struct usb_ohci_ed *ed;
483 struct usb_ohci_ed *ed_tmp;
484 struct usb_ohci_td *td;
485 __u32 td_hw_tmp;
486 __u32 td_hw;
488 spin_lock_irqsave(&usb_ed_lock, flags);
490 ed = ohci->ed_rm_list;
492 while (ed != NULL) {
494 switch((ed->ep_addr.bep.ep >> 5) & 0x03) {
495 case CTRL:
496 if(ed->ed_prev == NULL) {
497 writel(ed->hw.next_ed, &ohci->regs->ed_controlhead);
499 else {
500 ed->ed_prev->hw.next_ed = ed->hw.next_ed;
502 if(ohci->ed_controltail == ed) {
503 ohci->ed_controltail = ed->ed_prev;
505 break;
506 case BULK:
507 if(ed->ed_prev == NULL) {
508 writel(ed->hw.next_ed, &ohci->regs->ed_bulkhead);
510 else {
511 ed->ed_prev->hw.next_ed = ed->hw.next_ed;
513 if(ohci->ed_bulktail == ed) {
514 ohci->ed_bulktail = ed->ed_prev;
516 break;
517 case INT:
518 ed->ed_prev->hw.next_ed = ed->hw.next_ed;
519 break;
520 case ISO:
521 ed->ed_prev->hw.next_ed = ed->hw.next_ed;
522 if(ohci->ed_isotail == ed) {
523 ohci->ed_isotail = ed->ed_prev;
525 break;
528 if(ed->hw.next_ed != 0) ((struct usb_ohci_ed *) bus_to_virt(ed->hw.next_ed))->ed_prev = ed->ed_prev;
531 /* tds directly connected to ed */
533 td_hw = ed->hw.head_td & 0xfffffff0;
534 while(td_hw != 0) {
535 td = bus_to_virt(td_hw);
536 td_hw_tmp = td_hw;
537 td_hw = td->hw.next_td;
538 OHCI_FREE(td); /* free pending tds */
539 if(td_hw_tmp == ed->hw.tail_td) break;
543 /* mark TDs on the hc done list (if there are any) */
544 td_hw = readl(&ohci->regs->donehead) & 0xfffffff0;
545 while(td_hw != 0) {
546 td = bus_to_virt(td_hw);
547 td_hw = td->hw.next_td;
548 if(td->ep == ed) td->ep = 0;
551 /* mark TDs on the hcca done list (if there are any) */
552 td_hw = ohci->hc_area->hcca.done_head & 0xfffffff0 ;
554 while(td_hw != 0) {
555 td = bus_to_virt(td_hw);
556 td_hw = td->hw.next_td;
557 if(td->ep == ed) td->ep = 0;
560 ed_tmp = ed;
561 ed = ed->ed_list;
562 OHCI_FREE(ed_tmp); /* free ed */
564 writel(0, &ohci->regs->ed_controlcurrent); /* reset CTRL list */
565 writel(0, &ohci->regs->ed_bulkcurrent); /* reset BULK list */
566 writel_set((0x01<<4), &ohci->regs->control); /* start CTRL u. (BULK list) */
568 spin_unlock_irqrestore(&usb_ed_lock, flags);
570 ohci->ed_rm_list = NULL;
571 OHCI_DEBUG(printk("USB HC after rm ed control: %4x intrstat: %4x intrenable: %4x\n", readl(&ohci->regs->control),readl(&ohci->regs->intrstatus),readl(&ohci->regs->intrenable));)
574 return 0;
577 /* remove all endpoints of a function (device) */
578 int usb_ohci_rm_function( struct ohci * ohci, unsigned int ep_addr_in)
580 struct usb_ohci_ed *ed;
581 struct usb_ohci_ed *tmp;
582 union ep_addr_ ep_addr;
586 ep_addr.iep = ep_addr_in;
588 for(ed = ohci->ed_func_ep0[ep_addr.bep.fa]; ed != NULL;) {
589 tmp = ed;
590 ed = ed->ed_list;
591 usb_ohci_rm_ep(ohci, tmp);
596 return 1;
603 /******
604 *** TD handling functions
605 ************************************/
608 #define FILL_TD(TD_PT, HANDLER, INFO, DATA, LEN, LW0, LW1) \
609 td_pt = (TD_PT); \
610 td_pt1 = (struct usb_ohci_td *) bus_to_virt(usb_ep->hw.tail_td); \
611 td_pt1->ep = usb_ep; \
612 td_pt1->handler = (HANDLER); \
613 td_pt1->buffer_start = (DATA); \
614 td_pt1->lw0 = (LW0); \
615 td_pt1->lw1 = (LW1); \
616 td_pt1->hw.info = (INFO); \
617 td_pt1->hw.cur_buf = virt_to_bus(DATA); \
618 td_pt1->hw.buf_end = td_pt1->hw.cur_buf + (LEN) - 1; \
619 td_pt1->hw.next_td = virt_to_bus(td_pt); \
620 usb_ep->hw.tail_td = virt_to_bus(td_pt); \
621 td_pt->prev_td = td_pt1; \
622 td_pt->hw.next_td = 0
624 spinlock_t usb_req_lock = SPIN_LOCK_UNLOCKED;
626 int ohci_trans_req(struct ohci * ohci, unsigned int ep_addr, int ctrl_len, void *ctrl, void * data, int data_len, __OHCI_BAG lw0, __OHCI_BAG lw1) {
628 int ed_type;
629 unsigned int flags;
630 struct usb_ohci_td *td_pt;
631 struct usb_ohci_td *td_pt1;
632 struct usb_ohci_td *td_pt_a1, *td_pt_a2, *td_pt_a3;
633 struct usb_ohci_ed *usb_ep;
634 f_handler handler;
637 td_pt_a1 =NULL;
638 td_pt_a2 =NULL;
639 td_pt_a3 =NULL;
641 usb_ep = ohci_find_ep(ohci, ep_addr);
642 if(usb_ep == NULL ) return -1; /* not known ep */
644 handler = usb_ep->handler;
646 #ifdef VROOTHUB
647 if(usb_ep == &ohci->ed_rh_ep0) { /* root hub ep 0 control endpoint */
648 root_hub_control_msg(ohci, 8, ctrl, data, data_len, lw0, lw1, handler);
649 return 0;
652 if(usb_ep == &ohci->ed_rh_epi) { /* root hub interrupt endpoint */
654 root_hub_int_req(ohci, 8, ctrl, data, data_len, lw0, lw1, handler);
655 return 0;
657 #endif
658 /* struct usb_ohci_ed * usb_ep = usb_ohci_add_ep(pipe, ohci, interval, 1); */
660 ed_type = ((((union ep_addr_)ep_addr).bep.ep >> 5) & 0x07);
662 switch(ed_type) {
663 case BULK_IN:
664 case BULK_OUT:
665 case INT_IN:
666 case INT_OUT:
667 OHCI_ALLOC(td_pt_a1, sizeof(td_pt_a1));
668 break;
670 case CTRL_IN:
671 case CTRL_OUT:
672 OHCI_ALLOC(td_pt_a1, sizeof(td_pt_a1));
673 OHCI_ALLOC(td_pt_a3, sizeof(td_pt_a3));
674 if(data_len > 0) {
675 OHCI_ALLOC(td_pt_a2, sizeof(td_pt_a2));
677 break;
679 case ISO_IN:
680 case ISO_OUT:
684 spin_lock_irqsave(&usb_req_lock, flags);
686 switch(ed_type) {
687 case BULK_IN:
688 FILL_TD( td_pt_a1, handler, TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE, data, data_len, lw0, lw1 );
689 writel( OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
690 break;
692 case BULK_OUT:
693 FILL_TD( td_pt_a1, handler, TD_CC | TD_DP_OUT | TD_T_TOGGLE, data, data_len, lw0, lw1 );
694 writel( OHCI_BLF, &ohci->regs->cmdstatus); /* start bulk list */
695 break;
697 case INT_IN:
698 FILL_TD( td_pt_a1, handler, TD_CC | TD_R | TD_DP_IN | TD_T_TOGGLE, data, data_len, lw0, lw1 );
699 break;
701 case INT_OUT:
702 FILL_TD( td_pt_a1, handler, TD_CC | TD_DP_OUT | TD_T_TOGGLE, data, data_len, lw0, lw1 );
703 break;
705 case CTRL_IN:
706 FILL_TD( td_pt_a1, NULL, TD_CC | TD_DP_SETUP | TD_T_DATA0, ctrl, ctrl_len, 0, 0 );
707 if(data_len > 0) {
708 FILL_TD( td_pt_a2, NULL, TD_CC | TD_R | TD_DP_IN | TD_T_DATA1, data, data_len, 0, 0 );
710 FILL_TD( td_pt_a3, handler, TD_CC | TD_DP_OUT | TD_T_DATA1, NULL, 0, lw0, lw1 );
711 writel( OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
712 break;
714 case CTRL_OUT:
715 FILL_TD( td_pt_a1, NULL, TD_CC | TD_DP_SETUP | TD_T_DATA0, ctrl, ctrl_len, 0, 0 );
716 if(data_len > 0) {
717 FILL_TD( td_pt_a2, NULL, TD_CC | TD_R | TD_DP_OUT | TD_T_DATA1, data, data_len, 0, 0 );
719 FILL_TD( td_pt_a3, handler, TD_CC | TD_DP_IN | TD_T_DATA1, NULL, 0, lw0, lw1 );
720 writel( OHCI_CLF, &ohci->regs->cmdstatus); /* start Control list */
721 break;
723 case ISO_IN:
724 case ISO_OUT:
725 break;
731 td_pt1 = (struct usb_ohci_td *) bus_to_virt(usb_ep->hw.tail_td);
734 if(td_pt_a3 != NULL) td_pt_a3->prev_td = NULL;
735 else if (td_pt_a2 != NULL) td_pt_a2->prev_td = NULL;
736 else if (td_pt_a1 != NULL) td_pt_a1->prev_td = NULL;
738 spin_unlock_irqrestore(&usb_req_lock, flags);
739 return 0;
743 /******
744 *** Done List handling functions
745 ************************************/
747 /* replies to the request have to be on a FIFO basis so
748 * we reverse the reversed done-list */
750 static struct usb_ohci_td * ohci_reverse_done_list(struct ohci * ohci) {
752 __u32 td_list_hc;
753 struct usb_ohci_td * td_list = NULL;
754 struct usb_ohci_td * td_rev = NULL;
756 td_list_hc = ohci->hc_area->hcca.done_head & 0xfffffff0;
757 ohci->hc_area->hcca.done_head = 0;
759 while(td_list_hc) {
761 td_list = (struct usb_ohci_td *) bus_to_virt(td_list_hc);
762 td_list->next_dl_td = td_rev;
764 td_rev = td_list;
765 td_list_hc = td_list->hw.next_td & 0xfffffff0;
767 return td_list;
770 /* all done requests are replied here */
771 static int usb_ohci_done_list(struct ohci * ohci) {
773 struct usb_ohci_td * td = NULL;
774 struct usb_ohci_td * td_list;
775 struct usb_ohci_td * td_list_next = NULL;
776 struct usb_ohci_td * td_err = NULL;
777 __u32 td_hw;
780 td_list = ohci_reverse_done_list(ohci);
782 while(td_list) {
783 td_list_next = td_list->next_dl_td;
784 td = td_list;
786 if(td->ep == NULL) { /* removed ep */
787 OHCI_FREE(td_list);
788 break;
791 /* the HC halts an ED if an error occurs; put all pendings TDs of an halted ED on the
792 * done list; they are marked with an 0xf CC_error code
795 if(TD_CC_GET(td_list->hw.info) != TD_CC_NOERROR) { /* on error move all pending tds of an ed into the done list */
796 printk("******* USB BUS error %x @ep %x\n", TD_CC_GET(td_list->hw.info), td_list->ep->ep_addr.iep);
797 td_err= td_list;
798 td_hw = td_list->ep->hw.head_td & 0xfffffff0;
799 while(td_hw != 0) {
800 if(td_hw == td_list->ep->hw.tail_td) break;
801 td = bus_to_virt(td_hw);
802 td_err->next_dl_td = td;
803 td_err= td;
804 td_hw = td->hw.next_td;
806 td_list->ep->hw.head_td = td_list->ep->hw.tail_td;
807 td->next_dl_td = td_list_next;
808 td_list_next = td_list->next_dl_td;
811 /* send the reply */
812 if(td_list->handler != NULL) {
813 if(td_list->prev_td == NULL) {
814 td_list->handler((void *) ohci,
815 td_list->ep->ep_addr.iep,
817 NULL,
818 td_list->buffer_start,
819 td_list->hw.buf_end-virt_to_bus(td_list->buffer_start)+1,
820 TD_CC_GET(td_list->hw.info),
821 td_list->lw0,
822 td_list->lw1);
823 OHCI_FREE(td_list);
825 else {
826 if(td_list->prev_td->prev_td == NULL) { /* cntrl 2 Transactions dataless */
827 td_list->handler((void *) ohci,
828 td_list->ep->ep_addr.iep,
829 td_list->prev_td->hw.buf_end-virt_to_bus(td_list->prev_td->buffer_start)+1,
830 td_list->prev_td->buffer_start,
831 NULL,
833 (TD_CC_GET(td_list->prev_td->hw.info) > 0) ? TD_CC_GET(td_list->prev_td->hw.info) : TD_CC_GET(td_list->hw.info),
834 td_list->lw0,
835 td_list->lw1);
836 OHCI_FREE(td_list->prev_td);
837 OHCI_FREE(td_list);
839 else { /* cntrl 3 Transactions */
840 td_list->handler((void *) ohci,
841 td_list->ep->ep_addr.iep,
842 td_list->prev_td->prev_td->hw.buf_end-virt_to_bus(td_list->prev_td->prev_td->buffer_start)+1,
843 td_list->prev_td->prev_td->buffer_start,
844 td_list->prev_td->buffer_start,
845 td_list->prev_td->hw.buf_end-virt_to_bus(td_list->prev_td->buffer_start)+1,
846 (TD_CC_GET(td_list->prev_td->prev_td->hw.info) > 0) ? TD_CC_GET(td_list->prev_td->prev_td->hw.info)
847 : (TD_CC_GET(td_list->prev_td->hw.info) > 0) ? TD_CC_GET(td_list->prev_td->hw.info) : TD_CC_GET(td_list->hw.info),
848 td_list->lw0,
849 td_list->lw1);
850 OHCI_FREE(td_list->prev_td->prev_td);
851 OHCI_FREE(td_list->prev_td);
852 OHCI_FREE(td_list);
858 td_list = td_list_next;
860 return 0;
865 /******
866 *** HC functions
867 ************************************/
871 void reset_hc(struct ohci *ohci) {
872 int retries = 5;
873 int timeout = 30;
874 int fminterval;
876 if(readl(&ohci->regs->control) & 0x100) { /* SMM owns the HC */
877 writel(0x08, &ohci->regs->cmdstatus); /* request ownership */
878 printk("USB HC TakeOver from SMM\n");
879 do {
880 wait_ms(100);
881 if(--retries) {
882 printk("USB HC TakeOver timed out!\n");
883 break;
886 while(readl(&ohci->regs->control) & 0x100);
889 writel((1<<31), &ohci->regs->intrdisable); /* Disable HC interrupts */
890 OHCI_DEBUG(printk("USB HC reset_hc: %x ; retries: %d\n", readl(&ohci->regs->control), 5-retries);)
891 fminterval = readl(&ohci->regs->fminterval) & 0x3fff;
892 writel(1, &ohci->regs->cmdstatus); /* HC Reset */
893 while ((readl(&ohci->regs->cmdstatus) & 0x01) != 0) { /* 10us Reset */
894 if (--timeout == 0) {
895 printk("USB HC reset timed out!\n");
896 return;
898 udelay(1);
900 /* set the timing */
901 fminterval |= (((fminterval -210) * 6)/7)<<16;
902 writel(fminterval, &ohci->regs->fminterval);
903 writel(((fminterval&0x3fff)*9)/10, &ohci->regs->periodicstart);
908 * Reset and start an OHCI controller
910 void start_hc(struct ohci *ohci)
912 /* int fminterval; */
913 unsigned int mask;
914 /* fminterval = readl(&ohci->regs->fminterval) & 0x3fff;
915 reset_hc(ohci); */
918 writel(virt_to_bus(&ohci->hc_area->hcca), &ohci->regs->hcca); /* a reset clears this */
920 /* Choose the interrupts we care about now, others later on demand */
921 mask = OHCI_INTR_MIE | OHCI_INTR_WDH;
922 /* | OHCI_INTR_SO | OHCI_INTR_UE |OHCI_INTR_RHSC |OHCI_INTR_SF|
923 OHCI_INTR_FNO */
927 writel((0x00), &ohci->regs->control); /* USB Reset BUS */
928 wait_ms(10);
930 writel((0x97), &ohci->regs->control); /* USB Operational */
932 writel( 0x10000, &ohci->regs->roothub.status); /* root hub power on */
933 wait_ms(50);
935 OHCI_DEBUG(printk("USB HC rstart_hc_operational: %x\n", readl(&ohci->regs->control)); )
936 OHCI_DEBUG(printk("USB HC roothubstata: %x \n", readl( &(ohci->regs->roothub.a) )); )
937 OHCI_DEBUG(printk("USB HC roothubstatb: %x \n", readl( &(ohci->regs->roothub.b) )); )
938 OHCI_DEBUG(printk("USB HC roothubstatu: %x \n", readl( &(ohci->regs->roothub.status) )); )
939 OHCI_DEBUG(printk("USB HC roothubstat1: %x \n", readl( &(ohci->regs->roothub.portstatus[0]) )); )
940 OHCI_DEBUG(printk("USB HC roothubstat2: %x \n", readl( &(ohci->regs->roothub.portstatus[1]) )); )
942 /* control_wakeup = NULL; */
943 writel(mask, &ohci->regs->intrenable);
944 writel(mask, &ohci->regs->intrstatus);
946 #ifdef VROOTHUB
949 struct usb_device * usb_dev;
950 struct ohci_device *dev;
952 usb_dev = sohci_usb_allocate(ohci->root_hub->usb);
953 dev = usb_dev->hcpriv;
955 dev->ohci = ohci;
957 usb_connect(usb_dev);
959 ohci->root_hub->usb->children[0] = usb_dev;
961 usb_new_device(usb_dev);
963 #endif
972 static void ohci_interrupt(int irq, void *__ohci, struct pt_regs *r)
974 struct ohci *ohci = __ohci;
975 struct ohci_regs *regs = ohci->regs;
977 int ints;
980 if((ohci->hc_area->hcca.done_head != 0) && !(ohci->hc_area->hcca.done_head & 0x01)) {
981 ints = OHCI_INTR_WDH;
983 else {
984 if((ints = (readl(&regs->intrstatus) & readl(&regs->intrenable))) == 0)
985 return;
988 ohci->intrstatus |= ints;
989 OHCI_DEBUG(printk("USB HC interrupt: %x (%x) \n", ints, readl(&ohci->regs->intrstatus));)
991 /* ints &= ~(OHCI_INTR_WDH); WH Bit will be set by done list subroutine */
992 /* if(ints & OHCI_INTR_FNO) {
993 writel(OHCI_INTR_FNO, &regs->intrstatus);
994 if (waitqueue_active(&ohci_tasks)) wake_up(&ohci_tasks);
995 } */
997 if(ints & OHCI_INTR_WDH) {
998 writel(OHCI_INTR_WDH, &regs->intrdisable);
999 ohci->intrstatus &= (~OHCI_INTR_WDH);
1000 usb_ohci_done_list(ohci); /* prepare out channel list */
1001 writel(OHCI_INTR_WDH, &ohci->regs->intrstatus);
1002 writel(OHCI_INTR_WDH, &ohci->regs->intrenable);
1006 if(ints & OHCI_INTR_SF) {
1007 writel(OHCI_INTR_SF, &regs->intrdisable);
1008 writel(OHCI_INTR_SF, &ohci->regs->intrstatus);
1009 ohci->intrstatus &= (~OHCI_INTR_SF);
1010 if(ohci->ed_rm_list != NULL) {
1011 ohci_rm_eds(ohci);
1014 #ifndef VROOTHUB
1015 if(ints & OHCI_INTR_RHSC) {
1016 writel(OHCI_INTR_RHSC, &regs->intrdisable);
1017 writel(OHCI_INTR_RHSC, &ohci->regs->intrstatus);
1018 wake_up(&root_hub);
1021 #endif
1023 writel(OHCI_INTR_MIE, &regs->intrenable);
1027 #ifndef VROOTHUB
1029 * This gets called if the connect status on the root
1030 * hub (and the root hub only) changes.
1032 static void ohci_connect_change(struct ohci *ohci, unsigned int port_nr)
1034 struct usb_device *usb_dev;
1035 struct ohci_device *dev;
1036 OHCI_DEBUG(printk("uhci_connect_change: called for %d stat %x\n", port_nr,readl(&ohci->regs->roothub.portstatus[port_nr]) );)
1039 * Even if the status says we're connected,
1040 * the fact that the status bits changed may
1041 * that we got disconnected and then reconnected.
1043 * So start off by getting rid of any old devices..
1045 usb_disconnect(&ohci->root_hub->usb->children[port_nr]);
1047 if(!(readl(&ohci->regs->roothub.portstatus[port_nr]) & RH_PS_CCS)) {
1048 writel(RH_PS_CCS, &ohci->regs->roothub.portstatus[port_nr]);
1049 return; /* nothing connected */
1052 * Ok, we got a new connection. Allocate a device to it,
1053 * and find out what it wants to do..
1055 usb_dev = sohci_usb_allocate(ohci->root_hub->usb);
1056 dev = usb_dev->hcpriv;
1057 dev->ohci = ohci;
1058 usb_connect(dev->usb);
1059 ohci->root_hub->usb->children[port_nr] = usb_dev;
1060 wait_ms(200); /* wait for powerup */
1061 /* reset port/device */
1062 writel(RH_PS_PRS, &ohci->regs->roothub.portstatus[port_nr]); /* reset port */
1063 while(!(readl( &ohci->regs->roothub.portstatus[port_nr]) & RH_PS_PRSC)) wait_ms(10); /* reset active ? */
1064 writel(RH_PS_PES, &ohci->regs->roothub.portstatus[port_nr]); /* enable port */
1065 wait_ms(10);
1066 /* Get speed information */
1067 usb_dev->slow = (readl( &ohci->regs->roothub.portstatus[port_nr]) & RH_PS_LSDA) ? 1 : 0;
1070 * Ok, all the stuff specific to the root hub has been done.
1071 * The rest is generic for any new USB attach, regardless of
1072 * hub type.
1074 usb_new_device(usb_dev);
1076 #endif
1081 * Allocate the resources required for running an OHCI controller.
1082 * Host controller interrupts must not be running while calling this
1083 * function.
1085 * The mem_base parameter must be the usable -virtual- address of the
1086 * host controller's memory mapped I/O registers.
1088 * This is where OHCI triumphs over UHCI, because good is dumb.
1089 * Note how much simpler this function is than in uhci.c.
1091 * OHCI hardware takes care of most of the scheduling of different
1092 * transfer types with the correct prioritization for us.
1096 static struct ohci *alloc_ohci(void* mem_base)
1098 int i,j;
1099 struct ohci *ohci;
1100 struct ohci_hc_area *hc_area;
1101 struct usb_bus *bus;
1102 struct ohci_device *dev;
1103 struct usb_device *usb;
1106 * Here we allocate some dummy EDs as well as the
1107 * OHCI host controller communications area. The HCCA is just
1108 * a nice pool of memory with pointers to endpoint descriptors
1109 * for the different interrupts.
1111 * The first page of memory contains the HCCA and ohci structure
1113 hc_area = (struct ohci_hc_area *) __get_free_pages(GFP_KERNEL, 1);
1114 if (!hc_area)
1115 return NULL;
1116 memset(hc_area, 0, sizeof(*hc_area));
1117 ohci = &hc_area->ohci;
1118 ohci->irq = -1;
1119 ohci->regs = mem_base;
1121 ohci->hc_area = hc_area;
1122 /* Tell the controller where the HCCA is */
1123 writel(virt_to_bus(&hc_area->hcca), &ohci->regs->hcca);
1127 * Initialize the ED polling "tree", full tree;
1128 * dummy eds ed[i] (hc should skip them)
1129 * i == 0 is the end of the iso list;
1130 * 1 is the 1ms node,
1131 * 2,3 2ms nodes,
1132 * 4,5,6,7 4ms nodes,
1133 * 8 ... 15 8ms nodes,
1134 * 16 ... 31 16ms nodes,
1135 * 32 ... 63 32ms nodes
1136 * Sequenzes:
1137 * 32-16- 8-4-2-1-0
1138 * 33-17- 9-5-3-1-0
1139 * 34-18-10-6-2-1-0
1140 * 35-19-11-7-3-1-0
1141 * 36-20-12-4-2-1-0
1142 * 37-21-13-5-3-1-0
1143 * 38-22-14-6-2-1-0
1144 * 39-23-15-7-3-1-0
1145 * 40-24- 8-4-2-1-0
1146 * 41-25- 9-5-3-1-0
1147 * 42-26-10-6-2-1-0
1148 * : :
1149 * 63-31-15-7-3-1-0
1151 hc_area->ed[ED_ISO].info |= OHCI_ED_SKIP; /* place holder, so skip it */
1152 hc_area->ed[ED_ISO].next_ed = 0x0000; /* end of iso list */
1154 hc_area->ed[1].next_ed = virt_to_bus(&(hc_area->ed[ED_ISO]));
1155 hc_area->ed[1].info |= OHCI_ED_SKIP; /* place holder, skip it */
1157 j=1;
1158 for (i = 2; i < (NUM_INTS * 2); i++) {
1159 if (i >= NUM_INTS)
1160 hc_area->hcca.int_table[i - NUM_INTS] = virt_to_bus(&(hc_area->ed[i]));
1162 if( i == j*4) j *= 2;
1163 hc_area->ed[i].next_ed = virt_to_bus(&(hc_area->ed[j+ i%j]));
1164 hc_area->ed[i].info |= OHCI_ED_SKIP; /* place holder, skip it */
1169 * for load ballancing of the interrupt branches
1171 for (i = 0; i < NUM_INTS; i++) ohci->ohci_int_load[i] = 0;
1174 * Store the end of control and bulk list eds. So, we know where we can add
1175 * elements to these lists.
1177 ohci->ed_isotail = (struct usb_ohci_ed *) &(hc_area->ed[ED_ISO]);
1178 ohci->ed_controltail = NULL;
1179 ohci->ed_bulktail = NULL;
1182 * Tell the controller where the control and bulk lists are
1183 * The lists are empty now.
1185 writel(0, &ohci->regs->ed_controlhead);
1186 writel(0, &ohci->regs->ed_bulkhead);
1189 USB_ALLOC(bus, sizeof(*bus));
1190 if (!bus)
1191 return NULL;
1193 memset(bus, 0, sizeof(*bus));
1195 ohci->bus = bus;
1196 bus->hcpriv = (void *) ohci;
1197 bus->op = &sohci_device_operations;
1200 usb = sohci_usb_allocate(NULL);
1201 if (!usb)
1202 return NULL;
1204 dev = ohci->root_hub = usb_to_ohci(usb);
1206 usb->bus = bus;
1207 /* bus->root_hub = ohci_to_usb(ohci->root_hub); */
1208 dev->ohci = ohci;
1210 /* Initialize the root hub */
1212 usb->maxchild = readl(&ohci->regs->roothub.a) & 0xff;
1213 usb_init_root_hub(usb);
1215 return ohci;
1220 * De-allocate all resources..
1223 static void release_ohci(struct ohci *ohci)
1225 int i;
1226 union ep_addr_ ep_addr;
1227 ep_addr.iep = 0;
1229 OHCI_DEBUG(printk("USB HC release ohci \n");)
1231 if (ohci->irq >= 0) {
1232 free_irq(ohci->irq, ohci);
1233 ohci->irq = -1;
1236 /* stop hc */
1237 writel(OHCI_USB_SUSPEND, &ohci->regs->control);
1239 /* deallocate all EDs and TDs */
1240 for(i=0; i < 128; i ++) {
1241 ep_addr.bep.fa = i;
1242 usb_ohci_rm_function(ohci, ep_addr.iep);
1244 ohci_rm_eds(ohci); /* remove eds */
1246 /* disconnect all devices */
1247 if(ohci->root_hub)
1248 for(i = 0; i < ohci->root_hub->usb->maxchild; i++)
1249 usb_disconnect(ohci->root_hub->usb->children + i);
1251 USB_FREE(ohci->root_hub->usb);
1252 USB_FREE(ohci->root_hub);
1253 USB_FREE(ohci->bus);
1255 /* unmap the IO address space */
1256 iounmap(ohci->regs);
1259 free_pages((unsigned int) ohci->hc_area, 1);
1264 void cleanup_drivers(void);
1266 static int ohci_roothub_thread(void * __ohci)
1268 struct ohci *ohci = (struct ohci *)__ohci;
1269 lock_kernel();
1272 * This thread doesn't need any user-level access,
1273 * so get rid of all our resources..
1275 printk("ohci_roothub_thread at %p\n", &ohci_roothub_thread);
1276 exit_mm(current);
1277 exit_files(current);
1278 exit_fs(current);
1281 strcpy(current->comm, "root-hub");
1284 start_hc(ohci);
1285 writel( 0x10000, &ohci->regs->roothub.status);
1286 wait_ms(50); /* root hub power on */
1287 do {
1288 #ifdef CONFIG_APM
1289 if (apm_resume) {
1290 apm_resume = 0;
1291 start_hc(ohci);
1292 continue;
1294 #endif
1296 OHCI_DEBUG(printk("USB RH tasks: int: %x\n", ohci->intrstatus); )
1297 #ifndef VROOTHUB
1298 /* if (ohci->intrstatus & OHCI_INTR_RHSC) */
1300 int port_nr;
1301 for(port_nr=0; port_nr< ohci->root_hub->usb->maxchild; port_nr++)
1302 if(readl(&ohci->regs->roothub.portstatus[port_nr]) & (RH_PS_CSC | RH_PS_PRSC)) {
1303 ohci_connect_change(ohci, port_nr);
1304 writel(0xffff0000, &ohci->regs->roothub.portstatus[port_nr]);
1306 ohci->intrstatus &= ~(OHCI_INTR_RHSC);
1307 writel(OHCI_INTR_RHSC, &ohci->regs->intrenable);
1309 #endif
1311 interruptible_sleep_on(&root_hub);
1313 } while (!signal_pending(current));
1315 #ifdef VROOTHUB
1316 ohci_del_rh_int_timer(ohci);
1317 #endif
1320 cleanup_drivers();
1321 /* reset_hc(ohci); */
1323 release_ohci(ohci);
1324 MOD_DEC_USE_COUNT;
1326 printk("ohci_control_thread exiting\n");
1328 return 0;
1335 * Increment the module usage count, start the control thread and
1336 * return success.
1338 static int found_ohci(int irq, void* mem_base)
1340 int retval;
1341 struct ohci *ohci;
1342 OHCI_DEBUG(printk("USB HC found ohci: irq= %d membase= %x \n", irq, (int)mem_base);)
1343 /* Allocate the running OHCI structures */
1344 ohci = alloc_ohci(mem_base);
1345 if (!ohci) {
1346 return -ENOMEM;
1349 reset_hc(ohci);
1351 retval = -EBUSY;
1352 if (request_irq(irq, ohci_interrupt, SA_SHIRQ, "ohci-usb", ohci) == 0) {
1353 int pid;
1355 MOD_INC_USE_COUNT;
1356 ohci->irq = irq;
1358 pid = kernel_thread(ohci_roothub_thread, ohci, CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
1359 if (pid >= 0)
1360 return 0;
1363 MOD_DEC_USE_COUNT;
1364 retval = pid;
1367 release_ohci(ohci);
1368 return retval;
1371 static int start_ohci(struct pci_dev *dev)
1373 unsigned int mem_base = dev->base_address[0];
1375 /* If its OHCI, its memory */
1376 if (mem_base & PCI_BASE_ADDRESS_SPACE_IO)
1377 return -ENODEV;
1379 /* Get the memory address and map it for IO */
1380 mem_base &= PCI_BASE_ADDRESS_MEM_MASK;
1383 * FIXME ioremap_nocache isn't implemented on all CPUs (such
1384 * as the Alpha) [?] What should I use instead...
1386 * The iounmap() is done on in release_ohci.
1388 mem_base = (unsigned int) ioremap_nocache(mem_base, 4096);
1390 if (!mem_base) {
1391 printk("Error mapping OHCI memory\n");
1392 return -EFAULT;
1395 return found_ohci(dev->irq, (void *) mem_base);
1400 #ifdef CONFIG_APM
1401 static int handle_apm_event(apm_event_t event)
1403 static int down = 0;
1405 switch (event) {
1406 case APM_SYS_SUSPEND:
1407 case APM_USER_SUSPEND:
1408 if (down) {
1409 printk(KERN_DEBUG "ohci: received extra suspend event\n");
1410 break;
1412 down = 1;
1413 break;
1414 case APM_NORMAL_RESUME:
1415 case APM_CRITICAL_RESUME:
1416 if (!down) {
1417 printk(KERN_DEBUG "ohci: received bogus resume event\n");
1418 break;
1420 down = 0;
1421 if (waitqueue_active(&root_hub)) {
1422 apm_resume = 1;
1423 wake_up(&root_hub);
1425 break;
1427 return 0;
1429 #endif
1432 int usb_mouse_init(void);
1433 #ifdef MODULE
1435 void cleanup_module(void)
1437 #ifdef CONFIG_APM
1438 apm_unregister_callback(&handle_apm_event);
1439 #endif
1442 #define ohci_hcd_init init_module
1444 #endif
1446 #define PCI_CLASS_SERIAL_USB_OHCI 0x0C0310
1447 #define PCI_CLASS_SERIAL_USB_OHCI_PG 0x10
1450 int ohci_hcd_init(void)
1452 int retval;
1453 struct pci_dev *dev = NULL;
1455 retval = -ENODEV;
1457 dev = NULL;
1458 while((dev = pci_find_class(PCI_CLASS_SERIAL_USB_OHCI, dev))) { /* OHCI */
1459 retval = start_ohci(dev);
1460 if (retval < 0) break;
1463 #ifdef CONFIG_USB_MOUSE
1464 usb_mouse_init();
1465 #endif
1466 #ifdef CONFIG_USB_KBD
1467 usb_kbd_init();
1468 #endif
1469 hub_init();
1470 #ifdef CONFIG_USB_AUDIO
1471 usb_audio_init();
1472 #endif
1473 #ifdef CONFIG_APM
1474 apm_register_callback(&handle_apm_event);
1475 #endif
1477 return 0;
1479 return retval;
1482 void cleanup_drivers(void)
1484 hub_cleanup();
1485 #ifdef CONFIG_USB_MOUSE
1486 usb_mouse_cleanup();
1487 #endif