Skip to content

Commit

Permalink
[SCSI] aacraid: Fix endian issues in core and SRC portions of driver
Browse files Browse the repository at this point in the history
This may not fix all endian issues in this driver, but it does get the
driver working on PowerPC for a PMC SRC card. So it should at least fix
all the problems in the core and in the SRC support.

[jejb: fix >> 32 breakage reported by Fengguang Wu]
Signed-off-by: Ben Collins <bcollins@ubuntu.com>
Acked-by: Achim Leubner <Achim_Leubner@pmc-sierra.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
  • Loading branch information
Ben Collins authored and James Bottomley committed Jul 20, 2012
1 parent 30002f1 commit b5f1758
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 19 deletions.
4 changes: 2 additions & 2 deletions drivers/scsi/aacraid/comminit.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
init->MaxFibSize = cpu_to_le32(dev->max_fib_size);

init->MaxNumAif = cpu_to_le32(dev->max_num_aif);
init->HostRRQ_AddrHigh = (u32)((u64)dev->host_rrq_pa >> 32);
init->HostRRQ_AddrLow = (u32)(dev->host_rrq_pa & 0xffffffff);
init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32));
init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff));


/*
Expand Down
46 changes: 29 additions & 17 deletions drivers/scsi/aacraid/src.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
for (;;) {
isFastResponse = 0;
/* remove toggle bit (31) */
handle = (dev->host_rrq[index] & 0x7fffffff);
handle = le32_to_cpu(dev->host_rrq[index]) & 0x7fffffff;
/* check fast response bit (30) */
if (handle & 0x40000000)
isFastResponse = 1;
Expand Down Expand Up @@ -389,30 +389,42 @@ static int aac_src_deliver_message(struct fib *fib)
struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue];
unsigned long qflags;
u32 fibsize;
u64 address;
dma_addr_t address;
struct aac_fib_xporthdr *pFibX;
u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size);

spin_lock_irqsave(q->lock, qflags);
q->numpending++;
spin_unlock_irqrestore(q->lock, qflags);

/* Calculate the amount to the fibsize bits */
fibsize = (sizeof(struct aac_fib_xporthdr) +
fib->hw_fib_va->header.Size + 127) / 128 - 1;
fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1;
if (fibsize > (ALIGN32 - 1))
fibsize = ALIGN32 - 1;

/* Fill XPORT header */
pFibX = (struct aac_fib_xporthdr *)
((unsigned char *)fib->hw_fib_va -
sizeof(struct aac_fib_xporthdr));
pFibX->Handle = fib->hw_fib_va->header.SenderData + 1;
pFibX->HostAddress = fib->hw_fib_pa;
pFibX->Size = fib->hw_fib_va->header.Size;
address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr);

src_writel(dev, MUnit.IQ_H, (u32)(address >> 32));
src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize);
return -EMSGSIZE;

/* Fill XPORT header */
pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr);
/*
* This was stored by aac_fib_send() and it is the index into
* dev->fibs. Not sure why we add 1 to it, but I suspect that it's
* because it can't be zero when we pass it to the hardware. Note that
* it was stored in native endian, hence the lack of swapping. -- BenC
*/
pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.SenderData + 1);
pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa);
pFibX->Size = cpu_to_le32(hdr_size);

/*
* The xport header has been 32-byte aligned for us so that fibsize
* can be masked out of this address by hardware. -- BenC
*/
address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr);
if (address & (ALIGN32 - 1))
return -EINVAL;
address |= fibsize;
src_writel(dev, MUnit.IQ_H, (address >> 32) & 0xffffffff);
src_writel(dev, MUnit.IQ_L, address & 0xffffffff);

return 0;
}

Expand Down

0 comments on commit b5f1758

Please sign in to comment.