aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/infiniband/hw')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c36
-rw-r--r--drivers/infiniband/hw/ehca/ehca_tools.h2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_rc.c59
-rw-r--r--drivers/infiniband/hw/ipath/ipath_verbs.c2
4 files changed, 53 insertions, 46 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 2380994418a5f..024d511c4b58f 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -49,7 +49,7 @@
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
-MODULE_VERSION("SVNEHCA_0016");
+MODULE_VERSION("SVNEHCA_0017");
int ehca_open_aqp1 = 0;
int ehca_debug_level = 0;
@@ -239,7 +239,7 @@ init_node_guid1:
return ret;
}
-int ehca_register_device(struct ehca_shca *shca)
+int ehca_init_device(struct ehca_shca *shca)
{
int ret;
@@ -317,11 +317,6 @@ int ehca_register_device(struct ehca_shca *shca)
/* shca->ib_device.process_mad = ehca_process_mad; */
shca->ib_device.mmap = ehca_mmap;
- ret = ib_register_device(&shca->ib_device);
- if (ret)
- ehca_err(&shca->ib_device,
- "ib_register_device() failed ret=%x", ret);
-
return ret;
}
@@ -561,9 +556,9 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
goto probe1;
}
- ret = ehca_register_device(shca);
+ ret = ehca_init_device(shca);
if (ret) {
- ehca_gen_err("Cannot register Infiniband device");
+ ehca_gen_err("Cannot init ehca device struct");
goto probe1;
}
@@ -571,7 +566,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
ret = ehca_create_eq(shca, &shca->eq, EHCA_EQ, 2048);
if (ret) {
ehca_err(&shca->ib_device, "Cannot create EQ.");
- goto probe2;
+ goto probe1;
}
ret = ehca_create_eq(shca, &shca->neq, EHCA_NEQ, 513);
@@ -600,6 +595,13 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
goto probe5;
}
+ ret = ib_register_device(&shca->ib_device);
+ if (ret) {
+ ehca_err(&shca->ib_device,
+ "ib_register_device() failed ret=%x", ret);
+ goto probe6;
+ }
+
/* create AQP1 for port 1 */
if (ehca_open_aqp1 == 1) {
shca->sport[0].port_state = IB_PORT_DOWN;
@@ -607,7 +609,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
if (ret) {
ehca_err(&shca->ib_device,
"Cannot create AQP1 for port 1.");
- goto probe6;
+ goto probe7;
}
}
@@ -618,7 +620,7 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
if (ret) {
ehca_err(&shca->ib_device,
"Cannot create AQP1 for port 2.");
- goto probe7;
+ goto probe8;
}
}
@@ -630,12 +632,15 @@ static int __devinit ehca_probe(struct ibmebus_dev *dev,
return 0;
-probe7:
+probe8:
ret = ehca_destroy_aqp1(&shca->sport[0]);
if (ret)
ehca_err(&shca->ib_device,
"Cannot destroy AQP1 for port 1. ret=%x", ret);
+probe7:
+ ib_unregister_device(&shca->ib_device);
+
probe6:
ret = ehca_dereg_internal_maxmr(shca);
if (ret)
@@ -660,9 +665,6 @@ probe3:
ehca_err(&shca->ib_device,
"Cannot destroy EQ. ret=%x", ret);
-probe2:
- ib_unregister_device(&shca->ib_device);
-
probe1:
ib_dealloc_device(&shca->ib_device);
@@ -750,7 +752,7 @@ int __init ehca_module_init(void)
int ret;
printk(KERN_INFO "eHCA Infiniband Device Driver "
- "(Rel.: SVNEHCA_0016)\n");
+ "(Rel.: SVNEHCA_0017)\n");
idr_init(&ehca_qp_idr);
idr_init(&ehca_cq_idr);
spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ehca_tools.h b/drivers/infiniband/hw/ehca/ehca_tools.h
index 9f56bb846d93b..809da3ef706bd 100644
--- a/drivers/infiniband/hw/ehca/ehca_tools.h
+++ b/drivers/infiniband/hw/ehca/ehca_tools.h
@@ -117,7 +117,7 @@ extern int ehca_debug_level;
unsigned int l = (unsigned int)(len); \
unsigned char *deb = (unsigned char*)(adr); \
for (x = 0; x < l; x += 16) { \
- printk("EHCA_DMP:%s" format \
+ printk("EHCA_DMP:%s " format \
" adr=%p ofs=%04x %016lx %016lx\n", \
__FUNCTION__, ##args, deb, x, \
*((u64 *)&deb[0]), *((u64 *)&deb[8])); \
diff --git a/drivers/infiniband/hw/ipath/ipath_rc.c b/drivers/infiniband/hw/ipath/ipath_rc.c
index a504cf67f2727..ce6038743c5c2 100644
--- a/drivers/infiniband/hw/ipath/ipath_rc.c
+++ b/drivers/infiniband/hw/ipath/ipath_rc.c
@@ -241,10 +241,7 @@ int ipath_make_rc_req(struct ipath_qp *qp,
* original work request since we may need to resend
* it.
*/
- qp->s_sge.sge = wqe->sg_list[0];
- qp->s_sge.sg_list = wqe->sg_list + 1;
- qp->s_sge.num_sge = wqe->wr.num_sge;
- qp->s_len = len = wqe->length;
+ len = wqe->length;
ss = &qp->s_sge;
bth2 = 0;
switch (wqe->wr.opcode) {
@@ -368,14 +365,23 @@ int ipath_make_rc_req(struct ipath_qp *qp,
default:
goto done;
}
+ qp->s_sge.sge = wqe->sg_list[0];
+ qp->s_sge.sg_list = wqe->sg_list + 1;
+ qp->s_sge.num_sge = wqe->wr.num_sge;
+ qp->s_len = wqe->length;
if (newreq) {
qp->s_tail++;
if (qp->s_tail >= qp->s_size)
qp->s_tail = 0;
}
- bth2 |= qp->s_psn++ & IPATH_PSN_MASK;
- if ((int)(qp->s_psn - qp->s_next_psn) > 0)
- qp->s_next_psn = qp->s_psn;
+ bth2 |= qp->s_psn & IPATH_PSN_MASK;
+ if (wqe->wr.opcode == IB_WR_RDMA_READ)
+ qp->s_psn = wqe->lpsn + 1;
+ else {
+ qp->s_psn++;
+ if ((int)(qp->s_psn - qp->s_next_psn) > 0)
+ qp->s_next_psn = qp->s_psn;
+ }
/*
* Put the QP on the pending list so lost ACKs will cause
* a retry. More than one request can be pending so the
@@ -690,13 +696,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
struct ipath_swqe *wqe = get_swqe_ptr(qp, qp->s_last);
struct ipath_ibdev *dev;
- /*
- * If there are no requests pending, we are done.
- */
- if (ipath_cmp24(psn, qp->s_next_psn) >= 0 ||
- qp->s_last == qp->s_tail)
- goto done;
-
if (qp->s_retry == 0) {
wc->wr_id = wqe->wr.wr_id;
wc->status = IB_WC_RETRY_EXC_ERR;
@@ -731,8 +730,6 @@ void ipath_restart_rc(struct ipath_qp *qp, u32 psn, struct ib_wc *wc)
dev->n_rc_resends += (int)qp->s_psn - (int)psn;
reset_psn(qp, psn);
-
-done:
tasklet_hi_schedule(&qp->s_task);
bail:
@@ -765,6 +762,7 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
struct ib_wc wc;
struct ipath_swqe *wqe;
int ret = 0;
+ u32 ack_psn;
/*
* Remove the QP from the timeout queue (or RNR timeout queue).
@@ -777,26 +775,26 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
list_del_init(&qp->timerwait);
spin_unlock(&dev->pending_lock);
+ /* Nothing is pending to ACK/NAK. */
+ if (unlikely(qp->s_last == qp->s_tail))
+ goto bail;
+
/*
* Note that NAKs implicitly ACK outstanding SEND and RDMA write
* requests and implicitly NAK RDMA read and atomic requests issued
* before the NAK'ed request. The MSN won't include the NAK'ed
* request but will include an ACK'ed request(s).
*/
+ ack_psn = psn;
+ if (aeth >> 29)
+ ack_psn--;
wqe = get_swqe_ptr(qp, qp->s_last);
- /* Nothing is pending to ACK/NAK. */
- if (qp->s_last == qp->s_tail)
- goto bail;
-
/*
* The MSN might be for a later WQE than the PSN indicates so
* only complete WQEs that the PSN finishes.
*/
- while (ipath_cmp24(psn, wqe->lpsn) >= 0) {
- /* If we are ACKing a WQE, the MSN should be >= the SSN. */
- if (ipath_cmp24(aeth, wqe->ssn) < 0)
- break;
+ while (ipath_cmp24(ack_psn, wqe->lpsn) >= 0) {
/*
* If this request is a RDMA read or atomic, and the ACK is
* for a later operation, this ACK NAKs the RDMA read or
@@ -807,7 +805,8 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
* is sent but before the response is received.
*/
if ((wqe->wr.opcode == IB_WR_RDMA_READ &&
- opcode != OP(RDMA_READ_RESPONSE_LAST)) ||
+ (opcode != OP(RDMA_READ_RESPONSE_LAST) ||
+ ipath_cmp24(ack_psn, wqe->lpsn) != 0)) ||
((wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD) &&
(opcode != OP(ATOMIC_ACKNOWLEDGE) ||
@@ -825,6 +824,10 @@ static int do_rc_ack(struct ipath_qp *qp, u32 aeth, u32 psn, int opcode)
*/
goto bail;
}
+ if (wqe->wr.opcode == IB_WR_RDMA_READ ||
+ wqe->wr.opcode == IB_WR_ATOMIC_CMP_AND_SWP ||
+ wqe->wr.opcode == IB_WR_ATOMIC_FETCH_AND_ADD)
+ tasklet_hi_schedule(&qp->s_task);
/* Post a send completion queue entry if requested. */
if (!test_bit(IPATH_S_SIGNAL_REQ_WR, &qp->s_flags) ||
(wqe->wr.send_flags & IB_SEND_SIGNALED)) {
@@ -1055,7 +1058,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
/* no AETH, no ACK */
if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
dev->n_rdma_seq++;
- ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+ if (qp->s_last != qp->s_tail)
+ ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
goto ack_done;
}
rdma_read:
@@ -1091,7 +1095,8 @@ static inline void ipath_rc_rcv_resp(struct ipath_ibdev *dev,
/* ACKs READ req. */
if (unlikely(ipath_cmp24(psn, qp->s_last_psn + 1))) {
dev->n_rdma_seq++;
- ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
+ if (qp->s_last != qp->s_tail)
+ ipath_restart_rc(qp, qp->s_last_psn + 1, &wc);
goto ack_done;
}
/* FALLTHROUGH */
diff --git a/drivers/infiniband/hw/ipath/ipath_verbs.c b/drivers/infiniband/hw/ipath/ipath_verbs.c
index 42eaed88c281b..a5456108dbadc 100644
--- a/drivers/infiniband/hw/ipath/ipath_verbs.c
+++ b/drivers/infiniband/hw/ipath/ipath_verbs.c
@@ -1601,7 +1601,7 @@ int ipath_register_ib_device(struct ipath_devdata *dd)
dev->mmap = ipath_mmap;
snprintf(dev->node_desc, sizeof(dev->node_desc),
- IPATH_IDSTR " %s", system_utsname.nodename);
+ IPATH_IDSTR " %s", init_utsname()->nodename);
ret = ib_register_device(dev);
if (ret)