usb-ohci leaks PCI pool memory. I discovered that on a machine with two pc-card interfaces, both of which have an OHCI on them. (Behind the OHCI is a three-port serial interface which thinks it's a GSM phone. ;-)
"cardctl eject 0" says: Sep 10 15:48:23 clu kernel: usb.c: USB disconnect on device 06:00.0-0 address 1 Sep 10 15:48:23 clu kernel: usb.c: USB disconnect on device 06:00.0-1 address 2 Sep 10 15:48:23 clu kernel: usbserial.c: Generic converter now disconnected from ttyUSB3 Sep 10 15:48:23 clu kernel: usbserial.c: Generic converter now disconnected from ttyUSB4 Sep 10 15:48:23 clu kernel: usbserial.c: Generic converter now disconnected from ttyUSB5 Sep 10 15:48:23 clu kernel: usb-ohci.c: free device 2 timeout Sep 10 15:48:24 clu kernel: usb-ohci.c: USB HC TakeOver failed! Sep 10 15:48:24 clu kernel: usb.c: USB bus 2 deregistered Sep 10 15:48:24 clu kernel: pci_pool_destroy 06:00.0/ohci_td, c037f000 busy Sep 10 15:48:24 clu kernel: pci_pool_destroy 06:00.0/ohci_dev, c0381000 busy Sep 10 15:48:24 clu kernel: cs: cb_free(bus 6) Sep 10 15:48:25 clu kernel: usb.c: USB disconnect on device 02:00.0-0 address 1 Sep 10 15:48:25 clu kernel: usb.c: USB disconnect on device 02:00.0-1 address 2 Sep 10 15:48:25 clu kernel: usbserial.c: Generic converter now disconnected from ttyUSB0 Sep 10 15:48:25 clu kernel: usbserial.c: Generic converter now disconnected from ttyUSB1 Sep 10 15:48:25 clu kernel: usbserial.c: Generic converter now disconnected from ttyUSB2 Sep 10 15:48:25 clu kernel: usb.c: USB bus 1 deregistered This of course prevents usb-ohci from reattaching to the card when it's inserted next time. After applying the attached patch, I saw this upon "cardctl insert 0": Sep 10 15:55:29 clu kernel: usb-ohci.c: USB OHCI at membase 0xe046d000, IRQ 9 Sep 10 15:55:29 clu kernel: usb-ohci.c: usb-02:00.0, PCI device 1045:c861 Sep 10 15:55:29 clu kernel: usb.c: new USB bus registered, assigned bus number 1 Sep 10 15:55:29 clu kernel: hub.c: USB hub found Sep 10 15:55:29 clu kernel: hub.c: 2 ports detected Sep 10 15:55:30 clu kernel: hub.c: new USB device 02:00.0-1, assigned address 2 Sep 10 15:55:30 clu kernel: td_alloc- xc0005000 Sep 10 15:55:30 clu kernel: td_alloc+0 c0005040 Sep 10 15:55:30 clu kernel: td_alloc+1 c0005080 Sep 10 15:55:30 clu kernel: td_free+0 xc0005000 Sep 10 15:55:30 clu kernel: td_free+1 xc0005040 Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000 Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040 Sep 10 15:55:30 clu kernel: td_alloc+2 c00050c0 Sep 10 15:55:30 clu kernel: td_free+0 xc0005080 Sep 10 15:55:30 clu kernel: td_free+1 xc0005000 Sep 10 15:55:30 clu kernel: td_free+2 xc0005040 Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000 Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040 Sep 10 15:55:30 clu kernel: td_alloc+2 c0005080 Sep 10 15:55:30 clu kernel: td_free+0 xc00050c0 Sep 10 15:55:30 clu kernel: td_free+1 xc0005000 Sep 10 15:55:30 clu kernel: td_free+2 xc0005040 Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000 Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040 Sep 10 15:55:30 clu kernel: td_alloc+2 c00050c0 Sep 10 15:55:30 clu kernel: td_free+0 xc0005080 Sep 10 15:55:30 clu kernel: td_free+1 xc0005000 Sep 10 15:55:30 clu kernel: td_free+2 xc0005040 Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000 Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040 Sep 10 15:55:30 clu kernel: td_alloc+2 c0005080 Sep 10 15:55:30 clu kernel: td_free+0 xc00050c0 Sep 10 15:55:30 clu kernel: td_free+1 xc0005000 Sep 10 15:55:30 clu kernel: td_free+2 xc0005040 Sep 10 15:55:30 clu kernel: td_alloc+0 c0005000 Sep 10 15:55:30 clu kernel: td_alloc+1 c0005040 Sep 10 15:55:30 clu kernel: td_free+0 xc0005080 Sep 10 15:55:30 clu kernel: td_free+1 xc0005000 Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter detected Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter now attached to ttyUSB0 (or usb/tts/0 for devfs) Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter detected Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter now attached to ttyUSB1 (or usb/tts/1 for devfs) Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter detected Sep 10 15:55:30 clu kernel: usbserial.c: Generic converter now attached to ttyUSB2 (or usb/tts/2 for devfs) [The messages after ejecting are unchanged.] ... which tells me that something forgets to free that "td" someplace. I didn't instrument for ohci_dev yet; that's probably next. Help is appreciated. (As usual in these cases, the customer is on a deadline.) -- Matthias Urlichs | {M:U} IT Design @ m-u-it.de | [EMAIL PROTECTED]
--- /daten/src/kernel/remote/2.4/drivers/usb/host/usb-ohci.c 2004-07-22 15:19:12 +0200 +++ usb-ohci.c 2004-09-10 16:01:52 +0200 @@ -219,6 +219,7 @@ for (i = 0; i <= last; i++) { td = urb_priv->td [i]; +printk(KERN_DEBUG "td_free+%d x%p\n",i,td); if (td) td_free (hc, td); } @@ -685,6 +686,7 @@ /* allocate the TDs (updating hash chains) */ for (i = 0; i < size; i++) { urb_priv->td[i] = td_alloc (ohci, SLAB_ATOMIC); +printk(KERN_DEBUG "td_alloc+%d %p\n",i,urb_priv->td[i]); if (!urb_priv->td[i]) { urb_priv->length = i; urb_free_priv (ohci, urb_priv); @@ -1272,9 +1274,11 @@ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); /* skip ed */ /* dummy td; end of td list for ed */ td = td_alloc (ohci, SLAB_ATOMIC); +printk(KERN_DEBUG "td_alloc- x%p\n",td); /* hash the ed for later reverse mapping */ if (!td || !hash_add_ed (ohci, (ed_t *)ed)) { /* out of memory */ +printk(KERN_DEBUG "td_OOM x%p\n",td); if (td) td_free(ohci, td); return NULL; @@ -1659,6 +1663,7 @@ if (ed->state & ED_DEL) { /* set by sohci_free_dev */ struct ohci_device * dev = usb_to_ohci (ohci->dev[edINFO & 0x7F]); +printk(KERN_DEBUG "td_free- %p\n", tdTailP); td_free (ohci, tdTailP); /* free dummy td */ ed->hwINFO = cpu_to_le32 (OHCI_ED_SKIP); ed->state = ED_NEW;