From: Manish Rangankar Date: Thu, 19 Mar 2020 08:38:11 +0000 (-0700) Subject: scsi: qedi: Add PCI shutdown handler support X-Git-Tag: v5.15~4079^2~41 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4f93c4bf0f748f9d0f5e9764ba69ec16c368922a;p=platform%2Fkernel%2Flinux-starfive.git scsi: qedi: Add PCI shutdown handler support Add PCI shutdown handler support for supporting wake-on-lan feature. Link: https://lore.kernel.org/r/20200319083811.19499-3-mrangankar@marvell.com Signed-off-by: Manish Rangankar Signed-off-by: Nilesh Javali Signed-off-by: Martin K. Petersen --- diff --git a/drivers/scsi/qedi/qedi.h b/drivers/scsi/qedi/qedi.h index 812e368..9498279 100644 --- a/drivers/scsi/qedi/qedi.h +++ b/drivers/scsi/qedi/qedi.h @@ -36,6 +36,7 @@ struct qedi_endpoint; */ #define QEDI_MODE_NORMAL 0 #define QEDI_MODE_RECOVERY 1 +#define QEDI_MODE_SHUTDOWN 2 #define ISCSI_WQE_SET_PTU_INVALIDATE 1 #define QEDI_MAX_ISCSI_TASK 4096 @@ -278,6 +279,7 @@ struct qedi_ctx { #define QEDI_IOTHREAD_WAKE 2 #define QEDI_IN_RECOVERY 5 #define QEDI_IN_OFFLINE 6 +#define QEDI_IN_SHUTDOWN 7 u8 mac[ETH_ALEN]; u32 src_ip[4]; diff --git a/drivers/scsi/qedi/qedi_gbl.h b/drivers/scsi/qedi/qedi_gbl.h index 8ba7c77..116645c 100644 --- a/drivers/scsi/qedi/qedi_gbl.h +++ b/drivers/scsi/qedi/qedi_gbl.h @@ -73,5 +73,6 @@ void qedi_remove_sysfs_ctx_attr(struct qedi_ctx *qedi); void qedi_clearsq(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn, struct iscsi_task *task); +void qedi_clear_session_ctx(struct iscsi_cls_session *cls_sess); #endif diff --git a/drivers/scsi/qedi/qedi_iscsi.c b/drivers/scsi/qedi/qedi_iscsi.c index 8829880..1f4a5fb 100644 --- a/drivers/scsi/qedi/qedi_iscsi.c +++ b/drivers/scsi/qedi/qedi_iscsi.c @@ -392,6 +392,7 @@ static int qedi_conn_bind(struct iscsi_cls_session *cls_session, qedi_ep->conn = qedi_conn; qedi_conn->ep = qedi_ep; + qedi_conn->iscsi_ep = ep; qedi_conn->iscsi_conn_id = qedi_ep->iscsi_cid; qedi_conn->fw_cid = qedi_ep->fw_cid; qedi_conn->cmd_cleanup_req = 0; @@ -782,6 +783,9 @@ static int qedi_task_xmit(struct iscsi_task *task) struct qedi_cmd *cmd = task->dd_data; struct scsi_cmnd *sc = task->sc; + if (test_bit(QEDI_IN_SHUTDOWN, &qedi_conn->qedi->flags)) + return -ENODEV; + cmd->state = 0; cmd->task = NULL; cmd->use_slowpath = false; @@ -1596,6 +1600,20 @@ void qedi_process_iscsi_error(struct qedi_endpoint *ep, qedi_start_conn_recovery(qedi_conn->qedi, qedi_conn); } +void qedi_clear_session_ctx(struct iscsi_cls_session *cls_sess) +{ + struct iscsi_session *session = cls_sess->dd_data; + struct iscsi_conn *conn = session->leadconn; + struct qedi_conn *qedi_conn = conn->dd_data; + + if (iscsi_is_session_online(cls_sess)) + qedi_ep_disconnect(qedi_conn->iscsi_ep); + + qedi_conn_destroy(qedi_conn->cls_conn); + + qedi_session_destroy(cls_sess); +} + void qedi_process_tcp_error(struct qedi_endpoint *ep, struct iscsi_eqe_data *data) { diff --git a/drivers/scsi/qedi/qedi_iscsi.h b/drivers/scsi/qedi/qedi_iscsi.h index 67c3b73..39dc27c 100644 --- a/drivers/scsi/qedi/qedi_iscsi.h +++ b/drivers/scsi/qedi/qedi_iscsi.h @@ -149,6 +149,7 @@ struct qedi_conn { struct iscsi_cls_conn *cls_conn; struct qedi_ctx *qedi; struct qedi_endpoint *ep; + struct iscsi_endpoint *iscsi_ep; struct list_head active_cmd_list; spinlock_t list_lock; /* internal conn lock */ u32 active_cmd_count; diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index cfa705a..b995b19 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -2344,7 +2344,11 @@ static void __qedi_remove(struct pci_dev *pdev, int mode) struct qedi_ctx *qedi = pci_get_drvdata(pdev); int rval; - if (mode == QEDI_MODE_NORMAL) { + if (mode == QEDI_MODE_SHUTDOWN) + iscsi_host_for_each_session(qedi->shost, + qedi_clear_session_ctx); + + if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) { if (qedi->tmf_thread) { flush_workqueue(qedi->tmf_thread); destroy_workqueue(qedi->tmf_thread); @@ -2384,7 +2388,7 @@ static void __qedi_remove(struct pci_dev *pdev, int mode) qedi_destroy_fp(qedi); - if (mode == QEDI_MODE_NORMAL) { + if (mode == QEDI_MODE_NORMAL || mode == QEDI_MODE_SHUTDOWN) { qedi_release_cid_que(qedi); qedi_cm_free_mem(qedi); qedi_free_uio(qedi->udev); @@ -2404,6 +2408,16 @@ static void __qedi_remove(struct pci_dev *pdev, int mode) } } +static void qedi_shutdown(struct pci_dev *pdev) +{ + struct qedi_ctx *qedi = pci_get_drvdata(pdev); + + QEDI_ERR(&qedi->dbg_ctx, "%s: Shutdown qedi\n", __func__); + if (test_and_set_bit(QEDI_IN_SHUTDOWN, &qedi->flags)) + return; + __qedi_remove(pdev, QEDI_MODE_SHUTDOWN); +} + static int __qedi_probe(struct pci_dev *pdev, int mode) { struct qedi_ctx *qedi; @@ -2740,6 +2754,7 @@ static struct pci_driver qedi_pci_driver = { .id_table = qedi_pci_tbl, .probe = qedi_probe, .remove = qedi_remove, + .shutdown = qedi_shutdown, }; static int __init qedi_init(void)