aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/commsup.c
diff options
context:
space:
mode:
authorMark Haverkamp <markh@osdl.org>2005-05-16 21:28:42 -0400
committerJames Bottomley <jejb@mulgrave.(none)>2005-05-20 16:48:00 -0400
commit7c00ffa314bf0fb0e23858bbebad33b48b6abbb9 (patch)
tree4d6b65bb5a2c8fecf48a8c6402c2cc867aa2fe6c /drivers/scsi/aacraid/commsup.c
parent672b2d38da4fff4c4452685a25fb88b65243d1a6 (diff)
[SCSI] 2.6 aacraid: Variable FIB size (updated patch)
New code from the Adaptec driver. Performance enhancement for newer adapters. I hope that this isn't too big for a single patch. I believe that other than the few small cleanups mentioned, that the changes are all related. - Added Variable FIB size negotiation for new adapters. - Added support to maximize scatter gather tables and thus permit requests larger than 64KB/each. - Limit Scatter Gather to 34 elements for ROMB platforms. - aac_printf is only enabled with AAC_QUIRK_34SG - Large FIB ioctl support - some minor cleanup Passes sparse check. I have tested it on x86 and ppc64 machines. Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
Diffstat (limited to 'drivers/scsi/aacraid/commsup.c')
-rw-r--r--drivers/scsi/aacraid/commsup.c85
1 files changed, 50 insertions, 35 deletions
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c
index e2720b7be652..5322865942e2 100644
--- a/drivers/scsi/aacraid/commsup.c
+++ b/drivers/scsi/aacraid/commsup.c
@@ -25,7 +25,7 @@
25 * commsup.c 25 * commsup.c
26 * 26 *
27 * Abstract: Contain all routines that are required for FSA host/adapter 27 * Abstract: Contain all routines that are required for FSA host/adapter
28 * commuication. 28 * communication.
29 * 29 *
30 */ 30 */
31 31
@@ -38,6 +38,7 @@
38#include <linux/slab.h> 38#include <linux/slab.h>
39#include <linux/completion.h> 39#include <linux/completion.h>
40#include <linux/blkdev.h> 40#include <linux/blkdev.h>
41#include <scsi/scsi_host.h>
41#include <asm/semaphore.h> 42#include <asm/semaphore.h>
42 43
43#include "aacraid.h" 44#include "aacraid.h"
@@ -52,7 +53,13 @@
52 53
53static int fib_map_alloc(struct aac_dev *dev) 54static int fib_map_alloc(struct aac_dev *dev)
54{ 55{
55 if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, &dev->hw_fib_pa))==NULL) 56 dprintk((KERN_INFO
57 "allocate hardware fibs pci_alloc_consistent(%p, %d * (%d + %d), %p)\n",
58 dev->pdev, dev->max_fib_size, dev->scsi_host_ptr->can_queue,
59 AAC_NUM_MGT_FIB, &dev->hw_fib_pa));
60 if((dev->hw_fib_va = pci_alloc_consistent(dev->pdev, dev->max_fib_size
61 * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB),
62 &dev->hw_fib_pa))==NULL)
56 return -ENOMEM; 63 return -ENOMEM;
57 return 0; 64 return 0;
58} 65}
@@ -67,7 +74,7 @@ static int fib_map_alloc(struct aac_dev *dev)
67 74
68void fib_map_free(struct aac_dev *dev) 75void fib_map_free(struct aac_dev *dev)
69{ 76{
70 pci_free_consistent(dev->pdev, sizeof(struct hw_fib) * AAC_NUM_FIB, dev->hw_fib_va, dev->hw_fib_pa); 77 pci_free_consistent(dev->pdev, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), dev->hw_fib_va, dev->hw_fib_pa);
71} 78}
72 79
73/** 80/**
@@ -84,17 +91,22 @@ int fib_setup(struct aac_dev * dev)
84 struct hw_fib *hw_fib_va; 91 struct hw_fib *hw_fib_va;
85 dma_addr_t hw_fib_pa; 92 dma_addr_t hw_fib_pa;
86 int i; 93 int i;
87 94
88 if(fib_map_alloc(dev)<0) 95 while (((i = fib_map_alloc(dev)) == -ENOMEM)
96 && (dev->scsi_host_ptr->can_queue > (64 - AAC_NUM_MGT_FIB))) {
97 dev->init->MaxIoCommands = cpu_to_le32((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB) >> 1);
98 dev->scsi_host_ptr->can_queue = le32_to_cpu(dev->init->MaxIoCommands) - AAC_NUM_MGT_FIB;
99 }
100 if (i<0)
89 return -ENOMEM; 101 return -ENOMEM;
90 102
91 hw_fib_va = dev->hw_fib_va; 103 hw_fib_va = dev->hw_fib_va;
92 hw_fib_pa = dev->hw_fib_pa; 104 hw_fib_pa = dev->hw_fib_pa;
93 memset(hw_fib_va, 0, sizeof(struct hw_fib) * AAC_NUM_FIB); 105 memset(hw_fib_va, 0, dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB));
94 /* 106 /*
95 * Initialise the fibs 107 * Initialise the fibs
96 */ 108 */
97 for (i = 0, fibptr = &dev->fibs[i]; i < AAC_NUM_FIB; i++, fibptr++) 109 for (i = 0, fibptr = &dev->fibs[i]; i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); i++, fibptr++)
98 { 110 {
99 fibptr->dev = dev; 111 fibptr->dev = dev;
100 fibptr->hw_fib = hw_fib_va; 112 fibptr->hw_fib = hw_fib_va;
@@ -103,15 +115,15 @@ int fib_setup(struct aac_dev * dev)
103 init_MUTEX_LOCKED(&fibptr->event_wait); 115 init_MUTEX_LOCKED(&fibptr->event_wait);
104 spin_lock_init(&fibptr->event_lock); 116 spin_lock_init(&fibptr->event_lock);
105 hw_fib_va->header.XferState = cpu_to_le32(0xffffffff); 117 hw_fib_va->header.XferState = cpu_to_le32(0xffffffff);
106 hw_fib_va->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); 118 hw_fib_va->header.SenderSize = cpu_to_le16(dev->max_fib_size);
107 fibptr->hw_fib_pa = hw_fib_pa; 119 fibptr->hw_fib_pa = hw_fib_pa;
108 hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + sizeof(struct hw_fib)); 120 hw_fib_va = (struct hw_fib *)((unsigned char *)hw_fib_va + dev->max_fib_size);
109 hw_fib_pa = hw_fib_pa + sizeof(struct hw_fib); 121 hw_fib_pa = hw_fib_pa + dev->max_fib_size;
110 } 122 }
111 /* 123 /*
112 * Add the fib chain to the free list 124 * Add the fib chain to the free list
113 */ 125 */
114 dev->fibs[AAC_NUM_FIB-1].next = NULL; 126 dev->fibs[dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1].next = NULL;
115 /* 127 /*
116 * Enable this to debug out of queue space 128 * Enable this to debug out of queue space
117 */ 129 */
@@ -124,7 +136,7 @@ int fib_setup(struct aac_dev * dev)
124 * @dev: Adapter to allocate the fib for 136 * @dev: Adapter to allocate the fib for
125 * 137 *
126 * Allocate a fib from the adapter fib pool. If the pool is empty we 138 * Allocate a fib from the adapter fib pool. If the pool is empty we
127 * wait for fibs to become free. 139 * return NULL.
128 */ 140 */
129 141
130struct fib * fib_alloc(struct aac_dev *dev) 142struct fib * fib_alloc(struct aac_dev *dev)
@@ -133,10 +145,10 @@ struct fib * fib_alloc(struct aac_dev *dev)
133 unsigned long flags; 145 unsigned long flags;
134 spin_lock_irqsave(&dev->fib_lock, flags); 146 spin_lock_irqsave(&dev->fib_lock, flags);
135 fibptr = dev->free_fib; 147 fibptr = dev->free_fib;
136 /* Cannot sleep here or you get hangs. Instead we did the 148 if(!fibptr){
137 maths at compile time. */ 149 spin_unlock_irqrestore(&dev->fib_lock, flags);
138 if(!fibptr) 150 return fibptr;
139 BUG(); 151 }
140 dev->free_fib = fibptr->next; 152 dev->free_fib = fibptr->next;
141 spin_unlock_irqrestore(&dev->fib_lock, flags); 153 spin_unlock_irqrestore(&dev->fib_lock, flags);
142 /* 154 /*
@@ -196,11 +208,11 @@ void fib_init(struct fib *fibptr)
196 struct hw_fib *hw_fib = fibptr->hw_fib; 208 struct hw_fib *hw_fib = fibptr->hw_fib;
197 209
198 hw_fib->header.StructType = FIB_MAGIC; 210 hw_fib->header.StructType = FIB_MAGIC;
199 hw_fib->header.Size = cpu_to_le16(sizeof(struct hw_fib)); 211 hw_fib->header.Size = cpu_to_le16(fibptr->dev->max_fib_size);
200 hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable); 212 hw_fib->header.XferState = cpu_to_le32(HostOwned | FibInitialized | FibEmpty | FastResponseCapable);
201 hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa); 213 hw_fib->header.SenderFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
202 hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa); 214 hw_fib->header.ReceiverFibAddress = cpu_to_le32(fibptr->hw_fib_pa);
203 hw_fib->header.SenderSize = cpu_to_le16(sizeof(struct hw_fib)); 215 hw_fib->header.SenderSize = cpu_to_le16(fibptr->dev->max_fib_size);
204} 216}
205 217
206/** 218/**
@@ -279,7 +291,7 @@ static int aac_get_entry (struct aac_dev * dev, u32 qid, struct aac_entry **entr
279 } 291 }
280 292
281 if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */ 293 if ((*index + 1) == le32_to_cpu(*(q->headers.consumer))) { /* Queue is full */
282 printk(KERN_WARNING "Queue %d full, %d outstanding.\n", 294 printk(KERN_WARNING "Queue %d full, %u outstanding.\n",
283 qid, q->numpending); 295 qid, q->numpending);
284 return 0; 296 return 0;
285 } else { 297 } else {
@@ -743,22 +755,25 @@ int fib_complete(struct fib * fibptr)
743 755
744void aac_printf(struct aac_dev *dev, u32 val) 756void aac_printf(struct aac_dev *dev, u32 val)
745{ 757{
746 int length = val & 0xffff;
747 int level = (val >> 16) & 0xffff;
748 char *cp = dev->printfbuf; 758 char *cp = dev->printfbuf;
749 759 if (dev->printf_enabled)
750 /* 760 {
751 * The size of the printfbuf is set in port.c 761 int length = val & 0xffff;
752 * There is no variable or define for it 762 int level = (val >> 16) & 0xffff;
753 */ 763
754 if (length > 255) 764 /*
755 length = 255; 765 * The size of the printfbuf is set in port.c
756 if (cp[length] != 0) 766 * There is no variable or define for it
757 cp[length] = 0; 767 */
758 if (level == LOG_AAC_HIGH_ERROR) 768 if (length > 255)
759 printk(KERN_WARNING "aacraid:%s", cp); 769 length = 255;
760 else 770 if (cp[length] != 0)
761 printk(KERN_INFO "aacraid:%s", cp); 771 cp[length] = 0;
772 if (level == LOG_AAC_HIGH_ERROR)
773 printk(KERN_WARNING "aacraid:%s", cp);
774 else
775 printk(KERN_INFO "aacraid:%s", cp);
776 }
762 memset(cp, 0, 256); 777 memset(cp, 0, 256);
763} 778}
764 779