/drivers/usb/uhci/detect.inc |
---|
9,6 → 9,8 |
if( (last_bus = PciApi(1))==-1) |
return retval; |
dbgprintf("last bus %x\n", last_bus); |
for(bus=0;bus<=last_bus;bus++) |
{ |
u32_t devfn; |
37,12 → 39,12 |
hc = (hc_t*)kmalloc(sizeof(hc_t), 0); |
INIT_LIST_HEAD(&hc->list); |
INIT_LIST_HEAD(&hc->rq_list); |
hc->pciId = PciRead32(bus,devfn, 0); |
hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); |
hc->irq_line = PciRead32(bus,devfn, 0x3C) & 0xFF; |
dbgprintf("Host IRQ %d\n", hc->irq_line); |
for (i = 0; i < 6; i++) |
{ |
61,6 → 63,9 |
} |
} |
}; |
dbgprintf("host controller %x bus %x devfn %x, IRQ %d\n", |
hc->pciId, bus, devfn, hc->irq_line); |
list_add_tail(&hc->list, &hc_list); |
retval = true; |
}; |
/drivers/usb/uhci/hcd.inc |
---|
124,25 → 124,46 |
{ |
hc_t *hc; |
printf("USB interrupt\n"); |
// printf("USB interrupt\n"); |
hc = (hc_t*)hc_list.next; |
while( &hc->list != &hc_list) |
{ |
hc_t *tmp; |
hc_t *htmp; |
request_t *rq; |
u16_t status; |
tmp = hc; |
htmp = hc; |
hc = (hc_t*)hc->list.next; |
status = in16(tmp->iobase + USBSTS); |
status = in16(htmp->iobase + USBSTS); |
if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ |
continue; |
out16(tmp->iobase + USBSTS, status); /* Clear it */ |
} |
out16(htmp->iobase + USBSTS, status); /* Clear it */ |
rq = (request_t*)htmp->rq_list.next; |
while( &rq->list != &htmp->rq_list) |
{ |
request_t *rtmp; |
td_t *td; |
rtmp = rq; |
rq = (request_t*)rq->list.next; |
td = rtmp->td_tail; |
if( td->status & TD_CTRL_ACTIVE) |
continue; |
list_del(&rtmp->list); |
RaiseEvent(rtmp->evh, 0, &rtmp->event); |
}; |
} |
}; |
422,6 → 443,15 |
td->status |= TD_CTRL_IOC; |
rq->td_tail = td; |
rq->evh = CreateEvent(NULL, MANUAL_DESTROY); |
if(rq->evh.handle == 0) |
printf("%s: epic fail\n", __FUNCTION__); |
rq->event.code = 0xFF000001; |
rq->event.data[0] = (addr_t)rq; |
return rq; |
} |
437,6 → 467,15 |
addr_t data_dma = 0; |
bool retval; |
request_t *rq = (request_t*)kmalloc(sizeof(request_t),0); |
INIT_LIST_HEAD(&rq->list); |
rq->data = (addr_t)data; |
rq->size = req_size; |
rq->dev = dev; |
td0 = alloc_td(); |
td0->status = 0x00800000 | dev->speed; |
481,20 → 520,34 |
td->buffer = 0; |
td->bk = td_prev; |
rq->td_head = td0; |
rq->td_tail = td; |
rq->evh = CreateEvent(NULL, MANUAL_DESTROY); |
if(rq->evh.handle == 0) |
printf("%s: epic fail\n", __FUNCTION__); |
rq->event.code = 0xFF000001; |
rq->event.data[0] = (addr_t)rq; |
u32_t efl = safe_cli(); |
list_add_tail(&rq->list, &dev->host->rq_list); |
qh = dev->host->qh[SKEL_ASYNC]; |
qh->qelem = td0->dma; |
mb(); |
// __asm__ __volatile__ ("":::"memory"); |
count_t timeout = 25; |
while(timeout--){ |
delay(10/10); |
if( !(td->status & TD_CTRL_ACTIVE)) |
break; |
} |
safe_sti(efl); |
WaitEvent(rq->evh.handle, rq->evh.euid); |
dbgprintf("td0 status 0x%0x\n", td0->status); |
dbgprintf("td status 0x%0x\n", td->status); |
if( (td0->status & TD_ANY_ERROR) || |
(td_prev->status & TD_ANY_ERROR) || |
(td->status & TD_ANY_ERROR)) |
513,6 → 566,10 |
retval = false; |
} else retval = true; |
qh->qelem = 1; |
mb(); |
do |
{ |
td_prev = td->bk; |
520,6 → 577,11 |
td = td_prev; |
}while( td != NULL); |
/* |
delete event; |
*/ |
kfree(rq); |
return retval; |
}; |
545,7 → 607,10 |
dev->id, dev->host->pciId, dev->port); |
if( !ctrl_request(dev, req_descr, DIN, &descr, 18)) |
{ |
dbgprintf("%s epic fail\n",__FUNCTION__); |
return; |
}; |
dev->dev_descr = descr; |
/drivers/usb/uhci/hid.inc |
---|
103,6 → 103,7 |
bool mouse_handler(udev_t *dev, struct tag_request *rq) |
{ |
td_t *td; |
qh_t *qh; |
td = rq->td_head; |
115,6 → 116,13 |
td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed; |
td->token ^= DATA1; |
u32_t efl = safe_cli(); |
list_add_tail(&rq->list, &dev->host->rq_list); |
qh = dev->host->qh[6]; |
qh->qelem = rq->td_head->dma; |
mb(); |
safe_sti(efl); |
return true; |
}; |
148,7 → 156,12 |
rq->qnum = 6; |
rq->handler = &mouse_handler; |
list_add_tail(&rq->list, &rq_list); |
u32_t efl = safe_cli(); |
list_add_tail(&rq->list, &dev->host->rq_list); |
qh = dev->host->qh[6]; |
qh->qelem = rq->td_head->dma; |
mb(); |
safe_sti(efl); |
dbgprintf("create_hid_mouse\n"); |
} |
/drivers/usb/uhci/usb.c |
---|
104,43 → 104,26 |
{ |
udev_t *dev; |
request_t *rq; |
kevent_t event; |
u32_t handle; |
rq = (request_t*)rq_list.next; |
while( &rq->list != &rq_list) |
{ |
qh_t *qh; |
td_t *td; |
event.code = 0; |
event.data[0] = 0; |
td = rq->td_head; |
dev = rq->dev; |
handle = GetEvent(&event); |
qh = dev->host->qh[rq->qnum]; |
qh->qelem = td->dma; |
// dbgprintf("event handle 0x%0x code 0x%0x\n", |
// handle, event.code); |
mb(); |
if(event.code != 0xFF000001) |
continue; |
rq = (request_t*)rq->list.next; |
}; |
rq = (request_t*)event.data[0]; |
delay(10/10); |
// dbgprintf("rq = 0x%0x\n", rq); |
rq = (request_t*)rq_list.next; |
while( &rq->list != &rq_list) |
{ |
request_t *tmp; |
td_t *td; |
tmp = rq; |
rq = (request_t*)rq->list.next; |
td = tmp->td_head; |
if( td->status & TD_CTRL_ACTIVE) |
continue; |
tmp->handler(tmp->dev, tmp); |
rq->handler(rq->dev, rq); |
}; |
}; |
retval = RegService("USB", srv_usb); |
dbgprintf("reg service USB as: %x\n", retval); |
/drivers/usb/uhci/usb.h |
---|
44,17 → 44,7 |
#define SKEL_ISO 1 |
#define SKEL_ASYNC 9 |
/* |
#define QH_1 0 |
#define QH_2 1 |
#define QH_4 2 |
#define QH_8 3 |
#define QH_16 4 |
#define QH_32 5 |
#define QH_64 6 |
*/ |
typedef struct |
{ |
list_t list; |
81,6 → 71,8 |
size_t memSize[6]; |
u32_t memType[6]; |
u32_t irq_line; |
list_t rq_list; |
}hc_t; |
typedef struct tag_td |
233,6 → 225,8 |
udev_t *dev; |
u32_t type; |
int qnum; |
evhandle_t evh; |
kevent_t event; |
bool (*handler)(udev_t *dev, struct tag_request *rq); |
}request_t; |