Merge branch 'apic_io'
[dragonfly.git] / sys / dev / raid / amr / amr.c
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