From b50970fb744e5c7c937aa9188ab0bf33286d013f Mon Sep 17 00:00:00 2001 From: Sebastian Sumpf Date: Wed, 18 Jul 2012 15:40:43 +0200 Subject: [PATCH] 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 --- .../src/drivers/usb/arm/platform/platform.cc | 2 +- dde_linux/src/drivers/usb/dma.h | 3 +- dde_linux/src/drivers/usb/lx_emul.cc | 2 +- dde_linux/src/drivers/usb/main.cc | 5 +-- dde_linux/src/drivers/usb/pci_driver.cc | 36 +++++++++++-------- dde_linux/src/drivers/usb/signal/irq.cc | 5 ++- 6 files changed, 29 insertions(+), 24 deletions(-) diff --git a/dde_linux/src/drivers/usb/arm/platform/platform.cc b/dde_linux/src/drivers/usb/arm/platform/platform.cc index dbd8a061f8..aa361fdfc9 100644 --- a/dde_linux/src/drivers/usb/arm/platform/platform.cc +++ b/dde_linux/src/drivers/usb/arm/platform/platform.cc @@ -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; diff --git a/dde_linux/src/drivers/usb/dma.h b/dde_linux/src/drivers/usb/dma.h index 65ac83d93a..70f3c7996f 100644 --- a/dde_linux/src/drivers/usb/dma.h +++ b/dde_linux/src/drivers/usb/dma.h @@ -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; } diff --git a/dde_linux/src/drivers/usb/lx_emul.cc b/dde_linux/src/drivers/usb/lx_emul.cc index 177f279694..f86a307a4c 100644 --- a/dde_linux/src/drivers/usb/lx_emul.cc +++ b/dde_linux/src/drivers/usb/lx_emul.cc @@ -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; } diff --git a/dde_linux/src/drivers/usb/main.cc b/dde_linux/src/drivers/usb/main.cc index 10db6a80f7..2c4b368939 100644 --- a/dde_linux/src/drivers/usb/main.cc +++ b/dde_linux/src/drivers/usb/main.cc @@ -70,10 +70,7 @@ static void init(Services *services) module_usb_kbd_init(); } - /* - * Host controller. - * - */ + /* host controller */ platform_hcd_init(services); /* storage */ diff --git a/dde_linux/src/drivers/usb/pci_driver.cc b/dde_linux/src/drivers/usb/pci_driver.cc index d0fcd1c680..60d325337a 100644 --- a/dde_linux/src/drivers/usb/pci_driver.cc +++ b/dde_linux/src/drivers/usb/pci_driver.cc @@ -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; } diff --git a/dde_linux/src/drivers/usb/signal/irq.cc b/dde_linux/src/drivers/usb/signal/irq.cc index 9c2a5e0485..aa30920936 100644 --- a/dde_linux/src/drivers/usb/signal/irq.cc +++ b/dde_linux/src/drivers/usb/signal/irq.cc @@ -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); }