update usb driver

git-svn-id: svn://kolibrios.org@1613 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2010-09-11 22:23:28 +00:00
parent f751b2ee25
commit cedc365c6a
7 changed files with 182 additions and 81 deletions

View File

@ -9,6 +9,8 @@
.global _AttachIntHandler .global _AttachIntHandler
.global _CreateEvent
.global _CreateRingBuffer .global _CreateRingBuffer
.global _Delay .global _Delay
.global _DestroyObject .global _DestroyObject
@ -16,6 +18,7 @@
.global _FreeKernelSpace .global _FreeKernelSpace
.global _GetDisplay .global _GetDisplay
.global _GetEvent
.global _GetPgAddr .global _GetPgAddr
.global _GetService .global _GetService
@ -36,18 +39,24 @@
.global _PciWrite32 .global _PciWrite32
.global _PciWrite8 .global _PciWrite8
.global _RaiseEvent
.global _RegService .global _RegService
.global _SetMouseData .global _SetMouseData
.global _SetScreen .global _SetScreen
.global _SysMsgBoardStr .global _SysMsgBoardStr
.global _WaitEvent
.def _AllocPage; .scl 2; .type 32; .endef .def _AllocPage; .scl 2; .type 32; .endef
.def _AllocPages; .scl 2; .type 32; .endef .def _AllocPages; .scl 2; .type 32; .endef
.def _AttachIntHandler; .scl 2; .type 32; .endef .def _AttachIntHandler; .scl 2; .type 32; .endef
.def _CreateEvent; .scl 2; .type 32; .endef
.def _CreateRingBuffer; .scl 2; .type 32; .endef .def _CreateRingBuffer; .scl 2; .type 32; .endef
.def _Delay; .scl 2; .type 32; .endef .def _Delay; .scl 2; .type 32; .endef
@ -56,6 +65,7 @@
.def _FreeKernelSpace; .scl 2; .type 32; .endef .def _FreeKernelSpace; .scl 2; .type 32; .endef
.def _GetDisplay; .scl 2; .type 32; .endef .def _GetDisplay; .scl 2; .type 32; .endef
.def _GetEvent; .scl 2; .type 32; .endef
.def _GetPgAddr; .scl 2; .type 32; .endef .def _GetPgAddr; .scl 2; .type 32; .endef
.def _GetService; .scl 2; .type 32; .endef .def _GetService; .scl 2; .type 32; .endef
@ -76,18 +86,25 @@
.def _PciWrite32; .scl 2; .type 32; .endef .def _PciWrite32; .scl 2; .type 32; .endef
.def _PciWrite8; .scl 2; .type 32; .endef .def _PciWrite8; .scl 2; .type 32; .endef
.def _RaiseEvent; .scl 2; .type 32; .endef
.def _RegService; .scl 2; .type 32; .endef .def _RegService; .scl 2; .type 32; .endef
.def _SetScreen; .scl 2; .type 32; .endef .def _SetScreen; .scl 2; .type 32; .endef
.def _SetMouseData; .scl 2; .type 32; .endef .def _SetMouseData; .scl 2; .type 32; .endef
.def _SysMsgBoardStr; .scl 2; .type 32; .endef .def _SysMsgBoardStr; .scl 2; .type 32; .endef
.def _WaitEvent; .scl 2; .type 32; .endef
_AllocPage: _AllocPage:
_AllocPages: _AllocPages:
_AttachIntHandler: _AttachIntHandler:
_CreateEvent:
_CreateRingBuffer: _CreateRingBuffer:
_Delay: _Delay:
@ -97,6 +114,7 @@ _DestroyObject:
_FreeKernelSpace: _FreeKernelSpace:
_GetDisplay: _GetDisplay:
_GetEvent:
_GetPgAddr: _GetPgAddr:
_GetService: _GetService:
@ -117,11 +135,15 @@ _PciWrite16:
_PciWrite32: _PciWrite32:
_PciWrite8: _PciWrite8:
_RaiseEvent:
_RegService: _RegService:
_SetMouseData: _SetMouseData:
_SetScreen: _SetScreen:
_SysMsgBoardStr: _SysMsgBoardStr:
_WaitEvent:
ret ret
.section .drectve .section .drectve
@ -131,6 +153,8 @@ _SysMsgBoardStr:
.ascii " -export:AttachIntHandler" # stdcall .ascii " -export:AttachIntHandler" # stdcall
.ascii " -export:CreateEvent" #
.ascii " -export:CreateRingBuffer" # stdcall .ascii " -export:CreateRingBuffer" # stdcall
.ascii " -export:Delay" # stdcall .ascii " -export:Delay" # stdcall
@ -140,6 +164,7 @@ _SysMsgBoardStr:
.ascii " -export:FreeKernelSpace" # stdcall .ascii " -export:FreeKernelSpace" # stdcall
.ascii " -export:GetDisplay" # stdcall .ascii " -export:GetDisplay" # stdcall
.ascii " -export:GetEvent" #
.ascii " -export:GetPgAddr" # stdcall .ascii " -export:GetPgAddr" # stdcall
.ascii " -export:GetService" # stdcall .ascii " -export:GetService" # stdcall
@ -160,10 +185,13 @@ _SysMsgBoardStr:
.ascii " -export:PciWrite32" # stdcall .ascii " -export:PciWrite32" # stdcall
.ascii " -export:PciWrite8" # stdcall .ascii " -export:PciWrite8" # stdcall
.ascii " -export:RaiseEvent" #
.ascii " -export:RegService" # stdcall .ascii " -export:RegService" # stdcall
.ascii " -export:SetMouseData" # stdcall .ascii " -export:SetMouseData" # stdcall
.ascii " -export:SetScreen" # stdcall .ascii " -export:SetScreen" # stdcall
.ascii " -export:SysMsgBoardStr" # stdcall .ascii " -export:SysMsgBoardStr" # stdcall
.ascii " -export:WaitEvent" # stdcall

View File

@ -5,6 +5,12 @@
#define OS_BASE 0x80000000 #define OS_BASE 0x80000000
typedef struct
{
u32_t code;
u32_t data[5];
}kevent_t;
typedef struct typedef struct
{ {
u32_t handle; u32_t handle;
@ -51,10 +57,10 @@ void* STDCALL KernelFree(void *mem)__asm__("KernelFree");
void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc"); void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc");
int STDCALL UserFree(void *mem)__asm__("UserFree"); int STDCALL UserFree(void *mem)__asm__("UserFree");
void* STDCALL GetDisplay()__asm__("GetDisplay"); void* STDCALL GetDisplay(void)__asm__("GetDisplay");
addr_t STDCALL AllocPage()__asm__("AllocPage"); addr_t STDCALL AllocPage(void)__asm__("AllocPage");
addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages"); addr_t STDCALL AllocPages(count_t count)__asm__("AllocPages");
void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer"); void* STDCALL CreateRingBuffer(size_t size, u32_t map)__asm__("CreateRingBuffer");
@ -108,7 +114,24 @@ int dbgprintf(const char* format, ...);
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
static inline int GetScreenSize()
static inline u32_t CreateEvent(kevent_t *ev, u32_t flags, u32_t *uid)
{
u32_t handle;
u32_t euid;
__asm__ __volatile__ (
"call *__imp__CreateEvent"
:"=a"(handle),"=d"(euid)
:"S" (ev), "c"(flags));
__asm__ __volatile__ ("":::"ebx","ecx", "esi", "edi");
if(uid) *uid = euid;
return handle;
};
static inline int GetScreenSize(void)
{ {
int retval; int retval;
@ -118,7 +141,7 @@ static inline int GetScreenSize()
return retval; return retval;
} }
static inline int GetScreenBpp() static inline int GetScreenBpp(void)
{ {
int retval; int retval;
@ -128,7 +151,7 @@ static inline int GetScreenBpp()
return retval; return retval;
} }
static inline int GetScreenPitch() static inline int GetScreenPitch(void)
{ {
int retval; int retval;
@ -245,26 +268,6 @@ static inline void __DestroyObject(void *obj)
:::"eax","ebx","ecx","edx","esi","edi","cc","memory"); :::"eax","ebx","ecx","edx","esi","edi","cc","memory");
} }
/*
u32 __RegService(char *name, srv_proc_t proc)
{
u32 retval;
asm __volatile__
(
"pushl %%eax \n\t"
"pushl %%ebx \n\t"
"call *__imp__RegService \n\t"
:"=eax" (retval)
:"a" (proc), "b" (name)
:"memory"
);
return retval;
};
*/
static inline u32_t GetService(const char *name) static inline u32_t GetService(const char *name)
{ {
u32_t handle; u32_t handle;
@ -300,6 +303,16 @@ static inline void safe_sti(u32_t ifl)
); );
} }
static inline u32_t get_eflags(void)
{
u32_t val;
asm volatile (
"pushfl\n\t"
"popl %0\n"
: "=r" (val));
return val;
}
static inline void __clear (void * dst, unsigned len) static inline void __clear (void * dst, unsigned len)
{ {
u32_t tmp; u32_t tmp;
@ -364,13 +377,13 @@ static inline void delay(int time)
} }
static inline void change_task() static inline void change_task(void)
{ {
__asm__ __volatile__ ( __asm__ __volatile__ (
"call *__imp__ChangeTask"); "call *__imp__ChangeTask");
} }
static inline sysSetScreen(int width, int height, int pitch) static inline void sysSetScreen(int width, int height, int pitch)
{ {
__asm__ __volatile__ __asm__ __volatile__
( (

View File

@ -9,6 +9,8 @@ bool FindUSBControllers()
if( (last_bus = PciApi(1))==-1) if( (last_bus = PciApi(1))==-1)
return retval; return retval;
dbgprintf("last bus %x\n", last_bus);
for(bus=0;bus<=last_bus;bus++) for(bus=0;bus<=last_bus;bus++)
{ {
u32_t devfn; u32_t devfn;
@ -37,12 +39,12 @@ bool FindUSBControllers()
hc = (hc_t*)kmalloc(sizeof(hc_t), 0); hc = (hc_t*)kmalloc(sizeof(hc_t), 0);
INIT_LIST_HEAD(&hc->list); INIT_LIST_HEAD(&hc->list);
INIT_LIST_HEAD(&hc->rq_list);
hc->pciId = PciRead32(bus,devfn, 0); hc->pciId = PciRead32(bus,devfn, 0);
hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7);
hc->irq_line = PciRead32(bus,devfn, 0x3C) & 0xFF; hc->irq_line = PciRead32(bus,devfn, 0x3C) & 0xFF;
dbgprintf("Host IRQ %d\n", hc->irq_line);
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
@ -61,6 +63,9 @@ bool FindUSBControllers()
} }
} }
}; };
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); list_add_tail(&hc->list, &hc_list);
retval = true; retval = true;
}; };

View File

@ -124,24 +124,45 @@ void hc_interrupt()
{ {
hc_t *hc; hc_t *hc;
printf("USB interrupt\n"); // printf("USB interrupt\n");
hc = (hc_t*)hc_list.next; hc = (hc_t*)hc_list.next;
while( &hc->list != &hc_list) while( &hc->list != &hc_list)
{ {
hc_t *tmp; hc_t *htmp;
request_t *rq;
u16_t status; u16_t status;
tmp = hc; htmp = hc;
hc = (hc_t*)hc->list.next; hc = (hc_t*)hc->list.next;
status = in16(tmp->iobase + USBSTS); status = in16(htmp->iobase + USBSTS);
if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */ if (!(status & ~USBSTS_HCH)) /* shared interrupt, not mine */
continue; 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 @@ request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir,
td->status |= TD_CTRL_IOC; td->status |= TD_CTRL_IOC;
rq->td_tail = td; 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; return rq;
} }
@ -437,6 +467,15 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid,
addr_t data_dma = 0; addr_t data_dma = 0;
bool retval; 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 = alloc_td();
td0->status = 0x00800000 | dev->speed; td0->status = 0x00800000 | dev->speed;
@ -481,19 +520,33 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid,
td->buffer = 0; td->buffer = 0;
td->bk = td_prev; 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 = dev->host->qh[SKEL_ASYNC];
qh->qelem = td0->dma; qh->qelem = td0->dma;
mb(); mb();
// __asm__ __volatile__ ("":::"memory");
count_t timeout = 25; safe_sti(efl);
while(timeout--){
delay(10/10); WaitEvent(rq->evh.handle, rq->evh.euid);
if( !(td->status & TD_CTRL_ACTIVE))
break; dbgprintf("td0 status 0x%0x\n", td0->status);
} dbgprintf("td status 0x%0x\n", td->status);
if( (td0->status & TD_ANY_ERROR) || if( (td0->status & TD_ANY_ERROR) ||
(td_prev->status & TD_ANY_ERROR) || (td_prev->status & TD_ANY_ERROR) ||
@ -513,6 +566,10 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid,
retval = false; retval = false;
} else retval = true; } else retval = true;
qh->qelem = 1;
mb();
do do
{ {
td_prev = td->bk; td_prev = td->bk;
@ -520,6 +577,11 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid,
td = td_prev; td = td_prev;
}while( td != NULL); }while( td != NULL);
/*
delete event;
*/
kfree(rq);
return retval; return retval;
}; };
@ -545,7 +607,10 @@ bool init_device(udev_t *dev)
dev->id, dev->host->pciId, dev->port); dev->id, dev->host->pciId, dev->port);
if( !ctrl_request(dev, req_descr, DIN, &descr, 18)) if( !ctrl_request(dev, req_descr, DIN, &descr, 18))
{
dbgprintf("%s epic fail\n",__FUNCTION__);
return; return;
};
dev->dev_descr = descr; dev->dev_descr = descr;

View File

@ -103,6 +103,7 @@ bool init_hid(udev_t *dev)
bool mouse_handler(udev_t *dev, struct tag_request *rq) bool mouse_handler(udev_t *dev, struct tag_request *rq)
{ {
td_t *td; td_t *td;
qh_t *qh;
td = rq->td_head; td = rq->td_head;
@ -115,6 +116,13 @@ bool mouse_handler(udev_t *dev, struct tag_request *rq)
td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed; td->status = TD_CTRL_ACTIVE | TD_CTRL_IOC | dev->speed;
td->token ^= DATA1; 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; return true;
}; };
@ -148,7 +156,12 @@ void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d)
rq->qnum = 6; rq->qnum = 6;
rq->handler = &mouse_handler; 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"); dbgprintf("create_hid_mouse\n");
} }

View File

@ -104,42 +104,25 @@ u32_t drvEntry(int action, char *cmdline)
{ {
udev_t *dev; udev_t *dev;
request_t *rq; request_t *rq;
kevent_t event;
u32_t handle;
rq = (request_t*)rq_list.next; event.code = 0;
while( &rq->list != &rq_list) event.data[0] = 0;
{
qh_t *qh;
td_t *td;
td = rq->td_head; handle = GetEvent(&event);
dev = rq->dev;
qh = dev->host->qh[rq->qnum]; // dbgprintf("event handle 0x%0x code 0x%0x\n",
qh->qelem = td->dma; // 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; rq->handler(rq->dev, rq);
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);
};
}; };
retval = RegService("USB", srv_usb); retval = RegService("USB", srv_usb);

View File

@ -44,16 +44,6 @@ typedef struct
#define SKEL_ISO 1 #define SKEL_ISO 1
#define SKEL_ASYNC 9 #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 typedef struct
{ {
@ -81,6 +71,8 @@ typedef struct
size_t memSize[6]; size_t memSize[6];
u32_t memType[6]; u32_t memType[6];
u32_t irq_line; u32_t irq_line;
list_t rq_list;
}hc_t; }hc_t;
typedef struct tag_td typedef struct tag_td
@ -233,6 +225,8 @@ typedef struct tag_request
udev_t *dev; udev_t *dev;
u32_t type; u32_t type;
int qnum; int qnum;
evhandle_t evh;
kevent_t event;
bool (*handler)(udev_t *dev, struct tag_request *rq); bool (*handler)(udev_t *dev, struct tag_request *rq);
}request_t; }request_t;