amr.c revision 65763
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 *
27 *	$FreeBSD: head/sys/dev/amr/amr.c 65763 2000-09-11 23:19:13Z msmith $
28 */
29
30/*
31 * Driver for the AMI MegaRaid family of controllers.
32 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/malloc.h>
37#include <sys/kernel.h>
38
39#include <dev/amr/amr_compat.h>
40#include <sys/bus.h>
41#include <sys/conf.h>
42#include <sys/devicestat.h>
43#include <sys/disk.h>
44#include <sys/stat.h>
45
46#include <machine/bus_memio.h>
47#include <machine/bus_pio.h>
48#include <machine/bus.h>
49#include <machine/resource.h>
50#include <machine/clock.h>
51#include <sys/rman.h>
52
53#include <pci/pcireg.h>
54#include <pci/pcivar.h>
55
56#include <dev/amr/amrio.h>
57#include <dev/amr/amrreg.h>
58#include <dev/amr/amrvar.h>
59#define AMR_DEFINE_TABLES
60#include <dev/amr/amr_tables.h>
61
62#define AMR_CDEV_MAJOR	132
63
64static d_open_t         amr_open;
65static d_close_t        amr_close;
66static d_ioctl_t        amr_ioctl;
67
68static struct cdevsw amr_cdevsw = {
69		/* open */	amr_open,
70		/* close */	amr_close,
71		/* read */	noread,
72		/* write */	nowrite,
73		/* ioctl */	amr_ioctl,
74		/* poll */	nopoll,
75		/* mmap */	nommap,
76		/* strategy */	nostrategy,
77		/* name */ 	"amr",
78		/* maj */	AMR_CDEV_MAJOR,
79		/* dump */	nodump,
80		/* psize */ 	nopsize,
81		/* flags */	0,
82		/* bmaj */	254	/* XXX magic no-bdev */
83};
84
85/*
86 * Initialisation, bus interface.
87 */
88static void	amr_startup(void *arg);
89
90/*
91 * Command wrappers
92 */
93static int	amr_query_controller(struct amr_softc *sc);
94static void	*amr_enquiry(struct amr_softc *sc, size_t bufsize,
95			     u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual);
96static void	amr_completeio(struct amr_command *ac);
97
98/*
99 * Command buffer allocation.
100 */
101static void	amr_alloccmd_cluster(struct amr_softc *sc);
102static void	amr_freecmd_cluster(struct amr_command_cluster *acc);
103
104/*
105 * Command processing.
106 */
107static int	amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
108static int	amr_wait_command(struct amr_command *ac);
109static int	amr_poll_command(struct amr_command *ac);
110static int	amr_getslot(struct amr_command *ac);
111static void	amr_mapcmd(struct amr_command *ac);
112static void	amr_unmapcmd(struct amr_command *ac);
113static int	amr_start(struct amr_command *ac);
114static void	amr_complete(void *context, int pending);
115
116/*
117 * Status monitoring
118 */
119static void	amr_periodic(void *data);
120
121/*
122 * Interface-specific shims
123 */
124static int	amr_quartz_submit_command(struct amr_softc *sc);
125static int	amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
126
127static int	amr_std_submit_command(struct amr_softc *sc);
128static int	amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
129static void	amr_std_attach_mailbox(struct amr_softc *sc);
130
131#ifdef AMR_BOARD_INIT
132static int	amr_quartz_init(struct amr_softc *sc);
133static int	amr_std_init(struct amr_softc *sc);
134#endif
135
136/*
137 * Debugging
138 */
139static void	amr_describe_controller(struct amr_softc *sc);
140#ifdef AMR_DEBUG
141static void	amr_printcommand(struct amr_command *ac);
142#endif
143
144/********************************************************************************
145 ********************************************************************************
146                                                                      Inline Glue
147 ********************************************************************************
148 ********************************************************************************/
149
150/********************************************************************************
151 ********************************************************************************
152                                                                Public Interfaces
153 ********************************************************************************
154 ********************************************************************************/
155
156/********************************************************************************
157 * Initialise the controller and softc.
158 */
159int
160amr_attach(struct amr_softc *sc)
161{
162
163    debug_called(1);
164
165    /*
166     * Initialise per-controller queues.
167     */
168    TAILQ_INIT(&sc->amr_completed);
169    TAILQ_INIT(&sc->amr_freecmds);
170    TAILQ_INIT(&sc->amr_cmd_clusters);
171    TAILQ_INIT(&sc->amr_ready);
172    bioq_init(&sc->amr_bioq);
173
174#if __FreeBSD_version >= 500005
175    /*
176     * Initialise command-completion task.
177     */
178    TASK_INIT(&sc->amr_task_complete, 0, amr_complete, sc);
179#endif
180
181    debug(2, "queue init done");
182
183    /*
184     * Configure for this controller type.
185     */
186    if (AMR_IS_QUARTZ(sc)) {
187	sc->amr_submit_command = amr_quartz_submit_command;
188	sc->amr_get_work       = amr_quartz_get_work;
189    } else {
190	sc->amr_submit_command = amr_std_submit_command;
191	sc->amr_get_work       = amr_std_get_work;
192	amr_std_attach_mailbox(sc);;
193    }
194
195#ifdef AMR_BOARD_INIT
196    if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc))))
197	return(ENXIO);
198#endif
199
200    /*
201     * Quiz controller for features and limits.
202     */
203    if (amr_query_controller(sc))
204	return(ENXIO);
205
206    debug(2, "controller query complete");
207
208#ifdef AMR_SCSI_PASSTHROUGH
209    /*
210     * Attach our 'real' SCSI channels to CAM.
211     */
212    if (amr_cam_attach(sc))
213	return(ENXIO);
214    debug(2, "CAM attach done");
215#endif
216
217    /*
218     * Create the control device.
219     */
220    sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR,
221			     S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev));
222    sc->amr_dev_t->si_drv1 = sc;
223
224    /*
225     * Schedule ourselves to bring the controller up once interrupts are
226     * available.
227     */
228    bzero(&sc->amr_ich, sizeof(struct intr_config_hook));
229    sc->amr_ich.ich_func = amr_startup;
230    sc->amr_ich.ich_arg = sc;
231    if (config_intrhook_establish(&sc->amr_ich) != 0) {
232	device_printf(sc->amr_dev, "can't establish configuration hook\n");
233	return(ENOMEM);
234    }
235
236    /*
237     * Print a little information about the controller.
238     */
239    amr_describe_controller(sc);
240
241    debug(2, "attach complete");
242    return(0);
243}
244
245/********************************************************************************
246 * Locate disk resources and attach children to them.
247 */
248static void
249amr_startup(void *arg)
250{
251    struct amr_softc	*sc = (struct amr_softc *)arg;
252    struct amr_logdrive	*dr;
253    int			i, error;
254
255    debug_called(1);
256
257    /* pull ourselves off the intrhook chain */
258    config_intrhook_disestablish(&sc->amr_ich);
259
260    /* get up-to-date drive information */
261    if (amr_query_controller(sc)) {
262	device_printf(sc->amr_dev, "can't scan controller for drives\n");
263	return;
264    }
265
266    /* iterate over available drives */
267    for (i = 0, dr = &sc->amr_drive[0]; (i < AMR_MAXLD) && (dr->al_size != 0xffffffff); i++, dr++) {
268	/* are we already attached to this drive? */
269	if (dr->al_disk == 0) {
270	    /* generate geometry information */
271	    if (dr->al_size > 0x200000) {	/* extended translation? */
272		dr->al_heads = 255;
273		dr->al_sectors = 63;
274	    } else {
275		dr->al_heads = 64;
276		dr->al_sectors = 32;
277	    }
278	    dr->al_cylinders = dr->al_size / (dr->al_heads * dr->al_sectors);
279
280	    dr->al_disk = device_add_child(sc->amr_dev, NULL, -1);
281	    if (dr->al_disk == 0)
282		device_printf(sc->amr_dev, "device_add_child failed\n");
283	    device_set_ivars(dr->al_disk, dr);
284	}
285    }
286
287    if ((error = bus_generic_attach(sc->amr_dev)) != 0)
288	device_printf(sc->amr_dev, "bus_generic_attach returned %d\n", error);
289
290    /* mark controller back up */
291    sc->amr_state &= ~AMR_STATE_SHUTDOWN;
292
293    /* interrupts will be enabled before we do anything more */
294    sc->amr_state |= AMR_STATE_INTEN;
295
296    /*
297     * Start the timeout routine.
298     */
299/*    sc->amr_timeout = timeout(amr_periodic, sc, hz);*/
300
301    return;
302}
303
304/*******************************************************************************
305 * Free resources associated with a controller instance
306 */
307void
308amr_free(struct amr_softc *sc)
309{
310    struct amr_command_cluster	*acc;
311
312#ifdef AMR_SCSI_PASSTHROUGH
313    /* detach from CAM */
314    amr_cam_detach(sc);
315#endif
316
317    /* cancel status timeout */
318    untimeout(amr_periodic, sc, sc->amr_timeout);
319
320    /* throw away any command buffers */
321    while ((acc = TAILQ_FIRST(&sc->amr_cmd_clusters)) != NULL) {
322	TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link);
323	amr_freecmd_cluster(acc);
324    }
325}
326
327/*******************************************************************************
328 * Receive a bio structure from a child device and queue it on a particular
329 * disk resource, then poke the disk resource to start as much work as it can.
330 */
331int
332amr_submit_bio(struct amr_softc *sc, struct bio *bio)
333{
334    debug_called(2);
335
336    amr_enqueue_bio(sc, bio);
337    amr_startio(sc);
338    return(0);
339}
340
341/********************************************************************************
342 * Accept an open operation on the control device.
343 */
344int
345amr_open(dev_t dev, int flags, int fmt, struct proc *p)
346{
347    int			unit = minor(dev);
348    struct amr_softc	*sc = devclass_get_softc(amr_devclass, unit);
349
350    debug_called(1);
351
352    sc->amr_state |= AMR_STATE_OPEN;
353    return(0);
354}
355
356/********************************************************************************
357 * Accept the last close on the control device.
358 */
359int
360amr_close(dev_t dev, int flags, int fmt, struct proc *p)
361{
362    int			unit = minor(dev);
363    struct amr_softc	*sc = devclass_get_softc(amr_devclass, unit);
364
365    debug_called(1);
366
367    sc->amr_state &= ~AMR_STATE_OPEN;
368    return (0);
369}
370
371/********************************************************************************
372 * Handle controller-specific control operations.
373 */
374int
375amr_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
376{
377    struct amr_softc		*sc = (struct amr_softc *)dev->si_drv1;
378    int				*arg = (int *)addr;
379    struct amr_user_ioctl	*au = (struct amr_user_ioctl *)addr;
380    struct amr_command		*ac;
381    struct amr_mailbox_ioctl	*mbi;
382    struct amr_passthrough	*ap;
383    void			*dp;
384    int				error;
385
386    debug_called(1);
387
388    error = 0;
389    dp = NULL;
390    ap = NULL;
391    ac = NULL;
392    switch(cmd) {
393
394    case AMR_IO_VERSION:
395	debug(1, "AMR_IO_VERSION");
396	*arg = AMR_IO_VERSION_NUMBER;
397	break;
398
399    case AMR_IO_COMMAND:
400	debug(1, "AMR_IO_COMMAND");
401	/* handle inbound data buffer */
402	if (au->au_length != 0) {
403	    if ((dp = malloc(au->au_length, M_DEVBUF, M_WAITOK)) == NULL) {
404		error = ENOMEM;
405		break;
406	    }
407	    if ((error = copyin(au->au_buffer, dp, au->au_length)) != 0)
408		break;
409	}
410
411	if ((ac = amr_alloccmd(sc)) == NULL) {
412	    error = ENOMEM;
413	    break;
414	}
415
416	/* handle SCSI passthrough command */
417	if (au->au_cmd[0] == AMR_CMD_PASS) {
418	    if ((ap = malloc(sizeof(*ap), M_DEVBUF, M_WAITOK)) == NULL) {
419		error = ENOMEM;
420		break;
421	    }
422	    bzero(ap, sizeof(*ap));
423
424	    /* copy cdb */
425	    ap->ap_cdb_length = au->au_cmd[2];
426	    bcopy(&au->au_cmd[3], &ap->ap_cdb[0], ap->ap_cdb_length);
427
428	    /* build passthrough */
429	    ap->ap_timeout		= au->au_cmd[ap->ap_cdb_length + 3] & 0x07;
430	    ap->ap_ars			= (au->au_cmd[ap->ap_cdb_length + 3] & 0x08) ? 1 : 0;
431	    ap->ap_islogical		= (au->au_cmd[ap->ap_cdb_length + 3] & 0x80) ? 1 : 0;
432	    ap->ap_logical_drive_no	= au->au_cmd[ap->ap_cdb_length + 4];
433	    ap->ap_channel		= au->au_cmd[ap->ap_cdb_length + 5];
434	    ap->ap_scsi_id 		= au->au_cmd[ap->ap_cdb_length + 6];
435	    ap->ap_request_sense_length	= 14;
436	    /* XXX what about the request-sense area? does the caller want it? */
437
438	    /* build command */
439	    ac->ac_data = ap;
440	    ac->ac_length = sizeof(*ap);
441	    ac->ac_flags |= AMR_CMD_DATAOUT;
442	    ac->ac_ccb_data = dp;
443	    ac->ac_ccb_length = au->au_length;
444	    if (au->au_direction & AMR_IO_READ)
445		ac->ac_flags |= AMR_CMD_CCB_DATAIN;
446	    if (au->au_direction & AMR_IO_WRITE)
447		ac->ac_flags |= AMR_CMD_CCB_DATAOUT;
448
449	    ac->ac_mailbox.mb_command = AMR_CMD_PASS;
450
451	} else {
452	    /* direct command to controller */
453	    mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox;
454
455	    /* copy pertinent mailbox items */
456	    mbi->mb_command = au->au_cmd[0];
457	    mbi->mb_channel = au->au_cmd[1];
458	    mbi->mb_param = au->au_cmd[2];
459	    mbi->mb_pad[0] = au->au_cmd[3];
460	    mbi->mb_drive = au->au_cmd[4];
461
462	    /* build the command */
463	    ac->ac_data = dp;
464	    ac->ac_length = au->au_length;
465	    if (au->au_direction & AMR_IO_READ)
466		ac->ac_flags |= AMR_CMD_DATAIN;
467	    if (au->au_direction & AMR_IO_WRITE)
468		ac->ac_flags |= AMR_CMD_DATAOUT;
469	}
470
471	/* run the command */
472	if ((error = amr_wait_command(ac)) != 0)
473	    break;
474
475	/* copy out data and set status */
476	if (au->au_length != 0)
477	    error = copyout(dp, au->au_buffer, au->au_length);
478	au->au_status = ac->ac_status;
479	break;
480
481    default:
482	debug(1, "unknown ioctl 0x%lx", cmd);
483	error = ENOIOCTL;
484	break;
485    }
486
487    if (dp != NULL)
488	free(dp, M_DEVBUF);
489    if (ap != NULL)
490	free(ap, M_DEVBUF);
491    if (ac != NULL)
492	amr_releasecmd(ac);
493    return(error);
494}
495
496/********************************************************************************
497 ********************************************************************************
498                                                                Status Monitoring
499 ********************************************************************************
500 ********************************************************************************/
501
502/********************************************************************************
503 * Perform a periodic check of the controller status
504 */
505static void
506amr_periodic(void *data)
507{
508    struct amr_softc	*sc = (struct amr_softc *)data;
509
510    debug_called(2);
511
512    /* XXX perform periodic status checks here */
513
514    /* compensate for missed interrupts */
515    amr_done(sc);
516
517    /* reschedule */
518    sc->amr_timeout = timeout(amr_periodic, sc, hz);
519}
520
521/********************************************************************************
522 ********************************************************************************
523                                                                 Command Wrappers
524 ********************************************************************************
525 ********************************************************************************/
526
527/********************************************************************************
528 * Interrogate the controller for the operational parameters we require.
529 */
530static int
531amr_query_controller(struct amr_softc *sc)
532{
533    struct amr_enquiry3	*aex;
534    struct amr_prodinfo	*ap;
535    struct amr_enquiry	*ae;
536    int			ldrv;
537
538    /*
539     * If we haven't found the real limit yet, let us have a couple of commands in
540     * order to be able to probe.
541     */
542    if (sc->amr_maxio == 0)
543	sc->amr_maxio = 2;
544
545    /*
546     * Try to issue an ENQUIRY3 command
547     */
548    if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
549			   AMR_CONFIG_ENQ3_SOLICITED_FULL)) != NULL) {
550
551	/*
552	 * Fetch current state of logical drives.
553	 */
554	for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
555	    sc->amr_drive[ldrv].al_size       = aex->ae_drivesize[ldrv];
556	    sc->amr_drive[ldrv].al_state      = aex->ae_drivestate[ldrv];
557	    sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv];
558	    debug(2, "  drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
559		  sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
560	}
561	free(aex, M_DEVBUF);
562
563	/*
564	 * Get product info for channel count.
565	 */
566	if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) == NULL) {
567	    device_printf(sc->amr_dev, "can't obtain product data from controller\n");
568	    return(1);
569	}
570	sc->amr_maxdrives = 40;
571	sc->amr_maxchan = ap->ap_nschan;
572	sc->amr_maxio = ap->ap_maxio;
573	sc->amr_type |= AMR_TYPE_40LD;
574	free(ap, M_DEVBUF);
575
576    } else {
577
578	/* failed, try the 8LD ENQUIRY commands */
579	if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) == NULL) {
580	    if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) == NULL) {
581		device_printf(sc->amr_dev, "can't obtain configuration data from controller\n");
582		return(1);
583	    }
584	    ae->ae_signature = 0;
585	}
586
587	/*
588	 * Fetch current state of logical drives.
589	 */
590	for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) {
591	    sc->amr_drive[ldrv].al_size       = ae->ae_ldrv.al_size[ldrv];
592	    sc->amr_drive[ldrv].al_state      = ae->ae_ldrv.al_state[ldrv];
593	    sc->amr_drive[ldrv].al_properties = ae->ae_ldrv.al_properties[ldrv];
594	    debug(2, "  drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
595		  sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
596	}
597
598	sc->amr_maxdrives = 8;
599	sc->amr_maxchan = ae->ae_adapter.aa_channels;
600	sc->amr_maxio = ae->ae_adapter.aa_maxio;
601	free(ae, M_DEVBUF);
602    }
603
604    /*
605     * Mark remaining drives as unused.
606     */
607    for (; ldrv < AMR_MAXLD; ldrv++)
608	sc->amr_drive[ldrv].al_size = 0xffffffff;
609
610    /*
611     * Cap the maximum number of outstanding I/Os.  AMI's Linux driver doesn't trust
612     * the controller's reported value, and lockups have been seen when we do.
613     */
614    sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);
615
616    return(0);
617}
618
619/********************************************************************************
620 * Run a generic enquiry-style command.
621 */
622static void *
623amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual)
624{
625    struct amr_command	*ac;
626    void		*result;
627    u_int8_t		*mbox;
628    int			error;
629
630    debug_called(1);
631
632    error = 1;
633    result = NULL;
634
635    /* get ourselves a command buffer */
636    if ((ac = amr_alloccmd(sc)) == NULL)
637	goto out;
638    /* allocate the response structure */
639    if ((result = malloc(bufsize, M_DEVBUF, M_NOWAIT)) == NULL)
640	goto out;
641    /* set command flags */
642    ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
643
644    /* point the command at our data */
645    ac->ac_data = result;
646    ac->ac_length = bufsize;
647
648    /* build the command proper */
649    mbox = (u_int8_t *)&ac->ac_mailbox;		/* XXX want a real structure for this? */
650    mbox[0] = cmd;
651    mbox[2] = cmdsub;
652    mbox[3] = cmdqual;
653
654    /* can't assume that interrupts are going to work here, so play it safe */
655    if (amr_poll_command(ac))
656	goto out;
657    error = ac->ac_status;
658
659 out:
660    if (ac != NULL)
661	amr_releasecmd(ac);
662    if ((error != 0) && (result != NULL)) {
663	free(result, M_DEVBUF);
664	result = NULL;
665    }
666    return(result);
667}
668
669/********************************************************************************
670 * Flush the controller's internal cache, return status.
671 */
672int
673amr_flush(struct amr_softc *sc)
674{
675    struct amr_command	*ac;
676    int			error;
677
678    /* get ourselves a command buffer */
679    error = 1;
680    if ((ac = amr_alloccmd(sc)) == NULL)
681	goto out;
682    /* set command flags */
683    ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
684
685    /* build the command proper */
686    ac->ac_mailbox.mb_command = AMR_CMD_FLUSH;
687
688    /* we have to poll, as the system may be going down or otherwise damaged */
689    if (amr_poll_command(ac))
690	goto out;
691    error = ac->ac_status;
692
693 out:
694    if (ac != NULL)
695	amr_releasecmd(ac);
696    return(error);
697}
698
699/********************************************************************************
700 * Try to find I/O work for the controller from one or more of the work queues.
701 *
702 * We make the assumption that if the controller is not ready to take a command
703 * at some given time, it will generate an interrupt at some later time when
704 * it is.
705 */
706void
707amr_startio(struct amr_softc *sc)
708{
709    struct amr_command	*ac;
710
711    /* spin until something prevents us from doing any work */
712    for (;;) {
713
714	/* try to get a ready command */
715	ac = amr_dequeue_ready(sc);
716
717	/* if that failed, build a command from a bio */
718	if (ac == NULL)
719	    (void)amr_bio_command(sc, &ac);
720
721#ifdef AMR_SCSI_PASSTHROUGH
722	/* if that failed, build a command from a ccb */
723	if (ac == NULL)
724	    (void)amr_cam_command(sc, &ac);
725#endif
726
727	/* if we don't have anything to do, give up */
728	if (ac == NULL)
729	    break;
730
731	/* try to give the command to the controller; if this fails save it for later and give up */
732	if (amr_start(ac)) {
733	    debug(2, "controller busy, command deferred");
734	    amr_requeue_ready(ac);	/* XXX schedule retry very soon? */
735	    break;
736	}
737    }
738}
739
740/********************************************************************************
741 * Handle completion of an I/O command.
742 */
743static void
744amr_completeio(struct amr_command *ac)
745{
746    struct amr_softc	*sc = ac->ac_sc;
747
748    if (ac->ac_status != AMR_STATUS_SUCCESS) {	/* could be more verbose here? */
749	ac->ac_bio->bio_error = EIO;
750	ac->ac_bio->bio_flags |= BIO_ERROR;
751
752	device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status);
753/*	amr_printcommand(ac);*/
754    }
755    amrd_intr(ac->ac_bio);
756    amr_releasecmd(ac);
757}
758
759/********************************************************************************
760 ********************************************************************************
761                                                               Command Processing
762 ********************************************************************************
763 ********************************************************************************/
764
765/********************************************************************************
766 * Convert a bio off the top of the bio queue into a command.
767 */
768static int
769amr_bio_command(struct amr_softc *sc, struct amr_command **acp)
770{
771    struct amr_command	*ac;
772    struct amrd_softc	*amrd;
773    struct bio		*bio;
774    int			error;
775    int			blkcount;
776    int			driveno;
777    int			cmd;
778
779    ac = NULL;
780    error = 0;
781
782    /* get a bio to work on */
783    if ((bio = amr_dequeue_bio(sc)) == NULL)
784	goto out;
785
786    /* get a command */
787    if ((ac = amr_alloccmd(sc)) == NULL) {
788	error = ENOMEM;
789	goto out;
790    }
791
792    /* connect the bio to the command */
793    ac->ac_complete = amr_completeio;
794    ac->ac_bio = bio;
795    ac->ac_data = bio->bio_data;
796    ac->ac_length = bio->bio_bcount;
797    if (BIO_IS_READ(bio)) {
798	ac->ac_flags |= AMR_CMD_DATAIN;
799	cmd = AMR_CMD_LREAD;
800    } else {
801	ac->ac_flags |= AMR_CMD_DATAOUT;
802	cmd = AMR_CMD_LWRITE;
803    }
804    amrd = (struct amrd_softc *)bio->bio_dev->si_drv1;
805    driveno = amrd->amrd_drive - sc->amr_drive;
806    blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE;
807
808    ac->ac_mailbox.mb_command = cmd;
809    ac->ac_mailbox.mb_blkcount = blkcount;
810    ac->ac_mailbox.mb_lba = bio->bio_pblkno;
811    ac->ac_mailbox.mb_drive = driveno;
812    /* we fill in the s/g related data when the command is mapped */
813
814    if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size)
815	device_printf(sc->amr_dev, "I/O beyond end of unit (%u,%d > %u)\n",
816		      bio->bio_pblkno, blkcount, sc->amr_drive[driveno].al_size);
817
818out:
819    if (error != 0) {
820	if (ac != NULL)
821	    amr_releasecmd(ac);
822	if (bio != NULL)			/* this breaks ordering... */
823	    amr_enqueue_bio(sc, bio);
824    }
825    *acp = ac;
826    return(error);
827}
828
829/********************************************************************************
830 * Take a command, submit it to the controller and sleep until it completes
831 * or fails.  Interrupts must be enabled, returns nonzero on error.
832 */
833static int
834amr_wait_command(struct amr_command *ac)
835{
836    struct amr_softc	*sc = ac->ac_sc;
837    int			error, count;
838
839    debug_called(1);
840
841    ac->ac_complete = NULL;
842    ac->ac_flags |= AMR_CMD_SLEEP;
843    if ((error = amr_start(ac)) != 0)
844	return(error);
845
846    count = 0;
847    /* XXX better timeout? */
848    while ((ac->ac_flags & AMR_CMD_BUSY) && (count < 30)) {
849	tsleep(ac, PRIBIO | PCATCH, "amrwcmd", hz);
850    }
851
852    if (ac->ac_status != 0) {
853	device_printf(sc->amr_dev, "I/O error - 0x%x\n", ac->ac_status);
854	return(EIO);
855    }
856    return(0);
857}
858
859/********************************************************************************
860 * Take a command, submit it to the controller and busy-wait for it to return.
861 * Returns nonzero on error.  Can be safely called with interrupts enabled.
862 */
863static int
864amr_poll_command(struct amr_command *ac)
865{
866    struct amr_softc	*sc = ac->ac_sc;
867    int			error, count;
868
869    debug_called(2);
870
871    ac->ac_complete = NULL;
872    if ((error = amr_start(ac)) != 0)
873	return(error);
874
875    count = 0;
876    do {
877	/*
878	 * Poll for completion, although the interrupt handler may beat us to it.
879	 * Note that the timeout here is somewhat arbitrary.
880	 */
881	amr_done(sc);
882	DELAY(1000);
883    } while ((ac->ac_flags & AMR_CMD_BUSY) && (count++ < 1000));
884    if (!(ac->ac_flags & AMR_CMD_BUSY)) {
885	error = 0;
886    } else {
887	/* XXX the slot is now marked permanently busy */
888	error = EIO;
889	device_printf(sc->amr_dev, "polled command timeout\n");
890    }
891    return(error);
892}
893
894/********************************************************************************
895 * Get a free command slot for a command if it doesn't already have one.
896 *
897 * May be safely called multiple times for a given command.
898 */
899static int
900amr_getslot(struct amr_command *ac)
901{
902    struct amr_softc	*sc = ac->ac_sc;
903    int			s, slot, limit, error;
904
905    debug_called(3);
906
907    /* if the command already has a slot, don't try to give it another one */
908    if (ac->ac_slot != 0)
909	return(0);
910
911    /* enforce slot usage limit */
912    limit = (ac->ac_flags & AMR_CMD_PRIORITY) ? sc->amr_maxio : sc->amr_maxio - 4;
913    if (sc->amr_busyslots > limit)
914	return(EBUSY);
915
916    /*
917     * Allocate a slot.  XXX linear scan is slow
918     */
919    error = EBUSY;
920    s = splbio();
921    for (slot = 0; slot < sc->amr_maxio; slot++) {
922	if (sc->amr_busycmd[slot] == NULL) {
923	    sc->amr_busycmd[slot] = ac;
924	    sc->amr_busyslots++;
925	    ac->ac_slot = slot;
926	    error = 0;
927	    break;
928	}
929    }
930    splx(s);
931
932    return(error);
933}
934
935/********************************************************************************
936 * Map/unmap (ac)'s data in the controller's addressable space as required.
937 *
938 * These functions may be safely called multiple times on a given command.
939 */
940static void
941amr_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
942{
943    struct amr_command	*ac = (struct amr_command *)arg;
944    struct amr_softc	*sc = ac->ac_sc;
945    struct amr_sgentry	*sg;
946    int			i;
947
948    debug_called(3);
949
950    /* get base address of s/g table */
951    sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
952
953    /* save data physical address */
954    ac->ac_dataphys = segs[0].ds_addr;
955
956    /* decide whether we need to populate the s/g table */
957    if (nsegments < 2) {
958	ac->ac_mailbox.mb_nsgelem = 0;
959	ac->ac_mailbox.mb_physaddr = ac->ac_dataphys;
960    } else {
961	ac->ac_mailbox.mb_nsgelem = nsegments;
962	ac->ac_mailbox.mb_physaddr = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
963	for (i = 0; i < nsegments; i++, sg++) {
964	    sg->sg_addr = segs[i].ds_addr;
965	    sg->sg_count = segs[i].ds_len;
966	}
967    }
968}
969
970static void
971amr_setup_ccbmap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
972{
973    struct amr_command		*ac = (struct amr_command *)arg;
974    struct amr_softc		*sc = ac->ac_sc;
975    struct amr_sgentry		*sg;
976    struct amr_passthrough	*ap = (struct amr_passthrough *)ac->ac_data;
977    int				i;
978
979    /* get base address of s/g table */
980    sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
981
982    /* save s/g table information in passthrough */
983    ap->ap_no_sg_elements = nsegments;
984    ap->ap_data_transfer_address = sc->amr_sgbusaddr + (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
985
986    /* save pointer to passthrough in command   XXX is this already done above? */
987    ac->ac_mailbox.mb_physaddr = ac->ac_dataphys;
988
989    debug(2, "slot %d  %d segments at 0x%x, passthrough at 0x%x", ac->ac_slot,
990	   ap->ap_no_sg_elements, ap->ap_data_transfer_address, ac->ac_dataphys);
991
992    /* populate s/g table (overwrites previous call which mapped the passthrough) */
993    for (i = 0; i < nsegments; i++, sg++) {
994	sg->sg_addr = segs[i].ds_addr;
995	sg->sg_count = segs[i].ds_len;
996	debug(2, " %d: 0x%x/%d", i, sg->sg_addr, sg->sg_count);
997    }
998}
999
1000static void
1001amr_mapcmd(struct amr_command *ac)
1002{
1003    struct amr_softc	*sc = ac->ac_sc;
1004
1005    debug_called(2);
1006
1007    /* if the command involves data at all, and hasn't been mapped */
1008    if (!(ac->ac_flags & AMR_CMD_MAPPED)) {
1009
1010	if (ac->ac_data != NULL) {
1011	    /* map the data buffers into bus space and build the s/g list */
1012	    bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_dmamap, ac->ac_data, ac->ac_length,
1013			    amr_setup_dmamap, ac, 0);
1014	    if (ac->ac_flags & AMR_CMD_DATAIN)
1015		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREREAD);
1016	    if (ac->ac_flags & AMR_CMD_DATAOUT)
1017		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_PREWRITE);
1018	}
1019
1020	if (ac->ac_ccb_data != NULL) {
1021	    bus_dmamap_load(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, ac->ac_ccb_data, ac->ac_ccb_length,
1022			    amr_setup_ccbmap, ac, 0);
1023	    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1024		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREREAD);
1025	    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1026		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_PREWRITE);
1027	}
1028	ac->ac_flags |= AMR_CMD_MAPPED;
1029    }
1030}
1031
1032static void
1033amr_unmapcmd(struct amr_command *ac)
1034{
1035    struct amr_softc	*sc = ac->ac_sc;
1036
1037    debug_called(2);
1038
1039    /* if the command involved data at all and was mapped */
1040    if (ac->ac_flags & AMR_CMD_MAPPED) {
1041
1042	if (ac->ac_data != NULL) {
1043	    if (ac->ac_flags & AMR_CMD_DATAIN)
1044		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTREAD);
1045	    if (ac->ac_flags & AMR_CMD_DATAOUT)
1046		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_dmamap, BUS_DMASYNC_POSTWRITE);
1047	    bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_dmamap);
1048	}
1049
1050	if (ac->ac_ccb_data != NULL) {
1051	    if (ac->ac_flags & AMR_CMD_CCB_DATAIN)
1052		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTREAD);
1053	    if (ac->ac_flags & AMR_CMD_CCB_DATAOUT)
1054		bus_dmamap_sync(sc->amr_buffer_dmat, ac->ac_ccb_dmamap, BUS_DMASYNC_POSTWRITE);
1055	    bus_dmamap_unload(sc->amr_buffer_dmat, ac->ac_ccb_dmamap);
1056	}
1057	ac->ac_flags &= ~AMR_CMD_MAPPED;
1058    }
1059}
1060
1061/********************************************************************************
1062 * Take a command and give it to the controller, returns 0 if successful, or
1063 * EBUSY if the command should be retried later.
1064 */
1065static int
1066amr_start(struct amr_command *ac)
1067{
1068    struct amr_softc	*sc = ac->ac_sc;
1069    int			done, s, i;
1070
1071    debug_called(2);
1072
1073    /* mark command as busy so that polling consumer can tell */
1074    ac->ac_flags |= AMR_CMD_BUSY;
1075
1076    /* get a command slot (freed in amr_done) */
1077    if (amr_getslot(ac))
1078	return(EBUSY);
1079
1080    /* now we have a slot, we can map the command (unmapped in amr_complete) */
1081    amr_mapcmd(ac);
1082
1083    /* mark the new mailbox we are going to copy in as busy */
1084    ac->ac_mailbox.mb_busy = 1;
1085
1086    /* clear the poll/ack fields in the mailbox */
1087    sc->amr_mailbox->mb_poll = 0;
1088    sc->amr_mailbox->mb_ack = 0;
1089
1090    /*
1091     * Save the slot number so that we can locate this command when complete.
1092     * Note that ident = 0 seems to be special, so we don't use it.
1093     */
1094    ac->ac_mailbox.mb_ident = ac->ac_slot + 1;
1095
1096    /*
1097     * Spin waiting for the mailbox, give up after ~1 second.  We expect the
1098     * controller to be able to handle our I/O.
1099     *
1100     * XXX perhaps we should wait for less time, and count on the deferred command
1101     * handling to deal with retries?
1102     */
1103    debug(2, "wait for mailbox");
1104    for (i = 10000, done = 0; (i > 0) && !done; i--) {
1105	s = splbio();
1106
1107	/* is the mailbox free? */
1108	if (sc->amr_mailbox->mb_busy == 0) {
1109	    debug(2, "got mailbox");
1110	    sc->amr_mailbox64->mb64_segment = 0;
1111	    bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
1112	    done = 1;
1113
1114	    /* not free, spin waiting */
1115	} else {
1116	    debug(3, "busy flag %x\n", sc->amr_mailbox->mb_busy);
1117	    /* this is somewhat ugly */
1118	    DELAY(100);
1119	}
1120	splx(s);	/* drop spl to allow completion interrupts */
1121    }
1122
1123    /*
1124     * Now give the command to the controller
1125     */
1126    if (done) {
1127	if (sc->amr_submit_command(sc)) {
1128	    /* the controller wasn't ready to take the command, forget that we tried to post it */
1129	    sc->amr_mailbox->mb_busy = 0;
1130	    return(EBUSY);
1131	}
1132	debug(2, "posted command");
1133	return(0);
1134    }
1135
1136    /*
1137     * The controller wouldn't take the command.  Return the command as busy
1138     * so that it is retried later.
1139     */
1140    return(EBUSY);
1141}
1142
1143/********************************************************************************
1144 * Extract one or more completed commands from the controller (sc)
1145 *
1146 * Returns nonzero if any commands on the work queue were marked as completed.
1147 */
1148int
1149amr_done(struct amr_softc *sc)
1150{
1151    struct amr_command	*ac;
1152    struct amr_mailbox	mbox;
1153    int			i, idx, result;
1154
1155    debug_called(2);
1156
1157    /* See if there's anything for us to do */
1158    result = 0;
1159
1160    /* loop collecting completed commands */
1161    for (;;) {
1162	/* poll for a completed command's identifier and status */
1163	if (sc->amr_get_work(sc, &mbox)) {
1164	    result = 1;
1165
1166	    /* iterate over completed commands in this result */
1167	    for (i = 0; i < mbox.mb_nstatus; i++) {
1168		/* get pointer to busy command */
1169		idx = mbox.mb_completed[i] - 1;
1170		ac = sc->amr_busycmd[idx];
1171
1172		/* really a busy command? */
1173		if (ac != NULL) {
1174
1175		    /* pull the command from the busy index */
1176		    sc->amr_busycmd[idx] = NULL;
1177		    sc->amr_busyslots--;
1178
1179		    /* save status for later use */
1180		    ac->ac_status = mbox.mb_status;
1181		    amr_enqueue_completed(ac);
1182		    debug(3, "completed command with status %x", mbox.mb_status);
1183		} else {
1184		    device_printf(sc->amr_dev, "bad slot %d completed\n", idx);
1185		}
1186	    }
1187	} else {
1188	    break;	/* no work */
1189	}
1190    }
1191
1192    /* if we've completed any commands, try posting some more */
1193    if (result)
1194	amr_startio(sc);
1195
1196    /* handle completion and timeouts */
1197#if __FreeBSD_version >= 500005
1198    if (sc->amr_state & AMR_STATE_INTEN)
1199	taskqueue_enqueue(taskqueue_swi, &sc->amr_task_complete);
1200    else
1201#endif
1202	amr_complete(sc, 0);
1203
1204    return(result);
1205}
1206
1207/********************************************************************************
1208 * Do completion processing on done commands on (sc)
1209 */
1210static void
1211amr_complete(void *context, int pending)
1212{
1213    struct amr_softc	*sc = (struct amr_softc *)context;
1214    struct amr_command	*ac;
1215
1216    debug_called(2);
1217
1218    /* pull completed commands off the queue */
1219    for (;;) {
1220	ac = amr_dequeue_completed(sc);
1221	if (ac == NULL)
1222	    break;
1223
1224	/* unmap the command's data buffer */
1225	amr_unmapcmd(ac);
1226
1227	/* unbusy the command */
1228	ac->ac_flags &= ~AMR_CMD_BUSY;
1229
1230	/*
1231	 * Is there a completion handler?
1232	 */
1233	if (ac->ac_complete != NULL) {
1234	    ac->ac_complete(ac);
1235
1236	    /*
1237	     * Is someone sleeping on this one?
1238	     */
1239	} else if (ac->ac_flags & AMR_CMD_SLEEP) {
1240	    wakeup(ac);
1241	}
1242    }
1243}
1244
1245/********************************************************************************
1246 ********************************************************************************
1247                                                        Command Buffer Management
1248 ********************************************************************************
1249 ********************************************************************************/
1250
1251/********************************************************************************
1252 * Get a new command buffer.
1253 *
1254 * This may return NULL in low-memory cases.
1255 *
1256 * If possible, we recycle a command buffer that's been used before.
1257 */
1258struct amr_command *
1259amr_alloccmd(struct amr_softc *sc)
1260{
1261    struct amr_command	*ac;
1262
1263    debug_called(3);
1264
1265    ac = amr_dequeue_free(sc);
1266    if (ac == NULL) {
1267	amr_alloccmd_cluster(sc);
1268	ac = amr_dequeue_free(sc);
1269    }
1270    if (ac == NULL)
1271	return(NULL);
1272
1273    /* clear out significant fields */
1274    ac->ac_slot = 0;
1275    ac->ac_status = 0;
1276    bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox));
1277    ac->ac_flags = 0;
1278    ac->ac_bio = NULL;
1279    ac->ac_data = NULL;
1280    ac->ac_ccb_data = NULL;
1281    ac->ac_complete = NULL;
1282    return(ac);
1283}
1284
1285/********************************************************************************
1286 * Release a command buffer for recycling.
1287 */
1288void
1289amr_releasecmd(struct amr_command *ac)
1290{
1291    debug_called(3);
1292
1293    amr_enqueue_free(ac);
1294}
1295
1296/********************************************************************************
1297 * Allocate a new command cluster and initialise it.
1298 */
1299void
1300amr_alloccmd_cluster(struct amr_softc *sc)
1301{
1302    struct amr_command_cluster	*acc;
1303    struct amr_command		*ac;
1304    int				s, i;
1305
1306    acc = malloc(AMR_CMD_CLUSTERSIZE, M_DEVBUF, M_NOWAIT);
1307    if (acc != NULL) {
1308	s = splbio();
1309	TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link);
1310	splx(s);
1311	for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
1312	    ac = &acc->acc_command[i];
1313	    bzero(ac, sizeof(*ac));
1314	    ac->ac_sc = sc;
1315	    if (!bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap) &&
1316		!bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_ccb_dmamap))
1317		amr_releasecmd(ac);
1318	}
1319    }
1320}
1321
1322/********************************************************************************
1323 * Free a command cluster
1324 */
1325void
1326amr_freecmd_cluster(struct amr_command_cluster *acc)
1327{
1328    struct amr_softc	*sc = acc->acc_command[0].ac_sc;
1329    int			i;
1330
1331    for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++)
1332	bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
1333    free(acc, M_DEVBUF);
1334}
1335
1336/********************************************************************************
1337 ********************************************************************************
1338                                                         Interface-specific Shims
1339 ********************************************************************************
1340 ********************************************************************************/
1341
1342/********************************************************************************
1343 * Tell the controller that the mailbox contains a valid command
1344 */
1345static int
1346amr_quartz_submit_command(struct amr_softc *sc)
1347{
1348    debug_called(3);
1349
1350    if (AMR_QGET_IDB(sc) & AMR_QIDB_SUBMIT)
1351	return(EBUSY);
1352    AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
1353    return(0);
1354}
1355
1356static int
1357amr_std_submit_command(struct amr_softc *sc)
1358{
1359    debug_called(3);
1360
1361    if (AMR_SGET_MBSTAT(sc) & AMR_SMBOX_BUSYFLAG)
1362	return(EBUSY);
1363    AMR_SPOST_COMMAND(sc);
1364    return(0);
1365}
1366
1367/********************************************************************************
1368 * Claim any work that the controller has completed; acknowledge completion,
1369 * save details of the completion in (mbsave)
1370 */
1371static int
1372amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
1373{
1374    int		s, worked;
1375    u_int32_t	outd;
1376
1377    debug_called(3);
1378
1379    worked = 0;
1380    s = splbio();
1381
1382    /* work waiting for us? */
1383    if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) {
1384
1385	/* save mailbox, which contains a list of completed commands */
1386	bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
1387
1388	/* acknowledge interrupt */
1389	AMR_QPUT_ODB(sc, AMR_QODB_READY);
1390
1391	/* acknowledge that we have the commands */
1392	AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
1393
1394#ifndef AMR_QUARTZ_GOFASTER
1395	/*
1396	 * This waits for the controller to notice that we've taken the
1397	 * command from it.  It's very inefficient, and we shouldn't do it,
1398	 * but if we remove this code, we stop completing commands under
1399	 * load.
1400	 *
1401	 * Peter J says we shouldn't do this.  The documentation says we
1402	 * should.  Who is right?
1403	 */
1404	while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
1405	    ;				/* XXX aiee! what if it dies? */
1406#endif
1407
1408	worked = 1;			/* got some work */
1409    }
1410
1411    splx(s);
1412    return(worked);
1413}
1414
1415static int
1416amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
1417{
1418    int		s, worked;
1419    u_int8_t	istat;
1420
1421    debug_called(3);
1422
1423    worked = 0;
1424    s = splbio();
1425
1426    /* check for valid interrupt status */
1427    istat = AMR_SGET_ISTAT(sc);
1428    if ((istat & AMR_SINTR_VALID) != 0) {
1429	AMR_SPUT_ISTAT(sc, istat);	/* ack interrupt status */
1430
1431	/* save mailbox, which contains a list of completed commands */
1432	bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
1433
1434	AMR_SACK_INTERRUPT(sc);		/* acknowledge we have the mailbox */
1435	worked = 1;
1436    }
1437
1438    splx(s);
1439    return(worked);
1440}
1441
1442/********************************************************************************
1443 * Notify the controller of the mailbox location.
1444 */
1445static void
1446amr_std_attach_mailbox(struct amr_softc *sc)
1447{
1448
1449    /* program the mailbox physical address */
1450    AMR_SBYTE_SET(sc, AMR_SMBOX_0, sc->amr_mailboxphys         & 0xff);
1451    AMR_SBYTE_SET(sc, AMR_SMBOX_1, (sc->amr_mailboxphys >>  8) & 0xff);
1452    AMR_SBYTE_SET(sc, AMR_SMBOX_2, (sc->amr_mailboxphys >> 16) & 0xff);
1453    AMR_SBYTE_SET(sc, AMR_SMBOX_3, (sc->amr_mailboxphys >> 24) & 0xff);
1454    AMR_SBYTE_SET(sc, AMR_SMBOX_ENABLE, AMR_SMBOX_ADDR);
1455
1456    /* clear any outstanding interrupt and enable interrupts proper */
1457    AMR_SACK_INTERRUPT(sc);
1458    AMR_SENABLE_INTR(sc);
1459}
1460
1461#ifdef AMR_BOARD_INIT
1462/********************************************************************************
1463 * Initialise the controller
1464 */
1465static int
1466amr_quartz_init(struct amr_softc *sc)
1467{
1468    int		status, ostatus;
1469
1470    device_printf(sc->amr_dev, "initial init status %x\n", AMR_QGET_INITSTATUS(sc));
1471
1472    AMR_QRESET(sc);
1473
1474    ostatus = 0xff;
1475    while ((status = AMR_QGET_INITSTATUS(sc)) != AMR_QINIT_DONE) {
1476	if (status != ostatus) {
1477	    device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_qinit, status));
1478	    ostatus = status;
1479	}
1480	switch (status) {
1481	case AMR_QINIT_NOMEM:
1482	    return(ENOMEM);
1483
1484	case AMR_QINIT_SCAN:
1485	    /* XXX we could print channel/target here */
1486	    break;
1487	}
1488    }
1489    return(0);
1490}
1491
1492static int
1493amr_std_init(struct amr_softc *sc)
1494{
1495    int		status, ostatus;
1496
1497    device_printf(sc->amr_dev, "initial init status %x\n", AMR_SGET_INITSTATUS(sc));
1498
1499    AMR_SRESET(sc);
1500
1501    ostatus = 0xff;
1502    while ((status = AMR_SGET_INITSTATUS(sc)) != AMR_SINIT_DONE) {
1503	if (status != ostatus) {
1504	    device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_sinit, status));
1505	    ostatus = status;
1506	}
1507	switch (status) {
1508	case AMR_SINIT_NOMEM:
1509	    return(ENOMEM);
1510
1511	case AMR_SINIT_INPROG:
1512	    /* XXX we could print channel/target here? */
1513	    break;
1514	}
1515    }
1516    return(0);
1517}
1518#endif
1519
1520/********************************************************************************
1521 ********************************************************************************
1522                                                                        Debugging
1523 ********************************************************************************
1524 ********************************************************************************/
1525
1526/********************************************************************************
1527 * Identify the controller and print some information about it.
1528 */
1529static void
1530amr_describe_controller(struct amr_softc *sc)
1531{
1532    struct amr_prodinfo	*ap;
1533    struct amr_enquiry	*ae;
1534    char		*prod;
1535
1536    /*
1537     * Try to get 40LD product info, which tells us what the card is labelled as.
1538     */
1539    if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0)) != NULL) {
1540	device_printf(sc->amr_dev, "<%.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n",
1541		      ap->ap_product, ap->ap_firmware, ap->ap_bios,
1542		      ap->ap_memsize);
1543
1544	free(ap, M_DEVBUF);
1545	return;
1546    }
1547
1548    /*
1549     * Try 8LD extended ENQUIRY to get controller signature, and use lookup table.
1550     */
1551    if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0)) != NULL) {
1552	prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature);
1553
1554    } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0)) != NULL) {
1555
1556	/*
1557	 * Try to work it out based on the PCI signatures.
1558	 */
1559	switch (pci_get_device(sc->amr_dev)) {
1560	case 0x9010:
1561	    prod = "Series 428";
1562	    break;
1563	case 0x9060:
1564	    prod = "Series 434";
1565	    break;
1566	default:
1567	    prod = "unknown controller";
1568	    break;
1569	}
1570    } else {
1571	prod = "unsupported controller";
1572    }
1573    device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n",
1574		  prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios,
1575		  ae->ae_adapter.aa_memorysize);
1576    free(ae, M_DEVBUF);
1577}
1578
1579#ifdef AMR_DEBUG
1580/********************************************************************************
1581 * Print the command (ac) in human-readable format
1582 */
1583static void
1584amr_printcommand(struct amr_command *ac)
1585{
1586    struct amr_softc	*sc = ac->ac_sc;
1587    struct amr_sgentry	*sg;
1588    int			i;
1589
1590    device_printf(sc->amr_dev, "cmd %x  ident %d  drive %d\n",
1591		  ac->ac_mailbox.mb_command, ac->ac_mailbox.mb_ident, ac->ac_mailbox.mb_drive);
1592    device_printf(sc->amr_dev, "blkcount %d  lba %d\n",
1593		  ac->ac_mailbox.mb_blkcount, ac->ac_mailbox.mb_lba);
1594    device_printf(sc->amr_dev, "virtaddr %p  length %lu\n", ac->ac_data, (unsigned long)ac->ac_length);
1595    device_printf(sc->amr_dev, "sg physaddr %08x  nsg %d\n",
1596		  ac->ac_mailbox.mb_physaddr, ac->ac_mailbox.mb_nsgelem);
1597    device_printf(sc->amr_dev, "ccb %p  bio %p\n", ac->ac_ccb_data, ac->ac_bio);
1598
1599    /* get base address of s/g table */
1600    sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
1601    for (i = 0; i < ac->ac_mailbox.mb_nsgelem; i++, sg++)
1602	device_printf(sc->amr_dev, "  %x/%d\n", sg->sg_addr, sg->sg_count);
1603}
1604#endif
1605