On 6/8/26 11:30 AM, Dave Marquardt via B4 Relay wrote:
> From: Dave Marquardt <[email protected]>
> 
> Add support for fabric login in order to support the asynchronous
> event queue with its own interrupt as required by NPIV specification
> to support the asynchronous sub-queue and interrupt in order to
> support full and extended FPIN messages.
> ---
>  drivers/scsi/ibmvscsi/ibmvfc.c | 94 
> ++++++++++++++++++++++++++++++++++++++++--
>  drivers/scsi/ibmvscsi/ibmvfc.h | 16 +++++++
>  2 files changed, 106 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/scsi/ibmvscsi/ibmvfc.c b/drivers/scsi/ibmvscsi/ibmvfc.c
> index 88386d7c9106..a18861808325 100644
> --- a/drivers/scsi/ibmvscsi/ibmvfc.c
> +++ b/drivers/scsi/ibmvscsi/ibmvfc.c
> @@ -5244,6 +5244,86 @@ static void ibmvfc_discover_targets(struct ibmvfc_host 
> *vhost)
>               ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
>  }
>  
> +static void ibmvfc_fabric_login_done(struct ibmvfc_event *evt)
> +{
> +     struct ibmvfc_fabric_login *rsp = &evt->xfer_iu->fabric_login;
> +     u32 mad_status = be16_to_cpu(rsp->common.status);
> +     struct ibmvfc_host *vhost = evt->vhost;
> +     int level = IBMVFC_DEFAULT_LOG_LEVEL;
> +
> +     ENTER;
> +
> +     switch (mad_status) {
> +     case IBMVFC_MAD_SUCCESS:
> +             fc_host_port_id(vhost->host) = be64_to_cpu(rsp->nport_id);
> +             ibmvfc_free_event(evt);
> +             break;
> +
> +     case IBMVFC_MAD_FAILED:
> +             if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), 
> be16_to_cpu(rsp->error)))
> +                     level += ibmvfc_retry_host_init(vhost);
> +             else
> +                     ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
> +             ibmvfc_log(vhost, level, "Fabric Login failed: %s (%x:%x)\n",
> +                        ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), 
> be16_to_cpu(rsp->error)),
> +                                             be16_to_cpu(rsp->status), 
> be16_to_cpu(rsp->error));
> +             ibmvfc_free_event(evt);
> +             LEAVE;
> +             return;
> +
> +     case IBMVFC_MAD_CRQ_ERROR:
> +             ibmvfc_retry_host_init(vhost);
> +             fallthrough;
> +
> +     case IBMVFC_MAD_DRIVER_FAILED:
> +             ibmvfc_free_event(evt);
> +             LEAVE;
> +             return;
> +
> +     default:
> +             dev_err(vhost->dev, "Invalid fabric Login response: 0x%x\n", 
> mad_status);
> +             ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
> +             ibmvfc_free_event(evt);
> +             LEAVE;
> +             return;
> +     }
> +
> +     ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
> +     wake_up(&vhost->work_wait_q);
> +
> +     LEAVE;
> +}
> +
> +static void ibmvfc_fabric_login(struct ibmvfc_host *vhost)
> +{
> +     struct ibmvfc_fabric_login *mad;
> +     struct ibmvfc_event *evt = ibmvfc_get_reserved_event(&vhost->crq);
> +     int level = IBMVFC_DEFAULT_LOG_LEVEL;
> +
> +     if (!evt) {
> +             ibmvfc_log(vhost, level, "Fabric Login failed: no available 
> events\n");
> +             ibmvfc_hard_reset_host(vhost);
> +             return;
> +     }
> +
> +     ibmvfc_init_event(evt, ibmvfc_fabric_login_done, IBMVFC_MAD_FORMAT);
> +     mad = &evt->iu.fabric_login;
> +     memset(mad, 0, sizeof(*mad));
> +     if (vhost->scsi_scrqs.protocol == IBMVFC_PROTO_SCSI)
> +             mad->common.opcode = cpu_to_be32(IBMVFC_FABRIC_LOGIN);
> +     else {
> +             ibmvfc_log(vhost, level, "Fabric Login failed: unknown 
> protocol\n");
> +             return;
> +     }

This check is pretty pedantic. Seeing as you are directly referencing the scsi
sub-crqs. The protocol field exists so we can pass the sub-crqs blindly and the
code once NVMf comes along can determine the protocol.

Also, if somehow this was ever possibly the case you would leak the event
structure. I think we can drop the check all together.

-Tyrel



Reply via email to