Lines Matching refs:sc

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, int first);
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, int first);
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, int first);
88 static void mlx_periodic_eventlog_poll(struct mlx_softc *sc);
95 static void mlx_pause_action(struct mlx_softc *sc);
101 static void *mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize,
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);
111 static void mlx_startio(struct mlx_softc *sc);
113 static int mlx_user_command(struct mlx_softc *sc,
121 static struct mlx_command *mlx_alloccmd(struct mlx_softc *sc);
133 static int mlx_shutdown_locked(struct mlx_softc *sc);
135 static int mlx_done(struct mlx_softc *sc, int startio);
136 static void mlx_complete(struct mlx_softc *sc);
142 static void mlx_describe_controller(struct mlx_softc *sc);
143 static int mlx_fw_message(struct mlx_softc *sc, int status, int param1, int param2);
148 static struct mlx_sysdrive *mlx_findunit(struct mlx_softc *sc, int unit);
157 * Free all of the resources associated with (sc)
162 mlx_free(struct mlx_softc *sc)
169 if (sc->mlx_dev_t != NULL)
170 destroy_dev(sc->mlx_dev_t);
172 if (sc->mlx_intr)
173 bus_teardown_intr(sc->mlx_dev, sc->mlx_irq, sc->mlx_intr);
176 MLX_IO_LOCK(sc);
177 callout_stop(&sc->mlx_timeout);
180 while ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL) {
181 TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
184 MLX_IO_UNLOCK(sc);
185 callout_drain(&sc->mlx_timeout);
188 if (sc->mlx_buffer_dmat)
189 bus_dma_tag_destroy(sc->mlx_buffer_dmat);
192 if (sc->mlx_sgbusaddr)
193 bus_dmamap_unload(sc->mlx_sg_dmat, sc->mlx_sg_dmamap);
194 if (sc->mlx_sgtable)
195 bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap);
196 if (sc->mlx_sg_dmat)
197 bus_dma_tag_destroy(sc->mlx_sg_dmat);
200 if (sc->mlx_irq != NULL)
201 bus_release_resource(sc->mlx_dev, SYS_RES_IRQ, 0, sc->mlx_irq);
204 if (sc->mlx_parent_dmat)
205 bus_dma_tag_destroy(sc->mlx_parent_dmat);
208 if (sc->mlx_mem != NULL)
209 bus_release_resource(sc->mlx_dev, sc->mlx_mem_type, sc->mlx_mem_rid, sc->mlx_mem);
212 if (sc->mlx_enq2 != NULL)
213 free(sc->mlx_enq2, M_DEVBUF);
215 sx_destroy(&sc->mlx_config_lock);
216 mtx_destroy(&sc->mlx_io_lock);
225 struct mlx_softc *sc = (struct mlx_softc *)arg;
230 sc->mlx_sgbusaddr = segs->ds_addr;
234 mlx_sglist_map(struct mlx_softc *sc)
242 if (sc->mlx_sgbusaddr)
243 bus_dmamap_unload(sc->mlx_sg_dmat, sc->mlx_sg_dmamap);
244 if (sc->mlx_sgtable)
245 bus_dmamem_free(sc->mlx_sg_dmat, sc->mlx_sgtable, sc->mlx_sg_dmamap);
246 if (sc->mlx_sg_dmat)
247 bus_dma_tag_destroy(sc->mlx_sg_dmat);
248 sc->mlx_sgbusaddr = 0;
249 sc->mlx_sgtable = NULL;
250 sc->mlx_sg_dmat = NULL;
258 if (sc->mlx_enq2 == NULL) {
261 ncmd = sc->mlx_enq2->me_max_commands;
264 error = bus_dma_tag_create(sc->mlx_parent_dmat, /* parent */
273 &sc->mlx_sg_dmat);
275 device_printf(sc->mlx_dev, "can't allocate scatter/gather DMA tag\n");
288 error = bus_dmamem_alloc(sc->mlx_sg_dmat, (void **)&sc->mlx_sgtable,
289 BUS_DMA_NOWAIT, &sc->mlx_sg_dmamap);
291 device_printf(sc->mlx_dev, "can't allocate s/g table\n");
294 (void)bus_dmamap_load(sc->mlx_sg_dmat, sc->mlx_sg_dmamap, sc->mlx_sgtable,
295 segsize, mlx_dma_map_sg, sc, 0);
303 mlx_attach(struct mlx_softc *sc)
313 TAILQ_INIT(&sc->mlx_work);
314 TAILQ_INIT(&sc->mlx_freecmds);
315 bioq_init(&sc->mlx_bioq);
320 switch(sc->mlx_iftype) {
323 sc->mlx_tryqueue = mlx_v3_tryqueue;
324 sc->mlx_findcomplete = mlx_v3_findcomplete;
325 sc->mlx_intaction = mlx_v3_intaction;
326 sc->mlx_fw_handshake = mlx_v3_fw_handshake;
329 sc->mlx_tryqueue = mlx_v4_tryqueue;
330 sc->mlx_findcomplete = mlx_v4_findcomplete;
331 sc->mlx_intaction = mlx_v4_intaction;
332 sc->mlx_fw_handshake = mlx_v4_fw_handshake;
335 sc->mlx_tryqueue = mlx_v5_tryqueue;
336 sc->mlx_findcomplete = mlx_v5_findcomplete;
337 sc->mlx_intaction = mlx_v5_intaction;
338 sc->mlx_fw_handshake = mlx_v5_fw_handshake;
345 MLX_IO_LOCK(sc);
346 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
347 MLX_IO_UNLOCK(sc);
356 while ((hscode = sc->mlx_fw_handshake(sc, &hserror, &hsparam1, &hsparam2,
360 device_printf(sc->mlx_dev, "controller initialisation in progress...\n");
365 hscode = mlx_fw_message(sc, hserror, hsparam1, hsparam2);
373 device_printf(sc->mlx_dev, "initialisation complete.\n");
379 sc->mlx_irq = bus_alloc_resource_any(sc->mlx_dev, SYS_RES_IRQ, &rid,
381 if (sc->mlx_irq == NULL) {
382 device_printf(sc->mlx_dev, "can't allocate interrupt\n");
385 error = bus_setup_intr(sc->mlx_dev, sc->mlx_irq, INTR_TYPE_BIO |
386 INTR_ENTROPY | INTR_MPSAFE, NULL, mlx_intr, sc, &sc->mlx_intr);
388 device_printf(sc->mlx_dev, "can't set up interrupt\n");
395 error = bus_dma_tag_create(sc->mlx_parent_dmat, /* parent */
405 &sc->mlx_io_lock, /* lockarg */
406 &sc->mlx_buffer_dmat);
408 device_printf(sc->mlx_dev, "can't allocate buffer DMA tag\n");
416 error = mlx_sglist_map(sc);
418 device_printf(sc->mlx_dev, "can't make initial s/g list mapping\n");
425 sc->mlx_currevent = -1;
430 MLX_IO_LOCK(sc);
431 if ((sc->mlx_enq2 = mlx_enquire(sc, MLX_CMD_ENQUIRY2, sizeof(struct mlx_enquiry2), NULL)) == NULL) {
432 MLX_IO_UNLOCK(sc);
433 device_printf(sc->mlx_dev, "ENQUIRY2 failed\n");
440 fwminor = (sc->mlx_enq2->me_firmware_id >> 8) & 0xff;
441 switch(sc->mlx_iftype) {
444 if ((meo = mlx_enquire(sc, MLX_CMD_ENQUIRY_OLD, sizeof(struct mlx_enquiry_old), NULL)) == NULL) {
445 MLX_IO_UNLOCK(sc);
446 device_printf(sc->mlx_dev, "ENQUIRY_OLD failed\n");
449 sc->mlx_enq2->me_firmware_id = ('0' << 24) | (0 << 16) | (meo->me_fwminor << 8) | meo->me_fwmajor;
453 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
454 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 2.42 or later\n");
461 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
462 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 3.51 or later\n");
468 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
469 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 4.06 or later\n");
474 device_printf(sc->mlx_dev, " *** WARNING *** This firmware revision is not recommended\n");
475 device_printf(sc->mlx_dev, " *** WARNING *** Use revision 5.07 or later\n");
479 MLX_IO_UNLOCK(sc);
482 MLX_IO_UNLOCK(sc);
487 error = mlx_sglist_map(sc);
489 device_printf(sc->mlx_dev, "can't make final s/g list mapping\n");
496 sc->mlx_background = 0;
497 sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
502 sc->mlx_dev_t = make_dev(&mlx_cdevsw, 0, UID_ROOT, GID_OPERATOR,
503 S_IRUSR | S_IWUSR, "mlx%d", device_get_unit(sc->mlx_dev));
504 sc->mlx_dev_t->si_drv1 = sc;
509 callout_reset(&sc->mlx_timeout, hz, mlx_periodic, sc);
512 mlx_describe_controller(sc);
521 mlx_startup(struct mlx_softc *sc)
533 MLX_IO_LOCK(sc);
534 mes = mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(*mes) * MLX_MAXDRIVES, NULL);
535 MLX_IO_UNLOCK(sc);
537 device_printf(sc->mlx_dev, "error fetching drive status\n");
542 MLX_CONFIG_LOCK(sc);
543 for (i = 0, dr = &sc->mlx_sysdrive[0];
554 if (sc->mlx_geom == MLX_GEOM_128_32) {
563 dr->ms_disk = device_add_child(sc->mlx_dev, /*"mlxd"*/NULL, -1);
565 device_printf(sc->mlx_dev, "device_add_child failed\n");
570 if ((error = bus_generic_attach(sc->mlx_dev)) != 0)
571 device_printf(sc->mlx_dev, "bus_generic_attach returned %d", error);
574 MLX_IO_LOCK(sc);
575 sc->mlx_state &= ~MLX_STATE_SHUTDOWN;
578 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
579 MLX_IO_UNLOCK(sc);
580 MLX_CONFIG_UNLOCK(sc);
589 struct mlx_softc *sc = device_get_softc(dev);
596 MLX_CONFIG_LOCK(sc);
597 if (sc->mlx_state & MLX_STATE_OPEN)
601 if (sc->mlx_sysdrive[i].ms_disk != 0) {
602 mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk);
604 device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't detach\n");
611 MLX_CONFIG_UNLOCK(sc);
613 mlx_free(sc);
617 MLX_CONFIG_UNLOCK(sc);
634 struct mlx_softc *sc = device_get_softc(dev);
637 MLX_CONFIG_LOCK(sc);
638 error = mlx_shutdown_locked(sc);
639 MLX_CONFIG_UNLOCK(sc);
644 mlx_shutdown_locked(struct mlx_softc *sc)
650 MLX_CONFIG_ASSERT_LOCKED(sc);
652 MLX_IO_LOCK(sc);
653 sc->mlx_state |= MLX_STATE_SHUTDOWN;
654 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
657 device_printf(sc->mlx_dev, "flushing cache...");
658 if (mlx_flush(sc)) {
663 MLX_IO_UNLOCK(sc);
667 if (sc->mlx_sysdrive[i].ms_disk != 0) {
668 if ((error = device_delete_child(sc->mlx_dev, sc->mlx_sysdrive[i].ms_disk)) != 0)
670 sc->mlx_sysdrive[i].ms_disk = 0;
683 struct mlx_softc *sc = device_get_softc(dev);
687 MLX_IO_LOCK(sc);
688 sc->mlx_state |= MLX_STATE_SUSPEND;
691 device_printf(sc->mlx_dev, "flushing cache...");
692 printf("%s\n", mlx_flush(sc) ? "failed" : "done");
694 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
695 MLX_IO_UNLOCK(sc);
706 struct mlx_softc *sc = device_get_softc(dev);
710 MLX_IO_LOCK(sc);
711 sc->mlx_state &= ~MLX_STATE_SUSPEND;
712 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
713 MLX_IO_UNLOCK(sc);
725 struct mlx_softc *sc = (struct mlx_softc *)arg;
730 MLX_IO_LOCK(sc);
731 mlx_done(sc, 1);
732 MLX_IO_UNLOCK(sc);
740 mlx_submit_buf(struct mlx_softc *sc, struct bio *bp)
745 MLX_IO_ASSERT_LOCKED(sc);
746 bioq_insert_tail(&sc->mlx_bioq, bp);
747 sc->mlx_waitbufs++;
748 mlx_startio(sc);
758 struct mlx_softc *sc = dev->si_drv1;
760 MLX_CONFIG_LOCK(sc);
761 MLX_IO_LOCK(sc);
762 sc->mlx_state |= MLX_STATE_OPEN;
763 MLX_IO_UNLOCK(sc);
764 MLX_CONFIG_UNLOCK(sc);
774 struct mlx_softc *sc = dev->si_drv1;
776 MLX_CONFIG_LOCK(sc);
777 MLX_IO_LOCK(sc);
778 sc->mlx_state &= ~MLX_STATE_OPEN;
779 MLX_IO_UNLOCK(sc);
780 MLX_CONFIG_UNLOCK(sc);
790 struct mlx_softc *sc = dev->si_drv1;
807 MLX_CONFIG_LOCK(sc);
810 if (sc->mlx_sysdrive[i].ms_disk != 0) {
813 *arg = device_get_unit(sc->mlx_sysdrive[i].ms_disk);
814 MLX_CONFIG_UNLOCK(sc);
818 if (*arg == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
822 MLX_CONFIG_UNLOCK(sc);
830 mlx_startup(sc);
839 MLX_CONFIG_LOCK(sc);
840 if (((dr = mlx_findunit(sc, *arg)) == NULL) ||
842 MLX_CONFIG_UNLOCK(sc);
854 MLX_IO_LOCK(sc);
855 if (mlx_flush(sc)) {
856 MLX_IO_UNLOCK(sc);
860 MLX_IO_UNLOCK(sc);
863 if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0)
868 MLX_CONFIG_UNLOCK(sc);
885 if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS))
895 MLX_IO_LOCK(sc);
896 if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) {
898 sc->mlx_pause.mp_which = 0;
901 mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1);
904 if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0)) {
905 MLX_IO_UNLOCK(sc);
910 sc->mlx_pause.mp_which = mp->mp_which;
911 sc->mlx_pause.mp_when = time_second + mp->mp_when;
912 sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong;
914 MLX_IO_UNLOCK(sc);
921 return(mlx_user_command(sc, (struct mlx_usercommand *)addr));
927 MLX_IO_LOCK(sc);
928 if (sc->mlx_background != 0) {
929 MLX_IO_UNLOCK(sc);
933 rb->rr_status = mlx_rebuild(sc, rb->rr_channel, rb->rr_target);
958 sc->mlx_background = MLX_BACKGROUND_REBUILD;
959 MLX_IO_UNLOCK(sc);
966 MLX_IO_LOCK(sc);
967 *rs = sc->mlx_rebuildstat;
968 MLX_IO_UNLOCK(sc);
977 MLX_CONFIG_LOCK(sc);
981 if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) &&
982 (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) {
984 *arg = mlxd->mlxd_drive - sc->mlx_sysdrive;
986 MLX_CONFIG_UNLOCK(sc);
998 mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd,
1009 MLX_IO_LOCK(sc);
1011 MLX_IO_UNLOCK(sc);
1018 MLX_IO_LOCK(sc);
1019 if (sc->mlx_background != 0) {
1020 MLX_IO_UNLOCK(sc);
1024 result = mlx_check(sc, drive - &sc->mlx_sysdrive[0]);
1046 sc->mlx_background = MLX_BACKGROUND_CHECK;
1047 MLX_IO_UNLOCK(sc);
1068 struct mlx_softc *sc = (struct mlx_softc *)data;
1071 MLX_IO_ASSERT_LOCKED(sc);
1076 if ((sc->mlx_pause.mp_which != 0) &&
1077 (sc->mlx_pause.mp_when > 0) &&
1078 (time_second >= sc->mlx_pause.mp_when)){
1080 mlx_pause_action(sc); /* pause is running */
1081 sc->mlx_pause.mp_when = 0;
1087 } else if ((sc->mlx_pause.mp_which != 0) &&
1088 (sc->mlx_pause.mp_when == 0)) {
1091 if (time_second >= sc->mlx_pause.mp_howlong) {
1092 mlx_pause_action(sc);
1093 sc->mlx_pause.mp_which = 0; /* pause is complete */
1102 } else if (time_second > (sc->mlx_lastpoll + 10)) {
1103 sc->mlx_lastpoll = time_second;
1110 mlx_enquire(sc, (sc->mlx_iftype == MLX_IFTYPE_2) ? MLX_CMD_ENQUIRY_OLD : MLX_CMD_ENQUIRY,
1120 mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES,
1126 /* XXX should check sc->mlx_background if this is only valid while in progress */
1127 mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
1130 mlx_done(sc, 1);
1133 callout_reset(&sc->mlx_timeout, hz, mlx_periodic, sc);
1142 struct mlx_softc *sc = mc->mc_sc;
1145 MLX_IO_ASSERT_LOCKED(sc);
1149 device_printf(sc->mlx_dev, "periodic enquiry failed - %s\n", mlx_diagnose_command(mc));
1201 if (sc->mlx_currevent == -1) {
1203 sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num;
1204 } else if ((me->me_event_log_seq_num != sc->mlx_lastevent) && !(sc->mlx_flags & MLX_EVENTLOG_BUSY)) {
1206 sc->mlx_currevent = me->me_event_log_seq_num;
1207 debug(1, "event log pointer was %d, now %d\n", sc->mlx_lastevent, sc->mlx_currevent);
1210 sc->mlx_flags |= MLX_EVENTLOG_BUSY;
1213 mlx_periodic_eventlog_poll(sc);
1223 for (i = 0, dr = &sc->mlx_sysdrive[0];
1247 device_printf(sc->mlx_dev, "%s: unknown command 0x%x", __func__, mc->mc_mailbox[0]);
1280 * Instigate a poll for one event log message on (sc).
1284 mlx_periodic_eventlog_poll(struct mlx_softc *sc)
1291 MLX_IO_ASSERT_LOCKED(sc);
1295 if ((mc = mlx_alloccmd(sc)) == NULL)
1310 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1345 struct mlx_softc *sc = mc->mc_sc;
1350 MLX_IO_ASSERT_LOCKED(sc);
1352 sc->mlx_lastevent++; /* next message... */
1370 device_printf(sc->mlx_dev, "physical drive %d:%d killed %s\n",
1375 device_printf(sc->mlx_dev, "physical drive %d:%d reset\n",
1384 device_printf(sc->mlx_dev, "physical drive %d:%d error log: sense = %d asc = %x asq = %x\n",
1386 device_printf(sc->mlx_dev, " info %4D csi %4D\n", el->el_information, ":", el->el_csi, ":");
1391 device_printf(sc->mlx_dev, "unknown log message type 0x%x\n", el->el_type);
1395 device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc));
1397 sc->mlx_lastevent = sc->mlx_currevent;
1405 if (sc->mlx_lastevent != sc->mlx_currevent) {
1406 mlx_periodic_eventlog_poll(sc);
1409 sc->mlx_flags &= ~MLX_EVENTLOG_BUSY;
1419 struct mlx_softc *sc = mc->mc_sc;
1422 MLX_IO_ASSERT_LOCKED(sc);
1425 sc->mlx_rebuildstat = *mr;
1428 if (sc->mlx_background == 0) {
1429 sc->mlx_background = MLX_BACKGROUND_SPONTANEOUS;
1430 device_printf(sc->mlx_dev, "background check/rebuild operation started\n");
1435 switch(sc->mlx_background) {
1437 device_printf(sc->mlx_dev, "consistency check completed\n"); /* XXX print drive? */
1440 device_printf(sc->mlx_dev, "drive rebuild completed\n"); /* XXX print channel/target? */
1445 if (sc->mlx_rebuildstat.rs_code != MLX_REBUILDSTAT_IDLE) {
1446 device_printf(sc->mlx_dev, "background check/rebuild operation completed\n");
1449 sc->mlx_background = 0;
1450 sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
1464 * It's time to perform a channel pause action for (sc), either start or stop
1468 mlx_pause_action(struct mlx_softc *sc)
1473 MLX_IO_ASSERT_LOCKED(sc);
1476 if (sc->mlx_pause.mp_when == 0) {
1488 failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30;
1491 sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5;
1496 for (i = 0; i < sc->mlx_enq2->me_actual_channels; i++) {
1497 if ((1 << i) & sc->mlx_pause.mp_which) {
1500 if ((mc = mlx_alloccmd(sc)) == NULL)
1510 mc->mc_private = sc; /* XXX not needed */
1517 device_printf(sc->mlx_dev, "%s failed for channel %d\n",
1528 struct mlx_softc *sc = mc->mc_sc;
1532 MLX_IO_ASSERT_LOCKED(sc);
1534 device_printf(sc->mlx_dev, "%s command failed - %s\n",
1537 device_printf(sc->mlx_dev, "channel %d pausing for %ld seconds\n",
1538 channel, (long)(sc->mlx_pause.mp_howlong - time_second));
1540 device_printf(sc->mlx_dev, "channel %d resuming\n", channel);
1554 struct mlx_softc *sc;
1564 sc = mc->mc_sc;
1573 if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) :
1579 device_printf(sc->mlx_dev, "ENQUIRY failed - %s\n",
1594 mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, void (* complete)(struct mlx_command *mc))
1601 MLX_IO_ASSERT_LOCKED(sc);
1606 if ((mc = mlx_alloccmd(sc)) == NULL)
1626 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1649 mlx_flush(struct mlx_softc *sc)
1655 MLX_IO_ASSERT_LOCKED(sc);
1659 if ((mc = mlx_alloccmd(sc)) == NULL)
1674 device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc));
1692 mlx_check(struct mlx_softc *sc, int drive)
1698 MLX_IO_ASSERT_LOCKED(sc);
1702 if ((mc = mlx_alloccmd(sc)) == NULL)
1717 device_printf(sc->mlx_dev, "CHECK ASYNC failed - %s\n", mlx_diagnose_command(mc));
1719 device_printf(sc->mlx_sysdrive[drive].ms_disk, "consistency check started");
1736 mlx_rebuild(struct mlx_softc *sc, int channel, int target)
1742 MLX_IO_ASSERT_LOCKED(sc);
1746 if ((mc = mlx_alloccmd(sc)) == NULL)
1761 device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc));
1763 device_printf(sc->mlx_dev, "drive rebuild started for %d:%d\n", channel, target);
1781 struct mlx_softc *sc = mc->mc_sc;
1785 MLX_IO_ASSERT_LOCKED(sc);
1795 mtx_sleep(mc->mc_private, &sc->mlx_io_lock, PRIBIO | PCATCH, "mlxwcmd", hz);
1799 device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1816 struct mlx_softc *sc = mc->mc_sc;
1820 MLX_IO_ASSERT_LOCKED(sc);
1834 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
1837 device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1846 struct mlx_softc *sc;
1855 sc = mc->mc_sc;
1868 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1871 if ((bp->bio_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1872 device_printf(sc->mlx_dev,
1875 (u_long)sc->mlx_sysdrive[driveno].ms_size);
1881 if (sc->mlx_iftype == MLX_IFTYPE_2) {
1906 sc->mlx_state &= ~MLX_STATE_QFROZEN;
1914 mlx_startio(struct mlx_softc *sc)
1920 MLX_IO_ASSERT_LOCKED(sc);
1924 if (sc->mlx_state & MLX_STATE_QFROZEN)
1928 if ((bp = bioq_first(&sc->mlx_bioq)) == NULL)
1931 if ((mc = mlx_alloccmd(sc)) == NULL)
1939 bioq_remove(&sc->mlx_bioq, bp);
1940 sc->mlx_waitbufs--;
1949 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1952 sc->mlx_state |= MLX_STATE_QFROZEN;
1964 struct mlx_softc *sc = mc->mc_sc;
1968 MLX_IO_ASSERT_LOCKED(sc);
1981 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1983 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n",
1985 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " ");
2047 mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu)
2060 MLX_IO_LOCK(sc);
2061 if ((mc = mlx_alloccmd(sc)) == NULL) {
2062 MLX_IO_UNLOCK(sc);
2077 MLX_IO_UNLOCK(sc);
2080 MLX_IO_LOCK(sc);
2083 MLX_IO_LOCK(sc);
2106 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
2114 MLX_IO_UNLOCK(sc);
2116 MLX_IO_LOCK(sc);
2121 MLX_IO_UNLOCK(sc);
2142 struct mlx_softc *sc = mc->mc_sc;
2147 MLX_IO_ASSERT_LOCKED(sc);
2152 if (sc->mlx_enq2 != NULL) {
2153 limit = sc->mlx_enq2->me_max_commands;
2157 if (sc->mlx_busycmds >= ((mc->mc_flags & MLX_CMD_PRIORITY) ? limit : limit - 4))
2167 if (sc->mlx_busycmd[slot] == NULL)
2171 sc->mlx_busycmd[slot] = mc;
2172 sc->mlx_busycmds++;
2191 struct mlx_softc *sc = mc->mc_sc;
2198 if (sc->mlx_enq2 && (nsegments > sc->mlx_enq2->me_max_sg))
2200 sc->mlx_enq2->me_max_sg);
2203 sg = sc->mlx_sgtable + (mc->mc_slot * MLX_NSEG);
2207 mc->mc_sgphys = sc->mlx_sgbusaddr +
2219 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap,
2222 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap,
2229 struct mlx_softc *sc = mc->mc_sc;
2237 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTREAD);
2239 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE);
2241 bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap);
2253 struct mlx_softc *sc = mc->mc_sc;
2269 if (sc->mlx_tryqueue(sc, mc)) {
2271 TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link);
2274 mlx_done(sc, 0);
2281 sc->mlx_busycmd[mc->mc_slot] = NULL;
2282 device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n");
2284 mlx_complete(sc);
2289 * Poll the controller (sc) for completed commands.
2296 mlx_done(struct mlx_softc *sc, int startio)
2304 MLX_IO_ASSERT_LOCKED(sc);
2311 if (sc->mlx_findcomplete(sc, &slot, &status)) {
2313 mc = sc->mlx_busycmd[slot]; /* find command */
2319 sc->mlx_busycmd[slot] = NULL;
2320 sc->mlx_busycmds--;
2322 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot);
2325 device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot);
2334 mlx_startio(sc);
2337 mlx_complete(sc);
2343 * Perform post-completion processing for commands on (sc).
2346 mlx_complete(struct mlx_softc *sc)
2351 MLX_IO_ASSERT_LOCKED(sc);
2354 mc = TAILQ_FIRST(&sc->mlx_work);
2368 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2377 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2411 mlx_alloccmd(struct mlx_softc *sc)
2418 MLX_IO_ASSERT_LOCKED(sc);
2419 if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL)
2420 TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
2426 mc->mc_sc = sc;
2427 error = bus_dmamap_create(sc->mlx_buffer_dmat, 0, &mc->mc_dmamap);
2459 struct mlx_softc *sc = mc->mc_sc;
2462 bus_dmamap_destroy(sc->mlx_buffer_dmat, mc->mc_dmamap);
2478 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2483 MLX_IO_ASSERT_LOCKED(sc);
2486 if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) {
2489 MLX_V3_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2492 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_FULL);
2503 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2507 MLX_IO_ASSERT_LOCKED(sc);
2510 if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) {
2511 *slot = MLX_V3_GET_STATUS_IDENT(sc); /* get command identifier */
2512 *status = MLX_V3_GET_STATUS(sc); /* get status */
2515 MLX_V3_PUT_ODBR(sc, MLX_V3_ODB_SAVAIL);
2516 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2526 mlx_v3_intaction(struct mlx_softc *sc, int action)
2529 MLX_IO_ASSERT_LOCKED(sc);
2533 MLX_V3_PUT_IER(sc, 0);
2534 sc->mlx_state &= ~MLX_STATE_INTEN;
2537 MLX_V3_PUT_IER(sc, 1);
2538 sc->mlx_state |= MLX_STATE_INTEN;
2549 mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
2558 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2563 if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_INIT_BUSY))
2567 fwerror = MLX_V3_GET_FWERROR(sc);
2573 *param1 = MLX_V3_GET_FWERROR_PARAM1(sc);
2574 *param2 = MLX_V3_GET_FWERROR_PARAM2(sc);
2577 MLX_V3_PUT_FWERROR(sc, 0);
2593 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2598 MLX_IO_ASSERT_LOCKED(sc);
2601 if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) {
2604 MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2607 bus_barrier(sc->mlx_mem, MLX_V4_MAILBOX, MLX_V4_MAILBOX_LENGTH,
2611 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_HWMBOX_CMD);
2622 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2626 MLX_IO_ASSERT_LOCKED(sc);
2629 if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) {
2630 *slot = MLX_V4_GET_STATUS_IDENT(sc); /* get command identifier */
2631 *status = MLX_V4_GET_STATUS(sc); /* get status */
2634 MLX_V4_PUT_ODBR(sc, MLX_V4_ODB_HWMBOX_ACK);
2635 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2645 mlx_v4_intaction(struct mlx_softc *sc, int action)
2648 MLX_IO_ASSERT_LOCKED(sc);
2652 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK | MLX_V4_IER_DISINT);
2653 sc->mlx_state &= ~MLX_STATE_INTEN;
2656 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK & ~MLX_V4_IER_DISINT);
2657 sc->mlx_state |= MLX_STATE_INTEN;
2668 mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
2677 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2682 if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_INIT_BUSY))
2686 fwerror = MLX_V4_GET_FWERROR(sc);
2692 *param1 = MLX_V4_GET_FWERROR_PARAM1(sc);
2693 *param2 = MLX_V4_GET_FWERROR_PARAM2(sc);
2696 MLX_V4_PUT_FWERROR(sc, 0);
2712 mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2717 MLX_IO_ASSERT_LOCKED(sc);
2720 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) {
2723 MLX_V5_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2726 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_HWMBOX_CMD);
2737 mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2741 MLX_IO_ASSERT_LOCKED(sc);
2744 if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) {
2745 *slot = MLX_V5_GET_STATUS_IDENT(sc); /* get command identifier */
2746 *status = MLX_V5_GET_STATUS(sc); /* get status */
2749 MLX_V5_PUT_ODBR(sc, MLX_V5_ODB_HWMBOX_ACK);
2750 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2760 mlx_v5_intaction(struct mlx_softc *sc, int action)
2763 MLX_IO_ASSERT_LOCKED(sc);
2767 MLX_V5_PUT_IER(sc, 0xff & MLX_V5_IER_DISINT);
2768 sc->mlx_state &= ~MLX_STATE_INTEN;
2771 MLX_V5_PUT_IER(sc, 0xff & ~MLX_V5_IER_DISINT);
2772 sc->mlx_state |= MLX_STATE_INTEN;
2783 mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
2792 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2797 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_INIT_DONE)
2801 fwerror = MLX_V5_GET_FWERROR(sc);
2807 *param1 = MLX_V5_GET_FWERROR_PARAM1(sc);
2808 *param2 = MLX_V5_GET_FWERROR_PARAM2(sc);
2811 MLX_V5_PUT_FWERROR(sc, 0xff);
2908 * Print a string describing the controller (sc)
2929 mlx_describe_controller(struct mlx_softc *sc)
2936 if ((sc->mlx_enq2->me_hardware_id & 0xff) == mlx_controller_names[i].hwid) {
2942 sprintf(buf, " model 0x%x", sc->mlx_enq2->me_hardware_id & 0xff);
2945 device_printf(sc->mlx_dev, "DAC%s, %d channel%s, firmware %d.%02d-%c-%02d, %dMB RAM\n",
2947 sc->mlx_enq2->me_actual_channels,
2948 sc->mlx_enq2->me_actual_channels > 1 ? "s" : "",
2949 sc->mlx_enq2->me_firmware_id & 0xff,
2950 (sc->mlx_enq2->me_firmware_id >> 8) & 0xff,
2951 (sc->mlx_enq2->me_firmware_id >> 24) & 0xff,
2952 (sc->mlx_enq2->me_firmware_id >> 16) & 0xff,
2953 sc->mlx_enq2->me_mem_size / (1024 * 1024));
2956 device_printf(sc->mlx_dev, " Hardware ID 0x%08x\n", sc->mlx_enq2->me_hardware_id);
2957 device_printf(sc->mlx_dev, " Firmware ID 0x%08x\n", sc->mlx_enq2->me_firmware_id);
2958 device_printf(sc->mlx_dev, " Configured/Actual channels %d/%d\n", sc->mlx_enq2->me_configured_channels,
2959 sc->mlx_enq2->me_actual_channels);
2960 device_printf(sc->mlx_dev, " Max Targets %d\n", sc->mlx_enq2->me_max_targets);
2961 device_printf(sc->mlx_dev, " Max Tags %d\n", sc->mlx_enq2->me_max_tags);
2962 device_printf(sc->mlx_dev, " Max System Drives %d\n", sc->mlx_enq2->me_max_sys_drives);
2963 device_printf(sc->mlx_dev, " Max Arms %d\n", sc->mlx_enq2->me_max_arms);
2964 device_printf(sc->mlx_dev, " Max Spans %d\n", sc->mlx_enq2->me_max_spans);
2965 device_printf(sc->mlx_dev, " DRAM/cache/flash/NVRAM size %d/%d/%d/%d\n", sc->mlx_enq2->me_mem_size,
2966 sc->mlx_enq2->me_cache_size, sc->mlx_enq2->me_flash_size, sc->mlx_enq2->me_nvram_size);
2967 device_printf(sc->mlx_dev, " DRAM type %d\n", sc->mlx_enq2->me_mem_type);
2968 device_printf(sc->mlx_dev, " Clock Speed %dns\n", sc->mlx_enq2->me_clock_speed);
2969 device_printf(sc->mlx_dev, " Hardware Speed %dns\n", sc->mlx_enq2->me_hardware_speed);
2970 device_printf(sc->mlx_dev, " Max Commands %d\n", sc->mlx_enq2->me_max_commands);
2971 device_printf(sc->mlx_dev, " Max SG Entries %d\n", sc->mlx_enq2->me_max_sg);
2972 device_printf(sc->mlx_dev, " Max DP %d\n", sc->mlx_enq2->me_max_dp);
2973 device_printf(sc->mlx_dev, " Max IOD %d\n", sc->mlx_enq2->me_max_iod);
2974 device_printf(sc->mlx_dev, " Max Comb %d\n", sc->mlx_enq2->me_max_comb);
2975 device_printf(sc->mlx_dev, " Latency %ds\n", sc->mlx_enq2->me_latency);
2976 device_printf(sc->mlx_dev, " SCSI Timeout %ds\n", sc->mlx_enq2->me_scsi_timeout);
2977 device_printf(sc->mlx_dev, " Min Free Lines %d\n", sc->mlx_enq2->me_min_freelines);
2978 device_printf(sc->mlx_dev, " Rate Constant %d\n", sc->mlx_enq2->me_rate_const);
2979 device_printf(sc->mlx_dev, " MAXBLK %d\n", sc->mlx_enq2->me_maxblk);
2980 device_printf(sc->mlx_dev, " Blocking Factor %d sectors\n", sc->mlx_enq2->me_blocking_factor);
2981 device_printf(sc->mlx_dev, " Cache Line Size %d blocks\n", sc->mlx_enq2->me_cacheline);
2982 device_printf(sc->mlx_dev, " SCSI Capability %s%dMHz, %d bit\n",
2983 sc->mlx_enq2->me_scsi_cap & (1<<4) ? "differential " : "",
2984 (1 << ((sc->mlx_enq2->me_scsi_cap >> 2) & 3)) * 10,
2985 8 << (sc->mlx_enq2->me_scsi_cap & 0x3));
2986 device_printf(sc->mlx_dev, " Firmware Build Number %d\n", sc->mlx_enq2->me_firmware_build);
2987 device_printf(sc->mlx_dev, " Fault Management Type %d\n", sc->mlx_enq2->me_fault_mgmt_type);
2988 device_printf(sc->mlx_dev, " Features %b\n", sc->mlx_enq2->me_firmware_features,
3003 mlx_fw_message(struct mlx_softc *sc, int error, int param1, int param2)
3007 device_printf(sc->mlx_dev, "physical drive %d:%d not responding\n", param2, param1);
3011 if (!(sc->mlx_flags & MLX_SPINUP_REPORTED)) {
3012 device_printf(sc->mlx_dev, "spinning up drives...\n");
3013 sc->mlx_flags |= MLX_SPINUP_REPORTED;
3017 device_printf(sc->mlx_dev, "configuration checksum error\n");
3020 device_printf(sc->mlx_dev, "mirror race recovery failed\n");
3023 device_printf(sc->mlx_dev, "mirror race recovery in progress\n");
3026 device_printf(sc->mlx_dev, "physical drive %d:%d COD mismatch\n", param2, param1);
3029 device_printf(sc->mlx_dev, "logical drive installation aborted\n");
3032 device_printf(sc->mlx_dev, "mirror race on a critical system drive\n");
3035 device_printf(sc->mlx_dev, "new controller configuration found\n");
3038 device_printf(sc->mlx_dev, "FATAL MEMORY PARITY ERROR\n");
3041 device_printf(sc->mlx_dev, "unknown firmware initialisation error %02x:%02x:%02x\n", error, param1, param2);
3057 mlx_findunit(struct mlx_softc *sc, int unit)
3062 MLX_CONFIG_ASSERT_LOCKED(sc);
3065 if (sc->mlx_sysdrive[i].ms_disk != 0) {
3067 if (unit == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
3068 return(&sc->mlx_sysdrive[i]);