aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/hotplug/shpchp_ctrl.c
diff options
context:
space:
mode:
authorrajesh.shah@intel.com <rajesh.shah@intel.com>2005-10-13 15:05:40 -0400
committerGreg Kroah-Hartman <gregkh@suse.de>2005-10-28 18:37:00 -0400
commit70b6091946ab486c4dab8abeb4a3fc2bf7d3e7fe (patch)
treeb61b3262529be1b03cabac951bac5cf764e2daf2 /drivers/pci/hotplug/shpchp_ctrl.c
parent1410dc1cef1e2f5e90c1fcb97041f42e0eee35b4 (diff)
[PATCH] shpchp: dont save PCI config for hotplug slots/devices
This patch eliminates saving the PCI config header for devices in hotplug capable slots. We now use the PCI core to get the specific parts of the config header as required. Signed-off-by: Rajesh Shah <rajesh.shah@intel.com> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'drivers/pci/hotplug/shpchp_ctrl.c')
-rw-r--r--drivers/pci/hotplug/shpchp_ctrl.c48
1 files changed, 32 insertions, 16 deletions
diff --git a/drivers/pci/hotplug/shpchp_ctrl.c b/drivers/pci/hotplug/shpchp_ctrl.c
index 23dd61c4c66c..c55103f3cebd 100644
--- a/drivers/pci/hotplug/shpchp_ctrl.c
+++ b/drivers/pci/hotplug/shpchp_ctrl.c
@@ -328,21 +328,20 @@ static int slot_remove(struct pci_func * old_slot)
328/** 328/**
329 * bridge_slot_remove - Removes a node from the linked list of slots. 329 * bridge_slot_remove - Removes a node from the linked list of slots.
330 * @bridge: bridge to remove 330 * @bridge: bridge to remove
331 * @secondaryBus: secondary PCI bus number for bridge being removed
332 * @subordinateBus: subordinate PCI bus number for bridge being removed
331 * 333 *
332 * Returns 0 if successful, !0 otherwise. 334 * Returns 0 if successful, !0 otherwise.
333 */ 335 */
334static int bridge_slot_remove(struct pci_func *bridge) 336static int bridge_slot_remove(struct pci_func *bridge, u8 secondaryBus,
337 u8 subordinateBus)
335{ 338{
336 u8 subordinateBus, secondaryBus;
337 u8 tempBus; 339 u8 tempBus;
338 struct pci_func *next; 340 struct pci_func *next;
339 341
340 if (bridge == NULL) 342 if (bridge == NULL)
341 return(1); 343 return(1);
342 344
343 secondaryBus = (bridge->config_space[0x06] >> 8) & 0xFF;
344 subordinateBus = (bridge->config_space[0x06] >> 16) & 0xFF;
345
346 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) { 345 for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) {
347 next = shpchp_slot_list[tempBus]; 346 next = shpchp_slot_list[tempBus];
348 347
@@ -410,16 +409,23 @@ struct pci_func *shpchp_slot_find(u8 bus, u8 device, u8 index)
410 return(NULL); 409 return(NULL);
411} 410}
412 411
413static int is_bridge(struct pci_func * func) 412static int is_bridge(struct pci_func *func, struct controller *ctrl)
414{ 413{
415 /* Check the header type */ 414 u8 hdr_type;
416 if (((func->config_space[0x03] >> 16) & 0xFF) == 0x01) 415 struct pci_bus *bus = ctrl->pci_dev->subordinate;
416
417 /*
418 * Note: device may have just been hot-added and not yet scanned
419 * by the pci core, so its pci_dev structure may not exist yet
420 */
421 pci_bus_read_config_byte(bus, PCI_DEVFN(func->device, func->function),
422 PCI_HEADER_TYPE, &hdr_type);
423 if ((hdr_type & 0x7f) == PCI_HEADER_TYPE_BRIDGE)
417 return 1; 424 return 1;
418 else 425 else
419 return 0; 426 return 0;
420} 427}
421 428
422
423/* The following routines constitute the bulk of the 429/* The following routines constitute the bulk of the
424 hotplug controller logic 430 hotplug controller logic
425 */ 431 */
@@ -709,8 +715,6 @@ static u32 board_added(struct pci_func * func, struct controller * ctrl)
709 goto err_exit; 715 goto err_exit;
710 } 716 }
711 717
712 shpchp_save_slot_config(ctrl, func);
713
714 func->status = 0; 718 func->status = 0;
715 func->switch_save = 0x10; 719 func->switch_save = 0x10;
716 func->is_a_board = 0x01; 720 func->is_a_board = 0x01;
@@ -769,10 +773,18 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
769 u8 hp_slot; 773 u8 hp_slot;
770 u32 rc; 774 u32 rc;
771 struct slot *p_slot; 775 struct slot *p_slot;
776 u8 secondary = 0, subordinate = 0;
777 int remove_bridge;
772 778
773 if (func == NULL) 779 if (func == NULL)
774 return(1); 780 return(1);
775 781
782 if ((remove_bridge = is_bridge(func, ctrl))) {
783 /* Stash away bus information before we destroy it */
784 secondary = func->pci_dev->subordinate->secondary;
785 subordinate = func->pci_dev->subordinate->subordinate;
786 }
787
776 if (shpchp_unconfigure_device(func)) 788 if (shpchp_unconfigure_device(func))
777 return(1); 789 return(1);
778 790
@@ -825,10 +837,11 @@ static u32 remove_board(struct pci_func *func, struct controller *ctrl)
825 837
826 if (ctrl->add_support) { 838 if (ctrl->add_support) {
827 while (func) { 839 while (func) {
828 if (is_bridge(func)) { 840 if (remove_bridge) {
829 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, 841 dbg("PCI Bridge Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
830 func->device, func->function); 842 func->device, func->function);
831 bridge_slot_remove(func); 843 bridge_slot_remove(func, secondary,
844 subordinate);
832 } else 845 } else
833 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus, 846 dbg("PCI Function Hot-Remove s:b:d:f(%02x:%02x:%02x:%02x)\n", ctrl->seg, func->bus,
834 func->device, func->function); 847 func->device, func->function);
@@ -1185,9 +1198,12 @@ int shpchp_enable_slot (struct slot *p_slot)
1185 1198
1186 rc = board_added(func, p_slot->ctrl); 1199 rc = board_added(func, p_slot->ctrl);
1187 if (rc) { 1200 if (rc) {
1188 if (is_bridge(func)) 1201 if (is_bridge(func, p_slot->ctrl)) {
1189 bridge_slot_remove(func); 1202 u8 secondary = func->pci_dev->subordinate->secondary;
1190 else 1203 u8 subordinate =
1204 func->pci_dev->subordinate->subordinate;
1205 bridge_slot_remove(func, secondary, subordinate);
1206 } else
1191 slot_remove(func); 1207 slot_remove(func);
1192 1208
1193 /* Setup slot structure with entry for empty slot */ 1209 /* Setup slot structure with entry for empty slot */