Source
x
// SPDX-License-Identifier: GPL-2.0-only
/*
* Interfaces to retrieve and set PDC Stable options (firmware)
*
* Copyright (C) 2005-2006 Thibaut VARENE <varenet@parisc-linux.org>
*
* DEV NOTE: the PDC Procedures reference states that:
* "A minimum of 96 bytes of Stable Storage is required. Providing more than
* 96 bytes of Stable Storage is optional [...]. Failure to provide the
* optional locations from 96 to 192 results in the loss of certain
* functionality during boot."
*
* Since locations between 96 and 192 are the various paths, most (if not
* all) PA-RISC machines should have them. Anyway, for safety reasons, the
* following code can deal with just 96 bytes of Stable Storage, and all
* sizes between 96 and 192 bytes (provided they are multiple of struct
* device_path size, eg: 128, 160 and 192) to provide full information.
* One last word: there's one path we can always count on: the primary path.
* Anything above 224 bytes is used for 'osdep2' OS-dependent storage area.
*
* The first OS-dependent area should always be available. Obviously, this is
* not true for the other one. Also bear in mind that reading/writing from/to
* osdep2 is much more expensive than from/to osdep1.
* NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first
* 2 bytes of storage available right after OSID. That's a total of 4 bytes
* sacrificed: -ETOOLAZY :P
*
* The current policy wrt file permissions is:
* - write: root only
* - read: (reading triggers PDC calls) ? root only : everyone
* The rationale is that PDC calls could hog (DoS) the machine.
*
* TODO:
* - timer/fastsize write calls
*/
MODULE_AUTHOR("Thibaut VARENE <varenet@parisc-linux.org>");
MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data");
MODULE_LICENSE("GPL");
MODULE_VERSION(PDCS_VERSION);
/* holds Stable Storage size. Initialized once and for all, no lock needed */
static unsigned long pdcs_size __read_mostly;
/* holds OS ID. Initialized once and for all, hopefully to 0x0006 */
static u16 pdcs_osid __read_mostly;
/* This struct defines what we need to deal with a parisc pdc path entry */
struct pdcspath_entry {
rwlock_t rw_lock; /* to protect path entry access */
short ready; /* entry record is valid if != 0 */
unsigned long addr; /* entry address in stable storage */
char *name; /* entry name */
struct device_path devpath; /* device path in parisc representation */
struct device *dev; /* corresponding device */