From 988cbb15e00e6f924d052874b40c6a5447f9fdd7 Mon Sep 17 00:00:00 2001 From: Mitch Williams Date: Fri, 30 Mar 2007 11:54:08 -0700 Subject: PCI: Flush MSI-X table writes This patch fixes a kernel bug which is triggered when using the irqbalance daemon with MSI-X hardware. Because both MSI-X interrupt messages and MSI-X table writes are posted, it's possible for them to cross while in-flight. This results in interrupts being received long after the kernel thinks they're disabled, and in interrupts being sent to stale vectors after rebalancing. This patch performs a read flush after writes to the MSI-X table for mask and unmask operations. Since the SMP affinity is set while the interrupt is masked, and since it's unmasked immediately after, no additional flushes are required in the various affinity setting routines. This patch has been validated with (unreleased) network hardware which uses MSI-X. Revised with input from Eric Biederman. Signed-off-by: Mitch Williams Acked-by: "Eric W. Biederman" Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 435c195..a4ef93e 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -68,6 +68,29 @@ static void msix_set_enable(struct pci_dev *dev, int enable) } } +static void msix_flush_writes(unsigned int irq) +{ + struct msi_desc *entry; + + entry = get_irq_msi(irq); + BUG_ON(!entry || !entry->dev); + switch (entry->msi_attrib.type) { + case PCI_CAP_ID_MSI: + /* nothing to do */ + break; + case PCI_CAP_ID_MSIX: + { + int offset = entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET; + readl(entry->mask_base + offset); + break; + } + default: + BUG(); + break; + } +} + static void msi_set_mask_bit(unsigned int irq, int flag) { struct msi_desc *entry; @@ -187,11 +210,13 @@ void write_msi_msg(unsigned int irq, struct msi_msg *msg) void mask_msi_irq(unsigned int irq) { msi_set_mask_bit(irq, 1); + msix_flush_writes(irq); } void unmask_msi_irq(unsigned int irq) { msi_set_mask_bit(irq, 0); + msix_flush_writes(irq); } static int msi_free_irq(struct pci_dev* dev, int irq); -- cgit v0.10.2 From f7bdd12d234d9064bd0aa1b5610508959120a9b4 Mon Sep 17 00:00:00 2001 From: Brian King Date: Fri, 6 Apr 2007 16:39:36 -0500 Subject: pci: New PCI-E reset API Adds a new API which can be used to issue various types of PCI-E reset, including PCI-E warm reset and PCI-E hot reset. This is needed for an ipr PCI-E adapter which does not properly implement BIST. Running BIST on this adapter results in PCI-E errors. The only reliable reset mechanism that exists on this hardware is PCI Fundamental reset (warm reset). Since driving this type of reset is architecture unique, this provides the necessary hooks for architectures to add this support. Signed-off-by: Brian King Acked-by: Linas Vepstas Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2a45827..2086cd1 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -892,6 +892,34 @@ pci_disable_device(struct pci_dev *dev) } /** + * pcibios_set_pcie_reset_state - set reset state for device dev + * @dev: the PCI-E device reset + * @state: Reset state to enter into + * + * + * Sets the PCI-E reset state for the device. This is the default + * implementation. Architecture implementations can override this. + */ +int __attribute__ ((weak)) pcibios_set_pcie_reset_state(struct pci_dev *dev, + enum pcie_reset_state state) +{ + return -EINVAL; +} + +/** + * pci_set_pcie_reset_state - set reset state for device dev + * @dev: the PCI-E device reset + * @state: Reset state to enter into + * + * + * Sets the PCI reset state for the device. + */ +int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state) +{ + return pcibios_set_pcie_reset_state(dev, state); +} + +/** * pci_enable_wake - enable PCI device as wakeup event source * @dev: PCI device affected * @state: PCI state from which device will issue wakeup events @@ -1427,4 +1455,5 @@ EXPORT_SYMBOL(pci_set_power_state); EXPORT_SYMBOL(pci_save_state); EXPORT_SYMBOL(pci_restore_state); EXPORT_SYMBOL(pci_enable_wake); +EXPORT_SYMBOL_GPL(pci_set_pcie_reset_state); diff --git a/include/linux/pci.h b/include/linux/pci.h index 9724910..3aba02a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -96,6 +96,19 @@ enum pci_channel_state { pci_channel_io_perm_failure = (__force pci_channel_state_t) 3, }; +typedef unsigned int __bitwise pcie_reset_state_t; + +enum pcie_reset_state { + /* Reset is NOT asserted (Use to deassert reset) */ + pcie_deassert_reset = (__force pcie_reset_state_t) 1, + + /* Use #PERST to reset PCI-E device */ + pcie_warm_reset = (__force pcie_reset_state_t) 2, + + /* Use PCI-E Hot Reset to reset device */ + pcie_hot_reset = (__force pcie_reset_state_t) 3 +}; + typedef unsigned short __bitwise pci_bus_flags_t; enum pci_bus_flags { PCI_BUS_FLAGS_NO_MSI = (__force pci_bus_flags_t) 1, @@ -532,6 +545,7 @@ static inline int pci_is_managed(struct pci_dev *pdev) void pci_disable_device(struct pci_dev *dev); void pci_set_master(struct pci_dev *dev); +int pci_set_pcie_reset_state(struct pci_dev *dev, enum pcie_reset_state state); #define HAVE_PCI_SET_MWI int __must_check pci_set_mwi(struct pci_dev *dev); void pci_clear_mwi(struct pci_dev *dev); -- cgit v0.10.2 From 5d386e1ac4025b4bcc6bad6811e771cb76064dfe Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Tue, 6 Mar 2007 15:02:26 -0800 Subject: pciehp: Event handling rework The event handler of PCIEHP driver is unnecessarily very complex. In addition, current event handler can only a fixed number of events at the same time, and some of events would be lost if several number of events happened at the same time. This patch simplify the event handler using 'work queue', and it also fix the above-mentioned issue. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index d19fcae..c98e271 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -43,6 +43,7 @@ extern int pciehp_poll_mode; extern int pciehp_poll_time; extern int pciehp_debug; extern int pciehp_force; +extern struct workqueue_struct *pciehp_wq; #define dbg(format, arg...) \ do { \ @@ -70,14 +71,16 @@ struct slot { struct list_head slot_list; char name[SLOT_NAME_SIZE]; unsigned long last_emi_toggle; + struct delayed_work work; /* work for button event */ + struct mutex lock; }; struct event_info { u32 event_type; - u8 hp_slot; + struct slot *p_slot; + struct work_struct work; }; -#define MAX_EVENTS 10 struct controller { struct controller *next; struct mutex crit_sect; /* critical section mutex */ @@ -86,11 +89,9 @@ struct controller { int slot_num_inc; /* 1 or -1 */ struct pci_dev *pci_dev; struct list_head slot_list; - struct event_info event_queue[MAX_EVENTS]; struct slot *slot; struct hpc_ops *hpc_ops; wait_queue_head_t queue; /* sleep & wake process */ - u8 next_event; u8 bus; u8 device; u8 function; @@ -149,16 +150,15 @@ struct controller { #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) #define EMI(cap) (cap & EMI_PRSN) -extern int pciehp_event_start_thread(void); -extern void pciehp_event_stop_thread(void); -extern int pciehp_enable_slot(struct slot *slot); -extern int pciehp_disable_slot(struct slot *slot); +extern int pciehp_sysfs_enable_slot(struct slot *slot); +extern int pciehp_sysfs_disable_slot(struct slot *slot); extern u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); extern int pciehp_configure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot); +extern void queue_pushbutton_work(struct work_struct *work); int pcie_init(struct controller *ctrl, struct pcie_device *dev); /* Global variables */ diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index a92eda6..749227e 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -41,6 +41,7 @@ int pciehp_debug; int pciehp_poll_mode; int pciehp_poll_time; int pciehp_force; +struct workqueue_struct *pciehp_wq; struct controller *pciehp_ctrl_list; #define DRIVER_VERSION "0.4" @@ -62,7 +63,6 @@ MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing" #define PCIE_MODULE_NAME "pciehp" -static int pcie_start_thread (void); static int set_attention_status (struct hotplug_slot *slot, u8 value); static int enable_slot (struct hotplug_slot *slot); static int disable_slot (struct hotplug_slot *slot); @@ -229,6 +229,8 @@ static int init_slots(struct controller *ctrl) slot->device = ctrl->slot_device_offset + i; slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot; + mutex_init(&slot->lock); + INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; @@ -286,6 +288,9 @@ static void cleanup_slots(struct controller *ctrl) if (EMI(ctrl->ctrlcap)) sysfs_remove_file(&slot->hotplug_slot->kobj, &hotplug_slot_attr_lock.attr); + cancel_delayed_work(&slot->work); + flush_scheduled_work(); + flush_workqueue(pciehp_wq); pci_hp_deregister(slot->hotplug_slot); } } @@ -314,7 +319,7 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - return pciehp_enable_slot(slot); + return pciehp_sysfs_enable_slot(slot); } @@ -324,7 +329,7 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); - return pciehp_disable_slot(slot); + return pciehp_sysfs_disable_slot(slot); } static int get_power_status(struct hotplug_slot *hotplug_slot, u8 *value) @@ -466,9 +471,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); - /* Finish setting up the hot plug ctrl device */ - ctrl->next_event = 0; - if (!pciehp_ctrl_list) { pciehp_ctrl_list = ctrl; ctrl->next = NULL; @@ -496,22 +498,6 @@ err_out_none: return -ENODEV; } - -static int pcie_start_thread(void) -{ - int retval = 0; - - dbg("Initialize + Start the notification/polling mechanism \n"); - - retval = pciehp_event_start_thread(); - if (retval) { - dbg("pciehp_event_start_thread() failed\n"); - return retval; - } - - return retval; -} - static void __exit unload_pciehpd(void) { struct controller *ctrl; @@ -529,10 +515,6 @@ static void __exit unload_pciehpd(void) kfree(tctrl); } - - /* Stop the notification mechanism */ - pciehp_event_stop_thread(); - } static void pciehp_remove (struct pcie_device *device) @@ -585,21 +567,11 @@ static int __init pcied_init(void) pciehp_poll_mode = 1; #endif - retval = pcie_start_thread(); - if (retval) - goto error_hpc_init; - retval = pcie_port_service_register(&hpdriver_portdrv); dbg("pcie_port_service_register = %d\n", retval); info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); if (retval) dbg("%s: Failure to register service\n", __FUNCTION__); - -error_hpc_init: - if (retval) { - pciehp_event_stop_thread(); - }; - return retval; } diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 4283ef5..91441e5 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -32,92 +32,61 @@ #include #include #include +#include #include "../pci.h" #include "pciehp.h" -static void interrupt_event_handler(struct controller *ctrl); +static void interrupt_event_handler(struct work_struct *work); +static int pciehp_enable_slot(struct slot *p_slot); +static int pciehp_disable_slot(struct slot *p_slot); -static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ -static struct semaphore event_exit; /* guard ensure thread has exited before calling it quits */ -static int event_finished; -static unsigned long pushbutton_pending; /* = 0 */ -static unsigned long surprise_rm_pending; /* = 0 */ - -static inline char *slot_name(struct slot *p_slot) +static int queue_interrupt_event(struct slot *p_slot, u32 event_type) { - return p_slot->hotplug_slot->name; + struct event_info *info; + + info = kmalloc(sizeof(*info), GFP_ATOMIC); + if (!info) + return -ENOMEM; + + info->event_type = event_type; + info->p_slot = p_slot; + INIT_WORK(&info->work, interrupt_event_handler); + + schedule_work(&info->work); + + return 0; } u8 pciehp_handle_attention_button(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; - u8 rc = 0; - u8 getstatus; - struct event_info *taskInfo; + u32 event_type; /* Attention Button Change */ dbg("pciehp: Attention button interrupt received.\n"); - - /* This is the structure that tells the worker thread what to do */ - taskInfo = &(ctrl->event_queue[ctrl->next_event]); - p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - - p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); - - ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; - taskInfo->hp_slot = hp_slot; - rc++; + p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); /* * Button pressed - See if need to TAKE ACTION!!! */ - info("Button pressed on Slot(%s)\n", slot_name(p_slot)); - taskInfo->event_type = INT_BUTTON_PRESS; - - if ((p_slot->state == BLINKINGON_STATE) - || (p_slot->state == BLINKINGOFF_STATE)) { - /* Cancel if we are still blinking; this means that we press the - * attention again before the 5 sec. limit expires to cancel hot-add - * or hot-remove - */ - taskInfo->event_type = INT_BUTTON_CANCEL; - info("Button cancel on Slot(%s)\n", slot_name(p_slot)); - } else if ((p_slot->state == POWERON_STATE) - || (p_slot->state == POWEROFF_STATE)) { - /* Ignore if the slot is on power-on or power-off state; this - * means that the previous attention button action to hot-add or - * hot-remove is undergoing - */ - taskInfo->event_type = INT_BUTTON_IGNORE; - info("Button ignore on Slot(%s)\n", slot_name(p_slot)); - } + info("Button pressed on Slot(%s)\n", p_slot->name); + event_type = INT_BUTTON_PRESS; - if (rc) - up(&event_semaphore); /* signal event thread that new event is posted */ + queue_interrupt_event(p_slot, event_type); return 0; - } u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; - u8 rc = 0; u8 getstatus; - struct event_info *taskInfo; + u32 event_type; /* Switch Change */ dbg("pciehp: Switch interrupt received.\n"); - /* This is the structure that tells the worker thread - * what to do - */ - taskInfo = &(ctrl->event_queue[ctrl->next_event]); - ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; - taskInfo->hp_slot = hp_slot; - - rc++; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); @@ -125,39 +94,30 @@ u8 pciehp_handle_switch_change(u8 hp_slot, struct controller *ctrl) /* * Switch opened */ - info("Latch open on Slot(%s)\n", slot_name(p_slot)); - taskInfo->event_type = INT_SWITCH_OPEN; + info("Latch open on Slot(%s)\n", p_slot->name); + event_type = INT_SWITCH_OPEN; } else { /* * Switch closed */ - info("Latch close on Slot(%s)\n", slot_name(p_slot)); - taskInfo->event_type = INT_SWITCH_CLOSE; + info("Latch close on Slot(%s)\n", p_slot->name); + event_type = INT_SWITCH_CLOSE; } - if (rc) - up(&event_semaphore); /* signal event thread that new event is posted */ + queue_interrupt_event(p_slot, event_type); - return rc; + return 1; } u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; - u8 presence_save, rc = 0; - struct event_info *taskInfo; + u32 event_type; + u8 presence_save; /* Presence Change */ dbg("pciehp: Presence/Notify input change.\n"); - /* This is the structure that tells the worker thread - * what to do - */ - taskInfo = &(ctrl->event_queue[ctrl->next_event]); - ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; - taskInfo->hp_slot = hp_slot; - - rc++; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); /* Switch is open, assume a presence change @@ -168,59 +128,49 @@ u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl) /* * Card Present */ - info("Card present on Slot(%s)\n", slot_name(p_slot)); - taskInfo->event_type = INT_PRESENCE_ON; + info("Card present on Slot(%s)\n", p_slot->name); + event_type = INT_PRESENCE_ON; } else { /* * Not Present */ - info("Card not present on Slot(%s)\n", slot_name(p_slot)); - taskInfo->event_type = INT_PRESENCE_OFF; + info("Card not present on Slot(%s)\n", p_slot->name); + event_type = INT_PRESENCE_OFF; } - if (rc) - up(&event_semaphore); /* signal event thread that new event is posted */ + queue_interrupt_event(p_slot, event_type); - return rc; + return 1; } u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl) { struct slot *p_slot; - u8 rc = 0; - struct event_info *taskInfo; + u32 event_type; /* power fault */ dbg("pciehp: Power fault interrupt received.\n"); - /* this is the structure that tells the worker thread - * what to do - */ - taskInfo = &(ctrl->event_queue[ctrl->next_event]); - ctrl->next_event = (ctrl->next_event + 1) % MAX_EVENTS; - taskInfo->hp_slot = hp_slot; - - rc++; p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); if ( !(p_slot->hpc_ops->query_power_fault(p_slot))) { /* * power fault Cleared */ - info("Power fault cleared on Slot(%s)\n", slot_name(p_slot)); - taskInfo->event_type = INT_POWER_FAULT_CLEAR; + info("Power fault cleared on Slot(%s)\n", p_slot->name); + event_type = INT_POWER_FAULT_CLEAR; } else { /* * power fault */ - info("Power fault on Slot(%s)\n", slot_name(p_slot)); - taskInfo->event_type = INT_POWER_FAULT; + info("Power fault on Slot(%s)\n", p_slot->name); + event_type = INT_POWER_FAULT; info("power fault bit %x set\n", hp_slot); } - if (rc) - up(&event_semaphore); /* signal event thread that new event is posted */ - return rc; + queue_interrupt_event(p_slot, event_type); + + return 1; } /* The following routines constitute the bulk of the @@ -357,13 +307,10 @@ static int remove_board(struct slot *p_slot) return 0; } - -static void pushbutton_helper_thread(unsigned long data) -{ - pushbutton_pending = data; - - up(&event_semaphore); -} +struct power_work_info { + struct slot *p_slot; + struct work_struct work; +}; /** * pciehp_pushbutton_thread @@ -372,276 +319,214 @@ static void pushbutton_helper_thread(unsigned long data) * Handles all pending events and exits. * */ -static void pciehp_pushbutton_thread(unsigned long slot) +static void pciehp_power_thread(struct work_struct *work) { - struct slot *p_slot = (struct slot *) slot; - u8 getstatus; - - pushbutton_pending = 0; - - if (!p_slot) { - dbg("%s: Error! slot NULL\n", __FUNCTION__); - return; - } - - p_slot->hpc_ops->get_power_status(p_slot, &getstatus); - if (getstatus) { - p_slot->state = POWEROFF_STATE; - dbg("%s: disabling bus:device(%x:%x)\n", __FUNCTION__, - p_slot->bus, p_slot->device); - + struct power_work_info *info = + container_of(work, struct power_work_info, work); + struct slot *p_slot = info->p_slot; + + mutex_lock(&p_slot->lock); + switch (p_slot->state) { + case POWEROFF_STATE: + mutex_unlock(&p_slot->lock); + dbg("%s: disabling bus:device(%x:%x)\n", + __FUNCTION__, p_slot->bus, p_slot->device); pciehp_disable_slot(p_slot); + mutex_lock(&p_slot->lock); p_slot->state = STATIC_STATE; - } else { - p_slot->state = POWERON_STATE; - dbg("%s: adding bus:device(%x:%x)\n", __FUNCTION__, - p_slot->bus, p_slot->device); - + break; + case POWERON_STATE: + mutex_unlock(&p_slot->lock); if (pciehp_enable_slot(p_slot) && PWR_LED(p_slot->ctrl->ctrlcap)) p_slot->hpc_ops->green_led_off(p_slot); - + mutex_lock(&p_slot->lock); p_slot->state = STATIC_STATE; + break; + default: + break; } + mutex_unlock(&p_slot->lock); - return; + kfree(info); } -/** - * pciehp_surprise_rm_thread - * - * Scheduled procedure to handle blocking stuff for the surprise removal - * Handles all pending events and exits. - * - */ -static void pciehp_surprise_rm_thread(unsigned long slot) +void queue_pushbutton_work(struct work_struct *work) { - struct slot *p_slot = (struct slot *) slot; - u8 getstatus; - - surprise_rm_pending = 0; + struct slot *p_slot = container_of(work, struct slot, work.work); + struct power_work_info *info; - if (!p_slot) { - dbg("%s: Error! slot NULL\n", __FUNCTION__); + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + err("%s: Cannot allocate memory\n", __FUNCTION__); return; } + info->p_slot = p_slot; + INIT_WORK(&info->work, pciehp_power_thread); - p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); - if (!getstatus) { + mutex_lock(&p_slot->lock); + switch (p_slot->state) { + case BLINKINGOFF_STATE: p_slot->state = POWEROFF_STATE; - dbg("%s: removing bus:device(%x:%x)\n", - __FUNCTION__, p_slot->bus, p_slot->device); - - pciehp_disable_slot(p_slot); - p_slot->state = STATIC_STATE; - } else { + break; + case BLINKINGON_STATE: p_slot->state = POWERON_STATE; - dbg("%s: adding bus:device(%x:%x)\n", - __FUNCTION__, p_slot->bus, p_slot->device); - - if (pciehp_enable_slot(p_slot) && - PWR_LED(p_slot->ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_off(p_slot); - - p_slot->state = STATIC_STATE; + break; + default: + goto out; } - - return; + queue_work(pciehp_wq, &info->work); + out: + mutex_unlock(&p_slot->lock); } - - -/* this is the main worker thread */ -static int event_thread(void* data) -{ - struct controller *ctrl; - lock_kernel(); - daemonize("pciehpd_event"); - - unlock_kernel(); - - while (1) { - dbg("!!!!event_thread sleeping\n"); - down_interruptible (&event_semaphore); - dbg("event_thread woken finished = %d\n", event_finished); - if (event_finished || signal_pending(current)) - break; - /* Do stuff here */ - if (pushbutton_pending) - pciehp_pushbutton_thread(pushbutton_pending); - else if (surprise_rm_pending) - pciehp_surprise_rm_thread(surprise_rm_pending); - else - for (ctrl = pciehp_ctrl_list; ctrl; ctrl=ctrl->next) - interrupt_event_handler(ctrl); - } - dbg("event_thread signals exit\n"); - up(&event_exit); - return 0; -} - -int pciehp_event_start_thread(void) -{ - int pid; - - /* initialize our semaphores */ - init_MUTEX_LOCKED(&event_exit); - event_finished=0; - - init_MUTEX_LOCKED(&event_semaphore); - pid = kernel_thread(event_thread, NULL, 0); - - if (pid < 0) { - err ("Can't start up our event thread\n"); - return -1; - } - return 0; -} - - -void pciehp_event_stop_thread(void) -{ - event_finished = 1; - up(&event_semaphore); - down(&event_exit); -} - - static int update_slot_info(struct slot *slot) { struct hotplug_slot_info *info; - /* char buffer[SLOT_NAME_SIZE]; */ int result; - info = kmalloc(sizeof(struct hotplug_slot_info), GFP_KERNEL); + info = kmalloc(sizeof(*info), GFP_KERNEL); if (!info) return -ENOMEM; - /* make_slot_name (&buffer[0], SLOT_NAME_SIZE, slot); */ - slot->hpc_ops->get_power_status(slot, &(info->power_status)); slot->hpc_ops->get_attention_status(slot, &(info->attention_status)); slot->hpc_ops->get_latch_status(slot, &(info->latch_status)); slot->hpc_ops->get_adapter_status(slot, &(info->adapter_status)); - /* result = pci_hp_change_slot_info(buffer, info); */ result = pci_hp_change_slot_info(slot->hotplug_slot, info); kfree (info); return result; } -static void interrupt_event_handler(struct controller *ctrl) +/* + * Note: This function must be called with slot->lock held + */ +static void handle_button_press_event(struct slot *p_slot) { - int loop = 0; - int change = 1; - u8 hp_slot; + struct controller *ctrl = p_slot->ctrl; u8 getstatus; - struct slot *p_slot; - while (change) { - change = 0; - - for (loop = 0; loop < MAX_EVENTS; loop++) { - if (ctrl->event_queue[loop].event_type != 0) { - hp_slot = ctrl->event_queue[loop].hp_slot; - - p_slot = pciehp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); - - if (ctrl->event_queue[loop].event_type == INT_BUTTON_CANCEL) { - dbg("button cancel\n"); - del_timer(&p_slot->task_event); - - switch (p_slot->state) { - case BLINKINGOFF_STATE: - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_on(p_slot); - - if (ATTN_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->set_attention_status(p_slot, 0); - break; - case BLINKINGON_STATE: - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_off(p_slot); - - if (ATTN_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->set_attention_status(p_slot, 0); - break; - default: - warn("Not a valid state\n"); - return; - } - info("PCI slot #%s - action canceled due to button press.\n", slot_name(p_slot)); - p_slot->state = STATIC_STATE; - } - /* ***********Button Pressed (No action on 1st press...) */ - else if (ctrl->event_queue[loop].event_type == INT_BUTTON_PRESS) { - - if (ATTN_BUTTN(ctrl->ctrlcap)) { - dbg("Button pressed\n"); - p_slot->hpc_ops->get_power_status(p_slot, &getstatus); - if (getstatus) { - /* slot is on */ - dbg("slot is on\n"); - p_slot->state = BLINKINGOFF_STATE; - info("PCI slot #%s - powering off due to button press.\n", slot_name(p_slot)); - } else { - /* slot is off */ - dbg("slot is off\n"); - p_slot->state = BLINKINGON_STATE; - info("PCI slot #%s - powering on due to button press.\n", slot_name(p_slot)); - } - - /* blink green LED and turn off amber */ - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_blink(p_slot); - - if (ATTN_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->set_attention_status(p_slot, 0); - - init_timer(&p_slot->task_event); - p_slot->task_event.expires = jiffies + 5 * HZ; /* 5 second delay */ - p_slot->task_event.function = (void (*)(unsigned long)) pushbutton_helper_thread; - p_slot->task_event.data = (unsigned long) p_slot; - - add_timer(&p_slot->task_event); - } - } - /***********POWER FAULT********************/ - else if (ctrl->event_queue[loop].event_type == INT_POWER_FAULT) { - if (POWER_CTRL(ctrl->ctrlcap)) { - dbg("power fault\n"); - if (ATTN_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->set_attention_status(p_slot, 1); - - if (PWR_LED(ctrl->ctrlcap)) - p_slot->hpc_ops->green_led_off(p_slot); - } - } - /***********SURPRISE REMOVAL********************/ - else if ((ctrl->event_queue[loop].event_type == INT_PRESENCE_ON) || - (ctrl->event_queue[loop].event_type == INT_PRESENCE_OFF)) { - if (HP_SUPR_RM(ctrl->ctrlcap)) { - dbg("Surprise Removal\n"); - if (p_slot) { - surprise_rm_pending = (unsigned long) p_slot; - up(&event_semaphore); - update_slot_info(p_slot); - } - } - } else { - /* refresh notification */ - if (p_slot) - update_slot_info(p_slot); - } - - ctrl->event_queue[loop].event_type = 0; - - change = 1; - } - } /* End of FOR loop */ + switch (p_slot->state) { + case STATIC_STATE: + p_slot->hpc_ops->get_power_status(p_slot, &getstatus); + if (getstatus) { + p_slot->state = BLINKINGOFF_STATE; + info("PCI slot #%s - powering off due to button " + "press.\n", p_slot->name); + } else { + p_slot->state = BLINKINGON_STATE; + info("PCI slot #%s - powering on due to button " + "press.\n", p_slot->name); + } + /* blink green LED and turn off amber */ + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_blink(p_slot); + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 0); + + schedule_delayed_work(&p_slot->work, 5*HZ); + break; + case BLINKINGOFF_STATE: + case BLINKINGON_STATE: + /* + * Cancel if we are still blinking; this means that we + * press the attention again before the 5 sec. limit + * expires to cancel hot-add or hot-remove + */ + info("Button cancel on Slot(%s)\n", p_slot->name); + dbg("%s: button cancel\n", __FUNCTION__); + cancel_delayed_work(&p_slot->work); + if (p_slot->state == BLINKINGOFF_STATE) { + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_on(p_slot); + } else { + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_off(p_slot); + } + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 0); + info("PCI slot #%s - action canceled due to button press\n", + p_slot->name); + p_slot->state = STATIC_STATE; + break; + case POWEROFF_STATE: + case POWERON_STATE: + /* + * Ignore if the slot is on power-on or power-off state; + * this means that the previous attention button action + * to hot-add or hot-remove is undergoing + */ + info("Button ignore on Slot(%s)\n", p_slot->name); + update_slot_info(p_slot); + break; + default: + warn("Not a valid state\n"); + break; } } +/* + * Note: This function must be called with slot->lock held + */ +static void handle_surprise_event(struct slot *p_slot) +{ + u8 getstatus; + struct power_work_info *info; + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) { + err("%s: Cannot allocate memory\n", __FUNCTION__); + return; + } + info->p_slot = p_slot; + INIT_WORK(&info->work, pciehp_power_thread); + + p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); + if (!getstatus) + p_slot->state = POWEROFF_STATE; + else + p_slot->state = POWERON_STATE; + + queue_work(pciehp_wq, &info->work); +} + +static void interrupt_event_handler(struct work_struct *work) +{ + struct event_info *info = container_of(work, struct event_info, work); + struct slot *p_slot = info->p_slot; + struct controller *ctrl = p_slot->ctrl; + + mutex_lock(&p_slot->lock); + switch (info->event_type) { + case INT_BUTTON_PRESS: + handle_button_press_event(p_slot); + break; + case INT_POWER_FAULT: + if (!POWER_CTRL(ctrl->ctrlcap)) + break; + if (ATTN_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->set_attention_status(p_slot, 1); + if (PWR_LED(ctrl->ctrlcap)) + p_slot->hpc_ops->green_led_off(p_slot); + break; + case INT_PRESENCE_ON: + case INT_PRESENCE_OFF: + if (!HP_SUPR_RM(ctrl->ctrlcap)) + break; + dbg("Surprise Removal\n"); + update_slot_info(p_slot); + handle_surprise_event(p_slot); + break; + default: + update_slot_info(p_slot); + break; + } + mutex_unlock(&p_slot->lock); + + kfree(info); +} + int pciehp_enable_slot(struct slot *p_slot) { u8 getstatus = 0; @@ -653,7 +538,7 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (rc || !getstatus) { info("%s: no adapter on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -661,7 +546,7 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: latch open on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -671,7 +556,7 @@ int pciehp_enable_slot(struct slot *p_slot) rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (rc || getstatus) { info("%s: already enabled on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } @@ -706,7 +591,7 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_adapter_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: no adapter on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -716,7 +601,7 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus); if (ret || getstatus) { info("%s: latch open on slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -ENODEV; } @@ -726,7 +611,7 @@ int pciehp_disable_slot(struct slot *p_slot) ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus); if (ret || !getstatus) { info("%s: already disabled slot(%s)\n", __FUNCTION__, - slot_name(p_slot)); + p_slot->name); mutex_unlock(&p_slot->ctrl->crit_sect); return -EINVAL; } @@ -739,3 +624,66 @@ int pciehp_disable_slot(struct slot *p_slot) return ret; } +int pciehp_sysfs_enable_slot(struct slot *p_slot) +{ + int retval = -ENODEV; + + mutex_lock(&p_slot->lock); + switch (p_slot->state) { + case BLINKINGON_STATE: + cancel_delayed_work(&p_slot->work); + case STATIC_STATE: + p_slot->state = POWERON_STATE; + mutex_unlock(&p_slot->lock); + retval = pciehp_enable_slot(p_slot); + mutex_lock(&p_slot->lock); + p_slot->state = STATIC_STATE; + break; + case POWERON_STATE: + info("Slot %s is already in powering on state\n", + p_slot->name); + break; + case BLINKINGOFF_STATE: + case POWEROFF_STATE: + info("Already enabled on slot %s\n", p_slot->name); + break; + default: + err("Not a valid state on slot %s\n", p_slot->name); + break; + } + mutex_unlock(&p_slot->lock); + + return retval; +} + +int pciehp_sysfs_disable_slot(struct slot *p_slot) +{ + int retval = -ENODEV; + + mutex_lock(&p_slot->lock); + switch (p_slot->state) { + case BLINKINGOFF_STATE: + cancel_delayed_work(&p_slot->work); + case STATIC_STATE: + p_slot->state = POWEROFF_STATE; + mutex_unlock(&p_slot->lock); + retval = pciehp_disable_slot(p_slot); + mutex_lock(&p_slot->lock); + p_slot->state = STATIC_STATE; + break; + case POWEROFF_STATE: + info("Slot %s is already in powering off state\n", + p_slot->name); + break; + case BLINKINGON_STATE: + case POWERON_STATE: + info("Already disabled on slot %s\n", p_slot->name); + break; + default: + err("Not a valid state on slot %s\n", p_slot->name); + break; + } + mutex_unlock(&p_slot->lock); + + return retval; +} diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index fbc64aa..9aac6a8 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c @@ -71,6 +71,8 @@ #define DBG_LEAVE_ROUTINE #endif /* DEBUG */ +static atomic_t pciehp_num_controllers = ATOMIC_INIT(0); + struct ctrl_reg { u8 cap_id; u8 nxt_ptr; @@ -219,10 +221,7 @@ static inline int pciehp_writel(struct controller *ctrl, int reg, u32 value) #define EMI_STATE 0x0080 #define EMI_STATUS_BIT 7 -static spinlock_t hpc_event_lock; - DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */ -static int ctlr_seq_num = 0; /* Controller sequence # */ static irqreturn_t pcie_isr(int irq, void *dev_id); static void start_int_poll_timer(struct controller *ctrl, int sec); @@ -656,6 +655,13 @@ static void hpc_release_ctlr(struct controller *ctrl) else free_irq(ctrl->pci_dev->irq, ctrl); + /* + * If this is the last controller to be released, destroy the + * pciehp work queue + */ + if (atomic_dec_and_test(&pciehp_num_controllers)) + destroy_workqueue(pciehp_wq); + DBG_LEAVE_ROUTINE } @@ -1152,7 +1158,6 @@ int pciehp_acpi_get_hp_hw_control_from_firmware(struct pci_dev *dev) int pcie_init(struct controller * ctrl, struct pcie_device *dev) { int rc; - static int first = 1; u16 temp_word; u16 cap_reg; u16 intr_enable = 0; @@ -1221,11 +1226,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) dbg("%s: SLOTCTRL offset %x slot_ctrl %x\n", __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_ctrl); - if (first) { - spin_lock_init(&hpc_event_lock); - first = 0; - } - for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) if (pci_resource_len(pdev, rc) > 0) dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc, @@ -1286,7 +1286,8 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) rc = request_irq(ctrl->pci_dev->irq, pcie_isr, IRQF_SHARED, MY_NAME, (void *)ctrl); dbg("%s: request_irq %d for hpc%d (returns %d)\n", - __FUNCTION__, ctrl->pci_dev->irq, ctlr_seq_num, rc); + __FUNCTION__, ctrl->pci_dev->irq, + atomic_read(&pciehp_num_controllers), rc); if (rc) { err("Can't get irq %d for the hotplug controller\n", ctrl->pci_dev->irq); @@ -1296,6 +1297,18 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) dbg("pciehp ctrl b:d:f:irq=0x%x:%x:%x:%x\n", pdev->bus->number, PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq); + /* + * If this is the first controller to be initialized, + * initialize the pciehp work queue + */ + if (atomic_add_return(1, &pciehp_num_controllers) == 1) { + pciehp_wq = create_singlethread_workqueue("pciehpd"); + if (!pciehp_wq) { + rc = -ENOMEM; + goto abort_free_irq; + } + } + rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); if (rc) { err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); @@ -1349,7 +1362,6 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) goto abort_disable_intr; } - ctlr_seq_num++; ctrl->hpc_ops = &pciehp_hpc_ops; DBG_LEAVE_ROUTINE -- cgit v0.10.2 From 9233352628bc8e284f66fc90c4dc74473db1fbc1 Mon Sep 17 00:00:00 2001 From: Kenji Kaneshige Date: Tue, 6 Mar 2007 15:02:32 -0800 Subject: pciehp: Adapt to device driver model This patch adapts PCIEHP driver to PCI device driver model. Signed-off-by: Kenji Kaneshige Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index c98e271..74d0bf6 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -161,9 +161,6 @@ extern int pciehp_unconfigure_device(struct slot *p_slot); extern void queue_pushbutton_work(struct work_struct *work); int pcie_init(struct controller *ctrl, struct pcie_device *dev); -/* Global variables */ -extern struct controller *pciehp_ctrl_list; - static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) { struct slot *slot; diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 749227e..0550edf 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -42,7 +42,6 @@ int pciehp_poll_mode; int pciehp_poll_time; int pciehp_force; struct workqueue_struct *pciehp_wq; -struct controller *pciehp_ctrl_list; #define DRIVER_VERSION "0.4" #define DRIVER_AUTHOR "Dan Zink , Greg Kroah-Hartman , Dely Sy " @@ -471,14 +470,6 @@ static int pciehp_probe(struct pcie_device *dev, const struct pcie_port_service_ t_slot = pciehp_find_slot(ctrl, ctrl->slot_device_offset); - if (!pciehp_ctrl_list) { - pciehp_ctrl_list = ctrl; - ctrl->next = NULL; - } else { - ctrl->next = pciehp_ctrl_list; - pciehp_ctrl_list = ctrl; - } - t_slot->hpc_ops->get_adapter_status(t_slot, &value); /* Check if slot is occupied */ if ((POWER_CTRL(ctrl->ctrlcap)) && !value) { rc = t_slot->hpc_ops->power_off_slot(t_slot); /* Power off slot if not occupied*/ @@ -498,28 +489,14 @@ err_out_none: return -ENODEV; } -static void __exit unload_pciehpd(void) +static void pciehp_remove (struct pcie_device *dev) { - struct controller *ctrl; - struct controller *tctrl; - - ctrl = pciehp_ctrl_list; - - while (ctrl) { - cleanup_slots(ctrl); - - ctrl->hpc_ops->release_ctlr(ctrl); - - tctrl = ctrl; - ctrl = ctrl->next; - - kfree(tctrl); - } -} + struct pci_dev *pdev = dev->port; + struct controller *ctrl = pci_get_drvdata(pdev); -static void pciehp_remove (struct pcie_device *device) -{ - /* XXX - Needs to be adapted to device driver model */ + cleanup_slots(ctrl); + ctrl->hpc_ops->release_ctlr(ctrl); + kfree(ctrl); } #ifdef CONFIG_PM @@ -578,10 +555,7 @@ static int __init pcied_init(void) static void __exit pcied_cleanup(void) { dbg("unload_pciehpd()\n"); - unload_pciehpd(); - pcie_port_service_unregister(&hpdriver_portdrv); - info(DRIVER_DESC " version: " DRIVER_VERSION " unloaded\n"); } -- cgit v0.10.2 From e325e1f0783382298141c74737712637943c6063 Mon Sep 17 00:00:00 2001 From: Kristen Carlson Accardi Date: Wed, 21 Mar 2007 11:45:31 -0700 Subject: PCI: fix multiple definition of `queue_pushbutton_work' Fix duplicate names in shpchp and pciehp. Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 74d0bf6..ccc5762 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h @@ -158,7 +158,7 @@ extern u8 pciehp_handle_presence_change(u8 hp_slot, struct controller *ctrl); extern u8 pciehp_handle_power_fault(u8 hp_slot, struct controller *ctrl); extern int pciehp_configure_device(struct slot *p_slot); extern int pciehp_unconfigure_device(struct slot *p_slot); -extern void queue_pushbutton_work(struct work_struct *work); +extern void pciehp_queue_pushbutton_work(struct work_struct *work); int pcie_init(struct controller *ctrl, struct pcie_device *dev); static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index 0550edf..e5d3f0b 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c @@ -229,7 +229,7 @@ static int init_slots(struct controller *ctrl) slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot; mutex_init(&slot->lock); - INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); + INIT_DELAYED_WORK(&slot->work, pciehp_queue_pushbutton_work); /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 91441e5..7f22caa 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c @@ -351,7 +351,7 @@ static void pciehp_power_thread(struct work_struct *work) kfree(info); } -void queue_pushbutton_work(struct work_struct *work) +void pciehp_queue_pushbutton_work(struct work_struct *work) { struct slot *p_slot = container_of(work, struct slot, work.work); struct power_work_info *info; diff --git a/drivers/pci/hotplug/shpchp.h b/drivers/pci/hotplug/shpchp.h index 01d31a1..37ed088 100644 --- a/drivers/pci/hotplug/shpchp.h +++ b/drivers/pci/hotplug/shpchp.h @@ -166,7 +166,7 @@ extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl); extern int shpchp_configure_device(struct slot *p_slot); extern int shpchp_unconfigure_device(struct slot *p_slot); extern void cleanup_slots(struct controller *ctrl); -extern void queue_pushbutton_work(struct work_struct *work); +extern void shpchp_queue_pushbutton_work(struct work_struct *work); extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev); #ifdef CONFIG_ACPI diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index 5f4bc08..80dec97 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c @@ -136,7 +136,7 @@ static int init_slots(struct controller *ctrl) slot->hpc_ops = ctrl->hpc_ops; slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i); mutex_init(&slot->lock); - INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work); + INIT_DELAYED_WORK(&slot->work, shpchp_queue_pushbutton_work); /* register this slot with the hotplug pci core */ hotplug_slot->private = slot; diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c index b746bd2..2c94d44 100644 --- a/drivers/pci/hotplug/shpchp_ctrl.c +++ b/drivers/pci/hotplug/shpchp_ctrl.c @@ -433,7 +433,7 @@ static void shpchp_pushbutton_thread(struct work_struct *work) kfree(info); } -void queue_pushbutton_work(struct work_struct *work) +void shpchp_queue_pushbutton_work(struct work_struct *work) { struct slot *p_slot = container_of(work, struct slot, work.work); struct pushbutton_work_info *info; -- cgit v0.10.2 From a9dfd281a7e12f6d9b53b5a28649b3a3c76a70e6 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 6 Mar 2007 02:45:12 -0800 Subject: PCI: scatterlist.h needs types.h Most architectures' scatterlist.h use the type dma_addr_t, but omit to include which defines it. This could lead to build failures, so let's add the missing includes. Signed-off-by: Jean Delvare Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman diff --git a/include/asm-alpha/scatterlist.h b/include/asm-alpha/scatterlist.h index 6afb8bd..9173654 100644 --- a/include/asm-alpha/scatterlist.h +++ b/include/asm-alpha/scatterlist.h @@ -2,6 +2,7 @@ #define _ALPHA_SCATTERLIST_H #include +#include struct scatterlist { struct page *page; diff --git a/include/asm-avr32/scatterlist.h b/include/asm-avr32/scatterlist.h index bfe7d75..c6d5ce3 100644 --- a/include/asm-avr32/scatterlist.h +++ b/include/asm-avr32/scatterlist.h @@ -1,6 +1,8 @@ #ifndef __ASM_AVR32_SCATTERLIST_H #define __ASM_AVR32_SCATTERLIST_H +#include + struct scatterlist { struct page *page; unsigned int offset; diff --git a/include/asm-frv/scatterlist.h b/include/asm-frv/scatterlist.h index fb38fd3..8e827fa 100644 --- a/include/asm-frv/scatterlist.h +++ b/include/asm-frv/scatterlist.h @@ -1,6 +1,8 @@ #ifndef _ASM_SCATTERLIST_H #define _ASM_SCATTERLIST_H +#include + /* * Drivers must set either ->address or (preferred) ->page and ->offset * to indicate where data must be transferred to/from. diff --git a/include/asm-h8300/scatterlist.h b/include/asm-h8300/scatterlist.h index 7627f0c..985fdf5 100644 --- a/include/asm-h8300/scatterlist.h +++ b/include/asm-h8300/scatterlist.h @@ -1,6 +1,8 @@ #ifndef _H8300_SCATTERLIST_H #define _H8300_SCATTERLIST_H +#include + struct scatterlist { struct page *page; unsigned int offset; diff --git a/include/asm-i386/scatterlist.h b/include/asm-i386/scatterlist.h index 55d6c95..d7e45a8 100644 --- a/include/asm-i386/scatterlist.h +++ b/include/asm-i386/scatterlist.h @@ -1,6 +1,8 @@ #ifndef _I386_SCATTERLIST_H #define _I386_SCATTERLIST_H +#include + struct scatterlist { struct page *page; unsigned int offset; diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h index 9dbea88..a452ea2 100644 --- a/include/asm-ia64/scatterlist.h +++ b/include/asm-ia64/scatterlist.h @@ -6,6 +6,8 @@ * David Mosberger-Tang , Hewlett-Packard Co */ +#include + struct scatterlist { struct page *page; unsigned int offset; diff --git a/include/asm-m32r/scatterlist.h b/include/asm-m32r/scatterlist.h index c2de96c..352415f 100644 --- a/include/asm-m32r/scatterlist.h +++ b/include/asm-m32r/scatterlist.h @@ -1,6 +1,8 @@ #ifndef _ASM_M32R_SCATTERLIST_H #define _ASM_M32R_SCATTERLIST_H +#include + struct scatterlist { char * address; /* Location data is to be transferred to, NULL for * highmem page */ diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h index 2085d6f..4da79d3 100644 --- a/include/asm-m68knommu/scatterlist.h +++ b/include/asm-m68knommu/scatterlist.h @@ -2,6 +2,7 @@ #define _M68KNOMMU_SCATTERLIST_H #include +#include struct scatterlist { struct page *page; diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h index 2263470..7af104c 100644 --- a/include/asm-mips/scatterlist.h +++ b/include/asm-mips/scatterlist.h @@ -1,6 +1,8 @@ #ifndef __ASM_SCATTERLIST_H #define __ASM_SCATTERLIST_H +#include + struct scatterlist { struct page * page; unsigned int offset; diff --git a/include/asm-parisc/scatterlist.h b/include/asm-parisc/scatterlist.h index 236c1d0..e7211c7 100644 --- a/include/asm-parisc/scatterlist.h +++ b/include/asm-parisc/scatterlist.h @@ -2,6 +2,7 @@ #define _ASM_PARISC_SCATTERLIST_H #include +#include struct scatterlist { struct page *page; diff --git a/include/asm-sh/scatterlist.h b/include/asm-sh/scatterlist.h index d19e7cd..b9ae53c 100644 --- a/include/asm-sh/scatterlist.h +++ b/include/asm-sh/scatterlist.h @@ -1,6 +1,8 @@ #ifndef __ASM_SH_SCATTERLIST_H #define __ASM_SH_SCATTERLIST_H +#include + struct scatterlist { struct page * page; /* Location for highmem page, if any */ unsigned int offset;/* for highmem, page offset */ diff --git a/include/asm-sh64/scatterlist.h b/include/asm-sh64/scatterlist.h index 5d8fa32..1c723f2 100644 --- a/include/asm-sh64/scatterlist.h +++ b/include/asm-sh64/scatterlist.h @@ -11,6 +11,8 @@ #ifndef __ASM_SH64_SCATTERLIST_H #define __ASM_SH64_SCATTERLIST_H +#include + struct scatterlist { struct page * page; /* Location for highmem page, if any */ unsigned int offset;/* for highmem, page offset */ diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h index ec4f3c6..048fdb4 100644 --- a/include/asm-sparc64/scatterlist.h +++ b/include/asm-sparc64/scatterlist.h @@ -3,6 +3,7 @@ #define _SPARC64_SCATTERLIST_H #include +#include struct scatterlist { struct page *page; diff --git a/include/asm-v850/scatterlist.h b/include/asm-v850/scatterlist.h index af1cba6..56f4029 100644 --- a/include/asm-v850/scatterlist.h +++ b/include/asm-v850/scatterlist.h @@ -14,6 +14,8 @@ #ifndef __V850_SCATTERLIST_H__ #define __V850_SCATTERLIST_H__ +#include + struct scatterlist { struct page *page; unsigned offset; diff --git a/include/asm-x86_64/scatterlist.h b/include/asm-x86_64/scatterlist.h index 49d89f8..eaf7ada 100644 --- a/include/asm-x86_64/scatterlist.h +++ b/include/asm-x86_64/scatterlist.h @@ -1,6 +1,8 @@ #ifndef _X8664_SCATTERLIST_H #define _X8664_SCATTERLIST_H +#include + struct scatterlist { struct page *page; unsigned int offset; diff --git a/include/asm-xtensa/scatterlist.h b/include/asm-xtensa/scatterlist.h index 38a2b9a..ca337a2 100644 --- a/include/asm-xtensa/scatterlist.h +++ b/include/asm-xtensa/scatterlist.h @@ -11,6 +11,8 @@ #ifndef _XTENSA_SCATTERLIST_H #define _XTENSA_SCATTERLIST_H +#include + struct scatterlist { struct page *page; unsigned int offset; -- cgit v0.10.2 From 6473d160b4aba8023bcf38519a5989694dfd51a7 Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Tue, 6 Mar 2007 02:45:12 -0800 Subject: PCI: Cleanup the includes of I noticed that many source files include while they do not appear to need it. Here is an attempt to clean it all up. In order to find all possibly affected files, I searched for all files including but without any other occurence of "pci" or "PCI". I removed the include statement from all of these, then I compiled an allmodconfig kernel on both i386 and x86_64 and fixed the false positives manually. My tests covered 66% of the affected files, so there could be false positives remaining. Untested files are: arch/alpha/kernel/err_common.c arch/alpha/kernel/err_ev6.c arch/alpha/kernel/err_ev7.c arch/ia64/sn/kernel/huberror.c arch/ia64/sn/kernel/xpnet.c arch/m68knommu/kernel/dma.c arch/mips/lib/iomap.c arch/powerpc/platforms/pseries/ras.c arch/ppc/8260_io/enet.c arch/ppc/8260_io/fcc_enet.c arch/ppc/8xx_io/enet.c arch/ppc/syslib/ppc4xx_sgdma.c arch/sh64/mach-cayman/iomap.c arch/xtensa/kernel/xtensa_ksyms.c arch/xtensa/platform-iss/setup.c drivers/i2c/busses/i2c-at91.c drivers/i2c/busses/i2c-mpc.c drivers/media/video/saa711x.c drivers/misc/hdpuftrs/hdpu_cpustate.c drivers/misc/hdpuftrs/hdpu_nexus.c drivers/net/au1000_eth.c drivers/net/fec_8xx/fec_main.c drivers/net/fec_8xx/fec_mii.c drivers/net/fs_enet/fs_enet-main.c drivers/net/fs_enet/mac-fcc.c drivers/net/fs_enet/mac-fec.c drivers/net/fs_enet/mac-scc.c drivers/net/fs_enet/mii-bitbang.c drivers/net/fs_enet/mii-fec.c drivers/net/ibm_emac/ibm_emac_core.c drivers/net/lasi_82596.c drivers/parisc/hppb.c drivers/sbus/sbus.c drivers/video/g364fb.c drivers/video/platinumfb.c drivers/video/stifb.c drivers/video/valkyriefb.c include/asm-arm/arch-ixp4xx/dma.h sound/oss/au1550_ac97.c I would welcome test reports for these files. I am fine with removing the untested files from the patch if the general opinion is that these changes aren't safe. The tested part would still be nice to have. Note that this patch depends on another header fixup patch I submitted to LKML yesterday: [PATCH] scatterlist.h needs types.h http://lkml.org/lkml/2007/3/01/141 Signed-off-by: Jean Delvare Cc: Badari Pulavarty Signed-off-by: Greg Kroah-Hartman diff --git a/arch/alpha/kernel/err_common.c b/arch/alpha/kernel/err_common.c index 687580b..13d53b1 100644 --- a/arch/alpha/kernel/err_common.c +++ b/arch/alpha/kernel/err_common.c @@ -7,7 +7,6 @@ */ #include -#include #include #include diff --git a/arch/alpha/kernel/err_ev6.c b/arch/alpha/kernel/err_ev6.c index 69b5f4e..11aee01 100644 --- a/arch/alpha/kernel/err_ev6.c +++ b/arch/alpha/kernel/err_ev6.c @@ -7,7 +7,6 @@ */ #include -#include #include #include diff --git a/arch/alpha/kernel/err_ev7.c b/arch/alpha/kernel/err_ev7.c index 95463ab..bc799f7 100644 --- a/arch/alpha/kernel/err_ev7.c +++ b/arch/alpha/kernel/err_ev7.c @@ -7,7 +7,6 @@ */ #include -#include #include #include diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c index d59277c..b1acc8c 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-lib.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include diff --git a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c index ff0d898..e1c509a 100644 --- a/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c +++ b/arch/i386/kernel/cpu/cpufreq/speedstep-smi.c @@ -17,10 +17,10 @@ #include #include #include -#include #include #include #include +#include #include "speedstep-lib.h" diff --git a/arch/ia64/sn/kernel/huberror.c b/arch/ia64/sn/kernel/huberror.c index fcf7f93..2c3f9df 100644 --- a/arch/ia64/sn/kernel/huberror.c +++ b/arch/ia64/sn/kernel/huberror.c @@ -8,7 +8,6 @@ #include #include -#include #include #include #include "ioerror.h" diff --git a/arch/ia64/sn/kernel/xpnet.c b/arch/ia64/sn/kernel/xpnet.c index 5419acb..88fad85 100644 --- a/arch/ia64/sn/kernel/xpnet.c +++ b/arch/ia64/sn/kernel/xpnet.c @@ -24,7 +24,6 @@ #include #include -#include #include #include #include diff --git a/arch/m68knommu/kernel/dma.c b/arch/m68knommu/kernel/dma.c index 14b19c4..0a25874a 100644 --- a/arch/m68knommu/kernel/dma.c +++ b/arch/m68knommu/kernel/dma.c @@ -8,7 +8,6 @@ #include #include #include -#include #include void *dma_alloc_coherent(struct device *dev, size_t size, diff --git a/arch/mips/lib/iomap.c b/arch/mips/lib/iomap.c index d51d5cb..e3acb2d 100644 --- a/arch/mips/lib/iomap.c +++ b/arch/mips/lib/iomap.c @@ -6,7 +6,6 @@ * (C) Copyright 2007 MIPS Technologies, Inc. * written by Ralf Baechle */ -#include #include #include diff --git a/arch/powerpc/platforms/pseries/ras.c b/arch/powerpc/platforms/pseries/ras.c index 53aa041..3a393c7 100644 --- a/arch/powerpc/platforms/pseries/ras.c +++ b/arch/powerpc/platforms/pseries/ras.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/8260_io/enet.c b/arch/ppc/8260_io/enet.c index 48ce84f..4c0a7d7 100644 --- a/arch/ppc/8260_io/enet.c +++ b/arch/ppc/8260_io/enet.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/8260_io/fcc_enet.c b/arch/ppc/8260_io/fcc_enet.c index 9db825f..cab395d 100644 --- a/arch/ppc/8260_io/fcc_enet.c +++ b/arch/ppc/8260_io/fcc_enet.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/8xx_io/enet.c b/arch/ppc/8xx_io/enet.c index bfa3f52..e58288e 100644 --- a/arch/ppc/8xx_io/enet.c +++ b/arch/ppc/8xx_io/enet.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/arch/ppc/syslib/ppc4xx_sgdma.c b/arch/ppc/syslib/ppc4xx_sgdma.c index 939abe3..5dadca3e 100644 --- a/arch/ppc/syslib/ppc4xx_sgdma.c +++ b/arch/ppc/syslib/ppc4xx_sgdma.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include diff --git a/arch/sh64/mach-cayman/iomap.c b/arch/sh64/mach-cayman/iomap.c index 2d06e9a..a5c645f 100644 --- a/arch/sh64/mach-cayman/iomap.c +++ b/arch/sh64/mach-cayman/iomap.c @@ -9,7 +9,6 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. */ -#include #include #include diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 0b4cb93..cd7e6a0 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include diff --git a/arch/xtensa/platform-iss/setup.c b/arch/xtensa/platform-iss/setup.c index c8a42b6..f60c8cf 100644 --- a/arch/xtensa/platform-iss/setup.c +++ b/arch/xtensa/platform-iss/setup.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/atm/adummy.c b/drivers/atm/adummy.c index 8d60c4e..2ebd07f 100644 --- a/drivers/atm/adummy.c +++ b/drivers/atm/adummy.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/hw_random/via-rng.c b/drivers/char/hw_random/via-rng.c index 9ebf84d..ec435cb 100644 --- a/drivers/char/hw_random/via-rng.c +++ b/drivers/char/hw_random/via-rng.c @@ -26,7 +26,6 @@ #include #include -#include #include #include #include diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 157b1d0..13808f6 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -42,7 +42,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index bb9a43c..9f273f0 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -19,7 +19,6 @@ * */ #include -#include #include #include #include diff --git a/drivers/char/watchdog/sc1200wdt.c b/drivers/char/watchdog/sc1200wdt.c index 1e4a8d7..2f7ba7a 100644 --- a/drivers/char/watchdog/sc1200wdt.c +++ b/drivers/char/watchdog/sc1200wdt.c @@ -38,7 +38,6 @@ #include #include #include -#include #include #include diff --git a/drivers/char/watchdog/scx200_wdt.c b/drivers/char/watchdog/scx200_wdt.c index fc0e034..d4fd0fa 100644 --- a/drivers/char/watchdog/scx200_wdt.c +++ b/drivers/char/watchdog/scx200_wdt.c @@ -25,7 +25,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/i2c/busses/i2c-at91.c b/drivers/i2c/busses/i2c-at91.c index 67f91bd..f35156c 100644 --- a/drivers/i2c/busses/i2c-at91.c +++ b/drivers/i2c/busses/i2c-at91.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c index ee65aa1b..c6b6898 100644 --- a/drivers/i2c/busses/i2c-mpc.c +++ b/drivers/i2c/busses/i2c-mpc.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include diff --git a/drivers/i2c/busses/i2c-pca-isa.c b/drivers/i2c/busses/i2c-pca-isa.c index cc6536a..6b03e0d 100644 --- a/drivers/i2c/busses/i2c-pca-isa.c +++ b/drivers/i2c/busses/i2c-pca-isa.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include diff --git a/drivers/ieee1394/hosts.c b/drivers/ieee1394/hosts.c index 6164a9a..bd0755c 100644 --- a/drivers/ieee1394/hosts.c +++ b/drivers/ieee1394/hosts.c @@ -15,7 +15,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c index 842cd0b..eff591d 100644 --- a/drivers/infiniband/core/cm.c +++ b/drivers/infiniband/core/cm.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c index 891d1fa..223b1aa 100644 --- a/drivers/infiniband/core/iwcm.c +++ b/drivers/infiniband/core/iwcm.c @@ -39,7 +39,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/mad_priv.h b/drivers/infiniband/core/mad_priv.h index de89717..9be5cc0 100644 --- a/drivers/infiniband/core/mad_priv.h +++ b/drivers/infiniband/core/mad_priv.h @@ -39,7 +39,6 @@ #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c index 4a579b3..1e13ab4 100644 --- a/drivers/infiniband/core/multicast.c +++ b/drivers/infiniband/core/multicast.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c index 9a7eaad..6469406 100644 --- a/drivers/infiniband/core/sa_query.c +++ b/drivers/infiniband/core/sa_query.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c index 8199b83..d97ded2 100644 --- a/drivers/infiniband/core/user_mad.c +++ b/drivers/infiniband/core/user_mad.c @@ -40,7 +40,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/infiniband/hw/ipath/ipath_fs.c b/drivers/infiniband/hw/ipath/ipath_fs.c index ed55979..036ed1e 100644 --- a/drivers/infiniband/hw/ipath/ipath_fs.c +++ b/drivers/infiniband/hw/ipath/ipath_fs.c @@ -38,7 +38,6 @@ #include #include #include -#include #include "ipath_kernel.h" diff --git a/drivers/infiniband/hw/ipath/ipath_layer.c b/drivers/infiniband/hw/ipath/ipath_layer.c index e46aa4e..05a1d2b 100644 --- a/drivers/infiniband/hw/ipath/ipath_layer.c +++ b/drivers/infiniband/hw/ipath/ipath_layer.c @@ -37,7 +37,6 @@ */ #include -#include #include #include "ipath_kernel.h" diff --git a/drivers/infiniband/hw/ipath/ipath_stats.c b/drivers/infiniband/hw/ipath/ipath_stats.c index 9307f71..d8b5e4c 100644 --- a/drivers/infiniband/hw/ipath/ipath_stats.c +++ b/drivers/infiniband/hw/ipath/ipath_stats.c @@ -31,8 +31,6 @@ * SOFTWARE. */ -#include - #include "ipath_kernel.h" struct infinipath_stats ipath_stats; diff --git a/drivers/infiniband/hw/ipath/ipath_sysfs.c b/drivers/infiniband/hw/ipath/ipath_sysfs.c index ffa6318..4dc398d 100644 --- a/drivers/infiniband/hw/ipath/ipath_sysfs.c +++ b/drivers/infiniband/hw/ipath/ipath_sysfs.c @@ -32,7 +32,6 @@ */ #include -#include #include "ipath_kernel.h" #include "ipath_common.h" diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.h b/drivers/infiniband/hw/mthca/mthca_memfree.h index 5941441..a1ab068 100644 --- a/drivers/infiniband/hw/mthca/mthca_memfree.h +++ b/drivers/infiniband/hw/mthca/mthca_memfree.h @@ -38,7 +38,6 @@ #define MTHCA_MEMFREE_H #include -#include #include #define MTHCA_ICM_CHUNK_LEN \ diff --git a/drivers/infiniband/ulp/ipoib/ipoib.h b/drivers/infiniband/ulp/ipoib/ipoib.h index fd55826..d8f6bb4 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib.h +++ b/drivers/infiniband/ulp/ipoib/ipoib.h @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/isdn/hisax/netjet.c b/drivers/isdn/hisax/netjet.c index 38f648f..02c6fba 100644 --- a/drivers/isdn/hisax/netjet.c +++ b/drivers/isdn/hisax/netjet.c @@ -19,7 +19,6 @@ #include "isac.h" #include "hscx.h" #include "isdnl1.h" -#include #include #include #include diff --git a/drivers/isdn/hysdn/hysdn_proclog.c b/drivers/isdn/hysdn/hysdn_proclog.c index f7e83a8..4c7deda 100644 --- a/drivers/isdn/hysdn/hysdn_proclog.c +++ b/drivers/isdn/hysdn/hysdn_proclog.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include "hysdn_defs.h" diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c index a6cbbdd..34d7abc 100644 --- a/drivers/media/dvb/cinergyT2/cinergyT2.c +++ b/drivers/media/dvb/cinergyT2/cinergyT2.c @@ -26,11 +26,11 @@ #include #include #include -#include #include #include #include #include +#include #include "dmxdev.h" #include "dvb_demux.h" diff --git a/drivers/media/video/adv7170.c b/drivers/media/video/adv7170.c index 2aa9ce9..823cd6c 100644 --- a/drivers/media/video/adv7170.c +++ b/drivers/media/video/adv7170.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/adv7175.c b/drivers/media/video/adv7175.c index a3246a2..05c7820 100644 --- a/drivers/media/video/adv7175.c +++ b/drivers/media/video/adv7175.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/bt819.c b/drivers/media/video/bt819.c index 6867386..59a4360 100644 --- a/drivers/media/video/bt819.c +++ b/drivers/media/video/bt819.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/bt856.c b/drivers/media/video/bt856.c index 42e2299..853b1a3 100644 --- a/drivers/media/video/bt856.c +++ b/drivers/media/video/bt856.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/bt866.c b/drivers/media/video/bt866.c index 772fd52..2e4cf1e 100644 --- a/drivers/media/video/bt866.c +++ b/drivers/media/video/bt866.c @@ -37,7 +37,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/cx88/cx88-tvaudio.c b/drivers/media/video/cx88/cx88-tvaudio.c index 97ef421..e627062 100644 --- a/drivers/media/video/cx88/cx88-tvaudio.c +++ b/drivers/media/video/cx88/cx88-tvaudio.c @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/em28xx/em28xx-cards.c b/drivers/media/video/em28xx/em28xx-cards.c index ed882eb..418ea8b 100644 --- a/drivers/media/video/em28xx/em28xx-cards.c +++ b/drivers/media/video/em28xx/em28xx-cards.c @@ -23,7 +23,6 @@ #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7111.c b/drivers/media/video/saa7111.c index 44dc747..74839f9 100644 --- a/drivers/media/video/saa7111.c +++ b/drivers/media/video/saa7111.c @@ -36,7 +36,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7114.c b/drivers/media/video/saa7114.c index 2ce3321..87c3144 100644 --- a/drivers/media/video/saa7114.c +++ b/drivers/media/video/saa7114.c @@ -39,7 +39,6 @@ #include #include -#include #include #include #include diff --git a/drivers/media/video/saa711x.c b/drivers/media/video/saa711x.c index 269d711..80bf911 100644 --- a/drivers/media/video/saa711x.c +++ b/drivers/media/video/saa711x.c @@ -30,7 +30,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/media/video/saa7185.c b/drivers/media/video/saa7185.c index e0fdb1a..339592e 100644 --- a/drivers/media/video/saa7185.c +++ b/drivers/media/video/saa7185.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/misc/hdpuftrs/hdpu_cpustate.c b/drivers/misc/hdpuftrs/hdpu_cpustate.c index ca86f11..276ba3c 100644 --- a/drivers/misc/hdpuftrs/hdpu_cpustate.c +++ b/drivers/misc/hdpuftrs/hdpu_cpustate.c @@ -18,7 +18,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/misc/hdpuftrs/hdpu_nexus.c b/drivers/misc/hdpuftrs/hdpu_nexus.c index 6a51e99..60c8b26 100644 --- a/drivers/misc/hdpuftrs/hdpu_nexus.c +++ b/drivers/misc/hdpuftrs/hdpu_nexus.c @@ -18,7 +18,6 @@ #include #include #include -#include #include diff --git a/drivers/mtd/devices/doc2000.c b/drivers/mtd/devices/doc2000.c index 8a0c4de..c73e96b 100644 --- a/drivers/mtd/devices/doc2000.c +++ b/drivers/mtd/devices/doc2000.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/devices/doc2001.c b/drivers/mtd/devices/doc2001.c index 6f368ae..6413efc 100644 --- a/drivers/mtd/devices/doc2001.c +++ b/drivers/mtd/devices/doc2001.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/devices/doc2001plus.c b/drivers/mtd/devices/doc2001plus.c index 88ba82d..2b30b58 100644 --- a/drivers/mtd/devices/doc2001plus.c +++ b/drivers/mtd/devices/doc2001plus.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/devices/docecc.c b/drivers/mtd/devices/docecc.c index 52b5d63..fd8a8da 100644 --- a/drivers/mtd/devices/docecc.c +++ b/drivers/mtd/devices/docecc.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/inftlmount.c b/drivers/mtd/inftlmount.c index acf3ba2..ecac0e4 100644 --- a/drivers/mtd/inftlmount.c +++ b/drivers/mtd/inftlmount.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/nand/cs553x_nand.c b/drivers/mtd/nand/cs553x_nand.c index 8296305..89deff0 100644 --- a/drivers/mtd/nand/cs553x_nand.c +++ b/drivers/mtd/nand/cs553x_nand.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/mtd/nftlcore.c b/drivers/mtd/nftlcore.c index e6ef7d7..0c9ce19 100644 --- a/drivers/mtd/nftlcore.c +++ b/drivers/mtd/nftlcore.c @@ -17,7 +17,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atl1/atl1_param.c index c407214..bcd0bd89 100644 --- a/drivers/net/atl1/atl1_param.c +++ b/drivers/net/atl1/atl1_param.c @@ -22,7 +22,6 @@ */ #include -#include #include #include "atl1.h" diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c index d10fb80..c39ab80 100644 --- a/drivers/net/au1000_eth.c +++ b/drivers/net/au1000_eth.c @@ -45,7 +45,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fec_8xx/fec_main.c b/drivers/net/fec_8xx/fec_main.c index e824d5d..88efe97 100644 --- a/drivers/net/fec_8xx/fec_main.c +++ b/drivers/net/fec_8xx/fec_main.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c index e79700a..b3fa0d6 100644 --- a/drivers/net/fec_8xx/fec_mii.c +++ b/drivers/net/fec_8xx/fec_mii.c @@ -19,7 +19,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/fs_enet-main.c b/drivers/net/fs_enet/fs_enet-main.c index e2ddd61..a4a2a0e 100644 --- a/drivers/net/fs_enet/fs_enet-main.c +++ b/drivers/net/fs_enet/fs_enet-main.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mac-fcc.c b/drivers/net/fs_enet/mac-fcc.c index 8545e84..5603121 100644 --- a/drivers/net/fs_enet/mac-fcc.c +++ b/drivers/net/fs_enet/mac-fcc.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mac-fec.c b/drivers/net/fs_enet/mac-fec.c index cdcfb96..04b4f80 100644 --- a/drivers/net/fs_enet/mac-fec.c +++ b/drivers/net/fs_enet/mac-fec.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mac-scc.c b/drivers/net/fs_enet/mac-scc.c index 65925b5..d0f2898 100644 --- a/drivers/net/fs_enet/mac-scc.c +++ b/drivers/net/fs_enet/mac-scc.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mii-bitbang.c b/drivers/net/fs_enet/mii-bitbang.c index f914478..d384010 100644 --- a/drivers/net/fs_enet/mii-bitbang.c +++ b/drivers/net/fs_enet/mii-bitbang.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c index 235b177..0a563a8 100644 --- a/drivers/net/fs_enet/mii-fec.c +++ b/drivers/net/fs_enet/mii-fec.c @@ -21,7 +21,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ibm_emac/ibm_emac_core.c b/drivers/net/ibm_emac/ibm_emac_core.c index 3d82d46..50035eb 100644 --- a/drivers/net/ibm_emac/ibm_emac_core.c +++ b/drivers/net/ibm_emac/ibm_emac_core.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/ixgb/ixgb_osdep.h b/drivers/net/ixgb/ixgb_osdep.h index 8434d75..9e04a6b 100644 --- a/drivers/net/ixgb/ixgb_osdep.h +++ b/drivers/net/ixgb/ixgb_osdep.h @@ -34,7 +34,6 @@ #define _IXGB_OSDEP_H_ #include -#include #include #include #include diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c index 0edcd12..6b49fc4 100644 --- a/drivers/net/lasi_82596.c +++ b/drivers/net/lasi_82596.c @@ -81,7 +81,6 @@ #include #include #include -#include #include #include diff --git a/drivers/net/tokenring/madgemc.c b/drivers/net/tokenring/madgemc.c index ed274d6..f8f4d74 100644 --- a/drivers/net/tokenring/madgemc.c +++ b/drivers/net/tokenring/madgemc.c @@ -23,7 +23,6 @@ static const char version[] = "madgemc.c: v0.91 23/01/2000 by Adam Fritzler\n"; #include #include #include -#include #include #include #include diff --git a/drivers/net/tokenring/smctr.c b/drivers/net/tokenring/smctr.c index 9bbea5c..58d7e5d 100644 --- a/drivers/net/tokenring/smctr.c +++ b/drivers/net/tokenring/smctr.c @@ -41,7 +41,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/tulip/21142.c b/drivers/net/tulip/21142.c index 942b839..6c400cc 100644 --- a/drivers/net/tulip/21142.c +++ b/drivers/net/tulip/21142.c @@ -14,7 +14,6 @@ */ -#include #include #include "tulip.h" diff --git a/drivers/net/tulip/pnic.c b/drivers/net/tulip/pnic.c index 85a521e..be82a2e 100644 --- a/drivers/net/tulip/pnic.c +++ b/drivers/net/tulip/pnic.c @@ -15,7 +15,6 @@ */ #include -#include #include #include "tulip.h" diff --git a/drivers/net/tulip/pnic2.c b/drivers/net/tulip/pnic2.c index c31be0e..4e4a879 100644 --- a/drivers/net/tulip/pnic2.c +++ b/drivers/net/tulip/pnic2.c @@ -76,7 +76,6 @@ -#include #include "tulip.h" #include diff --git a/drivers/net/tulip/timer.c b/drivers/net/tulip/timer.c index df326fe..d2c1f42 100644 --- a/drivers/net/tulip/timer.c +++ b/drivers/net/tulip/timer.c @@ -14,7 +14,6 @@ */ -#include #include "tulip.h" diff --git a/drivers/net/tulip/tulip.h b/drivers/net/tulip/tulip.h index c840d2e..16f26a8 100644 --- a/drivers/net/tulip/tulip.h +++ b/drivers/net/tulip/tulip.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c index ae01555..574737b 100644 --- a/drivers/net/wan/lmc/lmc_media.c +++ b/drivers/net/wan/lmc/lmc_media.c @@ -8,7 +8,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/lmc/lmc_proto.c b/drivers/net/wan/lmc/lmc_proto.c index 74876c0..31e17995 100644 --- a/drivers/net/wan/lmc/lmc_proto.c +++ b/drivers/net/wan/lmc/lmc_proto.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c index 07dbdfb..e24a7b0 100644 --- a/drivers/net/wan/pc300_tty.c +++ b/drivers/net/wan/pc300_tty.c @@ -38,7 +38,6 @@ #include #include -#include #include #include #include diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c index 9bb4db5..a68b3b3 100644 --- a/drivers/parisc/hppb.c +++ b/drivers/parisc/hppb.c @@ -22,8 +22,6 @@ #include #include -#include - struct hppb_card { unsigned long hpa; struct resource mmio_region; diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c index ac00424..50cad3a 100644 --- a/drivers/pcmcia/cs.c +++ b/drivers/pcmcia/cs.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/pcmcia/socket_sysfs.c b/drivers/pcmcia/socket_sysfs.c index ea5765c..a2bb465 100644 --- a/drivers/pcmcia/socket_sysfs.c +++ b/drivers/pcmcia/socket_sysfs.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c index eee590a..0026433 100644 --- a/drivers/sbus/sbus.c +++ b/drivers/sbus/sbus.c @@ -6,7 +6,6 @@ #include #include #include -#include #include #include diff --git a/drivers/scsi/aacraid/dpcsup.c b/drivers/scsi/aacraid/dpcsup.c index d38b628..66aeb57 100644 --- a/drivers/scsi/aacraid/dpcsup.c +++ b/drivers/scsi/aacraid/dpcsup.c @@ -32,7 +32,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aacraid/sa.c b/drivers/scsi/aacraid/sa.c index 6f1a178..f4b5e97 100644 --- a/drivers/scsi/aacraid/sa.c +++ b/drivers/scsi/aacraid/sa.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 1d239f6..cbbfbc9 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/scsi/aic94xx/aic94xx_scb.c b/drivers/scsi/aic94xx/aic94xx_scb.c index 8f43ff7..db6ab1a 100644 --- a/drivers/scsi/aic94xx/aic94xx_scb.c +++ b/drivers/scsi/aic94xx/aic94xx_scb.c @@ -24,7 +24,6 @@ * */ -#include #include #include "aic94xx.h" diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 12497da..03bfed6 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c @@ -49,7 +49,6 @@ #include #include #include -#include #include #include diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index dc70c18..e34442e 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -22,7 +22,6 @@ * */ -#include #include #include "sas_internal.h" diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 89403b0..6335830 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c index a0cc05d..60d2944 100644 --- a/drivers/usb/net/kaweth.c +++ b/drivers/usb/net/kaweth.c @@ -55,7 +55,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c index 5084799..7db9de6 100644 --- a/drivers/video/aty/radeon_i2c.c +++ b/drivers/video/aty/radeon_i2c.c @@ -1,7 +1,6 @@ #include #include #include -#include #include diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c index ca93a75..b7655c0 100644 --- a/drivers/video/g364fb.c +++ b/drivers/video/g364fb.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c index 2338716..e64f8b5 100644 --- a/drivers/video/platinumfb.c +++ b/drivers/video/platinumfb.c @@ -28,7 +28,6 @@ #include #include #include -#include #include #include #include diff --git a/drivers/video/stifb.c b/drivers/video/stifb.c index 69f3b26..c97709e 100644 --- a/drivers/video/stifb.c +++ b/drivers/video/stifb.c @@ -64,7 +64,6 @@ #include #include #include -#include #include /* for HP-UX compatibility */ #include diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c index 06fc19a..ad66f07 100644 --- a/drivers/video/valkyriefb.c +++ b/drivers/video/valkyriefb.c @@ -51,7 +51,6 @@ #include #include #include -#include #include #include #include diff --git a/include/asm-arm/arch-ixp4xx/dma.h b/include/asm-arm/arch-ixp4xx/dma.h index 789f7f5..2c7f532 100644 --- a/include/asm-arm/arch-ixp4xx/dma.h +++ b/include/asm-arm/arch-ixp4xx/dma.h @@ -12,7 +12,6 @@ #define __ASM_ARCH_DMA_H #include -#include #include #include #include diff --git a/include/rdma/ib_mad.h b/include/rdma/ib_mad.h index 585d28e..739fa4d 100644 --- a/include/rdma/ib_mad.h +++ b/include/rdma/ib_mad.h @@ -39,8 +39,6 @@ #if !defined( IB_MAD_H ) #define IB_MAD_H -#include - #include /* Management base version */ diff --git a/sound/core/init.c b/sound/core/init.c index 4a431e3..f2fe357 100644 --- a/sound/core/init.c +++ b/sound/core/init.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c index a339f0c..23018a7 100644 --- a/sound/oss/au1550_ac97.c +++ b/sound/oss/au1550_ac97.c @@ -47,7 +47,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c index dcd8d6d..a9c23b2 100644 --- a/sound/oss/soundcard.c +++ b/sound/oss/soundcard.c @@ -44,6 +44,7 @@ #include #include #include +#include /* * This ought to be moved into include/asm/dma.h diff --git a/sound/pci/ca0106/ca0106_mixer.c b/sound/pci/ca0106/ca0106_mixer.c index b913a1f..9c3a9c8 100644 --- a/sound/pci/ca0106/ca0106_mixer.c +++ b/sound/pci/ca0106/ca0106_mixer.c @@ -62,7 +62,6 @@ #include #include #include -#include #include #include #include @@ -71,6 +70,7 @@ #include #include #include +#include #include "ca0106.h" diff --git a/sound/pci/ca0106/ca0106_proc.c b/sound/pci/ca0106/ca0106_proc.c index 75ca421..ae80f51 100644 --- a/sound/pci/ca0106/ca0106_proc.c +++ b/sound/pci/ca0106/ca0106_proc.c @@ -64,7 +64,6 @@ #include #include #include -#include #include #include #include @@ -73,6 +72,7 @@ #include #include #include +#include #include "ca0106.h" diff --git a/sound/pci/cs46xx/dsp_spos.c b/sound/pci/cs46xx/dsp_spos.c index 89c4027..336e77e 100644 --- a/sound/pci/cs46xx/dsp_spos.c +++ b/sound/pci/cs46xx/dsp_spos.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/pci/cs46xx/dsp_spos_scb_lib.c b/sound/pci/cs46xx/dsp_spos_scb_lib.c index 343f51d..57e357d 100644 --- a/sound/pci/cs46xx/dsp_spos_scb_lib.c +++ b/sound/pci/cs46xx/dsp_spos_scb_lib.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c index 1589d2f..1e5ff0c 100644 --- a/sound/pci/hda/hda_generic.c +++ b/sound/pci/hda/hda_generic.c @@ -23,7 +23,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 17df4d0..e313e68 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c @@ -23,7 +23,6 @@ #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/patch_atihdmi.c b/sound/pci/hda/patch_atihdmi.c index 7333f27..831469d 100644 --- a/sound/pci/hda/patch_atihdmi.c +++ b/sound/pci/hda/patch_atihdmi.c @@ -25,7 +25,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index ed5e45e..6fcda9b 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 4c839b0..2b11ac8 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -35,7 +35,6 @@ #include #include #include -#include #include #include "hda_codec.h" #include "hda_local.h" -- cgit v0.10.2 From 8d7d86e9bd377e5779bf3c8da03b27d823c039b4 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Fri, 16 Mar 2007 19:55:52 -0700 Subject: PCI: kernel-doc fix Warning(linux-2621-rc3g7/drivers/pci/pci.c:1283): No description found for parameter 'dev' Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 2086cd1..7bd8a72 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -1323,7 +1323,7 @@ pci_intx(struct pci_dev *pdev, int enable) /** * pci_msi_off - disables any msi or msix capabilities - * @pdev: the PCI device to operate on + * @dev: the PCI device to operate on * * If you want to use msi see pci_enable_msi and friends. * This is a lower level primitive that allows us to disable -- cgit v0.10.2 From 40ee9e9f8d52d85f2446bbdda7823a3f1de62f3f Mon Sep 17 00:00:00 2001 From: Jesse Barnes Date: Sat, 24 Mar 2007 11:03:32 -0700 Subject: PCI: fix sysfs rom file creation for BIOS ROM shadows At one time, if a BIOS ROM shadow was detected for the boot video device (stored at offset 0xc0000), we'd set a special resource flag, IORESOURCE_ROM_SHADOW, so that the sysfs ROM file code could handle it properly. That broke along the way somewhere though, so current kernels will be missing 'rom' files in sysfs if the video device doesn't have an explicit ROM BAR. This patch fixes the regression by moving the video fixup quirk to a little later in the boot cycle (to avoid having its work undone by PCI resource allocation) and checking in the PCI sysfs code whether a rom file should be created due to a shadow resource, which is also moved to a little later in the boot cycle so it will occur after the video fixup. Tested and works on my i386 test box. Signed-off-by: Jesse Barnes Signed-off-by: Greg Kroah-Hartman diff --git a/arch/i386/pci/fixup.c b/arch/i386/pci/fixup.c index 8053b17..b62eafb 100644 --- a/arch/i386/pci/fixup.c +++ b/arch/i386/pci/fixup.c @@ -354,7 +354,7 @@ static void __devinit pci_fixup_video(struct pci_dev *pdev) printk(KERN_DEBUG "Boot video device is %s\n", pci_name(pdev)); } } -DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); +DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_video); /* * Some Toshiba laptops need extra code to enable their TI TSB43AB22/A. diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index cd913a2..29676fe 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -620,7 +620,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) goto err_bin_file; /* If the device has a ROM, try to expose it in sysfs. */ - if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) { + if (pci_resource_len(pdev, PCI_ROM_RESOURCE) || + (pdev->resource[PCI_ROM_RESOURCE].flags & IORESOURCE_ROM_SHADOW)) { rom_attr = kzalloc(sizeof(*rom_attr), GFP_ATOMIC); if (rom_attr) { pdev->rom_attr = rom_attr; @@ -695,4 +696,4 @@ static int __init pci_sysfs_init(void) return 0; } -__initcall(pci_sysfs_init); +late_initcall(pci_sysfs_init); -- cgit v0.10.2 From 6ba186361ed2cda7e174856a3ab8a8e3237b3c3d Mon Sep 17 00:00:00 2001 From: Jean Delvare Date: Sat, 7 Apr 2007 17:21:28 +0200 Subject: PCI: Require vendor and device for new_id Currently, there is no minimum number of fields required when adding a new device ID to a PCI driver through the new_id sysfs file. It is possible to add a new ID with only the vendor ID set, causing the driver to attempt to attach to all PCI devices from that vendor. This has been reported to happen accidentally: http://lists.lm-sensors.org/pipermail/lm-sensors/2007-March/019366.html It is even possible to not even set the vendor ID field, causing the driver to attempt to attach to _all_ the PCI devices. This sounds dangerous and I fail to see any valid use of this "feature". Thus I suggest that we now require at least the first two fields (vendor ID and device ID) to be set. For what it's worth, this is what the USB subsystem does. Signed-off-by: Jean Delvare Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/pci.txt b/Documentation/pci.txt index cdf2f3c..a8ded1a 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt @@ -163,9 +163,9 @@ echo "vendor device subvendor subdevice class class_mask driver_data" > \ /sys/bus/pci/drivers/{driver}/new_id All fields are passed in as hexadecimal values (no leading 0x). -Users need pass only as many fields as necessary: - o vendor, device, subvendor, and subdevice fields default - to PCI_ANY_ID (FFFFFFFF), +The vendor and device fields are mandatory, the others are optional. Users +need pass only as many optional fields as necessary: + o subvendor and subdevice fields default to PCI_ANY_ID (FFFFFFFF) o class and classmask fields default to 0 o driver_data defaults to 0UL. diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 39e80fc..07fdb3c 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -52,7 +52,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) { struct pci_dynid *dynid; struct pci_driver *pdrv = to_pci_driver(driver); - __u32 vendor=PCI_ANY_ID, device=PCI_ANY_ID, subvendor=PCI_ANY_ID, + __u32 vendor, device, subvendor=PCI_ANY_ID, subdevice=PCI_ANY_ID, class=0, class_mask=0; unsigned long driver_data=0; int fields=0; @@ -61,7 +61,7 @@ store_new_id(struct device_driver *driver, const char *buf, size_t count) fields = sscanf(buf, "%x %x %x %x %x %x %lux", &vendor, &device, &subvendor, &subdevice, &class, &class_mask, &driver_data); - if (fields < 0) + if (fields < 2) return -EINVAL; dynid = kzalloc(sizeof(*dynid), GFP_KERNEL); -- cgit v0.10.2 From 96bde06a2df1b363206d3cdef53134b84ff37813 Mon Sep 17 00:00:00 2001 From: Sam Ravnborg Date: Mon, 26 Mar 2007 21:53:30 -0800 Subject: pci: do not mark exported functions as __devinit Functions marked __devinit will be removed after kernel init. But being exported they are potentially called by a module much later. So the safer choice seems to be to keep the function even in the non CONFIG_HOTPLUG case. This silence the follwoing section mismatch warnings: WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_bus_add_device from __ksymtab_gpl between '__ksymtab_pci_bus_add_device' (at offset 0x20) and '__ksymtab_pci_walk_bus' WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_create_bus from __ksymtab_gpl between '__ksymtab_pci_create_bus' (at offset 0x40) and '__ksymtab_pci_stop_bus_device' WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_bus_max_busnr from __ksymtab_gpl between '__ksymtab_pci_bus_max_busnr' (at offset 0xc0) and '__ksymtab_pci_assign_resource_fixed' WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_claim_resource from __ksymtab_gpl between '__ksymtab_pci_claim_resource' (at offset 0xe0) and '__ksymtab_pcie_port_bus_type' WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_bus_add_devices from __ksymtab between '__ksymtab_pci_bus_add_devices' (at offset 0x70) and '__ksymtab_pci_bus_alloc_resource' WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_scan_bus_parented from __ksymtab between '__ksymtab_pci_scan_bus_parented' (at offset 0x90) and '__ksymtab_pci_root_buses' WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_bus_assign_resources from __ksymtab between '__ksymtab_pci_bus_assign_resources' (at offset 0x4d0) and '__ksymtab_pci_bus_size_bridges' WARNING: drivers/built-in.o - Section mismatch: reference to .init.text:pci_bus_size_bridges from __ksymtab between '__ksymtab_pci_bus_size_bridges' (at offset 0x4e0) and '__ksymtab_pci_setup_cardbus' Signed-off-by: Sam Ravnborg Signed-off-by: Andrew Morton Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/bus.c b/drivers/pci/bus.c index aadaa3c..9e5ea07 100644 --- a/drivers/pci/bus.c +++ b/drivers/pci/bus.c @@ -77,7 +77,7 @@ pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, * This adds a single pci device to the global * device list and adds sysfs and procfs entries */ -int __devinit pci_bus_add_device(struct pci_dev *dev) +int pci_bus_add_device(struct pci_dev *dev) { int retval; retval = device_add(&dev->dev); @@ -105,7 +105,7 @@ int __devinit pci_bus_add_device(struct pci_dev *dev) * * Call hotplug for each new devices. */ -void __devinit pci_bus_add_devices(struct pci_bus *bus) +void pci_bus_add_devices(struct pci_bus *bus) { struct pci_dev *dev; int retval; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index 7bd8a72..fd47ac0 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -35,8 +35,7 @@ unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE; * Given a PCI bus, returns the highest PCI bus number present in the set * including the given PCI bus and its list of child PCI buses. */ -unsigned char __devinit -pci_bus_max_busnr(struct pci_bus* bus) +unsigned char pci_bus_max_busnr(struct pci_bus* bus) { struct list_head *tmp; unsigned char max, n; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2fe1d69..629edf3 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -364,7 +364,7 @@ void __devinit pci_read_bridge_bases(struct pci_bus *child) } } -static struct pci_bus * __devinit pci_alloc_bus(void) +static struct pci_bus * pci_alloc_bus(void) { struct pci_bus *b; @@ -432,7 +432,7 @@ error_register: return NULL; } -struct pci_bus * __devinit pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) +struct pci_bus *pci_add_new_bus(struct pci_bus *parent, struct pci_dev *dev, int busnr) { struct pci_bus *child; @@ -461,7 +461,7 @@ static void pci_enable_crs(struct pci_dev *dev) pci_write_config_word(dev, rpcap + PCI_EXP_RTCTL, rpctl); } -static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) +static void pci_fixup_parent_subordinate_busnr(struct pci_bus *child, int max) { struct pci_bus *parent = child->parent; @@ -477,7 +477,7 @@ static void __devinit pci_fixup_parent_subordinate_busnr(struct pci_bus *child, } } -unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); +unsigned int pci_scan_child_bus(struct pci_bus *bus); /* * If it's a bridge, configure it and scan the bus behind it. @@ -489,7 +489,7 @@ unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus); * them, we proceed to assigning numbers to the remaining buses in * order to avoid overlaps between old and new bus numbers. */ -int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass) +int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass) { struct pci_bus *child; int is_cardbus = (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS); @@ -912,7 +912,7 @@ pci_scan_device(struct pci_bus *bus, int devfn) return dev; } -void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus) +void pci_device_add(struct pci_dev *dev, struct pci_bus *bus) { device_initialize(&dev->dev); dev->dev.release = pci_release_dev; @@ -935,8 +935,7 @@ void __devinit pci_device_add(struct pci_dev *dev, struct pci_bus *bus) up_write(&pci_bus_sem); } -struct pci_dev * __devinit -pci_scan_single_device(struct pci_bus *bus, int devfn) +struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; @@ -958,7 +957,7 @@ pci_scan_single_device(struct pci_bus *bus, int devfn) * discovered devices to the @bus->devices list. New devices * will have an empty dev->global_list head. */ -int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) +int pci_scan_slot(struct pci_bus *bus, int devfn) { int func, nr = 0; int scan_all_fns; @@ -991,7 +990,7 @@ int __devinit pci_scan_slot(struct pci_bus *bus, int devfn) return nr; } -unsigned int __devinit pci_scan_child_bus(struct pci_bus *bus) +unsigned int pci_scan_child_bus(struct pci_bus *bus) { unsigned int devfn, pass, max = bus->secondary; struct pci_dev *dev; @@ -1041,7 +1040,7 @@ unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus) return max; } -struct pci_bus * __devinit pci_create_bus(struct device *parent, +struct pci_bus * pci_create_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { int error; @@ -1119,7 +1118,7 @@ err_out: } EXPORT_SYMBOL_GPL(pci_create_bus); -struct pci_bus * __devinit pci_scan_bus_parented(struct device *parent, +struct pci_bus *pci_scan_bus_parented(struct device *parent, int bus, struct pci_ops *ops, void *sysdata) { struct pci_bus *b; diff --git a/drivers/pci/search.c b/drivers/pci/search.c index 2dd8681..b137a27 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c @@ -15,8 +15,7 @@ DECLARE_RWSEM(pci_bus_sem); -static struct pci_bus * -pci_do_find_bus(struct pci_bus* bus, unsigned char busnr) +static struct pci_bus *pci_do_find_bus(struct pci_bus *bus, unsigned char busnr) { struct pci_bus* child; struct list_head *tmp; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 3554f39..5ec297d 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -36,8 +36,7 @@ #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) -static void __devinit -pbus_assign_resources_sorted(struct pci_bus *bus) +static void pbus_assign_resources_sorted(struct pci_bus *bus) { struct pci_dev *dev; struct resource *res; @@ -220,8 +219,7 @@ pci_setup_bridge(struct pci_bus *bus) /* Check whether the bridge supports optional I/O and prefetchable memory ranges. If not, the respective base/limit registers must be read-only and read as 0. */ -static void __devinit -pci_bridge_check_ranges(struct pci_bus *bus) +static void pci_bridge_check_ranges(struct pci_bus *bus) { u16 io; u32 pmem; @@ -259,8 +257,7 @@ pci_bridge_check_ranges(struct pci_bus *bus) bus resource of a given type. Note: we intentionally skip the bus resources which have already been assigned (that is, have non-NULL parent resource). */ -static struct resource * __devinit -find_free_bus_resource(struct pci_bus *bus, unsigned long type) +static struct resource *find_free_bus_resource(struct pci_bus *bus, unsigned long type) { int i; struct resource *r; @@ -281,8 +278,7 @@ find_free_bus_resource(struct pci_bus *bus, unsigned long type) since these windows have 4K granularity and the IO ranges of non-bridge PCI devices are limited to 256 bytes. We must be careful with the ISA aliasing though. */ -static void __devinit -pbus_size_io(struct pci_bus *bus) +static void pbus_size_io(struct pci_bus *bus) { struct pci_dev *dev; struct resource *b_res = find_free_bus_resource(bus, IORESOURCE_IO); @@ -326,8 +322,7 @@ pbus_size_io(struct pci_bus *bus) /* Calculate the size of the bus and minimal alignment which guarantees that all child resources fit in this size. */ -static int __devinit -pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) +static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) { struct pci_dev *dev; unsigned long min_align, align, size; @@ -447,8 +442,7 @@ pci_bus_size_cardbus(struct pci_bus *bus) } } -void __devinit -pci_bus_size_bridges(struct pci_bus *bus) +void pci_bus_size_bridges(struct pci_bus *bus) { struct pci_dev *dev; unsigned long mask, prefmask; @@ -498,8 +492,7 @@ pci_bus_size_bridges(struct pci_bus *bus) } EXPORT_SYMBOL(pci_bus_size_bridges); -void __devinit -pci_bus_assign_resources(struct pci_bus *bus) +void pci_bus_assign_resources(struct pci_bus *bus) { struct pci_bus *b; struct pci_dev *dev; diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index cb4ced3..6dfd861 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c @@ -101,8 +101,7 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) new & ~PCI_REGION_FLAG_MASK); } -int __devinit -pci_claim_resource(struct pci_dev *dev, int resource) +int pci_claim_resource(struct pci_dev *dev, int resource) { struct resource *res = &dev->resource[resource]; struct resource *root = NULL; @@ -212,8 +211,7 @@ EXPORT_SYMBOL_GPL(pci_assign_resource_fixed); #endif /* Sort resources by alignment */ -void __devinit -pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) +void pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) { int i; -- cgit v0.10.2 From 0da0ead90122578ef6e4afba9ba4bcd3455fd8e8 Mon Sep 17 00:00:00 2001 From: Sergei Shtylyov Date: Sun, 1 Apr 2007 21:13:58 +0400 Subject: PCI: define pci_request/release_regions() for CONFIG_PCI=n Balance declarations of pci_request_regions() and pci_release_regions() with empty inline definitions for the CONFIG_PCI=n case -- otherwise my patch to drivers/net/3c59x.c in the -mm tree doesn't compile. :-) Signed-off-by: Sergei Shtylyov Signed-off-by: Greg Kroah-Hartman diff --git a/include/linux/pci.h b/include/linux/pci.h index 3aba02a..99d4575 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -744,6 +744,9 @@ static inline int pci_set_power_state(struct pci_dev *dev, pci_power_t state) { static inline pci_power_t pci_choose_state(struct pci_dev *dev, pm_message_t state) { return PCI_D0; } static inline int pci_enable_wake(struct pci_dev *dev, pci_power_t state, int enable) { return 0; } +static inline int pci_request_regions(struct pci_dev *dev, const char *res_name) { return -EIO; } +static inline void pci_release_regions(struct pci_dev *dev) { } + #define pci_dma_burst_advice(pdev, strat, strategy_parameter) do { } while (0) static inline void pci_block_user_cfg_access(struct pci_dev *dev) { } -- cgit v0.10.2 From 54eee4c5bf553ad54ba200d00487b61eb6b155f6 Mon Sep 17 00:00:00 2001 From: Randy Dunlap Date: Wed, 4 Apr 2007 21:35:39 -0700 Subject: PCI Documentation: power/pci.txt fix copy/paste error Correct function name copy-paste error. Signed-off-by: Randy Dunlap Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/power/pci.txt b/Documentation/power/pci.txt index b6a3cbf..e00b099 100644 --- a/Documentation/power/pci.txt +++ b/Documentation/power/pci.txt @@ -203,7 +203,7 @@ resume Usage: -if (dev->driver && dev->driver->suspend) +if (dev->driver && dev->driver->resume) dev->driver->resume(dev) The resume callback may be called from any power state, and is always meant to -- cgit v0.10.2 From e387b9eefe89a23245f2446f947529cce5d6db35 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:27 +1100 Subject: MSI: Simplify BUG() handling in pci_disable_msi() Although it might be nice to do a printk before BUG'ing, it's really not necessary, and it complicates the code. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a4ef93e..9213c57 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -572,18 +572,15 @@ void pci_disable_msi(struct pci_dev* dev) if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { return; } - if (irq_has_action(dev->first_msi_irq)) { - printk(KERN_WARNING "PCI: %s: pci_disable_msi() called without " - "free_irq() on MSI irq %d\n", - pci_name(dev), dev->first_msi_irq); - BUG_ON(irq_has_action(dev->first_msi_irq)); - } else { - default_irq = entry->msi_attrib.default_irq; - msi_free_irq(dev, dev->first_msi_irq); - - /* Restore dev->irq to its default pin-assertion irq */ - dev->irq = default_irq; - } + + BUG_ON(irq_has_action(dev->first_msi_irq)); + + default_irq = entry->msi_attrib.default_irq; + msi_free_irq(dev, dev->first_msi_irq); + + /* Restore dev->irq to its default pin-assertion irq */ + dev->irq = default_irq; + dev->first_msi_irq = 0; } -- cgit v0.10.2 From 54bc6c0b0edd164fc2ea85b3964736c182f6bd5d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:27 +1100 Subject: MSI: Simplify BUG() handling in pci_disable_msix() Although it might be nice to do a printk before BUG'ing, it's really not necessary, and it complicates the code. The behaviour has changed slightly, in that before we set a flag if the irq had an action, and continued freeing the other irqs. But as I see it that's all irrelevant because we end up BUG'ing anyway. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 9213c57..db45231 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -676,7 +676,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) void pci_disable_msix(struct pci_dev* dev) { - int irq, head, tail = 0, warning = 0; + int irq, head, tail = 0; if (!pci_msi_enable) return; @@ -693,19 +693,14 @@ void pci_disable_msix(struct pci_dev* dev) irq = head = dev->first_msi_irq; while (head != tail) { tail = get_irq_msi(irq)->link.tail; - if (irq_has_action(irq)) - warning = 1; - else if (irq != head) /* Release MSI-X irq */ + + BUG_ON(irq_has_action(irq)); + + if (irq != head) /* Release MSI-X irq */ msi_free_irq(dev, irq); irq = tail; } msi_free_irq(dev, irq); - if (warning) { - printk(KERN_WARNING "PCI: %s: pci_disable_msix() called without " - "free_irq() on all MSI-X irqs\n", - pci_name(dev)); - BUG_ON(warning > 0); - } dev->first_msi_irq = 0; } -- cgit v0.10.2 From c31af3987020eeb1facf64d702dcf39e6c7382e6 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:31 +1100 Subject: MSI: Simplify BUG() handling in msi_remove_pci_irq_vectors() part 1 Although it might be nice to do a printk before BUG'ing, it's really not necessary, and it complicates the code. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index db45231..2a119f8 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -719,13 +719,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) return; if (dev->msi_enabled) { - if (irq_has_action(dev->first_msi_irq)) { - printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " - "called without free_irq() on MSI irq %d\n", - pci_name(dev), dev->first_msi_irq); - BUG_ON(irq_has_action(dev->first_msi_irq)); - } else /* Release MSI irq assigned to this device */ - msi_free_irq(dev, dev->first_msi_irq); + BUG_ON(irq_has_action(dev->first_msi_irq)); + msi_free_irq(dev, dev->first_msi_irq); } if (dev->msix_enabled) { int irq, head, tail = 0, warning = 0; -- cgit v0.10.2 From 00ba16ab2658afe11d4fdcaf16a331292c44bee6 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:31 +1100 Subject: MSI: Simplify BUG() handling in msi_remove_pci_irq_vectors() part 2 Although it might be nice to do a printk before BUG'ing, it's really not necessary, and it complicates the code. The behaviour has changed slightly, in that before we set a flag if the irq had an action, and continued freeing the other irqs. But as I see it that's all irrelevant because we end up BUG'ing anyway. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 2a119f8..91fed54 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -723,27 +723,21 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) msi_free_irq(dev, dev->first_msi_irq); } if (dev->msix_enabled) { - int irq, head, tail = 0, warning = 0; + int irq, head, tail = 0; void __iomem *base = NULL; irq = head = dev->first_msi_irq; while (head != tail) { tail = get_irq_msi(irq)->link.tail; base = get_irq_msi(irq)->mask_base; - if (irq_has_action(irq)) - warning = 1; - else if (irq != head) /* Release MSI-X irq */ + + BUG_ON(irq_has_action(irq)); + + if (irq != head) /* Release MSI-X irq */ msi_free_irq(dev, irq); irq = tail; } msi_free_irq(dev, irq); - if (warning) { - iounmap(base); - printk(KERN_WARNING "PCI: %s: msi_remove_pci_irq_vectors() " - "called without free_irq() on all MSI-X irqs\n", - pci_name(dev)); - BUG_ON(warning > 0); - } } } -- cgit v0.10.2 From fc4afc7b2bdd81e2dbded5a8222676d3161758d3 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:33 +1100 Subject: MSI: Consolidate MSI-X irq freeing code For the MSI-X case we do exactly the same logic in pci_disable_msix() and msi_remove_pci_irq_vectors(), so consolidate them. msi_remove_pci_irq_vectors() wasn't setting dev->first_msi_irq to 0, but I think it should have been, so the consolidated version does. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 91fed54..4f326f3 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -674,10 +674,26 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) return status; } -void pci_disable_msix(struct pci_dev* dev) +static void msix_free_all_irqs(struct pci_dev *dev) { int irq, head, tail = 0; + irq = head = dev->first_msi_irq; + while (head != tail) { + tail = get_irq_msi(irq)->link.tail; + + BUG_ON(irq_has_action(irq)); + + if (irq != head) + msi_free_irq(dev, irq); + irq = tail; + } + msi_free_irq(dev, irq); + dev->first_msi_irq = 0; +} + +void pci_disable_msix(struct pci_dev* dev) +{ if (!pci_msi_enable) return; if (!dev) @@ -690,18 +706,7 @@ void pci_disable_msix(struct pci_dev* dev) pci_intx(dev, 1); /* enable intx */ dev->msix_enabled = 0; - irq = head = dev->first_msi_irq; - while (head != tail) { - tail = get_irq_msi(irq)->link.tail; - - BUG_ON(irq_has_action(irq)); - - if (irq != head) /* Release MSI-X irq */ - msi_free_irq(dev, irq); - irq = tail; - } - msi_free_irq(dev, irq); - dev->first_msi_irq = 0; + msix_free_all_irqs(dev); } /** @@ -722,23 +727,9 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) BUG_ON(irq_has_action(dev->first_msi_irq)); msi_free_irq(dev, dev->first_msi_irq); } - if (dev->msix_enabled) { - int irq, head, tail = 0; - void __iomem *base = NULL; - irq = head = dev->first_msi_irq; - while (head != tail) { - tail = get_irq_msi(irq)->link.tail; - base = get_irq_msi(irq)->mask_base; - - BUG_ON(irq_has_action(irq)); - - if (irq != head) /* Release MSI-X irq */ - msi_free_irq(dev, irq); - irq = tail; - } - msi_free_irq(dev, irq); - } + if (dev->msix_enabled) + msix_free_all_irqs(dev); } void pci_no_msi(void) -- cgit v0.10.2 From 7ede9c1fa50e01a8222217d4606bcbc44cd68f1a Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:34 +1100 Subject: MSI: Consolidate BUG_ON()s. When freeing MSIs and MSI-Xs, we BUG_ON() if the irq has not been freed, ie. if it still has an action. We can consolidate all of these BUG_ON()s into msi_free_irqs() as all the code paths lead there almost immediately anyway. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 4f326f3..38e4c80 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -573,8 +573,6 @@ void pci_disable_msi(struct pci_dev* dev) return; } - BUG_ON(irq_has_action(dev->first_msi_irq)); - default_irq = entry->msi_attrib.default_irq; msi_free_irq(dev, dev->first_msi_irq); @@ -590,6 +588,8 @@ static int msi_free_irq(struct pci_dev* dev, int irq) int head, entry_nr, type; void __iomem *base; + BUG_ON(irq_has_action(irq)); + entry = get_irq_msi(irq); if (!entry || entry->dev != dev) { return -EINVAL; @@ -682,8 +682,6 @@ static void msix_free_all_irqs(struct pci_dev *dev) while (head != tail) { tail = get_irq_msi(irq)->link.tail; - BUG_ON(irq_has_action(irq)); - if (irq != head) msi_free_irq(dev, irq); irq = tail; @@ -723,10 +721,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) if (!pci_msi_enable || !dev) return; - if (dev->msi_enabled) { - BUG_ON(irq_has_action(dev->first_msi_irq)); + if (dev->msi_enabled) msi_free_irq(dev, dev->first_msi_irq); - } if (dev->msix_enabled) msix_free_all_irqs(dev); -- cgit v0.10.2 From 4cc086fa5b648dc3dcd56c963e42a212f2d9df29 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:34 +1100 Subject: MSI: Move EXPORT_SYMBOL()s near their definition Move EXPORT_SYMBOL()s near their definition. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 38e4c80..a2002e7 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -550,6 +550,7 @@ int pci_enable_msi(struct pci_dev* dev) status = msi_capability_init(dev); return status; } +EXPORT_SYMBOL(pci_enable_msi); void pci_disable_msi(struct pci_dev* dev) { @@ -581,6 +582,7 @@ void pci_disable_msi(struct pci_dev* dev) dev->first_msi_irq = 0; } +EXPORT_SYMBOL(pci_disable_msi); static int msi_free_irq(struct pci_dev* dev, int irq) { @@ -673,6 +675,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) status = msix_capability_init(dev, entries, nvec); return status; } +EXPORT_SYMBOL(pci_enable_msix); static void msix_free_all_irqs(struct pci_dev *dev) { @@ -706,6 +709,7 @@ void pci_disable_msix(struct pci_dev* dev) msix_free_all_irqs(dev); } +EXPORT_SYMBOL(pci_disable_msix); /** * msi_remove_pci_irq_vectors - reclaim MSI(X) irqs to unused state @@ -732,8 +736,3 @@ void pci_no_msi(void) { pci_msi_enable = 0; } - -EXPORT_SYMBOL(pci_enable_msi); -EXPORT_SYMBOL(pci_disable_msi); -EXPORT_SYMBOL(pci_enable_msix); -EXPORT_SYMBOL(pci_disable_msix); -- cgit v0.10.2 From 3e916c0503a34ba32202a69df1cfeb82f2c5749d Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:36 +1100 Subject: MSI: Remove msi_cache We don't need a special cache just for msi descriptors. They're not particularly large, under 100 bytes for sure, and don't seem to require any special alignment etc. On most systems there will be relatively few MSIs, and hence we waste most of a page on the cache. Better to just kzalloc the space for the few we do need. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index a2002e7..762bff1 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -24,20 +24,8 @@ #include "pci.h" #include "msi.h" -static struct kmem_cache* msi_cachep; - static int pci_msi_enable = 1; -static int msi_cache_init(void) -{ - msi_cachep = kmem_cache_create("msi_cache", sizeof(struct msi_desc), - 0, SLAB_HWCACHE_ALIGN, NULL, NULL); - if (!msi_cachep) - return -ENOMEM; - - return 0; -} - static void msi_set_enable(struct pci_dev *dev, int enable) { int pos; @@ -221,28 +209,12 @@ void unmask_msi_irq(unsigned int irq) static int msi_free_irq(struct pci_dev* dev, int irq); -static int msi_init(void) -{ - static int status = -ENOMEM; - - if (!status) - return status; - - status = msi_cache_init(); - if (status < 0) { - pci_msi_enable = 0; - printk(KERN_WARNING "PCI: MSI cache init failed\n"); - return status; - } - - return status; -} static struct msi_desc* alloc_msi_entry(void) { struct msi_desc *entry; - entry = kmem_cache_zalloc(msi_cachep, GFP_KERNEL); + entry = kzalloc(sizeof(struct msi_desc), GFP_KERNEL); if (!entry) return NULL; @@ -368,7 +340,7 @@ static int msi_capability_init(struct pci_dev *dev) /* Configure MSI capability structure */ irq = arch_setup_msi_irq(dev, entry); if (irq < 0) { - kmem_cache_free(msi_cachep, entry); + kfree(entry); return irq; } entry->link.head = irq; @@ -441,7 +413,7 @@ static int msix_capability_init(struct pci_dev *dev, /* Configure MSI-X capability structure */ irq = arch_setup_msi_irq(dev, entry); if (irq < 0) { - kmem_cache_free(msi_cachep, entry); + kfree(entry); break; } entries[i].vector = irq; @@ -530,10 +502,6 @@ int pci_enable_msi(struct pci_dev* dev) if (pci_msi_supported(dev) < 0) return -EINVAL; - status = msi_init(); - if (status < 0) - return status; - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); if (!pos) return -EINVAL; @@ -604,7 +572,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq) get_irq_msi(entry->link.tail)->link.head = entry->link.head; arch_teardown_msi_irq(irq); - kmem_cache_free(msi_cachep, entry); + kfree(entry); if (type == PCI_CAP_ID_MSIX) { writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + @@ -641,10 +609,6 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) if (!entries || pci_msi_supported(dev) < 0) return -EINVAL; - status = msi_init(); - if (status < 0) - return status; - pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); if (!pos) return -EINVAL; -- cgit v0.10.2 From b1e2303dba021ee417c65a89e467a2b145ff9217 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:39 +1100 Subject: MSI: Expand pci_msi_supported() pci_enable_msi() and pci_enable_msix() both search for the MSI/MSI-X capability, we can fold this into pci_msi_supported() by passing the type in. Update the code to match the comment for pci_msi_supported(). That is it returns 0 on success, and anything else indicates an error. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 762bff1..d5b9b94 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -459,12 +459,13 @@ static int msix_capability_init(struct pci_dev *dev, /** * pci_msi_supported - check whether MSI may be enabled on device * @dev: pointer to the pci_dev data structure of MSI device function + * @type: are we checking for MSI or MSI-X ? * * Look at global flags, the device itself, and its parent busses * to return 0 if MSI are supported for the device. **/ static -int pci_msi_supported(struct pci_dev * dev) +int pci_msi_supported(struct pci_dev * dev, int type) { struct pci_bus *bus; @@ -482,6 +483,9 @@ int pci_msi_supported(struct pci_dev * dev) if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) return -EINVAL; + if (!pci_find_capability(dev, type)) + return -EINVAL; + return 0; } @@ -497,13 +501,9 @@ int pci_msi_supported(struct pci_dev * dev) **/ int pci_enable_msi(struct pci_dev* dev) { - int pos, status; + int status; - if (pci_msi_supported(dev) < 0) - return -EINVAL; - - pos = pci_find_capability(dev, PCI_CAP_ID_MSI); - if (!pos) + if (pci_msi_supported(dev, PCI_CAP_ID_MSI)) return -EINVAL; WARN_ON(!!dev->msi_enabled); @@ -606,13 +606,10 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) int i, j; u16 control; - if (!entries || pci_msi_supported(dev) < 0) + if (!entries || pci_msi_supported(dev, PCI_CAP_ID_MSIX)) return -EINVAL; pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); - if (!pos) - return -EINVAL; - pci_read_config_word(dev, msi_control_reg(pos), &control); nr_entries = multi_msix_capable(control); if (nvec > nr_entries) -- cgit v0.10.2 From 128bc5fced238752d01b5169077f2ec624b3d59b Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 22 Mar 2007 21:51:39 +1100 Subject: MSI: Consolidate precondition checks Consolidate precondition checks into a single if statement. Signed-off-by: Michael Ellerman Acked-by: Eric W. Biederman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index d5b9b94..b6dc69e 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -525,12 +525,7 @@ void pci_disable_msi(struct pci_dev* dev) struct msi_desc *entry; int default_irq; - if (!pci_msi_enable) - return; - if (!dev) - return; - - if (!dev->msi_enabled) + if (!pci_msi_enable || !dev || !dev->msi_enabled) return; msi_set_enable(dev, 0); @@ -656,12 +651,7 @@ static void msix_free_all_irqs(struct pci_dev *dev) void pci_disable_msix(struct pci_dev* dev) { - if (!pci_msi_enable) - return; - if (!dev) - return; - - if (!dev->msix_enabled) + if (!pci_msi_enable || !dev || !dev->msix_enabled) return; msix_set_enable(dev, 0); -- cgit v0.10.2 From 17bbc12acdb23ffb9613e12ca974fafd31bfcb56 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 5 Apr 2007 17:19:07 +1000 Subject: MSI: Rename pci_msi_supported() to pci_msi_check_device() As pointed out by Eric, the name pci_msi_supported() suggests it should return a boolean value, however it doesn't. So update the name to be a bit less confusing and update the doco too. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index b6dc69e..34087af 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -457,15 +457,15 @@ static int msix_capability_init(struct pci_dev *dev, } /** - * pci_msi_supported - check whether MSI may be enabled on device + * pci_msi_check_device - check whether MSI may be enabled on a device * @dev: pointer to the pci_dev data structure of MSI device function * @type: are we checking for MSI or MSI-X ? * * Look at global flags, the device itself, and its parent busses - * to return 0 if MSI are supported for the device. + * to determine if MSI/-X are supported for the device. If MSI/-X is + * supported return 0, else return an error code. **/ -static -int pci_msi_supported(struct pci_dev * dev, int type) +static int pci_msi_check_device(struct pci_dev * dev, int type) { struct pci_bus *bus; @@ -503,7 +503,7 @@ int pci_enable_msi(struct pci_dev* dev) { int status; - if (pci_msi_supported(dev, PCI_CAP_ID_MSI)) + if (pci_msi_check_device(dev, PCI_CAP_ID_MSI)) return -EINVAL; WARN_ON(!!dev->msi_enabled); @@ -601,7 +601,7 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) int i, j; u16 control; - if (!entries || pci_msi_supported(dev, PCI_CAP_ID_MSIX)) + if (!entries || pci_msi_check_device(dev, PCI_CAP_ID_MSIX)) return -EINVAL; pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); -- cgit v0.10.2 From c9953a73e92df11edd812d863ff741877ea9e58c Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 5 Apr 2007 17:19:08 +1000 Subject: MSI: Add an arch_msi_check_device() Add an arch_check_device(), which gives archs a chance to check the input to pci_enable_msi/x. The arch might be interested in the value of nvec so pass it in. Propagate the error value returned from the arch routine out to the caller. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 34087af..5902c00 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -459,15 +459,17 @@ static int msix_capability_init(struct pci_dev *dev, /** * pci_msi_check_device - check whether MSI may be enabled on a device * @dev: pointer to the pci_dev data structure of MSI device function + * @nvec: how many MSIs have been requested ? * @type: are we checking for MSI or MSI-X ? * * Look at global flags, the device itself, and its parent busses * to determine if MSI/-X are supported for the device. If MSI/-X is * supported return 0, else return an error code. **/ -static int pci_msi_check_device(struct pci_dev * dev, int type) +static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type) { struct pci_bus *bus; + int ret; /* MSI must be globally enabled and supported by the device */ if (!pci_msi_enable || !dev || dev->no_msi) @@ -483,6 +485,10 @@ static int pci_msi_check_device(struct pci_dev * dev, int type) if (bus->bus_flags & PCI_BUS_FLAGS_NO_MSI) return -EINVAL; + ret = arch_msi_check_device(dev, nvec, type); + if (ret) + return ret; + if (!pci_find_capability(dev, type)) return -EINVAL; @@ -503,8 +509,9 @@ int pci_enable_msi(struct pci_dev* dev) { int status; - if (pci_msi_check_device(dev, PCI_CAP_ID_MSI)) - return -EINVAL; + status = pci_msi_check_device(dev, 1, PCI_CAP_ID_MSI); + if (status) + return status; WARN_ON(!!dev->msi_enabled); @@ -601,9 +608,13 @@ int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) int i, j; u16 control; - if (!entries || pci_msi_check_device(dev, PCI_CAP_ID_MSIX)) + if (!entries) return -EINVAL; + status = pci_msi_check_device(dev, nvec, PCI_CAP_ID_MSIX); + if (status) + return status; + pos = pci_find_capability(dev, PCI_CAP_ID_MSIX); pci_read_config_word(dev, msi_control_reg(pos), &control); nr_entries = multi_msix_capable(control); @@ -687,3 +698,13 @@ void pci_no_msi(void) { pci_msi_enable = 0; } + + +/* Arch hooks */ + +int __attribute__ ((weak)) +arch_msi_check_device(struct pci_dev* dev, int nvec, int type) +{ + return 0; +} + diff --git a/include/linux/msi.h b/include/linux/msi.h index e38fe682..d2a2000 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -41,6 +41,7 @@ struct msi_desc { */ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); +extern int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); #endif /* LINUX_MSI_H */ -- cgit v0.10.2 From 65891215e6b822c368fb3f36abf129ed48af8be0 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 5 Apr 2007 17:19:08 +1000 Subject: PCI: Create alloc_pci_dev(), the one true way to create a struct pci_dev There are currently several places in the kernel where we kmalloc() a struct pci_dev and start initialising it. It'd be preferable to have an allocator so we can ensure the pci_dev is correctly initialised in one place. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 629edf3..70d37bb 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -846,6 +846,21 @@ static void pci_release_bus_bridge_dev(struct device *dev) kfree(dev); } +struct pci_dev *alloc_pci_dev(void) +{ + struct pci_dev *dev; + + dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + if (!dev) + return NULL; + + INIT_LIST_HEAD(&dev->global_list); + INIT_LIST_HEAD(&dev->bus_list); + + return dev; +} +EXPORT_SYMBOL(alloc_pci_dev); + /* * Read the config data for a PCI device, sanity-check it * and fill in the dev structure... diff --git a/include/linux/pci.h b/include/linux/pci.h index 99d4575..c020747 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -193,6 +193,8 @@ struct pci_dev { #endif }; +extern struct pci_dev *alloc_pci_dev(void); + #define pci_dev_g(n) list_entry(n, struct pci_dev, global_list) #define pci_dev_b(n) list_entry(n, struct pci_dev, bus_list) #define to_pci_dev(n) container_of(n, struct pci_dev, dev) -- cgit v0.10.2 From bab41e9be75121c473b00df2ffa33af3c44066a7 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 5 Apr 2007 17:19:09 +1000 Subject: PCI: Convert to alloc_pci_dev() Convert code that allocs a struct pci_dev to use alloc_pci_dev(). Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c index 60d7d4b..7138092 100644 --- a/arch/powerpc/kernel/pci_64.c +++ b/arch/powerpc/kernel/pci_64.c @@ -340,7 +340,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node, struct pci_dev *dev; const char *type; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = alloc_pci_dev(); if (!dev) return NULL; type = of_get_property(node, "device_type", NULL); diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c index b0acf41..aa8f3a3 100644 --- a/drivers/char/agp/alpha-agp.c +++ b/drivers/char/agp/alpha-agp.c @@ -173,7 +173,7 @@ alpha_core_agp_setup(void) /* * Build a fake pci_dev struct */ - pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); + pdev = alloc_pci_dev(); if (!pdev) return -ENOMEM; pdev->vendor = 0xffff; diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c index 3d83b46..f4562cc 100644 --- a/drivers/char/agp/parisc-agp.c +++ b/drivers/char/agp/parisc-agp.c @@ -329,7 +329,7 @@ parisc_agp_setup(void __iomem *ioc_hpa, void __iomem *lba_hpa) struct agp_bridge_data *bridge; int error = 0; - fake_bridge_dev = kmalloc(sizeof (struct pci_dev), GFP_KERNEL); + fake_bridge_dev = alloc_pci_dev(); if (!fake_bridge_dev) { error = -ENOMEM; goto fail; diff --git a/drivers/pci/hotplug/fakephp.c b/drivers/pci/hotplug/fakephp.c index e27907c..027f686 100644 --- a/drivers/pci/hotplug/fakephp.c +++ b/drivers/pci/hotplug/fakephp.c @@ -238,7 +238,7 @@ static void pci_rescan_bus(const struct pci_bus *bus) { unsigned int devfn; struct pci_dev *dev; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = alloc_pci_dev(); if (!dev) return; diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 70d37bb..c659f8a 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -900,7 +900,7 @@ pci_scan_device(struct pci_bus *bus, int devfn) if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type)) return NULL; - dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL); + dev = alloc_pci_dev(); if (!dev) return NULL; diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 0aa3304..7fc6e06 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -2088,7 +2088,7 @@ megaraid_abort_and_reset(adapter_t *adapter, Scsi_Cmnd *cmd, int aor) static inline int make_local_pdev(adapter_t *adapter, struct pci_dev **pdev) { - *pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); + *pdev = alloc_pci_dev(); if( *pdev == NULL ) return -1; -- cgit v0.10.2 From 4aa9bc955d61fdf03b5f9cee67db188fe1ffa8b7 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 5 Apr 2007 17:19:10 +1000 Subject: MSI: Use a list instead of the custom link structure The msi descriptors are linked together with what looks a lot like a linked list, but isn't a struct list_head list. Make it one. The only complication is that previously we walked a list of irqs, and got the descriptor for each with get_irq_msi(). Now we have a list of descriptors and need to get the irq out of it, so it needs to be in the actual struct msi_desc. We use 0 to indicate no irq is setup. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 5902c00..434c718 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -218,7 +218,8 @@ static struct msi_desc* alloc_msi_entry(void) if (!entry) return NULL; - entry->link.tail = entry->link.head = 0; /* single message */ + INIT_LIST_HEAD(&entry->list); + entry->irq = 0; entry->dev = NULL; return entry; @@ -253,7 +254,6 @@ static void __pci_restore_msi_state(struct pci_dev *dev) static void __pci_restore_msix_state(struct pci_dev *dev) { int pos; - int irq, head, tail = 0; struct msi_desc *entry; u16 control; @@ -263,18 +263,14 @@ static void __pci_restore_msix_state(struct pci_dev *dev) /* route the table */ pci_intx(dev, 0); /* disable intx */ msix_set_enable(dev, 0); - irq = head = dev->first_msi_irq; - entry = get_irq_msi(irq); - pos = entry->msi_attrib.pos; - while (head != tail) { - entry = get_irq_msi(irq); - write_msi_msg(irq, &entry->msg); - msi_set_mask_bit(irq, entry->msi_attrib.masked); - tail = entry->link.tail; - irq = tail; + list_for_each_entry(entry, &dev->msi_list, list) { + write_msi_msg(entry->irq, &entry->msg); + msi_set_mask_bit(entry->irq, entry->msi_attrib.masked); } + entry = get_irq_msi(dev->first_msi_irq); + pos = entry->msi_attrib.pos; pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); control &= ~PCI_MSIX_FLAGS_MASKALL; control |= PCI_MSIX_FLAGS_ENABLE; @@ -343,8 +339,8 @@ static int msi_capability_init(struct pci_dev *dev) kfree(entry); return irq; } - entry->link.head = irq; - entry->link.tail = irq; + entry->irq = irq; + list_add(&entry->list, &dev->msi_list); dev->first_msi_irq = irq; set_irq_msi(irq, entry); @@ -370,8 +366,8 @@ static int msi_capability_init(struct pci_dev *dev) static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { - struct msi_desc *head = NULL, *tail = NULL, *entry = NULL; - int irq, pos, i, j, nr_entries, temp = 0; + struct msi_desc *entry; + int irq, pos, i, j, nr_entries; unsigned long phys_addr; u32 table_offset; u16 control; @@ -416,19 +412,9 @@ static int msix_capability_init(struct pci_dev *dev, kfree(entry); break; } + entry->irq = irq; entries[i].vector = irq; - if (!head) { - entry->link.head = irq; - entry->link.tail = irq; - head = entry; - } else { - entry->link.head = temp; - entry->link.tail = tail->link.tail; - tail->link.tail = irq; - head->link.head = irq; - } - temp = irq; - tail = entry; + list_add(&entry->list, &dev->msi_list); set_irq_msi(irq, entry); } @@ -557,7 +543,7 @@ EXPORT_SYMBOL(pci_disable_msi); static int msi_free_irq(struct pci_dev* dev, int irq) { struct msi_desc *entry; - int head, entry_nr, type; + int entry_nr, type; void __iomem *base; BUG_ON(irq_has_action(irq)); @@ -568,10 +554,8 @@ static int msi_free_irq(struct pci_dev* dev, int irq) } type = entry->msi_attrib.type; entry_nr = entry->msi_attrib.entry_nr; - head = entry->link.head; base = entry->mask_base; - get_irq_msi(entry->link.head)->link.tail = entry->link.tail; - get_irq_msi(entry->link.tail)->link.head = entry->link.head; + list_del(&entry->list); arch_teardown_msi_irq(irq); kfree(entry); @@ -580,7 +564,7 @@ static int msi_free_irq(struct pci_dev* dev, int irq) writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); - if (head == irq) + if (list_empty(&dev->msi_list)) iounmap(base); } @@ -646,17 +630,10 @@ EXPORT_SYMBOL(pci_enable_msix); static void msix_free_all_irqs(struct pci_dev *dev) { - int irq, head, tail = 0; - - irq = head = dev->first_msi_irq; - while (head != tail) { - tail = get_irq_msi(irq)->link.tail; + struct msi_desc *entry; - if (irq != head) - msi_free_irq(dev, irq); - irq = tail; - } - msi_free_irq(dev, irq); + list_for_each_entry(entry, &dev->msi_list, list) + msi_free_irq(dev, entry->irq); dev->first_msi_irq = 0; } @@ -699,6 +676,11 @@ void pci_no_msi(void) pci_msi_enable = 0; } +void pci_msi_init_pci_dev(struct pci_dev *dev) +{ + INIT_LIST_HEAD(&dev->msi_list); +} + /* Arch hooks */ diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h index 62ea04c..3fec13d 100644 --- a/drivers/pci/pci.h +++ b/drivers/pci/pci.h @@ -47,8 +47,10 @@ extern unsigned int pci_pm_d3_delay; #ifdef CONFIG_PCI_MSI void pci_no_msi(void); +extern void pci_msi_init_pci_dev(struct pci_dev *dev); #else static inline void pci_no_msi(void) { } +static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { } #endif #if defined(CONFIG_PCI_MSI) && defined(CONFIG_PM) diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index c659f8a..e48fcf0 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -857,6 +857,8 @@ struct pci_dev *alloc_pci_dev(void) INIT_LIST_HEAD(&dev->global_list); INIT_LIST_HEAD(&dev->bus_list); + pci_msi_init_pci_dev(dev); + return dev; } EXPORT_SYMBOL(alloc_pci_dev); diff --git a/include/linux/msi.h b/include/linux/msi.h index d2a2000..931e013 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -1,6 +1,8 @@ #ifndef LINUX_MSI_H #define LINUX_MSI_H +#include + struct msi_msg { u32 address_lo; /* low 32 bits of msi message address */ u32 address_hi; /* high 32 bits of msi message address */ @@ -24,10 +26,8 @@ struct msi_desc { unsigned default_irq; /* default pre-assigned irq */ }msi_attrib; - struct { - __u16 head; - __u16 tail; - }link; + unsigned int irq; + struct list_head list; void __iomem *mask_base; struct pci_dev *dev; diff --git a/include/linux/pci.h b/include/linux/pci.h index c020747..d43097d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -190,6 +190,7 @@ struct pci_dev { struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ #ifdef CONFIG_PCI_MSI unsigned int first_msi_irq; + struct list_head msi_list; #endif }; -- cgit v0.10.2 From 314e77b3eec57001eaff82b82920150175b74e09 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Thu, 5 Apr 2007 17:19:12 +1000 Subject: MSI: Remove dev->first_msi_irq Now that we keep a list of msi descriptors, we don't need first_msi_irq in the pci dev. If we somehow have zero MSIs configured list_entry() will give us weird oopes or nice memory corruption bugs. So be paranoid. Add BUG_ONs and also a check in pci_msi_check_device() to make sure nvec > 0. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 434c718..7a44ba4 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -269,7 +269,8 @@ static void __pci_restore_msix_state(struct pci_dev *dev) msi_set_mask_bit(entry->irq, entry->msi_attrib.masked); } - entry = get_irq_msi(dev->first_msi_irq); + BUG_ON(list_empty(&dev->msi_list)); + entry = list_entry(dev->msi_list.next, struct msi_desc, list); pos = entry->msi_attrib.pos; pci_read_config_word(dev, pos + PCI_MSIX_FLAGS, &control); control &= ~PCI_MSIX_FLAGS_MASKALL; @@ -341,7 +342,6 @@ static int msi_capability_init(struct pci_dev *dev) } entry->irq = irq; list_add(&entry->list, &dev->msi_list); - dev->first_msi_irq = irq; set_irq_msi(irq, entry); /* Set MSI enabled bits */ @@ -433,7 +433,6 @@ static int msix_capability_init(struct pci_dev *dev, avail = -EBUSY; return avail; } - dev->first_msi_irq = entries[0].vector; /* Set MSI-X enabled bits */ pci_intx(dev, 0); /* disable intx */ msix_set_enable(dev, 1); @@ -461,6 +460,14 @@ static int pci_msi_check_device(struct pci_dev* dev, int nvec, int type) if (!pci_msi_enable || !dev || dev->no_msi) return -EINVAL; + /* + * You can't ask to have 0 or less MSIs configured. + * a) it's stupid .. + * b) the list manipulation code assumes nvec >= 1. + */ + if (nvec < 1) + return -ERANGE; + /* Any bridge which does NOT route MSI transactions from it's * secondary bus to it's primary bus must set NO_MSI flag on * the secondary pci_bus. @@ -525,18 +532,17 @@ void pci_disable_msi(struct pci_dev* dev) pci_intx(dev, 1); /* enable intx */ dev->msi_enabled = 0; - entry = get_irq_msi(dev->first_msi_irq); - if (!entry || !entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { + BUG_ON(list_empty(&dev->msi_list)); + entry = list_entry(dev->msi_list.next, struct msi_desc, list); + if (!entry->dev || entry->msi_attrib.type != PCI_CAP_ID_MSI) { return; } default_irq = entry->msi_attrib.default_irq; - msi_free_irq(dev, dev->first_msi_irq); + msi_free_irq(dev, entry->irq); /* Restore dev->irq to its default pin-assertion irq */ dev->irq = default_irq; - - dev->first_msi_irq = 0; } EXPORT_SYMBOL(pci_disable_msi); @@ -634,7 +640,6 @@ static void msix_free_all_irqs(struct pci_dev *dev) list_for_each_entry(entry, &dev->msi_list, list) msi_free_irq(dev, entry->irq); - dev->first_msi_irq = 0; } void pci_disable_msix(struct pci_dev* dev) @@ -664,8 +669,12 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) if (!pci_msi_enable || !dev) return; - if (dev->msi_enabled) - msi_free_irq(dev, dev->first_msi_irq); + if (dev->msi_enabled) { + struct msi_desc *entry; + BUG_ON(list_empty(&dev->msi_list)); + entry = list_entry(dev->msi_list.next, struct msi_desc, list); + msi_free_irq(dev, entry->irq); + } if (dev->msix_enabled) msix_free_all_irqs(dev); diff --git a/include/linux/pci.h b/include/linux/pci.h index d43097d..a15569b 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -189,7 +189,6 @@ struct pci_dev { int rom_attr_enabled; /* has display of the rom attribute been enabled? */ struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */ #ifdef CONFIG_PCI_MSI - unsigned int first_msi_irq; struct list_head msi_list; #endif }; -- cgit v0.10.2 From f282b97021ddc95c6092b9016f667c0963858fb1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 18 Apr 2007 18:46:20 +1000 Subject: msi: introduce ARCH_SUPPORTS_MSI Kconfig option (rev2) Allows architectures to advertise that they support MSI rather than listing each architecture as a PCI_MSI dependency. Signed-off-by: Dan Williams Acked-by: "Eric W. Biederman" Signed-off-by: Greg Kroah-Hartman diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e7baca2..db00376 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -255,6 +255,7 @@ config ARCH_IOP13XX depends on MMU select PLAT_IOP select PCI + select ARCH_SUPPORTS_MSI help Support for Intel's IOP13XX (XScale) family of processors. diff --git a/arch/i386/Kconfig b/arch/i386/Kconfig index 53d6237..bcf2fc4 100644 --- a/arch/i386/Kconfig +++ b/arch/i386/Kconfig @@ -1073,6 +1073,7 @@ config PCI bool "PCI support" if !X86_VISWS depends on !X86_VOYAGER default y if X86_VISWS + select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index e19185d..3b71f97 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig @@ -14,6 +14,7 @@ config IA64 select PCI if (!IA64_HP_SIM) select ACPI if (!IA64_HP_SIM) select PM if (!IA64_HP_SIM) + select ARCH_SUPPORTS_MSI default y help The Itanium Processor Family is Intel's 64-bit successor to diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig index 590a41b..be9e10b 100644 --- a/arch/sparc64/Kconfig +++ b/arch/sparc64/Kconfig @@ -306,6 +306,7 @@ config SUN_IO config PCI bool "PCI support" + select ARCH_SUPPORTS_MSI help Find out whether you have a PCI motherboard. PCI is the name of a bus system, i.e. the way the CPU talks to the other stuff inside diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig index 56eb14c..e9b4f05 100644 --- a/arch/x86_64/Kconfig +++ b/arch/x86_64/Kconfig @@ -676,6 +676,7 @@ menu "Bus options (PCI etc.)" config PCI bool "PCI support" + select ARCH_SUPPORTS_MSI if (X86_LOCAL_APIC && X86_IO_APIC) # x86-64 doesn't support PCI BIOS access from long mode so always go direct. config PCI_DIRECT diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 5ea5bc7..70efe8f 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -1,10 +1,14 @@ # # PCI configuration # +config ARCH_SUPPORTS_MSI + bool + default n + config PCI_MSI bool "Message Signaled Interrupts (MSI and MSI-X)" depends on PCI - depends on (X86_LOCAL_APIC && X86_IO_APIC) || IA64 || SPARC64 + depends on ARCH_SUPPORTS_MSI help This allows device drivers to enable MSI (Message Signaled Interrupts). Message Signaled Interrupts enable a device to -- cgit v0.10.2 From 7fe3730de729b758e9f69b862b9255d998671b5f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 18 Apr 2007 19:39:21 +1000 Subject: MSI: arch must connect the irq and the msi_desc set_irq_msi() currently connects an irq_desc to an msi_desc. The archs call it at some point in their setup routine, and then the generic code sets up the reverse mapping from the msi_desc back to the irq. set_irq_msi() should do both connections, making it the one and only call required to connect an irq with it's MSI desc and vice versa. The arch code MUST call set_irq_msi(), and it must do so only once it's sure it's not going to fail the irq allocation. Given that there's no need for the arch to return the irq anymore, the return value from the arch setup routine just becomes 0 for success and anything else for failure. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/arch/i386/kernel/io_apic.c b/arch/i386/kernel/io_apic.c index b3ab8ff..89d85d2 100644 --- a/arch/i386/kernel/io_apic.c +++ b/arch/i386/kernel/io_apic.c @@ -2611,19 +2611,19 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) if (irq < 0) return irq; - set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); if (ret < 0) { destroy_irq(irq); return ret; } + set_irq_msi(irq, desc); write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return irq; + return 0; } void arch_teardown_msi_irq(unsigned int irq) diff --git a/arch/ia64/sn/kernel/msi_sn.c b/arch/ia64/sn/kernel/msi_sn.c index 49873aa..83f190f 100644 --- a/arch/ia64/sn/kernel/msi_sn.c +++ b/arch/ia64/sn/kernel/msi_sn.c @@ -87,7 +87,6 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) if (irq < 0) return irq; - set_irq_msi(irq, entry); /* * Set up the vector plumbing. Let the prom (via sn_intr_alloc) * decide which cpu to direct this msi at by default. @@ -144,10 +143,11 @@ int sn_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *entry) */ msg.data = 0x100 + irq; + set_irq_msi(irq, entry); write_msi_msg(irq, &msg); set_irq_chip_and_handler(irq, &sn_msi_chip, handle_edge_irq); - return irq; + return 0; } #ifdef CONFIG_SMP diff --git a/arch/sparc64/kernel/pci.c b/arch/sparc64/kernel/pci.c index 023af41..9a54954 100644 --- a/arch/sparc64/kernel/pci.c +++ b/arch/sparc64/kernel/pci.c @@ -1092,10 +1092,10 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc) return -EINVAL; err = p->setup_msi_irq(&virt_irq, pdev, desc); - if (err < 0) + if (err) return err; - return virt_irq; + return 0; } void arch_teardown_msi_irq(unsigned int virt_irq) diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c index 94295c2..1ccf4c9 100644 --- a/arch/sparc64/kernel/pci_sun4v.c +++ b/arch/sparc64/kernel/pci_sun4v.c @@ -1169,8 +1169,6 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, if (!devino) goto out_err; - set_irq_msi(*virt_irq_p, entry); - msiqid = ((devino - pbm->msiq_first_devino) + pbm->msiq_first); @@ -1204,6 +1202,8 @@ static int pci_sun4v_setup_msi_irq(unsigned int *virt_irq_p, msg.address_lo = pbm->msi32_start; } msg.data = msi_num; + + set_irq_msi(*virt_irq_p, entry); write_msi_msg(*virt_irq_p, &msg); irq_install_pre_handler(*virt_irq_p, diff --git a/arch/x86_64/kernel/io_apic.c b/arch/x86_64/kernel/io_apic.c index c6a5bc7..b7d2b76 100644 --- a/arch/x86_64/kernel/io_apic.c +++ b/arch/x86_64/kernel/io_apic.c @@ -1983,18 +1983,18 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc) if (irq < 0) return irq; - set_irq_msi(irq, desc); ret = msi_compose_msg(dev, irq, &msg); if (ret < 0) { destroy_irq(irq); return ret; } + set_irq_msi(irq, desc); write_msi_msg(irq, &msg); set_irq_chip_and_handler_name(irq, &msi_chip, handle_edge_irq, "edge"); - return irq; + return 0; } void arch_teardown_msi_irq(unsigned int irq) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 7a44ba4..88362f1 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -297,7 +297,7 @@ void pci_restore_msi_state(struct pci_dev *dev) static int msi_capability_init(struct pci_dev *dev) { struct msi_desc *entry; - int pos, irq; + int pos, ret; u16 control; msi_set_enable(dev, 0); /* Ensure msi is disabled as I set it up */ @@ -335,21 +335,19 @@ static int msi_capability_init(struct pci_dev *dev) maskbits); } /* Configure MSI capability structure */ - irq = arch_setup_msi_irq(dev, entry); - if (irq < 0) { + ret = arch_setup_msi_irq(dev, entry); + if (ret) { kfree(entry); - return irq; + return ret; } - entry->irq = irq; list_add(&entry->list, &dev->msi_list); - set_irq_msi(irq, entry); /* Set MSI enabled bits */ pci_intx(dev, 0); /* disable intx */ msi_set_enable(dev, 1); dev->msi_enabled = 1; - dev->irq = irq; + dev->irq = entry->irq; return 0; } @@ -367,7 +365,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { struct msi_desc *entry; - int irq, pos, i, j, nr_entries; + int irq, pos, i, j, nr_entries, ret; unsigned long phys_addr; u32 table_offset; u16 control; @@ -407,16 +405,13 @@ static int msix_capability_init(struct pci_dev *dev, entry->mask_base = base; /* Configure MSI-X capability structure */ - irq = arch_setup_msi_irq(dev, entry); - if (irq < 0) { + ret = arch_setup_msi_irq(dev, entry); + if (ret) { kfree(entry); break; } - entry->irq = irq; - entries[i].vector = irq; + entries[i].vector = entry->irq; list_add(&entry->list, &dev->msi_list); - - set_irq_msi(irq, entry); } if (i != nvec) { int avail = i - 1; diff --git a/kernel/irq/chip.c b/kernel/irq/chip.c index 0133f4f..615ce97 100644 --- a/kernel/irq/chip.c +++ b/kernel/irq/chip.c @@ -11,6 +11,7 @@ */ #include +#include #include #include #include @@ -185,6 +186,8 @@ int set_irq_msi(unsigned int irq, struct msi_desc *entry) desc = irq_desc + irq; spin_lock_irqsave(&desc->lock, flags); desc->msi_desc = entry; + if (entry) + entry->irq = irq; spin_unlock_irqrestore(&desc->lock, flags); return 0; } -- cgit v0.10.2 From 9c8313343c83c0ca731ceb8d2a4ab1e022ed9c94 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 18 Apr 2007 19:39:21 +1000 Subject: MSI: Give archs the option to allocate all MSI/Xs at once. This patch introduces an optional function, arch_setup_msi_irqs(), (note the plural) which gives an arch the opportunity to do per-device setup for MSI/X and then allocate all the requested MSI/Xs at once. If that's not required by the arch, the default version simply calls arch_setup_msi_irq() for each MSI irq required. arch_setup_msi_irqs() is passed a pdev, attached to the pdev is a list of msi_descs with irq == 0, it is up to the arch to connect these up to an irq (via set_irq_msi()) or return an error. For convenience the number of vectors and the type are passed also. All msi_descs with irq != 0 are considered allocated, and the arch teardown routine will be called on them when necessary. The existing semantics of pci_enable_msix() are that if the requested number of irqs can not be allocated, the maximum number that _could_ be allocated is returned. To support that, we define that in case of an error from arch_setup_msi_irqs(), the number of msi_descs with irq != 0 are considered allocated, and are counted toward the "max that could be allocated". Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 88362f1..c71e8e4 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -334,13 +334,15 @@ static int msi_capability_init(struct pci_dev *dev) msi_mask_bits_reg(pos, is_64bit_address(control)), maskbits); } + list_add(&entry->list, &dev->msi_list); + /* Configure MSI capability structure */ - ret = arch_setup_msi_irq(dev, entry); + ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI); if (ret) { + list_del(&entry->list); kfree(entry); return ret; } - list_add(&entry->list, &dev->msi_list); /* Set MSI enabled bits */ pci_intx(dev, 0); /* disable intx */ @@ -365,7 +367,7 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries, int nvec) { struct msi_desc *entry; - int irq, pos, i, j, nr_entries, ret; + int pos, i, j, nr_entries, ret; unsigned long phys_addr; u32 table_offset; u16 control; @@ -404,30 +406,33 @@ static int msix_capability_init(struct pci_dev *dev, entry->dev = dev; entry->mask_base = base; - /* Configure MSI-X capability structure */ - ret = arch_setup_msi_irq(dev, entry); - if (ret) { - kfree(entry); - break; - } - entries[i].vector = entry->irq; list_add(&entry->list, &dev->msi_list); } - if (i != nvec) { - int avail = i - 1; - i--; - for (; i >= 0; i--) { - irq = (entries + i)->vector; - msi_free_irq(dev, irq); - (entries + i)->vector = 0; + + ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX); + if (ret) { + int avail = 0; + list_for_each_entry(entry, &dev->msi_list, list) { + if (entry->irq != 0) { + avail++; + msi_free_irq(dev, entry->irq); + } } + /* If we had some success report the number of irqs * we succeeded in setting up. */ - if (avail <= 0) - avail = -EBUSY; + if (avail == 0) + avail = ret; return avail; } + + i = 0; + list_for_each_entry(entry, &dev->msi_list, list) { + entries[i].vector = entry->irq; + set_irq_msi(entry->irq, entry); + i++; + } /* Set MSI-X enabled bits */ pci_intx(dev, 0); /* disable intx */ msix_set_enable(dev, 1); @@ -694,3 +699,23 @@ arch_msi_check_device(struct pci_dev* dev, int nvec, int type) return 0; } +int __attribute__ ((weak)) +arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *entry) +{ + return 0; +} + +int __attribute__ ((weak)) +arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) +{ + struct msi_desc *entry; + int ret; + + list_for_each_entry(entry, &dev->msi_list, list) { + ret = arch_setup_msi_irq(dev, entry); + if (ret) + return ret; + } + + return 0; +} diff --git a/include/linux/msi.h b/include/linux/msi.h index 931e013..494627a 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -41,6 +41,7 @@ struct msi_desc { */ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); +extern int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); extern int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); -- cgit v0.10.2 From 032de8e2fe3c0eec5fb0ffe4d38aa602dad397dc Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 18 Apr 2007 19:39:22 +1000 Subject: MSI: Give archs the option to free all MSI/Xs at once. This patch introduces an optional function, arch_teardown_msi_irqs(), which gives an arch the opportunity to do per-device teardown for MSI/X. If that's not required, the default version simply calls arch_teardown_msi_irq() for each msi irq required. arch_teardown_msi_irqs() is simply passed a pdev, attached to the pdev is a list of msi_descs, it is up to the arch to free the irq associated with each of these as appropriate. For archs that _don't_ implement arch_teardown_msi_irqs(), all msi_descs with irq == 0 are considered unallocated, and the arch teardown routine is not called on them. Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index c71e8e4..9e1321d 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -207,7 +207,7 @@ void unmask_msi_irq(unsigned int irq) msix_flush_writes(irq); } -static int msi_free_irq(struct pci_dev* dev, int irq); +static int msi_free_irqs(struct pci_dev* dev); static struct msi_desc* alloc_msi_entry(void) @@ -339,8 +339,7 @@ static int msi_capability_init(struct pci_dev *dev) /* Configure MSI capability structure */ ret = arch_setup_msi_irqs(dev, 1, PCI_CAP_ID_MSI); if (ret) { - list_del(&entry->list); - kfree(entry); + msi_free_irqs(dev); return ret; } @@ -415,10 +414,11 @@ static int msix_capability_init(struct pci_dev *dev, list_for_each_entry(entry, &dev->msi_list, list) { if (entry->irq != 0) { avail++; - msi_free_irq(dev, entry->irq); } } + msi_free_irqs(dev); + /* If we had some success report the number of irqs * we succeeded in setting up. */ @@ -539,39 +539,33 @@ void pci_disable_msi(struct pci_dev* dev) } default_irq = entry->msi_attrib.default_irq; - msi_free_irq(dev, entry->irq); + msi_free_irqs(dev); /* Restore dev->irq to its default pin-assertion irq */ dev->irq = default_irq; } EXPORT_SYMBOL(pci_disable_msi); -static int msi_free_irq(struct pci_dev* dev, int irq) +static int msi_free_irqs(struct pci_dev* dev) { - struct msi_desc *entry; - int entry_nr, type; - void __iomem *base; - - BUG_ON(irq_has_action(irq)); + struct msi_desc *entry, *tmp; - entry = get_irq_msi(irq); - if (!entry || entry->dev != dev) { - return -EINVAL; - } - type = entry->msi_attrib.type; - entry_nr = entry->msi_attrib.entry_nr; - base = entry->mask_base; - list_del(&entry->list); + list_for_each_entry(entry, &dev->msi_list, list) + BUG_ON(irq_has_action(entry->irq)); - arch_teardown_msi_irq(irq); - kfree(entry); + arch_teardown_msi_irqs(dev); - if (type == PCI_CAP_ID_MSIX) { - writel(1, base + entry_nr * PCI_MSIX_ENTRY_SIZE + - PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); + list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) { + if (entry->msi_attrib.type == PCI_CAP_ID_MSIX) { + if (list_is_last(&entry->list, &dev->msi_list)) + iounmap(entry->mask_base); - if (list_empty(&dev->msi_list)) - iounmap(base); + writel(1, entry->mask_base + entry->msi_attrib.entry_nr + * PCI_MSIX_ENTRY_SIZE + + PCI_MSIX_ENTRY_VECTOR_CTRL_OFFSET); + } + list_del(&entry->list); + kfree(entry); } return 0; @@ -636,10 +630,7 @@ EXPORT_SYMBOL(pci_enable_msix); static void msix_free_all_irqs(struct pci_dev *dev) { - struct msi_desc *entry; - - list_for_each_entry(entry, &dev->msi_list, list) - msi_free_irq(dev, entry->irq); + msi_free_irqs(dev); } void pci_disable_msix(struct pci_dev* dev) @@ -669,12 +660,8 @@ void msi_remove_pci_irq_vectors(struct pci_dev* dev) if (!pci_msi_enable || !dev) return; - if (dev->msi_enabled) { - struct msi_desc *entry; - BUG_ON(list_empty(&dev->msi_list)); - entry = list_entry(dev->msi_list.next, struct msi_desc, list); - msi_free_irq(dev, entry->irq); - } + if (dev->msi_enabled) + msi_free_irqs(dev); if (dev->msix_enabled) msix_free_all_irqs(dev); @@ -719,3 +706,19 @@ arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type) return 0; } + +void __attribute__ ((weak)) arch_teardown_msi_irq(unsigned int irq) +{ + return; +} + +void __attribute__ ((weak)) +arch_teardown_msi_irqs(struct pci_dev *dev) +{ + struct msi_desc *entry; + + list_for_each_entry(entry, &dev->msi_list, list) { + if (entry->irq != 0) + arch_teardown_msi_irq(entry->irq); + } +} diff --git a/include/linux/msi.h b/include/linux/msi.h index 494627a..94bb46d 100644 --- a/include/linux/msi.h +++ b/include/linux/msi.h @@ -42,6 +42,7 @@ struct msi_desc { int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc); void arch_teardown_msi_irq(unsigned int irq); extern int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type); +extern void arch_teardown_msi_irqs(struct pci_dev *dev); extern int arch_msi_check_device(struct pci_dev* dev, int nvec, int type); -- cgit v0.10.2 From 5adc55da4a7758021bcc374904b0f8b076508a11 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Tue, 27 Mar 2007 03:02:51 +0200 Subject: PCI: remove the broken PCI_MULTITHREAD_PROBE option This patch removes the PCI_MULTITHREAD_PROBE option that had already been marked as broken. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/pci.txt b/Documentation/pci.txt index a8ded1a..40c4717 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt @@ -124,10 +124,6 @@ initialization with a pointer to a structure describing the driver err_handler See Documentation/pci-error-recovery.txt - multithread_probe Enable multi-threaded probe/scan. Driver must - provide its own locking/syncronization for init - operations if this is enabled. - The ID table is an array of struct pci_device_id entries ending with an all-zero entry. Each entry consists of: diff --git a/drivers/base/dd.c b/drivers/base/dd.c index 18dba8e..92428e5 100644 --- a/drivers/base/dd.c +++ b/drivers/base/dd.c @@ -226,12 +226,10 @@ static int device_probe_drivers(void *data) * * Walk the list of drivers that the bus has and call * driver_probe_device() for each pair. If a compatible - * pair is found, break out and return. If the bus specifies - * multithreaded probing, walking the list of drivers is done - * on a probing thread. + * pair is found, break out and return. * * Returns 1 if the device was bound to a driver; - * 0 if no matching device was found or multithreaded probing is done; + * 0 if no matching device was found; * -ENODEV if the device is not registered. * * When called for a USB interface, @dev->parent->sem must be held. @@ -239,7 +237,6 @@ static int device_probe_drivers(void *data) int device_attach(struct device * dev) { int ret = 0; - struct task_struct *probe_task = ERR_PTR(-ENOMEM); down(&dev->sem); if (dev->driver) { @@ -251,12 +248,7 @@ int device_attach(struct device * dev) ret = 0; } } else { - if (dev->bus->multithread_probe) - probe_task = kthread_run(device_probe_drivers, dev, - "probe-%s", dev->bus_id); - if(IS_ERR(probe_task)) - ret = bus_for_each_drv(dev->bus, NULL, dev, - __device_attach); + ret = bus_for_each_drv(dev->bus, NULL, dev, __device_attach); } up(&dev->sem); return ret; @@ -383,33 +375,6 @@ void driver_detach(struct device_driver * drv) } } -#ifdef CONFIG_PCI_MULTITHREAD_PROBE -static int __init wait_for_probes(void) -{ - DEFINE_WAIT(wait); - - printk(KERN_INFO "%s: waiting for %d threads\n", __FUNCTION__, - atomic_read(&probe_count)); - if (!atomic_read(&probe_count)) - return 0; - while (atomic_read(&probe_count)) { - prepare_to_wait(&probe_waitqueue, &wait, TASK_UNINTERRUPTIBLE); - if (atomic_read(&probe_count)) - schedule(); - } - finish_wait(&probe_waitqueue, &wait); - return 0; -} - -core_initcall_sync(wait_for_probes); -postcore_initcall_sync(wait_for_probes); -arch_initcall_sync(wait_for_probes); -subsys_initcall_sync(wait_for_probes); -fs_initcall_sync(wait_for_probes); -device_initcall_sync(wait_for_probes); -late_initcall_sync(wait_for_probes); -#endif - EXPORT_SYMBOL_GPL(device_bind_driver); EXPORT_SYMBOL_GPL(device_release_driver); EXPORT_SYMBOL_GPL(device_attach); diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 70efe8f..7a1d6d5 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -21,31 +21,6 @@ config PCI_MSI If you don't know what to do here, say N. -config PCI_MULTITHREAD_PROBE - bool "PCI Multi-threaded probe (EXPERIMENTAL)" - depends on PCI && EXPERIMENTAL && BROKEN - help - Say Y here if you want the PCI core to spawn a new thread for - every PCI device that is probed. This can cause a huge - speedup in boot times on multiprocessor machines, and even a - smaller speedup on single processor machines. - - But it can also cause lots of bad things to happen. A number - of PCI drivers cannot properly handle running in this way, - some will just not work properly at all, while others might - decide to blow up power supplies with a huge load all at once, - so use this option at your own risk. - - It is very unwise to use this option if you are not using a - boot process that can handle devices being created in any - order. A program that can create persistent block and network - device names (like udev) is a good idea if you wish to use - this option. - - Again, use this option at your own risk, you have been warned! - - When in doubt, say N. - config PCI_DEBUG bool "PCI Debugging" depends on PCI && DEBUG_KERNEL diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 07fdb3c..3bb7739 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c @@ -14,20 +14,6 @@ #include "pci.h" /* - * Registration of PCI drivers and handling of hot-pluggable devices. - */ - -/* multithreaded probe logic */ -static int pci_multithread_probe = -#ifdef CONFIG_PCI_MULTITHREAD_PROBE - 1; -#else - 0; -#endif -__module_param_call("", pci_multithread_probe, param_set_bool, param_get_bool, &pci_multithread_probe, 0644); - - -/* * Dynamic device IDs are disabled for !CONFIG_HOTPLUG */ @@ -569,7 +555,6 @@ struct bus_type pci_bus_type = { static int __init pci_driver_init(void) { - pci_bus_type.multithread_probe = pci_multithread_probe; return bus_register(&pci_bus_type); } diff --git a/include/linux/device.h b/include/linux/device.h index a0cd2ce..ff83b61 100644 --- a/include/linux/device.h +++ b/include/linux/device.h @@ -80,7 +80,6 @@ struct bus_type { int (*resume)(struct device * dev); unsigned int drivers_autoprobe:1; - unsigned int multithread_probe:1; }; extern int __must_check bus_register(struct bus_type * bus); -- cgit v0.10.2 From ecf36501bc4ad399e6df2e0bdaa513a2d510b7ec Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Fri, 6 Apr 2007 12:19:48 +0200 Subject: PCI: the overdue removal of pci_module_init() Unless we finally completely remove it, people will always add new users. Signed-off-by: Adrian Bunk Signed-off-by: Greg Kroah-Hartman diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt index 5c88ba1..144058c 100644 --- a/Documentation/feature-removal-schedule.txt +++ b/Documentation/feature-removal-schedule.txt @@ -117,13 +117,6 @@ Who: Adrian Bunk --------------------------- -What: pci_module_init(driver) -When: January 2007 -Why: Is replaced by pci_register_driver(pci_driver). -Who: Richard Knutsson and Greg Kroah-Hartman - ---------------------------- - What: Usage of invalid timevals in setitimer When: March 2007 Why: POSIX requires to validate timevals in the setitimer call. This diff --git a/Documentation/pci.txt b/Documentation/pci.txt index 40c4717..e2c9d0a 100644 --- a/Documentation/pci.txt +++ b/Documentation/pci.txt @@ -545,8 +545,6 @@ pci_find_slot() Find pci_dev corresponding to given bus and pci_set_power_state() Set PCI Power Management state (0=D0 ... 3=D3) pci_find_capability() Find specified capability in device's capability list. -pci_module_init() Inline helper function for ensuring correct - pci_driver initialization and error handling. pci_resource_start() Returns bus start address for a given PCI region pci_resource_end() Returns bus end address for a given PCI region pci_resource_len() Returns the byte length of a PCI region diff --git a/include/linux/pci.h b/include/linux/pci.h index a15569b..fbf3766 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -407,12 +407,6 @@ struct pci_driver { .vendor = PCI_ANY_ID, .device = PCI_ANY_ID, \ .subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID -/* - * pci_module_init is obsolete, this stays here till we fix up all usages of it - * in the tree. - */ -#define pci_module_init pci_register_driver - /** * PCI_VDEVICE - macro used to describe a specific pci device in short form * @vend: the vendor name -- cgit v0.10.2 From f14e3136509e3825a83f6689cb709f41dfacea47 Mon Sep 17 00:00:00 2001 From: Chuck Ebbert Date: Tue, 10 Apr 2007 10:25:44 -0400 Subject: PCI: add debug information to resource collision message Add more information to PCI resource collision message to help with debugging. Signed-off-by: Chuck Ebbert Signed-off-by: Greg Kroah-Hartman diff --git a/arch/i386/pci/i386.c b/arch/i386/pci/i386.c index 43005f0..bcd2f94 100644 --- a/arch/i386/pci/i386.c +++ b/arch/i386/pci/i386.c @@ -246,8 +246,8 @@ int pcibios_enable_resources(struct pci_dev *dev, int mask) continue; if (!r->start && r->end) { printk(KERN_ERR "PCI: Device %s not available " - "because of resource collisions\n", - pci_name(dev)); + "because of resource %d collisions\n", + pci_name(dev), idx); return -EINVAL; } if (r->flags & IORESOURCE_IO) -- cgit v0.10.2 From bf8cbae47559170d2f2947dd547492714f195dd3 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:07 -0700 Subject: PCI: rpaphp: Cleanup flow of control for rpaphp_add_slot Cleanup the flow of control for rpaphp_add_slot(), so as to make it easier to read. The ext patch will fix a bug in this same code. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 71a2cb8..f6c05f3 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -299,32 +299,32 @@ int rpaphp_add_slot(struct device_node *dn) const int *indexes, *names, *types, *power_domains; char *name, *type; + if (!dn->name || strcmp(dn->name, "pci")) + return 0; + + if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) + return 0; + dbg("Entry %s: dn->full_name=%s\n", __FUNCTION__, dn->full_name); /* register PCI devices */ - if (dn->name != 0 && strcmp(dn->name, "pci") == 0) { - if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) - goto exit; - - name = (char *) &names[1]; - type = (char *) &types[1]; - for (i = 0; i < indexes[0]; i++, - name += (strlen(name) + 1), type += (strlen(type) + 1)) { - - if (!(slot = alloc_slot_struct(dn, indexes[i + 1], name, - power_domains[i + 1]))) { - retval = -ENOMEM; - goto exit; - } - slot->type = simple_strtoul(type, NULL, 10); + name = (char *) &names[1]; + type = (char *) &types[1]; + for (i = 0; i < indexes[0]; i++) { + + slot = alloc_slot_struct(dn, indexes[i + 1], name, power_domains[i + 1]); + if (!slot) + return -ENOMEM; + + slot->type = simple_strtoul(type, NULL, 10); - dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", - indexes[i + 1], name, type); + dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", + indexes[i + 1], name, type); - retval = rpaphp_register_pci_slot(slot); - } + retval = rpaphp_register_pci_slot(slot); + name += strlen(name) + 1; + type += strlen(type) + 1; } -exit: dbg("%s - Exit: num_slots=%d rc[%d]\n", __FUNCTION__, num_slots, retval); return retval; -- cgit v0.10.2 From fa1891596ca252e48e8803738fd8ead5b3082217 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:08 -0700 Subject: PCI: rpaphp: Remove global num_slots variable Cleanup cruft: remove the global "num_slots" variable; although scattered across multiple files, it is used only once, in a debug statement. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 2e7accf..2ccbe8d 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -83,7 +83,6 @@ struct slot { extern struct hotplug_slot_ops rpaphp_hotplug_slot_ops; extern struct list_head rpaphp_slot_head; -extern int num_slots; /* function prototypes */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index f6c05f3..3afd154 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -41,7 +41,6 @@ int debug; static struct semaphore rpaphp_sem; LIST_HEAD(rpaphp_slot_head); -int num_slots; #define DRIVER_VERSION "0.1" #define DRIVER_AUTHOR "Linda Xie " @@ -325,8 +324,7 @@ int rpaphp_add_slot(struct device_node *dn) name += strlen(name) + 1; type += strlen(type) + 1; } - dbg("%s - Exit: num_slots=%d rc[%d]\n", - __FUNCTION__, num_slots, retval); + dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; } diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 3009193..907f130 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -140,8 +140,6 @@ int rpaphp_deregister_slot(struct slot *slot) retval = pci_hp_deregister(php_slot); if (retval) err("Problem unregistering a slot %s\n", slot->name); - else - num_slots--; dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); return retval; @@ -181,7 +179,6 @@ int rpaphp_register_slot(struct slot *slot) list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head); info("Slot [%s](PCI location=%s) registered\n", slot->name, slot->location); - num_slots++; return 0; sysfs_fail: -- cgit v0.10.2 From 31be7586d1122538747519d786408f142f59dd46 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:09 -0700 Subject: PCI: rpaphp: match up alloc and free in same routine The routine that called an alloc should be the same routine that calles the mathcing free, if anything in the middle failed. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 3afd154..ca95e151 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -321,10 +321,15 @@ int rpaphp_add_slot(struct device_node *dn) indexes[i + 1], name, type); retval = rpaphp_register_pci_slot(slot); + if (retval) + dealloc_slot_struct(slot); + name += strlen(name) + 1; type += strlen(type) + 1; } dbg("%s - Exit: rc[%d]\n", __FUNCTION__, retval); + + /* XXX FIXME: reports a failure only if last entry in loop failed */ return retval; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 6f6cbed..a669ba3 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -195,7 +195,6 @@ static int setup_pci_slot(struct slot *slot) } return 0; exit_rc: - dealloc_slot_struct(slot); return -EINVAL; } diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 907f130..dd1e275 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -184,7 +184,6 @@ int rpaphp_register_slot(struct slot *slot) sysfs_fail: pci_hp_deregister(php_slot); register_fail: - rpaphp_release_slot(php_slot); return retval; } -- cgit v0.10.2 From 5fd39c35a016150e93b68c472a04b2d4b5574a2b Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:10 -0700 Subject: PCI: rpaphp: Fix a memleak; slot->location string was never freed Fix a memleak; the slot->location string was never freed. Fix some whitespace and overlong-line probelms while we're here. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index dd1e275..865b0b7 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -56,7 +56,6 @@ static struct hotplug_slot_attribute php_attr_location = { static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot) { struct slot *slot = (struct slot *) hotplug_slot->private; - dealloc_slot_struct(slot); } @@ -65,12 +64,12 @@ void dealloc_slot_struct(struct slot *slot) kfree(slot->hotplug_slot->info); kfree(slot->hotplug_slot->name); kfree(slot->hotplug_slot); + kfree(slot->location); kfree(slot); - return; } -struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, - int power_domain) +struct slot *alloc_slot_struct(struct device_node *dn, + int drc_index, char *drc_name, int power_domain) { struct slot *slot; @@ -115,7 +114,7 @@ error_nomem: static int is_registered(struct slot *slot) { - struct slot *tmp_slot; + struct slot *tmp_slot; list_for_each_entry(tmp_slot, &rpaphp_slot_head, rpaphp_slot_list) { if (!strcmp(tmp_slot->name, slot->name)) -- cgit v0.10.2 From 3499f0726ec179afd19669070681ac457d27033f Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:11 -0700 Subject: PCI: rpaphp: Remove un-needed goto Remove un-needed goto. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 865b0b7..9b94007 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -157,14 +157,13 @@ int rpaphp_register_slot(struct slot *slot) /* should not try to register the same slot twice */ if (is_registered(slot)) { err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name); - retval = -EAGAIN; - goto register_fail; + return -EAGAIN; } retval = pci_hp_register(php_slot); if (retval) { err("pci_hp_register failed with error %d\n", retval); - goto register_fail; + return retval; } /* create "phy_location" file */ @@ -182,7 +181,6 @@ int rpaphp_register_slot(struct slot *slot) sysfs_fail: pci_hp_deregister(php_slot); -register_fail: return retval; } -- cgit v0.10.2 From 517d5a0417e19101eaa769039d1921d626ee546c Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:12 -0700 Subject: PCI: rpaphp: remove a function that does nothing but wrap debug printks Remove a stove-pipe-- a function that is called from only one place, does nothing but wraps another function with debug printk's. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index a669ba3..881e807 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -116,23 +116,6 @@ static void print_slot_pci_funcs(struct pci_bus *bus) return; } -static int setup_pci_hotplug_slot_info(struct slot *slot) -{ - struct hotplug_slot_info *hotplug_slot_info = slot->hotplug_slot->info; - - dbg("%s Initilize the PCI slot's hotplug->info structure ...\n", - __FUNCTION__); - rpaphp_get_power_status(slot, &hotplug_slot_info->power_status); - rpaphp_get_pci_adapter_status(slot, 1, - &hotplug_slot_info->adapter_status); - if (hotplug_slot_info->adapter_status == NOT_VALID) { - err("%s: NOT_VALID: skip dn->full_name=%s\n", - __FUNCTION__, slot->dn->full_name); - return -EINVAL; - } - return 0; -} - static void set_slot_name(struct slot *slot) { struct pci_bus *bus = slot->bus; @@ -200,14 +183,20 @@ exit_rc: int rpaphp_register_pci_slot(struct slot *slot) { - int rc = -EINVAL; + struct hotplug_slot_info *info = slot->hotplug_slot->info; + + rpaphp_get_power_status(slot, &info->power_status); + rpaphp_get_pci_adapter_status(slot, 1, &info->adapter_status); + + if (info->adapter_status == NOT_VALID) { + err("%s: NOT_VALID: skip dn->full_name=%s\n", + __FUNCTION__, slot->dn->full_name); + return -EINVAL; + } - if (setup_pci_hotplug_slot_info(slot)) - goto exit_rc; if (setup_pci_slot(slot)) - goto exit_rc; - rc = rpaphp_register_slot(slot); -exit_rc: - return rc; + return -EINVAL; + + return rpaphp_register_slot(slot); } -- cgit v0.10.2 From 427310ff02e80cc80826407c0121cec3694c9e7d Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:13 -0700 Subject: PCI: rpaphp: Remve another call that is a wrapper Remove another stovepipe: a call which wraps another call, and just adds printks. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index 2ccbe8d..fdd99b2 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -103,7 +103,6 @@ extern void dealloc_slot_struct(struct slot *slot); extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); extern int rpaphp_register_slot(struct slot *slot); extern int rpaphp_deregister_slot(struct slot *slot); -extern int rpaphp_get_power_status(struct slot *slot, u8 * value); extern int rpaphp_set_attention_status(struct slot *slot, u8 status); #endif /* _PPC64PHP_H */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index ca95e151..2d919fb 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -100,11 +100,13 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) */ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) { - int retval; + int retval, level; struct slot *slot = (struct slot *)hotplug_slot->private; down(&rpaphp_sem); - retval = rpaphp_get_power_status(slot, value); + retval = rtas_get_power_level (slot->power_domain, &level); + if (!retval) + *value = level; up(&rpaphp_sem); return retval; } diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 881e807..ba8c837 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -183,9 +183,14 @@ exit_rc: int rpaphp_register_pci_slot(struct slot *slot) { + int rc, level; struct hotplug_slot_info *info = slot->hotplug_slot->info; - rpaphp_get_power_status(slot, &info->power_status); + rc = rtas_get_power_level(slot->power_domain, &level); + if (rc) + return rc; + info->power_status = level; + rpaphp_get_pci_adapter_status(slot, 1, &info->adapter_status); if (info->adapter_status == NOT_VALID) { diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 9b94007..30c9dc9 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -184,24 +184,6 @@ sysfs_fail: return retval; } -int rpaphp_get_power_status(struct slot *slot, u8 * value) -{ - int rc = 0, level; - - rc = rtas_get_power_level(slot->power_domain, &level); - if (rc < 0) { - err("failed to get power-level for slot(%s), rc=0x%x\n", - slot->location, rc); - return rc; - } - - dbg("%s the power level of slot %s(pwd-domain:0x%x) is %d\n", - __FUNCTION__, slot->name, slot->power_domain, level); - *value = level; - - return rc; -} - int rpaphp_set_attention_status(struct slot *slot, u8 status) { int rc; -- cgit v0.10.2 From bf0af511fcc856649a2a39c627828695b580d124 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:14 -0700 Subject: PCI: rpaphp: Remove another wrappered function Remove another stove-pipe; this funcion was called from two different places, with a compile-time const that is then run-time checked to perform two different things. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index fdd99b2..a2b2257 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -89,7 +89,6 @@ extern struct list_head rpaphp_slot_head; /* rpaphp_pci.c */ extern int rpaphp_enable_pci_slot(struct slot *slot); extern int rpaphp_register_pci_slot(struct slot *slot); -extern int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value); extern int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 2d919fb..cab7cee 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -130,12 +130,22 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) { struct slot *slot = (struct slot *)hotplug_slot->private; - int retval = 0; + int rc, state; down(&rpaphp_sem); - retval = rpaphp_get_pci_adapter_status(slot, 0, value); + rc = rpaphp_get_sensor_state(slot, &state); up(&rpaphp_sem); - return retval; + + *value = NOT_VALID; + if (rc) + return rc; + + if (state == EMPTY) + *value = EMPTY; + else if (state == PRESENT) + *value = slot->state; + + return 0; } static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value) diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index ba8c837..b6a991a 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -64,43 +64,6 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state) return rc; } -/** - * get_pci_adapter_status - get the status of a slot - * - * 0-- slot is empty - * 1-- adapter is configured - * 2-- adapter is not configured - * 3-- not valid - */ -int rpaphp_get_pci_adapter_status(struct slot *slot, int is_init, u8 * value) -{ - struct pci_bus *bus; - int state, rc; - - *value = NOT_VALID; - rc = rpaphp_get_sensor_state(slot, &state); - if (rc) - goto exit; - - if (state == EMPTY) - *value = EMPTY; - else if (state == PRESENT) { - if (!is_init) { - /* at run-time slot->state can be changed by */ - /* config/unconfig adapter */ - *value = slot->state; - } else { - bus = pcibios_find_pci_bus(slot->dn); - if (bus && !list_empty(&bus->devices)) - *value = CONFIGURED; - else - *value = NOT_CONFIGURED; - } - } -exit: - return rc; -} - static void print_slot_pci_funcs(struct pci_bus *bus) { struct device_node *dn; @@ -183,20 +146,30 @@ exit_rc: int rpaphp_register_pci_slot(struct slot *slot) { - int rc, level; + int rc, level, state; + struct pci_bus *bus; struct hotplug_slot_info *info = slot->hotplug_slot->info; + /* Find out if the power is turned on for the slot */ rc = rtas_get_power_level(slot->power_domain, &level); if (rc) return rc; info->power_status = level; - rpaphp_get_pci_adapter_status(slot, 1, &info->adapter_status); + /* Figure out if there is an adapter in the slot */ + info->adapter_status = NOT_VALID; + rc = rpaphp_get_sensor_state(slot, &state); + if (rc) + return rc; - if (info->adapter_status == NOT_VALID) { - err("%s: NOT_VALID: skip dn->full_name=%s\n", - __FUNCTION__, slot->dn->full_name); - return -EINVAL; + if (state == EMPTY) + info->adapter_status = EMPTY; + else if (state == PRESENT) { + bus = pcibios_find_pci_bus(slot->dn); + if (bus && !list_empty(&bus->devices)) + info->adapter_status = CONFIGURED; + else + info->adapter_status = NOT_CONFIGURED; } if (setup_pci_slot(slot)) -- cgit v0.10.2 From ebf42c0edd5ee325043d4ae8fbb8caebd707e791 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:15 -0700 Subject: PCI: rpaphp: remove a call that does nothing but a pointer lookup Delete another stovepipe: a call to a routine which does nothing. Remove un-needed semaphore as well. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index cab7cee..3970cac 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -54,11 +54,6 @@ MODULE_LICENSE("GPL"); module_param(debug, bool, 0644); -static int rpaphp_get_attention_status(struct slot *slot) -{ - return slot->hotplug_slot->info->attention_status; -} - /** * set_attention_status - set attention LED * echo 0 > attention -- set LED OFF @@ -95,8 +90,6 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) * get_power_status - get power status of a slot * @hotplug_slot: slot to get status * @value: pointer to store status - * - * */ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) { @@ -113,18 +106,12 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) /** * get_attention_status - get attention LED status - * - * */ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 * value) { - int retval = 0; struct slot *slot = (struct slot *)hotplug_slot->private; - - down(&rpaphp_sem); - *value = rpaphp_get_attention_status(slot); - up(&rpaphp_sem); - return retval; + *value = slot->hotplug_slot->info->attention_status; + return 0; } static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) -- cgit v0.10.2 From 03a667559138d47cea487823332c4712fc6fbec7 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:16 -0700 Subject: PCI: rpaphp: Remove setup_pci_slot() The setup_pci_slot() routine appears to be nothing else than a big, complicated wrapper around pcibios_add_pci_devices(). Remove the wrapping, and call pcibios_add_pci_devices() directly. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index b6a991a..6417b70 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -92,64 +92,15 @@ static void set_slot_name(struct slot *slot) bus->number); } -static int setup_pci_slot(struct slot *slot) -{ - struct device_node *dn = slot->dn; - struct pci_bus *bus; - - BUG_ON(!dn); - bus = pcibios_find_pci_bus(dn); - if (!bus) { - err("%s: no pci_bus for dn %s\n", __FUNCTION__, dn->full_name); - goto exit_rc; - } - - slot->bus = bus; - slot->pci_devs = &bus->devices; - set_slot_name(slot); - - /* find slot's pci_dev if it's not empty */ - if (slot->hotplug_slot->info->adapter_status == EMPTY) { - slot->state = EMPTY; /* slot is empty */ - } else { - /* slot is occupied */ - if (!dn->child) { - /* non-empty slot has to have child */ - err("%s: slot[%s]'s device_node doesn't have child for adapter\n", - __FUNCTION__, slot->name); - goto exit_rc; - } - - if (slot->hotplug_slot->info->adapter_status == NOT_CONFIGURED) { - dbg("%s CONFIGURING pci adapter in slot[%s]\n", - __FUNCTION__, slot->name); - pcibios_add_pci_devices(slot->bus); - - } else if (slot->hotplug_slot->info->adapter_status != CONFIGURED) { - err("%s: slot[%s]'s adapter_status is NOT_VALID.\n", - __FUNCTION__, slot->name); - goto exit_rc; - } - print_slot_pci_funcs(slot->bus); - if (!list_empty(slot->pci_devs)) { - slot->state = CONFIGURED; - } else { - /* DLPAR add as opposed to - * boot time */ - slot->state = NOT_CONFIGURED; - } - } - return 0; -exit_rc: - return -EINVAL; -} - int rpaphp_register_pci_slot(struct slot *slot) { int rc, level, state; struct pci_bus *bus; struct hotplug_slot_info *info = slot->hotplug_slot->info; + info->adapter_status = NOT_VALID; + slot->state = EMPTY; + /* Find out if the power is turned on for the slot */ rc = rtas_get_power_level(slot->power_domain, &level); if (rc) @@ -157,23 +108,42 @@ int rpaphp_register_pci_slot(struct slot *slot) info->power_status = level; /* Figure out if there is an adapter in the slot */ - info->adapter_status = NOT_VALID; rc = rpaphp_get_sensor_state(slot, &state); if (rc) return rc; - if (state == EMPTY) - info->adapter_status = EMPTY; - else if (state == PRESENT) { - bus = pcibios_find_pci_bus(slot->dn); - if (bus && !list_empty(&bus->devices)) - info->adapter_status = CONFIGURED; - else - info->adapter_status = NOT_CONFIGURED; + bus = pcibios_find_pci_bus(slot->dn); + if (!bus) { + err("%s: no pci_bus for dn %s\n", __FUNCTION__, slot->dn->full_name); + return -EINVAL; } - if (setup_pci_slot(slot)) - return -EINVAL; + info->adapter_status = EMPTY; + slot->bus = bus; + slot->pci_devs = &bus->devices; + set_slot_name(slot); + + /* if there's an adapter in the slot, go add the pci devices */ + if (state == PRESENT) { + info->adapter_status = NOT_CONFIGURED; + slot->state = NOT_CONFIGURED; + + /* non-empty slot has to have child */ + if (!slot->dn->child) { + err("%s: slot[%s]'s device_node doesn't have child for adapter\n", + __FUNCTION__, slot->name); + return -EINVAL; + } + + if (list_empty(&bus->devices)) + pcibios_add_pci_devices(bus); + + print_slot_pci_funcs(bus); + if (!list_empty(&bus->devices)) { + info->adapter_status = CONFIGURED; + slot->state = CONFIGURED; + } + } return rpaphp_register_slot(slot); } -- cgit v0.10.2 From 307ff12e35526cfab9f09cafcb17239286e6eb85 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:17 -0700 Subject: PCI: rpaphp: remove print_slot_pci_funcs() The debug function print_slot_pci_funcs() is a large wrapper around two debug print statements. Just invoke these directly. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 6417b70..6271be8 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -64,21 +64,6 @@ int rpaphp_get_sensor_state(struct slot *slot, int *state) return rc; } -static void print_slot_pci_funcs(struct pci_bus *bus) -{ - struct device_node *dn; - struct pci_dev *dev; - - dn = pci_bus_to_OF_node(bus); - if (!dn) - return; - - dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, dn->full_name); - list_for_each_entry (dev, &bus->devices, bus_list) - dbg("\t%s\n", pci_name(dev)); - return; -} - static void set_slot_name(struct slot *slot) { struct pci_bus *bus = slot->bus; @@ -138,11 +123,17 @@ int rpaphp_register_pci_slot(struct slot *slot) if (list_empty(&bus->devices)) pcibios_add_pci_devices(bus); - print_slot_pci_funcs(bus); if (!list_empty(&bus->devices)) { info->adapter_status = CONFIGURED; slot->state = CONFIGURED; } + + if (debug) { + struct pci_dev *dev; + dbg("%s: pci_devs of slot[%s]\n", __FUNCTION__, slot->dn->full_name); + list_for_each_entry (dev, &bus->devices, bus_list) + dbg("\t%s\n", pci_name(dev)); + } } return rpaphp_register_slot(slot); -- cgit v0.10.2 From c02929c278f2bca68635e4c2daa00b7825d71061 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:18 -0700 Subject: PCI: rpaphp: remove rpaphp_set_attention_status() The rpaphp_set_attention_status() routine seems to be a wrapper around a single rtas call. Abolish it. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index a2b2257..e28e93c 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -102,6 +102,5 @@ extern void dealloc_slot_struct(struct slot *slot); extern struct slot *alloc_slot_struct(struct device_node *dn, int drc_index, char *drc_name, int power_domain); extern int rpaphp_register_slot(struct slot *slot); extern int rpaphp_deregister_slot(struct slot *slot); -extern int rpaphp_set_attention_status(struct slot *slot, u8 status); #endif /* _PPC64PHP_H */ diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 3970cac..e9c157d 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -63,27 +63,26 @@ module_param(debug, bool, 0644); */ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) { - int retval = 0; + int rc; struct slot *slot = (struct slot *)hotplug_slot->private; down(&rpaphp_sem); switch (value) { case 0: - retval = rpaphp_set_attention_status(slot, LED_OFF); - hotplug_slot->info->attention_status = 0; - break; case 1: - default: - retval = rpaphp_set_attention_status(slot, LED_ON); - hotplug_slot->info->attention_status = 1; - break; case 2: - retval = rpaphp_set_attention_status(slot, LED_ID); - hotplug_slot->info->attention_status = 2; + break; + default: + value = 1; break; } up(&rpaphp_sem); - return retval; + + rc = rtas_set_indicator(DR_INDICATOR, slot->index, value); + if (!rc) + hotplug_slot->info->attention_status = value; + + return rc; } /** diff --git a/drivers/pci/hotplug/rpaphp_slot.c b/drivers/pci/hotplug/rpaphp_slot.c index 30c9dc9..d4ee872 100644 --- a/drivers/pci/hotplug/rpaphp_slot.c +++ b/drivers/pci/hotplug/rpaphp_slot.c @@ -184,15 +184,3 @@ sysfs_fail: return retval; } -int rpaphp_set_attention_status(struct slot *slot, u8 status) -{ - int rc; - - /* status: LED_OFF or LED_ON */ - rc = rtas_set_indicator(DR_INDICATOR, slot->index, status); - if (rc < 0) - err("slot(name=%s location=%s index=0x%x) set attention-status(%d) failed! rc=0x%x\n", - slot->name, slot->location, slot->index, status, rc); - - return rc; -} -- cgit v0.10.2 From 6f79eb749df7f1eea76c947f31603ade7d2b5f6d Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:19 -0700 Subject: PCI: rpaphp: refactor tail call to rpaphp_register_slot() Eliminate the tail call to rpaphp_register_slot() by placing it in the caller. This will help later dis-entanglement. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index e9c157d..d8e5f9fd 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -319,6 +319,9 @@ int rpaphp_add_slot(struct device_node *dn) indexes[i + 1], name, type); retval = rpaphp_register_pci_slot(slot); + if (!retval) + retval = rpaphp_register_slot(slot); + if (retval) dealloc_slot_struct(slot); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 6271be8..2e297b9 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -136,6 +136,6 @@ int rpaphp_register_pci_slot(struct slot *slot) } } - return rpaphp_register_slot(slot); + return 0; } -- cgit v0.10.2 From fea54b8cc9c8290b4c99d481c3e600c46eb18fd5 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:20 -0700 Subject: PCI: rpaphp: Rename rpaphp_register_pci_slot() to rpaphp_enable_slot() Rename rpaphp_register_pci_slot() because its easy to confuse with rpaphp_register_slot() even though it does something completely different. Rename it to rpaphp_enable_slot() because its almost identical to enbale_slot(). Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp.h b/drivers/pci/hotplug/rpaphp.h index e28e93c..c822a77 100644 --- a/drivers/pci/hotplug/rpaphp.h +++ b/drivers/pci/hotplug/rpaphp.h @@ -87,13 +87,11 @@ extern struct list_head rpaphp_slot_head; /* function prototypes */ /* rpaphp_pci.c */ -extern int rpaphp_enable_pci_slot(struct slot *slot); -extern int rpaphp_register_pci_slot(struct slot *slot); +extern int rpaphp_enable_slot(struct slot *slot); extern int rpaphp_get_sensor_state(struct slot *slot, int *state); /* rpaphp_core.c */ extern int rpaphp_add_slot(struct device_node *dn); -extern int rpaphp_remove_slot(struct slot *slot); extern int rpaphp_get_drc_props(struct device_node *dn, int *drc_index, char **drc_name, char **drc_type, int *drc_power_domain); diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index d8e5f9fd..75113d9 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -318,7 +318,7 @@ int rpaphp_add_slot(struct device_node *dn) dbg("Found drc-index:0x%x drc-name:%s drc-type:%s\n", indexes[i + 1], name, type); - retval = rpaphp_register_pci_slot(slot); + retval = rpaphp_enable_slot(slot); if (!retval) retval = rpaphp_register_slot(slot); diff --git a/drivers/pci/hotplug/rpaphp_pci.c b/drivers/pci/hotplug/rpaphp_pci.c index 2e297b9..54ca865 100644 --- a/drivers/pci/hotplug/rpaphp_pci.c +++ b/drivers/pci/hotplug/rpaphp_pci.c @@ -77,7 +77,15 @@ static void set_slot_name(struct slot *slot) bus->number); } -int rpaphp_register_pci_slot(struct slot *slot) +/** + * rpaphp_enable_slot - record slot state, config pci device + * + * Initialize values in the slot, and the hotplug_slot info + * structures to indicate if there is a pci card plugged into + * the slot. If the slot is not empty, run the pcibios routine + * to get pcibios stuff correctly set up. + */ +int rpaphp_enable_slot(struct slot *slot) { int rc, level, state; struct pci_bus *bus; -- cgit v0.10.2 From 8485d1a123e0d367bbcbfec36acf134e6895f39a Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:21 -0700 Subject: PCI: rpaphp: Document find_php_slot() Document some of the interaction between dlpar and hotplug. viz, the a dlpar remove of a htoplug slot uses hotplug to remove it. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 7238346..4d74f0b 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -98,7 +98,15 @@ static struct device_node *find_dlpar_node(char *drc_name, int *node_type) return NULL; } -static struct slot *find_slot(struct device_node *dn) +/** + * find_php_slot - return hotplug slot structure for device node + * + * This routine will return the hotplug slot structure + * for a given device node. Note that built-in PCI slots + * may be dlpar-able, but not hot-pluggable, so this routine + * will return NULL for built-in PCI slots. + */ +static struct slot *find_php_slot(struct device_node *dn) { struct list_head *tmp, *n; struct slot *slot; @@ -224,9 +232,9 @@ static int dlpar_remove_phb(char *drc_name, struct device_node *dn) if (!pcibios_find_pci_bus(dn)) return -EINVAL; - slot = find_slot(dn); + /* If pci slot is hotplugable, use hotplug to remove it */ + slot = find_php_slot(dn); if (slot) { - /* Remove hotplug slot */ if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", @@ -370,9 +378,9 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) if (!bus) return -EINVAL; - slot = find_slot(dn); + /* If pci slot is hotplugable, use hotplug to remove it */ + slot = find_php_slot(dn); if (slot) { - /* Remove hotplug slot */ if (rpaphp_deregister_slot(slot)) { printk(KERN_ERR "%s: unable to remove hotplug slot %s\n", -- cgit v0.10.2 From da65944be2441191539f50ce71cd1f8030699be1 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:22 -0700 Subject: PCI: rpaphp: Document is_php_dn() Fix up the documentation: the rpaphp_add_slot() does not actually handle embedded slots: in fact, it ignores them. Fix the flow of control in the routine that checks for embedded slots. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 75113d9..aa8d9a6 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -262,6 +262,14 @@ static int is_php_type(char *drc_type) return 1; } +/** + * is_php_dn() - return 1 if this is a hotpluggable pci slot, else 0 + * + * This routine will return true only if the device node is + * a hotpluggable slot. This routine will return false + * for built-in pci slots (even when the built-in slots are + * dlparable.) + */ static int is_php_dn(struct device_node *dn, const int **indexes, const int **names, const int **types, const int **power_domains) { @@ -269,24 +277,31 @@ static int is_php_dn(struct device_node *dn, const int **indexes, int rc; rc = get_children_props(dn, indexes, names, &drc_types, power_domains); - if (rc >= 0) { - if (is_php_type((char *) &drc_types[1])) { - *types = drc_types; - return 1; - } - } + if (rc < 0) + return 0; - return 0; + if (!is_php_type((char *) &drc_types[1])) + return 0; + + *types = drc_types; + return 1; } /** - * rpaphp_add_slot -- add hotplug or dlpar slot + * rpaphp_add_slot -- declare a hotplug slot to the hotplug subsystem. + * @dn device node of slot + * + * This subroutine will register a hotplugable slot with the + * PCI hotplug infrastructure. This routine is typicaly called + * during boot time, if the hotplug slots are present at boot time, + * or is called later, by the dlpar add code, if the slot is + * being dynamically added during runtime. + * + * If the device node points at an embedded (built-in) slot, this + * routine will just return without doing anything, since embedded + * slots cannot be hotplugged. * - * rpaphp not only registers PCI hotplug slots(HOTPLUG), - * but also logical DR slots(EMBEDDED). - * HOTPLUG slot: An adapter can be physically added/removed. - * EMBEDDED slot: An adapter can be logically removed/added - * from/to a partition with the slot. + * To remove a slot, it suffices to call rpaphp_deregister_slot() */ int rpaphp_add_slot(struct device_node *dn) { @@ -299,6 +314,7 @@ int rpaphp_add_slot(struct device_node *dn) if (!dn->name || strcmp(dn->name, "pci")) return 0; + /* If this is not a hotplug slot, return without doing anything. */ if (!is_php_dn(dn, &indexes, &names, &types, &power_domains)) return 0; -- cgit v0.10.2 From e70ea2634afe7d04ffaf7417df7bfdbfdc460e10 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:23 -0700 Subject: PCI: rpaphp: Use pcibios_remove_pci_devices() symmetrically At first blush, the disable_slot() routine does not look at all like its symmetric with the enable_slot() routine; as it seems to call a very different set of routines. However, this is easily fixed: pcibios_remove_pci_devices() does the right thing. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index aa8d9a6..4efdaa1 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -424,18 +424,12 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) return retval; } -static int __disable_slot(struct slot *slot) +static inline int __disable_slot(struct slot *slot) { - struct pci_dev *dev, *tmp; - if (slot->state == NOT_CONFIGURED) return -EINVAL; - list_for_each_entry_safe(dev, tmp, &slot->bus->devices, bus_list) { - eeh_remove_bus_device(dev); - pci_remove_bus_device(dev); - } - + pcibios_remove_pci_devices(slot->bus); slot->state = NOT_CONFIGURED; return 0; } -- cgit v0.10.2 From b5661479eeb863749ae28b9ee0dd288464311854 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:24 -0700 Subject: PCI: rpaphp: Ensure more pcibios_add/pcibios_remove symmetry Calls to pcibios_add should be symmetric with calls to pcibios_remove. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpadlpar_core.c b/drivers/pci/hotplug/rpadlpar_core.c index 4d74f0b..bb3c101 100644 --- a/drivers/pci/hotplug/rpadlpar_core.c +++ b/drivers/pci/hotplug/rpadlpar_core.c @@ -387,13 +387,8 @@ int dlpar_remove_pci_slot(char *drc_name, struct device_node *dn) __FUNCTION__, drc_name); return -EIO; } - } else { - struct pci_dev *dev, *tmp; - list_for_each_entry_safe(dev, tmp, &bus->devices, bus_list) { - eeh_remove_bus_device(dev); - pci_remove_bus_device(dev); - } - } + } else + pcibios_remove_pci_devices(bus); if (unmap_bus_range(bus)) { printk(KERN_ERR "%s: failed to unmap bus range\n", -- cgit v0.10.2 From ac1f0e9923356652f21756526e194a4a1a37dd38 Mon Sep 17 00:00:00 2001 From: Linas Vepstas Date: Fri, 13 Apr 2007 15:34:25 -0700 Subject: PCI: rpaphp: Remove semaphores Remove the semaphores from the get routine. These do not appear to be protecting anything that I can make out, and they also do not seem to be required by the hotplug driver. Signed-off-by: Linas Vepstas Cc: John Rose Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 4efdaa1..847936f 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c @@ -39,7 +39,6 @@ #include "rpaphp.h" int debug; -static struct semaphore rpaphp_sem; LIST_HEAD(rpaphp_slot_head); #define DRIVER_VERSION "0.1" @@ -66,7 +65,6 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) int rc; struct slot *slot = (struct slot *)hotplug_slot->private; - down(&rpaphp_sem); switch (value) { case 0: case 1: @@ -76,7 +74,6 @@ static int set_attention_status(struct hotplug_slot *hotplug_slot, u8 value) value = 1; break; } - up(&rpaphp_sem); rc = rtas_set_indicator(DR_INDICATOR, slot->index, value); if (!rc) @@ -95,11 +92,9 @@ static int get_power_status(struct hotplug_slot *hotplug_slot, u8 * value) int retval, level; struct slot *slot = (struct slot *)hotplug_slot->private; - down(&rpaphp_sem); retval = rtas_get_power_level (slot->power_domain, &level); if (!retval) *value = level; - up(&rpaphp_sem); return retval; } @@ -118,9 +113,7 @@ static int get_adapter_status(struct hotplug_slot *hotplug_slot, u8 * value) struct slot *slot = (struct slot *)hotplug_slot->private; int rc, state; - down(&rpaphp_sem); rc = rpaphp_get_sensor_state(slot, &state); - up(&rpaphp_sem); *value = NOT_VALID; if (rc) @@ -138,7 +131,6 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe { struct slot *slot = (struct slot *)hotplug_slot->private; - down(&rpaphp_sem); switch (slot->type) { case 1: case 2: @@ -169,7 +161,6 @@ static int get_max_bus_speed(struct hotplug_slot *hotplug_slot, enum pci_bus_spe break; } - up(&rpaphp_sem); return 0; } @@ -374,7 +365,6 @@ static int __init rpaphp_init(void) struct device_node *dn = NULL; info(DRIVER_DESC " version: " DRIVER_VERSION "\n"); - init_MUTEX(&rpaphp_sem); while ((dn = of_find_node_by_name(dn, "pci"))) rpaphp_add_slot(dn); @@ -387,8 +377,9 @@ static void __exit rpaphp_exit(void) cleanup_slots(); } -static int __enable_slot(struct slot *slot) +static int enable_slot(struct hotplug_slot *hotplug_slot) { + struct slot *slot = (struct slot *)hotplug_slot->private; int state; int retval; @@ -412,20 +403,9 @@ static int __enable_slot(struct slot *slot) return 0; } -static int enable_slot(struct hotplug_slot *hotplug_slot) +static int disable_slot(struct hotplug_slot *hotplug_slot) { - int retval; struct slot *slot = (struct slot *)hotplug_slot->private; - - down(&rpaphp_sem); - retval = __enable_slot(slot); - up(&rpaphp_sem); - - return retval; -} - -static inline int __disable_slot(struct slot *slot) -{ if (slot->state == NOT_CONFIGURED) return -EINVAL; @@ -434,18 +414,6 @@ static inline int __disable_slot(struct slot *slot) return 0; } -static int disable_slot(struct hotplug_slot *hotplug_slot) -{ - struct slot *slot = (struct slot *)hotplug_slot->private; - int retval; - - down(&rpaphp_sem); - retval = __disable_slot (slot); - up(&rpaphp_sem); - - return retval; -} - struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { .owner = THIS_MODULE, .enable_slot = enable_slot, -- cgit v0.10.2 From 03555d591d2c8ee9291db171c0d21d3c9cab04d9 Mon Sep 17 00:00:00 2001 From: Scott Murray Date: Fri, 13 Apr 2007 15:34:26 -0700 Subject: PCI: ZT5550 CPCI Hotplug driver fix cc: Philip Guo Here's a small patch against the current git tree for the ZT5550 CPCI hotplug driver to fix an issue with port freeing that Philip Guo found. Signed-off-by: Scott Murray Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/cpcihp_zt5550.c b/drivers/pci/hotplug/cpcihp_zt5550.c index 1c12e91..41f6a8d 100644 --- a/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/drivers/pci/hotplug/cpcihp_zt5550.c @@ -296,13 +296,17 @@ static struct pci_driver zt5550_hc_driver = { static int __init zt5550_init(void) { struct resource* r; + int rc; info(DRIVER_DESC " version: " DRIVER_VERSION); r = request_region(ENUM_PORT, 1, "#ENUM hotswap signal register"); if(!r) return -EBUSY; - return pci_register_driver(&zt5550_hc_driver); + rc = pci_register_driver(&zt5550_hc_driver); + if(rc < 0) + release_region(ENUM_PORT, 1); + return rc; } static void __exit -- cgit v0.10.2 From d4770143fe72979d463a911d7a1f75f27ce6437b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Fri, 13 Apr 2007 15:34:27 -0700 Subject: PCI hotplug: Use menuconfig objects Use menuconfigs instead of menus, so the whole menu can be disabled at once instead of going through all options. Signed-off-by: Jan Engelhardt Cc: Scott Murray Signed-off-by: Kristen Carlson Accardi Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index be92695..63d6275 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig @@ -2,9 +2,7 @@ # PCI Hotplug support # -menu "PCI Hotplug Support" - -config HOTPLUG_PCI +menuconfig HOTPLUG_PCI tristate "Support for PCI Hotplug (EXPERIMENTAL)" depends on PCI && EXPERIMENTAL && HOTPLUG ---help--- @@ -17,9 +15,10 @@ config HOTPLUG_PCI When in doubt, say N. +if HOTPLUG_PCI + config HOTPLUG_PCI_FAKE tristate "Fake PCI Hotplug driver" - depends on HOTPLUG_PCI help Say Y here if you want to use the fake PCI hotplug driver. It can be used to simulate PCI hotplug events if even if your system is @@ -42,7 +41,7 @@ config HOTPLUG_PCI_FAKE config HOTPLUG_PCI_COMPAQ tristate "Compaq PCI Hotplug driver" - depends on HOTPLUG_PCI && X86 && PCI_BIOS + depends on X86 && PCI_BIOS help Say Y here if you have a motherboard with a Compaq PCI Hotplug controller. @@ -64,7 +63,7 @@ config HOTPLUG_PCI_COMPAQ_NVRAM config HOTPLUG_PCI_IBM tristate "IBM PCI Hotplug driver" - depends on HOTPLUG_PCI && X86_IO_APIC && X86 && PCI_BIOS + depends on X86_IO_APIC && X86 && PCI_BIOS help Say Y here if you have a motherboard with a IBM PCI Hotplug controller. @@ -76,7 +75,6 @@ config HOTPLUG_PCI_IBM config HOTPLUG_PCI_ACPI tristate "ACPI PCI Hotplug driver" - depends on HOTPLUG_PCI depends on (!ACPI_DOCK && ACPI) || (ACPI_DOCK) help Say Y here if you have a system that supports PCI Hotplug using @@ -101,7 +99,6 @@ config HOTPLUG_PCI_ACPI_IBM config HOTPLUG_PCI_CPCI bool "CompactPCI Hotplug driver" - depends on HOTPLUG_PCI help Say Y here if you have a CompactPCI system card with CompactPCI hotswap support per the PICMG 2.1 specification. @@ -110,7 +107,7 @@ config HOTPLUG_PCI_CPCI config HOTPLUG_PCI_CPCI_ZT5550 tristate "Ziatech ZT5550 CompactPCI Hotplug driver" - depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86 + depends on HOTPLUG_PCI_CPCI && X86 help Say Y here if you have an Performance Technologies (formerly Intel, formerly just Ziatech) Ziatech ZT5550 CompactPCI system card. @@ -122,7 +119,7 @@ config HOTPLUG_PCI_CPCI_ZT5550 config HOTPLUG_PCI_CPCI_GENERIC tristate "Generic port I/O CompactPCI Hotplug driver" - depends on HOTPLUG_PCI && HOTPLUG_PCI_CPCI && X86 + depends on HOTPLUG_PCI_CPCI && X86 help Say Y here if you have a CompactPCI system card that exposes the #ENUM hotswap signal as a bit in a system register that can be read through @@ -135,7 +132,6 @@ config HOTPLUG_PCI_CPCI_GENERIC config HOTPLUG_PCI_SHPC tristate "SHPC PCI Hotplug driver" - depends on HOTPLUG_PCI help Say Y here if you have a motherboard with a SHPC PCI Hotplug controller. @@ -147,7 +143,7 @@ config HOTPLUG_PCI_SHPC config HOTPLUG_PCI_RPA tristate "RPA PCI Hotplug driver" - depends on HOTPLUG_PCI && PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE + depends on PPC_PSERIES && PPC64 && !HOTPLUG_PCI_FAKE help Say Y here if you have a RPA system that supports PCI Hotplug. @@ -170,12 +166,11 @@ config HOTPLUG_PCI_RPA_DLPAR config HOTPLUG_PCI_SGI tristate "SGI PCI Hotplug Support" - depends on HOTPLUG_PCI && (IA64_SGI_SN2 || IA64_GENERIC) + depends on IA64_SGI_SN2 || IA64_GENERIC help Say Y here if you want to use the SGI Altix Hotplug Driver for PCI devices. When in doubt, say N. -endmenu - +endif # HOTPLUG_PCI -- cgit v0.10.2 From c0affe9db42bf85f4a606b3262c35ec59a5d3788 Mon Sep 17 00:00:00 2001 From: Tejun Heo Date: Mon, 16 Apr 2007 13:59:18 +0900 Subject: pci-quirks: disable MSI on RS400-200 and RS480 MSI doesn't work on RS400-200 and RS480 requiring pci=nomsi kernel boot parameter for ahci to work. This patch disables MSI on those chips. http://thread.gmane.org/gmane.linux.ide/17820 http://thread.gmane.org/gmane.linux.ide/17516 https://bugzilla.novell.com/show_bug.cgi?id=263893 Signed-off-by: Tejun Heo Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 3411483..147d86f 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -1648,6 +1648,8 @@ static void __devinit quirk_disable_msi(struct pci_dev *dev) } } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS400_200, quirk_disable_msi); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_RS480, quirk_disable_msi); /* Go through the list of Hypertransport capabilities and * return 1 if a HT MSI capability is found and enabled */ -- cgit v0.10.2 From 9890b12a4a65a7b3181dd963421740edf0e14d69 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Wed, 18 Apr 2007 13:34:12 +1000 Subject: PCI: Free resource files in error path of pci_create_sysfs_dev_files() pci_create_sysfs_dev_files() should call pci_remove_resource_files() in its error path, to match the call it makes to pci_create_resource_files(). Signed-off-by: Michael Ellerman Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 29676fe..284e83a 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c @@ -636,7 +636,7 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) goto err_rom; } else { retval = -ENOMEM; - goto err_bin_file; + goto err_resource_files; } } /* add platform-specific attributes */ @@ -646,6 +646,8 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) err_rom: kfree(rom_attr); +err_resource_files: + pci_remove_resource_files(pdev); err_bin_file: if (pdev->cfg_size < 4096) sysfs_remove_bin_file(&pdev->dev.kobj, &pci_config_attr); -- cgit v0.10.2