aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/libiscsi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r--drivers/scsi/libiscsi.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c
index 9584cbc082fe..fb65311c81dd 100644
--- a/drivers/scsi/libiscsi.c
+++ b/drivers/scsi/libiscsi.c
@@ -325,6 +325,30 @@ static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
325 wake_up(&conn->ehwait); 325 wake_up(&conn->ehwait);
326} 326}
327 327
328static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
329 char *data, int datalen)
330{
331 struct iscsi_reject *reject = (struct iscsi_reject *)hdr;
332 struct iscsi_hdr rejected_pdu;
333 uint32_t itt;
334
335 conn->exp_statsn = be32_to_cpu(reject->statsn) + 1;
336
337 if (reject->reason == ISCSI_REASON_DATA_DIGEST_ERROR) {
338 if (ntoh24(reject->dlength) > datalen)
339 return ISCSI_ERR_PROTO;
340
341 if (ntoh24(reject->dlength) >= sizeof(struct iscsi_hdr)) {
342 memcpy(&rejected_pdu, data, sizeof(struct iscsi_hdr));
343 itt = rejected_pdu.itt & ISCSI_ITT_MASK;
344 printk(KERN_ERR "itt 0x%x had pdu (op 0x%x) rejected "
345 "due to DataDigest error.\n", itt,
346 rejected_pdu.opcode);
347 }
348 }
349 return 0;
350}
351
328/** 352/**
329 * __iscsi_complete_pdu - complete pdu 353 * __iscsi_complete_pdu - complete pdu
330 * @conn: iscsi conn 354 * @conn: iscsi conn
@@ -436,6 +460,11 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
436 break; 460 break;
437 } 461 }
438 } else if (itt == ISCSI_RESERVED_TAG) { 462 } else if (itt == ISCSI_RESERVED_TAG) {
463 rc = iscsi_check_assign_cmdsn(session,
464 (struct iscsi_nopin*)hdr);
465 if (rc)
466 goto done;
467
439 switch(opcode) { 468 switch(opcode) {
440 case ISCSI_OP_NOOP_IN: 469 case ISCSI_OP_NOOP_IN:
441 if (datalen) { 470 if (datalen) {
@@ -443,11 +472,6 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
443 break; 472 break;
444 } 473 }
445 474
446 rc = iscsi_check_assign_cmdsn(session,
447 (struct iscsi_nopin*)hdr);
448 if (rc)
449 break;
450
451 if (hdr->ttt == ISCSI_RESERVED_TAG) 475 if (hdr->ttt == ISCSI_RESERVED_TAG)
452 break; 476 break;
453 477
@@ -455,7 +479,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr,
455 rc = ISCSI_ERR_CONN_FAILED; 479 rc = ISCSI_ERR_CONN_FAILED;
456 break; 480 break;
457 case ISCSI_OP_REJECT: 481 case ISCSI_OP_REJECT:
458 /* we need sth like iscsi_reject_rsp()*/ 482 rc = iscsi_handle_reject(conn, hdr, data, datalen);
483 break;
459 case ISCSI_OP_ASYNC_EVENT: 484 case ISCSI_OP_ASYNC_EVENT:
460 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; 485 conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1;
461 /* we need sth like iscsi_async_event_rsp() */ 486 /* we need sth like iscsi_async_event_rsp() */