[SCSI] lpfc 8.1.2: Add ERROR and WARM_START modes for diagnostic purposes.

Add ERROR and WARM_START modes for diagnostic purposes.

Signed-off-by: Jamie Wellnitz <Jamie.Wellnitz@emulex.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c
index 5c39617..5545492 100644
--- a/drivers/scsi/lpfc/lpfc_hbadisc.c
+++ b/drivers/scsi/lpfc/lpfc_hbadisc.c
@@ -1,7 +1,7 @@
 /*******************************************************************
  * This file is part of the Emulex Linux Device Driver for         *
  * Fibre Channel Host Bus Adapters.                                *
- * Copyright (C) 2004-2005 Emulex.  All rights reserved.           *
+ * Copyright (C) 2004-2006 Emulex.  All rights reserved.           *
  * EMULEX and SLI are trademarks of Emulex.                        *
  * www.emulex.com                                                  *
  * Portions Copyright (C) 2004-2005 Christoph Hellwig              *
@@ -120,11 +120,33 @@
 			free_evt = 0;
 			break;
 		case LPFC_EVT_ONLINE:
-			*(int *)(evtp->evt_arg1)  = lpfc_online(phba);
+			if (phba->hba_state < LPFC_LINK_DOWN)
+				*(int *)(evtp->evt_arg1)  = lpfc_online(phba);
+			else
+				*(int *)(evtp->evt_arg1)  = 0;
 			complete((struct completion *)(evtp->evt_arg2));
 			break;
 		case LPFC_EVT_OFFLINE:
-			*(int *)(evtp->evt_arg1)  = lpfc_offline(phba);
+			if (phba->hba_state >= LPFC_LINK_DOWN)
+				lpfc_offline(phba);
+			lpfc_sli_brdrestart(phba);
+			*(int *)(evtp->evt_arg1) =
+				lpfc_sli_brdready(phba,HS_FFRDY | HS_MBRDY);
+			complete((struct completion *)(evtp->evt_arg2));
+			break;
+		case LPFC_EVT_WARM_START:
+			if (phba->hba_state >= LPFC_LINK_DOWN)
+				lpfc_offline(phba);
+			lpfc_sli_brdreset(phba);
+			lpfc_hba_down_post(phba);
+			*(int *)(evtp->evt_arg1) =
+				lpfc_sli_brdready(phba, HS_MBRDY);
+			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)  = lpfc_sli_brdkill(phba);
 			complete((struct completion *)(evtp->evt_arg2));
 			break;
 		}
@@ -287,6 +309,10 @@
 	LPFC_MBOXQ_t     *mb;
 	int               rc, i;
 
+	if (phba->hba_state == LPFC_LINK_DOWN) {
+		return 0;
+	}
+
 	psli = &phba->sli;
 
 	/* sysfs or selective reset may call this routine to clean up */