Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=7343eb6570ae3b299e7b5185b139d8335ef60e9b
Commit:     7343eb6570ae3b299e7b5185b139d8335ef60e9b
Parent:     b10c36a57552f03582c0ab3ece04f3cce791922d
Author:     bo yang <[EMAIL PROTECTED]>
AuthorDate: Fri Nov 9 04:35:44 2007 -0500
Committer:  James Bottomley <[EMAIL PROTECTED]>
CommitDate: Fri Jan 11 18:22:43 2008 -0600

    [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 <[EMAIL PROTECTED]>
    Signed-off-by: James Bottomley <[EMAIL PROTECTED]>
---
 drivers/scsi/megaraid/megaraid_sas.c |  122 +++++++++++++++++++---------------
 drivers/scsi/megaraid/megaraid_sas.h |    2 +
 2 files changed, 70 insertions(+), 54 deletions(-)

diff --git a/drivers/scsi/megaraid/megaraid_sas.c 
b/drivers/scsi/megaraid/megaraid_sas.c
index a58ad61..08c3d43 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);
 
 static u32 megasas_dbg_lvl;
 
+static void
+megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd 
*cmd,
+                    u8 alt_status);
+
 /**
  * megasas_get_cmd -   Get a command from the free pool
  * @instance:          Adapter soft state
@@ -887,6 +891,64 @@ static int megasas_slave_configure(struct scsi_device 
*sdev)
 }
 
 /**
+ * megasas_complete_cmd_dpc     -      Returns FW's controller structure
+ * @instance_addr:                     Address of adapter soft state
+ *
+ * Tasklet to complete cmds
+ */
+static void megasas_complete_cmd_dpc(unsigned long instance_addr)
+{
+       u32 producer;
+       u32 consumer;
+       u32 context;
+       struct megasas_cmd *cmd;
+       struct megasas_instance *instance =
+                               (struct megasas_instance *)instance_addr;
+       unsigned long flags;
+
+       /* If we have already declared adapter dead, donot complete cmds */
+       if (instance->hw_crit_error)
+               return;
+
+       spin_lock_irqsave(&instance->completion_lock, flags);
+
+       producer = *instance->producer;
+       consumer = *instance->consumer;
+
+       while (consumer != producer) {
+               context = instance->reply_queue[consumer];
+
+               cmd = instance->cmd_list[context];
+
+               megasas_complete_cmd(instance, cmd, DID_OK);
+
+               consumer++;
+               if (consumer == (instance->max_fw_cmds + 1)) {
+                       consumer = 0;
+               }
+       }
+
+       *instance->consumer = producer;
+
+       spin_unlock_irqrestore(&instance->completion_lock, flags);
+
+       /*
+        * Check if we can restore can_queue
+        */
+       if (instance->flag & MEGASAS_FW_BUSY
+               && time_after(jiffies, instance->last_time + 5 * HZ)
+               && atomic_read(&instance->fw_outstanding) < 17) {
+
+               spin_lock_irqsave(instance->host->host_lock, flags);
+               instance->flag &= ~MEGASAS_FW_BUSY;
+               instance->host->can_queue =
+                               instance->max_fw_cmds - MEGASAS_INT_CMDS;
+
+               spin_unlock_irqrestore(instance->host->host_lock, flags);
+       }
+}
+
+/**
  * megasas_wait_for_outstanding -      Wait for all outstanding cmds
  * @instance:                          Adapter soft state
  *
@@ -909,6 +971,11 @@ static int megasas_wait_for_outstanding(struct 
megasas_instance *instance)
                if (!(i % MEGASAS_RESET_NOTICE_INTERVAL)) {
                        printk(KERN_NOTICE "megasas: [%2d]waiting for %d "
                               "commands to complete\n",i,outstanding);
+                       /*
+                        * Call cmd completion routine. Cmd to be
+                        * be completed directly without depending on isr.
+                        */
+                       megasas_complete_cmd_dpc((unsigned long)instance);
                }
 
                msleep(1000);
@@ -1750,60 +1817,6 @@ megasas_get_ctrl_info(struct megasas_instance *instance,
 }
 
 /**
- * megasas_complete_cmd_dpc     -      Returns FW's controller structure
- * @instance_addr:                     Address of adapter soft state
- *
- * Tasklet to complete cmds
- */
-static void megasas_complete_cmd_dpc(unsigned long instance_addr)
-{
-       u32 producer;
-       u32 consumer;
-       u32 context;
-       struct megasas_cmd *cmd;
-       struct megasas_instance *instance = (struct megasas_instance 
*)instance_addr;
-       unsigned long flags;
-
-       /* If we have already declared adapter dead, donot complete cmds */
-       if (instance->hw_crit_error)
-               return;
-
-       producer = *instance->producer;
-       consumer = *instance->consumer;
-
-       while (consumer != producer) {
-               context = instance->reply_queue[consumer];
-
-               cmd = instance->cmd_list[context];
-
-               megasas_complete_cmd(instance, cmd, DID_OK);
-
-               consumer++;
-               if (consumer == (instance->max_fw_cmds + 1)) {
-                       consumer = 0;
-               }
-       }
-
-       *instance->consumer = producer;
-
-       /*
-        * Check if we can restore can_queue
-        */
-       if (instance->flag & MEGASAS_FW_BUSY
-               && time_after(jiffies, instance->last_time + 5 * HZ)
-               && atomic_read(&instance->fw_outstanding) < 17) {
-
-               spin_lock_irqsave(instance->host->host_lock, flags);
-               instance->flag &= ~MEGASAS_FW_BUSY;
-               instance->host->can_queue =
-                               instance->max_fw_cmds - MEGASAS_INT_CMDS;
-
-               spin_unlock_irqrestore(instance->host->host_lock, flags);
-       }
-
-}
-
-/**
  * megasas_issue_init_mfi -    Initializes the FW
  * @instance:          Adapter soft state
  *
@@ -2395,6 +2408,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct 
pci_device_id *id)
        init_waitqueue_head(&instance->abort_cmd_wait_q);
 
        spin_lock_init(&instance->cmd_pool_lock);
+       spin_lock_init(&instance->completion_lock);
 
        mutex_init(&instance->aen_mutex);
        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 9739023..c3575a3 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -1084,6 +1084,8 @@ struct megasas_instance {
        struct megasas_cmd **cmd_list;
        struct list_head cmd_pool;
        spinlock_t cmd_pool_lock;
+       /* used to synch producer, consumer ptrs in dpc */
+       spinlock_t completion_lock;
        struct dma_pool *frame_dma_pool;
        struct dma_pool *sense_dma_pool;
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to