Merge patch series "qla2xxx driver enhancements"

Nilesh Javali <njavali@marvell.com> says:

Please apply the qla2xxx driver enhancements to the SCSI tree at your
earliest convenience.

Link: https://lore.kernel.org/r/20221222043933.2825-1-njavali@marvell.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Martin K. Petersen 2023-01-11 23:49:21 -05:00
commit e63d2ea838
18 changed files with 529 additions and 671 deletions

View File

@ -2732,7 +2732,7 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport)
spin_lock_irqsave(host->host_lock, flags);
/* Confirm port has not reappeared before clearing pointers. */
if (rport->port_state != FC_PORTSTATE_ONLINE) {
fcport->rport = fcport->drport = NULL;
fcport->rport = NULL;
*((fc_port_t **)rport->dd_data) = NULL;
}
spin_unlock_irqrestore(host->host_lock, flags);
@ -3171,8 +3171,7 @@ qla24xx_vport_delete(struct fc_vport *fc_vport)
set_bit(VPORT_DELETE, &vha->dpc_flags);
while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags) ||
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags))
while (test_bit(LOOP_RESYNC_ACTIVE, &vha->dpc_flags))
msleep(1000);

View File

@ -384,6 +384,13 @@ struct els_reject {
struct req_que;
struct qla_tgt_sess;
struct qla_buf_dsc {
u16 tag;
#define TAG_FREED 0xffff
void *buf;
dma_addr_t buf_dma;
};
/*
* SCSI Request Block
*/
@ -392,14 +399,16 @@ struct srb_cmd {
uint32_t request_sense_length;
uint32_t fw_sense_length;
uint8_t *request_sense_ptr;
struct ct6_dsd *ct6_ctx;
struct crc_context *crc_ctx;
struct ct6_dsd ct6_ctx;
struct qla_buf_dsc buf_dsc;
};
/*
* SRB flag definitions
*/
#define SRB_DMA_VALID BIT_0 /* Command sent to ISP */
#define SRB_GOT_BUF BIT_1
#define SRB_FCP_CMND_DMA_VALID BIT_12 /* DIF: DSD List valid */
#define SRB_CRC_CTX_DMA_VALID BIT_2 /* DIF: context DMA valid */
#define SRB_CRC_PROT_DMA_VALID BIT_4 /* DIF: prot DMA valid */
@ -2485,7 +2494,6 @@ struct ct_sns_desc {
enum discovery_state {
DSC_DELETED,
DSC_GNN_ID,
DSC_GNL,
DSC_LOGIN_PEND,
DSC_LOGIN_FAILED,
@ -2596,7 +2604,7 @@ typedef struct fc_port {
int login_retry;
struct fc_rport *rport, *drport;
struct fc_rport *rport;
u32 supported_classes;
uint8_t fc4_type;
@ -2699,7 +2707,6 @@ extern const char *const port_state_str[5];
static const char *const port_dstate_str[] = {
[DSC_DELETED] = "DELETED",
[DSC_GNN_ID] = "GNN_ID",
[DSC_GNL] = "GNL",
[DSC_LOGIN_PEND] = "LOGIN_PEND",
[DSC_LOGIN_FAILED] = "LOGIN_FAILED",
@ -3462,6 +3469,7 @@ struct qla_msix_entry {
int have_irq;
int in_use;
uint32_t vector;
uint32_t vector_base0;
uint16_t entry;
char name[30];
void *handle;
@ -3479,7 +3487,6 @@ enum qla_work_type {
QLA_EVT_ASYNC_ADISC,
QLA_EVT_UEVENT,
QLA_EVT_AENFX,
QLA_EVT_GPNID,
QLA_EVT_UNMAP,
QLA_EVT_NEW_SESS,
QLA_EVT_GPDB,
@ -3493,7 +3500,6 @@ enum qla_work_type {
QLA_EVT_GPNFT,
QLA_EVT_GPNFT_DONE,
QLA_EVT_GNNFT_DONE,
QLA_EVT_GNNID,
QLA_EVT_GFPNID,
QLA_EVT_SP_RETRY,
QLA_EVT_IIDMA,
@ -3534,9 +3540,6 @@ struct qla_work_evt {
struct {
srb_t *sp;
} iosb;
struct {
port_id_t id;
} gpnid;
struct {
port_id_t id;
u8 port_name[8];
@ -3544,7 +3547,7 @@ struct qla_work_evt {
void *pla;
u8 fc4_type;
} new_sess;
struct { /*Get PDB, Get Speed, update fcport, gnl, gidpn */
struct { /*Get PDB, Get Speed, update fcport, gnl */
fc_port_t *fcport;
u8 opt;
} fcport;
@ -3729,6 +3732,19 @@ struct qla_fw_resources {
#define QLA_IOCB_PCT_LIMIT 95
struct qla_buf_pool {
u16 num_bufs;
u16 num_active;
u16 max_used;
u16 num_alloc;
u16 prev_max;
u16 pad;
uint32_t take_snapshot:1;
unsigned long *buf_map;
void **buf_array;
dma_addr_t *dma_array;
};
/*Queue pair data structure */
struct qla_qpair {
spinlock_t qp_lock;
@ -3782,6 +3798,7 @@ struct qla_qpair {
struct qla_tgt_counters tgt_counters;
uint16_t cpuid;
struct qla_fw_resources fwres ____cacheline_aligned;
struct qla_buf_pool buf_pool;
u32 cmd_cnt;
u32 cmd_completion_cnt;
u32 prev_completion_cnt;
@ -3942,7 +3959,6 @@ struct qlt_hw_data {
__le32 __iomem *atio_q_out;
const struct qla_tgt_func_tmpl *tgt_ops;
struct qla_tgt_vp_map *tgt_vp_map;
int saved_set;
__le16 saved_exchange_count;
@ -4110,6 +4126,7 @@ struct qla_hw_data {
struct req_que **req_q_map;
struct rsp_que **rsp_q_map;
struct qla_qpair **queue_pair_map;
struct qla_qpair **qp_cpu_map;
unsigned long req_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
unsigned long rsp_qid_map[(QLA_MAX_QUEUES / 8) / sizeof(unsigned long)];
unsigned long qpair_qid_map[(QLA_MAX_QUEUES / 8)
@ -4766,6 +4783,7 @@ struct qla_hw_data {
spinlock_t sadb_lock; /* protects list */
struct els_reject elsrej;
u8 edif_post_stop_cnt_down;
struct qla_vp_map *vp_map;
};
#define RX_ELS_SIZE (roundup(sizeof(struct enode) + ELS_MAX_PAYLOAD, SMP_CACHE_BYTES))
@ -4861,6 +4879,7 @@ typedef struct scsi_qla_host {
#define LOOP_READY 5
#define LOOP_DEAD 6
unsigned long buf_expired;
unsigned long relogin_jif;
unsigned long dpc_flags;
#define RESET_MARKER_NEEDED 0 /* Send marker to ISP. */
@ -4876,7 +4895,6 @@ typedef struct scsi_qla_host {
#define ISP_ABORT_RETRY 10 /* ISP aborted. */
#define BEACON_BLINK_NEEDED 11
#define REGISTER_FDMI_NEEDED 12
#define FCPORT_UPDATE_NEEDED 13
#define VP_DPC_NEEDED 14 /* wake up for VP dpc handling */
#define UNLOADING 15
#define NPIV_CONFIG_NEEDED 16
@ -5026,7 +5044,6 @@ typedef struct scsi_qla_host {
uint8_t n2n_port_name[WWN_SIZE];
uint16_t n2n_id;
__le16 dport_data[4];
struct list_head gpnid_list;
struct fab_scan scan;
uint8_t scm_fabric_connection_flags;
@ -5068,7 +5085,7 @@ struct qla27xx_image_status {
#define SET_AL_PA 2
#define RESET_VP_IDX 3
#define RESET_AL_PA 4
struct qla_tgt_vp_map {
struct qla_vp_map {
uint8_t idx;
scsi_qla_host_t *vha;
};

View File

@ -479,6 +479,49 @@ void qla2x00_release_all_sadb(struct scsi_qla_host *vha, struct fc_port *fcport)
spin_unlock_irqrestore(&ha->sadb_lock, flags);
}
/**
* qla_delete_n2n_sess_and_wait: search for N2N session, tear it down and
* wait for tear down to complete. In N2N topology, there is only one
* session being active in tracking the remote device.
* @vha: host adapter pointer
* return code: 0 - found the session and completed the tear down.
* 1 - timeout occurred. Caller to use link bounce to reset.
*/
static int qla_delete_n2n_sess_and_wait(scsi_qla_host_t *vha)
{
struct fc_port *fcport;
int rc = -EIO;
ulong expire = jiffies + 23 * HZ;
if (!N2N_TOPO(vha->hw))
return 0;
fcport = NULL;
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (!fcport->n2n_flag)
continue;
ql_dbg(ql_dbg_disc, fcport->vha, 0x2016,
"%s reset sess at app start \n", __func__);
qla_edif_sa_ctl_init(vha, fcport);
qlt_schedule_sess_for_deletion(fcport);
while (time_before_eq(jiffies, expire)) {
if (fcport->disc_state != DSC_DELETE_PEND) {
rc = 0;
break;
}
msleep(1);
}
set_bit(RELOGIN_NEEDED, &vha->dpc_flags);
break;
}
return rc;
}
/**
* qla_edif_app_start: application has announce its present
* @vha: host adapter pointer
@ -518,18 +561,17 @@ qla_edif_app_start(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
fcport->n2n_link_reset_cnt = 0;
if (vha->hw->flags.n2n_fw_acc_sec) {
list_for_each_entry_safe(fcport, tf, &vha->vp_fcports, list)
qla_edif_sa_ctl_init(vha, fcport);
bool link_bounce = false;
/*
* While authentication app was not running, remote device
* could still try to login with this local port. Let's
* clear the state and try again.
* reset the session, reconnect and re-authenticate.
*/
qla2x00_wait_for_sess_deletion(vha);
if (qla_delete_n2n_sess_and_wait(vha))
link_bounce = true;
/* bounce the link to get the other guy to relogin */
if (!vha->hw->flags.n2n_bigger) {
/* bounce the link to start login */
if (!vha->hw->flags.n2n_bigger || link_bounce) {
set_bit(N2N_LINK_RESET, &vha->dpc_flags);
qla2xxx_wake_dpc(vha);
}
@ -925,7 +967,9 @@ qla_edif_app_getfcinfo(scsi_qla_host_t *vha, struct bsg_job *bsg_job)
if (!(fcport->flags & FCF_FCSP_DEVICE))
continue;
tdid = app_req.remote_pid;
tdid.b.domain = app_req.remote_pid.domain;
tdid.b.area = app_req.remote_pid.area;
tdid.b.al_pa = app_req.remote_pid.al_pa;
ql_dbg(ql_dbg_edif, vha, 0x2058,
"APP request entry - portid=%06x.\n", tdid.b24);
@ -3007,26 +3051,16 @@ qla28xx_start_scsi_edif(srb_t *sp)
goto queuing_error;
}
ctx = sp->u.scmd.ct6_ctx =
mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
if (!ctx) {
ql_log(ql_log_fatal, vha, 0x3010,
"Failed to allocate ctx for cmd=%p.\n", cmd);
goto queuing_error;
}
memset(ctx, 0, sizeof(struct ct6_dsd));
ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,
GFP_ATOMIC, &ctx->fcp_cmnd_dma);
if (!ctx->fcp_cmnd) {
if (qla_get_buf(vha, sp->qpair, &sp->u.scmd.buf_dsc)) {
ql_log(ql_log_fatal, vha, 0x3011,
"Failed to allocate fcp_cmnd for cmd=%p.\n", cmd);
"Failed to allocate buf for fcp_cmnd for cmd=%p.\n", cmd);
goto queuing_error;
}
/* Initialize the DSD list and dma handle */
INIT_LIST_HEAD(&ctx->dsd_list);
ctx->dsd_use_cnt = 0;
sp->flags |= SRB_GOT_BUF;
ctx = &sp->u.scmd.ct6_ctx;
ctx->fcp_cmnd = sp->u.scmd.buf_dsc.buf;
ctx->fcp_cmnd_dma = sp->u.scmd.buf_dsc.buf_dma;
if (cmd->cmd_len > 16) {
additional_cdb_len = cmd->cmd_len - 16;
@ -3145,7 +3179,6 @@ qla28xx_start_scsi_edif(srb_t *sp)
cmd_pkt->fcp_cmnd_dseg_len = cpu_to_le16(ctx->fcp_cmnd_len);
put_unaligned_le64(ctx->fcp_cmnd_dma, &cmd_pkt->fcp_cmnd_dseg_address);
sp->flags |= SRB_FCP_CMND_DMA_VALID;
cmd_pkt->byte_count = cpu_to_le32((uint32_t)scsi_bufflen(cmd));
/* Set total data segment count. */
cmd_pkt->entry_count = (uint8_t)req_cnt;
@ -3177,15 +3210,11 @@ qla28xx_start_scsi_edif(srb_t *sp)
return QLA_SUCCESS;
queuing_error_fcp_cmnd:
dma_pool_free(ha->fcp_cmnd_dma_pool, ctx->fcp_cmnd, ctx->fcp_cmnd_dma);
queuing_error:
if (tot_dsds)
scsi_dma_unmap(cmd);
if (sp->u.scmd.ct6_ctx) {
mempool_free(sp->u.scmd.ct6_ctx, ha->ctx_mempool);
sp->u.scmd.ct6_ctx = NULL;
}
qla_put_buf(sp->qpair, &sp->u.scmd.buf_dsc);
qla_put_fw_resources(sp->qpair, &sp->iores);
spin_unlock_irqrestore(lock, flags);

View File

@ -145,4 +145,6 @@ struct enode {
(qla_ini_mode_enabled(_s->vha) && (_s->disc_state == DSC_DELETE_PEND || \
_s->disc_state == DSC_DELETED))
#define EDIF_CAP(_ha) (ql2xsecenable && IS_QLA28XX(_ha))
#endif /* __QLA_EDIF_H */

View File

@ -89,7 +89,20 @@ struct app_plogi_reply {
struct app_pinfo_req {
struct app_id app_info;
uint8_t num_ports;
port_id_t remote_pid;
struct {
#ifdef __BIG_ENDIAN
uint8_t domain;
uint8_t area;
uint8_t al_pa;
#elif defined(__LITTLE_ENDIAN)
uint8_t al_pa;
uint8_t area;
uint8_t domain;
#else
#error "__BIG_ENDIAN or __LITTLE_ENDIAN must be defined!"
#endif
uint8_t rsvd_1;
} remote_pid;
uint8_t version;
uint8_t pad[VND_CMD_PAD_SIZE];
uint8_t reserved[VND_CMD_APP_RESERVED_SIZE];

View File

@ -257,6 +257,7 @@ struct edif_sa_ctl *qla_edif_find_sa_ctl_by_index(fc_port_t *fcport,
/*
* Global Functions in qla_mid.c source file.
*/
extern void qla_update_vp_map(struct scsi_qla_host *, int);
extern struct scsi_host_template qla2xxx_driver_template;
extern struct scsi_transport_template *qla2xxx_transport_vport_template;
extern void qla2x00_timer(struct timer_list *);
@ -292,6 +293,7 @@ extern void qla2x00_alert_all_vps(struct rsp_que *, uint16_t *);
extern void qla2x00_async_event(scsi_qla_host_t *, struct rsp_que *,
uint16_t *);
extern int qla2x00_vp_abort_isp(scsi_qla_host_t *);
void qla_adjust_buf(struct scsi_qla_host *);
/*
* Global Function Prototypes in qla_iocb.c source file.
@ -721,10 +723,6 @@ 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_post_gpnid_work(struct scsi_qla_host *, port_id_t *);
extern int qla24xx_async_gpnid(scsi_qla_host_t *, port_id_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 *);
void qla24xx_handle_gpsc_event(scsi_qla_host_t *, struct event_arg *);
@ -734,9 +732,6 @@ int qla24xx_async_gffid(scsi_qla_host_t *vha, fc_port_t *fcport, bool);
int qla24xx_async_gpnft(scsi_qla_host_t *, u8, srb_t *);
void qla24xx_async_gpnft_done(scsi_qla_host_t *, srb_t *);
void qla24xx_async_gnnft_done(scsi_qla_host_t *, srb_t *);
int qla24xx_async_gnnid(scsi_qla_host_t *, fc_port_t *);
void qla24xx_handle_gnnid_event(scsi_qla_host_t *, struct event_arg *);
int qla24xx_post_gnnid_work(struct scsi_qla_host *, fc_port_t *);
int qla24xx_post_gfpnid_work(struct scsi_qla_host *, fc_port_t *);
int qla24xx_async_gfpnid(scsi_qla_host_t *, fc_port_t *);
void qla24xx_handle_gfpnid_event(scsi_qla_host_t *, struct event_arg *);
@ -962,7 +957,7 @@ 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 *);
void qlt_unknown_atio_work_fn(struct work_struct *);
void qlt_update_host_map(struct scsi_qla_host *, port_id_t);
void qla_update_host_map(struct scsi_qla_host *, port_id_t);
void qla_remove_hostmap(struct qla_hw_data *ha);
void qlt_clr_qp_table(struct scsi_qla_host *vha);
void qlt_set_mode(struct scsi_qla_host *);
@ -975,6 +970,8 @@ extern void qla_nvme_abort_set_option
(struct abort_entry_24xx *abt, srb_t *sp);
extern void qla_nvme_abort_process_comp_status
(struct abort_entry_24xx *abt, srb_t *sp);
struct scsi_qla_host *qla_find_host_by_vp_idx(struct scsi_qla_host *vha,
uint16_t vp_idx);
/* nvme.c */
void qla_nvme_unregister_remote_port(struct fc_port *fcport);
@ -1019,5 +1016,8 @@ int qla2xxx_enable_port(struct Scsi_Host *shost);
uint64_t qla2x00_get_num_tgts(scsi_qla_host_t *vha);
uint64_t qla2x00_count_set_bits(u32 num);
int qla_create_buf_pool(struct scsi_qla_host *, struct qla_qpair *);
void qla_free_buf_pool(struct qla_qpair *);
int qla_get_buf(struct scsi_qla_host *, struct qla_qpair *, struct qla_buf_dsc *);
void qla_put_buf(struct qla_qpair *, struct qla_buf_dsc *);
#endif /* _QLA_GBL_H */

View File

@ -2949,22 +2949,6 @@ int qla24xx_async_gpsc(scsi_qla_host_t *vha, fc_port_t *fcport)
return rval;
}
int qla24xx_post_gpnid_work(struct scsi_qla_host *vha, port_id_t *id)
{
struct qla_work_evt *e;
if (test_bit(UNLOADING, &vha->dpc_flags) ||
(vha->vp_idx && test_bit(VPORT_DELETE, &vha->dpc_flags)))
return 0;
e = qla2x00_alloc_work(vha, QLA_EVT_GPNID);
if (!e)
return QLA_FUNCTION_FAILED;
e->u.gpnid.id = *id;
return qla2x00_post_work(vha, e);
}
void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
{
struct srb_iocb *c = &sp->u.iocb_cmd;
@ -2997,287 +2981,6 @@ void qla24xx_sp_unmap(scsi_qla_host_t *vha, srb_t *sp)
kref_put(&sp->cmd_kref, qla2x00_sp_release);
}
void qla24xx_handle_gpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
{
fc_port_t *fcport, *conflict, *t;
u16 data[2];
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d port_id: %06x\n",
__func__, __LINE__, ea->id.b24);
if (ea->rc) {
/* cable is disconnected */
list_for_each_entry_safe(fcport, t, &vha->vp_fcports, list) {
if (fcport->d_id.b24 == ea->id.b24)
fcport->scan_state = QLA_FCPORT_SCAN;
qlt_schedule_sess_for_deletion(fcport);
}
} else {
/* cable is connected */
fcport = qla2x00_find_fcport_by_wwpn(vha, ea->port_name, 1);
if (fcport) {
list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
list) {
if ((conflict->d_id.b24 == ea->id.b24) &&
(fcport != conflict))
/*
* 2 fcports with conflict Nport ID or
* an existing fcport is having nport ID
* conflict with new fcport.
*/
conflict->scan_state = QLA_FCPORT_SCAN;
qlt_schedule_sess_for_deletion(conflict);
}
fcport->scan_needed = 0;
fcport->rscn_gen++;
fcport->scan_state = QLA_FCPORT_FOUND;
fcport->flags |= FCF_FABRIC_DEVICE;
if (fcport->login_retry == 0) {
fcport->login_retry =
vha->hw->login_retry_count;
ql_dbg(ql_dbg_disc, vha, 0xffff,
"Port login retry %8phN, lid 0x%04x cnt=%d.\n",
fcport->port_name, fcport->loop_id,
fcport->login_retry);
}
switch (fcport->disc_state) {
case DSC_LOGIN_COMPLETE:
/* recheck session is still intact. */
ql_dbg(ql_dbg_disc, vha, 0x210d,
"%s %d %8phC revalidate session with ADISC\n",
__func__, __LINE__, fcport->port_name);
data[0] = data[1] = 0;
qla2x00_post_async_adisc_work(vha, fcport,
data);
break;
case DSC_DELETED:
ql_dbg(ql_dbg_disc, vha, 0x210d,
"%s %d %8phC login\n", __func__, __LINE__,
fcport->port_name);
fcport->d_id = ea->id;
qla24xx_fcport_handle_login(vha, fcport);
break;
case DSC_DELETE_PEND:
fcport->d_id = ea->id;
break;
default:
fcport->d_id = ea->id;
break;
}
} else {
list_for_each_entry_safe(conflict, t, &vha->vp_fcports,
list) {
if (conflict->d_id.b24 == ea->id.b24) {
/* 2 fcports with conflict Nport ID or
* an existing fcport is having nport ID
* conflict with new fcport.
*/
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d %8phC DS %d\n",
__func__, __LINE__,
conflict->port_name,
conflict->disc_state);
conflict->scan_state = QLA_FCPORT_SCAN;
qlt_schedule_sess_for_deletion(conflict);
}
}
/* create new fcport */
ql_dbg(ql_dbg_disc, vha, 0x2065,
"%s %d %8phC post new sess\n",
__func__, __LINE__, ea->port_name);
qla24xx_post_newsess_work(vha, &ea->id,
ea->port_name, NULL, NULL, 0);
}
}
}
static void qla2x00_async_gpnid_sp_done(srb_t *sp, int res)
{
struct scsi_qla_host *vha = sp->vha;
struct ct_sns_req *ct_req =
(struct ct_sns_req *)sp->u.iocb_cmd.u.ctarg.req;
struct ct_sns_rsp *ct_rsp =
(struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
struct event_arg ea;
struct qla_work_evt *e;
unsigned long flags;
if (res)
ql_dbg(ql_dbg_disc, vha, 0x2066,
"Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n",
sp->name, res, sp->gen1, &ct_req->req.port_id.port_id,
ct_rsp->rsp.gpn_id.port_name);
else
ql_dbg(ql_dbg_disc, vha, 0x2066,
"Async done-%s good rscn gen %d ID %3phC. %8phC\n",
sp->name, sp->gen1, &ct_req->req.port_id.port_id,
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 = be_to_port_id(ct_req->req.port_id.port_id);
ea.rc = res;
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
list_del(&sp->elem);
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
if (res) {
if (res == QLA_FUNCTION_TIMEOUT) {
qla24xx_post_gpnid_work(sp->vha, &ea.id);
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
return;
}
} else if (sp->gen1) {
/* There was another RSCN for this Nport ID */
qla24xx_post_gpnid_work(sp->vha, &ea.id);
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
return;
}
qla24xx_handle_gpnid_event(vha, &ea);
e = qla2x00_alloc_work(vha, QLA_EVT_UNMAP);
if (!e) {
/* please ignore kernel warning. otherwise, we have mem leak. */
dma_free_coherent(&vha->hw->pdev->dev,
sp->u.iocb_cmd.u.ctarg.req_allocated_size,
sp->u.iocb_cmd.u.ctarg.req,
sp->u.iocb_cmd.u.ctarg.req_dma);
sp->u.iocb_cmd.u.ctarg.req = NULL;
dma_free_coherent(&vha->hw->pdev->dev,
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size,
sp->u.iocb_cmd.u.ctarg.rsp,
sp->u.iocb_cmd.u.ctarg.rsp_dma);
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
return;
}
e->u.iosb.sp = sp;
qla2x00_post_work(vha, e);
}
/* Get WWPN with Nport ID. */
int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
{
int rval = QLA_FUNCTION_FAILED;
struct ct_sns_req *ct_req;
srb_t *sp, *tsp;
struct ct_sns_pkt *ct_sns;
unsigned long flags;
if (!vha->flags.online)
goto done;
/* ref: INIT */
sp = qla2x00_get_sp(vha, NULL, GFP_KERNEL);
if (!sp)
goto done;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gpnid";
sp->u.iocb_cmd.u.ctarg.id = *id;
sp->gen1 = 0;
qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
qla2x00_async_gpnid_sp_done);
spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags);
list_for_each_entry(tsp, &vha->gpnid_list, elem) {
if (tsp->u.iocb_cmd.u.ctarg.id.b24 == id->b24) {
tsp->gen1++;
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
goto done;
}
}
list_add_tail(&sp->elem, &vha->gpnid_list);
spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags);
sp->u.iocb_cmd.u.ctarg.req = dma_alloc_coherent(&vha->hw->pdev->dev,
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
GFP_KERNEL);
sp->u.iocb_cmd.u.ctarg.req_allocated_size = sizeof(struct ct_sns_pkt);
if (!sp->u.iocb_cmd.u.ctarg.req) {
ql_log(ql_log_warn, vha, 0xd041,
"Failed to allocate ct_sns request.\n");
goto done_free_sp;
}
sp->u.iocb_cmd.u.ctarg.rsp = dma_alloc_coherent(&vha->hw->pdev->dev,
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.rsp_dma,
GFP_KERNEL);
sp->u.iocb_cmd.u.ctarg.rsp_allocated_size = sizeof(struct ct_sns_pkt);
if (!sp->u.iocb_cmd.u.ctarg.rsp) {
ql_log(ql_log_warn, vha, 0xd042,
"Failed to allocate ct_sns request.\n");
goto done_free_sp;
}
ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.rsp;
memset(ct_sns, 0, sizeof(*ct_sns));
ct_sns = (struct ct_sns_pkt *)sp->u.iocb_cmd.u.ctarg.req;
/* CT_IU preamble */
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 = 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;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
ql_dbg(ql_dbg_disc, vha, 0x2067,
"Async-%s hdl=%x ID %3phC.\n", sp->name,
sp->handle, &ct_req->req.port_id.port_id);
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS)
goto done_free_sp;
return rval;
done_free_sp:
spin_lock_irqsave(&vha->hw->vport_slock, flags);
list_del(&sp->elem);
spin_unlock_irqrestore(&vha->hw->vport_slock, flags);
if (sp->u.iocb_cmd.u.ctarg.req) {
dma_free_coherent(&vha->hw->pdev->dev,
sizeof(struct ct_sns_pkt),
sp->u.iocb_cmd.u.ctarg.req,
sp->u.iocb_cmd.u.ctarg.req_dma);
sp->u.iocb_cmd.u.ctarg.req = NULL;
}
if (sp->u.iocb_cmd.u.ctarg.rsp) {
dma_free_coherent(&vha->hw->pdev->dev,
sizeof(struct ct_sns_pkt),
sp->u.iocb_cmd.u.ctarg.rsp,
sp->u.iocb_cmd.u.ctarg.rsp_dma);
sp->u.iocb_cmd.u.ctarg.rsp = NULL;
}
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
done:
return rval;
}
void qla24xx_async_gffid_sp_done(srb_t *sp, int res)
{
struct scsi_qla_host *vha = sp->vha;
@ -4190,116 +3893,6 @@ void qla_scan_work_fn(struct work_struct *work)
spin_unlock_irqrestore(&vha->work_lock, flags);
}
/* GNN_ID */
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(srb_t *sp, int res)
{
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;
struct event_arg ea;
u64 wwnn;
fcport->flags &= ~FCF_ASYNC_SENT;
wwnn = wwn_to_u64(node_name);
if (wwnn)
memcpy(fcport->node_name, node_name, WWN_SIZE);
memset(&ea, 0, sizeof(ea));
ea.fcport = fcport;
ea.sp = sp;
ea.rc = res;
ql_dbg(ql_dbg_disc, vha, 0x204f,
"Async done-%s res %x, WWPN %8phC %8phC\n",
sp->name, res, fcport->port_name, fcport->node_name);
qla24xx_handle_gnnid_event(vha, &ea);
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
}
int qla24xx_async_gnnid(scsi_qla_host_t *vha, fc_port_t *fcport)
{
int rval = QLA_FUNCTION_FAILED;
struct ct_sns_req *ct_req;
srb_t *sp;
if (!vha->flags.online || (fcport->flags & FCF_ASYNC_SENT))
return rval;
qla2x00_set_fcport_disc_state(fcport, DSC_GNN_ID);
/* ref: INIT */
sp = qla2x00_get_sp(vha, fcport, GFP_ATOMIC);
if (!sp)
goto done;
fcport->flags |= FCF_ASYNC_SENT;
sp->type = SRB_CT_PTHRU_CMD;
sp->name = "gnnid";
sp->gen1 = fcport->rscn_gen;
sp->gen2 = fcport->login_gen;
qla2x00_init_async_sp(sp, qla2x00_get_async_timeout(vha) + 2,
qla2x00_async_gnnid_sp_done);
/* CT_IU preamble */
ct_req = qla2x00_prep_ct_req(fcport->ct_desc.ct_sns, GNN_ID_CMD,
GNN_ID_RSP_SIZE);
/* GNN_ID req */
ct_req->req.port_id.port_id = port_id_to_be_id(fcport->d_id);
/* req & rsp use the same buffer */
sp->u.iocb_cmd.u.ctarg.req = fcport->ct_desc.ct_sns;
sp->u.iocb_cmd.u.ctarg.req_dma = fcport->ct_desc.ct_sns_dma;
sp->u.iocb_cmd.u.ctarg.rsp = fcport->ct_desc.ct_sns;
sp->u.iocb_cmd.u.ctarg.rsp_dma = fcport->ct_desc.ct_sns_dma;
sp->u.iocb_cmd.u.ctarg.req_size = GNN_ID_REQ_SIZE;
sp->u.iocb_cmd.u.ctarg.rsp_size = GNN_ID_RSP_SIZE;
sp->u.iocb_cmd.u.ctarg.nport_handle = NPH_SNS;
ql_dbg(ql_dbg_disc, vha, 0xffff,
"Async-%s - %8phC hdl=%x loopid=%x portid %06x.\n",
sp->name, fcport->port_name,
sp->handle, fcport->loop_id, fcport->d_id.b24);
rval = qla2x00_start_sp(sp);
if (rval != QLA_SUCCESS)
goto done_free_sp;
return rval;
done_free_sp:
/* ref: INIT */
kref_put(&sp->cmd_kref, qla2x00_sp_release);
fcport->flags &= ~FCF_ASYNC_SENT;
done:
return rval;
}
int qla24xx_post_gnnid_work(struct scsi_qla_host *vha, fc_port_t *fcport)
{
struct qla_work_evt *e;
int ls;
ls = atomic_read(&vha->loop_state);
if (((ls != LOOP_READY) && (ls != LOOP_UP)) ||
test_bit(UNLOADING, &vha->dpc_flags))
return 0;
e = qla2x00_alloc_work(vha, QLA_EVT_GNNID);
if (!e)
return QLA_FUNCTION_FAILED;
e->u.fcport.fcport = fcport;
return qla2x00_post_work(vha, e);
}
/* GPFN_ID */
void qla24xx_handle_gfpnid_event(scsi_qla_host_t *vha, struct event_arg *ea)
{

View File

@ -1718,12 +1718,7 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport)
}
break;
default:
if (wwn == 0) {
ql_dbg(ql_dbg_disc, vha, 0xffff,
"%s %d %8phC post GNNID\n",
__func__, __LINE__, fcport->port_name);
qla24xx_post_gnnid_work(vha, fcport);
} else if (fcport->loop_id == FC_NO_LOOP_ID) {
if (fcport->loop_id == FC_NO_LOOP_ID) {
ql_dbg(ql_dbg_disc, vha, 0x20bd,
"%s %d %8phC post gnl\n",
__func__, __LINE__, fcport->port_name);
@ -2323,7 +2318,7 @@ qla24xx_handle_plogi_done_event(struct scsi_qla_host *vha, struct event_arg *ea)
ea->fcport->login_pause = 1;
ql_dbg(ql_dbg_disc, vha, 0x20ed,
"%s %d %8phC NPortId %06x inuse with loopid 0x%x. post gidpn\n",
"%s %d %8phC NPortId %06x inuse with loopid 0x%x.\n",
__func__, __LINE__, ea->fcport->port_name,
ea->fcport->d_id.b24, lid);
} else {
@ -4827,9 +4822,9 @@ qla2x00_configure_hba(scsi_qla_host_t *vha)
spin_lock_irqsave(&ha->hardware_lock, flags);
if (vha->hw->flags.edif_enabled) {
if (topo != 2)
qlt_update_host_map(vha, id);
qla_update_host_map(vha, id);
} else if (!(topo == 2 && ha->flags.n2n_bigger))
qlt_update_host_map(vha, id);
qla_update_host_map(vha, id);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
if (!vha->flags.init_done)
@ -5224,27 +5219,6 @@ qla2x00_nvram_config(scsi_qla_host_t *vha)
return (rval);
}
static void
qla2x00_rport_del(void *data)
{
fc_port_t *fcport = data;
struct fc_rport *rport;
unsigned long flags;
spin_lock_irqsave(fcport->vha->host->host_lock, flags);
rport = fcport->drport ? fcport->drport : fcport->rport;
fcport->drport = NULL;
spin_unlock_irqrestore(fcport->vha->host->host_lock, flags);
if (rport) {
ql_dbg(ql_dbg_disc, fcport->vha, 0x210b,
"%s %8phN. rport %p roles %x\n",
__func__, fcport->port_name, rport,
rport->roles);
fc_remote_port_delete(rport);
}
}
void qla2x00_set_fcport_state(fc_port_t *fcport, int state)
{
int old_state;
@ -6761,33 +6735,6 @@ int qla2x00_perform_loop_resync(scsi_qla_host_t *ha)
return rval;
}
void
qla2x00_update_fcports(scsi_qla_host_t *base_vha)
{
fc_port_t *fcport;
struct scsi_qla_host *vha, *tvp;
struct qla_hw_data *ha = base_vha->hw;
unsigned long flags;
spin_lock_irqsave(&ha->vport_slock, flags);
/* Go with deferred removal of rport references. */
list_for_each_entry_safe(vha, tvp, &base_vha->hw->vp_list, list) {
atomic_inc(&vha->vref_count);
list_for_each_entry(fcport, &vha->vp_fcports, list) {
if (fcport->drport &&
atomic_read(&fcport->state) != FCS_UNCONFIGURED) {
spin_unlock_irqrestore(&ha->vport_slock, flags);
qla2x00_rport_del(fcport);
spin_lock_irqsave(&ha->vport_slock, flags);
}
}
atomic_dec(&vha->vref_count);
wake_up(&vha->vref_waitq);
}
spin_unlock_irqrestore(&ha->vport_slock, flags);
}
/* Assumes idc_lock always held on entry */
void
qla83xx_reset_ownership(scsi_qla_host_t *vha)
@ -9479,8 +9426,6 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
qpair->req = ha->req_q_map[req_id];
qpair->rsp->req = qpair->req;
qpair->rsp->qpair = qpair;
/* init qpair to this cpu. Will adjust at run time. */
qla_cpu_update(qpair, raw_smp_processor_id());
if (IS_T10_PI_CAPABLE(ha) && ql2xenabledif) {
if (ha->fw_attributes & BIT_4)
@ -9495,6 +9440,13 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
goto fail_mempool;
}
if (qla_create_buf_pool(vha, qpair)) {
ql_log(ql_log_warn, vha, 0xd036,
"Failed to initialize buf pool for qpair %d\n",
qpair->id);
goto fail_bufpool;
}
/* Mark as online */
qpair->online = 1;
@ -9510,7 +9462,10 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos,
}
return qpair;
fail_bufpool:
mempool_destroy(qpair->srb_mempool);
fail_mempool:
qla25xx_delete_req_que(vha, qpair->req);
fail_req:
qla25xx_delete_rsp_que(vha, qpair->rsp);
fail_rsp:
@ -9536,6 +9491,8 @@ int qla2xxx_delete_qpair(struct scsi_qla_host *vha, struct qla_qpair *qpair)
qpair->delete_in_progress = 1;
qla_free_buf_pool(qpair);
ret = qla25xx_delete_req_que(vha, qpair->req);
if (ret != QLA_SUCCESS)
goto fail;

View File

@ -515,3 +515,58 @@ fcport_is_bigger(fc_port_t *fcport)
{
return !fcport_is_smaller(fcport);
}
static inline struct qla_qpair *
qla_mapq_nvme_select_qpair(struct qla_hw_data *ha, struct qla_qpair *qpair)
{
int cpuid = smp_processor_id();
if (qpair->cpuid != cpuid &&
ha->qp_cpu_map[cpuid]) {
qpair = ha->qp_cpu_map[cpuid];
}
return qpair;
}
static inline void
qla_mapq_init_qp_cpu_map(struct qla_hw_data *ha,
struct qla_msix_entry *msix,
struct qla_qpair *qpair)
{
const struct cpumask *mask;
unsigned int cpu;
if (!ha->qp_cpu_map)
return;
mask = pci_irq_get_affinity(ha->pdev, msix->vector_base0);
qpair->cpuid = cpumask_first(mask);
for_each_cpu(cpu, mask) {
ha->qp_cpu_map[cpu] = qpair;
}
msix->cpuid = qpair->cpuid;
}
static inline void
qla_mapq_free_qp_cpu_map(struct qla_hw_data *ha)
{
if (ha->qp_cpu_map) {
kfree(ha->qp_cpu_map);
ha->qp_cpu_map = NULL;
}
}
static inline int qla_mapq_alloc_qp_cpu_map(struct qla_hw_data *ha)
{
scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev);
if (!ha->qp_cpu_map) {
ha->qp_cpu_map = kcalloc(NR_CPUS, sizeof(struct qla_qpair *),
GFP_KERNEL);
if (!ha->qp_cpu_map) {
ql_log(ql_log_fatal, vha, 0x0180,
"Unable to allocate memory for qp_cpu_map ptrs.\n");
return -1;
}
}
return 0;
}

View File

@ -623,7 +623,7 @@ qla24xx_build_scsi_type_6_iocbs(srb_t *sp, struct cmd_type_6 *cmd_pkt,
}
cur_seg = scsi_sglist(cmd);
ctx = sp->u.scmd.ct6_ctx;
ctx = &sp->u.scmd.ct6_ctx;
while (tot_dsds) {
avail_dsds = (tot_dsds > QLA_DSDS_PER_IOCB) ?
@ -2920,7 +2920,7 @@ static void qla2x00_els_dcmd2_sp_done(srb_t *sp, int res)
conflict_fcport->conflict = fcport;
fcport->login_pause = 1;
ql_dbg(ql_dbg_disc, vha, 0x20ed,
"%s %d %8phC pid %06x inuse with lid %#x post gidpn\n",
"%s %d %8phC pid %06x inuse with lid %#x.\n",
__func__, __LINE__,
fcport->port_name,
fcport->d_id.b24, lid);
@ -3459,13 +3459,7 @@ qla82xx_start_scsi(srb_t *sp)
goto queuing_error;
}
ctx = sp->u.scmd.ct6_ctx =
mempool_alloc(ha->ctx_mempool, GFP_ATOMIC);
if (!ctx) {
ql_log(ql_log_fatal, vha, 0x3010,
"Failed to allocate ctx for cmd=%p.\n", cmd);
goto queuing_error;
}
ctx = &sp->u.scmd.ct6_ctx;
memset(ctx, 0, sizeof(struct ct6_dsd));
ctx->fcp_cmnd = dma_pool_zalloc(ha->fcp_cmnd_dma_pool,

View File

@ -3769,7 +3769,6 @@ void qla24xx_process_response_queue(struct scsi_qla_host *vha,
if (rsp->qpair->cpuid != smp_processor_id() || !rsp->qpair->rcv_intr) {
rsp->qpair->rcv_intr = 1;
qla_cpu_update(rsp->qpair, smp_processor_id());
}
#define __update_rsp_in(_is_shadow_hba, _rsp, _rsp_in) \
@ -4377,6 +4376,7 @@ qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp)
for (i = 0; i < ha->msix_count; i++) {
qentry = &ha->msix_entries[i];
qentry->vector = pci_irq_vector(ha->pdev, i);
qentry->vector_base0 = i;
qentry->entry = i;
qentry->have_irq = 0;
qentry->in_use = 0;
@ -4604,5 +4604,6 @@ int qla25xx_request_irq(struct qla_hw_data *ha, struct qla_qpair *qpair,
}
msix->have_irq = 1;
msix->handle = qpair;
qla_mapq_init_qp_cpu_map(ha, msix, qpair);
return ret;
}

View File

@ -4010,7 +4010,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
rptid_entry->port_id[2], rptid_entry->port_id[1],
rptid_entry->port_id[0]);
ha->current_topology = ISP_CFG_NL;
qlt_update_host_map(vha, id);
qla_update_host_map(vha, id);
} else if (rptid_entry->format == 1) {
/* fabric */
@ -4126,7 +4126,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
WWN_SIZE);
}
qlt_update_host_map(vha, id);
qla_update_host_map(vha, id);
}
set_bit(REGISTER_FC4_NEEDED, &vha->dpc_flags);
@ -4153,7 +4153,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
if (!found)
return;
qlt_update_host_map(vp, id);
qla_update_host_map(vp, id);
/*
* Cannot configure here as we are still sitting on the
@ -4184,7 +4184,7 @@ qla24xx_report_id_acquisition(scsi_qla_host_t *vha,
ha->flags.n2n_ae = 1;
spin_lock_irqsave(&ha->vport_slock, flags);
qlt_update_vp_map(vha, SET_AL_PA);
qla_update_vp_map(vha, SET_AL_PA);
spin_unlock_irqrestore(&ha->vport_slock, flags);
list_for_each_entry(fcport, &vha->vp_fcports, list) {

View File

@ -52,7 +52,7 @@ qla24xx_allocate_vp_id(scsi_qla_host_t *vha)
spin_unlock_irqrestore(&ha->vport_slock, flags);
spin_lock_irqsave(&ha->hardware_lock, flags);
qlt_update_vp_map(vha, SET_VP_IDX);
qla_update_vp_map(vha, SET_VP_IDX);
spin_unlock_irqrestore(&ha->hardware_lock, flags);
mutex_unlock(&ha->vport_lock);
@ -80,7 +80,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
spin_lock_irqsave(&ha->vport_slock, flags);
if (atomic_read(&vha->vref_count) == 0) {
list_del(&vha->list);
qlt_update_vp_map(vha, RESET_VP_IDX);
qla_update_vp_map(vha, RESET_VP_IDX);
bailout = 1;
}
spin_unlock_irqrestore(&ha->vport_slock, flags);
@ -95,7 +95,7 @@ qla24xx_deallocate_vp_id(scsi_qla_host_t *vha)
"vha->vref_count=%u timeout\n", vha->vref_count.counter);
spin_lock_irqsave(&ha->vport_slock, flags);
list_del(&vha->list);
qlt_update_vp_map(vha, RESET_VP_IDX);
qla_update_vp_map(vha, RESET_VP_IDX);
spin_unlock_irqrestore(&ha->vport_slock, flags);
}
@ -187,7 +187,7 @@ qla24xx_disable_vp(scsi_qla_host_t *vha)
/* Remove port id from vp target map */
spin_lock_irqsave(&vha->hw->hardware_lock, flags);
qlt_update_vp_map(vha, RESET_AL_PA);
qla_update_vp_map(vha, RESET_AL_PA);
spin_unlock_irqrestore(&vha->hw->hardware_lock, flags);
qla2x00_mark_vp_devices_dead(vha);
@ -384,15 +384,6 @@ qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
}
}
if (test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags)) {
ql_dbg(ql_dbg_dpc, vha, 0x4016,
"FCPort update scheduled.\n");
qla2x00_update_fcports(vha);
clear_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags);
ql_dbg(ql_dbg_dpc, vha, 0x4017,
"FCPort update end.\n");
}
if (test_bit(RELOGIN_NEEDED, &vha->dpc_flags) &&
!test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) &&
atomic_read(&vha->loop_state) != LOOP_DOWN) {
@ -1014,3 +1005,288 @@ int qla24xx_control_vp(scsi_qla_host_t *vha, int cmd)
kref_put(&sp->cmd_kref, qla2x00_sp_release);
return rval;
}
struct scsi_qla_host *qla_find_host_by_vp_idx(struct scsi_qla_host *vha, uint16_t vp_idx)
{
struct qla_hw_data *ha = vha->hw;
if (vha->vp_idx == vp_idx)
return vha;
BUG_ON(ha->vp_map == NULL);
if (likely(test_bit(vp_idx, ha->vp_idx_map)))
return ha->vp_map[vp_idx].vha;
return NULL;
}
/* vport_slock to be held by the caller */
void
qla_update_vp_map(struct scsi_qla_host *vha, int cmd)
{
void *slot;
u32 key;
int rc;
if (!vha->hw->vp_map)
return;
key = vha->d_id.b24;
switch (cmd) {
case SET_VP_IDX:
vha->hw->vp_map[vha->vp_idx].vha = vha;
break;
case SET_AL_PA:
slot = btree_lookup32(&vha->hw->host_map, key);
if (!slot) {
ql_dbg(ql_dbg_disc, vha, 0xf018,
"Save vha in host_map %p %06x\n", vha, key);
rc = btree_insert32(&vha->hw->host_map,
key, vha, GFP_ATOMIC);
if (rc)
ql_log(ql_log_info, vha, 0xd03e,
"Unable to insert s_id into host_map: %06x\n",
key);
return;
}
ql_dbg(ql_dbg_disc, vha, 0xf019,
"replace existing vha in host_map %p %06x\n", vha, key);
btree_update32(&vha->hw->host_map, key, vha);
break;
case RESET_VP_IDX:
vha->hw->vp_map[vha->vp_idx].vha = NULL;
break;
case RESET_AL_PA:
ql_dbg(ql_dbg_disc, vha, 0xf01a,
"clear vha in host_map %p %06x\n", vha, key);
slot = btree_lookup32(&vha->hw->host_map, key);
if (slot)
btree_remove32(&vha->hw->host_map, key);
vha->d_id.b24 = 0;
break;
}
}
void qla_update_host_map(struct scsi_qla_host *vha, port_id_t id)
{
if (!vha->d_id.b24) {
vha->d_id = id;
qla_update_vp_map(vha, SET_AL_PA);
} else if (vha->d_id.b24 != id.b24) {
qla_update_vp_map(vha, RESET_AL_PA);
vha->d_id = id;
qla_update_vp_map(vha, SET_AL_PA);
}
}
int qla_create_buf_pool(struct scsi_qla_host *vha, struct qla_qpair *qp)
{
int sz;
qp->buf_pool.num_bufs = qp->req->length;
sz = BITS_TO_LONGS(qp->req->length);
qp->buf_pool.buf_map = kcalloc(sz, sizeof(long), GFP_KERNEL);
if (!qp->buf_pool.buf_map) {
ql_log(ql_log_warn, vha, 0x0186,
"Failed to allocate buf_map(%ld).\n", sz * sizeof(unsigned long));
return -ENOMEM;
}
sz = qp->req->length * sizeof(void *);
qp->buf_pool.buf_array = kcalloc(qp->req->length, sizeof(void *), GFP_KERNEL);
if (!qp->buf_pool.buf_array) {
ql_log(ql_log_warn, vha, 0x0186,
"Failed to allocate buf_array(%d).\n", sz);
kfree(qp->buf_pool.buf_map);
return -ENOMEM;
}
sz = qp->req->length * sizeof(dma_addr_t);
qp->buf_pool.dma_array = kcalloc(qp->req->length, sizeof(dma_addr_t), GFP_KERNEL);
if (!qp->buf_pool.dma_array) {
ql_log(ql_log_warn, vha, 0x0186,
"Failed to allocate dma_array(%d).\n", sz);
kfree(qp->buf_pool.buf_map);
kfree(qp->buf_pool.buf_array);
return -ENOMEM;
}
set_bit(0, qp->buf_pool.buf_map);
return 0;
}
void qla_free_buf_pool(struct qla_qpair *qp)
{
int i;
struct qla_hw_data *ha = qp->vha->hw;
for (i = 0; i < qp->buf_pool.num_bufs; i++) {
if (qp->buf_pool.buf_array[i] && qp->buf_pool.dma_array[i])
dma_pool_free(ha->fcp_cmnd_dma_pool, qp->buf_pool.buf_array[i],
qp->buf_pool.dma_array[i]);
qp->buf_pool.buf_array[i] = NULL;
qp->buf_pool.dma_array[i] = 0;
}
kfree(qp->buf_pool.dma_array);
kfree(qp->buf_pool.buf_array);
kfree(qp->buf_pool.buf_map);
}
/* it is assume qp->qp_lock is held at this point */
int qla_get_buf(struct scsi_qla_host *vha, struct qla_qpair *qp, struct qla_buf_dsc *dsc)
{
u16 tag, i = 0;
void *buf;
dma_addr_t buf_dma;
struct qla_hw_data *ha = vha->hw;
dsc->tag = TAG_FREED;
again:
tag = find_first_zero_bit(qp->buf_pool.buf_map, qp->buf_pool.num_bufs);
if (tag >= qp->buf_pool.num_bufs) {
ql_dbg(ql_dbg_io, vha, 0x00e2,
"qp(%d) ran out of buf resource.\n", qp->id);
return -EIO;
}
if (tag == 0) {
set_bit(0, qp->buf_pool.buf_map);
i++;
if (i == 5) {
ql_dbg(ql_dbg_io, vha, 0x00e3,
"qp(%d) unable to get tag.\n", qp->id);
return -EIO;
}
goto again;
}
if (!qp->buf_pool.buf_array[tag]) {
buf = dma_pool_zalloc(ha->fcp_cmnd_dma_pool, GFP_ATOMIC, &buf_dma);
if (!buf) {
ql_log(ql_log_fatal, vha, 0x13b1,
"Failed to allocate buf.\n");
return -ENOMEM;
}
dsc->buf = qp->buf_pool.buf_array[tag] = buf;
dsc->buf_dma = qp->buf_pool.dma_array[tag] = buf_dma;
qp->buf_pool.num_alloc++;
} else {
dsc->buf = qp->buf_pool.buf_array[tag];
dsc->buf_dma = qp->buf_pool.dma_array[tag];
memset(dsc->buf, 0, FCP_CMND_DMA_POOL_SIZE);
}
qp->buf_pool.num_active++;
if (qp->buf_pool.num_active > qp->buf_pool.max_used)
qp->buf_pool.max_used = qp->buf_pool.num_active;
dsc->tag = tag;
set_bit(tag, qp->buf_pool.buf_map);
return 0;
}
void qla_trim_buf(struct qla_qpair *qp, u16 trim)
{
int i, j;
struct qla_hw_data *ha = qp->vha->hw;
if (!trim)
return;
for (i = 0; i < trim; i++) {
j = qp->buf_pool.num_alloc - 1;
if (test_bit(j, qp->buf_pool.buf_map)) {
ql_dbg(ql_dbg_io + ql_dbg_verbose, qp->vha, 0x300b,
"QP id(%d): trim active buf[%d]. Remain %d bufs\n",
qp->id, j, qp->buf_pool.num_alloc);
return;
}
if (qp->buf_pool.buf_array[j]) {
dma_pool_free(ha->fcp_cmnd_dma_pool, qp->buf_pool.buf_array[j],
qp->buf_pool.dma_array[j]);
qp->buf_pool.buf_array[j] = NULL;
qp->buf_pool.dma_array[j] = 0;
}
qp->buf_pool.num_alloc--;
if (!qp->buf_pool.num_alloc)
break;
}
ql_dbg(ql_dbg_io + ql_dbg_verbose, qp->vha, 0x3010,
"QP id(%d): trimmed %d bufs. Remain %d bufs\n",
qp->id, trim, qp->buf_pool.num_alloc);
}
void __qla_adjust_buf(struct qla_qpair *qp)
{
u32 trim;
qp->buf_pool.take_snapshot = 0;
qp->buf_pool.prev_max = qp->buf_pool.max_used;
qp->buf_pool.max_used = qp->buf_pool.num_active;
if (qp->buf_pool.prev_max > qp->buf_pool.max_used &&
qp->buf_pool.num_alloc > qp->buf_pool.max_used) {
/* down trend */
trim = qp->buf_pool.num_alloc - qp->buf_pool.max_used;
trim = (trim * 10) / 100;
trim = trim ? trim : 1;
qla_trim_buf(qp, trim);
} else if (!qp->buf_pool.prev_max && !qp->buf_pool.max_used) {
/* 2 periods of no io */
qla_trim_buf(qp, qp->buf_pool.num_alloc);
}
}
/* it is assume qp->qp_lock is held at this point */
void qla_put_buf(struct qla_qpair *qp, struct qla_buf_dsc *dsc)
{
if (dsc->tag == TAG_FREED)
return;
lockdep_assert_held(qp->qp_lock_ptr);
clear_bit(dsc->tag, qp->buf_pool.buf_map);
qp->buf_pool.num_active--;
dsc->tag = TAG_FREED;
if (qp->buf_pool.take_snapshot)
__qla_adjust_buf(qp);
}
#define EXPIRE (60 * HZ)
void qla_adjust_buf(struct scsi_qla_host *vha)
{
unsigned long flags;
int i;
struct qla_qpair *qp;
if (vha->vp_idx)
return;
if (!vha->buf_expired) {
vha->buf_expired = jiffies + EXPIRE;
return;
}
if (time_before(jiffies, vha->buf_expired))
return;
vha->buf_expired = jiffies + EXPIRE;
for (i = 0; i < vha->hw->num_qpairs; i++) {
qp = vha->hw->queue_pair_map[i];
if (!qp)
continue;
if (!qp->buf_pool.num_alloc)
continue;
if (qp->buf_pool.take_snapshot) {
/* no io has gone through in the last EXPIRE period */
spin_lock_irqsave(qp->qp_lock_ptr, flags);
__qla_adjust_buf(qp);
spin_unlock_irqrestore(qp->qp_lock_ptr, flags);
} else {
qp->buf_pool.take_snapshot = 1;
}
}
}

View File

@ -609,6 +609,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
fc_port_t *fcport;
struct srb_iocb *nvme;
struct scsi_qla_host *vha;
struct qla_hw_data *ha;
int rval;
srb_t *sp;
struct qla_qpair *qpair = hw_queue_handle;
@ -629,6 +630,7 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
return -ENODEV;
vha = fcport->vha;
ha = vha->hw;
if (test_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags))
return -EBUSY;
@ -643,6 +645,8 @@ static int qla_nvme_post_cmd(struct nvme_fc_local_port *lport,
if (fcport->nvme_flag & NVME_FLAG_RESETTING)
return -EBUSY;
qpair = qla_mapq_nvme_select_qpair(ha, qpair);
/* Alloc SRB structure */
sp = qla2xxx_get_qpair_sp(vha, qpair, fcport, GFP_ATOMIC);
if (!sp)

View File

@ -472,6 +472,11 @@ static int qla2x00_alloc_queues(struct qla_hw_data *ha, struct req_que *req,
"Unable to allocate memory for queue pair ptrs.\n");
goto fail_qpair_map;
}
if (qla_mapq_alloc_qp_cpu_map(ha) != 0) {
kfree(ha->queue_pair_map);
ha->queue_pair_map = NULL;
goto fail_qpair_map;
}
}
/*
@ -546,6 +551,7 @@ static void qla2x00_free_queues(struct qla_hw_data *ha)
ha->base_qpair = NULL;
}
qla_mapq_free_qp_cpu_map(ha);
spin_lock_irqsave(&ha->hardware_lock, flags);
for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
if (!test_bit(cnt, ha->req_qid_map))
@ -733,15 +739,17 @@ void qla2x00_sp_free_dma(srb_t *sp)
}
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx1 = sp->u.scmd.ct6_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);
list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
}
if (sp->flags & SRB_GOT_BUF)
qla_put_buf(sp->qpair, &sp->u.scmd.buf_dsc);
}
void qla2x00_sp_compl(srb_t *sp, int res)
@ -817,14 +825,13 @@ void qla2xxx_qpair_sp_free_dma(srb_t *sp)
}
if (sp->flags & SRB_FCP_CMND_DMA_VALID) {
struct ct6_dsd *ctx1 = sp->u.scmd.ct6_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);
list_splice(&ctx1->dsd_list, &ha->gbl_dsd_list);
ha->gbl_dsd_inuse -= ctx1->dsd_use_cnt;
ha->gbl_dsd_avail += ctx1->dsd_use_cnt;
mempool_free(ctx1, ha->ctx_mempool);
sp->flags &= ~SRB_FCP_CMND_DMA_VALID;
}
@ -834,6 +841,9 @@ void qla2xxx_qpair_sp_free_dma(srb_t *sp)
dma_pool_free(ha->dl_dma_pool, ctx0, ctx0->crc_ctx_dma);
sp->flags &= ~SRB_CRC_CTX_DMA_VALID;
}
if (sp->flags & SRB_GOT_BUF)
qla_put_buf(sp->qpair, &sp->u.scmd.buf_dsc);
}
void qla2xxx_qpair_sp_compl(srb_t *sp, int res)
@ -4118,10 +4128,16 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
char name[16];
int rc;
if (QLA_TGT_MODE_ENABLED() || EDIF_CAP(ha)) {
ha->vp_map = kcalloc(MAX_MULTI_ID_FABRIC, sizeof(struct qla_vp_map), GFP_KERNEL);
if (!ha->vp_map)
goto fail;
}
ha->init_cb = dma_alloc_coherent(&ha->pdev->dev, ha->init_cb_size,
&ha->init_cb_dma, GFP_KERNEL);
if (!ha->init_cb)
goto fail;
goto fail_free_vp_map;
rc = btree_init32(&ha->host_map);
if (rc)
@ -4540,6 +4556,8 @@ qla2x00_mem_alloc(struct qla_hw_data *ha, uint16_t req_len, uint16_t rsp_len,
ha->init_cb_dma);
ha->init_cb = NULL;
ha->init_cb_dma = 0;
fail_free_vp_map:
kfree(ha->vp_map);
fail:
ql_log(ql_log_fatal, NULL, 0x0030,
"Memory allocation failure.\n");
@ -4981,6 +4999,9 @@ qla2x00_mem_free(struct qla_hw_data *ha)
ha->sf_init_cb = NULL;
ha->sf_init_cb_dma = 0;
ha->loop_id_map = NULL;
kfree(ha->vp_map);
ha->vp_map = NULL;
}
struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
@ -5016,7 +5037,6 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
INIT_LIST_HEAD(&vha->plogi_ack_list);
INIT_LIST_HEAD(&vha->qp_list);
INIT_LIST_HEAD(&vha->gnl.fcports);
INIT_LIST_HEAD(&vha->gpnid_list);
INIT_WORK(&vha->iocb_work, qla2x00_iocb_work_fn);
INIT_LIST_HEAD(&vha->purex_list.head);
@ -5461,9 +5481,6 @@ qla2x00_do_work(struct scsi_qla_host *vha)
case QLA_EVT_AENFX:
qlafx00_process_aen(vha, e);
break;
case QLA_EVT_GPNID:
qla24xx_async_gpnid(vha, &e->u.gpnid.id);
break;
case QLA_EVT_UNMAP:
qla24xx_sp_unmap(vha, e->u.iosb.sp);
break;
@ -5506,9 +5523,6 @@ qla2x00_do_work(struct scsi_qla_host *vha)
case QLA_EVT_GNNFT_DONE:
qla24xx_async_gnnft_done(vha, e->u.iosb.sp);
break;
case QLA_EVT_GNNID:
qla24xx_async_gnnid(vha, e->u.fcport.fcport);
break;
case QLA_EVT_GFPNID:
qla24xx_async_gfpnid(vha, e->u.fcport.fcport);
break;
@ -7025,11 +7039,6 @@ qla2x00_do_dpc(void *data)
}
}
if (test_and_clear_bit(FCPORT_UPDATE_NEEDED,
&base_vha->dpc_flags)) {
qla2x00_update_fcports(base_vha);
}
if (IS_QLAFX00(ha))
goto loop_resync_check;
@ -7519,13 +7528,13 @@ qla2x00_timer(struct timer_list *t)
set_bit(SET_ZIO_THRESHOLD_NEEDED, &vha->dpc_flags);
start_dpc++;
}
qla_adjust_buf(vha);
/* borrowing w to signify dpc will run */
w = 0;
/* Schedule the DPC routine if needed */
if ((test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags) ||
test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags) ||
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags) ||
start_dpc ||
test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags) ||
test_bit(BEACON_BLINK_NEEDED, &vha->dpc_flags) ||
@ -7536,13 +7545,10 @@ qla2x00_timer(struct timer_list *t)
test_bit(PROCESS_PUREX_IOCB, &vha->dpc_flags))) {
ql_dbg(ql_dbg_timer, vha, 0x600b,
"isp_abort_needed=%d loop_resync_needed=%d "
"fcport_update_needed=%d start_dpc=%d "
"reset_marker_needed=%d",
"start_dpc=%d reset_marker_needed=%d",
test_bit(ISP_ABORT_NEEDED, &vha->dpc_flags),
test_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags),
test_bit(FCPORT_UPDATE_NEEDED, &vha->dpc_flags),
start_dpc,
test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags));
start_dpc, test_bit(RESET_MARKER_NEEDED, &vha->dpc_flags));
ql_dbg(ql_dbg_timer, vha, 0x600c,
"beacon_blink_needed=%d isp_unrecoverable=%d "
"fcoe_ctx_reset_needed=%d vp_dpc_needed=%d "

View File

@ -198,22 +198,6 @@ struct scsi_qla_host *qla_find_host_by_d_id(struct scsi_qla_host *vha,
return host;
}
static inline
struct scsi_qla_host *qlt_find_host_by_vp_idx(struct scsi_qla_host *vha,
uint16_t vp_idx)
{
struct qla_hw_data *ha = vha->hw;
if (vha->vp_idx == vp_idx)
return vha;
BUG_ON(ha->tgt.tgt_vp_map == NULL);
if (likely(test_bit(vp_idx, ha->vp_idx_map)))
return ha->tgt.tgt_vp_map[vp_idx].vha;
return NULL;
}
static inline void qlt_incr_num_pend_cmds(struct scsi_qla_host *vha)
{
unsigned long flags;
@ -371,7 +355,7 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
if ((entry->u.isp24.vp_index != 0xFF) &&
(entry->u.isp24.nport_handle != cpu_to_le16(0xFFFF))) {
host = qlt_find_host_by_vp_idx(vha,
host = qla_find_host_by_vp_idx(vha,
entry->u.isp24.vp_index);
if (unlikely(!host)) {
ql_dbg(ql_dbg_tgt, vha, 0xe03f,
@ -395,7 +379,7 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha,
{
struct abts_recv_from_24xx *entry =
(struct abts_recv_from_24xx *)atio;
struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha,
struct scsi_qla_host *host = qla_find_host_by_vp_idx(vha,
entry->vp_index);
unsigned long flags;
@ -438,7 +422,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
case CTIO_TYPE7:
{
struct ctio7_from_24xx *entry = (struct ctio7_from_24xx *)pkt;
struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha,
struct scsi_qla_host *host = qla_find_host_by_vp_idx(vha,
entry->vp_index);
if (unlikely(!host)) {
ql_dbg(ql_dbg_tgt, vha, 0xe041,
@ -457,7 +441,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
struct imm_ntfy_from_isp *entry =
(struct imm_ntfy_from_isp *)pkt;
host = qlt_find_host_by_vp_idx(vha, entry->u.isp24.vp_index);
host = qla_find_host_by_vp_idx(vha, entry->u.isp24.vp_index);
if (unlikely(!host)) {
ql_dbg(ql_dbg_tgt, vha, 0xe042,
"qla_target(%d): Response pkt (IMMED_NOTIFY_TYPE) "
@ -475,7 +459,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
struct nack_to_isp *entry = (struct nack_to_isp *)pkt;
if (0xFF != entry->u.isp24.vp_index) {
host = qlt_find_host_by_vp_idx(vha,
host = qla_find_host_by_vp_idx(vha,
entry->u.isp24.vp_index);
if (unlikely(!host)) {
ql_dbg(ql_dbg_tgt, vha, 0xe043,
@ -495,7 +479,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
{
struct abts_recv_from_24xx *entry =
(struct abts_recv_from_24xx *)pkt;
struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha,
struct scsi_qla_host *host = qla_find_host_by_vp_idx(vha,
entry->vp_index);
if (unlikely(!host)) {
ql_dbg(ql_dbg_tgt, vha, 0xe044,
@ -512,7 +496,7 @@ void qlt_response_pkt_all_vps(struct scsi_qla_host *vha,
{
struct abts_resp_to_24xx *entry =
(struct abts_resp_to_24xx *)pkt;
struct scsi_qla_host *host = qlt_find_host_by_vp_idx(vha,
struct scsi_qla_host *host = qla_find_host_by_vp_idx(vha,
entry->vp_index);
if (unlikely(!host)) {
ql_dbg(ql_dbg_tgt, vha, 0xe045,
@ -7145,7 +7129,7 @@ qlt_probe_one_stage1(struct scsi_qla_host *base_vha, struct qla_hw_data *ha)
qlt_clear_mode(base_vha);
qlt_update_vp_map(base_vha, SET_VP_IDX);
qla_update_vp_map(base_vha, SET_VP_IDX);
}
irqreturn_t
@ -7224,17 +7208,10 @@ qlt_mem_alloc(struct qla_hw_data *ha)
if (!QLA_TGT_MODE_ENABLED())
return 0;
ha->tgt.tgt_vp_map = kcalloc(MAX_MULTI_ID_FABRIC,
sizeof(struct qla_tgt_vp_map),
GFP_KERNEL);
if (!ha->tgt.tgt_vp_map)
return -ENOMEM;
ha->tgt.atio_ring = dma_alloc_coherent(&ha->pdev->dev,
(ha->tgt.atio_q_length + 1) * sizeof(struct atio_from_isp),
&ha->tgt.atio_dma, GFP_KERNEL);
if (!ha->tgt.atio_ring) {
kfree(ha->tgt.tgt_vp_map);
return -ENOMEM;
}
return 0;
@ -7253,70 +7230,6 @@ qlt_mem_free(struct qla_hw_data *ha)
}
ha->tgt.atio_ring = NULL;
ha->tgt.atio_dma = 0;
kfree(ha->tgt.tgt_vp_map);
ha->tgt.tgt_vp_map = NULL;
}
/* vport_slock to be held by the caller */
void
qlt_update_vp_map(struct scsi_qla_host *vha, int cmd)
{
void *slot;
u32 key;
int rc;
key = vha->d_id.b24;
switch (cmd) {
case SET_VP_IDX:
if (!QLA_TGT_MODE_ENABLED())
return;
vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = vha;
break;
case SET_AL_PA:
slot = btree_lookup32(&vha->hw->host_map, key);
if (!slot) {
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf018,
"Save vha in host_map %p %06x\n", vha, key);
rc = btree_insert32(&vha->hw->host_map,
key, vha, GFP_ATOMIC);
if (rc)
ql_log(ql_log_info, vha, 0xd03e,
"Unable to insert s_id into host_map: %06x\n",
key);
return;
}
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf019,
"replace existing vha in host_map %p %06x\n", vha, key);
btree_update32(&vha->hw->host_map, key, vha);
break;
case RESET_VP_IDX:
if (!QLA_TGT_MODE_ENABLED())
return;
vha->hw->tgt.tgt_vp_map[vha->vp_idx].vha = NULL;
break;
case RESET_AL_PA:
ql_dbg(ql_dbg_tgt_mgt, vha, 0xf01a,
"clear vha in host_map %p %06x\n", vha, key);
slot = btree_lookup32(&vha->hw->host_map, key);
if (slot)
btree_remove32(&vha->hw->host_map, key);
vha->d_id.b24 = 0;
break;
}
}
void qlt_update_host_map(struct scsi_qla_host *vha, port_id_t id)
{
if (!vha->d_id.b24) {
vha->d_id = id;
qlt_update_vp_map(vha, SET_AL_PA);
} else if (vha->d_id.b24 != id.b24) {
qlt_update_vp_map(vha, RESET_AL_PA);
vha->d_id = id;
qlt_update_vp_map(vha, SET_AL_PA);
}
}
static int __init qlt_parse_ini_mode(void)

View File

@ -1017,7 +1017,6 @@ extern void qlt_fc_port_added(struct scsi_qla_host *, fc_port_t *);
extern void qlt_fc_port_deleted(struct scsi_qla_host *, fc_port_t *, int);
extern int __init qlt_init(void);
extern void qlt_exit(void);
extern void qlt_update_vp_map(struct scsi_qla_host *, int);
extern void qlt_free_session_done(struct work_struct *);
/*
* This macro is used during early initializations when host->active_mode

View File

@ -6,9 +6,9 @@
/*
* Driver version
*/
#define QLA2XXX_VERSION "10.02.08.100-k"
#define QLA2XXX_VERSION "10.02.08.200-k"
#define QLA_DRIVER_MAJOR_VER 10
#define QLA_DRIVER_MINOR_VER 2
#define QLA_DRIVER_PATCH_VER 8
#define QLA_DRIVER_BETA_VER 100
#define QLA_DRIVER_BETA_VER 200