aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/aacraid/comminit.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/aacraid/comminit.c')
-rw-r--r--drivers/scsi/aacraid/comminit.c92
1 files changed, 87 insertions, 5 deletions
diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c
index 6832a55ca907..43557bf661f6 100644
--- a/drivers/scsi/aacraid/comminit.c
+++ b/drivers/scsi/aacraid/comminit.c
@@ -39,6 +39,7 @@
39#include <linux/blkdev.h> 39#include <linux/blkdev.h>
40#include <linux/completion.h> 40#include <linux/completion.h>
41#include <linux/mm.h> 41#include <linux/mm.h>
42#include <scsi/scsi_host.h>
42#include <asm/semaphore.h> 43#include <asm/semaphore.h>
43 44
44#include "aacraid.h" 45#include "aacraid.h"
@@ -49,8 +50,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
49{ 50{
50 unsigned char *base; 51 unsigned char *base;
51 unsigned long size, align; 52 unsigned long size, align;
52 unsigned long fibsize = 4096; 53 const unsigned long fibsize = 4096;
53 unsigned long printfbufsiz = 256; 54 const unsigned long printfbufsiz = 256;
54 struct aac_init *init; 55 struct aac_init *init;
55 dma_addr_t phys; 56 dma_addr_t phys;
56 57
@@ -74,6 +75,8 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
74 init = dev->init; 75 init = dev->init;
75 76
76 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION); 77 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION);
78 if (dev->max_fib_size != sizeof(struct hw_fib))
79 init->InitStructRevision = cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4);
77 init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION); 80 init->MiniPortRevision = cpu_to_le32(Sa_MINIPORT_REVISION);
78 init->fsrev = cpu_to_le32(dev->fsrev); 81 init->fsrev = cpu_to_le32(dev->fsrev);
79 82
@@ -110,6 +113,10 @@ static int aac_alloc_comm(struct aac_dev *dev, void **commaddr, unsigned long co
110 init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES); 113 init->HostPhysMemPages = cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES);
111 } 114 }
112 115
116 init->InitFlags = 0;
117 init->MaxIoCommands = cpu_to_le32(dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB);
118 init->MaxIoSize = cpu_to_le32(dev->scsi_host_ptr->max_sectors << 9);
119 init->MaxFibSize = cpu_to_le32(dev->max_fib_size);
113 120
114 /* 121 /*
115 * Increment the base address by the amount already used 122 * Increment the base address by the amount already used
@@ -152,8 +159,8 @@ static void aac_queue_init(struct aac_dev * dev, struct aac_queue * q, u32 *mem,
152 init_waitqueue_head(&q->qfull); 159 init_waitqueue_head(&q->qfull);
153 spin_lock_init(&q->lockdata); 160 spin_lock_init(&q->lockdata);
154 q->lock = &q->lockdata; 161 q->lock = &q->lockdata;
155 q->headers.producer = mem; 162 q->headers.producer = (__le32 *)mem;
156 q->headers.consumer = mem+1; 163 q->headers.consumer = (__le32 *)(mem+1);
157 *(q->headers.producer) = cpu_to_le32(qsize); 164 *(q->headers.producer) = cpu_to_le32(qsize);
158 *(q->headers.consumer) = cpu_to_le32(qsize); 165 *(q->headers.consumer) = cpu_to_le32(qsize);
159 q->entries = qsize; 166 q->entries = qsize;
@@ -173,6 +180,8 @@ int aac_send_shutdown(struct aac_dev * dev)
173 int status; 180 int status;
174 181
175 fibctx = fib_alloc(dev); 182 fibctx = fib_alloc(dev);
183 if (!fibctx)
184 return -ENOMEM;
176 fib_init(fibctx); 185 fib_init(fibctx);
177 186
178 cmd = (struct aac_close *) fib_data(fibctx); 187 cmd = (struct aac_close *) fib_data(fibctx);
@@ -204,7 +213,7 @@ int aac_send_shutdown(struct aac_dev * dev)
204 * 0 - If there were errors initing. This is a fatal error. 213 * 0 - If there were errors initing. This is a fatal error.
205 */ 214 */
206 215
207int aac_comm_init(struct aac_dev * dev) 216static int aac_comm_init(struct aac_dev * dev)
208{ 217{
209 unsigned long hdrsize = (sizeof(u32) * NUMBER_OF_COMM_QUEUES) * 2; 218 unsigned long hdrsize = (sizeof(u32) * NUMBER_OF_COMM_QUEUES) * 2;
210 unsigned long queuesize = sizeof(struct aac_entry) * TOTAL_QUEUE_ENTRIES; 219 unsigned long queuesize = sizeof(struct aac_entry) * TOTAL_QUEUE_ENTRIES;
@@ -293,6 +302,79 @@ int aac_comm_init(struct aac_dev * dev)
293 302
294struct aac_dev *aac_init_adapter(struct aac_dev *dev) 303struct aac_dev *aac_init_adapter(struct aac_dev *dev)
295{ 304{
305 u32 status[5];
306 struct Scsi_Host * host = dev->scsi_host_ptr;
307
308 /*
309 * Check the preferred comm settings, defaults from template.
310 */
311 dev->max_fib_size = sizeof(struct hw_fib);
312 dev->sg_tablesize = host->sg_tablesize = (dev->max_fib_size
313 - sizeof(struct aac_fibhdr)
314 - sizeof(struct aac_write) + sizeof(struct sgmap))
315 / sizeof(struct sgmap);
316 if ((!aac_adapter_sync_cmd(dev, GET_COMM_PREFERRED_SETTINGS,
317 0, 0, 0, 0, 0, 0,
318 status+0, status+1, status+2, status+3, status+4))
319 && (status[0] == 0x00000001)) {
320 /*
321 * status[1] >> 16 maximum command size in KB
322 * status[1] & 0xFFFF maximum FIB size
323 * status[2] >> 16 maximum SG elements to driver
324 * status[2] & 0xFFFF maximum SG elements from driver
325 * status[3] & 0xFFFF maximum number FIBs outstanding
326 */
327 host->max_sectors = (status[1] >> 16) << 1;
328 dev->max_fib_size = status[1] & 0xFFFF;
329 host->sg_tablesize = status[2] >> 16;
330 dev->sg_tablesize = status[2] & 0xFFFF;
331 host->can_queue = (status[3] & 0xFFFF) - AAC_NUM_MGT_FIB;
332 /*
333 * NOTE:
334 * All these overrides are based on a fixed internal
335 * knowledge and understanding of existing adapters,
336 * acbsize should be set with caution.
337 */
338 if (acbsize == 512) {
339 host->max_sectors = AAC_MAX_32BIT_SGBCOUNT;
340 dev->max_fib_size = 512;
341 dev->sg_tablesize = host->sg_tablesize
342 = (512 - sizeof(struct aac_fibhdr)
343 - sizeof(struct aac_write) + sizeof(struct sgmap))
344 / sizeof(struct sgmap);
345 host->can_queue = AAC_NUM_IO_FIB;
346 } else if (acbsize == 2048) {
347 host->max_sectors = 512;
348 dev->max_fib_size = 2048;
349 host->sg_tablesize = 65;
350 dev->sg_tablesize = 81;
351 host->can_queue = 512 - AAC_NUM_MGT_FIB;
352 } else if (acbsize == 4096) {
353 host->max_sectors = 1024;
354 dev->max_fib_size = 4096;
355 host->sg_tablesize = 129;
356 dev->sg_tablesize = 166;
357 host->can_queue = 256 - AAC_NUM_MGT_FIB;
358 } else if (acbsize == 8192) {
359 host->max_sectors = 2048;
360 dev->max_fib_size = 8192;
361 host->sg_tablesize = 257;
362 dev->sg_tablesize = 337;
363 host->can_queue = 128 - AAC_NUM_MGT_FIB;
364 } else if (acbsize > 0) {
365 printk("Illegal acbsize=%d ignored\n", acbsize);
366 }
367 }
368 {
369
370 if (numacb > 0) {
371 if (numacb < host->can_queue)
372 host->can_queue = numacb;
373 else
374 printk("numacb=%d ignored\n", numacb);
375 }
376 }
377
296 /* 378 /*
297 * Ok now init the communication subsystem 379 * Ok now init the communication subsystem
298 */ 380 */