Subject: Re: mmem woes
To: None <port-dreamcast@netbsd.org>
From: ITOH Yasufumi <itohy@netbsd.org>
List: port-dreamcast
Date: 02/10/2003 23:03:12
logix@foobar.franken.de writes:

> Thanks, it now works!  I had to apply both patches, neither of
> the two alone helped.

OK.
However, the change keeps the access indicator on
when used with genuine Virual Memory.

I have created another patch to avoid this.
Is this work for you?
-- 
ITOH Yasufumi

Index: maple.c
===================================================================
RCS file: /cvsroot/src/sys/arch/dreamcast/dev/maple/maple.c,v
retrieving revision 1.23
diff -p -u -r1.23 maple.c
--- maple.c	2003/01/01 01:28:29	1.23
+++ maple.c	2003/02/10 13:58:57
@@ -697,6 +697,19 @@ maple_attach_unit(struct maple_softc *sc
 			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 actually only the storage funciton is implemented.
+	 */
+	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,26 @@ maple_check_responses(struct maple_softc
 						u->subunit),
 					    response);
 #endif
+#ifdef MAPLE_MEMCARD_PING_HACK
+					if (u->u_ping_stat
+					    == MAPLE_PING_MEMCARD) {
+						/*
+						 * The unit has never responded
+						 * to GETCOND.
+						 */
+#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_detach_unit(sc, u);
 				}
 				break;
@@ -1300,6 +1350,14 @@ maple_check_responses(struct maple_softc
 			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;
 			}
 
Index: maplevar.h
===================================================================
RCS file: /cvsroot/src/sys/arch/dreamcast/dev/maple/maplevar.h,v
retrieving revision 1.5
diff -p -u -r1.5 maplevar.h
--- maplevar.h	2002/11/15 13:30:21	1.5
+++ maplevar.h	2003/02/10 13:58:57
@@ -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 */