scsi: ibmvfc: Add cancel mad initialization helper
Add a helper routine for initializing a Cancel MAD. This will be useful for a channelized client that needs to send Cancel commands down every channel commands were sent for a particular LUN. Link: https://lore.kernel.org/r/20210114203148.246656-18-tyreld@linux.ibm.com Reviewed-by: Brian King <brking@linux.vnet.ibm.com> Signed-off-by: Tyrel Datwyler <tyreld@linux.ibm.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Родитель
b88a5d9b7f
Коммит
a61236da7f
|
@ -2379,6 +2379,45 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device,
|
|||
return SUCCESS;
|
||||
}
|
||||
|
||||
static struct ibmvfc_event *ibmvfc_init_tmf(struct ibmvfc_queue *queue,
|
||||
struct scsi_device *sdev,
|
||||
int type)
|
||||
{
|
||||
struct ibmvfc_host *vhost = shost_priv(sdev->host);
|
||||
struct scsi_target *starget = scsi_target(sdev);
|
||||
struct fc_rport *rport = starget_to_rport(starget);
|
||||
struct ibmvfc_event *evt;
|
||||
struct ibmvfc_tmf *tmf;
|
||||
|
||||
evt = ibmvfc_get_event(queue);
|
||||
ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
|
||||
|
||||
tmf = &evt->iu.tmf;
|
||||
memset(tmf, 0, sizeof(*tmf));
|
||||
if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) {
|
||||
tmf->common.version = cpu_to_be32(2);
|
||||
tmf->target_wwpn = cpu_to_be64(rport->port_name);
|
||||
} else {
|
||||
tmf->common.version = cpu_to_be32(1);
|
||||
}
|
||||
tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD);
|
||||
tmf->common.length = cpu_to_be16(sizeof(*tmf));
|
||||
tmf->scsi_id = cpu_to_be64(rport->port_id);
|
||||
int_to_scsilun(sdev->lun, &tmf->lun);
|
||||
if (!ibmvfc_check_caps(vhost, IBMVFC_CAN_SUPPRESS_ABTS))
|
||||
type &= ~IBMVFC_TMF_SUPPRESS_ABTS;
|
||||
if (vhost->state == IBMVFC_ACTIVE)
|
||||
tmf->flags = cpu_to_be32((type | IBMVFC_TMF_LUA_VALID));
|
||||
else
|
||||
tmf->flags = cpu_to_be32(((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID));
|
||||
tmf->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata);
|
||||
tmf->my_cancel_key = cpu_to_be32((unsigned long)starget->hostdata);
|
||||
|
||||
init_completion(&evt->comp);
|
||||
|
||||
return evt;
|
||||
}
|
||||
|
||||
/**
|
||||
* ibmvfc_cancel_all - Cancel all outstanding commands to the device
|
||||
* @sdev: scsi device to cancel commands
|
||||
|
@ -2393,9 +2432,6 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device,
|
|||
static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
|
||||
{
|
||||
struct ibmvfc_host *vhost = shost_priv(sdev->host);
|
||||
struct scsi_target *starget = scsi_target(sdev);
|
||||
struct fc_rport *rport = starget_to_rport(starget);
|
||||
struct ibmvfc_tmf *tmf;
|
||||
struct ibmvfc_event *evt, *found_evt;
|
||||
union ibmvfc_iu rsp;
|
||||
int rsp_rc = -EBUSY;
|
||||
|
@ -2422,32 +2458,8 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
|
|||
}
|
||||
|
||||
if (vhost->logged_in) {
|
||||
evt = ibmvfc_get_event(&vhost->crq);
|
||||
ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_MAD_FORMAT);
|
||||
|
||||
tmf = &evt->iu.tmf;
|
||||
memset(tmf, 0, sizeof(*tmf));
|
||||
if (ibmvfc_check_caps(vhost, IBMVFC_HANDLE_VF_WWPN)) {
|
||||
tmf->common.version = cpu_to_be32(2);
|
||||
tmf->target_wwpn = cpu_to_be64(rport->port_name);
|
||||
} else {
|
||||
tmf->common.version = cpu_to_be32(1);
|
||||
}
|
||||
tmf->common.opcode = cpu_to_be32(IBMVFC_TMF_MAD);
|
||||
tmf->common.length = cpu_to_be16(sizeof(*tmf));
|
||||
tmf->scsi_id = cpu_to_be64(rport->port_id);
|
||||
int_to_scsilun(sdev->lun, &tmf->lun);
|
||||
if (!ibmvfc_check_caps(vhost, IBMVFC_CAN_SUPPRESS_ABTS))
|
||||
type &= ~IBMVFC_TMF_SUPPRESS_ABTS;
|
||||
if (vhost->state == IBMVFC_ACTIVE)
|
||||
tmf->flags = cpu_to_be32((type | IBMVFC_TMF_LUA_VALID));
|
||||
else
|
||||
tmf->flags = cpu_to_be32(((type & IBMVFC_TMF_SUPPRESS_ABTS) | IBMVFC_TMF_LUA_VALID));
|
||||
tmf->cancel_key = cpu_to_be32((unsigned long)sdev->hostdata);
|
||||
tmf->my_cancel_key = cpu_to_be32((unsigned long)starget->hostdata);
|
||||
|
||||
evt = ibmvfc_init_tmf(&vhost->crq, sdev, type);
|
||||
evt->sync_iu = &rsp;
|
||||
init_completion(&evt->comp);
|
||||
rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout);
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче