Merge branch 'svn-trunk'

This commit is contained in:
Bart Van Assche
2019-08-24 20:22:00 -07:00
18 changed files with 529 additions and 706 deletions
+2 -4
View File
@@ -382,7 +382,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
ha->optrom_region_size = size;
ha->optrom_state = QLA_SREADING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
ha->optrom_buffer = vzalloc(ha->optrom_region_size);
if (ha->optrom_buffer == NULL) {
ql_log(ql_log_warn, vha, 0x7062,
"Unable to allocate memory for optrom retrieval "
@@ -404,7 +404,6 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
"Reading flash region -- 0x%x/0x%x.\n",
ha->optrom_region_start, ha->optrom_region_size);
memset(ha->optrom_buffer, 0, ha->optrom_region_size);
ha->isp_ops->read_optrom(vha, ha->optrom_buffer,
ha->optrom_region_start, ha->optrom_region_size);
break;
@@ -457,7 +456,7 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
ha->optrom_region_size = size;
ha->optrom_state = QLA_SWRITING;
ha->optrom_buffer = vmalloc(ha->optrom_region_size);
ha->optrom_buffer = vzalloc(ha->optrom_region_size);
if (ha->optrom_buffer == NULL) {
ql_log(ql_log_warn, vha, 0x7066,
"Unable to allocate memory for optrom update "
@@ -472,7 +471,6 @@ qla2x00_sysfs_write_optrom_ctl(struct file *filp, struct kobject *kobj,
"Staging flash region write -- 0x%x/0x%x.\n",
ha->optrom_region_start, ha->optrom_region_size);
memset(ha->optrom_buffer, 0, ha->optrom_region_size);
break;
case 3:
if (ha->optrom_state != QLA_SWRITING) {
+6 -6
View File
@@ -33,10 +33,8 @@ static inline void bsg_job_done_backport(struct fc_bsg_job *job, int result,
#endif
/* BSG support for ELS/CT pass through */
void
qla2x00_bsg_job_done(void *ptr, int res)
void qla2x00_bsg_job_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
#ifndef NEW_LIBFC_API
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
#else
@@ -50,10 +48,8 @@ qla2x00_bsg_job_done(void *ptr, int res)
sp->free(sp);
}
void
qla2x00_bsg_sp_free(void *ptr)
void qla2x00_bsg_sp_free(srb_t *sp)
{
srb_t *sp = ptr;
struct qla_hw_data *ha = sp->vha->hw;
#ifndef NEW_LIBFC_API
struct fc_bsg_job *bsg_job = sp->u.bsg_job;
@@ -380,6 +376,8 @@ qla2x00_process_els(struct bsg_job *bsg_job)
dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
if (!req_sg_cnt) {
dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
rval = -ENOMEM;
goto done_free_fcport;
}
@@ -387,6 +385,8 @@ qla2x00_process_els(struct bsg_job *bsg_job)
rsp_sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
if (!rsp_sg_cnt) {
dma_unmap_sg(&ha->pdev->dev, bsg_job->reply_payload.sg_list,
bsg_job->reply_payload.sg_cnt, DMA_FROM_DEVICE);
rval = -ENOMEM;
goto done_free_fcport;
}
+27 -28
View File
@@ -331,7 +331,8 @@ struct srb_cmd {
uint32_t request_sense_length;
uint32_t fw_sense_length;
uint8_t *request_sense_ptr;
void *ctx;
struct ct6_dsd *ct6_ctx;
struct crc_context *crc_ctx;
};
/*
@@ -610,6 +611,7 @@ typedef struct srb {
wait_queue_head_t nvme_ls_waitq;
struct fc_port *fcport;
struct scsi_qla_host *vha;
unsigned int start_timer:1;
uint32_t handle;
uint16_t flags;
uint16_t type;
@@ -631,14 +633,22 @@ typedef struct srb {
#endif
struct srb_cmd scmd;
} u;
void (*done)(void *, int);
void (*free)(void *);
/*
* Report completion status @res and call sp_put(@sp). @res is
* an NVMe status code, a SCSI result (e.g. DID_OK << 16) or a
* QLA_* status value.
*/
void (*done)(struct srb *sp, int res);
/* Stop the timer and free @sp. Only used by the FCP code. */
void (*free)(struct srb *sp);
/*
* Call nvme_private->fd->done() and free @sp. Only used by the NVMe
* code.
*/
void (*put_fn)(struct kref *kref);
} srb_t;
#define GET_CMD_SP(sp) (sp->u.scmd.cmd)
#define SET_CMD_SP(sp, cmd) (sp->u.scmd.cmd = cmd)
#define GET_CMD_CTX_SP(sp) (sp->u.scmd.ctx)
#define GET_CMD_SENSE_LEN(sp) \
(sp->u.scmd.request_sense_length)
@@ -998,6 +1008,11 @@ struct mbx_cmd_32 {
#define MBS_LINK_DOWN_ERROR 0x400B
#define MBS_DIAG_ECHO_TEST_ERROR 0x400C
static inline bool qla2xxx_is_valid_mbs(unsigned int mbs)
{
return MBS_COMMAND_COMPLETE <= mbs && mbs <= MBS_DIAG_ECHO_TEST_ERROR;
}
/*
* ISP mailbox asynchronous event status codes
*/
@@ -2366,22 +2381,6 @@ enum login_state { /* FW control Target side */
DSC_LS_LOGO_PEND,
};
enum fcport_mgt_event {
FCME_RELOGIN = 1,
FCME_RSCN,
FCME_PLOGI_DONE, /* Initiator side sent LLIOCB */
FCME_PRLI_DONE,
FCME_GNL_DONE,
FCME_GPSC_DONE,
FCME_GPDB_DONE,
FCME_GPNID_DONE,
FCME_GFFID_DONE,
FCME_ADISC_DONE,
FCME_GNNID_DONE,
FCME_GFPNID_DONE,
FCME_ELS_PLOGI_DONE,
};
enum rscn_addr_format {
RSCN_PORT_ADDR,
RSCN_AREA_ADDR,
@@ -2500,7 +2499,6 @@ typedef struct fc_port {
#define QLA_FCPORT_FOUND 2
struct event_arg {
enum fcport_mgt_event event;
fc_port_t *fcport;
srb_t *sp;
port_id_t id;
@@ -2823,7 +2821,7 @@ struct ct_sns_req {
/* GA_NXT, GPN_ID, GNN_ID, GFT_ID, GFPN_ID */
struct {
uint8_t reserved;
uint8_t port_id[3];
be_id_t port_id;
} port_id;
struct {
@@ -2842,13 +2840,13 @@ struct ct_sns_req {
struct {
uint8_t reserved;
uint8_t port_id[3];
be_id_t port_id;
uint8_t fc4_types[32];
} rft_id;
struct {
uint8_t reserved;
uint8_t port_id[3];
be_id_t port_id;
uint16_t reserved2;
uint8_t fc4_feature;
uint8_t fc4_type;
@@ -2856,7 +2854,7 @@ struct ct_sns_req {
struct {
uint8_t reserved;
uint8_t port_id[3];
be_id_t port_id;
uint8_t node_name[8];
} rnn_id;
@@ -2943,7 +2941,7 @@ struct ct_rsp_hdr {
struct ct_sns_gid_pt_data {
uint8_t control_byte;
uint8_t port_id[3];
be_id_t port_id;
};
/* It's the same for both GPN_FT and GNN_FT */
@@ -2973,7 +2971,7 @@ struct ct_sns_rsp {
union {
struct {
uint8_t port_type;
uint8_t port_id[3];
be_id_t port_id;
uint8_t port_name[8];
uint8_t sym_port_name_len;
uint8_t sym_port_name[255];
@@ -4706,6 +4704,7 @@ struct secure_flash_update_block_pk {
#define QLA_SUSPENDED 0x106
#define QLA_BUSY 0x107
#define QLA_ALREADY_REGISTERED 0x109
#define QLA_OS_TIMER_EXPIRED 0x10a
#define NVRAM_DELAY() udelay(10)
+13 -8
View File
@@ -98,7 +98,11 @@ extern int qla2x00_init_rings(scsi_qla_host_t *);
extern struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *,
int, int, bool);
extern int qla2xxx_delete_qpair(struct scsi_qla_host *, struct qla_qpair *);
void qla2x00_fcport_event_handler(scsi_qla_host_t *, struct event_arg *);
void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea);
void qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha,
struct event_arg *ea);
void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
struct event_arg *ea);
int qla24xx_async_gpdb(struct scsi_qla_host *, fc_port_t *, u8);
int qla24xx_async_prli(struct scsi_qla_host *, fc_port_t *);
int qla24xx_async_notify_ack(scsi_qla_host_t *, fc_port_t *,
@@ -219,9 +223,9 @@ extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
extern int qla2x00_post_uevent_work(struct scsi_qla_host *, u32);
extern void qla2x00_disable_board_on_pci_error(struct work_struct *);
extern void qla2x00_sp_compl(void *, int);
extern void qla2xxx_qpair_sp_free_dma(void *);
extern void qla2xxx_qpair_sp_compl(void *, int);
extern void qla2x00_sp_compl(srb_t *sp, int);
extern void qla2xxx_qpair_sp_free_dma(srb_t *sp);
extern void qla2xxx_qpair_sp_compl(srb_t *sp, int);
extern void qla24xx_sched_upd_fcport(fc_port_t *);
void qla2x00_handle_login_done_event(struct scsi_qla_host *, fc_port_t *,
uint16_t *);
@@ -250,7 +254,7 @@ extern void qla2x00_do_dpc_all_vps(scsi_qla_host_t *);
extern int qla24xx_vport_create_req_sanity_check(struct fc_vport *);
extern scsi_qla_host_t *qla24xx_create_vhost(struct fc_vport *);
extern void qla2x00_sp_free_dma(void *);
extern void qla2x00_sp_free_dma(srb_t *sp);
extern char *qla2x00_get_fw_version_str(struct scsi_qla_host *, char *);
extern void qla2x00_mark_device_lost(scsi_qla_host_t *, fc_port_t *, int, int);
@@ -278,6 +282,7 @@ extern void qla2x00_build_scsi_iocbs_32(srb_t *, cmd_entry_t *, uint16_t);
extern void qla2x00_build_scsi_iocbs_64(srb_t *, cmd_entry_t *, uint16_t);
extern void qla24xx_build_scsi_iocbs(srb_t *, struct cmd_type_7 *,
uint16_t, struct req_que *);
extern uint32_t qla2xxx_get_next_handle(struct req_que *req);
extern int qla2x00_start_scsi(srb_t *sp);
extern int qla24xx_start_scsi(srb_t *sp);
int qla2x00_marker(struct scsi_qla_host *, struct qla_qpair *,
@@ -796,10 +801,10 @@ extern int qla82xx_restart_isp(scsi_qla_host_t *);
/* IOCB related functions */
extern int qla82xx_start_scsi(srb_t *);
extern void qla2x00_sp_free(void *);
extern void qla2x00_sp_free(srb_t *sp);
extern void qla2x00_sp_timeout(struct timer_list *);
extern void qla2x00_bsg_job_done(void *, int);
extern void qla2x00_bsg_sp_free(void *);
extern void qla2x00_bsg_job_done(srb_t *sp, int);
extern void qla2x00_bsg_sp_free(srb_t *sp);
extern void qla2x00_start_iocbs(struct scsi_qla_host *, struct req_que *);
/* Interrupt related */
+93 -117
View File
@@ -226,9 +226,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_id */
ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -242,9 +240,7 @@ qla2x00_ga_nxt(scsi_qla_host_t *vha, fc_port_t *fcport)
rval = QLA_FUNCTION_FAILED;
} else {
/* Populate fc_port_t entry. */
fcport->d_id.b.domain = ct_rsp->rsp.ga_nxt.port_id[0];
fcport->d_id.b.area = ct_rsp->rsp.ga_nxt.port_id[1];
fcport->d_id.b.al_pa = ct_rsp->rsp.ga_nxt.port_id[2];
fcport->d_id = be_to_port_id(ct_rsp->rsp.ga_nxt.port_id);
memcpy(fcport->node_name, ct_rsp->rsp.ga_nxt.node_name,
WWN_SIZE);
@@ -337,9 +333,7 @@ qla2x00_gid_pt(scsi_qla_host_t *vha, sw_info_t *list)
/* Set port IDs in switch info list. */
for (i = 0; i < ha->max_fibre_devices; i++) {
gid_data = &ct_rsp->rsp.gid_pt.entries[i];
list[i].d_id.b.domain = gid_data->port_id[0];
list[i].d_id.b.area = gid_data->port_id[1];
list[i].d_id.b.al_pa = gid_data->port_id[2];
list[i].d_id = be_to_port_id(gid_data->port_id);
memset(list[i].fabric_port_name, 0, WWN_SIZE);
list[i].fp_speed = PORT_SPEED_UNKNOWN;
@@ -403,9 +397,7 @@ qla2x00_gpn_id(scsi_qla_host_t *vha, sw_info_t *list)
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_id */
ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -472,9 +464,7 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_id */
ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -509,9 +499,8 @@ qla2x00_gnn_id(scsi_qla_host_t *vha, sw_info_t *list)
return (rval);
}
static void qla2x00_async_sns_sp_done(void *s, int rc)
static void qla2x00_async_sns_sp_done(srb_t *sp, int rc)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
struct ct_sns_pkt *ct_sns;
struct qla_work_evt *e;
@@ -639,9 +628,7 @@ static int qla_async_rftid(scsi_qla_host_t *vha, port_id_t *d_id)
ct_req = qla2x00_prep_ct_req(ct_sns, RFT_ID_CMD, RFT_ID_RSP_SIZE);
/* Prepare CT arguments -- port_id, FC-4 types */
ct_req->req.rft_id.port_id[0] = vha->d_id.b.domain;
ct_req->req.rft_id.port_id[1] = vha->d_id.b.area;
ct_req->req.rft_id.port_id[2] = vha->d_id.b.al_pa;
ct_req->req.rft_id.port_id = port_id_to_be_id(vha->d_id);
ct_req->req.rft_id.fc4_types[2] = 0x01; /* FCP-3 */
if (vha->flags.nvme_enabled)
@@ -737,9 +724,7 @@ static int qla_async_rffid(scsi_qla_host_t *vha, port_id_t *d_id,
ct_req = qla2x00_prep_ct_req(ct_sns, RFF_ID_CMD, RFF_ID_RSP_SIZE);
/* Prepare CT arguments -- port_id, FC-4 feature, FC-4 type */
ct_req->req.rff_id.port_id[0] = d_id->b.domain;
ct_req->req.rff_id.port_id[1] = d_id->b.area;
ct_req->req.rff_id.port_id[2] = d_id->b.al_pa;
ct_req->req.rff_id.port_id = port_id_to_be_id(*d_id);
ct_req->req.rff_id.fc4_feature = fc4feature;
ct_req->req.rff_id.fc4_type = fc4type; /* SCSI - FCP */
@@ -830,9 +815,7 @@ static int qla_async_rnnid(scsi_qla_host_t *vha, port_id_t *d_id,
ct_req = qla2x00_prep_ct_req(ct_sns, RNN_ID_CMD, RNN_ID_RSP_SIZE);
/* Prepare CT arguments -- port_id, node_name */
ct_req->req.rnn_id.port_id[0] = vha->d_id.b.domain;
ct_req->req.rnn_id.port_id[1] = vha->d_id.b.area;
ct_req->req.rnn_id.port_id[2] = vha->d_id.b.al_pa;
ct_req->req.rnn_id.port_id = port_id_to_be_id(vha->d_id);
memcpy(ct_req->req.rnn_id.node_name, vha->node_name, WWN_SIZE);
sp->u.iocb_cmd.u.ctarg.req_size = RNN_ID_REQ_SIZE;
@@ -2728,9 +2711,7 @@ qla2x00_gfpn_id(scsi_qla_host_t *vha, sw_info_t *list)
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_id */
ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -2934,9 +2915,7 @@ qla2x00_gff_id(scsi_qla_host_t *vha, sw_info_t *list)
ct_rsp = &ha->ct_sns->p.rsp;
/* Prepare CT arguments -- port_id */
ct_req->req.port_id.port_id[0] = list[i].d_id.b.domain;
ct_req->req.port_id.port_id[1] = list[i].d_id.b.area;
ct_req->req.port_id.port_id[2] = list[i].d_id.b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(list[i].d_id);
/* Execute MS IOCB */
rval = qla2x00_issue_iocb(vha, ha->ms_iocb, ha->ms_iocb_dma,
@@ -3009,9 +2988,8 @@ void qla24xx_handle_gpsc_event(scsi_qla_host_t *vha, struct event_arg *ea)
qla_post_iidma_work(vha, fcport);
}
static void qla24xx_async_gpsc_sp_done(void *s, int res)
static void qla24xx_async_gpsc_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
struct qla_hw_data *ha = vha->hw;
fc_port_t *fcport = sp->fcport;
@@ -3052,11 +3030,10 @@ static void qla24xx_async_gpsc_sp_done(void *s, int res)
be16_to_cpu(ct_rsp->rsp.gpsc.speed));
}
memset(&ea, 0, sizeof(ea));
ea.event = FCME_GPSC_DONE;
ea.rc = res;
ea.fcport = fcport;
ea.sp = sp;
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_gpsc_event(vha, &ea);
done:
sp->free(sp);
@@ -3267,9 +3244,8 @@ void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
}
}
static void qla2x00_async_gpnid_sp_done(void *s, int res)
static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
struct ct_sns_req *ct_req =
(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
@@ -3283,27 +3259,24 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res)
ql_dbg(ql_dbg_disc, vha, 0x2066,
"Async done-%s fail res %x rscn gen %d ID %02x:%02x:%02x. %s\n",
sp->name, res, sp->gen1,
ct_req->req.port_id.port_id[0],
ct_req->req.port_id.port_id[1],
ct_req->req.port_id.port_id[2],
ct_req->req.port_id.port_id.domain,
ct_req->req.port_id.port_id.area,
ct_req->req.port_id.port_id.al_pa,
wwn_to_str(ct_rsp->rsp.gpn_id.port_name));
else
ql_dbg(ql_dbg_disc, vha, 0x2066,
"Async done-%s good rscn gen %d ID %02x:%02x:%02x. %s\n",
sp->name, sp->gen1,
ct_req->req.port_id.port_id[0],
ct_req->req.port_id.port_id[1],
ct_req->req.port_id.port_id[2],
ct_req->req.port_id.port_id.domain,
ct_req->req.port_id.port_id.area,
ct_req->req.port_id.port_id.al_pa,
wwn_to_str(ct_rsp->rsp.gpn_id.port_name));
memset(&ea, 0, sizeof(ea));
memcpy(ea.port_name, ct_rsp->rsp.gpn_id.port_name, WWN_SIZE);
ea.sp = sp;
ea.id.b.domain = ct_req->req.port_id.port_id[0];
ea.id.b.area = ct_req->req.port_id.port_id[1];
ea.id.b.al_pa = ct_req->req.port_id.port_id[2];
ea.id = be_to_port_id(ct_req->req.port_id.port_id);
ea.rc = res;
ea.event = FCME_GPNID_DONE;
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
list_del(&sp->elem);
@@ -3322,7 +3295,7 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res)
return;
}
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_gpnid_event(vha, &ea);
e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
if (!e) {
@@ -3409,9 +3382,7 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
ct_req = qla2x00_prep_ct_req(ct_sns, GPN_ID_CMD, GPN_ID_RSP_SIZE);
/* GPN_ID req */
ct_req->req.port_id.port_id[0] = id->b.domain;
ct_req->req.port_id.port_id[1] = id->b.area;
ct_req->req.port_id.port_id[2] = id->b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(*id);
sp->u.iocb_cmd.u.ctarg.req_size = GPN_ID_REQ_SIZE;
sp->u.iocb_cmd.u.ctarg.rsp_size = GPN_ID_RSP_SIZE;
@@ -3422,9 +3393,9 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
ql_dbg(ql_dbg_disc, vha, 0x2067, "Async-%s hdl=%x ID %02x:%02x:%02x.\n",
sp->name, sp->handle,
ct_req->req.port_id.port_id[0],
ct_req->req.port_id.port_id[1],
ct_req->req.port_id.port_id[2]);
ct_req->req.port_id.port_id.domain,
ct_req->req.port_id.port_id.area,
ct_req->req.port_id.port_id.al_pa);
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS)
@@ -3459,54 +3430,52 @@ done:
void qla24xx_handle_gffid_event(scsi_qla_host_t *vha, struct event_arg *ea)
{
fc_port_t *fcport = ea->fcport;
fc_port_t *fcport = ea->fcport;
qla24xx_post_gnl_work(vha, fcport);
qla24xx_post_gnl_work(vha, fcport);
}
void qla24xx_async_gffid_sp_done(void *s, int res)
void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
fc_port_t *fcport = sp->fcport;
struct ct_sns_rsp *ct_rsp;
struct event_arg ea;
struct scsi_qla_host *vha = sp->vha;
fc_port_t *fcport = sp->fcport;
struct ct_sns_rsp *ct_rsp;
struct event_arg ea;
ql_dbg(ql_dbg_disc, vha, 0x2133,
"Async done-%s res %x ID %x. %s\n",
sp->name, res, fcport->d_id.b24, wwn_to_str(fcport->port_name));
ql_dbg(ql_dbg_disc, vha, 0x2133,
"Async done-%s res %x ID %x. %s\n",
sp->name, res, fcport->d_id.b24, wwn_to_str(fcport->port_name));
fcport->flags &= ~FCF_ASYNC_SENT;
ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
/*
* FC-GS-7, 5.2.3.12 FC-4 Features - format
* The format of the FC-4 Features object, as defined by the FC-4,
* Shall be an array of 4-bit values, one for each type code value
*/
if (!res) {
if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
/* w1 b00:03 */
fcport->fc4_type =
ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
fcport->fc4_type &= 0xf;
}
fcport->flags &= ~FCF_ASYNC_SENT;
ct_rsp = &fcport->ct_desc.ct_sns->p.rsp;
/*
* FC-GS-7, 5.2.3.12 FC-4 Features - format
* The format of the FC-4 Features object, as defined by the FC-4,
* Shall be an array of 4-bit values, one for each type code value
*/
if (!res) {
if (ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET] & 0xf) {
/* w1 b00:03 */
fcport->fc4_type =
ct_rsp->rsp.gff_id.fc4_features[GFF_FCP_SCSI_OFFSET];
fcport->fc4_type &= 0xf;
}
if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
/* w5 [00:03]/28h */
fcport->fc4f_nvme =
ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
fcport->fc4f_nvme &= 0xf;
}
}
if (ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET] & 0xf) {
/* w5 [00:03]/28h */
fcport->fc4f_nvme =
ct_rsp->rsp.gff_id.fc4_features[GFF_NVME_OFFSET];
fcport->fc4f_nvme &= 0xf;
}
}
memset(&ea, 0, sizeof(ea));
ea.sp = sp;
ea.fcport = sp->fcport;
ea.rc = res;
ea.event = FCME_GFFID_DONE;
memset(&ea, 0, sizeof(ea));
ea.sp = sp;
ea.fcport = sp->fcport;
ea.rc = res;
qla2x00_fcport_event_handler(vha, &ea);
sp->free(sp);
qla24xx_handle_gffid_event(vha, &ea);
sp->free(sp);
}
/* Get FC4 Feature with Nport ID. */
@@ -3890,9 +3859,8 @@ static void qla2x00_find_free_fcp_nvme_slot(struct scsi_qla_host *vha,
}
}
static void qla2x00_async_gpnft_gnnft_sp_done(void *s, int res)
static void qla2x00_async_gpnft_gnnft_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
struct ct_sns_req *ct_req =
(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
@@ -4045,9 +4013,6 @@ static int qla24xx_async_gnnft(scsi_qla_host_t *vha, struct srb *sp,
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
goto done_free_sp;
}
@@ -4071,6 +4036,17 @@ done_free_sp:
sp->free(sp);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
if (vha->scan.scan_flags == 0) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s: schedule\n", __func__);
vha->scan.scan_flags |= SF_QUEUED;
schedule_delayed_work(&vha->scan.scan_work, 5);
}
spin_unlock_irqrestore(&vha->work_lock, flags);
return rval;
} /* GNNFT */
@@ -4144,7 +4120,7 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
rspsz,
&sp->u.iocb_cmd.u.ctarg.rsp_dma,
GFP_KERNEL);
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = rspsz;
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
ql_log(ql_log_warn, vha, 0xffff,
"Failed to allocate ct_sns request.\n");
@@ -4200,9 +4176,6 @@ int qla24xx_async_gpnft(scsi_qla_host_t *vha, u8 fc4_type, srb_t *sp)
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS) {
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
spin_unlock_irqrestore(&vha->work_lock, flags);
goto done_free_sp;
}
@@ -4226,6 +4199,17 @@ done_free_sp:
sp->free(sp);
spin_lock_irqsave(&vha->work_lock, flags);
vha->scan.scan_flags &= ~SF_SCANNING;
if (vha->scan.scan_flags == 0) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s: schedule\n", __func__);
vha->scan.scan_flags |= SF_QUEUED;
schedule_delayed_work(&vha->scan.scan_work, 5);
}
spin_unlock_irqrestore(&vha->work_lock, flags);
return rval;
}
@@ -4253,9 +4237,8 @@ void qla24xx_handle_gnnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
qla24xx_post_gnl_work(vha, ea->fcport);
}
static void qla2x00_async_gnnid_sp_done(void *s, int res)
static void qla2x00_async_gnnid_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
fc_port_t *fcport = sp->fcport;
u8 *node_name = fcport->ct_desc.ct_sns->p.rsp.rsp.gnn_id.node_name;
@@ -4271,14 +4254,13 @@ static void qla2x00_async_gnnid_sp_done(void *s, int res)
ea.fcport = fcport;
ea.sp = sp;
ea.rc = res;
ea.event = FCME_GNNID_DONE;
ql_dbg(ql_dbg_disc, vha, 0x204f,
"Async done-%s res %x, WWPN %s %s\n",
sp->name, res, wwn_to_str(fcport->port_name),
wwn_to_str(fcport->node_name));
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_gnnid_event(vha, &ea);
sp->free(sp);
}
@@ -4311,9 +4293,7 @@ int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
GNN_ID_RSP_SIZE);
/* GNN_ID req */
ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
/* req & rsp use the same buffer */
@@ -4389,9 +4369,8 @@ void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
qla24xx_post_gpsc_work(vha, fcport);
}
static void qla2x00_async_gfpnid_sp_done(void *s, int res)
static void qla2x00_async_gfpnid_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
fc_port_t *fcport = sp->fcport;
u8 *fpn = fcport->ct_desc.ct_sns->p.rsp.rsp.gfpn_id.port_name;
@@ -4406,14 +4385,13 @@ static void qla2x00_async_gfpnid_sp_done(void *s, int res)
ea.fcport = fcport;
ea.sp = sp;
ea.rc = res;
ea.event = FCME_GFPNID_DONE;
ql_dbg(ql_dbg_disc, vha, 0x204f,
"Async done-%s res %x, WWPN %s %s\n",
sp->name, res, wwn_to_str(fcport->port_name),
wwn_to_str(fcport->fabric_port_name));
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_gfpnid_event(vha, &ea);
sp->free(sp);
}
@@ -4444,9 +4422,7 @@ int qla24xx_async_gfpnid(scsi_qla_host_t *vha, fc_port_t *fcport)
GFPN_ID_RSP_SIZE);
/* GFPN_ID req */
ct_req->req.port_id.port_id[0] = fcport->d_id.b.domain;
ct_req->req.port_id.port_id[1] = fcport->d_id.b.area;
ct_req->req.port_id.port_id[2] = fcport->d_id.b.al_pa;
ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
/* req & rsp use the same buffer */
+197 -255
View File
@@ -36,8 +36,8 @@ static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
static int qla84xx_init_chip(scsi_qla_host_t *);
static int qla25xx_init_queues(struct qla_hw_data *);
static int qla24xx_post_prli_work(struct scsi_qla_host*, fc_port_t *);
static void qla24xx_handle_plogi_done_event(struct scsi_qla_host *,
struct event_arg *);
static void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha,
struct event_arg *ea);
static void qla24xx_handle_prli_done_event(struct scsi_qla_host *,
struct event_arg *);
static void __qla24xx_handle_gpdb_event(scsi_qla_host_t *, struct event_arg *);
@@ -62,10 +62,8 @@ qla2x00_sp_timeout(struct timer_list *t)
iocb->timeout(sp);
}
void
qla2x00_sp_free(void *ptr)
void qla2x00_sp_free(srb_t *sp)
{
srb_t *sp = ptr;
struct srb_iocb *iocb = &sp->u.iocb_cmd;
del_timer(&iocb->timer);
@@ -98,14 +96,26 @@ static void qla24xx_abort_iocb_timeout(void *data)
{
srb_t *sp = data;
struct srb_iocb *abt = &sp->u.iocb_cmd;
struct qla_qpair *qpair = sp->qpair;
u32 handle;
unsigned long flags;
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
for (handle = 1; handle < qpair->req->num_outstanding_cmds; handle++) {
/* removing the abort */
if (qpair->req->outstanding_cmds[handle] == sp) {
qpair->req->outstanding_cmds[handle] = NULL;
break;
}
}
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
abt->u.abt.comp_status = CS_TIMEOUT;
sp->done(sp, QLA_FUNCTION_TIMEOUT);
sp->done(sp, QLA_OS_TIMER_EXPIRED);
}
static void qla24xx_abort_sp_done(void *ptr, int res)
static void qla24xx_abort_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct srb_iocb *abt = &sp->u.iocb_cmd;
del_timer(&sp->u.iocb_cmd.timer);
@@ -158,6 +168,7 @@ static int qla24xx_async_abort_cmd(srb_t *cmd_sp, bool wait)
wait_for_completion(&abt_iocb->u.abt.comp);
rval = abt_iocb->u.abt.comp_status == CS_COMPLETE ?
QLA_SUCCESS : QLA_FUNCTION_FAILED;
sp->free(sp);
}
return rval;
@@ -230,13 +241,15 @@ qla2x00_async_iocb_timeout(void *data)
sp->done(sp, QLA_FUNCTION_TIMEOUT);
}
break;
default:
WARN_ON_ONCE(true);
sp->done(sp, QLA_FUNCTION_TIMEOUT);
break;
}
}
static void
qla2x00_async_login_sp_done(void *ptr, int res)
static void qla2x00_async_login_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct scsi_qla_host *vha = sp->vha;
struct srb_iocb *lio = &sp->u.iocb_cmd;
struct event_arg ea;
@@ -248,14 +261,13 @@ qla2x00_async_login_sp_done(void *ptr, int res)
if (!test_bit(UNLOADING, &vha->dpc_flags)) {
memset(&ea, 0, sizeof(ea));
ea.event = FCME_PLOGI_DONE;
ea.fcport = sp->fcport;
ea.data[0] = lio->u.logio.data[0];
ea.data[1] = lio->u.logio.data[1];
ea.iop[0] = lio->u.logio.iop[0];
ea.iop[1] = lio->u.logio.iop[1];
ea.sp = sp;
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_plogi_done_event(vha, &ea);
}
sp->free(sp);
@@ -285,8 +297,13 @@ qla2x00_async_login(struct scsi_qla_host *vha, fc_port_t *fcport,
struct srb_iocb *lio;
int rval = QLA_FUNCTION_FAILED;
if (!vha->flags.online)
goto done;
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) ||
fcport->loop_id == FC_NO_LOOP_ID) {
ql_log(ql_log_warn, vha, 0xffff,
"%s: %8phC - not sending command.\n",
__func__, fcport->port_name);
return rval;
}
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
@@ -338,11 +355,8 @@ done:
return rval;
}
static void
qla2x00_async_logout_sp_done(void *ptr, int res)
static void qla2x00_async_logout_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
sp->fcport->login_gen++;
qlt_logo_completion_handler(sp->fcport, res);
@@ -356,9 +370,6 @@ qla2x00_async_logout(struct scsi_qla_host *vha, fc_port_t *fcport)
struct srb_iocb *lio;
int rval = QLA_FUNCTION_FAILED;
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
return rval;
fcport->flags |= FCF_ASYNC_SENT;
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
if (!sp)
@@ -402,10 +413,8 @@ qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport,
qlt_logo_completion_handler(fcport, data[0]);
}
static void
qla2x00_async_prlo_sp_done(void *s, int res)
static void qla2x00_async_prlo_sp_done(srb_t *sp, int res)
{
srb_t *sp = (srb_t *)s;
struct srb_iocb *lio = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = sp->vha;
@@ -466,6 +475,9 @@ void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
fcport->fw_login_state, ea->rc, fcport->login_gen, ea->sp->gen2,
fcport->rscn_gen, ea->sp->gen1, fcport->loop_id);
WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
ea->data[0]);
if (ea->data[0] != MBS_COMMAND_COMPLETE) {
ql_dbg(ql_dbg_disc, vha, 0x2066,
"%s %s: adisc fail: post delete\n",
@@ -508,10 +520,8 @@ static int qla_post_els_plogi_work(struct scsi_qla_host *vha, fc_port_t *fcport)
return qla2x00_post_work(vha, e);
}
static void
qla2x00_async_adisc_sp_done(void *ptr, int res)
static void qla2x00_async_adisc_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct scsi_qla_host *vha = sp->vha;
struct event_arg ea;
struct srb_iocb *lio = &sp->u.iocb_cmd;
@@ -522,7 +532,6 @@ qla2x00_async_adisc_sp_done(void *ptr, int res)
sp->fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
memset(&ea, 0, sizeof(ea));
ea.event = FCME_ADISC_DONE;
ea.rc = res;
ea.data[0] = lio->u.logio.data[0];
ea.data[1] = lio->u.logio.data[1];
@@ -531,7 +540,7 @@ qla2x00_async_adisc_sp_done(void *ptr, int res)
ea.fcport = sp->fcport;
ea.sp = sp;
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_adisc_event(vha, &ea);
sp->free(sp);
}
@@ -916,10 +925,8 @@ static void qla24xx_handle_gnl_done_event(scsi_qla_host_t *vha,
}
} /* gnl_event */
static void
qla24xx_async_gnl_sp_done(void *s, int res)
static void qla24xx_async_gnl_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
unsigned long flags;
struct fc_port *fcport = NULL, *tf;
@@ -942,7 +949,6 @@ qla24xx_async_gnl_sp_done(void *s, int res)
memset(&ea, 0, sizeof(ea));
ea.sp = sp;
ea.rc = res;
ea.event = FCME_GNL_DONE;
if (sp->u.iocb_cmd.u.mbx.in_mb[1] >=
sizeof(struct get_name_list_extended)) {
@@ -981,7 +987,7 @@ qla24xx_async_gnl_sp_done(void *s, int res)
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
ea.fcport = fcport;
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_gnl_done_event(vha, &ea);
}
/* create new fcport if fw has knowledge of new sessions */
@@ -1105,10 +1111,8 @@ int qla24xx_post_gnl_work(struct scsi_qla_host *vha, fc_port_t *fcport)
return qla2x00_post_work(vha, e);
}
static
void qla24xx_async_gpdb_sp_done(void *s, int res)
static void qla24xx_async_gpdb_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
struct scsi_qla_host *vha = sp->vha;
struct qla_hw_data *ha = vha->hw;
fc_port_t *fcport = sp->fcport;
@@ -1127,11 +1131,10 @@ void qla24xx_async_gpdb_sp_done(void *s, int res)
fcport->flags &= ~(FCF_ASYNC_SENT | FCF_ASYNC_ACTIVE);
memset(&ea, 0, sizeof(ea));
ea.event = FCME_GPDB_DONE;
ea.fcport = fcport;
ea.sp = sp;
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_gpdb_event(vha, &ea);
dma_pool_free(ha->s_dma_pool, sp->u.iocb_cmd.u.mbx.in,
sp->u.iocb_cmd.u.mbx.in_dma);
@@ -1152,10 +1155,8 @@ static int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport)
return qla2x00_post_work(vha, e);
}
static void
qla2x00_async_prli_sp_done(void *ptr, int res)
static void qla2x00_async_prli_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct scsi_qla_host *vha = sp->vha;
struct srb_iocb *lio = &sp->u.iocb_cmd;
struct event_arg ea;
@@ -1167,7 +1168,6 @@ qla2x00_async_prli_sp_done(void *ptr, int res)
if (!test_bit(UNLOADING, &vha->dpc_flags)) {
memset(&ea, 0, sizeof(ea));
ea.event = FCME_PRLI_DONE;
ea.fcport = sp->fcport;
ea.data[0] = lio->u.logio.data[0];
ea.data[1] = lio->u.logio.data[1];
@@ -1175,7 +1175,7 @@ qla2x00_async_prli_sp_done(void *ptr, int res)
ea.iop[1] = lio->u.logio.iop[1];
ea.sp = sp;
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_prli_done_event(vha, &ea);
}
sp->free(sp);
@@ -1260,8 +1260,13 @@ int qla24xx_async_gpdb(struct scsi_qla_host *vha, fc_port_t *fcport, u8 opt)
struct port_database_24xx *pd;
struct qla_hw_data *ha = vha->hw;
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT) ||
fcport->loop_id == FC_NO_LOOP_ID) {
ql_log(ql_log_warn, vha, 0xffff,
"%s: %8phC - not sending command.\n",
__func__, fcport->port_name);
return rval;
}
fcport->disc_state = DSC_GPDB;
@@ -1633,12 +1638,34 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *vha, port_id_t *id,
return qla2x00_post_work(vha, e);
}
static
void qla2x00_handle_rscn(scsi_qla_host_t *vha, struct event_arg *ea)
{
fc_port_t *fcport;
unsigned long flags;
fcport = qla2x00_find_fcport_by_nportid(vha, &ea->id, 1);
if (fcport) {
fcport->scan_needed = 1;
fcport->rscn_gen++;
}
spin_lock_irqsave(&vha->work_lock, flags);
if (vha->scan.scan_flags == 0) {
ql_dbg(ql_dbg_disc, vha, 0xffff, "%s: schedule\n", __func__);
vha->scan.scan_flags |= SF_QUEUED;
schedule_delayed_work(&vha->scan.scan_work, 5);
}
spin_unlock_irqrestore(&vha->work_lock, flags);
}
void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
struct event_arg *ea)
{
fc_port_t *fcport = ea->fcport;
if (test_bit(UNLOADING, &vha->dpc_flags))
return;
ql_dbg(ql_dbg_disc, vha, 0x2102,
"%s %s DS %d LS %d P %d del %d cnfl %p rscn %d|%d login %d|%d fl %x\n",
__func__, wwn_to_str(fcport->port_name), fcport->disc_state,
@@ -1660,97 +1687,16 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha,
}
if (fcport->last_rscn_gen != fcport->rscn_gen) {
ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %s post gidpn\n",
ql_dbg(ql_dbg_disc, vha, 0x20e9, "%s %d %s post gnl\n",
__func__, __LINE__, wwn_to_str(fcport->port_name));
qla24xx_post_gnl_work(vha, fcport);
return;
}
qla24xx_fcport_handle_login(vha, fcport);
}
static void qla_handle_els_plogi_done(scsi_qla_host_t *vha,
struct event_arg *ea)
{
ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %s post PRLI\n",
__func__, __LINE__, wwn_to_str(ea->fcport->port_name));
qla24xx_post_prli_work(vha, ea->fcport);
}
void qla2x00_fcport_event_handler(scsi_qla_host_t *vha, struct event_arg *ea)
{
fc_port_t *fcport;
switch (ea->event) {
case FCME_RELOGIN:
if (test_bit(UNLOADING, &vha->dpc_flags))
return;
qla24xx_handle_relogin_event(vha, ea);
break;
case FCME_RSCN:
if (test_bit(UNLOADING, &vha->dpc_flags))
return;
{
unsigned long flags;
fcport = qla2x00_find_fcport_by_nportid
(vha, &ea->id, 1);
if (fcport) {
fcport->scan_needed = 1;
fcport->rscn_gen++;
}
spin_lock_irqsave(&vha->work_lock, flags);
if (vha->scan.scan_flags == 0) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s: schedule\n", __func__);
vha->scan.scan_flags |= SF_QUEUED;
schedule_delayed_work(&vha->scan.scan_work, 5);
}
spin_unlock_irqrestore(&vha->work_lock, flags);
}
break;
case FCME_GNL_DONE:
qla24xx_handle_gnl_done_event(vha, ea);
break;
case FCME_GPSC_DONE:
qla24xx_handle_gpsc_event(vha, ea);
break;
case FCME_PLOGI_DONE: /* Initiator side sent LLIOCB */
qla24xx_handle_plogi_done_event(vha, ea);
break;
case FCME_PRLI_DONE:
qla24xx_handle_prli_done_event(vha, ea);
break;
case FCME_GPDB_DONE:
qla24xx_handle_gpdb_event(vha, ea);
break;
case FCME_GPNID_DONE:
qla24xx_handle_gpnid_event(vha, ea);
break;
case FCME_GFFID_DONE:
qla24xx_handle_gffid_event(vha, ea);
break;
case FCME_ADISC_DONE:
qla24xx_handle_adisc_event(vha, ea);
break;
case FCME_GNNID_DONE:
qla24xx_handle_gnnid_event(vha, ea);
break;
case FCME_GFPNID_DONE:
qla24xx_handle_gfpnid_event(vha, ea);
break;
case FCME_ELS_PLOGI_DONE:
qla_handle_els_plogi_done(vha, ea);
break;
default:
BUG_ON(1);
break;
}
}
/*
* RSCN(s) came in for this fcport, but the RSCN(s) was not able
* to be consumed by the fcport
@@ -1768,10 +1714,9 @@ void qla_rscn_replay(fc_port_t *fcport)
if (fcport->scan_needed) {
memset(&ea, 0, sizeof(ea));
ea.event = FCME_RSCN;
ea.id = fcport->d_id;
ea.id.b.rsvd_1 = RSCN_PORT_ADDR;
qla2x00_fcport_event_handler(fcport->vha, &ea);
qla2x00_handle_rscn(fcport->vha, &ea);
}
}
@@ -1785,10 +1730,8 @@ qla2x00_tmf_iocb_timeout(void *data)
complete(&tmf->u.tmf.comp);
}
static void
qla2x00_tmf_sp_done(void *ptr, int res)
static void qla2x00_tmf_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct srb_iocb *tmf = &sp->u.iocb_cmd;
complete(&tmf->u.tmf.comp);
@@ -1886,6 +1829,9 @@ qla24xx_async_abort_command(srb_t *sp)
static void
qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
{
WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
ea->data[0]);
switch (ea->data[0]) {
case MBS_COMMAND_COMPLETE:
ql_dbg(ql_dbg_disc, vha, 0x2118, "%s %d %s post gpdb\n",
@@ -1924,7 +1870,7 @@ qla24xx_handle_prli_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
}
}
static void
void
qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
{
port_id_t cid; /* conflict Nport id */
@@ -1948,8 +1894,11 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
return;
}
if (fcport->disc_state == DSC_DELETE_PEND)
if ((fcport->disc_state == DSC_DELETE_PEND) ||
(fcport->disc_state == DSC_DELETED)) {
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
return;
}
if (ea->sp->gen2 != fcport->login_gen) {
/* target side must have changed it. */
@@ -1967,6 +1916,9 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
return;
}
WARN_ONCE(!qla2xxx_is_valid_mbs(ea->data[0]), "mbs: %#x\n",
ea->data[0]);
switch (ea->data[0]) {
case MBS_COMMAND_COMPLETE:
/*
@@ -2261,6 +2213,10 @@ qla2x00_initialize_adapter(scsi_qla_host_t *vha)
if (qla_ini_mode_enabled(vha) || qla_dual_mode_enabled(vha))
rval = qla2x00_init_rings(vha);
/* No point in continuing if firmware initialization failed. */
if (rval != QLA_SUCCESS)
return rval;
ha->flags.chip_reset_done = 1;
if (rval == QLA_SUCCESS && IS_QLA84XX(ha)) {
@@ -3077,103 +3033,113 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
}
static void
qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
qla2x00_init_fce_trace(scsi_qla_host_t *vha)
{
int rval;
dma_addr_t tc_dma;
void *tc;
struct qla_hw_data *ha = vha->hw;
if (!IS_FWI2_CAPABLE(ha))
return;
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
return;
if (ha->fce) {
ql_dbg(ql_dbg_init, vha, 0x00bd,
"%s: FCE Mem is already allocated.\n",
__func__);
return;
}
/* Allocate memory for Fibre Channel Event Buffer. */
tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
GFP_KERNEL);
if (!tc) {
ql_log(ql_log_warn, vha, 0x00be,
"Unable to allocate (%d KB) for FCE.\n",
FCE_SIZE / 1024);
return;
}
rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
ha->fce_mb, &ha->fce_bufs);
if (rval) {
ql_log(ql_log_warn, vha, 0x00bf,
"Unable to initialize FCE (%d).\n", rval);
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc, tc_dma);
return;
}
ql_dbg(ql_dbg_init, vha, 0x00c0,
"Allocated (%d KB) for FCE...\n", FCE_SIZE / 1024);
ha->flags.fce_enabled = 1;
ha->fce_dma = tc_dma;
ha->fce = tc;
}
static void
qla2x00_init_eft_trace(scsi_qla_host_t *vha)
{
int rval;
dma_addr_t tc_dma;
void *tc;
struct qla_hw_data *ha = vha->hw;
if (!IS_FWI2_CAPABLE(ha))
return;
if (ha->eft) {
ql_dbg(ql_dbg_init, vha, 0x00bd,
"%s: Offload Mem is already allocated.\n",
"%s: EFT Mem is already allocated.\n",
__func__);
return;
}
if (IS_FWI2_CAPABLE(ha)) {
/* Allocate memory for Fibre Channel Event Buffer. */
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
goto try_eft;
if (ha->fce)
dma_free_coherent(&ha->pdev->dev,
FCE_SIZE, ha->fce, ha->fce_dma);
/* Allocate memory for Fibre Channel Event Buffer. */
tc = dma_alloc_coherent(&ha->pdev->dev, FCE_SIZE, &tc_dma,
GFP_KERNEL);
if (!tc) {
ql_log(ql_log_warn, vha, 0x00be,
"Unable to allocate (%d KB) for FCE.\n",
FCE_SIZE / 1024);
goto try_eft;
}
rval = qla2x00_enable_fce_trace(vha, tc_dma, FCE_NUM_BUFFERS,
ha->fce_mb, &ha->fce_bufs);
if (rval) {
ql_log(ql_log_warn, vha, 0x00bf,
"Unable to initialize FCE (%d).\n", rval);
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, tc,
tc_dma);
ha->flags.fce_enabled = 0;
goto try_eft;
}
ql_dbg(ql_dbg_init, vha, 0x00c0,
"Allocate (%d KB) for FCE...\n", FCE_SIZE / 1024);
ha->flags.fce_enabled = 1;
ha->fce_dma = tc_dma;
ha->fce = tc;
try_eft:
if (ha->eft)
dma_free_coherent(&ha->pdev->dev,
EFT_SIZE, ha->eft, ha->eft_dma);
/* Allocate memory for Extended Trace Buffer. */
tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
GFP_KERNEL);
if (!tc) {
ql_log(ql_log_warn, vha, 0x00c1,
"Unable to allocate (%d KB) for EFT.\n",
EFT_SIZE / 1024);
goto eft_err;
}
rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
if (rval) {
ql_log(ql_log_warn, vha, 0x00c2,
"Unable to initialize EFT (%d).\n", rval);
dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc,
tc_dma);
goto eft_err;
}
ql_dbg(ql_dbg_init, vha, 0x00c3,
"Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
ha->eft_dma = tc_dma;
ha->eft = tc;
/* Allocate memory for Extended Trace Buffer. */
tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
GFP_KERNEL);
if (!tc) {
ql_log(ql_log_warn, vha, 0x00c1,
"Unable to allocate (%d KB) for EFT.\n",
EFT_SIZE / 1024);
return;
}
eft_err:
return;
rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
if (rval) {
ql_log(ql_log_warn, vha, 0x00c2,
"Unable to initialize EFT (%d).\n", rval);
dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc, tc_dma);
return;
}
ql_dbg(ql_dbg_init, vha, 0x00c3,
"Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
ha->eft_dma = tc_dma;
ha->eft = tc;
}
static void
qla2x00_alloc_offload_mem(scsi_qla_host_t *vha)
{
qla2x00_init_fce_trace(vha);
qla2x00_init_eft_trace(vha);
}
void
qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
{
int rval;
uint32_t dump_size, fixed_size, mem_size, req_q_size, rsp_q_size,
eft_size, fce_size, mq_size;
struct qla_hw_data *ha = vha->hw;
struct req_que *req = ha->req_q_map[0];
struct rsp_que *rsp = ha->rsp_q_map[0];
struct qla2xxx_fw_dump *fw_dump;
dma_addr_t tc_dma;
void *tc;
dump_size = fixed_size = mem_size = eft_size = fce_size = mq_size = 0;
req_q_size = rsp_q_size = 0;
@@ -3211,37 +3177,13 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
}
if (ha->tgt.atio_ring)
mq_size += ha->tgt.atio_q_length * sizeof(request_t);
/* Allocate memory for Fibre Channel Event Buffer. */
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
goto try_eft;
fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
try_eft:
qla2x00_init_fce_trace(vha);
if (ha->fce)
fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
qla2x00_init_eft_trace(vha);
if (ha->eft)
dma_free_coherent(&ha->pdev->dev,
EFT_SIZE, ha->eft, ha->eft_dma);
/* Allocate memory for Extended Trace Buffer. */
tc = dma_alloc_coherent(&ha->pdev->dev, EFT_SIZE, &tc_dma,
GFP_KERNEL);
if (!tc) {
ql_log(ql_log_warn, vha, 0x00c1,
"Unable to allocate (%d KB) for EFT.\n",
EFT_SIZE / 1024);
goto allocate;
}
rval = qla2x00_enable_eft_trace(vha, tc_dma, EFT_NUM_BUFFERS);
if (rval) {
ql_log(ql_log_warn, vha, 0x00c2,
"Unable to initialize EFT (%d).\n", rval);
dma_free_coherent(&ha->pdev->dev, EFT_SIZE, tc,
tc_dma);
}
ql_dbg(ql_dbg_init, vha, 0x00c3,
"Allocated (%d KB) EFT ...\n", EFT_SIZE / 1024);
eft_size = EFT_SIZE;
eft_size = EFT_SIZE;
}
if (IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@@ -3263,24 +3205,22 @@ try_eft:
j, fwdt->dump_size);
dump_size += fwdt->dump_size;
}
goto allocate;
} else {
req_q_size = req->length * sizeof(request_t);
rsp_q_size = rsp->length * sizeof(response_t);
dump_size = offsetof(struct qla2xxx_fw_dump, isp);
dump_size += fixed_size + mem_size + req_q_size + rsp_q_size
+ eft_size;
ha->chain_offset = dump_size;
dump_size += mq_size + fce_size;
if (ha->exchoffld_buf)
dump_size += sizeof(struct qla2xxx_offld_chain) +
ha->exchoffld_size;
if (ha->exlogin_buf)
dump_size += sizeof(struct qla2xxx_offld_chain) +
ha->exlogin_size;
}
req_q_size = req->length * sizeof(request_t);
rsp_q_size = rsp->length * sizeof(response_t);
dump_size = offsetof(struct qla2xxx_fw_dump, isp);
dump_size += fixed_size + mem_size + req_q_size + rsp_q_size + eft_size;
ha->chain_offset = dump_size;
dump_size += mq_size + fce_size;
if (ha->exchoffld_buf)
dump_size += sizeof(struct qla2xxx_offld_chain) +
ha->exchoffld_size;
if (ha->exlogin_buf)
dump_size += sizeof(struct qla2xxx_offld_chain) +
ha->exlogin_size;
allocate:
if (!ha->fw_dump_len || dump_size > ha->fw_dump_alloc_len) {
ql_dbg(ql_dbg_init, vha, 0x00c5,
@@ -6693,8 +6633,10 @@ qla2x00_abort_isp_cleanup(scsi_qla_host_t *vha)
}
/* Clear all async request states across all VPs. */
list_for_each_entry(fcport, &vha->vp_fcports, list)
list_for_each_entry(fcport, &vha->vp_fcports, list) {
fcport->flags &= ~(FCF_LOGIN_NEEDED | FCF_ASYNC_SENT);
fcport->scan_state = 0;
}
spin_lock_irqsave(&ha->vport_slock, flags);
list_for_each_entry(vp, &ha->vp_list, list) {
atomic_inc(&vp->vref_count);
+15 -13
View File
@@ -174,6 +174,18 @@ qla2x00_chip_is_down(scsi_qla_host_t *vha)
return (qla2x00_reset_active(vha) || !vha->hw->flags.fw_started);
}
static void qla2xxx_init_sp(srb_t *sp, scsi_qla_host_t *vha,
struct qla_qpair *qpair, fc_port_t *fcport)
{
memset(sp, 0, sizeof(*sp));
sp->fcport = fcport;
sp->iocbs = 1;
sp->vha = vha;
sp->qpair = qpair;
sp->cmd_type = TYPE_SRB;
INIT_LIST_HEAD(&sp->elem);
}
static inline srb_t *
qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
fc_port_t *fcport, gfp_t flag)
@@ -186,19 +198,9 @@ qla2xxx_get_qpair_sp(scsi_qla_host_t *vha, struct qla_qpair *qpair,
return NULL;
sp = mempool_alloc(qpair->srb_mempool, flag);
if (!sp)
goto done;
memset(sp, 0, sizeof(*sp));
sp->fcport = fcport;
sp->iocbs = 1;
sp->vha = vha;
sp->qpair = qpair;
sp->cmd_type = TYPE_SRB;
INIT_LIST_HEAD(&sp->elem);
done:
if (!sp)
if (sp)
qla2xxx_init_sp(sp, vha, qpair, fcport);
else
QLA_QPAIR_MARK_NOT_BUSY(qpair);
return sp;
}
+56 -115
View File
@@ -292,6 +292,26 @@ void qla2x00_build_scsi_iocbs_64(srb_t *sp, cmd_entry_t *cmd_pkt,
}
}
/*
* Find the first handle that is not in use, starting from
* req->current_outstanding_cmd + 1. The caller must hold the lock that is
* associated with @req.
*/
uint32_t qla2xxx_get_next_handle(struct req_que *req)
{
uint32_t index, handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
return handle;
}
return 0;
}
/**
* qla2x00_start_scsi() - Send a SCSI command to the ISP
* @sp: command to send to the ISP
@@ -306,7 +326,6 @@ qla2x00_start_scsi(srb_t *sp)
scsi_qla_host_t *vha;
struct scsi_cmnd *cmd;
uint32_t *clr_ptr;
uint32_t index;
uint32_t handle;
cmd_entry_t *cmd_pkt;
uint16_t cnt;
@@ -339,16 +358,8 @@ qla2x00_start_scsi(srb_t *sp)
/* Acquire ring specific lock */
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds)
handle = qla2xxx_get_next_handle(req);
if (handle == 0)
goto queuing_error;
/* Map the sg table so we have an accurate count of sg entries needed */
@@ -610,7 +621,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
}
cur_seg = scsi_sglist(cmd);
ctx = GET_CMD_CTX_SP(sp);
ctx = sp->u.scmd.ct6_ctx;
while (tot_dsds) {
avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ?
@@ -943,8 +954,7 @@ alloc_and_fill:
if (sp) {
list_add_tail(&dsd_ptr->list,
&((struct crc_context *)
sp->u.scmd.ctx)->dsd_list);
&sp->u.scmd.crc_ctx->dsd_list);
sp->flags |= SRB_CRC_CTX_DSD_VALID;
} else {
@@ -1041,8 +1051,7 @@ qla24xx_walk_and_build_sglist(struct qla_hw_data *ha, srb_t *sp,
if (sp) {
list_add_tail(&dsd_ptr->list,
&((struct crc_context *)
sp->u.scmd.ctx)->dsd_list);
&sp->u.scmd.crc_ctx->dsd_list);
sp->flags |= SRB_CRC_CTX_DSD_VALID;
} else {
@@ -1089,7 +1098,7 @@ qla24xx_walk_and_build_prot_sglist(struct qla_hw_data *ha, srb_t *sp,
sgl = scsi_prot_sglist(cmd);
vha = sp->vha;
difctx = sp->u.scmd.ctx;
difctx = sp->u.scmd.crc_ctx;
direction_to_device = cmd->sc_data_direction == DMA_TO_DEVICE;
ql_dbg(ql_dbg_tgt + ql_dbg_verbose, vha, 0xe021,
"%s: scsi_cmnd: %p, crc_ctx: %p, sp: %p\n",
@@ -1430,7 +1439,7 @@ qla24xx_build_scsi_crc_2_iocbs(srb_t *sp, struct cmd_type_crc_2 *cmd_pkt,
bundling = 0;
/* Allocate CRC context from global pool */
crc_ctx_pkt = sp->u.scmd.ctx =
crc_ctx_pkt = sp->u.scmd.crc_ctx =
dma_pool_zalloc(ha->dl_dma_pool, GFP_ATOMIC, &crc_ctx_dma);
if (!crc_ctx_pkt)
@@ -1590,7 +1599,6 @@ qla24xx_start_scsi(srb_t *sp)
int nseg;
unsigned long flags;
uint32_t *clr_ptr;
uint32_t index;
uint32_t handle;
struct cmd_type_7 *cmd_pkt;
uint16_t cnt;
@@ -1618,16 +1626,8 @@ qla24xx_start_scsi(srb_t *sp)
/* Acquire ring specific lock */
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds)
handle = qla2xxx_get_next_handle(req);
if (handle == 0)
goto queuing_error;
/* Map the sg table so we have an accurate count of sg entries needed */
@@ -1730,7 +1730,6 @@ qla24xx_dif_start_scsi(srb_t *sp)
int nseg;
unsigned long flags;
uint32_t *clr_ptr;
uint32_t index;
uint32_t handle;
uint16_t cnt;
uint16_t req_cnt = 0;
@@ -1771,17 +1770,8 @@ qla24xx_dif_start_scsi(srb_t *sp)
/* Acquire ring specific lock */
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds)
handle = qla2xxx_get_next_handle(req);
if (handle == 0)
goto queuing_error;
/* Compute number of required data segments */
@@ -1926,7 +1916,6 @@ qla2xxx_start_scsi_mq(srb_t *sp)
int nseg;
unsigned long flags;
uint32_t *clr_ptr;
uint32_t index;
uint32_t handle;
struct cmd_type_7 *cmd_pkt;
uint16_t cnt;
@@ -1957,16 +1946,8 @@ qla2xxx_start_scsi_mq(srb_t *sp)
vha->marker_needed = 0;
}
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds)
handle = qla2xxx_get_next_handle(req);
if (handle == 0)
goto queuing_error;
/* Map the sg table so we have an accurate count of sg entries needed */
@@ -2070,7 +2051,6 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
int nseg;
unsigned long flags;
uint32_t *clr_ptr;
uint32_t index;
uint32_t handle;
uint16_t cnt;
uint16_t req_cnt = 0;
@@ -2125,17 +2105,8 @@ qla2xxx_dif_start_scsi_mq(srb_t *sp)
vha->marker_needed = 0;
}
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds)
handle = qla2xxx_get_next_handle(req);
if (handle == 0)
goto queuing_error;
/* Compute number of required data segments */
@@ -2282,7 +2253,7 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
struct qla_hw_data *ha = vha->hw;
struct req_que *req = qpair->req;
device_reg_t *reg = ISP_QUE_REG(ha, req->id);
uint32_t index, handle;
uint32_t handle;
request_t *pkt;
uint16_t cnt, req_cnt;
@@ -2322,16 +2293,8 @@ __qla2x00_alloc_iocbs(struct qla_qpair *qpair, srb_t *sp)
goto queuing_error;
if (sp) {
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds) {
handle = qla2xxx_get_next_handle(req);
if (handle == 0) {
ql_log(ql_log_warn, vha, 0x700b,
"No room on outstanding cmd array.\n");
goto queuing_error;
@@ -2547,13 +2510,11 @@ void qla2x00_init_timer(srb_t *sp, unsigned long tmo)
sp->free = qla2x00_sp_free;
if (IS_QLAFX00(sp->vha->hw) && sp->type == SRB_FXIOCB_DCMD)
init_completion(&sp->u.iocb_cmd.u.fxiocb.fxiocb_comp);
add_timer(&sp->u.iocb_cmd.timer);
sp->start_timer = 1;
}
static void
qla2x00_els_dcmd_sp_free(void *data)
static void qla2x00_els_dcmd_sp_free(srb_t *sp)
{
srb_t *sp = data;
struct srb_iocb *elsio = &sp->u.iocb_cmd;
kfree(sp->fcport);
@@ -2583,10 +2544,8 @@ qla2x00_els_dcmd_iocb_timeout(void *data)
complete(&lio->u.els_logo.comp);
}
static void
qla2x00_els_dcmd_sp_done(void *ptr, int res)
static void qla2x00_els_dcmd_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
fc_port_t *fcport = sp->fcport;
struct srb_iocb *lio = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = sp->vha;
@@ -2779,10 +2738,8 @@ void qla2x00_els_dcmd2_free(scsi_qla_host_t *vha, struct els_plogi *els_plogi)
els_plogi->els_resp_pyld_dma);
}
static void
qla2x00_els_dcmd2_sp_done(void *ptr, int res)
static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
fc_port_t *fcport = sp->fcport;
struct srb_iocb *lio = &sp->u.iocb_cmd;
struct scsi_qla_host *vha = sp->vha;
@@ -2804,9 +2761,9 @@ qla2x00_els_dcmd2_sp_done(void *ptr, int res)
} else {
memset(&ea, 0, sizeof(ea));
ea.fcport = fcport;
ea.rc = res;
ea.event = FCME_ELS_PLOGI_DONE;
qla2x00_fcport_event_handler(vha, &ea);
ea.data[0] = MBS_COMMAND_COMPLETE;
ea.sp = sp;
qla24xx_handle_plogi_done_event(vha, &ea);
}
e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
@@ -3130,7 +3087,6 @@ qla82xx_start_scsi(srb_t *sp)
unsigned long flags;
struct scsi_cmnd *cmd;
uint32_t *clr_ptr;
uint32_t index;
uint32_t handle;
uint16_t cnt;
uint16_t req_cnt;
@@ -3170,16 +3126,8 @@ qla82xx_start_scsi(srb_t *sp)
/* Acquire ring specific lock */
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds)
handle = qla2xxx_get_next_handle(req);
if (handle == 0)
goto queuing_error;
/* Map the sg table so we have an accurate count of sg entries needed */
@@ -3250,7 +3198,7 @@ sufficient_dsds:
goto queuing_error;
}
ctx = sp->u.scmd.ctx =
ctx = sp->u.scmd.ct6_ctx =
mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
if (!ctx) {
ql_log(ql_log_fatal, vha, 0x3010,
@@ -3446,9 +3394,9 @@ queuing_error:
if (tot_dsds)
scsi_dma_unmap(cmd);
if (sp->u.scmd.ctx) {
mempool_free(sp->u.scmd.ctx, ha->ctx_mempool);
sp->u.scmd.ctx = NULL;
if (sp->u.scmd.crc_ctx) {
mempool_free(sp->u.scmd.crc_ctx, ha->ctx_mempool);
sp->u.scmd.crc_ctx = NULL;
}
spin_unlock_irqrestore(&ha->hardware_lock, flags);
@@ -3683,6 +3631,9 @@ qla2x00_start_sp(srb_t *sp)
break;
}
if (sp->start_timer)
add_timer(&sp->u.iocb_cmd.timer);
wmb();
qla2x00_start_iocbs(vha, qp->req);
done:
@@ -3788,7 +3739,6 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
struct qla_hw_data *ha = vha->hw;
unsigned long flags;
uint32_t handle;
uint32_t index;
uint16_t req_cnt;
uint16_t cnt;
uint32_t *clr_ptr;
@@ -3813,17 +3763,8 @@ qla2x00_start_bidir(srb_t *sp, struct scsi_qla_host *vha, uint32_t tot_dsds)
/* Acquire ring specific lock */
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds) {
handle = qla2xxx_get_next_handle(req);
if (handle == 0) {
rval = EXT_STATUS_BUSY;
goto queuing_error;
}
+8 -13
View File
@@ -788,7 +788,6 @@ skip_rio:
case MBA_LOOP_INIT_ERR:
ql_log(ql_log_warn, vha, 0x5090,
"LOOP INIT ERROR (%x).\n", mb[1]);
ha->isp_ops->fw_dump(vha, 1);
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
break;
@@ -1131,10 +1130,9 @@ global_port_update:
struct event_arg ea;
memset(&ea, 0, sizeof(ea));
ea.event = FCME_RSCN;
ea.id.b24 = rscn_entry;
ea.id.b.rsvd_1 = rscn_entry >> 24;
qla2x00_fcport_event_handler(vha, &ea);
qla2x00_handle_rscn(vha, &ea);
qla2x00_post_aen_work(vha, FCH_EVT_RSCN, rscn_entry);
}
break;
@@ -1530,7 +1528,7 @@ qla2x00_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
if (comp_status == CS_DATA_UNDERRUN) {
res = DID_OK << 16;
bsg_reply->reply_payload_rcv_len =
le16_to_cpu(((sts_entry_t *)pkt)->rsp_info_len);
le16_to_cpu(pkt->rsp_info_len);
ql_log(ql_log_warn, vha, 0x5048,
"CT pass-through-%s error comp_status=0x%x total_byte=0x%x.\n",
@@ -2281,11 +2279,8 @@ qla25xx_process_bidir_status_iocb(scsi_qla_host_t *vha, void *pkt,
#endif
struct fc_bsg_request *bsg_request;
struct fc_bsg_reply *bsg_reply;
sts_entry_t *sts;
struct sts_entry_24xx *sts24;
sts = (sts_entry_t *) pkt;
sts24 = (struct sts_entry_24xx *) pkt;
sts_entry_t *sts = pkt;
struct sts_entry_24xx *sts24 = pkt;
/* Validate handle. */
if (index >= req->num_outstanding_cmds) {
@@ -2431,8 +2426,8 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
srb_t *sp;
fc_port_t *fcport;
struct scsi_cmnd *cp;
sts_entry_t *sts;
struct sts_entry_24xx *sts24;
sts_entry_t *sts = pkt;
struct sts_entry_24xx *sts24 = pkt;
uint16_t comp_status;
uint16_t scsi_status;
uint16_t ox_id;
@@ -2450,8 +2445,6 @@ qla2x00_status_entry(scsi_qla_host_t *vha, struct rsp_que *rsp, void *pkt)
uint16_t state_flags = 0;
uint16_t retry_delay = 0;
sts = (sts_entry_t *) pkt;
sts24 = (struct sts_entry_24xx *) pkt;
if (IS_FWI2_CAPABLE(ha)) {
comp_status = le16_to_cpu(sts24->comp_status);
scsi_status = le16_to_cpu(sts24->scsi_status) & SS_MASK;
@@ -2868,6 +2861,8 @@ qla2x00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
if (sense_len == 0) {
rsp->status_srb = NULL;
sp->done(sp, cp->result);
} else {
WARN_ON_ONCE(true);
}
}
+1 -3
View File
@@ -6214,10 +6214,8 @@ qla26xx_dport_diagnostics(scsi_qla_host_t *vha,
return rval;
}
static void qla2x00_async_mb_sp_done(void *s, int res)
static void qla2x00_async_mb_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
sp->u.iocb_cmd.u.mbx.rc = res;
complete(&sp->u.iocb_cmd.u.mbx.comp);
+1 -3
View File
@@ -901,10 +901,8 @@ failed:
return 0;
}
static void qla_ctrlvp_sp_done(void *s, int res)
static void qla_ctrlvp_sp_done(srb_t *sp, int res)
{
struct srb *sp = s;
if (sp->comp)
complete(sp->comp);
/* don't free sp here. Let the caller do the free */
+21 -28
View File
@@ -1797,10 +1797,8 @@ qla2x00_fxdisc_iocb_timeout(void *data)
complete(&lio->u.fxiocb.fxiocb_comp);
}
static void
qla2x00_fxdisc_sp_done(void *ptr, int res)
static void qla2x00_fxdisc_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct srb_iocb *lio = &sp->u.iocb_cmd;
complete(&lio->u.fxiocb.fxiocb_comp);
@@ -1889,22 +1887,22 @@ qlafx00_fx_disc(scsi_qla_host_t *vha, fc_port_t *fcport, uint16_t fx_type)
phost_info = &preg_hsi->hsi;
memset(preg_hsi, 0, sizeof(struct register_host_info));
phost_info->os_type = OS_TYPE_LINUX;
strlcpy(phost_info->sysname,
p_sysid->sysname, SYSNAME_LENGTH);
strlcpy(phost_info->nodename,
p_sysid->nodename, NODENAME_LENGTH);
strlcpy(phost_info->sysname, p_sysid->sysname,
sizeof(phost_info->sysname));
strlcpy(phost_info->nodename, p_sysid->nodename,
sizeof(phost_info->nodename));
if (!strcmp(phost_info->nodename, "(none)"))
ha->mr.host_info_resend = true;
strlcpy(phost_info->release,
p_sysid->release, RELEASE_LENGTH);
strlcpy(phost_info->version,
p_sysid->version, VERSION_LENGTH);
strlcpy(phost_info->machine,
p_sysid->machine, MACHINE_LENGTH);
strlcpy(phost_info->domainname,
p_sysid->domainname, DOMNAME_LENGTH);
strlcpy(phost_info->hostdriver,
QLA2XXX_VERSION, VERSION_LENGTH);
strlcpy(phost_info->release, p_sysid->release,
sizeof(phost_info->release));
strlcpy(phost_info->version, p_sysid->version,
sizeof(phost_info->version));
strlcpy(phost_info->machine, p_sysid->machine,
sizeof(phost_info->machine));
strlcpy(phost_info->domainname, p_sysid->domainname,
sizeof(phost_info->domainname));
strlcpy(phost_info->hostdriver, QLA2XXX_VERSION,
sizeof(phost_info->hostdriver));
preg_hsi->utc = (uint64_t)ktime_get_real_seconds();
ql_dbg(ql_dbg_init, vha, 0x0149,
"ISP%04X: Host registration with firmware\n",
@@ -2556,6 +2554,8 @@ check_scsi_status:
if (rsp->status_srb == NULL)
sp->done(sp, res);
else
WARN_ON_ONCE(true);
}
/**
@@ -2633,6 +2633,8 @@ qlafx00_status_cont_entry(struct rsp_que *rsp, sts_cont_entry_t *pkt)
if (sense_len == 0) {
rsp->status_srb = NULL;
sp->done(sp, cp->result);
} else {
WARN_ON_ONCE(true);
}
}
@@ -3088,7 +3090,6 @@ qlafx00_start_scsi(srb_t *sp)
{
int nseg;
unsigned long flags;
uint32_t index;
uint32_t handle;
uint16_t cnt;
uint16_t req_cnt;
@@ -3112,16 +3113,8 @@ qlafx00_start_scsi(srb_t *sp)
/* Acquire ring specific lock */
spin_lock_irqsave(&ha->hardware_lock, flags);
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds)
handle = qla2xxx_get_next_handle(req);
if (handle == 0)
goto queuing_error;
/* Map the sg table so we have an accurate count of sg entries needed */
+8 -20
View File
@@ -191,10 +191,9 @@ static void qla_nvme_ls_complete(struct work_struct *work)
kref_put(&priv->sp->cmd_kref, qla_nvme_release_ls_cmd_kref);
}
static void qla_nvme_sp_ls_done(void *ptr, int res)
static void qla_nvme_sp_ls_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct nvme_private *priv;
struct nvme_private *priv = sp->priv;
if (WARN_ON_ONCE(kref_read(&sp->cmd_kref) == 0))
return;
@@ -202,17 +201,15 @@ static void qla_nvme_sp_ls_done(void *ptr, int res)
if (res)
res = -EINVAL;
priv = (struct nvme_private *)sp->priv;
priv->comp_status = res;
INIT_WORK(&priv->ls_work, qla_nvme_ls_complete);
schedule_work(&priv->ls_work);
}
/* it assumed that QPair lock is held. */
static void qla_nvme_sp_done(void *ptr, int res)
static void qla_nvme_sp_done(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct nvme_private *priv = (struct nvme_private *)sp->priv;
struct nvme_private *priv = sp->priv;
priv->comp_status = res;
kref_put(&sp->cmd_kref, qla_nvme_release_fcp_cmd_kref);
@@ -367,7 +364,6 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
{
unsigned long flags;
uint32_t *clr_ptr;
uint32_t index;
uint32_t handle;
struct cmd_nvme *cmd_pkt;
uint16_t cnt, i;
@@ -391,17 +387,8 @@ static inline int qla2x00_start_nvme_mq(srb_t *sp)
/* Acquire qpair specific lock */
spin_lock_irqsave(&qpair->qp_lock, flags);
/* Check for room in outstanding command list. */
handle = req->current_outstanding_cmd;
for (index = 1; index < req->num_outstanding_cmds; index++) {
handle++;
if (handle == req->num_outstanding_cmds)
handle = 1;
if (!req->outstanding_cmds[handle])
break;
}
if (index == req->num_outstanding_cmds) {
handle = qla2xxx_get_next_handle(req);
if (handle == 0) {
rval = -EBUSY;
goto queuing_error;
}
@@ -664,7 +651,8 @@ void qla_nvme_unregister_remote_port(struct fc_port *fcport)
__func__, fcport, fcport->port_name);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0)
nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0);
if (test_bit(PFLG_DRIVER_REMOVING, &fcport->vha->pci_flags))
nvme_fc_set_remoteport_devloss(fcport->nvme_remote_port, 0);
#endif
init_completion(&fcport->nvme_del_done);
ret = nvme_fc_unregister_remoteport(fcport->nvme_remote_port);
+1 -2
View File
@@ -164,6 +164,5 @@ static inline void qla_nvme_delete(struct scsi_qla_host *vha)
void qla24xx_nvme_ls4_iocb(struct scsi_qla_host *, struct pt_ls4_request *,
struct req_que *);
void qla24xx_async_gffid_sp_done(void *, int);
void qla24xx_async_gffid_sp_done(struct srb *sp, int);
#endif
+1 -1
View File
@@ -3685,7 +3685,7 @@ qla82xx_chip_reset_cleanup(scsi_qla_host_t *vha)
for (cnt = 1; cnt < req->num_outstanding_cmds; cnt++) {
sp = req->outstanding_cmds[cnt];
if (sp) {
if ((!sp->u.scmd.ctx ||
if ((!sp->u.scmd.crc_ctx ||
(sp->flags &
SRB_FCP_CMND_DMA_VALID)) &&
!ha->flags.isp82xx_fw_hung) {
+63 -78
View File
@@ -672,13 +672,10 @@ qla24xx_fw_version_str(struct scsi_qla_host *vha, char *str, size_t size)
return str;
}
void
qla2x00_sp_free_dma(void *ptr)
void qla2x00_sp_free_dma(srb_t *sp)
{
srb_t *sp = ptr;
struct qla_hw_data *ha = sp->vha->hw;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
void *ctx = GET_CMD_CTX_SP(sp);
if (sp->flags & SRB_DMA_VALID) {
scsi_dma_unmap(cmd);
@@ -691,24 +688,21 @@ qla2x00_sp_free_dma(void *ptr)
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
}
if (!ctx)
return;
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
qla2x00_clean_dsd_pool(ha, ctx);
qla2x00_clean_dsd_pool(ha, sp->u.scmd.crc_ctx);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
struct crc_context *ctx0 = ctx;
struct crc_context *ctx0 = sp->u.scmd.crc_ctx;
dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx1 = ctx;
struct ct6_dsd *ctx1 = sp->u.scmd.ct6_ctx;
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
ctx1->fcp_cmnd_dma);
@@ -719,10 +713,8 @@ qla2x00_sp_free_dma(void *ptr)
}
}
void
qla2x00_sp_compl(void *ptr, int res)
void qla2x00_sp_compl(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct completion *comp = sp->comp;
@@ -737,16 +729,12 @@ qla2x00_sp_compl(void *ptr, int res)
cmd->scsi_done(cmd);
if (comp)
complete(comp);
qla2x00_rel_sp(sp);
}
void
qla2xxx_qpair_sp_free_dma(void *ptr)
void qla2xxx_qpair_sp_free_dma(srb_t *sp)
{
srb_t *sp = (srb_t *)ptr;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct qla_hw_data *ha = sp->fcport->vha->hw;
void *ctx = GET_CMD_CTX_SP(sp);
if (sp->flags & SRB_DMA_VALID) {
scsi_dma_unmap(cmd);
@@ -759,17 +747,14 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
sp->flags &= ~SRB_CRC_PROT_DMA_VALID;
}
if (!ctx)
return;
if (sp->flags & SRB_CRC_CTX_DSD_VALID) {
/* List assured to be having elements */
qla2x00_clean_dsd_pool(ha, ctx);
qla2x00_clean_dsd_pool(ha, sp->u.scmd.crc_ctx);
sp->flags &= ~SRB_CRC_CTX_DSD_VALID;
}
if (sp->flags & SRB_DIF_BUNDL_DMA_VALID) {
struct crc_context *difctx = ctx;
struct crc_context *difctx = sp->u.scmd.crc_ctx;
struct dsd_dma *dif_dsd, *nxt_dsd;
list_for_each_entry_safe(dif_dsd, nxt_dsd,
@@ -805,7 +790,7 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
}
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx1 = ctx;
struct ct6_dsd *ctx1 = sp->u.scmd.ct6_ctx;
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx1->fcp_cmnd,
ctx1->fcp_cmnd_dma);
@@ -817,17 +802,15 @@ qla2xxx_qpair_sp_free_dma(void *ptr)
}
if (sp->flags & SRB_CRC_CTX_DMA_VALID) {
struct crc_context *ctx0 = ctx;
struct crc_context *ctx0 = sp->u.scmd.crc_ctx;
dma_pool_free(ha->dl_dma_pool, ctx, ctx0->crc_ctx_dma);
dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
}
void
qla2xxx_qpair_sp_compl(void *ptr, int res)
void qla2xxx_qpair_sp_compl(srb_t *sp, int res)
{
srb_t *sp = ptr;
struct scsi_cmnd *cmd = GET_CMD_SP(sp);
struct completion *comp = sp->comp;
@@ -842,7 +825,6 @@ qla2xxx_qpair_sp_compl(void *ptr, int res)
cmd->scsi_done(cmd);
if (comp)
complete(comp);
qla2xxx_rel_qpair_sp(sp->qpair, sp);
}
#if defined(RHEL_MAJOR) && RHEL_MAJOR -0 == 6 && RHEL_MINOR -0 >= 2
@@ -953,9 +935,8 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
else
goto qc24_target_busy;
sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
if (!sp)
goto qc24_host_busy;
sp = scsi_cmd_priv(cmd);
qla2xxx_init_sp(sp, vha, vha->hw->base_qpair, fcport);
sp->u.scmd.cmd = cmd;
sp->type = SRB_SCSI_CMD;
@@ -976,9 +957,6 @@ qla2xxx_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd)
qc24_host_busy_free_sp:
sp->free(sp);
qc24_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
qc24_target_busy:
return SCSI_MLQUEUE_TARGET_BUSY;
@@ -1039,9 +1017,8 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
else
goto qc24_target_busy;
sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
if (!sp)
goto qc24_host_busy;
sp = scsi_cmd_priv(cmd);
qla2xxx_init_sp(sp, vha, qpair, fcport);
sp->u.scmd.cmd = cmd;
sp->type = SRB_SCSI_CMD;
@@ -1065,9 +1042,6 @@ qla2xxx_mqueuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmd,
qc24_host_busy_free_sp:
sp->free(sp);
qc24_host_busy:
return SCSI_MLQUEUE_HOST_BUSY;
qc24_target_busy:
return SCSI_MLQUEUE_TARGET_BUSY;
@@ -1086,8 +1060,8 @@ qc24_fail_command:
* cmd = Scsi Command to wait on.
*
* Return:
* Not Found : 0
* Found : 1
* Completed in time : QLA_SUCCESS
* Did not complete in time : QLA_FUNCTION_FAILED
*/
static int
qla2x00_eh_wait_on_command(struct scsi_cmnd *cmd)
@@ -1309,10 +1283,8 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
int ret;
unsigned int id;
uint64_t lun;
unsigned long flags;
int rval;
struct qla_hw_data *ha = vha->hw;
struct qla_qpair *qpair;
if (qla2x00_isp_reg_stat(ha)) {
ql_log(ql_log_info, vha, 0x8042,
@@ -1324,30 +1296,15 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
if (ret != 0)
return ret;
sp = (srb_t *) CMD_SP(cmd);
if (!sp)
sp = scsi_cmd_priv(cmd);
if (sp->fcport && sp->fcport->deleted)
return SUCCESS;
qpair = sp->qpair;
if (!qpair)
/* Return if the command has already finished. */
if (sp_get(sp))
return SUCCESS;
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
if (sp->type != SRB_SCSI_CMD || GET_CMD_SP(sp) != cmd) {
/* there's a chance an interrupt could clear
the ptr as part of done & free */
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return SUCCESS;
}
/* Get a reference to the sp and drop the lock. */
if (sp_get(sp)){
/* ref_count is already 0 */
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return SUCCESS;
}
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
id = cmd->device->id;
lun = cmd->device->lun;
@@ -1355,7 +1312,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
"Aborting from RISC nexus=%ld:%d:%llu sp=%p cmd=%p handle=%x\n",
vha->host_no, id, lun, sp, cmd, sp->handle);
ret = SUCCESS;
rval = ha->isp_ops->abort_command(sp);
ql_dbg(ql_dbg_taskm, vha, 0x8003,
"Abort command mbx cmd=%p, rval=%x.\n", cmd, rval);
@@ -1367,23 +1323,32 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
* won't report a completion.
*/
sp->done(sp, DID_ABORT << 16);
ret = SUCCESS;
break;
case QLA_FUNCTION_PARAMETER_ERROR:
default: {
case QLA_FUNCTION_PARAMETER_ERROR: {
/* Wait for the command completion. */
uint32_t ratov = ha->r_a_tov/10;
uint32_t ratov_j = msecs_to_jiffies(4 * ratov * 1000);
WARN_ON_ONCE(sp->comp);
sp->comp = &comp;
if (!wait_for_completion_timeout(&comp, ratov_j)) {
ql_dbg(ql_dbg_taskm, vha, 0xffff,
"%s: Abort wait timer (4 * R_A_TOV[%d]) expired\n",
__func__, ha->r_a_tov);
ret = FAILED;
break;
} else {
ret = SUCCESS;
}
break;
}
default:
/*
* Either abort failed or abort and completion raced. Let
* the SCSI core retry the abort in the former case.
*/
ret = FAILED;
break;
}
sp->comp = NULL;
@@ -1395,6 +1360,9 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
return ret;
}
/*
* Returns: QLA_SUCCESS or QLA_FUNCTION_FAILED.
*/
int
qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *vha, unsigned int t,
uint64_t l, enum nexus_wait_type type)
@@ -1468,6 +1436,9 @@ __qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
if (err != 0)
return err;
if (fcport->deleted)
return SUCCESS;
ql_log(ql_log_info, vha, 0x8009,
"%s RESET ISSUED nexus=%ld:%d:%llu cmd=%p.\n", name, vha->host_no,
cmd->device->id, (u64)cmd->device->lun, cmd);
@@ -1582,6 +1553,9 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
return ret;
ret = FAILED;
if (qla2x00_chip_is_down(vha))
return ret;
ql_log(ql_log_info, vha, 0x8012,
"BUS RESET ISSUED nexus=%ld:%d:%llu.\n", vha->host_no, id, lun);
@@ -1794,6 +1768,8 @@ static void qla2x00_abort_srb(struct qla_qpair *qp, srb_t *sp, const int res,
spin_lock_irqsave(qp->qp_lock_ptr, *flags);
sp->comp = NULL;
}
atomic_dec(&sp->ref_count);
}
static void
@@ -1848,8 +1824,13 @@ qla2x00_abort_all_cmds(scsi_qla_host_t *vha, int res)
int que;
struct qla_hw_data *ha = vha->hw;
/* Continue only if initialization complete. */
if (!ha->base_qpair)
return;
__qla2x00_abort_all_cmds(ha->base_qpair, res);
if (!ha->queue_pair_map)
return;
for (que = 0; que < ha->max_qpairs; que++) {
if (!ha->queue_pair_map[que])
continue;
@@ -2529,7 +2510,7 @@ static struct isp_operations qla27xx_isp_ops = {
.config_rings = qla24xx_config_rings,
.reset_adapter = qla24xx_reset_adapter,
.nvram_config = qla81xx_nvram_config,
.update_fw_options = qla81xx_update_fw_options,
.update_fw_options = qla24xx_update_fw_options,
.load_risc = qla81xx_load_risc,
.pci_info_str = qla24xx_pci_info_str,
.fw_version_str = qla24xx_fw_version_str,
@@ -3206,6 +3187,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
ql_log(ql_log_fatal, base_vha, 0x003d,
"Failed to allocate memory for queue pointers..."
"aborting.\n");
ret = -ENODEV;
goto probe_failed;
}
@@ -4645,6 +4627,7 @@ qla2x00_free_fw_dump(struct qla_hw_data *ha)
ha->fce = NULL;
ha->fce_dma = 0;
ha->flags.fce_enabled = 0;
ha->eft = NULL;
ha->eft_dma = 0;
ha->fw_dumped = 0;
@@ -4763,7 +4746,7 @@ qla2x00_mem_free(struct qla_hw_data *ha)
mempool_destroy(ha->ctx_mempool);
ha->ctx_mempool = NULL;
if (ql2xenabledif) {
if (ql2xenabledif && ha->dif_bundl_pool) {
struct dsd_dma *dsd, *nxt;
list_for_each_entry_safe(dsd, nxt, &ha->pool.unusable.head,
@@ -4786,8 +4769,7 @@ qla2x00_mem_free(struct qla_hw_data *ha)
}
}
if (ha->dif_bundl_pool)
dma_pool_destroy(ha->dif_bundl_pool);
dma_pool_destroy(ha->dif_bundl_pool);
ha->dif_bundl_pool = NULL;
qlt_mem_free(ha);
@@ -4859,7 +4841,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
if (!vha->gnl.l) {
ql_log(ql_log_fatal, vha, 0xd04a,
"Alloc failed for name list.\n");
scsi_remove_host(vha->host);
scsi_host_put(vha->host);
return NULL;
}
@@ -4871,7 +4853,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
"Alloc failed for scan database.\n");
dma_free_coherent(&ha->pdev->dev, vha->gnl.size,
vha->gnl.l, vha->gnl.ldma);
scsi_remove_host(vha->host);
scsi_host_put(vha->host);
return NULL;
}
INIT_DELAYED_WORK(&vha->scan.scan_work, qla_scan_work_fn);
@@ -5138,6 +5120,7 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e)
if (fcport) {
fcport->id_changed = 1;
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->chip_reset = vha->hw->base_qpair->chip_reset;
memcpy(fcport->node_name, e->u.new_sess.node_name, WWN_SIZE);
if (pla) {
@@ -5400,9 +5383,8 @@ void qla2x00_relogin(struct scsi_qla_host *vha)
} else {
if (vha->hw->current_topology != ISP_CFG_NL) {
memset(&ea, 0, sizeof(ea));
ea.event = FCME_RELOGIN;
ea.fcport = fcport;
qla2x00_fcport_event_handler(vha, &ea);
qla24xx_handle_relogin_event(vha, &ea);
} else if (vha->hw->current_topology ==
ISP_CFG_NL) {
fcport->login_retry--;
@@ -6110,6 +6092,8 @@ qla2x00_disable_board_on_pci_error(struct work_struct *work)
qla2x00_delete_all_vps(ha, base_vha);
qla2x00_abort_all_cmds(base_vha, DID_NO_CONNECT << 16);
qla2x00_dfs_remove(base_vha);
qla84xx_put_chip(base_vha);
@@ -7229,6 +7213,7 @@ struct scsi_host_template qla2xxx_driver_template = {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)
.track_queue_depth = 1,
#endif
.cmd_size = sizeof(srb_t),
};
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 16, 0) && \
+15 -11
View File
@@ -572,10 +572,8 @@ static int qla24xx_post_nack_work(struct scsi_qla_host *vha, fc_port_t *fcport,
return qla2x00_post_work(vha, e);
}
static
void qla2x00_async_nack_sp_done(void *s, int res)
static void qla2x00_async_nack_sp_done(srb_t *sp, int res)
{
struct srb *sp = (struct srb *)s;
struct scsi_qla_host *vha = sp->vha;
unsigned long flags;
@@ -1224,7 +1222,6 @@ static void qla24xx_chk_fcp_state(struct fc_port *sess)
sess->logout_on_delete = 0;
sess->logo_ack_needed = 0;
sess->fw_login_state = DSC_LS_PORT_UNAVAIL;
sess->scan_state = 0;
}
}
@@ -3240,7 +3237,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
if (!qpair->fw_started || (cmd->reset_count != qpair->chip_reset) ||
(cmd->sess && cmd->sess->deleted)) {
cmd->state = QLA_TGT_STATE_PROCESSED;
return 0;
res = 0;
goto free;
}
ql_dbg_qp(ql_dbg_tgt, qpair, 0xe018,
@@ -3251,9 +3249,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
res = qlt_pre_xmit_response(cmd, &prm, xmit_type, scsi_status,
&full_req_cnt);
if (unlikely(res != 0)) {
return res;
}
if (unlikely(res != 0))
goto free;
spin_lock_irqsave(qpair->qp_lock_ptr, flags);
@@ -3273,7 +3270,8 @@ int qlt_xmit_response(struct qla_tgt_cmd *cmd, int xmit_type,
vha->flags.online, qla2x00_reset_active(vha),
cmd->reset_count, qpair->chip_reset);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
return 0;
res = 0;
goto free;
}
/* Does F/W have an IOCBs for this request */
@@ -3380,6 +3378,8 @@ out_unmap_unlock:
qlt_unmap_sg(vha, cmd);
spin_unlock_irqrestore(qpair->qp_lock_ptr, flags);
free:
vha->hw->tgt.tgt_ops->free_cmd(cmd);
return res;
}
EXPORT_SYMBOL(qlt_xmit_response);
@@ -6674,6 +6674,8 @@ qlt_enable_vha(struct scsi_qla_host *vha)
if (vha->qlini_mode == QLA2XXX_INI_MODE_ENABLED)
return;
if (ha->tgt.num_act_qpairs > ha->max_qpairs)
ha->tgt.num_act_qpairs = ha->max_qpairs;
spin_lock_irqsave(&ha->hardware_lock, flags);
tgt->tgt_stopped = 0;
qlt_set_mode(vha);
@@ -6720,7 +6722,9 @@ static void qlt_disable_vha(struct scsi_qla_host *vha)
set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
WARN_ON_ONCE(qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS);
if (qla2x00_wait_for_hba_online(vha) != QLA_SUCCESS)
ql_dbg(ql_dbg_tgt, vha, 0xe081,
"qla2x00_wait_for_hba_online() failed\n");
}
/*
@@ -6819,7 +6823,7 @@ qlt_24xx_process_atio_queue(struct scsi_qla_host *vha, uint8_t ha_locked)
*/
ql_log(ql_log_warn, vha, 0xd03c,
"corrupted fcp frame SID[%3phN] OXID[%04x] EXCG[%x] %64phN\n",
&pkt->u.isp24.fcp_hdr.s_id.domain,
&pkt->u.isp24.fcp_hdr.s_id,
be16_to_cpu(pkt->u.isp24.fcp_hdr.ox_id),
le32_to_cpu(pkt->u.isp24.exchange_addr), pkt);
+1 -1
View File
@@ -7,7 +7,7 @@
/*
* Driver version
*/
#define QLA2XXX_VERSION "10.01.00.16-k"
#define QLA2XXX_VERSION "10.01.00.18-k"
#define QLA_DRIVER_MAJOR_VER 10
#define QLA_DRIVER_MINOR_VER 1