2 * This file is part of the libpayload project.
4 * Copyright (C) 2008-2010 coresystems GmbH
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <arch/virtual.h>
35 #include "uhci_private.h"
37 static void uhci_start (hci_t *controller);
38 static void uhci_stop (hci_t *controller);
39 static void uhci_reset (hci_t *controller);
40 static void uhci_shutdown (hci_t *controller);
41 static int uhci_bulk (endpoint_t *ep, int size, u8 *data, int finalize);
42 static int uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq,
44 static void* uhci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming);
45 static void uhci_destroy_intr_queue (endpoint_t *ep, void *queue);
46 static u8* uhci_poll_intr_queue (void *queue);
51 uhci_dump (hci_t *controller)
53 debug ("dump:\nUSBCMD: %x\n", uhci_reg_read16 (controller, USBCMD));
54 debug ("USBSTS: %x\n", uhci_reg_read16 (controller, USBSTS));
55 debug ("USBINTR: %x\n", uhci_reg_read16 (controller, USBINTR));
56 debug ("FRNUM: %x\n", uhci_reg_read16 (controller, FRNUM));
57 debug ("FLBASEADD: %x\n", uhci_reg_read32 (controller, FLBASEADD));
58 debug ("SOFMOD: %x\n", uhci_reg_read8 (controller, SOFMOD));
59 debug ("PORTSC1: %x\n", uhci_reg_read16 (controller, PORTSC1));
60 debug ("PORTSC2: %x\n", uhci_reg_read16 (controller, PORTSC2));
69 switch (td->token & TD_PID_MASK) {
80 sprintf(td_value, "%x", td->token & TD_PID_MASK);
83 debug ("%s packet (at %lx) to %x.%x failed\n", td_type,
84 virt_to_phys (td), (td->token & TD_DEVADDR_MASK) >> TD_DEVADDR_SHIFT,
85 (td->token & TD_EP_MASK) >> TD_EP_SHIFT);
86 debug ("td (counter at %x) returns: ", td->ctrlsts >> TD_COUNTER_SHIFT);
87 debug (" bitstuff err: %x, ", !!(td->ctrlsts & TD_STATUS_BITSTUFF_ERR));
88 debug (" CRC err: %x, ", !!(td->ctrlsts & TD_STATUS_CRC_ERR));
89 debug (" NAK rcvd: %x, ", !!(td->ctrlsts & TD_STATUS_NAK_RCVD));
90 debug (" Babble: %x, ", !!(td->ctrlsts & TD_STATUS_BABBLE));
91 debug (" Data Buffer err: %x, ", !!(td->ctrlsts & TD_STATUS_DATABUF_ERR));
92 debug (" Stalled: %x, ", !!(td->ctrlsts & TD_STATUS_STALLED));
93 debug (" Active: %x\n", !!(td->ctrlsts & TD_STATUS_ACTIVE));
94 if (td->ctrlsts & TD_STATUS_BABBLE)
95 debug (" Babble because of %s\n",
96 (td->ctrlsts & TD_STATUS_BITSTUFF_ERR) ? "host" : "device");
97 if (td->ctrlsts & TD_STATUS_ACTIVE)
98 debug (" still active - timeout?\n");
102 uhci_reset (hci_t *controller)
105 uhci_reg_write16 (controller, USBCMD, 4);
107 uhci_reg_write16 (controller, USBCMD, 0);
109 uhci_reg_write16 (controller, USBCMD, 2);
110 while ((uhci_reg_read16 (controller, USBCMD) & 2) != 0)
113 uhci_reg_write32 (controller, FLBASEADD,
114 (u32) virt_to_phys (UHCI_INST (controller)->
116 //debug ("framelist at %p\n",UHCI_INST(controller)->framelistptr);
119 uhci_reg_write16 (controller, USBINTR, 0);
121 /* reset framelist index */
122 uhci_reg_write16 (controller, FRNUM, 0);
124 uhci_reg_write16(controller, USBCMD,
125 uhci_reg_read16(controller, USBCMD) | 0xc0); // max packets, configure flag
127 uhci_start (controller);
131 uhci_init (pcidev_t addr)
136 hci_t *controller = new_controller ();
139 fatal("Could not create USB controller instance.\n");
141 controller->instance = malloc (sizeof (uhci_t));
142 if(!controller->instance)
143 fatal("Not enough memory creating USB controller instance.\n");
145 controller->start = uhci_start;
146 controller->stop = uhci_stop;
147 controller->reset = uhci_reset;
148 controller->shutdown = uhci_shutdown;
149 controller->bulk = uhci_bulk;
150 controller->control = uhci_control;
151 controller->create_intr_queue = uhci_create_intr_queue;
152 controller->destroy_intr_queue = uhci_destroy_intr_queue;
153 controller->poll_intr_queue = uhci_poll_intr_queue;
154 for (i = 0; i < 128; i++) {
155 controller->devices[i] = 0;
157 init_device_entry (controller, 0);
158 UHCI_INST (controller)->roothub = controller->devices[0];
160 controller->bus_address = addr;
161 controller->reg_base = pci_read_config32 (controller->bus_address, 0x20) & ~1; /* ~1 clears the register type indicator that is set to 1 for IO space */
163 /* kill legacy support handler */
164 uhci_stop (controller);
166 uhci_reg_write16 (controller, USBSTS, 0x3f);
167 reg16 = pci_read_config16(controller->bus_address, 0xc0);
169 pci_write_config16 (controller->bus_address, 0xc0, reg16);
171 UHCI_INST (controller)->framelistptr = memalign (0x1000, 1024 * sizeof (flistp_t *)); /* 4kb aligned to 4kb */
172 if (! UHCI_INST (controller)->framelistptr)
173 fatal("Not enough memory for USB frame list pointer.\n");
175 memset (UHCI_INST (controller)->framelistptr, 0,
176 1024 * sizeof (flistp_t));
178 /* According to the *BSD UHCI code, this one is needed on some
179 PIIX chips, because otherwise they misbehave. It must be
180 added to the last chain.
182 FIXME: this leaks, if the driver should ever be reinited
183 for some reason. Not a problem now.
185 td_t *antiberserk = memalign(16, sizeof(td_t));
187 fatal("Not enough memory for chipset workaround.\n");
188 memset(antiberserk, 0, sizeof(td_t));
190 UHCI_INST (controller)->qh_prei = memalign (16, sizeof (qh_t));
191 UHCI_INST (controller)->qh_intr = memalign (16, sizeof (qh_t));
192 UHCI_INST (controller)->qh_data = memalign (16, sizeof (qh_t));
193 UHCI_INST (controller)->qh_last = memalign (16, sizeof (qh_t));
195 if (! UHCI_INST (controller)->qh_prei ||
196 ! UHCI_INST (controller)->qh_intr ||
197 ! UHCI_INST (controller)->qh_data ||
198 ! UHCI_INST (controller)->qh_last)
199 fatal("Not enough memory for USB controller queues.\n");
201 UHCI_INST (controller)->qh_prei->headlinkptr =
202 virt_to_phys (UHCI_INST (controller)->qh_intr) | FLISTP_QH;
203 UHCI_INST (controller)->qh_prei->elementlinkptr = 0 | FLISTP_TERMINATE;
205 UHCI_INST (controller)->qh_intr->headlinkptr =
206 virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_QH;
207 UHCI_INST (controller)->qh_intr->elementlinkptr = 0 | FLISTP_TERMINATE;
209 UHCI_INST (controller)->qh_data->headlinkptr =
210 virt_to_phys (UHCI_INST (controller)->qh_last) | FLISTP_QH;
211 UHCI_INST (controller)->qh_data->elementlinkptr = 0 | FLISTP_TERMINATE;
213 UHCI_INST (controller)->qh_last->headlinkptr = virt_to_phys (UHCI_INST (controller)->qh_data) | FLISTP_TERMINATE;
214 UHCI_INST (controller)->qh_last->elementlinkptr = virt_to_phys (antiberserk) | FLISTP_TERMINATE;
216 for (i = 0; i < 1024; i++) {
217 UHCI_INST (controller)->framelistptr[i] =
218 virt_to_phys (UHCI_INST (controller)->qh_prei) | FLISTP_QH;
220 controller->devices[0]->controller = controller;
221 controller->devices[0]->init = uhci_rh_init;
222 controller->devices[0]->init (controller->devices[0]);
223 uhci_reset (controller);
228 uhci_shutdown (hci_t *controller)
232 detach_controller (controller);
233 UHCI_INST (controller)->roothub->destroy (UHCI_INST (controller)->
235 uhci_reg_write16(controller, USBCMD,
236 uhci_reg_read16(controller, USBCMD) & 0); // stop work
237 free (UHCI_INST (controller)->framelistptr);
238 free (UHCI_INST (controller)->qh_prei);
239 free (UHCI_INST (controller)->qh_intr);
240 free (UHCI_INST (controller)->qh_data);
241 free (UHCI_INST (controller)->qh_last);
242 free (UHCI_INST (controller));
247 uhci_start (hci_t *controller)
249 uhci_reg_write16(controller, USBCMD,
250 uhci_reg_read16(controller, USBCMD) | 1); // start work on schedule
254 uhci_stop (hci_t *controller)
256 uhci_reg_write16(controller, USBCMD,
257 uhci_reg_read16(controller, USBCMD) & ~1); // stop work on schedule
260 #define GET_TD(x) ((void*)(((unsigned int)(x))&~0xf))
263 wait_for_completed_qh (hci_t *controller, qh_t *qh)
265 int timeout = 1000000; /* max 30 ms. */
266 void *current = GET_TD (qh->elementlinkptr);
267 while (((qh->elementlinkptr & FLISTP_TERMINATE) == 0) && (timeout-- > 0)) {
268 if (current != GET_TD (qh->elementlinkptr)) {
269 current = GET_TD (qh->elementlinkptr);
272 uhci_reg_write16(controller, USBSTS,
273 uhci_reg_read16(controller, USBSTS) | 0); // clear resettable registers
276 return (GET_TD (qh->elementlinkptr) ==
277 0) ? 0 : GET_TD (phys_to_virt (qh->elementlinkptr));
283 return (size - 1) & 0x7ff;
296 uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen,
299 int endp = 0; /* this is control: always 0 */
300 int mlen = dev->endpoints[0].maxpacketsize;
301 int count = (2 + (dalen + mlen - 1) / mlen);
302 unsigned short req = ((unsigned short *) devreq)[0];
304 td_t *tds = memalign (16, sizeof (td_t) * count);
305 memset (tds, 0, sizeof (td_t) * count);
306 count--; /* to compensate for 0-indexed array */
307 for (i = 0; i < count; i++) {
308 tds[i].ptr = virt_to_phys (&tds[i + 1]) | TD_DEPTH_FIRST;
310 tds[count].ptr = 0 | TD_DEPTH_FIRST | TD_TERMINATE;
312 tds[0].token = UHCI_SETUP |
313 dev->address << TD_DEVADDR_SHIFT |
314 endp << TD_EP_SHIFT |
316 maxlen(drlen) << TD_MAXLEN_SHIFT;
317 tds[0].bufptr = virt_to_phys (devreq);
318 tds[0].ctrlsts = (3 << TD_COUNTER_SHIFT) |
319 (dev->speed?TD_LOWSPEED:0) |
323 for (i = 1; i < count; i++) {
325 case SETUP: tds[i].token = UHCI_SETUP; break;
326 case IN: tds[i].token = UHCI_IN; break;
327 case OUT: tds[i].token = UHCI_OUT; break;
329 tds[i].token |= dev->address << TD_DEVADDR_SHIFT |
330 endp << TD_EP_SHIFT |
331 maxlen (min (mlen, dalen)) << TD_MAXLEN_SHIFT |
332 toggle << TD_TOGGLE_SHIFT;
333 tds[i].bufptr = virt_to_phys (data);
334 tds[i].ctrlsts = (3 << TD_COUNTER_SHIFT) |
335 (dev->speed?TD_LOWSPEED:0) |
342 tds[count].token = (dir == OUT) ? UHCI_IN : UHCI_OUT |
343 dev->address << TD_DEVADDR_SHIFT |
344 endp << TD_EP_SHIFT |
345 maxlen(0) << TD_MAXLEN_SHIFT |
347 tds[count].bufptr = 0;
348 tds[0].ctrlsts = (0 << TD_COUNTER_SHIFT) | /* as Linux 2.4.10 does */
349 (dev->speed?TD_LOWSPEED:0) |
351 UHCI_INST (dev->controller)->qh_data->elementlinkptr =
352 virt_to_phys (tds) & ~(FLISTP_QH | FLISTP_TERMINATE);
353 td_t *td = wait_for_completed_qh (dev->controller,
354 UHCI_INST (dev->controller)->
360 debug ("control packet, req %x\n", req);
369 create_schedule (int numpackets)
373 td_t *tds = memalign (16, sizeof (td_t) * numpackets);
374 memset (tds, 0, sizeof (td_t) * numpackets);
376 for (i = 0; i < numpackets; i++) {
377 tds[i].ptr = virt_to_phys (&tds[i + 1]) | TD_DEPTH_FIRST;
379 tds[numpackets - 1].ptr = 0 | TD_TERMINATE;
384 fill_schedule (td_t *td, endpoint_t *ep, int length, unsigned char *data,
387 switch (ep->direction) {
388 case IN: td->token = UHCI_IN; break;
389 case OUT: td->token = UHCI_OUT; break;
390 case SETUP: td->token = UHCI_SETUP; break;
392 td->token |= ep->dev->address << TD_DEVADDR_SHIFT |
393 (ep->endpoint & 0xf) << TD_EP_SHIFT |
394 maxlen (length) << TD_MAXLEN_SHIFT |
395 (*toggle & 1) << TD_TOGGLE_SHIFT;
396 td->bufptr = virt_to_phys (data);
397 td->ctrlsts = ((ep->direction == SETUP?3:0) << TD_COUNTER_SHIFT) |
398 ep->dev->speed?TD_LOWSPEED:0 |
404 run_schedule (usbdev_t *dev, td_t *td)
406 UHCI_INST (dev->controller)->qh_data->elementlinkptr =
407 virt_to_phys (td) | ~(FLISTP_QH | FLISTP_TERMINATE);
408 td = wait_for_completed_qh (dev->controller,
409 UHCI_INST (dev->controller)->qh_data);
418 /* finalize == 1: if data is of packet aligned size, add a zero length packet */
420 uhci_bulk (endpoint_t *ep, int size, u8 *data, int finalize)
422 int maxpsize = ep->maxpacketsize;
424 fatal("MaxPacketSize == 0!!!");
425 int numpackets = (size + maxpsize - 1 + finalize) / maxpsize;
428 td_t *tds = create_schedule (numpackets);
429 int i = 0, toggle = ep->toggle;
430 while ((size > 0) || ((size == 0) && (finalize != 0))) {
431 fill_schedule (&tds[i], ep, min (size, maxpsize), data,
437 if (run_schedule (ep->dev, tds) == 1) {
438 debug("Stalled. Trying to clean up.\n");
458 /* create and hook-up an intr queue into device schedule */
460 uhci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming)
462 u8 *data = malloc(reqsize*reqcount);
463 td_t *tds = memalign(16, sizeof(td_t) * reqcount);
464 qh_t *qh = memalign(16, sizeof(qh_t));
466 if (!data || !tds || !qh)
467 fatal("Not enough memory to create USB intr queue prerequisites.\n");
469 qh->elementlinkptr = virt_to_phys(tds);
471 intr_q *q = malloc(sizeof(intr_q));
473 fatal("Not enough memory to create USB intr queue.\n");
479 q->reqsize = reqsize;
480 q->last_td = &tds[reqcount - 1];
482 memset (tds, 0, sizeof (td_t) * reqcount);
484 for (i = 0; i < reqcount; i++) {
485 tds[i].ptr = virt_to_phys (&tds[i + 1]);
487 switch (ep->direction) {
488 case IN: tds[i].token = UHCI_IN; break;
489 case OUT: tds[i].token = UHCI_OUT; break;
490 case SETUP: tds[i].token = UHCI_SETUP; break;
492 tds[i].token |= ep->dev->address << TD_DEVADDR_SHIFT |
493 (ep->endpoint & 0xf) << TD_EP_SHIFT |
494 maxlen (reqsize) << TD_MAXLEN_SHIFT |
495 (ep->toggle & 1) << TD_TOGGLE_SHIFT;
496 tds[i].bufptr = virt_to_phys (data);
497 tds[i].ctrlsts = (0 << TD_COUNTER_SHIFT) |
498 ep->dev->speed?TD_LOWSPEED:0 |
503 tds[reqcount - 1].ptr = 0 | TD_TERMINATE;
504 for (i = reqtiming; i < 1024; i += reqtiming) {
505 /* FIXME: wrap in another qh, one for each occurance of the qh in the framelist */
506 qh->headlinkptr = UHCI_INST (ep->dev->controller)->framelistptr[i] & ~FLISTP_TERMINATE;
507 UHCI_INST (ep->dev->controller)->framelistptr[i] = virt_to_phys(qh) | FLISTP_QH;
512 /* remove queue from device schedule, dropping all data that came in */
514 uhci_destroy_intr_queue (endpoint_t *ep, void *q_)
516 intr_q *q = (intr_q*)q_;
517 u32 val = virt_to_phys (q->qh);
518 u32 end = virt_to_phys (UHCI_INST (ep->dev->controller)->qh_intr);
520 for (i=0; i<1024; i++) {
522 u32 ptr = UHCI_INST (ep->dev->controller)->framelistptr[i];
524 if (((qh_t*)phys_to_virt(ptr))->elementlinkptr == val) {
525 ((qh_t*)phys_to_virt(oldptr))->headlinkptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr;
526 free(phys_to_virt(ptr));
530 ptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr;
539 /* read one intr-packet from queue, if available. extend the queue for new input.
540 return NULL if nothing new available.
541 Recommended use: while (data=poll_intr_queue(q)) process(data);
544 uhci_poll_intr_queue (void *q_)
546 intr_q *q = (intr_q*)q_;
547 if ((q->tds[q->lastread].ctrlsts & TD_STATUS_ACTIVE) == 0) {
548 /* FIXME: handle errors */
549 int current = q->lastread;
551 if (q->lastread == 0) {
552 previous = q->total - 1;
554 previous = q->lastread - 1;
556 q->tds[previous].ctrlsts &= ~TD_STATUS_MASK;
557 q->tds[previous].ptr = 0 | TD_TERMINATE;
558 if (q->last_td != &q->tds[previous]) {
559 q->last_td->ptr = virt_to_phys(&q->tds[previous]) & ~TD_TERMINATE;
560 q->last_td = &q->tds[previous];
562 q->tds[previous].ctrlsts |= TD_STATUS_ACTIVE;
563 q->lastread = (q->lastread + 1) % q->total;
564 return &q->data[current*q->reqsize];
570 uhci_reg_write32 (hci_t *ctrl, usbreg reg, u32 value)
572 outl (value, ctrl->reg_base + reg);
576 uhci_reg_read32 (hci_t *ctrl, usbreg reg)
578 return inl (ctrl->reg_base + reg);
582 uhci_reg_write16 (hci_t *ctrl, usbreg reg, u16 value)
584 outw (value, ctrl->reg_base + reg);
588 uhci_reg_read16 (hci_t *ctrl, usbreg reg)
590 return inw (ctrl->reg_base + reg);
594 uhci_reg_write8 (hci_t *ctrl, usbreg reg, u8 value)
596 outb (value, ctrl->reg_base + reg);
600 uhci_reg_read8 (hci_t *ctrl, usbreg reg)
602 return inb (ctrl->reg_base + reg);