00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
00035
00036
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)
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