Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygensndblst.c
Go to the documentation of this file.
00001 /* 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS kernel 00005 * FILE: services/dd/sndblst/sndblst.c 00006 * PURPOSE: Sound Blaster / SB Pro / SB 16 driver 00007 * PROGRAMMER: Andrew Greenwood 00008 * UPDATE HISTORY: 00009 * Sept 28, 2003: Copied from mpu401.c as a template 00010 */ 00011 00012 /* INCLUDES ****************************************************************/ 00013 00014 #include <ntddk.h> 00015 #include "sndblst.h" 00016 00017 NTSTATUS NTAPI 00018 DriverEntry(PDRIVER_OBJECT DriverObject, 00019 PUNICODE_STRING RegistryPath); 00020 00021 /* INTERNAL VARIABLES ******************************************************/ 00022 00023 ULONG DeviceCount = 0; 00024 00025 00026 /* FUNCTIONS ***************************************************************/ 00027 00028 static NTSTATUS InitDevice( 00029 IN PWSTR RegistryPath, 00030 IN PVOID Context) 00031 { 00032 // PDEVICE_INSTANCE Instance = Context; 00033 PDEVICE_OBJECT DeviceObject; // = Context; 00034 PDEVICE_EXTENSION Parameters; // = DeviceObject->DeviceExtension; 00035 UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\WaveOut0"); // CHANGE THESE? 00036 UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\WaveOut0"); 00037 00038 // CONFIG Config; 00039 RTL_QUERY_REGISTRY_TABLE Table[2]; 00040 NTSTATUS s; 00041 USHORT DSP_Version = 0; 00042 UCHAR DSP_Major = 0, DSP_Minor = 0; 00043 00044 // This is TEMPORARY, to ensure that we don't process more than 1 device. 00045 // This limitation should be removed in future. 00046 if (DeviceCount > 0) 00047 { 00048 DPRINT("Sorry - only 1 device supported by Sound Blaster driver at present :(\n"); 00049 return STATUS_NOT_IMPLEMENTED; 00050 } 00051 00052 DPRINT("Creating IO device\n"); 00053 00054 s = IoCreateDevice(Context, // driverobject 00055 sizeof(DEVICE_EXTENSION), 00056 &DeviceName, 00057 FILE_DEVICE_SOUND, // Correct? 00058 0, 00059 FALSE, 00060 &DeviceObject); 00061 00062 if (!NT_SUCCESS(s)) 00063 return s; 00064 00065 DPRINT("Device Extension at 0x%x\n", DeviceObject->DeviceExtension); 00066 Parameters = DeviceObject->DeviceExtension; 00067 00068 DPRINT("Creating DOS link\n"); 00069 00070 /* Create the dos device link */ 00071 s = IoCreateSymbolicLink(&SymlinkName, 00072 &DeviceName); 00073 00074 if (!NT_SUCCESS(s)) 00075 { 00076 IoDeleteDevice(DeviceObject); 00077 return s; 00078 } 00079 00080 DPRINT("Initializing device\n"); 00081 00082 // DPRINT("Allocating memory for parameters structure\n"); 00083 // Bodged: 00084 // Parameters = (PDEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(DEVICE_EXTENSION)); 00085 // DeviceObject->DeviceExtension = Parameters; 00086 // Parameters = Instance->DriverObject->DriverExtension; 00087 00088 DPRINT("DeviceObject at 0x%x, DeviceExtension at 0x%x\n", DeviceObject, Parameters); 00089 00090 if (! Parameters) 00091 { 00092 DPRINT("NULL POINTER!\n"); 00093 return STATUS_INSUFFICIENT_RESOURCES; 00094 } 00095 00096 // Instance->DriverObject->DriverExtension = Parameters; 00097 00098 DPRINT("Setting reg path\n"); 00099 Parameters->RegistryPath = RegistryPath; 00100 // Parameters->DriverObject = Instance->DriverObject; 00101 00102 DPRINT("Zeroing table memory and setting query routine\n"); 00103 RtlZeroMemory(Table, sizeof(Table)); 00104 Table[0].QueryRoutine = LoadSettings; 00105 00106 DPRINT("Setting port and IRQ defaults\n"); 00107 Parameters->Port = DEFAULT_PORT; 00108 Parameters->IRQ = DEFAULT_IRQ; 00109 Parameters->DMA = DEFAULT_DMA; 00110 Parameters->BufferSize = DEFAULT_BUFSIZE; 00111 00112 // Only to be enabled once we can get support for multiple cards working :) 00113 /* 00114 DPRINT("Loading settings from: %S\n", RegistryPath); 00115 00116 s = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, RegistryPath, Table, 00117 &Parameters, NULL); 00118 00119 if (! NT_SUCCESS(s)) 00120 return s; 00121 */ 00122 00123 DPRINT("Port 0x%x IRQ %d DMA %d\n", Parameters->Port, Parameters->IRQ, Parameters->DMA); 00124 00125 // Instance->P 00126 00127 // Initialize the card 00128 DSP_Version = InitSoundCard(Parameters->Port); 00129 if (! DSP_Version) 00130 { 00131 DPRINT("Sound card initialization FAILED!\n"); 00132 // Set state indication somehow 00133 // Failure - what error code do we give?! 00134 // return STATUS_???? 00135 IoDeleteDevice(DeviceObject); 00136 return STATUS_UNSUCCESSFUL; 00137 } 00138 00139 DSP_Major = DSP_Version / 256; 00140 DSP_Minor = DSP_Version % 256; 00141 00142 // Do stuff related to version here... 00143 00144 DPRINT("Allocating DMA\n"); 00145 if (! CreateDMA(DeviceObject)) 00146 DPRINT("FAILURE!\n"); 00147 00148 // TEMPORARY TESTING STUFF: should be in BlasterCreate 00149 EnableSpeaker(Parameters->Port, TRUE); 00150 SetOutputSampleRate(Parameters->Port, 2205); 00151 BeginPlayback(Parameters->Port, 16, 2, Parameters->BufferSize); 00152 00153 DeviceCount ++; 00154 00155 return STATUS_SUCCESS; 00156 } 00157 00158 00159 static NTSTATUS NTAPI 00160 BlasterCreate(PDEVICE_OBJECT DeviceObject, 00161 PIRP Irp) 00162 /* 00163 * FUNCTION: Handles user mode requests 00164 * ARGUMENTS: 00165 * DeviceObject = Device for request 00166 * Irp = I/O request packet describing request 00167 * RETURNS: Success or failure 00168 */ 00169 { 00170 DPRINT("BlasterCreate() called!\n"); 00171 00172 // Initialize the MPU-401 00173 // ... do stuff ... 00174 00175 00176 // Play a note to say we're alive: 00177 // WaitToSend(MPU401_PORT); 00178 // MPU401_WRITE_DATA(MPU401_PORT, 0x90); 00179 // WaitToSend(MPU401_PORT); 00180 // MPU401_WRITE_DATA(MPU401_PORT, 0x50); 00181 // WaitToSend(MPU401_PORT); 00182 // MPU401_WRITE_DATA(MPU401_PORT, 0x7f); 00183 00184 Irp->IoStatus.Status = STATUS_SUCCESS; 00185 Irp->IoStatus.Information = 0; 00186 00187 DPRINT("IoCompleteRequest()\n"); 00188 00189 IoCompleteRequest(Irp, 00190 IO_NO_INCREMENT); 00191 00192 DPRINT("BlasterCreate() completed\n"); 00193 00194 return(STATUS_SUCCESS); 00195 } 00196 00197 00198 static NTSTATUS NTAPI 00199 BlasterClose(PDEVICE_OBJECT DeviceObject, 00200 PIRP Irp) 00201 /* 00202 * FUNCTION: Handles user mode requests 00203 * ARGUMENTS: 00204 * DeviceObject = Device for request 00205 * Irp = I/O request packet describing request 00206 * RETURNS: Success or failure 00207 */ 00208 { 00209 PDEVICE_EXTENSION DeviceExtension; 00210 NTSTATUS Status; 00211 00212 DPRINT("BlasterClose() called!\n"); 00213 00214 DeviceExtension = DeviceObject->DeviceExtension; 00215 00216 Status = STATUS_SUCCESS; 00217 00218 Irp->IoStatus.Status = Status; 00219 Irp->IoStatus.Information = 0; 00220 IoCompleteRequest(Irp, 00221 IO_NO_INCREMENT); 00222 00223 return(Status); 00224 } 00225 00226 00227 static NTSTATUS NTAPI 00228 BlasterCleanup(PDEVICE_OBJECT DeviceObject, 00229 PIRP Irp) 00230 /* 00231 * FUNCTION: Handles user mode requests 00232 * ARGUMENTS: 00233 * DeviceObject = Device for request 00234 * Irp = I/O request packet describing request 00235 * RETURNS: Success or failure 00236 */ 00237 { 00238 ULONG Channel; 00239 DPRINT("BlasterCleanup() called!\n"); 00240 00241 // Reset the device (should we do this?) 00242 for (Channel = 0; Channel <= 15; Channel ++) 00243 { 00244 // All notes off 00245 // MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 123, 0); 00246 // All controllers off 00247 // MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 121, 0); 00248 } 00249 00250 00251 Irp->IoStatus.Status = STATUS_SUCCESS; 00252 Irp->IoStatus.Information = 0; 00253 IoCompleteRequest(Irp, 00254 IO_NO_INCREMENT); 00255 00256 return(STATUS_SUCCESS); 00257 } 00258 00259 00260 static NTSTATUS NTAPI 00261 BlasterWrite(PDEVICE_OBJECT DeviceObject, PIRP Irp) 00262 { 00263 PIO_STACK_LOCATION Stack; 00264 PDEVICE_EXTENSION DeviceExtension; 00265 ULONG ByteCount; 00266 PUCHAR Data; 00267 00268 DPRINT("BlasterWrite() called!\n"); 00269 00270 DeviceExtension = DeviceObject->DeviceExtension; 00271 Stack = IoGetCurrentIrpStackLocation(Irp); 00272 00273 DPRINT("%d bytes\n", Stack->Parameters.Write.Length); 00274 00275 Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer; 00276 00277 for (ByteCount = 0; ByteCount < Stack->Parameters.Write.Length; ByteCount ++) 00278 { 00279 // DPRINT("0x%x ", Data[ByteCount]); 00280 00281 // MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]); 00282 } 00283 00284 Irp->IoStatus.Status = STATUS_SUCCESS; 00285 Irp->IoStatus.Information = 0; 00286 IoCompleteRequest(Irp, 00287 IO_NO_INCREMENT); 00288 00289 return(STATUS_SUCCESS); 00290 } 00291 00292 00293 static NTSTATUS NTAPI 00294 BlasterDeviceControl(PDEVICE_OBJECT DeviceObject, 00295 PIRP Irp) 00296 /* 00297 * FUNCTION: Handles user mode requests 00298 * ARGUMENTS: 00299 * DeviceObject = Device for request 00300 * Irp = I/O request packet describing request 00301 * RETURNS: Success or failure 00302 */ 00303 { 00304 PIO_STACK_LOCATION Stack; 00305 PDEVICE_EXTENSION DeviceExtension; 00306 00307 DPRINT("BlasterDeviceControl() called!\n"); 00308 00309 DeviceExtension = DeviceObject->DeviceExtension; 00310 Stack = IoGetCurrentIrpStackLocation(Irp); 00311 00312 switch(Stack->Parameters.DeviceIoControl.IoControlCode) 00313 { 00314 /* case IOCTL_MIDI_PLAY : 00315 { 00316 DPRINT("Received IOCTL_MIDI_PLAY\n"); 00317 Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer; 00318 00319 DPRINT("Sending %d bytes of MIDI data to 0x%d:\n", Stack->Parameters.DeviceIoControl.InputBufferLength, DeviceExtension->Port); 00320 00321 for (ByteCount = 0; ByteCount < Stack->Parameters.DeviceIoControl.InputBufferLength; ByteCount ++) 00322 { 00323 DPRINT("0x%x ", Data[ByteCount]); 00324 00325 MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]); 00326 // if (WaitToSend(MPU401_PORT)) 00327 // MPU401_WRITE_DATA(MPU401_PORT, Data[ByteCount]); 00328 } 00329 00330 Irp->IoStatus.Status = STATUS_SUCCESS; 00331 IoCompleteRequest(Irp, IO_NO_INCREMENT); 00332 00333 return(STATUS_SUCCESS); 00334 } 00335 */ 00336 } 00337 00338 return(STATUS_SUCCESS); 00339 00340 /* 00341 DeviceExtension = DeviceObject->DeviceExtension; 00342 Stack = IoGetCurrentIrpStackLocation(Irp); 00343 BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer; 00344 00345 Irp->IoStatus.Information = 0; 00346 00347 if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET) 00348 { 00349 Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED; 00350 IoCompleteRequest(Irp, 00351 IO_NO_INCREMENT); 00352 return(STATUS_NOT_IMPLEMENTED); 00353 } 00354 00355 if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS)) 00356 || (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM) 00357 || (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM)) 00358 { 00359 Irp->IoStatus.Status = STATUS_INVALID_PARAMETER; 00360 IoCompleteRequest(Irp, 00361 IO_NO_INCREMENT); 00362 return(STATUS_INVALID_PARAMETER); 00363 } 00364 00365 DueTime.QuadPart = 0; 00366 */ 00367 /* do the beep!! */ 00368 /* DPRINT("Beep:\n Freq: %lu Hz\n Dur: %lu ms\n", 00369 pbsp->Frequency, 00370 pbsp->Duration); 00371 00372 if (BeepParam->Duration >= 0) 00373 { 00374 DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000; 00375 00376 KeSetTimer(&DeviceExtension->Timer, 00377 DueTime, 00378 &DeviceExtension->Dpc); 00379 00380 HalMakeBeep(BeepParam->Frequency); 00381 DeviceExtension->BeepOn = TRUE; 00382 KeWaitForSingleObject(&DeviceExtension->Event, 00383 Executive, 00384 KernelMode, 00385 FALSE, 00386 NULL); 00387 } 00388 else if (BeepParam->Duration == (DWORD)-1) 00389 { 00390 if (DeviceExtension->BeepOn == TRUE) 00391 { 00392 HalMakeBeep(0); 00393 DeviceExtension->BeepOn = FALSE; 00394 } 00395 else 00396 { 00397 HalMakeBeep(BeepParam->Frequency); 00398 DeviceExtension->BeepOn = TRUE; 00399 } 00400 } 00401 00402 DPRINT("Did the beep!\n"); 00403 00404 Irp->IoStatus.Status = STATUS_SUCCESS; 00405 IoCompleteRequest(Irp, 00406 IO_NO_INCREMENT); 00407 return(STATUS_SUCCESS); 00408 */ 00409 } 00410 00411 00412 static VOID NTAPI 00413 BlasterUnload(PDRIVER_OBJECT DriverObject) 00414 { 00415 DPRINT("BlasterUnload() called!\n"); 00416 } 00417 00418 00419 NTSTATUS NTAPI 00420 DriverEntry(PDRIVER_OBJECT DriverObject, 00421 PUNICODE_STRING RegistryPath) 00422 /* 00423 * FUNCTION: Called by the system to initalize the driver 00424 * ARGUMENTS: 00425 * DriverObject = object describing this driver 00426 * RegistryPath = path to our configuration entries 00427 * RETURNS: Success or failure 00428 */ 00429 { 00430 // PDEVICE_EXTENSION DeviceExtension; 00431 // PDEVICE_OBJECT DeviceObject; 00432 // DEVICE_INSTANCE Instance; 00433 // Doesn't support multiple instances (yet ...) 00434 NTSTATUS Status; 00435 00436 DPRINT("Sound Blaster Device Driver 0.0.2\n"); 00437 00438 // Instance.DriverObject = DriverObject; 00439 // previous instance = NULL... 00440 00441 // DeviceExtension->RegistryPath = RegistryPath; 00442 00443 DriverObject->Flags = 0; 00444 DriverObject->MajorFunction[IRP_MJ_CREATE] = BlasterCreate; 00445 DriverObject->MajorFunction[IRP_MJ_CLOSE] = BlasterClose; 00446 DriverObject->MajorFunction[IRP_MJ_CLEANUP] = BlasterCleanup; 00447 DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = BlasterDeviceControl; 00448 DriverObject->MajorFunction[IRP_MJ_WRITE] = BlasterWrite; 00449 DriverObject->DriverUnload = BlasterUnload; 00450 00451 // Major hack to just get this damn thing working: 00452 Status = InitDevice(RegistryPath->Buffer, DriverObject); // ???? 00453 00454 // DPRINT("Enumerating devices at %wZ\n", RegistryPath); 00455 00456 // Status = EnumDeviceKeys(RegistryPath, PARMS_SUBKEY, InitDevice, (PVOID)&DeviceObject); // &Instance; 00457 00458 // check error 00459 00460 /* set up device extension */ 00461 // DeviceExtension = DeviceObject->DeviceExtension; 00462 // DeviceExtension->BeepOn = FALSE; 00463 00464 // return(STATUS_SUCCESS); 00465 return(Status); 00466 } 00467 00468 /* EOF */ Generated on Fri May 25 2012 04:24:39 for ReactOS by
1.7.6.1
|