#include "types.h" #include "link.h" #include #include #include #include "pci.h" #include "syscall.h" #include "usb.h" static Bool FindPciDevice(); int __stdcall srv_usb(ioctl_t *io); Bool init_hc(hc_t *hc); static slab_t qh_slab; static slab_t td_slab; static link_t hc_list; static link_t newdev_list; static link_t rq_list; u32_t __stdcall drvEntry(int action) { u32_t retval; hc_t *hc; udev_t *dev; int i; if(action != 1) return 0; if(!dbg_open("/rd/1/drivers/usb.log")) { printf("Can't open /rd/1/drivers/usb.log\nExit\n"); return 0; } list_initialize(&hc_list); list_initialize(&newdev_list); list_initialize(&rq_list); if( !FindPciDevice() ) { dbgprintf("no uhci devices found\n"); return 0; }; qh_slab.available = 256; qh_slab.start = KernelAlloc(4096); qh_slab.nextavail = (addr_t)qh_slab.start; qh_slab.dma = GetPgAddr(qh_slab.start); qh_t *p; addr_t dma; for (i = 0, p = (qh_t*)qh_slab.start, dma = qh_slab.dma; i < 256; i++, p++, dma+= sizeof(qh_t)) { p->qlink = (addr_t)(p+1); p->qelem = 1; p->dma = dma; p->r1 = 0; }; td_slab.available = 128; td_slab.start = KernelAlloc(4096); td_slab.nextavail = (addr_t)td_slab.start; td_slab.dma = GetPgAddr(td_slab.start); td_t *td; for (i = 0, td = (td_t*)td_slab.start, dma = td_slab.dma; i < 128; i++, td++, dma+= sizeof(td_t)) { td->link = (addr_t)(td+1); td->status = 0; td->token = 0; td->buffer = 0; td->dma = dma; }; hc = (hc_t*)hc_list.next; while( &hc->link != &hc_list) { init_hc(hc); hc = (hc_t*)hc->link.next; } dbgprintf("\n"); dev = (udev_t*)newdev_list.next; while( &dev->link != &newdev_list) { udev_t *tmp = dev; dev = (udev_t*)dev->link.next; if(tmp->id != 0) init_device(tmp); } while(1) { udev_t *dev; request_t *rq; rq = (request_t*)rq_list.next; while( &rq->link != &rq_list) { qh_t *qh; td_t *td; td = rq->td_head; dev = rq->dev; qh = dev->host->qh1; qh->qelem = td->dma; __asm__ __volatile__ ("":::"memory"); rq = (request_t*)rq->link.next; }; delay(10/10); rq = (request_t*)rq_list.next; while( &rq->link != &rq_list) { request_t *tmp; td_t *td; tmp = rq; rq = (request_t*)rq->link.next; td = tmp->td_head; if( td->status & TD_CTRL_ACTIVE) continue; tmp->handler(tmp->dev, tmp); }; }; retval = RegService("USB", srv_usb); dbgprintf("reg service USB as: %x\n", retval); return retval; }; #define API_VERSION 0x01000100 #define SRV_GETVERSION 0 int __stdcall srv_usb(ioctl_t *io) { u32_t *inp; u32_t *outp; inp = io->input; outp = io->output; switch(io->io_code) { case SRV_GETVERSION: if(io->out_size==4) { *outp = API_VERSION; return 0; } break; default: return ERR_PARAM; }; return ERR_PARAM; } static qh_t* alloc_qh() { if( qh_slab.available ) { qh_t *qh; qh_slab.available--; qh = (qh_t*)qh_slab.nextavail; qh_slab.nextavail = qh->qlink; return qh; } return NULL; }; static void free_qh(qh_t *qh) { qh->qlink = qh_slab.nextavail; qh_slab.nextavail = (addr_t)qh; qh_slab.available++; }; static td_t* alloc_td() { if( td_slab.available ) { td_t *td; td_slab.available--; td = (td_t*)td_slab.nextavail; td_slab.nextavail = td->link; return td; } return NULL; }; static void free_td(td_t *td) { td->link = td_slab.nextavail; td_slab.nextavail = (addr_t)td; td_slab.available++; }; #include "pci.inc" #include "detect.inc" #include "hcd.inc" #include "hid.inc"