• Main Page
  • Related Pages
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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 <stdio.h>
00023 #include <errno.h>
00024 #include <string.h>
00025 #include "CmosRWImpl.h"
00026 
00027 using namespace std;
00028 
00029 namespace cmos
00030 {
00031 
00032     //
00033     // NON-MEMBER FUNCTIONS
00034     //
00035     void readByteArray ( const ICmosRW &cmos, u32 indexPort, u32 dataPort, u32 offset, u8 * target, u32 count)
00036     {
00037         for (u32 i = 0; i < count; ++i)
00038         {
00039             target[i] = cmos.readByte (indexPort, dataPort, offset + i);
00040         }
00041     }
00042 
00043     void writeByteArray ( const ICmosRW &cmos, u32 indexPort, u32 dataPort, u32 offset, const u8 * source, u32 count)
00044     {
00045         const Suppressable *s = dynamic_cast<const Suppressable *>(&cmos);
00046         if(s)
00047             s->suppressNotification();
00048         for (u32 i = 0; i < count; ++i)
00049         {
00050             cmos.writeByte (indexPort, dataPort, offset + i, source[i]);
00051         }
00052         if(s)
00053             s->resumeNotification();
00054     }
00055 
00056 
00057 
00058     //
00059     // Suppressable
00060     //
00061     // This class is used to supress ->notify() calls inside an Observable
00062     // class. This lets us do many operations that may cause spurious
00063     // notifications. This would also probably let us do some simple
00064     // transaction-like operations.
00065     //
00066     Suppressable::Suppressable()
00067             : suppressNotify(false)
00068     {}
00069 
00070     Suppressable::~Suppressable()
00071     {}
00072 
00073     void Suppressable::suppressNotification(bool sup) const
00074     {
00075         suppressNotify = sup;
00076     }
00077 
00078     void Suppressable::resumeNotification(bool doNotify) const
00079     {
00080         const observer::IObservable *o = dynamic_cast<const observer::IObservable *>(this);
00081         if(o && doNotify)
00082             o->notify();
00083 
00084         suppressNotify = false;
00085     }
00086 
00087     bool Suppressable::isNotifySuppressed() const
00088     {
00089         return suppressNotify;
00090     }
00091 
00092     //
00093     // ICmosRW functions
00094     //
00095     ICmosRW::ICmosRW()
00096     {}
00097 
00098     ICmosRW::~ICmosRW()
00099     {}
00100 
00101     //
00102     // CmosRWFile functions
00103     //
00104 
00105     // REGULAR CONSTRUCTOR
00106     CmosRWFile::CmosRWFile ( const string &File )
00107             :ICmosRW(), Suppressable(), fileName (File)
00108     {}
00109 
00110     // DESTRUCTOR
00111     CmosRWFile::~CmosRWFile()
00112     {}
00113 
00114     CmosRWIo::~CmosRWIo()
00115     {}
00116 
00117     // TODO: need to throw exception on problem with file
00118     //
00119     u8 CmosRWFile::readByte (u32 indexPort, u32 dataPort, u32 offset) const
00120     {
00121         u8 retval = 0xFF;
00122         u32 realOffset = indexPort * 256 + offset;
00123         (void) dataPort; // unused
00124         string errMessage("Could not open CMOS file(" + fileName + ") for reading: ");
00125 
00126         FILE *fh = fopen (fileName.c_str (), "rb");
00127         if( !fh )
00128             throw smbios::InternalErrorImpl(errMessage + strerror(errno));
00129 
00130         fseek (fh, static_cast<long>(realOffset), SEEK_SET);
00131         size_t numBytes = fread (&retval, 1, sizeof (retval), fh); // only used in unit tests, so isnt critical
00132         fclose (fh);
00133         if (numBytes != sizeof(retval))
00134             throw std::exception(); // short read. there isnt really a good exception to throw here.
00135 
00136         return retval;
00137     }
00138 
00139     // TODO: need to throw exception on problem with file
00140     //
00141     void CmosRWFile::writeByte (u32 indexPort, u32 dataPort, u32 offset, u8 byte) const
00142     {
00143         //cout << "w(" << offset << ")";
00144         u32 realOffset = indexPort * 256 + offset;
00145         (void) dataPort; // unused
00146         string errMessage("Could not open CMOS file(" + fileName + ") for writing: ");
00147 
00148         FILE *fh = fopen (fileName.c_str (), "r+b");
00149         if( !fh )
00150             throw smbios::InternalErrorImpl(errMessage + strerror(errno));
00151 
00152         fseek (fh, static_cast<long>(realOffset), SEEK_SET);
00153         fwrite (&byte, 1, sizeof (byte), fh);
00154         fclose (fh);
00155         fflush(NULL);
00156 
00157         if(! isNotifySuppressed() )
00158         {
00159             // writers are responsible for only writing changed values
00160             // otherwise we get to see how fast our OS can do an
00161             // infinite loop. :-)
00162             notify();
00163         }
00164         return;
00165     }
00166 
00167 
00168 }

Generated on Sun Aug 22 2010 14:38:30 for SMBIOS Library by  doxygen 1.7.1