Annotation of ntddk/src/mmedia/sndblst/driver/init.c, revision 1.1.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.