aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/message/fusion/mptbase.c63
-rw-r--r--drivers/message/fusion/mptbase.h66
-rw-r--r--drivers/message/fusion/mptsas.c2
-rw-r--r--drivers/message/fusion/mptscsih.c3
-rw-r--r--drivers/message/fusion/mptscsih.h1
5 files changed, 105 insertions, 30 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c
index 7956a10f9488..517621fa8bca 100644
--- a/drivers/message/fusion/mptbase.c
+++ b/drivers/message/fusion/mptbase.c
@@ -63,6 +63,8 @@
63#ifdef CONFIG_MTRR 63#ifdef CONFIG_MTRR
64#include <asm/mtrr.h> 64#include <asm/mtrr.h>
65#endif 65#endif
66#include <linux/kthread.h>
67#include <scsi/scsi_host.h>
66 68
67#include "mptbase.h" 69#include "mptbase.h"
68#include "lsi/mpi_log_fc.h" 70#include "lsi/mpi_log_fc.h"
@@ -323,6 +325,32 @@ mpt_is_discovery_complete(MPT_ADAPTER *ioc)
323 return rc; 325 return rc;
324} 326}
325 327
328
329/**
330 * mpt_remove_dead_ioc_func - kthread context to remove dead ioc
331 * @arg: input argument, used to derive ioc
332 *
333 * Return 0 if controller is removed from pci subsystem.
334 * Return -1 for other case.
335 */
336static int mpt_remove_dead_ioc_func(void *arg)
337{
338 MPT_ADAPTER *ioc = (MPT_ADAPTER *)arg;
339 struct pci_dev *pdev;
340
341 if ((ioc == NULL))
342 return -1;
343
344 pdev = ioc->pcidev;
345 if ((pdev == NULL))
346 return -1;
347
348 pci_remove_bus_device(pdev);
349 return 0;
350}
351
352
353
326/** 354/**
327 * mpt_fault_reset_work - work performed on workq after ioc fault 355 * mpt_fault_reset_work - work performed on workq after ioc fault
328 * @work: input argument, used to derive ioc 356 * @work: input argument, used to derive ioc
@@ -336,12 +364,45 @@ mpt_fault_reset_work(struct work_struct *work)
336 u32 ioc_raw_state; 364 u32 ioc_raw_state;
337 int rc; 365 int rc;
338 unsigned long flags; 366 unsigned long flags;
367 MPT_SCSI_HOST *hd;
368 struct task_struct *p;
339 369
340 if (ioc->ioc_reset_in_progress || !ioc->active) 370 if (ioc->ioc_reset_in_progress || !ioc->active)
341 goto out; 371 goto out;
342 372
373
343 ioc_raw_state = mpt_GetIocState(ioc, 0); 374 ioc_raw_state = mpt_GetIocState(ioc, 0);
344 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) { 375 if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_MASK) {
376 printk(MYIOC_s_INFO_FMT "%s: IOC is non-operational !!!!\n",
377 ioc->name, __func__);
378
379 /*
380 * Call mptscsih_flush_pending_cmds callback so that we
381 * flush all pending commands back to OS.
382 * This call is required to aovid deadlock at block layer.
383 * Dead IOC will fail to do diag reset,and this call is safe
384 * since dead ioc will never return any command back from HW.
385 */
386 hd = shost_priv(ioc->sh);
387 ioc->schedule_dead_ioc_flush_running_cmds(hd);
388
389 /*Remove the Dead Host */
390 p = kthread_run(mpt_remove_dead_ioc_func, ioc,
391 "mpt_dead_ioc_%d", ioc->id);
392 if (IS_ERR(p)) {
393 printk(MYIOC_s_ERR_FMT
394 "%s: Running mpt_dead_ioc thread failed !\n",
395 ioc->name, __func__);
396 } else {
397 printk(MYIOC_s_WARN_FMT
398 "%s: Running mpt_dead_ioc thread success !\n",
399 ioc->name, __func__);
400 }
401 return; /* don't rearm timer */
402 }
403
404 if ((ioc_raw_state & MPI_IOC_STATE_MASK)
405 == MPI_IOC_STATE_FAULT) {
345 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n", 406 printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
346 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK); 407 ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
347 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n", 408 printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h
index fe902338539b..69ddabd51958 100644
--- a/drivers/message/fusion/mptbase.h
+++ b/drivers/message/fusion/mptbase.h
@@ -554,10 +554,47 @@ struct mptfc_rport_info
554 u8 flags; 554 u8 flags;
555}; 555};
556 556
557/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
558
559/*
560 * MPT_SCSI_HOST defines - Used by the IOCTL and the SCSI drivers
561 * Private to the driver.
562 */
563
564#define MPT_HOST_BUS_UNKNOWN (0xFF)
565#define MPT_HOST_TOO_MANY_TM (0x05)
566#define MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
567#define MPT_HOST_NO_CHAIN (0xFFFFFFFF)
568#define MPT_NVRAM_MASK_TIMEOUT (0x000000FF)
569#define MPT_NVRAM_SYNC_MASK (0x0000FF00)
570#define MPT_NVRAM_SYNC_SHIFT (8)
571#define MPT_NVRAM_DISCONNECT_ENABLE (0x00010000)
572#define MPT_NVRAM_ID_SCAN_ENABLE (0x00020000)
573#define MPT_NVRAM_LUN_SCAN_ENABLE (0x00040000)
574#define MPT_NVRAM_TAG_QUEUE_ENABLE (0x00080000)
575#define MPT_NVRAM_WIDE_DISABLE (0x00100000)
576#define MPT_NVRAM_BOOT_CHOICE (0x00200000)
577
578typedef enum {
579 FC,
580 SPI,
581 SAS
582} BUS_TYPE;
583
584typedef struct _MPT_SCSI_HOST {
585 struct _MPT_ADAPTER *ioc;
586 ushort sel_timeout[MPT_MAX_FC_DEVICES];
587 char *info_kbuf;
588 long last_queue_full;
589 u16 spi_pending;
590 struct list_head target_reset_list;
591} MPT_SCSI_HOST;
592
557typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr); 593typedef void (*MPT_ADD_SGE)(void *pAddr, u32 flagslength, dma_addr_t dma_addr);
558typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length, 594typedef void (*MPT_ADD_CHAIN)(void *pAddr, u8 next, u16 length,
559 dma_addr_t dma_addr); 595 dma_addr_t dma_addr);
560typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc); 596typedef void (*MPT_SCHEDULE_TARGET_RESET)(void *ioc);
597typedef void (*MPT_FLUSH_RUNNING_CMDS)(MPT_SCSI_HOST *hd);
561 598
562/* 599/*
563 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS 600 * Adapter Structure - pci_dev specific. Maximum: MPT_MAX_ADAPTERS
@@ -717,6 +754,7 @@ typedef struct _MPT_ADAPTER
717 u8 taskmgmt_quiesce_io; 754 u8 taskmgmt_quiesce_io;
718 u8 ioc_reset_in_progress; 755 u8 ioc_reset_in_progress;
719 MPT_SCHEDULE_TARGET_RESET schedule_target_reset; 756 MPT_SCHEDULE_TARGET_RESET schedule_target_reset;
757 MPT_FLUSH_RUNNING_CMDS schedule_dead_ioc_flush_running_cmds;
720 struct work_struct sas_persist_task; 758 struct work_struct sas_persist_task;
721 759
722 struct work_struct fc_setup_reset_work; 760 struct work_struct fc_setup_reset_work;
@@ -830,19 +868,6 @@ typedef struct _MPT_LOCAL_REPLY {
830 u32 pad; 868 u32 pad;
831} MPT_LOCAL_REPLY; 869} MPT_LOCAL_REPLY;
832 870
833#define MPT_HOST_BUS_UNKNOWN (0xFF)
834#define MPT_HOST_TOO_MANY_TM (0x05)
835#define MPT_HOST_NVRAM_INVALID (0xFFFFFFFF)
836#define MPT_HOST_NO_CHAIN (0xFFFFFFFF)
837#define MPT_NVRAM_MASK_TIMEOUT (0x000000FF)
838#define MPT_NVRAM_SYNC_MASK (0x0000FF00)
839#define MPT_NVRAM_SYNC_SHIFT (8)
840#define MPT_NVRAM_DISCONNECT_ENABLE (0x00010000)
841#define MPT_NVRAM_ID_SCAN_ENABLE (0x00020000)
842#define MPT_NVRAM_LUN_SCAN_ENABLE (0x00040000)
843#define MPT_NVRAM_TAG_QUEUE_ENABLE (0x00080000)
844#define MPT_NVRAM_WIDE_DISABLE (0x00100000)
845#define MPT_NVRAM_BOOT_CHOICE (0x00200000)
846 871
847/* The TM_STATE variable is used to provide strict single threading of TM 872/* The TM_STATE variable is used to provide strict single threading of TM
848 * requests as well as communicate TM error conditions. 873 * requests as well as communicate TM error conditions.
@@ -851,21 +876,6 @@ typedef struct _MPT_LOCAL_REPLY {
851#define TM_STATE_IN_PROGRESS (1) 876#define TM_STATE_IN_PROGRESS (1)
852#define TM_STATE_ERROR (2) 877#define TM_STATE_ERROR (2)
853 878
854typedef enum {
855 FC,
856 SPI,
857 SAS
858} BUS_TYPE;
859
860typedef struct _MPT_SCSI_HOST {
861 MPT_ADAPTER *ioc;
862 ushort sel_timeout[MPT_MAX_FC_DEVICES];
863 char *info_kbuf;
864 long last_queue_full;
865 u16 spi_pending;
866 struct list_head target_reset_list;
867} MPT_SCSI_HOST;
868
869/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ 879/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
870/* 880/*
871 * More Dynamic Multi-Pathing stuff... 881 * More Dynamic Multi-Pathing stuff...
diff --git a/drivers/message/fusion/mptsas.c b/drivers/message/fusion/mptsas.c
index 73229ff9cafa..d21924ba4b1a 100644
--- a/drivers/message/fusion/mptsas.c
+++ b/drivers/message/fusion/mptsas.c
@@ -5147,6 +5147,8 @@ mptsas_probe(struct pci_dev *pdev, const struct pci_device_id *id)
5147 ioc->TaskCtx = mptsasTaskCtx; 5147 ioc->TaskCtx = mptsasTaskCtx;
5148 ioc->InternalCtx = mptsasInternalCtx; 5148 ioc->InternalCtx = mptsasInternalCtx;
5149 ioc->schedule_target_reset = &mptsas_schedule_target_reset; 5149 ioc->schedule_target_reset = &mptsas_schedule_target_reset;
5150 ioc->schedule_dead_ioc_flush_running_cmds =
5151 &mptscsih_flush_running_cmds;
5150 /* Added sanity check on readiness of the MPT adapter. 5152 /* Added sanity check on readiness of the MPT adapter.
5151 */ 5153 */
5152 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) { 5154 if (ioc->last_state != MPI_IOC_STATE_OPERATIONAL) {
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index ce61a5769765..de8cf92d8614 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -1024,7 +1024,7 @@ out:
1024 * 1024 *
1025 * Must be called while new I/Os are being queued. 1025 * Must be called while new I/Os are being queued.
1026 */ 1026 */
1027static void 1027void
1028mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd) 1028mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
1029{ 1029{
1030 MPT_ADAPTER *ioc = hd->ioc; 1030 MPT_ADAPTER *ioc = hd->ioc;
@@ -1055,6 +1055,7 @@ mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd)
1055 sc->scsi_done(sc); 1055 sc->scsi_done(sc);
1056 } 1056 }
1057} 1057}
1058EXPORT_SYMBOL(mptscsih_flush_running_cmds);
1058 1059
1059/* 1060/*
1060 * mptscsih_search_running_cmds - Delete any commands associated 1061 * mptscsih_search_running_cmds - Delete any commands associated
diff --git a/drivers/message/fusion/mptscsih.h b/drivers/message/fusion/mptscsih.h
index 45a5ff3eff61..43e75ff39921 100644
--- a/drivers/message/fusion/mptscsih.h
+++ b/drivers/message/fusion/mptscsih.h
@@ -135,3 +135,4 @@ extern int mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id);
135extern struct device_attribute *mptscsih_host_attrs[]; 135extern struct device_attribute *mptscsih_host_attrs[];
136extern struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i); 136extern struct scsi_cmnd *mptscsih_get_scsi_lookup(MPT_ADAPTER *ioc, int i);
137extern void mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code); 137extern void mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code);
138extern void mptscsih_flush_running_cmds(MPT_SCSI_HOST *hd);