diff options
author | Ben Collins <bcollins@ubuntu.com> | 2012-06-11 16:14:36 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2012-07-20 03:58:44 -0400 |
commit | b5f1758f221e446c5a2956cf7ffdf62b005f6458 (patch) | |
tree | 032b27507e5521392393f665cf09ee88d784ff7f | |
parent | 30002f1c02ada69342443e7ed5ee9118feb89510 (diff) |
[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: Ben Collins <bcollins@ubuntu.com>
Acked-by: Achim Leubner <Achim_Leubner@pmc-sierra.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
-rw-r--r-- | drivers/scsi/aacraid/comminit.c | 4 | ||||
-rw-r--r-- | drivers/scsi/aacraid/src.c | 46 |
2 files changed, 31 insertions, 19 deletions
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index a35f54ebdce..8e4b525b1b7 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c | |||
@@ -132,8 +132,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co | |||
132 | init->MaxFibSize = cpu_to_le32(dev->max_fib_size); | 132 | init->MaxFibSize = cpu_to_le32(dev->max_fib_size); |
133 | 133 | ||
134 | init->MaxNumAif = cpu_to_le32(dev->max_num_aif); | 134 | init->MaxNumAif = cpu_to_le32(dev->max_num_aif); |
135 | init->HostRRQ_AddrHigh = (u32)((u64)dev->host_rrq_pa >> 32); | 135 | init->HostRRQ_AddrHigh = cpu_to_le32((u32)((u64)dev->host_rrq_pa >> 32)); |
136 | init->HostRRQ_AddrLow = (u32)(dev->host_rrq_pa & 0xffffffff); | 136 | init->HostRRQ_AddrLow = cpu_to_le32((u32)(dev->host_rrq_pa & 0xffffffff)); |
137 | 137 | ||
138 | 138 | ||
139 | /* | 139 | /* |
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 27a3e77de17..0fb1f5507cd 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c | |||
@@ -74,7 +74,7 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
74 | for (;;) { | 74 | for (;;) { |
75 | isFastResponse = 0; | 75 | isFastResponse = 0; |
76 | /* remove toggle bit (31) */ | 76 | /* remove toggle bit (31) */ |
77 | handle = (dev->host_rrq[index] & 0x7fffffff); | 77 | handle = le32_to_cpu(dev->host_rrq[index]) & 0x7fffffff; |
78 | /* check fast response bit (30) */ | 78 | /* check fast response bit (30) */ |
79 | if (handle & 0x40000000) | 79 | if (handle & 0x40000000) |
80 | isFastResponse = 1; | 80 | isFastResponse = 1; |
@@ -389,30 +389,42 @@ static int aac_src_deliver_message(struct fib *fib) | |||
389 | struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; | 389 | struct aac_queue *q = &dev->queues->queue[AdapNormCmdQueue]; |
390 | unsigned long qflags; | 390 | unsigned long qflags; |
391 | u32 fibsize; | 391 | u32 fibsize; |
392 | u64 address; | 392 | dma_addr_t address; |
393 | struct aac_fib_xporthdr *pFibX; | 393 | struct aac_fib_xporthdr *pFibX; |
394 | u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size); | ||
394 | 395 | ||
395 | spin_lock_irqsave(q->lock, qflags); | 396 | spin_lock_irqsave(q->lock, qflags); |
396 | q->numpending++; | 397 | q->numpending++; |
397 | spin_unlock_irqrestore(q->lock, qflags); | 398 | spin_unlock_irqrestore(q->lock, qflags); |
398 | 399 | ||
399 | /* Calculate the amount to the fibsize bits */ | 400 | /* Calculate the amount to the fibsize bits */ |
400 | fibsize = (sizeof(struct aac_fib_xporthdr) + | 401 | fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1; |
401 | fib->hw_fib_va->header.Size + 127) / 128 - 1; | ||
402 | if (fibsize > (ALIGN32 - 1)) | 402 | if (fibsize > (ALIGN32 - 1)) |
403 | fibsize = ALIGN32 - 1; | 403 | return -EMSGSIZE; |
404 | 404 | ||
405 | /* Fill XPORT header */ | 405 | /* Fill XPORT header */ |
406 | pFibX = (struct aac_fib_xporthdr *) | 406 | pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr); |
407 | ((unsigned char *)fib->hw_fib_va - | 407 | /* |
408 | sizeof(struct aac_fib_xporthdr)); | 408 | * This was stored by aac_fib_send() and it is the index into |
409 | pFibX->Handle = fib->hw_fib_va->header.SenderData + 1; | 409 | * dev->fibs. Not sure why we add 1 to it, but I suspect that it's |
410 | pFibX->HostAddress = fib->hw_fib_pa; | 410 | * because it can't be zero when we pass it to the hardware. Note that |
411 | pFibX->Size = fib->hw_fib_va->header.Size; | 411 | * it was stored in native endian, hence the lack of swapping. -- BenC |
412 | address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr); | 412 | */ |
413 | 413 | pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.SenderData + 1); | |
414 | src_writel(dev, MUnit.IQ_H, (u32)(address >> 32)); | 414 | pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa); |
415 | src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize); | 415 | pFibX->Size = cpu_to_le32(hdr_size); |
416 | |||
417 | /* | ||
418 | * The xport header has been 32-byte aligned for us so that fibsize | ||
419 | * can be masked out of this address by hardware. -- BenC | ||
420 | */ | ||
421 | address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr); | ||
422 | if (address & (ALIGN32 - 1)) | ||
423 | return -EINVAL; | ||
424 | address |= fibsize; | ||
425 | src_writel(dev, MUnit.IQ_H, (address >> 32) & 0xffffffff); | ||
426 | src_writel(dev, MUnit.IQ_L, address & 0xffffffff); | ||
427 | |||
416 | return 0; | 428 | return 0; |
417 | } | 429 | } |
418 | 430 | ||