Lines Matching defs:mlx

1 /*	$NetBSD: mlx.c,v 1.70 2021/08/07 16:19:12 thorpej Exp $	*/
57 * from FreeBSD: mlx.c,v 1.14.2.3 2000/08/04 06:52:50 msmith Exp
70 __KERNEL_RCSID(0, "$NetBSD: mlx.c,v 1.70 2021/08/07 16:19:12 thorpej Exp $");
260 mlx_init(struct mlx_softc *mlx, const char *intrstr)
271 SIMPLEQ_INIT(&mlx->mlx_ccb_queue);
272 SLIST_INIT(&mlx->mlx_ccb_freelist);
273 TAILQ_INIT(&mlx->mlx_ccb_worklist);
276 printf("%s: interrupting at %s\n", device_xname(mlx->mlx_dv),
284 if ((rv = bus_dmamem_alloc(mlx->mlx_dmat, size, PAGE_SIZE, 0, &seg, 1,
286 aprint_error_dev(mlx->mlx_dv,
291 if ((rv = bus_dmamem_map(mlx->mlx_dmat, &seg, rseg, size,
292 (void **)&mlx->mlx_sgls,
294 aprint_error_dev(mlx->mlx_dv,
299 if ((rv = bus_dmamap_create(mlx->mlx_dmat, size, 1, size, 0,
300 BUS_DMA_NOWAIT, &mlx->mlx_dmamap)) != 0) {
301 aprint_error_dev(mlx->mlx_dv,
306 if ((rv = bus_dmamap_load(mlx->mlx_dmat, mlx->mlx_dmamap,
307 mlx->mlx_sgls, size, NULL, BUS_DMA_NOWAIT)) != 0) {
308 aprint_error_dev(mlx->mlx_dv,
313 mlx->mlx_sgls_paddr = mlx->mlx_dmamap->dm_segs[0].ds_addr;
314 memset(mlx->mlx_sgls, 0, size);
320 mlx->mlx_ccbs = mc;
324 rv = bus_dmamap_create(mlx->mlx_dmat, MLX_MAX_XFER,
330 mlx->mlx_nccbs++;
331 mlx_ccb_free(mlx, mc);
333 if (mlx->mlx_nccbs != MLX_MAX_QUEUECNT)
334 printf("%s: %d/%d CCBs usable\n", device_xname(mlx->mlx_dv),
335 mlx->mlx_nccbs, MLX_MAX_QUEUECNT);
338 (*mlx->mlx_intaction)(mlx, 0);
341 if (mlx->mlx_reset != NULL) {
343 device_xname(mlx->mlx_dv));
344 if ((*mlx->mlx_reset)(mlx) != 0) {
345 aprint_error_dev(mlx->mlx_dv, "reset failed\n");
358 hscode = (*mlx->mlx_fw_handshake)(mlx, &hserr, &hsparam1,
363 device_xname(mlx->mlx_dv));
370 device_xname(mlx->mlx_dv));
376 hscode = mlx_fw_message(mlx, hserr, hsparam1, hsparam2);
387 ci = &mlx->mlx_ci;
390 me2 = mlx_enquire(mlx, MLX_CMD_ENQUIRY2,
393 aprint_error_dev(mlx->mlx_dv, "ENQUIRY2 failed\n");
415 meo = mlx_enquire(mlx, MLX_CMD_ENQUIRY_OLD,
418 aprint_error_dev(mlx->mlx_dv, "ENQUIRY_OLD failed\n");
465 mlx_describe(mlx);
469 device_xname(mlx->mlx_dv));
471 device_xname(mlx->mlx_dv), wantfwstr);
475 mlx->mlx_currevent = -1;
478 mlx->mlx_bg = 0;
479 mlx->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
482 mlx->mlx_max_queuecnt =
486 if (mlx->mlx_max_queuecnt < MLX_NCCBS_CONTROL + MLX_MAX_DRIVES)
488 device_xname(mlx->mlx_dv));
490 aprint_error_dev(mlx->mlx_dv,
497 mlx_configure(mlx, 0);
498 (*mlx->mlx_intaction)(mlx, 1);
499 mlx->mlx_flags |= MLXF_INITOK;
512 aprint_error_dev(mlx->mlx_dv,
521 mlx_describe(struct mlx_softc *mlx)
529 ci = &mlx->mlx_ci;
543 device_xname(mlx->mlx_dv), model, ci->ci_nchan,
556 mlx_configure(struct mlx_softc *mlx, int waitok)
567 mlx->mlx_flags |= MLXF_RESCANNING;
569 if (mlx->mlx_ci.ci_iftype <= 2) {
570 meo = mlx_enquire(mlx, MLX_CMD_ENQUIRY_OLD,
573 aprint_error_dev(mlx->mlx_dv, "ENQUIRY_OLD failed\n");
576 mlx->mlx_numsysdrives = meo->me_num_sys_drvs;
579 me = mlx_enquire(mlx, MLX_CMD_ENQUIRY,
582 aprint_error_dev(mlx->mlx_dv, "ENQUIRY failed\n");
585 mlx->mlx_numsysdrives = me->me_num_sys_drvs;
589 mes = mlx_enquire(mlx, MLX_CMD_ENQSYSDRIVE,
592 aprint_error_dev(mlx->mlx_dv, "error fetching drive status\n");
597 mlx_adjqparam(mlx, 1, 0);
599 ms = &mlx->mlx_sysdrive[0];
618 if (i >= mlx->mlx_numsysdrives)
630 ms->ms_dv = config_found(mlx->mlx_dv, &mlxa, mlx_print,
639 mlx_adjqparam(mlx, mlx->mlx_max_queuecnt / nunits,
640 mlx->mlx_max_queuecnt % nunits);
642 mlx->mlx_flags &= ~MLXF_RESCANNING;
664 * Shut down all configured `mlx' devices.
669 struct mlx_softc *mlx;
673 if ((mlx = device_lookup_private(&mlx_cd, i)) != NULL)
674 mlx_flush(mlx, 0);
681 mlx_adjqparam(struct mlx_softc *mlx, int mpu, int slop)
690 if (device_parent(ld->sc_dv) != mlx->mlx_dv)
703 struct mlx_softc *mlx;
705 if ((mlx = device_lookup_private(&mlx_cd, minor(dev))) == NULL)
707 if ((mlx->mlx_flags & MLXF_INITOK) == 0)
709 if ((mlx->mlx_flags & MLXF_OPEN) != 0)
712 mlx->mlx_flags |= MLXF_OPEN;
722 struct mlx_softc *mlx;
724 mlx = device_lookup_private(&mlx_cd, minor(dev));
725 mlx->mlx_flags &= ~MLXF_OPEN;
735 struct mlx_softc *mlx;
742 mlx = device_lookup_private(&mlx_cd, minor(dev));
755 mlx_configure(mlx, 1);
766 if ((mlx->mlx_flags & MLXF_PAUSEWORKS) == 0)
772 (mlx->mlx_pause.mp_when != 0)) {
774 mlx->mlx_pause.mp_which = 0;
779 mp->mp_which &= ((1 << mlx->mlx_ci.ci_nchan) -1);
789 if ((mlx->mlx_pause.mp_which != 0) &&
790 (mlx->mlx_pause.mp_when == 0)) {
796 mlx->mlx_pause.mp_which = mp->mp_which;
797 mlx->mlx_pause.mp_when = time_second + mp->mp_when;
798 mlx->mlx_pause.mp_howlong =
799 mlx->mlx_pause.mp_when + mp->mp_howlong;
812 return (mlx_user_command(mlx, (struct mlx_usercommand *)data));
818 if (mlx->mlx_bg != 0) {
824 rb->rr_status = mlx_rebuild(mlx, rb->rr_channel, rb->rr_target);
850 mlx->mlx_bg = MLX_BG_REBUILD;
858 *rs = mlx->mlx_rebuildstat;
867 ms = &mlx->mlx_sysdrive[i];
880 memcpy(arg, &mlx->mlx_ci, sizeof(mlx->mlx_ci));
890 ms = &mlx->mlx_sysdrive[*arg];
918 if (mlx->mlx_bg != 0) {
923 switch (result = mlx_check(mlx, *arg)) {
945 mlx->mlx_bg = MLX_BG_CHECK;
956 struct mlx_softc *mlx;
961 if ((mlx = device_lookup_private(&mlx_cd, i)) != NULL)
962 if (mlx->mlx_ci.ci_iftype > 1)
963 mlx_periodic(mlx);
970 mlx_periodic(struct mlx_softc *mlx)
975 if ((mlx->mlx_pause.mp_which != 0) &&
976 (mlx->mlx_pause.mp_when > 0) &&
977 (time_second >= mlx->mlx_pause.mp_when)) {
981 mlx_pause_action(mlx);
982 mlx->mlx_pause.mp_when = 0;
983 } else if ((mlx->mlx_pause.mp_which != 0) &&
984 (mlx->mlx_pause.mp_when == 0)) {
988 if (time_second >= mlx->mlx_pause.mp_howlong) {
989 mlx_pause_action(mlx);
990 mlx->mlx_pause.mp_which = 0;
992 } else if (time_second > (mlx->mlx_lastpoll + 10)) {
996 mlx->mlx_lastpoll = time_second;
1001 if ((mlx->mlx_flags & MLXF_PERIODIC_CTLR) == 0) {
1002 mlx->mlx_flags |= MLXF_PERIODIC_CTLR;
1004 if (mlx->mlx_ci.ci_iftype <= 2)
1009 mlx_enquire(mlx, etype, uimax(sizeof(struct mlx_enquiry),
1017 if ((mlx->mlx_flags & MLXF_PERIODIC_DRIVE) == 0) {
1018 mlx->mlx_flags |= MLXF_PERIODIC_DRIVE;
1019 mlx_enquire(mlx, MLX_CMD_ENQSYSDRIVE,
1028 if ((mlx->mlx_flags & MLXF_PERIODIC_REBUILD) == 0) {
1029 mlx->mlx_flags |= MLXF_PERIODIC_REBUILD;
1030 mlx_enquire(mlx, MLX_CMD_REBUILDSTAT,
1038 for (mc = TAILQ_FIRST(&mlx->mlx_ccb_worklist); mc != NULL; mc = nmc) {
1047 TAILQ_REMOVE(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
1064 struct mlx_softc *mlx;
1073 mlx = device_private(mc->mc_mx.mx_dv);
1074 mlx_ccb_unmap(mlx, mc);
1080 aprint_error_dev(mlx->mlx_dv, "periodic enquiry failed - %s\n",
1139 if (mlx->mlx_currevent == -1) {
1141 mlx->mlx_currevent = lsn;
1142 mlx->mlx_lastevent = lsn;
1143 } else if (lsn != mlx->mlx_lastevent &&
1144 (mlx->mlx_flags & MLXF_EVENTLOG_BUSY) == 0) {
1146 mlx->mlx_currevent = lsn;
1149 mlx->mlx_flags |= MLXF_EVENTLOG_BUSY;
1152 mlx_periodic_eventlog_poll(mlx);
1163 if ((mlx->mlx_flags & MLXF_RESCANNING) != 0)
1167 dr = &mlx->mlx_sysdrive[0];
1169 for (i = 0; i < mlx->mlx_numsysdrives; i++, dr++) {
1191 device_xname(mlx->mlx_dv), i, statestr);
1202 device_xname(mlx->mlx_dv));
1209 mlx->mlx_flags &= ~MLXF_PERIODIC_DRIVE;
1211 mlx->mlx_flags &= ~MLXF_PERIODIC_CTLR;
1214 mlx_ccb_free(mlx, mc);
1218 * Instigate a poll for one event log message on (mlx). We only poll for
1222 mlx_periodic_eventlog_poll(struct mlx_softc *mlx)
1230 if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0)
1237 if ((rv = mlx_ccb_map(mlx, mc, result, 1024, MC_XFER_IN)) != 0)
1240 mlx_ccb_unmap(mlx, mc);
1247 mlx->mlx_lastevent, 0, 0, mc->mc_xfer_phys, 0);
1250 mc->mc_mx.mx_dv = mlx->mlx_dv;
1254 mlx_ccb_enqueue(mlx, mc);
1259 mlx_ccb_free(mlx, mc);
1273 struct mlx_softc *mlx;
1278 mlx = device_private(mc->mc_mx.mx_dv);
1280 mlx_ccb_unmap(mlx, mc);
1282 mlx->mlx_lastevent++;
1309 device_xname(mlx->mlx_dv), chan, targ,
1318 device_xname(mlx->mlx_dv), chan, targ);
1329 device_xname(mlx->mlx_dv), chan, targ,
1333 device_xname(mlx->mlx_dv),
1345 aprint_error_dev(mlx->mlx_dv,
1350 aprint_error_dev(mlx->mlx_dv,
1357 mlx->mlx_lastevent = mlx->mlx_currevent;
1361 mlx_ccb_free(mlx, mc);
1366 if (mlx->mlx_lastevent != mlx->mlx_currevent)
1367 mlx_periodic_eventlog_poll(mlx);
1369 mlx->mlx_flags &= ~MLXF_EVENTLOG_BUSY;
1378 struct mlx_softc *mlx;
1382 mlx = device_private(mc->mc_mx.mx_dv);
1384 mlx_ccb_unmap(mlx, mc);
1391 mlx->mlx_rebuildstat = *mr;
1394 if (mlx->mlx_bg == 0) {
1395 mlx->mlx_bg = MLX_BG_SPONTANEOUS;
1397 device_xname(mlx->mlx_dv));
1405 switch (mlx->mlx_bg) {
1422 if (mlx->mlx_rebuildstat.rs_code !=
1430 printf("%s: %s completed\n", device_xname(mlx->mlx_dv),
1433 mlx->mlx_bg = 0;
1434 mlx->mlx_rebuildstat.rs_code = MLX_REBUILDSTAT_IDLE;
1439 mlx_ccb_free(mlx, mc);
1440 mlx->mlx_flags &= ~MLXF_PERIODIC_REBUILD;
1444 * It's time to perform a channel pause action for (mlx), either start or
1448 mlx_pause_action(struct mlx_softc *mlx)
1454 if (mlx->mlx_pause.mp_when == 0) {
1465 failsafe = ((mlx->mlx_pause.mp_howlong - time_second) + 5) / 30;
1469 mlx->mlx_pause.mp_howlong =
1475 for (i = 0; i < mlx->mlx_ci.ci_nchan; i++) {
1476 if ((1 << i) & mlx->mlx_pause.mp_which) {
1477 if (mlx_ccb_alloc(mlx, &mc, 1) != 0) {
1478 aprint_error_dev(mlx->mlx_dv,
1489 mc->mc_mx.mx_dv = mlx->mlx_dv;
1491 mlx_ccb_enqueue(mlx, mc);
1499 struct mlx_softc *mlx;
1502 mlx = device_private(mc->mc_mx.mx_dv);
1507 aprint_error_dev(mlx->mlx_dv, "%s command failed - %s\n",
1512 device_xname(mlx->mlx_dv), channel,
1513 (long)(mlx->mlx_pause.mp_howlong - time_second));
1515 printf("%s: channel %d resuming\n", device_xname(mlx->mlx_dv),
1518 mlx_ccb_free(mlx, mc);
1529 mlx_enquire(struct mlx_softc *mlx, int command, size_t bufsize,
1539 if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0)
1547 if ((rv = mlx_ccb_map(mlx, mc, result, bufsize, MC_XFER_IN)) != 0)
1561 mc->mc_mx.mx_dv = mlx->mlx_dv;
1563 mlx_ccb_enqueue(mlx, mc);
1567 rv = mlx_ccb_wait(mlx, mc);
1569 rv = mlx_ccb_poll(mlx, mc, 5000);
1576 mlx_ccb_unmap(mlx, mc);
1577 mlx_ccb_free(mlx, mc);
1583 mlx_ccb_free(mlx, mc);
1598 mlx_flush(struct mlx_softc *mlx, int async)
1603 if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0)
1610 rv = mlx_ccb_wait(mlx, mc);
1612 rv = mlx_ccb_poll(mlx, mc, MLX_TIMEOUT * 1000);
1618 aprint_error_dev(mlx->mlx_dv, "FLUSH failed - %s\n",
1624 mlx_ccb_free(mlx, mc);
1633 mlx_check(struct mlx_softc *mlx, int drive)
1641 if (mlx_ccb_alloc(mlx, &mc, 1) != 0)
1649 if (mlx_ccb_wait(mlx, mc) != 0)
1654 aprint_error_dev(mlx->mlx_dv, "CHECK ASYNC failed - %s\n",
1658 device_xname(mlx->mlx_sysdrive[drive].ms_dv));
1663 mlx_ccb_free(mlx, mc);
1675 mlx_rebuild(struct mlx_softc *mlx, int channel, int target)
1681 if (mlx_ccb_alloc(mlx, &mc, 1) != 0)
1689 if (mlx_ccb_wait(mlx, mc) != 0)
1694 aprint_normal_dev(mlx->mlx_dv, "REBUILD ASYNC failed - %s\n",
1697 aprint_normal_dev(mlx->mlx_dv, "rebuild started for %d:%d\n",
1704 mlx_ccb_free(mlx, mc);
1718 mlx_user_command(struct mlx_softc *mlx, struct mlx_usercommand *mu)
1733 if ((rv = mlx_ccb_alloc(mlx, &mc, 1)) != 0) {
1765 rv = mlx_ccb_map(mlx, mc, kbuf, mu->mu_datasize, mu->mu_bufdir);
1809 if ((rv = mlx_ccb_wait(mlx, mc)) != 0) {
1820 mlx_ccb_unmap(mlx, mc);
1821 mlx_ccb_free(mlx, mc);
1843 mlx_ccb_alloc(struct mlx_softc *mlx, struct mlx_ccb **mcp, int control)
1849 mc = SLIST_FIRST(&mlx->mlx_ccb_freelist);
1851 if (mlx->mlx_nccbs_ctrl >= MLX_NCCBS_CONTROL) {
1857 mlx->mlx_nccbs_ctrl++;
1859 SLIST_REMOVE_HEAD(&mlx->mlx_ccb_freelist, mc_chain.slist);
1870 mlx_ccb_free(struct mlx_softc *mlx, struct mlx_ccb *mc)
1876 mlx->mlx_nccbs_ctrl--;
1878 SLIST_INSERT_HEAD(&mlx->mlx_ccb_freelist, mc, mc_chain.slist);
1888 mlx_ccb_enqueue(struct mlx_softc *mlx, struct mlx_ccb *mc)
1895 SIMPLEQ_INSERT_TAIL(&mlx->mlx_ccb_queue, mc, mc_chain.simpleq);
1897 while ((mc = SIMPLEQ_FIRST(&mlx->mlx_ccb_queue)) != NULL) {
1898 if (mlx_ccb_submit(mlx, mc) != 0)
1900 SIMPLEQ_REMOVE_HEAD(&mlx->mlx_ccb_queue, mc_chain.simpleq);
1901 TAILQ_INSERT_TAIL(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
1912 mlx_ccb_map(struct mlx_softc *mlx, struct mlx_ccb *mc, void *data, int size,
1921 rv = bus_dmamap_load(mlx->mlx_dmat, xfer, data, size, NULL,
1934 sge = (struct mlx_sgentry *)((char *)mlx->mlx_sgls + sgloff);
1948 bus_dmamap_sync(mlx->mlx_dmat, xfer, 0, mc->mc_xfer_size, i);
1949 bus_dmamap_sync(mlx->mlx_dmat, mlx->mlx_dmamap, sgloff,
1959 mlx_ccb_unmap(struct mlx_softc *mlx, struct mlx_ccb *mc)
1963 bus_dmamap_sync(mlx->mlx_dmat, mlx->mlx_dmamap,
1974 bus_dmamap_sync(mlx->mlx_dmat, mc->mc_xfer_map, 0, mc->mc_xfer_size, i);
1975 bus_dmamap_unload(mlx->mlx_dmat, mc->mc_xfer_map);
1983 mlx_ccb_poll(struct mlx_softc *mlx, struct mlx_ccb *mc, int timo)
1989 if ((rv = mlx_ccb_submit(mlx, mc)) != 0)
1991 TAILQ_INSERT_TAIL(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
1994 mlx_intr(mlx);
2002 aprint_error_dev(mlx->mlx_dv, "command failed - %s\n",
2008 printf("%s: command timed out\n", device_xname(mlx->mlx_dv));
2020 mlx_ccb_wait(struct mlx_softc *mlx, struct mlx_ccb *mc)
2028 mlx_ccb_enqueue(mlx, mc);
2033 aprint_error_dev(mlx->mlx_dv, "command failed - %s\n",
2046 mlx_ccb_submit(struct mlx_softc *mlx, struct mlx_ccb *mc)
2060 r = (*mlx->mlx_submit)(mlx, mc);
2105 struct mlx_softc *mlx;
2110 mlx = cookie;
2113 while ((*mlx->mlx_findcomplete)(mlx, &ident, &status) != 0) {
2118 aprint_error_dev(mlx->mlx_dv,
2123 mc = mlx->mlx_ccbs + ident;
2126 aprint_error_dev(mlx->mlx_dv,
2131 TAILQ_REMOVE(&mlx->mlx_ccb_worklist, mc, mc_chain.tailq);
2143 mlx_ccb_enqueue(mlx, NULL);
2157 mlx_fw_message(struct mlx_softc *mlx, int error, int param1, int param2)
2171 if ((mlx->mlx_flags & MLXF_SPINUP_REPORTED) == 0) {
2173 device_xname(mlx->mlx_dv));
2174 mlx->mlx_flags |= MLXF_SPINUP_REPORTED;
2207 aprint_error_dev(mlx->mlx_dv, "FATAL MEMORY PARITY ERROR\n");
2211 aprint_error_dev(mlx->mlx_dv,
2217 aprint_normal_dev(mlx->mlx_dv, fmt, param2, param1);
2223 MODULE(MODULE_CLASS_DRIVER, mlx, NULL);