2008-12-13 04:32:16 +01:00
|
|
|
|
|
|
|
|
2010-09-13 22:07:22 +02:00
|
|
|
#include <ddk.h>
|
2010-09-03 11:42:20 +02:00
|
|
|
#include <mutex.h>
|
2011-08-24 13:00:06 +02:00
|
|
|
#include <linux/errno.h>
|
2010-09-03 11:42:20 +02:00
|
|
|
#include <pci.h>
|
2010-09-13 22:07:22 +02:00
|
|
|
#include <linux/dmapool.h>
|
2011-02-17 12:32:46 +01:00
|
|
|
#include <linux/string.h>
|
2010-09-03 11:42:20 +02:00
|
|
|
#include <syscall.h>
|
2008-12-13 04:32:16 +01:00
|
|
|
#include "usb.h"
|
|
|
|
|
|
|
|
int __stdcall srv_usb(ioctl_t *io);
|
|
|
|
|
2010-09-03 11:42:20 +02:00
|
|
|
bool init_hc(hc_t *hc);
|
2008-12-13 04:32:16 +01:00
|
|
|
|
|
|
|
static slab_t qh_slab;
|
|
|
|
|
2010-09-03 11:42:20 +02:00
|
|
|
LIST_HEAD( hc_list );
|
|
|
|
LIST_HEAD( newdev_list );
|
|
|
|
LIST_HEAD( rq_list );
|
2008-12-13 04:32:16 +01:00
|
|
|
|
2010-09-03 11:42:20 +02:00
|
|
|
u32_t drvEntry(int action, char *cmdline)
|
2008-12-13 04:32:16 +01:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2010-09-03 11:42:20 +02:00
|
|
|
if( !FindUSBControllers() ) {
|
2008-12-13 04:32:16 +01:00
|
|
|
dbgprintf("no uhci devices found\n");
|
|
|
|
return 0;
|
|
|
|
};
|
|
|
|
|
2011-02-17 12:32:46 +01:00
|
|
|
hcd_buffer_create();
|
|
|
|
|
|
|
|
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;
|
|
|
|
};
|
2008-12-13 04:32:16 +01:00
|
|
|
|
|
|
|
hc = (hc_t*)hc_list.next;
|
|
|
|
|
2010-09-03 11:42:20 +02:00
|
|
|
while( &hc->list != &hc_list)
|
2008-12-13 04:32:16 +01:00
|
|
|
{
|
2010-09-13 22:07:22 +02:00
|
|
|
hc_t *tmp = hc;
|
2010-09-03 11:42:20 +02:00
|
|
|
hc = (hc_t*)hc->list.next;
|
2010-09-13 22:07:22 +02:00
|
|
|
|
|
|
|
if( !init_hc(tmp))
|
|
|
|
list_del(&tmp->list);
|
|
|
|
};
|
2008-12-13 04:32:16 +01:00
|
|
|
|
|
|
|
dbgprintf("\n");
|
|
|
|
|
|
|
|
dev = (udev_t*)newdev_list.next;
|
2010-09-03 11:42:20 +02:00
|
|
|
while( &dev->list != &newdev_list)
|
2008-12-13 04:32:16 +01:00
|
|
|
{
|
|
|
|
udev_t *tmp = dev;
|
2010-09-03 11:42:20 +02:00
|
|
|
dev = (udev_t*)dev->list.next;
|
2008-12-13 04:32:16 +01:00
|
|
|
|
|
|
|
if(tmp->id != 0)
|
|
|
|
init_device(tmp);
|
|
|
|
}
|
|
|
|
|
|
|
|
while(1)
|
|
|
|
{
|
|
|
|
udev_t *dev;
|
|
|
|
request_t *rq;
|
2010-09-12 00:23:28 +02:00
|
|
|
kevent_t event;
|
|
|
|
u32_t handle;
|
2008-12-13 04:32:16 +01:00
|
|
|
|
2010-09-12 00:23:28 +02:00
|
|
|
event.code = 0;
|
|
|
|
event.data[0] = 0;
|
2008-12-13 04:32:16 +01:00
|
|
|
|
2010-09-12 00:23:28 +02:00
|
|
|
handle = GetEvent(&event);
|
2008-12-13 04:32:16 +01:00
|
|
|
|
2010-09-12 00:23:28 +02:00
|
|
|
// dbgprintf("event handle 0x%0x code 0x%0x\n",
|
|
|
|
// handle, event.code);
|
2008-12-13 04:32:16 +01:00
|
|
|
|
2010-09-12 00:23:28 +02:00
|
|
|
if(event.code != 0xFF000001)
|
|
|
|
continue;
|
2010-09-05 16:32:50 +02:00
|
|
|
|
2010-09-12 00:23:28 +02:00
|
|
|
rq = (request_t*)event.data[0];
|
2008-12-13 04:32:16 +01:00
|
|
|
|
2010-09-12 00:23:28 +02:00
|
|
|
// dbgprintf("rq = 0x%0x\n", rq);
|
2008-12-13 04:32:16 +01:00
|
|
|
|
2010-09-12 00:23:28 +02:00
|
|
|
rq->handler(rq->dev, rq);
|
2008-12-13 04:32:16 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
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++;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#include "pci.inc"
|
|
|
|
#include "detect.inc"
|
|
|
|
#include "hcd.inc"
|
|
|
|
#include "hid.inc"
|