summaryrefslogtreecommitdiff
path: root/sys/dev/sdmmc
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2016-04-23 14:16:00 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2016-04-23 14:16:00 +0000
commit3ba9d69b1be80cd2e191d5a7d5c7b334e17d0217 (patch)
tree3872414d67d017df6ee950bc68a37a106ba66087 /sys/dev/sdmmc
parent94f54ca69788c9f983931ac45f760910834d348f (diff)
Implement reading of the CIS for functions 1-7. Don't write a bogus bus width
value when initializing function 0, and correct a few related #defines. ok deraadt@
Diffstat (limited to 'sys/dev/sdmmc')
-rw-r--r--sys/dev/sdmmc/sdmmc_cis.c47
-rw-r--r--sys/dev/sdmmc/sdmmc_io.c22
-rw-r--r--sys/dev/sdmmc/sdmmc_ioreg.h9
3 files changed, 34 insertions, 44 deletions
diff --git a/sys/dev/sdmmc/sdmmc_cis.c b/sys/dev/sdmmc/sdmmc_cis.c
index 6f276f4d82f..21cf530b24f 100644
--- a/sys/dev/sdmmc/sdmmc_cis.c
+++ b/sys/dev/sdmmc/sdmmc_cis.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdmmc_cis.c,v 1.6 2016/01/11 07:32:38 kettenis Exp $ */
+/* $OpenBSD: sdmmc_cis.c,v 1.7 2016/04/23 14:15:59 kettenis Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -37,18 +37,16 @@ u_int32_t sdmmc_cisptr(struct sdmmc_function *);
u_int32_t
sdmmc_cisptr(struct sdmmc_function *sf)
{
+ struct sdmmc_function *sf0 = sf->sc->sc_fn0;
u_int32_t cisptr = 0;
+ int reg;
rw_assert_wrlock(&sf->sc->sc_lock);
- /* XXX where is the per-function CIS pointer register? */
- if (sf->number != 0)
- return SD_IO_CIS_START;
-
- /* XXX is the CIS pointer stored in little-endian format? */
- cisptr |= sdmmc_io_read_1(sf, SD_IO_CCCR_CISPTR+0) << 0;
- cisptr |= sdmmc_io_read_1(sf, SD_IO_CCCR_CISPTR+1) << 8;
- cisptr |= sdmmc_io_read_1(sf, SD_IO_CCCR_CISPTR+2) << 16;
+ reg = SD_IO_CCCR_CISPTR + (sf->number * SD_IO_CCCR_SIZE);
+ cisptr |= sdmmc_io_read_1(sf0, reg + 0) << 0;
+ cisptr |= sdmmc_io_read_1(sf0, reg + 1) << 8;
+ cisptr |= sdmmc_io_read_1(sf0, reg + 2) << 16;
return cisptr;
}
@@ -56,18 +54,13 @@ sdmmc_cisptr(struct sdmmc_function *sf)
int
sdmmc_read_cis(struct sdmmc_function *sf, struct sdmmc_cis *cis)
{
+ struct sdmmc_function *sf0 = sf->sc->sc_fn0;
int reg;
u_int8_t tplcode;
u_int8_t tpllen;
rw_assert_wrlock(&sf->sc->sc_lock);
- bzero(cis, sizeof *cis);
-
- /* XXX read per-function CIS */
- if (sf->number != 0)
- return 1;
-
reg = (int)sdmmc_cisptr(sf);
if (reg < SD_IO_CIS_START ||
reg >= (SD_IO_CIS_START+SD_IO_CIS_SIZE-16)) {
@@ -76,13 +69,13 @@ sdmmc_read_cis(struct sdmmc_function *sf, struct sdmmc_cis *cis)
}
for (;;) {
- tplcode = sdmmc_io_read_1(sf, reg++);
+ tplcode = sdmmc_io_read_1(sf0, reg++);
if (tplcode == SD_IO_CISTPL_END)
break;
if (tplcode == SD_IO_CISTPL_NULL)
continue;
- tpllen = sdmmc_io_read_1(sf, reg++);
+ tpllen = sdmmc_io_read_1(sf0, reg++);
if (tpllen == 0) {
printf("%s: CIS parse error at %d, "
"tuple code %#x, length %d\n",
@@ -98,7 +91,7 @@ sdmmc_read_cis(struct sdmmc_function *sf, struct sdmmc_cis *cis)
reg += tpllen;
break;
}
- cis->function = sdmmc_io_read_1(sf, reg);
+ cis->function = sdmmc_io_read_1(sf0, reg);
reg += tpllen;
break;
case SD_IO_CISTPL_MANFID:
@@ -108,10 +101,10 @@ sdmmc_read_cis(struct sdmmc_function *sf, struct sdmmc_cis *cis)
reg += tpllen;
break;
}
- cis->manufacturer = sdmmc_io_read_1(sf, reg++);
- cis->manufacturer |= sdmmc_io_read_1(sf, reg++) << 8;
- cis->product = sdmmc_io_read_1(sf, reg++);
- cis->product |= sdmmc_io_read_1(sf, reg++) << 8;
+ cis->manufacturer = sdmmc_io_read_1(sf0, reg++);
+ cis->manufacturer |= sdmmc_io_read_1(sf0, reg++) << 8;
+ cis->product = sdmmc_io_read_1(sf0, reg++);
+ cis->product |= sdmmc_io_read_1(sf0, reg++) << 8;
break;
case SD_IO_CISTPL_VERS_1:
if (tpllen < 2) {
@@ -123,12 +116,12 @@ sdmmc_read_cis(struct sdmmc_function *sf, struct sdmmc_cis *cis)
{
int start, i, ch, count;
- cis->cis1_major = sdmmc_io_read_1(sf, reg++);
- cis->cis1_minor = sdmmc_io_read_1(sf, reg++);
+ cis->cis1_major = sdmmc_io_read_1(sf0, reg++);
+ cis->cis1_minor = sdmmc_io_read_1(sf0, reg++);
for (count = 0, start = 0, i = 0;
(count < 4) && ((i + 4) < 256); i++) {
- ch = sdmmc_io_read_1(sf, reg + i);
+ ch = sdmmc_io_read_1(sf0, reg + i);
if (ch == 0xff)
break;
cis->cis1_info_buf[i] = ch;
@@ -178,8 +171,8 @@ sdmmc_print_cis(struct sdmmc_function *sf)
printf("%s: function %d: ", DEVNAME(sf->sc), sf->number);
switch (sf->cis.function) {
- case SDMMC_FUNCTION_WLAN:
- printf("wireless network adapter");
+ case TPLFID_FUNCTION_SDIO:
+ printf("SDIO");
break;
default:
printf("unknown (%d)", sf->cis.function);
diff --git a/sys/dev/sdmmc/sdmmc_io.c b/sys/dev/sdmmc/sdmmc_io.c
index f9cdc469430..922d6fa7537 100644
--- a/sys/dev/sdmmc/sdmmc_io.c
+++ b/sys/dev/sdmmc/sdmmc_io.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdmmc_io.c,v 1.22 2015/03/14 03:38:49 jsg Exp $ */
+/* $OpenBSD: sdmmc_io.c,v 1.23 2016/04/23 14:15:59 kettenis Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -171,21 +171,17 @@ sdmmc_io_init(struct sdmmc_softc *sc, struct sdmmc_function *sf)
{
rw_assert_wrlock(&sc->sc_lock);
- if (sf->number == 0) {
- sdmmc_io_write_1(sf, SD_IO_CCCR_BUS_WIDTH,
- CCCR_BUS_WIDTH_1);
+ if (sdmmc_read_cis(sf, &sf->cis) != 0) {
+ printf("%s: can't read CIS\n", DEVNAME(sc));
+ SET(sf->flags, SFF_ERROR);
+ return 1;
+ }
- if (sdmmc_read_cis(sf, &sf->cis) != 0) {
- printf("%s: can't read CIS\n", DEVNAME(sc));
- SET(sf->flags, SFF_ERROR);
- return 1;
- }
+ sdmmc_check_cis_quirks(sf);
- sdmmc_check_cis_quirks(sf);
+ if (sdmmc_verbose)
+ sdmmc_print_cis(sf);
- if (sdmmc_verbose)
- sdmmc_print_cis(sf);
- }
return 0;
}
diff --git a/sys/dev/sdmmc/sdmmc_ioreg.h b/sys/dev/sdmmc/sdmmc_ioreg.h
index c4c494d7381..b23edd898d7 100644
--- a/sys/dev/sdmmc/sdmmc_ioreg.h
+++ b/sys/dev/sdmmc/sdmmc_ioreg.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sdmmc_ioreg.h,v 1.5 2016/01/11 07:32:38 kettenis Exp $ */
+/* $OpenBSD: sdmmc_ioreg.h,v 1.6 2016/04/23 14:15:59 kettenis Exp $ */
/*
* Copyright (c) 2006 Uwe Stuehler <uwe@openbsd.org>
@@ -69,8 +69,9 @@
#define SD_IO_CCCR_CTL 0x06
#define CCCR_CTL_RES (1<<3)
#define SD_IO_CCCR_BUS_WIDTH 0x07
-#define CCCR_BUS_WIDTH_4 (1<<1)
-#define CCCR_BUS_WIDTH_1 (1<<0)
+#define CCCR_BUS_WIDTH_1 (0<<0)
+#define CCCR_BUS_WIDTH_4 (2<<0)
+#define CCCR_BUS_WIDTH_8 (3<<0)
#define SD_IO_CCCR_CISPTR 0x09 /* XXX 9-10, 10-11, or 9-12 */
/* Function Basic Registers (FBR) */
@@ -90,6 +91,6 @@
#define SD_IO_CISTPL_END 0xff
/* CISTPL_FUNCID codes */
-#define SDMMC_FUNCTION_WLAN 0x0c
+#define TPLFID_FUNCTION_SDIO 0x0c
#endif