Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (102 commits) [SCSI] scsi_dh: fix kconfig related build errors [SCSI] sym53c8xx: Fix bogus sym_que_entry re-implementation of container_of [SCSI] scsi_cmnd.h: remove double inclusion of linux/blkdev.h [SCSI] make struct scsi_{host,target}_type static [SCSI] fix locking in host use of blk_plug_device() [SCSI] zfcp: Cleanup external header file [SCSI] zfcp: Cleanup code in zfcp_erp.c [SCSI] zfcp: zfcp_fsf cleanup. [SCSI] zfcp: consolidate sysfs things into one file. [SCSI] zfcp: Cleanup of code in zfcp_aux.c [SCSI] zfcp: Cleanup of code in zfcp_scsi.c [SCSI] zfcp: Move status accessors from zfcp to SCSI include file. [SCSI] zfcp: Small QDIO cleanups [SCSI] zfcp: Adapter reopen for large number of unsolicited status [SCSI] zfcp: Fix error checking for ELS ADISC requests [SCSI] zfcp: wait until adapter is finished with ERP during auto-port [SCSI] ibmvfc: IBM Power Virtual Fibre Channel Adapter Client Driver [SCSI] sg: Add target reset support [SCSI] lib: Add support for the T10 (SCSI) Data Integrity Field CRC [SCSI] sd: Move scsi_disk() accessor function to sd.h ...
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
* For use with LSI PCI chip/adapter(s)
|
||||
* running LSI Fusion MPT (Message Passing Technology) firmware.
|
||||
*
|
||||
* Copyright (c) 1999-2007 LSI Corporation
|
||||
* Copyright (c) 1999-2008 LSI Corporation
|
||||
* (mailto:DL-MPTFusionLinux@lsi.com)
|
||||
*
|
||||
*/
|
||||
@@ -103,7 +103,7 @@ static int mfcounter = 0;
|
||||
* Public data...
|
||||
*/
|
||||
|
||||
struct proc_dir_entry *mpt_proc_root_dir;
|
||||
static struct proc_dir_entry *mpt_proc_root_dir;
|
||||
|
||||
#define WHOINIT_UNKNOWN 0xAA
|
||||
|
||||
@@ -253,6 +253,55 @@ mpt_get_cb_idx(MPT_DRIVER_CLASS dclass)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mpt_fault_reset_work - work performed on workq after ioc fault
|
||||
* @work: input argument, used to derive ioc
|
||||
*
|
||||
**/
|
||||
static void
|
||||
mpt_fault_reset_work(struct work_struct *work)
|
||||
{
|
||||
MPT_ADAPTER *ioc =
|
||||
container_of(work, MPT_ADAPTER, fault_reset_work.work);
|
||||
u32 ioc_raw_state;
|
||||
int rc;
|
||||
unsigned long flags;
|
||||
|
||||
if (ioc->diagPending || !ioc->active)
|
||||
goto out;
|
||||
|
||||
ioc_raw_state = mpt_GetIocState(ioc, 0);
|
||||
if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT) {
|
||||
printk(MYIOC_s_WARN_FMT "IOC is in FAULT state (%04xh)!!!\n",
|
||||
ioc->name, ioc_raw_state & MPI_DOORBELL_DATA_MASK);
|
||||
printk(MYIOC_s_WARN_FMT "Issuing HardReset from %s!!\n",
|
||||
ioc->name, __FUNCTION__);
|
||||
rc = mpt_HardResetHandler(ioc, CAN_SLEEP);
|
||||
printk(MYIOC_s_WARN_FMT "%s: HardReset: %s\n", ioc->name,
|
||||
__FUNCTION__, (rc == 0) ? "success" : "failed");
|
||||
ioc_raw_state = mpt_GetIocState(ioc, 0);
|
||||
if ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_FAULT)
|
||||
printk(MYIOC_s_WARN_FMT "IOC is in FAULT state after "
|
||||
"reset (%04xh)\n", ioc->name, ioc_raw_state &
|
||||
MPI_DOORBELL_DATA_MASK);
|
||||
}
|
||||
|
||||
out:
|
||||
/*
|
||||
* Take turns polling alternate controller
|
||||
*/
|
||||
if (ioc->alt_ioc)
|
||||
ioc = ioc->alt_ioc;
|
||||
|
||||
/* rearm the timer */
|
||||
spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
|
||||
if (ioc->reset_work_q)
|
||||
queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
|
||||
msecs_to_jiffies(MPT_POLLING_INTERVAL));
|
||||
spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Process turbo (context) reply...
|
||||
*/
|
||||
@@ -1616,6 +1665,22 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
/* Find lookup slot. */
|
||||
INIT_LIST_HEAD(&ioc->list);
|
||||
|
||||
|
||||
/* Initialize workqueue */
|
||||
INIT_DELAYED_WORK(&ioc->fault_reset_work, mpt_fault_reset_work);
|
||||
spin_lock_init(&ioc->fault_reset_work_lock);
|
||||
|
||||
snprintf(ioc->reset_work_q_name, KOBJ_NAME_LEN, "mpt_poll_%d", ioc->id);
|
||||
ioc->reset_work_q =
|
||||
create_singlethread_workqueue(ioc->reset_work_q_name);
|
||||
if (!ioc->reset_work_q) {
|
||||
printk(MYIOC_s_ERR_FMT "Insufficient memory to add adapter!\n",
|
||||
ioc->name);
|
||||
pci_release_selected_regions(pdev, ioc->bars);
|
||||
kfree(ioc);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dinitprintk(ioc, printk(MYIOC_s_INFO_FMT "facts @ %p, pfacts[0] @ %p\n",
|
||||
ioc->name, &ioc->facts, &ioc->pfacts[0]));
|
||||
|
||||
@@ -1727,6 +1792,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
iounmap(ioc->memmap);
|
||||
if (r != -5)
|
||||
pci_release_selected_regions(pdev, ioc->bars);
|
||||
|
||||
destroy_workqueue(ioc->reset_work_q);
|
||||
ioc->reset_work_q = NULL;
|
||||
|
||||
kfree(ioc);
|
||||
pci_set_drvdata(pdev, NULL);
|
||||
return r;
|
||||
@@ -1759,6 +1828,10 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (!ioc->alt_ioc)
|
||||
queue_delayed_work(ioc->reset_work_q, &ioc->fault_reset_work,
|
||||
msecs_to_jiffies(MPT_POLLING_INTERVAL));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1774,6 +1847,19 @@ mpt_detach(struct pci_dev *pdev)
|
||||
MPT_ADAPTER *ioc = pci_get_drvdata(pdev);
|
||||
char pname[32];
|
||||
u8 cb_idx;
|
||||
unsigned long flags;
|
||||
struct workqueue_struct *wq;
|
||||
|
||||
/*
|
||||
* Stop polling ioc for fault condition
|
||||
*/
|
||||
spin_lock_irqsave(&ioc->fault_reset_work_lock, flags);
|
||||
wq = ioc->reset_work_q;
|
||||
ioc->reset_work_q = NULL;
|
||||
spin_unlock_irqrestore(&ioc->fault_reset_work_lock, flags);
|
||||
cancel_delayed_work(&ioc->fault_reset_work);
|
||||
destroy_workqueue(wq);
|
||||
|
||||
|
||||
sprintf(pname, MPT_PROCFS_MPTBASEDIR "/%s/summary", ioc->name);
|
||||
remove_proc_entry(pname, NULL);
|
||||
@@ -7456,7 +7542,6 @@ EXPORT_SYMBOL(mpt_resume);
|
||||
EXPORT_SYMBOL(mpt_suspend);
|
||||
#endif
|
||||
EXPORT_SYMBOL(ioc_list);
|
||||
EXPORT_SYMBOL(mpt_proc_root_dir);
|
||||
EXPORT_SYMBOL(mpt_register);
|
||||
EXPORT_SYMBOL(mpt_deregister);
|
||||
EXPORT_SYMBOL(mpt_event_register);
|
||||
|
Reference in New Issue
Block a user