scsi: qla2xxx: Add ability to send PRLO
Add ability to send Implicit PRLO to flush IOs from FW back to driver. Signed-off-by: Quinn Tran <quinn.tran@cavium.com> Signed-off-by: Himanshu Madhani <himanshu.madhani@cavium.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
parent
9ecf0b0dd5
commit
11aea16ab3
@ -507,6 +507,7 @@ struct srb_iocb {
|
||||
#define SRB_NVME_LS 20
|
||||
#define SRB_PRLI_CMD 21
|
||||
#define SRB_CTRL_VP 22
|
||||
#define SRB_PRLO_CMD 23
|
||||
|
||||
enum {
|
||||
TYPE_SRB,
|
||||
@ -3140,6 +3141,8 @@ enum qla_work_type {
|
||||
QLA_EVT_GNL,
|
||||
QLA_EVT_NACK,
|
||||
QLA_EVT_RELOGIN,
|
||||
QLA_EVT_ASYNC_PRLO,
|
||||
QLA_EVT_ASYNC_PRLO_DONE,
|
||||
};
|
||||
|
||||
|
||||
|
@ -66,6 +66,7 @@ extern void qla84xx_put_chip(struct scsi_qla_host *);
|
||||
extern int qla2x00_async_login(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_async_logout(struct scsi_qla_host *, fc_port_t *);
|
||||
extern int qla2x00_async_prlo(struct scsi_qla_host *, fc_port_t *);
|
||||
extern int qla2x00_async_adisc(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_async_tm_cmd(fc_port_t *, uint32_t, uint32_t, uint32_t);
|
||||
@ -109,6 +110,13 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, u8 *,
|
||||
int qla24xx_fcport_handle_login(struct scsi_qla_host *, fc_port_t *);
|
||||
int qla24xx_detect_sfp(scsi_qla_host_t *vha);
|
||||
int qla24xx_post_gpdb_work(struct scsi_qla_host *, fc_port_t *, u8);
|
||||
void qla2x00_async_prlo_done(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_post_async_prlo_work(struct scsi_qla_host *, fc_port_t *,
|
||||
uint16_t *);
|
||||
extern int qla2x00_post_async_prlo_done_work(struct scsi_qla_host *,
|
||||
fc_port_t *, uint16_t *);
|
||||
|
||||
/*
|
||||
* Global Data in qla_os.c source file.
|
||||
*/
|
||||
|
@ -278,6 +278,65 @@ done:
|
||||
fcport->flags &= ~FCF_ASYNC_SENT;
|
||||
return rval;
|
||||
}
|
||||
|
||||
void
|
||||
qla2x00_async_prlo_done(struct scsi_qla_host *vha, fc_port_t *fcport,
|
||||
uint16_t *data)
|
||||
{
|
||||
/* Don't re-login in target mode */
|
||||
if (!fcport->tgt_session)
|
||||
qla2x00_mark_device_lost(vha, fcport, 1, 0);
|
||||
qlt_logo_completion_handler(fcport, data[0]);
|
||||
}
|
||||
|
||||
static void
|
||||
qla2x00_async_prlo_sp_done(void *s, int res)
|
||||
{
|
||||
srb_t *sp = (srb_t *)s;
|
||||
struct srb_iocb *lio = &sp->u.iocb_cmd;
|
||||
struct scsi_qla_host *vha = sp->vha;
|
||||
|
||||
if (!test_bit(UNLOADING, &vha->dpc_flags))
|
||||
qla2x00_post_async_prlo_done_work(sp->fcport->vha, sp->fcport,
|
||||
lio->u.logio.data);
|
||||
sp->free(sp);
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_async_prlo(struct scsi_qla_host *vha, fc_port_t *fcport)
|
||||
{
|
||||
srb_t *sp;
|
||||
struct srb_iocb *lio;
|
||||
int rval;
|
||||
|
||||
rval = QLA_FUNCTION_FAILED;
|
||||
sp = qla2x00_get_sp(vha, fcport, GFP_KERNEL);
|
||||
if (!sp)
|
||||
goto done;
|
||||
|
||||
sp->type = SRB_PRLO_CMD;
|
||||
sp->name = "prlo";
|
||||
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
|
||||
|
||||
lio = &sp->u.iocb_cmd;
|
||||
lio->timeout = qla2x00_async_iocb_timeout;
|
||||
sp->done = qla2x00_async_prlo_sp_done;
|
||||
rval = qla2x00_start_sp(sp);
|
||||
if (rval != QLA_SUCCESS)
|
||||
goto done_free_sp;
|
||||
|
||||
ql_dbg(ql_dbg_disc, vha, 0x2070,
|
||||
"Async-prlo - hdl=%x loop-id=%x portid=%02x%02x%02x.\n",
|
||||
sp->handle, fcport->loop_id, fcport->d_id.b.domain,
|
||||
fcport->d_id.b.area, fcport->d_id.b.al_pa);
|
||||
return rval;
|
||||
|
||||
done_free_sp:
|
||||
sp->free(sp);
|
||||
done:
|
||||
return rval;
|
||||
}
|
||||
|
||||
static
|
||||
void qla24xx_handle_adisc_event(scsi_qla_host_t *vha, struct event_arg *ea)
|
||||
{
|
||||
|
@ -3390,6 +3390,20 @@ qla25xx_ctrlvp_iocb(srb_t *sp, struct vp_ctrl_entry_24xx *vce)
|
||||
vce->vp_idx_map[map] |= 1 << pos;
|
||||
}
|
||||
|
||||
static void
|
||||
qla24xx_prlo_iocb(srb_t *sp, struct logio_entry_24xx *logio)
|
||||
{
|
||||
logio->entry_type = LOGINOUT_PORT_IOCB_TYPE;
|
||||
logio->control_flags =
|
||||
cpu_to_le16(LCF_COMMAND_PRLO|LCF_IMPL_PRLO);
|
||||
|
||||
logio->nport_handle = cpu_to_le16(sp->fcport->loop_id);
|
||||
logio->port_id[0] = sp->fcport->d_id.b.al_pa;
|
||||
logio->port_id[1] = sp->fcport->d_id.b.area;
|
||||
logio->port_id[2] = sp->fcport->d_id.b.domain;
|
||||
logio->vp_index = sp->fcport->vha->vp_idx;
|
||||
}
|
||||
|
||||
int
|
||||
qla2x00_start_sp(srb_t *sp)
|
||||
{
|
||||
@ -3471,6 +3485,9 @@ qla2x00_start_sp(srb_t *sp)
|
||||
case SRB_CTRL_VP:
|
||||
qla25xx_ctrlvp_iocb(sp, pkt);
|
||||
break;
|
||||
case SRB_PRLO_CMD:
|
||||
qla24xx_prlo_iocb(sp, pkt);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -4690,6 +4690,8 @@ qla2x00_post_async_work(logout, QLA_EVT_ASYNC_LOGOUT);
|
||||
qla2x00_post_async_work(logout_done, QLA_EVT_ASYNC_LOGOUT_DONE);
|
||||
qla2x00_post_async_work(adisc, QLA_EVT_ASYNC_ADISC);
|
||||
qla2x00_post_async_work(adisc_done, QLA_EVT_ASYNC_ADISC_DONE);
|
||||
qla2x00_post_async_work(prlo, QLA_EVT_ASYNC_PRLO);
|
||||
qla2x00_post_async_work(prlo_done, QLA_EVT_ASYNC_PRLO_DONE);
|
||||
|
||||
int
|
||||
qla2x00_post_uevent_work(struct scsi_qla_host *vha, u32 code)
|
||||
@ -4943,6 +4945,13 @@ qla2x00_do_work(struct scsi_qla_host *vha)
|
||||
case QLA_EVT_NACK:
|
||||
qla24xx_do_nack_work(vha, e);
|
||||
break;
|
||||
case QLA_EVT_ASYNC_PRLO:
|
||||
qla2x00_async_prlo(vha, e->u.logio.fcport);
|
||||
break;
|
||||
case QLA_EVT_ASYNC_PRLO_DONE:
|
||||
qla2x00_async_prlo_done(vha, e->u.logio.fcport,
|
||||
e->u.logio.data);
|
||||
break;
|
||||
}
|
||||
if (e->flags & QLA_EVT_FLAG_FREE)
|
||||
kfree(e);
|
||||
|
Loading…
Reference in New Issue
Block a user