diff options
Diffstat (limited to 'drivers/scsi/megaraid')
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.c | 66 | ||||
-rw-r--r-- | drivers/scsi/megaraid/megaraid_sas.h | 1 |
2 files changed, 45 insertions, 22 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c index 0791d62b167f..c730bb145436 100644 --- a/drivers/scsi/megaraid/megaraid_sas.c +++ b/drivers/scsi/megaraid/megaraid_sas.c | |||
@@ -1271,11 +1271,6 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, | |||
1271 | static int | 1271 | static int |
1272 | megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) | 1272 | megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) |
1273 | { | 1273 | { |
1274 | u32 producer; | ||
1275 | u32 consumer; | ||
1276 | u32 context; | ||
1277 | struct megasas_cmd *cmd; | ||
1278 | |||
1279 | /* | 1274 | /* |
1280 | * Check if it is our interrupt | 1275 | * Check if it is our interrupt |
1281 | * Clear the interrupt | 1276 | * Clear the interrupt |
@@ -1283,23 +1278,10 @@ megasas_deplete_reply_queue(struct megasas_instance *instance, u8 alt_status) | |||
1283 | if(instance->instancet->clear_intr(instance->reg_set)) | 1278 | if(instance->instancet->clear_intr(instance->reg_set)) |
1284 | return IRQ_NONE; | 1279 | return IRQ_NONE; |
1285 | 1280 | ||
1286 | producer = *instance->producer; | 1281 | /* |
1287 | consumer = *instance->consumer; | 1282 | * Schedule the tasklet for cmd completion |
1288 | 1283 | */ | |
1289 | while (consumer != producer) { | 1284 | tasklet_schedule(&instance->isr_tasklet); |
1290 | context = instance->reply_queue[consumer]; | ||
1291 | |||
1292 | cmd = instance->cmd_list[context]; | ||
1293 | |||
1294 | megasas_complete_cmd(instance, cmd, alt_status); | ||
1295 | |||
1296 | consumer++; | ||
1297 | if (consumer == (instance->max_fw_cmds + 1)) { | ||
1298 | consumer = 0; | ||
1299 | } | ||
1300 | } | ||
1301 | |||
1302 | *instance->consumer = producer; | ||
1303 | 1285 | ||
1304 | return IRQ_HANDLED; | 1286 | return IRQ_HANDLED; |
1305 | } | 1287 | } |
@@ -1742,6 +1724,39 @@ megasas_get_ctrl_info(struct megasas_instance *instance, | |||
1742 | } | 1724 | } |
1743 | 1725 | ||
1744 | /** | 1726 | /** |
1727 | * megasas_complete_cmd_dpc - Returns FW's controller structure | ||
1728 | * @instance_addr: Address of adapter soft state | ||
1729 | * | ||
1730 | * Tasklet to complete cmds | ||
1731 | */ | ||
1732 | void megasas_complete_cmd_dpc(unsigned long instance_addr) | ||
1733 | { | ||
1734 | u32 producer; | ||
1735 | u32 consumer; | ||
1736 | u32 context; | ||
1737 | struct megasas_cmd *cmd; | ||
1738 | struct megasas_instance *instance = (struct megasas_instance *)instance_addr; | ||
1739 | |||
1740 | producer = *instance->producer; | ||
1741 | consumer = *instance->consumer; | ||
1742 | |||
1743 | while (consumer != producer) { | ||
1744 | context = instance->reply_queue[consumer]; | ||
1745 | |||
1746 | cmd = instance->cmd_list[context]; | ||
1747 | |||
1748 | megasas_complete_cmd(instance, cmd, DID_OK); | ||
1749 | |||
1750 | consumer++; | ||
1751 | if (consumer == (instance->max_fw_cmds + 1)) { | ||
1752 | consumer = 0; | ||
1753 | } | ||
1754 | } | ||
1755 | |||
1756 | *instance->consumer = producer; | ||
1757 | } | ||
1758 | |||
1759 | /** | ||
1745 | * megasas_init_mfi - Initializes the FW | 1760 | * megasas_init_mfi - Initializes the FW |
1746 | * @instance: Adapter soft state | 1761 | * @instance: Adapter soft state |
1747 | * | 1762 | * |
@@ -1911,6 +1926,12 @@ static int megasas_init_mfi(struct megasas_instance *instance) | |||
1911 | 1926 | ||
1912 | kfree(ctrl_info); | 1927 | kfree(ctrl_info); |
1913 | 1928 | ||
1929 | /* | ||
1930 | * Setup tasklet for cmd completion | ||
1931 | */ | ||
1932 | |||
1933 | tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc, | ||
1934 | (unsigned long)instance); | ||
1914 | return 0; | 1935 | return 0; |
1915 | 1936 | ||
1916 | fail_fw_init: | 1937 | fail_fw_init: |
@@ -2470,6 +2491,7 @@ static void megasas_detach_one(struct pci_dev *pdev) | |||
2470 | scsi_remove_host(instance->host); | 2491 | scsi_remove_host(instance->host); |
2471 | megasas_flush_cache(instance); | 2492 | megasas_flush_cache(instance); |
2472 | megasas_shutdown_controller(instance); | 2493 | megasas_shutdown_controller(instance); |
2494 | tasklet_kill(&instance->isr_tasklet); | ||
2473 | 2495 | ||
2474 | /* | 2496 | /* |
2475 | * Take the instance off the instance array. Note that we will not | 2497 | * Take the instance off the instance array. Note that we will not |
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index ad7ef7444069..c79e55aa9166 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h | |||
@@ -1102,6 +1102,7 @@ struct megasas_instance { | |||
1102 | u32 hw_crit_error; | 1102 | u32 hw_crit_error; |
1103 | 1103 | ||
1104 | struct megasas_instance_template *instancet; | 1104 | struct megasas_instance_template *instancet; |
1105 | struct tasklet_struct isr_tasklet; | ||
1105 | }; | 1106 | }; |
1106 | 1107 | ||
1107 | #define MEGASAS_IS_LOGICAL(scp) \ | 1108 | #define MEGASAS_IS_LOGICAL(scp) \ |