home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Media Share 13
/
mediashare_13.zip
/
mediashare_13
/
ZIPPED
/
PROGRAM
/
DDJ9403A.ZIP
/
CDROM.ZIP
/
CDNOW.C
next >
Wrap
Text File
|
1993-10-13
|
14KB
|
535 lines
/********************************************************************
Copyright (c) 1993 Sing Li, Media Synergy Inc. All Rights Reserved
Module Name:
CDnow.c
Abstract:
This is the Scsi miniport driver for Panasonic 52x using
native or compatible controllers.
This module contains general routines which are independent
of specific drive models.
**********************************************************************/
#include "ntddk.h"
#include "stdarg.h"
#include "CDnow.h" // includes scsi.h
//***********************************************
//* Function ProtoTyping
//***********************************************
USHORT
LocateAdapterSpecific(
PSPECIFIC_DEVICE_EXTENSION deviceExtension,
IN PVOID Context,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
);
BOOLEAN
CDnowInitialize(
IN PVOID Context
);
NTSTATUS
CDRead( //)
ULONG LogAddr,
USHORT LogBlkRead,
PUCHAR userBuffer,
PSPECIFIC_DEVICE_EXTENSION dExt
);
ULONG
DriverEntry(
IN PVOID DriverObject,
IN PVOID Argument2
);
ULONG
CDnowFindAdapter(
IN PVOID Context,
IN PVOID AdaptersFound,
IN PVOID BusInformation,
IN PCHAR ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
OUT PBOOLEAN Again
);
BOOLEAN
CDnowStartIo(
IN PVOID Context,
IN PSCSI_REQUEST_BLOCK Srb
);
BOOLEAN
CDnowInterrupt(
IN PVOID Context
);
BOOLEAN
CDnowResetBus(
IN PVOID Context,
IN ULONG PathId
);
/*****************************************************************/
/*
Routine Description:
This dummy routine handles the interrupts for the CDnow. This was
necessary for March Beta of Windows NT. It was left in for
compatibility purposes.
Arguments:
Context - Device adapter context pointer.
Return Value:
FALSE indicates that this interrupt was NOT from us.
*/
/*****************************************************************/
BOOLEAN
CDnowInterrupt(
IN PVOID Context
)
{
PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
return FALSE;
} // end CDnowInterrupt()
/*****************************************************************/
/*
Routine Description:
Reset Bus from the SCSI Port driver. We basically do nothing
here.
*/
/*****************************************************************/
BOOLEAN
CDnowResetBus(
IN PVOID Context,
IN ULONG PathId
)
{
PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
return TRUE;
} // end CDnowResetBus()
/*****************************************************************/
/* Routine Description:
/* Simulate response the SCSI INQUIRY op-code. We make the port
/* driver believe that a SCSI CD-ROM is connected.
/*****************************************************************/
void
Cdrom_Inquiry(PSPECIFIC_LU_EXTENSION luExtension)
{
INQUIRYDATA *cdromInquiry;
cdromInquiry = (INQUIRYDATA *) luExtension->SavedDataPointer;
cdromInquiry->DeviceType = READ_ONLY_DIRECT_ACCESS_DEVICE;
cdromInquiry->DeviceTypeQualifier = DEVICE_CONNECTED;
memcpy(cdromInquiry->VendorId, "MedSyn", 8);
memcpy(cdromInquiry->ProductId, "Cd-Rom Now", 11);
}
/****************************************************************/
/*
Routine Description:
Simulate a response to the SCSI Read Capacity opcode. We
hardcode the sector size and volume size here for compatibility
with drives which cannot determine capacity.
The little endian to big endian conversion was a major gottcha.
*/
/*****************************************************************/
VOID CapacityRead(PSPECIFIC_LU_EXTENSION luExtension)
{
READ_CAPACITY_DATA *capacityRead;
ULONG FixBlockEnd;
ULONG FixBlockSize;
PFOUR_BYTE pEnd = (PFOUR_BYTE)&FixBlockEnd;
PFOUR_BYTE pSize = (PFOUR_BYTE)&FixBlockSize;
// Convert to big Endian
capacityRead = (READ_CAPACITY_DATA *) luExtension->SavedDataPointer;
FixBlockEnd = 270000;
FixBlockSize = 2048;
((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte3=
pEnd->Byte0;
((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte2=
pEnd->Byte1;
((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte1=
pEnd->Byte2;
((PFOUR_BYTE)&(capacityRead->LogicalBlockAddress))->Byte0=
pEnd->Byte3;
((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte3=
pSize->Byte0;
((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte2=
pSize->Byte1;
((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte2=
pSize->Byte2;
((PFOUR_BYTE)&(capacityRead->BytesPerBlock))->Byte0=
pSize->Byte3;
}
/*****************************************************************/
/* */
/* ReadCDRom */
/* Transform the Logical block address and size into our */
/* format for access by our read routine */
/* */
/*****************************************************************/
NTSTATUS ReadCDRom(PSPECIFIC_DEVICE_EXTENSION deviceExtension,
PSPECIFIC_LU_EXTENSION luExtension)
{
struct MYCDB {
UCHAR OperationCode;
UCHAR RelativeAddress : 1;
UCHAR Reserved1 : 2;
UCHAR ForceUnitAccess : 1;
UCHAR DisablePageOut : 1;
UCHAR LogicalUnitNumber : 3;
UCHAR LogicalBlockByte0;
UCHAR LogicalBlockByte1;
UCHAR LogicalBlockByte2;
UCHAR LogicalBlockByte3;
UCHAR Reserved2;
UCHAR TransferBlocksMsb;
UCHAR TransferBlocksLsb;
UCHAR Control;
} *cdb;
ULONG logicalBlockAddress;
USHORT transferBlocks;
cdb =(struct MYCDB *) luExtension->ActiveLuRequest->Cdb;
((PFOUR_BYTE)&logicalBlockAddress)->Byte3= cdb->LogicalBlockByte0;
((PFOUR_BYTE)&logicalBlockAddress)->Byte2= cdb->LogicalBlockByte1;
((PFOUR_BYTE)&logicalBlockAddress)->Byte1= cdb->LogicalBlockByte2;
((PFOUR_BYTE)&logicalBlockAddress)->Byte0= cdb->LogicalBlockByte3;
((PFOUR_BYTE)&transferBlocks)->Byte1= cdb->TransferBlocksMsb;
((PFOUR_BYTE)&transferBlocks)->Byte0= cdb->TransferBlocksLsb;
return( CDRead(logicalBlockAddress, transferBlocks,
luExtension->ActiveLuRequest->DataBuffer, deviceExtension));
}
/*****************************************************************/
/*
Routine Description:
This routine is called from the SCSI port driver synchronized
with the kernel with a request to be executed.
*/
/*****************************************************************/
BOOLEAN
CDnowStartIo(
IN PVOID Context,
IN PSCSI_REQUEST_BLOCK Srb
)
{
PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
PSPECIFIC_LU_EXTENSION luExtension;
//
// Determine the logical unit that this request is for.
//
deviceExtension->PathId = Srb->PathId;
luExtension = ScsiPortGetLogicalUnit(deviceExtension,
deviceExtension->PathId,
Srb->TargetId,
Srb->Lun);
Srb->SrbStatus = SRB_STATUS_PENDING;
switch (Srb->Function) {
case SRB_FUNCTION_ABORT_COMMAND:
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SRB_FUNCTION_RESET_BUS:
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
case SRB_FUNCTION_EXECUTE_SCSI:
if ((Srb->TargetId == 3) && (Srb->Lun == 0)) // not at 0 or 1
{
luExtension->ActiveLuRequest = Srb;
luExtension->LuState = LS_COMPLETE;
luExtension->SavedDataPointer = (ULONG) Srb->DataBuffer;
luExtension->SavedDataLength = Srb->DataTransferLength;
switch( Srb->Cdb[0])
{
// Get CD-ROM Inquiry Data
case (SCSIOP_INQUIRY):
//
// Setup the context for this target/lun.
//
Cdrom_Inquiry(luExtension);
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
// ReadCapacity: Hardwired data
case(SCSIOP_READ_CAPACITY):
CapacityRead(luExtension);
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
// Read Cd-ROM
case(SCSIOP_READ):
if NT_SUCCESS(ReadCDRom(deviceExtension,
luExtension))
Srb->SrbStatus = SRB_STATUS_SUCCESS;
else
Srb->SrbStatus = SRB_STATUS_ERROR;
break;
case (SCSIOP_TEST_UNIT_READY):
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
// Invalid Scsi Op code
default:
Srb->SrbStatus = SRB_STATUS_SUCCESS;
break;
} // of switch
} // of if
else
{
Srb->SrbStatus = SRB_STATUS_INVALID_TARGET_ID;
}
ScsiPortNotification(RequestComplete,
(PVOID) deviceExtension,
Srb);
break;
// Unexpected Scsi Function Call
default:
Srb->SrbStatus = SRB_STATUS_INVALID_REQUEST;
ScsiPortNotification(RequestComplete,
(PVOID) deviceExtension,
Srb);
break;
}
// Adapter ready for next request.
ScsiPortNotification(NextRequest,
deviceExtension,
NULL);
return TRUE;
} // end CDnowStartIo()
/*****************************************************************/
/* */
/* findAdapterPort */
/* - locate the Io port address of the adaptor */
/* */
/*****************************************************************/
USHORT findAdapterPort(
PSPECIFIC_DEVICE_EXTENSION deviceExtension,
IN PVOID Context,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo
)
{
ULONG PortBase = BASE_PORT;
deviceExtension->PortBase = PortBase;
return LocateAdapterSpecific(deviceExtension, Context, ConfigInfo); // PortBase;
}
/*****************************************************************/
/*
Routine Description:
This routine locates the CD controller card, and allocate
the IO ports from NT IO manager.
Return Value:
SP_RETURN_FOUND - if an adapter is found.
SP_RETURN_NOT_FOUND - if no adapter is found.
*/
/*****************************************************************/
ULONG
CDnowFindAdapter(
IN PVOID Context,
IN PVOID AdaptersFound,
IN PVOID BusInformation,
IN PCHAR ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo,
OUT PBOOLEAN Again
)
{
USHORT portAddress;
USHORT adaptersFound;
ULONG returnStatus = SP_RETURN_NOT_FOUND;
PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
*Again = FALSE;
returnStatus = SP_RETURN_FOUND; // assum found a valid card
//
// If there was no previously configured value for the IRQ,
// look at the other way to configure the value or use a default.
//
ConfigInfo->BusInterruptLevel = 10;
// fill in a default a target ID.
ConfigInfo->NumberOfBuses = 1;
ConfigInfo->ScatterGather = FALSE;
ConfigInfo->Master = FALSE;
portAddress= findAdapterPort(deviceExtension, Context, ConfigInfo);
deviceExtension->PortBase = portAddress;
if(portAddress == 0)
{
returnStatus = SP_RETURN_NOT_FOUND;
goto NotFound;
}
// Fill in the access array information.
ConfigInfo->NumberOfAccessRanges = 1;
(*ConfigInfo->AccessRanges)[0].RangeStart =
ScsiPortConvertUlongToPhysicalAddress(portAddress);
(*ConfigInfo->AccessRanges)[0].RangeLength = 4;
(*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
ConfigInfo->NumberOfBuses = 1;
adaptersFound = 1;
*((PULONG) AdaptersFound) == (ULONG) adaptersFound;
returnStatus = SP_RETURN_FOUND; // assum found a valid card
NotFound:
return (returnStatus);
} // end CDnowFindAdapter()
/*****************************************************************/
/*
Routine Description:
Driver initialization entry point for system.
*/
/*****************************************************************/
ULONG
DriverEntry(
IN PVOID DriverObject,
IN PVOID Argument2
)
{
HW_INITIALIZATION_DATA hwInitializationData;
ULONG i,status;
//
// Zero out the hwInitializationData structure.
//
for (i = 0; i < sizeof(HW_INITIALIZATION_DATA); i++) {
*(((PUCHAR)&hwInitializationData + i)) = 0;
}
hwInitializationData.HwInitializationDataSize = sizeof(HW_INITIALIZATION_DATA);
//
// Set entry points.
//
hwInitializationData.HwInitialize = CDnowInitialize;
hwInitializationData.HwStartIo = CDnowStartIo;
hwInitializationData.HwInterrupt = CDnowInterrupt;
hwInitializationData.HwFindAdapter = CDnowFindAdapter;
hwInitializationData.HwResetBus = CDnowResetBus;
// features not supported
hwInitializationData.HwDmaStarted = NULL;
hwInitializationData.HwAdapterState = NULL;
hwInitializationData.NeedPhysicalAddresses = FALSE;
//
// Specify size of extensions.
//
//
// Indicate need buffer mapping but not physical addresses.
//
hwInitializationData.MapBuffers = TRUE;
hwInitializationData.NeedPhysicalAddresses = FALSE;
hwInitializationData.NumberOfAccessRanges = 1;
//
// Specify size of device extension.
//
hwInitializationData.DeviceExtensionSize = sizeof(SPECIFIC_DEVICE_EXTENSION);
//
// Specify size of logical unit extension.
//
hwInitializationData.SpecificLuExtensionSize = sizeof(SPECIFIC_LU_EXTENSION);
//
// The fourth parameter below (i.e., "i") will show up as the
// "AdaptersFound" parameter when FindAdapter() is called.
//
// First try to configure for the Isa bus.
//
hwInitializationData.AdapterInterfaceType = Isa;
i = 0;
status = ScsiPortInitialize(DriverObject, Argument2,
&hwInitializationData, &(i));
return status;
} // end DriverEntry()
/*****************************************************************/
/*
Routine Description:
Inititialize adapter. We have dummied out this function for
compatibility purposes.
Arguments:
Context - Adapter object device extension.
Return Value:
Status.
*/
/*****************************************************************/
BOOLEAN
CDnowInitialize(
IN PVOID Context
)
{
PSPECIFIC_DEVICE_EXTENSION deviceExtension = Context;
return TRUE;
} // end CDnow<Initialize()