diff options
Diffstat (limited to 'drivers/infiniband/hw/mthca')
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_av.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_catas.c | 62 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cmd.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_cq.c | 10 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_dev.h | 12 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_mad.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_main.c | 88 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_provider.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_qp.c | 20 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_srq.c | 2 | ||||
-rw-r--r-- | drivers/infiniband/hw/mthca/mthca_uar.c | 2 |
11 files changed, 161 insertions, 43 deletions
diff --git a/drivers/infiniband/hw/mthca/mthca_av.c b/drivers/infiniband/hw/mthca/mthca_av.c index e215041b2db9..69599455aca2 100644 --- a/drivers/infiniband/hw/mthca/mthca_av.c +++ b/drivers/infiniband/hw/mthca/mthca_av.c | |||
@@ -90,7 +90,7 @@ static enum ib_rate tavor_rate_to_ib(u8 mthca_rate, u8 port_rate) | |||
90 | case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS; | 90 | case MTHCA_RATE_TAVOR_1X: return IB_RATE_2_5_GBPS; |
91 | case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS; | 91 | case MTHCA_RATE_TAVOR_1X_DDR: return IB_RATE_5_GBPS; |
92 | case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS; | 92 | case MTHCA_RATE_TAVOR_4X: return IB_RATE_10_GBPS; |
93 | default: return port_rate; | 93 | default: return mult_to_ib_rate(port_rate); |
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
diff --git a/drivers/infiniband/hw/mthca/mthca_catas.c b/drivers/infiniband/hw/mthca/mthca_catas.c index c3bec7490f52..cd044ea2dfa4 100644 --- a/drivers/infiniband/hw/mthca/mthca_catas.c +++ b/drivers/infiniband/hw/mthca/mthca_catas.c | |||
@@ -34,6 +34,7 @@ | |||
34 | 34 | ||
35 | #include <linux/jiffies.h> | 35 | #include <linux/jiffies.h> |
36 | #include <linux/timer.h> | 36 | #include <linux/timer.h> |
37 | #include <linux/workqueue.h> | ||
37 | 38 | ||
38 | #include "mthca_dev.h" | 39 | #include "mthca_dev.h" |
39 | 40 | ||
@@ -48,9 +49,41 @@ enum { | |||
48 | 49 | ||
49 | static DEFINE_SPINLOCK(catas_lock); | 50 | static DEFINE_SPINLOCK(catas_lock); |
50 | 51 | ||
52 | static LIST_HEAD(catas_list); | ||
53 | static struct workqueue_struct *catas_wq; | ||
54 | static struct work_struct catas_work; | ||
55 | |||
56 | static int catas_reset_disable; | ||
57 | module_param_named(catas_reset_disable, catas_reset_disable, int, 0644); | ||
58 | MODULE_PARM_DESC(catas_reset_disable, "disable reset on catastrophic event if nonzero"); | ||
59 | |||
60 | static void catas_reset(void *work_ptr) | ||
61 | { | ||
62 | struct mthca_dev *dev, *tmpdev; | ||
63 | LIST_HEAD(tlist); | ||
64 | int ret; | ||
65 | |||
66 | mutex_lock(&mthca_device_mutex); | ||
67 | |||
68 | spin_lock_irq(&catas_lock); | ||
69 | list_splice_init(&catas_list, &tlist); | ||
70 | spin_unlock_irq(&catas_lock); | ||
71 | |||
72 | list_for_each_entry_safe(dev, tmpdev, &tlist, catas_err.list) { | ||
73 | ret = __mthca_restart_one(dev->pdev); | ||
74 | if (ret) | ||
75 | mthca_err(dev, "Reset failed (%d)\n", ret); | ||
76 | else | ||
77 | mthca_dbg(dev, "Reset succeeded\n"); | ||
78 | } | ||
79 | |||
80 | mutex_unlock(&mthca_device_mutex); | ||
81 | } | ||
82 | |||
51 | static void handle_catas(struct mthca_dev *dev) | 83 | static void handle_catas(struct mthca_dev *dev) |
52 | { | 84 | { |
53 | struct ib_event event; | 85 | struct ib_event event; |
86 | unsigned long flags; | ||
54 | const char *type; | 87 | const char *type; |
55 | int i; | 88 | int i; |
56 | 89 | ||
@@ -82,6 +115,14 @@ static void handle_catas(struct mthca_dev *dev) | |||
82 | for (i = 0; i < dev->catas_err.size; ++i) | 115 | for (i = 0; i < dev->catas_err.size; ++i) |
83 | mthca_err(dev, " buf[%02x]: %08x\n", | 116 | mthca_err(dev, " buf[%02x]: %08x\n", |
84 | i, swab32(readl(dev->catas_err.map + i))); | 117 | i, swab32(readl(dev->catas_err.map + i))); |
118 | |||
119 | if (catas_reset_disable) | ||
120 | return; | ||
121 | |||
122 | spin_lock_irqsave(&catas_lock, flags); | ||
123 | list_add(&dev->catas_err.list, &catas_list); | ||
124 | queue_work(catas_wq, &catas_work); | ||
125 | spin_unlock_irqrestore(&catas_lock, flags); | ||
85 | } | 126 | } |
86 | 127 | ||
87 | static void poll_catas(unsigned long dev_ptr) | 128 | static void poll_catas(unsigned long dev_ptr) |
@@ -135,6 +176,7 @@ void mthca_start_catas_poll(struct mthca_dev *dev) | |||
135 | dev->catas_err.timer.data = (unsigned long) dev; | 176 | dev->catas_err.timer.data = (unsigned long) dev; |
136 | dev->catas_err.timer.function = poll_catas; | 177 | dev->catas_err.timer.function = poll_catas; |
137 | dev->catas_err.timer.expires = jiffies + MTHCA_CATAS_POLL_INTERVAL; | 178 | dev->catas_err.timer.expires = jiffies + MTHCA_CATAS_POLL_INTERVAL; |
179 | INIT_LIST_HEAD(&dev->catas_err.list); | ||
138 | add_timer(&dev->catas_err.timer); | 180 | add_timer(&dev->catas_err.timer); |
139 | } | 181 | } |
140 | 182 | ||
@@ -153,4 +195,24 @@ void mthca_stop_catas_poll(struct mthca_dev *dev) | |||
153 | dev->catas_err.addr), | 195 | dev->catas_err.addr), |
154 | dev->catas_err.size * 4); | 196 | dev->catas_err.size * 4); |
155 | } | 197 | } |
198 | |||
199 | spin_lock_irq(&catas_lock); | ||
200 | list_del(&dev->catas_err.list); | ||
201 | spin_unlock_irq(&catas_lock); | ||
202 | } | ||
203 | |||
204 | int __init mthca_catas_init(void) | ||
205 | { | ||
206 | INIT_WORK(&catas_work, catas_reset, NULL); | ||
207 | |||
208 | catas_wq = create_singlethread_workqueue("mthca_catas"); | ||
209 | if (!catas_wq) | ||
210 | return -ENOMEM; | ||
211 | |||
212 | return 0; | ||
213 | } | ||
214 | |||
215 | void mthca_catas_cleanup(void) | ||
216 | { | ||
217 | destroy_workqueue(catas_wq); | ||
156 | } | 218 | } |
diff --git a/drivers/infiniband/hw/mthca/mthca_cmd.c b/drivers/infiniband/hw/mthca/mthca_cmd.c index deabc14b4ea4..99a94d710935 100644 --- a/drivers/infiniband/hw/mthca/mthca_cmd.c +++ b/drivers/infiniband/hw/mthca/mthca_cmd.c | |||
@@ -34,7 +34,7 @@ | |||
34 | * $Id: mthca_cmd.c 1349 2004-12-16 21:09:43Z roland $ | 34 | * $Id: mthca_cmd.c 1349 2004-12-16 21:09:43Z roland $ |
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include <linux/sched.h> | 37 | #include <linux/completion.h> |
38 | #include <linux/pci.h> | 38 | #include <linux/pci.h> |
39 | #include <linux/errno.h> | 39 | #include <linux/errno.h> |
40 | #include <asm/io.h> | 40 | #include <asm/io.h> |
diff --git a/drivers/infiniband/hw/mthca/mthca_cq.c b/drivers/infiniband/hw/mthca/mthca_cq.c index 3e27a084257e..e393681ba7d4 100644 --- a/drivers/infiniband/hw/mthca/mthca_cq.c +++ b/drivers/infiniband/hw/mthca/mthca_cq.c | |||
@@ -544,11 +544,11 @@ static inline int mthca_poll_one(struct mthca_dev *dev, | |||
544 | wq = &(*cur_qp)->rq; | 544 | wq = &(*cur_qp)->rq; |
545 | wqe = be32_to_cpu(cqe->wqe); | 545 | wqe = be32_to_cpu(cqe->wqe); |
546 | wqe_index = wqe >> wq->wqe_shift; | 546 | wqe_index = wqe >> wq->wqe_shift; |
547 | /* | 547 | /* |
548 | * WQE addr == base - 1 might be reported in receive completion | 548 | * WQE addr == base - 1 might be reported in receive completion |
549 | * with error instead of (rq size - 1) by Sinai FW 1.0.800 and | 549 | * with error instead of (rq size - 1) by Sinai FW 1.0.800 and |
550 | * Arbel FW 5.1.400. This bug should be fixed in later FW revs. | 550 | * Arbel FW 5.1.400. This bug should be fixed in later FW revs. |
551 | */ | 551 | */ |
552 | if (unlikely(wqe_index < 0)) | 552 | if (unlikely(wqe_index < 0)) |
553 | wqe_index = wq->max - 1; | 553 | wqe_index = wq->max - 1; |
554 | entry->wr_id = (*cur_qp)->wrid[wqe_index]; | 554 | entry->wr_id = (*cur_qp)->wrid[wqe_index]; |
diff --git a/drivers/infiniband/hw/mthca/mthca_dev.h b/drivers/infiniband/hw/mthca/mthca_dev.h index f8160b8de090..fe5cecf70fed 100644 --- a/drivers/infiniband/hw/mthca/mthca_dev.h +++ b/drivers/infiniband/hw/mthca/mthca_dev.h | |||
@@ -45,6 +45,7 @@ | |||
45 | #include <linux/dma-mapping.h> | 45 | #include <linux/dma-mapping.h> |
46 | #include <linux/timer.h> | 46 | #include <linux/timer.h> |
47 | #include <linux/mutex.h> | 47 | #include <linux/mutex.h> |
48 | #include <linux/list.h> | ||
48 | 49 | ||
49 | #include <asm/semaphore.h> | 50 | #include <asm/semaphore.h> |
50 | 51 | ||
@@ -283,8 +284,11 @@ struct mthca_catas_err { | |||
283 | unsigned long stop; | 284 | unsigned long stop; |
284 | u32 size; | 285 | u32 size; |
285 | struct timer_list timer; | 286 | struct timer_list timer; |
287 | struct list_head list; | ||
286 | }; | 288 | }; |
287 | 289 | ||
290 | extern struct mutex mthca_device_mutex; | ||
291 | |||
288 | struct mthca_dev { | 292 | struct mthca_dev { |
289 | struct ib_device ib_dev; | 293 | struct ib_device ib_dev; |
290 | struct pci_dev *pdev; | 294 | struct pci_dev *pdev; |
@@ -450,6 +454,9 @@ void mthca_unregister_device(struct mthca_dev *dev); | |||
450 | 454 | ||
451 | void mthca_start_catas_poll(struct mthca_dev *dev); | 455 | void mthca_start_catas_poll(struct mthca_dev *dev); |
452 | void mthca_stop_catas_poll(struct mthca_dev *dev); | 456 | void mthca_stop_catas_poll(struct mthca_dev *dev); |
457 | int __mthca_restart_one(struct pci_dev *pdev); | ||
458 | int mthca_catas_init(void); | ||
459 | void mthca_catas_cleanup(void); | ||
453 | 460 | ||
454 | int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar); | 461 | int mthca_uar_alloc(struct mthca_dev *dev, struct mthca_uar *uar); |
455 | void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar); | 462 | void mthca_uar_free(struct mthca_dev *dev, struct mthca_uar *uar); |
@@ -506,7 +513,7 @@ int mthca_alloc_srq(struct mthca_dev *dev, struct mthca_pd *pd, | |||
506 | struct ib_srq_attr *attr, struct mthca_srq *srq); | 513 | struct ib_srq_attr *attr, struct mthca_srq *srq); |
507 | void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq); | 514 | void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq); |
508 | int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | 515 | int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, |
509 | enum ib_srq_attr_mask attr_mask); | 516 | enum ib_srq_attr_mask attr_mask, struct ib_udata *udata); |
510 | int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr); | 517 | int mthca_query_srq(struct ib_srq *srq, struct ib_srq_attr *srq_attr); |
511 | int mthca_max_srq_sge(struct mthca_dev *dev); | 518 | int mthca_max_srq_sge(struct mthca_dev *dev); |
512 | void mthca_srq_event(struct mthca_dev *dev, u32 srqn, | 519 | void mthca_srq_event(struct mthca_dev *dev, u32 srqn, |
@@ -521,7 +528,8 @@ void mthca_qp_event(struct mthca_dev *dev, u32 qpn, | |||
521 | enum ib_event_type event_type); | 528 | enum ib_event_type event_type); |
522 | int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask, | 529 | int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_mask, |
523 | struct ib_qp_init_attr *qp_init_attr); | 530 | struct ib_qp_init_attr *qp_init_attr); |
524 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask); | 531 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, |
532 | struct ib_udata *udata); | ||
525 | int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, | 533 | int mthca_tavor_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr, |
526 | struct ib_send_wr **bad_wr); | 534 | struct ib_send_wr **bad_wr); |
527 | int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, | 535 | int mthca_tavor_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr, |
diff --git a/drivers/infiniband/hw/mthca/mthca_mad.c b/drivers/infiniband/hw/mthca/mthca_mad.c index d9bc030bcccc..45e106f14807 100644 --- a/drivers/infiniband/hw/mthca/mthca_mad.c +++ b/drivers/infiniband/hw/mthca/mthca_mad.c | |||
@@ -119,7 +119,7 @@ static void smp_snoop(struct ib_device *ibdev, | |||
119 | 119 | ||
120 | mthca_update_rate(to_mdev(ibdev), port_num); | 120 | mthca_update_rate(to_mdev(ibdev), port_num); |
121 | update_sm_ah(to_mdev(ibdev), port_num, | 121 | update_sm_ah(to_mdev(ibdev), port_num, |
122 | be16_to_cpu(pinfo->lid), | 122 | be16_to_cpu(pinfo->sm_lid), |
123 | pinfo->neighbormtu_mastersmsl & 0xf); | 123 | pinfo->neighbormtu_mastersmsl & 0xf); |
124 | 124 | ||
125 | event.device = ibdev; | 125 | event.device = ibdev; |
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c index 7b82c1907f04..47ea02148368 100644 --- a/drivers/infiniband/hw/mthca/mthca_main.c +++ b/drivers/infiniband/hw/mthca/mthca_main.c | |||
@@ -80,6 +80,8 @@ static int tune_pci = 0; | |||
80 | module_param(tune_pci, int, 0444); | 80 | module_param(tune_pci, int, 0444); |
81 | MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero"); | 81 | MODULE_PARM_DESC(tune_pci, "increase PCI burst from the default set by BIOS if nonzero"); |
82 | 82 | ||
83 | struct mutex mthca_device_mutex; | ||
84 | |||
83 | static const char mthca_version[] __devinitdata = | 85 | static const char mthca_version[] __devinitdata = |
84 | DRV_NAME ": Mellanox InfiniBand HCA driver v" | 86 | DRV_NAME ": Mellanox InfiniBand HCA driver v" |
85 | DRV_VERSION " (" DRV_RELDATE ")\n"; | 87 | DRV_VERSION " (" DRV_RELDATE ")\n"; |
@@ -978,28 +980,15 @@ static struct { | |||
978 | MTHCA_FLAG_SINAI_OPT } | 980 | MTHCA_FLAG_SINAI_OPT } |
979 | }; | 981 | }; |
980 | 982 | ||
981 | static int __devinit mthca_init_one(struct pci_dev *pdev, | 983 | static int __mthca_init_one(struct pci_dev *pdev, int hca_type) |
982 | const struct pci_device_id *id) | ||
983 | { | 984 | { |
984 | static int mthca_version_printed = 0; | ||
985 | int ddr_hidden = 0; | 985 | int ddr_hidden = 0; |
986 | int err; | 986 | int err; |
987 | struct mthca_dev *mdev; | 987 | struct mthca_dev *mdev; |
988 | 988 | ||
989 | if (!mthca_version_printed) { | ||
990 | printk(KERN_INFO "%s", mthca_version); | ||
991 | ++mthca_version_printed; | ||
992 | } | ||
993 | |||
994 | printk(KERN_INFO PFX "Initializing %s\n", | 989 | printk(KERN_INFO PFX "Initializing %s\n", |
995 | pci_name(pdev)); | 990 | pci_name(pdev)); |
996 | 991 | ||
997 | if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) { | ||
998 | printk(KERN_ERR PFX "%s has invalid driver data %lx\n", | ||
999 | pci_name(pdev), id->driver_data); | ||
1000 | return -ENODEV; | ||
1001 | } | ||
1002 | |||
1003 | err = pci_enable_device(pdev); | 992 | err = pci_enable_device(pdev); |
1004 | if (err) { | 993 | if (err) { |
1005 | dev_err(&pdev->dev, "Cannot enable PCI device, " | 994 | dev_err(&pdev->dev, "Cannot enable PCI device, " |
@@ -1065,7 +1054,7 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, | |||
1065 | 1054 | ||
1066 | mdev->pdev = pdev; | 1055 | mdev->pdev = pdev; |
1067 | 1056 | ||
1068 | mdev->mthca_flags = mthca_hca_table[id->driver_data].flags; | 1057 | mdev->mthca_flags = mthca_hca_table[hca_type].flags; |
1069 | if (ddr_hidden) | 1058 | if (ddr_hidden) |
1070 | mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN; | 1059 | mdev->mthca_flags |= MTHCA_FLAG_DDR_HIDDEN; |
1071 | 1060 | ||
@@ -1099,13 +1088,13 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, | |||
1099 | if (err) | 1088 | if (err) |
1100 | goto err_cmd; | 1089 | goto err_cmd; |
1101 | 1090 | ||
1102 | if (mdev->fw_ver < mthca_hca_table[id->driver_data].latest_fw) { | 1091 | if (mdev->fw_ver < mthca_hca_table[hca_type].latest_fw) { |
1103 | mthca_warn(mdev, "HCA FW version %d.%d.%d is old (%d.%d.%d is current).\n", | 1092 | mthca_warn(mdev, "HCA FW version %d.%d.%d is old (%d.%d.%d is current).\n", |
1104 | (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff, | 1093 | (int) (mdev->fw_ver >> 32), (int) (mdev->fw_ver >> 16) & 0xffff, |
1105 | (int) (mdev->fw_ver & 0xffff), | 1094 | (int) (mdev->fw_ver & 0xffff), |
1106 | (int) (mthca_hca_table[id->driver_data].latest_fw >> 32), | 1095 | (int) (mthca_hca_table[hca_type].latest_fw >> 32), |
1107 | (int) (mthca_hca_table[id->driver_data].latest_fw >> 16) & 0xffff, | 1096 | (int) (mthca_hca_table[hca_type].latest_fw >> 16) & 0xffff, |
1108 | (int) (mthca_hca_table[id->driver_data].latest_fw & 0xffff)); | 1097 | (int) (mthca_hca_table[hca_type].latest_fw & 0xffff)); |
1109 | mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n"); | 1098 | mthca_warn(mdev, "If you have problems, try updating your HCA FW.\n"); |
1110 | } | 1099 | } |
1111 | 1100 | ||
@@ -1122,6 +1111,7 @@ static int __devinit mthca_init_one(struct pci_dev *pdev, | |||
1122 | goto err_unregister; | 1111 | goto err_unregister; |
1123 | 1112 | ||
1124 | pci_set_drvdata(pdev, mdev); | 1113 | pci_set_drvdata(pdev, mdev); |
1114 | mdev->hca_type = hca_type; | ||
1125 | 1115 | ||
1126 | return 0; | 1116 | return 0; |
1127 | 1117 | ||
@@ -1166,7 +1156,7 @@ err_disable_pdev: | |||
1166 | return err; | 1156 | return err; |
1167 | } | 1157 | } |
1168 | 1158 | ||
1169 | static void __devexit mthca_remove_one(struct pci_dev *pdev) | 1159 | static void __mthca_remove_one(struct pci_dev *pdev) |
1170 | { | 1160 | { |
1171 | struct mthca_dev *mdev = pci_get_drvdata(pdev); | 1161 | struct mthca_dev *mdev = pci_get_drvdata(pdev); |
1172 | u8 status; | 1162 | u8 status; |
@@ -1211,6 +1201,51 @@ static void __devexit mthca_remove_one(struct pci_dev *pdev) | |||
1211 | } | 1201 | } |
1212 | } | 1202 | } |
1213 | 1203 | ||
1204 | int __mthca_restart_one(struct pci_dev *pdev) | ||
1205 | { | ||
1206 | struct mthca_dev *mdev; | ||
1207 | |||
1208 | mdev = pci_get_drvdata(pdev); | ||
1209 | if (!mdev) | ||
1210 | return -ENODEV; | ||
1211 | __mthca_remove_one(pdev); | ||
1212 | return __mthca_init_one(pdev, mdev->hca_type); | ||
1213 | } | ||
1214 | |||
1215 | static int __devinit mthca_init_one(struct pci_dev *pdev, | ||
1216 | const struct pci_device_id *id) | ||
1217 | { | ||
1218 | static int mthca_version_printed = 0; | ||
1219 | int ret; | ||
1220 | |||
1221 | mutex_lock(&mthca_device_mutex); | ||
1222 | |||
1223 | if (!mthca_version_printed) { | ||
1224 | printk(KERN_INFO "%s", mthca_version); | ||
1225 | ++mthca_version_printed; | ||
1226 | } | ||
1227 | |||
1228 | if (id->driver_data >= ARRAY_SIZE(mthca_hca_table)) { | ||
1229 | printk(KERN_ERR PFX "%s has invalid driver data %lx\n", | ||
1230 | pci_name(pdev), id->driver_data); | ||
1231 | mutex_unlock(&mthca_device_mutex); | ||
1232 | return -ENODEV; | ||
1233 | } | ||
1234 | |||
1235 | ret = __mthca_init_one(pdev, id->driver_data); | ||
1236 | |||
1237 | mutex_unlock(&mthca_device_mutex); | ||
1238 | |||
1239 | return ret; | ||
1240 | } | ||
1241 | |||
1242 | static void __devexit mthca_remove_one(struct pci_dev *pdev) | ||
1243 | { | ||
1244 | mutex_lock(&mthca_device_mutex); | ||
1245 | __mthca_remove_one(pdev); | ||
1246 | mutex_unlock(&mthca_device_mutex); | ||
1247 | } | ||
1248 | |||
1214 | static struct pci_device_id mthca_pci_table[] = { | 1249 | static struct pci_device_id mthca_pci_table[] = { |
1215 | { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR), | 1250 | { PCI_DEVICE(PCI_VENDOR_ID_MELLANOX, PCI_DEVICE_ID_MELLANOX_TAVOR), |
1216 | .driver_data = TAVOR }, | 1251 | .driver_data = TAVOR }, |
@@ -1248,13 +1283,24 @@ static int __init mthca_init(void) | |||
1248 | { | 1283 | { |
1249 | int ret; | 1284 | int ret; |
1250 | 1285 | ||
1286 | mutex_init(&mthca_device_mutex); | ||
1287 | ret = mthca_catas_init(); | ||
1288 | if (ret) | ||
1289 | return ret; | ||
1290 | |||
1251 | ret = pci_register_driver(&mthca_driver); | 1291 | ret = pci_register_driver(&mthca_driver); |
1252 | return ret < 0 ? ret : 0; | 1292 | if (ret < 0) { |
1293 | mthca_catas_cleanup(); | ||
1294 | return ret; | ||
1295 | } | ||
1296 | |||
1297 | return 0; | ||
1253 | } | 1298 | } |
1254 | 1299 | ||
1255 | static void __exit mthca_cleanup(void) | 1300 | static void __exit mthca_cleanup(void) |
1256 | { | 1301 | { |
1257 | pci_unregister_driver(&mthca_driver); | 1302 | pci_unregister_driver(&mthca_driver); |
1303 | mthca_catas_cleanup(); | ||
1258 | } | 1304 | } |
1259 | 1305 | ||
1260 | module_init(mthca_init); | 1306 | module_init(mthca_init); |
diff --git a/drivers/infiniband/hw/mthca/mthca_provider.c b/drivers/infiniband/hw/mthca/mthca_provider.c index 265b1d1c4a62..981fe2eebdfa 100644 --- a/drivers/infiniband/hw/mthca/mthca_provider.c +++ b/drivers/infiniband/hw/mthca/mthca_provider.c | |||
@@ -1288,7 +1288,7 @@ int mthca_register_device(struct mthca_dev *dev) | |||
1288 | (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | | 1288 | (1ull << IB_USER_VERBS_CMD_DESTROY_QP) | |
1289 | (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) | | 1289 | (1ull << IB_USER_VERBS_CMD_ATTACH_MCAST) | |
1290 | (1ull << IB_USER_VERBS_CMD_DETACH_MCAST); | 1290 | (1ull << IB_USER_VERBS_CMD_DETACH_MCAST); |
1291 | dev->ib_dev.node_type = IB_NODE_CA; | 1291 | dev->ib_dev.node_type = RDMA_NODE_IB_CA; |
1292 | dev->ib_dev.phys_port_cnt = dev->limits.num_ports; | 1292 | dev->ib_dev.phys_port_cnt = dev->limits.num_ports; |
1293 | dev->ib_dev.dma_device = &dev->pdev->dev; | 1293 | dev->ib_dev.dma_device = &dev->pdev->dev; |
1294 | dev->ib_dev.class_dev.dev = &dev->pdev->dev; | 1294 | dev->ib_dev.class_dev.dev = &dev->pdev->dev; |
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c index 2e8f6f36e0a5..5e5c58b9920b 100644 --- a/drivers/infiniband/hw/mthca/mthca_qp.c +++ b/drivers/infiniband/hw/mthca/mthca_qp.c | |||
@@ -408,7 +408,7 @@ static void to_ib_ah_attr(struct mthca_dev *dev, struct ib_ah_attr *ib_ah_attr, | |||
408 | ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28; | 408 | ib_ah_attr->sl = be32_to_cpu(path->sl_tclass_flowlabel) >> 28; |
409 | ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f; | 409 | ib_ah_attr->src_path_bits = path->g_mylmc & 0x7f; |
410 | ib_ah_attr->static_rate = mthca_rate_to_ib(dev, | 410 | ib_ah_attr->static_rate = mthca_rate_to_ib(dev, |
411 | path->static_rate & 0x7, | 411 | path->static_rate & 0xf, |
412 | ib_ah_attr->port_num); | 412 | ib_ah_attr->port_num); |
413 | ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0; | 413 | ib_ah_attr->ah_flags = (path->g_mylmc & (1 << 7)) ? IB_AH_GRH : 0; |
414 | if (ib_ah_attr->ah_flags) { | 414 | if (ib_ah_attr->ah_flags) { |
@@ -472,10 +472,14 @@ int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_m | |||
472 | if (qp->transport == RC || qp->transport == UC) { | 472 | if (qp->transport == RC || qp->transport == UC) { |
473 | to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path); | 473 | to_ib_ah_attr(dev, &qp_attr->ah_attr, &context->pri_path); |
474 | to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path); | 474 | to_ib_ah_attr(dev, &qp_attr->alt_ah_attr, &context->alt_path); |
475 | qp_attr->alt_pkey_index = | ||
476 | be32_to_cpu(context->alt_path.port_pkey) & 0x7f; | ||
477 | qp_attr->alt_port_num = qp_attr->alt_ah_attr.port_num; | ||
475 | } | 478 | } |
476 | 479 | ||
477 | qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f; | 480 | qp_attr->pkey_index = be32_to_cpu(context->pri_path.port_pkey) & 0x7f; |
478 | qp_attr->alt_pkey_index = be32_to_cpu(context->alt_path.port_pkey) & 0x7f; | 481 | qp_attr->port_num = |
482 | (be32_to_cpu(context->pri_path.port_pkey) >> 24) & 0x3; | ||
479 | 483 | ||
480 | /* qp_attr->en_sqd_async_notify is only applicable in modify qp */ | 484 | /* qp_attr->en_sqd_async_notify is only applicable in modify qp */ |
481 | qp_attr->sq_draining = mthca_state == MTHCA_QP_STATE_DRAINING; | 485 | qp_attr->sq_draining = mthca_state == MTHCA_QP_STATE_DRAINING; |
@@ -486,11 +490,9 @@ int mthca_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *qp_attr, int qp_attr_m | |||
486 | 1 << ((be32_to_cpu(context->params2) >> 21) & 0x7); | 490 | 1 << ((be32_to_cpu(context->params2) >> 21) & 0x7); |
487 | qp_attr->min_rnr_timer = | 491 | qp_attr->min_rnr_timer = |
488 | (be32_to_cpu(context->rnr_nextrecvpsn) >> 24) & 0x1f; | 492 | (be32_to_cpu(context->rnr_nextrecvpsn) >> 24) & 0x1f; |
489 | qp_attr->port_num = qp_attr->ah_attr.port_num; | ||
490 | qp_attr->timeout = context->pri_path.ackto >> 3; | 493 | qp_attr->timeout = context->pri_path.ackto >> 3; |
491 | qp_attr->retry_cnt = (be32_to_cpu(context->params1) >> 16) & 0x7; | 494 | qp_attr->retry_cnt = (be32_to_cpu(context->params1) >> 16) & 0x7; |
492 | qp_attr->rnr_retry = context->pri_path.rnr_retry >> 5; | 495 | qp_attr->rnr_retry = context->pri_path.rnr_retry >> 5; |
493 | qp_attr->alt_port_num = qp_attr->alt_ah_attr.port_num; | ||
494 | qp_attr->alt_timeout = context->alt_path.ackto >> 3; | 496 | qp_attr->alt_timeout = context->alt_path.ackto >> 3; |
495 | qp_init_attr->cap = qp_attr->cap; | 497 | qp_init_attr->cap = qp_attr->cap; |
496 | 498 | ||
@@ -527,7 +529,8 @@ static int mthca_path_set(struct mthca_dev *dev, struct ib_ah_attr *ah, | |||
527 | return 0; | 529 | return 0; |
528 | } | 530 | } |
529 | 531 | ||
530 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | 532 | int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask, |
533 | struct ib_udata *udata) | ||
531 | { | 534 | { |
532 | struct mthca_dev *dev = to_mdev(ibqp->device); | 535 | struct mthca_dev *dev = to_mdev(ibqp->device); |
533 | struct mthca_qp *qp = to_mqp(ibqp); | 536 | struct mthca_qp *qp = to_mqp(ibqp); |
@@ -842,11 +845,10 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask) | |||
842 | * entries and reinitialize the QP. | 845 | * entries and reinitialize the QP. |
843 | */ | 846 | */ |
844 | if (new_state == IB_QPS_RESET && !qp->ibqp.uobject) { | 847 | if (new_state == IB_QPS_RESET && !qp->ibqp.uobject) { |
845 | mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn, | 848 | mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, |
846 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); | 849 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); |
847 | if (qp->ibqp.send_cq != qp->ibqp.recv_cq) | 850 | if (qp->ibqp.send_cq != qp->ibqp.recv_cq) |
848 | mthca_cq_clean(dev, to_mcq(qp->ibqp.recv_cq), qp->qpn, | 851 | mthca_cq_clean(dev, to_mcq(qp->ibqp.send_cq), qp->qpn, NULL); |
849 | qp->ibqp.srq ? to_msrq(qp->ibqp.srq) : NULL); | ||
850 | 852 | ||
851 | mthca_wq_reset(&qp->sq); | 853 | mthca_wq_reset(&qp->sq); |
852 | qp->sq.last = get_send_wqe(qp, qp->sq.max - 1); | 854 | qp->sq.last = get_send_wqe(qp, qp->sq.max - 1); |
diff --git a/drivers/infiniband/hw/mthca/mthca_srq.c b/drivers/infiniband/hw/mthca/mthca_srq.c index b60a9d79ae54..0f316c87bf64 100644 --- a/drivers/infiniband/hw/mthca/mthca_srq.c +++ b/drivers/infiniband/hw/mthca/mthca_srq.c | |||
@@ -358,7 +358,7 @@ void mthca_free_srq(struct mthca_dev *dev, struct mthca_srq *srq) | |||
358 | } | 358 | } |
359 | 359 | ||
360 | int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, | 360 | int mthca_modify_srq(struct ib_srq *ibsrq, struct ib_srq_attr *attr, |
361 | enum ib_srq_attr_mask attr_mask) | 361 | enum ib_srq_attr_mask attr_mask, struct ib_udata *udata) |
362 | { | 362 | { |
363 | struct mthca_dev *dev = to_mdev(ibsrq->device); | 363 | struct mthca_dev *dev = to_mdev(ibsrq->device); |
364 | struct mthca_srq *srq = to_msrq(ibsrq); | 364 | struct mthca_srq *srq = to_msrq(ibsrq); |
diff --git a/drivers/infiniband/hw/mthca/mthca_uar.c b/drivers/infiniband/hw/mthca/mthca_uar.c index 8e9219842be4..8b728486410d 100644 --- a/drivers/infiniband/hw/mthca/mthca_uar.c +++ b/drivers/infiniband/hw/mthca/mthca_uar.c | |||
@@ -60,7 +60,7 @@ int mthca_init_uar_table(struct mthca_dev *dev) | |||
60 | ret = mthca_alloc_init(&dev->uar_table.alloc, | 60 | ret = mthca_alloc_init(&dev->uar_table.alloc, |
61 | dev->limits.num_uars, | 61 | dev->limits.num_uars, |
62 | dev->limits.num_uars - 1, | 62 | dev->limits.num_uars - 1, |
63 | dev->limits.reserved_uars); | 63 | dev->limits.reserved_uars + 1); |
64 | if (ret) | 64 | if (ret) |
65 | return ret; | 65 | return ret; |
66 | 66 | ||