1 /*	$OpenBSD: aac.c,v 1.19 2004/03/20 03:58:09 aaron Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 Michael Smith
5  * Copyright (c) 2000 BSDi
6  * Copyright (c) 2000 Niklas Hallqvist
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  *	$FreeBSD: /c/ncvs/src/sys/dev/aac/aac.c,v 1.1 2000/09/13 03:20:34 msmith Exp $
31  */
32 
33 /*
34  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
35  */
36 
37 /*
38  * This driver would not have rewritten for OpenBSD if it was not for the
39  * hardware donation from Nocom.  I want to thank them for their support.
40  * Of course, credit should go to Mike Smith for the original work he did
41  * in the FreeBSD driver where I found lots of reusable code and inspiration.
42  * - Niklas Hallqvist
43  */
44 
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/buf.h>
48 #include <sys/device.h>
49 #include <sys/kernel.h>
50 #include <sys/malloc.h>
51 
52 #include <machine/bus.h>
53 
54 #include <uvm/uvm_extern.h>
55 
56 #include <scsi/scsi_all.h>
57 #include <scsi/scsi_disk.h>
58 #include <scsi/scsiconf.h>
59 
60 #include <dev/ic/aacreg.h>
61 #include <dev/ic/aacvar.h>
62 #include <dev/ic/aac_tables.h>
63 
64 /* Geometry constants. */
65 #define AAC_MAXCYLS		1024
66 #define AAC_HEADS		64
67 #define AAC_SECS		32	/* mapping 64*32 */
68 #define AAC_MEDHEADS		127
69 #define AAC_MEDSECS		63	/* mapping 127*63 */
70 #define AAC_BIGHEADS		255
71 #define AAC_BIGSECS		63	/* mapping 255*63 */
72 #define AAC_SECS32		0x1f	/* round capacity */
73 
74 void	aac_bio_complete(struct aac_ccb *);
75 void	aac_complete(void *, int);
76 void	aac_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t);
77 struct scsi_xfer *aac_dequeue(struct aac_softc *);
78 int	aac_dequeue_fib(struct aac_softc *, int, u_int32_t *,
79     struct aac_fib **);
80 char   *aac_describe_code(struct aac_code_lookup *, u_int32_t);
81 void	aac_describe_controller(struct aac_softc *);
82 void	aac_enqueue(struct aac_softc *, struct scsi_xfer *, int);
83 void	aac_enqueue_ccb(struct aac_softc *, struct aac_ccb *);
84 int	aac_enqueue_fib(struct aac_softc *, int, struct aac_ccb *);
85 void	aac_eval_mapping(u_int32_t, int *, int *, int *);
86 int	aac_exec_ccb(struct aac_ccb *);
87 void	aac_free_ccb(struct aac_softc *, struct aac_ccb *);
88 struct aac_ccb *aac_get_ccb(struct aac_softc *, int);
89 #if 0
90 void	aac_handle_aif(struct aac_softc *, struct aac_aif_command *);
91 #endif
92 void	aac_host_command(struct aac_softc *);
93 void	aac_host_response(struct aac_softc *);
94 int	aac_init(struct aac_softc *);
95 int	aac_internal_cache_cmd(struct scsi_xfer *);
96 int	aac_map_command(struct aac_ccb *);
97 #ifdef AAC_DEBUG
98 void	aac_print_fib(struct aac_softc *, struct aac_fib *, char *);
99 #endif
100 int	aac_raw_scsi_cmd(struct scsi_xfer *);
101 int	aac_scsi_cmd(struct scsi_xfer *);
102 int	aac_start(struct aac_ccb *);
103 void	aac_start_ccbs(struct aac_softc *);
104 void	aac_startup(struct aac_softc *);
105 int	aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t,
106     u_int32_t, u_int32_t, u_int32_t, u_int32_t *);
107 int	aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t, void *,
108     u_int16_t, void *, u_int16_t *);
109 void	aac_timeout(void *);
110 void	aac_unmap_command(struct aac_ccb *);
111 void	aac_watchdog(void *);
112 
113 struct cfdriver aac_cd = {
114 	NULL, "aac", DV_DULL
115 };
116 
117 struct scsi_adapter aac_switch = {
118 	aac_scsi_cmd, aacminphys, 0, 0,
119 };
120 
121 struct scsi_adapter aac_raw_switch = {
122 	aac_raw_scsi_cmd, aacminphys, 0, 0,
123 };
124 
125 struct scsi_device aac_dev = {
126 	NULL, NULL, NULL, NULL
127 };
128 
129 /* i960Rx interface */
130 int	aac_rx_get_fwstatus(struct aac_softc *);
131 void	aac_rx_qnotify(struct aac_softc *, int);
132 int	aac_rx_get_istatus(struct aac_softc *);
133 void	aac_rx_clear_istatus(struct aac_softc *, int);
134 void	aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
135     u_int32_t, u_int32_t, u_int32_t);
136 int	aac_rx_get_mailboxstatus(struct aac_softc *);
137 void	aac_rx_set_interrupts(struct aac_softc *, int);
138 
139 /* StrongARM interface */
140 int	aac_sa_get_fwstatus(struct aac_softc *);
141 void	aac_sa_qnotify(struct aac_softc *, int);
142 int	aac_sa_get_istatus(struct aac_softc *);
143 void	aac_sa_clear_istatus(struct aac_softc *, int);
144 void	aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
145     u_int32_t, u_int32_t, u_int32_t);
146 int	aac_sa_get_mailboxstatus(struct aac_softc *);
147 void	aac_sa_set_interrupts(struct aac_softc *, int);
148 
149 struct aac_interface aac_rx_interface = {
150 	aac_rx_get_fwstatus,
151 	aac_rx_qnotify,
152 	aac_rx_get_istatus,
153 	aac_rx_clear_istatus,
154 	aac_rx_set_mailbox,
155 	aac_rx_get_mailboxstatus,
156 	aac_rx_set_interrupts
157 };
158 
159 struct aac_interface aac_sa_interface = {
160 	aac_sa_get_fwstatus,
161 	aac_sa_qnotify,
162 	aac_sa_get_istatus,
163 	aac_sa_clear_istatus,
164 	aac_sa_set_mailbox,
165 	aac_sa_get_mailboxstatus,
166 	aac_sa_set_interrupts
167 };
168 
169 #ifdef AAC_DEBUG
170 int	aac_debug = AAC_DEBUG;
171 #endif
172 
173 int
aac_attach(sc)174 aac_attach(sc)
175 	struct aac_softc *sc;
176 {
177 	int i, error;
178 	bus_dma_segment_t seg;
179 	int nsegs;
180 	struct aac_ccb *ccb;
181 
182 	TAILQ_INIT(&sc->sc_free_ccb);
183 	TAILQ_INIT(&sc->sc_ccbq);
184 	TAILQ_INIT(&sc->sc_completed);
185 	LIST_INIT(&sc->sc_queue);
186 
187 	/* disable interrupts before we enable anything */
188 	AAC_MASK_INTERRUPTS(sc);
189 
190 	/* mark controller as suspended until we get ourselves organised */
191 	sc->sc_state |= AAC_STATE_SUSPEND;
192 
193 	/*
194 	 * Initialise the adapter.
195 	 */
196 	error = aac_init(sc);
197 	if (error)
198 		return (error);
199 
200 	/*
201 	 * Print a little information about the controller.
202 	 */
203 	aac_describe_controller(sc);
204 
205 	/* Initialize the ccbs */
206 	for (i = 0; i < AAC_ADAP_NORM_CMD_ENTRIES; i++) {
207 		ccb = &sc->sc_ccbs[i];
208 		error = bus_dmamap_create(sc->sc_dmat,
209 		    (AAC_MAXSGENTRIES - 1) << PGSHIFT, AAC_MAXSGENTRIES,
210 		    (AAC_MAXSGENTRIES - 1) << PGSHIFT, 0,
211 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &ccb->ac_dmamap_xfer);
212 		if (error) {
213 			printf("%s: cannot create ccb dmamap (%d)",
214 			    sc->sc_dev.dv_xname, error);
215 			/* XXX cleanup */
216 			return (1);
217 		}
218 
219 		/* allocate the FIB cluster in DMAable memory and load it */
220 		if (bus_dmamem_alloc(sc->sc_dmat, sizeof *ccb->ac_fib, 1, 0,
221 		    &seg, 1, &nsegs, BUS_DMA_NOWAIT)) {
222 			printf("%s: can't allocate FIB structure\n",
223 			    sc->sc_dev.dv_xname);
224 			/* XXX cleanup */
225 			return (1);
226 		}
227 		ccb->ac_fibphys = seg.ds_addr;
228 		if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs,
229 		    sizeof *ccb->ac_fib, (caddr_t *)&ccb->ac_fib, 0)) {
230 			printf("%s: can't map FIB structure\n",
231 			    sc->sc_dev.dv_xname);
232 			/* XXX cleanup */
233 			return (1);
234 		}
235 
236 		TAILQ_INSERT_TAIL(&sc->sc_free_ccb, &sc->sc_ccbs[i],
237 		    ac_chain);
238 	}
239 
240 	/* Fill in the prototype scsi_link. */
241 	sc->sc_link.adapter_softc = sc;
242 	sc->sc_link.adapter = &aac_switch;
243 	sc->sc_link.device = &aac_dev;
244 	/*
245 	 * XXX Theoretically this should be AAC_ADAP_NORM_CMD_ENTRIES but
246 	 * XXX in some configurations this can cause "not queued" errors.
247 	 * XXX A quarter of that number has been reported to be safe.
248 	 */
249 	sc->sc_link.openings = AAC_ADAP_NORM_CMD_ENTRIES / 4;
250 	sc->sc_link.adapter_buswidth = AAC_MAX_CONTAINERS;
251 	sc->sc_link.adapter_target = AAC_MAX_CONTAINERS;
252 
253 	config_found(&sc->sc_dev, &sc->sc_link, scsiprint);
254 
255 	return (0);
256 }
257 
258 /*
259  * Look up a text description of a numeric error code and return a pointer to
260  * same.
261  */
262 char *
aac_describe_code(table,code)263 aac_describe_code(table, code)
264 	struct aac_code_lookup *table;
265 	u_int32_t code;
266 {
267 	int i;
268 
269 	for (i = 0; table[i].string != NULL; i++)
270 		if (table[i].code == code)
271 			return (table[i].string);
272 	return (table[i + 1].string);
273 }
274 
275 void
aac_describe_controller(sc)276 aac_describe_controller(sc)
277 	struct aac_softc *sc;
278 {
279 	u_int8_t buf[AAC_FIB_DATASIZE];	/* XXX a bit big for the stack */
280 	u_int16_t bufsize;
281 	struct aac_adapter_info *info;
282 	u_int8_t arg;
283 
284 	arg = 0;
285 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof arg, &buf,
286 	    &bufsize)) {
287 		printf("%s: RequestAdapterInfo failed\n", sc->sc_dev.dv_xname);
288 		return;
289 	}
290 	if (bufsize != sizeof *info) {
291 		printf("%s: "
292 		    "RequestAdapterInfo returned wrong data size (%d != %d)\n",
293 		    sc->sc_dev.dv_xname, bufsize, sizeof *info);
294 		return;
295 	}
296 	info = (struct aac_adapter_info *)&buf[0];
297 
298 	printf("%s: %s %dMHz, %dMB, %s (%d) Kernel %d.%d-%d\n",
299 	    sc->sc_dev.dv_xname,
300 	    aac_describe_code(aac_cpu_variant, info->CpuVariant),
301 	    info->ClockSpeed, info->TotalMem / (1024 * 1024),
302 	    aac_describe_code(aac_battery_platform, info->batteryPlatform),
303 	    info->batteryPlatform, info->KernelRevision.external.comp.major,
304 	    info->KernelRevision.external.comp.minor,
305 	    info->KernelRevision.external.comp.dash);
306 
307 	/* save the kernel revision structure for later use */
308 	sc->sc_revision = info->KernelRevision;
309 }
310 
311 int
aac_init(sc)312 aac_init(sc)
313 	struct aac_softc *sc;
314 {
315 	bus_dma_segment_t seg;
316 	int nsegs;
317 	int i, error;
318 	int state = 0;
319 	struct aac_adapter_init	*ip;
320 	u_int32_t code;
321 	u_int8_t *qaddr;
322 
323 	/*
324 	 * First wait for the adapter to come ready.
325 	 */
326 	for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
327 		code = AAC_GET_FWSTATUS(sc);
328 		if (code & AAC_SELF_TEST_FAILED) {
329 			printf("%s: FATAL: selftest failed\n",
330 			    sc->sc_dev.dv_xname);
331 			return (ENXIO);
332 		}
333 		if (code & AAC_KERNEL_PANIC) {
334 			printf("%s: FATAL: controller kernel panic\n",
335 			    sc->sc_dev.dv_xname);
336 			return (ENXIO);
337 		}
338 		if (code & AAC_UP_AND_RUNNING)
339 			break;
340 		DELAY(1000);
341 	}
342 	if (i == AAC_BOOT_TIMEOUT * 1000) {
343 		printf("%s: FATAL: controller not coming ready, status %x\n",
344 		    sc->sc_dev.dv_xname, code);
345 		return (ENXIO);
346 	}
347 
348 	if (bus_dmamem_alloc(sc->sc_dmat, sizeof *sc->sc_common, 1, 0, &seg, 1,
349 	    &nsegs, BUS_DMA_NOWAIT)) {
350 		printf("%s: can't allocate common structure\n",
351 		    sc->sc_dev.dv_xname);
352 		return (ENOMEM);
353 	}
354 	state++;
355 	sc->sc_common_busaddr = seg.ds_addr;
356 	if (bus_dmamem_map(sc->sc_dmat, &seg, nsegs, sizeof *sc->sc_common,
357 	    (caddr_t *)&sc->sc_common, 0)) {
358 		printf("%s: can't map common structure\n",
359 		    sc->sc_dev.dv_xname);
360 		error = ENOMEM;
361 		goto bail_out;
362 	}
363 	state++;
364 	bzero(sc->sc_common, sizeof *sc->sc_common);
365 
366 	/*
367 	 * Fill in the init structure.  This tells the adapter about
368 	 * the physical location * of various important shared data
369 	 * structures.
370 	 */
371 	ip = &sc->sc_common->ac_init;
372 	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
373 
374 	ip->AdapterFibsPhysicalAddress =
375 	    sc->sc_common_busaddr + offsetof(struct aac_common, ac_fibs);
376 	ip->AdapterFibsVirtualAddress = &sc->sc_common->ac_fibs[0];
377 	ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
378 	ip->AdapterFibAlign = sizeof(struct aac_fib);
379 
380 	ip->PrintfBufferAddress =
381 	    sc->sc_common_busaddr + offsetof(struct aac_common, ac_printf);
382 	ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
383 
384 	ip->HostPhysMemPages = 0;	/* not used? */
385 	ip->HostElapsedSeconds = 0;	/* reset later if invalid */
386 
387 	/*
388 	 * Initialise FIB queues.  Note that it appears that the
389 	 * layout of the indexes and the segmentation of the entries
390 	 * is mandated by the adapter, which is only told about the
391 	 * base of the queue index fields.
392 	 *
393 	 * The initial values of the indices are assumed to inform the
394 	 * adapter of the sizes of the respective queues.
395 	 *
396 	 * The Linux driver uses a much more complex scheme whereby
397 	 * several header * records are kept for each queue.  We use a
398 	 * couple of generic list manipulation functions which
399 	 * 'know' the size of each list by virtue of a table.
400 	 */
401 	qaddr = &sc->sc_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
402 	qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN; 	/* XXX not portable */
403 	sc->sc_queues = (struct aac_queue_table *)qaddr;
404 	ip->CommHeaderAddress = sc->sc_common_busaddr +
405 	    ((char *)sc->sc_queues - (char *)sc->sc_common);
406 	bzero(sc->sc_queues, sizeof(struct aac_queue_table));
407 
408 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
409 	    AAC_HOST_NORM_CMD_ENTRIES;
410 	sc->sc_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
411 	    AAC_HOST_NORM_CMD_ENTRIES;
412 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
413 	    AAC_HOST_HIGH_CMD_ENTRIES;
414 	sc->sc_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
415 	    AAC_HOST_HIGH_CMD_ENTRIES;
416 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
417 	    AAC_ADAP_NORM_CMD_ENTRIES;
418 	sc->sc_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
419 	    AAC_ADAP_NORM_CMD_ENTRIES;
420 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
421 	    AAC_ADAP_HIGH_CMD_ENTRIES;
422 	sc->sc_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
423 	    AAC_ADAP_HIGH_CMD_ENTRIES;
424 	sc->sc_queues->
425 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] =
426 	    AAC_HOST_NORM_RESP_ENTRIES;
427 	sc->sc_queues->
428 	    qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] =
429 	    AAC_HOST_NORM_RESP_ENTRIES;
430 	sc->sc_queues->
431 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] =
432 	    AAC_HOST_HIGH_RESP_ENTRIES;
433 	sc->sc_queues->
434 	    qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] =
435 	    AAC_HOST_HIGH_RESP_ENTRIES;
436 	sc->sc_queues->
437 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX] =
438 	    AAC_ADAP_NORM_RESP_ENTRIES;
439 	sc->sc_queues->
440 	    qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX] =
441 	    AAC_ADAP_NORM_RESP_ENTRIES;
442 	sc->sc_queues->
443 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX] =
444 	    AAC_ADAP_HIGH_RESP_ENTRIES;
445 	sc->sc_queues->
446 	    qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX] =
447 	    AAC_ADAP_HIGH_RESP_ENTRIES;
448 	sc->sc_qentries[AAC_HOST_NORM_CMD_QUEUE] =
449 	    &sc->sc_queues->qt_HostNormCmdQueue[0];
450 	sc->sc_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
451 	    &sc->sc_queues->qt_HostHighCmdQueue[0];
452 	sc->sc_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
453 	    &sc->sc_queues->qt_AdapNormCmdQueue[0];
454 	sc->sc_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
455 	    &sc->sc_queues->qt_AdapHighCmdQueue[0];
456 	sc->sc_qentries[AAC_HOST_NORM_RESP_QUEUE] =
457 	    &sc->sc_queues->qt_HostNormRespQueue[0];
458 	sc->sc_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
459 	    &sc->sc_queues->qt_HostHighRespQueue[0];
460 	sc->sc_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
461 	    &sc->sc_queues->qt_AdapNormRespQueue[0];
462 	sc->sc_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
463 	    &sc->sc_queues->qt_AdapHighRespQueue[0];
464 
465 	/*
466 	 * Do controller-type-specific initialisation
467 	 */
468 	switch (sc->sc_hwif) {
469 	case AAC_HWIF_I960RX:
470 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
471 		break;
472 	}
473 
474 	/*
475 	 * Give the init structure to the controller.
476 	 */
477 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
478 	    sc->sc_common_busaddr + offsetof(struct aac_common, ac_init), 0, 0,
479 	    0, NULL)) {
480 		printf("%s: error establishing init structure\n",
481 		    sc->sc_dev.dv_xname);
482 		error = EIO;
483 		goto bail_out;
484 	}
485 
486 	aac_startup(sc);
487 
488 	return (0);
489 
490  bail_out:
491 	if (state > 1)
492 		bus_dmamem_unmap(sc->sc_dmat, (caddr_t)sc->sc_common,
493 		    sizeof *sc->sc_common);
494 	if (state > 0)
495 		bus_dmamem_free(sc->sc_dmat, &seg, 1);
496 	return (error);
497 }
498 
499 /*
500  * Probe for containers, create disks.
501  */
502 void
aac_startup(sc)503 aac_startup (sc)
504 	struct aac_softc *sc;
505 {
506 	struct aac_mntinfo mi;
507 	struct aac_mntinforesponse mir;
508 	u_int16_t rsize;
509 	int i, drv_cyls, drv_hds, drv_secs;
510 
511 	/* loop over possible containers */
512 	mi.Command = VM_NameServe;
513 	mi.MntType = FT_FILESYS;
514 	for (i = 0; i < AAC_MAX_CONTAINERS; i++) {
515 		/* request information on this container */
516 		mi.MntCount = i;
517 		if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof mi, &mir,
518 		    &rsize)) {
519 			printf("%s: error probing container %d",
520 			    sc->sc_dev.dv_xname, i);
521 			continue;
522 		}
523 		/* check response size */
524 		if (rsize != sizeof mir) {
525 			printf("%s: container info response wrong size "
526 			    "(%d should be %d)",
527 			    sc->sc_dev.dv_xname, rsize, sizeof mir);
528 			continue;
529 		}
530 
531 		/*
532 		 * Check container volume type for validity.  Note
533 		 * that many of the possible types * may never show
534 		 * up.
535 		 */
536 		if (mir.Status == ST_OK &&
537 		    mir.MntTable[0].VolType != CT_NONE) {
538 			AAC_DPRINTF(AAC_D_MISC,
539 			    ("%d: id %x  name '%.16s'  size %u  type %d", i,
540 			    mir.MntTable[0].ObjectId,
541 			    mir.MntTable[0].FileSystemName,
542 			    mir.MntTable[0].Capacity,
543 			    mir.MntTable[0].VolType));
544 
545 			sc->sc_hdr[i].hd_present = 1;
546 			sc->sc_hdr[i].hd_size = mir.MntTable[0].Capacity;
547 
548 			/*
549 			 * Evaluate mapping (sectors per head, heads per cyl)
550 			 */
551 			sc->sc_hdr[i].hd_size &= ~AAC_SECS32;
552 			aac_eval_mapping(sc->sc_hdr[i].hd_size, &drv_cyls,
553 			    &drv_hds, &drv_secs);
554 			sc->sc_hdr[i].hd_heads = drv_hds;
555 			sc->sc_hdr[i].hd_secs = drv_secs;
556 			/* Round the size */
557 			sc->sc_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs;
558 
559 			sc->sc_hdr[i].hd_devtype = mir.MntTable[0].VolType;
560 
561 			/* XXX Save the name too for use in IDENTIFY later */
562 		}
563 	}
564 
565 	/* mark the controller up */
566 	sc->sc_state &= ~AAC_STATE_SUSPEND;
567 
568 	/* enable interrupts now */
569 	AAC_UNMASK_INTERRUPTS(sc);
570 }
571 
572 void
aac_eval_mapping(size,cyls,heads,secs)573 aac_eval_mapping(size, cyls, heads, secs)
574 	u_int32_t size;
575 	int *cyls, *heads, *secs;
576 {
577 	*cyls = size / AAC_HEADS / AAC_SECS;
578 	if (*cyls < AAC_MAXCYLS) {
579 		*heads = AAC_HEADS;
580 		*secs = AAC_SECS;
581 	} else {
582 		/* Too high for 64 * 32 */
583 		*cyls = size / AAC_MEDHEADS / AAC_MEDSECS;
584 		if (*cyls < AAC_MAXCYLS) {
585 			*heads = AAC_MEDHEADS;
586 			*secs = AAC_MEDSECS;
587 		} else {
588 			/* Too high for 127 * 63 */
589 			*cyls = size / AAC_BIGHEADS / AAC_BIGSECS;
590 			*heads = AAC_BIGHEADS;
591 			*secs = AAC_BIGSECS;
592 		}
593 	}
594 }
595 
596 int
aac_raw_scsi_cmd(xs)597 aac_raw_scsi_cmd(xs)
598 	struct scsi_xfer *xs;
599 {
600 	AAC_DPRINTF(AAC_D_CMD, ("aac_raw_scsi_cmd "));
601 
602 	/* XXX Not yet implemented */
603 	xs->error = XS_DRIVER_STUFFUP;
604 	return (COMPLETE);
605 }
606 
607 int
aac_scsi_cmd(xs)608 aac_scsi_cmd(xs)
609 	struct scsi_xfer *xs;
610 {
611 	struct scsi_link *link = xs->sc_link;
612 	struct aac_softc *sc = link->adapter_softc;
613 	u_int8_t target = link->target;
614 	struct aac_ccb *ccb;
615 	u_int32_t blockno, blockcnt;
616 	struct scsi_rw *rw;
617 	struct scsi_rw_big *rwb;
618 	aac_lock_t lock;
619 	int retval = SUCCESSFULLY_QUEUED;
620 
621 	AAC_DPRINTF(AAC_D_CMD, ("aac_scsi_cmd "));
622 
623 	xs->error = XS_NOERROR;
624 
625 	if (target >= AAC_MAX_CONTAINERS || !sc->sc_hdr[target].hd_present ||
626 	    link->lun != 0) {
627 		/*
628 		 * XXX Should be XS_SENSE but that would require setting up a
629 		 * faked sense too.
630 		 */
631 		xs->error = XS_DRIVER_STUFFUP;
632 		xs->flags |= ITSDONE;
633 		scsi_done(xs);
634 		return (COMPLETE);
635 	}
636 
637 	lock = AAC_LOCK(sc);
638 
639 	/* Don't double enqueue if we came from aac_chain. */
640 	if (xs != LIST_FIRST(&sc->sc_queue))
641 		aac_enqueue(sc, xs, 0);
642 
643 	while ((xs = aac_dequeue(sc))) {
644 		xs->error = XS_NOERROR;
645 		ccb = NULL;
646 		link = xs->sc_link;
647 		target = link->target;
648 
649 		switch (xs->cmd->opcode) {
650 		case TEST_UNIT_READY:
651 		case REQUEST_SENSE:
652 		case INQUIRY:
653 		case MODE_SENSE:
654 		case START_STOP:
655 		case READ_CAPACITY:
656 #if 0
657 		case VERIFY:
658 #endif
659 			if (!aac_internal_cache_cmd(xs)) {
660 				AAC_UNLOCK(sc, lock);
661 				return (TRY_AGAIN_LATER);
662 			}
663 			xs->flags |= ITSDONE;
664 			scsi_done(xs);
665 			goto ready;
666 
667 		case PREVENT_ALLOW:
668 			AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW "));
669 			/* XXX Not yet implemented */
670 			xs->error = XS_NOERROR;
671 			xs->flags |= ITSDONE;
672 			scsi_done(xs);
673 			goto ready;
674 
675 		case SYNCHRONIZE_CACHE:
676 			AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE "));
677 			/* XXX Not yet implemented */
678 			xs->error = XS_NOERROR;
679 			xs->flags |= ITSDONE;
680 			scsi_done(xs);
681 			goto ready;
682 
683 		default:
684 			AAC_DPRINTF(AAC_D_CMD,
685 			    ("unknown opc %d ", xs->cmd->opcode));
686 			/* XXX Not yet implemented */
687 			xs->error = XS_DRIVER_STUFFUP;
688 			xs->flags |= ITSDONE;
689 			scsi_done(xs);
690 			goto ready;
691 
692 		case READ_COMMAND:
693 		case READ_BIG:
694 		case WRITE_COMMAND:
695 		case WRITE_BIG:
696 			AAC_DPRINTF(AAC_D_CMD,
697 			    ("rw opc %d ", xs->cmd->opcode));
698 
699 			if (xs->cmd->opcode != SYNCHRONIZE_CACHE) {
700 				/* A read or write operation. */
701 				if (xs->cmdlen == 6) {
702 					rw = (struct scsi_rw *)xs->cmd;
703 					blockno = _3btol(rw->addr) &
704 					    (SRW_TOPADDR << 16 | 0xffff);
705 					blockcnt =
706 					    rw->length ? rw->length : 0x100;
707 				} else {
708 					rwb = (struct scsi_rw_big *)xs->cmd;
709 					blockno = _4btol(rwb->addr);
710 					blockcnt = _2btol(rwb->length);
711 				}
712 				if (blockno >= sc->sc_hdr[target].hd_size ||
713 				    blockno + blockcnt >
714 				    sc->sc_hdr[target].hd_size) {
715 					printf(
716 					    "%s: out of bounds %u-%u >= %u\n",
717 					    sc->sc_dev.dv_xname, blockno,
718 					    blockcnt,
719 					    sc->sc_hdr[target].hd_size);
720 					/*
721 					 * XXX Should be XS_SENSE but that
722 					 * would require setting up a faked
723 					 * sense too.
724 					 */
725 					xs->error = XS_DRIVER_STUFFUP;
726 					xs->flags |= ITSDONE;
727 					scsi_done(xs);
728 					goto ready;
729 				}
730 			}
731 
732 			ccb = aac_get_ccb(sc, xs->flags);
733 
734 			/*
735 			 * We are out of commands, try again in a little while.
736 			 */
737 			if (ccb == NULL) {
738 				xs->error = XS_DRIVER_STUFFUP;
739 				AAC_UNLOCK(sc, lock);
740 				return (TRY_AGAIN_LATER);
741 			}
742 
743 			ccb->ac_blockno = blockno;
744 			ccb->ac_blockcnt = blockcnt;
745 			ccb->ac_xs = xs;
746 			ccb->ac_timeout = xs->timeout;
747 
748 			if (xs->cmd->opcode != SYNCHRONIZE_CACHE &&
749 			    aac_map_command(ccb)) {
750 				aac_free_ccb(sc, ccb);
751 				xs->error = XS_DRIVER_STUFFUP;
752 				xs->flags |= ITSDONE;
753 				scsi_done(xs);
754 				goto ready;
755 			}
756 
757 			aac_enqueue_ccb(sc, ccb);
758 			/* XXX what if enqueue did not start a transfer? */
759 			if (xs->flags & SCSI_POLL) {
760 #if 0
761 				if (!aac_wait(sc, ccb, ccb->ac_timeout)) {
762 					AAC_UNLOCK(sc, lock);
763 					printf("%s: command timed out\n",
764 					    sc->sc_dev.dv_xname);
765 					xs->error = XS_TIMEOUT;
766 					return (TRY_AGAIN_LATER);
767 				}
768 				xs->flags |= ITSDONE;
769 				scsi_done(xs);
770 #endif
771 			}
772 		}
773 
774 	ready:
775 		/*
776 		 * Don't process the queue if we are polling.
777 		 */
778 		if (xs->flags & SCSI_POLL) {
779 			retval = COMPLETE;
780 			break;
781 		}
782 	}
783 
784 	AAC_UNLOCK(sc, lock);
785 	return (retval);
786 }
787 
788 void
aac_copy_internal_data(xs,data,size)789 aac_copy_internal_data(xs, data, size)
790 	struct scsi_xfer *xs;
791 	u_int8_t *data;
792 	size_t size;
793 {
794 	size_t copy_cnt;
795 
796 	AAC_DPRINTF(AAC_D_MISC, ("aac_copy_internal_data "));
797 
798 	if (!xs->datalen)
799 		printf("uio move not yet supported\n");
800 	else {
801 		copy_cnt = MIN(size, xs->datalen);
802 		bcopy(data, xs->data, copy_cnt);
803 	}
804 }
805 
806 /* Emulated SCSI operation on cache device */
807 int
aac_internal_cache_cmd(xs)808 aac_internal_cache_cmd(xs)
809 	struct scsi_xfer *xs;
810 {
811 	struct scsi_link *link = xs->sc_link;
812 	struct aac_softc *sc = link->adapter_softc;
813 	struct scsi_inquiry_data inq;
814 	struct scsi_sense_data sd;
815 	struct {
816 		struct scsi_mode_header hd;
817 		struct scsi_blk_desc bd;
818 		union scsi_disk_pages dp;
819 	} mpd;
820 	struct scsi_read_cap_data rcd;
821 	u_int8_t target = link->target;
822 
823 	AAC_DPRINTF(AAC_D_CMD, ("aac_internal_cache_cmd "));
824 
825 	switch (xs->cmd->opcode) {
826 	case TEST_UNIT_READY:
827 	case START_STOP:
828 #if 0
829 	case VERIFY:
830 #endif
831 		AAC_DPRINTF(AAC_D_CMD, ("opc %d tgt %d ", xs->cmd->opcode,
832 		    target));
833 		break;
834 
835 	case REQUEST_SENSE:
836 		AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target));
837 		bzero(&sd, sizeof sd);
838 		sd.error_code = 0x70;
839 		sd.segment = 0;
840 		sd.flags = SKEY_NO_SENSE;
841 		aac_enc32(sd.info, 0);
842 		sd.extra_len = 0;
843 		aac_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd);
844 		break;
845 
846 	case INQUIRY:
847 		AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target,
848 		    sc->sc_hdr[target].hd_devtype));
849 		bzero(&inq, sizeof inq);
850 		/* XXX How do we detect removable/CD-ROM devices?  */
851 		inq.device = T_DIRECT;
852 		inq.dev_qual2 = 0;
853 		inq.version = 2;
854 		inq.response_format = 2;
855 		inq.additional_length = 32;
856 		strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor);
857 		snprintf(inq.product, sizeof inq.product, "Container #%02d",
858 		    target);
859 		strlcpy(inq.revision, "   ", sizeof inq.revision);
860 		aac_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq);
861 		break;
862 
863 	case MODE_SENSE:
864 		AAC_DPRINTF(AAC_D_CMD, ("MODE SENSE tgt %d ", target));
865 
866 		bzero(&mpd, sizeof mpd);
867 		switch (((struct scsi_mode_sense *)xs->cmd)->page) {
868 		case 4:
869 			/* scsi_disk.h says this should be 0x16 */
870 			mpd.dp.rigid_geometry.pg_length = 0x16;
871 			mpd.hd.data_length = sizeof mpd.hd + sizeof mpd.bd +
872 			    mpd.dp.rigid_geometry.pg_length;
873 			mpd.hd.blk_desc_len = sizeof mpd.bd;
874 
875 			/* XXX */
876 			mpd.hd.dev_spec = 0;
877 			_lto3b(AAC_BLOCK_SIZE, mpd.bd.blklen);
878 			mpd.dp.rigid_geometry.pg_code = 4;
879 			_lto3b(sc->sc_hdr[target].hd_size /
880 			    sc->sc_hdr[target].hd_heads /
881 			    sc->sc_hdr[target].hd_secs,
882 			    mpd.dp.rigid_geometry.ncyl);
883 			mpd.dp.rigid_geometry.nheads =
884 			    sc->sc_hdr[target].hd_heads;
885 			aac_copy_internal_data(xs, (u_int8_t *)&mpd,
886 			    sizeof mpd);
887 			break;
888 
889 		default:
890 			printf("%s: mode sense page %d not simulated\n",
891 			    sc->sc_dev.dv_xname,
892 			    ((struct scsi_mode_sense *)xs->cmd)->page);
893 			xs->error = XS_DRIVER_STUFFUP;
894 			return (0);
895 		}
896 		break;
897 
898 	case READ_CAPACITY:
899 		AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target));
900 		bzero(&rcd, sizeof rcd);
901 		_lto4b(sc->sc_hdr[target].hd_size - 1, rcd.addr);
902 		_lto4b(AAC_BLOCK_SIZE, rcd.length);
903 		aac_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
904 		break;
905 
906 	default:
907 		printf("aac_internal_cache_cmd got bad opcode: %d\n",
908 		    xs->cmd->opcode);
909 		xs->error = XS_DRIVER_STUFFUP;
910 		return (0);
911 	}
912 
913 	xs->error = XS_NOERROR;
914 	return (1);
915 }
916 
917 /*
918  * Take an interrupt.
919  */
920 int
aac_intr(arg)921 aac_intr(arg)
922 	void *arg;
923 {
924 	struct aac_softc *sc = arg;
925 	u_int16_t reason;
926 	int claimed = 0;
927 
928 	AAC_DPRINTF(AAC_D_INTR, ("aac_intr(%p) ", sc));
929 
930 	reason = AAC_GET_ISTATUS(sc);
931 	AAC_DPRINTF(AAC_D_INTR, ("istatus 0x%04x ", reason));
932 
933 	/* controller wants to talk to the log?  XXX should we defer this? */
934 	if (reason & AAC_DB_PRINTF) {
935 		if (sc->sc_common->ac_printf[0]) {
936 			printf("%s: ** %.*s", sc->sc_dev.dv_xname,
937 			    AAC_PRINTF_BUFSIZE, sc->sc_common->ac_printf);
938 			sc->sc_common->ac_printf[0] = 0;
939 		}
940 		AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
941 		AAC_QNOTIFY(sc, AAC_DB_PRINTF);
942 		claimed = 1;
943 	}
944 
945 	/* Controller has a message for us? */
946 	if (reason & AAC_DB_COMMAND_READY) {
947 		aac_host_command(sc);
948 		AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
949 		claimed = 1;
950 	}
951 
952 	/* Controller has a response for us? */
953 	if (reason & AAC_DB_RESPONSE_READY) {
954 		aac_host_response(sc);
955 		AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
956 		claimed = 1;
957 	}
958 
959 	/*
960 	 * Spurious interrupts that we don't use - reset the mask and clear
961 	 * the interrupts.
962 	 */
963 	if (reason & (AAC_DB_SYNC_COMMAND | AAC_DB_COMMAND_NOT_FULL |
964             AAC_DB_RESPONSE_NOT_FULL)) {
965 		AAC_UNMASK_INTERRUPTS(sc);
966 		AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND |
967 		    AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL);
968 		claimed = 1;
969 	}
970 
971 	return (claimed);
972 }
973 
974 /*
975  * Handle notification of one or more FIBs coming from the controller.
976  */
977 void
aac_host_command(struct aac_softc * sc)978 aac_host_command(struct aac_softc *sc)
979 {
980 	struct aac_fib *fib;
981 	u_int32_t fib_size;
982 
983 	for (;;) {
984 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE, &fib_size,
985 		    &fib))
986 			break;	/* nothing to do */
987 
988 		switch(fib->Header.Command) {
989 		case AifRequest:
990 #if 0
991 			aac_handle_aif(sc,
992 			    (struct aac_aif_command *)&fib->data[0]);
993 #endif
994 
995 			break;
996 		default:
997 			printf("%s: unknown command from controller\n",
998 			    sc->sc_dev.dv_xname);
999 			AAC_PRINT_FIB(sc, fib);
1000 			break;
1001 		}
1002 
1003 		/* XXX reply to FIBs requesting responses ?? */
1004 		/* XXX how do we return these FIBs to the controller? */
1005 	}
1006 }
1007 
1008 /*
1009  * Handle notification of one or more FIBs completed by the controller
1010  */
1011 void
aac_host_response(struct aac_softc * sc)1012 aac_host_response(struct aac_softc *sc)
1013 {
1014 	struct aac_ccb *ccb;
1015 	struct aac_fib *fib;
1016 	u_int32_t fib_size;
1017 
1018 	for (;;) {
1019 		/* look for completed FIBs on our queue */
1020 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1021 		    &fib))
1022 			break;	/* nothing to do */
1023 
1024 		/* get the command, unmap and queue for later processing */
1025 		ccb = (struct aac_ccb *)fib->Header.SenderData;
1026 		if (ccb == NULL) {
1027 			AAC_PRINT_FIB(sc, fib);
1028 		} else {
1029 			timeout_del(&ccb->ac_xs->stimeout);
1030 			aac_unmap_command(ccb);		/* XXX defer? */
1031 			aac_enqueue_completed(ccb);
1032 		}
1033 	}
1034 
1035 	/* handle completion processing */
1036 	aac_complete(sc, 0);
1037 }
1038 
1039 /*
1040  * Process completed commands.
1041  */
1042 void
aac_complete(void * context,int pending)1043 aac_complete(void *context, int pending)
1044 {
1045 	struct aac_softc *sc = (struct aac_softc *)context;
1046 	struct aac_ccb *ccb;
1047 
1048 	/* pull completed commands off the queue */
1049 	for (;;) {
1050 		ccb = aac_dequeue_completed(sc);
1051 		if (ccb == NULL)
1052 			return;
1053 		ccb->ac_flags |= AAC_ACF_COMPLETED;
1054 
1055 #if 0
1056 		/* is there a completion handler? */
1057 		if (ccb->ac_complete != NULL) {
1058 			ccb->ac_complete(ccb);
1059 		} else {
1060 			/* assume that someone is sleeping on this command */
1061 			wakeup(ccb);
1062 		}
1063 #else
1064 		aac_bio_complete(ccb);
1065 #endif
1066 	}
1067 }
1068 
1069 /*
1070  * Handle a bio-instigated command that has been completed.
1071  */
1072 void
aac_bio_complete(struct aac_ccb * ccb)1073 aac_bio_complete(struct aac_ccb *ccb)
1074 {
1075 	struct scsi_xfer *xs = ccb->ac_xs;
1076 	struct aac_softc *sc = xs->sc_link->adapter_softc;
1077 	struct buf *bp = xs->bp;
1078 	struct aac_blockread_response *brr;
1079 	struct aac_blockwrite_response *bwr;
1080 	AAC_FSAStatus status;
1081 
1082 	/* fetch relevant status and then release the command */
1083 	if (bp->b_flags & B_READ) {
1084 		brr = (struct aac_blockread_response *)&ccb->ac_fib->data[0];
1085 		status = brr->Status;
1086 	} else {
1087 		bwr = (struct aac_blockwrite_response *)&ccb->ac_fib->data[0];
1088 		status = bwr->Status;
1089 	}
1090 	aac_free_ccb(sc, ccb);
1091 
1092 	/* fix up the bio based on status */
1093 	if (status == ST_OK) {
1094 		bp->b_resid = 0;
1095 	} else {
1096 		bp->b_error = EIO;
1097 		bp->b_flags |= B_ERROR;
1098 
1099 		/* XXX be more verbose? */
1100 		printf("%s: I/O error %d (%s)\n", sc->sc_dev.dv_xname,
1101 		    status, AAC_COMMAND_STATUS(status));
1102 	}
1103 	scsi_done(xs);
1104 }
1105 
1106 /*
1107  * Send a synchronous command to the controller and wait for a result.
1108  */
1109 int
aac_sync_command(sc,command,arg0,arg1,arg2,arg3,sp)1110 aac_sync_command(sc, command, arg0, arg1, arg2, arg3, sp)
1111 	struct aac_softc *sc;
1112 	u_int32_t command;
1113 	u_int32_t arg0;
1114 	u_int32_t arg1;
1115 	u_int32_t arg2;
1116 	u_int32_t arg3;
1117 	u_int32_t *sp;
1118 {
1119 	int i;
1120 	u_int32_t status;
1121 	aac_lock_t lock = AAC_LOCK(sc);
1122 
1123 	/* populate the mailbox */
1124 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1125 
1126 	/* ensure the sync command doorbell flag is cleared */
1127 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1128 
1129 	/* then set it to signal the adapter */
1130 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1131 	DELAY(AAC_SYNC_DELAY);
1132 
1133 	/* spin waiting for the command to complete */
1134 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
1135 		if (AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND)
1136 			break;
1137 		DELAY(1000);
1138 	}
1139 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
1140 		AAC_UNLOCK(sc, lock);
1141 		return (EIO);
1142 	}
1143 
1144 	/* clear the completion flag */
1145 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1146 
1147 	/* get the command status */
1148 	status = AAC_GET_MAILBOXSTATUS(sc);
1149 	AAC_UNLOCK(sc, lock);
1150 	if (sp != NULL)
1151 		*sp = status;
1152 	return (0);	/* check command return status? */
1153 }
1154 
1155 /*
1156  * Send a synchronous FIB to the controller and wait for a result.
1157  */
1158 int
aac_sync_fib(sc,command,xferstate,data,datasize,result,resultsize)1159 aac_sync_fib(sc, command, xferstate, data, datasize, result, resultsize)
1160 	struct aac_softc *sc;
1161 	u_int32_t command;
1162 	u_int32_t xferstate;
1163 	void *data;
1164 	u_int16_t datasize;
1165 	void *result;
1166 	u_int16_t *resultsize;
1167 {
1168 	struct aac_fib *fib = &sc->sc_common->ac_sync_fib;
1169 
1170 	if (datasize > AAC_FIB_DATASIZE)
1171 		return (EINVAL);
1172 
1173 	/*
1174 	 * Set up the sync FIB
1175 	 */
1176 	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1177 	    AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_EMPTY;
1178 	fib->Header.XferState |= xferstate;
1179 	fib->Header.Command = command;
1180 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
1181 	fib->Header.Size = sizeof fib + datasize;
1182 	fib->Header.SenderSize = sizeof *fib;
1183 	fib->Header.SenderFibAddress = (u_int32_t)fib;
1184 	fib->Header.ReceiverFibAddress =
1185 	    sc->sc_common_busaddr + offsetof(struct aac_common, ac_sync_fib);
1186 
1187 	/*
1188 	 * Copy in data.
1189 	 */
1190 	if (data != NULL) {
1191 		bcopy(data, fib->data, datasize);
1192 		fib->Header.XferState |=
1193 		    AAC_FIBSTATE_FROMHOST | AAC_FIBSTATE_NORM;
1194 	}
1195 
1196 	/*
1197 	 * Give the FIB to the controller, wait for a response.
1198 	 */
1199 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1200 	    fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1201 		return (EIO);
1202 	}
1203 
1204 	/*
1205 	 * Copy out the result
1206 	 */
1207 	if (result != NULL) {
1208 		*resultsize = fib->Header.Size - sizeof fib->Header;
1209 		bcopy(fib->data, result, *resultsize);
1210 	}
1211 	return (0);
1212 }
1213 
1214 void
aacminphys(bp)1215 aacminphys(bp)
1216 	struct buf *bp;
1217 {
1218 #if 0
1219 	u_int8_t *buf = bp->b_data;
1220 	paddr_t pa;
1221 	long off;
1222 #endif
1223 
1224 	AAC_DPRINTF(AAC_D_MISC, ("aacminphys(0x%x) ", bp));
1225 
1226 #if 1
1227 #if 0	/* As this is way more than MAXPHYS it's really not necessary. */
1228 	if (bp->b_bcount > ((AAC_MAXOFFSETS - 1) * PAGE_SIZE))
1229 		bp->b_bcount = ((AAC_MAXOFFSETS - 1) * PAGE_SIZE);
1230 #endif
1231 #else
1232 	for (off = PAGE_SIZE, pa = vtophys(buf); off < bp->b_bcount;
1233 	    off += PAGE_SIZE)
1234 		if (pa + off != vtophys(buf + off)) {
1235 			bp->b_bcount = off;
1236 			break;
1237 		}
1238 #endif
1239 	minphys(bp);
1240 }
1241 
1242 /*
1243  * Read the current firmware status word.
1244  */
1245 int
aac_sa_get_fwstatus(sc)1246 aac_sa_get_fwstatus(sc)
1247 	struct aac_softc *sc;
1248 {
1249 	return (AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1250 }
1251 
1252 int
aac_rx_get_fwstatus(sc)1253 aac_rx_get_fwstatus(sc)
1254 	struct aac_softc *sc;
1255 {
1256 	return (AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1257 }
1258 
1259 /*
1260  * Notify the controller of a change in a given queue
1261  */
1262 
1263 void
aac_sa_qnotify(sc,qbit)1264 aac_sa_qnotify(sc, qbit)
1265 	struct aac_softc *sc;
1266 	int qbit;
1267 {
1268 	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1269 }
1270 
1271 void
aac_rx_qnotify(sc,qbit)1272 aac_rx_qnotify(sc, qbit)
1273 	struct aac_softc *sc;
1274 	int qbit;
1275 {
1276 	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1277 }
1278 
1279 /*
1280  * Get the interrupt reason bits
1281  */
1282 int
aac_sa_get_istatus(sc)1283 aac_sa_get_istatus(sc)
1284 	struct aac_softc *sc;
1285 {
1286 	return (AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1287 }
1288 
1289 int
aac_rx_get_istatus(sc)1290 aac_rx_get_istatus(sc)
1291 	struct aac_softc *sc;
1292 {
1293 	return (AAC_GETREG4(sc, AAC_RX_ODBR));
1294 }
1295 
1296 /*
1297  * Clear some interrupt reason bits
1298  */
1299 void
aac_sa_clear_istatus(sc,mask)1300 aac_sa_clear_istatus(sc, mask)
1301 	struct aac_softc *sc;
1302 	int mask;
1303 {
1304 	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1305 }
1306 
1307 void
aac_rx_clear_istatus(sc,mask)1308 aac_rx_clear_istatus(sc, mask)
1309 	struct aac_softc *sc;
1310 	int mask;
1311 {
1312 	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1313 }
1314 
1315 /*
1316  * Populate the mailbox and set the command word
1317  */
1318 void
aac_sa_set_mailbox(sc,command,arg0,arg1,arg2,arg3)1319 aac_sa_set_mailbox(sc, command, arg0, arg1, arg2, arg3)
1320 	struct aac_softc *sc;
1321 	u_int32_t command;
1322 	u_int32_t arg0;
1323 	u_int32_t arg1;
1324 	u_int32_t arg2;
1325 	u_int32_t arg3;
1326 {
1327 	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1328 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1329 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1330 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1331 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1332 }
1333 
1334 void
aac_rx_set_mailbox(sc,command,arg0,arg1,arg2,arg3)1335 aac_rx_set_mailbox(sc, command, arg0, arg1, arg2, arg3)
1336 	struct aac_softc *sc;
1337 	u_int32_t command;
1338 	u_int32_t arg0;
1339 	u_int32_t arg1;
1340 	u_int32_t arg2;
1341 	u_int32_t arg3;
1342 {
1343 	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1344 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1345 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1346 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1347 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1348 }
1349 
1350 /*
1351  * Fetch the immediate command status word
1352  */
1353 int
aac_sa_get_mailboxstatus(sc)1354 aac_sa_get_mailboxstatus(sc)
1355 	struct aac_softc *sc;
1356 {
1357 	return (AAC_GETREG4(sc, AAC_SA_MAILBOX));
1358 }
1359 
1360 int
aac_rx_get_mailboxstatus(sc)1361 aac_rx_get_mailboxstatus(sc)
1362 	struct aac_softc *sc;
1363 {
1364 	return (AAC_GETREG4(sc, AAC_RX_MAILBOX));
1365 }
1366 
1367 /*
1368  * Set/clear interrupt masks
1369  */
1370 void
aac_sa_set_interrupts(sc,enable)1371 aac_sa_set_interrupts(sc, enable)
1372 	struct aac_softc *sc;
1373 	int enable;
1374 {
1375 	if (enable)
1376 		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
1377 	else
1378 		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
1379 }
1380 
1381 void
aac_rx_set_interrupts(sc,enable)1382 aac_rx_set_interrupts(sc, enable)
1383 	struct aac_softc *sc;
1384 	int enable;
1385 {
1386 	if (enable)
1387 		AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
1388 	else
1389 		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
1390 }
1391 
1392 struct aac_ccb *
aac_get_ccb(sc,flags)1393 aac_get_ccb(sc, flags)
1394 	struct aac_softc *sc;
1395 	int flags;
1396 {
1397 	struct aac_ccb *ccb;
1398 	aac_lock_t lock;
1399 
1400 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_get_ccb(%p, 0x%x) ", sc, flags));
1401 
1402 	lock = AAC_LOCK(sc);
1403 
1404 	for (;;) {
1405 		ccb = TAILQ_FIRST(&sc->sc_free_ccb);
1406 		if (ccb != NULL)
1407 			break;
1408 		if (flags & SCSI_NOSLEEP)
1409 			goto bail_out;
1410 		tsleep(&sc->sc_free_ccb, PRIBIO, "aac_ccb", 0);
1411 	}
1412 
1413 	TAILQ_REMOVE(&sc->sc_free_ccb, ccb, ac_chain);
1414 
1415 	/* initialise the command/FIB */
1416 	ccb->ac_sgtable = NULL;
1417 	ccb->ac_flags = 0;
1418 	ccb->ac_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1419 	ccb->ac_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1420 	ccb->ac_fib->Header.Flags = 0;
1421 	ccb->ac_fib->Header.SenderSize = sizeof(struct aac_fib);
1422 
1423 	/*
1424 	 * These are duplicated in aac_start to cover the case where an
1425 	 * intermediate stage may have destroyed them.  They're left
1426 	 * initialised here for debugging purposes only.
1427 	 */
1428 	ccb->ac_fib->Header.SenderFibAddress = (u_int32_t)ccb->ac_fib;
1429 	ccb->ac_fib->Header.ReceiverFibAddress = ccb->ac_fibphys;
1430 
1431  bail_out:
1432 	AAC_UNLOCK(sc, lock);
1433 	return (ccb);
1434 }
1435 
1436 void
aac_free_ccb(sc,ccb)1437 aac_free_ccb(sc, ccb)
1438 	struct aac_softc *sc;
1439 	struct aac_ccb *ccb;
1440 {
1441 	aac_lock_t lock;
1442 
1443 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_free_ccb(%p, %p) ", sc, ccb));
1444 
1445 	lock = AAC_LOCK(sc);
1446 
1447 	TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, ac_chain);
1448 
1449 	/* If the free list was empty, wake up potential waiters. */
1450 	if (TAILQ_NEXT(ccb, ac_chain) == NULL)
1451 		wakeup(&sc->sc_free_ccb);
1452 
1453 	AAC_UNLOCK(sc, lock);
1454 }
1455 
1456 void
aac_enqueue_ccb(sc,ccb)1457 aac_enqueue_ccb(sc, ccb)
1458 	struct aac_softc *sc;
1459 	struct aac_ccb *ccb;
1460 {
1461 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_enqueue_ccb(%p, %p) ", sc, ccb));
1462 
1463 	timeout_set(&ccb->ac_xs->stimeout, aac_timeout, ccb);
1464 	TAILQ_INSERT_TAIL(&sc->sc_ccbq, ccb, ac_chain);
1465 	aac_start_ccbs(sc);
1466 }
1467 
1468 void
aac_start_ccbs(sc)1469 aac_start_ccbs(sc)
1470 	struct aac_softc *sc;
1471 {
1472 	struct aac_ccb *ccb;
1473 	struct scsi_xfer *xs;
1474 
1475 	AAC_DPRINTF(AAC_D_QUEUE, ("aac_start_ccbs(%p) ", sc));
1476 
1477 	while ((ccb = TAILQ_FIRST(&sc->sc_ccbq)) != NULL) {
1478 
1479 		xs = ccb->ac_xs;
1480 		if (ccb->ac_flags & AAC_ACF_WATCHDOG)
1481 			timeout_del(&xs->stimeout);
1482 
1483 		if (aac_exec_ccb(ccb) == 0) {
1484 			ccb->ac_flags |= AAC_ACF_WATCHDOG;
1485 			timeout_set(&ccb->ac_xs->stimeout, aac_watchdog, ccb);
1486 			timeout_add(&xs->stimeout,
1487 			    (AAC_WATCH_TIMEOUT * hz) / 1000);
1488 			break;
1489 		}
1490 		TAILQ_REMOVE(&sc->sc_ccbq, ccb, ac_chain);
1491 
1492 		if ((xs->flags & SCSI_POLL) == 0) {
1493 			timeout_set(&ccb->ac_xs->stimeout, aac_timeout, ccb);
1494 			timeout_add(&xs->stimeout,
1495 			    (ccb->ac_timeout * hz) / 1000);
1496 		}
1497 	}
1498 }
1499 
1500 int
aac_exec_ccb(ccb)1501 aac_exec_ccb(ccb)
1502 	struct aac_ccb *ccb;
1503 {
1504 	struct scsi_xfer *xs = ccb->ac_xs;
1505 	struct scsi_link *link = xs->sc_link;
1506 	u_int8_t target = link->target;
1507 	int i;
1508 	struct aac_fib *fib;
1509 	struct aac_blockread *br;
1510 	struct aac_blockwrite *bw;
1511 	bus_dmamap_t xfer;
1512 
1513 	AAC_DPRINTF(AAC_D_CMD, ("aac_exec_ccb(%p, %p) ", xs, ccb));
1514 
1515 	/* build the FIB */
1516 	fib = ccb->ac_fib;
1517 	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1518 	    AAC_FIBSTATE_INITIALISED | AAC_FIBSTATE_FROMHOST |
1519 	    AAC_FIBSTATE_REXPECTED | AAC_FIBSTATE_NORM;
1520 	fib->Header.Command = ContainerCommand;
1521 	fib->Header.Size = sizeof(struct aac_fib_header);
1522 
1523 	switch (xs->cmd->opcode) {
1524 	case PREVENT_ALLOW:
1525 	case SYNCHRONIZE_CACHE:
1526 		if (xs->cmd->opcode == PREVENT_ALLOW) {
1527 			/* XXX PREVENT_ALLOW support goes here */
1528 		} else {
1529 			AAC_DPRINTF(AAC_D_CMD,
1530 			    ("SYNCHRONIZE CACHE tgt %d ", target));
1531 		}
1532 		break;
1533 
1534 	case WRITE_COMMAND:
1535 	case WRITE_BIG:
1536 		bw = (struct aac_blockwrite *)&fib->data[0];
1537 		bw->Command = VM_CtBlockWrite;
1538 		bw->ContainerId = target;
1539 		bw->BlockNumber = ccb->ac_blockno;
1540 		bw->ByteCount = ccb->ac_blockcnt * DEV_BSIZE;
1541 		bw->Stable = CUNSTABLE;	/* XXX what's appropriate here? */
1542 		fib->Header.Size += sizeof(struct aac_blockwrite);
1543 		ccb->ac_sgtable = &bw->SgMap;
1544 		break;
1545 
1546 	case READ_COMMAND:
1547 	case READ_BIG:
1548 		br = (struct aac_blockread *)&fib->data[0];
1549 		br->Command = VM_CtBlockRead;
1550 		br->ContainerId = target;
1551 		br->BlockNumber = ccb->ac_blockno;
1552 		br->ByteCount = ccb->ac_blockcnt * DEV_BSIZE;
1553 		fib->Header.Size += sizeof(struct aac_blockread);
1554 		ccb->ac_sgtable = &br->SgMap;
1555 		break;
1556 	}
1557 
1558 	if (xs->cmd->opcode != PREVENT_ALLOW &&
1559 	    xs->cmd->opcode != SYNCHRONIZE_CACHE) {
1560 		xfer = ccb->ac_dmamap_xfer;
1561 		ccb->ac_sgtable->SgCount = xfer->dm_nsegs;
1562 		for (i = 0; i < xfer->dm_nsegs; i++) {
1563 			ccb->ac_sgtable->SgEntry[i].SgAddress =
1564 			    xfer->dm_segs[i].ds_addr;
1565 			ccb->ac_sgtable->SgEntry[i].SgByteCount =
1566 			    xfer->dm_segs[i].ds_len;
1567 			AAC_DPRINTF(AAC_D_IO,
1568 			    ("#%d va %p pa %p len %x\n", i, buf,
1569 			    xfer->dm_segs[i].ds_addr,
1570 			    xfer->dm_segs[i].ds_len));
1571 		}
1572 
1573 		/* update the FIB size for the s/g count */
1574 		fib->Header.Size += xfer->dm_nsegs *
1575 		    sizeof(struct aac_sg_entry);
1576 	}
1577 
1578 	if (aac_start(ccb) == 0) {
1579 		xs->error = XS_NOERROR;
1580 		xs->resid = 0;
1581 		return (1);
1582 	}
1583 	return (0);
1584 }
1585 
1586 /********************************************************************************
1587  * Deliver a command to the controller; allocate controller resources at the
1588  * last moment when possible.
1589  */
1590 int
aac_start(struct aac_ccb * ccb)1591 aac_start(struct aac_ccb *ccb)
1592 {
1593 	struct aac_softc *sc = ccb->ac_xs->sc_link->adapter_softc;
1594 
1595 #if 0
1596 	/* get the command mapped */
1597 	aac_map_command(ccb);
1598 #endif
1599 
1600 	/* fix up the address values */
1601 	ccb->ac_fib->Header.SenderFibAddress = (u_int32_t)ccb->ac_fib;
1602 	ccb->ac_fib->Header.ReceiverFibAddress = ccb->ac_fibphys;
1603 
1604 	/* save a pointer to the command for speedy reverse-lookup */
1605 	ccb->ac_fib->Header.SenderData = (u_int32_t)ccb; /* XXX ack, sizing */
1606 
1607 	/* put the FIB on the outbound queue */
1608 	if (aac_enqueue_fib(sc, AAC_ADAP_NORM_CMD_QUEUE, ccb))
1609 		return (EBUSY);
1610 
1611 	return (0);
1612 }
1613 
1614 /*
1615  * Map a command into controller-visible space.
1616  */
1617 int
aac_map_command(struct aac_ccb * ccb)1618 aac_map_command(struct aac_ccb *ccb)
1619 {
1620 	struct scsi_xfer *xs = ccb->ac_xs;
1621 	struct aac_softc *sc = xs->sc_link->adapter_softc;
1622 	int error;
1623 
1624 #if 0
1625 	/* don't map more than once */
1626 	if (ccb->ac_flags & AAC_CMD_MAPPED)
1627 		return;
1628 #endif
1629 
1630 	if (xs->datalen != 0) {
1631 		error = bus_dmamap_load(sc->sc_dmat, ccb->ac_dmamap_xfer,
1632 		    xs->data, xs->datalen, NULL,
1633 		    (xs->flags & SCSI_NOSLEEP) ? BUS_DMA_NOWAIT :
1634 		    BUS_DMA_WAITOK);
1635 		if (error) {
1636 			printf("%s: aac_scsi_cmd: ", sc->sc_dev.dv_xname);
1637 			if (error == EFBIG)
1638 				printf("more than %d dma segs\n",
1639 				    AAC_MAXSGENTRIES);
1640 			else
1641 				printf("error %d loading dma map\n", error);
1642 			return (error);
1643 		}
1644 
1645 		bus_dmamap_sync(sc->sc_dmat, ccb->ac_dmamap_xfer, 0,
1646 		    ccb->ac_dmamap_xfer->dm_mapsize,
1647 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_PREREAD :
1648 		    BUS_DMASYNC_PREWRITE);
1649 	}
1650 
1651 #if 0
1652 	ccb->ac_flags |= AAC_CMD_MAPPED;
1653 #endif
1654 	return (0);
1655 }
1656 
1657 /*
1658  * Unmap a command from controller-visible space.
1659  */
1660 void
aac_unmap_command(struct aac_ccb * ccb)1661 aac_unmap_command(struct aac_ccb *ccb)
1662 {
1663 	struct scsi_xfer *xs = ccb->ac_xs;
1664 	struct aac_softc *sc = xs->sc_link->adapter_softc;
1665 
1666 #if 0
1667 	if (!(ccb->ac_flags & AAC_CMD_MAPPED))
1668 		return;
1669 #endif
1670 
1671 	if (xs->datalen != 0) {
1672 		bus_dmamap_sync(sc->sc_dmat, ccb->ac_dmamap_xfer, 0,
1673 		    ccb->ac_dmamap_xfer->dm_mapsize,
1674 		    (xs->flags & SCSI_DATA_IN) ? BUS_DMASYNC_POSTREAD :
1675 		    BUS_DMASYNC_POSTWRITE);
1676 
1677 		bus_dmamap_unload(sc->sc_dmat, ccb->ac_dmamap_xfer);
1678 	}
1679 #if 0
1680 	ccb->ac_flags &= ~AAC_CMD_MAPPED;
1681 #endif
1682 }
1683 
1684 void
aac_timeout(arg)1685 aac_timeout(arg)
1686 	void *arg;
1687 {
1688 	struct aac_ccb *ccb = arg;
1689 	struct scsi_link *link = ccb->ac_xs->sc_link;
1690 	struct aac_softc *sc = link->adapter_softc;
1691 	aac_lock_t lock;
1692 
1693 	sc_print_addr(link);
1694 	printf("timed out\n");
1695 
1696 	/* XXX Test for multiple timeouts */
1697 
1698 	ccb->ac_xs->error = XS_TIMEOUT;
1699 	lock = AAC_LOCK(sc);
1700 	aac_enqueue_ccb(sc, ccb);
1701 	AAC_UNLOCK(sc, lock);
1702 }
1703 
1704 void
aac_watchdog(arg)1705 aac_watchdog(arg)
1706 	void *arg;
1707 {
1708 	struct aac_ccb *ccb = arg;
1709 	struct scsi_link *link = ccb->ac_xs->sc_link;
1710 	struct aac_softc *sc = link->adapter_softc;
1711 	aac_lock_t lock;
1712 
1713 	lock = AAC_LOCK(sc);
1714 	ccb->ac_flags &= ~AAC_ACF_WATCHDOG;
1715 	aac_start_ccbs(sc);
1716 	AAC_UNLOCK(sc, lock);
1717 }
1718 /*
1719  * Insert a command into the driver queue, either at the front or at the tail.
1720  * It's ok to overload the freelist link as these structures are never on
1721  * the freelist at this time.
1722  */
1723 void
aac_enqueue(sc,xs,infront)1724 aac_enqueue(sc, xs, infront)
1725 	struct aac_softc *sc;
1726 	struct scsi_xfer *xs;
1727 	int infront;
1728 {
1729 	if (infront || LIST_FIRST(&sc->sc_queue) == NULL) {
1730 		if (LIST_FIRST(&sc->sc_queue) == NULL)
1731 			sc->sc_queuelast = xs;
1732 		LIST_INSERT_HEAD(&sc->sc_queue, xs, free_list);
1733 		return;
1734 	}
1735 	LIST_INSERT_AFTER(sc->sc_queuelast, xs, free_list);
1736 	sc->sc_queuelast = xs;
1737 }
1738 
1739 /*
1740  * Pull a command off the front of the driver queue.
1741  */
1742 struct scsi_xfer *
aac_dequeue(sc)1743 aac_dequeue(sc)
1744 	struct aac_softc *sc;
1745 {
1746 	struct scsi_xfer *xs;
1747 
1748 	xs = LIST_FIRST(&sc->sc_queue);
1749 	if (xs == NULL)
1750 		return (NULL);
1751 	LIST_REMOVE(xs, free_list);
1752 
1753 	if (LIST_FIRST(&sc->sc_queue) == NULL)
1754 		sc->sc_queuelast = NULL;
1755 
1756 	return (xs);
1757 }
1758 
1759 /********************************************************************************
1760  * Adapter-space FIB queue manipulation
1761  *
1762  * Note that the queue implementation here is a little funky; neither the PI or
1763  * CI will ever be zero.  This behaviour is a controller feature.
1764  */
1765 static struct {
1766 	int size;
1767 	int notify;
1768 } aac_qinfo[] = {
1769 	{ AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL },
1770 	{ AAC_HOST_HIGH_CMD_ENTRIES, 0 },
1771 	{ AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY },
1772 	{ AAC_ADAP_HIGH_CMD_ENTRIES, 0 },
1773 	{ AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL },
1774 	{ AAC_HOST_HIGH_RESP_ENTRIES, 0 },
1775 	{ AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY },
1776 	{ AAC_ADAP_HIGH_RESP_ENTRIES, 0 }
1777 };
1778 
1779 /*
1780  * Atomically insert an entry into the nominated queue, returns 0 on success
1781  * or EBUSY if the queue is full.
1782  *
1783  * XXX Note that it would be more efficient to defer notifying the controller
1784  * in the case where we may be inserting several entries in rapid succession,
1785  * but implementing this usefully is difficult.
1786  */
1787 int
aac_enqueue_fib(struct aac_softc * sc,int queue,struct aac_ccb * ccb)1788 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_ccb *ccb)
1789 {
1790 	u_int32_t pi, ci;
1791 	int error;
1792 	aac_lock_t lock;
1793 	u_int32_t fib_size;
1794 	u_int32_t fib_addr;
1795 
1796 	fib_size = ccb->ac_fib->Header.Size;
1797 	fib_addr = ccb->ac_fib->Header.ReceiverFibAddress;
1798 
1799 	lock = AAC_LOCK(sc);
1800 
1801 	/* get the producer/consumer indices */
1802 	pi = sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1803 	ci = sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1804 
1805 	/* wrap the queue? */
1806 	if (pi >= aac_qinfo[queue].size)
1807 		pi = 0;
1808 
1809 	/* check for queue full */
1810 	if ((pi + 1) == ci) {
1811 		error = EBUSY;
1812 		goto out;
1813 	}
1814 
1815 	/* populate queue entry */
1816 	(sc->sc_qentries[queue] + pi)->aq_fib_size = fib_size;
1817 	(sc->sc_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1818 
1819 	/* update producer index */
1820 	sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1821 
1822 	/* notify the adapter if we know how */
1823 	if (aac_qinfo[queue].notify != 0)
1824 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1825 
1826 	error = 0;
1827 
1828 out:
1829 	AAC_UNLOCK(sc, lock);
1830 	return (error);
1831 }
1832 
1833 /*
1834  * Atomically remove one entry from the nominated queue, returns 0 on success
1835  * or ENOENT if the queue is empty.
1836  */
1837 int
aac_dequeue_fib(struct aac_softc * sc,int queue,u_int32_t * fib_size,struct aac_fib ** fib_addr)1838 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1839     struct aac_fib **fib_addr)
1840 {
1841 	u_int32_t pi, ci;
1842 	int notify;
1843 	int error;
1844 	aac_lock_t lock;
1845 
1846 	lock = AAC_LOCK(sc);
1847 
1848 	/* get the producer/consumer indices */
1849 	pi = sc->sc_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1850 	ci = sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1851 
1852 	/* check for queue empty */
1853 	if (ci == pi) {
1854 		error = ENOENT;
1855 		goto out;
1856 	}
1857 
1858 	notify = 0;
1859 	if (ci == pi + 1)
1860 		notify++;
1861 
1862 	/* wrap the queue? */
1863 	if (ci >= aac_qinfo[queue].size)
1864 		ci = 0;
1865 
1866 	/* fetch the entry */
1867 	*fib_size = (sc->sc_qentries[queue] + ci)->aq_fib_size;
1868 	*fib_addr =
1869 	    (struct aac_fib *)(sc->sc_qentries[queue] + ci)->aq_fib_addr;
1870 
1871 	/* update consumer index */
1872 	sc->sc_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1873 
1874 	/* if we have made the queue un-full, notify the adapter */
1875 	if (notify && (aac_qinfo[queue].notify != 0))
1876 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1877 	error = 0;
1878 
1879 out:
1880 	AAC_UNLOCK(sc, lock);
1881 	return (error);
1882 }
1883 
1884 #ifdef AAC_DEBUG
1885 /*
1886  * Print a FIB
1887  */
1888 void
aac_print_fib(struct aac_softc * sc,struct aac_fib * fib,char * caller)1889 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, char *caller)
1890 {
1891 	printf("%s: FIB @ %p\n", caller, fib);
1892 	printf("  XferState %b\n", fib->Header.XferState, "\20"
1893 	    "\1HOSTOWNED"
1894 	    "\2ADAPTEROWNED"
1895 	    "\3INITIALISED"
1896 	    "\4EMPTY"
1897 	    "\5FROMPOOL"
1898 	    "\6FROMHOST"
1899 	    "\7FROMADAP"
1900 	    "\10REXPECTED"
1901 	    "\11RNOTEXPECTED"
1902 	    "\12DONEADAP"
1903 	    "\13DONEHOST"
1904 	    "\14HIGH"
1905 	    "\15NORM"
1906 	    "\16ASYNC"
1907 	    "\17PAGEFILEIO"
1908 	    "\20SHUTDOWN"
1909 	    "\21LAZYWRITE"
1910 	    "\22ADAPMICROFIB"
1911 	    "\23BIOSFIB"
1912 	    "\24FAST_RESPONSE"
1913 	    "\25APIFIB\n");
1914 	printf("  Command         %d\n", fib->Header.Command);
1915 	printf("  StructType      %d\n", fib->Header.StructType);
1916 	printf("  Flags           0x%x\n", fib->Header.Flags);
1917 	printf("  Size            %d\n", fib->Header.Size);
1918 	printf("  SenderSize      %d\n", fib->Header.SenderSize);
1919 	printf("  SenderAddress   0x%x\n", fib->Header.SenderFibAddress);
1920 	printf("  ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress);
1921 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
1922 	switch(fib->Header.Command) {
1923 	case ContainerCommand: {
1924 		struct aac_blockread *br = (struct aac_blockread *)fib->data;
1925 		struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data;
1926 		struct aac_sg_table *sg = NULL;
1927 		int i;
1928 
1929 		if (br->Command == VM_CtBlockRead) {
1930 			printf("  BlockRead: container %d  0x%x/%d\n",
1931 			    br->ContainerId, br->BlockNumber, br->ByteCount);
1932 			    sg = &br->SgMap;
1933 		}
1934 		if (bw->Command == VM_CtBlockWrite) {
1935 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
1936 			    bw->ContainerId, bw->BlockNumber, bw->ByteCount,
1937 			    bw->Stable == CSTABLE ? "stable" : "unstable");
1938 			sg = &bw->SgMap;
1939 		}
1940 		if (sg != NULL) {
1941 			printf("  %d s/g entries\n", sg->SgCount);
1942 			for (i = 0; i < sg->SgCount; i++)
1943 				printf("  0x%08x/%d\n",
1944 				       sg->SgEntry[i].SgAddress,
1945 				       sg->SgEntry[i].SgByteCount);
1946 		}
1947 		break;
1948 	}
1949 	default:
1950 		printf("   %16D\n", fib->data, " ");
1951 		printf("   %16D\n", fib->data + 16, " ");
1952 	break;
1953 	}
1954 }
1955 #endif
1956