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