scsi: ibmvfc: Add cancel mad initialization helper
authorTyrel Datwyler <tyreld@linux.ibm.com>
Thu, 14 Jan 2021 20:31:44 +0000 (14:31 -0600)
committerMartin K. Petersen <martin.petersen@oracle.com>
Fri, 15 Jan 2021 03:31:04 +0000 (22:31 -0500)
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>
drivers/scsi/ibmvscsi/ibmvfc.c

index 7d9d8ac..fba2556 100644 (file)
@@ -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);
        }