mirror of
https://github.com/torvalds/linux.git
synced 2024-11-26 14:12:06 +00:00
[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>
This commit is contained in:
parent
adaf6990dd
commit
1e9e2be3ee
@ -159,6 +159,25 @@
|
||||
#define LSDW(x) ((u32)((u64)(x)))
|
||||
#define MSDW(x) ((u32)((((u64)(x)) >> 16) >> 16))
|
||||
|
||||
#define DEV_TYPE_IPV4 "ipv4"
|
||||
#define DEV_TYPE_IPV6 "ipv6"
|
||||
|
||||
#define DEV_DB_NON_PERSISTENT 0
|
||||
#define DEV_DB_PERSISTENT 1
|
||||
|
||||
#define COPY_ISID(dst_isid, src_isid) { \
|
||||
int i, j; \
|
||||
for (i = 0, j = ISID_SIZE - 1; i < ISID_SIZE;) \
|
||||
dst_isid[i++] = src_isid[j--]; \
|
||||
}
|
||||
|
||||
#define SET_BITVAL(o, n, v) { \
|
||||
if (o) \
|
||||
n |= v; \
|
||||
else \
|
||||
n &= ~v; \
|
||||
}
|
||||
|
||||
/*
|
||||
* Retry & Timeout Values
|
||||
*/
|
||||
@ -363,6 +382,8 @@ struct ql82xx_hw_data {
|
||||
uint32_t flt_iscsi_param;
|
||||
uint32_t flt_region_chap;
|
||||
uint32_t flt_chap_size;
|
||||
uint32_t flt_region_ddb;
|
||||
uint32_t flt_ddb_size;
|
||||
};
|
||||
|
||||
struct qla4_8xxx_legacy_intr_set {
|
||||
@ -501,6 +522,7 @@ struct scsi_qla_host {
|
||||
#define AF_INIT_DONE 1 /* 0x00000002 */
|
||||
#define AF_MBOX_COMMAND 2 /* 0x00000004 */
|
||||
#define AF_MBOX_COMMAND_DONE 3 /* 0x00000008 */
|
||||
#define AF_ST_DISCOVERY_IN_PROGRESS 4 /* 0x00000010 */
|
||||
#define AF_INTERRUPTS_ON 6 /* 0x00000040 */
|
||||
#define AF_GET_CRASH_RECORD 7 /* 0x00000080 */
|
||||
#define AF_LINK_UP 8 /* 0x00000100 */
|
||||
|
@ -288,6 +288,8 @@ union external_hw_config_reg {
|
||||
#define FA_GOLD_RISC_CODE_ADDR_82 0x80000
|
||||
#define FA_FLASH_ISCSI_CHAP 0x540000
|
||||
#define FA_FLASH_CHAP_SIZE 0xC0000
|
||||
#define FA_FLASH_ISCSI_DDB 0x420000
|
||||
#define FA_FLASH_DDB_SIZE 0x080000
|
||||
|
||||
/* Flash Description Table */
|
||||
struct qla_fdt_layout {
|
||||
@ -348,6 +350,7 @@ struct qla_flt_header {
|
||||
#define FLT_REG_BOOT_CODE_82 0x78
|
||||
#define FLT_REG_ISCSI_PARAM 0x65
|
||||
#define FLT_REG_ISCSI_CHAP 0x63
|
||||
#define FLT_REG_ISCSI_DDB 0x6A
|
||||
|
||||
struct qla_flt_region {
|
||||
uint32_t code;
|
||||
@ -779,12 +782,41 @@ struct dev_db_entry {
|
||||
#define DDB_OPT_IPV6_NULL_LINK_LOCAL 0x800 /* post connection */
|
||||
#define DDB_OPT_IPV6_FW_DEFINED_LINK_LOCAL 0x800 /* pre connection */
|
||||
|
||||
#define OPT_IS_FW_ASSIGNED_IPV6 11
|
||||
#define OPT_IPV6_DEVICE 8
|
||||
#define OPT_AUTO_SENDTGTS_DISABLE 6
|
||||
#define OPT_DISC_SESSION 4
|
||||
#define OPT_ENTRY_STATE 3
|
||||
uint16_t exec_throttle; /* 02-03 */
|
||||
uint16_t exec_count; /* 04-05 */
|
||||
uint16_t res0; /* 06-07 */
|
||||
uint16_t iscsi_options; /* 08-09 */
|
||||
#define ISCSIOPT_HEADER_DIGEST_EN 13
|
||||
#define ISCSIOPT_DATA_DIGEST_EN 12
|
||||
#define ISCSIOPT_IMMEDIATE_DATA_EN 11
|
||||
#define ISCSIOPT_INITIAL_R2T_EN 10
|
||||
#define ISCSIOPT_DATA_SEQ_IN_ORDER 9
|
||||
#define ISCSIOPT_DATA_PDU_IN_ORDER 8
|
||||
#define ISCSIOPT_CHAP_AUTH_EN 7
|
||||
#define ISCSIOPT_SNACK_REQ_EN 6
|
||||
#define ISCSIOPT_DISCOVERY_LOGOUT_EN 5
|
||||
#define ISCSIOPT_BIDI_CHAP_EN 4
|
||||
#define ISCSIOPT_DISCOVERY_AUTH_OPTIONAL 3
|
||||
#define ISCSIOPT_ERL1 1
|
||||
#define ISCSIOPT_ERL0 0
|
||||
|
||||
uint16_t tcp_options; /* 0A-0B */
|
||||
#define TCPOPT_TIMESTAMP_STAT 6
|
||||
#define TCPOPT_NAGLE_DISABLE 5
|
||||
#define TCPOPT_WSF_DISABLE 4
|
||||
#define TCPOPT_TIMER_SCALE3 3
|
||||
#define TCPOPT_TIMER_SCALE2 2
|
||||
#define TCPOPT_TIMER_SCALE1 1
|
||||
#define TCPOPT_TIMESTAMP_EN 0
|
||||
|
||||
uint16_t ip_options; /* 0C-0D */
|
||||
#define IPOPT_FRAGMENT_DISABLE 4
|
||||
|
||||
uint16_t iscsi_max_rcv_data_seg_len; /* 0E-0F */
|
||||
#define BYTE_UNITS 512
|
||||
uint32_t res1; /* 10-13 */
|
||||
@ -816,6 +848,8 @@ struct dev_db_entry {
|
||||
* much RAM */
|
||||
uint8_t link_local_ipv6_addr[0x10]; /* 1A0-1AF */
|
||||
uint8_t res5[0x10]; /* 1B0-1BF */
|
||||
#define DDB_NO_LINK 0xFFFF
|
||||
#define DDB_ISNS 0xFFFD
|
||||
uint16_t ddb_link; /* 1C0-1C1 */
|
||||
uint16_t chap_tbl_idx; /* 1C2-1C3 */
|
||||
uint16_t tgt_portal_grp; /* 1C4-1C5 */
|
||||
|
@ -191,6 +191,9 @@ int qla4xxx_ping_iocb(struct scsi_qla_host *ha, uint32_t options,
|
||||
int qla4xxx_post_ping_evt_work(struct scsi_qla_host *ha,
|
||||
uint32_t status, uint32_t pid,
|
||||
uint32_t data_size, uint8_t *data);
|
||||
int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
|
||||
struct dev_db_entry *fw_ddb_entry,
|
||||
dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index);
|
||||
|
||||
/* BSG Functions */
|
||||
int qla4xxx_bsg_request(struct bsg_job *bsg_job);
|
||||
@ -259,6 +262,10 @@ int qla4_83xx_post_idc_ack(struct scsi_qla_host *ha);
|
||||
void qla4_83xx_disable_pause(struct scsi_qla_host *ha);
|
||||
void qla4_83xx_enable_mbox_intrs(struct scsi_qla_host *ha);
|
||||
int qla4_83xx_can_perform_reset(struct scsi_qla_host *ha);
|
||||
int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
|
||||
dma_addr_t dma_addr);
|
||||
int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
|
||||
char *password, uint16_t chap_index);
|
||||
|
||||
extern int ql4xextended_error_logging;
|
||||
extern int ql4xdontresethba;
|
||||
|
@ -1288,8 +1288,8 @@ exit_about_fw:
|
||||
return status;
|
||||
}
|
||||
|
||||
static int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
|
||||
dma_addr_t dma_addr)
|
||||
int qla4xxx_get_default_ddb(struct scsi_qla_host *ha, uint32_t options,
|
||||
dma_addr_t dma_addr)
|
||||
{
|
||||
uint32_t mbox_cmd[MBOX_REG_COUNT];
|
||||
uint32_t mbox_sts[MBOX_REG_COUNT];
|
||||
@ -1417,6 +1417,52 @@ exit_bootdb_failed:
|
||||
return status;
|
||||
}
|
||||
|
||||
int qla4xxx_flashdb_by_index(struct scsi_qla_host *ha,
|
||||
struct dev_db_entry *fw_ddb_entry,
|
||||
dma_addr_t fw_ddb_entry_dma, uint16_t ddb_index)
|
||||
{
|
||||
uint32_t dev_db_start_offset = FLASH_OFFSET_DB_INFO;
|
||||
uint32_t dev_db_end_offset;
|
||||
int status = QLA_ERROR;
|
||||
|
||||
memset(fw_ddb_entry, 0, sizeof(*fw_ddb_entry));
|
||||
|
||||
if (is_qla40XX(ha)) {
|
||||
dev_db_start_offset = FLASH_OFFSET_DB_INFO;
|
||||
} else {
|
||||
dev_db_start_offset = FLASH_RAW_ACCESS_ADDR +
|
||||
(ha->hw.flt_region_ddb << 2);
|
||||
/* flt_ddb_size is DDB table size for both ports
|
||||
* so divide it by 2 to calculate the offset for second port
|
||||
*/
|
||||
if (ha->port_num == 1)
|
||||
dev_db_start_offset += (ha->hw.flt_ddb_size / 2);
|
||||
}
|
||||
|
||||
dev_db_end_offset = dev_db_start_offset + (ha->hw.flt_ddb_size / 2);
|
||||
dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));
|
||||
|
||||
if (dev_db_start_offset > dev_db_end_offset) {
|
||||
DEBUG2(ql4_printk(KERN_ERR, ha,
|
||||
"%s:Invalid DDB index %d", __func__,
|
||||
ddb_index));
|
||||
goto exit_fdb_failed;
|
||||
}
|
||||
|
||||
if (qla4xxx_get_flash(ha, fw_ddb_entry_dma, dev_db_start_offset,
|
||||
sizeof(*fw_ddb_entry)) != QLA_SUCCESS) {
|
||||
ql4_printk(KERN_ERR, ha, "scsi%ld: %s: Get Flash failed\n",
|
||||
ha->host_no, __func__);
|
||||
goto exit_fdb_failed;
|
||||
}
|
||||
|
||||
if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
|
||||
status = QLA_SUCCESS;
|
||||
|
||||
exit_fdb_failed:
|
||||
return status;
|
||||
}
|
||||
|
||||
int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
|
||||
uint16_t idx)
|
||||
{
|
||||
@ -1510,6 +1556,62 @@ exit_set_chap:
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int qla4xxx_get_uni_chap_at_index(struct scsi_qla_host *ha, char *username,
|
||||
char *password, uint16_t chap_index)
|
||||
{
|
||||
int rval = QLA_ERROR;
|
||||
struct ql4_chap_table *chap_table = NULL;
|
||||
int max_chap_entries;
|
||||
|
||||
if (!ha->chap_list) {
|
||||
ql4_printk(KERN_ERR, ha, "Do not have CHAP table cache\n");
|
||||
rval = QLA_ERROR;
|
||||
goto exit_uni_chap;
|
||||
}
|
||||
|
||||
if (!username || !password) {
|
||||
ql4_printk(KERN_ERR, ha, "No memory for username & secret\n");
|
||||
rval = QLA_ERROR;
|
||||
goto exit_uni_chap;
|
||||
}
|
||||
|
||||
if (is_qla80XX(ha))
|
||||
max_chap_entries = (ha->hw.flt_chap_size / 2) /
|
||||
sizeof(struct ql4_chap_table);
|
||||
else
|
||||
max_chap_entries = MAX_CHAP_ENTRIES_40XX;
|
||||
|
||||
if (chap_index > max_chap_entries) {
|
||||
ql4_printk(KERN_ERR, ha, "Invalid Chap index\n");
|
||||
rval = QLA_ERROR;
|
||||
goto exit_uni_chap;
|
||||
}
|
||||
|
||||
mutex_lock(&ha->chap_sem);
|
||||
chap_table = (struct ql4_chap_table *)ha->chap_list + chap_index;
|
||||
if (chap_table->cookie != __constant_cpu_to_le16(CHAP_VALID_COOKIE)) {
|
||||
rval = QLA_ERROR;
|
||||
goto exit_unlock_uni_chap;
|
||||
}
|
||||
|
||||
if (!(chap_table->flags & BIT_6)) {
|
||||
ql4_printk(KERN_ERR, ha, "Unidirectional entry not set\n");
|
||||
rval = QLA_ERROR;
|
||||
goto exit_unlock_uni_chap;
|
||||
}
|
||||
|
||||
strncpy(password, chap_table->secret, MAX_CHAP_SECRET_LEN);
|
||||
strncpy(username, chap_table->name, MAX_CHAP_NAME_LEN);
|
||||
|
||||
rval = QLA_SUCCESS;
|
||||
|
||||
exit_unlock_uni_chap:
|
||||
mutex_unlock(&ha->chap_sem);
|
||||
exit_uni_chap:
|
||||
return rval;
|
||||
}
|
||||
|
||||
/**
|
||||
* qla4xxx_get_chap_index - Get chap index given username and secret
|
||||
* @ha: pointer to adapter structure
|
||||
|
@ -3154,6 +3154,10 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
|
||||
hw->flt_region_chap = start;
|
||||
hw->flt_chap_size = le32_to_cpu(region->size);
|
||||
break;
|
||||
case FLT_REG_ISCSI_DDB:
|
||||
hw->flt_region_ddb = start;
|
||||
hw->flt_ddb_size = le32_to_cpu(region->size);
|
||||
break;
|
||||
}
|
||||
}
|
||||
goto done;
|
||||
@ -3168,13 +3172,17 @@ no_flash_data:
|
||||
hw->flt_region_fw = FA_RISC_CODE_ADDR_82;
|
||||
hw->flt_region_chap = FA_FLASH_ISCSI_CHAP >> 2;
|
||||
hw->flt_chap_size = FA_FLASH_CHAP_SIZE;
|
||||
hw->flt_region_ddb = FA_FLASH_ISCSI_DDB >> 2;
|
||||
hw->flt_ddb_size = FA_FLASH_DDB_SIZE;
|
||||
|
||||
done:
|
||||
DEBUG2(ql4_printk(KERN_INFO, ha,
|
||||
"FLT[%s]: flt=0x%x fdt=0x%x boot=0x%x bootload=0x%x fw=0x%x chap=0x%x\n",
|
||||
"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",
|
||||
loc, hw->flt_region_flt, hw->flt_region_fdt,
|
||||
hw->flt_region_boot, hw->flt_region_bootload,
|
||||
hw->flt_region_fw, hw->flt_region_chap));
|
||||
hw->flt_region_fw, hw->flt_region_chap,
|
||||
hw->flt_chap_size, hw->flt_region_ddb,
|
||||
hw->flt_ddb_size));
|
||||
}
|
||||
|
||||
static void
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user