1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * OHCI device driver File: ohci.c
6 * Open Host Controller Interface low-level routines
8 * Author: Mitch Lichtenberg (mpl@broadcom.com)
10 *********************************************************************
12 * Copyright 2000,2001,2002,2003
13 * Broadcom Corporation. All rights reserved.
15 * This software is furnished under license and may be used and
16 * copied only in accordance with the following terms and
17 * conditions. Subject to these conditions, you may download,
18 * copy, install, use, modify and distribute modified or unmodified
19 * copies of this software in source and/or binary form. No title
20 * or ownership is transferred hereby.
22 * 1) Any source code used, modified or distributed must reproduce
23 * and retain this copyright notice and list of conditions
24 * as they appear in the source file.
26 * 2) No right is granted to use any trade name, trademark, or
27 * logo of Broadcom Corporation. The "Broadcom Corporation"
28 * name may not be used to endorse or promote products derived
29 * from this software without the prior written permission of
30 * Broadcom Corporation.
32 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
33 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
34 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
35 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
36 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
37 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
38 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
39 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
40 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
41 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
42 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
43 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
44 * THE POSSIBILITY OF SUCH DAMAGE.
45 ********************************************************************* */
55 #define CPUCFG_COHERENT_DMA 1 /* hack runs on a PC, PCs are coherent */
57 #include "lib_types.h"
58 #include "lib_printf.h"
59 #include "lib_string.h"
60 #include "lib_physio.h"
61 #include "addrspace.h"
62 #include "cpu_config.h" /* for CPUCFG_COHERENT_DMA */
65 #include "lib_malloc.h"
66 #include "lib_queue.h"
72 /* *********************************************************************
73 * Macros for dealing with hardware
75 * This is all yucky stuff that needs to be made more
76 * processor-independent. It's mostly here now to help us with
78 ********************************************************************* */
80 #if defined(_CFE_) && defined(__MIPSEB)
81 #define BSWAP32(x) __swap32(x)
82 static inline uint32_t __swap32(uint32_t x
)
86 y
= ((x
& 0xFF) << 24) |
88 ((x
& 0xFF0000) >> 8) |
89 ((x
& 0xFF000000) >> 24);
94 #define BSWAP32(x) (x)
99 extern uint32_t vtop(void *ptr
);
100 extern void *ptov(uint32_t x
);
101 #define OHCI_VTOP(ptr) vtop(ptr)
102 #define OHCI_PTOV(ptr) ptov(ptr)
103 #define OHCI_WRITECSR(softc,x,y) \
104 *((volatile uint32_t *) ((softc)->ohci_regs + ((x)/sizeof(uint32_t)))) = (y)
105 #define OHCI_READCSR(softc,x) \
106 *((volatile uint32_t *) ((softc)->ohci_regs + ((x)/sizeof(uint32_t))))
108 #define OHCI_VTOP(ptr) ((uint32_t)PHYSADDR((long)(ptr)))
110 #if CPUCFG_COHERENT_DMA
111 #define OHCI_PTOV(ptr) ((void *)(KERNADDR(ptr)))
113 #define OHCI_PTOV(ptr) ((void *)(UNCADDR(ptr)))
116 #define OHCI_WRITECSR(softc,x,y) \
117 phys_write32(((softc)->ohci_regs + (x)),(y))
118 #define OHCI_READCSR(softc,x) \
119 phys_read32(((softc)->ohci_regs + (x)))
122 #if CPUCFG_COHERENT_DMA
123 #define OHCI_INVAL_RANGE(s,l)
124 #define OHCI_FLUSH_RANGE(s,l)
125 #else /* not coherent */
126 #define CFE_CACHE_INVAL_RANGE 32
127 #define CFE_CACHE_FLUSH_RANGE 64
128 extern void _cfe_flushcache(int,uint8_t *,uint8_t *);
129 #define OHCI_INVAL_RANGE(s,l) _cfe_flushcache(CFE_CACHE_INVAL_RANGE,((uint8_t *) (s)),((uint8_t *) (s))+(l))
130 #define OHCI_FLUSH_RANGE(s,l) _cfe_flushcache(CFE_CACHE_FLUSH_RANGE,((uint8_t *) (s)),((uint8_t *) (s))+(l))
134 /* *********************************************************************
135 * Bit-reverse table - this table consists of the numbers
136 * at its index, listed in reverse. So, the reverse of 0000 0010
138 ********************************************************************* */
140 const static int ohci_revbits
[OHCI_INTTABLE_SIZE
] = {
141 0x00, 0x10, 0x08, 0x18, 0x04, 0x14, 0x0c, 0x1c,
142 0x02, 0x12, 0x0a, 0x1a, 0x06, 0x16, 0x0e, 0x1e,
143 0x01, 0x11, 0x09, 0x19, 0x05, 0x15, 0x0d, 0x1d,
144 0x03, 0x13, 0x0b, 0x1b, 0x07, 0x17, 0x0f, 0x1f
148 /* *********************************************************************
149 * Macros to convert from "hardware" endpoint and transfer
150 * descriptors (ohci_ed_t, ohci_td_t) to "software"
151 * data structures (ohci_transfer_t, ohci_endpoint_t).
153 * Basically, there are two tables, indexed by the same value
154 * By subtracting the base of one pool from a pointer, we get
155 * the index into the other table.
157 * We *could* have included the ed and td in the software
158 * data structures, but placing all the hardware stuff in one
159 * pool will make it easier for hardware that does not handle
160 * coherent DMA, since we can be less careful about what we flush
161 * and what we invalidate.
162 ********************************************************************* */
164 #define ohci_td_from_transfer(softc,transfer) \
165 ((softc)->ohci_hwtdpool + ((transfer) - (softc)->ohci_transfer_pool))
167 #define ohci_transfer_from_td(softc,td) \
168 ((softc)->ohci_transfer_pool + ((td) - (softc)->ohci_hwtdpool))
170 #define ohci_ed_from_endpoint(softc,endpoint) \
171 ((softc)->ohci_hwedpool + ((endpoint) - (softc)->ohci_endpoint_pool))
173 #define ohci_endpoint_from_ed(softc,ed) \
174 ((softc)->ohci_endpoint_pool + ((ed) - (softc)->ohci_hwedpool))
176 /* *********************************************************************
177 * Forward declarations
178 ********************************************************************* */
180 static int ohci_roothub_xfer(usbbus_t
*bus
,usb_ept_t
*uept
,usbreq_t
*ur
);
181 static void ohci_roothub_statchg(ohci_softc_t
*softc
);
182 extern usb_hcdrv_t ohci_driver
;
184 /* *********************************************************************
186 ********************************************************************* */
189 void ohci_dumprhstat(uint32_t reg
);
190 void ohci_dumpportstat(int idx
,uint32_t reg
);
191 void ohci_dumptd(ohci_td_t
*td
);
192 void ohci_dumptdchain(ohci_td_t
*td
);
193 void ohci_dumped(ohci_ed_t
*ed
);
194 void ohci_dumpedchain(ohci_ed_t
*ed
);
197 /* *********************************************************************
198 * Some debug routines
199 ********************************************************************* */
201 void ohci_dumprhstat(uint32_t reg
)
203 printf("HubStatus: %08X ",reg
);
205 if (reg
& M_OHCI_RHSTATUS_LPS
) printf("LocalPowerStatus ");
206 if (reg
& M_OHCI_RHSTATUS_OCI
) printf("OverCurrent ");
207 if (reg
& M_OHCI_RHSTATUS_DRWE
) printf("DeviceRemoteWakeupEnable ");
208 if (reg
& M_OHCI_RHSTATUS_LPSC
) printf("LocalPowerStatusChange ");
209 if (reg
& M_OHCI_RHSTATUS_OCIC
) printf("OverCurrentIndicatorChange ");
214 void ohci_dumpportstat(int idx
,uint32_t reg
)
216 printf("Port %d: %08X ",idx
,reg
);
217 if (reg
& M_OHCI_RHPORTSTAT_CCS
) printf("Connected ");
218 if (reg
& M_OHCI_RHPORTSTAT_PES
) printf("PortEnabled ");
219 if (reg
& M_OHCI_RHPORTSTAT_PSS
) printf("PortSuspended ");
220 if (reg
& M_OHCI_RHPORTSTAT_POCI
) printf("PortOverCurrent ");
221 if (reg
& M_OHCI_RHPORTSTAT_PRS
) printf("PortReset ");
222 if (reg
& M_OHCI_RHPORTSTAT_PPS
) printf("PortPowered ");
223 if (reg
& M_OHCI_RHPORTSTAT_LSDA
) printf("LowSpeed ");
224 if (reg
& M_OHCI_RHPORTSTAT_CSC
) printf("ConnectStatusChange ");
225 if (reg
& M_OHCI_RHPORTSTAT_PESC
) printf("PortEnableStatusChange ");
226 if (reg
& M_OHCI_RHPORTSTAT_PSSC
) printf("PortSuspendStatusChange ");
227 if (reg
& M_OHCI_RHPORTSTAT_OCIC
) printf("OverCurrentIndicatorChange ");
228 if (reg
& M_OHCI_RHPORTSTAT_PRSC
) printf("PortResetStatusChange ");
232 void ohci_dumptd(ohci_td_t
*td
)
235 static char *pids
[4] = {"SETUP","OUT","IN","RSVD"};
237 ctl
= BSWAP32(td
->td_control
);
239 printf("[%08X] ctl=%08X (DP=%s,DI=%d,T=%d,EC=%d,CC=%d%s) cbp=%08X be=%08X next=%08X\n",
242 pids
[G_OHCI_TD_PID(ctl
)],
247 (ctl
& M_OHCI_TD_SHORTOK
) ? ",R" : "",
250 BSWAP32(td
->td_next_td
));
253 void ohci_dumptdchain(ohci_td_t
*td
)
257 printf("%d:[%08X] ctl=%08X cbp=%08X be=%08X next=%08X\n",
260 BSWAP32(td
->td_control
),
263 BSWAP32(td
->td_next_td
));
264 if (!td
->td_next_td
) break;
265 td
= (ohci_td_t
*) OHCI_PTOV(BSWAP32(td
->td_next_td
));
270 void ohci_dumped(ohci_ed_t
*ed
)
273 static char *pids
[4] = {"FTD","OUT","IN","FTD"};
275 ctl
= BSWAP32(ed
->ed_control
),
277 printf("[%08X] Ctl=%08X (MPS=%d%s%s%s,EN=%d,FA=%d,D=%s) Tailp=%08X headp=%08X next=%08X %s\n",
281 (ctl
& M_OHCI_ED_LOWSPEED
) ? ",LS" : "",
282 (ctl
& M_OHCI_ED_SKIP
) ? ",SKIP" : "",
283 (ctl
& M_OHCI_ED_ISOCFMT
) ? ",ISOC" : "",
286 pids
[G_OHCI_ED_DIR(ctl
)],
287 BSWAP32(ed
->ed_tailp
),
288 BSWAP32(ed
->ed_headp
),
289 BSWAP32(ed
->ed_next_ed
),
290 BSWAP32(ed
->ed_headp
) & M_OHCI_ED_HALT
? "HALT" : "");
291 if ((ed
->ed_headp
& M_OHCI_ED_PTRMASK
) == 0) return;
292 ohci_dumptdchain(OHCI_PTOV(BSWAP32(ed
->ed_headp
) & M_OHCI_ED_PTRMASK
));
295 void ohci_dumpedchain(ohci_ed_t
*ed
)
299 printf("---\nED#%d -> ",idx
);
301 if (!ed
->ed_next_ed
) break;
303 ed
= (ohci_ed_t
*) OHCI_PTOV(BSWAP32(ed
->ed_next_ed
));
309 static void eptstats(ohci_softc_t
*softc
)
315 e
= softc
->ohci_endpoint_freelist
;
316 while (e
) { e
= e
->ep_next
; cnt
++; }
317 printf("%d left, %d inuse\n",cnt
,OHCI_EDPOOL_SIZE
-cnt
);
320 /* *********************************************************************
321 * _ohci_allocept(softc)
323 * Allocate an endpoint data structure from the pool, and
324 * make it ready for use. The endpoint is NOT attached to
325 * the hardware at this time.
328 * softc - our OHCI controller
331 * pointer to endpoint or NULL
332 ********************************************************************* */
334 static ohci_endpoint_t
*_ohci_allocept(ohci_softc_t
*softc
)
340 printf("AllocEpt: ");eptstats(softc
);
343 e
= softc
->ohci_endpoint_freelist
;
346 printf("No endpoints left!\n");
350 softc
->ohci_endpoint_freelist
= e
->ep_next
;
352 ed
= ohci_ed_from_endpoint(softc
,e
);
354 ed
->ed_control
= BSWAP32(M_OHCI_ED_SKIP
);
355 ed
->ed_tailp
= BSWAP32(0);
356 ed
->ed_headp
= BSWAP32(0);
357 ed
->ed_next_ed
= BSWAP32(0);
359 e
->ep_phys
= OHCI_VTOP(ed
);
365 /* *********************************************************************
366 * _ohci_allocxfer(softc)
368 * Allocate a transfer descriptor. It is prepared for use
369 * but not attached to the hardware.
372 * softc - our OHCI controller
375 * transfer descriptor, or NULL
376 ********************************************************************* */
378 static ohci_transfer_t
*_ohci_allocxfer(ohci_softc_t
*softc
)
386 t
= softc
->ohci_transfer_freelist
;
387 while (t
) { t
= t
->t_next
; cnt
++; }
388 printf("AllocXfer: %d left, %d inuse\n",cnt
,OHCI_TDPOOL_SIZE
-cnt
);
391 t
= softc
->ohci_transfer_freelist
;
394 printf("No more transfer descriptors!\n");
398 softc
->ohci_transfer_freelist
= t
->t_next
;
400 td
= ohci_td_from_transfer(softc
,t
);
402 td
->td_control
= BSWAP32(0);
403 td
->td_cbp
= BSWAP32(0);
404 td
->td_next_td
= BSWAP32(0);
405 td
->td_be
= BSWAP32(0);
413 /* *********************************************************************
414 * _ohci_freeept(softc,e)
416 * Free an endpoint, returning it to the pool.
419 * softc - our OHCI controller
420 * e - endpoint descriptor to return
424 ********************************************************************* */
426 static void _ohci_freeept(ohci_softc_t
*softc
,ohci_endpoint_t
*e
)
432 ee
= softc
->ohci_endpoint_freelist
;
433 while (ee
) { ee
= ee
->ep_next
; cnt
++; }
434 printf("FreeEpt[%p]: %d left, %d inuse\n",e
,cnt
,OHCI_EDPOOL_SIZE
-cnt
);
437 e
->ep_next
= softc
->ohci_endpoint_freelist
;
438 softc
->ohci_endpoint_freelist
= e
;
441 /* *********************************************************************
442 * _ohci_freexfer(softc,t)
444 * Free a transfer descriptor, returning it to the pool.
447 * softc - our OHCI controller
448 * t - transfer descriptor to return
452 ********************************************************************* */
454 static void _ohci_freexfer(ohci_softc_t
*softc
,ohci_transfer_t
*t
)
456 t
->t_next
= softc
->ohci_transfer_freelist
;
457 softc
->ohci_transfer_freelist
= t
;
460 /* *********************************************************************
461 * _ohci_initpools(softc)
463 * Allocate and initialize the various pools of things that
464 * we use in the OHCI driver. We do this by allocating some
465 * big chunks from the heap and carving them up.
468 * softc - our OHCI controller
473 ********************************************************************* */
475 static int _ohci_initpools(ohci_softc_t
*softc
)
480 * Do the transfer descriptor pool
483 softc
->ohci_transfer_pool
= KMALLOC(OHCI_TDPOOL_SIZE
*sizeof(ohci_transfer_t
),0);
484 softc
->ohci_hwtdpool
= KMALLOC(OHCI_TDPOOL_SIZE
*sizeof(ohci_td_t
),OHCI_TD_ALIGN
);
487 * In the case of noncoherent DMA, make these uncached addresses.
488 * This way all our descriptors will be uncached. Makes life easier, as we
489 * do not need to worry about flushing descriptors, etc.
492 #if !CPUCFG_COHERENT_DMA
493 softc
->ohci_hwtdpool
= (void *) UNCADDR(PHYSADDR((uint32_t)(softc
->ohci_hwtdpool
)));
496 if (!softc
->ohci_transfer_pool
|| !softc
->ohci_hwtdpool
) {
497 printf("Could not allocate transfer descriptors\n");
501 softc
->ohci_transfer_freelist
= NULL
;
503 for (idx
= 0; idx
< OHCI_TDPOOL_SIZE
; idx
++) {
504 _ohci_freexfer(softc
,softc
->ohci_transfer_pool
+idx
);
508 * Do the endpoint descriptor pool
511 softc
->ohci_endpoint_pool
= KMALLOC(OHCI_EDPOOL_SIZE
*sizeof(ohci_endpoint_t
),0);
513 softc
->ohci_hwedpool
= KMALLOC(OHCI_EDPOOL_SIZE
*sizeof(ohci_ed_t
),OHCI_ED_ALIGN
);
515 #if !CPUCFG_COHERENT_DMA
516 softc
->ohci_hwedpool
= (void *) UNCADDR(PHYSADDR((uint32_t)(softc
->ohci_hwedpool
)));
519 if (!softc
->ohci_endpoint_pool
|| !softc
->ohci_hwedpool
) {
520 printf("Could not allocate transfer descriptors\n");
524 softc
->ohci_endpoint_freelist
= NULL
;
526 for (idx
= 0; idx
< OHCI_EDPOOL_SIZE
; idx
++) {
527 _ohci_freeept(softc
,softc
->ohci_endpoint_pool
+idx
);
531 * Finally the host communications area
534 softc
->ohci_hcca
= KMALLOC(sizeof(ohci_hcca_t
),sizeof(ohci_hcca_t
));
536 #if !CPUCFG_COHERENT_DMA
537 softc
->ohci_hcca
= (void *) UNCADDR(PHYSADDR((uint32_t)(softc
->ohci_hcca
)));
540 memset(softc
->ohci_hcca
,0,sizeof(ohci_hcca_t
));
546 /* *********************************************************************
549 * Start the OHCI controller. After this routine is called,
550 * the hardware will be operational and ready to accept
551 * descriptors and interrupt calls.
554 * bus - bus structure, from ohci_create
559 ********************************************************************* */
561 static int ohci_start(usbbus_t
*bus
)
563 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
569 * Force a reset to the controller, followed by a short delay
572 OHCI_WRITECSR(softc
,R_OHCI_CONTROL
,V_OHCI_CONTROL_HCFS(K_OHCI_HCFS_RESET
));
573 usb_delay_ms(bus
,OHCI_RESET_DELAY
);
575 /* Host controller state is now "RESET" */
578 * We need the frame interval later, so get a copy of it now.
580 frameint
= G_OHCI_FMINTERVAL_FI(OHCI_READCSR(softc
,R_OHCI_FMINTERVAL
));
583 * Reset the host controller. When you set the HCR bit
584 * if self-clears when the reset is complete.
587 OHCI_WRITECSR(softc
,R_OHCI_CMDSTATUS
,M_OHCI_CMDSTATUS_HCR
);
588 for (idx
= 0; idx
< 10000; idx
++) {
589 if (!(OHCI_READCSR(softc
,R_OHCI_CMDSTATUS
) & M_OHCI_CMDSTATUS_HCR
)) break;
592 if (OHCI_READCSR(softc
,R_OHCI_CMDSTATUS
) & M_OHCI_CMDSTATUS_HCR
) {
593 /* controller never came out of reset */
598 * Host controller state is now "SUSPEND". We must exit
599 * from this state within 2ms. (5.1.1.4)
601 * Set up pointers to data structures.
604 OHCI_WRITECSR(softc
,R_OHCI_HCCA
,OHCI_VTOP(softc
->ohci_hcca
));
605 OHCI_WRITECSR(softc
,R_OHCI_CONTROLHEADED
,softc
->ohci_ctl_list
->ep_phys
);
606 OHCI_WRITECSR(softc
,R_OHCI_BULKHEADED
,softc
->ohci_bulk_list
->ep_phys
);
609 * Our driver is polled, turn off interrupts
612 OHCI_WRITECSR(softc
,R_OHCI_INTDISABLE
,M_OHCI_INT_ALL
);
615 * Set up the control register.
618 reg
= OHCI_READCSR(softc
,R_OHCI_CONTROL
);
620 reg
= M_OHCI_CONTROL_PLE
| M_OHCI_CONTROL_CLE
| M_OHCI_CONTROL_BLE
|
622 V_OHCI_CONTROL_CBSR(K_OHCI_CBSR_41
) |
623 V_OHCI_CONTROL_HCFS(K_OHCI_HCFS_OPERATIONAL
);
625 OHCI_WRITECSR(softc
,R_OHCI_CONTROL
,reg
);
629 * controller state is now OPERATIONAL
632 reg
= OHCI_READCSR(softc
,R_OHCI_FMINTERVAL
);
633 reg
&= M_OHCI_FMINTERVAL_FIT
;
634 reg
^= M_OHCI_FMINTERVAL_FIT
;
635 reg
|= V_OHCI_FMINTERVAL_FSMPS(OHCI_CALC_FSMPS(frameint
)) |
636 V_OHCI_FMINTERVAL_FI(frameint
);
637 OHCI_WRITECSR(softc
,R_OHCI_FMINTERVAL
,reg
);
639 reg
= frameint
* 9 / 10; /* calculate 90% */
640 OHCI_WRITECSR(softc
,R_OHCI_PERIODICSTART
,reg
);
642 usb_delay_ms(softc
->ohci_bus
,10);
645 * Remember how many ports we have
648 reg
= OHCI_READCSR(softc
,R_OHCI_RHDSCRA
);
649 softc
->ohci_ndp
= G_OHCI_RHDSCRA_NDP(reg
);
656 OHCI_WRITECSR(softc
,R_OHCI_RHSTATUS
,M_OHCI_RHSTATUS_LPSC
);
657 usb_delay_ms(softc
->ohci_bus
,10);
663 /* *********************************************************************
664 * _ohci_setupepts(softc)
666 * Set up the endpoint tree, as described in the OHCI manual.
667 * Basically the hardware knows how to scan lists of lists,
668 * so we build a tree where each level is pointed to by two
669 * parent nodes. We can choose our scanning rate by attaching
670 * endpoints anywhere within this tree.
673 * softc - our OHCI controller
677 * else error (out of descriptors)
678 ********************************************************************* */
680 static int _ohci_setupepts(ohci_softc_t
*softc
)
685 ohci_endpoint_t
*child
;
688 * Set up the list heads for the isochronous, control,
689 * and bulk transfer lists. They don't get the same "tree"
690 * treatment that the interrupt devices get.
692 * For the purposes of CFE, it's probably not necessary
693 * to be this fancy. The only device we're planning to
694 * talk to is the keyboard and some hubs, which should
695 * have pretty minimal requirements. It's conceivable
696 * that this firmware may find a new home in other
697 * devices, so we'll meet halfway and do some things
701 softc
->ohci_isoc_list
= _ohci_allocept(softc
);
702 softc
->ohci_ctl_list
= _ohci_allocept(softc
);
703 softc
->ohci_bulk_list
= _ohci_allocept(softc
);
706 * Set up a tree of empty endpoint descriptors. This is
707 * tree is scanned by the hardware from the leaves up to
708 * the root. Once a millisecond, the hardware picks the
709 * next leaf and starts scanning descriptors looking
710 * for something to do. It traverses all of the endpoints
711 * along the way until it gets to the root.
713 * The idea here is if you put a transfer descriptor on the
714 * root node, the hardware will see it every millisecond,
715 * since the root will be examined each time. If you
716 * put the TD on the leaf, it will be 1/32 millisecond.
717 * The tree therefore is six levels deep.
720 for (idx
= 0; idx
< OHCI_INTTREE_SIZE
; idx
++) {
721 e
= _ohci_allocept(softc
); /* allocated with sKip bit set */
722 softc
->ohci_edtable
[idx
] = e
;
723 child
= (idx
== 0) ? softc
->ohci_isoc_list
: softc
->ohci_edtable
[(idx
-1)/2];
724 ed
= ohci_ed_from_endpoint(softc
,e
);
725 ed
->ed_next_ed
= BSWAP32(child
->ep_phys
);
730 * We maintain both physical and virtual copies of the interrupt
731 * table (leaves of the tree).
734 for (idx
= 0; idx
< OHCI_INTTABLE_SIZE
; idx
++) {
735 child
= softc
->ohci_edtable
[OHCI_INTTREE_SIZE
-OHCI_INTTABLE_SIZE
+idx
];
736 softc
->ohci_inttable
[ohci_revbits
[idx
]] = child
;
737 softc
->ohci_hcca
->hcca_inttable
[ohci_revbits
[idx
]] = BSWAP32(child
->ep_phys
);
741 * Okay, at this point the tree is built.
746 /* *********************************************************************
749 * Stop the OHCI hardware.
752 * bus - our bus structure
756 ********************************************************************* */
758 static void ohci_stop(usbbus_t
*bus
)
760 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
762 OHCI_WRITECSR(softc
,R_OHCI_CONTROL
,V_OHCI_CONTROL_HCFS(K_OHCI_HCFS_RESET
));
766 /* *********************************************************************
767 * _ohci_queueept(softc,queue,e)
769 * Add an endpoint to a list of endpoints. This routine
770 * does things in a particular way according to the OHCI
771 * spec so we can add endpoints while the hardware is running.
774 * queue - endpoint descriptor for head of queue
775 * e - endpoint to add to queue
779 ********************************************************************* */
781 static void _ohci_queueept(ohci_softc_t
*softc
,ohci_endpoint_t
*queue
,ohci_endpoint_t
*newept
)
786 qed
= ohci_ed_from_endpoint(softc
,queue
);
787 newed
= ohci_ed_from_endpoint(softc
,newept
);
789 newept
->ep_next
= queue
->ep_next
;
790 newed
->ed_next_ed
= qed
->ed_next_ed
;
792 queue
->ep_next
= newept
;
793 qed
->ed_next_ed
= BSWAP32(newept
->ep_phys
);
795 if (ohcidebug
> 1) ohci_dumped(newed
);
799 /* *********************************************************************
800 * _ohci_deqept(queue,e)
802 * Remove and endpoint from the list of endpoints. This
803 * routine does things in a particular way according to
804 * the OHCI specification, since we are operating on
808 * queue - base of queue to look for endpoint on
809 * e - endpoint to remove
813 ********************************************************************* */
815 static void _ohci_deqept(ohci_softc_t
*softc
,ohci_endpoint_t
*queue
,ohci_endpoint_t
*e
)
817 ohci_endpoint_t
*cur
;
823 while (cur
&& (cur
->ep_next
!= e
)) cur
= cur
->ep_next
;
826 printf("Could not remove EP %08X: not on the list!\n",(uint32_t) (intptr_t)e
);
831 * Remove from our regular list
834 cur
->ep_next
= e
->ep_next
;
837 * now remove from the hardware's list
840 cured
= ohci_ed_from_endpoint(softc
,cur
);
841 ed
= ohci_ed_from_endpoint(softc
,e
);
843 cured
->ed_next_ed
= ed
->ed_next_ed
;
847 /* *********************************************************************
848 * ohci_intr_procdoneq(softc)
850 * Process the "done" queue for this ohci controller. As
851 * descriptors are retired, the hardware links them to the
852 * "done" queue so we can examine the results.
855 * softc - our OHCI controller
859 ********************************************************************* */
861 static void ohci_intr_procdoneq(ohci_softc_t
*softc
)
864 ohci_transfer_t
*transfer
;
870 * Get the head of the queue
873 doneq
= softc
->ohci_hcca
->hcca_donehead
;
874 doneq
= BSWAP32(doneq
);
876 td
= (ohci_td_t
*) OHCI_PTOV(doneq
);
877 transfer
= ohci_transfer_from_td(softc
,td
);
880 * Process all elements from the queue
886 ohci_endpoint_t
*ept
;
887 usbreq_t
*xur
= transfer
->t_ref
;
891 ept
= (ohci_endpoint_t
*) xur
->ur_pipe
->up_hwendpoint
;
892 ed
= ohci_ed_from_endpoint(softc
,ept
);
893 // printf("ProcDoneQ:ED [%08X] -> ",ept->ep_phys);
899 * Get the pointer to next one before freeing this one
903 ur
= transfer
->t_ref
;
904 printf("Done(%d): ",ur
? ur
->ur_tdcount
: -1);
908 doneq
= BSWAP32(td
->td_next_td
);
910 val
= G_OHCI_TD_CC(BSWAP32(td
->td_control
));
912 if (val
!= 0) printf("[Transfer error: %d]\n",val
);
915 * See if it's time to call the callback.
917 ur
= transfer
->t_ref
;
921 if (BSWAP32(td
->td_cbp
) == 0) {
922 ur
->ur_xferred
+= transfer
->t_length
;
925 ur
->ur_xferred
+= transfer
->t_length
-
926 (BSWAP32(td
->td_be
) - BSWAP32(td
->td_cbp
) + 1);
928 if (ur
->ur_tdcount
== 0) {
929 /* Noncoherent DMA: need to invalidate, since data is in phys mem */
930 OHCI_INVAL_RANGE(ur
->ur_buffer
,ur
->ur_xferred
);
931 usb_complete_request(ur
,val
);
937 * Free up the request
939 _ohci_freexfer(softc
,transfer
);
943 * Advance to the next request.
946 td
= (ohci_td_t
*) OHCI_PTOV(doneq
);
947 transfer
= ohci_transfer_from_td(softc
,td
);
952 /* *********************************************************************
955 * Process pending interrupts for the OHCI controller.
958 * bus - our bus structure
961 * 0 if we did nothing
962 * nonzero if we did something.
963 ********************************************************************* */
965 static int ohci_intr(usbbus_t
*bus
)
968 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
971 * Read the interrupt status register.
974 reg
= OHCI_READCSR(softc
,R_OHCI_INTSTATUS
);
977 * Don't bother doing anything if nothing happened.
983 /* Scheduling Overruns */
984 if (reg
& M_OHCI_INT_SO
) {
985 printf("SchedOverrun\n");
989 if (reg
& M_OHCI_INT_WDH
) {
990 /* printf("DoneQueue\n"); */
991 ohci_intr_procdoneq(softc
);
995 if (reg
& M_OHCI_INT_SF
) {
996 /* don't be noisy about this */
1000 if (reg
& M_OHCI_INT_RD
) {
1001 printf("ResumeDetect\n");
1004 /* Unrecoverable errors */
1005 if (reg
& M_OHCI_INT_UE
) {
1006 printf("UnrecoverableError\n");
1009 /* Frame number overflow */
1010 if (reg
& M_OHCI_INT_FNO
) {
1011 /*printf("FrameNumberOverflow\n"); */
1014 /* Root Hub Status Change */
1015 if ((reg
& ~softc
->ohci_intdisable
) & M_OHCI_INT_RHSC
) {
1017 if (ohcidebug
> 0) {
1018 printf("RootHubStatusChange: ");
1019 reg
= OHCI_READCSR(softc
,R_OHCI_RHSTATUS
);
1020 ohci_dumprhstat(reg
);
1021 reg
= OHCI_READCSR(softc
,R_OHCI_RHPORTSTATUS(1));
1022 ohci_dumpportstat(1,reg
);
1023 reg
= OHCI_READCSR(softc
,R_OHCI_RHPORTSTATUS(2));
1024 ohci_dumpportstat(2,reg
);
1026 ohci_roothub_statchg(softc
);
1029 /* Ownership Change */
1030 if (reg
& M_OHCI_INT_OC
) {
1031 printf("OwnershipChange\n");
1035 * Write the value back to the interrupt
1036 * register to clear the bits that were set.
1039 OHCI_WRITECSR(softc
,R_OHCI_INTSTATUS
,reg
);
1045 /* *********************************************************************
1048 * Remove an OHCI bus structure and all resources allocated to
1049 * it (used when shutting down USB)
1052 * bus - our USB bus structure
1056 ********************************************************************* */
1058 static void ohci_delete(usbbus_t
*bus
)
1063 /* *********************************************************************
1066 * Create a USB bus structure and associate it with our OHCI
1067 * controller device.
1070 * addr - physical address of controller
1073 * usbbus structure pointer
1074 ********************************************************************* */
1076 static usbbus_t
*ohci_create(physaddr_t addr
)
1079 ohci_softc_t
*softc
;
1082 softc
= KMALLOC(sizeof(ohci_softc_t
),0);
1083 if (!softc
) return NULL
;
1085 bus
= KMALLOC(sizeof(usbbus_t
),0);
1086 if (!bus
) return NULL
;
1088 memset(softc
,0,sizeof(ohci_softc_t
));
1089 memset(bus
,0,sizeof(usbbus_t
));
1091 bus
->ub_hwsoftc
= (usb_hc_t
*) softc
;
1092 bus
->ub_hwdisp
= &ohci_driver
;
1094 q_init(&(softc
->ohci_rh_intrq
));
1097 softc
->ohci_regs
= addr
;
1099 softc
->ohci_regs
= (volatile uint32_t *) addr
;
1102 softc
->ohci_rh_newaddr
= -1;
1103 softc
->ohci_bus
= bus
;
1105 if ((res
= _ohci_initpools(softc
)) != 0) goto error
;
1106 if ((res
= _ohci_setupepts(softc
)) != 0) goto error
;
1108 OHCI_WRITECSR(softc
,R_OHCI_CONTROL
,V_OHCI_CONTROL_HCFS(K_OHCI_HCFS_RESET
));
1118 /* *********************************************************************
1119 * ohci_ept_create(bus,usbaddr,eptnum,mps,flags)
1121 * Create a hardware endpoint structure and attach it to
1122 * the hardware's endpoint list. The hardware manages lists
1123 * of queues, and this routine adds a new queue to the appropriate
1124 * list of queues for the endpoint in question. It roughly
1125 * corresponds to the information in the OHCI specification.
1128 * bus - the USB bus we're dealing with
1129 * usbaddr - USB address (0 means default address)
1130 * eptnum - the endpoint number
1131 * mps - the packet size for this endpoint
1132 * flags - various flags to control endpoint creation
1135 * endpoint structure poihter, or NULL
1136 ********************************************************************* */
1138 static usb_ept_t
*ohci_ept_create(usbbus_t
*bus
,
1145 ohci_endpoint_t
*ept
;
1147 ohci_transfer_t
*tailtransfer
;
1149 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
1151 ept
= _ohci_allocept(softc
);
1152 ed
= ohci_ed_from_endpoint(softc
,ept
);
1154 tailtransfer
= _ohci_allocxfer(softc
);
1155 tailtd
= ohci_td_from_transfer(softc
,tailtransfer
);
1158 * Set up functional address, endpoint number, and packet size
1161 eptflags
= V_OHCI_ED_FA(usbaddr
) |
1162 V_OHCI_ED_EN(eptnum
) |
1163 V_OHCI_ED_MPS(mps
) |
1167 * Set up the endpoint type based on the flags
1171 if (flags
& UP_TYPE_IN
) {
1172 eptflags
|= V_OHCI_ED_DIR(K_OHCI_ED_DIR_IN
);
1174 else if (flags
& UP_TYPE_OUT
) {
1175 eptflags
|= V_OHCI_ED_DIR(K_OHCI_ED_DIR_OUT
);
1178 eptflags
|= V_OHCI_ED_DIR(K_OHCI_ED_DIR_FROMTD
);
1182 * Don't forget about lowspeed devices.
1185 if (flags
& UP_TYPE_LOWSPEED
) {
1186 eptflags
|= M_OHCI_ED_LOWSPEED
;
1189 if (ohcidebug
> 0) {
1190 printf("Create endpoint %d addr %d flags %08X mps %d\n",
1191 eptnum
,usbaddr
,eptflags
,mps
);
1195 * Transfer this info into the endpoint descriptor.
1196 * No need to flush the cache here, it'll get done when
1197 * we add to the hardware list.
1200 ed
->ed_control
= BSWAP32(eptflags
);
1201 ed
->ed_tailp
= BSWAP32(OHCI_VTOP(tailtd
));
1202 ed
->ed_headp
= BSWAP32(OHCI_VTOP(tailtd
));
1203 ept
->ep_flags
= flags
;
1205 ept
->ep_num
= eptnum
;
1208 * Put it on the right queue
1211 if (flags
& UP_TYPE_CONTROL
) {
1212 _ohci_queueept(softc
,softc
->ohci_ctl_list
,ept
);
1214 else if (flags
& UP_TYPE_BULK
) {
1215 _ohci_queueept(softc
,softc
->ohci_bulk_list
,ept
);
1217 else if (flags
& UP_TYPE_INTR
) {
1218 _ohci_queueept(softc
,softc
->ohci_inttable
[0],ept
);
1221 return (usb_ept_t
*) ept
;
1224 /* *********************************************************************
1225 * ohci_ept_setaddr(bus,ept,usbaddr)
1227 * Change the functional address for a USB endpoint. We do this
1228 * when we switch the device's state from DEFAULT to ADDRESSED
1229 * and we've already got the default pipe open. This
1230 * routine mucks with the descriptor and changes its address
1234 * bus - usb bus structure
1235 * ept - an open endpoint descriptor
1236 * usbaddr - new address for this endpoint
1240 ********************************************************************* */
1242 static void ohci_ept_setaddr(usbbus_t
*bus
,usb_ept_t
*uept
,int usbaddr
)
1245 ohci_endpoint_t
*ept
= (ohci_endpoint_t
*) uept
;
1246 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
1247 ohci_ed_t
*ed
= ohci_ed_from_endpoint(softc
,ept
);
1249 eptflags
= BSWAP32(ed
->ed_control
);
1250 eptflags
&= ~M_OHCI_ED_FA
;
1251 eptflags
|= V_OHCI_ED_FA(usbaddr
);
1252 ed
->ed_control
= BSWAP32(eptflags
);
1256 /* *********************************************************************
1257 * ohci_ept_setmps(bus,ept,mps)
1259 * Set the maximum packet size of this endpoint. This is
1260 * normally used during the processing of endpoint 0 (default
1261 * pipe) after we find out how big ep0's packets can be.
1264 * bus - our USB bus structure
1265 * ept - endpoint structure
1266 * mps - new packet size
1270 ********************************************************************* */
1272 static void ohci_ept_setmps(usbbus_t
*bus
,usb_ept_t
*uept
,int mps
)
1275 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
1276 ohci_endpoint_t
*ept
= (ohci_endpoint_t
*) uept
;
1277 ohci_ed_t
*ed
= ohci_ed_from_endpoint(softc
,ept
);
1279 eptflags
= BSWAP32(ed
->ed_control
);
1280 eptflags
&= ~M_OHCI_ED_MPS
;
1281 eptflags
|= V_OHCI_ED_MPS(mps
);
1282 ed
->ed_control
= BSWAP32(eptflags
);
1287 /* *********************************************************************
1288 * ohci_ept_cleartoggle(bus,ept,mps)
1290 * Clear the data toggle for the specified endpoint.
1293 * bus - our USB bus structure
1294 * ept - endpoint structure
1298 ********************************************************************* */
1300 static void ohci_ept_cleartoggle(usbbus_t
*bus
,usb_ept_t
*uept
)
1303 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
1304 ohci_endpoint_t
*ept
= (ohci_endpoint_t
*) uept
;
1305 ohci_ed_t
*ed
= ohci_ed_from_endpoint(softc
,ept
);
1307 eptflags
= BSWAP32(ed
->ed_headp
);
1308 eptflags
&= ~(M_OHCI_ED_HALT
| M_OHCI_ED_TOGGLECARRY
);
1309 ed
->ed_headp
= BSWAP32(eptflags
);
1311 OHCI_WRITECSR(softc
,R_OHCI_CMDSTATUS
,M_OHCI_CMDSTATUS_CLF
);
1314 /* *********************************************************************
1315 * ohci_ept_delete(bus,ept)
1317 * Deletes an endpoint from the OHCI controller. This
1318 * routine also completes pending transfers for the
1319 * endpoint and gets rid of the hardware ept (queue base).
1322 * bus - ohci bus structure
1323 * ept - endpoint to remove
1327 ********************************************************************* */
1329 static void ohci_ept_delete(usbbus_t
*bus
,usb_ept_t
*uept
)
1331 ohci_endpoint_t
*queue
;
1332 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
1333 ohci_endpoint_t
*ept
= (ohci_endpoint_t
*) uept
;
1334 ohci_ed_t
*ed
= ohci_ed_from_endpoint(softc
,ept
);
1339 ohci_transfer_t
*transfer
;
1341 if (ept
->ep_flags
& UP_TYPE_CONTROL
) {
1342 queue
= softc
->ohci_ctl_list
;
1344 else if (ept
->ep_flags
& UP_TYPE_BULK
) {
1345 queue
= softc
->ohci_bulk_list
;
1347 else if (ept
->ep_flags
& UP_TYPE_INTR
) {
1348 queue
= softc
->ohci_inttable
[0];
1351 printf("Invalid endpoint\n");
1357 * Set the SKIP bit on the endpoint and
1358 * wait for two SOFs to guarantee that we're
1359 * not processing this ED anymore.
1362 ((volatile uint32_t) ed
->ed_control
) |= BSWAP32(M_OHCI_ED_SKIP
);
1364 framenum
= OHCI_READCSR(softc
,R_OHCI_FMNUMBER
) & 0xFFFF;
1365 while ((OHCI_READCSR(softc
,R_OHCI_FMNUMBER
) & 0xFFFF) == framenum
) ; /* NULL LOOP */
1367 framenum
= OHCI_READCSR(softc
,R_OHCI_FMNUMBER
) & 0xFFFF;
1368 while ((OHCI_READCSR(softc
,R_OHCI_FMNUMBER
) & 0xFFFF) == framenum
) ; /* NULL LOOP */
1371 * Remove endpoint from queue
1374 _ohci_deqept(softc
,queue
,ept
);
1377 * Free/complete the TDs on the queue
1380 tdphys
= BSWAP32(ed
->ed_headp
) & M_OHCI_ED_PTRMASK
;
1382 while (tdphys
!= BSWAP32(ed
->ed_tailp
)) {
1383 td
= (ohci_td_t
*) OHCI_PTOV(tdphys
);
1384 tdphys
= BSWAP32(td
->td_next_td
);
1385 transfer
= ohci_transfer_from_td(softc
,td
);
1387 ur
= transfer
->t_ref
;
1389 ur
->ur_status
= K_OHCI_CC_CANCELLED
;
1391 if (ur
->ur_tdcount
== 0) {
1392 if (ohcidebug
> 0) printf("Completing request due to closed pipe: %p\n",ur
);
1393 usb_complete_request(ur
,K_OHCI_CC_CANCELLED
);
1397 _ohci_freexfer(softc
,transfer
);
1401 * tdphys now points at the tail TD. Just free it.
1404 td
= (ohci_td_t
*) OHCI_PTOV(tdphys
);
1405 _ohci_freexfer(softc
,ohci_transfer_from_td(softc
,td
));
1408 * Return endpoint to free pool
1411 _ohci_freeept(softc
,ept
);
1416 /* *********************************************************************
1417 * ohci_xfer(bus,ept,ur)
1419 * Queue a transfer for the specified endpoint. Depending on
1420 * the transfer type, the transfer may go on one of many queues.
1421 * When the transfer completes, a callback will be called.
1424 * bus - bus structure
1425 * ept - endpoint descriptor
1426 * ur - request (includes pointer to user buffer)
1431 ********************************************************************* */
1433 static int ohci_xfer(usbbus_t
*bus
,usb_ept_t
*uept
,usbreq_t
*ur
)
1435 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
1436 ohci_endpoint_t
*ept
= (ohci_endpoint_t
*) uept
;
1437 ohci_ed_t
*ed
= ohci_ed_from_endpoint(softc
,ept
);
1438 ohci_transfer_t
*newtailtransfer
= 0;
1439 ohci_td_t
*newtailtd
= NULL
;
1440 ohci_transfer_t
*curtransfer
;
1446 uint32_t tdcontrol
= 0;
1449 * If the destination USB address matches
1450 * the address of the root hub, shunt the request
1451 * over to our root hub emulation.
1454 if (ur
->ur_dev
->ud_address
== softc
->ohci_rh_addr
) {
1455 return ohci_roothub_xfer(bus
,uept
,ur
);
1459 * Set up the TD flags based on the
1463 // pktlen = ept->ep_mps;
1464 pktlen
= OHCI_TD_MAX_DATA
- 16;
1466 if (ur
->ur_flags
& UR_FLAG_SETUP
) {
1467 tdcontrol
= V_OHCI_TD_PID(K_OHCI_TD_SETUP
) |
1468 V_OHCI_TD_DT(K_OHCI_TD_DT_DATA0
) |
1469 V_OHCI_TD_CC(K_OHCI_CC_NOTACCESSED
) |
1472 else if (ur
->ur_flags
& UR_FLAG_IN
) {
1473 tdcontrol
= V_OHCI_TD_PID(K_OHCI_TD_IN
) |
1474 V_OHCI_TD_DT(K_OHCI_TD_DT_TCARRY
) |
1475 V_OHCI_TD_CC(K_OHCI_CC_NOTACCESSED
) |
1478 else if (ur
->ur_flags
& UR_FLAG_OUT
) {
1479 tdcontrol
= V_OHCI_TD_PID(K_OHCI_TD_OUT
) |
1480 V_OHCI_TD_DT(K_OHCI_TD_DT_TCARRY
) |
1481 V_OHCI_TD_CC(K_OHCI_CC_NOTACCESSED
) |
1484 else if (ur
->ur_flags
& UR_FLAG_STATUS_OUT
) {
1485 tdcontrol
= V_OHCI_TD_PID(K_OHCI_TD_OUT
) |
1486 V_OHCI_TD_DT(K_OHCI_TD_DT_DATA1
) |
1487 V_OHCI_TD_CC(K_OHCI_CC_NOTACCESSED
) |
1490 else if (ur
->ur_flags
& UR_FLAG_STATUS_IN
) {
1491 tdcontrol
= V_OHCI_TD_PID(K_OHCI_TD_IN
) |
1492 V_OHCI_TD_DT(K_OHCI_TD_DT_DATA1
) |
1493 V_OHCI_TD_CC(K_OHCI_CC_NOTACCESSED
) |
1497 printf("Shouldn't happen!\n");
1500 if (ur
->ur_flags
& UR_FLAG_SHORTOK
) {
1501 tdcontrol
|= M_OHCI_TD_SHORTOK
;
1505 ptr
= ur
->ur_buffer
;
1506 len
= ur
->ur_length
;
1509 if (ohcidebug
> 1) {
1510 printf(">> Queueing xfer addr %d pipe %d ED %08X ptr %016llX length %d\n",
1511 ur
->ur_dev
->ud_address
,
1512 ur
->ur_pipe
->up_num
,
1514 (uint64_t) (uintptr_t) ptr
,
1519 curtd
= OHCI_PTOV(BSWAP32(ed
->ed_tailp
));
1520 curtransfer
= ohci_transfer_from_td(softc
,curtd
);
1523 newtailtransfer
= _ohci_allocxfer(softc
);
1524 newtailtd
= ohci_td_from_transfer(softc
,newtailtransfer
);
1527 curtd
->td_next_td
= BSWAP32(OHCI_VTOP(newtailtd
));
1528 curtd
->td_control
= BSWAP32(tdcontrol
);
1529 curtransfer
->t_next
= newtailtransfer
;
1530 curtransfer
->t_ref
= ur
;
1531 curtransfer
->t_length
= 0;
1532 if (ohcidebug
> 1) { printf("QueueTD: "); ohci_dumptd(curtd
); }
1536 /* Noncoherent DMA: need to flush user buffer to real memory first */
1537 OHCI_FLUSH_RANGE(ptr
,len
);
1540 if (amtcopy
> pktlen
) amtcopy
= pktlen
;
1541 newtailtransfer
= _ohci_allocxfer(softc
);
1542 newtailtd
= ohci_td_from_transfer(softc
,newtailtransfer
);
1543 curtd
->td_cbp
= BSWAP32(OHCI_VTOP(ptr
));
1544 curtd
->td_be
= BSWAP32(OHCI_VTOP(ptr
+amtcopy
)-1);
1545 curtd
->td_next_td
= BSWAP32(OHCI_VTOP(newtailtd
));
1546 curtd
->td_control
= BSWAP32(tdcontrol
);
1547 curtransfer
->t_next
= newtailtransfer
;
1548 curtransfer
->t_ref
= ur
;
1549 curtransfer
->t_length
= amtcopy
;
1550 if (ohcidebug
> 1) { printf("QueueTD: "); ohci_dumptd(curtd
); }
1552 curtransfer
= ohci_transfer_from_td(softc
,curtd
);
1559 curtd
= OHCI_PTOV(BSWAP32(ed
->ed_headp
& M_OHCI_ED_PTRMASK
));
1560 ed
->ed_tailp
= BSWAP32(OHCI_VTOP(newtailtd
));
1563 * Prod the controller depending on what type of list we put
1567 if (ept
->ep_flags
& UP_TYPE_BULK
) {
1568 OHCI_WRITECSR(softc
,R_OHCI_CMDSTATUS
,M_OHCI_CMDSTATUS_BLF
);
1571 OHCI_WRITECSR(softc
,R_OHCI_CMDSTATUS
,M_OHCI_CMDSTATUS_CLF
);
1577 /* *********************************************************************
1579 ********************************************************************* */
1581 usb_hcdrv_t ohci_driver
= {
1591 ohci_ept_cleartoggle
,
1595 /* *********************************************************************
1598 * Data structures and functions
1599 ********************************************************************* */
1602 * Data structures and routines to emulate the root hub.
1604 static usb_device_descr_t ohci_root_devdsc
= {
1605 sizeof(usb_device_descr_t
), /* bLength */
1606 USB_DEVICE_DESCRIPTOR_TYPE
, /* bDescriptorType */
1607 USBWORD(0x0100), /* bcdUSB */
1608 USB_DEVICE_CLASS_HUB
, /* bDeviceClass */
1609 0, /* bDeviceSubClass */
1610 0, /* bDeviceProtocol */
1611 64, /* bMaxPacketSize0 */
1612 USBWORD(0), /* idVendor */
1613 USBWORD(0), /* idProduct */
1614 USBWORD(0x0100), /* bcdDevice */
1615 1, /* iManufacturer */
1617 0, /* iSerialNumber */
1618 1 /* bNumConfigurations */
1621 static usb_config_descr_t ohci_root_cfgdsc
= {
1622 sizeof(usb_config_descr_t
), /* bLength */
1623 USB_CONFIGURATION_DESCRIPTOR_TYPE
, /* bDescriptorType */
1625 sizeof(usb_config_descr_t
) +
1626 sizeof(usb_interface_descr_t
) +
1627 sizeof(usb_endpoint_descr_t
)), /* wTotalLength */
1628 1, /* bNumInterfaces */
1629 1, /* bConfigurationValue */
1630 0, /* iConfiguration */
1631 USB_CONFIG_SELF_POWERED
, /* bmAttributes */
1635 static usb_interface_descr_t ohci_root_ifdsc
= {
1636 sizeof(usb_interface_descr_t
), /* bLength */
1637 USB_INTERFACE_DESCRIPTOR_TYPE
, /* bDescriptorType */
1638 0, /* bInterfaceNumber */
1639 0, /* bAlternateSetting */
1640 1, /* bNumEndpoints */
1641 USB_INTERFACE_CLASS_HUB
, /* bInterfaceClass */
1642 0, /* bInterfaceSubClass */
1643 0, /* bInterfaceProtocol */
1647 static usb_endpoint_descr_t ohci_root_epdsc
= {
1648 sizeof(usb_endpoint_descr_t
), /* bLength */
1649 USB_ENDPOINT_DESCRIPTOR_TYPE
, /* bDescriptorType */
1650 (USB_ENDPOINT_DIRECTION_IN
| 1), /* bEndpointAddress */
1651 USB_ENDPOINT_TYPE_INTERRUPT
, /* bmAttributes */
1652 USBWORD(8), /* wMaxPacketSize */
1656 static usb_hub_descr_t ohci_root_hubdsc
= {
1657 USB_HUB_DESCR_SIZE
, /* bLength */
1658 USB_HUB_DESCRIPTOR_TYPE
, /* bDescriptorType */
1659 0, /* bNumberOfPorts */
1660 USBWORD(0), /* wHubCharacteristics */
1661 0, /* bPowreOnToPowerGood */
1662 0, /* bHubControl Current */
1663 {0} /* bRemoveAndPowerMask */
1666 /* *********************************************************************
1667 * ohci_roothb_strdscr(ptr,str)
1669 * Construct a string descriptor for root hub requests
1672 * ptr - pointer to where to put descriptor
1673 * str - regular string to put into descriptor
1676 * number of bytes written to descriptor
1677 ********************************************************************* */
1679 static int ohci_roothub_strdscr(uint8_t *ptr
,char *str
)
1683 *p
++ = strlen(str
)*2 + 2; /* Unicode strings */
1684 *p
++ = USB_STRING_DESCRIPTOR_TYPE
;
1692 /* *********************************************************************
1693 * ohci_roothub_req(softc,req)
1695 * Handle a descriptor request on the control pipe for the
1696 * root hub. We pretend to be a real root hub here and
1697 * return all the standard descriptors.
1700 * softc - our OHCI controller
1701 * req - a usb request (completed immediately)
1706 ********************************************************************* */
1708 static int ohci_roothub_req(ohci_softc_t
*softc
,usb_device_request_t
*req
)
1714 usb_port_status_t ups
;
1715 usb_hub_descr_t hdsc
;
1721 ptr
= softc
->ohci_rh_buf
;
1723 wLength
= GETUSBFIELD(req
,wLength
);
1724 wValue
= GETUSBFIELD(req
,wValue
);
1725 wIndex
= GETUSBFIELD(req
,wIndex
);
1727 switch (REQSW(req
->bRequest
,req
->bmRequestType
)) {
1729 case REQCODE(USB_REQUEST_GET_STATUS
,USBREQ_DIR_IN
,USBREQ_TYPE_STD
,USBREQ_REC_DEVICE
):
1730 *ptr
++ = (USB_GETSTATUS_SELF_POWERED
& 0xFF);
1731 *ptr
++ = (USB_GETSTATUS_SELF_POWERED
>> 8);
1734 case REQCODE(USB_REQUEST_GET_STATUS
,USBREQ_DIR_IN
,USBREQ_TYPE_STD
,USBREQ_REC_ENDPOINT
):
1735 case REQCODE(USB_REQUEST_GET_STATUS
,USBREQ_DIR_IN
,USBREQ_TYPE_STD
,USBREQ_REC_INTERFACE
):
1740 case REQCODE(USB_REQUEST_GET_STATUS
,USBREQ_DIR_IN
,USBREQ_TYPE_CLASS
,USBREQ_REC_OTHER
):
1741 status
= OHCI_READCSR(softc
,(R_OHCI_RHPORTSTATUS(wIndex
)));
1742 if (ohcidebug
> 0) { printf("RHGetStatus: "); ohci_dumpportstat(wIndex
,status
);}
1743 PUTUSBFIELD((&ups
),wPortStatus
,(status
& 0xFFFF));
1744 PUTUSBFIELD((&ups
),wPortChange
,(status
>> 16));
1745 memcpy(ptr
,&ups
,sizeof(ups
));
1749 case REQCODE(USB_REQUEST_GET_STATUS
,USBREQ_DIR_IN
,USBREQ_TYPE_CLASS
,USBREQ_REC_DEVICE
):
1756 case REQCODE(USB_REQUEST_CLEAR_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_DEVICE
):
1757 case REQCODE(USB_REQUEST_CLEAR_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_INTERFACE
):
1758 case REQCODE(USB_REQUEST_CLEAR_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_ENDPOINT
):
1759 /* do nothing, not supported */
1762 case REQCODE(USB_REQUEST_CLEAR_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_CLASS
,USBREQ_REC_OTHER
):
1763 statport
= R_OHCI_RHPORTSTATUS(wIndex
);
1765 printf("RHClearFeature(%d): ",wValue
); ohci_dumpportstat(wIndex
,OHCI_READCSR(softc
,statport
));
1768 case USB_PORT_FEATURE_CONNECTION
:
1770 case USB_PORT_FEATURE_ENABLE
:
1771 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_CCS
);
1773 case USB_PORT_FEATURE_SUSPEND
:
1774 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_POCI
);
1776 case USB_PORT_FEATURE_OVER_CURRENT
:
1778 case USB_PORT_FEATURE_RESET
:
1780 case USB_PORT_FEATURE_POWER
:
1781 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_LSDA
);
1783 case USB_PORT_FEATURE_LOW_SPEED
:
1785 case USB_PORT_FEATURE_C_PORT_CONNECTION
:
1786 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_CSC
);
1788 case USB_PORT_FEATURE_C_PORT_ENABLE
:
1789 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_PESC
);
1791 case USB_PORT_FEATURE_C_PORT_SUSPEND
:
1792 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_PSSC
);
1794 case USB_PORT_FEATURE_C_PORT_OVER_CURRENT
:
1795 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_OCIC
);
1797 case USB_PORT_FEATURE_C_PORT_RESET
:
1798 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_PRSC
);
1804 * If we've cleared all of the conditions that
1805 * want our attention on the port status,
1806 * then we can accept port status interrupts again.
1809 if ((wValue
>= USB_PORT_FEATURE_C_PORT_CONNECTION
) &&
1810 (wValue
<= USB_PORT_FEATURE_C_PORT_RESET
)) {
1811 status
= OHCI_READCSR(softc
,statport
);
1812 if ((status
& M_OHCI_RHPORTSTAT_ALLC
) == 0) {
1813 softc
->ohci_intdisable
&= ~M_OHCI_INT_RHSC
;
1818 case REQCODE(USB_REQUEST_SET_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_DEVICE
):
1819 case REQCODE(USB_REQUEST_SET_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_INTERFACE
):
1820 case REQCODE(USB_REQUEST_SET_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_ENDPOINT
):
1824 case REQCODE(USB_REQUEST_SET_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_CLASS
,USBREQ_REC_DEVICE
):
1828 case REQCODE(USB_REQUEST_SET_FEATURE
,USBREQ_DIR_OUT
,USBREQ_TYPE_CLASS
,USBREQ_REC_OTHER
):
1829 statport
= R_OHCI_RHPORTSTATUS(wIndex
);
1831 case USB_PORT_FEATURE_CONNECTION
:
1833 case USB_PORT_FEATURE_ENABLE
:
1834 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_PES
);
1836 case USB_PORT_FEATURE_SUSPEND
:
1837 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_PSS
);
1839 case USB_PORT_FEATURE_OVER_CURRENT
:
1841 case USB_PORT_FEATURE_RESET
:
1842 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_PRS
);
1844 usb_delay_ms(softc
->ohci_bus
,100);
1845 if (!(OHCI_READCSR(softc
,statport
) & M_OHCI_RHPORTSTAT_PRS
)) break;
1848 case USB_PORT_FEATURE_POWER
:
1849 OHCI_WRITECSR(softc
,statport
,M_OHCI_RHPORTSTAT_PPS
);
1851 case USB_PORT_FEATURE_LOW_SPEED
:
1853 case USB_PORT_FEATURE_C_PORT_CONNECTION
:
1855 case USB_PORT_FEATURE_C_PORT_ENABLE
:
1857 case USB_PORT_FEATURE_C_PORT_SUSPEND
:
1859 case USB_PORT_FEATURE_C_PORT_OVER_CURRENT
:
1861 case USB_PORT_FEATURE_C_PORT_RESET
:
1868 case REQCODE(USB_REQUEST_SET_ADDRESS
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_DEVICE
):
1869 softc
->ohci_rh_newaddr
= wValue
;
1872 case REQCODE(USB_REQUEST_GET_DESCRIPTOR
,USBREQ_DIR_IN
,USBREQ_TYPE_STD
,USBREQ_REC_DEVICE
):
1873 switch (wValue
>> 8) {
1874 case USB_DEVICE_DESCRIPTOR_TYPE
:
1875 memcpy(ptr
,&ohci_root_devdsc
,sizeof(ohci_root_devdsc
));
1876 ptr
+= sizeof(ohci_root_devdsc
);
1878 case USB_CONFIGURATION_DESCRIPTOR_TYPE
:
1879 memcpy(ptr
,&ohci_root_cfgdsc
,sizeof(ohci_root_cfgdsc
));
1880 ptr
+= sizeof(ohci_root_cfgdsc
);
1881 memcpy(ptr
,&ohci_root_ifdsc
,sizeof(ohci_root_ifdsc
));
1882 ptr
+= sizeof(ohci_root_ifdsc
);
1883 memcpy(ptr
,&ohci_root_epdsc
,sizeof(ohci_root_epdsc
));
1884 ptr
+= sizeof(ohci_root_epdsc
);
1886 case USB_STRING_DESCRIPTOR_TYPE
:
1887 switch (wValue
& 0xFF) {
1889 ptr
+= ohci_roothub_strdscr(ptr
,"Generic");
1892 ptr
+= ohci_roothub_strdscr(ptr
,"Root Hub");
1905 case REQCODE(USB_REQUEST_GET_DESCRIPTOR
,USBREQ_DIR_IN
,USBREQ_TYPE_CLASS
,USBREQ_REC_DEVICE
):
1906 memcpy(&hdsc
,&ohci_root_hubdsc
,sizeof(hdsc
));
1907 hdsc
.bNumberOfPorts
= softc
->ohci_ndp
;
1908 status
= OHCI_READCSR(softc
,R_OHCI_RHDSCRA
);
1910 if (status
& M_OHCI_RHDSCRA_NPS
) tmpval
|= USB_HUBCHAR_PWR_NONE
;
1911 if (status
& M_OHCI_RHDSCRA_PSM
) tmpval
|= USB_HUBCHAR_PWR_GANGED
;
1912 else tmpval
|= USB_HUBCHAR_PWR_IND
;
1913 PUTUSBFIELD((&hdsc
),wHubCharacteristics
,tmpval
);
1914 tmpval
= G_OHCI_RHDSCRA_POTPGT(status
);
1915 hdsc
.bPowerOnToPowerGood
= tmpval
;
1916 hdsc
.bDescriptorLength
= USB_HUB_DESCR_SIZE
+ 1;
1917 status
= OHCI_READCSR(softc
,R_OHCI_RHDSCRB
);
1918 hdsc
.bRemoveAndPowerMask
[0] = (uint8_t) status
;
1919 memcpy(ptr
,&hdsc
,sizeof(hdsc
));
1920 ptr
+= sizeof(hdsc
);
1923 case REQCODE(USB_REQUEST_SET_DESCRIPTOR
,USBREQ_DIR_OUT
,USBREQ_TYPE_CLASS
,USBREQ_REC_DEVICE
):
1927 case REQCODE(USB_REQUEST_GET_CONFIGURATION
,USBREQ_DIR_IN
,USBREQ_TYPE_STD
,USBREQ_REC_DEVICE
):
1928 *ptr
++ = softc
->ohci_rh_conf
;
1931 case REQCODE(USB_REQUEST_SET_CONFIGURATION
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_DEVICE
):
1932 softc
->ohci_rh_conf
= wValue
;
1935 case REQCODE(USB_REQUEST_GET_INTERFACE
,USBREQ_DIR_IN
,USBREQ_TYPE_STD
,USBREQ_REC_INTERFACE
):
1939 case REQCODE(USB_REQUEST_SET_INTERFACE
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_INTERFACE
):
1943 case REQCODE(USB_REQUEST_SYNC_FRAME
,USBREQ_DIR_OUT
,USBREQ_TYPE_STD
,USBREQ_REC_ENDPOINT
):
1948 softc
->ohci_rh_ptr
= softc
->ohci_rh_buf
;
1949 softc
->ohci_rh_len
= ptr
- softc
->ohci_rh_buf
;
1954 /* *********************************************************************
1955 * ohci_roothub_statchg(softc)
1957 * This routine is called from the interrupt service routine
1958 * (well, polling routine) for the ohci controller. If the
1959 * controller notices a root hub status change, it dequeues an
1960 * interrupt transfer from the root hub's queue and completes
1964 * softc - our OHCI controller
1968 ********************************************************************* */
1970 static void ohci_roothub_statchg(ohci_softc_t
*softc
)
1974 uint8_t portstat
= 0;
1977 /* Note: this only works up to 8 ports */
1978 for (idx
= 1; idx
<= softc
->ohci_ndp
; idx
++) {
1979 status
= OHCI_READCSR(softc
,R_OHCI_RHPORTSTATUS(idx
));
1980 if (status
& M_OHCI_RHPORTSTAT_ALLC
) {
1981 portstat
= (1<<idx
);
1985 if (portstat
!= 0) {
1986 softc
->ohci_intdisable
|= M_OHCI_INT_RHSC
;
1989 ur
= (usbreq_t
*) q_deqnext(&(softc
->ohci_rh_intrq
));
1990 if (!ur
) return; /* no requests pending, ignore it */
1992 memset(ur
->ur_buffer
,0,ur
->ur_length
);
1993 ur
->ur_buffer
[0] = portstat
;
1994 ur
->ur_xferred
= ur
->ur_length
;
1996 usb_complete_request(ur
,0);
1999 /* *********************************************************************
2000 * ohci_roothub_xfer(softc,req)
2002 * Handle a root hub xfer - ohci_xfer transfers control here
2003 * if we detect the address of the root hub - no actual transfers
2004 * go out on the wire, we just handle the requests directly to
2005 * make it look like a hub is attached.
2007 * This seems to be common practice in the USB world, so we do
2011 * softc - our OHCI controller structure
2012 * req - usb request destined for host controller
2017 ********************************************************************* */
2019 static int ohci_roothub_xfer(usbbus_t
*bus
,usb_ept_t
*uept
,usbreq_t
*ur
)
2021 ohci_softc_t
*softc
= (ohci_softc_t
*) bus
->ub_hwsoftc
;
2022 ohci_endpoint_t
*ept
= (ohci_endpoint_t
*) uept
;
2025 switch (ept
->ep_num
) {
2033 * Three types of transfers: OUT (SETUP), IN (data), or STATUS.
2034 * figure out which is which.
2037 if (ur
->ur_flags
& UR_FLAG_SETUP
) {
2039 * SETUP packet - this is an OUT request to the control
2040 * pipe. We emulate the hub request here.
2042 usb_device_request_t
*req
;
2044 req
= (usb_device_request_t
*) ur
->ur_buffer
;
2046 res
= ohci_roothub_req(softc
,req
);
2047 if (res
!= 0) printf("Root hub request returned an error\n");
2049 ur
->ur_xferred
= ur
->ur_length
;
2051 usb_complete_request(ur
,0);
2054 else if (ur
->ur_flags
& UR_FLAG_STATUS_IN
) {
2056 * STATUS IN : it's sort of like a dummy IN request
2057 * to acknowledge a SETUP packet that otherwise has no
2058 * status. Just complete the usbreq.
2061 if (softc
->ohci_rh_newaddr
!= -1) {
2062 softc
->ohci_rh_addr
= softc
->ohci_rh_newaddr
;
2063 softc
->ohci_rh_newaddr
= -1;
2068 usb_complete_request(ur
,0);
2071 else if (ur
->ur_flags
& UR_FLAG_STATUS_OUT
) {
2073 * STATUS OUT : it's sort of like a dummy OUT request
2077 usb_complete_request(ur
,0);
2080 else if (ur
->ur_flags
& UR_FLAG_IN
) {
2082 * IN : return data from the root hub
2086 amtcopy
= softc
->ohci_rh_len
;
2087 if (amtcopy
> ur
->ur_length
) amtcopy
= ur
->ur_length
;
2089 memcpy(ur
->ur_buffer
,softc
->ohci_rh_ptr
,amtcopy
);
2091 softc
->ohci_rh_ptr
+= amtcopy
;
2092 softc
->ohci_rh_len
-= amtcopy
;
2095 ur
->ur_xferred
= amtcopy
;
2096 usb_complete_request(ur
,0);
2100 printf("Unknown root hub transfer type\n");
2106 * INTERRUPT ENDPOINT
2109 case 1: /* interrupt pipe */
2110 if (ur
->ur_flags
& UR_FLAG_IN
) {
2111 q_enqueue(&(softc
->ohci_rh_intrq
),(queue_t
*) ur
);