diff options
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r-- | drivers/scsi/aacraid/commsup.c | 41 |
1 files changed, 32 insertions, 9 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 060ac4bd5a14..dd7ad3ba2dad 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -5,7 +5,8 @@ | |||
5 | * based on the old aacraid driver that is.. | 5 | * based on the old aacraid driver that is.. |
6 | * Adaptec aacraid device driver for Linux. | 6 | * Adaptec aacraid device driver for Linux. |
7 | * | 7 | * |
8 | * Copyright (c) 2000-2007 Adaptec, Inc. (aacraid@adaptec.com) | 8 | * Copyright (c) 2000-2010 Adaptec, Inc. |
9 | * 2010 PMC-Sierra, Inc. (aacraid@pmc-sierra.com) | ||
9 | * | 10 | * |
10 | * This program is free software; you can redistribute it and/or modify | 11 | * This program is free software; you can redistribute it and/or modify |
11 | * it under the terms of the GNU General Public License as published by | 12 | * it under the terms of the GNU General Public License as published by |
@@ -63,9 +64,11 @@ static int fib_map_alloc(struct aac_dev *dev) | |||
63 | "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n", | 64 | "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n", |
64 | dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue, | 65 | dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue, |
65 | AAC_NUM_MGT_FIB, &dev->hw_fib_pa)); | 66 | AAC_NUM_MGT_FIB, &dev->hw_fib_pa)); |
66 | if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, dev->max_fib_size | 67 | dev->hw_fib_va = pci_alloc_consistent(dev->pdev, |
67 | * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), | 68 | (dev->max_fib_size + sizeof(struct aac_fib_xporthdr)) |
68 | &dev->hw_fib_pa))==NULL) | 69 | * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) + (ALIGN32 - 1), |
70 | &dev->hw_fib_pa); | ||
71 | if (dev->hw_fib_va == NULL) | ||
69 | return -ENOMEM; | 72 | return -ENOMEM; |
70 | return 0; | 73 | return 0; |
71 | } | 74 | } |
@@ -110,9 +113,22 @@ int aac_fib_setup(struct aac_dev * dev) | |||
110 | if (i<0) | 113 | if (i<0) |
111 | return -ENOMEM; | 114 | return -ENOMEM; |
112 | 115 | ||
116 | /* 32 byte alignment for PMC */ | ||
117 | hw_fib_pa = (dev->hw_fib_pa + (ALIGN32 - 1)) & ~(ALIGN32 - 1); | ||
118 | dev->hw_fib_va = (struct hw_fib *)((unsigned char *)dev->hw_fib_va + | ||
119 | (hw_fib_pa - dev->hw_fib_pa)); | ||
120 | dev->hw_fib_pa = hw_fib_pa; | ||
121 | memset(dev->hw_fib_va, 0, | ||
122 | (dev->max_fib_size + sizeof(struct aac_fib_xporthdr)) * | ||
123 | (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); | ||
124 | |||
125 | /* add Xport header */ | ||
126 | dev->hw_fib_va = (struct hw_fib *)((unsigned char *)dev->hw_fib_va + | ||
127 | sizeof(struct aac_fib_xporthdr)); | ||
128 | dev->hw_fib_pa += sizeof(struct aac_fib_xporthdr); | ||
129 | |||
113 | hw_fib = dev->hw_fib_va; | 130 | hw_fib = dev->hw_fib_va; |
114 | hw_fib_pa = dev->hw_fib_pa; | 131 | hw_fib_pa = dev->hw_fib_pa; |
115 | memset(hw_fib, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)); | ||
116 | /* | 132 | /* |
117 | * Initialise the fibs | 133 | * Initialise the fibs |
118 | */ | 134 | */ |
@@ -129,8 +145,10 @@ int aac_fib_setup(struct aac_dev * dev) | |||
129 | hw_fib->header.XferState = cpu_to_le32(0xffffffff); | 145 | hw_fib->header.XferState = cpu_to_le32(0xffffffff); |
130 | hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size); | 146 | hw_fib->header.SenderSize = cpu_to_le16(dev->max_fib_size); |
131 | fibptr->hw_fib_pa = hw_fib_pa; | 147 | fibptr->hw_fib_pa = hw_fib_pa; |
132 | hw_fib = (struct hw_fib *)((unsigned char *)hw_fib + dev->max_fib_size); | 148 | hw_fib = (struct hw_fib *)((unsigned char *)hw_fib + |
133 | hw_fib_pa = hw_fib_pa + dev->max_fib_size; | 149 | dev->max_fib_size + sizeof(struct aac_fib_xporthdr)); |
150 | hw_fib_pa = hw_fib_pa + | ||
151 | dev->max_fib_size + sizeof(struct aac_fib_xporthdr); | ||
134 | } | 152 | } |
135 | /* | 153 | /* |
136 | * Add the fib chain to the free list | 154 | * Add the fib chain to the free list |
@@ -664,9 +682,14 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
664 | unsigned long nointr = 0; | 682 | unsigned long nointr = 0; |
665 | unsigned long qflags; | 683 | unsigned long qflags; |
666 | 684 | ||
685 | if (dev->comm_interface == AAC_COMM_MESSAGE_TYPE1) { | ||
686 | kfree(hw_fib); | ||
687 | return 0; | ||
688 | } | ||
689 | |||
667 | if (hw_fib->header.XferState == 0) { | 690 | if (hw_fib->header.XferState == 0) { |
668 | if (dev->comm_interface == AAC_COMM_MESSAGE) | 691 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
669 | kfree (hw_fib); | 692 | kfree(hw_fib); |
670 | return 0; | 693 | return 0; |
671 | } | 694 | } |
672 | /* | 695 | /* |
@@ -674,7 +697,7 @@ int aac_fib_adapter_complete(struct fib *fibptr, unsigned short size) | |||
674 | */ | 697 | */ |
675 | if (hw_fib->header.StructType != FIB_MAGIC) { | 698 | if (hw_fib->header.StructType != FIB_MAGIC) { |
676 | if (dev->comm_interface == AAC_COMM_MESSAGE) | 699 | if (dev->comm_interface == AAC_COMM_MESSAGE) |
677 | kfree (hw_fib); | 700 | kfree(hw_fib); |
678 | return -EINVAL; | 701 | return -EINVAL; |
679 | } | 702 | } |
680 | /* | 703 | /* |