From cedc365c6a951ede23e592ab3b4f5c41932b4fd9 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Sat, 11 Sep 2010 22:23:28 +0000 Subject: [PATCH] update usb driver git-svn-id: svn://kolibrios.org@1613 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/ddk/core.S | 28 ++++++++++++ drivers/include/syscall.h | 67 ++++++++++++++++----------- drivers/usb/uhci/detect.inc | 7 ++- drivers/usb/uhci/hcd.inc | 91 +++++++++++++++++++++++++++++++------ drivers/usb/uhci/hid.inc | 15 +++++- drivers/usb/uhci/usb.c | 41 +++++------------ drivers/usb/uhci/usb.h | 14 ++---- 7 files changed, 182 insertions(+), 81 deletions(-) diff --git a/drivers/ddk/core.S b/drivers/ddk/core.S index 3f97feadcb..aa29f21c1f 100644 --- a/drivers/ddk/core.S +++ b/drivers/ddk/core.S @@ -9,6 +9,8 @@ .global _AttachIntHandler + .global _CreateEvent + .global _CreateRingBuffer .global _Delay .global _DestroyObject @@ -16,6 +18,7 @@ .global _FreeKernelSpace .global _GetDisplay + .global _GetEvent .global _GetPgAddr .global _GetService @@ -36,18 +39,24 @@ .global _PciWrite32 .global _PciWrite8 + .global _RaiseEvent + .global _RegService .global _SetMouseData .global _SetScreen .global _SysMsgBoardStr + .global _WaitEvent + .def _AllocPage; .scl 2; .type 32; .endef .def _AllocPages; .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 _Delay; .scl 2; .type 32; .endef @@ -56,6 +65,7 @@ .def _FreeKernelSpace; .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 _GetService; .scl 2; .type 32; .endef @@ -76,18 +86,25 @@ .def _PciWrite32; .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 _SetScreen; .scl 2; .type 32; .endef .def _SetMouseData; .scl 2; .type 32; .endef .def _SysMsgBoardStr; .scl 2; .type 32; .endef + .def _WaitEvent; .scl 2; .type 32; .endef + + _AllocPage: _AllocPages: _AttachIntHandler: +_CreateEvent: + _CreateRingBuffer: _Delay: @@ -97,6 +114,7 @@ _DestroyObject: _FreeKernelSpace: _GetDisplay: +_GetEvent: _GetPgAddr: _GetService: @@ -117,11 +135,15 @@ _PciWrite16: _PciWrite32: _PciWrite8: +_RaiseEvent: _RegService: _SetMouseData: _SetScreen: _SysMsgBoardStr: + +_WaitEvent: + ret .section .drectve @@ -131,6 +153,8 @@ _SysMsgBoardStr: .ascii " -export:AttachIntHandler" # stdcall + .ascii " -export:CreateEvent" # + .ascii " -export:CreateRingBuffer" # stdcall .ascii " -export:Delay" # stdcall @@ -140,6 +164,7 @@ _SysMsgBoardStr: .ascii " -export:FreeKernelSpace" # stdcall .ascii " -export:GetDisplay" # stdcall + .ascii " -export:GetEvent" # .ascii " -export:GetPgAddr" # stdcall .ascii " -export:GetService" # stdcall @@ -160,10 +185,13 @@ _SysMsgBoardStr: .ascii " -export:PciWrite32" # stdcall .ascii " -export:PciWrite8" # stdcall + .ascii " -export:RaiseEvent" # + .ascii " -export:RegService" # stdcall .ascii " -export:SetMouseData" # stdcall .ascii " -export:SetScreen" # stdcall .ascii " -export:SysMsgBoardStr" # stdcall + .ascii " -export:WaitEvent" # stdcall diff --git a/drivers/include/syscall.h b/drivers/include/syscall.h index fac26a727f..d99bb71e1c 100644 --- a/drivers/include/syscall.h +++ b/drivers/include/syscall.h @@ -5,6 +5,12 @@ #define OS_BASE 0x80000000 +typedef struct +{ + u32_t code; + u32_t data[5]; +}kevent_t; + typedef struct { u32_t handle; @@ -51,10 +57,10 @@ void* STDCALL KernelFree(void *mem)__asm__("KernelFree"); void* STDCALL UserAlloc(size_t size)__asm__("UserAlloc"); 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"); 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; @@ -118,7 +141,7 @@ static inline int GetScreenSize() return retval; } -static inline int GetScreenBpp() +static inline int GetScreenBpp(void) { int retval; @@ -128,7 +151,7 @@ static inline int GetScreenBpp() return retval; } -static inline int GetScreenPitch() +static inline int GetScreenPitch(void) { int retval; @@ -245,26 +268,6 @@ static inline void __DestroyObject(void *obj) :::"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) { 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) { 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__ ( "call *__imp__ChangeTask"); } -static inline sysSetScreen(int width, int height, int pitch) +static inline void sysSetScreen(int width, int height, int pitch) { __asm__ __volatile__ ( diff --git a/drivers/usb/uhci/detect.inc b/drivers/usb/uhci/detect.inc index 975f9ed777..50a5bc86e1 100644 --- a/drivers/usb/uhci/detect.inc +++ b/drivers/usb/uhci/detect.inc @@ -9,6 +9,8 @@ bool FindUSBControllers() 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 @@ bool FindUSBControllers() 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 @@ 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); retval = true; }; diff --git a/drivers/usb/uhci/hcd.inc b/drivers/usb/uhci/hcd.inc index 986f1b0cb4..b3659616e7 100644 --- a/drivers/usb/uhci/hcd.inc +++ b/drivers/usb/uhci/hcd.inc @@ -124,24 +124,45 @@ void hc_interrupt() { 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 @@ request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir, 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 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid, 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,19 +520,33 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid, 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) || @@ -513,6 +566,10 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid, retval = false; } else retval = true; + qh->qelem = 1; + + mb(); + do { td_prev = td->bk; @@ -520,6 +577,11 @@ bool ctrl_request(udev_t *dev, void *req, u32_t pid, td = td_prev; }while( td != NULL); +/* + delete event; +*/ + kfree(rq); + return retval; }; @@ -545,7 +607,10 @@ bool init_device(udev_t *dev) 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; diff --git a/drivers/usb/uhci/hid.inc b/drivers/usb/uhci/hid.inc index 698d5b73b1..e1a0adc9d8 100644 --- a/drivers/usb/uhci/hid.inc +++ b/drivers/usb/uhci/hid.inc @@ -103,6 +103,7 @@ bool init_hid(udev_t *dev) bool mouse_handler(udev_t *dev, struct tag_request *rq) { td_t *td; + qh_t *qh; 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->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 @@ void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d) 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"); } diff --git a/drivers/usb/uhci/usb.c b/drivers/usb/uhci/usb.c index 365a610ae6..44bec1f4a8 100644 --- a/drivers/usb/uhci/usb.c +++ b/drivers/usb/uhci/usb.c @@ -104,42 +104,25 @@ u32_t drvEntry(int action, char *cmdline) { 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); diff --git a/drivers/usb/uhci/usb.h b/drivers/usb/uhci/usb.h index 30c590cf71..447774093a 100644 --- a/drivers/usb/uhci/usb.h +++ b/drivers/usb/uhci/usb.h @@ -44,16 +44,6 @@ typedef struct #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 { @@ -81,6 +71,8 @@ typedef struct 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 @@ typedef struct tag_request 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;