2 * Adaptec AAC series RAID controller driver
3 * (c) Copyright 2001 Red Hat Inc. <alan@redhat.com>
5 * based on the old aacraid driver that is..
6 * Adaptec aacraid device driver for Linux.
8 * Copyright (c) 2000 Adaptec, Inc. (aacraid@adaptec.com)
10 * 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 * the Free Software Foundation; either version 2, or (at your option)
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; see the file COPYING. If not, write to
22 * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
27 * Abstract: This supports the initialization of the host adapter commuication interface.
28 * This is a platform dependent module for the pci cyclone board.
32 #include <linux/kernel.h>
33 #include <linux/init.h>
34 #include <linux/types.h>
35 #include <linux/sched.h>
36 #include <linux/pci.h>
37 #include <linux/spinlock.h>
38 #include <linux/slab.h>
39 #include <linux/blkdev.h>
40 #include <linux/completion.h>
42 #include <scsi/scsi_host.h>
43 #include <asm/semaphore.h>
47 struct aac_common aac_config
= {
51 static int aac_alloc_comm(struct aac_dev
*dev
, void **commaddr
, unsigned long commsize
, unsigned long commalign
)
54 unsigned long size
, align
;
55 const unsigned long fibsize
= 4096;
56 const unsigned long printfbufsiz
= 256;
57 struct aac_init
*init
;
60 size
= fibsize
+ sizeof(struct aac_init
) + commsize
+ commalign
+ printfbufsiz
;
63 base
= pci_alloc_consistent(dev
->pdev
, size
, &phys
);
67 printk(KERN_ERR
"aacraid: unable to create mapping.\n");
70 dev
->comm_addr
= (void *)base
;
71 dev
->comm_phys
= phys
;
72 dev
->comm_size
= size
;
74 dev
->init
= (struct aac_init
*)(base
+ fibsize
);
75 dev
->init_pa
= phys
+ fibsize
;
79 init
->InitStructRevision
= cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION
);
80 if (dev
->max_fib_size
!= sizeof(struct hw_fib
))
81 init
->InitStructRevision
= cpu_to_le32(ADAPTER_INIT_STRUCT_REVISION_4
);
82 init
->MiniPortRevision
= cpu_to_le32(Sa_MINIPORT_REVISION
);
83 init
->fsrev
= cpu_to_le32(dev
->fsrev
);
86 * Adapter Fibs are the first thing allocated so that they
89 dev
->aif_base_va
= (struct hw_fib
*)base
;
91 init
->AdapterFibsVirtualAddress
= 0;
92 init
->AdapterFibsPhysicalAddress
= cpu_to_le32((u32
)phys
);
93 init
->AdapterFibsSize
= cpu_to_le32(fibsize
);
94 init
->AdapterFibAlign
= cpu_to_le32(sizeof(struct hw_fib
));
95 init
->HostPhysMemPages
= cpu_to_le32(AAC_MAX_HOSTPHYSMEMPAGES
);
98 if (dev
->new_comm_interface
) {
99 init
->InitFlags
= cpu_to_le32(INITFLAGS_NEW_COMM_SUPPORTED
);
100 dprintk((KERN_WARNING
"aacraid: New Comm Interface enabled\n"));
102 init
->MaxIoCommands
= cpu_to_le32(dev
->scsi_host_ptr
->can_queue
+ AAC_NUM_MGT_FIB
);
103 init
->MaxIoSize
= cpu_to_le32(dev
->scsi_host_ptr
->max_sectors
<< 9);
104 init
->MaxFibSize
= cpu_to_le32(dev
->max_fib_size
);
107 * Increment the base address by the amount already used
109 base
= base
+ fibsize
+ sizeof(struct aac_init
);
110 phys
= (dma_addr_t
)((ulong
)phys
+ fibsize
+ sizeof(struct aac_init
));
112 * Align the beginning of Headers to commalign
114 align
= (commalign
- ((unsigned long)(base
) & (commalign
- 1)));
118 * Fill in addresses of the Comm Area Headers and Queues
121 init
->CommHeaderAddress
= cpu_to_le32((u32
)phys
);
123 * Increment the base address by the size of the CommArea
125 base
= base
+ commsize
;
126 phys
= phys
+ commsize
;
128 * Place the Printf buffer area after the Fast I/O comm area.
130 dev
->printfbuf
= (void *)base
;
131 init
->printfbuf
= cpu_to_le32(phys
);
132 init
->printfbufsiz
= cpu_to_le32(printfbufsiz
);
133 memset(base
, 0, printfbufsiz
);
137 static void aac_queue_init(struct aac_dev
* dev
, struct aac_queue
* q
, u32
*mem
, int qsize
)
141 init_waitqueue_head(&q
->cmdready
);
142 INIT_LIST_HEAD(&q
->cmdq
);
143 init_waitqueue_head(&q
->qfull
);
144 spin_lock_init(&q
->lockdata
);
145 q
->lock
= &q
->lockdata
;
146 q
->headers
.producer
= (__le32
*)mem
;
147 q
->headers
.consumer
= (__le32
*)(mem
+1);
148 *(q
->headers
.producer
) = cpu_to_le32(qsize
);
149 *(q
->headers
.consumer
) = cpu_to_le32(qsize
);
154 * aac_send_shutdown - shutdown an adapter
155 * @dev: Adapter to shutdown
157 * This routine will send a VM_CloseAll (shutdown) request to the adapter.
160 int aac_send_shutdown(struct aac_dev
* dev
)
163 struct aac_close
*cmd
;
166 fibctx
= aac_fib_alloc(dev
);
169 aac_fib_init(fibctx
);
171 cmd
= (struct aac_close
*) fib_data(fibctx
);
173 cmd
->command
= cpu_to_le32(VM_CloseAll
);
174 cmd
->cid
= cpu_to_le32(0xffffffff);
176 status
= aac_fib_send(ContainerCommand
,
178 sizeof(struct aac_close
),
180 -2 /* Timeout silently */, 1,
184 aac_fib_complete(fibctx
);
185 aac_fib_free(fibctx
);
190 * aac_comm_init - Initialise FSA data structures
191 * @dev: Adapter to initialise
193 * Initializes the data structures that are required for the FSA commuication
194 * interface to operate.
196 * 1 - if we were able to init the commuication interface.
197 * 0 - If there were errors initing. This is a fatal error.
200 static int aac_comm_init(struct aac_dev
* dev
)
202 unsigned long hdrsize
= (sizeof(u32
) * NUMBER_OF_COMM_QUEUES
) * 2;
203 unsigned long queuesize
= sizeof(struct aac_entry
) * TOTAL_QUEUE_ENTRIES
;
205 struct aac_entry
* queues
;
207 struct aac_queue_block
* comm
= dev
->queues
;
209 * Now allocate and initialize the zone structures used as our
210 * pool of FIB context records. The size of the zone is based
211 * on the system memory size. We also initialize the mutex used
212 * to protect the zone.
214 spin_lock_init(&dev
->fib_lock
);
217 * Allocate the physically contigous space for the commuication
221 size
= hdrsize
+ queuesize
;
223 if (!aac_alloc_comm(dev
, (void * *)&headers
, size
, QUEUE_ALIGNMENT
))
226 queues
= (struct aac_entry
*)(((ulong
)headers
) + hdrsize
);
228 /* Adapter to Host normal priority Command queue */
229 comm
->queue
[HostNormCmdQueue
].base
= queues
;
230 aac_queue_init(dev
, &comm
->queue
[HostNormCmdQueue
], headers
, HOST_NORM_CMD_ENTRIES
);
231 queues
+= HOST_NORM_CMD_ENTRIES
;
234 /* Adapter to Host high priority command queue */
235 comm
->queue
[HostHighCmdQueue
].base
= queues
;
236 aac_queue_init(dev
, &comm
->queue
[HostHighCmdQueue
], headers
, HOST_HIGH_CMD_ENTRIES
);
238 queues
+= HOST_HIGH_CMD_ENTRIES
;
241 /* Host to adapter normal priority command queue */
242 comm
->queue
[AdapNormCmdQueue
].base
= queues
;
243 aac_queue_init(dev
, &comm
->queue
[AdapNormCmdQueue
], headers
, ADAP_NORM_CMD_ENTRIES
);
245 queues
+= ADAP_NORM_CMD_ENTRIES
;
248 /* host to adapter high priority command queue */
249 comm
->queue
[AdapHighCmdQueue
].base
= queues
;
250 aac_queue_init(dev
, &comm
->queue
[AdapHighCmdQueue
], headers
, ADAP_HIGH_CMD_ENTRIES
);
252 queues
+= ADAP_HIGH_CMD_ENTRIES
;
255 /* adapter to host normal priority response queue */
256 comm
->queue
[HostNormRespQueue
].base
= queues
;
257 aac_queue_init(dev
, &comm
->queue
[HostNormRespQueue
], headers
, HOST_NORM_RESP_ENTRIES
);
258 queues
+= HOST_NORM_RESP_ENTRIES
;
261 /* adapter to host high priority response queue */
262 comm
->queue
[HostHighRespQueue
].base
= queues
;
263 aac_queue_init(dev
, &comm
->queue
[HostHighRespQueue
], headers
, HOST_HIGH_RESP_ENTRIES
);
265 queues
+= HOST_HIGH_RESP_ENTRIES
;
268 /* host to adapter normal priority response queue */
269 comm
->queue
[AdapNormRespQueue
].base
= queues
;
270 aac_queue_init(dev
, &comm
->queue
[AdapNormRespQueue
], headers
, ADAP_NORM_RESP_ENTRIES
);
272 queues
+= ADAP_NORM_RESP_ENTRIES
;
275 /* host to adapter high priority response queue */
276 comm
->queue
[AdapHighRespQueue
].base
= queues
;
277 aac_queue_init(dev
, &comm
->queue
[AdapHighRespQueue
], headers
, ADAP_HIGH_RESP_ENTRIES
);
279 comm
->queue
[AdapNormCmdQueue
].lock
= comm
->queue
[HostNormRespQueue
].lock
;
280 comm
->queue
[AdapHighCmdQueue
].lock
= comm
->queue
[HostHighRespQueue
].lock
;
281 comm
->queue
[AdapNormRespQueue
].lock
= comm
->queue
[HostNormCmdQueue
].lock
;
282 comm
->queue
[AdapHighRespQueue
].lock
= comm
->queue
[HostHighCmdQueue
].lock
;
287 struct aac_dev
*aac_init_adapter(struct aac_dev
*dev
)
290 struct Scsi_Host
* host
= dev
->scsi_host_ptr
;
293 * Check the preferred comm settings, defaults from template.
295 dev
->max_fib_size
= sizeof(struct hw_fib
);
296 dev
->sg_tablesize
= host
->sg_tablesize
= (dev
->max_fib_size
297 - sizeof(struct aac_fibhdr
)
298 - sizeof(struct aac_write
) + sizeof(struct sgentry
))
299 / sizeof(struct sgentry
);
300 dev
->new_comm_interface
= 0;
302 if ((!aac_adapter_sync_cmd(dev
, GET_ADAPTER_PROPERTIES
,
303 0, 0, 0, 0, 0, 0, status
+0, status
+1, status
+2, NULL
, NULL
)) &&
304 (status
[0] == 0x00000001)) {
305 if (status
[1] & AAC_OPT_NEW_COMM_64
)
307 if (status
[1] & AAC_OPT_NEW_COMM
)
308 dev
->new_comm_interface
= dev
->a_ops
.adapter_send
!= 0;
309 if (dev
->new_comm_interface
&& (status
[2] > dev
->base_size
)) {
310 aac_adapter_ioremap(dev
, 0);
311 dev
->base_size
= status
[2];
312 if (aac_adapter_ioremap(dev
, status
[2])) {
313 /* remap failed, go back ... */
314 dev
->new_comm_interface
= 0;
315 if (aac_adapter_ioremap(dev
, AAC_MIN_FOOTPRINT_SIZE
)) {
317 "aacraid: unable to map adapter.\n");
323 if ((!aac_adapter_sync_cmd(dev
, GET_COMM_PREFERRED_SETTINGS
,
325 status
+0, status
+1, status
+2, status
+3, status
+4))
326 && (status
[0] == 0x00000001)) {
328 * status[1] >> 16 maximum command size in KB
329 * status[1] & 0xFFFF maximum FIB size
330 * status[2] >> 16 maximum SG elements to driver
331 * status[2] & 0xFFFF maximum SG elements from driver
332 * status[3] & 0xFFFF maximum number FIBs outstanding
334 host
->max_sectors
= (status
[1] >> 16) << 1;
335 dev
->max_fib_size
= status
[1] & 0xFFFF;
336 host
->sg_tablesize
= status
[2] >> 16;
337 dev
->sg_tablesize
= status
[2] & 0xFFFF;
338 host
->can_queue
= (status
[3] & 0xFFFF) - AAC_NUM_MGT_FIB
;
341 * All these overrides are based on a fixed internal
342 * knowledge and understanding of existing adapters,
343 * acbsize should be set with caution.
345 if (acbsize
== 512) {
346 host
->max_sectors
= AAC_MAX_32BIT_SGBCOUNT
;
347 dev
->max_fib_size
= 512;
348 dev
->sg_tablesize
= host
->sg_tablesize
349 = (512 - sizeof(struct aac_fibhdr
)
350 - sizeof(struct aac_write
) + sizeof(struct sgentry
))
351 / sizeof(struct sgentry
);
352 host
->can_queue
= AAC_NUM_IO_FIB
;
353 } else if (acbsize
== 2048) {
354 host
->max_sectors
= 512;
355 dev
->max_fib_size
= 2048;
356 host
->sg_tablesize
= 65;
357 dev
->sg_tablesize
= 81;
358 host
->can_queue
= 512 - AAC_NUM_MGT_FIB
;
359 } else if (acbsize
== 4096) {
360 host
->max_sectors
= 1024;
361 dev
->max_fib_size
= 4096;
362 host
->sg_tablesize
= 129;
363 dev
->sg_tablesize
= 166;
364 host
->can_queue
= 256 - AAC_NUM_MGT_FIB
;
365 } else if (acbsize
== 8192) {
366 host
->max_sectors
= 2048;
367 dev
->max_fib_size
= 8192;
368 host
->sg_tablesize
= 257;
369 dev
->sg_tablesize
= 337;
370 host
->can_queue
= 128 - AAC_NUM_MGT_FIB
;
371 } else if (acbsize
> 0) {
372 printk("Illegal acbsize=%d ignored\n", acbsize
);
378 if (numacb
< host
->can_queue
)
379 host
->can_queue
= numacb
;
381 printk("numacb=%d ignored\n", numacb
);
386 * Ok now init the communication subsystem
389 dev
->queues
= kmalloc(sizeof(struct aac_queue_block
), GFP_KERNEL
);
390 if (dev
->queues
== NULL
) {
391 printk(KERN_ERR
"Error could not allocate comm region.\n");
394 memset(dev
->queues
, 0, sizeof(struct aac_queue_block
));
396 if (aac_comm_init(dev
)<0){
401 * Initialize the list of fibs
403 if (aac_fib_setup(dev
) < 0) {
408 INIT_LIST_HEAD(&dev
->fib_list
);