File: CmosRW.cpp

package info (click to toggle)
libsmbios 2.0.3.dfsg-1.1
  • links: PTS
  • area: main
  • in suites: squeeze, wheezy
  • size: 3,768 kB
  • ctags: 2,016
  • sloc: cpp: 14,292; sh: 9,408; xml: 3,820; makefile: 454; ansic: 402; python: 157
file content (167 lines) | stat: -rw-r--r-- 4,802 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
 *
 * Copyright (C) 2005 Dell Inc.
 *  by Michael Brown <Michael_E_Brown@dell.com>
 * Licensed under the Open Software License version 2.1
 *
 * Alternatively, you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published
 * by the Free Software Foundation; either version 2 of the License,
 * or (at your option) any later version.

 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 */

// compat header should always be first header if including system headers
#define LIBSMBIOS_SOURCE
#include "smbios/compat.h"
#include <errno.h>
#include <string.h>
#include "CmosRWImpl.h"

using namespace std;

namespace cmos
{

    //
    // NON-MEMBER FUNCTIONS
    //
    void readByteArray ( const ICmosRW &cmos, u32 indexPort, u32 dataPort, u32 offset, u8 * target, u32 count)
    {
        for (u32 i = 0; i < count; ++i)
        {
            target[i] = cmos.readByte (indexPort, dataPort, offset + i);
        }
    }

    void writeByteArray ( const ICmosRW &cmos, u32 indexPort, u32 dataPort, u32 offset, const u8 * source, u32 count)
    {
        const Suppressable *s = dynamic_cast<const Suppressable *>(&cmos);
        if(s)
            s->suppressNotification();
        for (u32 i = 0; i < count; ++i)
        {
            cmos.writeByte (indexPort, dataPort, offset + i, source[i]);
        }
        if(s)
            s->resumeNotification();
    }



    //
    // Suppressable
    //
    // This class is used to supress ->notify() calls inside an Observable
    // class. This lets us do many operations that may cause spurious
    // notifications. This would also probably let us do some simple
    // transaction-like operations.
    //
    Suppressable::Suppressable()
            : suppressNotify(false)
    {}

    Suppressable::~Suppressable()
    {}

    void Suppressable::suppressNotification(bool sup) const
    {
        suppressNotify = sup;
    }

    void Suppressable::resumeNotification(bool doNotify) const
    {
        const observer::IObservable *o = dynamic_cast<const observer::IObservable *>(this);
        if(o && doNotify)
            o->notify();

        suppressNotify = false;
    }

    bool Suppressable::isNotifySuppressed() const
    {
        return suppressNotify;
    }

    //
    // ICmosRW functions
    //
    ICmosRW::ICmosRW()
    {}

    ICmosRW::~ICmosRW()
    {}

    //
    // CmosRWFile functions
    //

    // REGULAR CONSTRUCTOR
    CmosRWFile::CmosRWFile ( const string &File )
            :ICmosRW(), Suppressable(), fileName (File)
    {}

    // DESTRUCTOR
    CmosRWFile::~CmosRWFile()
    {}

    CmosRWIo::~CmosRWIo()
    {}

    // TODO: need to throw exception on problem with file
    //
    u8 CmosRWFile::readByte (u32 indexPort, u32 dataPort, u32 offset) const
    {
        u8 retval = 0xFF;
        u32 realOffset = indexPort * 256 + offset;
        (void) dataPort; // unused
        string errMessage("Could not open CMOS file(" + fileName + ") for reading: ");

        FILE *fh = fopen (fileName.c_str (), "rb");
        if( !fh )
            throw smbios::InternalErrorImpl(errMessage + strerror(errno));

        fseek (fh, static_cast<long>(realOffset), SEEK_SET);
        size_t numBytes = fread (&retval, 1, sizeof (retval), fh); // only used in unit tests, so isnt critical
        fclose (fh);
        if (numBytes != sizeof(retval))
            throw std::exception(); // short read. there isnt really a good exception to throw here.

        return retval;
    }

    // TODO: need to throw exception on problem with file
    //
    void CmosRWFile::writeByte (u32 indexPort, u32 dataPort, u32 offset, u8 byte) const
    {
        //cout << "w(" << offset << ")";
        u32 realOffset = indexPort * 256 + offset;
        (void) dataPort; // unused
        string errMessage("Could not open CMOS file(" + fileName + ") for writing: ");

        FILE *fh = fopen (fileName.c_str (), "r+b");
        if( !fh )
            throw smbios::InternalErrorImpl(errMessage + strerror(errno));

        fseek (fh, static_cast<long>(realOffset), SEEK_SET);
        fwrite (&byte, 1, sizeof (byte), fh);
        fclose (fh);
        fflush(NULL);

        if(! isNotifySuppressed() )
        {
            // writers are responsible for only writing changed values
            // otherwise we get to see how fast our OS can do an
            // infinite loop. :-)
            notify();
        }
        return;
    }


}