mpt fusion: [2.6.30-rc6][Reviewed] rewrite taskmgmt request and completion routines
Subsystems (2)
PATCH 7/17 mpt fusion: [2.6.30-rc6][Reviewed] rewrite taskmgmt request and completion routines
1.) rewrite taskmanagement request and completion routines, making them
single threaded and using the generic MPT_MGMT struct, deleting mptscsih_TMHandler, replacing with single request TM handler mptscsih_IssueTaskMgmt, and killing the watchdog timer functions. 2.) cleanup ioc_reset callback handlers, introducing wrappers for synchronizing error recovery (mpt_set_taskmgmt_in_progress_flag, mpt_clear_taskmgmt_in_progress_flag), as the fusion firmware only handles one task management request at a time
---
Signed-off-by Kashyap Desai <[email protected]>
---
drivers/message/fusion/mptbase.c +66 -14
@@ -341,7 +341,7 @@ mpt_fault_reset_work(struct work_struct *work)int rc;unsigned long flags; -if (ioc->diagPending || !ioc->active) +if (ioc->ioc_reset_in_progress || !ioc->active) goto out; ioc_raw_state =mpt_GetIocState (ioc,0 );
@@ -1771,14 +1771,15 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) ioc->reply_sz =MPT_REPLY_FRAME_SIZE ; ioc->pcidev = pdev; - ioc->diagPending =0 ; -spin_lock_init (&ioc->diagLock);spin_lock_init (&ioc->initializing_hba_lock); +spin_lock_init (&ioc->taskmgmt_lock);mutex_init (&ioc->internal_cmds.mutex);init_completion (&ioc->internal_cmds.done);mutex_init (&ioc->mptbase_cmds.mutex);init_completion (&ioc->mptbase_cmds.done); +mutex_init (&ioc->taskmgmt_cmds.mutex); +init_completion (&ioc->taskmgmt_cmds.done);/* Initialize the event logging. */
@@ -6572,6 +6573,53 @@ mpt_print_ioc_summary(MPT_ADAPTER *ioc, char *buffer, int *size, int len, int sh *size = y; } +/** +* mpt_set_taskmgmt_in_progress_flag - set flags associated with task managment +* @ioc: Pointer to MPT_ADAPTER structure +* +* Returns 0 for SUCCESS or -1 if FAILED. +* +* If -1 is return, then it was not possible to set the flags +**/ +int +mpt_set_taskmgmt_in_progress_flag (MPT_ADAPTER *ioc) +{ +unsigned long flags; +int retval; + +spin_lock_irqsave (&ioc->taskmgmt_lock, flags); +if (ioc->ioc_reset_in_progress || ioc->taskmgmt_in_progress || + (ioc->alt_ioc && ioc->alt_ioc->taskmgmt_in_progress)) { + retval =-1 ; + goto out; + } + retval =0 ; + ioc->taskmgmt_in_progress =1 ; +if (ioc->alt_ioc) + ioc->alt_ioc->taskmgmt_in_progress =1 ; + out: +spin_unlock_irqrestore (&ioc->taskmgmt_lock, flags); +return retval; +} +EXPORT_SYMBOL (mpt_set_taskmgmt_in_progress_flag); + +/** +* mpt_clear_taskmgmt_in_progress_flag - clear flags associated with task managment +* @ioc: Pointer to MPT_ADAPTER structure +* +**/ +void +mpt_clear_taskmgmt_in_progress_flag (MPT_ADAPTER *ioc) +{ +unsigned long flags; + +spin_lock_irqsave (&ioc->taskmgmt_lock, flags); + ioc->taskmgmt_in_progress =0 ; +if (ioc->alt_ioc) + ioc->alt_ioc->taskmgmt_in_progress =0 ; +spin_unlock_irqrestore (&ioc->taskmgmt_lock, flags); +} +EXPORT_SYMBOL (mpt_clear_taskmgmt_in_progress_flag);/**
@@ -6638,14 +6686,15 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)/* Reset the adapter. Prevent more than 1 call to * mpt_do_ioc_recovery at any instant in time. */ -spin_lock_irqsave (&ioc->diagLock, flags); -if ((ioc->diagPending) || (ioc->alt_ioc && ioc->alt_ioc->diagPending)){ -spin_unlock_irqrestore (&ioc->diagLock, flags); +spin_lock_irqsave (&ioc->taskmgmt_lock, flags); +if (ioc->ioc_reset_in_progress) { +spin_unlock_irqrestore (&ioc->taskmgmt_lock, flags);return 0 ; - }else { - ioc->diagPending =1 ; } -spin_unlock_irqrestore (&ioc->diagLock, flags); + ioc->ioc_reset_in_progress =1 ; +if (ioc->alt_ioc) + ioc->alt_ioc->ioc_reset_in_progress =1 ; +spin_unlock_irqrestore (&ioc->taskmgmt_lock, flags);/* FIXME: If do_ioc_recovery fails, repeat.... */
@@ -6680,11 +6729,14 @@ mpt_HardResetHandler(MPT_ADAPTER *ioc, int sleepFlag)if (ioc->alt_ioc) ioc->alt_ioc->reload_fw =0 ; -spin_lock_irqsave (&ioc->diagLock, flags); - ioc->diagPending =0 ; -if (ioc->alt_ioc) - ioc->alt_ioc->diagPending =0 ; -spin_unlock_irqrestore (&ioc->diagLock, flags); +spin_lock_irqsave (&ioc->taskmgmt_lock, flags); + ioc->ioc_reset_in_progress =0 ; + ioc->taskmgmt_in_progress =0 ; +if (ioc->alt_ioc) { + ioc->alt_ioc->ioc_reset_in_progress =0 ; + ioc->alt_ioc->taskmgmt_in_progress =0 ; + } +spin_unlock_irqrestore (&ioc->taskmgmt_lock, flags);dtmprintk (ioc,printk (MYIOC_s_DEBUG_FMT"HardResetHandler rc = %d!\n" , ioc->name, rc));
drivers/message/fusion/mptbase.h +6 -2
@@ -657,8 +657,6 @@ typedef struct _MPT_ADAPTERMPT_IOCTL *ioctl;/* ioctl data pointer */ struct proc_dir_entry *ioc_dentry;struct _MPT_ADAPTER *alt_ioc;/* ptr to 929 bound adapter port */ -spinlock_t diagLock;/* diagnostic reset lock */ -int diagPending;u32 biosVersion;/* BIOS version from IO Unit Page 2 */ int eventTypes;/* Event logging parameters */ int eventContext;/* Next event context */
@@ -712,6 +710,10 @@ typedef struct _MPT_ADAPTERMPT_MGMT sas_mgmt;MPT_MGMT mptbase_cmds;/* for sending config pages */ MPT_MGMT internal_cmds; +MPT_MGMT taskmgmt_cmds; +spinlock_t taskmgmt_lock;/* diagnostic reset lock */ +int taskmgmt_in_progress; +u8 ioc_reset_in_progress;struct work_struct sas_persist_task;struct work_struct fc_setup_reset_work;
@@ -931,6 +933,8 @@ extern void mpt_free_fw_memory(MPT_ADAPTER *ioc);extern int mpt_findImVolumes (MPT_ADAPTER *ioc);extern int mptbase_sas_persist_operation (MPT_ADAPTER *ioc,u8 persist_opcode);extern int mpt_raid_phys_disk_pg0 (MPT_ADAPTER *ioc,u8 phys_disk_num,pRaidPhysDiskPage0_t phys_disk); +extern int mpt_set_taskmgmt_in_progress_flag (MPT_ADAPTER *ioc); +extern void mpt_clear_taskmgmt_in_progress_flag (MPT_ADAPTER *ioc);extern void mpt_halt_firmware (MPT_ADAPTER *ioc);
drivers/message/fusion/mptscsih.c +164 -295
595 lines not on this page · raw message
drivers/message/fusion/mptscsih.h +2 -1
@@ -113,6 +113,8 @@ extern int mptscsih_resume(struct pci_dev *pdev);extern int mptscsih_proc_info (struct Scsi_Host *host,char *buffer,char **start,off_t offset,int length,int func);extern const char *mptscsih_info (struct Scsi_Host *SChost);extern int mptscsih_qcmd (struct scsi_cmnd *SCpnt,void (*done)(struct scsi_cmnd *)); +extern int mptscsih_IssueTaskMgmt (MPT_SCSI_HOST *hd,u8 type,u8 channel, +u8 id,int lun,int ctx2abort,ulong timeout);extern void mptscsih_slave_destroy (struct scsi_device *device);extern int mptscsih_slave_configure (struct scsi_device *device);extern int mptscsih_abort (struct scsi_cmnd * SCpnt);
@@ -127,7 +129,6 @@ extern int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEextern int mptscsih_ioc_reset (MPT_ADAPTER *ioc,int post_reset);extern int mptscsih_change_queue_depth (struct scsi_device *sdev,int qdepth);extern void mptscsih_timer_expired (unsigned long data); -extern int mptscsih_TMHandler (MPT_SCSI_HOST *hd,u8 type,u8 channel,u8 id,int lun,int ctx2abort,ulong timeout);extern u8 mptscsih_raid_id_to_num (MPT_ADAPTER *ioc,u8 channel,u8 id);extern int mptscsih_is_phys_disk (MPT_ADAPTER *ioc,u8 channel,u8 id);extern struct device_attribute *mptscsih_host_attrs[];
drivers/message/fusion/mptspi.c +1 -1
@@ -1522,7 +1522,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)* issue internal bus reset */ if (ioc->spi_data.bus_reset) -mptscsih_TMHandler (hd, +mptscsih_IssueTaskMgmt (hd,MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS ,0 ,0 ,0 ,0 ,5 );