779098b168202ce36a8d4b02556b28ef02370fd2
[coreboot.git] / payloads / libpayload / drivers / usb / uhci.c
1 /*
2  * This file is part of the libpayload project.
3  *
4  * Copyright (C) 2008-2010 coresystems GmbH
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
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.
16  *
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
27  * SUCH DAMAGE.
28  */
29
30 //#define USB_DEBUG
31
32 #include <arch/virtual.h>
33 #include <usb/usb.h>
34 #include "uhci.h"
35 #include "uhci_private.h"
36
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,
43                          int dalen, u8 *data);
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);
47
48 #if 0
49 /* dump uhci */
50 static void
51 uhci_dump (hci_t *controller)
52 {
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));
61 }
62 #endif
63
64 static void
65 td_dump (td_t *td)
66 {
67         char td_value[3];
68         const char *td_type;
69         switch (td->pid) {
70                 case UHCI_SETUP:
71                         td_type="SETUP";
72                         break;
73                 case UHCI_IN:
74                         td_type="IN";
75                         break;
76                 case UHCI_OUT:
77                         td_type="OUT";
78                         break;
79                 default:
80                         sprintf(td_value, "%x", td->pid);
81                         td_type=td_value;
82         }
83         debug ("%s packet (at %lx) to %x.%x failed\n", td_type,
84                 virt_to_phys (td), td->dev_addr, td->endp);
85         debug ("td (counter at %x) returns: ", td->counter);
86         debug (" bitstuff err: %x, ", td->status_bitstuff_err);
87         debug (" CRC err: %x, ", td->status_crc_err);
88         debug (" NAK rcvd: %x, ", td->status_nakrcvd);
89         debug (" Babble: %x, ", td->status_babble);
90         debug (" Data Buffer err: %x, ", td->status_databuf_err);
91         debug (" Stalled: %x, ", td->status_stalled);
92         debug (" Active: %x\n", td->status_active);
93         if (td->status_babble)
94                 debug (" Babble because of %s\n",
95                         td->status_bitstuff_err ? "host" : "device");
96         if (td->status_active)
97                 debug (" still active - timeout?\n");
98 }
99
100 static void
101 uhci_reset (hci_t *controller)
102 {
103         /* reset */
104         uhci_reg_write16 (controller, USBCMD, 4);
105         mdelay (50);
106         uhci_reg_write16 (controller, USBCMD, 0);
107         mdelay (10);
108         uhci_reg_write16 (controller, USBCMD, 2);
109         while ((uhci_reg_read16 (controller, USBCMD) & 2) != 0)
110                 mdelay (1);
111
112         uhci_reg_write32 (controller, FLBASEADD,
113                           (u32) virt_to_phys (UHCI_INST (controller)->
114                                               framelistptr));
115         //debug ("framelist at %p\n",UHCI_INST(controller)->framelistptr);
116
117         /* disable irqs */
118         uhci_reg_write16 (controller, USBINTR, 0);
119
120         /* reset framelist index */
121         uhci_reg_write16 (controller, FRNUM, 0);
122
123         uhci_reg_mask16 (controller, USBCMD, ~0, 0xc0); // max packets, configure flag
124
125         uhci_start (controller);
126 }
127
128 hci_t *
129 uhci_init (pcidev_t addr)
130 {
131         int i;
132         u16 reg16;
133
134         hci_t *controller = new_controller ();
135
136         if (!controller)
137                 fatal("Could not create USB controller instance.\n");
138
139         controller->instance = malloc (sizeof (uhci_t));
140         if(!controller->instance)
141                 fatal("Not enough memory creating USB controller instance.\n");
142
143         controller->start = uhci_start;
144         controller->stop = uhci_stop;
145         controller->reset = uhci_reset;
146         controller->shutdown = uhci_shutdown;
147         controller->bulk = uhci_bulk;
148         controller->control = uhci_control;
149         controller->create_intr_queue = uhci_create_intr_queue;
150         controller->destroy_intr_queue = uhci_destroy_intr_queue;
151         controller->poll_intr_queue = uhci_poll_intr_queue;
152         for (i = 0; i < 128; i++) {
153                 controller->devices[i] = 0;
154         }
155         init_device_entry (controller, 0);
156         UHCI_INST (controller)->roothub = controller->devices[0];
157
158         controller->bus_address = addr;
159         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 */
160
161         /* kill legacy support handler */
162         uhci_stop (controller);
163         mdelay (1);
164         uhci_reg_write16 (controller, USBSTS, 0x3f);
165         reg16 = pci_read_config16(controller->bus_address, 0xc0);
166         reg16 &= 0xdf80;
167         pci_write_config16 (controller->bus_address, 0xc0, reg16);
168
169         UHCI_INST (controller)->framelistptr = memalign (0x1000, 1024 * sizeof (flistp_t *));   /* 4kb aligned to 4kb */
170         if (! UHCI_INST (controller)->framelistptr)
171                 fatal("Not enough memory for USB frame list pointer.\n");
172
173         memset (UHCI_INST (controller)->framelistptr, 0,
174                 1024 * sizeof (flistp_t));
175
176         /* According to the *BSD UHCI code, this one is needed on some
177            PIIX chips, because otherwise they misbehave. It must be
178            added to the last chain.
179
180            FIXME: this leaks, if the driver should ever be reinited
181                   for some reason. Not a problem now.
182            */
183         td_t *antiberserk = memalign(16, sizeof(td_t));
184         if (!antiberserk)
185                 fatal("Not enough memory for chipset workaround.\n");
186         memset(antiberserk, 0, sizeof(td_t));
187
188         UHCI_INST (controller)->qh_prei = memalign (16, sizeof (qh_t));
189         UHCI_INST (controller)->qh_intr = memalign (16, sizeof (qh_t));
190         UHCI_INST (controller)->qh_data = memalign (16, sizeof (qh_t));
191         UHCI_INST (controller)->qh_last = memalign (16, sizeof (qh_t));
192
193         if (! UHCI_INST (controller)->qh_prei ||
194             ! UHCI_INST (controller)->qh_intr ||
195             ! UHCI_INST (controller)->qh_data ||
196             ! UHCI_INST (controller)->qh_last)
197                 fatal("Not enough memory for USB controller queues.\n");
198
199         UHCI_INST (controller)->qh_prei->headlinkptr.ptr =
200                 virt_to_phys (UHCI_INST (controller)->qh_intr);
201         UHCI_INST (controller)->qh_prei->headlinkptr.queue_head = 1;
202         UHCI_INST (controller)->qh_prei->elementlinkptr.ptr = 0;
203         UHCI_INST (controller)->qh_prei->elementlinkptr.terminate = 1;
204
205         UHCI_INST (controller)->qh_intr->headlinkptr.ptr =
206                 virt_to_phys (UHCI_INST (controller)->qh_data);
207         UHCI_INST (controller)->qh_intr->headlinkptr.queue_head = 1;
208         UHCI_INST (controller)->qh_intr->elementlinkptr.ptr = 0;
209         UHCI_INST (controller)->qh_intr->elementlinkptr.terminate = 1;
210
211         UHCI_INST (controller)->qh_data->headlinkptr.ptr =
212                 virt_to_phys (UHCI_INST (controller)->qh_last);
213         UHCI_INST (controller)->qh_data->headlinkptr.queue_head = 1;
214         UHCI_INST (controller)->qh_data->elementlinkptr.ptr = 0;
215         UHCI_INST (controller)->qh_data->elementlinkptr.terminate = 1;
216
217         UHCI_INST (controller)->qh_last->headlinkptr.ptr = virt_to_phys (UHCI_INST (controller)->qh_data);
218         UHCI_INST (controller)->qh_last->headlinkptr.terminate = 1;
219         UHCI_INST (controller)->qh_last->elementlinkptr.ptr = virt_to_phys (antiberserk);
220         UHCI_INST (controller)->qh_last->elementlinkptr.terminate = 1;
221
222         for (i = 0; i < 1024; i++) {
223                 UHCI_INST (controller)->framelistptr[i].ptr =
224                         virt_to_phys (UHCI_INST (controller)->qh_prei);
225                 UHCI_INST (controller)->framelistptr[i].terminate = 0;
226                 UHCI_INST (controller)->framelistptr[i].queue_head = 1;
227         }
228         controller->devices[0]->controller = controller;
229         controller->devices[0]->init = uhci_rh_init;
230         controller->devices[0]->init (controller->devices[0]);
231         uhci_reset (controller);
232         return controller;
233 }
234
235 static void
236 uhci_shutdown (hci_t *controller)
237 {
238         if (controller == 0)
239                 return;
240         detach_controller (controller);
241         UHCI_INST (controller)->roothub->destroy (UHCI_INST (controller)->
242                                                   roothub);
243         uhci_reg_mask16 (controller, USBCMD, 0, 0);     // stop work
244         free (UHCI_INST (controller)->framelistptr);
245         free (UHCI_INST (controller)->qh_prei);
246         free (UHCI_INST (controller)->qh_intr);
247         free (UHCI_INST (controller)->qh_data);
248         free (UHCI_INST (controller)->qh_last);
249         free (UHCI_INST (controller));
250         free (controller);
251 }
252
253 static void
254 uhci_start (hci_t *controller)
255 {
256         uhci_reg_mask16 (controller, USBCMD, ~0, 1);    // start work on schedule
257 }
258
259 static void
260 uhci_stop (hci_t *controller)
261 {
262         uhci_reg_mask16 (controller, USBCMD, ~1, 0);    // stop work on schedule
263 }
264
265 #define GET_TD(x) ((void*)(((unsigned int)(x))&~0xf))
266
267 static td_t *
268 wait_for_completed_qh (hci_t *controller, qh_t *qh)
269 {
270         int timeout = 1000000;  /* max 30 ms. */
271         void *current = GET_TD (qh->elementlinkptr.ptr);
272         while ((qh->elementlinkptr.terminate == 0) && (timeout-- > 0)) {
273                 if (current != GET_TD (qh->elementlinkptr.ptr)) {
274                         current = GET_TD (qh->elementlinkptr.ptr);
275                         timeout = 1000000;
276                 }
277                 uhci_reg_mask16 (controller, USBSTS, ~0, 0);    // clear resettable registers
278                 udelay (30);
279         }
280         return (GET_TD (qh->elementlinkptr.ptr) ==
281                 0) ? 0 : GET_TD (phys_to_virt (qh->elementlinkptr.ptr));
282 }
283
284 static int
285 maxlen (int size)
286 {
287         return (size - 1) & 0x7ff;
288 }
289
290 static int
291 min (int a, int b)
292 {
293         if (a < b)
294                 return a;
295         else
296                 return b;
297 }
298
299 static int
300 uhci_control (usbdev_t *dev, direction_t dir, int drlen, void *devreq, int dalen,
301               unsigned char *data)
302 {
303         int endp = 0;           /* this is control: always 0 */
304         int mlen = dev->endpoints[0].maxpacketsize;
305         int count = (2 + (dalen + mlen - 1) / mlen);
306         unsigned short req = ((unsigned short *) devreq)[0];
307         int i;
308         td_t *tds = memalign (16, sizeof (td_t) * count);
309         memset (tds, 0, sizeof (td_t) * count);
310         count--;                /* to compensate for 0-indexed array */
311         for (i = 0; i < count; i++) {
312                 tds[i].ptr = virt_to_phys (&tds[i + 1]);
313                 tds[i].depth_first = 1;
314                 tds[i].terminate = 0;
315         }
316         tds[count].ptr = 0;
317         tds[count].depth_first = 1;
318         tds[count].terminate = 1;
319
320         tds[0].pid = UHCI_SETUP;
321         tds[0].dev_addr = dev->address;
322         tds[0].endp = endp;
323         tds[0].maxlen = maxlen (drlen);
324         tds[0].counter = 3;
325         tds[0].data_toggle = 0;
326         tds[0].lowspeed = dev->speed;
327         tds[0].bufptr = virt_to_phys (devreq);
328         tds[0].status_active = 1;
329
330         int toggle = 1;
331         for (i = 1; i < count; i++) {
332                 switch (dir) {
333                         case SETUP: tds[i].pid = UHCI_SETUP; break;
334                         case IN:    tds[i].pid = UHCI_IN;    break;
335                         case OUT:   tds[i].pid = UHCI_OUT;   break;
336                 }
337                 tds[i].dev_addr = dev->address;
338                 tds[i].endp = endp;
339                 tds[i].maxlen = maxlen (min (mlen, dalen));
340                 tds[i].counter = 3;
341                 tds[i].data_toggle = toggle;
342                 tds[i].lowspeed = dev->speed;
343                 tds[i].bufptr = virt_to_phys (data);
344                 tds[i].status_active = 1;
345                 toggle ^= 1;
346                 dalen -= mlen;
347                 data += mlen;
348         }
349
350         tds[count].pid = (dir == OUT) ? UHCI_IN : UHCI_OUT;
351         tds[count].dev_addr = dev->address;
352         tds[count].endp = endp;
353         tds[count].maxlen = maxlen (0);
354         tds[count].counter = 0; /* as per linux 2.4.10 */
355         tds[count].data_toggle = 1;
356         tds[count].lowspeed = dev->speed;
357         tds[count].bufptr = 0;
358         tds[count].status_active = 1;
359         UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
360                 virt_to_phys (tds);
361         UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
362         UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
363         td_t *td = wait_for_completed_qh (dev->controller,
364                                           UHCI_INST (dev->controller)->
365                                           qh_data);
366         int result;
367         if (td == 0) {
368                 result = 0;
369         } else {
370                 debug ("control packet, req %x\n", req);
371                 td_dump (td);
372                 result = 1;
373         }
374         free (tds);
375         return result;
376 }
377
378 static td_t *
379 create_schedule (int numpackets)
380 {
381         if (numpackets == 0)
382                 return 0;
383         td_t *tds = memalign (16, sizeof (td_t) * numpackets);
384         memset (tds, 0, sizeof (td_t) * numpackets);
385         int i;
386         for (i = 0; i < numpackets; i++) {
387                 tds[i].ptr = virt_to_phys (&tds[i + 1]);
388                 tds[i].terminate = 0;
389                 tds[i].queue_head = 0;
390                 tds[i].depth_first = 1;
391         }
392         tds[numpackets - 1].ptr = 0;
393         tds[numpackets - 1].terminate = 1;
394         tds[numpackets - 1].queue_head = 0;
395         tds[numpackets - 1].depth_first = 0;
396         return tds;
397 }
398
399 static void
400 fill_schedule (td_t *td, endpoint_t *ep, int length, unsigned char *data,
401                int *toggle)
402 {
403         switch (ep->direction) {
404                 case IN: td->pid = UHCI_IN; break;
405                 case OUT: td->pid = UHCI_OUT; break;
406                 case SETUP: td->pid = UHCI_SETUP; break;
407         }
408         td->dev_addr = ep->dev->address;
409         td->endp = ep->endpoint & 0xf;
410         td->maxlen = maxlen (length);
411         if (ep->direction == SETUP)
412                 td->counter = 3;
413         else
414                 td->counter = 0;
415         td->data_toggle = *toggle & 1;
416         td->lowspeed = ep->dev->speed;
417         td->bufptr = virt_to_phys (data);
418
419         td->status_active = 1;
420         *toggle ^= 1;
421 }
422
423 static int
424 run_schedule (usbdev_t *dev, td_t *td)
425 {
426         UHCI_INST (dev->controller)->qh_data->elementlinkptr.ptr =
427                 virt_to_phys (td);
428         UHCI_INST (dev->controller)->qh_data->elementlinkptr.queue_head = 0;
429         UHCI_INST (dev->controller)->qh_data->elementlinkptr.terminate = 0;
430         td = wait_for_completed_qh (dev->controller,
431                                     UHCI_INST (dev->controller)->qh_data);
432         if (td == 0) {
433                 return 0;
434         } else {
435                 td_dump (td);
436                 return 1;
437         }
438 }
439
440 /* finalize == 1: if data is of packet aligned size, add a zero length packet */
441 static int
442 uhci_bulk (endpoint_t *ep, int size, u8 *data, int finalize)
443 {
444         int maxpsize = ep->maxpacketsize;
445         if (maxpsize == 0)
446                 fatal("MaxPacketSize == 0!!!");
447         int numpackets = (size + maxpsize - 1 + finalize) / maxpsize;
448         if (numpackets == 0)
449                 return 0;
450         td_t *tds = create_schedule (numpackets);
451         int i = 0, toggle = ep->toggle;
452         while ((size > 0) || ((size == 0) && (finalize != 0))) {
453                 fill_schedule (&tds[i], ep, min (size, maxpsize), data,
454                                &toggle);
455                 i++;
456                 data += maxpsize;
457                 size -= maxpsize;
458         }
459         if (run_schedule (ep->dev, tds) == 1) {
460                 debug("Stalled. Trying to clean up.\n");
461                 clear_stall (ep);
462                 free (tds);
463                 return 1;
464         }
465         ep->toggle = toggle;
466         free (tds);
467         return 0;
468 }
469
470 typedef struct {
471         qh_t *qh;
472         td_t *tds;
473         td_t *last_td;
474         u8 *data;
475         int lastread;
476         int total;
477         int reqsize;
478 } intr_q;
479
480 /* create and hook-up an intr queue into device schedule */
481 static void*
482 uhci_create_intr_queue (endpoint_t *ep, int reqsize, int reqcount, int reqtiming)
483 {
484         u8 *data = malloc(reqsize*reqcount);
485         td_t *tds = memalign(16, sizeof(td_t) * reqcount);
486         qh_t *qh = memalign(16, sizeof(qh_t));
487
488         if (!data || !tds || !qh)
489                 fatal("Not enough memory to create USB intr queue prerequisites.\n");
490
491         qh->elementlinkptr.ptr = virt_to_phys(tds);
492         qh->elementlinkptr.queue_head = 0;
493         qh->elementlinkptr.terminate = 0;
494
495         intr_q *q = malloc(sizeof(intr_q));
496         if (!q)
497                 fatal("Not enough memory to create USB intr queue.\n");
498         q->qh = qh;
499         q->tds = tds;
500         q->data = data;
501         q->lastread = 0;
502         q->total = reqcount;
503         q->reqsize = reqsize;
504         q->last_td = &tds[reqcount - 1];
505
506         memset (tds, 0, sizeof (td_t) * reqcount);
507         int i;
508         for (i = 0; i < reqcount; i++) {
509                 tds[i].ptr = virt_to_phys (&tds[i + 1]);
510                 tds[i].terminate = 0;
511                 tds[i].queue_head = 0;
512                 tds[i].depth_first = 0;
513
514                 switch (ep->direction) {
515                         case IN: tds[i].pid = UHCI_IN; break;
516                         case OUT: tds[i].pid = UHCI_OUT; break;
517                         case SETUP: tds[i].pid = UHCI_SETUP; break;
518                 }
519                 tds[i].dev_addr = ep->dev->address;
520                 tds[i].endp = ep->endpoint & 0xf;
521                 tds[i].maxlen = maxlen (reqsize);
522                 tds[i].counter = 0;
523                 tds[i].data_toggle = ep->toggle & 1;
524                 tds[i].lowspeed = ep->dev->speed;
525                 tds[i].bufptr = virt_to_phys (data);
526                 tds[i].status_active = 1;
527                 ep->toggle ^= 1;
528                 data += reqsize;
529         }
530         tds[reqcount - 1].ptr = 0;
531         tds[reqcount - 1].terminate = 1;
532         tds[reqcount - 1].queue_head = 0;
533         tds[reqcount - 1].depth_first = 0;
534         for (i = reqtiming; i < 1024; i += reqtiming) {
535                 /* FIXME: wrap in another qh, one for each occurance of the qh in the framelist */
536                 qh->headlinkptr.ptr = UHCI_INST (ep->dev->controller)->framelistptr[i].ptr;
537                 qh->headlinkptr.terminate = 0;
538                 UHCI_INST (ep->dev->controller)->framelistptr[i].ptr = virt_to_phys(qh);
539                 UHCI_INST (ep->dev->controller)->framelistptr[i].terminate = 0;
540                 UHCI_INST (ep->dev->controller)->framelistptr[i].queue_head = 1;
541         }
542         return q;
543 }
544
545 /* remove queue from device schedule, dropping all data that came in */
546 static void
547 uhci_destroy_intr_queue (endpoint_t *ep, void *q_)
548 {
549         intr_q *q = (intr_q*)q_;
550         u32 val = virt_to_phys (q->qh);
551         u32 end = virt_to_phys (UHCI_INST (ep->dev->controller)->qh_intr);
552         int i;
553         for (i=0; i<1024; i++) {
554                 u32 oldptr = 0;
555                 u32 ptr = UHCI_INST (ep->dev->controller)->framelistptr[i].ptr;
556                 while (ptr != end) {
557                         if (((qh_t*)phys_to_virt(ptr))->elementlinkptr.ptr == val) {
558                                 ((qh_t*)phys_to_virt(oldptr))->headlinkptr.ptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr.ptr;
559                                 free(phys_to_virt(ptr));
560                                 break;
561                         }
562                         oldptr = ptr;
563                         ptr = ((qh_t*)phys_to_virt(ptr))->headlinkptr.ptr;
564                 }
565         }
566         free(q->data);
567         free(q->tds);
568         free(q->qh);
569         free(q);
570 }
571
572 /* read one intr-packet from queue, if available. extend the queue for new input.
573    return NULL if nothing new available.
574    Recommended use: while (data=poll_intr_queue(q)) process(data);
575  */
576 static u8*
577 uhci_poll_intr_queue (void *q_)
578 {
579         intr_q *q = (intr_q*)q_;
580         if (q->tds[q->lastread].status_active == 0) {
581                 /* FIXME: handle errors */
582                 int current = q->lastread;
583                 int previous;
584                 if (q->lastread == 0) {
585                         previous = q->total - 1;
586                 } else {
587                         previous = q->lastread - 1;
588                 }
589                 q->tds[previous].status = 0;
590                 q->tds[previous].ptr = 0;
591                 q->tds[previous].terminate = 1;
592                 if (q->last_td != &q->tds[previous]) {
593                         q->last_td->ptr = virt_to_phys(&q->tds[previous]);
594                         q->last_td->terminate = 0;
595                         q->last_td = &q->tds[previous];
596                 }
597                 q->tds[previous].status_active = 1;
598                 q->lastread = (q->lastread + 1) % q->total;
599                 return &q->data[current*q->reqsize];
600         }
601         return NULL;
602 }
603
604 void
605 uhci_reg_write32 (hci_t *ctrl, usbreg reg, u32 value)
606 {
607         outl (value, ctrl->reg_base + reg);
608 }
609
610 u32
611 uhci_reg_read32 (hci_t *ctrl, usbreg reg)
612 {
613         return inl (ctrl->reg_base + reg);
614 }
615
616 void
617 uhci_reg_write16 (hci_t *ctrl, usbreg reg, u16 value)
618 {
619         outw (value, ctrl->reg_base + reg);
620 }
621
622 u16
623 uhci_reg_read16 (hci_t *ctrl, usbreg reg)
624 {
625         return inw (ctrl->reg_base + reg);
626 }
627
628 void
629 uhci_reg_write8 (hci_t *ctrl, usbreg reg, u8 value)
630 {
631         outb (value, ctrl->reg_base + reg);
632 }
633
634 u8
635 uhci_reg_read8 (hci_t *ctrl, usbreg reg)
636 {
637         return inb (ctrl->reg_base + reg);
638 }
639
640 void
641 uhci_reg_mask32 (hci_t *ctrl, usbreg reg, u32 andmask, u32 ormask)
642 {
643         uhci_reg_write32 (ctrl, reg,
644                           (uhci_reg_read32 (ctrl, reg) & andmask) | ormask);
645 }
646
647 void
648 uhci_reg_mask16 (hci_t *ctrl, usbreg reg, u16 andmask, u16 ormask)
649 {
650         uhci_reg_write16 (ctrl, reg,
651                           (uhci_reg_read16 (ctrl, reg) & andmask) | ormask);
652 }
653
654 void
655 uhci_reg_mask8 (hci_t *ctrl, usbreg reg, u8 andmask, u8 ormask)
656 {
657         uhci_reg_write8 (ctrl, reg,
658                          (uhci_reg_read8 (ctrl, reg) & andmask) | ormask);
659 }