Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/arch/sandpoint Pass a name and flags precisely describin...
details: https://anonhg.NetBSD.org/src/rev/627daebd45a4
branches: trunk
changeset: 340777:627daebd45a4
user: phx <phx%NetBSD.org@localhost>
date: Wed Sep 30 14:14:32 2015 +0000
description:
Pass a name and flags precisely describing the current model and its
features via a new bootinfo node (currently Synology only). This allows
for example the configuration of model-specific temperature I2C sensors
and fan control.
Support for the Synology DS207 and DS209 drive LEDs and wait until the
2nd drive is completely powered up.
diffstat:
sys/arch/sandpoint/include/bootinfo.h | 17 ++-
sys/arch/sandpoint/stand/altboot/brdsetup.c | 179 +++++++++++++++++++++++++--
sys/arch/sandpoint/stand/altboot/globals.h | 4 +-
sys/arch/sandpoint/stand/altboot/main.c | 4 +-
sys/arch/sandpoint/stand/altboot/siisata.c | 26 +++-
sys/arch/sandpoint/stand/altboot/version | 2 +
6 files changed, 205 insertions(+), 27 deletions(-)
diffs (truncated from 375 to 300 lines):
diff -r fbb2d6ff1951 -r 627daebd45a4 sys/arch/sandpoint/include/bootinfo.h
--- a/sys/arch/sandpoint/include/bootinfo.h Wed Sep 30 08:42:04 2015 +0000
+++ b/sys/arch/sandpoint/include/bootinfo.h Wed Sep 30 14:14:32 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: bootinfo.h,v 1.8 2011/01/11 06:57:35 nisimura Exp $ */
+/* $NetBSD: bootinfo.h,v 1.9 2015/09/30 14:14:32 phx Exp $ */
/*
* Copyright (c) 1997
@@ -45,6 +45,7 @@
#define BTINFO_NET 7
#define BTINFO_PRODFAMILY 8
#define BTINFO_MODULELIST 9
+#define BTINFO_MODEL 10
struct btinfo_magic {
struct btinfo_common common;
@@ -91,6 +92,20 @@
char name[24];
};
+struct btinfo_model {
+ struct btinfo_common common;
+ char name[28];
+ unsigned flags; /* model specific flags */
+/* Synology flags: */
+#define BI_MODEL_CPLDVER_MASK 0x07
+#define BI_MODEL_CPLD207 0x08
+#define BI_MODEL_CPLD209 0x10
+#define BI_MODEL_CPLD406 0x18
+#define BI_MODEL_CPLD407 0x20
+#define BI_MODEL_CPLD_MASK 0x38
+#define BI_MODEL_THERMAL 0x40
+};
+
struct btinfo_modulelist {
struct btinfo_common common;
int num;
diff -r fbb2d6ff1951 -r 627daebd45a4 sys/arch/sandpoint/stand/altboot/brdsetup.c
--- a/sys/arch/sandpoint/stand/altboot/brdsetup.c Wed Sep 30 08:42:04 2015 +0000
+++ b/sys/arch/sandpoint/stand/altboot/brdsetup.c Wed Sep 30 14:14:32 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: brdsetup.c,v 1.35 2014/08/08 21:18:10 joerg Exp $ */
+/* $NetBSD: brdsetup.c,v 1.36 2015/09/30 14:14:32 phx Exp $ */
/*-
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -111,7 +111,14 @@
#define IOMEGA_PACKETSIZE 8
/* NH230/231 GPIO */
-#define NHGPIO_WRITE(x) *((uint8_t *)0x70000000) = x
+#define NHGPIO_WRITE(x) *((volatile uint8_t *)0x70000000) = (x)
+
+/* Synology CPLD (2007 and newer models) */
+#define SYNOCPLD_READ(r) *((volatile uint8_t *)0xff000000 + (r))
+#define SYNOCPLD_WRITE(r,x) do { \
+ *((volatile uint8_t *)0xff000000 + (r)) = (x); \
+ delay(10); \
+ } while(0)
static struct brdprop brdlist[] = {
{
@@ -719,47 +726,183 @@
send_sat("247");
}
+#define SYNO_FAN_TIMEOUT 500 /* 500ms to turn the fan off */
+#define SYNO_DISK_DELAY 30 /* 30 seconds to power up 2nd disk */
+
void
synopcifix(struct brdprop *brd)
{
- static const char csmodel[4][7] = {
- "CS406e", "CS406", "RS406", "CS407e"
+ static const char models207[4][7] = {
+ "???", "DS107e", "DS107", "DS207"
+ };
+ static const char models209[2][7] = {
+ "DS109j", "DS209j"
+ };
+ static const char models406[3][7] = {
+ "CS406e", "CS406", "RS406"
+ };
+ static const char models407[4][7] = {
+ "???", "CS407e", "CS407", "RS407"
};
- volatile uint8_t *cpld = (volatile uint8_t *)0xff000000;
- uint8_t pwrstate;
+ extern struct btinfo_model bi_model;
+ const char *model_name;
+ unsigned cpld, version, flags;
+ uint8_t v, status;
+ int i;
+
+ /*
+ * Determine if a CPLD is present and whether is has 4-bit
+ * (models 107, 207, 209) or 8-bit (models 406, 407) registers.
+ * The register set repeats every 16 bytes.
+ */
+ cpld = 0;
+ flags = 0;
+ version = 0;
+ model_name = NULL;
+
+ SYNOCPLD_WRITE(0, 0x00); /* LEDs blinking yellow (default) */
+ v = SYNOCPLD_READ(0);
+
+ if (v != 0x00) {
+ v &= 0xf0;
+ if (v != 0x00 || (SYNOCPLD_READ(16 + 0) & 0xf0) != v)
+ goto cpld_done;
+
+ cpld4bits:
+ /* 4-bit registers assumed, make LEDs solid yellow */
+ SYNOCPLD_WRITE(0, 0x50);
+ v = SYNOCPLD_READ(0) & 0xf0;
+ if (v != 0x50 || (SYNOCPLD_READ(32 + 0) & 0xf0) != v)
+ goto cpld_done;
+
+ v = SYNOCPLD_READ(2) & 0xf0;
+ if ((SYNOCPLD_READ(48 + 2) & 0xf0) != v)
+ goto cpld_done;
+ version = (v >> 4) & 7;
+
+ /*
+ * Try to determine whether it is a 207-style or 209-style
+ * CPLD register set, by turning the fan off and check if
+ * either bit 5 or bit 4 changes from 0 to 1 to indicate
+ * the fan is stopped.
+ */
+ status = SYNOCPLD_READ(3) & 0xf0;
+ SYNOCPLD_WRITE(3, 0x00); /* fan off */
- if (nata > 1) {
+ for (i = 0; i < SYNO_FAN_TIMEOUT * 100; i++) {
+ delay(10);
+ v = SYNOCPLD_READ(3) & 0xf0;
+ if ((status & 0x20) == 0 && (v & 0x20) != 0) {
+ /* set x07 model */
+ v = SYNOCPLD_READ(1) >> 6;
+ model_name = models207[v];
+ cpld = BI_MODEL_CPLD207;
+ /* XXXX DS107v2/v3 have no thermal sensor */
+ flags |= BI_MODEL_THERMAL;
+ break;
+ }
+ if ((status & 0x10) == 0 && (v & 0x10) != 0) {
+ /* set x09 model */
+ v = SYNOCPLD_READ(1) >> 7;
+ model_name = models209[v];
+ cpld = BI_MODEL_CPLD209;
+ if (v == 1) /* DS209j */
+ flags |= BI_MODEL_THERMAL;
+ break;
+ }
+ /* XXX What about DS108j? Does it have a CPLD? */
+ }
+
+ /* turn the fan on again */
+ SYNOCPLD_WRITE(3, status);
+
+ if (i >= SYNO_FAN_TIMEOUT * 100)
+ goto cpld_done; /* timeout: no valid CPLD */
+ } else {
+ if (SYNOCPLD_READ(16 + 0) != v)
+ goto cpld4bits;
+
+ /* 8-bit registers assumed, make LEDs solid yellow */
+ SYNOCPLD_WRITE(0, 0x55);
+ v = SYNOCPLD_READ(0);
+ if (v != 0x55)
+ goto cpld4bits; /* try 4 bits instead */
+ if (SYNOCPLD_READ(32 + 0) != v)
+ goto cpld_done;
+
+ v = SYNOCPLD_READ(2);
+ if (SYNOCPLD_READ(48 + 2) != v)
+ goto cpld_done;
+ version = v & 3;
+
+ if ((v & 0x0c) != 0x0c) {
+ /* set 406 model */
+ model_name = models406[(v >> 2) & 3];
+ cpld = BI_MODEL_CPLD406;
+ } else {
+ /* set 407 model */
+ model_name = models407[v >> 6];
+ cpld = BI_MODEL_CPLD407;
+ flags |= BI_MODEL_THERMAL;
+ }
+ }
+
+ printf("CPLD V%s%u detected for model %s\n",
+ cpld < BI_MODEL_CPLD406 ? "" : "1.",
+ version, model_name);
+
+ if (cpld == BI_MODEL_CPLD406 || cpld == BI_MODEL_CPLD407) {
/*
* CS/RS stations power-up their disks one after another.
* We have to watch over the current power state in a CPLD
* register, until all disks become available.
*/
- printf("CPLD V1.%d for model %s\n", cpld[2] & 3,
- csmodel[(cpld[2] & 0x0c) >> 2]);
- cpld[0] = 0x00; /* all drive LEDs blinking yellow */
do {
delay(1000 * 1000);
- pwrstate = cpld[1];
- printf("Power state: %02x\r", pwrstate);
- } while (pwrstate != 0xff);
+ v = SYNOCPLD_READ(1);
+ printf("Power state: %02x\r", v);
+ } while (v != 0xff);
putchar('\n');
+ } else if (model_name != NULL && model_name[2] == '2') {
+ /*
+ * DS207 and DS209 have a second SATA disk, which is started
+ * with several seconds delay, but no CPLD register to
+ * monitor the power state. So all we can do is to
+ * wait some more seconds during SATA-init.
+ */
+ sata_delay[1] = SYNO_DISK_DELAY;
}
+
+ cpld_done:
+ if (model_name != NULL) {
+ snprintf(bi_model.name, sizeof(bi_model.name), "%s", model_name);
+ bi_model.flags = cpld | version | flags;
+ } else
+ printf("No CPLD found. DS101/DS106.\n");
}
void
synolaunch(struct brdprop *brd)
{
- volatile uint8_t *cpld = (volatile uint8_t *)0xff000000;
+ extern struct btinfo_model bi_model;
struct dkdev_ata *sata1, *sata2;
+ unsigned cpld;
- if (nata > 1) {
- /* enable drive LEDs for active disk drives on CS/RS models */
+ cpld = bi_model.flags & BI_MODEL_CPLD_MASK;
+
+ if (cpld == BI_MODEL_CPLD406 || cpld == BI_MODEL_CPLD407) {
+ /* set drive LEDs for active disk drives on CS/RS models */
sata1 = lata[0].drv;
sata2 = lata[1].drv;
- cpld[0] = (sata1->presense[0] ? 0x80 : 0xc0) |
+ SYNOCPLD_WRITE(0, (sata1->presense[0] ? 0x80 : 0xc0) |
(sata1->presense[1] ? 0x20 : 0x30) |
(sata2->presense[0] ? 0x08 : 0x0c) |
- (sata2->presense[1] ? 0x02 : 0x03);
+ (sata2->presense[1] ? 0x02 : 0x03));
+ } else if (cpld == BI_MODEL_CPLD207 || cpld == BI_MODEL_CPLD209) {
+ /* set drive LEDs for DS207 and DS209 models */
+ sata1 = lata[0].drv;
+ SYNOCPLD_WRITE(0, (sata1->presense[0] ? 0x80 : 0xc0) |
+ (sata1->presense[1] ? 0x20 : 0x30));
}
}
diff -r fbb2d6ff1951 -r 627daebd45a4 sys/arch/sandpoint/stand/altboot/globals.h
--- a/sys/arch/sandpoint/stand/altboot/globals.h Wed Sep 30 08:42:04 2015 +0000
+++ b/sys/arch/sandpoint/stand/altboot/globals.h Wed Sep 30 14:14:32 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: globals.h,v 1.20 2015/09/29 15:12:52 phx Exp $ */
+/* $NetBSD: globals.h,v 1.21 2015/09/30 14:14:32 phx Exp $ */
#ifdef DEBUG
#define DPRINTF(x) printf x
@@ -197,6 +197,8 @@
DSK_DECL(pciide);
DSK_DECL(siisata);
+extern int sata_delay[4];
+
/* status */
#define ATA_STS_BUSY 0x80
#define ATA_STS_DRDY 0x40
diff -r fbb2d6ff1951 -r 627daebd45a4 sys/arch/sandpoint/stand/altboot/main.c
--- a/sys/arch/sandpoint/stand/altboot/main.c Wed Sep 30 08:42:04 2015 +0000
+++ b/sys/arch/sandpoint/stand/altboot/main.c Wed Sep 30 14:14:32 2015 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: main.c,v 1.26 2014/08/05 17:55:20 joerg Exp $ */
+/* $NetBSD: main.c,v 1.27 2015/09/30 14:14:32 phx Exp $ */
/*-
* Copyright (c) 2007 The NetBSD Foundation, Inc.
@@ -72,6 +72,7 @@
struct btinfo_console bi_cons;
struct btinfo_clock bi_clk;
struct btinfo_prodfamily bi_fam;
+struct btinfo_model bi_model;
struct btinfo_bootpath bi_path;
struct btinfo_rootdevice bi_rdev;
struct btinfo_net bi_net;
@@ -362,6 +363,7 @@
/* need to pass this MAC address to kernel */
Home |
Main Index |
Thread Index |
Old Index