mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-17 18:56:24 +00:00
scsi: qla2xxx: Serialize GPNID for multiple RSCN
GPNID is triggered by RSCN. For multiple RSCNs of the same affected NPORT ID, serialize the GPNID to prevent confusion. Fixes: 726b85487067d ("qla2xxx: Add framework for async fabric discovery") Cc: <stable@vger.kernel.org> # 4.10+ 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
25ad76b703
commit
2d73ac6102
@ -315,6 +315,29 @@ struct srb_cmd {
|
|||||||
/* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
|
/* To identify if a srb is of T10-CRC type. @sp => srb_t pointer */
|
||||||
#define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID)
|
#define IS_PROT_IO(sp) (sp->flags & SRB_CRC_CTX_DSD_VALID)
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 24 bit port ID type definition.
|
||||||
|
*/
|
||||||
|
typedef union {
|
||||||
|
uint32_t b24 : 24;
|
||||||
|
|
||||||
|
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;
|
||||||
|
} b;
|
||||||
|
} port_id_t;
|
||||||
|
#define INVALID_PORT_ID 0xFFFFFF
|
||||||
|
|
||||||
struct els_logo_payload {
|
struct els_logo_payload {
|
||||||
uint8_t opcode;
|
uint8_t opcode;
|
||||||
uint8_t rsvd[3];
|
uint8_t rsvd[3];
|
||||||
@ -338,6 +361,7 @@ struct ct_arg {
|
|||||||
u32 rsp_size;
|
u32 rsp_size;
|
||||||
void *req;
|
void *req;
|
||||||
void *rsp;
|
void *rsp;
|
||||||
|
port_id_t id;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -499,6 +523,7 @@ typedef struct srb {
|
|||||||
const char *name;
|
const char *name;
|
||||||
int iocbs;
|
int iocbs;
|
||||||
struct qla_qpair *qpair;
|
struct qla_qpair *qpair;
|
||||||
|
struct list_head elem;
|
||||||
u32 gen1; /* scratch */
|
u32 gen1; /* scratch */
|
||||||
u32 gen2; /* scratch */
|
u32 gen2; /* scratch */
|
||||||
union {
|
union {
|
||||||
@ -2164,28 +2189,6 @@ struct imm_ntfy_from_isp {
|
|||||||
#define REQUEST_ENTRY_SIZE (sizeof(request_t))
|
#define REQUEST_ENTRY_SIZE (sizeof(request_t))
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* 24 bit port ID type definition.
|
|
||||||
*/
|
|
||||||
typedef union {
|
|
||||||
uint32_t b24 : 24;
|
|
||||||
|
|
||||||
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;
|
|
||||||
} b;
|
|
||||||
} port_id_t;
|
|
||||||
#define INVALID_PORT_ID 0xFFFFFF
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Switch info gathering structure.
|
* Switch info gathering structure.
|
||||||
@ -4252,6 +4255,7 @@ typedef struct scsi_qla_host {
|
|||||||
uint8_t n2n_node_name[WWN_SIZE];
|
uint8_t n2n_node_name[WWN_SIZE];
|
||||||
uint8_t n2n_port_name[WWN_SIZE];
|
uint8_t n2n_port_name[WWN_SIZE];
|
||||||
uint16_t n2n_id;
|
uint16_t n2n_id;
|
||||||
|
struct list_head gpnid_list;
|
||||||
} scsi_qla_host_t;
|
} scsi_qla_host_t;
|
||||||
|
|
||||||
struct qla27xx_image_status {
|
struct qla27xx_image_status {
|
||||||
|
@ -3221,16 +3221,17 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res)
|
|||||||
(struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
|
(struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp;
|
||||||
struct event_arg ea;
|
struct event_arg ea;
|
||||||
struct qla_work_evt *e;
|
struct qla_work_evt *e;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (res)
|
if (res)
|
||||||
ql_dbg(ql_dbg_disc, vha, 0x2066,
|
ql_dbg(ql_dbg_disc, vha, 0x2066,
|
||||||
"Async done-%s fail res %x ID %3phC. %8phC\n",
|
"Async done-%s fail res %x rscn gen %d ID %3phC. %8phC\n",
|
||||||
sp->name, res, ct_req->req.port_id.port_id,
|
sp->name, res, sp->gen1, ct_req->req.port_id.port_id,
|
||||||
ct_rsp->rsp.gpn_id.port_name);
|
ct_rsp->rsp.gpn_id.port_name);
|
||||||
else
|
else
|
||||||
ql_dbg(ql_dbg_disc, vha, 0x2066,
|
ql_dbg(ql_dbg_disc, vha, 0x2066,
|
||||||
"Async done-%s good ID %3phC. %8phC\n",
|
"Async done-%s good rscn gen %d ID %3phC. %8phC\n",
|
||||||
sp->name, ct_req->req.port_id.port_id,
|
sp->name, sp->gen1, ct_req->req.port_id.port_id,
|
||||||
ct_rsp->rsp.gpn_id.port_name);
|
ct_rsp->rsp.gpn_id.port_name);
|
||||||
|
|
||||||
memset(&ea, 0, sizeof(ea));
|
memset(&ea, 0, sizeof(ea));
|
||||||
@ -3242,11 +3243,20 @@ static void qla2x00_async_gpnid_sp_done(void *s, int res)
|
|||||||
ea.rc = res;
|
ea.rc = res;
|
||||||
ea.event = FCME_GPNID_DONE;
|
ea.event = FCME_GPNID_DONE;
|
||||||
|
|
||||||
|
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) {
|
||||||
if (res == QLA_FUNCTION_TIMEOUT)
|
if (res == QLA_FUNCTION_TIMEOUT)
|
||||||
qla24xx_post_gpnid_work(sp->vha, &ea.id);
|
qla24xx_post_gpnid_work(sp->vha, &ea.id);
|
||||||
sp->free(sp);
|
sp->free(sp);
|
||||||
return;
|
return;
|
||||||
|
} else if (sp->gen1) {
|
||||||
|
/* There was anoter RSNC for this Nport ID */
|
||||||
|
qla24xx_post_gpnid_work(sp->vha, &ea.id);
|
||||||
|
sp->free(sp);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qla2x00_fcport_event_handler(vha, &ea);
|
qla2x00_fcport_event_handler(vha, &ea);
|
||||||
@ -3282,8 +3292,9 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
|
|||||||
{
|
{
|
||||||
int rval = QLA_FUNCTION_FAILED;
|
int rval = QLA_FUNCTION_FAILED;
|
||||||
struct ct_sns_req *ct_req;
|
struct ct_sns_req *ct_req;
|
||||||
srb_t *sp;
|
srb_t *sp, *tsp;
|
||||||
struct ct_sns_pkt *ct_sns;
|
struct ct_sns_pkt *ct_sns;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
if (!vha->flags.online)
|
if (!vha->flags.online)
|
||||||
goto done;
|
goto done;
|
||||||
@ -3294,8 +3305,22 @@ int qla24xx_async_gpnid(scsi_qla_host_t *vha, port_id_t *id)
|
|||||||
|
|
||||||
sp->type = SRB_CT_PTHRU_CMD;
|
sp->type = SRB_CT_PTHRU_CMD;
|
||||||
sp->name = "gpnid";
|
sp->name = "gpnid";
|
||||||
|
sp->u.iocb_cmd.u.ctarg.id = *id;
|
||||||
|
sp->gen1 = 0;
|
||||||
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
|
qla2x00_init_timer(sp, qla2x00_get_async_timeout(vha) + 2);
|
||||||
|
|
||||||
|
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);
|
||||||
|
sp->free(sp);
|
||||||
|
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,
|
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,
|
sizeof(struct ct_sns_pkt), &sp->u.iocb_cmd.u.ctarg.req_dma,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
|
@ -1574,7 +1574,7 @@ qla24xx_els_ct_entry(scsi_qla_host_t *vha, struct req_que *req,
|
|||||||
/* borrowing sts_entry_24xx.comp_status.
|
/* borrowing sts_entry_24xx.comp_status.
|
||||||
same location as ct_entry_24xx.comp_status
|
same location as ct_entry_24xx.comp_status
|
||||||
*/
|
*/
|
||||||
res = qla2x00_chk_ms_status(vha, (ms_iocb_entry_t *)pkt,
|
res = qla2x00_chk_ms_status(sp->vha, (ms_iocb_entry_t *)pkt,
|
||||||
(struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp,
|
(struct ct_sns_rsp *)sp->u.iocb_cmd.u.ctarg.rsp,
|
||||||
sp->name);
|
sp->name);
|
||||||
sp->done(sp, res);
|
sp->done(sp, res);
|
||||||
|
@ -4515,6 +4515,7 @@ struct scsi_qla_host *qla2x00_create_host(struct scsi_host_template *sht,
|
|||||||
INIT_LIST_HEAD(&vha->qp_list);
|
INIT_LIST_HEAD(&vha->qp_list);
|
||||||
INIT_LIST_HEAD(&vha->gnl.fcports);
|
INIT_LIST_HEAD(&vha->gnl.fcports);
|
||||||
INIT_LIST_HEAD(&vha->nvme_rport_list);
|
INIT_LIST_HEAD(&vha->nvme_rport_list);
|
||||||
|
INIT_LIST_HEAD(&vha->gpnid_list);
|
||||||
|
|
||||||
spin_lock_init(&vha->work_lock);
|
spin_lock_init(&vha->work_lock);
|
||||||
spin_lock_init(&vha->cmd_list_lock);
|
spin_lock_init(&vha->cmd_list_lock);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user