Skip to contentSkip to conversation

lpfc 8.1.4 : Introduce lpfc_reset_barrier() function for resets on dual channel adapters

PATCH In review James Smart 1 participant 1 message Mar 7, 2006

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

PATCH 4/6 lpfc 8.1.4 : Introduce lpfc_reset_barrier() function for resets on dual channel adapters

Introduce lpfc_reset_barrier() function for resets on dual channel adapters

Workaround for a hardware errata on dual channel asics. There is a potential for the chip to lock up on a reset if a shared dma engine is in use. The (ugly) work around requires a reset process which uses a mailbox command to synchronize the independent channels prior to the reset to avoid the issue. Unfortunately, the timing windows required to ensure this workaround succeeds are very specific, meaning we can't release the cpu during the barrier.

drivers/scsi/lpfc/lpfc_hbadisc.c +3 -1
@@ -155,6 +155,7 @@ lpfc_work_list_done(struct lpfc_hba * ph
 		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) =
@@ -164,7 +165,8 @@ lpfc_work_list_done(struct lpfc_hba * ph
 		case LPFC_EVT_KILL:
 			if (phba->hba_state >= LPFC_LINK_DOWN)
 				lpfc_offline(phba);
-			*(int *)(evtp->evt_arg1)  = lpfc_sli_brdkill(phba);
+			*(int *)(evtp->evt_arg1)
+				= (phba->stopped) ? 0 : lpfc_sli_brdkill(phba);
 			complete((struct completion *)(evtp->evt_arg2));
 			break;
 		}
drivers/scsi/lpfc/lpfc_init.c +2 -2
@@ -464,8 +464,6 @@ lpfc_hba_down_prep(struct lpfc_hba * phb
 	lpfc_els_flush_cmd(phba);
 	lpfc_disc_flush_list(phba);
 
-	/* Disable SLI2 since we disabled interrupts */
-	phba->sli.sli_flag &= ~LPFC_SLI2_ACTIVE;
 	return (0);
 }
 
@@ -526,6 +524,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba
 				phba->work_status[0], phba->work_status[1]);
 		spin_lock_irq(phba->host->host_lock);
 		phba->fc_flag |= FC_ESTABLISH_LINK;
+		psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 		spin_unlock_irq(phba->host->host_lock);
 
 		/*
@@ -559,6 +558,7 @@ lpfc_handle_eratt(struct lpfc_hba * phba
 				phba->brd_no, phba->work_hs,
 				phba->work_status[0], phba->work_status[1]);
 
+		psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 		lpfc_offline(phba);
 		phba->hba_state = LPFC_HBA_ERROR;
 		lpfc_hba_down_post(phba);
drivers/scsi/lpfc/lpfc_crtn.h +1 -0
@@ -139,6 +139,7 @@ struct lpfc_iocbq * lpfc_sli_get_iocbq(s
 void lpfc_sli_release_iocbq(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
 uint16_t lpfc_sli_next_iotag(struct lpfc_hba * phba, struct lpfc_iocbq * iocb);
 
+void lpfc_reset_barrier(struct lpfc_hba * phba);
 int lpfc_sli_brdready(struct lpfc_hba *, uint32_t);
 int lpfc_sli_brdkill(struct lpfc_hba *);
 int lpfc_sli_brdreset(struct lpfc_hba *);
drivers/scsi/lpfc/lpfc.h +1 -0
@@ -197,6 +197,7 @@ struct lpfc_hba {
 #define LPFC_HBA_READY            32
 #define LPFC_HBA_ERROR            -1
 
+	int32_t stopped;   /* HBA has not been restarted since last ERATT */
 	uint8_t fc_linkspeed;	/* Link speed after last READ_LA */
 
 	uint32_t fc_eventTag;	/* event tag for link attention */
drivers/scsi/lpfc/lpfc_sli.c +93 -6

160 lines not on this page · raw message