aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Gordeev <agordeev@redhat.com>2013-12-30 02:28:14 -0500
committerBjorn Helgaas <bhelgaas@google.com>2014-01-03 19:17:55 -0500
commit7b92b4f61ec49cb1a5813298f35258bd7ecd3667 (patch)
tree3ca281ebb26a2885ff9ff5fd4e1b15393b6f7c20
parentd1ac1d2622e8f0fd2a25127a8649d135b54db8a9 (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.txt39
-rw-r--r--drivers/ata/ahci.c56
-rw-r--r--drivers/pci/msi.c25
-rw-r--r--include/linux/pci.h7
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()
127returns as soon as it finds any constraint that doesn't allow the 127returns as soon as it finds any constraint that doesn't allow the
128call to succeed. 128call to succeed.
129 129
1304.2.3 pci_enable_msi_block_auto 1304.2.3 pci_disable_msi
131
132int pci_enable_msi_block_auto(struct pci_dev *dev, int *count)
133
134This variation on pci_enable_msi() call allows a device driver to request
135the maximum possible number of MSIs. The MSI specification only allows
136interrupts to be allocated in powers of two, up to a maximum of 2^5 (32).
137
138If this function returns a positive number, it indicates that it has
139succeeded and the returned value is the number of allocated interrupts. In
140this case, the function enables MSI on this device and updates dev->irq to
141be the lowest of the new interrupts assigned to it. The other interrupts
142assigned to the device are in the range dev->irq to dev->irq + returned
143value - 1.
144
145If this function returns a negative number, it indicates an error and
146the driver should not attempt to request any more MSI interrupts for
147this device.
148
149If the device driver needs to know the number of interrupts the device
150supports it can pass the pointer count where that number is stored. The
151device driver must decide what action to take if pci_enable_msi_block_auto()
152succeeds, but returns a value less than the number of interrupts supported.
153If the device driver does not need to know the number of interrupts
154supported, it can set the pointer count to NULL.
155
1564.2.4 pci_disable_msi
157 131
158void pci_disable_msi(struct pci_dev *dev) 132void pci_disable_msi(struct pci_dev *dev)
159 133
160This function should be used to undo the effect of pci_enable_msi() or 134This function should be used to undo the effect of pci_enable_msi() or
161pci_enable_msi_block() or pci_enable_msi_block_auto(). Calling it restores 135pci_enable_msi_block(). Calling it restores dev->irq to the pin-based
162dev->irq to the pin-based interrupt number and frees the previously 136interrupt number and frees the previously allocated message signaled
163allocated message signaled interrupt(s). The interrupt may subsequently be 137interrupt(s). The interrupt may subsequently be assigned to another
164assigned to another device, so drivers should not cache the value of 138device, so drivers should not cache the value of dev->irq.
165dev->irq.
166 139
167Before calling this function, a device driver must always call free_irq() 140Before calling this function, a device driver must always call free_irq()
168on any interrupt for which it previously called request_irq(). 141on any interrupt for which it previously called request_irq().
169Failure to do so results in a BUG_ON(), leaving the device with 142Failure to do so results in a BUG_ON(), leaving the device with
170MSI enabled and thus leaking its vector. 143MSI enabled and thus leaking its vector.
171 144
1724.2.5 pci_msi_vec_count 1454.2.4 pci_msi_vec_count
173 146
174int pci_msi_vec_count(struct pci_dev *dev) 147int 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
1098int ahci_init_interrupts(struct pci_dev *pdev, struct ahci_host_priv *hpriv) 1098int 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
1125single_msi:
1126 rc = pci_enable_msi(pdev);
1127 if (rc)
1128 goto intx;
1129 return 1;
1130
1131intx:
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}
912EXPORT_SYMBOL(pci_enable_msi_block); 912EXPORT_SYMBOL(pci_enable_msi_block);
913 913
914int 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}
937EXPORT_SYMBOL(pci_enable_msi_block_auto);
938
939void pci_msi_shutdown(struct pci_dev *dev) 914void 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
1167static inline int
1168pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec)
1169{
1170 return -ENOSYS;
1171}
1172
1173static inline void pci_msi_shutdown(struct pci_dev *dev) 1167static inline void pci_msi_shutdown(struct pci_dev *dev)
1174{ } 1168{ }
1175static inline void pci_disable_msi(struct pci_dev *dev) 1169static inline void pci_disable_msi(struct pci_dev *dev)
@@ -1202,7 +1196,6 @@ static inline int pci_msi_enabled(void)
1202#else 1196#else
1203int pci_msi_vec_count(struct pci_dev *dev); 1197int pci_msi_vec_count(struct pci_dev *dev);
1204int pci_enable_msi_block(struct pci_dev *dev, int nvec); 1198int pci_enable_msi_block(struct pci_dev *dev, int nvec);
1205int pci_enable_msi_block_auto(struct pci_dev *dev, int *maxvec);
1206void pci_msi_shutdown(struct pci_dev *dev); 1199void pci_msi_shutdown(struct pci_dev *dev);
1207void pci_disable_msi(struct pci_dev *dev); 1200void pci_disable_msi(struct pci_dev *dev);
1208int pci_msix_table_size(struct pci_dev *dev); 1201int pci_msix_table_size(struct pci_dev *dev);