diff options
Diffstat (limited to 'drivers/scsi/libiscsi.c')
-rw-r--r-- | drivers/scsi/libiscsi.c | 37 |
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 | ||
328 | static 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() */ |