Skip to content

Commit

Permalink
[SCSI] qla4xxx: Boot from SAN support for open-iscsi
Browse files Browse the repository at this point in the history
Hook qla4xxx in fw boot sysfs interface so iscsi tools
can use the info to create boot sessions.

Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: Vikas Chaudhary <vikas.chaudhary@qlogic.com>
Signed-off-by: Mike Christie <michaelc@cs.wisc.edu>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Manish Rangankar authored and James Bottomley committed Aug 27, 2011
1 parent 0e7e850 commit 2a991c2
Show file tree
Hide file tree
Showing 7 changed files with 650 additions and 2 deletions.
42 changes: 41 additions & 1 deletion drivers/scsi/qla4xxx/ql4_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ struct ql82xx_hw_data {
uint32_t flt_region_boot;
uint32_t flt_region_bootload;
uint32_t flt_region_fw;

uint32_t flt_iscsi_param;
uint32_t reserved;
};

Expand Down Expand Up @@ -343,6 +345,41 @@ struct ipaddress_config {
struct in6_addr ipv6_default_router_addr;
};

#define QL4_CHAP_MAX_NAME_LEN 256
#define QL4_CHAP_MAX_SECRET_LEN 100

struct ql4_chap_format {
u8 intr_chap_name[QL4_CHAP_MAX_NAME_LEN];
u8 intr_secret[QL4_CHAP_MAX_SECRET_LEN];
u8 target_chap_name[QL4_CHAP_MAX_NAME_LEN];
u8 target_secret[QL4_CHAP_MAX_SECRET_LEN];
u16 intr_chap_name_length;
u16 intr_secret_length;
u16 target_chap_name_length;
u16 target_secret_length;
};

struct ip_address_format {
u8 ip_type;
u8 ip_address[16];
};

struct ql4_conn_info {
u16 dest_port;
struct ip_address_format dest_ipaddr;
struct ql4_chap_format chap;
};

struct ql4_boot_session_info {
u8 target_name[224];
struct ql4_conn_info conn_list[1];
};

struct ql4_boot_tgt_info {
struct ql4_boot_session_info boot_pri_sess;
struct ql4_boot_session_info boot_sec_sess;
};

/*
* Linux Host Adapter structure
*/
Expand Down Expand Up @@ -444,7 +481,7 @@ struct scsi_qla_host {
/* --- From FlashSysInfo --- */
uint8_t my_mac[MAC_ADDR_LEN];
uint8_t serial_number[16];

uint16_t port_num;
/* --- From GetFwState --- */
uint32_t firmware_state;
uint32_t addl_fw_state;
Expand Down Expand Up @@ -569,6 +606,9 @@ struct scsi_qla_host {
#define CHAP_DMA_BLOCK_SIZE 512
struct workqueue_struct *task_wq;
unsigned long ddb_idx_map[MAX_DDB_ENTRIES / BITS_PER_LONG];
#define SYSFS_FLAG_FW_SEL_BOOT 2
struct iscsi_boot_kset *boot_kset;
struct ql4_boot_tgt_info boot_tgt;
};

struct ql4_task_data {
Expand Down
21 changes: 20 additions & 1 deletion drivers/scsi/qla4xxx/ql4_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,13 @@ struct isp_reg {
#define QL4022_NVRAM_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (10+16))
#define QL4022_FLASH_SEM_MASK (QL4022_RESOURCE_MASK_BASE_CODE << (13+16))

/* nvram address for 4032 */
#define NVRAM_PORT0_BOOT_MODE 0x03b1
#define NVRAM_PORT0_BOOT_PRI_TGT 0x03b2
#define NVRAM_PORT0_BOOT_SEC_TGT 0x03bb
#define NVRAM_PORT1_BOOT_MODE 0x07b1
#define NVRAM_PORT1_BOOT_PRI_TGT 0x07b2
#define NVRAM_PORT1_BOOT_SEC_TGT 0x07bb


/* Page # defines for 4022 */
Expand Down Expand Up @@ -298,6 +305,7 @@ struct qla_flt_header {
#define FLT_REG_FW_82 0x74
#define FLT_REG_GOLD_FW_82 0x75
#define FLT_REG_BOOT_CODE_82 0x78
#define FLT_REG_ISCSI_PARAM 0x65

struct qla_flt_region {
uint32_t code;
Expand Down Expand Up @@ -733,7 +741,10 @@ struct dev_db_entry {
uint8_t tcp_rcv_wsf; /* 1C7 */
uint32_t stat_sn; /* 1C8-1CB */
uint32_t exp_stat_sn; /* 1CC-1CF */
uint8_t res6[0x30]; /* 1D0-1FF */
uint8_t res6[0x2b]; /* 1D0-1FB */
#define DDB_VALID_COOKIE 0x9034
uint16_t cookie; /* 1FC-1FD */
uint16_t len; /* 1FE-1FF */
};

/*************************************************************************/
Expand All @@ -745,6 +756,14 @@ struct dev_db_entry {
#define FLASH_EOF_OFFSET (FLASH_DEFAULTBLOCKSIZE-8) /* 4 bytes
* for EOF
* signature */
#define FLASH_RAW_ACCESS_ADDR 0x8e000000

#define BOOT_PARAM_OFFSET_PORT0 0x3b0
#define BOOT_PARAM_OFFSET_PORT1 0x7b0

#define FLASH_OFFSET_DB_INFO 0x05000000
#define FLASH_OFFSET_DB_END (FLASH_OFFSET_DB_INFO + 0x7fff)


struct sys_info_phys_addr {
uint8_t address[6]; /* 00-05 */
Expand Down
7 changes: 7 additions & 0 deletions drivers/scsi/qla4xxx/ql4_glbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ int qla4xxx_get_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
uint32_t *mbox_sts, dma_addr_t acb_dma);
void qla4xxx_mark_device_missing(struct iscsi_cls_session *cls_session);
u16 rd_nvram_word(struct scsi_qla_host *ha, int offset);
u8 rd_nvram_byte(struct scsi_qla_host *ha, int offset);
void qla4xxx_get_crash_record(struct scsi_qla_host *ha);
int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host *ha);
int qla4xxx_about_firmware(struct scsi_qla_host *ha);
Expand Down Expand Up @@ -154,6 +155,12 @@ int qla4xxx_get_mgmt_data(struct scsi_qla_host *ha, uint16_t fw_ddb_index,
uint16_t stats_size, dma_addr_t stats_dma);
void qla4xxx_update_session_conn_param(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry);
int qla4xxx_bootdb_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);
int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username,
char *password, uint16_t idx);

/* BSG Functions */
int qla4xxx_bsg_request(struct bsg_job *bsg_job);
int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job);
Expand Down
77 changes: 77 additions & 0 deletions drivers/scsi/qla4xxx/ql4_mbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,83 @@ int qla4xxx_set_flash(struct scsi_qla_host *ha, dma_addr_t dma_addr,
return status;
}

int qla4xxx_bootdb_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));

dev_db_start_offset += (ddb_index * sizeof(*fw_ddb_entry));
dev_db_end_offset = FLASH_OFFSET_DB_END;

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_bootdb_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_bootdb_failed;
}

if (fw_ddb_entry->cookie == DDB_VALID_COOKIE)
status = QLA_SUCCESS;

exit_bootdb_failed:
return status;
}

int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password,
uint16_t idx)
{
int ret = 0;
int rval = QLA_ERROR;
uint32_t offset = 0;
struct ql4_chap_table *chap_table;
dma_addr_t chap_dma;

chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma);
if (chap_table == NULL) {
ret = -ENOMEM;
goto exit_get_chap;
}

memset(chap_table, 0, sizeof(struct ql4_chap_table));

offset = 0x06000000 | (idx * sizeof(struct ql4_chap_table));

rval = qla4xxx_get_flash(ha, chap_dma, offset,
sizeof(struct ql4_chap_table));
if (rval != QLA_SUCCESS) {
ret = -EINVAL;
goto exit_get_chap;
}

DEBUG2(ql4_printk(KERN_INFO, ha, "Chap Cookie: x%x\n",
__le16_to_cpu(chap_table->cookie)));

if (__le16_to_cpu(chap_table->cookie) != CHAP_VALID_COOKIE) {
ql4_printk(KERN_ERR, ha, "No valid chap entry found\n");
goto exit_get_chap;
}

strncpy(password, chap_table->secret, QL4_CHAP_MAX_SECRET_LEN);
strncpy(username, chap_table->name, QL4_CHAP_MAX_NAME_LEN);
chap_table->cookie = __constant_cpu_to_le16(CHAP_VALID_COOKIE);

exit_get_chap:
dma_pool_free(ha->chap_dma_pool, chap_table, chap_dma);
return ret;
}

static int qla4xxx_set_chap(struct scsi_qla_host *ha, char *username,
char *password, uint16_t idx, int bidi)
{
Expand Down
21 changes: 21 additions & 0 deletions drivers/scsi/qla4xxx/ql4_nvram.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,27 @@ u16 rd_nvram_word(struct scsi_qla_host * ha, int offset)
return val;
}

u8 rd_nvram_byte(struct scsi_qla_host *ha, int offset)
{
u16 val = 0;
u8 rval = 0;
int index = 0;

if (offset & 0x1)
index = (offset - 1) / 2;
else
index = offset / 2;

val = le16_to_cpu(rd_nvram_word(ha, index));

if (offset & 0x1)
rval = (u8)((val & 0xff00) >> 8);
else
rval = (u8)((val & 0x00ff));

return rval;
}

int qla4xxx_is_nvram_configuration_valid(struct scsi_qla_host * ha)
{
int status = QLA_ERROR;
Expand Down
4 changes: 4 additions & 0 deletions drivers/scsi/qla4xxx/ql4_nx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2020,6 +2020,9 @@ qla4_8xxx_get_flt_info(struct scsi_qla_host *ha, uint32_t flt_addr)
case FLT_REG_BOOTLOAD_82:
hw->flt_region_bootload = start;
break;
case FLT_REG_ISCSI_PARAM:
hw->flt_iscsi_param = start;
break;
}
}
goto done;
Expand Down Expand Up @@ -2258,6 +2261,7 @@ int qla4_8xxx_get_sys_info(struct scsi_qla_host *ha)
}

/* Save M.A.C. address & serial_number */
ha->port_num = sys_info->port_num;
memcpy(ha->my_mac, &sys_info->mac_addr[0],
min(sizeof(ha->my_mac), sizeof(sys_info->mac_addr)));
memcpy(ha->serial_number, &sys_info->serial_number,
Expand Down
Loading

0 comments on commit 2a991c2

Please sign in to comment.