Annotation of ntddk/src/mmedia/sndblst/driver/init.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1991  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     init.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This module contains code for the initialization phase of the
        !            12:     Sound Blaster device driver.
        !            13: 
        !            14: Author:
        !            15: 
        !            16:     Robin Speed (RobinSp) 17-Oct-1992
        !            17: 
        !            18: Environment:
        !            19: 
        !            20:     Kernel mode
        !            21: 
        !            22: Revision History:
        !            23: 
        !            24: --*/
        !            25: 
        !            26: #include "sound.h"
        !            27: #include "stdlib.h"
        !            28: 
        !            29: //
        !            30: // Local definitions
        !            31: //
        !            32: NTSTATUS
        !            33: DriverEntry(
        !            34:     IN   PDRIVER_OBJECT pDriverObject,
        !            35:     IN   PUNICODE_STRING RegistryPathName
        !            36: );
        !            37: VOID
        !            38: SoundCleanup(
        !            39:     IN   PGLOBAL_DEVICE_INFO pGDI
        !            40: );
        !            41: VOID SoundUnload(
        !            42:     IN   PDRIVER_OBJECT pDriverObject
        !            43: );
        !            44: BOOLEAN
        !            45: SoundExcludeRoutine(
        !            46:     IN OUT PLOCAL_DEVICE_INFO pLDI,
        !            47:     IN     SOUND_EXCLUDE_CODE Code
        !            48: );
        !            49: 
        !            50: //
        !            51: // Remove initialization stuff from resident memory
        !            52: //
        !            53: 
        !            54: #ifdef ALLOC_PRAGMA
        !            55: #pragma alloc_text(init,DriverEntry)
        !            56: #endif
        !            57: 
        !            58: //
        !            59: // Device initialization data
        !            60: //
        !            61: 
        !            62: SOUND_DEVICE_INIT DeviceInit[NumberOfDevices] =
        !            63: {
        !            64:     {
        !            65:         REG_VALUENAME_LEFTADC, REG_VALUENAME_RIGHTADC,
        !            66:         0,
        !            67:         FILE_DEVICE_WAVE_IN,
        !            68:         WAVE_IN,
        !            69:         "LDWi",
        !            70:         DD_WAVE_IN_DEVICE_NAME_U,
        !            71:         SoundWaveDeferred,
        !            72:         SoundExcludeRoutine,
        !            73:         SoundWaveDispatch,
        !            74:         SoundWaveInGetCaps,
        !            75:         SoundNoVolume,
        !            76:         DO_DIRECT_IO
        !            77:     },
        !            78:     {
        !            79:         REG_VALUENAME_LEFTDAC, REG_VALUENAME_RIGHTDAC,
        !            80:         0x90000000,
        !            81:         FILE_DEVICE_WAVE_OUT,
        !            82:         WAVE_OUT,
        !            83:         "LDWo",
        !            84:         DD_WAVE_OUT_DEVICE_NAME_U,
        !            85:         SoundWaveDeferred,
        !            86:         SoundExcludeRoutine,
        !            87:         SoundWaveDispatch,
        !            88:         SoundWaveOutGetCaps,
        !            89:         HwSetVolume,
        !            90:         DO_DIRECT_IO
        !            91:     },
        !            92:     {
        !            93:         NULL, NULL,
        !            94:         0,
        !            95:         FILE_DEVICE_MIDI_OUT,
        !            96:         MIDI_OUT,
        !            97:         "LDMo",
        !            98:         DD_MIDI_OUT_DEVICE_NAME_U,
        !            99:         NULL,
        !           100:         SoundExcludeRoutine,
        !           101:         SoundMidiDispatch,
        !           102:         SoundMidiOutGetCaps,
        !           103:         SoundNoVolume,
        !           104:         DO_DIRECT_IO
        !           105:     },
        !           106:     {
        !           107:         NULL, NULL,
        !           108:         0,
        !           109:         FILE_DEVICE_MIDI_IN,
        !           110:         MIDI_IN,
        !           111:         "LDMi",
        !           112:         DD_MIDI_IN_DEVICE_NAME_U,
        !           113:         SoundMidiInDeferred,
        !           114:         SoundExcludeRoutine,
        !           115:         SoundMidiDispatch,
        !           116:         SoundMidiInGetCaps,
        !           117:         SoundNoVolume,
        !           118:         DO_DIRECT_IO
        !           119:     },
        !           120:     {
        !           121:         REG_VALUENAME_LEFTLINEIN, REG_VALUENAME_RIGHTLINEIN,
        !           122:         0,
        !           123:         FILE_DEVICE_SOUND,
        !           124:         AUX_DEVICE,
        !           125:         "LDLi",
        !           126:         DD_AUX_DEVICE_NAME_U,
        !           127:         NULL,
        !           128:         SoundExcludeRoutine,
        !           129:         SoundAuxDispatch,
        !           130:         SoundAuxGetCaps,
        !           131:         HwSetVolume,
        !           132:         DO_BUFFERED_IO
        !           133:     }
        !           134: #ifdef MICMIX
        !           135:     ,
        !           136:     {
        !           137:         REG_VALUENAME_LEFTMICMIX, REG_VALUENAME_RIGHTMICMIX,
        !           138:         0,
        !           139:         FILE_DEVICE_SOUND,
        !           140:         AUX_DEVICE,
        !           141:         "LDMc",
        !           142:         DD_AUX_DEVICE_NAME_U,
        !           143:         NULL,
        !           144:         SoundExcludeRoutine,
        !           145:         SoundAuxDispatch,
        !           146:         SoundAuxGetCaps,
        !           147:         HwSetVolume,
        !           148:         DO_BUFFERED_IO
        !           149:     }
        !           150: #endif // MICMIX
        !           151: #ifdef MASTERVOLUME
        !           152:     ,
        !           153:     {
        !           154:         REG_VALUENAME_LEFTMASTER, REG_VALUENAME_RIGHTMASTER,
        !           155:         DEF_AUX_VOLUME,
        !           156:         FILE_DEVICE_SOUND,
        !           157:         AUX_DEVICE,
        !           158:         "LDMa",
        !           159:         DD_AUX_DEVICE_NAME_U,
        !           160:         NULL,                   // No Dpc routine
        !           161:         SoundExcludeRoutine,
        !           162:         SoundAuxDispatch,
        !           163:         SoundAuxGetCaps,
        !           164:         SoundNoVolume,          // Simulated volume setting
        !           165:         DO_BUFFERED_IO
        !           166:     }
        !           167: #endif // MASTERVOLUME
        !           168: };
        !           169: 
        !           170: 
        !           171: NTSTATUS
        !           172: SoundShutdown(
        !           173:     IN    PDEVICE_OBJECT pDO,
        !           174:     IN    PIRP pIrp
        !           175: )
        !           176: /*++
        !           177: 
        !           178: Routine Description:
        !           179: 
        !           180:     Save away volume settings when the system is shut down
        !           181: 
        !           182: Arguments:
        !           183: 
        !           184:     pDO - the device object we registered for shutdown with
        !           185:     pIrp - No used
        !           186: 
        !           187: Return Value:
        !           188: 
        !           189:     The function value is the final status from the initialization operation.
        !           190:     Here STATUS_SUCCESS
        !           191: 
        !           192: --*/
        !           193: {
        !           194:     //
        !           195:     // Save volume for all devices
        !           196:     //
        !           197: 
        !           198:     PLOCAL_DEVICE_INFO pLDI;
        !           199:     PGLOBAL_DEVICE_INFO pGDI;
        !           200: 
        !           201:     pLDI = pDO->DeviceExtension;
        !           202: 
        !           203:     SoundSaveVolume(pLDI->pGlobalInfo);
        !           204: 
        !           205:     return STATUS_SUCCESS;
        !           206: }
        !           207: 
        !           208: BOOLEAN
        !           209: SoundExcludeRoutine(
        !           210:     IN OUT PLOCAL_DEVICE_INFO pLDI,
        !           211:     IN     SOUND_EXCLUDE_CODE Code
        !           212: )
        !           213: 
        !           214: /*++
        !           215: 
        !           216: Routine Description:
        !           217: 
        !           218:     Perform mutual exclusion for our devices
        !           219: 
        !           220: Arguments:
        !           221: 
        !           222:     pLDI - device info for the device being open, closed, entered or left
        !           223:     Code - Function to perform (see devices.h)
        !           224: 
        !           225: Return Value:
        !           226: 
        !           227:     The function value is the final status from the initialization operation.
        !           228: 
        !           229: --*/
        !           230: {
        !           231:     PGLOBAL_DEVICE_INFO pGDI;
        !           232:     BOOLEAN ReturnCode;
        !           233: 
        !           234:     pGDI = pLDI->pGlobalInfo;
        !           235: 
        !           236:     ReturnCode = FALSE;
        !           237: 
        !           238:     switch (Code) {
        !           239:         case SoundExcludeOpen:
        !           240: 
        !           241:             //
        !           242:             // Special case - for sound blaster 1 midi out and
        !           243:             // midi in cannot run simultaneously
        !           244:             //
        !           245: 
        !           246:             if (SB1(&pGDI->Hw) &&
        !           247:                 (pLDI->DeviceIndex == MidiOutDevice &&
        !           248:                     pGDI->Usage == WaveInDevice ||
        !           249:                  pLDI->DeviceIndex == MidiInDevice &&
        !           250:                     pGDI->MidiInUse)) {
        !           251:             } else {
        !           252: 
        !           253:                 switch (pLDI->DeviceIndex) {
        !           254:                     case WaveInDevice:
        !           255:                     case WaveOutDevice:
        !           256:                     case MidiInDevice:
        !           257: 
        !           258:                         if (pGDI->Usage == 0xFF) {
        !           259:                            pGDI->Usage = pLDI->DeviceIndex;
        !           260:                            ReturnCode = TRUE;
        !           261:                         }
        !           262:                         break;
        !           263: 
        !           264:                     case MidiOutDevice:
        !           265:                         if (!pGDI->MidiInUse) {
        !           266:                            pGDI->MidiInUse = TRUE;
        !           267:                            ReturnCode = TRUE;
        !           268:                         }
        !           269:                         break;
        !           270: 
        !           271:                     default:
        !           272:                         //
        !           273:                         // aux devices should not receive this call
        !           274:                         //
        !           275: 
        !           276:                         ASSERT(FALSE);
        !           277:                         break;
        !           278:                 }
        !           279:             }
        !           280:             break;
        !           281: 
        !           282:         case SoundExcludeClose:
        !           283: 
        !           284:             ReturnCode = TRUE;
        !           285:             switch (pLDI->DeviceIndex) {
        !           286:                 case WaveInDevice:
        !           287:                 case WaveOutDevice:
        !           288:                 case MidiInDevice:
        !           289: 
        !           290:                     ASSERT(pGDI->Usage != 0xFF);
        !           291:                     pGDI->Usage = 0xFF;
        !           292:                     break;
        !           293: 
        !           294:                 case MidiOutDevice:
        !           295:                     ASSERT(pGDI->MidiInUse);
        !           296:                     pGDI->MidiInUse = FALSE;
        !           297:                     break;
        !           298: 
        !           299:                 default:
        !           300:                     //
        !           301:                     // aux devices should not receive this call
        !           302:                     //
        !           303: 
        !           304:                     ASSERT(FALSE);
        !           305:                     break;
        !           306:             }
        !           307:             break;
        !           308: 
        !           309:         case SoundExcludeEnter:
        !           310: 
        !           311:             ReturnCode = TRUE;
        !           312: 
        !           313:             switch (pLDI->DeviceIndex) {
        !           314:                 case MidiOutDevice:
        !           315: 
        !           316:                     KeWaitForSingleObject(&pGDI->MidiMutex,
        !           317:                                           Executive,
        !           318:                                           KernelMode,
        !           319:                                           FALSE,         // Not alertable
        !           320:                                           NULL);
        !           321: 
        !           322:                     break;
        !           323: 
        !           324:                 default:
        !           325: 
        !           326:                     KeWaitForSingleObject(&pGDI->DeviceMutex,
        !           327:                                           Executive,
        !           328:                                           KernelMode,
        !           329:                                           FALSE,         // Not alertable
        !           330:                                           NULL);
        !           331: 
        !           332:                     break;
        !           333:             }
        !           334:             break;
        !           335: 
        !           336:         case SoundExcludeLeave:
        !           337: 
        !           338:             ReturnCode = TRUE;
        !           339: 
        !           340:             switch (pLDI->DeviceIndex) {
        !           341:                 case MidiOutDevice:
        !           342:                     KeReleaseMutex(&pGDI->MidiMutex, FALSE);
        !           343:                     break;
        !           344: 
        !           345:                 default:
        !           346:                     KeReleaseMutex(&pGDI->DeviceMutex, FALSE);
        !           347:                     break;
        !           348:             }
        !           349:             break;
        !           350: 
        !           351:         case SoundExcludeQueryOpen:
        !           352: 
        !           353:             switch (pLDI->DeviceIndex) {
        !           354:                 case WaveInDevice:
        !           355:                 case WaveOutDevice:
        !           356:                 case MidiInDevice:
        !           357: 
        !           358:                     //
        !           359:                     // Guess!
        !           360:                     //
        !           361:                     ReturnCode = pGDI->Usage == pLDI->DeviceIndex;
        !           362: 
        !           363:                     break;
        !           364: 
        !           365:                 case MidiOutDevice:
        !           366: 
        !           367:                     ReturnCode = pGDI->MidiInUse;
        !           368:                     break;
        !           369: 
        !           370:                 default:
        !           371: 
        !           372:                     ASSERT(FALSE);
        !           373:                     break;
        !           374:             }
        !           375:             break;
        !           376:     }
        !           377: 
        !           378:     return ReturnCode;
        !           379: }
        !           380: 
        !           381: 
        !           382: NTSTATUS
        !           383: DriverEntry(
        !           384:     IN   PDRIVER_OBJECT pDriverObject,
        !           385:     IN   PUNICODE_STRING RegistryPathName
        !           386: )
        !           387: 
        !           388: /*++
        !           389: 
        !           390: Routine Description:
        !           391: 
        !           392:     This routine performs initialization for the sound system
        !           393:     device driver when it is first loaded
        !           394: 
        !           395:     The design is as follows :
        !           396: 
        !           397:     0. Cleanup is always by calling SoundCleanup.  This routine
        !           398:        is also called by the unload entry point.
        !           399: 
        !           400:     1. Find which bus our device is on (this is needed for
        !           401:        mapping things via the Hal).
        !           402: 
        !           403:     1. Allocate space to store our global info
        !           404: 
        !           405:     1. Open the driver's registry information and read it
        !           406: 
        !           407:     2. Fill in the driver object with our routines
        !           408: 
        !           409:     3. Create devices
        !           410: 
        !           411:        1. Wave input
        !           412:        2. Wave output
        !           413:        3. Midi output
        !           414:        4. Line in
        !           415:        5. Master volume control
        !           416: 
        !           417:        Customize each device type and initialize data
        !           418: 
        !           419:        Also store the registry string in our global info so we can
        !           420:        open it again to store volume settings etc on shutdown
        !           421: 
        !           422:     4. Check hardware conflicts by calling IoReportResourceUsage
        !           423:        for each device (as required)
        !           424: 
        !           425:     5. Find our IO port and check the device is really there
        !           426: 
        !           427:     6. Allocate DMA channel
        !           428: 
        !           429:     7. Connect interrupt
        !           430: 
        !           431:     8. Test interrupt and DMA channel and write config data
        !           432:        back to the registry
        !           433: 
        !           434:        During this phase the interrupt and channel may get changed
        !           435:        if conflicts arise
        !           436: 
        !           437:        In any even close our registry handle
        !           438: 
        !           439: Arguments:
        !           440: 
        !           441:     pDriverObject - Pointer to a driver object.
        !           442:     RegistryPathName - the path to our driver services node
        !           443: 
        !           444: Return Value:
        !           445: 
        !           446:     The function value is the final status from the initialization operation.
        !           447: 
        !           448: --*/
        !           449: 
        !           450: {
        !           451:    /********************************************************************
        !           452:     *
        !           453:     * Local variables
        !           454:     *
        !           455:     ********************************************************************/
        !           456: 
        !           457:     //
        !           458:     // Return code from last function called
        !           459:     //
        !           460: 
        !           461:     NTSTATUS Status;
        !           462: 
        !           463:     //
        !           464:     // Configuration data :
        !           465:     //
        !           466: 
        !           467:     SB_CONFIG_DATA ConfigData;
        !           468: 
        !           469:     //
        !           470:     // Where we keep all general driver information
        !           471:     // We avoid using static data because :
        !           472:     //     1. Accesses are slower with 32-bit offsets
        !           473:     //     2. If we supported more than one card with the same driver
        !           474:     //        we could not use static data
        !           475:     //
        !           476: 
        !           477:     PGLOBAL_DEVICE_INFO pGDI;
        !           478: 
        !           479:     //
        !           480:     // The number of devices we actually create
        !           481:     //
        !           482: 
        !           483:     int NumberOfDevicesCreated;
        !           484: 
        !           485:    /********************************************************************
        !           486:     *
        !           487:     * Initialize debugging
        !           488:     *
        !           489:     ********************************************************************/
        !           490: #if DBG
        !           491:     DriverName = "SNDBLST";
        !           492: #endif
        !           493: 
        !           494: 
        !           495: #if DBG
        !           496:     if (SoundDebugLevel >= 4) {
        !           497:         DbgBreakPoint();
        !           498:     }
        !           499: #endif
        !           500: 
        !           501:    /********************************************************************
        !           502:     *
        !           503:     * Allocate our global info
        !           504:     *
        !           505:     ********************************************************************/
        !           506: 
        !           507:     pGDI =
        !           508:         (PGLOBAL_DEVICE_INFO)ExAllocatePool(
        !           509:                                   NonPagedPool,
        !           510:                                   sizeof(GLOBAL_DEVICE_INFO));
        !           511: 
        !           512:     if (pGDI == NULL) {
        !           513:         return STATUS_INSUFFICIENT_RESOURCES;
        !           514:     }
        !           515: 
        !           516:     dprintf4(("  GlobalInfo    : %08lXH", pGDI));
        !           517:     RtlZeroMemory(pGDI, sizeof(GLOBAL_DEVICE_INFO));
        !           518:     pGDI->Key = GDI_KEY;
        !           519: 
        !           520:     pGDI->Usage = 0xFF;  // Free
        !           521:     pGDI->DriverObject = pDriverObject;
        !           522: 
        !           523:     //
        !           524:     // Initialize some of the device global info.  Note that ALL
        !           525:     // devices share the same exclusion.  More than one device can
        !           526:     // be open in the case of Midi Output and other devices.  In
        !           527:     // this case the midi output is synchronized with wave output
        !           528:     // either by the mutual exclusion or the wave spin lock which
        !           529:     // it grabs.
        !           530:     //
        !           531: 
        !           532:     KeInitializeMutex(&pGDI->DeviceMutex,
        !           533:                        2                     // High level
        !           534:                        );
        !           535: 
        !           536:     KeInitializeMutex(&pGDI->MidiMutex,
        !           537:                        1                     // Low level
        !           538:                        );
        !           539: 
        !           540:     //
        !           541:     // Initialize generic device environments - first get the
        !           542:     // hardware routines in place
        !           543:     //
        !           544: 
        !           545:     HwInitialize(pGDI);
        !           546: 
        !           547:     SoundInitMidiIn(&pGDI->MidiInfo,
        !           548:                     &pGDI->Hw);
        !           549: 
        !           550: 
        !           551:    /********************************************************************
        !           552:     *
        !           553:     *  See if we can find our bus.  We run on both ISA and EISA
        !           554:     *  We ASSUME that if there's an ISA bus we're on that
        !           555:     *
        !           556:     ********************************************************************/
        !           557: 
        !           558:     Status = SoundGetBusNumber(Isa, &pGDI->BusNumber);
        !           559: 
        !           560:     if (!NT_SUCCESS(Status)) {
        !           561:         //
        !           562:         // Cound not find an ISA bus so try EISA
        !           563:         //
        !           564:         Status = SoundGetBusNumber(Eisa, &pGDI->BusNumber);
        !           565: 
        !           566:         if (!NT_SUCCESS(Status)) {
        !           567:             dprintf1(("driver does not work on non-Isa/Eisa"));
        !           568:             SoundCleanup(pGDI);
        !           569:             return Status;
        !           570:         }
        !           571: 
        !           572:         pGDI->BusType = Eisa;
        !           573:     } else {
        !           574:         pGDI->BusType = Isa;
        !           575:     }
        !           576: 
        !           577: 
        !           578:    /********************************************************************
        !           579:     *
        !           580:     *  Save our registry path.  This is needed to save volume settings
        !           581:     *  into the registry on shutdown.  We append the parameters subkey
        !           582:     *  at this stage to make things easier (since we discard this code).
        !           583:     *
        !           584:     ********************************************************************/
        !           585: 
        !           586:     Status = SoundSaveRegistryPath(RegistryPathName, &pGDI->RegistryPathName);
        !           587:     if (!NT_SUCCESS(Status)) {
        !           588:         SoundCleanup(pGDI);
        !           589:         return STATUS_INSUFFICIENT_RESOURCES;
        !           590:     }
        !           591: 
        !           592: 
        !           593:     //
        !           594:     // Set configuration to default in case we don't get all the
        !           595:     // values back from the registry.
        !           596:     //
        !           597:     // Also set default volume for all devices
        !           598:     //
        !           599: 
        !           600:     ConfigData.Port = SOUND_DEF_PORT;
        !           601:     ConfigData.InterruptNumber = SOUND_DEF_INT;
        !           602:     ConfigData.DmaChannel = SOUND_DEF_DMACHANNEL;
        !           603:     ConfigData.InputSource = INPUT_MIC;     // Default to microphone
        !           604:     ConfigData.DmaBufferSize = DEFAULT_DMA_BUFFERSIZE;
        !           605: 
        !           606:     {
        !           607:         int i;
        !           608:         for (i = 0; i < NumberOfDevices ; i++) {
        !           609:             ConfigData.Volume[i].Left =
        !           610:                 DeviceInit[i].DefaultVolume;
        !           611:             ConfigData.Volume[i].Right =
        !           612:                 DeviceInit[i].DefaultVolume;
        !           613:         }
        !           614:     }
        !           615: 
        !           616:     //
        !           617:     // Get the system configuration information for this driver.
        !           618:     //
        !           619:     //
        !           620:     //     Port, Interrupt, DMA channel, DMA buffer size
        !           621:     //     Volume settings
        !           622:     //
        !           623: 
        !           624:     {
        !           625:         RTL_QUERY_REGISTRY_TABLE Table[2];
        !           626: 
        !           627:         RtlZeroMemory(Table, sizeof(Table));
        !           628: 
        !           629:         Table[0].QueryRoutine = SoundReadConfiguration;
        !           630: 
        !           631:         Status = RtlQueryRegistryValues(
        !           632:                      RTL_REGISTRY_ABSOLUTE,
        !           633:                      pGDI->RegistryPathName,
        !           634:                      Table,
        !           635:                      &ConfigData,
        !           636:                      NULL);
        !           637: 
        !           638:         if (!NT_SUCCESS(Status)) {
        !           639:             SoundCleanup(pGDI);
        !           640:             return Status;
        !           641:         }
        !           642:     }
        !           643: 
        !           644: 
        !           645:     //
        !           646:     // print out some info about the configuration
        !           647:     //
        !           648: 
        !           649:     dprintf2(("port %3X", ConfigData.Port));
        !           650:     dprintf2(("int %u", ConfigData.InterruptNumber));
        !           651:     dprintf2(("DMA channel %u", ConfigData.DmaChannel));
        !           652: 
        !           653:     //
        !           654:     // Create a couple of devices to ease reporting problems and
        !           655:     // bypass kernel IO ss bugs
        !           656:     //
        !           657:     {
        !           658:         int i;
        !           659: 
        !           660:         for (i = 0; i < 2 ; i++) {
        !           661:             Status = SoundCreateDevice(
        !           662:                          &DeviceInit[i],
        !           663:                          (BOOLEAN)FALSE,  // No range for midi out
        !           664:                          pDriverObject,
        !           665:                          pGDI,
        !           666:                          (PVOID)&pGDI->WaveInfo,
        !           667:                          &pGDI->Hw,
        !           668:                          i,
        !           669:                          &pGDI->DeviceObject[i]);
        !           670: 
        !           671:             if (!NT_SUCCESS(Status)) {
        !           672:                 dprintf1(("Failed to create device %ls - status %8X",
        !           673:                          DeviceInit[i].PrototypeName, Status));
        !           674:                 SoundCleanup(pGDI);
        !           675:                 return Status;
        !           676:             }
        !           677:         }
        !           678:     }
        !           679: 
        !           680: 
        !           681:     //
        !           682:     // Report all resources used.
        !           683:     //
        !           684: 
        !           685:     Status =  SoundReportResourceUsage(
        !           686:                                     (PDEVICE_OBJECT)pGDI->DriverObject,
        !           687:                                     pGDI->BusType,
        !           688:                                     pGDI->BusNumber,
        !           689:                                     &ConfigData.InterruptNumber,
        !           690:                                     INTERRUPT_MODE,
        !           691:                                     IRQ_SHARABLE,
        !           692:                                     &ConfigData.DmaChannel,
        !           693:                                     &ConfigData.Port,
        !           694:                                     NUMBER_OF_SOUND_PORTS);
        !           695: 
        !           696:     if (!NT_SUCCESS(Status)) {
        !           697:         SoundCleanup(pGDI);
        !           698:         return Status;
        !           699:     }
        !           700: 
        !           701:     //
        !           702:     // Check the configuration and acquire the resources
        !           703:     // If this doesn't work try again after trying to init the
        !           704:     // Pro spectrum
        !           705:     //
        !           706: 
        !           707:     Status = SoundInitHardwareConfig(pGDI, &ConfigData);
        !           708: 
        !           709:     if (!NT_SUCCESS(Status)) {
        !           710:         SoundCleanup(pGDI);
        !           711:         return Status;
        !           712:     }
        !           713: 
        !           714:     SoundInitializeWaveInfo(&pGDI->WaveInfo,
        !           715:                             (UCHAR)(SB1(&pGDI->Hw) ?
        !           716:                                        SoundReprogramOnInterruptDMA :
        !           717:                                        SoundAutoInitDMA),
        !           718:                             SoundQueryFormat,
        !           719:                             &pGDI->Hw);
        !           720: 
        !           721: 
        !           722:     //
        !           723:     // Create our devices
        !           724:     //
        !           725:     {
        !           726:         int i;
        !           727:         PLOCAL_DEVICE_INFO pLDI;
        !           728: 
        !           729:         if (pGDI->ProAudioSpectrum || SBPRO(&pGDI->Hw)) {
        !           730:             NumberOfDevicesCreated = NumberOfDevices;
        !           731:         } else {
        !           732:             //
        !           733:             // Early cards do not support wave volume setting
        !           734:             //
        !           735:             ((PLOCAL_DEVICE_INFO)pGDI->DeviceObject[WaveInDevice]->DeviceExtension)
        !           736:             ->CreationFlags |= SOUND_CREATION_NO_VOLUME;
        !           737:             ((PLOCAL_DEVICE_INFO)pGDI->DeviceObject[WaveOutDevice]->DeviceExtension)
        !           738:             ->CreationFlags |= SOUND_CREATION_NO_VOLUME;
        !           739: 
        !           740:             NumberOfDevicesCreated = 4;
        !           741:         }
        !           742: 
        !           743:         for (i = 2; i < NumberOfDevicesCreated ; i++) {
        !           744: 
        !           745:             //
        !           746:             // No Midi for Pro spectrum or ThunderBoard
        !           747:             //
        !           748: 
        !           749:             if (!((i == MidiInDevice ||
        !           750:                    i == MidiOutDevice) &&
        !           751:                    pGDI->Hw.ThunderBoard)) {
        !           752: 
        !           753:                 //
        !           754:                 // Create device
        !           755:                 //
        !           756: 
        !           757:                 Status = SoundCreateDevice(
        !           758:                              &DeviceInit[i],
        !           759:                              (UCHAR)(i == MidiInDevice || i == MidiOutDevice ?
        !           760:                                      SOUND_CREATION_NO_VOLUME : 0),
        !           761:                              pDriverObject,
        !           762:                              pGDI,
        !           763:                              i == MidiInDevice || i == MidiOutDevice ?
        !           764:                                 (PVOID)&pGDI->MidiInfo :
        !           765:                                 NULL,
        !           766:                              &pGDI->Hw,
        !           767:                              i,
        !           768:                              &pGDI->DeviceObject[i]);
        !           769: 
        !           770:                 if (!NT_SUCCESS(Status)) {
        !           771:                     dprintf1(("Failed to create device %ls - status %8X",
        !           772:                              DeviceInit[i].PrototypeName, Status));
        !           773:                     SoundCleanup(pGDI);
        !           774:                     return Status;
        !           775:                 }
        !           776: 
        !           777: 
        !           778: #ifdef MASTERVOLUME
        !           779:                 pLDI =
        !           780:                     (PLOCAL_DEVICE_INFO)pGDI->DeviceObject[i]->DeviceExtension;
        !           781:                 if (i == MasterVolumeDevice) {
        !           782:                     pLDI->MasterVolume = TRUE;
        !           783:                 }
        !           784: #endif // MASTERVOLUME
        !           785:             }
        !           786:         }
        !           787: 
        !           788:         IoRegisterShutdownNotification(pGDI->DeviceObject[WaveInDevice]);
        !           789:     }
        !           790: 
        !           791:     //
        !           792:     // Initialize volume settings in hardware
        !           793:     //
        !           794: 
        !           795:     {
        !           796:         int i;
        !           797:         for (i = 0; i < NumberOfDevicesCreated; i++) {
        !           798:             PLOCAL_DEVICE_INFO pLDI;
        !           799: 
        !           800:             if (pGDI->DeviceObject[i]) {
        !           801:                 pLDI = pGDI->DeviceObject[i]->DeviceExtension;
        !           802: 
        !           803:                 pLDI->Volume = ConfigData.Volume[i];
        !           804: 
        !           805:                 (*pLDI->DeviceInit->HwSetVolume)(pLDI);
        !           806:             }
        !           807:         }
        !           808:     }
        !           809: 
        !           810:     //
        !           811:     // initialise mixer level for midi synth to max volume
        !           812:     // (the synth driver does not access the mixer, and controls the
        !           813:     // volume via changes to the synth instrument parameters)
        !           814:     //
        !           815:     HwInitVolume(pGDI);
        !           816: 
        !           817: 
        !           818:     //
        !           819:     // Initialize the driver object dispatch table.
        !           820:     //
        !           821: 
        !           822:     pDriverObject->DriverUnload                         = SoundUnload;
        !           823:     pDriverObject->MajorFunction[IRP_MJ_CREATE]         = SoundDispatch;
        !           824:     pDriverObject->MajorFunction[IRP_MJ_CLOSE]          = SoundDispatch;
        !           825:     pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = SoundDispatch;
        !           826:     pDriverObject->MajorFunction[IRP_MJ_READ]           = SoundDispatch;
        !           827:     pDriverObject->MajorFunction[IRP_MJ_WRITE]          = SoundDispatch;
        !           828:     pDriverObject->MajorFunction[IRP_MJ_CLEANUP]        = SoundDispatch;
        !           829:     pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN]       = SoundShutdown;
        !           830: 
        !           831:     //
        !           832:     // We'd like to get called on shutdown to save away our volume
        !           833:     // settings but only file systems get called.
        !           834:     //
        !           835:     // pDriverObject->MajorFunction[IRP_MJ_SHUTDOWN]       = SoundDispatch;
        !           836: 
        !           837: 
        !           838:     return STATUS_SUCCESS;
        !           839: 
        !           840: }
        !           841: 
        !           842: 
        !           843: 
        !           844: VOID
        !           845: SoundCleanup(
        !           846:     IN   PGLOBAL_DEVICE_INFO pGDI
        !           847: )
        !           848: 
        !           849: /*++
        !           850: 
        !           851: Routine Description:
        !           852: 
        !           853:     Clean up all resources allocated by our initialization
        !           854: 
        !           855: Arguments:
        !           856: 
        !           857:     pGDI - Pointer to global data
        !           858: 
        !           859: Return Value:
        !           860: 
        !           861:     NONE
        !           862: 
        !           863: --*/
        !           864: 
        !           865: {
        !           866:     //
        !           867:     // Free our interrupt
        !           868:     //
        !           869: 
        !           870:     if (pGDI->WaveInfo.Interrupt) {
        !           871:         IoDisconnectInterrupt(pGDI->WaveInfo.Interrupt);
        !           872:     }
        !           873: 
        !           874:     SoundFreeCommonBuffer(&pGDI->WaveInfo.DMABuf);
        !           875: 
        !           876:     if (pGDI->DeviceObject[WaveInDevice]) {
        !           877: 
        !           878:         //
        !           879:         // There are some devices to delete
        !           880:         //
        !           881: 
        !           882:         PDRIVER_OBJECT DriverObject;
        !           883: 
        !           884:         IoUnregisterShutdownNotification(pGDI->DeviceObject[WaveInDevice]);
        !           885: 
        !           886:         DriverObject = pGDI->DeviceObject[WaveInDevice]->DriverObject;
        !           887: 
        !           888:         while (DriverObject->DeviceObject != NULL) {
        !           889:             //
        !           890:             // Undeclare resources used by device and
        !           891:             // delete the device object and associated data
        !           892:             //
        !           893: 
        !           894:             SoundFreeDevice(DriverObject->DeviceObject);
        !           895:         }
        !           896:     }
        !           897: 
        !           898:     if (pGDI->MemType == 0) {
        !           899:       if (pGDI->Hw.PortBase != NULL) {
        !           900:           MmUnmapIoSpace(pGDI->Hw.PortBase, NUMBER_OF_SOUND_PORTS);
        !           901:       }
        !           902:       if (pGDI->PASInfo.PROBase != NULL) {
        !           903:           MmUnmapIoSpace(pGDI->PASInfo.PROBase, 0x10000);
        !           904:       }
        !           905:     }
        !           906: 
        !           907: 
        !           908:     //
        !           909:     // Free device name
        !           910:     //
        !           911: 
        !           912:     if (pGDI->RegistryPathName) {
        !           913:         ExFreePool(pGDI->RegistryPathName);
        !           914:     }
        !           915: 
        !           916:     ExFreePool(pGDI);
        !           917: }
        !           918: 
        !           919: 
        !           920: VOID
        !           921: SoundUnload(
        !           922:     IN OUT PDRIVER_OBJECT pDriverObject
        !           923: )
        !           924: {
        !           925:     PGLOBAL_DEVICE_INFO pGDI;
        !           926: 
        !           927:     dprintf3(("Unload request"));
        !           928: 
        !           929:     //
        !           930:     // Find our global data
        !           931:     //
        !           932: 
        !           933:     pGDI = ((PLOCAL_DEVICE_INFO)pDriverObject->DeviceObject->DeviceExtension)
        !           934:            ->pGlobalInfo;
        !           935: 
        !           936:     //
        !           937:     // Write out volume settings
        !           938:     //
        !           939: 
        !           940:     SoundSaveVolume(pGDI);
        !           941: 
        !           942:     //
        !           943:     // Assume all handles (and therefore interrupts etc) are closed down
        !           944:     //
        !           945: 
        !           946:     //
        !           947:     // Delete the things we allocated - devices, Interrupt objects,
        !           948:     // adapter objects.  The driver object has a chain of devices
        !           949:     // across it.
        !           950:     //
        !           951: 
        !           952:     SoundCleanup(pGDI);
        !           953: 
        !           954: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.