diff options
Diffstat (limited to 'drivers/pci/hotplug')
-rw-r--r-- | drivers/pci/hotplug/Kconfig | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpi_pcihp.c | 40 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 27 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_core.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp.h | 167 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_core.c | 1100 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_ctrl.c | 371 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_nvram.c | 97 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_pci.c | 599 | ||||
-rw-r--r-- | drivers/pci/hotplug/ibmphp_core.c | 56 | ||||
-rw-r--r-- | drivers/pci/hotplug/pci_hotplug_core.c | 155 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 3 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_core.c | 112 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 31 | ||||
-rw-r--r-- | drivers/pci/hotplug/pcihp_skeleton.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/rpaphp_core.c | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/sgi_hotplug.c | 5 | ||||
-rw-r--r-- | drivers/pci/hotplug/shpchp_core.c | 1 |
19 files changed, 1288 insertions, 1484 deletions
diff --git a/drivers/pci/hotplug/Kconfig b/drivers/pci/hotplug/Kconfig index 9aa4fe100a0d..66f29bc00be4 100644 --- a/drivers/pci/hotplug/Kconfig +++ b/drivers/pci/hotplug/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | menuconfig HOTPLUG_PCI | 5 | menuconfig HOTPLUG_PCI |
6 | tristate "Support for PCI Hotplug" | 6 | tristate "Support for PCI Hotplug" |
7 | depends on PCI && HOTPLUG | 7 | depends on PCI && HOTPLUG && SYSFS |
8 | ---help--- | 8 | ---help--- |
9 | Say Y here if you have a motherboard with a PCI Hotplug controller. | 9 | Say Y here if you have a motherboard with a PCI Hotplug controller. |
10 | This allows you to add and remove PCI cards while the machine is | 10 | This allows you to add and remove PCI cards while the machine is |
@@ -41,7 +41,7 @@ config HOTPLUG_PCI_FAKE | |||
41 | 41 | ||
42 | config HOTPLUG_PCI_COMPAQ | 42 | config HOTPLUG_PCI_COMPAQ |
43 | tristate "Compaq PCI Hotplug driver" | 43 | tristate "Compaq PCI Hotplug driver" |
44 | depends on X86 && PCI_BIOS && PCI_LEGACY | 44 | depends on X86 && PCI_BIOS |
45 | help | 45 | help |
46 | Say Y here if you have a motherboard with a Compaq PCI Hotplug | 46 | Say Y here if you have a motherboard with a Compaq PCI Hotplug |
47 | controller. | 47 | controller. |
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c index fbc63d5e459f..eb159587d0bf 100644 --- a/drivers/pci/hotplug/acpi_pcihp.c +++ b/drivers/pci/hotplug/acpi_pcihp.c | |||
@@ -354,7 +354,7 @@ acpi_status acpi_get_hp_params_from_firmware(struct pci_bus *bus, | |||
354 | status = acpi_run_hpp(handle, hpp); | 354 | status = acpi_run_hpp(handle, hpp); |
355 | if (ACPI_SUCCESS(status)) | 355 | if (ACPI_SUCCESS(status)) |
356 | break; | 356 | break; |
357 | if (acpi_root_bridge(handle)) | 357 | if (acpi_is_root_bridge(handle)) |
358 | break; | 358 | break; |
359 | status = acpi_get_parent(handle, &phandle); | 359 | status = acpi_get_parent(handle, &phandle); |
360 | if (ACPI_FAILURE(status)) | 360 | if (ACPI_FAILURE(status)) |
@@ -428,7 +428,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags) | |||
428 | status = acpi_run_oshp(handle); | 428 | status = acpi_run_oshp(handle); |
429 | if (ACPI_SUCCESS(status)) | 429 | if (ACPI_SUCCESS(status)) |
430 | goto got_one; | 430 | goto got_one; |
431 | if (acpi_root_bridge(handle)) | 431 | if (acpi_is_root_bridge(handle)) |
432 | break; | 432 | break; |
433 | chandle = handle; | 433 | chandle = handle; |
434 | status = acpi_get_parent(chandle, &handle); | 434 | status = acpi_get_parent(chandle, &handle); |
@@ -449,42 +449,6 @@ got_one: | |||
449 | } | 449 | } |
450 | EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); | 450 | EXPORT_SYMBOL(acpi_get_hp_hw_control_from_firmware); |
451 | 451 | ||
452 | /* acpi_root_bridge - check to see if this acpi object is a root bridge | ||
453 | * | ||
454 | * @handle - the acpi object in question. | ||
455 | */ | ||
456 | int acpi_root_bridge(acpi_handle handle) | ||
457 | { | ||
458 | acpi_status status; | ||
459 | struct acpi_device_info *info; | ||
460 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | ||
461 | int i; | ||
462 | |||
463 | status = acpi_get_object_info(handle, &buffer); | ||
464 | if (ACPI_SUCCESS(status)) { | ||
465 | info = buffer.pointer; | ||
466 | if ((info->valid & ACPI_VALID_HID) && | ||
467 | !strcmp(PCI_ROOT_HID_STRING, | ||
468 | info->hardware_id.value)) { | ||
469 | kfree(buffer.pointer); | ||
470 | return 1; | ||
471 | } | ||
472 | if (info->valid & ACPI_VALID_CID) { | ||
473 | for (i=0; i < info->compatibility_id.count; i++) { | ||
474 | if (!strcmp(PCI_ROOT_HID_STRING, | ||
475 | info->compatibility_id.id[i].value)) { | ||
476 | kfree(buffer.pointer); | ||
477 | return 1; | ||
478 | } | ||
479 | } | ||
480 | } | ||
481 | kfree(buffer.pointer); | ||
482 | } | ||
483 | return 0; | ||
484 | } | ||
485 | EXPORT_SYMBOL_GPL(acpi_root_bridge); | ||
486 | |||
487 | |||
488 | static int is_ejectable(acpi_handle handle) | 452 | static int is_ejectable(acpi_handle handle) |
489 | { | 453 | { |
490 | acpi_status status; | 454 | acpi_status status; |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index 43c10bd261b4..4dd7114964ac 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -77,7 +77,6 @@ static int get_latch_status (struct hotplug_slot *slot, u8 *value); | |||
77 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 77 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); |
78 | 78 | ||
79 | static struct hotplug_slot_ops acpi_hotplug_slot_ops = { | 79 | static struct hotplug_slot_ops acpi_hotplug_slot_ops = { |
80 | .owner = THIS_MODULE, | ||
81 | .enable_slot = enable_slot, | 80 | .enable_slot = enable_slot, |
82 | .disable_slot = disable_slot, | 81 | .disable_slot = disable_slot, |
83 | .set_attention_status = set_attention_status, | 82 | .set_attention_status = set_attention_status, |
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 3a6064bce561..0cb0f830a993 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -678,18 +678,9 @@ static void remove_bridge(acpi_handle handle) | |||
678 | 678 | ||
679 | static struct pci_dev * get_apic_pci_info(acpi_handle handle) | 679 | static struct pci_dev * get_apic_pci_info(acpi_handle handle) |
680 | { | 680 | { |
681 | struct acpi_pci_id id; | ||
682 | struct pci_bus *bus; | ||
683 | struct pci_dev *dev; | 681 | struct pci_dev *dev; |
684 | 682 | ||
685 | if (ACPI_FAILURE(acpi_get_pci_id(handle, &id))) | 683 | dev = acpi_get_pci_dev(handle); |
686 | return NULL; | ||
687 | |||
688 | bus = pci_find_bus(id.segment, id.bus); | ||
689 | if (!bus) | ||
690 | return NULL; | ||
691 | |||
692 | dev = pci_get_slot(bus, PCI_DEVFN(id.device, id.function)); | ||
693 | if (!dev) | 684 | if (!dev) |
694 | return NULL; | 685 | return NULL; |
695 | 686 | ||
@@ -1396,19 +1387,16 @@ static void acpiphp_sanitize_bus(struct pci_bus *bus) | |||
1396 | /* Program resources in newly inserted bridge */ | 1387 | /* Program resources in newly inserted bridge */ |
1397 | static int acpiphp_configure_bridge (acpi_handle handle) | 1388 | static int acpiphp_configure_bridge (acpi_handle handle) |
1398 | { | 1389 | { |
1399 | struct acpi_pci_id pci_id; | 1390 | struct pci_dev *dev; |
1400 | struct pci_bus *bus; | 1391 | struct pci_bus *bus; |
1401 | 1392 | ||
1402 | if (ACPI_FAILURE(acpi_get_pci_id(handle, &pci_id))) { | 1393 | dev = acpi_get_pci_dev(handle); |
1394 | if (!dev) { | ||
1403 | err("cannot get PCI domain and bus number for bridge\n"); | 1395 | err("cannot get PCI domain and bus number for bridge\n"); |
1404 | return -EINVAL; | 1396 | return -EINVAL; |
1405 | } | 1397 | } |
1406 | bus = pci_find_bus(pci_id.segment, pci_id.bus); | 1398 | |
1407 | if (!bus) { | 1399 | bus = dev->bus; |
1408 | err("cannot find bus %d:%d\n", | ||
1409 | pci_id.segment, pci_id.bus); | ||
1410 | return -EINVAL; | ||
1411 | } | ||
1412 | 1400 | ||
1413 | pci_bus_size_bridges(bus); | 1401 | pci_bus_size_bridges(bus); |
1414 | pci_bus_assign_resources(bus); | 1402 | pci_bus_assign_resources(bus); |
@@ -1416,6 +1404,7 @@ static int acpiphp_configure_bridge (acpi_handle handle) | |||
1416 | acpiphp_set_hpp_values(handle, bus); | 1404 | acpiphp_set_hpp_values(handle, bus); |
1417 | pci_enable_bridges(bus); | 1405 | pci_enable_bridges(bus); |
1418 | acpiphp_configure_ioapics(handle); | 1406 | acpiphp_configure_ioapics(handle); |
1407 | pci_dev_put(dev); | ||
1419 | return 0; | 1408 | return 0; |
1420 | } | 1409 | } |
1421 | 1410 | ||
@@ -1631,7 +1620,7 @@ find_root_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | |||
1631 | { | 1620 | { |
1632 | int *count = (int *)context; | 1621 | int *count = (int *)context; |
1633 | 1622 | ||
1634 | if (acpi_root_bridge(handle)) { | 1623 | if (acpi_is_root_bridge(handle)) { |
1635 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, | 1624 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
1636 | handle_hotplug_event_bridge, NULL); | 1625 | handle_hotplug_event_bridge, NULL); |
1637 | (*count)++; | 1626 | (*count)++; |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index de94f4feef8c..a5b9f6ae507b 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -72,7 +72,6 @@ static int get_adapter_status(struct hotplug_slot *slot, u8 * value); | |||
72 | static int get_latch_status(struct hotplug_slot *slot, u8 * value); | 72 | static int get_latch_status(struct hotplug_slot *slot, u8 * value); |
73 | 73 | ||
74 | static struct hotplug_slot_ops cpci_hotplug_slot_ops = { | 74 | static struct hotplug_slot_ops cpci_hotplug_slot_ops = { |
75 | .owner = THIS_MODULE, | ||
76 | .enable_slot = enable_slot, | 75 | .enable_slot = enable_slot, |
77 | .disable_slot = disable_slot, | 76 | .disable_slot = disable_slot, |
78 | .set_attention_status = set_attention_status, | 77 | .set_attention_status = set_attention_status, |
diff --git a/drivers/pci/hotplug/cpqphp.h b/drivers/pci/hotplug/cpqphp.h index afaf8f69f73e..53836001d511 100644 --- a/drivers/pci/hotplug/cpqphp.h +++ b/drivers/pci/hotplug/cpqphp.h | |||
@@ -150,25 +150,25 @@ struct ctrl_reg { /* offset */ | |||
150 | 150 | ||
151 | /* offsets to the controller registers based on the above structure layout */ | 151 | /* offsets to the controller registers based on the above structure layout */ |
152 | enum ctrl_offsets { | 152 | enum ctrl_offsets { |
153 | SLOT_RST = offsetof(struct ctrl_reg, slot_RST), | 153 | SLOT_RST = offsetof(struct ctrl_reg, slot_RST), |
154 | SLOT_ENABLE = offsetof(struct ctrl_reg, slot_enable), | 154 | SLOT_ENABLE = offsetof(struct ctrl_reg, slot_enable), |
155 | MISC = offsetof(struct ctrl_reg, misc), | 155 | MISC = offsetof(struct ctrl_reg, misc), |
156 | LED_CONTROL = offsetof(struct ctrl_reg, led_control), | 156 | LED_CONTROL = offsetof(struct ctrl_reg, led_control), |
157 | INT_INPUT_CLEAR = offsetof(struct ctrl_reg, int_input_clear), | 157 | INT_INPUT_CLEAR = offsetof(struct ctrl_reg, int_input_clear), |
158 | INT_MASK = offsetof(struct ctrl_reg, int_mask), | 158 | INT_MASK = offsetof(struct ctrl_reg, int_mask), |
159 | CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0), | 159 | CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0), |
160 | CTRL_RESERVED1 = offsetof(struct ctrl_reg, reserved1), | 160 | CTRL_RESERVED1 = offsetof(struct ctrl_reg, reserved1), |
161 | CTRL_RESERVED2 = offsetof(struct ctrl_reg, reserved1), | 161 | CTRL_RESERVED2 = offsetof(struct ctrl_reg, reserved1), |
162 | GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB), | 162 | GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB), |
163 | NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input), | 163 | NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input), |
164 | CTRL_RESERVED3 = offsetof(struct ctrl_reg, reserved3), | 164 | CTRL_RESERVED3 = offsetof(struct ctrl_reg, reserved3), |
165 | CTRL_RESERVED4 = offsetof(struct ctrl_reg, reserved4), | 165 | CTRL_RESERVED4 = offsetof(struct ctrl_reg, reserved4), |
166 | CTRL_RESERVED5 = offsetof(struct ctrl_reg, reserved5), | 166 | CTRL_RESERVED5 = offsetof(struct ctrl_reg, reserved5), |
167 | CTRL_RESERVED6 = offsetof(struct ctrl_reg, reserved6), | 167 | CTRL_RESERVED6 = offsetof(struct ctrl_reg, reserved6), |
168 | CTRL_RESERVED7 = offsetof(struct ctrl_reg, reserved7), | 168 | CTRL_RESERVED7 = offsetof(struct ctrl_reg, reserved7), |
169 | CTRL_RESERVED8 = offsetof(struct ctrl_reg, reserved8), | 169 | CTRL_RESERVED8 = offsetof(struct ctrl_reg, reserved8), |
170 | SLOT_MASK = offsetof(struct ctrl_reg, slot_mask), | 170 | SLOT_MASK = offsetof(struct ctrl_reg, slot_mask), |
171 | CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9), | 171 | CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9), |
172 | CTRL_RESERVED10 = offsetof(struct ctrl_reg, reserved10), | 172 | CTRL_RESERVED10 = offsetof(struct ctrl_reg, reserved10), |
173 | CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11), | 173 | CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11), |
174 | SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR), | 174 | SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR), |
@@ -190,7 +190,9 @@ struct hrt { | |||
190 | u32 reserved2; | 190 | u32 reserved2; |
191 | } __attribute__ ((packed)); | 191 | } __attribute__ ((packed)); |
192 | 192 | ||
193 | /* offsets to the hotplug resource table registers based on the above structure layout */ | 193 | /* offsets to the hotplug resource table registers based on the above |
194 | * structure layout | ||
195 | */ | ||
194 | enum hrt_offsets { | 196 | enum hrt_offsets { |
195 | SIG0 = offsetof(struct hrt, sig0), | 197 | SIG0 = offsetof(struct hrt, sig0), |
196 | SIG1 = offsetof(struct hrt, sig1), | 198 | SIG1 = offsetof(struct hrt, sig1), |
@@ -217,18 +219,20 @@ struct slot_rt { | |||
217 | u16 pre_mem_length; | 219 | u16 pre_mem_length; |
218 | } __attribute__ ((packed)); | 220 | } __attribute__ ((packed)); |
219 | 221 | ||
220 | /* offsets to the hotplug slot resource table registers based on the above structure layout */ | 222 | /* offsets to the hotplug slot resource table registers based on the above |
223 | * structure layout | ||
224 | */ | ||
221 | enum slot_rt_offsets { | 225 | enum slot_rt_offsets { |
222 | DEV_FUNC = offsetof(struct slot_rt, dev_func), | 226 | DEV_FUNC = offsetof(struct slot_rt, dev_func), |
223 | PRIMARY_BUS = offsetof(struct slot_rt, primary_bus), | 227 | PRIMARY_BUS = offsetof(struct slot_rt, primary_bus), |
224 | SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus), | 228 | SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus), |
225 | MAX_BUS = offsetof(struct slot_rt, max_bus), | 229 | MAX_BUS = offsetof(struct slot_rt, max_bus), |
226 | IO_BASE = offsetof(struct slot_rt, io_base), | 230 | IO_BASE = offsetof(struct slot_rt, io_base), |
227 | IO_LENGTH = offsetof(struct slot_rt, io_length), | 231 | IO_LENGTH = offsetof(struct slot_rt, io_length), |
228 | MEM_BASE = offsetof(struct slot_rt, mem_base), | 232 | MEM_BASE = offsetof(struct slot_rt, mem_base), |
229 | MEM_LENGTH = offsetof(struct slot_rt, mem_length), | 233 | MEM_LENGTH = offsetof(struct slot_rt, mem_length), |
230 | PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base), | 234 | PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base), |
231 | PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length), | 235 | PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length), |
232 | }; | 236 | }; |
233 | 237 | ||
234 | struct pci_func { | 238 | struct pci_func { |
@@ -286,8 +290,8 @@ struct event_info { | |||
286 | struct controller { | 290 | struct controller { |
287 | struct controller *next; | 291 | struct controller *next; |
288 | u32 ctrl_int_comp; | 292 | u32 ctrl_int_comp; |
289 | struct mutex crit_sect; /* critical section mutex */ | 293 | struct mutex crit_sect; /* critical section mutex */ |
290 | void __iomem *hpc_reg; /* cookie for our pci controller location */ | 294 | void __iomem *hpc_reg; /* cookie for our pci controller location */ |
291 | struct pci_resource *mem_head; | 295 | struct pci_resource *mem_head; |
292 | struct pci_resource *p_mem_head; | 296 | struct pci_resource *p_mem_head; |
293 | struct pci_resource *io_head; | 297 | struct pci_resource *io_head; |
@@ -299,7 +303,7 @@ struct controller { | |||
299 | u8 next_event; | 303 | u8 next_event; |
300 | u8 interrupt; | 304 | u8 interrupt; |
301 | u8 cfgspc_irq; | 305 | u8 cfgspc_irq; |
302 | u8 bus; /* bus number for the pci hotplug controller */ | 306 | u8 bus; /* bus number for the pci hotplug controller */ |
303 | u8 rev; | 307 | u8 rev; |
304 | u8 slot_device_offset; | 308 | u8 slot_device_offset; |
305 | u8 first_slot; | 309 | u8 first_slot; |
@@ -401,46 +405,57 @@ struct resource_lists { | |||
401 | 405 | ||
402 | 406 | ||
403 | /* debugfs functions for the hotplug controller info */ | 407 | /* debugfs functions for the hotplug controller info */ |
404 | extern void cpqhp_initialize_debugfs (void); | 408 | extern void cpqhp_initialize_debugfs(void); |
405 | extern void cpqhp_shutdown_debugfs (void); | 409 | extern void cpqhp_shutdown_debugfs(void); |
406 | extern void cpqhp_create_debugfs_files (struct controller *ctrl); | 410 | extern void cpqhp_create_debugfs_files(struct controller *ctrl); |
407 | extern void cpqhp_remove_debugfs_files (struct controller *ctrl); | 411 | extern void cpqhp_remove_debugfs_files(struct controller *ctrl); |
408 | 412 | ||
409 | /* controller functions */ | 413 | /* controller functions */ |
410 | extern void cpqhp_pushbutton_thread (unsigned long event_pointer); | 414 | extern void cpqhp_pushbutton_thread(unsigned long event_pointer); |
411 | extern irqreturn_t cpqhp_ctrl_intr (int IRQ, void *data); | 415 | extern irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data); |
412 | extern int cpqhp_find_available_resources (struct controller *ctrl, void __iomem *rom_start); | 416 | extern int cpqhp_find_available_resources(struct controller *ctrl, |
413 | extern int cpqhp_event_start_thread (void); | 417 | void __iomem *rom_start); |
414 | extern void cpqhp_event_stop_thread (void); | 418 | extern int cpqhp_event_start_thread(void); |
415 | extern struct pci_func *cpqhp_slot_create (unsigned char busnumber); | 419 | extern void cpqhp_event_stop_thread(void); |
416 | extern struct pci_func *cpqhp_slot_find (unsigned char bus, unsigned char device, unsigned char index); | 420 | extern struct pci_func *cpqhp_slot_create(unsigned char busnumber); |
417 | extern int cpqhp_process_SI (struct controller *ctrl, struct pci_func *func); | 421 | extern struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device, |
418 | extern int cpqhp_process_SS (struct controller *ctrl, struct pci_func *func); | 422 | unsigned char index); |
419 | extern int cpqhp_hardware_test (struct controller *ctrl, int test_num); | 423 | extern int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func); |
424 | extern int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func); | ||
425 | extern int cpqhp_hardware_test(struct controller *ctrl, int test_num); | ||
420 | 426 | ||
421 | /* resource functions */ | 427 | /* resource functions */ |
422 | extern int cpqhp_resource_sort_and_combine (struct pci_resource **head); | 428 | extern int cpqhp_resource_sort_and_combine (struct pci_resource **head); |
423 | 429 | ||
424 | /* pci functions */ | 430 | /* pci functions */ |
425 | extern int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); | 431 | extern int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num); |
426 | extern int cpqhp_get_bus_dev (struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot); | 432 | extern int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num, |
427 | extern int cpqhp_save_config (struct controller *ctrl, int busnumber, int is_hot_plug); | 433 | u8 slot); |
428 | extern int cpqhp_save_base_addr_length (struct controller *ctrl, struct pci_func * func); | 434 | extern int cpqhp_save_config(struct controller *ctrl, int busnumber, |
429 | extern int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func); | 435 | int is_hot_plug); |
430 | extern int cpqhp_configure_board (struct controller *ctrl, struct pci_func * func); | 436 | extern int cpqhp_save_base_addr_length(struct controller *ctrl, |
431 | extern int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot); | 437 | struct pci_func *func); |
432 | extern int cpqhp_valid_replace (struct controller *ctrl, struct pci_func * func); | 438 | extern int cpqhp_save_used_resources(struct controller *ctrl, |
433 | extern void cpqhp_destroy_board_resources (struct pci_func * func); | 439 | struct pci_func *func); |
434 | extern int cpqhp_return_board_resources (struct pci_func * func, struct resource_lists * resources); | 440 | extern int cpqhp_configure_board(struct controller *ctrl, |
435 | extern void cpqhp_destroy_resource_list (struct resource_lists * resources); | 441 | struct pci_func *func); |
436 | extern int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func); | 442 | extern int cpqhp_save_slot_config(struct controller *ctrl, |
437 | extern int cpqhp_unconfigure_device (struct pci_func* func); | 443 | struct pci_func *new_slot); |
444 | extern int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func); | ||
445 | extern void cpqhp_destroy_board_resources(struct pci_func *func); | ||
446 | extern int cpqhp_return_board_resources (struct pci_func *func, | ||
447 | struct resource_lists *resources); | ||
448 | extern void cpqhp_destroy_resource_list(struct resource_lists *resources); | ||
449 | extern int cpqhp_configure_device(struct controller *ctrl, | ||
450 | struct pci_func *func); | ||
451 | extern int cpqhp_unconfigure_device(struct pci_func *func); | ||
438 | 452 | ||
439 | /* Global variables */ | 453 | /* Global variables */ |
440 | extern int cpqhp_debug; | 454 | extern int cpqhp_debug; |
441 | extern int cpqhp_legacy_mode; | 455 | extern int cpqhp_legacy_mode; |
442 | extern struct controller *cpqhp_ctrl_list; | 456 | extern struct controller *cpqhp_ctrl_list; |
443 | extern struct pci_func *cpqhp_slot_list[256]; | 457 | extern struct pci_func *cpqhp_slot_list[256]; |
458 | extern struct irq_routing_table *cpqhp_routing_table; | ||
444 | 459 | ||
445 | /* these can be gotten rid of, but for debugging they are purty */ | 460 | /* these can be gotten rid of, but for debugging they are purty */ |
446 | extern u8 cpqhp_nic_irq; | 461 | extern u8 cpqhp_nic_irq; |
@@ -449,7 +464,7 @@ extern u8 cpqhp_disk_irq; | |||
449 | 464 | ||
450 | /* inline functions */ | 465 | /* inline functions */ |
451 | 466 | ||
452 | static inline char *slot_name(struct slot *slot) | 467 | static inline const char *slot_name(struct slot *slot) |
453 | { | 468 | { |
454 | return hotplug_slot_name(slot->hotplug_slot); | 469 | return hotplug_slot_name(slot->hotplug_slot); |
455 | } | 470 | } |
@@ -458,9 +473,9 @@ static inline char *slot_name(struct slot *slot) | |||
458 | * return_resource | 473 | * return_resource |
459 | * | 474 | * |
460 | * Puts node back in the resource list pointed to by head | 475 | * Puts node back in the resource list pointed to by head |
461 | * | ||
462 | */ | 476 | */ |
463 | static inline void return_resource(struct pci_resource **head, struct pci_resource *node) | 477 | static inline void return_resource(struct pci_resource **head, |
478 | struct pci_resource *node) | ||
464 | { | 479 | { |
465 | if (!node || !head) | 480 | if (!node || !head) |
466 | return; | 481 | return; |
@@ -471,7 +486,7 @@ static inline void return_resource(struct pci_resource **head, struct pci_resour | |||
471 | static inline void set_SOGO(struct controller *ctrl) | 486 | static inline void set_SOGO(struct controller *ctrl) |
472 | { | 487 | { |
473 | u16 misc; | 488 | u16 misc; |
474 | 489 | ||
475 | misc = readw(ctrl->hpc_reg + MISC); | 490 | misc = readw(ctrl->hpc_reg + MISC); |
476 | misc = (misc | 0x0001) & 0xFFFB; | 491 | misc = (misc | 0x0001) & 0xFFFB; |
477 | writew(misc, ctrl->hpc_reg + MISC); | 492 | writew(misc, ctrl->hpc_reg + MISC); |
@@ -481,7 +496,7 @@ static inline void set_SOGO(struct controller *ctrl) | |||
481 | static inline void amber_LED_on(struct controller *ctrl, u8 slot) | 496 | static inline void amber_LED_on(struct controller *ctrl, u8 slot) |
482 | { | 497 | { |
483 | u32 led_control; | 498 | u32 led_control; |
484 | 499 | ||
485 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); | 500 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); |
486 | led_control |= (0x01010000L << slot); | 501 | led_control |= (0x01010000L << slot); |
487 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); | 502 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); |
@@ -491,7 +506,7 @@ static inline void amber_LED_on(struct controller *ctrl, u8 slot) | |||
491 | static inline void amber_LED_off(struct controller *ctrl, u8 slot) | 506 | static inline void amber_LED_off(struct controller *ctrl, u8 slot) |
492 | { | 507 | { |
493 | u32 led_control; | 508 | u32 led_control; |
494 | 509 | ||
495 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); | 510 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); |
496 | led_control &= ~(0x01010000L << slot); | 511 | led_control &= ~(0x01010000L << slot); |
497 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); | 512 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); |
@@ -504,7 +519,7 @@ static inline int read_amber_LED(struct controller *ctrl, u8 slot) | |||
504 | 519 | ||
505 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); | 520 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); |
506 | led_control &= (0x01010000L << slot); | 521 | led_control &= (0x01010000L << slot); |
507 | 522 | ||
508 | return led_control ? 1 : 0; | 523 | return led_control ? 1 : 0; |
509 | } | 524 | } |
510 | 525 | ||
@@ -512,7 +527,7 @@ static inline int read_amber_LED(struct controller *ctrl, u8 slot) | |||
512 | static inline void green_LED_on(struct controller *ctrl, u8 slot) | 527 | static inline void green_LED_on(struct controller *ctrl, u8 slot) |
513 | { | 528 | { |
514 | u32 led_control; | 529 | u32 led_control; |
515 | 530 | ||
516 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); | 531 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); |
517 | led_control |= 0x0101L << slot; | 532 | led_control |= 0x0101L << slot; |
518 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); | 533 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); |
@@ -521,7 +536,7 @@ static inline void green_LED_on(struct controller *ctrl, u8 slot) | |||
521 | static inline void green_LED_off(struct controller *ctrl, u8 slot) | 536 | static inline void green_LED_off(struct controller *ctrl, u8 slot) |
522 | { | 537 | { |
523 | u32 led_control; | 538 | u32 led_control; |
524 | 539 | ||
525 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); | 540 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); |
526 | led_control &= ~(0x0101L << slot); | 541 | led_control &= ~(0x0101L << slot); |
527 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); | 542 | writel(led_control, ctrl->hpc_reg + LED_CONTROL); |
@@ -531,7 +546,7 @@ static inline void green_LED_off(struct controller *ctrl, u8 slot) | |||
531 | static inline void green_LED_blink(struct controller *ctrl, u8 slot) | 546 | static inline void green_LED_blink(struct controller *ctrl, u8 slot) |
532 | { | 547 | { |
533 | u32 led_control; | 548 | u32 led_control; |
534 | 549 | ||
535 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); | 550 | led_control = readl(ctrl->hpc_reg + LED_CONTROL); |
536 | led_control &= ~(0x0101L << slot); | 551 | led_control &= ~(0x0101L << slot); |
537 | led_control |= (0x0001L << slot); | 552 | led_control |= (0x0001L << slot); |
@@ -575,22 +590,21 @@ static inline u8 read_slot_enable(struct controller *ctrl) | |||
575 | } | 590 | } |
576 | 591 | ||
577 | 592 | ||
578 | /* | 593 | /** |
579 | * get_controller_speed - find the current frequency/mode of controller. | 594 | * get_controller_speed - find the current frequency/mode of controller. |
580 | * | 595 | * |
581 | * @ctrl: controller to get frequency/mode for. | 596 | * @ctrl: controller to get frequency/mode for. |
582 | * | 597 | * |
583 | * Returns controller speed. | 598 | * Returns controller speed. |
584 | * | ||
585 | */ | 599 | */ |
586 | static inline u8 get_controller_speed(struct controller *ctrl) | 600 | static inline u8 get_controller_speed(struct controller *ctrl) |
587 | { | 601 | { |
588 | u8 curr_freq; | 602 | u8 curr_freq; |
589 | u16 misc; | 603 | u16 misc; |
590 | 604 | ||
591 | if (ctrl->pcix_support) { | 605 | if (ctrl->pcix_support) { |
592 | curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ); | 606 | curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ); |
593 | if ((curr_freq & 0xB0) == 0xB0) | 607 | if ((curr_freq & 0xB0) == 0xB0) |
594 | return PCI_SPEED_133MHz_PCIX; | 608 | return PCI_SPEED_133MHz_PCIX; |
595 | if ((curr_freq & 0xA0) == 0xA0) | 609 | if ((curr_freq & 0xA0) == 0xA0) |
596 | return PCI_SPEED_100MHz_PCIX; | 610 | return PCI_SPEED_100MHz_PCIX; |
@@ -602,19 +616,18 @@ static inline u8 get_controller_speed(struct controller *ctrl) | |||
602 | return PCI_SPEED_33MHz; | 616 | return PCI_SPEED_33MHz; |
603 | } | 617 | } |
604 | 618 | ||
605 | misc = readw(ctrl->hpc_reg + MISC); | 619 | misc = readw(ctrl->hpc_reg + MISC); |
606 | return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; | 620 | return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz; |
607 | } | 621 | } |
608 | |||
609 | 622 | ||
610 | /* | 623 | |
624 | /** | ||
611 | * get_adapter_speed - find the max supported frequency/mode of adapter. | 625 | * get_adapter_speed - find the max supported frequency/mode of adapter. |
612 | * | 626 | * |
613 | * @ctrl: hotplug controller. | 627 | * @ctrl: hotplug controller. |
614 | * @hp_slot: hotplug slot where adapter is installed. | 628 | * @hp_slot: hotplug slot where adapter is installed. |
615 | * | 629 | * |
616 | * Returns adapter speed. | 630 | * Returns adapter speed. |
617 | * | ||
618 | */ | 631 | */ |
619 | static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot) | 632 | static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot) |
620 | { | 633 | { |
@@ -672,7 +685,8 @@ static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot) | |||
672 | } | 685 | } |
673 | 686 | ||
674 | 687 | ||
675 | static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slot) | 688 | static inline int cpq_get_latch_status(struct controller *ctrl, |
689 | struct slot *slot) | ||
676 | { | 690 | { |
677 | u32 status; | 691 | u32 status; |
678 | u8 hp_slot; | 692 | u8 hp_slot; |
@@ -687,7 +701,8 @@ static inline int cpq_get_latch_status(struct controller *ctrl, struct slot *slo | |||
687 | } | 701 | } |
688 | 702 | ||
689 | 703 | ||
690 | static inline int get_presence_status(struct controller *ctrl, struct slot *slot) | 704 | static inline int get_presence_status(struct controller *ctrl, |
705 | struct slot *slot) | ||
691 | { | 706 | { |
692 | int presence_save = 0; | 707 | int presence_save = 0; |
693 | u8 hp_slot; | 708 | u8 hp_slot; |
@@ -696,7 +711,8 @@ static inline int get_presence_status(struct controller *ctrl, struct slot *slot | |||
696 | hp_slot = slot->device - ctrl->slot_device_offset; | 711 | hp_slot = slot->device - ctrl->slot_device_offset; |
697 | 712 | ||
698 | tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); | 713 | tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); |
699 | presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) >> hp_slot) & 0x02; | 714 | presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15)) |
715 | >> hp_slot) & 0x02; | ||
700 | 716 | ||
701 | return presence_save; | 717 | return presence_save; |
702 | } | 718 | } |
@@ -718,5 +734,12 @@ static inline int wait_for_ctrl_irq(struct controller *ctrl) | |||
718 | return retval; | 734 | return retval; |
719 | } | 735 | } |
720 | 736 | ||
721 | #endif | 737 | #include <asm/pci_x86.h> |
738 | static inline int cpqhp_routing_table_length(void) | ||
739 | { | ||
740 | BUG_ON(cpqhp_routing_table == NULL); | ||
741 | return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) / | ||
742 | sizeof(struct irq_info)); | ||
743 | } | ||
722 | 744 | ||
745 | #endif | ||
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index c2e1bcbb28a7..075b4f4b6e0d 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -25,8 +25,7 @@ | |||
25 | * Send feedback to <greg@kroah.com> | 25 | * Send feedback to <greg@kroah.com> |
26 | * | 26 | * |
27 | * Jan 12, 2003 - Added 66/100/133MHz PCI-X support, | 27 | * Jan 12, 2003 - Added 66/100/133MHz PCI-X support, |
28 | * Torben Mathiasen <torben.mathiasen@hp.com> | 28 | * Torben Mathiasen <torben.mathiasen@hp.com> |
29 | * | ||
30 | */ | 29 | */ |
31 | 30 | ||
32 | #include <linux/module.h> | 31 | #include <linux/module.h> |
@@ -45,7 +44,6 @@ | |||
45 | 44 | ||
46 | #include "cpqphp.h" | 45 | #include "cpqphp.h" |
47 | #include "cpqphp_nvram.h" | 46 | #include "cpqphp_nvram.h" |
48 | #include <asm/pci_x86.h> | ||
49 | 47 | ||
50 | 48 | ||
51 | /* Global variables */ | 49 | /* Global variables */ |
@@ -53,6 +51,7 @@ int cpqhp_debug; | |||
53 | int cpqhp_legacy_mode; | 51 | int cpqhp_legacy_mode; |
54 | struct controller *cpqhp_ctrl_list; /* = NULL */ | 52 | struct controller *cpqhp_ctrl_list; /* = NULL */ |
55 | struct pci_func *cpqhp_slot_list[256]; | 53 | struct pci_func *cpqhp_slot_list[256]; |
54 | struct irq_routing_table *cpqhp_routing_table; | ||
56 | 55 | ||
57 | /* local variables */ | 56 | /* local variables */ |
58 | static void __iomem *smbios_table; | 57 | static void __iomem *smbios_table; |
@@ -78,33 +77,6 @@ MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); | |||
78 | 77 | ||
79 | #define CPQHPC_MODULE_MINOR 208 | 78 | #define CPQHPC_MODULE_MINOR 208 |
80 | 79 | ||
81 | static int one_time_init (void); | ||
82 | static int set_attention_status (struct hotplug_slot *slot, u8 value); | ||
83 | static int process_SI (struct hotplug_slot *slot); | ||
84 | static int process_SS (struct hotplug_slot *slot); | ||
85 | static int hardware_test (struct hotplug_slot *slot, u32 value); | ||
86 | static int get_power_status (struct hotplug_slot *slot, u8 *value); | ||
87 | static int get_attention_status (struct hotplug_slot *slot, u8 *value); | ||
88 | static int get_latch_status (struct hotplug_slot *slot, u8 *value); | ||
89 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | ||
90 | static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
91 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | ||
92 | |||
93 | static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { | ||
94 | .owner = THIS_MODULE, | ||
95 | .set_attention_status = set_attention_status, | ||
96 | .enable_slot = process_SI, | ||
97 | .disable_slot = process_SS, | ||
98 | .hardware_test = hardware_test, | ||
99 | .get_power_status = get_power_status, | ||
100 | .get_attention_status = get_attention_status, | ||
101 | .get_latch_status = get_latch_status, | ||
102 | .get_adapter_status = get_adapter_status, | ||
103 | .get_max_bus_speed = get_max_bus_speed, | ||
104 | .get_cur_bus_speed = get_cur_bus_speed, | ||
105 | }; | ||
106 | |||
107 | |||
108 | static inline int is_slot64bit(struct slot *slot) | 80 | static inline int is_slot64bit(struct slot *slot) |
109 | { | 81 | { |
110 | return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0; | 82 | return (readb(slot->p_sm_slot + SMBIOS_SLOT_WIDTH) == 0x06) ? 1 : 0; |
@@ -144,7 +116,7 @@ static void __iomem * detect_SMBIOS_pointer(void __iomem *begin, void __iomem *e | |||
144 | break; | 116 | break; |
145 | } | 117 | } |
146 | } | 118 | } |
147 | 119 | ||
148 | if (!status) | 120 | if (!status) |
149 | fp = NULL; | 121 | fp = NULL; |
150 | 122 | ||
@@ -171,7 +143,7 @@ static int init_SERR(struct controller * ctrl) | |||
171 | tempdword = ctrl->first_slot; | 143 | tempdword = ctrl->first_slot; |
172 | 144 | ||
173 | number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F; | 145 | number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F; |
174 | // Loop through slots | 146 | /* Loop through slots */ |
175 | while (number_of_slots) { | 147 | while (number_of_slots) { |
176 | physical_slot = tempdword; | 148 | physical_slot = tempdword; |
177 | writeb(0, ctrl->hpc_reg + SLOT_SERR); | 149 | writeb(0, ctrl->hpc_reg + SLOT_SERR); |
@@ -182,41 +154,42 @@ static int init_SERR(struct controller * ctrl) | |||
182 | return 0; | 154 | return 0; |
183 | } | 155 | } |
184 | 156 | ||
185 | 157 | static int init_cpqhp_routing_table(void) | |
186 | /* nice debugging output */ | ||
187 | static int pci_print_IRQ_route (void) | ||
188 | { | 158 | { |
189 | struct irq_routing_table *routing_table; | ||
190 | int len; | 159 | int len; |
191 | int loop; | ||
192 | |||
193 | u8 tbus, tdevice, tslot; | ||
194 | 160 | ||
195 | routing_table = pcibios_get_irq_routing_table(); | 161 | cpqhp_routing_table = pcibios_get_irq_routing_table(); |
196 | if (routing_table == NULL) { | 162 | if (cpqhp_routing_table == NULL) |
197 | err("No BIOS Routing Table??? Not good\n"); | ||
198 | return -ENOMEM; | 163 | return -ENOMEM; |
199 | } | ||
200 | 164 | ||
201 | len = (routing_table->size - sizeof(struct irq_routing_table)) / | 165 | len = cpqhp_routing_table_length(); |
202 | sizeof(struct irq_info); | ||
203 | // Make sure I got at least one entry | ||
204 | if (len == 0) { | 166 | if (len == 0) { |
205 | kfree(routing_table); | 167 | kfree(cpqhp_routing_table); |
168 | cpqhp_routing_table = NULL; | ||
206 | return -1; | 169 | return -1; |
207 | } | 170 | } |
208 | 171 | ||
209 | dbg("bus dev func slot\n"); | 172 | return 0; |
173 | } | ||
174 | |||
175 | /* nice debugging output */ | ||
176 | static void pci_print_IRQ_route(void) | ||
177 | { | ||
178 | int len; | ||
179 | int loop; | ||
180 | u8 tbus, tdevice, tslot; | ||
181 | |||
182 | len = cpqhp_routing_table_length(); | ||
210 | 183 | ||
184 | dbg("bus dev func slot\n"); | ||
211 | for (loop = 0; loop < len; ++loop) { | 185 | for (loop = 0; loop < len; ++loop) { |
212 | tbus = routing_table->slots[loop].bus; | 186 | tbus = cpqhp_routing_table->slots[loop].bus; |
213 | tdevice = routing_table->slots[loop].devfn; | 187 | tdevice = cpqhp_routing_table->slots[loop].devfn; |
214 | tslot = routing_table->slots[loop].slot; | 188 | tslot = cpqhp_routing_table->slots[loop].slot; |
215 | dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot); | 189 | dbg("%d %d %d %d\n", tbus, tdevice >> 3, tdevice & 0x7, tslot); |
216 | 190 | ||
217 | } | 191 | } |
218 | kfree(routing_table); | 192 | return; |
219 | return 0; | ||
220 | } | 193 | } |
221 | 194 | ||
222 | 195 | ||
@@ -242,9 +215,9 @@ static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start, | |||
242 | void __iomem *p_max; | 215 | void __iomem *p_max; |
243 | 216 | ||
244 | if (!smbios_table || !curr) | 217 | if (!smbios_table || !curr) |
245 | return(NULL); | 218 | return NULL; |
246 | 219 | ||
247 | // set p_max to the end of the table | 220 | /* set p_max to the end of the table */ |
248 | p_max = smbios_start + readw(smbios_table + ST_LENGTH); | 221 | p_max = smbios_start + readw(smbios_table + ST_LENGTH); |
249 | 222 | ||
250 | p_temp = curr; | 223 | p_temp = curr; |
@@ -253,20 +226,19 @@ static void __iomem *get_subsequent_smbios_entry(void __iomem *smbios_start, | |||
253 | while ((p_temp < p_max) && !bail) { | 226 | while ((p_temp < p_max) && !bail) { |
254 | /* Look for the double NULL terminator | 227 | /* Look for the double NULL terminator |
255 | * The first condition is the previous byte | 228 | * The first condition is the previous byte |
256 | * and the second is the curr */ | 229 | * and the second is the curr |
257 | if (!previous_byte && !(readb(p_temp))) { | 230 | */ |
231 | if (!previous_byte && !(readb(p_temp))) | ||
258 | bail = 1; | 232 | bail = 1; |
259 | } | ||
260 | 233 | ||
261 | previous_byte = readb(p_temp); | 234 | previous_byte = readb(p_temp); |
262 | p_temp++; | 235 | p_temp++; |
263 | } | 236 | } |
264 | 237 | ||
265 | if (p_temp < p_max) { | 238 | if (p_temp < p_max) |
266 | return p_temp; | 239 | return p_temp; |
267 | } else { | 240 | else |
268 | return NULL; | 241 | return NULL; |
269 | } | ||
270 | } | 242 | } |
271 | 243 | ||
272 | 244 | ||
@@ -292,21 +264,18 @@ static void __iomem *get_SMBIOS_entry(void __iomem *smbios_start, | |||
292 | if (!smbios_table) | 264 | if (!smbios_table) |
293 | return NULL; | 265 | return NULL; |
294 | 266 | ||
295 | if (!previous) { | 267 | if (!previous) |
296 | previous = smbios_start; | 268 | previous = smbios_start; |
297 | } else { | 269 | else |
298 | previous = get_subsequent_smbios_entry(smbios_start, | 270 | previous = get_subsequent_smbios_entry(smbios_start, |
299 | smbios_table, previous); | 271 | smbios_table, previous); |
300 | } | ||
301 | 272 | ||
302 | while (previous) { | 273 | while (previous) |
303 | if (readb(previous + SMBIOS_GENERIC_TYPE) != type) { | 274 | if (readb(previous + SMBIOS_GENERIC_TYPE) != type) |
304 | previous = get_subsequent_smbios_entry(smbios_start, | 275 | previous = get_subsequent_smbios_entry(smbios_start, |
305 | smbios_table, previous); | 276 | smbios_table, previous); |
306 | } else { | 277 | else |
307 | break; | 278 | break; |
308 | } | ||
309 | } | ||
310 | 279 | ||
311 | return previous; | 280 | return previous; |
312 | } | 281 | } |
@@ -322,144 +291,6 @@ static void release_slot(struct hotplug_slot *hotplug_slot) | |||
322 | kfree(slot); | 291 | kfree(slot); |
323 | } | 292 | } |
324 | 293 | ||
325 | #define SLOT_NAME_SIZE 10 | ||
326 | |||
327 | static int ctrl_slot_setup(struct controller *ctrl, | ||
328 | void __iomem *smbios_start, | ||
329 | void __iomem *smbios_table) | ||
330 | { | ||
331 | struct slot *slot; | ||
332 | struct hotplug_slot *hotplug_slot; | ||
333 | struct hotplug_slot_info *hotplug_slot_info; | ||
334 | u8 number_of_slots; | ||
335 | u8 slot_device; | ||
336 | u8 slot_number; | ||
337 | u8 ctrl_slot; | ||
338 | u32 tempdword; | ||
339 | char name[SLOT_NAME_SIZE]; | ||
340 | void __iomem *slot_entry= NULL; | ||
341 | int result = -ENOMEM; | ||
342 | |||
343 | dbg("%s\n", __func__); | ||
344 | |||
345 | tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); | ||
346 | |||
347 | number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F; | ||
348 | slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4; | ||
349 | slot_number = ctrl->first_slot; | ||
350 | |||
351 | while (number_of_slots) { | ||
352 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | ||
353 | if (!slot) | ||
354 | goto error; | ||
355 | |||
356 | slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)), | ||
357 | GFP_KERNEL); | ||
358 | if (!slot->hotplug_slot) | ||
359 | goto error_slot; | ||
360 | hotplug_slot = slot->hotplug_slot; | ||
361 | |||
362 | hotplug_slot->info = | ||
363 | kzalloc(sizeof(*(hotplug_slot->info)), | ||
364 | GFP_KERNEL); | ||
365 | if (!hotplug_slot->info) | ||
366 | goto error_hpslot; | ||
367 | hotplug_slot_info = hotplug_slot->info; | ||
368 | |||
369 | slot->ctrl = ctrl; | ||
370 | slot->bus = ctrl->bus; | ||
371 | slot->device = slot_device; | ||
372 | slot->number = slot_number; | ||
373 | dbg("slot->number = %u\n", slot->number); | ||
374 | |||
375 | slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, | ||
376 | slot_entry); | ||
377 | |||
378 | while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != | ||
379 | slot->number)) { | ||
380 | slot_entry = get_SMBIOS_entry(smbios_start, | ||
381 | smbios_table, 9, slot_entry); | ||
382 | } | ||
383 | |||
384 | slot->p_sm_slot = slot_entry; | ||
385 | |||
386 | init_timer(&slot->task_event); | ||
387 | slot->task_event.expires = jiffies + 5 * HZ; | ||
388 | slot->task_event.function = cpqhp_pushbutton_thread; | ||
389 | |||
390 | //FIXME: these capabilities aren't used but if they are | ||
391 | // they need to be correctly implemented | ||
392 | slot->capabilities |= PCISLOT_REPLACE_SUPPORTED; | ||
393 | slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED; | ||
394 | |||
395 | if (is_slot64bit(slot)) | ||
396 | slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; | ||
397 | if (is_slot66mhz(slot)) | ||
398 | slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; | ||
399 | if (ctrl->speed == PCI_SPEED_66MHz) | ||
400 | slot->capabilities |= PCISLOT_66_MHZ_OPERATION; | ||
401 | |||
402 | ctrl_slot = | ||
403 | slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4); | ||
404 | |||
405 | // Check presence | ||
406 | slot->capabilities |= | ||
407 | ((((~tempdword) >> 23) | | ||
408 | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02; | ||
409 | // Check the switch state | ||
410 | slot->capabilities |= | ||
411 | ((~tempdword & 0xFF) >> ctrl_slot) & 0x01; | ||
412 | // Check the slot enable | ||
413 | slot->capabilities |= | ||
414 | ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; | ||
415 | |||
416 | /* register this slot with the hotplug pci core */ | ||
417 | hotplug_slot->release = &release_slot; | ||
418 | hotplug_slot->private = slot; | ||
419 | snprintf(name, SLOT_NAME_SIZE, "%u", slot->number); | ||
420 | hotplug_slot->ops = &cpqphp_hotplug_slot_ops; | ||
421 | |||
422 | hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot); | ||
423 | hotplug_slot_info->attention_status = | ||
424 | cpq_get_attention_status(ctrl, slot); | ||
425 | hotplug_slot_info->latch_status = | ||
426 | cpq_get_latch_status(ctrl, slot); | ||
427 | hotplug_slot_info->adapter_status = | ||
428 | get_presence_status(ctrl, slot); | ||
429 | |||
430 | dbg("registering bus %d, dev %d, number %d, " | ||
431 | "ctrl->slot_device_offset %d, slot %d\n", | ||
432 | slot->bus, slot->device, | ||
433 | slot->number, ctrl->slot_device_offset, | ||
434 | slot_number); | ||
435 | result = pci_hp_register(hotplug_slot, | ||
436 | ctrl->pci_dev->bus, | ||
437 | slot->device, | ||
438 | name); | ||
439 | if (result) { | ||
440 | err("pci_hp_register failed with error %d\n", result); | ||
441 | goto error_info; | ||
442 | } | ||
443 | |||
444 | slot->next = ctrl->slot; | ||
445 | ctrl->slot = slot; | ||
446 | |||
447 | number_of_slots--; | ||
448 | slot_device++; | ||
449 | slot_number++; | ||
450 | } | ||
451 | |||
452 | return 0; | ||
453 | error_info: | ||
454 | kfree(hotplug_slot_info); | ||
455 | error_hpslot: | ||
456 | kfree(hotplug_slot); | ||
457 | error_slot: | ||
458 | kfree(slot); | ||
459 | error: | ||
460 | return result; | ||
461 | } | ||
462 | |||
463 | static int ctrl_slot_cleanup (struct controller * ctrl) | 294 | static int ctrl_slot_cleanup (struct controller * ctrl) |
464 | { | 295 | { |
465 | struct slot *old_slot, *next_slot; | 296 | struct slot *old_slot, *next_slot; |
@@ -476,36 +307,32 @@ static int ctrl_slot_cleanup (struct controller * ctrl) | |||
476 | 307 | ||
477 | cpqhp_remove_debugfs_files(ctrl); | 308 | cpqhp_remove_debugfs_files(ctrl); |
478 | 309 | ||
479 | //Free IRQ associated with hot plug device | 310 | /* Free IRQ associated with hot plug device */ |
480 | free_irq(ctrl->interrupt, ctrl); | 311 | free_irq(ctrl->interrupt, ctrl); |
481 | //Unmap the memory | 312 | /* Unmap the memory */ |
482 | iounmap(ctrl->hpc_reg); | 313 | iounmap(ctrl->hpc_reg); |
483 | //Finally reclaim PCI mem | 314 | /* Finally reclaim PCI mem */ |
484 | release_mem_region(pci_resource_start(ctrl->pci_dev, 0), | 315 | release_mem_region(pci_resource_start(ctrl->pci_dev, 0), |
485 | pci_resource_len(ctrl->pci_dev, 0)); | 316 | pci_resource_len(ctrl->pci_dev, 0)); |
486 | 317 | ||
487 | return(0); | 318 | return 0; |
488 | } | 319 | } |
489 | 320 | ||
490 | 321 | ||
491 | //============================================================================ | 322 | /** |
492 | // function: get_slot_mapping | 323 | * get_slot_mapping - determine logical slot mapping for PCI device |
493 | // | 324 | * |
494 | // Description: Attempts to determine a logical slot mapping for a PCI | 325 | * Won't work for more than one PCI-PCI bridge in a slot. |
495 | // device. Won't work for more than one PCI-PCI bridge | 326 | * |
496 | // in a slot. | 327 | * @bus_num - bus number of PCI device |
497 | // | 328 | * @dev_num - device number of PCI device |
498 | // Input: u8 bus_num - bus number of PCI device | 329 | * @slot - Pointer to u8 where slot number will be returned |
499 | // u8 dev_num - device number of PCI device | 330 | * |
500 | // u8 *slot - Pointer to u8 where slot number will | 331 | * Output: SUCCESS or FAILURE |
501 | // be returned | 332 | */ |
502 | // | ||
503 | // Output: SUCCESS or FAILURE | ||
504 | //============================================================================= | ||
505 | static int | 333 | static int |
506 | get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot) | 334 | get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot) |
507 | { | 335 | { |
508 | struct irq_routing_table *PCIIRQRoutingInfoLength; | ||
509 | u32 work; | 336 | u32 work; |
510 | long len; | 337 | long len; |
511 | long loop; | 338 | long loop; |
@@ -516,36 +343,25 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot) | |||
516 | 343 | ||
517 | bridgeSlot = 0xFF; | 344 | bridgeSlot = 0xFF; |
518 | 345 | ||
519 | PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table(); | 346 | len = cpqhp_routing_table_length(); |
520 | if (!PCIIRQRoutingInfoLength) | ||
521 | return -1; | ||
522 | |||
523 | len = (PCIIRQRoutingInfoLength->size - | ||
524 | sizeof(struct irq_routing_table)) / sizeof(struct irq_info); | ||
525 | // Make sure I got at least one entry | ||
526 | if (len == 0) { | ||
527 | kfree(PCIIRQRoutingInfoLength); | ||
528 | return -1; | ||
529 | } | ||
530 | |||
531 | for (loop = 0; loop < len; ++loop) { | 347 | for (loop = 0; loop < len; ++loop) { |
532 | tbus = PCIIRQRoutingInfoLength->slots[loop].bus; | 348 | tbus = cpqhp_routing_table->slots[loop].bus; |
533 | tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn >> 3; | 349 | tdevice = cpqhp_routing_table->slots[loop].devfn >> 3; |
534 | tslot = PCIIRQRoutingInfoLength->slots[loop].slot; | 350 | tslot = cpqhp_routing_table->slots[loop].slot; |
535 | 351 | ||
536 | if ((tbus == bus_num) && (tdevice == dev_num)) { | 352 | if ((tbus == bus_num) && (tdevice == dev_num)) { |
537 | *slot = tslot; | 353 | *slot = tslot; |
538 | kfree(PCIIRQRoutingInfoLength); | ||
539 | return 0; | 354 | return 0; |
540 | } else { | 355 | } else { |
541 | /* Did not get a match on the target PCI device. Check | 356 | /* Did not get a match on the target PCI device. Check |
542 | * if the current IRQ table entry is a PCI-to-PCI bridge | 357 | * if the current IRQ table entry is a PCI-to-PCI |
543 | * device. If so, and it's secondary bus matches the | 358 | * bridge device. If so, and it's secondary bus |
544 | * bus number for the target device, I need to save the | 359 | * matches the bus number for the target device, I need |
545 | * bridge's slot number. If I can not find an entry for | 360 | * to save the bridge's slot number. If I can not find |
546 | * the target device, I will have to assume it's on the | 361 | * an entry for the target device, I will have to |
547 | * other side of the bridge, and assign it the bridge's | 362 | * assume it's on the other side of the bridge, and |
548 | * slot. */ | 363 | * assign it the bridge's slot. |
364 | */ | ||
549 | bus->number = tbus; | 365 | bus->number = tbus; |
550 | pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0), | 366 | pci_bus_read_config_dword(bus, PCI_DEVFN(tdevice, 0), |
551 | PCI_CLASS_REVISION, &work); | 367 | PCI_CLASS_REVISION, &work); |
@@ -555,25 +371,23 @@ get_slot_mapping(struct pci_bus *bus, u8 bus_num, u8 dev_num, u8 *slot) | |||
555 | PCI_DEVFN(tdevice, 0), | 371 | PCI_DEVFN(tdevice, 0), |
556 | PCI_PRIMARY_BUS, &work); | 372 | PCI_PRIMARY_BUS, &work); |
557 | // See if bridge's secondary bus matches target bus. | 373 | // See if bridge's secondary bus matches target bus. |
558 | if (((work >> 8) & 0x000000FF) == (long) bus_num) { | 374 | if (((work >> 8) & 0x000000FF) == (long) bus_num) |
559 | bridgeSlot = tslot; | 375 | bridgeSlot = tslot; |
560 | } | ||
561 | } | 376 | } |
562 | } | 377 | } |
563 | 378 | ||
564 | } | 379 | } |
565 | 380 | ||
566 | // If we got here, we didn't find an entry in the IRQ mapping table | 381 | /* If we got here, we didn't find an entry in the IRQ mapping table for |
567 | // for the target PCI device. If we did determine that the target | 382 | * the target PCI device. If we did determine that the target device |
568 | // device is on the other side of a PCI-to-PCI bridge, return the | 383 | * is on the other side of a PCI-to-PCI bridge, return the slot number |
569 | // slot number for the bridge. | 384 | * for the bridge. |
385 | */ | ||
570 | if (bridgeSlot != 0xFF) { | 386 | if (bridgeSlot != 0xFF) { |
571 | *slot = bridgeSlot; | 387 | *slot = bridgeSlot; |
572 | kfree(PCIIRQRoutingInfoLength); | ||
573 | return 0; | 388 | return 0; |
574 | } | 389 | } |
575 | kfree(PCIIRQRoutingInfoLength); | 390 | /* Couldn't find an entry in the routing table for this PCI device */ |
576 | // Couldn't find an entry in the routing table for this PCI device | ||
577 | return -1; | 391 | return -1; |
578 | } | 392 | } |
579 | 393 | ||
@@ -591,32 +405,32 @@ cpqhp_set_attention_status(struct controller *ctrl, struct pci_func *func, | |||
591 | u8 hp_slot; | 405 | u8 hp_slot; |
592 | 406 | ||
593 | if (func == NULL) | 407 | if (func == NULL) |
594 | return(1); | 408 | return 1; |
595 | 409 | ||
596 | hp_slot = func->device - ctrl->slot_device_offset; | 410 | hp_slot = func->device - ctrl->slot_device_offset; |
597 | 411 | ||
598 | // Wait for exclusive access to hardware | 412 | /* Wait for exclusive access to hardware */ |
599 | mutex_lock(&ctrl->crit_sect); | 413 | mutex_lock(&ctrl->crit_sect); |
600 | 414 | ||
601 | if (status == 1) { | 415 | if (status == 1) |
602 | amber_LED_on (ctrl, hp_slot); | 416 | amber_LED_on (ctrl, hp_slot); |
603 | } else if (status == 0) { | 417 | else if (status == 0) |
604 | amber_LED_off (ctrl, hp_slot); | 418 | amber_LED_off (ctrl, hp_slot); |
605 | } else { | 419 | else { |
606 | // Done with exclusive hardware access | 420 | /* Done with exclusive hardware access */ |
607 | mutex_unlock(&ctrl->crit_sect); | 421 | mutex_unlock(&ctrl->crit_sect); |
608 | return(1); | 422 | return 1; |
609 | } | 423 | } |
610 | 424 | ||
611 | set_SOGO(ctrl); | 425 | set_SOGO(ctrl); |
612 | 426 | ||
613 | // Wait for SOBS to be unset | 427 | /* Wait for SOBS to be unset */ |
614 | wait_for_ctrl_irq (ctrl); | 428 | wait_for_ctrl_irq (ctrl); |
615 | 429 | ||
616 | // Done with exclusive hardware access | 430 | /* Done with exclusive hardware access */ |
617 | mutex_unlock(&ctrl->crit_sect); | 431 | mutex_unlock(&ctrl->crit_sect); |
618 | 432 | ||
619 | return(0); | 433 | return 0; |
620 | } | 434 | } |
621 | 435 | ||
622 | 436 | ||
@@ -719,7 +533,7 @@ static int hardware_test(struct hotplug_slot *hotplug_slot, u32 value) | |||
719 | 533 | ||
720 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); | 534 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); |
721 | 535 | ||
722 | return cpqhp_hardware_test(ctrl, value); | 536 | return cpqhp_hardware_test(ctrl, value); |
723 | } | 537 | } |
724 | 538 | ||
725 | 539 | ||
@@ -738,7 +552,7 @@ static int get_attention_status(struct hotplug_slot *hotplug_slot, u8 *value) | |||
738 | { | 552 | { |
739 | struct slot *slot = hotplug_slot->private; | 553 | struct slot *slot = hotplug_slot->private; |
740 | struct controller *ctrl = slot->ctrl; | 554 | struct controller *ctrl = slot->ctrl; |
741 | 555 | ||
742 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); | 556 | dbg("%s - physical_slot = %s\n", __func__, slot_name(slot)); |
743 | 557 | ||
744 | *value = cpq_get_attention_status(ctrl, slot); | 558 | *value = cpq_get_attention_status(ctrl, slot); |
@@ -793,6 +607,230 @@ static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp | |||
793 | return 0; | 607 | return 0; |
794 | } | 608 | } |
795 | 609 | ||
610 | static struct hotplug_slot_ops cpqphp_hotplug_slot_ops = { | ||
611 | .set_attention_status = set_attention_status, | ||
612 | .enable_slot = process_SI, | ||
613 | .disable_slot = process_SS, | ||
614 | .hardware_test = hardware_test, | ||
615 | .get_power_status = get_power_status, | ||
616 | .get_attention_status = get_attention_status, | ||
617 | .get_latch_status = get_latch_status, | ||
618 | .get_adapter_status = get_adapter_status, | ||
619 | .get_max_bus_speed = get_max_bus_speed, | ||
620 | .get_cur_bus_speed = get_cur_bus_speed, | ||
621 | }; | ||
622 | |||
623 | #define SLOT_NAME_SIZE 10 | ||
624 | |||
625 | static int ctrl_slot_setup(struct controller *ctrl, | ||
626 | void __iomem *smbios_start, | ||
627 | void __iomem *smbios_table) | ||
628 | { | ||
629 | struct slot *slot; | ||
630 | struct hotplug_slot *hotplug_slot; | ||
631 | struct hotplug_slot_info *hotplug_slot_info; | ||
632 | u8 number_of_slots; | ||
633 | u8 slot_device; | ||
634 | u8 slot_number; | ||
635 | u8 ctrl_slot; | ||
636 | u32 tempdword; | ||
637 | char name[SLOT_NAME_SIZE]; | ||
638 | void __iomem *slot_entry= NULL; | ||
639 | int result = -ENOMEM; | ||
640 | |||
641 | dbg("%s\n", __func__); | ||
642 | |||
643 | tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); | ||
644 | |||
645 | number_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F; | ||
646 | slot_device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4; | ||
647 | slot_number = ctrl->first_slot; | ||
648 | |||
649 | while (number_of_slots) { | ||
650 | slot = kzalloc(sizeof(*slot), GFP_KERNEL); | ||
651 | if (!slot) | ||
652 | goto error; | ||
653 | |||
654 | slot->hotplug_slot = kzalloc(sizeof(*(slot->hotplug_slot)), | ||
655 | GFP_KERNEL); | ||
656 | if (!slot->hotplug_slot) | ||
657 | goto error_slot; | ||
658 | hotplug_slot = slot->hotplug_slot; | ||
659 | |||
660 | hotplug_slot->info = kzalloc(sizeof(*(hotplug_slot->info)), | ||
661 | GFP_KERNEL); | ||
662 | if (!hotplug_slot->info) | ||
663 | goto error_hpslot; | ||
664 | hotplug_slot_info = hotplug_slot->info; | ||
665 | |||
666 | slot->ctrl = ctrl; | ||
667 | slot->bus = ctrl->bus; | ||
668 | slot->device = slot_device; | ||
669 | slot->number = slot_number; | ||
670 | dbg("slot->number = %u\n", slot->number); | ||
671 | |||
672 | slot_entry = get_SMBIOS_entry(smbios_start, smbios_table, 9, | ||
673 | slot_entry); | ||
674 | |||
675 | while (slot_entry && (readw(slot_entry + SMBIOS_SLOT_NUMBER) != | ||
676 | slot->number)) { | ||
677 | slot_entry = get_SMBIOS_entry(smbios_start, | ||
678 | smbios_table, 9, slot_entry); | ||
679 | } | ||
680 | |||
681 | slot->p_sm_slot = slot_entry; | ||
682 | |||
683 | init_timer(&slot->task_event); | ||
684 | slot->task_event.expires = jiffies + 5 * HZ; | ||
685 | slot->task_event.function = cpqhp_pushbutton_thread; | ||
686 | |||
687 | /*FIXME: these capabilities aren't used but if they are | ||
688 | * they need to be correctly implemented | ||
689 | */ | ||
690 | slot->capabilities |= PCISLOT_REPLACE_SUPPORTED; | ||
691 | slot->capabilities |= PCISLOT_INTERLOCK_SUPPORTED; | ||
692 | |||
693 | if (is_slot64bit(slot)) | ||
694 | slot->capabilities |= PCISLOT_64_BIT_SUPPORTED; | ||
695 | if (is_slot66mhz(slot)) | ||
696 | slot->capabilities |= PCISLOT_66_MHZ_SUPPORTED; | ||
697 | if (ctrl->speed == PCI_SPEED_66MHz) | ||
698 | slot->capabilities |= PCISLOT_66_MHZ_OPERATION; | ||
699 | |||
700 | ctrl_slot = | ||
701 | slot_device - (readb(ctrl->hpc_reg + SLOT_MASK) >> 4); | ||
702 | |||
703 | /* Check presence */ | ||
704 | slot->capabilities |= | ||
705 | ((((~tempdword) >> 23) | | ||
706 | ((~tempdword) >> 15)) >> ctrl_slot) & 0x02; | ||
707 | /* Check the switch state */ | ||
708 | slot->capabilities |= | ||
709 | ((~tempdword & 0xFF) >> ctrl_slot) & 0x01; | ||
710 | /* Check the slot enable */ | ||
711 | slot->capabilities |= | ||
712 | ((read_slot_enable(ctrl) << 2) >> ctrl_slot) & 0x04; | ||
713 | |||
714 | /* register this slot with the hotplug pci core */ | ||
715 | hotplug_slot->release = &release_slot; | ||
716 | hotplug_slot->private = slot; | ||
717 | snprintf(name, SLOT_NAME_SIZE, "%u", slot->number); | ||
718 | hotplug_slot->ops = &cpqphp_hotplug_slot_ops; | ||
719 | |||
720 | hotplug_slot_info->power_status = get_slot_enabled(ctrl, slot); | ||
721 | hotplug_slot_info->attention_status = | ||
722 | cpq_get_attention_status(ctrl, slot); | ||
723 | hotplug_slot_info->latch_status = | ||
724 | cpq_get_latch_status(ctrl, slot); | ||
725 | hotplug_slot_info->adapter_status = | ||
726 | get_presence_status(ctrl, slot); | ||
727 | |||
728 | dbg("registering bus %d, dev %d, number %d, " | ||
729 | "ctrl->slot_device_offset %d, slot %d\n", | ||
730 | slot->bus, slot->device, | ||
731 | slot->number, ctrl->slot_device_offset, | ||
732 | slot_number); | ||
733 | result = pci_hp_register(hotplug_slot, | ||
734 | ctrl->pci_dev->bus, | ||
735 | slot->device, | ||
736 | name); | ||
737 | if (result) { | ||
738 | err("pci_hp_register failed with error %d\n", result); | ||
739 | goto error_info; | ||
740 | } | ||
741 | |||
742 | slot->next = ctrl->slot; | ||
743 | ctrl->slot = slot; | ||
744 | |||
745 | number_of_slots--; | ||
746 | slot_device++; | ||
747 | slot_number++; | ||
748 | } | ||
749 | |||
750 | return 0; | ||
751 | error_info: | ||
752 | kfree(hotplug_slot_info); | ||
753 | error_hpslot: | ||
754 | kfree(hotplug_slot); | ||
755 | error_slot: | ||
756 | kfree(slot); | ||
757 | error: | ||
758 | return result; | ||
759 | } | ||
760 | |||
761 | static int one_time_init(void) | ||
762 | { | ||
763 | int loop; | ||
764 | int retval = 0; | ||
765 | |||
766 | if (initialized) | ||
767 | return 0; | ||
768 | |||
769 | power_mode = 0; | ||
770 | |||
771 | retval = init_cpqhp_routing_table(); | ||
772 | if (retval) | ||
773 | goto error; | ||
774 | |||
775 | if (cpqhp_debug) | ||
776 | pci_print_IRQ_route(); | ||
777 | |||
778 | dbg("Initialize + Start the notification mechanism \n"); | ||
779 | |||
780 | retval = cpqhp_event_start_thread(); | ||
781 | if (retval) | ||
782 | goto error; | ||
783 | |||
784 | dbg("Initialize slot lists\n"); | ||
785 | for (loop = 0; loop < 256; loop++) | ||
786 | cpqhp_slot_list[loop] = NULL; | ||
787 | |||
788 | /* FIXME: We also need to hook the NMI handler eventually. | ||
789 | * this also needs to be worked with Christoph | ||
790 | * register_NMI_handler(); | ||
791 | */ | ||
792 | /* Map rom address */ | ||
793 | cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN); | ||
794 | if (!cpqhp_rom_start) { | ||
795 | err ("Could not ioremap memory region for ROM\n"); | ||
796 | retval = -EIO; | ||
797 | goto error; | ||
798 | } | ||
799 | |||
800 | /* Now, map the int15 entry point if we are on compaq specific | ||
801 | * hardware | ||
802 | */ | ||
803 | compaq_nvram_init(cpqhp_rom_start); | ||
804 | |||
805 | /* Map smbios table entry point structure */ | ||
806 | smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start, | ||
807 | cpqhp_rom_start + ROM_PHY_LEN); | ||
808 | if (!smbios_table) { | ||
809 | err ("Could not find the SMBIOS pointer in memory\n"); | ||
810 | retval = -EIO; | ||
811 | goto error_rom_start; | ||
812 | } | ||
813 | |||
814 | smbios_start = ioremap(readl(smbios_table + ST_ADDRESS), | ||
815 | readw(smbios_table + ST_LENGTH)); | ||
816 | if (!smbios_start) { | ||
817 | err ("Could not ioremap memory region taken from SMBIOS values\n"); | ||
818 | retval = -EIO; | ||
819 | goto error_smbios_start; | ||
820 | } | ||
821 | |||
822 | initialized = 1; | ||
823 | |||
824 | return retval; | ||
825 | |||
826 | error_smbios_start: | ||
827 | iounmap(smbios_start); | ||
828 | error_rom_start: | ||
829 | iounmap(cpqhp_rom_start); | ||
830 | error: | ||
831 | return retval; | ||
832 | } | ||
833 | |||
796 | static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 834 | static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
797 | { | 835 | { |
798 | u8 num_of_slots = 0; | 836 | u8 num_of_slots = 0; |
@@ -815,7 +853,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
815 | return err; | 853 | return err; |
816 | } | 854 | } |
817 | 855 | ||
818 | // Need to read VID early b/c it's used to differentiate CPQ and INTC discovery | 856 | /* Need to read VID early b/c it's used to differentiate CPQ and INTC |
857 | * discovery | ||
858 | */ | ||
819 | rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); | 859 | rc = pci_read_config_word(pdev, PCI_VENDOR_ID, &vendor_id); |
820 | if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) { | 860 | if (rc || ((vendor_id != PCI_VENDOR_ID_COMPAQ) && (vendor_id != PCI_VENDOR_ID_INTEL))) { |
821 | err(msg_HPC_non_compaq_or_intel); | 861 | err(msg_HPC_non_compaq_or_intel); |
@@ -832,217 +872,209 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
832 | } | 872 | } |
833 | 873 | ||
834 | /* Check for the proper subsytem ID's | 874 | /* Check for the proper subsytem ID's |
835 | * Intel uses a different SSID programming model than Compaq. | 875 | * Intel uses a different SSID programming model than Compaq. |
836 | * For Intel, each SSID bit identifies a PHP capability. | 876 | * For Intel, each SSID bit identifies a PHP capability. |
837 | * Also Intel HPC's may have RID=0. | 877 | * Also Intel HPC's may have RID=0. |
838 | */ | 878 | */ |
839 | if ((pdev->revision > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) { | 879 | if ((pdev->revision <= 2) && (vendor_id != PCI_VENDOR_ID_INTEL)) { |
840 | // TODO: This code can be made to support non-Compaq or Intel subsystem IDs | 880 | err(msg_HPC_not_supported); |
841 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); | 881 | return -ENODEV; |
842 | if (rc) { | 882 | } |
843 | err("%s : pci_read_config_word failed\n", __func__); | ||
844 | goto err_disable_device; | ||
845 | } | ||
846 | dbg("Subsystem Vendor ID: %x\n", subsystem_vid); | ||
847 | if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) { | ||
848 | err(msg_HPC_non_compaq_or_intel); | ||
849 | rc = -ENODEV; | ||
850 | goto err_disable_device; | ||
851 | } | ||
852 | 883 | ||
853 | ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL); | 884 | /* TODO: This code can be made to support non-Compaq or Intel |
854 | if (!ctrl) { | 885 | * subsystem IDs |
855 | err("%s : out of memory\n", __func__); | 886 | */ |
856 | rc = -ENOMEM; | 887 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); |
857 | goto err_disable_device; | 888 | if (rc) { |
858 | } | 889 | err("%s : pci_read_config_word failed\n", __func__); |
890 | goto err_disable_device; | ||
891 | } | ||
892 | dbg("Subsystem Vendor ID: %x\n", subsystem_vid); | ||
893 | if ((subsystem_vid != PCI_VENDOR_ID_COMPAQ) && (subsystem_vid != PCI_VENDOR_ID_INTEL)) { | ||
894 | err(msg_HPC_non_compaq_or_intel); | ||
895 | rc = -ENODEV; | ||
896 | goto err_disable_device; | ||
897 | } | ||
859 | 898 | ||
860 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid); | 899 | ctrl = kzalloc(sizeof(struct controller), GFP_KERNEL); |
861 | if (rc) { | 900 | if (!ctrl) { |
862 | err("%s : pci_read_config_word failed\n", __func__); | 901 | err("%s : out of memory\n", __func__); |
863 | goto err_free_ctrl; | 902 | rc = -ENOMEM; |
864 | } | 903 | goto err_disable_device; |
904 | } | ||
865 | 905 | ||
866 | info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid); | 906 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_ID, &subsystem_deviceid); |
867 | 907 | if (rc) { | |
868 | /* Set Vendor ID, so it can be accessed later from other functions */ | 908 | err("%s : pci_read_config_word failed\n", __func__); |
869 | ctrl->vendor_id = vendor_id; | 909 | goto err_free_ctrl; |
870 | 910 | } | |
871 | switch (subsystem_vid) { | ||
872 | case PCI_VENDOR_ID_COMPAQ: | ||
873 | if (pdev->revision >= 0x13) { /* CIOBX */ | ||
874 | ctrl->push_flag = 1; | ||
875 | ctrl->slot_switch_type = 1; | ||
876 | ctrl->push_button = 1; | ||
877 | ctrl->pci_config_space = 1; | ||
878 | ctrl->defeature_PHP = 1; | ||
879 | ctrl->pcix_support = 1; | ||
880 | ctrl->pcix_speed_capability = 1; | ||
881 | pci_read_config_byte(pdev, 0x41, &bus_cap); | ||
882 | if (bus_cap & 0x80) { | ||
883 | dbg("bus max supports 133MHz PCI-X\n"); | ||
884 | ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; | ||
885 | break; | ||
886 | } | ||
887 | if (bus_cap & 0x40) { | ||
888 | dbg("bus max supports 100MHz PCI-X\n"); | ||
889 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | ||
890 | break; | ||
891 | } | ||
892 | if (bus_cap & 20) { | ||
893 | dbg("bus max supports 66MHz PCI-X\n"); | ||
894 | ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; | ||
895 | break; | ||
896 | } | ||
897 | if (bus_cap & 10) { | ||
898 | dbg("bus max supports 66MHz PCI\n"); | ||
899 | ctrl->speed_capability = PCI_SPEED_66MHz; | ||
900 | break; | ||
901 | } | ||
902 | |||
903 | break; | ||
904 | } | ||
905 | |||
906 | switch (subsystem_deviceid) { | ||
907 | case PCI_SUB_HPC_ID: | ||
908 | /* Original 6500/7000 implementation */ | ||
909 | ctrl->slot_switch_type = 1; | ||
910 | ctrl->speed_capability = PCI_SPEED_33MHz; | ||
911 | ctrl->push_button = 0; | ||
912 | ctrl->pci_config_space = 1; | ||
913 | ctrl->defeature_PHP = 1; | ||
914 | ctrl->pcix_support = 0; | ||
915 | ctrl->pcix_speed_capability = 0; | ||
916 | break; | ||
917 | case PCI_SUB_HPC_ID2: | ||
918 | /* First Pushbutton implementation */ | ||
919 | ctrl->push_flag = 1; | ||
920 | ctrl->slot_switch_type = 1; | ||
921 | ctrl->speed_capability = PCI_SPEED_33MHz; | ||
922 | ctrl->push_button = 1; | ||
923 | ctrl->pci_config_space = 1; | ||
924 | ctrl->defeature_PHP = 1; | ||
925 | ctrl->pcix_support = 0; | ||
926 | ctrl->pcix_speed_capability = 0; | ||
927 | break; | ||
928 | case PCI_SUB_HPC_ID_INTC: | ||
929 | /* Third party (6500/7000) */ | ||
930 | ctrl->slot_switch_type = 1; | ||
931 | ctrl->speed_capability = PCI_SPEED_33MHz; | ||
932 | ctrl->push_button = 0; | ||
933 | ctrl->pci_config_space = 1; | ||
934 | ctrl->defeature_PHP = 1; | ||
935 | ctrl->pcix_support = 0; | ||
936 | ctrl->pcix_speed_capability = 0; | ||
937 | break; | ||
938 | case PCI_SUB_HPC_ID3: | ||
939 | /* First 66 Mhz implementation */ | ||
940 | ctrl->push_flag = 1; | ||
941 | ctrl->slot_switch_type = 1; | ||
942 | ctrl->speed_capability = PCI_SPEED_66MHz; | ||
943 | ctrl->push_button = 1; | ||
944 | ctrl->pci_config_space = 1; | ||
945 | ctrl->defeature_PHP = 1; | ||
946 | ctrl->pcix_support = 0; | ||
947 | ctrl->pcix_speed_capability = 0; | ||
948 | break; | ||
949 | case PCI_SUB_HPC_ID4: | ||
950 | /* First PCI-X implementation, 100MHz */ | ||
951 | ctrl->push_flag = 1; | ||
952 | ctrl->slot_switch_type = 1; | ||
953 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | ||
954 | ctrl->push_button = 1; | ||
955 | ctrl->pci_config_space = 1; | ||
956 | ctrl->defeature_PHP = 1; | ||
957 | ctrl->pcix_support = 1; | ||
958 | ctrl->pcix_speed_capability = 0; | ||
959 | break; | ||
960 | default: | ||
961 | err(msg_HPC_not_supported); | ||
962 | rc = -ENODEV; | ||
963 | goto err_free_ctrl; | ||
964 | } | ||
965 | break; | ||
966 | 911 | ||
967 | case PCI_VENDOR_ID_INTEL: | 912 | info("Hot Plug Subsystem Device ID: %x\n", subsystem_deviceid); |
968 | /* Check for speed capability (0=33, 1=66) */ | 913 | |
969 | if (subsystem_deviceid & 0x0001) { | 914 | /* Set Vendor ID, so it can be accessed later from other |
970 | ctrl->speed_capability = PCI_SPEED_66MHz; | 915 | * functions |
971 | } else { | 916 | */ |
972 | ctrl->speed_capability = PCI_SPEED_33MHz; | 917 | ctrl->vendor_id = vendor_id; |
973 | } | 918 | |
974 | 919 | switch (subsystem_vid) { | |
975 | /* Check for push button */ | 920 | case PCI_VENDOR_ID_COMPAQ: |
976 | if (subsystem_deviceid & 0x0002) { | 921 | if (pdev->revision >= 0x13) { /* CIOBX */ |
977 | /* no push button */ | 922 | ctrl->push_flag = 1; |
978 | ctrl->push_button = 0; | 923 | ctrl->slot_switch_type = 1; |
979 | } else { | 924 | ctrl->push_button = 1; |
980 | /* push button supported */ | 925 | ctrl->pci_config_space = 1; |
981 | ctrl->push_button = 1; | 926 | ctrl->defeature_PHP = 1; |
982 | } | 927 | ctrl->pcix_support = 1; |
983 | 928 | ctrl->pcix_speed_capability = 1; | |
984 | /* Check for slot switch type (0=mechanical, 1=not mechanical) */ | 929 | pci_read_config_byte(pdev, 0x41, &bus_cap); |
985 | if (subsystem_deviceid & 0x0004) { | 930 | if (bus_cap & 0x80) { |
986 | /* no switch */ | 931 | dbg("bus max supports 133MHz PCI-X\n"); |
987 | ctrl->slot_switch_type = 0; | 932 | ctrl->speed_capability = PCI_SPEED_133MHz_PCIX; |
988 | } else { | ||
989 | /* switch */ | ||
990 | ctrl->slot_switch_type = 1; | ||
991 | } | ||
992 | |||
993 | /* PHP Status (0=De-feature PHP, 1=Normal operation) */ | ||
994 | if (subsystem_deviceid & 0x0008) { | ||
995 | ctrl->defeature_PHP = 1; // PHP supported | ||
996 | } else { | ||
997 | ctrl->defeature_PHP = 0; // PHP not supported | ||
998 | } | ||
999 | |||
1000 | /* Alternate Base Address Register Interface (0=not supported, 1=supported) */ | ||
1001 | if (subsystem_deviceid & 0x0010) { | ||
1002 | ctrl->alternate_base_address = 1; // supported | ||
1003 | } else { | ||
1004 | ctrl->alternate_base_address = 0; // not supported | ||
1005 | } | ||
1006 | |||
1007 | /* PCI Config Space Index (0=not supported, 1=supported) */ | ||
1008 | if (subsystem_deviceid & 0x0020) { | ||
1009 | ctrl->pci_config_space = 1; // supported | ||
1010 | } else { | ||
1011 | ctrl->pci_config_space = 0; // not supported | ||
1012 | } | ||
1013 | |||
1014 | /* PCI-X support */ | ||
1015 | if (subsystem_deviceid & 0x0080) { | ||
1016 | /* PCI-X capable */ | ||
1017 | ctrl->pcix_support = 1; | ||
1018 | /* Frequency of operation in PCI-X mode */ | ||
1019 | if (subsystem_deviceid & 0x0040) { | ||
1020 | /* 133MHz PCI-X if bit 7 is 1 */ | ||
1021 | ctrl->pcix_speed_capability = 1; | ||
1022 | } else { | ||
1023 | /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */ | ||
1024 | /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */ | ||
1025 | ctrl->pcix_speed_capability = 0; | ||
1026 | } | ||
1027 | } else { | ||
1028 | /* Conventional PCI */ | ||
1029 | ctrl->pcix_support = 0; | ||
1030 | ctrl->pcix_speed_capability = 0; | ||
1031 | } | ||
1032 | break; | 933 | break; |
934 | } | ||
935 | if (bus_cap & 0x40) { | ||
936 | dbg("bus max supports 100MHz PCI-X\n"); | ||
937 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | ||
938 | break; | ||
939 | } | ||
940 | if (bus_cap & 20) { | ||
941 | dbg("bus max supports 66MHz PCI-X\n"); | ||
942 | ctrl->speed_capability = PCI_SPEED_66MHz_PCIX; | ||
943 | break; | ||
944 | } | ||
945 | if (bus_cap & 10) { | ||
946 | dbg("bus max supports 66MHz PCI\n"); | ||
947 | ctrl->speed_capability = PCI_SPEED_66MHz; | ||
948 | break; | ||
949 | } | ||
950 | |||
951 | break; | ||
952 | } | ||
1033 | 953 | ||
1034 | default: | 954 | switch (subsystem_deviceid) { |
1035 | err(msg_HPC_not_supported); | 955 | case PCI_SUB_HPC_ID: |
1036 | rc = -ENODEV; | 956 | /* Original 6500/7000 implementation */ |
1037 | goto err_free_ctrl; | 957 | ctrl->slot_switch_type = 1; |
958 | ctrl->speed_capability = PCI_SPEED_33MHz; | ||
959 | ctrl->push_button = 0; | ||
960 | ctrl->pci_config_space = 1; | ||
961 | ctrl->defeature_PHP = 1; | ||
962 | ctrl->pcix_support = 0; | ||
963 | ctrl->pcix_speed_capability = 0; | ||
964 | break; | ||
965 | case PCI_SUB_HPC_ID2: | ||
966 | /* First Pushbutton implementation */ | ||
967 | ctrl->push_flag = 1; | ||
968 | ctrl->slot_switch_type = 1; | ||
969 | ctrl->speed_capability = PCI_SPEED_33MHz; | ||
970 | ctrl->push_button = 1; | ||
971 | ctrl->pci_config_space = 1; | ||
972 | ctrl->defeature_PHP = 1; | ||
973 | ctrl->pcix_support = 0; | ||
974 | ctrl->pcix_speed_capability = 0; | ||
975 | break; | ||
976 | case PCI_SUB_HPC_ID_INTC: | ||
977 | /* Third party (6500/7000) */ | ||
978 | ctrl->slot_switch_type = 1; | ||
979 | ctrl->speed_capability = PCI_SPEED_33MHz; | ||
980 | ctrl->push_button = 0; | ||
981 | ctrl->pci_config_space = 1; | ||
982 | ctrl->defeature_PHP = 1; | ||
983 | ctrl->pcix_support = 0; | ||
984 | ctrl->pcix_speed_capability = 0; | ||
985 | break; | ||
986 | case PCI_SUB_HPC_ID3: | ||
987 | /* First 66 Mhz implementation */ | ||
988 | ctrl->push_flag = 1; | ||
989 | ctrl->slot_switch_type = 1; | ||
990 | ctrl->speed_capability = PCI_SPEED_66MHz; | ||
991 | ctrl->push_button = 1; | ||
992 | ctrl->pci_config_space = 1; | ||
993 | ctrl->defeature_PHP = 1; | ||
994 | ctrl->pcix_support = 0; | ||
995 | ctrl->pcix_speed_capability = 0; | ||
996 | break; | ||
997 | case PCI_SUB_HPC_ID4: | ||
998 | /* First PCI-X implementation, 100MHz */ | ||
999 | ctrl->push_flag = 1; | ||
1000 | ctrl->slot_switch_type = 1; | ||
1001 | ctrl->speed_capability = PCI_SPEED_100MHz_PCIX; | ||
1002 | ctrl->push_button = 1; | ||
1003 | ctrl->pci_config_space = 1; | ||
1004 | ctrl->defeature_PHP = 1; | ||
1005 | ctrl->pcix_support = 1; | ||
1006 | ctrl->pcix_speed_capability = 0; | ||
1007 | break; | ||
1008 | default: | ||
1009 | err(msg_HPC_not_supported); | ||
1010 | rc = -ENODEV; | ||
1011 | goto err_free_ctrl; | ||
1038 | } | 1012 | } |
1013 | break; | ||
1014 | |||
1015 | case PCI_VENDOR_ID_INTEL: | ||
1016 | /* Check for speed capability (0=33, 1=66) */ | ||
1017 | if (subsystem_deviceid & 0x0001) | ||
1018 | ctrl->speed_capability = PCI_SPEED_66MHz; | ||
1019 | else | ||
1020 | ctrl->speed_capability = PCI_SPEED_33MHz; | ||
1021 | |||
1022 | /* Check for push button */ | ||
1023 | if (subsystem_deviceid & 0x0002) | ||
1024 | ctrl->push_button = 0; | ||
1025 | else | ||
1026 | ctrl->push_button = 1; | ||
1027 | |||
1028 | /* Check for slot switch type (0=mechanical, 1=not mechanical) */ | ||
1029 | if (subsystem_deviceid & 0x0004) | ||
1030 | ctrl->slot_switch_type = 0; | ||
1031 | else | ||
1032 | ctrl->slot_switch_type = 1; | ||
1033 | |||
1034 | /* PHP Status (0=De-feature PHP, 1=Normal operation) */ | ||
1035 | if (subsystem_deviceid & 0x0008) | ||
1036 | ctrl->defeature_PHP = 1; /* PHP supported */ | ||
1037 | else | ||
1038 | ctrl->defeature_PHP = 0; /* PHP not supported */ | ||
1039 | |||
1040 | /* Alternate Base Address Register Interface | ||
1041 | * (0=not supported, 1=supported) | ||
1042 | */ | ||
1043 | if (subsystem_deviceid & 0x0010) | ||
1044 | ctrl->alternate_base_address = 1; | ||
1045 | else | ||
1046 | ctrl->alternate_base_address = 0; | ||
1047 | |||
1048 | /* PCI Config Space Index (0=not supported, 1=supported) */ | ||
1049 | if (subsystem_deviceid & 0x0020) | ||
1050 | ctrl->pci_config_space = 1; | ||
1051 | else | ||
1052 | ctrl->pci_config_space = 0; | ||
1053 | |||
1054 | /* PCI-X support */ | ||
1055 | if (subsystem_deviceid & 0x0080) { | ||
1056 | ctrl->pcix_support = 1; | ||
1057 | if (subsystem_deviceid & 0x0040) | ||
1058 | /* 133MHz PCI-X if bit 7 is 1 */ | ||
1059 | ctrl->pcix_speed_capability = 1; | ||
1060 | else | ||
1061 | /* 100MHz PCI-X if bit 7 is 1 and bit 0 is 0, */ | ||
1062 | /* 66MHz PCI-X if bit 7 is 1 and bit 0 is 1 */ | ||
1063 | ctrl->pcix_speed_capability = 0; | ||
1064 | } else { | ||
1065 | /* Conventional PCI */ | ||
1066 | ctrl->pcix_support = 0; | ||
1067 | ctrl->pcix_speed_capability = 0; | ||
1068 | } | ||
1069 | break; | ||
1039 | 1070 | ||
1040 | } else { | 1071 | default: |
1041 | err(msg_HPC_not_supported); | 1072 | err(msg_HPC_not_supported); |
1042 | return -ENODEV; | 1073 | rc = -ENODEV; |
1074 | goto err_free_ctrl; | ||
1043 | } | 1075 | } |
1044 | 1076 | ||
1045 | // Tell the user that we found one. | 1077 | /* Tell the user that we found one. */ |
1046 | info("Initializing the PCI hot plug controller residing on PCI bus %d\n", | 1078 | info("Initializing the PCI hot plug controller residing on PCI bus %d\n", |
1047 | pdev->bus->number); | 1079 | pdev->bus->number); |
1048 | 1080 | ||
@@ -1087,7 +1119,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1087 | if (rc) { | 1119 | if (rc) { |
1088 | goto err_free_bus; | 1120 | goto err_free_bus; |
1089 | } | 1121 | } |
1090 | 1122 | ||
1091 | dbg("pdev = %p\n", pdev); | 1123 | dbg("pdev = %p\n", pdev); |
1092 | dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0)); | 1124 | dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0)); |
1093 | dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0)); | 1125 | dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0)); |
@@ -1109,7 +1141,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1109 | goto err_free_mem_region; | 1141 | goto err_free_mem_region; |
1110 | } | 1142 | } |
1111 | 1143 | ||
1112 | // Check for 66Mhz operation | 1144 | /* Check for 66Mhz operation */ |
1113 | ctrl->speed = get_controller_speed(ctrl); | 1145 | ctrl->speed = get_controller_speed(ctrl); |
1114 | 1146 | ||
1115 | 1147 | ||
@@ -1120,7 +1152,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1120 | * | 1152 | * |
1121 | ********************************************************/ | 1153 | ********************************************************/ |
1122 | 1154 | ||
1123 | // find the physical slot number of the first hot plug slot | 1155 | /* find the physical slot number of the first hot plug slot */ |
1124 | 1156 | ||
1125 | /* Get slot won't work for devices behind bridges, but | 1157 | /* Get slot won't work for devices behind bridges, but |
1126 | * in this case it will always be called for the "base" | 1158 | * in this case it will always be called for the "base" |
@@ -1137,7 +1169,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1137 | goto err_iounmap; | 1169 | goto err_iounmap; |
1138 | } | 1170 | } |
1139 | 1171 | ||
1140 | // Store PCI Config Space for all devices on this bus | 1172 | /* Store PCI Config Space for all devices on this bus */ |
1141 | rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK)); | 1173 | rc = cpqhp_save_config(ctrl, ctrl->bus, readb(ctrl->hpc_reg + SLOT_MASK)); |
1142 | if (rc) { | 1174 | if (rc) { |
1143 | err("%s: unable to save PCI configuration data, error %d\n", | 1175 | err("%s: unable to save PCI configuration data, error %d\n", |
@@ -1148,7 +1180,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1148 | /* | 1180 | /* |
1149 | * Get IO, memory, and IRQ resources for new devices | 1181 | * Get IO, memory, and IRQ resources for new devices |
1150 | */ | 1182 | */ |
1151 | // The next line is required for cpqhp_find_available_resources | 1183 | /* The next line is required for cpqhp_find_available_resources */ |
1152 | ctrl->interrupt = pdev->irq; | 1184 | ctrl->interrupt = pdev->irq; |
1153 | if (ctrl->interrupt < 0x10) { | 1185 | if (ctrl->interrupt < 0x10) { |
1154 | cpqhp_legacy_mode = 1; | 1186 | cpqhp_legacy_mode = 1; |
@@ -1182,7 +1214,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1182 | __func__, rc); | 1214 | __func__, rc); |
1183 | goto err_iounmap; | 1215 | goto err_iounmap; |
1184 | } | 1216 | } |
1185 | 1217 | ||
1186 | /* Mask all general input interrupts */ | 1218 | /* Mask all general input interrupts */ |
1187 | writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK); | 1219 | writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK); |
1188 | 1220 | ||
@@ -1196,12 +1228,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1196 | goto err_iounmap; | 1228 | goto err_iounmap; |
1197 | } | 1229 | } |
1198 | 1230 | ||
1199 | /* Enable Shift Out interrupt and clear it, also enable SERR on power fault */ | 1231 | /* Enable Shift Out interrupt and clear it, also enable SERR on power |
1232 | * fault | ||
1233 | */ | ||
1200 | temp_word = readw(ctrl->hpc_reg + MISC); | 1234 | temp_word = readw(ctrl->hpc_reg + MISC); |
1201 | temp_word |= 0x4006; | 1235 | temp_word |= 0x4006; |
1202 | writew(temp_word, ctrl->hpc_reg + MISC); | 1236 | writew(temp_word, ctrl->hpc_reg + MISC); |
1203 | 1237 | ||
1204 | // Changed 05/05/97 to clear all interrupts at start | 1238 | /* Changed 05/05/97 to clear all interrupts at start */ |
1205 | writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR); | 1239 | writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_INPUT_CLEAR); |
1206 | 1240 | ||
1207 | ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); | 1241 | ctrl->ctrl_int_comp = readl(ctrl->hpc_reg + INT_INPUT_CLEAR); |
@@ -1216,13 +1250,14 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1216 | cpqhp_ctrl_list = ctrl; | 1250 | cpqhp_ctrl_list = ctrl; |
1217 | } | 1251 | } |
1218 | 1252 | ||
1219 | // turn off empty slots here unless command line option "ON" set | 1253 | /* turn off empty slots here unless command line option "ON" set |
1220 | // Wait for exclusive access to hardware | 1254 | * Wait for exclusive access to hardware |
1255 | */ | ||
1221 | mutex_lock(&ctrl->crit_sect); | 1256 | mutex_lock(&ctrl->crit_sect); |
1222 | 1257 | ||
1223 | num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F; | 1258 | num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0F; |
1224 | 1259 | ||
1225 | // find first device number for the ctrl | 1260 | /* find first device number for the ctrl */ |
1226 | device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4; | 1261 | device = readb(ctrl->hpc_reg + SLOT_MASK) >> 4; |
1227 | 1262 | ||
1228 | while (num_of_slots) { | 1263 | while (num_of_slots) { |
@@ -1234,23 +1269,21 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1234 | hp_slot = func->device - ctrl->slot_device_offset; | 1269 | hp_slot = func->device - ctrl->slot_device_offset; |
1235 | dbg("hp_slot: %d\n", hp_slot); | 1270 | dbg("hp_slot: %d\n", hp_slot); |
1236 | 1271 | ||
1237 | // We have to save the presence info for these slots | 1272 | /* We have to save the presence info for these slots */ |
1238 | temp_word = ctrl->ctrl_int_comp >> 16; | 1273 | temp_word = ctrl->ctrl_int_comp >> 16; |
1239 | func->presence_save = (temp_word >> hp_slot) & 0x01; | 1274 | func->presence_save = (temp_word >> hp_slot) & 0x01; |
1240 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; | 1275 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; |
1241 | 1276 | ||
1242 | if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) { | 1277 | if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) |
1243 | func->switch_save = 0; | 1278 | func->switch_save = 0; |
1244 | } else { | 1279 | else |
1245 | func->switch_save = 0x10; | 1280 | func->switch_save = 0x10; |
1246 | } | ||
1247 | 1281 | ||
1248 | if (!power_mode) { | 1282 | if (!power_mode) |
1249 | if (!func->is_a_board) { | 1283 | if (!func->is_a_board) { |
1250 | green_LED_off(ctrl, hp_slot); | 1284 | green_LED_off(ctrl, hp_slot); |
1251 | slot_disable(ctrl, hp_slot); | 1285 | slot_disable(ctrl, hp_slot); |
1252 | } | 1286 | } |
1253 | } | ||
1254 | 1287 | ||
1255 | device++; | 1288 | device++; |
1256 | num_of_slots--; | 1289 | num_of_slots--; |
@@ -1258,7 +1291,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1258 | 1291 | ||
1259 | if (!power_mode) { | 1292 | if (!power_mode) { |
1260 | set_SOGO(ctrl); | 1293 | set_SOGO(ctrl); |
1261 | // Wait for SOBS to be unset | 1294 | /* Wait for SOBS to be unset */ |
1262 | wait_for_ctrl_irq(ctrl); | 1295 | wait_for_ctrl_irq(ctrl); |
1263 | } | 1296 | } |
1264 | 1297 | ||
@@ -1269,7 +1302,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1269 | goto err_free_irq; | 1302 | goto err_free_irq; |
1270 | } | 1303 | } |
1271 | 1304 | ||
1272 | // Done with exclusive hardware access | 1305 | /* Done with exclusive hardware access */ |
1273 | mutex_unlock(&ctrl->crit_sect); | 1306 | mutex_unlock(&ctrl->crit_sect); |
1274 | 1307 | ||
1275 | cpqhp_create_debugfs_files(ctrl); | 1308 | cpqhp_create_debugfs_files(ctrl); |
@@ -1291,77 +1324,6 @@ err_disable_device: | |||
1291 | return rc; | 1324 | return rc; |
1292 | } | 1325 | } |
1293 | 1326 | ||
1294 | |||
1295 | static int one_time_init(void) | ||
1296 | { | ||
1297 | int loop; | ||
1298 | int retval = 0; | ||
1299 | |||
1300 | if (initialized) | ||
1301 | return 0; | ||
1302 | |||
1303 | power_mode = 0; | ||
1304 | |||
1305 | retval = pci_print_IRQ_route(); | ||
1306 | if (retval) | ||
1307 | goto error; | ||
1308 | |||
1309 | dbg("Initialize + Start the notification mechanism \n"); | ||
1310 | |||
1311 | retval = cpqhp_event_start_thread(); | ||
1312 | if (retval) | ||
1313 | goto error; | ||
1314 | |||
1315 | dbg("Initialize slot lists\n"); | ||
1316 | for (loop = 0; loop < 256; loop++) { | ||
1317 | cpqhp_slot_list[loop] = NULL; | ||
1318 | } | ||
1319 | |||
1320 | // FIXME: We also need to hook the NMI handler eventually. | ||
1321 | // this also needs to be worked with Christoph | ||
1322 | // register_NMI_handler(); | ||
1323 | |||
1324 | // Map rom address | ||
1325 | cpqhp_rom_start = ioremap(ROM_PHY_ADDR, ROM_PHY_LEN); | ||
1326 | if (!cpqhp_rom_start) { | ||
1327 | err ("Could not ioremap memory region for ROM\n"); | ||
1328 | retval = -EIO; | ||
1329 | goto error; | ||
1330 | } | ||
1331 | |||
1332 | /* Now, map the int15 entry point if we are on compaq specific hardware */ | ||
1333 | compaq_nvram_init(cpqhp_rom_start); | ||
1334 | |||
1335 | /* Map smbios table entry point structure */ | ||
1336 | smbios_table = detect_SMBIOS_pointer(cpqhp_rom_start, | ||
1337 | cpqhp_rom_start + ROM_PHY_LEN); | ||
1338 | if (!smbios_table) { | ||
1339 | err ("Could not find the SMBIOS pointer in memory\n"); | ||
1340 | retval = -EIO; | ||
1341 | goto error_rom_start; | ||
1342 | } | ||
1343 | |||
1344 | smbios_start = ioremap(readl(smbios_table + ST_ADDRESS), | ||
1345 | readw(smbios_table + ST_LENGTH)); | ||
1346 | if (!smbios_start) { | ||
1347 | err ("Could not ioremap memory region taken from SMBIOS values\n"); | ||
1348 | retval = -EIO; | ||
1349 | goto error_smbios_start; | ||
1350 | } | ||
1351 | |||
1352 | initialized = 1; | ||
1353 | |||
1354 | return retval; | ||
1355 | |||
1356 | error_smbios_start: | ||
1357 | iounmap(smbios_start); | ||
1358 | error_rom_start: | ||
1359 | iounmap(cpqhp_rom_start); | ||
1360 | error: | ||
1361 | return retval; | ||
1362 | } | ||
1363 | |||
1364 | |||
1365 | static void __exit unload_cpqphpd(void) | 1327 | static void __exit unload_cpqphpd(void) |
1366 | { | 1328 | { |
1367 | struct pci_func *next; | 1329 | struct pci_func *next; |
@@ -1381,10 +1343,10 @@ static void __exit unload_cpqphpd(void) | |||
1381 | if (ctrl->hpc_reg) { | 1343 | if (ctrl->hpc_reg) { |
1382 | u16 misc; | 1344 | u16 misc; |
1383 | rc = read_slot_enable (ctrl); | 1345 | rc = read_slot_enable (ctrl); |
1384 | 1346 | ||
1385 | writeb(0, ctrl->hpc_reg + SLOT_SERR); | 1347 | writeb(0, ctrl->hpc_reg + SLOT_SERR); |
1386 | writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK); | 1348 | writel(0xFFFFFFC0L | ~rc, ctrl->hpc_reg + INT_MASK); |
1387 | 1349 | ||
1388 | misc = readw(ctrl->hpc_reg + MISC); | 1350 | misc = readw(ctrl->hpc_reg + MISC); |
1389 | misc &= 0xFFFD; | 1351 | misc &= 0xFFFD; |
1390 | writew(misc, ctrl->hpc_reg + MISC); | 1352 | writew(misc, ctrl->hpc_reg + MISC); |
@@ -1464,38 +1426,34 @@ static void __exit unload_cpqphpd(void) | |||
1464 | } | 1426 | } |
1465 | } | 1427 | } |
1466 | 1428 | ||
1467 | // Stop the notification mechanism | 1429 | /* Stop the notification mechanism */ |
1468 | if (initialized) | 1430 | if (initialized) |
1469 | cpqhp_event_stop_thread(); | 1431 | cpqhp_event_stop_thread(); |
1470 | 1432 | ||
1471 | //unmap the rom address | 1433 | /* unmap the rom address */ |
1472 | if (cpqhp_rom_start) | 1434 | if (cpqhp_rom_start) |
1473 | iounmap(cpqhp_rom_start); | 1435 | iounmap(cpqhp_rom_start); |
1474 | if (smbios_start) | 1436 | if (smbios_start) |
1475 | iounmap(smbios_start); | 1437 | iounmap(smbios_start); |
1476 | } | 1438 | } |
1477 | 1439 | ||
1478 | |||
1479 | |||
1480 | static struct pci_device_id hpcd_pci_tbl[] = { | 1440 | static struct pci_device_id hpcd_pci_tbl[] = { |
1481 | { | 1441 | { |
1482 | /* handle any PCI Hotplug controller */ | 1442 | /* handle any PCI Hotplug controller */ |
1483 | .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00), | 1443 | .class = ((PCI_CLASS_SYSTEM_PCI_HOTPLUG << 8) | 0x00), |
1484 | .class_mask = ~0, | 1444 | .class_mask = ~0, |
1485 | 1445 | ||
1486 | /* no matter who makes it */ | 1446 | /* no matter who makes it */ |
1487 | .vendor = PCI_ANY_ID, | 1447 | .vendor = PCI_ANY_ID, |
1488 | .device = PCI_ANY_ID, | 1448 | .device = PCI_ANY_ID, |
1489 | .subvendor = PCI_ANY_ID, | 1449 | .subvendor = PCI_ANY_ID, |
1490 | .subdevice = PCI_ANY_ID, | 1450 | .subdevice = PCI_ANY_ID, |
1491 | 1451 | ||
1492 | }, { /* end: all zeroes */ } | 1452 | }, { /* end: all zeroes */ } |
1493 | }; | 1453 | }; |
1494 | 1454 | ||
1495 | MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl); | 1455 | MODULE_DEVICE_TABLE(pci, hpcd_pci_tbl); |
1496 | 1456 | ||
1497 | |||
1498 | |||
1499 | static struct pci_driver cpqhpc_driver = { | 1457 | static struct pci_driver cpqhpc_driver = { |
1500 | .name = "compaq_pci_hotplug", | 1458 | .name = "compaq_pci_hotplug", |
1501 | .id_table = hpcd_pci_tbl, | 1459 | .id_table = hpcd_pci_tbl, |
@@ -1503,8 +1461,6 @@ static struct pci_driver cpqhpc_driver = { | |||
1503 | /* remove: cpqhpc_remove_one, */ | 1461 | /* remove: cpqhpc_remove_one, */ |
1504 | }; | 1462 | }; |
1505 | 1463 | ||
1506 | |||
1507 | |||
1508 | static int __init cpqhpc_init(void) | 1464 | static int __init cpqhpc_init(void) |
1509 | { | 1465 | { |
1510 | int result; | 1466 | int result; |
@@ -1518,7 +1474,6 @@ static int __init cpqhpc_init(void) | |||
1518 | return result; | 1474 | return result; |
1519 | } | 1475 | } |
1520 | 1476 | ||
1521 | |||
1522 | static void __exit cpqhpc_cleanup(void) | 1477 | static void __exit cpqhpc_cleanup(void) |
1523 | { | 1478 | { |
1524 | dbg("unload_cpqphpd()\n"); | 1479 | dbg("unload_cpqphpd()\n"); |
@@ -1529,8 +1484,5 @@ static void __exit cpqhpc_cleanup(void) | |||
1529 | cpqhp_shutdown_debugfs(); | 1484 | cpqhp_shutdown_debugfs(); |
1530 | } | 1485 | } |
1531 | 1486 | ||
1532 | |||
1533 | module_init(cpqhpc_init); | 1487 | module_init(cpqhpc_init); |
1534 | module_exit(cpqhpc_cleanup); | 1488 | module_exit(cpqhpc_cleanup); |
1535 | |||
1536 | |||
diff --git a/drivers/pci/hotplug/cpqphp_ctrl.c b/drivers/pci/hotplug/cpqphp_ctrl.c index cc227a8c4b11..2fa47af992a8 100644 --- a/drivers/pci/hotplug/cpqphp_ctrl.c +++ b/drivers/pci/hotplug/cpqphp_ctrl.c | |||
@@ -81,14 +81,15 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl) | |||
81 | 81 | ||
82 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { | 82 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { |
83 | if (change & (0x1L << hp_slot)) { | 83 | if (change & (0x1L << hp_slot)) { |
84 | /********************************** | 84 | /* |
85 | * this one changed. | 85 | * this one changed. |
86 | **********************************/ | 86 | */ |
87 | func = cpqhp_slot_find(ctrl->bus, | 87 | func = cpqhp_slot_find(ctrl->bus, |
88 | (hp_slot + ctrl->slot_device_offset), 0); | 88 | (hp_slot + ctrl->slot_device_offset), 0); |
89 | 89 | ||
90 | /* this is the structure that tells the worker thread | 90 | /* this is the structure that tells the worker thread |
91 | *what to do */ | 91 | * what to do |
92 | */ | ||
92 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); | 93 | taskInfo = &(ctrl->event_queue[ctrl->next_event]); |
93 | ctrl->next_event = (ctrl->next_event + 1) % 10; | 94 | ctrl->next_event = (ctrl->next_event + 1) % 10; |
94 | taskInfo->hp_slot = hp_slot; | 95 | taskInfo->hp_slot = hp_slot; |
@@ -100,17 +101,17 @@ static u8 handle_switch_change(u8 change, struct controller * ctrl) | |||
100 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; | 101 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; |
101 | 102 | ||
102 | if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) { | 103 | if (ctrl->ctrl_int_comp & (0x1L << hp_slot)) { |
103 | /********************************** | 104 | /* |
104 | * Switch opened | 105 | * Switch opened |
105 | **********************************/ | 106 | */ |
106 | 107 | ||
107 | func->switch_save = 0; | 108 | func->switch_save = 0; |
108 | 109 | ||
109 | taskInfo->event_type = INT_SWITCH_OPEN; | 110 | taskInfo->event_type = INT_SWITCH_OPEN; |
110 | } else { | 111 | } else { |
111 | /********************************** | 112 | /* |
112 | * Switch closed | 113 | * Switch closed |
113 | **********************************/ | 114 | */ |
114 | 115 | ||
115 | func->switch_save = 0x10; | 116 | func->switch_save = 0x10; |
116 | 117 | ||
@@ -131,9 +132,8 @@ static struct slot *cpqhp_find_slot(struct controller *ctrl, u8 device) | |||
131 | { | 132 | { |
132 | struct slot *slot = ctrl->slot; | 133 | struct slot *slot = ctrl->slot; |
133 | 134 | ||
134 | while (slot && (slot->device != device)) { | 135 | while (slot && (slot->device != device)) |
135 | slot = slot->next; | 136 | slot = slot->next; |
136 | } | ||
137 | 137 | ||
138 | return slot; | 138 | return slot; |
139 | } | 139 | } |
@@ -152,17 +152,17 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl) | |||
152 | if (!change) | 152 | if (!change) |
153 | return 0; | 153 | return 0; |
154 | 154 | ||
155 | /********************************** | 155 | /* |
156 | * Presence Change | 156 | * Presence Change |
157 | **********************************/ | 157 | */ |
158 | dbg("cpqsbd: Presence/Notify input change.\n"); | 158 | dbg("cpqsbd: Presence/Notify input change.\n"); |
159 | dbg(" Changed bits are 0x%4.4x\n", change ); | 159 | dbg(" Changed bits are 0x%4.4x\n", change ); |
160 | 160 | ||
161 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { | 161 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { |
162 | if (change & (0x0101 << hp_slot)) { | 162 | if (change & (0x0101 << hp_slot)) { |
163 | /********************************** | 163 | /* |
164 | * this one changed. | 164 | * this one changed. |
165 | **********************************/ | 165 | */ |
166 | func = cpqhp_slot_find(ctrl->bus, | 166 | func = cpqhp_slot_find(ctrl->bus, |
167 | (hp_slot + ctrl->slot_device_offset), 0); | 167 | (hp_slot + ctrl->slot_device_offset), 0); |
168 | 168 | ||
@@ -177,22 +177,23 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl) | |||
177 | return 0; | 177 | return 0; |
178 | 178 | ||
179 | /* If the switch closed, must be a button | 179 | /* If the switch closed, must be a button |
180 | * If not in button mode, nevermind */ | 180 | * If not in button mode, nevermind |
181 | */ | ||
181 | if (func->switch_save && (ctrl->push_button == 1)) { | 182 | if (func->switch_save && (ctrl->push_button == 1)) { |
182 | temp_word = ctrl->ctrl_int_comp >> 16; | 183 | temp_word = ctrl->ctrl_int_comp >> 16; |
183 | temp_byte = (temp_word >> hp_slot) & 0x01; | 184 | temp_byte = (temp_word >> hp_slot) & 0x01; |
184 | temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02; | 185 | temp_byte |= (temp_word >> (hp_slot + 7)) & 0x02; |
185 | 186 | ||
186 | if (temp_byte != func->presence_save) { | 187 | if (temp_byte != func->presence_save) { |
187 | /************************************** | 188 | /* |
188 | * button Pressed (doesn't do anything) | 189 | * button Pressed (doesn't do anything) |
189 | **************************************/ | 190 | */ |
190 | dbg("hp_slot %d button pressed\n", hp_slot); | 191 | dbg("hp_slot %d button pressed\n", hp_slot); |
191 | taskInfo->event_type = INT_BUTTON_PRESS; | 192 | taskInfo->event_type = INT_BUTTON_PRESS; |
192 | } else { | 193 | } else { |
193 | /********************************** | 194 | /* |
194 | * button Released - TAKE ACTION!!!! | 195 | * button Released - TAKE ACTION!!!! |
195 | **********************************/ | 196 | */ |
196 | dbg("hp_slot %d button released\n", hp_slot); | 197 | dbg("hp_slot %d button released\n", hp_slot); |
197 | taskInfo->event_type = INT_BUTTON_RELEASE; | 198 | taskInfo->event_type = INT_BUTTON_RELEASE; |
198 | 199 | ||
@@ -210,7 +211,8 @@ static u8 handle_presence_change(u16 change, struct controller * ctrl) | |||
210 | } | 211 | } |
211 | } else { | 212 | } else { |
212 | /* Switch is open, assume a presence change | 213 | /* Switch is open, assume a presence change |
213 | * Save the presence state */ | 214 | * Save the presence state |
215 | */ | ||
214 | temp_word = ctrl->ctrl_int_comp >> 16; | 216 | temp_word = ctrl->ctrl_int_comp >> 16; |
215 | func->presence_save = (temp_word >> hp_slot) & 0x01; | 217 | func->presence_save = (temp_word >> hp_slot) & 0x01; |
216 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; | 218 | func->presence_save |= (temp_word >> (hp_slot + 7)) & 0x02; |
@@ -241,17 +243,17 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl) | |||
241 | if (!change) | 243 | if (!change) |
242 | return 0; | 244 | return 0; |
243 | 245 | ||
244 | /********************************** | 246 | /* |
245 | * power fault | 247 | * power fault |
246 | **********************************/ | 248 | */ |
247 | 249 | ||
248 | info("power fault interrupt\n"); | 250 | info("power fault interrupt\n"); |
249 | 251 | ||
250 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { | 252 | for (hp_slot = 0; hp_slot < 6; hp_slot++) { |
251 | if (change & (0x01 << hp_slot)) { | 253 | if (change & (0x01 << hp_slot)) { |
252 | /********************************** | 254 | /* |
253 | * this one changed. | 255 | * this one changed. |
254 | **********************************/ | 256 | */ |
255 | func = cpqhp_slot_find(ctrl->bus, | 257 | func = cpqhp_slot_find(ctrl->bus, |
256 | (hp_slot + ctrl->slot_device_offset), 0); | 258 | (hp_slot + ctrl->slot_device_offset), 0); |
257 | 259 | ||
@@ -262,16 +264,16 @@ static u8 handle_power_fault(u8 change, struct controller * ctrl) | |||
262 | rc++; | 264 | rc++; |
263 | 265 | ||
264 | if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) { | 266 | if (ctrl->ctrl_int_comp & (0x00000100 << hp_slot)) { |
265 | /********************************** | 267 | /* |
266 | * power fault Cleared | 268 | * power fault Cleared |
267 | **********************************/ | 269 | */ |
268 | func->status = 0x00; | 270 | func->status = 0x00; |
269 | 271 | ||
270 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; | 272 | taskInfo->event_type = INT_POWER_FAULT_CLEAR; |
271 | } else { | 273 | } else { |
272 | /********************************** | 274 | /* |
273 | * power fault | 275 | * power fault |
274 | **********************************/ | 276 | */ |
275 | taskInfo->event_type = INT_POWER_FAULT; | 277 | taskInfo->event_type = INT_POWER_FAULT; |
276 | 278 | ||
277 | if (ctrl->rev < 4) { | 279 | if (ctrl->rev < 4) { |
@@ -432,13 +434,15 @@ static struct pci_resource *do_pre_bridge_resource_split(struct pci_resource **h | |||
432 | 434 | ||
433 | 435 | ||
434 | /* If we got here, there the bridge requires some of the resource, but | 436 | /* If we got here, there the bridge requires some of the resource, but |
435 | * we may be able to split some off of the front */ | 437 | * we may be able to split some off of the front |
438 | */ | ||
436 | 439 | ||
437 | node = *head; | 440 | node = *head; |
438 | 441 | ||
439 | if (node->length & (alignment -1)) { | 442 | if (node->length & (alignment -1)) { |
440 | /* this one isn't an aligned length, so we'll make a new entry | 443 | /* this one isn't an aligned length, so we'll make a new entry |
441 | * and split it up. */ | 444 | * and split it up. |
445 | */ | ||
442 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 446 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
443 | 447 | ||
444 | if (!split_node) | 448 | if (!split_node) |
@@ -544,10 +548,10 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
544 | if (!(*head)) | 548 | if (!(*head)) |
545 | return NULL; | 549 | return NULL; |
546 | 550 | ||
547 | if ( cpqhp_resource_sort_and_combine(head) ) | 551 | if (cpqhp_resource_sort_and_combine(head)) |
548 | return NULL; | 552 | return NULL; |
549 | 553 | ||
550 | if ( sort_by_size(head) ) | 554 | if (sort_by_size(head)) |
551 | return NULL; | 555 | return NULL; |
552 | 556 | ||
553 | for (node = *head; node; node = node->next) { | 557 | for (node = *head; node; node = node->next) { |
@@ -556,7 +560,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
556 | 560 | ||
557 | if (node->base & (size - 1)) { | 561 | if (node->base & (size - 1)) { |
558 | /* this one isn't base aligned properly | 562 | /* this one isn't base aligned properly |
559 | * so we'll make a new entry and split it up */ | 563 | * so we'll make a new entry and split it up |
564 | */ | ||
560 | temp_dword = (node->base | (size-1)) + 1; | 565 | temp_dword = (node->base | (size-1)) + 1; |
561 | 566 | ||
562 | /* Short circuit if adjusted size is too small */ | 567 | /* Short circuit if adjusted size is too small */ |
@@ -581,7 +586,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
581 | /* Don't need to check if too small since we already did */ | 586 | /* Don't need to check if too small since we already did */ |
582 | if (node->length > size) { | 587 | if (node->length > size) { |
583 | /* this one is longer than we need | 588 | /* this one is longer than we need |
584 | * so we'll make a new entry and split it up */ | 589 | * so we'll make a new entry and split it up |
590 | */ | ||
585 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 591 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
586 | 592 | ||
587 | if (!split_node) | 593 | if (!split_node) |
@@ -601,7 +607,8 @@ static struct pci_resource *get_io_resource(struct pci_resource **head, u32 size | |||
601 | continue; | 607 | continue; |
602 | 608 | ||
603 | /* If we got here, then it is the right size | 609 | /* If we got here, then it is the right size |
604 | * Now take it out of the list and break */ | 610 | * Now take it out of the list and break |
611 | */ | ||
605 | if (*head == node) { | 612 | if (*head == node) { |
606 | *head = node->next; | 613 | *head = node->next; |
607 | } else { | 614 | } else { |
@@ -642,14 +649,16 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz | |||
642 | return NULL; | 649 | return NULL; |
643 | 650 | ||
644 | for (max = *head; max; max = max->next) { | 651 | for (max = *head; max; max = max->next) { |
645 | /* If not big enough we could probably just bail, | 652 | /* If not big enough we could probably just bail, |
646 | * instead we'll continue to the next. */ | 653 | * instead we'll continue to the next. |
654 | */ | ||
647 | if (max->length < size) | 655 | if (max->length < size) |
648 | continue; | 656 | continue; |
649 | 657 | ||
650 | if (max->base & (size - 1)) { | 658 | if (max->base & (size - 1)) { |
651 | /* this one isn't base aligned properly | 659 | /* this one isn't base aligned properly |
652 | * so we'll make a new entry and split it up */ | 660 | * so we'll make a new entry and split it up |
661 | */ | ||
653 | temp_dword = (max->base | (size-1)) + 1; | 662 | temp_dword = (max->base | (size-1)) + 1; |
654 | 663 | ||
655 | /* Short circuit if adjusted size is too small */ | 664 | /* Short circuit if adjusted size is too small */ |
@@ -672,7 +681,8 @@ static struct pci_resource *get_max_resource(struct pci_resource **head, u32 siz | |||
672 | 681 | ||
673 | if ((max->base + max->length) & (size - 1)) { | 682 | if ((max->base + max->length) & (size - 1)) { |
674 | /* this one isn't end aligned properly at the top | 683 | /* this one isn't end aligned properly at the top |
675 | * so we'll make a new entry and split it up */ | 684 | * so we'll make a new entry and split it up |
685 | */ | ||
676 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 686 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
677 | 687 | ||
678 | if (!split_node) | 688 | if (!split_node) |
@@ -744,7 +754,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size) | |||
744 | if (node->base & (size - 1)) { | 754 | if (node->base & (size - 1)) { |
745 | dbg("%s: not aligned\n", __func__); | 755 | dbg("%s: not aligned\n", __func__); |
746 | /* this one isn't base aligned properly | 756 | /* this one isn't base aligned properly |
747 | * so we'll make a new entry and split it up */ | 757 | * so we'll make a new entry and split it up |
758 | */ | ||
748 | temp_dword = (node->base | (size-1)) + 1; | 759 | temp_dword = (node->base | (size-1)) + 1; |
749 | 760 | ||
750 | /* Short circuit if adjusted size is too small */ | 761 | /* Short circuit if adjusted size is too small */ |
@@ -769,7 +780,8 @@ static struct pci_resource *get_resource(struct pci_resource **head, u32 size) | |||
769 | if (node->length > size) { | 780 | if (node->length > size) { |
770 | dbg("%s: too big\n", __func__); | 781 | dbg("%s: too big\n", __func__); |
771 | /* this one is longer than we need | 782 | /* this one is longer than we need |
772 | * so we'll make a new entry and split it up */ | 783 | * so we'll make a new entry and split it up |
784 | */ | ||
773 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); | 785 | split_node = kmalloc(sizeof(*split_node), GFP_KERNEL); |
774 | 786 | ||
775 | if (!split_node) | 787 | if (!split_node) |
@@ -886,19 +898,19 @@ irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data) | |||
886 | u32 Diff; | 898 | u32 Diff; |
887 | u32 temp_dword; | 899 | u32 temp_dword; |
888 | 900 | ||
889 | 901 | ||
890 | misc = readw(ctrl->hpc_reg + MISC); | 902 | misc = readw(ctrl->hpc_reg + MISC); |
891 | /*************************************** | 903 | /* |
892 | * Check to see if it was our interrupt | 904 | * Check to see if it was our interrupt |
893 | ***************************************/ | 905 | */ |
894 | if (!(misc & 0x000C)) { | 906 | if (!(misc & 0x000C)) { |
895 | return IRQ_NONE; | 907 | return IRQ_NONE; |
896 | } | 908 | } |
897 | 909 | ||
898 | if (misc & 0x0004) { | 910 | if (misc & 0x0004) { |
899 | /********************************** | 911 | /* |
900 | * Serial Output interrupt Pending | 912 | * Serial Output interrupt Pending |
901 | **********************************/ | 913 | */ |
902 | 914 | ||
903 | /* Clear the interrupt */ | 915 | /* Clear the interrupt */ |
904 | misc |= 0x0004; | 916 | misc |= 0x0004; |
@@ -961,11 +973,8 @@ struct pci_func *cpqhp_slot_create(u8 busnumber) | |||
961 | struct pci_func *next; | 973 | struct pci_func *next; |
962 | 974 | ||
963 | new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL); | 975 | new_slot = kzalloc(sizeof(*new_slot), GFP_KERNEL); |
964 | if (new_slot == NULL) { | 976 | if (new_slot == NULL) |
965 | /* I'm not dead yet! | ||
966 | * You will be. */ | ||
967 | return new_slot; | 977 | return new_slot; |
968 | } | ||
969 | 978 | ||
970 | new_slot->next = NULL; | 979 | new_slot->next = NULL; |
971 | new_slot->configured = 1; | 980 | new_slot->configured = 1; |
@@ -996,10 +1005,8 @@ static int slot_remove(struct pci_func * old_slot) | |||
996 | return 1; | 1005 | return 1; |
997 | 1006 | ||
998 | next = cpqhp_slot_list[old_slot->bus]; | 1007 | next = cpqhp_slot_list[old_slot->bus]; |
999 | 1008 | if (next == NULL) | |
1000 | if (next == NULL) { | ||
1001 | return 1; | 1009 | return 1; |
1002 | } | ||
1003 | 1010 | ||
1004 | if (next == old_slot) { | 1011 | if (next == old_slot) { |
1005 | cpqhp_slot_list[old_slot->bus] = old_slot->next; | 1012 | cpqhp_slot_list[old_slot->bus] = old_slot->next; |
@@ -1008,9 +1015,8 @@ static int slot_remove(struct pci_func * old_slot) | |||
1008 | return 0; | 1015 | return 0; |
1009 | } | 1016 | } |
1010 | 1017 | ||
1011 | while ((next->next != old_slot) && (next->next != NULL)) { | 1018 | while ((next->next != old_slot) && (next->next != NULL)) |
1012 | next = next->next; | 1019 | next = next->next; |
1013 | } | ||
1014 | 1020 | ||
1015 | if (next->next == old_slot) { | 1021 | if (next->next == old_slot) { |
1016 | next->next = old_slot->next; | 1022 | next->next = old_slot->next; |
@@ -1040,9 +1046,8 @@ static int bridge_slot_remove(struct pci_func *bridge) | |||
1040 | for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) { | 1046 | for (tempBus = secondaryBus; tempBus <= subordinateBus; tempBus++) { |
1041 | next = cpqhp_slot_list[tempBus]; | 1047 | next = cpqhp_slot_list[tempBus]; |
1042 | 1048 | ||
1043 | while (!slot_remove(next)) { | 1049 | while (!slot_remove(next)) |
1044 | next = cpqhp_slot_list[tempBus]; | 1050 | next = cpqhp_slot_list[tempBus]; |
1045 | } | ||
1046 | } | 1051 | } |
1047 | 1052 | ||
1048 | next = cpqhp_slot_list[bridge->bus]; | 1053 | next = cpqhp_slot_list[bridge->bus]; |
@@ -1130,39 +1135,43 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1130 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); | 1135 | u8 slot_power = readb(ctrl->hpc_reg + SLOT_POWER); |
1131 | u16 reg16; | 1136 | u16 reg16; |
1132 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); | 1137 | u32 leds = readl(ctrl->hpc_reg + LED_CONTROL); |
1133 | 1138 | ||
1134 | if (ctrl->speed == adapter_speed) | 1139 | if (ctrl->speed == adapter_speed) |
1135 | return 0; | 1140 | return 0; |
1136 | 1141 | ||
1137 | /* We don't allow freq/mode changes if we find another adapter running | 1142 | /* We don't allow freq/mode changes if we find another adapter running |
1138 | * in another slot on this controller */ | 1143 | * in another slot on this controller |
1144 | */ | ||
1139 | for(slot = ctrl->slot; slot; slot = slot->next) { | 1145 | for(slot = ctrl->slot; slot; slot = slot->next) { |
1140 | if (slot->device == (hp_slot + ctrl->slot_device_offset)) | 1146 | if (slot->device == (hp_slot + ctrl->slot_device_offset)) |
1141 | continue; | 1147 | continue; |
1142 | if (!slot->hotplug_slot || !slot->hotplug_slot->info) | 1148 | if (!slot->hotplug_slot || !slot->hotplug_slot->info) |
1143 | continue; | 1149 | continue; |
1144 | if (slot->hotplug_slot->info->adapter_status == 0) | 1150 | if (slot->hotplug_slot->info->adapter_status == 0) |
1145 | continue; | 1151 | continue; |
1146 | /* If another adapter is running on the same segment but at a | 1152 | /* If another adapter is running on the same segment but at a |
1147 | * lower speed/mode, we allow the new adapter to function at | 1153 | * lower speed/mode, we allow the new adapter to function at |
1148 | * this rate if supported */ | 1154 | * this rate if supported |
1149 | if (ctrl->speed < adapter_speed) | 1155 | */ |
1156 | if (ctrl->speed < adapter_speed) | ||
1150 | return 0; | 1157 | return 0; |
1151 | 1158 | ||
1152 | return 1; | 1159 | return 1; |
1153 | } | 1160 | } |
1154 | 1161 | ||
1155 | /* If the controller doesn't support freq/mode changes and the | 1162 | /* If the controller doesn't support freq/mode changes and the |
1156 | * controller is running at a higher mode, we bail */ | 1163 | * controller is running at a higher mode, we bail |
1164 | */ | ||
1157 | if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) | 1165 | if ((ctrl->speed > adapter_speed) && (!ctrl->pcix_speed_capability)) |
1158 | return 1; | 1166 | return 1; |
1159 | 1167 | ||
1160 | /* But we allow the adapter to run at a lower rate if possible */ | 1168 | /* But we allow the adapter to run at a lower rate if possible */ |
1161 | if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) | 1169 | if ((ctrl->speed < adapter_speed) && (!ctrl->pcix_speed_capability)) |
1162 | return 0; | 1170 | return 0; |
1163 | 1171 | ||
1164 | /* We try to set the max speed supported by both the adapter and | 1172 | /* We try to set the max speed supported by both the adapter and |
1165 | * controller */ | 1173 | * controller |
1174 | */ | ||
1166 | if (ctrl->speed_capability < adapter_speed) { | 1175 | if (ctrl->speed_capability < adapter_speed) { |
1167 | if (ctrl->speed == ctrl->speed_capability) | 1176 | if (ctrl->speed == ctrl->speed_capability) |
1168 | return 0; | 1177 | return 0; |
@@ -1171,22 +1180,22 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1171 | 1180 | ||
1172 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); | 1181 | writel(0x0L, ctrl->hpc_reg + LED_CONTROL); |
1173 | writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE); | 1182 | writeb(0x00, ctrl->hpc_reg + SLOT_ENABLE); |
1174 | 1183 | ||
1175 | set_SOGO(ctrl); | 1184 | set_SOGO(ctrl); |
1176 | wait_for_ctrl_irq(ctrl); | 1185 | wait_for_ctrl_irq(ctrl); |
1177 | 1186 | ||
1178 | if (adapter_speed != PCI_SPEED_133MHz_PCIX) | 1187 | if (adapter_speed != PCI_SPEED_133MHz_PCIX) |
1179 | reg = 0xF5; | 1188 | reg = 0xF5; |
1180 | else | 1189 | else |
1181 | reg = 0xF4; | 1190 | reg = 0xF4; |
1182 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); | 1191 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); |
1183 | 1192 | ||
1184 | reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ); | 1193 | reg16 = readw(ctrl->hpc_reg + NEXT_CURR_FREQ); |
1185 | reg16 &= ~0x000F; | 1194 | reg16 &= ~0x000F; |
1186 | switch(adapter_speed) { | 1195 | switch(adapter_speed) { |
1187 | case(PCI_SPEED_133MHz_PCIX): | 1196 | case(PCI_SPEED_133MHz_PCIX): |
1188 | reg = 0x75; | 1197 | reg = 0x75; |
1189 | reg16 |= 0xB; | 1198 | reg16 |= 0xB; |
1190 | break; | 1199 | break; |
1191 | case(PCI_SPEED_100MHz_PCIX): | 1200 | case(PCI_SPEED_100MHz_PCIX): |
1192 | reg = 0x74; | 1201 | reg = 0x74; |
@@ -1203,48 +1212,48 @@ static u8 set_controller_speed(struct controller *ctrl, u8 adapter_speed, u8 hp_ | |||
1203 | default: /* 33MHz PCI 2.2 */ | 1212 | default: /* 33MHz PCI 2.2 */ |
1204 | reg = 0x71; | 1213 | reg = 0x71; |
1205 | break; | 1214 | break; |
1206 | 1215 | ||
1207 | } | 1216 | } |
1208 | reg16 |= 0xB << 12; | 1217 | reg16 |= 0xB << 12; |
1209 | writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ); | 1218 | writew(reg16, ctrl->hpc_reg + NEXT_CURR_FREQ); |
1210 | 1219 | ||
1211 | mdelay(5); | 1220 | mdelay(5); |
1212 | 1221 | ||
1213 | /* Reenable interrupts */ | 1222 | /* Reenable interrupts */ |
1214 | writel(0, ctrl->hpc_reg + INT_MASK); | 1223 | writel(0, ctrl->hpc_reg + INT_MASK); |
1215 | 1224 | ||
1216 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); | 1225 | pci_write_config_byte(ctrl->pci_dev, 0x41, reg); |
1217 | 1226 | ||
1218 | /* Restart state machine */ | 1227 | /* Restart state machine */ |
1219 | reg = ~0xF; | 1228 | reg = ~0xF; |
1220 | pci_read_config_byte(ctrl->pci_dev, 0x43, ®); | 1229 | pci_read_config_byte(ctrl->pci_dev, 0x43, ®); |
1221 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); | 1230 | pci_write_config_byte(ctrl->pci_dev, 0x43, reg); |
1222 | 1231 | ||
1223 | /* Only if mode change...*/ | 1232 | /* Only if mode change...*/ |
1224 | if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || | 1233 | if (((ctrl->speed == PCI_SPEED_66MHz) && (adapter_speed == PCI_SPEED_66MHz_PCIX)) || |
1225 | ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) | 1234 | ((ctrl->speed == PCI_SPEED_66MHz_PCIX) && (adapter_speed == PCI_SPEED_66MHz))) |
1226 | set_SOGO(ctrl); | 1235 | set_SOGO(ctrl); |
1227 | 1236 | ||
1228 | wait_for_ctrl_irq(ctrl); | 1237 | wait_for_ctrl_irq(ctrl); |
1229 | mdelay(1100); | 1238 | mdelay(1100); |
1230 | 1239 | ||
1231 | /* Restore LED/Slot state */ | 1240 | /* Restore LED/Slot state */ |
1232 | writel(leds, ctrl->hpc_reg + LED_CONTROL); | 1241 | writel(leds, ctrl->hpc_reg + LED_CONTROL); |
1233 | writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE); | 1242 | writeb(slot_power, ctrl->hpc_reg + SLOT_ENABLE); |
1234 | 1243 | ||
1235 | set_SOGO(ctrl); | 1244 | set_SOGO(ctrl); |
1236 | wait_for_ctrl_irq(ctrl); | 1245 | wait_for_ctrl_irq(ctrl); |
1237 | 1246 | ||
1238 | ctrl->speed = adapter_speed; | 1247 | ctrl->speed = adapter_speed; |
1239 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 1248 | slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
1240 | 1249 | ||
1241 | info("Successfully changed frequency/mode for adapter in slot %d\n", | 1250 | info("Successfully changed frequency/mode for adapter in slot %d\n", |
1242 | slot->number); | 1251 | slot->number); |
1243 | return 0; | 1252 | return 0; |
1244 | } | 1253 | } |
1245 | 1254 | ||
1246 | /* the following routines constitute the bulk of the | 1255 | /* the following routines constitute the bulk of the |
1247 | hotplug controller logic | 1256 | * hotplug controller logic |
1248 | */ | 1257 | */ |
1249 | 1258 | ||
1250 | 1259 | ||
@@ -1268,17 +1277,17 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1268 | 1277 | ||
1269 | hp_slot = func->device - ctrl->slot_device_offset; | 1278 | hp_slot = func->device - ctrl->slot_device_offset; |
1270 | 1279 | ||
1271 | if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) { | 1280 | /* |
1272 | /********************************** | 1281 | * The switch is open. |
1273 | * The switch is open. | 1282 | */ |
1274 | **********************************/ | 1283 | if (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot)) |
1275 | rc = INTERLOCK_OPEN; | 1284 | rc = INTERLOCK_OPEN; |
1276 | } else if (is_slot_enabled (ctrl, hp_slot)) { | 1285 | /* |
1277 | /********************************** | 1286 | * The board is already on |
1278 | * The board is already on | 1287 | */ |
1279 | **********************************/ | 1288 | else if (is_slot_enabled (ctrl, hp_slot)) |
1280 | rc = CARD_FUNCTIONING; | 1289 | rc = CARD_FUNCTIONING; |
1281 | } else { | 1290 | else { |
1282 | mutex_lock(&ctrl->crit_sect); | 1291 | mutex_lock(&ctrl->crit_sect); |
1283 | 1292 | ||
1284 | /* turn on board without attaching to the bus */ | 1293 | /* turn on board without attaching to the bus */ |
@@ -1299,7 +1308,7 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1299 | 1308 | ||
1300 | /* Wait for SOBS to be unset */ | 1309 | /* Wait for SOBS to be unset */ |
1301 | wait_for_ctrl_irq (ctrl); | 1310 | wait_for_ctrl_irq (ctrl); |
1302 | 1311 | ||
1303 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1312 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1304 | if (ctrl->speed != adapter_speed) | 1313 | if (ctrl->speed != adapter_speed) |
1305 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1314 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
@@ -1352,7 +1361,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1352 | * Get slot won't work for devices behind | 1361 | * Get slot won't work for devices behind |
1353 | * bridges, but in this case it will always be | 1362 | * bridges, but in this case it will always be |
1354 | * called for the "base" bus/dev/func of an | 1363 | * called for the "base" bus/dev/func of an |
1355 | * adapter. */ | 1364 | * adapter. |
1365 | */ | ||
1356 | 1366 | ||
1357 | mutex_lock(&ctrl->crit_sect); | 1367 | mutex_lock(&ctrl->crit_sect); |
1358 | 1368 | ||
@@ -1377,7 +1387,8 @@ static u32 board_replaced(struct pci_func *func, struct controller *ctrl) | |||
1377 | 1387 | ||
1378 | * Get slot won't work for devices behind bridges, but | 1388 | * Get slot won't work for devices behind bridges, but |
1379 | * in this case it will always be called for the "base" | 1389 | * in this case it will always be called for the "base" |
1380 | * bus/dev/func of an adapter. */ | 1390 | * bus/dev/func of an adapter. |
1391 | */ | ||
1381 | 1392 | ||
1382 | mutex_lock(&ctrl->crit_sect); | 1393 | mutex_lock(&ctrl->crit_sect); |
1383 | 1394 | ||
@@ -1434,7 +1445,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1434 | wait_for_ctrl_irq (ctrl); | 1445 | wait_for_ctrl_irq (ctrl); |
1435 | 1446 | ||
1436 | /* Change bits in slot power register to force another shift out | 1447 | /* Change bits in slot power register to force another shift out |
1437 | * NOTE: this is to work around the timer bug */ | 1448 | * NOTE: this is to work around the timer bug |
1449 | */ | ||
1438 | temp_byte = readb(ctrl->hpc_reg + SLOT_POWER); | 1450 | temp_byte = readb(ctrl->hpc_reg + SLOT_POWER); |
1439 | writeb(0x00, ctrl->hpc_reg + SLOT_POWER); | 1451 | writeb(0x00, ctrl->hpc_reg + SLOT_POWER); |
1440 | writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER); | 1452 | writeb(temp_byte, ctrl->hpc_reg + SLOT_POWER); |
@@ -1443,12 +1455,12 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1443 | 1455 | ||
1444 | /* Wait for SOBS to be unset */ | 1456 | /* Wait for SOBS to be unset */ |
1445 | wait_for_ctrl_irq (ctrl); | 1457 | wait_for_ctrl_irq (ctrl); |
1446 | 1458 | ||
1447 | adapter_speed = get_adapter_speed(ctrl, hp_slot); | 1459 | adapter_speed = get_adapter_speed(ctrl, hp_slot); |
1448 | if (ctrl->speed != adapter_speed) | 1460 | if (ctrl->speed != adapter_speed) |
1449 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) | 1461 | if (set_controller_speed(ctrl, adapter_speed, hp_slot)) |
1450 | rc = WRONG_BUS_FREQUENCY; | 1462 | rc = WRONG_BUS_FREQUENCY; |
1451 | 1463 | ||
1452 | /* turn off board without attaching to the bus */ | 1464 | /* turn off board without attaching to the bus */ |
1453 | disable_slot_power (ctrl, hp_slot); | 1465 | disable_slot_power (ctrl, hp_slot); |
1454 | 1466 | ||
@@ -1461,7 +1473,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1461 | 1473 | ||
1462 | if (rc) | 1474 | if (rc) |
1463 | return rc; | 1475 | return rc; |
1464 | 1476 | ||
1465 | p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); | 1477 | p_slot = cpqhp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset); |
1466 | 1478 | ||
1467 | /* turn on board and blink green LED */ | 1479 | /* turn on board and blink green LED */ |
@@ -1521,7 +1533,7 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1521 | } | 1533 | } |
1522 | 1534 | ||
1523 | /* All F's is an empty slot or an invalid board */ | 1535 | /* All F's is an empty slot or an invalid board */ |
1524 | if (temp_register != 0xFFFFFFFF) { /* Check for a board in the slot */ | 1536 | if (temp_register != 0xFFFFFFFF) { |
1525 | res_lists.io_head = ctrl->io_head; | 1537 | res_lists.io_head = ctrl->io_head; |
1526 | res_lists.mem_head = ctrl->mem_head; | 1538 | res_lists.mem_head = ctrl->mem_head; |
1527 | res_lists.p_mem_head = ctrl->p_mem_head; | 1539 | res_lists.p_mem_head = ctrl->p_mem_head; |
@@ -1570,9 +1582,8 @@ static u32 board_added(struct pci_func *func, struct controller *ctrl) | |||
1570 | index = 0; | 1582 | index = 0; |
1571 | do { | 1583 | do { |
1572 | new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++); | 1584 | new_slot = cpqhp_slot_find(ctrl->bus, func->device, index++); |
1573 | if (new_slot && !new_slot->pci_dev) { | 1585 | if (new_slot && !new_slot->pci_dev) |
1574 | cpqhp_configure_device(ctrl, new_slot); | 1586 | cpqhp_configure_device(ctrl, new_slot); |
1575 | } | ||
1576 | } while (new_slot); | 1587 | } while (new_slot); |
1577 | 1588 | ||
1578 | mutex_lock(&ctrl->crit_sect); | 1589 | mutex_lock(&ctrl->crit_sect); |
@@ -1859,12 +1870,12 @@ static void interrupt_event_handler(struct controller *ctrl) | |||
1859 | info(msg_button_on, p_slot->number); | 1870 | info(msg_button_on, p_slot->number); |
1860 | } | 1871 | } |
1861 | mutex_lock(&ctrl->crit_sect); | 1872 | mutex_lock(&ctrl->crit_sect); |
1862 | 1873 | ||
1863 | dbg("blink green LED and turn off amber\n"); | 1874 | dbg("blink green LED and turn off amber\n"); |
1864 | 1875 | ||
1865 | amber_LED_off (ctrl, hp_slot); | 1876 | amber_LED_off (ctrl, hp_slot); |
1866 | green_LED_blink (ctrl, hp_slot); | 1877 | green_LED_blink (ctrl, hp_slot); |
1867 | 1878 | ||
1868 | set_SOGO(ctrl); | 1879 | set_SOGO(ctrl); |
1869 | 1880 | ||
1870 | /* Wait for SOBS to be unset */ | 1881 | /* Wait for SOBS to be unset */ |
@@ -1958,7 +1969,7 @@ void cpqhp_pushbutton_thread(unsigned long slot) | |||
1958 | if (cpqhp_process_SI(ctrl, func) != 0) { | 1969 | if (cpqhp_process_SI(ctrl, func) != 0) { |
1959 | amber_LED_on(ctrl, hp_slot); | 1970 | amber_LED_on(ctrl, hp_slot); |
1960 | green_LED_off(ctrl, hp_slot); | 1971 | green_LED_off(ctrl, hp_slot); |
1961 | 1972 | ||
1962 | set_SOGO(ctrl); | 1973 | set_SOGO(ctrl); |
1963 | 1974 | ||
1964 | /* Wait for SOBS to be unset */ | 1975 | /* Wait for SOBS to be unset */ |
@@ -2079,7 +2090,7 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func) | |||
2079 | struct pci_bus *pci_bus = ctrl->pci_bus; | 2090 | struct pci_bus *pci_bus = ctrl->pci_bus; |
2080 | int physical_slot=0; | 2091 | int physical_slot=0; |
2081 | 2092 | ||
2082 | device = func->device; | 2093 | device = func->device; |
2083 | func = cpqhp_slot_find(ctrl->bus, device, index++); | 2094 | func = cpqhp_slot_find(ctrl->bus, device, index++); |
2084 | p_slot = cpqhp_find_slot(ctrl, device); | 2095 | p_slot = cpqhp_find_slot(ctrl, device); |
2085 | if (p_slot) { | 2096 | if (p_slot) { |
@@ -2113,9 +2124,8 @@ int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func) | |||
2113 | 2124 | ||
2114 | /* If the VGA Enable bit is set, remove isn't | 2125 | /* If the VGA Enable bit is set, remove isn't |
2115 | * supported */ | 2126 | * supported */ |
2116 | if (BCR & PCI_BRIDGE_CTL_VGA) { | 2127 | if (BCR & PCI_BRIDGE_CTL_VGA) |
2117 | rc = REMOVE_NOT_SUPPORTED; | 2128 | rc = REMOVE_NOT_SUPPORTED; |
2118 | } | ||
2119 | } | 2129 | } |
2120 | } | 2130 | } |
2121 | 2131 | ||
@@ -2183,67 +2193,67 @@ int cpqhp_hardware_test(struct controller *ctrl, int test_num) | |||
2183 | num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f; | 2193 | num_of_slots = readb(ctrl->hpc_reg + SLOT_MASK) & 0x0f; |
2184 | 2194 | ||
2185 | switch (test_num) { | 2195 | switch (test_num) { |
2186 | case 1: | 2196 | case 1: |
2187 | /* Do stuff here! */ | 2197 | /* Do stuff here! */ |
2188 | 2198 | ||
2189 | /* Do that funky LED thing */ | 2199 | /* Do that funky LED thing */ |
2190 | /* so we can restore them later */ | 2200 | /* so we can restore them later */ |
2191 | save_LED = readl(ctrl->hpc_reg + LED_CONTROL); | 2201 | save_LED = readl(ctrl->hpc_reg + LED_CONTROL); |
2192 | work_LED = 0x01010101; | 2202 | work_LED = 0x01010101; |
2193 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2203 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2194 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2204 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2195 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2205 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2196 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2206 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2197 | 2207 | ||
2198 | work_LED = 0x01010000; | 2208 | work_LED = 0x01010000; |
2199 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2209 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2200 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2210 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2201 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2211 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2202 | work_LED = 0x00000101; | 2212 | work_LED = 0x00000101; |
2203 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2213 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2204 | switch_leds(ctrl, num_of_slots, &work_LED, 0); | 2214 | switch_leds(ctrl, num_of_slots, &work_LED, 0); |
2205 | switch_leds(ctrl, num_of_slots, &work_LED, 1); | 2215 | switch_leds(ctrl, num_of_slots, &work_LED, 1); |
2216 | |||
2217 | work_LED = 0x01010000; | ||
2218 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | ||
2219 | for (loop = 0; loop < num_of_slots; loop++) { | ||
2220 | set_SOGO(ctrl); | ||
2206 | 2221 | ||
2207 | work_LED = 0x01010000; | 2222 | /* Wait for SOGO interrupt */ |
2208 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2223 | wait_for_ctrl_irq (ctrl); |
2209 | for (loop = 0; loop < num_of_slots; loop++) { | ||
2210 | set_SOGO(ctrl); | ||
2211 | 2224 | ||
2212 | /* Wait for SOGO interrupt */ | 2225 | /* Get ready for next iteration */ |
2213 | wait_for_ctrl_irq (ctrl); | 2226 | long_delay((3*HZ)/10); |
2227 | work_LED = work_LED >> 16; | ||
2228 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | ||
2214 | 2229 | ||
2215 | /* Get ready for next iteration */ | 2230 | set_SOGO(ctrl); |
2216 | long_delay((3*HZ)/10); | ||
2217 | work_LED = work_LED >> 16; | ||
2218 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | ||
2219 | |||
2220 | set_SOGO(ctrl); | ||
2221 | 2231 | ||
2222 | /* Wait for SOGO interrupt */ | 2232 | /* Wait for SOGO interrupt */ |
2223 | wait_for_ctrl_irq (ctrl); | 2233 | wait_for_ctrl_irq (ctrl); |
2224 | 2234 | ||
2225 | /* Get ready for next iteration */ | 2235 | /* Get ready for next iteration */ |
2226 | long_delay((3*HZ)/10); | 2236 | long_delay((3*HZ)/10); |
2227 | work_LED = work_LED << 16; | 2237 | work_LED = work_LED << 16; |
2228 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2238 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2229 | work_LED = work_LED << 1; | 2239 | work_LED = work_LED << 1; |
2230 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); | 2240 | writel(work_LED, ctrl->hpc_reg + LED_CONTROL); |
2231 | } | 2241 | } |
2232 | 2242 | ||
2233 | /* put it back the way it was */ | 2243 | /* put it back the way it was */ |
2234 | writel(save_LED, ctrl->hpc_reg + LED_CONTROL); | 2244 | writel(save_LED, ctrl->hpc_reg + LED_CONTROL); |
2235 | 2245 | ||
2236 | set_SOGO(ctrl); | 2246 | set_SOGO(ctrl); |
2237 | 2247 | ||
2238 | /* Wait for SOBS to be unset */ | 2248 | /* Wait for SOBS to be unset */ |
2239 | wait_for_ctrl_irq (ctrl); | 2249 | wait_for_ctrl_irq (ctrl); |
2240 | break; | 2250 | break; |
2241 | case 2: | 2251 | case 2: |
2242 | /* Do other stuff here! */ | 2252 | /* Do other stuff here! */ |
2243 | break; | 2253 | break; |
2244 | case 3: | 2254 | case 3: |
2245 | /* and more... */ | 2255 | /* and more... */ |
2246 | break; | 2256 | break; |
2247 | } | 2257 | } |
2248 | return 0; | 2258 | return 0; |
2249 | } | 2259 | } |
@@ -2312,9 +2322,9 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func | |||
2312 | while ((function < max_functions) && (!stop_it)) { | 2322 | while ((function < max_functions) && (!stop_it)) { |
2313 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID); | 2323 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(func->device, function), 0x00, &ID); |
2314 | 2324 | ||
2315 | if (ID == 0xFFFFFFFF) { /* There's nothing there. */ | 2325 | if (ID == 0xFFFFFFFF) { |
2316 | function++; | 2326 | function++; |
2317 | } else { /* There's something there */ | 2327 | } else { |
2318 | /* Setup slot structure. */ | 2328 | /* Setup slot structure. */ |
2319 | new_slot = cpqhp_slot_create(func->bus); | 2329 | new_slot = cpqhp_slot_create(func->bus); |
2320 | 2330 | ||
@@ -2339,8 +2349,8 @@ static u32 configure_new_device(struct controller * ctrl, struct pci_func * func | |||
2339 | 2349 | ||
2340 | 2350 | ||
2341 | /* | 2351 | /* |
2342 | Configuration logic that involves the hotplug data structures and | 2352 | * Configuration logic that involves the hotplug data structures and |
2343 | their bookkeeping | 2353 | * their bookkeeping |
2344 | */ | 2354 | */ |
2345 | 2355 | ||
2346 | 2356 | ||
@@ -2393,7 +2403,7 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2393 | if (rc) | 2403 | if (rc) |
2394 | return rc; | 2404 | return rc; |
2395 | 2405 | ||
2396 | if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { /* PCI-PCI Bridge */ | 2406 | if ((temp_byte & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
2397 | /* set Primary bus */ | 2407 | /* set Primary bus */ |
2398 | dbg("set Primary bus = %d\n", func->bus); | 2408 | dbg("set Primary bus = %d\n", func->bus); |
2399 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus); | 2409 | rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_PRIMARY_BUS, func->bus); |
@@ -2484,7 +2494,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2484 | temp_resources.irqs = &irqs; | 2494 | temp_resources.irqs = &irqs; |
2485 | 2495 | ||
2486 | /* Make copies of the nodes we are going to pass down so that | 2496 | /* Make copies of the nodes we are going to pass down so that |
2487 | * if there is a problem,we can just use these to free resources */ | 2497 | * if there is a problem,we can just use these to free resources |
2498 | */ | ||
2488 | hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL); | 2499 | hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL); |
2489 | hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL); | 2500 | hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL); |
2490 | hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL); | 2501 | hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL); |
@@ -2556,7 +2567,8 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2556 | temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; | 2567 | temp_word = (p_mem_node->base + p_mem_node->length - 1) >> 16; |
2557 | rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); | 2568 | rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word); |
2558 | 2569 | ||
2559 | /* Adjust this to compensate for extra adjustment in first loop */ | 2570 | /* Adjust this to compensate for extra adjustment in first loop |
2571 | */ | ||
2560 | irqs.barber_pole--; | 2572 | irqs.barber_pole--; |
2561 | 2573 | ||
2562 | rc = 0; | 2574 | rc = 0; |
@@ -2917,27 +2929,26 @@ static int configure_new_function(struct controller *ctrl, struct pci_func *func | |||
2917 | } /* End of base register loop */ | 2929 | } /* End of base register loop */ |
2918 | if (cpqhp_legacy_mode) { | 2930 | if (cpqhp_legacy_mode) { |
2919 | /* Figure out which interrupt pin this function uses */ | 2931 | /* Figure out which interrupt pin this function uses */ |
2920 | rc = pci_bus_read_config_byte (pci_bus, devfn, | 2932 | rc = pci_bus_read_config_byte (pci_bus, devfn, |
2921 | PCI_INTERRUPT_PIN, &temp_byte); | 2933 | PCI_INTERRUPT_PIN, &temp_byte); |
2922 | 2934 | ||
2923 | /* If this function needs an interrupt and we are behind | 2935 | /* If this function needs an interrupt and we are behind |
2924 | * a bridge and the pin is tied to something that's | 2936 | * a bridge and the pin is tied to something that's |
2925 | * alread mapped, set this one the same */ | 2937 | * alread mapped, set this one the same */ |
2926 | if (temp_byte && resources->irqs && | 2938 | if (temp_byte && resources->irqs && |
2927 | (resources->irqs->valid_INT & | 2939 | (resources->irqs->valid_INT & |
2928 | (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) { | 2940 | (0x01 << ((temp_byte + resources->irqs->barber_pole - 1) & 0x03)))) { |
2929 | /* We have to share with something already set up */ | 2941 | /* We have to share with something already set up */ |
2930 | IRQ = resources->irqs->interrupt[(temp_byte + | 2942 | IRQ = resources->irqs->interrupt[(temp_byte + |
2931 | resources->irqs->barber_pole - 1) & 0x03]; | 2943 | resources->irqs->barber_pole - 1) & 0x03]; |
2932 | } else { | 2944 | } else { |
2933 | /* Program IRQ based on card type */ | 2945 | /* Program IRQ based on card type */ |
2934 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); | 2946 | rc = pci_bus_read_config_byte (pci_bus, devfn, 0x0B, &class_code); |
2935 | 2947 | ||
2936 | if (class_code == PCI_BASE_CLASS_STORAGE) { | 2948 | if (class_code == PCI_BASE_CLASS_STORAGE) |
2937 | IRQ = cpqhp_disk_irq; | 2949 | IRQ = cpqhp_disk_irq; |
2938 | } else { | 2950 | else |
2939 | IRQ = cpqhp_nic_irq; | 2951 | IRQ = cpqhp_nic_irq; |
2940 | } | ||
2941 | } | 2952 | } |
2942 | 2953 | ||
2943 | /* IRQ Line */ | 2954 | /* IRQ Line */ |
diff --git a/drivers/pci/hotplug/cpqphp_nvram.c b/drivers/pci/hotplug/cpqphp_nvram.c index cb174888002b..76ba8a1c774d 100644 --- a/drivers/pci/hotplug/cpqphp_nvram.c +++ b/drivers/pci/hotplug/cpqphp_nvram.c | |||
@@ -94,12 +94,13 @@ static u8 evbuffer[1024]; | |||
94 | 94 | ||
95 | static void __iomem *compaq_int15_entry_point; | 95 | static void __iomem *compaq_int15_entry_point; |
96 | 96 | ||
97 | static spinlock_t int15_lock; /* lock for ordering int15_bios_call() */ | 97 | /* lock for ordering int15_bios_call() */ |
98 | static spinlock_t int15_lock; | ||
98 | 99 | ||
99 | 100 | ||
100 | /* This is a series of function that deals with | 101 | /* This is a series of function that deals with |
101 | setting & getting the hotplug resource table in some environment variable. | 102 | * setting & getting the hotplug resource table in some environment variable. |
102 | */ | 103 | */ |
103 | 104 | ||
104 | /* | 105 | /* |
105 | * We really shouldn't be doing this unless there is a _very_ good reason to!!! | 106 | * We really shouldn't be doing this unless there is a _very_ good reason to!!! |
@@ -113,7 +114,7 @@ static u32 add_byte( u32 **p_buffer, u8 value, u32 *used, u32 *avail) | |||
113 | 114 | ||
114 | if ((*used + 1) > *avail) | 115 | if ((*used + 1) > *avail) |
115 | return(1); | 116 | return(1); |
116 | 117 | ||
117 | *((u8*)*p_buffer) = value; | 118 | *((u8*)*p_buffer) = value; |
118 | tByte = (u8**)p_buffer; | 119 | tByte = (u8**)p_buffer; |
119 | (*tByte)++; | 120 | (*tByte)++; |
@@ -170,10 +171,10 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size) | |||
170 | unsigned long flags; | 171 | unsigned long flags; |
171 | int op = operation; | 172 | int op = operation; |
172 | int ret_val; | 173 | int ret_val; |
173 | 174 | ||
174 | if (!compaq_int15_entry_point) | 175 | if (!compaq_int15_entry_point) |
175 | return -ENODEV; | 176 | return -ENODEV; |
176 | 177 | ||
177 | spin_lock_irqsave(&int15_lock, flags); | 178 | spin_lock_irqsave(&int15_lock, flags); |
178 | __asm__ ( | 179 | __asm__ ( |
179 | "xorl %%ebx,%%ebx\n" \ | 180 | "xorl %%ebx,%%ebx\n" \ |
@@ -187,7 +188,7 @@ static u32 access_EV (u16 operation, u8 *ev_name, u8 *buffer, u32 *buf_size) | |||
187 | "D" (buffer), "m" (compaq_int15_entry_point) | 188 | "D" (buffer), "m" (compaq_int15_entry_point) |
188 | : "%ebx", "%edx"); | 189 | : "%ebx", "%edx"); |
189 | spin_unlock_irqrestore(&int15_lock, flags); | 190 | spin_unlock_irqrestore(&int15_lock, flags); |
190 | 191 | ||
191 | return((ret_val & 0xFF00) >> 8); | 192 | return((ret_val & 0xFF00) >> 8); |
192 | } | 193 | } |
193 | 194 | ||
@@ -210,14 +211,16 @@ static int load_HRT (void __iomem *rom_start) | |||
210 | 211 | ||
211 | available = 1024; | 212 | available = 1024; |
212 | 213 | ||
213 | // Now load the EV | 214 | /* Now load the EV */ |
214 | temp_dword = available; | 215 | temp_dword = available; |
215 | 216 | ||
216 | rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword); | 217 | rc = access_EV(READ_EV, "CQTHPS", evbuffer, &temp_dword); |
217 | 218 | ||
218 | evbuffer_length = temp_dword; | 219 | evbuffer_length = temp_dword; |
219 | 220 | ||
220 | // We're maintaining the resource lists so write FF to invalidate old info | 221 | /* We're maintaining the resource lists so write FF to invalidate old |
222 | * info | ||
223 | */ | ||
221 | temp_dword = 1; | 224 | temp_dword = 1; |
222 | 225 | ||
223 | rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword); | 226 | rc = access_EV(WRITE_EV, "CQTHPS", &temp_byte, &temp_dword); |
@@ -263,13 +266,13 @@ static u32 store_HRT (void __iomem *rom_start) | |||
263 | p_EV_header = (struct ev_hrt_header *) pFill; | 266 | p_EV_header = (struct ev_hrt_header *) pFill; |
264 | 267 | ||
265 | ctrl = cpqhp_ctrl_list; | 268 | ctrl = cpqhp_ctrl_list; |
266 | 269 | ||
267 | // The revision of this structure | 270 | /* The revision of this structure */ |
268 | rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available); | 271 | rc = add_byte( &pFill, 1 + ctrl->push_flag, &usedbytes, &available); |
269 | if (rc) | 272 | if (rc) |
270 | return(rc); | 273 | return(rc); |
271 | 274 | ||
272 | // The number of controllers | 275 | /* The number of controllers */ |
273 | rc = add_byte( &pFill, 1, &usedbytes, &available); | 276 | rc = add_byte( &pFill, 1, &usedbytes, &available); |
274 | if (rc) | 277 | if (rc) |
275 | return(rc); | 278 | return(rc); |
@@ -279,27 +282,27 @@ static u32 store_HRT (void __iomem *rom_start) | |||
279 | 282 | ||
280 | numCtrl++; | 283 | numCtrl++; |
281 | 284 | ||
282 | // The bus number | 285 | /* The bus number */ |
283 | rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available); | 286 | rc = add_byte( &pFill, ctrl->bus, &usedbytes, &available); |
284 | if (rc) | 287 | if (rc) |
285 | return(rc); | 288 | return(rc); |
286 | 289 | ||
287 | // The device Number | 290 | /* The device Number */ |
288 | rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available); | 291 | rc = add_byte( &pFill, PCI_SLOT(ctrl->pci_dev->devfn), &usedbytes, &available); |
289 | if (rc) | 292 | if (rc) |
290 | return(rc); | 293 | return(rc); |
291 | 294 | ||
292 | // The function Number | 295 | /* The function Number */ |
293 | rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available); | 296 | rc = add_byte( &pFill, PCI_FUNC(ctrl->pci_dev->devfn), &usedbytes, &available); |
294 | if (rc) | 297 | if (rc) |
295 | return(rc); | 298 | return(rc); |
296 | 299 | ||
297 | // Skip the number of available entries | 300 | /* Skip the number of available entries */ |
298 | rc = add_dword( &pFill, 0, &usedbytes, &available); | 301 | rc = add_dword( &pFill, 0, &usedbytes, &available); |
299 | if (rc) | 302 | if (rc) |
300 | return(rc); | 303 | return(rc); |
301 | 304 | ||
302 | // Figure out memory Available | 305 | /* Figure out memory Available */ |
303 | 306 | ||
304 | resNode = ctrl->mem_head; | 307 | resNode = ctrl->mem_head; |
305 | 308 | ||
@@ -308,12 +311,12 @@ static u32 store_HRT (void __iomem *rom_start) | |||
308 | while (resNode) { | 311 | while (resNode) { |
309 | loop ++; | 312 | loop ++; |
310 | 313 | ||
311 | // base | 314 | /* base */ |
312 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); | 315 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); |
313 | if (rc) | 316 | if (rc) |
314 | return(rc); | 317 | return(rc); |
315 | 318 | ||
316 | // length | 319 | /* length */ |
317 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); | 320 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); |
318 | if (rc) | 321 | if (rc) |
319 | return(rc); | 322 | return(rc); |
@@ -321,10 +324,10 @@ static u32 store_HRT (void __iomem *rom_start) | |||
321 | resNode = resNode->next; | 324 | resNode = resNode->next; |
322 | } | 325 | } |
323 | 326 | ||
324 | // Fill in the number of entries | 327 | /* Fill in the number of entries */ |
325 | p_ev_ctrl->mem_avail = loop; | 328 | p_ev_ctrl->mem_avail = loop; |
326 | 329 | ||
327 | // Figure out prefetchable memory Available | 330 | /* Figure out prefetchable memory Available */ |
328 | 331 | ||
329 | resNode = ctrl->p_mem_head; | 332 | resNode = ctrl->p_mem_head; |
330 | 333 | ||
@@ -333,12 +336,12 @@ static u32 store_HRT (void __iomem *rom_start) | |||
333 | while (resNode) { | 336 | while (resNode) { |
334 | loop ++; | 337 | loop ++; |
335 | 338 | ||
336 | // base | 339 | /* base */ |
337 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); | 340 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); |
338 | if (rc) | 341 | if (rc) |
339 | return(rc); | 342 | return(rc); |
340 | 343 | ||
341 | // length | 344 | /* length */ |
342 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); | 345 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); |
343 | if (rc) | 346 | if (rc) |
344 | return(rc); | 347 | return(rc); |
@@ -346,10 +349,10 @@ static u32 store_HRT (void __iomem *rom_start) | |||
346 | resNode = resNode->next; | 349 | resNode = resNode->next; |
347 | } | 350 | } |
348 | 351 | ||
349 | // Fill in the number of entries | 352 | /* Fill in the number of entries */ |
350 | p_ev_ctrl->p_mem_avail = loop; | 353 | p_ev_ctrl->p_mem_avail = loop; |
351 | 354 | ||
352 | // Figure out IO Available | 355 | /* Figure out IO Available */ |
353 | 356 | ||
354 | resNode = ctrl->io_head; | 357 | resNode = ctrl->io_head; |
355 | 358 | ||
@@ -358,12 +361,12 @@ static u32 store_HRT (void __iomem *rom_start) | |||
358 | while (resNode) { | 361 | while (resNode) { |
359 | loop ++; | 362 | loop ++; |
360 | 363 | ||
361 | // base | 364 | /* base */ |
362 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); | 365 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); |
363 | if (rc) | 366 | if (rc) |
364 | return(rc); | 367 | return(rc); |
365 | 368 | ||
366 | // length | 369 | /* length */ |
367 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); | 370 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); |
368 | if (rc) | 371 | if (rc) |
369 | return(rc); | 372 | return(rc); |
@@ -371,10 +374,10 @@ static u32 store_HRT (void __iomem *rom_start) | |||
371 | resNode = resNode->next; | 374 | resNode = resNode->next; |
372 | } | 375 | } |
373 | 376 | ||
374 | // Fill in the number of entries | 377 | /* Fill in the number of entries */ |
375 | p_ev_ctrl->io_avail = loop; | 378 | p_ev_ctrl->io_avail = loop; |
376 | 379 | ||
377 | // Figure out bus Available | 380 | /* Figure out bus Available */ |
378 | 381 | ||
379 | resNode = ctrl->bus_head; | 382 | resNode = ctrl->bus_head; |
380 | 383 | ||
@@ -383,12 +386,12 @@ static u32 store_HRT (void __iomem *rom_start) | |||
383 | while (resNode) { | 386 | while (resNode) { |
384 | loop ++; | 387 | loop ++; |
385 | 388 | ||
386 | // base | 389 | /* base */ |
387 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); | 390 | rc = add_dword( &pFill, resNode->base, &usedbytes, &available); |
388 | if (rc) | 391 | if (rc) |
389 | return(rc); | 392 | return(rc); |
390 | 393 | ||
391 | // length | 394 | /* length */ |
392 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); | 395 | rc = add_dword( &pFill, resNode->length, &usedbytes, &available); |
393 | if (rc) | 396 | if (rc) |
394 | return(rc); | 397 | return(rc); |
@@ -396,15 +399,15 @@ static u32 store_HRT (void __iomem *rom_start) | |||
396 | resNode = resNode->next; | 399 | resNode = resNode->next; |
397 | } | 400 | } |
398 | 401 | ||
399 | // Fill in the number of entries | 402 | /* Fill in the number of entries */ |
400 | p_ev_ctrl->bus_avail = loop; | 403 | p_ev_ctrl->bus_avail = loop; |
401 | 404 | ||
402 | ctrl = ctrl->next; | 405 | ctrl = ctrl->next; |
403 | } | 406 | } |
404 | 407 | ||
405 | p_EV_header->num_of_ctrl = numCtrl; | 408 | p_EV_header->num_of_ctrl = numCtrl; |
406 | 409 | ||
407 | // Now store the EV | 410 | /* Now store the EV */ |
408 | 411 | ||
409 | temp_dword = usedbytes; | 412 | temp_dword = usedbytes; |
410 | 413 | ||
@@ -449,20 +452,21 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | |||
449 | struct ev_hrt_header *p_EV_header; | 452 | struct ev_hrt_header *p_EV_header; |
450 | 453 | ||
451 | if (!evbuffer_init) { | 454 | if (!evbuffer_init) { |
452 | // Read the resource list information in from NVRAM | 455 | /* Read the resource list information in from NVRAM */ |
453 | if (load_HRT(rom_start)) | 456 | if (load_HRT(rom_start)) |
454 | memset (evbuffer, 0, 1024); | 457 | memset (evbuffer, 0, 1024); |
455 | 458 | ||
456 | evbuffer_init = 1; | 459 | evbuffer_init = 1; |
457 | } | 460 | } |
458 | 461 | ||
459 | // If we saved information in NVRAM, use it now | 462 | /* If we saved information in NVRAM, use it now */ |
460 | p_EV_header = (struct ev_hrt_header *) evbuffer; | 463 | p_EV_header = (struct ev_hrt_header *) evbuffer; |
461 | 464 | ||
462 | // The following code is for systems where version 1.0 of this | 465 | /* The following code is for systems where version 1.0 of this |
463 | // driver has been loaded, but doesn't support the hardware. | 466 | * driver has been loaded, but doesn't support the hardware. |
464 | // In that case, the driver would incorrectly store something | 467 | * In that case, the driver would incorrectly store something |
465 | // in NVRAM. | 468 | * in NVRAM. |
469 | */ | ||
466 | if ((p_EV_header->Version == 2) || | 470 | if ((p_EV_header->Version == 2) || |
467 | ((p_EV_header->Version == 1) && !ctrl->push_flag)) { | 471 | ((p_EV_header->Version == 1) && !ctrl->push_flag)) { |
468 | p_byte = &(p_EV_header->next); | 472 | p_byte = &(p_EV_header->next); |
@@ -479,7 +483,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | |||
479 | function = p_ev_ctrl->function; | 483 | function = p_ev_ctrl->function; |
480 | 484 | ||
481 | while ((bus != ctrl->bus) || | 485 | while ((bus != ctrl->bus) || |
482 | (device != PCI_SLOT(ctrl->pci_dev->devfn)) || | 486 | (device != PCI_SLOT(ctrl->pci_dev->devfn)) || |
483 | (function != PCI_FUNC(ctrl->pci_dev->devfn))) { | 487 | (function != PCI_FUNC(ctrl->pci_dev->devfn))) { |
484 | nummem = p_ev_ctrl->mem_avail; | 488 | nummem = p_ev_ctrl->mem_avail; |
485 | numpmem = p_ev_ctrl->p_mem_avail; | 489 | numpmem = p_ev_ctrl->p_mem_avail; |
@@ -491,7 +495,7 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | |||
491 | if (p_byte > ((u8*)p_EV_header + evbuffer_length)) | 495 | if (p_byte > ((u8*)p_EV_header + evbuffer_length)) |
492 | return 2; | 496 | return 2; |
493 | 497 | ||
494 | // Skip forward to the next entry | 498 | /* Skip forward to the next entry */ |
495 | p_byte += (nummem + numpmem + numio + numbus) * 8; | 499 | p_byte += (nummem + numpmem + numio + numbus) * 8; |
496 | 500 | ||
497 | if (p_byte > ((u8*)p_EV_header + evbuffer_length)) | 501 | if (p_byte > ((u8*)p_EV_header + evbuffer_length)) |
@@ -629,8 +633,9 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | |||
629 | ctrl->bus_head = bus_node; | 633 | ctrl->bus_head = bus_node; |
630 | } | 634 | } |
631 | 635 | ||
632 | // If all of the following fail, we don't have any resources for | 636 | /* If all of the following fail, we don't have any resources for |
633 | // hot plug add | 637 | * hot plug add |
638 | */ | ||
634 | rc = 1; | 639 | rc = 1; |
635 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head)); | 640 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head)); |
636 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head)); | 641 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head)); |
@@ -640,14 +645,14 @@ int compaq_nvram_load (void __iomem *rom_start, struct controller *ctrl) | |||
640 | if (rc) | 645 | if (rc) |
641 | return(rc); | 646 | return(rc); |
642 | } else { | 647 | } else { |
643 | if ((evbuffer[0] != 0) && (!ctrl->push_flag)) | 648 | if ((evbuffer[0] != 0) && (!ctrl->push_flag)) |
644 | return 1; | 649 | return 1; |
645 | } | 650 | } |
646 | 651 | ||
647 | return 0; | 652 | return 0; |
648 | } | 653 | } |
649 | 654 | ||
650 | 655 | ||
651 | int compaq_nvram_store (void __iomem *rom_start) | 656 | int compaq_nvram_store (void __iomem *rom_start) |
652 | { | 657 | { |
653 | int rc = 1; | 658 | int rc = 1; |
diff --git a/drivers/pci/hotplug/cpqphp_pci.c b/drivers/pci/hotplug/cpqphp_pci.c index 6c0ed0fcb8ee..6173b9a4544e 100644 --- a/drivers/pci/hotplug/cpqphp_pci.c +++ b/drivers/pci/hotplug/cpqphp_pci.c | |||
@@ -37,7 +37,6 @@ | |||
37 | #include "../pci.h" | 37 | #include "../pci.h" |
38 | #include "cpqphp.h" | 38 | #include "cpqphp.h" |
39 | #include "cpqphp_nvram.h" | 39 | #include "cpqphp_nvram.h" |
40 | #include <asm/pci_x86.h> | ||
41 | 40 | ||
42 | 41 | ||
43 | u8 cpqhp_nic_irq; | 42 | u8 cpqhp_nic_irq; |
@@ -82,14 +81,14 @@ static void __iomem *detect_HRT_floating_pointer(void __iomem *begin, void __iom | |||
82 | } | 81 | } |
83 | 82 | ||
84 | 83 | ||
85 | int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) | 84 | int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) |
86 | { | 85 | { |
87 | unsigned char bus; | 86 | unsigned char bus; |
88 | struct pci_bus *child; | 87 | struct pci_bus *child; |
89 | int num; | 88 | int num; |
90 | 89 | ||
91 | if (func->pci_dev == NULL) | 90 | if (func->pci_dev == NULL) |
92 | func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); | 91 | func->pci_dev = pci_get_bus_and_slot(func->bus,PCI_DEVFN(func->device, func->function)); |
93 | 92 | ||
94 | /* No pci device, we need to create it then */ | 93 | /* No pci device, we need to create it then */ |
95 | if (func->pci_dev == NULL) { | 94 | if (func->pci_dev == NULL) { |
@@ -99,7 +98,7 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) | |||
99 | if (num) | 98 | if (num) |
100 | pci_bus_add_devices(ctrl->pci_dev->bus); | 99 | pci_bus_add_devices(ctrl->pci_dev->bus); |
101 | 100 | ||
102 | func->pci_dev = pci_find_slot(func->bus, PCI_DEVFN(func->device, func->function)); | 101 | func->pci_dev = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, func->function)); |
103 | if (func->pci_dev == NULL) { | 102 | if (func->pci_dev == NULL) { |
104 | dbg("ERROR: pci_dev still null\n"); | 103 | dbg("ERROR: pci_dev still null\n"); |
105 | return 0; | 104 | return 0; |
@@ -112,20 +111,24 @@ int cpqhp_configure_device (struct controller* ctrl, struct pci_func* func) | |||
112 | pci_do_scan_bus(child); | 111 | pci_do_scan_bus(child); |
113 | } | 112 | } |
114 | 113 | ||
114 | pci_dev_put(func->pci_dev); | ||
115 | |||
115 | return 0; | 116 | return 0; |
116 | } | 117 | } |
117 | 118 | ||
118 | 119 | ||
119 | int cpqhp_unconfigure_device(struct pci_func* func) | 120 | int cpqhp_unconfigure_device(struct pci_func* func) |
120 | { | 121 | { |
121 | int j; | 122 | int j; |
122 | 123 | ||
123 | dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function); | 124 | dbg("%s: bus/dev/func = %x/%x/%x\n", __func__, func->bus, func->device, func->function); |
124 | 125 | ||
125 | for (j=0; j<8 ; j++) { | 126 | for (j=0; j<8 ; j++) { |
126 | struct pci_dev* temp = pci_find_slot(func->bus, PCI_DEVFN(func->device, j)); | 127 | struct pci_dev* temp = pci_get_bus_and_slot(func->bus, PCI_DEVFN(func->device, j)); |
127 | if (temp) | 128 | if (temp) { |
129 | pci_dev_put(temp); | ||
128 | pci_remove_bus_device(temp); | 130 | pci_remove_bus_device(temp); |
131 | } | ||
129 | } | 132 | } |
130 | return 0; | 133 | return 0; |
131 | } | 134 | } |
@@ -178,32 +181,22 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) | |||
178 | if (!rc) | 181 | if (!rc) |
179 | return !rc; | 182 | return !rc; |
180 | 183 | ||
181 | // set the Edge Level Control Register (ELCR) | 184 | /* set the Edge Level Control Register (ELCR) */ |
182 | temp_word = inb(0x4d0); | 185 | temp_word = inb(0x4d0); |
183 | temp_word |= inb(0x4d1) << 8; | 186 | temp_word |= inb(0x4d1) << 8; |
184 | 187 | ||
185 | temp_word |= 0x01 << irq_num; | 188 | temp_word |= 0x01 << irq_num; |
186 | 189 | ||
187 | // This should only be for x86 as it sets the Edge Level Control Register | 190 | /* This should only be for x86 as it sets the Edge Level |
188 | outb((u8) (temp_word & 0xFF), 0x4d0); | 191 | * Control Register |
189 | outb((u8) ((temp_word & 0xFF00) >> 8), 0x4d1); | 192 | */ |
190 | rc = 0; | 193 | outb((u8) (temp_word & 0xFF), 0x4d0); outb((u8) ((temp_word & |
191 | } | 194 | 0xFF00) >> 8), 0x4d1); rc = 0; } |
192 | 195 | ||
193 | return rc; | 196 | return rc; |
194 | } | 197 | } |
195 | 198 | ||
196 | 199 | ||
197 | /* | ||
198 | * WTF??? This function isn't in the code, yet a function calls it, but the | ||
199 | * compiler optimizes it away? strange. Here as a placeholder to keep the | ||
200 | * compiler happy. | ||
201 | */ | ||
202 | static int PCI_ScanBusNonBridge (u8 bus, u8 device) | ||
203 | { | ||
204 | return 0; | ||
205 | } | ||
206 | |||
207 | static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num) | 200 | static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev_num) |
208 | { | 201 | { |
209 | u16 tdevice; | 202 | u16 tdevice; |
@@ -213,11 +206,11 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev | |||
213 | ctrl->pci_bus->number = bus_num; | 206 | ctrl->pci_bus->number = bus_num; |
214 | 207 | ||
215 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { | 208 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { |
216 | //Scan for access first | 209 | /* Scan for access first */ |
217 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) | 210 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) |
218 | continue; | 211 | continue; |
219 | dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); | 212 | dbg("Looking for nonbridge bus_num %d dev_num %d\n", bus_num, tdevice); |
220 | //Yep we got one. Not a bridge ? | 213 | /* Yep we got one. Not a bridge ? */ |
221 | if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) { | 214 | if ((work >> 8) != PCI_TO_PCI_BRIDGE_CLASS) { |
222 | *dev_num = tdevice; | 215 | *dev_num = tdevice; |
223 | dbg("found it !\n"); | 216 | dbg("found it !\n"); |
@@ -225,16 +218,16 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev | |||
225 | } | 218 | } |
226 | } | 219 | } |
227 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { | 220 | for (tdevice = 0; tdevice < 0xFF; tdevice++) { |
228 | //Scan for access first | 221 | /* Scan for access first */ |
229 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) | 222 | if (PCI_RefinedAccessConfig(ctrl->pci_bus, tdevice, 0x08, &work) == -1) |
230 | continue; | 223 | continue; |
231 | dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); | 224 | dbg("Looking for bridge bus_num %d dev_num %d\n", bus_num, tdevice); |
232 | //Yep we got one. bridge ? | 225 | /* Yep we got one. bridge ? */ |
233 | if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { | 226 | if ((work >> 8) == PCI_TO_PCI_BRIDGE_CLASS) { |
234 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus); | 227 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(tdevice, 0), PCI_SECONDARY_BUS, &tbus); |
228 | /* XXX: no recursion, wtf? */ | ||
235 | dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice); | 229 | dbg("Recurse on bus_num %d tdevice %d\n", tbus, tdevice); |
236 | if (PCI_ScanBusNonBridge(tbus, tdevice) == 0) | 230 | return 0; |
237 | return 0; | ||
238 | } | 231 | } |
239 | } | 232 | } |
240 | 233 | ||
@@ -244,39 +237,23 @@ static int PCI_ScanBusForNonBridge(struct controller *ctrl, u8 bus_num, u8 * dev | |||
244 | 237 | ||
245 | static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge) | 238 | static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num, u8 slot, u8 nobridge) |
246 | { | 239 | { |
247 | struct irq_routing_table *PCIIRQRoutingInfoLength; | 240 | int loop, len; |
248 | long len; | ||
249 | long loop; | ||
250 | u32 work; | 241 | u32 work; |
251 | |||
252 | u8 tbus, tdevice, tslot; | 242 | u8 tbus, tdevice, tslot; |
253 | 243 | ||
254 | PCIIRQRoutingInfoLength = pcibios_get_irq_routing_table(); | 244 | len = cpqhp_routing_table_length(); |
255 | if (!PCIIRQRoutingInfoLength) | ||
256 | return -1; | ||
257 | |||
258 | len = (PCIIRQRoutingInfoLength->size - | ||
259 | sizeof(struct irq_routing_table)) / sizeof(struct irq_info); | ||
260 | // Make sure I got at least one entry | ||
261 | if (len == 0) { | ||
262 | kfree(PCIIRQRoutingInfoLength ); | ||
263 | return -1; | ||
264 | } | ||
265 | |||
266 | for (loop = 0; loop < len; ++loop) { | 245 | for (loop = 0; loop < len; ++loop) { |
267 | tbus = PCIIRQRoutingInfoLength->slots[loop].bus; | 246 | tbus = cpqhp_routing_table->slots[loop].bus; |
268 | tdevice = PCIIRQRoutingInfoLength->slots[loop].devfn; | 247 | tdevice = cpqhp_routing_table->slots[loop].devfn; |
269 | tslot = PCIIRQRoutingInfoLength->slots[loop].slot; | 248 | tslot = cpqhp_routing_table->slots[loop].slot; |
270 | 249 | ||
271 | if (tslot == slot) { | 250 | if (tslot == slot) { |
272 | *bus_num = tbus; | 251 | *bus_num = tbus; |
273 | *dev_num = tdevice; | 252 | *dev_num = tdevice; |
274 | ctrl->pci_bus->number = tbus; | 253 | ctrl->pci_bus->number = tbus; |
275 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); | 254 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_VENDOR_ID, &work); |
276 | if (!nobridge || (work == 0xffffffff)) { | 255 | if (!nobridge || (work == 0xffffffff)) |
277 | kfree(PCIIRQRoutingInfoLength ); | ||
278 | return 0; | 256 | return 0; |
279 | } | ||
280 | 257 | ||
281 | dbg("bus_num %d devfn %d\n", *bus_num, *dev_num); | 258 | dbg("bus_num %d devfn %d\n", *bus_num, *dev_num); |
282 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work); | 259 | pci_bus_read_config_dword (ctrl->pci_bus, *dev_num, PCI_CLASS_REVISION, &work); |
@@ -287,28 +264,26 @@ static int PCI_GetBusDevHelper(struct controller *ctrl, u8 *bus_num, u8 *dev_num | |||
287 | dbg("Scan bus for Non Bridge: bus %d\n", tbus); | 264 | dbg("Scan bus for Non Bridge: bus %d\n", tbus); |
288 | if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { | 265 | if (PCI_ScanBusForNonBridge(ctrl, tbus, dev_num) == 0) { |
289 | *bus_num = tbus; | 266 | *bus_num = tbus; |
290 | kfree(PCIIRQRoutingInfoLength ); | ||
291 | return 0; | 267 | return 0; |
292 | } | 268 | } |
293 | } else { | 269 | } else |
294 | kfree(PCIIRQRoutingInfoLength ); | ||
295 | return 0; | 270 | return 0; |
296 | } | ||
297 | |||
298 | } | 271 | } |
299 | } | 272 | } |
300 | kfree(PCIIRQRoutingInfoLength ); | ||
301 | return -1; | 273 | return -1; |
302 | } | 274 | } |
303 | 275 | ||
304 | 276 | ||
305 | int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot) | 277 | int cpqhp_get_bus_dev (struct controller *ctrl, u8 * bus_num, u8 * dev_num, u8 slot) |
306 | { | 278 | { |
307 | return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); //plain (bridges allowed) | 279 | /* plain (bridges allowed) */ |
280 | return PCI_GetBusDevHelper(ctrl, bus_num, dev_num, slot, 0); | ||
308 | } | 281 | } |
309 | 282 | ||
310 | 283 | ||
311 | /* More PCI configuration routines; this time centered around hotplug controller */ | 284 | /* More PCI configuration routines; this time centered around hotplug |
285 | * controller | ||
286 | */ | ||
312 | 287 | ||
313 | 288 | ||
314 | /* | 289 | /* |
@@ -339,12 +314,12 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) | |||
339 | int stop_it; | 314 | int stop_it; |
340 | int index; | 315 | int index; |
341 | 316 | ||
342 | // Decide which slots are supported | 317 | /* Decide which slots are supported */ |
343 | 318 | ||
344 | if (is_hot_plug) { | 319 | if (is_hot_plug) { |
345 | //********************************* | 320 | /* |
346 | // is_hot_plug is the slot mask | 321 | * is_hot_plug is the slot mask |
347 | //********************************* | 322 | */ |
348 | FirstSupported = is_hot_plug >> 4; | 323 | FirstSupported = is_hot_plug >> 4; |
349 | LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1; | 324 | LastSupported = FirstSupported + (is_hot_plug & 0x0F) - 1; |
350 | } else { | 325 | } else { |
@@ -352,123 +327,127 @@ int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug) | |||
352 | LastSupported = 0x1F; | 327 | LastSupported = 0x1F; |
353 | } | 328 | } |
354 | 329 | ||
355 | // Save PCI configuration space for all devices in supported slots | 330 | /* Save PCI configuration space for all devices in supported slots */ |
356 | ctrl->pci_bus->number = busnumber; | 331 | ctrl->pci_bus->number = busnumber; |
357 | for (device = FirstSupported; device <= LastSupported; device++) { | 332 | for (device = FirstSupported; device <= LastSupported; device++) { |
358 | ID = 0xFFFFFFFF; | 333 | ID = 0xFFFFFFFF; |
359 | rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID); | 334 | rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID); |
335 | |||
336 | if (ID == 0xFFFFFFFF) { | ||
337 | if (is_hot_plug) { | ||
338 | /* Setup slot structure with entry for empty | ||
339 | * slot | ||
340 | */ | ||
341 | new_slot = cpqhp_slot_create(busnumber); | ||
342 | if (new_slot == NULL) | ||
343 | return 1; | ||
360 | 344 | ||
361 | if (ID != 0xFFFFFFFF) { // device in slot | 345 | new_slot->bus = (u8) busnumber; |
362 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code); | 346 | new_slot->device = (u8) device; |
363 | if (rc) | 347 | new_slot->function = 0; |
364 | return rc; | 348 | new_slot->is_a_board = 0; |
349 | new_slot->presence_save = 0; | ||
350 | new_slot->switch_save = 0; | ||
351 | } | ||
352 | continue; | ||
353 | } | ||
365 | 354 | ||
366 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type); | 355 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), 0x0B, &class_code); |
367 | if (rc) | 356 | if (rc) |
368 | return rc; | 357 | return rc; |
369 | 358 | ||
370 | // If multi-function device, set max_functions to 8 | 359 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, 0), PCI_HEADER_TYPE, &header_type); |
371 | if (header_type & 0x80) | 360 | if (rc) |
372 | max_functions = 8; | 361 | return rc; |
373 | else | ||
374 | max_functions = 1; | ||
375 | 362 | ||
376 | function = 0; | 363 | /* If multi-function device, set max_functions to 8 */ |
364 | if (header_type & 0x80) | ||
365 | max_functions = 8; | ||
366 | else | ||
367 | max_functions = 1; | ||
377 | 368 | ||
378 | do { | 369 | function = 0; |
379 | DevError = 0; | ||
380 | 370 | ||
381 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // P-P Bridge | 371 | do { |
382 | // Recurse the subordinate bus | 372 | DevError = 0; |
383 | // get the subordinate bus number | 373 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
384 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus); | 374 | /* Recurse the subordinate bus |
385 | if (rc) { | 375 | * get the subordinate bus number |
376 | */ | ||
377 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_SECONDARY_BUS, &secondary_bus); | ||
378 | if (rc) { | ||
379 | return rc; | ||
380 | } else { | ||
381 | sub_bus = (int) secondary_bus; | ||
382 | |||
383 | /* Save secondary bus cfg spc | ||
384 | * with this recursive call. | ||
385 | */ | ||
386 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | ||
387 | if (rc) | ||
386 | return rc; | 388 | return rc; |
387 | } else { | 389 | ctrl->pci_bus->number = busnumber; |
388 | sub_bus = (int) secondary_bus; | ||
389 | |||
390 | // Save secondary bus cfg spc | ||
391 | // with this recursive call. | ||
392 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | ||
393 | if (rc) | ||
394 | return rc; | ||
395 | ctrl->pci_bus->number = busnumber; | ||
396 | } | ||
397 | } | 390 | } |
391 | } | ||
398 | 392 | ||
399 | index = 0; | 393 | index = 0; |
394 | new_slot = cpqhp_slot_find(busnumber, device, index++); | ||
395 | while (new_slot && | ||
396 | (new_slot->function != (u8) function)) | ||
400 | new_slot = cpqhp_slot_find(busnumber, device, index++); | 397 | new_slot = cpqhp_slot_find(busnumber, device, index++); |
401 | while (new_slot && | ||
402 | (new_slot->function != (u8) function)) | ||
403 | new_slot = cpqhp_slot_find(busnumber, device, index++); | ||
404 | 398 | ||
405 | if (!new_slot) { | 399 | if (!new_slot) { |
406 | // Setup slot structure. | 400 | /* Setup slot structure. */ |
407 | new_slot = cpqhp_slot_create(busnumber); | 401 | new_slot = cpqhp_slot_create(busnumber); |
408 | 402 | if (new_slot == NULL) | |
409 | if (new_slot == NULL) | 403 | return 1; |
410 | return(1); | 404 | } |
411 | } | ||
412 | |||
413 | new_slot->bus = (u8) busnumber; | ||
414 | new_slot->device = (u8) device; | ||
415 | new_slot->function = (u8) function; | ||
416 | new_slot->is_a_board = 1; | ||
417 | new_slot->switch_save = 0x10; | ||
418 | // In case of unsupported board | ||
419 | new_slot->status = DevError; | ||
420 | new_slot->pci_dev = pci_find_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function); | ||
421 | |||
422 | for (cloop = 0; cloop < 0x20; cloop++) { | ||
423 | rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); | ||
424 | if (rc) | ||
425 | return rc; | ||
426 | } | ||
427 | 405 | ||
428 | function++; | 406 | new_slot->bus = (u8) busnumber; |
407 | new_slot->device = (u8) device; | ||
408 | new_slot->function = (u8) function; | ||
409 | new_slot->is_a_board = 1; | ||
410 | new_slot->switch_save = 0x10; | ||
411 | /* In case of unsupported board */ | ||
412 | new_slot->status = DevError; | ||
413 | new_slot->pci_dev = pci_get_bus_and_slot(new_slot->bus, (new_slot->device << 3) | new_slot->function); | ||
429 | 414 | ||
430 | stop_it = 0; | 415 | for (cloop = 0; cloop < 0x20; cloop++) { |
416 | rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); | ||
417 | if (rc) | ||
418 | return rc; | ||
419 | } | ||
431 | 420 | ||
432 | // this loop skips to the next present function | 421 | pci_dev_put(new_slot->pci_dev); |
433 | // reading in Class Code and Header type. | ||
434 | 422 | ||
435 | while ((function < max_functions)&&(!stop_it)) { | 423 | function++; |
436 | rc = pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID); | ||
437 | if (ID == 0xFFFFFFFF) { // nothing there. | ||
438 | function++; | ||
439 | } else { // Something there | ||
440 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code); | ||
441 | if (rc) | ||
442 | return rc; | ||
443 | 424 | ||
444 | rc = pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type); | 425 | stop_it = 0; |
445 | if (rc) | ||
446 | return rc; | ||
447 | 426 | ||
448 | stop_it++; | 427 | /* this loop skips to the next present function |
449 | } | 428 | * reading in Class Code and Header type. |
429 | */ | ||
430 | while ((function < max_functions) && (!stop_it)) { | ||
431 | rc = pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_VENDOR_ID, &ID); | ||
432 | if (ID == 0xFFFFFFFF) { | ||
433 | function++; | ||
434 | continue; | ||
450 | } | 435 | } |
436 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), 0x0B, &class_code); | ||
437 | if (rc) | ||
438 | return rc; | ||
451 | 439 | ||
452 | } while (function < max_functions); | 440 | rc = pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(device, function), PCI_HEADER_TYPE, &header_type); |
453 | } // End of IF (device in slot?) | 441 | if (rc) |
454 | else if (is_hot_plug) { | 442 | return rc; |
455 | // Setup slot structure with entry for empty slot | ||
456 | new_slot = cpqhp_slot_create(busnumber); | ||
457 | 443 | ||
458 | if (new_slot == NULL) { | 444 | stop_it++; |
459 | return(1); | ||
460 | } | 445 | } |
461 | 446 | ||
462 | new_slot->bus = (u8) busnumber; | 447 | } while (function < max_functions); |
463 | new_slot->device = (u8) device; | 448 | } /* End of FOR loop */ |
464 | new_slot->function = 0; | ||
465 | new_slot->is_a_board = 0; | ||
466 | new_slot->presence_save = 0; | ||
467 | new_slot->switch_save = 0; | ||
468 | } | ||
469 | } // End of FOR loop | ||
470 | 449 | ||
471 | return(0); | 450 | return 0; |
472 | } | 451 | } |
473 | 452 | ||
474 | 453 | ||
@@ -489,7 +468,7 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) | |||
489 | u8 secondary_bus; | 468 | u8 secondary_bus; |
490 | int sub_bus; | 469 | int sub_bus; |
491 | int max_functions; | 470 | int max_functions; |
492 | int function; | 471 | int function = 0; |
493 | int cloop = 0; | 472 | int cloop = 0; |
494 | int stop_it; | 473 | int stop_it; |
495 | 474 | ||
@@ -498,63 +477,58 @@ int cpqhp_save_slot_config (struct controller *ctrl, struct pci_func * new_slot) | |||
498 | ctrl->pci_bus->number = new_slot->bus; | 477 | ctrl->pci_bus->number = new_slot->bus; |
499 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID); | 478 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_VENDOR_ID, &ID); |
500 | 479 | ||
501 | if (ID != 0xFFFFFFFF) { // device in slot | 480 | if (ID == 0xFFFFFFFF) |
502 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code); | 481 | return 2; |
503 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type); | ||
504 | |||
505 | if (header_type & 0x80) // Multi-function device | ||
506 | max_functions = 8; | ||
507 | else | ||
508 | max_functions = 1; | ||
509 | |||
510 | function = 0; | ||
511 | |||
512 | do { | ||
513 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | ||
514 | // Recurse the subordinate bus | ||
515 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus); | ||
516 | 482 | ||
517 | sub_bus = (int) secondary_bus; | 483 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), 0x0B, &class_code); |
484 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, 0), PCI_HEADER_TYPE, &header_type); | ||
518 | 485 | ||
519 | // Save the config headers for the secondary bus. | 486 | if (header_type & 0x80) /* Multi-function device */ |
520 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | 487 | max_functions = 8; |
521 | if (rc) | 488 | else |
522 | return(rc); | 489 | max_functions = 1; |
523 | ctrl->pci_bus->number = new_slot->bus; | ||
524 | 490 | ||
525 | } // End of IF | 491 | while (function < max_functions) { |
492 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | ||
493 | /* Recurse the subordinate bus */ | ||
494 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_SECONDARY_BUS, &secondary_bus); | ||
526 | 495 | ||
527 | new_slot->status = 0; | 496 | sub_bus = (int) secondary_bus; |
528 | 497 | ||
529 | for (cloop = 0; cloop < 0x20; cloop++) { | 498 | /* Save the config headers for the secondary |
530 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); | 499 | * bus. |
531 | } | 500 | */ |
501 | rc = cpqhp_save_config(ctrl, sub_bus, 0); | ||
502 | if (rc) | ||
503 | return(rc); | ||
504 | ctrl->pci_bus->number = new_slot->bus; | ||
532 | 505 | ||
533 | function++; | 506 | } |
534 | 507 | ||
535 | stop_it = 0; | 508 | new_slot->status = 0; |
536 | 509 | ||
537 | // this loop skips to the next present function | 510 | for (cloop = 0; cloop < 0x20; cloop++) |
538 | // reading in the Class Code and the Header type. | 511 | pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), cloop << 2, (u32 *) & (new_slot-> config_space [cloop])); |
539 | 512 | ||
540 | while ((function < max_functions) && (!stop_it)) { | 513 | function++; |
541 | pci_bus_read_config_dword (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID); | ||
542 | 514 | ||
543 | if (ID == 0xFFFFFFFF) { // nothing there. | 515 | stop_it = 0; |
544 | function++; | ||
545 | } else { // Something there | ||
546 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code); | ||
547 | 516 | ||
548 | pci_bus_read_config_byte (ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type); | 517 | /* this loop skips to the next present function |
518 | * reading in the Class Code and the Header type. | ||
519 | */ | ||
520 | while ((function < max_functions) && (!stop_it)) { | ||
521 | pci_bus_read_config_dword(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_VENDOR_ID, &ID); | ||
549 | 522 | ||
550 | stop_it++; | 523 | if (ID == 0xFFFFFFFF) |
551 | } | 524 | function++; |
525 | else { | ||
526 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), 0x0B, &class_code); | ||
527 | pci_bus_read_config_byte(ctrl->pci_bus, PCI_DEVFN(new_slot->device, function), PCI_HEADER_TYPE, &header_type); | ||
528 | stop_it++; | ||
552 | } | 529 | } |
530 | } | ||
553 | 531 | ||
554 | } while (function < max_functions); | ||
555 | } // End of IF (device in slot?) | ||
556 | else { | ||
557 | return 2; | ||
558 | } | 532 | } |
559 | 533 | ||
560 | return 0; | 534 | return 0; |
@@ -590,11 +564,10 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
590 | pci_bus->number = func->bus; | 564 | pci_bus->number = func->bus; |
591 | devfn = PCI_DEVFN(func->device, func->function); | 565 | devfn = PCI_DEVFN(func->device, func->function); |
592 | 566 | ||
593 | // Check for Bridge | 567 | /* Check for Bridge */ |
594 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 568 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
595 | 569 | ||
596 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { | 570 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
597 | // PCI-PCI Bridge | ||
598 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); | 571 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); |
599 | 572 | ||
600 | sub_bus = (int) secondary_bus; | 573 | sub_bus = (int) secondary_bus; |
@@ -610,23 +583,27 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
610 | } | 583 | } |
611 | pci_bus->number = func->bus; | 584 | pci_bus->number = func->bus; |
612 | 585 | ||
613 | //FIXME: this loop is duplicated in the non-bridge case. The two could be rolled together | 586 | /* FIXME: this loop is duplicated in the non-bridge |
614 | // Figure out IO and memory base lengths | 587 | * case. The two could be rolled together Figure out |
588 | * IO and memory base lengths | ||
589 | */ | ||
615 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { | 590 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { |
616 | temp_register = 0xFFFFFFFF; | 591 | temp_register = 0xFFFFFFFF; |
617 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); | 592 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); |
618 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); | 593 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); |
619 | 594 | /* If this register is implemented */ | |
620 | if (base) { // If this register is implemented | 595 | if (base) { |
621 | if (base & 0x01L) { | 596 | if (base & 0x01L) { |
622 | // IO base | 597 | /* IO base |
623 | // set base = amount of IO space requested | 598 | * set base = amount of IO space |
599 | * requested | ||
600 | */ | ||
624 | base = base & 0xFFFFFFFE; | 601 | base = base & 0xFFFFFFFE; |
625 | base = (~base) + 1; | 602 | base = (~base) + 1; |
626 | 603 | ||
627 | type = 1; | 604 | type = 1; |
628 | } else { | 605 | } else { |
629 | // memory base | 606 | /* memory base */ |
630 | base = base & 0xFFFFFFF0; | 607 | base = base & 0xFFFFFFF0; |
631 | base = (~base) + 1; | 608 | base = (~base) + 1; |
632 | 609 | ||
@@ -637,32 +614,36 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
637 | type = 0; | 614 | type = 0; |
638 | } | 615 | } |
639 | 616 | ||
640 | // Save information in slot structure | 617 | /* Save information in slot structure */ |
641 | func->base_length[(cloop - 0x10) >> 2] = | 618 | func->base_length[(cloop - 0x10) >> 2] = |
642 | base; | 619 | base; |
643 | func->base_type[(cloop - 0x10) >> 2] = type; | 620 | func->base_type[(cloop - 0x10) >> 2] = type; |
644 | 621 | ||
645 | } // End of base register loop | 622 | } /* End of base register loop */ |
646 | 623 | ||
647 | 624 | } else if ((header_type & 0x7F) == 0x00) { | |
648 | } else if ((header_type & 0x7F) == 0x00) { // PCI-PCI Bridge | 625 | /* Figure out IO and memory base lengths */ |
649 | // Figure out IO and memory base lengths | ||
650 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { | 626 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { |
651 | temp_register = 0xFFFFFFFF; | 627 | temp_register = 0xFFFFFFFF; |
652 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); | 628 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); |
653 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); | 629 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); |
654 | 630 | ||
655 | if (base) { // If this register is implemented | 631 | /* If this register is implemented */ |
632 | if (base) { | ||
656 | if (base & 0x01L) { | 633 | if (base & 0x01L) { |
657 | // IO base | 634 | /* IO base |
658 | // base = amount of IO space requested | 635 | * base = amount of IO space |
636 | * requested | ||
637 | */ | ||
659 | base = base & 0xFFFFFFFE; | 638 | base = base & 0xFFFFFFFE; |
660 | base = (~base) + 1; | 639 | base = (~base) + 1; |
661 | 640 | ||
662 | type = 1; | 641 | type = 1; |
663 | } else { | 642 | } else { |
664 | // memory base | 643 | /* memory base |
665 | // base = amount of memory space requested | 644 | * base = amount of memory |
645 | * space requested | ||
646 | */ | ||
666 | base = base & 0xFFFFFFF0; | 647 | base = base & 0xFFFFFFF0; |
667 | base = (~base) + 1; | 648 | base = (~base) + 1; |
668 | 649 | ||
@@ -673,16 +654,16 @@ int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func * func) | |||
673 | type = 0; | 654 | type = 0; |
674 | } | 655 | } |
675 | 656 | ||
676 | // Save information in slot structure | 657 | /* Save information in slot structure */ |
677 | func->base_length[(cloop - 0x10) >> 2] = base; | 658 | func->base_length[(cloop - 0x10) >> 2] = base; |
678 | func->base_type[(cloop - 0x10) >> 2] = type; | 659 | func->base_type[(cloop - 0x10) >> 2] = type; |
679 | 660 | ||
680 | } // End of base register loop | 661 | } /* End of base register loop */ |
681 | 662 | ||
682 | } else { // Some other unknown header type | 663 | } else { /* Some other unknown header type */ |
683 | } | 664 | } |
684 | 665 | ||
685 | // find the next device in this slot | 666 | /* find the next device in this slot */ |
686 | func = cpqhp_slot_find(func->bus, func->device, index++); | 667 | func = cpqhp_slot_find(func->bus, func->device, index++); |
687 | } | 668 | } |
688 | 669 | ||
@@ -728,18 +709,18 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
728 | pci_bus->number = func->bus; | 709 | pci_bus->number = func->bus; |
729 | devfn = PCI_DEVFN(func->device, func->function); | 710 | devfn = PCI_DEVFN(func->device, func->function); |
730 | 711 | ||
731 | // Save the command register | 712 | /* Save the command register */ |
732 | pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command); | 713 | pci_bus_read_config_word(pci_bus, devfn, PCI_COMMAND, &save_command); |
733 | 714 | ||
734 | // disable card | 715 | /* disable card */ |
735 | command = 0x00; | 716 | command = 0x00; |
736 | pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); | 717 | pci_bus_write_config_word(pci_bus, devfn, PCI_COMMAND, command); |
737 | 718 | ||
738 | // Check for Bridge | 719 | /* Check for Bridge */ |
739 | pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 720 | pci_bus_read_config_byte(pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
740 | 721 | ||
741 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | 722 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
742 | // Clear Bridge Control Register | 723 | /* Clear Bridge Control Register */ |
743 | command = 0x00; | 724 | command = 0x00; |
744 | pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command); | 725 | pci_bus_write_config_word(pci_bus, devfn, PCI_BRIDGE_CONTROL, command); |
745 | pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); | 726 | pci_bus_read_config_byte(pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); |
@@ -755,7 +736,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
755 | bus_node->next = func->bus_head; | 736 | bus_node->next = func->bus_head; |
756 | func->bus_head = bus_node; | 737 | func->bus_head = bus_node; |
757 | 738 | ||
758 | // Save IO base and Limit registers | 739 | /* Save IO base and Limit registers */ |
759 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base); | 740 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_BASE, &b_base); |
760 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length); | 741 | pci_bus_read_config_byte(pci_bus, devfn, PCI_IO_LIMIT, &b_length); |
761 | 742 | ||
@@ -771,7 +752,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
771 | func->io_head = io_node; | 752 | func->io_head = io_node; |
772 | } | 753 | } |
773 | 754 | ||
774 | // Save memory base and Limit registers | 755 | /* Save memory base and Limit registers */ |
775 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base); | 756 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_BASE, &w_base); |
776 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length); | 757 | pci_bus_read_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, &w_length); |
777 | 758 | ||
@@ -787,7 +768,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
787 | func->mem_head = mem_node; | 768 | func->mem_head = mem_node; |
788 | } | 769 | } |
789 | 770 | ||
790 | // Save prefetchable memory base and Limit registers | 771 | /* Save prefetchable memory base and Limit registers */ |
791 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base); | 772 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, &w_base); |
792 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length); | 773 | pci_bus_read_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, &w_length); |
793 | 774 | ||
@@ -802,7 +783,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
802 | p_mem_node->next = func->p_mem_head; | 783 | p_mem_node->next = func->p_mem_head; |
803 | func->p_mem_head = p_mem_node; | 784 | func->p_mem_head = p_mem_node; |
804 | } | 785 | } |
805 | // Figure out IO and memory base lengths | 786 | /* Figure out IO and memory base lengths */ |
806 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { | 787 | for (cloop = 0x10; cloop <= 0x14; cloop += 4) { |
807 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base); | 788 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &save_base); |
808 | 789 | ||
@@ -812,11 +793,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
812 | 793 | ||
813 | temp_register = base; | 794 | temp_register = base; |
814 | 795 | ||
815 | if (base) { // If this register is implemented | 796 | /* If this register is implemented */ |
797 | if (base) { | ||
816 | if (((base & 0x03L) == 0x01) | 798 | if (((base & 0x03L) == 0x01) |
817 | && (save_command & 0x01)) { | 799 | && (save_command & 0x01)) { |
818 | // IO base | 800 | /* IO base |
819 | // set temp_register = amount of IO space requested | 801 | * set temp_register = amount |
802 | * of IO space requested | ||
803 | */ | ||
820 | temp_register = base & 0xFFFFFFFE; | 804 | temp_register = base & 0xFFFFFFFE; |
821 | temp_register = (~temp_register) + 1; | 805 | temp_register = (~temp_register) + 1; |
822 | 806 | ||
@@ -834,7 +818,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
834 | } else | 818 | } else |
835 | if (((base & 0x0BL) == 0x08) | 819 | if (((base & 0x0BL) == 0x08) |
836 | && (save_command & 0x02)) { | 820 | && (save_command & 0x02)) { |
837 | // prefetchable memory base | 821 | /* prefetchable memory base */ |
838 | temp_register = base & 0xFFFFFFF0; | 822 | temp_register = base & 0xFFFFFFF0; |
839 | temp_register = (~temp_register) + 1; | 823 | temp_register = (~temp_register) + 1; |
840 | 824 | ||
@@ -851,7 +835,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
851 | } else | 835 | } else |
852 | if (((base & 0x0BL) == 0x00) | 836 | if (((base & 0x0BL) == 0x00) |
853 | && (save_command & 0x02)) { | 837 | && (save_command & 0x02)) { |
854 | // prefetchable memory base | 838 | /* prefetchable memory base */ |
855 | temp_register = base & 0xFFFFFFF0; | 839 | temp_register = base & 0xFFFFFFF0; |
856 | temp_register = (~temp_register) + 1; | 840 | temp_register = (~temp_register) + 1; |
857 | 841 | ||
@@ -868,9 +852,10 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
868 | } else | 852 | } else |
869 | return(1); | 853 | return(1); |
870 | } | 854 | } |
871 | } // End of base register loop | 855 | } /* End of base register loop */ |
872 | } else if ((header_type & 0x7F) == 0x00) { // Standard header | 856 | /* Standard header */ |
873 | // Figure out IO and memory base lengths | 857 | } else if ((header_type & 0x7F) == 0x00) { |
858 | /* Figure out IO and memory base lengths */ | ||
874 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { | 859 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { |
875 | pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base); | 860 | pci_bus_read_config_dword(pci_bus, devfn, cloop, &save_base); |
876 | 861 | ||
@@ -880,11 +865,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
880 | 865 | ||
881 | temp_register = base; | 866 | temp_register = base; |
882 | 867 | ||
883 | if (base) { // If this register is implemented | 868 | /* If this register is implemented */ |
869 | if (base) { | ||
884 | if (((base & 0x03L) == 0x01) | 870 | if (((base & 0x03L) == 0x01) |
885 | && (save_command & 0x01)) { | 871 | && (save_command & 0x01)) { |
886 | // IO base | 872 | /* IO base |
887 | // set temp_register = amount of IO space requested | 873 | * set temp_register = amount |
874 | * of IO space requested | ||
875 | */ | ||
888 | temp_register = base & 0xFFFFFFFE; | 876 | temp_register = base & 0xFFFFFFFE; |
889 | temp_register = (~temp_register) + 1; | 877 | temp_register = (~temp_register) + 1; |
890 | 878 | ||
@@ -901,7 +889,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
901 | } else | 889 | } else |
902 | if (((base & 0x0BL) == 0x08) | 890 | if (((base & 0x0BL) == 0x08) |
903 | && (save_command & 0x02)) { | 891 | && (save_command & 0x02)) { |
904 | // prefetchable memory base | 892 | /* prefetchable memory base */ |
905 | temp_register = base & 0xFFFFFFF0; | 893 | temp_register = base & 0xFFFFFFF0; |
906 | temp_register = (~temp_register) + 1; | 894 | temp_register = (~temp_register) + 1; |
907 | 895 | ||
@@ -918,7 +906,7 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
918 | } else | 906 | } else |
919 | if (((base & 0x0BL) == 0x00) | 907 | if (((base & 0x0BL) == 0x00) |
920 | && (save_command & 0x02)) { | 908 | && (save_command & 0x02)) { |
921 | // prefetchable memory base | 909 | /* prefetchable memory base */ |
922 | temp_register = base & 0xFFFFFFF0; | 910 | temp_register = base & 0xFFFFFFF0; |
923 | temp_register = (~temp_register) + 1; | 911 | temp_register = (~temp_register) + 1; |
924 | 912 | ||
@@ -935,15 +923,14 @@ int cpqhp_save_used_resources (struct controller *ctrl, struct pci_func * func) | |||
935 | } else | 923 | } else |
936 | return(1); | 924 | return(1); |
937 | } | 925 | } |
938 | } // End of base register loop | 926 | } /* End of base register loop */ |
939 | } else { // Some other unknown header type | ||
940 | } | 927 | } |
941 | 928 | ||
942 | // find the next device in this slot | 929 | /* find the next device in this slot */ |
943 | func = cpqhp_slot_find(func->bus, func->device, index++); | 930 | func = cpqhp_slot_find(func->bus, func->device, index++); |
944 | } | 931 | } |
945 | 932 | ||
946 | return(0); | 933 | return 0; |
947 | } | 934 | } |
948 | 935 | ||
949 | 936 | ||
@@ -975,16 +962,16 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) | |||
975 | pci_bus->number = func->bus; | 962 | pci_bus->number = func->bus; |
976 | devfn = PCI_DEVFN(func->device, func->function); | 963 | devfn = PCI_DEVFN(func->device, func->function); |
977 | 964 | ||
978 | // Start at the top of config space so that the control | 965 | /* Start at the top of config space so that the control |
979 | // registers are programmed last | 966 | * registers are programmed last |
980 | for (cloop = 0x3C; cloop > 0; cloop -= 4) { | 967 | */ |
968 | for (cloop = 0x3C; cloop > 0; cloop -= 4) | ||
981 | pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]); | 969 | pci_bus_write_config_dword (pci_bus, devfn, cloop, func->config_space[cloop >> 2]); |
982 | } | ||
983 | 970 | ||
984 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 971 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
985 | 972 | ||
986 | // If this is a bridge device, restore subordinate devices | 973 | /* If this is a bridge device, restore subordinate devices */ |
987 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | 974 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
988 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); | 975 | pci_bus_read_config_byte (pci_bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); |
989 | 976 | ||
990 | sub_bus = (int) secondary_bus; | 977 | sub_bus = (int) secondary_bus; |
@@ -1000,8 +987,9 @@ int cpqhp_configure_board(struct controller *ctrl, struct pci_func * func) | |||
1000 | } | 987 | } |
1001 | } else { | 988 | } else { |
1002 | 989 | ||
1003 | // Check all the base Address Registers to make sure | 990 | /* Check all the base Address Registers to make sure |
1004 | // they are the same. If not, the board is different. | 991 | * they are the same. If not, the board is different. |
992 | */ | ||
1005 | 993 | ||
1006 | for (cloop = 16; cloop < 40; cloop += 4) { | 994 | for (cloop = 16; cloop < 40; cloop += 4) { |
1007 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp); | 995 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &temp); |
@@ -1058,27 +1046,28 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1058 | 1046 | ||
1059 | pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register); | 1047 | pci_bus_read_config_dword (pci_bus, devfn, PCI_VENDOR_ID, &temp_register); |
1060 | 1048 | ||
1061 | // No adapter present | 1049 | /* No adapter present */ |
1062 | if (temp_register == 0xFFFFFFFF) | 1050 | if (temp_register == 0xFFFFFFFF) |
1063 | return(NO_ADAPTER_PRESENT); | 1051 | return(NO_ADAPTER_PRESENT); |
1064 | 1052 | ||
1065 | if (temp_register != func->config_space[0]) | 1053 | if (temp_register != func->config_space[0]) |
1066 | return(ADAPTER_NOT_SAME); | 1054 | return(ADAPTER_NOT_SAME); |
1067 | 1055 | ||
1068 | // Check for same revision number and class code | 1056 | /* Check for same revision number and class code */ |
1069 | pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register); | 1057 | pci_bus_read_config_dword (pci_bus, devfn, PCI_CLASS_REVISION, &temp_register); |
1070 | 1058 | ||
1071 | // Adapter not the same | 1059 | /* Adapter not the same */ |
1072 | if (temp_register != func->config_space[0x08 >> 2]) | 1060 | if (temp_register != func->config_space[0x08 >> 2]) |
1073 | return(ADAPTER_NOT_SAME); | 1061 | return(ADAPTER_NOT_SAME); |
1074 | 1062 | ||
1075 | // Check for Bridge | 1063 | /* Check for Bridge */ |
1076 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); | 1064 | pci_bus_read_config_byte (pci_bus, devfn, PCI_HEADER_TYPE, &header_type); |
1077 | 1065 | ||
1078 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { // PCI-PCI Bridge | 1066 | if ((header_type & 0x7F) == PCI_HEADER_TYPE_BRIDGE) { |
1079 | // In order to continue checking, we must program the | 1067 | /* In order to continue checking, we must program the |
1080 | // bus registers in the bridge to respond to accesses | 1068 | * bus registers in the bridge to respond to accesses |
1081 | // for it's subordinate bus(es) | 1069 | * for its subordinate bus(es) |
1070 | */ | ||
1082 | 1071 | ||
1083 | temp_register = func->config_space[0x18 >> 2]; | 1072 | temp_register = func->config_space[0x18 >> 2]; |
1084 | pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register); | 1073 | pci_bus_write_config_dword (pci_bus, devfn, PCI_PRIMARY_BUS, temp_register); |
@@ -1096,35 +1085,39 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1096 | } | 1085 | } |
1097 | 1086 | ||
1098 | } | 1087 | } |
1099 | // Check to see if it is a standard config header | 1088 | /* Check to see if it is a standard config header */ |
1100 | else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) { | 1089 | else if ((header_type & 0x7F) == PCI_HEADER_TYPE_NORMAL) { |
1101 | // Check subsystem vendor and ID | 1090 | /* Check subsystem vendor and ID */ |
1102 | pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register); | 1091 | pci_bus_read_config_dword (pci_bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &temp_register); |
1103 | 1092 | ||
1104 | if (temp_register != func->config_space[0x2C >> 2]) { | 1093 | if (temp_register != func->config_space[0x2C >> 2]) { |
1105 | // If it's a SMART-2 and the register isn't filled | 1094 | /* If it's a SMART-2 and the register isn't |
1106 | // in, ignore the difference because | 1095 | * filled in, ignore the difference because |
1107 | // they just have an old rev of the firmware | 1096 | * they just have an old rev of the firmware |
1108 | 1097 | */ | |
1109 | if (!((func->config_space[0] == 0xAE100E11) | 1098 | if (!((func->config_space[0] == 0xAE100E11) |
1110 | && (temp_register == 0x00L))) | 1099 | && (temp_register == 0x00L))) |
1111 | return(ADAPTER_NOT_SAME); | 1100 | return(ADAPTER_NOT_SAME); |
1112 | } | 1101 | } |
1113 | // Figure out IO and memory base lengths | 1102 | /* Figure out IO and memory base lengths */ |
1114 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { | 1103 | for (cloop = 0x10; cloop <= 0x24; cloop += 4) { |
1115 | temp_register = 0xFFFFFFFF; | 1104 | temp_register = 0xFFFFFFFF; |
1116 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); | 1105 | pci_bus_write_config_dword (pci_bus, devfn, cloop, temp_register); |
1117 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); | 1106 | pci_bus_read_config_dword (pci_bus, devfn, cloop, &base); |
1118 | if (base) { // If this register is implemented | 1107 | |
1108 | /* If this register is implemented */ | ||
1109 | if (base) { | ||
1119 | if (base & 0x01L) { | 1110 | if (base & 0x01L) { |
1120 | // IO base | 1111 | /* IO base |
1121 | // set base = amount of IO space requested | 1112 | * set base = amount of IO |
1113 | * space requested | ||
1114 | */ | ||
1122 | base = base & 0xFFFFFFFE; | 1115 | base = base & 0xFFFFFFFE; |
1123 | base = (~base) + 1; | 1116 | base = (~base) + 1; |
1124 | 1117 | ||
1125 | type = 1; | 1118 | type = 1; |
1126 | } else { | 1119 | } else { |
1127 | // memory base | 1120 | /* memory base */ |
1128 | base = base & 0xFFFFFFF0; | 1121 | base = base & 0xFFFFFFF0; |
1129 | base = (~base) + 1; | 1122 | base = (~base) + 1; |
1130 | 1123 | ||
@@ -1135,23 +1128,24 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1135 | type = 0; | 1128 | type = 0; |
1136 | } | 1129 | } |
1137 | 1130 | ||
1138 | // Check information in slot structure | 1131 | /* Check information in slot structure */ |
1139 | if (func->base_length[(cloop - 0x10) >> 2] != base) | 1132 | if (func->base_length[(cloop - 0x10) >> 2] != base) |
1140 | return(ADAPTER_NOT_SAME); | 1133 | return(ADAPTER_NOT_SAME); |
1141 | 1134 | ||
1142 | if (func->base_type[(cloop - 0x10) >> 2] != type) | 1135 | if (func->base_type[(cloop - 0x10) >> 2] != type) |
1143 | return(ADAPTER_NOT_SAME); | 1136 | return(ADAPTER_NOT_SAME); |
1144 | 1137 | ||
1145 | } // End of base register loop | 1138 | } /* End of base register loop */ |
1146 | 1139 | ||
1147 | } // End of (type 0 config space) else | 1140 | } /* End of (type 0 config space) else */ |
1148 | else { | 1141 | else { |
1149 | // this is not a type 0 or 1 config space header so | 1142 | /* this is not a type 0 or 1 config space header so |
1150 | // we don't know how to do it | 1143 | * we don't know how to do it |
1144 | */ | ||
1151 | return(DEVICE_TYPE_NOT_SUPPORTED); | 1145 | return(DEVICE_TYPE_NOT_SUPPORTED); |
1152 | } | 1146 | } |
1153 | 1147 | ||
1154 | // Get the next function | 1148 | /* Get the next function */ |
1155 | func = cpqhp_slot_find(func->bus, func->device, index++); | 1149 | func = cpqhp_slot_find(func->bus, func->device, index++); |
1156 | } | 1150 | } |
1157 | 1151 | ||
@@ -1168,7 +1162,7 @@ int cpqhp_valid_replace(struct controller *ctrl, struct pci_func * func) | |||
1168 | * this function is for hot plug ADD! | 1162 | * this function is for hot plug ADD! |
1169 | * | 1163 | * |
1170 | * returns 0 if success | 1164 | * returns 0 if success |
1171 | */ | 1165 | */ |
1172 | int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start) | 1166 | int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_start) |
1173 | { | 1167 | { |
1174 | u8 temp; | 1168 | u8 temp; |
@@ -1187,10 +1181,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1187 | rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff); | 1181 | rom_resource_table = detect_HRT_floating_pointer(rom_start, rom_start+0xffff); |
1188 | dbg("rom_resource_table = %p\n", rom_resource_table); | 1182 | dbg("rom_resource_table = %p\n", rom_resource_table); |
1189 | 1183 | ||
1190 | if (rom_resource_table == NULL) { | 1184 | if (rom_resource_table == NULL) |
1191 | return -ENODEV; | 1185 | return -ENODEV; |
1192 | } | 1186 | |
1193 | // Sum all resources and setup resource maps | 1187 | /* Sum all resources and setup resource maps */ |
1194 | unused_IRQ = readl(rom_resource_table + UNUSED_IRQ); | 1188 | unused_IRQ = readl(rom_resource_table + UNUSED_IRQ); |
1195 | dbg("unused_IRQ = %x\n", unused_IRQ); | 1189 | dbg("unused_IRQ = %x\n", unused_IRQ); |
1196 | 1190 | ||
@@ -1222,13 +1216,11 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1222 | 1216 | ||
1223 | temp = 0; | 1217 | temp = 0; |
1224 | 1218 | ||
1225 | if (!cpqhp_nic_irq) { | 1219 | if (!cpqhp_nic_irq) |
1226 | cpqhp_nic_irq = ctrl->cfgspc_irq; | 1220 | cpqhp_nic_irq = ctrl->cfgspc_irq; |
1227 | } | ||
1228 | 1221 | ||
1229 | if (!cpqhp_disk_irq) { | 1222 | if (!cpqhp_disk_irq) |
1230 | cpqhp_disk_irq = ctrl->cfgspc_irq; | 1223 | cpqhp_disk_irq = ctrl->cfgspc_irq; |
1231 | } | ||
1232 | 1224 | ||
1233 | dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq); | 1225 | dbg("cpqhp_disk_irq, cpqhp_nic_irq= %d, %d\n", cpqhp_disk_irq, cpqhp_nic_irq); |
1234 | 1226 | ||
@@ -1262,13 +1254,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1262 | dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length, | 1254 | dev_func, io_base, io_length, mem_base, mem_length, pre_mem_base, pre_mem_length, |
1263 | primary_bus, secondary_bus, max_bus); | 1255 | primary_bus, secondary_bus, max_bus); |
1264 | 1256 | ||
1265 | // If this entry isn't for our controller's bus, ignore it | 1257 | /* If this entry isn't for our controller's bus, ignore it */ |
1266 | if (primary_bus != ctrl->bus) { | 1258 | if (primary_bus != ctrl->bus) { |
1267 | i--; | 1259 | i--; |
1268 | one_slot += sizeof (struct slot_rt); | 1260 | one_slot += sizeof (struct slot_rt); |
1269 | continue; | 1261 | continue; |
1270 | } | 1262 | } |
1271 | // find out if this entry is for an occupied slot | 1263 | /* find out if this entry is for an occupied slot */ |
1272 | ctrl->pci_bus->number = primary_bus; | 1264 | ctrl->pci_bus->number = primary_bus; |
1273 | pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword); | 1265 | pci_bus_read_config_dword (ctrl->pci_bus, dev_func, PCI_VENDOR_ID, &temp_dword); |
1274 | dbg("temp_D_word = %x\n", temp_dword); | 1266 | dbg("temp_D_word = %x\n", temp_dword); |
@@ -1282,13 +1274,13 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1282 | func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++); | 1274 | func = cpqhp_slot_find(primary_bus, dev_func >> 3, index++); |
1283 | } | 1275 | } |
1284 | 1276 | ||
1285 | // If we can't find a match, skip this table entry | 1277 | /* If we can't find a match, skip this table entry */ |
1286 | if (!func) { | 1278 | if (!func) { |
1287 | i--; | 1279 | i--; |
1288 | one_slot += sizeof (struct slot_rt); | 1280 | one_slot += sizeof (struct slot_rt); |
1289 | continue; | 1281 | continue; |
1290 | } | 1282 | } |
1291 | // this may not work and shouldn't be used | 1283 | /* this may not work and shouldn't be used */ |
1292 | if (secondary_bus != primary_bus) | 1284 | if (secondary_bus != primary_bus) |
1293 | bridged_slot = 1; | 1285 | bridged_slot = 1; |
1294 | else | 1286 | else |
@@ -1301,7 +1293,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1301 | } | 1293 | } |
1302 | 1294 | ||
1303 | 1295 | ||
1304 | // If we've got a valid IO base, use it | 1296 | /* If we've got a valid IO base, use it */ |
1305 | 1297 | ||
1306 | temp_dword = io_base + io_length; | 1298 | temp_dword = io_base + io_length; |
1307 | 1299 | ||
@@ -1325,7 +1317,7 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1325 | } | 1317 | } |
1326 | } | 1318 | } |
1327 | 1319 | ||
1328 | // If we've got a valid memory base, use it | 1320 | /* If we've got a valid memory base, use it */ |
1329 | temp_dword = mem_base + mem_length; | 1321 | temp_dword = mem_base + mem_length; |
1330 | if ((mem_base) && (temp_dword < 0x10000)) { | 1322 | if ((mem_base) && (temp_dword < 0x10000)) { |
1331 | mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL); | 1323 | mem_node = kmalloc(sizeof(*mem_node), GFP_KERNEL); |
@@ -1348,8 +1340,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1348 | } | 1340 | } |
1349 | } | 1341 | } |
1350 | 1342 | ||
1351 | // If we've got a valid prefetchable memory base, and | 1343 | /* If we've got a valid prefetchable memory base, and |
1352 | // the base + length isn't greater than 0xFFFF | 1344 | * the base + length isn't greater than 0xFFFF |
1345 | */ | ||
1353 | temp_dword = pre_mem_base + pre_mem_length; | 1346 | temp_dword = pre_mem_base + pre_mem_length; |
1354 | if ((pre_mem_base) && (temp_dword < 0x10000)) { | 1347 | if ((pre_mem_base) && (temp_dword < 0x10000)) { |
1355 | p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL); | 1348 | p_mem_node = kmalloc(sizeof(*p_mem_node), GFP_KERNEL); |
@@ -1372,9 +1365,10 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1372 | } | 1365 | } |
1373 | } | 1366 | } |
1374 | 1367 | ||
1375 | // If we've got a valid bus number, use it | 1368 | /* If we've got a valid bus number, use it |
1376 | // The second condition is to ignore bus numbers on | 1369 | * The second condition is to ignore bus numbers on |
1377 | // populated slots that don't have PCI-PCI bridges | 1370 | * populated slots that don't have PCI-PCI bridges |
1371 | */ | ||
1378 | if (secondary_bus && (secondary_bus != primary_bus)) { | 1372 | if (secondary_bus && (secondary_bus != primary_bus)) { |
1379 | bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL); | 1373 | bus_node = kmalloc(sizeof(*bus_node), GFP_KERNEL); |
1380 | if (!bus_node) | 1374 | if (!bus_node) |
@@ -1398,8 +1392,9 @@ int cpqhp_find_available_resources(struct controller *ctrl, void __iomem *rom_st | |||
1398 | one_slot += sizeof (struct slot_rt); | 1392 | one_slot += sizeof (struct slot_rt); |
1399 | } | 1393 | } |
1400 | 1394 | ||
1401 | // If all of the following fail, we don't have any resources for | 1395 | /* If all of the following fail, we don't have any resources for |
1402 | // hot plug add | 1396 | * hot plug add |
1397 | */ | ||
1403 | rc = 1; | 1398 | rc = 1; |
1404 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head)); | 1399 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->mem_head)); |
1405 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head)); | 1400 | rc &= cpqhp_resource_sort_and_combine(&(ctrl->p_mem_head)); |
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c index dd18f857dfb0..7485ffda950c 100644 --- a/drivers/pci/hotplug/ibmphp_core.c +++ b/drivers/pci/hotplug/ibmphp_core.c | |||
@@ -153,45 +153,47 @@ int ibmphp_init_devno(struct slot **cur_slot) | |||
153 | return -1; | 153 | return -1; |
154 | } | 154 | } |
155 | for (loop = 0; loop < len; loop++) { | 155 | for (loop = 0; loop < len; loop++) { |
156 | if ((*cur_slot)->number == rtable->slots[loop].slot) { | 156 | if ((*cur_slot)->number == rtable->slots[loop].slot && |
157 | if ((*cur_slot)->bus == rtable->slots[loop].bus) { | 157 | (*cur_slot)->bus == rtable->slots[loop].bus) { |
158 | struct io_apic_irq_attr irq_attr; | ||
159 | |||
158 | (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); | 160 | (*cur_slot)->device = PCI_SLOT(rtable->slots[loop].devfn); |
159 | for (i = 0; i < 4; i++) | 161 | for (i = 0; i < 4; i++) |
160 | (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus, | 162 | (*cur_slot)->irq[i] = IO_APIC_get_PCI_irq_vector((int) (*cur_slot)->bus, |
161 | (int) (*cur_slot)->device, i); | 163 | (int) (*cur_slot)->device, i, |
162 | 164 | &irq_attr); | |
163 | debug("(*cur_slot)->irq[0] = %x\n", | 165 | |
164 | (*cur_slot)->irq[0]); | 166 | debug("(*cur_slot)->irq[0] = %x\n", |
165 | debug("(*cur_slot)->irq[1] = %x\n", | 167 | (*cur_slot)->irq[0]); |
166 | (*cur_slot)->irq[1]); | 168 | debug("(*cur_slot)->irq[1] = %x\n", |
167 | debug("(*cur_slot)->irq[2] = %x\n", | 169 | (*cur_slot)->irq[1]); |
168 | (*cur_slot)->irq[2]); | 170 | debug("(*cur_slot)->irq[2] = %x\n", |
169 | debug("(*cur_slot)->irq[3] = %x\n", | 171 | (*cur_slot)->irq[2]); |
170 | (*cur_slot)->irq[3]); | 172 | debug("(*cur_slot)->irq[3] = %x\n", |
171 | 173 | (*cur_slot)->irq[3]); | |
172 | debug("rtable->exlusive_irqs = %x\n", | 174 | |
175 | debug("rtable->exlusive_irqs = %x\n", | ||
173 | rtable->exclusive_irqs); | 176 | rtable->exclusive_irqs); |
174 | debug("rtable->slots[loop].irq[0].bitmap = %x\n", | 177 | debug("rtable->slots[loop].irq[0].bitmap = %x\n", |
175 | rtable->slots[loop].irq[0].bitmap); | 178 | rtable->slots[loop].irq[0].bitmap); |
176 | debug("rtable->slots[loop].irq[1].bitmap = %x\n", | 179 | debug("rtable->slots[loop].irq[1].bitmap = %x\n", |
177 | rtable->slots[loop].irq[1].bitmap); | 180 | rtable->slots[loop].irq[1].bitmap); |
178 | debug("rtable->slots[loop].irq[2].bitmap = %x\n", | 181 | debug("rtable->slots[loop].irq[2].bitmap = %x\n", |
179 | rtable->slots[loop].irq[2].bitmap); | 182 | rtable->slots[loop].irq[2].bitmap); |
180 | debug("rtable->slots[loop].irq[3].bitmap = %x\n", | 183 | debug("rtable->slots[loop].irq[3].bitmap = %x\n", |
181 | rtable->slots[loop].irq[3].bitmap); | 184 | rtable->slots[loop].irq[3].bitmap); |
182 | 185 | ||
183 | debug("rtable->slots[loop].irq[0].link = %x\n", | 186 | debug("rtable->slots[loop].irq[0].link = %x\n", |
184 | rtable->slots[loop].irq[0].link); | 187 | rtable->slots[loop].irq[0].link); |
185 | debug("rtable->slots[loop].irq[1].link = %x\n", | 188 | debug("rtable->slots[loop].irq[1].link = %x\n", |
186 | rtable->slots[loop].irq[1].link); | 189 | rtable->slots[loop].irq[1].link); |
187 | debug("rtable->slots[loop].irq[2].link = %x\n", | 190 | debug("rtable->slots[loop].irq[2].link = %x\n", |
188 | rtable->slots[loop].irq[2].link); | 191 | rtable->slots[loop].irq[2].link); |
189 | debug("rtable->slots[loop].irq[3].link = %x\n", | 192 | debug("rtable->slots[loop].irq[3].link = %x\n", |
190 | rtable->slots[loop].irq[3].link); | 193 | rtable->slots[loop].irq[3].link); |
191 | debug("end of init_devno\n"); | 194 | debug("end of init_devno\n"); |
192 | kfree(rtable); | 195 | kfree(rtable); |
193 | return 0; | 196 | return 0; |
194 | } | ||
195 | } | 197 | } |
196 | } | 198 | } |
197 | 199 | ||
@@ -1316,7 +1318,6 @@ error: | |||
1316 | } | 1318 | } |
1317 | 1319 | ||
1318 | struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { | 1320 | struct hotplug_slot_ops ibmphp_hotplug_slot_ops = { |
1319 | .owner = THIS_MODULE, | ||
1320 | .set_attention_status = set_attention_status, | 1321 | .set_attention_status = set_attention_status, |
1321 | .enable_slot = enable_slot, | 1322 | .enable_slot = enable_slot, |
1322 | .disable_slot = ibmphp_disable_slot, | 1323 | .disable_slot = ibmphp_disable_slot, |
@@ -1419,3 +1420,4 @@ static void __exit ibmphp_exit(void) | |||
1419 | } | 1420 | } |
1420 | 1421 | ||
1421 | module_init(ibmphp_init); | 1422 | module_init(ibmphp_init); |
1423 | module_exit(ibmphp_exit); | ||
diff --git a/drivers/pci/hotplug/pci_hotplug_core.c b/drivers/pci/hotplug/pci_hotplug_core.c index 535fce0f07f9..844580489d4d 100644 --- a/drivers/pci/hotplug/pci_hotplug_core.c +++ b/drivers/pci/hotplug/pci_hotplug_core.c | |||
@@ -347,125 +347,129 @@ static struct pci_slot_attribute hotplug_slot_attr_test = { | |||
347 | .store = test_write_file | 347 | .store = test_write_file |
348 | }; | 348 | }; |
349 | 349 | ||
350 | static int has_power_file(struct pci_slot *pci_slot) | 350 | static bool has_power_file(struct pci_slot *pci_slot) |
351 | { | 351 | { |
352 | struct hotplug_slot *slot = pci_slot->hotplug; | 352 | struct hotplug_slot *slot = pci_slot->hotplug; |
353 | if ((!slot) || (!slot->ops)) | 353 | if ((!slot) || (!slot->ops)) |
354 | return -ENODEV; | 354 | return false; |
355 | if ((slot->ops->enable_slot) || | 355 | if ((slot->ops->enable_slot) || |
356 | (slot->ops->disable_slot) || | 356 | (slot->ops->disable_slot) || |
357 | (slot->ops->get_power_status)) | 357 | (slot->ops->get_power_status)) |
358 | return 0; | 358 | return true; |
359 | return -ENOENT; | 359 | return false; |
360 | } | 360 | } |
361 | 361 | ||
362 | static int has_attention_file(struct pci_slot *pci_slot) | 362 | static bool has_attention_file(struct pci_slot *pci_slot) |
363 | { | 363 | { |
364 | struct hotplug_slot *slot = pci_slot->hotplug; | 364 | struct hotplug_slot *slot = pci_slot->hotplug; |
365 | if ((!slot) || (!slot->ops)) | 365 | if ((!slot) || (!slot->ops)) |
366 | return -ENODEV; | 366 | return false; |
367 | if ((slot->ops->set_attention_status) || | 367 | if ((slot->ops->set_attention_status) || |
368 | (slot->ops->get_attention_status)) | 368 | (slot->ops->get_attention_status)) |
369 | return 0; | 369 | return true; |
370 | return -ENOENT; | 370 | return false; |
371 | } | 371 | } |
372 | 372 | ||
373 | static int has_latch_file(struct pci_slot *pci_slot) | 373 | static bool has_latch_file(struct pci_slot *pci_slot) |
374 | { | 374 | { |
375 | struct hotplug_slot *slot = pci_slot->hotplug; | 375 | struct hotplug_slot *slot = pci_slot->hotplug; |
376 | if ((!slot) || (!slot->ops)) | 376 | if ((!slot) || (!slot->ops)) |
377 | return -ENODEV; | 377 | return false; |
378 | if (slot->ops->get_latch_status) | 378 | if (slot->ops->get_latch_status) |
379 | return 0; | 379 | return true; |
380 | return -ENOENT; | 380 | return false; |
381 | } | 381 | } |
382 | 382 | ||
383 | static int has_adapter_file(struct pci_slot *pci_slot) | 383 | static bool has_adapter_file(struct pci_slot *pci_slot) |
384 | { | 384 | { |
385 | struct hotplug_slot *slot = pci_slot->hotplug; | 385 | struct hotplug_slot *slot = pci_slot->hotplug; |
386 | if ((!slot) || (!slot->ops)) | 386 | if ((!slot) || (!slot->ops)) |
387 | return -ENODEV; | 387 | return false; |
388 | if (slot->ops->get_adapter_status) | 388 | if (slot->ops->get_adapter_status) |
389 | return 0; | 389 | return true; |
390 | return -ENOENT; | 390 | return false; |
391 | } | 391 | } |
392 | 392 | ||
393 | static int has_max_bus_speed_file(struct pci_slot *pci_slot) | 393 | static bool has_max_bus_speed_file(struct pci_slot *pci_slot) |
394 | { | 394 | { |
395 | struct hotplug_slot *slot = pci_slot->hotplug; | 395 | struct hotplug_slot *slot = pci_slot->hotplug; |
396 | if ((!slot) || (!slot->ops)) | 396 | if ((!slot) || (!slot->ops)) |
397 | return -ENODEV; | 397 | return false; |
398 | if (slot->ops->get_max_bus_speed) | 398 | if (slot->ops->get_max_bus_speed) |
399 | return 0; | 399 | return true; |
400 | return -ENOENT; | 400 | return false; |
401 | } | 401 | } |
402 | 402 | ||
403 | static int has_cur_bus_speed_file(struct pci_slot *pci_slot) | 403 | static bool has_cur_bus_speed_file(struct pci_slot *pci_slot) |
404 | { | 404 | { |
405 | struct hotplug_slot *slot = pci_slot->hotplug; | 405 | struct hotplug_slot *slot = pci_slot->hotplug; |
406 | if ((!slot) || (!slot->ops)) | 406 | if ((!slot) || (!slot->ops)) |
407 | return -ENODEV; | 407 | return false; |
408 | if (slot->ops->get_cur_bus_speed) | 408 | if (slot->ops->get_cur_bus_speed) |
409 | return 0; | 409 | return true; |
410 | return -ENOENT; | 410 | return false; |
411 | } | 411 | } |
412 | 412 | ||
413 | static int has_test_file(struct pci_slot *pci_slot) | 413 | static bool has_test_file(struct pci_slot *pci_slot) |
414 | { | 414 | { |
415 | struct hotplug_slot *slot = pci_slot->hotplug; | 415 | struct hotplug_slot *slot = pci_slot->hotplug; |
416 | if ((!slot) || (!slot->ops)) | 416 | if ((!slot) || (!slot->ops)) |
417 | return -ENODEV; | 417 | return false; |
418 | if (slot->ops->hardware_test) | 418 | if (slot->ops->hardware_test) |
419 | return 0; | 419 | return true; |
420 | return -ENOENT; | 420 | return false; |
421 | } | 421 | } |
422 | 422 | ||
423 | static int fs_add_slot(struct pci_slot *slot) | 423 | static int fs_add_slot(struct pci_slot *slot) |
424 | { | 424 | { |
425 | int retval = 0; | 425 | int retval = 0; |
426 | 426 | ||
427 | if (has_power_file(slot) == 0) { | 427 | /* Create symbolic link to the hotplug driver module */ |
428 | retval = sysfs_create_file(&slot->kobj, &hotplug_slot_attr_power.attr); | 428 | pci_hp_create_module_link(slot); |
429 | |||
430 | if (has_power_file(slot)) { | ||
431 | retval = sysfs_create_file(&slot->kobj, | ||
432 | &hotplug_slot_attr_power.attr); | ||
429 | if (retval) | 433 | if (retval) |
430 | goto exit_power; | 434 | goto exit_power; |
431 | } | 435 | } |
432 | 436 | ||
433 | if (has_attention_file(slot) == 0) { | 437 | if (has_attention_file(slot)) { |
434 | retval = sysfs_create_file(&slot->kobj, | 438 | retval = sysfs_create_file(&slot->kobj, |
435 | &hotplug_slot_attr_attention.attr); | 439 | &hotplug_slot_attr_attention.attr); |
436 | if (retval) | 440 | if (retval) |
437 | goto exit_attention; | 441 | goto exit_attention; |
438 | } | 442 | } |
439 | 443 | ||
440 | if (has_latch_file(slot) == 0) { | 444 | if (has_latch_file(slot)) { |
441 | retval = sysfs_create_file(&slot->kobj, | 445 | retval = sysfs_create_file(&slot->kobj, |
442 | &hotplug_slot_attr_latch.attr); | 446 | &hotplug_slot_attr_latch.attr); |
443 | if (retval) | 447 | if (retval) |
444 | goto exit_latch; | 448 | goto exit_latch; |
445 | } | 449 | } |
446 | 450 | ||
447 | if (has_adapter_file(slot) == 0) { | 451 | if (has_adapter_file(slot)) { |
448 | retval = sysfs_create_file(&slot->kobj, | 452 | retval = sysfs_create_file(&slot->kobj, |
449 | &hotplug_slot_attr_presence.attr); | 453 | &hotplug_slot_attr_presence.attr); |
450 | if (retval) | 454 | if (retval) |
451 | goto exit_adapter; | 455 | goto exit_adapter; |
452 | } | 456 | } |
453 | 457 | ||
454 | if (has_max_bus_speed_file(slot) == 0) { | 458 | if (has_max_bus_speed_file(slot)) { |
455 | retval = sysfs_create_file(&slot->kobj, | 459 | retval = sysfs_create_file(&slot->kobj, |
456 | &hotplug_slot_attr_max_bus_speed.attr); | 460 | &hotplug_slot_attr_max_bus_speed.attr); |
457 | if (retval) | 461 | if (retval) |
458 | goto exit_max_speed; | 462 | goto exit_max_speed; |
459 | } | 463 | } |
460 | 464 | ||
461 | if (has_cur_bus_speed_file(slot) == 0) { | 465 | if (has_cur_bus_speed_file(slot)) { |
462 | retval = sysfs_create_file(&slot->kobj, | 466 | retval = sysfs_create_file(&slot->kobj, |
463 | &hotplug_slot_attr_cur_bus_speed.attr); | 467 | &hotplug_slot_attr_cur_bus_speed.attr); |
464 | if (retval) | 468 | if (retval) |
465 | goto exit_cur_speed; | 469 | goto exit_cur_speed; |
466 | } | 470 | } |
467 | 471 | ||
468 | if (has_test_file(slot) == 0) { | 472 | if (has_test_file(slot)) { |
469 | retval = sysfs_create_file(&slot->kobj, | 473 | retval = sysfs_create_file(&slot->kobj, |
470 | &hotplug_slot_attr_test.attr); | 474 | &hotplug_slot_attr_test.attr); |
471 | if (retval) | 475 | if (retval) |
@@ -475,55 +479,61 @@ static int fs_add_slot(struct pci_slot *slot) | |||
475 | goto exit; | 479 | goto exit; |
476 | 480 | ||
477 | exit_test: | 481 | exit_test: |
478 | if (has_cur_bus_speed_file(slot) == 0) | 482 | if (has_cur_bus_speed_file(slot)) |
479 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); | 483 | sysfs_remove_file(&slot->kobj, |
480 | 484 | &hotplug_slot_attr_cur_bus_speed.attr); | |
481 | exit_cur_speed: | 485 | exit_cur_speed: |
482 | if (has_max_bus_speed_file(slot) == 0) | 486 | if (has_max_bus_speed_file(slot)) |
483 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); | 487 | sysfs_remove_file(&slot->kobj, |
484 | 488 | &hotplug_slot_attr_max_bus_speed.attr); | |
485 | exit_max_speed: | 489 | exit_max_speed: |
486 | if (has_adapter_file(slot) == 0) | 490 | if (has_adapter_file(slot)) |
487 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); | 491 | sysfs_remove_file(&slot->kobj, |
488 | 492 | &hotplug_slot_attr_presence.attr); | |
489 | exit_adapter: | 493 | exit_adapter: |
490 | if (has_latch_file(slot) == 0) | 494 | if (has_latch_file(slot)) |
491 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); | 495 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); |
492 | |||
493 | exit_latch: | 496 | exit_latch: |
494 | if (has_attention_file(slot) == 0) | 497 | if (has_attention_file(slot)) |
495 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr); | 498 | sysfs_remove_file(&slot->kobj, |
496 | 499 | &hotplug_slot_attr_attention.attr); | |
497 | exit_attention: | 500 | exit_attention: |
498 | if (has_power_file(slot) == 0) | 501 | if (has_power_file(slot)) |
499 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); | 502 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); |
500 | exit_power: | 503 | exit_power: |
504 | pci_hp_remove_module_link(slot); | ||
501 | exit: | 505 | exit: |
502 | return retval; | 506 | return retval; |
503 | } | 507 | } |
504 | 508 | ||
505 | static void fs_remove_slot(struct pci_slot *slot) | 509 | static void fs_remove_slot(struct pci_slot *slot) |
506 | { | 510 | { |
507 | if (has_power_file(slot) == 0) | 511 | if (has_power_file(slot)) |
508 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); | 512 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_power.attr); |
509 | 513 | ||
510 | if (has_attention_file(slot) == 0) | 514 | if (has_attention_file(slot)) |
511 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_attention.attr); | 515 | sysfs_remove_file(&slot->kobj, |
516 | &hotplug_slot_attr_attention.attr); | ||
512 | 517 | ||
513 | if (has_latch_file(slot) == 0) | 518 | if (has_latch_file(slot)) |
514 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); | 519 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_latch.attr); |
515 | 520 | ||
516 | if (has_adapter_file(slot) == 0) | 521 | if (has_adapter_file(slot)) |
517 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_presence.attr); | 522 | sysfs_remove_file(&slot->kobj, |
523 | &hotplug_slot_attr_presence.attr); | ||
518 | 524 | ||
519 | if (has_max_bus_speed_file(slot) == 0) | 525 | if (has_max_bus_speed_file(slot)) |
520 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_max_bus_speed.attr); | 526 | sysfs_remove_file(&slot->kobj, |
527 | &hotplug_slot_attr_max_bus_speed.attr); | ||
521 | 528 | ||
522 | if (has_cur_bus_speed_file(slot) == 0) | 529 | if (has_cur_bus_speed_file(slot)) |
523 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_cur_bus_speed.attr); | 530 | sysfs_remove_file(&slot->kobj, |
531 | &hotplug_slot_attr_cur_bus_speed.attr); | ||
524 | 532 | ||
525 | if (has_test_file(slot) == 0) | 533 | if (has_test_file(slot)) |
526 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); | 534 | sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_test.attr); |
535 | |||
536 | pci_hp_remove_module_link(slot); | ||
527 | } | 537 | } |
528 | 538 | ||
529 | static struct hotplug_slot *get_slot_from_name (const char *name) | 539 | static struct hotplug_slot *get_slot_from_name (const char *name) |
@@ -540,10 +550,10 @@ static struct hotplug_slot *get_slot_from_name (const char *name) | |||
540 | } | 550 | } |
541 | 551 | ||
542 | /** | 552 | /** |
543 | * pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem | 553 | * __pci_hp_register - register a hotplug_slot with the PCI hotplug subsystem |
544 | * @bus: bus this slot is on | 554 | * @bus: bus this slot is on |
545 | * @slot: pointer to the &struct hotplug_slot to register | 555 | * @slot: pointer to the &struct hotplug_slot to register |
546 | * @slot_nr: slot number | 556 | * @devnr: device number |
547 | * @name: name registered with kobject core | 557 | * @name: name registered with kobject core |
548 | * | 558 | * |
549 | * Registers a hotplug slot with the pci hotplug subsystem, which will allow | 559 | * Registers a hotplug slot with the pci hotplug subsystem, which will allow |
@@ -551,8 +561,9 @@ static struct hotplug_slot *get_slot_from_name (const char *name) | |||
551 | * | 561 | * |
552 | * Returns 0 if successful, anything else for an error. | 562 | * Returns 0 if successful, anything else for an error. |
553 | */ | 563 | */ |
554 | int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr, | 564 | int __pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, |
555 | const char *name) | 565 | int devnr, const char *name, |
566 | struct module *owner, const char *mod_name) | ||
556 | { | 567 | { |
557 | int result; | 568 | int result; |
558 | struct pci_slot *pci_slot; | 569 | struct pci_slot *pci_slot; |
@@ -567,14 +578,16 @@ int pci_hp_register(struct hotplug_slot *slot, struct pci_bus *bus, int slot_nr, | |||
567 | return -EINVAL; | 578 | return -EINVAL; |
568 | } | 579 | } |
569 | 580 | ||
570 | mutex_lock(&pci_hp_mutex); | 581 | slot->ops->owner = owner; |
582 | slot->ops->mod_name = mod_name; | ||
571 | 583 | ||
584 | mutex_lock(&pci_hp_mutex); | ||
572 | /* | 585 | /* |
573 | * No problems if we call this interface from both ACPI_PCI_SLOT | 586 | * No problems if we call this interface from both ACPI_PCI_SLOT |
574 | * driver and call it here again. If we've already created the | 587 | * driver and call it here again. If we've already created the |
575 | * pci_slot, the interface will simply bump the refcount. | 588 | * pci_slot, the interface will simply bump the refcount. |
576 | */ | 589 | */ |
577 | pci_slot = pci_create_slot(bus, slot_nr, name, slot); | 590 | pci_slot = pci_create_slot(bus, devnr, name, slot); |
578 | if (IS_ERR(pci_slot)) { | 591 | if (IS_ERR(pci_slot)) { |
579 | result = PTR_ERR(pci_slot); | 592 | result = PTR_ERR(pci_slot); |
580 | goto out; | 593 | goto out; |
@@ -684,6 +697,6 @@ MODULE_LICENSE("GPL"); | |||
684 | module_param(debug, bool, 0644); | 697 | module_param(debug, bool, 0644); |
685 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); | 698 | MODULE_PARM_DESC(debug, "Debugging mode enabled or not"); |
686 | 699 | ||
687 | EXPORT_SYMBOL_GPL(pci_hp_register); | 700 | EXPORT_SYMBOL_GPL(__pci_hp_register); |
688 | EXPORT_SYMBOL_GPL(pci_hp_deregister); | 701 | EXPORT_SYMBOL_GPL(pci_hp_deregister); |
689 | EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); | 702 | EXPORT_SYMBOL_GPL(pci_hp_change_slot_info); |
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index 0a368547e633..e6cf096498be 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -81,7 +81,6 @@ struct slot { | |||
81 | struct hpc_ops *hpc_ops; | 81 | struct hpc_ops *hpc_ops; |
82 | struct hotplug_slot *hotplug_slot; | 82 | struct hotplug_slot *hotplug_slot; |
83 | struct list_head slot_list; | 83 | struct list_head slot_list; |
84 | unsigned long last_emi_toggle; | ||
85 | struct delayed_work work; /* work for button event */ | 84 | struct delayed_work work; /* work for button event */ |
86 | struct mutex lock; | 85 | struct mutex lock; |
87 | }; | 86 | }; |
@@ -203,8 +202,6 @@ struct hpc_ops { | |||
203 | int (*set_attention_status)(struct slot *slot, u8 status); | 202 | int (*set_attention_status)(struct slot *slot, u8 status); |
204 | int (*get_latch_status)(struct slot *slot, u8 *status); | 203 | int (*get_latch_status)(struct slot *slot, u8 *status); |
205 | int (*get_adapter_status)(struct slot *slot, u8 *status); | 204 | int (*get_adapter_status)(struct slot *slot, u8 *status); |
206 | int (*get_emi_status)(struct slot *slot, u8 *status); | ||
207 | int (*toggle_emi)(struct slot *slot); | ||
208 | int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | 205 | int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); |
209 | int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); | 206 | int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed); |
210 | int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val); | 207 | int (*get_max_lnk_width)(struct slot *slot, enum pcie_link_width *val); |
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c index fb254b2454de..2317557fdee6 100644 --- a/drivers/pci/hotplug/pciehp_core.c +++ b/drivers/pci/hotplug/pciehp_core.c | |||
@@ -73,7 +73,6 @@ static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *val | |||
73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 73 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
74 | 74 | ||
75 | static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { | 75 | static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { |
76 | .owner = THIS_MODULE, | ||
77 | .set_attention_status = set_attention_status, | 76 | .set_attention_status = set_attention_status, |
78 | .enable_slot = enable_slot, | 77 | .enable_slot = enable_slot, |
79 | .disable_slot = disable_slot, | 78 | .disable_slot = disable_slot, |
@@ -85,99 +84,6 @@ static struct hotplug_slot_ops pciehp_hotplug_slot_ops = { | |||
85 | .get_cur_bus_speed = get_cur_bus_speed, | 84 | .get_cur_bus_speed = get_cur_bus_speed, |
86 | }; | 85 | }; |
87 | 86 | ||
88 | /* | ||
89 | * Check the status of the Electro Mechanical Interlock (EMI) | ||
90 | */ | ||
91 | static int get_lock_status(struct hotplug_slot *hotplug_slot, u8 *value) | ||
92 | { | ||
93 | struct slot *slot = hotplug_slot->private; | ||
94 | return (slot->hpc_ops->get_emi_status(slot, value)); | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * sysfs interface for the Electro Mechanical Interlock (EMI) | ||
99 | * 1 == locked, 0 == unlocked | ||
100 | */ | ||
101 | static ssize_t lock_read_file(struct hotplug_slot *slot, char *buf) | ||
102 | { | ||
103 | int retval; | ||
104 | u8 value; | ||
105 | |||
106 | retval = get_lock_status(slot, &value); | ||
107 | if (retval) | ||
108 | goto lock_read_exit; | ||
109 | retval = sprintf (buf, "%d\n", value); | ||
110 | |||
111 | lock_read_exit: | ||
112 | return retval; | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Change the status of the Electro Mechanical Interlock (EMI) | ||
117 | * This is a toggle - in addition there must be at least 1 second | ||
118 | * in between toggles. | ||
119 | */ | ||
120 | static int set_lock_status(struct hotplug_slot *hotplug_slot, u8 status) | ||
121 | { | ||
122 | struct slot *slot = hotplug_slot->private; | ||
123 | int retval; | ||
124 | u8 value; | ||
125 | |||
126 | mutex_lock(&slot->ctrl->crit_sect); | ||
127 | |||
128 | /* has it been >1 sec since our last toggle? */ | ||
129 | if ((get_seconds() - slot->last_emi_toggle) < 1) { | ||
130 | mutex_unlock(&slot->ctrl->crit_sect); | ||
131 | return -EINVAL; | ||
132 | } | ||
133 | |||
134 | /* see what our current state is */ | ||
135 | retval = get_lock_status(hotplug_slot, &value); | ||
136 | if (retval || (value == status)) | ||
137 | goto set_lock_exit; | ||
138 | |||
139 | slot->hpc_ops->toggle_emi(slot); | ||
140 | set_lock_exit: | ||
141 | mutex_unlock(&slot->ctrl->crit_sect); | ||
142 | return 0; | ||
143 | } | ||
144 | |||
145 | /* | ||
146 | * sysfs interface which allows the user to toggle the Electro Mechanical | ||
147 | * Interlock. Valid values are either 0 or 1. 0 == unlock, 1 == lock | ||
148 | */ | ||
149 | static ssize_t lock_write_file(struct hotplug_slot *hotplug_slot, | ||
150 | const char *buf, size_t count) | ||
151 | { | ||
152 | struct slot *slot = hotplug_slot->private; | ||
153 | unsigned long llock; | ||
154 | u8 lock; | ||
155 | int retval = 0; | ||
156 | |||
157 | llock = simple_strtoul(buf, NULL, 10); | ||
158 | lock = (u8)(llock & 0xff); | ||
159 | |||
160 | switch (lock) { | ||
161 | case 0: | ||
162 | case 1: | ||
163 | retval = set_lock_status(hotplug_slot, lock); | ||
164 | break; | ||
165 | default: | ||
166 | ctrl_err(slot->ctrl, "%d is an invalid lock value\n", | ||
167 | lock); | ||
168 | retval = -EINVAL; | ||
169 | } | ||
170 | if (retval) | ||
171 | return retval; | ||
172 | return count; | ||
173 | } | ||
174 | |||
175 | static struct hotplug_slot_attribute hotplug_slot_attr_lock = { | ||
176 | .attr = {.name = "lock", .mode = S_IFREG | S_IRUGO | S_IWUSR}, | ||
177 | .show = lock_read_file, | ||
178 | .store = lock_write_file | ||
179 | }; | ||
180 | |||
181 | /** | 87 | /** |
182 | * release_slot - free up the memory used by a slot | 88 | * release_slot - free up the memory used by a slot |
183 | * @hotplug_slot: slot to free | 89 | * @hotplug_slot: slot to free |
@@ -236,17 +142,6 @@ static int init_slots(struct controller *ctrl) | |||
236 | get_attention_status(hotplug_slot, &info->attention_status); | 142 | get_attention_status(hotplug_slot, &info->attention_status); |
237 | get_latch_status(hotplug_slot, &info->latch_status); | 143 | get_latch_status(hotplug_slot, &info->latch_status); |
238 | get_adapter_status(hotplug_slot, &info->adapter_status); | 144 | get_adapter_status(hotplug_slot, &info->adapter_status); |
239 | /* create additional sysfs entries */ | ||
240 | if (EMI(ctrl)) { | ||
241 | retval = sysfs_create_file(&hotplug_slot->pci_slot->kobj, | ||
242 | &hotplug_slot_attr_lock.attr); | ||
243 | if (retval) { | ||
244 | pci_hp_deregister(hotplug_slot); | ||
245 | ctrl_err(ctrl, "Cannot create additional sysfs " | ||
246 | "entries\n"); | ||
247 | goto error_info; | ||
248 | } | ||
249 | } | ||
250 | } | 145 | } |
251 | 146 | ||
252 | return 0; | 147 | return 0; |
@@ -261,13 +156,8 @@ error: | |||
261 | static void cleanup_slots(struct controller *ctrl) | 156 | static void cleanup_slots(struct controller *ctrl) |
262 | { | 157 | { |
263 | struct slot *slot; | 158 | struct slot *slot; |
264 | 159 | list_for_each_entry(slot, &ctrl->slot_list, slot_list) | |
265 | list_for_each_entry(slot, &ctrl->slot_list, slot_list) { | ||
266 | if (EMI(ctrl)) | ||
267 | sysfs_remove_file(&slot->hotplug_slot->pci_slot->kobj, | ||
268 | &hotplug_slot_attr_lock.attr); | ||
269 | pci_hp_deregister(slot->hotplug_slot); | 160 | pci_hp_deregister(slot->hotplug_slot); |
270 | } | ||
271 | } | 161 | } |
272 | 162 | ||
273 | /* | 163 | /* |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 07bd32151146..52813257e5bf 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -422,35 +422,6 @@ static int hpc_query_power_fault(struct slot *slot) | |||
422 | return !!(slot_status & PCI_EXP_SLTSTA_PFD); | 422 | return !!(slot_status & PCI_EXP_SLTSTA_PFD); |
423 | } | 423 | } |
424 | 424 | ||
425 | static int hpc_get_emi_status(struct slot *slot, u8 *status) | ||
426 | { | ||
427 | struct controller *ctrl = slot->ctrl; | ||
428 | u16 slot_status; | ||
429 | int retval; | ||
430 | |||
431 | retval = pciehp_readw(ctrl, PCI_EXP_SLTSTA, &slot_status); | ||
432 | if (retval) { | ||
433 | ctrl_err(ctrl, "Cannot check EMI status\n"); | ||
434 | return retval; | ||
435 | } | ||
436 | *status = !!(slot_status & PCI_EXP_SLTSTA_EIS); | ||
437 | return retval; | ||
438 | } | ||
439 | |||
440 | static int hpc_toggle_emi(struct slot *slot) | ||
441 | { | ||
442 | u16 slot_cmd; | ||
443 | u16 cmd_mask; | ||
444 | int rc; | ||
445 | |||
446 | slot_cmd = PCI_EXP_SLTCTL_EIC; | ||
447 | cmd_mask = PCI_EXP_SLTCTL_EIC; | ||
448 | rc = pcie_write_cmd(slot->ctrl, slot_cmd, cmd_mask); | ||
449 | slot->last_emi_toggle = get_seconds(); | ||
450 | |||
451 | return rc; | ||
452 | } | ||
453 | |||
454 | static int hpc_set_attention_status(struct slot *slot, u8 value) | 425 | static int hpc_set_attention_status(struct slot *slot, u8 value) |
455 | { | 426 | { |
456 | struct controller *ctrl = slot->ctrl; | 427 | struct controller *ctrl = slot->ctrl; |
@@ -874,8 +845,6 @@ static struct hpc_ops pciehp_hpc_ops = { | |||
874 | .get_attention_status = hpc_get_attention_status, | 845 | .get_attention_status = hpc_get_attention_status, |
875 | .get_latch_status = hpc_get_latch_status, | 846 | .get_latch_status = hpc_get_latch_status, |
876 | .get_adapter_status = hpc_get_adapter_status, | 847 | .get_adapter_status = hpc_get_adapter_status, |
877 | .get_emi_status = hpc_get_emi_status, | ||
878 | .toggle_emi = hpc_toggle_emi, | ||
879 | 848 | ||
880 | .get_max_bus_speed = hpc_get_max_lnk_speed, | 849 | .get_max_bus_speed = hpc_get_max_lnk_speed, |
881 | .get_cur_bus_speed = hpc_get_cur_lnk_speed, | 850 | .get_cur_bus_speed = hpc_get_cur_lnk_speed, |
diff --git a/drivers/pci/hotplug/pcihp_skeleton.c b/drivers/pci/hotplug/pcihp_skeleton.c index e3dd6cf9e89f..5175d9b26f0b 100644 --- a/drivers/pci/hotplug/pcihp_skeleton.c +++ b/drivers/pci/hotplug/pcihp_skeleton.c | |||
@@ -82,7 +82,6 @@ static int get_latch_status (struct hotplug_slot *slot, u8 *value); | |||
82 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); | 82 | static int get_adapter_status (struct hotplug_slot *slot, u8 *value); |
83 | 83 | ||
84 | static struct hotplug_slot_ops skel_hotplug_slot_ops = { | 84 | static struct hotplug_slot_ops skel_hotplug_slot_ops = { |
85 | .owner = THIS_MODULE, | ||
86 | .enable_slot = enable_slot, | 85 | .enable_slot = enable_slot, |
87 | .disable_slot = disable_slot, | 86 | .disable_slot = disable_slot, |
88 | .set_attention_status = set_attention_status, | 87 | .set_attention_status = set_attention_status, |
diff --git a/drivers/pci/hotplug/rpaphp_core.c b/drivers/pci/hotplug/rpaphp_core.c index 95d02a08fdc7..c159223389ec 100644 --- a/drivers/pci/hotplug/rpaphp_core.c +++ b/drivers/pci/hotplug/rpaphp_core.c | |||
@@ -423,7 +423,6 @@ static int disable_slot(struct hotplug_slot *hotplug_slot) | |||
423 | } | 423 | } |
424 | 424 | ||
425 | struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { | 425 | struct hotplug_slot_ops rpaphp_hotplug_slot_ops = { |
426 | .owner = THIS_MODULE, | ||
427 | .enable_slot = enable_slot, | 426 | .enable_slot = enable_slot, |
428 | .disable_slot = disable_slot, | 427 | .disable_slot = disable_slot, |
429 | .set_attention_status = set_attention_status, | 428 | .set_attention_status = set_attention_status, |
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c index 3eee70928d45..a4494d78e7c2 100644 --- a/drivers/pci/hotplug/sgi_hotplug.c +++ b/drivers/pci/hotplug/sgi_hotplug.c | |||
@@ -83,7 +83,6 @@ static int disable_slot(struct hotplug_slot *slot); | |||
83 | static inline int get_power_status(struct hotplug_slot *slot, u8 *value); | 83 | static inline int get_power_status(struct hotplug_slot *slot, u8 *value); |
84 | 84 | ||
85 | static struct hotplug_slot_ops sn_hotplug_slot_ops = { | 85 | static struct hotplug_slot_ops sn_hotplug_slot_ops = { |
86 | .owner = THIS_MODULE, | ||
87 | .enable_slot = enable_slot, | 86 | .enable_slot = enable_slot, |
88 | .disable_slot = disable_slot, | 87 | .disable_slot = disable_slot, |
89 | .get_power_status = get_power_status, | 88 | .get_power_status = get_power_status, |
@@ -679,7 +678,7 @@ alloc_err: | |||
679 | return rc; | 678 | return rc; |
680 | } | 679 | } |
681 | 680 | ||
682 | static int sn_pci_hotplug_init(void) | 681 | static int __init sn_pci_hotplug_init(void) |
683 | { | 682 | { |
684 | struct pci_bus *pci_bus = NULL; | 683 | struct pci_bus *pci_bus = NULL; |
685 | int rc; | 684 | int rc; |
@@ -716,7 +715,7 @@ static int sn_pci_hotplug_init(void) | |||
716 | return registered == 1 ? 0 : -ENODEV; | 715 | return registered == 1 ? 0 : -ENODEV; |
717 | } | 716 | } |
718 | 717 | ||
719 | static void sn_pci_hotplug_exit(void) | 718 | static void __exit sn_pci_hotplug_exit(void) |
720 | { | 719 | { |
721 | struct hotplug_slot *bss_hotplug_slot; | 720 | struct hotplug_slot *bss_hotplug_slot; |
722 | 721 | ||
diff --git a/drivers/pci/hotplug/shpchp_core.c b/drivers/pci/hotplug/shpchp_core.c index fe8d149c2293..8a520a3d0f59 100644 --- a/drivers/pci/hotplug/shpchp_core.c +++ b/drivers/pci/hotplug/shpchp_core.c | |||
@@ -69,7 +69,6 @@ static int get_max_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *val | |||
69 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); | 69 | static int get_cur_bus_speed (struct hotplug_slot *slot, enum pci_bus_speed *value); |
70 | 70 | ||
71 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { | 71 | static struct hotplug_slot_ops shpchp_hotplug_slot_ops = { |
72 | .owner = THIS_MODULE, | ||
73 | .set_attention_status = set_attention_status, | 72 | .set_attention_status = set_attention_status, |
74 | .enable_slot = enable_slot, | 73 | .enable_slot = enable_slot, |
75 | .disable_slot = disable_slot, | 74 | .disable_slot = disable_slot, |