On Thu, 5 Aug 2004 15:03:58 -0700 "Aleksey Gorelov" <[EMAIL PROTECTED]> wrote:
> I wonder how this problem might be addressed in general case: when > some device is sharing IRQ with UHCI, and is initialized (with > request_irq, etc...) before actual UHCI driver starts? I have a patch which prevents SMM BIOS from doing this to us by requesting unconditional handoff (it comes from Vojtech @SuSE, modified by John Stulz from IBM for 2.4). However, if you have a "normal" BIOS doing this, I'm a little lost as to what to do. It can still honor the handoff, if you're lucky. -- Pete diff -ruN linux-rhel/Documentation/kernel-parameters.txt linux-rhel-fix/Documentation/kernel-parameters.txt --- linux-rhel/Documentation/kernel-parameters.txt 2004-07-20 15:19:47.000000000 -0700 +++ linux-rhel-fix/Documentation/kernel-parameters.txt 2004-07-20 15:26:06.000000000 -0700 @@ -616,7 +616,9 @@ uart6850= [HW,SOUND] usbfix [BUGS=IA-64] - + + no-usb-legacy [HW] Disables BIOS SMM USB Legacy Support + video= [FB] frame buffer configuration. vga= [BOOT] on ix386, select a particular video mode diff -ruN linux-rhel/drivers/pci/quirks.c linux-rhel-fix/drivers/pci/quirks.c --- linux-rhel/drivers/pci/quirks.c 2004-07-20 15:20:06.000000000 -0700 +++ linux-rhel-fix/drivers/pci/quirks.c 2004-07-20 16:32:26.000000000 -0700 @@ -701,6 +701,76 @@ request_region(0x170, 8, "libata"); /* port 1 */ } + +#define UHCI_USBLEGSUP 0xc0 /* legacy support */ +#define UHCI_USBCMD 0 /* command register */ +#define UHCI_USBINTR 4 /* interrupt register */ +#define UHCI_USBLEGSUP_DEFAULT 0x2000 /* only PIRQ enable set */ +#define UHCI_USBCMD_GRESET 0x0004 /* Global reset */ + +#define OHCI_CONTROL 0x04 +#define OHCI_CMDSTATUS 0x08 +#define OHCI_INTRENABLE 0x10 +#define OHCI_OCR (1 << 3) /* ownership change request */ +#define OHCI_CTRL_IR (1 << 8) /* interrupt routing */ +#define OHCI_INTR_OC (1 << 30) /* ownership change */ + +int disable_legacy_usb __initdata = 0; +static int __init usb_legacy_disable(char *str) +{ + disable_legacy_usb = 1; + return 0; +} +__setup("no-usb-legacy", usb_legacy_disable); + +static void __init quirk_usb_disable_smm_bios(struct pci_dev *pdev) +{ + if (!disable_legacy_usb) + return; + + if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x00)) { /* UHCI */ + int i; + unsigned long base = 0; + + for (i = 0; i < PCI_ROM_RESOURCE; i++) + if ((pci_resource_flags(pdev, i) & IORESOURCE_IO)) { + base = pci_resource_start(pdev, i); + break; + } + + if (!base) + return; + + outw(0, base + UHCI_USBINTR); + outw(UHCI_USBCMD_GRESET, base + UHCI_USBCMD); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ*50+999) / 1000); + outw(0, base + UHCI_USBCMD); + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout((HZ*10+999) / 1000); + + pci_write_config_word(pdev, UHCI_USBLEGSUP, UHCI_USBLEGSUP_DEFAULT); + } + + if (pdev->class == ((PCI_CLASS_SERIAL_USB << 8) | 0x10)) { /* OHCI */ + char *base = ioremap_nocache(pci_resource_start(pdev, 0), + pci_resource_len(pdev, 0)); + if (base == NULL) return; + + if (readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { + int temp = 500; /* arbitrary: five seconds */ + writel(OHCI_INTR_OC, base + OHCI_INTRENABLE); + writel(OHCI_OCR, base + OHCI_CMDSTATUS); + while (temp && readl(base + OHCI_CONTROL) & OHCI_CTRL_IR) { + temp--; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout( HZ / 100); + } + } + iounmap(base); + } +} + /* * The main table of quirks. */ @@ -780,6 +850,7 @@ #endif { PCI_FIXUP_FINAL, PCI_VENDOR_ID_INTEL, PCI_ANY_ID, quirk_intel_ide_combined }, + { PCI_FIXUP_FINAL, PCI_ANY_ID, PCI_ANY_ID, quirk_usb_disable_smm_bios }, { 0 } }; diff -ruN linux-rhel/include/asm-i386/smpboot.h linux-rhel-fix/include/asm-i386/smpboot.h --- linux-rhel/include/asm-i386/smpboot.h 2004-07-20 15:20:14.000000000 -0700 +++ linux-rhel-fix/include/asm-i386/smpboot.h 2004-07-20 15:29:20.000000000 -0700 @@ -15,6 +15,7 @@ extern unsigned char int_delivery_mode; extern unsigned int int_dest_addr_mode; extern int cyclone_setup(char*); +extern int disable_legacy_usb; static inline void detect_clustered_apic(char* oem, char* prod) { @@ -32,6 +33,7 @@ esr_disable = 1; /*Start cyclone clock*/ cyclone_setup(0); + disable_legacy_usb = 1; } else if (!strncmp(oem, "IBM ENSW", 8) && !strncmp(prod, "RUTHLESS SMP", 9)){ clustered_apic_mode = CLUSTERED_APIC_XAPIC; @@ -41,6 +43,7 @@ esr_disable = 1; /*Start cyclone clock*/ cyclone_setup(0); + disable_legacy_usb = 1; } else if (!strncmp(oem, "IBM NUMA", 8)){ clustered_apic_mode = CLUSTERED_APIC_NUMAQ; ------------------------------------------------------- This SF.Net email is sponsored by OSTG. Have you noticed the changes on Linux.com, ITManagersJournal and NewsForge in the past few weeks? Now, one more big change to announce. We are now OSTG- Open Source Technology Group. Come see the changes on the new OSTG site. www.ostg.com _______________________________________________ [EMAIL PROTECTED] To unsubscribe, use the last form field at: https://lists.sourceforge.net/lists/listinfo/linux-usb-devel