diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.c | 37 | ||||
-rw-r--r-- | drivers/infiniband/ulp/srp/ib_srp.h | 2 |
2 files changed, 21 insertions, 18 deletions
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index baafee085e33..c28833070201 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -515,6 +515,8 @@ static int srp_connect_target(struct srp_target_port *target) | |||
515 | int retries = 3; | 515 | int retries = 3; |
516 | int ret; | 516 | int ret; |
517 | 517 | ||
518 | target->qp_in_error = false; | ||
519 | |||
518 | ret = srp_lookup_path(target); | 520 | ret = srp_lookup_path(target); |
519 | if (ret) | 521 | if (ret) |
520 | return ret; | 522 | return ret; |
@@ -689,7 +691,6 @@ static int srp_reconnect_target(struct srp_target_port *target) | |||
689 | for (i = 0; i < SRP_SQ_SIZE; ++i) | 691 | for (i = 0; i < SRP_SQ_SIZE; ++i) |
690 | list_add(&target->tx_ring[i]->list, &target->free_tx); | 692 | list_add(&target->tx_ring[i]->list, &target->free_tx); |
691 | 693 | ||
692 | target->qp_in_error = 0; | ||
693 | ret = srp_connect_target(target); | 694 | ret = srp_connect_target(target); |
694 | 695 | ||
695 | unblock: | 696 | unblock: |
@@ -1269,6 +1270,15 @@ static void srp_handle_recv(struct srp_target_port *target, struct ib_wc *wc) | |||
1269 | PFX "Recv failed with error code %d\n", res); | 1270 | PFX "Recv failed with error code %d\n", res); |
1270 | } | 1271 | } |
1271 | 1272 | ||
1273 | static void srp_handle_qp_err(enum ib_wc_status wc_status, | ||
1274 | enum ib_wc_opcode wc_opcode, | ||
1275 | struct srp_target_port *target) | ||
1276 | { | ||
1277 | shost_printk(KERN_ERR, target->scsi_host, PFX "failed %s status %d\n", | ||
1278 | wc_opcode & IB_WC_RECV ? "receive" : "send", wc_status); | ||
1279 | target->qp_in_error = true; | ||
1280 | } | ||
1281 | |||
1272 | static void srp_recv_completion(struct ib_cq *cq, void *target_ptr) | 1282 | static void srp_recv_completion(struct ib_cq *cq, void *target_ptr) |
1273 | { | 1283 | { |
1274 | struct srp_target_port *target = target_ptr; | 1284 | struct srp_target_port *target = target_ptr; |
@@ -1276,15 +1286,12 @@ static void srp_recv_completion(struct ib_cq *cq, void *target_ptr) | |||
1276 | 1286 | ||
1277 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); | 1287 | ib_req_notify_cq(cq, IB_CQ_NEXT_COMP); |
1278 | while (ib_poll_cq(cq, 1, &wc) > 0) { | 1288 | while (ib_poll_cq(cq, 1, &wc) > 0) { |
1279 | if (wc.status) { | 1289 | if (likely(wc.status == IB_WC_SUCCESS)) { |
1280 | shost_printk(KERN_ERR, target->scsi_host, | 1290 | srp_handle_recv(target, &wc); |
1281 | PFX "failed receive status %d\n", | 1291 | } else { |
1282 | wc.status); | 1292 | srp_handle_qp_err(wc.status, wc.opcode, target); |
1283 | target->qp_in_error = 1; | ||
1284 | break; | 1293 | break; |
1285 | } | 1294 | } |
1286 | |||
1287 | srp_handle_recv(target, &wc); | ||
1288 | } | 1295 | } |
1289 | } | 1296 | } |
1290 | 1297 | ||
@@ -1295,16 +1302,13 @@ static void srp_send_completion(struct ib_cq *cq, void *target_ptr) | |||
1295 | struct srp_iu *iu; | 1302 | struct srp_iu *iu; |
1296 | 1303 | ||
1297 | while (ib_poll_cq(cq, 1, &wc) > 0) { | 1304 | while (ib_poll_cq(cq, 1, &wc) > 0) { |
1298 | if (wc.status) { | 1305 | if (likely(wc.status == IB_WC_SUCCESS)) { |
1299 | shost_printk(KERN_ERR, target->scsi_host, | 1306 | iu = (struct srp_iu *) (uintptr_t) wc.wr_id; |
1300 | PFX "failed send status %d\n", | 1307 | list_add(&iu->list, &target->free_tx); |
1301 | wc.status); | 1308 | } else { |
1302 | target->qp_in_error = 1; | 1309 | srp_handle_qp_err(wc.status, wc.opcode, target); |
1303 | break; | 1310 | break; |
1304 | } | 1311 | } |
1305 | |||
1306 | iu = (struct srp_iu *) (uintptr_t) wc.wr_id; | ||
1307 | list_add(&iu->list, &target->free_tx); | ||
1308 | } | 1312 | } |
1309 | } | 1313 | } |
1310 | 1314 | ||
@@ -2269,7 +2273,6 @@ static ssize_t srp_create_target(struct device *dev, | |||
2269 | if (ret) | 2273 | if (ret) |
2270 | goto err_free_ib; | 2274 | goto err_free_ib; |
2271 | 2275 | ||
2272 | target->qp_in_error = 0; | ||
2273 | ret = srp_connect_target(target); | 2276 | ret = srp_connect_target(target); |
2274 | if (ret) { | 2277 | if (ret) { |
2275 | shost_printk(KERN_ERR, target->scsi_host, | 2278 | shost_printk(KERN_ERR, target->scsi_host, |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.h b/drivers/infiniband/ulp/srp/ib_srp.h index 8b436cee46ad..02dc3acb718c 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.h +++ b/drivers/infiniband/ulp/srp/ib_srp.h | |||
@@ -179,7 +179,7 @@ struct srp_target_port { | |||
179 | struct list_head list; | 179 | struct list_head list; |
180 | struct completion done; | 180 | struct completion done; |
181 | int status; | 181 | int status; |
182 | int qp_in_error; | 182 | bool qp_in_error; |
183 | 183 | ||
184 | struct completion tsk_mgmt_done; | 184 | struct completion tsk_mgmt_done; |
185 | u8 tsk_mgmt_status; | 185 | u8 tsk_mgmt_status; |