Skip to content

Commit

Permalink
[SCSI] qla4xxx: support iscsiadm session mgmt
Browse files Browse the repository at this point in the history
Add scsi_transport_iscsi hooks in qla4xxx to support
iSCSI session management using iscsiadm.

This patch is based on discussion here
http://groups.google.com/group/open-iscsi/browse_thread/thread/e89fd888baf656a0#

Now users can use iscsiadm to do target discovery and do login/logout to
individual targets using the qla4xxx iSCSI class interface.

This patch leaves some dead code, but to make it easier to review
we are leaving and in the next patch we will remove that old code.

V2 - NOTE: Added code to avoid waiting for AEN during login/logout
in the driver, instead added a kernel to user event
to notify iscsid about login status. Because of this
iscsid will not get blocked.

Signed-off-by: Manish Rangankar <manish.rangankar@qlogic.com>
Signed-off-by: Lalit Chandivade <lalit.chandivade@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 17fa575 commit b3a271a
Show file tree
Hide file tree
Showing 8 changed files with 1,416 additions and 365 deletions.
36 changes: 32 additions & 4 deletions drivers/scsi/qla4xxx/ql4_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,12 @@
#include <scsi/scsi_transport_iscsi.h>
#include <scsi/scsi_bsg_iscsi.h>
#include <scsi/scsi_netlink.h>
#include <scsi/libiscsi.h>

#include "ql4_dbg.h"
#include "ql4_nx.h"
#include "ql4_fw.h"
#include "ql4_nvram.h"

#ifndef PCI_DEVICE_ID_QLOGIC_ISP4010
#define PCI_DEVICE_ID_QLOGIC_ISP4010 0x4010
Expand Down Expand Up @@ -112,7 +115,7 @@
#define MAX_BUSES 1
#define MAX_TARGETS MAX_DEV_DB_ENTRIES
#define MAX_LUNS 0xffff
#define MAX_AEN_ENTRIES 256 /* should be > EXT_DEF_MAX_AEN_QUEUE */
#define MAX_AEN_ENTRIES MAX_DEV_DB_ENTRIES
#define MAX_DDB_ENTRIES MAX_DEV_DB_ENTRIES
#define MAX_PDU_ENTRIES 32
#define INVALID_ENTRY 0xFFFF
Expand Down Expand Up @@ -296,8 +299,6 @@ struct ddb_entry {
#define DF_FO_MASKED 3


#include "ql4_fw.h"
#include "ql4_nvram.h"

struct ql82xx_hw_data {
/* Offsets for flash/nvram access (set to ~0 if not used). */
Expand Down Expand Up @@ -607,6 +608,33 @@ struct scsi_qla_host {
#define QLFLASH_WAITING 0
#define QLFLASH_READING 1
#define QLFLASH_WRITING 2
struct dma_pool *chap_dma_pool;
#define CHAP_DMA_BLOCK_SIZE 512
struct workqueue_struct *task_wq;
unsigned long ddb_idx_map[MAX_DDB_ENTRIES / BITS_PER_LONG];
};

struct ql4_task_data {
struct scsi_qla_host *ha;
uint8_t iocb_req_cnt;
dma_addr_t data_dma;
void *req_buffer;
dma_addr_t req_dma;
void *resp_buffer;
dma_addr_t resp_dma;
uint32_t resp_len;
struct iscsi_task *task;
struct passthru_status sts;
struct work_struct task_work;
};

struct qla_endpoint {
struct Scsi_Host *host;
struct sockaddr dst_addr;
};

struct qla_conn {
struct qla_endpoint *qla_ep;
};

static inline int is_ipv4_enabled(struct scsi_qla_host *ha)
Expand Down Expand Up @@ -657,7 +685,7 @@ static inline int adapter_up(struct scsi_qla_host *ha)

static inline struct scsi_qla_host* to_qla_host(struct Scsi_Host *shost)
{
return (struct scsi_qla_host *)shost->hostdata;
return (struct scsi_qla_host *)iscsi_host_priv(shost);
}

static inline void __iomem* isp_semaphore(struct scsi_qla_host *ha)
Expand Down
82 changes: 75 additions & 7 deletions drivers/scsi/qla4xxx/ql4_fw.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,11 @@ struct qla_flt_region {
#define MBOX_CMD_WRITE_FLASH 0x0025
#define MBOX_CMD_READ_FLASH 0x0026
#define MBOX_CMD_CLEAR_DATABASE_ENTRY 0x0031
#define MBOX_CMD_CONN_OPEN 0x0074
#define MBOX_CMD_CONN_CLOSE_SESS_LOGOUT 0x0056
#define LOGOUT_OPTION_CLOSE_SESSION 0x01
#define LOGOUT_OPTION_RELOGIN 0x02
#define LOGOUT_OPTION_CLOSE_SESSION 0x0002
#define LOGOUT_OPTION_RELOGIN 0x0004
#define LOGOUT_OPTION_FREE_DDB 0x0008
#define MBOX_CMD_EXECUTE_IOCB_A64 0x005A
#define MBOX_CMD_INITIALIZE_FIRMWARE 0x0060
#define MBOX_CMD_GET_INIT_FW_CTRL_BLOCK 0x0061
Expand All @@ -342,6 +344,7 @@ struct qla_flt_region {
#define MBOX_CMD_GET_DATABASE_ENTRY 0x0064
#define DDB_DS_UNASSIGNED 0x00
#define DDB_DS_NO_CONNECTION_ACTIVE 0x01
#define DDB_DS_DISCOVERY 0x02
#define DDB_DS_SESSION_ACTIVE 0x04
#define DDB_DS_SESSION_FAILED 0x06
#define DDB_DS_LOGIN_IN_PROCESS 0x07
Expand Down Expand Up @@ -375,7 +378,10 @@ struct qla_flt_region {
#define FW_ADDSTATE_DHCPv4_LEASE_EXPIRED 0x0008
#define FW_ADDSTATE_LINK_UP 0x0010
#define FW_ADDSTATE_ISNS_SVC_ENABLED 0x0020

#define MBOX_CMD_GET_DATABASE_ENTRY_DEFAULTS 0x006B
#define IPV6_DEFAULT_DDB_ENTRY 0x0001

#define MBOX_CMD_CONN_OPEN_SESS_LOGIN 0x0074
#define MBOX_CMD_GET_CRASH_RECORD 0x0076 /* 4010 only */
#define MBOX_CMD_GET_CONN_EVENT_LOG 0x0077
Expand Down Expand Up @@ -463,7 +469,8 @@ struct addr_ctrl_blk {
uint8_t res0; /* 07 */
uint16_t eth_mtu_size; /* 08-09 */
uint16_t add_fw_options; /* 0A-0B */
#define SERIALIZE_TASK_MGMT 0x0400
#define ADFWOPT_SERIALIZE_TASK_MGMT 0x0400
#define ADFWOPT_AUTOCONN_DISABLE 0x0002

uint8_t hb_interval; /* 0C */
uint8_t inst_num; /* 0D */
Expand Down Expand Up @@ -655,11 +662,30 @@ struct addr_ctrl_blk_def {

/*************************************************************************/

#define MAX_CHAP_ENTRIES_40XX 128
#define MAX_CHAP_ENTRIES_82XX 1024

struct ql4_chap_table {
uint16_t link;
uint8_t flags;
uint8_t secret_len;
#define MIN_CHAP_SECRET_LEN 12
#define MAX_CHAP_SECRET_LEN 100
uint8_t secret[MAX_CHAP_SECRET_LEN];
#define MAX_CHAP_NAME_LEN 256
uint8_t name[MAX_CHAP_NAME_LEN];
uint16_t reserved;
#define CHAP_VALID_COOKIE 0x4092
#define CHAP_INVALID_COOKIE 0xFFEE
uint16_t cookie;
};

struct dev_db_entry {
uint16_t options; /* 00-01 */
#define DDB_OPT_DISC_SESSION 0x10
#define DDB_OPT_TARGET 0x02 /* device is a target */
#define DDB_OPT_IPV6_DEVICE 0x100
#define DDB_OPT_AUTO_SENDTGTS_DISABLE 0x40
#define DDB_OPT_IPV6_NULL_LINK_LOCAL 0x800 /* post connection */
#define DDB_OPT_IPV6_FW_DEFINED_LINK_LOCAL 0x800 /* pre connection */

Expand All @@ -670,6 +696,7 @@ struct dev_db_entry {
uint16_t tcp_options; /* 0A-0B */
uint16_t ip_options; /* 0C-0D */
uint16_t iscsi_max_rcv_data_seg_len; /* 0E-0F */
#define BYTE_UNITS 512
uint32_t res1; /* 10-13 */
uint16_t iscsi_max_snd_data_seg_len; /* 14-15 */
uint16_t iscsi_first_burst_len; /* 16-17 */
Expand Down Expand Up @@ -853,6 +880,7 @@ struct qla4_header {

uint8_t entryStatus;
uint8_t systemDefined;
#define SD_ISCSI_PDU 0x01
uint8_t entryCount;

/* SyetemDefined definition */
Expand Down Expand Up @@ -1010,21 +1038,22 @@ struct passthru0 {
struct qla4_header hdr; /* 00-03 */
uint32_t handle; /* 04-07 */
uint16_t target; /* 08-09 */
uint16_t connectionID; /* 0A-0B */
uint16_t connection_id; /* 0A-0B */
#define ISNS_DEFAULT_SERVER_CONN_ID ((uint16_t)0x8000)

uint16_t controlFlags; /* 0C-0D */
uint16_t control_flags; /* 0C-0D */
#define PT_FLAG_ETHERNET_FRAME 0x8000
#define PT_FLAG_ISNS_PDU 0x8000
#define PT_FLAG_SEND_BUFFER 0x0200
#define PT_FLAG_WAIT_4_RESPONSE 0x0100
#define PT_FLAG_ISCSI_PDU 0x1000

uint16_t timeout; /* 0E-0F */
#define PT_DEFAULT_TIMEOUT 30 /* seconds */

struct data_seg_a64 outDataSeg64; /* 10-1B */
struct data_seg_a64 out_dsd; /* 10-1B */
uint32_t res1; /* 1C-1F */
struct data_seg_a64 inDataSeg64; /* 20-2B */
struct data_seg_a64 in_dsd; /* 20-2B */
uint8_t res2[20]; /* 2C-3F */
};

Expand Down Expand Up @@ -1057,4 +1086,43 @@ struct response {
#define RESPONSE_PROCESSED 0xDEADDEAD /* Signature */
};

struct ql_iscsi_stats {
uint8_t reserved1[656]; /* 0000-028F */
uint32_t tx_cmd_pdu; /* 0290-0293 */
uint32_t tx_resp_pdu; /* 0294-0297 */
uint32_t rx_cmd_pdu; /* 0298-029B */
uint32_t rx_resp_pdu; /* 029C-029F */

uint64_t tx_data_octets; /* 02A0-02A7 */
uint64_t rx_data_octets; /* 02A8-02AF */

uint32_t hdr_digest_err; /* 02B0–02B3 */
uint32_t data_digest_err; /* 02B4–02B7 */
uint32_t conn_timeout_err; /* 02B8–02BB */
uint32_t framing_err; /* 02BC–02BF */

uint32_t tx_nopout_pdus; /* 02C0–02C3 */
uint32_t tx_scsi_cmd_pdus; /* 02C4–02C7 */
uint32_t tx_tmf_cmd_pdus; /* 02C8–02CB */
uint32_t tx_login_cmd_pdus; /* 02CC–02CF */
uint32_t tx_text_cmd_pdus; /* 02D0–02D3 */
uint32_t tx_scsi_write_pdus; /* 02D4–02D7 */
uint32_t tx_logout_cmd_pdus; /* 02D8–02DB */
uint32_t tx_snack_req_pdus; /* 02DC–02DF */

uint32_t rx_nopin_pdus; /* 02E0–02E3 */
uint32_t rx_scsi_resp_pdus; /* 02E4–02E7 */
uint32_t rx_tmf_resp_pdus; /* 02E8–02EB */
uint32_t rx_login_resp_pdus; /* 02EC–02EF */
uint32_t rx_text_resp_pdus; /* 02F0–02F3 */
uint32_t rx_scsi_read_pdus; /* 02F4–02F7 */
uint32_t rx_logout_resp_pdus; /* 02F8–02FB */

uint32_t rx_r2t_pdus; /* 02FC–02FF */
uint32_t rx_async_pdus; /* 0300–0303 */
uint32_t rx_reject_pdus; /* 0304–0307 */

uint8_t reserved2[264]; /* 0x0308 - 0x040F */
};

#endif /* _QLA4X_FW_H */
21 changes: 17 additions & 4 deletions drivers/scsi/qla4xxx/ql4_glbl.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ int qla4xxx_get_fwddb_entry(struct scsi_qla_host *ha,
uint16_t *connection_id);

int qla4xxx_set_ddb_entry(struct scsi_qla_host * ha, uint16_t fw_ddb_index,
dma_addr_t fw_ddb_entry_dma);
dma_addr_t fw_ddb_entry_dma, uint32_t *mbx_sts);
uint8_t qla4xxx_get_ifcb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
uint32_t *mbox_sts, dma_addr_t init_fw_cb_dma);
int qla4xxx_conn_close_sess_logout(struct scsi_qla_host *ha,
Expand All @@ -63,8 +63,7 @@ int qla4xxx_set_acb(struct scsi_qla_host *ha, uint32_t *mbox_cmd,
uint32_t *mbox_sts, dma_addr_t acb_dma);
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 scsi_qla_host *ha,
struct ddb_entry *ddb_entry);
void qla4xxx_mark_device_missing(struct iscsi_cls_session *cls_session);
u16 rd_nvram_word(struct scsi_qla_host *ha, int offset);
void qla4xxx_get_crash_record(struct scsi_qla_host *ha);
struct ddb_entry *qla4xxx_alloc_sess(struct scsi_qla_host *ha);
Expand Down Expand Up @@ -150,7 +149,21 @@ int qla4_8xxx_device_state_handler(struct scsi_qla_host *ha);
void qla4_8xxx_need_qsnt_handler(struct scsi_qla_host *ha);
void qla4_8xxx_clear_drv_active(struct scsi_qla_host *ha);
void qla4_8xxx_set_drv_active(struct scsi_qla_host *ha);

int qla4xxx_conn_open(struct scsi_qla_host *ha, uint16_t fw_ddb_index);
int qla4xxx_set_param_ddbentry(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry,
struct iscsi_cls_conn *cls_conn,
uint32_t *mbx_sts);
int qla4xxx_session_logout_ddb(struct scsi_qla_host *ha,
struct ddb_entry *ddb_entry, int options);
int qla4xxx_req_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index,
uint32_t *mbx_sts);
int qla4xxx_clear_ddb_entry(struct scsi_qla_host *ha, uint32_t fw_ddb_index);
int qla4xxx_send_passthru0(struct iscsi_task *task);
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);
/* BSG Functions */
int qla4xxx_bsg_request(struct bsg_job *bsg_job);
int qla4xxx_process_vendor_specific(struct bsg_job *bsg_job);
Expand Down
Loading

0 comments on commit b3a271a

Please sign in to comment.