]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - sys/dev/aacraid/aacraid.c
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / sys / dev / aacraid / aacraid.c
1 /*-
2  * Copyright (c) 2000 Michael Smith
3  * Copyright (c) 2001 Scott Long
4  * Copyright (c) 2000 BSDi
5  * Copyright (c) 2001-2010 Adaptec, Inc.
6  * Copyright (c) 2010-2012 PMC-Sierra, Inc.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */
30
31 #include <sys/cdefs.h>
32 __FBSDID("$FreeBSD$");
33
34 /*
35  * Driver for the Adaptec by PMC Series 6,7,8,... families of RAID controllers
36  */
37 #define AAC_DRIVERNAME                  "aacraid"
38
39 #include "opt_aacraid.h"
40
41 /* #include <stddef.h> */
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
46 #include <sys/kthread.h>
47 #include <sys/sysctl.h>
48 #include <sys/poll.h>
49 #include <sys/ioccom.h>
50
51 #include <sys/bus.h>
52 #include <sys/conf.h>
53 #include <sys/signalvar.h>
54 #include <sys/time.h>
55 #include <sys/eventhandler.h>
56 #include <sys/rman.h>
57
58 #include <machine/bus.h>
59 #include <sys/bus_dma.h>
60 #include <machine/resource.h>
61
62 #include <dev/pci/pcireg.h>
63 #include <dev/pci/pcivar.h>
64
65 #include <dev/aacraid/aacraid_reg.h>
66 #include <sys/aac_ioctl.h>
67 #include <dev/aacraid/aacraid_debug.h>
68 #include <dev/aacraid/aacraid_var.h>
69
70 #ifndef FILTER_HANDLED
71 #define FILTER_HANDLED  0x02
72 #endif
73
74 static void     aac_add_container(struct aac_softc *sc,
75                                   struct aac_mntinforesp *mir, int f, 
76                                   u_int32_t uid);
77 static void     aac_get_bus_info(struct aac_softc *sc);
78 static void     aac_container_bus(struct aac_softc *sc);
79 static void     aac_daemon(void *arg);
80 static int aac_convert_sgraw2(struct aac_softc *sc, struct aac_raw_io2 *raw,
81                                                           int pages, int nseg, int nseg_new);
82
83 /* Command Processing */
84 static void     aac_timeout(struct aac_softc *sc);
85 static void     aac_command_thread(struct aac_softc *sc);
86 static int      aac_sync_fib(struct aac_softc *sc, u_int32_t command,
87                                      u_int32_t xferstate, struct aac_fib *fib,
88                                      u_int16_t datasize);
89 /* Command Buffer Management */
90 static void     aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
91                                        int nseg, int error);
92 static int      aac_alloc_commands(struct aac_softc *sc);
93 static void     aac_free_commands(struct aac_softc *sc);
94 static void     aac_unmap_command(struct aac_command *cm);
95
96 /* Hardware Interface */
97 static int      aac_alloc(struct aac_softc *sc);
98 static void     aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
99                                int error);
100 static int      aac_check_firmware(struct aac_softc *sc);
101 static int      aac_init(struct aac_softc *sc);
102 static int      aac_setup_intr(struct aac_softc *sc);
103
104 /* PMC SRC interface */
105 static int      aac_src_get_fwstatus(struct aac_softc *sc);
106 static void     aac_src_qnotify(struct aac_softc *sc, int qbit);
107 static int      aac_src_get_istatus(struct aac_softc *sc);
108 static void     aac_src_clear_istatus(struct aac_softc *sc, int mask);
109 static void     aac_src_set_mailbox(struct aac_softc *sc, u_int32_t command,
110                                     u_int32_t arg0, u_int32_t arg1,
111                                     u_int32_t arg2, u_int32_t arg3);
112 static int      aac_src_get_mailbox(struct aac_softc *sc, int mb);
113 static void     aac_src_set_interrupts(struct aac_softc *sc, int enable);
114 static int aac_src_send_command(struct aac_softc *sc, struct aac_command *cm);
115 static int aac_src_get_outb_queue(struct aac_softc *sc);
116 static void aac_src_set_outb_queue(struct aac_softc *sc, int index);
117
118 struct aac_interface aacraid_src_interface = {
119         aac_src_get_fwstatus,
120         aac_src_qnotify,
121         aac_src_get_istatus,
122         aac_src_clear_istatus,
123         aac_src_set_mailbox,
124         aac_src_get_mailbox,
125         aac_src_set_interrupts,
126         aac_src_send_command,
127         aac_src_get_outb_queue,
128         aac_src_set_outb_queue
129 };
130
131 /* PMC SRCv interface */
132 static void     aac_srcv_set_mailbox(struct aac_softc *sc, u_int32_t command,
133                                     u_int32_t arg0, u_int32_t arg1,
134                                     u_int32_t arg2, u_int32_t arg3);
135 static int      aac_srcv_get_mailbox(struct aac_softc *sc, int mb);
136
137 struct aac_interface aacraid_srcv_interface = {
138         aac_src_get_fwstatus,
139         aac_src_qnotify,
140         aac_src_get_istatus,
141         aac_src_clear_istatus,
142         aac_srcv_set_mailbox,
143         aac_srcv_get_mailbox,
144         aac_src_set_interrupts,
145         aac_src_send_command,
146         aac_src_get_outb_queue,
147         aac_src_set_outb_queue
148 };
149
150 /* Debugging and Diagnostics */
151 static struct aac_code_lookup aac_cpu_variant[] = {
152         {"i960JX",              CPUI960_JX},
153         {"i960CX",              CPUI960_CX},
154         {"i960HX",              CPUI960_HX},
155         {"i960RX",              CPUI960_RX},
156         {"i960 80303",          CPUI960_80303},
157         {"StrongARM SA110",     CPUARM_SA110},
158         {"PPC603e",             CPUPPC_603e},
159         {"XScale 80321",        CPU_XSCALE_80321},
160         {"MIPS 4KC",            CPU_MIPS_4KC},
161         {"MIPS 5KC",            CPU_MIPS_5KC},
162         {"Unknown StrongARM",   CPUARM_xxx},
163         {"Unknown PowerPC",     CPUPPC_xxx},
164         {NULL, 0},
165         {"Unknown processor",   0}
166 };
167
168 static struct aac_code_lookup aac_battery_platform[] = {
169         {"required battery present",            PLATFORM_BAT_REQ_PRESENT},
170         {"REQUIRED BATTERY NOT PRESENT",        PLATFORM_BAT_REQ_NOTPRESENT},
171         {"optional battery present",            PLATFORM_BAT_OPT_PRESENT},
172         {"optional battery not installed",      PLATFORM_BAT_OPT_NOTPRESENT},
173         {"no battery support",                  PLATFORM_BAT_NOT_SUPPORTED},
174         {NULL, 0},
175         {"unknown battery platform",            0}
176 };
177 static void     aac_describe_controller(struct aac_softc *sc);
178 static char     *aac_describe_code(struct aac_code_lookup *table,
179                                    u_int32_t code);
180
181 /* Management Interface */
182 static d_open_t         aac_open;
183 static d_ioctl_t        aac_ioctl;
184 static d_poll_t         aac_poll;
185 #if __FreeBSD_version >= 702000
186 static void             aac_cdevpriv_dtor(void *arg);
187 #else
188 static d_close_t        aac_close;
189 #endif
190 static int      aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
191 static int      aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
192 static void     aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib);
193 static void     aac_request_aif(struct aac_softc *sc);
194 static int      aac_rev_check(struct aac_softc *sc, caddr_t udata);
195 static int      aac_open_aif(struct aac_softc *sc, caddr_t arg);
196 static int      aac_close_aif(struct aac_softc *sc, caddr_t arg);
197 static int      aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
198 static int      aac_return_aif(struct aac_softc *sc,
199                                struct aac_fib_context *ctx, caddr_t uptr);
200 static int      aac_query_disk(struct aac_softc *sc, caddr_t uptr);
201 static int      aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
202 static int      aac_supported_features(struct aac_softc *sc, caddr_t uptr);
203 static void     aac_ioctl_event(struct aac_softc *sc,
204                                 struct aac_event *event, void *arg);
205 static int      aac_reset_adapter(struct aac_softc *sc);
206 static int      aac_get_container_info(struct aac_softc *sc, 
207                                        struct aac_fib *fib, int cid,
208                                        struct aac_mntinforesp *mir, 
209                                        u_int32_t *uid);         
210 static u_int32_t
211         aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled);
212
213 static struct cdevsw aacraid_cdevsw = {
214         .d_version =    D_VERSION,
215         .d_flags =      D_NEEDGIANT,
216         .d_open =       aac_open,
217 #if __FreeBSD_version < 702000
218         .d_close =      aac_close,
219 #endif
220         .d_ioctl =      aac_ioctl,
221         .d_poll =       aac_poll,
222         .d_name =       "aacraid",
223 };
224
225 MALLOC_DEFINE(M_AACRAIDBUF, "aacraid_buf", "Buffers for the AACRAID driver");
226
227 /* sysctl node */
228 SYSCTL_NODE(_hw, OID_AUTO, aacraid, CTLFLAG_RD, 0, "AACRAID driver parameters");
229
230 /*
231  * Device Interface
232  */
233
234 /*
235  * Initialize the controller and softc
236  */
237 int
238 aacraid_attach(struct aac_softc *sc)
239 {
240         int error, unit;
241         struct aac_fib *fib;
242         struct aac_mntinforesp mir;
243         int count = 0, i = 0;
244         u_int32_t uid;
245
246         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
247         sc->hint_flags = device_get_flags(sc->aac_dev);
248         /*
249          * Initialize per-controller queues.
250          */
251         aac_initq_free(sc);
252         aac_initq_ready(sc);
253         aac_initq_busy(sc);
254
255         /* mark controller as suspended until we get ourselves organised */
256         sc->aac_state |= AAC_STATE_SUSPEND;
257
258         /*
259          * Check that the firmware on the card is supported.
260          */
261         if ((error = aac_check_firmware(sc)) != 0)
262                 return(error);
263
264         /*
265          * Initialize locks
266          */
267         mtx_init(&sc->aac_io_lock, "AACRAID I/O lock", NULL, MTX_DEF);
268         TAILQ_INIT(&sc->aac_container_tqh);
269         TAILQ_INIT(&sc->aac_ev_cmfree);
270
271 #if __FreeBSD_version >= 800000
272         /* Initialize the clock daemon callout. */
273         callout_init_mtx(&sc->aac_daemontime, &sc->aac_io_lock, 0);
274 #endif
275         /*
276          * Initialize the adapter.
277          */
278         if ((error = aac_alloc(sc)) != 0)
279                 return(error);
280         if (!(sc->flags & AAC_FLAGS_SYNC_MODE)) {
281                 if ((error = aac_init(sc)) != 0)
282                         return(error);
283         }
284
285         /*
286          * Allocate and connect our interrupt.
287          */
288         if ((error = aac_setup_intr(sc)) != 0)
289                 return(error);
290
291         /*
292          * Print a little information about the controller.
293          */
294         aac_describe_controller(sc);
295
296         /*
297          * Make the control device.
298          */
299         unit = device_get_unit(sc->aac_dev);
300         sc->aac_dev_t = make_dev(&aacraid_cdevsw, unit, UID_ROOT, GID_OPERATOR,
301                                  0640, "aacraid%d", unit);
302         sc->aac_dev_t->si_drv1 = sc;
303
304         /* Create the AIF thread */
305         if (aac_kthread_create((void(*)(void *))aac_command_thread, sc,
306                    &sc->aifthread, 0, 0, "aacraid%daif", unit))
307                 panic("Could not create AIF thread");
308
309         /* Register the shutdown method to only be called post-dump */
310         if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aacraid_shutdown,
311             sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
312                 device_printf(sc->aac_dev,
313                               "shutdown event registration failed\n");
314
315         /* Find containers */
316         mtx_lock(&sc->aac_io_lock);
317         aac_alloc_sync_fib(sc, &fib);
318         /* loop over possible containers */
319         do {
320                 if ((aac_get_container_info(sc, fib, i, &mir, &uid)) != 0)
321                         continue;
322                 if (i == 0) 
323                         count = mir.MntRespCount;
324                 aac_add_container(sc, &mir, 0, uid);
325                 i++;
326         } while ((i < count) && (i < AAC_MAX_CONTAINERS));
327         aac_release_sync_fib(sc);
328         mtx_unlock(&sc->aac_io_lock);
329
330         /* Register with CAM for the containers */
331         TAILQ_INIT(&sc->aac_sim_tqh);
332         aac_container_bus(sc);
333         /* Register with CAM for the non-DASD devices */
334         if ((sc->flags & AAC_FLAGS_ENABLE_CAM) != 0) 
335                 aac_get_bus_info(sc);
336
337         /* poke the bus to actually attach the child devices */
338         bus_generic_attach(sc->aac_dev);
339
340         /* mark the controller up */
341         sc->aac_state &= ~AAC_STATE_SUSPEND;
342
343         /* enable interrupts now */
344         AAC_UNMASK_INTERRUPTS(sc);
345
346 #if __FreeBSD_version >= 800000
347         mtx_lock(&sc->aac_io_lock);
348         callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc);
349         mtx_unlock(&sc->aac_io_lock);
350 #else
351         {
352                 struct timeval tv;
353                 tv.tv_sec = 60;
354                 tv.tv_usec = 0;
355                 sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv));
356         }
357 #endif
358
359         return(0);
360 }
361
362 static void
363 aac_daemon(void *arg)
364 {
365         struct aac_softc *sc;
366         struct timeval tv;
367         struct aac_command *cm;
368         struct aac_fib *fib;
369
370         sc = arg;
371         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
372
373 #if __FreeBSD_version >= 800000
374         mtx_assert(&sc->aac_io_lock, MA_OWNED);
375         if (callout_pending(&sc->aac_daemontime) ||
376             callout_active(&sc->aac_daemontime) == 0)
377                 return;
378 #else
379         mtx_lock(&sc->aac_io_lock);
380 #endif
381         getmicrotime(&tv);
382
383         if (!aacraid_alloc_command(sc, &cm)) {
384                 fib = cm->cm_fib;
385                 cm->cm_timestamp = time_uptime;
386                 cm->cm_datalen = 0;
387                 cm->cm_flags |= AAC_CMD_WAIT;
388
389                 fib->Header.Size = 
390                         sizeof(struct aac_fib_header) + sizeof(u_int32_t);
391                 fib->Header.XferState =
392                         AAC_FIBSTATE_HOSTOWNED   |
393                         AAC_FIBSTATE_INITIALISED |
394                         AAC_FIBSTATE_EMPTY       |
395                         AAC_FIBSTATE_FROMHOST    |
396                         AAC_FIBSTATE_REXPECTED   |
397                         AAC_FIBSTATE_NORM        |
398                         AAC_FIBSTATE_ASYNC       |
399                         AAC_FIBSTATE_FAST_RESPONSE;
400                 fib->Header.Command = SendHostTime;
401                 *(uint32_t *)fib->data = tv.tv_sec;
402
403                 aacraid_map_command_sg(cm, NULL, 0, 0);
404                 aacraid_release_command(cm);
405         }
406
407 #if __FreeBSD_version >= 800000
408         callout_schedule(&sc->aac_daemontime, 30 * 60 * hz);
409 #else
410         mtx_unlock(&sc->aac_io_lock);
411         tv.tv_sec = 30 * 60;
412         tv.tv_usec = 0;
413         sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv));
414 #endif
415 }
416
417 void
418 aacraid_add_event(struct aac_softc *sc, struct aac_event *event)
419 {
420
421         switch (event->ev_type & AAC_EVENT_MASK) {
422         case AAC_EVENT_CMFREE:
423                 TAILQ_INSERT_TAIL(&sc->aac_ev_cmfree, event, ev_links);
424                 break;
425         default:
426                 device_printf(sc->aac_dev, "aac_add event: unknown event %d\n",
427                     event->ev_type);
428                 break;
429         }
430
431         return;
432 }
433
434 /*
435  * Request information of container #cid
436  */
437 static int
438 aac_get_container_info(struct aac_softc *sc, struct aac_fib *sync_fib, int cid,
439                        struct aac_mntinforesp *mir, u_int32_t *uid)
440 {
441         struct aac_command *cm;
442         struct aac_fib *fib;
443         struct aac_mntinfo *mi;
444         struct aac_cnt_config *ccfg;
445
446         if (sync_fib == NULL) {
447                 if (aacraid_alloc_command(sc, &cm)) {
448                         device_printf(sc->aac_dev,
449                                 "Warning, no free command available\n");
450                         return (-1);
451                 }
452                 fib = cm->cm_fib;
453         } else {
454                 fib = sync_fib;
455         }
456
457         mi = (struct aac_mntinfo *)&fib->data[0];
458         /* 4KB support?, 64-bit LBA? */
459         if (sc->aac_support_opt2 & AAC_SUPPORTED_VARIABLE_BLOCK_SIZE)
460                 mi->Command = VM_NameServeAllBlk;
461         else if (sc->flags & AAC_FLAGS_LBA_64BIT) 
462                 mi->Command = VM_NameServe64;
463         else
464                 mi->Command = VM_NameServe;
465         mi->MntType = FT_FILESYS;
466         mi->MntCount = cid;
467
468         if (sync_fib) {
469                 if (aac_sync_fib(sc, ContainerCommand, 0, fib,
470                          sizeof(struct aac_mntinfo))) {
471                         device_printf(sc->aac_dev, "Error probing container %d\n", cid);
472                         return (-1);
473                 }
474         } else {
475                 cm->cm_timestamp = time_uptime;
476                 cm->cm_datalen = 0;
477
478                 fib->Header.Size = 
479                         sizeof(struct aac_fib_header) + sizeof(struct aac_mntinfo);
480                 fib->Header.XferState =
481                         AAC_FIBSTATE_HOSTOWNED   |
482                         AAC_FIBSTATE_INITIALISED |
483                         AAC_FIBSTATE_EMPTY       |
484                         AAC_FIBSTATE_FROMHOST    |
485                         AAC_FIBSTATE_REXPECTED   |
486                         AAC_FIBSTATE_NORM        |
487                         AAC_FIBSTATE_ASYNC       |
488                         AAC_FIBSTATE_FAST_RESPONSE;
489                 fib->Header.Command = ContainerCommand;
490                 if (aacraid_wait_command(cm) != 0) {
491                         device_printf(sc->aac_dev, "Error probing container %d\n", cid);
492                         aacraid_release_command(cm);
493                         return (-1);
494                 }
495         }
496         bcopy(&fib->data[0], mir, sizeof(struct aac_mntinforesp));
497
498         /* UID */
499         *uid = cid;
500         if (mir->MntTable[0].VolType != CT_NONE && 
501                 !(mir->MntTable[0].ContentState & AAC_FSCS_HIDDEN)) {
502                 if (!(sc->aac_support_opt2 & AAC_SUPPORTED_VARIABLE_BLOCK_SIZE))
503                         mir->MntTable[0].ObjExtension.BlockSize = 0x200;
504
505                 ccfg = (struct aac_cnt_config *)&fib->data[0];
506                 bzero(ccfg, sizeof (*ccfg) - CT_PACKET_SIZE);
507                 ccfg->Command = VM_ContainerConfig;
508                 ccfg->CTCommand.command = CT_CID_TO_32BITS_UID;
509                 ccfg->CTCommand.param[0] = cid;
510
511                 if (sync_fib) {
512                         if (aac_sync_fib(sc, ContainerCommand, 0, fib,
513                                 sizeof(struct aac_cnt_config) == 0) &&
514                                 ccfg->CTCommand.param[0] == ST_OK &&
515                                 mir->MntTable[0].VolType != CT_PASSTHRU)
516                                 *uid = ccfg->CTCommand.param[1];
517                 } else {
518                         fib->Header.Size = 
519                                 sizeof(struct aac_fib_header) + sizeof(struct aac_cnt_config);
520                         fib->Header.XferState =
521                                 AAC_FIBSTATE_HOSTOWNED   |
522                                 AAC_FIBSTATE_INITIALISED |
523                                 AAC_FIBSTATE_EMPTY       |
524                                 AAC_FIBSTATE_FROMHOST    |
525                                 AAC_FIBSTATE_REXPECTED   |
526                                 AAC_FIBSTATE_NORM        |
527                                 AAC_FIBSTATE_ASYNC       |
528                                 AAC_FIBSTATE_FAST_RESPONSE;
529                         fib->Header.Command = ContainerCommand;
530                         if (aacraid_wait_command(cm) == 0 &&
531                                 ccfg->CTCommand.param[0] == ST_OK &&
532                                 mir->MntTable[0].VolType != CT_PASSTHRU)
533                                 *uid = ccfg->CTCommand.param[1];
534                         aacraid_release_command(cm);
535                 }
536         }
537
538         return (0);
539 }
540
541 /*
542  * Create a device to represent a new container
543  */
544 static void
545 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f, 
546                   u_int32_t uid)
547 {
548         struct aac_container *co;
549
550         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); 
551
552         /*
553          * Check container volume type for validity.  Note that many of
554          * the possible types may never show up.
555          */
556         if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
557                 co = (struct aac_container *)malloc(sizeof *co, M_AACRAIDBUF,
558                        M_NOWAIT | M_ZERO);
559                 if (co == NULL) {
560                         panic("Out of memory?!");
561                 }
562
563                 co->co_found = f;
564                 bcopy(&mir->MntTable[0], &co->co_mntobj,
565                       sizeof(struct aac_mntobj));
566                 co->co_uid = uid;
567                 TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
568         }
569 }
570
571 /*
572  * Allocate resources associated with (sc)
573  */
574 static int
575 aac_alloc(struct aac_softc *sc)
576 {
577         bus_size_t maxsize;
578
579         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
580
581         /*
582          * Create DMA tag for mapping buffers into controller-addressable space.
583          */
584         if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
585                                1, 0,                    /* algnmnt, boundary */
586                                (sc->flags & AAC_FLAGS_SG_64BIT) ?
587                                BUS_SPACE_MAXADDR :
588                                BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
589                                BUS_SPACE_MAXADDR,       /* highaddr */
590                                NULL, NULL,              /* filter, filterarg */
591                                MAXBSIZE,                /* maxsize */
592                                sc->aac_sg_tablesize,    /* nsegments */
593                                MAXBSIZE,                /* maxsegsize */
594                                BUS_DMA_ALLOCNOW,        /* flags */
595                                busdma_lock_mutex,       /* lockfunc */
596                                &sc->aac_io_lock,        /* lockfuncarg */
597                                &sc->aac_buffer_dmat)) {
598                 device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
599                 return (ENOMEM);
600         }
601
602         /*
603          * Create DMA tag for mapping FIBs into controller-addressable space..
604          */
605         if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
606                 maxsize = sc->aac_max_fibs_alloc * (sc->aac_max_fib_size +
607                         sizeof(struct aac_fib_xporthdr) + 31);
608         else
609                 maxsize = sc->aac_max_fibs_alloc * (sc->aac_max_fib_size + 31);
610         if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
611                                1, 0,                    /* algnmnt, boundary */
612                                (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
613                                BUS_SPACE_MAXADDR_32BIT :
614                                0x7fffffff,              /* lowaddr */
615                                BUS_SPACE_MAXADDR,       /* highaddr */
616                                NULL, NULL,              /* filter, filterarg */
617                                maxsize,                 /* maxsize */
618                                1,                       /* nsegments */
619                                maxsize,                 /* maxsize */
620                                0,                       /* flags */
621                                NULL, NULL,              /* No locking needed */
622                                &sc->aac_fib_dmat)) {
623                 device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
624                 return (ENOMEM);
625         }
626
627         /*
628          * Create DMA tag for the common structure and allocate it.
629          */
630         maxsize = sizeof(struct aac_common);
631         maxsize += sc->aac_max_fibs * sizeof(u_int32_t);
632         if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
633                                1, 0,                    /* algnmnt, boundary */
634                                (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
635                                BUS_SPACE_MAXADDR_32BIT :
636                                0x7fffffff,              /* lowaddr */
637                                BUS_SPACE_MAXADDR,       /* highaddr */
638                                NULL, NULL,              /* filter, filterarg */
639                                maxsize,                 /* maxsize */
640                                1,                       /* nsegments */
641                                maxsize,                 /* maxsegsize */
642                                0,                       /* flags */
643                                NULL, NULL,              /* No locking needed */
644                                &sc->aac_common_dmat)) {
645                 device_printf(sc->aac_dev,
646                               "can't allocate common structure DMA tag\n");
647                 return (ENOMEM);
648         }
649         if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
650                              BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
651                 device_printf(sc->aac_dev, "can't allocate common structure\n");
652                 return (ENOMEM);
653         }
654
655         (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
656                         sc->aac_common, maxsize,
657                         aac_common_map, sc, 0);
658         bzero(sc->aac_common, maxsize);
659
660         /* Allocate some FIBs and associated command structs */
661         TAILQ_INIT(&sc->aac_fibmap_tqh);
662         sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
663                                   M_AACRAIDBUF, M_WAITOK|M_ZERO);
664         mtx_lock(&sc->aac_io_lock);
665         while (sc->total_fibs < sc->aac_max_fibs) {
666                 if (aac_alloc_commands(sc) != 0)
667                         break;
668         }
669         mtx_unlock(&sc->aac_io_lock);
670         if (sc->total_fibs == 0)
671                 return (ENOMEM);
672
673         return (0);
674 }
675
676 /*
677  * Free all of the resources associated with (sc)
678  *
679  * Should not be called if the controller is active.
680  */
681 void
682 aacraid_free(struct aac_softc *sc)
683 {
684         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
685
686         /* remove the control device */
687         if (sc->aac_dev_t != NULL)
688                 destroy_dev(sc->aac_dev_t);
689
690         /* throw away any FIB buffers, discard the FIB DMA tag */
691         aac_free_commands(sc);
692         if (sc->aac_fib_dmat)
693                 bus_dma_tag_destroy(sc->aac_fib_dmat);
694
695         free(sc->aac_commands, M_AACRAIDBUF);
696
697         /* destroy the common area */
698         if (sc->aac_common) {
699                 bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
700                 bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
701                                 sc->aac_common_dmamap);
702         }
703         if (sc->aac_common_dmat)
704                 bus_dma_tag_destroy(sc->aac_common_dmat);
705
706         /* disconnect the interrupt handler */
707         if (sc->aac_intr)
708                 bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
709         if (sc->aac_irq != NULL)
710                 bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
711                                      sc->aac_irq);
712
713         /* destroy data-transfer DMA tag */
714         if (sc->aac_buffer_dmat)
715                 bus_dma_tag_destroy(sc->aac_buffer_dmat);
716
717         /* destroy the parent DMA tag */
718         if (sc->aac_parent_dmat)
719                 bus_dma_tag_destroy(sc->aac_parent_dmat);
720
721         /* release the register window mapping */
722         if (sc->aac_regs_res0 != NULL)
723                 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
724                                      sc->aac_regs_rid0, sc->aac_regs_res0);
725         if (sc->aac_regs_res1 != NULL)
726                 bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
727                                      sc->aac_regs_rid1, sc->aac_regs_res1);
728 }
729
730 /*
731  * Disconnect from the controller completely, in preparation for unload.
732  */
733 int
734 aacraid_detach(device_t dev)
735 {
736         struct aac_softc *sc;
737         struct aac_container *co;
738         struct aac_sim  *sim;
739         int error;
740
741         sc = device_get_softc(dev);
742         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
743
744 #if __FreeBSD_version >= 800000
745         callout_drain(&sc->aac_daemontime);
746 #else
747         untimeout(aac_daemon, (void *)sc, sc->timeout_id);
748 #endif
749         /* Remove the child containers */
750         while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
751                 TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
752                 free(co, M_AACRAIDBUF);
753         }
754
755         /* Remove the CAM SIMs */
756         while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
757                 TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
758                 error = device_delete_child(dev, sim->sim_dev);
759                 if (error)
760                         return (error);
761                 free(sim, M_AACRAIDBUF);
762         }
763
764         if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
765                 sc->aifflags |= AAC_AIFFLAGS_EXIT;
766                 wakeup(sc->aifthread);
767                 tsleep(sc->aac_dev, PUSER | PCATCH, "aac_dch", 30 * hz);
768         }
769
770         if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
771                 panic("Cannot shutdown AIF thread");
772
773         if ((error = aacraid_shutdown(dev)))
774                 return(error);
775
776         EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
777
778         aacraid_free(sc);
779
780         mtx_destroy(&sc->aac_io_lock);
781
782         return(0);
783 }
784
785 /*
786  * Bring the controller down to a dormant state and detach all child devices.
787  *
788  * This function is called before detach or system shutdown.
789  *
790  * Note that we can assume that the bioq on the controller is empty, as we won't
791  * allow shutdown if any device is open.
792  */
793 int
794 aacraid_shutdown(device_t dev)
795 {
796         struct aac_softc *sc;
797         struct aac_fib *fib;
798         struct aac_close_command *cc;
799
800         sc = device_get_softc(dev);
801         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
802
803         sc->aac_state |= AAC_STATE_SUSPEND;
804
805         /*
806          * Send a Container shutdown followed by a HostShutdown FIB to the
807          * controller to convince it that we don't want to talk to it anymore.
808          * We've been closed and all I/O completed already
809          */
810         device_printf(sc->aac_dev, "shutting down controller...");
811
812         mtx_lock(&sc->aac_io_lock);
813         aac_alloc_sync_fib(sc, &fib);
814         cc = (struct aac_close_command *)&fib->data[0];
815
816         bzero(cc, sizeof(struct aac_close_command));
817         cc->Command = VM_CloseAll;
818         cc->ContainerId = 0xffffffff;
819         if (aac_sync_fib(sc, ContainerCommand, 0, fib,
820             sizeof(struct aac_close_command)))
821                 printf("FAILED.\n");
822         else
823                 printf("done\n");
824
825         AAC_MASK_INTERRUPTS(sc);
826         aac_release_sync_fib(sc);
827         mtx_unlock(&sc->aac_io_lock);
828
829         return(0);
830 }
831
832 /*
833  * Bring the controller to a quiescent state, ready for system suspend.
834  */
835 int
836 aacraid_suspend(device_t dev)
837 {
838         struct aac_softc *sc;
839
840         sc = device_get_softc(dev);
841
842         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
843         sc->aac_state |= AAC_STATE_SUSPEND;
844
845         AAC_MASK_INTERRUPTS(sc);
846         return(0);
847 }
848
849 /*
850  * Bring the controller back to a state ready for operation.
851  */
852 int
853 aacraid_resume(device_t dev)
854 {
855         struct aac_softc *sc;
856
857         sc = device_get_softc(dev);
858
859         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
860         sc->aac_state &= ~AAC_STATE_SUSPEND;
861         AAC_UNMASK_INTERRUPTS(sc);
862         return(0);
863 }
864
865 /*
866  * Interrupt handler for NEW_COMM_TYPE1, NEW_COMM_TYPE2, NEW_COMM_TYPE34 interface.
867  */
868 void
869 aacraid_new_intr_type1(void *arg)
870 {
871         struct aac_softc *sc;
872         struct aac_command *cm;
873         struct aac_fib *fib;
874         u_int32_t bellbits, bellbits_shifted, index, handle;
875         int isFastResponse, isAif, noMoreAif;
876
877         sc = (struct aac_softc *)arg;
878
879         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
880         mtx_lock(&sc->aac_io_lock);
881         bellbits = AAC_MEM0_GETREG4(sc, AAC_SRC_ODBR_R);
882         if (bellbits & AAC_DB_RESPONSE_SENT_NS) {
883                 bellbits = AAC_DB_RESPONSE_SENT_NS;
884                 AAC_MEM0_SETREG4(sc, AAC_SRC_ODBR_C, bellbits);
885                 AAC_MEM0_GETREG4(sc, AAC_SRC_ODBR_R);   /* ODR readback,Prep #238630 */
886                 /* handle async. status */
887                 index = sc->aac_host_rrq_idx;
888                 for (;;) {
889                         isFastResponse = isAif = noMoreAif = 0;
890                         /* remove toggle bit (31) */
891                         handle = (sc->aac_common->ac_host_rrq[index] & 0x7fffffff);
892                         /* check fast response bit (30) */
893                         if (handle & 0x40000000) 
894                                 isFastResponse = 1;
895                         /* check AIF bit (23) */
896                         else if (handle & 0x00800000) 
897                                 isAif = TRUE;
898                         handle &= 0x0000ffff;
899                         if (handle == 0) 
900                                 break;
901
902                         cm = sc->aac_commands + (handle - 1);
903                         fib = cm->cm_fib;
904                         if (isAif) {
905                                 noMoreAif = (fib->Header.XferState & AAC_FIBSTATE_NOMOREAIF) ? 1:0;
906                                 if (!noMoreAif)
907                                         aac_handle_aif(sc, fib);
908                                 aac_remove_busy(cm);
909                                 aacraid_release_command(cm);
910                         } else {
911                                 if (isFastResponse) {
912                                         fib->Header.XferState |= AAC_FIBSTATE_DONEADAP;
913                                         *((u_int32_t *)(fib->data)) = ST_OK;
914                                         cm->cm_flags |= AAC_CMD_FASTRESP;
915                                 }
916                                 aac_remove_busy(cm);
917                                 aac_unmap_command(cm);
918                                 cm->cm_flags |= AAC_CMD_COMPLETED;
919
920                                 /* is there a completion handler? */
921                                 if (cm->cm_complete != NULL) {
922                                         cm->cm_complete(cm);
923                                 } else {
924                                         /* assume that someone is sleeping on this command */
925                                         wakeup(cm);
926                                 }
927                                 sc->flags &= ~AAC_QUEUE_FRZN;
928                         }
929
930                         sc->aac_common->ac_host_rrq[index++] = 0;
931                         if (index == sc->aac_max_fibs) 
932                                 index = 0;
933                         sc->aac_host_rrq_idx = index;
934
935                         if ((isAif && !noMoreAif) || sc->aif_pending) 
936                                 aac_request_aif(sc);
937                 }
938         } else {
939                 bellbits_shifted = (bellbits >> AAC_SRC_ODR_SHIFT);
940                 AAC_MEM0_SETREG4(sc, AAC_SRC_ODBR_C, bellbits);
941                 if (bellbits_shifted & AAC_DB_AIF_PENDING) {
942                         /* handle AIF */
943                         aac_request_aif(sc);
944                 } else if (bellbits_shifted & AAC_DB_SYNC_COMMAND) {
945                         if (sc->aac_sync_cm) {  
946                                 cm = sc->aac_sync_cm;
947                                 cm->cm_flags |= AAC_CMD_COMPLETED;
948                                 /* is there a completion handler? */
949                                 if (cm->cm_complete != NULL) {
950                                         cm->cm_complete(cm);
951                                 } else {
952                                         /* assume that someone is sleeping on this command */
953                                         wakeup(cm);
954                                 }
955                                 sc->flags &= ~AAC_QUEUE_FRZN;
956                                 sc->aac_sync_cm = NULL;
957                         }
958                 }
959         }
960
961         /* see if we can start some more I/O */
962         if ((sc->flags & AAC_QUEUE_FRZN) == 0)
963                 aacraid_startio(sc);
964         mtx_unlock(&sc->aac_io_lock);
965 }
966
967 /*
968  * Handle notification of one or more FIBs coming from the controller.
969  */
970 static void
971 aac_command_thread(struct aac_softc *sc)
972 {
973         int retval;
974
975         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
976
977         mtx_lock(&sc->aac_io_lock);
978         sc->aifflags = AAC_AIFFLAGS_RUNNING;
979
980         while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
981
982                 retval = 0;
983                 if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
984                         retval = msleep(sc->aifthread, &sc->aac_io_lock, PRIBIO,
985                                         "aacraid_aifthd", AAC_PERIODIC_INTERVAL * hz);
986
987                 /*
988                  * First see if any FIBs need to be allocated.  This needs
989                  * to be called without the driver lock because contigmalloc
990                  * will grab Giant, and would result in an LOR.
991                  */
992                 if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
993                         aac_alloc_commands(sc);
994                         sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
995                         aacraid_startio(sc);
996                 }
997
998                 /*
999                  * While we're here, check to see if any commands are stuck.
1000                  * This is pretty low-priority, so it's ok if it doesn't
1001                  * always fire.
1002                  */
1003                 if (retval == EWOULDBLOCK)
1004                         aac_timeout(sc);
1005
1006                 /* Check the hardware printf message buffer */
1007                 if (sc->aac_common->ac_printf[0] != 0)
1008                         aac_print_printf(sc);
1009         }
1010         sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
1011         mtx_unlock(&sc->aac_io_lock);
1012         wakeup(sc->aac_dev);
1013
1014         aac_kthread_exit(0);
1015 }
1016
1017 /*
1018  * Submit a command to the controller, return when it completes.
1019  * XXX This is very dangerous!  If the card has gone out to lunch, we could
1020  *     be stuck here forever.  At the same time, signals are not caught
1021  *     because there is a risk that a signal could wakeup the sleep before
1022  *     the card has a chance to complete the command.  Since there is no way
1023  *     to cancel a command that is in progress, we can't protect against the
1024  *     card completing a command late and spamming the command and data
1025  *     memory.  So, we are held hostage until the command completes.
1026  */
1027 int
1028 aacraid_wait_command(struct aac_command *cm)
1029 {
1030         struct aac_softc *sc;
1031         int error;
1032
1033         sc = cm->cm_sc;
1034         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1035         mtx_assert(&sc->aac_io_lock, MA_OWNED);
1036
1037         /* Put the command on the ready queue and get things going */
1038         aac_enqueue_ready(cm);
1039         aacraid_startio(sc);
1040         error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacraid_wait", 0);
1041         return(error);
1042 }
1043
1044 /*
1045  *Command Buffer Management
1046  */
1047
1048 /*
1049  * Allocate a command.
1050  */
1051 int
1052 aacraid_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1053 {
1054         struct aac_command *cm;
1055
1056         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1057
1058         if ((cm = aac_dequeue_free(sc)) == NULL) {
1059                 if (sc->total_fibs < sc->aac_max_fibs) {
1060                         sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1061                         wakeup(sc->aifthread);
1062                 }
1063                 return (EBUSY);
1064         }
1065
1066         *cmp = cm;
1067         return(0);
1068 }
1069
1070 /*
1071  * Release a command back to the freelist.
1072  */
1073 void
1074 aacraid_release_command(struct aac_command *cm)
1075 {
1076         struct aac_event *event;
1077         struct aac_softc *sc;
1078
1079         sc = cm->cm_sc;
1080         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1081         mtx_assert(&sc->aac_io_lock, MA_OWNED);
1082
1083         /* (re)initialize the command/FIB */
1084         cm->cm_sgtable = NULL;
1085         cm->cm_flags = 0;
1086         cm->cm_complete = NULL;
1087         cm->cm_ccb = NULL;
1088         cm->cm_passthr_dmat = 0;
1089         cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1090         cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1091         cm->cm_fib->Header.Unused = 0;
1092         cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
1093
1094         /*
1095          * These are duplicated in aac_start to cover the case where an
1096          * intermediate stage may have destroyed them.  They're left
1097          * initialized here for debugging purposes only.
1098          */
1099         cm->cm_fib->Header.u.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1100         cm->cm_fib->Header.Handle = 0;
1101
1102         aac_enqueue_free(cm);
1103
1104         /*
1105          * Dequeue all events so that there's no risk of events getting
1106          * stranded.
1107          */
1108         while ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
1109                 TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
1110                 event->ev_callback(sc, event, event->ev_arg);
1111         }
1112 }
1113
1114 /*
1115  * Map helper for command/FIB allocation.
1116  */
1117 static void
1118 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1119 {
1120         uint64_t        *fibphys;
1121
1122         fibphys = (uint64_t *)arg;
1123
1124         *fibphys = segs[0].ds_addr;
1125 }
1126
1127 /*
1128  * Allocate and initialize commands/FIBs for this adapter.
1129  */
1130 static int
1131 aac_alloc_commands(struct aac_softc *sc)
1132 {
1133         struct aac_command *cm;
1134         struct aac_fibmap *fm;
1135         uint64_t fibphys;
1136         int i, error;
1137         u_int32_t maxsize;
1138
1139         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1140         mtx_assert(&sc->aac_io_lock, MA_OWNED);
1141
1142         if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
1143                 return (ENOMEM);
1144
1145         fm = malloc(sizeof(struct aac_fibmap), M_AACRAIDBUF, M_NOWAIT|M_ZERO);
1146         if (fm == NULL)
1147                 return (ENOMEM);
1148
1149         mtx_unlock(&sc->aac_io_lock);
1150         /* allocate the FIBs in DMAable memory and load them */
1151         if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1152                              BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1153                 device_printf(sc->aac_dev,
1154                               "Not enough contiguous memory available.\n");
1155                 free(fm, M_AACRAIDBUF);
1156                 mtx_lock(&sc->aac_io_lock);
1157                 return (ENOMEM);
1158         }
1159
1160         maxsize = sc->aac_max_fib_size + 31;
1161         if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
1162                 maxsize += sizeof(struct aac_fib_xporthdr);
1163         /* Ignore errors since this doesn't bounce */
1164         (void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1165                               sc->aac_max_fibs_alloc * maxsize,
1166                               aac_map_command_helper, &fibphys, 0);
1167         mtx_lock(&sc->aac_io_lock);
1168
1169         /* initialize constant fields in the command structure */
1170         bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * maxsize);
1171         for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
1172                 cm = sc->aac_commands + sc->total_fibs;
1173                 fm->aac_commands = cm;
1174                 cm->cm_sc = sc;
1175                 cm->cm_fib = (struct aac_fib *)
1176                         ((u_int8_t *)fm->aac_fibs + i * maxsize);
1177                 cm->cm_fibphys = fibphys + i * maxsize;
1178                 if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) {
1179                         u_int64_t fibphys_aligned;
1180                         fibphys_aligned = 
1181                                 (cm->cm_fibphys + sizeof(struct aac_fib_xporthdr) + 31) & ~31;
1182                         cm->cm_fib = (struct aac_fib *)
1183                                 ((u_int8_t *)cm->cm_fib + (fibphys_aligned - cm->cm_fibphys));
1184                         cm->cm_fibphys = fibphys_aligned;
1185                 } else {
1186                         u_int64_t fibphys_aligned;
1187                         fibphys_aligned = (cm->cm_fibphys + 31) & ~31;
1188                         cm->cm_fib = (struct aac_fib *)
1189                                 ((u_int8_t *)cm->cm_fib + (fibphys_aligned - cm->cm_fibphys));
1190                         cm->cm_fibphys = fibphys_aligned;
1191                 }
1192                 cm->cm_index = sc->total_fibs;
1193
1194                 if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1195                                                &cm->cm_datamap)) != 0)
1196                         break;
1197                 if (sc->aac_max_fibs <= 1 || sc->aac_max_fibs - sc->total_fibs > 1)
1198                         aacraid_release_command(cm);
1199                 sc->total_fibs++;
1200         }
1201
1202         if (i > 0) {
1203                 TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1204                 fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs);
1205                 return (0);
1206         }
1207
1208         bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1209         bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1210         free(fm, M_AACRAIDBUF);
1211         return (ENOMEM);
1212 }
1213
1214 /*
1215  * Free FIBs owned by this adapter.
1216  */
1217 static void
1218 aac_free_commands(struct aac_softc *sc)
1219 {
1220         struct aac_fibmap *fm;
1221         struct aac_command *cm;
1222         int i;
1223
1224         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1225
1226         while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1227
1228                 TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1229                 /*
1230                  * We check against total_fibs to handle partially
1231                  * allocated blocks.
1232                  */
1233                 for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) {
1234                         cm = fm->aac_commands + i;
1235                         bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1236                 }
1237                 bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1238                 bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1239                 free(fm, M_AACRAIDBUF);
1240         }
1241 }
1242
1243 /*
1244  * Command-mapping helper function - populate this command's s/g table.
1245  */
1246 void
1247 aacraid_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1248 {
1249         struct aac_softc *sc;
1250         struct aac_command *cm;
1251         struct aac_fib *fib;
1252         int i;
1253
1254         cm = (struct aac_command *)arg;
1255         sc = cm->cm_sc;
1256         fib = cm->cm_fib;
1257         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "nseg %d", nseg);
1258         mtx_assert(&sc->aac_io_lock, MA_OWNED);
1259
1260         /* copy into the FIB */
1261         if (cm->cm_sgtable != NULL) {
1262                 if (fib->Header.Command == RawIo2) {
1263                         struct aac_raw_io2 *raw;
1264                         struct aac_sge_ieee1212 *sg;
1265                         u_int32_t min_size = PAGE_SIZE, cur_size;
1266                         int conformable = TRUE;
1267
1268                         raw = (struct aac_raw_io2 *)&fib->data[0];
1269                         sg = (struct aac_sge_ieee1212 *)cm->cm_sgtable;
1270                         raw->sgeCnt = nseg;
1271
1272                         for (i = 0; i < nseg; i++) {
1273                                 cur_size = segs[i].ds_len;
1274                                 sg[i].addrHigh = 0;
1275                                 *(bus_addr_t *)&sg[i].addrLow = segs[i].ds_addr;
1276                                 sg[i].length = cur_size;
1277                                 sg[i].flags = 0;
1278                                 if (i == 0) {
1279                                         raw->sgeFirstSize = cur_size;
1280                                 } else if (i == 1) {
1281                                         raw->sgeNominalSize = cur_size;
1282                                         min_size = cur_size;
1283                                 } else if ((i+1) < nseg && 
1284                                         cur_size != raw->sgeNominalSize) {
1285                                         conformable = FALSE;
1286                                         if (cur_size < min_size)
1287                                                 min_size = cur_size;
1288                                 }
1289                         }
1290
1291                         /* not conformable: evaluate required sg elements */
1292                         if (!conformable) {
1293                                 int j, err_found, nseg_new = nseg;
1294                                 for (i = min_size / PAGE_SIZE; i >= 1; --i) {
1295                                         err_found = FALSE;
1296                                         nseg_new = 2;
1297                                         for (j = 1; j < nseg - 1; ++j) {
1298                                                 if (sg[j].length % (i*PAGE_SIZE)) {
1299                                                         err_found = TRUE;
1300                                                         break;
1301                                                 }
1302                                                 nseg_new += (sg[j].length / (i*PAGE_SIZE));
1303                                         }
1304                                         if (!err_found)
1305                                                 break;
1306                                 }
1307                                 if (i>0 && nseg_new<=sc->aac_sg_tablesize && 
1308                                         !(sc->hint_flags & 4))
1309                                         nseg = aac_convert_sgraw2(sc, 
1310                                                 raw, i, nseg, nseg_new);
1311                         } else {
1312                                 raw->flags |= RIO2_SGL_CONFORMANT;
1313                         }
1314
1315                         /* update the FIB size for the s/g count */
1316                         fib->Header.Size += nseg * 
1317                                 sizeof(struct aac_sge_ieee1212);
1318
1319                 } else if (fib->Header.Command == RawIo) {
1320                         struct aac_sg_tableraw *sg;
1321                         sg = (struct aac_sg_tableraw *)cm->cm_sgtable;
1322                         sg->SgCount = nseg;
1323                         for (i = 0; i < nseg; i++) {
1324                                 sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr;
1325                                 sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len;
1326                                 sg->SgEntryRaw[i].Next = 0;
1327                                 sg->SgEntryRaw[i].Prev = 0;
1328                                 sg->SgEntryRaw[i].Flags = 0;
1329                         }
1330                         /* update the FIB size for the s/g count */
1331                         fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw);
1332                 } else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1333                         struct aac_sg_table *sg;
1334                         sg = cm->cm_sgtable;
1335                         sg->SgCount = nseg;
1336                         for (i = 0; i < nseg; i++) {
1337                                 sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1338                                 sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1339                         }
1340                         /* update the FIB size for the s/g count */
1341                         fib->Header.Size += nseg*sizeof(struct aac_sg_entry);
1342                 } else {
1343                         struct aac_sg_table64 *sg;
1344                         sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1345                         sg->SgCount = nseg;
1346                         for (i = 0; i < nseg; i++) {
1347                                 sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1348                                 sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1349                         }
1350                         /* update the FIB size for the s/g count */
1351                         fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1352                 }
1353         }
1354
1355         /* Fix up the address values in the FIB.  Use the command array index
1356          * instead of a pointer since these fields are only 32 bits.  Shift
1357          * the SenderFibAddress over to make room for the fast response bit
1358          * and for the AIF bit
1359          */
1360         cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2);
1361         cm->cm_fib->Header.u.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1362
1363         /* save a pointer to the command for speedy reverse-lookup */
1364         cm->cm_fib->Header.Handle += cm->cm_index + 1;
1365
1366         if (cm->cm_passthr_dmat == 0) {
1367                 if (cm->cm_flags & AAC_CMD_DATAIN)
1368                         bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1369                                                         BUS_DMASYNC_PREREAD);
1370                 if (cm->cm_flags & AAC_CMD_DATAOUT)
1371                         bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1372                                                         BUS_DMASYNC_PREWRITE);
1373         }
1374
1375         cm->cm_flags |= AAC_CMD_MAPPED;
1376
1377         if (sc->flags & AAC_FLAGS_SYNC_MODE) {
1378                 u_int32_t wait = 0;
1379                 aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 0, 0, &wait, NULL);
1380         } else if (cm->cm_flags & AAC_CMD_WAIT) {
1381                 aacraid_sync_command(sc, AAC_MONKER_SYNCFIB, cm->cm_fibphys, 0, 0, 0, NULL, NULL);
1382         } else {
1383                 int count = 10000000L;
1384                 while (AAC_SEND_COMMAND(sc, cm) != 0) {
1385                         if (--count == 0) {
1386                                 aac_unmap_command(cm);
1387                                 sc->flags |= AAC_QUEUE_FRZN;
1388                                 aac_requeue_ready(cm);
1389                         }
1390                         DELAY(5);                       /* wait 5 usec. */
1391                 }
1392         }
1393 }
1394
1395
1396 static int 
1397 aac_convert_sgraw2(struct aac_softc *sc, struct aac_raw_io2 *raw,
1398                                    int pages, int nseg, int nseg_new)
1399 {
1400         struct aac_sge_ieee1212 *sge;
1401         int i, j, pos;
1402         u_int32_t addr_low;
1403
1404         sge = malloc(nseg_new * sizeof(struct aac_sge_ieee1212), 
1405                 M_AACRAIDBUF, M_NOWAIT|M_ZERO);
1406         if (sge == NULL)
1407                 return nseg;
1408
1409         for (i = 1, pos = 1; i < nseg - 1; ++i) {
1410                 for (j = 0; j < raw->sge[i].length / (pages*PAGE_SIZE); ++j) {
1411                         addr_low = raw->sge[i].addrLow + j * pages * PAGE_SIZE;
1412                         sge[pos].addrLow = addr_low;
1413                         sge[pos].addrHigh = raw->sge[i].addrHigh;
1414                         if (addr_low < raw->sge[i].addrLow)
1415                                 sge[pos].addrHigh++;
1416                         sge[pos].length = pages * PAGE_SIZE;
1417                         sge[pos].flags = 0;
1418                         pos++;
1419                 }
1420         }
1421         sge[pos] = raw->sge[nseg-1];
1422         for (i = 1; i < nseg_new; ++i)
1423                 raw->sge[i] = sge[i];
1424
1425         free(sge, M_AACRAIDBUF);
1426         raw->sgeCnt = nseg_new;
1427         raw->flags |= RIO2_SGL_CONFORMANT;
1428         raw->sgeNominalSize = pages * PAGE_SIZE;
1429         return nseg_new;
1430 }
1431
1432
1433 /*
1434  * Unmap a command from controller-visible space.
1435  */
1436 static void
1437 aac_unmap_command(struct aac_command *cm)
1438 {
1439         struct aac_softc *sc;
1440
1441         sc = cm->cm_sc;
1442         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1443
1444         if (!(cm->cm_flags & AAC_CMD_MAPPED))
1445                 return;
1446
1447         if (cm->cm_datalen != 0 && cm->cm_passthr_dmat == 0) {
1448                 if (cm->cm_flags & AAC_CMD_DATAIN)
1449                         bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1450                                         BUS_DMASYNC_POSTREAD);
1451                 if (cm->cm_flags & AAC_CMD_DATAOUT)
1452                         bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1453                                         BUS_DMASYNC_POSTWRITE);
1454
1455                 bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1456         }
1457         cm->cm_flags &= ~AAC_CMD_MAPPED;
1458 }
1459
1460 /*
1461  * Hardware Interface
1462  */
1463
1464 /*
1465  * Initialize the adapter.
1466  */
1467 static void
1468 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1469 {
1470         struct aac_softc *sc;
1471
1472         sc = (struct aac_softc *)arg;
1473         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1474
1475         sc->aac_common_busaddr = segs[0].ds_addr;
1476 }
1477
1478 static int
1479 aac_check_firmware(struct aac_softc *sc)
1480 {
1481         u_int32_t code, major, minor, maxsize;
1482         u_int32_t options = 0, atu_size = 0, status;
1483         time_t then;
1484
1485         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1486         /*
1487          * Wait for the adapter to come ready.
1488          */
1489         then = time_uptime;
1490         do {
1491                 code = AAC_GET_FWSTATUS(sc);
1492                 if (code & AAC_SELF_TEST_FAILED) {
1493                         device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1494                         return(ENXIO);
1495                 }
1496                 if (code & AAC_KERNEL_PANIC) {
1497                         device_printf(sc->aac_dev,
1498                                       "FATAL: controller kernel panic");
1499                         return(ENXIO);
1500                 }
1501                 if (time_uptime > (then + AAC_BOOT_TIMEOUT)) {
1502                         device_printf(sc->aac_dev,
1503                                       "FATAL: controller not coming ready, "
1504                                            "status %x\n", code);
1505                         return(ENXIO);
1506                 }
1507         } while (!(code & AAC_UP_AND_RUNNING));
1508
1509         /*
1510          * Retrieve the firmware version numbers.  Dell PERC2/QC cards with
1511          * firmware version 1.x are not compatible with this driver.
1512          */
1513         if (sc->flags & AAC_FLAGS_PERC2QC) {
1514                 if (aacraid_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1515                                      NULL, NULL)) {
1516                         device_printf(sc->aac_dev,
1517                                       "Error reading firmware version\n");
1518                         return (EIO);
1519                 }
1520
1521                 /* These numbers are stored as ASCII! */
1522                 major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1523                 minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1524                 if (major == 1) {
1525                         device_printf(sc->aac_dev,
1526                             "Firmware version %d.%d is not supported.\n",
1527                             major, minor);
1528                         return (EINVAL);
1529                 }
1530         }
1531         /*
1532          * Retrieve the capabilities/supported options word so we know what
1533          * work-arounds to enable.  Some firmware revs don't support this
1534          * command.
1535          */
1536         if (aacraid_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status, NULL)) {
1537                 if (status != AAC_SRB_STS_INVALID_REQUEST) {
1538                         device_printf(sc->aac_dev,
1539                              "RequestAdapterInfo failed\n");
1540                         return (EIO);
1541                 }
1542         } else {
1543                 options = AAC_GET_MAILBOX(sc, 1);
1544                 atu_size = AAC_GET_MAILBOX(sc, 2);
1545                 sc->supported_options = options;
1546
1547                 if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1548                     (sc->flags & AAC_FLAGS_NO4GB) == 0)
1549                         sc->flags |= AAC_FLAGS_4GB_WINDOW;
1550                 if (options & AAC_SUPPORTED_NONDASD)
1551                         sc->flags |= AAC_FLAGS_ENABLE_CAM;
1552                 if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1553                         && (sizeof(bus_addr_t) > 4)
1554                         && (sc->hint_flags & 0x1)) {
1555                         device_printf(sc->aac_dev,
1556                             "Enabling 64-bit address support\n");
1557                         sc->flags |= AAC_FLAGS_SG_64BIT;
1558                 }
1559                 if (sc->aac_if.aif_send_command) {
1560                         if ((options & AAC_SUPPORTED_NEW_COMM_TYPE3) ||
1561                                 (options & AAC_SUPPORTED_NEW_COMM_TYPE4))
1562                                 sc->flags |= AAC_FLAGS_NEW_COMM | AAC_FLAGS_NEW_COMM_TYPE34;
1563                         else if (options & AAC_SUPPORTED_NEW_COMM_TYPE1)
1564                                 sc->flags |= AAC_FLAGS_NEW_COMM | AAC_FLAGS_NEW_COMM_TYPE1;
1565                         else if (options & AAC_SUPPORTED_NEW_COMM_TYPE2)
1566                                 sc->flags |= AAC_FLAGS_NEW_COMM | AAC_FLAGS_NEW_COMM_TYPE2;
1567                 }
1568                 if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
1569                         sc->flags |= AAC_FLAGS_ARRAY_64BIT;
1570         }
1571
1572         if (!(sc->flags & AAC_FLAGS_NEW_COMM)) {
1573                 device_printf(sc->aac_dev, "Communication interface not supported!\n");
1574                 return (ENXIO);
1575         }
1576
1577         if (sc->hint_flags & 2) {
1578                 device_printf(sc->aac_dev, 
1579                         "Sync. mode enforced by driver parameter. This will cause a significant performance decrease!\n");
1580                 sc->flags |= AAC_FLAGS_SYNC_MODE;
1581         } else if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE34) {
1582                 device_printf(sc->aac_dev, 
1583                         "Async. mode not supported by current driver, sync. mode enforced.\nPlease update driver to get full performance.\n");
1584                 sc->flags |= AAC_FLAGS_SYNC_MODE;
1585         }
1586
1587         /* Check for broken hardware that does a lower number of commands */
1588         sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512);
1589
1590         /* Remap mem. resource, if required */
1591         if (atu_size > rman_get_size(sc->aac_regs_res0)) {
1592                 bus_release_resource(
1593                         sc->aac_dev, SYS_RES_MEMORY,
1594                         sc->aac_regs_rid0, sc->aac_regs_res0);
1595                 sc->aac_regs_res0 = bus_alloc_resource(
1596                         sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid0,
1597                         0ul, ~0ul, atu_size, RF_ACTIVE);
1598                 if (sc->aac_regs_res0 == NULL) {
1599                         sc->aac_regs_res0 = bus_alloc_resource_any(
1600                                 sc->aac_dev, SYS_RES_MEMORY,
1601                                 &sc->aac_regs_rid0, RF_ACTIVE);
1602                         if (sc->aac_regs_res0 == NULL) {
1603                                 device_printf(sc->aac_dev,
1604                                         "couldn't allocate register window\n");
1605                                 return (ENXIO);
1606                         }
1607                 }
1608                 sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
1609                 sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
1610         }
1611
1612         /* Read preferred settings */
1613         sc->aac_max_fib_size = sizeof(struct aac_fib);
1614         sc->aac_max_sectors = 128;                              /* 64KB */
1615         sc->aac_max_aif = 1;
1616         if (sc->flags & AAC_FLAGS_SG_64BIT)
1617                 sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1618                  - sizeof(struct aac_blockwrite64))
1619                  / sizeof(struct aac_sg_entry64);
1620         else
1621                 sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1622                  - sizeof(struct aac_blockwrite))
1623                  / sizeof(struct aac_sg_entry);
1624
1625         if (!aacraid_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL, NULL)) {
1626                 options = AAC_GET_MAILBOX(sc, 1);
1627                 sc->aac_max_fib_size = (options & 0xFFFF);
1628                 sc->aac_max_sectors = (options >> 16) << 1;
1629                 options = AAC_GET_MAILBOX(sc, 2);
1630                 sc->aac_sg_tablesize = (options >> 16);
1631                 options = AAC_GET_MAILBOX(sc, 3);
1632                 sc->aac_max_fibs = (options & 0xFFFF);
1633                 options = AAC_GET_MAILBOX(sc, 4);
1634                 sc->aac_max_aif = (options & 0xFFFF);
1635         }
1636
1637         maxsize = sc->aac_max_fib_size + 31;
1638         if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
1639                 maxsize += sizeof(struct aac_fib_xporthdr);
1640         if (maxsize > PAGE_SIZE) {
1641         sc->aac_max_fib_size -= (maxsize - PAGE_SIZE);
1642                 maxsize = PAGE_SIZE;
1643         }
1644         sc->aac_max_fibs_alloc = PAGE_SIZE / maxsize;
1645
1646         if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1647                 sc->flags |= AAC_FLAGS_RAW_IO;
1648                 device_printf(sc->aac_dev, "Enable Raw I/O\n");
1649         }
1650         if ((sc->flags & AAC_FLAGS_RAW_IO) &&
1651             (sc->flags & AAC_FLAGS_ARRAY_64BIT)) {
1652                 sc->flags |= AAC_FLAGS_LBA_64BIT;
1653                 device_printf(sc->aac_dev, "Enable 64-bit array\n");
1654         }
1655
1656         aacraid_get_fw_debug_buffer(sc);
1657         return (0);
1658 }
1659
1660 static int
1661 aac_init(struct aac_softc *sc)
1662 {
1663         struct aac_adapter_init *ip;
1664         int error;
1665
1666         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1667
1668         /* reset rrq index */
1669         sc->aac_host_rrq_idx = 0;
1670
1671         /*
1672          * Fill in the init structure.  This tells the adapter about the
1673          * physical location of various important shared data structures.
1674          */
1675         ip = &sc->aac_common->ac_init;
1676         ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1677         if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1678                 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_4;
1679                 sc->flags |= AAC_FLAGS_RAW_IO;
1680         }
1681         ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1682
1683         ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1684                                          offsetof(struct aac_common, ac_fibs);
1685         ip->AdapterFibsVirtualAddress = 0;
1686         ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1687         ip->AdapterFibAlign = sizeof(struct aac_fib);
1688
1689         ip->PrintfBufferAddress = sc->aac_common_busaddr +
1690                                   offsetof(struct aac_common, ac_printf);
1691         ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1692
1693         /*
1694          * The adapter assumes that pages are 4K in size, except on some
1695          * broken firmware versions that do the page->byte conversion twice,
1696          * therefore 'assuming' that this value is in 16MB units (2^24).
1697          * Round up since the granularity is so high.
1698          */
1699         ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1700         if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1701                 ip->HostPhysMemPages =
1702                     (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1703         }
1704         ip->HostElapsedSeconds = time_uptime;   /* reset later if invalid */
1705
1706         ip->InitFlags = AAC_INITFLAGS_NEW_COMM_SUPPORTED;
1707         if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) {
1708                 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_6;
1709                 ip->InitFlags |= (AAC_INITFLAGS_NEW_COMM_TYPE1_SUPPORTED |
1710                         AAC_INITFLAGS_FAST_JBOD_SUPPORTED);
1711                 ip->MiniPortRevision = 0L;
1712                 device_printf(sc->aac_dev, "New comm. interface type1 enabled\n");
1713         } else if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE2) {
1714                 ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_7;
1715                 ip->InitFlags |= (AAC_INITFLAGS_NEW_COMM_TYPE2_SUPPORTED |
1716                         AAC_INITFLAGS_FAST_JBOD_SUPPORTED);
1717                 device_printf(sc->aac_dev, "New comm. interface type2 enabled\n");
1718         }
1719         ip->MaxNumAif = sc->aac_max_aif;
1720         ip->HostRRQ_AddrLow = 
1721                 sc->aac_common_busaddr + offsetof(struct aac_common, ac_host_rrq);
1722         /* always 32-bit address */
1723         ip->HostRRQ_AddrHigh = 0;
1724
1725         if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) {
1726                 ip->InitFlags |= AAC_INITFLAGS_DRIVER_SUPPORTS_PM;
1727                 ip->InitFlags |= AAC_INITFLAGS_DRIVER_USES_UTC_TIME;
1728                 device_printf(sc->aac_dev, "Power Management enabled\n");
1729         }
1730
1731         ip->MaxIoCommands = sc->aac_max_fibs;
1732         ip->MaxIoSize = sc->aac_max_sectors << 9;
1733         ip->MaxFibSize = sc->aac_max_fib_size;
1734
1735         /*
1736          * Do controller-type-specific initialisation
1737          */
1738         AAC_MEM0_SETREG4(sc, AAC_SRC_ODBR_C, ~0);
1739
1740         /*
1741          * Give the init structure to the controller.
1742          */
1743         if (aacraid_sync_command(sc, AAC_MONKER_INITSTRUCT,
1744                              sc->aac_common_busaddr +
1745                              offsetof(struct aac_common, ac_init), 0, 0, 0,
1746                              NULL, NULL)) {
1747                 device_printf(sc->aac_dev,
1748                               "error establishing init structure\n");
1749                 error = EIO;
1750                 goto out;
1751         }
1752
1753         error = 0;
1754 out:
1755         return(error);
1756 }
1757
1758 static int
1759 aac_setup_intr(struct aac_softc *sc)
1760 {
1761         sc->aac_irq_rid = 0;
1762         if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
1763                                                   &sc->aac_irq_rid,
1764                                                   RF_SHAREABLE |
1765                                                   RF_ACTIVE)) == NULL) {
1766                 device_printf(sc->aac_dev, "can't allocate interrupt\n");
1767                 return (EINVAL);
1768         }
1769         if (aac_bus_setup_intr(sc->aac_dev, sc->aac_irq,
1770                            INTR_MPSAFE|INTR_TYPE_BIO, NULL, 
1771                            aacraid_new_intr_type1, sc, &sc->aac_intr)) {
1772                 device_printf(sc->aac_dev, "can't set up interrupt\n");
1773                 return (EINVAL);
1774         }
1775         return (0);
1776 }
1777
1778 /*
1779  * Send a synchronous command to the controller and wait for a result.
1780  * Indicate if the controller completed the command with an error status.
1781  */
1782 int
1783 aacraid_sync_command(struct aac_softc *sc, u_int32_t command,
1784                  u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1785                  u_int32_t *sp, u_int32_t *r1)
1786 {
1787         time_t then;
1788         u_int32_t status;
1789
1790         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1791
1792         /* populate the mailbox */
1793         AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1794
1795         /* ensure the sync command doorbell flag is cleared */
1796         AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1797
1798         /* then set it to signal the adapter */
1799         AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1800
1801         if ((command != AAC_MONKER_SYNCFIB) || (sp == NULL) || (*sp != 0)) {
1802                 /* spin waiting for the command to complete */
1803                 then = time_uptime;
1804                 do {
1805                         if (time_uptime > (then + AAC_IMMEDIATE_TIMEOUT)) {
1806                                 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "timed out");
1807                                 return(EIO);
1808                         }
1809                 } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1810
1811                 /* clear the completion flag */
1812                 AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1813
1814                 /* get the command status */
1815                 status = AAC_GET_MAILBOX(sc, 0);
1816                 if (sp != NULL)
1817                         *sp = status;
1818
1819                 /* return parameter */
1820                 if (r1 != NULL) 
1821                         *r1 = AAC_GET_MAILBOX(sc, 1);
1822
1823                 if (status != AAC_SRB_STS_SUCCESS)
1824                         return (-1);
1825         }
1826         return(0);
1827 }
1828
1829 static int
1830 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1831                  struct aac_fib *fib, u_int16_t datasize)
1832 {
1833         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1834         mtx_assert(&sc->aac_io_lock, MA_OWNED);
1835
1836         if (datasize > AAC_FIB_DATASIZE)
1837                 return(EINVAL);
1838
1839         /*
1840          * Set up the sync FIB
1841          */
1842         fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1843                                 AAC_FIBSTATE_INITIALISED |
1844                                 AAC_FIBSTATE_EMPTY;
1845         fib->Header.XferState |= xferstate;
1846         fib->Header.Command = command;
1847         fib->Header.StructType = AAC_FIBTYPE_TFIB;
1848         fib->Header.Size = sizeof(struct aac_fib_header) + datasize;
1849         fib->Header.SenderSize = sizeof(struct aac_fib);
1850         fib->Header.SenderFibAddress = 0;       /* Not needed */
1851         fib->Header.u.ReceiverFibAddress = sc->aac_common_busaddr +
1852                                          offsetof(struct aac_common,
1853                                                   ac_sync_fib);
1854
1855         /*
1856          * Give the FIB to the controller, wait for a response.
1857          */
1858         if (aacraid_sync_command(sc, AAC_MONKER_SYNCFIB,
1859                              fib->Header.u.ReceiverFibAddress, 0, 0, 0, NULL, NULL)) {
1860                 fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error");
1861                 return(EIO);
1862         }
1863
1864         return (0);
1865 }
1866
1867 /*
1868  * Check for commands that have been outstanding for a suspiciously long time,
1869  * and complain about them.
1870  */
1871 static void
1872 aac_timeout(struct aac_softc *sc)
1873 {
1874         struct aac_command *cm;
1875         time_t deadline;
1876         int timedout, code;
1877
1878         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1879         /*
1880          * Traverse the busy command list, bitch about late commands once
1881          * only.
1882          */
1883         timedout = 0;
1884         deadline = time_uptime - AAC_CMD_TIMEOUT;
1885         TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1886                 if ((cm->cm_timestamp  < deadline)
1887                         /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
1888                         cm->cm_flags |= AAC_CMD_TIMEDOUT;
1889                         device_printf(sc->aac_dev,
1890                                       "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
1891                                       cm, (int)(time_uptime-cm->cm_timestamp));
1892                         AAC_PRINT_FIB(sc, cm->cm_fib);
1893                         timedout++;
1894                 }
1895         }
1896
1897         if (timedout) {
1898                 code = AAC_GET_FWSTATUS(sc);
1899                 if (code != AAC_UP_AND_RUNNING) {
1900                         device_printf(sc->aac_dev, "WARNING! Controller is no "
1901                                       "longer running! code= 0x%x\n", code);
1902                         aac_reset_adapter(sc);
1903                 }
1904         }
1905         aacraid_print_queues(sc);
1906 }
1907
1908 /*
1909  * Interface Function Vectors
1910  */
1911
1912 /*
1913  * Read the current firmware status word.
1914  */
1915 static int
1916 aac_src_get_fwstatus(struct aac_softc *sc)
1917 {
1918         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1919
1920         return(AAC_MEM0_GETREG4(sc, AAC_SRC_OMR));
1921 }
1922
1923 /*
1924  * Notify the controller of a change in a given queue
1925  */
1926 static void
1927 aac_src_qnotify(struct aac_softc *sc, int qbit)
1928 {
1929         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1930
1931         AAC_MEM0_SETREG4(sc, AAC_SRC_IDBR, qbit << AAC_SRC_IDR_SHIFT);
1932 }
1933
1934 /*
1935  * Get the interrupt reason bits
1936  */
1937 static int
1938 aac_src_get_istatus(struct aac_softc *sc)
1939 {
1940         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1941
1942         return(AAC_MEM0_GETREG4(sc, AAC_SRC_ODBR_R) >> AAC_SRC_ODR_SHIFT);
1943 }
1944
1945 /*
1946  * Clear some interrupt reason bits
1947  */
1948 static void
1949 aac_src_clear_istatus(struct aac_softc *sc, int mask)
1950 {
1951         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1952
1953         AAC_MEM0_SETREG4(sc, AAC_SRC_ODBR_C, mask << AAC_SRC_ODR_SHIFT);
1954 }
1955
1956 /*
1957  * Populate the mailbox and set the command word
1958  */
1959 static void
1960 aac_src_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1961                     u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1962 {
1963         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1964
1965         AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX, command);
1966         AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 4, arg0);
1967         AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 8, arg1);
1968         AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 12, arg2);
1969         AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 16, arg3);
1970 }
1971
1972 static void
1973 aac_srcv_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1974                     u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1975 {
1976         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1977
1978         AAC_MEM0_SETREG4(sc, AAC_SRCV_MAILBOX, command);
1979         AAC_MEM0_SETREG4(sc, AAC_SRCV_MAILBOX + 4, arg0);
1980         AAC_MEM0_SETREG4(sc, AAC_SRCV_MAILBOX + 8, arg1);
1981         AAC_MEM0_SETREG4(sc, AAC_SRCV_MAILBOX + 12, arg2);
1982         AAC_MEM0_SETREG4(sc, AAC_SRCV_MAILBOX + 16, arg3);
1983 }
1984
1985 /*
1986  * Fetch the immediate command status word
1987  */
1988 static int
1989 aac_src_get_mailbox(struct aac_softc *sc, int mb)
1990 {
1991         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1992
1993         return(AAC_MEM0_GETREG4(sc, AAC_SRC_MAILBOX + (mb * 4)));
1994 }
1995
1996 static int
1997 aac_srcv_get_mailbox(struct aac_softc *sc, int mb)
1998 {
1999         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2000
2001         return(AAC_MEM0_GETREG4(sc, AAC_SRCV_MAILBOX + (mb * 4)));
2002 }
2003
2004 /*
2005  * Set/clear interrupt masks
2006  */
2007 static void
2008 aac_src_set_interrupts(struct aac_softc *sc, int enable)
2009 {
2010         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2011
2012         if (enable) {
2013                 AAC_MEM0_SETREG4(sc, AAC_SRC_OIMR, ~AAC_DB_INT_NEW_COMM_TYPE1);
2014         } else {
2015                 AAC_MEM0_SETREG4(sc, AAC_SRC_OIMR, ~0);
2016         }
2017 }
2018
2019 /*
2020  * New comm. interface: Send command functions
2021  */
2022 static int
2023 aac_src_send_command(struct aac_softc *sc, struct aac_command *cm)
2024 {
2025         struct aac_fib_xporthdr *pFibX;
2026         u_int32_t fibsize, high_addr;
2027         u_int64_t address;
2028
2029         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm. type1)");
2030
2031         if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE2) {
2032                 /* Calculate the amount to the fibsize bits */
2033                 fibsize = (cm->cm_fib->Header.Size + 127) / 128 - 1; 
2034                 /* Fill new FIB header */
2035                 address = cm->cm_fibphys;
2036                 high_addr = (u_int32_t)(address >> 32);
2037                 if (high_addr == 0L) {
2038                         cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB2;
2039                         cm->cm_fib->Header.u.TimeStamp = 0L;
2040                 } else {
2041                         cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB2_64;
2042                         cm->cm_fib->Header.u.SenderFibAddressHigh = high_addr;
2043                 }
2044                 cm->cm_fib->Header.SenderFibAddress = (u_int32_t)address;
2045         } else {
2046                 /* Calculate the amount to the fibsize bits */
2047                 fibsize = (sizeof(struct aac_fib_xporthdr) + 
2048                    cm->cm_fib->Header.Size + 127) / 128 - 1; 
2049                 /* Fill XPORT header */ 
2050                 pFibX = (struct aac_fib_xporthdr *)
2051                         ((unsigned char *)cm->cm_fib - sizeof(struct aac_fib_xporthdr));
2052                 pFibX->Handle = cm->cm_fib->Header.Handle;
2053                 pFibX->HostAddress = cm->cm_fibphys;
2054                 pFibX->Size = cm->cm_fib->Header.Size;
2055                 address = cm->cm_fibphys - sizeof(struct aac_fib_xporthdr);
2056                 high_addr = (u_int32_t)(address >> 32);
2057         }
2058
2059         if (fibsize > 31) 
2060                 fibsize = 31;
2061         aac_enqueue_busy(cm);
2062         if (high_addr) {
2063                 AAC_MEM0_SETREG4(sc, AAC_SRC_IQUE64_H, high_addr);
2064                 AAC_MEM0_SETREG4(sc, AAC_SRC_IQUE64_L, (u_int32_t)address + fibsize);
2065         } else {
2066                 AAC_MEM0_SETREG4(sc, AAC_SRC_IQUE32, (u_int32_t)address + fibsize);
2067         }
2068         return 0;
2069 }
2070
2071 /*
2072  * New comm. interface: get, set outbound queue index
2073  */
2074 static int
2075 aac_src_get_outb_queue(struct aac_softc *sc)
2076 {
2077         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2078
2079         return(-1);
2080 }
2081
2082 static void
2083 aac_src_set_outb_queue(struct aac_softc *sc, int index)
2084 {
2085         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2086 }
2087
2088 /*
2089  * Debugging and Diagnostics
2090  */
2091
2092 /*
2093  * Print some information about the controller.
2094  */
2095 static void
2096 aac_describe_controller(struct aac_softc *sc)
2097 {
2098         struct aac_fib *fib;
2099         struct aac_adapter_info *info;
2100         char *adapter_type = "Adaptec RAID controller";
2101
2102         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2103
2104         mtx_lock(&sc->aac_io_lock);
2105         aac_alloc_sync_fib(sc, &fib);
2106
2107         if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
2108                 fib->data[0] = 0;
2109                 if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1)) 
2110                         device_printf(sc->aac_dev, "RequestSupplementAdapterInfo failed\n");
2111                 else {
2112                         struct aac_supplement_adapter_info *supp_info;
2113
2114                         supp_info = ((struct aac_supplement_adapter_info *)&fib->data[0]); 
2115                         adapter_type = (char *)supp_info->AdapterTypeText;
2116                         sc->aac_feature_bits = supp_info->FeatureBits;
2117                         sc->aac_support_opt2 = supp_info->SupportedOptions2;
2118                 }
2119         }
2120         device_printf(sc->aac_dev, "%s, aacraid driver %d.%d.%d-%d\n",
2121                 adapter_type,
2122                 AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
2123                 AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
2124
2125         fib->data[0] = 0;
2126         if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2127                 device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2128                 aac_release_sync_fib(sc);
2129                 mtx_unlock(&sc->aac_io_lock);
2130                 return;
2131         }
2132
2133         /* save the kernel revision structure for later use */
2134         info = (struct aac_adapter_info *)&fib->data[0];
2135         sc->aac_revision = info->KernelRevision;
2136
2137         if (bootverbose) {
2138                 device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
2139                     "(%dMB cache, %dMB execution), %s\n",
2140                     aac_describe_code(aac_cpu_variant, info->CpuVariant),
2141                     info->ClockSpeed, info->TotalMem / (1024 * 1024),
2142                     info->BufferMem / (1024 * 1024),
2143                     info->ExecutionMem / (1024 * 1024),
2144                     aac_describe_code(aac_battery_platform,
2145                     info->batteryPlatform));
2146
2147                 device_printf(sc->aac_dev,
2148                     "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2149                     info->KernelRevision.external.comp.major,
2150                     info->KernelRevision.external.comp.minor,
2151                     info->KernelRevision.external.comp.dash,
2152                     info->KernelRevision.buildNumber,
2153                     (u_int32_t)(info->SerialNumber & 0xffffff));
2154
2155                 device_printf(sc->aac_dev, "Supported Options=%b\n",
2156                               sc->supported_options,
2157                               "\20"
2158                               "\1SNAPSHOT"
2159                               "\2CLUSTERS"
2160                               "\3WCACHE"
2161                               "\4DATA64"
2162                               "\5HOSTTIME"
2163                               "\6RAID50"
2164                               "\7WINDOW4GB"
2165                               "\10SCSIUPGD"
2166                               "\11SOFTERR"
2167                               "\12NORECOND"
2168                               "\13SGMAP64"
2169                               "\14ALARM"
2170                               "\15NONDASD"
2171                               "\16SCSIMGT"
2172                               "\17RAIDSCSI"
2173                               "\21ADPTINFO"
2174                               "\22NEWCOMM"
2175                               "\23ARRAY64BIT"
2176                               "\24HEATSENSOR");
2177         }
2178
2179         aac_release_sync_fib(sc);
2180         mtx_unlock(&sc->aac_io_lock);
2181 }
2182
2183 /*
2184  * Look up a text description of a numeric error code and return a pointer to
2185  * same.
2186  */
2187 static char *
2188 aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2189 {
2190         int i;
2191
2192         for (i = 0; table[i].string != NULL; i++)
2193                 if (table[i].code == code)
2194                         return(table[i].string);
2195         return(table[i + 1].string);
2196 }
2197
2198 /*
2199  * Management Interface
2200  */
2201
2202 static int
2203 aac_open(struct cdev *dev, int flags, int fmt, struct thread *td)
2204 {
2205         struct aac_softc *sc;
2206
2207         sc = dev->si_drv1;
2208         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2209 #if __FreeBSD_version >= 702000
2210         device_busy(sc->aac_dev);
2211         devfs_set_cdevpriv(sc, aac_cdevpriv_dtor);
2212 #endif
2213         return 0;
2214 }
2215
2216 static int
2217 aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
2218 {
2219         union aac_statrequest *as;
2220         struct aac_softc *sc;
2221         int error = 0;
2222
2223         as = (union aac_statrequest *)arg;
2224         sc = dev->si_drv1;
2225         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2226
2227         switch (cmd) {
2228         case AACIO_STATS:
2229                 switch (as->as_item) {
2230                 case AACQ_FREE:
2231                 case AACQ_READY:
2232                 case AACQ_BUSY:
2233                         bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2234                               sizeof(struct aac_qstat));
2235                         break;
2236                 default:
2237                         error = ENOENT;
2238                         break;
2239                 }
2240         break;
2241
2242         case FSACTL_SENDFIB:
2243         case FSACTL_SEND_LARGE_FIB:
2244                 arg = *(caddr_t*)arg;
2245         case FSACTL_LNX_SENDFIB:
2246         case FSACTL_LNX_SEND_LARGE_FIB:
2247                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SENDFIB");
2248                 error = aac_ioctl_sendfib(sc, arg);
2249                 break;
2250         case FSACTL_SEND_RAW_SRB:
2251                 arg = *(caddr_t*)arg;
2252         case FSACTL_LNX_SEND_RAW_SRB:
2253                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SEND_RAW_SRB");
2254                 error = aac_ioctl_send_raw_srb(sc, arg);
2255                 break;
2256         case FSACTL_AIF_THREAD:
2257         case FSACTL_LNX_AIF_THREAD:
2258                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_AIF_THREAD");
2259                 error = EINVAL;
2260                 break;
2261         case FSACTL_OPEN_GET_ADAPTER_FIB:
2262                 arg = *(caddr_t*)arg;
2263         case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2264                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_OPEN_GET_ADAPTER_FIB");
2265                 error = aac_open_aif(sc, arg);
2266                 break;
2267         case FSACTL_GET_NEXT_ADAPTER_FIB:
2268                 arg = *(caddr_t*)arg;
2269         case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2270                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_NEXT_ADAPTER_FIB");
2271                 error = aac_getnext_aif(sc, arg);
2272                 break;
2273         case FSACTL_CLOSE_GET_ADAPTER_FIB:
2274                 arg = *(caddr_t*)arg;
2275         case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2276                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2277                 error = aac_close_aif(sc, arg);
2278                 break;
2279         case FSACTL_MINIPORT_REV_CHECK:
2280                 arg = *(caddr_t*)arg;
2281         case FSACTL_LNX_MINIPORT_REV_CHECK:
2282                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_MINIPORT_REV_CHECK");
2283                 error = aac_rev_check(sc, arg);
2284                 break;
2285         case FSACTL_QUERY_DISK:
2286                 arg = *(caddr_t*)arg;
2287         case FSACTL_LNX_QUERY_DISK:
2288                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_QUERY_DISK");
2289                 error = aac_query_disk(sc, arg);
2290                 break;
2291         case FSACTL_DELETE_DISK:
2292         case FSACTL_LNX_DELETE_DISK:
2293                 /*
2294                  * We don't trust the underland to tell us when to delete a
2295                  * container, rather we rely on an AIF coming from the
2296                  * controller
2297                  */
2298                 error = 0;
2299                 break;
2300         case FSACTL_GET_PCI_INFO:
2301                 arg = *(caddr_t*)arg;
2302         case FSACTL_LNX_GET_PCI_INFO:
2303                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_PCI_INFO");
2304                 error = aac_get_pci_info(sc, arg);
2305                 break;
2306         case FSACTL_GET_FEATURES:
2307                 arg = *(caddr_t*)arg;
2308         case FSACTL_LNX_GET_FEATURES:
2309                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_FEATURES");
2310                 error = aac_supported_features(sc, arg);
2311                 break;
2312         default:
2313                 fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "unsupported cmd 0x%lx\n", cmd);
2314                 error = EINVAL;
2315                 break;
2316         }
2317         return(error);
2318 }
2319
2320 static int
2321 aac_poll(struct cdev *dev, int poll_events, struct thread *td)
2322 {
2323         struct aac_softc *sc;
2324         struct aac_fib_context *ctx;
2325         int revents;
2326
2327         sc = dev->si_drv1;
2328         revents = 0;
2329
2330         mtx_lock(&sc->aac_io_lock);
2331         if ((poll_events & (POLLRDNORM | POLLIN)) != 0) {
2332                 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
2333                         if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap) {
2334                                 revents |= poll_events & (POLLIN | POLLRDNORM);
2335                                 break;
2336                         }
2337                 }
2338         }
2339         mtx_unlock(&sc->aac_io_lock);
2340
2341         if (revents == 0) {
2342                 if (poll_events & (POLLIN | POLLRDNORM))
2343                         selrecord(td, &sc->rcv_select);
2344         }
2345
2346         return (revents);
2347 }
2348
2349 static void
2350 aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
2351 {
2352
2353         switch (event->ev_type) {
2354         case AAC_EVENT_CMFREE:
2355                 mtx_assert(&sc->aac_io_lock, MA_OWNED);
2356                 if (aacraid_alloc_command(sc, (struct aac_command **)arg)) {
2357                         aacraid_add_event(sc, event);
2358                         return;
2359                 }
2360                 free(event, M_AACRAIDBUF);
2361                 wakeup(arg);
2362                 break;
2363         default:
2364                 break;
2365         }
2366 }
2367
2368 /*
2369  * Send a FIB supplied from userspace
2370  */
2371 static int
2372 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2373 {
2374         struct aac_command *cm;
2375         int size, error;
2376
2377         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2378
2379         cm = NULL;
2380
2381         /*
2382          * Get a command
2383          */
2384         mtx_lock(&sc->aac_io_lock);
2385         if (aacraid_alloc_command(sc, &cm)) {
2386                 struct aac_event *event;
2387
2388                 event = malloc(sizeof(struct aac_event), M_AACRAIDBUF,
2389                     M_NOWAIT | M_ZERO);
2390                 if (event == NULL) {
2391                         error = EBUSY;
2392                         mtx_unlock(&sc->aac_io_lock);
2393                         goto out;
2394                 }
2395                 event->ev_type = AAC_EVENT_CMFREE;
2396                 event->ev_callback = aac_ioctl_event;
2397                 event->ev_arg = &cm;
2398                 aacraid_add_event(sc, event);
2399                 msleep(cm, &sc->aac_io_lock, 0, "aacraid_ctlsfib", 0);
2400         }
2401         mtx_unlock(&sc->aac_io_lock);
2402
2403         /*
2404          * Fetch the FIB header, then re-copy to get data as well.
2405          */
2406         if ((error = copyin(ufib, cm->cm_fib,
2407                             sizeof(struct aac_fib_header))) != 0)
2408                 goto out;
2409         size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
2410         if (size > sc->aac_max_fib_size) {
2411                 device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
2412                               size, sc->aac_max_fib_size);
2413                 size = sc->aac_max_fib_size;
2414         }
2415         if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
2416                 goto out;
2417         cm->cm_fib->Header.Size = size;
2418         cm->cm_timestamp = time_uptime;
2419         cm->cm_datalen = 0;
2420
2421         /*
2422          * Pass the FIB to the controller, wait for it to complete.
2423          */
2424         mtx_lock(&sc->aac_io_lock);
2425         error = aacraid_wait_command(cm);
2426         mtx_unlock(&sc->aac_io_lock);
2427         if (error != 0) {
2428                 device_printf(sc->aac_dev,
2429                               "aacraid_wait_command return %d\n", error);
2430                 goto out;
2431         }
2432
2433         /*
2434          * Copy the FIB and data back out to the caller.
2435          */
2436         size = cm->cm_fib->Header.Size;
2437         if (size > sc->aac_max_fib_size) {
2438                 device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
2439                               size, sc->aac_max_fib_size);
2440                 size = sc->aac_max_fib_size;
2441         }
2442         error = copyout(cm->cm_fib, ufib, size);
2443
2444 out:
2445         if (cm != NULL) {
2446                 mtx_lock(&sc->aac_io_lock);
2447                 aacraid_release_command(cm);
2448                 mtx_unlock(&sc->aac_io_lock);
2449         }
2450         return(error);
2451 }
2452
2453 /*
2454  * Send a passthrough FIB supplied from userspace
2455  */
2456 static int
2457 aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
2458 {
2459         struct aac_command *cm;
2460         struct aac_fib *fib;
2461         struct aac_srb *srbcmd;
2462         struct aac_srb *user_srb = (struct aac_srb *)arg;
2463         void *user_reply;
2464         int error, transfer_data = 0;
2465         bus_dmamap_t orig_map = 0;
2466         u_int32_t fibsize = 0;
2467         u_int64_t srb_sg_address;
2468         u_int32_t srb_sg_bytecount;
2469
2470         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2471
2472         cm = NULL;
2473
2474         mtx_lock(&sc->aac_io_lock);
2475         if (aacraid_alloc_command(sc, &cm)) {
2476                 struct aac_event *event;
2477
2478                 event = malloc(sizeof(struct aac_event), M_AACRAIDBUF,
2479                     M_NOWAIT | M_ZERO);
2480                 if (event == NULL) {
2481                         error = EBUSY;
2482                         mtx_unlock(&sc->aac_io_lock);
2483                         goto out;
2484                 }
2485                 event->ev_type = AAC_EVENT_CMFREE;
2486                 event->ev_callback = aac_ioctl_event;
2487                 event->ev_arg = &cm;
2488                 aacraid_add_event(sc, event);
2489                 msleep(cm, &sc->aac_io_lock, 0, "aacraid_ctlsraw", 0);
2490         }
2491         mtx_unlock(&sc->aac_io_lock);
2492
2493         cm->cm_data = NULL;
2494         /* save original dma map */
2495         orig_map = cm->cm_datamap;
2496
2497         fib = cm->cm_fib;
2498         srbcmd = (struct aac_srb *)fib->data;
2499         if ((error = copyin((void *)&user_srb->data_len, &fibsize, 
2500                 sizeof (u_int32_t)) != 0)) 
2501                 goto out;
2502         if (fibsize > (sc->aac_max_fib_size-sizeof(struct aac_fib_header))) {
2503                 error = EINVAL;
2504                 goto out;
2505         }
2506         if ((error = copyin((void *)user_srb, srbcmd, fibsize) != 0)) 
2507                 goto out;
2508
2509         srbcmd->function = 0;           /* SRBF_ExecuteScsi */
2510         srbcmd->retry_limit = 0;        /* obsolete */
2511
2512         /* only one sg element from userspace supported */
2513         if (srbcmd->sg_map.SgCount > 1) {
2514                 error = EINVAL;
2515                 goto out;
2516         }
2517         /* check fibsize */
2518         if (fibsize == (sizeof(struct aac_srb) + 
2519                 srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
2520                 struct aac_sg_entry *sgp = srbcmd->sg_map.SgEntry;
2521                 srb_sg_bytecount = sgp->SgByteCount;
2522                 srb_sg_address = (u_int64_t)sgp->SgAddress;
2523         } else if (fibsize == (sizeof(struct aac_srb) + 
2524                 srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) {
2525 #ifdef __LP64__
2526                 struct aac_sg_entry64 *sgp = 
2527                         (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry;
2528                 srb_sg_bytecount = sgp->SgByteCount;
2529                 srb_sg_address = sgp->SgAddress;
2530                 if (srb_sg_address > 0xffffffffull && 
2531                         !(sc->flags & AAC_FLAGS_SG_64BIT))
2532 #endif  
2533                 {
2534                         error = EINVAL;
2535                         goto out;
2536                 }
2537         } else {
2538                 error = EINVAL;
2539                 goto out;
2540         }
2541         user_reply = (char *)arg + fibsize;
2542         srbcmd->data_len = srb_sg_bytecount;
2543         if (srbcmd->sg_map.SgCount == 1) 
2544                 transfer_data = 1;
2545
2546         if (transfer_data) {
2547                 /*
2548                  * Create DMA tag for the passthr. data buffer and allocate it.
2549                  */
2550                 if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
2551                         1, 0,                   /* algnmnt, boundary */
2552                         (sc->flags & AAC_FLAGS_SG_64BIT) ?
2553                         BUS_SPACE_MAXADDR_32BIT :
2554                         0x7fffffff,             /* lowaddr */
2555                         BUS_SPACE_MAXADDR,      /* highaddr */
2556                         NULL, NULL,             /* filter, filterarg */
2557                         srb_sg_bytecount,       /* size */
2558                         sc->aac_sg_tablesize,   /* nsegments */
2559                         srb_sg_bytecount,       /* maxsegsize */
2560                         0,                      /* flags */
2561                         NULL, NULL,             /* No locking needed */
2562                         &cm->cm_passthr_dmat)) {
2563                         error = ENOMEM;
2564                         goto out;
2565                 }
2566                 if (bus_dmamem_alloc(cm->cm_passthr_dmat, (void **)&cm->cm_data,
2567                         BUS_DMA_NOWAIT, &cm->cm_datamap)) {
2568                         error = ENOMEM;
2569                         goto out;
2570                 }
2571                 /* fill some cm variables */
2572                 cm->cm_datalen = srb_sg_bytecount;
2573                 if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) 
2574                         cm->cm_flags |= AAC_CMD_DATAIN;
2575                 if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT)
2576                         cm->cm_flags |= AAC_CMD_DATAOUT;
2577
2578                 if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) {
2579                         if ((error = copyin((void *)(uintptr_t)srb_sg_address,
2580                                 cm->cm_data, cm->cm_datalen)) != 0)
2581                                 goto out;
2582                         /* sync required for bus_dmamem_alloc() alloc. mem.? */
2583                         bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap,
2584                                 BUS_DMASYNC_PREWRITE);
2585                 }
2586         }
2587
2588         /* build the FIB */
2589         fib->Header.Size = sizeof(struct aac_fib_header) + 
2590                 sizeof(struct aac_srb);
2591         fib->Header.XferState =
2592                 AAC_FIBSTATE_HOSTOWNED   |
2593                 AAC_FIBSTATE_INITIALISED |
2594                 AAC_FIBSTATE_EMPTY       |
2595                 AAC_FIBSTATE_FROMHOST    |
2596                 AAC_FIBSTATE_REXPECTED   |
2597                 AAC_FIBSTATE_NORM        |
2598                 AAC_FIBSTATE_ASYNC;
2599
2600         fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ? 
2601                 ScsiPortCommandU64 : ScsiPortCommand;
2602         cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map;
2603
2604         /* send command */
2605         if (transfer_data) {
2606                 bus_dmamap_load(cm->cm_passthr_dmat,
2607                         cm->cm_datamap, cm->cm_data,
2608                         cm->cm_datalen,
2609                         aacraid_map_command_sg, cm, 0);
2610         } else {
2611                 aacraid_map_command_sg(cm, NULL, 0, 0);
2612         }
2613
2614         /* wait for completion */
2615         mtx_lock(&sc->aac_io_lock);
2616         while (!(cm->cm_flags & AAC_CMD_COMPLETED))
2617                 msleep(cm, &sc->aac_io_lock, 0, "aacraid_ctlsrw2", 0);
2618         mtx_unlock(&sc->aac_io_lock);
2619
2620         /* copy data */
2621         if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)) {
2622                 if ((error = copyout(cm->cm_data,
2623                         (void *)(uintptr_t)srb_sg_address,
2624                         cm->cm_datalen)) != 0)
2625                         goto out;
2626                 /* sync required for bus_dmamem_alloc() allocated mem.? */
2627                 bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap,
2628                                 BUS_DMASYNC_POSTREAD);
2629         }
2630
2631         /* status */
2632         error = copyout(fib->data, user_reply, sizeof(struct aac_srb_response));
2633
2634 out:
2635         if (cm && cm->cm_data) {
2636                 if (transfer_data)
2637                         bus_dmamap_unload(cm->cm_passthr_dmat, cm->cm_datamap);
2638                 bus_dmamem_free(cm->cm_passthr_dmat, cm->cm_data, cm->cm_datamap);
2639                 cm->cm_datamap = orig_map;
2640         }
2641         if (cm && cm->cm_passthr_dmat) 
2642                 bus_dma_tag_destroy(cm->cm_passthr_dmat);
2643         if (cm) { 
2644                 mtx_lock(&sc->aac_io_lock);
2645                 aacraid_release_command(cm);
2646                 mtx_unlock(&sc->aac_io_lock);
2647         }
2648         return(error);
2649 }
2650
2651 /*
2652  * Request an AIF from the controller (new comm. type1)
2653  */
2654 static void
2655 aac_request_aif(struct aac_softc *sc)
2656 {
2657         struct aac_command *cm;
2658         struct aac_fib *fib;
2659
2660         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2661
2662         if (aacraid_alloc_command(sc, &cm)) {
2663                 sc->aif_pending = 1;
2664                 return;
2665         }
2666         sc->aif_pending = 0;
2667     
2668         /* build the FIB */
2669         fib = cm->cm_fib;
2670         fib->Header.Size = sizeof(struct aac_fib);
2671         fib->Header.XferState =
2672         AAC_FIBSTATE_HOSTOWNED   |
2673         AAC_FIBSTATE_INITIALISED |
2674         AAC_FIBSTATE_EMPTY       |
2675         AAC_FIBSTATE_FROMHOST    |
2676         AAC_FIBSTATE_REXPECTED   |
2677         AAC_FIBSTATE_NORM        |
2678         AAC_FIBSTATE_ASYNC;
2679         /* set AIF marker */
2680         fib->Header.Handle = 0x00800000;
2681         fib->Header.Command = AifRequest;
2682         ((struct aac_aif_command *)fib->data)->command = AifReqEvent;
2683
2684         aacraid_map_command_sg(cm, NULL, 0, 0);
2685 }
2686
2687
2688 #if __FreeBSD_version >= 702000
2689 /*
2690  * cdevpriv interface private destructor.
2691  */
2692 static void
2693 aac_cdevpriv_dtor(void *arg)
2694 {
2695         struct aac_softc *sc;
2696
2697         sc = arg;
2698         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2699         mtx_lock(&Giant);
2700         device_unbusy(sc->aac_dev);
2701         mtx_unlock(&Giant);
2702 }
2703 #else
2704 static int
2705 aac_close(struct cdev *dev, int flags, int fmt, struct thread *td)
2706 {
2707         struct aac_softc *sc;
2708
2709         sc = dev->si_drv1;
2710         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2711         return 0;
2712 }
2713 #endif
2714
2715 /*
2716  * Handle an AIF sent to us by the controller; queue it for later reference.
2717  * If the queue fills up, then drop the older entries.
2718  */
2719 static void
2720 aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
2721 {
2722         struct aac_aif_command *aif;
2723         struct aac_container *co, *co_next;
2724         struct aac_fib_context *ctx;
2725         struct aac_fib *sync_fib;
2726         struct aac_mntinforesp mir;
2727         int next, current, found;
2728         int count = 0, changed = 0, i = 0;
2729         u_int32_t channel, uid;
2730
2731         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2732
2733         aif = (struct aac_aif_command*)&fib->data[0];
2734         aacraid_print_aif(sc, aif);
2735
2736         /* Is it an event that we should care about? */
2737         switch (aif->command) {
2738         case AifCmdEventNotify:
2739                 switch (aif->data.EN.type) {
2740                 case AifEnAddContainer:
2741                 case AifEnDeleteContainer:
2742                         /*
2743                          * A container was added or deleted, but the message
2744                          * doesn't tell us anything else!  Re-enumerate the
2745                          * containers and sort things out.
2746                          */
2747                         aac_alloc_sync_fib(sc, &sync_fib);
2748                         do {
2749                                 /*
2750                                  * Ask the controller for its containers one at
2751                                  * a time.
2752                                  * XXX What if the controller's list changes
2753                                  * midway through this enumaration?
2754                                  * XXX This should be done async.
2755                                  */
2756                                 if (aac_get_container_info(sc, sync_fib, i, 
2757                                         &mir, &uid) != 0)
2758                                         continue;
2759                                 if (i == 0)
2760                                         count = mir.MntRespCount;
2761                                 /*
2762                                  * Check the container against our list.
2763                                  * co->co_found was already set to 0 in a
2764                                  * previous run.
2765                                  */
2766                                 if ((mir.Status == ST_OK) &&
2767                                     (mir.MntTable[0].VolType != CT_NONE)) {
2768                                         found = 0;
2769                                         TAILQ_FOREACH(co,
2770                                                       &sc->aac_container_tqh,
2771                                                       co_link) {
2772                                                 if (co->co_mntobj.ObjectId ==
2773                                                     mir.MntTable[0].ObjectId) {
2774                                                         co->co_found = 1;
2775                                                         found = 1;
2776                                                         break;
2777                                                 }
2778                                         }
2779                                         /*
2780                                          * If the container matched, continue
2781                                          * in the list.
2782                                          */
2783                                         if (found) {
2784                                                 i++;
2785                                                 continue;
2786                                         }
2787
2788                                         /*
2789                                          * This is a new container.  Do all the
2790                                          * appropriate things to set it up.
2791                                          */
2792                                         aac_add_container(sc, &mir, 1, uid);
2793                                         changed = 1;
2794                                 }
2795                                 i++;
2796                         } while ((i < count) && (i < AAC_MAX_CONTAINERS));
2797                         aac_release_sync_fib(sc);
2798
2799                         /*
2800                          * Go through our list of containers and see which ones
2801                          * were not marked 'found'.  Since the controller didn't
2802                          * list them they must have been deleted.  Do the
2803                          * appropriate steps to destroy the device.  Also reset
2804                          * the co->co_found field.
2805                          */
2806                         co = TAILQ_FIRST(&sc->aac_container_tqh);
2807                         while (co != NULL) {
2808                                 if (co->co_found == 0) {
2809                                         co_next = TAILQ_NEXT(co, co_link);
2810                                         TAILQ_REMOVE(&sc->aac_container_tqh, co,
2811                                                      co_link);
2812                                         free(co, M_AACRAIDBUF);
2813                                         changed = 1;
2814                                         co = co_next;
2815                                 } else {
2816                                         co->co_found = 0;
2817                                         co = TAILQ_NEXT(co, co_link);
2818                                 }
2819                         }
2820
2821                         /* Attach the newly created containers */
2822                         if (changed) {
2823                                 if (sc->cam_rescan_cb != NULL) 
2824                                         sc->cam_rescan_cb(sc, 0,
2825                                         AAC_CAM_TARGET_WILDCARD);
2826                         }
2827
2828                         break;
2829
2830                 case AifEnEnclosureManagement:
2831                         switch (aif->data.EN.data.EEE.eventType) {
2832                         case AIF_EM_DRIVE_INSERTION:
2833                         case AIF_EM_DRIVE_REMOVAL:
2834                                 channel = aif->data.EN.data.EEE.unitID;
2835                                 if (sc->cam_rescan_cb != NULL)
2836                                         sc->cam_rescan_cb(sc,
2837                                             ((channel>>24) & 0xF) + 1,
2838                                             (channel & 0xFFFF));
2839                                 break;
2840                         }
2841                         break;
2842
2843                 case AifEnAddJBOD:
2844                 case AifEnDeleteJBOD:
2845                 case AifRawDeviceRemove:
2846                         channel = aif->data.EN.data.ECE.container;
2847                         if (sc->cam_rescan_cb != NULL)
2848                                 sc->cam_rescan_cb(sc, ((channel>>24) & 0xF) + 1,
2849                                     AAC_CAM_TARGET_WILDCARD);
2850                         break;
2851
2852                 default:
2853                         break;
2854                 }
2855
2856         default:
2857                 break;
2858         }
2859
2860         /* Copy the AIF data to the AIF queue for ioctl retrieval */
2861         current = sc->aifq_idx;
2862         next = (current + 1) % AAC_AIFQ_LENGTH;
2863         if (next == 0)
2864                 sc->aifq_filled = 1;
2865         bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib));
2866         /* modify AIF contexts */
2867         if (sc->aifq_filled) {
2868                 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
2869                         if (next == ctx->ctx_idx)
2870                                 ctx->ctx_wrap = 1;
2871                         else if (current == ctx->ctx_idx && ctx->ctx_wrap)
2872                                 ctx->ctx_idx = next;
2873                 }       
2874         }
2875         sc->aifq_idx = next;
2876         /* On the off chance that someone is sleeping for an aif... */
2877         if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
2878                 wakeup(sc->aac_aifq);
2879         /* Wakeup any poll()ers */
2880         selwakeuppri(&sc->rcv_select, PRIBIO);
2881
2882         return;
2883 }
2884
2885 /*
2886  * Return the Revision of the driver to userspace and check to see if the
2887  * userspace app is possibly compatible.  This is extremely bogus since
2888  * our driver doesn't follow Adaptec's versioning system.  Cheat by just
2889  * returning what the card reported.
2890  */
2891 static int
2892 aac_rev_check(struct aac_softc *sc, caddr_t udata)
2893 {
2894         struct aac_rev_check rev_check;
2895         struct aac_rev_check_resp rev_check_resp;
2896         int error = 0;
2897
2898         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2899
2900         /*
2901          * Copyin the revision struct from userspace
2902          */
2903         if ((error = copyin(udata, (caddr_t)&rev_check,
2904                         sizeof(struct aac_rev_check))) != 0) {
2905                 return error;
2906         }
2907
2908         fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "Userland revision= %d\n",
2909               rev_check.callingRevision.buildNumber);
2910
2911         /*
2912          * Doctor up the response struct.
2913          */
2914         rev_check_resp.possiblyCompatible = 1;
2915         rev_check_resp.adapterSWRevision.external.comp.major =
2916             AAC_DRIVER_MAJOR_VERSION;
2917         rev_check_resp.adapterSWRevision.external.comp.minor =
2918             AAC_DRIVER_MINOR_VERSION;
2919         rev_check_resp.adapterSWRevision.external.comp.type =
2920             AAC_DRIVER_TYPE;
2921         rev_check_resp.adapterSWRevision.external.comp.dash =
2922             AAC_DRIVER_BUGFIX_LEVEL;
2923         rev_check_resp.adapterSWRevision.buildNumber =
2924             AAC_DRIVER_BUILD;
2925
2926         return(copyout((caddr_t)&rev_check_resp, udata,
2927                         sizeof(struct aac_rev_check_resp)));
2928 }
2929
2930 /*
2931  * Pass the fib context to the caller
2932  */
2933 static int
2934 aac_open_aif(struct aac_softc *sc, caddr_t arg)
2935 {
2936         struct aac_fib_context *fibctx, *ctx;
2937         int error = 0;
2938
2939         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2940
2941         fibctx = malloc(sizeof(struct aac_fib_context), M_AACRAIDBUF, M_NOWAIT|M_ZERO);
2942         if (fibctx == NULL)
2943                 return (ENOMEM);
2944
2945         mtx_lock(&sc->aac_io_lock);
2946         /* all elements are already 0, add to queue */
2947         if (sc->fibctx == NULL)
2948                 sc->fibctx = fibctx;
2949         else {
2950                 for (ctx = sc->fibctx; ctx->next; ctx = ctx->next)
2951                         ;
2952                 ctx->next = fibctx;
2953                 fibctx->prev = ctx;
2954         }
2955
2956         /* evaluate unique value */
2957         fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
2958         ctx = sc->fibctx;
2959         while (ctx != fibctx) {
2960                 if (ctx->unique == fibctx->unique) {
2961                         fibctx->unique++;
2962                         ctx = sc->fibctx;
2963                 } else {
2964                         ctx = ctx->next;
2965                 }
2966         }
2967
2968         error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t));
2969         mtx_unlock(&sc->aac_io_lock);
2970         if (error)
2971                 aac_close_aif(sc, (caddr_t)ctx);
2972         return error;
2973 }
2974
2975 /*
2976  * Close the caller's fib context
2977  */
2978 static int
2979 aac_close_aif(struct aac_softc *sc, caddr_t arg)
2980 {
2981         struct aac_fib_context *ctx;
2982
2983         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2984
2985         mtx_lock(&sc->aac_io_lock);
2986         for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
2987                 if (ctx->unique == *(uint32_t *)&arg) {
2988                         if (ctx == sc->fibctx)
2989                                 sc->fibctx = NULL;
2990                         else {
2991                                 ctx->prev->next = ctx->next;
2992                                 if (ctx->next)
2993                                         ctx->next->prev = ctx->prev;
2994                         }
2995                         break;
2996                 }
2997         }
2998         if (ctx)
2999                 free(ctx, M_AACRAIDBUF);
3000
3001         mtx_unlock(&sc->aac_io_lock);
3002         return 0;
3003 }
3004
3005 /*
3006  * Pass the caller the next AIF in their queue
3007  */
3008 static int
3009 aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
3010 {
3011         struct get_adapter_fib_ioctl agf;
3012         struct aac_fib_context *ctx;
3013         int error;
3014
3015         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3016
3017         mtx_lock(&sc->aac_io_lock);
3018         if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
3019                 for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3020                         if (agf.AdapterFibContext == ctx->unique)
3021                                 break;
3022                 }
3023                 if (!ctx) {
3024                         mtx_unlock(&sc->aac_io_lock);
3025                         return (EFAULT);
3026                 }
3027
3028                 error = aac_return_aif(sc, ctx, agf.AifFib);
3029                 if (error == EAGAIN && agf.Wait) {
3030                         fwprintf(sc, HBA_FLAGS_DBG_AIF_B, "aac_getnext_aif(): waiting for AIF");
3031                         sc->aac_state |= AAC_STATE_AIF_SLEEPER;
3032                         while (error == EAGAIN) {
3033                                 mtx_unlock(&sc->aac_io_lock);
3034                                 error = tsleep(sc->aac_aifq, PRIBIO |
3035                                                PCATCH, "aacaif", 0);
3036                                 mtx_lock(&sc->aac_io_lock);
3037                                 if (error == 0)
3038                                         error = aac_return_aif(sc, ctx, agf.AifFib);
3039                         }
3040                         sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
3041                 }
3042         }
3043         mtx_unlock(&sc->aac_io_lock);
3044         return(error);
3045 }
3046
3047 /*
3048  * Hand the next AIF off the top of the queue out to userspace.
3049  */
3050 static int
3051 aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
3052 {
3053         int current, error;
3054
3055         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3056
3057         current = ctx->ctx_idx;
3058         if (current == sc->aifq_idx && !ctx->ctx_wrap) {
3059                 /* empty */
3060                 return (EAGAIN);
3061         }
3062         error =
3063                 copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
3064         if (error)
3065                 device_printf(sc->aac_dev,
3066                     "aac_return_aif: copyout returned %d\n", error);
3067         else {
3068                 ctx->ctx_wrap = 0;
3069                 ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
3070         }
3071         return(error);
3072 }
3073
3074 static int
3075 aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
3076 {
3077         struct aac_pci_info {
3078                 u_int32_t bus;
3079                 u_int32_t slot;
3080         } pciinf;
3081         int error;
3082
3083         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3084
3085         pciinf.bus = pci_get_bus(sc->aac_dev);
3086         pciinf.slot = pci_get_slot(sc->aac_dev);
3087
3088         error = copyout((caddr_t)&pciinf, uptr,
3089                         sizeof(struct aac_pci_info));
3090
3091         return (error);
3092 }
3093
3094 static int
3095 aac_supported_features(struct aac_softc *sc, caddr_t uptr)
3096 {
3097         struct aac_features f;
3098         int error;
3099
3100         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3101
3102         if ((error = copyin(uptr, &f, sizeof (f))) != 0)
3103                 return (error);
3104
3105         /*
3106          * When the management driver receives FSACTL_GET_FEATURES ioctl with
3107          * ALL zero in the featuresState, the driver will return the current
3108          * state of all the supported features, the data field will not be
3109          * valid.
3110          * When the management driver receives FSACTL_GET_FEATURES ioctl with
3111          * a specific bit set in the featuresState, the driver will return the
3112          * current state of this specific feature and whatever data that are
3113          * associated with the feature in the data field or perform whatever
3114          * action needed indicates in the data field.
3115          */
3116          if (f.feat.fValue == 0) {
3117                 f.feat.fBits.largeLBA =
3118                     (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3119                 f.feat.fBits.JBODSupport = 1;
3120                 /* TODO: In the future, add other features state here as well */
3121         } else {
3122                 if (f.feat.fBits.largeLBA)
3123                         f.feat.fBits.largeLBA =
3124                             (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3125                 /* TODO: Add other features state and data in the future */
3126         }
3127
3128         error = copyout(&f, uptr, sizeof (f));
3129         return (error);
3130 }
3131
3132 /*
3133  * Give the userland some information about the container.  The AAC arch
3134  * expects the driver to be a SCSI passthrough type driver, so it expects
3135  * the containers to have b:t:l numbers.  Fake it.
3136  */
3137 static int
3138 aac_query_disk(struct aac_softc *sc, caddr_t uptr)
3139 {
3140         struct aac_query_disk query_disk;
3141         struct aac_container *co;
3142         int error, id;
3143
3144         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3145
3146         mtx_lock(&sc->aac_io_lock);
3147         error = copyin(uptr, (caddr_t)&query_disk,
3148                        sizeof(struct aac_query_disk));
3149         if (error) {
3150                 mtx_unlock(&sc->aac_io_lock);
3151                 return (error);
3152         }
3153
3154         id = query_disk.ContainerNumber;
3155         if (id == -1) {
3156                 mtx_unlock(&sc->aac_io_lock);
3157                 return (EINVAL);
3158         }
3159
3160         TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
3161                 if (co->co_mntobj.ObjectId == id)
3162                         break;
3163                 }
3164
3165         if (co == NULL) {
3166                         query_disk.Valid = 0;
3167                         query_disk.Locked = 0;
3168                         query_disk.Deleted = 1;         /* XXX is this right? */
3169         } else {
3170                 query_disk.Valid = 1;
3171                 query_disk.Locked = 1;
3172                 query_disk.Deleted = 0;
3173                 query_disk.Bus = device_get_unit(sc->aac_dev);
3174                 query_disk.Target = 0;
3175                 query_disk.Lun = 0;
3176                 query_disk.UnMapped = 0;
3177         }
3178
3179         error = copyout((caddr_t)&query_disk, uptr,
3180                         sizeof(struct aac_query_disk));
3181
3182         mtx_unlock(&sc->aac_io_lock);
3183         return (error);
3184 }
3185
3186 static void
3187 aac_container_bus(struct aac_softc *sc)
3188 {
3189         struct aac_sim *sim;
3190         device_t child;
3191
3192         sim =(struct aac_sim *)malloc(sizeof(struct aac_sim),
3193                 M_AACRAIDBUF, M_NOWAIT | M_ZERO);
3194         if (sim == NULL) {
3195                 device_printf(sc->aac_dev,
3196                 "No memory to add container bus\n");
3197                 panic("Out of memory?!");
3198         };
3199         child = device_add_child(sc->aac_dev, "aacraidp", -1);
3200         if (child == NULL) {
3201                 device_printf(sc->aac_dev,
3202                 "device_add_child failed for container bus\n");
3203                 free(sim, M_AACRAIDBUF);
3204                 panic("Out of memory?!");
3205         }
3206
3207         sim->TargetsPerBus = AAC_MAX_CONTAINERS;
3208         sim->BusNumber = 0;
3209         sim->BusType = CONTAINER_BUS;
3210         sim->InitiatorBusId = -1;
3211         sim->aac_sc = sc;
3212         sim->sim_dev = child;
3213         sim->aac_cam = NULL;
3214
3215         device_set_ivars(child, sim);
3216         device_set_desc(child, "Container Bus");
3217         TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, sim, sim_link);
3218         /*
3219         device_set_desc(child, aac_describe_code(aac_container_types,
3220                         mir->MntTable[0].VolType));
3221         */
3222         bus_generic_attach(sc->aac_dev);
3223 }
3224
3225 static void
3226 aac_get_bus_info(struct aac_softc *sc)
3227 {
3228         struct aac_fib *fib;
3229         struct aac_ctcfg *c_cmd;
3230         struct aac_ctcfg_resp *c_resp;
3231         struct aac_vmioctl *vmi;
3232         struct aac_vmi_businf_resp *vmi_resp;
3233         struct aac_getbusinf businfo;
3234         struct aac_sim *caminf;
3235         device_t child;
3236         int i, error;
3237
3238         mtx_lock(&sc->aac_io_lock);
3239         aac_alloc_sync_fib(sc, &fib);
3240         c_cmd = (struct aac_ctcfg *)&fib->data[0];
3241         bzero(c_cmd, sizeof(struct aac_ctcfg));
3242
3243         c_cmd->Command = VM_ContainerConfig;
3244         c_cmd->cmd = CT_GET_SCSI_METHOD;
3245         c_cmd->param = 0;
3246
3247         error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3248             sizeof(struct aac_ctcfg));
3249         if (error) {
3250                 device_printf(sc->aac_dev, "Error %d sending "
3251                     "VM_ContainerConfig command\n", error);
3252                 aac_release_sync_fib(sc);
3253                 mtx_unlock(&sc->aac_io_lock);
3254                 return;
3255         }
3256
3257         c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
3258         if (c_resp->Status != ST_OK) {
3259                 device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
3260                     c_resp->Status);
3261                 aac_release_sync_fib(sc);
3262                 mtx_unlock(&sc->aac_io_lock);
3263                 return;
3264         }
3265
3266         sc->scsi_method_id = c_resp->param;
3267
3268         vmi = (struct aac_vmioctl *)&fib->data[0];
3269         bzero(vmi, sizeof(struct aac_vmioctl));
3270
3271         vmi->Command = VM_Ioctl;
3272         vmi->ObjType = FT_DRIVE;
3273         vmi->MethId = sc->scsi_method_id;
3274         vmi->ObjId = 0;
3275         vmi->IoctlCmd = GetBusInfo;
3276
3277         error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3278             sizeof(struct aac_vmi_businf_resp));
3279         if (error) {
3280                 device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
3281                     error);
3282                 aac_release_sync_fib(sc);
3283                 mtx_unlock(&sc->aac_io_lock);
3284                 return;
3285         }
3286
3287         vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
3288         if (vmi_resp->Status != ST_OK) {
3289                 device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
3290                     vmi_resp->Status);
3291                 aac_release_sync_fib(sc);
3292                 mtx_unlock(&sc->aac_io_lock);
3293                 return;
3294         }
3295
3296         bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
3297         aac_release_sync_fib(sc);
3298         mtx_unlock(&sc->aac_io_lock);
3299
3300         for (i = 0; i < businfo.BusCount; i++) {
3301                 if (businfo.BusValid[i] != AAC_BUS_VALID)
3302                         continue;
3303
3304                 caminf = (struct aac_sim *)malloc( sizeof(struct aac_sim),
3305                     M_AACRAIDBUF, M_NOWAIT | M_ZERO);
3306                 if (caminf == NULL) {
3307                         device_printf(sc->aac_dev,
3308                             "No memory to add passthrough bus %d\n", i);
3309                         break;
3310                 };
3311
3312                 child = device_add_child(sc->aac_dev, "aacraidp", -1);
3313                 if (child == NULL) {
3314                         device_printf(sc->aac_dev,
3315                             "device_add_child failed for passthrough bus %d\n",
3316                             i);
3317                         free(caminf, M_AACRAIDBUF);
3318                         break;
3319                 }
3320
3321                 caminf->TargetsPerBus = businfo.TargetsPerBus;
3322                 caminf->BusNumber = i+1;
3323                 caminf->BusType = PASSTHROUGH_BUS;
3324                 caminf->InitiatorBusId = businfo.InitiatorBusId[i];
3325                 caminf->aac_sc = sc;
3326                 caminf->sim_dev = child;
3327                 caminf->aac_cam = NULL;
3328
3329                 device_set_ivars(child, caminf);
3330                 device_set_desc(child, "SCSI Passthrough Bus");
3331                 TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
3332         }
3333 }
3334
3335 /*
3336  * Check to see if the kernel is up and running. If we are in a
3337  * BlinkLED state, return the BlinkLED code.
3338  */
3339 static u_int32_t
3340 aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled)
3341 {
3342         u_int32_t ret;
3343
3344         ret = AAC_GET_FWSTATUS(sc);
3345
3346         if (ret & AAC_UP_AND_RUNNING)
3347                 ret = 0;
3348         else if (ret & AAC_KERNEL_PANIC && bled)
3349                 *bled = (ret >> 16) & 0xff;
3350
3351         return (ret);
3352 }
3353
3354 /*
3355  * Once do an IOP reset, basically have to re-initialize the card as
3356  * if coming up from a cold boot, and the driver is responsible for
3357  * any IO that was outstanding to the adapter at the time of the IOP
3358  * RESET. And prepare the driver for IOP RESET by making the init code
3359  * modular with the ability to call it from multiple places.
3360  */
3361 static int
3362 aac_reset_adapter(struct aac_softc *sc)
3363 {
3364         struct aac_command *cm;
3365         struct aac_fib *fib;
3366         struct aac_pause_command *pc;
3367         u_int32_t status, old_flags, reset_mask, waitCount;
3368
3369         fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3370
3371         if (sc->aac_state & AAC_STATE_RESET) {
3372                 device_printf(sc->aac_dev, "aac_reset_adapter() already in progress\n");
3373                 return (EINVAL);
3374         }
3375         sc->aac_state |= AAC_STATE_RESET;
3376
3377         /* disable interrupt */
3378         AAC_MASK_INTERRUPTS(sc);
3379
3380         /*
3381          * Abort all pending commands:
3382          * a) on the controller
3383          */
3384         while ((cm = aac_dequeue_busy(sc)) != NULL) {
3385                 cm->cm_flags |= AAC_CMD_RESET;
3386
3387                 /* is there a completion handler? */
3388                 if (cm->cm_complete != NULL) {
3389                         cm->cm_complete(cm);
3390                 } else {
3391                         /* assume that someone is sleeping on this
3392                          * command
3393                          */
3394                         wakeup(cm);
3395                 }
3396         }
3397
3398         /* b) in the waiting queues */
3399         while ((cm = aac_dequeue_ready(sc)) != NULL) {
3400                 cm->cm_flags |= AAC_CMD_RESET;
3401
3402                 /* is there a completion handler? */
3403                 if (cm->cm_complete != NULL) {
3404                         cm->cm_complete(cm);
3405                 } else {
3406                         /* assume that someone is sleeping on this
3407                          * command
3408                          */
3409                         wakeup(cm);
3410                 }
3411         }
3412
3413         /* flush drives */
3414         if (aac_check_adapter_health(sc, NULL) == 0) {
3415                 mtx_unlock(&sc->aac_io_lock);
3416                 (void) aacraid_shutdown(sc->aac_dev);
3417                 mtx_lock(&sc->aac_io_lock);
3418         }
3419
3420         /* execute IOP reset */
3421         if (sc->aac_support_opt2 & AAC_SUPPORTED_MU_RESET) {
3422                 AAC_MEM0_SETREG4(sc, AAC_IRCSR, AAC_IRCSR_CORES_RST);
3423
3424                 /* We need to wait for 5 seconds before accessing the MU again
3425                  * 10000 * 100us = 1000,000us = 1000ms = 1s  
3426                  */
3427                 waitCount = 5 * 10000;
3428                 while (waitCount) {
3429                         DELAY(100);                     /* delay 100 microseconds */
3430                         waitCount--;
3431                 }
3432         } else if ((aacraid_sync_command(sc, 
3433                 AAC_IOP_RESET_ALWAYS, 0, 0, 0, 0, &status, &reset_mask)) != 0) {
3434                 /* call IOP_RESET for older firmware */
3435                 if ((aacraid_sync_command(sc,
3436                         AAC_IOP_RESET, 0, 0, 0, 0, &status, NULL)) != 0) {
3437
3438                         if (status == AAC_SRB_STS_INVALID_REQUEST)
3439                                 device_printf(sc->aac_dev, "IOP_RESET not supported\n");
3440                         else
3441                                 /* probably timeout */
3442                                 device_printf(sc->aac_dev, "IOP_RESET failed\n");
3443
3444                         /* unwind aac_shutdown() */
3445                         aac_alloc_sync_fib(sc, &fib);
3446                         pc = (struct aac_pause_command *)&fib->data[0];
3447                         pc->Command = VM_ContainerConfig;
3448                         pc->Type = CT_PAUSE_IO;
3449                         pc->Timeout = 1;
3450                         pc->Min = 1;
3451                         pc->NoRescan = 1;
3452
3453                         (void) aac_sync_fib(sc, ContainerCommand, 0, fib,
3454                                 sizeof (struct aac_pause_command));
3455                         aac_release_sync_fib(sc);
3456
3457                         goto finish;
3458                 }
3459         } else if (sc->aac_support_opt2 & AAC_SUPPORTED_DOORBELL_RESET) {
3460                 AAC_MEM0_SETREG4(sc, AAC_SRC_IDBR, reset_mask);
3461                 /* We need to wait for 5 seconds before accessing the doorbell again
3462                  * 10000 * 100us = 1000,000us = 1000ms = 1s  
3463                  */
3464                 waitCount = 5 * 10000;
3465                 while (waitCount) {
3466                         DELAY(100);                     /* delay 100 microseconds */
3467                         waitCount--;
3468                 }
3469         }
3470
3471         /*
3472          * Re-read and renegotiate the FIB parameters, as one of the actions
3473          * that can result from an IOP reset is the running of a new firmware
3474          * image.
3475          */
3476         old_flags = sc->flags;
3477         /*
3478          * Initialize the adapter.
3479          */
3480         if (aac_check_firmware(sc) != 0)
3481                 goto finish;
3482         if (!(sc->flags & AAC_FLAGS_SYNC_MODE)) {
3483                 if (aac_init(sc) != 0)
3484                         goto finish;
3485         }
3486
3487 finish:
3488         sc->aac_state &= ~AAC_STATE_RESET;
3489         AAC_UNMASK_INTERRUPTS(sc);
3490         aacraid_startio(sc);
3491         return (0);
3492 }