diff --git a/drivers/usb/uhci/detect.inc b/drivers/usb/uhci/detect.inc index eb892f35cb..8ae16f99ab 100644 --- a/drivers/usb/uhci/detect.inc +++ b/drivers/usb/uhci/detect.inc @@ -1,8 +1,8 @@ -Bool FindPciDevice() +bool FindUSBControllers() { - Bool retval = FALSE; + bool retval = false; u32_t bus, last_bus; PCITAG tag; @@ -35,9 +35,8 @@ Bool FindPciDevice() if (! pcicmd & PCI_COMMAND_IO) continue; - hc = (hc_t*)malloc(sizeof(hc_t)); - memset(hc, 0, sizeof(hc_t)); - link_initialize(&hc->link); + hc = (hc_t*)kmalloc(sizeof(hc_t), 0); + INIT_LIST_HEAD(&hc->list); hc->pciId = PciRead32(bus,devfn, 0); hc->PciTag = pciTag(bus,(devfn>>3)&0x1F,devfn&0x7); @@ -45,7 +44,7 @@ Bool FindPciDevice() for (i = 0; i < 6; i++) { u32_t base; - Bool validSize; + bool validSize; base = PciRead32(bus,devfn, PCI_MAP_REG_START + (i << 2)); if(base) @@ -59,9 +58,164 @@ Bool FindPciDevice() } } }; - list_prepend(&hc->link, &hc_list); - retval = TRUE; + list_add_tail(&hc->list, &hc_list); + retval = true; }; }; return retval; }; + + +#if 0 + +/* these helpers provide future and backwards compatibility + * for accessing popular PCI BAR info */ +#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start) +#define pci_resource_end(dev, bar) ((dev)->resource[(bar)].end) +#define pci_resource_flags(dev, bar) ((dev)->resource[(bar)].flags) +#define pci_resource_len(dev,bar) \ + ((pci_resource_start((dev), (bar)) == 0 && \ + pci_resource_end((dev), (bar)) == \ + pci_resource_start((dev), (bar))) ? 0 : \ + \ + (pci_resource_end((dev), (bar)) - \ + pci_resource_start((dev), (bar)) + 1)) + +static int __devinit mmio_resource_enabled(struct pci_dev *pdev, int idx) +{ + return pci_resource_start(pdev, idx) && mmio_enabled(pdev); +} + +static void __devinit quirk_usb_disable_ehci(struct pci_dev *pdev) +{ + int wait_time, delta; + void __iomem *base, *op_reg_base; + u32 hcc_params, val; + u8 offset, cap_length; + int count = 256/4; + int tried_handoff = 0; + + if (!mmio_resource_enabled(pdev, 0)) + return; + + base = pci_ioremap_bar(pdev, 0); + if (base == NULL) + return; + + cap_length = readb(base); + op_reg_base = base + cap_length; + + /* EHCI 0.96 and later may have "extended capabilities" + * spec section 5.1 explains the bios handoff, e.g. for + * booting from USB disk or using a usb keyboard + */ + hcc_params = readl(base + EHCI_HCC_PARAMS); + offset = (hcc_params >> 8) & 0xff; + while (offset && --count) { + u32 cap; + int msec; + + pci_read_config_dword(pdev, offset, &cap); + switch (cap & 0xff) { + case 1: /* BIOS/SMM/... handoff support */ + if ((cap & EHCI_USBLEGSUP_BIOS)) { + dev_dbg(&pdev->dev, "EHCI: BIOS handoff\n"); + +#if 0 +/* aleksey_gorelov@phoenix.com reports that some systems need SMI forced on, + * but that seems dubious in general (the BIOS left it off intentionally) + * and is known to prevent some systems from booting. so we won't do this + * unless maybe we can determine when we're on a system that needs SMI forced. + */ + /* BIOS workaround (?): be sure the + * pre-Linux code receives the SMI + */ + pci_read_config_dword(pdev, + offset + EHCI_USBLEGCTLSTS, + &val); + pci_write_config_dword(pdev, + offset + EHCI_USBLEGCTLSTS, + val | EHCI_USBLEGCTLSTS_SOOE); +#endif + + /* some systems get upset if this semaphore is + * set for any other reason than forcing a BIOS + * handoff.. + */ + pci_write_config_byte(pdev, offset + 3, 1); + } + + /* if boot firmware now owns EHCI, spin till + * it hands it over. + */ + msec = 1000; + while ((cap & EHCI_USBLEGSUP_BIOS) && (msec > 0)) { + tried_handoff = 1; + msleep(10); + msec -= 10; + pci_read_config_dword(pdev, offset, &cap); + } + + if (cap & EHCI_USBLEGSUP_BIOS) { + /* well, possibly buggy BIOS... try to shut + * it down, and hope nothing goes too wrong + */ + dev_warn(&pdev->dev, "EHCI: BIOS handoff failed" + " (BIOS bug?) %08x\n", cap); + pci_write_config_byte(pdev, offset + 2, 0); + } + + /* just in case, always disable EHCI SMIs */ + pci_write_config_dword(pdev, + offset + EHCI_USBLEGCTLSTS, + 0); + + /* If the BIOS ever owned the controller then we + * can't expect any power sessions to remain intact. + */ + if (tried_handoff) + writel(0, op_reg_base + EHCI_CONFIGFLAG); + break; + case 0: /* illegal reserved capability */ + cap = 0; + /* FALLTHROUGH */ + default: + dev_warn(&pdev->dev, "EHCI: unrecognized capability " + "%02x\n", cap & 0xff); + break; + } + offset = (cap >> 8) & 0xff; + } + if (!count) + dev_printk(KERN_DEBUG, &pdev->dev, "EHCI: capability loop?\n"); + + /* + * halt EHCI & disable its interrupts in any case + */ + val = readl(op_reg_base + EHCI_USBSTS); + if ((val & EHCI_USBSTS_HALTED) == 0) { + val = readl(op_reg_base + EHCI_USBCMD); + val &= ~EHCI_USBCMD_RUN; + writel(val, op_reg_base + EHCI_USBCMD); + + wait_time = 2000; + delta = 100; + do { + writel(0x3f, op_reg_base + EHCI_USBSTS); + udelay(delta); + wait_time -= delta; + val = readl(op_reg_base + EHCI_USBSTS); + if ((val == ~(u32)0) || (val & EHCI_USBSTS_HALTED)) { + break; + } + } while (wait_time > 0); + } + writel(0, op_reg_base + EHCI_USBINTR); + writel(0x3f, op_reg_base + EHCI_USBSTS); + + iounmap(base); + + return; +} + +#endif diff --git a/drivers/usb/uhci/hcd.inc b/drivers/usb/uhci/hcd.inc index 1ab8248f18..37eff3f31d 100644 --- a/drivers/usb/uhci/hcd.inc +++ b/drivers/usb/uhci/hcd.inc @@ -118,11 +118,11 @@ reset_needed: } -Bool init_hc(hc_t *hc) +bool init_hc(hc_t *hc) { - int port; - u32_t ifl; - u16_t dev_status; + int port; + u32_t ifl; + u16_t dev_status; int i; dbgprintf("\n\ninit uhci %x\n\n", hc->pciId); @@ -212,7 +212,7 @@ Bool init_hc(hc_t *hc) status = in16(hc->iobase + USBPORTSC1 + (port * 2)); if(status & 1) { - udev_t *dev = malloc(sizeof(udev_t)); + udev_t *dev = kmalloc(sizeof(udev_t),0); out16(hc->iobase + USBPORTSC1 + (port * 2), 0x0E); @@ -222,10 +222,9 @@ Bool init_hc(hc_t *hc) status = in16(hc->iobase + USBPORTSC1 + (port * 2)); dbgprintf("port%d status %x\n", port, status); - link_initialize(&dev->link); - dev->id = 0; + INIT_LIST_HEAD(&dev->list); + dev->host = hc; - dev->addr = 0; dev->port = port; dev->ep0_size = 8; dev->status = status; @@ -244,7 +243,7 @@ Bool init_hc(hc_t *hc) }; if(set_address(dev)) { - list_prepend(&dev->link, &newdev_list); + list_add_tail(&dev->list, &newdev_list); hc->port_map |= 1<addr = address; dev->id = (++udev_id << 8) | address; @@ -303,12 +302,12 @@ Bool set_address(udev_t *dev) data[1] = 0; if( !ctrl_request(dev, &req_descr, DIN, data, 8)) - return FALSE; + return false; dev_descr_t *descr = (dev_descr_t*)&data; dev->ep0_size = descr->bMaxPacketSize0; - return TRUE; + return true; } request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir, @@ -317,26 +316,31 @@ request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir, td_t *td, *td_prev; addr_t data_dma; - request_t *rq = (request_t*)malloc(sizeof(request_t)); + size_t packet_size = enp->size; + size_t size = req_size; - link_initialize(&rq->link); + request_t *rq = (request_t*)kmalloc(sizeof(request_t),0); - rq->td_head = 0; - rq->td_tail = 0; + INIT_LIST_HEAD(&rq->list); rq->data = (addr_t)data; rq->size = req_size; - rq->dev = dev; + rq->dev = dev; if(data) data_dma = DMA(data); td_prev = NULL; - while(req_size >= enp->size) + while(size > 0) { + if ( size < packet_size) + { + packet_size = size; + }; + td = alloc_td(); - td->link = 1; + td->link = 1; if(rq->td_head == NULL) rq->td_head = td; @@ -344,34 +348,15 @@ request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir, if( td_prev ) td_prev->link = td->dma | 4; td->status = 0x00800000 | dev->speed; - td->token = TOKEN(enp->size,enp->toggle,enp->address, + td->token = TOKEN(packet_size,enp->toggle,enp->address, dev->addr,dir); td->buffer = data_dma; td->bk = td_prev; td_prev = td; - data_dma+= enp->size; - req_size-= enp->size; - enp->toggle ^= DATA1; - } - if(req_size) - { - td = alloc_td(); - td->link = 1; - - if(rq->td_head == NULL) - rq->td_head = td; - - if( td_prev ) - td_prev->link = td->dma | 4; - - td->status = 0x00800000 | dev->speed; - td->token = TOKEN( req_size, enp->toggle, enp->address, - dev->addr, dir); - td->buffer = data_dma; - td->bk = td_prev; - + data_dma+= packet_size; + size-= packet_size; enp->toggle ^= DATA1; } rq->td_tail = td; @@ -387,7 +372,7 @@ request_t *create_request(udev_t *dev, endp_t *enp, u32_t dir, return rq; } -Bool ctrl_request(udev_t *dev, void *req, u32_t pid, +bool ctrl_request(udev_t *dev, void *req, u32_t pid, void *data, size_t req_size) { size_t packet_size = dev->ep0_size; @@ -397,7 +382,7 @@ Bool ctrl_request(udev_t *dev, void *req, u32_t pid, td_t *td0, *td, *td_prev; qh_t *qh; addr_t data_dma = 0; - Bool retval; + bool retval; td0 = alloc_td(); @@ -411,8 +396,13 @@ Bool ctrl_request(udev_t *dev, void *req, u32_t pid, td_prev = td0; - while(size >= packet_size) + while(size > 0) { + if ( size < packet_size) + { + packet_size = size; + }; + td = alloc_td(); td_prev->link = td->dma | 4; td->status = 0x00800000 | dev->speed; @@ -426,21 +416,6 @@ Bool ctrl_request(udev_t *dev, void *req, u32_t pid, size-= packet_size; toggle ^= DATA1; } - if(size) - { - td = alloc_td(); - td_prev->link = td->dma | 4; - td->status = 0x00800000 | dev->speed; - td->token = ((size-1)<<21)|toggle|(dev->addr<<8)|pid; - td->buffer = data_dma; - td->bk = td_prev; - - td_prev = td; - - data_dma+= packet_size; - size-= packet_size; - toggle ^= DATA1; - } td = alloc_td(); td_prev->link = td->dma | 4; @@ -480,8 +455,8 @@ Bool ctrl_request(udev_t *dev, void *req, u32_t pid, dbgprintf("td status %x\n",td->status); dbgprintf("qh %x \n", qh->qelem); - retval = FALSE; - } else retval = TRUE; + retval = false; + } else retval = true; do { @@ -494,7 +469,7 @@ Bool ctrl_request(udev_t *dev, void *req, u32_t pid, }; -Bool init_device(udev_t *dev) +bool init_device(udev_t *dev) { static u16_t __attribute__((aligned(16))) req_descr[4] = {0x0680,0x0100,0x0000,18}; @@ -586,7 +561,7 @@ Bool init_device(udev_t *dev) break; case USB_CLASS_HID: dev->conf = conf; - list_remove(&dev->link); + list_del(&dev->list); return init_hid(dev); case USB_CLASS_PRINTER: diff --git a/drivers/usb/uhci/hid.inc b/drivers/usb/uhci/hid.inc index 598f9227b4..265cb74e45 100644 --- a/drivers/usb/uhci/hid.inc +++ b/drivers/usb/uhci/hid.inc @@ -16,7 +16,7 @@ struct hid_descriptor { void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d); -Bool init_hid(udev_t *dev) +bool init_hid(udev_t *dev) { interface_descr_t *interface; struct hid_descriptor *hds; @@ -96,11 +96,11 @@ Bool init_hid(udev_t *dev) if( interface->bInterfaceProtocol == 2) create_hid_mouse(dev, ep); // } - return TRUE; + return true; }; -Bool mouse_handler(udev_t *dev, struct tag_request *rq) +bool mouse_handler(udev_t *dev, struct tag_request *rq) { td_t *td; @@ -115,7 +115,7 @@ Bool mouse_handler(udev_t *dev, struct tag_request *rq) td->status = 0x00800000 | dev->speed; td->token ^= DATA1; - return TRUE; + return true; }; void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d) @@ -142,13 +142,12 @@ void create_hid_mouse(udev_t *dev, endpoint_descr_t *en_d) enp.size = en_d->wMaxPacketSize; enp.toggle = DATA0; - packet = malloc(enp.size); - memset(packet, 0, enp.size); + packet = kzalloc(enp.size, 0); rq = create_request(dev, &enp, DIN, packet, enp.size); rq->handler = &mouse_handler; - list_prepend(&rq->link, &rq_list); + list_add_tail(&rq->list, &rq_list); dbgprintf("create_hid_mouse\n"); } diff --git a/drivers/usb/uhci/makefile b/drivers/usb/uhci/makefile index f40c710c4d..0de8aff0ee 100644 --- a/drivers/usb/uhci/makefile +++ b/drivers/usb/uhci/makefile @@ -1,16 +1,21 @@ CC = gcc -FASM = e:/fasm/fasm.exe CFLAGS = -c -O2 -fomit-frame-pointer -fno-builtin-printf -LDRHD = -shared -T ld.x -s --file-alignment 32 +LDFLAGS = -nostdlib -shared -s -Map usb.map --image-base 0\ + --file-alignment 512 --section-alignment 4096 + +DEFINES = -D__KERNEL__ -DCONFIG_X86_32 + +DRV_TOPDIR = $(CURDIR)/../.. + +DRV_INCLUDES = $(DRV_TOPDIR)/include + +INCLUDES = -I$(DRV_INCLUDES) \ + -I$(DRV_INCLUDES)/linux + +LIBPATH = $(DRV_TOPDIR)/ddk -INCLUDES = -I ../../include -HFILES:= ../../include/types.h \ - ../../include/syscall.h \ - ../../include/link.h \ - ../../include/pci.h \ - usb.h SRC_DEP:= pci.inc \ detect.inc \ @@ -21,17 +26,18 @@ USB_SRC:= usb.c USB_OBJ:= usb.obj +LIBS:= -ldrv -lcore USB = usb.dll all: $(USB) $(USB): $(USB_OBJ) $(SRC_DEP) $(HFILES) Makefile - wlink name usb.dll SYS nt_dll lib libdrv op offset=0 op nod op maxe=25 op el op STUB=stub.exe op START=_drvEntry @usb.lk + ld $(LDFLAGS) -L$(LIBPATH) -T usb.lds -o $@ $(USB_OBJ) $(LIBS) kpack.exe usb.dll usb.drv usb.obj : usb.c $(SRC_DEP) $(HFILES) Makefile - $(CC) $(INCLUDES) $(CFLAGS) -o usb.obj usb.c + $(CC) $(DEFINES) $(INCLUDES) $(CFLAGS) -o usb.obj usb.c %.obj : %.c $(HFILES) $(CC) $(CFLAGS) -o $@ $< diff --git a/drivers/usb/uhci/pci.inc b/drivers/usb/uhci/pci.inc index 2db682ad91..e6bb11b05a 100644 --- a/drivers/usb/uhci/pci.inc +++ b/drivers/usb/uhci/pci.inc @@ -1,7 +1,7 @@ u32_t pciGetBaseSize(int bus, int devfn, int index, - Bool destructive, Bool *min) + bool destructive, bool *min) { int offset; u32_t addr1; diff --git a/drivers/usb/uhci/usb.c b/drivers/usb/uhci/usb.c index 8169237963..68afba4e4e 100644 --- a/drivers/usb/uhci/usb.c +++ b/drivers/usb/uhci/usb.c @@ -1,30 +1,30 @@ -#include "types.h" -#include "link.h" +#include +#include +#include -#include -#include -#include +//#include +//#include +//#include -#include "pci.h" -#include "syscall.h" +#include #include "usb.h" int __stdcall srv_usb(ioctl_t *io); -Bool init_hc(hc_t *hc); +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; +LIST_HEAD( hc_list ); +LIST_HEAD( newdev_list ); +LIST_HEAD( rq_list ); -u32_t __stdcall drvEntry(int action) +u32_t drvEntry(int action, char *cmdline) { u32_t retval; hc_t *hc; @@ -41,11 +41,7 @@ u32_t __stdcall drvEntry(int action) return 0; } - list_initialize(&hc_list); - list_initialize(&newdev_list); - list_initialize(&rq_list); - - if( !FindPciDevice() ) { + if( !FindUSBControllers() ) { dbgprintf("no uhci devices found\n"); return 0; }; @@ -86,19 +82,19 @@ u32_t __stdcall drvEntry(int action) hc = (hc_t*)hc_list.next; - while( &hc->link != &hc_list) + while( &hc->list != &hc_list) { init_hc(hc); - hc = (hc_t*)hc->link.next; + hc = (hc_t*)hc->list.next; } dbgprintf("\n"); dev = (udev_t*)newdev_list.next; - while( &dev->link != &newdev_list) + while( &dev->list != &newdev_list) { udev_t *tmp = dev; - dev = (udev_t*)dev->link.next; + dev = (udev_t*)dev->list.next; if(tmp->id != 0) init_device(tmp); @@ -110,7 +106,7 @@ u32_t __stdcall drvEntry(int action) request_t *rq; rq = (request_t*)rq_list.next; - while( &rq->link != &rq_list) + while( &rq->list != &rq_list) { qh_t *qh; td_t *td; @@ -122,19 +118,19 @@ u32_t __stdcall drvEntry(int action) qh->qelem = td->dma; __asm__ __volatile__ ("":::"memory"); - rq = (request_t*)rq->link.next; + rq = (request_t*)rq->list.next; }; delay(10/10); rq = (request_t*)rq_list.next; - while( &rq->link != &rq_list) + while( &rq->list != &rq_list) { request_t *tmp; td_t *td; tmp = rq; - rq = (request_t*)rq->link.next; + rq = (request_t*)rq->list.next; td = tmp->td_head; diff --git a/drivers/usb/uhci/usb.h b/drivers/usb/uhci/usb.h index 2e53961157..e04283f79f 100644 --- a/drivers/usb/uhci/usb.h +++ b/drivers/usb/uhci/usb.h @@ -1,4 +1,6 @@ +typedef struct list_head list_t; + typedef struct { int available; /**< Count of available items in this slab. */ @@ -38,7 +40,7 @@ typedef struct typedef struct { - link_t link; + list_t list; addr_t iobase; @@ -184,7 +186,7 @@ typedef struct __attribute__ ((packed)) typedef struct { - link_t link; + list_t list; u32_t id; hc_t *host; @@ -205,14 +207,14 @@ typedef struct typedef struct tag_request { - link_t link; + list_t list; td_t *td_head; td_t *td_tail; addr_t data; size_t size; udev_t *dev; u32_t type; - Bool (*handler)(udev_t *dev, struct tag_request *rq); + bool (*handler)(udev_t *dev, struct tag_request *rq); }request_t; @@ -221,22 +223,23 @@ typedef struct tag_request #define TOKEN( size, toggle, ep, addr, pid) \ ( (((size)-1)<<21)|(toggle)|(((ep)&0xF)<<15)|((addr)<<8)|(pid)) -Bool ctrl_request(udev_t *dev, void *req, u32_t dir, +bool FindUSBControllers(); + +bool ctrl_request(udev_t *dev, void *req, u32_t dir, void *data, size_t req_size); +bool set_address(udev_t *dev); -Bool set_address(udev_t *dev); +bool init_device(udev_t *dev); -Bool init_device(udev_t *dev); - -Bool init_hid(udev_t *dev); +bool init_hid(udev_t *dev); struct boot_packet { - u8_t buttons; - i8_t x; - i8_t y; - i8_t z; + u8_t buttons; + char x; + char y; + char z; }__attribute__ ((packed)); #define DOUT 0xE1 diff --git a/drivers/usb/uhci/usb.lds b/drivers/usb/uhci/usb.lds new file mode 100644 index 0000000000..8bb43eefae --- /dev/null +++ b/drivers/usb/uhci/usb.lds @@ -0,0 +1,56 @@ + + +OUTPUT_FORMAT(pei-i386) + +ENTRY("_drvEntry") + +SECTIONS +{ + . = SIZEOF_HEADERS; + . = ALIGN(__section_alignment__); + + .text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) : + + { + *(.text) *(.rdata) + } + + .data ALIGN(__section_alignment__) : + { + *(.data) + } + + .bss ALIGN(__section_alignment__): + { + *(.bss) + *(COMMON) + } + + /DISCARD/ : + { + *(.debug$S) + *(.debug$T) + *(.debug$F) + *(.drectve) + *(.edata) + } + + .idata ALIGN(__section_alignment__): + { + SORT(*)(.idata$2) + SORT(*)(.idata$3) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + SORT(*)(.idata$4) + SORT(*)(.idata$5) + SORT(*)(.idata$6) + SORT(*)(.idata$7) + } + + .reloc ALIGN(__section_alignment__) : + { + *(.reloc) + } + +} + diff --git a/drivers/usb/uhci/usb.lk b/drivers/usb/uhci/usb.lk deleted file mode 100644 index 054e70e857..0000000000 --- a/drivers/usb/uhci/usb.lk +++ /dev/null @@ -1,22 +0,0 @@ -IMP - _KernelAlloc core.KernelAlloc, - _KernelFree core.KernelFree, - _UserAlloc core.UserAlloc, - _UserFree core.UserFree, - _MapIoMem core.MapIoMem, - _GetPgAddr core.GetPgAddr, - _PciApi core.PciApi, - _PciRead8 core.PciRead8, - _PciRead16 core.PciRead16, - _PciRead32 core.PciRead32, - _PciWrite16 core.PciWrite16, - _PciWrite32 core.PciWrite32, - _RegService core.RegService, - _SysMsgBoardStr core.SysMsgBoardStr, - _Delay core.Delay, - _SetMouseData core.SetMouseData - - -FIL usb.obj, - vsprintf.obj, - icompute.obj