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