diff options
author | David E. O'Brien <obrien@FreeBSD.org> | 2004-11-01 17:21:04 +0000 |
---|---|---|
committer | David E. O'Brien <obrien@FreeBSD.org> | 2004-11-01 17:21:04 +0000 |
commit | 220df35f05a78a5e60cb9b5bfb6bf6b8cb19dcba (patch) | |
tree | c392b2435687a80d7a8b4a3ad8523116aff10537 /sys | |
parent | 164d3f0bdc12d7a6707d2bd80c96b29c67439bc9 (diff) | |
download | src-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.c | 35 | ||||
-rw-r--r-- | sys/dev/sk/if_skreg.h | 1 | ||||
-rw-r--r-- | sys/pci/if_sk.c | 35 | ||||
-rw-r--r-- | sys/pci/if_skreg.h | 1 |
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 */ |