diff options
-rw-r--r-- | drivers/pci/msi.c | 6 | ||||
-rw-r--r-- | drivers/pci/pci.c | 9 | ||||
-rw-r--r-- | include/linux/pci.h | 2 |
3 files changed, 14 insertions, 3 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 9c69b6966e79..3ec558dc6523 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -453,9 +453,11 @@ static void enable_msi_mode(struct pci_dev *dev, int pos, int type) | |||
453 | /* Set enabled bits to single MSI & enable MSI_enable bit */ | 453 | /* Set enabled bits to single MSI & enable MSI_enable bit */ |
454 | msi_enable(control, 1); | 454 | msi_enable(control, 1); |
455 | pci_write_config_word(dev, msi_control_reg(pos), control); | 455 | pci_write_config_word(dev, msi_control_reg(pos), control); |
456 | dev->msi_enabled = 1; | ||
456 | } else { | 457 | } else { |
457 | msix_enable(control); | 458 | msix_enable(control); |
458 | pci_write_config_word(dev, msi_control_reg(pos), control); | 459 | pci_write_config_word(dev, msi_control_reg(pos), control); |
460 | dev->msix_enabled = 1; | ||
459 | } | 461 | } |
460 | if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { | 462 | if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { |
461 | /* PCI Express Endpoint device detected */ | 463 | /* PCI Express Endpoint device detected */ |
@@ -472,9 +474,11 @@ void disable_msi_mode(struct pci_dev *dev, int pos, int type) | |||
472 | /* Set enabled bits to single MSI & enable MSI_enable bit */ | 474 | /* Set enabled bits to single MSI & enable MSI_enable bit */ |
473 | msi_disable(control); | 475 | msi_disable(control); |
474 | pci_write_config_word(dev, msi_control_reg(pos), control); | 476 | pci_write_config_word(dev, msi_control_reg(pos), control); |
477 | dev->msi_enabled = 0; | ||
475 | } else { | 478 | } else { |
476 | msix_disable(control); | 479 | msix_disable(control); |
477 | pci_write_config_word(dev, msi_control_reg(pos), control); | 480 | pci_write_config_word(dev, msi_control_reg(pos), control); |
481 | dev->msix_enabled = 0; | ||
478 | } | 482 | } |
479 | if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { | 483 | if (pci_find_capability(dev, PCI_CAP_ID_EXP)) { |
480 | /* PCI Express Endpoint device detected */ | 484 | /* PCI Express Endpoint device detected */ |
@@ -549,7 +553,6 @@ int pci_save_msi_state(struct pci_dev *dev) | |||
549 | pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); | 553 | pci_read_config_dword(dev, pos + PCI_MSI_DATA_32, &cap[i++]); |
550 | if (control & PCI_MSI_FLAGS_MASKBIT) | 554 | if (control & PCI_MSI_FLAGS_MASKBIT) |
551 | pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); | 555 | pci_read_config_dword(dev, pos + PCI_MSI_MASK_BIT, &cap[i++]); |
552 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSI); | ||
553 | save_state->cap_nr = PCI_CAP_ID_MSI; | 556 | save_state->cap_nr = PCI_CAP_ID_MSI; |
554 | pci_add_saved_cap(dev, save_state); | 557 | pci_add_saved_cap(dev, save_state); |
555 | return 0; | 558 | return 0; |
@@ -639,7 +642,6 @@ int pci_save_msix_state(struct pci_dev *dev) | |||
639 | } | 642 | } |
640 | dev->irq = temp; | 643 | dev->irq = temp; |
641 | 644 | ||
642 | disable_msi_mode(dev, pos, PCI_CAP_ID_MSIX); | ||
643 | save_state->cap_nr = PCI_CAP_ID_MSIX; | 645 | save_state->cap_nr = PCI_CAP_ID_MSIX; |
644 | pci_add_saved_cap(dev, save_state); | 646 | pci_add_saved_cap(dev, save_state); |
645 | return 0; | 647 | return 0; |
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index aa480370ef10..d408a3c30426 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c | |||
@@ -551,7 +551,14 @@ void | |||
551 | pci_disable_device(struct pci_dev *dev) | 551 | pci_disable_device(struct pci_dev *dev) |
552 | { | 552 | { |
553 | u16 pci_command; | 553 | u16 pci_command; |
554 | 554 | ||
555 | if (dev->msi_enabled) | ||
556 | disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), | ||
557 | PCI_CAP_ID_MSI); | ||
558 | if (dev->msix_enabled) | ||
559 | disable_msi_mode(dev, pci_find_capability(dev, PCI_CAP_ID_MSI), | ||
560 | PCI_CAP_ID_MSIX); | ||
561 | |||
555 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); | 562 | pci_read_config_word(dev, PCI_COMMAND, &pci_command); |
556 | if (pci_command & PCI_COMMAND_MASTER) { | 563 | if (pci_command & PCI_COMMAND_MASTER) { |
557 | pci_command &= ~PCI_COMMAND_MASTER; | 564 | pci_command &= ~PCI_COMMAND_MASTER; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 91c37750cd34..62a8c22f5f60 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -163,6 +163,8 @@ struct pci_dev { | |||
163 | unsigned int no_msi:1; /* device may not use msi */ | 163 | unsigned int no_msi:1; /* device may not use msi */ |
164 | unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ | 164 | unsigned int block_ucfg_access:1; /* userspace config space access is blocked */ |
165 | unsigned int broken_parity_status:1; /* Device generates false positive parity */ | 165 | unsigned int broken_parity_status:1; /* Device generates false positive parity */ |
166 | unsigned int msi_enabled:1; | ||
167 | unsigned int msix_enabled:1; | ||
166 | 168 | ||
167 | u32 saved_config_space[16]; /* config space saved at suspend time */ | 169 | u32 saved_config_space[16]; /* config space saved at suspend time */ |
168 | struct hlist_head saved_cap_space; | 170 | struct hlist_head saved_cap_space; |