/drivers/usb/uhci/usb.lk |
---|
File deleted |
/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 |
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 |
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 |
} |
} |
}; |
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 |
/drivers/usb/uhci/hcd.inc |
---|
118,7 → 118,7 |
} |
Bool init_hc(hc_t *hc) |
bool init_hc(hc_t *hc) |
{ |
int port; |
u32_t ifl; |
212,7 → 212,7 |
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 |
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 |
}; |
if(set_address(dev)) { |
list_prepend(&dev->link, &newdev_list); |
list_add_tail(&dev->list, &newdev_list); |
hc->port_map |= 1<<port; |
} |
else { |
255,7 → 254,7 |
}; |
}; |
}; |
return TRUE; |
return true; |
}; |
u16_t __attribute__((aligned(16))) |
269,7 → 268,7 |
*/ |
Bool set_address(udev_t *dev) |
bool set_address(udev_t *dev) |
{ |
static udev_id = 0; |
static udev_addr = 0; |
292,7 → 291,7 |
req_addr[1] = address; |
if( !ctrl_request(dev, &req_addr, DOUT, NULL, 0)) |
return FALSE; |
return false; |
dev->addr = address; |
dev->id = (++udev_id << 8) | address; |
303,12 → 302,12 |
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,12 → 316,12 |
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; |
333,8 → 332,13 |
td_prev = NULL; |
while(req_size >= enp->size) |
while(size > 0) |
{ |
if ( size < packet_size) |
{ |
packet_size = size; |
}; |
td = alloc_td(); |
td->link = 1; |
344,7 → 348,7 |
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; |
351,29 → 355,10 |
td_prev = td; |
data_dma+= enp->size; |
req_size-= enp->size; |
data_dma+= packet_size; |
size-= packet_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; |
enp->toggle ^= DATA1; |
} |
rq->td_tail = td; |
/* |
dbgprintf("create request %x\n" |
387,7 → 372,7 |
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 |
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 |
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,22 → 416,7 |
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 |
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 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 |
break; |
case USB_CLASS_HID: |
dev->conf = conf; |
list_remove(&dev->link); |
list_del(&dev->list); |
return init_hid(dev); |
case USB_CLASS_PRINTER: |
/drivers/usb/uhci/hid.inc |
---|
16,7 → 16,7 |
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 |
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 |
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 |
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"); |
} |
/drivers/usb/uhci/makefile |
---|
1,17 → 1,22 |
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 |
INCLUDES = -I ../../include |
DEFINES = -D__KERNEL__ -DCONFIG_X86_32 |
HFILES:= ../../include/types.h \ |
../../include/syscall.h \ |
../../include/link.h \ |
../../include/pci.h \ |
usb.h |
DRV_TOPDIR = $(CURDIR)/../.. |
DRV_INCLUDES = $(DRV_TOPDIR)/include |
INCLUDES = -I$(DRV_INCLUDES) \ |
-I$(DRV_INCLUDES)/linux |
LIBPATH = $(DRV_TOPDIR)/ddk |
SRC_DEP:= pci.inc \ |
detect.inc \ |
hcd.inc \ |
21,6 → 26,7 |
USB_OBJ:= usb.obj |
LIBS:= -ldrv -lcore |
USB = usb.dll |
27,11 → 33,11 |
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 $@ $< |
/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; |
/drivers/usb/uhci/usb.c |
---|
1,30 → 1,30 |
#include "types.h" |
#include "link.h" |
#include <kernel.h> |
#include <mutex.h> |
#include <pci.h> |
#include <stdio.h> |
#include <malloc.h> |
#include <memory.h> |
//#include <stdio.h> |
//#include <malloc.h> |
//#include <memory.h> |
#include "pci.h" |
#include "syscall.h" |
#include <syscall.h> |
#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 |
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 |
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 |
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 |
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; |
/drivers/usb/uhci/usb.h |
---|
1,5 → 1,7 |
typedef struct list_head list_t; |
typedef struct { |
int available; /**< Count of available items in this slab. */ |
void *start; /**< Start address of first item. */ |
38,7 → 40,7 |
typedef struct |
{ |
link_t link; |
list_t list; |
addr_t iobase; |
184,7 → 186,7 |
typedef struct |
{ |
link_t link; |
list_t list; |
u32_t id; |
hc_t *host; |
205,7 → 207,7 |
typedef struct tag_request |
{ |
link_t link; |
list_t list; |
td_t *td_head; |
td_t *td_tail; |
addr_t data; |
212,7 → 214,7 |
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 |
#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; |
char x; |
char y; |
char z; |
}__attribute__ ((packed)); |
#define DOUT 0xE1 |
/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) |
} |
} |