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