diff options
Diffstat (limited to 'drivers/scsi/aacraid/src.c')
-rw-r--r-- | drivers/scsi/aacraid/src.c | 96 |
1 files changed, 58 insertions, 38 deletions
diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 762820636304..3b021ec63255 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c | |||
@@ -56,25 +56,14 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
56 | if (bellbits & PmDoorBellResponseSent) { | 56 | if (bellbits & PmDoorBellResponseSent) { |
57 | bellbits = PmDoorBellResponseSent; | 57 | bellbits = PmDoorBellResponseSent; |
58 | /* handle async. status */ | 58 | /* handle async. status */ |
59 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
60 | src_readl(dev, MUnit.ODR_C); | ||
59 | our_interrupt = 1; | 61 | our_interrupt = 1; |
60 | index = dev->host_rrq_idx; | 62 | index = dev->host_rrq_idx; |
61 | if (dev->host_rrq[index] == 0) { | ||
62 | u32 old_index = index; | ||
63 | /* adjust index */ | ||
64 | do { | ||
65 | index++; | ||
66 | if (index == dev->scsi_host_ptr->can_queue + | ||
67 | AAC_NUM_MGT_FIB) | ||
68 | index = 0; | ||
69 | if (dev->host_rrq[index] != 0) | ||
70 | break; | ||
71 | } while (index != old_index); | ||
72 | dev->host_rrq_idx = index; | ||
73 | } | ||
74 | for (;;) { | 63 | for (;;) { |
75 | isFastResponse = 0; | 64 | isFastResponse = 0; |
76 | /* remove toggle bit (31) */ | 65 | /* remove toggle bit (31) */ |
77 | handle = (dev->host_rrq[index] & 0x7fffffff); | 66 | handle = le32_to_cpu(dev->host_rrq[index]) & 0x7fffffff; |
78 | /* check fast response bit (30) */ | 67 | /* check fast response bit (30) */ |
79 | if (handle & 0x40000000) | 68 | if (handle & 0x40000000) |
80 | isFastResponse = 1; | 69 | isFastResponse = 1; |
@@ -93,6 +82,8 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
93 | } else { | 82 | } else { |
94 | bellbits_shifted = (bellbits >> SRC_ODR_SHIFT); | 83 | bellbits_shifted = (bellbits >> SRC_ODR_SHIFT); |
95 | if (bellbits_shifted & DoorBellAifPending) { | 84 | if (bellbits_shifted & DoorBellAifPending) { |
85 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
86 | src_readl(dev, MUnit.ODR_C); | ||
96 | our_interrupt = 1; | 87 | our_interrupt = 1; |
97 | /* handle AIF */ | 88 | /* handle AIF */ |
98 | aac_intr_normal(dev, 0, 2, 0, NULL); | 89 | aac_intr_normal(dev, 0, 2, 0, NULL); |
@@ -100,6 +91,13 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
100 | unsigned long sflags; | 91 | unsigned long sflags; |
101 | struct list_head *entry; | 92 | struct list_head *entry; |
102 | int send_it = 0; | 93 | int send_it = 0; |
94 | extern int aac_sync_mode; | ||
95 | |||
96 | if (!aac_sync_mode) { | ||
97 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
98 | src_readl(dev, MUnit.ODR_C); | ||
99 | our_interrupt = 1; | ||
100 | } | ||
103 | 101 | ||
104 | if (dev->sync_fib) { | 102 | if (dev->sync_fib) { |
105 | our_interrupt = 1; | 103 | our_interrupt = 1; |
@@ -132,7 +130,6 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) | |||
132 | } | 130 | } |
133 | 131 | ||
134 | if (our_interrupt) { | 132 | if (our_interrupt) { |
135 | src_writel(dev, MUnit.ODR_C, bellbits); | ||
136 | return IRQ_HANDLED; | 133 | return IRQ_HANDLED; |
137 | } | 134 | } |
138 | return IRQ_NONE; | 135 | return IRQ_NONE; |
@@ -336,6 +333,9 @@ static void aac_src_start_adapter(struct aac_dev *dev) | |||
336 | { | 333 | { |
337 | struct aac_init *init; | 334 | struct aac_init *init; |
338 | 335 | ||
336 | /* reset host_rrq_idx first */ | ||
337 | dev->host_rrq_idx = 0; | ||
338 | |||
339 | init = dev->init; | 339 | init = dev->init; |
340 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); | 340 | init->HostElapsedSeconds = cpu_to_le32(get_seconds()); |
341 | 341 | ||
@@ -389,30 +389,51 @@ 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 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE2) { |
400 | fibsize = (sizeof(struct aac_fib_xporthdr) + | 401 | /* Calculate the amount to the fibsize bits */ |
401 | fib->hw_fib_va->header.Size + 127) / 128 - 1; | 402 | fibsize = (hdr_size + 127) / 128 - 1; |
402 | if (fibsize > (ALIGN32 - 1)) | 403 | if (fibsize > (ALIGN32 - 1)) |
403 | fibsize = ALIGN32 - 1; | 404 | return -EMSGSIZE; |
404 | 405 | /* New FIB header, 32-bit */ | |
405 | /* Fill XPORT header */ | 406 | address = fib->hw_fib_pa; |
406 | pFibX = (struct aac_fib_xporthdr *) | 407 | fib->hw_fib_va->header.StructType = FIB_MAGIC2; |
407 | ((unsigned char *)fib->hw_fib_va - | 408 | fib->hw_fib_va->header.SenderFibAddress = (u32)address; |
408 | sizeof(struct aac_fib_xporthdr)); | 409 | fib->hw_fib_va->header.u.TimeStamp = 0; |
409 | pFibX->Handle = fib->hw_fib_va->header.SenderData + 1; | 410 | BUG_ON((u32)(address >> 32) != 0L); |
410 | pFibX->HostAddress = fib->hw_fib_pa; | 411 | address |= fibsize; |
411 | pFibX->Size = fib->hw_fib_va->header.Size; | 412 | } else { |
412 | address = fib->hw_fib_pa - (u64)sizeof(struct aac_fib_xporthdr); | 413 | /* Calculate the amount to the fibsize bits */ |
413 | 414 | fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1; | |
414 | src_writel(dev, MUnit.IQ_H, (u32)(address >> 32)); | 415 | if (fibsize > (ALIGN32 - 1)) |
415 | src_writel(dev, MUnit.IQ_L, (u32)(address & 0xffffffff) + fibsize); | 416 | return -EMSGSIZE; |
417 | |||
418 | /* Fill XPORT header */ | ||
419 | pFibX = (void *)fib->hw_fib_va - sizeof(struct aac_fib_xporthdr); | ||
420 | pFibX->Handle = cpu_to_le32(fib->hw_fib_va->header.Handle); | ||
421 | pFibX->HostAddress = cpu_to_le64(fib->hw_fib_pa); | ||
422 | pFibX->Size = cpu_to_le32(hdr_size); | ||
423 | |||
424 | /* | ||
425 | * The xport header has been 32-byte aligned for us so that fibsize | ||
426 | * can be masked out of this address by hardware. -- BenC | ||
427 | */ | ||
428 | address = fib->hw_fib_pa - sizeof(struct aac_fib_xporthdr); | ||
429 | if (address & (ALIGN32 - 1)) | ||
430 | return -EINVAL; | ||
431 | address |= fibsize; | ||
432 | } | ||
433 | |||
434 | src_writel(dev, MUnit.IQ_H, (address >> 32) & 0xffffffff); | ||
435 | src_writel(dev, MUnit.IQ_L, address & 0xffffffff); | ||
436 | |||
416 | return 0; | 437 | return 0; |
417 | } | 438 | } |
418 | 439 | ||
@@ -435,8 +456,7 @@ static int aac_src_ioremap(struct aac_dev *dev, u32 size) | |||
435 | dev->base = NULL; | 456 | dev->base = NULL; |
436 | if (dev->regs.src.bar1 == NULL) | 457 | if (dev->regs.src.bar1 == NULL) |
437 | return -1; | 458 | return -1; |
438 | dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base, | 459 | dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size); |
439 | size); | ||
440 | if (dev->base == NULL) { | 460 | if (dev->base == NULL) { |
441 | iounmap(dev->regs.src.bar1); | 461 | iounmap(dev->regs.src.bar1); |
442 | dev->regs.src.bar1 = NULL; | 462 | dev->regs.src.bar1 = NULL; |
@@ -459,7 +479,7 @@ static int aac_srcv_ioremap(struct aac_dev *dev, u32 size) | |||
459 | dev->base = dev->regs.src.bar0 = NULL; | 479 | dev->base = dev->regs.src.bar0 = NULL; |
460 | return 0; | 480 | return 0; |
461 | } | 481 | } |
462 | dev->base = dev->regs.src.bar0 = ioremap(dev->scsi_host_ptr->base, size); | 482 | dev->base = dev->regs.src.bar0 = ioremap(dev->base_start, size); |
463 | if (dev->base == NULL) | 483 | if (dev->base == NULL) |
464 | return -1; | 484 | return -1; |
465 | dev->IndexRegs = &((struct src_registers __iomem *) | 485 | dev->IndexRegs = &((struct src_registers __iomem *) |
@@ -753,7 +773,7 @@ int aac_srcv_init(struct aac_dev *dev) | |||
753 | 773 | ||
754 | if (aac_init_adapter(dev) == NULL) | 774 | if (aac_init_adapter(dev) == NULL) |
755 | goto error_iounmap; | 775 | goto error_iounmap; |
756 | if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE1) | 776 | if (dev->comm_interface != AAC_COMM_MESSAGE_TYPE2) |
757 | goto error_iounmap; | 777 | goto error_iounmap; |
758 | dev->msi = aac_msi && !pci_enable_msi(dev->pdev); | 778 | dev->msi = aac_msi && !pci_enable_msi(dev->pdev); |
759 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, | 779 | if (request_irq(dev->pdev->irq, dev->a_ops.adapter_intr, |
@@ -764,7 +784,7 @@ int aac_srcv_init(struct aac_dev *dev) | |||
764 | name, instance); | 784 | name, instance); |
765 | goto error_iounmap; | 785 | goto error_iounmap; |
766 | } | 786 | } |
767 | dev->dbg_base = dev->scsi_host_ptr->base; | 787 | dev->dbg_base = dev->base_start; |
768 | dev->dbg_base_mapped = dev->base; | 788 | dev->dbg_base_mapped = dev->base; |
769 | dev->dbg_size = dev->base_size; | 789 | dev->dbg_size = dev->base_size; |
770 | 790 | ||