xref: /dragonfly/sys/dev/raid/aac/aac.c (revision 030b0c8c4cf27c560ccec70410c8e21934ae677d)
1 /*-
2  * Copyright (c) 2000 Michael Smith
3  * Copyright (c) 2001 Scott Long
4  * Copyright (c) 2000 BSDi
5  * Copyright (c) 2001 Adaptec, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD: head/sys/dev/aac/aac.c 260044 2013-12-29 17:37:32Z marius $
30  */
31 
32 /*
33  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34  */
35 #define AAC_DRIVERNAME                            "aac"
36 
37 #include "opt_aac.h"
38 
39 /* #include <stddef.h> */
40 #include <sys/param.h>
41 #include <sys/systm.h>
42 #include <sys/malloc.h>
43 #include <sys/kernel.h>
44 #include <sys/kthread.h>
45 #include <sys/poll.h>
46 
47 #include <sys/bus.h>
48 #include <sys/conf.h>
49 #include <sys/signalvar.h>
50 #include <sys/time.h>
51 #include <sys/eventhandler.h>
52 #include <sys/rman.h>
53 
54 #include <sys/bus_dma.h>
55 #include <sys/device.h>
56 #include <sys/mplock2.h>
57 
58 #include <bus/pci/pcireg.h>
59 #include <bus/pci/pcivar.h>
60 
61 #include <dev/raid/aac/aacreg.h>
62 #include <dev/raid/aac/aac_ioctl.h>
63 #include <dev/raid/aac/aacvar.h>
64 #include <dev/raid/aac/aac_tables.h>
65 
66 static void         aac_startup(void *arg);
67 static void         aac_add_container(struct aac_softc *sc,
68                                           struct aac_mntinforesp *mir, int f);
69 static void         aac_get_bus_info(struct aac_softc *sc);
70 static void         aac_daemon(void *arg);
71 
72 /* Command Processing */
73 static void         aac_timeout(struct aac_softc *sc);
74 static void         aac_complete(void *context, int pending);
75 static int          aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
76 static void         aac_bio_complete(struct aac_command *cm);
77 static int          aac_wait_command(struct aac_command *cm);
78 static void         aac_command_thread(void *arg);
79 
80 /* Command Buffer Management */
81 static void         aac_map_command_sg(void *arg, bus_dma_segment_t *segs,
82                                            int nseg, int error);
83 static void         aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
84                                                int nseg, int error);
85 static int          aac_alloc_commands(struct aac_softc *sc);
86 static void         aac_free_commands(struct aac_softc *sc);
87 static void         aac_unmap_command(struct aac_command *cm);
88 
89 /* Hardware Interface */
90 static int          aac_alloc(struct aac_softc *sc);
91 static void         aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
92                                      int error);
93 static int          aac_check_firmware(struct aac_softc *sc);
94 static int          aac_init(struct aac_softc *sc);
95 static int          aac_sync_command(struct aac_softc *sc, u_int32_t command,
96                                          u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
97                                          u_int32_t arg3, u_int32_t *sp);
98 static int          aac_setup_intr(struct aac_softc *sc);
99 static int          aac_enqueue_fib(struct aac_softc *sc, int queue,
100                                         struct aac_command *cm);
101 static int          aac_dequeue_fib(struct aac_softc *sc, int queue,
102                                         u_int32_t *fib_size, struct aac_fib **fib_addr);
103 static int          aac_enqueue_response(struct aac_softc *sc, int queue,
104                                              struct aac_fib *fib);
105 
106 /* StrongARM interface */
107 static int          aac_sa_get_fwstatus(struct aac_softc *sc);
108 static void         aac_sa_qnotify(struct aac_softc *sc, int qbit);
109 static int          aac_sa_get_istatus(struct aac_softc *sc);
110 static void         aac_sa_clear_istatus(struct aac_softc *sc, int mask);
111 static void         aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
112                                            u_int32_t arg0, u_int32_t arg1,
113                                            u_int32_t arg2, u_int32_t arg3);
114 static int          aac_sa_get_mailbox(struct aac_softc *sc, int mb);
115 static void         aac_sa_set_interrupts(struct aac_softc *sc, int enable);
116 
117 const struct aac_interface aac_sa_interface = {
118           aac_sa_get_fwstatus,
119           aac_sa_qnotify,
120           aac_sa_get_istatus,
121           aac_sa_clear_istatus,
122           aac_sa_set_mailbox,
123           aac_sa_get_mailbox,
124           aac_sa_set_interrupts,
125           NULL, NULL, NULL
126 };
127 
128 /* i960Rx interface */
129 static int          aac_rx_get_fwstatus(struct aac_softc *sc);
130 static void         aac_rx_qnotify(struct aac_softc *sc, int qbit);
131 static int          aac_rx_get_istatus(struct aac_softc *sc);
132 static void         aac_rx_clear_istatus(struct aac_softc *sc, int mask);
133 static void         aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
134                                            u_int32_t arg0, u_int32_t arg1,
135                                            u_int32_t arg2, u_int32_t arg3);
136 static int          aac_rx_get_mailbox(struct aac_softc *sc, int mb);
137 static void         aac_rx_set_interrupts(struct aac_softc *sc, int enable);
138 static int aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm);
139 static int aac_rx_get_outb_queue(struct aac_softc *sc);
140 static void aac_rx_set_outb_queue(struct aac_softc *sc, int index);
141 
142 const struct aac_interface aac_rx_interface = {
143           aac_rx_get_fwstatus,
144           aac_rx_qnotify,
145           aac_rx_get_istatus,
146           aac_rx_clear_istatus,
147           aac_rx_set_mailbox,
148           aac_rx_get_mailbox,
149           aac_rx_set_interrupts,
150           aac_rx_send_command,
151           aac_rx_get_outb_queue,
152           aac_rx_set_outb_queue
153 };
154 
155 /* Rocket/MIPS interface */
156 static int          aac_rkt_get_fwstatus(struct aac_softc *sc);
157 static void         aac_rkt_qnotify(struct aac_softc *sc, int qbit);
158 static int          aac_rkt_get_istatus(struct aac_softc *sc);
159 static void         aac_rkt_clear_istatus(struct aac_softc *sc, int mask);
160 static void         aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command,
161                                             u_int32_t arg0, u_int32_t arg1,
162                                             u_int32_t arg2, u_int32_t arg3);
163 static int          aac_rkt_get_mailbox(struct aac_softc *sc, int mb);
164 static void         aac_rkt_set_interrupts(struct aac_softc *sc, int enable);
165 static int aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm);
166 static int aac_rkt_get_outb_queue(struct aac_softc *sc);
167 static void aac_rkt_set_outb_queue(struct aac_softc *sc, int index);
168 
169 const struct aac_interface aac_rkt_interface = {
170           aac_rkt_get_fwstatus,
171           aac_rkt_qnotify,
172           aac_rkt_get_istatus,
173           aac_rkt_clear_istatus,
174           aac_rkt_set_mailbox,
175           aac_rkt_get_mailbox,
176           aac_rkt_set_interrupts,
177           aac_rkt_send_command,
178           aac_rkt_get_outb_queue,
179           aac_rkt_set_outb_queue
180 };
181 
182 /* Debugging and Diagnostics */
183 static void                   aac_describe_controller(struct aac_softc *sc);
184 static const char   *aac_describe_code(const struct aac_code_lookup *table,
185                                            u_int32_t code);
186 
187 /* Management Interface */
188 static d_open_t               aac_open;
189 static d_close_t    aac_close;
190 static d_ioctl_t    aac_ioctl;
191 static d_kqfilter_t aac_kqfilter;
192 static void                   aac_filter_detach(struct knote *kn);
193 static int                    aac_filter_read(struct knote *kn, long hint);
194 static int                    aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
195 static int                    aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
196 static void                   aac_handle_aif(struct aac_softc *sc,
197                                                      struct aac_fib *fib);
198 static int                    aac_rev_check(struct aac_softc *sc, caddr_t udata);
199 static int                    aac_open_aif(struct aac_softc *sc, caddr_t arg);
200 static int                    aac_close_aif(struct aac_softc *sc, caddr_t arg);
201 static int                    aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
202 static int                    aac_return_aif(struct aac_softc *sc,
203                                                   struct aac_fib_context *ctx, caddr_t uptr);
204 static int                    aac_query_disk(struct aac_softc *sc, caddr_t uptr);
205 static int                    aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
206 static int                    aac_supported_features(struct aac_softc *sc, caddr_t uptr);
207 static void                   aac_ioctl_event(struct aac_softc *sc,
208                                                   struct aac_event *event, void *arg);
209 static struct aac_mntinforesp *
210           aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
211 
212 static struct dev_ops aac_ops = {
213           { "aac", 0, 0 },
214           .d_open = aac_open,
215           .d_close =          aac_close,
216           .d_ioctl =          aac_ioctl,
217           .d_kqfilter =       aac_kqfilter
218 };
219 
220 static MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
221 
222 /* sysctl node */
223 SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
224 
225 /*
226  * Device Interface
227  */
228 
229 /*
230  * Initialize the controller and softc
231  */
232 int
aac_attach(struct aac_softc * sc)233 aac_attach(struct aac_softc *sc)
234 {
235           int error, unit;
236 
237           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
238 
239           /*
240            * Initialize per-controller queues.
241            */
242           aac_initq_free(sc);
243           aac_initq_ready(sc);
244           aac_initq_busy(sc);
245           aac_initq_bio(sc);
246 
247           /*
248            * Initialize command-completion task.
249            */
250           TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
251 
252           /* mark controller as suspended until we get ourselves organised */
253           sc->aac_state |= AAC_STATE_SUSPEND;
254 
255           /*
256            * Check that the firmware on the card is supported.
257            */
258           if ((error = aac_check_firmware(sc)) != 0)
259                     return(error);
260 
261           /*
262            * Initialize locks
263            */
264           lockinit(&sc->aac_aifq_lock, "AAC AIF lock", 0, LK_CANRECURSE);
265           lockinit(&sc->aac_io_lock, "AAC I/O lock", 0, LK_CANRECURSE);
266           lockinit(&sc->aac_container_lock, "AAC container lock", 0, LK_CANRECURSE);
267           TAILQ_INIT(&sc->aac_container_tqh);
268           TAILQ_INIT(&sc->aac_ev_cmfree);
269 
270           /* Initialize the clock daemon callout. */
271           callout_init_mp(&sc->aac_daemontime);
272 
273           /*
274            * Initialize the adapter.
275            */
276           if ((error = aac_alloc(sc)) != 0)
277                     return(error);
278           if ((error = aac_init(sc)) != 0)
279                     return(error);
280 
281           /*
282            * Allocate and connect our interrupt.
283            */
284           if ((error = aac_setup_intr(sc)) != 0)
285                     return(error);
286 
287           /*
288            * Print a little information about the controller.
289            */
290           aac_describe_controller(sc);
291 
292           /*
293            * Add sysctls.
294            */
295           SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->aac_dev),
296               SYSCTL_CHILDREN(device_get_sysctl_tree(sc->aac_dev)),
297               OID_AUTO, "firmware_build", CTLFLAG_RD,
298               &sc->aac_revision.buildNumber, 0,
299               "firmware build number");
300 
301           /*
302            * Register to probe our containers later.
303            */
304           sc->aac_ich.ich_func = aac_startup;
305           sc->aac_ich.ich_arg = sc;
306           sc->aac_ich.ich_desc = "aac";
307           if (config_intrhook_establish(&sc->aac_ich) != 0) {
308                     device_printf(sc->aac_dev,
309                                     "can't establish configuration hook\n");
310                     return(ENXIO);
311           }
312 
313           /*
314            * Make the control device.
315            */
316           unit = device_get_unit(sc->aac_dev);
317           sc->aac_dev_t = make_dev(&aac_ops, unit, UID_ROOT, GID_OPERATOR,
318                                          0640, "aac%d", unit);
319           (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
320           (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
321           sc->aac_dev_t->si_drv1 = sc;
322 
323           /* Create the AIF thread */
324           if (kthread_create(aac_command_thread, sc,
325                                  &sc->aifthread, "aac%daif", unit))
326                     panic("Could not create AIF thread");
327 
328           /* Register the shutdown method to only be called post-dump */
329           if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
330               sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
331                     device_printf(sc->aac_dev,
332                                     "shutdown event registration failed\n");
333 
334           /* Register with CAM for the non-DASD devices */
335           if ((sc->flags & AAC_FLAGS_ENABLE_CAM) != 0) {
336                     TAILQ_INIT(&sc->aac_sim_tqh);
337                     aac_get_bus_info(sc);
338           }
339 
340           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
341           callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc);
342           lockmgr(&sc->aac_io_lock, LK_RELEASE);
343 
344           return(0);
345 }
346 
347 static void
aac_daemon(void * arg)348 aac_daemon(void *arg)
349 {
350           struct timeval tv;
351           struct aac_softc *sc;
352           struct aac_fib *fib;
353 
354           sc = arg;
355           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
356 
357           if (callout_pending(&sc->aac_daemontime) ||
358               callout_active(&sc->aac_daemontime) == 0) {
359                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
360                     return;
361           }
362           getmicrotime(&tv);
363           aac_alloc_sync_fib(sc, &fib);
364           *(uint32_t *)fib->data = tv.tv_sec;
365           aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t));
366           aac_release_sync_fib(sc);
367           callout_reset(&sc->aac_daemontime, 30 * 60 * hz, aac_daemon, sc);
368           lockmgr(&sc->aac_io_lock, LK_RELEASE);
369 }
370 
371 void
aac_add_event(struct aac_softc * sc,struct aac_event * event)372 aac_add_event(struct aac_softc *sc, struct aac_event *event)
373 {
374 
375           switch (event->ev_type & AAC_EVENT_MASK) {
376           case AAC_EVENT_CMFREE:
377                     TAILQ_INSERT_TAIL(&sc->aac_ev_cmfree, event, ev_links);
378                     break;
379           default:
380                     device_printf(sc->aac_dev, "aac_add event: unknown event %d\n",
381                         event->ev_type);
382                     break;
383           }
384 }
385 
386 /*
387  * Request information of container #cid
388  */
389 static struct aac_mntinforesp *
aac_get_container_info(struct aac_softc * sc,struct aac_fib * fib,int cid)390 aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid)
391 {
392           struct aac_mntinfo *mi;
393 
394           mi = (struct aac_mntinfo *)&fib->data[0];
395           /* use 64-bit LBA if enabled */
396           mi->Command = (sc->flags & AAC_FLAGS_LBA_64BIT) ?
397               VM_NameServe64 : VM_NameServe;
398           mi->MntType = FT_FILESYS;
399           mi->MntCount = cid;
400 
401           if (aac_sync_fib(sc, ContainerCommand, 0, fib,
402                                sizeof(struct aac_mntinfo))) {
403                     device_printf(sc->aac_dev, "Error probing container %d\n", cid);
404                     return (NULL);
405           }
406 
407           return ((struct aac_mntinforesp *)&fib->data[0]);
408 }
409 
410 /*
411  * Probe for containers, create disks.
412  */
413 static void
aac_startup(void * arg)414 aac_startup(void *arg)
415 {
416           struct aac_softc *sc;
417           struct aac_fib *fib;
418           struct aac_mntinforesp *mir;
419           int count = 0, i = 0;
420 
421           sc = (struct aac_softc *)arg;
422           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
423 
424           /* disconnect ourselves from the intrhook chain */
425           config_intrhook_disestablish(&sc->aac_ich);
426 
427           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
428           aac_alloc_sync_fib(sc, &fib);
429 
430           /* loop over possible containers */
431           do {
432                     if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
433                               continue;
434                     if (i == 0)
435                               count = mir->MntRespCount;
436                     aac_add_container(sc, mir, 0);
437                     i++;
438           } while ((i < count) && (i < AAC_MAX_CONTAINERS));
439 
440           aac_release_sync_fib(sc);
441           lockmgr(&sc->aac_io_lock, LK_RELEASE);
442 
443           /* poke the bus to actually attach the child devices */
444           if (bus_generic_attach(sc->aac_dev))
445                     device_printf(sc->aac_dev, "bus_generic_attach failed\n");
446 
447           /* mark the controller up */
448           sc->aac_state &= ~AAC_STATE_SUSPEND;
449 
450           /* enable interrupts now */
451           AAC_UNMASK_INTERRUPTS(sc);
452 }
453 
454 /*
455  * Create a device to represent a new container
456  */
457 static void
aac_add_container(struct aac_softc * sc,struct aac_mntinforesp * mir,int f)458 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
459 {
460           struct aac_container *co;
461           device_t child;
462 
463           /*
464            * Check container volume type for validity.  Note that many of
465            * the possible types may never show up.
466            */
467           if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
468                     co = (struct aac_container *)kmalloc(sizeof *co, M_AACBUF,
469                            M_INTWAIT | M_ZERO);
470                     fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "id %x  name '%.16s'  size %u  type %d",
471                           mir->MntTable[0].ObjectId,
472                           mir->MntTable[0].FileSystemName,
473                           mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
474 
475                     if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
476                               device_printf(sc->aac_dev, "device_add_child failed\n");
477                     else
478                               device_set_ivars(child, co);
479                     device_set_desc(child, aac_describe_code(aac_container_types,
480                                         mir->MntTable[0].VolType));
481                     co->co_disk = child;
482                     co->co_found = f;
483                     bcopy(&mir->MntTable[0], &co->co_mntobj,
484                           sizeof(struct aac_mntobj));
485                     lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
486                     TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
487                     lockmgr(&sc->aac_container_lock, LK_RELEASE);
488           }
489 }
490 
491 /*
492  * Allocate resources associated with (sc)
493  */
494 static int
aac_alloc(struct aac_softc * sc)495 aac_alloc(struct aac_softc *sc)
496 {
497 
498           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
499 
500           /*
501            * Create DMA tag for mapping buffers into controller-addressable space.
502            */
503           if (bus_dma_tag_create(sc->aac_parent_dmat,       /* parent */
504                                      1, 0,                            /* algnmnt, boundary */
505                                      (sc->flags & AAC_FLAGS_SG_64BIT) ?
506                                      BUS_SPACE_MAXADDR :
507                                      BUS_SPACE_MAXADDR_32BIT,         /* lowaddr */
508                                      BUS_SPACE_MAXADDR,     /* highaddr */
509                                      MAXBSIZE,              /* maxsize */
510                                      sc->aac_sg_tablesize,  /* nsegments */
511                                      MAXBSIZE,              /* maxsegsize */
512                                      BUS_DMA_ALLOCNOW,      /* flags */
513                                      &sc->aac_buffer_dmat)) {
514                     device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
515                     return (ENOMEM);
516           }
517 
518           /*
519            * Create DMA tag for mapping FIBs into controller-addressable space..
520            */
521           if (bus_dma_tag_create(sc->aac_parent_dmat,       /* parent */
522                                      1, 0,                            /* algnmnt, boundary */
523                                      (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
524                                      BUS_SPACE_MAXADDR_32BIT :
525                                      0x7fffffff,            /* lowaddr */
526                                      BUS_SPACE_MAXADDR,     /* highaddr */
527                                      sc->aac_max_fibs_alloc *
528                                      sc->aac_max_fib_size,  /* maxsize */
529                                      1,                     /* nsegments */
530                                      sc->aac_max_fibs_alloc *
531                                      sc->aac_max_fib_size,  /* maxsize */
532                                      0,                     /* flags */
533                                      &sc->aac_fib_dmat)) {
534                     device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
535                     return (ENOMEM);
536           }
537 
538           /*
539            * Create DMA tag for the common structure and allocate it.
540            */
541           if (bus_dma_tag_create(sc->aac_parent_dmat,       /* parent */
542                                      1, 0,                            /* algnmnt, boundary */
543                                      (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
544                                      BUS_SPACE_MAXADDR_32BIT :
545                                      0x7fffffff,            /* lowaddr */
546                                      BUS_SPACE_MAXADDR,     /* highaddr */
547                                      8192 + sizeof(struct aac_common), /* maxsize */
548                                      1,                     /* nsegments */
549                                      BUS_SPACE_MAXSIZE_32BIT,         /* maxsegsize */
550                                      0,                     /* flags */
551                                      &sc->aac_common_dmat)) {
552                     device_printf(sc->aac_dev,
553                                     "can't allocate common structure DMA tag\n");
554                     return (ENOMEM);
555           }
556           if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
557                                    BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
558                     device_printf(sc->aac_dev, "can't allocate common structure\n");
559                     return (ENOMEM);
560           }
561 
562           /*
563            * Work around a bug in the 2120 and 2200 that cannot DMA commands
564            * below address 8192 in physical memory.
565            * XXX If the padding is not needed, can it be put to use instead
566            * of ignored?
567            */
568           (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
569                               sc->aac_common, 8192 + sizeof(*sc->aac_common),
570                               aac_common_map, sc, 0);
571 
572           if (sc->aac_common_busaddr < 8192) {
573                     sc->aac_common = (struct aac_common *)
574                         ((uint8_t *)sc->aac_common + 8192);
575                     sc->aac_common_busaddr += 8192;
576           }
577           bzero(sc->aac_common, sizeof(*sc->aac_common));
578 
579           /* Allocate some FIBs and associated command structs */
580           TAILQ_INIT(&sc->aac_fibmap_tqh);
581           sc->aac_commands = kmalloc(sc->aac_max_fibs * sizeof(struct aac_command),
582                                           M_AACBUF, M_WAITOK|M_ZERO);
583           while (sc->total_fibs < sc->aac_max_fibs) {
584                     if (aac_alloc_commands(sc) != 0)
585                               break;
586           }
587           if (sc->total_fibs == 0)
588                     return (ENOMEM);
589 
590           return (0);
591 }
592 
593 /*
594  * Free all of the resources associated with (sc)
595  *
596  * Should not be called if the controller is active.
597  */
598 void
aac_free(struct aac_softc * sc)599 aac_free(struct aac_softc *sc)
600 {
601 
602           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
603 
604           /* remove the control device */
605           if (sc->aac_dev_t != NULL)
606                     destroy_dev(sc->aac_dev_t);
607 
608           /* throw away any FIB buffers, discard the FIB DMA tag */
609           aac_free_commands(sc);
610           if (sc->aac_fib_dmat)
611                     bus_dma_tag_destroy(sc->aac_fib_dmat);
612 
613           kfree(sc->aac_commands, M_AACBUF);
614 
615           /* destroy the common area */
616           if (sc->aac_common) {
617                     bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
618                     bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
619                                         sc->aac_common_dmamap);
620           }
621           if (sc->aac_common_dmat)
622                     bus_dma_tag_destroy(sc->aac_common_dmat);
623 
624           /* disconnect the interrupt handler */
625           if (sc->aac_intr)
626                     bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
627           if (sc->aac_irq != NULL) {
628                     bus_release_resource(sc->aac_dev, SYS_RES_IRQ,
629                         rman_get_rid(sc->aac_irq), sc->aac_irq);
630                     if (sc->aac_irq_type == PCI_INTR_TYPE_MSI)
631                               pci_release_msi(sc->aac_dev);
632           }
633 
634           /* destroy data-transfer DMA tag */
635           if (sc->aac_buffer_dmat)
636                     bus_dma_tag_destroy(sc->aac_buffer_dmat);
637 
638           /* destroy the parent DMA tag */
639           if (sc->aac_parent_dmat)
640                     bus_dma_tag_destroy(sc->aac_parent_dmat);
641 
642           /* release the register window mapping */
643           if (sc->aac_regs_res0 != NULL)
644                     bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
645                         rman_get_rid(sc->aac_regs_res0), sc->aac_regs_res0);
646           if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL)
647                     bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
648                         rman_get_rid(sc->aac_regs_res1), sc->aac_regs_res1);
649           dev_ops_remove_minor(&aac_ops, device_get_unit(sc->aac_dev));
650 }
651 
652 /*
653  * Disconnect from the controller completely, in preparation for unload.
654  */
655 int
aac_detach(device_t dev)656 aac_detach(device_t dev)
657 {
658           struct aac_softc *sc;
659           struct aac_container *co;
660           struct aac_sim      *sim;
661           int error;
662 
663           sc = device_get_softc(dev);
664           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
665 
666           callout_terminate(&sc->aac_daemontime);
667 
668           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
669           while (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
670                     sc->aifflags |= AAC_AIFFLAGS_EXIT;
671                     wakeup(sc->aifthread);
672                     lksleep(sc->aac_dev, &sc->aac_io_lock, 0, "aacdch", 0);
673           }
674           lockmgr(&sc->aac_io_lock, LK_RELEASE);
675           KASSERT((sc->aifflags & AAC_AIFFLAGS_RUNNING) == 0,
676               ("%s: invalid detach state", __func__));
677 
678           /* Remove the child containers */
679           while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
680                     error = device_delete_child(dev, co->co_disk);
681                     if (error)
682                               return (error);
683                     TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
684                     kfree(co, M_AACBUF);
685           }
686 
687           /* Remove the CAM SIMs */
688           while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
689                     TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
690                     error = device_delete_child(dev, sim->sim_dev);
691                     if (error)
692                               return (error);
693                     kfree(sim, M_AACBUF);
694           }
695 
696           if ((error = aac_shutdown(dev)))
697                     return(error);
698 
699           EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
700 
701           aac_free(sc);
702 
703           lockuninit(&sc->aac_aifq_lock);
704           lockuninit(&sc->aac_io_lock);
705           lockuninit(&sc->aac_container_lock);
706 
707           return(0);
708 }
709 
710 /*
711  * Bring the controller down to a dormant state and detach all child devices.
712  *
713  * This function is called before detach or system shutdown.
714  *
715  * Note that we can assume that the bioq on the controller is empty, as we won't
716  * allow shutdown if any device is open.
717  */
718 int
aac_shutdown(device_t dev)719 aac_shutdown(device_t dev)
720 {
721           struct aac_softc *sc;
722           struct aac_fib *fib;
723           struct aac_close_command *cc;
724 
725           sc = device_get_softc(dev);
726           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
727 
728           sc->aac_state |= AAC_STATE_SUSPEND;
729 
730           /*
731            * Send a Container shutdown followed by a HostShutdown FIB to the
732            * controller to convince it that we don't want to talk to it anymore.
733            * We've been closed and all I/O completed already
734            */
735           device_printf(sc->aac_dev, "shutting down controller...");
736 
737           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
738           aac_alloc_sync_fib(sc, &fib);
739           cc = (struct aac_close_command *)&fib->data[0];
740 
741           bzero(cc, sizeof(struct aac_close_command));
742           cc->Command = VM_CloseAll;
743           cc->ContainerId = 0xffffffff;
744           if (aac_sync_fib(sc, ContainerCommand, 0, fib,
745               sizeof(struct aac_close_command)))
746                     kprintf("FAILED.\n");
747           else
748                     kprintf("done\n");
749 #if 0
750           else {
751                     fib->data[0] = 0;
752                     /*
753                      * XXX Issuing this command to the controller makes it shut down
754                      * but also keeps it from coming back up without a reset of the
755                      * PCI bus.  This is not desirable if you are just unloading the
756                      * driver module with the intent to reload it later.
757                      */
758                     if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
759                         fib, 1)) {
760                               kprintf("FAILED.\n");
761                     } else {
762                               kprintf("done.\n");
763                     }
764           }
765 #endif
766 
767           AAC_MASK_INTERRUPTS(sc);
768           aac_release_sync_fib(sc);
769           lockmgr(&sc->aac_io_lock, LK_RELEASE);
770 
771           return(0);
772 }
773 
774 /*
775  * Bring the controller to a quiescent state, ready for system suspend.
776  */
777 int
aac_suspend(device_t dev)778 aac_suspend(device_t dev)
779 {
780           struct aac_softc *sc;
781 
782           sc = device_get_softc(dev);
783 
784           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
785           sc->aac_state |= AAC_STATE_SUSPEND;
786 
787           AAC_MASK_INTERRUPTS(sc);
788           return(0);
789 }
790 
791 /*
792  * Bring the controller back to a state ready for operation.
793  */
794 int
aac_resume(device_t dev)795 aac_resume(device_t dev)
796 {
797           struct aac_softc *sc;
798 
799           sc = device_get_softc(dev);
800 
801           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
802           sc->aac_state &= ~AAC_STATE_SUSPEND;
803           AAC_UNMASK_INTERRUPTS(sc);
804           return(0);
805 }
806 
807 /*
808  * Interrupt handler for NEW_COMM interface.
809  */
810 void
aac_new_intr(void * arg)811 aac_new_intr(void *arg)
812 {
813           struct aac_softc *sc;
814           u_int32_t index, fast;
815           struct aac_command *cm;
816           struct aac_fib *fib;
817           int i;
818 
819           sc = (struct aac_softc *)arg;
820 
821           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
822           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
823           while (1) {
824                     index = AAC_GET_OUTB_QUEUE(sc);
825                     if (index == 0xffffffff)
826                               index = AAC_GET_OUTB_QUEUE(sc);
827                     if (index == 0xffffffff)
828                               break;
829                     if (index & 2) {
830                               if (index == 0xfffffffe) {
831                                         /* XXX This means that the controller wants
832                                          * more work.  Ignore it for now.
833                                          */
834                                         continue;
835                               }
836                               /* AIF */
837                               fib = (struct aac_fib *)kmalloc(sizeof *fib, M_AACBUF,
838                                            M_INTWAIT | M_ZERO);
839                               index &= ~2;
840                               for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
841                                         ((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
842                               aac_handle_aif(sc, fib);
843                               kfree(fib, M_AACBUF);
844 
845                               /*
846                                * AIF memory is owned by the adapter, so let it
847                                * know that we are done with it.
848                                */
849                               AAC_SET_OUTB_QUEUE(sc, index);
850                               AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
851                     } else {
852                               fast = index & 1;
853                               cm = sc->aac_commands + (index >> 2);
854                               fib = cm->cm_fib;
855                               if (fast) {
856                                         fib->Header.XferState |= AAC_FIBSTATE_DONEADAP;
857                                         *((u_int32_t *)(fib->data)) = AAC_ERROR_NORMAL;
858                               }
859                               aac_remove_busy(cm);
860                               aac_unmap_command(cm);
861                               cm->cm_flags |= AAC_CMD_COMPLETED;
862 
863                               /* is there a completion handler? */
864                               if (cm->cm_complete != NULL) {
865                                         cm->cm_complete(cm);
866                               } else {
867                                         /* assume that someone is sleeping on this
868                                          * command
869                                          */
870                                         wakeup(cm);
871                               }
872                               sc->flags &= ~AAC_QUEUE_FRZN;
873                     }
874           }
875           /* see if we can start some more I/O */
876           if ((sc->flags & AAC_QUEUE_FRZN) == 0)
877                     aac_startio(sc);
878 
879           lockmgr(&sc->aac_io_lock, LK_RELEASE);
880 }
881 
882 /*
883  * Interrupt filter for !NEW_COMM interface.
884  */
885 void
aac_filter(void * arg)886 aac_filter(void *arg)
887 {
888           struct aac_softc *sc;
889           u_int16_t reason;
890 
891           sc = (struct aac_softc *)arg;
892 
893           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
894           /*
895            * Read the status register directly.  This is faster than taking the
896            * driver lock and reading the queues directly.  It also saves having
897            * to turn parts of the driver lock into a spin mutex, which would be
898            * ugly.
899            */
900           reason = AAC_GET_ISTATUS(sc);
901           AAC_CLEAR_ISTATUS(sc, reason);
902 
903           /* handle completion processing */
904           if (reason & AAC_DB_RESPONSE_READY)
905                     taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
906 
907           /* controller wants to talk to us */
908           if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY)) {
909                     /*
910                      * XXX Make sure that we don't get fooled by strange messages
911                      * that start with a NULL.
912                      */
913                     if ((reason & AAC_DB_PRINTF) &&
914                               (sc->aac_common->ac_printf[0] == 0))
915                               sc->aac_common->ac_printf[0] = 32;
916 
917                     /*
918                      * This might miss doing the actual wakeup.  However, the
919                      * lksleep that this is waking up has a timeout, so it will
920                      * wake up eventually.  AIFs and printfs are low enough
921                      * priority that they can handle hanging out for a few seconds
922                      * if needed.
923                      */
924                     wakeup(sc->aifthread);
925           }
926 }
927 
928 /*
929  * Command Processing
930  */
931 
932 /*
933  * Start as much queued I/O as possible on the controller
934  */
935 void
aac_startio(struct aac_softc * sc)936 aac_startio(struct aac_softc *sc)
937 {
938           struct aac_command *cm;
939           int error;
940 
941           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
942 
943           for (;;) {
944                     /*
945                      * This flag might be set if the card is out of resources.
946                      * Checking it here prevents an infinite loop of deferrals.
947                      */
948                     if (sc->flags & AAC_QUEUE_FRZN)
949                               break;
950 
951                     /*
952                      * Try to get a command that's been put off for lack of
953                      * resources
954                      */
955                     cm = aac_dequeue_ready(sc);
956 
957                     /*
958                      * Try to build a command off the bio queue (ignore error
959                      * return)
960                      */
961                     if (cm == NULL)
962                               aac_bio_command(sc, &cm);
963 
964                     /* nothing to do? */
965                     if (cm == NULL)
966                               break;
967 
968                     /* don't map more than once */
969                     if (cm->cm_flags & AAC_CMD_MAPPED)
970                               panic("aac: command %p already mapped", cm);
971 
972                     /*
973                      * Set up the command to go to the controller.  If there are no
974                      * data buffers associated with the command then it can bypass
975                      * busdma.
976                      */
977                     if (cm->cm_datalen != 0) {
978                               error = bus_dmamap_load(sc->aac_buffer_dmat,
979                                                             cm->cm_datamap, cm->cm_data,
980                                                             cm->cm_datalen,
981                                                             aac_map_command_sg, cm, 0);
982                               if (error == EINPROGRESS) {
983                                         fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "freezing queue\n");
984                                         sc->flags |= AAC_QUEUE_FRZN;
985                                         error = 0;
986                               } else if (error != 0)
987                                         panic("aac_startio: unexpected error %d from "
988                                               "busdma", error);
989                     } else
990                               aac_map_command_sg(cm, NULL, 0, 0);
991           }
992 }
993 
994 /*
995  * Handle notification of one or more FIBs coming from the controller.
996  */
997 static void
aac_command_thread(void * arg)998 aac_command_thread(void *arg)
999 {
1000           struct aac_softc *sc = arg;
1001           struct aac_fib *fib;
1002           u_int32_t fib_size;
1003           int size, retval;
1004 
1005           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1006 
1007           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1008           sc->aifflags = AAC_AIFFLAGS_RUNNING;
1009 
1010           while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
1011 
1012                     retval = 0;
1013                     if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
1014                               retval = lksleep(sc->aifthread, &sc->aac_io_lock, 0,
1015                                                   "aifthd", AAC_PERIODIC_INTERVAL * hz);
1016 
1017                     /*
1018                      * First see if any FIBs need to be allocated.  This needs
1019                      * to be called without the driver lock because contigmalloc
1020                      * can sleep.
1021                      */
1022                     if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
1023                               lockmgr(&sc->aac_io_lock, LK_RELEASE);
1024                               aac_alloc_commands(sc);
1025                               lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1026                               sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
1027                               aac_startio(sc);
1028                     }
1029 
1030                     /*
1031                      * While we're here, check to see if any commands are stuck.
1032                      * This is pretty low-priority, so it's ok if it doesn't
1033                      * always fire.
1034                      */
1035                     if (retval == EWOULDBLOCK)
1036                               aac_timeout(sc);
1037 
1038                     /* Check the hardware printf message buffer */
1039                     if (sc->aac_common->ac_printf[0] != 0)
1040                               aac_print_printf(sc);
1041 
1042                     /* Also check to see if the adapter has a command for us. */
1043                     if (sc->flags & AAC_FLAGS_NEW_COMM)
1044                               continue;
1045                     for (;;) {
1046                               if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
1047                                                      &fib_size, &fib))
1048                                         break;
1049 
1050                               AAC_PRINT_FIB(sc, fib);
1051 
1052                               switch (fib->Header.Command) {
1053                               case AifRequest:
1054                                         aac_handle_aif(sc, fib);
1055                                         break;
1056                               default:
1057                                         device_printf(sc->aac_dev, "unknown command "
1058                                                         "from controller\n");
1059                                         break;
1060                               }
1061 
1062                               if ((fib->Header.XferState == 0) ||
1063                                   (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
1064                                         break;
1065                               }
1066 
1067                               /* Return the AIF to the controller. */
1068                               if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
1069                                         fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
1070                                         *(AAC_FSAStatus*)fib->data = ST_OK;
1071 
1072                                         /* XXX Compute the Size field? */
1073                                         size = fib->Header.Size;
1074                                         if (size > sizeof(struct aac_fib)) {
1075                                                   size = sizeof(struct aac_fib);
1076                                                   fib->Header.Size = size;
1077                                         }
1078                                         /*
1079                                          * Since we did not generate this command, it
1080                                          * cannot go through the normal
1081                                          * enqueue->startio chain.
1082                                          */
1083                                         aac_enqueue_response(sc,
1084                                                              AAC_ADAP_NORM_RESP_QUEUE,
1085                                                              fib);
1086                               }
1087                     }
1088           }
1089           sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
1090           lockmgr(&sc->aac_io_lock, LK_RELEASE);
1091           wakeup(sc->aac_dev);
1092 }
1093 
1094 /*
1095  * Process completed commands.
1096  */
1097 static void
aac_complete(void * context,int pending)1098 aac_complete(void *context, int pending)
1099 {
1100           struct aac_softc *sc;
1101           struct aac_command *cm;
1102           struct aac_fib *fib;
1103           u_int32_t fib_size;
1104 
1105           sc = (struct aac_softc *)context;
1106           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1107 
1108           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1109 
1110           /* pull completed commands off the queue */
1111           for (;;) {
1112                     /* look for completed FIBs on our queue */
1113                     if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1114                                                                       &fib))
1115                               break;    /* nothing to do */
1116 
1117                     /* get the command, unmap and hand off for processing */
1118                     cm = sc->aac_commands + fib->Header.SenderData;
1119                     if (cm == NULL) {
1120                               AAC_PRINT_FIB(sc, fib);
1121                               break;
1122                     }
1123                     if ((cm->cm_flags & AAC_CMD_TIMEDOUT) != 0)
1124                               device_printf(sc->aac_dev,
1125                                   "COMMAND %p COMPLETED AFTER %d SECONDS\n",
1126                                   cm, (int)(time_uptime - cm->cm_timestamp));
1127 
1128                     aac_remove_busy(cm);
1129 
1130                     aac_unmap_command(cm);
1131                     cm->cm_flags |= AAC_CMD_COMPLETED;
1132 
1133                     /* is there a completion handler? */
1134                     if (cm->cm_complete != NULL) {
1135                               cm->cm_complete(cm);
1136                     } else {
1137                               /* assume that someone is sleeping on this command */
1138                               wakeup(cm);
1139                     }
1140           }
1141 
1142           /* see if we can start some more I/O */
1143           sc->flags &= ~AAC_QUEUE_FRZN;
1144           aac_startio(sc);
1145 
1146           lockmgr(&sc->aac_io_lock, LK_RELEASE);
1147 }
1148 
1149 /*
1150  * Handle a bio submitted from a disk device.
1151  */
1152 void
aac_submit_bio(struct aac_disk * ad,struct bio * bio)1153 aac_submit_bio(struct aac_disk *ad, struct bio *bio)
1154 {
1155           struct aac_softc *sc;
1156 
1157           bio->bio_driver_info = ad;
1158           sc = ad->ad_controller;
1159           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1160 
1161           /* queue the BIO and try to get some work done */
1162           aac_enqueue_bio(sc, bio);
1163           aac_startio(sc);
1164 }
1165 
1166 /*
1167  * Get a bio and build a command to go with it.
1168  */
1169 static int
aac_bio_command(struct aac_softc * sc,struct aac_command ** cmp)1170 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
1171 {
1172           struct aac_command *cm;
1173           struct aac_fib *fib;
1174           struct aac_disk *ad;
1175           struct bio *bio;
1176           struct buf *bp;
1177 
1178           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1179 
1180           /* get the resources we will need */
1181           cm = NULL;
1182           bio = NULL;
1183           if (aac_alloc_command(sc, &cm))         /* get a command */
1184                     goto fail;
1185           if ((bio = aac_dequeue_bio(sc)) == NULL)
1186                     goto fail;
1187 
1188           /* fill out the command */
1189           bp = bio->bio_buf;
1190           cm->cm_data = (void *)bp->b_data;
1191           cm->cm_datalen = bp->b_bcount;
1192           cm->cm_complete = aac_bio_complete;
1193           cm->cm_private = bio;
1194           cm->cm_timestamp = time_uptime;
1195 
1196           /* build the FIB */
1197           fib = cm->cm_fib;
1198           fib->Header.Size = sizeof(struct aac_fib_header);
1199           fib->Header.XferState =
1200                     AAC_FIBSTATE_HOSTOWNED   |
1201                     AAC_FIBSTATE_INITIALISED |
1202                     AAC_FIBSTATE_EMPTY   |
1203                     AAC_FIBSTATE_FROMHOST          |
1204                     AAC_FIBSTATE_REXPECTED   |
1205                     AAC_FIBSTATE_NORM    |
1206                     AAC_FIBSTATE_ASYNC   |
1207                     AAC_FIBSTATE_FAST_RESPONSE;
1208 
1209           /* build the read/write request */
1210           ad = (struct aac_disk *)bio->bio_driver_info;
1211 
1212           if (sc->flags & AAC_FLAGS_RAW_IO) {
1213                     struct aac_raw_io *raw;
1214                     raw = (struct aac_raw_io *)&fib->data[0];
1215                     fib->Header.Command = RawIo;
1216                     raw->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1217                     raw->ByteCount = bp->b_bcount;
1218                     raw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1219                     raw->BpTotal = 0;
1220                     raw->BpComplete = 0;
1221                     fib->Header.Size += sizeof(struct aac_raw_io);
1222                     cm->cm_sgtable = (struct aac_sg_table *)&raw->SgMapRaw;
1223                     if (bp->b_cmd == BUF_CMD_READ) {
1224                               raw->Flags = 1;
1225                               cm->cm_flags |= AAC_CMD_DATAIN;
1226                     } else {
1227                               raw->Flags = 0;
1228                               cm->cm_flags |= AAC_CMD_DATAOUT;
1229                     }
1230           } else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1231                     fib->Header.Command = ContainerCommand;
1232                     if (bp->b_cmd == BUF_CMD_READ) {
1233                               struct aac_blockread *br;
1234                               br = (struct aac_blockread *)&fib->data[0];
1235                               br->Command = VM_CtBlockRead;
1236                               br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1237                               br->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1238                               br->ByteCount = bp->b_bcount;
1239                               fib->Header.Size += sizeof(struct aac_blockread);
1240                               cm->cm_sgtable = &br->SgMap;
1241                               cm->cm_flags |= AAC_CMD_DATAIN;
1242                     } else {
1243                               struct aac_blockwrite *bw;
1244                               bw = (struct aac_blockwrite *)&fib->data[0];
1245                               bw->Command = VM_CtBlockWrite;
1246                               bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1247                               bw->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1248                               bw->ByteCount = bp->b_bcount;
1249                               bw->Stable = CUNSTABLE;
1250                               fib->Header.Size += sizeof(struct aac_blockwrite);
1251                               cm->cm_flags |= AAC_CMD_DATAOUT;
1252                               cm->cm_sgtable = &bw->SgMap;
1253                     }
1254           } else {
1255                     fib->Header.Command = ContainerCommand64;
1256                     if (bp->b_cmd == BUF_CMD_READ) {
1257                               struct aac_blockread64 *br;
1258                               br = (struct aac_blockread64 *)&fib->data[0];
1259                               br->Command = VM_CtHostRead64;
1260                               br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1261                               br->SectorCount = bp->b_bcount / AAC_BLOCK_SIZE;
1262                               br->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1263                               br->Pad = 0;
1264                               br->Flags = 0;
1265                               fib->Header.Size += sizeof(struct aac_blockread64);
1266                               cm->cm_flags |= AAC_CMD_DATAIN;
1267                               cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
1268                     } else {
1269                               struct aac_blockwrite64 *bw;
1270                               bw = (struct aac_blockwrite64 *)&fib->data[0];
1271                               bw->Command = VM_CtHostWrite64;
1272                               bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1273                               bw->SectorCount = bp->b_bcount / AAC_BLOCK_SIZE;
1274                               bw->BlockNumber = bio->bio_offset / AAC_BLOCK_SIZE;
1275                               bw->Pad = 0;
1276                               bw->Flags = 0;
1277                               fib->Header.Size += sizeof(struct aac_blockwrite64);
1278                               cm->cm_flags |= AAC_CMD_DATAOUT;
1279                               cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
1280                     }
1281           }
1282 
1283           *cmp = cm;
1284           return(0);
1285 
1286 fail:
1287           if (bio != NULL)
1288                     aac_enqueue_bio(sc, bio);
1289           if (cm != NULL)
1290                     aac_release_command(cm);
1291           return(ENOMEM);
1292 }
1293 
1294 /*
1295  * Handle a bio-instigated command that has been completed.
1296  */
1297 static void
aac_bio_complete(struct aac_command * cm)1298 aac_bio_complete(struct aac_command *cm)
1299 {
1300           struct aac_blockread_response *brr;
1301           struct aac_blockwrite_response *bwr;
1302           struct bio *bio;
1303           struct buf *bp;
1304           const char *code;
1305           AAC_FSAStatus status;
1306 
1307           /* fetch relevant status and then release the command */
1308           bio = (struct bio *)cm->cm_private;
1309           bp = bio->bio_buf;
1310           if (bp->b_cmd == BUF_CMD_READ) {
1311                     brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
1312                     status = brr->Status;
1313           } else {
1314                     bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
1315                     status = bwr->Status;
1316           }
1317           aac_release_command(cm);
1318 
1319           /* fix up the bio based on status */
1320           if (status == ST_OK) {
1321                     bp->b_resid = 0;
1322                     code = NULL;
1323           } else {
1324                     bp->b_error = EIO;
1325                     bp->b_flags |= B_ERROR;
1326           }
1327           aac_biodone(bio, code);
1328 }
1329 
1330 /*
1331  * Submit a command to the controller, return when it completes.
1332  * XXX This is very dangerous!  If the card has gone out to lunch, we could
1333  *     be stuck here forever.  At the same time, signals are not caught
1334  *     because there is a risk that a signal could wakeup the sleep before
1335  *     the card has a chance to complete the command.  Since there is no way
1336  *     to cancel a command that is in progress, we can't protect against the
1337  *     card completing a command late and spamming the command and data
1338  *     memory.  So, we are held hostage until the command completes.
1339  */
1340 static int
aac_wait_command(struct aac_command * cm)1341 aac_wait_command(struct aac_command *cm)
1342 {
1343           struct aac_softc *sc;
1344           int error;
1345 
1346           sc = cm->cm_sc;
1347           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1348 
1349           /* Put the command on the ready queue and get things going */
1350           aac_enqueue_ready(cm);
1351           aac_startio(sc);
1352           error = lksleep(cm, &sc->aac_io_lock, 0, "aacwait", 0);
1353           return(error);
1354 }
1355 
1356 /*
1357  *Command Buffer Management
1358  */
1359 
1360 /*
1361  * Allocate a command.
1362  */
1363 int
aac_alloc_command(struct aac_softc * sc,struct aac_command ** cmp)1364 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1365 {
1366           struct aac_command *cm;
1367 
1368           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1369 
1370           if ((cm = aac_dequeue_free(sc)) == NULL) {
1371                     if (sc->total_fibs < sc->aac_max_fibs) {
1372                               lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1373                               sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1374                               lockmgr(&sc->aac_io_lock, LK_RELEASE);
1375                               wakeup(sc->aifthread);
1376                     }
1377                     return (EBUSY);
1378           }
1379 
1380           *cmp = cm;
1381           return(0);
1382 }
1383 
1384 /*
1385  * Release a command back to the freelist.
1386  */
1387 void
aac_release_command(struct aac_command * cm)1388 aac_release_command(struct aac_command *cm)
1389 {
1390           struct aac_event *event;
1391           struct aac_softc *sc;
1392 
1393           sc = cm->cm_sc;
1394           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1395 
1396           /* (re)initialize the command/FIB */
1397           cm->cm_sgtable = NULL;
1398           cm->cm_flags = 0;
1399           cm->cm_complete = NULL;
1400           cm->cm_private = NULL;
1401           cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1402           cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1403           cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1404           cm->cm_fib->Header.Flags = 0;
1405           cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
1406 
1407           /*
1408            * These are duplicated in aac_start to cover the case where an
1409            * intermediate stage may have destroyed them.  They're left
1410            * initialized here for debugging purposes only.
1411            */
1412           cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1413           cm->cm_fib->Header.SenderData = 0;
1414 
1415           aac_enqueue_free(cm);
1416 
1417           if ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
1418                     TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
1419                     event->ev_callback(sc, event, event->ev_arg);
1420           }
1421 }
1422 
1423 /*
1424  * Map helper for command/FIB allocation.
1425  */
1426 static void
aac_map_command_helper(void * arg,bus_dma_segment_t * segs,int nseg,int error)1427 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1428 {
1429           uint64_t  *fibphys;
1430 
1431           fibphys = (uint64_t *)arg;
1432 
1433           *fibphys = segs[0].ds_addr;
1434 }
1435 
1436 /*
1437  * Allocate and initialize commands/FIBs for this adapter.
1438  */
1439 static int
aac_alloc_commands(struct aac_softc * sc)1440 aac_alloc_commands(struct aac_softc *sc)
1441 {
1442           struct aac_command *cm;
1443           struct aac_fibmap *fm;
1444           uint64_t fibphys;
1445           int i, error;
1446 
1447           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1448 
1449           if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
1450                     return (ENOMEM);
1451 
1452           fm = kmalloc(sizeof(struct aac_fibmap), M_AACBUF, M_INTWAIT | M_ZERO);
1453 
1454           /* allocate the FIBs in DMAable memory and load them */
1455           if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1456                                    BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1457                     device_printf(sc->aac_dev,
1458                                     "Not enough contiguous memory available.\n");
1459                     kfree(fm, M_AACBUF);
1460                     return (ENOMEM);
1461           }
1462 
1463           /* Ignore errors since this doesn't bounce */
1464           (void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1465                                     sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
1466                                     aac_map_command_helper, &fibphys, 0);
1467 
1468           /* initialize constant fields in the command structure */
1469           bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
1470           for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
1471                     cm = sc->aac_commands + sc->total_fibs;
1472                     fm->aac_commands = cm;
1473                     cm->cm_sc = sc;
1474                     cm->cm_fib = (struct aac_fib *)
1475                               ((u_int8_t *)fm->aac_fibs + i*sc->aac_max_fib_size);
1476                     cm->cm_fibphys = fibphys + i*sc->aac_max_fib_size;
1477                     cm->cm_index = sc->total_fibs;
1478 
1479                     if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1480                                                          &cm->cm_datamap)) != 0)
1481                               break;
1482                     lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1483                     aac_release_command(cm);
1484                     sc->total_fibs++;
1485                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
1486           }
1487 
1488           if (i > 0) {
1489                     lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
1490                     TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1491                     fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs);
1492                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
1493                     return (0);
1494           }
1495 
1496           bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1497           bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1498           kfree(fm, M_AACBUF);
1499           return (ENOMEM);
1500 }
1501 
1502 /*
1503  * Free FIBs owned by this adapter.
1504  */
1505 static void
aac_free_commands(struct aac_softc * sc)1506 aac_free_commands(struct aac_softc *sc)
1507 {
1508           struct aac_fibmap *fm;
1509           struct aac_command *cm;
1510           int i;
1511 
1512           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1513 
1514           while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1515 
1516                     TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1517                     /*
1518                      * We check against total_fibs to handle partially
1519                      * allocated blocks.
1520                      */
1521                     for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) {
1522                               cm = fm->aac_commands + i;
1523                               bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1524                     }
1525                     bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1526                     bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1527                     kfree(fm, M_AACBUF);
1528           }
1529 }
1530 
1531 /*
1532  * Command-mapping helper function - populate this command's s/g table.
1533  */
1534 static void
aac_map_command_sg(void * arg,bus_dma_segment_t * segs,int nseg,int error)1535 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1536 {
1537           struct aac_softc *sc;
1538           struct aac_command *cm;
1539           struct aac_fib *fib;
1540           int i;
1541 
1542           cm = (struct aac_command *)arg;
1543           sc = cm->cm_sc;
1544           fib = cm->cm_fib;
1545           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1546 
1547           /* copy into the FIB */
1548           if (cm->cm_sgtable != NULL) {
1549                     if (fib->Header.Command == RawIo) {
1550                               struct aac_sg_tableraw *sg;
1551                               sg = (struct aac_sg_tableraw *)cm->cm_sgtable;
1552                               sg->SgCount = nseg;
1553                               for (i = 0; i < nseg; i++) {
1554                                         sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr;
1555                                         sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len;
1556                                         sg->SgEntryRaw[i].Next = 0;
1557                                         sg->SgEntryRaw[i].Prev = 0;
1558                                         sg->SgEntryRaw[i].Flags = 0;
1559                               }
1560                               /* update the FIB size for the s/g count */
1561                               fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw);
1562                     } else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1563                               struct aac_sg_table *sg;
1564                               sg = cm->cm_sgtable;
1565                               sg->SgCount = nseg;
1566                               for (i = 0; i < nseg; i++) {
1567                                         sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1568                                         sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1569                               }
1570                               /* update the FIB size for the s/g count */
1571                               fib->Header.Size += nseg*sizeof(struct aac_sg_entry);
1572                     } else {
1573                               struct aac_sg_table64 *sg;
1574                               sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1575                               sg->SgCount = nseg;
1576                               for (i = 0; i < nseg; i++) {
1577                                         sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1578                                         sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1579                               }
1580                               /* update the FIB size for the s/g count */
1581                               fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1582                     }
1583           }
1584 
1585           /* Fix up the address values in the FIB.  Use the command array index
1586            * instead of a pointer since these fields are only 32 bits.  Shift
1587            * the SenderFibAddress over to make room for the fast response bit
1588            * and for the AIF bit
1589            */
1590           cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2);
1591           cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1592 
1593           /* save a pointer to the command for speedy reverse-lookup */
1594           cm->cm_fib->Header.SenderData = cm->cm_index;
1595 
1596           if (cm->cm_flags & AAC_CMD_DATAIN)
1597                     bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1598                                         BUS_DMASYNC_PREREAD);
1599           if (cm->cm_flags & AAC_CMD_DATAOUT)
1600                     bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1601                                         BUS_DMASYNC_PREWRITE);
1602           cm->cm_flags |= AAC_CMD_MAPPED;
1603 
1604           if (sc->flags & AAC_FLAGS_NEW_COMM) {
1605                     int count = 10000000L;
1606                     while (AAC_SEND_COMMAND(sc, cm) != 0) {
1607                               if (--count == 0) {
1608                                         aac_unmap_command(cm);
1609                                         sc->flags |= AAC_QUEUE_FRZN;
1610                                         aac_requeue_ready(cm);
1611                               }
1612                               DELAY(5);                     /* wait 5 usec. */
1613                     }
1614           } else {
1615                     /* Put the FIB on the outbound queue */
1616                     if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1617                               aac_unmap_command(cm);
1618                               sc->flags |= AAC_QUEUE_FRZN;
1619                               aac_requeue_ready(cm);
1620                     }
1621           }
1622 }
1623 
1624 /*
1625  * Unmap a command from controller-visible space.
1626  */
1627 static void
aac_unmap_command(struct aac_command * cm)1628 aac_unmap_command(struct aac_command *cm)
1629 {
1630           struct aac_softc *sc;
1631 
1632           sc = cm->cm_sc;
1633           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1634 
1635           if (!(cm->cm_flags & AAC_CMD_MAPPED))
1636                     return;
1637 
1638           if (cm->cm_datalen != 0) {
1639                     if (cm->cm_flags & AAC_CMD_DATAIN)
1640                               bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1641                                                   BUS_DMASYNC_POSTREAD);
1642                     if (cm->cm_flags & AAC_CMD_DATAOUT)
1643                               bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1644                                                   BUS_DMASYNC_POSTWRITE);
1645 
1646                     bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1647           }
1648           cm->cm_flags &= ~AAC_CMD_MAPPED;
1649 }
1650 
1651 /*
1652  * Hardware Interface
1653  */
1654 
1655 /*
1656  * Initialize the adapter.
1657  */
1658 static void
aac_common_map(void * arg,bus_dma_segment_t * segs,int nseg,int error)1659 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1660 {
1661           struct aac_softc *sc;
1662 
1663           sc = (struct aac_softc *)arg;
1664           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1665 
1666           sc->aac_common_busaddr = segs[0].ds_addr;
1667 }
1668 
1669 static int
aac_check_firmware(struct aac_softc * sc)1670 aac_check_firmware(struct aac_softc *sc)
1671 {
1672           u_int32_t code, major, minor, options = 0, atu_size = 0;
1673           int rid, status;
1674           time_t then;
1675 
1676           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1677           /*
1678            * Wait for the adapter to come ready.
1679            */
1680           then = time_uptime;
1681           do {
1682                     code = AAC_GET_FWSTATUS(sc);
1683                     if (code & AAC_SELF_TEST_FAILED) {
1684                               device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1685                               return(ENXIO);
1686                     }
1687                     if (code & AAC_KERNEL_PANIC) {
1688                               device_printf(sc->aac_dev,
1689                                               "FATAL: controller kernel panic");
1690                               return(ENXIO);
1691                     }
1692                     if (time_uptime > (then + AAC_BOOT_TIMEOUT)) {
1693                               device_printf(sc->aac_dev,
1694                                               "FATAL: controller not coming ready, "
1695                                                      "status %x\n", code);
1696                               return(ENXIO);
1697                     }
1698           } while (!(code & AAC_UP_AND_RUNNING));
1699 
1700           /*
1701            * Retrieve the firmware version numbers.  Dell PERC2/QC cards with
1702            * firmware version 1.x are not compatible with this driver.
1703            */
1704           if (sc->flags & AAC_FLAGS_PERC2QC) {
1705                     if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1706                                              NULL)) {
1707                               device_printf(sc->aac_dev,
1708                                               "Error reading firmware version\n");
1709                               return (EIO);
1710                     }
1711 
1712                     /* These numbers are stored as ASCII! */
1713                     major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1714                     minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1715                     if (major == 1) {
1716                               device_printf(sc->aac_dev,
1717                                   "Firmware version %d.%d is not supported.\n",
1718                                   major, minor);
1719                               return (EINVAL);
1720                     }
1721           }
1722 
1723           /*
1724            * Retrieve the capabilities/supported options word so we know what
1725            * work-arounds to enable.  Some firmware revs don't support this
1726            * command.
1727            */
1728           if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
1729                     if (status != AAC_SRB_STS_INVALID_REQUEST) {
1730                               device_printf(sc->aac_dev,
1731                                    "RequestAdapterInfo failed\n");
1732                               return (EIO);
1733                     }
1734           } else {
1735                     options = AAC_GET_MAILBOX(sc, 1);
1736                     atu_size = AAC_GET_MAILBOX(sc, 2);
1737                     sc->supported_options = options;
1738 
1739                     if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1740                         (sc->flags & AAC_FLAGS_NO4GB) == 0)
1741                               sc->flags |= AAC_FLAGS_4GB_WINDOW;
1742                     if (options & AAC_SUPPORTED_NONDASD)
1743                               sc->flags |= AAC_FLAGS_ENABLE_CAM;
1744                     if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1745                          && (sizeof(bus_addr_t) > 4)) {
1746                               device_printf(sc->aac_dev,
1747                                   "Enabling 64-bit address support\n");
1748                               sc->flags |= AAC_FLAGS_SG_64BIT;
1749                     }
1750                     if ((options & AAC_SUPPORTED_NEW_COMM)
1751                      && sc->aac_if->aif_send_command)
1752                               sc->flags |= AAC_FLAGS_NEW_COMM;
1753                     if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
1754                               sc->flags |= AAC_FLAGS_ARRAY_64BIT;
1755           }
1756 
1757           /* Check for broken hardware that does a lower number of commands */
1758           sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512);
1759 
1760           /* Remap mem. resource, if required */
1761           if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
1762               atu_size > rman_get_size(sc->aac_regs_res1)) {
1763                     rid = rman_get_rid(sc->aac_regs_res1);
1764                     bus_release_resource(sc->aac_dev, SYS_RES_MEMORY, rid,
1765                         sc->aac_regs_res1);
1766                     sc->aac_regs_res1 = bus_alloc_resource(sc->aac_dev,
1767                         SYS_RES_MEMORY, &rid, 0ul, ~0ul, atu_size, RF_ACTIVE);
1768                     if (sc->aac_regs_res1 == NULL) {
1769                               sc->aac_regs_res1 = bus_alloc_resource_any(
1770                                   sc->aac_dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
1771                               if (sc->aac_regs_res1 == NULL) {
1772                                         device_printf(sc->aac_dev,
1773                                             "couldn't allocate register window\n");
1774                                         return (ENXIO);
1775                               }
1776                               sc->flags &= ~AAC_FLAGS_NEW_COMM;
1777                     }
1778                     sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
1779                     sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
1780 
1781                     if (sc->aac_hwif == AAC_HWIF_NARK) {
1782                               sc->aac_regs_res0 = sc->aac_regs_res1;
1783                               sc->aac_btag0 = sc->aac_btag1;
1784                               sc->aac_bhandle0 = sc->aac_bhandle1;
1785                     }
1786           }
1787 
1788           /* Read preferred settings */
1789           sc->aac_max_fib_size = sizeof(struct aac_fib);
1790           sc->aac_max_sectors = 128;                                  /* 64KB */
1791           if (sc->flags & AAC_FLAGS_SG_64BIT)
1792                     sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1793                      - sizeof(struct aac_blockwrite64))
1794                      / sizeof(struct aac_sg_entry64);
1795           else
1796                     sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1797                      - sizeof(struct aac_blockwrite))
1798                      / sizeof(struct aac_sg_entry);
1799 
1800           if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
1801                     options = AAC_GET_MAILBOX(sc, 1);
1802                     sc->aac_max_fib_size = (options & 0xFFFF);
1803                     sc->aac_max_sectors = (options >> 16) << 1;
1804                     options = AAC_GET_MAILBOX(sc, 2);
1805                     sc->aac_sg_tablesize = (options >> 16);
1806                     options = AAC_GET_MAILBOX(sc, 3);
1807                     sc->aac_max_fibs = (options & 0xFFFF);
1808           }
1809           if (sc->aac_max_fib_size > PAGE_SIZE)
1810                     sc->aac_max_fib_size = PAGE_SIZE;
1811           sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size;
1812 
1813           if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1814                     sc->flags |= AAC_FLAGS_RAW_IO;
1815                     device_printf(sc->aac_dev, "Enable Raw I/O\n");
1816           }
1817           if ((sc->flags & AAC_FLAGS_RAW_IO) &&
1818               (sc->flags & AAC_FLAGS_ARRAY_64BIT)) {
1819                     sc->flags |= AAC_FLAGS_LBA_64BIT;
1820                     device_printf(sc->aac_dev, "Enable 64-bit array\n");
1821           }
1822 
1823           return (0);
1824 }
1825 
1826 static int
aac_init(struct aac_softc * sc)1827 aac_init(struct aac_softc *sc)
1828 {
1829           struct aac_adapter_init       *ip;
1830           u_int32_t qoffset;
1831           int error;
1832 
1833           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1834 
1835           /*
1836            * Fill in the init structure.  This tells the adapter about the
1837            * physical location of various important shared data structures.
1838            */
1839           ip = &sc->aac_common->ac_init;
1840           ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1841           if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1842                     ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_4;
1843                     sc->flags |= AAC_FLAGS_RAW_IO;
1844           }
1845           ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1846 
1847           ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1848                                                    offsetof(struct aac_common, ac_fibs);
1849           ip->AdapterFibsVirtualAddress = 0;
1850           ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1851           ip->AdapterFibAlign = sizeof(struct aac_fib);
1852 
1853           ip->PrintfBufferAddress = sc->aac_common_busaddr +
1854                                           offsetof(struct aac_common, ac_printf);
1855           ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1856 
1857           /*
1858            * The adapter assumes that pages are 4K in size, except on some
1859            * broken firmware versions that do the page->byte conversion twice,
1860            * therefore 'assuming' that this value is in 16MB units (2^24).
1861            * Round up since the granularity is so high.
1862            */
1863           ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1864           if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1865                     ip->HostPhysMemPages =
1866                         (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1867           }
1868           ip->HostElapsedSeconds = time_uptime;   /* reset later if invalid */
1869 
1870           ip->InitFlags = 0;
1871           if (sc->flags & AAC_FLAGS_NEW_COMM) {
1872                     ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED;
1873                     device_printf(sc->aac_dev, "New comm. interface enabled\n");
1874           }
1875 
1876           ip->MaxIoCommands = sc->aac_max_fibs;
1877           ip->MaxIoSize = sc->aac_max_sectors << 9;
1878           ip->MaxFibSize = sc->aac_max_fib_size;
1879 
1880           /*
1881            * Initialize FIB queues.  Note that it appears that the layout of the
1882            * indexes and the segmentation of the entries may be mandated by the
1883            * adapter, which is only told about the base of the queue index fields.
1884            *
1885            * The initial values of the indices are assumed to inform the adapter
1886            * of the sizes of the respective queues, and theoretically it could
1887            * work out the entire layout of the queue structures from this.  We
1888            * take the easy route and just lay this area out like everyone else
1889            * does.
1890            *
1891            * The Linux driver uses a much more complex scheme whereby several
1892            * header records are kept for each queue.  We use a couple of generic
1893            * list manipulation functions which 'know' the size of each list by
1894            * virtue of a table.
1895            */
1896           qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1897           qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1898           sc->aac_queues =
1899               (struct aac_queue_table *)((uintptr_t)sc->aac_common + qoffset);
1900           ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1901 
1902           sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1903                     AAC_HOST_NORM_CMD_ENTRIES;
1904           sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1905                     AAC_HOST_NORM_CMD_ENTRIES;
1906           sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1907                     AAC_HOST_HIGH_CMD_ENTRIES;
1908           sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1909                     AAC_HOST_HIGH_CMD_ENTRIES;
1910           sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1911                     AAC_ADAP_NORM_CMD_ENTRIES;
1912           sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1913                     AAC_ADAP_NORM_CMD_ENTRIES;
1914           sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1915                     AAC_ADAP_HIGH_CMD_ENTRIES;
1916           sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1917                     AAC_ADAP_HIGH_CMD_ENTRIES;
1918           sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1919                     AAC_HOST_NORM_RESP_ENTRIES;
1920           sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1921                     AAC_HOST_NORM_RESP_ENTRIES;
1922           sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1923                     AAC_HOST_HIGH_RESP_ENTRIES;
1924           sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1925                     AAC_HOST_HIGH_RESP_ENTRIES;
1926           sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1927                     AAC_ADAP_NORM_RESP_ENTRIES;
1928           sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1929                     AAC_ADAP_NORM_RESP_ENTRIES;
1930           sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1931                     AAC_ADAP_HIGH_RESP_ENTRIES;
1932           sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1933                     AAC_ADAP_HIGH_RESP_ENTRIES;
1934           sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1935                     &sc->aac_queues->qt_HostNormCmdQueue[0];
1936           sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1937                     &sc->aac_queues->qt_HostHighCmdQueue[0];
1938           sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1939                     &sc->aac_queues->qt_AdapNormCmdQueue[0];
1940           sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1941                     &sc->aac_queues->qt_AdapHighCmdQueue[0];
1942           sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1943                     &sc->aac_queues->qt_HostNormRespQueue[0];
1944           sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1945                     &sc->aac_queues->qt_HostHighRespQueue[0];
1946           sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1947                     &sc->aac_queues->qt_AdapNormRespQueue[0];
1948           sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1949                     &sc->aac_queues->qt_AdapHighRespQueue[0];
1950 
1951           /*
1952            * Do controller-type-specific initialisation
1953            */
1954           switch (sc->aac_hwif) {
1955           case AAC_HWIF_I960RX:
1956                     AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, ~0);
1957                     break;
1958           case AAC_HWIF_RKT:
1959                     AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, ~0);
1960                     break;
1961           default:
1962                     break;
1963           }
1964 
1965           /*
1966            * Give the init structure to the controller.
1967            */
1968           if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1969                                    sc->aac_common_busaddr +
1970                                    offsetof(struct aac_common, ac_init), 0, 0, 0,
1971                                    NULL)) {
1972                     device_printf(sc->aac_dev,
1973                                     "error establishing init structure\n");
1974                     error = EIO;
1975                     goto out;
1976           }
1977 
1978           error = 0;
1979 out:
1980           return(error);
1981 }
1982 
1983 static int
aac_setup_intr(struct aac_softc * sc)1984 aac_setup_intr(struct aac_softc *sc)
1985 {
1986 
1987           if (sc->flags & AAC_FLAGS_NEW_COMM) {
1988                     if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
1989                                            INTR_MPSAFE,
1990                                            aac_new_intr, sc, &sc->aac_intr, NULL)) {
1991                               device_printf(sc->aac_dev, "can't set up interrupt\n");
1992                               return (EINVAL);
1993                     }
1994           } else {
1995                     if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
1996                                            0, aac_filter,
1997                                            sc, &sc->aac_intr, NULL)) {
1998                               device_printf(sc->aac_dev,
1999                                               "can't set up interrupt filter\n");
2000                               return (EINVAL);
2001                     }
2002           }
2003           return (0);
2004 }
2005 
2006 /*
2007  * Send a synchronous command to the controller and wait for a result.
2008  * Indicate if the controller completed the command with an error status.
2009  */
2010 static int
aac_sync_command(struct aac_softc * sc,u_int32_t command,u_int32_t arg0,u_int32_t arg1,u_int32_t arg2,u_int32_t arg3,u_int32_t * sp)2011 aac_sync_command(struct aac_softc *sc, u_int32_t command,
2012                      u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
2013                      u_int32_t *sp)
2014 {
2015           time_t then;
2016           u_int32_t status;
2017 
2018           if (sp != NULL)
2019                     *sp = 0;  /* avoid gcc warnings */
2020           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2021 
2022           /* populate the mailbox */
2023           AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
2024 
2025           /* ensure the sync command doorbell flag is cleared */
2026           AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2027 
2028           /* then set it to signal the adapter */
2029           AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
2030 
2031           /* spin waiting for the command to complete */
2032           then = time_uptime;
2033           do {
2034                     if (time_uptime > (then + AAC_IMMEDIATE_TIMEOUT)) {
2035                               fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "timed out");
2036                               return(EIO);
2037                     }
2038           } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
2039 
2040           /* clear the completion flag */
2041           AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2042 
2043           /* get the command status */
2044           status = AAC_GET_MAILBOX(sc, 0);
2045           if (sp != NULL)
2046                     *sp = status;
2047 
2048           if (status != AAC_SRB_STS_SUCCESS)
2049                     return (-1);
2050           return(0);
2051 }
2052 
2053 int
aac_sync_fib(struct aac_softc * sc,u_int32_t command,u_int32_t xferstate,struct aac_fib * fib,u_int16_t datasize)2054 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
2055                      struct aac_fib *fib, u_int16_t datasize)
2056 {
2057           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2058 #if 0 /* XXX swildner */
2059           KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
2060 #endif
2061 
2062           if (datasize > AAC_FIB_DATASIZE)
2063                     return(EINVAL);
2064 
2065           /*
2066            * Set up the sync FIB
2067            */
2068           fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
2069                                         AAC_FIBSTATE_INITIALISED |
2070                                         AAC_FIBSTATE_EMPTY;
2071           fib->Header.XferState |= xferstate;
2072           fib->Header.Command = command;
2073           fib->Header.StructType = AAC_FIBTYPE_TFIB;
2074           fib->Header.Size = sizeof(struct aac_fib_header) + datasize;
2075           fib->Header.SenderSize = sizeof(struct aac_fib);
2076           fib->Header.SenderFibAddress = 0;       /* Not needed */
2077           fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
2078                                                    offsetof(struct aac_common,
2079                                                               ac_sync_fib);
2080 
2081           /*
2082            * Give the FIB to the controller, wait for a response.
2083            */
2084           if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
2085                                    fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
2086                     fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error");
2087                     return(EIO);
2088           }
2089 
2090           return (0);
2091 }
2092 
2093 /*
2094  * Adapter-space FIB queue manipulation
2095  *
2096  * Note that the queue implementation here is a little funky; neither the PI or
2097  * CI will ever be zero.  This behaviour is a controller feature.
2098  */
2099 static const struct {
2100           int                 size;
2101           int                 notify;
2102 } aac_qinfo[] = {
2103           {AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
2104           {AAC_HOST_HIGH_CMD_ENTRIES, 0},
2105           {AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
2106           {AAC_ADAP_HIGH_CMD_ENTRIES, 0},
2107           {AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
2108           {AAC_HOST_HIGH_RESP_ENTRIES, 0},
2109           {AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
2110           {AAC_ADAP_HIGH_RESP_ENTRIES, 0}
2111 };
2112 
2113 /*
2114  * Atomically insert an entry into the nominated queue, returns 0 on success or
2115  * EBUSY if the queue is full.
2116  *
2117  * Note: it would be more efficient to defer notifying the controller in
2118  *         the case where we may be inserting several entries in rapid succession,
2119  *         but implementing this usefully may be difficult (it would involve a
2120  *         separate queue/notify interface).
2121  */
2122 static int
aac_enqueue_fib(struct aac_softc * sc,int queue,struct aac_command * cm)2123 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
2124 {
2125           u_int32_t pi, ci;
2126           int error;
2127           u_int32_t fib_size;
2128           u_int32_t fib_addr;
2129 
2130           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2131 
2132           fib_size = cm->cm_fib->Header.Size;
2133           fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
2134 
2135           /* get the producer/consumer indices */
2136           pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2137           ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2138 
2139           /* wrap the queue? */
2140           if (pi >= aac_qinfo[queue].size)
2141                     pi = 0;
2142 
2143           /* check for queue full */
2144           if ((pi + 1) == ci) {
2145                     error = EBUSY;
2146                     goto out;
2147           }
2148 
2149           /*
2150            * To avoid a race with its completion interrupt, place this command on
2151            * the busy queue prior to advertising it to the controller.
2152            */
2153           aac_enqueue_busy(cm);
2154 
2155           /* populate queue entry */
2156           (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2157           (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2158 
2159           /* update producer index */
2160           sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2161 
2162           /* notify the adapter if we know how */
2163           if (aac_qinfo[queue].notify != 0)
2164                     AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2165 
2166           error = 0;
2167 
2168 out:
2169           return(error);
2170 }
2171 
2172 /*
2173  * Atomically remove one entry from the nominated queue, returns 0 on
2174  * success or ENOENT if the queue is empty.
2175  */
2176 static int
aac_dequeue_fib(struct aac_softc * sc,int queue,u_int32_t * fib_size,struct aac_fib ** fib_addr)2177 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
2178                     struct aac_fib **fib_addr)
2179 {
2180           u_int32_t pi, ci;
2181           u_int32_t fib_index;
2182           int error;
2183           int notify;
2184 
2185           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2186 
2187           /* get the producer/consumer indices */
2188           pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2189           ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2190 
2191           /* check for queue empty */
2192           if (ci == pi) {
2193                     error = ENOENT;
2194                     goto out;
2195           }
2196 
2197           /* wrap the pi so the following test works */
2198           if (pi >= aac_qinfo[queue].size)
2199                     pi = 0;
2200 
2201           notify = 0;
2202           if (ci == pi + 1)
2203                     notify++;
2204 
2205           /* wrap the queue? */
2206           if (ci >= aac_qinfo[queue].size)
2207                     ci = 0;
2208 
2209           /* fetch the entry */
2210           *fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
2211 
2212           switch (queue) {
2213           case AAC_HOST_NORM_CMD_QUEUE:
2214           case AAC_HOST_HIGH_CMD_QUEUE:
2215                     /*
2216                      * The aq_fib_addr is only 32 bits wide so it can't be counted
2217                      * on to hold an address.  For AIF's, the adapter assumes
2218                      * that it's giving us an address into the array of AIF fibs.
2219                      * Therefore, we have to convert it to an index.
2220                      */
2221                     fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
2222                               sizeof(struct aac_fib);
2223                     *fib_addr = &sc->aac_common->ac_fibs[fib_index];
2224                     break;
2225 
2226           case AAC_HOST_NORM_RESP_QUEUE:
2227           case AAC_HOST_HIGH_RESP_QUEUE:
2228           {
2229                     struct aac_command *cm;
2230 
2231                     /*
2232                      * As above, an index is used instead of an actual address.
2233                      * Gotta shift the index to account for the fast response
2234                      * bit.  No other correction is needed since this value was
2235                      * originally provided by the driver via the SenderFibAddress
2236                      * field.
2237                      */
2238                     fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
2239                     cm = sc->aac_commands + (fib_index >> 2);
2240                     *fib_addr = cm->cm_fib;
2241 
2242                     /*
2243                      * Is this a fast response? If it is, update the fib fields in
2244                      * local memory since the whole fib isn't DMA'd back up.
2245                      */
2246                     if (fib_index & 0x01) {
2247                               (*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
2248                               *((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
2249                     }
2250                     break;
2251           }
2252           default:
2253                     panic("Invalid queue in aac_dequeue_fib()");
2254                     break;
2255           }
2256 
2257           /* update consumer index */
2258           sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
2259 
2260           /* if we have made the queue un-full, notify the adapter */
2261           if (notify && (aac_qinfo[queue].notify != 0))
2262                     AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2263           error = 0;
2264 
2265 out:
2266           return(error);
2267 }
2268 
2269 /*
2270  * Put our response to an Adapter Initialed Fib on the response queue
2271  */
2272 static int
aac_enqueue_response(struct aac_softc * sc,int queue,struct aac_fib * fib)2273 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
2274 {
2275           u_int32_t pi, ci;
2276           int error;
2277           u_int32_t fib_size;
2278           u_int32_t fib_addr;
2279 
2280           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2281 
2282           /* Tell the adapter where the FIB is */
2283           fib_size = fib->Header.Size;
2284           fib_addr = fib->Header.SenderFibAddress;
2285           fib->Header.ReceiverFibAddress = fib_addr;
2286 
2287           /* get the producer/consumer indices */
2288           pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2289           ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2290 
2291           /* wrap the queue? */
2292           if (pi >= aac_qinfo[queue].size)
2293                     pi = 0;
2294 
2295           /* check for queue full */
2296           if ((pi + 1) == ci) {
2297                     error = EBUSY;
2298                     goto out;
2299           }
2300 
2301           /* populate queue entry */
2302           (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2303           (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2304 
2305           /* update producer index */
2306           sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2307 
2308           /* notify the adapter if we know how */
2309           if (aac_qinfo[queue].notify != 0)
2310                     AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2311 
2312           error = 0;
2313 
2314 out:
2315           return(error);
2316 }
2317 
2318 /*
2319  * Check for commands that have been outstanding for a suspiciously long time,
2320  * and complain about them.
2321  */
2322 static void
aac_timeout(struct aac_softc * sc)2323 aac_timeout(struct aac_softc *sc)
2324 {
2325           struct aac_command *cm;
2326           time_t deadline;
2327           int timedout, code;
2328 
2329           /*
2330            * Traverse the busy command list, bitch about late commands once
2331            * only.
2332            */
2333           timedout = 0;
2334           deadline = time_uptime - AAC_CMD_TIMEOUT;
2335           TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
2336                     if ((cm->cm_timestamp  < deadline)
2337                         && !(cm->cm_flags & AAC_CMD_TIMEDOUT)) {
2338                               cm->cm_flags |= AAC_CMD_TIMEDOUT;
2339                               device_printf(sc->aac_dev,
2340                                   "COMMAND %p (TYPE %d) TIMEOUT AFTER %d SECONDS\n",
2341                                   cm, cm->cm_fib->Header.Command,
2342                                   (int)(time_uptime-cm->cm_timestamp));
2343                               AAC_PRINT_FIB(sc, cm->cm_fib);
2344                               timedout++;
2345                     }
2346           }
2347 
2348           if (timedout) {
2349                     code = AAC_GET_FWSTATUS(sc);
2350                     if (code != AAC_UP_AND_RUNNING) {
2351                               device_printf(sc->aac_dev, "WARNING! Controller is no "
2352                                               "longer running! code= 0x%x\n", code);
2353                     }
2354           }
2355 }
2356 
2357 /*
2358  * Interface Function Vectors
2359  */
2360 
2361 /*
2362  * Read the current firmware status word.
2363  */
2364 static int
aac_sa_get_fwstatus(struct aac_softc * sc)2365 aac_sa_get_fwstatus(struct aac_softc *sc)
2366 {
2367           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2368 
2369           return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
2370 }
2371 
2372 static int
aac_rx_get_fwstatus(struct aac_softc * sc)2373 aac_rx_get_fwstatus(struct aac_softc *sc)
2374 {
2375           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2376 
2377           return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2378               AAC_RX_OMR0 : AAC_RX_FWSTATUS));
2379 }
2380 
2381 static int
aac_rkt_get_fwstatus(struct aac_softc * sc)2382 aac_rkt_get_fwstatus(struct aac_softc *sc)
2383 {
2384           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2385 
2386           return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2387               AAC_RKT_OMR0 : AAC_RKT_FWSTATUS));
2388 }
2389 
2390 /*
2391  * Notify the controller of a change in a given queue
2392  */
2393 
2394 static void
aac_sa_qnotify(struct aac_softc * sc,int qbit)2395 aac_sa_qnotify(struct aac_softc *sc, int qbit)
2396 {
2397           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2398 
2399           AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
2400 }
2401 
2402 static void
aac_rx_qnotify(struct aac_softc * sc,int qbit)2403 aac_rx_qnotify(struct aac_softc *sc, int qbit)
2404 {
2405           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2406 
2407           AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
2408 }
2409 
2410 static void
aac_rkt_qnotify(struct aac_softc * sc,int qbit)2411 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
2412 {
2413           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2414 
2415           AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
2416 }
2417 
2418 /*
2419  * Get the interrupt reason bits
2420  */
2421 static int
aac_sa_get_istatus(struct aac_softc * sc)2422 aac_sa_get_istatus(struct aac_softc *sc)
2423 {
2424           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2425 
2426           return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
2427 }
2428 
2429 static int
aac_rx_get_istatus(struct aac_softc * sc)2430 aac_rx_get_istatus(struct aac_softc *sc)
2431 {
2432           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2433 
2434           return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
2435 }
2436 
2437 static int
aac_rkt_get_istatus(struct aac_softc * sc)2438 aac_rkt_get_istatus(struct aac_softc *sc)
2439 {
2440           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2441 
2442           return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
2443 }
2444 
2445 /*
2446  * Clear some interrupt reason bits
2447  */
2448 static void
aac_sa_clear_istatus(struct aac_softc * sc,int mask)2449 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
2450 {
2451           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2452 
2453           AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
2454 }
2455 
2456 static void
aac_rx_clear_istatus(struct aac_softc * sc,int mask)2457 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
2458 {
2459           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2460 
2461           AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
2462 }
2463 
2464 static void
aac_rkt_clear_istatus(struct aac_softc * sc,int mask)2465 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
2466 {
2467           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2468 
2469           AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
2470 }
2471 
2472 /*
2473  * Populate the mailbox and set the command word
2474  */
2475 static void
aac_sa_set_mailbox(struct aac_softc * sc,u_int32_t command,u_int32_t arg0,u_int32_t arg1,u_int32_t arg2,u_int32_t arg3)2476 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2477                     u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2478 {
2479           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2480 
2481           AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX, command);
2482           AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
2483           AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
2484           AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
2485           AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
2486 }
2487 
2488 static void
aac_rx_set_mailbox(struct aac_softc * sc,u_int32_t command,u_int32_t arg0,u_int32_t arg1,u_int32_t arg2,u_int32_t arg3)2489 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
2490                     u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2491 {
2492           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2493 
2494           AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX, command);
2495           AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2496           AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2497           AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2498           AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2499 }
2500 
2501 static void
aac_rkt_set_mailbox(struct aac_softc * sc,u_int32_t command,u_int32_t arg0,u_int32_t arg1,u_int32_t arg2,u_int32_t arg3)2502 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2503                         u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2504 {
2505           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2506 
2507           AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX, command);
2508           AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
2509           AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
2510           AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
2511           AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
2512 }
2513 
2514 /*
2515  * Fetch the immediate command status word
2516  */
2517 static int
aac_sa_get_mailbox(struct aac_softc * sc,int mb)2518 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2519 {
2520           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2521 
2522           return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2523 }
2524 
2525 static int
aac_rx_get_mailbox(struct aac_softc * sc,int mb)2526 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2527 {
2528           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2529 
2530           return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2531 }
2532 
2533 static int
aac_rkt_get_mailbox(struct aac_softc * sc,int mb)2534 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2535 {
2536           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2537 
2538           return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2539 }
2540 
2541 /*
2542  * Set/clear interrupt masks
2543  */
2544 static void
aac_sa_set_interrupts(struct aac_softc * sc,int enable)2545 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2546 {
2547           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2548 
2549           if (enable) {
2550                     AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2551           } else {
2552                     AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2553           }
2554 }
2555 
2556 static void
aac_rx_set_interrupts(struct aac_softc * sc,int enable)2557 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2558 {
2559           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2560 
2561           if (enable) {
2562                     if (sc->flags & AAC_FLAGS_NEW_COMM)
2563                               AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
2564                     else
2565                               AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2566           } else {
2567                     AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
2568           }
2569 }
2570 
2571 static void
aac_rkt_set_interrupts(struct aac_softc * sc,int enable)2572 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2573 {
2574           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2575 
2576           if (enable) {
2577                     if (sc->flags & AAC_FLAGS_NEW_COMM)
2578                               AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
2579                     else
2580                               AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2581           } else {
2582                     AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
2583           }
2584 }
2585 
2586 /*
2587  * New comm. interface: Send command functions
2588  */
2589 static int
aac_rx_send_command(struct aac_softc * sc,struct aac_command * cm)2590 aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm)
2591 {
2592           u_int32_t index, device;
2593 
2594           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2595 
2596           index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2597           if (index == 0xffffffffL)
2598                     index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2599           if (index == 0xffffffffL)
2600                     return index;
2601           aac_enqueue_busy(cm);
2602           device = index;
2603           AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2604           device += 4;
2605           AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2606           device += 4;
2607           AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2608           AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
2609           return 0;
2610 }
2611 
2612 static int
aac_rkt_send_command(struct aac_softc * sc,struct aac_command * cm)2613 aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
2614 {
2615           u_int32_t index, device;
2616 
2617           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2618 
2619           index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2620           if (index == 0xffffffffL)
2621                     index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2622           if (index == 0xffffffffL)
2623                     return index;
2624           aac_enqueue_busy(cm);
2625           device = index;
2626           AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2627           device += 4;
2628           AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2629           device += 4;
2630           AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2631           AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
2632           return 0;
2633 }
2634 
2635 /*
2636  * New comm. interface: get, set outbound queue index
2637  */
2638 static int
aac_rx_get_outb_queue(struct aac_softc * sc)2639 aac_rx_get_outb_queue(struct aac_softc *sc)
2640 {
2641           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2642 
2643           return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
2644 }
2645 
2646 static int
aac_rkt_get_outb_queue(struct aac_softc * sc)2647 aac_rkt_get_outb_queue(struct aac_softc *sc)
2648 {
2649           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2650 
2651           return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
2652 }
2653 
2654 static void
aac_rx_set_outb_queue(struct aac_softc * sc,int index)2655 aac_rx_set_outb_queue(struct aac_softc *sc, int index)
2656 {
2657           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2658 
2659           AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
2660 }
2661 
2662 static void
aac_rkt_set_outb_queue(struct aac_softc * sc,int index)2663 aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
2664 {
2665           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2666 
2667           AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
2668 }
2669 
2670 /*
2671  * Debugging and Diagnostics
2672  */
2673 
2674 /*
2675  * Print some information about the controller.
2676  */
2677 static void
aac_describe_controller(struct aac_softc * sc)2678 aac_describe_controller(struct aac_softc *sc)
2679 {
2680           struct aac_fib *fib;
2681           struct aac_adapter_info       *info;
2682           char *adapter_type = "Adaptec RAID controller";
2683 
2684           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2685 
2686           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
2687           aac_alloc_sync_fib(sc, &fib);
2688 
2689           fib->data[0] = 0;
2690           if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2691                     device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2692                     aac_release_sync_fib(sc);
2693                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
2694                     return;
2695           }
2696 
2697           /* save the kernel revision structure for later use */
2698           info = (struct aac_adapter_info *)&fib->data[0];
2699           sc->aac_revision = info->KernelRevision;
2700 
2701           if (bootverbose) {
2702                     device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
2703                         "(%dMB cache, %dMB execution), %s\n",
2704                         aac_describe_code(aac_cpu_variant, info->CpuVariant),
2705                         info->ClockSpeed, info->TotalMem / (1024 * 1024),
2706                         info->BufferMem / (1024 * 1024),
2707                         info->ExecutionMem / (1024 * 1024),
2708                         aac_describe_code(aac_battery_platform,
2709                         info->batteryPlatform));
2710 
2711                     device_printf(sc->aac_dev,
2712                         "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2713                         info->KernelRevision.external.comp.major,
2714                         info->KernelRevision.external.comp.minor,
2715                         info->KernelRevision.external.comp.dash,
2716                         info->KernelRevision.buildNumber,
2717                         (u_int32_t)(info->SerialNumber & 0xffffff));
2718 
2719                     device_printf(sc->aac_dev, "Supported Options=%pb%i\n",
2720                                     "\20"
2721                                     "\1SNAPSHOT"
2722                                     "\2CLUSTERS"
2723                                     "\3WCACHE"
2724                                     "\4DATA64"
2725                                     "\5HOSTTIME"
2726                                     "\6RAID50"
2727                                     "\7WINDOW4GB"
2728                                     "\10SCSIUPGD"
2729                                     "\11SOFTERR"
2730                                     "\12NORECOND"
2731                                     "\13SGMAP64"
2732                                     "\14ALARM"
2733                                     "\15NONDASD"
2734                                     "\16SCSIMGT"
2735                                     "\17RAIDSCSI"
2736                                     "\21ADPTINFO"
2737                                     "\22NEWCOMM"
2738                                     "\23ARRAY64BIT"
2739                                     "\24HEATSENSOR"
2740                                     , sc->supported_options);
2741           }
2742 
2743           if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
2744                     fib->data[0] = 0;
2745                     if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
2746                               device_printf(sc->aac_dev,
2747                                   "RequestSupplementAdapterInfo failed\n");
2748                     else
2749                               adapter_type = ((struct aac_supplement_adapter_info *)
2750                                   &fib->data[0])->AdapterTypeText;
2751           }
2752           device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
2753                     adapter_type,
2754                     AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
2755                     AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
2756 
2757           aac_release_sync_fib(sc);
2758           lockmgr(&sc->aac_io_lock, LK_RELEASE);
2759 }
2760 
2761 /*
2762  * Look up a text description of a numeric error code and return a pointer to
2763  * same.
2764  */
2765 static const char *
aac_describe_code(const struct aac_code_lookup * table,u_int32_t code)2766 aac_describe_code(const struct aac_code_lookup *table, u_int32_t code)
2767 {
2768           int i;
2769 
2770           for (i = 0; table[i].string != NULL; i++)
2771                     if (table[i].code == code)
2772                               return(table[i].string);
2773           return(table[i + 1].string);
2774 }
2775 
2776 /*
2777  * Management Interface
2778  */
2779 
2780 static int
aac_open(struct dev_open_args * ap)2781 aac_open(struct dev_open_args *ap)
2782 {
2783           cdev_t dev = ap->a_head.a_dev;
2784           struct aac_softc *sc;
2785 
2786           sc = dev->si_drv1;
2787           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2788           device_busy(sc->aac_dev);
2789 
2790           return 0;
2791 }
2792 
2793 static int
aac_ioctl(struct dev_ioctl_args * ap)2794 aac_ioctl(struct dev_ioctl_args *ap)
2795 {
2796           caddr_t arg = ap->a_data;
2797           cdev_t dev = ap->a_head.a_dev;
2798           u_long cmd = ap->a_cmd;
2799           union aac_statrequest *as;
2800           struct aac_softc *sc;
2801           int error = 0;
2802 
2803           as = (union aac_statrequest *)arg;
2804           sc = dev->si_drv1;
2805           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2806 
2807           switch (cmd) {
2808           case AACIO_STATS:
2809                     switch (as->as_item) {
2810                     case AACQ_FREE:
2811                     case AACQ_BIO:
2812                     case AACQ_READY:
2813                     case AACQ_BUSY:
2814                               bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2815                                     sizeof(struct aac_qstat));
2816                               break;
2817                     default:
2818                               error = ENOENT;
2819                               break;
2820                     }
2821           break;
2822 
2823           case FSACTL_SENDFIB:
2824           case FSACTL_SEND_LARGE_FIB:
2825                     arg = *(caddr_t*)arg;
2826           case FSACTL_LNX_SENDFIB:
2827           case FSACTL_LNX_SEND_LARGE_FIB:
2828                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SENDFIB");
2829                     error = aac_ioctl_sendfib(sc, arg);
2830                     break;
2831           case FSACTL_SEND_RAW_SRB:
2832                     arg = *(caddr_t*)arg;
2833           case FSACTL_LNX_SEND_RAW_SRB:
2834                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SEND_RAW_SRB");
2835                     error = aac_ioctl_send_raw_srb(sc, arg);
2836                     break;
2837           case FSACTL_AIF_THREAD:
2838           case FSACTL_LNX_AIF_THREAD:
2839                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_AIF_THREAD");
2840                     error = EINVAL;
2841                     break;
2842           case FSACTL_OPEN_GET_ADAPTER_FIB:
2843                     arg = *(caddr_t*)arg;
2844           case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2845                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_OPEN_GET_ADAPTER_FIB");
2846                     error = aac_open_aif(sc, arg);
2847                     break;
2848           case FSACTL_GET_NEXT_ADAPTER_FIB:
2849                     arg = *(caddr_t*)arg;
2850           case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2851                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_NEXT_ADAPTER_FIB");
2852                     error = aac_getnext_aif(sc, arg);
2853                     break;
2854           case FSACTL_CLOSE_GET_ADAPTER_FIB:
2855                     arg = *(caddr_t*)arg;
2856           case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2857                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2858                     error = aac_close_aif(sc, arg);
2859                     break;
2860           case FSACTL_MINIPORT_REV_CHECK:
2861                     arg = *(caddr_t*)arg;
2862           case FSACTL_LNX_MINIPORT_REV_CHECK:
2863                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_MINIPORT_REV_CHECK");
2864                     error = aac_rev_check(sc, arg);
2865                     break;
2866           case FSACTL_QUERY_DISK:
2867                     arg = *(caddr_t*)arg;
2868           case FSACTL_LNX_QUERY_DISK:
2869                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_QUERY_DISK");
2870                     error = aac_query_disk(sc, arg);
2871                     break;
2872           case FSACTL_DELETE_DISK:
2873           case FSACTL_LNX_DELETE_DISK:
2874                     /*
2875                      * We don't trust the underland to tell us when to delete a
2876                      * container, rather we rely on an AIF coming from the
2877                      * controller
2878                      */
2879                     error = 0;
2880                     break;
2881           case FSACTL_GET_PCI_INFO:
2882                     arg = *(caddr_t*)arg;
2883           case FSACTL_LNX_GET_PCI_INFO:
2884                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_PCI_INFO");
2885                     error = aac_get_pci_info(sc, arg);
2886                     break;
2887           case FSACTL_GET_FEATURES:
2888                     arg = *(caddr_t*)arg;
2889           case FSACTL_LNX_GET_FEATURES:
2890                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_FEATURES");
2891                     error = aac_supported_features(sc, arg);
2892                     break;
2893           default:
2894                     fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "unsupported cmd 0x%lx\n", cmd);
2895                     error = EINVAL;
2896                     break;
2897           }
2898           return(error);
2899 }
2900 
2901 static struct filterops aac_filterops =
2902           { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, aac_filter_detach, aac_filter_read };
2903 
2904 static int
aac_kqfilter(struct dev_kqfilter_args * ap)2905 aac_kqfilter(struct dev_kqfilter_args *ap)
2906 {
2907           cdev_t dev = ap->a_head.a_dev;
2908           struct aac_softc *sc = dev->si_drv1;
2909           struct knote *kn = ap->a_kn;
2910           struct klist *klist;
2911 
2912           ap->a_result = 0;
2913 
2914           switch (kn->kn_filter) {
2915           case EVFILT_READ:
2916                     kn->kn_fop = &aac_filterops;
2917                     kn->kn_hook = (caddr_t)sc;
2918                     break;
2919           default:
2920                     ap->a_result = EOPNOTSUPP;
2921                     return (0);
2922           }
2923 
2924           klist = &sc->rcv_kq.ki_note;
2925           knote_insert(klist, kn);
2926 
2927           return (0);
2928 }
2929 
2930 static void
aac_filter_detach(struct knote * kn)2931 aac_filter_detach(struct knote *kn)
2932 {
2933           struct aac_softc *sc = (struct aac_softc *)kn->kn_hook;
2934           struct klist *klist;
2935 
2936           klist = &sc->rcv_kq.ki_note;
2937           knote_remove(klist, kn);
2938 }
2939 
2940 static int
aac_filter_read(struct knote * kn,long hint)2941 aac_filter_read(struct knote *kn, long hint)
2942 {
2943           struct aac_softc *sc;
2944           struct aac_fib_context *ctx;
2945           int ret = 0;
2946 
2947           sc = (struct aac_softc *)kn->kn_hook;
2948 
2949           lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
2950           for (ctx = sc->fibctx; ctx; ctx = ctx->next)
2951                     if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap)
2952                               ret = 1;
2953           lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
2954 
2955           return(ret);
2956 }
2957 
2958 static void
aac_ioctl_event(struct aac_softc * sc,struct aac_event * event,void * arg)2959 aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
2960 {
2961 
2962           switch (event->ev_type) {
2963           case AAC_EVENT_CMFREE:
2964                     KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
2965                     if (aac_alloc_command(sc, (struct aac_command **)arg)) {
2966                               aac_add_event(sc, event);
2967                               return;
2968                     }
2969                     kfree(event, M_AACBUF);
2970                     wakeup(arg);
2971                     break;
2972           default:
2973                     break;
2974           }
2975 }
2976 
2977 /*
2978  * Send a FIB supplied from userspace
2979  */
2980 static int
aac_ioctl_sendfib(struct aac_softc * sc,caddr_t ufib)2981 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2982 {
2983           struct aac_command *cm;
2984           int size, error;
2985 
2986           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2987 
2988           cm = NULL;
2989 
2990           /*
2991            * Get a command
2992            */
2993           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
2994           if (aac_alloc_command(sc, &cm)) {
2995                     struct aac_event *event;
2996 
2997                     event = kmalloc(sizeof(struct aac_event), M_AACBUF,
2998                         M_INTWAIT | M_ZERO);
2999                     event->ev_type = AAC_EVENT_CMFREE;
3000                     event->ev_callback = aac_ioctl_event;
3001                     event->ev_arg = &cm;
3002                     aac_add_event(sc, event);
3003                     lksleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
3004           }
3005           lockmgr(&sc->aac_io_lock, LK_RELEASE);
3006 
3007           /*
3008            * Fetch the FIB header, then re-copy to get data as well.
3009            */
3010           if ((error = copyin(ufib, cm->cm_fib,
3011                                   sizeof(struct aac_fib_header))) != 0)
3012                     goto out;
3013           size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
3014           if (size > sc->aac_max_fib_size) {
3015                     device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
3016                                     size, sc->aac_max_fib_size);
3017                     size = sc->aac_max_fib_size;
3018           }
3019           if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
3020                     goto out;
3021           cm->cm_fib->Header.Size = size;
3022           cm->cm_timestamp = time_uptime;
3023 
3024           /*
3025            * Pass the FIB to the controller, wait for it to complete.
3026            */
3027           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3028           error = aac_wait_command(cm);
3029           lockmgr(&sc->aac_io_lock, LK_RELEASE);
3030           if (error != 0) {
3031                     device_printf(sc->aac_dev,
3032                                     "aac_wait_command return %d\n", error);
3033                     goto out;
3034           }
3035 
3036           /*
3037            * Copy the FIB and data back out to the caller.
3038            */
3039           size = cm->cm_fib->Header.Size;
3040           if (size > sc->aac_max_fib_size) {
3041                     device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
3042                                     size, sc->aac_max_fib_size);
3043                     size = sc->aac_max_fib_size;
3044           }
3045           error = copyout(cm->cm_fib, ufib, size);
3046 
3047 out:
3048           if (cm != NULL) {
3049                     lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3050                     aac_release_command(cm);
3051                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
3052           }
3053           return(error);
3054 }
3055 
3056 /*
3057  * Send a passthrough FIB supplied from userspace
3058  */
3059 static int
aac_ioctl_send_raw_srb(struct aac_softc * sc,caddr_t arg)3060 aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
3061 {
3062           struct aac_command *cm;
3063           struct aac_event *event;
3064           struct aac_fib *fib;
3065           struct aac_srb *srbcmd, *user_srb;
3066           struct aac_sg_entry *sge;
3067 #ifdef __x86_64__
3068           struct aac_sg_entry64 *sge64;
3069 #endif
3070           void *srb_sg_address, *ureply;
3071           uint32_t fibsize, srb_sg_bytecount;
3072           int error, transfer_data;
3073 
3074           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3075 
3076           cm = NULL;
3077           transfer_data = 0;
3078           fibsize = 0;
3079           user_srb = (struct aac_srb *)arg;
3080 
3081           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3082           if (aac_alloc_command(sc, &cm)) {
3083                      event = kmalloc(sizeof(struct aac_event), M_AACBUF,
3084                         M_NOWAIT | M_ZERO);
3085                     if (event == NULL) {
3086                               error = EBUSY;
3087                               lockmgr(&sc->aac_io_lock, LK_RELEASE);
3088                               goto out;
3089                     }
3090                     event->ev_type = AAC_EVENT_CMFREE;
3091                     event->ev_callback = aac_ioctl_event;
3092                     event->ev_arg = &cm;
3093                     aac_add_event(sc, event);
3094                     lksleep(cm, &sc->aac_io_lock, 0, "aacraw", 0);
3095           }
3096           lockmgr(&sc->aac_io_lock, LK_RELEASE);
3097 
3098           cm->cm_data = NULL;
3099           fib = cm->cm_fib;
3100           srbcmd = (struct aac_srb *)fib->data;
3101           error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t));
3102           if (error != 0)
3103                     goto out;
3104           if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) {
3105                     error = EINVAL;
3106                     goto out;
3107           }
3108           error = copyin(user_srb, srbcmd, fibsize);
3109           if (error != 0)
3110                     goto out;
3111           srbcmd->function = 0;
3112           srbcmd->retry_limit = 0;
3113           if (srbcmd->sg_map.SgCount > 1) {
3114                     error = EINVAL;
3115                     goto out;
3116           }
3117 
3118           /* Retrieve correct SG entries. */
3119           if (fibsize == (sizeof(struct aac_srb) +
3120               srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
3121                     sge = srbcmd->sg_map.SgEntry;
3122                     srb_sg_bytecount = sge->SgByteCount;
3123                     srb_sg_address = (void *)(uintptr_t)sge->SgAddress;
3124           }
3125 #ifdef __x86_64__
3126           else if (fibsize == (sizeof(struct aac_srb) +
3127               srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) {
3128                     sge = NULL;
3129                     sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry;
3130                     srb_sg_bytecount = sge64->SgByteCount;
3131                     srb_sg_address = (void *)sge64->SgAddress;
3132                     if (sge64->SgAddress > 0xffffffffull &&
3133                         (sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
3134                               error = EINVAL;
3135                               goto out;
3136                     }
3137           }
3138 #endif
3139           else {
3140                     error = EINVAL;
3141                     goto out;
3142           }
3143           ureply = (char *)arg + fibsize;
3144           srbcmd->data_len = srb_sg_bytecount;
3145           if (srbcmd->sg_map.SgCount == 1)
3146                     transfer_data = 1;
3147 
3148           cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map;
3149           if (transfer_data) {
3150                     cm->cm_datalen = srb_sg_bytecount;
3151                     cm->cm_data = kmalloc(cm->cm_datalen, M_AACBUF, M_NOWAIT);
3152                     if (cm->cm_data == NULL) {
3153                               error = ENOMEM;
3154                               goto out;
3155                     }
3156                     if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)
3157                               cm->cm_flags |= AAC_CMD_DATAIN;
3158                     if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) {
3159                               cm->cm_flags |= AAC_CMD_DATAOUT;
3160                               error = copyin(srb_sg_address, cm->cm_data,
3161                                   cm->cm_datalen);
3162                               if (error != 0)
3163                                         goto out;
3164                     }
3165           }
3166 
3167           fib->Header.Size = sizeof(struct aac_fib_header) +
3168               sizeof(struct aac_srb);
3169           fib->Header.XferState =
3170               AAC_FIBSTATE_HOSTOWNED   |
3171               AAC_FIBSTATE_INITIALISED |
3172               AAC_FIBSTATE_EMPTY       |
3173               AAC_FIBSTATE_FROMHOST    |
3174               AAC_FIBSTATE_REXPECTED   |
3175               AAC_FIBSTATE_NORM        |
3176               AAC_FIBSTATE_ASYNC       |
3177               AAC_FIBSTATE_FAST_RESPONSE;
3178           fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ?
3179               ScsiPortCommandU64 : ScsiPortCommand;
3180 
3181           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3182           aac_wait_command(cm);
3183           lockmgr(&sc->aac_io_lock, LK_RELEASE);
3184 
3185           if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) {
3186                     error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen);
3187                     if (error != 0)
3188                               goto out;
3189           }
3190           error = copyout(fib->data, ureply, sizeof(struct aac_srb_response));
3191 out:
3192           if (cm != NULL) {
3193                     if (cm->cm_data != NULL)
3194                               kfree(cm->cm_data, M_AACBUF);
3195                     lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3196                     aac_release_command(cm);
3197                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
3198           }
3199           return(error);
3200 }
3201 
3202 static int
aac_close(struct dev_close_args * ap)3203 aac_close(struct dev_close_args *ap)
3204 {
3205           cdev_t dev = ap->a_head.a_dev;
3206           struct aac_softc *sc;
3207 
3208           sc = dev->si_drv1;
3209           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3210           get_mplock();
3211           device_unbusy(sc->aac_dev);
3212           rel_mplock();
3213 
3214           return 0;
3215 }
3216 
3217 /*
3218  * Handle an AIF sent to us by the controller; queue it for later reference.
3219  * If the queue fills up, then drop the older entries.
3220  */
3221 static void
aac_handle_aif(struct aac_softc * sc,struct aac_fib * fib)3222 aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
3223 {
3224           struct aac_aif_command *aif;
3225           struct aac_container *co, *co_next;
3226           struct aac_fib_context *ctx;
3227           struct aac_mntinforesp *mir;
3228           int next, current, found;
3229           int count = 0, added = 0, i = 0;
3230           uint32_t channel;
3231 
3232           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3233 
3234           aif = (struct aac_aif_command*)&fib->data[0];
3235           aac_print_aif(sc, aif);
3236 
3237           /* Is it an event that we should care about? */
3238           switch (aif->command) {
3239           case AifCmdEventNotify:
3240                     switch (aif->data.EN.type) {
3241                     case AifEnAddContainer:
3242                     case AifEnDeleteContainer:
3243                               /*
3244                                * A container was added or deleted, but the message
3245                                * doesn't tell us anything else!  Re-enumerate the
3246                                * containers and sort things out.
3247                                */
3248                               aac_alloc_sync_fib(sc, &fib);
3249                               do {
3250                                         /*
3251                                          * Ask the controller for its containers one at
3252                                          * a time.
3253                                          * XXX What if the controller's list changes
3254                                          * midway through this enumaration?
3255                                          * XXX This should be done async.
3256                                          */
3257                                         if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
3258                                                   continue;
3259                                         if (i == 0)
3260                                                   count = mir->MntRespCount;
3261                                         /*
3262                                          * Check the container against our list.
3263                                          * co->co_found was already set to 0 in a
3264                                          * previous run.
3265                                          */
3266                                         if ((mir->Status == ST_OK) &&
3267                                             (mir->MntTable[0].VolType != CT_NONE)) {
3268                                                   found = 0;
3269                                                   TAILQ_FOREACH(co,
3270                                                                   &sc->aac_container_tqh,
3271                                                                   co_link) {
3272                                                             if (co->co_mntobj.ObjectId ==
3273                                                                 mir->MntTable[0].ObjectId) {
3274                                                                       co->co_found = 1;
3275                                                                       found = 1;
3276                                                                       break;
3277                                                             }
3278                                                   }
3279                                                   /*
3280                                                    * If the container matched, continue
3281                                                    * in the list.
3282                                                    */
3283                                                   if (found) {
3284                                                             i++;
3285                                                             continue;
3286                                                   }
3287 
3288                                                   /*
3289                                                    * This is a new container.  Do all the
3290                                                    * appropriate things to set it up.
3291                                                    */
3292                                                   aac_add_container(sc, mir, 1);
3293                                                   added = 1;
3294                                         }
3295                                         i++;
3296                               } while ((i < count) && (i < AAC_MAX_CONTAINERS));
3297                               aac_release_sync_fib(sc);
3298 
3299                               /*
3300                                * Go through our list of containers and see which ones
3301                                * were not marked 'found'.  Since the controller didn't
3302                                * list them they must have been deleted.  Do the
3303                                * appropriate steps to destroy the device.  Also reset
3304                                * the co->co_found field.
3305                                */
3306                               co = TAILQ_FIRST(&sc->aac_container_tqh);
3307                               while (co != NULL) {
3308                                         if (co->co_found == 0) {
3309                                                   lockmgr(&sc->aac_io_lock, LK_RELEASE);
3310                                                   get_mplock();
3311                                                   device_delete_child(sc->aac_dev,
3312                                                                           co->co_disk);
3313                                                   rel_mplock();
3314                                                   lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3315                                                   co_next = TAILQ_NEXT(co, co_link);
3316                                                   lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
3317                                                   TAILQ_REMOVE(&sc->aac_container_tqh, co,
3318                                                                  co_link);
3319                                                   lockmgr(&sc->aac_container_lock, LK_RELEASE);
3320                                                   kfree(co, M_AACBUF);
3321                                                   co = co_next;
3322                                         } else {
3323                                                   co->co_found = 0;
3324                                                   co = TAILQ_NEXT(co, co_link);
3325                                         }
3326                               }
3327 
3328                               /* Attach the newly created containers */
3329                               if (added) {
3330                                         lockmgr(&sc->aac_io_lock, LK_RELEASE);
3331                                         get_mplock();
3332                                         bus_generic_attach(sc->aac_dev);
3333                                         rel_mplock();
3334                                         lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3335                               }
3336 
3337                               break;
3338 
3339                     case AifEnEnclosureManagement:
3340                               switch (aif->data.EN.data.EEE.eventType) {
3341                               case AIF_EM_DRIVE_INSERTION:
3342                               case AIF_EM_DRIVE_REMOVAL:
3343                                         channel = aif->data.EN.data.EEE.unitID;
3344                                         if (sc->cam_rescan_cb != NULL)
3345                                                   sc->cam_rescan_cb(sc,
3346                                                       (channel >> 24) & 0xF,
3347                                                       (channel & 0xFFFF));
3348                                         break;
3349                               }
3350                               break;
3351 
3352                     case AifEnAddJBOD:
3353                     case AifEnDeleteJBOD:
3354                               channel = aif->data.EN.data.ECE.container;
3355                               if (sc->cam_rescan_cb != NULL)
3356                                         sc->cam_rescan_cb(sc, (channel >> 24) & 0xF,
3357                                             AAC_CAM_TARGET_WILDCARD);
3358                               break;
3359 
3360                     default:
3361                               break;
3362                     }
3363 
3364           default:
3365                     break;
3366           }
3367 
3368           /* Copy the AIF data to the AIF queue for ioctl retrieval */
3369           lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3370           current = sc->aifq_idx;
3371           next = (current + 1) % AAC_AIFQ_LENGTH;
3372           if (next == 0)
3373                     sc->aifq_filled = 1;
3374           bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib));
3375           /* modify AIF contexts */
3376           if (sc->aifq_filled) {
3377                     for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3378                               if (next == ctx->ctx_idx)
3379                                         ctx->ctx_wrap = 1;
3380                               else if (current == ctx->ctx_idx && ctx->ctx_wrap)
3381                                         ctx->ctx_idx = next;
3382                     }
3383           }
3384           sc->aifq_idx = next;
3385           /* On the off chance that someone is sleeping for an aif... */
3386           if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
3387                     wakeup(sc->aac_aifq);
3388           /* token may have been lost */
3389           /* Wakeup any poll()ers */
3390           KNOTE(&sc->rcv_kq.ki_note, 0);
3391           /* token may have been lost */
3392           lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3393 }
3394 
3395 /*
3396  * Return the Revision of the driver to userspace and check to see if the
3397  * userspace app is possibly compatible.  This is extremely bogus since
3398  * our driver doesn't follow Adaptec's versioning system.  Cheat by just
3399  * returning what the card reported.
3400  */
3401 static int
aac_rev_check(struct aac_softc * sc,caddr_t udata)3402 aac_rev_check(struct aac_softc *sc, caddr_t udata)
3403 {
3404           struct aac_rev_check rev_check;
3405           struct aac_rev_check_resp rev_check_resp;
3406           int error = 0;
3407 
3408           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3409 
3410           /*
3411            * Copyin the revision struct from userspace
3412            */
3413           if ((error = copyin(udata, (caddr_t)&rev_check,
3414                               sizeof(struct aac_rev_check))) != 0) {
3415                     return error;
3416           }
3417 
3418           fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "Userland revision= %d\n",
3419                 rev_check.callingRevision.buildNumber);
3420 
3421           /*
3422            * Doctor up the response struct.
3423            */
3424           rev_check_resp.possiblyCompatible = 1;
3425           rev_check_resp.adapterSWRevision.external.comp.major =
3426               AAC_DRIVER_MAJOR_VERSION;
3427           rev_check_resp.adapterSWRevision.external.comp.minor =
3428               AAC_DRIVER_MINOR_VERSION;
3429           rev_check_resp.adapterSWRevision.external.comp.type =
3430               AAC_DRIVER_TYPE;
3431           rev_check_resp.adapterSWRevision.external.comp.dash =
3432               AAC_DRIVER_BUGFIX_LEVEL;
3433           rev_check_resp.adapterSWRevision.buildNumber =
3434               AAC_DRIVER_BUILD;
3435 
3436           return(copyout((caddr_t)&rev_check_resp, udata,
3437                               sizeof(struct aac_rev_check_resp)));
3438 }
3439 
3440 /*
3441  * Pass the fib context to the caller
3442  */
3443 static int
aac_open_aif(struct aac_softc * sc,caddr_t arg)3444 aac_open_aif(struct aac_softc *sc, caddr_t arg)
3445 {
3446           struct aac_fib_context *fibctx, *ctx;
3447           int error = 0;
3448 
3449           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3450 
3451           fibctx = kmalloc(sizeof(struct aac_fib_context), M_AACBUF, M_NOWAIT|M_ZERO);
3452           if (fibctx == NULL)
3453                     return (ENOMEM);
3454 
3455           lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3456           /* all elements are already 0, add to queue */
3457           if (sc->fibctx == NULL)
3458                     sc->fibctx = fibctx;
3459           else {
3460                     for (ctx = sc->fibctx; ctx->next; ctx = ctx->next)
3461                               ;
3462                     ctx->next = fibctx;
3463                     fibctx->prev = ctx;
3464           }
3465 
3466           /* evaluate unique value */
3467           fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
3468           ctx = sc->fibctx;
3469           while (ctx != fibctx) {
3470                     if (ctx->unique == fibctx->unique) {
3471                               fibctx->unique++;
3472                               ctx = sc->fibctx;
3473                     } else {
3474                               ctx = ctx->next;
3475                     }
3476           }
3477           lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3478 
3479           error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t));
3480           if (error)
3481                     aac_close_aif(sc, (caddr_t)ctx);
3482           return error;
3483 }
3484 
3485 /*
3486  * Close the caller's fib context
3487  */
3488 static int
aac_close_aif(struct aac_softc * sc,caddr_t arg)3489 aac_close_aif(struct aac_softc *sc, caddr_t arg)
3490 {
3491           struct aac_fib_context *ctx;
3492 
3493           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3494 
3495           lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3496           for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3497                     if (ctx->unique == *(uint32_t *)&arg) {
3498                               if (ctx == sc->fibctx)
3499                                         sc->fibctx = NULL;
3500                               else {
3501                                         ctx->prev->next = ctx->next;
3502                                         if (ctx->next)
3503                                                   ctx->next->prev = ctx->prev;
3504                               }
3505                               break;
3506                     }
3507           }
3508           lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3509           if (ctx)
3510                     kfree(ctx, M_AACBUF);
3511 
3512           return 0;
3513 }
3514 
3515 /*
3516  * Pass the caller the next AIF in their queue
3517  */
3518 static int
aac_getnext_aif(struct aac_softc * sc,caddr_t arg)3519 aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
3520 {
3521           struct get_adapter_fib_ioctl agf;
3522           struct aac_fib_context *ctx;
3523           int error;
3524 
3525           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3526 
3527           if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
3528                     for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3529                               if (agf.AdapterFibContext == ctx->unique)
3530                                         break;
3531                     }
3532                     if (!ctx)
3533                               return (EFAULT);
3534 
3535                     error = aac_return_aif(sc, ctx, agf.AifFib);
3536                     if (error == EAGAIN && agf.Wait) {
3537                               fwprintf(sc, HBA_FLAGS_DBG_AIF_B, "aac_getnext_aif(): waiting for AIF");
3538                               sc->aac_state |= AAC_STATE_AIF_SLEEPER;
3539                               while (error == EAGAIN) {
3540                                         error = tsleep(sc->aac_aifq,
3541                                                          PCATCH, "aacaif", 0);
3542                                         if (error == 0)
3543                                                   error = aac_return_aif(sc, ctx, agf.AifFib);
3544                               }
3545                               sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
3546                     }
3547           }
3548           return(error);
3549 }
3550 
3551 /*
3552  * Hand the next AIF off the top of the queue out to userspace.
3553  */
3554 static int
aac_return_aif(struct aac_softc * sc,struct aac_fib_context * ctx,caddr_t uptr)3555 aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
3556 {
3557           int current, error;
3558 
3559           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3560 
3561           lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
3562           current = ctx->ctx_idx;
3563           if (current == sc->aifq_idx && !ctx->ctx_wrap) {
3564                     /* empty */
3565                     lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3566                     return (EAGAIN);
3567           }
3568           error =
3569                     copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
3570           if (error)
3571                     device_printf(sc->aac_dev,
3572                         "aac_return_aif: copyout returned %d\n", error);
3573           else {
3574                     ctx->ctx_wrap = 0;
3575                     ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
3576           }
3577           lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
3578           return(error);
3579 }
3580 
3581 static int
aac_get_pci_info(struct aac_softc * sc,caddr_t uptr)3582 aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
3583 {
3584           struct aac_pci_info {
3585                     u_int32_t bus;
3586                     u_int32_t slot;
3587           } pciinf;
3588           int error;
3589 
3590           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3591 
3592           pciinf.bus = pci_get_bus(sc->aac_dev);
3593           pciinf.slot = pci_get_slot(sc->aac_dev);
3594 
3595           error = copyout((caddr_t)&pciinf, uptr,
3596                               sizeof(struct aac_pci_info));
3597 
3598           return (error);
3599 }
3600 
3601 static int
aac_supported_features(struct aac_softc * sc,caddr_t uptr)3602 aac_supported_features(struct aac_softc *sc, caddr_t uptr)
3603 {
3604           struct aac_features f;
3605           int error;
3606 
3607           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3608 
3609           if ((error = copyin(uptr, &f, sizeof (f))) != 0)
3610                     return (error);
3611 
3612           /*
3613            * When the management driver receives FSACTL_GET_FEATURES ioctl with
3614            * ALL zero in the featuresState, the driver will return the current
3615            * state of all the supported features, the data field will not be
3616            * valid.
3617            * When the management driver receives FSACTL_GET_FEATURES ioctl with
3618            * a specific bit set in the featuresState, the driver will return the
3619            * current state of this specific feature and whatever data that are
3620            * associated with the feature in the data field or perform whatever
3621            * action needed indicates in the data field.
3622            */
3623           if (f.feat.fValue == 0) {
3624                     f.feat.fBits.largeLBA =
3625                         (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3626                     /* TODO: In the future, add other features state here as well */
3627           } else {
3628                     if (f.feat.fBits.largeLBA)
3629                               f.feat.fBits.largeLBA =
3630                                   (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3631                     /* TODO: Add other features state and data in the future */
3632           }
3633 
3634           error = copyout(&f, uptr, sizeof (f));
3635           return (error);
3636 }
3637 
3638 /*
3639  * Give the userland some information about the container.  The AAC arch
3640  * expects the driver to be a SCSI passthrough type driver, so it expects
3641  * the containers to have b:t:l numbers.  Fake it.
3642  */
3643 static int
aac_query_disk(struct aac_softc * sc,caddr_t uptr)3644 aac_query_disk(struct aac_softc *sc, caddr_t uptr)
3645 {
3646           struct aac_query_disk query_disk;
3647           struct aac_container *co;
3648           struct aac_disk     *disk;
3649           int error, id;
3650 
3651           fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3652 
3653           disk = NULL;
3654 
3655           error = copyin(uptr, (caddr_t)&query_disk,
3656                            sizeof(struct aac_query_disk));
3657           if (error)
3658                     return (error);
3659 
3660           id = query_disk.ContainerNumber;
3661           if (id == -1)
3662                     return (EINVAL);
3663 
3664           lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
3665           TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
3666                     if (co->co_mntobj.ObjectId == id)
3667                               break;
3668                     }
3669 
3670           if (co == NULL) {
3671                               query_disk.Valid = 0;
3672                               query_disk.Locked = 0;
3673                               query_disk.Deleted = 1;                 /* XXX is this right? */
3674           } else {
3675                     disk = device_get_softc(co->co_disk);
3676                     query_disk.Valid = 1;
3677                     query_disk.Locked =
3678                         (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
3679                     query_disk.Deleted = 0;
3680                     query_disk.Bus = device_get_unit(sc->aac_dev);
3681                     query_disk.Target = disk->unit;
3682                     query_disk.Lun = 0;
3683                     query_disk.UnMapped = 0;
3684                     bcopy(disk->ad_dev_t->si_name,
3685                           &query_disk.diskDeviceName[0], 10);
3686           }
3687           lockmgr(&sc->aac_container_lock, LK_RELEASE);
3688 
3689           error = copyout((caddr_t)&query_disk, uptr,
3690                               sizeof(struct aac_query_disk));
3691 
3692           return (error);
3693 }
3694 
3695 static void
aac_get_bus_info(struct aac_softc * sc)3696 aac_get_bus_info(struct aac_softc *sc)
3697 {
3698           struct aac_fib *fib;
3699           struct aac_ctcfg *c_cmd;
3700           struct aac_ctcfg_resp *c_resp;
3701           struct aac_vmioctl *vmi;
3702           struct aac_vmi_businf_resp *vmi_resp;
3703           struct aac_getbusinf businfo;
3704           struct aac_sim *caminf;
3705           device_t child;
3706           int i, found, error;
3707 
3708           lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
3709           aac_alloc_sync_fib(sc, &fib);
3710           c_cmd = (struct aac_ctcfg *)&fib->data[0];
3711           bzero(c_cmd, sizeof(struct aac_ctcfg));
3712 
3713           c_cmd->Command = VM_ContainerConfig;
3714           c_cmd->cmd = CT_GET_SCSI_METHOD;
3715           c_cmd->param = 0;
3716 
3717           error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3718               sizeof(struct aac_ctcfg));
3719           if (error) {
3720                     device_printf(sc->aac_dev, "Error %d sending "
3721                         "VM_ContainerConfig command\n", error);
3722                     aac_release_sync_fib(sc);
3723                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
3724                     return;
3725           }
3726 
3727           c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
3728           if (c_resp->Status != ST_OK) {
3729                     device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
3730                         c_resp->Status);
3731                     aac_release_sync_fib(sc);
3732                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
3733                     return;
3734           }
3735 
3736           sc->scsi_method_id = c_resp->param;
3737 
3738           vmi = (struct aac_vmioctl *)&fib->data[0];
3739           bzero(vmi, sizeof(struct aac_vmioctl));
3740 
3741           vmi->Command = VM_Ioctl;
3742           vmi->ObjType = FT_DRIVE;
3743           vmi->MethId = sc->scsi_method_id;
3744           vmi->ObjId = 0;
3745           vmi->IoctlCmd = GetBusInfo;
3746 
3747           error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3748               sizeof(struct aac_vmi_businf_resp));
3749           if (error) {
3750                     device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
3751                         error);
3752                     aac_release_sync_fib(sc);
3753                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
3754                     return;
3755           }
3756 
3757           vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
3758           if (vmi_resp->Status != ST_OK) {
3759                     device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
3760                         vmi_resp->Status);
3761                     aac_release_sync_fib(sc);
3762                     lockmgr(&sc->aac_io_lock, LK_RELEASE);
3763                     return;
3764           }
3765 
3766           bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
3767           aac_release_sync_fib(sc);
3768           lockmgr(&sc->aac_io_lock, LK_RELEASE);
3769 
3770           found = 0;
3771           for (i = 0; i < businfo.BusCount; i++) {
3772                     if (businfo.BusValid[i] != AAC_BUS_VALID)
3773                               continue;
3774 
3775                     caminf = (struct aac_sim *)kmalloc(sizeof(struct aac_sim),
3776                         M_AACBUF, M_INTWAIT | M_ZERO);
3777 
3778                     child = device_add_child(sc->aac_dev, "aacp", -1);
3779                     if (child == NULL) {
3780                               device_printf(sc->aac_dev,
3781                                   "device_add_child failed for passthrough bus %d\n",
3782                                   i);
3783                               kfree(caminf, M_AACBUF);
3784                               break;
3785                     }
3786 
3787                     caminf->TargetsPerBus = businfo.TargetsPerBus;
3788                     caminf->BusNumber = i;
3789                     caminf->InitiatorBusId = businfo.InitiatorBusId[i];
3790                     caminf->aac_sc = sc;
3791                     caminf->sim_dev = child;
3792 
3793                     device_set_ivars(child, caminf);
3794                     device_set_desc(child, "SCSI Passthrough Bus");
3795                     TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
3796 
3797                     found = 1;
3798           }
3799 
3800           if (found)
3801                     bus_generic_attach(sc->aac_dev);
3802 }
3803