Smi_Linux.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 
00023 #include <sys/file.h>
00024 
00025 #include "SmiImpl.h"
00026 
00027 using namespace std;
00028 
00029 #define SMI_DATA_FILE       "/sys/devices/platform/dcdbas/smi_data"
00030 #define SMI_PHYS_ADDR_FILE  "/sys/devices/platform/dcdbas/smi_data_buf_phys_addr"
00031 #define SMI_DO_REQUEST_FILE "/sys/devices/platform/dcdbas/smi_request"
00032 #define SMI_BUF_SIZE_FILE   "/sys/devices/platform/dcdbas/smi_data_buf_size"
00033 
00034 //#define SMI_DATA_FILE       "/tmp/smi_data"
00035 //#define SMI_PHYS_ADDR_FILE  "/tmp/smi_data_buf_phys_addr"
00036 //#define SMI_DO_REQUEST_FILE "/tmp/smi_request"
00037 
00038 struct smiLinuxPrivateData
00039 {
00040     FILE *fh_data;
00041     FILE *fh_doReq;
00042 };
00043 
00044 namespace smi
00045 {
00046     SmiArchStrategy::SmiArchStrategy()
00047     {
00048         privateData = new smiLinuxPrivateData;
00049         memset(privateData, 0, sizeof(smiLinuxPrivateData));
00050     }
00051 
00052     SmiArchStrategy::~SmiArchStrategy()
00053     {
00054         smiLinuxPrivateData *tmpPrivPtr = reinterpret_cast<smiLinuxPrivateData *>(privateData);
00055 
00056         if(tmpPrivPtr->fh_data)
00057             fclose(tmpPrivPtr->fh_data);
00058 
00059         if(tmpPrivPtr->fh_doReq)
00060             fclose(tmpPrivPtr->fh_doReq);
00061 
00062         delete tmpPrivPtr;
00063         privateData = 0;
00064     }
00065 
00066     void SmiArchStrategy::lock()
00067     {
00068         smiLinuxPrivateData *tmpPrivPtr = reinterpret_cast<smiLinuxPrivateData *>(privateData);
00069 
00070 
00071         tmpPrivPtr->fh_data = fopen(SMI_DATA_FILE, "r+b");
00072         if( ! tmpPrivPtr->fh_data )
00073             throw smbios::InternalErrorImpl("Could not open file " SMI_DATA_FILE ". Check that dcdbas driver is properly loaded.");
00074 
00075         tmpPrivPtr->fh_doReq = fopen(SMI_DO_REQUEST_FILE, "wb");
00076         if( ! tmpPrivPtr->fh_doReq)
00077             throw smbios::InternalErrorImpl("Could not open file " SMI_DO_REQUEST_FILE ". Check that dcdbas driver is properly loaded.");
00078 
00079         flock( fileno(tmpPrivPtr->fh_data), LOCK_EX );
00080 
00081         fseek(tmpPrivPtr->fh_doReq, 0L, 0);
00082         fwrite("0", 1, 1, tmpPrivPtr->fh_doReq);
00083         fseek(tmpPrivPtr->fh_doReq, 0L, 0);
00084     }
00085 
00086     size_t SmiArchStrategy::getPhysicalBufferBaseAddress()
00087     {
00088         const int bufSize=63;
00089         char tmpBuf[bufSize+1] = {0,};
00090         size_t retval = 0;
00091 
00092         fflush(NULL);
00093 
00094         FILE *fh = fopen(SMI_PHYS_ADDR_FILE, "rb");
00095         if( ! fh )
00096             throw smbios::InternalErrorImpl("Could not open file " SMI_PHYS_ADDR_FILE ". Check that dcdbas driver is properly loaded.");
00097 
00098         fseek(fh, 0L, 0);
00099         size_t numBytes = fread(tmpBuf, 1, bufSize, fh);
00100         fclose(fh);
00101         fh=0;
00102         if (!numBytes) // dont care how many bytes as long as we get at least 1.
00103             throw smbios::InternalErrorImpl("Short read from physical address file. Driver problem?");
00104 
00105         retval = strtoll(tmpBuf, NULL, 16);
00106 
00107         return retval;
00108     }
00109 
00110     void SmiArchStrategy::setSize(int newSize)
00111     {
00112         const int bufSize=63;
00113         char tmpBuf[bufSize+1] = {0,};
00114 
00115         fflush(NULL);
00116 
00117         FILE *fh = fopen(SMI_BUF_SIZE_FILE, "w+b");
00118         if( ! fh )
00119             throw smbios::InternalErrorImpl("Could not open file " SMI_BUF_SIZE_FILE ". Check that dcdbas driver is properly loaded.");
00120 
00121         snprintf(tmpBuf, bufSize, "%d", newSize);
00122         fwrite(tmpBuf, 1, bufSize, fh);
00123         fclose(fh);
00124 
00125         fflush(NULL);
00126         fh=0;
00127     }
00128 
00129     void SmiArchStrategy::addInputBuffer(u8 *buffer, size_t size)
00130     {
00131         smiLinuxPrivateData *tmpPrivPtr = reinterpret_cast<smiLinuxPrivateData *>(privateData);
00132         fwrite(buffer,  1,  size,  tmpPrivPtr->fh_data);
00133     }
00134 
00135     void SmiArchStrategy::getResultBuffer(u8 *buffer, size_t size)
00136     {
00137         smiLinuxPrivateData *tmpPrivPtr = reinterpret_cast<smiLinuxPrivateData *>(privateData);
00138         fflush(NULL);
00139         int numbytes = fread(buffer,  1,  size,  tmpPrivPtr->fh_data);
00140         if (!numbytes)
00141             throw smbios::InternalErrorImpl("Short read from file handle");
00142     }
00143 
00144 
00145     void SmiArchStrategy::execute()
00146     {
00147         smiLinuxPrivateData *tmpPrivPtr = reinterpret_cast<smiLinuxPrivateData *>(privateData);
00148         fflush(NULL);
00149         fwrite("1", 1, 1, tmpPrivPtr->fh_doReq);
00150         fflush(NULL);
00151         fseek(tmpPrivPtr->fh_data, 0L, 0);
00152     }
00153 
00154     void SmiArchStrategy::finish()
00155     {
00156         smiLinuxPrivateData *tmpPrivPtr = reinterpret_cast<smiLinuxPrivateData *>(privateData);
00157         flock( fileno(tmpPrivPtr->fh_data), LOCK_UN );
00158         fclose(tmpPrivPtr->fh_doReq);
00159         fclose(tmpPrivPtr->fh_data);
00160 
00161         tmpPrivPtr->fh_doReq=0;
00162         tmpPrivPtr->fh_data=0;
00163     }
00164 }
00165 

Generated on Tue Aug 28 01:56:18 2007 for SMBIOS Library by  doxygen 1.5.2