Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Add HVM configuration capability, init/deinit, etc
[palacios.git] / bios / seabios / src / usb-ehci.c
1 // Code for handling EHCI USB controllers.
2 //
3 // Copyright (C) 2010  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-ehci.h" // struct ehci_qh
12 #include "pci_ids.h" // PCI_CLASS_SERIAL_USB_UHCI
13 #include "pci_regs.h" // PCI_BASE_ADDRESS_0
14 #include "usb.h" // struct usb_s
15 #include "farptr.h" // GET_FLATPTR
16 #include "usb-uhci.h" // init_uhci
17 #include "usb-ohci.h" // init_ohci
18
19 struct usb_ehci_s {
20     struct usb_s usb;
21     struct ehci_caps *caps;
22     struct ehci_regs *regs;
23     struct ehci_qh *async_qh;
24     struct pci_device *companion[8];
25     int checkports;
26     int legacycount;
27 };
28
29
30 /****************************************************************
31  * Root hub
32  ****************************************************************/
33
34 #define EHCI_TIME_POSTPOWER 20
35 #define EHCI_TIME_POSTRESET 2
36
37 // Check if need companion controllers for full/low speed devices
38 static void
39 ehci_note_port(struct usb_ehci_s *cntl)
40 {
41     if (--cntl->checkports)
42         // Ports still being detected.
43         return;
44     if (! cntl->legacycount)
45         // No full/low speed devices found.
46         return;
47     // Start companion controllers.
48     int i;
49     for (i=0; i<ARRAY_SIZE(cntl->companion); i++) {
50         struct pci_device *pci = cntl->companion[i];
51         if (!pci)
52             break;
53
54         // ohci/uhci_init call pci_config_XXX - don't run from irq handler.
55         wait_preempt();
56
57         if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_UHCI)
58             uhci_init(pci, cntl->usb.busid + i);
59         else if (pci_classprog(pci) == PCI_CLASS_SERIAL_USB_OHCI)
60             ohci_init(pci, cntl->usb.busid + i);
61     }
62 }
63
64 // Check if device attached to port
65 static int
66 ehci_hub_detect(struct usbhub_s *hub, u32 port)
67 {
68     struct usb_ehci_s *cntl = container_of(hub->cntl, struct usb_ehci_s, usb);
69     u32 *portreg = &cntl->regs->portsc[port];
70     u32 portsc = readl(portreg);
71
72     // Power up port.
73     if (!(portsc & PORT_POWER)) {
74         portsc |= PORT_POWER;
75         writel(portreg, portsc);
76         msleep(EHCI_TIME_POSTPOWER);
77     } else {
78         msleep(1); // XXX - time for connect to be detected.
79     }
80     portsc = readl(portreg);
81
82     if (!(portsc & PORT_CONNECT))
83         // No device present
84         goto doneearly;
85
86     if ((portsc & PORT_LINESTATUS_MASK) == PORT_LINESTATUS_KSTATE) {
87         // low speed device
88         cntl->legacycount++;
89         writel(portreg, portsc | PORT_OWNER);
90         goto doneearly;
91     }
92
93     // XXX - if just powered up, need to wait for USB_TIME_ATTDB?
94
95     // Begin reset on port
96     portsc = (portsc & ~PORT_PE) | PORT_RESET;
97     writel(portreg, portsc);
98     msleep(USB_TIME_DRSTR);
99     return 0;
100
101 doneearly:
102     ehci_note_port(cntl);
103     return -1;
104 }
105
106 // Reset device on port
107 static int
108 ehci_hub_reset(struct usbhub_s *hub, u32 port)
109 {
110     struct usb_ehci_s *cntl = container_of(hub->cntl, struct usb_ehci_s, usb);
111     u32 *portreg = &cntl->regs->portsc[port];
112     u32 portsc = readl(portreg);
113
114     // Finish reset on port
115     portsc &= ~PORT_RESET;
116     writel(portreg, portsc);
117     msleep(EHCI_TIME_POSTRESET);
118
119     int rv = -1;
120     portsc = readl(portreg);
121     if (!(portsc & PORT_CONNECT))
122         // No longer connected
123         goto resetfail;
124     if (!(portsc & PORT_PE)) {
125         // full speed device
126         cntl->legacycount++;
127         writel(portreg, portsc | PORT_OWNER);
128         goto resetfail;
129     }
130
131     rv = USB_HIGHSPEED;
132 resetfail:
133     ehci_note_port(cntl);
134     return rv;
135 }
136
137 // Disable port
138 static void
139 ehci_hub_disconnect(struct usbhub_s *hub, u32 port)
140 {
141     struct usb_ehci_s *cntl = container_of(hub->cntl, struct usb_ehci_s, usb);
142     u32 *portreg = &cntl->regs->portsc[port];
143     u32 portsc = readl(portreg);
144     writel(portreg, portsc & ~PORT_PE);
145 }
146
147 static struct usbhub_op_s ehci_HubOp = {
148     .detect = ehci_hub_detect,
149     .reset = ehci_hub_reset,
150     .disconnect = ehci_hub_disconnect,
151 };
152
153 // Find any devices connected to the root hub.
154 static int
155 check_ehci_ports(struct usb_ehci_s *cntl)
156 {
157     ASSERT32FLAT();
158     struct usbhub_s hub;
159     memset(&hub, 0, sizeof(hub));
160     hub.cntl = &cntl->usb;
161     hub.portcount = cntl->checkports;
162     hub.op = &ehci_HubOp;
163     usb_enumerate(&hub);
164     return hub.devcount;
165 }
166
167
168 /****************************************************************
169  * Setup
170  ****************************************************************/
171
172 static void
173 configure_ehci(void *data)
174 {
175     struct usb_ehci_s *cntl = data;
176
177     // Allocate ram for schedule storage
178     struct ehci_framelist *fl = memalign_high(sizeof(*fl), sizeof(*fl));
179     struct ehci_qh *intr_qh = memalign_high(EHCI_QH_ALIGN, sizeof(*intr_qh));
180     struct ehci_qh *async_qh = memalign_high(EHCI_QH_ALIGN, sizeof(*async_qh));
181     if (!fl || !intr_qh || !async_qh) {
182         warn_noalloc();
183         goto fail;
184     }
185
186     // XXX - check for halted?
187
188     // Reset the HC
189     u32 cmd = readl(&cntl->regs->usbcmd);
190     writel(&cntl->regs->usbcmd, (cmd & ~(CMD_ASE | CMD_PSE)) | CMD_HCRESET);
191     u64 end = calc_future_tsc(250);
192     for (;;) {
193         cmd = readl(&cntl->regs->usbcmd);
194         if (!(cmd & CMD_HCRESET))
195             break;
196         if (check_tsc(end)) {
197             warn_timeout();
198             goto fail;
199         }
200         yield();
201     }
202
203     // Disable interrupts (just to be safe).
204     writel(&cntl->regs->usbintr, 0);
205
206     // Set schedule to point to primary intr queue head
207     memset(intr_qh, 0, sizeof(*intr_qh));
208     intr_qh->next = EHCI_PTR_TERM;
209     intr_qh->info2 = (0x01 << QH_SMASK_SHIFT);
210     intr_qh->token = QTD_STS_HALT;
211     intr_qh->qtd_next = intr_qh->alt_next = EHCI_PTR_TERM;
212     int i;
213     for (i=0; i<ARRAY_SIZE(fl->links); i++)
214         fl->links[i] = (u32)intr_qh | EHCI_PTR_QH;
215     writel(&cntl->regs->periodiclistbase, (u32)fl);
216
217     // Set async list to point to primary async queue head
218     memset(async_qh, 0, sizeof(*async_qh));
219     async_qh->next = (u32)async_qh | EHCI_PTR_QH;
220     async_qh->info1 = QH_HEAD;
221     async_qh->token = QTD_STS_HALT;
222     async_qh->qtd_next = async_qh->alt_next = EHCI_PTR_TERM;
223     cntl->async_qh = async_qh;
224     writel(&cntl->regs->asynclistbase, (u32)async_qh);
225
226     // Enable queues
227     writel(&cntl->regs->usbcmd, cmd | CMD_ASE | CMD_PSE | CMD_RUN);
228
229     // Set default of high speed for root hub.
230     writel(&cntl->regs->configflag, 1);
231     cntl->checkports = readl(&cntl->caps->hcsparams) & HCS_N_PORTS_MASK;
232
233     // Find devices
234     int count = check_ehci_ports(cntl);
235     free_pipe(cntl->usb.defaultpipe);
236     if (count)
237         // Success
238         return;
239
240     // No devices found - shutdown and free controller.
241     writel(&cntl->regs->usbcmd, cmd & ~CMD_RUN);
242     msleep(4);  // 2ms to stop reading memory - XXX
243 fail:
244     free(fl);
245     free(intr_qh);
246     free(async_qh);
247     free(cntl);
248 }
249
250 int
251 ehci_init(struct pci_device *pci, int busid, struct pci_device *comppci)
252 {
253     if (! CONFIG_USB_EHCI)
254         return -1;
255
256     u16 bdf = pci->bdf;
257     u32 baseaddr = pci_config_readl(bdf, PCI_BASE_ADDRESS_0);
258     struct ehci_caps *caps = (void*)(baseaddr & PCI_BASE_ADDRESS_MEM_MASK);
259     u32 hcc_params = readl(&caps->hccparams);
260     if (hcc_params & HCC_64BIT_ADDR) {
261         dprintf(1, "No support for 64bit EHCI\n");
262         return -1;
263     }
264
265     struct usb_ehci_s *cntl = malloc_tmphigh(sizeof(*cntl));
266     if (!cntl) {
267         warn_noalloc();
268         return -1;
269     }
270     memset(cntl, 0, sizeof(*cntl));
271     cntl->usb.busid = busid;
272     cntl->usb.pci = pci;
273     cntl->usb.type = USB_TYPE_EHCI;
274     cntl->caps = caps;
275     cntl->regs = (void*)caps + readb(&caps->caplength);
276
277     dprintf(1, "EHCI init on dev %02x:%02x.%x (regs=%p)\n"
278             , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)
279             , pci_bdf_to_fn(bdf), cntl->regs);
280
281     pci_config_maskw(bdf, PCI_COMMAND, 0, PCI_COMMAND_MASTER);
282
283     // XXX - check for and disable SMM control?
284
285     // Find companion controllers.
286     int count = 0;
287     for (;;) {
288         if (!comppci || comppci == pci)
289             break;
290         if (pci_classprog(comppci) == PCI_CLASS_SERIAL_USB_UHCI)
291             cntl->companion[count++] = comppci;
292         else if (pci_classprog(comppci) == PCI_CLASS_SERIAL_USB_OHCI)
293             cntl->companion[count++] = comppci;
294         comppci = comppci->next;
295     }
296
297     run_thread(configure_ehci, cntl);
298     return 0;
299 }
300
301
302 /****************************************************************
303  * End point communication
304  ****************************************************************/
305
306 static int
307 ehci_wait_qh(struct usb_ehci_s *cntl, struct ehci_qh *qh)
308 {
309     // XXX - 500ms just a guess
310     u64 end = calc_future_tsc(500);
311     for (;;) {
312         if (qh->qtd_next & EHCI_PTR_TERM)
313             // XXX - confirm
314             return 0;
315         if (check_tsc(end)) {
316             warn_timeout();
317             return -1;
318         }
319         yield();
320     }
321 }
322
323 // Wait for next USB async frame to start - for ensuring safe memory release.
324 static void
325 ehci_waittick(struct usb_ehci_s *cntl)
326 {
327     if (MODE16) {
328         msleep(10);
329         return;
330     }
331     // Wait for access to "doorbell"
332     barrier();
333     u32 cmd, sts;
334     u64 end = calc_future_tsc(100);
335     for (;;) {
336         sts = readl(&cntl->regs->usbsts);
337         if (!(sts & STS_IAA)) {
338             cmd = readl(&cntl->regs->usbcmd);
339             if (!(cmd & CMD_IAAD))
340                 break;
341         }
342         if (check_tsc(end)) {
343             warn_timeout();
344             return;
345         }
346         yield();
347     }
348     // Ring "doorbell"
349     writel(&cntl->regs->usbcmd, cmd | CMD_IAAD);
350     // Wait for completion
351     for (;;) {
352         sts = readl(&cntl->regs->usbsts);
353         if (sts & STS_IAA)
354             break;
355         if (check_tsc(end)) {
356             warn_timeout();
357             return;
358         }
359         yield();
360     }
361     // Ack completion
362     writel(&cntl->regs->usbsts, STS_IAA);
363 }
364
365 struct ehci_pipe {
366     struct ehci_qh qh;
367     struct ehci_qtd *next_td, *tds;
368     void *data;
369     struct usb_pipe pipe;
370 };
371
372 void
373 ehci_free_pipe(struct usb_pipe *p)
374 {
375     if (! CONFIG_USB_EHCI)
376         return;
377     dprintf(7, "ehci_free_pipe %p\n", p);
378     struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe);
379     struct usb_ehci_s *cntl = container_of(
380         pipe->pipe.cntl, struct usb_ehci_s, usb);
381
382     struct ehci_qh *start = cntl->async_qh;
383     struct ehci_qh *pos = start;
384     for (;;) {
385         struct ehci_qh *next = (void*)(pos->next & ~EHCI_PTR_BITS);
386         if (next == start) {
387             // Not found?!  Exit without freeing.
388             warn_internalerror();
389             return;
390         }
391         if (next == &pipe->qh) {
392             pos->next = next->next;
393             ehci_waittick(cntl);
394             free(pipe);
395             return;
396         }
397         pos = next;
398     }
399 }
400
401 struct usb_pipe *
402 ehci_alloc_control_pipe(struct usb_pipe *dummy)
403 {
404     if (! CONFIG_USB_EHCI)
405         return NULL;
406     struct usb_ehci_s *cntl = container_of(
407         dummy->cntl, struct usb_ehci_s, usb);
408     dprintf(7, "ehci_alloc_control_pipe %p\n", &cntl->usb);
409
410     // Allocate a queue head.
411     struct ehci_pipe *pipe = memalign_tmphigh(EHCI_QH_ALIGN, sizeof(*pipe));
412     if (!pipe) {
413         warn_noalloc();
414         return NULL;
415     }
416     memset(pipe, 0, sizeof(*pipe));
417     memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
418     pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM;
419     pipe->qh.token = QTD_STS_HALT;
420
421     // Add queue head to controller list.
422     struct ehci_qh *async_qh = cntl->async_qh;
423     pipe->qh.next = async_qh->next;
424     barrier();
425     async_qh->next = (u32)&pipe->qh | EHCI_PTR_QH;
426     return &pipe->pipe;
427 }
428
429 static int
430 fillTDbuffer(struct ehci_qtd *td, u16 maxpacket, const void *buf, int bytes)
431 {
432     u32 dest = (u32)buf;
433     u32 *pos = td->buf;
434     while (bytes) {
435         if (pos >= &td->buf[ARRAY_SIZE(td->buf)])
436             // More data than can transfer in a single qtd - only use
437             // full packets to prevent a babble error.
438             return ALIGN_DOWN(dest - (u32)buf, maxpacket);
439         u32 count = bytes;
440         u32 max = 0x1000 - (dest & 0xfff);
441         if (count > max)
442             count = max;
443         *pos = dest;
444         bytes -= count;
445         dest += count;
446         pos++;
447     }
448     return dest - (u32)buf;
449 }
450
451 int
452 ehci_control(struct usb_pipe *p, int dir, const void *cmd, int cmdsize
453              , void *data, int datasize)
454 {
455     ASSERT32FLAT();
456     if (! CONFIG_USB_EHCI)
457         return -1;
458     dprintf(5, "ehci_control %p\n", p);
459     if (datasize > 4*4096 || cmdsize > 4*4096) {
460         // XXX - should support larger sizes.
461         warn_noalloc();
462         return -1;
463     }
464     struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe);
465     struct usb_ehci_s *cntl = container_of(
466         pipe->pipe.cntl, struct usb_ehci_s, usb);
467
468     u16 maxpacket = pipe->pipe.maxpacket;
469     int speed = pipe->pipe.speed;
470
471     // Setup fields in qh
472     pipe->qh.info1 = (
473         (1 << QH_MULT_SHIFT) | (speed != USB_HIGHSPEED ? QH_CONTROL : 0)
474         | (maxpacket << QH_MAXPACKET_SHIFT)
475         | QH_TOGGLECONTROL
476         | (speed << QH_SPEED_SHIFT)
477         | (pipe->pipe.ep << QH_EP_SHIFT)
478         | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT));
479     pipe->qh.info2 = ((1 << QH_MULT_SHIFT)
480                       | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT)
481                       | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT));
482
483     // Setup transfer descriptors
484     struct ehci_qtd *tds = memalign_tmphigh(EHCI_QTD_ALIGN, sizeof(*tds) * 3);
485     if (!tds) {
486         warn_noalloc();
487         return -1;
488     }
489     memset(tds, 0, sizeof(*tds) * 3);
490     struct ehci_qtd *td = tds;
491
492     td->qtd_next = (u32)&td[1];
493     td->alt_next = EHCI_PTR_TERM;
494     td->token = (ehci_explen(cmdsize) | QTD_STS_ACTIVE
495                  | QTD_PID_SETUP | ehci_maxerr(3));
496     fillTDbuffer(td, maxpacket, cmd, cmdsize);
497     td++;
498
499     if (datasize) {
500         td->qtd_next = (u32)&td[1];
501         td->alt_next = EHCI_PTR_TERM;
502         td->token = (QTD_TOGGLE | ehci_explen(datasize) | QTD_STS_ACTIVE
503                      | (dir ? QTD_PID_IN : QTD_PID_OUT) | ehci_maxerr(3));
504         fillTDbuffer(td, maxpacket, data, datasize);
505         td++;
506     }
507
508     td->qtd_next = EHCI_PTR_TERM;
509     td->alt_next = EHCI_PTR_TERM;
510     td->token = (QTD_TOGGLE | QTD_STS_ACTIVE
511                  | (dir ? QTD_PID_OUT : QTD_PID_IN) | ehci_maxerr(3));
512
513     // Transfer data
514     barrier();
515     pipe->qh.qtd_next = (u32)tds;
516     barrier();
517     pipe->qh.token = 0;
518     int ret = ehci_wait_qh(cntl, &pipe->qh);
519     pipe->qh.token = QTD_STS_HALT;
520     if (ret) {
521         pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM;
522         // XXX - halt qh?
523         ehci_waittick(cntl);
524     }
525     free(tds);
526     return ret;
527 }
528
529 struct usb_pipe *
530 ehci_alloc_bulk_pipe(struct usb_pipe *dummy)
531 {
532     // XXX - this func is same as alloc_control except for malloc_low
533     if (! CONFIG_USB_EHCI)
534         return NULL;
535     struct usb_ehci_s *cntl = container_of(
536         dummy->cntl, struct usb_ehci_s, usb);
537     dprintf(7, "ehci_alloc_bulk_pipe %p\n", &cntl->usb);
538
539     // Allocate a queue head.
540     struct ehci_pipe *pipe = memalign_low(EHCI_QH_ALIGN, sizeof(*pipe));
541     if (!pipe) {
542         warn_noalloc();
543         return NULL;
544     }
545     memset(pipe, 0, sizeof(*pipe));
546     memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
547     pipe->qh.qtd_next = pipe->qh.alt_next = EHCI_PTR_TERM;
548     pipe->qh.token = QTD_STS_HALT;
549
550     // Add queue head to controller list.
551     struct ehci_qh *async_qh = cntl->async_qh;
552     pipe->qh.next = async_qh->next;
553     barrier();
554     async_qh->next = (u32)&pipe->qh | EHCI_PTR_QH;
555     return &pipe->pipe;
556 }
557
558 static int
559 ehci_wait_td(struct ehci_qtd *td)
560 {
561     u64 end = calc_future_tsc(5000); // XXX - lookup real time.
562     u32 status;
563     for (;;) {
564         status = td->token;
565         if (!(status & QTD_STS_ACTIVE))
566             break;
567         if (check_tsc(end)) {
568             warn_timeout();
569             return -1;
570         }
571         yield();
572     }
573     if (status & QTD_STS_HALT) {
574         dprintf(1, "ehci_wait_td error - status=%x\n", status);
575         return -2;
576     }
577     return 0;
578 }
579
580 #define STACKQTDS 4
581
582 int
583 ehci_send_bulk(struct usb_pipe *p, int dir, void *data, int datasize)
584 {
585     if (! CONFIG_USB_EHCI)
586         return -1;
587     struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe);
588     dprintf(7, "ehci_send_bulk qh=%p dir=%d data=%p size=%d\n"
589             , &pipe->qh, dir, data, datasize);
590
591     // Allocate 4 tds on stack (16byte aligned)
592     u8 tdsbuf[sizeof(struct ehci_qtd) * STACKQTDS + EHCI_QTD_ALIGN - 1];
593     struct ehci_qtd *tds = (void*)ALIGN((u32)tdsbuf, EHCI_QTD_ALIGN);
594     memset(tds, 0, sizeof(*tds) * STACKQTDS);
595
596     // Setup fields in qh
597     u16 maxpacket = GET_FLATPTR(pipe->pipe.maxpacket);
598     SET_FLATPTR(pipe->qh.info1
599                 , ((1 << QH_MULT_SHIFT)
600                    | (maxpacket << QH_MAXPACKET_SHIFT)
601                    | (GET_FLATPTR(pipe->pipe.speed) << QH_SPEED_SHIFT)
602                    | (GET_FLATPTR(pipe->pipe.ep) << QH_EP_SHIFT)
603                    | (GET_FLATPTR(pipe->pipe.devaddr) << QH_DEVADDR_SHIFT)));
604     SET_FLATPTR(pipe->qh.info2
605                 , ((1 << QH_MULT_SHIFT)
606                    | (GET_FLATPTR(pipe->pipe.tt_port) << QH_HUBPORT_SHIFT)
607                    | (GET_FLATPTR(pipe->pipe.tt_devaddr) << QH_HUBADDR_SHIFT)));
608     barrier();
609     SET_FLATPTR(pipe->qh.qtd_next, (u32)MAKE_FLATPTR(GET_SEG(SS), tds));
610     barrier();
611     SET_FLATPTR(pipe->qh.token, GET_FLATPTR(pipe->qh.token) & QTD_TOGGLE);
612
613     int tdpos = 0;
614     while (datasize) {
615         struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS];
616         int ret = ehci_wait_td(td);
617         if (ret)
618             goto fail;
619
620         struct ehci_qtd *nexttd_fl = MAKE_FLATPTR(GET_SEG(SS)
621                                                  , &tds[tdpos % STACKQTDS]);
622
623         int transfer = fillTDbuffer(td, maxpacket, data, datasize);
624         td->qtd_next = (transfer==datasize ? EHCI_PTR_TERM : (u32)nexttd_fl);
625         td->alt_next = EHCI_PTR_TERM;
626         barrier();
627         td->token = (ehci_explen(transfer) | QTD_STS_ACTIVE
628                      | (dir ? QTD_PID_IN : QTD_PID_OUT) | ehci_maxerr(3));
629
630         data += transfer;
631         datasize -= transfer;
632     }
633     int i;
634     for (i=0; i<STACKQTDS; i++) {
635         struct ehci_qtd *td = &tds[tdpos++ % STACKQTDS];
636         int ret = ehci_wait_td(td);
637         if (ret)
638             goto fail;
639     }
640
641     return 0;
642 fail:
643     dprintf(1, "ehci_send_bulk failed\n");
644     SET_FLATPTR(pipe->qh.qtd_next, EHCI_PTR_TERM);
645     SET_FLATPTR(pipe->qh.alt_next, EHCI_PTR_TERM);
646     // XXX - halt qh?
647     struct usb_ehci_s *cntl = container_of(
648         GET_FLATPTR(pipe->pipe.cntl), struct usb_ehci_s, usb);
649     ehci_waittick(cntl);
650     return -1;
651 }
652
653 struct usb_pipe *
654 ehci_alloc_intr_pipe(struct usb_pipe *dummy, int frameexp)
655 {
656     if (! CONFIG_USB_EHCI)
657         return NULL;
658     struct usb_ehci_s *cntl = container_of(
659         dummy->cntl, struct usb_ehci_s, usb);
660     dprintf(7, "ehci_alloc_intr_pipe %p %d\n", &cntl->usb, frameexp);
661
662     if (frameexp > 10)
663         frameexp = 10;
664     int maxpacket = dummy->maxpacket;
665     // Determine number of entries needed for 2 timer ticks.
666     int ms = 1<<frameexp;
667     int count = DIV_ROUND_UP(PIT_TICK_INTERVAL * 1000 * 2, PIT_TICK_RATE * ms);
668     struct ehci_pipe *pipe = memalign_low(EHCI_QH_ALIGN, sizeof(*pipe));
669     struct ehci_qtd *tds = memalign_low(EHCI_QTD_ALIGN, sizeof(*tds) * count);
670     void *data = malloc_low(maxpacket * count);
671     if (!pipe || !tds || !data) {
672         warn_noalloc();
673         goto fail;
674     }
675     memset(pipe, 0, sizeof(*pipe));
676     memcpy(&pipe->pipe, dummy, sizeof(pipe->pipe));
677     pipe->next_td = pipe->tds = tds;
678     pipe->data = data;
679
680     pipe->qh.info1 = (
681         (1 << QH_MULT_SHIFT)
682         | (maxpacket << QH_MAXPACKET_SHIFT)
683         | (pipe->pipe.speed << QH_SPEED_SHIFT)
684         | (pipe->pipe.ep << QH_EP_SHIFT)
685         | (pipe->pipe.devaddr << QH_DEVADDR_SHIFT));
686     pipe->qh.info2 = ((1 << QH_MULT_SHIFT)
687                       | (pipe->pipe.tt_port << QH_HUBPORT_SHIFT)
688                       | (pipe->pipe.tt_devaddr << QH_HUBADDR_SHIFT)
689                       | (0x01 << QH_SMASK_SHIFT)
690                       | (0x1c << QH_CMASK_SHIFT));
691     pipe->qh.qtd_next = (u32)tds;
692
693     int i;
694     for (i=0; i<count; i++) {
695         struct ehci_qtd *td = &tds[i];
696         td->qtd_next = (i==count-1 ? (u32)tds : (u32)&td[1]);
697         td->alt_next = EHCI_PTR_TERM;
698         td->token = (ehci_explen(maxpacket) | QTD_STS_ACTIVE
699                      | QTD_PID_IN | ehci_maxerr(3));
700         td->buf[0] = (u32)data + maxpacket * i;
701     }
702
703     // Add to interrupt schedule.
704     struct ehci_framelist *fl = (void*)readl(&cntl->regs->periodiclistbase);
705     if (frameexp == 0) {
706         // Add to existing interrupt entry.
707         struct ehci_qh *intr_qh = (void*)(fl->links[0] & ~EHCI_PTR_BITS);
708         pipe->qh.next = intr_qh->next;
709         barrier();
710         intr_qh->next = (u32)&pipe->qh | EHCI_PTR_QH;
711     } else {
712         int startpos = 1<<(frameexp-1);
713         pipe->qh.next = fl->links[startpos];
714         barrier();
715         for (i=startpos; i<ARRAY_SIZE(fl->links); i+=ms)
716             fl->links[i] = (u32)&pipe->qh | EHCI_PTR_QH;
717     }
718
719     return &pipe->pipe;
720 fail:
721     free(pipe);
722     free(tds);
723     free(data);
724     return NULL;
725 }
726
727 int
728 ehci_poll_intr(struct usb_pipe *p, void *data)
729 {
730     ASSERT16();
731     if (! CONFIG_USB_EHCI)
732         return -1;
733     struct ehci_pipe *pipe = container_of(p, struct ehci_pipe, pipe);
734     struct ehci_qtd *td = GET_FLATPTR(pipe->next_td);
735     u32 token = GET_FLATPTR(td->token);
736     if (token & QTD_STS_ACTIVE)
737         // No intrs found.
738         return -1;
739     // XXX - check for errors.
740
741     // Copy data.
742     int maxpacket = GET_FLATPTR(pipe->pipe.maxpacket);
743     int pos = td - GET_FLATPTR(pipe->tds);
744     void *tddata = GET_FLATPTR(pipe->data) + maxpacket * pos;
745     memcpy_far(GET_SEG(SS), data
746                , FLATPTR_TO_SEG(tddata), (void*)FLATPTR_TO_OFFSET(tddata)
747                , maxpacket);
748
749     // Reenable this td.
750     struct ehci_qtd *next = (void*)(GET_FLATPTR(td->qtd_next) & ~EHCI_PTR_BITS);
751     SET_FLATPTR(pipe->next_td, next);
752     SET_FLATPTR(td->buf[0], (u32)tddata);
753     barrier();
754     SET_FLATPTR(td->token, (ehci_explen(maxpacket) | QTD_STS_ACTIVE
755                             | QTD_PID_IN | ehci_maxerr(3)));
756
757     return 0;
758 }