1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 /* 4 * ibmvfc-nvme.c -- IBM Power Virtual Fibre Channel NVMeoF HBA driver 5 * 6 * Written By: Tyrel Datwyler <tyreld@linux.ibm.com>, IBM Corporation 7 * 8 * Copyright (C) IBM Corporation, 2026 9 */ 10 11 #include <linux/dmapool.h> 12 #include <scsi/scsi_transport_fc.h> 13 14 #include "ibmvfc-nvme.h" 15 16 static unsigned int default_timeout = IBMVFC_DEFAULT_TIMEOUT; 17 18 static void ibmvfc_nvme_localport_delete(struct nvme_fc_local_port *lport) 19 { 20 struct ibmvfc_host *vhost = lport->private; 21 22 vhost->nvme_local_port = NULL; 23 complete(&vhost->nvme_delete_done); 24 } 25 26 static void ibmvfc_nvme_remoteport_delete(struct nvme_fc_remote_port *rport) 27 { 28 struct ibmvfc_target *tgt = rport->private; 29 30 tgt->nvme_remote_port = NULL; 31 complete(&tgt->nvme_delete_done); 32 } 33 34 static int ibmvfc_nvme_create_queue(struct nvme_fc_local_port *lport, unsigned int qidx, 35 u16 qsize, void **handle) 36 { 37 struct ibmvfc_host *vhost = lport->private; 38 struct ibmvfc_nvme_qhandle *qhandle; 39 40 if (!vhost->nvme_scrqs.active_queues) 41 return -ENODEV; 42 43 qhandle = kzalloc_obj(struct ibmvfc_nvme_qhandle); 44 if (!qhandle) 45 return -ENOMEM; 46 47 qhandle->cpu_id = raw_smp_processor_id(); 48 qhandle->qidx = qidx; 49 50 /* Admin and first IO queue are both mapped to index 0 */ 51 if (qidx) 52 qhandle->index = (qidx - 1) % vhost->nvme_scrqs.active_queues; 53 else 54 qhandle->index = qidx; 55 56 qhandle->queue = &vhost->nvme_scrqs.scrqs[qhandle->index]; 57 58 *handle = qhandle; 59 return 0; 60 } 61 62 static void ibmvfc_nvme_delete_queue(struct nvme_fc_local_port *lport, unsigned int qidx, 63 void *handle) 64 { 65 kfree(handle); 66 } 67 68 static void ibmvfc_ls_req_done(struct ibmvfc_event *evt) 69 { 70 struct ibmvfc_target *tgt = evt->tgt; 71 struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru; 72 struct fcnvme_ls_rqst_w0 *ls_rqst; 73 struct fcnvme_ls_cr_assoc_acc *ls_resp; 74 u32 status = be16_to_cpu(mad->common.status); 75 int rc = 0; 76 77 ls_rqst = (struct fcnvme_ls_rqst_w0 *)evt->ls_req->rqstaddr; 78 ls_resp = (struct fcnvme_ls_cr_assoc_acc *)evt->ls_req->rspaddr; 79 80 switch (status) { 81 case IBMVFC_MAD_SUCCESS: 82 tgt_dbg(tgt, "ls_req succeeded\n"); 83 if ((ls_rqst->ls_cmd == FCNVME_LS_CREATE_ASSOCIATION) && 84 (ls_resp->hdr.w0.ls_cmd == FCNVME_LS_ACC)) { 85 tgt->assoc_id = be64_to_cpu(ls_resp->associd.association_id); 86 tgt_dbg(tgt, "assoc_id 0x%llx\n", tgt->assoc_id); 87 } 88 break; 89 case IBMVFC_MAD_DRIVER_FAILED: 90 break; 91 case IBMVFC_MAD_FAILED: 92 default: 93 tgt_info(tgt, "ls_req failed: %s (%x:%x) rc=0x%02X\n", 94 ibmvfc_get_cmd_error(be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error)), 95 be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error), status); 96 break; 97 } 98 99 if (status) 100 rc = -EIO; 101 102 evt->ls_req->done(evt->ls_req, rc); 103 104 kref_put(&tgt->kref, ibmvfc_release_tgt); 105 ibmvfc_free_event(evt); 106 } 107 108 static void ibmvfc_init_ls_req(struct ibmvfc_event *evt, struct nvmefc_ls_req *ls_req) 109 { 110 struct ibmvfc_passthru_mad *mad = &evt->iu.passthru; 111 112 memset(mad, 0, sizeof(*mad)); 113 mad->common.version = cpu_to_be32(2); 114 mad->common.opcode = cpu_to_be32(IBMVFC_NVMF_PASSTHRU); 115 mad->common.length = cpu_to_be16(sizeof(*mad) - sizeof(mad->fc_iu) - sizeof(mad->iu)); 116 mad->cmd_ioba.va = cpu_to_be64((u64)be64_to_cpu(evt->crq.ioba) + 117 offsetof(struct ibmvfc_passthru_mad, iu)); 118 mad->cmd_ioba.len = cpu_to_be32(sizeof(mad->iu)); 119 mad->iu.cmd_len = cpu_to_be32(ls_req->rqstlen); 120 mad->iu.rsp_len = cpu_to_be32(ls_req->rsplen); 121 mad->iu.cmd.va = cpu_to_be64(ls_req->rqstdma); 122 mad->iu.cmd.len = cpu_to_be32(ls_req->rqstlen); 123 mad->iu.rsp.va = cpu_to_be64(ls_req->rspdma); 124 mad->iu.rsp.len = cpu_to_be32(ls_req->rsplen); 125 } 126 127 static int ibmvfc_nvme_ls_req(struct nvme_fc_local_port *lport, 128 struct nvme_fc_remote_port *rport, 129 struct nvmefc_ls_req *ls_req) 130 { 131 struct ibmvfc_host *vhost = lport->private; 132 struct ibmvfc_target *tgt = rport->private; 133 struct ibmvfc_passthru_mad *mad; 134 struct ibmvfc_event *evt; 135 136 kref_get(&tgt->kref); 137 evt = ibmvfc_get_event(&vhost->crq); 138 if (!evt) { 139 kref_put(&tgt->kref, ibmvfc_release_tgt); 140 return -EBUSY; 141 } 142 143 ibmvfc_init_event(evt, ibmvfc_ls_req_done, IBMVFC_MAD_FORMAT); 144 evt->tgt = tgt; 145 evt->ls_req = ls_req; 146 ls_req->private = evt; 147 148 ibmvfc_init_ls_req(evt, ls_req); 149 mad = &evt->iu.passthru; 150 mad->iu.flags = cpu_to_be32(IBMVFC_FC4_LS_DSC_CTRL); 151 mad->iu.scsi_id = cpu_to_be64(tgt->scsi_id); 152 mad->iu.cancel_key = cpu_to_be32((u64)evt); 153 mad->iu.target_wwpn = cpu_to_be64(tgt->wwpn); 154 155 ibmvfc_dbg(vhost, "nvme_ls_req\n"); 156 if (ibmvfc_send_event(evt, vhost, IBMVFC_FC4_LS_PLUS_CANCEL_TIMEOUT)) { 157 kref_put(&tgt->kref, ibmvfc_release_tgt); 158 return -ENXIO; 159 } 160 161 return 0; 162 } 163 164 static void ibmvfc_sync_nvme_completion(struct ibmvfc_event *evt) 165 { 166 /* copy the response back */ 167 if (evt->sync_iu) 168 *evt->sync_iu = *evt->xfer_iu; 169 170 complete(&evt->comp); 171 } 172 173 static void ibmvfc_init_ls_abort(struct ibmvfc_event *evt, struct nvmefc_ls_req *ls_abort) 174 { 175 struct ibmvfc_tmf *tmf; 176 struct ibmvfc_event *abt_evt = ls_abort->private; 177 struct ibmvfc_target *tgt = abt_evt->tgt; 178 struct ibmvfc_host *vhost = evt->vhost; 179 180 tmf = &evt->iu.tmf; 181 memset(tmf, 0, sizeof(*tmf)); 182 tmf->common.version = cpu_to_be32(2); 183 tmf->target_wwpn = cpu_to_be64(tgt->wwpn); 184 tmf->common.opcode = cpu_to_be32(IBMVFC_NVMF_TMF_MAD); 185 tmf->common.length = cpu_to_be16(sizeof(*tmf)); 186 if (vhost->state != IBMVFC_ACTIVE) 187 if (!ibmvfc_check_caps(vhost, IBMVFC_CAN_SUPPRESS_ABTS)) 188 tmf->flags = cpu_to_be32(IBMVFC_TMF_SUPPRESS_ABTS); 189 tmf->cancel_key = cpu_to_be32((u64)abt_evt); 190 tmf->my_cancel_key = cpu_to_be32((u64)evt); 191 tmf->assoc_id = cpu_to_be64(tgt->assoc_id); 192 193 init_completion(&evt->comp); 194 } 195 196 static void ibmvfc_nvme_ls_abort(struct nvme_fc_local_port *lport, 197 struct nvme_fc_remote_port *rport, 198 struct nvmefc_ls_req *ls_abort) 199 { 200 struct ibmvfc_host *vhost = lport->private; 201 struct ibmvfc_target *tgt = rport->private; 202 struct ibmvfc_event *evt; 203 union ibmvfc_iu rsp; 204 unsigned long flags; 205 u16 status; 206 207 evt = ibmvfc_get_event(&vhost->crq); 208 if (!vhost->logged_in || !evt) 209 return; 210 211 spin_lock_irqsave(vhost->host->host_lock, flags); 212 kref_get(&tgt->kref); 213 ibmvfc_init_event(evt, ibmvfc_sync_nvme_completion, IBMVFC_MAD_FORMAT); 214 ibmvfc_init_ls_abort(evt, ls_abort); 215 evt->sync_iu = &rsp; 216 217 if (ibmvfc_send_event(evt, vhost, default_timeout)) 218 goto out; 219 220 spin_unlock_irqrestore(vhost->host->host_lock, flags); 221 222 wait_for_completion(&evt->comp); 223 status = be16_to_cpu(rsp.mad_common.status); 224 spin_lock_irqsave(vhost->host->host_lock, flags); 225 ibmvfc_free_event(evt); 226 out: 227 spin_unlock_irqrestore(vhost->host->host_lock, flags); 228 ibmvfc_dbg(vhost, "ls_abort: cancel failed with rc=%x\n", status); 229 kref_put(&tgt->kref, ibmvfc_release_tgt); 230 } 231 232 static void ibmvfc_nvme_done(struct ibmvfc_event *evt) 233 { 234 struct ibmvfc_cmd *vfc_cmd = &evt->xfer_iu->cmd; 235 struct nvmefc_fcp_req *fcp_req = evt->fcp_req; 236 struct nvme_fc_ersp_iu *ersp = (struct nvme_fc_ersp_iu *)fcp_req->rspaddr; 237 struct nvme_completion *cqe = &ersp->cqe; 238 struct nvme_command *sqe = &((struct nvme_fc_cmd_iu *)fcp_req->cmdaddr)->sqe; 239 240 ibmvfc_dbg(evt->vhost, "fc_done: (%x:%x)\n", be16_to_cpu(vfc_cmd->status), 241 be16_to_cpu(vfc_cmd->error)); 242 ibmvfc_dbg(evt->vhost, "fc_done: cmdlen: %d, rsplen %d, payload_len %d\n", 243 fcp_req->cmdlen, fcp_req->rsplen, fcp_req->payload_length); 244 245 fcp_req->status = 0; 246 if (!vfc_cmd->status) { 247 fcp_req->rcv_rsplen = NVME_FC_SIZEOF_ZEROS_RSP; 248 fcp_req->transferred_length = fcp_req->payload_length; 249 } else if (be16_to_cpu(vfc_cmd->status) & IBMVFC_FC_NVME_STATUS) { 250 fcp_req->rcv_rsplen = sizeof(struct nvme_fc_ersp_iu); 251 fcp_req->transferred_length = be32_to_cpu(ersp->xfrd_len); 252 if (be16_to_cpu(vfc_cmd->error) & IBMVFC_NVMS_VALID_NODMA_CQE) 253 cqe->command_id = sqe->common.command_id; 254 } else { 255 fcp_req->rcv_rsplen = 0; 256 fcp_req->transferred_length = 0; 257 fcp_req->status = NVME_SC_INTERNAL; 258 } 259 260 fcp_req->done(fcp_req); 261 ibmvfc_free_event(evt); 262 } 263 264 static struct ibmvfc_cmd *ibmvfc_nvme_init_vfc_cmd(struct ibmvfc_event *evt, 265 struct nvme_fc_remote_port *rport, 266 struct nvmefc_fcp_req *fcp_req) 267 { 268 struct ibmvfc_target *tgt = rport->private; 269 struct ibmvfc_cmd *vfc_cmd = &evt->iu.cmd; 270 271 memset(vfc_cmd, 0, sizeof(*vfc_cmd)); 272 273 vfc_cmd->resp.va = cpu_to_be64(fcp_req->rspdma); 274 vfc_cmd->resp.len = cpu_to_be32(fcp_req->rsplen); 275 vfc_cmd->frame_type = cpu_to_be32(IBMVFC_NVME_FCP_TYPE); 276 vfc_cmd->flags |= cpu_to_be16(IBMVFC_NVMEOF_PROTOCOL); 277 vfc_cmd->payload_len = cpu_to_be32(fcp_req->cmdlen); 278 vfc_cmd->resp_len = cpu_to_be32(fcp_req->rsplen); 279 vfc_cmd->cancel_key = cpu_to_be32((u64)evt); 280 vfc_cmd->target_wwpn = cpu_to_be64(rport->port_name); 281 vfc_cmd->tgt_scsi_id = cpu_to_be64(rport->port_id); 282 vfc_cmd->assoc_id = cpu_to_be64(tgt->assoc_id); 283 284 memcpy(&vfc_cmd->v3nvme.iu, fcp_req->cmdaddr, fcp_req->cmdlen); 285 286 return vfc_cmd; 287 } 288 289 static void ibmvfc_nvme_map_sg_list(struct nvmefc_fcp_req *fcp_req, 290 struct srp_direct_buf *md) 291 { 292 int i; 293 struct scatterlist *sg; 294 295 for_each_sg(fcp_req->first_sgl, sg, fcp_req->sg_cnt, i) { 296 md[i].va = cpu_to_be64(sg_dma_address(sg)); 297 md[i].len = cpu_to_be32(sg_dma_len(sg)); 298 md[i].key = 0; 299 } 300 } 301 302 static int ibmvfc_nvme_map_sg_data(struct nvmefc_fcp_req *fcp_req, 303 struct ibmvfc_event *evt, 304 struct ibmvfc_cmd *vfc_cmd) 305 { 306 struct srp_direct_buf *data = &vfc_cmd->ioba; 307 struct ibmvfc_host *vhost = evt->vhost; 308 309 if (!fcp_req->sg_cnt) { 310 vfc_cmd->flags |= cpu_to_be16(IBMVFC_NO_MEM_DESC); 311 return 0; 312 } 313 314 if (fcp_req->io_dir == NVMEFC_FCP_WRITE) 315 vfc_cmd->flags |= cpu_to_be16(IBMVFC_WRITE); 316 else 317 vfc_cmd->flags |= cpu_to_be16(IBMVFC_READ); 318 319 if (fcp_req->sg_cnt == 1) { 320 ibmvfc_nvme_map_sg_list(fcp_req, data); 321 return 0; 322 } 323 324 vfc_cmd->flags |= cpu_to_be16(IBMVFC_SCATTERLIST); 325 326 if (!evt->ext_list) { 327 evt->ext_list = dma_pool_alloc(vhost->sg_pool, GFP_ATOMIC, 328 &evt->ext_list_token); 329 330 if (!evt->ext_list) 331 return -ENOMEM; 332 } 333 334 ibmvfc_nvme_map_sg_list(fcp_req, evt->ext_list); 335 336 data->va = cpu_to_be64(evt->ext_list_token); 337 data->len = cpu_to_be32(fcp_req->sg_cnt * sizeof(struct srp_direct_buf)); 338 data->key = 0; 339 return 0; 340 } 341 342 static int ibmvfc_nvme_fcp_io(struct nvme_fc_local_port *lport, 343 struct nvme_fc_remote_port *rport, 344 void *hw_queue_handle, 345 struct nvmefc_fcp_req *fcp_req) 346 { 347 struct ibmvfc_host *vhost = lport->private; 348 struct ibmvfc_nvme_qhandle *qhandle = hw_queue_handle; 349 struct ibmvfc_cmd *vfc_cmd; 350 struct ibmvfc_event *evt; 351 int rc; 352 353 ibmvfc_dbg(vhost, "nvme_fcp_io\n"); 354 evt = ibmvfc_get_event(qhandle->queue); 355 if (!evt) 356 return -EBUSY; 357 358 evt->hwq = qhandle->index; 359 ibmvfc_dbg(vhost, "vfc-nvme-mq-%d\n", evt->hwq); 360 361 ibmvfc_init_event(evt, ibmvfc_nvme_done, IBMVFC_CMD_FORMAT); 362 evt->fcp_req = fcp_req; 363 fcp_req->private = evt; 364 365 vfc_cmd = ibmvfc_nvme_init_vfc_cmd(evt, rport, fcp_req); 366 367 vfc_cmd->correlation = cpu_to_be64((u64)evt); 368 369 if (likely(!(rc = ibmvfc_nvme_map_sg_data(fcp_req, evt, vfc_cmd)))) 370 return ibmvfc_send_event(evt, vhost, 0); 371 372 ibmvfc_free_event(evt); 373 374 return rc; 375 } 376 377 static void ibmvfc_init_fcp_abort(struct ibmvfc_event *evt, 378 struct nvmefc_fcp_req *abort_req) 379 { 380 struct ibmvfc_tmf *tmf; 381 struct ibmvfc_event *abt_evt = abort_req->private; 382 struct ibmvfc_target *tgt = abt_evt->tgt; 383 384 tmf = &evt->iu.tmf; 385 memset(tmf, 0, sizeof(*tmf)); 386 tmf->common.version = cpu_to_be32(2); 387 tmf->common.opcode = cpu_to_be32(IBMVFC_NVMF_TMF_MAD); 388 tmf->common.length = cpu_to_be16(sizeof(*tmf)); 389 tmf->flags = cpu_to_be32(IBMVFC_TMF_ABORT_TASK | IBMVFC_TMF_NVMF_ASSOC); 390 tmf->cancel_key = cpu_to_be32((u64)abt_evt); 391 tmf->my_cancel_key = cpu_to_be32((u64)evt); 392 tmf->target_wwpn = cpu_to_be64(tgt->wwpn); 393 tmf->assoc_id = cpu_to_be64(tgt->assoc_id); 394 tmf->task_tag = cpu_to_be64((u64)abt_evt); 395 396 init_completion(&evt->comp); 397 } 398 399 static void ibmvfc_nvme_fcp_abort(struct nvme_fc_local_port *lport, 400 struct nvme_fc_remote_port *rport, 401 void *hw_queue_handle, 402 struct nvmefc_fcp_req *abort_req) 403 { 404 struct ibmvfc_host *vhost = lport->private; 405 struct ibmvfc_target *tgt = rport->private; 406 struct ibmvfc_event *evt, *abt_evt = abort_req->private; 407 struct ibmvfc_queue *queue; 408 union ibmvfc_iu rsp; 409 unsigned long flags; 410 u16 status = 0; 411 412 if (!abt_evt) 413 return; 414 415 queue = abt_evt->queue; 416 if (!vhost->logged_in || !queue) 417 return; 418 419 evt = ibmvfc_get_event(queue); 420 if (!evt) 421 return; 422 423 spin_lock_irqsave(queue->q_lock, flags); 424 kref_get(&tgt->kref); 425 ibmvfc_init_event(evt, ibmvfc_sync_nvme_completion, IBMVFC_MAD_FORMAT); 426 ibmvfc_init_fcp_abort(evt, abort_req); 427 evt->sync_iu = &rsp; 428 429 if (ibmvfc_send_event(evt, vhost, default_timeout)) 430 goto out; 431 432 spin_unlock_irqrestore(queue->q_lock, flags); 433 434 wait_for_completion(&evt->comp); 435 status = be16_to_cpu(rsp.mad_common.status); 436 437 spin_lock_irqsave(queue->q_lock, flags); 438 ibmvfc_free_event(evt); 439 out: 440 spin_unlock_irqrestore(queue->q_lock, flags); 441 442 if (status) 443 ibmvfc_dbg(vhost, "fcp_abort: cancel failed with rc=%x\n", status); 444 445 kref_put(&tgt->kref, ibmvfc_release_tgt); 446 } 447 448 static struct nvme_fc_port_template ibmvfc_nvme_fc_transport = { 449 .localport_delete = ibmvfc_nvme_localport_delete, 450 .remoteport_delete = ibmvfc_nvme_remoteport_delete, 451 .create_queue = ibmvfc_nvme_create_queue, 452 .delete_queue = ibmvfc_nvme_delete_queue, 453 .ls_req = ibmvfc_nvme_ls_req, 454 .ls_abort = ibmvfc_nvme_ls_abort, 455 .fcp_io = ibmvfc_nvme_fcp_io, 456 .fcp_abort = ibmvfc_nvme_fcp_abort, 457 .map_queues = NULL, 458 .max_hw_queues = IBMVFC_NVME_HW_QUEUES, 459 .max_sgl_segments = 1024, 460 .max_dif_sgl_segments = 64, 461 .dma_boundary = 0xFFFFFFFF, 462 .local_priv_sz = sizeof(struct ibmvfc_host *), 463 .remote_priv_sz = sizeof(struct ibmvfc_target *), 464 .lsrqst_priv_sz = sizeof(struct ibmvfc_event *), 465 .fcprqst_priv_sz = sizeof(struct ibmvfc_event *), 466 }; 467 468 int ibmvfc_nvme_register_remoteport(struct ibmvfc_target *tgt) 469 { 470 struct ibmvfc_host *vhost = tgt->vhost; 471 struct nvme_fc_port_info pinfo; 472 int rc; 473 474 if (!IS_ENABLED(CONFIG_NVME_FC)) 475 return 0; 476 477 if (!vhost->nvme_local_port) { 478 dev_err(vhost->dev, "Attempt to register NVMe fc remoteport without valid localport\n"); 479 return -EINVAL; 480 } 481 482 memset(&pinfo, 0, sizeof(struct nvme_fc_port_info)); 483 pinfo.node_name = tgt->ids.node_name; 484 pinfo.port_name = tgt->ids.port_name; 485 pinfo.port_id = tgt->ids.port_id; 486 pinfo.port_role = FC_PORT_ROLE_NVME_TARGET; 487 488 rc = nvme_fc_register_remoteport(vhost->nvme_local_port, &pinfo, 489 &tgt->nvme_remote_port); 490 491 if (!rc) { 492 ibmvfc_log(vhost, 2, "register_remoteport: traddr=nn-0x%llx:pn-0x%llx PortID:%x\n", 493 pinfo.node_name, pinfo.port_name, pinfo.port_id); 494 tgt->nvme_remote_port->private = tgt; 495 } 496 497 return rc; 498 } 499 500 void ibmvfc_nvme_unregister_remoteport(struct ibmvfc_target *tgt) 501 { 502 struct ibmvfc_host *vhost = tgt->vhost; 503 struct nvme_fc_remote_port *rport = tgt->nvme_remote_port; 504 int rc; 505 506 if (!IS_ENABLED(CONFIG_NVME_FC)) 507 return; 508 509 if (!tgt->nvme_remote_port) 510 return; 511 512 ibmvfc_log(vhost, 2, "unregister_remoteport: traddr=nn-0x%llx:pn-0x%llx PortID:%x\n", 513 rport->node_name, rport->port_name, rport->port_id); 514 init_completion(&tgt->nvme_delete_done); 515 rc = nvme_fc_unregister_remoteport(tgt->nvme_remote_port); 516 517 if (!rc) { 518 wait_for_completion(&tgt->nvme_delete_done); 519 } 520 } 521 522 int ibmvfc_nvme_register(struct ibmvfc_host *vhost) 523 { 524 struct nvme_fc_port_info pinfo; 525 int rc; 526 527 if (!IS_ENABLED(CONFIG_NVME_FC)) 528 return 0; 529 530 pinfo.node_name = fc_host_node_name(vhost->host); 531 pinfo.port_name = fc_host_port_name(vhost->host); 532 pinfo.port_id = fc_host_port_id(vhost->host); 533 pinfo.port_role = FC_PORT_ROLE_NVME_INITIATOR; 534 pinfo.dev_loss_tmo = 0; 535 536 rc = nvme_fc_register_localport(&pinfo, &ibmvfc_nvme_fc_transport, 537 get_device(vhost->dev), 538 &vhost->nvme_local_port); 539 540 if (!rc) { 541 ibmvfc_log(vhost, 2, "register_localport: host-traddr=nn-0x%llx:pn-0x%llx on portID:%x\n", 542 pinfo.node_name, pinfo.port_name, pinfo.port_id); 543 vhost->nvme_local_port->private = vhost; 544 } else { 545 dev_err(vhost->dev, "Failed to register NVMe fc localport (%d)\n", rc); 546 put_device(vhost->dev); 547 } 548 549 return rc; 550 } 551 552 void ibmvfc_nvme_unregister(struct ibmvfc_host *vhost) 553 { 554 int rc; 555 556 if (!IS_ENABLED(CONFIG_NVME_FC)) 557 return; 558 559 if (vhost->nvme_local_port) { 560 ibmvfc_log(vhost, 2, "unregister_localport: host-traddr=nn-0x%llx:pn-0x%llx on portID:%x\n", 561 vhost->nvme_local_port->node_name, 562 vhost->nvme_local_port->port_name, 563 vhost->nvme_local_port->port_id); 564 init_completion(&vhost->nvme_delete_done); 565 rc = nvme_fc_unregister_localport(vhost->nvme_local_port); 566 if (!rc) { 567 wait_for_completion(&vhost->nvme_delete_done); 568 } else 569 dev_err(vhost->dev, "Failed to unregister NVMe fc localport (%d)\n", rc); 570 571 put_device(vhost->dev); 572 } 573 } 574