on 24/09/2009 17:51 Hans Petter Selasky said the following: > > Your patch looks good. Send me the final version when it is ready and testers > report OK. I will then review and commit it. > > I think that if you need to reload the control head, you will also need to > reload the other head list pointers? Could you check that? I am just thinking that maybe there is a more clever / proper approach to fixing this. I did some additional debugging, maybe you'd find this interesting. First debugging setup: diff --git a/sys/dev/usb/controller/ohci.c b/sys/dev/usb/controller/ohci.c index fb6ba34..83cb4bb 100644 --- a/sys/dev/usb/controller/ohci.c +++ b/sys/dev/usb/controller/ohci.c _at__at_ -80,6 +80,8 _at__at_ __FBSDID("$FreeBSD$"); #ifdef USB_DEBUG static int ohcidebug = 0; +extern devclass_t ohci_devclass; /* XXX */ + SYSCTL_NODE(_hw_usb, OID_AUTO, ohci, CTLFLAG_RW, 0, "USB ohci"); SYSCTL_INT(_hw_usb_ohci, OID_AUTO, debug, CTLFLAG_RW, &ohcidebug, 0, "ohci debug level"); _at__at_ -227,9 +229,9 _at__at_ reset: return (USB_ERR_IOERROR); } #ifdef USB_DEBUG - if (ohcidebug > 15) { +// if (ohcidebug > 15) { ohci_dumpregs(sc); - } +// } #endif /* The controller is now in SUSPEND state, we have 2ms to finish. */ _at__at_ -286,8 +289,15 _at__at_ reset: } #ifdef USB_DEBUG - if (ohcidebug > 5) { +// if (ohcidebug > 5) { ohci_dumpregs(sc); +// } + int unit = device_get_unit(sc->sc_dev); + if (unit != 0) { + DPRINTFN(0, "dump of ohci0 regs:\n"); + sc = devclass_get_softc(ohci_devclass, 0); + if (sc != NULL) + ohci_dumpregs(sc); } #endif return (USB_ERR_NORMAL_COMPLETION); diff --git a/sys/dev/usb/controller/ohci_pci.c b/sys/dev/usb/controller/ohci_pci.c index 3be6e42..755a90b 100644 --- a/sys/dev/usb/controller/ohci_pci.c +++ b/sys/dev/usb/controller/ohci_pci.c _at__at_ -400,7 +400,7 _at__at_ static driver_t ohci_driver = .size = sizeof(struct ohci_softc), }; -static devclass_t ohci_devclass; +devclass_t ohci_devclass; /* XXX */ DRIVER_MODULE(ohci, pci, ohci_driver, ohci_devclass, 0, 0); MODULE_DEPEND(ohci, usb, 1, 1, 1); The idea is to always dump all HW regs just after reset, after HW programming and additionally dump HW regs of ohci0 after each of the subsequent controllers gets programmed. So, now the results: ohci0: <OHCI (generic) USB controller> mem 0xfe02e000-0xfe02efff irq 16 at device 18.0 on pci0 ohci0: [ITHREAD] ohci_dumpregs:540: ohci_dumpregs: rev=0x00000110 control=0x000000c0 command=0x00000000 ohci_dumpregs:544: intrstat=0x00000040 intre=0x00000000 intrd=0x00000000 ohci_dumpregs:548: hcca=0x00000000 percur=0x00000000 ctrlhd=0x00000000 ohci_dumpregs:552: ctrlcur=0x00000000 bulkhd=0x00000000 bulkcur=0x00000000 ohci_dumpregs:556: done=0x00000000 fmival=0x00002edf fmrem=0x00000000 ohci_dumpregs:560: fmnum=0x00000000 perst=0x00000000 lsthrs=0x00000628 ohci_dumpregs:564: desca=0x02000b03 descb=0x00000000 stat=0x00000000 ohci_dumpregs:567: port1=0x00010301 port2=0x00000100 ohci_dumpregs:573: HCCA: frame_number=0x0000 done_head=0x00000000 ohci_dumpregs:540: ohci_dumpregs: rev=0x00000110 control=0x000000af command=0x00000000 ohci_dumpregs:544: intrstat=0x00000044 intre=0x8000005a intrd=0x8000005a ohci_dumpregs:548: hcca=0x0304b000 percur=0x00000000 ctrlhd=0x03082000 ohci_dumpregs:552: ctrlcur=0x00000000 bulkhd=0x03083000 bulkcur=0x00000000 ohci_dumpregs:556: done=0x00000000 fmival=0xa7782edf fmrem=0x800013dd ohci_dumpregs:560: fmnum=0x0000000d perst=0x00002a2f lsthrs=0x00000628 ohci_dumpregs:564: desca=0x02000b03 descb=0x00000000 stat=0x00000000 ohci_dumpregs:567: port1=0x00010301 port2=0x00000100 ohci_dumpregs:573: HCCA: frame_number=0x000e done_head=0x00000000 usbus0: <OHCI (generic) USB controller> on ohci0 ohci1: <OHCI (generic) USB controller> mem 0xfe02d000-0xfe02dfff irq 16 at device 18.1 on pci0 ohci1: [ITHREAD] ohci_dumpregs:540: ohci_dumpregs: rev=0x00000110 control=0x000000c0 command=0x00000000 ohci_dumpregs:544: intrstat=0x00000000 intre=0x00000000 intrd=0x00000000 ohci_dumpregs:548: hcca=0x00000000 percur=0x00000000 ctrlhd=0x00000000 ohci_dumpregs:552: ctrlcur=0x00000000 bulkhd=0x00000000 bulkcur=0x00000000 ohci_dumpregs:556: done=0x00000000 fmival=0x00002edf fmrem=0x00000000 ohci_dumpregs:560: fmnum=0x00000000 perst=0x00000000 lsthrs=0x00000628 ohci_dumpregs:564: desca=0x02000b03 descb=0x00000000 stat=0x00000000 ohci_dumpregs:567: port1=0x00000100 port2=0x00000100 ohci_dumpregs:573: HCCA: frame_number=0x0000 done_head=0x00000000 ohci_dumpregs:540: ohci_dumpregs: rev=0x00000110 control=0x000000af command=0x00000000 ohci_dumpregs:544: intrstat=0x00000004 intre=0x8000005a intrd=0x8000005a ohci_dumpregs:548: hcca=0x030a8000 percur=0x00000000 ctrlhd=0x030a9000 ohci_dumpregs:552: ctrlcur=0x00000000 bulkhd=0x030b1000 bulkcur=0x00000000 ohci_dumpregs:556: done=0x00000000 fmival=0xa7782edf fmrem=0x800013d5 ohci_dumpregs:560: fmnum=0x0000000d perst=0x00002a2f lsthrs=0x00000628 ohci_dumpregs:564: desca=0x02000b03 descb=0x00000000 stat=0x00000000 ohci_dumpregs:567: port1=0x00000100 port2=0x00000100 ohci_dumpregs:573: HCCA: frame_number=0x000e done_head=0x00000000 ohci_controller_init:297: dump of ohci0 regs: ohci_dumpregs:540: ohci_dumpregs: rev=0x00000110 control=0x000000af command=0x00000000 ohci_dumpregs:544: intrstat=0x00000004 intre=0x8000005a intrd=0x8000005a ohci_dumpregs:548: hcca=0x0304b000 percur=0x00000000 ctrlhd=0xbfdf1c50 ohci_dumpregs:552: ctrlcur=0x00000000 bulkhd=0x03083000 bulkcur=0x00000000 ohci_dumpregs:556: done=0xbfdf1ca0 fmival=0xa7782edf fmrem=0x80002e51 ohci_dumpregs:560: fmnum=0x0000019f perst=0x00002a2f lsthrs=0x00000628 ohci_dumpregs:564: desca=0x02000b03 descb=0x00000000 stat=0x00000000 ohci_dumpregs:567: port1=0x00000303 port2=0x00000100 ohci_dumpregs:573: HCCA: frame_number=0x019f done_head=0x00000000 So, as expected, reset does clear the registers, programming does set them correctly. But as soon as we are done programming ohci1, ctrlhd of ohci0 gets re-programmed to 0xbfdf1c50. BTW, to answer your question, other lists seem to be unaffected, head/cur values seem to be preserved intact. hcca register is also OK. Not sure how to interpret this. Either a timing issue, i.e. the register gets over-written some time after we program it. Or perhaps a bug in SMM code, i.e. when we generate an SMI (e.g. while doing ohci1 takeover) SMM code erroneously writes something to ohci0 ctrlhead. Or something else... :) -- Andriy GaponReceived on Fri Sep 25 2009 - 04:34:27 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:56 UTC