--- linux-2.6.11-rc1.orig/drivers/usb/host/sl811-hcd.c Wed Jan 12 05:00:38 2005 +++ linux-2.6.11-rc1/drivers/usb/host/sl811-hcd.c Thu Feb 17 04:37:55 2005 @@ -83,8 +83,9 @@ */ #define DISABLE_ISO -// #define QUIRK2 -#define QUIRK3 +/* with other QUIRK combinations it crashes */ +#define QUIRK2 +//#define QUIRK3 static const char hcd_name[] = "sl811-hcd"; @@ -831,8 +832,11 @@ #endif /* avoid all allocations within spinlocks */ - if (!hep->hcpriv) + if (!hep->hcpriv) { ep = kcalloc(1, sizeof *ep, mem_flags); + /* set hep, otherwise sl811h_ep *start(struct sl811 *sl811, u8 bank) crashes */ + ep->hep = hep; + } spin_lock_irqsave(&sl811->lock, flags); @@ -952,7 +956,11 @@ retval = 0; goto fail; } - urb->hcpriv = hep; + + /* when uncommented, causes this error on mouse open: + drivers/usb/input/usbmouse.c: can't resubmit intr, sl811-hcd-1/input0, status -22 + urb->hcpriv = hep; */ + spin_unlock(&urb->lock); start_transfer(sl811); @@ -1037,6 +1045,9 @@ /* assume we'd just wait for the irq */ if (!list_empty(&hep->urb_list)) msleep(3); + + /* this error occurs, when the device is connected, opened and then disconnected; + after this warning, the process freezes */ if (!list_empty(&hep->urb_list)) WARN("ep %p not empty?\n", ep); @@ -1580,6 +1591,14 @@ if (sl811->board && sl811->board->power) hub_set_power_budget(udev, sl811->board->power * 2); + // enable power and interupts + port_power(sl811, 1); + + /* reset USB (without this the devices were not detected at boot, only after plugging) */ + sl811_write(sl811, SL11H_CTLREG1, 0x08); + mdelay(20); + sl811_write(sl811, SL11H_CTLREG1, 0); + return 0; } @@ -1639,11 +1658,11 @@ free_irq(hcd->irq, hcd); iounmap(sl811->data_reg); - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); release_mem_region(res->start, 1); iounmap(sl811->addr_reg); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + res = platform_get_resource(pdev, IORESOURCE_IO, 0); release_mem_region(res->start, 1); usb_put_hcd(hcd); @@ -1674,8 +1693,28 @@ if (pdev->num_resources < 3) return -ENODEV; - addr = platform_get_resource(pdev, IORESOURCE_MEM, 0); - data = platform_get_resource(pdev, IORESOURCE_MEM, 1); + /* IORESOURCE_IO, because I think it is IO access. The following + resources in the platform description file works: + static struct resource usb_resources[] = { + [0] = { + .start = YOUR_PLATFORM_USB_PHYS, + .end = YOUR_PLATFORM_USB_PHYS + 256 + .flags = IORESOURCE_IO, + }, + [1] = { + .start = YOUR_PLATFORM_USB_PHYS + 0x010000, + .end = YOUR_PLATFORM_USB_PHYS + 0x010000 + 256 + .flags = IORESOURCE_MEM, + }, + [2] = { + .start = USB_IRQ, + .end = USB_IRQ, + .flags = IORESOURCE_IRQ, + }, + };*/ + + addr = platform_get_resource(pdev, IORESOURCE_IO, 0); + data = platform_get_resource(pdev, IORESOURCE_MEM, 0); irq = platform_get_irq(pdev, 0); if (!addr || !data || irq < 0) return -ENODEV; @@ -1700,7 +1739,7 @@ retval = -EBUSY; goto err3; } - data_reg = ioremap(data->start, resource_len(addr)); + data_reg = ioremap(data->start, resource_len(data)); if (data_reg == NULL) { retval = -ENOMEM; goto err4; @@ -1728,7 +1767,6 @@ sl811->timer.data = (unsigned long) sl811; sl811->addr_reg = addr_reg; sl811->data_reg = data_reg; - spin_lock_irq(&sl811->lock); port_power(sl811, 0); spin_unlock_irq(&sl811->lock);