forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-12 a5969cabbb4660eab42b6ef0412cbbd1200cf14d
kernel/drivers/scsi/ibmvscsi/ibmvfc.c
....@@ -1,24 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * ibmvfc.c -- driver for IBM Power Virtual Fibre Channel Adapter
34 *
45 * Written By: Brian King <brking@linux.vnet.ibm.com>, IBM Corporation
56 *
67 * Copyright (C) IBM Corporation, 2008
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
12
- *
13
- * This program is distributed in the hope that it will be useful,
14
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
15
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
- * GNU General Public License for more details.
17
- *
18
- * You should have received a copy of the GNU General Public License
19
- * along with this program; if not, write to the Free Software
20
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21
- *
228 */
239
2410 #include <linux/module.h>
....@@ -139,6 +125,7 @@
139125 { IBMVFC_FC_FAILURE, IBMVFC_VENDOR_SPECIFIC, DID_ERROR, 1, 1, "vendor specific" },
140126
141127 { IBMVFC_FC_SCSI_ERROR, 0, DID_OK, 1, 0, "SCSI error" },
128
+ { IBMVFC_FC_SCSI_ERROR, IBMVFC_COMMAND_FAILED, DID_ERROR, 0, 1, "PRLI to device failed." },
142129 };
143130
144131 static void ibmvfc_npiv_login(struct ibmvfc_host *);
....@@ -146,6 +133,8 @@
146133 static void ibmvfc_tgt_send_plogi(struct ibmvfc_target *);
147134 static void ibmvfc_tgt_query_target(struct ibmvfc_target *);
148135 static void ibmvfc_npiv_logout(struct ibmvfc_host *);
136
+static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *);
137
+static void ibmvfc_tgt_move_login(struct ibmvfc_target *);
149138
150139 static const char *unknown_error = "unknown error";
151140
....@@ -426,22 +415,59 @@
426415 * @tgt: ibmvfc target struct
427416 * @action: action to perform
428417 *
418
+ * Returns:
419
+ * 0 if action changed / non-zero if not changed
429420 **/
430
-static void ibmvfc_set_tgt_action(struct ibmvfc_target *tgt,
421
+static int ibmvfc_set_tgt_action(struct ibmvfc_target *tgt,
431422 enum ibmvfc_target_action action)
432423 {
424
+ int rc = -EINVAL;
425
+
433426 switch (tgt->action) {
434
- case IBMVFC_TGT_ACTION_DEL_RPORT:
435
- if (action == IBMVFC_TGT_ACTION_DELETED_RPORT)
427
+ case IBMVFC_TGT_ACTION_LOGOUT_RPORT:
428
+ if (action == IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT ||
429
+ action == IBMVFC_TGT_ACTION_DEL_RPORT) {
436430 tgt->action = action;
431
+ rc = 0;
432
+ }
433
+ break;
434
+ case IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT:
435
+ if (action == IBMVFC_TGT_ACTION_DEL_RPORT ||
436
+ action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
437
+ tgt->action = action;
438
+ rc = 0;
439
+ }
440
+ break;
441
+ case IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT:
442
+ if (action == IBMVFC_TGT_ACTION_LOGOUT_RPORT) {
443
+ tgt->action = action;
444
+ rc = 0;
445
+ }
446
+ break;
447
+ case IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT:
448
+ if (action == IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT) {
449
+ tgt->action = action;
450
+ rc = 0;
451
+ }
452
+ break;
453
+ case IBMVFC_TGT_ACTION_DEL_RPORT:
454
+ if (action == IBMVFC_TGT_ACTION_DELETED_RPORT) {
455
+ tgt->action = action;
456
+ rc = 0;
457
+ }
458
+ break;
437459 case IBMVFC_TGT_ACTION_DELETED_RPORT:
438460 break;
439461 default:
440
- if (action == IBMVFC_TGT_ACTION_DEL_RPORT)
441
- tgt->add_rport = 0;
442462 tgt->action = action;
463
+ rc = 0;
443464 break;
444465 }
466
+
467
+ if (action >= IBMVFC_TGT_ACTION_LOGOUT_RPORT)
468
+ tgt->add_rport = 0;
469
+
470
+ return rc;
445471 }
446472
447473 /**
....@@ -538,7 +564,8 @@
538564 **/
539565 static void ibmvfc_reinit_host(struct ibmvfc_host *vhost)
540566 {
541
- if (vhost->action == IBMVFC_HOST_ACTION_NONE) {
567
+ if (vhost->action == IBMVFC_HOST_ACTION_NONE &&
568
+ vhost->state == IBMVFC_ACTIVE) {
542569 if (!ibmvfc_set_host_state(vhost, IBMVFC_INITIALIZING)) {
543570 scsi_block_requests(vhost->host);
544571 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY);
....@@ -547,6 +574,19 @@
547574 vhost->reinit = 1;
548575
549576 wake_up(&vhost->work_wait_q);
577
+}
578
+
579
+/**
580
+ * ibmvfc_del_tgt - Schedule cleanup and removal of the target
581
+ * @tgt: ibmvfc target struct
582
+ * @job_step: job step to perform
583
+ *
584
+ **/
585
+static void ibmvfc_del_tgt(struct ibmvfc_target *tgt)
586
+{
587
+ if (!ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_RPORT))
588
+ tgt->job_step = ibmvfc_tgt_implicit_logout_and_del;
589
+ wake_up(&tgt->vhost->work_wait_q);
550590 }
551591
552592 /**
....@@ -563,7 +603,7 @@
563603 ENTER;
564604 scsi_block_requests(vhost->host);
565605 list_for_each_entry(tgt, &vhost->targets, queue)
566
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
606
+ ibmvfc_del_tgt(tgt);
567607 ibmvfc_set_host_state(vhost, state);
568608 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_DEL);
569609 vhost->events_to_log |= IBMVFC_AE_LINKDOWN;
....@@ -595,8 +635,13 @@
595635 memset(vhost->async_crq.msgs, 0, PAGE_SIZE);
596636 vhost->async_crq.cur = 0;
597637
598
- list_for_each_entry(tgt, &vhost->targets, queue)
599
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
638
+ list_for_each_entry(tgt, &vhost->targets, queue) {
639
+ if (vhost->client_migrated)
640
+ tgt->need_login = 1;
641
+ else
642
+ ibmvfc_del_tgt(tgt);
643
+ }
644
+
600645 scsi_block_requests(vhost->host);
601646 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT);
602647 vhost->job_step = ibmvfc_npiv_login;
....@@ -1321,7 +1366,7 @@
13211366 }
13221367
13231368 /**
1324
- * ibmvfc_map_sg_data - Maps dma for a scatterlist and initializes decriptor fields
1369
+ * ibmvfc_map_sg_data - Maps dma for a scatterlist and initializes descriptor fields
13251370 * @scmd: struct scsi_cmnd with the scatterlist
13261371 * @evt: ibmvfc event struct
13271372 * @vfc_cmd: vfc_cmd that contains the memory descriptor
....@@ -1494,9 +1539,9 @@
14941539 if (rsp->flags & FCP_RSP_LEN_VALID)
14951540 rsp_code = rsp->data.info.rsp_code;
14961541
1497
- scmd_printk(KERN_ERR, cmnd, "Command (%02X) failed: %s (%x:%x) "
1542
+ scmd_printk(KERN_ERR, cmnd, "Command (%02X) : %s (%x:%x) "
14981543 "flags: %x fcp_rsp: %x, resid=%d, scsi_status: %x\n",
1499
- cmnd->cmnd[0], err, vfc_cmd->status, vfc_cmd->error,
1544
+ cmnd->cmnd[0], err, be16_to_cpu(vfc_cmd->status), be16_to_cpu(vfc_cmd->error),
15001545 rsp->flags, rsp_code, scsi_get_resid(cmnd), rsp->scsi_status);
15011546 }
15021547
....@@ -1513,7 +1558,7 @@
15131558
15141559 list_for_each_entry(tgt, &vhost->targets, queue) {
15151560 if (rport == tgt->rport) {
1516
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
1561
+ ibmvfc_del_tgt(tgt);
15171562 break;
15181563 }
15191564 }
....@@ -1843,6 +1888,7 @@
18431888 port_id = (bsg_request->rqst_data.h_els.port_id[0] << 16) |
18441889 (bsg_request->rqst_data.h_els.port_id[1] << 8) |
18451890 bsg_request->rqst_data.h_els.port_id[2];
1891
+ fallthrough;
18461892 case FC_BSG_RPT_ELS:
18471893 fc_flags = IBMVFC_FC_ELS;
18481894 break;
....@@ -1851,6 +1897,7 @@
18511897 port_id = (bsg_request->rqst_data.h_ct.port_id[0] << 16) |
18521898 (bsg_request->rqst_data.h_ct.port_id[1] << 8) |
18531899 bsg_request->rqst_data.h_ct.port_id[2];
1900
+ fallthrough;
18541901 case FC_BSG_RPT_CT:
18551902 fc_flags = IBMVFC_FC_CT_IU;
18561903 break;
....@@ -2022,7 +2069,7 @@
20222069 sdev_printk(KERN_ERR, sdev, "%s reset failed: %s (%x:%x) "
20232070 "flags: %x fcp_rsp: %x, scsi_status: %x\n", desc,
20242071 ibmvfc_get_cmd_error(be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error)),
2025
- rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
2072
+ be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error), fc_rsp->flags, rsp_code,
20262073 fc_rsp->scsi_status);
20272074 rsp_rc = -EIO;
20282075 } else
....@@ -2381,7 +2428,7 @@
23812428 sdev_printk(KERN_ERR, sdev, "Abort failed: %s (%x:%x) "
23822429 "flags: %x fcp_rsp: %x, scsi_status: %x\n",
23832430 ibmvfc_get_cmd_error(be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error)),
2384
- rsp_iu.cmd.status, rsp_iu.cmd.error, fc_rsp->flags, rsp_code,
2431
+ be16_to_cpu(rsp_iu.cmd.status), be16_to_cpu(rsp_iu.cmd.error), fc_rsp->flags, rsp_code,
23852432 fc_rsp->scsi_status);
23862433 rsp_rc = -EIO;
23872434 } else
....@@ -2549,7 +2596,9 @@
25492596 struct ibmvfc_host *vhost = shost_priv(shost);
25502597 struct fc_rport *dev_rport;
25512598 struct scsi_device *sdev;
2552
- unsigned long rc;
2599
+ struct ibmvfc_target *tgt;
2600
+ unsigned long rc, flags;
2601
+ unsigned int found;
25532602
25542603 ENTER;
25552604 shost_for_each_device(sdev, shost) {
....@@ -2563,6 +2612,27 @@
25632612
25642613 if (rc == FAILED)
25652614 ibmvfc_issue_fc_host_lip(shost);
2615
+
2616
+ spin_lock_irqsave(shost->host_lock, flags);
2617
+ found = 0;
2618
+ list_for_each_entry(tgt, &vhost->targets, queue) {
2619
+ if (tgt->scsi_id == rport->port_id) {
2620
+ found++;
2621
+ break;
2622
+ }
2623
+ }
2624
+
2625
+ if (found && tgt->action == IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT) {
2626
+ /*
2627
+ * If we get here, that means we previously attempted to send
2628
+ * an implicit logout to the target but it failed, most likely
2629
+ * due to I/O being pending, so we need to send it again
2630
+ */
2631
+ ibmvfc_del_tgt(tgt);
2632
+ ibmvfc_reinit_host(vhost);
2633
+ }
2634
+
2635
+ spin_unlock_irqrestore(shost->host_lock, flags);
25662636 LEAVE;
25672637 }
25682638
....@@ -2697,7 +2767,7 @@
26972767 if (tgt->need_login && be64_to_cpu(crq->event) == IBMVFC_AE_ELS_LOGO)
26982768 tgt->logo_rcvd = 1;
26992769 if (!tgt->need_login || be64_to_cpu(crq->event) == IBMVFC_AE_ELS_PLOGI) {
2700
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
2770
+ ibmvfc_del_tgt(tgt);
27012771 ibmvfc_reinit_host(vhost);
27022772 }
27032773 }
....@@ -2755,16 +2825,21 @@
27552825 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE);
27562826 if (crq->format == IBMVFC_PARTITION_MIGRATED) {
27572827 /* We need to re-setup the interpartition connection */
2758
- dev_info(vhost->dev, "Re-enabling adapter\n");
2828
+ dev_info(vhost->dev, "Partition migrated, Re-enabling adapter\n");
27592829 vhost->client_migrated = 1;
2830
+
2831
+ scsi_block_requests(vhost->host);
27602832 ibmvfc_purge_requests(vhost, DID_REQUEUE);
2761
- ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
2833
+ ibmvfc_set_host_state(vhost, IBMVFC_LINK_DOWN);
27622834 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_REENABLE);
2763
- } else {
2764
- dev_err(vhost->dev, "Virtual adapter failed (rc=%d)\n", crq->format);
2835
+ wake_up(&vhost->work_wait_q);
2836
+ } else if (crq->format == IBMVFC_PARTNER_FAILED || crq->format == IBMVFC_PARTNER_DEREGISTER) {
2837
+ dev_err(vhost->dev, "Host partner adapter deregistered or failed (rc=%d)\n", crq->format);
27652838 ibmvfc_purge_requests(vhost, DID_ERROR);
27662839 ibmvfc_link_down(vhost, IBMVFC_LINK_DOWN);
27672840 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_RESET);
2841
+ } else {
2842
+ dev_err(vhost->dev, "Received unknown transport event from partner (rc=%d)\n", crq->format);
27682843 }
27692844 return;
27702845 case IBMVFC_CRQ_CMD_RSP:
....@@ -3102,7 +3177,6 @@
31023177 .this_id = -1,
31033178 .sg_tablesize = SG_ALL,
31043179 .max_sectors = IBMVFC_MAX_SECTORS,
3105
- .use_clustering = ENABLE_CLUSTERING,
31063180 .shost_attrs = ibmvfc_attrs,
31073181 .track_queue_depth = 1,
31083182 };
....@@ -3232,8 +3306,8 @@
32323306 static void ibmvfc_init_tgt(struct ibmvfc_target *tgt,
32333307 void (*job_step) (struct ibmvfc_target *))
32343308 {
3235
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT);
3236
- tgt->job_step = job_step;
3309
+ if (!ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT))
3310
+ tgt->job_step = job_step;
32373311 wake_up(&tgt->vhost->work_wait_q);
32383312 }
32393313
....@@ -3249,7 +3323,7 @@
32493323 void (*job_step) (struct ibmvfc_target *))
32503324 {
32513325 if (++tgt->init_retries > IBMVFC_MAX_TGT_INIT_RETRIES) {
3252
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3326
+ ibmvfc_del_tgt(tgt);
32533327 wake_up(&tgt->vhost->work_wait_q);
32543328 return 0;
32553329 } else
....@@ -3324,13 +3398,13 @@
33243398 tgt->ids.roles |= FC_PORT_ROLE_FCP_INITIATOR;
33253399 tgt->add_rport = 1;
33263400 } else
3327
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3401
+ ibmvfc_del_tgt(tgt);
33283402 } else if (prli_rsp[index].retry)
33293403 ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
33303404 else
3331
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3405
+ ibmvfc_del_tgt(tgt);
33323406 } else
3333
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3407
+ ibmvfc_del_tgt(tgt);
33343408 break;
33353409 case IBMVFC_MAD_DRIVER_FAILED:
33363410 break;
....@@ -3347,11 +3421,11 @@
33473421 else if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)))
33483422 level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_prli);
33493423 else
3350
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3424
+ ibmvfc_del_tgt(tgt);
33513425
33523426 tgt_log(tgt, level, "Process Login failed: %s (%x:%x) rc=0x%02X\n",
33533427 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3354
- rsp->status, rsp->error, status);
3428
+ be16_to_cpu(rsp->status), be16_to_cpu(rsp->error), status);
33553429 break;
33563430 }
33573431
....@@ -3446,12 +3520,13 @@
34463520 if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)))
34473521 level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_send_plogi);
34483522 else
3449
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3523
+ ibmvfc_del_tgt(tgt);
34503524
34513525 tgt_log(tgt, level, "Port Login failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
3452
- ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)), rsp->status, rsp->error,
3453
- ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), rsp->fc_type,
3454
- ibmvfc_get_ls_explain(be16_to_cpu(rsp->fc_explain)), rsp->fc_explain, status);
3526
+ ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3527
+ be16_to_cpu(rsp->status), be16_to_cpu(rsp->error),
3528
+ ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), be16_to_cpu(rsp->fc_type),
3529
+ ibmvfc_get_ls_explain(be16_to_cpu(rsp->fc_explain)), be16_to_cpu(rsp->fc_explain), status);
34553530 break;
34563531 }
34573532
....@@ -3526,13 +3601,36 @@
35263601 break;
35273602 }
35283603
3529
- if (vhost->action == IBMVFC_HOST_ACTION_TGT_INIT)
3530
- ibmvfc_init_tgt(tgt, ibmvfc_tgt_send_plogi);
3531
- else if (vhost->action == IBMVFC_HOST_ACTION_QUERY_TGTS &&
3532
- tgt->scsi_id != tgt->new_scsi_id)
3533
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3604
+ ibmvfc_init_tgt(tgt, ibmvfc_tgt_send_plogi);
35343605 kref_put(&tgt->kref, ibmvfc_release_tgt);
35353606 wake_up(&vhost->work_wait_q);
3607
+}
3608
+
3609
+/**
3610
+ * __ibmvfc_tgt_get_implicit_logout_evt - Allocate and init an event for implicit logout
3611
+ * @tgt: ibmvfc target struct
3612
+ *
3613
+ * Returns:
3614
+ * Allocated and initialized ibmvfc_event struct
3615
+ **/
3616
+static struct ibmvfc_event *__ibmvfc_tgt_get_implicit_logout_evt(struct ibmvfc_target *tgt,
3617
+ void (*done) (struct ibmvfc_event *))
3618
+{
3619
+ struct ibmvfc_implicit_logout *mad;
3620
+ struct ibmvfc_host *vhost = tgt->vhost;
3621
+ struct ibmvfc_event *evt;
3622
+
3623
+ kref_get(&tgt->kref);
3624
+ evt = ibmvfc_get_event(vhost);
3625
+ ibmvfc_init_event(evt, done, IBMVFC_MAD_FORMAT);
3626
+ evt->tgt = tgt;
3627
+ mad = &evt->iu.implicit_logout;
3628
+ memset(mad, 0, sizeof(*mad));
3629
+ mad->common.version = cpu_to_be32(1);
3630
+ mad->common.opcode = cpu_to_be32(IBMVFC_IMPLICIT_LOGOUT);
3631
+ mad->common.length = cpu_to_be16(sizeof(*mad));
3632
+ mad->old_scsi_id = cpu_to_be64(tgt->scsi_id);
3633
+ return evt;
35363634 }
35373635
35383636 /**
....@@ -3542,24 +3640,15 @@
35423640 **/
35433641 static void ibmvfc_tgt_implicit_logout(struct ibmvfc_target *tgt)
35443642 {
3545
- struct ibmvfc_implicit_logout *mad;
35463643 struct ibmvfc_host *vhost = tgt->vhost;
35473644 struct ibmvfc_event *evt;
35483645
35493646 if (vhost->discovery_threads >= disc_threads)
35503647 return;
35513648
3552
- kref_get(&tgt->kref);
3553
- evt = ibmvfc_get_event(vhost);
35543649 vhost->discovery_threads++;
3555
- ibmvfc_init_event(evt, ibmvfc_tgt_implicit_logout_done, IBMVFC_MAD_FORMAT);
3556
- evt->tgt = tgt;
3557
- mad = &evt->iu.implicit_logout;
3558
- memset(mad, 0, sizeof(*mad));
3559
- mad->common.version = cpu_to_be32(1);
3560
- mad->common.opcode = cpu_to_be32(IBMVFC_IMPLICIT_LOGOUT);
3561
- mad->common.length = cpu_to_be16(sizeof(*mad));
3562
- mad->old_scsi_id = cpu_to_be64(tgt->scsi_id);
3650
+ evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt,
3651
+ ibmvfc_tgt_implicit_logout_done);
35633652
35643653 ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
35653654 if (ibmvfc_send_event(evt, vhost, default_timeout)) {
....@@ -3568,6 +3657,157 @@
35683657 kref_put(&tgt->kref, ibmvfc_release_tgt);
35693658 } else
35703659 tgt_dbg(tgt, "Sent Implicit Logout\n");
3660
+}
3661
+
3662
+/**
3663
+ * ibmvfc_tgt_implicit_logout_and_del_done - Completion handler for Implicit Logout MAD
3664
+ * @evt: ibmvfc event struct
3665
+ *
3666
+ **/
3667
+static void ibmvfc_tgt_implicit_logout_and_del_done(struct ibmvfc_event *evt)
3668
+{
3669
+ struct ibmvfc_target *tgt = evt->tgt;
3670
+ struct ibmvfc_host *vhost = evt->vhost;
3671
+ struct ibmvfc_passthru_mad *mad = &evt->xfer_iu->passthru;
3672
+ u32 status = be16_to_cpu(mad->common.status);
3673
+
3674
+ vhost->discovery_threads--;
3675
+ ibmvfc_free_event(evt);
3676
+
3677
+ /*
3678
+ * If our state is IBMVFC_HOST_OFFLINE, we could be unloading the
3679
+ * driver in which case we need to free up all the targets. If we are
3680
+ * not unloading, we will still go through a hard reset to get out of
3681
+ * offline state, so there is no need to track the old targets in that
3682
+ * case.
3683
+ */
3684
+ if (status == IBMVFC_MAD_SUCCESS || vhost->state == IBMVFC_HOST_OFFLINE)
3685
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3686
+ else
3687
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT);
3688
+
3689
+ tgt_dbg(tgt, "Implicit Logout %s\n", (status == IBMVFC_MAD_SUCCESS) ? "succeeded" : "failed");
3690
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
3691
+ wake_up(&vhost->work_wait_q);
3692
+}
3693
+
3694
+/**
3695
+ * ibmvfc_tgt_implicit_logout_and_del - Initiate an Implicit Logout for specified target
3696
+ * @tgt: ibmvfc target struct
3697
+ *
3698
+ **/
3699
+static void ibmvfc_tgt_implicit_logout_and_del(struct ibmvfc_target *tgt)
3700
+{
3701
+ struct ibmvfc_host *vhost = tgt->vhost;
3702
+ struct ibmvfc_event *evt;
3703
+
3704
+ if (!vhost->logged_in) {
3705
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3706
+ return;
3707
+ }
3708
+
3709
+ if (vhost->discovery_threads >= disc_threads)
3710
+ return;
3711
+
3712
+ vhost->discovery_threads++;
3713
+ evt = __ibmvfc_tgt_get_implicit_logout_evt(tgt,
3714
+ ibmvfc_tgt_implicit_logout_and_del_done);
3715
+
3716
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT);
3717
+ if (ibmvfc_send_event(evt, vhost, default_timeout)) {
3718
+ vhost->discovery_threads--;
3719
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3720
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
3721
+ } else
3722
+ tgt_dbg(tgt, "Sent Implicit Logout\n");
3723
+}
3724
+
3725
+/**
3726
+ * ibmvfc_tgt_move_login_done - Completion handler for Move Login
3727
+ * @evt: ibmvfc event struct
3728
+ *
3729
+ **/
3730
+static void ibmvfc_tgt_move_login_done(struct ibmvfc_event *evt)
3731
+{
3732
+ struct ibmvfc_target *tgt = evt->tgt;
3733
+ struct ibmvfc_host *vhost = evt->vhost;
3734
+ struct ibmvfc_move_login *rsp = &evt->xfer_iu->move_login;
3735
+ u32 status = be16_to_cpu(rsp->common.status);
3736
+ int level = IBMVFC_DEFAULT_LOG_LEVEL;
3737
+
3738
+ vhost->discovery_threads--;
3739
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_NONE);
3740
+ switch (status) {
3741
+ case IBMVFC_MAD_SUCCESS:
3742
+ tgt_dbg(tgt, "Move Login succeeded for old scsi_id: %llX\n", tgt->old_scsi_id);
3743
+ tgt->ids.node_name = wwn_to_u64(rsp->service_parms.node_name);
3744
+ tgt->ids.port_name = wwn_to_u64(rsp->service_parms.port_name);
3745
+ tgt->ids.port_id = tgt->scsi_id;
3746
+ memcpy(&tgt->service_parms, &rsp->service_parms,
3747
+ sizeof(tgt->service_parms));
3748
+ memcpy(&tgt->service_parms_change, &rsp->service_parms_change,
3749
+ sizeof(tgt->service_parms_change));
3750
+ ibmvfc_init_tgt(tgt, ibmvfc_tgt_send_prli);
3751
+ break;
3752
+ case IBMVFC_MAD_DRIVER_FAILED:
3753
+ break;
3754
+ case IBMVFC_MAD_CRQ_ERROR:
3755
+ ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_move_login);
3756
+ break;
3757
+ case IBMVFC_MAD_FAILED:
3758
+ default:
3759
+ level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_move_login);
3760
+
3761
+ tgt_log(tgt, level,
3762
+ "Move Login failed: old scsi_id: %llX, flags:%x, vios_flags:%x, rc=0x%02X\n",
3763
+ tgt->old_scsi_id, be32_to_cpu(rsp->flags), be16_to_cpu(rsp->vios_flags),
3764
+ status);
3765
+ break;
3766
+ }
3767
+
3768
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
3769
+ ibmvfc_free_event(evt);
3770
+ wake_up(&vhost->work_wait_q);
3771
+}
3772
+
3773
+
3774
+/**
3775
+ * ibmvfc_tgt_move_login - Initiate a move login for specified target
3776
+ * @tgt: ibmvfc target struct
3777
+ *
3778
+ **/
3779
+static void ibmvfc_tgt_move_login(struct ibmvfc_target *tgt)
3780
+{
3781
+ struct ibmvfc_host *vhost = tgt->vhost;
3782
+ struct ibmvfc_move_login *move;
3783
+ struct ibmvfc_event *evt;
3784
+
3785
+ if (vhost->discovery_threads >= disc_threads)
3786
+ return;
3787
+
3788
+ kref_get(&tgt->kref);
3789
+ evt = ibmvfc_get_event(vhost);
3790
+ vhost->discovery_threads++;
3791
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_INIT_WAIT);
3792
+ ibmvfc_init_event(evt, ibmvfc_tgt_move_login_done, IBMVFC_MAD_FORMAT);
3793
+ evt->tgt = tgt;
3794
+ move = &evt->iu.move_login;
3795
+ memset(move, 0, sizeof(*move));
3796
+ move->common.version = cpu_to_be32(1);
3797
+ move->common.opcode = cpu_to_be32(IBMVFC_MOVE_LOGIN);
3798
+ move->common.length = cpu_to_be16(sizeof(*move));
3799
+
3800
+ move->old_scsi_id = cpu_to_be64(tgt->old_scsi_id);
3801
+ move->new_scsi_id = cpu_to_be64(tgt->scsi_id);
3802
+ move->wwpn = cpu_to_be64(tgt->wwpn);
3803
+ move->node_name = cpu_to_be64(tgt->ids.node_name);
3804
+
3805
+ if (ibmvfc_send_event(evt, vhost, default_timeout)) {
3806
+ vhost->discovery_threads--;
3807
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3808
+ kref_put(&tgt->kref, ibmvfc_release_tgt);
3809
+ } else
3810
+ tgt_dbg(tgt, "Sent Move Login for old scsi_id: %llX\n", tgt->old_scsi_id);
35713811 }
35723812
35733813 /**
....@@ -3611,18 +3851,18 @@
36113851 case IBMVFC_MAD_SUCCESS:
36123852 tgt_dbg(tgt, "ADISC succeeded\n");
36133853 if (ibmvfc_adisc_needs_plogi(mad, tgt))
3614
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3854
+ ibmvfc_del_tgt(tgt);
36153855 break;
36163856 case IBMVFC_MAD_DRIVER_FAILED:
36173857 break;
36183858 case IBMVFC_MAD_FAILED:
36193859 default:
3620
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
3860
+ ibmvfc_del_tgt(tgt);
36213861 fc_reason = (be32_to_cpu(mad->fc_iu.response[1]) & 0x00ff0000) >> 16;
36223862 fc_explain = (be32_to_cpu(mad->fc_iu.response[1]) & 0x0000ff00) >> 8;
36233863 tgt_info(tgt, "ADISC failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
36243864 ibmvfc_get_cmd_error(be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error)),
3625
- mad->iu.status, mad->iu.error,
3865
+ be16_to_cpu(mad->iu.status), be16_to_cpu(mad->iu.error),
36263866 ibmvfc_get_fc_type(fc_reason), fc_reason,
36273867 ibmvfc_get_ls_explain(fc_explain), fc_explain, status);
36283868 break;
....@@ -3810,9 +4050,8 @@
38104050 switch (status) {
38114051 case IBMVFC_MAD_SUCCESS:
38124052 tgt_dbg(tgt, "Query Target succeeded\n");
3813
- tgt->new_scsi_id = be64_to_cpu(rsp->scsi_id);
38144053 if (be64_to_cpu(rsp->scsi_id) != tgt->scsi_id)
3815
- ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
4054
+ ibmvfc_del_tgt(tgt);
38164055 else
38174056 ibmvfc_init_tgt(tgt, ibmvfc_tgt_adisc);
38184057 break;
....@@ -3826,17 +4065,18 @@
38264065 if ((be16_to_cpu(rsp->status) & IBMVFC_FABRIC_MAPPED) == IBMVFC_FABRIC_MAPPED &&
38274066 be16_to_cpu(rsp->error) == IBMVFC_UNABLE_TO_PERFORM_REQ &&
38284067 be16_to_cpu(rsp->fc_explain) == IBMVFC_PORT_NAME_NOT_REG)
3829
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
4068
+ ibmvfc_del_tgt(tgt);
38304069 else if (ibmvfc_retry_cmd(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)))
38314070 level += ibmvfc_retry_tgt_init(tgt, ibmvfc_tgt_query_target);
38324071 else
3833
- ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DEL_RPORT);
4072
+ ibmvfc_del_tgt(tgt);
38344073
38354074 tgt_log(tgt, level, "Query Target failed: %s (%x:%x) %s (%x) %s (%x) rc=0x%02X\n",
38364075 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3837
- rsp->status, rsp->error, ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)),
3838
- rsp->fc_type, ibmvfc_get_gs_explain(be16_to_cpu(rsp->fc_explain)),
3839
- rsp->fc_explain, status);
4076
+ be16_to_cpu(rsp->status), be16_to_cpu(rsp->error),
4077
+ ibmvfc_get_fc_type(be16_to_cpu(rsp->fc_type)), be16_to_cpu(rsp->fc_type),
4078
+ ibmvfc_get_gs_explain(be16_to_cpu(rsp->fc_explain)), be16_to_cpu(rsp->fc_explain),
4079
+ status);
38404080 break;
38414081 }
38424082
....@@ -3888,32 +4128,77 @@
38884128 * Returns:
38894129 * 0 on success / other on failure
38904130 **/
3891
-static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, u64 scsi_id)
4131
+static int ibmvfc_alloc_target(struct ibmvfc_host *vhost,
4132
+ struct ibmvfc_discover_targets_entry *target)
38924133 {
4134
+ struct ibmvfc_target *stgt = NULL;
4135
+ struct ibmvfc_target *wtgt = NULL;
38934136 struct ibmvfc_target *tgt;
38944137 unsigned long flags;
4138
+ u64 scsi_id = be32_to_cpu(target->scsi_id) & IBMVFC_DISC_TGT_SCSI_ID_MASK;
4139
+ u64 wwpn = be64_to_cpu(target->wwpn);
38954140
4141
+ /* Look to see if we already have a target allocated for this SCSI ID or WWPN */
38964142 spin_lock_irqsave(vhost->host->host_lock, flags);
38974143 list_for_each_entry(tgt, &vhost->targets, queue) {
3898
- if (tgt->scsi_id == scsi_id) {
3899
- if (tgt->need_login)
3900
- ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
3901
- goto unlock_out;
4144
+ if (tgt->wwpn == wwpn) {
4145
+ wtgt = tgt;
4146
+ break;
39024147 }
4148
+ }
4149
+
4150
+ list_for_each_entry(tgt, &vhost->targets, queue) {
4151
+ if (tgt->scsi_id == scsi_id) {
4152
+ stgt = tgt;
4153
+ break;
4154
+ }
4155
+ }
4156
+
4157
+ if (wtgt && !stgt) {
4158
+ /*
4159
+ * A WWPN target has moved and we still are tracking the old
4160
+ * SCSI ID. The only way we should be able to get here is if
4161
+ * we attempted to send an implicit logout for the old SCSI ID
4162
+ * and it failed for some reason, such as there being I/O
4163
+ * pending to the target. In this case, we will have already
4164
+ * deleted the rport from the FC transport so we do a move
4165
+ * login, which works even with I/O pending, as it will cancel
4166
+ * any active commands.
4167
+ */
4168
+ if (wtgt->action == IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT) {
4169
+ /*
4170
+ * Do a move login here. The old target is no longer
4171
+ * known to the transport layer We don't use the
4172
+ * normal ibmvfc_set_tgt_action to set this, as we
4173
+ * don't normally want to allow this state change.
4174
+ */
4175
+ wtgt->old_scsi_id = wtgt->scsi_id;
4176
+ wtgt->scsi_id = scsi_id;
4177
+ wtgt->action = IBMVFC_TGT_ACTION_INIT;
4178
+ ibmvfc_init_tgt(wtgt, ibmvfc_tgt_move_login);
4179
+ goto unlock_out;
4180
+ } else {
4181
+ tgt_err(wtgt, "Unexpected target state: %d, %p\n",
4182
+ wtgt->action, wtgt->rport);
4183
+ }
4184
+ } else if (stgt) {
4185
+ if (tgt->need_login)
4186
+ ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
4187
+ goto unlock_out;
39034188 }
39044189 spin_unlock_irqrestore(vhost->host->host_lock, flags);
39054190
39064191 tgt = mempool_alloc(vhost->tgt_pool, GFP_NOIO);
39074192 memset(tgt, 0, sizeof(*tgt));
39084193 tgt->scsi_id = scsi_id;
3909
- tgt->new_scsi_id = scsi_id;
4194
+ tgt->wwpn = wwpn;
39104195 tgt->vhost = vhost;
39114196 tgt->need_login = 1;
3912
- tgt->cancel_key = vhost->task_set++;
39134197 timer_setup(&tgt->timer, ibmvfc_adisc_timeout, 0);
39144198 kref_init(&tgt->kref);
39154199 ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout);
39164200 spin_lock_irqsave(vhost->host->host_lock, flags);
4201
+ tgt->cancel_key = vhost->task_set++;
39174202 list_add_tail(&tgt->queue, &vhost->targets);
39184203
39194204 unlock_out:
....@@ -3933,9 +4218,7 @@
39334218 int i, rc;
39344219
39354220 for (i = 0, rc = 0; !rc && i < vhost->num_targets; i++)
3936
- rc = ibmvfc_alloc_target(vhost,
3937
- be32_to_cpu(vhost->disc_buf->scsi_id[i]) &
3938
- IBMVFC_DISC_TGT_SCSI_ID_MASK);
4221
+ rc = ibmvfc_alloc_target(vhost, &vhost->disc_buf[i]);
39394222
39404223 return rc;
39414224 }
....@@ -3962,7 +4245,7 @@
39624245 level += ibmvfc_retry_host_init(vhost);
39634246 ibmvfc_log(vhost, level, "Discover Targets failed: %s (%x:%x)\n",
39644247 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
3965
- rsp->status, rsp->error);
4248
+ be16_to_cpu(rsp->status), be16_to_cpu(rsp->error));
39664249 break;
39674250 case IBMVFC_MAD_DRIVER_FAILED:
39684251 break;
....@@ -3995,6 +4278,7 @@
39954278 mad->bufflen = cpu_to_be32(vhost->disc_buf_sz);
39964279 mad->buffer.va = cpu_to_be64(vhost->disc_buf_dma);
39974280 mad->buffer.len = cpu_to_be32(vhost->disc_buf_sz);
4281
+ mad->flags = cpu_to_be32(IBMVFC_DISC_TGT_PORT_ID_WWPN_LIST);
39984282 ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_INIT_WAIT);
39994283
40004284 if (!ibmvfc_send_event(evt, vhost, default_timeout))
....@@ -4027,11 +4311,12 @@
40274311 ibmvfc_link_down(vhost, IBMVFC_LINK_DEAD);
40284312 ibmvfc_log(vhost, level, "NPIV Login failed: %s (%x:%x)\n",
40294313 ibmvfc_get_cmd_error(be16_to_cpu(rsp->status), be16_to_cpu(rsp->error)),
4030
- rsp->status, rsp->error);
4314
+ be16_to_cpu(rsp->status), be16_to_cpu(rsp->error));
40314315 ibmvfc_free_event(evt);
40324316 return;
40334317 case IBMVFC_MAD_CRQ_ERROR:
40344318 ibmvfc_retry_host_init(vhost);
4319
+ fallthrough;
40354320 case IBMVFC_MAD_DRIVER_FAILED:
40364321 ibmvfc_free_event(evt);
40374322 return;
....@@ -4198,6 +4483,25 @@
41984483 }
41994484
42004485 /**
4486
+ * ibmvfc_dev_logo_to_do - Is there target logout work to do?
4487
+ * @vhost: ibmvfc host struct
4488
+ *
4489
+ * Returns:
4490
+ * 1 if work to do / 0 if not
4491
+ **/
4492
+static int ibmvfc_dev_logo_to_do(struct ibmvfc_host *vhost)
4493
+{
4494
+ struct ibmvfc_target *tgt;
4495
+
4496
+ list_for_each_entry(tgt, &vhost->targets, queue) {
4497
+ if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT ||
4498
+ tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT)
4499
+ return 1;
4500
+ }
4501
+ return 0;
4502
+}
4503
+
4504
+/**
42014505 * __ibmvfc_work_to_do - Is there task level work to do? (no locking)
42024506 * @vhost: ibmvfc host struct
42034507 *
....@@ -4226,11 +4530,20 @@
42264530 if (tgt->action == IBMVFC_TGT_ACTION_INIT_WAIT)
42274531 return 0;
42284532 return 1;
4533
+ case IBMVFC_HOST_ACTION_TGT_DEL:
4534
+ case IBMVFC_HOST_ACTION_TGT_DEL_FAILED:
4535
+ if (vhost->discovery_threads == disc_threads)
4536
+ return 0;
4537
+ list_for_each_entry(tgt, &vhost->targets, queue)
4538
+ if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT)
4539
+ return 1;
4540
+ list_for_each_entry(tgt, &vhost->targets, queue)
4541
+ if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT_WAIT)
4542
+ return 0;
4543
+ return 1;
42294544 case IBMVFC_HOST_ACTION_LOGO:
42304545 case IBMVFC_HOST_ACTION_INIT:
42314546 case IBMVFC_HOST_ACTION_ALLOC_TGTS:
4232
- case IBMVFC_HOST_ACTION_TGT_DEL:
4233
- case IBMVFC_HOST_ACTION_TGT_DEL_FAILED:
42344547 case IBMVFC_HOST_ACTION_QUERY:
42354548 case IBMVFC_HOST_ACTION_RESET:
42364549 case IBMVFC_HOST_ACTION_REENABLE:
....@@ -4300,6 +4613,13 @@
43004613 fc_remote_port_delete(rport);
43014614 del_timer_sync(&tgt->timer);
43024615 kref_put(&tgt->kref, ibmvfc_release_tgt);
4616
+ return;
4617
+ } else if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
4618
+ tgt_dbg(tgt, "Deleting rport with outstanding I/O\n");
4619
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT);
4620
+ tgt->rport = NULL;
4621
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
4622
+ fc_remote_port_delete(rport);
43034623 return;
43044624 } else if (rport && tgt->action == IBMVFC_TGT_ACTION_DELETED_RPORT) {
43054625 spin_unlock_irqrestore(vhost->host->host_lock, flags);
....@@ -4419,6 +4739,18 @@
44194739 case IBMVFC_HOST_ACTION_TGT_DEL:
44204740 case IBMVFC_HOST_ACTION_TGT_DEL_FAILED:
44214741 list_for_each_entry(tgt, &vhost->targets, queue) {
4742
+ if (tgt->action == IBMVFC_TGT_ACTION_LOGOUT_RPORT) {
4743
+ tgt->job_step(tgt);
4744
+ break;
4745
+ }
4746
+ }
4747
+
4748
+ if (ibmvfc_dev_logo_to_do(vhost)) {
4749
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
4750
+ return;
4751
+ }
4752
+
4753
+ list_for_each_entry(tgt, &vhost->targets, queue) {
44224754 if (tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) {
44234755 tgt_dbg(tgt, "Deleting rport\n");
44244756 rport = tgt->rport;
....@@ -4430,6 +4762,15 @@
44304762 fc_remote_port_delete(rport);
44314763 del_timer_sync(&tgt->timer);
44324764 kref_put(&tgt->kref, ibmvfc_release_tgt);
4765
+ return;
4766
+ } else if (tgt->action == IBMVFC_TGT_ACTION_DEL_AND_LOGOUT_RPORT) {
4767
+ tgt_dbg(tgt, "Deleting rport with I/O outstanding\n");
4768
+ rport = tgt->rport;
4769
+ tgt->rport = NULL;
4770
+ ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT);
4771
+ spin_unlock_irqrestore(vhost->host->host_lock, flags);
4772
+ if (rport)
4773
+ fc_remote_port_delete(rport);
44334774 return;
44344775 }
44354776 }
....@@ -4663,7 +5004,7 @@
46635004 goto free_sg_pool;
46645005 }
46655006
4666
- vhost->disc_buf_sz = sizeof(vhost->disc_buf->scsi_id[0]) * max_targets;
5007
+ vhost->disc_buf_sz = sizeof(*vhost->disc_buf) * max_targets;
46675008 vhost->disc_buf = dma_alloc_coherent(dev, vhost->disc_buf_sz,
46685009 &vhost->disc_buf_dma, GFP_KERNEL);
46695010