From b0229f368598c9c143856e26154578c62961c822 Mon Sep 17 00:00:00 2001 From: Brent Casavant Date: Tue, 6 Jan 2009 14:41:06 -0800 Subject: [PATCH] --- yaml --- r: 126287 b: refs/heads/master c: 08adefd4791772d8b3fe23cc9d2554123e21dfa3 h: refs/heads/master i: 126285: bbf8ff6334270a1eaac5c94cd03f23d4f5ccb0c4 126283: 930675862d818ba01b39cfcaf4c00c542008b648 126279: 6c2af69fabe5f121ad72111725ccd14a7171e6dd 126271: 74919892bf003cec2156e45103102c9e54ff68e5 v: v3 --- [refs] | 2 +- trunk/drivers/misc/ioc4.c | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 737ea25a0992..ab347af8a8f5 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: bfa0b1c3ca802bd9813987e861d932ddc1c8cf50 +refs/heads/master: 08adefd4791772d8b3fe23cc9d2554123e21dfa3 diff --git a/trunk/drivers/misc/ioc4.c b/trunk/drivers/misc/ioc4.c index 6f76573e7c8a..60b0b1a4fb3a 100644 --- a/trunk/drivers/misc/ioc4.c +++ b/trunk/drivers/misc/ioc4.c @@ -269,6 +269,16 @@ ioc4_variant(struct ioc4_driver_data *idd) return IOC4_VARIANT_PCI_RT; } +static void +ioc4_load_modules(struct work_struct *work) +{ + /* arg just has to be freed */ + + request_module("sgiioc4"); + + kfree(work); +} + /* Adds a new instance of an IOC4 card */ static int ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) @@ -378,6 +388,30 @@ ioc4_probe(struct pci_dev *pdev, const struct pci_device_id *pci_id) } mutex_unlock(&ioc4_mutex); + /* Request sgiioc4 IDE driver on boards that bring that functionality + * off of IOC4. The root filesystem may be hosted on a drive connected + * to IOC4, so we need to make sure the sgiioc4 driver is loaded as it + * won't be picked up by modprobes due to the ioc4 module owning the + * PCI device. + */ + if (idd->idd_variant != IOC4_VARIANT_PCI_RT) { + struct work_struct *work; + work = kzalloc(sizeof(struct work_struct), GFP_KERNEL); + if (!work) { + printk(KERN_WARNING + "%s: IOC4 unable to allocate memory for " + "load of sub-modules.\n", __func__); + } else { + /* Request the module from a work procedure as the + * modprobe goes out to a userland helper and that + * will hang if done directly from ioc4_probe(). + */ + printk(KERN_INFO "IOC4 loading sgiioc4 submodule\n"); + INIT_WORK(work, ioc4_load_modules); + schedule_work(work); + } + } + return 0; out_misc_region: @@ -462,6 +496,8 @@ ioc4_init(void) static void __devexit ioc4_exit(void) { + /* Ensure ioc4_load_modules() has completed before exiting */ + flush_scheduled_work(); pci_unregister_driver(&ioc4_driver); }