Deleted Added
full compact
aac.c (111691) aac.c (111815)
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
1/*-
2 * Copyright (c) 2000 Michael Smith
3 * Copyright (c) 2001 Scott Long
4 * Copyright (c) 2000 BSDi
5 * Copyright (c) 2001 Adaptec, Inc.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $FreeBSD: head/sys/dev/aac/aac.c 111691 2003-03-01 05:07:19Z scottl $
29 * $FreeBSD: head/sys/dev/aac/aac.c 111815 2003-03-03 12:15:54Z phk $
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37
38/* #include <stddef.h> */
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/malloc.h>
42#include <sys/kernel.h>
43#include <sys/kthread.h>
44#include <sys/sysctl.h>
45#include <sys/poll.h>
46
47#include <sys/bus.h>
48#include <sys/conf.h>
49#include <sys/devicestat.h>
50#include <sys/disk.h>
51#include <sys/signalvar.h>
52#include <sys/time.h>
53#include <sys/eventhandler.h>
54
55#include <machine/bus_memio.h>
56#include <machine/bus.h>
57#include <machine/resource.h>
58
59#include <dev/aac/aacreg.h>
60#include <dev/aac/aac_ioctl.h>
61#include <dev/aac/aacvar.h>
62#include <dev/aac/aac_tables.h>
63
64static void aac_startup(void *arg);
65static void aac_add_container(struct aac_softc *sc,
66 struct aac_mntinforesp *mir, int f);
67static void aac_get_bus_info(struct aac_softc *sc);
68
69/* Command Processing */
70static void aac_timeout(struct aac_softc *sc);
71static int aac_start(struct aac_command *cm);
72static void aac_complete(void *context, int pending);
73static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
74static void aac_bio_complete(struct aac_command *cm);
75static int aac_wait_command(struct aac_command *cm, int timeout);
76static void aac_command_thread(struct aac_softc *sc);
77
78/* Command Buffer Management */
79static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
80 int nseg, int error);
81static int aac_alloc_commands(struct aac_softc *sc);
82static void aac_free_commands(struct aac_softc *sc);
83static void aac_map_command(struct aac_command *cm);
84static void aac_unmap_command(struct aac_command *cm);
85
86/* Hardware Interface */
87static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
88 int error);
89static int aac_check_firmware(struct aac_softc *sc);
90static int aac_init(struct aac_softc *sc);
91static int aac_sync_command(struct aac_softc *sc, u_int32_t command,
92 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
93 u_int32_t arg3, u_int32_t *sp);
94static int aac_enqueue_fib(struct aac_softc *sc, int queue,
95 struct aac_command *cm);
96static int aac_dequeue_fib(struct aac_softc *sc, int queue,
97 u_int32_t *fib_size, struct aac_fib **fib_addr);
98static int aac_enqueue_response(struct aac_softc *sc, int queue,
99 struct aac_fib *fib);
100
101/* Falcon/PPC interface */
102static int aac_fa_get_fwstatus(struct aac_softc *sc);
103static void aac_fa_qnotify(struct aac_softc *sc, int qbit);
104static int aac_fa_get_istatus(struct aac_softc *sc);
105static void aac_fa_clear_istatus(struct aac_softc *sc, int mask);
106static void aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
107 u_int32_t arg0, u_int32_t arg1,
108 u_int32_t arg2, u_int32_t arg3);
109static int aac_fa_get_mailboxstatus(struct aac_softc *sc);
110static void aac_fa_set_interrupts(struct aac_softc *sc, int enable);
111
112struct aac_interface aac_fa_interface = {
113 aac_fa_get_fwstatus,
114 aac_fa_qnotify,
115 aac_fa_get_istatus,
116 aac_fa_clear_istatus,
117 aac_fa_set_mailbox,
118 aac_fa_get_mailboxstatus,
119 aac_fa_set_interrupts
120};
121
122/* StrongARM interface */
123static int aac_sa_get_fwstatus(struct aac_softc *sc);
124static void aac_sa_qnotify(struct aac_softc *sc, int qbit);
125static int aac_sa_get_istatus(struct aac_softc *sc);
126static void aac_sa_clear_istatus(struct aac_softc *sc, int mask);
127static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
128 u_int32_t arg0, u_int32_t arg1,
129 u_int32_t arg2, u_int32_t arg3);
130static int aac_sa_get_mailboxstatus(struct aac_softc *sc);
131static void aac_sa_set_interrupts(struct aac_softc *sc, int enable);
132
133struct aac_interface aac_sa_interface = {
134 aac_sa_get_fwstatus,
135 aac_sa_qnotify,
136 aac_sa_get_istatus,
137 aac_sa_clear_istatus,
138 aac_sa_set_mailbox,
139 aac_sa_get_mailboxstatus,
140 aac_sa_set_interrupts
141};
142
143/* i960Rx interface */
144static int aac_rx_get_fwstatus(struct aac_softc *sc);
145static void aac_rx_qnotify(struct aac_softc *sc, int qbit);
146static int aac_rx_get_istatus(struct aac_softc *sc);
147static void aac_rx_clear_istatus(struct aac_softc *sc, int mask);
148static void aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
149 u_int32_t arg0, u_int32_t arg1,
150 u_int32_t arg2, u_int32_t arg3);
151static int aac_rx_get_mailboxstatus(struct aac_softc *sc);
152static void aac_rx_set_interrupts(struct aac_softc *sc, int enable);
153
154struct aac_interface aac_rx_interface = {
155 aac_rx_get_fwstatus,
156 aac_rx_qnotify,
157 aac_rx_get_istatus,
158 aac_rx_clear_istatus,
159 aac_rx_set_mailbox,
160 aac_rx_get_mailboxstatus,
161 aac_rx_set_interrupts
162};
163
164/* Debugging and Diagnostics */
165static void aac_describe_controller(struct aac_softc *sc);
166static char *aac_describe_code(struct aac_code_lookup *table,
167 u_int32_t code);
168
169/* Management Interface */
170static d_open_t aac_open;
171static d_close_t aac_close;
172static d_ioctl_t aac_ioctl;
173static d_poll_t aac_poll;
174static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
175static void aac_handle_aif(struct aac_softc *sc,
176 struct aac_fib *fib);
177static int aac_rev_check(struct aac_softc *sc, caddr_t udata);
178static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
179static int aac_return_aif(struct aac_softc *sc, caddr_t uptr);
180static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
181
182#define AAC_CDEV_MAJOR 150
183
184static struct cdevsw aac_cdevsw = {
30 */
31
32/*
33 * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34 */
35
36#include "opt_aac.h"
37
38/* #include <stddef.h> */
39#include <sys/param.h>
40#include <sys/systm.h>
41#include <sys/malloc.h>
42#include <sys/kernel.h>
43#include <sys/kthread.h>
44#include <sys/sysctl.h>
45#include <sys/poll.h>
46
47#include <sys/bus.h>
48#include <sys/conf.h>
49#include <sys/devicestat.h>
50#include <sys/disk.h>
51#include <sys/signalvar.h>
52#include <sys/time.h>
53#include <sys/eventhandler.h>
54
55#include <machine/bus_memio.h>
56#include <machine/bus.h>
57#include <machine/resource.h>
58
59#include <dev/aac/aacreg.h>
60#include <dev/aac/aac_ioctl.h>
61#include <dev/aac/aacvar.h>
62#include <dev/aac/aac_tables.h>
63
64static void aac_startup(void *arg);
65static void aac_add_container(struct aac_softc *sc,
66 struct aac_mntinforesp *mir, int f);
67static void aac_get_bus_info(struct aac_softc *sc);
68
69/* Command Processing */
70static void aac_timeout(struct aac_softc *sc);
71static int aac_start(struct aac_command *cm);
72static void aac_complete(void *context, int pending);
73static int aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
74static void aac_bio_complete(struct aac_command *cm);
75static int aac_wait_command(struct aac_command *cm, int timeout);
76static void aac_command_thread(struct aac_softc *sc);
77
78/* Command Buffer Management */
79static void aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
80 int nseg, int error);
81static int aac_alloc_commands(struct aac_softc *sc);
82static void aac_free_commands(struct aac_softc *sc);
83static void aac_map_command(struct aac_command *cm);
84static void aac_unmap_command(struct aac_command *cm);
85
86/* Hardware Interface */
87static void aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
88 int error);
89static int aac_check_firmware(struct aac_softc *sc);
90static int aac_init(struct aac_softc *sc);
91static int aac_sync_command(struct aac_softc *sc, u_int32_t command,
92 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
93 u_int32_t arg3, u_int32_t *sp);
94static int aac_enqueue_fib(struct aac_softc *sc, int queue,
95 struct aac_command *cm);
96static int aac_dequeue_fib(struct aac_softc *sc, int queue,
97 u_int32_t *fib_size, struct aac_fib **fib_addr);
98static int aac_enqueue_response(struct aac_softc *sc, int queue,
99 struct aac_fib *fib);
100
101/* Falcon/PPC interface */
102static int aac_fa_get_fwstatus(struct aac_softc *sc);
103static void aac_fa_qnotify(struct aac_softc *sc, int qbit);
104static int aac_fa_get_istatus(struct aac_softc *sc);
105static void aac_fa_clear_istatus(struct aac_softc *sc, int mask);
106static void aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
107 u_int32_t arg0, u_int32_t arg1,
108 u_int32_t arg2, u_int32_t arg3);
109static int aac_fa_get_mailboxstatus(struct aac_softc *sc);
110static void aac_fa_set_interrupts(struct aac_softc *sc, int enable);
111
112struct aac_interface aac_fa_interface = {
113 aac_fa_get_fwstatus,
114 aac_fa_qnotify,
115 aac_fa_get_istatus,
116 aac_fa_clear_istatus,
117 aac_fa_set_mailbox,
118 aac_fa_get_mailboxstatus,
119 aac_fa_set_interrupts
120};
121
122/* StrongARM interface */
123static int aac_sa_get_fwstatus(struct aac_softc *sc);
124static void aac_sa_qnotify(struct aac_softc *sc, int qbit);
125static int aac_sa_get_istatus(struct aac_softc *sc);
126static void aac_sa_clear_istatus(struct aac_softc *sc, int mask);
127static void aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
128 u_int32_t arg0, u_int32_t arg1,
129 u_int32_t arg2, u_int32_t arg3);
130static int aac_sa_get_mailboxstatus(struct aac_softc *sc);
131static void aac_sa_set_interrupts(struct aac_softc *sc, int enable);
132
133struct aac_interface aac_sa_interface = {
134 aac_sa_get_fwstatus,
135 aac_sa_qnotify,
136 aac_sa_get_istatus,
137 aac_sa_clear_istatus,
138 aac_sa_set_mailbox,
139 aac_sa_get_mailboxstatus,
140 aac_sa_set_interrupts
141};
142
143/* i960Rx interface */
144static int aac_rx_get_fwstatus(struct aac_softc *sc);
145static void aac_rx_qnotify(struct aac_softc *sc, int qbit);
146static int aac_rx_get_istatus(struct aac_softc *sc);
147static void aac_rx_clear_istatus(struct aac_softc *sc, int mask);
148static void aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
149 u_int32_t arg0, u_int32_t arg1,
150 u_int32_t arg2, u_int32_t arg3);
151static int aac_rx_get_mailboxstatus(struct aac_softc *sc);
152static void aac_rx_set_interrupts(struct aac_softc *sc, int enable);
153
154struct aac_interface aac_rx_interface = {
155 aac_rx_get_fwstatus,
156 aac_rx_qnotify,
157 aac_rx_get_istatus,
158 aac_rx_clear_istatus,
159 aac_rx_set_mailbox,
160 aac_rx_get_mailboxstatus,
161 aac_rx_set_interrupts
162};
163
164/* Debugging and Diagnostics */
165static void aac_describe_controller(struct aac_softc *sc);
166static char *aac_describe_code(struct aac_code_lookup *table,
167 u_int32_t code);
168
169/* Management Interface */
170static d_open_t aac_open;
171static d_close_t aac_close;
172static d_ioctl_t aac_ioctl;
173static d_poll_t aac_poll;
174static int aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
175static void aac_handle_aif(struct aac_softc *sc,
176 struct aac_fib *fib);
177static int aac_rev_check(struct aac_softc *sc, caddr_t udata);
178static int aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
179static int aac_return_aif(struct aac_softc *sc, caddr_t uptr);
180static int aac_query_disk(struct aac_softc *sc, caddr_t uptr);
181
182#define AAC_CDEV_MAJOR 150
183
184static struct cdevsw aac_cdevsw = {
185 aac_open, /* open */
186 aac_close, /* close */
187 noread, /* read */
188 nowrite, /* write */
189 aac_ioctl, /* ioctl */
190 aac_poll, /* poll */
191 nommap, /* mmap */
192 nostrategy, /* strategy */
193 "aac", /* name */
194 AAC_CDEV_MAJOR, /* major */
195 nodump, /* dump */
196 nopsize, /* psize */
197 0, /* flags */
185 .d_open = aac_open,
186 .d_close = aac_close,
187 .d_ioctl = aac_ioctl,
188 .d_poll = aac_poll,
189 .d_name = "aac",
190 .d_maj = AAC_CDEV_MAJOR,
198};
199
200MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
201
202/* sysctl node */
203SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
204
205/*
206 * Device Interface
207 */
208
209/*
210 * Initialise the controller and softc
211 */
212int
213aac_attach(struct aac_softc *sc)
214{
215 int error, unit;
216
217 debug_called(1);
218
219 /*
220 * Initialise per-controller queues.
221 */
222 aac_initq_free(sc);
223 aac_initq_ready(sc);
224 aac_initq_busy(sc);
225 aac_initq_bio(sc);
226
227 /*
228 * Initialise command-completion task.
229 */
230 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
231
232 /* disable interrupts before we enable anything */
233 AAC_MASK_INTERRUPTS(sc);
234
235 /* mark controller as suspended until we get ourselves organised */
236 sc->aac_state |= AAC_STATE_SUSPEND;
237
238 /*
239 * Check that the firmware on the card is supported.
240 */
241 if ((error = aac_check_firmware(sc)) != 0)
242 return(error);
243
244 /* Init the sync fib lock */
245 AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock");
246
247 /*
248 * Initialise the adapter.
249 */
250 if ((error = aac_init(sc)) != 0)
251 return(error);
252
253 /*
254 * Print a little information about the controller.
255 */
256 aac_describe_controller(sc);
257
258 /*
259 * Initialize locks
260 */
261 AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock");
262 TAILQ_INIT(&sc->aac_container_tqh);
263 AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
264 AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock");
265
266 /*
267 * Register to probe our containers later.
268 */
269 sc->aac_ich.ich_func = aac_startup;
270 sc->aac_ich.ich_arg = sc;
271 if (config_intrhook_establish(&sc->aac_ich) != 0) {
272 device_printf(sc->aac_dev,
273 "can't establish configuration hook\n");
274 return(ENXIO);
275 }
276
277 /*
278 * Make the control device.
279 */
280 unit = device_get_unit(sc->aac_dev);
281 sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_OPERATOR,
282 0640, "aac%d", unit);
283 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
284 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
285 sc->aac_dev_t->si_drv1 = sc;
286
287 /* Create the AIF thread */
288 if (kthread_create((void(*)(void *))aac_command_thread, sc,
289 &sc->aifthread, 0, 0, "aac%daif", unit))
290 panic("Could not create AIF thread\n");
291
292 /* Register the shutdown method to only be called post-dump */
293 if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
294 sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
295 device_printf(sc->aac_dev,
296 "shutdown event registration failed\n");
297
298 /* Register with CAM for the non-DASD devices */
299 if (!(sc->quirks & AAC_QUIRK_NOCAM)) {
300 TAILQ_INIT(&sc->aac_sim_tqh);
301 aac_get_bus_info(sc);
302 }
303
304 return(0);
305}
306
307/*
308 * Probe for containers, create disks.
309 */
310static void
311aac_startup(void *arg)
312{
313 struct aac_softc *sc;
314 struct aac_fib *fib;
315 struct aac_mntinfo *mi;
316 struct aac_mntinforesp *mir = NULL;
317 int i = 0;
318
319 debug_called(1);
320
321 sc = (struct aac_softc *)arg;
322
323 /* disconnect ourselves from the intrhook chain */
324 config_intrhook_disestablish(&sc->aac_ich);
325
326 aac_alloc_sync_fib(sc, &fib, 0);
327 mi = (struct aac_mntinfo *)&fib->data[0];
328
329 /* loop over possible containers */
330 do {
331 /* request information on this container */
332 bzero(mi, sizeof(struct aac_mntinfo));
333 mi->Command = VM_NameServe;
334 mi->MntType = FT_FILESYS;
335 mi->MntCount = i;
336 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
337 sizeof(struct aac_mntinfo))) {
338 debug(2, "error probing container %d", i);
339 continue;
340 }
341
342 mir = (struct aac_mntinforesp *)&fib->data[0];
343 aac_add_container(sc, mir, 0);
344 i++;
345 } while ((i < mir->MntRespCount) && (i < AAC_MAX_CONTAINERS));
346
347 aac_release_sync_fib(sc);
348
349 /* poke the bus to actually attach the child devices */
350 if (bus_generic_attach(sc->aac_dev))
351 device_printf(sc->aac_dev, "bus_generic_attach failed\n");
352
353 /* mark the controller up */
354 sc->aac_state &= ~AAC_STATE_SUSPEND;
355
356 /* enable interrupts now */
357 AAC_UNMASK_INTERRUPTS(sc);
358}
359
360/*
361 * Create a device to respresent a new container
362 */
363static void
364aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
365{
366 struct aac_container *co;
367 device_t child;
368
369 /*
370 * Check container volume type for validity. Note that many of
371 * the possible types may never show up.
372 */
373 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
374 co = (struct aac_container *)malloc(sizeof *co, M_AACBUF,
375 M_NOWAIT | M_ZERO);
376 if (co == NULL)
377 panic("Out of memory?!\n");
378 debug(1, "id %x name '%.16s' size %u type %d",
379 mir->MntTable[0].ObjectId,
380 mir->MntTable[0].FileSystemName,
381 mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
382
383 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
384 device_printf(sc->aac_dev, "device_add_child failed\n");
385 else
386 device_set_ivars(child, co);
387 device_set_desc(child, aac_describe_code(aac_container_types,
388 mir->MntTable[0].VolType));
389 co->co_disk = child;
390 co->co_found = f;
391 bcopy(&mir->MntTable[0], &co->co_mntobj,
392 sizeof(struct aac_mntobj));
393 AAC_LOCK_ACQUIRE(&sc->aac_container_lock);
394 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
395 AAC_LOCK_RELEASE(&sc->aac_container_lock);
396 }
397}
398
399/*
400 * Free all of the resources associated with (sc)
401 *
402 * Should not be called if the controller is active.
403 */
404void
405aac_free(struct aac_softc *sc)
406{
407
408 debug_called(1);
409
410 /* remove the control device */
411 if (sc->aac_dev_t != NULL)
412 destroy_dev(sc->aac_dev_t);
413
414 /* throw away any FIB buffers, discard the FIB DMA tag */
415 aac_free_commands(sc);
416 if (sc->aac_fib_dmat)
417 bus_dma_tag_destroy(sc->aac_fib_dmat);
418
419 free(sc->aac_commands, M_AACBUF);
420
421 /* destroy the common area */
422 if (sc->aac_common) {
423 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
424 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
425 sc->aac_common_dmamap);
426 }
427 if (sc->aac_common_dmat)
428 bus_dma_tag_destroy(sc->aac_common_dmat);
429
430 /* disconnect the interrupt handler */
431 if (sc->aac_intr)
432 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
433 if (sc->aac_irq != NULL)
434 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
435 sc->aac_irq);
436
437 /* destroy data-transfer DMA tag */
438 if (sc->aac_buffer_dmat)
439 bus_dma_tag_destroy(sc->aac_buffer_dmat);
440
441 /* destroy the parent DMA tag */
442 if (sc->aac_parent_dmat)
443 bus_dma_tag_destroy(sc->aac_parent_dmat);
444
445 /* release the register window mapping */
446 if (sc->aac_regs_resource != NULL)
447 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
448 sc->aac_regs_rid, sc->aac_regs_resource);
449}
450
451/*
452 * Disconnect from the controller completely, in preparation for unload.
453 */
454int
455aac_detach(device_t dev)
456{
457 struct aac_softc *sc;
458 struct aac_container *co;
459 struct aac_sim *sim;
460 int error;
461
462 debug_called(1);
463
464 sc = device_get_softc(dev);
465
466 if (sc->aac_state & AAC_STATE_OPEN)
467 return(EBUSY);
468
469 /* Remove the child containers */
470 while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
471 error = device_delete_child(dev, co->co_disk);
472 if (error)
473 return (error);
474 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
475 free(co, M_AACBUF);
476 }
477
478 /* Remove the CAM SIMs */
479 while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
480 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
481 error = device_delete_child(dev, sim->sim_dev);
482 if (error)
483 return (error);
484 free(sim, M_AACBUF);
485 }
486
487 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
488 sc->aifflags |= AAC_AIFFLAGS_EXIT;
489 wakeup(sc->aifthread);
490 tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
491 }
492
493 if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
494 panic("Cannot shutdown AIF thread\n");
495
496 if ((error = aac_shutdown(dev)))
497 return(error);
498
499 EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
500
501 aac_free(sc);
502
503 return(0);
504}
505
506/*
507 * Bring the controller down to a dormant state and detach all child devices.
508 *
509 * This function is called before detach or system shutdown.
510 *
511 * Note that we can assume that the bioq on the controller is empty, as we won't
512 * allow shutdown if any device is open.
513 */
514int
515aac_shutdown(device_t dev)
516{
517 struct aac_softc *sc;
518 struct aac_fib *fib;
519 struct aac_close_command *cc;
520
521 debug_called(1);
522
523 sc = device_get_softc(dev);
524
525 sc->aac_state |= AAC_STATE_SUSPEND;
526
527 /*
528 * Send a Container shutdown followed by a HostShutdown FIB to the
529 * controller to convince it that we don't want to talk to it anymore.
530 * We've been closed and all I/O completed already
531 */
532 device_printf(sc->aac_dev, "shutting down controller...");
533
534 aac_alloc_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE);
535 cc = (struct aac_close_command *)&fib->data[0];
536
537 bzero(cc, sizeof(struct aac_close_command));
538 cc->Command = VM_CloseAll;
539 cc->ContainerId = 0xffffffff;
540 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
541 sizeof(struct aac_close_command)))
542 printf("FAILED.\n");
543 else
544 printf("done\n");
545#if 0
546 else {
547 fib->data[0] = 0;
548 /*
549 * XXX Issuing this command to the controller makes it shut down
550 * but also keeps it from coming back up without a reset of the
551 * PCI bus. This is not desirable if you are just unloading the
552 * driver module with the intent to reload it later.
553 */
554 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
555 fib, 1)) {
556 printf("FAILED.\n");
557 } else {
558 printf("done.\n");
559 }
560 }
561#endif
562
563 AAC_MASK_INTERRUPTS(sc);
564
565 return(0);
566}
567
568/*
569 * Bring the controller to a quiescent state, ready for system suspend.
570 */
571int
572aac_suspend(device_t dev)
573{
574 struct aac_softc *sc;
575
576 debug_called(1);
577
578 sc = device_get_softc(dev);
579
580 sc->aac_state |= AAC_STATE_SUSPEND;
581
582 AAC_MASK_INTERRUPTS(sc);
583 return(0);
584}
585
586/*
587 * Bring the controller back to a state ready for operation.
588 */
589int
590aac_resume(device_t dev)
591{
592 struct aac_softc *sc;
593
594 debug_called(1);
595
596 sc = device_get_softc(dev);
597
598 sc->aac_state &= ~AAC_STATE_SUSPEND;
599 AAC_UNMASK_INTERRUPTS(sc);
600 return(0);
601}
602
603/*
604 * Take an interrupt.
605 */
606void
607aac_intr(void *arg)
608{
609 struct aac_softc *sc;
610 u_int32_t *resp_queue;
611 u_int16_t reason;
612
613 debug_called(2);
614
615 sc = (struct aac_softc *)arg;
616
617 /*
618 * Optimize the common case of adapter response interrupts.
619 * We must read from the card prior to processing the responses
620 * to ensure the clear is flushed prior to accessing the queues.
621 * Reading the queues from local memory might save us a PCI read.
622 */
623 resp_queue = sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE];
624 if (resp_queue[AAC_PRODUCER_INDEX] != resp_queue[AAC_CONSUMER_INDEX])
625 reason = AAC_DB_RESPONSE_READY;
626 else
627 reason = AAC_GET_ISTATUS(sc);
628 AAC_CLEAR_ISTATUS(sc, reason);
629 (void)AAC_GET_ISTATUS(sc);
630
631 /* It's not ok to return here because of races with the previous step */
632 if (reason & AAC_DB_RESPONSE_READY)
633 /* handle completion processing */
634 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
635
636 /* controller wants to talk to the log */
637 if (reason & AAC_DB_PRINTF) {
638 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
639 sc->aifflags |= AAC_AIFFLAGS_PRINTF;
640 } else
641 aac_print_printf(sc);
642 }
643
644 /* controller has a message for us? */
645 if (reason & AAC_DB_COMMAND_READY) {
646 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
647 sc->aifflags |= AAC_AIFFLAGS_AIF;
648 } else {
649 /*
650 * XXX If the kthread is dead and we're at this point,
651 * there are bigger problems than just figuring out
652 * what to do with an AIF.
653 */
654 }
655
656 }
657
658 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) != 0)
659 /* XXX Should this be done with cv_signal? */
660 wakeup(sc->aifthread);
661}
662
663/*
664 * Command Processing
665 */
666
667/*
668 * Start as much queued I/O as possible on the controller
669 */
670void
671aac_startio(struct aac_softc *sc)
672{
673 struct aac_command *cm;
674
675 debug_called(2);
676
677 for (;;) {
678 /*
679 * Try to get a command that's been put off for lack of
680 * resources
681 */
682 cm = aac_dequeue_ready(sc);
683
684 /*
685 * Try to build a command off the bio queue (ignore error
686 * return)
687 */
688 if (cm == NULL)
689 aac_bio_command(sc, &cm);
690
691 /* nothing to do? */
692 if (cm == NULL)
693 break;
694
695 /* try to give the command to the controller */
696 if (aac_start(cm) == EBUSY) {
697 /* put it on the ready queue for later */
698 aac_requeue_ready(cm);
699 break;
700 }
701 }
702}
703
704/*
705 * Deliver a command to the controller; allocate controller resources at the
706 * last moment when possible.
707 */
708static int
709aac_start(struct aac_command *cm)
710{
711 struct aac_softc *sc;
712 int error;
713
714 debug_called(2);
715
716 sc = cm->cm_sc;
717
718 /* get the command mapped */
719 aac_map_command(cm);
720
721 /* fix up the address values in the FIB */
722 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
723 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
724
725 /* save a pointer to the command for speedy reverse-lookup */
726 cm->cm_fib->Header.SenderData = cm->cm_index;
727 /* put the FIB on the outbound queue */
728 error = aac_enqueue_fib(sc, cm->cm_queue, cm);
729 return(error);
730}
731
732/*
733 * Handle notification of one or more FIBs coming from the controller.
734 */
735static void
736aac_command_thread(struct aac_softc *sc)
737{
738 struct aac_fib *fib;
739 u_int32_t fib_size;
740 int size;
741
742 debug_called(2);
743
744 sc->aifflags |= AAC_AIFFLAGS_RUNNING;
745
746 while (!(sc->aifflags & AAC_AIFFLAGS_EXIT)) {
747 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
748 tsleep(sc->aifthread, PRIBIO, "aifthd",
749 AAC_PERIODIC_INTERVAL * hz);
750
751 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
752 aac_timeout(sc);
753
754 /* Check the hardware printf message buffer */
755 if ((sc->aifflags & AAC_AIFFLAGS_PRINTF) != 0) {
756 sc->aifflags &= ~AAC_AIFFLAGS_PRINTF;
757 aac_print_printf(sc);
758 }
759
760 /* See if any FIBs need to be allocated */
761 if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
762 mtx_lock(&Giant);
763 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
764 aac_alloc_commands(sc);
765 sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
766 AAC_LOCK_RELEASE(&sc->aac_io_lock);
767 mtx_unlock(&Giant);
768 }
769
770 /* While we're here, check to see if any commands are stuck */
771 while (sc->aifflags & AAC_AIFFLAGS_AIF) {
772 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
773 &fib_size, &fib)) {
774 sc->aifflags &= ~AAC_AIFFLAGS_AIF;
775 break; /* nothing to do */
776 }
777
778 AAC_PRINT_FIB(sc, fib);
779
780 switch (fib->Header.Command) {
781 case AifRequest:
782 aac_handle_aif(sc, fib);
783 break;
784 default:
785 device_printf(sc->aac_dev, "unknown command "
786 "from controller\n");
787 break;
788 }
789
790 if ((fib->Header.XferState == 0) ||
791 (fib->Header.StructType != AAC_FIBTYPE_TFIB))
792 break;
793
794 /* Return the AIF to the controller. */
795 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
796 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
797 *(AAC_FSAStatus*)fib->data = ST_OK;
798
799 /* XXX Compute the Size field? */
800 size = fib->Header.Size;
801 if (size > sizeof(struct aac_fib)) {
802 size = sizeof(struct aac_fib);
803 fib->Header.Size = size;
804 }
805 /*
806 * Since we did not generate this command, it
807 * cannot go through the normal
808 * enqueue->startio chain.
809 */
810 aac_enqueue_response(sc,
811 AAC_ADAP_NORM_RESP_QUEUE,
812 fib);
813 }
814 }
815 }
816 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
817 wakeup(sc->aac_dev);
818
819 mtx_lock(&Giant);
820 kthread_exit(0);
821}
822
823/*
824 * Process completed commands.
825 */
826static void
827aac_complete(void *context, int pending)
828{
829 struct aac_softc *sc;
830 struct aac_command *cm;
831 struct aac_fib *fib;
832 u_int32_t fib_size;
833
834 debug_called(2);
835
836 sc = (struct aac_softc *)context;
837
838 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
839
840 /* pull completed commands off the queue */
841 for (;;) {
842 /* look for completed FIBs on our queue */
843 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
844 &fib))
845 break; /* nothing to do */
846
847 /* get the command, unmap and queue for later processing */
848 cm = sc->aac_commands + fib->Header.SenderData;
849 if (cm == NULL) {
850 AAC_PRINT_FIB(sc, fib);
851 break;
852 }
853
854 aac_remove_busy(cm);
855 aac_unmap_command(cm); /* XXX defer? */
856 cm->cm_flags |= AAC_CMD_COMPLETED;
857
858 /* is there a completion handler? */
859 if (cm->cm_complete != NULL) {
860 cm->cm_complete(cm);
861 } else {
862 /* assume that someone is sleeping on this command */
863 wakeup(cm);
864 }
865 }
866
867 /* see if we can start some more I/O */
868 aac_startio(sc);
869
870 AAC_LOCK_RELEASE(&sc->aac_io_lock);
871}
872
873/*
874 * Handle a bio submitted from a disk device.
875 */
876void
877aac_submit_bio(struct bio *bp)
878{
879 struct aac_disk *ad;
880 struct aac_softc *sc;
881
882 debug_called(2);
883
884 ad = (struct aac_disk *)bp->bio_disk->d_drv1;
885 sc = ad->ad_controller;
886
887 /* queue the BIO and try to get some work done */
888 aac_enqueue_bio(sc, bp);
889 aac_startio(sc);
890}
891
892/*
893 * Get a bio and build a command to go with it.
894 */
895static int
896aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
897{
898 struct aac_command *cm;
899 struct aac_fib *fib;
900 struct aac_blockread *br;
901 struct aac_blockwrite *bw;
902 struct aac_disk *ad;
903 struct bio *bp;
904
905 debug_called(2);
906
907 /* get the resources we will need */
908 cm = NULL;
909 if ((bp = aac_dequeue_bio(sc)) == NULL)
910 goto fail;
911 if (aac_alloc_command(sc, &cm)) /* get a command */
912 goto fail;
913
914 /* fill out the command */
915 cm->cm_data = (void *)bp->bio_data;
916 cm->cm_datalen = bp->bio_bcount;
917 cm->cm_complete = aac_bio_complete;
918 cm->cm_private = bp;
919 cm->cm_timestamp = time_second;
920 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
921
922 /* build the FIB */
923 fib = cm->cm_fib;
924 fib->Header.XferState =
925 AAC_FIBSTATE_HOSTOWNED |
926 AAC_FIBSTATE_INITIALISED |
927 AAC_FIBSTATE_EMPTY |
928 AAC_FIBSTATE_FROMHOST |
929 AAC_FIBSTATE_REXPECTED |
930 AAC_FIBSTATE_NORM |
931 AAC_FIBSTATE_ASYNC |
932 AAC_FIBSTATE_FAST_RESPONSE;
933 fib->Header.Command = ContainerCommand;
934 fib->Header.Size = sizeof(struct aac_fib_header);
935
936 /* build the read/write request */
937 ad = (struct aac_disk *)bp->bio_disk->d_drv1;
938 if (bp->bio_cmd == BIO_READ) {
939 br = (struct aac_blockread *)&fib->data[0];
940 br->Command = VM_CtBlockRead;
941 br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
942 br->BlockNumber = bp->bio_pblkno;
943 br->ByteCount = bp->bio_bcount;
944 fib->Header.Size += sizeof(struct aac_blockread);
945 cm->cm_sgtable = &br->SgMap;
946 cm->cm_flags |= AAC_CMD_DATAIN;
947 } else {
948 bw = (struct aac_blockwrite *)&fib->data[0];
949 bw->Command = VM_CtBlockWrite;
950 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
951 bw->BlockNumber = bp->bio_pblkno;
952 bw->ByteCount = bp->bio_bcount;
953 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */
954 fib->Header.Size += sizeof(struct aac_blockwrite);
955 cm->cm_flags |= AAC_CMD_DATAOUT;
956 cm->cm_sgtable = &bw->SgMap;
957 }
958
959 *cmp = cm;
960 return(0);
961
962fail:
963 if (bp != NULL)
964 aac_enqueue_bio(sc, bp);
965 if (cm != NULL)
966 aac_release_command(cm);
967 return(ENOMEM);
968}
969
970/*
971 * Handle a bio-instigated command that has been completed.
972 */
973static void
974aac_bio_complete(struct aac_command *cm)
975{
976 struct aac_blockread_response *brr;
977 struct aac_blockwrite_response *bwr;
978 struct bio *bp;
979 AAC_FSAStatus status;
980
981 /* fetch relevant status and then release the command */
982 bp = (struct bio *)cm->cm_private;
983 if (bp->bio_cmd == BIO_READ) {
984 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
985 status = brr->Status;
986 } else {
987 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
988 status = bwr->Status;
989 }
990 aac_release_command(cm);
991
992 /* fix up the bio based on status */
993 if (status == ST_OK) {
994 bp->bio_resid = 0;
995 } else {
996 bp->bio_error = EIO;
997 bp->bio_flags |= BIO_ERROR;
998 /* pass an error string out to the disk layer */
999 bp->bio_driver1 = aac_describe_code(aac_command_status_table,
1000 status);
1001 }
1002 aac_biodone(bp);
1003}
1004
1005/*
1006 * Submit a command to the controller, return when it completes.
1007 * XXX This is very dangerous! If the card has gone out to lunch, we could
1008 * be stuck here forever. At the same time, signals are not caught
1009 * because there is a risk that a signal could wakeup the tsleep before
1010 * the card has a chance to complete the command. The passed in timeout
1011 * is ignored for the same reason. Since there is no way to cancel a
1012 * command in progress, we should probably create a 'dead' queue where
1013 * commands go that have been interrupted/timed-out/etc, that keeps them
1014 * out of the free pool. That way, if the card is just slow, it won't
1015 * spam the memory of a command that has been recycled.
1016 */
1017static int
1018aac_wait_command(struct aac_command *cm, int timeout)
1019{
1020 struct aac_softc *sc;
1021 int error = 0;
1022
1023 debug_called(2);
1024
1025 sc = cm->cm_sc;
1026
1027 /* Put the command on the ready queue and get things going */
1028 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1029 aac_enqueue_ready(cm);
1030 aac_startio(sc);
1031 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
1032 error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
1033 }
1034 return(error);
1035}
1036
1037/*
1038 *Command Buffer Management
1039 */
1040
1041/*
1042 * Allocate a command.
1043 */
1044int
1045aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1046{
1047 struct aac_command *cm;
1048
1049 debug_called(3);
1050
1051 if ((cm = aac_dequeue_free(sc)) == NULL) {
1052 sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1053 wakeup(sc->aifthread);
1054 return (EBUSY);
1055 }
1056
1057 *cmp = cm;
1058 return(0);
1059}
1060
1061/*
1062 * Release a command back to the freelist.
1063 */
1064void
1065aac_release_command(struct aac_command *cm)
1066{
1067 debug_called(3);
1068
1069 /* (re)initialise the command/FIB */
1070 cm->cm_sgtable = NULL;
1071 cm->cm_flags = 0;
1072 cm->cm_complete = NULL;
1073 cm->cm_private = NULL;
1074 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1075 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1076 cm->cm_fib->Header.Flags = 0;
1077 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1078
1079 /*
1080 * These are duplicated in aac_start to cover the case where an
1081 * intermediate stage may have destroyed them. They're left
1082 * initialised here for debugging purposes only.
1083 */
1084 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
1085 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1086 cm->cm_fib->Header.SenderData = 0;
1087
1088 aac_enqueue_free(cm);
1089}
1090
1091/*
1092 * Map helper for command/FIB allocation.
1093 */
1094static void
1095aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1096{
1097 uint32_t *fibphys;
1098
1099 fibphys = (uint32_t *)arg;
1100
1101 debug_called(3);
1102
1103 *fibphys = segs[0].ds_addr;
1104}
1105
1106/*
1107 * Allocate and initialise commands/FIBs for this adapter.
1108 */
1109static int
1110aac_alloc_commands(struct aac_softc *sc)
1111{
1112 struct aac_command *cm;
1113 struct aac_fibmap *fm;
1114 uint32_t fibphys;
1115 int i, error;
1116
1117 debug_called(1);
1118
1119 if (sc->total_fibs + AAC_FIB_COUNT > AAC_MAX_FIBS)
1120 return (ENOMEM);
1121
1122 fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
1123
1124 /* allocate the FIBs in DMAable memory and load them */
1125 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1126 BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1127 device_printf(sc->aac_dev,
1128 "Not enough contiguous memory available.\n");
1129 free(fm, M_AACBUF);
1130 return (ENOMEM);
1131 }
1132
1133 bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1134 AAC_FIB_COUNT * sizeof(struct aac_fib),
1135 aac_map_command_helper, &fibphys, 0);
1136
1137 /* initialise constant fields in the command structure */
1138 bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib));
1139 for (i = 0; i < AAC_FIB_COUNT; i++) {
1140 cm = sc->aac_commands + sc->total_fibs;
1141 fm->aac_commands = cm;
1142 cm->cm_sc = sc;
1143 cm->cm_fib = fm->aac_fibs + i;
1144 cm->cm_fibphys = fibphys + (i * sizeof(struct aac_fib));
1145 cm->cm_index = sc->total_fibs;
1146
1147 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1148 &cm->cm_datamap)) == 0)
1149 aac_release_command(cm);
1150 else
1151 break;
1152 sc->total_fibs++;
1153 }
1154
1155 if (i > 0) {
1156 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1157 return (0);
1158 }
1159
1160 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1161 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1162 free(fm, M_AACBUF);
1163 return (ENOMEM);
1164}
1165
1166/*
1167 * Free FIBs owned by this adapter.
1168 */
1169static void
1170aac_free_commands(struct aac_softc *sc)
1171{
1172 struct aac_fibmap *fm;
1173 struct aac_command *cm;
1174 int i;
1175
1176 debug_called(1);
1177
1178 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1179
1180 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1181 /*
1182 * We check against total_fibs to handle partially
1183 * allocated blocks.
1184 */
1185 for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) {
1186 cm = fm->aac_commands + i;
1187 bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1188 }
1189 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1190 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1191 free(fm, M_AACBUF);
1192 }
1193}
1194
1195/*
1196 * Command-mapping helper function - populate this command's s/g table.
1197 */
1198static void
1199aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1200{
1201 struct aac_command *cm;
1202 struct aac_fib *fib;
1203 struct aac_sg_table *sg;
1204 int i;
1205
1206 debug_called(3);
1207
1208 cm = (struct aac_command *)arg;
1209 fib = cm->cm_fib;
1210
1211 /* find the s/g table */
1212 sg = cm->cm_sgtable;
1213
1214 /* copy into the FIB */
1215 if (sg != NULL) {
1216 sg->SgCount = nseg;
1217 for (i = 0; i < nseg; i++) {
1218 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1219 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1220 }
1221 /* update the FIB size for the s/g count */
1222 fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1223 }
1224
1225}
1226
1227/*
1228 * Map a command into controller-visible space.
1229 */
1230static void
1231aac_map_command(struct aac_command *cm)
1232{
1233 struct aac_softc *sc;
1234
1235 debug_called(2);
1236
1237 sc = cm->cm_sc;
1238
1239 /* don't map more than once */
1240 if (cm->cm_flags & AAC_CMD_MAPPED)
1241 return;
1242
1243 if (cm->cm_datalen != 0) {
1244 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
1245 cm->cm_data, cm->cm_datalen,
1246 aac_map_command_sg, cm, 0);
1247
1248 if (cm->cm_flags & AAC_CMD_DATAIN)
1249 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1250 BUS_DMASYNC_PREREAD);
1251 if (cm->cm_flags & AAC_CMD_DATAOUT)
1252 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1253 BUS_DMASYNC_PREWRITE);
1254 }
1255 cm->cm_flags |= AAC_CMD_MAPPED;
1256}
1257
1258/*
1259 * Unmap a command from controller-visible space.
1260 */
1261static void
1262aac_unmap_command(struct aac_command *cm)
1263{
1264 struct aac_softc *sc;
1265
1266 debug_called(2);
1267
1268 sc = cm->cm_sc;
1269
1270 if (!(cm->cm_flags & AAC_CMD_MAPPED))
1271 return;
1272
1273 if (cm->cm_datalen != 0) {
1274 if (cm->cm_flags & AAC_CMD_DATAIN)
1275 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1276 BUS_DMASYNC_POSTREAD);
1277 if (cm->cm_flags & AAC_CMD_DATAOUT)
1278 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1279 BUS_DMASYNC_POSTWRITE);
1280
1281 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1282 }
1283 cm->cm_flags &= ~AAC_CMD_MAPPED;
1284}
1285
1286/*
1287 * Hardware Interface
1288 */
1289
1290/*
1291 * Initialise the adapter.
1292 */
1293static void
1294aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1295{
1296 struct aac_softc *sc;
1297
1298 debug_called(1);
1299
1300 sc = (struct aac_softc *)arg;
1301
1302 sc->aac_common_busaddr = segs[0].ds_addr;
1303}
1304
1305/*
1306 * Retrieve the firmware version numbers. Dell PERC2/QC cards with
1307 * firmware version 1.x are not compatible with this driver.
1308 */
1309static int
1310aac_check_firmware(struct aac_softc *sc)
1311{
1312 u_int32_t major, minor;
1313
1314 debug_called(1);
1315
1316 if (sc->quirks & AAC_QUIRK_PERC2QC) {
1317 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1318 NULL)) {
1319 device_printf(sc->aac_dev,
1320 "Error reading firmware version\n");
1321 return (EIO);
1322 }
1323
1324 /* These numbers are stored as ASCII! */
1325 major = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 4) & 0xff) - 0x30;
1326 minor = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 8) & 0xff) - 0x30;
1327 if (major == 1) {
1328 device_printf(sc->aac_dev,
1329 "Firmware version %d.%d is not supported.\n",
1330 major, minor);
1331 return (EINVAL);
1332 }
1333 }
1334
1335 return (0);
1336}
1337
1338static int
1339aac_init(struct aac_softc *sc)
1340{
1341 struct aac_adapter_init *ip;
1342 time_t then;
1343 u_int32_t code;
1344 u_int8_t *qaddr;
1345
1346 debug_called(1);
1347
1348 /*
1349 * First wait for the adapter to come ready.
1350 */
1351 then = time_second;
1352 do {
1353 code = AAC_GET_FWSTATUS(sc);
1354 if (code & AAC_SELF_TEST_FAILED) {
1355 device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1356 return(ENXIO);
1357 }
1358 if (code & AAC_KERNEL_PANIC) {
1359 device_printf(sc->aac_dev,
1360 "FATAL: controller kernel panic\n");
1361 return(ENXIO);
1362 }
1363 if (time_second > (then + AAC_BOOT_TIMEOUT)) {
1364 device_printf(sc->aac_dev,
1365 "FATAL: controller not coming ready, "
1366 "status %x\n", code);
1367 return(ENXIO);
1368 }
1369 } while (!(code & AAC_UP_AND_RUNNING));
1370
1371 /*
1372 * Create DMA tag for the common structure and allocate it.
1373 */
1374 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
1375 1, 0, /* algnmnt, boundary */
1376 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
1377 BUS_SPACE_MAXADDR, /* highaddr */
1378 NULL, NULL, /* filter, filterarg */
1379 8192 + sizeof(struct aac_common), /* maxsize */
1380 1, /* nsegments */
1381 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1382 0, /* flags */
1383 &sc->aac_common_dmat)) {
1384 device_printf(sc->aac_dev,
1385 "can't allocate common structure DMA tag\n");
1386 return(ENOMEM);
1387 }
1388 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1389 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1390 device_printf(sc->aac_dev, "can't allocate common structure\n");
1391 return(ENOMEM);
1392 }
1393
1394 /*
1395 * Work around a bug in the 2120 and 2200 that cannot DMA commands
1396 * below address 8192 in physical memory.
1397 * XXX If the padding is not needed, can it be put to use instead
1398 * of ignored?
1399 */
1400 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1401 sc->aac_common, 8192 + sizeof(*sc->aac_common),
1402 aac_common_map, sc, 0);
1403
1404 if (sc->aac_common_busaddr < 8192) {
1405 (uint8_t *)sc->aac_common += 8192;
1406 sc->aac_common_busaddr += 8192;
1407 }
1408 bzero(sc->aac_common, sizeof(*sc->aac_common));
1409
1410 /* Allocate some FIBs and associated command structs */
1411 TAILQ_INIT(&sc->aac_fibmap_tqh);
1412 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command),
1413 M_AACBUF, M_WAITOK|M_ZERO);
1414 while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
1415 if (aac_alloc_commands(sc) != 0)
1416 break;
1417 }
1418 if (sc->total_fibs == 0)
1419 return (ENOMEM);
1420
1421 /*
1422 * Fill in the init structure. This tells the adapter about the
1423 * physical location of various important shared data structures.
1424 */
1425 ip = &sc->aac_common->ac_init;
1426 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1427 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1428
1429 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1430 offsetof(struct aac_common, ac_fibs);
1431 ip->AdapterFibsVirtualAddress = (u_int32_t)&sc->aac_common->ac_fibs[0];
1432 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1433 ip->AdapterFibAlign = sizeof(struct aac_fib);
1434
1435 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1436 offsetof(struct aac_common, ac_printf);
1437 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1438
1439 /* The adapter assumes that pages are 4K in size */
1440 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1441 ip->HostElapsedSeconds = time_second; /* reset later if invalid */
1442
1443 /*
1444 * Initialise FIB queues. Note that it appears that the layout of the
1445 * indexes and the segmentation of the entries may be mandated by the
1446 * adapter, which is only told about the base of the queue index fields.
1447 *
1448 * The initial values of the indices are assumed to inform the adapter
1449 * of the sizes of the respective queues, and theoretically it could
1450 * work out the entire layout of the queue structures from this. We
1451 * take the easy route and just lay this area out like everyone else
1452 * does.
1453 *
1454 * The Linux driver uses a much more complex scheme whereby several
1455 * header records are kept for each queue. We use a couple of generic
1456 * list manipulation functions which 'know' the size of each list by
1457 * virtue of a table.
1458 */
1459 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1460 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1461 sc->aac_queues = (struct aac_queue_table *)qaddr;
1462 ip->CommHeaderAddress = sc->aac_common_busaddr +
1463 ((u_int32_t)sc->aac_queues -
1464 (u_int32_t)sc->aac_common);
1465
1466 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1467 AAC_HOST_NORM_CMD_ENTRIES;
1468 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1469 AAC_HOST_NORM_CMD_ENTRIES;
1470 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1471 AAC_HOST_HIGH_CMD_ENTRIES;
1472 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1473 AAC_HOST_HIGH_CMD_ENTRIES;
1474 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1475 AAC_ADAP_NORM_CMD_ENTRIES;
1476 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1477 AAC_ADAP_NORM_CMD_ENTRIES;
1478 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1479 AAC_ADAP_HIGH_CMD_ENTRIES;
1480 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1481 AAC_ADAP_HIGH_CMD_ENTRIES;
1482 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1483 AAC_HOST_NORM_RESP_ENTRIES;
1484 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1485 AAC_HOST_NORM_RESP_ENTRIES;
1486 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1487 AAC_HOST_HIGH_RESP_ENTRIES;
1488 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1489 AAC_HOST_HIGH_RESP_ENTRIES;
1490 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1491 AAC_ADAP_NORM_RESP_ENTRIES;
1492 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1493 AAC_ADAP_NORM_RESP_ENTRIES;
1494 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1495 AAC_ADAP_HIGH_RESP_ENTRIES;
1496 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1497 AAC_ADAP_HIGH_RESP_ENTRIES;
1498 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1499 &sc->aac_queues->qt_HostNormCmdQueue[0];
1500 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1501 &sc->aac_queues->qt_HostHighCmdQueue[0];
1502 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1503 &sc->aac_queues->qt_AdapNormCmdQueue[0];
1504 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1505 &sc->aac_queues->qt_AdapHighCmdQueue[0];
1506 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1507 &sc->aac_queues->qt_HostNormRespQueue[0];
1508 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1509 &sc->aac_queues->qt_HostHighRespQueue[0];
1510 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1511 &sc->aac_queues->qt_AdapNormRespQueue[0];
1512 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1513 &sc->aac_queues->qt_AdapHighRespQueue[0];
1514
1515 /*
1516 * Do controller-type-specific initialisation
1517 */
1518 switch (sc->aac_hwif) {
1519 case AAC_HWIF_I960RX:
1520 AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1521 break;
1522 }
1523
1524 /*
1525 * Give the init structure to the controller.
1526 */
1527 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1528 sc->aac_common_busaddr +
1529 offsetof(struct aac_common, ac_init), 0, 0, 0,
1530 NULL)) {
1531 device_printf(sc->aac_dev,
1532 "error establishing init structure\n");
1533 return(EIO);
1534 }
1535
1536 return(0);
1537}
1538
1539/*
1540 * Send a synchronous command to the controller and wait for a result.
1541 */
1542static int
1543aac_sync_command(struct aac_softc *sc, u_int32_t command,
1544 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1545 u_int32_t *sp)
1546{
1547 time_t then;
1548 u_int32_t status;
1549
1550 debug_called(3);
1551
1552 /* populate the mailbox */
1553 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1554
1555 /* ensure the sync command doorbell flag is cleared */
1556 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1557
1558 /* then set it to signal the adapter */
1559 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1560
1561 /* spin waiting for the command to complete */
1562 then = time_second;
1563 do {
1564 if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) {
1565 debug(2, "timed out");
1566 return(EIO);
1567 }
1568 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1569
1570 /* clear the completion flag */
1571 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1572
1573 /* get the command status */
1574 status = AAC_GET_MAILBOXSTATUS(sc);
1575 if (sp != NULL)
1576 *sp = status;
1577 return(0);
1578}
1579
1580/*
1581 * Grab the sync fib area.
1582 */
1583int
1584aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1585{
1586
1587 /*
1588 * If the force flag is set, the system is shutting down, or in
1589 * trouble. Ignore the mutex.
1590 */
1591 if (!(flags & AAC_SYNC_LOCK_FORCE))
1592 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);
1593
1594 *fib = &sc->aac_common->ac_sync_fib;
1595
1596 return (1);
1597}
1598
1599/*
1600 * Release the sync fib area.
1601 */
1602void
1603aac_release_sync_fib(struct aac_softc *sc)
1604{
1605
1606 AAC_LOCK_RELEASE(&sc->aac_sync_lock);
1607}
1608
1609/*
1610 * Send a synchronous FIB to the controller and wait for a result.
1611 */
1612int
1613aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1614 struct aac_fib *fib, u_int16_t datasize)
1615{
1616 debug_called(3);
1617
1618 if (datasize > AAC_FIB_DATASIZE)
1619 return(EINVAL);
1620
1621 /*
1622 * Set up the sync FIB
1623 */
1624 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1625 AAC_FIBSTATE_INITIALISED |
1626 AAC_FIBSTATE_EMPTY;
1627 fib->Header.XferState |= xferstate;
1628 fib->Header.Command = command;
1629 fib->Header.StructType = AAC_FIBTYPE_TFIB;
1630 fib->Header.Size = sizeof(struct aac_fib) + datasize;
1631 fib->Header.SenderSize = sizeof(struct aac_fib);
1632 fib->Header.SenderFibAddress = (u_int32_t)fib;
1633 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1634 offsetof(struct aac_common,
1635 ac_sync_fib);
1636
1637 /*
1638 * Give the FIB to the controller, wait for a response.
1639 */
1640 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1641 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1642 debug(2, "IO error");
1643 return(EIO);
1644 }
1645
1646 return (0);
1647}
1648
1649/*
1650 * Adapter-space FIB queue manipulation
1651 *
1652 * Note that the queue implementation here is a little funky; neither the PI or
1653 * CI will ever be zero. This behaviour is a controller feature.
1654 */
1655static struct {
1656 int size;
1657 int notify;
1658} aac_qinfo[] = {
1659 {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
1660 {AAC_HOST_HIGH_CMD_ENTRIES, 0},
1661 {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
1662 {AAC_ADAP_HIGH_CMD_ENTRIES, 0},
1663 {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
1664 {AAC_HOST_HIGH_RESP_ENTRIES, 0},
1665 {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
1666 {AAC_ADAP_HIGH_RESP_ENTRIES, 0}
1667};
1668
1669/*
1670 * Atomically insert an entry into the nominated queue, returns 0 on success or
1671 * EBUSY if the queue is full.
1672 *
1673 * Note: it would be more efficient to defer notifying the controller in
1674 * the case where we may be inserting several entries in rapid succession,
1675 * but implementing this usefully may be difficult (it would involve a
1676 * separate queue/notify interface).
1677 */
1678static int
1679aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1680{
1681 u_int32_t pi, ci;
1682 int error;
1683 u_int32_t fib_size;
1684 u_int32_t fib_addr;
1685
1686 debug_called(3);
1687
1688 fib_size = cm->cm_fib->Header.Size;
1689 fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1690
1691 /* get the producer/consumer indices */
1692 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1693 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1694
1695 /* wrap the queue? */
1696 if (pi >= aac_qinfo[queue].size)
1697 pi = 0;
1698
1699 /* check for queue full */
1700 if ((pi + 1) == ci) {
1701 error = EBUSY;
1702 goto out;
1703 }
1704
1705 /* populate queue entry */
1706 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1707 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1708
1709 /* update producer index */
1710 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1711
1712 /*
1713 * To avoid a race with its completion interrupt, place this command on
1714 * the busy queue prior to advertising it to the controller.
1715 */
1716 aac_enqueue_busy(cm);
1717
1718 /* notify the adapter if we know how */
1719 if (aac_qinfo[queue].notify != 0)
1720 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1721
1722 error = 0;
1723
1724out:
1725 return(error);
1726}
1727
1728/*
1729 * Atomically remove one entry from the nominated queue, returns 0 on
1730 * success or ENOENT if the queue is empty.
1731 */
1732static int
1733aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1734 struct aac_fib **fib_addr)
1735{
1736 u_int32_t pi, ci;
1737 int error;
1738 int notify;
1739
1740 debug_called(3);
1741
1742 /* get the producer/consumer indices */
1743 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1744 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1745
1746 /* check for queue empty */
1747 if (ci == pi) {
1748 error = ENOENT;
1749 goto out;
1750 }
1751
1752 notify = 0;
1753 if (ci == pi + 1)
1754 notify++;
1755
1756 /* wrap the queue? */
1757 if (ci >= aac_qinfo[queue].size)
1758 ci = 0;
1759
1760 /* fetch the entry */
1761 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1762 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] +
1763 ci)->aq_fib_addr;
1764
1765 /*
1766 * Is this a fast response? If it is, update the fib fields in
1767 * local memory so the whole fib doesn't have to be DMA'd back up.
1768 */
1769 if (*(uintptr_t *)fib_addr & 0x01) {
1770 *(uintptr_t *)fib_addr &= ~0x01;
1771 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
1772 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
1773 }
1774 /* update consumer index */
1775 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1776
1777 /* if we have made the queue un-full, notify the adapter */
1778 if (notify && (aac_qinfo[queue].notify != 0))
1779 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1780 error = 0;
1781
1782out:
1783 return(error);
1784}
1785
1786/*
1787 * Put our response to an Adapter Initialed Fib on the response queue
1788 */
1789static int
1790aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1791{
1792 u_int32_t pi, ci;
1793 int error;
1794 u_int32_t fib_size;
1795 u_int32_t fib_addr;
1796
1797 debug_called(1);
1798
1799 /* Tell the adapter where the FIB is */
1800 fib_size = fib->Header.Size;
1801 fib_addr = fib->Header.SenderFibAddress;
1802 fib->Header.ReceiverFibAddress = fib_addr;
1803
1804 /* get the producer/consumer indices */
1805 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1806 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1807
1808 /* wrap the queue? */
1809 if (pi >= aac_qinfo[queue].size)
1810 pi = 0;
1811
1812 /* check for queue full */
1813 if ((pi + 1) == ci) {
1814 error = EBUSY;
1815 goto out;
1816 }
1817
1818 /* populate queue entry */
1819 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1820 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1821
1822 /* update producer index */
1823 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1824
1825 /* notify the adapter if we know how */
1826 if (aac_qinfo[queue].notify != 0)
1827 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1828
1829 error = 0;
1830
1831out:
1832 return(error);
1833}
1834
1835/*
1836 * Check for commands that have been outstanding for a suspiciously long time,
1837 * and complain about them.
1838 */
1839static void
1840aac_timeout(struct aac_softc *sc)
1841{
1842 struct aac_command *cm;
1843 time_t deadline;
1844
1845 /*
1846 * Traverse the busy command list, bitch about late commands once
1847 * only.
1848 */
1849 deadline = time_second - AAC_CMD_TIMEOUT;
1850 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1851 if ((cm->cm_timestamp < deadline)
1852 /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
1853 cm->cm_flags |= AAC_CMD_TIMEDOUT;
1854 device_printf(sc->aac_dev,
1855 "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
1856 cm, (int)(time_second-cm->cm_timestamp));
1857 AAC_PRINT_FIB(sc, cm->cm_fib);
1858 }
1859 }
1860
1861 return;
1862}
1863
1864/*
1865 * Interface Function Vectors
1866 */
1867
1868/*
1869 * Read the current firmware status word.
1870 */
1871static int
1872aac_sa_get_fwstatus(struct aac_softc *sc)
1873{
1874 debug_called(3);
1875
1876 return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1877}
1878
1879static int
1880aac_rx_get_fwstatus(struct aac_softc *sc)
1881{
1882 debug_called(3);
1883
1884 return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1885}
1886
1887static int
1888aac_fa_get_fwstatus(struct aac_softc *sc)
1889{
1890 int val;
1891
1892 debug_called(3);
1893
1894 val = AAC_GETREG4(sc, AAC_FA_FWSTATUS);
1895 return (val);
1896}
1897
1898/*
1899 * Notify the controller of a change in a given queue
1900 */
1901
1902static void
1903aac_sa_qnotify(struct aac_softc *sc, int qbit)
1904{
1905 debug_called(3);
1906
1907 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1908}
1909
1910static void
1911aac_rx_qnotify(struct aac_softc *sc, int qbit)
1912{
1913 debug_called(3);
1914
1915 AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1916}
1917
1918static void
1919aac_fa_qnotify(struct aac_softc *sc, int qbit)
1920{
1921 debug_called(3);
1922
1923 AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
1924 AAC_FA_HACK(sc);
1925}
1926
1927/*
1928 * Get the interrupt reason bits
1929 */
1930static int
1931aac_sa_get_istatus(struct aac_softc *sc)
1932{
1933 debug_called(3);
1934
1935 return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1936}
1937
1938static int
1939aac_rx_get_istatus(struct aac_softc *sc)
1940{
1941 debug_called(3);
1942
1943 return(AAC_GETREG4(sc, AAC_RX_ODBR));
1944}
1945
1946static int
1947aac_fa_get_istatus(struct aac_softc *sc)
1948{
1949 int val;
1950
1951 debug_called(3);
1952
1953 val = AAC_GETREG2(sc, AAC_FA_DOORBELL0);
1954 return (val);
1955}
1956
1957/*
1958 * Clear some interrupt reason bits
1959 */
1960static void
1961aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1962{
1963 debug_called(3);
1964
1965 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1966}
1967
1968static void
1969aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1970{
1971 debug_called(3);
1972
1973 AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1974}
1975
1976static void
1977aac_fa_clear_istatus(struct aac_softc *sc, int mask)
1978{
1979 debug_called(3);
1980
1981 AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
1982 AAC_FA_HACK(sc);
1983}
1984
1985/*
1986 * Populate the mailbox and set the command word
1987 */
1988static void
1989aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
1990 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1991{
1992 debug_called(4);
1993
1994 AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1995 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1996 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1997 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1998 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1999}
2000
2001static void
2002aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
2003 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2004{
2005 debug_called(4);
2006
2007 AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
2008 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2009 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2010 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2011 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2012}
2013
2014static void
2015aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2016 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2017{
2018 debug_called(4);
2019
2020 AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
2021 AAC_FA_HACK(sc);
2022 AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
2023 AAC_FA_HACK(sc);
2024 AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
2025 AAC_FA_HACK(sc);
2026 AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
2027 AAC_FA_HACK(sc);
2028 AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
2029 AAC_FA_HACK(sc);
2030}
2031
2032/*
2033 * Fetch the immediate command status word
2034 */
2035static int
2036aac_sa_get_mailboxstatus(struct aac_softc *sc)
2037{
2038 debug_called(4);
2039
2040 return(AAC_GETREG4(sc, AAC_SA_MAILBOX));
2041}
2042
2043static int
2044aac_rx_get_mailboxstatus(struct aac_softc *sc)
2045{
2046 debug_called(4);
2047
2048 return(AAC_GETREG4(sc, AAC_RX_MAILBOX));
2049}
2050
2051static int
2052aac_fa_get_mailboxstatus(struct aac_softc *sc)
2053{
2054 int val;
2055
2056 debug_called(4);
2057
2058 val = AAC_GETREG4(sc, AAC_FA_MAILBOX);
2059 return (val);
2060}
2061
2062/*
2063 * Set/clear interrupt masks
2064 */
2065static void
2066aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2067{
2068 debug(2, "%sable interrupts", enable ? "en" : "dis");
2069
2070 if (enable) {
2071 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2072 } else {
2073 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2074 }
2075}
2076
2077static void
2078aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2079{
2080 debug(2, "%sable interrupts", enable ? "en" : "dis");
2081
2082 if (enable) {
2083 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2084 } else {
2085 AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
2086 }
2087}
2088
2089static void
2090aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2091{
2092 debug(2, "%sable interrupts", enable ? "en" : "dis");
2093
2094 if (enable) {
2095 AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2096 AAC_FA_HACK(sc);
2097 } else {
2098 AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
2099 AAC_FA_HACK(sc);
2100 }
2101}
2102
2103/*
2104 * Debugging and Diagnostics
2105 */
2106
2107/*
2108 * Print some information about the controller.
2109 */
2110static void
2111aac_describe_controller(struct aac_softc *sc)
2112{
2113 struct aac_fib *fib;
2114 struct aac_adapter_info *info;
2115
2116 debug_called(2);
2117
2118 aac_alloc_sync_fib(sc, &fib, 0);
2119
2120 fib->data[0] = 0;
2121 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2122 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2123 aac_release_sync_fib(sc);
2124 return;
2125 }
2126 info = (struct aac_adapter_info *)&fib->data[0];
2127
2128 device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n",
2129 aac_describe_code(aac_cpu_variant, info->CpuVariant),
2130 info->ClockSpeed, info->BufferMem / (1024 * 1024),
2131 aac_describe_code(aac_battery_platform,
2132 info->batteryPlatform));
2133
2134 /* save the kernel revision structure for later use */
2135 sc->aac_revision = info->KernelRevision;
2136 device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2137 info->KernelRevision.external.comp.major,
2138 info->KernelRevision.external.comp.minor,
2139 info->KernelRevision.external.comp.dash,
2140 info->KernelRevision.buildNumber,
2141 (u_int32_t)(info->SerialNumber & 0xffffff));
2142
2143 aac_release_sync_fib(sc);
2144}
2145
2146/*
2147 * Look up a text description of a numeric error code and return a pointer to
2148 * same.
2149 */
2150static char *
2151aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2152{
2153 int i;
2154
2155 for (i = 0; table[i].string != NULL; i++)
2156 if (table[i].code == code)
2157 return(table[i].string);
2158 return(table[i + 1].string);
2159}
2160
2161/*
2162 * Management Interface
2163 */
2164
2165static int
2166aac_open(dev_t dev, int flags, int fmt, d_thread_t *td)
2167{
2168 struct aac_softc *sc;
2169
2170 debug_called(2);
2171
2172 sc = dev->si_drv1;
2173
2174 /* Check to make sure the device isn't already open */
2175 if (sc->aac_state & AAC_STATE_OPEN) {
2176 return EBUSY;
2177 }
2178 sc->aac_state |= AAC_STATE_OPEN;
2179
2180 return 0;
2181}
2182
2183static int
2184aac_close(dev_t dev, int flags, int fmt, d_thread_t *td)
2185{
2186 struct aac_softc *sc;
2187
2188 debug_called(2);
2189
2190 sc = dev->si_drv1;
2191
2192 /* Mark this unit as no longer open */
2193 sc->aac_state &= ~AAC_STATE_OPEN;
2194
2195 return 0;
2196}
2197
2198static int
2199aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
2200{
2201 union aac_statrequest *as;
2202 struct aac_softc *sc;
2203 int error = 0;
2204 int i;
2205
2206 debug_called(2);
2207
2208 as = (union aac_statrequest *)arg;
2209 sc = dev->si_drv1;
2210
2211 switch (cmd) {
2212 case AACIO_STATS:
2213 switch (as->as_item) {
2214 case AACQ_FREE:
2215 case AACQ_BIO:
2216 case AACQ_READY:
2217 case AACQ_BUSY:
2218 case AACQ_COMPLETE:
2219 bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2220 sizeof(struct aac_qstat));
2221 break;
2222 default:
2223 error = ENOENT;
2224 break;
2225 }
2226 break;
2227
2228 case FSACTL_SENDFIB:
2229 arg = *(caddr_t*)arg;
2230 case FSACTL_LNX_SENDFIB:
2231 debug(1, "FSACTL_SENDFIB");
2232 error = aac_ioctl_sendfib(sc, arg);
2233 break;
2234 case FSACTL_AIF_THREAD:
2235 case FSACTL_LNX_AIF_THREAD:
2236 debug(1, "FSACTL_AIF_THREAD");
2237 error = EINVAL;
2238 break;
2239 case FSACTL_OPEN_GET_ADAPTER_FIB:
2240 arg = *(caddr_t*)arg;
2241 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2242 debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
2243 /*
2244 * Pass the caller out an AdapterFibContext.
2245 *
2246 * Note that because we only support one opener, we
2247 * basically ignore this. Set the caller's context to a magic
2248 * number just in case.
2249 *
2250 * The Linux code hands the driver a pointer into kernel space,
2251 * and then trusts it when the caller hands it back. Aiee!
2252 * Here, we give it the proc pointer of the per-adapter aif
2253 * thread. It's only used as a sanity check in other calls.
2254 */
2255 i = (int)sc->aifthread;
2256 error = copyout(&i, arg, sizeof(i));
2257 break;
2258 case FSACTL_GET_NEXT_ADAPTER_FIB:
2259 arg = *(caddr_t*)arg;
2260 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2261 debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB");
2262 error = aac_getnext_aif(sc, arg);
2263 break;
2264 case FSACTL_CLOSE_GET_ADAPTER_FIB:
2265 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2266 debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2267 /* don't do anything here */
2268 break;
2269 case FSACTL_MINIPORT_REV_CHECK:
2270 arg = *(caddr_t*)arg;
2271 case FSACTL_LNX_MINIPORT_REV_CHECK:
2272 debug(1, "FSACTL_MINIPORT_REV_CHECK");
2273 error = aac_rev_check(sc, arg);
2274 break;
2275 case FSACTL_QUERY_DISK:
2276 arg = *(caddr_t*)arg;
2277 case FSACTL_LNX_QUERY_DISK:
2278 debug(1, "FSACTL_QUERY_DISK");
2279 error = aac_query_disk(sc, arg);
2280 break;
2281 case FSACTL_DELETE_DISK:
2282 case FSACTL_LNX_DELETE_DISK:
2283 /*
2284 * We don't trust the underland to tell us when to delete a
2285 * container, rather we rely on an AIF coming from the
2286 * controller
2287 */
2288 error = 0;
2289 break;
2290 default:
2291 debug(1, "unsupported cmd 0x%lx\n", cmd);
2292 error = EINVAL;
2293 break;
2294 }
2295 return(error);
2296}
2297
2298static int
2299aac_poll(dev_t dev, int poll_events, d_thread_t *td)
2300{
2301 struct aac_softc *sc;
2302 int revents;
2303
2304 sc = dev->si_drv1;
2305 revents = 0;
2306
2307 AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
2308 if ((poll_events & (POLLRDNORM | POLLIN)) != 0) {
2309 if (sc->aac_aifq_tail != sc->aac_aifq_head)
2310 revents |= poll_events & (POLLIN | POLLRDNORM);
2311 }
2312 AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
2313
2314 if (revents == 0) {
2315 if (poll_events & (POLLIN | POLLRDNORM))
2316 selrecord(td, &sc->rcv_select);
2317 }
2318
2319 return (revents);
2320}
2321
2322/*
2323 * Send a FIB supplied from userspace
2324 */
2325static int
2326aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2327{
2328 struct aac_command *cm;
2329 int size, error;
2330
2331 debug_called(2);
2332
2333 cm = NULL;
2334
2335 /*
2336 * Get a command
2337 */
2338 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
2339 if (aac_alloc_command(sc, &cm)) {
2340 error = EBUSY;
2341 goto out;
2342 }
2343
2344 /*
2345 * Fetch the FIB header, then re-copy to get data as well.
2346 */
2347 if ((error = copyin(ufib, cm->cm_fib,
2348 sizeof(struct aac_fib_header))) != 0)
2349 goto out;
2350 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
2351 if (size > sizeof(struct aac_fib)) {
2352 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
2353 size, sizeof(struct aac_fib));
2354 size = sizeof(struct aac_fib);
2355 }
2356 if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
2357 goto out;
2358 cm->cm_fib->Header.Size = size;
2359 cm->cm_timestamp = time_second;
2360
2361 /*
2362 * Pass the FIB to the controller, wait for it to complete.
2363 */
2364 if ((error = aac_wait_command(cm, 30)) != 0) { /* XXX user timeout? */
2365 device_printf(sc->aac_dev,
2366 "aac_wait_command return %d\n", error);
2367 goto out;
2368 }
2369
2370 /*
2371 * Copy the FIB and data back out to the caller.
2372 */
2373 size = cm->cm_fib->Header.Size;
2374 if (size > sizeof(struct aac_fib)) {
2375 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
2376 size, sizeof(struct aac_fib));
2377 size = sizeof(struct aac_fib);
2378 }
2379 error = copyout(cm->cm_fib, ufib, size);
2380
2381out:
2382 if (cm != NULL) {
2383 aac_release_command(cm);
2384 }
2385
2386 AAC_LOCK_RELEASE(&sc->aac_io_lock);
2387 return(error);
2388}
2389
2390/*
2391 * Handle an AIF sent to us by the controller; queue it for later reference.
2392 * If the queue fills up, then drop the older entries.
2393 */
2394static void
2395aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
2396{
2397 struct aac_aif_command *aif;
2398 struct aac_container *co, *co_next;
2399 struct aac_mntinfo *mi;
2400 struct aac_mntinforesp *mir = NULL;
2401 u_int16_t rsize;
2402 int next, found;
2403 int added = 0, i = 0;
2404
2405 debug_called(2);
2406
2407 aif = (struct aac_aif_command*)&fib->data[0];
2408 aac_print_aif(sc, aif);
2409
2410 /* Is it an event that we should care about? */
2411 switch (aif->command) {
2412 case AifCmdEventNotify:
2413 switch (aif->data.EN.type) {
2414 case AifEnAddContainer:
2415 case AifEnDeleteContainer:
2416 /*
2417 * A container was added or deleted, but the message
2418 * doesn't tell us anything else! Re-enumerate the
2419 * containers and sort things out.
2420 */
2421 aac_alloc_sync_fib(sc, &fib, 0);
2422 mi = (struct aac_mntinfo *)&fib->data[0];
2423 do {
2424 /*
2425 * Ask the controller for its containers one at
2426 * a time.
2427 * XXX What if the controller's list changes
2428 * midway through this enumaration?
2429 * XXX This should be done async.
2430 */
2431 bzero(mi, sizeof(struct aac_mntinfo));
2432 mi->Command = VM_NameServe;
2433 mi->MntType = FT_FILESYS;
2434 mi->MntCount = i;
2435 rsize = sizeof(mir);
2436 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
2437 sizeof(struct aac_mntinfo))) {
2438 debug(2, "Error probing container %d\n",
2439 i);
2440 continue;
2441 }
2442 mir = (struct aac_mntinforesp *)&fib->data[0];
2443 /*
2444 * Check the container against our list.
2445 * co->co_found was already set to 0 in a
2446 * previous run.
2447 */
2448 if ((mir->Status == ST_OK) &&
2449 (mir->MntTable[0].VolType != CT_NONE)) {
2450 found = 0;
2451 TAILQ_FOREACH(co,
2452 &sc->aac_container_tqh,
2453 co_link) {
2454 if (co->co_mntobj.ObjectId ==
2455 mir->MntTable[0].ObjectId) {
2456 co->co_found = 1;
2457 found = 1;
2458 break;
2459 }
2460 }
2461 /*
2462 * If the container matched, continue
2463 * in the list.
2464 */
2465 if (found) {
2466 i++;
2467 continue;
2468 }
2469
2470 /*
2471 * This is a new container. Do all the
2472 * appropriate things to set it up.
2473 */
2474 aac_add_container(sc, mir, 1);
2475 added = 1;
2476 }
2477 i++;
2478 } while ((i < mir->MntRespCount) &&
2479 (i < AAC_MAX_CONTAINERS));
2480 aac_release_sync_fib(sc);
2481
2482 /*
2483 * Go through our list of containers and see which ones
2484 * were not marked 'found'. Since the controller didn't
2485 * list them they must have been deleted. Do the
2486 * appropriate steps to destroy the device. Also reset
2487 * the co->co_found field.
2488 */
2489 co = TAILQ_FIRST(&sc->aac_container_tqh);
2490 while (co != NULL) {
2491 if (co->co_found == 0) {
2492 device_delete_child(sc->aac_dev,
2493 co->co_disk);
2494 co_next = TAILQ_NEXT(co, co_link);
2495 AAC_LOCK_ACQUIRE(&sc->
2496 aac_container_lock);
2497 TAILQ_REMOVE(&sc->aac_container_tqh, co,
2498 co_link);
2499 AAC_LOCK_RELEASE(&sc->
2500 aac_container_lock);
2501 FREE(co, M_AACBUF);
2502 co = co_next;
2503 } else {
2504 co->co_found = 0;
2505 co = TAILQ_NEXT(co, co_link);
2506 }
2507 }
2508
2509 /* Attach the newly created containers */
2510 if (added)
2511 bus_generic_attach(sc->aac_dev);
2512
2513 break;
2514
2515 default:
2516 break;
2517 }
2518
2519 default:
2520 break;
2521 }
2522
2523 /* Copy the AIF data to the AIF queue for ioctl retrieval */
2524 AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
2525 next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
2526 if (next != sc->aac_aifq_tail) {
2527 bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
2528 sc->aac_aifq_head = next;
2529
2530 /* On the off chance that someone is sleeping for an aif... */
2531 if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
2532 wakeup(sc->aac_aifq);
2533 /* Wakeup any poll()ers */
2534 selwakeup(&sc->rcv_select);
2535 }
2536 AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
2537
2538 return;
2539}
2540
2541/*
2542 * Return the Revision of the driver to userspace and check to see if the
2543 * userspace app is possibly compatible. This is extremely bogus since
2544 * our driver doesn't follow Adaptec's versioning system. Cheat by just
2545 * returning what the card reported.
2546 */
2547static int
2548aac_rev_check(struct aac_softc *sc, caddr_t udata)
2549{
2550 struct aac_rev_check rev_check;
2551 struct aac_rev_check_resp rev_check_resp;
2552 int error = 0;
2553
2554 debug_called(2);
2555
2556 /*
2557 * Copyin the revision struct from userspace
2558 */
2559 if ((error = copyin(udata, (caddr_t)&rev_check,
2560 sizeof(struct aac_rev_check))) != 0) {
2561 return error;
2562 }
2563
2564 debug(2, "Userland revision= %d\n",
2565 rev_check.callingRevision.buildNumber);
2566
2567 /*
2568 * Doctor up the response struct.
2569 */
2570 rev_check_resp.possiblyCompatible = 1;
2571 rev_check_resp.adapterSWRevision.external.ul =
2572 sc->aac_revision.external.ul;
2573 rev_check_resp.adapterSWRevision.buildNumber =
2574 sc->aac_revision.buildNumber;
2575
2576 return(copyout((caddr_t)&rev_check_resp, udata,
2577 sizeof(struct aac_rev_check_resp)));
2578}
2579
2580/*
2581 * Pass the caller the next AIF in their queue
2582 */
2583static int
2584aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
2585{
2586 struct get_adapter_fib_ioctl agf;
2587 int error;
2588
2589 debug_called(2);
2590
2591 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
2592
2593 /*
2594 * Check the magic number that we gave the caller.
2595 */
2596 if (agf.AdapterFibContext != (int)sc->aifthread) {
2597 error = EFAULT;
2598 } else {
2599 error = aac_return_aif(sc, agf.AifFib);
2600 if ((error == EAGAIN) && (agf.Wait)) {
2601 sc->aac_state |= AAC_STATE_AIF_SLEEPER;
2602 while (error == EAGAIN) {
2603 error = tsleep(sc->aac_aifq, PRIBIO |
2604 PCATCH, "aacaif", 0);
2605 if (error == 0)
2606 error = aac_return_aif(sc,
2607 agf.AifFib);
2608 }
2609 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
2610 }
2611 }
2612 }
2613 return(error);
2614}
2615
2616/*
2617 * Hand the next AIF off the top of the queue out to userspace.
2618 */
2619static int
2620aac_return_aif(struct aac_softc *sc, caddr_t uptr)
2621{
2622 int error;
2623
2624 debug_called(2);
2625
2626 AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
2627 if (sc->aac_aifq_tail == sc->aac_aifq_head) {
2628 error = EAGAIN;
2629 } else {
2630 error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr,
2631 sizeof(struct aac_aif_command));
2632 if (error)
2633 device_printf(sc->aac_dev,
2634 "aac_return_aif: copyout returned %d\n", error);
2635 if (!error)
2636 sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) %
2637 AAC_AIFQ_LENGTH;
2638 }
2639 AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
2640 return(error);
2641}
2642
2643/*
2644 * Give the userland some information about the container. The AAC arch
2645 * expects the driver to be a SCSI passthrough type driver, so it expects
2646 * the containers to have b:t:l numbers. Fake it.
2647 */
2648static int
2649aac_query_disk(struct aac_softc *sc, caddr_t uptr)
2650{
2651 struct aac_query_disk query_disk;
2652 struct aac_container *co;
2653 struct aac_disk *disk;
2654 int error, id;
2655
2656 debug_called(2);
2657
2658 disk = NULL;
2659
2660 error = copyin(uptr, (caddr_t)&query_disk,
2661 sizeof(struct aac_query_disk));
2662 if (error)
2663 return (error);
2664
2665 id = query_disk.ContainerNumber;
2666 if (id == -1)
2667 return (EINVAL);
2668
2669 AAC_LOCK_ACQUIRE(&sc->aac_container_lock);
2670 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
2671 if (co->co_mntobj.ObjectId == id)
2672 break;
2673 }
2674
2675 if (co == NULL) {
2676 query_disk.Valid = 0;
2677 query_disk.Locked = 0;
2678 query_disk.Deleted = 1; /* XXX is this right? */
2679 } else {
2680 disk = device_get_softc(co->co_disk);
2681 query_disk.Valid = 1;
2682 query_disk.Locked =
2683 (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
2684 query_disk.Deleted = 0;
2685 query_disk.Bus = device_get_unit(sc->aac_dev);
2686 query_disk.Target = disk->unit;
2687 query_disk.Lun = 0;
2688 query_disk.UnMapped = 0;
2689 sprintf(&query_disk.diskDeviceName[0], "%s%d",
2690 disk->ad_disk.d_name, disk->ad_disk.d_unit);
2691 }
2692 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2693
2694 error = copyout((caddr_t)&query_disk, uptr,
2695 sizeof(struct aac_query_disk));
2696
2697 return (error);
2698}
2699
2700static void
2701aac_get_bus_info(struct aac_softc *sc)
2702{
2703 struct aac_fib *fib;
2704 struct aac_ctcfg *c_cmd;
2705 struct aac_ctcfg_resp *c_resp;
2706 struct aac_vmioctl *vmi;
2707 struct aac_vmi_businf_resp *vmi_resp;
2708 struct aac_getbusinf businfo;
2709 struct aac_sim *caminf;
2710 device_t child;
2711 int i, found, error;
2712
2713 aac_alloc_sync_fib(sc, &fib, 0);
2714 c_cmd = (struct aac_ctcfg *)&fib->data[0];
2715 bzero(c_cmd, sizeof(struct aac_ctcfg));
2716
2717 c_cmd->Command = VM_ContainerConfig;
2718 c_cmd->cmd = CT_GET_SCSI_METHOD;
2719 c_cmd->param = 0;
2720
2721 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
2722 sizeof(struct aac_ctcfg));
2723 if (error) {
2724 device_printf(sc->aac_dev, "Error %d sending "
2725 "VM_ContainerConfig command\n", error);
2726 aac_release_sync_fib(sc);
2727 return;
2728 }
2729
2730 c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
2731 if (c_resp->Status != ST_OK) {
2732 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
2733 c_resp->Status);
2734 aac_release_sync_fib(sc);
2735 return;
2736 }
2737
2738 sc->scsi_method_id = c_resp->param;
2739
2740 vmi = (struct aac_vmioctl *)&fib->data[0];
2741 bzero(vmi, sizeof(struct aac_vmioctl));
2742
2743 vmi->Command = VM_Ioctl;
2744 vmi->ObjType = FT_DRIVE;
2745 vmi->MethId = sc->scsi_method_id;
2746 vmi->ObjId = 0;
2747 vmi->IoctlCmd = GetBusInfo;
2748
2749 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
2750 sizeof(struct aac_vmioctl));
2751 if (error) {
2752 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
2753 error);
2754 aac_release_sync_fib(sc);
2755 return;
2756 }
2757
2758 vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
2759 if (vmi_resp->Status != ST_OK) {
2760 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
2761 vmi_resp->Status);
2762 aac_release_sync_fib(sc);
2763 return;
2764 }
2765
2766 bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
2767 aac_release_sync_fib(sc);
2768
2769 found = 0;
2770 for (i = 0; i < businfo.BusCount; i++) {
2771 if (businfo.BusValid[i] != AAC_BUS_VALID)
2772 continue;
2773
2774 caminf = (struct aac_sim *)malloc( sizeof(struct aac_sim),
2775 M_AACBUF, M_NOWAIT | M_ZERO);
2776 if (caminf == NULL)
2777 continue;
2778
2779 child = device_add_child(sc->aac_dev, "aacp", -1);
2780 if (child == NULL) {
2781 device_printf(sc->aac_dev, "device_add_child failed\n");
2782 continue;
2783 }
2784
2785 caminf->TargetsPerBus = businfo.TargetsPerBus;
2786 caminf->BusNumber = i;
2787 caminf->InitiatorBusId = businfo.InitiatorBusId[i];
2788 caminf->aac_sc = sc;
2789 caminf->sim_dev = child;
2790
2791 device_set_ivars(child, caminf);
2792 device_set_desc(child, "SCSI Passthrough Bus");
2793 TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
2794
2795 found = 1;
2796 }
2797
2798 if (found)
2799 bus_generic_attach(sc->aac_dev);
2800
2801 return;
2802}
191};
192
193MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
194
195/* sysctl node */
196SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
197
198/*
199 * Device Interface
200 */
201
202/*
203 * Initialise the controller and softc
204 */
205int
206aac_attach(struct aac_softc *sc)
207{
208 int error, unit;
209
210 debug_called(1);
211
212 /*
213 * Initialise per-controller queues.
214 */
215 aac_initq_free(sc);
216 aac_initq_ready(sc);
217 aac_initq_busy(sc);
218 aac_initq_bio(sc);
219
220 /*
221 * Initialise command-completion task.
222 */
223 TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
224
225 /* disable interrupts before we enable anything */
226 AAC_MASK_INTERRUPTS(sc);
227
228 /* mark controller as suspended until we get ourselves organised */
229 sc->aac_state |= AAC_STATE_SUSPEND;
230
231 /*
232 * Check that the firmware on the card is supported.
233 */
234 if ((error = aac_check_firmware(sc)) != 0)
235 return(error);
236
237 /* Init the sync fib lock */
238 AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock");
239
240 /*
241 * Initialise the adapter.
242 */
243 if ((error = aac_init(sc)) != 0)
244 return(error);
245
246 /*
247 * Print a little information about the controller.
248 */
249 aac_describe_controller(sc);
250
251 /*
252 * Initialize locks
253 */
254 AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock");
255 TAILQ_INIT(&sc->aac_container_tqh);
256 AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
257 AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock");
258
259 /*
260 * Register to probe our containers later.
261 */
262 sc->aac_ich.ich_func = aac_startup;
263 sc->aac_ich.ich_arg = sc;
264 if (config_intrhook_establish(&sc->aac_ich) != 0) {
265 device_printf(sc->aac_dev,
266 "can't establish configuration hook\n");
267 return(ENXIO);
268 }
269
270 /*
271 * Make the control device.
272 */
273 unit = device_get_unit(sc->aac_dev);
274 sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_OPERATOR,
275 0640, "aac%d", unit);
276 (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
277 (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
278 sc->aac_dev_t->si_drv1 = sc;
279
280 /* Create the AIF thread */
281 if (kthread_create((void(*)(void *))aac_command_thread, sc,
282 &sc->aifthread, 0, 0, "aac%daif", unit))
283 panic("Could not create AIF thread\n");
284
285 /* Register the shutdown method to only be called post-dump */
286 if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
287 sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
288 device_printf(sc->aac_dev,
289 "shutdown event registration failed\n");
290
291 /* Register with CAM for the non-DASD devices */
292 if (!(sc->quirks & AAC_QUIRK_NOCAM)) {
293 TAILQ_INIT(&sc->aac_sim_tqh);
294 aac_get_bus_info(sc);
295 }
296
297 return(0);
298}
299
300/*
301 * Probe for containers, create disks.
302 */
303static void
304aac_startup(void *arg)
305{
306 struct aac_softc *sc;
307 struct aac_fib *fib;
308 struct aac_mntinfo *mi;
309 struct aac_mntinforesp *mir = NULL;
310 int i = 0;
311
312 debug_called(1);
313
314 sc = (struct aac_softc *)arg;
315
316 /* disconnect ourselves from the intrhook chain */
317 config_intrhook_disestablish(&sc->aac_ich);
318
319 aac_alloc_sync_fib(sc, &fib, 0);
320 mi = (struct aac_mntinfo *)&fib->data[0];
321
322 /* loop over possible containers */
323 do {
324 /* request information on this container */
325 bzero(mi, sizeof(struct aac_mntinfo));
326 mi->Command = VM_NameServe;
327 mi->MntType = FT_FILESYS;
328 mi->MntCount = i;
329 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
330 sizeof(struct aac_mntinfo))) {
331 debug(2, "error probing container %d", i);
332 continue;
333 }
334
335 mir = (struct aac_mntinforesp *)&fib->data[0];
336 aac_add_container(sc, mir, 0);
337 i++;
338 } while ((i < mir->MntRespCount) && (i < AAC_MAX_CONTAINERS));
339
340 aac_release_sync_fib(sc);
341
342 /* poke the bus to actually attach the child devices */
343 if (bus_generic_attach(sc->aac_dev))
344 device_printf(sc->aac_dev, "bus_generic_attach failed\n");
345
346 /* mark the controller up */
347 sc->aac_state &= ~AAC_STATE_SUSPEND;
348
349 /* enable interrupts now */
350 AAC_UNMASK_INTERRUPTS(sc);
351}
352
353/*
354 * Create a device to respresent a new container
355 */
356static void
357aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
358{
359 struct aac_container *co;
360 device_t child;
361
362 /*
363 * Check container volume type for validity. Note that many of
364 * the possible types may never show up.
365 */
366 if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
367 co = (struct aac_container *)malloc(sizeof *co, M_AACBUF,
368 M_NOWAIT | M_ZERO);
369 if (co == NULL)
370 panic("Out of memory?!\n");
371 debug(1, "id %x name '%.16s' size %u type %d",
372 mir->MntTable[0].ObjectId,
373 mir->MntTable[0].FileSystemName,
374 mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
375
376 if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
377 device_printf(sc->aac_dev, "device_add_child failed\n");
378 else
379 device_set_ivars(child, co);
380 device_set_desc(child, aac_describe_code(aac_container_types,
381 mir->MntTable[0].VolType));
382 co->co_disk = child;
383 co->co_found = f;
384 bcopy(&mir->MntTable[0], &co->co_mntobj,
385 sizeof(struct aac_mntobj));
386 AAC_LOCK_ACQUIRE(&sc->aac_container_lock);
387 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
388 AAC_LOCK_RELEASE(&sc->aac_container_lock);
389 }
390}
391
392/*
393 * Free all of the resources associated with (sc)
394 *
395 * Should not be called if the controller is active.
396 */
397void
398aac_free(struct aac_softc *sc)
399{
400
401 debug_called(1);
402
403 /* remove the control device */
404 if (sc->aac_dev_t != NULL)
405 destroy_dev(sc->aac_dev_t);
406
407 /* throw away any FIB buffers, discard the FIB DMA tag */
408 aac_free_commands(sc);
409 if (sc->aac_fib_dmat)
410 bus_dma_tag_destroy(sc->aac_fib_dmat);
411
412 free(sc->aac_commands, M_AACBUF);
413
414 /* destroy the common area */
415 if (sc->aac_common) {
416 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
417 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
418 sc->aac_common_dmamap);
419 }
420 if (sc->aac_common_dmat)
421 bus_dma_tag_destroy(sc->aac_common_dmat);
422
423 /* disconnect the interrupt handler */
424 if (sc->aac_intr)
425 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
426 if (sc->aac_irq != NULL)
427 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
428 sc->aac_irq);
429
430 /* destroy data-transfer DMA tag */
431 if (sc->aac_buffer_dmat)
432 bus_dma_tag_destroy(sc->aac_buffer_dmat);
433
434 /* destroy the parent DMA tag */
435 if (sc->aac_parent_dmat)
436 bus_dma_tag_destroy(sc->aac_parent_dmat);
437
438 /* release the register window mapping */
439 if (sc->aac_regs_resource != NULL)
440 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
441 sc->aac_regs_rid, sc->aac_regs_resource);
442}
443
444/*
445 * Disconnect from the controller completely, in preparation for unload.
446 */
447int
448aac_detach(device_t dev)
449{
450 struct aac_softc *sc;
451 struct aac_container *co;
452 struct aac_sim *sim;
453 int error;
454
455 debug_called(1);
456
457 sc = device_get_softc(dev);
458
459 if (sc->aac_state & AAC_STATE_OPEN)
460 return(EBUSY);
461
462 /* Remove the child containers */
463 while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
464 error = device_delete_child(dev, co->co_disk);
465 if (error)
466 return (error);
467 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
468 free(co, M_AACBUF);
469 }
470
471 /* Remove the CAM SIMs */
472 while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
473 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
474 error = device_delete_child(dev, sim->sim_dev);
475 if (error)
476 return (error);
477 free(sim, M_AACBUF);
478 }
479
480 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
481 sc->aifflags |= AAC_AIFFLAGS_EXIT;
482 wakeup(sc->aifthread);
483 tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
484 }
485
486 if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
487 panic("Cannot shutdown AIF thread\n");
488
489 if ((error = aac_shutdown(dev)))
490 return(error);
491
492 EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
493
494 aac_free(sc);
495
496 return(0);
497}
498
499/*
500 * Bring the controller down to a dormant state and detach all child devices.
501 *
502 * This function is called before detach or system shutdown.
503 *
504 * Note that we can assume that the bioq on the controller is empty, as we won't
505 * allow shutdown if any device is open.
506 */
507int
508aac_shutdown(device_t dev)
509{
510 struct aac_softc *sc;
511 struct aac_fib *fib;
512 struct aac_close_command *cc;
513
514 debug_called(1);
515
516 sc = device_get_softc(dev);
517
518 sc->aac_state |= AAC_STATE_SUSPEND;
519
520 /*
521 * Send a Container shutdown followed by a HostShutdown FIB to the
522 * controller to convince it that we don't want to talk to it anymore.
523 * We've been closed and all I/O completed already
524 */
525 device_printf(sc->aac_dev, "shutting down controller...");
526
527 aac_alloc_sync_fib(sc, &fib, AAC_SYNC_LOCK_FORCE);
528 cc = (struct aac_close_command *)&fib->data[0];
529
530 bzero(cc, sizeof(struct aac_close_command));
531 cc->Command = VM_CloseAll;
532 cc->ContainerId = 0xffffffff;
533 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
534 sizeof(struct aac_close_command)))
535 printf("FAILED.\n");
536 else
537 printf("done\n");
538#if 0
539 else {
540 fib->data[0] = 0;
541 /*
542 * XXX Issuing this command to the controller makes it shut down
543 * but also keeps it from coming back up without a reset of the
544 * PCI bus. This is not desirable if you are just unloading the
545 * driver module with the intent to reload it later.
546 */
547 if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
548 fib, 1)) {
549 printf("FAILED.\n");
550 } else {
551 printf("done.\n");
552 }
553 }
554#endif
555
556 AAC_MASK_INTERRUPTS(sc);
557
558 return(0);
559}
560
561/*
562 * Bring the controller to a quiescent state, ready for system suspend.
563 */
564int
565aac_suspend(device_t dev)
566{
567 struct aac_softc *sc;
568
569 debug_called(1);
570
571 sc = device_get_softc(dev);
572
573 sc->aac_state |= AAC_STATE_SUSPEND;
574
575 AAC_MASK_INTERRUPTS(sc);
576 return(0);
577}
578
579/*
580 * Bring the controller back to a state ready for operation.
581 */
582int
583aac_resume(device_t dev)
584{
585 struct aac_softc *sc;
586
587 debug_called(1);
588
589 sc = device_get_softc(dev);
590
591 sc->aac_state &= ~AAC_STATE_SUSPEND;
592 AAC_UNMASK_INTERRUPTS(sc);
593 return(0);
594}
595
596/*
597 * Take an interrupt.
598 */
599void
600aac_intr(void *arg)
601{
602 struct aac_softc *sc;
603 u_int32_t *resp_queue;
604 u_int16_t reason;
605
606 debug_called(2);
607
608 sc = (struct aac_softc *)arg;
609
610 /*
611 * Optimize the common case of adapter response interrupts.
612 * We must read from the card prior to processing the responses
613 * to ensure the clear is flushed prior to accessing the queues.
614 * Reading the queues from local memory might save us a PCI read.
615 */
616 resp_queue = sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE];
617 if (resp_queue[AAC_PRODUCER_INDEX] != resp_queue[AAC_CONSUMER_INDEX])
618 reason = AAC_DB_RESPONSE_READY;
619 else
620 reason = AAC_GET_ISTATUS(sc);
621 AAC_CLEAR_ISTATUS(sc, reason);
622 (void)AAC_GET_ISTATUS(sc);
623
624 /* It's not ok to return here because of races with the previous step */
625 if (reason & AAC_DB_RESPONSE_READY)
626 /* handle completion processing */
627 taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
628
629 /* controller wants to talk to the log */
630 if (reason & AAC_DB_PRINTF) {
631 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
632 sc->aifflags |= AAC_AIFFLAGS_PRINTF;
633 } else
634 aac_print_printf(sc);
635 }
636
637 /* controller has a message for us? */
638 if (reason & AAC_DB_COMMAND_READY) {
639 if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
640 sc->aifflags |= AAC_AIFFLAGS_AIF;
641 } else {
642 /*
643 * XXX If the kthread is dead and we're at this point,
644 * there are bigger problems than just figuring out
645 * what to do with an AIF.
646 */
647 }
648
649 }
650
651 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) != 0)
652 /* XXX Should this be done with cv_signal? */
653 wakeup(sc->aifthread);
654}
655
656/*
657 * Command Processing
658 */
659
660/*
661 * Start as much queued I/O as possible on the controller
662 */
663void
664aac_startio(struct aac_softc *sc)
665{
666 struct aac_command *cm;
667
668 debug_called(2);
669
670 for (;;) {
671 /*
672 * Try to get a command that's been put off for lack of
673 * resources
674 */
675 cm = aac_dequeue_ready(sc);
676
677 /*
678 * Try to build a command off the bio queue (ignore error
679 * return)
680 */
681 if (cm == NULL)
682 aac_bio_command(sc, &cm);
683
684 /* nothing to do? */
685 if (cm == NULL)
686 break;
687
688 /* try to give the command to the controller */
689 if (aac_start(cm) == EBUSY) {
690 /* put it on the ready queue for later */
691 aac_requeue_ready(cm);
692 break;
693 }
694 }
695}
696
697/*
698 * Deliver a command to the controller; allocate controller resources at the
699 * last moment when possible.
700 */
701static int
702aac_start(struct aac_command *cm)
703{
704 struct aac_softc *sc;
705 int error;
706
707 debug_called(2);
708
709 sc = cm->cm_sc;
710
711 /* get the command mapped */
712 aac_map_command(cm);
713
714 /* fix up the address values in the FIB */
715 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
716 cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
717
718 /* save a pointer to the command for speedy reverse-lookup */
719 cm->cm_fib->Header.SenderData = cm->cm_index;
720 /* put the FIB on the outbound queue */
721 error = aac_enqueue_fib(sc, cm->cm_queue, cm);
722 return(error);
723}
724
725/*
726 * Handle notification of one or more FIBs coming from the controller.
727 */
728static void
729aac_command_thread(struct aac_softc *sc)
730{
731 struct aac_fib *fib;
732 u_int32_t fib_size;
733 int size;
734
735 debug_called(2);
736
737 sc->aifflags |= AAC_AIFFLAGS_RUNNING;
738
739 while (!(sc->aifflags & AAC_AIFFLAGS_EXIT)) {
740 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
741 tsleep(sc->aifthread, PRIBIO, "aifthd",
742 AAC_PERIODIC_INTERVAL * hz);
743
744 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
745 aac_timeout(sc);
746
747 /* Check the hardware printf message buffer */
748 if ((sc->aifflags & AAC_AIFFLAGS_PRINTF) != 0) {
749 sc->aifflags &= ~AAC_AIFFLAGS_PRINTF;
750 aac_print_printf(sc);
751 }
752
753 /* See if any FIBs need to be allocated */
754 if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
755 mtx_lock(&Giant);
756 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
757 aac_alloc_commands(sc);
758 sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
759 AAC_LOCK_RELEASE(&sc->aac_io_lock);
760 mtx_unlock(&Giant);
761 }
762
763 /* While we're here, check to see if any commands are stuck */
764 while (sc->aifflags & AAC_AIFFLAGS_AIF) {
765 if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
766 &fib_size, &fib)) {
767 sc->aifflags &= ~AAC_AIFFLAGS_AIF;
768 break; /* nothing to do */
769 }
770
771 AAC_PRINT_FIB(sc, fib);
772
773 switch (fib->Header.Command) {
774 case AifRequest:
775 aac_handle_aif(sc, fib);
776 break;
777 default:
778 device_printf(sc->aac_dev, "unknown command "
779 "from controller\n");
780 break;
781 }
782
783 if ((fib->Header.XferState == 0) ||
784 (fib->Header.StructType != AAC_FIBTYPE_TFIB))
785 break;
786
787 /* Return the AIF to the controller. */
788 if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
789 fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
790 *(AAC_FSAStatus*)fib->data = ST_OK;
791
792 /* XXX Compute the Size field? */
793 size = fib->Header.Size;
794 if (size > sizeof(struct aac_fib)) {
795 size = sizeof(struct aac_fib);
796 fib->Header.Size = size;
797 }
798 /*
799 * Since we did not generate this command, it
800 * cannot go through the normal
801 * enqueue->startio chain.
802 */
803 aac_enqueue_response(sc,
804 AAC_ADAP_NORM_RESP_QUEUE,
805 fib);
806 }
807 }
808 }
809 sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
810 wakeup(sc->aac_dev);
811
812 mtx_lock(&Giant);
813 kthread_exit(0);
814}
815
816/*
817 * Process completed commands.
818 */
819static void
820aac_complete(void *context, int pending)
821{
822 struct aac_softc *sc;
823 struct aac_command *cm;
824 struct aac_fib *fib;
825 u_int32_t fib_size;
826
827 debug_called(2);
828
829 sc = (struct aac_softc *)context;
830
831 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
832
833 /* pull completed commands off the queue */
834 for (;;) {
835 /* look for completed FIBs on our queue */
836 if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
837 &fib))
838 break; /* nothing to do */
839
840 /* get the command, unmap and queue for later processing */
841 cm = sc->aac_commands + fib->Header.SenderData;
842 if (cm == NULL) {
843 AAC_PRINT_FIB(sc, fib);
844 break;
845 }
846
847 aac_remove_busy(cm);
848 aac_unmap_command(cm); /* XXX defer? */
849 cm->cm_flags |= AAC_CMD_COMPLETED;
850
851 /* is there a completion handler? */
852 if (cm->cm_complete != NULL) {
853 cm->cm_complete(cm);
854 } else {
855 /* assume that someone is sleeping on this command */
856 wakeup(cm);
857 }
858 }
859
860 /* see if we can start some more I/O */
861 aac_startio(sc);
862
863 AAC_LOCK_RELEASE(&sc->aac_io_lock);
864}
865
866/*
867 * Handle a bio submitted from a disk device.
868 */
869void
870aac_submit_bio(struct bio *bp)
871{
872 struct aac_disk *ad;
873 struct aac_softc *sc;
874
875 debug_called(2);
876
877 ad = (struct aac_disk *)bp->bio_disk->d_drv1;
878 sc = ad->ad_controller;
879
880 /* queue the BIO and try to get some work done */
881 aac_enqueue_bio(sc, bp);
882 aac_startio(sc);
883}
884
885/*
886 * Get a bio and build a command to go with it.
887 */
888static int
889aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
890{
891 struct aac_command *cm;
892 struct aac_fib *fib;
893 struct aac_blockread *br;
894 struct aac_blockwrite *bw;
895 struct aac_disk *ad;
896 struct bio *bp;
897
898 debug_called(2);
899
900 /* get the resources we will need */
901 cm = NULL;
902 if ((bp = aac_dequeue_bio(sc)) == NULL)
903 goto fail;
904 if (aac_alloc_command(sc, &cm)) /* get a command */
905 goto fail;
906
907 /* fill out the command */
908 cm->cm_data = (void *)bp->bio_data;
909 cm->cm_datalen = bp->bio_bcount;
910 cm->cm_complete = aac_bio_complete;
911 cm->cm_private = bp;
912 cm->cm_timestamp = time_second;
913 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
914
915 /* build the FIB */
916 fib = cm->cm_fib;
917 fib->Header.XferState =
918 AAC_FIBSTATE_HOSTOWNED |
919 AAC_FIBSTATE_INITIALISED |
920 AAC_FIBSTATE_EMPTY |
921 AAC_FIBSTATE_FROMHOST |
922 AAC_FIBSTATE_REXPECTED |
923 AAC_FIBSTATE_NORM |
924 AAC_FIBSTATE_ASYNC |
925 AAC_FIBSTATE_FAST_RESPONSE;
926 fib->Header.Command = ContainerCommand;
927 fib->Header.Size = sizeof(struct aac_fib_header);
928
929 /* build the read/write request */
930 ad = (struct aac_disk *)bp->bio_disk->d_drv1;
931 if (bp->bio_cmd == BIO_READ) {
932 br = (struct aac_blockread *)&fib->data[0];
933 br->Command = VM_CtBlockRead;
934 br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
935 br->BlockNumber = bp->bio_pblkno;
936 br->ByteCount = bp->bio_bcount;
937 fib->Header.Size += sizeof(struct aac_blockread);
938 cm->cm_sgtable = &br->SgMap;
939 cm->cm_flags |= AAC_CMD_DATAIN;
940 } else {
941 bw = (struct aac_blockwrite *)&fib->data[0];
942 bw->Command = VM_CtBlockWrite;
943 bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
944 bw->BlockNumber = bp->bio_pblkno;
945 bw->ByteCount = bp->bio_bcount;
946 bw->Stable = CUNSTABLE; /* XXX what's appropriate here? */
947 fib->Header.Size += sizeof(struct aac_blockwrite);
948 cm->cm_flags |= AAC_CMD_DATAOUT;
949 cm->cm_sgtable = &bw->SgMap;
950 }
951
952 *cmp = cm;
953 return(0);
954
955fail:
956 if (bp != NULL)
957 aac_enqueue_bio(sc, bp);
958 if (cm != NULL)
959 aac_release_command(cm);
960 return(ENOMEM);
961}
962
963/*
964 * Handle a bio-instigated command that has been completed.
965 */
966static void
967aac_bio_complete(struct aac_command *cm)
968{
969 struct aac_blockread_response *brr;
970 struct aac_blockwrite_response *bwr;
971 struct bio *bp;
972 AAC_FSAStatus status;
973
974 /* fetch relevant status and then release the command */
975 bp = (struct bio *)cm->cm_private;
976 if (bp->bio_cmd == BIO_READ) {
977 brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
978 status = brr->Status;
979 } else {
980 bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
981 status = bwr->Status;
982 }
983 aac_release_command(cm);
984
985 /* fix up the bio based on status */
986 if (status == ST_OK) {
987 bp->bio_resid = 0;
988 } else {
989 bp->bio_error = EIO;
990 bp->bio_flags |= BIO_ERROR;
991 /* pass an error string out to the disk layer */
992 bp->bio_driver1 = aac_describe_code(aac_command_status_table,
993 status);
994 }
995 aac_biodone(bp);
996}
997
998/*
999 * Submit a command to the controller, return when it completes.
1000 * XXX This is very dangerous! If the card has gone out to lunch, we could
1001 * be stuck here forever. At the same time, signals are not caught
1002 * because there is a risk that a signal could wakeup the tsleep before
1003 * the card has a chance to complete the command. The passed in timeout
1004 * is ignored for the same reason. Since there is no way to cancel a
1005 * command in progress, we should probably create a 'dead' queue where
1006 * commands go that have been interrupted/timed-out/etc, that keeps them
1007 * out of the free pool. That way, if the card is just slow, it won't
1008 * spam the memory of a command that has been recycled.
1009 */
1010static int
1011aac_wait_command(struct aac_command *cm, int timeout)
1012{
1013 struct aac_softc *sc;
1014 int error = 0;
1015
1016 debug_called(2);
1017
1018 sc = cm->cm_sc;
1019
1020 /* Put the command on the ready queue and get things going */
1021 cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1022 aac_enqueue_ready(cm);
1023 aac_startio(sc);
1024 while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
1025 error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
1026 }
1027 return(error);
1028}
1029
1030/*
1031 *Command Buffer Management
1032 */
1033
1034/*
1035 * Allocate a command.
1036 */
1037int
1038aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1039{
1040 struct aac_command *cm;
1041
1042 debug_called(3);
1043
1044 if ((cm = aac_dequeue_free(sc)) == NULL) {
1045 sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1046 wakeup(sc->aifthread);
1047 return (EBUSY);
1048 }
1049
1050 *cmp = cm;
1051 return(0);
1052}
1053
1054/*
1055 * Release a command back to the freelist.
1056 */
1057void
1058aac_release_command(struct aac_command *cm)
1059{
1060 debug_called(3);
1061
1062 /* (re)initialise the command/FIB */
1063 cm->cm_sgtable = NULL;
1064 cm->cm_flags = 0;
1065 cm->cm_complete = NULL;
1066 cm->cm_private = NULL;
1067 cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1068 cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1069 cm->cm_fib->Header.Flags = 0;
1070 cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1071
1072 /*
1073 * These are duplicated in aac_start to cover the case where an
1074 * intermediate stage may have destroyed them. They're left
1075 * initialised here for debugging purposes only.
1076 */
1077 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
1078 cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1079 cm->cm_fib->Header.SenderData = 0;
1080
1081 aac_enqueue_free(cm);
1082}
1083
1084/*
1085 * Map helper for command/FIB allocation.
1086 */
1087static void
1088aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1089{
1090 uint32_t *fibphys;
1091
1092 fibphys = (uint32_t *)arg;
1093
1094 debug_called(3);
1095
1096 *fibphys = segs[0].ds_addr;
1097}
1098
1099/*
1100 * Allocate and initialise commands/FIBs for this adapter.
1101 */
1102static int
1103aac_alloc_commands(struct aac_softc *sc)
1104{
1105 struct aac_command *cm;
1106 struct aac_fibmap *fm;
1107 uint32_t fibphys;
1108 int i, error;
1109
1110 debug_called(1);
1111
1112 if (sc->total_fibs + AAC_FIB_COUNT > AAC_MAX_FIBS)
1113 return (ENOMEM);
1114
1115 fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
1116
1117 /* allocate the FIBs in DMAable memory and load them */
1118 if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1119 BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1120 device_printf(sc->aac_dev,
1121 "Not enough contiguous memory available.\n");
1122 free(fm, M_AACBUF);
1123 return (ENOMEM);
1124 }
1125
1126 bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1127 AAC_FIB_COUNT * sizeof(struct aac_fib),
1128 aac_map_command_helper, &fibphys, 0);
1129
1130 /* initialise constant fields in the command structure */
1131 bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib));
1132 for (i = 0; i < AAC_FIB_COUNT; i++) {
1133 cm = sc->aac_commands + sc->total_fibs;
1134 fm->aac_commands = cm;
1135 cm->cm_sc = sc;
1136 cm->cm_fib = fm->aac_fibs + i;
1137 cm->cm_fibphys = fibphys + (i * sizeof(struct aac_fib));
1138 cm->cm_index = sc->total_fibs;
1139
1140 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1141 &cm->cm_datamap)) == 0)
1142 aac_release_command(cm);
1143 else
1144 break;
1145 sc->total_fibs++;
1146 }
1147
1148 if (i > 0) {
1149 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1150 return (0);
1151 }
1152
1153 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1154 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1155 free(fm, M_AACBUF);
1156 return (ENOMEM);
1157}
1158
1159/*
1160 * Free FIBs owned by this adapter.
1161 */
1162static void
1163aac_free_commands(struct aac_softc *sc)
1164{
1165 struct aac_fibmap *fm;
1166 struct aac_command *cm;
1167 int i;
1168
1169 debug_called(1);
1170
1171 while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1172
1173 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1174 /*
1175 * We check against total_fibs to handle partially
1176 * allocated blocks.
1177 */
1178 for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) {
1179 cm = fm->aac_commands + i;
1180 bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1181 }
1182 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1183 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1184 free(fm, M_AACBUF);
1185 }
1186}
1187
1188/*
1189 * Command-mapping helper function - populate this command's s/g table.
1190 */
1191static void
1192aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1193{
1194 struct aac_command *cm;
1195 struct aac_fib *fib;
1196 struct aac_sg_table *sg;
1197 int i;
1198
1199 debug_called(3);
1200
1201 cm = (struct aac_command *)arg;
1202 fib = cm->cm_fib;
1203
1204 /* find the s/g table */
1205 sg = cm->cm_sgtable;
1206
1207 /* copy into the FIB */
1208 if (sg != NULL) {
1209 sg->SgCount = nseg;
1210 for (i = 0; i < nseg; i++) {
1211 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1212 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1213 }
1214 /* update the FIB size for the s/g count */
1215 fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1216 }
1217
1218}
1219
1220/*
1221 * Map a command into controller-visible space.
1222 */
1223static void
1224aac_map_command(struct aac_command *cm)
1225{
1226 struct aac_softc *sc;
1227
1228 debug_called(2);
1229
1230 sc = cm->cm_sc;
1231
1232 /* don't map more than once */
1233 if (cm->cm_flags & AAC_CMD_MAPPED)
1234 return;
1235
1236 if (cm->cm_datalen != 0) {
1237 bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
1238 cm->cm_data, cm->cm_datalen,
1239 aac_map_command_sg, cm, 0);
1240
1241 if (cm->cm_flags & AAC_CMD_DATAIN)
1242 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1243 BUS_DMASYNC_PREREAD);
1244 if (cm->cm_flags & AAC_CMD_DATAOUT)
1245 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1246 BUS_DMASYNC_PREWRITE);
1247 }
1248 cm->cm_flags |= AAC_CMD_MAPPED;
1249}
1250
1251/*
1252 * Unmap a command from controller-visible space.
1253 */
1254static void
1255aac_unmap_command(struct aac_command *cm)
1256{
1257 struct aac_softc *sc;
1258
1259 debug_called(2);
1260
1261 sc = cm->cm_sc;
1262
1263 if (!(cm->cm_flags & AAC_CMD_MAPPED))
1264 return;
1265
1266 if (cm->cm_datalen != 0) {
1267 if (cm->cm_flags & AAC_CMD_DATAIN)
1268 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1269 BUS_DMASYNC_POSTREAD);
1270 if (cm->cm_flags & AAC_CMD_DATAOUT)
1271 bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1272 BUS_DMASYNC_POSTWRITE);
1273
1274 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1275 }
1276 cm->cm_flags &= ~AAC_CMD_MAPPED;
1277}
1278
1279/*
1280 * Hardware Interface
1281 */
1282
1283/*
1284 * Initialise the adapter.
1285 */
1286static void
1287aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1288{
1289 struct aac_softc *sc;
1290
1291 debug_called(1);
1292
1293 sc = (struct aac_softc *)arg;
1294
1295 sc->aac_common_busaddr = segs[0].ds_addr;
1296}
1297
1298/*
1299 * Retrieve the firmware version numbers. Dell PERC2/QC cards with
1300 * firmware version 1.x are not compatible with this driver.
1301 */
1302static int
1303aac_check_firmware(struct aac_softc *sc)
1304{
1305 u_int32_t major, minor;
1306
1307 debug_called(1);
1308
1309 if (sc->quirks & AAC_QUIRK_PERC2QC) {
1310 if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1311 NULL)) {
1312 device_printf(sc->aac_dev,
1313 "Error reading firmware version\n");
1314 return (EIO);
1315 }
1316
1317 /* These numbers are stored as ASCII! */
1318 major = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 4) & 0xff) - 0x30;
1319 minor = (AAC_GETREG4(sc, AAC_SA_MAILBOX + 8) & 0xff) - 0x30;
1320 if (major == 1) {
1321 device_printf(sc->aac_dev,
1322 "Firmware version %d.%d is not supported.\n",
1323 major, minor);
1324 return (EINVAL);
1325 }
1326 }
1327
1328 return (0);
1329}
1330
1331static int
1332aac_init(struct aac_softc *sc)
1333{
1334 struct aac_adapter_init *ip;
1335 time_t then;
1336 u_int32_t code;
1337 u_int8_t *qaddr;
1338
1339 debug_called(1);
1340
1341 /*
1342 * First wait for the adapter to come ready.
1343 */
1344 then = time_second;
1345 do {
1346 code = AAC_GET_FWSTATUS(sc);
1347 if (code & AAC_SELF_TEST_FAILED) {
1348 device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1349 return(ENXIO);
1350 }
1351 if (code & AAC_KERNEL_PANIC) {
1352 device_printf(sc->aac_dev,
1353 "FATAL: controller kernel panic\n");
1354 return(ENXIO);
1355 }
1356 if (time_second > (then + AAC_BOOT_TIMEOUT)) {
1357 device_printf(sc->aac_dev,
1358 "FATAL: controller not coming ready, "
1359 "status %x\n", code);
1360 return(ENXIO);
1361 }
1362 } while (!(code & AAC_UP_AND_RUNNING));
1363
1364 /*
1365 * Create DMA tag for the common structure and allocate it.
1366 */
1367 if (bus_dma_tag_create(sc->aac_parent_dmat, /* parent */
1368 1, 0, /* algnmnt, boundary */
1369 BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
1370 BUS_SPACE_MAXADDR, /* highaddr */
1371 NULL, NULL, /* filter, filterarg */
1372 8192 + sizeof(struct aac_common), /* maxsize */
1373 1, /* nsegments */
1374 BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
1375 0, /* flags */
1376 &sc->aac_common_dmat)) {
1377 device_printf(sc->aac_dev,
1378 "can't allocate common structure DMA tag\n");
1379 return(ENOMEM);
1380 }
1381 if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1382 BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1383 device_printf(sc->aac_dev, "can't allocate common structure\n");
1384 return(ENOMEM);
1385 }
1386
1387 /*
1388 * Work around a bug in the 2120 and 2200 that cannot DMA commands
1389 * below address 8192 in physical memory.
1390 * XXX If the padding is not needed, can it be put to use instead
1391 * of ignored?
1392 */
1393 bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1394 sc->aac_common, 8192 + sizeof(*sc->aac_common),
1395 aac_common_map, sc, 0);
1396
1397 if (sc->aac_common_busaddr < 8192) {
1398 (uint8_t *)sc->aac_common += 8192;
1399 sc->aac_common_busaddr += 8192;
1400 }
1401 bzero(sc->aac_common, sizeof(*sc->aac_common));
1402
1403 /* Allocate some FIBs and associated command structs */
1404 TAILQ_INIT(&sc->aac_fibmap_tqh);
1405 sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command),
1406 M_AACBUF, M_WAITOK|M_ZERO);
1407 while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
1408 if (aac_alloc_commands(sc) != 0)
1409 break;
1410 }
1411 if (sc->total_fibs == 0)
1412 return (ENOMEM);
1413
1414 /*
1415 * Fill in the init structure. This tells the adapter about the
1416 * physical location of various important shared data structures.
1417 */
1418 ip = &sc->aac_common->ac_init;
1419 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1420 ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1421
1422 ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1423 offsetof(struct aac_common, ac_fibs);
1424 ip->AdapterFibsVirtualAddress = (u_int32_t)&sc->aac_common->ac_fibs[0];
1425 ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1426 ip->AdapterFibAlign = sizeof(struct aac_fib);
1427
1428 ip->PrintfBufferAddress = sc->aac_common_busaddr +
1429 offsetof(struct aac_common, ac_printf);
1430 ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1431
1432 /* The adapter assumes that pages are 4K in size */
1433 ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1434 ip->HostElapsedSeconds = time_second; /* reset later if invalid */
1435
1436 /*
1437 * Initialise FIB queues. Note that it appears that the layout of the
1438 * indexes and the segmentation of the entries may be mandated by the
1439 * adapter, which is only told about the base of the queue index fields.
1440 *
1441 * The initial values of the indices are assumed to inform the adapter
1442 * of the sizes of the respective queues, and theoretically it could
1443 * work out the entire layout of the queue structures from this. We
1444 * take the easy route and just lay this area out like everyone else
1445 * does.
1446 *
1447 * The Linux driver uses a much more complex scheme whereby several
1448 * header records are kept for each queue. We use a couple of generic
1449 * list manipulation functions which 'know' the size of each list by
1450 * virtue of a table.
1451 */
1452 qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1453 qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1454 sc->aac_queues = (struct aac_queue_table *)qaddr;
1455 ip->CommHeaderAddress = sc->aac_common_busaddr +
1456 ((u_int32_t)sc->aac_queues -
1457 (u_int32_t)sc->aac_common);
1458
1459 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1460 AAC_HOST_NORM_CMD_ENTRIES;
1461 sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1462 AAC_HOST_NORM_CMD_ENTRIES;
1463 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1464 AAC_HOST_HIGH_CMD_ENTRIES;
1465 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1466 AAC_HOST_HIGH_CMD_ENTRIES;
1467 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1468 AAC_ADAP_NORM_CMD_ENTRIES;
1469 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1470 AAC_ADAP_NORM_CMD_ENTRIES;
1471 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1472 AAC_ADAP_HIGH_CMD_ENTRIES;
1473 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1474 AAC_ADAP_HIGH_CMD_ENTRIES;
1475 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1476 AAC_HOST_NORM_RESP_ENTRIES;
1477 sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1478 AAC_HOST_NORM_RESP_ENTRIES;
1479 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1480 AAC_HOST_HIGH_RESP_ENTRIES;
1481 sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1482 AAC_HOST_HIGH_RESP_ENTRIES;
1483 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1484 AAC_ADAP_NORM_RESP_ENTRIES;
1485 sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1486 AAC_ADAP_NORM_RESP_ENTRIES;
1487 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1488 AAC_ADAP_HIGH_RESP_ENTRIES;
1489 sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1490 AAC_ADAP_HIGH_RESP_ENTRIES;
1491 sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1492 &sc->aac_queues->qt_HostNormCmdQueue[0];
1493 sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1494 &sc->aac_queues->qt_HostHighCmdQueue[0];
1495 sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1496 &sc->aac_queues->qt_AdapNormCmdQueue[0];
1497 sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1498 &sc->aac_queues->qt_AdapHighCmdQueue[0];
1499 sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1500 &sc->aac_queues->qt_HostNormRespQueue[0];
1501 sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1502 &sc->aac_queues->qt_HostHighRespQueue[0];
1503 sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1504 &sc->aac_queues->qt_AdapNormRespQueue[0];
1505 sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1506 &sc->aac_queues->qt_AdapHighRespQueue[0];
1507
1508 /*
1509 * Do controller-type-specific initialisation
1510 */
1511 switch (sc->aac_hwif) {
1512 case AAC_HWIF_I960RX:
1513 AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1514 break;
1515 }
1516
1517 /*
1518 * Give the init structure to the controller.
1519 */
1520 if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1521 sc->aac_common_busaddr +
1522 offsetof(struct aac_common, ac_init), 0, 0, 0,
1523 NULL)) {
1524 device_printf(sc->aac_dev,
1525 "error establishing init structure\n");
1526 return(EIO);
1527 }
1528
1529 return(0);
1530}
1531
1532/*
1533 * Send a synchronous command to the controller and wait for a result.
1534 */
1535static int
1536aac_sync_command(struct aac_softc *sc, u_int32_t command,
1537 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1538 u_int32_t *sp)
1539{
1540 time_t then;
1541 u_int32_t status;
1542
1543 debug_called(3);
1544
1545 /* populate the mailbox */
1546 AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1547
1548 /* ensure the sync command doorbell flag is cleared */
1549 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1550
1551 /* then set it to signal the adapter */
1552 AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1553
1554 /* spin waiting for the command to complete */
1555 then = time_second;
1556 do {
1557 if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) {
1558 debug(2, "timed out");
1559 return(EIO);
1560 }
1561 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1562
1563 /* clear the completion flag */
1564 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1565
1566 /* get the command status */
1567 status = AAC_GET_MAILBOXSTATUS(sc);
1568 if (sp != NULL)
1569 *sp = status;
1570 return(0);
1571}
1572
1573/*
1574 * Grab the sync fib area.
1575 */
1576int
1577aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1578{
1579
1580 /*
1581 * If the force flag is set, the system is shutting down, or in
1582 * trouble. Ignore the mutex.
1583 */
1584 if (!(flags & AAC_SYNC_LOCK_FORCE))
1585 AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);
1586
1587 *fib = &sc->aac_common->ac_sync_fib;
1588
1589 return (1);
1590}
1591
1592/*
1593 * Release the sync fib area.
1594 */
1595void
1596aac_release_sync_fib(struct aac_softc *sc)
1597{
1598
1599 AAC_LOCK_RELEASE(&sc->aac_sync_lock);
1600}
1601
1602/*
1603 * Send a synchronous FIB to the controller and wait for a result.
1604 */
1605int
1606aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1607 struct aac_fib *fib, u_int16_t datasize)
1608{
1609 debug_called(3);
1610
1611 if (datasize > AAC_FIB_DATASIZE)
1612 return(EINVAL);
1613
1614 /*
1615 * Set up the sync FIB
1616 */
1617 fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1618 AAC_FIBSTATE_INITIALISED |
1619 AAC_FIBSTATE_EMPTY;
1620 fib->Header.XferState |= xferstate;
1621 fib->Header.Command = command;
1622 fib->Header.StructType = AAC_FIBTYPE_TFIB;
1623 fib->Header.Size = sizeof(struct aac_fib) + datasize;
1624 fib->Header.SenderSize = sizeof(struct aac_fib);
1625 fib->Header.SenderFibAddress = (u_int32_t)fib;
1626 fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1627 offsetof(struct aac_common,
1628 ac_sync_fib);
1629
1630 /*
1631 * Give the FIB to the controller, wait for a response.
1632 */
1633 if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1634 fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1635 debug(2, "IO error");
1636 return(EIO);
1637 }
1638
1639 return (0);
1640}
1641
1642/*
1643 * Adapter-space FIB queue manipulation
1644 *
1645 * Note that the queue implementation here is a little funky; neither the PI or
1646 * CI will ever be zero. This behaviour is a controller feature.
1647 */
1648static struct {
1649 int size;
1650 int notify;
1651} aac_qinfo[] = {
1652 {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
1653 {AAC_HOST_HIGH_CMD_ENTRIES, 0},
1654 {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
1655 {AAC_ADAP_HIGH_CMD_ENTRIES, 0},
1656 {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
1657 {AAC_HOST_HIGH_RESP_ENTRIES, 0},
1658 {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
1659 {AAC_ADAP_HIGH_RESP_ENTRIES, 0}
1660};
1661
1662/*
1663 * Atomically insert an entry into the nominated queue, returns 0 on success or
1664 * EBUSY if the queue is full.
1665 *
1666 * Note: it would be more efficient to defer notifying the controller in
1667 * the case where we may be inserting several entries in rapid succession,
1668 * but implementing this usefully may be difficult (it would involve a
1669 * separate queue/notify interface).
1670 */
1671static int
1672aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1673{
1674 u_int32_t pi, ci;
1675 int error;
1676 u_int32_t fib_size;
1677 u_int32_t fib_addr;
1678
1679 debug_called(3);
1680
1681 fib_size = cm->cm_fib->Header.Size;
1682 fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1683
1684 /* get the producer/consumer indices */
1685 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1686 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1687
1688 /* wrap the queue? */
1689 if (pi >= aac_qinfo[queue].size)
1690 pi = 0;
1691
1692 /* check for queue full */
1693 if ((pi + 1) == ci) {
1694 error = EBUSY;
1695 goto out;
1696 }
1697
1698 /* populate queue entry */
1699 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1700 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1701
1702 /* update producer index */
1703 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1704
1705 /*
1706 * To avoid a race with its completion interrupt, place this command on
1707 * the busy queue prior to advertising it to the controller.
1708 */
1709 aac_enqueue_busy(cm);
1710
1711 /* notify the adapter if we know how */
1712 if (aac_qinfo[queue].notify != 0)
1713 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1714
1715 error = 0;
1716
1717out:
1718 return(error);
1719}
1720
1721/*
1722 * Atomically remove one entry from the nominated queue, returns 0 on
1723 * success or ENOENT if the queue is empty.
1724 */
1725static int
1726aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1727 struct aac_fib **fib_addr)
1728{
1729 u_int32_t pi, ci;
1730 int error;
1731 int notify;
1732
1733 debug_called(3);
1734
1735 /* get the producer/consumer indices */
1736 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1737 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1738
1739 /* check for queue empty */
1740 if (ci == pi) {
1741 error = ENOENT;
1742 goto out;
1743 }
1744
1745 notify = 0;
1746 if (ci == pi + 1)
1747 notify++;
1748
1749 /* wrap the queue? */
1750 if (ci >= aac_qinfo[queue].size)
1751 ci = 0;
1752
1753 /* fetch the entry */
1754 *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1755 *fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] +
1756 ci)->aq_fib_addr;
1757
1758 /*
1759 * Is this a fast response? If it is, update the fib fields in
1760 * local memory so the whole fib doesn't have to be DMA'd back up.
1761 */
1762 if (*(uintptr_t *)fib_addr & 0x01) {
1763 *(uintptr_t *)fib_addr &= ~0x01;
1764 (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
1765 *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
1766 }
1767 /* update consumer index */
1768 sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1769
1770 /* if we have made the queue un-full, notify the adapter */
1771 if (notify && (aac_qinfo[queue].notify != 0))
1772 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1773 error = 0;
1774
1775out:
1776 return(error);
1777}
1778
1779/*
1780 * Put our response to an Adapter Initialed Fib on the response queue
1781 */
1782static int
1783aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1784{
1785 u_int32_t pi, ci;
1786 int error;
1787 u_int32_t fib_size;
1788 u_int32_t fib_addr;
1789
1790 debug_called(1);
1791
1792 /* Tell the adapter where the FIB is */
1793 fib_size = fib->Header.Size;
1794 fib_addr = fib->Header.SenderFibAddress;
1795 fib->Header.ReceiverFibAddress = fib_addr;
1796
1797 /* get the producer/consumer indices */
1798 pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1799 ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1800
1801 /* wrap the queue? */
1802 if (pi >= aac_qinfo[queue].size)
1803 pi = 0;
1804
1805 /* check for queue full */
1806 if ((pi + 1) == ci) {
1807 error = EBUSY;
1808 goto out;
1809 }
1810
1811 /* populate queue entry */
1812 (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1813 (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1814
1815 /* update producer index */
1816 sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1817
1818 /* notify the adapter if we know how */
1819 if (aac_qinfo[queue].notify != 0)
1820 AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1821
1822 error = 0;
1823
1824out:
1825 return(error);
1826}
1827
1828/*
1829 * Check for commands that have been outstanding for a suspiciously long time,
1830 * and complain about them.
1831 */
1832static void
1833aac_timeout(struct aac_softc *sc)
1834{
1835 struct aac_command *cm;
1836 time_t deadline;
1837
1838 /*
1839 * Traverse the busy command list, bitch about late commands once
1840 * only.
1841 */
1842 deadline = time_second - AAC_CMD_TIMEOUT;
1843 TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1844 if ((cm->cm_timestamp < deadline)
1845 /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
1846 cm->cm_flags |= AAC_CMD_TIMEDOUT;
1847 device_printf(sc->aac_dev,
1848 "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
1849 cm, (int)(time_second-cm->cm_timestamp));
1850 AAC_PRINT_FIB(sc, cm->cm_fib);
1851 }
1852 }
1853
1854 return;
1855}
1856
1857/*
1858 * Interface Function Vectors
1859 */
1860
1861/*
1862 * Read the current firmware status word.
1863 */
1864static int
1865aac_sa_get_fwstatus(struct aac_softc *sc)
1866{
1867 debug_called(3);
1868
1869 return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1870}
1871
1872static int
1873aac_rx_get_fwstatus(struct aac_softc *sc)
1874{
1875 debug_called(3);
1876
1877 return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1878}
1879
1880static int
1881aac_fa_get_fwstatus(struct aac_softc *sc)
1882{
1883 int val;
1884
1885 debug_called(3);
1886
1887 val = AAC_GETREG4(sc, AAC_FA_FWSTATUS);
1888 return (val);
1889}
1890
1891/*
1892 * Notify the controller of a change in a given queue
1893 */
1894
1895static void
1896aac_sa_qnotify(struct aac_softc *sc, int qbit)
1897{
1898 debug_called(3);
1899
1900 AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1901}
1902
1903static void
1904aac_rx_qnotify(struct aac_softc *sc, int qbit)
1905{
1906 debug_called(3);
1907
1908 AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1909}
1910
1911static void
1912aac_fa_qnotify(struct aac_softc *sc, int qbit)
1913{
1914 debug_called(3);
1915
1916 AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
1917 AAC_FA_HACK(sc);
1918}
1919
1920/*
1921 * Get the interrupt reason bits
1922 */
1923static int
1924aac_sa_get_istatus(struct aac_softc *sc)
1925{
1926 debug_called(3);
1927
1928 return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1929}
1930
1931static int
1932aac_rx_get_istatus(struct aac_softc *sc)
1933{
1934 debug_called(3);
1935
1936 return(AAC_GETREG4(sc, AAC_RX_ODBR));
1937}
1938
1939static int
1940aac_fa_get_istatus(struct aac_softc *sc)
1941{
1942 int val;
1943
1944 debug_called(3);
1945
1946 val = AAC_GETREG2(sc, AAC_FA_DOORBELL0);
1947 return (val);
1948}
1949
1950/*
1951 * Clear some interrupt reason bits
1952 */
1953static void
1954aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1955{
1956 debug_called(3);
1957
1958 AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1959}
1960
1961static void
1962aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1963{
1964 debug_called(3);
1965
1966 AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1967}
1968
1969static void
1970aac_fa_clear_istatus(struct aac_softc *sc, int mask)
1971{
1972 debug_called(3);
1973
1974 AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
1975 AAC_FA_HACK(sc);
1976}
1977
1978/*
1979 * Populate the mailbox and set the command word
1980 */
1981static void
1982aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
1983 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1984{
1985 debug_called(4);
1986
1987 AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1988 AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1989 AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1990 AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1991 AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1992}
1993
1994static void
1995aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
1996 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1997{
1998 debug_called(4);
1999
2000 AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
2001 AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2002 AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2003 AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2004 AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2005}
2006
2007static void
2008aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2009 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2010{
2011 debug_called(4);
2012
2013 AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
2014 AAC_FA_HACK(sc);
2015 AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
2016 AAC_FA_HACK(sc);
2017 AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
2018 AAC_FA_HACK(sc);
2019 AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
2020 AAC_FA_HACK(sc);
2021 AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
2022 AAC_FA_HACK(sc);
2023}
2024
2025/*
2026 * Fetch the immediate command status word
2027 */
2028static int
2029aac_sa_get_mailboxstatus(struct aac_softc *sc)
2030{
2031 debug_called(4);
2032
2033 return(AAC_GETREG4(sc, AAC_SA_MAILBOX));
2034}
2035
2036static int
2037aac_rx_get_mailboxstatus(struct aac_softc *sc)
2038{
2039 debug_called(4);
2040
2041 return(AAC_GETREG4(sc, AAC_RX_MAILBOX));
2042}
2043
2044static int
2045aac_fa_get_mailboxstatus(struct aac_softc *sc)
2046{
2047 int val;
2048
2049 debug_called(4);
2050
2051 val = AAC_GETREG4(sc, AAC_FA_MAILBOX);
2052 return (val);
2053}
2054
2055/*
2056 * Set/clear interrupt masks
2057 */
2058static void
2059aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2060{
2061 debug(2, "%sable interrupts", enable ? "en" : "dis");
2062
2063 if (enable) {
2064 AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2065 } else {
2066 AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2067 }
2068}
2069
2070static void
2071aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2072{
2073 debug(2, "%sable interrupts", enable ? "en" : "dis");
2074
2075 if (enable) {
2076 AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2077 } else {
2078 AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
2079 }
2080}
2081
2082static void
2083aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2084{
2085 debug(2, "%sable interrupts", enable ? "en" : "dis");
2086
2087 if (enable) {
2088 AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2089 AAC_FA_HACK(sc);
2090 } else {
2091 AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
2092 AAC_FA_HACK(sc);
2093 }
2094}
2095
2096/*
2097 * Debugging and Diagnostics
2098 */
2099
2100/*
2101 * Print some information about the controller.
2102 */
2103static void
2104aac_describe_controller(struct aac_softc *sc)
2105{
2106 struct aac_fib *fib;
2107 struct aac_adapter_info *info;
2108
2109 debug_called(2);
2110
2111 aac_alloc_sync_fib(sc, &fib, 0);
2112
2113 fib->data[0] = 0;
2114 if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2115 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2116 aac_release_sync_fib(sc);
2117 return;
2118 }
2119 info = (struct aac_adapter_info *)&fib->data[0];
2120
2121 device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n",
2122 aac_describe_code(aac_cpu_variant, info->CpuVariant),
2123 info->ClockSpeed, info->BufferMem / (1024 * 1024),
2124 aac_describe_code(aac_battery_platform,
2125 info->batteryPlatform));
2126
2127 /* save the kernel revision structure for later use */
2128 sc->aac_revision = info->KernelRevision;
2129 device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2130 info->KernelRevision.external.comp.major,
2131 info->KernelRevision.external.comp.minor,
2132 info->KernelRevision.external.comp.dash,
2133 info->KernelRevision.buildNumber,
2134 (u_int32_t)(info->SerialNumber & 0xffffff));
2135
2136 aac_release_sync_fib(sc);
2137}
2138
2139/*
2140 * Look up a text description of a numeric error code and return a pointer to
2141 * same.
2142 */
2143static char *
2144aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2145{
2146 int i;
2147
2148 for (i = 0; table[i].string != NULL; i++)
2149 if (table[i].code == code)
2150 return(table[i].string);
2151 return(table[i + 1].string);
2152}
2153
2154/*
2155 * Management Interface
2156 */
2157
2158static int
2159aac_open(dev_t dev, int flags, int fmt, d_thread_t *td)
2160{
2161 struct aac_softc *sc;
2162
2163 debug_called(2);
2164
2165 sc = dev->si_drv1;
2166
2167 /* Check to make sure the device isn't already open */
2168 if (sc->aac_state & AAC_STATE_OPEN) {
2169 return EBUSY;
2170 }
2171 sc->aac_state |= AAC_STATE_OPEN;
2172
2173 return 0;
2174}
2175
2176static int
2177aac_close(dev_t dev, int flags, int fmt, d_thread_t *td)
2178{
2179 struct aac_softc *sc;
2180
2181 debug_called(2);
2182
2183 sc = dev->si_drv1;
2184
2185 /* Mark this unit as no longer open */
2186 sc->aac_state &= ~AAC_STATE_OPEN;
2187
2188 return 0;
2189}
2190
2191static int
2192aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
2193{
2194 union aac_statrequest *as;
2195 struct aac_softc *sc;
2196 int error = 0;
2197 int i;
2198
2199 debug_called(2);
2200
2201 as = (union aac_statrequest *)arg;
2202 sc = dev->si_drv1;
2203
2204 switch (cmd) {
2205 case AACIO_STATS:
2206 switch (as->as_item) {
2207 case AACQ_FREE:
2208 case AACQ_BIO:
2209 case AACQ_READY:
2210 case AACQ_BUSY:
2211 case AACQ_COMPLETE:
2212 bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2213 sizeof(struct aac_qstat));
2214 break;
2215 default:
2216 error = ENOENT;
2217 break;
2218 }
2219 break;
2220
2221 case FSACTL_SENDFIB:
2222 arg = *(caddr_t*)arg;
2223 case FSACTL_LNX_SENDFIB:
2224 debug(1, "FSACTL_SENDFIB");
2225 error = aac_ioctl_sendfib(sc, arg);
2226 break;
2227 case FSACTL_AIF_THREAD:
2228 case FSACTL_LNX_AIF_THREAD:
2229 debug(1, "FSACTL_AIF_THREAD");
2230 error = EINVAL;
2231 break;
2232 case FSACTL_OPEN_GET_ADAPTER_FIB:
2233 arg = *(caddr_t*)arg;
2234 case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2235 debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
2236 /*
2237 * Pass the caller out an AdapterFibContext.
2238 *
2239 * Note that because we only support one opener, we
2240 * basically ignore this. Set the caller's context to a magic
2241 * number just in case.
2242 *
2243 * The Linux code hands the driver a pointer into kernel space,
2244 * and then trusts it when the caller hands it back. Aiee!
2245 * Here, we give it the proc pointer of the per-adapter aif
2246 * thread. It's only used as a sanity check in other calls.
2247 */
2248 i = (int)sc->aifthread;
2249 error = copyout(&i, arg, sizeof(i));
2250 break;
2251 case FSACTL_GET_NEXT_ADAPTER_FIB:
2252 arg = *(caddr_t*)arg;
2253 case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2254 debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB");
2255 error = aac_getnext_aif(sc, arg);
2256 break;
2257 case FSACTL_CLOSE_GET_ADAPTER_FIB:
2258 case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2259 debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2260 /* don't do anything here */
2261 break;
2262 case FSACTL_MINIPORT_REV_CHECK:
2263 arg = *(caddr_t*)arg;
2264 case FSACTL_LNX_MINIPORT_REV_CHECK:
2265 debug(1, "FSACTL_MINIPORT_REV_CHECK");
2266 error = aac_rev_check(sc, arg);
2267 break;
2268 case FSACTL_QUERY_DISK:
2269 arg = *(caddr_t*)arg;
2270 case FSACTL_LNX_QUERY_DISK:
2271 debug(1, "FSACTL_QUERY_DISK");
2272 error = aac_query_disk(sc, arg);
2273 break;
2274 case FSACTL_DELETE_DISK:
2275 case FSACTL_LNX_DELETE_DISK:
2276 /*
2277 * We don't trust the underland to tell us when to delete a
2278 * container, rather we rely on an AIF coming from the
2279 * controller
2280 */
2281 error = 0;
2282 break;
2283 default:
2284 debug(1, "unsupported cmd 0x%lx\n", cmd);
2285 error = EINVAL;
2286 break;
2287 }
2288 return(error);
2289}
2290
2291static int
2292aac_poll(dev_t dev, int poll_events, d_thread_t *td)
2293{
2294 struct aac_softc *sc;
2295 int revents;
2296
2297 sc = dev->si_drv1;
2298 revents = 0;
2299
2300 AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
2301 if ((poll_events & (POLLRDNORM | POLLIN)) != 0) {
2302 if (sc->aac_aifq_tail != sc->aac_aifq_head)
2303 revents |= poll_events & (POLLIN | POLLRDNORM);
2304 }
2305 AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
2306
2307 if (revents == 0) {
2308 if (poll_events & (POLLIN | POLLRDNORM))
2309 selrecord(td, &sc->rcv_select);
2310 }
2311
2312 return (revents);
2313}
2314
2315/*
2316 * Send a FIB supplied from userspace
2317 */
2318static int
2319aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2320{
2321 struct aac_command *cm;
2322 int size, error;
2323
2324 debug_called(2);
2325
2326 cm = NULL;
2327
2328 /*
2329 * Get a command
2330 */
2331 AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
2332 if (aac_alloc_command(sc, &cm)) {
2333 error = EBUSY;
2334 goto out;
2335 }
2336
2337 /*
2338 * Fetch the FIB header, then re-copy to get data as well.
2339 */
2340 if ((error = copyin(ufib, cm->cm_fib,
2341 sizeof(struct aac_fib_header))) != 0)
2342 goto out;
2343 size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
2344 if (size > sizeof(struct aac_fib)) {
2345 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
2346 size, sizeof(struct aac_fib));
2347 size = sizeof(struct aac_fib);
2348 }
2349 if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
2350 goto out;
2351 cm->cm_fib->Header.Size = size;
2352 cm->cm_timestamp = time_second;
2353
2354 /*
2355 * Pass the FIB to the controller, wait for it to complete.
2356 */
2357 if ((error = aac_wait_command(cm, 30)) != 0) { /* XXX user timeout? */
2358 device_printf(sc->aac_dev,
2359 "aac_wait_command return %d\n", error);
2360 goto out;
2361 }
2362
2363 /*
2364 * Copy the FIB and data back out to the caller.
2365 */
2366 size = cm->cm_fib->Header.Size;
2367 if (size > sizeof(struct aac_fib)) {
2368 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
2369 size, sizeof(struct aac_fib));
2370 size = sizeof(struct aac_fib);
2371 }
2372 error = copyout(cm->cm_fib, ufib, size);
2373
2374out:
2375 if (cm != NULL) {
2376 aac_release_command(cm);
2377 }
2378
2379 AAC_LOCK_RELEASE(&sc->aac_io_lock);
2380 return(error);
2381}
2382
2383/*
2384 * Handle an AIF sent to us by the controller; queue it for later reference.
2385 * If the queue fills up, then drop the older entries.
2386 */
2387static void
2388aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
2389{
2390 struct aac_aif_command *aif;
2391 struct aac_container *co, *co_next;
2392 struct aac_mntinfo *mi;
2393 struct aac_mntinforesp *mir = NULL;
2394 u_int16_t rsize;
2395 int next, found;
2396 int added = 0, i = 0;
2397
2398 debug_called(2);
2399
2400 aif = (struct aac_aif_command*)&fib->data[0];
2401 aac_print_aif(sc, aif);
2402
2403 /* Is it an event that we should care about? */
2404 switch (aif->command) {
2405 case AifCmdEventNotify:
2406 switch (aif->data.EN.type) {
2407 case AifEnAddContainer:
2408 case AifEnDeleteContainer:
2409 /*
2410 * A container was added or deleted, but the message
2411 * doesn't tell us anything else! Re-enumerate the
2412 * containers and sort things out.
2413 */
2414 aac_alloc_sync_fib(sc, &fib, 0);
2415 mi = (struct aac_mntinfo *)&fib->data[0];
2416 do {
2417 /*
2418 * Ask the controller for its containers one at
2419 * a time.
2420 * XXX What if the controller's list changes
2421 * midway through this enumaration?
2422 * XXX This should be done async.
2423 */
2424 bzero(mi, sizeof(struct aac_mntinfo));
2425 mi->Command = VM_NameServe;
2426 mi->MntType = FT_FILESYS;
2427 mi->MntCount = i;
2428 rsize = sizeof(mir);
2429 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
2430 sizeof(struct aac_mntinfo))) {
2431 debug(2, "Error probing container %d\n",
2432 i);
2433 continue;
2434 }
2435 mir = (struct aac_mntinforesp *)&fib->data[0];
2436 /*
2437 * Check the container against our list.
2438 * co->co_found was already set to 0 in a
2439 * previous run.
2440 */
2441 if ((mir->Status == ST_OK) &&
2442 (mir->MntTable[0].VolType != CT_NONE)) {
2443 found = 0;
2444 TAILQ_FOREACH(co,
2445 &sc->aac_container_tqh,
2446 co_link) {
2447 if (co->co_mntobj.ObjectId ==
2448 mir->MntTable[0].ObjectId) {
2449 co->co_found = 1;
2450 found = 1;
2451 break;
2452 }
2453 }
2454 /*
2455 * If the container matched, continue
2456 * in the list.
2457 */
2458 if (found) {
2459 i++;
2460 continue;
2461 }
2462
2463 /*
2464 * This is a new container. Do all the
2465 * appropriate things to set it up.
2466 */
2467 aac_add_container(sc, mir, 1);
2468 added = 1;
2469 }
2470 i++;
2471 } while ((i < mir->MntRespCount) &&
2472 (i < AAC_MAX_CONTAINERS));
2473 aac_release_sync_fib(sc);
2474
2475 /*
2476 * Go through our list of containers and see which ones
2477 * were not marked 'found'. Since the controller didn't
2478 * list them they must have been deleted. Do the
2479 * appropriate steps to destroy the device. Also reset
2480 * the co->co_found field.
2481 */
2482 co = TAILQ_FIRST(&sc->aac_container_tqh);
2483 while (co != NULL) {
2484 if (co->co_found == 0) {
2485 device_delete_child(sc->aac_dev,
2486 co->co_disk);
2487 co_next = TAILQ_NEXT(co, co_link);
2488 AAC_LOCK_ACQUIRE(&sc->
2489 aac_container_lock);
2490 TAILQ_REMOVE(&sc->aac_container_tqh, co,
2491 co_link);
2492 AAC_LOCK_RELEASE(&sc->
2493 aac_container_lock);
2494 FREE(co, M_AACBUF);
2495 co = co_next;
2496 } else {
2497 co->co_found = 0;
2498 co = TAILQ_NEXT(co, co_link);
2499 }
2500 }
2501
2502 /* Attach the newly created containers */
2503 if (added)
2504 bus_generic_attach(sc->aac_dev);
2505
2506 break;
2507
2508 default:
2509 break;
2510 }
2511
2512 default:
2513 break;
2514 }
2515
2516 /* Copy the AIF data to the AIF queue for ioctl retrieval */
2517 AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
2518 next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
2519 if (next != sc->aac_aifq_tail) {
2520 bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
2521 sc->aac_aifq_head = next;
2522
2523 /* On the off chance that someone is sleeping for an aif... */
2524 if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
2525 wakeup(sc->aac_aifq);
2526 /* Wakeup any poll()ers */
2527 selwakeup(&sc->rcv_select);
2528 }
2529 AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
2530
2531 return;
2532}
2533
2534/*
2535 * Return the Revision of the driver to userspace and check to see if the
2536 * userspace app is possibly compatible. This is extremely bogus since
2537 * our driver doesn't follow Adaptec's versioning system. Cheat by just
2538 * returning what the card reported.
2539 */
2540static int
2541aac_rev_check(struct aac_softc *sc, caddr_t udata)
2542{
2543 struct aac_rev_check rev_check;
2544 struct aac_rev_check_resp rev_check_resp;
2545 int error = 0;
2546
2547 debug_called(2);
2548
2549 /*
2550 * Copyin the revision struct from userspace
2551 */
2552 if ((error = copyin(udata, (caddr_t)&rev_check,
2553 sizeof(struct aac_rev_check))) != 0) {
2554 return error;
2555 }
2556
2557 debug(2, "Userland revision= %d\n",
2558 rev_check.callingRevision.buildNumber);
2559
2560 /*
2561 * Doctor up the response struct.
2562 */
2563 rev_check_resp.possiblyCompatible = 1;
2564 rev_check_resp.adapterSWRevision.external.ul =
2565 sc->aac_revision.external.ul;
2566 rev_check_resp.adapterSWRevision.buildNumber =
2567 sc->aac_revision.buildNumber;
2568
2569 return(copyout((caddr_t)&rev_check_resp, udata,
2570 sizeof(struct aac_rev_check_resp)));
2571}
2572
2573/*
2574 * Pass the caller the next AIF in their queue
2575 */
2576static int
2577aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
2578{
2579 struct get_adapter_fib_ioctl agf;
2580 int error;
2581
2582 debug_called(2);
2583
2584 if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
2585
2586 /*
2587 * Check the magic number that we gave the caller.
2588 */
2589 if (agf.AdapterFibContext != (int)sc->aifthread) {
2590 error = EFAULT;
2591 } else {
2592 error = aac_return_aif(sc, agf.AifFib);
2593 if ((error == EAGAIN) && (agf.Wait)) {
2594 sc->aac_state |= AAC_STATE_AIF_SLEEPER;
2595 while (error == EAGAIN) {
2596 error = tsleep(sc->aac_aifq, PRIBIO |
2597 PCATCH, "aacaif", 0);
2598 if (error == 0)
2599 error = aac_return_aif(sc,
2600 agf.AifFib);
2601 }
2602 sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
2603 }
2604 }
2605 }
2606 return(error);
2607}
2608
2609/*
2610 * Hand the next AIF off the top of the queue out to userspace.
2611 */
2612static int
2613aac_return_aif(struct aac_softc *sc, caddr_t uptr)
2614{
2615 int error;
2616
2617 debug_called(2);
2618
2619 AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
2620 if (sc->aac_aifq_tail == sc->aac_aifq_head) {
2621 error = EAGAIN;
2622 } else {
2623 error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr,
2624 sizeof(struct aac_aif_command));
2625 if (error)
2626 device_printf(sc->aac_dev,
2627 "aac_return_aif: copyout returned %d\n", error);
2628 if (!error)
2629 sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) %
2630 AAC_AIFQ_LENGTH;
2631 }
2632 AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
2633 return(error);
2634}
2635
2636/*
2637 * Give the userland some information about the container. The AAC arch
2638 * expects the driver to be a SCSI passthrough type driver, so it expects
2639 * the containers to have b:t:l numbers. Fake it.
2640 */
2641static int
2642aac_query_disk(struct aac_softc *sc, caddr_t uptr)
2643{
2644 struct aac_query_disk query_disk;
2645 struct aac_container *co;
2646 struct aac_disk *disk;
2647 int error, id;
2648
2649 debug_called(2);
2650
2651 disk = NULL;
2652
2653 error = copyin(uptr, (caddr_t)&query_disk,
2654 sizeof(struct aac_query_disk));
2655 if (error)
2656 return (error);
2657
2658 id = query_disk.ContainerNumber;
2659 if (id == -1)
2660 return (EINVAL);
2661
2662 AAC_LOCK_ACQUIRE(&sc->aac_container_lock);
2663 TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
2664 if (co->co_mntobj.ObjectId == id)
2665 break;
2666 }
2667
2668 if (co == NULL) {
2669 query_disk.Valid = 0;
2670 query_disk.Locked = 0;
2671 query_disk.Deleted = 1; /* XXX is this right? */
2672 } else {
2673 disk = device_get_softc(co->co_disk);
2674 query_disk.Valid = 1;
2675 query_disk.Locked =
2676 (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
2677 query_disk.Deleted = 0;
2678 query_disk.Bus = device_get_unit(sc->aac_dev);
2679 query_disk.Target = disk->unit;
2680 query_disk.Lun = 0;
2681 query_disk.UnMapped = 0;
2682 sprintf(&query_disk.diskDeviceName[0], "%s%d",
2683 disk->ad_disk.d_name, disk->ad_disk.d_unit);
2684 }
2685 AAC_LOCK_RELEASE(&sc->aac_container_lock);
2686
2687 error = copyout((caddr_t)&query_disk, uptr,
2688 sizeof(struct aac_query_disk));
2689
2690 return (error);
2691}
2692
2693static void
2694aac_get_bus_info(struct aac_softc *sc)
2695{
2696 struct aac_fib *fib;
2697 struct aac_ctcfg *c_cmd;
2698 struct aac_ctcfg_resp *c_resp;
2699 struct aac_vmioctl *vmi;
2700 struct aac_vmi_businf_resp *vmi_resp;
2701 struct aac_getbusinf businfo;
2702 struct aac_sim *caminf;
2703 device_t child;
2704 int i, found, error;
2705
2706 aac_alloc_sync_fib(sc, &fib, 0);
2707 c_cmd = (struct aac_ctcfg *)&fib->data[0];
2708 bzero(c_cmd, sizeof(struct aac_ctcfg));
2709
2710 c_cmd->Command = VM_ContainerConfig;
2711 c_cmd->cmd = CT_GET_SCSI_METHOD;
2712 c_cmd->param = 0;
2713
2714 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
2715 sizeof(struct aac_ctcfg));
2716 if (error) {
2717 device_printf(sc->aac_dev, "Error %d sending "
2718 "VM_ContainerConfig command\n", error);
2719 aac_release_sync_fib(sc);
2720 return;
2721 }
2722
2723 c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
2724 if (c_resp->Status != ST_OK) {
2725 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
2726 c_resp->Status);
2727 aac_release_sync_fib(sc);
2728 return;
2729 }
2730
2731 sc->scsi_method_id = c_resp->param;
2732
2733 vmi = (struct aac_vmioctl *)&fib->data[0];
2734 bzero(vmi, sizeof(struct aac_vmioctl));
2735
2736 vmi->Command = VM_Ioctl;
2737 vmi->ObjType = FT_DRIVE;
2738 vmi->MethId = sc->scsi_method_id;
2739 vmi->ObjId = 0;
2740 vmi->IoctlCmd = GetBusInfo;
2741
2742 error = aac_sync_fib(sc, ContainerCommand, 0, fib,
2743 sizeof(struct aac_vmioctl));
2744 if (error) {
2745 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
2746 error);
2747 aac_release_sync_fib(sc);
2748 return;
2749 }
2750
2751 vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
2752 if (vmi_resp->Status != ST_OK) {
2753 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
2754 vmi_resp->Status);
2755 aac_release_sync_fib(sc);
2756 return;
2757 }
2758
2759 bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
2760 aac_release_sync_fib(sc);
2761
2762 found = 0;
2763 for (i = 0; i < businfo.BusCount; i++) {
2764 if (businfo.BusValid[i] != AAC_BUS_VALID)
2765 continue;
2766
2767 caminf = (struct aac_sim *)malloc( sizeof(struct aac_sim),
2768 M_AACBUF, M_NOWAIT | M_ZERO);
2769 if (caminf == NULL)
2770 continue;
2771
2772 child = device_add_child(sc->aac_dev, "aacp", -1);
2773 if (child == NULL) {
2774 device_printf(sc->aac_dev, "device_add_child failed\n");
2775 continue;
2776 }
2777
2778 caminf->TargetsPerBus = businfo.TargetsPerBus;
2779 caminf->BusNumber = i;
2780 caminf->InitiatorBusId = businfo.InitiatorBusId[i];
2781 caminf->aac_sc = sc;
2782 caminf->sim_dev = child;
2783
2784 device_set_ivars(child, caminf);
2785 device_set_desc(child, "SCSI Passthrough Bus");
2786 TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
2787
2788 found = 1;
2789 }
2790
2791 if (found)
2792 bus_generic_attach(sc->aac_dev);
2793
2794 return;
2795}