Loading drivers/scsi/lpfc/lpfc.h +1 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,7 @@ struct lpfc_hba { #define FC_FABRIC 0x100 /* We are fabric attached */ #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ #define FC_RSCN_DISCOVERY 0x400 /* Authenticate all devices after RSCN*/ #define FC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */ #define FC_LOADING 0x1000 /* HBA in process of loading drvr */ #define FC_UNLOADING 0x2000 /* HBA in process of unloading drvr */ #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ Loading drivers/scsi/lpfc/lpfc_attr.c +67 −16 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ *******************************************************************/ #include <linux/ctype.h> #include <linux/delay.h> #include <linux/pci.h> #include <linux/interrupt.h> Loading Loading @@ -213,6 +214,7 @@ lpfc_issue_lip(struct Scsi_Host *host) int mbxstatus = MBXERR_ERROR; if ((phba->fc_flag & FC_OFFLINE_MODE) || (phba->fc_flag & FC_BLOCK_MGMT_IO) || (phba->hba_state != LPFC_HBA_READY)) return -EPERM; Loading Loading @@ -247,19 +249,62 @@ lpfc_issue_lip(struct Scsi_Host *host) } static int lpfc_selective_reset(struct lpfc_hba *phba) lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) { struct completion online_compl; struct lpfc_sli_ring *pring; struct lpfc_sli *psli; int status = 0; int cnt = 0; int i; init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_OFFLINE); LPFC_EVT_OFFLINE_PREP); wait_for_completion(&online_compl); if (status != 0) return -EIO; psli = &phba->sli; for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; /* The linkdown event takes 30 seconds to timeout. */ while (pring->txcmplq_cnt) { msleep(10); if (cnt++ > 3000) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "%d:0466 Outstanding IO when " "bringing Adapter offline\n", phba->brd_no); break; } } } init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, type); wait_for_completion(&online_compl); if (status != 0) return -EIO; return 0; } static int lpfc_selective_reset(struct lpfc_hba *phba) { struct completion online_compl; int status = 0; status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); if (status != 0) return status; init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_ONLINE); Loading Loading @@ -324,23 +369,19 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) init_completion(&online_compl); if(strncmp(buf, "online", sizeof("online") - 1) == 0) if(strncmp(buf, "online", sizeof("online") - 1) == 0) { lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_ONLINE); else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_OFFLINE); wait_for_completion(&online_compl); } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_WARM_START); status = lpfc_do_offline(phba, LPFC_EVT_WARM_START); else if (strncmp(buf, "error", sizeof("error") - 1) == 0) lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_KILL); status = lpfc_do_offline(phba, LPFC_EVT_KILL); else return -EINVAL; wait_for_completion(&online_compl); if (!status) return strlen(buf); else Loading Loading @@ -645,9 +686,7 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) dev_printk(KERN_NOTICE, &phba->pcidev->dev, "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); init_completion(&online_compl); lpfc_workq_post_event(phba, &stat1, &online_compl, LPFC_EVT_OFFLINE); wait_for_completion(&online_compl); stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); if (stat1) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "%d:0463 lpfc_soft_wwpn attribute set failed to reinit " Loading Loading @@ -1307,6 +1346,12 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) return -EPERM; } if (phba->fc_flag & FC_BLOCK_MGMT_IO) { sysfs_mbox_idle(phba); spin_unlock_irq(host->host_lock); return -EAGAIN; } if ((phba->fc_flag & FC_OFFLINE_MODE) || (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ Loading Loading @@ -1551,6 +1596,9 @@ lpfc_get_stats(struct Scsi_Host *shost) unsigned long seconds; int rc = 0; if (phba->fc_flag & FC_BLOCK_MGMT_IO) return NULL; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return NULL; Loading Loading @@ -1651,6 +1699,9 @@ lpfc_reset_stats(struct Scsi_Host *shost) MAILBOX_t *pmb; int rc = 0; if (phba->fc_flag & FC_BLOCK_MGMT_IO) return; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return; Loading drivers/scsi/lpfc/lpfc_crtn.h +4 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,10 @@ void lpfc_hba_init(struct lpfc_hba *, uint32_t *); int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); int lpfc_online(struct lpfc_hba *); int lpfc_offline(struct lpfc_hba *); void lpfc_block_mgmt_io(struct lpfc_hba *); void lpfc_unblock_mgmt_io(struct lpfc_hba *); void lpfc_offline_prep(struct lpfc_hba *); void lpfc_offline(struct lpfc_hba *); int lpfc_sli_setup(struct lpfc_hba *); int lpfc_sli_queue_setup(struct lpfc_hba *); Loading drivers/scsi/lpfc/lpfc_disc.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ /* worker thread events */ enum lpfc_work_type { LPFC_EVT_ONLINE, LPFC_EVT_OFFLINE_PREP, LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL, Loading drivers/scsi/lpfc/lpfc_hbadisc.c +13 −7 Original line number Diff line number Diff line Loading @@ -185,29 +185,35 @@ lpfc_work_list_done(struct lpfc_hba * phba) *(int *)(evtp->evt_arg1) = 0; complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_OFFLINE: case LPFC_EVT_OFFLINE_PREP: if (phba->hba_state >= LPFC_LINK_DOWN) lpfc_offline_prep(phba); *(int *)(evtp->evt_arg1) = 0; complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_OFFLINE: lpfc_offline(phba); lpfc_sli_brdrestart(phba); *(int *)(evtp->evt_arg1) = lpfc_sli_brdready(phba, HS_FFRDY | HS_MBRDY); lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_WARM_START: if (phba->hba_state >= LPFC_LINK_DOWN) lpfc_offline(phba); lpfc_reset_barrier(phba); lpfc_sli_brdreset(phba); lpfc_hba_down_post(phba); *(int *)(evtp->evt_arg1) = lpfc_sli_brdready(phba, HS_MBRDY); lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_KILL: if (phba->hba_state >= LPFC_LINK_DOWN) lpfc_offline(phba); *(int *)(evtp->evt_arg1) = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; } Loading Loading
drivers/scsi/lpfc/lpfc.h +1 −0 Original line number Diff line number Diff line Loading @@ -244,6 +244,7 @@ struct lpfc_hba { #define FC_FABRIC 0x100 /* We are fabric attached */ #define FC_ESTABLISH_LINK 0x200 /* Reestablish Link */ #define FC_RSCN_DISCOVERY 0x400 /* Authenticate all devices after RSCN*/ #define FC_BLOCK_MGMT_IO 0x800 /* Don't allow mgmt mbx or iocb cmds */ #define FC_LOADING 0x1000 /* HBA in process of loading drvr */ #define FC_UNLOADING 0x2000 /* HBA in process of unloading drvr */ #define FC_SCSI_SCAN_TMO 0x4000 /* scsi scan timer running */ Loading
drivers/scsi/lpfc/lpfc_attr.c +67 −16 Original line number Diff line number Diff line Loading @@ -20,6 +20,7 @@ *******************************************************************/ #include <linux/ctype.h> #include <linux/delay.h> #include <linux/pci.h> #include <linux/interrupt.h> Loading Loading @@ -213,6 +214,7 @@ lpfc_issue_lip(struct Scsi_Host *host) int mbxstatus = MBXERR_ERROR; if ((phba->fc_flag & FC_OFFLINE_MODE) || (phba->fc_flag & FC_BLOCK_MGMT_IO) || (phba->hba_state != LPFC_HBA_READY)) return -EPERM; Loading Loading @@ -247,19 +249,62 @@ lpfc_issue_lip(struct Scsi_Host *host) } static int lpfc_selective_reset(struct lpfc_hba *phba) lpfc_do_offline(struct lpfc_hba *phba, uint32_t type) { struct completion online_compl; struct lpfc_sli_ring *pring; struct lpfc_sli *psli; int status = 0; int cnt = 0; int i; init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_OFFLINE); LPFC_EVT_OFFLINE_PREP); wait_for_completion(&online_compl); if (status != 0) return -EIO; psli = &phba->sli; for (i = 0; i < psli->num_rings; i++) { pring = &psli->ring[i]; /* The linkdown event takes 30 seconds to timeout. */ while (pring->txcmplq_cnt) { msleep(10); if (cnt++ > 3000) { lpfc_printf_log(phba, KERN_WARNING, LOG_INIT, "%d:0466 Outstanding IO when " "bringing Adapter offline\n", phba->brd_no); break; } } } init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, type); wait_for_completion(&online_compl); if (status != 0) return -EIO; return 0; } static int lpfc_selective_reset(struct lpfc_hba *phba) { struct completion online_compl; int status = 0; status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); if (status != 0) return status; init_completion(&online_compl); lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_ONLINE); Loading Loading @@ -324,23 +369,19 @@ lpfc_board_mode_store(struct class_device *cdev, const char *buf, size_t count) init_completion(&online_compl); if(strncmp(buf, "online", sizeof("online") - 1) == 0) if(strncmp(buf, "online", sizeof("online") - 1) == 0) { lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_ONLINE); else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_OFFLINE); wait_for_completion(&online_compl); } else if (strncmp(buf, "offline", sizeof("offline") - 1) == 0) status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); else if (strncmp(buf, "warm", sizeof("warm") - 1) == 0) lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_WARM_START); status = lpfc_do_offline(phba, LPFC_EVT_WARM_START); else if (strncmp(buf, "error", sizeof("error") - 1) == 0) lpfc_workq_post_event(phba, &status, &online_compl, LPFC_EVT_KILL); status = lpfc_do_offline(phba, LPFC_EVT_KILL); else return -EINVAL; wait_for_completion(&online_compl); if (!status) return strlen(buf); else Loading Loading @@ -645,9 +686,7 @@ lpfc_soft_wwpn_store(struct class_device *cdev, const char *buf, size_t count) dev_printk(KERN_NOTICE, &phba->pcidev->dev, "lpfc%d: Reinitializing to use soft_wwpn\n", phba->brd_no); init_completion(&online_compl); lpfc_workq_post_event(phba, &stat1, &online_compl, LPFC_EVT_OFFLINE); wait_for_completion(&online_compl); stat1 = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); if (stat1) lpfc_printf_log(phba, KERN_ERR, LOG_INIT, "%d:0463 lpfc_soft_wwpn attribute set failed to reinit " Loading Loading @@ -1307,6 +1346,12 @@ sysfs_mbox_read(struct kobject *kobj, char *buf, loff_t off, size_t count) return -EPERM; } if (phba->fc_flag & FC_BLOCK_MGMT_IO) { sysfs_mbox_idle(phba); spin_unlock_irq(host->host_lock); return -EAGAIN; } if ((phba->fc_flag & FC_OFFLINE_MODE) || (!(phba->sli.sli_flag & LPFC_SLI2_ACTIVE))){ Loading Loading @@ -1551,6 +1596,9 @@ lpfc_get_stats(struct Scsi_Host *shost) unsigned long seconds; int rc = 0; if (phba->fc_flag & FC_BLOCK_MGMT_IO) return NULL; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return NULL; Loading Loading @@ -1651,6 +1699,9 @@ lpfc_reset_stats(struct Scsi_Host *shost) MAILBOX_t *pmb; int rc = 0; if (phba->fc_flag & FC_BLOCK_MGMT_IO) return; pmboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); if (!pmboxq) return; Loading
drivers/scsi/lpfc/lpfc_crtn.h +4 −1 Original line number Diff line number Diff line Loading @@ -112,7 +112,10 @@ void lpfc_hba_init(struct lpfc_hba *, uint32_t *); int lpfc_post_buffer(struct lpfc_hba *, struct lpfc_sli_ring *, int, int); void lpfc_decode_firmware_rev(struct lpfc_hba *, char *, int); int lpfc_online(struct lpfc_hba *); int lpfc_offline(struct lpfc_hba *); void lpfc_block_mgmt_io(struct lpfc_hba *); void lpfc_unblock_mgmt_io(struct lpfc_hba *); void lpfc_offline_prep(struct lpfc_hba *); void lpfc_offline(struct lpfc_hba *); int lpfc_sli_setup(struct lpfc_hba *); int lpfc_sli_queue_setup(struct lpfc_hba *); Loading
drivers/scsi/lpfc/lpfc_disc.h +1 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ /* worker thread events */ enum lpfc_work_type { LPFC_EVT_ONLINE, LPFC_EVT_OFFLINE_PREP, LPFC_EVT_OFFLINE, LPFC_EVT_WARM_START, LPFC_EVT_KILL, Loading
drivers/scsi/lpfc/lpfc_hbadisc.c +13 −7 Original line number Diff line number Diff line Loading @@ -185,29 +185,35 @@ lpfc_work_list_done(struct lpfc_hba * phba) *(int *)(evtp->evt_arg1) = 0; complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_OFFLINE: case LPFC_EVT_OFFLINE_PREP: if (phba->hba_state >= LPFC_LINK_DOWN) lpfc_offline_prep(phba); *(int *)(evtp->evt_arg1) = 0; complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_OFFLINE: lpfc_offline(phba); lpfc_sli_brdrestart(phba); *(int *)(evtp->evt_arg1) = lpfc_sli_brdready(phba, HS_FFRDY | HS_MBRDY); lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_WARM_START: if (phba->hba_state >= LPFC_LINK_DOWN) lpfc_offline(phba); lpfc_reset_barrier(phba); lpfc_sli_brdreset(phba); lpfc_hba_down_post(phba); *(int *)(evtp->evt_arg1) = lpfc_sli_brdready(phba, HS_MBRDY); lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; case LPFC_EVT_KILL: if (phba->hba_state >= LPFC_LINK_DOWN) lpfc_offline(phba); *(int *)(evtp->evt_arg1) = (phba->stopped) ? 0 : lpfc_sli_brdkill(phba); lpfc_unblock_mgmt_io(phba); complete((struct completion *)(evtp->evt_arg2)); break; } Loading