aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdheer Chandravanshi <adheer.chandravanshi@qlogic.com>2013-03-22 07:41:31 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-04-11 18:32:26 -0400
commit1e9e2be3ee03b8b5c6066d3943c9c5ab1632ed0a (patch)
treefebbbde85d138c7926a6fea8ea14409d83755231
parentadaf6990ddf50b301c38eda7c0cb7b182df01c3b (diff)
[SCSI] qla4xxx: Add flash node mgmt support
This patch allows iscsiadm to manage iSCSI target information stored on qla4xxx adapter flash on per host basis. Signed-off-by: Adheer Chandravanshi <adheer.chandravanshi@qlogic.com> Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com> Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r--drivers/scsi/qla4xxx/ql4_def.h22
-rw-r--r--drivers/scsi/qla4xxx/ql4_fw.h34
-rw-r--r--drivers/scsi/qla4xxx/ql4_glbl.h7
-rw-r--r--drivers/scsi/qla4xxx/ql4_mbx.c106
-rw-r--r--drivers/scsi/qla4xxx/ql4_nx.c12
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c1647
6 files changed, 1824 insertions, 4 deletions
diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h
index 129f5dd02822..b487b0aa4dee 100644
--- a/drivers/scsi/qla4xxx/ql4_def.h
+++ b/drivers/scsi/qla4xxx/ql4_def.h
@@ -159,6 +159,25 @@
159#define LSDW(x) ((u32)((u64)(x))) 159#define LSDW(x) ((u32)((u64)(x)))
160#define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16)) 160#define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16))
161 161
162#define DEV_TYPE_IPV4 "ipv4"
163#define DEV_TYPE_IPV6 "ipv6"
164
165#define DEV_DB_NON_PERSISTENT 0
166#define DEV_DB_PERSISTENT 1
167
168#define COPY_ISID(dst_isid, src_isid) { \
169 int i, j; \
170 for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \
171 dst_isid[i++] = src_isid[j--]; \
172}
173
174#define SET_BITVAL(o, n, v) { \
175 if (o) \
176 n |= v; \
177 else \
178 n &= ~v; \
179}
180
162/* 181/*
163 * Retry & Timeout Values 182 * Retry & Timeout Values
164 */ 183 */
@@ -363,6 +382,8 @@ struct ql82xx_hw_data {
363 uint32_t flt_iscsi_param; 382 uint32_t flt_iscsi_param;
364 uint32_t flt_region_chap; 383 uint32_t flt_region_chap;
365 uint32_t flt_chap_size; 384 uint32_t flt_chap_size;
385 uint32_t flt_region_ddb;
386 uint32_t flt_ddb_size;
366}; 387};
367 388
368struct qla4_8xxx_legacy_intr_set { 389struct qla4_8xxx_legacy_intr_set {
@@ -501,6 +522,7 @@ struct scsi_qla_host {
501#define AF_INIT_DONE 1 /* 0x00000002 */ 522#define AF_INIT_DONE 1 /* 0x00000002 */
502#define AF_MBOX_COMMAND 2 /* 0x00000004 */ 523#define AF_MBOX_COMMAND 2 /* 0x00000004 */
503#define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */ 524#define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */
525#define AF_ST_DISCOVERY_IN_PROGRESS 4 /* 0x00000010 */
504#define AF_INTERRUPTS_ON 6 /* 0x00000040 */ 526#define AF_INTERRUPTS_ON 6 /* 0x00000040 */
505#define AF_GET_CRASH_RECORD 7 /* 0x00000080 */ 527#define AF_GET_CRASH_RECORD 7 /* 0x00000080 */
506#define AF_LINK_UP 8 /* 0x00000100 */ 528#define AF_LINK_UP 8 /* 0x00000100 */
diff --git a/drivers/scsi/qla4xxx/ql4_fw.h b/drivers/scsi/qla4xxx/ql4_fw.h
index ad9d2e2d370f..5945829d662f 100644
--- a/drivers/scsi/qla4xxx/ql4_fw.h
+++ b/drivers/scsi/qla4xxx/ql4_fw.h
@@ -288,6 +288,8 @@ union external_hw_config_reg {
288#define FA_GOLD_RISC_CODE_ADDR_82 0x80000 288#define FA_GOLD_RISC_CODE_ADDR_82 0x80000
289#define FA_FLASH_ISCSI_CHAP 0x540000 289#define FA_FLASH_ISCSI_CHAP 0x540000
290#define FA_FLASH_CHAP_SIZE 0xC0000 290#define FA_FLASH_CHAP_SIZE 0xC0000
291#define FA_FLASH_ISCSI_DDB 0x420000
292#define FA_FLASH_DDB_SIZE 0x080000
291 293
292/* Flash Description Table */ 294/* Flash Description Table */
293struct qla_fdt_layout { 295struct qla_fdt_layout {
@@ -348,6 +350,7 @@ struct qla_flt_header {
348#define FLT_REG_BOOT_CODE_82 0x78 350#define FLT_REG_BOOT_CODE_82 0x78
349#define FLT_REG_ISCSI_PARAM 0x65 351#define FLT_REG_ISCSI_PARAM 0x65
350#define FLT_REG_ISCSI_CHAP 0x63 352#define FLT_REG_ISCSI_CHAP 0x63
353#define FLT_REG_ISCSI_DDB 0x6A
351 354
352struct qla_flt_region { 355struct qla_flt_region {
353 uint32_t code; 356 uint32_t code;
@@ -779,12 +782,41 @@ struct dev_db_entry {
779#define DDB_OPT_IPV6_NULL_LINK_LOCAL 0x800 /* post connection */ 782#define DDB_OPT_IPV6_NULL_LINK_LOCAL 0x800 /* post connection */
780#define DDB_OPT_IPV6_FW_DEFINED_LINK_LOCAL 0x800 /* pre connection */ 783#define DDB_OPT_IPV6_FW_DEFINED_LINK_LOCAL 0x800 /* pre connection */
781 784
785#define OPT_IS_FW_ASSIGNED_IPV6 11
786#define OPT_IPV6_DEVICE 8
787#define OPT_AUTO_SENDTGTS_DISABLE 6
788#define OPT_DISC_SESSION 4
789#define OPT_ENTRY_STATE 3
782 uint16_t exec_throttle; /* 02-03 */ 790 uint16_t exec_throttle; /* 02-03 */
783 uint16_t exec_count; /* 04-05 */ 791 uint16_t exec_count; /* 04-05 */
784 uint16_t res0; /* 06-07 */ 792 uint16_t res0; /* 06-07 */
785 uint16_t iscsi_options; /* 08-09 */ 793 uint16_t iscsi_options; /* 08-09 */
794#define ISCSIOPT_HEADER_DIGEST_EN 13
795#define ISCSIOPT_DATA_DIGEST_EN 12
796#define ISCSIOPT_IMMEDIATE_DATA_EN 11
797#define ISCSIOPT_INITIAL_R2T_EN 10
798#define ISCSIOPT_DATA_SEQ_IN_ORDER 9
799#define ISCSIOPT_DATA_PDU_IN_ORDER 8
800#define ISCSIOPT_CHAP_AUTH_EN 7
801#define ISCSIOPT_SNACK_REQ_EN 6
802#define ISCSIOPT_DISCOVERY_LOGOUT_EN 5
803#define ISCSIOPT_BIDI_CHAP_EN 4
804#define ISCSIOPT_DISCOVERY_AUTH_OPTIONAL 3
805#define ISCSIOPT_ERL1 1
806#define ISCSIOPT_ERL0 0
807
786 uint16_t tcp_options; /* 0A-0B */ 808 uint16_t tcp_options; /* 0A-0B */
809#define TCPOPT_TIMESTAMP_STAT 6
810#define TCPOPT_NAGLE_DISABLE 5
811#define TCPOPT_WSF_DISABLE 4
812#define TCPOPT_TIMER_SCALE3 3
813#define TCPOPT_TIMER_SCALE2 2
814#define TCPOPT_TIMER_SCALE1 1
815#define TCPOPT_TIMESTAMP_EN 0
816
787 uint16_t ip_options; /* 0C-0D */ 817 uint16_t ip_options; /* 0C-0D */
818#define IPOPT_FRAGMENT_DISABLE 4
819
788 uint16_t iscsi_max_rcv_data_seg_len; /* 0E-0F */ 820 uint16_t iscsi_max_rcv_data_seg_len; /* 0E-0F */
789#define BYTE_UNITS 512 821#define BYTE_UNITS 512
790 uint32_t res1; /* 10-13 */ 822 uint32_t res1; /* 10-13 */
@@ -816,6 +848,8 @@ struct dev_db_entry {
816 * much RAM */ 848 * much RAM */
817 uint8_t link_local_ipv6_addr[0x10]; /* 1A0-1AF */ 849 uint8_t link_local_ipv6_addr[0x10]; /* 1A0-1AF */
818 uint8_t res5[0x10]; /* 1B0-1BF */ 850 uint8_t res5[0x10]; /* 1B0-1BF */
851#define DDB_NO_LINK 0xFFFF
852#define DDB_ISNS 0xFFFD
819 uint16_t ddb_link; /* 1C0-1C1 */ 853 uint16_t ddb_link; /* 1C0-1C1 */
820 uint16_t chap_tbl_idx; /* 1C2-1C3 */ 854 uint16_t chap_tbl_idx; /* 1C2-1C3 */
821 uint16_t tgt_portal_grp; /* 1C4-1C5 */ 855 uint16_t tgt_portal_grp; /* 1C4-1C5 */
diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h
index 22706f66266f..4a428009f699 100644
--- a/drivers/scsi/qla4xxx/ql4_glbl.h
+++ b/drivers/scsi/qla4xxx/ql4_glbl.h
@@ -191,6 +191,9 @@ int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
191int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha, 191int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
192 uint32_t status, uint32_t pid, 192 uint32_t status, uint32_t pid,
193 uint32_t data_size, uint8_t *data); 193 uint32_t data_size, uint8_t *data);
194int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
195 struct dev_db_entry *fw_ddb_entry,
196 dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index);
194 197
195/* BSG Functions */ 198/* BSG Functions */
196int qla4xxx_bsg_request(struct bsg_job *bsg_job); 199int qla4xxx_bsg_request(struct bsg_job *bsg_job);
@@ -259,6 +262,10 @@ int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha);
259void qla4_83xx_disable_pause(struct scsi_qla_host *ha); 262void qla4_83xx_disable_pause(struct scsi_qla_host *ha);
260void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha); 263void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha);
261int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha); 264int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha);
265int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
266 dma_addr_t dma_addr);
267int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
268 char *password, uint16_t chap_index);
262 269
263extern int ql4xextended_error_logging; 270extern int ql4xextended_error_logging;
264extern int ql4xdontresethba; 271extern int ql4xdontresethba;
diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c
index ce4654501fab..8985997de576 100644
--- a/drivers/scsi/qla4xxx/ql4_mbx.c
+++ b/drivers/scsi/qla4xxx/ql4_mbx.c
@@ -1288,8 +1288,8 @@ exit_about_fw:
1288 return status; 1288 return status;
1289} 1289}
1290 1290
1291static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options, 1291int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
1292 dma_addr_t dma_addr) 1292 dma_addr_t dma_addr)
1293{ 1293{
1294 uint32_t mbox_cmd[MBOX_REG_COUNT]; 1294 uint32_t mbox_cmd[MBOX_REG_COUNT];
1295 uint32_t mbox_sts[MBOX_REG_COUNT]; 1295 uint32_t mbox_sts[MBOX_REG_COUNT];
@@ -1417,6 +1417,52 @@ exit_bootdb_failed:
1417 return status; 1417 return status;
1418} 1418}
1419 1419
1420int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
1421 struct dev_db_entry *fw_ddb_entry,
1422 dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)
1423{
1424 uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;
1425 uint32_t dev_db_end_offset;
1426 int status = QLA_ERROR;
1427
1428 memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));
1429
1430 if (is_qla40XX(ha)) {
1431 dev_db_start_offset = FLASH_OFFSET_DB_INFO;
1432 } else {
1433 dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +
1434 (ha->hw.flt_region_ddb << 2);
1435 /* flt_ddb_size is DDB table size for both ports
1436 * so divide it by 2 to calculate the offset for second port
1437 */
1438 if (ha->port_num == 1)
1439 dev_db_start_offset += (ha->hw.flt_ddb_size / 2);
1440 }
1441
1442 dev_db_end_offset = dev_db_start_offset + (ha->hw.flt_ddb_size / 2);
1443 dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));
1444
1445 if (dev_db_start_offset > dev_db_end_offset) {
1446 DEBUG2(ql4_printk(KERN_ERR, ha,
1447 "%s:Invalid DDB index %d", __func__,
1448 ddb_index));
1449 goto exit_fdb_failed;
1450 }
1451
1452 if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
1453 sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {
1454 ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash failed\n",
1455 ha->host_no, __func__);
1456 goto exit_fdb_failed;
1457 }
1458
1459 if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
1460 status = QLA_SUCCESS;
1461
1462exit_fdb_failed:
1463 return status;
1464}
1465
1420int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password, 1466int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
1421 uint16_t idx) 1467 uint16_t idx)
1422{ 1468{
@@ -1510,6 +1556,62 @@ exit_set_chap:
1510 return ret; 1556 return ret;
1511} 1557}
1512 1558
1559
1560int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
1561 char *password, uint16_t chap_index)
1562{
1563 int rval = QLA_ERROR;
1564 struct ql4_chap_table *chap_table = NULL;
1565 int max_chap_entries;
1566
1567 if (!ha->chap_list) {
1568 ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
1569 rval = QLA_ERROR;
1570 goto exit_uni_chap;
1571 }
1572
1573 if (!username || !password) {
1574 ql4_printk(KERN_ERR, ha, "No memory for username & secret\n");
1575 rval = QLA_ERROR;
1576 goto exit_uni_chap;
1577 }
1578
1579 if (is_qla80XX(ha))
1580 max_chap_entries = (ha->hw.flt_chap_size / 2) /
1581 sizeof(struct ql4_chap_table);
1582 else
1583 max_chap_entries = MAX_CHAP_ENTRIES_40XX;
1584
1585 if (chap_index > max_chap_entries) {
1586 ql4_printk(KERN_ERR, ha, "Invalid Chap index\n");
1587 rval = QLA_ERROR;
1588 goto exit_uni_chap;
1589 }
1590
1591 mutex_lock(&ha->chap_sem);
1592 chap_table = (struct ql4_chap_table *)ha->chap_list + chap_index;
1593 if (chap_table->cookie != __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
1594 rval = QLA_ERROR;
1595 goto exit_unlock_uni_chap;
1596 }
1597
1598 if (!(chap_table->flags & BIT_6)) {
1599 ql4_printk(KERN_ERR, ha, "Unidirectional entry not set\n");
1600 rval = QLA_ERROR;
1601 goto exit_unlock_uni_chap;
1602 }
1603
1604 strncpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN);
1605 strncpy(username, chap_table->name, MAX_CHAP_NAME_LEN);
1606
1607 rval = QLA_SUCCESS;
1608
1609exit_unlock_uni_chap:
1610 mutex_unlock(&ha->chap_sem);
1611exit_uni_chap:
1612 return rval;
1613}
1614
1513/** 1615/**
1514 * qla4xxx_get_chap_index - Get chap index given username and secret 1616 * qla4xxx_get_chap_index - Get chap index given username and secret
1515 * @ha: pointer to adapter structure 1617 * @ha: pointer to adapter structure
diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c
index 31fac90e54e2..5f1dbb7c7bef 100644
--- a/drivers/scsi/qla4xxx/ql4_nx.c
+++ b/drivers/scsi/qla4xxx/ql4_nx.c
@@ -3154,6 +3154,10 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
3154 hw->flt_region_chap = start; 3154 hw->flt_region_chap = start;
3155 hw->flt_chap_size = le32_to_cpu(region->size); 3155 hw->flt_chap_size = le32_to_cpu(region->size);
3156 break; 3156 break;
3157 case FLT_REG_ISCSI_DDB:
3158 hw->flt_region_ddb = start;
3159 hw->flt_ddb_size = le32_to_cpu(region->size);
3160 break;
3157 } 3161 }
3158 } 3162 }
3159 goto done; 3163 goto done;
@@ -3168,13 +3172,17 @@ no_flash_data:
3168 hw->flt_region_fw = FA_RISC_CODE_ADDR_82; 3172 hw->flt_region_fw = FA_RISC_CODE_ADDR_82;
3169 hw->flt_region_chap = FA_FLASH_ISCSI_CHAP >> 2; 3173 hw->flt_region_chap = FA_FLASH_ISCSI_CHAP >> 2;
3170 hw->flt_chap_size = FA_FLASH_CHAP_SIZE; 3174 hw->flt_chap_size = FA_FLASH_CHAP_SIZE;
3175 hw->flt_region_ddb = FA_FLASH_ISCSI_DDB >> 2;
3176 hw->flt_ddb_size = FA_FLASH_DDB_SIZE;
3171 3177
3172done: 3178done:
3173 DEBUG2(ql4_printk(KERN_INFO, ha, 3179 DEBUG2(ql4_printk(KERN_INFO, ha,
3174 "FLT[%s]: flt=0x%x fdt=0x%x boot=0x%x bootload=0x%x fw=0x%x chap=0x%x\n", 3180 "FLT[%s]: flt=0x%x fdt=0x%x boot=0x%x bootload=0x%x fw=0x%x chap=0x%x chap_size=0x%x ddb=0x%x ddb_size=0x%x\n",
3175 loc, hw->flt_region_flt, hw->flt_region_fdt, 3181 loc, hw->flt_region_flt, hw->flt_region_fdt,
3176 hw->flt_region_boot, hw->flt_region_bootload, 3182 hw->flt_region_boot, hw->flt_region_bootload,
3177 hw->flt_region_fw, hw->flt_region_chap)); 3183 hw->flt_region_fw, hw->flt_region_chap,
3184 hw->flt_chap_size, hw->flt_region_ddb,
3185 hw->flt_ddb_size));
3178} 3186}
3179 3187
3180static void 3188static void
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index f3cf04ebf516..497ac681d733 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -166,6 +166,26 @@ static int qla4xxx_host_reset(struct Scsi_Host *shost, int reset_type);
166static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth, 166static int qla4xxx_change_queue_depth(struct scsi_device *sdev, int qdepth,
167 int reason); 167 int reason);
168 168
169/*
170 * iSCSI Flash DDB sysfs entry points
171 */
172static int
173qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,
174 struct iscsi_bus_flash_conn *fnode_conn,
175 void *data, int len);
176static int
177qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
178 int param, char *buf);
179static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,
180 int len);
181static int
182qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess);
183static int qla4xxx_sysfs_ddb_login(struct iscsi_bus_flash_session *fnode_sess,
184 struct iscsi_bus_flash_conn *fnode_conn);
185static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess,
186 struct iscsi_bus_flash_conn *fnode_conn);
187static int qla4xxx_sysfs_ddb_logout_sid(struct iscsi_cls_session *cls_sess);
188
169static struct qla4_8xxx_legacy_intr_set legacy_intr[] = 189static struct qla4_8xxx_legacy_intr_set legacy_intr[] =
170 QLA82XX_LEGACY_INTR_CONFIG; 190 QLA82XX_LEGACY_INTR_CONFIG;
171 191
@@ -232,6 +252,13 @@ static struct iscsi_transport qla4xxx_iscsi_transport = {
232 .send_ping = qla4xxx_send_ping, 252 .send_ping = qla4xxx_send_ping,
233 .get_chap = qla4xxx_get_chap_list, 253 .get_chap = qla4xxx_get_chap_list,
234 .delete_chap = qla4xxx_delete_chap, 254 .delete_chap = qla4xxx_delete_chap,
255 .get_flashnode_param = qla4xxx_sysfs_ddb_get_param,
256 .set_flashnode_param = qla4xxx_sysfs_ddb_set_param,
257 .new_flashnode = qla4xxx_sysfs_ddb_add,
258 .del_flashnode = qla4xxx_sysfs_ddb_delete,
259 .login_flashnode = qla4xxx_sysfs_ddb_login,
260 .logout_flashnode = qla4xxx_sysfs_ddb_logout,
261 .logout_flashnode_sid = qla4xxx_sysfs_ddb_logout_sid,
235}; 262};
236 263
237static struct scsi_transport_template *qla4xxx_scsi_transport; 264static struct scsi_transport_template *qla4xxx_scsi_transport;
@@ -376,6 +403,68 @@ static umode_t qla4_attr_is_visible(int param_type, int param)
376 default: 403 default:
377 return 0; 404 return 0;
378 } 405 }
406 case ISCSI_FLASHNODE_PARAM:
407 switch (param) {
408 case ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6:
409 case ISCSI_FLASHNODE_PORTAL_TYPE:
410 case ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE:
411 case ISCSI_FLASHNODE_DISCOVERY_SESS:
412 case ISCSI_FLASHNODE_ENTRY_EN:
413 case ISCSI_FLASHNODE_HDR_DGST_EN:
414 case ISCSI_FLASHNODE_DATA_DGST_EN:
415 case ISCSI_FLASHNODE_IMM_DATA_EN:
416 case ISCSI_FLASHNODE_INITIAL_R2T_EN:
417 case ISCSI_FLASHNODE_DATASEQ_INORDER:
418 case ISCSI_FLASHNODE_PDU_INORDER:
419 case ISCSI_FLASHNODE_CHAP_AUTH_EN:
420 case ISCSI_FLASHNODE_SNACK_REQ_EN:
421 case ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN:
422 case ISCSI_FLASHNODE_BIDI_CHAP_EN:
423 case ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL:
424 case ISCSI_FLASHNODE_ERL:
425 case ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT:
426 case ISCSI_FLASHNODE_TCP_NAGLE_DISABLE:
427 case ISCSI_FLASHNODE_TCP_WSF_DISABLE:
428 case ISCSI_FLASHNODE_TCP_TIMER_SCALE:
429 case ISCSI_FLASHNODE_TCP_TIMESTAMP_EN:
430 case ISCSI_FLASHNODE_IP_FRAG_DISABLE:
431 case ISCSI_FLASHNODE_MAX_RECV_DLENGTH:
432 case ISCSI_FLASHNODE_MAX_XMIT_DLENGTH:
433 case ISCSI_FLASHNODE_FIRST_BURST:
434 case ISCSI_FLASHNODE_DEF_TIME2WAIT:
435 case ISCSI_FLASHNODE_DEF_TIME2RETAIN:
436 case ISCSI_FLASHNODE_MAX_R2T:
437 case ISCSI_FLASHNODE_KEEPALIVE_TMO:
438 case ISCSI_FLASHNODE_ISID:
439 case ISCSI_FLASHNODE_TSID:
440 case ISCSI_FLASHNODE_PORT:
441 case ISCSI_FLASHNODE_MAX_BURST:
442 case ISCSI_FLASHNODE_DEF_TASKMGMT_TMO:
443 case ISCSI_FLASHNODE_IPADDR:
444 case ISCSI_FLASHNODE_ALIAS:
445 case ISCSI_FLASHNODE_REDIRECT_IPADDR:
446 case ISCSI_FLASHNODE_MAX_SEGMENT_SIZE:
447 case ISCSI_FLASHNODE_LOCAL_PORT:
448 case ISCSI_FLASHNODE_IPV4_TOS:
449 case ISCSI_FLASHNODE_IPV6_TC:
450 case ISCSI_FLASHNODE_IPV6_FLOW_LABEL:
451 case ISCSI_FLASHNODE_NAME:
452 case ISCSI_FLASHNODE_TPGT:
453 case ISCSI_FLASHNODE_LINK_LOCAL_IPV6:
454 case ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX:
455 case ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE:
456 case ISCSI_FLASHNODE_TCP_XMIT_WSF:
457 case ISCSI_FLASHNODE_TCP_RECV_WSF:
458 case ISCSI_FLASHNODE_CHAP_OUT_IDX:
459 case ISCSI_FLASHNODE_USERNAME:
460 case ISCSI_FLASHNODE_PASSWORD:
461 case ISCSI_FLASHNODE_STATSN:
462 case ISCSI_FLASHNODE_EXP_STATSN:
463 case ISCSI_FLASHNODE_IS_BOOT_TGT:
464 return S_IRUGO;
465 default:
466 return 0;
467 }
379 } 468 }
380 469
381 return 0; 470 return 0;
@@ -1922,6 +2011,250 @@ static int qla4xxx_task_xmit(struct iscsi_task *task)
1922 return -ENOSYS; 2011 return -ENOSYS;
1923} 2012}
1924 2013
2014static int qla4xxx_copy_from_fwddb_param(struct iscsi_bus_flash_session *sess,
2015 struct iscsi_bus_flash_conn *conn,
2016 struct dev_db_entry *fw_ddb_entry)
2017{
2018 unsigned long options = 0;
2019 int rc = 0;
2020
2021 options = le16_to_cpu(fw_ddb_entry->options);
2022 conn->is_fw_assigned_ipv6 = test_bit(OPT_IS_FW_ASSIGNED_IPV6, &options);
2023 if (test_bit(OPT_IPV6_DEVICE, &options)) {
2024 rc = iscsi_switch_str_param(&sess->portal_type, DEV_TYPE_IPV6);
2025 if (rc)
2026 goto exit_copy;
2027 } else {
2028 rc = iscsi_switch_str_param(&sess->portal_type, DEV_TYPE_IPV4);
2029 if (rc)
2030 goto exit_copy;
2031 }
2032
2033 sess->auto_snd_tgt_disable = test_bit(OPT_AUTO_SENDTGTS_DISABLE,
2034 &options);
2035 sess->discovery_sess = test_bit(OPT_DISC_SESSION, &options);
2036 sess->entry_state = test_bit(OPT_ENTRY_STATE, &options);
2037
2038 options = le16_to_cpu(fw_ddb_entry->iscsi_options);
2039 conn->hdrdgst_en = test_bit(ISCSIOPT_HEADER_DIGEST_EN, &options);
2040 conn->datadgst_en = test_bit(ISCSIOPT_DATA_DIGEST_EN, &options);
2041 sess->imm_data_en = test_bit(ISCSIOPT_IMMEDIATE_DATA_EN, &options);
2042 sess->initial_r2t_en = test_bit(ISCSIOPT_INITIAL_R2T_EN, &options);
2043 sess->dataseq_inorder_en = test_bit(ISCSIOPT_DATA_SEQ_IN_ORDER,
2044 &options);
2045 sess->pdu_inorder_en = test_bit(ISCSIOPT_DATA_PDU_IN_ORDER, &options);
2046 sess->chap_auth_en = test_bit(ISCSIOPT_CHAP_AUTH_EN, &options);
2047 conn->snack_req_en = test_bit(ISCSIOPT_SNACK_REQ_EN, &options);
2048 sess->discovery_logout_en = test_bit(ISCSIOPT_DISCOVERY_LOGOUT_EN,
2049 &options);
2050 sess->bidi_chap_en = test_bit(ISCSIOPT_BIDI_CHAP_EN, &options);
2051 sess->discovery_auth_optional =
2052 test_bit(ISCSIOPT_DISCOVERY_AUTH_OPTIONAL, &options);
2053 if (test_bit(ISCSIOPT_ERL1, &options))
2054 sess->erl |= BIT_1;
2055 if (test_bit(ISCSIOPT_ERL0, &options))
2056 sess->erl |= BIT_0;
2057
2058 options = le16_to_cpu(fw_ddb_entry->tcp_options);
2059 conn->tcp_timestamp_stat = test_bit(TCPOPT_TIMESTAMP_STAT, &options);
2060 conn->tcp_nagle_disable = test_bit(TCPOPT_NAGLE_DISABLE, &options);
2061 conn->tcp_wsf_disable = test_bit(TCPOPT_WSF_DISABLE, &options);
2062 if (test_bit(TCPOPT_TIMER_SCALE3, &options))
2063 conn->tcp_timer_scale |= BIT_3;
2064 if (test_bit(TCPOPT_TIMER_SCALE2, &options))
2065 conn->tcp_timer_scale |= BIT_2;
2066 if (test_bit(TCPOPT_TIMER_SCALE1, &options))
2067 conn->tcp_timer_scale |= BIT_1;
2068
2069 conn->tcp_timer_scale >>= 1;
2070 conn->tcp_timestamp_en = test_bit(TCPOPT_TIMESTAMP_EN, &options);
2071
2072 options = le16_to_cpu(fw_ddb_entry->ip_options);
2073 conn->fragment_disable = test_bit(IPOPT_FRAGMENT_DISABLE, &options);
2074
2075 conn->max_recv_dlength = BYTE_UNITS *
2076 le16_to_cpu(fw_ddb_entry->iscsi_max_rcv_data_seg_len);
2077 conn->max_xmit_dlength = BYTE_UNITS *
2078 le16_to_cpu(fw_ddb_entry->iscsi_max_snd_data_seg_len);
2079 sess->first_burst = BYTE_UNITS *
2080 le16_to_cpu(fw_ddb_entry->iscsi_first_burst_len);
2081 sess->max_burst = BYTE_UNITS *
2082 le16_to_cpu(fw_ddb_entry->iscsi_max_burst_len);
2083 sess->max_r2t = le16_to_cpu(fw_ddb_entry->iscsi_max_outsnd_r2t);
2084 sess->time2wait = le16_to_cpu(fw_ddb_entry->iscsi_def_time2wait);
2085 sess->time2retain = le16_to_cpu(fw_ddb_entry->iscsi_def_time2retain);
2086 sess->tpgt = le32_to_cpu(fw_ddb_entry->tgt_portal_grp);
2087 conn->max_segment_size = le16_to_cpu(fw_ddb_entry->mss);
2088 conn->tcp_xmit_wsf = fw_ddb_entry->tcp_xmt_wsf;
2089 conn->tcp_recv_wsf = fw_ddb_entry->tcp_rcv_wsf;
2090 conn->ipv6_flow_label = le16_to_cpu(fw_ddb_entry->ipv6_flow_lbl);
2091 conn->keepalive_timeout = le16_to_cpu(fw_ddb_entry->ka_timeout);
2092 conn->local_port = le16_to_cpu(fw_ddb_entry->lcl_port);
2093 conn->statsn = le32_to_cpu(fw_ddb_entry->stat_sn);
2094 conn->exp_statsn = le32_to_cpu(fw_ddb_entry->exp_stat_sn);
2095 sess->discovery_parent_idx = le16_to_cpu(fw_ddb_entry->ddb_link);
2096 sess->discovery_parent_type = le16_to_cpu(fw_ddb_entry->ddb_link);
2097 sess->chap_out_idx = le16_to_cpu(fw_ddb_entry->chap_tbl_idx);
2098 sess->tsid = le16_to_cpu(fw_ddb_entry->tsid);
2099
2100 sess->default_taskmgmt_timeout =
2101 le16_to_cpu(fw_ddb_entry->def_timeout);
2102 conn->port = le16_to_cpu(fw_ddb_entry->port);
2103
2104 options = le16_to_cpu(fw_ddb_entry->options);
2105 conn->ipaddress = kzalloc(IPv6_ADDR_LEN, GFP_KERNEL);
2106 if (!conn->ipaddress) {
2107 rc = -ENOMEM;
2108 goto exit_copy;
2109 }
2110
2111 conn->redirect_ipaddr = kzalloc(IPv6_ADDR_LEN, GFP_KERNEL);
2112 if (!conn->redirect_ipaddr) {
2113 rc = -ENOMEM;
2114 goto exit_copy;
2115 }
2116
2117 memcpy(conn->ipaddress, fw_ddb_entry->ip_addr, IPv6_ADDR_LEN);
2118 memcpy(conn->redirect_ipaddr, fw_ddb_entry->tgt_addr, IPv6_ADDR_LEN);
2119
2120 if (test_bit(OPT_IPV6_DEVICE, &options)) {
2121 conn->ipv6_traffic_class = fw_ddb_entry->ipv4_tos;
2122
2123 conn->link_local_ipv6_addr = kzalloc(IPv6_ADDR_LEN, GFP_KERNEL);
2124 if (!conn->link_local_ipv6_addr) {
2125 rc = -ENOMEM;
2126 goto exit_copy;
2127 }
2128
2129 memcpy(conn->link_local_ipv6_addr,
2130 fw_ddb_entry->link_local_ipv6_addr, IPv6_ADDR_LEN);
2131 } else {
2132 conn->ipv4_tos = fw_ddb_entry->ipv4_tos;
2133 }
2134
2135 if (fw_ddb_entry->iscsi_name[0]) {
2136 rc = iscsi_switch_str_param(&sess->targetname,
2137 (char *)fw_ddb_entry->iscsi_name);
2138 if (rc)
2139 goto exit_copy;
2140 }
2141
2142 if (fw_ddb_entry->iscsi_alias[0]) {
2143 rc = iscsi_switch_str_param(&sess->targetalias,
2144 (char *)fw_ddb_entry->iscsi_alias);
2145 if (rc)
2146 goto exit_copy;
2147 }
2148
2149 COPY_ISID(sess->isid, fw_ddb_entry->isid);
2150
2151exit_copy:
2152 return rc;
2153}
2154
2155static int qla4xxx_copy_to_fwddb_param(struct iscsi_bus_flash_session *sess,
2156 struct iscsi_bus_flash_conn *conn,
2157 struct dev_db_entry *fw_ddb_entry)
2158{
2159 uint16_t options;
2160 int rc = 0;
2161
2162 options = le16_to_cpu(fw_ddb_entry->options);
2163 SET_BITVAL(conn->is_fw_assigned_ipv6, options, BIT_11);
2164 if (!strncmp(sess->portal_type, DEV_TYPE_IPV6, 4))
2165 options |= BIT_8;
2166 else
2167 options &= ~BIT_8;
2168
2169 SET_BITVAL(sess->auto_snd_tgt_disable, options, BIT_6);
2170 SET_BITVAL(sess->discovery_sess, options, BIT_4);
2171 SET_BITVAL(sess->entry_state, options, BIT_3);
2172 fw_ddb_entry->options = cpu_to_le16(options);
2173
2174 options = le16_to_cpu(fw_ddb_entry->iscsi_options);
2175 SET_BITVAL(conn->hdrdgst_en, options, BIT_13);
2176 SET_BITVAL(conn->datadgst_en, options, BIT_12);
2177 SET_BITVAL(sess->imm_data_en, options, BIT_11);
2178 SET_BITVAL(sess->initial_r2t_en, options, BIT_10);
2179 SET_BITVAL(sess->dataseq_inorder_en, options, BIT_9);
2180 SET_BITVAL(sess->pdu_inorder_en, options, BIT_8);
2181 SET_BITVAL(sess->chap_auth_en, options, BIT_7);
2182 SET_BITVAL(conn->snack_req_en, options, BIT_6);
2183 SET_BITVAL(sess->discovery_logout_en, options, BIT_5);
2184 SET_BITVAL(sess->bidi_chap_en, options, BIT_4);
2185 SET_BITVAL(sess->discovery_auth_optional, options, BIT_3);
2186 SET_BITVAL(sess->erl & BIT_1, options, BIT_1);
2187 SET_BITVAL(sess->erl & BIT_0, options, BIT_0);
2188 fw_ddb_entry->iscsi_options = cpu_to_le16(options);
2189
2190 options = le16_to_cpu(fw_ddb_entry->tcp_options);
2191 SET_BITVAL(conn->tcp_timestamp_stat, options, BIT_6);
2192 SET_BITVAL(conn->tcp_nagle_disable, options, BIT_5);
2193 SET_BITVAL(conn->tcp_wsf_disable, options, BIT_4);
2194 SET_BITVAL(conn->tcp_timer_scale & BIT_2, options, BIT_3);
2195 SET_BITVAL(conn->tcp_timer_scale & BIT_1, options, BIT_2);
2196 SET_BITVAL(conn->tcp_timer_scale & BIT_0, options, BIT_1);
2197 SET_BITVAL(conn->tcp_timestamp_en, options, BIT_0);
2198 fw_ddb_entry->tcp_options = cpu_to_le16(options);
2199
2200 options = le16_to_cpu(fw_ddb_entry->ip_options);
2201 SET_BITVAL(conn->fragment_disable, options, BIT_4);
2202 fw_ddb_entry->ip_options = cpu_to_le16(options);
2203
2204 fw_ddb_entry->iscsi_max_outsnd_r2t = cpu_to_le16(sess->max_r2t);
2205 fw_ddb_entry->iscsi_max_rcv_data_seg_len =
2206 cpu_to_le16(conn->max_recv_dlength / BYTE_UNITS);
2207 fw_ddb_entry->iscsi_max_snd_data_seg_len =
2208 cpu_to_le16(conn->max_xmit_dlength / BYTE_UNITS);
2209 fw_ddb_entry->iscsi_first_burst_len =
2210 cpu_to_le16(sess->first_burst / BYTE_UNITS);
2211 fw_ddb_entry->iscsi_max_burst_len = cpu_to_le16(sess->max_burst /
2212 BYTE_UNITS);
2213 fw_ddb_entry->iscsi_def_time2wait = cpu_to_le16(sess->time2wait);
2214 fw_ddb_entry->iscsi_def_time2retain = cpu_to_le16(sess->time2retain);
2215 fw_ddb_entry->tgt_portal_grp = cpu_to_le16(sess->tpgt);
2216 fw_ddb_entry->mss = cpu_to_le16(conn->max_segment_size);
2217 fw_ddb_entry->tcp_xmt_wsf = cpu_to_le16(conn->tcp_xmit_wsf);
2218 fw_ddb_entry->tcp_rcv_wsf = cpu_to_le16(conn->tcp_recv_wsf);
2219 fw_ddb_entry->ipv4_tos = conn->ipv4_tos;
2220 fw_ddb_entry->ipv6_flow_lbl = cpu_to_le16(conn->ipv6_flow_label);
2221 fw_ddb_entry->ka_timeout = cpu_to_le16(conn->keepalive_timeout);
2222 fw_ddb_entry->lcl_port = cpu_to_le16(conn->local_port);
2223 fw_ddb_entry->stat_sn = cpu_to_le16(conn->statsn);
2224 fw_ddb_entry->exp_stat_sn = cpu_to_le16(conn->exp_statsn);
2225 fw_ddb_entry->ddb_link = cpu_to_le16(sess->discovery_parent_type);
2226 fw_ddb_entry->chap_tbl_idx = cpu_to_le16(sess->chap_out_idx);
2227 fw_ddb_entry->tsid = cpu_to_le16(sess->tsid);
2228 fw_ddb_entry->port = cpu_to_le16(conn->port);
2229 fw_ddb_entry->def_timeout =
2230 cpu_to_le16(sess->default_taskmgmt_timeout);
2231
2232 if (conn->ipaddress)
2233 memcpy(fw_ddb_entry->ip_addr, conn->ipaddress,
2234 sizeof(fw_ddb_entry->ip_addr));
2235
2236 if (conn->redirect_ipaddr)
2237 memcpy(fw_ddb_entry->tgt_addr, conn->redirect_ipaddr,
2238 sizeof(fw_ddb_entry->tgt_addr));
2239
2240 if (conn->link_local_ipv6_addr)
2241 memcpy(fw_ddb_entry->link_local_ipv6_addr,
2242 conn->link_local_ipv6_addr,
2243 sizeof(fw_ddb_entry->link_local_ipv6_addr));
2244
2245 if (sess->targetname)
2246 memcpy(fw_ddb_entry->iscsi_name, sess->targetname,
2247 sizeof(fw_ddb_entry->iscsi_name));
2248
2249 if (sess->targetalias)
2250 memcpy(fw_ddb_entry->iscsi_alias, sess->targetalias,
2251 sizeof(fw_ddb_entry->iscsi_alias));
2252
2253 COPY_ISID(fw_ddb_entry->isid, sess->isid);
2254
2255 return rc;
2256}
2257
1925static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha, 2258static void qla4xxx_copy_fwddb_param(struct scsi_qla_host *ha,
1926 struct dev_db_entry *fw_ddb_entry, 2259 struct dev_db_entry *fw_ddb_entry,
1927 struct iscsi_cls_session *cls_sess, 2260 struct iscsi_cls_session *cls_sess,
@@ -5062,6 +5395,1315 @@ exit_nt_list:
5062 dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma); 5395 dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
5063} 5396}
5064 5397
5398static void qla4xxx_build_new_nt_list(struct scsi_qla_host *ha,
5399 struct list_head *list_nt)
5400{
5401 struct dev_db_entry *fw_ddb_entry;
5402 dma_addr_t fw_ddb_dma;
5403 int max_ddbs;
5404 int fw_idx_size;
5405 int ret;
5406 uint32_t idx = 0, next_idx = 0;
5407 uint32_t state = 0, conn_err = 0;
5408 uint16_t conn_id = 0;
5409 struct qla_ddb_index *nt_ddb_idx;
5410
5411 fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,
5412 &fw_ddb_dma);
5413 if (fw_ddb_entry == NULL) {
5414 DEBUG2(ql4_printk(KERN_ERR, ha, "Out of memory\n"));
5415 goto exit_new_nt_list;
5416 }
5417 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
5418 MAX_DEV_DB_ENTRIES;
5419 fw_idx_size = sizeof(struct qla_ddb_index);
5420
5421 for (idx = 0; idx < max_ddbs; idx = next_idx) {
5422 ret = qla4xxx_get_fwddb_entry(ha, idx, fw_ddb_entry, fw_ddb_dma,
5423 NULL, &next_idx, &state,
5424 &conn_err, NULL, &conn_id);
5425 if (ret == QLA_ERROR)
5426 break;
5427
5428 /* Check if NT, then add it to list */
5429 if (strlen((char *)fw_ddb_entry->iscsi_name) == 0)
5430 goto continue_next_new_nt;
5431
5432 if (!(state == DDB_DS_NO_CONNECTION_ACTIVE))
5433 goto continue_next_new_nt;
5434
5435 DEBUG2(ql4_printk(KERN_INFO, ha,
5436 "Adding DDB to session = 0x%x\n", idx));
5437
5438 nt_ddb_idx = vmalloc(fw_idx_size);
5439 if (!nt_ddb_idx)
5440 break;
5441
5442 nt_ddb_idx->fw_ddb_idx = idx;
5443
5444 ret = qla4xxx_is_session_exists(ha, fw_ddb_entry);
5445 if (ret == QLA_SUCCESS) {
5446 /* free nt_ddb_idx and do not add to list_nt */
5447 vfree(nt_ddb_idx);
5448 goto continue_next_new_nt;
5449 }
5450
5451 list_add_tail(&nt_ddb_idx->list, list_nt);
5452
5453 ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, RESET_ADAPTER,
5454 idx);
5455 if (ret == QLA_ERROR)
5456 goto exit_new_nt_list;
5457
5458continue_next_new_nt:
5459 if (next_idx == 0)
5460 break;
5461 }
5462
5463exit_new_nt_list:
5464 if (fw_ddb_entry)
5465 dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
5466}
5467
5468/**
5469 * qla4xxx_sysfs_ddb_is_non_persistent - check for non-persistence of ddb entry
5470 * @dev: dev associated with the sysfs entry
5471 * @data: pointer to flashnode session object
5472 *
5473 * Returns:
5474 * 1: if flashnode entry is non-persistent
5475 * 0: if flashnode entry is persistent
5476 **/
5477static int qla4xxx_sysfs_ddb_is_non_persistent(struct device *dev, void *data)
5478{
5479 struct iscsi_bus_flash_session *fnode_sess;
5480
5481 if (!iscsi_flashnode_bus_match(dev, NULL))
5482 return 0;
5483
5484 fnode_sess = iscsi_dev_to_flash_session(dev);
5485
5486 return (fnode_sess->flash_state == DEV_DB_NON_PERSISTENT);
5487}
5488
5489/**
5490 * qla4xxx_sysfs_ddb_tgt_create - Create sysfs entry for target
5491 * @ha: pointer to host
5492 * @fw_ddb_entry: flash ddb data
5493 * @idx: target index
5494 * @user: if set then this call is made from userland else from kernel
5495 *
5496 * Returns:
5497 * On sucess: QLA_SUCCESS
5498 * On failure: QLA_ERROR
5499 *
5500 * This create separate sysfs entries for session and connection attributes of
5501 * the given fw ddb entry.
5502 * If this is invoked as a result of a userspace call then the entry is marked
5503 * as nonpersistent using flash_state field.
5504 **/
5505int qla4xxx_sysfs_ddb_tgt_create(struct scsi_qla_host *ha,
5506 struct dev_db_entry *fw_ddb_entry,
5507 uint16_t *idx, int user)
5508{
5509 struct iscsi_bus_flash_session *fnode_sess = NULL;
5510 struct iscsi_bus_flash_conn *fnode_conn = NULL;
5511 int rc = QLA_ERROR;
5512
5513 fnode_sess = iscsi_create_flashnode_sess(ha->host, *idx,
5514 &qla4xxx_iscsi_transport, 0);
5515 if (!fnode_sess) {
5516 ql4_printk(KERN_ERR, ha,
5517 "%s: Unable to create session sysfs entry for flashnode %d of host%lu\n",
5518 __func__, *idx, ha->host_no);
5519 goto exit_tgt_create;
5520 }
5521
5522 fnode_conn = iscsi_create_flashnode_conn(ha->host, fnode_sess,
5523 &qla4xxx_iscsi_transport, 0);
5524 if (!fnode_conn) {
5525 ql4_printk(KERN_ERR, ha,
5526 "%s: Unable to create conn sysfs entry for flashnode %d of host%lu\n",
5527 __func__, *idx, ha->host_no);
5528 goto free_sess;
5529 }
5530
5531 if (user) {
5532 fnode_sess->flash_state = DEV_DB_NON_PERSISTENT;
5533 } else {
5534 fnode_sess->flash_state = DEV_DB_PERSISTENT;
5535
5536 if (*idx == ha->pri_ddb_idx || *idx == ha->sec_ddb_idx)
5537 fnode_sess->is_boot_target = 1;
5538 else
5539 fnode_sess->is_boot_target = 0;
5540 }
5541
5542 rc = qla4xxx_copy_from_fwddb_param(fnode_sess, fnode_conn,
5543 fw_ddb_entry);
5544
5545 ql4_printk(KERN_INFO, ha, "%s: sysfs entry %s created\n",
5546 __func__, fnode_sess->dev.kobj.name);
5547
5548 ql4_printk(KERN_INFO, ha, "%s: sysfs entry %s created\n",
5549 __func__, fnode_conn->dev.kobj.name);
5550
5551 return QLA_SUCCESS;
5552
5553free_sess:
5554 iscsi_destroy_flashnode_sess(fnode_sess);
5555
5556exit_tgt_create:
5557 return QLA_ERROR;
5558}
5559
5560/**
5561 * qla4xxx_sysfs_ddb_add - Add new ddb entry in flash
5562 * @shost: pointer to host
5563 * @buf: type of ddb entry (ipv4/ipv6)
5564 * @len: length of buf
5565 *
5566 * This creates new ddb entry in the flash by finding first free index and
5567 * storing default ddb there. And then create sysfs entry for the new ddb entry.
5568 **/
5569static int qla4xxx_sysfs_ddb_add(struct Scsi_Host *shost, const char *buf,
5570 int len)
5571{
5572 struct scsi_qla_host *ha = to_qla_host(shost);
5573 struct dev_db_entry *fw_ddb_entry = NULL;
5574 dma_addr_t fw_ddb_entry_dma;
5575 struct device *dev;
5576 uint16_t idx = 0;
5577 uint16_t max_ddbs = 0;
5578 uint32_t options = 0;
5579 uint32_t rval = QLA_ERROR;
5580
5581 if (strncasecmp(DEV_TYPE_IPV4, buf, 4) &&
5582 strncasecmp(DEV_TYPE_IPV6, buf, 4)) {
5583 DEBUG2(ql4_printk(KERN_ERR, ha, "%s: Invalid portal type\n",
5584 __func__));
5585 goto exit_ddb_add;
5586 }
5587
5588 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
5589 MAX_DEV_DB_ENTRIES;
5590
5591 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5592 &fw_ddb_entry_dma, GFP_KERNEL);
5593 if (!fw_ddb_entry) {
5594 DEBUG2(ql4_printk(KERN_ERR, ha,
5595 "%s: Unable to allocate dma buffer\n",
5596 __func__));
5597 goto exit_ddb_add;
5598 }
5599
5600 dev = iscsi_find_flashnode_sess(ha->host, NULL,
5601 qla4xxx_sysfs_ddb_is_non_persistent);
5602 if (dev) {
5603 ql4_printk(KERN_ERR, ha,
5604 "%s: A non-persistent entry %s found\n",
5605 __func__, dev->kobj.name);
5606 goto exit_ddb_add;
5607 }
5608
5609 for (idx = 0; idx < max_ddbs; idx++) {
5610 if (qla4xxx_flashdb_by_index(ha, fw_ddb_entry,
5611 fw_ddb_entry_dma, idx))
5612 break;
5613 }
5614
5615 if (idx == max_ddbs)
5616 goto exit_ddb_add;
5617
5618 if (!strncasecmp("ipv6", buf, 4))
5619 options |= IPV6_DEFAULT_DDB_ENTRY;
5620
5621 rval = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);
5622 if (rval == QLA_ERROR)
5623 goto exit_ddb_add;
5624
5625 rval = qla4xxx_sysfs_ddb_tgt_create(ha, fw_ddb_entry, &idx, 1);
5626
5627exit_ddb_add:
5628 if (fw_ddb_entry)
5629 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5630 fw_ddb_entry, fw_ddb_entry_dma);
5631 if (rval == QLA_SUCCESS)
5632 return idx;
5633 else
5634 return -EIO;
5635}
5636
5637/**
5638 * qla4xxx_sysfs_ddb_apply - write the target ddb contents to Flash
5639 * @fnode_sess: pointer to session attrs of flash ddb entry
5640 * @fnode_conn: pointer to connection attrs of flash ddb entry
5641 *
5642 * This writes the contents of target ddb buffer to Flash with a valid cookie
5643 * value in order to make the ddb entry persistent.
5644 **/
5645static int qla4xxx_sysfs_ddb_apply(struct iscsi_bus_flash_session *fnode_sess,
5646 struct iscsi_bus_flash_conn *fnode_conn)
5647{
5648 struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
5649 struct scsi_qla_host *ha = to_qla_host(shost);
5650 uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;
5651 struct dev_db_entry *fw_ddb_entry = NULL;
5652 dma_addr_t fw_ddb_entry_dma;
5653 uint32_t options = 0;
5654 int rval = 0;
5655
5656 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5657 &fw_ddb_entry_dma, GFP_KERNEL);
5658 if (!fw_ddb_entry) {
5659 DEBUG2(ql4_printk(KERN_ERR, ha,
5660 "%s: Unable to allocate dma buffer\n",
5661 __func__));
5662 rval = -ENOMEM;
5663 goto exit_ddb_apply;
5664 }
5665
5666 if (!strncasecmp(fnode_sess->portal_type, DEV_TYPE_IPV6, 4))
5667 options |= IPV6_DEFAULT_DDB_ENTRY;
5668
5669 rval = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);
5670 if (rval == QLA_ERROR)
5671 goto exit_ddb_apply;
5672
5673 dev_db_start_offset += (fnode_sess->target_id *
5674 sizeof(*fw_ddb_entry));
5675
5676 qla4xxx_copy_to_fwddb_param(fnode_sess, fnode_conn, fw_ddb_entry);
5677 fw_ddb_entry->cookie = DDB_VALID_COOKIE;
5678
5679 rval = qla4xxx_set_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
5680 sizeof(*fw_ddb_entry), FLASH_OPT_RMW_COMMIT);
5681
5682 if (rval == QLA_SUCCESS) {
5683 fnode_sess->flash_state = DEV_DB_PERSISTENT;
5684 ql4_printk(KERN_INFO, ha,
5685 "%s: flash node %u of host %lu written to flash\n",
5686 __func__, fnode_sess->target_id, ha->host_no);
5687 } else {
5688 rval = -EIO;
5689 ql4_printk(KERN_ERR, ha,
5690 "%s: Error while writing flash node %u of host %lu to flash\n",
5691 __func__, fnode_sess->target_id, ha->host_no);
5692 }
5693
5694exit_ddb_apply:
5695 if (fw_ddb_entry)
5696 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5697 fw_ddb_entry, fw_ddb_entry_dma);
5698 return rval;
5699}
5700
5701static ssize_t qla4xxx_sysfs_ddb_conn_open(struct scsi_qla_host *ha,
5702 struct dev_db_entry *fw_ddb_entry,
5703 uint16_t idx)
5704{
5705 struct dev_db_entry *ddb_entry = NULL;
5706 dma_addr_t ddb_entry_dma;
5707 unsigned long wtime;
5708 uint32_t mbx_sts = 0;
5709 uint32_t state = 0, conn_err = 0;
5710 uint16_t tmo = 0;
5711 int ret = 0;
5712
5713 ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*ddb_entry),
5714 &ddb_entry_dma, GFP_KERNEL);
5715 if (!ddb_entry) {
5716 DEBUG2(ql4_printk(KERN_ERR, ha,
5717 "%s: Unable to allocate dma buffer\n",
5718 __func__));
5719 return QLA_ERROR;
5720 }
5721
5722 memcpy(ddb_entry, fw_ddb_entry, sizeof(*ddb_entry));
5723
5724 ret = qla4xxx_set_ddb_entry(ha, idx, ddb_entry_dma, &mbx_sts);
5725 if (ret != QLA_SUCCESS) {
5726 DEBUG2(ql4_printk(KERN_ERR, ha,
5727 "%s: Unable to set ddb entry for index %d\n",
5728 __func__, idx));
5729 goto exit_ddb_conn_open;
5730 }
5731
5732 qla4xxx_conn_open(ha, idx);
5733
5734 /* To ensure that sendtargets is done, wait for at least 12 secs */
5735 tmo = ((ha->def_timeout > LOGIN_TOV) &&
5736 (ha->def_timeout < LOGIN_TOV * 10) ?
5737 ha->def_timeout : LOGIN_TOV);
5738
5739 DEBUG2(ql4_printk(KERN_INFO, ha,
5740 "Default time to wait for login to ddb %d\n", tmo));
5741
5742 wtime = jiffies + (HZ * tmo);
5743 do {
5744 ret = qla4xxx_get_fwddb_entry(ha, idx, NULL, 0, NULL,
5745 NULL, &state, &conn_err, NULL,
5746 NULL);
5747 if (ret == QLA_ERROR)
5748 continue;
5749
5750 if (state == DDB_DS_NO_CONNECTION_ACTIVE ||
5751 state == DDB_DS_SESSION_FAILED)
5752 break;
5753
5754 schedule_timeout_uninterruptible(HZ / 10);
5755 } while (time_after(wtime, jiffies));
5756
5757exit_ddb_conn_open:
5758 if (ddb_entry)
5759 dma_free_coherent(&ha->pdev->dev, sizeof(*ddb_entry),
5760 ddb_entry, ddb_entry_dma);
5761 return ret;
5762}
5763
5764static int qla4xxx_ddb_login_st(struct scsi_qla_host *ha,
5765 struct dev_db_entry *fw_ddb_entry)
5766{
5767 struct qla_ddb_index *ddb_idx, *ddb_idx_tmp;
5768 struct list_head list_nt;
5769 uint16_t ddb_index;
5770 int ret = 0;
5771
5772 if (test_bit(AF_ST_DISCOVERY_IN_PROGRESS, &ha->flags)) {
5773 ql4_printk(KERN_WARNING, ha,
5774 "%s: A discovery already in progress!\n", __func__);
5775 return QLA_ERROR;
5776 }
5777
5778 INIT_LIST_HEAD(&list_nt);
5779
5780 set_bit(AF_ST_DISCOVERY_IN_PROGRESS, &ha->flags);
5781
5782 ret = qla4xxx_get_ddb_index(ha, &ddb_index);
5783 if (ret == QLA_ERROR)
5784 goto exit_login_st_clr_bit;
5785
5786 ret = qla4xxx_sysfs_ddb_conn_open(ha, fw_ddb_entry, ddb_index);
5787 if (ret == QLA_ERROR)
5788 goto exit_login_st;
5789
5790 qla4xxx_build_new_nt_list(ha, &list_nt);
5791
5792 list_for_each_entry_safe(ddb_idx, ddb_idx_tmp, &list_nt, list) {
5793 list_del_init(&ddb_idx->list);
5794 qla4xxx_clear_ddb_entry(ha, ddb_idx->fw_ddb_idx);
5795 vfree(ddb_idx);
5796 }
5797
5798exit_login_st:
5799 if (qla4xxx_clear_ddb_entry(ha, ddb_index) == QLA_ERROR) {
5800 ql4_printk(KERN_ERR, ha,
5801 "Unable to clear DDB index = 0x%x\n", ddb_index);
5802 }
5803
5804 clear_bit(ddb_index, ha->ddb_idx_map);
5805
5806exit_login_st_clr_bit:
5807 clear_bit(AF_ST_DISCOVERY_IN_PROGRESS, &ha->flags);
5808 return ret;
5809}
5810
5811static int qla4xxx_ddb_login_nt(struct scsi_qla_host *ha,
5812 struct dev_db_entry *fw_ddb_entry,
5813 uint16_t idx)
5814{
5815 int ret = QLA_ERROR;
5816
5817 ret = qla4xxx_is_session_exists(ha, fw_ddb_entry);
5818 if (ret != QLA_SUCCESS)
5819 ret = qla4xxx_sess_conn_setup(ha, fw_ddb_entry, RESET_ADAPTER,
5820 idx);
5821 else
5822 ret = -EPERM;
5823
5824 return ret;
5825}
5826
5827/**
5828 * qla4xxx_sysfs_ddb_login - Login to the specified target
5829 * @fnode_sess: pointer to session attrs of flash ddb entry
5830 * @fnode_conn: pointer to connection attrs of flash ddb entry
5831 *
5832 * This logs in to the specified target
5833 **/
5834static int qla4xxx_sysfs_ddb_login(struct iscsi_bus_flash_session *fnode_sess,
5835 struct iscsi_bus_flash_conn *fnode_conn)
5836{
5837 struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
5838 struct scsi_qla_host *ha = to_qla_host(shost);
5839 struct dev_db_entry *fw_ddb_entry = NULL;
5840 dma_addr_t fw_ddb_entry_dma;
5841 uint32_t options = 0;
5842 int ret = 0;
5843
5844 if (fnode_sess->flash_state == DEV_DB_NON_PERSISTENT) {
5845 ql4_printk(KERN_ERR, ha,
5846 "%s: Target info is not persistent\n", __func__);
5847 ret = -EIO;
5848 goto exit_ddb_login;
5849 }
5850
5851 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5852 &fw_ddb_entry_dma, GFP_KERNEL);
5853 if (!fw_ddb_entry) {
5854 DEBUG2(ql4_printk(KERN_ERR, ha,
5855 "%s: Unable to allocate dma buffer\n",
5856 __func__));
5857 ret = -ENOMEM;
5858 goto exit_ddb_login;
5859 }
5860
5861 if (!strncasecmp(fnode_sess->portal_type, DEV_TYPE_IPV6, 4))
5862 options |= IPV6_DEFAULT_DDB_ENTRY;
5863
5864 ret = qla4xxx_get_default_ddb(ha, options, fw_ddb_entry_dma);
5865 if (ret == QLA_ERROR)
5866 goto exit_ddb_login;
5867
5868 qla4xxx_copy_to_fwddb_param(fnode_sess, fnode_conn, fw_ddb_entry);
5869 fw_ddb_entry->cookie = DDB_VALID_COOKIE;
5870
5871 if (strlen((char *)fw_ddb_entry->iscsi_name) == 0)
5872 ret = qla4xxx_ddb_login_st(ha, fw_ddb_entry);
5873 else
5874 ret = qla4xxx_ddb_login_nt(ha, fw_ddb_entry,
5875 fnode_sess->target_id);
5876
5877 if (ret > 0)
5878 ret = -EIO;
5879
5880exit_ddb_login:
5881 if (fw_ddb_entry)
5882 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5883 fw_ddb_entry, fw_ddb_entry_dma);
5884 return ret;
5885}
5886
5887/**
5888 * qla4xxx_sysfs_ddb_logout_sid - Logout session for the specified target
5889 * @cls_sess: pointer to session to be logged out
5890 *
5891 * This performs session log out from the specified target
5892 **/
5893static int qla4xxx_sysfs_ddb_logout_sid(struct iscsi_cls_session *cls_sess)
5894{
5895 struct iscsi_session *sess;
5896 struct ddb_entry *ddb_entry = NULL;
5897 struct scsi_qla_host *ha;
5898 struct dev_db_entry *fw_ddb_entry = NULL;
5899 dma_addr_t fw_ddb_entry_dma;
5900 unsigned long flags;
5901 unsigned long wtime;
5902 uint32_t ddb_state;
5903 int options;
5904 int ret = 0;
5905
5906 sess = cls_sess->dd_data;
5907 ddb_entry = sess->dd_data;
5908 ha = ddb_entry->ha;
5909
5910 if (ddb_entry->ddb_type != FLASH_DDB) {
5911 ql4_printk(KERN_ERR, ha, "%s: Not a flash node session\n",
5912 __func__);
5913 ret = -ENXIO;
5914 goto exit_ddb_logout;
5915 }
5916
5917 options = LOGOUT_OPTION_CLOSE_SESSION;
5918 if (qla4xxx_session_logout_ddb(ha, ddb_entry, options) == QLA_ERROR) {
5919 ql4_printk(KERN_ERR, ha, "%s: Logout failed\n", __func__);
5920 ret = -EIO;
5921 goto exit_ddb_logout;
5922 }
5923
5924 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5925 &fw_ddb_entry_dma, GFP_KERNEL);
5926 if (!fw_ddb_entry) {
5927 ql4_printk(KERN_ERR, ha,
5928 "%s: Unable to allocate dma buffer\n", __func__);
5929 ret = -ENOMEM;
5930 goto exit_ddb_logout;
5931 }
5932
5933 wtime = jiffies + (HZ * LOGOUT_TOV);
5934 do {
5935 ret = qla4xxx_get_fwddb_entry(ha, ddb_entry->fw_ddb_index,
5936 fw_ddb_entry, fw_ddb_entry_dma,
5937 NULL, NULL, &ddb_state, NULL,
5938 NULL, NULL);
5939 if (ret == QLA_ERROR)
5940 goto ddb_logout_clr_sess;
5941
5942 if ((ddb_state == DDB_DS_NO_CONNECTION_ACTIVE) ||
5943 (ddb_state == DDB_DS_SESSION_FAILED))
5944 goto ddb_logout_clr_sess;
5945
5946 schedule_timeout_uninterruptible(HZ);
5947 } while ((time_after(wtime, jiffies)));
5948
5949ddb_logout_clr_sess:
5950 qla4xxx_clear_ddb_entry(ha, ddb_entry->fw_ddb_index);
5951 /*
5952 * we have decremented the reference count of the driver
5953 * when we setup the session to have the driver unload
5954 * to be seamless without actually destroying the
5955 * session
5956 **/
5957 try_module_get(qla4xxx_iscsi_transport.owner);
5958 iscsi_destroy_endpoint(ddb_entry->conn->ep);
5959
5960 spin_lock_irqsave(&ha->hardware_lock, flags);
5961 qla4xxx_free_ddb(ha, ddb_entry);
5962 spin_unlock_irqrestore(&ha->hardware_lock, flags);
5963
5964 iscsi_session_teardown(ddb_entry->sess);
5965
5966 ret = QLA_SUCCESS;
5967
5968exit_ddb_logout:
5969 if (fw_ddb_entry)
5970 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry),
5971 fw_ddb_entry, fw_ddb_entry_dma);
5972 return ret;
5973}
5974
5975/**
5976 * qla4xxx_sysfs_ddb_logout - Logout from the specified target
5977 * @fnode_sess: pointer to session attrs of flash ddb entry
5978 * @fnode_conn: pointer to connection attrs of flash ddb entry
5979 *
5980 * This performs log out from the specified target
5981 **/
5982static int qla4xxx_sysfs_ddb_logout(struct iscsi_bus_flash_session *fnode_sess,
5983 struct iscsi_bus_flash_conn *fnode_conn)
5984{
5985 struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
5986 struct scsi_qla_host *ha = to_qla_host(shost);
5987 struct ql4_tuple_ddb *flash_tddb = NULL;
5988 struct ql4_tuple_ddb *tmp_tddb = NULL;
5989 struct dev_db_entry *fw_ddb_entry = NULL;
5990 struct ddb_entry *ddb_entry = NULL;
5991 dma_addr_t fw_ddb_dma;
5992 uint32_t next_idx = 0;
5993 uint32_t state = 0, conn_err = 0;
5994 uint16_t conn_id = 0;
5995 int idx, index;
5996 int status, ret = 0;
5997
5998 fw_ddb_entry = dma_pool_alloc(ha->fw_ddb_dma_pool, GFP_KERNEL,
5999 &fw_ddb_dma);
6000 if (fw_ddb_entry == NULL) {
6001 ql4_printk(KERN_ERR, ha, "%s:Out of memory\n", __func__);
6002 ret = -ENOMEM;
6003 goto exit_ddb_logout;
6004 }
6005
6006 flash_tddb = vzalloc(sizeof(*flash_tddb));
6007 if (!flash_tddb) {
6008 ql4_printk(KERN_WARNING, ha,
6009 "%s:Memory Allocation failed.\n", __func__);
6010 ret = -ENOMEM;
6011 goto exit_ddb_logout;
6012 }
6013
6014 tmp_tddb = vzalloc(sizeof(*tmp_tddb));
6015 if (!tmp_tddb) {
6016 ql4_printk(KERN_WARNING, ha,
6017 "%s:Memory Allocation failed.\n", __func__);
6018 ret = -ENOMEM;
6019 goto exit_ddb_logout;
6020 }
6021
6022 if (!fnode_sess->targetname) {
6023 ql4_printk(KERN_ERR, ha,
6024 "%s:Cannot logout from SendTarget entry\n",
6025 __func__);
6026 ret = -EPERM;
6027 goto exit_ddb_logout;
6028 }
6029
6030 if (fnode_sess->is_boot_target) {
6031 ql4_printk(KERN_ERR, ha,
6032 "%s: Logout from boot target entry is not permitted.\n",
6033 __func__);
6034 ret = -EPERM;
6035 goto exit_ddb_logout;
6036 }
6037
6038 strncpy(flash_tddb->iscsi_name, fnode_sess->targetname,
6039 ISCSI_NAME_SIZE);
6040
6041 if (!strncmp(fnode_sess->portal_type, DEV_TYPE_IPV6, 4))
6042 sprintf(flash_tddb->ip_addr, "%pI6", fnode_conn->ipaddress);
6043 else
6044 sprintf(flash_tddb->ip_addr, "%pI4", fnode_conn->ipaddress);
6045
6046 flash_tddb->tpgt = fnode_sess->tpgt;
6047 flash_tddb->port = fnode_conn->port;
6048
6049 COPY_ISID(flash_tddb->isid, fnode_sess->isid);
6050
6051 for (idx = 0; idx < MAX_DDB_ENTRIES; idx++) {
6052 ddb_entry = qla4xxx_lookup_ddb_by_fw_index(ha, idx);
6053 if (ddb_entry == NULL)
6054 continue;
6055
6056 if (ddb_entry->ddb_type != FLASH_DDB)
6057 continue;
6058
6059 index = ddb_entry->sess->target_id;
6060 status = qla4xxx_get_fwddb_entry(ha, index, fw_ddb_entry,
6061 fw_ddb_dma, NULL, &next_idx,
6062 &state, &conn_err, NULL,
6063 &conn_id);
6064 if (status == QLA_ERROR) {
6065 ret = -ENOMEM;
6066 break;
6067 }
6068
6069 qla4xxx_convert_param_ddb(fw_ddb_entry, tmp_tddb, NULL);
6070
6071 status = qla4xxx_compare_tuple_ddb(ha, flash_tddb, tmp_tddb,
6072 true);
6073 if (status == QLA_SUCCESS) {
6074 ret = qla4xxx_sysfs_ddb_logout_sid(ddb_entry->sess);
6075 break;
6076 }
6077 }
6078
6079 if (idx == MAX_DDB_ENTRIES)
6080 ret = -ESRCH;
6081
6082exit_ddb_logout:
6083 if (flash_tddb)
6084 vfree(flash_tddb);
6085 if (tmp_tddb)
6086 vfree(tmp_tddb);
6087 if (fw_ddb_entry)
6088 dma_pool_free(ha->fw_ddb_dma_pool, fw_ddb_entry, fw_ddb_dma);
6089
6090 return ret;
6091}
6092
6093static int
6094qla4xxx_sysfs_ddb_get_param(struct iscsi_bus_flash_session *fnode_sess,
6095 int param, char *buf)
6096{
6097 struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
6098 struct scsi_qla_host *ha = to_qla_host(shost);
6099 struct iscsi_bus_flash_conn *fnode_conn;
6100 struct ql4_chap_table chap_tbl;
6101 struct device *dev;
6102 int parent_type, parent_index = 0xffff;
6103 int rc = 0;
6104
6105 dev = iscsi_find_flashnode_conn(fnode_sess, NULL,
6106 iscsi_is_flashnode_conn_dev);
6107 if (!dev)
6108 return -EIO;
6109
6110 fnode_conn = iscsi_dev_to_flash_conn(dev);
6111
6112 switch (param) {
6113 case ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6:
6114 rc = sprintf(buf, "%u\n", fnode_conn->is_fw_assigned_ipv6);
6115 break;
6116 case ISCSI_FLASHNODE_PORTAL_TYPE:
6117 rc = sprintf(buf, "%s\n", fnode_sess->portal_type);
6118 break;
6119 case ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE:
6120 rc = sprintf(buf, "%u\n", fnode_sess->auto_snd_tgt_disable);
6121 break;
6122 case ISCSI_FLASHNODE_DISCOVERY_SESS:
6123 rc = sprintf(buf, "%u\n", fnode_sess->discovery_sess);
6124 break;
6125 case ISCSI_FLASHNODE_ENTRY_EN:
6126 rc = sprintf(buf, "%u\n", fnode_sess->entry_state);
6127 break;
6128 case ISCSI_FLASHNODE_HDR_DGST_EN:
6129 rc = sprintf(buf, "%u\n", fnode_conn->hdrdgst_en);
6130 break;
6131 case ISCSI_FLASHNODE_DATA_DGST_EN:
6132 rc = sprintf(buf, "%u\n", fnode_conn->datadgst_en);
6133 break;
6134 case ISCSI_FLASHNODE_IMM_DATA_EN:
6135 rc = sprintf(buf, "%u\n", fnode_sess->imm_data_en);
6136 break;
6137 case ISCSI_FLASHNODE_INITIAL_R2T_EN:
6138 rc = sprintf(buf, "%u\n", fnode_sess->initial_r2t_en);
6139 break;
6140 case ISCSI_FLASHNODE_DATASEQ_INORDER:
6141 rc = sprintf(buf, "%u\n", fnode_sess->dataseq_inorder_en);
6142 break;
6143 case ISCSI_FLASHNODE_PDU_INORDER:
6144 rc = sprintf(buf, "%u\n", fnode_sess->pdu_inorder_en);
6145 break;
6146 case ISCSI_FLASHNODE_CHAP_AUTH_EN:
6147 rc = sprintf(buf, "%u\n", fnode_sess->chap_auth_en);
6148 break;
6149 case ISCSI_FLASHNODE_SNACK_REQ_EN:
6150 rc = sprintf(buf, "%u\n", fnode_conn->snack_req_en);
6151 break;
6152 case ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN:
6153 rc = sprintf(buf, "%u\n", fnode_sess->discovery_logout_en);
6154 break;
6155 case ISCSI_FLASHNODE_BIDI_CHAP_EN:
6156 rc = sprintf(buf, "%u\n", fnode_sess->bidi_chap_en);
6157 break;
6158 case ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL:
6159 rc = sprintf(buf, "%u\n", fnode_sess->discovery_auth_optional);
6160 break;
6161 case ISCSI_FLASHNODE_ERL:
6162 rc = sprintf(buf, "%u\n", fnode_sess->erl);
6163 break;
6164 case ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT:
6165 rc = sprintf(buf, "%u\n", fnode_conn->tcp_timestamp_stat);
6166 break;
6167 case ISCSI_FLASHNODE_TCP_NAGLE_DISABLE:
6168 rc = sprintf(buf, "%u\n", fnode_conn->tcp_nagle_disable);
6169 break;
6170 case ISCSI_FLASHNODE_TCP_WSF_DISABLE:
6171 rc = sprintf(buf, "%u\n", fnode_conn->tcp_wsf_disable);
6172 break;
6173 case ISCSI_FLASHNODE_TCP_TIMER_SCALE:
6174 rc = sprintf(buf, "%u\n", fnode_conn->tcp_timer_scale);
6175 break;
6176 case ISCSI_FLASHNODE_TCP_TIMESTAMP_EN:
6177 rc = sprintf(buf, "%u\n", fnode_conn->tcp_timestamp_en);
6178 break;
6179 case ISCSI_FLASHNODE_IP_FRAG_DISABLE:
6180 rc = sprintf(buf, "%u\n", fnode_conn->fragment_disable);
6181 break;
6182 case ISCSI_FLASHNODE_MAX_RECV_DLENGTH:
6183 rc = sprintf(buf, "%u\n", fnode_conn->max_recv_dlength);
6184 break;
6185 case ISCSI_FLASHNODE_MAX_XMIT_DLENGTH:
6186 rc = sprintf(buf, "%u\n", fnode_conn->max_xmit_dlength);
6187 break;
6188 case ISCSI_FLASHNODE_FIRST_BURST:
6189 rc = sprintf(buf, "%u\n", fnode_sess->first_burst);
6190 break;
6191 case ISCSI_FLASHNODE_DEF_TIME2WAIT:
6192 rc = sprintf(buf, "%u\n", fnode_sess->time2wait);
6193 break;
6194 case ISCSI_FLASHNODE_DEF_TIME2RETAIN:
6195 rc = sprintf(buf, "%u\n", fnode_sess->time2retain);
6196 break;
6197 case ISCSI_FLASHNODE_MAX_R2T:
6198 rc = sprintf(buf, "%u\n", fnode_sess->max_r2t);
6199 break;
6200 case ISCSI_FLASHNODE_KEEPALIVE_TMO:
6201 rc = sprintf(buf, "%u\n", fnode_conn->keepalive_timeout);
6202 break;
6203 case ISCSI_FLASHNODE_ISID:
6204 rc = sprintf(buf, "%02x%02x%02x%02x%02x%02x\n",
6205 fnode_sess->isid[0], fnode_sess->isid[1],
6206 fnode_sess->isid[2], fnode_sess->isid[3],
6207 fnode_sess->isid[4], fnode_sess->isid[5]);
6208 break;
6209 case ISCSI_FLASHNODE_TSID:
6210 rc = sprintf(buf, "%u\n", fnode_sess->tsid);
6211 break;
6212 case ISCSI_FLASHNODE_PORT:
6213 rc = sprintf(buf, "%d\n", fnode_conn->port);
6214 break;
6215 case ISCSI_FLASHNODE_MAX_BURST:
6216 rc = sprintf(buf, "%u\n", fnode_sess->max_burst);
6217 break;
6218 case ISCSI_FLASHNODE_DEF_TASKMGMT_TMO:
6219 rc = sprintf(buf, "%u\n",
6220 fnode_sess->default_taskmgmt_timeout);
6221 break;
6222 case ISCSI_FLASHNODE_IPADDR:
6223 if (!strncmp(fnode_sess->portal_type, DEV_TYPE_IPV6, 4))
6224 rc = sprintf(buf, "%pI6\n", fnode_conn->ipaddress);
6225 else
6226 rc = sprintf(buf, "%pI4\n", fnode_conn->ipaddress);
6227 break;
6228 case ISCSI_FLASHNODE_ALIAS:
6229 if (fnode_sess->targetalias)
6230 rc = sprintf(buf, "%s\n", fnode_sess->targetalias);
6231 else
6232 rc = sprintf(buf, "\n");
6233 break;
6234 case ISCSI_FLASHNODE_REDIRECT_IPADDR:
6235 if (!strncmp(fnode_sess->portal_type, DEV_TYPE_IPV6, 4))
6236 rc = sprintf(buf, "%pI6\n",
6237 fnode_conn->redirect_ipaddr);
6238 else
6239 rc = sprintf(buf, "%pI4\n",
6240 fnode_conn->redirect_ipaddr);
6241 break;
6242 case ISCSI_FLASHNODE_MAX_SEGMENT_SIZE:
6243 rc = sprintf(buf, "%u\n", fnode_conn->max_segment_size);
6244 break;
6245 case ISCSI_FLASHNODE_LOCAL_PORT:
6246 rc = sprintf(buf, "%u\n", fnode_conn->local_port);
6247 break;
6248 case ISCSI_FLASHNODE_IPV4_TOS:
6249 rc = sprintf(buf, "%u\n", fnode_conn->ipv4_tos);
6250 break;
6251 case ISCSI_FLASHNODE_IPV6_TC:
6252 if (!strncmp(fnode_sess->portal_type, DEV_TYPE_IPV6, 4))
6253 rc = sprintf(buf, "%u\n",
6254 fnode_conn->ipv6_traffic_class);
6255 else
6256 rc = sprintf(buf, "\n");
6257 break;
6258 case ISCSI_FLASHNODE_IPV6_FLOW_LABEL:
6259 rc = sprintf(buf, "%u\n", fnode_conn->ipv6_flow_label);
6260 break;
6261 case ISCSI_FLASHNODE_LINK_LOCAL_IPV6:
6262 if (!strncmp(fnode_sess->portal_type, DEV_TYPE_IPV6, 4))
6263 rc = sprintf(buf, "%pI6\n",
6264 fnode_conn->link_local_ipv6_addr);
6265 else
6266 rc = sprintf(buf, "\n");
6267 break;
6268 case ISCSI_FLASHNODE_DISCOVERY_PARENT_IDX:
6269 if ((fnode_sess->discovery_parent_idx) >= 0 &&
6270 (fnode_sess->discovery_parent_idx < MAX_DDB_ENTRIES))
6271 parent_index = fnode_sess->discovery_parent_idx;
6272
6273 rc = sprintf(buf, "%u\n", parent_index);
6274 break;
6275 case ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE:
6276 if (fnode_sess->discovery_parent_type == DDB_ISNS)
6277 parent_type = ISCSI_DISC_PARENT_ISNS;
6278 else if (fnode_sess->discovery_parent_type == DDB_NO_LINK)
6279 parent_type = ISCSI_DISC_PARENT_UNKNOWN;
6280 else if (fnode_sess->discovery_parent_type >= 0 &&
6281 fnode_sess->discovery_parent_type < MAX_DDB_ENTRIES)
6282 parent_type = ISCSI_DISC_PARENT_SENDTGT;
6283 else
6284 parent_type = ISCSI_DISC_PARENT_UNKNOWN;
6285
6286 rc = sprintf(buf, "%s\n",
6287 iscsi_get_discovery_parent_name(parent_type));
6288 break;
6289 case ISCSI_FLASHNODE_NAME:
6290 if (fnode_sess->targetname)
6291 rc = sprintf(buf, "%s\n", fnode_sess->targetname);
6292 else
6293 rc = sprintf(buf, "\n");
6294 break;
6295 case ISCSI_FLASHNODE_TPGT:
6296 rc = sprintf(buf, "%u\n", fnode_sess->tpgt);
6297 break;
6298 case ISCSI_FLASHNODE_TCP_XMIT_WSF:
6299 rc = sprintf(buf, "%u\n", fnode_conn->tcp_xmit_wsf);
6300 break;
6301 case ISCSI_FLASHNODE_TCP_RECV_WSF:
6302 rc = sprintf(buf, "%u\n", fnode_conn->tcp_recv_wsf);
6303 break;
6304 case ISCSI_FLASHNODE_CHAP_OUT_IDX:
6305 rc = sprintf(buf, "%u\n", fnode_sess->chap_out_idx);
6306 break;
6307 case ISCSI_FLASHNODE_USERNAME:
6308 if (fnode_sess->chap_auth_en) {
6309 qla4xxx_get_uni_chap_at_index(ha,
6310 chap_tbl.name,
6311 chap_tbl.secret,
6312 fnode_sess->chap_out_idx);
6313 rc = sprintf(buf, "%s\n", chap_tbl.name);
6314 } else {
6315 rc = sprintf(buf, "\n");
6316 }
6317 break;
6318 case ISCSI_FLASHNODE_PASSWORD:
6319 if (fnode_sess->chap_auth_en) {
6320 qla4xxx_get_uni_chap_at_index(ha,
6321 chap_tbl.name,
6322 chap_tbl.secret,
6323 fnode_sess->chap_out_idx);
6324 rc = sprintf(buf, "%s\n", chap_tbl.secret);
6325 } else {
6326 rc = sprintf(buf, "\n");
6327 }
6328 break;
6329 case ISCSI_FLASHNODE_STATSN:
6330 rc = sprintf(buf, "%u\n", fnode_conn->statsn);
6331 break;
6332 case ISCSI_FLASHNODE_EXP_STATSN:
6333 rc = sprintf(buf, "%u\n", fnode_conn->exp_statsn);
6334 break;
6335 case ISCSI_FLASHNODE_IS_BOOT_TGT:
6336 rc = sprintf(buf, "%u\n", fnode_sess->is_boot_target);
6337 break;
6338 default:
6339 rc = -ENOSYS;
6340 break;
6341 }
6342 return rc;
6343}
6344
6345/**
6346 * qla4xxx_sysfs_ddb_set_param - Set parameter for firmware DDB entry
6347 * @fnode_sess: pointer to session attrs of flash ddb entry
6348 * @fnode_conn: pointer to connection attrs of flash ddb entry
6349 * @data: Parameters and their values to update
6350 * @len: len of data
6351 *
6352 * This sets the parameter of flash ddb entry and writes them to flash
6353 **/
6354static int
6355qla4xxx_sysfs_ddb_set_param(struct iscsi_bus_flash_session *fnode_sess,
6356 struct iscsi_bus_flash_conn *fnode_conn,
6357 void *data, int len)
6358{
6359 struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
6360 struct scsi_qla_host *ha = to_qla_host(shost);
6361 struct dev_db_entry *fw_ddb_entry = NULL;
6362 struct iscsi_flashnode_param_info *fnode_param;
6363 struct nlattr *attr;
6364 int rc = QLA_ERROR;
6365 uint32_t rem = len;
6366
6367 fw_ddb_entry = kzalloc(sizeof(*fw_ddb_entry), GFP_KERNEL);
6368 if (!fw_ddb_entry) {
6369 DEBUG2(ql4_printk(KERN_ERR, ha,
6370 "%s: Unable to allocate ddb buffer\n",
6371 __func__));
6372 return -ENOMEM;
6373 }
6374
6375 nla_for_each_attr(attr, data, len, rem) {
6376 fnode_param = nla_data(attr);
6377
6378 switch (fnode_param->param) {
6379 case ISCSI_FLASHNODE_IS_FW_ASSIGNED_IPV6:
6380 fnode_conn->is_fw_assigned_ipv6 = fnode_param->value[0];
6381 break;
6382 case ISCSI_FLASHNODE_PORTAL_TYPE:
6383 memcpy(fnode_sess->portal_type, fnode_param->value,
6384 strlen(fnode_sess->portal_type));
6385 break;
6386 case ISCSI_FLASHNODE_AUTO_SND_TGT_DISABLE:
6387 fnode_sess->auto_snd_tgt_disable =
6388 fnode_param->value[0];
6389 break;
6390 case ISCSI_FLASHNODE_DISCOVERY_SESS:
6391 fnode_sess->discovery_sess = fnode_param->value[0];
6392 break;
6393 case ISCSI_FLASHNODE_ENTRY_EN:
6394 fnode_sess->entry_state = fnode_param->value[0];
6395 break;
6396 case ISCSI_FLASHNODE_HDR_DGST_EN:
6397 fnode_conn->hdrdgst_en = fnode_param->value[0];
6398 break;
6399 case ISCSI_FLASHNODE_DATA_DGST_EN:
6400 fnode_conn->datadgst_en = fnode_param->value[0];
6401 break;
6402 case ISCSI_FLASHNODE_IMM_DATA_EN:
6403 fnode_sess->imm_data_en = fnode_param->value[0];
6404 break;
6405 case ISCSI_FLASHNODE_INITIAL_R2T_EN:
6406 fnode_sess->initial_r2t_en = fnode_param->value[0];
6407 break;
6408 case ISCSI_FLASHNODE_DATASEQ_INORDER:
6409 fnode_sess->dataseq_inorder_en = fnode_param->value[0];
6410 break;
6411 case ISCSI_FLASHNODE_PDU_INORDER:
6412 fnode_sess->pdu_inorder_en = fnode_param->value[0];
6413 break;
6414 case ISCSI_FLASHNODE_CHAP_AUTH_EN:
6415 fnode_sess->chap_auth_en = fnode_param->value[0];
6416 break;
6417 case ISCSI_FLASHNODE_SNACK_REQ_EN:
6418 fnode_conn->snack_req_en = fnode_param->value[0];
6419 break;
6420 case ISCSI_FLASHNODE_DISCOVERY_LOGOUT_EN:
6421 fnode_sess->discovery_logout_en = fnode_param->value[0];
6422 break;
6423 case ISCSI_FLASHNODE_BIDI_CHAP_EN:
6424 fnode_sess->bidi_chap_en = fnode_param->value[0];
6425 break;
6426 case ISCSI_FLASHNODE_DISCOVERY_AUTH_OPTIONAL:
6427 fnode_sess->discovery_auth_optional =
6428 fnode_param->value[0];
6429 break;
6430 case ISCSI_FLASHNODE_ERL:
6431 fnode_sess->erl = fnode_param->value[0];
6432 break;
6433 case ISCSI_FLASHNODE_TCP_TIMESTAMP_STAT:
6434 fnode_conn->tcp_timestamp_stat = fnode_param->value[0];
6435 break;
6436 case ISCSI_FLASHNODE_TCP_NAGLE_DISABLE:
6437 fnode_conn->tcp_nagle_disable = fnode_param->value[0];
6438 break;
6439 case ISCSI_FLASHNODE_TCP_WSF_DISABLE:
6440 fnode_conn->tcp_wsf_disable = fnode_param->value[0];
6441 break;
6442 case ISCSI_FLASHNODE_TCP_TIMER_SCALE:
6443 fnode_conn->tcp_timer_scale = fnode_param->value[0];
6444 break;
6445 case ISCSI_FLASHNODE_TCP_TIMESTAMP_EN:
6446 fnode_conn->tcp_timestamp_en = fnode_param->value[0];
6447 break;
6448 case ISCSI_FLASHNODE_IP_FRAG_DISABLE:
6449 fnode_conn->fragment_disable = fnode_param->value[0];
6450 break;
6451 case ISCSI_FLASHNODE_MAX_RECV_DLENGTH:
6452 fnode_conn->max_recv_dlength =
6453 *(unsigned *)fnode_param->value;
6454 break;
6455 case ISCSI_FLASHNODE_MAX_XMIT_DLENGTH:
6456 fnode_conn->max_xmit_dlength =
6457 *(unsigned *)fnode_param->value;
6458 break;
6459 case ISCSI_FLASHNODE_FIRST_BURST:
6460 fnode_sess->first_burst =
6461 *(unsigned *)fnode_param->value;
6462 break;
6463 case ISCSI_FLASHNODE_DEF_TIME2WAIT:
6464 fnode_sess->time2wait = *(uint16_t *)fnode_param->value;
6465 break;
6466 case ISCSI_FLASHNODE_DEF_TIME2RETAIN:
6467 fnode_sess->time2retain =
6468 *(uint16_t *)fnode_param->value;
6469 break;
6470 case ISCSI_FLASHNODE_MAX_R2T:
6471 fnode_sess->max_r2t =
6472 *(uint16_t *)fnode_param->value;
6473 break;
6474 case ISCSI_FLASHNODE_KEEPALIVE_TMO:
6475 fnode_conn->keepalive_timeout =
6476 *(uint16_t *)fnode_param->value;
6477 break;
6478 case ISCSI_FLASHNODE_ISID:
6479 memcpy(fnode_sess->isid, fnode_param->value,
6480 sizeof(fnode_sess->isid));
6481 break;
6482 case ISCSI_FLASHNODE_TSID:
6483 fnode_sess->tsid = *(uint16_t *)fnode_param->value;
6484 break;
6485 case ISCSI_FLASHNODE_PORT:
6486 fnode_conn->port = *(uint16_t *)fnode_param->value;
6487 break;
6488 case ISCSI_FLASHNODE_MAX_BURST:
6489 fnode_sess->max_burst = *(unsigned *)fnode_param->value;
6490 break;
6491 case ISCSI_FLASHNODE_DEF_TASKMGMT_TMO:
6492 fnode_sess->default_taskmgmt_timeout =
6493 *(uint16_t *)fnode_param->value;
6494 break;
6495 case ISCSI_FLASHNODE_IPADDR:
6496 memcpy(fnode_conn->ipaddress, fnode_param->value,
6497 IPv6_ADDR_LEN);
6498 break;
6499 case ISCSI_FLASHNODE_ALIAS:
6500 rc = iscsi_switch_str_param(&fnode_sess->targetalias,
6501 (char *)fnode_param->value);
6502 break;
6503 case ISCSI_FLASHNODE_REDIRECT_IPADDR:
6504 memcpy(fnode_conn->redirect_ipaddr, fnode_param->value,
6505 IPv6_ADDR_LEN);
6506 break;
6507 case ISCSI_FLASHNODE_MAX_SEGMENT_SIZE:
6508 fnode_conn->max_segment_size =
6509 *(unsigned *)fnode_param->value;
6510 break;
6511 case ISCSI_FLASHNODE_LOCAL_PORT:
6512 fnode_conn->local_port =
6513 *(uint16_t *)fnode_param->value;
6514 break;
6515 case ISCSI_FLASHNODE_IPV4_TOS:
6516 fnode_conn->ipv4_tos = fnode_param->value[0];
6517 break;
6518 case ISCSI_FLASHNODE_IPV6_TC:
6519 fnode_conn->ipv6_traffic_class = fnode_param->value[0];
6520 break;
6521 case ISCSI_FLASHNODE_IPV6_FLOW_LABEL:
6522 fnode_conn->ipv6_flow_label = fnode_param->value[0];
6523 break;
6524 case ISCSI_FLASHNODE_NAME:
6525 rc = iscsi_switch_str_param(&fnode_sess->targetname,
6526 (char *)fnode_param->value);
6527 break;
6528 case ISCSI_FLASHNODE_TPGT:
6529 fnode_sess->tpgt = *(uint16_t *)fnode_param->value;
6530 break;
6531 case ISCSI_FLASHNODE_LINK_LOCAL_IPV6:
6532 memcpy(fnode_conn->link_local_ipv6_addr,
6533 fnode_param->value, IPv6_ADDR_LEN);
6534 break;
6535 case ISCSI_FLASHNODE_DISCOVERY_PARENT_TYPE:
6536 fnode_sess->discovery_parent_type =
6537 *(uint16_t *)fnode_param->value;
6538 break;
6539 case ISCSI_FLASHNODE_TCP_XMIT_WSF:
6540 fnode_conn->tcp_xmit_wsf =
6541 *(uint8_t *)fnode_param->value;
6542 break;
6543 case ISCSI_FLASHNODE_TCP_RECV_WSF:
6544 fnode_conn->tcp_recv_wsf =
6545 *(uint8_t *)fnode_param->value;
6546 break;
6547 case ISCSI_FLASHNODE_STATSN:
6548 fnode_conn->statsn = *(uint32_t *)fnode_param->value;
6549 break;
6550 case ISCSI_FLASHNODE_EXP_STATSN:
6551 fnode_conn->exp_statsn =
6552 *(uint32_t *)fnode_param->value;
6553 break;
6554 default:
6555 ql4_printk(KERN_ERR, ha,
6556 "%s: No such sysfs attribute\n", __func__);
6557 rc = -ENOSYS;
6558 goto exit_set_param;
6559 }
6560 }
6561
6562 rc = qla4xxx_sysfs_ddb_apply(fnode_sess, fnode_conn);
6563
6564exit_set_param:
6565 return rc;
6566}
6567
6568/**
6569 * qla4xxx_sysfs_ddb_delete - Delete firmware DDB entry
6570 * @fnode_sess: pointer to session attrs of flash ddb entry
6571 *
6572 * This invalidates the flash ddb entry at the given index
6573 **/
6574static int qla4xxx_sysfs_ddb_delete(struct iscsi_bus_flash_session *fnode_sess)
6575{
6576 struct Scsi_Host *shost = iscsi_flash_session_to_shost(fnode_sess);
6577 struct scsi_qla_host *ha = to_qla_host(shost);
6578 uint32_t dev_db_start_offset;
6579 uint32_t dev_db_end_offset;
6580 struct dev_db_entry *fw_ddb_entry = NULL;
6581 dma_addr_t fw_ddb_entry_dma;
6582 uint16_t *ddb_cookie = NULL;
6583 int target_id;
6584 int rc = 0;
6585
6586 if (!fnode_sess) {
6587 rc = -EINVAL;
6588 goto exit_ddb_del;
6589 }
6590
6591 if (fnode_sess->is_boot_target) {
6592 rc = -EPERM;
6593 DEBUG2(ql4_printk(KERN_ERR, ha,
6594 "%s: Deletion of boot target entry is not permitted.\n",
6595 __func__));
6596 goto exit_ddb_del;
6597 }
6598
6599 if (fnode_sess->flash_state == DEV_DB_NON_PERSISTENT)
6600 goto sysfs_ddb_del;
6601
6602 ddb_cookie = dma_alloc_coherent(&ha->pdev->dev, sizeof(*ddb_cookie),
6603 &fw_ddb_entry_dma, GFP_KERNEL);
6604 if (!ddb_cookie) {
6605 rc = -ENOMEM;
6606 DEBUG2(ql4_printk(KERN_ERR, ha,
6607 "%s: Unable to allocate dma buffer\n",
6608 __func__));
6609 goto exit_ddb_del;
6610 }
6611
6612 if (is_qla40XX(ha)) {
6613 dev_db_start_offset = FLASH_OFFSET_DB_INFO;
6614 } else {
6615 dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +
6616 (ha->hw.flt_region_ddb << 2);
6617 /* flt_ddb_size is DDB table size for both ports
6618 * so divide it by 2 to calculate the offset for second port
6619 */
6620 if (ha->port_num == 1)
6621 dev_db_start_offset += (ha->hw.flt_ddb_size / 2);
6622 }
6623
6624 dev_db_end_offset = dev_db_start_offset + (ha->hw.flt_ddb_size / 2);
6625 dev_db_start_offset += (fnode_sess->target_id * sizeof(*fw_ddb_entry));
6626 dev_db_start_offset += (void *)&(fw_ddb_entry->cookie) -
6627 (void *)fw_ddb_entry;
6628
6629 DEBUG2(ql4_printk(KERN_ERR, ha, "%s: start offset=%u, end offset=%u\n",
6630 __func__, dev_db_start_offset, dev_db_end_offset));
6631
6632 if (dev_db_start_offset > dev_db_end_offset) {
6633 rc = -EIO;
6634 DEBUG2(ql4_printk(KERN_ERR, ha, "%s:Invalid DDB index %u\n",
6635 __func__, fnode_sess->target_id));
6636 goto exit_ddb_del;
6637 }
6638
6639 /* invalidate the cookie */
6640 *ddb_cookie = 0xFFEE;
6641 qla4xxx_set_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
6642 sizeof(*ddb_cookie), FLASH_OPT_RMW_COMMIT);
6643
6644sysfs_ddb_del:
6645 target_id = fnode_sess->target_id;
6646 iscsi_destroy_flashnode_sess(fnode_sess);
6647 ql4_printk(KERN_INFO, ha,
6648 "%s: session and conn entries for flashnode %u of host %lu deleted\n",
6649 __func__, target_id, ha->host_no);
6650exit_ddb_del:
6651 if (ddb_cookie)
6652 dma_free_coherent(&ha->pdev->dev, sizeof(*ddb_cookie),
6653 ddb_cookie, fw_ddb_entry_dma);
6654 return rc;
6655}
6656
6657/**
6658 * qla4xxx_sysfs_ddb_export - Create sysfs entries for firmware DDBs
6659 * @ha: pointer to adapter structure
6660 *
6661 * Export the firmware DDB for all send targets and normal targets to sysfs.
6662 **/
6663static int qla4xxx_sysfs_ddb_export(struct scsi_qla_host *ha)
6664{
6665 struct dev_db_entry *fw_ddb_entry = NULL;
6666 dma_addr_t fw_ddb_entry_dma;
6667 uint16_t max_ddbs;
6668 uint16_t idx = 0;
6669 int ret = QLA_SUCCESS;
6670
6671 fw_ddb_entry = dma_alloc_coherent(&ha->pdev->dev,
6672 sizeof(*fw_ddb_entry),
6673 &fw_ddb_entry_dma, GFP_KERNEL);
6674 if (!fw_ddb_entry) {
6675 DEBUG2(ql4_printk(KERN_ERR, ha,
6676 "%s: Unable to allocate dma buffer\n",
6677 __func__));
6678 return -ENOMEM;
6679 }
6680
6681 max_ddbs = is_qla40XX(ha) ? MAX_DEV_DB_ENTRIES_40XX :
6682 MAX_DEV_DB_ENTRIES;
6683
6684 for (idx = 0; idx < max_ddbs; idx++) {
6685 if (qla4xxx_flashdb_by_index(ha, fw_ddb_entry, fw_ddb_entry_dma,
6686 idx))
6687 continue;
6688
6689 ret = qla4xxx_sysfs_ddb_tgt_create(ha, fw_ddb_entry, &idx, 0);
6690 if (ret) {
6691 ret = -EIO;
6692 break;
6693 }
6694 }
6695
6696 dma_free_coherent(&ha->pdev->dev, sizeof(*fw_ddb_entry), fw_ddb_entry,
6697 fw_ddb_entry_dma);
6698
6699 return ret;
6700}
6701
6702static void qla4xxx_sysfs_ddb_remove(struct scsi_qla_host *ha)
6703{
6704 iscsi_destroy_all_flashnode(ha->host);
6705}
6706
5065/** 6707/**
5066 * qla4xxx_build_ddb_list - Build ddb list and setup sessions 6708 * qla4xxx_build_ddb_list - Build ddb list and setup sessions
5067 * @ha: pointer to adapter structure 6709 * @ha: pointer to adapter structure
@@ -5452,6 +7094,10 @@ skip_retry_init:
5452 ql4_printk(KERN_ERR, ha, 7094 ql4_printk(KERN_ERR, ha,
5453 "%s: No iSCSI boot target configured\n", __func__); 7095 "%s: No iSCSI boot target configured\n", __func__);
5454 7096
7097 if (qla4xxx_sysfs_ddb_export(ha))
7098 ql4_printk(KERN_ERR, ha,
7099 "%s: Error exporting ddb to sysfs\n", __func__);
7100
5455 /* Perform the build ddb list and login to each */ 7101 /* Perform the build ddb list and login to each */
5456 qla4xxx_build_ddb_list(ha, INIT_ADAPTER); 7102 qla4xxx_build_ddb_list(ha, INIT_ADAPTER);
5457 iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb); 7103 iscsi_host_for_each_session(ha->host, qla4xxx_login_flash_ddb);
@@ -5577,6 +7223,7 @@ static void qla4xxx_remove_adapter(struct pci_dev *pdev)
5577 qla4xxx_destroy_fw_ddb_session(ha); 7223 qla4xxx_destroy_fw_ddb_session(ha);
5578 qla4_8xxx_free_sysfs_attr(ha); 7224 qla4_8xxx_free_sysfs_attr(ha);
5579 7225
7226 qla4xxx_sysfs_ddb_remove(ha);
5580 scsi_remove_host(ha->host); 7227 scsi_remove_host(ha->host);
5581 7228
5582 qla4xxx_free_adapter(ha); 7229 qla4xxx_free_adapter(ha);