]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - src/hwinfo/src/hd/prom.c
Zwischencommit Installer...
[ipfire-2.x.git] / src / hwinfo / src / hd / prom.c
diff --git a/src/hwinfo/src/hd/prom.c b/src/hwinfo/src/hd/prom.c
new file mode 100644 (file)
index 0000000..0a2a28f
--- /dev/null
@@ -0,0 +1,694 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <dirent.h>
+#include <sys/stat.h>
+
+#include "hd.h"
+#include "hd_int.h"
+#include "hddb.h"
+#include "prom.h"
+
+/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ * prom info
+ *
+ * Note: make sure that hd_scan_sysfs_pci() has been run!
+ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ */
+
+#if defined(__PPC__)
+
+static devtree_t *add_devtree_entry(devtree_t **devtree, devtree_t *new);
+static devtree_t *new_devtree_entry(devtree_t *parent);
+static void read_str(char *path, char *name, char **str);
+static void read_mem(char *path, char *name, unsigned char **mem, unsigned len);
+static void read_int(char *path, char *name, int *val);
+static void read_devtree(hd_data_t *hd_data);
+static void add_pci_prom_devices(hd_data_t *hd_data, hd_t *hd_parent, devtree_t *parent);
+static void add_legacy_prom_devices(hd_data_t *hd_data, devtree_t *dt);
+static int add_prom_display(hd_data_t *hd_data, devtree_t *dt);
+static int add_prom_vscsi(hd_data_t *hd_data, devtree_t *dt);
+static int add_prom_veth(hd_data_t *hd_data, devtree_t *dt);
+static void add_devices(hd_data_t *hd_data);
+static void dump_devtree_data(hd_data_t *hd_data);
+
+static unsigned veth_cnt, vscsi_cnt;
+
+int detect_smp_prom(hd_data_t *hd_data)
+{
+  unsigned cpus;
+  devtree_t *devtree;
+
+  if(!(devtree = hd_data->devtree)) return -1; /* hd_scan_prom() not called */
+
+  for(cpus = 0; devtree; devtree = devtree->next) {
+    if(devtree->device_type && !strcmp(devtree->device_type, "cpu")) cpus++;
+  }
+
+  return cpus > 1 ? cpus : 0;
+}
+
+void hd_scan_prom(hd_data_t *hd_data)
+{
+  hd_t *hd;
+  unsigned char buf[16];
+  FILE *f;
+  prom_info_t *pt;
+
+  if(!hd_probe_feature(hd_data, pr_prom)) return;
+
+  hd_data->module = mod_prom;
+
+  /* some clean-up */
+  remove_hd_entries(hd_data);
+  hd_data->devtree = free_devtree(hd_data);
+
+  veth_cnt = vscsi_cnt = 0;
+
+  PROGRESS(1, 0, "devtree");
+
+  read_devtree(hd_data);
+  if(hd_data->debug) dump_devtree_data(hd_data);
+  add_devices(hd_data);
+
+  PROGRESS(2, 0, "color");
+
+  hd = add_hd_entry(hd_data, __LINE__, 0);
+  hd->base_class.id = bc_internal;
+  hd->sub_class.id = sc_int_prom;
+  hd->detail = new_mem(sizeof *hd->detail);
+  hd->detail->type = hd_detail_prom;
+  hd->detail->prom.data = pt = new_mem(sizeof *pt);
+
+  if((f = fopen(PROC_PROM "/color-code", "r"))) {
+    if(fread(buf, 1, 2, f) == 2) {
+      pt->has_color = 1;
+      pt->color = buf[1];
+      hd_data->color_code = pt->color | 0x10000;
+      ADD2LOG("color-code: 0x%04x\n", (buf[0] << 8) + buf[1]);
+    }
+
+    fclose(f);
+  }
+
+}
+
+/* store a device tree entry */
+devtree_t *add_devtree_entry(devtree_t **devtree, devtree_t *new)
+{
+  while(*devtree) devtree = &(*devtree)->next;
+  return *devtree = new;
+}
+
+/* create a new device tree entry */
+devtree_t *new_devtree_entry(devtree_t *parent)
+{
+  static unsigned idx = 0;
+  devtree_t *devtree = new_mem(sizeof *devtree);
+
+  if(!parent) idx = 0;
+  devtree->idx = ++idx;
+  devtree->parent = parent;
+
+  devtree->interrupt = devtree->class_code =
+  devtree->device_id = devtree->vendor_id =
+  devtree->subdevice_id = devtree->subvendor_id =
+  devtree->revision_id = -1;
+
+  return devtree;
+}
+
+void read_str(char *path, char *name, char **str)
+{
+  char *s = NULL;
+  str_list_t *sl;
+
+  str_printf(&s, 0, "%s/%s", path, name);
+  if((sl = read_file(s, 0, 1))) {
+    *str = sl->str;
+    sl->str = NULL;
+    sl = free_str_list(sl);
+  }
+  free_mem(s);
+}
+
+void read_mem(char *path, char *name, unsigned char **mem, unsigned len)
+{
+  FILE *f;
+  char *s = NULL;
+  unsigned char *m = new_mem(len);
+
+  str_printf(&s, 0, "%s/%s", path, name);
+  if((f = fopen(s, "r"))) {
+    if(fread(m, len, 1, f) == 1) {
+      *mem = m;
+      m = NULL;
+    }
+    fclose(f);
+  }
+  free_mem(s);
+  free_mem(m);
+}
+
+void read_int(char *path, char *name, int *val)
+{
+  unsigned char *p = NULL;
+
+  read_mem(path, name, &p, sizeof (int));
+  if(p) memcpy(val, p, sizeof (int));
+  free_mem(p);
+}
+
+void read_devtree_entry(hd_data_t *hd_data, devtree_t *parent, char *dirname)
+{
+  DIR *dir;
+  struct dirent *de;
+  struct stat sbuf;
+  char *path, *s;
+  devtree_t *devtree, *dt2;
+
+  devtree = add_devtree_entry(&hd_data->devtree, new_devtree_entry(parent));
+
+  devtree->filename = new_str(dirname);
+
+  str_printf(&devtree->path, 0, "%s%s%s",
+    parent ? parent->path : "", parent && *parent->path ? "/" : "", dirname
+  );
+
+  path = 0;
+  str_printf(&path, 0, PROC_PROM "/%s", devtree->path);
+
+  if((dir = opendir(path))) {
+    while((de = readdir(dir))) {
+      if(!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..")) continue;
+      s = NULL;
+      str_printf(&s, 0, "%s/%s", path, de->d_name);
+      if(!lstat(s, &sbuf)) {
+        if(S_ISDIR(sbuf.st_mode)) {
+          /* prom entries don't always have unique names, unfortunately... */
+          for(dt2 = hd_data->devtree; dt2; dt2 = dt2->next) {
+            if(
+              dt2->parent == devtree &&
+              !strcmp(dt2->filename, de->d_name)
+            ) break;
+          }
+          if(!dt2) read_devtree_entry(hd_data, devtree, de->d_name);
+        }
+      }
+      s = free_mem(s);
+    }
+    closedir(dir);
+  }
+
+  read_str(path, "name", &devtree->name);
+  read_str(path, "model", &devtree->model);
+  read_str(path, "device_type", &devtree->device_type);
+  read_str(path, "compatible", &devtree->compatible);
+
+  read_int(path, "interrupts", &devtree->interrupt);
+  read_int(path, "AAPL,interrupts", &devtree->interrupt);
+  read_int(path, "class-code", &devtree->class_code);
+  read_int(path, "vendor-id", &devtree->vendor_id);
+  read_int(path, "device-id", &devtree->device_id);
+  read_int(path, "subsystem-vendor-id", &devtree->subvendor_id);
+  read_int(path, "subsystem-id", &devtree->subdevice_id);
+  read_int(path, "revision-id", &devtree->revision_id);
+
+  read_mem(path, "EDID", &devtree->edid, 0x80);
+  if(!devtree->edid) read_mem(path, "DFP,EDID", &devtree->edid, 0x80);
+
+  if(
+    devtree->class_code != -1 && devtree->vendor_id != -1 &&
+    devtree->device_id != -1
+  ) {
+    devtree->pci = 1;
+  }
+
+  path = free_mem(path);
+}
+
+void read_devtree(hd_data_t *hd_data)
+{
+  read_devtree_entry(hd_data, NULL, "");
+
+}
+
+void add_pci_prom_devices(hd_data_t *hd_data, hd_t *hd_parent, devtree_t *parent)
+{
+  hd_t *hd;
+  hd_res_t *res;
+  devtree_t *dt, *dt2;
+  int irq, floppy_ctrl_idx;
+  unsigned sound_ok = 0, net_ok = 0, scsi_ok = 0;
+  unsigned id;
+  char *s;
+
+  for(dt = hd_data->devtree; dt; dt = dt->next) {
+    if(
+      dt->parent == parent ||
+      (
+        /* special magic to reach some sound chips */
+        dt->parent &&
+        dt->parent->parent == parent &&
+        !dt->parent->pci
+      )
+    ) {
+
+      if(
+        dt->device_type &&
+        (!strcmp(dt->device_type, "block") || !strcmp(dt->device_type, "swim3"))
+      ) {
+        /* block devices */
+
+        s = dt->compatible ? dt->compatible : dt->name;
+        id = 0;
+
+        if(s) {
+          if(strstr(s, "swim3")) {
+            id = MAKE_ID(TAG_SPECIAL, 0x0040);
+          }
+        }
+
+        if(id) {
+          hd = add_hd_entry(hd_data, __LINE__, 0);
+          hd->bus.id = bus_none;
+          hd->base_class.id = bc_storage;
+          hd->sub_class.id = sc_sto_floppy;
+
+          hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0401);
+          hd->device.id = id;
+          hd->attached_to = hd_parent->idx;
+          hd->rom_id = new_str(dt->path);
+          if(dt->interrupt) {
+            res = add_res_entry(&hd->res, new_mem(sizeof *res));
+            res->irq.type = res_irq;
+            res->irq.enabled = 1;
+            res->irq.base = dt->interrupt;
+          }
+          floppy_ctrl_idx = hd->idx;
+
+          hd = add_hd_entry(hd_data, __LINE__, 0);
+          hd->base_class.id = bc_storage_device;
+          hd->sub_class.id = sc_sdev_floppy;
+          hd->bus.id = bus_floppy;
+          hd->unix_dev_name = new_str("/dev/fd0");
+
+          res = add_res_entry(&hd->res, new_mem(sizeof *res));
+          res->size.type = res_size;
+          res->size.val1 = str2float("3.5", 2);
+          res->size.unit = size_unit_cinch;
+
+          res = add_res_entry(&hd->res, new_mem(sizeof *res));
+          res->size.type = res_size;
+          res->size.val1 = 2880;
+          res->size.val2 = 0x200;
+          res->size.unit = size_unit_sectors;
+
+          hd->attached_to = floppy_ctrl_idx;
+        }
+      }
+
+      if(
+        !scsi_ok &&
+        dt->device_type &&
+        !strcmp(dt->device_type, "scsi")
+      ) {
+        /* scsi */
+        scsi_ok = 1;   /* max. 1 controller */
+
+        s = dt->compatible ? dt->compatible : dt->name;
+        id = 0;
+
+        if(s) {
+          if(strstr(s, "mesh")) {      /* mesh || chrp,mesh0 */
+            id = MAKE_ID(TAG_SPECIAL, 0x0030);
+          }
+          else if(!strcmp(s, "53c94")) {
+            id = MAKE_ID(TAG_SPECIAL, 0x0031);
+          }
+        }
+
+        if(id) {
+          hd = add_hd_entry(hd_data, __LINE__, 0);
+          hd->bus.id = bus_none;
+          hd->base_class.id = bc_storage;
+          hd->sub_class.id = sc_sto_scsi;
+
+          hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0401);
+          hd->device.id = id;
+          hd->attached_to = hd_parent->idx;
+          hd->rom_id = new_str(dt->path);
+          if(dt->interrupt) {
+            res = add_res_entry(&hd->res, new_mem(sizeof *res));
+            res->irq.type = res_irq;
+            res->irq.enabled = 1;
+            res->irq.base = dt->interrupt;
+          }
+        }
+      }
+
+      if(
+        !net_ok &&
+        dt->device_type &&
+        !strcmp(dt->device_type, "network")
+      ) {
+        /* network */
+        net_ok = 1;    /* max. 1 controller */
+
+        s = dt->compatible ? dt->compatible : dt->name;
+        id = 0;
+
+        if(s) {
+          if(!strcmp(s, "mace")) {
+            id = MAKE_ID(TAG_SPECIAL, 0x0020);
+          }
+          else if(!strcmp(s, "bmac")) {
+            id = MAKE_ID(TAG_SPECIAL, 0x0021);
+          }
+          else if(!strcmp(s, "bmac+")) {
+            id = MAKE_ID(TAG_SPECIAL, 0x0022);
+          }
+        }
+
+        if(id) {
+          hd = add_hd_entry(hd_data, __LINE__, 0);
+          hd->bus.id = bus_none;
+          hd->base_class.id = bc_network;
+          hd->sub_class.id = 0;        /* ethernet */
+
+          hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0401);
+          hd->device.id = id;
+          hd->attached_to = hd_parent->idx;
+          hd->rom_id = new_str(dt->path);
+          if(dt->interrupt) {
+            res = add_res_entry(&hd->res, new_mem(sizeof *res));
+            res->irq.type = res_irq;
+            res->irq.enabled = 1;
+            res->irq.base = dt->interrupt;
+          }
+        }
+      }
+
+      if(
+        !sound_ok &&
+        dt->device_type &&
+        strstr(dt->device_type, "sound") == dt->device_type
+      ) {
+        /* sound */
+        sound_ok = 1;  /* max 1 controller */
+
+        for(dt2 = dt; dt2; dt2 = dt2->next) {
+          if(
+            (
+              dt2 == dt ||
+              (dt2->parent && dt2->parent == dt)
+            ) &&
+            (
+              !strcmp(dt2->device_type, "sound") ||
+              !strcmp(dt2->device_type, "soundchip")
+            )
+          ) break;
+        }
+        if(!dt2) dt2 = dt;
+
+        hd = add_hd_entry(hd_data, __LINE__, 0);
+        hd->bus.id = bus_none;
+        hd->base_class.id = bc_multimedia;
+        hd->sub_class.id = sc_multi_audio;
+        hd->attached_to = hd_parent->idx;
+        hd->rom_id = new_str(dt2->path);
+        irq = dt2->interrupt;
+        if(irq <= 1 && dt2->parent && !dt2->parent->pci) {
+          irq = dt2->parent->interrupt;
+        }
+        if(irq > 1) {
+          res = add_res_entry(&hd->res, new_mem(sizeof *res));
+          res->irq.type = res_irq;
+          res->irq.enabled = 1;
+          res->irq.base = irq;
+        }
+
+        hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x401);           /* Apple */
+        hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0010);
+
+        if(dt2->compatible) {
+          if(!strcmp(dt2->compatible, "screamer")) {
+            hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0011);
+          }
+          else if(!strcmp(dt2->compatible, "burgundy")) {
+            hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0012);
+          }
+          else if(!strcmp(dt2->compatible, "daca")) {
+            hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0013);
+          }
+          else if(!strcmp(dt2->compatible, "CRUS,CS4236B")) {
+            hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x402);       /* IBM */
+            hd->device.id = MAKE_ID(TAG_SPECIAL, 0x0014);
+          }
+        }
+      }
+    }
+  }
+}
+
+
+void add_legacy_prom_devices(hd_data_t *hd_data, devtree_t *dt)
+{
+  if(dt->pci) return;
+
+  if(add_prom_display(hd_data, dt)) return;
+  if(add_prom_vscsi(hd_data, dt)) return;
+  if(add_prom_veth(hd_data, dt)) return;
+}
+
+int add_prom_display(hd_data_t *hd_data, devtree_t *dt)
+{
+  hd_t *hd;
+  hd_res_t *res;
+  unsigned id;
+
+  if(
+    dt->device_type &&
+    !strcmp(dt->device_type, "display")
+  ) {
+    /* display devices */
+
+    id = 0;
+
+    if(dt->name) {
+      if(!strcmp(dt->name, "valkyrie")) {
+        id = MAKE_ID(TAG_SPECIAL, 0x3000);
+      }
+      else if(!strcmp(dt->name, "platinum")) {
+        id = MAKE_ID(TAG_SPECIAL, 0x3001);
+      }
+    }
+
+    if(id) {
+      hd = add_hd_entry(hd_data, __LINE__, 0);
+      hd->bus.id = bus_none;
+      hd->base_class.id = bc_display;
+      hd->sub_class.id = sc_dis_other;
+
+      hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x0401);
+      hd->device.id = id;
+      hd->rom_id = new_str(dt->path);
+      if(dt->interrupt) {
+        res = add_res_entry(&hd->res, new_mem(sizeof *res));
+        res->irq.type = res_irq;
+        res->irq.enabled = 1;
+        res->irq.base = dt->interrupt;
+      }
+
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+int add_prom_vscsi(hd_data_t *hd_data, devtree_t *dt)
+{
+  hd_t *hd;
+  char *s, *id;
+
+  if(
+    dt->path &&
+    dt->device_type &&
+    !strcmp(dt->device_type, "vscsi")
+  ) {
+    /* vscsi storage */
+
+    if(
+      (s = strstr(dt->path, "v-scsi@")) &&
+      *(id = s + sizeof "v-scsi@" - 1)
+    ) {
+      hd = add_hd_entry(hd_data, __LINE__, 0);
+      hd->bus.id = bus_none;
+      hd->base_class.id = bc_storage;
+      hd->sub_class.id = sc_sto_scsi;
+      hd->slot = veth_cnt++;
+
+      hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6001);
+      hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1001);
+      str_printf(&hd->device.name, 0, "Virtual SCSI %d", hd->slot);
+      hd->rom_id = new_str(dt->path);
+
+      str_printf(&hd->sysfs_id, 0, "/devices/vio/%s", id);
+
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+int add_prom_veth(hd_data_t *hd_data, devtree_t *dt)
+{
+  hd_t *hd;
+  char *s, *id;
+
+  if(
+    dt->path &&
+    dt->device_type &&
+    dt->compatible &&
+    !strcmp(dt->device_type, "network") &&
+    !strcmp(dt->compatible, "IBM,l-lan")
+  ) {
+    /* veth network */
+
+    if(
+      (s = strstr(dt->path, "l-lan@")) &&
+      *(id = s + sizeof "l-lan@" - 1)
+    ) {
+      hd = add_hd_entry(hd_data, __LINE__, 0);
+      hd->bus.id = bus_none;
+      hd->base_class.id = bc_network;
+      hd->sub_class.id = 0x00;
+      hd->slot = veth_cnt++;
+
+      hd->vendor.id = MAKE_ID(TAG_SPECIAL, 0x6001);
+      hd->device.id = MAKE_ID(TAG_SPECIAL, 0x1002);
+      str_printf(&hd->device.name, 0, "Virtual Ethernet card %d", hd->slot);
+      hd->rom_id = new_str(dt->path);
+
+      str_printf(&hd->sysfs_id, 0, "/devices/vio/%s", id);
+
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+void add_devices(hd_data_t *hd_data)
+{
+  hd_t *hd;
+  devtree_t *dt;
+#if 0
+  hd_res_t *res;
+  unsigned pci_slot = 0, u;
+#endif
+
+  /* remove old assignments */
+  for(hd = hd_data->hd; hd; hd = hd->next) {
+    if(ID_TAG(hd->device.id) == TAG_PCI && ID_TAG(hd->vendor.id) == TAG_PCI) {
+      hd->rom_id = free_mem(hd->rom_id);
+      hd->detail = free_hd_detail(hd->detail);
+    }
+  }
+
+  for(dt = hd_data->devtree; dt; dt = dt->next) {
+    if(dt->pci) {
+      for(hd = hd_data->hd; hd; hd = hd->next) {
+        if(
+          /* do *not* compare class ids */
+          /* It would be better to check the slot numbers instead but
+           * as they are not stored within /proc/device-tree in a consistent
+           * way, we can't do that.
+           */
+          !hd->rom_id &&
+          ID_TAG(hd->device.id) == TAG_PCI &&
+          ID_TAG(hd->vendor.id) == TAG_PCI &&
+          ID_VALUE(hd->device.id) == dt->device_id &&
+          ID_VALUE(hd->vendor.id) == dt->vendor_id &&
+          (dt->subvendor_id == -1 || ID_VALUE(hd->sub_vendor.id) == dt->subvendor_id) &&
+          (dt->subdevice_id == -1 || ID_VALUE(hd->sub_device.id) == dt->subdevice_id) &&
+          hd->revision.id == dt->revision_id
+        ) break;
+      }
+
+      if(hd) {
+        hd->rom_id = new_str(dt->path);
+        hd->detail = new_mem(sizeof *hd->detail);
+        hd->detail->type = hd_detail_devtree;
+        hd->detail->devtree.data = dt;
+        add_pci_prom_devices(hd_data, hd, dt);
+      }
+    }
+    else {
+      add_legacy_prom_devices(hd_data, dt);
+    }
+  }
+}
+
+void dump_devtree_data(hd_data_t *hd_data)
+{
+  unsigned u;
+  devtree_t *devtree;
+
+  devtree = hd_data->devtree;
+  if(!devtree) return;
+
+  ADD2LOG("----- /proc device tree -----\n");
+
+  for(; devtree; devtree = devtree->next) {
+    u = devtree->parent ? devtree->parent->idx : 0;
+    ADD2LOG("  %02u @%02u  %s", devtree->idx, u, devtree->path);
+    if(devtree->pci) ADD2LOG("  [pci]");
+    ADD2LOG("\n");
+
+    ADD2LOG(
+      "    name \"%s\", model \"%s\", dtype \"%s\", compat \"%s\"\n",
+      devtree->name ? devtree->name : "",
+      devtree->model ? devtree->model : "",
+      devtree->device_type ? devtree->device_type : "",
+      devtree->compatible ? devtree->compatible : ""
+    );
+
+    if(
+      devtree->class_code != -1 || devtree->vendor_id != -1 ||
+      devtree->device_id != -1 || devtree->revision_id != -1 ||
+      devtree->subdevice_id != -1 || devtree->subvendor_id != -1 ||
+      devtree->interrupt != -1
+    ) {
+      ADD2LOG("  ");
+      if(devtree->class_code != -1) ADD2LOG("  class 0x%06x", devtree->class_code);
+      if(devtree->vendor_id != -1) ADD2LOG("  vend 0x%04x", devtree->vendor_id);
+      if(devtree->device_id != -1) ADD2LOG("  dev 0x%04x", devtree->device_id);
+      if(devtree->subvendor_id != -1) ADD2LOG("  svend 0x%04x", devtree->subvendor_id);
+      if(devtree->subdevice_id != -1) ADD2LOG("  sdev 0x%04x", devtree->subdevice_id);
+      if(devtree->revision_id != -1) ADD2LOG("  rev 0x%02x", devtree->revision_id);
+      if(devtree->interrupt != -1) ADD2LOG("  irq %d", devtree->interrupt);
+      ADD2LOG("\n");
+    }
+
+    if(devtree->edid) {
+      ADD2LOG("    EDID record:\n");
+      for(u = 0; u < 0x80; u += 0x10) {
+        ADD2LOG("    %02x  ", u);
+        hexdump(&hd_data->log, 1, 0x10, devtree->edid + u);
+        ADD2LOG("\n");
+      }
+    }
+
+    if(devtree->next) ADD2LOG("\n");
+  }
+
+  ADD2LOG("----- /proc device tree end -----\n");
+}
+
+
+#endif /* defined(__PPC__) */
+