diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 19:16:39 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-12 19:16:39 -0400 |
commit | 07f5fef981bd89e92d67a69370c6487679cf66e4 (patch) | |
tree | 172a3f5862ae54d5a4b24a5e9173be8fad44f1c0 | |
parent | 96c57ade7e9ba2d1deba635a5989cc111f185dca (diff) | |
parent | f220baad08963a75c78c80cdc1c9e9492ca0eb2a (diff) |
Merge tag 'ntb-3.15' of git://github.com/jonmason/ntb
Pull PCIe non-transparent bridge fixes and features from Jon Mason:
"NTB driver bug fixes to address issues in list traversal, skb leak in
ntb_netdev, a typo, and a leak of msix entries in the error path.
Clean ups of the event handling logic, as well as a overall style
cleanup. Finally, the driver was converted to use the new
pci_enable_msix_range logic (and the refactoring to go along with it)"
* tag 'ntb-3.15' of git://github.com/jonmason/ntb:
ntb: Use pci_enable_msix_range() instead of pci_enable_msix()
ntb: Split ntb_setup_msix() into separate BWD/SNB routines
ntb: Use pci_msix_vec_count() to obtain number of MSI-Xs
NTB: Code Style Clean-up
NTB: client event cleanup
ntb: Fix leakage of ntb_device::msix_entries[] array
NTB: Fix typo in setting one translation register
ntb_netdev: Fix skb free issue in open
ntb_netdev: Fix list_for_each_entry exit issue
-rw-r--r-- | drivers/net/ntb_netdev.c | 27 | ||||
-rw-r--r-- | drivers/ntb/ntb_hw.c | 192 | ||||
-rw-r--r-- | drivers/ntb/ntb_hw.h | 8 | ||||
-rw-r--r-- | drivers/ntb/ntb_transport.c | 20 | ||||
-rw-r--r-- | include/linux/ntb.h | 19 |
5 files changed, 150 insertions, 116 deletions
diff --git a/drivers/net/ntb_netdev.c b/drivers/net/ntb_netdev.c index f3cdf64997d6..63aa9d9e34c5 100644 --- a/drivers/net/ntb_netdev.c +++ b/drivers/net/ntb_netdev.c | |||
@@ -78,11 +78,19 @@ static void ntb_netdev_event_handler(void *data, int status) | |||
78 | netdev_dbg(ndev, "Event %x, Link %x\n", status, | 78 | netdev_dbg(ndev, "Event %x, Link %x\n", status, |
79 | ntb_transport_link_query(dev->qp)); | 79 | ntb_transport_link_query(dev->qp)); |
80 | 80 | ||
81 | /* Currently, only link status event is supported */ | 81 | switch (status) { |
82 | if (status) | 82 | case NTB_LINK_DOWN: |
83 | netif_carrier_on(ndev); | ||
84 | else | ||
85 | netif_carrier_off(ndev); | 83 | netif_carrier_off(ndev); |
84 | break; | ||
85 | case NTB_LINK_UP: | ||
86 | if (!ntb_transport_link_query(dev->qp)) | ||
87 | return; | ||
88 | |||
89 | netif_carrier_on(ndev); | ||
90 | break; | ||
91 | default: | ||
92 | netdev_warn(ndev, "Unsupported event type %d\n", status); | ||
93 | } | ||
86 | } | 94 | } |
87 | 95 | ||
88 | static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data, | 96 | static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data, |
@@ -182,8 +190,10 @@ static int ntb_netdev_open(struct net_device *ndev) | |||
182 | 190 | ||
183 | rc = ntb_transport_rx_enqueue(dev->qp, skb, skb->data, | 191 | rc = ntb_transport_rx_enqueue(dev->qp, skb, skb->data, |
184 | ndev->mtu + ETH_HLEN); | 192 | ndev->mtu + ETH_HLEN); |
185 | if (rc == -EINVAL) | 193 | if (rc == -EINVAL) { |
194 | dev_kfree_skb(skb); | ||
186 | goto err; | 195 | goto err; |
196 | } | ||
187 | } | 197 | } |
188 | 198 | ||
189 | netif_carrier_off(ndev); | 199 | netif_carrier_off(ndev); |
@@ -367,12 +377,15 @@ static void ntb_netdev_remove(struct pci_dev *pdev) | |||
367 | { | 377 | { |
368 | struct net_device *ndev; | 378 | struct net_device *ndev; |
369 | struct ntb_netdev *dev; | 379 | struct ntb_netdev *dev; |
380 | bool found = false; | ||
370 | 381 | ||
371 | list_for_each_entry(dev, &dev_list, list) { | 382 | list_for_each_entry(dev, &dev_list, list) { |
372 | if (dev->pdev == pdev) | 383 | if (dev->pdev == pdev) { |
384 | found = true; | ||
373 | break; | 385 | break; |
386 | } | ||
374 | } | 387 | } |
375 | if (dev == NULL) | 388 | if (!found) |
376 | return; | 389 | return; |
377 | 390 | ||
378 | list_del(&dev->list); | 391 | list_del(&dev->list); |
diff --git a/drivers/ntb/ntb_hw.c b/drivers/ntb/ntb_hw.c index 170e8e60cdb7..372e08c4ffef 100644 --- a/drivers/ntb/ntb_hw.c +++ b/drivers/ntb/ntb_hw.c | |||
@@ -91,7 +91,7 @@ static struct dentry *debugfs_dir; | |||
91 | /* Translate memory window 0,1 to BAR 2,4 */ | 91 | /* Translate memory window 0,1 to BAR 2,4 */ |
92 | #define MW_TO_BAR(mw) (mw * NTB_MAX_NUM_MW + 2) | 92 | #define MW_TO_BAR(mw) (mw * NTB_MAX_NUM_MW + 2) |
93 | 93 | ||
94 | static DEFINE_PCI_DEVICE_TABLE(ntb_pci_tbl) = { | 94 | static const struct pci_device_id ntb_pci_tbl[] = { |
95 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)}, | 95 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_BWD)}, |
96 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_JSF)}, | 96 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_JSF)}, |
97 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_SNB)}, | 97 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_NTB_B2B_SNB)}, |
@@ -120,7 +120,8 @@ MODULE_DEVICE_TABLE(pci, ntb_pci_tbl); | |||
120 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. | 120 | * RETURNS: An appropriate -ERRNO error value on error, or zero for success. |
121 | */ | 121 | */ |
122 | int ntb_register_event_callback(struct ntb_device *ndev, | 122 | int ntb_register_event_callback(struct ntb_device *ndev, |
123 | void (*func)(void *handle, enum ntb_hw_event event)) | 123 | void (*func)(void *handle, |
124 | enum ntb_hw_event event)) | ||
124 | { | 125 | { |
125 | if (ndev->event_cb) | 126 | if (ndev->event_cb) |
126 | return -EINVAL; | 127 | return -EINVAL; |
@@ -715,9 +716,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
715 | SNB_PBAR4LMT_OFFSET); | 716 | SNB_PBAR4LMT_OFFSET); |
716 | /* HW errata on the Limit registers. They can only be | 717 | /* HW errata on the Limit registers. They can only be |
717 | * written when the base register is 4GB aligned and | 718 | * written when the base register is 4GB aligned and |
718 | * < 32bit. This should already be the case based on the | 719 | * < 32bit. This should already be the case based on |
719 | * driver defaults, but write the Limit registers first | 720 | * the driver defaults, but write the Limit registers |
720 | * just in case. | 721 | * first just in case. |
721 | */ | 722 | */ |
722 | } else { | 723 | } else { |
723 | ndev->limits.max_mw = SNB_MAX_MW; | 724 | ndev->limits.max_mw = SNB_MAX_MW; |
@@ -739,9 +740,9 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
739 | writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET); | 740 | writeq(0, ndev->reg_base + SNB_PBAR4LMT_OFFSET); |
740 | /* HW errata on the Limit registers. They can only be | 741 | /* HW errata on the Limit registers. They can only be |
741 | * written when the base register is 4GB aligned and | 742 | * written when the base register is 4GB aligned and |
742 | * < 32bit. This should already be the case based on the | 743 | * < 32bit. This should already be the case based on |
743 | * driver defaults, but write the Limit registers first | 744 | * the driver defaults, but write the Limit registers |
744 | * just in case. | 745 | * first just in case. |
745 | */ | 746 | */ |
746 | } | 747 | } |
747 | 748 | ||
@@ -785,7 +786,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
785 | /* B2B_XLAT_OFFSET is a 64bit register, but can | 786 | /* B2B_XLAT_OFFSET is a 64bit register, but can |
786 | * only take 32bit writes | 787 | * only take 32bit writes |
787 | */ | 788 | */ |
788 | writel(SNB_MBAR01_DSD_ADDR & 0xffffffff, | 789 | writel(SNB_MBAR01_USD_ADDR & 0xffffffff, |
789 | ndev->reg_base + SNB_B2B_XLAT_OFFSETL); | 790 | ndev->reg_base + SNB_B2B_XLAT_OFFSETL); |
790 | writel(SNB_MBAR01_USD_ADDR >> 32, | 791 | writel(SNB_MBAR01_USD_ADDR >> 32, |
791 | ndev->reg_base + SNB_B2B_XLAT_OFFSETU); | 792 | ndev->reg_base + SNB_B2B_XLAT_OFFSETU); |
@@ -803,7 +804,7 @@ static int ntb_xeon_setup(struct ntb_device *ndev) | |||
803 | ndev->conn_type = NTB_CONN_RP; | 804 | ndev->conn_type = NTB_CONN_RP; |
804 | 805 | ||
805 | if (xeon_errata_workaround) { | 806 | if (xeon_errata_workaround) { |
806 | dev_err(&ndev->pdev->dev, | 807 | dev_err(&ndev->pdev->dev, |
807 | "NTB-RP disabled due to hardware errata. To disregard this warning and potentially lock-up the system, add the parameter 'xeon_errata_workaround=0'.\n"); | 808 | "NTB-RP disabled due to hardware errata. To disregard this warning and potentially lock-up the system, add the parameter 'xeon_errata_workaround=0'.\n"); |
808 | return -EINVAL; | 809 | return -EINVAL; |
809 | } | 810 | } |
@@ -1079,111 +1080,131 @@ static irqreturn_t ntb_interrupt(int irq, void *dev) | |||
1079 | return IRQ_HANDLED; | 1080 | return IRQ_HANDLED; |
1080 | } | 1081 | } |
1081 | 1082 | ||
1082 | static int ntb_setup_msix(struct ntb_device *ndev) | 1083 | static int ntb_setup_snb_msix(struct ntb_device *ndev, int msix_entries) |
1083 | { | 1084 | { |
1084 | struct pci_dev *pdev = ndev->pdev; | 1085 | struct pci_dev *pdev = ndev->pdev; |
1085 | struct msix_entry *msix; | 1086 | struct msix_entry *msix; |
1086 | int msix_entries; | ||
1087 | int rc, i; | 1087 | int rc, i; |
1088 | u16 val; | ||
1089 | 1088 | ||
1090 | if (!pdev->msix_cap) { | 1089 | if (msix_entries < ndev->limits.msix_cnt) |
1091 | rc = -EIO; | 1090 | return -ENOSPC; |
1092 | goto err; | ||
1093 | } | ||
1094 | 1091 | ||
1095 | rc = pci_read_config_word(pdev, pdev->msix_cap + PCI_MSIX_FLAGS, &val); | 1092 | rc = pci_enable_msix_exact(pdev, ndev->msix_entries, msix_entries); |
1096 | if (rc) | 1093 | if (rc < 0) |
1097 | goto err; | 1094 | return rc; |
1098 | 1095 | ||
1099 | msix_entries = msix_table_size(val); | 1096 | for (i = 0; i < msix_entries; i++) { |
1100 | if (msix_entries > ndev->limits.msix_cnt) { | 1097 | msix = &ndev->msix_entries[i]; |
1101 | rc = -EINVAL; | 1098 | WARN_ON(!msix->vector); |
1102 | goto err; | 1099 | |
1100 | if (i == msix_entries - 1) { | ||
1101 | rc = request_irq(msix->vector, | ||
1102 | xeon_event_msix_irq, 0, | ||
1103 | "ntb-event-msix", ndev); | ||
1104 | if (rc) | ||
1105 | goto err; | ||
1106 | } else { | ||
1107 | rc = request_irq(msix->vector, | ||
1108 | xeon_callback_msix_irq, 0, | ||
1109 | "ntb-callback-msix", | ||
1110 | &ndev->db_cb[i]); | ||
1111 | if (rc) | ||
1112 | goto err; | ||
1113 | } | ||
1103 | } | 1114 | } |
1104 | 1115 | ||
1105 | ndev->msix_entries = kmalloc(sizeof(struct msix_entry) * msix_entries, | 1116 | ndev->num_msix = msix_entries; |
1106 | GFP_KERNEL); | 1117 | ndev->max_cbs = msix_entries - 1; |
1107 | if (!ndev->msix_entries) { | 1118 | |
1108 | rc = -ENOMEM; | 1119 | return 0; |
1109 | goto err; | 1120 | |
1121 | err: | ||
1122 | while (--i >= 0) { | ||
1123 | /* Code never reaches here for entry nr 'ndev->num_msix - 1' */ | ||
1124 | msix = &ndev->msix_entries[i]; | ||
1125 | free_irq(msix->vector, &ndev->db_cb[i]); | ||
1110 | } | 1126 | } |
1111 | 1127 | ||
1112 | for (i = 0; i < msix_entries; i++) | 1128 | pci_disable_msix(pdev); |
1113 | ndev->msix_entries[i].entry = i; | 1129 | ndev->num_msix = 0; |
1114 | 1130 | ||
1115 | rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); | 1131 | return rc; |
1116 | if (rc < 0) | 1132 | } |
1117 | goto err1; | ||
1118 | if (rc > 0) { | ||
1119 | /* On SNB, the link interrupt is always tied to 4th vector. If | ||
1120 | * we can't get all 4, then we can't use MSI-X. | ||
1121 | */ | ||
1122 | if (ndev->hw_type != BWD_HW) { | ||
1123 | rc = -EIO; | ||
1124 | goto err1; | ||
1125 | } | ||
1126 | 1133 | ||
1127 | dev_warn(&pdev->dev, | 1134 | static int ntb_setup_bwd_msix(struct ntb_device *ndev, int msix_entries) |
1128 | "Only %d MSI-X vectors. Limiting the number of queues to that number.\n", | 1135 | { |
1129 | rc); | 1136 | struct pci_dev *pdev = ndev->pdev; |
1130 | msix_entries = rc; | 1137 | struct msix_entry *msix; |
1138 | int rc, i; | ||
1131 | 1139 | ||
1132 | rc = pci_enable_msix(pdev, ndev->msix_entries, msix_entries); | 1140 | msix_entries = pci_enable_msix_range(pdev, ndev->msix_entries, |
1133 | if (rc) | 1141 | 1, msix_entries); |
1134 | goto err1; | 1142 | if (msix_entries < 0) |
1135 | } | 1143 | return msix_entries; |
1136 | 1144 | ||
1137 | for (i = 0; i < msix_entries; i++) { | 1145 | for (i = 0; i < msix_entries; i++) { |
1138 | msix = &ndev->msix_entries[i]; | 1146 | msix = &ndev->msix_entries[i]; |
1139 | WARN_ON(!msix->vector); | 1147 | WARN_ON(!msix->vector); |
1140 | 1148 | ||
1141 | /* Use the last MSI-X vector for Link status */ | 1149 | rc = request_irq(msix->vector, bwd_callback_msix_irq, 0, |
1142 | if (ndev->hw_type == BWD_HW) { | 1150 | "ntb-callback-msix", &ndev->db_cb[i]); |
1143 | rc = request_irq(msix->vector, bwd_callback_msix_irq, 0, | 1151 | if (rc) |
1144 | "ntb-callback-msix", &ndev->db_cb[i]); | 1152 | goto err; |
1145 | if (rc) | ||
1146 | goto err2; | ||
1147 | } else { | ||
1148 | if (i == msix_entries - 1) { | ||
1149 | rc = request_irq(msix->vector, | ||
1150 | xeon_event_msix_irq, 0, | ||
1151 | "ntb-event-msix", ndev); | ||
1152 | if (rc) | ||
1153 | goto err2; | ||
1154 | } else { | ||
1155 | rc = request_irq(msix->vector, | ||
1156 | xeon_callback_msix_irq, 0, | ||
1157 | "ntb-callback-msix", | ||
1158 | &ndev->db_cb[i]); | ||
1159 | if (rc) | ||
1160 | goto err2; | ||
1161 | } | ||
1162 | } | ||
1163 | } | 1153 | } |
1164 | 1154 | ||
1165 | ndev->num_msix = msix_entries; | 1155 | ndev->num_msix = msix_entries; |
1156 | ndev->max_cbs = msix_entries; | ||
1157 | |||
1158 | return 0; | ||
1159 | |||
1160 | err: | ||
1161 | while (--i >= 0) | ||
1162 | free_irq(msix->vector, &ndev->db_cb[i]); | ||
1163 | |||
1164 | pci_disable_msix(pdev); | ||
1165 | ndev->num_msix = 0; | ||
1166 | |||
1167 | return rc; | ||
1168 | } | ||
1169 | |||
1170 | static int ntb_setup_msix(struct ntb_device *ndev) | ||
1171 | { | ||
1172 | struct pci_dev *pdev = ndev->pdev; | ||
1173 | int msix_entries; | ||
1174 | int rc, i; | ||
1175 | |||
1176 | msix_entries = pci_msix_vec_count(pdev); | ||
1177 | if (msix_entries < 0) { | ||
1178 | rc = msix_entries; | ||
1179 | goto err; | ||
1180 | } else if (msix_entries > ndev->limits.msix_cnt) { | ||
1181 | rc = -EINVAL; | ||
1182 | goto err; | ||
1183 | } | ||
1184 | |||
1185 | ndev->msix_entries = kmalloc(sizeof(struct msix_entry) * msix_entries, | ||
1186 | GFP_KERNEL); | ||
1187 | if (!ndev->msix_entries) { | ||
1188 | rc = -ENOMEM; | ||
1189 | goto err; | ||
1190 | } | ||
1191 | |||
1192 | for (i = 0; i < msix_entries; i++) | ||
1193 | ndev->msix_entries[i].entry = i; | ||
1194 | |||
1166 | if (ndev->hw_type == BWD_HW) | 1195 | if (ndev->hw_type == BWD_HW) |
1167 | ndev->max_cbs = msix_entries; | 1196 | rc = ntb_setup_bwd_msix(ndev, msix_entries); |
1168 | else | 1197 | else |
1169 | ndev->max_cbs = msix_entries - 1; | 1198 | rc = ntb_setup_snb_msix(ndev, msix_entries); |
1199 | if (rc) | ||
1200 | goto err1; | ||
1170 | 1201 | ||
1171 | return 0; | 1202 | return 0; |
1172 | 1203 | ||
1173 | err2: | ||
1174 | while (--i >= 0) { | ||
1175 | msix = &ndev->msix_entries[i]; | ||
1176 | if (ndev->hw_type != BWD_HW && i == ndev->num_msix - 1) | ||
1177 | free_irq(msix->vector, ndev); | ||
1178 | else | ||
1179 | free_irq(msix->vector, &ndev->db_cb[i]); | ||
1180 | } | ||
1181 | pci_disable_msix(pdev); | ||
1182 | err1: | 1204 | err1: |
1183 | kfree(ndev->msix_entries); | 1205 | kfree(ndev->msix_entries); |
1184 | dev_err(&pdev->dev, "Error allocating MSI-X interrupt\n"); | ||
1185 | err: | 1206 | err: |
1186 | ndev->num_msix = 0; | 1207 | dev_err(&pdev->dev, "Error allocating MSI-X interrupt\n"); |
1187 | return rc; | 1208 | return rc; |
1188 | } | 1209 | } |
1189 | 1210 | ||
@@ -1281,6 +1302,7 @@ static void ntb_free_interrupts(struct ntb_device *ndev) | |||
1281 | free_irq(msix->vector, &ndev->db_cb[i]); | 1302 | free_irq(msix->vector, &ndev->db_cb[i]); |
1282 | } | 1303 | } |
1283 | pci_disable_msix(pdev); | 1304 | pci_disable_msix(pdev); |
1305 | kfree(ndev->msix_entries); | ||
1284 | } else { | 1306 | } else { |
1285 | free_irq(pdev->irq, ndev); | 1307 | free_irq(pdev->irq, ndev); |
1286 | 1308 | ||
diff --git a/drivers/ntb/ntb_hw.h b/drivers/ntb/ntb_hw.h index bbdb7edca10c..465517b7393e 100644 --- a/drivers/ntb/ntb_hw.h +++ b/drivers/ntb/ntb_hw.h | |||
@@ -45,6 +45,7 @@ | |||
45 | * Contact Information: | 45 | * Contact Information: |
46 | * Jon Mason <jon.mason@intel.com> | 46 | * Jon Mason <jon.mason@intel.com> |
47 | */ | 47 | */ |
48 | #include <linux/ntb.h> | ||
48 | 49 | ||
49 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_JSF 0x3725 | 50 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_JSF 0x3725 |
50 | #define PCI_DEVICE_ID_INTEL_NTB_PS_JSF 0x3726 | 51 | #define PCI_DEVICE_ID_INTEL_NTB_PS_JSF 0x3726 |
@@ -60,8 +61,6 @@ | |||
60 | #define PCI_DEVICE_ID_INTEL_NTB_SS_HSX 0x2F0F | 61 | #define PCI_DEVICE_ID_INTEL_NTB_SS_HSX 0x2F0F |
61 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_BWD 0x0C4E | 62 | #define PCI_DEVICE_ID_INTEL_NTB_B2B_BWD 0x0C4E |
62 | 63 | ||
63 | #define msix_table_size(control) ((control & PCI_MSIX_FLAGS_QSIZE)+1) | ||
64 | |||
65 | #ifndef readq | 64 | #ifndef readq |
66 | static inline u64 readq(void __iomem *addr) | 65 | static inline u64 readq(void __iomem *addr) |
67 | { | 66 | { |
@@ -83,9 +82,6 @@ static inline void writeq(u64 val, void __iomem *addr) | |||
83 | #define NTB_BAR_MASK ((1 << NTB_BAR_MMIO) | (1 << NTB_BAR_23) |\ | 82 | #define NTB_BAR_MASK ((1 << NTB_BAR_MMIO) | (1 << NTB_BAR_23) |\ |
84 | (1 << NTB_BAR_45)) | 83 | (1 << NTB_BAR_45)) |
85 | 84 | ||
86 | #define NTB_LINK_DOWN 0 | ||
87 | #define NTB_LINK_UP 1 | ||
88 | |||
89 | #define NTB_HB_TIMEOUT msecs_to_jiffies(1000) | 85 | #define NTB_HB_TIMEOUT msecs_to_jiffies(1000) |
90 | 86 | ||
91 | #define NTB_MAX_NUM_MW 2 | 87 | #define NTB_MAX_NUM_MW 2 |
@@ -233,7 +229,7 @@ int ntb_register_db_callback(struct ntb_device *ndev, unsigned int idx, | |||
233 | int db_num)); | 229 | int db_num)); |
234 | void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx); | 230 | void ntb_unregister_db_callback(struct ntb_device *ndev, unsigned int idx); |
235 | int ntb_register_event_callback(struct ntb_device *ndev, | 231 | int ntb_register_event_callback(struct ntb_device *ndev, |
236 | void (*event_cb_func) (void *handle, | 232 | void (*event_cb_func)(void *handle, |
237 | enum ntb_hw_event event)); | 233 | enum ntb_hw_event event)); |
238 | void ntb_unregister_event_callback(struct ntb_device *ndev); | 234 | void ntb_unregister_event_callback(struct ntb_device *ndev); |
239 | int ntb_get_max_spads(struct ntb_device *ndev); | 235 | int ntb_get_max_spads(struct ntb_device *ndev); |
diff --git a/drivers/ntb/ntb_transport.c b/drivers/ntb/ntb_transport.c index 3217f394d45b..9dd63b822025 100644 --- a/drivers/ntb/ntb_transport.c +++ b/drivers/ntb/ntb_transport.c | |||
@@ -56,7 +56,6 @@ | |||
56 | #include <linux/pci.h> | 56 | #include <linux/pci.h> |
57 | #include <linux/slab.h> | 57 | #include <linux/slab.h> |
58 | #include <linux/types.h> | 58 | #include <linux/types.h> |
59 | #include <linux/ntb.h> | ||
60 | #include "ntb_hw.h" | 59 | #include "ntb_hw.h" |
61 | 60 | ||
62 | #define NTB_TRANSPORT_VERSION 3 | 61 | #define NTB_TRANSPORT_VERSION 3 |
@@ -107,8 +106,8 @@ struct ntb_transport_qp { | |||
107 | struct ntb_rx_info __iomem *rx_info; | 106 | struct ntb_rx_info __iomem *rx_info; |
108 | struct ntb_rx_info *remote_rx_info; | 107 | struct ntb_rx_info *remote_rx_info; |
109 | 108 | ||
110 | void (*tx_handler) (struct ntb_transport_qp *qp, void *qp_data, | 109 | void (*tx_handler)(struct ntb_transport_qp *qp, void *qp_data, |
111 | void *data, int len); | 110 | void *data, int len); |
112 | struct list_head tx_free_q; | 111 | struct list_head tx_free_q; |
113 | spinlock_t ntb_tx_free_q_lock; | 112 | spinlock_t ntb_tx_free_q_lock; |
114 | void __iomem *tx_mw; | 113 | void __iomem *tx_mw; |
@@ -117,8 +116,8 @@ struct ntb_transport_qp { | |||
117 | unsigned int tx_max_entry; | 116 | unsigned int tx_max_entry; |
118 | unsigned int tx_max_frame; | 117 | unsigned int tx_max_frame; |
119 | 118 | ||
120 | void (*rx_handler) (struct ntb_transport_qp *qp, void *qp_data, | 119 | void (*rx_handler)(struct ntb_transport_qp *qp, void *qp_data, |
121 | void *data, int len); | 120 | void *data, int len); |
122 | struct list_head rx_pend_q; | 121 | struct list_head rx_pend_q; |
123 | struct list_head rx_free_q; | 122 | struct list_head rx_free_q; |
124 | spinlock_t ntb_rx_pend_q_lock; | 123 | spinlock_t ntb_rx_pend_q_lock; |
@@ -129,7 +128,7 @@ struct ntb_transport_qp { | |||
129 | unsigned int rx_max_frame; | 128 | unsigned int rx_max_frame; |
130 | dma_cookie_t last_cookie; | 129 | dma_cookie_t last_cookie; |
131 | 130 | ||
132 | void (*event_handler) (void *data, int status); | 131 | void (*event_handler)(void *data, int status); |
133 | struct delayed_work link_work; | 132 | struct delayed_work link_work; |
134 | struct work_struct link_cleanup; | 133 | struct work_struct link_cleanup; |
135 | 134 | ||
@@ -480,7 +479,7 @@ static void ntb_list_add(spinlock_t *lock, struct list_head *entry, | |||
480 | } | 479 | } |
481 | 480 | ||
482 | static struct ntb_queue_entry *ntb_list_rm(spinlock_t *lock, | 481 | static struct ntb_queue_entry *ntb_list_rm(spinlock_t *lock, |
483 | struct list_head *list) | 482 | struct list_head *list) |
484 | { | 483 | { |
485 | struct ntb_queue_entry *entry; | 484 | struct ntb_queue_entry *entry; |
486 | unsigned long flags; | 485 | unsigned long flags; |
@@ -839,7 +838,7 @@ static void ntb_qp_link_work(struct work_struct *work) | |||
839 | } | 838 | } |
840 | 839 | ||
841 | static int ntb_transport_init_queue(struct ntb_transport *nt, | 840 | static int ntb_transport_init_queue(struct ntb_transport *nt, |
842 | unsigned int qp_num) | 841 | unsigned int qp_num) |
843 | { | 842 | { |
844 | struct ntb_transport_qp *qp; | 843 | struct ntb_transport_qp *qp; |
845 | unsigned int num_qps_mw, tx_size; | 844 | unsigned int num_qps_mw, tx_size; |
@@ -1055,7 +1054,7 @@ static void ntb_async_rx(struct ntb_queue_entry *entry, void *offset, | |||
1055 | if (!chan) | 1054 | if (!chan) |
1056 | goto err; | 1055 | goto err; |
1057 | 1056 | ||
1058 | if (len < copy_bytes) | 1057 | if (len < copy_bytes) |
1059 | goto err_wait; | 1058 | goto err_wait; |
1060 | 1059 | ||
1061 | device = chan->device; | 1060 | device = chan->device; |
@@ -1190,8 +1189,7 @@ out: | |||
1190 | return 0; | 1189 | return 0; |
1191 | 1190 | ||
1192 | err: | 1191 | err: |
1193 | ntb_list_add(&qp->ntb_rx_pend_q_lock, &entry->entry, | 1192 | ntb_list_add(&qp->ntb_rx_pend_q_lock, &entry->entry, &qp->rx_pend_q); |
1194 | &qp->rx_pend_q); | ||
1195 | /* Ensure that the data is fully copied out before clearing the flag */ | 1193 | /* Ensure that the data is fully copied out before clearing the flag */ |
1196 | wmb(); | 1194 | wmb(); |
1197 | hdr->flags = 0; | 1195 | hdr->flags = 0; |
diff --git a/include/linux/ntb.h b/include/linux/ntb.h index f6a15205853b..9ac1a62fc6f5 100644 --- a/include/linux/ntb.h +++ b/include/linux/ntb.h | |||
@@ -50,8 +50,13 @@ struct ntb_transport_qp; | |||
50 | 50 | ||
51 | struct ntb_client { | 51 | struct ntb_client { |
52 | struct device_driver driver; | 52 | struct device_driver driver; |
53 | int (*probe) (struct pci_dev *pdev); | 53 | int (*probe)(struct pci_dev *pdev); |
54 | void (*remove) (struct pci_dev *pdev); | 54 | void (*remove)(struct pci_dev *pdev); |
55 | }; | ||
56 | |||
57 | enum { | ||
58 | NTB_LINK_DOWN = 0, | ||
59 | NTB_LINK_UP, | ||
55 | }; | 60 | }; |
56 | 61 | ||
57 | int ntb_register_client(struct ntb_client *drvr); | 62 | int ntb_register_client(struct ntb_client *drvr); |
@@ -60,11 +65,11 @@ int ntb_register_client_dev(char *device_name); | |||
60 | void ntb_unregister_client_dev(char *device_name); | 65 | void ntb_unregister_client_dev(char *device_name); |
61 | 66 | ||
62 | struct ntb_queue_handlers { | 67 | struct ntb_queue_handlers { |
63 | void (*rx_handler) (struct ntb_transport_qp *qp, void *qp_data, | 68 | void (*rx_handler)(struct ntb_transport_qp *qp, void *qp_data, |
64 | void *data, int len); | 69 | void *data, int len); |
65 | void (*tx_handler) (struct ntb_transport_qp *qp, void *qp_data, | 70 | void (*tx_handler)(struct ntb_transport_qp *qp, void *qp_data, |
66 | void *data, int len); | 71 | void *data, int len); |
67 | void (*event_handler) (void *data, int status); | 72 | void (*event_handler)(void *data, int status); |
68 | }; | 73 | }; |
69 | 74 | ||
70 | unsigned char ntb_transport_qp_num(struct ntb_transport_qp *qp); | 75 | unsigned char ntb_transport_qp_num(struct ntb_transport_qp *qp); |