amr.c revision 184573
1/*-
2 * Copyright (c) 1999,2000 Michael Smith
3 * Copyright (c) 2000 BSDi
4 * Copyright (c) 2005 Scott Long
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28/*-
29 * Copyright (c) 2002 Eric Moore
30 * Copyright (c) 2002, 2004 LSI Logic Corporation
31 * All rights reserved.
32 *
33 * Redistribution and use in source and binary forms, with or without
34 * modification, are permitted provided that the following conditions
35 * are met:
36 * 1. Redistributions of source code must retain the above copyright
37 *    notice, this list of conditions and the following disclaimer.
38 * 2. Redistributions in binary form must reproduce the above copyright
39 *    notice, this list of conditions and the following disclaimer in the
40 *    documentation and/or other materials provided with the distribution.
41 * 3. The party using or redistributing the source code and binary forms
42 *    agrees to the disclaimer below and the terms and conditions set forth
43 *    herein.
44 *
45 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
46 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
47 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
48 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
49 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
50 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
51 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
53 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
54 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
55 * SUCH DAMAGE.
56 */
57
58#include <sys/cdefs.h>
59__FBSDID("$FreeBSD: head/sys/dev/amr/amr.c 184573 2008-11-03 00:53:54Z scottl $");
60
61/*
62 * Driver for the AMI MegaRaid family of controllers.
63 */
64
65#include <sys/param.h>
66#include <sys/systm.h>
67#include <sys/malloc.h>
68#include <sys/kernel.h>
69#include <sys/proc.h>
70#include <sys/sysctl.h>
71
72#include <sys/bio.h>
73#include <sys/bus.h>
74#include <sys/conf.h>
75#include <sys/stat.h>
76
77#include <machine/bus.h>
78#include <machine/cpu.h>
79#include <machine/resource.h>
80#include <sys/rman.h>
81
82#include <dev/pci/pcireg.h>
83#include <dev/pci/pcivar.h>
84
85#include <dev/amr/amrio.h>
86#include <dev/amr/amrreg.h>
87#include <dev/amr/amrvar.h>
88#define AMR_DEFINE_TABLES
89#include <dev/amr/amr_tables.h>
90
91SYSCTL_NODE(_hw, OID_AUTO, amr, CTLFLAG_RD, 0, "AMR driver parameters");
92
93static d_open_t         amr_open;
94static d_close_t        amr_close;
95static d_ioctl_t        amr_ioctl;
96
97static struct cdevsw amr_cdevsw = {
98	.d_version =	D_VERSION,
99	.d_flags =	D_NEEDGIANT,
100	.d_open =	amr_open,
101	.d_close =	amr_close,
102	.d_ioctl =	amr_ioctl,
103	.d_name =	"amr",
104};
105
106int linux_no_adapter = 0;
107/*
108 * Initialisation, bus interface.
109 */
110static void	amr_startup(void *arg);
111
112/*
113 * Command wrappers
114 */
115static int	amr_query_controller(struct amr_softc *sc);
116static void	*amr_enquiry(struct amr_softc *sc, size_t bufsize,
117			     u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual, int *status);
118static void	amr_completeio(struct amr_command *ac);
119static int	amr_support_ext_cdb(struct amr_softc *sc);
120
121/*
122 * Command buffer allocation.
123 */
124static void	amr_alloccmd_cluster(struct amr_softc *sc);
125static void	amr_freecmd_cluster(struct amr_command_cluster *acc);
126
127/*
128 * Command processing.
129 */
130static int	amr_bio_command(struct amr_softc *sc, struct amr_command **acp);
131static int	amr_wait_command(struct amr_command *ac) __unused;
132static int	amr_mapcmd(struct amr_command *ac);
133static void	amr_unmapcmd(struct amr_command *ac);
134static int	amr_start(struct amr_command *ac);
135static void	amr_complete(void *context, ac_qhead_t *head);
136static void	amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
137static void	amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
138static void	amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegments, int error);
139static void	amr_abort_load(struct amr_command *ac);
140
141/*
142 * Status monitoring
143 */
144static void	amr_periodic(void *data);
145
146/*
147 * Interface-specific shims
148 */
149static int	amr_quartz_submit_command(struct amr_command *ac);
150static int	amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
151static int	amr_quartz_poll_command(struct amr_command *ac);
152static int	amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac);
153
154static int	amr_std_submit_command(struct amr_command *ac);
155static int	amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave);
156static int	amr_std_poll_command(struct amr_command *ac);
157static void	amr_std_attach_mailbox(struct amr_softc *sc);
158
159#ifdef AMR_BOARD_INIT
160static int	amr_quartz_init(struct amr_softc *sc);
161static int	amr_std_init(struct amr_softc *sc);
162#endif
163
164/*
165 * Debugging
166 */
167static void	amr_describe_controller(struct amr_softc *sc);
168#ifdef AMR_DEBUG
169#if 0
170static void	amr_printcommand(struct amr_command *ac);
171#endif
172#endif
173
174static void	amr_init_sysctl(struct amr_softc *sc);
175static int	amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr,
176		    int32_t flag, d_thread_t *td);
177
178MALLOC_DEFINE(M_AMR, "amr", "AMR memory");
179
180/********************************************************************************
181 ********************************************************************************
182                                                                      Inline Glue
183 ********************************************************************************
184 ********************************************************************************/
185
186/********************************************************************************
187 ********************************************************************************
188                                                                Public Interfaces
189 ********************************************************************************
190 ********************************************************************************/
191
192/********************************************************************************
193 * Initialise the controller and softc.
194 */
195int
196amr_attach(struct amr_softc *sc)
197{
198    device_t child;
199
200    debug_called(1);
201
202    /*
203     * Initialise per-controller queues.
204     */
205    amr_init_qhead(&sc->amr_freecmds);
206    amr_init_qhead(&sc->amr_ready);
207    TAILQ_INIT(&sc->amr_cmd_clusters);
208    bioq_init(&sc->amr_bioq);
209
210    debug(2, "queue init done");
211
212    /*
213     * Configure for this controller type.
214     */
215    if (AMR_IS_QUARTZ(sc)) {
216	sc->amr_submit_command = amr_quartz_submit_command;
217	sc->amr_get_work       = amr_quartz_get_work;
218	sc->amr_poll_command   = amr_quartz_poll_command;
219	sc->amr_poll_command1  = amr_quartz_poll_command1;
220    } else {
221	sc->amr_submit_command = amr_std_submit_command;
222	sc->amr_get_work       = amr_std_get_work;
223	sc->amr_poll_command   = amr_std_poll_command;
224	amr_std_attach_mailbox(sc);;
225    }
226
227#ifdef AMR_BOARD_INIT
228    if ((AMR_IS_QUARTZ(sc) ? amr_quartz_init(sc) : amr_std_init(sc))))
229	return(ENXIO);
230#endif
231
232    /*
233     * Allocate initial commands.
234     */
235    amr_alloccmd_cluster(sc);
236
237    /*
238     * Quiz controller for features and limits.
239     */
240    if (amr_query_controller(sc))
241	return(ENXIO);
242
243    debug(2, "controller query complete");
244
245    /*
246     * preallocate the remaining commands.
247     */
248    while (sc->amr_nextslot < sc->amr_maxio)
249	amr_alloccmd_cluster(sc);
250
251    /*
252     * Setup sysctls.
253     */
254    amr_init_sysctl(sc);
255
256    /*
257     * Attach our 'real' SCSI channels to CAM.
258     */
259    child = device_add_child(sc->amr_dev, "amrp", -1);
260    sc->amr_pass = child;
261    if (child != NULL) {
262	device_set_softc(child, sc);
263	device_set_desc(child, "SCSI Passthrough Bus");
264	bus_generic_attach(sc->amr_dev);
265    }
266
267    /*
268     * Create the control device.
269     */
270    sc->amr_dev_t = make_dev(&amr_cdevsw, device_get_unit(sc->amr_dev), UID_ROOT, GID_OPERATOR,
271			     S_IRUSR | S_IWUSR, "amr%d", device_get_unit(sc->amr_dev));
272    sc->amr_dev_t->si_drv1 = sc;
273    linux_no_adapter++;
274    if (device_get_unit(sc->amr_dev) == 0)
275	make_dev_alias(sc->amr_dev_t, "megadev0");
276
277    /*
278     * Schedule ourselves to bring the controller up once interrupts are
279     * available.
280     */
281    bzero(&sc->amr_ich, sizeof(struct intr_config_hook));
282    sc->amr_ich.ich_func = amr_startup;
283    sc->amr_ich.ich_arg = sc;
284    if (config_intrhook_establish(&sc->amr_ich) != 0) {
285	device_printf(sc->amr_dev, "can't establish configuration hook\n");
286	return(ENOMEM);
287    }
288
289    /*
290     * Print a little information about the controller.
291     */
292    amr_describe_controller(sc);
293
294    debug(2, "attach complete");
295    return(0);
296}
297
298/********************************************************************************
299 * Locate disk resources and attach children to them.
300 */
301static void
302amr_startup(void *arg)
303{
304    struct amr_softc	*sc = (struct amr_softc *)arg;
305    struct amr_logdrive	*dr;
306    int			i, error;
307
308    debug_called(1);
309
310    /* pull ourselves off the intrhook chain */
311    if (sc->amr_ich.ich_func)
312	config_intrhook_disestablish(&sc->amr_ich);
313    sc->amr_ich.ich_func = NULL;
314
315    /* get up-to-date drive information */
316    if (amr_query_controller(sc)) {
317	device_printf(sc->amr_dev, "can't scan controller for drives\n");
318	return;
319    }
320
321    /* iterate over available drives */
322    for (i = 0, dr = &sc->amr_drive[0]; (i < AMR_MAXLD) && (dr->al_size != 0xffffffff); i++, dr++) {
323	/* are we already attached to this drive? */
324	if (dr->al_disk == 0) {
325	    /* generate geometry information */
326	    if (dr->al_size > 0x200000) {	/* extended translation? */
327		dr->al_heads = 255;
328		dr->al_sectors = 63;
329	    } else {
330		dr->al_heads = 64;
331		dr->al_sectors = 32;
332	    }
333	    dr->al_cylinders = dr->al_size / (dr->al_heads * dr->al_sectors);
334
335	    dr->al_disk = device_add_child(sc->amr_dev, NULL, -1);
336	    if (dr->al_disk == 0)
337		device_printf(sc->amr_dev, "device_add_child failed\n");
338	    device_set_ivars(dr->al_disk, dr);
339	}
340    }
341
342    if ((error = bus_generic_attach(sc->amr_dev)) != 0)
343	device_printf(sc->amr_dev, "bus_generic_attach returned %d\n", error);
344
345    /* mark controller back up */
346    sc->amr_state &= ~AMR_STATE_SHUTDOWN;
347
348    /* interrupts will be enabled before we do anything more */
349    sc->amr_state |= AMR_STATE_INTEN;
350
351    /*
352     * Start the timeout routine.
353     */
354/*    sc->amr_timeout = timeout(amr_periodic, sc, hz);*/
355
356    return;
357}
358
359static void
360amr_init_sysctl(struct amr_softc *sc)
361{
362
363    SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
364	SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
365	OID_AUTO, "allow_volume_configure", CTLFLAG_RW, &sc->amr_allow_vol_config, 0,
366	"");
367    SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
368	SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
369	OID_AUTO, "nextslot", CTLFLAG_RD, &sc->amr_nextslot, 0,
370	"");
371    SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
372	SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
373	OID_AUTO, "busyslots", CTLFLAG_RD, &sc->amr_busyslots, 0,
374	"");
375    SYSCTL_ADD_INT(device_get_sysctl_ctx(sc->amr_dev),
376	SYSCTL_CHILDREN(device_get_sysctl_tree(sc->amr_dev)),
377	OID_AUTO, "maxio", CTLFLAG_RD, &sc->amr_maxio, 0,
378	"");
379}
380
381
382/*******************************************************************************
383 * Free resources associated with a controller instance
384 */
385void
386amr_free(struct amr_softc *sc)
387{
388    struct amr_command_cluster	*acc;
389
390    /* detach from CAM */
391    if (sc->amr_pass != NULL)
392	device_delete_child(sc->amr_dev, sc->amr_pass);
393
394    /* cancel status timeout */
395    untimeout(amr_periodic, sc, sc->amr_timeout);
396
397    /* throw away any command buffers */
398    while ((acc = TAILQ_FIRST(&sc->amr_cmd_clusters)) != NULL) {
399	TAILQ_REMOVE(&sc->amr_cmd_clusters, acc, acc_link);
400	amr_freecmd_cluster(acc);
401    }
402
403    /* destroy control device */
404    if( sc->amr_dev_t != (struct cdev *)NULL)
405	    destroy_dev(sc->amr_dev_t);
406
407    if (mtx_initialized(&sc->amr_hw_lock))
408	mtx_destroy(&sc->amr_hw_lock);
409
410    if (mtx_initialized(&sc->amr_list_lock))
411	mtx_destroy(&sc->amr_list_lock);
412}
413
414/*******************************************************************************
415 * Receive a bio structure from a child device and queue it on a particular
416 * disk resource, then poke the disk resource to start as much work as it can.
417 */
418int
419amr_submit_bio(struct amr_softc *sc, struct bio *bio)
420{
421    debug_called(2);
422
423    mtx_lock(&sc->amr_list_lock);
424    amr_enqueue_bio(sc, bio);
425    amr_startio(sc);
426    mtx_unlock(&sc->amr_list_lock);
427    return(0);
428}
429
430/********************************************************************************
431 * Accept an open operation on the control device.
432 */
433static int
434amr_open(struct cdev *dev, int flags, int fmt, d_thread_t *td)
435{
436    int			unit = dev2unit(dev);
437    struct amr_softc	*sc = devclass_get_softc(devclass_find("amr"), unit);
438
439    debug_called(1);
440
441    sc->amr_state |= AMR_STATE_OPEN;
442    return(0);
443}
444
445#ifdef LSI
446static int
447amr_del_ld(struct amr_softc *sc, int drv_no, int status)
448{
449
450    debug_called(1);
451
452    sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
453    sc->amr_state &= ~AMR_STATE_LD_DELETE;
454    sc->amr_state |= AMR_STATE_REMAP_LD;
455    debug(1, "State Set");
456
457    if (!status) {
458	debug(1, "disk begin destroyed %d",drv_no);
459	if (--amr_disks_registered == 0)
460	    cdevsw_remove(&amrddisk_cdevsw);
461	debug(1, "disk begin destroyed success");
462    }
463    return 0;
464}
465
466static int
467amr_prepare_ld_delete(struct amr_softc *sc)
468{
469
470    debug_called(1);
471    if (sc->ld_del_supported == 0)
472	return(ENOIOCTL);
473
474    sc->amr_state |= AMR_STATE_QUEUE_FRZN;
475    sc->amr_state |= AMR_STATE_LD_DELETE;
476
477    /* 5 minutes for the all the commands to be flushed.*/
478    tsleep((void *)&sc->ld_del_supported, PCATCH | PRIBIO,"delete_logical_drv",hz * 60 * 1);
479    if ( sc->amr_busyslots )
480	return(ENOIOCTL);
481
482    return 0;
483}
484#endif
485
486/********************************************************************************
487 * Accept the last close on the control device.
488 */
489static int
490amr_close(struct cdev *dev, int flags, int fmt, d_thread_t *td)
491{
492    int			unit = dev2unit(dev);
493    struct amr_softc	*sc = devclass_get_softc(devclass_find("amr"), unit);
494
495    debug_called(1);
496
497    sc->amr_state &= ~AMR_STATE_OPEN;
498    return (0);
499}
500
501/********************************************************************************
502 * Handle controller-specific control operations.
503 */
504static void
505amr_rescan_drives(struct cdev *dev)
506{
507    struct amr_softc	*sc = (struct amr_softc *)dev->si_drv1;
508    int			i, error = 0;
509
510    sc->amr_state |= AMR_STATE_REMAP_LD;
511    while (sc->amr_busyslots) {
512	device_printf(sc->amr_dev, "idle controller\n");
513	amr_done(sc);
514    }
515
516    /* mark ourselves as in-shutdown */
517    sc->amr_state |= AMR_STATE_SHUTDOWN;
518
519    /* flush controller */
520    device_printf(sc->amr_dev, "flushing cache...");
521    printf("%s\n", amr_flush(sc) ? "failed" : "done");
522
523    /* delete all our child devices */
524    for(i = 0 ; i < AMR_MAXLD; i++) {
525	if(sc->amr_drive[i].al_disk != 0) {
526	    if((error = device_delete_child(sc->amr_dev,
527		sc->amr_drive[i].al_disk)) != 0)
528		goto shutdown_out;
529
530	     sc->amr_drive[i].al_disk = 0;
531	}
532    }
533
534shutdown_out:
535    amr_startup(sc);
536}
537
538int
539amr_linux_ioctl_int(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag,
540    d_thread_t *td)
541{
542    struct amr_softc		*sc = (struct amr_softc *)dev->si_drv1;
543    struct amr_command		*ac;
544    struct amr_mailbox		*mb;
545    struct amr_linux_ioctl	ali;
546    void			*dp, *temp;
547    int				error;
548    int				adapter, len, ac_flags = 0;
549    int				logical_drives_changed = 0;
550    u_int32_t			linux_version = 0x02100000;
551    u_int8_t			status;
552    struct amr_passthrough	*ap;	/* 60 bytes */
553
554    error = 0;
555    dp = NULL;
556    ac = NULL;
557    ap = NULL;
558
559    if ((error = copyin(addr, &ali, sizeof(ali))) != 0)
560	return (error);
561    switch (ali.ui.fcs.opcode) {
562    case 0x82:
563	switch(ali.ui.fcs.subopcode) {
564	case 'e':
565	    copyout(&linux_version, (void *)(uintptr_t)ali.data,
566		sizeof(linux_version));
567	    error = 0;
568	    break;
569
570	case 'm':
571	    copyout(&linux_no_adapter, (void *)(uintptr_t)ali.data,
572		sizeof(linux_no_adapter));
573	    td->td_retval[0] = linux_no_adapter;
574	    error = 0;
575	    break;
576
577	default:
578	    printf("Unknown subopcode\n");
579	    error = ENOIOCTL;
580	    break;
581	}
582    break;
583
584    case 0x80:
585    case 0x81:
586	if (ali.ui.fcs.opcode == 0x80)
587	    len = max(ali.outlen, ali.inlen);
588	else
589	    len = ali.ui.fcs.length;
590
591	adapter = (ali.ui.fcs.adapno) ^ 'm' << 8;
592
593	mb = (void *)&ali.mbox[0];
594
595	if ((ali.mbox[0] == FC_DEL_LOGDRV  && ali.mbox[2] == OP_DEL_LOGDRV) ||	/* delete */
596	    (ali.mbox[0] == AMR_CMD_CONFIG && ali.mbox[2] == 0x0d)) {		/* create */
597	    if (sc->amr_allow_vol_config == 0) {
598		error = EPERM;
599		break;
600	    }
601	    logical_drives_changed = 1;
602	}
603
604	if (ali.mbox[0] == AMR_CMD_PASS) {
605	    mtx_lock(&sc->amr_list_lock);
606	    while ((ac = amr_alloccmd(sc)) == NULL)
607		msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
608	    mtx_unlock(&sc->amr_list_lock);
609	    ap = &ac->ac_ccb->ccb_pthru;
610
611	    error = copyin((void *)(uintptr_t)mb->mb_physaddr, ap,
612		sizeof(struct amr_passthrough));
613	    if (error)
614		break;
615
616	    if (ap->ap_data_transfer_length)
617		dp = malloc(ap->ap_data_transfer_length, M_AMR,
618		    M_WAITOK | M_ZERO);
619
620	    if (ali.inlen) {
621		error = copyin((void *)(uintptr_t)ap->ap_data_transfer_address,
622		    dp, ap->ap_data_transfer_length);
623		if (error)
624		    break;
625	    }
626
627	    ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT|AMR_CMD_CCB;
628	    bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox));
629	    ac->ac_mailbox.mb_command = AMR_CMD_PASS;
630	    ac->ac_flags = ac_flags;
631
632	    ac->ac_data = dp;
633	    ac->ac_length = ap->ap_data_transfer_length;
634	    temp = (void *)(uintptr_t)ap->ap_data_transfer_address;
635
636	    mtx_lock(&sc->amr_list_lock);
637	    error = amr_wait_command(ac);
638	    mtx_unlock(&sc->amr_list_lock);
639	    if (error)
640		break;
641
642	    status = ac->ac_status;
643	    error = copyout(&status, &((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_scsi_status, sizeof(status));
644	    if (error)
645		break;
646
647	    if (ali.outlen) {
648		error = copyout(dp, temp, ap->ap_data_transfer_length);
649	        if (error)
650		    break;
651	    }
652	    error = copyout(ap->ap_request_sense_area, ((struct amr_passthrough *)(uintptr_t)mb->mb_physaddr)->ap_request_sense_area, ap->ap_request_sense_length);
653	    if (error)
654		break;
655
656	    error = 0;
657	    break;
658	} else if (ali.mbox[0] == AMR_CMD_PASS_64) {
659	    printf("No AMR_CMD_PASS_64\n");
660	    error = ENOIOCTL;
661	    break;
662	} else if (ali.mbox[0] == AMR_CMD_EXTPASS) {
663	    printf("No AMR_CMD_EXTPASS\n");
664	    error = ENOIOCTL;
665	    break;
666	} else {
667	    /*
668	     * Bug-for-bug compatibility with Linux!
669	     * Some apps will send commands with inlen and outlen set to 0,
670	     * even though they expect data to be transfered to them from the
671	     * card.  Linux accidentally allows this by allocating a 4KB
672	     * buffer for the transfer anyways, but it then throws it away
673	     * without copying it back to the app.
674	     */
675	    if (!len)
676		len = 4096;
677
678	    dp = malloc(len, M_AMR, M_WAITOK | M_ZERO);
679
680	    if (ali.inlen) {
681		error = copyin((void *)(uintptr_t)mb->mb_physaddr, dp, len);
682		if (error)
683		    break;
684	    }
685
686	    mtx_lock(&sc->amr_list_lock);
687	    while ((ac = amr_alloccmd(sc)) == NULL)
688		msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
689
690	    ac_flags = AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
691	    bzero(&ac->ac_mailbox, sizeof(ac->ac_mailbox));
692	    bcopy(&ali.mbox[0], &ac->ac_mailbox, sizeof(ali.mbox));
693
694	    ac->ac_length = len;
695	    ac->ac_data = dp;
696	    ac->ac_flags = ac_flags;
697
698	    error = amr_wait_command(ac);
699	    mtx_unlock(&sc->amr_list_lock);
700	    if (error)
701		break;
702
703	    status = ac->ac_status;
704	    error = copyout(&status, &((struct amr_mailbox *)&((struct amr_linux_ioctl *)addr)->mbox[0])->mb_status, sizeof(status));
705	    if (ali.outlen) {
706		error = copyout(dp, (void *)(uintptr_t)mb->mb_physaddr, len);
707		if (error)
708		    break;
709	    }
710
711	    error = 0;
712	    if (logical_drives_changed)
713		amr_rescan_drives(dev);
714	    break;
715	}
716	break;
717
718    default:
719	debug(1, "unknown linux ioctl 0x%lx", cmd);
720	printf("unknown linux ioctl 0x%lx\n", cmd);
721	error = ENOIOCTL;
722	break;
723    }
724
725    /*
726     * At this point, we know that there is a lock held and that these
727     * objects have been allocated.
728     */
729    mtx_lock(&sc->amr_list_lock);
730    if (ac != NULL)
731	amr_releasecmd(ac);
732    mtx_unlock(&sc->amr_list_lock);
733    if (dp != NULL)
734	free(dp, M_AMR);
735    return(error);
736}
737
738static int
739amr_ioctl(struct cdev *dev, u_long cmd, caddr_t addr, int32_t flag, d_thread_t *td)
740{
741    struct amr_softc		*sc = (struct amr_softc *)dev->si_drv1;
742    union {
743	void			*_p;
744	struct amr_user_ioctl	*au;
745#ifdef AMR_IO_COMMAND32
746	struct amr_user_ioctl32	*au32;
747#endif
748	int			*result;
749    } arg;
750    struct amr_command		*ac;
751    struct amr_mailbox_ioctl	*mbi;
752    void			*dp, *au_buffer;
753    unsigned long		au_length;
754    unsigned char		*au_cmd;
755    int				*au_statusp, au_direction;
756    int				error;
757    struct amr_passthrough	*ap;	/* 60 bytes */
758    int				logical_drives_changed = 0;
759
760    debug_called(1);
761
762    arg._p = (void *)addr;
763
764    error = 0;
765    dp = NULL;
766    ac = NULL;
767    ap = NULL;
768
769    switch(cmd) {
770
771    case AMR_IO_VERSION:
772	debug(1, "AMR_IO_VERSION");
773	*arg.result = AMR_IO_VERSION_NUMBER;
774	return(0);
775
776#ifdef AMR_IO_COMMAND32
777    /*
778     * Accept ioctl-s from 32-bit binaries on non-32-bit
779     * platforms, such as AMD. LSI's MEGAMGR utility is
780     * the only example known today...	-mi
781     */
782    case AMR_IO_COMMAND32:
783	debug(1, "AMR_IO_COMMAND32 0x%x", arg.au32->au_cmd[0]);
784	au_cmd = arg.au32->au_cmd;
785	au_buffer = (void *)(u_int64_t)arg.au32->au_buffer;
786	au_length = arg.au32->au_length;
787	au_direction = arg.au32->au_direction;
788	au_statusp = &arg.au32->au_status;
789	break;
790#endif
791
792    case AMR_IO_COMMAND:
793	debug(1, "AMR_IO_COMMAND  0x%x", arg.au->au_cmd[0]);
794	au_cmd = arg.au->au_cmd;
795	au_buffer = (void *)arg.au->au_buffer;
796	au_length = arg.au->au_length;
797	au_direction = arg.au->au_direction;
798	au_statusp = &arg.au->au_status;
799	break;
800
801    case 0xc0046d00:
802    case 0xc06e6d00:	/* Linux emulation */
803	{
804	    devclass_t			devclass;
805	    struct amr_linux_ioctl	ali;
806	    int				adapter, error;
807
808	    devclass = devclass_find("amr");
809	    if (devclass == NULL)
810		return (ENOENT);
811
812	    error = copyin(addr, &ali, sizeof(ali));
813	    if (error)
814		return (error);
815	    if (ali.ui.fcs.opcode == 0x82)
816		adapter = 0;
817	    else
818		adapter = (ali.ui.fcs.adapno) ^ 'm' << 8;
819
820	    sc = devclass_get_softc(devclass, adapter);
821	    if (sc == NULL)
822		return (ENOENT);
823
824	    return (amr_linux_ioctl_int(sc->amr_dev_t, cmd, addr, 0, td));
825	}
826    default:
827	debug(1, "unknown ioctl 0x%lx", cmd);
828	return(ENOIOCTL);
829    }
830
831    if ((au_cmd[0] == FC_DEL_LOGDRV && au_cmd[1] == OP_DEL_LOGDRV) ||	/* delete */
832	(au_cmd[0] == AMR_CMD_CONFIG && au_cmd[1] == 0x0d)) {		/* create */
833	if (sc->amr_allow_vol_config == 0) {
834	    error = EPERM;
835	    goto out;
836	}
837	logical_drives_changed = 1;
838#ifdef LSI
839	if ((error = amr_prepare_ld_delete(sc)) != 0)
840	    return (error);
841#endif
842    }
843
844    /* handle inbound data buffer */
845    if (au_length != 0 && au_cmd[0] != 0x06) {
846	if ((dp = malloc(au_length, M_AMR, M_WAITOK|M_ZERO)) == NULL) {
847	    error = ENOMEM;
848	    goto out;
849	}
850	if ((error = copyin(au_buffer, dp, au_length)) != 0) {
851	    free(dp, M_AMR);
852	    return (error);
853	}
854	debug(2, "copyin %ld bytes from %p -> %p", au_length, au_buffer, dp);
855    }
856
857    /* Allocate this now before the mutex gets held */
858
859    mtx_lock(&sc->amr_list_lock);
860    while ((ac = amr_alloccmd(sc)) == NULL)
861	msleep(sc, &sc->amr_list_lock, PPAUSE, "amrioc", hz);
862
863    /* handle SCSI passthrough command */
864    if (au_cmd[0] == AMR_CMD_PASS) {
865        int len;
866
867	ap = &ac->ac_ccb->ccb_pthru;
868	bzero(ap, sizeof(struct amr_passthrough));
869
870	/* copy cdb */
871        len = au_cmd[2];
872	ap->ap_cdb_length = len;
873	bcopy(au_cmd + 3, ap->ap_cdb, len);
874
875	/* build passthrough */
876	ap->ap_timeout		= au_cmd[len + 3] & 0x07;
877	ap->ap_ars		= (au_cmd[len + 3] & 0x08) ? 1 : 0;
878	ap->ap_islogical		= (au_cmd[len + 3] & 0x80) ? 1 : 0;
879	ap->ap_logical_drive_no	= au_cmd[len + 4];
880	ap->ap_channel		= au_cmd[len + 5];
881	ap->ap_scsi_id 		= au_cmd[len + 6];
882	ap->ap_request_sense_length	= 14;
883	ap->ap_data_transfer_length	= au_length;
884	/* XXX what about the request-sense area? does the caller want it? */
885
886	/* build command */
887	ac->ac_mailbox.mb_command = AMR_CMD_PASS;
888	ac->ac_flags = AMR_CMD_CCB;
889
890    } else {
891	/* direct command to controller */
892	mbi = (struct amr_mailbox_ioctl *)&ac->ac_mailbox;
893
894	/* copy pertinent mailbox items */
895	mbi->mb_command = au_cmd[0];
896	mbi->mb_channel = au_cmd[1];
897	mbi->mb_param = au_cmd[2];
898	mbi->mb_pad[0] = au_cmd[3];
899	mbi->mb_drive = au_cmd[4];
900	ac->ac_flags = 0;
901    }
902
903    /* build the command */
904    ac->ac_data = dp;
905    ac->ac_length = au_length;
906    ac->ac_flags |= AMR_CMD_DATAIN|AMR_CMD_DATAOUT;
907
908    /* run the command */
909    error = amr_wait_command(ac);
910    mtx_unlock(&sc->amr_list_lock);
911    if (error)
912	goto out;
913
914    /* copy out data and set status */
915    if (au_length != 0) {
916	error = copyout(dp, au_buffer, au_length);
917    }
918    debug(2, "copyout %ld bytes from %p -> %p", au_length, dp, au_buffer);
919    if (dp != NULL)
920	debug(2, "%p status 0x%x", dp, ac->ac_status);
921    *au_statusp = ac->ac_status;
922
923out:
924    /*
925     * At this point, we know that there is a lock held and that these
926     * objects have been allocated.
927     */
928    mtx_lock(&sc->amr_list_lock);
929    if (ac != NULL)
930	amr_releasecmd(ac);
931    mtx_unlock(&sc->amr_list_lock);
932    if (dp != NULL)
933	free(dp, M_AMR);
934
935#ifndef LSI
936    if (logical_drives_changed)
937	amr_rescan_drives(dev);
938#endif
939
940    return(error);
941}
942
943/********************************************************************************
944 ********************************************************************************
945                                                                Status Monitoring
946 ********************************************************************************
947 ********************************************************************************/
948
949/********************************************************************************
950 * Perform a periodic check of the controller status
951 */
952static void
953amr_periodic(void *data)
954{
955    struct amr_softc	*sc = (struct amr_softc *)data;
956
957    debug_called(2);
958
959    /* XXX perform periodic status checks here */
960
961    /* compensate for missed interrupts */
962    amr_done(sc);
963
964    /* reschedule */
965    sc->amr_timeout = timeout(amr_periodic, sc, hz);
966}
967
968/********************************************************************************
969 ********************************************************************************
970                                                                 Command Wrappers
971 ********************************************************************************
972 ********************************************************************************/
973
974/********************************************************************************
975 * Interrogate the controller for the operational parameters we require.
976 */
977static int
978amr_query_controller(struct amr_softc *sc)
979{
980    struct amr_enquiry3	*aex;
981    struct amr_prodinfo	*ap;
982    struct amr_enquiry	*ae;
983    int			ldrv;
984    int			status;
985
986    /*
987     * Greater than 10 byte cdb support
988     */
989    sc->support_ext_cdb = amr_support_ext_cdb(sc);
990
991    if(sc->support_ext_cdb) {
992	debug(2,"supports extended CDBs.");
993    }
994
995    /*
996     * Try to issue an ENQUIRY3 command
997     */
998    if ((aex = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_ENQ3,
999			   AMR_CONFIG_ENQ3_SOLICITED_FULL, &status)) != NULL) {
1000
1001	/*
1002	 * Fetch current state of logical drives.
1003	 */
1004	for (ldrv = 0; ldrv < aex->ae_numldrives; ldrv++) {
1005	    sc->amr_drive[ldrv].al_size       = aex->ae_drivesize[ldrv];
1006	    sc->amr_drive[ldrv].al_state      = aex->ae_drivestate[ldrv];
1007	    sc->amr_drive[ldrv].al_properties = aex->ae_driveprop[ldrv];
1008	    debug(2, "  drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
1009		  sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
1010	}
1011	free(aex, M_AMR);
1012
1013	/*
1014	 * Get product info for channel count.
1015	 */
1016	if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0, &status)) == NULL) {
1017	    device_printf(sc->amr_dev, "can't obtain product data from controller\n");
1018	    return(1);
1019	}
1020	sc->amr_maxdrives = 40;
1021	sc->amr_maxchan = ap->ap_nschan;
1022	sc->amr_maxio = ap->ap_maxio;
1023	sc->amr_type |= AMR_TYPE_40LD;
1024	free(ap, M_AMR);
1025
1026	ap = amr_enquiry(sc, 0, FC_DEL_LOGDRV, OP_SUP_DEL_LOGDRV, 0, &status);
1027	if (ap != NULL)
1028	    free(ap, M_AMR);
1029	if (!status) {
1030	    sc->amr_ld_del_supported = 1;
1031	    device_printf(sc->amr_dev, "delete logical drives supported by controller\n");
1032	}
1033    } else {
1034
1035	/* failed, try the 8LD ENQUIRY commands */
1036	if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0, &status)) == NULL) {
1037	    if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0, &status)) == NULL) {
1038		device_printf(sc->amr_dev, "can't obtain configuration data from controller\n");
1039		return(1);
1040	    }
1041	    ae->ae_signature = 0;
1042	}
1043
1044	/*
1045	 * Fetch current state of logical drives.
1046	 */
1047	for (ldrv = 0; ldrv < ae->ae_ldrv.al_numdrives; ldrv++) {
1048	    sc->amr_drive[ldrv].al_size       = ae->ae_ldrv.al_size[ldrv];
1049	    sc->amr_drive[ldrv].al_state      = ae->ae_ldrv.al_state[ldrv];
1050	    sc->amr_drive[ldrv].al_properties = ae->ae_ldrv.al_properties[ldrv];
1051	    debug(2, "  drive %d: %d state %x properties %x\n", ldrv, sc->amr_drive[ldrv].al_size,
1052		  sc->amr_drive[ldrv].al_state, sc->amr_drive[ldrv].al_properties);
1053	}
1054
1055	sc->amr_maxdrives = 8;
1056	sc->amr_maxchan = ae->ae_adapter.aa_channels;
1057	sc->amr_maxio = ae->ae_adapter.aa_maxio;
1058	free(ae, M_AMR);
1059    }
1060
1061    /*
1062     * Mark remaining drives as unused.
1063     */
1064    for (; ldrv < AMR_MAXLD; ldrv++)
1065	sc->amr_drive[ldrv].al_size = 0xffffffff;
1066
1067    /*
1068     * Cap the maximum number of outstanding I/Os.  AMI's Linux driver doesn't trust
1069     * the controller's reported value, and lockups have been seen when we do.
1070     */
1071    sc->amr_maxio = imin(sc->amr_maxio, AMR_LIMITCMD);
1072
1073    return(0);
1074}
1075
1076/********************************************************************************
1077 * Run a generic enquiry-style command.
1078 */
1079static void *
1080amr_enquiry(struct amr_softc *sc, size_t bufsize, u_int8_t cmd, u_int8_t cmdsub, u_int8_t cmdqual, int *status)
1081{
1082    struct amr_command	*ac;
1083    void		*result;
1084    u_int8_t		*mbox;
1085    int			error;
1086
1087    debug_called(1);
1088
1089    error = 1;
1090    result = NULL;
1091
1092    /* get ourselves a command buffer */
1093    mtx_lock(&sc->amr_list_lock);
1094    ac = amr_alloccmd(sc);
1095    mtx_unlock(&sc->amr_list_lock);
1096    if (ac == NULL)
1097	goto out;
1098    /* allocate the response structure */
1099    if ((result = malloc(bufsize, M_AMR, M_ZERO|M_NOWAIT)) == NULL)
1100	goto out;
1101    /* set command flags */
1102
1103    ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAIN;
1104
1105    /* point the command at our data */
1106    ac->ac_data = result;
1107    ac->ac_length = bufsize;
1108
1109    /* build the command proper */
1110    mbox = (u_int8_t *)&ac->ac_mailbox;		/* XXX want a real structure for this? */
1111    mbox[0] = cmd;
1112    mbox[2] = cmdsub;
1113    mbox[3] = cmdqual;
1114    *status = 0;
1115
1116    /* can't assume that interrupts are going to work here, so play it safe */
1117    if (sc->amr_poll_command(ac))
1118	goto out;
1119    error = ac->ac_status;
1120    *status = ac->ac_status;
1121
1122 out:
1123    mtx_lock(&sc->amr_list_lock);
1124    if (ac != NULL)
1125	amr_releasecmd(ac);
1126    mtx_unlock(&sc->amr_list_lock);
1127    if ((error != 0) && (result != NULL)) {
1128	free(result, M_AMR);
1129	result = NULL;
1130    }
1131    return(result);
1132}
1133
1134/********************************************************************************
1135 * Flush the controller's internal cache, return status.
1136 */
1137int
1138amr_flush(struct amr_softc *sc)
1139{
1140    struct amr_command	*ac;
1141    int			error;
1142
1143    /* get ourselves a command buffer */
1144    error = 1;
1145    mtx_lock(&sc->amr_list_lock);
1146    ac = amr_alloccmd(sc);
1147    mtx_unlock(&sc->amr_list_lock);
1148    if (ac == NULL)
1149	goto out;
1150    /* set command flags */
1151    ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
1152
1153    /* build the command proper */
1154    ac->ac_mailbox.mb_command = AMR_CMD_FLUSH;
1155
1156    /* we have to poll, as the system may be going down or otherwise damaged */
1157    if (sc->amr_poll_command(ac))
1158	goto out;
1159    error = ac->ac_status;
1160
1161 out:
1162    mtx_lock(&sc->amr_list_lock);
1163    if (ac != NULL)
1164	amr_releasecmd(ac);
1165    mtx_unlock(&sc->amr_list_lock);
1166    return(error);
1167}
1168
1169/********************************************************************************
1170 * Detect extented cdb >> greater than 10 byte cdb support
1171 * returns '1' means this support exist
1172 * returns '0' means this support doesn't exist
1173 */
1174static int
1175amr_support_ext_cdb(struct amr_softc *sc)
1176{
1177    struct amr_command	*ac;
1178    u_int8_t		*mbox;
1179    int			error;
1180
1181    /* get ourselves a command buffer */
1182    error = 0;
1183    mtx_lock(&sc->amr_list_lock);
1184    ac = amr_alloccmd(sc);
1185    mtx_unlock(&sc->amr_list_lock);
1186    if (ac == NULL)
1187	goto out;
1188    /* set command flags */
1189    ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
1190
1191    /* build the command proper */
1192    mbox = (u_int8_t *)&ac->ac_mailbox;		/* XXX want a real structure for this? */
1193    mbox[0] = 0xA4;
1194    mbox[2] = 0x16;
1195
1196
1197    /* we have to poll, as the system may be going down or otherwise damaged */
1198    if (sc->amr_poll_command(ac))
1199	goto out;
1200    if( ac->ac_status == AMR_STATUS_SUCCESS ) {
1201	    error = 1;
1202    }
1203
1204out:
1205    mtx_lock(&sc->amr_list_lock);
1206    if (ac != NULL)
1207	amr_releasecmd(ac);
1208    mtx_unlock(&sc->amr_list_lock);
1209    return(error);
1210}
1211
1212/********************************************************************************
1213 * Try to find I/O work for the controller from one or more of the work queues.
1214 *
1215 * We make the assumption that if the controller is not ready to take a command
1216 * at some given time, it will generate an interrupt at some later time when
1217 * it is.
1218 */
1219void
1220amr_startio(struct amr_softc *sc)
1221{
1222    struct amr_command	*ac;
1223
1224    /* spin until something prevents us from doing any work */
1225    for (;;) {
1226
1227	/* Don't bother to queue commands no bounce buffers are available. */
1228	if (sc->amr_state & AMR_STATE_QUEUE_FRZN)
1229	    break;
1230
1231	/* try to get a ready command */
1232	ac = amr_dequeue_ready(sc);
1233
1234	/* if that failed, build a command from a bio */
1235	if (ac == NULL)
1236	    (void)amr_bio_command(sc, &ac);
1237
1238	/* if that failed, build a command from a ccb */
1239	if ((ac == NULL) && (sc->amr_cam_command != NULL))
1240	    sc->amr_cam_command(sc, &ac);
1241
1242	/* if we don't have anything to do, give up */
1243	if (ac == NULL)
1244	    break;
1245
1246	/* try to give the command to the controller; if this fails save it for later and give up */
1247	if (amr_start(ac)) {
1248	    debug(2, "controller busy, command deferred");
1249	    amr_requeue_ready(ac);	/* XXX schedule retry very soon? */
1250	    break;
1251	}
1252    }
1253}
1254
1255/********************************************************************************
1256 * Handle completion of an I/O command.
1257 */
1258static void
1259amr_completeio(struct amr_command *ac)
1260{
1261    struct amrd_softc		*sc = ac->ac_bio->bio_disk->d_drv1;
1262    static struct timeval	lastfail;
1263    static int			curfail;
1264
1265    if (ac->ac_status != AMR_STATUS_SUCCESS) {	/* could be more verbose here? */
1266	ac->ac_bio->bio_error = EIO;
1267	ac->ac_bio->bio_flags |= BIO_ERROR;
1268
1269	if (ppsratecheck(&lastfail, &curfail, 1))
1270	    device_printf(sc->amrd_dev, "I/O error - 0x%x\n", ac->ac_status);
1271/*	amr_printcommand(ac);*/
1272    }
1273    amrd_intr(ac->ac_bio);
1274    mtx_lock(&ac->ac_sc->amr_list_lock);
1275    amr_releasecmd(ac);
1276    mtx_unlock(&ac->ac_sc->amr_list_lock);
1277}
1278
1279/********************************************************************************
1280 ********************************************************************************
1281                                                               Command Processing
1282 ********************************************************************************
1283 ********************************************************************************/
1284
1285/********************************************************************************
1286 * Convert a bio off the top of the bio queue into a command.
1287 */
1288static int
1289amr_bio_command(struct amr_softc *sc, struct amr_command **acp)
1290{
1291    struct amr_command	*ac;
1292    struct amrd_softc	*amrd;
1293    struct bio		*bio;
1294    int			error;
1295    int			blkcount;
1296    int			driveno;
1297    int			cmd;
1298
1299    ac = NULL;
1300    error = 0;
1301
1302    /* get a command */
1303    if ((ac = amr_alloccmd(sc)) == NULL)
1304	return (ENOMEM);
1305
1306    /* get a bio to work on */
1307    if ((bio = amr_dequeue_bio(sc)) == NULL) {
1308	amr_releasecmd(ac);
1309	return (0);
1310    }
1311
1312    /* connect the bio to the command */
1313    ac->ac_complete = amr_completeio;
1314    ac->ac_bio = bio;
1315    ac->ac_data = bio->bio_data;
1316    ac->ac_length = bio->bio_bcount;
1317    cmd = 0;
1318    switch (bio->bio_cmd) {
1319    case BIO_READ:
1320	ac->ac_flags |= AMR_CMD_DATAIN;
1321	if (AMR_IS_SG64(sc)) {
1322	    cmd = AMR_CMD_LREAD64;
1323	    ac->ac_flags |= AMR_CMD_SG64;
1324	} else
1325	    cmd = AMR_CMD_LREAD;
1326	break;
1327    case BIO_WRITE:
1328	ac->ac_flags |= AMR_CMD_DATAOUT;
1329	if (AMR_IS_SG64(sc)) {
1330	    cmd = AMR_CMD_LWRITE64;
1331	    ac->ac_flags |= AMR_CMD_SG64;
1332	} else
1333	    cmd = AMR_CMD_LWRITE;
1334	break;
1335    case BIO_FLUSH:
1336	ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
1337	cmd = AMR_CMD_FLUSH;
1338	break;
1339    }
1340    amrd = (struct amrd_softc *)bio->bio_disk->d_drv1;
1341    driveno = amrd->amrd_drive - sc->amr_drive;
1342    blkcount = (bio->bio_bcount + AMR_BLKSIZE - 1) / AMR_BLKSIZE;
1343
1344    ac->ac_mailbox.mb_command = cmd;
1345    if (bio->bio_cmd & (BIO_READ|BIO_WRITE)) {
1346	ac->ac_mailbox.mb_blkcount = blkcount;
1347	ac->ac_mailbox.mb_lba = bio->bio_pblkno;
1348	if ((bio->bio_pblkno + blkcount) > sc->amr_drive[driveno].al_size) {
1349	    device_printf(sc->amr_dev,
1350			  "I/O beyond end of unit (%lld,%d > %lu)\n",
1351			  (long long)bio->bio_pblkno, blkcount,
1352			  (u_long)sc->amr_drive[driveno].al_size);
1353	}
1354    }
1355    ac->ac_mailbox.mb_drive = driveno;
1356    if (sc->amr_state & AMR_STATE_REMAP_LD)
1357	ac->ac_mailbox.mb_drive |= 0x80;
1358
1359    /* we fill in the s/g related data when the command is mapped */
1360
1361
1362    *acp = ac;
1363    return(error);
1364}
1365
1366/********************************************************************************
1367 * Take a command, submit it to the controller and sleep until it completes
1368 * or fails.  Interrupts must be enabled, returns nonzero on error.
1369 */
1370static int
1371amr_wait_command(struct amr_command *ac)
1372{
1373    int			error = 0;
1374    struct amr_softc	*sc = ac->ac_sc;
1375
1376    debug_called(1);
1377
1378    ac->ac_complete = NULL;
1379    ac->ac_flags |= AMR_CMD_SLEEP;
1380    if ((error = amr_start(ac)) != 0) {
1381	return(error);
1382    }
1383
1384    while ((ac->ac_flags & AMR_CMD_BUSY) && (error != EWOULDBLOCK)) {
1385	error = msleep(ac,&sc->amr_list_lock, PRIBIO, "amrwcmd", 0);
1386    }
1387
1388    return(error);
1389}
1390
1391/********************************************************************************
1392 * Take a command, submit it to the controller and busy-wait for it to return.
1393 * Returns nonzero on error.  Can be safely called with interrupts enabled.
1394 */
1395static int
1396amr_std_poll_command(struct amr_command *ac)
1397{
1398    struct amr_softc	*sc = ac->ac_sc;
1399    int			error, count;
1400
1401    debug_called(2);
1402
1403    ac->ac_complete = NULL;
1404    if ((error = amr_start(ac)) != 0)
1405	return(error);
1406
1407    count = 0;
1408    do {
1409	/*
1410	 * Poll for completion, although the interrupt handler may beat us to it.
1411	 * Note that the timeout here is somewhat arbitrary.
1412	 */
1413	amr_done(sc);
1414	DELAY(1000);
1415    } while ((ac->ac_flags & AMR_CMD_BUSY) && (count++ < 1000));
1416    if (!(ac->ac_flags & AMR_CMD_BUSY)) {
1417	error = 0;
1418    } else {
1419	/* XXX the slot is now marked permanently busy */
1420	error = EIO;
1421	device_printf(sc->amr_dev, "polled command timeout\n");
1422    }
1423    return(error);
1424}
1425
1426static void
1427amr_setup_polled_dmamap(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
1428{
1429    struct amr_command *ac = arg;
1430    struct amr_softc *sc = ac->ac_sc;
1431    int mb_channel;
1432
1433    if (err) {
1434	device_printf(sc->amr_dev, "error %d in %s", err, __FUNCTION__);
1435	ac->ac_status = AMR_STATUS_ABORTED;
1436	return;
1437    }
1438
1439    amr_setup_sg(arg, segs, nsegs, err);
1440
1441    /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
1442    mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel;
1443    if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG &&
1444        ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) ||
1445        (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)))
1446	((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments;
1447
1448    ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments;
1449    ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr;
1450    if (AC_IS_SG64(ac)) {
1451	ac->ac_sg64_hi = 0;
1452	ac->ac_sg64_lo = ac->ac_sgbusaddr;
1453    }
1454
1455    sc->amr_poll_command1(sc, ac);
1456}
1457
1458/********************************************************************************
1459 * Take a command, submit it to the controller and busy-wait for it to return.
1460 * Returns nonzero on error.  Can be safely called with interrupts enabled.
1461 */
1462static int
1463amr_quartz_poll_command(struct amr_command *ac)
1464{
1465    struct amr_softc	*sc = ac->ac_sc;
1466    int			error;
1467
1468    debug_called(2);
1469
1470    error = 0;
1471
1472    if (AC_IS_SG64(ac)) {
1473	ac->ac_tag = sc->amr_buffer64_dmat;
1474	ac->ac_datamap = ac->ac_dma64map;
1475    } else {
1476	ac->ac_tag = sc->amr_buffer_dmat;
1477	ac->ac_datamap = ac->ac_dmamap;
1478    }
1479
1480    /* now we have a slot, we can map the command (unmapped in amr_complete) */
1481    if (ac->ac_data != 0) {
1482	if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data,
1483	    ac->ac_length, amr_setup_polled_dmamap, ac, BUS_DMA_NOWAIT) != 0) {
1484	    error = 1;
1485	}
1486    } else {
1487	error = amr_quartz_poll_command1(sc, ac);
1488    }
1489
1490    return (error);
1491}
1492
1493static int
1494amr_quartz_poll_command1(struct amr_softc *sc, struct amr_command *ac)
1495{
1496    int count, error;
1497
1498    mtx_lock(&sc->amr_hw_lock);
1499    if ((sc->amr_state & AMR_STATE_INTEN) == 0) {
1500	count=0;
1501	while (sc->amr_busyslots) {
1502	    msleep(sc, &sc->amr_hw_lock, PRIBIO | PCATCH, "amrpoll", hz);
1503	    if(count++>10) {
1504		break;
1505	    }
1506	}
1507
1508	if(sc->amr_busyslots) {
1509	    device_printf(sc->amr_dev, "adapter is busy\n");
1510	    mtx_unlock(&sc->amr_hw_lock);
1511	    if (ac->ac_data != NULL) {
1512		bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
1513	    }
1514    	    ac->ac_status=0;
1515	    return(1);
1516	}
1517    }
1518
1519    bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, AMR_MBOX_CMDSIZE);
1520
1521    /* clear the poll/ack fields in the mailbox */
1522    sc->amr_mailbox->mb_ident = 0xFE;
1523    sc->amr_mailbox->mb_nstatus = 0xFF;
1524    sc->amr_mailbox->mb_status = 0xFF;
1525    sc->amr_mailbox->mb_poll = 0;
1526    sc->amr_mailbox->mb_ack = 0;
1527    sc->amr_mailbox->mb_busy = 1;
1528
1529    AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
1530
1531    while(sc->amr_mailbox->mb_nstatus == 0xFF)
1532	DELAY(1);
1533    while(sc->amr_mailbox->mb_status == 0xFF)
1534	DELAY(1);
1535    ac->ac_status=sc->amr_mailbox->mb_status;
1536    error = (ac->ac_status !=AMR_STATUS_SUCCESS) ? 1:0;
1537    while(sc->amr_mailbox->mb_poll != 0x77)
1538	DELAY(1);
1539    sc->amr_mailbox->mb_poll = 0;
1540    sc->amr_mailbox->mb_ack = 0x77;
1541
1542    /* acknowledge that we have the commands */
1543    AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_ACK);
1544    while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
1545	DELAY(1);
1546    mtx_unlock(&sc->amr_hw_lock);
1547
1548    /* unmap the command's data buffer */
1549    if (ac->ac_flags & AMR_CMD_DATAIN) {
1550	bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTREAD);
1551    }
1552    if (ac->ac_flags & AMR_CMD_DATAOUT) {
1553	bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, BUS_DMASYNC_POSTWRITE);
1554    }
1555    bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
1556
1557    return(error);
1558}
1559
1560static __inline int
1561amr_freeslot(struct amr_command *ac)
1562{
1563    struct amr_softc *sc = ac->ac_sc;
1564    int			slot;
1565
1566    debug_called(3);
1567
1568    slot = ac->ac_slot;
1569    if (sc->amr_busycmd[slot] == NULL)
1570	panic("amr: slot %d not busy?\n", slot);
1571
1572    sc->amr_busycmd[slot] = NULL;
1573    atomic_subtract_int(&sc->amr_busyslots, 1);
1574
1575    return (0);
1576}
1577
1578/********************************************************************************
1579 * Map/unmap (ac)'s data in the controller's addressable space as required.
1580 *
1581 * These functions may be safely called multiple times on a given command.
1582 */
1583static void
1584amr_setup_sg(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
1585{
1586    struct amr_command	*ac = (struct amr_command *)arg;
1587    struct amr_sgentry	*sg;
1588    struct amr_sg64entry *sg64;
1589    int flags, i;
1590
1591    debug_called(3);
1592
1593    /* get base address of s/g table */
1594    sg = ac->ac_sg.sg32;
1595    sg64 = ac->ac_sg.sg64;
1596
1597    if (AC_IS_SG64(ac)) {
1598	ac->ac_nsegments = nsegments;
1599	ac->ac_mb_physaddr = 0xffffffff;
1600	for (i = 0; i < nsegments; i++, sg64++) {
1601	    sg64->sg_addr = segs[i].ds_addr;
1602	    sg64->sg_count = segs[i].ds_len;
1603	}
1604    } else {
1605	/* decide whether we need to populate the s/g table */
1606	if (nsegments < 2) {
1607	    ac->ac_nsegments = 0;
1608	    ac->ac_mb_physaddr = segs[0].ds_addr;
1609	} else {
1610            ac->ac_nsegments = nsegments;
1611	    ac->ac_mb_physaddr = ac->ac_sgbusaddr;
1612	    for (i = 0; i < nsegments; i++, sg++) {
1613		sg->sg_addr = segs[i].ds_addr;
1614		sg->sg_count = segs[i].ds_len;
1615	    }
1616	}
1617    }
1618
1619    flags = 0;
1620    if (ac->ac_flags & AMR_CMD_DATAIN)
1621	flags |= BUS_DMASYNC_PREREAD;
1622    if (ac->ac_flags & AMR_CMD_DATAOUT)
1623	flags |= BUS_DMASYNC_PREWRITE;
1624    bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flags);
1625    ac->ac_flags |= AMR_CMD_MAPPED;
1626}
1627
1628static void
1629amr_setup_data(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
1630{
1631    struct amr_command *ac = arg;
1632    struct amr_softc *sc = ac->ac_sc;
1633    int mb_channel;
1634
1635    if (err) {
1636	device_printf(sc->amr_dev, "error %d in %s", err, __FUNCTION__);
1637	amr_abort_load(ac);
1638	return;
1639    }
1640
1641    amr_setup_sg(arg, segs, nsegs, err);
1642
1643    /* for AMR_CMD_CONFIG Read/Write the s/g count goes elsewhere */
1644    mb_channel = ((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_channel;
1645    if (ac->ac_mailbox.mb_command == AMR_CMD_CONFIG &&
1646        ((mb_channel == AMR_CONFIG_READ_NVRAM_CONFIG) ||
1647        (mb_channel == AMR_CONFIG_WRITE_NVRAM_CONFIG)))
1648	((struct amr_mailbox_ioctl *)&ac->ac_mailbox)->mb_param = ac->ac_nsegments;
1649
1650    ac->ac_mailbox.mb_nsgelem = ac->ac_nsegments;
1651    ac->ac_mailbox.mb_physaddr = ac->ac_mb_physaddr;
1652    if (AC_IS_SG64(ac)) {
1653	ac->ac_sg64_hi = 0;
1654	ac->ac_sg64_lo = ac->ac_sgbusaddr;
1655    }
1656
1657    if (sc->amr_submit_command(ac) == EBUSY) {
1658	amr_freeslot(ac);
1659	amr_requeue_ready(ac);
1660    }
1661}
1662
1663static void
1664amr_setup_ccb(void *arg, bus_dma_segment_t *segs, int nsegs, int err)
1665{
1666    struct amr_command *ac = arg;
1667    struct amr_softc *sc = ac->ac_sc;
1668    struct amr_passthrough *ap = &ac->ac_ccb->ccb_pthru;
1669    struct amr_ext_passthrough *aep = &ac->ac_ccb->ccb_epthru;
1670
1671    if (err) {
1672	device_printf(sc->amr_dev, "error %d in %s", err, __FUNCTION__);
1673	amr_abort_load(ac);
1674	return;
1675    }
1676
1677    /* Set up the mailbox portion of the command to point at the ccb */
1678    ac->ac_mailbox.mb_nsgelem = 0;
1679    ac->ac_mailbox.mb_physaddr = ac->ac_ccb_busaddr;
1680
1681    amr_setup_sg(arg, segs, nsegs, err);
1682
1683    switch (ac->ac_mailbox.mb_command) {
1684    case AMR_CMD_EXTPASS:
1685	aep->ap_no_sg_elements = ac->ac_nsegments;
1686	aep->ap_data_transfer_address = ac->ac_mb_physaddr;
1687        break;
1688    case AMR_CMD_PASS:
1689	ap->ap_no_sg_elements = ac->ac_nsegments;
1690	ap->ap_data_transfer_address = ac->ac_mb_physaddr;
1691	break;
1692    default:
1693	panic("Unknown ccb command");
1694    }
1695
1696    if (sc->amr_submit_command(ac) == EBUSY) {
1697	amr_freeslot(ac);
1698	amr_requeue_ready(ac);
1699    }
1700}
1701
1702static int
1703amr_mapcmd(struct amr_command *ac)
1704{
1705    bus_dmamap_callback_t *cb;
1706    struct amr_softc	*sc = ac->ac_sc;
1707
1708    debug_called(3);
1709
1710    if (AC_IS_SG64(ac)) {
1711	ac->ac_tag = sc->amr_buffer64_dmat;
1712	ac->ac_datamap = ac->ac_dma64map;
1713    } else {
1714	ac->ac_tag = sc->amr_buffer_dmat;
1715	ac->ac_datamap = ac->ac_dmamap;
1716    }
1717
1718    if (ac->ac_flags & AMR_CMD_CCB)
1719	cb = amr_setup_ccb;
1720    else
1721	cb = amr_setup_data;
1722
1723    /* if the command involves data at all, and hasn't been mapped */
1724    if ((ac->ac_flags & AMR_CMD_MAPPED) == 0 && (ac->ac_data != NULL)) {
1725	/* map the data buffers into bus space and build the s/g list */
1726	if (bus_dmamap_load(ac->ac_tag, ac->ac_datamap, ac->ac_data,
1727	     ac->ac_length, cb, ac, 0) == EINPROGRESS) {
1728	    sc->amr_state |= AMR_STATE_QUEUE_FRZN;
1729	}
1730   } else {
1731    	if (sc->amr_submit_command(ac) == EBUSY) {
1732	    amr_freeslot(ac);
1733	    amr_requeue_ready(ac);
1734	}
1735   }
1736
1737    return (0);
1738}
1739
1740static void
1741amr_unmapcmd(struct amr_command *ac)
1742{
1743    int			flag;
1744
1745    debug_called(3);
1746
1747    /* if the command involved data at all and was mapped */
1748    if (ac->ac_flags & AMR_CMD_MAPPED) {
1749
1750	if (ac->ac_data != NULL) {
1751
1752	    flag = 0;
1753	    if (ac->ac_flags & AMR_CMD_DATAIN)
1754		flag |= BUS_DMASYNC_POSTREAD;
1755	    if (ac->ac_flags & AMR_CMD_DATAOUT)
1756		flag |= BUS_DMASYNC_POSTWRITE;
1757
1758	    bus_dmamap_sync(ac->ac_tag, ac->ac_datamap, flag);
1759	    bus_dmamap_unload(ac->ac_tag, ac->ac_datamap);
1760	}
1761
1762	ac->ac_flags &= ~AMR_CMD_MAPPED;
1763    }
1764}
1765
1766static void
1767amr_abort_load(struct amr_command *ac)
1768{
1769    ac_qhead_t head;
1770    struct amr_softc *sc = ac->ac_sc;
1771
1772    mtx_assert(&sc->amr_list_lock, MA_OWNED);
1773
1774    ac->ac_status = AMR_STATUS_ABORTED;
1775    amr_init_qhead(&head);
1776    amr_enqueue_completed(ac, &head);
1777
1778    mtx_unlock(&sc->amr_list_lock);
1779    amr_complete(sc, &head);
1780    mtx_lock(&sc->amr_list_lock);
1781}
1782
1783/********************************************************************************
1784 * Take a command and give it to the controller, returns 0 if successful, or
1785 * EBUSY if the command should be retried later.
1786 */
1787static int
1788amr_start(struct amr_command *ac)
1789{
1790    struct amr_softc *sc;
1791    int error = 0;
1792    int slot;
1793
1794    debug_called(3);
1795
1796    /* mark command as busy so that polling consumer can tell */
1797    sc = ac->ac_sc;
1798    ac->ac_flags |= AMR_CMD_BUSY;
1799
1800    /* get a command slot (freed in amr_done) */
1801    slot = ac->ac_slot;
1802    if (sc->amr_busycmd[slot] != NULL)
1803	panic("amr: slot %d busy?\n", slot);
1804    sc->amr_busycmd[slot] = ac;
1805    atomic_add_int(&sc->amr_busyslots, 1);
1806
1807    /* Now we have a slot, we can map the command (unmapped in amr_complete). */
1808    if ((error = amr_mapcmd(ac)) == ENOMEM) {
1809	/*
1810	 * Memroy resources are short, so free the slot and let this be tried
1811	 * later.
1812	 */
1813	amr_freeslot(ac);
1814    }
1815
1816    return (error);
1817}
1818
1819/********************************************************************************
1820 * Extract one or more completed commands from the controller (sc)
1821 *
1822 * Returns nonzero if any commands on the work queue were marked as completed.
1823 */
1824
1825int
1826amr_done(struct amr_softc *sc)
1827{
1828    ac_qhead_t		head;
1829    struct amr_command	*ac;
1830    struct amr_mailbox	mbox;
1831    int			i, idx, result;
1832
1833    debug_called(3);
1834
1835    /* See if there's anything for us to do */
1836    result = 0;
1837    amr_init_qhead(&head);
1838
1839    /* loop collecting completed commands */
1840    for (;;) {
1841	/* poll for a completed command's identifier and status */
1842	if (sc->amr_get_work(sc, &mbox)) {
1843	    result = 1;
1844
1845	    /* iterate over completed commands in this result */
1846	    for (i = 0; i < mbox.mb_nstatus; i++) {
1847		/* get pointer to busy command */
1848		idx = mbox.mb_completed[i] - 1;
1849		ac = sc->amr_busycmd[idx];
1850
1851		/* really a busy command? */
1852		if (ac != NULL) {
1853
1854		    /* pull the command from the busy index */
1855		    amr_freeslot(ac);
1856
1857		    /* save status for later use */
1858		    ac->ac_status = mbox.mb_status;
1859		    amr_enqueue_completed(ac, &head);
1860		    debug(3, "completed command with status %x", mbox.mb_status);
1861		} else {
1862		    device_printf(sc->amr_dev, "bad slot %d completed\n", idx);
1863		}
1864	    }
1865	} else
1866	    break;	/* no work */
1867    }
1868
1869    /* handle completion and timeouts */
1870    amr_complete(sc, &head);
1871
1872    return(result);
1873}
1874
1875/********************************************************************************
1876 * Do completion processing on done commands on (sc)
1877 */
1878
1879static void
1880amr_complete(void *context, ac_qhead_t *head)
1881{
1882    struct amr_softc	*sc = (struct amr_softc *)context;
1883    struct amr_command	*ac;
1884
1885    debug_called(3);
1886
1887    /* pull completed commands off the queue */
1888    for (;;) {
1889	ac = amr_dequeue_completed(sc, head);
1890	if (ac == NULL)
1891	    break;
1892
1893	/* unmap the command's data buffer */
1894	amr_unmapcmd(ac);
1895
1896	/*
1897	 * Is there a completion handler?
1898	 */
1899	if (ac->ac_complete != NULL) {
1900	    /* unbusy the command */
1901	    ac->ac_flags &= ~AMR_CMD_BUSY;
1902	    ac->ac_complete(ac);
1903
1904	    /*
1905	     * Is someone sleeping on this one?
1906	     */
1907	} else {
1908	    mtx_lock(&sc->amr_list_lock);
1909	    ac->ac_flags &= ~AMR_CMD_BUSY;
1910	    if (ac->ac_flags & AMR_CMD_SLEEP) {
1911		/* unbusy the command */
1912		wakeup(ac);
1913	    }
1914	    mtx_unlock(&sc->amr_list_lock);
1915	}
1916
1917	if(!sc->amr_busyslots) {
1918	    wakeup(sc);
1919	}
1920    }
1921
1922    mtx_lock(&sc->amr_list_lock);
1923    sc->amr_state &= ~AMR_STATE_QUEUE_FRZN;
1924    amr_startio(sc);
1925    mtx_unlock(&sc->amr_list_lock);
1926}
1927
1928/********************************************************************************
1929 ********************************************************************************
1930                                                        Command Buffer Management
1931 ********************************************************************************
1932 ********************************************************************************/
1933
1934/********************************************************************************
1935 * Get a new command buffer.
1936 *
1937 * This may return NULL in low-memory cases.
1938 *
1939 * If possible, we recycle a command buffer that's been used before.
1940 */
1941struct amr_command *
1942amr_alloccmd(struct amr_softc *sc)
1943{
1944    struct amr_command	*ac;
1945
1946    debug_called(3);
1947
1948    ac = amr_dequeue_free(sc);
1949    if (ac == NULL) {
1950	sc->amr_state |= AMR_STATE_QUEUE_FRZN;
1951	return(NULL);
1952    }
1953
1954    /* clear out significant fields */
1955    ac->ac_status = 0;
1956    bzero(&ac->ac_mailbox, sizeof(struct amr_mailbox));
1957    ac->ac_flags = 0;
1958    ac->ac_bio = NULL;
1959    ac->ac_data = NULL;
1960    ac->ac_complete = NULL;
1961    ac->ac_retries = 0;
1962    ac->ac_tag = NULL;
1963    ac->ac_datamap = NULL;
1964    return(ac);
1965}
1966
1967/********************************************************************************
1968 * Release a command buffer for recycling.
1969 */
1970void
1971amr_releasecmd(struct amr_command *ac)
1972{
1973    debug_called(3);
1974
1975    amr_enqueue_free(ac);
1976}
1977
1978/********************************************************************************
1979 * Allocate a new command cluster and initialise it.
1980 */
1981static void
1982amr_alloccmd_cluster(struct amr_softc *sc)
1983{
1984    struct amr_command_cluster	*acc;
1985    struct amr_command		*ac;
1986    int				i, nextslot;
1987
1988    /*
1989     * If we haven't found the real limit yet, let us have a couple of
1990     * commands in order to be able to probe.
1991     */
1992    if (sc->amr_maxio == 0)
1993	sc->amr_maxio = 2;
1994
1995    if (sc->amr_nextslot > sc->amr_maxio)
1996	return;
1997    acc = malloc(AMR_CMD_CLUSTERSIZE, M_AMR, M_NOWAIT | M_ZERO);
1998    if (acc != NULL) {
1999	nextslot = sc->amr_nextslot;
2000	mtx_lock(&sc->amr_list_lock);
2001	TAILQ_INSERT_TAIL(&sc->amr_cmd_clusters, acc, acc_link);
2002	mtx_unlock(&sc->amr_list_lock);
2003	for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
2004	    ac = &acc->acc_command[i];
2005	    ac->ac_sc = sc;
2006	    ac->ac_slot = nextslot;
2007
2008	    /*
2009	     * The SG table for each slot is a fixed size and is assumed to
2010	     * to hold 64-bit s/g objects when the driver is configured to do
2011	     * 64-bit DMA.  32-bit DMA commands still use the same table, but
2012	     * cast down to 32-bit objects.
2013	     */
2014	    if (AMR_IS_SG64(sc)) {
2015		ac->ac_sgbusaddr = sc->amr_sgbusaddr +
2016		    (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sg64entry));
2017	        ac->ac_sg.sg64 = sc->amr_sg64table + (ac->ac_slot * AMR_NSEG);
2018	    } else {
2019		ac->ac_sgbusaddr = sc->amr_sgbusaddr +
2020		    (ac->ac_slot * AMR_NSEG * sizeof(struct amr_sgentry));
2021	        ac->ac_sg.sg32 = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
2022	    }
2023
2024	    ac->ac_ccb = sc->amr_ccb + ac->ac_slot;
2025	    ac->ac_ccb_busaddr = sc->amr_ccb_busaddr +
2026		(ac->ac_slot * sizeof(union amr_ccb));
2027
2028	    if (bus_dmamap_create(sc->amr_buffer_dmat, 0, &ac->ac_dmamap))
2029		break;
2030	    if (AMR_IS_SG64(sc) &&
2031		(bus_dmamap_create(sc->amr_buffer64_dmat, 0,&ac->ac_dma64map)))
2032		break;
2033	    amr_releasecmd(ac);
2034	    if (++nextslot > sc->amr_maxio)
2035		break;
2036	}
2037	sc->amr_nextslot = nextslot;
2038    }
2039}
2040
2041/********************************************************************************
2042 * Free a command cluster
2043 */
2044static void
2045amr_freecmd_cluster(struct amr_command_cluster *acc)
2046{
2047    struct amr_softc	*sc = acc->acc_command[0].ac_sc;
2048    int			i;
2049
2050    for (i = 0; i < AMR_CMD_CLUSTERCOUNT; i++) {
2051	if (acc->acc_command[i].ac_sc == NULL)
2052	    break;
2053	bus_dmamap_destroy(sc->amr_buffer_dmat, acc->acc_command[i].ac_dmamap);
2054	if (AMR_IS_SG64(sc))
2055		bus_dmamap_destroy(sc->amr_buffer64_dmat, acc->acc_command[i].ac_dma64map);
2056    }
2057    free(acc, M_AMR);
2058}
2059
2060/********************************************************************************
2061 ********************************************************************************
2062                                                         Interface-specific Shims
2063 ********************************************************************************
2064 ********************************************************************************/
2065
2066/********************************************************************************
2067 * Tell the controller that the mailbox contains a valid command
2068 */
2069static int
2070amr_quartz_submit_command(struct amr_command *ac)
2071{
2072    struct amr_softc	*sc = ac->ac_sc;
2073    static struct timeval lastfail;
2074    static int		curfail;
2075    int			i = 0;
2076
2077    mtx_lock(&sc->amr_hw_lock);
2078    while (sc->amr_mailbox->mb_busy && (i++ < 10)) {
2079        DELAY(1);
2080	/* This is a no-op read that flushes pending mailbox updates */
2081	AMR_QGET_ODB(sc);
2082    }
2083    if (sc->amr_mailbox->mb_busy) {
2084	mtx_unlock(&sc->amr_hw_lock);
2085	if (ac->ac_retries++ > 1000) {
2086	    if (ppsratecheck(&lastfail, &curfail, 1))
2087		device_printf(sc->amr_dev, "Too many retries on command %p.  "
2088			      "Controller is likely dead\n", ac);
2089	    ac->ac_retries = 0;
2090	}
2091	return (EBUSY);
2092    }
2093
2094    /*
2095     * Save the slot number so that we can locate this command when complete.
2096     * Note that ident = 0 seems to be special, so we don't use it.
2097     */
2098    ac->ac_mailbox.mb_ident = ac->ac_slot + 1; /* will be coppied into mbox */
2099    bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, 14);
2100    sc->amr_mailbox->mb_busy = 1;
2101    sc->amr_mailbox->mb_poll = 0;
2102    sc->amr_mailbox->mb_ack  = 0;
2103    sc->amr_mailbox64->sg64_hi = ac->ac_sg64_hi;
2104    sc->amr_mailbox64->sg64_lo = ac->ac_sg64_lo;
2105
2106    AMR_QPUT_IDB(sc, sc->amr_mailboxphys | AMR_QIDB_SUBMIT);
2107    mtx_unlock(&sc->amr_hw_lock);
2108    return(0);
2109}
2110
2111static int
2112amr_std_submit_command(struct amr_command *ac)
2113{
2114    struct amr_softc	*sc = ac->ac_sc;
2115    static struct timeval lastfail;
2116    static int		curfail;
2117
2118    mtx_lock(&sc->amr_hw_lock);
2119    if (AMR_SGET_MBSTAT(sc) & AMR_SMBOX_BUSYFLAG) {
2120	mtx_unlock(&sc->amr_hw_lock);
2121	if (ac->ac_retries++ > 1000) {
2122	    if (ppsratecheck(&lastfail, &curfail, 1))
2123		device_printf(sc->amr_dev, "Too many retries on command %p.  "
2124			      "Controller is likely dead\n", ac);
2125	    ac->ac_retries = 0;
2126	}
2127	return (EBUSY);
2128    }
2129
2130    /*
2131     * Save the slot number so that we can locate this command when complete.
2132     * Note that ident = 0 seems to be special, so we don't use it.
2133     */
2134    ac->ac_mailbox.mb_ident = ac->ac_slot + 1; /* will be coppied into mbox */
2135    bcopy(&ac->ac_mailbox, (void *)(uintptr_t)(volatile void *)sc->amr_mailbox, 14);
2136    sc->amr_mailbox->mb_busy = 1;
2137    sc->amr_mailbox->mb_poll = 0;
2138    sc->amr_mailbox->mb_ack  = 0;
2139
2140    AMR_SPOST_COMMAND(sc);
2141    mtx_unlock(&sc->amr_hw_lock);
2142    return(0);
2143}
2144
2145/********************************************************************************
2146 * Claim any work that the controller has completed; acknowledge completion,
2147 * save details of the completion in (mbsave)
2148 */
2149static int
2150amr_quartz_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
2151{
2152    int		worked, i;
2153    u_int32_t	outd;
2154    u_int8_t	nstatus;
2155    u_int8_t	completed[46];
2156
2157    debug_called(3);
2158
2159    worked = 0;
2160
2161    /* work waiting for us? */
2162    if ((outd = AMR_QGET_ODB(sc)) == AMR_QODB_READY) {
2163
2164	/* acknowledge interrupt */
2165	AMR_QPUT_ODB(sc, AMR_QODB_READY);
2166
2167	while ((nstatus = sc->amr_mailbox->mb_nstatus) == 0xff)
2168	    DELAY(1);
2169	sc->amr_mailbox->mb_nstatus = 0xff;
2170
2171	/* wait until fw wrote out all completions */
2172	for (i = 0; i < nstatus; i++) {
2173	    while ((completed[i] = sc->amr_mailbox->mb_completed[i]) == 0xff)
2174		DELAY(1);
2175	    sc->amr_mailbox->mb_completed[i] = 0xff;
2176	}
2177
2178	/* Save information for later processing */
2179	mbsave->mb_nstatus = nstatus;
2180	mbsave->mb_status = sc->amr_mailbox->mb_status;
2181	sc->amr_mailbox->mb_status = 0xff;
2182
2183	for (i = 0; i < nstatus; i++)
2184	    mbsave->mb_completed[i] = completed[i];
2185
2186	/* acknowledge that we have the commands */
2187	AMR_QPUT_IDB(sc, AMR_QIDB_ACK);
2188
2189#if 0
2190#ifndef AMR_QUARTZ_GOFASTER
2191	/*
2192	 * This waits for the controller to notice that we've taken the
2193	 * command from it.  It's very inefficient, and we shouldn't do it,
2194	 * but if we remove this code, we stop completing commands under
2195	 * load.
2196	 *
2197	 * Peter J says we shouldn't do this.  The documentation says we
2198	 * should.  Who is right?
2199	 */
2200	while(AMR_QGET_IDB(sc) & AMR_QIDB_ACK)
2201	    ;				/* XXX aiee! what if it dies? */
2202#endif
2203#endif
2204
2205	worked = 1;			/* got some work */
2206    }
2207
2208    return(worked);
2209}
2210
2211static int
2212amr_std_get_work(struct amr_softc *sc, struct amr_mailbox *mbsave)
2213{
2214    int		worked;
2215    u_int8_t	istat;
2216
2217    debug_called(3);
2218
2219    worked = 0;
2220
2221    /* check for valid interrupt status */
2222    istat = AMR_SGET_ISTAT(sc);
2223    if ((istat & AMR_SINTR_VALID) != 0) {
2224	AMR_SPUT_ISTAT(sc, istat);	/* ack interrupt status */
2225
2226	/* save mailbox, which contains a list of completed commands */
2227	bcopy((void *)(uintptr_t)(volatile void *)sc->amr_mailbox, mbsave, sizeof(*mbsave));
2228
2229	AMR_SACK_INTERRUPT(sc);		/* acknowledge we have the mailbox */
2230	worked = 1;
2231    }
2232
2233    return(worked);
2234}
2235
2236/********************************************************************************
2237 * Notify the controller of the mailbox location.
2238 */
2239static void
2240amr_std_attach_mailbox(struct amr_softc *sc)
2241{
2242
2243    /* program the mailbox physical address */
2244    AMR_SBYTE_SET(sc, AMR_SMBOX_0, sc->amr_mailboxphys         & 0xff);
2245    AMR_SBYTE_SET(sc, AMR_SMBOX_1, (sc->amr_mailboxphys >>  8) & 0xff);
2246    AMR_SBYTE_SET(sc, AMR_SMBOX_2, (sc->amr_mailboxphys >> 16) & 0xff);
2247    AMR_SBYTE_SET(sc, AMR_SMBOX_3, (sc->amr_mailboxphys >> 24) & 0xff);
2248    AMR_SBYTE_SET(sc, AMR_SMBOX_ENABLE, AMR_SMBOX_ADDR);
2249
2250    /* clear any outstanding interrupt and enable interrupts proper */
2251    AMR_SACK_INTERRUPT(sc);
2252    AMR_SENABLE_INTR(sc);
2253}
2254
2255#ifdef AMR_BOARD_INIT
2256/********************************************************************************
2257 * Initialise the controller
2258 */
2259static int
2260amr_quartz_init(struct amr_softc *sc)
2261{
2262    int		status, ostatus;
2263
2264    device_printf(sc->amr_dev, "initial init status %x\n", AMR_QGET_INITSTATUS(sc));
2265
2266    AMR_QRESET(sc);
2267
2268    ostatus = 0xff;
2269    while ((status = AMR_QGET_INITSTATUS(sc)) != AMR_QINIT_DONE) {
2270	if (status != ostatus) {
2271	    device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_qinit, status));
2272	    ostatus = status;
2273	}
2274	switch (status) {
2275	case AMR_QINIT_NOMEM:
2276	    return(ENOMEM);
2277
2278	case AMR_QINIT_SCAN:
2279	    /* XXX we could print channel/target here */
2280	    break;
2281	}
2282    }
2283    return(0);
2284}
2285
2286static int
2287amr_std_init(struct amr_softc *sc)
2288{
2289    int		status, ostatus;
2290
2291    device_printf(sc->amr_dev, "initial init status %x\n", AMR_SGET_INITSTATUS(sc));
2292
2293    AMR_SRESET(sc);
2294
2295    ostatus = 0xff;
2296    while ((status = AMR_SGET_INITSTATUS(sc)) != AMR_SINIT_DONE) {
2297	if (status != ostatus) {
2298	    device_printf(sc->amr_dev, "(%x) %s\n", status, amr_describe_code(amr_table_sinit, status));
2299	    ostatus = status;
2300	}
2301	switch (status) {
2302	case AMR_SINIT_NOMEM:
2303	    return(ENOMEM);
2304
2305	case AMR_SINIT_INPROG:
2306	    /* XXX we could print channel/target here? */
2307	    break;
2308	}
2309    }
2310    return(0);
2311}
2312#endif
2313
2314/********************************************************************************
2315 ********************************************************************************
2316                                                                        Debugging
2317 ********************************************************************************
2318 ********************************************************************************/
2319
2320/********************************************************************************
2321 * Identify the controller and print some information about it.
2322 */
2323static void
2324amr_describe_controller(struct amr_softc *sc)
2325{
2326    struct amr_prodinfo	*ap;
2327    struct amr_enquiry	*ae;
2328    char		*prod;
2329    int			status;
2330
2331    /*
2332     * Try to get 40LD product info, which tells us what the card is labelled as.
2333     */
2334    if ((ap = amr_enquiry(sc, 2048, AMR_CMD_CONFIG, AMR_CONFIG_PRODUCT_INFO, 0, &status)) != NULL) {
2335	device_printf(sc->amr_dev, "<LSILogic %.80s> Firmware %.16s, BIOS %.16s, %dMB RAM\n",
2336		      ap->ap_product, ap->ap_firmware, ap->ap_bios,
2337		      ap->ap_memsize);
2338
2339	free(ap, M_AMR);
2340	return;
2341    }
2342
2343    /*
2344     * Try 8LD extended ENQUIRY to get controller signature, and use lookup table.
2345     */
2346    if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_EXT_ENQUIRY2, 0, 0, &status)) != NULL) {
2347	prod = amr_describe_code(amr_table_adaptertype, ae->ae_signature);
2348
2349    } else if ((ae = (struct amr_enquiry *)amr_enquiry(sc, 2048, AMR_CMD_ENQUIRY, 0, 0, &status)) != NULL) {
2350
2351	/*
2352	 * Try to work it out based on the PCI signatures.
2353	 */
2354	switch (pci_get_device(sc->amr_dev)) {
2355	case 0x9010:
2356	    prod = "Series 428";
2357	    break;
2358	case 0x9060:
2359	    prod = "Series 434";
2360	    break;
2361	default:
2362	    prod = "unknown controller";
2363	    break;
2364	}
2365    } else {
2366	device_printf(sc->amr_dev, "<unsupported controller>\n");
2367	return;
2368    }
2369
2370    /*
2371     * HP NetRaid controllers have a special encoding of the firmware and
2372     * BIOS versions. The AMI version seems to have it as strings whereas
2373     * the HP version does it with a leading uppercase character and two
2374     * binary numbers.
2375     */
2376
2377    if(ae->ae_adapter.aa_firmware[2] >= 'A' &&
2378       ae->ae_adapter.aa_firmware[2] <= 'Z' &&
2379       ae->ae_adapter.aa_firmware[1] <  ' ' &&
2380       ae->ae_adapter.aa_firmware[0] <  ' ' &&
2381       ae->ae_adapter.aa_bios[2] >= 'A'     &&
2382       ae->ae_adapter.aa_bios[2] <= 'Z'     &&
2383       ae->ae_adapter.aa_bios[1] <  ' '     &&
2384       ae->ae_adapter.aa_bios[0] <  ' ') {
2385
2386	/* this looks like we have an HP NetRaid version of the MegaRaid */
2387
2388    	if(ae->ae_signature == AMR_SIG_438) {
2389    		/* the AMI 438 is a NetRaid 3si in HP-land */
2390    		prod = "HP NetRaid 3si";
2391    	}
2392
2393	device_printf(sc->amr_dev, "<%s> Firmware %c.%02d.%02d, BIOS %c.%02d.%02d, %dMB RAM\n",
2394		      prod, ae->ae_adapter.aa_firmware[2],
2395		      ae->ae_adapter.aa_firmware[1],
2396		      ae->ae_adapter.aa_firmware[0],
2397		      ae->ae_adapter.aa_bios[2],
2398		      ae->ae_adapter.aa_bios[1],
2399		      ae->ae_adapter.aa_bios[0],
2400		      ae->ae_adapter.aa_memorysize);
2401    } else {
2402	device_printf(sc->amr_dev, "<%s> Firmware %.4s, BIOS %.4s, %dMB RAM\n",
2403		      prod, ae->ae_adapter.aa_firmware, ae->ae_adapter.aa_bios,
2404		      ae->ae_adapter.aa_memorysize);
2405    }
2406    free(ae, M_AMR);
2407}
2408
2409int
2410amr_dump_blocks(struct amr_softc *sc, int unit, u_int32_t lba, void *data, int blks)
2411{
2412    struct amr_command	*ac;
2413    int			error = EIO;
2414
2415    debug_called(1);
2416
2417    sc->amr_state |= AMR_STATE_INTEN;
2418
2419    /* get ourselves a command buffer */
2420    if ((ac = amr_alloccmd(sc)) == NULL)
2421	goto out;
2422    /* set command flags */
2423    ac->ac_flags |= AMR_CMD_PRIORITY | AMR_CMD_DATAOUT;
2424
2425    /* point the command at our data */
2426    ac->ac_data = data;
2427    ac->ac_length = blks * AMR_BLKSIZE;
2428
2429    /* build the command proper */
2430    ac->ac_mailbox.mb_command 	= AMR_CMD_LWRITE;
2431    ac->ac_mailbox.mb_blkcount	= blks;
2432    ac->ac_mailbox.mb_lba	= lba;
2433    ac->ac_mailbox.mb_drive	= unit;
2434
2435    /* can't assume that interrupts are going to work here, so play it safe */
2436    if (sc->amr_poll_command(ac))
2437	goto out;
2438    error = ac->ac_status;
2439
2440 out:
2441    if (ac != NULL)
2442	amr_releasecmd(ac);
2443
2444    sc->amr_state &= ~AMR_STATE_INTEN;
2445    return (error);
2446}
2447
2448
2449
2450#ifdef AMR_DEBUG
2451/********************************************************************************
2452 * Print the command (ac) in human-readable format
2453 */
2454#if 0
2455static void
2456amr_printcommand(struct amr_command *ac)
2457{
2458    struct amr_softc	*sc = ac->ac_sc;
2459    struct amr_sgentry	*sg;
2460    int			i;
2461
2462    device_printf(sc->amr_dev, "cmd %x  ident %d  drive %d\n",
2463		  ac->ac_mailbox.mb_command, ac->ac_mailbox.mb_ident, ac->ac_mailbox.mb_drive);
2464    device_printf(sc->amr_dev, "blkcount %d  lba %d\n",
2465		  ac->ac_mailbox.mb_blkcount, ac->ac_mailbox.mb_lba);
2466    device_printf(sc->amr_dev, "virtaddr %p  length %lu\n", ac->ac_data, (unsigned long)ac->ac_length);
2467    device_printf(sc->amr_dev, "sg physaddr %08x  nsg %d\n",
2468		  ac->ac_mailbox.mb_physaddr, ac->ac_mailbox.mb_nsgelem);
2469    device_printf(sc->amr_dev, "ccb %p  bio %p\n", ac->ac_ccb_data, ac->ac_bio);
2470
2471    /* get base address of s/g table */
2472    sg = sc->amr_sgtable + (ac->ac_slot * AMR_NSEG);
2473    for (i = 0; i < ac->ac_mailbox.mb_nsgelem; i++, sg++)
2474	device_printf(sc->amr_dev, "  %x/%d\n", sg->sg_addr, sg->sg_count);
2475}
2476#endif
2477#endif
2478