diff options
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_base.c')
-rw-r--r-- | drivers/scsi/mpt2sas/mpt2sas_base.c | 73 |
1 files changed, 33 insertions, 40 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.c b/drivers/scsi/mpt2sas/mpt2sas_base.c index 2e4bc3d2b435..d95d2f274cb3 100644 --- a/drivers/scsi/mpt2sas/mpt2sas_base.c +++ b/drivers/scsi/mpt2sas/mpt2sas_base.c @@ -687,6 +687,14 @@ _base_unmask_interrupts(struct MPT2SAS_ADAPTER *ioc) ioc->mask_interrupts = 0; } +union reply_descriptor { + u64 word; + struct { + u32 low; + u32 high; + } u; +}; + /** * _base_interrupt - MPT adapter (IOC) specific interrupt handler. * @irq: irq number (not used) @@ -698,47 +706,38 @@ _base_unmask_interrupts(struct MPT2SAS_ADAPTER *ioc) static irqreturn_t _base_interrupt(int irq, void *bus_id) { - union reply_descriptor { - u64 word; - struct { - u32 low; - u32 high; - } u; - }; union reply_descriptor rd; - u32 post_index, post_index_next, completed_cmds; + u32 completed_cmds; u8 request_desript_type; u16 smid; u8 cb_idx; u32 reply; u8 VF_ID; - int i; struct MPT2SAS_ADAPTER *ioc = bus_id; + Mpi2ReplyDescriptorsUnion_t *rpf; if (ioc->mask_interrupts) return IRQ_NONE; - post_index = ioc->reply_post_host_index; - request_desript_type = ioc->reply_post_free[post_index]. - Default.ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; + rpf = &ioc->reply_post_free[ioc->reply_post_host_index]; + request_desript_type = rpf->Default.ReplyFlags + & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) return IRQ_NONE; completed_cmds = 0; do { - rd.word = ioc->reply_post_free[post_index].Words; + rd.word = rpf->Words; if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX) goto out; reply = 0; cb_idx = 0xFF; - smid = le16_to_cpu(ioc->reply_post_free[post_index]. - Default.DescriptorTypeDependent1); - VF_ID = ioc->reply_post_free[post_index]. - Default.VF_ID; + smid = le16_to_cpu(rpf->Default.DescriptorTypeDependent1); + VF_ID = rpf->Default.VF_ID; if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_ADDRESS_REPLY) { - reply = le32_to_cpu(ioc->reply_post_free[post_index]. - AddressReply.ReplyFrameAddress); + reply = le32_to_cpu + (rpf->AddressReply.ReplyFrameAddress); } else if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_TARGET_COMMAND_BUFFER) goto next; @@ -765,21 +764,27 @@ _base_interrupt(int irq, void *bus_id) 0 : ioc->reply_free_host_index + 1; ioc->reply_free[ioc->reply_free_host_index] = cpu_to_le32(reply); + wmb(); writel(ioc->reply_free_host_index, &ioc->chip->ReplyFreeHostIndex); - wmb(); } next: - post_index_next = (post_index == (ioc->reply_post_queue_depth - - 1)) ? 0 : post_index + 1; + + rpf->Words = ULLONG_MAX; + ioc->reply_post_host_index = (ioc->reply_post_host_index == + (ioc->reply_post_queue_depth - 1)) ? 0 : + ioc->reply_post_host_index + 1; request_desript_type = - ioc->reply_post_free[post_index_next].Default.ReplyFlags - & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; + ioc->reply_post_free[ioc->reply_post_host_index].Default. + ReplyFlags & MPI2_RPY_DESCRIPT_FLAGS_TYPE_MASK; completed_cmds++; if (request_desript_type == MPI2_RPY_DESCRIPT_FLAGS_UNUSED) goto out; - post_index = post_index_next; + if (!ioc->reply_post_host_index) + rpf = ioc->reply_post_free; + else + rpf++; } while (1); out: @@ -787,19 +792,8 @@ _base_interrupt(int irq, void *bus_id) if (!completed_cmds) return IRQ_NONE; - /* reply post descriptor handling */ - post_index_next = ioc->reply_post_host_index; - for (i = 0 ; i < completed_cmds; i++) { - post_index = post_index_next; - /* poison the reply post descriptor */ - ioc->reply_post_free[post_index_next].Words = ULLONG_MAX; - post_index_next = (post_index == - (ioc->reply_post_queue_depth - 1)) - ? 0 : post_index + 1; - } - ioc->reply_post_host_index = post_index_next; - writel(post_index_next, &ioc->chip->ReplyPostHostIndex); wmb(); + writel(ioc->reply_post_host_index, &ioc->chip->ReplyPostHostIndex); return IRQ_HANDLED; } @@ -1650,7 +1644,7 @@ _base_static_config_pages(struct MPT2SAS_ADAPTER *ioc) iounit_pg1_flags |= MPI2_IOUNITPAGE1_DISABLE_TASK_SET_FULL_HANDLING; ioc->iounit_pg1.Flags = cpu_to_le32(iounit_pg1_flags); - mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, ioc->iounit_pg1); + mpt2sas_config_set_iounit_pg1(ioc, &mpi_reply, &ioc->iounit_pg1); } /** @@ -3306,13 +3300,11 @@ mpt2sas_base_attach(struct MPT2SAS_ADAPTER *ioc) ioc->tm_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ioc->tm_cmds.status = MPT2_CMD_NOT_USED; mutex_init(&ioc->tm_cmds.mutex); - init_completion(&ioc->tm_cmds.done); /* config page internal command bits */ ioc->config_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); ioc->config_cmds.status = MPT2_CMD_NOT_USED; mutex_init(&ioc->config_cmds.mutex); - init_completion(&ioc->config_cmds.done); /* ctl module internal command bits */ ioc->ctl_cmds.reply = kzalloc(ioc->reply_sz, GFP_KERNEL); @@ -3436,6 +3428,7 @@ _base_reset_handler(struct MPT2SAS_ADAPTER *ioc, int reset_phase) if (ioc->config_cmds.status & MPT2_CMD_PENDING) { ioc->config_cmds.status |= MPT2_CMD_RESET; mpt2sas_base_free_smid(ioc, ioc->config_cmds.smid); + ioc->config_cmds.smid = USHORT_MAX; complete(&ioc->config_cmds.done); } break; |