aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorDavid E. O'Brien <obrien@FreeBSD.org>2004-11-01 17:21:04 +0000
committerDavid E. O'Brien <obrien@FreeBSD.org>2004-11-01 17:21:04 +0000
commit220df35f05a78a5e60cb9b5bfb6bf6b8cb19dcba (patch)
treec392b2435687a80d7a8b4a3ad8523116aff10537 /sys
parent164d3f0bdc12d7a6707d2bd80c96b29c67439bc9 (diff)
downloadsrc-220df35f05a78a5e60cb9b5bfb6bf6b8cb19dcba.tar.gz
src-220df35f05a78a5e60cb9b5bfb6bf6b8cb19dcba.zip
* Correct an off-by-one reading vpd ro data.
* Announce some more fields from ro area for better debugging of broken sk(4)s on various boards. Submitted by: Bjoern A. Zeeb <bzeeb-lists@lists.zabbadoz.net>
Notes
Notes: svn path=/head/; revision=137111
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/sk/if_sk.c35
-rw-r--r--sys/dev/sk/if_skreg.h1
-rw-r--r--sys/pci/if_sk.c35
-rw-r--r--sys/pci/if_skreg.h1
4 files changed, 66 insertions, 6 deletions
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index 49ad9e2b36f4..d00980a3cb59 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -473,6 +473,7 @@ sk_vpd_read(sc)
free(sc->sk_vpd_readonly, M_DEVBUF);
sc->sk_vpd_prodname = NULL;
sc->sk_vpd_readonly = NULL;
+ sc->sk_vpd_readonly_len = 0;
sk_vpd_read_res(sc, &res, pos);
@@ -505,8 +506,9 @@ sk_vpd_read(sc)
pos += sizeof(res);
sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
- for (i = 0; i < res.vr_len + 1; i++)
+ for (i = 0; i < res.vr_len; i++)
sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos);
+ sc->sk_vpd_readonly_len = res.vr_len;
return;
}
@@ -1612,9 +1614,36 @@ skc_attach(dev)
goto fail;
}
- /* Announce the product name. */
+ /* Announce the product name and more VPD data if there. */
if (sc->sk_vpd_prodname != NULL)
- printf("skc%d: %s\n", sc->sk_unit, sc->sk_vpd_prodname);
+ printf("skc%d: %s\n", sc->sk_unit, sc->sk_vpd_prodname);
+ if (sc->sk_vpd_readonly != NULL && sc->sk_vpd_readonly_len != 0) {
+ char buf[256];
+ char *dp = sc->sk_vpd_readonly;
+ uint16_t l, len = sc->sk_vpd_readonly_len;
+
+ while (len >= 3) {
+ if ( (*dp == 'P' && *(dp+1) == 'N') ||
+ (*dp == 'E' && *(dp+1) == 'C') ||
+ (*dp == 'M' && *(dp+1) == 'N') ||
+ (*dp == 'S' && *(dp+1) == 'N') ) {
+
+ l = 0;
+ while(l < *(dp+2)) {
+ buf[l] = *(dp+3+l);
+ ++l;
+ }
+ buf[l] = '\0';
+ printf("skc%d: %c%c: %s\n",
+ sc->sk_unit, *dp, *(dp+1), buf);
+ len -= (3 + l);
+ dp += (3 + l);
+ } else {
+ len -= (3 + *(dp+2));
+ dp += (3 + *(dp+2));
+ }
+ }
+ }
sc->sk_devs[SK_PORT_A] = device_add_child(dev, "sk", -1);
port = malloc(sizeof(int), M_DEVBUF, M_NOWAIT);
*port = SK_PORT_A;
diff --git a/sys/dev/sk/if_skreg.h b/sys/dev/sk/if_skreg.h
index 2ef61c456945..8271c037c7a7 100644
--- a/sys/dev/sk/if_skreg.h
+++ b/sys/dev/sk/if_skreg.h
@@ -1427,6 +1427,7 @@ struct sk_softc {
u_int8_t sk_type;
char *sk_vpd_prodname;
char *sk_vpd_readonly;
+ uint16_t sk_vpd_readonly_len;
u_int32_t sk_rboff; /* RAMbuffer offset */
u_int32_t sk_ramsize; /* amount of RAM on NIC */
u_int32_t sk_pmd; /* physical media type */
diff --git a/sys/pci/if_sk.c b/sys/pci/if_sk.c
index 49ad9e2b36f4..d00980a3cb59 100644
--- a/sys/pci/if_sk.c
+++ b/sys/pci/if_sk.c
@@ -473,6 +473,7 @@ sk_vpd_read(sc)
free(sc->sk_vpd_readonly, M_DEVBUF);
sc->sk_vpd_prodname = NULL;
sc->sk_vpd_readonly = NULL;
+ sc->sk_vpd_readonly_len = 0;
sk_vpd_read_res(sc, &res, pos);
@@ -505,8 +506,9 @@ sk_vpd_read(sc)
pos += sizeof(res);
sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
- for (i = 0; i < res.vr_len + 1; i++)
+ for (i = 0; i < res.vr_len; i++)
sc->sk_vpd_readonly[i] = sk_vpd_readbyte(sc, i + pos);
+ sc->sk_vpd_readonly_len = res.vr_len;
return;
}
@@ -1612,9 +1614,36 @@ skc_attach(dev)
goto fail;
}
- /* Announce the product name. */
+ /* Announce the product name and more VPD data if there. */
if (sc->sk_vpd_prodname != NULL)
- printf("skc%d: %s\n", sc->sk_unit, sc->sk_vpd_prodname);
+ printf("skc%d: %s\n", sc->sk_unit, sc->sk_vpd_prodname);
+ if (sc->sk_vpd_readonly != NULL && sc->sk_vpd_readonly_len != 0) {
+ char buf[256];
+ char *dp = sc->sk_vpd_readonly;
+ uint16_t l, len = sc->sk_vpd_readonly_len;
+
+ while (len >= 3) {
+ if ( (*dp == 'P' && *(dp+1) == 'N') ||
+ (*dp == 'E' && *(dp+1) == 'C') ||
+ (*dp == 'M' && *(dp+1) == 'N') ||
+ (*dp == 'S' && *(dp+1) == 'N') ) {
+
+ l = 0;
+ while(l < *(dp+2)) {
+ buf[l] = *(dp+3+l);
+ ++l;
+ }
+ buf[l] = '\0';
+ printf("skc%d: %c%c: %s\n",
+ sc->sk_unit, *dp, *(dp+1), buf);
+ len -= (3 + l);
+ dp += (3 + l);
+ } else {
+ len -= (3 + *(dp+2));
+ dp += (3 + *(dp+2));
+ }
+ }
+ }
sc->sk_devs[SK_PORT_A] = device_add_child(dev, "sk", -1);
port = malloc(sizeof(int), M_DEVBUF, M_NOWAIT);
*port = SK_PORT_A;
diff --git a/sys/pci/if_skreg.h b/sys/pci/if_skreg.h
index 2ef61c456945..8271c037c7a7 100644
--- a/sys/pci/if_skreg.h
+++ b/sys/pci/if_skreg.h
@@ -1427,6 +1427,7 @@ struct sk_softc {
u_int8_t sk_type;
char *sk_vpd_prodname;
char *sk_vpd_readonly;
+ uint16_t sk_vpd_readonly_len;
u_int32_t sk_rboff; /* RAMbuffer offset */
u_int32_t sk_ramsize; /* amount of RAM on NIC */
u_int32_t sk_pmd; /* physical media type */