diff --git a/drivers/scsi/be2iscsi/be.h b/drivers/scsi/be2iscsi/be.h index 23c73fe42648..1bfb0bd01198 100644 --- a/drivers/scsi/be2iscsi/be.h +++ b/drivers/scsi/be2iscsi/be.h @@ -139,6 +139,7 @@ struct be_ctrl_info { #define PAGE_SHIFT_4K 12 #define PAGE_SIZE_4K (1 << PAGE_SHIFT_4K) #define mcc_timeout 120000 /* 12s timeout */ +#define BEISCSI_LOGOUT_SYNC_DELAY 250 /* Returns number of pages spanned by the data starting at the given addr */ #define PAGES_4K_SPANNED(_address, size) \ diff --git a/drivers/scsi/be2iscsi/be_cmds.c b/drivers/scsi/be2iscsi/be_cmds.c index 86d91f31a6a3..1432ed5e9fc6 100644 --- a/drivers/scsi/be2iscsi/be_cmds.c +++ b/drivers/scsi/be2iscsi/be_cmds.c @@ -400,8 +400,23 @@ static struct be_mcc_compl *be_mcc_compl_get(struct beiscsi_hba *phba) return NULL; } -static void be2iscsi_fail_session(struct iscsi_cls_session *cls_session) +/** + * be2iscsi_fail_session(): Closing session with appropriate error + * @cls_session: ptr to session + * + * Depending on adapter state appropriate error flag is passed. + **/ +void be2iscsi_fail_session(struct iscsi_cls_session *cls_session) { + struct Scsi_Host *shost = iscsi_session_to_shost(cls_session); + struct beiscsi_hba *phba = iscsi_host_priv(shost); + uint32_t iscsi_err_flag; + + if (phba->state & BE_ADAPTER_STATE_SHUTDOWN) + iscsi_err_flag = ISCSI_ERR_INVALID_HOST; + else + iscsi_err_flag = ISCSI_ERR_CONN_FAILED; + iscsi_session_failure(cls_session->dd_data, ISCSI_ERR_CONN_FAILED); } diff --git a/drivers/scsi/be2iscsi/be_cmds.h b/drivers/scsi/be2iscsi/be_cmds.h index 14c51e6f2445..7cf7f99ee442 100644 --- a/drivers/scsi/be2iscsi/be_cmds.h +++ b/drivers/scsi/be2iscsi/be_cmds.h @@ -1318,4 +1318,5 @@ void be_wrb_hdr_prepare(struct be_mcc_wrb *wrb, int payload_len, void be_cmd_hdr_prepare(struct be_cmd_req_hdr *req_hdr, u8 subsystem, u8 opcode, int cmd_len); +void be2iscsi_fail_session(struct iscsi_cls_session *cls_session); #endif /* !BEISCSI_CMDS_H */ diff --git a/drivers/scsi/be2iscsi/be_iscsi.c b/drivers/scsi/be2iscsi/be_iscsi.c index a7a210ef407c..a3df43324c98 100644 --- a/drivers/scsi/be2iscsi/be_iscsi.c +++ b/drivers/scsi/be2iscsi/be_iscsi.c @@ -1361,6 +1361,7 @@ void beiscsi_ep_disconnect(struct iscsi_endpoint *ep) beiscsi_mccq_compl(phba, tag, NULL, NULL); beiscsi_close_conn(beiscsi_ep, tcp_upload_flag); free_ep: + msleep(BEISCSI_LOGOUT_SYNC_DELAY); beiscsi_free_ep(beiscsi_ep); beiscsi_unbind_conn_to_cid(phba, beiscsi_ep->ep_cid); iscsi_destroy_endpoint(beiscsi_ep->openiscsi_ep); diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index 89c95f1537e8..b1b6e74e0b7c 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -5301,6 +5301,8 @@ static void beiscsi_shutdown(struct pci_dev *pcidev) return; } + phba->state = BE_ADAPTER_STATE_SHUTDOWN; + iscsi_host_for_each_session(phba->shost, be2iscsi_fail_session); beiscsi_quiesce(phba, BEISCSI_CLEAN_UNLOAD); pci_disable_device(pcidev); } diff --git a/drivers/scsi/be2iscsi/be_main.h b/drivers/scsi/be2iscsi/be_main.h index e02e14cedd5d..77f33a472845 100644 --- a/drivers/scsi/be2iscsi/be_main.h +++ b/drivers/scsi/be2iscsi/be_main.h @@ -97,9 +97,14 @@ #define INVALID_SESS_HANDLE 0xFFFFFFFF +/** + * Adapter States + **/ #define BE_ADAPTER_LINK_UP 0x001 #define BE_ADAPTER_LINK_DOWN 0x002 #define BE_ADAPTER_PCI_ERR 0x004 +#define BE_ADAPTER_STATE_SHUTDOWN 0x008 + #define BEISCSI_CLEAN_UNLOAD 0x01 #define BEISCSI_EEH_UNLOAD 0x02