aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi
diff options
context:
space:
mode:
authorVikas Chaudhary <vikas.chaudhary@qlogic.com>2010-04-28 02:11:21 -0400
committerJames Bottomley <James.Bottomley@suse.de>2010-05-02 15:39:49 -0400
commit821d6e5413481a57bbe1c2722dbe1fee4ff675c4 (patch)
tree8e0ddfabf4fda472a06b104d809c5e2078040720 /drivers/scsi
parentc301b0266c65c8781361ca152981cff4fac05498 (diff)
[SCSI] qla4xxx: do not retry login to CHAP auth failed targets
Per RFC 3720, Login Response Status Code 0x02 should not be retried. Condensed connection error checking code to a single routine, and added check for status class 0x02. Signed-off-by: Karen Higgins <karen.higgins@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: Ravi Anand <ravi.anand@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
Diffstat (limited to 'drivers/scsi')
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h5
-rw-r--r--drivers/scsi/qla4xxx/ql4_init.c130
-rw-r--r--drivers/scsi/qla4xxx/ql4_isr.c2
3 files changed, 94 insertions, 43 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 96ebfb021f6c..987658f5bc13 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -67,11 +67,12 @@ struct srb * qla4xxx_del_from_active_array(struct scsi_qla_host *ha,
67 uint32_t index); 67 uint32_t index);
68void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb); 68void qla4xxx_srb_compl(struct scsi_qla_host *ha, struct srb *srb);
69int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha); 69int qla4xxx_reinitialize_ddb_list(struct scsi_qla_host * ha);
70int qla4xxx_process_ddb_changed(struct scsi_qla_host * ha, 70int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
71 uint32_t fw_ddb_index, uint32_t state); 71 uint32_t state, uint32_t conn_error);
72void qla4xxx_dump_buffer(void *b, uint32_t size); 72void qla4xxx_dump_buffer(void *b, uint32_t size);
73int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha, 73int qla4xxx_send_marker_iocb(struct scsi_qla_host *ha,
74 struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod); 74 struct ddb_entry *ddb_entry, int lun, uint16_t mrkr_mod);
75int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err);
75 76
76extern int ql4xextended_error_logging; 77extern int ql4xextended_error_logging;
77extern int ql4xdiscoverywait; 78extern int ql4xdiscoverywait;
diff --git a/drivers/scsi/qla4xxx/ql4_init.c b/drivers/scsi/qla4xxx/ql4_init.c
index beaeb18a66ab..5510df8a7fa6 100644
--- a/drivers/scsi/qla4xxx/ql4_init.c
+++ b/drivers/scsi/qla4xxx/ql4_init.c
@@ -505,6 +505,7 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
505 struct dev_db_entry *fw_ddb_entry = NULL; 505 struct dev_db_entry *fw_ddb_entry = NULL;
506 dma_addr_t fw_ddb_entry_dma; 506 dma_addr_t fw_ddb_entry_dma;
507 int status = QLA_ERROR; 507 int status = QLA_ERROR;
508 uint32_t conn_err;
508 509
509 if (ddb_entry == NULL) { 510 if (ddb_entry == NULL) {
510 DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no, 511 DEBUG2(printk("scsi%ld: %s: ddb_entry is NULL\n", ha->host_no,
@@ -525,7 +526,7 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
525 526
526 if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry, 527 if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry,
527 fw_ddb_entry_dma, NULL, NULL, 528 fw_ddb_entry_dma, NULL, NULL,
528 &ddb_entry->fw_ddb_device_state, NULL, 529 &ddb_entry->fw_ddb_device_state, &conn_err,
529 &ddb_entry->tcp_source_port_num, 530 &ddb_entry->tcp_source_port_num,
530 &ddb_entry->connection_id) == 531 &ddb_entry->connection_id) ==
531 QLA_ERROR) { 532 QLA_ERROR) {
@@ -578,12 +579,26 @@ static int qla4xxx_update_ddb_entry(struct scsi_qla_host *ha,
578 fw_ddb_entry->link_local_ipv6_addr, 579 fw_ddb_entry->link_local_ipv6_addr,
579 min(sizeof(ddb_entry->link_local_ipv6_addr), 580 min(sizeof(ddb_entry->link_local_ipv6_addr),
580 sizeof(fw_ddb_entry->link_local_ipv6_addr))); 581 sizeof(fw_ddb_entry->link_local_ipv6_addr)));
581 }
582
583 DEBUG2(printk("scsi%ld: %s: ddb[%d] - State= %x status= %d.\n",
584 ha->host_no, __func__, fw_ddb_index,
585 ddb_entry->fw_ddb_device_state, status));
586 582
583 DEBUG2(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d "
584 "State %04x ConnErr %08x IP %pI6 "
585 ":%04d \"%s\"\n",
586 __func__, fw_ddb_index,
587 ddb_entry->os_target_id,
588 ddb_entry->fw_ddb_device_state,
589 conn_err, fw_ddb_entry->ip_addr,
590 le16_to_cpu(fw_ddb_entry->port),
591 fw_ddb_entry->iscsi_name));
592 } else
593 DEBUG2(dev_info(&ha->pdev->dev, "%s: DDB[%d] osIdx = %d "
594 "State %04x ConnErr %08x IP %pI4 "
595 ":%04d \"%s\"\n",
596 __func__, fw_ddb_index,
597 ddb_entry->os_target_id,
598 ddb_entry->fw_ddb_device_state,
599 conn_err, fw_ddb_entry->ip_addr,
600 le16_to_cpu(fw_ddb_entry->port),
601 fw_ddb_entry->iscsi_name));
587exit_update_ddb: 602exit_update_ddb:
588 if (fw_ddb_entry) 603 if (fw_ddb_entry)
589 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 604 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
@@ -630,6 +645,40 @@ static struct ddb_entry * qla4xxx_alloc_ddb(struct scsi_qla_host *ha,
630} 645}
631 646
632/** 647/**
648 * qla4_is_relogin_allowed - Are we allowed to login?
649 * @ha: Pointer to host adapter structure.
650 * @conn_err: Last connection error associated with the ddb
651 *
652 * This routine tests the given connection error to determine if
653 * we are allowed to login.
654 **/
655int qla4_is_relogin_allowed(struct scsi_qla_host *ha, uint32_t conn_err)
656{
657 uint32_t err_code, login_rsp_sts_class;
658 int relogin = 1;
659
660 err_code = ((conn_err & 0x00ff0000) >> 16);
661 login_rsp_sts_class = ((conn_err & 0x0000ff00) >> 8);
662 if (err_code == 0x1c || err_code == 0x06) {
663 DEBUG2(dev_info(&ha->pdev->dev,
664 ": conn_err=0x%08x, send target completed"
665 " or access denied failure\n", conn_err));
666 relogin = 0;
667 }
668 if ((err_code == 0x08) && (login_rsp_sts_class == 0x02)) {
669 /* Login Response PDU returned an error.
670 Login Response Status in Error Code Detail
671 indicates login should not be retried.*/
672 DEBUG2(dev_info(&ha->pdev->dev,
673 ": conn_err=0x%08x, do not retry relogin\n",
674 conn_err));
675 relogin = 0;
676 }
677
678 return relogin;
679}
680
681/**
633 * qla4xxx_configure_ddbs - builds driver ddb list 682 * qla4xxx_configure_ddbs - builds driver ddb list
634 * @ha: Pointer to host adapter structure. 683 * @ha: Pointer to host adapter structure.
635 * 684 *
@@ -643,18 +692,30 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
643 uint32_t fw_ddb_index = 0; 692 uint32_t fw_ddb_index = 0;
644 uint32_t next_fw_ddb_index = 0; 693 uint32_t next_fw_ddb_index = 0;
645 uint32_t ddb_state; 694 uint32_t ddb_state;
646 uint32_t conn_err, err_code; 695 uint32_t conn_err;
647 struct ddb_entry *ddb_entry; 696 struct ddb_entry *ddb_entry;
697 struct dev_db_entry *fw_ddb_entry = NULL;
698 dma_addr_t fw_ddb_entry_dma;
699 uint32_t ipv6_device;
648 uint32_t new_tgt; 700 uint32_t new_tgt;
649 701
702 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
703 &fw_ddb_entry_dma, GFP_KERNEL);
704 if (fw_ddb_entry == NULL) {
705 DEBUG2(dev_info(&ha->pdev->dev, "%s: DMA alloc failed\n",
706 __func__));
707 return QLA_ERROR;
708 }
709
650 dev_info(&ha->pdev->dev, "Initializing DDBs ...\n"); 710 dev_info(&ha->pdev->dev, "Initializing DDBs ...\n");
651 for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES; 711 for (fw_ddb_index = 0; fw_ddb_index < MAX_DDB_ENTRIES;
652 fw_ddb_index = next_fw_ddb_index) { 712 fw_ddb_index = next_fw_ddb_index) {
653 /* First, let's see if a device exists here */ 713 /* First, let's see if a device exists here */
654 if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, NULL, 0, NULL, 714 if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, fw_ddb_entry,
655 &next_fw_ddb_index, &ddb_state, 715 0, NULL, &next_fw_ddb_index,
656 &conn_err, NULL, NULL) == 716 &ddb_state, &conn_err,
657 QLA_ERROR) { 717 NULL, NULL) ==
718 QLA_ERROR) {
658 DEBUG2(printk("scsi%ld: %s: get_ddb_entry, " 719 DEBUG2(printk("scsi%ld: %s: get_ddb_entry, "
659 "fw_ddb_index %d failed", ha->host_no, 720 "fw_ddb_index %d failed", ha->host_no,
660 __func__, fw_ddb_index)); 721 __func__, fw_ddb_index));
@@ -671,18 +732,19 @@ static int qla4xxx_build_ddb_list(struct scsi_qla_host *ha)
671 /* Try and login to device */ 732 /* Try and login to device */
672 DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n", 733 DEBUG2(printk("scsi%ld: %s: Login to DDB[%d]\n",
673 ha->host_no, __func__, fw_ddb_index)); 734 ha->host_no, __func__, fw_ddb_index));
674 err_code = ((conn_err & 0x00ff0000) >> 16); 735 ipv6_device = le16_to_cpu(fw_ddb_entry->options) &
675 if (err_code == 0x1c || err_code == 0x06) { 736 DDB_OPT_IPV6_DEVICE;
676 DEBUG2(printk("scsi%ld: %s send target " 737 if (qla4_is_relogin_allowed(ha, conn_err) &&
677 "completed " 738 ((!ipv6_device &&
678 "or access denied failure\n", 739 *((uint32_t *)fw_ddb_entry->ip_addr))
679 ha->host_no, __func__)); 740 || ipv6_device)) {
680 } else {
681 qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0); 741 qla4xxx_set_ddb_entry(ha, fw_ddb_index, 0);
682 if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index, 742 if (qla4xxx_get_fwddb_entry(ha, fw_ddb_index,
683 NULL, 0, NULL, &next_fw_ddb_index, 743 NULL, 0, NULL,
684 &ddb_state, &conn_err, NULL, NULL) 744 &next_fw_ddb_index,
685 == QLA_ERROR) { 745 &ddb_state, &conn_err,
746 NULL, NULL)
747 == QLA_ERROR) {
686 DEBUG2(printk("scsi%ld: %s:" 748 DEBUG2(printk("scsi%ld: %s:"
687 "get_ddb_entry %d failed\n", 749 "get_ddb_entry %d failed\n",
688 ha->host_no, 750 ha->host_no,
@@ -737,7 +799,6 @@ next_one:
737struct qla4_relog_scan { 799struct qla4_relog_scan {
738 int halt_wait; 800 int halt_wait;
739 uint32_t conn_err; 801 uint32_t conn_err;
740 uint32_t err_code;
741 uint32_t fw_ddb_index; 802 uint32_t fw_ddb_index;
742 uint32_t next_fw_ddb_index; 803 uint32_t next_fw_ddb_index;
743 uint32_t fw_ddb_device_state; 804 uint32_t fw_ddb_device_state;
@@ -747,18 +808,7 @@ static int qla4_test_rdy(struct scsi_qla_host *ha, struct qla4_relog_scan *rs)
747{ 808{
748 struct ddb_entry *ddb_entry; 809 struct ddb_entry *ddb_entry;
749 810
750 /* 811 if (qla4_is_relogin_allowed(ha, rs->conn_err)) {
751 * Don't want to do a relogin if connection
752 * error is 0x1c.
753 */
754 rs->err_code = ((rs->conn_err & 0x00ff0000) >> 16);
755 if (rs->err_code == 0x1c || rs->err_code == 0x06) {
756 DEBUG2(printk(
757 "scsi%ld: %s send target"
758 " completed or "
759 "access denied failure\n",
760 ha->host_no, __func__));
761 } else {
762 /* We either have a device that is in 812 /* We either have a device that is in
763 * the process of relogging in or a 813 * the process of relogging in or a
764 * device that is waiting to be 814 * device that is waiting to be
@@ -1411,8 +1461,8 @@ static void qla4xxx_add_device_dynamically(struct scsi_qla_host *ha,
1411 * 1461 *
1412 * This routine processes a Decive Database Changed AEN Event. 1462 * This routine processes a Decive Database Changed AEN Event.
1413 **/ 1463 **/
1414int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, 1464int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
1415 uint32_t fw_ddb_index, uint32_t state) 1465 uint32_t state, uint32_t conn_err)
1416{ 1466{
1417 struct ddb_entry * ddb_entry; 1467 struct ddb_entry * ddb_entry;
1418 uint32_t old_fw_ddb_device_state; 1468 uint32_t old_fw_ddb_device_state;
@@ -1470,13 +1520,13 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
1470 1520
1471 /* 1521 /*
1472 * Relogin if device state changed to a not active state. 1522 * Relogin if device state changed to a not active state.
1473 * However, do not relogin if this aen is a result of an IOCTL 1523 * However, do not relogin if a RELOGIN is in process, or
1474 * logout (DF_NO_RELOGIN) or if this is a discovered device. 1524 * we are not allowed to relogin to this DDB.
1475 */ 1525 */
1476 if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_FAILED && 1526 if (ddb_entry->fw_ddb_device_state == DDB_DS_SESSION_FAILED &&
1477 !test_bit(DF_RELOGIN, &ddb_entry->flags) && 1527 !test_bit(DF_RELOGIN, &ddb_entry->flags) &&
1478 !test_bit(DF_NO_RELOGIN, &ddb_entry->flags) && 1528 !test_bit(DF_NO_RELOGIN, &ddb_entry->flags) &&
1479 !test_bit(DF_ISNS_DISCOVERED, &ddb_entry->flags)) { 1529 qla4_is_relogin_allowed(ha, conn_err)) {
1480 /* 1530 /*
1481 * This triggers a relogin. After the relogin_timer 1531 * This triggers a relogin. After the relogin_timer
1482 * expires, the relogin gets scheduled. We must wait a 1532 * expires, the relogin gets scheduled. We must wait a
@@ -1484,7 +1534,7 @@ int qla4xxx_process_ddb_changed(struct scsi_qla_host *ha,
1484 * with failed device_state or a logout response before 1534 * with failed device_state or a logout response before
1485 * we can issue another relogin. 1535 * we can issue another relogin.
1486 */ 1536 */
1487 /* Firmware padds this timeout: (time2wait +1). 1537 /* Firmware pads this timeout: (time2wait +1).
1488 * Driver retry to login should be longer than F/W. 1538 * Driver retry to login should be longer than F/W.
1489 * Otherwise F/W will fail 1539 * Otherwise F/W will fail
1490 * set_ddb() mbx cmd with 0x4005 since it still 1540 * set_ddb() mbx cmd with 0x4005 since it still
diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c
index 9db286df7ca0..ce5838eb685e 100644
--- a/drivers/scsi/qla4xxx/ql4_isr.c
+++ b/drivers/scsi/qla4xxx/ql4_isr.c
@@ -838,7 +838,7 @@ void qla4xxx_process_aen(struct scsi_qla_host * ha, uint8_t process_aen)
838 qla4xxx_reinitialize_ddb_list(ha); 838 qla4xxx_reinitialize_ddb_list(ha);
839 } else if (mbox_sts[1] == 1) { /* Specific device. */ 839 } else if (mbox_sts[1] == 1) { /* Specific device. */
840 qla4xxx_process_ddb_changed(ha, mbox_sts[2], 840 qla4xxx_process_ddb_changed(ha, mbox_sts[2],
841 mbox_sts[3]); 841 mbox_sts[3], mbox_sts[4]);
842 } 842 }
843 break; 843 break;
844 } 844 }