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;
|
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
|
* ibmvfc_cancel_all - Cancel all outstanding commands to the device
|
||||||
* @sdev: scsi device to cancel commands
|
* @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)
|
static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
|
||||||
{
|
{
|
||||||
struct ibmvfc_host *vhost = shost_priv(sdev->host);
|
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;
|
struct ibmvfc_event *evt, *found_evt;
|
||||||
union ibmvfc_iu rsp;
|
union ibmvfc_iu rsp;
|
||||||
int rsp_rc = -EBUSY;
|
int rsp_rc = -EBUSY;
|
||||||
|
@ -2422,32 +2458,8 @@ static int ibmvfc_cancel_all(struct scsi_device *sdev, int type)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vhost->logged_in) {
|
if (vhost->logged_in) {
|
||||||
evt = ibmvfc_get_event(&vhost->crq);
|
evt = ibmvfc_init_tmf(&vhost->crq, sdev, type);
|
||||||
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->sync_iu = &rsp;
|
evt->sync_iu = &rsp;
|
||||||
init_completion(&evt->comp);
|
|
||||||
rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout);
|
rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче