aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qla4xxx
diff options
context:
space:
mode:
authorLalit Chandivade <lalit.chandivade@qlogic.com>2011-10-07 19:55:42 -0400
committerJames Bottomley <JBottomley@Parallels.com>2011-10-16 12:08:41 -0400
commit4549415af6915017f5d3fbdbfd5edd1dfbe63fa9 (patch)
treeb06ad5224dd3093d6fd9377d8461a295f101e1b7 /drivers/scsi/qla4xxx
parent0854f665a1cbb4566d3ebe449169b0200b8cdad0 (diff)
[SCSI] qla4xxx: Do not add duplicate CHAP entry in FLASH
QLogic applications store the CHAP information in FLASH. During login, authentication information is provided using an index into the CHAP region. In order to support QLogic applications along with iscsiadm, updated the LLD to not add duplicate CHAP entries in the CHAP region and preserve the existing CHAP info in the CHAP region in FLASH. This allows QLogic applications to pre-write the CHAP entries in the CHAP region. With iscsiadm, when the CHAP authentication information is sent to the LLD, the LLD searches for the entry in CHAP region in FLASH, if exists then do not add. If CHAP entry does not exist then add the CHAP entry in the CHAP region. JIRA Key: UPSISCSI-146 Signed-off-by: Lalit Chandivade <lalit.chandivade@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Reviewed-by: Mike Christie <michaelc@cs.wisc.edu> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/qla4xxx')
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h10
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h5
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c141
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c7
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c67
5 files changed, 195 insertions, 35 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index a80adfc6d780..fcb1dff9bc19 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -279,7 +279,8 @@ struct ql82xx_hw_data {
279 uint32_t flt_region_fw; 279 uint32_t flt_region_fw;
280 280
281 uint32_t flt_iscsi_param; 281 uint32_t flt_iscsi_param;
282 uint32_t reserved; 282 uint32_t flt_region_chap;
283 uint32_t flt_chap_size;
283}; 284};
284 285
285struct qla4_8xxx_legacy_intr_set { 286struct qla4_8xxx_legacy_intr_set {
@@ -609,6 +610,8 @@ struct scsi_qla_host {
609#define QLFLASH_READING 1 610#define QLFLASH_READING 1
610#define QLFLASH_WRITING 2 611#define QLFLASH_WRITING 2
611 struct dma_pool *chap_dma_pool; 612 struct dma_pool *chap_dma_pool;
613 uint8_t *chap_list; /* CHAP table cache */
614 struct mutex chap_sem;
612#define CHAP_DMA_BLOCK_SIZE 512 615#define CHAP_DMA_BLOCK_SIZE 512
613 struct workqueue_struct *task_wq; 616 struct workqueue_struct *task_wq;
614 unsigned long ddb_idx_map[MAX_DDB_ENTRIES / BITS_PER_LONG]; 617 unsigned long ddb_idx_map[MAX_DDB_ENTRIES / BITS_PER_LONG];
@@ -671,6 +674,11 @@ static inline int is_qla4032(struct scsi_qla_host *ha)
671 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4032; 674 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP4032;
672} 675}
673 676
677static inline int is_qla40XX(struct scsi_qla_host *ha)
678{
679 return is_qla4032(ha) || is_qla4022(ha) || is_qla4010(ha);
680}
681
674static inline int is_qla8022(struct scsi_qla_host *ha) 682static inline int is_qla8022(struct scsi_qla_host *ha)
675{ 683{
676 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022; 684 return ha->pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8022;
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index 597875fbb24b..cbd5a20dbbd1 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -251,6 +251,8 @@ union external_hw_config_reg {
251#define FA_BOOT_CODE_ADDR_82 0x20000 251#define FA_BOOT_CODE_ADDR_82 0x20000
252#define FA_RISC_CODE_ADDR_82 0x40000 252#define FA_RISC_CODE_ADDR_82 0x40000
253#define FA_GOLD_RISC_CODE_ADDR_82 0x80000 253#define FA_GOLD_RISC_CODE_ADDR_82 0x80000
254#define FA_FLASH_ISCSI_CHAP 0x540000
255#define FA_FLASH_CHAP_SIZE 0xC0000
254 256
255/* Flash Description Table */ 257/* Flash Description Table */
256struct qla_fdt_layout { 258struct qla_fdt_layout {
@@ -310,6 +312,7 @@ struct qla_flt_header {
310#define FLT_REG_GOLD_FW_82 0x75 312#define FLT_REG_GOLD_FW_82 0x75
311#define FLT_REG_BOOT_CODE_82 0x78 313#define FLT_REG_BOOT_CODE_82 0x78
312#define FLT_REG_ISCSI_PARAM 0x65 314#define FLT_REG_ISCSI_PARAM 0x65
315#define FLT_REG_ISCSI_CHAP 0x63
313 316
314struct qla_flt_region { 317struct qla_flt_region {
315 uint32_t code; 318 uint32_t code;
@@ -681,6 +684,8 @@ struct addr_ctrl_blk_def {
681 684
682#define MAX_CHAP_ENTRIES_40XX 128 685#define MAX_CHAP_ENTRIES_40XX 128
683#define MAX_CHAP_ENTRIES_82XX 1024 686#define MAX_CHAP_ENTRIES_82XX 1024
687#define MAX_RESRV_CHAP_IDX 3
688#define FLASH_CHAP_OFFSET 0x06000000
684 689
685struct ql4_chap_table { 690struct ql4_chap_table {
686 uint16_t link; 691 uint16_t link;
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index b60b90301a8b..4c2b84870392 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1304,7 +1304,7 @@ int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
1304{ 1304{
1305 int ret = 0; 1305 int ret = 0;
1306 int rval = QLA_ERROR; 1306 int rval = QLA_ERROR;
1307 uint32_t offset = 0; 1307 uint32_t offset = 0, chap_size;
1308 struct ql4_chap_table *chap_table; 1308 struct ql4_chap_table *chap_table;
1309 dma_addr_t chap_dma; 1309 dma_addr_t chap_dma;
1310 1310
@@ -1314,12 +1314,22 @@ int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
1314 goto exit_get_chap; 1314 goto exit_get_chap;
1315 } 1315 }
1316 1316
1317 memset(chap_table, 0, sizeof(struct ql4_chap_table)); 1317 chap_size = sizeof(struct ql4_chap_table);
1318 1318 memset(chap_table, 0, chap_size);
1319 offset = 0x06000000 | (idx * sizeof(struct ql4_chap_table)); 1319
1320 if (is_qla40XX(ha))
1321 offset = FLASH_CHAP_OFFSET | (idx * chap_size);
1322 else {
1323 offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);
1324 /* flt_chap_size is CHAP table size for both ports
1325 * so divide it by 2 to calculate the offset for second port
1326 */
1327 if (ha->port_num == 1)
1328 offset += (ha->hw.flt_chap_size / 2);
1329 offset += (idx * chap_size);
1330 }
1320 1331
1321 rval = qla4xxx_get_flash(ha, chap_dma, offset, 1332 rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);
1322 sizeof(struct ql4_chap_table));
1323 if (rval != QLA_SUCCESS) { 1333 if (rval != QLA_SUCCESS) {
1324 ret = -EINVAL; 1334 ret = -EINVAL;
1325 goto exit_get_chap; 1335 goto exit_get_chap;
@@ -1366,10 +1376,16 @@ static int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username,
1366 strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN); 1376 strncpy(chap_table->secret, password, MAX_CHAP_SECRET_LEN);
1367 strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN); 1377 strncpy(chap_table->name, username, MAX_CHAP_NAME_LEN);
1368 chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE); 1378 chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE);
1369 offset = 0x06000000 | (idx * sizeof(struct ql4_chap_table)); 1379 offset = FLASH_CHAP_OFFSET | (idx * sizeof(struct ql4_chap_table));
1370 rval = qla4xxx_set_flash(ha, chap_dma, offset, 1380 rval = qla4xxx_set_flash(ha, chap_dma, offset,
1371 sizeof(struct ql4_chap_table), 1381 sizeof(struct ql4_chap_table),
1372 FLASH_OPT_RMW_COMMIT); 1382 FLASH_OPT_RMW_COMMIT);
1383
1384 if (rval == QLA_SUCCESS && ha->chap_list) {
1385 /* Update ha chap_list cache */
1386 memcpy((struct ql4_chap_table *)ha->chap_list + idx,
1387 chap_table, sizeof(struct ql4_chap_table));
1388 }
1373 dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma); 1389 dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);
1374 if (rval != QLA_SUCCESS) 1390 if (rval != QLA_SUCCESS)
1375 ret = -EINVAL; 1391 ret = -EINVAL;
@@ -1378,6 +1394,83 @@ exit_set_chap:
1378 return ret; 1394 return ret;
1379} 1395}
1380 1396
1397/**
1398 * qla4xxx_get_chap_index - Get chap index given username and secret
1399 * @ha: pointer to adapter structure
1400 * @username: CHAP username to be searched
1401 * @password: CHAP password to be searched
1402 * @bidi: Is this a BIDI CHAP
1403 * @chap_index: CHAP index to be returned
1404 *
1405 * Match the username and password in the chap_list, return the index if a
1406 * match is found. If a match is not found then add the entry in FLASH and
1407 * return the index at which entry is written in the FLASH.
1408 **/
1409static int qla4xxx_get_chap_index(struct scsi_qla_host *ha, char *username,
1410 char *password, int bidi, uint16_t *chap_index)
1411{
1412 int i, rval;
1413 int free_index = -1;
1414 int found_index = 0;
1415 int max_chap_entries = 0;
1416 struct ql4_chap_table *chap_table;
1417
1418 if (is_qla8022(ha))
1419 max_chap_entries = (ha->hw.flt_chap_size / 2) /
1420 sizeof(struct ql4_chap_table);
1421 else
1422 max_chap_entries = MAX_CHAP_ENTRIES_40XX;
1423
1424 if (!ha->chap_list) {
1425 ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
1426 return QLA_ERROR;
1427 }
1428
1429 mutex_lock(&ha->chap_sem);
1430 for (i = 0; i < max_chap_entries; i++) {
1431 chap_table = (struct ql4_chap_table *)ha->chap_list + i;
1432 if (chap_table->cookie !=
1433 __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
1434 if (i > MAX_RESRV_CHAP_IDX && free_index == -1)
1435 free_index = i;
1436 continue;
1437 }
1438 if (bidi) {
1439 if (chap_table->flags & BIT_7)
1440 continue;
1441 } else {
1442 if (chap_table->flags & BIT_6)
1443 continue;
1444 }
1445 if (!strncmp(chap_table->secret, password,
1446 MAX_CHAP_SECRET_LEN) &&
1447 !strncmp(chap_table->name, username,
1448 MAX_CHAP_NAME_LEN)) {
1449 *chap_index = i;
1450 found_index = 1;
1451 break;
1452 }
1453 }
1454
1455 /* If chap entry is not present and a free index is available then
1456 * write the entry in flash
1457 */
1458 if (!found_index && free_index != -1) {
1459 rval = qla4xxx_set_chap(ha, username, password,
1460 free_index, bidi);
1461 if (!rval) {
1462 *chap_index = free_index;
1463 found_index = 1;
1464 }
1465 }
1466
1467 mutex_unlock(&ha->chap_sem);
1468
1469 if (found_index)
1470 return QLA_SUCCESS;
1471 return QLA_ERROR;
1472}
1473
1381int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha, 1474int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
1382 uint16_t fw_ddb_index, 1475 uint16_t fw_ddb_index,
1383 uint16_t connection_id, 1476 uint16_t connection_id,
@@ -1490,7 +1583,6 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
1490 uint16_t iscsi_opts = 0; 1583 uint16_t iscsi_opts = 0;
1491 uint32_t options = 0; 1584 uint32_t options = 0;
1492 uint16_t idx; 1585 uint16_t idx;
1493 int max_chap_entries = 0;
1494 1586
1495 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), 1587 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
1496 &fw_ddb_entry_dma, GFP_KERNEL); 1588 &fw_ddb_entry_dma, GFP_KERNEL);
@@ -1559,26 +1651,14 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
1559 goto exit_set_param; 1651 goto exit_set_param;
1560 } 1652 }
1561 1653
1562 if (is_qla8022(ha))
1563 max_chap_entries = MAX_CHAP_ENTRIES_82XX;
1564 else
1565 max_chap_entries = MAX_CHAP_ENTRIES_40XX;
1566 /* CHAP */ 1654 /* CHAP */
1567 if (sess->username != NULL && sess->password != NULL) { 1655 if (sess->username != NULL && sess->password != NULL) {
1568 if (strlen(sess->username) && strlen(sess->password)) { 1656 if (strlen(sess->username) && strlen(sess->password)) {
1569 iscsi_opts |= BIT_7; 1657 iscsi_opts |= BIT_7;
1570 idx = ddb_entry->fw_ddb_index * 2;
1571 if (idx > max_chap_entries) {
1572 ql4_printk(KERN_ERR, ha,
1573 "%s: Invalid ddb or chap index\n",
1574 __func__);
1575 rval = -EINVAL;
1576 goto exit_set_param;
1577 }
1578 1658
1579 rval = qla4xxx_set_chap(ha, sess->username, 1659 rval = qla4xxx_get_chap_index(ha, sess->username,
1580 sess->password, idx, 1660 sess->password,
1581 LOCAL_CHAP); 1661 LOCAL_CHAP, &idx);
1582 if (rval) 1662 if (rval)
1583 goto exit_set_param; 1663 goto exit_set_param;
1584 1664
@@ -1590,17 +1670,10 @@ int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
1590 /* Check if BIDI CHAP */ 1670 /* Check if BIDI CHAP */
1591 if (strlen(sess->username_in) && strlen(sess->password_in)) { 1671 if (strlen(sess->username_in) && strlen(sess->password_in)) {
1592 iscsi_opts |= BIT_4; 1672 iscsi_opts |= BIT_4;
1593 idx = (ddb_entry->fw_ddb_index * 2) + 1; 1673
1594 if (idx > max_chap_entries) { 1674 rval = qla4xxx_get_chap_index(ha, sess->username_in,
1595 ql4_printk(KERN_ERR, ha, 1675 sess->password_in,
1596 "%s: Invalid ddb or bidi chap " 1676 BIDI_CHAP, &idx);
1597 "index\n", __func__);
1598 rval = -EINVAL;
1599 goto exit_set_param;
1600 }
1601 rval = qla4xxx_set_chap(ha, sess->username_in,
1602 sess->password_in, idx,
1603 BIDI_CHAP);
1604 if (rval) 1677 if (rval)
1605 goto exit_set_param; 1678 goto exit_set_param;
1606 } 1679 }
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 84c254afac0a..f484ff438199 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -2024,6 +2024,10 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
2024 case FLT_REG_ISCSI_PARAM: 2024 case FLT_REG_ISCSI_PARAM:
2025 hw->flt_iscsi_param = start; 2025 hw->flt_iscsi_param = start;
2026 break; 2026 break;
2027 case FLT_REG_ISCSI_CHAP:
2028 hw->flt_region_chap = start;
2029 hw->flt_chap_size = le32_to_cpu(region->size);
2030 break;
2027 } 2031 }
2028 } 2032 }
2029 goto done; 2033 goto done;
@@ -2036,6 +2040,9 @@ no_flash_data:
2036 hw->flt_region_boot = FA_BOOT_CODE_ADDR_82; 2040 hw->flt_region_boot = FA_BOOT_CODE_ADDR_82;
2037 hw->flt_region_bootload = FA_BOOT_LOAD_ADDR_82; 2041 hw->flt_region_bootload = FA_BOOT_LOAD_ADDR_82;
2038 hw->flt_region_fw = FA_RISC_CODE_ADDR_82; 2042 hw->flt_region_fw = FA_RISC_CODE_ADDR_82;
2043 hw->flt_region_chap = FA_FLASH_ISCSI_CHAP;
2044 hw->flt_chap_size = FA_FLASH_CHAP_SIZE;
2045
2039done: 2046done:
2040 DEBUG2(ql4_printk(KERN_INFO, ha, "FLT[%s]: flt=0x%x fdt=0x%x " 2047 DEBUG2(ql4_printk(KERN_INFO, ha, "FLT[%s]: flt=0x%x fdt=0x%x "
2041 "boot=0x%x bootload=0x%x fw=0x%x\n", loc, hw->flt_region_flt, 2048 "boot=0x%x bootload=0x%x fw=0x%x\n", loc, hw->flt_region_flt,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index ce391d5511e3..874621db4a98 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -1605,6 +1605,10 @@ static void qla4xxx_mem_free(struct scsi_qla_host *ha)
1605 if (ha->chap_dma_pool) 1605 if (ha->chap_dma_pool)
1606 dma_pool_destroy(ha->chap_dma_pool); 1606 dma_pool_destroy(ha->chap_dma_pool);
1607 1607
1608 if (ha->chap_list)
1609 vfree(ha->chap_list);
1610 ha->chap_list = NULL;
1611
1608 /* release io space registers */ 1612 /* release io space registers */
1609 if (is_qla8022(ha)) { 1613 if (is_qla8022(ha)) {
1610 if (ha->nx_pcibase) 1614 if (ha->nx_pcibase)
@@ -3058,6 +3062,66 @@ kset_free:
3058 return -ENOMEM; 3062 return -ENOMEM;
3059} 3063}
3060 3064
3065
3066/**
3067 * qla4xxx_create chap_list - Create CHAP list from FLASH
3068 * @ha: pointer to adapter structure
3069 *
3070 * Read flash and make a list of CHAP entries, during login when a CHAP entry
3071 * is received, it will be checked in this list. If entry exist then the CHAP
3072 * entry index is set in the DDB. If CHAP entry does not exist in this list
3073 * then a new entry is added in FLASH in CHAP table and the index obtained is
3074 * used in the DDB.
3075 **/
3076static void qla4xxx_create_chap_list(struct scsi_qla_host *ha)
3077{
3078 int rval = 0;
3079 uint8_t *chap_flash_data = NULL;
3080 uint32_t offset;
3081 dma_addr_t chap_dma;
3082 uint32_t chap_size = 0;
3083
3084 if (is_qla40XX(ha))
3085 chap_size = MAX_CHAP_ENTRIES_40XX *
3086 sizeof(struct ql4_chap_table);
3087 else /* Single region contains CHAP info for both
3088 * ports which is divided into half for each port.
3089 */
3090 chap_size = ha->hw.flt_chap_size / 2;
3091
3092 chap_flash_data = dma_alloc_coherent(&ha->pdev->dev, chap_size,
3093 &chap_dma, GFP_KERNEL);
3094 if (!chap_flash_data) {
3095 ql4_printk(KERN_ERR, ha, "No memory for chap_flash_data\n");
3096 return;
3097 }
3098 if (is_qla40XX(ha))
3099 offset = FLASH_CHAP_OFFSET;
3100 else {
3101 offset = FLASH_RAW_ACCESS_ADDR + (ha->hw.flt_region_chap << 2);
3102 if (ha->port_num == 1)
3103 offset += chap_size;
3104 }
3105
3106 rval = qla4xxx_get_flash(ha, chap_dma, offset, chap_size);
3107 if (rval != QLA_SUCCESS)
3108 goto exit_chap_list;
3109
3110 if (ha->chap_list == NULL)
3111 ha->chap_list = vmalloc(chap_size);
3112 if (ha->chap_list == NULL) {
3113 ql4_printk(KERN_ERR, ha, "No memory for ha->chap_list\n");
3114 goto exit_chap_list;
3115 }
3116
3117 memcpy(ha->chap_list, chap_flash_data, chap_size);
3118
3119exit_chap_list:
3120 dma_free_coherent(&ha->pdev->dev, chap_size,
3121 chap_flash_data, chap_dma);
3122 return;
3123}
3124
3061/** 3125/**
3062 * qla4xxx_probe_adapter - callback function to probe HBA 3126 * qla4xxx_probe_adapter - callback function to probe HBA
3063 * @pdev: pointer to pci_dev structure 3127 * @pdev: pointer to pci_dev structure
@@ -3135,6 +3199,7 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3135 INIT_LIST_HEAD(&ha->free_srb_q); 3199 INIT_LIST_HEAD(&ha->free_srb_q);
3136 3200
3137 mutex_init(&ha->mbox_sem); 3201 mutex_init(&ha->mbox_sem);
3202 mutex_init(&ha->chap_sem);
3138 init_completion(&ha->mbx_intr_comp); 3203 init_completion(&ha->mbx_intr_comp);
3139 init_completion(&ha->disable_acb_comp); 3204 init_completion(&ha->disable_acb_comp);
3140 3205
@@ -3266,6 +3331,8 @@ static int __devinit qla4xxx_probe_adapter(struct pci_dev *pdev,
3266 ha->host_no, ha->firmware_version[0], ha->firmware_version[1], 3331 ha->host_no, ha->firmware_version[0], ha->firmware_version[1],
3267 ha->patch_number, ha->build_number); 3332 ha->patch_number, ha->build_number);
3268 3333
3334 qla4xxx_create_chap_list(ha);
3335
3269 if (qla4xxx_setup_boot_info(ha)) 3336 if (qla4xxx_setup_boot_info(ha))
3270 ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n", 3337 ql4_printk(KERN_ERR, ha, "%s:ISCSI boot info setup failed\n",
3271 __func__); 3338 __func__);