Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
pdc_stable.c
Go to the documentation of this file.
1 /*
2  * Interfaces to retrieve and set PDC Stable options (firmware)
3  *
4  * Copyright (C) 2005-2006 Thibaut VARENE <[email protected]>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License, version 2, as
8  * published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  *
20  * DEV NOTE: the PDC Procedures reference states that:
21  * "A minimum of 96 bytes of Stable Storage is required. Providing more than
22  * 96 bytes of Stable Storage is optional [...]. Failure to provide the
23  * optional locations from 96 to 192 results in the loss of certain
24  * functionality during boot."
25  *
26  * Since locations between 96 and 192 are the various paths, most (if not
27  * all) PA-RISC machines should have them. Anyway, for safety reasons, the
28  * following code can deal with just 96 bytes of Stable Storage, and all
29  * sizes between 96 and 192 bytes (provided they are multiple of struct
30  * device_path size, eg: 128, 160 and 192) to provide full information.
31  * One last word: there's one path we can always count on: the primary path.
32  * Anything above 224 bytes is used for 'osdep2' OS-dependent storage area.
33  *
34  * The first OS-dependent area should always be available. Obviously, this is
35  * not true for the other one. Also bear in mind that reading/writing from/to
36  * osdep2 is much more expensive than from/to osdep1.
37  * NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first
38  * 2 bytes of storage available right after OSID. That's a total of 4 bytes
39  * sacrificed: -ETOOLAZY :P
40  *
41  * The current policy wrt file permissions is:
42  * - write: root only
43  * - read: (reading triggers PDC calls) ? root only : everyone
44  * The rationale is that PDC calls could hog (DoS) the machine.
45  *
46  * TODO:
47  * - timer/fastsize write calls
48  */
49 
50 #undef PDCS_DEBUG
51 #ifdef PDCS_DEBUG
52 #define DPRINTK(fmt, args...) printk(KERN_DEBUG fmt, ## args)
53 #else
54 #define DPRINTK(fmt, args...)
55 #endif
56 
57 #include <linux/module.h>
58 #include <linux/init.h>
59 #include <linux/kernel.h>
60 #include <linux/string.h>
61 #include <linux/capability.h>
62 #include <linux/ctype.h>
63 #include <linux/sysfs.h>
64 #include <linux/kobject.h>
65 #include <linux/device.h>
66 #include <linux/errno.h>
67 #include <linux/spinlock.h>
68 
69 #include <asm/pdc.h>
70 #include <asm/page.h>
71 #include <asm/uaccess.h>
72 #include <asm/hardware.h>
73 
74 #define PDCS_VERSION "0.30"
75 #define PDCS_PREFIX "PDC Stable Storage"
76 
77 #define PDCS_ADDR_PPRI 0x00
78 #define PDCS_ADDR_OSID 0x40
79 #define PDCS_ADDR_OSD1 0x48
80 #define PDCS_ADDR_DIAG 0x58
81 #define PDCS_ADDR_FSIZ 0x5C
82 #define PDCS_ADDR_PCON 0x60
83 #define PDCS_ADDR_PALT 0x80
84 #define PDCS_ADDR_PKBD 0xA0
85 #define PDCS_ADDR_OSD2 0xE0
86 
87 MODULE_AUTHOR("Thibaut VARENE <[email protected]>");
88 MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
89 MODULE_LICENSE("GPL");
91 
92 /* holds Stable Storage size. Initialized once and for all, no lock needed */
93 static unsigned long pdcs_size __read_mostly;
94 
95 /* holds OS ID. Initialized once and for all, hopefully to 0x0006 */
96 static u16 pdcs_osid __read_mostly;
97 
98 /* This struct defines what we need to deal with a parisc pdc path entry */
100  rwlock_t rw_lock; /* to protect path entry access */
101  short ready; /* entry record is valid if != 0 */
102  unsigned long addr; /* entry address in stable storage */
103  char *name; /* entry name */
104  struct device_path devpath; /* device path in parisc representation */
105  struct device *dev; /* corresponding device */
106  struct kobject kobj;
107 };
108 
110  struct attribute attr;
111  ssize_t (*show)(struct pdcspath_entry *entry, char *buf);
112  ssize_t (*store)(struct pdcspath_entry *entry, const char *buf, size_t count);
113 };
114 
115 #define PDCSPATH_ENTRY(_addr, _name) \
116 struct pdcspath_entry pdcspath_entry_##_name = { \
117  .ready = 0, \
118  .addr = _addr, \
119  .name = __stringify(_name), \
120 };
121 
122 #define PDCS_ATTR(_name, _mode, _show, _store) \
123 struct kobj_attribute pdcs_attr_##_name = { \
124  .attr = {.name = __stringify(_name), .mode = _mode}, \
125  .show = _show, \
126  .store = _store, \
127 };
128 
129 #define PATHS_ATTR(_name, _mode, _show, _store) \
130 struct pdcspath_attribute paths_attr_##_name = { \
131  .attr = {.name = __stringify(_name), .mode = _mode}, \
132  .show = _show, \
133  .store = _store, \
134 };
135 
136 #define to_pdcspath_attribute(_attr) container_of(_attr, struct pdcspath_attribute, attr)
137 #define to_pdcspath_entry(obj) container_of(obj, struct pdcspath_entry, kobj)
138 
151 static int
152 pdcspath_fetch(struct pdcspath_entry *entry)
153 {
154  struct device_path *devpath;
155 
156  if (!entry)
157  return -EINVAL;
158 
159  devpath = &entry->devpath;
160 
161  DPRINTK("%s: fetch: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
162  entry, devpath, entry->addr);
163 
164  /* addr, devpath and count must be word aligned */
165  if (pdc_stable_read(entry->addr, devpath, sizeof(*devpath)) != PDC_OK)
166  return -EIO;
167 
168  /* Find the matching device.
169  NOTE: hardware_path overlays with device_path, so the nice cast can
170  be used */
171  entry->dev = hwpath_to_device((struct hardware_path *)devpath);
172 
173  entry->ready = 1;
174 
175  DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
176 
177  return 0;
178 }
179 
192 static void
193 pdcspath_store(struct pdcspath_entry *entry)
194 {
195  struct device_path *devpath;
196 
197  BUG_ON(!entry);
198 
199  devpath = &entry->devpath;
200 
201  /* We expect the caller to set the ready flag to 0 if the hardware
202  path struct provided is invalid, so that we know we have to fill it.
203  First case, we don't have a preset hwpath... */
204  if (!entry->ready) {
205  /* ...but we have a device, map it */
206  BUG_ON(!entry->dev);
207  device_to_hwpath(entry->dev, (struct hardware_path *)devpath);
208  }
209  /* else, we expect the provided hwpath to be valid. */
210 
211  DPRINTK("%s: store: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
212  entry, devpath, entry->addr);
213 
214  /* addr, devpath and count must be word aligned */
215  if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK) {
216  printk(KERN_ERR "%s: an error occurred when writing to PDC.\n"
217  "It is likely that the Stable Storage data has been corrupted.\n"
218  "Please check it carefully upon next reboot.\n", __func__);
219  WARN_ON(1);
220  }
221 
222  /* kobject is already registered */
223  entry->ready = 2;
224 
225  DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
226 }
227 
235 static ssize_t
236 pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf)
237 {
238  char *out = buf;
239  struct device_path *devpath;
240  short i;
241 
242  if (!entry || !buf)
243  return -EINVAL;
244 
245  read_lock(&entry->rw_lock);
246  devpath = &entry->devpath;
247  i = entry->ready;
248  read_unlock(&entry->rw_lock);
249 
250  if (!i) /* entry is not ready */
251  return -ENODATA;
252 
253  for (i = 0; i < 6; i++) {
254  if (devpath->bc[i] >= 128)
255  continue;
256  out += sprintf(out, "%u/", (unsigned char)devpath->bc[i]);
257  }
258  out += sprintf(out, "%u\n", (unsigned char)devpath->mod);
259 
260  return out - buf;
261 }
262 
278 static ssize_t
279 pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t count)
280 {
281  struct hardware_path hwpath;
282  unsigned short i;
283  char in[count+1], *temp;
284  struct device *dev;
285  int ret;
286 
287  if (!entry || !buf || !count)
288  return -EINVAL;
289 
290  /* We'll use a local copy of buf */
291  memset(in, 0, count+1);
292  strncpy(in, buf, count);
293 
294  /* Let's clean up the target. 0xff is a blank pattern */
295  memset(&hwpath, 0xff, sizeof(hwpath));
296 
297  /* First, pick the mod field (the last one of the input string) */
298  if (!(temp = strrchr(in, '/')))
299  return -EINVAL;
300 
301  hwpath.mod = simple_strtoul(temp+1, NULL, 10);
302  in[temp-in] = '\0'; /* truncate the remaining string. just precaution */
303  DPRINTK("%s: mod: %d\n", __func__, hwpath.mod);
304 
305  /* Then, loop for each delimiter, making sure we don't have too many.
306  we write the bc fields in a down-top way. No matter what, we stop
307  before writing the last field. If there are too many fields anyway,
308  then the user is a moron and it'll be caught up later when we'll
309  check the consistency of the given hwpath. */
310  for (i=5; ((temp = strrchr(in, '/'))) && (temp-in > 0) && (likely(i)); i--) {
311  hwpath.bc[i] = simple_strtoul(temp+1, NULL, 10);
312  in[temp-in] = '\0';
313  DPRINTK("%s: bc[%d]: %d\n", __func__, i, hwpath.bc[i]);
314  }
315 
316  /* Store the final field */
317  hwpath.bc[i] = simple_strtoul(in, NULL, 10);
318  DPRINTK("%s: bc[%d]: %d\n", __func__, i, hwpath.bc[i]);
319 
320  /* Now we check that the user isn't trying to lure us */
321  if (!(dev = hwpath_to_device((struct hardware_path *)&hwpath))) {
322  printk(KERN_WARNING "%s: attempt to set invalid \"%s\" "
323  "hardware path: %s\n", __func__, entry->name, buf);
324  return -EINVAL;
325  }
326 
327  /* So far so good, let's get in deep */
328  write_lock(&entry->rw_lock);
329  entry->ready = 0;
330  entry->dev = dev;
331 
332  /* Now, dive in. Write back to the hardware */
333  pdcspath_store(entry);
334 
335  /* Update the symlink to the real device */
336  sysfs_remove_link(&entry->kobj, "device");
337  ret = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
338  WARN_ON(ret);
339 
340  write_unlock(&entry->rw_lock);
341 
342  printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
343  entry->name, buf);
344 
345  return count;
346 }
347 
355 static ssize_t
356 pdcspath_layer_read(struct pdcspath_entry *entry, char *buf)
357 {
358  char *out = buf;
359  struct device_path *devpath;
360  short i;
361 
362  if (!entry || !buf)
363  return -EINVAL;
364 
365  read_lock(&entry->rw_lock);
366  devpath = &entry->devpath;
367  i = entry->ready;
368  read_unlock(&entry->rw_lock);
369 
370  if (!i) /* entry is not ready */
371  return -ENODATA;
372 
373  for (i = 0; i < 6 && devpath->layers[i]; i++)
374  out += sprintf(out, "%u ", devpath->layers[i]);
375 
376  out += sprintf(out, "\n");
377 
378  return out - buf;
379 }
380 
393 static ssize_t
394 pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count)
395 {
396  unsigned int layers[6]; /* device-specific info (ctlr#, unit#, ...) */
397  unsigned short i;
398  char in[count+1], *temp;
399 
400  if (!entry || !buf || !count)
401  return -EINVAL;
402 
403  /* We'll use a local copy of buf */
404  memset(in, 0, count+1);
405  strncpy(in, buf, count);
406 
407  /* Let's clean up the target. 0 is a blank pattern */
408  memset(&layers, 0, sizeof(layers));
409 
410  /* First, pick the first layer */
411  if (unlikely(!isdigit(*in)))
412  return -EINVAL;
413  layers[0] = simple_strtoul(in, NULL, 10);
414  DPRINTK("%s: layer[0]: %d\n", __func__, layers[0]);
415 
416  temp = in;
417  for (i=1; ((temp = strchr(temp, '.'))) && (likely(i<6)); i++) {
418  if (unlikely(!isdigit(*(++temp))))
419  return -EINVAL;
420  layers[i] = simple_strtoul(temp, NULL, 10);
421  DPRINTK("%s: layer[%d]: %d\n", __func__, i, layers[i]);
422  }
423 
424  /* So far so good, let's get in deep */
425  write_lock(&entry->rw_lock);
426 
427  /* First, overwrite the current layers with the new ones, not touching
428  the hardware path. */
429  memcpy(&entry->devpath.layers, &layers, sizeof(layers));
430 
431  /* Now, dive in. Write back to the hardware */
432  pdcspath_store(entry);
433  write_unlock(&entry->rw_lock);
434 
435  printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n",
436  entry->name, buf);
437 
438  return count;
439 }
440 
447 static ssize_t
448 pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
449 {
450  struct pdcspath_entry *entry = to_pdcspath_entry(kobj);
451  struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);
452  ssize_t ret = 0;
453 
454  if (pdcs_attr->show)
455  ret = pdcs_attr->show(entry, buf);
456 
457  return ret;
458 }
459 
467 static ssize_t
468 pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
469  const char *buf, size_t count)
470 {
471  struct pdcspath_entry *entry = to_pdcspath_entry(kobj);
472  struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);
473  ssize_t ret = 0;
474 
475  if (!capable(CAP_SYS_ADMIN))
476  return -EACCES;
477 
478  if (pdcs_attr->store)
479  ret = pdcs_attr->store(entry, buf, count);
480 
481  return ret;
482 }
483 
484 static const struct sysfs_ops pdcspath_attr_ops = {
485  .show = pdcspath_attr_show,
486  .store = pdcspath_attr_store,
487 };
488 
489 /* These are the two attributes of any PDC path. */
490 static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write);
491 static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write);
492 
493 static struct attribute *paths_subsys_attrs[] = {
494  &paths_attr_hwpath.attr,
495  &paths_attr_layer.attr,
496  NULL,
497 };
498 
499 /* Specific kobject type for our PDC paths */
500 static struct kobj_type ktype_pdcspath = {
501  .sysfs_ops = &pdcspath_attr_ops,
502  .default_attrs = paths_subsys_attrs,
503 };
504 
505 /* We hard define the 4 types of path we expect to find */
509 static PDCSPATH_ENTRY(PDCS_ADDR_PKBD, keyboard);
510 
511 /* An array containing all PDC paths we will deal with */
512 static struct pdcspath_entry *pdcspath_entries[] = {
513  &pdcspath_entry_primary,
514  &pdcspath_entry_alternative,
515  &pdcspath_entry_console,
516  &pdcspath_entry_keyboard,
517  NULL,
518 };
519 
520 
521 /* For more insight of what's going on here, refer to PDC Procedures doc,
522  * Section PDC_STABLE */
523 
528 static ssize_t pdcs_size_read(struct kobject *kobj,
529  struct kobj_attribute *attr,
530  char *buf)
531 {
532  char *out = buf;
533 
534  if (!buf)
535  return -EINVAL;
536 
537  /* show the size of the stable storage */
538  out += sprintf(out, "%ld\n", pdcs_size);
539 
540  return out - buf;
541 }
542 
548 static ssize_t pdcs_auto_read(struct kobject *kobj,
549  struct kobj_attribute *attr,
550  char *buf, int knob)
551 {
552  char *out = buf;
553  struct pdcspath_entry *pathentry;
554 
555  if (!buf)
556  return -EINVAL;
557 
558  /* Current flags are stored in primary boot path entry */
559  pathentry = &pdcspath_entry_primary;
560 
561  read_lock(&pathentry->rw_lock);
562  out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ?
563  "On" : "Off");
564  read_unlock(&pathentry->rw_lock);
565 
566  return out - buf;
567 }
568 
573 static ssize_t pdcs_autoboot_read(struct kobject *kobj,
574  struct kobj_attribute *attr, char *buf)
575 {
576  return pdcs_auto_read(kobj, attr, buf, PF_AUTOBOOT);
577 }
578 
583 static ssize_t pdcs_autosearch_read(struct kobject *kobj,
584  struct kobj_attribute *attr, char *buf)
585 {
586  return pdcs_auto_read(kobj, attr, buf, PF_AUTOSEARCH);
587 }
588 
595 static ssize_t pdcs_timer_read(struct kobject *kobj,
596  struct kobj_attribute *attr, char *buf)
597 {
598  char *out = buf;
599  struct pdcspath_entry *pathentry;
600 
601  if (!buf)
602  return -EINVAL;
603 
604  /* Current flags are stored in primary boot path entry */
605  pathentry = &pdcspath_entry_primary;
606 
607  /* print the timer value in seconds */
608  read_lock(&pathentry->rw_lock);
609  out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ?
610  (1 << (pathentry->devpath.flags & PF_TIMER)) : 0);
611  read_unlock(&pathentry->rw_lock);
612 
613  return out - buf;
614 }
615 
620 static ssize_t pdcs_osid_read(struct kobject *kobj,
621  struct kobj_attribute *attr, char *buf)
622 {
623  char *out = buf;
624 
625  if (!buf)
626  return -EINVAL;
627 
628  out += sprintf(out, "%s dependent data (0x%.4x)\n",
629  os_id_to_string(pdcs_osid), pdcs_osid);
630 
631  return out - buf;
632 }
633 
640 static ssize_t pdcs_osdep1_read(struct kobject *kobj,
641  struct kobj_attribute *attr, char *buf)
642 {
643  char *out = buf;
644  u32 result[4];
645 
646  if (!buf)
647  return -EINVAL;
648 
649  if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK)
650  return -EIO;
651 
652  out += sprintf(out, "0x%.8x\n", result[0]);
653  out += sprintf(out, "0x%.8x\n", result[1]);
654  out += sprintf(out, "0x%.8x\n", result[2]);
655  out += sprintf(out, "0x%.8x\n", result[3]);
656 
657  return out - buf;
658 }
659 
666 static ssize_t pdcs_diagnostic_read(struct kobject *kobj,
667  struct kobj_attribute *attr, char *buf)
668 {
669  char *out = buf;
670  u32 result;
671 
672  if (!buf)
673  return -EINVAL;
674 
675  /* get diagnostic */
676  if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK)
677  return -EIO;
678 
679  out += sprintf(out, "0x%.4x\n", (result >> 16));
680 
681  return out - buf;
682 }
683 
690 static ssize_t pdcs_fastsize_read(struct kobject *kobj,
691  struct kobj_attribute *attr, char *buf)
692 {
693  char *out = buf;
694  u32 result;
695 
696  if (!buf)
697  return -EINVAL;
698 
699  /* get fast-size */
700  if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK)
701  return -EIO;
702 
703  if ((result & 0x0F) < 0x0E)
704  out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256);
705  else
706  out += sprintf(out, "All");
707  out += sprintf(out, "\n");
708 
709  return out - buf;
710 }
711 
718 static ssize_t pdcs_osdep2_read(struct kobject *kobj,
719  struct kobj_attribute *attr, char *buf)
720 {
721  char *out = buf;
722  unsigned long size;
723  unsigned short i;
724  u32 result;
725 
726  if (unlikely(pdcs_size <= 224))
727  return -ENODATA;
728 
729  size = pdcs_size - 224;
730 
731  if (!buf)
732  return -EINVAL;
733 
734  for (i=0; i<size; i+=4) {
735  if (unlikely(pdc_stable_read(PDCS_ADDR_OSD2 + i, &result,
736  sizeof(result)) != PDC_OK))
737  return -EIO;
738  out += sprintf(out, "0x%.8x\n", result);
739  }
740 
741  return out - buf;
742 }
743 
754 static ssize_t pdcs_auto_write(struct kobject *kobj,
755  struct kobj_attribute *attr, const char *buf,
756  size_t count, int knob)
757 {
758  struct pdcspath_entry *pathentry;
759  unsigned char flags;
760  char in[count+1], *temp;
761  char c;
762 
763  if (!capable(CAP_SYS_ADMIN))
764  return -EACCES;
765 
766  if (!buf || !count)
767  return -EINVAL;
768 
769  /* We'll use a local copy of buf */
770  memset(in, 0, count+1);
771  strncpy(in, buf, count);
772 
773  /* Current flags are stored in primary boot path entry */
774  pathentry = &pdcspath_entry_primary;
775 
776  /* Be nice to the existing flag record */
777  read_lock(&pathentry->rw_lock);
778  flags = pathentry->devpath.flags;
779  read_unlock(&pathentry->rw_lock);
780 
781  DPRINTK("%s: flags before: 0x%X\n", __func__, flags);
782 
783  temp = skip_spaces(in);
784 
785  c = *temp++ - '0';
786  if ((c != 0) && (c != 1))
787  goto parse_error;
788  if (c == 0)
789  flags &= ~knob;
790  else
791  flags |= knob;
792 
793  DPRINTK("%s: flags after: 0x%X\n", __func__, flags);
794 
795  /* So far so good, let's get in deep */
796  write_lock(&pathentry->rw_lock);
797 
798  /* Change the path entry flags first */
799  pathentry->devpath.flags = flags;
800 
801  /* Now, dive in. Write back to the hardware */
802  pdcspath_store(pathentry);
803  write_unlock(&pathentry->rw_lock);
804 
805  printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" to \"%s\"\n",
806  (knob & PF_AUTOBOOT) ? "autoboot" : "autosearch",
807  (flags & knob) ? "On" : "Off");
808 
809  return count;
810 
811 parse_error:
812  printk(KERN_WARNING "%s: Parse error: expect \"n\" (n == 0 or 1)\n", __func__);
813  return -EINVAL;
814 }
815 
825 static ssize_t pdcs_autoboot_write(struct kobject *kobj,
826  struct kobj_attribute *attr,
827  const char *buf, size_t count)
828 {
829  return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOBOOT);
830 }
831 
841 static ssize_t pdcs_autosearch_write(struct kobject *kobj,
842  struct kobj_attribute *attr,
843  const char *buf, size_t count)
844 {
845  return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOSEARCH);
846 }
847 
857 static ssize_t pdcs_osdep1_write(struct kobject *kobj,
858  struct kobj_attribute *attr,
859  const char *buf, size_t count)
860 {
861  u8 in[16];
862 
863  if (!capable(CAP_SYS_ADMIN))
864  return -EACCES;
865 
866  if (!buf || !count)
867  return -EINVAL;
868 
869  if (unlikely(pdcs_osid != OS_ID_LINUX))
870  return -EPERM;
871 
872  if (count > 16)
873  return -EMSGSIZE;
874 
875  /* We'll use a local copy of buf */
876  memset(in, 0, 16);
877  memcpy(in, buf, count);
878 
879  if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK)
880  return -EIO;
881 
882  return count;
883 }
884 
894 static ssize_t pdcs_osdep2_write(struct kobject *kobj,
895  struct kobj_attribute *attr,
896  const char *buf, size_t count)
897 {
898  unsigned long size;
899  unsigned short i;
900  u8 in[4];
901 
902  if (!capable(CAP_SYS_ADMIN))
903  return -EACCES;
904 
905  if (!buf || !count)
906  return -EINVAL;
907 
908  if (unlikely(pdcs_size <= 224))
909  return -ENOSYS;
910 
911  if (unlikely(pdcs_osid != OS_ID_LINUX))
912  return -EPERM;
913 
914  size = pdcs_size - 224;
915 
916  if (count > size)
917  return -EMSGSIZE;
918 
919  /* We'll use a local copy of buf */
920 
921  for (i=0; i<count; i+=4) {
922  memset(in, 0, 4);
923  memcpy(in, buf+i, (count-i < 4) ? count-i : 4);
925  sizeof(in)) != PDC_OK))
926  return -EIO;
927  }
928 
929  return count;
930 }
931 
932 /* The remaining attributes. */
933 static PDCS_ATTR(size, 0444, pdcs_size_read, NULL);
934 static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write);
935 static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write);
936 static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL);
937 static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL);
938 static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write);
939 static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL);
940 static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
941 static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write);
942 
943 static struct attribute *pdcs_subsys_attrs[] = {
944  &pdcs_attr_size.attr,
945  &pdcs_attr_autoboot.attr,
946  &pdcs_attr_autosearch.attr,
947  &pdcs_attr_timer.attr,
948  &pdcs_attr_osid.attr,
949  &pdcs_attr_osdep1.attr,
950  &pdcs_attr_diagnostic.attr,
951  &pdcs_attr_fastsize.attr,
952  &pdcs_attr_osdep2.attr,
953  NULL,
954 };
955 
956 static struct attribute_group pdcs_attr_group = {
957  .attrs = pdcs_subsys_attrs,
958 };
959 
960 static struct kobject *stable_kobj;
961 static struct kset *paths_kset;
962 
972 static inline int __init
973 pdcs_register_pathentries(void)
974 {
975  unsigned short i;
976  struct pdcspath_entry *entry;
977  int err;
978 
979  /* Initialize the entries rw_lock before anything else */
980  for (i = 0; (entry = pdcspath_entries[i]); i++)
981  rwlock_init(&entry->rw_lock);
982 
983  for (i = 0; (entry = pdcspath_entries[i]); i++) {
984  write_lock(&entry->rw_lock);
985  err = pdcspath_fetch(entry);
986  write_unlock(&entry->rw_lock);
987 
988  if (err < 0)
989  continue;
990 
991  entry->kobj.kset = paths_kset;
992  err = kobject_init_and_add(&entry->kobj, &ktype_pdcspath, NULL,
993  "%s", entry->name);
994  if (err)
995  return err;
996 
997  /* kobject is now registered */
998  write_lock(&entry->rw_lock);
999  entry->ready = 2;
1000 
1001  /* Add a nice symlink to the real device */
1002  if (entry->dev) {
1003  err = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
1004  WARN_ON(err);
1005  }
1006 
1007  write_unlock(&entry->rw_lock);
1008  kobject_uevent(&entry->kobj, KOBJ_ADD);
1009  }
1010 
1011  return 0;
1012 }
1013 
1017 static inline void
1018 pdcs_unregister_pathentries(void)
1019 {
1020  unsigned short i;
1021  struct pdcspath_entry *entry;
1022 
1023  for (i = 0; (entry = pdcspath_entries[i]); i++) {
1024  read_lock(&entry->rw_lock);
1025  if (entry->ready >= 2)
1026  kobject_put(&entry->kobj);
1027  read_unlock(&entry->rw_lock);
1028  }
1029 }
1030 
1031 /*
1032  * For now we register the stable subsystem with the firmware subsystem
1033  * and the paths subsystem with the stable subsystem
1034  */
1035 static int __init
1036 pdc_stable_init(void)
1037 {
1038  int rc = 0, error = 0;
1039  u32 result;
1040 
1041  /* find the size of the stable storage */
1042  if (pdc_stable_get_size(&pdcs_size) != PDC_OK)
1043  return -ENODEV;
1044 
1045  /* make sure we have enough data */
1046  if (pdcs_size < 96)
1047  return -ENODATA;
1048 
1049  printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION);
1050 
1051  /* get OSID */
1052  if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
1053  return -EIO;
1054 
1055  /* the actual result is 16 bits away */
1056  pdcs_osid = (u16)(result >> 16);
1057 
1058  /* For now we'll register the directory at /sys/firmware/stable */
1059  stable_kobj = kobject_create_and_add("stable", firmware_kobj);
1060  if (!stable_kobj) {
1061  rc = -ENOMEM;
1062  goto fail_firmreg;
1063  }
1064 
1065  /* Don't forget the root entries */
1066  error = sysfs_create_group(stable_kobj, &pdcs_attr_group);
1067 
1068  /* register the paths kset as a child of the stable kset */
1069  paths_kset = kset_create_and_add("paths", NULL, stable_kobj);
1070  if (!paths_kset) {
1071  rc = -ENOMEM;
1072  goto fail_ksetreg;
1073  }
1074 
1075  /* now we create all "files" for the paths kset */
1076  if ((rc = pdcs_register_pathentries()))
1077  goto fail_pdcsreg;
1078 
1079  return rc;
1080 
1081 fail_pdcsreg:
1082  pdcs_unregister_pathentries();
1083  kset_unregister(paths_kset);
1084 
1085 fail_ksetreg:
1086  kobject_put(stable_kobj);
1087 
1088 fail_firmreg:
1089  printk(KERN_INFO PDCS_PREFIX " bailing out\n");
1090  return rc;
1091 }
1092 
1093 static void __exit
1094 pdc_stable_exit(void)
1095 {
1096  pdcs_unregister_pathentries();
1097  kset_unregister(paths_kset);
1098  kobject_put(stable_kobj);
1099 }
1100 
1101 
1102 module_init(pdc_stable_init);
1103 module_exit(pdc_stable_exit);