Subversion Repositories Kolibri OS

Compare Revisions

Regard whitespace Rev 1500 → Rev 1600

/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)
}
 
}