summaryrefslogtreecommitdiff
path: root/sys/arch/sgi
diff options
context:
space:
mode:
Diffstat (limited to 'sys/arch/sgi')
-rw-r--r--sys/arch/sgi/dev/owmac.c186
-rw-r--r--sys/arch/sgi/dev/owmacvar.h35
-rw-r--r--sys/arch/sgi/dev/owmem_subr.c46
-rw-r--r--sys/arch/sgi/dev/owmem_subr.h25
-rw-r--r--sys/arch/sgi/dev/owserial.c217
-rw-r--r--sys/arch/sgi/dev/owserialvar.h39
6 files changed, 548 insertions, 0 deletions
diff --git a/sys/arch/sgi/dev/owmac.c b/sys/arch/sgi/dev/owmac.c
new file mode 100644
index 00000000000..c178a3591aa
--- /dev/null
+++ b/sys/arch/sgi/dev/owmac.c
@@ -0,0 +1,186 @@
+/* $OpenBSD: owmac.c,v 1.1 2008/04/07 22:55:57 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DS1981/1982/2502 1-Wire Add-only memory driver, for SGI machines.
+ *
+ * SGI uses DS1981 (or compatibles) to store the Ethernet address
+ * on IOC boards.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+
+#include <dev/onewire/onewiredevs.h>
+#include <dev/onewire/onewirereg.h>
+#include <dev/onewire/onewirevar.h>
+
+#include <sgi/dev/owmem_subr.h>
+#include <sgi/dev/owmacvar.h>
+
+int owmac_match(struct device *, void *, void *);
+void owmac_attach(struct device *, struct device *, void *);
+
+struct cfattach owmac_ca = {
+ sizeof(struct owmac_softc), owmac_match, owmac_attach,
+};
+
+struct cfdriver owmac_cd = {
+ NULL, "owmac", DV_DULL
+};
+
+#define EEPROM_NPAGES 4
+
+static const struct onewire_matchfam owmac_fams[] = {
+ { ONEWIRE_FAMILY_DS1982 }
+};
+
+int owmac_read_page(struct owmac_softc *, int, uint8_t *);
+int owmac_read_redirect(struct owmac_softc *);
+
+void owmac_read_mac(struct owmac_softc *);
+
+int
+owmac_match(struct device *parent, void *match, void *aux)
+{
+ return (onewire_matchbyfam(aux, owmac_fams,
+ sizeof(owmac_fams) /sizeof(owmac_fams[0])));
+}
+
+void
+owmac_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct owmac_softc *sc = (struct owmac_softc *)self;
+ struct onewire_attach_args *oa = aux;
+
+ sc->sc_onewire = oa->oa_onewire;
+ sc->sc_rom = oa->oa_rom;
+
+ /*
+ * Read the redirection table.
+ */
+ if (owmac_read_redirect(sc) != 0) {
+ printf(": unable to read redirection data\n");
+ return;
+ }
+
+ printf("\n");
+
+ /*
+ * Read the data.
+ */
+ owmac_read_mac(sc);
+}
+
+int
+owmac_read_redirect(struct owmac_softc *sc)
+{
+ int rc = 0;
+ int status_offset;
+
+ status_offset = 0x0001; /* 1..4 */
+
+ onewire_lock(sc->sc_onewire, 0);
+ if ((rc = onewire_reset(sc->sc_onewire)) != 0)
+ goto unlock;
+
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+
+ /*
+ * Start reading the EEPROM status block, at the page redirection
+ * offset.
+ */
+ onewire_write_byte(sc->sc_onewire, ONEWIRE_CMD_READ_STATUS);
+ onewire_write_byte(sc->sc_onewire, status_offset & 0xff);
+ onewire_write_byte(sc->sc_onewire, status_offset >> 8);
+ /* XXX should verify this crc value */
+ (void)onewire_read_byte(sc->sc_onewire);
+
+ onewire_read_block(sc->sc_onewire, &sc->sc_redir, EEPROM_NPAGES);
+
+ onewire_reset(sc->sc_onewire);
+unlock:
+ onewire_unlock(sc->sc_onewire);
+
+ return rc;
+}
+
+int
+owmac_read_page(struct owmac_softc *sc, int page, uint8_t *buf)
+{
+ int rc = 0;
+ int pg;
+
+ /*
+ * Follow the redirection information.
+ */
+ if ((pg = owmem_redirect(sc->sc_redir, EEPROM_NPAGES, page)) < 0)
+ return EINVAL;
+
+ pg = page * EEPROM_PAGE_SIZE;
+
+ onewire_lock(sc->sc_onewire, 0);
+ if ((rc = onewire_reset(sc->sc_onewire)) != 0)
+ goto unlock;
+
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+
+ /*
+ * Start reading the EEPROM data.
+ */
+ onewire_write_byte(sc->sc_onewire, ONEWIRE_CMD_READ_MEMORY);
+ onewire_write_byte(sc->sc_onewire, pg & 0xff);
+ onewire_write_byte(sc->sc_onewire, 0);
+ /* XXX should verify this crc value */
+ (void)onewire_read_byte(sc->sc_onewire);
+
+ onewire_read_block(sc->sc_onewire, buf, EEPROM_PAGE_SIZE);
+
+ onewire_reset(sc->sc_onewire);
+unlock:
+ onewire_unlock(sc->sc_onewire);
+
+ return rc;
+}
+
+void
+owmac_read_mac(struct owmac_softc *sc)
+{
+ uint8_t buf[EEPROM_PAGE_SIZE];
+
+ if (owmac_read_page(sc, 0, buf) != 0)
+ return;
+
+ if (buf[0] != 0x0a)
+ return;
+
+ sc->sc_enaddr[0] = buf[10];
+ sc->sc_enaddr[1] = buf[9];
+ sc->sc_enaddr[2] = buf[0];
+ sc->sc_enaddr[3] = buf[7];
+ sc->sc_enaddr[4] = buf[6];
+ sc->sc_enaddr[5] = buf[5];
+
+ printf("%s: Ethernet Address %02x:%02x:%02x:%02x:%02x:%02x\n",
+ sc->sc_dev.dv_xname,
+ sc->sc_enaddr[0], sc->sc_enaddr[1], sc->sc_enaddr[2],
+ sc->sc_enaddr[3], sc->sc_enaddr[4], sc->sc_enaddr[5]);
+}
diff --git a/sys/arch/sgi/dev/owmacvar.h b/sys/arch/sgi/dev/owmacvar.h
new file mode 100644
index 00000000000..14b6456dcb5
--- /dev/null
+++ b/sys/arch/sgi/dev/owmacvar.h
@@ -0,0 +1,35 @@
+/* $OpenBSD: owmacvar.h,v 1.1 2008/04/07 22:55:57 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DS1981/1982/2502 1-Wire Add-only memory driver, for SGI machines.
+ *
+ * SGI uses DS1981 (or compatibles) to store the Ethernet address
+ * on IOC boards.
+ */
+
+struct owmac_softc {
+ struct device sc_dev;
+
+ void *sc_onewire;
+ uint64_t sc_rom;
+
+ uint8_t sc_redir[4]; /* redirection table */
+
+ uint8_t sc_enaddr[6];
+};
diff --git a/sys/arch/sgi/dev/owmem_subr.c b/sys/arch/sgi/dev/owmem_subr.c
new file mode 100644
index 00000000000..3ae3ca89c52
--- /dev/null
+++ b/sys/arch/sgi/dev/owmem_subr.c
@@ -0,0 +1,46 @@
+/* $OpenBSD: owmem_subr.c,v 1.1 2008/04/07 22:55:57 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Common routines to owmac and owserial drivers.
+ */
+
+#include <sys/param.h>
+
+#include <sgi/dev/owmem_subr.h>
+
+int
+owmem_redirect(uint8_t *redir, u_int npages, u_int page)
+{
+ int skips = 0;
+
+ /*
+ * Follow the redirecting table until we end up in our final
+ * position. We have to be careful not to loop if the table
+ * is wrong.
+ */
+ while (redir[page] != 0xff) {
+ if (++skips >= npages)
+ return -1;
+ page = 0xff ^ redir[page];
+ if (page >= npages)
+ return -1;
+ }
+
+ return page;
+}
diff --git a/sys/arch/sgi/dev/owmem_subr.h b/sys/arch/sgi/dev/owmem_subr.h
new file mode 100644
index 00000000000..2e955c89f25
--- /dev/null
+++ b/sys/arch/sgi/dev/owmem_subr.h
@@ -0,0 +1,25 @@
+/* $OpenBSD: owmem_subr.h,v 1.1 2008/04/07 22:55:57 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * Common routines to owmac and owserial drivers.
+ */
+
+#define EEPROM_PAGE_SIZE (256 / NBBY) /* 256 bits per page */
+
+int owmem_redirect(uint8_t *, u_int, u_int);
diff --git a/sys/arch/sgi/dev/owserial.c b/sys/arch/sgi/dev/owserial.c
new file mode 100644
index 00000000000..9fc26f9c6f1
--- /dev/null
+++ b/sys/arch/sgi/dev/owserial.c
@@ -0,0 +1,217 @@
+/* $OpenBSD: owserial.c,v 1.1 2008/04/07 22:55:57 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DS2505 1-Wire Add-only memory driver, for SGI machines.
+ *
+ * SGI seems to use DS2505 (or compatibles) to store serial numbers.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/kernel.h>
+#include <sys/proc.h>
+
+#include <dev/onewire/onewiredevs.h>
+#include <dev/onewire/onewirereg.h>
+#include <dev/onewire/onewirevar.h>
+
+#include <sgi/dev/owmem_subr.h>
+#include <sgi/dev/owserialvar.h>
+
+int owserial_match(struct device *, void *, void *);
+void owserial_attach(struct device *, struct device *, void *);
+
+struct cfattach owserial_ca = {
+ sizeof(struct owserial_softc), owserial_match, owserial_attach,
+};
+
+struct cfdriver owserial_cd = {
+ NULL, "owserial", DV_DULL
+};
+
+#define EEPROM_PAGE_SIZE (256 / NBBY) /* 256 bits per page */
+
+static const struct onewire_matchfam owserial_fams[] = {
+ { ONEWIRE_FAMILY_DS2505 },
+ { ONEWIRE_FAMILY_DS2506 }
+};
+
+int owserial_read_page(struct owserial_softc *, int, uint8_t *);
+int owserial_read_redirect(struct owserial_softc *);
+
+void owserial_read_serial(struct owserial_softc *);
+
+int
+owserial_match(struct device *parent, void *match, void *aux)
+{
+ return (onewire_matchbyfam(aux, owserial_fams,
+ sizeof(owserial_fams) /sizeof(owserial_fams[0])));
+}
+
+void
+owserial_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct owserial_softc *sc = (struct owserial_softc *)self;
+ struct onewire_attach_args *oa = aux;
+
+ sc->sc_onewire = oa->oa_onewire;
+ sc->sc_rom = oa->oa_rom;
+
+ /*
+ * Decide how many pages of 256 bits we have.
+ */
+
+ if (ONEWIRE_ROM_FAMILY_TYPE(sc->sc_rom) == ONEWIRE_FAMILY_DS2506)
+ sc->sc_npages = 256;
+ else
+ sc->sc_npages = 64;
+
+ /*
+ * Read the redirection table.
+ */
+ if (owserial_read_redirect(sc) != 0) {
+ printf(": unable to read redirection data\n");
+ return;
+ }
+
+ printf("\n");
+
+ /*
+ * Read the data.
+ */
+ owserial_read_serial(sc);
+}
+
+int
+owserial_read_redirect(struct owserial_softc *sc)
+{
+ int rc = 0;
+ int status_offset, pos;
+
+ status_offset = 0x0100; /* 100..13f or 100..1ff */
+ pos = 0;
+
+ onewire_lock(sc->sc_onewire, 0);
+ if ((rc = onewire_reset(sc->sc_onewire)) != 0)
+ goto unlock;
+
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+
+ /*
+ * Start reading the EEPROM status block, at the page redirection
+ * offset.
+ */
+ onewire_write_byte(sc->sc_onewire, ONEWIRE_CMD_READ_STATUS);
+ onewire_write_byte(sc->sc_onewire, status_offset & 0xff);
+ onewire_write_byte(sc->sc_onewire, status_offset >> 8);
+
+ for (pos = 0; pos < sc->sc_npages; pos += 8) {
+ onewire_read_block(sc->sc_onewire, sc->sc_redir + pos, 8);
+ /* XXX check crc */
+ (void)onewire_read_byte(sc->sc_onewire);
+ (void)onewire_read_byte(sc->sc_onewire);
+ }
+
+ onewire_reset(sc->sc_onewire);
+unlock:
+ onewire_unlock(sc->sc_onewire);
+
+ return rc;
+}
+
+int
+owserial_read_page(struct owserial_softc *sc, int page, uint8_t *buf)
+{
+ int rc = 0;
+ int pg;
+
+ /*
+ * Follow the redirection information.
+ */
+ if ((pg = owmem_redirect(sc->sc_redir, sc->sc_npages, page)) < 0)
+ return EINVAL;
+
+ pg = page * EEPROM_PAGE_SIZE;
+
+ onewire_lock(sc->sc_onewire, 0);
+ if ((rc = onewire_reset(sc->sc_onewire)) != 0)
+ goto unlock;
+
+ onewire_matchrom(sc->sc_onewire, sc->sc_rom);
+
+ /*
+ * Start reading the EEPROM data.
+ */
+ onewire_write_byte(sc->sc_onewire, ONEWIRE_CMD_READ_MEMORY);
+ onewire_write_byte(sc->sc_onewire, pg & 0xff);
+ onewire_write_byte(sc->sc_onewire, pg >> 8);
+
+ onewire_read_block(sc->sc_onewire, buf, EEPROM_PAGE_SIZE);
+
+ onewire_reset(sc->sc_onewire);
+unlock:
+ onewire_unlock(sc->sc_onewire);
+
+ return rc;
+}
+
+void
+owserial_read_serial(struct owserial_softc *sc)
+{
+ uint8_t buf[EEPROM_PAGE_SIZE * 2];
+ char serial[1 + OWSERIAL_NAME_LEN];
+ char descr[1 + OWSERIAL_SERIAL_LEN], *dptr;
+ int pg;
+ int i;
+
+ pg = owmem_redirect(sc->sc_redir, sc->sc_npages, 0);
+ if (pg < 0 || owserial_read_page(sc, pg, buf) != 0)
+ return;
+
+ pg = owmem_redirect(sc->sc_redir, sc->sc_npages, 1);
+ if (pg < 0 || owserial_read_page(sc, pg, buf + EEPROM_PAGE_SIZE) != 0)
+ return;
+
+ /* minimal sanity check */
+ if (buf[0] != 0x01)
+ return;
+ for (i = EEPROM_PAGE_SIZE + 10; i < EEPROM_PAGE_SIZE + 16; i++)
+ if (buf[i] != 0xff)
+ return;
+
+ bcopy(buf + 21, serial, 9);
+ bcopy(buf + EEPROM_PAGE_SIZE + 3, serial + 9, 3);
+ serial[OWSERIAL_NAME_LEN] = '\0';
+ for (i = 0; i < OWSERIAL_NAME_LEN; i++)
+ if (serial[i] != '-' && (serial[i] < '0' || serial[i] > '9'))
+ return;
+
+ bcopy(buf + EEPROM_PAGE_SIZE + 16, descr, OWSERIAL_SERIAL_LEN);
+ descr[OWSERIAL_SERIAL_LEN] = '\0';
+ for (i = 0; i < OWSERIAL_SERIAL_LEN; i++)
+ if (descr[i] < ' ' || descr[i] > '~')
+ return;
+ for (dptr = descr; *dptr == ' '; dptr++);
+
+ strlcpy(sc->sc_name, dptr, sizeof sc->sc_name);
+ strlcpy(sc->sc_serial, serial, sizeof sc->sc_serial);
+
+ printf("%s: \"%s\" serial %s\n", sc->sc_dev.dv_xname, dptr, serial);
+}
diff --git a/sys/arch/sgi/dev/owserialvar.h b/sys/arch/sgi/dev/owserialvar.h
new file mode 100644
index 00000000000..acdfde41fe6
--- /dev/null
+++ b/sys/arch/sgi/dev/owserialvar.h
@@ -0,0 +1,39 @@
+/* $OpenBSD: owserialvar.h,v 1.1 2008/04/07 22:55:57 miod Exp $ */
+
+/*
+ * Copyright (c) 2008 Miodrag Vallat.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * DS2505 1-Wire Add-only memory driver, for SGI machines.
+ *
+ * SGI seems to use DS2505 (or compatibles) to store serial numbers.
+ */
+
+#define OWSERIAL_NAME_LEN 12
+#define OWSERIAL_SERIAL_LEN 14
+
+struct owserial_softc {
+ struct device sc_dev;
+
+ void *sc_onewire;
+ uint64_t sc_rom;
+
+ int sc_npages; /* number of pages */
+ uint8_t sc_redir[256]; /* redirection table */
+
+ char sc_name[1 + OWSERIAL_NAME_LEN];
+ char sc_serial[1 + OWSERIAL_SERIAL_LEN];
+};