tizen 2.3.1 release
[external/qemu.git] / roms / seabios / src / usb-uhci.c
1 // Code for handling UHCI USB controllers.
2 //
3 // Copyright (C) 2009  Kevin O'Connor <kevin@koconnor.net>
4 //
5 // This file may be distributed under the terms of the GNU LGPLv3 license.
6
7 #include "util.h" // dprintf
8 #include "pci.h" // pci_bdf_to_bus
9 #include "config.h" // CONFIG_*
10 #include "ioport.h" // outw
11 #include "usb-uhci.h" // USBLEGSUP
12 #include "pci_regs.h" // PCI_BASE_ADDRESS_4
13 #include "usb.h" // struct usb_s
14 #include "biosvar.h" // GET_LOWFLAT
15
16 struct usb_uhci_s {
17     struct usb_s usb;
18     u16 iobase;
19     struct uhci_qh *control_qh;
20     struct uhci_framelist *framelist;
21 };
22
23 struct uhci_pipe {
24     struct uhci_qh qh;
25     struct uhci_td *next_td;
26     struct usb_pipe pipe;
27     u16 iobase;
28     u8 toggle;
29 };
30
31
32 /****************************************************************
33  * Root hub
34  ****************************************************************/
35
36 // Check if device attached to a given port
37 static int
38 uhci_hub_detect(struct usbhub_s *hub, u32 port)
39 {
40     struct usb_uhci_s *cntl = container_of(hub->cntl, struct usb_uhci_s, usb);
41     u16 ioport = cntl->iobase + USBPORTSC1 + port * 2;
42
43     u16 status = inw(ioport);
44     if (!(status & USBPORTSC_CCS))
45         // No device
46         return -1;
47
48     // XXX - if just powered up, need to wait for USB_TIME_ATTDB?
49
50     // Begin reset on port
51     outw(USBPORTSC_PR, ioport);
52     msleep(USB_TIME_DRSTR);
53     return 0;
54 }
55
56 // Reset device on port
57 static int
58 uhci_hub_reset(struct usbhub_s *hub, u32 port)
59 {
60     struct usb_uhci_s *cntl = container_of(hub->cntl, struct usb_uhci_s, usb);
61     u16 ioport = cntl->iobase + USBPORTSC1 + port * 2;
62
63     // Finish reset on port
64     outw(0, ioport);
65     udelay(6); // 64 high-speed bit times
66     u16 status = inw(ioport);
67     if (!(status & USBPORTSC_CCS))
68         // No longer connected
69         return -1;
70     outw(USBPORTSC_PE, ioport);
71     return !!(status & USBPORTSC_LSDA);
72 }
73
74 // Disable port
75 static void
76 uhci_hub_disconnect(struct usbhub_s *hub, u32 port)
77 {
78     struct usb_uhci_s *cntl = container_of(hub->cntl, struct usb_uhci_s, usb);
79     u16 ioport = cntl->iobase + USBPORTSC1 + port * 2;
80     outw(0, ioport);
81 }
82
83 static struct usbhub_op_s uhci_HubOp = {
84     .detect = uhci_hub_detect,
85     .reset = uhci_hub_reset,
86     .disconnect = uhci_hub_disconnect,
87 };
88
89 // Find any devices connected to the root hub.
90 static int
91 check_uhci_ports(struct usb_uhci_s *cntl)
92 {
93     ASSERT32FLAT();
94     struct usbhub_s hub;
95     memset(&hub, 0, sizeof(hub));
96     hub.cntl = &cntl->usb;
97     hub.portcount = 2;
98     hub.op = &uhci_HubOp;
99     usb_enumerate(&hub);
100     return hub.devcount;
101 }
102
103
104 /****************************************************************
105  * Setup
106  ****************************************************************/
107
108 // Wait for next USB frame to start - for ensuring safe memory release.
109 static void
110 uhci_waittick(u16 iobase)
111 {
112     barrier();
113     u16 startframe = inw(iobase + USBFRNUM);
114     u64 end = calc_future_tsc(1000 * 5);
115     for (;;) {
116         if (inw(iobase + USBFRNUM) != startframe)
117             break;
118         if (check_tsc(end)) {
119             warn_timeout();
120             return;
121         }
122         yield();
123     }
124 }
125
126 static void
127 uhci_free_pipes(struct usb_uhci_s *cntl)
128 {
129     dprintf(7, "uhci_free_pipes %p\n", cntl);
130
131     struct uhci_qh *pos = (void*)(cntl->framelist->links[0] & ~UHCI_PTR_BITS);
132     for (;;) {
133         u32 link = pos->link;
134         if (link == UHCI_PTR_TERM)
135             break;
136         struct uhci_qh *next = (void*)(link & ~UHCI_PTR_BITS);
137         struct uhci_pipe *pipe = container_of(next, struct uhci_pipe, qh);
138         if (pipe->pipe.cntl != &cntl->usb)
139             pos->link = next->link;
140         else
141             pos = next;
142     }
143     uhci_waittick(cntl->iobase);
144     for (;;) {
145         struct usb_pipe *usbpipe = cntl->usb.freelist;
146         if (!usbpipe)
147             break;
148         cntl->usb.freelist = usbpipe->freenext;
149         struct uhci_pipe *pipe = container_of(usbpipe, struct uhci_pipe, pipe);
150         free(pipe);
151     }
152 }
153
154 static void
155 reset_uhci(struct usb_uhci_s *cntl, u16 bdf)
156 {
157     // XXX - don't reset if not needed.
158
159     // Reset PIRQ and SMI
160     pci_config_writew(bdf, USBLEGSUP, USBLEGSUP_RWC);
161
162     // Reset the HC
163     outw(USBCMD_HCRESET, cntl->iobase + USBCMD);
164     udelay(5);
165
166     // Disable interrupts and commands (just to be safe).
167     outw(0, cntl->iobase + USBINTR);
168     outw(0, cntl->iobase + USBCMD);
169 }
170
171 static void
172 configure_uhci(void *data)
173 {
174     struct usb_uhci_s *cntl = data;
175
176     // Allocate ram for schedule storage
177     struct uhci_td *term_td = malloc_high(sizeof(*term_td));
178     struct uhci_framelist *fl = memalign_high(sizeof(*fl), sizeof(*fl));
179     struct uhci_pipe *intr_pipe = malloc_high(sizeof(*intr_pipe));
180     struct uhci_pipe *term_pipe = malloc_high(sizeof(*term_pipe));
181     if (!term_td || !fl || !intr_pipe || !term_pipe) {
182         warn_noalloc();
183         goto fail;
184     }
185
186     // Work around for PIIX errata
187     memset(term_td, 0, sizeof(*term_td));
188     term_td->link = UHCI_PTR_TERM;
189     term_td->token = (uhci_explen(0) | (0x7f << TD_TOKEN_DEVADDR_SHIFT)
190                       | USB_PID_IN);
191     memset(term_pipe, 0, sizeof(*term_pipe));
192     term_pipe->qh.element = (u32)term_td;
193     term_pipe->qh.link = UHCI_PTR_TERM;
194     term_pipe->pipe.cntl = &cntl->usb;
195
196     // Set schedule to point to primary intr queue head
197     memset(intr_pipe, 0, sizeof(*intr_pipe));
198     intr_pipe->qh.element = UHCI_PTR_TERM;
199     intr_pipe->qh.link = (u32)&term_pipe->qh | UHCI_PTR_QH;
200     intr_pipe->pipe.cntl = &cntl->usb;
201     int i;
202     for (i=0; i<ARRAY_SIZE(fl->links); i++)
203         fl->links[i] = (u32)&intr_pipe->qh | UHCI_PTR_QH;
204     cntl->framelist = fl;
205     cntl->control_qh = &intr_pipe->qh;
206     barrier();
207
208     // Set the frame length to the default: 1 ms exactly
209     outb(USBSOF_DEFAULT, cntl->iobase + USBSOF);
210
211     // Store the frame list base address
212     outl((u32)fl->links, cntl->iobase + USBFLBASEADD);
213
214     // Set the current frame number
215     outw(0, cntl->iobase + USBFRNUM);
216
217     // Mark as configured and running with a 64-byte max packet.
218     outw(USBCMD_RS | USBCMD_CF | USBCMD_MAXP, cntl->iobase + USBCMD);
219
220     // Find devices
221     int count = check_uhci_ports(cntl);
222     uhci_free_pipes(cntl);
223     if (count)
224         // Success
225         return;
226
227     // No devices found - shutdown and free controller.
228     outw(0, cntl->iobase + USBCMD);
229 fail:
230     free(term_td);
231     free(fl);
232     free(intr_pipe);
233     free(term_pipe);
234     free(cntl);
235 }
236
237 void
238 uhci_init(struct pci_device *pci, int busid)
239 {
240     if (! CONFIG_USB_UHCI)
241         return;
242     u16 bdf = pci->bdf;
243     struct usb_uhci_s *cntl = malloc_tmphigh(sizeof(*cntl));
244     if (!cntl) {
245         warn_noalloc();
246         return;
247     }
248     memset(cntl, 0, sizeof(*cntl));
249     cntl->usb.busid = busid;
250     cntl->usb.pci = pci;
251     cntl->usb.type = USB_TYPE_UHCI;
252     cntl->iobase = (pci_config_readl(bdf, PCI_BASE_ADDRESS_4)
253                     & PCI_BASE_ADDRESS_IO_MASK);
254
255     dprintf(1, "UHCI init on dev %02x:%02x.%x (io=%x)\n"
256             , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)
257             , pci_bdf_to_fn(bdf), cntl->iobase);
258
259     pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
260
261     reset_uhci(cntl, bdf);
262
263     run_thread(configure_uhci, cntl);
264 }
265
266
267 /****************************************************************
268  * End point communication
269  ****************************************************************/
270
271 static struct usb_pipe *
272 uhci_alloc_intr_pipe(struct usbdevice_s *usbdev
273                      , struct usb_endpoint_descriptor *epdesc)
274 {
275     struct usb_uhci_s *cntl = container_of(
276         usbdev->hub->cntl, struct usb_uhci_s, usb);
277     int frameexp = usb_getFrameExp(usbdev, epdesc);
278     dprintf(7, "uhci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
279
280     if (frameexp > 10)
281         frameexp = 10;
282     int maxpacket = epdesc->wMaxPacketSize;
283     // Determine number of entries needed for 2 timer ticks.
284     int ms = 1<<frameexp;
285     int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
286     count = ALIGN(count, 2);
287     struct uhci_pipe *pipe = malloc_low(sizeof(*pipe));
288     struct uhci_td *tds = malloc_low(sizeof(*tds) * count);
289     void *data = malloc_low(maxpacket * count);
290     if (!pipe || !tds || !data) {
291         warn_noalloc();
292         goto fail;
293     }
294     memset(pipe, 0, sizeof(*pipe));
295     usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
296     int lowspeed = pipe->pipe.speed;
297     int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
298     pipe->qh.element = (u32)tds;
299     pipe->next_td = &tds[0];
300     pipe->iobase = cntl->iobase;
301
302     int toggle = 0;
303     int i;
304     for (i=0; i<count; i++) {
305         tds[i].link = (i==count-1 ? (u32)&tds[0] : (u32)&tds[i+1]);
306         tds[i].status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0)
307                          | TD_CTRL_ACTIVE);
308         tds[i].token = (uhci_explen(maxpacket) | toggle
309                         | (devaddr << TD_TOKEN_DEVADDR_SHIFT)
310                         | USB_PID_IN);
311         tds[i].buffer = data + maxpacket * i;
312         toggle ^= TD_TOKEN_TOGGLE;
313     }
314
315     // Add to interrupt schedule.
316     struct uhci_framelist *fl = cntl->framelist;
317     if (frameexp == 0) {
318         // Add to existing interrupt entry.
319         struct uhci_qh *intr_qh = (void*)(fl->links[0] & ~UHCI_PTR_BITS);
320         pipe->qh.link = intr_qh->link;
321         barrier();
322         intr_qh->link = (u32)&pipe->qh | UHCI_PTR_QH;
323         if (cntl->control_qh == intr_qh)
324             cntl->control_qh = &pipe->qh;
325     } else {
326         int startpos = 1<<(frameexp-1);
327         pipe->qh.link = fl->links[startpos];
328         barrier();
329         for (i=startpos; i<ARRAY_SIZE(fl->links); i+=ms)
330             fl->links[i] = (u32)&pipe->qh | UHCI_PTR_QH;
331     }
332
333     return &pipe->pipe;
334 fail:
335     free(pipe);
336     free(tds);
337     free(data);
338     return NULL;
339 }
340
341 struct usb_pipe *
342 uhci_alloc_pipe(struct usbdevice_s *usbdev
343                 , struct usb_endpoint_descriptor *epdesc)
344 {
345     if (! CONFIG_USB_UHCI)
346         return NULL;
347     u8 eptype = epdesc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK;
348     if (eptype == USB_ENDPOINT_XFER_INT)
349         return uhci_alloc_intr_pipe(usbdev, epdesc);
350     struct usb_uhci_s *cntl = container_of(
351         usbdev->hub->cntl, struct usb_uhci_s, usb);
352     dprintf(7, "uhci_alloc_async_pipe %p %d\n", &cntl->usb, eptype);
353
354     struct usb_pipe *usbpipe = usb_getFreePipe(&cntl->usb, eptype);
355     if (usbpipe) {
356         // Use previously allocated pipe.
357         usb_desc2pipe(usbpipe, usbdev, epdesc);
358         return usbpipe;
359     }
360
361     // Allocate a new queue head.
362     struct uhci_pipe *pipe;
363     if (eptype == USB_ENDPOINT_XFER_CONTROL)
364         pipe = malloc_tmphigh(sizeof(*pipe));
365     else
366         pipe = malloc_low(sizeof(*pipe));
367     if (!pipe) {
368         warn_noalloc();
369         return NULL;
370     }
371     memset(pipe, 0, sizeof(*pipe));
372     usb_desc2pipe(&pipe->pipe, usbdev, epdesc);
373     pipe->qh.element = UHCI_PTR_TERM;
374     pipe->iobase = cntl->iobase;
375
376     // Add queue head to controller list.
377     struct uhci_qh *control_qh = cntl->control_qh;
378     pipe->qh.link = control_qh->link;
379     barrier();
380     control_qh->link = (u32)&pipe->qh | UHCI_PTR_QH;
381     if (eptype == USB_ENDPOINT_XFER_CONTROL)
382         cntl->control_qh = &pipe->qh;
383     return &pipe->pipe;
384 }
385
386 static int
387 wait_pipe(struct uhci_pipe *pipe, int timeout)
388 {
389     u64 end = calc_future_tsc(timeout);
390     for (;;) {
391         u32 el_link = GET_LOWFLAT(pipe->qh.element);
392         if (el_link & UHCI_PTR_TERM)
393             return 0;
394         if (check_tsc(end)) {
395             warn_timeout();
396             u16 iobase = GET_LOWFLAT(pipe->iobase);
397             struct uhci_td *td = (void*)(el_link & ~UHCI_PTR_BITS);
398             dprintf(1, "Timeout on wait_pipe %p (td=%p s=%x c=%x/%x)\n"
399                     , pipe, (void*)el_link, GET_LOWFLAT(td->status)
400                     , inw(iobase + USBCMD)
401                     , inw(iobase + USBSTS));
402             SET_LOWFLAT(pipe->qh.element, UHCI_PTR_TERM);
403             uhci_waittick(iobase);
404             return -1;
405         }
406         yield();
407     }
408 }
409
410 static int
411 wait_td(struct uhci_td *td)
412 {
413     u64 end = calc_future_tsc(5000); // XXX - lookup real time.
414     u32 status;
415     for (;;) {
416         status = td->status;
417         if (!(status & TD_CTRL_ACTIVE))
418             break;
419         if (check_tsc(end)) {
420             warn_timeout();
421             return -1;
422         }
423         yield();
424     }
425     if (status & TD_CTRL_ANY_ERROR) {
426         dprintf(1, "wait_td error - status=%x\n", status);
427         return -2;
428     }
429     return 0;
430 }
431
432 int
433 uhci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
434              , void *data, int datasize)
435 {
436     ASSERT32FLAT();
437     if (! CONFIG_USB_UHCI)
438         return -1;
439     dprintf(5, "uhci_control %p\n", p);
440     struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe);
441
442     int maxpacket = pipe->pipe.maxpacket;
443     int lowspeed = pipe->pipe.speed;
444     int devaddr = pipe->pipe.devaddr | (pipe->pipe.ep << 7);
445
446     // Setup transfer descriptors
447     int count = 2 + DIV_ROUND_UP(datasize, maxpacket);
448     struct uhci_td *tds = malloc_tmphigh(sizeof(*tds) * count);
449     if (!tds) {
450         warn_noalloc();
451         return -1;
452     }
453
454     tds[0].link = (u32)&tds[1] | UHCI_PTR_DEPTH;
455     tds[0].status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0)
456                      | TD_CTRL_ACTIVE);
457     tds[0].token = (uhci_explen(cmdsize) | (devaddr << TD_TOKEN_DEVADDR_SHIFT)
458                     | USB_PID_SETUP);
459     tds[0].buffer = (void*)cmd;
460     int toggle = TD_TOKEN_TOGGLE;
461     int i;
462     for (i=1; i<count-1; i++) {
463         tds[i].link = (u32)&tds[i+1] | UHCI_PTR_DEPTH;
464         tds[i].status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0)
465                          | TD_CTRL_ACTIVE);
466         int len = (i == count-2 ? (datasize - (i-1)*maxpacket) : maxpacket);
467         tds[i].token = (uhci_explen(len) | toggle
468                         | (devaddr << TD_TOKEN_DEVADDR_SHIFT)
469                         | (dir ? USB_PID_IN : USB_PID_OUT));
470         tds[i].buffer = data + (i-1) * maxpacket;
471         toggle ^= TD_TOKEN_TOGGLE;
472     }
473     tds[i].link = UHCI_PTR_TERM;
474     tds[i].status = (uhci_maxerr(0) | (lowspeed ? TD_CTRL_LS : 0)
475                      | TD_CTRL_ACTIVE);
476     tds[i].token = (uhci_explen(0) | TD_TOKEN_TOGGLE
477                     | (devaddr << TD_TOKEN_DEVADDR_SHIFT)
478                     | (dir ? USB_PID_OUT : USB_PID_IN));
479     tds[i].buffer = 0;
480
481     // Transfer data
482     barrier();
483     pipe->qh.element = (u32)&tds[0];
484     int ret = wait_pipe(pipe, 500);
485     free(tds);
486     return ret;
487 }
488
489 #define STACKTDS 4
490 #define TDALIGN 16
491
492 int
493 uhci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
494 {
495     if (! CONFIG_USB_UHCI)
496         return -1;
497     struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe);
498     dprintf(7, "uhci_send_bulk qh=%p dir=%d data=%p size=%d\n"
499             , &pipe->qh, dir, data, datasize);
500     int maxpacket = GET_LOWFLAT(pipe->pipe.maxpacket);
501     int lowspeed = GET_LOWFLAT(pipe->pipe.speed);
502     int devaddr = (GET_LOWFLAT(pipe->pipe.devaddr)
503                    | (GET_LOWFLAT(pipe->pipe.ep) << 7));
504     int toggle = GET_LOWFLAT(pipe->toggle) ? TD_TOKEN_TOGGLE : 0;
505
506     // Allocate 4 tds on stack (16byte aligned)
507     u8 tdsbuf[sizeof(struct uhci_td) * STACKTDS + TDALIGN - 1];
508     struct uhci_td *tds = (void*)ALIGN((u32)tdsbuf, TDALIGN);
509     memset(tds, 0, sizeof(*tds) * STACKTDS);
510
511     // Enable tds
512     barrier();
513     SET_LOWFLAT(pipe->qh.element, (u32)MAKE_FLATPTR(GET_SEG(SS), tds));
514
515     int tdpos = 0;
516     while (datasize) {
517         struct uhci_td *td = &tds[tdpos++ % STACKTDS];
518         int ret = wait_td(td);
519         if (ret)
520             goto fail;
521
522         int transfer = datasize;
523         if (transfer > maxpacket)
524             transfer = maxpacket;
525         struct uhci_td *nexttd_fl = MAKE_FLATPTR(GET_SEG(SS)
526                                                  , &tds[tdpos % STACKTDS]);
527         td->link = (transfer==datasize ? UHCI_PTR_TERM : (u32)nexttd_fl);
528         td->token = (uhci_explen(transfer) | toggle
529                      | (devaddr << TD_TOKEN_DEVADDR_SHIFT)
530                      | (dir ? USB_PID_IN : USB_PID_OUT));
531         td->buffer = data;
532         barrier();
533         td->status = (uhci_maxerr(3) | (lowspeed ? TD_CTRL_LS : 0)
534                       | TD_CTRL_ACTIVE);
535         toggle ^= TD_TOKEN_TOGGLE;
536
537         data += transfer;
538         datasize -= transfer;
539     }
540     SET_LOWFLAT(pipe->toggle, !!toggle);
541     return wait_pipe(pipe, 5000);
542 fail:
543     dprintf(1, "uhci_send_bulk failed\n");
544     SET_LOWFLAT(pipe->qh.element, UHCI_PTR_TERM);
545     uhci_waittick(GET_LOWFLAT(pipe->iobase));
546     return -1;
547 }
548
549 int
550 uhci_poll_intr(struct usb_pipe *p, void *data)
551 {
552     ASSERT16();
553     if (! CONFIG_USB_UHCI)
554         return -1;
555
556     struct uhci_pipe *pipe = container_of(p, struct uhci_pipe, pipe);
557     struct uhci_td *td = GET_LOWFLAT(pipe->next_td);
558     u32 status = GET_LOWFLAT(td->status);
559     u32 token = GET_LOWFLAT(td->token);
560     if (status & TD_CTRL_ACTIVE)
561         // No intrs found.
562         return -1;
563     // XXX - check for errors.
564
565     // Copy data.
566     void *tddata = GET_LOWFLAT(td->buffer);
567     memcpy_far(GET_SEG(SS), data, SEG_LOW, LOWFLAT2LOW(tddata)
568                , uhci_expected_length(token));
569
570     // Reenable this td.
571     struct uhci_td *next = (void*)(GET_LOWFLAT(td->link) & ~UHCI_PTR_BITS);
572     SET_LOWFLAT(pipe->next_td, next);
573     barrier();
574     SET_LOWFLAT(td->status, (uhci_maxerr(0) | (status & TD_CTRL_LS)
575                              | TD_CTRL_ACTIVE));
576
577     return 0;
578 }