Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-7]: src/sys/arch/sandpoint Pull up following revision(s) (request...



details:   https://anonhg.NetBSD.org/src/rev/21b83c27fcc2
branches:  netbsd-7
changeset: 799755:21b83c27fcc2
user:      snj <snj%NetBSD.org@localhost>
date:      Sat Jan 16 10:04:04 2016 +0000

description:
Pull up following revision(s) (requested by phx in ticket #1059):
        sys/arch/sandpoint/include/bootinfo.h: revision 1.9
        sys/arch/sandpoint/stand/altboot/brdsetup.c: revisions 1.36, 1.37
        sys/arch/sandpoint/stand/altboot/dsk.c: revision 1.18
        sys/arch/sandpoint/stand/altboot/globals.h: revisions 1.20, 1.21
        sys/arch/sandpoint/stand/altboot/main.c: revision 1.27
        sys/arch/sandpoint/stand/altboot/siisata.c: revision 1.6
        sys/arch/sandpoint/stand/altboot/version: revision 1.8
The disk's unittag is not equal to the channel, so we need an additional
unitchan entry to make lba_read() work in all cases.
The libsa-printf() does not seem to support 64-bit output, so cast the
block number to unsigned when printing an error message.
--
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.
--
fix a board type check logic error that affected Linkstation and Kurobox (HG).
They were mistakenly recognized kurot4 type and ended up with kernel boot
failure.

diffstat:

 sys/arch/sandpoint/include/bootinfo.h       |   17 ++-
 sys/arch/sandpoint/stand/altboot/brdsetup.c |  189 ++++++++++++++++++++++++---
 sys/arch/sandpoint/stand/altboot/dsk.c      |    8 +-
 sys/arch/sandpoint/stand/altboot/globals.h  |    5 +-
 sys/arch/sandpoint/stand/altboot/main.c     |    4 +-
 sys/arch/sandpoint/stand/altboot/siisata.c  |   26 ++-
 sys/arch/sandpoint/stand/altboot/version    |    2 +
 7 files changed, 218 insertions(+), 33 deletions(-)

diffs (truncated from 437 to 300 lines):

diff -r 450541bfd84a -r 21b83c27fcc2 sys/arch/sandpoint/include/bootinfo.h
--- a/sys/arch/sandpoint/include/bootinfo.h     Fri Jan 15 17:38:53 2016 +0000
+++ b/sys/arch/sandpoint/include/bootinfo.h     Sat Jan 16 10:04:04 2016 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bootinfo.h,v 1.8 2011/01/11 06:57:35 nisimura Exp $    */
+/*     $NetBSD: bootinfo.h,v 1.8.34.1 2016/01/16 10:04:04 snj 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 450541bfd84a -r 21b83c27fcc2 sys/arch/sandpoint/stand/altboot/brdsetup.c
--- a/sys/arch/sandpoint/stand/altboot/brdsetup.c       Fri Jan 15 17:38:53 2016 +0000
+++ b/sys/arch/sandpoint/stand/altboot/brdsetup.c       Sat Jan 16 10:04:04 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: brdsetup.c,v 1.35 2014/08/08 21:18:10 joerg Exp $ */
+/* $NetBSD: brdsetup.c,v 1.35.2.1 2016/01/16 10:04:04 snj 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[] = {
     {
@@ -253,10 +260,14 @@
        }
        else if (PCI_CLASS(pcicfgread(dev11, PCI_CLASS_REG)) == PCI_CLASS_ETH) {
                /* ADMtek AN985 (tlp) or RealTek 8169S (re) at dev 11 */
-               if (PCI_VENDOR(pcicfgread(dev12, PCI_ID_REG)) != 0x1095)
+               if (PCI_VENDOR(pcicfgread(dev11, PCI_ID_REG)) == 0x1317)
                        brdtype = BRD_KUROBOX;
-               else
-                       brdtype = BRD_KUROBOXT4;
+               else if (PCI_VENDOR(pcicfgread(dev11, PCI_ID_REG)) == 0x10ec) {
+                       if (PCI_PRODUCT(pcicfgread(dev12,PCI_ID_REG)) != 0x3512)
+                               brdtype = BRD_KUROBOX;
+                       else
+                               brdtype = BRD_KUROBOXT4;
+               }
        }
        else if (PCI_VENDOR(pcicfgread(dev15, PCI_ID_REG)) == 0x11ab) {
                /* SKnet/Marvell (sk) at dev 15 */
@@ -719,47 +730,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 450541bfd84a -r 21b83c27fcc2 sys/arch/sandpoint/stand/altboot/dsk.c
--- a/sys/arch/sandpoint/stand/altboot/dsk.c    Fri Jan 15 17:38:53 2016 +0000
+++ b/sys/arch/sandpoint/stand/altboot/dsk.c    Sat Jan 16 10:04:04 2016 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: dsk.c,v 1.17 2014/08/05 17:55:20 joerg Exp $ */
+/* $NetBSD: dsk.c,v 1.17.2.1 2016/01/16 10:04:05 snj Exp $ */
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -125,6 +125,7 @@
                }
                d = &ldisk[ndrive];
                d->dvops = l;
+               d->unitchan = n;
                d->unittag = ndrive;
                snprintf(d->xname, sizeof(d->xname), "wd%d", d->unittag);
                set_xfermode(l, n);
@@ -404,7 +405,7 @@
        int error;



Home | Main Index | Thread Index | Old Index