CmosRW.cpp

Go to the documentation of this file.
00001 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
00002  * vim:expandtab:autoindent:tabstop=4:shiftwidth=4:filetype=c:cindent:textwidth=0:
00003  *
00004  * Copyright (C) 2005 Dell Inc.
00005  *  by Michael Brown <Michael_E_Brown@dell.com>
00006  * Licensed under the Open Software License version 2.1
00007  *
00008  * Alternatively, you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published
00010  * by the Free Software Foundation; either version 2 of the License,
00011  * or (at your option) any later version.
00012 
00013  * This program is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00016  * See the GNU General Public License for more details.
00017  */
00018 
00019 // compat header should always be first header if including system headers
00020 #define LIBSMBIOS_SOURCE
00021 #include "smbios/compat.h"
00022 #include <errno.h>
00023 #include "CmosRWImpl.h"
00024 
00025 using namespace std;
00026 
00027 namespace cmos
00028 {
00029 
00030     //
00031     // NON-MEMBER FUNCTIONS
00032     //
00033     void readByteArray ( const ICmosRW &cmos, u32 indexPort, u32 dataPort, u32 offset, u8 * target, u32 count)
00034     {
00035         for (u32 i = 0; i < count; ++i)
00036         {
00037             target[i] = cmos.readByte (indexPort, dataPort, offset + i);
00038         }
00039     }
00040 
00041     void writeByteArray ( const ICmosRW &cmos, u32 indexPort, u32 dataPort, u32 offset, const u8 * source, u32 count)
00042     {
00043         const Suppressable *s = dynamic_cast<const Suppressable *>(&cmos);
00044         if(s)
00045             s->suppressNotification();
00046         for (u32 i = 0; i < count; ++i)
00047         {
00048             cmos.writeByte (indexPort, dataPort, offset + i, source[i]);
00049         }
00050         if(s)
00051             s->resumeNotification();
00052     }
00053 
00054 
00055 
00056     //
00057     // Suppressable
00058     //
00059     // This class is used to supress ->notify() calls inside an Observable
00060     // class. This lets us do many operations that may cause spurious
00061     // notifications. This would also probably let us do some simple
00062     // transaction-like operations.
00063     //
00064     Suppressable::Suppressable()
00065             : suppressNotify(false)
00066     {}
00067 
00068     Suppressable::~Suppressable()
00069     {}
00070 
00071     void Suppressable::suppressNotification(bool sup) const
00072     {
00073         suppressNotify = sup;
00074     }
00075 
00076     void Suppressable::resumeNotification(bool doNotify) const
00077     {
00078         const observer::IObservable *o = dynamic_cast<const observer::IObservable *>(this);
00079         if(o && doNotify)
00080             o->notify();
00081 
00082         suppressNotify = false;
00083     }
00084 
00085     bool Suppressable::isNotifySuppressed() const
00086     {
00087         return suppressNotify;
00088     }
00089 
00090     //
00091     // ICmosRW functions
00092     //
00093     ICmosRW::ICmosRW()
00094     {}
00095 
00096     ICmosRW::~ICmosRW()
00097     {}
00098 
00099     //
00100     // CmosRWFile functions
00101     //
00102 
00103     // REGULAR CONSTRUCTOR
00104     CmosRWFile::CmosRWFile ( const string &File )
00105             :ICmosRW(), Suppressable(), fileName (File)
00106     {}
00107 
00108     // DESTRUCTOR
00109     CmosRWFile::~CmosRWFile()
00110     {}
00111 
00112     CmosRWIo::~CmosRWIo()
00113     {}
00114 
00115     // TODO: need to throw exception on problem with file
00116     //
00117     u8 CmosRWFile::readByte (u32 indexPort, u32 dataPort, u32 offset) const
00118     {
00119         u8 retval = 0xFF;
00120         u32 realOffset = indexPort * 256 + offset;
00121         (void) dataPort; // unused
00122         string errMessage("Could not open CMOS file(" + fileName + ") for reading: ");
00123 
00124         FILE *fh = fopen (fileName.c_str (), "rb");
00125         if( !fh )
00126             throw smbios::InternalErrorImpl(errMessage + strerror(errno));
00127 
00128         fseek (fh, static_cast<long>(realOffset), SEEK_SET);
00129         size_t numBytes = fread (&retval, 1, sizeof (retval), fh); // only used in unit tests, so isnt critical
00130         fclose (fh);
00131         if (numBytes != sizeof(retval))
00132             throw std::exception(); // short read. there isnt really a good exception to throw here.
00133 
00134         return retval;
00135     }
00136 
00137     // TODO: need to throw exception on problem with file
00138     //
00139     void CmosRWFile::writeByte (u32 indexPort, u32 dataPort, u32 offset, u8 byte) const
00140     {
00141         //cout << "w(" << offset << ")";
00142         u32 realOffset = indexPort * 256 + offset;
00143         (void) dataPort; // unused
00144         string errMessage("Could not open CMOS file(" + fileName + ") for writing: ");
00145 
00146         FILE *fh = fopen (fileName.c_str (), "r+b");
00147         if( !fh )
00148             throw smbios::InternalErrorImpl(errMessage + strerror(errno));
00149 
00150         fseek (fh, static_cast<long>(realOffset), SEEK_SET);
00151         fwrite (&byte, 1, sizeof (byte), fh);
00152         fclose (fh);
00153         fflush(NULL);
00154 
00155         if(! isNotifySuppressed() )
00156         {
00157             // writers are responsible for only writing changed values
00158             // otherwise we get to see how fast our OS can do an
00159             // infinite loop. :-)
00160             notify();
00161         }
00162         return;
00163     }
00164 
00165 
00166 }

Generated on Tue Feb 26 14:51:55 2008 for SMBIOS Library by  doxygen 1.4.7