Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /* 
0003  *    Interfaces to retrieve and set PDC Stable options (firmware)
0004  *
0005  *    Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org>
0006  *
0007  *    DEV NOTE: the PDC Procedures reference states that:
0008  *    "A minimum of 96 bytes of Stable Storage is required. Providing more than
0009  *    96 bytes of Stable Storage is optional [...]. Failure to provide the
0010  *    optional locations from 96 to 192 results in the loss of certain
0011  *    functionality during boot."
0012  *
0013  *    Since locations between 96 and 192 are the various paths, most (if not
0014  *    all) PA-RISC machines should have them. Anyway, for safety reasons, the
0015  *    following code can deal with just 96 bytes of Stable Storage, and all
0016  *    sizes between 96 and 192 bytes (provided they are multiple of struct
0017  *    device_path size, eg: 128, 160 and 192) to provide full information.
0018  *    One last word: there's one path we can always count on: the primary path.
0019  *    Anything above 224 bytes is used for 'osdep2' OS-dependent storage area.
0020  *
0021  *    The first OS-dependent area should always be available. Obviously, this is
0022  *    not true for the other one. Also bear in mind that reading/writing from/to
0023  *    osdep2 is much more expensive than from/to osdep1.
0024  *    NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first
0025  *    2 bytes of storage available right after OSID. That's a total of 4 bytes
0026  *    sacrificed: -ETOOLAZY :P
0027  *
0028  *    The current policy wrt file permissions is:
0029  *  - write: root only
0030  *  - read: (reading triggers PDC calls) ? root only : everyone
0031  *    The rationale is that PDC calls could hog (DoS) the machine.
0032  *
0033  *  TODO:
0034  *  - timer/fastsize write calls
0035  */
0036 
0037 #undef PDCS_DEBUG
0038 #ifdef PDCS_DEBUG
0039 #define DPRINTK(fmt, args...)   printk(KERN_DEBUG fmt, ## args)
0040 #else
0041 #define DPRINTK(fmt, args...)
0042 #endif
0043 
0044 #include <linux/module.h>
0045 #include <linux/init.h>
0046 #include <linux/kernel.h>
0047 #include <linux/string.h>
0048 #include <linux/capability.h>
0049 #include <linux/ctype.h>
0050 #include <linux/sysfs.h>
0051 #include <linux/kobject.h>
0052 #include <linux/device.h>
0053 #include <linux/errno.h>
0054 #include <linux/spinlock.h>
0055 
0056 #include <asm/pdc.h>
0057 #include <asm/page.h>
0058 #include <linux/uaccess.h>
0059 #include <asm/hardware.h>
0060 
0061 #define PDCS_VERSION    "0.30"
0062 #define PDCS_PREFIX "PDC Stable Storage"
0063 
0064 #define PDCS_ADDR_PPRI  0x00
0065 #define PDCS_ADDR_OSID  0x40
0066 #define PDCS_ADDR_OSD1  0x48
0067 #define PDCS_ADDR_DIAG  0x58
0068 #define PDCS_ADDR_FSIZ  0x5C
0069 #define PDCS_ADDR_PCON  0x60
0070 #define PDCS_ADDR_PALT  0x80
0071 #define PDCS_ADDR_PKBD  0xA0
0072 #define PDCS_ADDR_OSD2  0xE0
0073 
0074 MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>");
0075 MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
0076 MODULE_LICENSE("GPL");
0077 MODULE_VERSION(PDCS_VERSION);
0078 
0079 /* holds Stable Storage size. Initialized once and for all, no lock needed */
0080 static unsigned long pdcs_size __read_mostly;
0081 
0082 /* holds OS ID. Initialized once and for all, hopefully to 0x0006 */
0083 static u16 pdcs_osid __read_mostly;
0084 
0085 /* This struct defines what we need to deal with a parisc pdc path entry */
0086 struct pdcspath_entry {
0087     rwlock_t rw_lock;       /* to protect path entry access */
0088     short ready;            /* entry record is valid if != 0 */
0089     unsigned long addr;     /* entry address in stable storage */
0090     char *name;         /* entry name */
0091     struct device_path devpath; /* device path in parisc representation */
0092     struct device *dev;     /* corresponding device */
0093     struct kobject kobj;
0094 };
0095 
0096 struct pdcspath_attribute {
0097     struct attribute attr;
0098     ssize_t (*show)(struct pdcspath_entry *entry, char *buf);
0099     ssize_t (*store)(struct pdcspath_entry *entry, const char *buf, size_t count);
0100 };
0101 
0102 #define PDCSPATH_ENTRY(_addr, _name) \
0103 struct pdcspath_entry pdcspath_entry_##_name = { \
0104     .ready = 0, \
0105     .addr = _addr, \
0106     .name = __stringify(_name), \
0107 };
0108 
0109 #define PDCS_ATTR(_name, _mode, _show, _store) \
0110 struct kobj_attribute pdcs_attr_##_name = { \
0111     .attr = {.name = __stringify(_name), .mode = _mode}, \
0112     .show = _show, \
0113     .store = _store, \
0114 };
0115 
0116 #define PATHS_ATTR(_name, _mode, _show, _store) \
0117 struct pdcspath_attribute paths_attr_##_name = { \
0118     .attr = {.name = __stringify(_name), .mode = _mode}, \
0119     .show = _show, \
0120     .store = _store, \
0121 };
0122 
0123 #define to_pdcspath_attribute(_attr) container_of(_attr, struct pdcspath_attribute, attr)
0124 #define to_pdcspath_entry(obj)  container_of(obj, struct pdcspath_entry, kobj)
0125 
0126 /**
0127  * pdcspath_fetch - This function populates the path entry structs.
0128  * @entry: A pointer to an allocated pdcspath_entry.
0129  * 
0130  * The general idea is that you don't read from the Stable Storage every time
0131  * you access the files provided by the facilities. We store a copy of the
0132  * content of the stable storage WRT various paths in these structs. We read
0133  * these structs when reading the files, and we will write to these structs when
0134  * writing to the files, and only then write them back to the Stable Storage.
0135  *
0136  * This function expects to be called with @entry->rw_lock write-hold.
0137  */
0138 static int
0139 pdcspath_fetch(struct pdcspath_entry *entry)
0140 {
0141     struct device_path *devpath;
0142 
0143     if (!entry)
0144         return -EINVAL;
0145 
0146     devpath = &entry->devpath;
0147     
0148     DPRINTK("%s: fetch: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
0149             entry, devpath, entry->addr);
0150 
0151     /* addr, devpath and count must be word aligned */
0152     if (pdc_stable_read(entry->addr, devpath, sizeof(*devpath)) != PDC_OK)
0153         return -EIO;
0154         
0155     /* Find the matching device.
0156        NOTE: hardware_path overlays with device_path, so the nice cast can
0157        be used */
0158     entry->dev = hwpath_to_device((struct hardware_path *)devpath);
0159 
0160     entry->ready = 1;
0161     
0162     DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
0163     
0164     return 0;
0165 }
0166 
0167 /**
0168  * pdcspath_store - This function writes a path to stable storage.
0169  * @entry: A pointer to an allocated pdcspath_entry.
0170  * 
0171  * It can be used in two ways: either by passing it a preset devpath struct
0172  * containing an already computed hardware path, or by passing it a device
0173  * pointer, from which it'll find out the corresponding hardware path.
0174  * For now we do not handle the case where there's an error in writing to the
0175  * Stable Storage area, so you'd better not mess up the data :P
0176  *
0177  * This function expects to be called with @entry->rw_lock write-hold.
0178  */
0179 static void
0180 pdcspath_store(struct pdcspath_entry *entry)
0181 {
0182     struct device_path *devpath;
0183 
0184     BUG_ON(!entry);
0185 
0186     devpath = &entry->devpath;
0187     
0188     /* We expect the caller to set the ready flag to 0 if the hardware
0189        path struct provided is invalid, so that we know we have to fill it.
0190        First case, we don't have a preset hwpath... */
0191     if (!entry->ready) {
0192         /* ...but we have a device, map it */
0193         BUG_ON(!entry->dev);
0194         device_to_hwpath(entry->dev, (struct hardware_path *)devpath);
0195     }
0196     /* else, we expect the provided hwpath to be valid. */
0197     
0198     DPRINTK("%s: store: 0x%p, 0x%p, addr: 0x%lx\n", __func__,
0199             entry, devpath, entry->addr);
0200 
0201     /* addr, devpath and count must be word aligned */
0202     if (pdc_stable_write(entry->addr, devpath, sizeof(*devpath)) != PDC_OK)
0203         WARN(1, KERN_ERR "%s: an error occurred when writing to PDC.\n"
0204                 "It is likely that the Stable Storage data has been corrupted.\n"
0205                 "Please check it carefully upon next reboot.\n", __func__);
0206         
0207     /* kobject is already registered */
0208     entry->ready = 2;
0209     
0210     DPRINTK("%s: device: 0x%p\n", __func__, entry->dev);
0211 }
0212 
0213 /**
0214  * pdcspath_hwpath_read - This function handles hardware path pretty printing.
0215  * @entry: An allocated and populated pdscpath_entry struct.
0216  * @buf: The output buffer to write to.
0217  * 
0218  * We will call this function to format the output of the hwpath attribute file.
0219  */
0220 static ssize_t
0221 pdcspath_hwpath_read(struct pdcspath_entry *entry, char *buf)
0222 {
0223     char *out = buf;
0224     struct device_path *devpath;
0225     short i;
0226 
0227     if (!entry || !buf)
0228         return -EINVAL;
0229 
0230     read_lock(&entry->rw_lock);
0231     devpath = &entry->devpath;
0232     i = entry->ready;
0233     read_unlock(&entry->rw_lock);
0234 
0235     if (!i) /* entry is not ready */
0236         return -ENODATA;
0237     
0238     for (i = 0; i < 6; i++) {
0239         if (devpath->bc[i] >= 128)
0240             continue;
0241         out += sprintf(out, "%u/", (unsigned char)devpath->bc[i]);
0242     }
0243     out += sprintf(out, "%u\n", (unsigned char)devpath->mod);
0244     
0245     return out - buf;
0246 }
0247 
0248 /**
0249  * pdcspath_hwpath_write - This function handles hardware path modifying.
0250  * @entry: An allocated and populated pdscpath_entry struct.
0251  * @buf: The input buffer to read from.
0252  * @count: The number of bytes to be read.
0253  * 
0254  * We will call this function to change the current hardware path.
0255  * Hardware paths are to be given '/'-delimited, without brackets.
0256  * We make sure that the provided path actually maps to an existing
0257  * device, BUT nothing would prevent some foolish user to set the path to some
0258  * PCI bridge or even a CPU...
0259  * A better work around would be to make sure we are at the end of a device tree
0260  * for instance, but it would be IMHO beyond the simple scope of that driver.
0261  * The aim is to provide a facility. Data correctness is left to userland.
0262  */
0263 static ssize_t
0264 pdcspath_hwpath_write(struct pdcspath_entry *entry, const char *buf, size_t count)
0265 {
0266     struct hardware_path hwpath;
0267     unsigned short i;
0268     char in[64], *temp;
0269     struct device *dev;
0270     int ret;
0271 
0272     if (!entry || !buf || !count)
0273         return -EINVAL;
0274 
0275     /* We'll use a local copy of buf */
0276     count = min_t(size_t, count, sizeof(in)-1);
0277     strncpy(in, buf, count);
0278     in[count] = '\0';
0279     
0280     /* Let's clean up the target. 0xff is a blank pattern */
0281     memset(&hwpath, 0xff, sizeof(hwpath));
0282     
0283     /* First, pick the mod field (the last one of the input string) */
0284     if (!(temp = strrchr(in, '/')))
0285         return -EINVAL;
0286             
0287     hwpath.mod = simple_strtoul(temp+1, NULL, 10);
0288     in[temp-in] = '\0'; /* truncate the remaining string. just precaution */
0289     DPRINTK("%s: mod: %d\n", __func__, hwpath.mod);
0290     
0291     /* Then, loop for each delimiter, making sure we don't have too many.
0292        we write the bc fields in a down-top way. No matter what, we stop
0293        before writing the last field. If there are too many fields anyway,
0294        then the user is a moron and it'll be caught up later when we'll
0295        check the consistency of the given hwpath. */
0296     for (i=5; ((temp = strrchr(in, '/'))) && (temp-in > 0) && (likely(i)); i--) {
0297         hwpath.bc[i] = simple_strtoul(temp+1, NULL, 10);
0298         in[temp-in] = '\0';
0299         DPRINTK("%s: bc[%d]: %d\n", __func__, i, hwpath.bc[i]);
0300     }
0301     
0302     /* Store the final field */     
0303     hwpath.bc[i] = simple_strtoul(in, NULL, 10);
0304     DPRINTK("%s: bc[%d]: %d\n", __func__, i, hwpath.bc[i]);
0305     
0306     /* Now we check that the user isn't trying to lure us */
0307     if (!(dev = hwpath_to_device((struct hardware_path *)&hwpath))) {
0308         printk(KERN_WARNING "%s: attempt to set invalid \"%s\" "
0309             "hardware path: %s\n", __func__, entry->name, buf);
0310         return -EINVAL;
0311     }
0312     
0313     /* So far so good, let's get in deep */
0314     write_lock(&entry->rw_lock);
0315     entry->ready = 0;
0316     entry->dev = dev;
0317     
0318     /* Now, dive in. Write back to the hardware */
0319     pdcspath_store(entry);
0320     
0321     /* Update the symlink to the real device */
0322     sysfs_remove_link(&entry->kobj, "device");
0323     write_unlock(&entry->rw_lock);
0324 
0325     ret = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
0326     WARN_ON(ret);
0327 
0328     printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" path to \"%s\"\n",
0329         entry->name, buf);
0330     
0331     return count;
0332 }
0333 
0334 /**
0335  * pdcspath_layer_read - Extended layer (eg. SCSI ids) pretty printing.
0336  * @entry: An allocated and populated pdscpath_entry struct.
0337  * @buf: The output buffer to write to.
0338  * 
0339  * We will call this function to format the output of the layer attribute file.
0340  */
0341 static ssize_t
0342 pdcspath_layer_read(struct pdcspath_entry *entry, char *buf)
0343 {
0344     char *out = buf;
0345     struct device_path *devpath;
0346     short i;
0347 
0348     if (!entry || !buf)
0349         return -EINVAL;
0350     
0351     read_lock(&entry->rw_lock);
0352     devpath = &entry->devpath;
0353     i = entry->ready;
0354     read_unlock(&entry->rw_lock);
0355 
0356     if (!i) /* entry is not ready */
0357         return -ENODATA;
0358     
0359     for (i = 0; i < 6 && devpath->layers[i]; i++)
0360         out += sprintf(out, "%u ", devpath->layers[i]);
0361 
0362     out += sprintf(out, "\n");
0363     
0364     return out - buf;
0365 }
0366 
0367 /**
0368  * pdcspath_layer_write - This function handles extended layer modifying.
0369  * @entry: An allocated and populated pdscpath_entry struct.
0370  * @buf: The input buffer to read from.
0371  * @count: The number of bytes to be read.
0372  * 
0373  * We will call this function to change the current layer value.
0374  * Layers are to be given '.'-delimited, without brackets.
0375  * XXX beware we are far less checky WRT input data provided than for hwpath.
0376  * Potential harm can be done, since there's no way to check the validity of
0377  * the layer fields.
0378  */
0379 static ssize_t
0380 pdcspath_layer_write(struct pdcspath_entry *entry, const char *buf, size_t count)
0381 {
0382     unsigned int layers[6]; /* device-specific info (ctlr#, unit#, ...) */
0383     unsigned short i;
0384     char in[64], *temp;
0385 
0386     if (!entry || !buf || !count)
0387         return -EINVAL;
0388 
0389     /* We'll use a local copy of buf */
0390     count = min_t(size_t, count, sizeof(in)-1);
0391     strncpy(in, buf, count);
0392     in[count] = '\0';
0393     
0394     /* Let's clean up the target. 0 is a blank pattern */
0395     memset(&layers, 0, sizeof(layers));
0396     
0397     /* First, pick the first layer */
0398     if (unlikely(!isdigit(*in)))
0399         return -EINVAL;
0400     layers[0] = simple_strtoul(in, NULL, 10);
0401     DPRINTK("%s: layer[0]: %d\n", __func__, layers[0]);
0402     
0403     temp = in;
0404     for (i=1; ((temp = strchr(temp, '.'))) && (likely(i<6)); i++) {
0405         if (unlikely(!isdigit(*(++temp))))
0406             return -EINVAL;
0407         layers[i] = simple_strtoul(temp, NULL, 10);
0408         DPRINTK("%s: layer[%d]: %d\n", __func__, i, layers[i]);
0409     }
0410         
0411     /* So far so good, let's get in deep */
0412     write_lock(&entry->rw_lock);
0413     
0414     /* First, overwrite the current layers with the new ones, not touching
0415        the hardware path. */
0416     memcpy(&entry->devpath.layers, &layers, sizeof(layers));
0417     
0418     /* Now, dive in. Write back to the hardware */
0419     pdcspath_store(entry);
0420     write_unlock(&entry->rw_lock);
0421     
0422     printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" layers to \"%s\"\n",
0423         entry->name, buf);
0424     
0425     return count;
0426 }
0427 
0428 /**
0429  * pdcspath_attr_show - Generic read function call wrapper.
0430  * @kobj: The kobject to get info from.
0431  * @attr: The attribute looked upon.
0432  * @buf: The output buffer.
0433  */
0434 static ssize_t
0435 pdcspath_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
0436 {
0437     struct pdcspath_entry *entry = to_pdcspath_entry(kobj);
0438     struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);
0439     ssize_t ret = 0;
0440 
0441     if (pdcs_attr->show)
0442         ret = pdcs_attr->show(entry, buf);
0443 
0444     return ret;
0445 }
0446 
0447 /**
0448  * pdcspath_attr_store - Generic write function call wrapper.
0449  * @kobj: The kobject to write info to.
0450  * @attr: The attribute to be modified.
0451  * @buf: The input buffer.
0452  * @count: The size of the buffer.
0453  */
0454 static ssize_t
0455 pdcspath_attr_store(struct kobject *kobj, struct attribute *attr,
0456             const char *buf, size_t count)
0457 {
0458     struct pdcspath_entry *entry = to_pdcspath_entry(kobj);
0459     struct pdcspath_attribute *pdcs_attr = to_pdcspath_attribute(attr);
0460     ssize_t ret = 0;
0461 
0462     if (!capable(CAP_SYS_ADMIN))
0463         return -EACCES;
0464 
0465     if (pdcs_attr->store)
0466         ret = pdcs_attr->store(entry, buf, count);
0467 
0468     return ret;
0469 }
0470 
0471 static const struct sysfs_ops pdcspath_attr_ops = {
0472     .show = pdcspath_attr_show,
0473     .store = pdcspath_attr_store,
0474 };
0475 
0476 /* These are the two attributes of any PDC path. */
0477 static PATHS_ATTR(hwpath, 0644, pdcspath_hwpath_read, pdcspath_hwpath_write);
0478 static PATHS_ATTR(layer, 0644, pdcspath_layer_read, pdcspath_layer_write);
0479 
0480 static struct attribute *paths_subsys_attrs[] = {
0481     &paths_attr_hwpath.attr,
0482     &paths_attr_layer.attr,
0483     NULL,
0484 };
0485 ATTRIBUTE_GROUPS(paths_subsys);
0486 
0487 /* Specific kobject type for our PDC paths */
0488 static struct kobj_type ktype_pdcspath = {
0489     .sysfs_ops = &pdcspath_attr_ops,
0490     .default_groups = paths_subsys_groups,
0491 };
0492 
0493 /* We hard define the 4 types of path we expect to find */
0494 static PDCSPATH_ENTRY(PDCS_ADDR_PPRI, primary);
0495 static PDCSPATH_ENTRY(PDCS_ADDR_PCON, console);
0496 static PDCSPATH_ENTRY(PDCS_ADDR_PALT, alternative);
0497 static PDCSPATH_ENTRY(PDCS_ADDR_PKBD, keyboard);
0498 
0499 /* An array containing all PDC paths we will deal with */
0500 static struct pdcspath_entry *pdcspath_entries[] = {
0501     &pdcspath_entry_primary,
0502     &pdcspath_entry_alternative,
0503     &pdcspath_entry_console,
0504     &pdcspath_entry_keyboard,
0505     NULL,
0506 };
0507 
0508 
0509 /* For more insight of what's going on here, refer to PDC Procedures doc,
0510  * Section PDC_STABLE */
0511 
0512 /**
0513  * pdcs_size_read - Stable Storage size output.
0514  * @buf: The output buffer to write to.
0515  */
0516 static ssize_t pdcs_size_read(struct kobject *kobj,
0517                   struct kobj_attribute *attr,
0518                   char *buf)
0519 {
0520     char *out = buf;
0521 
0522     if (!buf)
0523         return -EINVAL;
0524 
0525     /* show the size of the stable storage */
0526     out += sprintf(out, "%ld\n", pdcs_size);
0527 
0528     return out - buf;
0529 }
0530 
0531 /**
0532  * pdcs_auto_read - Stable Storage autoboot/search flag output.
0533  * @buf: The output buffer to write to.
0534  * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag
0535  */
0536 static ssize_t pdcs_auto_read(struct kobject *kobj,
0537                   struct kobj_attribute *attr,
0538                   char *buf, int knob)
0539 {
0540     char *out = buf;
0541     struct pdcspath_entry *pathentry;
0542 
0543     if (!buf)
0544         return -EINVAL;
0545 
0546     /* Current flags are stored in primary boot path entry */
0547     pathentry = &pdcspath_entry_primary;
0548 
0549     read_lock(&pathentry->rw_lock);
0550     out += sprintf(out, "%s\n", (pathentry->devpath.flags & knob) ?
0551                     "On" : "Off");
0552     read_unlock(&pathentry->rw_lock);
0553 
0554     return out - buf;
0555 }
0556 
0557 /**
0558  * pdcs_autoboot_read - Stable Storage autoboot flag output.
0559  * @buf: The output buffer to write to.
0560  */
0561 static ssize_t pdcs_autoboot_read(struct kobject *kobj,
0562                   struct kobj_attribute *attr, char *buf)
0563 {
0564     return pdcs_auto_read(kobj, attr, buf, PF_AUTOBOOT);
0565 }
0566 
0567 /**
0568  * pdcs_autosearch_read - Stable Storage autoboot flag output.
0569  * @buf: The output buffer to write to.
0570  */
0571 static ssize_t pdcs_autosearch_read(struct kobject *kobj,
0572                     struct kobj_attribute *attr, char *buf)
0573 {
0574     return pdcs_auto_read(kobj, attr, buf, PF_AUTOSEARCH);
0575 }
0576 
0577 /**
0578  * pdcs_timer_read - Stable Storage timer count output (in seconds).
0579  * @buf: The output buffer to write to.
0580  *
0581  * The value of the timer field correponds to a number of seconds in powers of 2.
0582  */
0583 static ssize_t pdcs_timer_read(struct kobject *kobj,
0584                    struct kobj_attribute *attr, char *buf)
0585 {
0586     char *out = buf;
0587     struct pdcspath_entry *pathentry;
0588 
0589     if (!buf)
0590         return -EINVAL;
0591 
0592     /* Current flags are stored in primary boot path entry */
0593     pathentry = &pdcspath_entry_primary;
0594 
0595     /* print the timer value in seconds */
0596     read_lock(&pathentry->rw_lock);
0597     out += sprintf(out, "%u\n", (pathentry->devpath.flags & PF_TIMER) ?
0598                 (1 << (pathentry->devpath.flags & PF_TIMER)) : 0);
0599     read_unlock(&pathentry->rw_lock);
0600 
0601     return out - buf;
0602 }
0603 
0604 /**
0605  * pdcs_osid_read - Stable Storage OS ID register output.
0606  * @buf: The output buffer to write to.
0607  */
0608 static ssize_t pdcs_osid_read(struct kobject *kobj,
0609                   struct kobj_attribute *attr, char *buf)
0610 {
0611     char *out = buf;
0612 
0613     if (!buf)
0614         return -EINVAL;
0615 
0616     out += sprintf(out, "%s dependent data (0x%.4x)\n",
0617         os_id_to_string(pdcs_osid), pdcs_osid);
0618 
0619     return out - buf;
0620 }
0621 
0622 /**
0623  * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output.
0624  * @buf: The output buffer to write to.
0625  *
0626  * This can hold 16 bytes of OS-Dependent data.
0627  */
0628 static ssize_t pdcs_osdep1_read(struct kobject *kobj,
0629                 struct kobj_attribute *attr, char *buf)
0630 {
0631     char *out = buf;
0632     u32 result[4];
0633 
0634     if (!buf)
0635         return -EINVAL;
0636 
0637     if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK)
0638         return -EIO;
0639 
0640     out += sprintf(out, "0x%.8x\n", result[0]);
0641     out += sprintf(out, "0x%.8x\n", result[1]);
0642     out += sprintf(out, "0x%.8x\n", result[2]);
0643     out += sprintf(out, "0x%.8x\n", result[3]);
0644 
0645     return out - buf;
0646 }
0647 
0648 /**
0649  * pdcs_diagnostic_read - Stable Storage Diagnostic register output.
0650  * @buf: The output buffer to write to.
0651  *
0652  * I have NFC how to interpret the content of that register ;-).
0653  */
0654 static ssize_t pdcs_diagnostic_read(struct kobject *kobj,
0655                     struct kobj_attribute *attr, char *buf)
0656 {
0657     char *out = buf;
0658     u32 result;
0659 
0660     if (!buf)
0661         return -EINVAL;
0662 
0663     /* get diagnostic */
0664     if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK)
0665         return -EIO;
0666 
0667     out += sprintf(out, "0x%.4x\n", (result >> 16));
0668 
0669     return out - buf;
0670 }
0671 
0672 /**
0673  * pdcs_fastsize_read - Stable Storage FastSize register output.
0674  * @buf: The output buffer to write to.
0675  *
0676  * This register holds the amount of system RAM to be tested during boot sequence.
0677  */
0678 static ssize_t pdcs_fastsize_read(struct kobject *kobj,
0679                   struct kobj_attribute *attr, char *buf)
0680 {
0681     char *out = buf;
0682     u32 result;
0683 
0684     if (!buf)
0685         return -EINVAL;
0686 
0687     /* get fast-size */
0688     if (pdc_stable_read(PDCS_ADDR_FSIZ, &result, sizeof(result)) != PDC_OK)
0689         return -EIO;
0690 
0691     if ((result & 0x0F) < 0x0E)
0692         out += sprintf(out, "%d kB", (1<<(result & 0x0F))*256);
0693     else
0694         out += sprintf(out, "All");
0695     out += sprintf(out, "\n");
0696     
0697     return out - buf;
0698 }
0699 
0700 /**
0701  * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output.
0702  * @buf: The output buffer to write to.
0703  *
0704  * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available.
0705  */
0706 static ssize_t pdcs_osdep2_read(struct kobject *kobj,
0707                 struct kobj_attribute *attr, char *buf)
0708 {
0709     char *out = buf;
0710     unsigned long size;
0711     unsigned short i;
0712     u32 result;
0713 
0714     if (unlikely(pdcs_size <= 224))
0715         return -ENODATA;
0716 
0717     size = pdcs_size - 224;
0718 
0719     if (!buf)
0720         return -EINVAL;
0721 
0722     for (i=0; i<size; i+=4) {
0723         if (unlikely(pdc_stable_read(PDCS_ADDR_OSD2 + i, &result,
0724                     sizeof(result)) != PDC_OK))
0725             return -EIO;
0726         out += sprintf(out, "0x%.8x\n", result);
0727     }
0728 
0729     return out - buf;
0730 }
0731 
0732 /**
0733  * pdcs_auto_write - This function handles autoboot/search flag modifying.
0734  * @buf: The input buffer to read from.
0735  * @count: The number of bytes to be read.
0736  * @knob: The PF_AUTOBOOT or PF_AUTOSEARCH flag
0737  * 
0738  * We will call this function to change the current autoboot flag.
0739  * We expect a precise syntax:
0740  *  \"n\" (n == 0 or 1) to toggle AutoBoot Off or On
0741  */
0742 static ssize_t pdcs_auto_write(struct kobject *kobj,
0743                    struct kobj_attribute *attr, const char *buf,
0744                    size_t count, int knob)
0745 {
0746     struct pdcspath_entry *pathentry;
0747     unsigned char flags;
0748     char in[8], *temp;
0749     char c;
0750 
0751     if (!capable(CAP_SYS_ADMIN))
0752         return -EACCES;
0753 
0754     if (!buf || !count)
0755         return -EINVAL;
0756 
0757     /* We'll use a local copy of buf */
0758     count = min_t(size_t, count, sizeof(in)-1);
0759     strncpy(in, buf, count);
0760     in[count] = '\0';
0761 
0762     /* Current flags are stored in primary boot path entry */
0763     pathentry = &pdcspath_entry_primary;
0764     
0765     /* Be nice to the existing flag record */
0766     read_lock(&pathentry->rw_lock);
0767     flags = pathentry->devpath.flags;
0768     read_unlock(&pathentry->rw_lock);
0769     
0770     DPRINTK("%s: flags before: 0x%X\n", __func__, flags);
0771 
0772     temp = skip_spaces(in);
0773 
0774     c = *temp++ - '0';
0775     if ((c != 0) && (c != 1))
0776         goto parse_error;
0777     if (c == 0)
0778         flags &= ~knob;
0779     else
0780         flags |= knob;
0781     
0782     DPRINTK("%s: flags after: 0x%X\n", __func__, flags);
0783         
0784     /* So far so good, let's get in deep */
0785     write_lock(&pathentry->rw_lock);
0786     
0787     /* Change the path entry flags first */
0788     pathentry->devpath.flags = flags;
0789         
0790     /* Now, dive in. Write back to the hardware */
0791     pdcspath_store(pathentry);
0792     write_unlock(&pathentry->rw_lock);
0793     
0794     printk(KERN_INFO PDCS_PREFIX ": changed \"%s\" to \"%s\"\n",
0795         (knob & PF_AUTOBOOT) ? "autoboot" : "autosearch",
0796         (flags & knob) ? "On" : "Off");
0797     
0798     return count;
0799 
0800 parse_error:
0801     printk(KERN_WARNING "%s: Parse error: expect \"n\" (n == 0 or 1)\n", __func__);
0802     return -EINVAL;
0803 }
0804 
0805 /**
0806  * pdcs_autoboot_write - This function handles autoboot flag modifying.
0807  * @buf: The input buffer to read from.
0808  * @count: The number of bytes to be read.
0809  *
0810  * We will call this function to change the current boot flags.
0811  * We expect a precise syntax:
0812  *  \"n\" (n == 0 or 1) to toggle AutoSearch Off or On
0813  */
0814 static ssize_t pdcs_autoboot_write(struct kobject *kobj,
0815                    struct kobj_attribute *attr,
0816                    const char *buf, size_t count)
0817 {
0818     return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOBOOT);
0819 }
0820 
0821 /**
0822  * pdcs_autosearch_write - This function handles autosearch flag modifying.
0823  * @buf: The input buffer to read from.
0824  * @count: The number of bytes to be read.
0825  *
0826  * We will call this function to change the current boot flags.
0827  * We expect a precise syntax:
0828  *  \"n\" (n == 0 or 1) to toggle AutoSearch Off or On
0829  */
0830 static ssize_t pdcs_autosearch_write(struct kobject *kobj,
0831                      struct kobj_attribute *attr,
0832                      const char *buf, size_t count)
0833 {
0834     return pdcs_auto_write(kobj, attr, buf, count, PF_AUTOSEARCH);
0835 }
0836 
0837 /**
0838  * pdcs_osdep1_write - Stable Storage OS-Dependent data area 1 input.
0839  * @buf: The input buffer to read from.
0840  * @count: The number of bytes to be read.
0841  *
0842  * This can store 16 bytes of OS-Dependent data. We use a byte-by-byte
0843  * write approach. It's up to userspace to deal with it when constructing
0844  * its input buffer.
0845  */
0846 static ssize_t pdcs_osdep1_write(struct kobject *kobj,
0847                  struct kobj_attribute *attr,
0848                  const char *buf, size_t count)
0849 {
0850     u8 in[16];
0851 
0852     if (!capable(CAP_SYS_ADMIN))
0853         return -EACCES;
0854 
0855     if (!buf || !count)
0856         return -EINVAL;
0857 
0858     if (unlikely(pdcs_osid != OS_ID_LINUX))
0859         return -EPERM;
0860 
0861     if (count > 16)
0862         return -EMSGSIZE;
0863 
0864     /* We'll use a local copy of buf */
0865     memset(in, 0, 16);
0866     memcpy(in, buf, count);
0867 
0868     if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK)
0869         return -EIO;
0870 
0871     return count;
0872 }
0873 
0874 /**
0875  * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input.
0876  * @buf: The input buffer to read from.
0877  * @count: The number of bytes to be read.
0878  *
0879  * This can store pdcs_size - 224 bytes of OS-Dependent data. We use a
0880  * byte-by-byte write approach. It's up to userspace to deal with it when
0881  * constructing its input buffer.
0882  */
0883 static ssize_t pdcs_osdep2_write(struct kobject *kobj,
0884                  struct kobj_attribute *attr,
0885                  const char *buf, size_t count)
0886 {
0887     unsigned long size;
0888     unsigned short i;
0889     u8 in[4];
0890 
0891     if (!capable(CAP_SYS_ADMIN))
0892         return -EACCES;
0893 
0894     if (!buf || !count)
0895         return -EINVAL;
0896 
0897     if (unlikely(pdcs_size <= 224))
0898         return -ENOSYS;
0899 
0900     if (unlikely(pdcs_osid != OS_ID_LINUX))
0901         return -EPERM;
0902 
0903     size = pdcs_size - 224;
0904 
0905     if (count > size)
0906         return -EMSGSIZE;
0907 
0908     /* We'll use a local copy of buf */
0909 
0910     for (i=0; i<count; i+=4) {
0911         memset(in, 0, 4);
0912         memcpy(in, buf+i, (count-i < 4) ? count-i : 4);
0913         if (unlikely(pdc_stable_write(PDCS_ADDR_OSD2 + i, &in,
0914                     sizeof(in)) != PDC_OK))
0915             return -EIO;
0916     }
0917 
0918     return count;
0919 }
0920 
0921 /* The remaining attributes. */
0922 static PDCS_ATTR(size, 0444, pdcs_size_read, NULL);
0923 static PDCS_ATTR(autoboot, 0644, pdcs_autoboot_read, pdcs_autoboot_write);
0924 static PDCS_ATTR(autosearch, 0644, pdcs_autosearch_read, pdcs_autosearch_write);
0925 static PDCS_ATTR(timer, 0444, pdcs_timer_read, NULL);
0926 static PDCS_ATTR(osid, 0444, pdcs_osid_read, NULL);
0927 static PDCS_ATTR(osdep1, 0600, pdcs_osdep1_read, pdcs_osdep1_write);
0928 static PDCS_ATTR(diagnostic, 0400, pdcs_diagnostic_read, NULL);
0929 static PDCS_ATTR(fastsize, 0400, pdcs_fastsize_read, NULL);
0930 static PDCS_ATTR(osdep2, 0600, pdcs_osdep2_read, pdcs_osdep2_write);
0931 
0932 static struct attribute *pdcs_subsys_attrs[] = {
0933     &pdcs_attr_size.attr,
0934     &pdcs_attr_autoboot.attr,
0935     &pdcs_attr_autosearch.attr,
0936     &pdcs_attr_timer.attr,
0937     &pdcs_attr_osid.attr,
0938     &pdcs_attr_osdep1.attr,
0939     &pdcs_attr_diagnostic.attr,
0940     &pdcs_attr_fastsize.attr,
0941     &pdcs_attr_osdep2.attr,
0942     NULL,
0943 };
0944 
0945 static const struct attribute_group pdcs_attr_group = {
0946     .attrs = pdcs_subsys_attrs,
0947 };
0948 
0949 static struct kobject *stable_kobj;
0950 static struct kset *paths_kset;
0951 
0952 /**
0953  * pdcs_register_pathentries - Prepares path entries kobjects for sysfs usage.
0954  * 
0955  * It creates kobjects corresponding to each path entry with nice sysfs
0956  * links to the real device. This is where the magic takes place: when
0957  * registering the subsystem attributes during module init, each kobject hereby
0958  * created will show in the sysfs tree as a folder containing files as defined
0959  * by path_subsys_attr[].
0960  */
0961 static inline int __init
0962 pdcs_register_pathentries(void)
0963 {
0964     unsigned short i;
0965     struct pdcspath_entry *entry;
0966     int err;
0967     
0968     /* Initialize the entries rw_lock before anything else */
0969     for (i = 0; (entry = pdcspath_entries[i]); i++)
0970         rwlock_init(&entry->rw_lock);
0971 
0972     for (i = 0; (entry = pdcspath_entries[i]); i++) {
0973         write_lock(&entry->rw_lock);
0974         err = pdcspath_fetch(entry);
0975         write_unlock(&entry->rw_lock);
0976 
0977         if (err < 0)
0978             continue;
0979 
0980         entry->kobj.kset = paths_kset;
0981         err = kobject_init_and_add(&entry->kobj, &ktype_pdcspath, NULL,
0982                        "%s", entry->name);
0983         if (err) {
0984             kobject_put(&entry->kobj);
0985             return err;
0986         }
0987 
0988         /* kobject is now registered */
0989         write_lock(&entry->rw_lock);
0990         entry->ready = 2;
0991         write_unlock(&entry->rw_lock);
0992         
0993         /* Add a nice symlink to the real device */
0994         if (entry->dev) {
0995             err = sysfs_create_link(&entry->kobj, &entry->dev->kobj, "device");
0996             WARN_ON(err);
0997         }
0998 
0999         kobject_uevent(&entry->kobj, KOBJ_ADD);
1000     }
1001     
1002     return 0;
1003 }
1004 
1005 /**
1006  * pdcs_unregister_pathentries - Routine called when unregistering the module.
1007  */
1008 static inline void
1009 pdcs_unregister_pathentries(void)
1010 {
1011     unsigned short i;
1012     struct pdcspath_entry *entry;
1013     
1014     for (i = 0; (entry = pdcspath_entries[i]); i++) {
1015         read_lock(&entry->rw_lock);
1016         if (entry->ready >= 2)
1017             kobject_put(&entry->kobj);
1018         read_unlock(&entry->rw_lock);
1019     }
1020 }
1021 
1022 /*
1023  * For now we register the stable subsystem with the firmware subsystem
1024  * and the paths subsystem with the stable subsystem
1025  */
1026 static int __init
1027 pdc_stable_init(void)
1028 {
1029     int rc = 0, error = 0;
1030     u32 result;
1031 
1032     /* find the size of the stable storage */
1033     if (pdc_stable_get_size(&pdcs_size) != PDC_OK) 
1034         return -ENODEV;
1035 
1036     /* make sure we have enough data */
1037     if (pdcs_size < 96)
1038         return -ENODATA;
1039 
1040     printk(KERN_INFO PDCS_PREFIX " facility v%s\n", PDCS_VERSION);
1041 
1042     /* get OSID */
1043     if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK)
1044         return -EIO;
1045 
1046     /* the actual result is 16 bits away */
1047     pdcs_osid = (u16)(result >> 16);
1048 
1049     /* For now we'll register the directory at /sys/firmware/stable */
1050     stable_kobj = kobject_create_and_add("stable", firmware_kobj);
1051     if (!stable_kobj) {
1052         rc = -ENOMEM;
1053         goto fail_firmreg;
1054     }
1055 
1056     /* Don't forget the root entries */
1057     error = sysfs_create_group(stable_kobj, &pdcs_attr_group);
1058 
1059     /* register the paths kset as a child of the stable kset */
1060     paths_kset = kset_create_and_add("paths", NULL, stable_kobj);
1061     if (!paths_kset) {
1062         rc = -ENOMEM;
1063         goto fail_ksetreg;
1064     }
1065 
1066     /* now we create all "files" for the paths kset */
1067     if ((rc = pdcs_register_pathentries()))
1068         goto fail_pdcsreg;
1069 
1070     return rc;
1071     
1072 fail_pdcsreg:
1073     pdcs_unregister_pathentries();
1074     kset_unregister(paths_kset);
1075     
1076 fail_ksetreg:
1077     kobject_put(stable_kobj);
1078     
1079 fail_firmreg:
1080     printk(KERN_INFO PDCS_PREFIX " bailing out\n");
1081     return rc;
1082 }
1083 
1084 static void __exit
1085 pdc_stable_exit(void)
1086 {
1087     pdcs_unregister_pathentries();
1088     kset_unregister(paths_kset);
1089     kobject_put(stable_kobj);
1090 }
1091 
1092 
1093 module_init(pdc_stable_init);
1094 module_exit(pdc_stable_exit);