Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b5f1758f authored by Ben Collins's avatar Ben Collins Committed by James Bottomley
Browse files

[SCSI] aacraid: Fix endian issues in core and SRC portions of driver



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: default avatarBen Collins <bcollins@ubuntu.com>
Acked-by: default avatarAchim Leubner <Achim_Leubner@pmc-sierra.com>
Signed-off-by: default avatarJames Bottomley <JBottomley@Parallels.com>
parent 30002f1c
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -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));


	/*
+29 −17
Original line number Diff line number Diff line
@@ -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;
@@ -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;
		return -EMSGSIZE;

	/* 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);
	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;
}