2 * Universal Host Controller Interface driver
5 * Better (any) root hub handling
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"
22 #define UHCI_MAX_PORTS 8
24 #define FRAME_LIST_ENTRIES 1024
25 #define TD_ENTRIES (4096/32) /* number of entries allocated */
26 #define QH_ENTRIES (4096/16)
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 */
39 /* in PCI config space for some reason */
40 #define UHCI_REG_LEGSUP 0xC0
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 */
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)
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 */
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 */
76 #define ptr_to_flp(x) (((uintptr_t)x) >> 4)
77 #define flp_to_ptr(x) (uintptr_t)(((uintptr_t)x) << 4)
79 /* frame structures */
85 uint32_t depth_select:1; /* only for TD */
86 uint32_t resv:1; /* zero */
87 uint32_t flp:28; /* frame list pointer */
92 uint32_t pid:8; /* packet id */
93 uint32_t dev_addr:7; /* device address */
95 uint32_t data_toggle:1;
97 uint32_t maxlen:11; /* maximum pkt length */
102 uint32_t actual_len:11;
105 /* status information */
111 uint32_t buffer_error:1;
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 */
124 #define TD_FL_ASYNC 1
125 #define TD_FL_USED 0x80000000
129 struct frame_list_ptr flp;
130 struct td_control control;
131 struct td_token token;
135 struct frame_list_ptr *head; /* for fast removal */
141 struct frame_list_ptr qhlp; /* queue head link pointer */
142 struct frame_list_ptr qelp; /* queue elem link pointer */
149 struct pci_io *io; /* pci io space */
151 struct frame_list_ptr *frame_list; /* page aligned frame list */
153 struct tx_descriptor *td_pool;
154 struct bitmap *td_used;
155 struct queue_head *qh_pool;
156 struct bitmap *qh_used;
159 uint8_t attached_ports;
161 int timeouts; /* number of timeouts */
163 struct semaphore td_sem;
164 struct list devices; /* devices on host */
165 struct list waiting; /* threads waiting */
170 struct tx_descriptor *td;
171 struct uhci_dev_info *ud;
172 struct semaphore sem;
173 struct list_elem peers;
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 */
184 struct queue_head *qh;
189 struct uhci_dev_info *ud;
191 int maxpkt; /* max packet size */
192 int toggle; /* data toggle bit for bulk transfers */
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)
201 static int token_to_pid (int token);
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);
206 static int uhci_detect_change (host_info);
209 static int uhci_tx_pkt_now (struct uhci_eop_info *ue, int token, void *pkt,
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,
217 static int uhci_process_completed (struct uhci_info *ui);
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);
224 static void qh_free (struct uhci_info *ui, struct queue_head *qh);
225 static struct queue_head *qh_alloc (struct uhci_info *ui);
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);
236 static struct tx_descriptor *td_from_pool (struct uhci_info *ui, int idx);
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) \
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);
255 static int uhci_remove_stalled (struct uhci_info *ui);
256 static void uhci_stall_watchdog (struct uhci_info *ui) UNUSED;
258 static void dump_all_qh (struct uhci_info *ui);
259 static void dump_qh (struct queue_head *qh);
261 static void dump_regs (struct uhci_info *ui);
263 void uhci_init (void);
265 static struct usb_host uhci_host = {
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
284 while ((pd = pci_get_dev_by_class (PCI_MAJOR_SERIALBUS, PCI_MINOR_USB,
285 PCI_USB_IFACE_UHCI, dev_num)) != NULL)
288 struct uhci_info *ui;
295 while ((io = pci_io_enum (pd, io)) != NULL)
297 if (pci_io_size (io) == UHCI_REGSZ)
301 /* not found, next PCI */
305 ui = uhci_create_info (io);
308 uhci_detect_ports (ui);
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");
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);
319 pci_reg_write16 (ui->io, UHCI_REG_PORTSC1, 0);
320 pci_reg_write16 (ui->io, UHCI_REG_PORTSC2, 0);
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");
327 /* deactivate SMM junk, only enable IRQ */
328 pci_write_config16 (ui->dev, UHCI_REG_LEGSUP, 0x2000);
330 asm volatile ("mfence":::"memory");
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);
338 asm volatile ("mfence":::"memory");
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);
345 pci_register_irq (pd, uhci_irq, ui);
347 usb_register_host (&uhci_host, ui);
351 #define UHCI_PORT_TIMEOUT 1000
353 uhci_enable_port (struct uhci_info *ui, int idx)
356 int time, stable_since;
360 port = UHCI_REG_PORTSC1 + idx * 2;
364 for (time = 0; ; time += 25)
367 new_status = pci_reg_read16 (ui->io, port);
368 if (status != (new_status & USB_PORT_CONNECTSTATUS)
369 || new_status & USB_PORT_CONNECTCHG)
371 if (new_status & USB_PORT_CONNECTCHG)
372 pci_reg_write16 (ui->io, port, (new_status & ~0xe80a) | USB_PORT_CONNECTCHG);
374 status = new_status & USB_PORT_CONNECTSTATUS;
376 else if (time - stable_since >= 100)
378 else if (time >= 1500)
383 if (!(status & USB_PORT_CONNECTSTATUS))
386 for (count = 0; count < 3; count++)
388 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
389 pci_reg_write16 (ui->io, port, status | USB_PORT_RESET);
392 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
393 pci_reg_write16 (ui->io, port, status & ~USB_PORT_RESET);
396 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
397 pci_reg_write16 (ui->io, port, status & ~(USB_PORT_CONNECTCHG | USB_PORT_CHANGE));
399 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
400 pci_reg_write16 (ui->io, port, status | USB_PORT_ENABLE);
402 status = pci_reg_read16 (ui->io, port);
403 if (status & USB_PORT_ENABLE)
407 if (!(status & USB_PORT_CONNECTSTATUS))
409 pci_reg_write16 (ui->io, port, 0);
418 dump_regs (struct uhci_info *ui)
420 int regs[] = { 0, 2, 4, 6, 8, 0xc, 0x10, 0x12 };
421 int sz[] = { 2, 2, 2, 2, 4, 2, 2, 2 };
423 { "cmd", "sts", "intr", "frnum", "base", "sofmod", "portsc1", "portsc2" };
425 printf ("UHCI registers:\n");
426 for (i = 0; i < 8; i++)
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]));
436 uhci_destroy_info (struct uhci_info *ui)
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);
446 static struct uhci_info *
447 uhci_create_info (struct pci_io *io)
449 struct uhci_info *ui;
452 ui = malloc (sizeof (struct uhci_info));
455 lock_init (&ui->lock);
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;
463 /* permit 3 timeouts */
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);
473 list_init (&ui->devices);
474 list_init (&ui->waiting);
481 uhci_tx_pkt (host_eop_info hei, int token, void *pkt, int min_sz,
482 int max_sz, int *in_sz, bool wait)
484 struct uhci_eop_info *ue;
485 struct uhci_dev_info *ud;
487 ASSERT (min_sz <= max_sz);
489 /* can't have page overlap */
493 ASSERT (pg_no (pkt + max_sz - 1) == pg_no (pkt));
499 /* don't bother if ports are down */
500 if (ud->ui->attached_ports == 0)
502 return USB_HOST_ERR_NODEV;
505 /* setup token acts to synchronize data toggle */
506 if (token == USB_TOKEN_SETUP)
511 return uhci_tx_pkt_bulk (ue, token, pkt, max_sz, in_sz);
519 return uhci_tx_pkt_now (ue, token, pkt, max_sz);
523 return uhci_tx_pkt_wait (ue, token, pkt, max_sz, in_sz);
531 uhci_tx_pkt_bulk (struct uhci_eop_info *ue, int token, void *buf,
534 /* XXX this can be made to use async packets */
538 /* send data in max_pkt sized chunks */
547 to_tx = (left > ue->maxpkt) ? ue->maxpkt : left;
548 wait_on_pkt = (left <= to_tx) ? true : false;
551 err = uhci_tx_pkt (ue, token, buf + bytes, 0, to_tx, &pkt_txed,
566 return USB_HOST_ERR_NONE;
570 token_to_pid (int token)
574 case USB_TOKEN_SETUP:
575 return USB_PID_SETUP;
581 PANIC ("Unknown USB token\n");
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)
589 td->buf_ptr = (sz == 0) ? 0 : vtop (pkt);
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;
598 td->control.actual_len = 0;
599 td->control.active = 1;
600 td->flp.qh_select = 0;
601 td->flp.depth_select = 0;
603 /* kill packet if too many errors */
604 td->control.error_limit = 3;
608 uhci_tx_pkt_now (struct uhci_eop_info *ue, int token, void *pkt, int sz)
610 struct tx_descriptor *td;
611 struct uhci_dev_info *ud;
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,
625 uhci_add_td_to_qh (ud->qh, td);
626 td->flags = TD_FL_ASYNC | TD_FL_USED;
629 uhci_unlock (ud->ui);
632 return USB_HOST_ERR_NONE;
636 uhci_tx_pkt_wait (struct uhci_eop_info *ue, int token, void *pkt,
637 int max_sz, int *in_sz)
639 enum intr_level old_lvl;
640 struct tx_descriptor *td;
643 struct uhci_dev_info *ud;
649 td = uhci_acquire_td (ud->ui);
650 memset (td, 0, sizeof (struct tx_descriptor));
652 uhci_setup_td (td, ud->dev_addr, token, ue->eop, pkt, max_sz, ue->toggle,
658 sema_init (&w.sem, 0);
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;
666 list_push_back (&ud->ui->waiting, &w.peers);
668 /* reactivate controller and wait */
669 old_lvl = intr_disable ();
671 uhci_unlock (ud->ui);
673 intr_set_level (old_lvl);
677 if (w.td->control.actual_len == 0x7ff)
680 *in_sz = w.td->control.actual_len + 1;
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;
697 err = USB_HOST_ERR_NONE;
701 uhci_release_td (ud->ui, td);
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"
710 n = (w.td->control.actual_len + 1) & 0x7ff;
711 hex_dump (0, pkt, n, true);
713 printf ("tx_pkt_wait: err=%d\n", err);
720 uhci_add_td_to_qh (struct queue_head *qh, struct tx_descriptor *td)
722 struct frame_list_ptr *fp;
726 td->head = &qh->qelp;
727 if (qh->qelp.terminate == 1)
730 td->flp.terminate = 1;
733 qh->qelp.flp = ptr_to_flp (vtop (td));
734 qh->qelp.terminate = 0;
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)
743 fp = ptov (flp_to_ptr (fp->flp));
746 /* set TD to terminated ptr */
750 fp->depth_select = 0;
751 fp->flp = ptr_to_flp (vtop (td));
758 uhci_irq (void *uhci_data)
760 struct uhci_info *ui;
764 status = pci_reg_read16 (ui->io, UHCI_REG_USBSTS);
765 if (status & USB_STATUS_PROCESSERR)
769 PANIC ("UHCI: Malformed schedule");
771 else if (status & USB_STATUS_HOSTERR)
775 PANIC ("UHCI: Host system error");
777 else if (status & USB_STATUS_INTERR)
780 pci_reg_write16 (ui->io, UHCI_REG_USBSTS, USB_STATUS_INTERR);
783 if (status & USB_STATUS_USBINT)
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);
794 uhci_process_completed (struct uhci_info *ui)
796 struct list_elem *li;
800 li = list_begin (&ui->waiting);
801 while (li != list_end (&ui->waiting))
804 struct list_elem *next;
806 next = list_next (li);
807 uw = list_entry (li, struct usb_wait, peers);
809 if (!uw->td->control.active)
812 if (uw->td->control.error_limit == 0 || uw->td->control.stalled)
814 uhci_remove_error_td (uw->td);
823 /* must be a completed async TD.. */
824 /* is this too time consuming? I hope not */
828 while (start < TD_ENTRIES)
830 struct tx_descriptor *td;
832 start = bitmap_scan (ui->td_used, start, 1, true);
833 if (start == BITMAP_ERROR)
836 td = td_from_pool (ui, start);
838 if (!td->control.active && (td->flags & TD_FL_ASYNC) &&
839 (td->flags & TD_FL_USED))
841 if (td->control.error_limit == 0 || td->control.stalled)
843 uhci_remove_error_td (td);
845 uhci_release_td (ui, td);
855 uhci_remove_error_td (struct tx_descriptor *td)
857 struct frame_list_ptr *fp;
860 ASSERT (td->head != NULL);
863 td_flp = ptr_to_flp (vtop (td));
864 while (fp->flp != td_flp)
866 ASSERT (fp->terminate == 0);
867 fp = ptov (flp_to_ptr (fp->flp));
873 uhci_detect_change (host_info hi)
875 struct uhci_info *ui;
882 for (i = 0; i < ui->num_ports; i++)
884 change = check_and_flip_change (ui, i);
894 check_and_flip_change (struct uhci_info *ui, int port)
899 reg = UHCI_REG_PORTSC1 + port * 2;
900 val = pci_reg_read16 (ui->io, reg);
901 if (val & USB_PORT_CHANGE)
903 pci_reg_write16 (ui->io, reg, val & ~(USB_PORT_CHANGE));
911 uhci_create_chan (host_info hi, int dev_addr, int ver)
913 struct uhci_info *ui;
914 struct uhci_dev_info *ud;
917 ASSERT (dev_addr <= 127 && dev_addr >= 0);
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;
927 lock_init (&ud->lock);
931 ud->qh = qh_alloc (ud->ui);
934 memset (ud->qh, 0, sizeof (*ud->qh));
935 ud->qh->qelp.terminate = 1;
937 ud->qh->qelp.flp = 0;
938 ud->qh->qelp.qh_select = 0;
939 ud->qh->qhlp.qh_select = 1;
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++)
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;
953 /* add to device list */
954 list_push_back (&ui->devices, &ud->peers);
963 uhci_destroy_chan (host_dev_info hd)
965 struct uhci_dev_info *ud;
966 struct list_elem *li;
973 uhci_remove_qh (ud->ui, ud->qh);
975 /* wake up all waiting */
976 li = list_begin (&ud->ui->waiting);
977 while (li != list_end (&ud->ui->waiting))
980 w = list_entry (li, struct usb_wait, peers);
989 list_remove (&ud->peers);
993 qh_free (ud->ui, ud->qh);
995 uhci_unlock (ud->ui);
1001 * Remove a queue from the UHCI schedule
1004 uhci_remove_qh (struct uhci_info *ui, struct queue_head *qh)
1008 ASSERT (lock_held_by_current_thread (&ui->lock));
1009 ASSERT (uhci_is_stopped (ui));
1010 ASSERT (qh != NULL);
1012 qh_flp = ptr_to_flp (vtop (qh));
1013 /* remove from host queue */
1014 if (ui->frame_list[0].flp == qh_flp)
1018 for (i = 0; i < FRAME_LIST_ENTRIES; i++)
1020 ui->frame_list[i] = qh->qhlp;
1026 struct frame_list_ptr *fp;
1027 struct frame_list_ptr *prev;
1029 fp = ptov (flp_to_ptr (ui->frame_list[0].flp));
1030 ASSERT (!fp->terminate);
1034 fp = ptov (flp_to_ptr (fp->flp));
1036 while (!fp->terminate && fp->flp != qh_flp);
1042 * Put UHCI into stop state
1043 * Wait until status register reflects setting
1046 uhci_stop (struct uhci_info *ui)
1048 ASSERT (intr_get_level () != INTR_OFF);
1049 ASSERT (lock_held_by_current_thread (&ui->lock));
1051 uhci_stop_unlocked (ui);
1055 uhci_stop_unlocked (struct uhci_info *ui)
1060 cmd = pci_reg_read16 (ui->io, UHCI_REG_USBCMD);
1061 cmd = cmd & ~USB_CMD_RS;
1063 pci_reg_write16 (ui->io, UHCI_REG_USBCMD, cmd);
1065 /* wait for execution schedule to finish up */
1066 for (i = 0; i < 1000; i++)
1068 if (uhci_is_stopped (ui))
1072 PANIC ("UHCI: Controller did not halt\n");
1077 uhci_run_unlocked (struct uhci_info *ui)
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);
1086 * Put UHCI into 'Run' State
1089 uhci_run (struct uhci_info *ui)
1091 ASSERT (lock_held_by_current_thread (&ui->lock));
1092 uhci_run_unlocked (ui);
1095 static struct tx_descriptor *
1096 uhci_acquire_td (struct uhci_info *ui)
1099 struct tx_descriptor *td;
1101 ASSERT (lock_held_by_current_thread (&ui->lock));
1102 ASSERT (!uhci_is_stopped (ui));
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);
1113 uhci_modify_chan (host_dev_info hd, int dev_addr, int ver)
1115 struct uhci_dev_info *ud;
1118 ud->dev_addr = dev_addr;
1119 ud->low_speed = (ver == USB_VERSION_1_0) ? true : false;
1123 uhci_set_toggle (host_eop_info he, int toggle)
1125 struct uhci_eop_info *ue;
1128 ue->toggle = toggle;
1132 dump_all_qh (struct uhci_info *ui)
1134 struct list_elem *li;
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))
1141 struct uhci_dev_info *ud;
1142 ud = list_entry (li, struct uhci_dev_info, peers);
1144 li = list_next (li);
1149 dump_qh (struct queue_head *qh)
1151 struct frame_list_ptr *fp;
1152 printf ("qh: %p %x\n", qh, vtop (qh));
1154 while (!fp->terminate)
1156 printf ("%x %x\n", *((uint32_t *) fp), *(uint32_t *) (fp + 1));
1157 fp = ptov (flp_to_ptr (fp->flp));
1159 printf ("%x %x\n\n", *(uint32_t *) fp, *(uint32_t *) (fp + 1));
1162 static struct tx_descriptor *
1163 td_from_pool (struct uhci_info *ui, int idx)
1165 ASSERT (idx >= 0 && idx < TD_ENTRIES);
1166 return (((void *) ui->td_pool) + idx * 32);
1170 uhci_detect_ports (struct uhci_info *ui)
1174 for (i = 0; i < UHCI_MAX_PORTS; i++)
1177 status = pci_reg_read16 (ui->io, UHCI_REG_PORTSC1 + i * 2);
1178 if (!(status & 0x0080) || status == 0xffff)
1185 uhci_stall_watchdog (struct uhci_info *ui)
1190 timer_msleep (1000);
1191 printf ("watchdog\n");
1194 rmved = uhci_remove_stalled (ui);
1196 printf ("removed stalled packet in watchdog\n");
1203 uhci_remove_stalled (struct uhci_info *ui)
1205 struct list_elem *li;
1209 li = list_begin (&ui->waiting);
1213 while (li != list_end (&ui->waiting))
1215 struct usb_wait *uw;
1216 struct list_elem *next;
1219 next = list_next (li);
1220 uw = list_entry (li, struct usb_wait, peers);
1222 if ((!uw->td->control.active && uw->td->control.stalled) ||
1223 (uw->td->control.nak))
1225 memcpy (&ctrl, &uw->td->control, 4);
1226 printf ("CTRL: %x\n", ctrl);
1228 uhci_remove_error_td (uw->td);
1241 uhci_release_td (struct uhci_info *ui, struct tx_descriptor *td)
1243 int ofs = (uintptr_t) td - (uintptr_t) ui->td_pool;
1244 int entry = ofs / 32;
1246 ASSERT (entry < TD_ENTRIES);
1249 bitmap_reset (ui->td_used, entry);
1250 sema_up (&ui->td_sem);
1253 static host_eop_info
1254 uhci_create_eop (host_dev_info hd, int eop, int maxpkt)
1256 struct uhci_dev_info *ud;
1257 struct uhci_eop_info *e;
1261 e = malloc (sizeof (struct uhci_eop_info));
1271 uhci_remove_eop (host_eop_info hei)
1276 static struct queue_head *
1277 qh_alloc (struct uhci_info *ui)
1280 struct queue_head *qh;
1282 ASSERT (lock_held_by_current_thread (&ui->lock));
1284 qh_idx = bitmap_scan_and_flip (ui->qh_used, 0, 1, false);
1285 if (qh_idx == BITMAP_ERROR)
1287 PANIC ("UHCI: Too many queue heads in use-- runaway USB stack?\n");
1289 qh = (void *) (((intptr_t) ui->qh_pool) + qh_idx * 16);
1295 qh_free (struct uhci_info *ui, struct queue_head *qh)
1298 ASSERT (lock_held_by_current_thread (&ui->lock));
1300 entry = ((intptr_t) qh - (intptr_t) ui->qh_pool) / 16;
1301 bitmap_reset (ui->qh_used, entry);