00001
00009 #include <round.h>
00010 #include <stdio.h>
00011 #include <string.h>
00012 #include <kernel/bitmap.h>
00013 #include "threads/pte.h"
00014 #include "threads/malloc.h"
00015 #include "threads/palloc.h"
00016 #include "threads/synch.h"
00017 #include "threads/interrupt.h"
00018 #include "threads/thread.h"
00019 #include "devices/pci.h"
00020 #include "devices/usb.h"
00021 #include "devices/timer.h"
00022
00023 #define UHCI_MAX_PORTS 8
00024
00025 #define FRAME_LIST_ENTRIES 1024
00026 #define TD_ENTRIES (4096/32)
00027 #define QH_ENTRIES (4096/16)
00028
00029
00030 #define UHCI_REG_USBCMD 0x00
00031 #define UHCI_REG_USBSTS 0x02
00032 #define UHCI_REG_USBINTR 0x04
00033 #define UHCI_REG_FRNUM 0x06
00034 #define UHCI_REG_FLBASEADD 0x08
00035 #define UHCI_REG_SOFMOD 0x0c
00036 #define UHCI_REG_PORTSC1 0x10
00037 #define UHCI_REG_PORTSC2 0x12
00038 #define UHCI_REGSZ 0x20
00039
00040
00041 #define UHCI_REG_LEGSUP 0xC0
00042
00043
00044
00045 #define USB_CMD_MAX_PACKET (1 << 7)
00046 #define USB_CMD_CONFIGURE (1 << 6)
00047 #define USB_CMD_FGR (1 << 4)
00048 #define USB_CMD_EGSM (1 << 3)
00049 #define USB_CMD_GRESET (1 << 2)
00050 #define USB_CMD_HCRESET (1 << 1)
00051 #define USB_CMD_RS (1 << 0)
00052
00053
00054 #define USB_STATUS_HALTED (1 << 5)
00055 #define USB_STATUS_PROCESSERR (1 << 4)
00056 #define USB_STATUS_HOSTERR (1 << 3)
00057 #define USB_STATUS_RESUME (1 << 2)
00058 #define USB_STATUS_INTERR (1 << 1)
00059 #define USB_STATUS_USBINT (1 << 0)
00060
00061
00062 #define USB_INTR_SHORT (1 << 3)
00063 #define USB_INTR_IOC (1 << 2)
00064 #define USB_INTR_RESUME (1 << 1)
00065 #define USB_INTR_TIMEOUT (1 << 0)
00066
00067
00068 #define USB_PORT_SUSPEND (1 << 12)
00069 #define USB_PORT_RESET (1 << 9)
00070 #define USB_PORT_LOWSPEED (1 << 8)
00071 #define USB_PORT_RESUMED (1 << 6)
00072 #define USB_PORT_CHANGE (1 << 3)
00073 #define USB_PORT_ENABLE (1 << 2)
00074 #define USB_PORT_CONNECTCHG (1 << 1)
00075 #define USB_PORT_CONNECTSTATUS (1 << 0)
00076
00077 #define ptr_to_flp(x) (((uintptr_t)x) >> 4)
00078 #define flp_to_ptr(x) (uintptr_t)(((uintptr_t)x) << 4)
00079
00080
00081 #pragma pack(1)
00082 struct frame_list_ptr
00083 {
00084 uint32_t terminate:1;
00085 uint32_t qh_select:1;
00086 uint32_t depth_select:1;
00087 uint32_t resv:1;
00088 uint32_t flp:28;
00089 };
00090
00091 struct td_token
00092 {
00093 uint32_t pid:8;
00094 uint32_t dev_addr:7;
00095 uint32_t end_point:4;
00096 uint32_t data_toggle:1;
00097 uint32_t resv:1;
00098 uint32_t maxlen:11;
00099 };
00100
00101 struct td_control
00102 {
00103 uint32_t actual_len:11;
00104 uint32_t resv1:5;
00105
00106
00107 uint32_t resv2:1;
00108 uint32_t bitstuff:1;
00109 uint32_t timeout:1;
00110 uint32_t nak:1;
00111 uint32_t babble:1;
00112 uint32_t buffer_error:1;
00113 uint32_t stalled:1;
00114 uint32_t active:1;
00115
00116
00117 uint32_t ioc:1;
00118 uint32_t ios:1;
00119 uint32_t ls:1;
00120 uint32_t error_limit:2;
00121 uint32_t spd:1;
00122 uint32_t resv3:2;
00123 };
00124
00125 #define TD_FL_ASYNC 1
00126 #define TD_FL_USED 0x80000000
00127
00128 struct tx_descriptor
00129 {
00130 struct frame_list_ptr flp;
00131 struct td_control control;
00132 struct td_token token;
00133 uint32_t buf_ptr;
00134
00135
00136 struct frame_list_ptr *head;
00137 uint32_t flags;
00138 };
00139
00140 struct queue_head
00141 {
00142 struct frame_list_ptr qhlp;
00143 struct frame_list_ptr qelp;
00144 };
00145 #pragma pack()
00146
00147 struct uhci_info
00148 {
00149 struct pci_dev *dev;
00150 struct pci_io *io;
00151 struct lock lock;
00152 struct frame_list_ptr *frame_list;
00153
00154 struct tx_descriptor *td_pool;
00155 struct bitmap *td_used;
00156 struct queue_head *qh_pool;
00157 struct bitmap *qh_used;
00158
00159 uint8_t num_ports;
00160 uint8_t attached_ports;
00161
00162 int timeouts;
00163
00164 struct semaphore td_sem;
00165 struct list devices;
00166 struct list waiting;
00167 };
00168
00169 struct usb_wait
00170 {
00171 struct tx_descriptor *td;
00172 struct uhci_dev_info *ud;
00173 struct semaphore sem;
00174 struct list_elem peers;
00175 };
00176
00177 struct uhci_dev_info
00178 {
00179 struct uhci_info *ui;
00180 bool low_speed;
00181 int dev_addr;
00182 int errors;
00183 struct list_elem peers;
00184 struct lock lock;
00185 struct queue_head *qh;
00186 };
00187
00188 struct uhci_eop_info
00189 {
00190 struct uhci_dev_info *ud;
00191 int eop;
00192 int maxpkt;
00193 int toggle;
00194 };
00195
00196 #define uhci_lock(x) lock_acquire(&(x)->lock)
00197 #define uhci_unlock(x) lock_release(&(x)->lock)
00198 #define dev_lock(x) lock_acquire(&(x)->lock)
00199 #define dev_unlock(x) lock_release(&(x)->lock)
00200
00201
00202 static int token_to_pid (int token);
00203
00204 static int uhci_tx_pkt (host_eop_info eop, int token, void *pkt,
00205 int min_sz, int max_sz, int *in_sz, bool wait);
00206
00207 static int uhci_detect_change (host_info);
00208
00209
00210 static int uhci_tx_pkt_now (struct uhci_eop_info *ue, int token, void *pkt,
00211 int sz);
00212 static int uhci_tx_pkt_wait (struct uhci_eop_info *ue, int token, void *pkt,
00213 int max_sz, int *in_sz);
00214 static int uhci_tx_pkt_bulk (struct uhci_eop_info *ue, int token, void *buf,
00215 int sz, int *tx);
00216
00217
00218 static int uhci_process_completed (struct uhci_info *ui);
00219
00220 static struct tx_descriptor *uhci_acquire_td (struct uhci_info *);
00221 static void uhci_release_td (struct uhci_info *, struct tx_descriptor *);
00222 static void uhci_remove_qh (struct uhci_info *ui, struct queue_head *qh);
00223
00224
00225 static void qh_free (struct uhci_info *ui, struct queue_head *qh);
00226 static struct queue_head *qh_alloc (struct uhci_info *ui);
00227
00228 static struct uhci_info *uhci_create_info (struct pci_io *io);
00229 static void uhci_destroy_info (struct uhci_info *ui) UNUSED;
00230 static host_eop_info uhci_create_eop (host_dev_info hd, int eop, int maxpkt);
00231 static void uhci_remove_eop (host_eop_info hei);
00232 static host_dev_info uhci_create_chan (host_info hi, int dev_addr, int ver);
00233 static void uhci_destroy_chan (host_dev_info);
00234 static void uhci_modify_chan (host_dev_info, int dev_addr, int ver);
00235 static void uhci_set_toggle (host_eop_info, int toggle);
00236
00237 static struct tx_descriptor *td_from_pool (struct uhci_info *ui, int idx);
00238
00239 static int check_and_flip_change (struct uhci_info *ui, int reg);
00240 static void uhci_stop (struct uhci_info *ui);
00241 static void uhci_run (struct uhci_info *ui);
00242 static void uhci_stop_unlocked (struct uhci_info *ui);
00243 static void uhci_run_unlocked (struct uhci_info *ui);
00244 #define uhci_is_stopped(x) (pci_reg_read16((x)->io, UHCI_REG_USBSTS) \
00245 & USB_STATUS_HALTED)
00246 #define uhci_port_enabled(x, y) (pci_reg_read16((x)->io, (y)) & USB_PORT_ENABLE)
00247 static void uhci_add_td_to_qh (struct queue_head *qh,
00248 struct tx_descriptor *td);
00249 static void uhci_remove_error_td (struct tx_descriptor *td);
00250 static void uhci_setup_td (struct tx_descriptor *td, int dev_addr, int token,
00251 int eop, void *pkt, int sz, int toggle, bool ls);
00252 static int uhci_enable_port (struct uhci_info *ui, int port);
00253 static void uhci_irq (void *uhci_data);
00254 static void uhci_detect_ports (struct uhci_info *ui);
00255
00256 static int uhci_remove_stalled (struct uhci_info *ui);
00257 static void uhci_stall_watchdog (struct uhci_info *ui) UNUSED;
00258
00259 static void dump_all_qh (struct uhci_info *ui);
00260 static void dump_qh (struct queue_head *qh);
00261
00262 static void dump_regs (struct uhci_info *ui);
00263
00264 void uhci_init (void);
00265
00266 static struct usb_host uhci_host = {
00267 .name = "UHCI",
00268 .tx_pkt = uhci_tx_pkt,
00269 .detect_change = uhci_detect_change,
00270 .create_dev_channel = uhci_create_chan,
00271 .remove_dev_channel = uhci_destroy_chan,
00272 .modify_dev_channel = uhci_modify_chan,
00273 .set_toggle = uhci_set_toggle,
00274 .create_eop = uhci_create_eop,
00275 .remove_eop = uhci_remove_eop
00276 };
00277
00278 void
00279 uhci_init (void)
00280 {
00281 struct pci_dev *pd;
00282 int dev_num;
00283
00284 dev_num = 0;
00285 while ((pd = pci_get_dev_by_class (PCI_MAJOR_SERIALBUS, PCI_MINOR_USB,
00286 PCI_USB_IFACE_UHCI, dev_num)) != NULL)
00287 {
00288 struct pci_io *io;
00289 struct uhci_info *ui;
00290 int i;
00291
00292 dev_num++;
00293
00294
00295 io = NULL;
00296 while ((io = pci_io_enum (pd, io)) != NULL)
00297 {
00298 if (pci_io_size (io) == UHCI_REGSZ)
00299 break;
00300 }
00301
00302
00303 if (io == NULL)
00304 continue;
00305
00306 ui = uhci_create_info (io);
00307 ui->dev = pd;
00308
00309 uhci_detect_ports (ui);
00310
00311 pci_write_config16 (ui->dev, UHCI_REG_LEGSUP, 0x8f00);
00312 pci_reg_write16 (ui->io, UHCI_REG_USBCMD, USB_CMD_HCRESET);
00313 asm volatile ("mfence":::"memory");
00314 timer_usleep (5);
00315 if (pci_reg_read16 (ui->io, UHCI_REG_USBCMD) & USB_CMD_HCRESET)
00316 printf ("reset failed!\n");
00317 pci_reg_write16 (ui->io, UHCI_REG_USBINTR, 0);
00318 pci_reg_write16 (ui->io, UHCI_REG_USBCMD, 0);
00319
00320 pci_reg_write16 (ui->io, UHCI_REG_PORTSC1, 0);
00321 pci_reg_write16 (ui->io, UHCI_REG_PORTSC2, 0);
00322
00323 pci_reg_write8 (ui->io, UHCI_REG_SOFMOD, 64);
00324 pci_reg_write32 (ui->io, UHCI_REG_FLBASEADD, vtop (ui->frame_list));
00325 pci_reg_write16 (ui->io, UHCI_REG_FRNUM, 0);
00326 asm volatile ("mfence":::"memory");
00327
00328
00329 pci_write_config16 (ui->dev, UHCI_REG_LEGSUP, 0x2000);
00330
00331 asm volatile ("mfence":::"memory");
00332
00333 pci_reg_write16 (ui->io, UHCI_REG_USBCMD,
00334 USB_CMD_RS | USB_CMD_CONFIGURE | USB_CMD_MAX_PACKET);
00335 pci_reg_write16 (ui->io, UHCI_REG_USBINTR,
00336 USB_INTR_SHORT | USB_INTR_IOC |
00337 USB_INTR_TIMEOUT | USB_INTR_RESUME);
00338
00339 asm volatile ("mfence":::"memory");
00340
00341 printf ("UHCI: Enabling %d root ports\n", ui->num_ports);
00342 ui->attached_ports = 0;
00343 for (i = 0; i < ui->num_ports; i++)
00344 ui->attached_ports += uhci_enable_port (ui, i);
00345
00346 pci_register_irq (pd, uhci_irq, ui);
00347
00348 usb_register_host (&uhci_host, ui);
00349 }
00350 }
00351
00352 #define UHCI_PORT_TIMEOUT 1000
00353 static int
00354 uhci_enable_port (struct uhci_info *ui, int idx)
00355 {
00356 uint16_t status;
00357 int time, stable_since;
00358 int count;
00359 int port;
00360
00361 port = UHCI_REG_PORTSC1 + idx * 2;
00362
00363 status = 0xffff;
00364 stable_since = 0;
00365 for (time = 0; ; time += 25)
00366 {
00367 uint16_t new_status;
00368 new_status = pci_reg_read16 (ui->io, port);
00369 if (status != (new_status & USB_PORT_CONNECTSTATUS)
00370 || new_status & USB_PORT_CONNECTCHG)
00371 {
00372 if (new_status & USB_PORT_CONNECTCHG)
00373 pci_reg_write16 (ui->io, port, (new_status & ~0xe80a) | USB_PORT_CONNECTCHG);
00374 stable_since = time;
00375 status = new_status & USB_PORT_CONNECTSTATUS;
00376 }
00377 else if (time - stable_since >= 100)
00378 break;
00379 else if (time >= 1500)
00380 return 0;
00381 timer_msleep (25);
00382 }
00383
00384 if (!(status & USB_PORT_CONNECTSTATUS))
00385 return 0;
00386
00387 for (count = 0; count < 3; count++)
00388 {
00389 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
00390 pci_reg_write16 (ui->io, port, status | USB_PORT_RESET);
00391 timer_msleep (50);
00392
00393 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
00394 pci_reg_write16 (ui->io, port, status & ~USB_PORT_RESET);
00395 timer_usleep (10);
00396
00397 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
00398 pci_reg_write16 (ui->io, port, status & ~(USB_PORT_CONNECTCHG | USB_PORT_CHANGE));
00399
00400 status = pci_reg_read16 (ui->io, port) & ~0xe80a;
00401 pci_reg_write16 (ui->io, port, status | USB_PORT_ENABLE);
00402
00403 status = pci_reg_read16 (ui->io, port);
00404 if (status & USB_PORT_ENABLE)
00405 break;
00406 }
00407
00408 if (!(status & USB_PORT_CONNECTSTATUS))
00409 {
00410 pci_reg_write16 (ui->io, port, 0);
00411 return 0;
00412 }
00413
00414 return 1;
00415 }
00416
00417
00418 static void
00419 dump_regs (struct uhci_info *ui)
00420 {
00421 int regs[] = { 0, 2, 4, 6, 8, 0xc, 0x10, 0x12 };
00422 int sz[] = { 2, 2, 2, 2, 4, 2, 2, 2 };
00423 char *name[] =
00424 { "cmd", "sts", "intr", "frnum", "base", "sofmod", "portsc1", "portsc2" };
00425 int i;
00426 printf ("UHCI registers:\n");
00427 for (i = 0; i < 8; i++)
00428 {
00429 printf ("%s: %x\n", name[i], (sz[i] == 2) ?
00430 pci_reg_read16 (ui->io, regs[i]) :
00431 pci_reg_read32 (ui->io, regs[i]));
00432
00433 }
00434 }
00435
00436 static void
00437 uhci_destroy_info (struct uhci_info *ui)
00438 {
00439 palloc_free_page (ui->frame_list);
00440 palloc_free_page (ui->td_pool);
00441 palloc_free_page (ui->qh_pool);
00442 bitmap_destroy (ui->qh_used);
00443 bitmap_destroy (ui->td_used);
00444 free (ui);
00445 }
00446
00447 static struct uhci_info *
00448 uhci_create_info (struct pci_io *io)
00449 {
00450 struct uhci_info *ui;
00451 int i;
00452
00453 ui = malloc (sizeof (struct uhci_info));
00454
00455 ui->io = io;
00456 lock_init (&ui->lock);
00457
00458
00459 ui->frame_list = palloc_get_page (PAL_ASSERT | PAL_NOCACHE);
00460 memset (ui->frame_list, 0, PGSIZE);
00461 for (i = 0; i < FRAME_LIST_ENTRIES; i++)
00462 ui->frame_list[i].terminate = 1;
00463
00464
00465 ui->timeouts = 3;
00466
00467
00468 ui->td_pool = palloc_get_page (PAL_ASSERT | PAL_NOCACHE);
00469 ui->td_used = bitmap_create (TD_ENTRIES);
00470 ui->qh_pool = palloc_get_page (PAL_ASSERT | PAL_NOCACHE);
00471 ui->qh_used = bitmap_create (QH_ENTRIES);
00472 sema_init (&ui->td_sem, TD_ENTRIES);
00473
00474 list_init (&ui->devices);
00475 list_init (&ui->waiting);
00476
00477 return ui;
00478 }
00479
00480
00481 static int
00482 uhci_tx_pkt (host_eop_info hei, int token, void *pkt, int min_sz,
00483 int max_sz, int *in_sz, bool wait)
00484 {
00485 struct uhci_eop_info *ue;
00486 struct uhci_dev_info *ud;
00487
00488 ASSERT (min_sz <= max_sz);
00489
00490
00491 if (pkt != NULL)
00492 {
00493 ASSERT (max_sz > 0);
00494 ASSERT (pg_no (pkt + max_sz - 1) == pg_no (pkt));
00495 }
00496
00497 ue = hei;
00498 ud = ue->ud;
00499
00500
00501 if (ud->ui->attached_ports == 0)
00502 {
00503 return USB_HOST_ERR_NODEV;
00504 }
00505
00506
00507 if (token == USB_TOKEN_SETUP)
00508 ue->toggle = 0;
00509
00510 if (min_sz != 0)
00511 {
00512 return uhci_tx_pkt_bulk (ue, token, pkt, max_sz, in_sz);
00513 }
00514 else
00515 {
00516 if (wait == false)
00517 {
00518 if (in_sz != NULL)
00519 *in_sz = max_sz;
00520 return uhci_tx_pkt_now (ue, token, pkt, max_sz);
00521 }
00522 else
00523 {
00524 return uhci_tx_pkt_wait (ue, token, pkt, max_sz, in_sz);
00525 }
00526 }
00527
00528 return 0;
00529 }
00530
00531 static int
00532 uhci_tx_pkt_bulk (struct uhci_eop_info *ue, int token, void *buf,
00533 int sz, int *tx)
00534 {
00535
00536 int bytes = 0;
00537 int txed = 0;
00538
00539
00540 while (bytes < sz)
00541 {
00542 int to_tx, pkt_txed;
00543 int left;
00544 int err;
00545 bool wait_on_pkt;
00546
00547 left = sz - bytes;
00548 to_tx = (left > ue->maxpkt) ? ue->maxpkt : left;
00549 wait_on_pkt = (left <= to_tx) ? true : false;
00550
00551 pkt_txed = 0;
00552 err = uhci_tx_pkt (ue, token, buf + bytes, 0, to_tx, &pkt_txed,
00553 wait_on_pkt);
00554 if (err)
00555 {
00556 if (tx != NULL)
00557 *tx = txed;
00558 return err;
00559 }
00560 txed += pkt_txed;
00561 bytes += pkt_txed;
00562 }
00563
00564 if (tx != NULL)
00565 *tx = txed;
00566
00567 return USB_HOST_ERR_NONE;
00568 }
00569
00570 static int
00571 token_to_pid (int token)
00572 {
00573 switch (token)
00574 {
00575 case USB_TOKEN_SETUP:
00576 return USB_PID_SETUP;
00577 case USB_TOKEN_IN:
00578 return USB_PID_IN;
00579 case USB_TOKEN_OUT:
00580 return USB_PID_OUT;
00581 default:
00582 PANIC ("Unknown USB token\n");
00583 }
00584 }
00585
00586 static void
00587 uhci_setup_td (struct tx_descriptor *td, int dev_addr, int token,
00588 int eop, void *pkt, int sz, int toggle, bool ls UNUSED)
00589 {
00590 td->buf_ptr = (sz == 0) ? 0 : vtop (pkt);
00591
00592 td->token.pid = token_to_pid (token);
00593 td->token.dev_addr = dev_addr;
00594 td->token.end_point = eop;
00595 td->token.data_toggle = toggle;
00596 td->token.maxlen = sz - 1;
00597
00598
00599 td->control.actual_len = 0;
00600 td->control.active = 1;
00601 td->flp.qh_select = 0;
00602 td->flp.depth_select = 0;
00603
00604
00605 td->control.error_limit = 3;
00606 }
00607
00608 static int
00609 uhci_tx_pkt_now (struct uhci_eop_info *ue, int token, void *pkt, int sz)
00610 {
00611 struct tx_descriptor *td;
00612 struct uhci_dev_info *ud;
00613
00614 ud = ue->ud;
00615
00616 uhci_lock (ud->ui);
00617
00618 td = uhci_acquire_td (ud->ui);
00619 memset (td, 0, sizeof (struct tx_descriptor));
00620 uhci_setup_td (td, ud->dev_addr, token, ue->eop, pkt, sz, ue->toggle,
00621 ud->low_speed);
00622
00623
00624 if (!uhci_is_stopped (ud->ui))
00625 uhci_stop (ud->ui);
00626
00627 uhci_add_td_to_qh (ud->qh, td);
00628 td->flags = TD_FL_ASYNC | TD_FL_USED;
00629
00630
00631 uhci_unlock (ud->ui);
00632
00633 ue->toggle ^= 1;
00634 return USB_HOST_ERR_NONE;
00635 }
00636
00637 static int
00638 uhci_tx_pkt_wait (struct uhci_eop_info *ue, int token, void *pkt,
00639 int max_sz, int *in_sz)
00640 {
00641 enum intr_level old_lvl;
00642 struct tx_descriptor *td;
00643 struct usb_wait w;
00644 int err;
00645 struct uhci_dev_info *ud;
00646
00647 ud = ue->ud;
00648
00649 uhci_lock (ud->ui);
00650
00651 td = uhci_acquire_td (ud->ui);
00652 memset (td, 0, sizeof (struct tx_descriptor));
00653
00654 uhci_setup_td (td, ud->dev_addr, token, ue->eop, pkt, max_sz, ue->toggle,
00655 ud->low_speed);
00656 td->control.ioc = 1;
00657
00658 w.td = td;
00659 w.ud = ud;
00660 sema_init (&w.sem, 0);
00661
00662 uhci_stop (ud->ui);
00663
00664
00665 uhci_add_td_to_qh (ud->qh, td);
00666 td->flags = TD_FL_USED;
00667
00668 list_push_back (&ud->ui->waiting, &w.peers);
00669
00670
00671 old_lvl = intr_disable ();
00672 uhci_run (ud->ui);
00673 uhci_unlock (ud->ui);
00674 sema_down (&w.sem);
00675 intr_set_level (old_lvl);
00676
00677 if (in_sz != NULL)
00678 {
00679 if (w.td->control.actual_len == 0x7ff)
00680 *in_sz = 0;
00681 else
00682 *in_sz = w.td->control.actual_len + 1;
00683 }
00684
00685 if (w.td->control.bitstuff)
00686 err = USB_HOST_ERR_BITSTUFF;
00687 else if (w.td->control.timeout)
00688 err = USB_HOST_ERR_TIMEOUT;
00689 else if (w.td->control.nak)
00690 err = USB_HOST_ERR_NAK;
00691 else if (w.td->control.babble)
00692 err = USB_HOST_ERR_BABBLE;
00693 else if (w.td->control.buffer_error)
00694 err = USB_HOST_ERR_BUFFER;
00695 else if (w.td->control.stalled)
00696 err = USB_HOST_ERR_STALL;
00697 else
00698 {
00699 err = USB_HOST_ERR_NONE;
00700 ue->toggle ^= 1;
00701 }
00702
00703 uhci_release_td (ud->ui, td);
00704
00705 #if 0
00706 printf ("%s to device %d:\n",
00707 token == USB_TOKEN_OUT ? "OUT"
00708 : token == USB_TOKEN_IN ? "IN"
00709 : token == USB_TOKEN_SETUP ? "SETUP"
00710 : "unknown",
00711 ud->dev_addr);
00712 n = (w.td->control.actual_len + 1) & 0x7ff;
00713 hex_dump (0, pkt, n, true);
00714 if (err)
00715 printf ("tx_pkt_wait: err=%d\n", err);
00716 #endif
00717
00718 return err;
00719 }
00720
00721 static void
00722 uhci_add_td_to_qh (struct queue_head *qh, struct tx_descriptor *td)
00723 {
00724 struct frame_list_ptr *fp;
00725
00726 ASSERT (td != NULL);
00727
00728 td->head = &qh->qelp;
00729 if (qh->qelp.terminate == 1)
00730 {
00731
00732 td->flp.terminate = 1;
00733 barrier ();
00734 td->flp.flp = 0;
00735 qh->qelp.flp = ptr_to_flp (vtop (td));
00736 qh->qelp.terminate = 0;
00737 }
00738 else
00739 {
00740
00741 fp = ptov (flp_to_ptr (qh->qelp.flp));
00742 ASSERT (qh->qelp.terminate == 0);
00743 while (!fp->terminate)
00744 {
00745 fp = ptov (flp_to_ptr (fp->flp));
00746 }
00747
00748
00749 td->flp = *fp;
00750
00751 fp->qh_select = 0;
00752 fp->depth_select = 0;
00753 fp->flp = ptr_to_flp (vtop (td));
00754 barrier ();
00755 fp->terminate = 0;
00756 }
00757 }
00758
00759 static void
00760 uhci_irq (void *uhci_data)
00761 {
00762 struct uhci_info *ui;
00763 uint16_t status;
00764
00765 ui = uhci_data;
00766 status = pci_reg_read16 (ui->io, UHCI_REG_USBSTS);
00767 if (status & USB_STATUS_PROCESSERR)
00768 {
00769 dump_all_qh (ui);
00770 dump_regs (ui);
00771 PANIC ("UHCI: Malformed schedule");
00772 }
00773 else if (status & USB_STATUS_HOSTERR)
00774 {
00775 dump_all_qh (ui);
00776 dump_regs (ui);
00777 PANIC ("UHCI: Host system error");
00778 }
00779 else if (status & USB_STATUS_INTERR)
00780 {
00781
00782 pci_reg_write16 (ui->io, UHCI_REG_USBSTS, USB_STATUS_INTERR);
00783 }
00784
00785 if (status & USB_STATUS_USBINT)
00786 {
00787
00788 uhci_stop_unlocked (ui);
00789 pci_reg_write16 (ui->io, UHCI_REG_USBSTS, USB_STATUS_USBINT);
00790 uhci_process_completed (ui);
00791 uhci_run_unlocked (ui);
00792 }
00793 }
00794
00795 static int
00796 uhci_process_completed (struct uhci_info *ui)
00797 {
00798 struct list_elem *li;
00799 int completed = 0;
00800 size_t start = 0;
00801
00802 li = list_begin (&ui->waiting);
00803 while (li != list_end (&ui->waiting))
00804 {
00805 struct usb_wait *uw;
00806 struct list_elem *next;
00807
00808 next = list_next (li);
00809 uw = list_entry (li, struct usb_wait, peers);
00810
00811 if (!uw->td->control.active)
00812 {
00813 list_remove (li);
00814 if (uw->td->control.error_limit == 0 || uw->td->control.stalled)
00815 {
00816 uhci_remove_error_td (uw->td);
00817 }
00818 uw->td->flags = 0;
00819 sema_up (&uw->sem);
00820 completed++;
00821 }
00822 li = next;
00823 }
00824
00825
00826 if (completed == 0)
00827 return completed;
00828
00829 while (start < TD_ENTRIES)
00830 {
00831 struct tx_descriptor *td;
00832
00833 start = bitmap_scan (ui->td_used, start, 1, true);
00834 if (start == BITMAP_ERROR)
00835 break;
00836
00837 td = td_from_pool (ui, start);
00838
00839 if (!td->control.active && (td->flags & TD_FL_ASYNC) &&
00840 (td->flags & TD_FL_USED))
00841 {
00842 if (td->control.error_limit == 0 || td->control.stalled)
00843 {
00844 uhci_remove_error_td (td);
00845 }
00846 uhci_release_td (ui, td);
00847 completed++;
00848 }
00849 start++;
00850 }
00851
00852 return completed;
00853 }
00854
00855 static void
00856 uhci_remove_error_td (struct tx_descriptor *td)
00857 {
00858 struct frame_list_ptr *fp;
00859 uint32_t td_flp;
00860
00861 ASSERT (td->head != NULL);
00862
00863 fp = td->head;
00864 td_flp = ptr_to_flp (vtop (td));
00865 while (fp->flp != td_flp)
00866 {
00867 ASSERT (fp->terminate == 0);
00868 fp = ptov (flp_to_ptr (fp->flp));
00869 }
00870 *fp = td->flp;
00871 }
00872
00873 static int
00874 uhci_detect_change (host_info hi)
00875 {
00876 struct uhci_info *ui;
00877 int change;
00878 int i;
00879
00880 ui = hi;
00881 change = 0;
00882 uhci_lock (ui);
00883 for (i = 0; i < ui->num_ports; i++)
00884 {
00885 change = check_and_flip_change (ui, i);
00886 if (change != 0)
00887 break;
00888 }
00889 uhci_unlock (ui);
00890
00891 return change;
00892 }
00893
00894 static int
00895 check_and_flip_change (struct uhci_info *ui, int port)
00896 {
00897 int val;
00898 int reg;
00899
00900 reg = UHCI_REG_PORTSC1 + port * 2;
00901 val = pci_reg_read16 (ui->io, reg);
00902 if (val & USB_PORT_CHANGE)
00903 {
00904 pci_reg_write16 (ui->io, reg, val & ~(USB_PORT_CHANGE));
00905 return 1;
00906 }
00907
00908 return 0;
00909 }
00910
00911 static host_dev_info
00912 uhci_create_chan (host_info hi, int dev_addr, int ver)
00913 {
00914 struct uhci_info *ui;
00915 struct uhci_dev_info *ud;
00916 int i;
00917
00918 ASSERT (dev_addr <= 127 && dev_addr >= 0);
00919
00920 ui = hi;
00921
00922 ud = malloc (sizeof (struct uhci_dev_info));
00923 ud->dev_addr = dev_addr;
00924 ud->low_speed = (ver == USB_VERSION_1_0) ? true : false;
00925
00926 ud->errors = 0;
00927 ud->ui = ui;
00928 lock_init (&ud->lock);
00929
00930 uhci_lock (ui);
00931
00932 ud->qh = qh_alloc (ud->ui);
00933
00934
00935 memset (ud->qh, 0, sizeof (*ud->qh));
00936 ud->qh->qelp.terminate = 1;
00937 barrier ();
00938 ud->qh->qelp.flp = 0;
00939 ud->qh->qelp.qh_select = 0;
00940 ud->qh->qhlp.qh_select = 1;
00941
00942 uhci_stop (ui);
00943
00944
00945 ud->qh->qhlp.flp = ui->frame_list[0].flp;
00946 ud->qh->qhlp.terminate = ui->frame_list[0].terminate;
00947 for (i = 0; i < FRAME_LIST_ENTRIES; i++)
00948 {
00949 ui->frame_list[i].flp = ptr_to_flp (vtop (ud->qh));
00950 ui->frame_list[i].qh_select = 1;
00951 ui->frame_list[i].terminate = 0;
00952 }
00953
00954
00955 list_push_back (&ui->devices, &ud->peers);
00956
00957 uhci_run (ui);
00958 uhci_unlock (ui);
00959
00960 return ud;
00961 }
00962
00963 static void
00964 uhci_destroy_chan (host_dev_info hd)
00965 {
00966 struct uhci_dev_info *ud;
00967 struct list_elem *li;
00968
00969 ud = hd;
00970 uhci_lock (ud->ui);
00971
00972 uhci_stop (ud->ui);
00973
00974 uhci_remove_qh (ud->ui, ud->qh);
00975
00976
00977 li = list_begin (&ud->ui->waiting);
00978 while (li != list_end (&ud->ui->waiting))
00979 {
00980 struct usb_wait *w;
00981 w = list_entry (li, struct usb_wait, peers);
00982 if (w->ud == ud)
00983 {
00984 sema_up (&w->sem);
00985 list_remove (li);
00986 }
00987 li = list_next (li);
00988 }
00989
00990 list_remove (&ud->peers);
00991
00992 uhci_run (ud->ui);
00993
00994 qh_free (ud->ui, ud->qh);
00995
00996 uhci_unlock (ud->ui);
00997
00998 free (ud);
00999 }
01000
01004 static void
01005 uhci_remove_qh (struct uhci_info *ui, struct queue_head *qh)
01006 {
01007 uintptr_t qh_flp;
01008
01009 ASSERT (lock_held_by_current_thread (&ui->lock));
01010 ASSERT (uhci_is_stopped (ui));
01011 ASSERT (qh != NULL);
01012
01013 qh_flp = ptr_to_flp (vtop (qh));
01014
01015 if (ui->frame_list[0].flp == qh_flp)
01016 {
01017 int i;
01018
01019 for (i = 0; i < FRAME_LIST_ENTRIES; i++)
01020 {
01021 ui->frame_list[i] = qh->qhlp;
01022 }
01023 }
01024 else
01025 {
01026
01027 struct frame_list_ptr *fp;
01028 struct frame_list_ptr *prev;
01029
01030 fp = ptov (flp_to_ptr (ui->frame_list[0].flp));
01031 ASSERT (!fp->terminate);
01032 do
01033 {
01034 prev = fp;
01035 fp = ptov (flp_to_ptr (fp->flp));
01036 }
01037 while (!fp->terminate && fp->flp != qh_flp);
01038 *prev = qh->qhlp;
01039 }
01040 }
01041
01046 static void
01047 uhci_stop (struct uhci_info *ui)
01048 {
01049 ASSERT (intr_get_level () != INTR_OFF);
01050 ASSERT (lock_held_by_current_thread (&ui->lock));
01051
01052 uhci_stop_unlocked (ui);
01053 }
01054
01055 static void
01056 uhci_stop_unlocked (struct uhci_info *ui)
01057 {
01058 uint16_t cmd;
01059 int i;
01060
01061 cmd = pci_reg_read16 (ui->io, UHCI_REG_USBCMD);
01062 cmd = cmd & ~USB_CMD_RS;
01063
01064 pci_reg_write16 (ui->io, UHCI_REG_USBCMD, cmd);
01065
01066
01067 for (i = 0; i < 1000; i++)
01068 {
01069 if (uhci_is_stopped (ui))
01070 return;
01071 }
01072
01073 PANIC ("UHCI: Controller did not halt\n");
01074
01075 }
01076
01077 static void
01078 uhci_run_unlocked (struct uhci_info *ui)
01079 {
01080 uint16_t cmd;
01081 cmd = pci_reg_read16 (ui->io, UHCI_REG_USBCMD);
01082 cmd = cmd | USB_CMD_RS | USB_CMD_MAX_PACKET;
01083 pci_reg_write16 (ui->io, UHCI_REG_USBCMD, cmd);
01084 }
01085
01089 static void
01090 uhci_run (struct uhci_info *ui)
01091 {
01092 ASSERT (lock_held_by_current_thread (&ui->lock));
01093 uhci_run_unlocked (ui);
01094 }
01095
01096 static struct tx_descriptor *
01097 uhci_acquire_td (struct uhci_info *ui)
01098 {
01099 size_t td_idx;
01100 struct tx_descriptor *td;
01101
01102 ASSERT (lock_held_by_current_thread (&ui->lock));
01103
01104 sema_down (&ui->td_sem);
01105 td_idx = bitmap_scan_and_flip (ui->td_used, 0, 1, false);
01106 ASSERT (td_idx != BITMAP_ERROR);
01107 td = td_from_pool (ui, td_idx);
01108
01109 return td;
01110 }
01111
01112 static void
01113 uhci_modify_chan (host_dev_info hd, int dev_addr, int ver)
01114 {
01115 struct uhci_dev_info *ud;
01116
01117 ud = hd;
01118 ud->dev_addr = dev_addr;
01119 ud->low_speed = (ver == USB_VERSION_1_0) ? true : false;
01120 }
01121
01122 static void
01123 uhci_set_toggle (host_eop_info he, int toggle)
01124 {
01125 struct uhci_eop_info *ue;
01126
01127 ue = he;
01128 ue->toggle = toggle;
01129 }
01130
01131 static void
01132 dump_all_qh (struct uhci_info *ui)
01133 {
01134 struct list_elem *li;
01135
01136 printf ("schedule: %x...", vtop (ui->frame_list));
01137 printf ("%x", *((uint32_t *) ui->frame_list));
01138 li = list_begin (&ui->devices);
01139 while (li != list_end (&ui->devices))
01140 {
01141 struct uhci_dev_info *ud;
01142 ud = list_entry (li, struct uhci_dev_info, peers);
01143 dump_qh (ud->qh);
01144 li = list_next (li);
01145 }
01146 }
01147
01148 static void
01149 dump_qh (struct queue_head *qh)
01150 {
01151 struct frame_list_ptr *fp;
01152 printf ("qh: %p %x\n", qh, vtop (qh));
01153 fp = &qh->qelp;
01154 while (!fp->terminate)
01155 {
01156 printf ("%x %x\n", *((uint32_t *) fp), *(uint32_t *) (fp + 1));
01157 fp = ptov (flp_to_ptr (fp->flp));
01158 }
01159 printf ("%x %x\n\n", *(uint32_t *) fp, *(uint32_t *) (fp + 1));
01160 }
01161
01162 static struct tx_descriptor *
01163 td_from_pool (struct uhci_info *ui, int idx)
01164 {
01165 ASSERT (idx >= 0 && idx < TD_ENTRIES);
01166 return (((void *) ui->td_pool) + idx * 32);
01167 }
01168
01169 static void
01170 uhci_detect_ports (struct uhci_info *ui)
01171 {
01172 int i;
01173 ui->num_ports = 0;
01174 for (i = 0; i < UHCI_MAX_PORTS; i++)
01175 {
01176 uint16_t status;
01177 status = pci_reg_read16 (ui->io, UHCI_REG_PORTSC1 + i * 2);
01178 if (!(status & 0x0080) || status == 0xffff)
01179 return;
01180 ui->num_ports++;
01181 }
01182 }
01183
01184 static void
01185 uhci_stall_watchdog (struct uhci_info *ui)
01186 {
01187 while (1)
01188 {
01189 int rmved;
01190 timer_msleep (1000);
01191 printf ("watchdog\n");
01192 uhci_lock (ui);
01193 uhci_stop (ui);
01194 rmved = uhci_remove_stalled (ui);
01195 if (rmved > 0)
01196 printf ("removed stalled packet in watchdog\n");
01197 uhci_run (ui);
01198 uhci_unlock (ui);
01199 }
01200 }
01201
01202 static int
01203 uhci_remove_stalled (struct uhci_info *ui)
01204 {
01205 struct list_elem *li;
01206 int rmved;
01207
01208 rmved = 0;
01209 li = list_begin (&ui->waiting);
01210
01211 intr_disable ();
01212
01213 while (li != list_end (&ui->waiting))
01214 {
01215 struct usb_wait *uw;
01216 struct list_elem *next;
01217 uint32_t ctrl;
01218
01219 next = list_next (li);
01220 uw = list_entry (li, struct usb_wait, peers);
01221
01222 if ((!uw->td->control.active && uw->td->control.stalled) ||
01223 (uw->td->control.nak))
01224 {
01225 memcpy (&ctrl, &uw->td->control, 4);
01226 printf ("CTRL: %x\n", ctrl);
01227 list_remove (li);
01228 uhci_remove_error_td (uw->td);
01229 sema_up (&uw->sem);
01230 rmved++;
01231 }
01232 li = next;
01233 }
01234
01235 intr_enable ();
01236
01237 return rmved;
01238 }
01239
01240 static void
01241 uhci_release_td (struct uhci_info *ui, struct tx_descriptor *td)
01242 {
01243 int ofs = (uintptr_t) td - (uintptr_t) ui->td_pool;
01244 int entry = ofs / 32;
01245
01246 ASSERT (entry < TD_ENTRIES);
01247
01248 td->flags = 0;
01249 bitmap_reset (ui->td_used, entry);
01250 sema_up (&ui->td_sem);
01251 }
01252
01253 static host_eop_info
01254 uhci_create_eop (host_dev_info hd, int eop, int maxpkt)
01255 {
01256 struct uhci_dev_info *ud;
01257 struct uhci_eop_info *e;
01258
01259 ud = hd;
01260
01261 e = malloc (sizeof (struct uhci_eop_info));
01262 e->eop = eop;
01263 e->ud = ud;
01264 e->maxpkt = maxpkt;
01265 e->toggle = 0;
01266
01267 return e;
01268 }
01269
01270 static void
01271 uhci_remove_eop (host_eop_info hei)
01272 {
01273 free (hei);
01274 }
01275
01276 static struct queue_head *
01277 qh_alloc (struct uhci_info *ui)
01278 {
01279 size_t qh_idx;
01280 struct queue_head *qh;
01281
01282 ASSERT (lock_held_by_current_thread (&ui->lock));
01283
01284 qh_idx = bitmap_scan_and_flip (ui->qh_used, 0, 1, false);
01285 if (qh_idx == BITMAP_ERROR)
01286 {
01287 PANIC ("UHCI: Too many queue heads in use-- runaway USB stack?\n");
01288 }
01289 qh = (void *) (((intptr_t) ui->qh_pool) + qh_idx * 16);
01290
01291 return qh;
01292 }
01293
01294 static void
01295 qh_free (struct uhci_info *ui, struct queue_head *qh)
01296 {
01297 size_t entry;
01298 ASSERT (lock_held_by_current_thread (&ui->lock));
01299
01300 entry = ((intptr_t) qh - (intptr_t) ui->qh_pool) / 16;
01301 bitmap_reset (ui->qh_used, entry);
01302 }