[Patch 6/7] megaraid_sas: adds tasklet for cmd completion

From: Sumant Patro
Date: Wed Sep 20 2006 - 21:31:53 EST


This patch adds a tasklet for command completion.

Signed-off-by: Sumant Patro <Sumant.Patro@xxxxxxxx>


diff -uprN linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.c 2006-09-20 15:20:45.000000000 -0700
+++ linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.c 2006-09-20 15:22:28.000000000 -0700
@@ -1273,11 +1273,6 @@ megasas_complete_cmd(struct megasas_inst
static int
megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
{
- u32 producer;
- u32 consumer;
- u32 context;
- struct megasas_cmd *cmd;
-
/*
* Check if it is our interrupt
* Clear the interrupt
@@ -1285,23 +1280,10 @@ megasas_deplete_reply_queue(struct megas
if(instance->instancet->clear_intr(instance->reg_set))
return IRQ_NONE;

- producer = *instance->producer;
- consumer = *instance->consumer;
-
- while (consumer != producer) {
- context = instance->reply_queue[consumer];
-
- cmd = instance->cmd_list[context];
-
- megasas_complete_cmd(instance, cmd, alt_status);
-
- consumer++;
- if (consumer == (instance->max_fw_cmds + 1)) {
- consumer = 0;
- }
- }
-
- *instance->consumer = producer;
+ /*
+ * Schedule the tasklet for cmd completion
+ */
+ tasklet_schedule(&instance->isr_tasklet);

return IRQ_HANDLED;
}
@@ -1744,6 +1726,39 @@ megasas_get_ctrl_info(struct megasas_ins
}

/**
+ * megasas_complete_cmd_dpc - Returns FW's controller structure
+ * @instance_addr: Address of adapter soft state
+ *
+ * Tasklet to complete cmds
+ */
+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;
+
+ 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;
+}
+
+/**
* megasas_init_mfi - Initializes the FW
* @instance: Adapter soft state
*
@@ -1913,6 +1928,12 @@ static int megasas_init_mfi(struct megas

kfree(ctrl_info);

+ /*
+ * Setup tasklet for cmd completion
+ */
+
+ tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
+ (unsigned long)instance);
return 0;

fail_fw_init:
@@ -2502,6 +2523,7 @@ static void megasas_detach_one(struct pc
scsi_remove_host(instance->host);
megasas_flush_cache(instance);
megasas_shutdown_controller(instance);
+ tasklet_kill(&instance->isr_tasklet);

/*
* Take the instance off the instance array. Note that we will not
diff -uprN linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.h 2006-09-20 15:20:45.000000000 -0700
+++ linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.h 2006-09-20 15:22:28.000000000 -0700
@@ -1102,6 +1102,7 @@ struct megasas_instance {
u32 hw_crit_error;

struct megasas_instance_template *instancet;
+ struct tasklet_struct isr_tasklet;
};

#define MEGASAS_IS_LOGICAL(scp) \

diff -uprN linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.c 2006-09-20 15:20:45.000000000 -0700
+++ linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.c 2006-09-20 15:22:28.000000000 -0700
@@ -1273,11 +1273,6 @@ megasas_complete_cmd(struct megasas_inst
static int
megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status)
{
- u32 producer;
- u32 consumer;
- u32 context;
- struct megasas_cmd *cmd;
-
/*
* Check if it is our interrupt
* Clear the interrupt
@@ -1285,23 +1280,10 @@ megasas_deplete_reply_queue(struct megas
if(instance->instancet->clear_intr(instance->reg_set))
return IRQ_NONE;

- producer = *instance->producer;
- consumer = *instance->consumer;
-
- while (consumer != producer) {
- context = instance->reply_queue[consumer];
-
- cmd = instance->cmd_list[context];
-
- megasas_complete_cmd(instance, cmd, alt_status);
-
- consumer++;
- if (consumer == (instance->max_fw_cmds + 1)) {
- consumer = 0;
- }
- }
-
- *instance->consumer = producer;
+ /*
+ * Schedule the tasklet for cmd completion
+ */
+ tasklet_schedule(&instance->isr_tasklet);

return IRQ_HANDLED;
}
@@ -1744,6 +1726,39 @@ megasas_get_ctrl_info(struct megasas_ins
}

/**
+ * megasas_complete_cmd_dpc - Returns FW's controller structure
+ * @instance_addr: Address of adapter soft state
+ *
+ * Tasklet to complete cmds
+ */
+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;
+
+ 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;
+}
+
+/**
* megasas_init_mfi - Initializes the FW
* @instance: Adapter soft state
*
@@ -1913,6 +1928,12 @@ static int megasas_init_mfi(struct megas

kfree(ctrl_info);

+ /*
+ * Setup tasklet for cmd completion
+ */
+
+ tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
+ (unsigned long)instance);
return 0;

fail_fw_init:
@@ -2502,6 +2523,7 @@ static void megasas_detach_one(struct pc
scsi_remove_host(instance->host);
megasas_flush_cache(instance);
megasas_shutdown_controller(instance);
+ tasklet_kill(&instance->isr_tasklet);

/*
* Take the instance off the instance array. Note that we will not
diff -uprN linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6-orig/drivers/scsi/megaraid/megaraid_sas.h 2006-09-20 15:20:45.000000000 -0700
+++ linux-2.6-new/drivers/scsi/megaraid/megaraid_sas.h 2006-09-20 15:22:28.000000000 -0700
@@ -1102,6 +1102,7 @@ struct megasas_instance {
u32 hw_crit_error;

struct megasas_instance_template *instancet;
+ struct tasklet_struct isr_tasklet;
};

#define MEGASAS_IS_LOGICAL(scp) \