2 * This file is part of the libpayload project.
4 * Copyright (C) 2008 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>
34 static void uhci_start (hci_t *controller);
35 static void uhci_stop (hci_t *controller);
36 static void uhci_reset (hci_t *controller);
37 static void uhci_shutdown (hci_t *controller);
38 static int uhci_packet (usbdev_t *dev, int endp, int pid, int toggle,
39 int length, u8 *data);
40 static int uhci_bulk (endpoint_t *ep, int size, u8 *data, int finalize);
41 static int uhci_control (usbdev_t *dev, pid_t dir, int drlen, void *devreq,
47 uhci_dump (hci_t *controller)
49 printf ("dump:\nUSBCMD: %x\n", uhci_reg_read16 (controller, USBCMD));
50 printf ("USBSTS: %x\n", uhci_reg_read16 (controller, USBSTS));
51 printf ("USBINTR: %x\n", uhci_reg_read16 (controller, USBINTR));
52 printf ("FRNUM: %x\n", uhci_reg_read16 (controller, FRNUM));
53 printf ("FLBASEADD: %x\n", uhci_reg_read32 (controller, FLBASEADD));
54 printf ("SOFMOD: %x\n", uhci_reg_read8 (controller, SOFMOD));
55 printf ("PORTSC1: %x\n", uhci_reg_read16 (controller, PORTSC1));
56 printf ("PORTSC2: %x\n", uhci_reg_read16 (controller, PORTSC2));
63 printf ("%x packet (at %lx) to %x.%x failed\n", td->pid,
64 virt_to_phys (td), td->dev_addr, td->endp);
65 printf ("td (counter at %x) returns: ", td->counter);
66 printf (" bitstuff err: %x, ", td->status_bitstuff_err);
67 printf (" CRC err: %x, ", td->status_crc_err);
68 printf (" NAK rcvd: %x, ", td->status_nakrcvd);
69 printf (" Babble: %x, ", td->status_babble);
70 printf (" Data Buffer err: %x, ", td->status_databuf_err);
71 printf (" Stalled: %x, ", td->status_stalled);
72 printf (" Active: %x\n", td->status_active);
73 if (td->status_babble)
74 printf (" Babble because of %s\n",
75 td->status_bitstuff_err ? "host" : "device");
76 if (td->status_active)
77 printf (" still active - timeout?\n");
81 uhci_reset (hci_t *controller)
84 uhci_reg_write16 (controller, USBCMD, 4);
86 uhci_reg_write16 (controller, USBCMD, 0);
88 uhci_reg_write16 (controller, USBCMD, 2);
89 while ((uhci_reg_read16 (controller, USBCMD) & 2) != 0)
92 uhci_reg_write32 (controller, FLBASEADD,
93 (u32) virt_to_phys (UHCI_INST (controller)->
95 //printf ("framelist at %p\n",UHCI_INST(controller)->framelistptr);
98 uhci_reg_write16 (controller, USBINTR, 0);
100 /* reset framelist index */
101 uhci_reg_write16 (controller, FRNUM, 0);
103 uhci_reg_mask16 (controller, USBCMD, ~0, 0xc0); // max packets, configure flag
105 uhci_start (controller);
109 uhci_init (pcidev_t addr)
112 hci_t *controller = new_controller ();
114 controller->instance = malloc (sizeof (uhci_t));
115 controller->start = uhci_start;
116 controller->stop = uhci_stop;
117 controller->reset = uhci_reset;
118 controller->shutdown = uhci_shutdown;
119 controller->packet = uhci_packet;
120 controller->bulk = uhci_bulk;
121 controller->control = uhci_control;
122 UHCI_INST (controller)->roothub = &(controller->devices[0]);
124 controller->bus_address = addr;
125 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 */
127 /* kill legacy support handler */
128 uhci_stop (controller);
130 uhci_reg_write16 (controller, USBSTS, 0x3f);
131 pci_write_config32 (controller->bus_address, 0xc0, 0x8f00);
133 UHCI_INST (controller)->framelistptr = memalign (0x1000, 1024 * sizeof (flistp_t *)); /* 4kb aligned to 4kb */
134 memset (UHCI_INST (controller)->framelistptr, 0,
135 1024 * sizeof (flistp_t));
137 UHCI_INST (controller)->qh_intr = memalign (16, sizeof (qh_t));
138 UHCI_INST (controller)->qh_data = memalign (16, sizeof (qh_t));
139 UHCI_INST (controller)->qh_last = memalign (16, sizeof (qh_t));
141 UHCI_INST (controller)->qh_intr->headlinkptr.ptr =
142 virt_to_phys (UHCI_INST (controller)->qh_data);
143 UHCI_INST (controller)->qh_intr->headlinkptr.queue_head = 1;
144 UHCI_INST (controller)->qh_intr->elementlinkptr.ptr = 0;
145 UHCI_INST (controller)->qh_intr->elementlinkptr.terminate = 1;
147 UHCI_INST (controller)->qh_data->headlinkptr.ptr =
148 virt_to_phys (UHCI_INST (controller)->qh_last);
149 UHCI_INST (controller)->qh_data->headlinkptr.queue_head = 1;
150 UHCI_INST (controller)->qh_data->elementlinkptr.ptr = 0;
151 UHCI_INST (controller)->qh_data->elementlinkptr.terminate = 1;
153 UHCI_INST (controller)->qh_last->headlinkptr.ptr = 0;
154 UHCI_INST (controller)->qh_last->headlinkptr.terminate = 1;
155 UHCI_INST (controller)->qh_last->elementlinkptr.ptr = 0;
156 UHCI_INST (controller)->qh_last->elementlinkptr.terminate = 1;
158 for (i = 0; i < 1024; i++) {
159 UHCI_INST (controller)->framelistptr[i].ptr =
160 virt_to_phys (UHCI_INST (controller)->qh_intr);
161 UHCI_INST (controller)->framelistptr[i].terminate = 0;
162 UHCI_INST (controller)->framelistptr[i].queue_head = 1;
164 for (i = 1; i < 128; i++) {
165 init_device_entry (controller, i);
167 controller->devices[0].controller = controller;
168 controller->devices[0].init = uhci_rh_init;
169 controller->devices[0].init (&controller->devices[0]);
170 uhci_reset (controller);
175 uhci_shutdown (hci_t *controller)
179 detach_controller (controller);
180 UHCI_INST (controller)->roothub->destroy (UHCI_INST (controller)->
182 uhci_reg_mask16 (controller, USBCMD, 0, 0); // stop work
183 free (UHCI_INST (controller)->framelistptr);
184 free (UHCI_INST (controller)->qh_intr);
185 free (UHCI_INST (controller)->qh_data);
186 free (UHCI_INST (controller)->qh_last);
187 free (UHCI_INST (controller));
192 uhci_start (hci_t *controller)
194 uhci_reg_mask16 (controller, USBCMD, ~0, 1); // start work on schedule
198 uhci_stop (hci_t *controller)
200 uhci_reg_mask16 (controller, USBCMD, ~1, 0); // stop work on schedule
203 #define GET_TD(x) ((void*)(((unsigned int)(x))&~0xf))
206 wait_for_completed_qh (hci_t *controller, qh_t *qh)
208 int timeout = 1000; /* max 30 ms. */
209 void *current = GET_TD (qh->elementlinkptr.ptr);
210 while ((qh->elementlinkptr.terminate == 0) && (timeout-- > 0)) {
211 if (current != GET_TD (qh->elementlinkptr.ptr)) {
212 current = GET_TD (qh->elementlinkptr.ptr);
215 uhci_reg_mask16 (controller, USBSTS, ~0, 0); // clear resettable registers
218 return (GET_TD (qh->elementlinkptr.ptr) ==
219 0) ? 0 : GET_TD (phys_to_virt (qh->elementlinkptr.ptr));
223 wait_for_completed_td (hci_t *controller, td_t *td)
226 while ((td->status_active == 1)
227 && ((uhci_reg_read16 (controller, USBSTS) & 2) == 0)
228 && (timeout-- > 0)) {
229 uhci_reg_mask16 (controller, USBSTS, ~0, 0); // clear resettable registers
237 return (size - 1) & 0x7ff;
250 uhci_control (usbdev_t *dev, pid_t dir, int drlen, void *devreq, int dalen,
253 int endp = 0; /* this is control: always 0 */
254 int mlen = dev->endpoints[0].maxpacketsize;
255 int count = (2 + (dalen + mlen - 1) / mlen);
256 unsigned short req = ((unsigned short *) devreq)[0];
258 td_t *tds = memalign (16, sizeof (td_t) * count);
259 memset (tds, 0, sizeof (td_t) * count);
260 count--; /* to compensate for 0-indexed array */
261 for (i = 0; i < count; i++) {
262 tds[i].ptr = virt_to_phys (&tds[i + 1]);
263 tds[i].depth_first = 1;
264 tds[i].terminate = 0;
267 tds[count].depth_first = 1;
268 tds[count].terminate = 1;
271 tds[0].dev_addr = dev->address;
273 tds[0].maxlen = maxlen (drlen);
275 tds[0].data_toggle = 0;
276 tds[0].lowspeed = dev->lowspeed;
277 tds[0].bufptr = virt_to_phys (devreq);
278 tds[0].status_active = 1;
281 for (i = 1; i < count; i++) {
283 tds[i].dev_addr = dev->address;
285 tds[i].maxlen = maxlen (min (mlen, dalen));
287 tds[i].data_toggle = toggle;
288 tds[i].lowspeed = dev->lowspeed;
289 tds[i].bufptr = virt_to_phys (data);
290 tds[i].status_active = 1;
296 tds[count].pid = (dir == OUT) ? IN : OUT;
297 tds[count].dev_addr = dev->address;
298 tds[count].endp = endp;
299 tds[count].maxlen = maxlen (0);
300 tds[count].counter = 0; /* as per linux 2.4.10 */
301 tds[count].data_toggle = 1;
302 tds[count].lowspeed = dev->lowspeed, tds[count].bufptr = 0;
303 tds[count].status_active = 1;
304 UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
306 UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
307 UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
308 td_t *td = wait_for_completed_qh (dev->controller,
309 UHCI_INST (dev->controller)->
315 printf ("control packet, req %x\n", req);
324 uhci_packet (usbdev_t *dev, int endp, int pid, int toggle, int length,
329 td = memalign (16, sizeof (td_t));
331 memset (td, 0, sizeof (td_t));
337 td->dev_addr = dev->address;
338 td->endp = endp & 0xf;
339 td->maxlen = maxlen (length);
344 td->data_toggle = toggle & 1;
345 td->lowspeed = dev->lowspeed;
346 td->bufptr = virt_to_phys (data);
348 td->status_active = 1;
350 UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
352 UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
353 UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
354 wait_for_completed_td (dev->controller, td);
355 if ((td->status & 0x7f) == 0) {
356 //printf("successfully sent a %x packet to %x.%x\n",pid, dev->address,endp);
366 create_schedule (int numpackets)
370 td_t *tds = memalign (16, sizeof (td_t) * numpackets);
371 memset (tds, 0, sizeof (td_t) * numpackets);
373 for (i = 0; i < numpackets; i++) {
374 tds[i].ptr = virt_to_phys (&tds[i + 1]);
375 tds[i].terminate = 0;
376 tds[i].queue_head = 0;
377 tds[i].depth_first = 1;
379 tds[numpackets - 1].ptr = 0;
380 tds[numpackets - 1].terminate = 1;
381 tds[numpackets - 1].queue_head = 0;
382 tds[numpackets - 1].depth_first = 0;
387 fill_schedule (td_t *td, endpoint_t *ep, int length, unsigned char *data,
390 td->pid = ep->direction;
391 td->dev_addr = ep->dev->address;
392 td->endp = ep->endpoint & 0xf;
393 td->maxlen = maxlen (length);
394 if (ep->direction == SETUP)
398 td->data_toggle = *toggle & 1;
399 td->lowspeed = ep->dev->lowspeed;
400 td->bufptr = virt_to_phys (data);
402 td->status_active = 1;
407 run_schedule (usbdev_t *dev, td_t *td)
409 UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
411 UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
412 UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
413 td = wait_for_completed_qh (dev->controller,
414 UHCI_INST (dev->controller)->qh_data);
423 /* finalize == 1: if data is of packet aligned size, add a zero length packet */
425 uhci_bulk (endpoint_t *ep, int size, u8 *data, int finalize)
427 int maxpsize = ep->maxpacketsize;
429 fatal ("MaxPacketSize == 0!!!");
430 int numpackets = (size + maxpsize - 1 + finalize) / maxpsize;
433 td_t *tds = create_schedule (numpackets);
434 int i = 0, toggle = ep->toggle;
435 while ((size > 0) || ((size == 0) && (finalize != 0))) {
436 fill_schedule (&tds[i], ep, min (size, maxpsize), data,
442 if (run_schedule (ep->dev, tds) == 1) {
453 uhci_reg_write32 (hci_t *ctrl, usbreg reg, u32 value)
455 outl (value, ctrl->reg_base + reg);
459 uhci_reg_read32 (hci_t *ctrl, usbreg reg)
461 return inl (ctrl->reg_base + reg);
465 uhci_reg_write16 (hci_t *ctrl, usbreg reg, u16 value)
467 outw (value, ctrl->reg_base + reg);
471 uhci_reg_read16 (hci_t *ctrl, usbreg reg)
473 return inw (ctrl->reg_base + reg);
477 uhci_reg_write8 (hci_t *ctrl, usbreg reg, u8 value)
479 outb (value, ctrl->reg_base + reg);
483 uhci_reg_read8 (hci_t *ctrl, usbreg reg)
485 return inb (ctrl->reg_base + reg);
489 uhci_reg_mask32 (hci_t *ctrl, usbreg reg, u32 andmask, u32 ormask)
491 uhci_reg_write32 (ctrl, reg,
492 (uhci_reg_read32 (ctrl, reg) & andmask) | ormask);
496 uhci_reg_mask16 (hci_t *ctrl, usbreg reg, u16 andmask, u16 ormask)
498 uhci_reg_write16 (ctrl, reg,
499 (uhci_reg_read16 (ctrl, reg) & andmask) | ormask);
503 uhci_reg_mask8 (hci_t *ctrl, usbreg reg, u8 andmask, u8 ormask)
505 uhci_reg_write8 (ctrl, reg,
506 (uhci_reg_read8 (ctrl, reg) & andmask) | ormask);