merged in all changes done to the trunk up to Aug 28
[pintos-anon] / src / devices / usb_uhci.c
1 /**
2  * Universal Host Controller Interface driver
3  * TODO:
4  *      Stall timeouts
5  *      Better (any) root hub handling
6  */
7
8 #include <round.h>
9 #include <stdio.h>
10 #include <string.h>
11 #include <kernel/bitmap.h>
12 #include "threads/pte.h"
13 #include "threads/malloc.h"
14 #include "threads/palloc.h"
15 #include "threads/synch.h"
16 #include "threads/interrupt.h"
17 #include "threads/thread.h"
18 #include "devices/pci.h"
19 #include "devices/usb.h"
20 #include "devices/timer.h"
21
22 #define UHCI_MAX_PORTS          8
23
24 #define FRAME_LIST_ENTRIES      1024
25 #define TD_ENTRIES              (4096/32)       /* number of entries allocated */
26 #define QH_ENTRIES              (4096/16)
27
28 /* uhci pci registers */
29 #define UHCI_REG_USBCMD         0x00    /* Command */
30 #define UHCI_REG_USBSTS         0x02    /* Status */
31 #define UHCI_REG_USBINTR        0x04    /* interrupt enable */
32 #define UHCI_REG_FRNUM          0x06    /* frame number */
33 #define UHCI_REG_FLBASEADD      0x08    /* frame list base address */
34 #define UHCI_REG_SOFMOD         0x0c    /* start of frame modify */
35 #define UHCI_REG_PORTSC1        0x10    /* port 1 status/control */
36 #define UHCI_REG_PORTSC2        0x12    /* port 2 status/control */
37 #define UHCI_REGSZ              0x20    /* register iospace size */
38
39 /* in PCI config space for some reason */
40 #define UHCI_REG_LEGSUP         0xC0
41
42
43 /* command register */
44 #define USB_CMD_MAX_PACKET      (1 << 7)
45 #define USB_CMD_CONFIGURE       (1 << 6)
46 #define USB_CMD_FGR             (1 << 4)        /* force global resume */
47 #define USB_CMD_EGSM            (1 << 3)        /* global suspend mode */
48 #define USB_CMD_GRESET          (1 << 2)        /* global reset */
49 #define USB_CMD_HCRESET         (1 << 1)        /* host controller reset */
50 #define USB_CMD_RS              (1 << 0)        /* run/stop */
51
52 /* status register */
53 #define USB_STATUS_HALTED       (1 << 5)
54 #define USB_STATUS_PROCESSERR   (1 << 4)
55 #define USB_STATUS_HOSTERR      (1 << 3)
56 #define USB_STATUS_RESUME       (1 << 2)
57 #define USB_STATUS_INTERR       (1 << 1)
58 #define USB_STATUS_USBINT       (1 << 0)
59
60 /* interrupt enable register */
61 #define USB_INTR_SHORT          (1 << 3)        /* enable short packets */
62 #define USB_INTR_IOC            (1 << 2)        /* interrupt on complete */
63 #define USB_INTR_RESUME         (1 << 1)        /* resume interrupt enable */
64 #define USB_INTR_TIMEOUT        (1 << 0)        /* timeout int enable */
65
66 /* port control register */
67 #define USB_PORT_SUSPEND        (1 << 12)
68 #define USB_PORT_RESET          (1 << 9)
69 #define USB_PORT_LOWSPEED       (1 << 8)
70 #define USB_PORT_RESUMED        (1 << 6)        /* resume detected */
71 #define USB_PORT_CHANGE         (1 << 3)        /* enable change */
72 #define USB_PORT_ENABLE         (1 << 2)        /* enable the port */
73 #define USB_PORT_CONNECTCHG     (1 << 1)        /* connect status changed */
74 #define USB_PORT_CONNECTSTATUS  (1 << 0)        /* device is connected */
75
76 #define ptr_to_flp(x)   (((uintptr_t)x) >> 4)
77 #define flp_to_ptr(x)   (uintptr_t)(((uintptr_t)x) << 4)
78
79 /* frame structures */
80 #pragma pack(1)
81 struct frame_list_ptr
82 {
83   uint32_t terminate:1;
84   uint32_t qh_select:1;
85   uint32_t depth_select:1;      /* only for TD */
86   uint32_t resv:1;              /* zero */
87   uint32_t flp:28;              /* frame list pointer */
88 };
89
90 struct td_token
91 {
92   uint32_t pid:8;               /* packet id */
93   uint32_t dev_addr:7;          /* device address */
94   uint32_t end_point:4;
95   uint32_t data_toggle:1;
96   uint32_t resv:1;
97   uint32_t maxlen:11;           /* maximum pkt length */
98 };
99
100 struct td_control
101 {
102   uint32_t actual_len:11;
103   uint32_t resv1:5;
104
105   /* status information */
106   uint32_t resv2:1;
107   uint32_t bitstuff:1;
108   uint32_t timeout:1;
109   uint32_t nak:1;
110   uint32_t babble:1;
111   uint32_t buffer_error:1;
112   uint32_t stalled:1;
113   uint32_t active:1;
114
115   /* config data */
116   uint32_t ioc:1;               /* issue int on complete */
117   uint32_t ios:1;               /* isochronous select */
118   uint32_t ls:1;                /* low speed device */
119   uint32_t error_limit:2;       /* errors before interrupt */
120   uint32_t spd:1;               /* short packet detect */
121   uint32_t resv3:2;
122 };
123
124 #define TD_FL_ASYNC     1
125 #define TD_FL_USED      0x80000000
126
127 struct tx_descriptor
128 {
129   struct frame_list_ptr flp;
130   struct td_control control;
131   struct td_token token;
132   uint32_t buf_ptr;
133
134
135   struct frame_list_ptr *head;  /* for fast removal */
136   uint32_t flags;
137 };
138
139 struct queue_head
140 {
141   struct frame_list_ptr qhlp;   /* queue head link pointer */
142   struct frame_list_ptr qelp;   /* queue elem link pointer */
143 };
144 #pragma pack()
145
146 struct uhci_info
147 {
148   struct pci_dev *dev;
149   struct pci_io *io;            /* pci io space */
150   struct lock lock;
151   struct frame_list_ptr *frame_list;    /* page aligned frame list */
152
153   struct tx_descriptor *td_pool;
154   struct bitmap *td_used;
155   struct queue_head *qh_pool;
156   struct bitmap *qh_used;
157
158   uint8_t num_ports;
159   uint8_t attached_ports;
160
161   int timeouts;                 /* number of timeouts */
162
163   struct semaphore td_sem;
164   struct list devices;          /* devices on host */
165   struct list waiting;          /* threads waiting */
166 };
167
168 struct usb_wait
169 {
170   struct tx_descriptor *td;
171   struct uhci_dev_info *ud;
172   struct semaphore sem;
173   struct list_elem peers;
174 };
175
176 struct uhci_dev_info
177 {
178   struct uhci_info *ui;         /* owner */
179   bool low_speed;               /* whether device is low speed */
180   int dev_addr;                 /* device address */
181   int errors;                   /* aggregate errors */
182   struct list_elem peers;       /* next dev on host */
183   struct lock lock;
184   struct queue_head *qh;
185 };
186
187 struct uhci_eop_info
188 {
189   struct uhci_dev_info *ud;
190   int eop;
191   int maxpkt;                   /* max packet size */
192   int toggle;                   /* data toggle bit for bulk transfers */
193 };
194
195 #define uhci_lock(x)    lock_acquire(&(x)->lock)
196 #define uhci_unlock(x)  lock_release(&(x)->lock)
197 #define dev_lock(x)     lock_acquire(&(x)->lock)
198 #define dev_unlock(x)   lock_release(&(x)->lock)
199
200
201 static int token_to_pid (int token);
202
203 static int uhci_tx_pkt (host_eop_info eop, int token, void *pkt,
204                         int min_sz, int max_sz, int *in_sz, bool wait);
205
206 static int uhci_detect_change (host_info);
207
208
209 static int uhci_tx_pkt_now (struct uhci_eop_info *ue, int token, void *pkt,
210                             int sz);
211 static int uhci_tx_pkt_wait (struct uhci_eop_info *ue, int token, void *pkt,
212                              int max_sz, int *in_sz);
213 static int uhci_tx_pkt_bulk (struct uhci_eop_info *ue, int token, void *buf,
214                              int sz, int *tx);
215
216
217 static int uhci_process_completed (struct uhci_info *ui);
218
219 static struct tx_descriptor *uhci_acquire_td (struct uhci_info *);
220 static void uhci_release_td (struct uhci_info *, struct tx_descriptor *);
221 static void uhci_remove_qh (struct uhci_info *ui, struct queue_head *qh);
222
223
224 static void qh_free (struct uhci_info *ui, struct queue_head *qh);
225 static struct queue_head *qh_alloc (struct uhci_info *ui);
226
227 static struct uhci_info *uhci_create_info (struct pci_io *io);
228 static void uhci_destroy_info (struct uhci_info *ui) UNUSED;
229 static host_eop_info uhci_create_eop (host_dev_info hd, int eop, int maxpkt);
230 static void uhci_remove_eop (host_eop_info hei);
231 static host_dev_info uhci_create_chan (host_info hi, int dev_addr, int ver);
232 static void uhci_destroy_chan (host_dev_info);
233 static void uhci_modify_chan (host_dev_info, int dev_addr, int ver);
234 static void uhci_set_toggle (host_eop_info, int toggle);
235
236 static struct tx_descriptor *td_from_pool (struct uhci_info *ui, int idx);
237
238 static int check_and_flip_change (struct uhci_info *ui, int reg);
239 static void uhci_stop (struct uhci_info *ui);
240 static void uhci_run (struct uhci_info *ui);
241 static void uhci_stop_unlocked (struct uhci_info *ui);
242 static void uhci_run_unlocked (struct uhci_info *ui);
243 #define uhci_is_stopped(x)      (pci_reg_read16((x)->io, UHCI_REG_USBSTS) \
244                                 & USB_STATUS_HALTED)
245 #define uhci_port_enabled(x, y) (pci_reg_read16((x)->io, (y)) & USB_PORT_ENABLE)
246 static void uhci_add_td_to_qh (struct queue_head *qh,
247                                struct tx_descriptor *td);
248 static void uhci_remove_error_td (struct tx_descriptor *td);
249 static void uhci_setup_td (struct tx_descriptor *td, int dev_addr, int token,
250                            int eop, void *pkt, int sz, int toggle, bool ls);
251 static int uhci_enable_port (struct uhci_info *ui, int port);
252 static void uhci_irq (void *uhci_data);
253 static void uhci_detect_ports (struct uhci_info *ui);
254
255 static int uhci_remove_stalled (struct uhci_info *ui);
256 static void uhci_stall_watchdog (struct uhci_info *ui) UNUSED;
257
258 static void dump_all_qh (struct uhci_info *ui);
259 static void dump_qh (struct queue_head *qh);
260
261 static void dump_regs (struct uhci_info *ui);
262
263 void uhci_init (void);
264
265 static struct usb_host uhci_host = {
266   .name = "UHCI",
267   .tx_pkt = uhci_tx_pkt,
268   .detect_change = uhci_detect_change,
269   .create_dev_channel = uhci_create_chan,
270   .remove_dev_channel = uhci_destroy_chan,
271   .modify_dev_channel = uhci_modify_chan,
272   .set_toggle = uhci_set_toggle,
273   .create_eop = uhci_create_eop,
274   .remove_eop = uhci_remove_eop
275 };
276
277 void
278 uhci_init (void)
279 {
280   struct pci_dev *pd;
281   int dev_num;
282
283   dev_num = 0;
284   while ((pd = pci_get_dev_by_class (PCI_MAJOR_SERIALBUS, PCI_MINOR_USB,
285                                      PCI_USB_IFACE_UHCI, dev_num)) != NULL)
286     {
287       struct pci_io *io;
288       struct uhci_info *ui;
289       int i;
290
291       dev_num++;
292
293       /* find IO space */
294       io = NULL;
295       while ((io = pci_io_enum (pd, io)) != NULL)
296         {
297           if (pci_io_size (io) == UHCI_REGSZ)
298             break;
299         }
300
301       /* not found, next PCI */
302       if (io == NULL)
303         continue;
304
305       ui = uhci_create_info (io);
306       ui->dev = pd;
307
308       uhci_detect_ports (ui);
309
310       pci_write_config16 (ui->dev, UHCI_REG_LEGSUP, 0x8f00);
311       pci_reg_write16 (ui->io, UHCI_REG_USBCMD, USB_CMD_HCRESET);
312       asm volatile ("mfence":::"memory");
313       timer_usleep (5);
314       if (pci_reg_read16 (ui->io, UHCI_REG_USBCMD) & USB_CMD_HCRESET)
315         printf ("reset failed!\n");
316       pci_reg_write16 (ui->io, UHCI_REG_USBINTR, 0);
317       pci_reg_write16 (ui->io, UHCI_REG_USBCMD, 0);
318
319       pci_reg_write16 (ui->io, UHCI_REG_PORTSC1, 0);
320       pci_reg_write16 (ui->io, UHCI_REG_PORTSC2, 0);
321
322       pci_reg_write8 (ui->io, UHCI_REG_SOFMOD, 64);
323       pci_reg_write32 (ui->io, UHCI_REG_FLBASEADD, vtop (ui->frame_list));
324       pci_reg_write16 (ui->io, UHCI_REG_FRNUM, 0);
325       asm volatile ("mfence":::"memory");
326
327       /* deactivate SMM junk, only enable IRQ */
328       pci_write_config16 (ui->dev, UHCI_REG_LEGSUP, 0x2000);
329
330       asm volatile ("mfence":::"memory");
331
332       pci_reg_write16 (ui->io, UHCI_REG_USBCMD,
333                        USB_CMD_RS | USB_CMD_CONFIGURE | USB_CMD_MAX_PACKET);
334       pci_reg_write16 (ui->io, UHCI_REG_USBINTR,
335                        USB_INTR_SHORT | USB_INTR_IOC |
336                        USB_INTR_TIMEOUT | USB_INTR_RESUME);
337
338       asm volatile ("mfence":::"memory");
339
340       printf ("UHCI: Enabling %d root ports\n", ui->num_ports);
341       ui->attached_ports = 0;
342       for (i = 0; i < ui->num_ports; i++)
343         ui->attached_ports += uhci_enable_port (ui, i);
344
345       pci_register_irq (pd, uhci_irq, ui);
346
347       usb_register_host (&uhci_host, ui);
348     }
349 }
350
351 #define UHCI_PORT_TIMEOUT       1000
352 static int
353 uhci_enable_port (struct uhci_info *ui, int idx)
354 {
355   uint16_t status;
356   int time, stable_since;
357   int count;
358   int port;
359
360   port = UHCI_REG_PORTSC1 + idx * 2;
361
362   status = 0xffff;
363   stable_since = 0;
364   for (time = 0; ; time += 25) 
365     {
366       uint16_t new_status;
367       new_status = pci_reg_read16 (ui->io, port);
368       if (status != (new_status & USB_PORT_CONNECTSTATUS)
369           || new_status & USB_PORT_CONNECTCHG) 
370         {
371           if (new_status & USB_PORT_CONNECTCHG)
372             pci_reg_write16 (ui->io, port, (new_status & ~0xe80a) | USB_PORT_CONNECTCHG);
373           stable_since = time;
374           status = new_status & USB_PORT_CONNECTSTATUS;
375         }
376       else if (time - stable_since >= 100)
377         break;
378       else if (time >= 1500)
379         return 0;
380       timer_msleep (25);
381     }
382
383   if (!(status & USB_PORT_CONNECTSTATUS))
384     return 0;
385
386   for (count = 0; count < 3; count++) 
387     {
388       status = pci_reg_read16 (ui->io, port) & ~0xe80a;
389       pci_reg_write16 (ui->io, port, status | USB_PORT_RESET);
390       timer_msleep (50);
391
392       status = pci_reg_read16 (ui->io, port) & ~0xe80a;
393       pci_reg_write16 (ui->io, port, status & ~USB_PORT_RESET);
394       timer_usleep (10);
395
396       status = pci_reg_read16 (ui->io, port) & ~0xe80a;
397       pci_reg_write16 (ui->io, port, status & ~(USB_PORT_CONNECTCHG | USB_PORT_CHANGE));
398
399       status = pci_reg_read16 (ui->io, port) & ~0xe80a;
400       pci_reg_write16 (ui->io, port, status | USB_PORT_ENABLE);
401
402       status = pci_reg_read16 (ui->io, port);
403       if (status & USB_PORT_ENABLE)
404         break;
405     }
406
407   if (!(status & USB_PORT_CONNECTSTATUS))
408     {
409       pci_reg_write16 (ui->io, port, 0);
410       return 0;
411     }
412
413   return 1;
414 }
415
416
417 static void
418 dump_regs (struct uhci_info *ui)
419 {
420   int regs[] = { 0, 2, 4, 6, 8, 0xc, 0x10, 0x12 };
421   int sz[] = { 2, 2, 2, 2, 4, 2, 2, 2 };
422   char *name[] =
423     { "cmd", "sts", "intr", "frnum", "base", "sofmod", "portsc1", "portsc2" };
424   int i;
425   printf ("UHCI registers:\n");
426   for (i = 0; i < 8; i++)
427     {
428       printf ("%s: %x\n", name[i], (sz[i] == 2) ?
429               pci_reg_read16 (ui->io, regs[i]) :
430               pci_reg_read32 (ui->io, regs[i]));
431
432     }
433 }
434
435 static void
436 uhci_destroy_info (struct uhci_info *ui)
437 {
438   palloc_free_page (ui->frame_list);
439   palloc_free_page (ui->td_pool);
440   palloc_free_page (ui->qh_pool);
441   bitmap_destroy (ui->qh_used);
442   bitmap_destroy (ui->td_used);
443   free (ui);
444 }
445
446 static struct uhci_info *
447 uhci_create_info (struct pci_io *io)
448 {
449   struct uhci_info *ui;
450   int i;
451
452   ui = malloc (sizeof (struct uhci_info));
453
454   ui->io = io;
455   lock_init (&ui->lock);
456
457   /* create an empty schedule */
458   ui->frame_list = palloc_get_page (PAL_ASSERT | PAL_NOCACHE);
459   memset (ui->frame_list, 0, PGSIZE);
460   for (i = 0; i < FRAME_LIST_ENTRIES; i++)
461     ui->frame_list[i].terminate = 1;
462
463   /* permit 3 timeouts */
464   ui->timeouts = 3;
465 //  thread_create ("uhci watchdog", PRI_MIN,
466 //               (thread_func *) uhci_stall_watchdog, ui);
467   ui->td_pool = palloc_get_page (PAL_ASSERT | PAL_NOCACHE);
468   ui->td_used = bitmap_create (TD_ENTRIES);
469   ui->qh_pool = palloc_get_page (PAL_ASSERT | PAL_NOCACHE);
470   ui->qh_used = bitmap_create (QH_ENTRIES);
471   sema_init (&ui->td_sem, TD_ENTRIES);
472
473   list_init (&ui->devices);
474   list_init (&ui->waiting);
475
476   return ui;
477 }
478
479
480 static int
481 uhci_tx_pkt (host_eop_info hei, int token, void *pkt, int min_sz,
482              int max_sz, int *in_sz, bool wait)
483 {
484   struct uhci_eop_info *ue;
485   struct uhci_dev_info *ud;
486
487   ASSERT (min_sz <= max_sz);
488
489   /* can't have page overlap */
490   if (pkt != NULL)
491     {
492       ASSERT (max_sz > 0);
493       ASSERT (pg_no (pkt + max_sz - 1) == pg_no (pkt));
494     }
495
496   ue = hei;
497   ud = ue->ud;
498
499   /* don't bother if ports are down */
500   if (ud->ui->attached_ports == 0)
501     {
502       return USB_HOST_ERR_NODEV;
503     }
504
505   /* setup token acts to synchronize data toggle */
506   if (token == USB_TOKEN_SETUP)
507     ue->toggle = 0;
508
509   if (min_sz != 0)
510     {
511       return uhci_tx_pkt_bulk (ue, token, pkt, max_sz, in_sz);
512     }
513   else
514     {
515       if (wait == false)
516         {
517           if (in_sz != NULL)
518             *in_sz = max_sz;
519           return uhci_tx_pkt_now (ue, token, pkt, max_sz);
520         }
521       else
522         {
523           return uhci_tx_pkt_wait (ue, token, pkt, max_sz, in_sz);
524         }
525     }
526
527   return 0;
528 }
529
530 static int
531 uhci_tx_pkt_bulk (struct uhci_eop_info *ue, int token, void *buf,
532                   int sz, int *tx)
533 {
534   /* XXX this can be made to use async packets */
535   int bytes = 0;
536   int txed = 0;
537
538   /* send data in max_pkt sized chunks */
539   while (bytes < sz)
540     {
541       int to_tx, pkt_txed;
542       int left;
543       int err;
544       bool wait_on_pkt;
545
546       left = sz - bytes;
547       to_tx = (left > ue->maxpkt) ? ue->maxpkt : left;
548       wait_on_pkt = (left <= to_tx) ? true : false;
549
550       pkt_txed = 0;
551       err = uhci_tx_pkt (ue, token, buf + bytes, 0, to_tx, &pkt_txed, 
552                          wait_on_pkt);
553       if (err)
554         {
555           if (tx != NULL)
556             *tx = txed;
557           return err;
558         }
559       txed += pkt_txed;
560       bytes += pkt_txed;
561     }
562
563   if (tx != NULL)
564     *tx = txed;
565
566   return USB_HOST_ERR_NONE;
567 }
568
569 static int
570 token_to_pid (int token)
571 {
572   switch (token)
573     {
574     case USB_TOKEN_SETUP:
575       return USB_PID_SETUP;
576     case USB_TOKEN_IN:
577       return USB_PID_IN;
578     case USB_TOKEN_OUT:
579       return USB_PID_OUT;
580     default:
581       PANIC ("Unknown USB token\n");
582     }
583 }
584
585 static void
586 uhci_setup_td (struct tx_descriptor *td, int dev_addr, int token,
587                int eop, void *pkt, int sz, int toggle, bool ls UNUSED)
588 {
589   td->buf_ptr = (sz == 0) ? 0 : vtop (pkt);
590
591   td->token.pid = token_to_pid (token);
592   td->token.dev_addr = dev_addr;
593   td->token.end_point = eop;
594   td->token.data_toggle = toggle;
595   td->token.maxlen = sz - 1;
596 //  td->control.ls = ls;
597
598   td->control.actual_len = 0;
599   td->control.active = 1;
600   td->flp.qh_select = 0;
601   td->flp.depth_select = 0;
602
603   /* kill packet if too many errors */
604   td->control.error_limit = 3;
605 }
606
607 static int
608 uhci_tx_pkt_now (struct uhci_eop_info *ue, int token, void *pkt, int sz)
609 {
610   struct tx_descriptor *td;
611   struct uhci_dev_info *ud;
612
613   ud = ue->ud;
614
615   uhci_lock (ud->ui);
616
617   td = uhci_acquire_td (ud->ui);
618   memset (td, 0, sizeof (struct tx_descriptor));
619   uhci_setup_td (td, ud->dev_addr, token, ue->eop, pkt, sz, ue->toggle,
620                  ud->low_speed);
621   td->control.ioc = 1;
622
623   uhci_stop (ud->ui);
624
625   uhci_add_td_to_qh (ud->qh, td);
626   td->flags = TD_FL_ASYNC | TD_FL_USED;
627
628   uhci_run (ud->ui);
629   uhci_unlock (ud->ui);
630
631   ue->toggle ^= 1;
632   return USB_HOST_ERR_NONE;
633 }
634
635 static int
636 uhci_tx_pkt_wait (struct uhci_eop_info *ue, int token, void *pkt,
637                   int max_sz, int *in_sz)
638 {
639   enum intr_level old_lvl;
640   struct tx_descriptor *td;
641   struct usb_wait w;
642   int err;
643   struct uhci_dev_info *ud;
644
645   ud = ue->ud;
646
647   uhci_lock (ud->ui);
648
649   td = uhci_acquire_td (ud->ui);
650   memset (td, 0, sizeof (struct tx_descriptor));
651
652   uhci_setup_td (td, ud->dev_addr, token, ue->eop, pkt, max_sz, ue->toggle,
653                  ud->low_speed);
654   td->control.ioc = 1;
655
656   w.td = td;
657   w.ud = ud;
658   sema_init (&w.sem, 0);
659
660   uhci_stop (ud->ui);
661
662   /* put into device's queue and add to waiting packet list */
663   uhci_add_td_to_qh (ud->qh, td);
664   td->flags = TD_FL_USED;
665
666   list_push_back (&ud->ui->waiting, &w.peers);
667
668   /* reactivate controller and wait */
669   old_lvl = intr_disable ();
670   uhci_run (ud->ui);
671   uhci_unlock (ud->ui);
672   sema_down (&w.sem);
673   intr_set_level (old_lvl);
674
675   if (in_sz != NULL)
676     {
677       if (w.td->control.actual_len == 0x7ff)
678         *in_sz = 0;
679       else
680         *in_sz = w.td->control.actual_len + 1;
681     }
682
683   if (w.td->control.bitstuff)
684     err = USB_HOST_ERR_BITSTUFF;
685   else if (w.td->control.timeout)
686     err = USB_HOST_ERR_TIMEOUT;
687   else if (w.td->control.nak)
688     err = USB_HOST_ERR_NAK;
689   else if (w.td->control.babble)
690     err = USB_HOST_ERR_BABBLE;
691   else if (w.td->control.buffer_error)
692     err = USB_HOST_ERR_BUFFER;
693   else if (w.td->control.stalled)
694     err = USB_HOST_ERR_STALL;
695   else
696     {
697       err = USB_HOST_ERR_NONE;
698       ue->toggle ^= 1;
699     }
700
701   uhci_release_td (ud->ui, td);
702
703 #if 0
704   printf ("%s to device %d:\n",
705           token == USB_TOKEN_OUT ? "OUT"
706           : token == USB_TOKEN_IN ? "IN"
707           : token == USB_TOKEN_SETUP ? "SETUP"
708           : "unknown",
709           ud->dev_addr);
710   n = (w.td->control.actual_len + 1) & 0x7ff;
711   hex_dump (0, pkt, n, true); 
712   if (err) 
713     printf ("tx_pkt_wait: err=%d\n", err);
714 #endif
715
716   return err;
717 }
718
719 static void
720 uhci_add_td_to_qh (struct queue_head *qh, struct tx_descriptor *td)
721 {
722   struct frame_list_ptr *fp;
723
724   ASSERT (td != NULL);
725
726   td->head = &qh->qelp;
727   if (qh->qelp.terminate == 1)
728     {
729       /* queue is empty */
730       td->flp.terminate = 1;
731       barrier ();
732       td->flp.flp = 0;
733       qh->qelp.flp = ptr_to_flp (vtop (td));
734       qh->qelp.terminate = 0;
735     }
736   else
737     {
738       /* find the last element in the queue */
739       fp = ptov (flp_to_ptr (qh->qelp.flp));
740       ASSERT (qh->qelp.terminate == 0);
741       while (!fp->terminate)
742         {
743           fp = ptov (flp_to_ptr (fp->flp));
744         }
745
746       /* set TD to terminated ptr */
747       td->flp = *fp;
748
749       fp->qh_select = 0;
750       fp->depth_select = 0;
751       fp->flp = ptr_to_flp (vtop (td));
752       barrier ();
753       fp->terminate = 0;
754     }
755 }
756
757 static void
758 uhci_irq (void *uhci_data)
759 {
760   struct uhci_info *ui;
761   uint16_t status;
762
763   ui = uhci_data;
764   status = pci_reg_read16 (ui->io, UHCI_REG_USBSTS);
765   if (status & USB_STATUS_PROCESSERR)
766     {
767       dump_all_qh (ui);
768       dump_regs (ui);
769       PANIC ("UHCI: Malformed schedule");
770     }
771   else if (status & USB_STATUS_HOSTERR)
772     {
773       dump_all_qh (ui);
774       dump_regs (ui);
775       PANIC ("UHCI: Host system error");
776     }
777   else if (status & USB_STATUS_INTERR)
778     {
779       /* errors */
780       pci_reg_write16 (ui->io, UHCI_REG_USBSTS, USB_STATUS_INTERR);
781     }
782
783   if (status & USB_STATUS_USBINT)
784     {
785       /* turn off interrupt */
786       uhci_stop_unlocked (ui);
787       pci_reg_write16 (ui->io, UHCI_REG_USBSTS, USB_STATUS_USBINT);
788       uhci_process_completed (ui);
789       uhci_run_unlocked (ui);
790     }
791 }
792
793 static int
794 uhci_process_completed (struct uhci_info *ui)
795 {
796   struct list_elem *li;
797   int completed = 0;
798   size_t start = 0;
799
800   li = list_begin (&ui->waiting);
801   while (li != list_end (&ui->waiting))
802     {
803       struct usb_wait *uw;
804       struct list_elem *next;
805
806       next = list_next (li);
807       uw = list_entry (li, struct usb_wait, peers);
808
809       if (!uw->td->control.active)
810         {
811           list_remove (li);
812           if (uw->td->control.error_limit == 0 || uw->td->control.stalled)
813             {
814               uhci_remove_error_td (uw->td);
815             }
816           uw->td->flags = 0;
817           sema_up (&uw->sem);
818           completed++;
819         }
820       li = next;
821     }
822
823   /* must be a completed async TD.. */
824   /* is this too time consuming? I hope not */
825   if (completed != 0)
826     return completed;
827
828   while (start < TD_ENTRIES)
829     {
830       struct tx_descriptor *td;
831
832       start = bitmap_scan (ui->td_used, start, 1, true);
833       if (start == BITMAP_ERROR)
834         break;
835
836       td = td_from_pool (ui, start);
837
838       if (!td->control.active && (td->flags & TD_FL_ASYNC) &&
839           (td->flags & TD_FL_USED))
840         {
841           if (td->control.error_limit == 0 || td->control.stalled)
842             {
843               uhci_remove_error_td (td);
844             }
845           uhci_release_td (ui, td);
846           completed++;
847         }
848       start++;
849     }
850
851   return completed;
852 }
853
854 static void
855 uhci_remove_error_td (struct tx_descriptor *td)
856 {
857   struct frame_list_ptr *fp;
858   uint32_t td_flp;
859
860   ASSERT (td->head != NULL);
861
862   fp = td->head;
863   td_flp = ptr_to_flp (vtop (td));
864   while (fp->flp != td_flp)
865     {
866       ASSERT (fp->terminate == 0);
867       fp = ptov (flp_to_ptr (fp->flp));
868     }
869   *fp = td->flp;
870 }
871
872 static int
873 uhci_detect_change (host_info hi)
874 {
875   struct uhci_info *ui;
876   int change;
877   int i;
878
879   ui = hi;
880   change = 0;
881   uhci_lock (ui);
882   for (i = 0; i < ui->num_ports; i++)
883     {
884       change = check_and_flip_change (ui, i);
885       if (change != 0)
886         break;
887     }
888   uhci_unlock (ui);
889
890   return change;
891 }
892
893 static int
894 check_and_flip_change (struct uhci_info *ui, int port)
895 {
896   int val;
897   int reg;
898
899   reg = UHCI_REG_PORTSC1 + port * 2;
900   val = pci_reg_read16 (ui->io, reg);
901   if (val & USB_PORT_CHANGE)
902     {
903       pci_reg_write16 (ui->io, reg, val & ~(USB_PORT_CHANGE));
904       return 1;
905     }
906
907   return 0;
908 }
909
910 static host_dev_info
911 uhci_create_chan (host_info hi, int dev_addr, int ver)
912 {
913   struct uhci_info *ui;
914   struct uhci_dev_info *ud;
915   int i;
916
917   ASSERT (dev_addr <= 127 && dev_addr >= 0);
918
919   ui = hi;
920
921   ud = malloc (sizeof (struct uhci_dev_info));
922   ud->dev_addr = dev_addr;
923   ud->low_speed = (ver == USB_VERSION_1_0) ? true : false;
924
925   ud->errors = 0;
926   ud->ui = ui;
927   lock_init (&ud->lock);
928
929   uhci_lock (ui);
930
931   ud->qh = qh_alloc (ud->ui);
932
933   /* queue data */
934   memset (ud->qh, 0, sizeof (*ud->qh));
935   ud->qh->qelp.terminate = 1;
936   barrier ();
937   ud->qh->qelp.flp = 0;
938   ud->qh->qelp.qh_select = 0;
939   ud->qh->qhlp.qh_select = 1;
940
941   uhci_stop (ui);
942
943   /* add to queues in frame list */
944   ud->qh->qhlp.flp = ui->frame_list[0].flp;
945   ud->qh->qhlp.terminate = ui->frame_list[0].terminate;
946   for (i = 0; i < FRAME_LIST_ENTRIES; i++)
947     {
948       ui->frame_list[i].flp = ptr_to_flp (vtop (ud->qh));
949       ui->frame_list[i].qh_select = 1;
950       ui->frame_list[i].terminate = 0;
951     }
952
953   /* add to device list */
954   list_push_back (&ui->devices, &ud->peers);
955
956   uhci_run (ui);
957   uhci_unlock (ui);
958
959   return ud;
960 }
961
962 static void
963 uhci_destroy_chan (host_dev_info hd)
964 {
965   struct uhci_dev_info *ud;
966   struct list_elem *li;
967
968   ud = hd;
969   uhci_lock (ud->ui);
970
971   uhci_stop (ud->ui);
972
973   uhci_remove_qh (ud->ui, ud->qh);
974
975   /* wake up all waiting */
976   li = list_begin (&ud->ui->waiting);
977   while (li != list_end (&ud->ui->waiting))
978     {
979       struct usb_wait *w;
980       w = list_entry (li, struct usb_wait, peers);
981       if (w->ud == ud)
982         {
983           sema_up (&w->sem);
984           list_remove (li);
985         }
986       li = list_next (li);
987     }
988
989   list_remove (&ud->peers);
990
991   uhci_run (ud->ui);
992
993   qh_free (ud->ui, ud->qh);
994
995   uhci_unlock (ud->ui);
996
997   free (ud);
998 }
999
1000 /**
1001  * Remove a queue from the UHCI schedule
1002  */
1003 static void
1004 uhci_remove_qh (struct uhci_info *ui, struct queue_head *qh)
1005 {
1006   uintptr_t qh_flp;
1007
1008   ASSERT (lock_held_by_current_thread (&ui->lock));
1009   ASSERT (uhci_is_stopped (ui));
1010   ASSERT (qh != NULL);
1011
1012   qh_flp = ptr_to_flp (vtop (qh));
1013   /* remove from host queue */
1014   if (ui->frame_list[0].flp == qh_flp)
1015     {
1016       int i;
1017       /* up top */
1018       for (i = 0; i < FRAME_LIST_ENTRIES; i++)
1019         {
1020           ui->frame_list[i] = qh->qhlp;
1021         }
1022     }
1023   else
1024     {
1025       /* in the middle */
1026       struct frame_list_ptr *fp;
1027       struct frame_list_ptr *prev;
1028
1029       fp = ptov (flp_to_ptr (ui->frame_list[0].flp));
1030       ASSERT (!fp->terminate);
1031       do
1032         {
1033           prev = fp;
1034           fp = ptov (flp_to_ptr (fp->flp));
1035         }
1036       while (!fp->terminate && fp->flp != qh_flp);
1037       *prev = qh->qhlp;
1038     }
1039 }
1040
1041 /**
1042  * Put UHCI into stop state
1043  * Wait until status register reflects setting
1044  */
1045 static void
1046 uhci_stop (struct uhci_info *ui)
1047 {
1048   ASSERT (intr_get_level () != INTR_OFF);
1049   ASSERT (lock_held_by_current_thread (&ui->lock));
1050
1051   uhci_stop_unlocked (ui);
1052 }
1053
1054 static void
1055 uhci_stop_unlocked (struct uhci_info *ui)
1056 {
1057   uint16_t cmd;
1058   int i;
1059
1060   cmd = pci_reg_read16 (ui->io, UHCI_REG_USBCMD);
1061   cmd = cmd & ~USB_CMD_RS;
1062
1063   pci_reg_write16 (ui->io, UHCI_REG_USBCMD, cmd);
1064
1065   /* wait for execution schedule to finish up */
1066   for (i = 0; i < 1000; i++)
1067     {
1068       if (uhci_is_stopped (ui))
1069         return;
1070     }
1071
1072   PANIC ("UHCI: Controller did not halt\n");
1073
1074 }
1075
1076 static void
1077 uhci_run_unlocked (struct uhci_info *ui)
1078 {
1079   uint16_t cmd;
1080   cmd = pci_reg_read16 (ui->io, UHCI_REG_USBCMD);
1081   cmd = cmd | USB_CMD_RS | USB_CMD_MAX_PACKET;
1082   pci_reg_write16 (ui->io, UHCI_REG_USBCMD, cmd);
1083 }
1084
1085 /**
1086  * Put UHCI into 'Run' State 
1087  */
1088 static void
1089 uhci_run (struct uhci_info *ui)
1090 {
1091   ASSERT (lock_held_by_current_thread (&ui->lock));
1092   uhci_run_unlocked (ui);
1093 }
1094
1095 static struct tx_descriptor *
1096 uhci_acquire_td (struct uhci_info *ui)
1097 {
1098   size_t td_idx;
1099   struct tx_descriptor *td;
1100
1101   ASSERT (lock_held_by_current_thread (&ui->lock));
1102   ASSERT (!uhci_is_stopped (ui));
1103
1104   sema_down (&ui->td_sem);
1105   td_idx = bitmap_scan_and_flip (ui->td_used, 0, 1, false);
1106   ASSERT (td_idx != BITMAP_ERROR);
1107   td = td_from_pool (ui, td_idx);
1108
1109   return td;
1110 }
1111
1112 static void
1113 uhci_modify_chan (host_dev_info hd, int dev_addr, int ver)
1114 {
1115   struct uhci_dev_info *ud;
1116
1117   ud = hd;
1118   ud->dev_addr = dev_addr;
1119   ud->low_speed = (ver == USB_VERSION_1_0) ? true : false;
1120 }
1121
1122 static void
1123 uhci_set_toggle (host_eop_info he, int toggle) 
1124 {
1125   struct uhci_eop_info *ue;
1126
1127   ue = he;
1128   ue->toggle = toggle;
1129 }
1130
1131 static void
1132 dump_all_qh (struct uhci_info *ui)
1133 {
1134   struct list_elem *li;
1135
1136   printf ("schedule: %x...", vtop (ui->frame_list));
1137   printf ("%x", *((uint32_t *) ui->frame_list));
1138   li = list_begin (&ui->devices);
1139   while (li != list_end (&ui->devices))
1140     {
1141       struct uhci_dev_info *ud;
1142       ud = list_entry (li, struct uhci_dev_info, peers);
1143       dump_qh (ud->qh);
1144       li = list_next (li);
1145     }
1146 }
1147
1148 static void
1149 dump_qh (struct queue_head *qh)
1150 {
1151   struct frame_list_ptr *fp;
1152   printf ("qh: %p %x\n", qh, vtop (qh));
1153   fp = &qh->qelp;
1154   while (!fp->terminate)
1155     {
1156       printf ("%x %x\n", *((uint32_t *) fp), *(uint32_t *) (fp + 1));
1157       fp = ptov (flp_to_ptr (fp->flp));
1158     }
1159   printf ("%x %x\n\n", *(uint32_t *) fp, *(uint32_t *) (fp + 1));
1160 }
1161
1162 static struct tx_descriptor *
1163 td_from_pool (struct uhci_info *ui, int idx)
1164 {
1165   ASSERT (idx >= 0 && idx < TD_ENTRIES);
1166   return (((void *) ui->td_pool) + idx * 32);
1167 }
1168
1169 static void
1170 uhci_detect_ports (struct uhci_info *ui)
1171 {
1172   int i;
1173   ui->num_ports = 0;
1174   for (i = 0; i < UHCI_MAX_PORTS; i++)
1175     {
1176       uint16_t status;
1177       status = pci_reg_read16 (ui->io, UHCI_REG_PORTSC1 + i * 2);
1178       if (!(status & 0x0080) || status == 0xffff)
1179         return;
1180       ui->num_ports++;
1181     }
1182 }
1183
1184 static void
1185 uhci_stall_watchdog (struct uhci_info *ui)
1186 {
1187   while (1)
1188     {
1189       int rmved;
1190       timer_msleep (1000);
1191       printf ("watchdog\n");
1192       uhci_lock (ui);
1193       uhci_stop (ui);
1194       rmved = uhci_remove_stalled (ui);
1195       if (rmved > 0)
1196         printf ("removed stalled packet in watchdog\n");
1197       uhci_run (ui);
1198       uhci_unlock (ui);
1199     }
1200 }
1201
1202 static int
1203 uhci_remove_stalled (struct uhci_info *ui)
1204 {
1205   struct list_elem *li;
1206   int rmved;
1207
1208   rmved = 0;
1209   li = list_begin (&ui->waiting);
1210
1211   intr_disable ();
1212
1213   while (li != list_end (&ui->waiting))
1214     {
1215       struct usb_wait *uw;
1216       struct list_elem *next;
1217       uint32_t ctrl;
1218
1219       next = list_next (li);
1220       uw = list_entry (li, struct usb_wait, peers);
1221
1222       if ((!uw->td->control.active && uw->td->control.stalled) ||
1223           (uw->td->control.nak))
1224         {
1225           memcpy (&ctrl, &uw->td->control, 4);
1226           printf ("CTRL: %x\n", ctrl);
1227           list_remove (li);
1228           uhci_remove_error_td (uw->td);
1229           sema_up (&uw->sem);
1230           rmved++;
1231         }
1232       li = next;
1233     }
1234
1235   intr_enable ();
1236
1237   return rmved;
1238 }
1239
1240 static void
1241 uhci_release_td (struct uhci_info *ui, struct tx_descriptor *td)
1242 {
1243   int ofs = (uintptr_t) td - (uintptr_t) ui->td_pool;
1244   int entry = ofs / 32;
1245
1246   ASSERT (entry < TD_ENTRIES);
1247
1248   td->flags = 0;
1249   bitmap_reset (ui->td_used, entry);
1250   sema_up (&ui->td_sem);
1251 }
1252
1253 static host_eop_info
1254 uhci_create_eop (host_dev_info hd, int eop, int maxpkt)
1255 {
1256   struct uhci_dev_info *ud;
1257   struct uhci_eop_info *e;
1258
1259   ud = hd;
1260
1261   e = malloc (sizeof (struct uhci_eop_info));
1262   e->eop = eop;
1263   e->ud = ud;
1264   e->maxpkt = maxpkt;
1265   e->toggle = 0;
1266
1267   return e;
1268 }
1269
1270 static void
1271 uhci_remove_eop (host_eop_info hei)
1272 {
1273   free (hei);
1274 }
1275
1276 static struct queue_head *
1277 qh_alloc (struct uhci_info *ui)
1278 {
1279   size_t qh_idx;
1280   struct queue_head *qh;
1281
1282   ASSERT (lock_held_by_current_thread (&ui->lock));
1283
1284   qh_idx = bitmap_scan_and_flip (ui->qh_used, 0, 1, false);
1285   if (qh_idx == BITMAP_ERROR)
1286     {
1287       PANIC ("UHCI: Too many queue heads in use-- runaway USB stack?\n");
1288     }
1289   qh = (void *) (((intptr_t) ui->qh_pool) + qh_idx * 16);
1290
1291   return qh;
1292 }
1293
1294 static void
1295 qh_free (struct uhci_info *ui, struct queue_head *qh)
1296 {
1297   size_t entry;
1298   ASSERT (lock_held_by_current_thread (&ui->lock));
1299
1300   entry = ((intptr_t) qh - (intptr_t) ui->qh_pool) / 16;
1301   bitmap_reset (ui->qh_used, entry);
1302 }