diff options
Diffstat (limited to 'drivers/pci')
-rw-r--r-- | drivers/pci/Makefile | 4 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_core.c | 6 | ||||
-rw-r--r-- | drivers/pci/hotplug/acpiphp_glue.c | 53 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_core.c | 66 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpci_hotplug_pci.c | 2 | ||||
-rw-r--r-- | drivers/pci/hotplug/cpqphp_core.c | 12 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp.h | 1 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_ctrl.c | 12 | ||||
-rw-r--r-- | drivers/pci/hotplug/pciehp_hpc.c | 191 | ||||
-rw-r--r-- | drivers/pci/pci-acpi.c | 8 | ||||
-rw-r--r-- | drivers/pci/pci-sysfs.c | 11 | ||||
-rw-r--r-- | drivers/pci/pci.c | 200 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/Kconfig | 2 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/Makefile | 3 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv.c | 2 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv.h | 14 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_acpi.c | 36 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aerdrv_core.c | 34 | ||||
-rw-r--r-- | drivers/pci/probe.c | 3 | ||||
-rw-r--r-- | drivers/pci/proc.c | 1 | ||||
-rw-r--r-- | drivers/pci/quirks.c | 30 | ||||
-rw-r--r-- | drivers/pci/search.c | 7 | ||||
-rw-r--r-- | drivers/pci/setup-bus.c | 8 | ||||
-rw-r--r-- | drivers/pci/syscall.c | 20 |
25 files changed, 488 insertions, 239 deletions
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index e3beb784406f..006054a40995 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile | |||
@@ -41,9 +41,7 @@ obj-$(CONFIG_ACPI) += pci-acpi.o | |||
41 | # Cardbus & CompactPCI use setup-bus | 41 | # Cardbus & CompactPCI use setup-bus |
42 | obj-$(CONFIG_HOTPLUG) += setup-bus.o | 42 | obj-$(CONFIG_HOTPLUG) += setup-bus.o |
43 | 43 | ||
44 | ifndef CONFIG_X86 | 44 | obj-$(CONFIG_PCI_SYSCALL) += syscall.o |
45 | obj-y += syscall.o | ||
46 | endif | ||
47 | 45 | ||
48 | ifeq ($(CONFIG_PCI_DEBUG),y) | 46 | ifeq ($(CONFIG_PCI_DEBUG),y) |
49 | EXTRA_CFLAGS += -DDEBUG | 47 | EXTRA_CFLAGS += -DDEBUG |
diff --git a/drivers/pci/hotplug/acpiphp.h b/drivers/pci/hotplug/acpiphp.h index ddbadd95387e..f6cc0c5b5657 100644 --- a/drivers/pci/hotplug/acpiphp.h +++ b/drivers/pci/hotplug/acpiphp.h | |||
@@ -211,6 +211,7 @@ typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data); | |||
211 | 211 | ||
212 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); | 212 | extern int acpiphp_enable_slot (struct acpiphp_slot *slot); |
213 | extern int acpiphp_disable_slot (struct acpiphp_slot *slot); | 213 | extern int acpiphp_disable_slot (struct acpiphp_slot *slot); |
214 | extern int acpiphp_eject_slot (struct acpiphp_slot *slot); | ||
214 | extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); | 215 | extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot); |
215 | extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); | 216 | extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot); |
216 | extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); | 217 | extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot); |
diff --git a/drivers/pci/hotplug/acpiphp_core.c b/drivers/pci/hotplug/acpiphp_core.c index fa5c0197d571..a0ca63adad5a 100644 --- a/drivers/pci/hotplug/acpiphp_core.c +++ b/drivers/pci/hotplug/acpiphp_core.c | |||
@@ -156,11 +156,15 @@ static int enable_slot(struct hotplug_slot *hotplug_slot) | |||
156 | static int disable_slot(struct hotplug_slot *hotplug_slot) | 156 | static int disable_slot(struct hotplug_slot *hotplug_slot) |
157 | { | 157 | { |
158 | struct slot *slot = hotplug_slot->private; | 158 | struct slot *slot = hotplug_slot->private; |
159 | int retval; | ||
159 | 160 | ||
160 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); | 161 | dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name); |
161 | 162 | ||
162 | /* disable the specified slot */ | 163 | /* disable the specified slot */ |
163 | return acpiphp_disable_slot(slot->acpi_slot); | 164 | retval = acpiphp_disable_slot(slot->acpi_slot); |
165 | if (!retval) | ||
166 | retval = acpiphp_eject_slot(slot->acpi_slot); | ||
167 | return retval; | ||
164 | } | 168 | } |
165 | 169 | ||
166 | 170 | ||
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c index 9ef4e989afc4..1e125b56c9a9 100644 --- a/drivers/pci/hotplug/acpiphp_glue.c +++ b/drivers/pci/hotplug/acpiphp_glue.c | |||
@@ -1282,7 +1282,7 @@ static unsigned int get_slot_status(struct acpiphp_slot *slot) | |||
1282 | /** | 1282 | /** |
1283 | * acpiphp_eject_slot - physically eject the slot | 1283 | * acpiphp_eject_slot - physically eject the slot |
1284 | */ | 1284 | */ |
1285 | static int acpiphp_eject_slot(struct acpiphp_slot *slot) | 1285 | int acpiphp_eject_slot(struct acpiphp_slot *slot) |
1286 | { | 1286 | { |
1287 | acpi_status status; | 1287 | acpi_status status; |
1288 | struct acpiphp_func *func; | 1288 | struct acpiphp_func *func; |
@@ -1368,6 +1368,9 @@ static void program_hpp(struct pci_dev *dev, struct acpiphp_bridge *bridge) | |||
1368 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) | 1368 | (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI))) |
1369 | return; | 1369 | return; |
1370 | 1370 | ||
1371 | if ((dev->class >> 8) == PCI_CLASS_BRIDGE_HOST) | ||
1372 | return; | ||
1373 | |||
1371 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, | 1374 | pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, |
1372 | bridge->hpp.t0->cache_line_size); | 1375 | bridge->hpp.t0->cache_line_size); |
1373 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, | 1376 | pci_write_config_byte(dev, PCI_LATENCY_TIMER, |
@@ -1502,6 +1505,37 @@ static void handle_bridge_insertion(acpi_handle handle, u32 type) | |||
1502 | * ACPI event handlers | 1505 | * ACPI event handlers |
1503 | */ | 1506 | */ |
1504 | 1507 | ||
1508 | static acpi_status | ||
1509 | count_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
1510 | { | ||
1511 | int *count = (int *)context; | ||
1512 | struct acpiphp_bridge *bridge; | ||
1513 | |||
1514 | bridge = acpiphp_handle_to_bridge(handle); | ||
1515 | if (bridge) | ||
1516 | (*count)++; | ||
1517 | return AE_OK ; | ||
1518 | } | ||
1519 | |||
1520 | static acpi_status | ||
1521 | check_sub_bridges(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
1522 | { | ||
1523 | struct acpiphp_bridge *bridge; | ||
1524 | char objname[64]; | ||
1525 | struct acpi_buffer buffer = { .length = sizeof(objname), | ||
1526 | .pointer = objname }; | ||
1527 | |||
1528 | bridge = acpiphp_handle_to_bridge(handle); | ||
1529 | if (bridge) { | ||
1530 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
1531 | dbg("%s: re-enumerating slots under %s\n", | ||
1532 | __FUNCTION__, objname); | ||
1533 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer); | ||
1534 | acpiphp_check_bridge(bridge); | ||
1535 | } | ||
1536 | return AE_OK ; | ||
1537 | } | ||
1538 | |||
1505 | /** | 1539 | /** |
1506 | * handle_hotplug_event_bridge - handle ACPI event on bridges | 1540 | * handle_hotplug_event_bridge - handle ACPI event on bridges |
1507 | * | 1541 | * |
@@ -1519,6 +1553,7 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
1519 | struct acpi_buffer buffer = { .length = sizeof(objname), | 1553 | struct acpi_buffer buffer = { .length = sizeof(objname), |
1520 | .pointer = objname }; | 1554 | .pointer = objname }; |
1521 | struct acpi_device *device; | 1555 | struct acpi_device *device; |
1556 | int num_sub_bridges = 0; | ||
1522 | 1557 | ||
1523 | if (acpi_bus_get_device(handle, &device)) { | 1558 | if (acpi_bus_get_device(handle, &device)) { |
1524 | /* This bridge must have just been physically inserted */ | 1559 | /* This bridge must have just been physically inserted */ |
@@ -1527,7 +1562,12 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
1527 | } | 1562 | } |
1528 | 1563 | ||
1529 | bridge = acpiphp_handle_to_bridge(handle); | 1564 | bridge = acpiphp_handle_to_bridge(handle); |
1530 | if (!bridge) { | 1565 | if (type == ACPI_NOTIFY_BUS_CHECK) { |
1566 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, ACPI_UINT32_MAX, | ||
1567 | count_sub_bridges, &num_sub_bridges, NULL); | ||
1568 | } | ||
1569 | |||
1570 | if (!bridge && !num_sub_bridges) { | ||
1531 | err("cannot get bridge info\n"); | 1571 | err("cannot get bridge info\n"); |
1532 | return; | 1572 | return; |
1533 | } | 1573 | } |
@@ -1538,7 +1578,14 @@ static void handle_hotplug_event_bridge(acpi_handle handle, u32 type, void *cont | |||
1538 | case ACPI_NOTIFY_BUS_CHECK: | 1578 | case ACPI_NOTIFY_BUS_CHECK: |
1539 | /* bus re-enumerate */ | 1579 | /* bus re-enumerate */ |
1540 | dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname); | 1580 | dbg("%s: Bus check notify on %s\n", __FUNCTION__, objname); |
1541 | acpiphp_check_bridge(bridge); | 1581 | if (bridge) { |
1582 | dbg("%s: re-enumerating slots under %s\n", | ||
1583 | __FUNCTION__, objname); | ||
1584 | acpiphp_check_bridge(bridge); | ||
1585 | } | ||
1586 | if (num_sub_bridges) | ||
1587 | acpi_walk_namespace(ACPI_TYPE_DEVICE, handle, | ||
1588 | ACPI_UINT32_MAX, check_sub_bridges, NULL, NULL); | ||
1542 | break; | 1589 | break; |
1543 | 1590 | ||
1544 | case ACPI_NOTIFY_DEVICE_CHECK: | 1591 | case ACPI_NOTIFY_DEVICE_CHECK: |
diff --git a/drivers/pci/hotplug/cpci_hotplug_core.c b/drivers/pci/hotplug/cpci_hotplug_core.c index 684551559d44..ed4d44e3332c 100644 --- a/drivers/pci/hotplug/cpci_hotplug_core.c +++ b/drivers/pci/hotplug/cpci_hotplug_core.c | |||
@@ -35,6 +35,7 @@ | |||
35 | #include <linux/smp_lock.h> | 35 | #include <linux/smp_lock.h> |
36 | #include <asm/atomic.h> | 36 | #include <asm/atomic.h> |
37 | #include <linux/delay.h> | 37 | #include <linux/delay.h> |
38 | #include <linux/kthread.h> | ||
38 | #include "cpci_hotplug.h" | 39 | #include "cpci_hotplug.h" |
39 | 40 | ||
40 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" | 41 | #define DRIVER_AUTHOR "Scott Murray <scottm@somanetworks.com>" |
@@ -59,9 +60,8 @@ static int slots; | |||
59 | static atomic_t extracting; | 60 | static atomic_t extracting; |
60 | int cpci_debug; | 61 | int cpci_debug; |
61 | static struct cpci_hp_controller *controller; | 62 | static struct cpci_hp_controller *controller; |
62 | static struct semaphore event_semaphore; /* mutex for process loop (up if something to process) */ | 63 | static struct task_struct *cpci_thread; |
63 | static struct semaphore thread_exit; /* guard ensure thread has exited before calling it quits */ | 64 | static int thread_finished; |
64 | static int thread_finished = 1; | ||
65 | 65 | ||
66 | static int enable_slot(struct hotplug_slot *slot); | 66 | static int enable_slot(struct hotplug_slot *slot); |
67 | static int disable_slot(struct hotplug_slot *slot); | 67 | static int disable_slot(struct hotplug_slot *slot); |
@@ -357,9 +357,7 @@ cpci_hp_intr(int irq, void *data) | |||
357 | controller->ops->disable_irq(); | 357 | controller->ops->disable_irq(); |
358 | 358 | ||
359 | /* Trigger processing by the event thread */ | 359 | /* Trigger processing by the event thread */ |
360 | dbg("Signal event_semaphore"); | 360 | wake_up_process(cpci_thread); |
361 | up(&event_semaphore); | ||
362 | dbg("exited cpci_hp_intr"); | ||
363 | return IRQ_HANDLED; | 361 | return IRQ_HANDLED; |
364 | } | 362 | } |
365 | 363 | ||
@@ -521,17 +519,12 @@ event_thread(void *data) | |||
521 | { | 519 | { |
522 | int rc; | 520 | int rc; |
523 | 521 | ||
524 | lock_kernel(); | ||
525 | daemonize("cpci_hp_eventd"); | ||
526 | unlock_kernel(); | ||
527 | |||
528 | dbg("%s - event thread started", __FUNCTION__); | 522 | dbg("%s - event thread started", __FUNCTION__); |
529 | while (1) { | 523 | while (1) { |
530 | dbg("event thread sleeping"); | 524 | dbg("event thread sleeping"); |
531 | down_interruptible(&event_semaphore); | 525 | set_current_state(TASK_INTERRUPTIBLE); |
532 | dbg("event thread woken, thread_finished = %d", | 526 | schedule(); |
533 | thread_finished); | 527 | if (kthread_should_stop()) |
534 | if (thread_finished || signal_pending(current)) | ||
535 | break; | 528 | break; |
536 | do { | 529 | do { |
537 | rc = check_slots(); | 530 | rc = check_slots(); |
@@ -541,18 +534,17 @@ event_thread(void *data) | |||
541 | } else if (rc < 0) { | 534 | } else if (rc < 0) { |
542 | dbg("%s - error checking slots", __FUNCTION__); | 535 | dbg("%s - error checking slots", __FUNCTION__); |
543 | thread_finished = 1; | 536 | thread_finished = 1; |
544 | break; | 537 | goto out; |
545 | } | 538 | } |
546 | } while (atomic_read(&extracting) && !thread_finished); | 539 | } while (atomic_read(&extracting) && !kthread_should_stop()); |
547 | if (thread_finished) | 540 | if (kthread_should_stop()) |
548 | break; | 541 | break; |
549 | 542 | ||
550 | /* Re-enable ENUM# interrupt */ | 543 | /* Re-enable ENUM# interrupt */ |
551 | dbg("%s - re-enabling irq", __FUNCTION__); | 544 | dbg("%s - re-enabling irq", __FUNCTION__); |
552 | controller->ops->enable_irq(); | 545 | controller->ops->enable_irq(); |
553 | } | 546 | } |
554 | dbg("%s - event thread signals exit", __FUNCTION__); | 547 | out: |
555 | up(&thread_exit); | ||
556 | return 0; | 548 | return 0; |
557 | } | 549 | } |
558 | 550 | ||
@@ -562,12 +554,8 @@ poll_thread(void *data) | |||
562 | { | 554 | { |
563 | int rc; | 555 | int rc; |
564 | 556 | ||
565 | lock_kernel(); | ||
566 | daemonize("cpci_hp_polld"); | ||
567 | unlock_kernel(); | ||
568 | |||
569 | while (1) { | 557 | while (1) { |
570 | if (thread_finished || signal_pending(current)) | 558 | if (kthread_should_stop() || signal_pending(current)) |
571 | break; | 559 | break; |
572 | if (controller->ops->query_enum()) { | 560 | if (controller->ops->query_enum()) { |
573 | do { | 561 | do { |
@@ -578,48 +566,36 @@ poll_thread(void *data) | |||
578 | } else if (rc < 0) { | 566 | } else if (rc < 0) { |
579 | dbg("%s - error checking slots", __FUNCTION__); | 567 | dbg("%s - error checking slots", __FUNCTION__); |
580 | thread_finished = 1; | 568 | thread_finished = 1; |
581 | break; | 569 | goto out; |
582 | } | 570 | } |
583 | } while (atomic_read(&extracting) && !thread_finished); | 571 | } while (atomic_read(&extracting) && !kthread_should_stop()); |
584 | } | 572 | } |
585 | msleep(100); | 573 | msleep(100); |
586 | } | 574 | } |
587 | dbg("poll thread signals exit"); | 575 | out: |
588 | up(&thread_exit); | ||
589 | return 0; | 576 | return 0; |
590 | } | 577 | } |
591 | 578 | ||
592 | static int | 579 | static int |
593 | cpci_start_thread(void) | 580 | cpci_start_thread(void) |
594 | { | 581 | { |
595 | int pid; | ||
596 | |||
597 | /* initialize our semaphores */ | ||
598 | init_MUTEX_LOCKED(&event_semaphore); | ||
599 | init_MUTEX_LOCKED(&thread_exit); | ||
600 | thread_finished = 0; | ||
601 | |||
602 | if (controller->irq) | 582 | if (controller->irq) |
603 | pid = kernel_thread(event_thread, NULL, 0); | 583 | cpci_thread = kthread_run(event_thread, NULL, "cpci_hp_eventd"); |
604 | else | 584 | else |
605 | pid = kernel_thread(poll_thread, NULL, 0); | 585 | cpci_thread = kthread_run(poll_thread, NULL, "cpci_hp_polld"); |
606 | if (pid < 0) { | 586 | if (IS_ERR(cpci_thread)) { |
607 | err("Can't start up our thread"); | 587 | err("Can't start up our thread"); |
608 | return -1; | 588 | return PTR_ERR(cpci_thread); |
609 | } | 589 | } |
610 | dbg("Our thread pid = %d", pid); | 590 | thread_finished = 0; |
611 | return 0; | 591 | return 0; |
612 | } | 592 | } |
613 | 593 | ||
614 | static void | 594 | static void |
615 | cpci_stop_thread(void) | 595 | cpci_stop_thread(void) |
616 | { | 596 | { |
597 | kthread_stop(cpci_thread); | ||
617 | thread_finished = 1; | 598 | thread_finished = 1; |
618 | dbg("thread finish command given"); | ||
619 | if (controller->irq) | ||
620 | up(&event_semaphore); | ||
621 | dbg("wait for thread to exit"); | ||
622 | down(&thread_exit); | ||
623 | } | 599 | } |
624 | 600 | ||
625 | int | 601 | int |
diff --git a/drivers/pci/hotplug/cpci_hotplug_pci.c b/drivers/pci/hotplug/cpci_hotplug_pci.c index 7b1beaad2752..5e9be44817cb 100644 --- a/drivers/pci/hotplug/cpci_hotplug_pci.c +++ b/drivers/pci/hotplug/cpci_hotplug_pci.c | |||
@@ -45,8 +45,6 @@ extern int cpci_debug; | |||
45 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) | 45 | #define info(format, arg...) printk(KERN_INFO "%s: " format "\n", MY_NAME , ## arg) |
46 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) | 46 | #define warn(format, arg...) printk(KERN_WARNING "%s: " format "\n", MY_NAME , ## arg) |
47 | 47 | ||
48 | #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) | ||
49 | |||
50 | 48 | ||
51 | u8 cpci_get_attention_status(struct slot* slot) | 49 | u8 cpci_get_attention_status(struct slot* slot) |
52 | { | 50 | { |
diff --git a/drivers/pci/hotplug/cpqphp_core.c b/drivers/pci/hotplug/cpqphp_core.c index 5617cfdadc5c..d590a99930fa 100644 --- a/drivers/pci/hotplug/cpqphp_core.c +++ b/drivers/pci/hotplug/cpqphp_core.c | |||
@@ -796,7 +796,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
796 | u8 num_of_slots = 0; | 796 | u8 num_of_slots = 0; |
797 | u8 hp_slot = 0; | 797 | u8 hp_slot = 0; |
798 | u8 device; | 798 | u8 device; |
799 | u8 rev; | ||
800 | u8 bus_cap; | 799 | u8 bus_cap; |
801 | u16 temp_word; | 800 | u16 temp_word; |
802 | u16 vendor_id; | 801 | u16 vendor_id; |
@@ -823,9 +822,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
823 | } | 822 | } |
824 | dbg("Vendor ID: %x\n", vendor_id); | 823 | dbg("Vendor ID: %x\n", vendor_id); |
825 | 824 | ||
826 | rc = pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); | 825 | dbg("revision: %d\n", pdev->revision); |
827 | dbg("revision: %d\n", rev); | 826 | if ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!pdev->revision)) { |
828 | if (rc || ((vendor_id == PCI_VENDOR_ID_COMPAQ) && (!rev))) { | ||
829 | err(msg_HPC_rev_error); | 827 | err(msg_HPC_rev_error); |
830 | rc = -ENODEV; | 828 | rc = -ENODEV; |
831 | goto err_disable_device; | 829 | goto err_disable_device; |
@@ -836,7 +834,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
836 | * For Intel, each SSID bit identifies a PHP capability. | 834 | * For Intel, each SSID bit identifies a PHP capability. |
837 | * Also Intel HPC's may have RID=0. | 835 | * Also Intel HPC's may have RID=0. |
838 | */ | 836 | */ |
839 | if ((rev > 2) || (vendor_id == PCI_VENDOR_ID_INTEL)) { | 837 | 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 | 838 | // TODO: This code can be made to support non-Compaq or Intel subsystem IDs |
841 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); | 839 | rc = pci_read_config_word(pdev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vid); |
842 | if (rc) { | 840 | if (rc) { |
@@ -870,7 +868,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
870 | 868 | ||
871 | switch (subsystem_vid) { | 869 | switch (subsystem_vid) { |
872 | case PCI_VENDOR_ID_COMPAQ: | 870 | case PCI_VENDOR_ID_COMPAQ: |
873 | if (rev >= 0x13) { /* CIOBX */ | 871 | if (pdev->revision >= 0x13) { /* CIOBX */ |
874 | ctrl->push_flag = 1; | 872 | ctrl->push_flag = 1; |
875 | ctrl->slot_switch_type = 1; | 873 | ctrl->slot_switch_type = 1; |
876 | ctrl->push_button = 1; | 874 | ctrl->push_button = 1; |
@@ -1075,7 +1073,7 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1075 | memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus)); | 1073 | memcpy(ctrl->pci_bus, pdev->bus, sizeof(*ctrl->pci_bus)); |
1076 | 1074 | ||
1077 | ctrl->bus = pdev->bus->number; | 1075 | ctrl->bus = pdev->bus->number; |
1078 | ctrl->rev = rev; | 1076 | ctrl->rev = pdev->revision; |
1079 | dbg("bus device function rev: %d %d %d %d\n", ctrl->bus, | 1077 | dbg("bus device function rev: %d %d %d %d\n", ctrl->bus, |
1080 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev); | 1078 | PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), ctrl->rev); |
1081 | 1079 | ||
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h index ccc57627201e..7959c222dc24 100644 --- a/drivers/pci/hotplug/pciehp.h +++ b/drivers/pci/hotplug/pciehp.h | |||
@@ -103,6 +103,7 @@ struct controller { | |||
103 | u8 cap_base; | 103 | u8 cap_base; |
104 | struct timer_list poll_timer; | 104 | struct timer_list poll_timer; |
105 | volatile int cmd_busy; | 105 | volatile int cmd_busy; |
106 | spinlock_t lock; | ||
106 | }; | 107 | }; |
107 | 108 | ||
108 | #define INT_BUTTON_IGNORE 0 | 109 | #define INT_BUTTON_IGNORE 0 |
diff --git a/drivers/pci/hotplug/pciehp_ctrl.c b/drivers/pci/hotplug/pciehp_ctrl.c index 7f22caa70178..98e541ffef3d 100644 --- a/drivers/pci/hotplug/pciehp_ctrl.c +++ b/drivers/pci/hotplug/pciehp_ctrl.c | |||
@@ -197,6 +197,12 @@ static void set_slot_off(struct controller *ctrl, struct slot * pslot) | |||
197 | __FUNCTION__); | 197 | __FUNCTION__); |
198 | return; | 198 | return; |
199 | } | 199 | } |
200 | /* | ||
201 | * After turning power off, we must wait for at least | ||
202 | * 1 second before taking any action that relies on | ||
203 | * power having been removed from the slot/adapter. | ||
204 | */ | ||
205 | msleep(1000); | ||
200 | } | 206 | } |
201 | } | 207 | } |
202 | 208 | ||
@@ -615,6 +621,12 @@ int pciehp_disable_slot(struct slot *p_slot) | |||
615 | mutex_unlock(&p_slot->ctrl->crit_sect); | 621 | mutex_unlock(&p_slot->ctrl->crit_sect); |
616 | return -EINVAL; | 622 | return -EINVAL; |
617 | } | 623 | } |
624 | /* | ||
625 | * After turning power off, we must wait for at least | ||
626 | * 1 second before taking any action that relies on | ||
627 | * power having been removed from the slot/adapter. | ||
628 | */ | ||
629 | msleep(1000); | ||
618 | } | 630 | } |
619 | 631 | ||
620 | ret = remove_board(p_slot); | 632 | ret = remove_board(p_slot); |
diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c index 9aac6a87eb53..016eea94a8a5 100644 --- a/drivers/pci/hotplug/pciehp_hpc.c +++ b/drivers/pci/hotplug/pciehp_hpc.c | |||
@@ -275,11 +275,19 @@ static inline int pcie_wait_cmd(struct controller *ctrl) | |||
275 | return retval; | 275 | return retval; |
276 | } | 276 | } |
277 | 277 | ||
278 | static int pcie_write_cmd(struct slot *slot, u16 cmd) | 278 | /** |
279 | * pcie_write_cmd - Issue controller command | ||
280 | * @slot: slot to which the command is issued | ||
281 | * @cmd: command value written to slot control register | ||
282 | * @mask: bitmask of slot control register to be modified | ||
283 | */ | ||
284 | static int pcie_write_cmd(struct slot *slot, u16 cmd, u16 mask) | ||
279 | { | 285 | { |
280 | struct controller *ctrl = slot->ctrl; | 286 | struct controller *ctrl = slot->ctrl; |
281 | int retval = 0; | 287 | int retval = 0; |
282 | u16 slot_status; | 288 | u16 slot_status; |
289 | u16 slot_ctrl; | ||
290 | unsigned long flags; | ||
283 | 291 | ||
284 | DBG_ENTER_ROUTINE | 292 | DBG_ENTER_ROUTINE |
285 | 293 | ||
@@ -299,17 +307,29 @@ static int pcie_write_cmd(struct slot *slot, u16 cmd) | |||
299 | __FUNCTION__); | 307 | __FUNCTION__); |
300 | } | 308 | } |
301 | 309 | ||
302 | ctrl->cmd_busy = 1; | 310 | spin_lock_irqsave(&ctrl->lock, flags); |
303 | retval = pciehp_writew(ctrl, SLOTCTRL, (cmd | CMD_CMPL_INTR_ENABLE)); | 311 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); |
304 | if (retval) { | 312 | if (retval) { |
305 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | 313 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); |
306 | goto out; | 314 | goto out_spin_unlock; |
307 | } | 315 | } |
308 | 316 | ||
317 | slot_ctrl &= ~mask; | ||
318 | slot_ctrl |= ((cmd & mask) | CMD_CMPL_INTR_ENABLE); | ||
319 | |||
320 | ctrl->cmd_busy = 1; | ||
321 | retval = pciehp_writew(ctrl, SLOTCTRL, slot_ctrl); | ||
322 | if (retval) | ||
323 | err("%s: Cannot write to SLOTCTRL register\n", __FUNCTION__); | ||
324 | |||
325 | out_spin_unlock: | ||
326 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
327 | |||
309 | /* | 328 | /* |
310 | * Wait for command completion. | 329 | * Wait for command completion. |
311 | */ | 330 | */ |
312 | retval = pcie_wait_cmd(ctrl); | 331 | if (!retval) |
332 | retval = pcie_wait_cmd(ctrl); | ||
313 | out: | 333 | out: |
314 | mutex_unlock(&ctrl->ctrl_lock); | 334 | mutex_unlock(&ctrl->ctrl_lock); |
315 | DBG_LEAVE_ROUTINE | 335 | DBG_LEAVE_ROUTINE |
@@ -502,25 +522,20 @@ static int hpc_get_emi_status(struct slot *slot, u8 *status) | |||
502 | 522 | ||
503 | static int hpc_toggle_emi(struct slot *slot) | 523 | static int hpc_toggle_emi(struct slot *slot) |
504 | { | 524 | { |
505 | struct controller *ctrl = slot->ctrl; | 525 | u16 slot_cmd; |
506 | u16 slot_cmd = 0; | 526 | u16 cmd_mask; |
507 | u16 slot_ctrl; | 527 | int rc; |
508 | int rc = 0; | ||
509 | 528 | ||
510 | DBG_ENTER_ROUTINE | 529 | DBG_ENTER_ROUTINE |
511 | 530 | ||
512 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 531 | slot_cmd = EMI_CTRL; |
513 | if (rc) { | 532 | cmd_mask = EMI_CTRL; |
514 | err("%s : hp_register_read_word SLOT_CTRL failed\n", | 533 | if (!pciehp_poll_mode) { |
515 | __FUNCTION__); | ||
516 | return rc; | ||
517 | } | ||
518 | |||
519 | slot_cmd = (slot_ctrl | EMI_CTRL); | ||
520 | if (!pciehp_poll_mode) | ||
521 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 534 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
535 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
536 | } | ||
522 | 537 | ||
523 | pcie_write_cmd(slot, slot_cmd); | 538 | rc = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
524 | slot->last_emi_toggle = get_seconds(); | 539 | slot->last_emi_toggle = get_seconds(); |
525 | DBG_LEAVE_ROUTINE | 540 | DBG_LEAVE_ROUTINE |
526 | return rc; | 541 | return rc; |
@@ -529,35 +544,32 @@ static int hpc_toggle_emi(struct slot *slot) | |||
529 | static int hpc_set_attention_status(struct slot *slot, u8 value) | 544 | static int hpc_set_attention_status(struct slot *slot, u8 value) |
530 | { | 545 | { |
531 | struct controller *ctrl = slot->ctrl; | 546 | struct controller *ctrl = slot->ctrl; |
532 | u16 slot_cmd = 0; | 547 | u16 slot_cmd; |
533 | u16 slot_ctrl; | 548 | u16 cmd_mask; |
534 | int rc = 0; | 549 | int rc; |
535 | 550 | ||
536 | DBG_ENTER_ROUTINE | 551 | DBG_ENTER_ROUTINE |
537 | 552 | ||
538 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 553 | cmd_mask = ATTN_LED_CTRL; |
539 | if (rc) { | ||
540 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
541 | return rc; | ||
542 | } | ||
543 | |||
544 | switch (value) { | 554 | switch (value) { |
545 | case 0 : /* turn off */ | 555 | case 0 : /* turn off */ |
546 | slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x00C0; | 556 | slot_cmd = 0x00C0; |
547 | break; | 557 | break; |
548 | case 1: /* turn on */ | 558 | case 1: /* turn on */ |
549 | slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0040; | 559 | slot_cmd = 0x0040; |
550 | break; | 560 | break; |
551 | case 2: /* turn blink */ | 561 | case 2: /* turn blink */ |
552 | slot_cmd = (slot_ctrl & ~ATTN_LED_CTRL) | 0x0080; | 562 | slot_cmd = 0x0080; |
553 | break; | 563 | break; |
554 | default: | 564 | default: |
555 | return -1; | 565 | return -1; |
556 | } | 566 | } |
557 | if (!pciehp_poll_mode) | 567 | if (!pciehp_poll_mode) { |
558 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | 568 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
569 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
570 | } | ||
559 | 571 | ||
560 | pcie_write_cmd(slot, slot_cmd); | 572 | rc = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
561 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 573 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
562 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 574 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
563 | 575 | ||
@@ -570,21 +582,18 @@ static void hpc_set_green_led_on(struct slot *slot) | |||
570 | { | 582 | { |
571 | struct controller *ctrl = slot->ctrl; | 583 | struct controller *ctrl = slot->ctrl; |
572 | u16 slot_cmd; | 584 | u16 slot_cmd; |
573 | u16 slot_ctrl; | 585 | u16 cmd_mask; |
574 | int rc = 0; | ||
575 | 586 | ||
576 | DBG_ENTER_ROUTINE | 587 | DBG_ENTER_ROUTINE |
577 | 588 | ||
578 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 589 | slot_cmd = 0x0100; |
579 | if (rc) { | 590 | cmd_mask = PWR_LED_CTRL; |
580 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 591 | if (!pciehp_poll_mode) { |
581 | return; | 592 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
593 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
582 | } | 594 | } |
583 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0100; | ||
584 | if (!pciehp_poll_mode) | ||
585 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | ||
586 | 595 | ||
587 | pcie_write_cmd(slot, slot_cmd); | 596 | pcie_write_cmd(slot, slot_cmd, cmd_mask); |
588 | 597 | ||
589 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 598 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
590 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 599 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
@@ -596,22 +605,18 @@ static void hpc_set_green_led_off(struct slot *slot) | |||
596 | { | 605 | { |
597 | struct controller *ctrl = slot->ctrl; | 606 | struct controller *ctrl = slot->ctrl; |
598 | u16 slot_cmd; | 607 | u16 slot_cmd; |
599 | u16 slot_ctrl; | 608 | u16 cmd_mask; |
600 | int rc = 0; | ||
601 | 609 | ||
602 | DBG_ENTER_ROUTINE | 610 | DBG_ENTER_ROUTINE |
603 | 611 | ||
604 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 612 | slot_cmd = 0x0300; |
605 | if (rc) { | 613 | cmd_mask = PWR_LED_CTRL; |
606 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 614 | if (!pciehp_poll_mode) { |
607 | return; | 615 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
616 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
608 | } | 617 | } |
609 | 618 | ||
610 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0300; | 619 | pcie_write_cmd(slot, slot_cmd, cmd_mask); |
611 | |||
612 | if (!pciehp_poll_mode) | ||
613 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | ||
614 | pcie_write_cmd(slot, slot_cmd); | ||
615 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 620 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
616 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 621 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
617 | 622 | ||
@@ -623,22 +628,18 @@ static void hpc_set_green_led_blink(struct slot *slot) | |||
623 | { | 628 | { |
624 | struct controller *ctrl = slot->ctrl; | 629 | struct controller *ctrl = slot->ctrl; |
625 | u16 slot_cmd; | 630 | u16 slot_cmd; |
626 | u16 slot_ctrl; | 631 | u16 cmd_mask; |
627 | int rc = 0; | ||
628 | 632 | ||
629 | DBG_ENTER_ROUTINE | 633 | DBG_ENTER_ROUTINE |
630 | 634 | ||
631 | rc = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 635 | slot_cmd = 0x0200; |
632 | if (rc) { | 636 | cmd_mask = PWR_LED_CTRL; |
633 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | 637 | if (!pciehp_poll_mode) { |
634 | return; | 638 | slot_cmd = slot_cmd | HP_INTR_ENABLE; |
639 | cmd_mask = cmd_mask | HP_INTR_ENABLE; | ||
635 | } | 640 | } |
636 | 641 | ||
637 | slot_cmd = (slot_ctrl & ~PWR_LED_CTRL) | 0x0200; | 642 | pcie_write_cmd(slot, slot_cmd, cmd_mask); |
638 | |||
639 | if (!pciehp_poll_mode) | ||
640 | slot_cmd = slot_cmd | HP_INTR_ENABLE; | ||
641 | pcie_write_cmd(slot, slot_cmd); | ||
642 | 643 | ||
643 | dbg("%s: SLOTCTRL %x write cmd %x\n", | 644 | dbg("%s: SLOTCTRL %x write cmd %x\n", |
644 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); | 645 | __FUNCTION__, ctrl->cap_base + SLOTCTRL, slot_cmd); |
@@ -669,7 +670,8 @@ static int hpc_power_on_slot(struct slot * slot) | |||
669 | { | 670 | { |
670 | struct controller *ctrl = slot->ctrl; | 671 | struct controller *ctrl = slot->ctrl; |
671 | u16 slot_cmd; | 672 | u16 slot_cmd; |
672 | u16 slot_ctrl, slot_status; | 673 | u16 cmd_mask; |
674 | u16 slot_status; | ||
673 | int retval = 0; | 675 | int retval = 0; |
674 | 676 | ||
675 | DBG_ENTER_ROUTINE | 677 | DBG_ENTER_ROUTINE |
@@ -692,23 +694,23 @@ static int hpc_power_on_slot(struct slot * slot) | |||
692 | } | 694 | } |
693 | } | 695 | } |
694 | 696 | ||
695 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 697 | slot_cmd = POWER_ON; |
696 | if (retval) { | 698 | cmd_mask = PWR_CTRL; |
697 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
698 | return retval; | ||
699 | } | ||
700 | |||
701 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_ON; | ||
702 | |||
703 | /* Enable detection that we turned off at slot power-off time */ | 699 | /* Enable detection that we turned off at slot power-off time */ |
704 | if (!pciehp_poll_mode) | 700 | if (!pciehp_poll_mode) { |
705 | slot_cmd = slot_cmd | | 701 | slot_cmd = slot_cmd | |
706 | PWR_FAULT_DETECT_ENABLE | | 702 | PWR_FAULT_DETECT_ENABLE | |
707 | MRL_DETECT_ENABLE | | 703 | MRL_DETECT_ENABLE | |
708 | PRSN_DETECT_ENABLE | | 704 | PRSN_DETECT_ENABLE | |
709 | HP_INTR_ENABLE; | 705 | HP_INTR_ENABLE; |
706 | cmd_mask = cmd_mask | | ||
707 | PWR_FAULT_DETECT_ENABLE | | ||
708 | MRL_DETECT_ENABLE | | ||
709 | PRSN_DETECT_ENABLE | | ||
710 | HP_INTR_ENABLE; | ||
711 | } | ||
710 | 712 | ||
711 | retval = pcie_write_cmd(slot, slot_cmd); | 713 | retval = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
712 | 714 | ||
713 | if (retval) { | 715 | if (retval) { |
714 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); | 716 | err("%s: Write %x command failed!\n", __FUNCTION__, slot_cmd); |
@@ -726,21 +728,15 @@ static int hpc_power_off_slot(struct slot * slot) | |||
726 | { | 728 | { |
727 | struct controller *ctrl = slot->ctrl; | 729 | struct controller *ctrl = slot->ctrl; |
728 | u16 slot_cmd; | 730 | u16 slot_cmd; |
729 | u16 slot_ctrl; | 731 | u16 cmd_mask; |
730 | int retval = 0; | 732 | int retval = 0; |
731 | 733 | ||
732 | DBG_ENTER_ROUTINE | 734 | DBG_ENTER_ROUTINE |
733 | 735 | ||
734 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); | 736 | dbg("%s: slot->hp_slot %x\n", __FUNCTION__, slot->hp_slot); |
735 | 737 | ||
736 | retval = pciehp_readw(ctrl, SLOTCTRL, &slot_ctrl); | 738 | slot_cmd = POWER_OFF; |
737 | if (retval) { | 739 | cmd_mask = PWR_CTRL; |
738 | err("%s: Cannot read SLOTCTRL register\n", __FUNCTION__); | ||
739 | return retval; | ||
740 | } | ||
741 | |||
742 | slot_cmd = (slot_ctrl & ~PWR_CTRL) | POWER_OFF; | ||
743 | |||
744 | /* | 740 | /* |
745 | * If we get MRL or presence detect interrupts now, the isr | 741 | * If we get MRL or presence detect interrupts now, the isr |
746 | * will notice the sticky power-fault bit too and issue power | 742 | * will notice the sticky power-fault bit too and issue power |
@@ -748,14 +744,19 @@ static int hpc_power_off_slot(struct slot * slot) | |||
748 | * of command completions, since the power-fault bit remains on | 744 | * of command completions, since the power-fault bit remains on |
749 | * till the slot is powered on again. | 745 | * till the slot is powered on again. |
750 | */ | 746 | */ |
751 | if (!pciehp_poll_mode) | 747 | if (!pciehp_poll_mode) { |
752 | slot_cmd = (slot_cmd & | 748 | slot_cmd = (slot_cmd & |
753 | ~PWR_FAULT_DETECT_ENABLE & | 749 | ~PWR_FAULT_DETECT_ENABLE & |
754 | ~MRL_DETECT_ENABLE & | 750 | ~MRL_DETECT_ENABLE & |
755 | ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE; | 751 | ~PRSN_DETECT_ENABLE) | HP_INTR_ENABLE; |
752 | cmd_mask = cmd_mask | | ||
753 | PWR_FAULT_DETECT_ENABLE | | ||
754 | MRL_DETECT_ENABLE | | ||
755 | PRSN_DETECT_ENABLE | | ||
756 | HP_INTR_ENABLE; | ||
757 | } | ||
756 | 758 | ||
757 | retval = pcie_write_cmd(slot, slot_cmd); | 759 | retval = pcie_write_cmd(slot, slot_cmd, cmd_mask); |
758 | |||
759 | if (retval) { | 760 | if (retval) { |
760 | err("%s: Write command failed!\n", __FUNCTION__); | 761 | err("%s: Write command failed!\n", __FUNCTION__); |
761 | return -1; | 762 | return -1; |
@@ -775,6 +776,7 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
775 | u16 temp_word; | 776 | u16 temp_word; |
776 | int hp_slot = 0; /* only 1 slot per PCI Express port */ | 777 | int hp_slot = 0; /* only 1 slot per PCI Express port */ |
777 | int rc = 0; | 778 | int rc = 0; |
779 | unsigned long flags; | ||
778 | 780 | ||
779 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 781 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
780 | if (rc) { | 782 | if (rc) { |
@@ -794,10 +796,12 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
794 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); | 796 | dbg("%s: intr_loc %x\n", __FUNCTION__, intr_loc); |
795 | /* Mask Hot-plug Interrupt Enable */ | 797 | /* Mask Hot-plug Interrupt Enable */ |
796 | if (!pciehp_poll_mode) { | 798 | if (!pciehp_poll_mode) { |
799 | spin_lock_irqsave(&ctrl->lock, flags); | ||
797 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | 800 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
798 | if (rc) { | 801 | if (rc) { |
799 | err("%s: Cannot read SLOT_CTRL register\n", | 802 | err("%s: Cannot read SLOT_CTRL register\n", |
800 | __FUNCTION__); | 803 | __FUNCTION__); |
804 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
801 | return IRQ_NONE; | 805 | return IRQ_NONE; |
802 | } | 806 | } |
803 | 807 | ||
@@ -808,8 +812,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
808 | if (rc) { | 812 | if (rc) { |
809 | err("%s: Cannot write to SLOTCTRL register\n", | 813 | err("%s: Cannot write to SLOTCTRL register\n", |
810 | __FUNCTION__); | 814 | __FUNCTION__); |
815 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
811 | return IRQ_NONE; | 816 | return IRQ_NONE; |
812 | } | 817 | } |
818 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
813 | 819 | ||
814 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 820 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
815 | if (rc) { | 821 | if (rc) { |
@@ -859,10 +865,12 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
859 | } | 865 | } |
860 | /* Unmask Hot-plug Interrupt Enable */ | 866 | /* Unmask Hot-plug Interrupt Enable */ |
861 | if (!pciehp_poll_mode) { | 867 | if (!pciehp_poll_mode) { |
868 | spin_lock_irqsave(&ctrl->lock, flags); | ||
862 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); | 869 | rc = pciehp_readw(ctrl, SLOTCTRL, &temp_word); |
863 | if (rc) { | 870 | if (rc) { |
864 | err("%s: Cannot read SLOTCTRL register\n", | 871 | err("%s: Cannot read SLOTCTRL register\n", |
865 | __FUNCTION__); | 872 | __FUNCTION__); |
873 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
866 | return IRQ_NONE; | 874 | return IRQ_NONE; |
867 | } | 875 | } |
868 | 876 | ||
@@ -873,8 +881,10 @@ static irqreturn_t pcie_isr(int irq, void *dev_id) | |||
873 | if (rc) { | 881 | if (rc) { |
874 | err("%s: Cannot write to SLOTCTRL register\n", | 882 | err("%s: Cannot write to SLOTCTRL register\n", |
875 | __FUNCTION__); | 883 | __FUNCTION__); |
884 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
876 | return IRQ_NONE; | 885 | return IRQ_NONE; |
877 | } | 886 | } |
887 | spin_unlock_irqrestore(&ctrl->lock, flags); | ||
878 | 888 | ||
879 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); | 889 | rc = pciehp_readw(ctrl, SLOTSTATUS, &slot_status); |
880 | if (rc) { | 890 | if (rc) { |
@@ -1237,6 +1247,7 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) | |||
1237 | 1247 | ||
1238 | mutex_init(&ctrl->crit_sect); | 1248 | mutex_init(&ctrl->crit_sect); |
1239 | mutex_init(&ctrl->ctrl_lock); | 1249 | mutex_init(&ctrl->ctrl_lock); |
1250 | spin_lock_init(&ctrl->lock); | ||
1240 | 1251 | ||
1241 | /* setup wait queue */ | 1252 | /* setup wait queue */ |
1242 | init_waitqueue_head(&ctrl->queue); | 1253 | init_waitqueue_head(&ctrl->queue); |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index b5ac810404c0..c8062494009f 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -55,8 +55,6 @@ acpi_query_osc ( | |||
55 | 55 | ||
56 | status = acpi_evaluate_object(handle, "_OSC", &input, &output); | 56 | status = acpi_evaluate_object(handle, "_OSC", &input, &output); |
57 | if (ACPI_FAILURE (status)) { | 57 | if (ACPI_FAILURE (status)) { |
58 | printk(KERN_DEBUG | ||
59 | "Evaluate _OSC Set fails. Status = 0x%04x\n", status); | ||
60 | *ret_status = status; | 58 | *ret_status = status; |
61 | return status; | 59 | return status; |
62 | } | 60 | } |
@@ -124,11 +122,9 @@ acpi_run_osc ( | |||
124 | in_params[3].buffer.pointer = (u8 *)context; | 122 | in_params[3].buffer.pointer = (u8 *)context; |
125 | 123 | ||
126 | status = acpi_evaluate_object(handle, "_OSC", &input, &output); | 124 | status = acpi_evaluate_object(handle, "_OSC", &input, &output); |
127 | if (ACPI_FAILURE (status)) { | 125 | if (ACPI_FAILURE (status)) |
128 | printk(KERN_DEBUG | ||
129 | "Evaluate _OSC Set fails. Status = 0x%04x\n", status); | ||
130 | return status; | 126 | return status; |
131 | } | 127 | |
132 | out_obj = output.pointer; | 128 | out_obj = output.pointer; |
133 | if (out_obj->type != ACPI_TYPE_BUFFER) { | 129 | if (out_obj->type != ACPI_TYPE_BUFFER) { |
134 | printk(KERN_DEBUG | 130 | printk(KERN_DEBUG |
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c index 6543cbe83be5..10dbdec80416 100644 --- a/drivers/pci/pci-sysfs.c +++ b/drivers/pci/pci-sysfs.c | |||
@@ -603,6 +603,11 @@ static struct bin_attribute pcie_config_attr = { | |||
603 | .write = pci_write_config, | 603 | .write = pci_write_config, |
604 | }; | 604 | }; |
605 | 605 | ||
606 | int __attribute__ ((weak)) pcibios_add_platform_entries(struct pci_dev *dev) | ||
607 | { | ||
608 | return 0; | ||
609 | } | ||
610 | |||
606 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | 611 | int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) |
607 | { | 612 | { |
608 | struct bin_attribute *rom_attr = NULL; | 613 | struct bin_attribute *rom_attr = NULL; |
@@ -642,10 +647,14 @@ int __must_check pci_create_sysfs_dev_files (struct pci_dev *pdev) | |||
642 | } | 647 | } |
643 | } | 648 | } |
644 | /* add platform-specific attributes */ | 649 | /* add platform-specific attributes */ |
645 | pcibios_add_platform_entries(pdev); | 650 | if (pcibios_add_platform_entries(pdev)) |
651 | goto err_rom_file; | ||
646 | 652 | ||
647 | return 0; | 653 | return 0; |
648 | 654 | ||
655 | err_rom_file: | ||
656 | if (pci_resource_len(pdev, PCI_ROM_RESOURCE)) | ||
657 | sysfs_remove_bin_file(&pdev->dev.kobj, rom_attr); | ||
649 | err_rom: | 658 | err_rom: |
650 | kfree(rom_attr); | 659 | kfree(rom_attr); |
651 | err_resource_files: | 660 | err_resource_files: |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index fd47ac0c4730..03fd59e80fef 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -406,6 +406,13 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
406 | if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) | 406 | if ((state == PCI_D1 || state == PCI_D2) && pci_no_d1d2(dev)) |
407 | return 0; | 407 | return 0; |
408 | 408 | ||
409 | /* find PCI PM capability in list */ | ||
410 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | ||
411 | |||
412 | /* abort if the device doesn't support PM capabilities */ | ||
413 | if (!pm) | ||
414 | return -EIO; | ||
415 | |||
409 | /* Validate current state: | 416 | /* Validate current state: |
410 | * Can enter D0 from any state, but if we can only go deeper | 417 | * Can enter D0 from any state, but if we can only go deeper |
411 | * to sleep if we're already in a low power state | 418 | * to sleep if we're already in a low power state |
@@ -418,13 +425,6 @@ pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
418 | return 0; /* we're already there */ | 425 | return 0; /* we're already there */ |
419 | 426 | ||
420 | 427 | ||
421 | /* find PCI PM capability in list */ | ||
422 | pm = pci_find_capability(dev, PCI_CAP_ID_PM); | ||
423 | |||
424 | /* abort if the device doesn't support PM capabilities */ | ||
425 | if (!pm) | ||
426 | return -EIO; | ||
427 | |||
428 | pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc); | 428 | pci_read_config_word(dev,pm + PCI_PM_PMC,&pmc); |
429 | if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { | 429 | if ((pmc & PCI_PM_CAP_VER_MASK) > 3) { |
430 | printk(KERN_DEBUG | 430 | printk(KERN_DEBUG |
@@ -1186,6 +1186,11 @@ int pci_set_mwi(struct pci_dev *dev) | |||
1186 | return 0; | 1186 | return 0; |
1187 | } | 1187 | } |
1188 | 1188 | ||
1189 | int pci_try_set_mwi(struct pci_dev *dev) | ||
1190 | { | ||
1191 | return 0; | ||
1192 | } | ||
1193 | |||
1189 | void pci_clear_mwi(struct pci_dev *dev) | 1194 | void pci_clear_mwi(struct pci_dev *dev) |
1190 | { | 1195 | { |
1191 | } | 1196 | } |
@@ -1242,9 +1247,7 @@ pci_set_cacheline_size(struct pci_dev *dev) | |||
1242 | * pci_set_mwi - enables memory-write-invalidate PCI transaction | 1247 | * pci_set_mwi - enables memory-write-invalidate PCI transaction |
1243 | * @dev: the PCI device for which MWI is enabled | 1248 | * @dev: the PCI device for which MWI is enabled |
1244 | * | 1249 | * |
1245 | * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND, | 1250 | * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND. |
1246 | * and then calls @pcibios_set_mwi to do the needed arch specific | ||
1247 | * operations or a generic mwi-prep function. | ||
1248 | * | 1251 | * |
1249 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | 1252 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. |
1250 | */ | 1253 | */ |
@@ -1260,7 +1263,8 @@ pci_set_mwi(struct pci_dev *dev) | |||
1260 | 1263 | ||
1261 | pci_read_config_word(dev, PCI_COMMAND, &cmd); | 1264 | pci_read_config_word(dev, PCI_COMMAND, &cmd); |
1262 | if (! (cmd & PCI_COMMAND_INVALIDATE)) { | 1265 | if (! (cmd & PCI_COMMAND_INVALIDATE)) { |
1263 | pr_debug("PCI: Enabling Mem-Wr-Inval for device %s\n", pci_name(dev)); | 1266 | pr_debug("PCI: Enabling Mem-Wr-Inval for device %s\n", |
1267 | pci_name(dev)); | ||
1264 | cmd |= PCI_COMMAND_INVALIDATE; | 1268 | cmd |= PCI_COMMAND_INVALIDATE; |
1265 | pci_write_config_word(dev, PCI_COMMAND, cmd); | 1269 | pci_write_config_word(dev, PCI_COMMAND, cmd); |
1266 | } | 1270 | } |
@@ -1269,6 +1273,21 @@ pci_set_mwi(struct pci_dev *dev) | |||
1269 | } | 1273 | } |
1270 | 1274 | ||
1271 | /** | 1275 | /** |
1276 | * pci_try_set_mwi - enables memory-write-invalidate PCI transaction | ||
1277 | * @dev: the PCI device for which MWI is enabled | ||
1278 | * | ||
1279 | * Enables the Memory-Write-Invalidate transaction in %PCI_COMMAND. | ||
1280 | * Callers are not required to check the return value. | ||
1281 | * | ||
1282 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | ||
1283 | */ | ||
1284 | int pci_try_set_mwi(struct pci_dev *dev) | ||
1285 | { | ||
1286 | int rc = pci_set_mwi(dev); | ||
1287 | return rc; | ||
1288 | } | ||
1289 | |||
1290 | /** | ||
1272 | * pci_clear_mwi - disables Memory-Write-Invalidate for device dev | 1291 | * pci_clear_mwi - disables Memory-Write-Invalidate for device dev |
1273 | * @dev: the PCI device to disable | 1292 | * @dev: the PCI device to disable |
1274 | * | 1293 | * |
@@ -1375,6 +1394,164 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask) | |||
1375 | #endif | 1394 | #endif |
1376 | 1395 | ||
1377 | /** | 1396 | /** |
1397 | * pcix_get_max_mmrbc - get PCI-X maximum designed memory read byte count | ||
1398 | * @dev: PCI device to query | ||
1399 | * | ||
1400 | * Returns mmrbc: maximum designed memory read count in bytes | ||
1401 | * or appropriate error value. | ||
1402 | */ | ||
1403 | int pcix_get_max_mmrbc(struct pci_dev *dev) | ||
1404 | { | ||
1405 | int err, cap; | ||
1406 | u32 stat; | ||
1407 | |||
1408 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | ||
1409 | if (!cap) | ||
1410 | return -EINVAL; | ||
1411 | |||
1412 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | ||
1413 | if (err) | ||
1414 | return -EINVAL; | ||
1415 | |||
1416 | return (stat & PCI_X_STATUS_MAX_READ) >> 12; | ||
1417 | } | ||
1418 | EXPORT_SYMBOL(pcix_get_max_mmrbc); | ||
1419 | |||
1420 | /** | ||
1421 | * pcix_get_mmrbc - get PCI-X maximum memory read byte count | ||
1422 | * @dev: PCI device to query | ||
1423 | * | ||
1424 | * Returns mmrbc: maximum memory read count in bytes | ||
1425 | * or appropriate error value. | ||
1426 | */ | ||
1427 | int pcix_get_mmrbc(struct pci_dev *dev) | ||
1428 | { | ||
1429 | int ret, cap; | ||
1430 | u32 cmd; | ||
1431 | |||
1432 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | ||
1433 | if (!cap) | ||
1434 | return -EINVAL; | ||
1435 | |||
1436 | ret = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | ||
1437 | if (!ret) | ||
1438 | ret = 512 << ((cmd & PCI_X_CMD_MAX_READ) >> 2); | ||
1439 | |||
1440 | return ret; | ||
1441 | } | ||
1442 | EXPORT_SYMBOL(pcix_get_mmrbc); | ||
1443 | |||
1444 | /** | ||
1445 | * pcix_set_mmrbc - set PCI-X maximum memory read byte count | ||
1446 | * @dev: PCI device to query | ||
1447 | * @mmrbc: maximum memory read count in bytes | ||
1448 | * valid values are 512, 1024, 2048, 4096 | ||
1449 | * | ||
1450 | * If possible sets maximum memory read byte count, some bridges have erratas | ||
1451 | * that prevent this. | ||
1452 | */ | ||
1453 | int pcix_set_mmrbc(struct pci_dev *dev, int mmrbc) | ||
1454 | { | ||
1455 | int cap, err = -EINVAL; | ||
1456 | u32 stat, cmd, v, o; | ||
1457 | |||
1458 | if (mmrbc < 512 || mmrbc > 4096 || (mmrbc & (mmrbc-1))) | ||
1459 | goto out; | ||
1460 | |||
1461 | v = ffs(mmrbc) - 10; | ||
1462 | |||
1463 | cap = pci_find_capability(dev, PCI_CAP_ID_PCIX); | ||
1464 | if (!cap) | ||
1465 | goto out; | ||
1466 | |||
1467 | err = pci_read_config_dword(dev, cap + PCI_X_STATUS, &stat); | ||
1468 | if (err) | ||
1469 | goto out; | ||
1470 | |||
1471 | if (v > (stat & PCI_X_STATUS_MAX_READ) >> 21) | ||
1472 | return -E2BIG; | ||
1473 | |||
1474 | err = pci_read_config_dword(dev, cap + PCI_X_CMD, &cmd); | ||
1475 | if (err) | ||
1476 | goto out; | ||
1477 | |||
1478 | o = (cmd & PCI_X_CMD_MAX_READ) >> 2; | ||
1479 | if (o != v) { | ||
1480 | if (v > o && dev->bus && | ||
1481 | (dev->bus->bus_flags & PCI_BUS_FLAGS_NO_MMRBC)) | ||
1482 | return -EIO; | ||
1483 | |||
1484 | cmd &= ~PCI_X_CMD_MAX_READ; | ||
1485 | cmd |= v << 2; | ||
1486 | err = pci_write_config_dword(dev, cap + PCI_X_CMD, cmd); | ||
1487 | } | ||
1488 | out: | ||
1489 | return err; | ||
1490 | } | ||
1491 | EXPORT_SYMBOL(pcix_set_mmrbc); | ||
1492 | |||
1493 | /** | ||
1494 | * pcie_get_readrq - get PCI Express read request size | ||
1495 | * @dev: PCI device to query | ||
1496 | * | ||
1497 | * Returns maximum memory read request in bytes | ||
1498 | * or appropriate error value. | ||
1499 | */ | ||
1500 | int pcie_get_readrq(struct pci_dev *dev) | ||
1501 | { | ||
1502 | int ret, cap; | ||
1503 | u16 ctl; | ||
1504 | |||
1505 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
1506 | if (!cap) | ||
1507 | return -EINVAL; | ||
1508 | |||
1509 | ret = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); | ||
1510 | if (!ret) | ||
1511 | ret = 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); | ||
1512 | |||
1513 | return ret; | ||
1514 | } | ||
1515 | EXPORT_SYMBOL(pcie_get_readrq); | ||
1516 | |||
1517 | /** | ||
1518 | * pcie_set_readrq - set PCI Express maximum memory read request | ||
1519 | * @dev: PCI device to query | ||
1520 | * @count: maximum memory read count in bytes | ||
1521 | * valid values are 128, 256, 512, 1024, 2048, 4096 | ||
1522 | * | ||
1523 | * If possible sets maximum read byte count | ||
1524 | */ | ||
1525 | int pcie_set_readrq(struct pci_dev *dev, int rq) | ||
1526 | { | ||
1527 | int cap, err = -EINVAL; | ||
1528 | u16 ctl, v; | ||
1529 | |||
1530 | if (rq < 128 || rq > 4096 || (rq & (rq-1))) | ||
1531 | goto out; | ||
1532 | |||
1533 | v = (ffs(rq) - 8) << 12; | ||
1534 | |||
1535 | cap = pci_find_capability(dev, PCI_CAP_ID_EXP); | ||
1536 | if (!cap) | ||
1537 | goto out; | ||
1538 | |||
1539 | err = pci_read_config_word(dev, cap + PCI_EXP_DEVCTL, &ctl); | ||
1540 | if (err) | ||
1541 | goto out; | ||
1542 | |||
1543 | if ((ctl & PCI_EXP_DEVCTL_READRQ) != v) { | ||
1544 | ctl &= ~PCI_EXP_DEVCTL_READRQ; | ||
1545 | ctl |= v; | ||
1546 | err = pci_write_config_dword(dev, cap + PCI_EXP_DEVCTL, ctl); | ||
1547 | } | ||
1548 | |||
1549 | out: | ||
1550 | return err; | ||
1551 | } | ||
1552 | EXPORT_SYMBOL(pcie_set_readrq); | ||
1553 | |||
1554 | /** | ||
1378 | * pci_select_bars - Make BAR mask from the type of resource | 1555 | * pci_select_bars - Make BAR mask from the type of resource |
1379 | * @dev: the PCI device for which BAR mask is made | 1556 | * @dev: the PCI device for which BAR mask is made |
1380 | * @flags: resource type mask to be selected | 1557 | * @flags: resource type mask to be selected |
@@ -1442,6 +1619,7 @@ EXPORT_SYMBOL(pci_release_selected_regions); | |||
1442 | EXPORT_SYMBOL(pci_request_selected_regions); | 1619 | EXPORT_SYMBOL(pci_request_selected_regions); |
1443 | EXPORT_SYMBOL(pci_set_master); | 1620 | EXPORT_SYMBOL(pci_set_master); |
1444 | EXPORT_SYMBOL(pci_set_mwi); | 1621 | EXPORT_SYMBOL(pci_set_mwi); |
1622 | EXPORT_SYMBOL(pci_try_set_mwi); | ||
1445 | EXPORT_SYMBOL(pci_clear_mwi); | 1623 | EXPORT_SYMBOL(pci_clear_mwi); |
1446 | EXPORT_SYMBOL_GPL(pci_intx); | 1624 | EXPORT_SYMBOL_GPL(pci_intx); |
1447 | EXPORT_SYMBOL(pci_set_dma_mask); | 1625 | EXPORT_SYMBOL(pci_set_dma_mask); |
diff --git a/drivers/pci/pcie/aer/Kconfig b/drivers/pci/pcie/aer/Kconfig index 3f37a60a6438..c3bde588aa13 100644 --- a/drivers/pci/pcie/aer/Kconfig +++ b/drivers/pci/pcie/aer/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | config PCIEAER | 5 | config PCIEAER |
6 | boolean "Root Port Advanced Error Reporting support" | 6 | boolean "Root Port Advanced Error Reporting support" |
7 | depends on PCIEPORTBUS && ACPI | 7 | depends on PCIEPORTBUS |
8 | default y | 8 | default y |
9 | help | 9 | help |
10 | This enables PCI Express Root Port Advanced Error Reporting | 10 | This enables PCI Express Root Port Advanced Error Reporting |
diff --git a/drivers/pci/pcie/aer/Makefile b/drivers/pci/pcie/aer/Makefile index 15a4f40d520b..8da3bd8455a8 100644 --- a/drivers/pci/pcie/aer/Makefile +++ b/drivers/pci/pcie/aer/Makefile | |||
@@ -4,5 +4,6 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_PCIEAER) += aerdriver.o | 5 | obj-$(CONFIG_PCIEAER) += aerdriver.o |
6 | 6 | ||
7 | aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o aerdrv_acpi.o | 7 | aerdriver-objs := aerdrv_errprint.o aerdrv_core.o aerdrv.o |
8 | aerdriver-$(CONFIG_ACPI) += aerdrv_acpi.o | ||
8 | 9 | ||
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c index db6ad8e763ac..6846fb42b399 100644 --- a/drivers/pci/pcie/aer/aerdrv.c +++ b/drivers/pci/pcie/aer/aerdrv.c | |||
@@ -157,7 +157,7 @@ static struct aer_rpc* aer_alloc_rpc(struct pcie_device *dev) | |||
157 | * Initialize Root lock access, e_lock, to Root Error Status Reg, | 157 | * Initialize Root lock access, e_lock, to Root Error Status Reg, |
158 | * Root Error ID Reg, and Root error producer/consumer index. | 158 | * Root Error ID Reg, and Root error producer/consumer index. |
159 | */ | 159 | */ |
160 | rpc->e_lock = SPIN_LOCK_UNLOCKED; | 160 | spin_lock_init(&rpc->e_lock); |
161 | 161 | ||
162 | rpc->rpd = dev; | 162 | rpc->rpd = dev; |
163 | INIT_WORK(&rpc->dpc_handler, aer_isr); | 163 | INIT_WORK(&rpc->dpc_handler, aer_isr); |
diff --git a/drivers/pci/pcie/aer/aerdrv.h b/drivers/pci/pcie/aer/aerdrv.h index 5cca394d5999..c7ad68b6c6d6 100644 --- a/drivers/pci/pcie/aer/aerdrv.h +++ b/drivers/pci/pcie/aer/aerdrv.h | |||
@@ -19,10 +19,6 @@ | |||
19 | #define AER_ERROR_MASK 0x001fffff | 19 | #define AER_ERROR_MASK 0x001fffff |
20 | #define AER_ERROR(d) (d & AER_ERROR_MASK) | 20 | #define AER_ERROR(d) (d & AER_ERROR_MASK) |
21 | 21 | ||
22 | #define OSC_METHOD_RUN_SUCCESS 0 | ||
23 | #define OSC_METHOD_NOT_SUPPORTED 1 | ||
24 | #define OSC_METHOD_RUN_FAILURE 2 | ||
25 | |||
26 | /* Root Error Status Register Bits */ | 22 | /* Root Error Status Register Bits */ |
27 | #define ROOT_ERR_STATUS_MASKS 0x0f | 23 | #define ROOT_ERR_STATUS_MASKS 0x0f |
28 | 24 | ||
@@ -121,6 +117,14 @@ extern void aer_delete_rootport(struct aer_rpc *rpc); | |||
121 | extern int aer_init(struct pcie_device *dev); | 117 | extern int aer_init(struct pcie_device *dev); |
122 | extern void aer_isr(struct work_struct *work); | 118 | extern void aer_isr(struct work_struct *work); |
123 | extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); | 119 | extern void aer_print_error(struct pci_dev *dev, struct aer_err_info *info); |
124 | extern int aer_osc_setup(struct pci_dev *dev); | 120 | |
121 | #ifdef CONFIG_ACPI | ||
122 | extern int aer_osc_setup(struct pcie_device *pciedev); | ||
123 | #else | ||
124 | static inline int aer_osc_setup(struct pcie_device *pciedev) | ||
125 | { | ||
126 | return 0; | ||
127 | } | ||
128 | #endif | ||
125 | 129 | ||
126 | #endif //_AERDRV_H_ | 130 | #endif //_AERDRV_H_ |
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c index fa68e89ebec9..1a1eb45a779e 100644 --- a/drivers/pci/pcie/aer/aerdrv_acpi.c +++ b/drivers/pci/pcie/aer/aerdrv_acpi.c | |||
@@ -20,19 +20,18 @@ | |||
20 | 20 | ||
21 | /** | 21 | /** |
22 | * aer_osc_setup - run ACPI _OSC method | 22 | * aer_osc_setup - run ACPI _OSC method |
23 | * @pciedev: pcie_device which AER is being enabled on | ||
23 | * | 24 | * |
24 | * Return: | 25 | * @return: Zero on success. Nonzero otherwise. |
25 | * Zero if success. Nonzero for otherwise. | ||
26 | * | 26 | * |
27 | * Invoked when PCIE bus loads AER service driver. To avoid conflict with | 27 | * Invoked when PCIE bus loads AER service driver. To avoid conflict with |
28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. | 28 | * BIOS AER support requires BIOS to yield AER control to OS native driver. |
29 | **/ | 29 | **/ |
30 | int aer_osc_setup(struct pci_dev *dev) | 30 | int aer_osc_setup(struct pcie_device *pciedev) |
31 | { | 31 | { |
32 | int retval = OSC_METHOD_RUN_SUCCESS; | 32 | acpi_status status = AE_NOT_FOUND; |
33 | acpi_status status; | 33 | struct pci_dev *pdev = pciedev->port; |
34 | acpi_handle handle = DEVICE_ACPI_HANDLE(&dev->dev); | 34 | acpi_handle handle = DEVICE_ACPI_HANDLE(&pdev->dev); |
35 | struct pci_dev *pdev = dev; | ||
36 | struct pci_bus *parent; | 35 | struct pci_bus *parent; |
37 | 36 | ||
38 | while (!handle) { | 37 | while (!handle) { |
@@ -50,19 +49,20 @@ int aer_osc_setup(struct pci_dev *dev) | |||
50 | pdev = parent->self; | 49 | pdev = parent->self; |
51 | } | 50 | } |
52 | 51 | ||
53 | if (!handle) | 52 | if (handle) { |
54 | return OSC_METHOD_NOT_SUPPORTED; | 53 | pci_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); |
54 | status = pci_osc_control_set(handle, | ||
55 | OSC_PCI_EXPRESS_AER_CONTROL | | ||
56 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
57 | } | ||
55 | 58 | ||
56 | pci_osc_support_set(OSC_EXT_PCI_CONFIG_SUPPORT); | ||
57 | status = pci_osc_control_set(handle, OSC_PCI_EXPRESS_AER_CONTROL | | ||
58 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
59 | if (ACPI_FAILURE(status)) { | 59 | if (ACPI_FAILURE(status)) { |
60 | if (status == AE_SUPPORT) | 60 | printk(KERN_DEBUG "AER service couldn't init device %s - %s\n", |
61 | retval = OSC_METHOD_NOT_SUPPORTED; | 61 | pciedev->device.bus_id, |
62 | else | 62 | (status == AE_SUPPORT || status == AE_NOT_FOUND) ? |
63 | retval = OSC_METHOD_RUN_FAILURE; | 63 | "no _OSC support" : "Run ACPI _OSC fails"); |
64 | return -1; | ||
64 | } | 65 | } |
65 | 66 | ||
66 | return retval; | 67 | return 0; |
67 | } | 68 | } |
68 | |||
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c index 08e13033ced8..92a8469b21ba 100644 --- a/drivers/pci/pcie/aer/aerdrv_core.c +++ b/drivers/pci/pcie/aer/aerdrv_core.c | |||
@@ -22,8 +22,6 @@ | |||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/pm.h> | 23 | #include <linux/pm.h> |
24 | #include <linux/suspend.h> | 24 | #include <linux/suspend.h> |
25 | #include <linux/acpi.h> | ||
26 | #include <linux/pci-acpi.h> | ||
27 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
28 | #include "aerdrv.h" | 26 | #include "aerdrv.h" |
29 | 27 | ||
@@ -119,6 +117,21 @@ int pci_cleanup_aer_uncorrect_error_status(struct pci_dev *dev) | |||
119 | return 0; | 117 | return 0; |
120 | } | 118 | } |
121 | 119 | ||
120 | int pci_cleanup_aer_correct_error_status(struct pci_dev *dev) | ||
121 | { | ||
122 | int pos; | ||
123 | u32 status; | ||
124 | |||
125 | pos = pci_find_aer_capability(dev); | ||
126 | if (!pos) | ||
127 | return -EIO; | ||
128 | |||
129 | pci_read_config_dword(dev, pos + PCI_ERR_COR_STATUS, &status); | ||
130 | pci_write_config_dword(dev, pos + PCI_ERR_COR_STATUS, status); | ||
131 | |||
132 | return 0; | ||
133 | } | ||
134 | |||
122 | static int find_device_iter(struct device *device, void *data) | 135 | static int find_device_iter(struct device *device, void *data) |
123 | { | 136 | { |
124 | struct pci_dev *dev; | 137 | struct pci_dev *dev; |
@@ -733,20 +746,8 @@ void aer_delete_rootport(struct aer_rpc *rpc) | |||
733 | **/ | 746 | **/ |
734 | int aer_init(struct pcie_device *dev) | 747 | int aer_init(struct pcie_device *dev) |
735 | { | 748 | { |
736 | int status; | 749 | if (aer_osc_setup(dev) && !forceload) |
737 | 750 | return -ENXIO; | |
738 | /* Run _OSC Method */ | ||
739 | status = aer_osc_setup(dev->port); | ||
740 | |||
741 | if(status != OSC_METHOD_RUN_SUCCESS) { | ||
742 | printk(KERN_DEBUG "%s: AER service init fails - %s\n", | ||
743 | __FUNCTION__, | ||
744 | (status == OSC_METHOD_NOT_SUPPORTED) ? | ||
745 | "No ACPI _OSC support" : "Run ACPI _OSC fails"); | ||
746 | |||
747 | if (!forceload) | ||
748 | return status; | ||
749 | } | ||
750 | 751 | ||
751 | return AER_SUCCESS; | 752 | return AER_SUCCESS; |
752 | } | 753 | } |
@@ -755,4 +756,5 @@ EXPORT_SYMBOL_GPL(pci_find_aer_capability); | |||
755 | EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); | 756 | EXPORT_SYMBOL_GPL(pci_enable_pcie_error_reporting); |
756 | EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); | 757 | EXPORT_SYMBOL_GPL(pci_disable_pcie_error_reporting); |
757 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); | 758 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_uncorrect_error_status); |
759 | EXPORT_SYMBOL_GPL(pci_cleanup_aer_correct_error_status); | ||
758 | 760 | ||
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 08783bd381f5..a7bce75c6732 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c | |||
@@ -654,7 +654,7 @@ int pci_scan_bridge(struct pci_bus *bus, struct pci_dev * dev, int max, int pass | |||
654 | pcibios_assign_all_busses() ? " " : | 654 | pcibios_assign_all_busses() ? " " : |
655 | " (try 'pci=assign-busses')"); | 655 | " (try 'pci=assign-busses')"); |
656 | printk(KERN_WARNING "Please report the result to " | 656 | printk(KERN_WARNING "Please report the result to " |
657 | "linux-kernel to fix this permanently\n"); | 657 | "<bk@suse.de> to fix this permanently\n"); |
658 | } | 658 | } |
659 | bus = bus->parent; | 659 | bus = bus->parent; |
660 | } | 660 | } |
@@ -700,6 +700,7 @@ static int pci_setup_device(struct pci_dev * dev) | |||
700 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); | 700 | dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn)); |
701 | 701 | ||
702 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); | 702 | pci_read_config_dword(dev, PCI_CLASS_REVISION, &class); |
703 | dev->revision = class & 0xff; | ||
703 | class >>= 8; /* upper 3 bytes */ | 704 | class >>= 8; /* upper 3 bytes */ |
704 | dev->class = class; | 705 | dev->class = class; |
705 | class >>= 8; | 706 | class >>= 8; |
diff --git a/drivers/pci/proc.c b/drivers/pci/proc.c index 0425a7b7350d..cfa0dfe61b1a 100644 --- a/drivers/pci/proc.c +++ b/drivers/pci/proc.c | |||
@@ -480,7 +480,6 @@ static int __init pci_proc_init(void) | |||
480 | __initcall(pci_proc_init); | 480 | __initcall(pci_proc_init); |
481 | 481 | ||
482 | #ifdef CONFIG_HOTPLUG | 482 | #ifdef CONFIG_HOTPLUG |
483 | EXPORT_SYMBOL(pci_proc_attach_device); | ||
484 | EXPORT_SYMBOL(pci_proc_detach_bus); | 483 | EXPORT_SYMBOL(pci_proc_detach_bus); |
485 | #endif | 484 | #endif |
486 | 485 | ||
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index 01d8f8a8843c..c559085c89a5 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c | |||
@@ -587,10 +587,7 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_v | |||
587 | */ | 587 | */ |
588 | static void __devinit quirk_amd_ioapic(struct pci_dev *dev) | 588 | static void __devinit quirk_amd_ioapic(struct pci_dev *dev) |
589 | { | 589 | { |
590 | u8 rev; | 590 | if (dev->revision >= 0x02) { |
591 | |||
592 | pci_read_config_byte(dev, PCI_REVISION_ID, &rev); | ||
593 | if (rev >= 0x02) { | ||
594 | printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n"); | 591 | printk(KERN_WARNING "I/O APIC: AMD Erratum #22 may be present. In the event of instability try\n"); |
595 | printk(KERN_WARNING " : booting with the \"noapic\" option.\n"); | 592 | printk(KERN_WARNING " : booting with the \"noapic\" option.\n"); |
596 | } | 593 | } |
@@ -610,13 +607,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw ); | |||
610 | #define AMD8131_NIOAMODE_BIT 0 | 607 | #define AMD8131_NIOAMODE_BIT 0 |
611 | static void quirk_amd_8131_ioapic(struct pci_dev *dev) | 608 | static void quirk_amd_8131_ioapic(struct pci_dev *dev) |
612 | { | 609 | { |
613 | unsigned char revid, tmp; | 610 | unsigned char tmp; |
614 | 611 | ||
615 | if (nr_ioapics == 0) | 612 | if (nr_ioapics == 0) |
616 | return; | 613 | return; |
617 | 614 | ||
618 | pci_read_config_byte(dev, PCI_REVISION_ID, &revid); | 615 | if (dev->revision == AMD8131_revA0 || dev->revision == AMD8131_revB0) { |
619 | if (revid == AMD8131_revA0 || revid == AMD8131_revB0) { | ||
620 | printk(KERN_INFO "Fixing up AMD8131 IOAPIC mode\n"); | 616 | printk(KERN_INFO "Fixing up AMD8131 IOAPIC mode\n"); |
621 | pci_read_config_byte( dev, AMD8131_MISC, &tmp); | 617 | pci_read_config_byte( dev, AMD8131_MISC, &tmp); |
622 | tmp &= ~(1 << AMD8131_NIOAMODE_BIT); | 618 | tmp &= ~(1 << AMD8131_NIOAMODE_BIT); |
@@ -627,6 +623,22 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_ | |||
627 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); | 623 | DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic); |
628 | #endif /* CONFIG_X86_IO_APIC */ | 624 | #endif /* CONFIG_X86_IO_APIC */ |
629 | 625 | ||
626 | /* | ||
627 | * Some settings of MMRBC can lead to data corruption so block changes. | ||
628 | * See AMD 8131 HyperTransport PCI-X Tunnel Revision Guide | ||
629 | */ | ||
630 | static void __init quirk_amd_8131_mmrbc(struct pci_dev *dev) | ||
631 | { | ||
632 | unsigned char revid; | ||
633 | |||
634 | pci_read_config_byte(dev, PCI_REVISION_ID, &revid); | ||
635 | if (dev->subordinate && revid <= 0x12) { | ||
636 | printk(KERN_INFO "AMD8131 rev %x detected, disabling PCI-X " | ||
637 | "MMRBC\n", revid); | ||
638 | dev->subordinate->bus_flags |= PCI_BUS_FLAGS_NO_MMRBC; | ||
639 | } | ||
640 | } | ||
641 | DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_mmrbc); | ||
630 | 642 | ||
631 | /* | 643 | /* |
632 | * FIXME: it is questionable that quirk_via_acpi | 644 | * FIXME: it is questionable that quirk_via_acpi |
@@ -843,10 +855,8 @@ DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, qu | |||
843 | static void quirk_disable_pxb(struct pci_dev *pdev) | 855 | static void quirk_disable_pxb(struct pci_dev *pdev) |
844 | { | 856 | { |
845 | u16 config; | 857 | u16 config; |
846 | u8 rev; | ||
847 | 858 | ||
848 | pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); | 859 | if (pdev->revision != 0x04) /* Only C0 requires this */ |
849 | if (rev != 0x04) /* Only C0 requires this */ | ||
850 | return; | 860 | return; |
851 | pci_read_config_word(pdev, 0x40, &config); | 861 | pci_read_config_word(pdev, 0x40, &config); |
852 | if (config & (1<<6)) { | 862 | if (config & (1<<6)) { |
diff --git a/drivers/pci/search.c b/drivers/pci/search.c index c13232435dc0..9f7090fa8771 100644 --- a/drivers/pci/search.c +++ b/drivers/pci/search.c | |||
@@ -139,12 +139,14 @@ struct pci_dev * pci_get_slot(struct pci_bus *bus, unsigned int devfn) | |||
139 | } | 139 | } |
140 | 140 | ||
141 | /** | 141 | /** |
142 | * pci_get_bus_and_slot - locate PCI device from a given PCI slot | 142 | * pci_get_bus_and_slot - locate PCI device from a given PCI bus & slot |
143 | * @bus: number of PCI bus on which desired PCI device resides | 143 | * @bus: number of PCI bus on which desired PCI device resides |
144 | * @devfn: encodes number of PCI slot in which the desired PCI | 144 | * @devfn: encodes number of PCI slot in which the desired PCI |
145 | * device resides and the logical device number within that slot | 145 | * device resides and the logical device number within that slot |
146 | * in case of multi-function devices. | 146 | * in case of multi-function devices. |
147 | * | 147 | * |
148 | * Note: the bus/slot search is limited to PCI domain (segment) 0. | ||
149 | * | ||
148 | * Given a PCI bus and slot/function number, the desired PCI device | 150 | * Given a PCI bus and slot/function number, the desired PCI device |
149 | * is located in system global list of PCI devices. If the device | 151 | * is located in system global list of PCI devices. If the device |
150 | * is found, a pointer to its data structure is returned. If no | 152 | * is found, a pointer to its data structure is returned. If no |
@@ -157,7 +159,8 @@ struct pci_dev * pci_get_bus_and_slot(unsigned int bus, unsigned int devfn) | |||
157 | struct pci_dev *dev = NULL; | 159 | struct pci_dev *dev = NULL; |
158 | 160 | ||
159 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { | 161 | while ((dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) { |
160 | if (dev->bus->number == bus && dev->devfn == devfn) | 162 | if (pci_domain_nr(dev->bus) == 0 && |
163 | (dev->bus->number == bus && dev->devfn == devfn)) | ||
161 | return dev; | 164 | return dev; |
162 | } | 165 | } |
163 | return NULL; | 166 | return NULL; |
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 5ec297d7a5b4..5e5191ec8de6 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c | |||
@@ -34,8 +34,6 @@ | |||
34 | #define DBG(x...) | 34 | #define DBG(x...) |
35 | #endif | 35 | #endif |
36 | 36 | ||
37 | #define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) | ||
38 | |||
39 | static void pbus_assign_resources_sorted(struct pci_bus *bus) | 37 | static void pbus_assign_resources_sorted(struct pci_bus *bus) |
40 | { | 38 | { |
41 | struct pci_dev *dev; | 39 | struct pci_dev *dev; |
@@ -310,7 +308,7 @@ static void pbus_size_io(struct pci_bus *bus) | |||
310 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) | 308 | #if defined(CONFIG_ISA) || defined(CONFIG_EISA) |
311 | size = (size & 0xff) + ((size & ~0xffUL) << 2); | 309 | size = (size & 0xff) + ((size & ~0xffUL) << 2); |
312 | #endif | 310 | #endif |
313 | size = ROUND_UP(size + size1, 4096); | 311 | size = ALIGN(size + size1, 4096); |
314 | if (!size) { | 312 | if (!size) { |
315 | b_res->flags = 0; | 313 | b_res->flags = 0; |
316 | return; | 314 | return; |
@@ -378,11 +376,11 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long | |||
378 | 376 | ||
379 | if (!align) | 377 | if (!align) |
380 | min_align = align1; | 378 | min_align = align1; |
381 | else if (ROUND_UP(align + min_align, min_align) < align1) | 379 | else if (ALIGN(align + min_align, min_align) < align1) |
382 | min_align = align1 >> 1; | 380 | min_align = align1 >> 1; |
383 | align += aligns[order]; | 381 | align += aligns[order]; |
384 | } | 382 | } |
385 | size = ROUND_UP(size, min_align); | 383 | size = ALIGN(size, min_align); |
386 | if (!size) { | 384 | if (!size) { |
387 | b_res->flags = 0; | 385 | b_res->flags = 0; |
388 | return 1; | 386 | return 1; |
diff --git a/drivers/pci/syscall.c b/drivers/pci/syscall.c index 9d37fec27f24..2ac050d7f8cf 100644 --- a/drivers/pci/syscall.c +++ b/drivers/pci/syscall.c | |||
@@ -23,14 +23,14 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn, | |||
23 | u8 byte; | 23 | u8 byte; |
24 | u16 word; | 24 | u16 word; |
25 | u32 dword; | 25 | u32 dword; |
26 | long err, cfg_ret; | 26 | long err; |
27 | long cfg_ret; | ||
27 | 28 | ||
28 | err = -EPERM; | ||
29 | if (!capable(CAP_SYS_ADMIN)) | 29 | if (!capable(CAP_SYS_ADMIN)) |
30 | goto error; | 30 | return -EPERM; |
31 | 31 | ||
32 | err = -ENODEV; | 32 | err = -ENODEV; |
33 | dev = pci_find_slot(bus, dfn); | 33 | dev = pci_get_bus_and_slot(bus, dfn); |
34 | if (!dev) | 34 | if (!dev) |
35 | goto error; | 35 | goto error; |
36 | 36 | ||
@@ -66,7 +66,8 @@ sys_pciconfig_read(unsigned long bus, unsigned long dfn, | |||
66 | case 4: | 66 | case 4: |
67 | err = put_user(dword, (unsigned int __user *)buf); | 67 | err = put_user(dword, (unsigned int __user *)buf); |
68 | break; | 68 | break; |
69 | }; | 69 | } |
70 | pci_dev_put(dev); | ||
70 | return err; | 71 | return err; |
71 | 72 | ||
72 | error: | 73 | error: |
@@ -83,7 +84,8 @@ error: | |||
83 | case 4: | 84 | case 4: |
84 | put_user(-1, (unsigned int __user *)buf); | 85 | put_user(-1, (unsigned int __user *)buf); |
85 | break; | 86 | break; |
86 | }; | 87 | } |
88 | pci_dev_put(dev); | ||
87 | return err; | 89 | return err; |
88 | } | 90 | } |
89 | 91 | ||
@@ -101,7 +103,7 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, | |||
101 | if (!capable(CAP_SYS_ADMIN)) | 103 | if (!capable(CAP_SYS_ADMIN)) |
102 | return -EPERM; | 104 | return -EPERM; |
103 | 105 | ||
104 | dev = pci_find_slot(bus, dfn); | 106 | dev = pci_get_bus_and_slot(bus, dfn); |
105 | if (!dev) | 107 | if (!dev) |
106 | return -ENODEV; | 108 | return -ENODEV; |
107 | 109 | ||
@@ -137,8 +139,8 @@ sys_pciconfig_write(unsigned long bus, unsigned long dfn, | |||
137 | default: | 139 | default: |
138 | err = -EINVAL; | 140 | err = -EINVAL; |
139 | break; | 141 | break; |
140 | }; | 142 | } |
141 | unlock_kernel(); | 143 | unlock_kernel(); |
142 | 144 | pci_dev_put(dev); | |
143 | return err; | 145 | return err; |
144 | } | 146 | } |