Exemplo n.º 1
0
// Read data from the audio Buffer.
// Called at interrupt time to get the good data from the audiobuffer object.
//
BOOL WAVESTREAM::_vReadAudioBuf(void)
{
   PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhInProcess.Head();
   ULONG pdataBuf;
   ULONG Buff_left, bytesread;

   if(!pTemp) return FALSE;

   // get the buffer pointer and amount of data remaining
   pdataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos;
   Buff_left = pTemp->ulBuffsz - pTemp->ulBuffpos;

   // write the audio buffer
   bytesread = OSS16_StreamAddBuffer(this, pdataBuf, Buff_left);
   if(bytesread == 0) {
	return FALSE; //no more data
   }

   dprintf4(("_vReadAudioBuf %lx size %d, bytes read %d", pdataBuf, Buff_left, bytesread));

   // update the buffer pos counter
   pTemp->ulBuffpos  += bytesread;
   _ulBytesProcessed += bytesread;

   if(pTemp->ulBuffpos == pTemp->ulBuffsz) {
      	qhDone.PushOnTail(qhInProcess.PopHead());
	ReturnBuffer();
   	dprintf4(("_vReadAudioBuf return buffer %lx size %ld, bytes read %ld", (ULONG)pTemp->pBuffptr, pTemp->ulBuffsz, bytesread));
   }

   return TRUE;
}
Exemplo n.º 2
0
void *fill_bounds_dir_buf_self(long byte_offset_inside_bounds_dir,
			   long buffer_size_bytes, void *buffer)

{
	unsigned char vec[buffer_size_bytes / PAGE_SIZE];
	char *dig_bounds_dir_ptr =
		(void *)(bounds_dir_global + byte_offset_inside_bounds_dir);
	/*
	 * use mincore() to quickly find the areas of the bounds directory
	 * that have memory and thus will be worth scanning.
	 */
	int incore_ret;

	int incore = 0;
	int i;

	dprintf4("%s() dig_bounds_dir_ptr: %p\n", __func__, dig_bounds_dir_ptr);

	incore_ret = mincore(dig_bounds_dir_ptr, buffer_size_bytes, &vec[0]);
	if (incore_ret) {
		printf("mincore ret: %d\n", incore_ret);
		perror("mincore");
		mpx_dig_abort();
	}
	for (i = 0; i < sizeof(vec); i++)
		incore += vec[i];
	dprintf4("%s() total incore: %d\n", __func__, incore);
	if (!incore)
		return NULL;
	dprintf3("%s() total incore: %d\n", __func__, incore);
	return dig_bounds_dir_ptr;
}
Exemplo n.º 3
0
/*****************************************************************************
    SoundInitDmaChannel()

*****************************************************************************/
NTSTATUS    SoundInitDmaChannel( IN OUT PGLOBAL_DEVICE_INFO pGDI,
                              IN OUT PULONG DmaChannel,
                              IN     ULONG  DmaBufferSize )
{
        /***** Local Variables *****/

    DEVICE_DESCRIPTION  DeviceDescription;              // DMA adapter object

                /***** Start *****/

    dprintf3(("SoundInitDmaChannel(): Start"));
    dprintf4((" SoundInitDmaChannel():  DMA Channel     = %u", *DmaChannel));
    dprintf4((" SoundInitDmaChannel():  DMA Buffer Size = %XH", DmaBufferSize));

    //
    // See if we can get this channel
    //

    //
    // Zero the device description structure.
    //

    RtlZeroMemory(&DeviceDescription,
                  sizeof(DEVICE_DESCRIPTION));

    //
    // Get the adapter object for this card.
    //

    DeviceDescription.Version        = DEVICE_DESCRIPTION_VERSION;
    DeviceDescription.AutoInitialize = TRUE;
    DeviceDescription.ScatterGather  = FALSE;
    DeviceDescription.DmaChannel     = *DmaChannel;
    DeviceDescription.InterfaceType  = Isa;                 // Must use Isa DMA
    DeviceDescription.DmaSpeed       = Compatible;
    DeviceDescription.MaximumLength  = DmaBufferSize;
    DeviceDescription.BusNumber      = pGDI->BusNumber;

    //
    // Check the DMA Channel to set the DMA width
    //
    if ( *DmaChannel > 4 )
        {
        // 16 Bit DMA
        DeviceDescription.DmaWidth       = Width16Bits;
        }
    else
        {
        // 8 Bit DMA
        DeviceDescription.DmaWidth       = Width8Bits;
        }

    return SoundGetCommonBuffer(&DeviceDescription, &pGDI->WaveInfo.DMABuf);

}           // End SoundInitDmaChannel()
Exemplo n.º 4
0
static void
gx_print_segment(const segment * pseg)
{
    double px = fixed2float(pseg->pt.x);
    double py = fixed2float(pseg->pt.y);
    char out[80];

    sprintf(out, "0x%lx<0x%lx,0x%lx>:%u",
         (ulong) pseg, (ulong) pseg->prev, (ulong) pseg->next, pseg->notes);
    switch (pseg->type) {
        case s_start:{
                const subpath *const psub = (const subpath *)pseg;

                dprintf5("   %1.4f %1.4f moveto\t%% %s #curves=%d last=0x%lx\n",
                         px, py, out, psub->curve_count, (ulong) psub->last);
                break;
            }
        case s_curve:{
                const curve_segment *const pcur = (const curve_segment *)pseg;

                dprintf7("   %1.4f %1.4f %1.4f %1.4f %1.4f %1.4f curveto\t%% %s\n",
                         fixed2float(pcur->p1.x), fixed2float(pcur->p1.y),
                         fixed2float(pcur->p2.x), fixed2float(pcur->p2.y),
                         px, py, out);
                break;
            }
        case s_line:
            dprintf3("   %1.4f %1.4f lineto\t%% %s\n", px, py, out);
            break;
        case s_gap:
            dprintf3("   %1.4f %1.4f gapto\t%% %s\n", px, py, out);
            break;
        case s_dash:{
                const dash_segment *const pd = (const dash_segment *)pseg;

                dprintf5("   %1.4f %1.4f %1.4f  %1.4f dash\t%% %s\n",
                         fixed2float(pd->pt.x), fixed2float(pd->pt.y),
                         fixed2float(pd->tangent.x),fixed2float(pd->tangent.y),
                         out);
                break;
            }
        case s_line_close:{
                const line_close_segment *const plc =
                (const line_close_segment *)pseg;

                dprintf4("   closepath\t%% %s %1.4f %1.4f 0x%lx\n",
                         out, px, py, (ulong) (plc->sub));
                break;
            }
        default:
            dprintf4("   %1.4f %1.4f <type 0x%x>\t%% %s\n",
                     px, py, pseg->type, out);
    }
}
Exemplo n.º 5
0
int inspect_pid(int pid)
{
	static int dig_nr;
	long offset_inside_bounds_dir;
	char bounds_dir_buf[sizeof(unsigned long) * (1UL << 15)];
	char *dig_bounds_dir_ptr;
	int total_entries = 0;
	int nr_populated_bdes = 0;
	int inspect_self;

	if (getpid() == pid) {
		dprintf4("inspecting self\n");
		inspect_self = 1;
	} else {
		dprintf4("inspecting pid %d\n", pid);
		mpx_dig_abort();
	}

	for (offset_inside_bounds_dir = 0;
	     offset_inside_bounds_dir < MPX_BOUNDS_TABLE_SIZE_BYTES;
	     offset_inside_bounds_dir += sizeof(bounds_dir_buf)) {
		static int bufs_skipped;
		int this_entries;

		if (inspect_self) {
			dig_bounds_dir_ptr =
				fill_bounds_dir_buf_self(offset_inside_bounds_dir,
							 sizeof(bounds_dir_buf),
							 &bounds_dir_buf[0]);
		} else {
			dig_bounds_dir_ptr =
				fill_bounds_dir_buf_other(offset_inside_bounds_dir,
							  sizeof(bounds_dir_buf),
							  &bounds_dir_buf[0]);
		}
		if (!dig_bounds_dir_ptr) {
			bufs_skipped++;
			continue;
		}
		this_entries = search_bd_buf(dig_bounds_dir_ptr,
					sizeof(bounds_dir_buf),
					offset_inside_bounds_dir,
					&nr_populated_bdes);
		total_entries += this_entries;
	}
	printf("mpx dig (%3d) complete, SUCCESS (%8d / %4d)\n", ++dig_nr,
			total_entries, nr_populated_bdes);
	return total_entries + nr_populated_bdes;
}
Exemplo n.º 6
0
/*****************************************************************************
    SoundInitInterrupt()

*****************************************************************************/
NTSTATUS    SoundInitInterrupt( IN OUT PGLOBAL_DEVICE_INFO pGDI,
                             IN OUT PULONG              Interrupt )
{
        /***** Local Variables *****/

    NTSTATUS            Status;

                /***** Start *****/

    dprintf4(("SoundInitInterrupt(): Start"));

    //
    // See if we can get this interrupt
    //

    Status = SoundConnectInterrupt(*Interrupt,
                                   pGDI->BusType,
                                   pGDI->BusNumber,
                                   SoundISR,
                                  (PVOID)pGDI,
                                   INTERRUPT_MODE,
                                   IRQ_SHARABLE,
                                  &pGDI->WaveInfo.Interrupt );

    if (!NT_SUCCESS(Status))
        {
        dprintf1(("ERROR: SoundInitInterrupt(): SoundConnectInterrupt() Failed with Status = %XH",
                                        Status));
        return Status;
        }           // End IF (!NT_SUCCESS(Status))

    return STATUS_SUCCESS;

}           // End SoundInitInterrupt()
Exemplo n.º 7
0
VOID
sndStopDMA(
    IN    PGLOBAL_DEVICE_INFO pGDI
)
/*++

Routine Description:

    Stop the DMA at once by disabling the hardware
    Free the adapter channel.
    (Opposite of sndStartDMA).

Arguments:

    pGDI - pointer to global device info

Return Value:

    None

--*/
{

    //
    // Pass HALT DMA to the MIPSSND
    //

    if (pGDI->DMABusy) {
        KeSynchronizeExecution(pGDI->pInterrupt, StopDMA, pGDI);

        //
        // Flush our buffers
        //
        sndFlush(pGDI, 0);
        sndFlush(pGDI, 1);

        //
        // Stop the DMA controller
        //

        if (pGDI->Usage == SoundInterruptUsageWaveIn) {
                IoFreeAdapterChannel(pGDI->pAdapterObject[2]);
                IoFreeAdapterChannel(pGDI->pAdapterObject[3]);
        } else {
                IoFreeAdapterChannel(pGDI->pAdapterObject[0]);
                IoFreeAdapterChannel(pGDI->pAdapterObject[1]);
        }
    }

    dprintf4(" dma_stopped");


    //
    // Note our new state
    //

    pGDI->DMABusy = FALSE;
}
Exemplo n.º 8
0
long inspect_me(struct mpx_bounds_dir *bounds_dir)
{
	int pid = getpid();

	pid_load_vaddrs(pid);
	bounds_dir_global = (unsigned long)bounds_dir;
	dprintf4("enter %s() bounds dir: %p\n", __func__, bounds_dir);
	return inspect_pid(pid);
}
Exemplo n.º 9
0
/*****************************************************************************

    SoundInitIoPort()

*****************************************************************************/
NTSTATUS    SoundInitIoPort( IN OUT PGLOBAL_DEVICE_INFO pGDI,
                          IN OUT PPAS_CONFIG_DATA ConfigData )
{
        /***** Local Variables *****/

//  NTSTATUS        Status;
    NTSTATUS        PasStatus;

                /***** Start *****/

    //
    // Find where our device is mapped
    //

    dprintf4(("SoundInitIoPort(): Start"));

#if 0
    // Do this in FindPasHardware instead!!
    pGDI->Hw.PortBase = SoundMapPortAddress( pGDI->BusType,
                                            pGDI->BusNumber,
                                            ConfigData->Port,
                                            NUMBER_OF_PAS_PORTS,
                                           &pGDI->MemType);
#else
    pGDI->Hw.PortBase = (PUCHAR) &pGDI->PASInfo.ProPort;
#endif          // 0

    //
    // Try to Locate any ProAudio Spectrums
    //
    PasStatus = FindPasHardware( pGDI,
                                ConfigData );

    if ( !NT_SUCCESS(PasStatus) )
        {
        dprintf1(("ERROR: SoundInitIoPort(): FindPasHardware() Failed with Status = %XH",
                                     PasStatus));
        return STATUS_DEVICE_CONFIGURATION_ERROR;
        }           // End IF (!NT_SUCCESS(PasStatus))

    pGDI->ProAudioSpectrum = TRUE;
    pGDI->Hw.ThunderBoard  = FALSE;

    InitPasAndMixer( pGDI,
                   &pGDI->PASInfo,
                    ConfigData );

    //
    // Setup Min & Max values
    //
    pGDI->MinHz    = MIN_SAMPLE_RATE;
    pGDI->MaxInHz  = MAX_SAMPLE_RATE;
    pGDI->MaxOutHz = MAX_SAMPLE_RATE;

    return STATUS_SUCCESS;

}           // End SoundInitIoPort()
Exemplo n.º 10
0
// called by the irq function in the hardware object when we get an interrupt
// first call _vUpdateProcessed() to update the dma amd audio buffer related
// stuff. Next if we have buffers on the primary queue try to read/write them
// to the audiobuffer. Look at the buffers on the done queue and see if they
// can be returned and finally process any events pending.
void WAVESTREAM::Process(void)
{
 PSTREAMBUFFER ptemp;
 ULONG         ulCurBytesProcessed = 0;
 ULONG         bytesinc;

   switch (ulStreamType & STREAM_WRITE) {
   case STREAM_WRITE:
   {
   	OSS16_StreamGetPos(this, &ulCurBytesProcessed);
   	if(ulCurBytesProcessed == 0) {
		//shouldn't happen
		DebugInt3();
		return;
	}
   	bytesinc           = ulCurBytesProcessed - _ulBytesProcessed;
	dprintf4(("Process: %lx %x", ulCurBytesProcessed, (USHORT)bytesinc));
	if(ulCurBytesProcessed < _ulBytesProcessed) {
       		dprintf(("WARNING: Process: Current pos %ld incr %d", ulCurBytesProcessed, (USHORT)bytesinc));
	}
   	_ulBytesProcessed  = ulCurBytesProcessed;

      	while(bytesinc) {
      	  if(qhDone.IsElements()) {  // if there are buffers that have been
                                  // completly written to the audio buffer
                                  // check the first one on the done queue
                                  // if it's data has been consumed by
                                  // the hardware return it
         	ptemp = (PSTREAMBUFFER)qhDone.Head();
		ptemp->ulDonepos += bytesinc;
		bytesinc          = 0;
		if(ptemp->ulDonepos >= ptemp->ulBuffsz) {
			//calc position in next buffer
			bytesinc = ptemp->ulDonepos - ptemp->ulBuffsz;
			dprintf3(("Process: Return buffer %lx size %d", ptemp->pBuffptr, ptemp->ulBuffsz));
		 	ReturnBuffer();
		}
      	  }
	  else	break; //shouldn't happen
      	}
	AddBuffers(FALSE);
	break;
   }
   case STREAM_READ:
	while(_vReadAudioBuf());
	break;
   default:
      break;
   } /* endswitch */

   ProcessEvents();
}
Exemplo n.º 11
0
//
// write one buffer to the audio buffer
// the caller of this function MUST make sure it ok to write the audio buffer..
// _AudioBufWrite will not check if there is room in the audio buffer of if
// there are buffers on pHead... BEWARE
//
ULONG WAVESTREAM::AddBuffer(ULONG space)
{
   PSTREAMBUFFER pTemp = (PSTREAMBUFFER)qhDone.Tail();
   ULONG pdataBuf;
   ULONG Buff_left, byteswritten;

   if(!pTemp || pTemp->ulBuffpos >= (pTemp->ulBuffsz & 0xFFFFFFFC)) {
	pTemp = (PSTREAMBUFFER)qhInProcess.Head();
   }
   if(!pTemp) {
	dprintf4(("AddBuffer: pTemp == NULL"));
	return (ULONG)-1;
   }

   // get the buffer pointer and amount of data remaining
   pdataBuf = (ULONG)pTemp->pBuffptr + pTemp->ulBuffpos;
   Buff_left = pTemp->ulBuffsz - pTemp->ulBuffpos;

   if(Buff_left) {
        // write the audio buffer
        Buff_left = min(Buff_left, space);
        byteswritten = OSS16_StreamAddBuffer(this, pdataBuf, Buff_left);
        if(byteswritten == 0) {
  	    return (ULONG)-1; //no more room
        }

        // update the buffer pos counter
        pTemp->ulBuffpos += byteswritten;
   } 
   else byteswritten = 0;

   if(pTemp == qhInProcess.Head()) {
	qhDone.PushOnTail(qhInProcess.PopHead());
   }
   dprintf4(("AddBuffer %lx size %d, bytes written %d", pdataBuf, (USHORT)Buff_left, (USHORT)byteswritten));
   return byteswritten;
}
Exemplo n.º 12
0
int __pid_load_vaddrs(int pid)
{
	int ret = 0;
	int proc_maps_fd = open_proc(pid, "maps");
	char linebuf[10000];
	unsigned long start;
	unsigned long end;
	char rest[1000];
	FILE *f = fdopen(proc_maps_fd, "r");

	if (!f)
		mpx_dig_abort();
	nr_ranges_populated = 0;
	while (!feof(f)) {
		char *readret = fgets(linebuf, sizeof(linebuf), f);
		int parsed;

		if (readret == NULL) {
			if (feof(f))
				break;
			mpx_dig_abort();
		}

		parsed = sscanf(linebuf, "%lx-%lx%s", &start, &end, rest);
		if (parsed != 3)
			mpx_dig_abort();

		dprintf4("result[%d]: %lx-%lx<->%s\n", parsed, start, end, rest);
		if (nr_ranges_populated >= nr_ranges_allocated) {
			ret = -E2BIG;
			break;
		}
		ranges[nr_ranges_populated].start = start;
		ranges[nr_ranges_populated].end = end;
		nr_ranges_populated++;
	}
	last_range = -1;
	fclose(f);
	close(proc_maps_fd);
	return ret;
}
Exemplo n.º 13
0
static int
svg_lineto(gx_device_vector *vdev, floatp x0, floatp y0,
           floatp x, floatp y, gx_path_type_t type)
{
    gx_device_svg *svg = (gx_device_svg *)vdev;
    char line[SVG_LINESIZE];

    /* hack single-page output */
    if (svg->page_count)
        return 0;

    /* skip non-drawing paths for now */
    if (!(type & gx_path_type_fill) && !(type & gx_path_type_stroke))
        return 0;

    dprintf4("svg_lineto(%lf,%lf,%lf,%lf) ", x0,y0, x,y);
    svg_print_path_type(svg, type);
    dprintf("\n");

    sprintf(line, " L%lf,%lf", x, y);
    svg_write(svg, line);

    return 0;
}
Exemplo n.º 14
0
/*****************************************************************************

Routine Description :

    Saves the drivers Volume configuration information for our device

Arguments :

    PGLOBAL_DEVICE_INFO pGDI

Return Value :

    NT status code - STATUS_SUCCESS if no problems

*****************************************************************************/
VOID    SoundSaveVolume( PGLOBAL_DEVICE_INFO pGDI )
{
        /***** Local Variables *****/

    int                     i;
    PLOCAL_DEVICE_INFO  pLDI;

                /***** Start *****/

    dprintf4(("SoundSaveVolume(): Start"));

    //
    // Write out left and right volume settings for each device
    //

    for (i = 0; i < NumberOfDevices; i++) {
        if ( pGDI->DeviceObject[i] ) {
            pLDI = (PLOCAL_DEVICE_INFO)pGDI->DeviceObject[i]->DeviceExtension;
            SoundSaveDeviceVolume( pLDI, pGDI->RegistryPathName );
        }

    }           // End FOR (i < NumberOfDevices)

}           // End SoundSaveVolume()
Exemplo n.º 15
0
VOID
sndReStartDMA(
    IN PGLOBAL_DEVICE_INFO pGDI,
    IN int WhichBuffer
    )
/*++

Routine Description:

    Restart the DMA on a given channel

Arguments:

    pGDI -  Supplies pointer to global device info.
    WhichBuffer - which channel to use

Return Value:

    Returns FALSE

--*/
{
    ULONG length;


    length = pGDI->DmaHalfBufferSize;

    //
    // Increment count of pending interrupts.
    //

    pGDI->SoundHardware.TcInterruptsPending += 1;

    dprintf5("sndReStartDMA(): incremented pending interrupts %d",
             pGDI->SoundHardware.TcInterruptsPending);

    //
    // Program the DMA controller registers for the transfer
    // Set the direction of transfer by whether we're wave in or
    // wave out.
    //

    KeFlushIoBuffers( pGDI->pDMABufferMDL[WhichBuffer],
                     (pGDI->Usage == SoundInterruptUsageWaveIn),
                                         TRUE);

    dprintf4("sndReStartDMA(): calling IoMapTransfer BUFFER = %d", WhichBuffer);

    if (pGDI->Usage == SoundInterruptUsageWaveIn) {

        IoMapTransfer(pGDI->pAdapterObject[(WhichBuffer) ? 3 : 2],
                  pGDI->pDMABufferMDL[WhichBuffer],
                  pGDI->pMRB[WhichBuffer],
                  pGDI->DMABuffer[WhichBuffer].Buf,
                  &length,
                  (BOOLEAN)(pGDI->Usage != SoundInterruptUsageWaveIn));

    } else {

        IoMapTransfer(pGDI->pAdapterObject[WhichBuffer],
                  pGDI->pDMABufferMDL[WhichBuffer],
                  pGDI->pMRB[WhichBuffer],
                  pGDI->DMABuffer[WhichBuffer].Buf,
                  &length,
                  (BOOLEAN)(pGDI->Usage != SoundInterruptUsageWaveIn));

    }
}
Exemplo n.º 16
0
NTSTATUS
SoundCardInstanceInit(
    IN   PWSTR RegistryPathName,
    IN   PVOID Context
)
{
    /*
    ** Instance data
    */

    PSOUND_CARD_INSTANCE CardInstance;

    //
    // Return code from last function called
    //

    NTSTATUS        Status;

    //
    // Configuration data :
    //

    SB_CONFIG_DATA  ConfigData;

    //
    // Where we keep all general driver information
    // We avoid using static data because :
    //     1. Accesses are slower with 32-bit offsets
    //     2. We support more than one card instance
    //

    PGLOBAL_DEVICE_INFO pGDI;

    //
    // The number of devices we actually create
    //

    int         NumberOfDevicesCreated;

    //
    //  The context is the global device info pointer from the previous
    //  instance
    //

    CardInstance = Context;


   /********************************************************************
    *
    * Allocate our global info
    *
    ********************************************************************/

    pGDI =
        (PGLOBAL_DEVICE_INFO)ExAllocatePool(
                                  NonPagedPool,
                                  sizeof(GLOBAL_DEVICE_INFO));

    if (pGDI == NULL) {
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    dprintf4((" DriverEntry():  GlobalInfo    : %08lXH", pGDI));

    RtlZeroMemory(pGDI, sizeof(GLOBAL_DEVICE_INFO));
    pGDI->Key              = GDI_KEY;
    pGDI->Hw.Key           = HARDWARE_KEY;
    pGDI->RegistryPathName = RegistryPathName;

    pGDI->Usage            = 0xFF;                    // Free
    pGDI->DriverObject     = CardInstance->pDriverObject;

    //
    // Mutual exclusion :
    //
    //    Everything is synchronized on the DeviceMutex (except for
    //    some stuff inside the wave device) except
    //
    //    Midi external output which takes too long and so is synchronized
    //    separately but grabs the DeviceMutex every time it actually
    //    writes anything and
    //
    //    Synth output where the hardware is separate but callbacks to the
    //    mixer must grab the DeviceMutex.
    //

    KeInitializeMutex(&pGDI->DeviceMutex,
                       2                     // High level
                       );

    KeInitializeMutex(&pGDI->MidiMutex,
                       1                     // Low level
                       );

    KeInitializeMutex(&pGDI->Hw.DSPMutex,
                       3                     // Highest level
                       );

   /********************************************************************
    *
    *  Add ourselves to the ring of cards
    *
    ********************************************************************/

    if (CardInstance->PrevGDI == NULL) {
        pGDI->Next = pGDI;
    } else {
        PGLOBAL_DEVICE_INFO pNext;
        pNext = CardInstance->PrevGDI->Next;
        CardInstance->PrevGDI->Next = pGDI;
        pGDI->Next = pNext;
    }
    CardInstance->PrevGDI = pGDI;


   /********************************************************************
    *
    *  See if we can find our bus.  We run on both ISA and EISA
    *  We ASSUME that if there's an ISA bus we're on that
    *
    ********************************************************************/

    Status = SoundGetBusNumber(Isa, &pGDI->BusNumber);

    if (!NT_SUCCESS(Status)) {
        //
        // Cound not find an ISA bus so try EISA
        //
        Status = SoundGetBusNumber(Eisa, &pGDI->BusNumber);

        if (!NT_SUCCESS(Status)) {
            Status = SoundGetBusNumber(MicroChannel, &pGDI->BusNumber);

            if (!NT_SUCCESS(Status)) {
                dprintf1(("driver does not work on non-Isa/Eisa/Mca"));
                return Status;
            }
            pGDI->BusType = MicroChannel;

        } else {
            pGDI->BusType = Eisa;
        }
    } else {
        pGDI->BusType = Isa;
    }

    //
    // Set configuration to default in case we don't get all the
    // values back from the registry.
    //
    // Also set default volume for all devices
    //

    ConfigData.Port            = SOUND_DEF_PORT;
    ConfigData.InterruptNumber = SOUND_DEF_INT;
    ConfigData.DmaChannel      = SOUND_DEF_DMACHANNEL;
    ConfigData.DmaChannel16    = SOUND_DEF_DMACHANNEL16;
    ConfigData.DmaBufferSize   = DEFAULT_DMA_BUFFERSIZE;
    ConfigData.MPU401Port      = SOUND_DEF_MPU401_PORT;
    ConfigData.LoadType        = SOUND_LOADTYPE_NORMAL;
    ConfigData.MixerSettingsFound = FALSE;

    //
    // Get the system configuration information for this driver.
    //
    //
    //     Port, Interrupt, DMA channel, DMA 16-bit channel DMA buffer size
    //

    {
        RTL_QUERY_REGISTRY_TABLE    Table[2];

        RtlZeroMemory(Table, sizeof(Table));

        Table[0].QueryRoutine = SoundReadConfiguration;

        Status = RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE,
                                         pGDI->RegistryPathName,
                                         Table,
                                         &ConfigData,
                                         NULL );

        if (!NT_SUCCESS(Status)) {
            dprintf1(("ERROR: DriverEntry(): RtlQueryRegistryValues() Failed with Status = %XH", Status));
            return Status;
        }           // End IF (!NT_SUCCESS(Status))
    }           // End Query Resistry Values

    //
    // Save additional Config data
    //
    pGDI->InterruptNumber = ConfigData.InterruptNumber;
    pGDI->DmaChannel      = ConfigData.DmaChannel;
    pGDI->DmaChannel16    = ConfigData.DmaChannel16;

    //
    // Verify the DMA Buffer Size
    //
    if ( ConfigData.DmaBufferSize < MIN_DMA_BUFFERSIZE ) {
        ConfigData.DmaBufferSize = MIN_DMA_BUFFERSIZE;
        dprintf1((" DriverEntry(): Adjusting the DMA Buffer size, size in Registry was too small"));
    }

    //
    // print out some info about the configuration
    //

    dprintf2((" DriverEntry():  Base I/O Port     = %XH", ConfigData.Port));
    dprintf2((" DriverEntry():  Interrupt         = %u",  ConfigData.InterruptNumber));
    dprintf2((" DriverEntry():  DMA Channel       = %u",  ConfigData.DmaChannel));
    dprintf2((" DriverEntry():  DMA Channel (16 bit) = %u",  ConfigData.DmaChannel16));
    dprintf2((" DriverEntry():  DMA Buffer Size   = %XH", ConfigData.DmaBufferSize));
    dprintf2((" DriverEntry():  MPU 401 port      = %XH", ConfigData.MPU401Port));

    /*
    **  Create our wave devices to ease reporting problems
    */

    Status = SBCreateDevice(pGDI, WaveInDevice);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    Status = SBCreateDevice(pGDI, WaveOutDevice);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    /*
    **  Say we want to be called at shutdown time
    */

    Status = IoRegisterShutdownNotification(pGDI->DeviceObject[WaveInDevice]);
    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    pGDI->ShutdownRegistered = TRUE;


    /*
    **  Check the configuration and acquire the resources
    */

    Status = SoundInitHardwareConfig(pGDI, &ConfigData);

    if (!NT_SUCCESS(Status)) {
        dprintf1(("ERROR: DriverEntry(): SoundInitHardwareConfig() Failed with Status = %XH",
                                 Status));
        return Status;
    }

    /*
    **  Initialize generic device environments - first get the
    **  hardware routines in place.
    **  We do this here after we've found out what hardware we've got
    */

    HwInitialize(pGDI);

    SoundInitMidiIn(&pGDI->MidiInfo,
                    &pGDI->Hw);


    /*
    **  Register most of our resources.  Some may be registered on
    **  the wave output device :
    **     16-bit dma channel
    **
    **  We wipe out the registration of the MPU401 port when we do this
    **  but this is OK.
    */

    {
        ULONG PortToReport;
        PortToReport = ConfigData.Port + MIX_ADDR_PORT;

        Status = SoundReportResourceUsage(
                     pGDI->DeviceObject[WaveInDevice],  // As good as any device to own
                                                   // it
                     pGDI->BusType,
                     pGDI->BusNumber,
                     &ConfigData.InterruptNumber,
                     INTERRUPT_MODE,
                     (BOOLEAN)(SB16(&pGDI->Hw) ? TRUE : FALSE),  // Sharable for SB16
                     &ConfigData.DmaChannel,
                     &PortToReport,
                     NUMBER_OF_SOUND_PORTS - MIX_ADDR_PORT);
    }

    if (!NT_SUCCESS(Status)) {
        dprintf1(("Error - failed to claim resources - code %8X", Status));
        pGDI->LoadStatus = SOUND_CONFIG_ERROR;
        return Status;
    }
    /*
    **  Now we know what device we've got we can create the appropriate
    **  devices
    */

    /*
    **  Thuderboard has no external midi and we're going to
    **  drive the SB16 in MPU401 mode if we can
    */

    if (!pGDI->Hw.ThunderBoard) {
        //
        //  Don't create the MPU401 device if it is disabled
        //
        if (!SB16(&pGDI->Hw) ||
            (ULONG)-1 != ConfigData.MPU401Port)
        {
            Status = SBCreateDevice(pGDI, MidiOutDevice);
            if (!NT_SUCCESS(Status)) {
                return Status;
            }
            Status = SBCreateDevice(pGDI, MidiInDevice);
            if (!NT_SUCCESS(Status)) {
                return Status;
            }
        }
    }

    /*
    **  Create volume control stuff for those devices which have it
    */

    if (SBPRO(&pGDI->Hw) || SB16(&pGDI->Hw)
#ifdef SB_CD
        ||
        pGDI->Hw.SBCDBase != NULL
#endif // SB_CD
        ) {
        Status = SBCreateDevice(pGDI, LineInDevice);
        if (!NT_SUCCESS(Status)) {
            return Status;
        }
        Status = SBCreateDevice(pGDI, CDInternal);
        if (!NT_SUCCESS(Status)) {
            return Status;
        }
        Status = SBCreateDevice(pGDI, MixerDevice);
        if (!NT_SUCCESS(Status)) {
            return Status;
        }
    } else {
        /*  Volume setting not supported for our wave device */
        ((PLOCAL_DEVICE_INFO)pGDI->DeviceObject[WaveOutDevice]->DeviceExtension)->CreationFlags |=
            SOUND_CREATION_NO_VOLUME;
    }

    /*
    ** Init the WaveInfo structure
    */

    SoundInitializeWaveInfo(&pGDI->WaveInfo,
                            (UCHAR)(SB1(&pGDI->Hw) ?
                                        SoundReprogramOnInterruptDMA :
                                        SoundAutoInitDMA),
                            SoundQueryFormat,
                            &pGDI->Hw);

    if (ConfigData.SynthType == SOUND_SYNTH_TYPE_NONE) {
        /*
        **  This will happen if the user selected a basic config without
        **  a synthesizer.
        */
        dprintf2(("No synth!"));
    } else {
        Status = SynthInit(CardInstance->pDriverObject,
                           pGDI->RegistryPathName,
                           &pGDI->Synth,
                           SB16(&pGDI->Hw) ||
                           SBPRO(&pGDI->Hw) && INPORT(&pGDI->Hw, 0) == 0 ?
                               ConfigData.Port : SYNTH_PORT,
                           FALSE,                         // Interrupt not enabled
                           pGDI->BusType,
                           pGDI->BusNumber,
                           NULL,
                           SOUND_MIXER_INVALID_CONTROL_ID,// Set volume later
                           TRUE,                          // Allow multiple
                           SoundMidiOutGetSynthCaps
                           );
        
        if (!NT_SUCCESS(Status)) {
        
            /*
            **  OK - we can get along without a synth
            */
        
            dprintf2(("No synth!"));
        } else {
            if (!pGDI->Synth.IsOpl3) {
                dprintf2(("Synth is Adlib"));
            } else {
        
                /*
                **  Bad aliasing in early sound blasters means we can
                **  guess wrong.
                */
        
                if (!(SB16(&pGDI->Hw) || SBPRO(&pGDI->Hw) && INPORT(&pGDI->Hw, 0) == 0)) {
                    pGDI->Synth.IsOpl3 = FALSE;
                }
                dprintf2(("Synth is Opl3"));
            }
        }
    }

    /*
    **  Set the mixer up.
    **
    **  Note that the mixer info depends on what hardware is present
    **  so this must be called after we have checked out the hardware.
    */

    if (pGDI->DeviceObject[MixerDevice]) {
        Status = SoundMixerInit(pGDI->DeviceObject[MixerDevice]->DeviceExtension,
                                &ConfigData.MixerSettings,
                                ConfigData.MixerSettingsFound);

        if (!NT_SUCCESS(Status)) {
            return Status;
        }
    }

    /*
    ** Save new settings
    */

    Status = SoundSaveConfig(pGDI->RegistryPathName,
                             ConfigData.Port,
                             ConfigData.DmaChannel,
                             ConfigData.DmaChannel16,
                             ConfigData.InterruptNumber,
                             ConfigData.MPU401Port,
                             (BOOLEAN)(pGDI->Synth.DeviceObject != NULL),
                             pGDI->Synth.IsOpl3,
                             pGDI->WaveInfo.DMABuf.BufferSize);

    if (!NT_SUCCESS(Status)) {
        return Status;
    }

    /*
    **  Finally test the PRO interrupt
    */

    if (SBPRO(&pGDI->Hw)) {
        BOOLEAN Ok;

        SoundEnter(pGDI->DeviceObject[WaveOutDevice]->DeviceExtension,
                   TRUE);
        Ok = 0 == SoundTestWaveDevice(pGDI->DeviceObject[WaveOutDevice]);
        SoundEnter(pGDI->DeviceObject[WaveOutDevice]->DeviceExtension,
                   FALSE);
        if (!Ok) {
            pGDI->LoadStatus = SOUND_CONFIG_BADDMA;
            return STATUS_DEVICE_CONFIGURATION_ERROR;
        }
    }

    /*
    ** Exit OK Message
    */

    pGDI->LoadStatus = SOUND_CONFIG_OK;

    return STATUS_SUCCESS;

}
Exemplo n.º 17
0
/*****************************************************************************

Routine Description :

    Saves the drivers configuration information for our device

Arguments :

    Registry Key values

Return Value :

    NT status code - STATUS_SUCCESS if no problems

*****************************************************************************/
NTSTATUS    SoundSaveConfig( IN  PWSTR DeviceKey,
                          IN  ULONG Port,
                          IN  ULONG DmaChannel,
                          IN  ULONG Interrupt,
                          IN  ULONG InputSource )
{
        /***** Local Variables *****/

    NTSTATUS Status;

                /***** Start *****/

    dprintf4(("SoundSaveConfig(): Start"));

    //
    // Port
    //
    Status = SoundWriteRegistryDWORD( DeviceKey,
                                     SOUND_REG_PORT,
                                     Port );

    if (!NT_SUCCESS(Status))
        {
        return Status;
        }

    //
    // DmaChannel
    //
    Status = SoundWriteRegistryDWORD( DeviceKey,
                                     SOUND_REG_DMACHANNEL,
                                     DmaChannel );

    if (!NT_SUCCESS(Status))
        {
        return Status;
        }

    //
    // Interrupt
    //
    Status = SoundWriteRegistryDWORD( DeviceKey,
                                     SOUND_REG_INTERRUPT,
                                     Interrupt );

    if (!NT_SUCCESS(Status))
        {
        return Status;
        }

    //
    // Input Source
    //
    Status = SoundWriteRegistryDWORD( DeviceKey,
                                     SOUND_REG_INPUTSOURCE,
                                     InputSource );

    if (!NT_SUCCESS(Status))
        {
        return Status;
        }

    //
    // Make sure the config routine sees the data
    //


    return STATUS_SUCCESS;
}           // End SoundSaveConfig()
Exemplo n.º 18
0
int search_bd_buf(char *buf, int len_bytes, unsigned long bd_offset_bytes,
		int *nr_populated_bdes)
{
	unsigned long i;
	int total_entries = 0;

	dprintf3("%s(%p, %x, %lx, ...) buf end: %p\n", __func__, buf,
			len_bytes, bd_offset_bytes, buf + len_bytes);

	for (i = 0; i < len_bytes; i += sizeof(unsigned long)) {
		unsigned long bd_index = (bd_offset_bytes + i) / sizeof(unsigned long);
		unsigned long *bounds_dir_entry_ptr = (unsigned long *)&buf[i];
		unsigned long bounds_dir_entry;
		unsigned long bd_for_vaddr;
		unsigned long bt_start;
		unsigned long bt_tail;
		int nr_entries;

		dprintf4("%s() loop i: %ld bounds_dir_entry_ptr: %p\n", __func__, i,
				bounds_dir_entry_ptr);

		bounds_dir_entry = *bounds_dir_entry_ptr;
		if (!bounds_dir_entry) {
			dprintf4("no bounds dir at index 0x%lx / 0x%lx "
				 "start at offset:%lx %lx\n", bd_index, bd_index,
					bd_offset_bytes, i);
			continue;
		}
		dprintf3("found bounds_dir_entry: 0x%lx @ "
			 "index 0x%lx buf ptr: %p\n", bounds_dir_entry, i,
					&buf[i]);
		/* mask off the enable bit: */
		bounds_dir_entry &= ~0x1;
		(*nr_populated_bdes)++;
		dprintf4("nr_populated_bdes: %p\n", nr_populated_bdes);
		dprintf4("*nr_populated_bdes: %d\n", *nr_populated_bdes);

		bt_start = bounds_dir_entry;
		bt_tail = bounds_dir_entry + MPX_BOUNDS_TABLE_SIZE_BYTES - 1;
		if (!vaddr_mapped_by_range(bt_start)) {
			printf("bounds directory 0x%lx points to nowhere\n",
					bounds_dir_entry);
			mpx_dig_abort();
		}
		if (!vaddr_mapped_by_range(bt_tail)) {
			printf("bounds directory end 0x%lx points to nowhere\n",
					bt_tail);
			mpx_dig_abort();
		}
		/*
		 * Each bounds directory entry controls 1MB of virtual address
		 * space.  This variable is the virtual address in the process
		 * of the beginning of the area controlled by this bounds_dir.
		 */
		bd_for_vaddr = bd_index * (1UL<<20);

		nr_entries = dump_table(bounds_dir_entry, bd_for_vaddr,
				bounds_dir_global+bd_offset_bytes+i);
		total_entries += nr_entries;
		dprintf5("dir entry[%4ld @ %p]: 0x%lx %6d entries "
			 "total this buf: %7d bd_for_vaddrs: 0x%lx -> 0x%lx\n",
				bd_index, buf+i,
				bounds_dir_entry, nr_entries, total_entries,
				bd_for_vaddr, bd_for_vaddr + (1UL<<20));
	}
	dprintf3("%s(%p, %x, %lx, ...) done\n", __func__, buf, len_bytes,
			bd_offset_bytes);
	return total_entries;
}
Exemplo n.º 19
0
int dump_table(unsigned long table_vaddr, unsigned long base_controlled_vaddr,
		unsigned long bde_vaddr)
{
	unsigned long offset_inside_bt;
	int nr_entries = 0;
	int do_abort = 0;
	char *bt_buf;

	dprintf3("%s() base_controlled_vaddr: 0x%012lx bde_vaddr: 0x%012lx\n",
			__func__, base_controlled_vaddr, bde_vaddr);

	bt_buf = read_bounds_table_into_buf(table_vaddr);

	dprintf4("%s() read done\n", __func__);

	for (offset_inside_bt = 0;
	     offset_inside_bt < MPX_BOUNDS_TABLE_SIZE_BYTES;
	     offset_inside_bt += bt_entry_size_bytes) {
		unsigned long bt_entry_index;
		unsigned long bt_entry_controls;
		unsigned long this_bt_entry_for_vaddr;
		unsigned long *bt_entry_buf;
		int i;

		dprintf4("%s() offset_inside_bt: 0x%lx of 0x%llx\n", __func__,
			offset_inside_bt, MPX_BOUNDS_TABLE_SIZE_BYTES);
		bt_entry_buf = (void *)&bt_buf[offset_inside_bt];
		if (!bt_buf) {
			printf("null bt_buf\n");
			mpx_dig_abort();
		}
		if (!bt_entry_buf) {
			printf("null bt_entry_buf\n");
			mpx_dig_abort();
		}
		dprintf4("%s() reading *bt_entry_buf @ %p\n", __func__,
				bt_entry_buf);
		if (!bt_entry_buf[0] &&
		    !bt_entry_buf[1] &&
		    !bt_entry_buf[2] &&
		    !bt_entry_buf[3])
			continue;

		nr_entries++;

		bt_entry_index = offset_inside_bt/bt_entry_size_bytes;
		bt_entry_controls = sizeof(void *);
		this_bt_entry_for_vaddr =
			base_controlled_vaddr + bt_entry_index*bt_entry_controls;
		/*
		 * We sign extend vaddr bits 48->63 which effectively
		 * creates a hole in the virtual address space.
		 * This calculation corrects for the hole.
		 */
		if (this_bt_entry_for_vaddr > 0x00007fffffffffffUL)
			this_bt_entry_for_vaddr |= 0xffff800000000000;

		if (!vaddr_mapped_by_range(this_bt_entry_for_vaddr)) {
			printf("bt_entry_buf: %p\n", bt_entry_buf);
			printf("there is a bte for %lx but no mapping\n",
					this_bt_entry_for_vaddr);
			printf("	  bde   vaddr: %016lx\n", bde_vaddr);
			printf("base_controlled_vaddr: %016lx\n", base_controlled_vaddr);
			printf("	  table_vaddr: %016lx\n", table_vaddr);
			printf("	  entry vaddr: %016lx @ offset %lx\n",
				table_vaddr + offset_inside_bt, offset_inside_bt);
			do_abort = 1;
			mpx_dig_abort();
		}
		if (DEBUG_LEVEL < 4)
			continue;

		printf("table entry[%lx]: ", offset_inside_bt);
		for (i = 0; i < bt_entry_size_bytes; i += sizeof(unsigned long))
			printf("0x%016lx ", bt_entry_buf[i]);
		printf("\n");
	}
	if (do_abort)
		mpx_dig_abort();
	dprintf4("%s() done\n",  __func__);
	return nr_entries;
}
Exemplo n.º 20
0
int
main(int argc, const char *argv[])
{
    char achar = '0';
    gs_memory_t *mem;

    gs_state *pgs;
    const gx_device *const *list;
    gx_device *dev;
    gx_device_bbox *bbdev;
    int code;

    gp_init();
    mem = gs_malloc_init();
    gs_lib_init1(mem);
    if (argc < 2 || (achar = argv[1][0]) < '1' ||
        achar > '0' + countof(tests) - 1
        ) {
        lprintf1("Usage: gslib 1..%c\n", '0' + (char)countof(tests) - 1);
        gs_abort(mem);
    }
    gs_debug['@'] = 1;
    gs_debug['?'] = 1;
/*gs_debug['B'] = 1; *//****** PATCH ******/
/*gs_debug['L'] = 1; *//****** PATCH ******/
    /*
     * gs_iodev_init must be called after the rest of the inits, for
     * obscure reasons that really should be documented!
     */
    gs_iodev_init(mem);
/****** WRONG ******/
    gs_lib_device_list(&list, NULL);
    gs_copydevice(&dev, list[0], mem);
    check_device_separable(dev);
    gx_device_fill_in_procs(dev);
    bbdev =
        gs_alloc_struct_immovable(mem, gx_device_bbox, &st_device_bbox,
                                  "bbox");
    gx_device_bbox_init(bbdev, dev, mem);

    code = dev_proc(dev, get_profile)(dev, &bbdev->icc_struct);
    rc_increment(bbdev->icc_struct);

    /* Print out the device name just to test the gsparam.c API. */
    {
        gs_c_param_list list;
        gs_param_string nstr;

        gs_c_param_list_write(&list, mem);
        code = gs_getdeviceparams(dev, (gs_param_list *) & list);
        if (code < 0) {
            lprintf1("getdeviceparams failed! code = %d\n", code);
            gs_abort(mem);
        }
        gs_c_param_list_read(&list);
        code = param_read_string((gs_param_list *) & list, "Name", &nstr);
        if (code < 0) {
            lprintf1("reading Name failed! code = %d\n", code);
            gs_abort(mem);
        }
        dputs("Device name = ");
        debug_print_string(nstr.data, nstr.size);
        dputs("\n");
        gs_c_param_list_release(&list);
    }
    /*
     * If this is a device that takes an OutputFile, set the OutputFile
     * to "-" in the copy.
     */
    {
        gs_c_param_list list;
        gs_param_string nstr;

        gs_c_param_list_write(&list, mem);
        param_string_from_string(nstr, "-");
        code = param_write_string((gs_param_list *)&list, "OutputFile", &nstr);
        if (code < 0) {
            lprintf1("writing OutputFile failed! code = %d\n", code);
            gs_abort(mem);
        }
        gs_c_param_list_read(&list);
        code = gs_putdeviceparams(dev, (gs_param_list *)&list);
        gs_c_param_list_release(&list);
        if (code < 0 && code != gs_error_undefined) {
            lprintf1("putdeviceparams failed! code = %d\n", code);
            gs_abort(mem);
        }
    }
    dev = (gx_device *) bbdev;
    pgs = gs_state_alloc(mem);
    gs_setdevice_no_erase(pgs, dev);	/* can't erase yet */
    {
        gs_point dpi;
        gs_screen_halftone ht;

        gs_dtransform(pgs, 72.0, 72.0, &dpi);
        ht.frequency = min(fabs(dpi.x), fabs(dpi.y)) / 16.001;
        ht.angle = 0;
        ht.spot_function = odsf;
        gs_setscreen(pgs, &ht);
    }
    /* gsave and grestore (among other places) assume that */
    /* there are at least 2 gstates on the graphics stack. */
    /* Ensure that now. */
    gs_gsave(pgs);
    gs_erasepage(pgs);

    code = (*tests[achar - '1']) (pgs, mem);
    gs_output_page(pgs, 1, 1);
    {
        gs_rect bbox;

        gx_device_bbox_bbox(bbdev, &bbox);
        dprintf4("Bounding box: [%g %g %g %g]\n",
                 bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y);
    }
    if (code)
        dprintf1("**** Test returned code = %d.\n", code);
    dputs("Done.  Press <enter> to exit.");
    fgetc(mem->gs_lib_ctx->fstdin);
    gs_lib_finit(0, 0, mem);
    return 0;
#undef mem
}
Exemplo n.º 21
0
/*****************************************************************************

    SoundInitHardwareConfig()

*****************************************************************************/
NTSTATUS    SoundInitHardwareConfig( IN OUT PGLOBAL_DEVICE_INFO pGDI,
                                  IN     PPAS_CONFIG_DATA ConfigData )
{
        /***** Local Variables *****/

    NTSTATUS        Status;

                /***** Start *****/

    dprintf4(("SoundInitHardwareConfig(): Start"));

    //
    // Check the input source
    //
    if ( ConfigData->InputSource > INPUT_OUTPUT)
        {
        dprintf1(("ERROR: SoundInitHardwareConfig(): Invalid Input Source = %u",
                                            ConfigData->InputSource));
        return STATUS_DEVICE_CONFIGURATION_ERROR;
        }

    pGDI->Hw.InputSource = (UCHAR) ConfigData->InputSource;

    //
    // Find the Base Port and Wake up the PAS Hardware
    //
    Status = SoundInitIoPort( pGDI,
                             ConfigData );

    if (!NT_SUCCESS(Status))
        {
        dprintf1(("ERROR: SoundInitHardwareConfig(): SoundInitIoPort() Failed with Status = %u",
                                            Status));

        SoundWriteRegistryDWORD( pGDI->RegistryPathName,
                               REG_VALUENAME_DRIVER_STATUS,
                               ERROR_NO_HW_FOUND );

        return Status;
        }           // End IF (!NT_SUCCESS(Status))

    //
    // Find interrupt
    //
    Status = SoundInitInterrupt( pGDI,
                               &ConfigData->InterruptNumber );

    if (!NT_SUCCESS(Status))
        {
        dprintf1(("ERROR: SoundInitHardwareConfig(): SoundInitInterrupt() Failed with Status = %u",
                                            Status));
        SoundWriteRegistryDWORD( pGDI->RegistryPathName,
                               REG_VALUENAME_DRIVER_STATUS,
                               ERROR_INT_CONFLICT );
        return Status;
        }           // End IF (!NT_SUCCESS(Status))

    //
    // Find DMA channel
    //
    Status = SoundInitDmaChannel( pGDI,
                                &ConfigData->DmaChannel,
                                 ConfigData->DmaBufferSize);

    if (!NT_SUCCESS(Status))
        {
        dprintf1(("ERROR: SoundInitHardwareConfig(): SoundInitDmaChannel() Failed with Status = %u",
                                            Status));
        SoundWriteRegistryDWORD( pGDI->RegistryPathName,
                               REG_VALUENAME_DRIVER_STATUS,
                               ERROR_DMA_CONFLICT );
        return Status;
        }           // End IF (!NT_SUCCESS(Status))

    //
    // Initialize the ProAudio hardware registers
    //
    HwInitPAS( pGDI );

    return STATUS_SUCCESS;

}           // End SoundInitHardwareConfig()
Exemplo n.º 22
0
VOID
SoundInDeferred(
    IN    PKDPC pDpc,
    IN OUT PDEVICE_OBJECT pDeviceObject,
    IN    PIRP pIrp,
    IN    PVOID Context
)
/*++

Routine Description:

    Dpc routine for wave input device

    Collect the data from the DMA buffer and pass it to the application's
    buffer(s).

Arguments:


Return Value:

    None.

--*/
{
    PLOCAL_DEVICE_INFO pLDI;
    PGLOBAL_DEVICE_INFO pGDI;

    pLDI = (PLOCAL_DEVICE_INFO)pDeviceObject->DeviceExtension;
    pGDI = pLDI->pGlobalInfo;

    //
    // Acquire the spin lock before we mess with the list
    //

    GlobalEnter(pGDI);

    //
    // Fill in any buffers we can
    //

    dprintf4(pGDI->NextHalf == LowerHalf ? "dpc():L" : "dpc():U");


    //
    // Zero bytes taken out of new buffer
    //

    if( pGDI->DMABuffer[pGDI->NextHalf].nBytes == DMA_BUFFER_SIZE / 2)
	pGDI->DMABuffer[pGDI->NextHalf].nBytes = 0;

    //
    // Request input without posting the last buffer
    //

    sndFlush(pGDI, pGDI->NextHalf);
    sndFillInputBuffers(pLDI, pGDI->NextHalf);

    //
    // Restart this buffer's DMA
    //
    sndReStartDMA(pGDI, pGDI->NextHalf);

    //
    // Move on to next half
    //
    pGDI->NextHalf = UpperHalf + LowerHalf - pGDI->NextHalf;

    //
    // Release the spin lock
    //

    GlobalLeave(pGDI);

    return;

    DBG_UNREFERENCED_PARAMETER(pDpc);
    DBG_UNREFERENCED_PARAMETER(Context);
    DBG_UNREFERENCED_PARAMETER(pIrp);
}
Exemplo n.º 23
0
VOID
sndFillInputBuffers(
    PLOCAL_DEVICE_INFO pLDI,
    DMA_BUFFER_NEXT_HALF Half
)
/*++

Routine Description:

    Send input to client

    Take the data from the last recorded position in the DMA
    buffer.  The length of the data is passed in.  Try to
    insert it into the caller's buffers.  Note that the client gets
    no notification if the data is truncated.

Arguments:

    pLDI - pointer to our local device info
    Half - which half of the DMA buffer to get input data from

Return Value:

    None

--*/

{
    PUCHAR pData;
    ULONG BytesTransferred;
    PGLOBAL_DEVICE_INFO pGDI;

    pGDI = pLDI->pGlobalInfo;
    ASSERT(pGDI->Key == GDI_KEY);


    //
    // Get last recorded position
    //

    pData = pGDI->DMABuffer[Half].Buf;

    BytesTransferred = pGDI->DMABuffer[Half].nBytes;

    //
    // Make sure we get the right data
    // (NOTE - not sure this is necessary as this code will only
    //  ever run on Ix86 ?).
    // IoFlushAdapterBuffers(pLDI->pGlobalInfo->pAdapterObject);

    //
    // While there is data and somewhere to put it
    //

    while (BytesTransferred < DMA_BUFFER_SIZE / 2) {

        ULONG BytesToCopy;

        //
        // We might have completed the last buffer
        // Note that we cope with 0 length buffers here
        //

        if (pGDI->pUserBuffer == NULL) {

            sndGetNextBuffer(pLDI);

            if (pGDI->pUserBuffer == NULL) {

                //
                // There REALLY aren't any buffers
                //

                break;
            }
        }

        //
        // Find out how much space we have left in the
        // client's buffers
        // Note that BytesToCopy may be 0 - this is OK
        //


        BytesToCopy =
            min(pGDI->UserBufferSize - pGDI->UserBufferPosition,
                DMA_BUFFER_SIZE / 2 - BytesTransferred);

        //
        // Copy the data
        //

        RtlMoveMemory(pGDI->pUserBuffer + pGDI->UserBufferPosition,
                      pData + BytesTransferred,
                      BytesToCopy);

        //
        // Update counters etc.
        //

        pGDI->UserBufferPosition += BytesToCopy;
        BytesTransferred += BytesToCopy;


        //
        // Update our total of bytes
        //

        pLDI->SampleNumber += BytesToCopy;


        //
        // See if we've now filled a user buffer
        //

        if (pGDI->UserBufferPosition == pGDI->UserBufferSize) {

	    dprintf4(" finished");

	    //
	    // Unmap the users buffer and set data length
	    //

            sndCompleteIoBuffer(pGDI);

            //
            // Mark request as complete
            //

            pGDI->pIrp->IoStatus.Status = STATUS_SUCCESS;
            IoCompleteRequest(pGDI->pIrp, IO_SOUND_INCREMENT);
        }

    }

    pGDI->DMABuffer[Half].nBytes = BytesTransferred;

}
Exemplo n.º 24
0
BOOLEAN
SoundInitiate (
    IN PVOID Context
    )

/*++

Routine Description:

    This routine initiates DMA transfers and is synchronized with the controller
    interrupt.

Arguments:

    Context -  Supplies pointer to global device info.

Return Value:

    Returns FALSE

--*/

{
    PGLOBAL_DEVICE_INFO pGDI;
    UCHAR regval, dfmtval;
    PSOUND_REGISTERS pSoundRegisters;
    ULONG ChangedShadowRegisters=0, tempdfmtval;


    pGDI = (PGLOBAL_DEVICE_INFO)Context;

    pSoundRegisters = pGDI->SoundHardware.SoundVirtualBase;

    dprintf4("SoundInitiate()");

    //
    // Disable Playback and Recording.
    //

    regval =  READAUDIO_DMACNTRL(&pSoundRegisters);
    WRITEAUDIO_DMACNTRL(&pSoundRegisters, (regval & ~(REC_ENABLE|PLAY_ENABLE)));


    //
    // Clear any outstanding interrupts.
    //

    regval = READAUDIO_CONFIG(&pSoundRegisters);
    WRITEAUDIO_CONFIG(&pSoundRegisters, (regval & ~(REC_OVF_INTR|PLAY_UND_INTR)));

    regval = READAUDIO_ENDIAN(&pSoundRegisters);
    WRITEAUDIO_ENDIAN(&pSoundRegisters, (regval & ~DMA_TCINTR));

    regval = READAUDIO_CONFIG(&pSoundRegisters);

    //
    // Do NOT set Data Format Register to stereo.
    // Use Config Register for it.
    //

    if (pGDI->Usage == SoundInterruptUsageWaveIn) {

        //
        // We are Recording
        //

	regval &= ~REC_XLATION;

        if (pGDI->Channels == 1) {
            if (pGDI->BytesPerSample == 1) {
		regval |= (MONO_8BIT << REC_XLATION_SHIFT);
            } else {
		regval |= (MONO_16BIT << REC_XLATION_SHIFT);
            }
        } else {
            if (pGDI->BytesPerSample == 1) {
		regval |= (STEREO_8BIT << REC_XLATION_SHIFT);
            } else {
		regval |= (STEREO_16BIT << REC_XLATION_SHIFT);
            }
        }

    } else {

        // We are Playing

	regval &= ~PLAY_XLATION;

        if (pGDI->Channels == 1) {
            if (pGDI->BytesPerSample == 1) {
		regval |= (MONO_8BIT << PLAY_XLATION_SHIFT);
            } else {
		regval |= (MONO_16BIT << PLAY_XLATION_SHIFT);
            }
        } else {
            if (pGDI->BytesPerSample == 1) {
		regval |= (STEREO_8BIT << PLAY_XLATION_SHIFT);
            } else {
		regval |= (STEREO_16BIT << PLAY_XLATION_SHIFT);
            }
        }
    }

    //
    // Set the correct data size to enable/disable 2's comple calculation
    // Set Play and Record to the same data size (board requirement)
    //

    if (pGDI->BytesPerSample == 1) {
	regval |= (REC_8WAVE_ENABLE|PLAY_8WAVE_ENABLE);
    } else {
	regval &= ~(REC_8WAVE_ENABLE|PLAY_8WAVE_ENABLE);
    }

    WRITEAUDIO_CONFIG(&pSoundRegisters, regval);


    //
    // There are Two shadow registers SCNTRL and DATAFMT.
    // If any of them is changed then go into control mode
    // and shift them out to CODEC.
    //

    regval = READAUDIO_SCNTRL(&pSoundRegisters);


    // Always keep the CODEC in 16 bit linear stereo mode
    // That is already done by init.c
    // Take care when changing DATAFMTVAL

    dfmtval = READAUDIO_DATAFMT(&pSoundRegisters);
    tempdfmtval = dfmtval & DATA_CONVERSION_FREQ;

    if (pGDI->SamplesPerSec == 11025) {
        if ((regval & CLKSRC_11KHZ) != CLKSRC_11KHZ){
            ChangedShadowRegisters = 1;
            regval &= ~CLOCK_SOURCE_SELECT;
            regval |= CLKSRC_11KHZ;
        }
        if (tempdfmtval != CONFREQ_11KHZ){
            ChangedShadowRegisters = 1;
            dfmtval &= ~DATA_CONVERSION_FREQ;
            dfmtval |= CONFREQ_11KHZ;
        }
    }

    if (pGDI->SamplesPerSec == 22050) {
        if ((regval & CLKSRC_22KHZ) != CLKSRC_22KHZ){
            ChangedShadowRegisters = 1;
            regval &= ~CLOCK_SOURCE_SELECT;
            regval |= CLKSRC_22KHZ;
        }
        if (tempdfmtval != CONFREQ_22KHZ){
            ChangedShadowRegisters = 1;
            dfmtval &= ~DATA_CONVERSION_FREQ;
            dfmtval |= CONFREQ_22KHZ;
        }
    }

    if (pGDI->SamplesPerSec == 44100) {
        if ((regval & CLKSRC_44KHZ) != CLKSRC_44KHZ){
            ChangedShadowRegisters = 1;
            regval &= ~CLOCK_SOURCE_SELECT;
            regval |= CLKSRC_44KHZ;
        }
        if (tempdfmtval != CONFREQ_44KHZ){
            ChangedShadowRegisters = 1;
            dfmtval &= ~DATA_CONVERSION_FREQ;
            dfmtval |= CONFREQ_44KHZ;
        }
    }

    if (pGDI->SamplesPerSec == 8000) {
        if ((regval & CLKSRC_8KHZ) != CLKSRC_8KHZ){
            ChangedShadowRegisters = 1;
            regval &= ~CLOCK_SOURCE_SELECT;
            regval |= CLKSRC_8KHZ;
        }
        if (tempdfmtval != CONFREQ_8KHZ){
            ChangedShadowRegisters = 1;
            dfmtval &= ~DATA_CONVERSION_FREQ;
            dfmtval |= CONFREQ_8KHZ;
        }
    }

    if (ChangedShadowRegisters) {

	// Whenever the CODEC is taken from data mode (normal mode
	// to control mode there is a slight click on the outside.
	// Here we try to avoid the clicks by using sndMute()
	// and sndSetOutputVolume()

	sndMute( pGDI );

        WRITEAUDIO_SCNTRL(&pSoundRegisters, regval);
        WRITEAUDIO_DATAFMT(&pSoundRegisters, dfmtval);

        //
        // Shift out the above shadow registers to the CODEC
        //

        sndSetControlRegisters(pGDI);

	// Dont set volume here because MIPS_TAIL_BUG will set it for you

    }


    //
    // Set the NON-shadow registers now (after the above routine call).
    //

    regval = READAUDIO_DMACNTRL(&pSoundRegisters);

    if (pGDI->Usage == SoundInterruptUsageWaveIn) {

        //
        // We are Recording
        //
        regval &= ~REC_CHANNEL_IN_USE;
        regval |= (CH4_IN_USE << REC_CHANNEL_SHIFT);

    } else {

        //
        // We are Playing
        //

        regval &= ~PLAY_CHANNEL_IN_USE;
        regval |= (CH2_IN_USE << PLAY_CHANNEL_SHIFT);

    }

    WRITEAUDIO_DMACNTRL(&pSoundRegisters, regval);

    //
    // Finally start Recording or Playing
    //

    regval = READAUDIO_DMACNTRL(&pSoundRegisters);

    if (pGDI->Usage == SoundInterruptUsageWaveIn) {

        //
        // Set the monitor attenuation to 0 so that the input can be heard
        //

        // rightInputVal = READAUDIO_RICNTRL(&pSoundRegisters);
        // rightInputVal &= ~MON_ATTN_MASK;
        // WRITEAUDIO_RICNTRL(&pSoundRegisters, rightInputVal );

        // Start the actual DMA transfers
        WRITEAUDIO_DMACNTRL(&pSoundRegisters, (regval | REC_ENABLE));

    } else {

        WRITEAUDIO_DMACNTRL(&pSoundRegisters, (regval | PLAY_ENABLE));

#ifdef MIPSSND_TAIL_BUG

    //
    // Since we are ready to play turn on the headphone and lineout
    //
    sndSetOutputVolume(pGDI);

    // If we had turned off the headphone to mute then turn it on.
    // Mute using volume "sounds" better.
    //sndHeadphoneControl(pGDI, ON);
    //sndLineoutControl(pGDI, ON);

#endif // MIPSSND_TAIL_BUG

    }

    return FALSE;
}
Exemplo n.º 25
0
IO_ALLOCATION_ACTION
sndProgramDMA(
    IN    PDEVICE_OBJECT pDO,
    IN    PIRP pIrp,
    IN    PVOID pMRB,
    IN    PVOID Context
)
/*++

Routine Description:

    This routine is executed when an adapter channel is allocated
    for our DMA needs.

Arguments:

    pDO     - Device object
    pIrp    - IO request packet
    pMRB    -
    Context - Which buffer are we using


Return Value:

    Tell the system what to do with the adapter object

--*/
{
    PGLOBAL_DEVICE_INFO pGDI;
    int WhichBuffer;

    UNREFERENCED_PARAMETER(pIrp);

    WhichBuffer = (int) Context;

    pGDI = ((PLOCAL_DEVICE_INFO)pDO->DeviceExtension)->pGlobalInfo;

    pGDI->pMRB[WhichBuffer] = pMRB;

    sndReStartDMA(pGDI, WhichBuffer);

    //
    // return a value that says we want to keep the channel
    // and map registers.
    //

    if (WhichBuffer == 0) {

        //
        // Do the other one.
        //


        if (pGDI->Usage == SoundInterruptUsageWaveIn) {

            dprintf4("Allocating adapter channel (buffer = 3)");
            IoAllocateAdapterChannel(pGDI->pAdapterObject[3],
                pGDI->pWaveInDevObj,
                BYTES_TO_PAGES(pGDI->DmaHalfBufferSize),
                sndProgramDMA,
                (PVOID)1);              // next buffer


        } else {

            dprintf4("Allocating adapter channel (buffer = 1)");
            IoAllocateAdapterChannel(pGDI->pAdapterObject[1],
                pGDI->pWaveOutDevObj,
                BYTES_TO_PAGES(pGDI->DmaHalfBufferSize),
                sndProgramDMA,
                (PVOID)1);              // next buffer
        }

        //
        // Execution will continue in sndProgramDMA when the
        // adapter has been allocated (AGAIN)
        //

    } else {

        //
        // Now program the hardware on the card to begin the transfer.
        // Note that this must be synchronized with the isr
        //

        dprintf4("Calling (sync) sndInitiate");
        KeSynchronizeExecution(pGDI->pInterrupt,
                               pGDI->StartDMA,
                               pGDI);

        //
        // Execution continues in the SoundInitiate routine
        //
    }

    return KeepObject;
}
Exemplo n.º 26
0
VOID
sndStartDMA(
    IN    PGLOBAL_DEVICE_INFO pGDI,
    IN    int PlayBack
)
/*++

Routine Description:

    Allocate the adapter channel (this had better not wait !)

Arguments:

    pGDI - Pointer to the global device data

Return Value:

    None

--*/
{
    ULONG DataLong;

    //
    // Test if DMA is already running
    //

    ASSERT(pGDI->DMABusy == FALSE);

    pGDI->DMABusy = TRUE;


    dprintf5("sndStartDMA()");

    //
    // Program the DMA hardware (isn't this a bit illegal ?)
    //

    DataLong = 0;

    ((PDMA_CHANNEL_MODE)(&DataLong))->AccessTime = ACCESS_200NS;

    if (pGDI->BytesPerSample == 1) {
        ((PDMA_CHANNEL_MODE)(&DataLong))->TransferWidth = WIDTH_8BITS;
    } else {
        ((PDMA_CHANNEL_MODE)(&DataLong))->TransferWidth = WIDTH_16BITS;
    }


    if (PlayBack){

        ((PDMA_CHANNEL_MODE)(&DataLong))->BurstMode = 0x01;

        WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_A].Mode.Long,
                         DataLong);
        WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_B].Mode.Long,
                         DataLong);

    } else {

        WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_A+2].Mode.Long,
                         DataLong);
        WRITE_REGISTER_ULONG(&DMA_CONTROL->Channel[SOUND_CHANNEL_B+2].Mode.Long,
                         DataLong);

    }

    //
    // Allocate an adapter channel.  When the system allocates
    // the channel, processing will continue in the sndProgramDMA
    // routine below.
    //


    if (PlayBack) {
        dprintf4("Allocating adapter channel (buffer = 0)");
        IoAllocateAdapterChannel(pGDI->pAdapterObject[0],
                             pGDI->pWaveOutDevObj,
                             BYTES_TO_PAGES(pGDI->DmaHalfBufferSize),
                             sndProgramDMA,
                             (PVOID)0);         // Context
    } else {
        dprintf4("Allocating adapter channel (buffer = 2)");
        IoAllocateAdapterChannel(pGDI->pAdapterObject[2],
                             pGDI->pWaveInDevObj,
                             BYTES_TO_PAGES(pGDI->DmaHalfBufferSize),
                             sndProgramDMA,
                             (PVOID)0);         // Context
    }

    //
    // Execution will continue in sndProgramDMA when the
    // adapter has been allocated
    //

}
Exemplo n.º 27
0
NTSTATUS
SoundConnectInterrupt(
    IN ULONG InterruptNumber,
    IN INTERFACE_TYPE BusType,
    IN ULONG BusNumber,
    IN PKSERVICE_ROUTINE Isr,
    IN PVOID ServiceContext,
    IN KINTERRUPT_MODE InterruptMode,
    IN BOOLEAN ShareVector,
    OUT PKINTERRUPT *Interrupt
)
/*++

Routine Description :

    Connect to an interrupt.  From this point on our interrupt service
    routine can receive interrupts

    We assume that floating point arithmetic will not be used in the
    service routine.

Arguments :

    InterruptNumber - the interrupt number we're using
    BusType - Our bus type
    BusNumber - the number of our buse (of type BusType)
    Isr - the interrupt service routine
    ServiceContext - a value passed to the interrupt service routine
    InterruptMode - whether it's latched or level sensitive
    ShareVector - whether the interrupt can be shared
    Interrupt - Returns the pointer to the interrupt object

Return Value :

    An NTSTATUS return value - STATUS_SUCCESS if OK.

--*/
{
    KAFFINITY Affinity;
    KIRQL InterruptRequestLevel;
    ULONG InterruptVector;
    NTSTATUS Status;

    //
    // Call HalGetInterruptVector to get the interrupt vector,
    // processor affinity and  request level to pass to IoConnectInterrupt
    //	
	
	//dprintf2(("BusType = %x", BusType));
	//dprintf2(("BusNumber = %d",BusNumber));
	//dprintf2(("InterruptNumber = %d", InterruptNumber));

	dprintf4(("HalGetInterruptVector()2: BusType             = %d", BusType));
	dprintf4(("HalGetInterruptVector()2: BusNumber           = %d", BusNumber));
    dprintf4(("HalGetInterruptVector()2: InterruptLevel      = %d", INTERRUPT_LEVEL));
    dprintf4(("HalGetInterruptVector()2: InterruptNumber     = %d", InterruptNumber));
		

    InterruptVector = HalGetInterruptVector(BusType,
                                            BusNumber,
                                            INTERRUPT_LEVEL,	// Interrupt Level
                                            InterruptNumber,	// Interrupt Vector
                                            &InterruptRequestLevel,
                                            &Affinity);
	
	dprintf4(("IoConnectInterrupt(): ServiceRoutine  = %8x", Isr));
    dprintf4(("IoConnectInterrupt(): ServicContext   = %8x", ServiceContext));
    dprintf4(("IoConnectInterrupt(): SpinLock        = NULL"));
	dprintf4(("IoConnectInterrupt(): InterruptVector = %d", InterruptVector));
	dprintf4(("IoConnectInterrupt(): InterruptReqLvl = %d", InterruptRequestLevel));
	dprintf4(("IoConnectInterrupt(): SyncronizedIRQL = %d", InterruptRequestLevel));
	dprintf4(("IoConnectInterrupt(): InterruptMode   = %d", InterruptMode));
	dprintf4(("IoConnectInterrupt(): ShareVector     = %d", ShareVector));
	dprintf4(("IoConnectInterrupt(): ProcessorMask   = %d", Affinity));
	dprintf4(("IoConnectInterrupt(): FloatingSave    = %d", FALSE));

      
    Status = IoConnectInterrupt(
                   Interrupt,
                   Isr,
                   ServiceContext,
                   (PKSPIN_LOCK)NULL,
                   InterruptVector,
                   InterruptRequestLevel,
                   InterruptRequestLevel,
                   InterruptMode,
                   ShareVector,
                   Affinity,
                   FALSE                      // No floating point save
                   );

	dprintf4(("IoConnectInterrupt(): Status =%8x",Status));

    return Status == STATUS_INVALID_PARAMETER ?
                       STATUS_DEVICE_CONFIGURATION_ERROR : Status;
}
Exemplo n.º 28
0
/*****************************************************************************

Routine Description :

    Return configuration information for our device

Arguments :

    ConfigData - where to store the result

Return Value :

    NT status code - STATUS_SUCCESS if no problems

*****************************************************************************/
NTSTATUS    SoundReadConfiguration( IN  PWSTR ValueName,
                                 IN  ULONG ValueType,
                                 IN  PVOID ValueData,
                                 IN  ULONG ValueLength,
                                 IN  PVOID Context,
                                 IN  PVOID EntryContext )
{
        /***** Local Variables *****/

    PPAS_CONFIG_DATA    ConfigData;

                /***** Start *****/

    dprintf4(("SoundReadConfiguration(): Start"));

    ConfigData = Context;

    if ( ValueType == REG_DWORD )
        {
        // Base I/O Port
        if ( _wcsicmp(ValueName, SOUND_REG_PORT)  == 0 )
            {
            ConfigData->Port = *(PULONG)ValueData;
            dprintf3((" SoundReadConfiguration(): Read Port Base       = %XH",
                                                 ConfigData->Port));
            }

        // Interrupt
        else if ( _wcsicmp(ValueName, SOUND_REG_INTERRUPT)  == 0 )
            {
            ConfigData->InterruptNumber = *(PULONG)ValueData;
            dprintf3((" SoundReadConfiguration(): Read Interrupt       = %u",
                                                 ConfigData->InterruptNumber));
            }

        // DMA Channel
        else if ( _wcsicmp(ValueName, SOUND_REG_DMACHANNEL)  == 0 )
            {
            ConfigData->DmaChannel = *(PULONG)ValueData;
            dprintf3((" SoundReadConfiguration(): Read DMA Channel     = %u",
                                                 ConfigData->DmaChannel));
            }

        // DMA Buffer Size
        else if ( _wcsicmp(ValueName, SOUND_REG_DMABUFFERSIZE )  == 0 )
            {
            ConfigData->DmaBufferSize = *(PULONG)ValueData;
            dprintf3((" SoundReadConfiguration(): Read DMA Buffer Size = %XH",
                                                 ConfigData->DmaBufferSize));
            }

        // FM Clock Override
        else if ( _wcsicmp(ValueName, SOUND_REG_FM_CLK_OVRID)  == 0 )
            {
            ConfigData->FMClockOverride = *(PULONG)ValueData;
            dprintf3((" SoundReadConfiguration(): Read FMClockOverride = %u",
                                                 ConfigData->FMClockOverride));
            }
        else if ( _wcsicmp(ValueName, SOUND_REG_ALLOWMICLINEINTOLINEOUT)  == 0 )
            {
            ConfigData->AllowMicOrLineInToLineOut = (BOOLEAN)(*(PULONG)ValueData != 0);
            dprintf3((" SoundReadConfiguration(): Read FMClockOverride = %u",
                                                 ConfigData->FMClockOverride));
            }

        // Input Source
        else if ( _wcsicmp(ValueName, SOUND_REG_INPUTSOURCE)  == 0 )
            {
            ConfigData->InputSource = *(PULONG)ValueData;
            dprintf3((" SoundReadConfiguration() Read Input Source     = %s",
                       ConfigData->InputSource == INPUT_LINEIN ? "Line in" :
                       ConfigData->InputSource == INPUT_AUX ? "Aux" :
                       ConfigData->InputSource == INPUT_MIC ? "Microphone" :
                       ConfigData->InputSource == INPUT_OUTPUT ? "Output" :
                      "Invalid input source" ));
            }
        }           // End IF (ValueType == REG_DWORD)
     else {
        if (ValueType == REG_BINARY &&
            _wcsicmp(ValueName, SOUND_MIXER_SETTINGS_NAME) == 0) {
            ASSERTMSG("Mixer data wrong length!",
                      ValueLength == sizeof(ConfigData->MixerSettings));

            dprintf3(("Mixer settings"));
            RtlCopyMemory((PVOID)ConfigData->MixerSettings,
                          ValueData,
                          ValueLength);
            ConfigData->MixerSettingsFound = TRUE;
        }
    }

    return STATUS_SUCCESS;

}
Exemplo n.º 29
0
NTSTATUS
SoundPortValid(
    IN OUT PGLOBAL_DEVICE_INFO pGDI,
    IN OUT PULONG Port
)
{


    NTSTATUS Status;

	dprintf5((">>> SoundPortValid(): Port = %8x", *Port));

    //
    // Check we're going to be allowed to use this port or whether
    // some other device thinks it owns this hardware
    //

    Status = SoundReportResourceUsage(
                 pGDI->DeviceObject[WaveInDevice],  // As good as any device to own it
                 pGDI->BusType,
                 pGDI->BusNumber,
                 NULL,
                 0,
                 FALSE,
                 NULL,
                 Port,
                 NUMBER_OF_SOUND_PORTS);

    if (!NT_SUCCESS(Status)) {
        return Status;
    }

	dprintf5(("SoundReportResourceUsage() Success!!"));

    //
    // Find where our device is mapped
    //

    pGDI->Hw.PortBase = SoundMapPortAddress(
                               pGDI->BusType,
                               pGDI->BusNumber,
                               *Port,
                               NUMBER_OF_SOUND_PORTS,
                               &pGDI->MemType);
	
	dprintf4(("Mapped PortBase = %8x", pGDI->Hw.PortBase));

    //
    // Finally we can check and see if the hardware is happy
    //

    if (HwIsIoValid(&pGDI->Hw)) {

		dprintf5(("HwIsIoValid() Success!!"));

        return STATUS_SUCCESS;
    }

	dprintf2(("HwIsIoValid() Faided!!"));

    //
    // Free any resources.  (note we don't have to do
    // IoReportResourceUsage again because each one overwrites the
    // previous).
    //

    if (pGDI->MemType == 0) {
        MmUnmapIoSpace(pGDI->Hw.PortBase, NUMBER_OF_SOUND_PORTS);
    	dprintf4(("Free IO space"));
    }

    pGDI->Hw.PortBase = NULL;

    return STATUS_DEVICE_CONFIGURATION_ERROR;
}
Exemplo n.º 30
0
PUCHAR
SoundMapPortAddress(
    INTERFACE_TYPE BusType,
    ULONG BusNumber,
    ULONG PortBase,
    ULONG Length,
    PULONG MemType
)
/*++

Routine Description :

    Map a physical device port address to an address we can pass
    to READ/WRITE_PORT_UCHAR/USHORT etc

Arguments :
    BusType - type of bus
    BusNumber - bus number
    PortBase - The port start address
    Length - how many bytes of port space to map (needed by MmMapIoSpace)

Return Value :

    The virtual port address

--*/
{
    PHYSICAL_ADDRESS PortAddress;
    PHYSICAL_ADDRESS MappedAddress;

  	*MemType = 0;  				// Memory Space   
	
    PortAddress.LowPart = PortBase;
    PortAddress.HighPart = 0;
   
	dprintf5((">>>> PortBase = %8x", PortBase));

    dprintf4(("HalTranslateBusAddress()2: Bustype     = %d", BusType));
	dprintf4(("HalTranslateBusAddress()2: BusNumber   = %d", BusNumber));
    dprintf4(("HalTranslateBusAddress()2: PortAddr.lo = 0x%16x", PortAddress.LowPart));
    dprintf4(("HalTranslateBusAddress()2: PortAddr.hi = 0x%16x", PortAddress.HighPart));
    dprintf4(("HalTranslateBusAddress()2: MemType     = %d", *MemType));
    
    HalTranslateBusAddress(
                BusType,
                BusNumber,
                PortAddress,
                MemType,
                &MappedAddress);

	dprintf4(("HalTranslateBusAddress()2: MemType(Out) = %d", *MemType));
	dprintf4(("HalTranslateBusAddress()2: MapAddr(Out) = 0x%16x", MappedAddress));



    if (*MemType == 0) {
        //
        // Map memory type IO space into our address space
        //
        return (PUCHAR)MmMapIoSpace(MappedAddress, Length, FALSE);
    } else {
        return (PUCHAR)MappedAddress.LowPart;
    }
}