ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

common.cpp
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2006-2007 dogbert <dogber1@gmail.com>
00003 All rights reserved.
00004 
00005 Redistribution and use in source and binary forms, with or without
00006 modification, are permitted provided that the following conditions
00007 are met:
00008 1. Redistributions of source code must retain the above copyright
00009    notice, this list of conditions and the following disclaimer.
00010 2. Redistributions in binary form must reproduce the above copyright
00011    notice, this list of conditions and the following disclaimer in the
00012    documentation and/or other materials provided with the distribution.
00013 3. The name of the author may not be used to endorse or promote products
00014    derived from this software without specific prior written permission.
00015 
00016 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
00017 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00018 OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
00019 IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
00020 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
00021 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00022 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00023 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00024 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
00025 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00026 */
00027 
00028 #include "common.hpp"
00029 
00030 #ifdef _MSC_VER
00031 #pragma code_seg("PAGE") /* warning - ignored by GCC compiler */
00032 #endif
00033 
00034 NTSTATUS
00035 NewCMIAdapter(
00036     PUNKNOWN *Unknown, 
00037     REFCLSID,
00038     PUNKNOWN UnknownOuter, 
00039     POOL_TYPE PoolType)
00040 {
00041 #if 1
00042     //PAGED_CODE();
00043     DBGPRINT(("NewCMIAdapter()"));
00044     ASSERT (Unknown);
00045 #endif
00046     STD_CREATE_BODY_(CCMIAdapter, Unknown, UnknownOuter, PoolType, PCMIADAPTER);
00047 }
00048 
00049 
00050 STDMETHODIMP_(NTSTATUS) CCMIAdapter::init(PRESOURCELIST ResourceList, PDEVICE_OBJECT aDeviceObject)
00051 {
00052 #if 0
00053     //PAGED_CODE();
00054     //ASSERT(ResourceList);
00055     //ASSERT(aDeviceObject);
00056     //ASSERT(ResourceList->FindTranslatedPort(0));
00057     DBGPRINT(("CCMIAdapter[%p]::init()", this));
00058 #endif
00059 
00060     NTSTATUS ntStatus = STATUS_SUCCESS;
00061 
00062     RtlFillMemory(&mixerCache, 0xFF, 0xFF);
00063     RtlFillMemory(&cm, sizeof(cm), 0x00);
00064 
00065     DeviceObject = aDeviceObject;
00066 
00067     cm.IOBase = 0;
00068     for ( UINT i=0; i < ResourceList->NumberOfPorts(); i++ ) {
00069         if (ResourceList->FindTranslatedPort(i)->u.Port.Length == 0x100) {
00070             cm.IOBase = (UInt32*)ResourceList->FindTranslatedPort(i)->u.Port.Start.QuadPart;
00071         }
00072     }
00073 
00074     if (cm.IOBase == 0) {
00075         return STATUS_INSUFFICIENT_RESOURCES;
00076     }
00077     cm.MPUBase = 0;
00078 
00079 #ifdef WAVERT
00080     INFOPRINT(("Driver Version: %s-WAVERT", CMIVERSION));
00081 #else
00082     INFOPRINT(("Driver Version: %s", CMIVERSION));
00083 #endif
00084     INFOPRINT(("Configuration:"));
00085     INFOPRINT(("    IO Base:      0x%X", cm.IOBase));
00086     INFOPRINT(("    MPU Base:     0x%X", cm.MPUBase));
00087 
00088     if (!queryChip()) {
00089         return STATUS_INSUFFICIENT_RESOURCES;
00090     }
00091 
00092     INFOPRINT(("    Chip Version: %d", cm.chipVersion));
00093     INFOPRINT(("    Max Channels: %d", cm.maxChannels));
00094     INFOPRINT(("    CanAC3HW:     %d", cm.canAC3HW));
00095 
00096     resetController();
00097 
00098     ntStatus = PcNewInterruptSync(&(InterruptSync), NULL, ResourceList, 0, InterruptSyncModeNormal);
00099     if (!NT_SUCCESS(ntStatus) || !(InterruptSync)) {
00100         DBGPRINT(("Failed to create an interrupt sync!"));
00101         return STATUS_INSUFFICIENT_RESOURCES;
00102     }
00103     ntStatus = InterruptSync->RegisterServiceRoutine(InterruptServiceRoutine, (PVOID)this, FALSE);
00104     if (!NT_SUCCESS(ntStatus)) {
00105         DBGPRINT(("Failed to register ISR!"));
00106         return ntStatus;
00107     }
00108 
00109     ntStatus = InterruptSync->Connect();
00110     if (!NT_SUCCESS(ntStatus)) {
00111         DBGPRINT(("Failed to connect the ISR with InterruptSync!"));
00112         return ntStatus;
00113     }
00114 
00115     // Initialize the device state.
00116     CurrentPowerState = PowerDeviceD0;
00117 
00118     return ntStatus;
00119 }
00120 
00121 
00122 CCMIAdapter::~CCMIAdapter()
00123 {
00124     //PAGED_CODE ();
00125     DBGPRINT(("CCMIAdapter[%p]::~CCMIAdapter()", this));
00126 
00127     if (InterruptSync) {
00128         InterruptSync->Disconnect();
00129         InterruptSync->Release();
00130         InterruptSync = NULL;
00131     }
00132 }
00133 
00134 STDMETHODIMP_(NTSTATUS) CCMIAdapter::QueryInterface(REFIID Interface, PVOID* Object)
00135 {
00136     //PAGED_CODE();
00137 
00138     DBGPRINT(("CCMIAdapter[%p]::NonDelegatingQueryInterface()", this));
00139 
00140     //ASSERT(Object);
00141 
00142     // Is it IID_IUnknown?
00143     if (IsEqualGUIDAligned (Interface, IID_IUnknown)) {
00144         *Object = (PVOID)(PUNKNOWN)(PCMIADAPTER)this;
00145     }
00146     else
00147     // or IID_IAdapterCommon ...
00148     if (IsEqualGUIDAligned (Interface, IID_ICMIAdapter)) {
00149         *Object = (PVOID)(PCMIADAPTER)this;
00150     } else
00151     // or IID_IAdapterPowerManagement ...
00152     if (IsEqualGUIDAligned (Interface, IID_IAdapterPowerManagement)) {
00153         *Object = (PVOID)(PADAPTERPOWERMANAGEMENT)this;
00154     } else {
00155     // nothing found, must be an unknown interface.
00156         *Object = NULL;
00157         return STATUS_INVALID_PARAMETER;
00158     }
00159 
00160     //
00161     // We reference the interface for the caller.
00162     //
00163     ((PUNKNOWN)*Object)->AddRef();
00164     return STATUS_SUCCESS;
00165 }
00166 
00167 bool CCMIAdapter::queryChip()
00168 {
00169     //PAGED_CODE();
00170     DBGPRINT(("CCMIAdapter[%p]::queryChip()", this));
00171 
00172     UInt32 version = readUInt32(REG_INTHLDCLR) & VERSION_MASK;
00173     if (version == 0xFFFFFFFF) {
00174         return false;
00175     }
00176     if (version) {
00177         if (version & VERSION_68) {
00178             cm.chipVersion = 68;
00179             cm.maxChannels = 8;
00180             cm.canAC3HW = true;
00181             cm.hasDualDAC = true;
00182             cm.canMultiChannel = true;
00183             return true;
00184         }
00185         if (version & VERSION_55) {
00186             cm.chipVersion = 55;
00187             cm.maxChannels = 6;
00188             cm.canAC3HW = true;
00189             cm.hasDualDAC = true;
00190             cm.canMultiChannel = true;
00191             return true;
00192         }
00193         if (version & VERSION_39) {
00194             cm.chipVersion = 39;
00195             if (version & VERSION_39_6) {
00196                 cm.maxChannels = 6;
00197             } else {
00198                 cm.maxChannels = 4;
00199             }
00200             cm.canAC3HW = true;
00201             cm.hasDualDAC = true;
00202             cm.canMultiChannel = true;
00203             return true;
00204         }
00205     } else {
00206         version = readUInt32(REG_CHFORMAT) & VERSION_37;
00207         if (!version) {
00208             cm.chipVersion = 33;
00209             cm.maxChannels = 2;
00210             if (cm.doAC3SW) {
00211                 cm.canAC3SW = true;
00212             } else {
00213                 cm.canAC3HW = true;
00214             }
00215             cm.hasDualDAC = true;
00216             return true;
00217         } else {
00218             cm.chipVersion = 37;
00219             cm.maxChannels = 2;
00220             cm.canAC3HW = true;
00221             cm.hasDualDAC = 1;
00222             return true;
00223         }
00224     }
00225     return false;
00226 }
00227 
00228 void CCMIAdapter::resetMixer()
00229 {
00230     //PAGED_CODE();
00231     DBGPRINT(("CCMIAdapter[%p]::resetMixer()", this));
00232 
00233     writeMixer(0, 0);
00234     setUInt8Bit(REG_MIXER1, EN_SPDI2DAC);
00235 }
00236 
00237 void CCMIAdapter::resetController()
00238 {
00239 #if 0
00240     //PAGED_CODE();
00241     DBGPRINT(("CCMIAdapter[%p]::resetController()", this));
00242 #endif
00243 
00244     writeUInt32(REG_INTHLDCLR, 0);
00245 
00246 #if OUT_CHANNEL == 1
00247     writeUInt32(REG_FUNCTRL0, ADC_CH0 | (RST_CH0 | RST_CH1));
00248     writeUInt32(REG_FUNCTRL0, ADC_CH0 & ~(RST_CH0 | RST_CH1));
00249 #else
00250     writeUInt32(REG_FUNCTRL0, ADC_CH1 | (RST_CH0 | RST_CH1));
00251     writeUInt32(REG_FUNCTRL0, ADC_CH1 & ~(RST_CH0 | RST_CH1));
00252 #endif
00253     KeStallExecutionProcessor(100L);
00254 
00255     writeUInt32(REG_FUNCTRL0, 0);
00256     writeUInt32(REG_FUNCTRL1, 0);
00257 
00258     writeUInt32(REG_CHFORMAT, 0);
00259     writeUInt32(REG_MISCCTRL, EN_DBLDAC);
00260 #if OUT_CHANNEL == 1
00261     setUInt32Bit(REG_MISCCTRL, XCHG_DAC);
00262 #endif
00263 
00264     setUInt32Bit(REG_FUNCTRL1, BREQ);
00265 
00266     writeMixer(0, 0);
00267 
00268     return;
00269 }
00270 
00271 
00272 STDMETHODIMP_(NTSTATUS) CCMIAdapter::activateMPU(ULONG* MPUBase)
00273 {
00274     UInt32 LegacyCtrl;
00275 #if 0
00276     //PAGED_CODE();
00277     DBGPRINT(("CCMIAdapter[%p]::activateMPU(%X)", this, MPUBase));
00278 #endif
00279 
00280     switch ((LONGLONG)MPUBase) {
00281         case 0x300: LegacyCtrl = UART_300; break;
00282         case 0x310: LegacyCtrl = UART_310; break;
00283         case 0x320: LegacyCtrl = UART_320; break;
00284         case 0x330: LegacyCtrl = UART_330; break; // UART_330 == 0
00285         default: LegacyCtrl = 0xFFFFFFFF;  break;
00286     }
00287     if (LegacyCtrl < 0xFFFFFFFF) {
00288         cm.MPUBase = MPUBase;
00289         setUInt32Bit(REG_FUNCTRL1, EN_UART);
00290         writeUInt32(REG_LEGACY, LegacyCtrl);
00291         return STATUS_SUCCESS;
00292     }
00293 
00294     return STATUS_UNSUCCESSFUL;
00295 }
00296 
00297 // "The code for this method must reside in paged memory.", IID_IAdapterPowerManagement.PowerChangeState() docs
00298 // XP's order of power states when going to hibernate: D3 -> D0, waking up: D0 -> D3.
00299 STDMETHODIMP_(void) CCMIAdapter::PowerChangeState(POWER_STATE NewState)
00300 {
00301 #if 0
00302     //PAGED_CODE();
00303     DBGPRINT(("CCMIAdapter[%p]::PowerChangeState(%p)", this, NewState));
00304 #endif
00305 
00306     if (NewState.DeviceState == CurrentPowerState ) {
00307         return;
00308     }
00309 
00310     switch (NewState.DeviceState) {
00311         case PowerDeviceD0: // powering up, hardware access allowed
00312             clearUInt32Bit(REG_MISCCTRL, PWD_CHIP);
00313             cm.WaveMiniport->powerUp();
00314             CurrentPowerState = NewState.DeviceState;
00315             break;
00316 
00317         case PowerDeviceD1: // powering down, hardware access still allowed
00318             setUInt32Bit(REG_MISCCTRL, PWD_CHIP);
00319             CurrentPowerState = NewState.DeviceState;
00320             break;
00321 
00322         case PowerDeviceD2: // sleep state - hardware access not allowed
00323         case PowerDeviceD3: // hibernation state - hardware access not allowed
00324             if (CurrentPowerState == PowerDeviceD0) {
00325                 cm.WaveMiniport->powerDown();
00326                 setUInt32Bit(REG_MISCCTRL, PWD_CHIP);
00327             }
00328             CurrentPowerState = NewState.DeviceState;
00329             break;
00330         default:            // unknown power state
00331             break;
00332     }
00333 }
00334 
00335 STDMETHODIMP_(NTSTATUS) CCMIAdapter::QueryPowerChangeState(POWER_STATE NewStateQuery)
00336 {
00337 #if 0
00338     //PAGED_CODE();
00339     DBGPRINT(("CCMIAdapter[%p]::QueryPowerChangeState(%p)", this, NewStateQuery));
00340 #endif
00341     return STATUS_SUCCESS;
00342 }
00343 
00344 STDMETHODIMP_(NTSTATUS) CCMIAdapter::QueryDeviceCapabilities(PDEVICE_CAPABILITIES PowerDeviceCaps)
00345 {
00346 #if 0
00347     //PAGED_CODE();
00348     DBGPRINT(("CCMIAdapter[%p]::QueryDeviceCapabilities(%p)", this, PowerDeviceCaps));
00349 #endif
00350     return STATUS_SUCCESS;
00351 }
00352 
00353 STDMETHODIMP_(NTSTATUS) CCMIAdapter::loadSBMixerFromMemory()
00354 {
00355     UInt8 sbIndex[] = { 0x04, 0x0A, 0x22, 0x28, 0x2E, 0x30, 0x31, 0x32, 0x33, 0x36, 0x37, 0x38,
00356                         0x39, 0x3A, 0x3C, 0x3D, 0x3E, 0xF0 };
00357 
00358 #if 0
00359     //PAGED_CODE();
00360     DBGPRINT(("CCMIAdapter[%p]::loadSBMixerFromMemory()", this));
00361 #endif
00362     for ( UINT i = 0; i < (sizeof(sbIndex)/sizeof(sbIndex[0])); i++ ) {
00363         writeUInt8(REG_SBINDEX, sbIndex[i]);
00364         writeUInt8(REG_SBDATA, mixerCache[i]);
00365     }
00366 
00367     return STATUS_SUCCESS;
00368 }
00369 
00370 /*
00371 ** non-paged code below
00372 */
00373 #ifdef _MSC_VER
00374 #pragma code_seg() /* warning - ignored by GCC compiler */
00375 #endif
00376 
00377 STDMETHODIMP_(UInt8) CCMIAdapter::readUInt8(UInt8 reg)
00378 {
00379     return READ_PORT_UCHAR((PUCHAR)(reinterpret_cast<PUCHAR>(cm.IOBase) + reg));
00380 }
00381 
00382 STDMETHODIMP_(void) CCMIAdapter::writeUInt8(UInt8 cmd, UInt8 value)
00383 {
00384     WRITE_PORT_UCHAR((PUCHAR)(reinterpret_cast<PUCHAR>(cm.IOBase) + cmd), value);
00385 }
00386 
00387 STDMETHODIMP_(void) CCMIAdapter::setUInt8Bit(UInt8 reg, UInt8 flag)
00388 {
00389     writeUInt8(reg, readUInt8(reg) | flag);
00390 }
00391 
00392 STDMETHODIMP_(void) CCMIAdapter::clearUInt8Bit(UInt8 reg, UInt8 flag)
00393 {
00394     writeUInt8(reg, readUInt8(reg) & ~flag);
00395 }
00396 
00397 STDMETHODIMP_(UInt16) CCMIAdapter::readUInt16(UInt8 reg)
00398 {
00399     return READ_PORT_USHORT((PUSHORT)(reinterpret_cast<PUCHAR>(cm.IOBase) + reg));
00400 }
00401 
00402 STDMETHODIMP_(void) CCMIAdapter::writeUInt16(UInt8 cmd, UInt16 value)
00403 {
00404     WRITE_PORT_USHORT((PUSHORT)(reinterpret_cast<PUCHAR>(cm.IOBase) + cmd), value);
00405 }
00406 
00407 
00408 STDMETHODIMP_(UInt32) CCMIAdapter::readUInt32(UInt8 reg)
00409 {
00410     return READ_PORT_ULONG((PULONG)(reinterpret_cast<PUCHAR>(cm.IOBase) + reg));
00411 }
00412 
00413 STDMETHODIMP_(void) CCMIAdapter::writeUInt32(UInt8 cmd, UInt32 value)
00414 {
00415     WRITE_PORT_ULONG((PULONG)(reinterpret_cast<PUCHAR>(cm.IOBase) + cmd), value);
00416 }
00417 
00418 STDMETHODIMP_(void) CCMIAdapter::setUInt32Bit(UInt8 reg, UInt32 flag)
00419 {
00420     writeUInt32(reg, readUInt32(reg) | flag);
00421 }
00422 
00423 STDMETHODIMP_(void) CCMIAdapter::clearUInt32Bit(UInt8 reg, UInt32 flag)
00424 {
00425     writeUInt32(reg, readUInt32(reg) & ~flag);
00426 }
00427 
00428 STDMETHODIMP_(UInt8) CCMIAdapter::readMixer(UInt8 index)
00429 {
00430     if (mixerCache[index] == 0xFF) {
00431         writeUInt8(REG_SBINDEX, index);
00432         mixerCache[index] = readUInt8(REG_SBDATA);
00433     }
00434     return mixerCache[index];
00435 }
00436 
00437 STDMETHODIMP_(void) CCMIAdapter::writeMixer(UInt8 index, UInt8 value)
00438 {
00439     if (value != mixerCache[index]) {
00440         mixerCache[index] = value;
00441         writeUInt8(REG_SBINDEX, index);
00442         writeUInt8(REG_SBDATA, value);
00443     }
00444 }
00445 
00446 STDMETHODIMP_(void) CCMIAdapter::setMixerBit(UInt8 index, UInt8 flag)
00447 {
00448     writeMixer(index, readMixer(index) | flag);
00449 }
00450 
00451 STDMETHODIMP_(void) CCMIAdapter::clearMixerBit(UInt8 index, UInt8 flag)
00452 {
00453     writeMixer(index, readMixer(index) & ~flag);
00454 }
00455 
00456 NTSTATUS NTAPI CCMIAdapter::InterruptServiceRoutine(PINTERRUPTSYNC InterruptSync, PVOID DynamicContext)
00457 {
00458     UInt32 status, mask = 0;
00459 
00460     CCMIAdapter *CMIAdapter = (CCMIAdapter *)DynamicContext;
00461 
00462 #if 0
00463     //ASSERT(InterruptSync);
00464     //ASSERT(DynamicContext);
00465 #endif
00466 
00467     if (!(CMIAdapter->cm.WaveMiniport)) {
00468             return STATUS_UNSUCCESSFUL;
00469     }
00470 
00471     status = CMIAdapter->readUInt32(REG_INT_STAT);
00472 
00473     if ((!(status & INT_PENDING)) || (status == 0xFFFFFFFF)) {
00474         return STATUS_UNSUCCESSFUL;
00475     }
00476 
00477     if (status & INT_CH0) {
00478         mask |= EN_CH0_INT;
00479 #if OUT_CHANNEL == 0
00480         CMIAdapter->cm.WaveMiniport->ServiceWaveISR(PCM_OUT_STREAM);
00481 #endif
00482 #if IN_CHANNEL == 0
00483         CMIAdapter->cm.WaveMiniport->ServiceWaveISR(PCM_IN_STREAM);
00484 #endif
00485     }
00486     if (status & INT_CH1) {
00487         mask |= EN_CH1_INT;
00488 #if OUT_CHANNEL == 1
00489         CMIAdapter->cm.WaveMiniport->ServiceWaveISR(PCM_OUT_STREAM);
00490 #endif
00491 #if IN_CHANNEL == 1
00492         CMIAdapter->cm.WaveMiniport->ServiceWaveISR(PCM_IN_STREAM);
00493 #endif
00494     }
00495 #ifdef UART
00496     if (status & INT_UART) {
00497         // the UART miniport should catch / have caught the interrupt
00498         return STATUS_UNSUCCESSFUL;
00499     }
00500 #endif
00501 
00502     CMIAdapter->clearUInt32Bit(REG_INTHLDCLR, mask);
00503     CMIAdapter->setUInt32Bit(REG_INTHLDCLR, mask);
00504 
00505     return STATUS_SUCCESS;
00506 }

Generated on Sun May 27 2012 04:28:38 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.