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