Skip to content

Commit

Permalink
[SCSI] mpt2sas : the sanity check in base_interrupt needs to be on dw…
Browse files Browse the repository at this point in the history
…ord boundary

The poison sanity check on the reply_post_free register needs to be by 32bit,
not 64bit. The poison check is there because its possible that the driver read
the 1st 32bit before the 2nd 32bit has been written to by firmware.  In other
words, this handles race between driver reading the 64 bit register, and it
being dma'd across pci memory from controller firmware as two 32bit pci writes.

Signed-off-by: Eric Moore <eric.moore@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
  • Loading branch information
Eric Moore authored and James Bottomley committed Apr 27, 2009
1 parent fd01825 commit 03ea111
Showing 1 changed file with 12 additions and 3 deletions.
15 changes: 12 additions & 3 deletions drivers/scsi/mpt2sas/mpt2sas_base.c
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,14 @@ _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;
u8 request_desript_type;
u16 smid;
Expand All @@ -656,7 +664,8 @@ _base_interrupt(int irq, void *bus_id)

completed_cmds = 0;
do {
if (ioc->reply_post_free[post_index].Words == ~0ULL)
rd.word = ioc->reply_post_free[post_index].Words;
if (rd.u.low == UINT_MAX || rd.u.high == UINT_MAX)
goto out;
reply = 0;
cb_idx = 0xFF;
Expand Down Expand Up @@ -721,7 +730,7 @@ _base_interrupt(int irq, void *bus_id)
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 = ~0ULL;
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;
Expand Down Expand Up @@ -3068,7 +3077,7 @@ _base_make_ioc_operational(struct MPT2SAS_ADAPTER *ioc, u8 VF_ID,

/* initialize Reply Post Free Queue */
for (i = 0; i < ioc->reply_post_queue_depth; i++)
ioc->reply_post_free[i].Words = ~0ULL;
ioc->reply_post_free[i].Words = ULLONG_MAX;

r = _base_send_ioc_init(ioc, VF_ID, sleep_flag);
if (r)
Expand Down

0 comments on commit 03ea111

Please sign in to comment.