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