diff options
author | Alexander Gordeev <agordeev@redhat.com> | 2013-12-30 02:28:14 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2014-01-03 19:17:55 -0500 |
commit | 7b92b4f61ec49cb1a5813298f35258bd7ecd3667 (patch) | |
tree | 3ca281ebb26a2885ff9ff5fd4e1b15393b6f7c20 | |
parent | d1ac1d2622e8f0fd2a25127a8649d135b54db8a9 (diff) |
PCI/MSI: Remove pci_enable_msi_block_auto()
The new pci_msi_vec_count() interface makes pci_enable_msi_block_auto()
superfluous.
Drivers can use pci_msi_vec_count() to learn the maximum number of MSIs
supported by the device, and then call pci_enable_msi_block().
pci_enable_msi_block_auto() was introduced recently, and its only user is
the AHCI driver, which is also updated by this change.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Tejun Heo <tj@kernel.org>
-rw-r--r-- | Documentation/PCI/MSI-HOWTO.txt | 39 | ||||
-rw-r--r-- | drivers/ata/ahci.c | 56 | ||||
-rw-r--r-- | drivers/pci/msi.c | 25 | ||||
-rw-r--r-- | include/linux/pci.h | 7 |
4 files changed, 41 insertions, 86 deletions
diff --git a/Documentation/PCI/MSI-HOWTO.txt b/Documentation/PCI/MSI-HOWTO.txt index a8b41788dfde..aa4ad987510d 100644 --- a/Documentation/PCI/MSI-HOWTO.txt +++ b/Documentation/PCI/MSI-HOWTO.txt | |||
@@ -127,49 +127,22 @@ on the number of vectors that can be allocated; pci_enable_msi_block() | |||
127 | returns as soon as it finds any constraint that doesn't allow the | 127 | returns as soon as it finds any constraint that doesn't allow the |
128 | call to succeed. | 128 | call to succeed. |
129 | 129 | ||
130 | 4.2.3 pci_enable_msi_block_auto | 130 | 4.2.3 pci_disable_msi |
131 | |||
132 | int pci_enable_msi_block_auto(struct pci_dev *dev, int *count) | ||
133 | |||
134 | This variation on pci_enable_msi() call allows a device driver to request | ||
135 | the maximum possible number of MSIs. The MSI specification only allows | ||
136 | interrupts to be allocated in powers of two, up to a maximum of 2^5 (32). | ||
137 | |||
138 | If this function returns a positive number, it indicates that it has | ||
139 | succeeded and the returned value is the number of allocated interrupts. In | ||
140 | this case, the function enables MSI on this device and updates dev->irq to | ||
141 | be the lowest of the new interrupts assigned to it. The other interrupts | ||
142 | assigned to the device are in the range dev->irq to dev->irq + returned | ||
143 | value - 1. | ||
144 | |||
145 | If this function returns a negative number, it indicates an error and | ||
146 | the driver should not attempt to request any more MSI interrupts for | ||
147 | this device. | ||
148 | |||
149 | If the device driver needs to know the number of interrupts the device | ||
150 | supports it can pass the pointer count where that number is stored. The | ||
151 | device driver must decide what action to take if pci_enable_msi_block_auto() | ||
152 | succeeds, but returns a value less than the number of interrupts supported. | ||
153 | If the device driver does not need to know the number of interrupts | ||
154 | supported, it can set the pointer count to NULL. | ||
155 | |||
156 | 4.2.4 pci_disable_msi | ||
157 | 131 | ||
158 | void pci_disable_msi(struct pci_dev *dev) | 132 | void pci_disable_msi(struct pci_dev *dev) |
159 | 133 | ||
160 | This function should be used to undo the effect of pci_enable_msi() or | 134 | This function should be used to undo the effect of pci_enable_msi() or |
161 | pci_enable_msi_block() or pci_enable_msi_block_auto(). Calling it restores | 135 | pci_enable_msi_block(). Calling it restores dev->irq to the pin-based |
162 | dev->irq to the pin-based interrupt number and frees the previously | 136 | interrupt number and frees the previously allocated message signaled |
163 | allocated message signaled interrupt(s). The interrupt may subsequently be | 137 | interrupt(s). The interrupt may subsequently be assigned to another |
164 | assigned to another device, so drivers should not cache the value of | 138 | device, so drivers should not cache the value of dev->irq. |
165 | dev->irq. | ||
166 | 139 | ||
167 | Before calling this function, a device driver must always call free_irq() | 140 | Before calling this function, a device driver must always call free_irq() |
168 | on any interrupt for which it previously called request_irq(). | 141 | on any interrupt for which it previously called request_irq(). |
169 | Failure to do so results in a BUG_ON(), leaving the device with | 142 | Failure to do so results in a BUG_ON(), leaving the device with |
170 | MSI enabled and thus leaking its vector. | 143 | MSI enabled and thus leaking its vector. |
171 | 144 | ||
172 | 4.2.5 pci_msi_vec_count | 145 | 4.2.4 pci_msi_vec_count |
173 | 146 | ||
174 | int pci_msi_vec_count(struct pci_dev *dev) | 147 | int pci_msi_vec_count(struct pci_dev *dev) |
175 | 148 | ||
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index e2903d03180e..8516f4d47893 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -1095,26 +1095,40 @@ static inline void ahci_gtf_filter_workaround(struct ata_host *host) | |||
1095 | {} | 1095 | {} |
1096 | #endif | 1096 | #endif |
1097 | 1097 | ||
1098 | int ahci_init_interrupts(struct pci_dev *pdev, struct ahci_host_priv *hpriv) | 1098 | int ahci_init_interrupts(struct pci_dev *pdev, unsigned int n_ports, |
1099 | struct ahci_host_priv *hpriv) | ||
1099 | { | 1100 | { |
1100 | int rc; | 1101 | int rc, nvec; |
1101 | unsigned int maxvec; | ||
1102 | 1102 | ||
1103 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) { | 1103 | if (hpriv->flags & AHCI_HFLAG_NO_MSI) |
1104 | rc = pci_enable_msi_block_auto(pdev, &maxvec); | 1104 | goto intx; |
1105 | if (rc > 0) { | 1105 | |
1106 | if ((rc == maxvec) || (rc == 1)) | 1106 | rc = pci_msi_vec_count(pdev); |
1107 | return rc; | 1107 | if (rc < 0) |
1108 | /* | 1108 | goto intx; |
1109 | * Assume that advantage of multipe MSIs is negated, | 1109 | |
1110 | * so fallback to single MSI mode to save resources | 1110 | /* |
1111 | */ | 1111 | * If number of MSIs is less than number of ports then Sharing Last |
1112 | pci_disable_msi(pdev); | 1112 | * Message mode could be enforced. In this case assume that advantage |
1113 | if (!pci_enable_msi(pdev)) | 1113 | * of multipe MSIs is negated and use single MSI mode instead. |
1114 | return 1; | 1114 | */ |
1115 | } | 1115 | if (rc < n_ports) |
1116 | } | 1116 | goto single_msi; |
1117 | |||
1118 | nvec = rc; | ||
1119 | rc = pci_enable_msi_block(pdev, nvec); | ||
1120 | if (rc) | ||
1121 | goto intx; | ||
1117 | 1122 | ||
1123 | return nvec; | ||
1124 | |||
1125 | single_msi: | ||
1126 | rc = pci_enable_msi(pdev); | ||
1127 | if (rc) | ||
1128 | goto intx; | ||
1129 | return 1; | ||
1130 | |||
1131 | intx: | ||
1118 | pci_intx(pdev, 1); | 1132 | pci_intx(pdev, 1); |
1119 | return 0; | 1133 | return 0; |
1120 | } | 1134 | } |
@@ -1281,10 +1295,6 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1281 | 1295 | ||
1282 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; | 1296 | hpriv->mmio = pcim_iomap_table(pdev)[ahci_pci_bar]; |
1283 | 1297 | ||
1284 | n_msis = ahci_init_interrupts(pdev, hpriv); | ||
1285 | if (n_msis > 1) | ||
1286 | hpriv->flags |= AHCI_HFLAG_MULTI_MSI; | ||
1287 | |||
1288 | /* save initial config */ | 1298 | /* save initial config */ |
1289 | ahci_pci_save_initial_config(pdev, hpriv); | 1299 | ahci_pci_save_initial_config(pdev, hpriv); |
1290 | 1300 | ||
@@ -1339,6 +1349,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
1339 | */ | 1349 | */ |
1340 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); | 1350 | n_ports = max(ahci_nr_ports(hpriv->cap), fls(hpriv->port_map)); |
1341 | 1351 | ||
1352 | n_msis = ahci_init_interrupts(pdev, n_ports, hpriv); | ||
1353 | if (n_msis > 1) | ||
1354 | hpriv->flags |= AHCI_HFLAG_MULTI_MSI; | ||
1355 | |||
1342 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | 1356 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
1343 | if (!host) | 1357 | if (!host) |
1344 | return -ENOMEM; | 1358 | return -ENOMEM; |
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index ba6d0a9bdd39..76507ab13beb 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c | |||
@@ -911,31 +911,6 @@ int pci_enable_msi_block(struct pci_dev *dev, int nvec) | |||
911 | } | 911 | } |
912 | EXPORT_SYMBOL(pci_enable_msi_block); | 912 | EXPORT_SYMBOL(pci_enable_msi_block); |
913 | 913 | ||
914 | int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec) | ||
915 | { | ||
916 | int ret, nvec; | ||
917 | |||
918 | if (dev->current_state != PCI_D0) | ||
919 | return -EINVAL; | ||
920 | |||
921 | ret = pci_msi_vec_count(dev); | ||
922 | if (ret < 0) | ||
923 | return ret; | ||
924 | |||
925 | if (maxvec) | ||
926 | *maxvec = ret; | ||
927 | |||
928 | do { | ||
929 | nvec = ret; | ||
930 | ret = pci_enable_msi_block(dev, nvec); | ||
931 | } while (ret > 0); | ||
932 | |||
933 | if (ret < 0) | ||
934 | return ret; | ||
935 | return nvec; | ||
936 | } | ||
937 | EXPORT_SYMBOL(pci_enable_msi_block_auto); | ||
938 | |||
939 | void pci_msi_shutdown(struct pci_dev *dev) | 914 | void pci_msi_shutdown(struct pci_dev *dev) |
940 | { | 915 | { |
941 | struct msi_desc *desc; | 916 | struct msi_desc *desc; |
diff --git a/include/linux/pci.h b/include/linux/pci.h index 6691de093f1c..86dcf006adcc 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h | |||
@@ -1164,12 +1164,6 @@ static inline int pci_enable_msi_block(struct pci_dev *dev, int nvec) | |||
1164 | return -ENOSYS; | 1164 | return -ENOSYS; |
1165 | } | 1165 | } |
1166 | 1166 | ||
1167 | static inline int | ||
1168 | pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec) | ||
1169 | { | ||
1170 | return -ENOSYS; | ||
1171 | } | ||
1172 | |||
1173 | static inline void pci_msi_shutdown(struct pci_dev *dev) | 1167 | static inline void pci_msi_shutdown(struct pci_dev *dev) |
1174 | { } | 1168 | { } |
1175 | static inline void pci_disable_msi(struct pci_dev *dev) | 1169 | static inline void pci_disable_msi(struct pci_dev *dev) |
@@ -1202,7 +1196,6 @@ static inline int pci_msi_enabled(void) | |||
1202 | #else | 1196 | #else |
1203 | int pci_msi_vec_count(struct pci_dev *dev); | 1197 | int pci_msi_vec_count(struct pci_dev *dev); |
1204 | int pci_enable_msi_block(struct pci_dev *dev, int nvec); | 1198 | int pci_enable_msi_block(struct pci_dev *dev, int nvec); |
1205 | int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec); | ||
1206 | void pci_msi_shutdown(struct pci_dev *dev); | 1199 | void pci_msi_shutdown(struct pci_dev *dev); |
1207 | void pci_disable_msi(struct pci_dev *dev); | 1200 | void pci_disable_msi(struct pci_dev *dev); |
1208 | int pci_msix_table_size(struct pci_dev *dev); | 1201 | int pci_msix_table_size(struct pci_dev *dev); |