linux/include/linux/nvram.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0 */
   2#ifndef _LINUX_NVRAM_H
   3#define _LINUX_NVRAM_H
   4
   5#include <linux/errno.h>
   6#include <uapi/linux/nvram.h>
   7
   8#ifdef CONFIG_PPC
   9#include <asm/machdep.h>
  10#endif
  11
  12/**
  13 * struct nvram_ops - NVRAM functionality made available to drivers
  14 * @read: validate checksum (if any) then load a range of bytes from NVRAM
  15 * @write: store a range of bytes to NVRAM then update checksum (if any)
  16 * @read_byte: load a single byte from NVRAM
  17 * @write_byte: store a single byte to NVRAM
  18 * @get_size: return the fixed number of bytes in the NVRAM
  19 *
  20 * Architectures which provide an nvram ops struct need not implement all
  21 * of these methods. If the NVRAM hardware can be accessed only one byte
  22 * at a time then it may be sufficient to provide .read_byte and .write_byte.
  23 * If the NVRAM has a checksum (and it is to be checked) the .read and
  24 * .write methods can be used to implement that efficiently.
  25 *
  26 * Portable drivers may use the wrapper functions defined here.
  27 * The nvram_read() and nvram_write() functions call the .read and .write
  28 * methods when available and fall back on the .read_byte and .write_byte
  29 * methods otherwise.
  30 */
  31
  32struct nvram_ops {
  33        ssize_t         (*get_size)(void);
  34        unsigned char   (*read_byte)(int);
  35        void            (*write_byte)(unsigned char, int);
  36        ssize_t         (*read)(char *, size_t, loff_t *);
  37        ssize_t         (*write)(char *, size_t, loff_t *);
  38#if defined(CONFIG_X86) || defined(CONFIG_M68K)
  39        long            (*initialize)(void);
  40        long            (*set_checksum)(void);
  41#endif
  42};
  43
  44extern const struct nvram_ops arch_nvram_ops;
  45
  46static inline ssize_t nvram_get_size(void)
  47{
  48#ifdef CONFIG_PPC
  49        if (ppc_md.nvram_size)
  50                return ppc_md.nvram_size();
  51#else
  52        if (arch_nvram_ops.get_size)
  53                return arch_nvram_ops.get_size();
  54#endif
  55        return -ENODEV;
  56}
  57
  58static inline unsigned char nvram_read_byte(int addr)
  59{
  60#ifdef CONFIG_PPC
  61        if (ppc_md.nvram_read_val)
  62                return ppc_md.nvram_read_val(addr);
  63#else
  64        if (arch_nvram_ops.read_byte)
  65                return arch_nvram_ops.read_byte(addr);
  66#endif
  67        return 0xFF;
  68}
  69
  70static inline void nvram_write_byte(unsigned char val, int addr)
  71{
  72#ifdef CONFIG_PPC
  73        if (ppc_md.nvram_write_val)
  74                ppc_md.nvram_write_val(addr, val);
  75#else
  76        if (arch_nvram_ops.write_byte)
  77                arch_nvram_ops.write_byte(val, addr);
  78#endif
  79}
  80
  81static inline ssize_t nvram_read_bytes(char *buf, size_t count, loff_t *ppos)
  82{
  83        ssize_t nvram_size = nvram_get_size();
  84        loff_t i;
  85        char *p = buf;
  86
  87        if (nvram_size < 0)
  88                return nvram_size;
  89        for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
  90                *p = nvram_read_byte(i);
  91        *ppos = i;
  92        return p - buf;
  93}
  94
  95static inline ssize_t nvram_write_bytes(char *buf, size_t count, loff_t *ppos)
  96{
  97        ssize_t nvram_size = nvram_get_size();
  98        loff_t i;
  99        char *p = buf;
 100
 101        if (nvram_size < 0)
 102                return nvram_size;
 103        for (i = *ppos; count > 0 && i < nvram_size; ++i, ++p, --count)
 104                nvram_write_byte(*p, i);
 105        *ppos = i;
 106        return p - buf;
 107}
 108
 109static inline ssize_t nvram_read(char *buf, size_t count, loff_t *ppos)
 110{
 111#ifdef CONFIG_PPC
 112        if (ppc_md.nvram_read)
 113                return ppc_md.nvram_read(buf, count, ppos);
 114#else
 115        if (arch_nvram_ops.read)
 116                return arch_nvram_ops.read(buf, count, ppos);
 117#endif
 118        return nvram_read_bytes(buf, count, ppos);
 119}
 120
 121static inline ssize_t nvram_write(char *buf, size_t count, loff_t *ppos)
 122{
 123#ifdef CONFIG_PPC
 124        if (ppc_md.nvram_write)
 125                return ppc_md.nvram_write(buf, count, ppos);
 126#else
 127        if (arch_nvram_ops.write)
 128                return arch_nvram_ops.write(buf, count, ppos);
 129#endif
 130        return nvram_write_bytes(buf, count, ppos);
 131}
 132
 133#endif  /* _LINUX_NVRAM_H */
 134