Lines Matching defs: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, DEVICE_UNIT_ANY);
565 device_printf(sc->mlx_dev, "device_add_child failed\n");
570 bus_attach_children(sc->mlx_dev);
573 MLX_IO_LOCK(sc);
574 sc->mlx_state &= ~MLX_STATE_SHUTDOWN;
577 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
578 MLX_IO_UNLOCK(sc);
579 MLX_CONFIG_UNLOCK(sc);
588 struct mlx_softc *sc = device_get_softc(dev);
595 MLX_CONFIG_LOCK(sc);
596 if (sc->mlx_state & MLX_STATE_OPEN)
600 if (sc->mlx_sysdrive[i].ms_disk != 0) {
601 mlxd = device_get_softc(sc->mlx_sysdrive[i].ms_disk);
603 device_printf(sc->mlx_sysdrive[i].ms_disk, "still open, can't detach\n");
610 MLX_CONFIG_UNLOCK(sc);
612 mlx_free(sc);
616 MLX_CONFIG_UNLOCK(sc);
633 struct mlx_softc *sc = device_get_softc(dev);
636 MLX_CONFIG_LOCK(sc);
637 error = mlx_shutdown_locked(sc);
638 MLX_CONFIG_UNLOCK(sc);
643 mlx_shutdown_locked(struct mlx_softc *sc)
649 MLX_CONFIG_ASSERT_LOCKED(sc);
651 MLX_IO_LOCK(sc);
652 sc->mlx_state |= MLX_STATE_SHUTDOWN;
653 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
656 device_printf(sc->mlx_dev, "flushing cache...");
657 if (mlx_flush(sc)) {
662 MLX_IO_UNLOCK(sc);
665 error = bus_generic_detach(sc->mlx_dev);
676 struct mlx_softc *sc = device_get_softc(dev);
680 MLX_IO_LOCK(sc);
681 sc->mlx_state |= MLX_STATE_SUSPEND;
684 device_printf(sc->mlx_dev, "flushing cache...");
685 printf("%s\n", mlx_flush(sc) ? "failed" : "done");
687 sc->mlx_intaction(sc, MLX_INTACTION_DISABLE);
688 MLX_IO_UNLOCK(sc);
699 struct mlx_softc *sc = device_get_softc(dev);
703 MLX_IO_LOCK(sc);
704 sc->mlx_state &= ~MLX_STATE_SUSPEND;
705 sc->mlx_intaction(sc, MLX_INTACTION_ENABLE);
706 MLX_IO_UNLOCK(sc);
718 struct mlx_softc *sc = (struct mlx_softc *)arg;
723 MLX_IO_LOCK(sc);
724 mlx_done(sc, 1);
725 MLX_IO_UNLOCK(sc);
733 mlx_submit_buf(struct mlx_softc *sc, struct bio *bp)
738 MLX_IO_ASSERT_LOCKED(sc);
739 bioq_insert_tail(&sc->mlx_bioq, bp);
740 sc->mlx_waitbufs++;
741 mlx_startio(sc);
751 struct mlx_softc *sc = dev->si_drv1;
753 MLX_CONFIG_LOCK(sc);
754 MLX_IO_LOCK(sc);
755 sc->mlx_state |= MLX_STATE_OPEN;
756 MLX_IO_UNLOCK(sc);
757 MLX_CONFIG_UNLOCK(sc);
767 struct mlx_softc *sc = dev->si_drv1;
769 MLX_CONFIG_LOCK(sc);
770 MLX_IO_LOCK(sc);
771 sc->mlx_state &= ~MLX_STATE_OPEN;
772 MLX_IO_UNLOCK(sc);
773 MLX_CONFIG_UNLOCK(sc);
783 struct mlx_softc *sc = dev->si_drv1;
800 MLX_CONFIG_LOCK(sc);
803 if (sc->mlx_sysdrive[i].ms_disk != 0) {
806 *arg = device_get_unit(sc->mlx_sysdrive[i].ms_disk);
807 MLX_CONFIG_UNLOCK(sc);
811 if (*arg == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
815 MLX_CONFIG_UNLOCK(sc);
823 mlx_startup(sc);
832 MLX_CONFIG_LOCK(sc);
833 if (((dr = mlx_findunit(sc, *arg)) == NULL) ||
835 MLX_CONFIG_UNLOCK(sc);
847 MLX_IO_LOCK(sc);
848 if (mlx_flush(sc)) {
849 MLX_IO_UNLOCK(sc);
853 MLX_IO_UNLOCK(sc);
856 if ((error = device_delete_child(sc->mlx_dev, dr->ms_disk)) != 0)
861 MLX_CONFIG_UNLOCK(sc);
878 if (!(sc->mlx_feature & MLX_FEAT_PAUSEWORKS))
888 MLX_IO_LOCK(sc);
889 if ((mp->mp_which == MLX_PAUSE_CANCEL) && (sc->mlx_pause.mp_when != 0)) {
891 sc->mlx_pause.mp_which = 0;
894 mp->mp_which &= ((1 << sc->mlx_enq2->me_actual_channels) -1);
897 if ((sc->mlx_pause.mp_which != 0) && (sc->mlx_pause.mp_when == 0)) {
898 MLX_IO_UNLOCK(sc);
903 sc->mlx_pause.mp_which = mp->mp_which;
904 sc->mlx_pause.mp_when = time_second + mp->mp_when;
905 sc->mlx_pause.mp_howlong = sc->mlx_pause.mp_when + mp->mp_howlong;
907 MLX_IO_UNLOCK(sc);
914 return(mlx_user_command(sc, (struct mlx_usercommand *)addr));
920 MLX_IO_LOCK(sc);
921 if (sc->mlx_background != 0) {
922 MLX_IO_UNLOCK(sc);
926 rb->rr_status = mlx_rebuild(sc, rb->rr_channel, rb->rr_target);
951 sc->mlx_background = MLX_BACKGROUND_REBUILD;
952 MLX_IO_UNLOCK(sc);
959 MLX_IO_LOCK(sc);
960 *rs = sc->mlx_rebuildstat;
961 MLX_IO_UNLOCK(sc);
970 MLX_CONFIG_LOCK(sc);
974 if ((mlxd != NULL) && (mlxd->mlxd_drive >= sc->mlx_sysdrive) &&
975 (mlxd->mlxd_drive < (sc->mlx_sysdrive + MLX_MAXDRIVES))) {
977 *arg = mlxd->mlxd_drive - sc->mlx_sysdrive;
979 MLX_CONFIG_UNLOCK(sc);
991 mlx_submit_ioctl(struct mlx_softc *sc, struct mlx_sysdrive *drive, u_long cmd,
1002 MLX_IO_LOCK(sc);
1004 MLX_IO_UNLOCK(sc);
1011 MLX_IO_LOCK(sc);
1012 if (sc->mlx_background != 0) {
1013 MLX_IO_UNLOCK(sc);
1017 result = mlx_check(sc, drive - &sc->mlx_sysdrive[0]);
1039 sc->mlx_background = MLX_BACKGROUND_CHECK;
1040 MLX_IO_UNLOCK(sc);
1061 struct mlx_softc *sc = (struct mlx_softc *)data;
1064 MLX_IO_ASSERT_LOCKED(sc);
1069 if ((sc->mlx_pause.mp_which != 0) &&
1070 (sc->mlx_pause.mp_when > 0) &&
1071 (time_second >= sc->mlx_pause.mp_when)){
1073 mlx_pause_action(sc); /* pause is running */
1074 sc->mlx_pause.mp_when = 0;
1080 } else if ((sc->mlx_pause.mp_which != 0) &&
1081 (sc->mlx_pause.mp_when == 0)) {
1084 if (time_second >= sc->mlx_pause.mp_howlong) {
1085 mlx_pause_action(sc);
1086 sc->mlx_pause.mp_which = 0; /* pause is complete */
1095 } else if (time_second > (sc->mlx_lastpoll + 10)) {
1096 sc->mlx_lastpoll = time_second;
1103 mlx_enquire(sc, (sc->mlx_iftype == MLX_IFTYPE_2) ? MLX_CMD_ENQUIRY_OLD : MLX_CMD_ENQUIRY,
1113 mlx_enquire(sc, MLX_CMD_ENQSYSDRIVE, sizeof(struct mlx_enq_sys_drive) * MLX_MAXDRIVES,
1119 /* XXX should check sc->mlx_background if this is only valid while in progress */
1120 mlx_enquire(sc, MLX_CMD_REBUILDSTAT, sizeof(struct mlx_rebuild_stat), mlx_periodic_rebuild);
1123 mlx_done(sc, 1);
1126 callout_reset(&sc->mlx_timeout, hz, mlx_periodic, sc);
1135 struct mlx_softc *sc = mc->mc_sc;
1138 MLX_IO_ASSERT_LOCKED(sc);
1142 device_printf(sc->mlx_dev, "periodic enquiry failed - %s\n", mlx_diagnose_command(mc));
1194 if (sc->mlx_currevent == -1) {
1196 sc->mlx_currevent = sc->mlx_lastevent = me->me_event_log_seq_num;
1197 } else if ((me->me_event_log_seq_num != sc->mlx_lastevent) && !(sc->mlx_flags & MLX_EVENTLOG_BUSY)) {
1199 sc->mlx_currevent = me->me_event_log_seq_num;
1200 debug(1, "event log pointer was %d, now %d\n", sc->mlx_lastevent, sc->mlx_currevent);
1203 sc->mlx_flags |= MLX_EVENTLOG_BUSY;
1206 mlx_periodic_eventlog_poll(sc);
1216 for (i = 0, dr = &sc->mlx_sysdrive[0];
1240 device_printf(sc->mlx_dev, "%s: unknown command 0x%x", __func__, mc->mc_mailbox[0]);
1273 * Instigate a poll for one event log message on (sc).
1277 mlx_periodic_eventlog_poll(struct mlx_softc *sc)
1284 MLX_IO_ASSERT_LOCKED(sc);
1288 if ((mc = mlx_alloccmd(sc)) == NULL)
1303 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1338 struct mlx_softc *sc = mc->mc_sc;
1343 MLX_IO_ASSERT_LOCKED(sc);
1345 sc->mlx_lastevent++; /* next message... */
1363 device_printf(sc->mlx_dev, "physical drive %d:%d killed %s\n",
1368 device_printf(sc->mlx_dev, "physical drive %d:%d reset\n",
1377 device_printf(sc->mlx_dev, "physical drive %d:%d error log: sense = %d asc = %x asq = %x\n",
1379 device_printf(sc->mlx_dev, " info %4D csi %4D\n", el->el_information, ":", el->el_csi, ":");
1384 device_printf(sc->mlx_dev, "unknown log message type 0x%x\n", el->el_type);
1388 device_printf(sc->mlx_dev, "error reading message log - %s\n", mlx_diagnose_command(mc));
1390 sc->mlx_lastevent = sc->mlx_currevent;
1398 if (sc->mlx_lastevent != sc->mlx_currevent) {
1399 mlx_periodic_eventlog_poll(sc);
1402 sc->mlx_flags &= ~MLX_EVENTLOG_BUSY;
1412 struct mlx_softc *sc = mc->mc_sc;
1415 MLX_IO_ASSERT_LOCKED(sc);
1418 sc->mlx_rebuildstat = *mr;
1421 if (sc->mlx_background == 0) {
1422 sc->mlx_background = MLX_BACKGROUND_SPONTANEOUS;
1423 device_printf(sc->mlx_dev, "background check/rebuild operation started\n");
1428 switch(sc->mlx_background) {
1430 device_printf(sc->mlx_dev, "consistency check completed\n"); /* XXX print drive? */
1433 device_printf(sc->mlx_dev, "drive rebuild completed\n"); /* XXX print channel/target? */
1438 if (sc->mlx_rebuildstat.rs_code != MLX_REBUILDSTAT_IDLE) {
1439 device_printf(sc->mlx_dev, "background check/rebuild operation completed\n");
1442 sc->mlx_background = 0;
1443 sc->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
1457 * It's time to perform a channel pause action for (sc), either start or stop
1461 mlx_pause_action(struct mlx_softc *sc)
1466 MLX_IO_ASSERT_LOCKED(sc);
1469 if (sc->mlx_pause.mp_when == 0) {
1481 failsafe = ((sc->mlx_pause.mp_howlong - time_second) + 5) / 30;
1484 sc->mlx_pause.mp_howlong = time_second + (0xf * 30) - 5;
1489 for (i = 0; i < sc->mlx_enq2->me_actual_channels; i++) {
1490 if ((1 << i) & sc->mlx_pause.mp_which) {
1493 if ((mc = mlx_alloccmd(sc)) == NULL)
1503 mc->mc_private = sc; /* XXX not needed */
1510 device_printf(sc->mlx_dev, "%s failed for channel %d\n",
1521 struct mlx_softc *sc = mc->mc_sc;
1525 MLX_IO_ASSERT_LOCKED(sc);
1527 device_printf(sc->mlx_dev, "%s command failed - %s\n",
1530 device_printf(sc->mlx_dev, "channel %d pausing for %ld seconds\n",
1531 channel, (long)(sc->mlx_pause.mp_howlong - time_second));
1533 device_printf(sc->mlx_dev, "channel %d resuming\n", channel);
1547 struct mlx_softc *sc;
1557 sc = mc->mc_sc;
1566 if ((sc->mlx_state & MLX_STATE_INTEN) ? mlx_wait_command(mc) :
1572 device_printf(sc->mlx_dev, "ENQUIRY failed - %s\n",
1587 mlx_enquire(struct mlx_softc *sc, int command, size_t bufsize, void (* complete)(struct mlx_command *mc))
1594 MLX_IO_ASSERT_LOCKED(sc);
1599 if ((mc = mlx_alloccmd(sc)) == NULL)
1619 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1642 mlx_flush(struct mlx_softc *sc)
1648 MLX_IO_ASSERT_LOCKED(sc);
1652 if ((mc = mlx_alloccmd(sc)) == NULL)
1667 device_printf(sc->mlx_dev, "FLUSH failed - %s\n", mlx_diagnose_command(mc));
1685 mlx_check(struct mlx_softc *sc, int drive)
1691 MLX_IO_ASSERT_LOCKED(sc);
1695 if ((mc = mlx_alloccmd(sc)) == NULL)
1710 device_printf(sc->mlx_dev, "CHECK ASYNC failed - %s\n", mlx_diagnose_command(mc));
1712 device_printf(sc->mlx_sysdrive[drive].ms_disk, "consistency check started");
1729 mlx_rebuild(struct mlx_softc *sc, int channel, int target)
1735 MLX_IO_ASSERT_LOCKED(sc);
1739 if ((mc = mlx_alloccmd(sc)) == NULL)
1754 device_printf(sc->mlx_dev, "REBUILD ASYNC failed - %s\n", mlx_diagnose_command(mc));
1756 device_printf(sc->mlx_dev, "drive rebuild started for %d:%d\n", channel, target);
1774 struct mlx_softc *sc = mc->mc_sc;
1778 MLX_IO_ASSERT_LOCKED(sc);
1788 mtx_sleep(mc->mc_private, &sc->mlx_io_lock, PRIBIO | PCATCH, "mlxwcmd", hz);
1792 device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1809 struct mlx_softc *sc = mc->mc_sc;
1813 MLX_IO_ASSERT_LOCKED(sc);
1827 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
1830 device_printf(sc->mlx_dev, "command failed - %s\n", mlx_diagnose_command(mc));
1839 struct mlx_softc *sc;
1848 sc = mc->mc_sc;
1861 driveno = mlxd->mlxd_drive - sc->mlx_sysdrive;
1864 if ((bp->bio_pblkno + blkcount) > sc->mlx_sysdrive[driveno].ms_size)
1865 device_printf(sc->mlx_dev,
1868 (u_long)sc->mlx_sysdrive[driveno].ms_size);
1874 if (sc->mlx_iftype == MLX_IFTYPE_2) {
1899 sc->mlx_state &= ~MLX_STATE_QFROZEN;
1907 mlx_startio(struct mlx_softc *sc)
1913 MLX_IO_ASSERT_LOCKED(sc);
1917 if (sc->mlx_state & MLX_STATE_QFROZEN)
1921 if ((bp = bioq_first(&sc->mlx_bioq)) == NULL)
1924 if ((mc = mlx_alloccmd(sc)) == NULL)
1932 bioq_remove(&sc->mlx_bioq, bp);
1933 sc->mlx_waitbufs--;
1942 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
1945 sc->mlx_state |= MLX_STATE_QFROZEN;
1957 struct mlx_softc *sc = mc->mc_sc;
1961 MLX_IO_ASSERT_LOCKED(sc);
1974 device_printf(sc->mlx_dev, "I/O error - %s\n", mlx_diagnose_command(mc));
1976 device_printf(sc->mlx_dev, " b_bcount %ld blkcount %ld b_pblkno %d\n",
1978 device_printf(sc->mlx_dev, " %13D\n", mc->mc_mailbox, " ");
2040 mlx_user_command(struct mlx_softc *sc, struct mlx_usercommand *mu)
2053 MLX_IO_LOCK(sc);
2054 if ((mc = mlx_alloccmd(sc)) == NULL) {
2055 MLX_IO_UNLOCK(sc);
2070 MLX_IO_UNLOCK(sc);
2073 MLX_IO_LOCK(sc);
2076 MLX_IO_LOCK(sc);
2099 error = bus_dmamap_load(sc->mlx_buffer_dmat, mc->mc_dmamap, mc->mc_data,
2107 MLX_IO_UNLOCK(sc);
2109 MLX_IO_LOCK(sc);
2114 MLX_IO_UNLOCK(sc);
2135 struct mlx_softc *sc = mc->mc_sc;
2140 MLX_IO_ASSERT_LOCKED(sc);
2145 if (sc->mlx_enq2 != NULL) {
2146 limit = sc->mlx_enq2->me_max_commands;
2150 if (sc->mlx_busycmds >= ((mc->mc_flags & MLX_CMD_PRIORITY) ? limit : limit - 4))
2160 if (sc->mlx_busycmd[slot] == NULL)
2164 sc->mlx_busycmd[slot] = mc;
2165 sc->mlx_busycmds++;
2184 struct mlx_softc *sc = mc->mc_sc;
2191 if (sc->mlx_enq2 && (nsegments > sc->mlx_enq2->me_max_sg))
2193 sc->mlx_enq2->me_max_sg);
2196 sg = sc->mlx_sgtable + (mc->mc_slot * MLX_NSEG);
2200 mc->mc_sgphys = sc->mlx_sgbusaddr +
2212 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap,
2215 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap,
2222 struct mlx_softc *sc = mc->mc_sc;
2230 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTREAD);
2232 bus_dmamap_sync(sc->mlx_buffer_dmat, mc->mc_dmamap, BUS_DMASYNC_POSTWRITE);
2234 bus_dmamap_unload(sc->mlx_buffer_dmat, mc->mc_dmamap);
2246 struct mlx_softc *sc = mc->mc_sc;
2262 if (sc->mlx_tryqueue(sc, mc)) {
2264 TAILQ_INSERT_TAIL(&sc->mlx_work, mc, mc_link);
2267 mlx_done(sc, 0);
2274 sc->mlx_busycmd[mc->mc_slot] = NULL;
2275 device_printf(sc->mlx_dev, "controller wedged (not taking commands)\n");
2277 mlx_complete(sc);
2282 * Poll the controller (sc) for completed commands.
2289 mlx_done(struct mlx_softc *sc, int startio)
2297 MLX_IO_ASSERT_LOCKED(sc);
2304 if (sc->mlx_findcomplete(sc, &slot, &status)) {
2306 mc = sc->mlx_busycmd[slot]; /* find command */
2312 sc->mlx_busycmd[slot] = NULL;
2313 sc->mlx_busycmds--;
2315 device_printf(sc->mlx_dev, "duplicate done event for slot %d\n", slot);
2318 device_printf(sc->mlx_dev, "done event for nonbusy slot %d\n", slot);
2327 mlx_startio(sc);
2330 mlx_complete(sc);
2336 * Perform post-completion processing for commands on (sc).
2339 mlx_complete(struct mlx_softc *sc)
2344 MLX_IO_ASSERT_LOCKED(sc);
2347 mc = TAILQ_FIRST(&sc->mlx_work);
2361 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2370 TAILQ_REMOVE(&sc->mlx_work, mc, mc_link);
2404 mlx_alloccmd(struct mlx_softc *sc)
2411 MLX_IO_ASSERT_LOCKED(sc);
2412 if ((mc = TAILQ_FIRST(&sc->mlx_freecmds)) != NULL)
2413 TAILQ_REMOVE(&sc->mlx_freecmds, mc, mc_link);
2419 mc->mc_sc = sc;
2420 error = bus_dmamap_create(sc->mlx_buffer_dmat, 0, &mc->mc_dmamap);
2452 struct mlx_softc *sc = mc->mc_sc;
2455 bus_dmamap_destroy(sc->mlx_buffer_dmat, mc->mc_dmamap);
2471 mlx_v3_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2476 MLX_IO_ASSERT_LOCKED(sc);
2479 if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_FULL)) {
2482 MLX_V3_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2485 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_FULL);
2496 mlx_v3_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2500 MLX_IO_ASSERT_LOCKED(sc);
2503 if (MLX_V3_GET_ODBR(sc) & MLX_V3_ODB_SAVAIL) {
2504 *slot = MLX_V3_GET_STATUS_IDENT(sc); /* get command identifier */
2505 *status = MLX_V3_GET_STATUS(sc); /* get status */
2508 MLX_V3_PUT_ODBR(sc, MLX_V3_ODB_SAVAIL);
2509 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2519 mlx_v3_intaction(struct mlx_softc *sc, int action)
2522 MLX_IO_ASSERT_LOCKED(sc);
2526 MLX_V3_PUT_IER(sc, 0);
2527 sc->mlx_state &= ~MLX_STATE_INTEN;
2530 MLX_V3_PUT_IER(sc, 1);
2531 sc->mlx_state |= MLX_STATE_INTEN;
2542 mlx_v3_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
2551 MLX_V3_PUT_IDBR(sc, MLX_V3_IDB_SACK);
2556 if (!(MLX_V3_GET_IDBR(sc) & MLX_V3_IDB_INIT_BUSY))
2560 fwerror = MLX_V3_GET_FWERROR(sc);
2566 *param1 = MLX_V3_GET_FWERROR_PARAM1(sc);
2567 *param2 = MLX_V3_GET_FWERROR_PARAM2(sc);
2570 MLX_V3_PUT_FWERROR(sc, 0);
2586 mlx_v4_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2591 MLX_IO_ASSERT_LOCKED(sc);
2594 if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_FULL)) {
2597 MLX_V4_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2600 bus_barrier(sc->mlx_mem, MLX_V4_MAILBOX, MLX_V4_MAILBOX_LENGTH,
2604 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_HWMBOX_CMD);
2615 mlx_v4_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2619 MLX_IO_ASSERT_LOCKED(sc);
2622 if (MLX_V4_GET_ODBR(sc) & MLX_V4_ODB_HWSAVAIL) {
2623 *slot = MLX_V4_GET_STATUS_IDENT(sc); /* get command identifier */
2624 *status = MLX_V4_GET_STATUS(sc); /* get status */
2627 MLX_V4_PUT_ODBR(sc, MLX_V4_ODB_HWMBOX_ACK);
2628 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2638 mlx_v4_intaction(struct mlx_softc *sc, int action)
2641 MLX_IO_ASSERT_LOCKED(sc);
2645 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK | MLX_V4_IER_DISINT);
2646 sc->mlx_state &= ~MLX_STATE_INTEN;
2649 MLX_V4_PUT_IER(sc, MLX_V4_IER_MASK & ~MLX_V4_IER_DISINT);
2650 sc->mlx_state |= MLX_STATE_INTEN;
2661 mlx_v4_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
2670 MLX_V4_PUT_IDBR(sc, MLX_V4_IDB_SACK);
2675 if (!(MLX_V4_GET_IDBR(sc) & MLX_V4_IDB_INIT_BUSY))
2679 fwerror = MLX_V4_GET_FWERROR(sc);
2685 *param1 = MLX_V4_GET_FWERROR_PARAM1(sc);
2686 *param2 = MLX_V4_GET_FWERROR_PARAM2(sc);
2689 MLX_V4_PUT_FWERROR(sc, 0);
2705 mlx_v5_tryqueue(struct mlx_softc *sc, struct mlx_command *mc)
2710 MLX_IO_ASSERT_LOCKED(sc);
2713 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_EMPTY) {
2716 MLX_V5_PUT_MAILBOX(sc, i, mc->mc_mailbox[i]);
2719 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_HWMBOX_CMD);
2730 mlx_v5_findcomplete(struct mlx_softc *sc, u_int8_t *slot, u_int16_t *status)
2734 MLX_IO_ASSERT_LOCKED(sc);
2737 if (MLX_V5_GET_ODBR(sc) & MLX_V5_ODB_HWSAVAIL) {
2738 *slot = MLX_V5_GET_STATUS_IDENT(sc); /* get command identifier */
2739 *status = MLX_V5_GET_STATUS(sc); /* get status */
2742 MLX_V5_PUT_ODBR(sc, MLX_V5_ODB_HWMBOX_ACK);
2743 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2753 mlx_v5_intaction(struct mlx_softc *sc, int action)
2756 MLX_IO_ASSERT_LOCKED(sc);
2760 MLX_V5_PUT_IER(sc, 0xff & MLX_V5_IER_DISINT);
2761 sc->mlx_state &= ~MLX_STATE_INTEN;
2764 MLX_V5_PUT_IER(sc, 0xff & ~MLX_V5_IER_DISINT);
2765 sc->mlx_state |= MLX_STATE_INTEN;
2776 mlx_v5_fw_handshake(struct mlx_softc *sc, int *error, int *param1, int *param2,
2785 MLX_V5_PUT_IDBR(sc, MLX_V5_IDB_SACK);
2790 if (MLX_V5_GET_IDBR(sc) & MLX_V5_IDB_INIT_DONE)
2794 fwerror = MLX_V5_GET_FWERROR(sc);
2800 *param1 = MLX_V5_GET_FWERROR_PARAM1(sc);
2801 *param2 = MLX_V5_GET_FWERROR_PARAM2(sc);
2804 MLX_V5_PUT_FWERROR(sc, 0xff);
2901 * Print a string describing the controller (sc)
2922 mlx_describe_controller(struct mlx_softc *sc)
2929 if ((sc->mlx_enq2->me_hardware_id & 0xff) == mlx_controller_names[i].hwid) {
2935 sprintf(buf, " model 0x%x", sc->mlx_enq2->me_hardware_id & 0xff);
2938 device_printf(sc->mlx_dev, "DAC%s, %d channel%s, firmware %d.%02d-%c-%02d, %dMB RAM\n",
2940 sc->mlx_enq2->me_actual_channels,
2941 sc->mlx_enq2->me_actual_channels > 1 ? "s" : "",
2942 sc->mlx_enq2->me_firmware_id & 0xff,
2943 (sc->mlx_enq2->me_firmware_id >> 8) & 0xff,
2944 (sc->mlx_enq2->me_firmware_id >> 24) & 0xff,
2945 (sc->mlx_enq2->me_firmware_id >> 16) & 0xff,
2946 sc->mlx_enq2->me_mem_size / (1024 * 1024));
2949 device_printf(sc->mlx_dev, " Hardware ID 0x%08x\n", sc->mlx_enq2->me_hardware_id);
2950 device_printf(sc->mlx_dev, " Firmware ID 0x%08x\n", sc->mlx_enq2->me_firmware_id);
2951 device_printf(sc->mlx_dev, " Configured/Actual channels %d/%d\n", sc->mlx_enq2->me_configured_channels,
2952 sc->mlx_enq2->me_actual_channels);
2953 device_printf(sc->mlx_dev, " Max Targets %d\n", sc->mlx_enq2->me_max_targets);
2954 device_printf(sc->mlx_dev, " Max Tags %d\n", sc->mlx_enq2->me_max_tags);
2955 device_printf(sc->mlx_dev, " Max System Drives %d\n", sc->mlx_enq2->me_max_sys_drives);
2956 device_printf(sc->mlx_dev, " Max Arms %d\n", sc->mlx_enq2->me_max_arms);
2957 device_printf(sc->mlx_dev, " Max Spans %d\n", sc->mlx_enq2->me_max_spans);
2958 device_printf(sc->mlx_dev, " DRAM/cache/flash/NVRAM size %d/%d/%d/%d\n", sc->mlx_enq2->me_mem_size,
2959 sc->mlx_enq2->me_cache_size, sc->mlx_enq2->me_flash_size, sc->mlx_enq2->me_nvram_size);
2960 device_printf(sc->mlx_dev, " DRAM type %d\n", sc->mlx_enq2->me_mem_type);
2961 device_printf(sc->mlx_dev, " Clock Speed %dns\n", sc->mlx_enq2->me_clock_speed);
2962 device_printf(sc->mlx_dev, " Hardware Speed %dns\n", sc->mlx_enq2->me_hardware_speed);
2963 device_printf(sc->mlx_dev, " Max Commands %d\n", sc->mlx_enq2->me_max_commands);
2964 device_printf(sc->mlx_dev, " Max SG Entries %d\n", sc->mlx_enq2->me_max_sg);
2965 device_printf(sc->mlx_dev, " Max DP %d\n", sc->mlx_enq2->me_max_dp);
2966 device_printf(sc->mlx_dev, " Max IOD %d\n", sc->mlx_enq2->me_max_iod);
2967 device_printf(sc->mlx_dev, " Max Comb %d\n", sc->mlx_enq2->me_max_comb);
2968 device_printf(sc->mlx_dev, " Latency %ds\n", sc->mlx_enq2->me_latency);
2969 device_printf(sc->mlx_dev, " SCSI Timeout %ds\n", sc->mlx_enq2->me_scsi_timeout);
2970 device_printf(sc->mlx_dev, " Min Free Lines %d\n", sc->mlx_enq2->me_min_freelines);
2971 device_printf(sc->mlx_dev, " Rate Constant %d\n", sc->mlx_enq2->me_rate_const);
2972 device_printf(sc->mlx_dev, " MAXBLK %d\n", sc->mlx_enq2->me_maxblk);
2973 device_printf(sc->mlx_dev, " Blocking Factor %d sectors\n", sc->mlx_enq2->me_blocking_factor);
2974 device_printf(sc->mlx_dev, " Cache Line Size %d blocks\n", sc->mlx_enq2->me_cacheline);
2975 device_printf(sc->mlx_dev, " SCSI Capability %s%dMHz, %d bit\n",
2976 sc->mlx_enq2->me_scsi_cap & (1<<4) ? "differential " : "",
2977 (1 << ((sc->mlx_enq2->me_scsi_cap >> 2) & 3)) * 10,
2978 8 << (sc->mlx_enq2->me_scsi_cap & 0x3));
2979 device_printf(sc->mlx_dev, " Firmware Build Number %d\n", sc->mlx_enq2->me_firmware_build);
2980 device_printf(sc->mlx_dev, " Fault Management Type %d\n", sc->mlx_enq2->me_fault_mgmt_type);
2981 device_printf(sc->mlx_dev, " Features %b\n", sc->mlx_enq2->me_firmware_features,
2996 mlx_fw_message(struct mlx_softc *sc, int error, int param1, int param2)
3000 device_printf(sc->mlx_dev, "physical drive %d:%d not responding\n", param2, param1);
3004 if (!(sc->mlx_flags & MLX_SPINUP_REPORTED)) {
3005 device_printf(sc->mlx_dev, "spinning up drives...\n");
3006 sc->mlx_flags |= MLX_SPINUP_REPORTED;
3010 device_printf(sc->mlx_dev, "configuration checksum error\n");
3013 device_printf(sc->mlx_dev, "mirror race recovery failed\n");
3016 device_printf(sc->mlx_dev, "mirror race recovery in progress\n");
3019 device_printf(sc->mlx_dev, "physical drive %d:%d COD mismatch\n", param2, param1);
3022 device_printf(sc->mlx_dev, "logical drive installation aborted\n");
3025 device_printf(sc->mlx_dev, "mirror race on a critical system drive\n");
3028 device_printf(sc->mlx_dev, "new controller configuration found\n");
3031 device_printf(sc->mlx_dev, "FATAL MEMORY PARITY ERROR\n");
3034 device_printf(sc->mlx_dev, "unknown firmware initialisation error %02x:%02x:%02x\n", error, param1, param2);
3050 mlx_findunit(struct mlx_softc *sc, int unit)
3055 MLX_CONFIG_ASSERT_LOCKED(sc);
3058 if (sc->mlx_sysdrive[i].ms_disk != 0) {
3060 if (unit == device_get_unit(sc->mlx_sysdrive[i].ms_disk))
3061 return(&sc->mlx_sysdrive[i]);