Merge from vendor branch TNFTP:
[dragonfly.git] / sys / dev / raid / mlx / mlx.c
1 /*-
2  * Copyright (c) 1999 Michael Smith
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *      $FreeBSD: src/sys/dev/mlx/mlx.c,v 1.14.2.5 2001/09/11 09:49:53 kris Exp $
27  *      $DragonFly: src/sys/dev/raid/mlx/mlx.c,v 1.24 2006/12/22 23:26:24 swildner Exp $
28  */
29
30 /*
31  * Driver for the Mylex DAC960 family of RAID controllers.
32  */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/malloc.h>
37 #include <sys/kernel.h>
38 #include <sys/bus.h>
39 #include <sys/conf.h>
40 #include <sys/devicestat.h>
41 #include <sys/disk.h>
42 #include <sys/stat.h>
43 #include <sys/rman.h>
44 #include <sys/thread2.h>
45
46 #include <machine/clock.h>
47
48 #include "mlx_compat.h"
49 #include "mlxio.h"
50 #include "mlxvar.h"
51 #include "mlxreg.h"
52
53 #define MLX_CDEV_MAJOR  130
54
55 static struct dev_ops mlx_ops = {
56         { "mlx", MLX_CDEV_MAJOR, 0 },
57         .d_open =       mlx_open,
58         .d_close =      mlx_close,
59         .d_ioctl =      mlx_ioctl,
60 };
61
62 devclass_t      mlx_devclass;
63
64 /*
65  * Per-interface accessor methods
66  */
67 static int                      mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
68 static int                      mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
69 static void                     mlx_v3_intaction(struct mlx_softc *sc, int action);
70 static int                      mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
71
72 static int                      mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
73 static int                      mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
74 static void                     mlx_v4_intaction(struct mlx_softc *sc, int action);
75 static int                      mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
76
77 static int                      mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc);
78 static int                      mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status);
79 static void                     mlx_v5_intaction(struct mlx_softc *sc, int action);
80 static int                      mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2);
81
82 /*
83  * Status monitoring
84  */
85 static void                     mlx_periodic(void *data);
86 static void                     mlx_periodic_enquiry(struct mlx_command *mc);
87 static void                     mlx_periodic_eventlog_poll(struct mlx_softc *sc);
88 static void                     mlx_periodic_eventlog_respond(struct mlx_command *mc);
89 static void                     mlx_periodic_rebuild(struct mlx_command *mc);
90
91 /*
92  * Channel Pause
93  */
94 static void                     mlx_pause_action(struct mlx_softc *sc);
95 static void                     mlx_pause_done(struct mlx_command *mc);
96
97 /*
98  * Command submission.
99  */
100 static void                     *mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, 
101                                              void (*complete)(struct mlx_command *mc));
102 static int                      mlx_flush(struct mlx_softc *sc);
103 static int                      mlx_check(struct mlx_softc *sc, int drive);
104 static int                      mlx_rebuild(struct mlx_softc *sc, int channel, int target);
105 static int                      mlx_wait_command(struct mlx_command *mc);
106 static int                      mlx_poll_command(struct mlx_command *mc);
107 static void                     mlx_startio(struct mlx_softc *sc);
108 static void                     mlx_completeio(struct mlx_command *mc);
109 static int                      mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu);
110
111 /*
112  * Command buffer allocation.
113  */
114 static struct mlx_command       *mlx_alloccmd(struct mlx_softc *sc);
115 static void                     mlx_releasecmd(struct mlx_command *mc);
116 static void                     mlx_freecmd(struct mlx_command *mc);
117
118 /*
119  * Command management.
120  */
121 static int                      mlx_getslot(struct mlx_command *mc);
122 static void                     mlx_mapcmd(struct mlx_command *mc);
123 static void                     mlx_unmapcmd(struct mlx_command *mc);
124 static int                      mlx_start(struct mlx_command *mc);
125 static int                      mlx_done(struct mlx_softc *sc);
126 static void                     mlx_complete(struct mlx_softc *sc);
127
128 /*
129  * Debugging.
130  */
131 static char                     *mlx_diagnose_command(struct mlx_command *mc);
132 static void                     mlx_describe_controller(struct mlx_softc *sc);
133 static int                      mlx_fw_message(struct mlx_softc *sc, int status, int param1, int param2);
134
135 /*
136  * Utility functions.
137  */
138 static struct mlx_sysdrive      *mlx_findunit(struct mlx_softc *sc, int unit);
139
140 /********************************************************************************
141  ********************************************************************************
142                                                                 Public Interfaces
143  ********************************************************************************
144  ********************************************************************************/
145
146 /********************************************************************************
147  * Free all of the resources associated with (sc)
148  *
149  * Should not be called if the controller is active.
150  */
151 void
152 mlx_free(struct mlx_softc *sc)
153 {
154     struct mlx_command  *mc;
155
156     debug_called(1);
157
158     /* cancel status timeout */
159     callout_stop(&sc->mlx_timeout);
160
161     /* throw away any command buffers */
162     while ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) {
163         TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
164         mlx_freecmd(mc);
165     }
166
167     /* destroy data-transfer DMA tag */
168     if (sc->mlx_buffer_dmat)
169         bus_dma_tag_destroy(sc->mlx_buffer_dmat);
170
171     /* free and destroy DMA memory and tag for s/g lists */
172     if (sc->mlx_sgtable)
173         bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap);
174     if (sc->mlx_sg_dmat)
175         bus_dma_tag_destroy(sc->mlx_sg_dmat);
176
177     /* disconnect the interrupt handler */
178     if (sc->mlx_intr)
179         bus_teardown_intr(sc->mlx_dev, sc->mlx_irq, sc->mlx_intr);
180     if (sc->mlx_irq != NULL)
181         bus_release_resource(sc->mlx_dev, SYS_RES_IRQ, 0, sc->mlx_irq);
182
183     /* destroy the parent DMA tag */
184     if (sc->mlx_parent_dmat)
185         bus_dma_tag_destroy(sc->mlx_parent_dmat);
186
187     /* release the register window mapping */
188     if (sc->mlx_mem != NULL)
189         bus_release_resource(sc->mlx_dev, sc->mlx_mem_type, sc->mlx_mem_rid, sc->mlx_mem);
190
191     /* free controller enquiry data */
192     if (sc->mlx_enq2 != NULL)
193         kfree(sc->mlx_enq2, M_DEVBUF);
194
195     dev_ops_remove(&mlx_ops, -1, device_get_unit(sc->mlx_dev));
196 }
197
198 /********************************************************************************
199  * Map the scatter/gather table into bus space
200  */
201 static void
202 mlx_dma_map_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
203 {
204     struct mlx_softc    *sc = (struct mlx_softc *)arg;
205
206     debug_called(1);
207
208     /* save base of s/g table's address in bus space */
209     sc->mlx_sgbusaddr = segs->ds_addr;
210 }
211
212 static int
213 mlx_sglist_map(struct mlx_softc *sc)
214 {
215     size_t      segsize;
216     int         error, ncmd;
217
218     debug_called(1);
219
220     /* destroy any existing mappings */
221     if (sc->mlx_sgtable)
222         bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap);
223     if (sc->mlx_sg_dmat)
224         bus_dma_tag_destroy(sc->mlx_sg_dmat);
225
226     /*
227      * Create a single tag describing a region large enough to hold all of
228      * the s/g lists we will need.  If we're called early on, we don't know how
229      * many commands we're going to be asked to support, so only allocate enough
230      * for a couple.
231      */
232     if (sc->mlx_enq2 == NULL) {
233         ncmd = 2;
234     } else {
235         ncmd = sc->mlx_enq2->me_max_commands;
236     }
237     segsize = sizeof(struct mlx_sgentry) * MLX_NSEG * ncmd;
238     error = bus_dma_tag_create(sc->mlx_parent_dmat,     /* parent */
239                                1, 0,                    /* alignment, boundary */
240                                BUS_SPACE_MAXADDR,       /* lowaddr */
241                                BUS_SPACE_MAXADDR,       /* highaddr */
242                                NULL, NULL,              /* filter, filterarg */
243                                segsize, 1,              /* maxsize, nsegments */
244                                BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
245                                0,                       /* flags */
246                                &sc->mlx_sg_dmat);
247     if (error != 0) {
248         device_printf(sc->mlx_dev, "can't allocate scatter/gather DMA tag\n");
249         return(ENOMEM);
250     }
251
252     /*
253      * Allocate enough s/g maps for all commands and permanently map them into
254      * controller-visible space.
255      *  
256      * XXX this assumes we can get enough space for all the s/g maps in one 
257      * contiguous slab.  We may need to switch to a more complex arrangement where
258      * we allocate in smaller chunks and keep a lookup table from slot to bus address.
259      */
260     error = bus_dmamem_alloc(sc->mlx_sg_dmat, (void **)&sc->mlx_sgtable, BUS_DMA_NOWAIT, &sc->mlx_sg_dmamap);
261     if (error) {
262         device_printf(sc->mlx_dev, "can't allocate s/g table\n");
263         return(ENOMEM);
264     }
265     bus_dmamap_load(sc->mlx_sg_dmat, sc->mlx_sg_dmamap, sc->mlx_sgtable, segsize, mlx_dma_map_sg, sc, 0);
266     return(0);
267 }
268
269 /********************************************************************************
270  * Initialise the controller and softc
271  */
272 int
273 mlx_attach(struct mlx_softc *sc)
274 {
275     struct mlx_enquiry_old      *meo;
276     int                         rid, error, fwminor, hscode, hserror, hsparam1, hsparam2, hsmsg;
277
278     debug_called(1);
279     callout_init(&sc->mlx_timeout);
280
281     /*
282      * Initialise per-controller queues.
283      */
284     TAILQ_INIT(&sc->mlx_work);
285     TAILQ_INIT(&sc->mlx_freecmds);
286     bioq_init(&sc->mlx_bioq);
287
288     /* 
289      * Select accessor methods based on controller interface type.
290      */
291     switch(sc->mlx_iftype) {
292     case MLX_IFTYPE_2:
293     case MLX_IFTYPE_3:
294         sc->mlx_tryqueue        = mlx_v3_tryqueue;
295         sc->mlx_findcomplete    = mlx_v3_findcomplete;
296         sc->mlx_intaction       = mlx_v3_intaction;
297         sc->mlx_fw_handshake    = mlx_v3_fw_handshake;
298         break;
299     case MLX_IFTYPE_4:
300         sc->mlx_tryqueue        = mlx_v4_tryqueue;
301         sc->mlx_findcomplete    = mlx_v4_findcomplete;
302         sc->mlx_intaction       = mlx_v4_intaction;
303         sc->mlx_fw_handshake    = mlx_v4_fw_handshake;
304         break;
305     case MLX_IFTYPE_5:
306         sc->mlx_tryqueue        = mlx_v5_tryqueue;
307         sc->mlx_findcomplete    = mlx_v5_findcomplete;
308         sc->mlx_intaction       = mlx_v5_intaction;
309         sc->mlx_fw_handshake    = mlx_v5_fw_handshake;
310         break;
311     default:
312         mlx_free(sc);
313         return(ENXIO);          /* should never happen */
314     }
315
316     /* disable interrupts before we start talking to the controller */
317     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
318
319     /* 
320      * Wait for the controller to come ready, handshake with the firmware if required.
321      * This is typically only necessary on platforms where the controller BIOS does not
322      * run.
323      */
324     hsmsg = 0;
325     DELAY(1000);
326     while ((hscode = sc->mlx_fw_handshake(sc, &hserror, &hsparam1, &hsparam2)) != 0) {
327         /* report first time around... */
328         if (hsmsg == 0) {
329             device_printf(sc->mlx_dev, "controller initialisation in progress...\n");
330             hsmsg = 1;
331         }
332         /* did we get a real message? */
333         if (hscode == 2) {
334             hscode = mlx_fw_message(sc, hserror, hsparam1, hsparam2);
335             /* fatal initialisation error? */
336             if (hscode != 0) {
337                 mlx_free(sc);
338                 return(ENXIO);
339             }
340         }
341     }
342     if (hsmsg == 1)
343         device_printf(sc->mlx_dev, "initialisation complete.\n");
344
345     /* 
346      * Allocate and connect our interrupt.
347      */
348     rid = 0;
349     sc->mlx_irq = bus_alloc_resource(sc->mlx_dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
350     if (sc->mlx_irq == NULL) {
351         device_printf(sc->mlx_dev, "can't allocate interrupt\n");
352         mlx_free(sc);
353         return(ENXIO);
354     }
355     error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, 
356                            0, mlx_intr, sc,
357                            &sc->mlx_intr, NULL);
358     if (error) {
359         device_printf(sc->mlx_dev, "can't set up interrupt\n");
360         mlx_free(sc);
361         return(ENXIO);
362     }
363
364     /*
365      * Create DMA tag for mapping buffers into controller-addressable space.
366      */
367     error = bus_dma_tag_create(sc->mlx_parent_dmat,             /* parent */
368                                1, 0,                            /* alignment, boundary */
369                                BUS_SPACE_MAXADDR,               /* lowaddr */
370                                BUS_SPACE_MAXADDR,               /* highaddr */
371                                NULL, NULL,                      /* filter, filterarg */
372                                MAXBSIZE, MLX_NSEG,              /* maxsize, nsegments */
373                                BUS_SPACE_MAXSIZE_32BIT,         /* maxsegsize */
374                                0,                               /* flags */
375                                &sc->mlx_buffer_dmat);
376     if (error != 0) {
377         device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n");
378         mlx_free(sc);
379         return(ENOMEM);
380     }
381
382     /*
383      * Create some initial scatter/gather mappings so we can run the probe commands.
384      */
385     error = mlx_sglist_map(sc);
386     if (error != 0) {
387         device_printf(sc->mlx_dev, "can't make initial s/g list mapping\n");
388         mlx_free(sc);
389         return(error);
390     }
391
392     /*
393      * We don't (yet) know where the event log is up to.
394      */
395     sc->mlx_currevent = -1;
396
397     /* 
398      * Obtain controller feature information
399      */
400     if ((sc->mlx_enq2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(struct mlx_enquiry2), NULL)) == NULL) {
401         device_printf(sc->mlx_dev, "ENQUIRY2 failed\n");
402         mlx_free(sc);
403         return(ENXIO);
404     }
405
406     /*
407      * Do quirk/feature related things.
408      */
409     fwminor = (sc->mlx_enq2->me_firmware_id >> 8) & 0xff;
410     switch(sc->mlx_iftype) {
411     case MLX_IFTYPE_2:
412         /* These controllers don't report the firmware version in the ENQUIRY2 response */
413         if ((meo = mlx_enquire(sc, MLX_CMD_ENQUIRY_OLD, sizeof(struct mlx_enquiry_old), NULL)) == NULL) {
414             device_printf(sc->mlx_dev, "ENQUIRY_OLD failed\n");
415             mlx_free(sc);
416             return(ENXIO);
417         }
418         sc->mlx_enq2->me_firmware_id = ('0' << 24) | (0 << 16) | (meo->me_fwminor << 8) | meo->me_fwmajor;
419         kfree(meo, M_DEVBUF);
420         
421         /* XXX require 2.42 or better (PCI) or 2.14 or better (EISA) */
422         if (meo->me_fwminor < 42) {
423             device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
424             device_printf(sc->mlx_dev, " *** WARNING *** Use revision 2.42 or later\n");
425         }
426         break;
427     case MLX_IFTYPE_3:
428         /* XXX certify 3.52? */
429         if (fwminor < 51) {
430             device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
431             device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n");
432         }
433         break;
434     case MLX_IFTYPE_4:
435         /* XXX certify firmware versions? */
436         if (fwminor < 6) {
437             device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
438             device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n");
439         }
440         break;
441     case MLX_IFTYPE_5:
442         if (fwminor < 7) {
443             device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
444             device_printf(sc->mlx_dev, " *** WARNING *** Use revision 5.07 or later\n");
445         }
446         break;
447     default:
448         mlx_free(sc);
449         return(ENXIO);          /* should never happen */
450     }
451
452     /*
453      * Create the final scatter/gather mappings now that we have characterised the controller.
454      */
455     error = mlx_sglist_map(sc);
456     if (error != 0) {
457         device_printf(sc->mlx_dev, "can't make final s/g list mapping\n");
458         mlx_free(sc);
459         return(error);
460     }
461
462     /*
463      * No user-requested background operation is in progress.
464      */
465     sc->mlx_background = 0;
466     sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
467
468     /*
469      * Create the control device.
470      */
471     dev_ops_add(&mlx_ops, -1, device_get_unit(sc->mlx_dev));
472     make_dev(&mlx_ops, device_get_unit(sc->mlx_dev), 
473             UID_ROOT, GID_OPERATOR, S_IRUSR | S_IWUSR,
474             "mlx%d", device_get_unit(sc->mlx_dev));
475
476     /*
477      * Start the timeout routine.
478      */
479     callout_reset(&sc->mlx_timeout, hz, mlx_periodic, sc);
480
481     /* print a little information about the controller */
482     mlx_describe_controller(sc);
483
484     return(0);
485 }
486
487 /********************************************************************************
488  * Locate disk resources and attach children to them.
489  */
490 void
491 mlx_startup(struct mlx_softc *sc)
492 {
493     struct mlx_enq_sys_drive    *mes;
494     struct mlx_sysdrive         *dr;
495     int                         i, error;
496
497     debug_called(1);
498     
499     /*
500      * Scan all the system drives and attach children for those that
501      * don't currently have them.
502      */
503     mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL);
504     if (mes == NULL) {
505         device_printf(sc->mlx_dev, "error fetching drive status\n");
506         return;
507     }
508     
509     /* iterate over drives returned */
510     for (i = 0, dr = &sc->mlx_sysdrive[0];
511          (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff);
512          i++, dr++) {
513         /* are we already attached to this drive? */
514         if (dr->ms_disk == 0) {
515             /* pick up drive information */
516             dr->ms_size = mes[i].sd_size;
517             dr->ms_raidlevel = mes[i].sd_raidlevel & 0xf;
518             dr->ms_state = mes[i].sd_state;
519
520             /* generate geometry information */
521             if (sc->mlx_geom == MLX_GEOM_128_32) {
522                 dr->ms_heads = 128;
523                 dr->ms_sectors = 32;
524                 dr->ms_cylinders = dr->ms_size / (128 * 32);
525             } else {        /* MLX_GEOM_255/63 */
526                 dr->ms_heads = 255;
527                 dr->ms_sectors = 63;
528                 dr->ms_cylinders = dr->ms_size / (255 * 63);
529             }
530             dr->ms_disk =  device_add_child(sc->mlx_dev, /*"mlxd"*/NULL, -1);
531             if (dr->ms_disk == 0)
532                 device_printf(sc->mlx_dev, "device_add_child failed\n");
533             device_set_ivars(dr->ms_disk, dr);
534         }
535     }
536     kfree(mes, M_DEVBUF);
537     if ((error = bus_generic_attach(sc->mlx_dev)) != 0)
538         device_printf(sc->mlx_dev, "bus_generic_attach returned %d", error);
539
540     /* mark controller back up */
541     sc->mlx_state &= ~MLX_STATE_SHUTDOWN;
542
543     /* enable interrupts */
544     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
545 }
546
547 /********************************************************************************
548  * Disconnect from the controller completely, in preparation for unload.
549  */
550 int
551 mlx_detach(device_t dev)
552 {
553     struct mlx_softc    *sc = device_get_softc(dev);
554     struct mlxd_softc   *mlxd;
555     int                 i, error;
556
557     debug_called(1);
558
559     error = EBUSY;
560     crit_enter();
561     if (sc->mlx_state & MLX_STATE_OPEN)
562         goto out;
563
564     for (i = 0; i < MLX_MAXDRIVES; i++) {
565         if (sc->mlx_sysdrive[i].ms_disk != 0) {
566             mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk);
567             if (mlxd->mlxd_flags & MLXD_OPEN) {         /* drive is mounted, abort detach */
568                 device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't detach\n");
569                 goto out;
570             }
571         }
572     }
573     if ((error = mlx_shutdown(dev)))
574         goto out;
575
576     mlx_free(sc);
577
578     error = 0;
579  out:
580     crit_exit();
581     return(error);
582 }
583
584 /********************************************************************************
585  * Bring the controller down to a dormant state and detach all child devices.
586  *
587  * This function is called before detach, system shutdown, or before performing
588  * an operation which may add or delete system disks.  (Call mlx_startup to
589  * resume normal operation.)
590  *
591  * Note that we can assume that the bioq on the controller is empty, as we won't
592  * allow shutdown if any device is open.
593  */
594 int
595 mlx_shutdown(device_t dev)
596 {
597     struct mlx_softc    *sc = device_get_softc(dev);
598     int                 i, error;
599
600     debug_called(1);
601
602     crit_enter();
603     error = 0;
604
605     sc->mlx_state |= MLX_STATE_SHUTDOWN;
606     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
607
608     /* flush controller */
609     device_printf(sc->mlx_dev, "flushing cache...");
610     if (mlx_flush(sc)) {
611         kprintf("failed\n");
612     } else {
613         kprintf("done\n");
614     }
615     
616     /* delete all our child devices */
617     for (i = 0; i < MLX_MAXDRIVES; i++) {
618         if (sc->mlx_sysdrive[i].ms_disk != 0) {
619             if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0)
620                 goto out;
621             sc->mlx_sysdrive[i].ms_disk = 0;
622         }
623     }
624
625  out:
626     crit_exit();
627     return(error);
628 }
629
630 /********************************************************************************
631  * Bring the controller to a quiescent state, ready for system suspend.
632  */
633 int
634 mlx_suspend(device_t dev)
635 {
636     struct mlx_softc    *sc = device_get_softc(dev);
637
638     debug_called(1);
639
640     crit_enter();
641     sc->mlx_state |= MLX_STATE_SUSPEND;
642     
643     /* flush controller */
644     device_printf(sc->mlx_dev, "flushing cache...");
645     kprintf("%s\n", mlx_flush(sc) ? "failed" : "done");
646
647     sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
648     crit_exit();
649
650     return(0);
651 }
652
653 /********************************************************************************
654  * Bring the controller back to a state ready for operation.
655  */
656 int
657 mlx_resume(device_t dev)
658 {
659     struct mlx_softc    *sc = device_get_softc(dev);
660
661     debug_called(1);
662
663     sc->mlx_state &= ~MLX_STATE_SUSPEND;
664     sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
665
666     return(0);
667 }
668
669 /*******************************************************************************
670  * Take an interrupt, or be poked by other code to look for interrupt-worthy
671  * status.
672  */
673 void
674 mlx_intr(void *arg)
675 {
676     struct mlx_softc    *sc = (struct mlx_softc *)arg;
677
678     debug_called(1);
679
680     /* collect finished commands, queue anything waiting */
681     mlx_done(sc);
682 };
683
684 /*******************************************************************************
685  * Receive a buf structure from a child device and queue it on a particular
686  * disk resource, then poke the disk resource to start as much work as it can.
687  */
688 int
689 mlx_submit_bio(struct mlx_softc *sc, struct bio *bio)
690 {
691     debug_called(1);
692
693     crit_enter();
694     bioq_insert_tail(&sc->mlx_bioq, bio);
695     sc->mlx_waitbufs++;
696     crit_exit();
697     mlx_startio(sc);
698     return(0);
699 }
700
701 /********************************************************************************
702  * Accept an open operation on the control device.
703  */
704 int
705 mlx_open(struct dev_open_args *ap)
706 {
707     cdev_t dev = ap->a_head.a_dev;
708     int                 unit = minor(dev);
709     struct mlx_softc    *sc = devclass_get_softc(mlx_devclass, unit);
710
711     sc->mlx_state |= MLX_STATE_OPEN;
712     return(0);
713 }
714
715 /********************************************************************************
716  * Accept the last close on the control device.
717  */
718 int
719 mlx_close(struct dev_close_args *ap)
720 {
721     cdev_t dev = ap->a_head.a_dev;
722     int                 unit = minor(dev);
723     struct mlx_softc    *sc = devclass_get_softc(mlx_devclass, unit);
724
725     sc->mlx_state &= ~MLX_STATE_OPEN;
726     return (0);
727 }
728
729 /********************************************************************************
730  * Handle controller-specific control operations.
731  */
732 int
733 mlx_ioctl(struct dev_ioctl_args *ap)
734 {
735     cdev_t dev = ap->a_head.a_dev;
736     int                         unit = minor(dev);
737     struct mlx_softc            *sc = devclass_get_softc(mlx_devclass, unit);
738     struct mlx_rebuild_request  *rb = (struct mlx_rebuild_request *)ap->a_data;
739     struct mlx_rebuild_status   *rs = (struct mlx_rebuild_status *)ap->a_data;
740     int                         *arg = (int *)ap->a_data;
741     struct mlx_pause            *mp;
742     struct mlx_sysdrive         *dr;
743     struct mlxd_softc           *mlxd;
744     int                         i, error;
745     
746     switch(ap->a_cmd) {
747         /*
748          * Enumerate connected system drives; returns the first system drive's
749          * unit number if *arg is -1, or the next unit after *arg if it's
750          * a valid unit on this controller.
751          */
752     case MLX_NEXT_CHILD:
753         /* search system drives */
754         for (i = 0; i < MLX_MAXDRIVES; i++) {
755             /* is this one attached? */
756             if (sc->mlx_sysdrive[i].ms_disk != 0) {
757                 /* looking for the next one we come across? */
758                 if (*arg == -1) {
759                     *arg = device_get_unit(sc->mlx_sysdrive[0].ms_disk);
760                     return(0);
761                 }
762                 /* we want the one after this one */
763                 if (*arg == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
764                     *arg = -1;
765             }
766         }
767         return(ENOENT);
768
769         /*
770          * Scan the controller to see whether new drives have appeared.
771          */
772     case MLX_RESCAN_DRIVES:
773         mlx_startup(sc);
774         return(0);
775
776         /*
777          * Disconnect from the specified drive; it may be about to go 
778          * away.
779          */
780     case MLX_DETACH_DRIVE:                      /* detach one drive */
781         
782         if (((dr = mlx_findunit(sc, *arg)) == NULL) || 
783             ((mlxd = device_get_softc(dr->ms_disk)) == NULL))
784             return(ENOENT);
785
786         device_printf(dr->ms_disk, "detaching...");
787         error = 0;
788         if (mlxd->mlxd_flags & MLXD_OPEN) {
789             error = EBUSY;
790             goto detach_out;
791         }
792         
793         /* flush controller */
794         if (mlx_flush(sc)) {
795             error = EBUSY;
796             goto detach_out;
797         }
798
799         /* nuke drive */
800         if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0)
801             goto detach_out;
802         dr->ms_disk = 0;
803
804     detach_out:
805         if (error) {
806             kprintf("failed\n");
807         } else {
808             kprintf("done\n");
809         }
810         return(error);
811
812         /*
813          * Pause one or more SCSI channels for a period of time, to assist
814          * in the process of hot-swapping devices.
815          *
816          * Note that at least the 3.51 firmware on the DAC960PL doesn't seem
817          * to do this right.
818          */
819     case MLX_PAUSE_CHANNEL:                     /* schedule a channel pause */
820         /* Does this command work on this firmware? */
821         if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS))
822             return(EOPNOTSUPP);
823
824         mp = (struct mlx_pause *)ap->a_data;
825         if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) {
826             /* cancel a pending pause operation */
827             sc->mlx_pause.mp_which = 0;
828         } else {
829             /* fix for legal channels */
830             mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1);
831             /* check time values */
832             if ((mp->mp_when < 0) || (mp->mp_when > 3600))
833                 return(EINVAL);
834             if ((mp->mp_howlong < 1) || (mp->mp_howlong > (0xf * 30)))
835                 return(EINVAL);
836             
837             /* check for a pause currently running */
838             if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0))
839                 return(EBUSY);
840
841             /* looks ok, go with it */
842             sc->mlx_pause.mp_which = mp->mp_which;
843             sc->mlx_pause.mp_when = time_second + mp->mp_when;
844             sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong;
845         }
846         return(0);
847
848         /*
849          * Accept a command passthrough-style.
850          */
851     case MLX_COMMAND:
852         return(mlx_user_command(sc, (struct mlx_usercommand *)ap->a_data));
853
854         /*
855          * Start a rebuild on a given SCSI disk
856          */
857     case MLX_REBUILDASYNC:
858         if (sc->mlx_background != 0) {
859             rb->rr_status = 0x0106;
860             return(EBUSY);
861         }
862         rb->rr_status = mlx_rebuild(sc, rb->rr_channel, rb->rr_target);
863         switch (rb->rr_status) {
864         case 0:
865             error = 0;
866             break;
867         case 0x10000:
868             error = ENOMEM;             /* couldn't set up the command */
869             break;
870         case 0x0002:    
871             error = EBUSY;
872             break;
873         case 0x0104:
874             error = EIO;
875             break;
876         case 0x0105:
877             error = ERANGE;
878             break;
879         case 0x0106:
880             error = EBUSY;
881             break;
882         default:
883             error = EINVAL;
884             break;
885         }
886         if (error == 0)
887             sc->mlx_background = MLX_BACKGROUND_REBUILD;
888         return(error);
889         
890         /*
891          * Get the status of the current rebuild or consistency check.
892          */
893     case MLX_REBUILDSTAT:
894         *rs = sc->mlx_rebuildstat;
895         return(0);
896
897         /*
898          * Return the per-controller system drive number matching the
899          * disk device number in (arg), if it happens to belong to us.
900          */
901     case MLX_GET_SYSDRIVE:
902         error = ENOENT;
903         mlxd = (struct mlxd_softc *)devclass_get_softc(mlxd_devclass, *arg);
904         if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) && 
905             (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) {
906             error = 0;
907             *arg = mlxd->mlxd_drive - sc->mlx_sysdrive;
908         }
909         return(error);
910         
911     default:    
912         return(ENOTTY);
913     }
914 }
915
916 /********************************************************************************
917  * Handle operations requested by a System Drive connected to this controller.
918  */
919 int
920 mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd, 
921                 caddr_t addr, int32_t flag)
922 {
923     int                         *arg = (int *)addr;
924     int                         error, result;
925
926     switch(cmd) {
927         /*
928          * Return the current status of this drive.
929          */
930     case MLXD_STATUS:
931         *arg = drive->ms_state;
932         return(0);
933         
934         /*
935          * Start a background consistency check on this drive.
936          */
937     case MLXD_CHECKASYNC:               /* start a background consistency check */
938         if (sc->mlx_background != 0) {
939             *arg = 0x0106;
940             return(EBUSY);
941         }
942         result = mlx_check(sc, drive - &sc->mlx_sysdrive[0]);
943         switch (result) {
944         case 0:
945             error = 0;
946             break;
947         case 0x10000:
948             error = ENOMEM;             /* couldn't set up the command */
949             break;
950         case 0x0002:    
951             error = EIO;
952             break;
953         case 0x0105:
954             error = ERANGE;
955             break;
956         case 0x0106:
957             error = EBUSY;
958             break;
959         default:
960             error = EINVAL;
961             break;
962         }
963         if (error == 0)
964             sc->mlx_background = MLX_BACKGROUND_CHECK;
965         *arg = result;
966         return(error);
967
968     }
969     return(ENOIOCTL);
970 }
971
972
973 /********************************************************************************
974  ********************************************************************************
975                                                                 Status Monitoring
976  ********************************************************************************
977  ********************************************************************************/
978
979 /********************************************************************************
980  * Fire off commands to periodically check the status of connected drives.
981  */
982 static void
983 mlx_periodic(void *data)
984 {
985     struct mlx_softc *sc = (struct mlx_softc *)data;
986
987     debug_called(1);
988
989     /*
990      * Run a bus pause? 
991      */
992     if ((sc->mlx_pause.mp_which != 0) &&
993         (sc->mlx_pause.mp_when > 0) &&
994         (time_second >= sc->mlx_pause.mp_when)){
995
996         mlx_pause_action(sc);           /* pause is running */
997         sc->mlx_pause.mp_when = 0;
998         sysbeep(500, hz);
999
1000         /* 
1001          * Bus pause still running?
1002          */
1003     } else if ((sc->mlx_pause.mp_which != 0) &&
1004                (sc->mlx_pause.mp_when == 0)) {
1005
1006         /* time to stop bus pause? */
1007         if (time_second >= sc->mlx_pause.mp_howlong) {
1008             mlx_pause_action(sc);
1009             sc->mlx_pause.mp_which = 0; /* pause is complete */
1010             sysbeep(500, hz);
1011         } else {
1012             sysbeep((time_second % 5) * 100 + 500, hz/8);
1013         }
1014
1015         /* 
1016          * Run normal periodic activities? 
1017          */
1018     } else if (time_second > (sc->mlx_lastpoll + 10)) {
1019         sc->mlx_lastpoll = time_second;
1020
1021         /* 
1022          * Check controller status.
1023          *
1024          * XXX Note that this may not actually launch a command in situations of high load.
1025          */
1026         mlx_enquire(sc, (sc->mlx_iftype == MLX_IFTYPE_2) ? MLX_CMD_ENQUIRY_OLD : MLX_CMD_ENQUIRY, 
1027                     imax(sizeof(struct mlx_enquiry), sizeof(struct mlx_enquiry_old)), mlx_periodic_enquiry);
1028
1029         /*
1030          * Check system drive status.
1031          *
1032          * XXX This might be better left to event-driven detection, eg. I/O to an offline
1033          *     drive will detect it's offline, rebuilds etc. should detect the drive is back
1034          *     online.
1035          */
1036         mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES, 
1037                         mlx_periodic_enquiry);
1038                 
1039     }
1040
1041     /* get drive rebuild/check status */
1042     /* XXX should check sc->mlx_background if this is only valid while in progress */
1043     mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
1044
1045     /* deal with possibly-missed interrupts and timed-out commands */
1046     mlx_done(sc);
1047
1048     /* reschedule another poll next second or so */
1049     callout_reset(&sc->mlx_timeout, hz, mlx_periodic, sc);
1050 }
1051
1052 /********************************************************************************
1053  * Handle the result of an ENQUIRY command instigated by periodic status polling.
1054  */
1055 static void
1056 mlx_periodic_enquiry(struct mlx_command *mc)
1057 {
1058     struct mlx_softc            *sc = mc->mc_sc;
1059
1060     debug_called(1);
1061
1062     /* Command completed OK? */
1063     if (mc->mc_status != 0) {
1064         device_printf(sc->mlx_dev, "periodic enquiry failed - %s\n", mlx_diagnose_command(mc));
1065         goto out;
1066     }
1067
1068     /* respond to command */
1069     switch(mc->mc_mailbox[0]) {
1070         /*
1071          * This is currently a bit fruitless, as we don't know how to extract the eventlog
1072          * pointer yet.
1073          */
1074     case MLX_CMD_ENQUIRY_OLD:
1075     {
1076         struct mlx_enquiry              *me = (struct mlx_enquiry *)mc->mc_data;
1077         struct mlx_enquiry_old          *meo = (struct mlx_enquiry_old *)mc->mc_data;
1078         int                             i;
1079
1080         /* convert data in-place to new format */
1081         for (i = (sizeof(me->me_dead) / sizeof(me->me_dead[0])) - 1; i >= 0; i--) {
1082             me->me_dead[i].dd_chan = meo->me_dead[i].dd_chan;
1083             me->me_dead[i].dd_targ = meo->me_dead[i].dd_targ;
1084         }
1085         me->me_misc_flags        = 0;
1086         me->me_rebuild_count     = meo->me_rebuild_count;
1087         me->me_dead_count        = meo->me_dead_count;
1088         me->me_critical_sd_count = meo->me_critical_sd_count;
1089         me->me_event_log_seq_num = 0;
1090         me->me_offline_sd_count  = meo->me_offline_sd_count;
1091         me->me_max_commands      = meo->me_max_commands;
1092         me->me_rebuild_flag      = meo->me_rebuild_flag;
1093         me->me_fwmajor           = meo->me_fwmajor;
1094         me->me_fwminor           = meo->me_fwminor;
1095         me->me_status_flags      = meo->me_status_flags;
1096         me->me_flash_age         = meo->me_flash_age;
1097         for (i = (sizeof(me->me_drvsize) / sizeof(me->me_drvsize[0])) - 1; i >= 0; i--) {
1098             if (i > ((sizeof(meo->me_drvsize) / sizeof(meo->me_drvsize[0])) - 1)) {
1099                 me->me_drvsize[i] = 0;          /* drive beyond supported range */
1100             } else {
1101                 me->me_drvsize[i] = meo->me_drvsize[i];
1102             }
1103         }
1104         me->me_num_sys_drvs = meo->me_num_sys_drvs;
1105     }
1106     /* FALLTHROUGH */
1107
1108         /*
1109          * Generic controller status update.  We could do more with this than just
1110          * checking the event log.
1111          */
1112     case MLX_CMD_ENQUIRY:
1113     {
1114         struct mlx_enquiry              *me = (struct mlx_enquiry *)mc->mc_data;
1115         
1116         if (sc->mlx_currevent == -1) {
1117             /* initialise our view of the event log */
1118             sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num;
1119         } else if ((me->me_event_log_seq_num != sc->mlx_lastevent) && !(sc->mlx_flags & MLX_EVENTLOG_BUSY)) {
1120             /* record where current events are up to */
1121             sc->mlx_currevent = me->me_event_log_seq_num;
1122             debug(1, "event log pointer was %d, now %d\n", sc->mlx_lastevent, sc->mlx_currevent);
1123
1124             /* mark the event log as busy */
1125             atomic_set_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY);
1126             
1127             /* drain new eventlog entries */
1128             mlx_periodic_eventlog_poll(sc);
1129         }
1130         break;
1131     }
1132     case MLX_CMD_ENQSYSDRIVE:
1133     {
1134         struct mlx_enq_sys_drive        *mes = (struct mlx_enq_sys_drive *)mc->mc_data;
1135         struct mlx_sysdrive             *dr;
1136         int                             i;
1137         
1138         for (i = 0, dr = &sc->mlx_sysdrive[0]; 
1139              (i < MLX_MAXDRIVES) && (mes[i].sd_size != 0xffffffff); 
1140              i++) {
1141
1142             /* has state been changed by controller? */
1143             if (dr->ms_state != mes[i].sd_state) {
1144                 switch(mes[i].sd_state) {
1145                 case MLX_SYSD_OFFLINE:
1146                     device_printf(dr->ms_disk, "drive offline\n");
1147                     break;
1148                 case MLX_SYSD_ONLINE:
1149                     device_printf(dr->ms_disk, "drive online\n");
1150                     break;
1151                 case MLX_SYSD_CRITICAL:
1152                     device_printf(dr->ms_disk, "drive critical\n");
1153                     break;
1154                 }
1155                 /* save new state */
1156                 dr->ms_state = mes[i].sd_state;
1157             }
1158         }
1159         break;
1160     }
1161     default:
1162         device_printf(sc->mlx_dev, "%s: unknown command 0x%x", __func__, mc->mc_mailbox[0]);
1163         break;
1164     }
1165
1166  out:
1167     kfree(mc->mc_data, M_DEVBUF);
1168     mlx_releasecmd(mc);
1169 }
1170
1171 /********************************************************************************
1172  * Instigate a poll for one event log message on (sc).
1173  * We only poll for one message at a time, to keep our command usage down.
1174  */
1175 static void
1176 mlx_periodic_eventlog_poll(struct mlx_softc *sc)
1177 {
1178     struct mlx_command  *mc;
1179     void                *result = NULL;
1180     int                 error;
1181
1182     debug_called(1);
1183
1184     /* get ourselves a command buffer */
1185     error = 1;
1186     if ((mc = mlx_alloccmd(sc)) == NULL)
1187         goto out;
1188     /*
1189      * allocate the response structure - sizeof(struct mlx_eventlog_entry)?
1190      * Called from timeout - use M_NOWAIT (repoll later on failure?)
1191      */
1192     if ((result = kmalloc(1024, M_DEVBUF, M_NOWAIT)) == NULL)
1193         goto out;
1194     /* get a command slot */
1195     if (mlx_getslot(mc))
1196         goto out;
1197
1198     /* map the command so the controller can see it */
1199     mc->mc_data = result;
1200     mc->mc_length = /*sizeof(struct mlx_eventlog_entry)*/1024;
1201     mlx_mapcmd(mc);
1202
1203     /* build the command to get one entry */
1204     mlx_make_type3(mc, MLX_CMD_LOGOP, MLX_LOGOP_GET, 1, sc->mlx_lastevent, 0, 0, mc->mc_dataphys, 0);
1205     mc->mc_complete = mlx_periodic_eventlog_respond;
1206     mc->mc_private = mc;
1207
1208     /* start the command */
1209     if ((error = mlx_start(mc)) != 0)
1210         goto out;
1211     
1212     error = 0;                  /* success */
1213  out:
1214     if (error != 0) {
1215         if (mc != NULL)
1216             mlx_releasecmd(mc);
1217         if (result != NULL)
1218             kfree(result, M_DEVBUF);
1219     }
1220 }
1221
1222 /********************************************************************************
1223  * Handle the result of polling for a log message, generate diagnostic output.
1224  * If this wasn't the last message waiting for us, we'll go collect another.
1225  */
1226 static char *mlx_sense_messages[] = {
1227     "because write recovery failed",
1228     "because of SCSI bus reset failure",
1229     "because of double check condition",
1230     "because it was removed",
1231     "because of gross error on SCSI chip",
1232     "because of bad tag returned from drive",
1233     "because of timeout on SCSI command",
1234     "because of reset SCSI command issued from system",
1235     "because busy or parity error count exceeded limit",
1236     "because of 'kill drive' command from system",
1237     "because of selection timeout",
1238     "due to SCSI phase sequence error",
1239     "due to unknown status"
1240 };
1241
1242 static void
1243 mlx_periodic_eventlog_respond(struct mlx_command *mc)
1244 {
1245     struct mlx_softc            *sc = mc->mc_sc;
1246     struct mlx_eventlog_entry   *el = (struct mlx_eventlog_entry *)mc->mc_data;
1247     char                        *reason;
1248
1249     debug_called(1);
1250
1251     sc->mlx_lastevent++;                /* next message... */
1252     if (mc->mc_status == 0) {
1253
1254         /* handle event log message */
1255         switch(el->el_type) {
1256             /*
1257              * This is the only sort of message we understand at the moment.
1258              * The tests here are probably incomplete.
1259              */
1260         case MLX_LOGMSG_SENSE:  /* sense data */
1261             /* Mylex vendor-specific message indicating a drive was killed? */
1262             if ((el->el_sensekey == 9) &&
1263                 (el->el_asc == 0x80)) {
1264                 if (el->el_asq < (sizeof(mlx_sense_messages) / sizeof(mlx_sense_messages[0]))) {
1265                     reason = mlx_sense_messages[el->el_asq];
1266                 } else {
1267                     reason = "for unknown reason";
1268                 }
1269                 device_printf(sc->mlx_dev, "physical drive %d:%d killed %s\n",
1270                               el->el_channel, el->el_target, reason);
1271             }
1272             /* SCSI drive was reset? */
1273             if ((el->el_sensekey == 6) && (el->el_asc == 0x29)) {
1274                 device_printf(sc->mlx_dev, "physical drive %d:%d reset\n", 
1275                               el->el_channel, el->el_target);
1276             }
1277             /* SCSI drive error? */
1278             if (!((el->el_sensekey == 0) ||
1279                   ((el->el_sensekey == 2) &&
1280                    (el->el_asc == 0x04) &&
1281                    ((el->el_asq == 0x01) ||
1282                     (el->el_asq == 0x02))))) {
1283                 device_printf(sc->mlx_dev, "physical drive %d:%d error log: sense = %d asc = %x asq = %x\n",
1284                               el->el_channel, el->el_target, el->el_sensekey, el->el_asc, el->el_asq);
1285                 device_printf(sc->mlx_dev, "  info %4D csi %4D\n", el->el_information, ":", el->el_csi, ":");
1286             }
1287             break;
1288             
1289         default:
1290             device_printf(sc->mlx_dev, "unknown log message type 0x%x\n", el->el_type);
1291             break;
1292         }
1293     } else {
1294         device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc));
1295         /* give up on all the outstanding messages, as we may have come unsynched */
1296         sc->mlx_lastevent = sc->mlx_currevent;
1297     }
1298         
1299     /* dispose of command and data */
1300     kfree(mc->mc_data, M_DEVBUF);
1301     mlx_releasecmd(mc);
1302
1303     /* is there another message to obtain? */
1304     if (sc->mlx_lastevent != sc->mlx_currevent) {
1305         mlx_periodic_eventlog_poll(sc);
1306     } else {
1307         /* clear log-busy status */
1308         atomic_clear_int(&sc->mlx_flags, MLX_EVENTLOG_BUSY);
1309     }
1310 }
1311
1312 /********************************************************************************
1313  * Handle check/rebuild operations in progress.
1314  */
1315 static void
1316 mlx_periodic_rebuild(struct mlx_command *mc)
1317 {
1318     struct mlx_softc            *sc = mc->mc_sc;
1319     struct mlx_rebuild_status   *mr = (struct mlx_rebuild_status *)mc->mc_data;
1320
1321     switch(mc->mc_status) {
1322     case 0:                             /* operation running, update stats */
1323         sc->mlx_rebuildstat = *mr;
1324
1325         /* spontaneous rebuild/check? */
1326         if (sc->mlx_background == 0) {
1327             sc->mlx_background = MLX_BACKGROUND_SPONTANEOUS;
1328             device_printf(sc->mlx_dev, "background check/rebuild operation started\n");
1329         }
1330         break;
1331
1332     case 0x0105:                        /* nothing running, finalise stats and report */
1333         switch(sc->mlx_background) {
1334         case MLX_BACKGROUND_CHECK:
1335             device_printf(sc->mlx_dev, "consistency check completed\n");        /* XXX print drive? */
1336             break;
1337         case MLX_BACKGROUND_REBUILD:
1338             device_printf(sc->mlx_dev, "drive rebuild completed\n");    /* XXX print channel/target? */
1339             break;
1340         case MLX_BACKGROUND_SPONTANEOUS:
1341         default:
1342             /* if we have previously been non-idle, report the transition */
1343             if (sc->mlx_rebuildstat.rs_code != MLX_REBUILDSTAT_IDLE) {
1344                 device_printf(sc->mlx_dev, "background check/rebuild operation completed\n");
1345             }
1346         }
1347         sc->mlx_background = 0;
1348         sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
1349         break;
1350     }
1351     kfree(mc->mc_data, M_DEVBUF);
1352     mlx_releasecmd(mc);
1353 }
1354
1355 /********************************************************************************
1356  ********************************************************************************
1357                                                                     Channel Pause
1358  ********************************************************************************
1359  ********************************************************************************/
1360
1361 /********************************************************************************
1362  * It's time to perform a channel pause action for (sc), either start or stop
1363  * the pause.
1364  */
1365 static void
1366 mlx_pause_action(struct mlx_softc *sc)
1367 {
1368     struct mlx_command  *mc;
1369     int                 failsafe, i, command;
1370
1371     /* What are we doing here? */
1372     if (sc->mlx_pause.mp_when == 0) {
1373         command = MLX_CMD_STARTCHANNEL;
1374         failsafe = 0;
1375
1376     } else {
1377         command = MLX_CMD_STOPCHANNEL;
1378
1379         /* 
1380          * Channels will always start again after the failsafe period, 
1381          * which is specified in multiples of 30 seconds.
1382          * This constrains us to a maximum pause of 450 seconds.
1383          */
1384         failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30;
1385         if (failsafe > 0xf) {
1386             failsafe = 0xf;
1387             sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5;
1388         }
1389     }
1390
1391     /* build commands for every channel requested */
1392     for (i = 0; i < sc->mlx_enq2->me_actual_channels; i++) {
1393         if ((1 << i) & sc->mlx_pause.mp_which) {
1394
1395             /* get ourselves a command buffer */
1396             if ((mc = mlx_alloccmd(sc)) == NULL)
1397                 goto fail;
1398             /* get a command slot */
1399             mc->mc_flags |= MLX_CMD_PRIORITY;
1400             if (mlx_getslot(mc))
1401                 goto fail;
1402
1403             /* build the command */
1404             mlx_make_type2(mc, command, (failsafe << 4) | i, 0, 0, 0, 0, 0, 0, 0);
1405             mc->mc_complete = mlx_pause_done;
1406             mc->mc_private = sc;                /* XXX not needed */
1407             if (mlx_start(mc))
1408                 goto fail;
1409             /* command submitted OK */
1410             return;
1411     
1412         fail:
1413             device_printf(sc->mlx_dev, "%s failed for channel %d\n", 
1414                           command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", i);
1415             if (mc != NULL)
1416                 mlx_releasecmd(mc);
1417         }
1418     }
1419 }
1420
1421 static void
1422 mlx_pause_done(struct mlx_command *mc)
1423 {
1424     struct mlx_softc    *sc = mc->mc_sc;
1425     int                 command = mc->mc_mailbox[0];
1426     int                 channel = mc->mc_mailbox[2] & 0xf;
1427     
1428     if (mc->mc_status != 0) {
1429         device_printf(sc->mlx_dev, "%s command failed - %s\n", 
1430                       command == MLX_CMD_STOPCHANNEL ? "pause" : "resume", mlx_diagnose_command(mc));
1431     } else if (command == MLX_CMD_STOPCHANNEL) {
1432         device_printf(sc->mlx_dev, "channel %d pausing for %ld seconds\n", 
1433                       channel, (long)(sc->mlx_pause.mp_howlong - time_second));
1434     } else {
1435         device_printf(sc->mlx_dev, "channel %d resuming\n", channel);
1436     }
1437     mlx_releasecmd(mc);
1438 }
1439
1440 /********************************************************************************
1441  ********************************************************************************
1442                                                                Command Submission
1443  ********************************************************************************
1444  ********************************************************************************/
1445
1446 /********************************************************************************
1447  * Perform an Enquiry command using a type-3 command buffer and a return a single
1448  * linear result buffer.  If the completion function is specified, it will
1449  * be called with the completed command (and the result response will not be
1450  * valid until that point).  Otherwise, the command will either be busy-waited
1451  * for (interrupts not enabled), or slept for.
1452  */
1453 static void *
1454 mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, void (* complete)(struct mlx_command *mc))
1455 {
1456     struct mlx_command  *mc;
1457     void                *result;
1458     int                 error;
1459
1460     debug_called(1);
1461
1462     /* get ourselves a command buffer */
1463     error = 1;
1464     result = NULL;
1465     if ((mc = mlx_alloccmd(sc)) == NULL)
1466         goto out;
1467     /* allocate the response structure */
1468     result = kmalloc(bufsize, M_DEVBUF, M_INTWAIT);
1469     /* get a command slot */
1470     mc->mc_flags |= MLX_CMD_PRIORITY | MLX_CMD_DATAOUT;
1471     if (mlx_getslot(mc))
1472         goto out;
1473
1474     /* map the command so the controller can see it */
1475     mc->mc_data = result;
1476     mc->mc_length = bufsize;
1477     mlx_mapcmd(mc);
1478
1479     /* build an enquiry command */
1480     mlx_make_type2(mc, command, 0, 0, 0, 0, 0, 0, mc->mc_dataphys, 0);
1481
1482     /* do we want a completion callback? */
1483     if (complete != NULL) {
1484         mc->mc_complete = complete;
1485         mc->mc_private = mc;
1486         if ((error = mlx_start(mc)) != 0)
1487             goto out;
1488     } else {
1489         /* run the command in either polled or wait mode */
1490         if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) : mlx_poll_command(mc))
1491             goto out;
1492     
1493         /* command completed OK? */
1494         if (mc->mc_status != 0) {
1495             device_printf(sc->mlx_dev, "ENQUIRY failed - %s\n", mlx_diagnose_command(mc));
1496             goto out;
1497         }
1498     }
1499     error = 0;                  /* success */
1500  out:
1501     /* we got a command, but nobody else will free it */
1502     if ((complete == NULL) && (mc != NULL))
1503         mlx_releasecmd(mc);
1504     /* we got an error, and we allocated a result */
1505     if ((error != 0) && (result != NULL)) {
1506         kfree(result, M_DEVBUF);
1507         result = NULL;
1508     }
1509     return(result);
1510 }
1511
1512
1513 /********************************************************************************
1514  * Perform a Flush command on the nominated controller.
1515  *
1516  * May be called with interrupts enabled or disabled; will not return until
1517  * the flush operation completes or fails.
1518  */
1519 static int
1520 mlx_flush(struct mlx_softc *sc)
1521 {
1522     struct mlx_command  *mc;
1523     int                 error;
1524
1525     debug_called(1);
1526
1527     /* get ourselves a command buffer */
1528     error = 1;
1529     if ((mc = mlx_alloccmd(sc)) == NULL)
1530         goto out;
1531     /* get a command slot */
1532     if (mlx_getslot(mc))
1533         goto out;
1534
1535     /* build a flush command */
1536     mlx_make_type2(mc, MLX_CMD_FLUSH, 0, 0, 0, 0, 0, 0, 0, 0);
1537
1538     /* can't assume that interrupts are going to work here, so play it safe */
1539     if (mlx_poll_command(mc))
1540         goto out;
1541     
1542     /* command completed OK? */
1543     if (mc->mc_status != 0) {
1544         device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc));
1545         goto out;
1546     }
1547     
1548     error = 0;                  /* success */
1549  out:
1550     if (mc != NULL)
1551         mlx_releasecmd(mc);
1552     return(error);
1553 }
1554
1555 /********************************************************************************
1556  * Start a background consistency check on (drive).
1557  *
1558  * May be called with interrupts enabled or disabled; will return as soon as the
1559  * operation has started or been refused.
1560  */
1561 static int
1562 mlx_check(struct mlx_softc *sc, int drive)
1563 {
1564     struct mlx_command  *mc;
1565     int                 error;
1566
1567     debug_called(1);
1568
1569     /* get ourselves a command buffer */
1570     error = 0x10000;
1571     if ((mc = mlx_alloccmd(sc)) == NULL)
1572         goto out;
1573     /* get a command slot */
1574     if (mlx_getslot(mc))
1575         goto out;
1576
1577     /* build a checkasync command, set the "fix it" flag */
1578     mlx_make_type2(mc, MLX_CMD_CHECKASYNC, 0, 0, 0, 0, 0, drive | 0x80, 0, 0);
1579
1580     /* start the command and wait for it to be returned */
1581     if (mlx_wait_command(mc))
1582         goto out;
1583     
1584     /* command completed OK? */
1585     if (mc->mc_status != 0) {   
1586         device_printf(sc->mlx_dev, "CHECK ASYNC failed - %s\n", mlx_diagnose_command(mc));
1587     } else {
1588         device_printf(sc->mlx_sysdrive[drive].ms_disk, "consistency check started");
1589     }
1590     error = mc->mc_status;
1591
1592  out:
1593     if (mc != NULL)
1594         mlx_releasecmd(mc);
1595     return(error);
1596 }
1597
1598 /********************************************************************************
1599  * Start a background rebuild of the physical drive at (channel),(target).
1600  *
1601  * May be called with interrupts enabled or disabled; will return as soon as the
1602  * operation has started or been refused.
1603  */
1604 static int
1605 mlx_rebuild(struct mlx_softc *sc, int channel, int target)
1606 {
1607     struct mlx_command  *mc;
1608     int                 error;
1609
1610     debug_called(1);
1611
1612     /* get ourselves a command buffer */
1613     error = 0x10000;
1614     if ((mc = mlx_alloccmd(sc)) == NULL)
1615         goto out;
1616     /* get a command slot */
1617     if (mlx_getslot(mc))
1618         goto out;
1619
1620     /* build a checkasync command, set the "fix it" flag */
1621     mlx_make_type2(mc, MLX_CMD_REBUILDASYNC, channel, target, 0, 0, 0, 0, 0, 0);
1622
1623     /* start the command and wait for it to be returned */
1624     if (mlx_wait_command(mc))
1625         goto out;
1626     
1627     /* command completed OK? */
1628     if (mc->mc_status != 0) {   
1629         device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc));
1630     } else {
1631         device_printf(sc->mlx_dev, "drive rebuild started for %d:%d\n", channel, target);
1632     }
1633     error = mc->mc_status;
1634
1635  out:
1636     if (mc != NULL)
1637         mlx_releasecmd(mc);
1638     return(error);
1639 }
1640
1641 /********************************************************************************
1642  * Run the command (mc) and return when it completes.
1643  *
1644  * Interrupts need to be enabled; returns nonzero on error.
1645  */
1646 static int
1647 mlx_wait_command(struct mlx_command *mc)
1648 {
1649     struct mlx_softc    *sc = mc->mc_sc;
1650     int                 error, count;
1651
1652     debug_called(1);
1653
1654     mc->mc_complete = NULL;
1655     mc->mc_private = mc;                /* wake us when you're done */
1656     if ((error = mlx_start(mc)) != 0)
1657         return(error);
1658
1659     count = 0;
1660     /* XXX better timeout? */
1661     while ((mc->mc_status == MLX_STATUS_BUSY) && (count < 30)) {
1662         tsleep(mc->mc_private, PCATCH, "mlxwcmd", hz);
1663     }
1664
1665     if (mc->mc_status != 0) {
1666         device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1667         return(EIO);
1668     }
1669     return(0);
1670 }
1671
1672
1673 /********************************************************************************
1674  * Start the command (mc) and busy-wait for it to complete.
1675  *
1676  * Should only be used when interrupts can't be relied upon. Returns 0 on 
1677  * success, nonzero on error.
1678  * Successfully completed commands are dequeued.
1679  */
1680 static int
1681 mlx_poll_command(struct mlx_command *mc)
1682 {
1683     struct mlx_softc    *sc = mc->mc_sc;
1684     int                 error, count;
1685
1686     debug_called(1);
1687
1688     mc->mc_complete = NULL;
1689     mc->mc_private = NULL;      /* we will poll for it */
1690     if ((error = mlx_start(mc)) != 0)
1691         return(error);
1692     
1693     count = 0;
1694     do {
1695         /* poll for completion */
1696         mlx_done(mc->mc_sc);
1697         
1698     } while ((mc->mc_status == MLX_STATUS_BUSY) && (count++ < 15000000));
1699     if (mc->mc_status != MLX_STATUS_BUSY) {
1700         crit_enter();
1701         TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
1702         crit_exit();
1703         return(0);
1704     }
1705     device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1706     return(EIO);
1707 }
1708
1709 /********************************************************************************
1710  * Pull as much work off the softc's work queue as possible and give it to the
1711  * controller.  Leave a couple of slots free for emergencies.
1712  *
1713  * Must be called at splbio or in an equivalent fashion that prevents 
1714  * reentry or activity on the bioq.
1715  */
1716 static void
1717 mlx_startio(struct mlx_softc *sc)
1718 {
1719     struct mlx_command  *mc;
1720     struct mlxd_softc   *mlxd;
1721     struct bio          *bio;
1722     struct buf          *bp;
1723     int                 blkcount;
1724     int                 driveno;
1725     int                 cmd;
1726     u_daddr_t           blkno;
1727
1728     /* avoid reentrancy */
1729     if (mlx_lock_tas(sc, MLX_LOCK_STARTING))
1730         return;
1731
1732     /* spin until something prevents us from doing any work */
1733     crit_enter();
1734     for (;;) {
1735
1736         /* see if there's work to be done */
1737         if ((bio = bioq_first(&sc->mlx_bioq)) == NULL)
1738             break;
1739         /* get a command */
1740         if ((mc = mlx_alloccmd(sc)) == NULL)
1741             break;
1742         /* get a slot for the command */
1743         if (mlx_getslot(mc) != 0) {
1744             mlx_releasecmd(mc);
1745             break;
1746         }
1747         /* get the buf containing our work */
1748         bioq_remove(&sc->mlx_bioq, bio);
1749         bp = bio->bio_buf;
1750         sc->mlx_waitbufs--;
1751         crit_exit();
1752         
1753         /* connect the buf to the command */
1754         mc->mc_complete = mlx_completeio;
1755         mc->mc_private = bp;
1756         mc->mc_data = bp->b_data;
1757         mc->mc_length = bp->b_bcount;
1758         if (bp->b_cmd == BUF_CMD_READ) {
1759             mc->mc_flags |= MLX_CMD_DATAIN;
1760             cmd = MLX_CMD_READSG;
1761         } else {
1762             mc->mc_flags |= MLX_CMD_DATAOUT;
1763             cmd = MLX_CMD_WRITESG;
1764         }
1765         
1766         /* map the command so the controller can work with it */
1767         mlx_mapcmd(mc);
1768         
1769         /* build a suitable I/O command (assumes 512-byte rounded transfers) */
1770         mlxd = (struct mlxd_softc *)bio->bio_driver_info;
1771         driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1772         blkcount = (bp->b_bcount + MLX_BLKSIZE - 1) / MLX_BLKSIZE;
1773         blkno = bio->bio_offset / MLX_BLKSIZE;
1774
1775         if ((blkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1776             device_printf(sc->mlx_dev, "I/O beyond end of unit (%u,%d > %u)\n", 
1777                           blkno, blkcount, sc->mlx_sysdrive[driveno].ms_size);
1778
1779         /*
1780          * Build the I/O command.  Note that the SG list type bits are set to zero,
1781          * denoting the format of SG list that we are using.
1782          */
1783         if (sc->mlx_iftype == MLX_IFTYPE_2) {
1784             mlx_make_type1(mc, (cmd == MLX_CMD_WRITESG) ? MLX_CMD_WRITESG_OLD : MLX_CMD_READSG_OLD,
1785                            blkcount & 0xff,                             /* xfer length low byte */
1786                            blkno,                               /* physical block number */
1787                            driveno,                                     /* target drive number */
1788                            mc->mc_sgphys,                               /* location of SG list */
1789                            mc->mc_nsgent & 0x3f);                       /* size of SG list (top 3 bits clear) */
1790         } else {
1791             mlx_make_type5(mc, cmd, 
1792                            blkcount & 0xff,                             /* xfer length low byte */
1793                            (driveno << 3) | ((blkcount >> 8) & 0x07),   /* target and length high 3 bits */
1794                            blkno,                               /* physical block number */
1795                            mc->mc_sgphys,                               /* location of SG list */
1796                            mc->mc_nsgent & 0x3f);                       /* size of SG list (top 3 bits clear) */
1797         }
1798         
1799         /* try to give command to controller */
1800         if (mlx_start(mc) != 0) {
1801             /* fail the command */
1802             mc->mc_status = MLX_STATUS_WEDGED;
1803             mlx_completeio(mc);
1804         }
1805         crit_enter();
1806     }
1807     crit_exit();
1808     mlx_lock_clr(sc, MLX_LOCK_STARTING);
1809 }
1810
1811 /********************************************************************************
1812  * Handle completion of an I/O command.
1813  */
1814 static void
1815 mlx_completeio(struct mlx_command *mc)
1816 {
1817     struct mlx_softc    *sc = mc->mc_sc;
1818     struct bio          *bio = (mlx_bio *)mc->mc_private;
1819     struct mlxd_softc   *mlxd = (struct mlxd_softc *)bio->bio_driver_info;
1820     struct buf          *bp = bio->bio_buf;
1821     
1822     if (mc->mc_status != MLX_STATUS_OK) {       /* could be more verbose here? */
1823         bp->b_error = EIO;
1824         bp->b_flags |= B_ERROR;
1825
1826         switch(mc->mc_status) {
1827         case MLX_STATUS_RDWROFFLINE:            /* system drive has gone offline */
1828             device_printf(mlxd->mlxd_dev, "drive offline\n");
1829             /* should signal this with a return code */
1830             mlxd->mlxd_drive->ms_state = MLX_SYSD_OFFLINE;
1831             break;
1832
1833         default:                                /* other I/O error */
1834             device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1835 #if 0
1836             device_printf(sc->mlx_dev, "  b_bcount %ld  offset %lld\n", 
1837                           bp->b_bcount, bio->bio_offset);
1838             device_printf(sc->mlx_dev, "  %13D\n", mc->mc_mailbox, " ");
1839 #endif
1840             break;
1841         }
1842     }
1843     mlx_releasecmd(mc);
1844     mlxd_intr(bio);
1845 }
1846
1847 /********************************************************************************
1848  * Take a command from user-space and try to run it.
1849  *
1850  * XXX Note that this can't perform very much in the way of error checking, and
1851  *     as such, applications _must_ be considered trustworthy.
1852  * XXX Commands using S/G for data are not supported.
1853  */
1854 static int
1855 mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu)
1856 {
1857     struct mlx_command  *mc;
1858     struct mlx_dcdb     *dcdb;
1859     void                *kbuf;
1860     int                 error;
1861     
1862     debug_called(0);
1863     
1864     kbuf = NULL;
1865     mc = NULL;
1866     dcdb = NULL;
1867     error = ENOMEM;
1868
1869     /* get ourselves a command and copy in from user space */
1870     if ((mc = mlx_alloccmd(sc)) == NULL)
1871         goto out;
1872     bcopy(mu->mu_command, mc->mc_mailbox, sizeof(mc->mc_mailbox));
1873     debug(0, "got command buffer");
1874
1875     /* if we need a buffer for data transfer, allocate one and copy in its initial contents */
1876     if (mu->mu_datasize > 0) {
1877         if (mu->mu_datasize > MAXPHYS)
1878             return (EINVAL);
1879         if (((kbuf = kmalloc(mu->mu_datasize, M_DEVBUF, M_WAITOK)) == NULL) ||
1880             (error = copyin(mu->mu_buf, kbuf, mu->mu_datasize)))
1881             goto out;
1882         debug(0, "got kernel buffer");
1883     }
1884
1885     /* get a command slot */
1886     if (mlx_getslot(mc))
1887         goto out;
1888     debug(0, "got a slot");
1889     
1890     /* map the command so the controller can see it */
1891     mc->mc_data = kbuf;
1892     mc->mc_length = mu->mu_datasize;
1893     mlx_mapcmd(mc);
1894     debug(0, "mapped");
1895
1896     /* 
1897      * If this is a passthrough SCSI command, the DCDB is packed at the 
1898      * beginning of the data area.  Fix up the DCDB to point to the correct physical
1899      * address and override any bufptr supplied by the caller since we know
1900      * what it's meant to be.
1901      */
1902     if (mc->mc_mailbox[0] == MLX_CMD_DIRECT_CDB) {
1903         dcdb = (struct mlx_dcdb *)kbuf;
1904         dcdb->dcdb_physaddr = mc->mc_dataphys + sizeof(*dcdb);
1905         mu->mu_bufptr = 8;
1906     }
1907     
1908     /* 
1909      * If there's a data buffer, fix up the command's buffer pointer.
1910      */
1911     if (mu->mu_datasize > 0) {
1912
1913         /* range check the pointer to physical buffer address */
1914         if ((mu->mu_bufptr < 0) || (mu->mu_bufptr > (sizeof(mu->mu_command) - sizeof(u_int32_t)))) {
1915             error = EINVAL;
1916             goto out;
1917         }
1918         mc->mc_mailbox[mu->mu_bufptr    ] =  mc->mc_dataphys        & 0xff;
1919         mc->mc_mailbox[mu->mu_bufptr + 1] = (mc->mc_dataphys >> 8)  & 0xff;
1920         mc->mc_mailbox[mu->mu_bufptr + 2] = (mc->mc_dataphys >> 16) & 0xff;
1921         mc->mc_mailbox[mu->mu_bufptr + 3] = (mc->mc_dataphys >> 24) & 0xff;
1922     }
1923     debug(0, "command fixup");
1924
1925     /* submit the command and wait */
1926     if ((error = mlx_wait_command(mc)) != 0)
1927         goto out;
1928
1929     /* copy out status and data */
1930     mu->mu_status = mc->mc_status;
1931     if ((mu->mu_datasize > 0) && ((error = copyout(kbuf, mu->mu_buf, mu->mu_datasize))))
1932         goto out;
1933     error = 0;
1934     
1935  out:
1936     mlx_releasecmd(mc);
1937     if (kbuf != NULL)
1938         kfree(kbuf, M_DEVBUF);
1939     return(error);
1940 }
1941
1942 /********************************************************************************
1943  ********************************************************************************
1944                                                         Command I/O to Controller
1945  ********************************************************************************
1946  ********************************************************************************/
1947
1948 /********************************************************************************
1949  * Find a free command slot for (mc).
1950  *
1951  * Don't hand out a slot to a normal-priority command unless there are at least
1952  * 4 slots free for priority commands.
1953  */
1954 static int
1955 mlx_getslot(struct mlx_command *mc)
1956 {
1957     struct mlx_softc    *sc = mc->mc_sc;
1958     int                 slot, limit;
1959
1960     debug_called(1);
1961
1962     /* 
1963      * Enforce slot-usage limit, if we have the required information.
1964      */
1965     if (sc->mlx_enq2 != NULL) {
1966         limit = sc->mlx_enq2->me_max_commands;
1967     } else {
1968         limit = 2;
1969     }
1970     if (sc->mlx_busycmds >= ((mc->mc_flags & MLX_CMD_PRIORITY) ? limit : limit - 4))
1971         return(EBUSY);
1972
1973     /* 
1974      * Allocate an outstanding command slot 
1975      *
1976      * XXX linear search is slow
1977      */
1978     crit_enter();
1979     for (slot = 0; slot < limit; slot++) {
1980         debug(2, "try slot %d", slot);
1981         if (sc->mlx_busycmd[slot] == NULL)
1982             break;
1983     }
1984     if (slot < limit) {
1985         sc->mlx_busycmd[slot] = mc;
1986         sc->mlx_busycmds++;
1987     }
1988     crit_exit();
1989
1990     /* out of slots? */
1991     if (slot >= limit)
1992         return(EBUSY);
1993
1994     debug(2, "got slot %d", slot);
1995     mc->mc_slot = slot;
1996     return(0);
1997 }
1998
1999 /********************************************************************************
2000  * Map/unmap (mc)'s data in the controller's addressable space.
2001  */
2002 static void
2003 mlx_setup_dmamap(void *arg, bus_dma_segment_t *segs, int nsegments, int error)
2004 {
2005     struct mlx_command  *mc = (struct mlx_command *)arg;
2006     struct mlx_softc    *sc = mc->mc_sc;
2007     struct mlx_sgentry  *sg;
2008     int                 i;
2009
2010     debug_called(1);
2011
2012     /* XXX should be unnecessary */
2013     if (sc->mlx_enq2 && (nsegments > sc->mlx_enq2->me_max_sg))
2014         panic("MLX: too many s/g segments (%d, max %d)", nsegments, sc->mlx_enq2->me_max_sg);
2015
2016     /* get base address of s/g table */
2017     sg = sc->mlx_sgtable + (mc->mc_slot * MLX_NSEG);
2018
2019     /* save s/g table information in command */
2020     mc->mc_nsgent = nsegments;
2021     mc->mc_sgphys = sc->mlx_sgbusaddr + (mc->mc_slot * MLX_NSEG * sizeof(struct mlx_sgentry));
2022     mc->mc_dataphys = segs[0].ds_addr;
2023
2024     /* populate s/g table */
2025     for (i = 0; i < nsegments; i++, sg++) {
2026         sg->sg_addr = segs[i].ds_addr;
2027         sg->sg_count = segs[i].ds_len;
2028     }
2029 }
2030
2031 static void
2032 mlx_mapcmd(struct mlx_command *mc)
2033 {
2034     struct mlx_softc    *sc = mc->mc_sc;
2035
2036     debug_called(1);
2037
2038     /* if the command involves data at all */
2039     if (mc->mc_data != NULL) {
2040         
2041         /* map the data buffer into bus space and build the s/g list */
2042         bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data, mc->mc_length, 
2043                         mlx_setup_dmamap, mc, 0);
2044         if (mc->mc_flags & MLX_CMD_DATAIN)
2045             bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_PREREAD);
2046         if (mc->mc_flags & MLX_CMD_DATAOUT)
2047             bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_PREWRITE);
2048     }
2049 }
2050
2051 static void
2052 mlx_unmapcmd(struct mlx_command *mc)
2053 {
2054     struct mlx_softc    *sc = mc->mc_sc;
2055
2056     debug_called(1);
2057
2058     /* if the command involved data at all */
2059     if (mc->mc_data != NULL) {
2060         
2061         if (mc->mc_flags & MLX_CMD_DATAIN)
2062             bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTREAD);
2063         if (mc->mc_flags & MLX_CMD_DATAOUT)
2064             bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE);
2065
2066         bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap); 
2067     }
2068 }
2069
2070 /********************************************************************************
2071  * Try to deliver (mc) to the controller.
2072  *
2073  * Can be called at any interrupt level, with or without interrupts enabled.
2074  */
2075 static int
2076 mlx_start(struct mlx_command *mc)
2077 {
2078     struct mlx_softc    *sc = mc->mc_sc;
2079     int                 i, done;
2080
2081     debug_called(1);
2082
2083     /* save the slot number as ident so we can handle this command when complete */
2084     mc->mc_mailbox[0x1] = mc->mc_slot;
2085
2086     /* mark the command as currently being processed */
2087     mc->mc_status = MLX_STATUS_BUSY;
2088
2089     /* set a default 60-second timeout  XXX tunable?  XXX not currently used */
2090     mc->mc_timeout = time_second + 60;
2091     
2092     /* spin waiting for the mailbox */
2093     for (i = 100000, done = 0; (i > 0) && !done; i--) {
2094         crit_enter();
2095         if (sc->mlx_tryqueue(sc, mc)) {
2096             done = 1;
2097             /* move command to work queue */
2098             TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link);
2099         }
2100         crit_exit();    /* drop spl to allow completion interrupts */
2101     }
2102
2103     /* command is enqueued */
2104     if (done)
2105         return(0);
2106
2107     /* 
2108      * We couldn't get the controller to take the command.  Revoke the slot
2109      * that the command was given and return it with a bad status.
2110      */
2111     sc->mlx_busycmd[mc->mc_slot] = NULL;
2112     device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n");
2113     mc->mc_status = MLX_STATUS_WEDGED;
2114     mlx_complete(sc);
2115     return(EIO);
2116 }
2117
2118 /********************************************************************************
2119  * Poll the controller (sc) for completed commands.
2120  * Update command status and free slots for reuse.  If any slots were freed,
2121  * new commands may be posted.
2122  *
2123  * Returns nonzero if one or more commands were completed.
2124  */
2125 static int
2126 mlx_done(struct mlx_softc *sc)
2127 {
2128     struct mlx_command  *mc;
2129     int                 result;
2130     u_int8_t            slot;
2131     u_int16_t           status;
2132     
2133     debug_called(2);
2134
2135     result = 0;
2136
2137     /* loop collecting completed commands */
2138     crit_enter();
2139     for (;;) {
2140         /* poll for a completed command's identifier and status */
2141         if (sc->mlx_findcomplete(sc, &slot, &status)) {
2142             result = 1;
2143             mc = sc->mlx_busycmd[slot];                 /* find command */
2144             if (mc != NULL) {                           /* paranoia */
2145                 if (mc->mc_status == MLX_STATUS_BUSY) {
2146                     mc->mc_status = status;             /* save status */
2147
2148                     /* free slot for reuse */
2149                     sc->mlx_busycmd[slot] = NULL;
2150                     sc->mlx_busycmds--;
2151                 } else {
2152                     device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot);
2153                 }
2154             } else {
2155                 device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot);
2156             }
2157         } else {
2158             break;
2159         }
2160     }
2161     crit_exit();
2162
2163     /* if we've completed any commands, try posting some more */
2164     if (result)
2165         mlx_startio(sc);
2166
2167     /* handle completion and timeouts */
2168     mlx_complete(sc);
2169
2170     return(result);
2171 }
2172
2173 /********************************************************************************
2174  * Perform post-completion processing for commands on (sc).
2175  */
2176 static void
2177 mlx_complete(struct mlx_softc *sc) 
2178 {
2179     struct mlx_command  *mc, *nc;
2180     int                 count;
2181     
2182     debug_called(2);
2183
2184     /* avoid reentrancy  XXX might want to signal and request a restart */
2185     if (mlx_lock_tas(sc, MLX_LOCK_COMPLETING))
2186         return;
2187
2188     crit_enter();
2189     count = 0;
2190
2191     /* scan the list of busy/done commands */
2192     mc = TAILQ_FIRST(&sc->mlx_work);
2193     while (mc != NULL) {
2194         nc = TAILQ_NEXT(mc, mc_link);
2195
2196         /* Command has been completed in some fashion */
2197         if (mc->mc_status != MLX_STATUS_BUSY) {
2198         
2199             /* unmap the command's data buffer */
2200             mlx_unmapcmd(mc);
2201             /*
2202              * Does the command have a completion handler?
2203              */
2204             if (mc->mc_complete != NULL) {
2205                 /* remove from list and give to handler */
2206                 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2207                 mc->mc_complete(mc);
2208
2209                 /* 
2210                  * Is there a sleeper waiting on this command?
2211                  */
2212             } else if (mc->mc_private != NULL) {        /* sleeping caller wants to know about it */
2213
2214                 /* remove from list and wake up sleeper */
2215                 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2216                 wakeup_one(mc->mc_private);
2217
2218                 /*
2219                  * Leave the command for a caller that's polling for it.
2220                  */
2221             } else {
2222             }
2223         }
2224         mc = nc;
2225     }
2226     crit_exit();
2227
2228     mlx_lock_clr(sc, MLX_LOCK_COMPLETING);
2229 }
2230
2231 /********************************************************************************
2232  ********************************************************************************
2233                                                         Command Buffer Management
2234  ********************************************************************************
2235  ********************************************************************************/
2236
2237 /********************************************************************************
2238  * Get a new command buffer.
2239  *
2240  * This may return NULL in low-memory cases.
2241  *
2242  * Note that using malloc() is expensive (the command buffer is << 1 page) but
2243  * necessary if we are to be a loadable module before the zone allocator is fixed.
2244  *
2245  * If possible, we recycle a command buffer that's been used before.
2246  *
2247  * XXX Note that command buffers are not cleaned out - it is the caller's 
2248  *     responsibility to ensure that all required fields are filled in before
2249  *     using a buffer.
2250  */
2251 static struct mlx_command *
2252 mlx_alloccmd(struct mlx_softc *sc)
2253 {
2254     struct mlx_command  *mc;
2255     int                 error;
2256
2257     debug_called(1);
2258
2259     crit_enter();
2260     if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL)
2261         TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
2262     crit_exit();
2263
2264     /* allocate a new command buffer? */
2265     if (mc == NULL) {
2266         mc = kmalloc(sizeof(*mc), M_DEVBUF, M_INTWAIT | M_ZERO);
2267         mc->mc_sc = sc;
2268         error = bus_dmamap_create(sc->mlx_buffer_dmat, 0, &mc->mc_dmamap);
2269         if (error) {
2270             kfree(mc, M_DEVBUF);
2271             return(NULL);
2272         }
2273     }
2274     return(mc);
2275 }
2276
2277 /********************************************************************************
2278  * Release a command buffer for recycling.
2279  *
2280  * XXX It might be a good idea to limit the number of commands we save for reuse
2281  *     if it's shown that this list bloats out massively.
2282  */
2283 static void
2284 mlx_releasecmd(struct mlx_command *mc)
2285 {
2286     debug_called(1);
2287
2288     crit_enter();
2289     TAILQ_INSERT_HEAD(&mc->mc_sc->mlx_freecmds, mc, mc_link);
2290     crit_exit();
2291 }
2292
2293 /********************************************************************************
2294  * Permanently discard a command buffer.
2295  */
2296 static void
2297 mlx_freecmd(struct mlx_command *mc) 
2298 {
2299     struct mlx_softc    *sc = mc->mc_sc;
2300     
2301     debug_called(1);
2302     bus_dmamap_destroy(sc->mlx_buffer_dmat, mc->mc_dmamap);
2303     kfree(mc, M_DEVBUF);
2304 }
2305
2306
2307 /********************************************************************************
2308  ********************************************************************************
2309                                                 Type 3 interface accessor methods
2310  ********************************************************************************
2311  ********************************************************************************/
2312
2313 /********************************************************************************
2314  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2315  * (the controller is not ready to take a command).
2316  *
2317  * Must be called at splbio or in a fashion that prevents reentry.
2318  */
2319 static int
2320 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2321 {
2322     int         i;
2323     
2324     debug_called(2);
2325
2326     /* ready for our command? */
2327     if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) {
2328         /* copy mailbox data to window */
2329         for (i = 0; i < 13; i++)
2330             MLX_V3_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2331         
2332         /* post command */
2333         MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_FULL);
2334         return(1);
2335     }
2336     return(0);
2337 }
2338
2339 /********************************************************************************
2340  * See if a command has been completed, if so acknowledge its completion
2341  * and recover the slot number and status code.
2342  *
2343  * Must be called at splbio or in a fashion that prevents reentry.
2344  */
2345 static int
2346 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2347 {
2348
2349     debug_called(2);
2350
2351     /* status available? */
2352     if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) {
2353         *slot = MLX_V3_GET_STATUS_IDENT(sc);            /* get command identifier */
2354         *status = MLX_V3_GET_STATUS(sc);                /* get status */
2355
2356         /* acknowledge completion */
2357         MLX_V3_PUT_ODBR(sc, MLX_V3_ODB_SAVAIL);
2358         MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2359         return(1);
2360     }
2361     return(0);
2362 }
2363
2364 /********************************************************************************
2365  * Enable/disable interrupts as requested. (No acknowledge required)
2366  *
2367  * Must be called at splbio or in a fashion that prevents reentry.
2368  */
2369 static void
2370 mlx_v3_intaction(struct mlx_softc *sc, int action)
2371 {
2372     debug_called(1);
2373
2374     switch(action) {
2375     case MLX_INTACTION_DISABLE:
2376         MLX_V3_PUT_IER(sc, 0);
2377         sc->mlx_state &= ~MLX_STATE_INTEN;
2378         break;
2379     case MLX_INTACTION_ENABLE:
2380         MLX_V3_PUT_IER(sc, 1);
2381         sc->mlx_state |= MLX_STATE_INTEN;
2382         break;
2383     }
2384 }
2385
2386 /********************************************************************************
2387  * Poll for firmware error codes during controller initialisation.
2388  * Returns 0 if initialisation is complete, 1 if still in progress but no 
2389  * error has been fetched, 2 if an error has been retrieved.
2390  */
2391 static int 
2392 mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
2393 {
2394     u_int8_t    fwerror;
2395     static int  initted = 0;
2396
2397     debug_called(2);
2398
2399     /* first time around, clear any hardware completion status */
2400     if (!initted) {
2401         MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2402         DELAY(1000);
2403         initted = 1;
2404     }
2405
2406     /* init in progress? */
2407     if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_INIT_BUSY))
2408         return(0);
2409
2410     /* test error value */
2411     fwerror = MLX_V3_GET_FWERROR(sc);
2412     if (!(fwerror & MLX_V3_FWERROR_PEND))
2413         return(1);
2414
2415     /* mask status pending bit, fetch status */
2416     *error = fwerror & ~MLX_V3_FWERROR_PEND;
2417     *param1 = MLX_V3_GET_FWERROR_PARAM1(sc);
2418     *param2 = MLX_V3_GET_FWERROR_PARAM2(sc);
2419
2420     /* acknowledge */
2421     MLX_V3_PUT_FWERROR(sc, 0);
2422
2423     return(2);
2424 }
2425
2426 /********************************************************************************
2427  ********************************************************************************
2428                                                 Type 4 interface accessor methods
2429  ********************************************************************************
2430  ********************************************************************************/
2431
2432 /********************************************************************************
2433  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2434  * (the controller is not ready to take a command).
2435  *
2436  * Must be called at splbio or in a fashion that prevents reentry.
2437  */
2438 static int
2439 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2440 {
2441     int         i;
2442     
2443     debug_called(2);
2444
2445     /* ready for our command? */
2446     if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) {
2447         /* copy mailbox data to window */
2448         for (i = 0; i < 13; i++)
2449             MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2450         
2451         /* memory-mapped controller, so issue a write barrier to ensure the mailbox is filled */
2452         bus_space_barrier(sc->mlx_btag, sc->mlx_bhandle, MLX_V4_MAILBOX, MLX_V4_MAILBOX_LENGTH,
2453                           BUS_SPACE_BARRIER_WRITE);
2454
2455         /* post command */
2456         MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_HWMBOX_CMD);
2457         return(1);
2458     }
2459     return(0);
2460 }
2461
2462 /********************************************************************************
2463  * See if a command has been completed, if so acknowledge its completion
2464  * and recover the slot number and status code.
2465  *
2466  * Must be called at splbio or in a fashion that prevents reentry.
2467  */
2468 static int
2469 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2470 {
2471
2472     debug_called(2);
2473
2474     /* status available? */
2475     if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) {
2476         *slot = MLX_V4_GET_STATUS_IDENT(sc);            /* get command identifier */
2477         *status = MLX_V4_GET_STATUS(sc);                /* get status */
2478
2479         /* acknowledge completion */
2480         MLX_V4_PUT_ODBR(sc, MLX_V4_ODB_HWMBOX_ACK);
2481         MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2482         return(1);
2483     }
2484     return(0);
2485 }
2486
2487 /********************************************************************************
2488  * Enable/disable interrupts as requested.
2489  *
2490  * Must be called at splbio or in a fashion that prevents reentry.
2491  */
2492 static void
2493 mlx_v4_intaction(struct mlx_softc *sc, int action)
2494 {
2495     debug_called(1);
2496
2497     switch(action) {
2498     case MLX_INTACTION_DISABLE:
2499         MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK | MLX_V4_IER_DISINT);
2500         sc->mlx_state &= ~MLX_STATE_INTEN;
2501         break;
2502     case MLX_INTACTION_ENABLE:
2503         MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK & ~MLX_V4_IER_DISINT);
2504         sc->mlx_state |= MLX_STATE_INTEN;
2505         break;
2506     }
2507 }
2508
2509 /********************************************************************************
2510  * Poll for firmware error codes during controller initialisation.
2511  * Returns 0 if initialisation is complete, 1 if still in progress but no 
2512  * error has been fetched, 2 if an error has been retrieved.
2513  */
2514 static int 
2515 mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
2516 {
2517     u_int8_t    fwerror;
2518     static int  initted = 0;
2519
2520     debug_called(2);
2521
2522     /* first time around, clear any hardware completion status */
2523     if (!initted) {
2524         MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2525         DELAY(1000);
2526         initted = 1;
2527     }
2528
2529     /* init in progress? */
2530     if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_INIT_BUSY))
2531         return(0);
2532
2533     /* test error value */
2534     fwerror = MLX_V4_GET_FWERROR(sc);
2535     if (!(fwerror & MLX_V4_FWERROR_PEND))
2536         return(1);
2537
2538     /* mask status pending bit, fetch status */
2539     *error = fwerror & ~MLX_V4_FWERROR_PEND;
2540     *param1 = MLX_V4_GET_FWERROR_PARAM1(sc);
2541     *param2 = MLX_V4_GET_FWERROR_PARAM2(sc);
2542
2543     /* acknowledge */
2544     MLX_V4_PUT_FWERROR(sc, 0);
2545
2546     return(2);
2547 }
2548
2549 /********************************************************************************
2550  ********************************************************************************
2551                                                 Type 5 interface accessor methods
2552  ********************************************************************************
2553  ********************************************************************************/
2554
2555 /********************************************************************************
2556  * Try to give (mc) to the controller.  Returns 1 if successful, 0 on failure
2557  * (the controller is not ready to take a command).
2558  *
2559  * Must be called at splbio or in a fashion that prevents reentry.
2560  */
2561 static int
2562 mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2563 {
2564     int         i;
2565
2566     debug_called(2);
2567
2568     /* ready for our command? */
2569     if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) {
2570         /* copy mailbox data to window */
2571         for (i = 0; i < 13; i++)
2572             MLX_V5_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2573
2574         /* post command */
2575         MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_HWMBOX_CMD);
2576         return(1);
2577     }
2578     return(0);
2579 }
2580
2581 /********************************************************************************
2582  * See if a command has been completed, if so acknowledge its completion
2583  * and recover the slot number and status code.
2584  *
2585  * Must be called at splbio or in a fashion that prevents reentry.
2586  */
2587 static int
2588 mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2589 {
2590
2591     debug_called(2);
2592
2593     /* status available? */
2594     if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) {
2595         *slot = MLX_V5_GET_STATUS_IDENT(sc);            /* get command identifier */
2596         *status = MLX_V5_GET_STATUS(sc);                /* get status */
2597
2598         /* acknowledge completion */
2599         MLX_V5_PUT_ODBR(sc, MLX_V5_ODB_HWMBOX_ACK);
2600         MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2601         return(1);
2602     }
2603     return(0);
2604 }
2605
2606 /********************************************************************************
2607  * Enable/disable interrupts as requested.
2608  *
2609  * Must be called at splbio or in a fashion that prevents reentry.
2610  */
2611 static void
2612 mlx_v5_intaction(struct mlx_softc *sc, int action)
2613 {
2614     debug_called(1);
2615
2616     switch(action) {
2617     case MLX_INTACTION_DISABLE:
2618         MLX_V5_PUT_IER(sc, 0xff & MLX_V5_IER_DISINT);
2619         sc->mlx_state &= ~MLX_STATE_INTEN;
2620         break;
2621     case MLX_INTACTION_ENABLE:
2622         MLX_V5_PUT_IER(sc, 0xff & ~MLX_V5_IER_DISINT);
2623         sc->mlx_state |= MLX_STATE_INTEN;
2624         break;
2625     }
2626 }
2627
2628 /********************************************************************************
2629  * Poll for firmware error codes during controller initialisation.
2630  * Returns 0 if initialisation is complete, 1 if still in progress but no 
2631  * error has been fetched, 2 if an error has been retrieved.
2632  */
2633 static int 
2634 mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2)
2635 {
2636     u_int8_t    fwerror;
2637     static int  initted = 0;
2638
2639     debug_called(2);
2640
2641     /* first time around, clear any hardware completion status */
2642     if (!initted) {
2643         MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2644         DELAY(1000);
2645         initted = 1;
2646     }
2647
2648     /* init in progress? */
2649     if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_INIT_DONE)
2650         return(0);
2651
2652     /* test for error value */
2653     fwerror = MLX_V5_GET_FWERROR(sc);
2654     if (!(fwerror & MLX_V5_FWERROR_PEND))
2655         return(1);
2656
2657     /* mask status pending bit, fetch status */
2658     *error = fwerror & ~MLX_V5_FWERROR_PEND;
2659     *param1 = MLX_V5_GET_FWERROR_PARAM1(sc);
2660     *param2 = MLX_V5_GET_FWERROR_PARAM2(sc);
2661
2662     /* acknowledge */
2663     MLX_V5_PUT_FWERROR(sc, 0xff);
2664
2665     return(2);
2666 }
2667
2668 /********************************************************************************
2669  ********************************************************************************
2670                                                                         Debugging
2671  ********************************************************************************
2672  ********************************************************************************/
2673
2674 /********************************************************************************
2675  * Return a status message describing (mc)
2676  */
2677 static char *mlx_status_messages[] = {
2678     "normal completion",                        /* 00 */
2679     "irrecoverable data error",                 /* 01 */
2680     "drive does not exist, or is offline",      /* 02 */
2681     "attempt to write beyond end of drive",     /* 03 */
2682     "bad data encountered",                     /* 04 */
2683     "invalid log entry request",                /* 05 */
2684     "attempt to rebuild online drive",          /* 06 */
2685     "new disk failed during rebuild",           /* 07 */
2686     "invalid channel/target",                   /* 08 */
2687     "rebuild/check already in progress",        /* 09 */
2688     "one or more disks are dead",               /* 10 */
2689     "invalid or non-redundant drive",           /* 11 */
2690     "channel is busy",                          /* 12 */
2691     "channel is not stopped",                   /* 13 */
2692     "rebuild successfully terminated",          /* 14 */
2693     "unsupported command",                      /* 15 */
2694     "check condition received",                 /* 16 */
2695     "device is busy",                           /* 17 */
2696     "selection or command timeout",             /* 18 */
2697     "command terminated abnormally",            /* 19 */
2698     ""
2699 };
2700
2701 static struct
2702 {
2703     int         command;
2704     u_int16_t   status;
2705     int         msg;
2706 } mlx_messages[] = {
2707     {MLX_CMD_READSG,            0x0001,  1},
2708     {MLX_CMD_READSG,            0x0002,  1},
2709     {MLX_CMD_READSG,            0x0105,  3},
2710     {MLX_CMD_READSG,            0x010c,  4},
2711     {MLX_CMD_WRITESG,           0x0001,  1},
2712     {MLX_CMD_WRITESG,           0x0002,  1},
2713     {MLX_CMD_WRITESG,           0x0105,  3},
2714     {MLX_CMD_READSG_OLD,        0x0001,  1},
2715     {MLX_CMD_READSG_OLD,        0x0002,  1},
2716     {MLX_CMD_READSG_OLD,        0x0105,  3},
2717     {MLX_CMD_WRITESG_OLD,       0x0001,  1},
2718     {MLX_CMD_WRITESG_OLD,       0x0002,  1},
2719     {MLX_CMD_WRITESG_OLD,       0x0105,  3},
2720     {MLX_CMD_LOGOP,             0x0105,  5},
2721     {MLX_CMD_REBUILDASYNC,      0x0002,  6},
2722     {MLX_CMD_REBUILDASYNC,      0x0004,  7},
2723     {MLX_CMD_REBUILDASYNC,      0x0105,  8},
2724     {MLX_CMD_REBUILDASYNC,      0x0106,  9},
2725     {MLX_CMD_REBUILDASYNC,      0x0107, 14},
2726     {MLX_CMD_CHECKASYNC,        0x0002, 10},
2727     {MLX_CMD_CHECKASYNC,        0x0105, 11},
2728     {MLX_CMD_CHECKASYNC,        0x0106,  9},
2729     {MLX_CMD_STOPCHANNEL,       0x0106, 12},
2730     {MLX_CMD_STOPCHANNEL,       0x0105,  8},
2731     {MLX_CMD_STARTCHANNEL,      0x0005, 13},
2732     {MLX_CMD_STARTCHANNEL,      0x0105,  8},
2733     {MLX_CMD_DIRECT_CDB,        0x0002, 16},
2734     {MLX_CMD_DIRECT_CDB,        0x0008, 17},
2735     {MLX_CMD_DIRECT_CDB,        0x000e, 18},
2736     {MLX_CMD_DIRECT_CDB,        0x000f, 19},
2737     {MLX_CMD_DIRECT_CDB,        0x0105,  8},
2738     
2739     {0,                         0x0104, 14},
2740     {-1, 0, 0}
2741 };
2742
2743 static char *
2744 mlx_diagnose_command(struct mlx_command *mc)
2745 {
2746     static char unkmsg[80];
2747     int         i;
2748     
2749     /* look up message in table */
2750     for (i = 0; mlx_messages[i].command != -1; i++)
2751         if (((mc->mc_mailbox[0] == mlx_messages[i].command) || (mlx_messages[i].command == 0)) &&
2752             (mc->mc_status == mlx_messages[i].status))
2753             return(mlx_status_messages[mlx_messages[i].msg]);
2754         
2755     ksprintf(unkmsg, "unknown response 0x%x for command 0x%x", (int)mc->mc_status, (int)mc->mc_mailbox[0]);
2756     return(unkmsg);
2757 }
2758
2759 /*******************************************************************************
2760  * Print a string describing the controller (sc)
2761  */
2762 static struct 
2763 {
2764     int         hwid;
2765     char        *name;
2766 } mlx_controller_names[] = {
2767     {0x01,      "960P/PD"},
2768     {0x02,      "960PL"},
2769     {0x10,      "960PG"},
2770     {0x11,      "960PJ"},
2771     {0x12,      "960PR"},
2772     {0x13,      "960PT"},
2773     {0x14,      "960PTL0"},
2774     {0x15,      "960PRL"},
2775     {0x16,      "960PTL1"},
2776     {0x20,      "1164PVX"},
2777     {-1, NULL}
2778 };
2779
2780 static void
2781 mlx_describe_controller(struct mlx_softc *sc) 
2782 {
2783     static char         buf[80];
2784     char                *model;
2785     int                 i;
2786
2787     for (i = 0, model = NULL; mlx_controller_names[i].name != NULL; i++) {
2788         if ((sc->mlx_enq2->me_hardware_id & 0xff) == mlx_controller_names[i].hwid) {
2789             model = mlx_controller_names[i].name;
2790             break;
2791         }
2792     }
2793     if (model == NULL) {
2794         ksprintf(buf, " model 0x%x", sc->mlx_enq2->me_hardware_id & 0xff);
2795         model = buf;
2796     }
2797     device_printf(sc->mlx_dev, "DAC%s, %d channel%s, firmware %d.%02d-%c-%02d, %dMB RAM\n",
2798                   model, 
2799                   sc->mlx_enq2->me_actual_channels, 
2800                   sc->mlx_enq2->me_actual_channels > 1 ? "s" : "",
2801                   sc->mlx_enq2->me_firmware_id & 0xff,
2802                   (sc->mlx_enq2->me_firmware_id >> 8) & 0xff,
2803                   (sc->mlx_enq2->me_firmware_id >> 24) & 0xff,
2804                   (sc->mlx_enq2->me_firmware_id >> 16) & 0xff,
2805                   sc->mlx_enq2->me_mem_size / (1024 * 1024));
2806
2807     if (bootverbose) {
2808         device_printf(sc->mlx_dev, "  Hardware ID                 0x%08x\n", sc->mlx_enq2->me_hardware_id);
2809         device_printf(sc->mlx_dev, "  Firmware ID                 0x%08x\n", sc->mlx_enq2->me_firmware_id);
2810         device_printf(sc->mlx_dev, "  Configured/Actual channels  %d/%d\n", sc->mlx_enq2->me_configured_channels,
2811                       sc->mlx_enq2->me_actual_channels);
2812         device_printf(sc->mlx_dev, "  Max Targets                 %d\n", sc->mlx_enq2->me_max_targets);
2813         device_printf(sc->mlx_dev, "  Max Tags                    %d\n", sc->mlx_enq2->me_max_tags);
2814         device_printf(sc->mlx_dev, "  Max System Drives           %d\n", sc->mlx_enq2->me_max_sys_drives);
2815         device_printf(sc->mlx_dev, "  Max Arms                    %d\n", sc->mlx_enq2->me_max_arms);
2816         device_printf(sc->mlx_dev, "  Max Spans                   %d\n", sc->mlx_enq2->me_max_spans);
2817         device_printf(sc->mlx_dev, "  DRAM/cache/flash/NVRAM size %d/%d/%d/%d\n", sc->mlx_enq2->me_mem_size,
2818                       sc->mlx_enq2->me_cache_size, sc->mlx_enq2->me_flash_size, sc->mlx_enq2->me_nvram_size);
2819         device_printf(sc->mlx_dev, "  DRAM type                   %d\n", sc->mlx_enq2->me_mem_type);
2820         device_printf(sc->mlx_dev, "  Clock Speed                 %dns\n", sc->mlx_enq2->me_clock_speed);
2821         device_printf(sc->mlx_dev, "  Hardware Speed              %dns\n", sc->mlx_enq2->me_hardware_speed);
2822         device_printf(sc->mlx_dev, "  Max Commands                %d\n", sc->mlx_enq2->me_max_commands);
2823         device_printf(sc->mlx_dev, "  Max SG Entries              %d\n", sc->mlx_enq2->me_max_sg);
2824         device_printf(sc->mlx_dev, "  Max DP                      %d\n", sc->mlx_enq2->me_max_dp);
2825         device_printf(sc->mlx_dev, "  Max IOD                     %d\n", sc->mlx_enq2->me_max_iod);
2826         device_printf(sc->mlx_dev, "  Max Comb                    %d\n", sc->mlx_enq2->me_max_comb);
2827         device_printf(sc->mlx_dev, "  Latency                     %ds\n", sc->mlx_enq2->me_latency);
2828         device_printf(sc->mlx_dev, "  SCSI Timeout                %ds\n", sc->mlx_enq2->me_scsi_timeout);
2829         device_printf(sc->mlx_dev, "  Min Free Lines              %d\n", sc->mlx_enq2->me_min_freelines);
2830         device_printf(sc->mlx_dev, "  Rate Constant               %d\n", sc->mlx_enq2->me_rate_const);
2831         device_printf(sc->mlx_dev, "  MAXBLK                      %d\n", sc->mlx_enq2->me_maxblk);
2832         device_printf(sc->mlx_dev, "  Blocking Factor             %d sectors\n", sc->mlx_enq2->me_blocking_factor);
2833         device_printf(sc->mlx_dev, "  Cache Line Size             %d blocks\n", sc->mlx_enq2->me_cacheline);
2834         device_printf(sc->mlx_dev, "  SCSI Capability             %s%dMHz, %d bit\n", 
2835                       sc->mlx_enq2->me_scsi_cap & (1<<4) ? "differential " : "",
2836                       (1 << ((sc->mlx_enq2->me_scsi_cap >> 2) & 3)) * 10,
2837                       8 << (sc->mlx_enq2->me_scsi_cap & 0x3));
2838         device_printf(sc->mlx_dev, "  Firmware Build Number       %d\n", sc->mlx_enq2->me_firmware_build);
2839         device_printf(sc->mlx_dev, "  Fault Management Type       %d\n", sc->mlx_enq2->me_fault_mgmt_type);
2840         device_printf(sc->mlx_dev, "  Features                    %b\n", sc->mlx_enq2->me_firmware_features,
2841                       "\20\4Background Init\3Read Ahead\2MORE\1Cluster\n");
2842         
2843     }
2844 }
2845
2846 /*******************************************************************************
2847  * Emit a string describing the firmware handshake status code, and return a flag 
2848  * indicating whether the code represents a fatal error.
2849  *
2850  * Error code interpretations are from the Linux driver, and don't directly match
2851  * the messages printed by Mylex's BIOS.  This may change if documentation on the
2852  * codes is forthcoming.
2853  */
2854 static int
2855 mlx_fw_message(struct mlx_softc *sc, int error, int param1, int param2)
2856 {
2857     switch(error) {
2858     case 0x00:
2859         device_printf(sc->mlx_dev, "physical drive %d:%d not responding\n", param2, param1);
2860         break;
2861     case 0x08:
2862         /* we could be neater about this and give some indication when we receive more of them */
2863         if (!(sc->mlx_flags & MLX_SPINUP_REPORTED)) {
2864             device_printf(sc->mlx_dev, "spinning up drives...\n");
2865             sc->mlx_flags |= MLX_SPINUP_REPORTED;
2866         }
2867         break;
2868     case 0x30:
2869         device_printf(sc->mlx_dev, "configuration checksum error\n");
2870         break;
2871     case 0x60:
2872         device_printf(sc->mlx_dev, "mirror race recovery failed\n");
2873         break;
2874     case 0x70:
2875         device_printf(sc->mlx_dev, "mirror race recovery in progress\n");
2876         break;
2877     case 0x90:
2878         device_printf(sc->mlx_dev, "physical drive %d:%d COD mismatch\n", param2, param1);
2879         break;
2880     case 0xa0:
2881         device_printf(sc->mlx_dev, "logical drive installation aborted\n");
2882         break;
2883     case 0xb0:
2884         device_printf(sc->mlx_dev, "mirror race on a critical system drive\n");
2885         break;
2886     case 0xd0:
2887         device_printf(sc->mlx_dev, "new controller configuration found\n");
2888         break;
2889     case 0xf0:
2890         device_printf(sc->mlx_dev, "FATAL MEMORY PARITY ERROR\n");
2891         return(1);
2892     default:
2893         device_printf(sc->mlx_dev, "unknown firmware initialisation error %02x:%02x:%02x\n", error, param1, param2);
2894         break;
2895     }
2896     return(0);
2897 }
2898
2899 /********************************************************************************
2900  ********************************************************************************
2901                                                                 Utility Functions
2902  ********************************************************************************
2903  ********************************************************************************/
2904
2905 /********************************************************************************
2906  * Find the disk whose unit number is (unit) on this controller
2907  */
2908 static struct mlx_sysdrive *
2909 mlx_findunit(struct mlx_softc *sc, int unit)
2910 {
2911     int         i;
2912     
2913     /* search system drives */
2914     for (i = 0; i < MLX_MAXDRIVES; i++) {
2915         /* is this one attached? */
2916         if (sc->mlx_sysdrive[i].ms_disk != 0) {
2917             /* is this the one? */
2918             if (unit == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
2919                 return(&sc->mlx_sysdrive[i]);
2920         }
2921     }
2922     return(NULL);
2923 }