2 * This file is part of the libpayload project.
4 * Copyright (C) 2010 Patrick Georgi
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 #include "ohci_private.h"
37 static void ohci_start (hci_t *controller);
38 static void ohci_stop (hci_t *controller);
39 static void ohci_reset (hci_t *controller);
40 static void ohci_shutdown (hci_t *controller);
41 static int ohci_bulk (endpoint_t *ep, int size, u8 *data, int finalize);
42 static int ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq,
44 static void* ohci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming);
45 static void ohci_destroy_intr_queue (endpoint_t *ep, void *queue);
46 static u8* ohci_poll_intr_queue (void *queue);
49 ohci_reset (hci_t *controller)
55 static const char *completion_codes[] = {
59 "Data toggle mismatch",
61 "Device not responding",
75 static const char *direction[] = {
84 ohci_init (pcidev_t addr)
88 hci_t *controller = new_controller ();
91 fatal("Could not create USB controller instance.\n");
93 controller->instance = malloc (sizeof (ohci_t));
94 if(!controller->instance)
95 fatal("Not enough memory creating USB controller instance.\n");
97 controller->start = ohci_start;
98 controller->stop = ohci_stop;
99 controller->reset = ohci_reset;
100 controller->shutdown = ohci_shutdown;
101 controller->bulk = ohci_bulk;
102 controller->control = ohci_control;
103 controller->create_intr_queue = ohci_create_intr_queue;
104 controller->destroy_intr_queue = ohci_destroy_intr_queue;
105 controller->poll_intr_queue = ohci_poll_intr_queue;
106 for (i = 0; i < 128; i++) {
107 controller->devices[i] = 0;
109 init_device_entry (controller, 0);
110 OHCI_INST (controller)->roothub = controller->devices[0];
112 controller->bus_address = addr;
113 controller->reg_base = pci_read_config32 (controller->bus_address, 0x10); // OHCI mandates MMIO, so bit 0 is clear
114 OHCI_INST (controller)->opreg = (opreg_t*)phys_to_virt(controller->reg_base);
115 printf("OHCI Version %x.%x\n", (OHCI_INST (controller)->opreg->HcRevision >> 4) & 0xf, OHCI_INST (controller)->opreg->HcRevision & 0xf);
117 if ((OHCI_INST (controller)->opreg->HcControl & HostControllerFunctionalStateMask) == USBReset) {
119 OHCI_INST (controller)->opreg->HcControl &= ~RemoteWakeupConnected;
120 OHCI_INST (controller)->opreg->HcFmInterval = (11999 * FrameInterval) | ((((11999 - 210)*6)/7) * FSLargestDataPacket);
121 /* TODO: right value for PowerOnToPowerGoodTime ? */
122 OHCI_INST (controller)->opreg->HcRhDescriptorA = NoPowerSwitching | NoOverCurrentProtection | (10 * PowerOnToPowerGoodTime);
123 OHCI_INST (controller)->opreg->HcRhDescriptorB = (0 * DeviceRemovable);
124 udelay(100); /* TODO: reset asserting according to USB spec */
125 } else if ((OHCI_INST (controller)->opreg->HcControl & HostControllerFunctionalStateMask) != USBOperational) {
126 OHCI_INST (controller)->opreg->HcControl = (OHCI_INST (controller)->opreg->HcControl & ~HostControllerFunctionalStateMask) | USBResume;
127 udelay(100); /* TODO: resume time according to USB spec */
129 int interval = OHCI_INST (controller)->opreg->HcFmInterval;
131 td_t *periodic_td = memalign(sizeof(*periodic_td), sizeof(*periodic_td));
132 memset((void*)periodic_td, 0, sizeof(*periodic_td));
133 for (i=0; i<32; i++) OHCI_INST (controller)->hcca->HccaInterruptTable[i] = virt_to_phys(periodic_td);
134 /* TODO: build HCCA data structures */
136 OHCI_INST (controller)->opreg->HcCommandStatus = HostControllerReset;
137 udelay (10); /* at most 10us for reset to complete. State must be set to Operational within 2ms (5.1.1.4) */
138 OHCI_INST (controller)->opreg->HcFmInterval = interval;
139 OHCI_INST (controller)->hcca = memalign(256, 256);
140 memset((void*)OHCI_INST (controller)->hcca, 0, 256);
142 OHCI_INST (controller)->opreg->HcHCCA = virt_to_phys(OHCI_INST (controller)->hcca);
143 OHCI_INST (controller)->opreg->HcControl &= ~IsochronousEnable; // unused by this driver
144 // disable everything, contrary to what OHCI spec says in 5.1.1.4, as we don't need IRQs
145 OHCI_INST (controller)->opreg->HcInterruptEnable = 1<<31;
146 OHCI_INST (controller)->opreg->HcInterruptDisable = ~(1<<31);
147 OHCI_INST (controller)->opreg->HcInterruptStatus = ~0;
148 OHCI_INST (controller)->opreg->HcPeriodicStart = (((OHCI_INST (controller)->opreg->HcFmInterval & FrameIntervalMask) / 10) * 9);
149 OHCI_INST (controller)->opreg->HcControl = (OHCI_INST (controller)->opreg->HcControl & ~HostControllerFunctionalStateMask) | USBOperational;
153 controller->devices[0]->controller = controller;
154 controller->devices[0]->init = ohci_rh_init;
155 controller->devices[0]->init (controller->devices[0]);
156 ohci_reset (controller);
161 ohci_shutdown (hci_t *controller)
165 detach_controller (controller);
166 ohci_stop(controller);
167 OHCI_INST (controller)->roothub->destroy (OHCI_INST (controller)->
169 free (OHCI_INST (controller));
174 ohci_start (hci_t *controller)
176 // TODO: turn on all operation of OHCI, but assume that it's initialized.
180 ohci_stop (hci_t *controller)
182 // TODO: turn off all operation of OHCI
186 dump_td(td_t *cur, int level)
189 static const char *spaces=" ";
190 const char *spc=spaces+(10-level);
191 debug("%std at %x (%s), condition code: %s\n", spc, cur, direction[(cur->config & TD_DIRECTION_MASK) >> TD_DIRECTION_SHIFT],
192 completion_codes[(cur->config & TD_CC_MASK) >> TD_CC_SHIFT]);
193 debug("%s toggle: %x\n", spc, !!(cur->config & TD_TOGGLE_DATA1));
198 wait_for_ed(usbdev_t *dev, ed_t *head)
202 /* wait for results */
203 while (((head->head_pointer & ~3) != head->tail_pointer) &&
204 !(head->head_pointer & 1) &&
205 ((((td_t*)phys_to_virt(head->head_pointer & ~3))->config & TD_CC_MASK) >= TD_CC_NOACCESS)) {
206 debug("intst: %x; ctrl: %x; cmdst: %x; head: %x -> %x, tail: %x, condition: %x\n",
207 OHCI_INST(dev->controller)->opreg->HcInterruptStatus,
208 OHCI_INST(dev->controller)->opreg->HcControl,
209 OHCI_INST(dev->controller)->opreg->HcCommandStatus,
211 ((td_t*)phys_to_virt(head->head_pointer & ~3))->next_td,
213 (((td_t*)phys_to_virt(head->head_pointer & ~3))->config & TD_CC_MASK) >> TD_CC_SHIFT);
217 if (OHCI_INST(dev->controller)->opreg->HcInterruptStatus & WritebackDoneHead) {
218 debug("done queue:\n");
219 debug("%x, %x\n", OHCI_INST(dev->controller)->hcca->HccaDoneHead, phys_to_virt(OHCI_INST(dev->controller)->hcca->HccaDoneHead));
220 if ((OHCI_INST(dev->controller)->hcca->HccaDoneHead & ~1) == 0) {
221 debug("HcInterruptStatus %x\n", OHCI_INST(dev->controller)->opreg->HcInterruptStatus);
223 td_t *done_queue = NULL;
224 td_t *done_head = (td_t*)phys_to_virt(OHCI_INST(dev->controller)->hcca->HccaDoneHead);
226 td_t *oldnext = (td_t*)phys_to_virt(done_head->next_td);
227 if (oldnext == done_queue) break; /* last element refers to second to last, ie. endless loop */
228 if (oldnext == phys_to_virt(0)) break; /* last element of done list == first element of real list */
229 debug("head is %x, pointing to %x. requeueing to %x\n", done_head, oldnext, done_queue);
230 done_head->next_td = (u32)done_queue;
231 done_queue = done_head;
234 for (cur = done_queue; cur != 0; cur = (td_t*)cur->next_td) {
237 OHCI_INST(dev->controller)->opreg->HcInterruptStatus &= ~WritebackDoneHead;
240 if (head->head_pointer & 1) {
248 ohci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen,
255 // pages are specified as 4K in OHCI, so don't use getpagesize()
256 int first_page = (unsigned long)data / 4096;
257 int last_page = (unsigned long)(data+dalen-1)/4096;
258 if (last_page < first_page) last_page = first_page;
259 int pages = (dalen==0)?0:(last_page - first_page + 1);
260 int td_count = (pages+1)/2;
262 td_t *tds = memalign(sizeof(td_t), (td_count+3)*sizeof(td_t));
263 memset((void*)tds, 0, (td_count+3)*sizeof(td_t));
265 for (i=0; i < td_count + 3; i++) {
266 tds[i].next_td = virt_to_phys(&tds[i+1]);
268 tds[td_count + 3].next_td = 0;
270 tds[0].config = TD_DIRECTION_SETUP |
271 TD_DELAY_INTERRUPT_NODELAY |
275 tds[0].current_buffer_pointer = virt_to_phys(devreq);
276 tds[0].buffer_end = virt_to_phys(devreq + drlen - 1);
282 cur->config = (dir==IN)?TD_DIRECTION_IN:TD_DIRECTION_OUT |
283 TD_DELAY_INTERRUPT_NODELAY |
286 cur->current_buffer_pointer = virt_to_phys(data);
288 int consumed = (4096 - ((unsigned long)data % 4096));
289 if (consumed >= dalen) {
290 // end of data is within same page
291 cur->buffer_end = virt_to_phys(data + dalen - 1);
293 /* assert(pages == 0); */
298 int second_page_size = dalen;
300 second_page_size = 4096;
302 cur->buffer_end = virt_to_phys(data + second_page_size - 1);
303 dalen -= second_page_size;
304 data += second_page_size;
309 cur->config = (dir==IN)?TD_DIRECTION_OUT:TD_DIRECTION_IN |
310 TD_DELAY_INTERRUPT_NODELAY |
314 cur->current_buffer_pointer = 0;
320 /* Data structures */
321 ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t));
322 memset((void*)head, 0, sizeof(*head));
323 head->config = (dev->address << ED_FUNC_SHIFT) |
325 (OHCI_FROM_TD << ED_DIR_SHIFT) |
326 (dev->speed?ED_LOWSPEED:0) |
327 (dev->endpoints[0].maxpacketsize << ED_MPS_SHIFT);
328 head->tail_pointer = virt_to_phys(cur);
329 head->head_pointer = virt_to_phys(tds);
331 debug("doing control transfer with %x. first_td at %x\n", head->config & ED_FUNC_MASK, virt_to_phys(tds));
333 /* activate schedule */
334 OHCI_INST(dev->controller)->opreg->HcControlHeadED = virt_to_phys(head);
335 OHCI_INST(dev->controller)->opreg->HcControl |= ControlListEnable;
336 OHCI_INST(dev->controller)->opreg->HcCommandStatus = ControlListFilled;
338 int failure = wait_for_ed(dev, head);
339 OHCI_INST(dev->controller)->opreg->HcControl &= ~ControlListEnable;
348 /* finalize == 1: if data is of packet aligned size, add a zero length packet */
350 ohci_bulk (endpoint_t *ep, int dalen, u8 *data, int finalize)
353 debug("bulk: %x bytes from %x, finalize: %x, maxpacketsize: %x\n", dalen, data, finalize, ep->maxpacketsize);
357 // pages are specified as 4K in OHCI, so don't use getpagesize()
358 int first_page = (unsigned long)data / 4096;
359 int last_page = (unsigned long)(data+dalen-1)/4096;
360 if (last_page < first_page) last_page = first_page;
361 int pages = (dalen==0)?0:(last_page - first_page + 1);
362 int td_count = (pages+1)/2;
364 if (finalize && ((dalen % ep->maxpacketsize) == 0)) {
368 td_t *tds = memalign(sizeof(td_t), (td_count+1)*sizeof(td_t));
369 memset((void*)tds, 0, (td_count+1)*sizeof(td_t));
371 for (i=0; i < td_count; i++) {
372 tds[i].next_td = virt_to_phys(&tds[i+1]);
375 for (cur = tds; cur->next_td != 0; cur++) {
376 cur->config = (ep->direction==IN)?TD_DIRECTION_IN:TD_DIRECTION_OUT |
377 TD_DELAY_INTERRUPT_NODELAY |
380 cur->current_buffer_pointer = virt_to_phys(data);
383 /* magic TD for empty packet transfer */
384 cur->current_buffer_pointer = 0;
386 /* assert((pages == 0) && finalize); */
388 int consumed = (4096 - ((unsigned long)data % 4096));
389 if (consumed >= dalen) {
390 // end of data is within same page
391 cur->buffer_end = virt_to_phys(data + dalen - 1);
393 /* assert(pages == finalize); */
398 int second_page_size = dalen;
400 second_page_size = 4096;
402 cur->buffer_end = virt_to_phys(data + second_page_size - 1);
403 dalen -= second_page_size;
404 data += second_page_size;
408 /* Data structures */
409 ed_t *head = memalign(sizeof(ed_t), sizeof(ed_t));
410 memset((void*)head, 0, sizeof(*head));
411 head->config = (ep->dev->address << ED_FUNC_SHIFT) |
412 ((ep->endpoint & 0xf) << ED_EP_SHIFT) |
413 (((ep->direction==IN)?OHCI_IN:OHCI_OUT) << ED_DIR_SHIFT) |
414 (ep->dev->speed?ED_LOWSPEED:0) |
415 (ep->maxpacketsize << ED_MPS_SHIFT);
416 head->tail_pointer = virt_to_phys(cur);
417 head->head_pointer = virt_to_phys(tds) | (ep->toggle?ED_TOGGLE:0);
419 debug("doing bulk transfer with %x(%x). first_td at %x, last %x\n", head->config & ED_FUNC_MASK,
420 (head->config & ED_EP_MASK) >> ED_EP_SHIFT, virt_to_phys(tds), virt_to_phys(cur));
422 /* activate schedule */
423 OHCI_INST(ep->dev->controller)->opreg->HcBulkHeadED = virt_to_phys(head);
424 OHCI_INST(ep->dev->controller)->opreg->HcControl |= BulkListEnable;
425 OHCI_INST(ep->dev->controller)->opreg->HcCommandStatus = BulkListFilled;
427 int failure = wait_for_ed(ep->dev, head);
428 OHCI_INST(ep->dev->controller)->opreg->HcControl &= ~BulkListEnable;
430 ep->toggle = head->head_pointer & ED_TOGGLE;
444 /* create and hook-up an intr queue into device schedule */
446 ohci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming)
451 /* remove queue from device schedule, dropping all data that came in */
453 ohci_destroy_intr_queue (endpoint_t *ep, void *q_)
457 /* read one intr-packet from queue, if available. extend the queue for new input.
458 return NULL if nothing new available.
459 Recommended use: while (data=poll_intr_queue(q)) process(data);
462 ohci_poll_intr_queue (void *q_)