USB: Test and fix errors on x86 boxes

Added support for more than one UHCI controller. Make sure the 'PIRQ' bit in the
legacy support register (PCI config space) of the UHCI controller is enabled and
also that the 'Trap on IRQ' bit is disabled. Fix offset bug in PCI-config space
emulation for Linux.

Fixes #282
This commit is contained in:
Sebastian Sumpf 2012-07-18 15:40:43 +02:00 committed by Norman Feske
parent 9e582c59a9
commit b50970fb74
6 changed files with 29 additions and 24 deletions

View File

@ -398,7 +398,7 @@ void platform_hcd_init(Services *services)
/*
* Needed for DMA buffer allocation. See 'hcd_buffer_alloc' in 'buffer.c'
*/
static u64 dma_mask = ~(u32)0;
static u64 dma_mask = ~(u64)0;
pdev->dev.dma_mask = &dma_mask;
pdev->dev.coherent_dma_mask = ~0;

View File

@ -55,7 +55,7 @@ namespace Genode {
}
addr_t base() const { return _base; };
addr_t end() const { return _base + SIZE -1; }
addr_t end() const { return _base + SIZE - 1; }
/**
* Alloc 'size' bytes of DMA memory
@ -67,7 +67,6 @@ namespace Genode {
PERR("DMA of %zu bytes allocation failed", size);
return 0;
}
return addr;
}

View File

@ -610,7 +610,7 @@ static void* _alloc(size_t size, int align, dma_addr_t *dma)
return 0;
*dma = (dma_addr_t)Genode::Dma::pool()->phys_addr(addr);
dde_kit_log(DEBUG_DMA, "DMA pool alloc addr: %p size %zx align: %d, pysh: %lx", addr, size, align, *dma);
dde_kit_log(DEBUG_DMA, "DMA pool alloc addr: %p size %zx align: %d, phys: %lx", addr, size, align, *dma);
memset(addr, 0, size);
return addr;
}

View File

@ -70,10 +70,7 @@ static void init(Services *services)
module_usb_kbd_init();
}
/*
* Host controller.
*
*/
/* host controller */
platform_hcd_init(services);
/* storage */

View File

@ -93,6 +93,11 @@ class Pci_driver
_dev->revision = client.config_read(REV, Device::ACCESS_8BIT);
_dev->dev.driver = &_drv->driver;
/* dummy dma mask used to mark device as DMA capable */
static u64 dma_mask = ~(u64)0;
_dev->dev.dma_mask = &dma_mask;
_dev->dev.coherent_dma_mask = ~0;
/* read interrupt line */
_dev->irq = client.config_read(IRQ, Device::ACCESS_8BIT);
@ -221,6 +226,7 @@ int pci_register_driver(struct pci_driver *drv)
Pci::Device_capability cap = pci.first_device();
Pci::Device_capability old;
bool found = false;
while (cap.valid()) {
uint8_t bus, dev, func;
@ -228,11 +234,11 @@ int pci_register_driver(struct pci_driver *drv)
client.bus_address(&bus, &dev, &func);
dde_kit_log(DEBUG_PCI, "bus: %x dev: %x func: %x", bus, dev, func);
Pci_driver *pci_drv= 0;
Pci_driver *pci_drv = 0;
try {
pci_drv = new (env()->heap()) Pci_driver(drv, cap);
pci.on_destruction(Pci::Connection::KEEP_OPEN);
return 0;
found = true;
} catch (...) {
destroy(env()->heap(), pci_drv);
pci_drv = 0;
@ -243,7 +249,7 @@ int pci_register_driver(struct pci_driver *drv)
pci.release_device(old);
}
return -ENODEV;
return found ? 0 : -ENODEV;
}
@ -276,38 +282,38 @@ unsigned int pci_resource_flags(struct pci_dev *dev, unsigned bar)
}
int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int devfn, int, u8 *val)
int pci_bus_read_config_byte(struct pci_bus *bus, unsigned int, int where, u8 *val)
{
Pci_driver *drv = (Pci_driver *)bus;
drv->config_read(devfn, val);
dde_kit_log(DEBUG_PCI, "READ %p: %x", drv, *val);
drv->config_read(where, val);
dde_kit_log(DEBUG_PCI, "READ %p: where: %x val: %x", drv, where, *val);
return 0;
}
int pci_bus_read_config_word(struct pci_bus *bus, unsigned int devfn, int, u16 *val)
int pci_bus_read_config_word(struct pci_bus *bus, unsigned int, int where, u16 *val)
{
Pci_driver *drv = (Pci_driver *)bus;
drv->config_read(devfn, val);
dde_kit_log(DEBUG_PCI, "READ %p: %x", drv, *val);
drv->config_read(where, val);
dde_kit_log(DEBUG_PCI, "READ %p: where: %x val: %x", drv, where, *val);
return 0;
}
int pci_bus_write_config_word(struct pci_bus *bus, unsigned int devfn, int, u16 val)
int pci_bus_write_config_word(struct pci_bus *bus, unsigned int, int where, u16 val)
{
Pci_driver *drv = (Pci_driver *)bus;
dde_kit_log(DEBUG_PCI, "WRITE %p: %x", drv, val);
drv->config_write(devfn, val);
dde_kit_log(DEBUG_PCI, "WRITE %p: where: %x val: %x", drv, where, val);
drv->config_write(where, val);
return 0;
}
int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int devfn, int, u8 val)
int pci_bus_write_config_byte(struct pci_bus *bus, unsigned int, int where, u8 val)
{
Pci_driver *drv = (Pci_driver *)bus;
dde_kit_log(DEBUG_PCI, "WRITE %p: %x", drv, val);
drv->config_write(devfn, val);
dde_kit_log(DEBUG_PCI, "WRITE %p: where: %x val: %x", drv, where, val);
drv->config_write(where, val);
return 0;
}

View File

@ -83,7 +83,10 @@ class Irq_context : public Driver_context,
_ctx_cap(_signal->receiver()->manage(this))
{
/* register at DDE (shared) */
dde_kit_interrupt_attach(_irq, 1, 0, _dde_handler, this);
int ret = dde_kit_interrupt_attach(_irq, 0, 0, _dde_handler, this);
if (ret)
PERR("Interrupt attach return %d for IRQ %u", ret, irq);
dde_kit_interrupt_enable(_irq);
_list()->insert(this);
}