Commit 726b8548 authored by Quinn Tran's avatar Quinn Tran Committed by Nicholas Bellinger

qla2xxx: Add framework for async fabric discovery

Currently code performs a full scan of the fabric for
every RSCN. Its an expensive process in a noisy large SAN.

This patch optimizes expensive fabric discovery process by
scanning switch for the affected port when RSCN is received.

Currently Initiator Mode code makes login/logout decision without
knowledge of target mode. This causes driver and firmware to go
out-of-sync. This framework synchronizes both initiator mode
personality and target mode personality in making login/logout
decision.

This patch adds following capabilities in the driver

- Send Notification Acknowledgement asynchronously.
- Update session/fcport state asynchronously.
- Create a session or fcport struct asynchronously.
- Send GNL asynchronously. The command will ask FW to
  provide a list of FC Port entries FW knows about.
- Send GPDB asynchronously. The command will ask FW to
  provide detail data of an FC Port FW knows about or
  perform ADISC to verify the state of the session.
- Send GPNID asynchronously. The command will ask switch
  to provide WWPN for provided NPort ID.
- Send GPSC asynchronously. The command will ask switch
  to provide registered port speed for provided WWPN.
- Send GIDPN asynchronously. The command will ask the
  switch to provide Nport ID for provided WWPN.
- In driver unload path, schedule all session for deletion
  and wait for deletion to complete before allowing driver
  unload to proceed.
Signed-off-by: default avatarQuinn Tran <quinn.tran@cavium.com>
Signed-off-by: default avatarHimanshu Madhani <himanshu.madhani@cavium.com>
[ bvanassche: fixed spelling in patch description ]
Signed-off-by: default avatarBart Van Assche <bart.vanassche@sandisk.com>
Signed-off-by: default avatarNicholas Bellinger <nab@linux-iscsi.org>
parent 5d964837
...@@ -2163,6 +2163,9 @@ qla24xx_vport_delete(struct fc_vport *fc_vport) ...@@ -2163,6 +2163,9 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
clear_bit(vha->vp_idx, ha->vp_idx_map); clear_bit(vha->vp_idx, ha->vp_idx_map);
mutex_unlock(&ha->vport_lock); mutex_unlock(&ha->vport_lock);
dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l,
vha->gnl.ldma);
if (vha->qpair->vp_idx == vha->vp_idx) { if (vha->qpair->vp_idx == vha->vp_idx) {
if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS)
ql_log(ql_log_warn, vha, 0x7087, ql_log(ql_log_warn, vha, 0x7087,
......
...@@ -55,6 +55,8 @@ ...@@ -55,6 +55,8 @@
#include "qla_settings.h" #include "qla_settings.h"
#define MODE_DUAL (MODE_TARGET | MODE_INITIATOR)
/* /*
* Data bit definitions * Data bit definitions
*/ */
...@@ -251,6 +253,14 @@ ...@@ -251,6 +253,14 @@
#define MAX_CMDSZ 16 /* SCSI maximum CDB size. */ #define MAX_CMDSZ 16 /* SCSI maximum CDB size. */
#include "qla_fw.h" #include "qla_fw.h"
struct name_list_extended {
struct get_name_list_extended *l;
dma_addr_t ldma;
struct list_head fcports; /* protect by sess_list */
u32 size;
u8 sent;
};
/* /*
* Timeout timer counts in seconds * Timeout timer counts in seconds
*/ */
...@@ -309,6 +319,17 @@ struct els_logo_payload { ...@@ -309,6 +319,17 @@ struct els_logo_payload {
uint8_t wwpn[WWN_SIZE]; uint8_t wwpn[WWN_SIZE];
}; };
struct ct_arg {
void *iocb;
u16 nport_handle;
dma_addr_t req_dma;
dma_addr_t rsp_dma;
u32 req_size;
u32 rsp_size;
void *req;
void *rsp;
};
/* /*
* SRB extensions. * SRB extensions.
*/ */
...@@ -320,6 +341,7 @@ struct srb_iocb { ...@@ -320,6 +341,7 @@ struct srb_iocb {
#define SRB_LOGIN_COND_PLOGI BIT_1 #define SRB_LOGIN_COND_PLOGI BIT_1
#define SRB_LOGIN_SKIP_PRLI BIT_2 #define SRB_LOGIN_SKIP_PRLI BIT_2
uint16_t data[2]; uint16_t data[2];
u32 iop[2];
} logio; } logio;
struct { struct {
#define ELS_DCMD_TIMEOUT 20 #define ELS_DCMD_TIMEOUT 20
...@@ -372,6 +394,16 @@ struct srb_iocb { ...@@ -372,6 +394,16 @@ struct srb_iocb {
__le16 comp_status; __le16 comp_status;
struct completion comp; struct completion comp;
} abt; } abt;
struct ct_arg ctarg;
struct {
__le16 in_mb[28]; /* fr fw */
__le16 out_mb[28]; /* to fw */
void *out, *in;
dma_addr_t out_dma, in_dma;
} mbx;
struct {
struct imm_ntfy_from_isp *ntfy;
} nack;
} u; } u;
struct timer_list timer; struct timer_list timer;
...@@ -392,16 +424,24 @@ struct srb_iocb { ...@@ -392,16 +424,24 @@ struct srb_iocb {
#define SRB_FXIOCB_BCMD 11 #define SRB_FXIOCB_BCMD 11
#define SRB_ABT_CMD 12 #define SRB_ABT_CMD 12
#define SRB_ELS_DCMD 13 #define SRB_ELS_DCMD 13
#define SRB_MB_IOCB 14
#define SRB_CT_PTHRU_CMD 15
#define SRB_NACK_PLOGI 16
#define SRB_NACK_PRLI 17
#define SRB_NACK_LOGO 18
typedef struct srb { typedef struct srb {
atomic_t ref_count; atomic_t ref_count;
struct fc_port *fcport; struct fc_port *fcport;
void *vha;
uint32_t handle; uint32_t handle;
uint16_t flags; uint16_t flags;
uint16_t type; uint16_t type;
char *name; char *name;
int iocbs; int iocbs;
struct qla_qpair *qpair; struct qla_qpair *qpair;
u32 gen1; /* scratch */
u32 gen2; /* scratch */
union { union {
struct srb_iocb iocb_cmd; struct srb_iocb iocb_cmd;
struct bsg_job *bsg_job; struct bsg_job *bsg_job;
...@@ -2101,6 +2141,18 @@ typedef struct { ...@@ -2101,6 +2141,18 @@ typedef struct {
#define FC4_TYPE_OTHER 0x0 #define FC4_TYPE_OTHER 0x0
#define FC4_TYPE_UNKNOWN 0xff #define FC4_TYPE_UNKNOWN 0xff
/* mailbox command 4G & above */
struct mbx_24xx_entry {
uint8_t entry_type;
uint8_t entry_count;
uint8_t sys_define1;
uint8_t entry_status;
uint32_t handle;
uint16_t mb[28];
};
#define IOCB_SIZE 64
/* /*
* Fibre channel port type. * Fibre channel port type.
*/ */
...@@ -2113,6 +2165,12 @@ typedef enum { ...@@ -2113,6 +2165,12 @@ typedef enum {
FCT_TARGET FCT_TARGET
} fc_port_type_t; } fc_port_type_t;
enum qla_sess_deletion {
QLA_SESS_DELETION_NONE = 0,
QLA_SESS_DELETION_IN_PROGRESS,
QLA_SESS_DELETED,
};
enum qlt_plogi_link_t { enum qlt_plogi_link_t {
QLT_PLOGI_LINK_SAME_WWN, QLT_PLOGI_LINK_SAME_WWN,
QLT_PLOGI_LINK_CONFLICT, QLT_PLOGI_LINK_CONFLICT,
...@@ -2124,6 +2182,48 @@ struct qlt_plogi_ack_t { ...@@ -2124,6 +2182,48 @@ struct qlt_plogi_ack_t {
struct imm_ntfy_from_isp iocb; struct imm_ntfy_from_isp iocb;
port_id_t id; port_id_t id;
int ref_count; int ref_count;
void *fcport;
};
struct ct_sns_desc {
struct ct_sns_pkt *ct_sns;
dma_addr_t ct_sns_dma;
};
enum discovery_state {
DSC_DELETED,
DSC_GID_PN,
DSC_GNL,
DSC_LOGIN_PEND,
DSC_LOGIN_FAILED,
DSC_GPDB,
DSC_GPSC,
DSC_UPD_FCPORT,
DSC_LOGIN_COMPLETE,
DSC_DELETE_PEND,
};
enum login_state { /* FW control Target side */
DSC_LS_LLIOCB_SENT = 2,
DSC_LS_PLOGI_PEND,
DSC_LS_PLOGI_COMP,
DSC_LS_PRLI_PEND,
DSC_LS_PRLI_COMP,
DSC_LS_PORT_UNAVAIL,
DSC_LS_PRLO_PEND = 9,
DSC_LS_LOGO_PEND,
};
enum fcport_mgt_event {
FCME_RELOGIN = 1,
FCME_RSCN,
FCME_GIDPN_DONE,
FCME_PLOGI_DONE, /* Initiator side sent LLIOCB */
FCME_GNL_DONE,
FCME_GPSC_DONE,
FCME_GPDB_DONE,
FCME_GPNID_DONE,
FCME_DELETE_DONE,
}; };
/* /*
...@@ -2143,9 +2243,13 @@ typedef struct fc_port { ...@@ -2143,9 +2243,13 @@ typedef struct fc_port {
unsigned int deleted:2; unsigned int deleted:2;
unsigned int local:1; unsigned int local:1;
unsigned int logout_on_delete:1; unsigned int logout_on_delete:1;
unsigned int logo_ack_needed:1;
unsigned int keep_nport_handle:1; unsigned int keep_nport_handle:1;
unsigned int send_els_logo:1; unsigned int send_els_logo:1;
unsigned int login_pause:1;
unsigned int login_succ:1;
struct fc_port *conflict;
unsigned char logout_completed; unsigned char logout_completed;
int generation; int generation;
...@@ -2186,8 +2290,30 @@ typedef struct fc_port { ...@@ -2186,8 +2290,30 @@ typedef struct fc_port {
unsigned long retry_delay_timestamp; unsigned long retry_delay_timestamp;
struct qla_tgt_sess *tgt_session; struct qla_tgt_sess *tgt_session;
struct ct_sns_desc ct_desc;
enum discovery_state disc_state;
enum login_state fw_login_state;
u32 login_gen, last_login_gen;
u32 rscn_gen, last_rscn_gen;
u32 chip_reset;
struct list_head gnl_entry;
struct work_struct del_work;
u8 iocb[IOCB_SIZE];
} fc_port_t; } fc_port_t;
#define QLA_FCPORT_SCAN 1
#define QLA_FCPORT_FOUND 2
struct event_arg {
enum fcport_mgt_event event;
fc_port_t *fcport;
srb_t *sp;
port_id_t id;
u16 data[2], rc;
u8 port_name[WWN_SIZE];
u32 iop[2];
};
#include "qla_mr.h" #include "qla_mr.h"
/* /*
...@@ -2265,6 +2391,10 @@ static const char * const port_state_str[] = { ...@@ -2265,6 +2391,10 @@ static const char * const port_state_str[] = {
#define GFT_ID_REQ_SIZE (16 + 4) #define GFT_ID_REQ_SIZE (16 + 4)
#define GFT_ID_RSP_SIZE (16 + 32) #define GFT_ID_RSP_SIZE (16 + 32)
#define GID_PN_CMD 0x121
#define GID_PN_REQ_SIZE (16 + 8)
#define GID_PN_RSP_SIZE (16 + 4)
#define RFT_ID_CMD 0x217 #define RFT_ID_CMD 0x217
#define RFT_ID_REQ_SIZE (16 + 4 + 32) #define RFT_ID_REQ_SIZE (16 + 4 + 32)
#define RFT_ID_RSP_SIZE 16 #define RFT_ID_RSP_SIZE 16
...@@ -2590,6 +2720,10 @@ struct ct_sns_req { ...@@ -2590,6 +2720,10 @@ struct ct_sns_req {
uint8_t reserved; uint8_t reserved;
uint8_t port_name[3]; uint8_t port_name[3];
} gff_id; } gff_id;
struct {
uint8_t port_name[8];
} gid_pn;
} req; } req;
}; };
...@@ -2669,6 +2803,10 @@ struct ct_sns_rsp { ...@@ -2669,6 +2803,10 @@ struct ct_sns_rsp {
struct { struct {
uint8_t fc4_features[128]; uint8_t fc4_features[128];
} gff_id; } gff_id;
struct {
uint8_t reserved;
uint8_t port_id[3];
} gid_pn;
} rsp; } rsp;
}; };
...@@ -2810,11 +2948,11 @@ struct isp_operations { ...@@ -2810,11 +2948,11 @@ struct isp_operations {
uint16_t (*calc_req_entries) (uint16_t); uint16_t (*calc_req_entries) (uint16_t);
void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t); void (*build_iocbs) (srb_t *, cmd_entry_t *, uint16_t);
void * (*prep_ms_iocb) (struct scsi_qla_host *, uint32_t, uint32_t); void *(*prep_ms_iocb) (struct scsi_qla_host *, struct ct_arg *);
void * (*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t, void *(*prep_ms_fdmi_iocb) (struct scsi_qla_host *, uint32_t,
uint32_t); uint32_t);
uint8_t * (*read_nvram) (struct scsi_qla_host *, uint8_t *, uint8_t *(*read_nvram) (struct scsi_qla_host *, uint8_t *,
uint32_t, uint32_t); uint32_t, uint32_t);
int (*write_nvram) (struct scsi_qla_host *, uint8_t *, uint32_t, int (*write_nvram) (struct scsi_qla_host *, uint8_t *, uint32_t,
uint32_t); uint32_t);
...@@ -2876,13 +3014,21 @@ enum qla_work_type { ...@@ -2876,13 +3014,21 @@ enum qla_work_type {
QLA_EVT_AEN, QLA_EVT_AEN,
QLA_EVT_IDC_ACK, QLA_EVT_IDC_ACK,
QLA_EVT_ASYNC_LOGIN, QLA_EVT_ASYNC_LOGIN,
QLA_EVT_ASYNC_LOGIN_DONE,
QLA_EVT_ASYNC_LOGOUT, QLA_EVT_ASYNC_LOGOUT,
QLA_EVT_ASYNC_LOGOUT_DONE, QLA_EVT_ASYNC_LOGOUT_DONE,
QLA_EVT_ASYNC_ADISC, QLA_EVT_ASYNC_ADISC,
QLA_EVT_ASYNC_ADISC_DONE, QLA_EVT_ASYNC_ADISC_DONE,
QLA_EVT_UEVENT, QLA_EVT_UEVENT,
QLA_EVT_AENFX, QLA_EVT_AENFX,
QLA_EVT_GIDPN,
QLA_EVT_GPNID,
QLA_EVT_GPNID_DONE,
QLA_EVT_NEW_SESS,
QLA_EVT_GPDB,
QLA_EVT_GPSC,
QLA_EVT_UPD_FCPORT,
QLA_EVT_GNL,
QLA_EVT_NACK,
}; };
...@@ -2918,6 +3064,23 @@ struct qla_work_evt { ...@@ -2918,6 +3064,23 @@ struct qla_work_evt {
struct { struct {
srb_t *sp; srb_t *sp;
} iosb; } iosb;
struct {
port_id_t id;
} gpnid;
struct {
port_id_t id;
u8 port_name[8];
void *pla;
} new_sess;
struct { /*Get PDB, Get Speed, update fcport, gnl, gidpn */
fc_port_t *fcport;
u8 opt;
} fcport;
struct {
fc_port_t *fcport;
u8 iocb[IOCB_SIZE];
int type;
} nack;
} u; } u;
}; };
...@@ -3899,6 +4062,10 @@ typedef struct scsi_qla_host { ...@@ -3899,6 +4062,10 @@ typedef struct scsi_qla_host {
struct qla8044_reset_template reset_tmplt; struct qla8044_reset_template reset_tmplt;
struct qla_tgt_counters tgt_counters; struct qla_tgt_counters tgt_counters;
uint16_t bbcr; uint16_t bbcr;
struct name_list_extended gnl;
/* Count of active session/fcport */
int fcport_count;
wait_queue_head_t fcport_waitQ;
} scsi_qla_host_t; } scsi_qla_host_t;
struct qla27xx_image_status { struct qla27xx_image_status {
......
...@@ -72,6 +72,37 @@ struct port_database_24xx { ...@@ -72,6 +72,37 @@ struct port_database_24xx {
uint8_t reserved_3[24]; uint8_t reserved_3[24];
}; };
/*
* MB 75h returns a list of DB entries similar to port_database_24xx(64B).
* However, in this case it returns 1st 40 bytes.
*/
struct get_name_list_extended {
__le16 flags;
u8 current_login_state;
u8 last_login_state;
u8 hard_address[3];
u8 reserved_1;
u8 port_id[3];
u8 sequence_id;
__le16 port_timer;
__le16 nport_handle; /* N_PORT handle. */
__le16 receive_data_size;
__le16 reserved_2;
/* PRLI SVC Param are Big endian */
u8 prli_svc_param_word_0[2]; /* Bits 15-0 of word 0 */
u8 prli_svc_param_word_3[2]; /* Bits 15-0 of word 3 */
u8 port_name[WWN_SIZE];
u8 node_name[WWN_SIZE];
};
/* MB 75h: This is the short version of the database */
struct get_name_list {
u8 port_node_name[WWN_SIZE]; /* B7 most sig, B0 least sig */
__le16 nport_handle;
u8 reserved;
};
struct vp_database_24xx { struct vp_database_24xx {
uint16_t vp_status; uint16_t vp_status;
uint8_t options; uint8_t options;
......
...@@ -73,6 +73,10 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *, ...@@ -73,6 +73,10 @@ extern void qla2x00_async_logout_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *); uint16_t *);
extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *, extern void qla2x00_async_adisc_done(struct scsi_qla_host *, fc_port_t *,
uint16_t *); uint16_t *);
struct qla_work_evt *qla2x00_alloc_work(struct scsi_qla_host *,
enum qla_work_type);
extern int qla24xx_async_gnl(struct scsi_qla_host *, fc_port_t *);
int qla2x00_post_work(struct scsi_qla_host *vha, struct qla_work_evt *e);
extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *); extern void *qla2x00_alloc_iocbs(struct scsi_qla_host *, srb_t *);
extern void *qla2x00_alloc_iocbs_ready(struct scsi_qla_host *, srb_t *); extern void *qla2x00_alloc_iocbs_ready(struct scsi_qla_host *, srb_t *);
extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *); extern int qla24xx_update_fcport_fcp_prio(scsi_qla_host_t *, fc_port_t *);
...@@ -94,6 +98,13 @@ extern uint8_t qla27xx_find_valid_image(struct scsi_qla_host *); ...@@ -94,6 +98,13 @@ extern uint8_t qla27xx_find_valid_image(struct scsi_qla_host *);
extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *, extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *,
int, int); int, int);
extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *); extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *);
void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *);
int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8);
int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
struct imm_ntfy_from_isp *, int);
int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, u8 *,
void *);
int qla24xx_fcport_handle_login(struct scsi_qla_host *, fc_port_t *);
/* /*
* Global Data in qla_os.c source file. * Global Data in qla_os.c source file.
...@@ -135,8 +146,6 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum ...@@ -135,8 +146,6 @@ extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *); extern int qla2x00_post_idc_ack_work(struct scsi_qla_host *, uint16_t *);
extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *, extern int qla2x00_post_async_login_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *); uint16_t *);
extern int qla2x00_post_async_login_done_work(struct scsi_qla_host *,
fc_port_t *, uint16_t *);
extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *, extern int qla2x00_post_async_logout_work(struct scsi_qla_host *, fc_port_t *,
uint16_t *); uint16_t *);
extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *, extern int qla2x00_post_async_logout_done_work(struct scsi_qla_host *,
...@@ -179,6 +188,10 @@ extern void qla2x00_disable_board_on_pci_error(struct work_struct *); ...@@ -179,6 +188,10 @@ extern void qla2x00_disable_board_on_pci_error(struct work_struct *);
extern void qla2x00_sp_compl(void *, void *, int); extern void qla2x00_sp_compl(void *, void *, int);
extern void qla2xxx_qpair_sp_free_dma(void *, void *); extern void qla2xxx_qpair_sp_free_dma(void *, void *);
extern void qla2xxx_qpair_sp_compl(void *, void *, int); extern void qla2xxx_qpair_sp_compl(void *, void *, int);
extern int qla24xx_post_upd_fcport_work(struct scsi_qla_host *, fc_port_t *);
void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
int qla24xx_post_gnl_work(struct scsi_qla_host *, fc_port_t *);
/* /*
* Global Functions in qla_mid.c source file. * Global Functions in qla_mid.c source file.
...@@ -301,9 +314,6 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *, uint8_t *, uint8_t *, uint16_t *); ...@@ -301,9 +314,6 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *, uint8_t *, uint8_t *, uint16_t *);
extern int extern int
qla2x00_init_firmware(scsi_qla_host_t *, uint16_t); qla2x00_init_firmware(scsi_qla_host_t *, uint16_t);
extern int
qla2x00_get_node_name_list(scsi_qla_host_t *, void **, int *);
extern int extern int
qla2x00_get_port_database(scsi_qla_host_t *, fc_port_t *, uint8_t); qla2x00_get_port_database(scsi_qla_host_t *, fc_port_t *, uint8_t);
...@@ -483,6 +493,9 @@ qla2x00_process_completed_request(struct scsi_qla_host *, struct req_que *, ...@@ -483,6 +493,9 @@ qla2x00_process_completed_request(struct scsi_qla_host *, struct req_que *,
uint32_t); uint32_t);
extern irqreturn_t extern irqreturn_t
qla2xxx_msix_rsp_q(int irq, void *dev_id); qla2xxx_msix_rsp_q(int irq, void *dev_id);
fc_port_t *qla2x00_find_fcport_by_loopid(scsi_qla_host_t *, uint16_t);
fc_port_t *qla2x00_find_fcport_by_wwpn(scsi_qla_host_t *, u8 *, u8);
fc_port_t *qla2x00_find_fcport_by_nportid(scsi_qla_host_t *, port_id_t *, u8);
/* /*
* Global Function Prototypes in qla_sup.c source file. * Global Function Prototypes in qla_sup.c source file.
...@@ -574,8 +587,8 @@ extern void qla2xxx_dump_post_process(scsi_qla_host_t *, int); ...@@ -574,8 +587,8 @@ extern void qla2xxx_dump_post_process(scsi_qla_host_t *, int);
/* /*
* Global Function Prototypes in qla_gs.c source file. * Global Function Prototypes in qla_gs.c source file.
*/ */
extern void *qla2x00_prep_ms_iocb(scsi_qla_host_t *, uint32_t, uint32_t); extern void *qla2x00_prep_ms_iocb(scsi_qla_host_t *, struct ct_arg *);
extern void *qla24xx_prep_ms_iocb(scsi_qla_host_t *, uint32_t, uint32_t); extern void *qla24xx_prep_ms_iocb(scsi_qla_host_t *, struct ct_arg *);
extern int qla2x00_ga_nxt(scsi_qla_host_t *, fc_port_t *); extern int qla2x00_ga_nxt(scsi_qla_host_t *, fc_port_t *);
extern int qla2x00_gid_pt(scsi_qla_host_t *, sw_info_t *); extern int qla2x00_gid_pt(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *); extern int qla2x00_gpn_id(scsi_qla_host_t *, sw_info_t *);
...@@ -591,6 +604,23 @@ extern int qla2x00_fdmi_register(scsi_qla_host_t *); ...@@ -591,6 +604,23 @@ extern int qla2x00_fdmi_register(scsi_qla_host_t *);
extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *); extern int qla2x00_gfpn_id(scsi_qla_host_t *, sw_info_t *);
extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *); extern int qla2x00_gpsc(scsi_qla_host_t *, sw_info_t *);
extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *, size_t); extern void qla2x00_get_sym_node_name(scsi_qla_host_t *, uint8_t *, size_t);
extern int qla2x00_chk_ms_status(scsi_qla_host_t *, ms_iocb_entry_t *,
struct ct_sns_rsp *, const char *);
extern void qla2x00_async_iocb_timeout(void *data);
extern int qla24xx_async_gidpn(scsi_qla_host_t *, fc_port_t *);
int qla24xx_post_gidpn_work(struct scsi_qla_host *, fc_port_t *);
void qla24xx_handle_gidpn_event(scsi_qla_host_t *, struct event_arg *);
extern void qla2x00_free_fcport(fc_port_t *);
extern int qla24xx_post_gpnid_work(struct scsi_qla_host *, port_id_t *);
extern int qla24xx_async_gpnid(scsi_qla_host_t *, port_id_t *);
void qla24xx_async_gpnid_done(scsi_qla_host_t *, srb_t*);
void qla24xx_handle_gpnid_event(scsi_qla_host_t *, struct event_arg *);
int qla24xx_post_gpsc_work(struct scsi_qla_host *, fc_port_t *);
int qla24xx_async_gpsc(scsi_qla_host_t *, fc_port_t *);
int qla2x00_mgmt_svr_login(scsi_qla_host_t *);
/* /*
* Global Function Prototypes in qla_attr.c source file. * Global Function Prototypes in qla_attr.c source file.
...@@ -803,4 +833,16 @@ extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *); ...@@ -803,4 +833,16 @@ extern int qla_get_exchoffld_status(scsi_qla_host_t *, uint16_t *, uint16_t *);
extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t); extern int qla_set_exchoffld_mem_cfg(scsi_qla_host_t *, dma_addr_t);
extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *); extern void qlt_handle_abts_recv(struct scsi_qla_host *, response_t *);
int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
struct imm_ntfy_from_isp *, int);
void qla24xx_do_nack_work(struct scsi_qla_host *, struct qla_work_evt *);
void qlt_plogi_ack_link(struct scsi_qla_host *, struct qlt_plogi_ack_t *,
struct fc_port *, enum qlt_plogi_link_t);
void qlt_plogi_ack_unref(struct scsi_qla_host *, struct qlt_plogi_ack_t *);
extern void qlt_schedule_sess_for_deletion(struct fc_port *, bool);
extern void qlt_schedule_sess_for_deletion_lock(struct fc_port *);
extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *,
uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **);
void qla24xx_delete_sess_fn(struct work_struct *);
#endif /* _QLA_GBL_H */ #endif /* _QLA_GBL_H */
This diff is collapsed.
This diff is collapsed.
...@@ -166,8 +166,8 @@ qla2x00_set_fcport_state(fc_port_t *fcport, int state) ...@@ -166,8 +166,8 @@ qla2x00_set_fcport_state(fc_port_t *fcport, int state)
/* Don't print state transitions during initial allocation of fcport */ /* Don't print state transitions during initial allocation of fcport */
if (old_state && old_state != state) { if (old_state && old_state != state) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x207d, ql_dbg(ql_dbg_disc, fcport->vha, 0x207d,
"FCPort state transitioned from %s to %s - " "FCPort %8phC state transitioned from %s to %s - "
"portid=%02x%02x%02x.\n", "portid=%02x%02x%02x.\n", fcport->port_name,
port_state_str[old_state], port_state_str[state], port_state_str[old_state], port_state_str[state],
fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.domain, fcport->d_id.b.area,
fcport->d_id.b.al_pa); fcport->d_id.b.al_pa);
...@@ -263,6 +263,7 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag) ...@@ -263,6 +263,7 @@ qla2x00_get_sp(scsi_qla_host_t *vha, fc_port_t *fcport, gfp_t flag)
memset(sp, 0, sizeof(*sp)); memset(sp, 0, sizeof(*sp));
sp->fcport = fcport; sp->fcport = fcport;
sp->iocbs = 1; sp->iocbs = 1;
sp->vha = vha;
done: done:
if (!sp) if (!sp)
QLA_VHA_MARK_NOT_BUSY(vha); QLA_VHA_MARK_NOT_BUSY(vha);
...@@ -285,7 +286,7 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo) ...@@ -285,7 +286,7 @@ qla2x00_init_timer(srb_t *sp, unsigned long tmo)
sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout; sp->u.iocb_cmd.timer.function = qla2x00_sp_timeout;
add_timer(&sp->u.iocb_cmd.timer); add_timer(&sp->u.iocb_cmd.timer);
sp->free = qla2x00_sp_free; sp->free = qla2x00_sp_free;
if ((IS_QLAFX00(sp->fcport->vha->hw)) && if ((IS_QLAFX00(((scsi_qla_host_t *)sp->vha)->hw)) &&
(sp->type == SRB_FXIOCB_DCMD)) (sp->type == SRB_FXIOCB_DCMD))
init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp); init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
if (sp->type == SRB_ELS_DCMD) if (sp->type == SRB_ELS_DCMD)
......
...@@ -2247,7 +2247,7 @@ qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio) ...@@ -2247,7 +2247,7 @@ qla24xx_logout_iocb(srb_t *sp, struct logio_entry_24xx *logio)
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE; logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
logio->control_flags = logio->control_flags =
cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO); cpu_to_le16(LCF_COMMAND_LOGO|LCF_IMPL_LOGO);
if (!sp->fcport->tgt_session || if (!sp->fcport->se_sess ||
!sp->fcport->keep_nport_handle) !sp->fcport->keep_nport_handle)
logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT); logio->control_flags |= cpu_to_le16(LCF_FREE_NPORT);
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id); logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
...@@ -3079,19 +3079,69 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb) ...@@ -3079,19 +3079,69 @@ qla24xx_abort_iocb(srb_t *sp, struct abort_entry_24xx *abt_iocb)
wmb(); wmb();
} }
static void
qla2x00_mb_iocb(srb_t *sp, struct mbx_24xx_entry *mbx)
{
int i, sz;
mbx->entry_type = MBX_IOCB_TYPE;
mbx->handle = sp->handle;
sz = min(ARRAY_SIZE(mbx->mb), ARRAY_SIZE(sp->u.iocb_cmd.u.mbx.out_mb));
for (i = 0; i < sz; i++)
mbx->mb[i] = cpu_to_le16(sp->u.iocb_cmd.u.mbx.out_mb[i]);
}
static void
qla2x00_ctpthru_cmd_iocb(srb_t *sp, struct ct_entry_24xx *ct_pkt)
{
sp->u.iocb_cmd.u.ctarg.iocb = ct_pkt;
qla24xx_prep_ms_iocb(sp->vha, &sp->u.iocb_cmd.u.ctarg);
ct_pkt->handle = sp->handle;
}
static void qla2x00_send_notify_ack_iocb(srb_t *sp,
struct nack_to_isp *nack)
{
struct imm_ntfy_from_isp *ntfy = sp->u.iocb_cmd.u.nack.ntfy;
nack->entry_type = NOTIFY_ACK_TYPE;
nack->entry_count = 1;
nack->ox_id = ntfy->ox_id;
nack->u.isp24.handle = sp->handle;
nack->u.isp24.nport_handle = ntfy->u.isp24.nport_handle;
if (le16_to_cpu(ntfy->u.isp24.status) == IMM_NTFY_ELS) {
nack->u.isp24.flags = ntfy->u.isp24.flags &
cpu_to_le32(NOTIFY24XX_FLAGS_PUREX_IOCB);
}
nack->u.isp24.srr_rx_id = ntfy->u.isp24.srr_rx_id;
nack->u.isp24.status = ntfy->u.isp24.status;
nack->u.isp24.status_subcode = ntfy->u.isp24.status_subcode;
nack->u.isp24.fw_handle = ntfy->u.isp24.fw_handle;
nack->u.isp24.exchange_address = ntfy->u.isp24.exchange_address;
nack->u.isp24.srr_rel_offs = ntfy->u.isp24.srr_rel_offs;
nack->u.isp24.srr_ui = ntfy->u.isp24.srr_ui;
nack->u.isp24.srr_flags = 0;
nack->u.isp24.srr_reject_code = 0;
nack->u.isp24.srr_reject_code_expl = 0;
nack->u.isp24.vp_index = ntfy->u.isp24.vp_index;
}
int int
qla2x00_start_sp(srb_t *sp) qla2x00_start_sp(srb_t *sp)
{ {
int rval; int rval;
struct qla_hw_data *ha = sp->fcport->vha->hw; scsi_qla_host_t *vha = (scsi_qla_host_t *)sp->vha;
struct qla_hw_data *ha = vha->hw;
void *pkt; void *pkt;
unsigned long flags; unsigned long flags;
rval = QLA_FUNCTION_FAILED; rval = QLA_FUNCTION_FAILED;
spin_lock_irqsave(&ha->hardware_lock, flags); spin_lock_irqsave(&ha->hardware_lock, flags);
pkt = qla2x00_alloc_iocbs(sp->fcport->vha, sp); pkt = qla2x00_alloc_iocbs(vha, sp);
if (!pkt) { if (!pkt) {
ql_log(ql_log_warn, sp->fcport->vha, 0x700c, ql_log(ql_log_warn, vha, 0x700c,
"qla2x00_alloc_iocbs failed.\n"); "qla2x00_alloc_iocbs failed.\n");
goto done; goto done;
} }
...@@ -3139,12 +3189,23 @@ qla2x00_start_sp(srb_t *sp) ...@@ -3139,12 +3189,23 @@ qla2x00_start_sp(srb_t *sp)
case SRB_ELS_DCMD: case SRB_ELS_DCMD:
qla24xx_els_logo_iocb(sp, pkt); qla24xx_els_logo_iocb(sp, pkt);
break; break;
case SRB_CT_PTHRU_CMD:
qla2x00_ctpthru_cmd_iocb(sp, pkt);
break;
case SRB_MB_IOCB:
qla2x00_mb_iocb(sp, pkt);
break;
case SRB_NACK_PLOGI:
case SRB_NACK_PRLI:
case SRB_NACK_LOGO:
qla2x00_send_notify_ack_iocb(sp, pkt);
break;
default: default:
break; break;
} }
wmb(); wmb();
qla2x00_start_iocbs(sp->fcport->vha, ha->req_q_map[0]); qla2x00_start_iocbs(vha, ha->req_q_map[0]);
done: done:
spin_unlock_irqrestore(&ha->hardware_lock, flags); spin_unlock_irqrestore(&ha->hardware_lock, flags);
return rval; return rval;
......
...@@ -561,14 +561,50 @@ qla2x00_is_a_vp_did(scsi_qla_host_t *vha, uint32_t rscn_entry) ...@@ -561,14 +561,50 @@ qla2x00_is_a_vp_did(scsi_qla_host_t *vha, uint32_t rscn_entry)
return ret; return ret;
} }
static inline fc_port_t * fc_port_t *
qla2x00_find_fcport_by_loopid(scsi_qla_host_t *vha, uint16_t loop_id) qla2x00_find_fcport_by_loopid(scsi_qla_host_t *vha, uint16_t loop_id)
{ {
fc_port_t *fcport; fc_port_t *f, *tf;
list_for_each_entry(fcport, &vha->vp_fcports, list) f = tf = NULL;
if (fcport->loop_id == loop_id) list_for_each_entry_safe(f, tf, &vha->vp_fcports, list)
return fcport; if (f->loop_id == loop_id)
return f;
return NULL;
}
fc_port_t *
qla2x00_find_fcport_by_wwpn(scsi_qla_host_t *vha, u8 *wwpn, u8 incl_deleted)
{
fc_port_t *f, *tf;
f = tf = NULL;
list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
if (memcmp(f->port_name, wwpn, WWN_SIZE) == 0) {
if (incl_deleted)
return f;
else if (f->deleted == 0)
return f;
}
}
return NULL;
}
fc_port_t *
qla2x00_find_fcport_by_nportid(scsi_qla_host_t *vha, port_id_t *id,
u8 incl_deleted)
{
fc_port_t *f, *tf;
f = tf = NULL;
list_for_each_entry_safe(f, tf, &vha->vp_fcports, list) {
if (f->d_id.b24 == id->b24) {
if (incl_deleted)
return f;
else if (f->deleted == 0)
return f;
}
}
return NULL; return NULL;
} }
...@@ -934,7 +970,11 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ...@@ -934,7 +970,11 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
ql_dbg(ql_dbg_async, vha, 0x508a, ql_dbg(ql_dbg_async, vha, 0x508a,
"Marking port lost loopid=%04x portid=%06x.\n", "Marking port lost loopid=%04x portid=%06x.\n",
fcport->loop_id, fcport->d_id.b24); fcport->loop_id, fcport->d_id.b24);
if (qla_ini_mode_enabled(vha)) {
qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
fcport->logout_on_delete = 0;
qlt_schedule_sess_for_deletion_lock(fcport);
}
break; break;
global_port_update: global_port_update:
...@@ -1024,27 +1064,17 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb) ...@@ -1024,27 +1064,17 @@ qla2x00_async_event(scsi_qla_host_t *vha, struct rsp_que *rsp, uint16_t *mb)
if (qla2x00_is_a_vp_did(vha, rscn_entry)) if (qla2x00_is_a_vp_did(vha, rscn_entry))
break; break;
/*
* Search for the rport related to this RSCN entry and mark it
* as lost.
*/
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (atomic_read(&fcport->state) != FCS_ONLINE)
continue;
if (fcport->d_id.b24 == rscn_entry) {
qla2x00_mark_device_lost(vha, fcport, 0, 0);
break;
}
}
atomic_set(&vha->loop_down_timer, 0); atomic_set(&vha->loop_down_timer, 0);
vha->flags.management_server_logged_in = 0; vha->flags.management_server_logged_in = 0;
{
struct event_arg ea;
set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); memset(&ea, 0, sizeof(ea));
set_bit(RSCN_UPDATE, &vha->dpc_flags); ea.event = FCME_RSCN;
qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry); ea.id.b24 = rscn_entry;
qla2x00_fcport_event_handler(vha, &ea);
}
break; break;
/* case MBA_RIO_RESPONSE: */ /* case MBA_RIO_RESPONSE: */
case MBA_ZIO_RESPONSE: case MBA_ZIO_RESPONSE:
ql_dbg(ql_dbg_async, vha, 0x5015, ql_dbg(ql_dbg_async, vha, 0x5015,
...@@ -1235,7 +1265,8 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func, ...@@ -1235,7 +1265,8 @@ qla2x00_get_sp_from_handle(scsi_qla_host_t *vha, const char *func,
index = LSW(pkt->handle); index = LSW(pkt->handle);
if (index >= req->num_outstanding_cmds) { if (index >= req->num_outstanding_cmds) {
ql_log(ql_log_warn, vha, 0x5031, ql_log(ql_log_warn, vha, 0x5031,
"Invalid command index (%x).\n", index); "Invalid command index (%x) type %8ph.\n",
index, iocb);
if (IS_P3P_TYPE(ha)) if (IS_P3P_TYPE(ha))
set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags);
else else
...@@ -1346,6 +1377,49 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1346,6 +1377,49 @@ qla2x00_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
sp->done(vha, sp, 0); sp->done(vha, sp, 0);
} }
static void
qla24xx_mbx_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
struct mbx_24xx_entry *pkt)
{
const char func[] = "MBX-IOCB2";
srb_t *sp;
struct srb_iocb *si;
u16 sz, i;
int res;
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (!sp)
return;
si = &sp->u.iocb_cmd;
sz = min(ARRAY_SIZE(pkt->mb), ARRAY_SIZE(sp->u.iocb_cmd.u.mbx.in_mb));
for (i = 0; i < sz; i++)
si->u.mbx.in_mb[i] = le16_to_cpu(pkt->mb[i]);
res = (si->u.mbx.in_mb[0] & MBS_MASK);
sp->done(vha, sp, res);
}
static void
qla24xxx_nack_iocb_entry(scsi_qla_host_t *vha, struct req_que *req,
struct nack_to_isp *pkt)
{
const char func[] = "nack";
srb_t *sp;
int res = 0;
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (!sp)
return;
if (pkt->u.isp2x.status != cpu_to_le16(NOTIFY_ACK_SUCCESS))
res = QLA_FUNCTION_FAILED;
sp->done(vha, sp, res);
}
static void static void
qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
sts_entry_t *pkt, int iocb_type) sts_entry_t *pkt, int iocb_type)
...@@ -1356,12 +1430,14 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1356,12 +1430,14 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
struct bsg_job *bsg_job; struct bsg_job *bsg_job;
struct fc_bsg_reply *bsg_reply; struct fc_bsg_reply *bsg_reply;
uint16_t comp_status; uint16_t comp_status;
int res; int res = 0;
sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); sp = qla2x00_get_sp_from_handle(vha, func, req, pkt);
if (!sp) if (!sp)
return; return;
switch (sp->type) {
case SRB_CT_CMD:
bsg_job = sp->u.bsg_job; bsg_job = sp->u.bsg_job;
bsg_reply = bsg_job->reply; bsg_reply = bsg_job->reply;
...@@ -1369,7 +1445,8 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1369,7 +1445,8 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
comp_status = le16_to_cpu(pkt->comp_status); comp_status = le16_to_cpu(pkt->comp_status);
/* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT /*
* return FC_CTELS_STATUS_OK and leave the decoding of the ELS/CT
* fc payload to the caller * fc payload to the caller
*/ */
bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK; bsg_reply->reply_data.ctels_reply.status = FC_CTELS_STATUS_OK;
...@@ -1382,14 +1459,13 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1382,14 +1459,13 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len); le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
ql_log(ql_log_warn, vha, 0x5048, ql_log(ql_log_warn, vha, 0x5048,
"CT pass-through-%s error " "CT pass-through-%s error comp_status=0x%x total_byte=0x%x.\n",
"comp_status-status=0x%x total_byte = 0x%x.\n",
type, comp_status, type, comp_status,
bsg_reply->reply_payload_rcv_len); bsg_reply->reply_payload_rcv_len);
} else { } else {
ql_log(ql_log_warn, vha, 0x5049, ql_log(ql_log_warn, vha, 0x5049,
"CT pass-through-%s error " "CT pass-through-%s error comp_status=0x%x.\n",
"comp_status-status=0x%x.\n", type, comp_status); type, comp_status);
res = DID_ERROR << 16; res = DID_ERROR << 16;
bsg_reply->reply_payload_rcv_len = 0; bsg_reply->reply_payload_rcv_len = 0;
} }
...@@ -1401,6 +1477,17 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1401,6 +1477,17 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
bsg_job->reply_payload.payload_len; bsg_job->reply_payload.payload_len;
bsg_job->reply_len = 0; bsg_job->reply_len = 0;
} }
break;
case SRB_CT_PTHRU_CMD:
/*
* borrowing sts_entry_24xx.comp_status.
* same location as ct_entry_24xx.comp_status
*/
res = qla2x00_chk_ms_status(vha, (ms_iocb_entry_t *)pkt,
(struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp,
sp->name);
break;
}
sp->done(vha, sp, res); sp->done(vha, sp, res);
} }
...@@ -1440,6 +1527,15 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1440,6 +1527,15 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
"Completing %s: (%p) type=%d.\n", type, sp, sp->type); "Completing %s: (%p) type=%d.\n", type, sp, sp->type);
sp->done(vha, sp, 0); sp->done(vha, sp, 0);
return; return;
case SRB_CT_PTHRU_CMD:
/* borrowing sts_entry_24xx.comp_status.
same location as ct_entry_24xx.comp_status
*/
res = qla2x00_chk_ms_status(vha, (ms_iocb_entry_t *)pkt,
(struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp,
sp->name);
sp->done(vha, sp, res);
return;
default: default:
ql_dbg(ql_dbg_user, vha, 0x503e, ql_dbg(ql_dbg_user, vha, 0x503e,
"Unrecognized SRB: (%p) type=%d.\n", sp, sp->type); "Unrecognized SRB: (%p) type=%d.\n", sp, sp->type);
...@@ -1566,6 +1662,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req, ...@@ -1566,6 +1662,8 @@ qla24xx_logio_entry(scsi_qla_host_t *vha, struct req_que *req,
iop[0] = le32_to_cpu(logio->io_parameter[0]); iop[0] = le32_to_cpu(logio->io_parameter[0]);
iop[1] = le32_to_cpu(logio->io_parameter[1]); iop[1] = le32_to_cpu(logio->io_parameter[1]);
lio->u.logio.iop[0] = iop[0];
lio->u.logio.iop[1] = iop[1];
switch (iop[0]) { switch (iop[0]) {
case LSC_SCODE_PORTID_USED: case LSC_SCODE_PORTID_USED:
data[0] = MBS_PORT_ID_USED; data[0] = MBS_PORT_ID_USED;
...@@ -2074,6 +2172,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -2074,6 +2172,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
int res = 0; int res = 0;
uint16_t state_flags = 0; uint16_t state_flags = 0;
uint16_t retry_delay = 0; uint16_t retry_delay = 0;
uint8_t no_logout = 0;
sts = (sts_entry_t *) pkt; sts = (sts_entry_t *) pkt;
sts24 = (struct sts_entry_24xx *) pkt; sts24 = (struct sts_entry_24xx *) pkt;
...@@ -2334,6 +2433,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -2334,6 +2433,7 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break; break;
case CS_PORT_LOGGED_OUT: case CS_PORT_LOGGED_OUT:
no_logout = 1;
case CS_PORT_CONFIG_CHG: case CS_PORT_CONFIG_CHG:
case CS_PORT_BUSY: case CS_PORT_BUSY:
case CS_INCOMPLETE: case CS_INCOMPLETE:
...@@ -2356,14 +2456,21 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt) ...@@ -2356,14 +2456,21 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
break; break;
} }
ql_dbg(ql_dbg_io, fcport->vha, 0x3021, if (atomic_read(&fcport->state) == FCS_ONLINE) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x3021,
"Port to be marked lost on fcport=%02x%02x%02x, current " "Port to be marked lost on fcport=%02x%02x%02x, current "
"port state= %s.\n", fcport->d_id.b.domain, "port state= %s comp_status %x.\n", fcport->d_id.b.domain,
fcport->d_id.b.area, fcport->d_id.b.al_pa, fcport->d_id.b.area, fcport->d_id.b.al_pa,
port_state_str[atomic_read(&fcport->state)]); port_state_str[atomic_read(&fcport->state)],
comp_status);
if (no_logout)
fcport->logout_on_delete = 0;
if (atomic_read(&fcport->state) == FCS_ONLINE)
qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1); qla2x00_mark_device_lost(fcport->vha, fcport, 1, 1);
qlt_schedule_sess_for_deletion_lock(fcport);
}
break; break;
case CS_ABORTED: case CS_ABORTED:
...@@ -2627,10 +2734,16 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -2627,10 +2734,16 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
} }
case ABTS_RESP_24XX: case ABTS_RESP_24XX:
case CTIO_TYPE7: case CTIO_TYPE7:
case NOTIFY_ACK_TYPE:
case CTIO_CRC2: case CTIO_CRC2:
qlt_response_pkt_all_vps(vha, (response_t *)pkt); qlt_response_pkt_all_vps(vha, (response_t *)pkt);
break; break;
case NOTIFY_ACK_TYPE:
if (pkt->handle == QLA_TGT_SKIP_HANDLE)
qlt_response_pkt_all_vps(vha, (response_t *)pkt);
else
qla24xxx_nack_iocb_entry(vha, rsp->req,
(struct nack_to_isp *)pkt);
break;
case MARKER_TYPE: case MARKER_TYPE:
/* Do nothing in this case, this check is to prevent it /* Do nothing in this case, this check is to prevent it
* from falling into default case * from falling into default case
...@@ -2640,6 +2753,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -2640,6 +2753,10 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
qla24xx_abort_iocb_entry(vha, rsp->req, qla24xx_abort_iocb_entry(vha, rsp->req,
(struct abort_entry_24xx *)pkt); (struct abort_entry_24xx *)pkt);
break; break;
case MBX_IOCB_TYPE:
qla24xx_mbx_iocb_entry(vha, rsp->req,
(struct mbx_24xx_entry *)pkt);
break;
default: default:
/* Type Not Supported. */ /* Type Not Supported. */
ql_dbg(ql_dbg_async, vha, 0x5042, ql_dbg(ql_dbg_async, vha, 0x5042,
...@@ -2656,8 +2773,9 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha, ...@@ -2656,8 +2773,9 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
if (IS_P3P_TYPE(ha)) { if (IS_P3P_TYPE(ha)) {
struct device_reg_82xx __iomem *reg = &ha->iobase->isp82; struct device_reg_82xx __iomem *reg = &ha->iobase->isp82;
WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index); WRT_REG_DWORD(&reg->rsp_q_out[0], rsp->ring_index);
} else } else {
WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index); WRT_REG_DWORD(rsp->rsp_q_out, rsp->ring_index);
}
} }
static void static void
......
...@@ -1637,94 +1637,6 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size) ...@@ -1637,94 +1637,6 @@ qla2x00_init_firmware(scsi_qla_host_t *vha, uint16_t size)
return rval; return rval;
} }
/*
* qla2x00_get_node_name_list
* Issue get node name list mailbox command, kmalloc()
* and return the resulting list. Caller must kfree() it!
*
* Input:
* ha = adapter state pointer.
* out_data = resulting list
* out_len = length of the resulting list
*
* Returns:
* qla2x00 local function return status code.
*
* Context:
* Kernel context.
*/
int
qla2x00_get_node_name_list(scsi_qla_host_t *vha, void **out_data, int *out_len)
{
struct qla_hw_data *ha = vha->hw;
struct qla_port_24xx_data *list = NULL;
void *pmap;
mbx_cmd_t mc;
dma_addr_t pmap_dma;
ulong dma_size;
int rval, left;
left = 1;
while (left > 0) {
dma_size = left * sizeof(*list);
pmap = dma_alloc_coherent(&ha->pdev->dev, dma_size,
&pmap_dma, GFP_KERNEL);
if (!pmap) {
ql_log(ql_log_warn, vha, 0x113f,
"%s(%ld): DMA Alloc failed of %ld\n",
__func__, vha->host_no, dma_size);
rval = QLA_MEMORY_ALLOC_FAILED;
goto out;
}
mc.mb[0] = MBC_PORT_NODE_NAME_LIST;
mc.mb[1] = BIT_1 | BIT_3;
mc.mb[2] = MSW(pmap_dma);
mc.mb[3] = LSW(pmap_dma);
mc.mb[6] = MSW(MSD(pmap_dma));
mc.mb[7] = LSW(MSD(pmap_dma));
mc.mb[8] = dma_size;
mc.out_mb = MBX_0|MBX_1|MBX_2|MBX_3|MBX_6|MBX_7|MBX_8;
mc.in_mb = MBX_0|MBX_1;
mc.tov = 30;
mc.flags = MBX_DMA_IN;
rval = qla2x00_mailbox_command(vha, &mc);
if (rval != QLA_SUCCESS) {
if ((mc.mb[0] == MBS_COMMAND_ERROR) &&
(mc.mb[1] == 0xA)) {
left += le16_to_cpu(mc.mb[2]) /
sizeof(struct qla_port_24xx_data);
goto restart;
}
goto out_free;
}
left = 0;
list = kmemdup(pmap, dma_size, GFP_KERNEL);
if (!list) {
ql_log(ql_log_warn, vha, 0x1140,
"%s(%ld): failed to allocate node names list "
"structure.\n", __func__, vha->host_no);
rval = QLA_MEMORY_ALLOC_FAILED;
goto out_free;
}
restart:
dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
}
*out_data = list;
*out_len = dma_size;
out:
return rval;
out_free:
dma_free_coherent(&ha->pdev->dev, dma_size, pmap, pmap_dma);
return rval;
}
/* /*
* qla2x00_get_port_database * qla2x00_get_port_database
......
This diff is collapsed.
This diff is collapsed.
...@@ -799,7 +799,6 @@ struct qla_tgt { ...@@ -799,7 +799,6 @@ struct qla_tgt {
/* Protected by hardware_lock */ /* Protected by hardware_lock */
struct list_head del_sess_list; struct list_head del_sess_list;
struct delayed_work sess_del_work;
spinlock_t sess_work_lock; spinlock_t sess_work_lock;
struct list_head sess_works_list; struct list_head sess_works_list;
...@@ -823,13 +822,6 @@ struct qla_tgt_sess_op { ...@@ -823,13 +822,6 @@ struct qla_tgt_sess_op {
bool aborted; bool aborted;
}; };
enum qla_sess_deletion {
QLA_SESS_DELETION_NONE = 0,
QLA_SESS_DELETION_PENDING = 1, /* hopefully we can get rid of
* this one */
QLA_SESS_DELETION_IN_PROGRESS = 2,
};
enum trace_flags { enum trace_flags {
TRC_NEW_CMD = BIT_0, TRC_NEW_CMD = BIT_0,
TRC_DO_WORK = BIT_1, TRC_DO_WORK = BIT_1,
...@@ -987,12 +979,17 @@ extern int ql2x_ini_mode; ...@@ -987,12 +979,17 @@ extern int ql2x_ini_mode;
static inline bool qla_tgt_mode_enabled(struct scsi_qla_host *ha) static inline bool qla_tgt_mode_enabled(struct scsi_qla_host *ha)
{ {
return ha->host->active_mode & MODE_TARGET; return ha->host->active_mode == MODE_TARGET;
} }
static inline bool qla_ini_mode_enabled(struct scsi_qla_host *ha) static inline bool qla_ini_mode_enabled(struct scsi_qla_host *ha)
{ {
return ha->host->active_mode & MODE_INITIATOR; return ha->host->active_mode == MODE_INITIATOR;
}
static inline bool qla_dual_mode_enabled(struct scsi_qla_host *ha)
{
return (ha->host->active_mode == MODE_DUAL);
} }
static inline void qla_reverse_ini_mode(struct scsi_qla_host *ha) static inline void qla_reverse_ini_mode(struct scsi_qla_host *ha)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment