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 #define LIBSMBIOS_SOURCE 00020 #include "SmiImpl.h" 00021 #include "FactoryImpl2.h" 00022 #include "TokenImpl.h" 00023 00024 // message.h should be included last. 00025 #include "smbios/message.h" 00026 00027 using namespace std; 00028 00029 namespace smi 00030 { 00031 class SmiFactoryImpl : public factory::TFactory<SmiFactory> 00032 { 00033 public: 00034 SmiFactoryImpl() { setParameter("smiFile", ""); }; 00035 virtual ~SmiFactoryImpl() throw() {}; 00036 virtual std::auto_ptr<ISmi> makeNew(u8 type); // use me 00037 protected: 00038 static ISmi *_cmosPtr; 00039 }; 00040 00041 // 00042 SmiFactory::~SmiFactory() throw() 00043 {} 00044 SmiFactory::SmiFactory() 00045 {} 00046 00047 SmiFactory *SmiFactory::getFactory() 00048 { 00049 // reinterpret_cast<...>(0) to ensure template parameter is correct 00050 // this is a workaround for VC6 which cannot use explicit member template 00051 // function initialization. 00052 return SmiFactoryImpl::getFactory(reinterpret_cast<SmiFactoryImpl *>(0)); 00053 } 00054 00055 std::auto_ptr<ISmi> SmiFactoryImpl::makeNew( u8 type ) 00056 { 00057 ISmi *ret = 0; 00058 SmiStrategy *strategyPtr = 0; 00059 00060 if (mode == AutoDetectMode ) 00061 strategyPtr = new SmiArchStrategy(); 00062 00063 else if (mode == UnitTestMode) 00064 strategyPtr = new SmiMockStrategy(getParameterString("smiFile")); 00065 00066 00067 // used for automatic setup of magic io stuff 00068 u16 cmdIOAddress = 0; 00069 u8 cmdIOCode = 0; 00070 smbios::TokenTableFactory *ttFactory = 0; 00071 smbios::ITokenTable *tokenTable = 0; 00072 00073 switch( type ) 00074 { 00075 case DELL_CALLING_INTERFACE_SMI_RAW: 00076 ret = new DellCallingInterfaceSmiImpl(strategyPtr); 00077 break; 00078 00079 case DELL_CALLING_INTERFACE_SMI: 00080 ret = new DellCallingInterfaceSmiImpl(strategyPtr); 00081 // automatically set up cmd io port/magic 00082 // step 1: get token table 00083 ttFactory = smbios::TokenTableFactory::getFactory() ; 00084 tokenTable = ttFactory->getSingleton(); 00085 // step 2: iterate through token table 00086 for( 00087 smbios::ITokenTable::iterator token = tokenTable->begin(); 00088 token != tokenTable->end(); 00089 ++token ) 00090 { 00091 // Step 3: go until we get to the first one that will dynamic cast 00092 // into a TokenDA 00093 try{ 00094 if( token->getTokenClass() != "TokenDA" ) 00095 continue; 00096 00097 // Step 4: then set cmd io stuff 00098 dynamic_cast<smbios::ISmiToken *>(&*token)->getSmiDetails(&cmdIOAddress, &cmdIOCode, static_cast<u8*>(0)); 00099 ret->setCommandIOMagic( cmdIOAddress, cmdIOCode ); 00100 break; 00101 } catch(...){ 00102 } 00103 } 00104 00105 if( ! (cmdIOAddress && cmdIOCode)) 00106 throw SmiExceptionImpl(_("Could not automatically setup up magic io")); 00107 00108 break; 00109 default: 00110 throw InvalidSmiModeImpl(_("Unknown smi factory mode requested")); 00111 break; 00112 } 00113 00114 if( ! ret ) 00115 throw InvalidSmiModeImpl(_("Could not allocate SMI object")); 00116 00117 std::auto_ptr<ISmi> foo(ret); 00118 return foo; 00119 } 00120 00121 }