aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorbo yang <bo.yang@lsi.com>2007-11-09 04:35:44 -0500
committerJames Bottomley <James.Bottomley@HansenPartnership.com>2008-01-11 19:22:43 -0500
commit7343eb6570ae3b299e7b5185b139d8335ef60e9b (patch)
tree1d2c354b15e7ad00618fcc1c03404125f0aca9e0 /drivers
parentb10c36a57552f03582c0ab3ece04f3cce791922d (diff)
[SCSI] megaraid_sas: call cmd completion from reset
Driver will call cmd completion routine from Reset path without waiting for cmd completion from isr context. Signed-off-by: Bo Yang <bo.yang@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c122
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h2
2 files changed, 70 insertions, 54 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index a58ad61aa36a..08c3d4315eb8 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -77,6 +77,10 @@ static DEFINE_MUTEX(megasas_async_queue_mutex);
77 77
78static u32 megasas_dbg_lvl; 78static u32 megasas_dbg_lvl;
79 79
80static void
81megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
82 u8 alt_status);
83
80/** 84/**
81 * megasas_get_cmd - Get a command from the free pool 85 * megasas_get_cmd - Get a command from the free pool
82 * @instance: Adapter soft state 86 * @instance: Adapter soft state
@@ -887,6 +891,64 @@ static int megasas_slave_configure(struct scsi_device *sdev)
887} 891}
888 892
889/** 893/**
894 * megasas_complete_cmd_dpc - Returns FW's controller structure
895 * @instance_addr: Address of adapter soft state
896 *
897 * Tasklet to complete cmds
898 */
899static void megasas_complete_cmd_dpc(unsigned long instance_addr)
900{
901 u32 producer;
902 u32 consumer;
903 u32 context;
904 struct megasas_cmd *cmd;
905 struct megasas_instance *instance =
906 (struct megasas_instance *)instance_addr;
907 unsigned long flags;
908
909 /* If we have already declared adapter dead, donot complete cmds */
910 if (instance->hw_crit_error)
911 return;
912
913 spin_lock_irqsave(&instance->completion_lock, flags);
914
915 producer = *instance->producer;
916 consumer = *instance->consumer;
917
918 while (consumer != producer) {
919 context = instance->reply_queue[consumer];
920
921 cmd = instance->cmd_list[context];
922
923 megasas_complete_cmd(instance, cmd, DID_OK);
924
925 consumer++;
926 if (consumer == (instance->max_fw_cmds + 1)) {
927 consumer = 0;
928 }
929 }
930
931 *instance->consumer = producer;
932
933 spin_unlock_irqrestore(&instance->completion_lock, flags);
934
935 /*
936 * Check if we can restore can_queue
937 */
938 if (instance->flag & MEGASAS_FW_BUSY
939 && time_after(jiffies, instance->last_time + 5 * HZ)
940 && atomic_read(&instance->fw_outstanding) < 17) {
941
942 spin_lock_irqsave(instance->host->host_lock, flags);
943 instance->flag &= ~MEGASAS_FW_BUSY;
944 instance->host->can_queue =
945 instance->max_fw_cmds - MEGASAS_INT_CMDS;
946
947 spin_unlock_irqrestore(instance->host->host_lock, flags);
948 }
949}
950
951/**
890 * megasas_wait_for_outstanding - Wait for all outstanding cmds 952 * megasas_wait_for_outstanding - Wait for all outstanding cmds
891 * @instance: Adapter soft state 953 * @instance: Adapter soft state
892 * 954 *
@@ -909,6 +971,11 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
909 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) { 971 if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
910 printk(KERN_NOTICE "megasas: [%2d]waiting for %d " 972 printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
911 "commands to complete\n",i,outstanding); 973 "commands to complete\n",i,outstanding);
974 /*
975 * Call cmd completion routine. Cmd to be
976 * be completed directly without depending on isr.
977 */
978 megasas_complete_cmd_dpc((unsigned long)instance);
912 } 979 }
913 980
914 msleep(1000); 981 msleep(1000);
@@ -1750,60 +1817,6 @@ megasas_get_ctrl_info(struct megasas_instance *instance,
1750} 1817}
1751 1818
1752/** 1819/**
1753 * megasas_complete_cmd_dpc - Returns FW's controller structure
1754 * @instance_addr: Address of adapter soft state
1755 *
1756 * Tasklet to complete cmds
1757 */
1758static void megasas_complete_cmd_dpc(unsigned long instance_addr)
1759{
1760 u32 producer;
1761 u32 consumer;
1762 u32 context;
1763 struct megasas_cmd *cmd;
1764 struct megasas_instance *instance = (struct megasas_instance *)instance_addr;
1765 unsigned long flags;
1766
1767 /* If we have already declared adapter dead, donot complete cmds */
1768 if (instance->hw_crit_error)
1769 return;
1770
1771 producer = *instance->producer;
1772 consumer = *instance->consumer;
1773
1774 while (consumer != producer) {
1775 context = instance->reply_queue[consumer];
1776
1777 cmd = instance->cmd_list[context];
1778
1779 megasas_complete_cmd(instance, cmd, DID_OK);
1780
1781 consumer++;
1782 if (consumer == (instance->max_fw_cmds + 1)) {
1783 consumer = 0;
1784 }
1785 }
1786
1787 *instance->consumer = producer;
1788
1789 /*
1790 * Check if we can restore can_queue
1791 */
1792 if (instance->flag & MEGASAS_FW_BUSY
1793 && time_after(jiffies, instance->last_time + 5 * HZ)
1794 && atomic_read(&instance->fw_outstanding) < 17) {
1795
1796 spin_lock_irqsave(instance->host->host_lock, flags);
1797 instance->flag &= ~MEGASAS_FW_BUSY;
1798 instance->host->can_queue =
1799 instance->max_fw_cmds - MEGASAS_INT_CMDS;
1800
1801 spin_unlock_irqrestore(instance->host->host_lock, flags);
1802 }
1803
1804}
1805
1806/**
1807 * megasas_issue_init_mfi - Initializes the FW 1820 * megasas_issue_init_mfi - Initializes the FW
1808 * @instance: Adapter soft state 1821 * @instance: Adapter soft state
1809 * 1822 *
@@ -2395,6 +2408,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
2395 init_waitqueue_head(&instance->abort_cmd_wait_q); 2408 init_waitqueue_head(&instance->abort_cmd_wait_q);
2396 2409
2397 spin_lock_init(&instance->cmd_pool_lock); 2410 spin_lock_init(&instance->cmd_pool_lock);
2411 spin_lock_init(&instance->completion_lock);
2398 2412
2399 mutex_init(&instance->aen_mutex); 2413 mutex_init(&instance->aen_mutex);
2400 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS); 2414 sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 9739023a222c..c3575a304c6a 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1084,6 +1084,8 @@ struct megasas_instance {
1084 struct megasas_cmd **cmd_list; 1084 struct megasas_cmd **cmd_list;
1085 struct list_head cmd_pool; 1085 struct list_head cmd_pool;
1086 spinlock_t cmd_pool_lock; 1086 spinlock_t cmd_pool_lock;
1087 /* used to synch producer, consumer ptrs in dpc */
1088 spinlock_t completion_lock;
1087 struct dma_pool *frame_dma_pool; 1089 struct dma_pool *frame_dma_pool;
1088 struct dma_pool *sense_dma_pool; 1090 struct dma_pool *sense_dma_pool;
1089 1091