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