summaryrefslogtreecommitdiffstats
path: root/sys/dev
diff options
context:
space:
mode:
authorjmg <jmg@FreeBSD.org>2006-10-09 16:15:56 +0000
committerjmg <jmg@FreeBSD.org>2006-10-09 16:15:56 +0000
commit6a8dfa76182b17f26de62b30dea11f79111400b7 (patch)
tree1d727b5091a8658d90d11ec0750cf847f4a210f6 /sys/dev
parent03ea52e1daed73beb0329e7b08c841ce9c831f6d (diff)
downloadFreeBSD-src-6a8dfa76182b17f26de62b30dea11f79111400b7.zip
FreeBSD-src-6a8dfa76182b17f26de62b30dea11f79111400b7.tar.gz
provide routines to access VPD data at the PCI layer...
remove sk's own implementation, and use the new calls to get the data... Reviewed by: -arch
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/pci.c342
-rw-r--r--sys/dev/pci/pci_if.m13
-rw-r--r--sys/dev/pci/pci_private.h4
-rw-r--r--sys/dev/pci/pcivar.h34
-rw-r--r--sys/dev/sk/if_sk.c155
-rw-r--r--sys/dev/sk/if_skreg.h31
6 files changed, 397 insertions, 182 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c
index 1816a26..ca4aee1 100644
--- a/sys/dev/pci/pci.c
+++ b/sys/dev/pci/pci.c
@@ -41,7 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/queue.h>
#include <sys/sysctl.h>
-#include <sys/types.h>
+#include <sys/endian.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -90,6 +90,13 @@ static int pci_modevent(module_t mod, int what, void *arg);
static void pci_hdrtypedata(device_t pcib, int b, int s, int f,
pcicfgregs *cfg);
static void pci_read_extcap(device_t pcib, pcicfgregs *cfg);
+static uint32_t pci_read_vpd_reg(device_t pcib, pcicfgregs *cfg,
+ int reg);
+#if 0
+static void pci_write_vpd_reg(device_t pcib, pcicfgregs *cfg,
+ int reg, uint32_t data);
+#endif
+static void pci_read_vpd(device_t pcib, pcicfgregs *cfg);
static device_method_t pci_methods[] = {
/* Device interface */
@@ -127,6 +134,8 @@ static device_method_t pci_methods[] = {
DEVMETHOD(pci_disable_busmaster, pci_disable_busmaster_method),
DEVMETHOD(pci_enable_io, pci_enable_io_method),
DEVMETHOD(pci_disable_io, pci_disable_io_method),
+ DEVMETHOD(pci_get_vpd_ident, pci_get_vpd_ident_method),
+ DEVMETHOD(pci_get_vpd_readonly, pci_get_vpd_readonly_method),
DEVMETHOD(pci_get_powerstate, pci_get_powerstate_method),
DEVMETHOD(pci_set_powerstate, pci_set_powerstate_method),
DEVMETHOD(pci_assign_interrupt, pci_assign_interrupt_method),
@@ -344,7 +353,6 @@ pci_hdrtypedata(device_t pcib, int b, int s, int f, pcicfgregs *cfg)
}
/* read configuration header into pcicfgregs structure */
-
struct pci_devinfo *
pci_read_device(device_t pcib, int b, int s, int f, size_t size)
{
@@ -428,7 +436,7 @@ pci_read_extcap(device_t pcib, pcicfgregs *cfg)
ptrptr = PCIR_CAP_PTR;
break;
case 2:
- ptrptr = PCIR_CAP_PTR_2;
+ ptrptr = PCIR_CAP_PTR_2; /* cardbus capabilities ptr */
break;
default:
return; /* no extended capabilities support */
@@ -468,13 +476,304 @@ pci_read_extcap(device_t pcib, pcicfgregs *cfg)
cfg->msi.msi_data = PCIR_MSI_DATA;
cfg->msi.msi_msgnum = 1 << ((cfg->msi.msi_ctrl &
PCIM_MSICTRL_MMC_MASK)>>1);
+ break;
+ case PCIY_VPD: /* PCI Vital Product Data */
+ cfg->vpd.vpd_reg = ptr;
+ pci_read_vpd(pcib, cfg);
+ break;
+ default:
+ break;
+ }
+ }
+/* REG use carry through to next functions */
+}
+
+/*
+ * PCI Vital Product Data
+ */
+static uint32_t
+pci_read_vpd_reg(device_t pcib, pcicfgregs *cfg, int reg)
+{
+#define WREG(n, v, w) PCIB_WRITE_CONFIG(pcib, cfg->bus, cfg->slot, cfg->func, n, v, w)
+
+ KASSERT((reg & 3) == 0, ("VPD register must by 4 byte aligned"));
+
+ WREG(cfg->vpd.vpd_reg + 2, reg, 2);
+ while ((REG(cfg->vpd.vpd_reg + 2, 2) & 0x8000) != 0x8000)
+ DELAY(1); /* limit looping */
+
+ return REG(cfg->vpd.vpd_reg + 4, 4);
+}
+
+#if 0
+static void
+pci_write_vpd_reg(device_t pcib, pcicfgregs *cfg, int reg, uint32_t data)
+{
+ KASSERT((reg & 3) == 0, ("VPD register must by 4 byte aligned"));
+
+ WREG(cfg->vpd.vpd_reg + 4, data, 4);
+ WREG(cfg->vpd.vpd_reg + 2, reg | 0x8000, 2);
+ while ((REG(cfg->vpd.vpd_reg + 2, 2) & 0x8000) == 0x8000)
+ DELAY(1); /* limit looping */
+
+ return;
+}
+#endif
+#undef WREG
+
+struct vpd_readstate {
+ device_t pcib;
+ pcicfgregs *cfg;
+ uint32_t val;
+ int bytesinval;
+ int off;
+ uint8_t cksum;
+};
+
+static uint8_t
+vpd_nextbyte(struct vpd_readstate *vrs)
+{
+ uint8_t byte;
+
+ if (vrs->bytesinval == 0) {
+ vrs->val = le32toh(pci_read_vpd_reg(vrs->pcib, vrs->cfg,
+ vrs->off));
+ vrs->off += 4;
+ byte = vrs->val & 0xff;
+ vrs->bytesinval = 3;
+ } else {
+ vrs->val = vrs->val >> 8;
+ byte = vrs->val & 0xff;
+ vrs->bytesinval--;
+ }
+
+ vrs->cksum += byte;
+ return byte;
+}
+
+static void
+pci_read_vpd(device_t pcib, pcicfgregs *cfg)
+{
+ struct vpd_readstate vrs;
+ int state;
+ int name;
+ int remain;
+ int end;
+ int i;
+ uint8_t byte;
+ int alloc, off; /* alloc/off for RO/W arrays */
+ int cksumvalid;
+ int dflen;
+
+ /* init vpd reader */
+ vrs.bytesinval = 0;
+ vrs.off = 0;
+ vrs.pcib = pcib;
+ vrs.cfg = cfg;
+ vrs.cksum = 0;
+
+ state = 0;
+ name = remain = i = 0; /* shut up stupid gcc */
+ alloc = off = 0; /* shut up stupid gcc */
+ dflen = 0; /* shut up stupid gcc */
+ end = 0;
+ cksumvalid = -1;
+ for (; !end;) {
+ byte = vpd_nextbyte(&vrs);
+#if 0
+ printf("vpd: val: %#x, off: %d, bytesinval: %d, byte: %#hhx, " \
+ "state: %d, remain: %d, name: %#x, i: %d\n", vrs.val,
+ vrs.off, vrs.bytesinval, byte, state, remain, name, i);
+#endif
+ switch (state) {
+ case 0: /* item name */
+ if (byte & 0x80) {
+ remain = vpd_nextbyte(&vrs);
+ remain |= vpd_nextbyte(&vrs) << 8;
+ if (remain > (0x7f*4 - vrs.off)) {
+ end = 1;
+ printf(
+ "pci%d:%d:%d: invalid vpd data, remain %#x\n",
+ cfg->bus, cfg->slot, cfg->func,
+ remain);
+ }
+ name = byte & 0x7f;
+ } else {
+ remain = byte & 0x7;
+ name = (byte >> 3) & 0xf;
+ }
+ switch (name) {
+ case 0x2: /* String */
+ cfg->vpd.vpd_ident = malloc(remain + 1,
+ M_DEVBUF, M_WAITOK);
+ i = 0;
+ state = 1;
+ break;
+ case 0xf: /* End */
+ end = 1;
+ state = -1;
+ break;
+ case 0x10: /* VPD-R */
+ alloc = 8;
+ off = 0;
+ cfg->vpd.vpd_ros = malloc(alloc *
+ sizeof *cfg->vpd.vpd_ros, M_DEVBUF,
+ M_WAITOK);
+ state = 2;
+ break;
+ case 0x11: /* VPD-W */
+ alloc = 8;
+ off = 0;
+ cfg->vpd.vpd_w = malloc(alloc *
+ sizeof *cfg->vpd.vpd_w, M_DEVBUF,
+ M_WAITOK);
+ state = 5;
+ break;
+ default: /* XXX - unimplemented */
+ state = 4;
+ break;
+ }
+ break;
+
+ case 1: /* Identifier String */
+ cfg->vpd.vpd_ident[i++] = byte;
+ remain--;
+ if (remain == 0) {
+ cfg->vpd.vpd_ident[i] = '\0';
+ state = 0;
+ }
+ break;
+
+ case 2: /* VPD-R Keyword Header */
+ if (off == alloc) {
+ cfg->vpd.vpd_ros = reallocf(cfg->vpd.vpd_ros,
+ (alloc *= 2) * sizeof *cfg->vpd.vpd_ros,
+ M_DEVBUF, M_WAITOK);
+ }
+ cfg->vpd.vpd_ros[off].keyword[0] = byte;
+ cfg->vpd.vpd_ros[off].keyword[1] = vpd_nextbyte(&vrs);
+ dflen = vpd_nextbyte(&vrs);
+ cfg->vpd.vpd_ros[off].value = malloc((dflen + 1) *
+ sizeof *cfg->vpd.vpd_ros[off].value,
+ M_DEVBUF, M_WAITOK);
+ remain -= 3;
+ i = 0;
+ state = 3;
+ break;
+
+ case 3: /* VPD-R Keyword Value */
+ cfg->vpd.vpd_ros[off].value[i++] = byte;
+ if (strncmp(cfg->vpd.vpd_ros[off].keyword,
+ "RV", 2) == 0 && cksumvalid == -1) {
+ if (vrs.cksum == 0)
+ cksumvalid = 1;
+ else {
+ printf(
+ "pci%d:%d:%d: bad VPD cksum, remain %hhu\n",
+ cfg->bus, cfg->slot, cfg->func,
+ vrs.cksum);
+ cksumvalid = 0;
+ }
+ }
+ dflen--;
+ remain--;
+ if (dflen == 0)
+ cfg->vpd.vpd_ros[off++].value[i++] = '\0';
+ if (dflen == 0 && remain == 0) {
+ cfg->vpd.vpd_rocnt = off;
+ cfg->vpd.vpd_ros = reallocf(cfg->vpd.vpd_ros,
+ off * sizeof *cfg->vpd.vpd_ros,
+ M_DEVBUF, M_WAITOK);
+ state = 0;
+ } else if (dflen == 0)
+ state = 2;
+ break;
+
+ case 4:
+ remain--;
+ if (remain == 0)
+ state = 0;
+ break;
+
+ case 5: /* VPD-W Keyword Header */
+ if (off == alloc) {
+ cfg->vpd.vpd_w = reallocf(cfg->vpd.vpd_w,
+ (alloc *= 2) * sizeof *cfg->vpd.vpd_w,
+ M_DEVBUF, M_WAITOK);
+ }
+ cfg->vpd.vpd_w[off].keyword[0] = byte;
+ cfg->vpd.vpd_w[off].keyword[1] = vpd_nextbyte(&vrs);
+ cfg->vpd.vpd_w[off].len = dflen = vpd_nextbyte(&vrs);
+ cfg->vpd.vpd_w[off].start = vrs.off - vrs.bytesinval;
+ cfg->vpd.vpd_w[off].value = malloc((dflen + 1) *
+ sizeof *cfg->vpd.vpd_w[off].value,
+ M_DEVBUF, M_WAITOK);
+ remain -= 3;
+ i = 0;
+ state = 6;
+ break;
+
+ case 6: /* VPD-W Keyword Value */
+ cfg->vpd.vpd_w[off].value[i++] = byte;
+ dflen--;
+ remain--;
+ if (dflen == 0)
+ cfg->vpd.vpd_w[off++].value[i++] = '\0';
+ if (dflen == 0 && remain == 0) {
+ cfg->vpd.vpd_wcnt = off;
+ cfg->vpd.vpd_w = reallocf(cfg->vpd.vpd_w,
+ off * sizeof *cfg->vpd.vpd_w,
+ M_DEVBUF, M_WAITOK);
+ state = 0;
+ } else if (dflen == 0)
+ state = 5;
+ break;
+
default:
+ printf("pci%d:%d:%d: invalid state: %d\n",
+ cfg->bus, cfg->slot, cfg->func, state);
+ end = 1;
break;
}
}
#undef REG
}
+int
+pci_get_vpd_ident_method(device_t dev, device_t child, const char **identptr)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+
+ *identptr = cfg->vpd.vpd_ident;
+
+ if (*identptr == NULL)
+ return ENXIO;
+
+ return 0;
+}
+
+int
+pci_get_vpd_readonly_method(device_t dev, device_t child, const char *kw,
+ const char **vptr)
+{
+ struct pci_devinfo *dinfo = device_get_ivars(child);
+ pcicfgregs *cfg = &dinfo->cfg;
+ int i;
+
+ for (i = 0; i < cfg->vpd.vpd_rocnt; i++)
+ if (memcmp(kw, cfg->vpd.vpd_ros[i].keyword,
+ sizeof cfg->vpd.vpd_ros[i].keyword) == 0) {
+ *vptr = cfg->vpd.vpd_ros[i].value;
+ }
+
+ if (i != cfg->vpd.vpd_rocnt)
+ return 0;
+
+ *vptr = NULL;
+ return ENXIO;
+}
+
/*
* Return the offset in configuration space of the requested extended
* capability entry or 0 if the specified capability was not found.
@@ -532,9 +831,19 @@ int
pci_freecfg(struct pci_devinfo *dinfo)
{
struct devlist *devlist_head;
+ int i;
devlist_head = &pci_devq;
+ if (dinfo->cfg.vpd.vpd_reg) {
+ free(dinfo->cfg.vpd.vpd_ident, M_DEVBUF);
+ for (i = 0; i < dinfo->cfg.vpd.vpd_rocnt; i++)
+ free(dinfo->cfg.vpd.vpd_ros[i].value, M_DEVBUF);
+ free(dinfo->cfg.vpd.vpd_ros, M_DEVBUF);
+ for (i = 0; i < dinfo->cfg.vpd.vpd_wcnt; i++)
+ free(dinfo->cfg.vpd.vpd_w[i].value, M_DEVBUF);
+ free(dinfo->cfg.vpd.vpd_w, M_DEVBUF);
+ }
STAILQ_REMOVE(devlist_head, dinfo, pci_devinfo, pci_links);
free(dinfo, M_DEVBUF);
@@ -766,6 +1075,8 @@ pci_disable_io_method(device_t dev, device_t child, int space)
void
pci_print_verbose(struct pci_devinfo *dinfo)
{
+ int i;
+
if (bootverbose) {
pcicfgregs *cfg = &dinfo->cfg;
@@ -794,6 +1105,31 @@ pci_print_verbose(struct pci_devinfo *dinfo)
cfg->pp.pp_cap & PCIM_PCAP_D2SUPP ? " D2" : "",
status & PCIM_PSTAT_DMASK);
}
+ if (cfg->vpd.vpd_reg) {
+ printf("\tVPD Ident: %s\n", cfg->vpd.vpd_ident);
+ for (i = 0; i < cfg->vpd.vpd_rocnt; i++) {
+ struct vpd_readonly *vrop;
+ vrop = &cfg->vpd.vpd_ros[i];
+ if (strncmp("CP", vrop->keyword, 2) == 0)
+ printf("CP: id %d, BAR%d, off %#x\n",
+ vrop->value[0], vrop->value[1],
+ le16toh(
+ *(uint16_t *)&vrop->value[2]));
+ else if (strncmp("RV", vrop->keyword, 2) == 0)
+ printf("RV: %#hhx\n", vrop->value[0]);
+ else
+ printf("\t%.2s: %s\n", vrop->keyword,
+ vrop->value);
+ }
+ for (i = 0; i < cfg->vpd.vpd_wcnt; i++) {
+ struct vpd_write *vwp;
+ vwp = &cfg->vpd.vpd_w[i];
+ if (strncmp("RW", vwp->keyword, 2) != 0)
+ printf("\t%.2s(%#x-%#x): %s\n",
+ vwp->keyword, vwp->start,
+ vwp->start + vwp->len, vwp->value);
+ }
+ }
if (cfg->msi.msi_data) {
int ctrl;
diff --git a/sys/dev/pci/pci_if.m b/sys/dev/pci/pci_if.m
index 0de5696..df2456a 100644
--- a/sys/dev/pci/pci_if.m
+++ b/sys/dev/pci/pci_if.m
@@ -56,6 +56,19 @@ METHOD int set_powerstate {
int state;
};
+METHOD int get_vpd_ident {
+ device_t dev;
+ device_t child;
+ const char **identptr;
+};
+
+METHOD int get_vpd_readonly {
+ device_t dev;
+ device_t child;
+ const char *kw;
+ const char **vptr;
+};
+
METHOD int enable_busmaster {
device_t dev;
device_t child;
diff --git a/sys/dev/pci/pci_private.h b/sys/dev/pci/pci_private.h
index b6bbaa0..dc1866f 100644
--- a/sys/dev/pci/pci_private.h
+++ b/sys/dev/pci/pci_private.h
@@ -49,6 +49,10 @@ int pci_read_ivar(device_t dev, device_t child, int which,
uintptr_t *result);
int pci_write_ivar(device_t dev, device_t child, int which,
uintptr_t value);
+int pci_get_vpd_ident_method(device_t dev, device_t child,
+ const char **identptr);
+int pci_get_vpd_readonly_method(device_t dev, device_t child,
+ const char *kw, const char **vptr);
int pci_set_powerstate_method(device_t dev, device_t child,
int state);
int pci_get_powerstate_method(device_t dev, device_t child);
diff --git a/sys/dev/pci/pcivar.h b/sys/dev/pci/pcivar.h
index ade206a..fc37941 100644
--- a/sys/dev/pci/pcivar.h
+++ b/sys/dev/pci/pcivar.h
@@ -59,6 +59,27 @@ struct pcicfg_pp {
uint8_t pp_data; /* config space address of PCI power data reg */
};
+struct vpd_readonly {
+ char keyword[2];
+ char *value;
+};
+
+struct vpd_write {
+ char keyword[2];
+ char *value;
+ int start;
+ int len;
+};
+
+struct pcicfg_vpd {
+ uint8_t vpd_reg; /* base register, + 2 for addr, + 4 data */
+ char *vpd_ident; /* string identifier */
+ int vpd_rocnt;
+ struct vpd_readonly *vpd_ros;
+ int vpd_wcnt;
+ struct vpd_write *vpd_w;
+};
+
/* Interesting values for PCI MSI */
struct pcicfg_msi {
uint16_t msi_ctrl; /* Message Control */
@@ -103,6 +124,7 @@ typedef struct pcicfg {
uint8_t func; /* config space function number */
struct pcicfg_pp pp; /* pci power management */
+ struct pcicfg_vpd vpd; /* pci vital product data */
struct pcicfg_msi msi; /* pci msi */
} pcicfgregs;
@@ -292,6 +314,18 @@ pci_disable_io(device_t dev, int space)
return(PCI_DISABLE_IO(device_get_parent(dev), dev, space));
}
+static __inline int
+pci_get_vpd_ident(device_t dev, const char **identptr)
+{
+ return(PCI_GET_VPD_IDENT(device_get_parent(dev), dev, identptr));
+}
+
+static __inline int
+pci_get_vpd_readonly(device_t dev, const char *kw, const char **identptr)
+{
+ return(PCI_GET_VPD_READONLY(device_get_parent(dev), dev, kw, identptr));
+}
+
/*
* Check if the address range falls within the VGA defined address range(s)
*/
diff --git a/sys/dev/sk/if_sk.c b/sys/dev/sk/if_sk.c
index dfc0e5e..19c946c 100644
--- a/sys/dev/sk/if_sk.c
+++ b/sys/dev/sk/if_sk.c
@@ -256,9 +256,6 @@ static u_int8_t sk_win_read_1(struct sk_softc *, int);
static void sk_win_write_4(struct sk_softc *, int, u_int32_t);
static void sk_win_write_2(struct sk_softc *, int, u_int32_t);
static void sk_win_write_1(struct sk_softc *, int, u_int32_t);
-static u_int8_t sk_vpd_readbyte(struct sk_softc *, int);
-static void sk_vpd_read_res(struct sk_softc *, struct vpd_res *, int);
-static void sk_vpd_read(struct sk_softc *);
static int sk_miibus_readreg(device_t, int, int);
static int sk_miibus_writereg(device_t, int, int, int);
@@ -472,113 +469,6 @@ sk_win_write_1(sc, reg, val)
return;
}
-/*
- * The VPD EEPROM contains Vital Product Data, as suggested in
- * the PCI 2.1 specification. The VPD data is separared into areas
- * denoted by resource IDs. The SysKonnect VPD contains an ID string
- * resource (the name of the adapter), a read-only area resource
- * containing various key/data fields and a read/write area which
- * can be used to store asset management information or log messages.
- * We read the ID string and read-only into buffers attached to
- * the controller softc structure for later use. At the moment,
- * we only use the ID string during skc_attach().
- */
-static u_int8_t
-sk_vpd_readbyte(sc, addr)
- struct sk_softc *sc;
- int addr;
-{
- int i;
-
- sk_win_write_2(sc, SK_PCI_REG(SK_PCI_VPD_ADDR), addr);
- for (i = 0; i < SK_TIMEOUT; i++) {
- /* ASUS LOM takes a very long time to read VPD. */
- DELAY(100);
- if (sk_win_read_2(sc,
- SK_PCI_REG(SK_PCI_VPD_ADDR)) & SK_VPD_FLAG)
- break;
- }
-
- if (i == SK_TIMEOUT)
- return(0);
-
- return(sk_win_read_1(sc, SK_PCI_REG(SK_PCI_VPD_DATA)));
-}
-
-static void
-sk_vpd_read_res(sc, res, addr)
- struct sk_softc *sc;
- struct vpd_res *res;
- int addr;
-{
- int i;
- u_int8_t *ptr;
-
- ptr = (u_int8_t *)res;
- for (i = 0; i < sizeof(struct vpd_res); i++)
- ptr[i] = sk_vpd_readbyte(sc, i + addr);
-
- return;
-}
-
-static void
-sk_vpd_read(sc)
- struct sk_softc *sc;
-{
- int pos = 0, i;
- struct vpd_res res;
-
- /* Check VPD capability */
- if (sk_win_read_1(sc, SK_PCI_REG(SK_PCI_VPD_CAPID)) != PCIY_VPD)
- return;
- if (sc->sk_vpd_prodname != NULL)
- free(sc->sk_vpd_prodname, M_DEVBUF);
- if (sc->sk_vpd_readonly != NULL)
- 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);
-
- /*
- * Bail out quietly if the eeprom appears to be missing or empty.
- */
- if (res.vr_id == 0xff && res.vr_len == 0xff && res.vr_pad == 0xff)
- return;
-
- if (res.vr_id != VPD_RES_ID) {
- device_printf(sc->sk_dev, "bad VPD resource id: expected %x "
- "got %x\n", VPD_RES_ID, res.vr_id);
- return;
- }
-
- pos += sizeof(res);
- sc->sk_vpd_prodname = malloc(res.vr_len + 1, M_DEVBUF, M_NOWAIT);
- if (sc->sk_vpd_prodname != NULL) {
- for (i = 0; i < res.vr_len; i++)
- sc->sk_vpd_prodname[i] = sk_vpd_readbyte(sc, i + pos);
- sc->sk_vpd_prodname[i] = '\0';
- }
- pos += res.vr_len;
-
- sk_vpd_read_res(sc, &res, pos);
-
- if (res.vr_id != VPD_RES_READ) {
- device_printf(sc->sk_dev, "bad VPD resource id: expected %x "
- "got %x\n", VPD_RES_READ, res.vr_id);
- return;
- }
-
- pos += sizeof(res);
- sc->sk_vpd_readonly = malloc(res.vr_len, M_DEVBUF, M_NOWAIT);
- 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;
-}
-
static int
sk_miibus_readreg(dev, phy, reg)
device_t dev;
@@ -1690,7 +1580,8 @@ skc_attach(dev)
struct sk_softc *sc;
int error = 0, *port, sk_macs;
uint8_t skrs;
- char *pname, *revstr;
+ const char *pname;
+ char *revstr;
sc = device_get_softc(dev);
sc->sk_dev = dev;
@@ -1757,9 +1648,6 @@ skc_attach(dev)
/* Reset the adapter. */
sk_reset(sc);
- /* Read and save vital product data from EEPROM. */
- sk_vpd_read(sc);
-
skrs = sk_win_read_1(sc, SK_EPROM0);
if (sc->sk_type == SK_GENESIS) {
/* Read and save RAM size and RAMbuffer offset */
@@ -1811,7 +1699,8 @@ skc_attach(dev)
case DEVICEID_DLINK_DGE530T_A1:
case DEVICEID_DLINK_DGE530T_B1:
/* Stay with VPD PN. */
- pname = sc->sk_vpd_prodname;
+ if (pci_get_vpd_ident(dev, &pname))
+ goto vpdfailed;
break;
case DEVICEID_SK_V2:
case DEVICEID_MRVL_4360:
@@ -1821,7 +1710,8 @@ skc_attach(dev)
switch (sc->sk_type) {
case SK_GENESIS:
/* Stay with VPD PN. */
- pname = sc->sk_vpd_prodname;
+ if (pci_get_vpd_ident(dev, &pname))
+ goto vpdfailed;
break;
case SK_YUKON:
pname = "Marvell Yukon Gigabit Ethernet";
@@ -1861,6 +1751,7 @@ skc_attach(dev)
}
break;
default:
+vpdfailed:
device_printf(dev, "unknown device: vendor=%04x, device=%04x, "
"chipver=%02x, rev=%x\n",
pci_get_vendor(dev), pci_get_device(dev),
@@ -1908,33 +1799,6 @@ skc_attach(dev)
pname != NULL ? pname : "<unknown>", revstr, sc->sk_rev);
if (bootverbose) {
- 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';
- device_printf(dev, "%c%c: %s\n",
- *dp, *(dp+1), buf);
- len -= (3 + l);
- dp += (3 + l);
- } else {
- len -= (3 + *(dp+2));
- dp += (3 + *(dp+2));
- }
- }
- }
device_printf(dev, "chip ver = 0x%02x\n", sc->sk_type);
device_printf(dev, "chip rev = 0x%02x\n", sc->sk_rev);
device_printf(dev, "SK_EPROM0 = 0x%02x\n", skrs);
@@ -2084,11 +1948,6 @@ skc_detach(dev)
bus_generic_detach(dev);
}
- if (sc->sk_vpd_prodname != NULL)
- free(sc->sk_vpd_prodname, M_DEVBUF);
- if (sc->sk_vpd_readonly != NULL)
- free(sc->sk_vpd_readonly, M_DEVBUF);
-
if (sc->sk_intrhand)
bus_teardown_intr(dev, sc->sk_res[1], sc->sk_intrhand);
bus_release_resources(dev, sc->sk_res_spec, sc->sk_res);
diff --git a/sys/dev/sk/if_skreg.h b/sys/dev/sk/if_skreg.h
index a9fa27c..937c5f7 100644
--- a/sys/dev/sk/if_skreg.h
+++ b/sys/dev/sk/if_skreg.h
@@ -1290,10 +1290,6 @@
#define SK_PCI_PWRMGMTCAP 0x004A /* 16 bits */
#define SK_PCI_PWRMGMTCTRL 0x004C /* 16 bits */
#define SK_PCI_PME_EVENT 0x004F
-#define SK_PCI_VPD_CAPID 0x0050
-#define SK_PCI_VPD_NEXTPTR 0x0051
-#define SK_PCI_VPD_ADDR 0x0052
-#define SK_PCI_VPD_DATA 0x0054
#define SK_PSTATE_MASK 0x0003
#define SK_PSTATE_D0 0x0000
@@ -1303,30 +1299,6 @@
#define SK_PME_EN 0x0010
#define SK_PME_STATUS 0x8000
-/*
- * VPD flag bit. Set to 0 to initiate a read, will become 1 when
- * read is complete. Set to 1 to initiate a write, will become 0
- * when write is finished.
- */
-#define SK_VPD_FLAG 0x8000
-
-/* VPD structures */
-struct vpd_res {
- u_int8_t vr_id;
- u_int8_t vr_len;
- u_int8_t vr_pad;
-};
-
-struct vpd_key {
- char vk_key[2];
- u_int8_t vk_len;
-};
-
-#define VPD_RES_ID 0x82 /* ID string */
-#define VPD_RES_READ 0x90 /* start of read only area */
-#define VPD_RES_WRITE 0x81 /* start of read/write area */
-#define VPD_RES_END 0x78 /* end tag */
-
#define CSR_WRITE_4(sc, reg, val) \
bus_write_4((sc)->sk_res[0], (reg), (val))
#define CSR_WRITE_2(sc, reg, val) \
@@ -1528,9 +1500,6 @@ struct sk_softc {
u_int8_t sk_type;
u_int8_t sk_rev;
u_int8_t spare;
- 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 */
OpenPOWER on IntegriCloud