Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

525 lines
12 KiB

/*++
Copyright (c) 1994 Microsoft Corporation
Module Name:
Dacioctl.c
Abstract:
This module provides support for DAC960 configuration IOCTls.
Author:
Mouli ([email protected])
Environment:
kernel mode only
Revision History:
--*/
#include "miniport.h"
#include "Dmc960Nt.h"
#include "Dac960Nt.h"
#include "d960api.h"
BOOLEAN
SubmitRequest(
IN PDEVICE_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
BOOLEAN
SubmitCdbDirect(
IN PDEVICE_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
);
BOOLEAN
IsAdapterReady(
IN PDEVICE_EXTENSION DeviceExtension
);
VOID
SendRequest(
IN PDEVICE_EXTENSION DeviceExtension
);
VOID
SendCdbDirect(
IN PDEVICE_EXTENSION DeviceExtension
);
BOOLEAN
SendIoctlDcmdRequest(
IN PDEVICE_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
)
/*++
Routine Description:
Build and submit IOCTL Request-DAC960(Non-DCDB) command to DAC960.
Arguments:
DeviceExtension - Adapter state.
SRB - System request.
Return Value:
TRUE if command was started
FALSE if host adapter is busy
--*/
{
ULONG physicalAddress;
PIOCTL_REQ_HEADER IoctlReqHeader;
ULONG i;
UCHAR busyCurrentIndex;
//
// Determine if adapter can accept new request.
//
if(!IsAdapterReady(DeviceExtension)) {
return FALSE;
}
//
// Check that next slot is vacant.
//
if (DeviceExtension->ActiveRequests[DeviceExtension->CurrentIndex]) {
//
// Collision occurred.
//
busyCurrentIndex = DeviceExtension->CurrentIndex++;
do {
if (! DeviceExtension->ActiveRequests[DeviceExtension->CurrentIndex]) {
break;
}
} while (++DeviceExtension->CurrentIndex != busyCurrentIndex) ;
if (DeviceExtension->CurrentIndex == busyCurrentIndex) {
//
// We should never encounter this condition.
//
DebugPrint((0,
"DAC960: SendIoctlDcmdRequest-Collision in active request array\n"));
return FALSE;
}
}
IoctlReqHeader = (PIOCTL_REQ_HEADER) Srb->DataBuffer;
physicalAddress =
ScsiPortConvertPhysicalAddressToUlong(
ScsiPortGetPhysicalAddress(DeviceExtension,
Srb,
((PUCHAR)Srb->DataBuffer +
sizeof(IOCTL_REQ_HEADER)),
&i));
//
// The buffer passed in may not be physically contiguous.
//
if (i < Srb->DataTransferLength - sizeof(IOCTL_REQ_HEADER)) {
DebugPrint((1,
"Dac960: DCMD IOCTL buffer is not contiguous\n"));
return FALSE;
}
//
// Write physical address in mailbox.
//
DeviceExtension->MailBox.PhysicalAddress = physicalAddress;
//
// Write command in mailbox.
//
DeviceExtension->MailBox.OperationCode =
IoctlReqHeader->GenMailBox.Reg0;
//
// Write request in mailbox.
//
DeviceExtension->MailBox.CommandIdSubmit =
DeviceExtension->CurrentIndex;
//
// Write Mail Box Registers 2 and 3.
//
DeviceExtension->MailBox.BlockCount = (USHORT)
(IoctlReqHeader->GenMailBox.Reg2 |
(IoctlReqHeader->GenMailBox.Reg3 << 8));
//
// Write Mail Box Registers 4, 5 and 6.
//
DeviceExtension->MailBox.BlockNumber[0] =
IoctlReqHeader->GenMailBox.Reg4;
DeviceExtension->MailBox.BlockNumber[1] =
IoctlReqHeader->GenMailBox.Reg5;
DeviceExtension->MailBox.BlockNumber[2] =
IoctlReqHeader->GenMailBox.Reg6;
//
// Write Mail Box Register 7.
//
DeviceExtension->MailBox.DriveNumber =
IoctlReqHeader->GenMailBox.Reg7;
//
// Write Mail Box Register C.
//
DeviceExtension->MailBox.ScatterGatherCount =
IoctlReqHeader->GenMailBox.RegC;
//
// Start writing mailbox to controller.
//
SendRequest(DeviceExtension);
return(TRUE);
} // SendIoctlDcmdRequest()
BOOLEAN
SendIoctlCdbDirect(
IN PDEVICE_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
)
/*++
Routine Description:
Send IOCTL Request-CDB directly to device.
Arguments:
DeviceExtension - Adapter state.
SRB - System request.
Return Value:
TRUE if command was started
FALSE if host adapter is busy
--*/
{
ULONG physicalAddress;
PDIRECT_CDB directCdb;
PIOCTL_REQ_HEADER IoctlReqHeader;
ULONG i;
UCHAR busyCurrentIndex;
//
// Determine if adapter can accept new request.
//
if(!IsAdapterReady(DeviceExtension)) {
return FALSE;
}
//
// Check that next slot is vacant.
//
if (DeviceExtension->ActiveRequests[DeviceExtension->CurrentIndex]) {
//
// Collision occurred.
//
busyCurrentIndex = DeviceExtension->CurrentIndex++;
do {
if (! DeviceExtension->ActiveRequests[DeviceExtension->CurrentIndex]) {
break;
}
} while (++DeviceExtension->CurrentIndex != busyCurrentIndex) ;
if (DeviceExtension->CurrentIndex == busyCurrentIndex) {
//
// We should never encounter this condition.
//
DebugPrint((0,
"DAC960: SendIoctlCdbDirect-Collision in active request array\n"));
return FALSE;
}
}
IoctlReqHeader = (PIOCTL_REQ_HEADER) Srb->DataBuffer;
directCdb =
(PDIRECT_CDB)((PUCHAR)Srb->DataBuffer + sizeof(IOCTL_REQ_HEADER));
//
// Get address of data buffer offset.
//
physicalAddress =
ScsiPortConvertPhysicalAddressToUlong(
ScsiPortGetPhysicalAddress(DeviceExtension,
Srb,
((PUCHAR)Srb->DataBuffer +
sizeof(IOCTL_REQ_HEADER) +
sizeof(DIRECT_CDB)),
&i));
//
// The buffer passed in may not be physically contiguous.
//
if (i < Srb->DataTransferLength -
(sizeof(IOCTL_REQ_HEADER) + sizeof(DIRECT_CDB))) {
DebugPrint((1,
"Dac960: DCDB IOCTL buffer is not contiguous\n"));
return FALSE;
}
directCdb->DataBufferAddress = physicalAddress;
if (directCdb->DataTransferLength == 0) {
//
// mask off data xfer in/out bits
//
directCdb->CommandControl &= ~(DAC960_CONTROL_DATA_IN |
DAC960_CONTROL_DATA_OUT);
}
//
// Disable Early-status on command bit
//
directCdb->CommandControl &= 0xfb;
//
// Get physical address of direct CDB packet.
//
physicalAddress =
ScsiPortConvertPhysicalAddressToUlong(
ScsiPortGetPhysicalAddress(DeviceExtension,
Srb,
directCdb,
&i));
//
// Write physical address in mailbox.
//
DeviceExtension->MailBox.PhysicalAddress = physicalAddress;
//
// Write command in mailbox.
//
DeviceExtension->MailBox.OperationCode =
IoctlReqHeader->GenMailBox.Reg0;
//
// Write request id in mailbox.
//
DeviceExtension->MailBox.CommandIdSubmit =
DeviceExtension->CurrentIndex;
//
// Start writing mailbox to controller.
//
SendCdbDirect(DeviceExtension);
return(TRUE);
} // SendIoctlCdbDirect()
VOID
SetupAdapterInfo(
IN PDEVICE_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
)
/*++
Routine Description:
Copy Adapter Information to Application Buffer.
Arguments:
DeviceExtension - Adapter state.
SRB - System request.
Return Value:
None.
--*/
{
PADAPTER_INFO AdpInfo;
AdpInfo = (PADAPTER_INFO)((PUCHAR) Srb->DataBuffer +
sizeof(IOCTL_REQ_HEADER));
//
// Fill in Adapter Features Information.
//
if (DeviceExtension->AdapterInterfaceType == MicroChannel) {
AdpInfo->AdpFeatures.Model = (UCHAR) DeviceExtension->PosData.AdapterId;
AdpInfo->AdpFeatures.SubModel = DeviceExtension->PosData.OptionData3;
}
else {
AdpInfo->AdpFeatures.Model = 0;
AdpInfo->AdpFeatures.SubModel = 0;
}
if (DeviceExtension->AdapterType == DAC960_NEW_ADAPTER) {
AdpInfo->AdpFeatures.MaxSysDrv = 32;
AdpInfo->AdpFeatures.MaxTgt = 16;
}
else {
AdpInfo->AdpFeatures.MaxSysDrv = 8;
if (AdpInfo->AdpFeatures.MaxChn == 5) {
AdpInfo->AdpFeatures.MaxTgt = 4;
}
else {
AdpInfo->AdpFeatures.MaxTgt = 7;
}
}
AdpInfo->AdpFeatures.MaxChn = (UCHAR) DeviceExtension->NumberOfChannels;
AdpInfo->AdpFeatures.AdapterType = (UCHAR) DeviceExtension->AdapterType;
AdpInfo->AdpFeatures.PktFormat = 0;
AdpInfo->AdpFeatures.Reserved1 = 0;
AdpInfo->AdpFeatures.Reserved2 = 0;
AdpInfo->AdpFeatures.CacheSize = 0;
AdpInfo->AdpFeatures.OemCode = 0;
AdpInfo->AdpFeatures.Reserved3 = 0;
//
// Fill in the System Resources information.
//
AdpInfo->SysResources.BusInterface =
(UCHAR) DeviceExtension->AdapterInterfaceType;
AdpInfo->SysResources.BusNumber =
(UCHAR) DeviceExtension->SystemIoBusNumber;
AdpInfo->SysResources.IrqVector =
(UCHAR) DeviceExtension->BusInterruptLevel;
AdpInfo->SysResources.IrqType =
(UCHAR) DeviceExtension->InterruptMode;
AdpInfo->SysResources.Slot = DeviceExtension->Slot;
AdpInfo->SysResources.Reserved2 = 0;
AdpInfo->SysResources.IoAddress = (ULONG) DeviceExtension->BaseIoAddress;
AdpInfo->SysResources.MemAddress = 0;
AdpInfo->SysResources.BiosAddress = (ULONG) DeviceExtension->BaseBiosAddress;
AdpInfo->SysResources.Reserved3 = 0;
//
// Fill in the Firmware & BIOS version information.
//
if (DeviceExtension->AdapterType == DAC960_NEW_ADAPTER) {
AdpInfo->VerControl.MinorFirmwareRevision =
((PDAC960_ENQUIRY_3X)DeviceExtension->NoncachedExtension)->MinorFirmwareRevision;
}
else {
AdpInfo->VerControl.MajorFirmwareRevision =
((PDAC960_ENQUIRY)DeviceExtension->NoncachedExtension)->MajorFirmwareRevision;
}
AdpInfo->VerControl.MinorBIOSRevision = 0;
AdpInfo->VerControl.MajorBIOSRevision = 0;
AdpInfo->VerControl.Reserved = 0;
}
VOID
SetupDriverVersionInfo(
IN PDEVICE_EXTENSION DeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
)
/*++
Routine Description:
Copy Driver Version Information to Application Buffer.
Arguments:
DeviceExtension - Adapter state.
SRB - System request.
Return Value:
None.
--*/
{
PDRIVER_VERSION driverVersion;
driverVersion = (PDRIVER_VERSION)((PUCHAR) Srb->DataBuffer +
sizeof(IOCTL_REQ_HEADER));
driverVersion->DriverMajorVersion = (UCHAR) (DRIVER_REVISION >> 8);
driverVersion->DriverMinorVersion = (UCHAR) DRIVER_REVISION;
driverVersion->Month = (UCHAR) (DRIVER_BUILD_DATE >> 16);
driverVersion->Date = (UCHAR) (DRIVER_BUILD_DATE >> 8);
driverVersion->Year = (UCHAR) DRIVER_BUILD_DATE;
}