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

Information | Donate

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

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

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

ReactOS Development > Doxygen

mpu401.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/mpu401/mpu401.c
00006  * PURPOSE:              MPU-401 MIDI device driver
00007  * PROGRAMMER:           Andrew Greenwood
00008  * UPDATE HISTORY:
00009  *                       Sept 26, 2003: Copied from beep.c as template
00010  *                       Sept 27, 2003: Implemented MPU-401 init & playback
00011  */
00012 
00013 /* INCLUDES ****************************************************************/
00014 
00015 #include <ntddk.h>
00016 //#include <ntddbeep.h>
00017 
00018 //#define NDEBUG
00019 #include <debug.h>
00020 
00021 #include "mpu401.h"
00022 
00023 
00024 /* INTERNAL VARIABLES ******************************************************/
00025 
00026 ULONG DeviceCount = 0;
00027 
00028 
00029 /* FUNCTIONS ***************************************************************/
00030 
00031 static NTSTATUS InitDevice(
00032     IN PUNICODE_STRING RegistryPath,
00033     IN PVOID Context)
00034 {
00035 //    PDEVICE_INSTANCE Instance = Context;
00036     PDEVICE_OBJECT DeviceObject; // = Context;
00037     PDEVICE_EXTENSION Parameters; // = DeviceObject->DeviceExtension;
00038     UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\\Device\\MidiOut0");
00039     UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\\??\\MidiOut0");
00040 //    CONFIG Config;
00041     RTL_QUERY_REGISTRY_TABLE Table[2];
00042     NTSTATUS s;
00043 
00044     // This is TEMPORARY, to ensure that we don't process more than 1 device.
00045     // I'll remove this limitation in the future.
00046     if (DeviceCount > 0)
00047     {
00048         DPRINT("Sorry - only 1 device supported by MPU401 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     IoCreateSymbolicLink(&SymlinkName,
00072                &DeviceName);
00073 
00074     DPRINT("Initializing device\n");
00075 
00076 //    DPRINT("Allocating memory for parameters structure\n");
00077     // Bodged:
00078 //    Parameters = (PDEVICE_EXTENSION)ExAllocatePool(NonPagedPool, sizeof(DEVICE_EXTENSION));
00079 //    DeviceObject->DeviceExtension = Parameters;
00080 //    Parameters = Instance->DriverObject->DriverExtension;
00081 
00082     DPRINT("DeviceObject at 0x%x, DeviceExtension at 0x%x\n", DeviceObject, Parameters);
00083 
00084     if (! Parameters)
00085     {
00086         DPRINT("NULL POINTER!\n");
00087         return STATUS_INSUFFICIENT_RESOURCES;
00088     }
00089 
00090 //    Instance->DriverObject->DriverExtension = Parameters;
00091 
00092     DPRINT("Setting reg path\n");
00093     Parameters->RegistryPath = RegistryPath;
00094 //    Parameters->DriverObject = Instance->DriverObject;
00095 
00096     DPRINT("Zeroing table memory and setting query routine\n");
00097     RtlZeroMemory(Table, sizeof(Table));
00098     Table[0].QueryRoutine = LoadSettings;
00099 
00100     DPRINT("Setting port and IRQ defaults\n");
00101     Parameters->Port = DEFAULT_PORT;
00102     Parameters->IRQ = DEFAULT_IRQ;
00103 
00104 // Only to be enabled once we can get support for multiple cards working :)
00105 /*
00106     DPRINT("Loading settings from: %S\n", RegistryPath);
00107 
00108     s = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, RegistryPath, Table,
00109                                 &Parameters, NULL);
00110 */
00111 
00112     if (! NT_SUCCESS(s))
00113         return s;
00114 
00115     DPRINT("Port 0x%x  IRQ %d\n", Parameters->Port, Parameters->IRQ);
00116 
00117 //    Instance->P
00118 
00119     // Enter UART mode (should be done in init phase
00120     if (! InitUARTMode(Parameters->Port))
00121     {
00122         DPRINT("UART mode initialization FAILED!\n");
00123         // Set state indication somehow
00124         // Failure - what error code do we give?!
00125         // return STATUS_????
00126     }
00127 
00128     DeviceCount ++;
00129 
00130     return STATUS_SUCCESS;
00131 }
00132 
00133 
00134 static NTSTATUS NTAPI
00135 MPU401Create(PDEVICE_OBJECT DeviceObject,
00136        PIRP Irp)
00137 /*
00138  * FUNCTION: Handles user mode requests
00139  * ARGUMENTS:
00140  *                       DeviceObject = Device for request
00141  *                       Irp = I/O request packet describing request
00142  * RETURNS: Success or failure
00143  */
00144 {
00145     DPRINT("MPU401Create() called!\n");
00146 
00147     // Initialize the MPU-401?
00148     // ... do stuff ...
00149 
00150 
00151     // Play a note to say we're alive:
00152     WaitToSend(MPU401_PORT);
00153     MPU401_WRITE_DATA(MPU401_PORT, 0x90);
00154     WaitToSend(MPU401_PORT);
00155     MPU401_WRITE_DATA(MPU401_PORT, 0x50);
00156     WaitToSend(MPU401_PORT);
00157     MPU401_WRITE_DATA(MPU401_PORT, 0x7f);
00158 
00159     Irp->IoStatus.Status = STATUS_SUCCESS;
00160     Irp->IoStatus.Information = 0;
00161     IoCompleteRequest(Irp,
00162             IO_NO_INCREMENT);
00163 
00164     return(STATUS_SUCCESS);
00165 }
00166 
00167 
00168 static NTSTATUS NTAPI
00169 MPU401Close(PDEVICE_OBJECT DeviceObject,
00170       PIRP Irp)
00171 /*
00172  * FUNCTION: Handles user mode requests
00173  * ARGUMENTS:
00174  *                       DeviceObject = Device for request
00175  *                       Irp = I/O request packet describing request
00176  * RETURNS: Success or failure
00177  */
00178 {
00179   PDEVICE_EXTENSION DeviceExtension;
00180   NTSTATUS Status;
00181 
00182   DPRINT("MPU401Close() called!\n");
00183 
00184   DeviceExtension = DeviceObject->DeviceExtension;
00185 
00186   Status = STATUS_SUCCESS;
00187 
00188   Irp->IoStatus.Status = Status;
00189   Irp->IoStatus.Information = 0;
00190   IoCompleteRequest(Irp,
00191             IO_NO_INCREMENT);
00192 
00193   return(Status);
00194 }
00195 
00196 
00197 static NTSTATUS NTAPI
00198 MPU401Cleanup(PDEVICE_OBJECT DeviceObject,
00199         PIRP Irp)
00200 /*
00201  * FUNCTION: Handles user mode requests
00202  * ARGUMENTS:
00203  *                       DeviceObject = Device for request
00204  *                       Irp = I/O request packet describing request
00205  * RETURNS: Success or failure
00206  */
00207 {
00208   ULONG Channel;
00209   DPRINT("MPU401Cleanup() called!\n");
00210 
00211     // Reset the device (should we do this?)
00212     for (Channel = 0; Channel <= 15; Channel ++)
00213     {
00214         // All notes off
00215 //        MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 123, 0);
00216         // All controllers off
00217 //        MPU401_WRITE_MESSAGE(MPU401_PORT, 0xb0 + Channel, 121, 0);
00218     }
00219 
00220 
00221   Irp->IoStatus.Status = STATUS_SUCCESS;
00222   Irp->IoStatus.Information = 0;
00223   IoCompleteRequest(Irp,
00224             IO_NO_INCREMENT);
00225 
00226   return(STATUS_SUCCESS);
00227 }
00228 
00229 
00230 static NTSTATUS NTAPI
00231 MPU401DeviceControl(PDEVICE_OBJECT DeviceObject,
00232           PIRP Irp)
00233 /*
00234  * FUNCTION: Handles user mode requests
00235  * ARGUMENTS:
00236  *                       DeviceObject = Device for request
00237  *                       Irp = I/O request packet describing request
00238  * RETURNS: Success or failure
00239  */
00240 {
00241     PIO_STACK_LOCATION Stack;
00242     PDEVICE_EXTENSION DeviceExtension;
00243     ULONG ByteCount;
00244     PUCHAR Data;
00245 
00246     DPRINT("MPU401DeviceControl() called!\n");
00247 
00248     DeviceExtension = DeviceObject->DeviceExtension;
00249     Stack = IoGetCurrentIrpStackLocation(Irp);
00250 
00251     DPRINT("Control code %d [0x%x]\n", Stack->Parameters.DeviceIoControl.IoControlCode,
00252                 Stack->Parameters.DeviceIoControl.IoControlCode);
00253 
00254     switch(Stack->Parameters.DeviceIoControl.IoControlCode)
00255     {
00256         case IOCTL_MIDI_PLAY :
00257         {
00258             DPRINT("Received IOCTL_MIDI_PLAY\n");
00259             Data = (PUCHAR) Irp->AssociatedIrp.SystemBuffer;
00260 
00261             DPRINT("Sending %d bytes of MIDI data to 0x%d:\n", Stack->Parameters.DeviceIoControl.InputBufferLength, DeviceExtension->Port);
00262 
00263             for (ByteCount = 0; ByteCount < Stack->Parameters.DeviceIoControl.InputBufferLength; ByteCount ++)
00264             {
00265                 DPRINT("0x%x ", Data[ByteCount]);
00266 
00267                 MPU401_WRITE_BYTE(DeviceExtension->Port, Data[ByteCount]);
00268 //                if (WaitToSend(MPU401_PORT))
00269 //                    MPU401_WRITE_DATA(MPU401_PORT, Data[ByteCount]);
00270             }
00271 
00272             Irp->IoStatus.Status = STATUS_SUCCESS;
00273             IoCompleteRequest(Irp, IO_NO_INCREMENT);
00274 
00275             return(STATUS_SUCCESS);
00276         }
00277     }
00278 
00279     return(STATUS_SUCCESS);
00280 
00281 /*
00282   DeviceExtension = DeviceObject->DeviceExtension;
00283   Stack = IoGetCurrentIrpStackLocation(Irp);
00284   BeepParam = (PBEEP_SET_PARAMETERS)Irp->AssociatedIrp.SystemBuffer;
00285 
00286   Irp->IoStatus.Information = 0;
00287 
00288   if (Stack->Parameters.DeviceIoControl.IoControlCode != IOCTL_BEEP_SET)
00289     {
00290       Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
00291       IoCompleteRequest(Irp,
00292             IO_NO_INCREMENT);
00293       return(STATUS_NOT_IMPLEMENTED);
00294     }
00295 
00296   if ((Stack->Parameters.DeviceIoControl.InputBufferLength != sizeof(BEEP_SET_PARAMETERS))
00297       || (BeepParam->Frequency < BEEP_FREQUENCY_MINIMUM)
00298       || (BeepParam->Frequency > BEEP_FREQUENCY_MAXIMUM))
00299     {
00300       Irp->IoStatus.Status = STATUS_INVALID_PARAMETER;
00301       IoCompleteRequest(Irp,
00302             IO_NO_INCREMENT);
00303       return(STATUS_INVALID_PARAMETER);
00304     }
00305 
00306   DueTime.QuadPart = 0;
00307 */
00308   /* do the beep!! */
00309 /*  DPRINT("Beep:\n  Freq: %lu Hz\n  Dur: %lu ms\n",
00310      pbsp->Frequency,
00311      pbsp->Duration);
00312 
00313   if (BeepParam->Duration >= 0)
00314     {
00315       DueTime.QuadPart = (LONGLONG)BeepParam->Duration * -10000;
00316 
00317       KeSetTimer(&DeviceExtension->Timer,
00318          DueTime,
00319          &DeviceExtension->Dpc);
00320 
00321       HalMakeBeep(BeepParam->Frequency);
00322       DeviceExtension->BeepOn = TRUE;
00323       KeWaitForSingleObject(&DeviceExtension->Event,
00324                 Executive,
00325                 KernelMode,
00326                 FALSE,
00327                 NULL);
00328     }
00329   else if (BeepParam->Duration == (DWORD)-1)
00330     {
00331       if (DeviceExtension->BeepOn == TRUE)
00332     {
00333       HalMakeBeep(0);
00334       DeviceExtension->BeepOn = FALSE;
00335     }
00336       else
00337     {
00338       HalMakeBeep(BeepParam->Frequency);
00339       DeviceExtension->BeepOn = TRUE;
00340     }
00341     }
00342 
00343   DPRINT("Did the beep!\n");
00344 
00345   Irp->IoStatus.Status = STATUS_SUCCESS;
00346   IoCompleteRequest(Irp,
00347             IO_NO_INCREMENT);
00348   return(STATUS_SUCCESS);
00349 */
00350 }
00351 
00352 
00353 static VOID NTAPI
00354 MPU401Unload(PDRIVER_OBJECT DriverObject)
00355 {
00356   DPRINT("MPU401Unload() called!\n");
00357 }
00358 
00359 
00360 NTSTATUS NTAPI
00361 DriverEntry(PDRIVER_OBJECT DriverObject,
00362         PUNICODE_STRING RegistryPath)
00363 /*
00364  * FUNCTION:  Called by the system to initalize the driver
00365  * ARGUMENTS:
00366  *            DriverObject = object describing this driver
00367  *            RegistryPath = path to our configuration entries
00368  * RETURNS:   Success or failure
00369  */
00370 {
00371 //  PDEVICE_EXTENSION DeviceExtension;
00372 //  PDEVICE_OBJECT DeviceObject;
00373 //  DEVICE_INSTANCE Instance;
00374   // Doesn't support multiple instances (yet ...)
00375   NTSTATUS Status;
00376 
00377   DPRINT("MPU401 Device Driver 0.0.1\n");
00378 
00379     // Is this really necessary? Yes! (Talking to myself again...)
00380 //    Instance.DriverObject = DriverObject;
00381     // previous instance = NULL...
00382 
00383 //    DeviceExtension->RegistryPath = RegistryPath;
00384 
00385   DriverObject->Flags = 0;
00386   DriverObject->MajorFunction[IRP_MJ_CREATE] = MPU401Create;
00387   DriverObject->MajorFunction[IRP_MJ_CLOSE] = MPU401Close;
00388   DriverObject->MajorFunction[IRP_MJ_CLEANUP] = MPU401Cleanup;
00389   DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MPU401DeviceControl;
00390   DriverObject->DriverUnload = MPU401Unload;
00391 
00392     // Major hack to just get this damn thing working:
00393     Status = InitDevice(RegistryPath, DriverObject);    // ????
00394 
00395 //    DPRINT("Enumerating devices at %wZ\n", RegistryPath);
00396 
00397 //    Status = EnumDeviceKeys(RegistryPath, PARMS_SUBKEY, InitDevice, (PVOID)&DeviceObject); // &Instance;
00398 
00399     // check error
00400 
00401   /* set up device extension */
00402 //  DeviceExtension = DeviceObject->DeviceExtension;
00403 //  DeviceExtension->BeepOn = FALSE;
00404 
00405   return(STATUS_SUCCESS);
00406 }
00407 
00408 /* EOF */

Generated on Thu May 24 2012 04:28:23 for ReactOS by doxygen 1.7.6.1

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