summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/qedf
diff options
context:
space:
mode:
authorChad Dupuis <cdupuis@marvell.com>2019-03-26 03:38:47 -0400
committerMartin K. Petersen <martin.petersen@oracle.com>2019-03-27 21:54:52 -0400
commita66c6cd2a8ade6150364687f5872934a7e623fb2 (patch)
tree13080abaab6228800b53f5dfd81b417f2be04163 /drivers/scsi/qedf
parent627cc7dd73f6aa3025398507c729b97fb19c270b (diff)
scsi: qedf: Wait for upload and link down processing during soft ctx reset
- Wait for all the connections to get uploaded. Signed-off-by: Chad Dupuis <cdupuis@marvell.com> Signed-off-by: Saurav Kashyap <skashyap@marvell.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Diffstat (limited to 'drivers/scsi/qedf')
-rw-r--r--drivers/scsi/qedf/qedf.h4
-rw-r--r--drivers/scsi/qedf/qedf_fip.c4
-rw-r--r--drivers/scsi/qedf/qedf_main.c60
3 files changed, 57 insertions, 11 deletions
diff --git a/drivers/scsi/qedf/qedf.h b/drivers/scsi/qedf/qedf.h
index fb7d0d5ffa67..1e0d1429ed48 100644
--- a/drivers/scsi/qedf/qedf.h
+++ b/drivers/scsi/qedf/qedf.h
@@ -500,7 +500,7 @@ extern void qedf_set_vlan_id(struct qedf_ctx *qedf, int vlan_id);
500extern void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf); 500extern void qedf_create_sysfs_ctx_attr(struct qedf_ctx *qedf);
501extern void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf); 501extern void qedf_remove_sysfs_ctx_attr(struct qedf_ctx *qedf);
502extern void qedf_capture_grc_dump(struct qedf_ctx *qedf); 502extern void qedf_capture_grc_dump(struct qedf_ctx *qedf);
503extern void qedf_wait_for_upload(struct qedf_ctx *qedf); 503bool qedf_wait_for_upload(struct qedf_ctx *qedf);
504extern void qedf_process_unsol_compl(struct qedf_ctx *qedf, uint16_t que_idx, 504extern void qedf_process_unsol_compl(struct qedf_ctx *qedf, uint16_t que_idx,
505 struct fcoe_cqe *cqe); 505 struct fcoe_cqe *cqe);
506extern void qedf_restart_rport(struct qedf_rport *fcport); 506extern void qedf_restart_rport(struct qedf_rport *fcport);
@@ -514,6 +514,8 @@ extern void qedf_get_protocol_tlv_data(void *dev, void *data);
514extern void qedf_fp_io_handler(struct work_struct *work); 514extern void qedf_fp_io_handler(struct work_struct *work);
515extern void qedf_get_generic_tlv_data(void *dev, struct qed_generic_tlvs *data); 515extern void qedf_get_generic_tlv_data(void *dev, struct qed_generic_tlvs *data);
516extern void qedf_wq_grcdump(struct work_struct *work); 516extern void qedf_wq_grcdump(struct work_struct *work);
517void qedf_stag_change_work(struct work_struct *work);
518void qedf_ctx_soft_reset(struct fc_lport *lport);
517 519
518#define FCOE_WORD_TO_BYTE 4 520#define FCOE_WORD_TO_BYTE 4
519#define QEDF_MAX_TASK_NUM 0xFFFF 521#define QEDF_MAX_TASK_NUM 0xFFFF
diff --git a/drivers/scsi/qedf/qedf_fip.c b/drivers/scsi/qedf/qedf_fip.c
index e669679e6a3b..53c5eca55061 100644
--- a/drivers/scsi/qedf/qedf_fip.c
+++ b/drivers/scsi/qedf/qedf_fip.c
@@ -236,9 +236,7 @@ void qedf_fip_recv(struct qedf_ctx *qedf, struct sk_buff *skb)
236 QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2, 236 QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_LL2,
237 "do_reset=%d.\n", do_reset); 237 "do_reset=%d.\n", do_reset);
238 if (do_reset) { 238 if (do_reset) {
239 fcoe_ctlr_link_down(&qedf->ctlr); 239 qedf_ctx_soft_reset(qedf->lport);
240 qedf_wait_for_upload(qedf);
241 fcoe_ctlr_link_up(&qedf->ctlr);
242 } 240 }
243 kfree_skb(skb); 241 kfree_skb(skb);
244 } else { 242 } else {
diff --git a/drivers/scsi/qedf/qedf_main.c b/drivers/scsi/qedf/qedf_main.c
index bc787ce0b526..ad72a1eb3bca 100644
--- a/drivers/scsi/qedf/qedf_main.c
+++ b/drivers/scsi/qedf/qedf_main.c
@@ -156,7 +156,8 @@ static void qedf_handle_link_update(struct work_struct *work)
156 container_of(work, struct qedf_ctx, link_update.work); 156 container_of(work, struct qedf_ctx, link_update.work);
157 int rc; 157 int rc;
158 158
159 QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, "Entered.\n"); 159 QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC, "Entered. link_state=%d.\n",
160 atomic_read(&qedf->link_state));
160 161
161 if (atomic_read(&qedf->link_state) == QEDF_LINK_UP) { 162 if (atomic_read(&qedf->link_state) == QEDF_LINK_UP) {
162 rc = qedf_initiate_fipvlan_req(qedf); 163 rc = qedf_initiate_fipvlan_req(qedf);
@@ -194,7 +195,9 @@ static void qedf_handle_link_update(struct work_struct *work)
194 QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, 195 QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
195 "Calling fcoe_ctlr_link_down().\n"); 196 "Calling fcoe_ctlr_link_down().\n");
196 fcoe_ctlr_link_down(&qedf->ctlr); 197 fcoe_ctlr_link_down(&qedf->ctlr);
197 qedf_wait_for_upload(qedf); 198 if (qedf_wait_for_upload(qedf) == false)
199 QEDF_ERR(&qedf->dbg_ctx,
200 "Could not upload all sessions.\n");
198 /* Reset the number of FIP VLAN retries */ 201 /* Reset the number of FIP VLAN retries */
199 qedf->fipvlan_retries = qedf_fipvlan_retries; 202 qedf->fipvlan_retries = qedf_fipvlan_retries;
200 } 203 }
@@ -780,22 +783,42 @@ static int qedf_eh_device_reset(struct scsi_cmnd *sc_cmd)
780 return qedf_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET); 783 return qedf_initiate_tmf(sc_cmd, FCP_TMF_LUN_RESET);
781} 784}
782 785
783void qedf_wait_for_upload(struct qedf_ctx *qedf) 786bool qedf_wait_for_upload(struct qedf_ctx *qedf)
784{ 787{
788 struct qedf_rport *fcport = NULL;
789
785 while (1) { 790 while (1) {
786 if (atomic_read(&qedf->num_offloads)) 791 if (atomic_read(&qedf->num_offloads))
787 QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC, 792 QEDF_INFO(&(qedf->dbg_ctx), QEDF_LOG_DISC,
788 "Waiting for all uploads to complete.\n"); 793 "Waiting for all uploads to complete.\n");
789 else 794 else
790 break; 795 return true;
791 msleep(500); 796 msleep(500);
792 } 797 }
798
799 rcu_read_lock();
800 list_for_each_entry_rcu(fcport, &qedf->fcports, peers) {
801 if (fcport && test_bit(QEDF_RPORT_SESSION_READY,
802 &fcport->flags)) {
803 if (fcport->rdata)
804 QEDF_ERR(&qedf->dbg_ctx,
805 "Waiting for fcport %p portid=%06x.\n",
806 fcport, fcport->rdata->ids.port_id);
807 } else {
808 QEDF_ERR(&qedf->dbg_ctx,
809 "Waiting for fcport %p.\n", fcport);
810 }
811 }
812 rcu_read_unlock();
813 return false;
814
793} 815}
794 816
795/* Performs soft reset of qedf_ctx by simulating a link down/up */ 817/* Performs soft reset of qedf_ctx by simulating a link down/up */
796static void qedf_ctx_soft_reset(struct fc_lport *lport) 818void qedf_ctx_soft_reset(struct fc_lport *lport)
797{ 819{
798 struct qedf_ctx *qedf; 820 struct qedf_ctx *qedf;
821 struct qed_link_output if_link;
799 822
800 if (lport->vport) { 823 if (lport->vport) {
801 QEDF_ERR(NULL, "Cannot issue host reset on NPIV port.\n"); 824 QEDF_ERR(NULL, "Cannot issue host reset on NPIV port.\n");
@@ -806,11 +829,32 @@ static void qedf_ctx_soft_reset(struct fc_lport *lport)
806 829
807 /* For host reset, essentially do a soft link up/down */ 830 /* For host reset, essentially do a soft link up/down */
808 atomic_set(&qedf->link_state, QEDF_LINK_DOWN); 831 atomic_set(&qedf->link_state, QEDF_LINK_DOWN);
832 QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
833 "Queuing link down work.\n");
809 queue_delayed_work(qedf->link_update_wq, &qedf->link_update, 834 queue_delayed_work(qedf->link_update_wq, &qedf->link_update,
810 0); 835 0);
811 qedf_wait_for_upload(qedf); 836
837 if (qedf_wait_for_upload(qedf) == false) {
838 QEDF_ERR(&qedf->dbg_ctx, "Could not upload all sessions.\n");
839 WARN_ON(atomic_read(&qedf->num_offloads));
840 }
841
842 /* Before setting link up query physical link state */
843 qed_ops->common->get_link(qedf->cdev, &if_link);
844 /* Bail if the physical link is not up */
845 if (!if_link.link_up) {
846 QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
847 "Physical link is not up.\n");
848 return;
849 }
850 /* Flush and wait to make sure link down is processed */
851 flush_delayed_work(&qedf->link_update);
852 msleep(500);
853
812 atomic_set(&qedf->link_state, QEDF_LINK_UP); 854 atomic_set(&qedf->link_state, QEDF_LINK_UP);
813 qedf->vlan_id = 0; 855 qedf->vlan_id = 0;
856 QEDF_INFO(&qedf->dbg_ctx, QEDF_LOG_DISC,
857 "Queue link up work.\n");
814 queue_delayed_work(qedf->link_update_wq, &qedf->link_update, 858 queue_delayed_work(qedf->link_update_wq, &qedf->link_update,
815 0); 859 0);
816} 860}
@@ -3453,7 +3497,9 @@ static void __qedf_remove(struct pci_dev *pdev, int mode)
3453 fcoe_ctlr_link_down(&qedf->ctlr); 3497 fcoe_ctlr_link_down(&qedf->ctlr);
3454 else 3498 else
3455 fc_fabric_logoff(qedf->lport); 3499 fc_fabric_logoff(qedf->lport);
3456 qedf_wait_for_upload(qedf); 3500
3501 if (qedf_wait_for_upload(qedf) == false)
3502 QEDF_ERR(&qedf->dbg_ctx, "Could not upload all sessions.\n");
3457 3503
3458#ifdef CONFIG_DEBUG_FS 3504#ifdef CONFIG_DEBUG_FS
3459 qedf_dbg_host_exit(&(qedf->dbg_ctx)); 3505 qedf_dbg_host_exit(&(qedf->dbg_ctx));