diff --git a/sys/arch/dreamcast/dev/maple/maple.c b/sys/arch/dreamcast/dev/maple/maple.c index 71bf2d66fdf2..15074516835b 100644 --- a/sys/arch/dreamcast/dev/maple/maple.c +++ b/sys/arch/dreamcast/dev/maple/maple.c @@ -1,4 +1,4 @@ -/* $NetBSD: maple.c,v 1.23 2003/01/01 01:28:29 thorpej Exp $ */ +/* $NetBSD: maple.c,v 1.24 2003/02/11 01:21:46 itohy Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -697,6 +697,19 @@ maple_attach_unit(struct maple_softc *sc, struct maple_unit *u) u->u_ping_func = f; /* XXX using largest func */ } } +#ifdef MAPLE_MEMCARD_PING_HACK + /* + * Some 3rd party memory card pretend to be Visual Memory, + * but need special handling for ping. + */ + if (func == (MAPLE_FUNC(MAPLE_FN_MEMCARD) | MAPLE_FUNC(MAPLE_FN_LCD) | + MAPLE_FUNC(MAPLE_FN_CLOCK))) { + u->u_ping_func = MAPLE_FN_MEMCARD; + u->u_ping_stat = MAPLE_PING_MEMCARD; + } else { + u->u_ping_stat = MAPLE_PING_NORMAL; + } +#endif strcpy(sc->sc_dev.dv_xname, oldxname); sc->sc_port_units[u->port] |= 1 << u->subunit; @@ -957,15 +970,32 @@ maple_unit_ping(struct maple_softc *sc) { struct maple_unit *u; struct maple_func *fn; +#ifdef MAPLE_MEMCARD_PING_HACK + static u_int32_t memcard_ping_arg[2] = { + 0x02000000, /* htonl(MAPLE_FUNC(MAPLE_FN_MEMCARD)) */ + 0 /* pt (1 byte) and unused 3 bytes */ + }; +#endif if ((u = TAILQ_FIRST(&sc->sc_pingq)) != NULL) { KASSERT(u->u_queuestat == MAPLE_QUEUE_PING); maple_remove_from_queues(sc, u); if (u->u_dma_stat == MAPLE_DMA_IDLE && u->u_noping == 0) { - fn = &u->u_func[u->u_ping_func]; - fn->f_work = htonl(MAPLE_FUNC(u->u_ping_func)); - maple_write_command(sc, u, MAPLE_COMMAND_GETCOND, - 1, &fn->f_work); +#ifdef MAPLE_MEMCARD_PING_HACK + if (u->u_ping_stat == MAPLE_PING_MINFO) { + /* use MINFO for some memory cards */ + maple_write_command(sc, u, + MAPLE_COMMAND_GETMINFO, + 2, memcard_ping_arg); + } else +#endif + { + fn = &u->u_func[u->u_ping_func]; + fn->f_work = htonl(MAPLE_FUNC(u->u_ping_func)); + maple_write_command(sc, u, + MAPLE_COMMAND_GETCOND, + 1, &fn->f_work); + } u->u_dma_stat = MAPLE_DMA_PING; /* u->u_dma_func = XXX; */ } else { @@ -1292,6 +1322,30 @@ maple_check_responses(struct maple_softc *sc) u->subunit), response); #endif +#ifdef MAPLE_MEMCARD_PING_HACK + if (u->u_ping_stat + == MAPLE_PING_MEMCARD) { + /* + * The unit claims itself to be + * a Visual Memory, and has + * never responded to GETCOND. + * Try again using MINFO, in + * case it is a poorly + * implemented 3rd party card. + */ +#ifdef MAPLE_DEBUG + printf("%s: switching ping method\n", + maple_unit_name(buf, + u->port, u->subunit)); +#endif + u->u_ping_stat + = MAPLE_PING_MINFO; + TAILQ_INSERT_TAIL(&sc->sc_pingq, + u, u_q); + u->u_queuestat + = MAPLE_QUEUE_PING; + } else +#endif /* MAPLE_MEMCARD_PING_HACK */ maple_detach_unit(sc, u); } break; @@ -1300,6 +1354,14 @@ maple_check_responses(struct maple_softc *sc) case MAPLE_RESPONSE_DATATRF: TAILQ_INSERT_TAIL(&sc->sc_pingq, u, u_q); u->u_queuestat = MAPLE_QUEUE_PING; +#ifdef MAPLE_MEMCARD_PING_HACK + /* + * If the unit responds to GETCOND, it is a + * normal implementation. + */ + if (u->u_ping_stat == MAPLE_PING_MEMCARD) + u->u_ping_stat = MAPLE_PING_NORMAL; +#endif break; } diff --git a/sys/arch/dreamcast/dev/maple/maplevar.h b/sys/arch/dreamcast/dev/maple/maplevar.h index 9d1a966ec60d..254475e570cb 100644 --- a/sys/arch/dreamcast/dev/maple/maplevar.h +++ b/sys/arch/dreamcast/dev/maple/maplevar.h @@ -1,4 +1,4 @@ -/* $NetBSD: maplevar.h,v 1.5 2002/11/15 13:30:21 itohy Exp $ */ +/* $NetBSD: maplevar.h,v 1.6 2003/02/11 01:21:46 itohy Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -109,12 +109,22 @@ struct maple_func { TAILQ_ENTRY(maple_func) f_cmdq; }; +/* work-around problem with 3rd party memory cards */ +#define MAPLE_MEMCARD_PING_HACK + struct maple_unit { int port, subunit; struct maple_func u_func[MAPLE_NFUNC]; u_int32_t getcond_func_set; int u_ping_func; /* function used for ping */ u_int32_t u_noping; /* stop ping (bitmap of function) */ +#ifdef MAPLE_MEMCARD_PING_HACK + enum maple_ping_stat { + MAPLE_PING_NORMAL, /* ping with GETCOND */ + MAPLE_PING_MEMCARD, /* memory card, possibly 3rd party */ + MAPLE_PING_MINFO /* poorly implemented 3rd party card */ + } u_ping_stat; +#endif struct maple_devinfo devinfo; /* DMA status / function */