diff options
author | Alexander Gordeev <agordeev@redhat.com> | 2014-03-11 12:00:22 -0400 |
---|---|---|
committer | Jon Mason <jon.mason@intel.com> | 2014-04-07 13:59:19 -0400 |
commit | 53a788a765b5336bd5ac5935e6d962bcdd281802 (patch) | |
tree | 5246550b04b662a0dddb2d411b8f09525feb88c3 /drivers/ntb | |
parent | 77733513c481d741d997139a1cac5d0d10bf3639 (diff) |
ntb: Split ntb_setup_msix() into separate BWD/SNB routines
This is an cleanup effort to make ntb_setup_msix() more
readable - use ntb_setup_bwd_msix() to init MSI-Xs on
BWD hardware and ntb_setup_snb_msix() - on SNB hardware.
Function ntb_setup_snb_msix() also initializes MSI-Xs the
way it should has been done - looping pci_enable_msix()
until success or failure.
Signed-off-by: Alexander Gordeev <agordeev@redhat.com>
Signed-off-by: Jon Mason <jon.mason@intel.com>
Diffstat (limited to 'drivers/ntb')
-rw-r--r-- | drivers/ntb/ntb_hw.c | 167 |
1 files changed, 102 insertions, 65 deletions
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 06d605c6f362..22a7eb415d76 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c | |||
@@ -1080,10 +1080,106 @@ static irqreturn_t ntb_interrupt(int irq, void *dev) | |||
1080 | return IRQ_HANDLED; | 1080 | return IRQ_HANDLED; |
1081 | } | 1081 | } |
1082 | 1082 | ||
1083 | static int ntb_setup_msix(struct ntb_device *ndev) | 1083 | static int ntb_setup_snb_msix(struct ntb_device *ndev, int msix_entries) |
1084 | { | 1084 | { |
1085 | struct pci_dev *pdev = ndev->pdev; | 1085 | struct pci_dev *pdev = ndev->pdev; |
1086 | struct msix_entry *msix; | 1086 | struct msix_entry *msix; |
1087 | int rc, i; | ||
1088 | |||
1089 | if (msix_entries < ndev->limits.msix_cnt) | ||
1090 | return -ENOSPC; | ||
1091 | |||
1092 | rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); | ||
1093 | if (rc < 0) | ||
1094 | return rc; | ||
1095 | else if (rc > 0) | ||
1096 | return -ENOSPC; | ||
1097 | |||
1098 | for (i = 0; i < msix_entries; i++) { | ||
1099 | msix = &ndev->msix_entries[i]; | ||
1100 | WARN_ON(!msix->vector); | ||
1101 | |||
1102 | if (i == msix_entries - 1) { | ||
1103 | rc = request_irq(msix->vector, | ||
1104 | xeon_event_msix_irq, 0, | ||
1105 | "ntb-event-msix", ndev); | ||
1106 | if (rc) | ||
1107 | goto err; | ||
1108 | } else { | ||
1109 | rc = request_irq(msix->vector, | ||
1110 | xeon_callback_msix_irq, 0, | ||
1111 | "ntb-callback-msix", | ||
1112 | &ndev->db_cb[i]); | ||
1113 | if (rc) | ||
1114 | goto err; | ||
1115 | } | ||
1116 | } | ||
1117 | |||
1118 | ndev->num_msix = msix_entries; | ||
1119 | ndev->max_cbs = msix_entries - 1; | ||
1120 | |||
1121 | return 0; | ||
1122 | |||
1123 | err: | ||
1124 | while (--i >= 0) { | ||
1125 | /* Code never reaches here for entry nr 'ndev->num_msix - 1' */ | ||
1126 | msix = &ndev->msix_entries[i]; | ||
1127 | free_irq(msix->vector, &ndev->db_cb[i]); | ||
1128 | } | ||
1129 | |||
1130 | pci_disable_msix(pdev); | ||
1131 | ndev->num_msix = 0; | ||
1132 | |||
1133 | return rc; | ||
1134 | } | ||
1135 | |||
1136 | static int ntb_setup_bwd_msix(struct ntb_device *ndev, int msix_entries) | ||
1137 | { | ||
1138 | struct pci_dev *pdev = ndev->pdev; | ||
1139 | struct msix_entry *msix; | ||
1140 | int rc, i; | ||
1141 | |||
1142 | retry: | ||
1143 | rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); | ||
1144 | if (rc < 0) | ||
1145 | return rc; | ||
1146 | else if (rc > 0) { | ||
1147 | dev_warn(&pdev->dev, | ||
1148 | "Only %d MSI-X vectors. " | ||
1149 | "Limiting the number of queues to that number.\n", | ||
1150 | rc); | ||
1151 | msix_entries = rc; | ||
1152 | goto retry; | ||
1153 | } | ||
1154 | |||
1155 | for (i = 0; i < msix_entries; i++) { | ||
1156 | msix = &ndev->msix_entries[i]; | ||
1157 | WARN_ON(!msix->vector); | ||
1158 | |||
1159 | rc = request_irq(msix->vector, bwd_callback_msix_irq, 0, | ||
1160 | "ntb-callback-msix", &ndev->db_cb[i]); | ||
1161 | if (rc) | ||
1162 | goto err; | ||
1163 | } | ||
1164 | |||
1165 | ndev->num_msix = msix_entries; | ||
1166 | ndev->max_cbs = msix_entries; | ||
1167 | |||
1168 | return 0; | ||
1169 | |||
1170 | err: | ||
1171 | while (--i >= 0) | ||
1172 | free_irq(msix->vector, &ndev->db_cb[i]); | ||
1173 | |||
1174 | pci_disable_msix(pdev); | ||
1175 | ndev->num_msix = 0; | ||
1176 | |||
1177 | return rc; | ||
1178 | } | ||
1179 | |||
1180 | static int ntb_setup_msix(struct ntb_device *ndev) | ||
1181 | { | ||
1182 | struct pci_dev *pdev = ndev->pdev; | ||
1087 | int msix_entries; | 1183 | int msix_entries; |
1088 | int rc, i; | 1184 | int rc, i; |
1089 | 1185 | ||
@@ -1106,78 +1202,19 @@ static int ntb_setup_msix(struct ntb_device *ndev) | |||
1106 | for (i = 0; i < msix_entries; i++) | 1202 | for (i = 0; i < msix_entries; i++) |
1107 | ndev->msix_entries[i].entry = i; | 1203 | ndev->msix_entries[i].entry = i; |
1108 | 1204 | ||
1109 | rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); | ||
1110 | if (rc < 0) | ||
1111 | goto err1; | ||
1112 | if (rc > 0) { | ||
1113 | /* On SNB, the link interrupt is always tied to 4th vector. If | ||
1114 | * we can't get all 4, then we can't use MSI-X. | ||
1115 | */ | ||
1116 | if (ndev->hw_type != BWD_HW) { | ||
1117 | rc = -EIO; | ||
1118 | goto err1; | ||
1119 | } | ||
1120 | |||
1121 | dev_warn(&pdev->dev, | ||
1122 | "Only %d MSI-X vectors. Limiting the number of queues to that number.\n", | ||
1123 | rc); | ||
1124 | msix_entries = rc; | ||
1125 | |||
1126 | rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); | ||
1127 | if (rc) | ||
1128 | goto err1; | ||
1129 | } | ||
1130 | |||
1131 | for (i = 0; i < msix_entries; i++) { | ||
1132 | msix = &ndev->msix_entries[i]; | ||
1133 | WARN_ON(!msix->vector); | ||
1134 | |||
1135 | /* Use the last MSI-X vector for Link status */ | ||
1136 | if (ndev->hw_type == BWD_HW) { | ||
1137 | rc = request_irq(msix->vector, bwd_callback_msix_irq, 0, | ||
1138 | "ntb-callback-msix", &ndev->db_cb[i]); | ||
1139 | if (rc) | ||
1140 | goto err2; | ||
1141 | } else { | ||
1142 | if (i == msix_entries - 1) { | ||
1143 | rc = request_irq(msix->vector, | ||
1144 | xeon_event_msix_irq, 0, | ||
1145 | "ntb-event-msix", ndev); | ||
1146 | if (rc) | ||
1147 | goto err2; | ||
1148 | } else { | ||
1149 | rc = request_irq(msix->vector, | ||
1150 | xeon_callback_msix_irq, 0, | ||
1151 | "ntb-callback-msix", | ||
1152 | &ndev->db_cb[i]); | ||
1153 | if (rc) | ||
1154 | goto err2; | ||
1155 | } | ||
1156 | } | ||
1157 | } | ||
1158 | |||
1159 | ndev->num_msix = msix_entries; | ||
1160 | if (ndev->hw_type == BWD_HW) | 1205 | if (ndev->hw_type == BWD_HW) |
1161 | ndev->max_cbs = msix_entries; | 1206 | rc = ntb_setup_bwd_msix(ndev, msix_entries); |
1162 | else | 1207 | else |
1163 | ndev->max_cbs = msix_entries - 1; | 1208 | rc = ntb_setup_snb_msix(ndev, msix_entries); |
1209 | if (rc) | ||
1210 | goto err1; | ||
1164 | 1211 | ||
1165 | return 0; | 1212 | return 0; |
1166 | 1213 | ||
1167 | err2: | ||
1168 | while (--i >= 0) { | ||
1169 | msix = &ndev->msix_entries[i]; | ||
1170 | if (ndev->hw_type != BWD_HW && i == ndev->num_msix - 1) | ||
1171 | free_irq(msix->vector, ndev); | ||
1172 | else | ||
1173 | free_irq(msix->vector, &ndev->db_cb[i]); | ||
1174 | } | ||
1175 | pci_disable_msix(pdev); | ||
1176 | err1: | 1214 | err1: |
1177 | kfree(ndev->msix_entries); | 1215 | kfree(ndev->msix_entries); |
1178 | dev_err(&pdev->dev, "Error allocating MSI-X interrupt\n"); | ||
1179 | err: | 1216 | err: |
1180 | ndev->num_msix = 0; | 1217 | dev_err(&pdev->dev, "Error allocating MSI-X interrupt\n"); |
1181 | return rc; | 1218 | return rc; |
1182 | } | 1219 | } |
1183 | 1220 | ||