📄 atapi.c
字号:
if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
switch (errorByte >> 4) {
case SCSI_SENSE_NO_SENSE:
DebugPrint((1,
"ATAPI: No sense information\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_RECOVERED_ERROR:
DebugPrint((1,
"ATAPI: Recovered error\n"));
scsiStatus = 0;
srbStatus = SRB_STATUS_SUCCESS;
break;
case SCSI_SENSE_NOT_READY:
DebugPrint((1,
"ATAPI: Device not ready\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_MEDIUM_ERROR:
DebugPrint((1,
"ATAPI: Media error\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_HARDWARE_ERROR:
DebugPrint((1,
"ATAPI: Hardware error\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_ILLEGAL_REQUEST:
DebugPrint((1,
"ATAPI: Illegal request\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_UNIT_ATTENTION:
DebugPrint((1,
"ATAPI: Unit attention\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_DATA_PROTECT:
DebugPrint((1,
"ATAPI: Data protect\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_BLANK_CHECK:
DebugPrint((1,
"ATAPI: Blank check\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
case SCSI_SENSE_ABORTED_COMMAND:
DebugPrint((1,
"Atapi: Command Aborted\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
break;
default:
DebugPrint((1,
"ATAPI: Invalid sense information\n"));
scsiStatus = 0;
srbStatus = SRB_STATUS_ERROR;
break;
}
} else {
scsiStatus = 0;
//
// Save errorByte,to be used by SCSIOP_REQUEST_SENSE.
//
deviceExtension->ReturningMediaStatus = errorByte;
if (errorByte & IDE_ERROR_MEDIA_CHANGE_REQ) {
DebugPrint((1,
"IDE: Media change\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
} else if (errorByte & IDE_ERROR_COMMAND_ABORTED) {
DebugPrint((1,
"IDE: Command abort\n"));
srbStatus = SRB_STATUS_ABORTED;
scsiStatus = SCSISTAT_CHECK_CONDITION;
if (Srb->SenseInfoBuffer) {
PSENSE_DATA senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
senseBuffer->ErrorCode = 0x70;
senseBuffer->Valid = 1;
senseBuffer->AdditionalSenseLength = 0xb;
senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
senseBuffer->AdditionalSenseCode = 0;
senseBuffer->AdditionalSenseCodeQualifier = 0;
srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
}
deviceExtension->ErrorCount++;
} else if (errorByte & IDE_ERROR_END_OF_MEDIA) {
DebugPrint((1,
"IDE: End of media\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_MEDIA_STATUS_ENABLED)){
deviceExtension->ErrorCount++;
}
} else if (errorByte & IDE_ERROR_ILLEGAL_LENGTH) {
DebugPrint((1,
"IDE: Illegal length\n"));
srbStatus = SRB_STATUS_INVALID_REQUEST;
} else if (errorByte & IDE_ERROR_BAD_BLOCK) {
DebugPrint((1,
"IDE: Bad block\n"));
srbStatus = SRB_STATUS_ERROR;
scsiStatus = SCSISTAT_CHECK_CONDITION;
if (Srb->SenseInfoBuffer) {
PSENSE_DATA senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
senseBuffer->ErrorCode = 0x70;
senseBuffer->Valid = 1;
senseBuffer->AdditionalSenseLength = 0xb;
senseBuffer->SenseKey = SCSI_SENSE_MEDIUM_ERROR;
senseBuffer->AdditionalSenseCode = 0;
senseBuffer->AdditionalSenseCodeQualifier = 0;
srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
}
} else if (errorByte & IDE_ERROR_ID_NOT_FOUND) {
DebugPrint((1,
"IDE: Id not found\n"));
srbStatus = SRB_STATUS_ERROR;
scsiStatus = SCSISTAT_CHECK_CONDITION;
if (Srb->SenseInfoBuffer) {
PSENSE_DATA senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
senseBuffer->ErrorCode = 0x70;
senseBuffer->Valid = 1;
senseBuffer->AdditionalSenseLength = 0xb;
senseBuffer->SenseKey = SCSI_SENSE_MEDIUM_ERROR;
senseBuffer->AdditionalSenseCode = 0;
senseBuffer->AdditionalSenseCodeQualifier = 0;
srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
}
deviceExtension->ErrorCount++;
} else if (errorByte & IDE_ERROR_MEDIA_CHANGE) {
DebugPrint((1,
"IDE: Media change\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
if (Srb->SenseInfoBuffer) {
PSENSE_DATA senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
senseBuffer->ErrorCode = 0x70;
senseBuffer->Valid = 1;
senseBuffer->AdditionalSenseLength = 0xb;
senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
senseBuffer->AdditionalSenseCode = SCSI_ADSENSE_MEDIUM_CHANGED;
senseBuffer->AdditionalSenseCodeQualifier = 0;
srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
}
} else if (errorByte & IDE_ERROR_DATA_ERROR) {
DebugPrint((1,
"IDE: Data error\n"));
scsiStatus = SCSISTAT_CHECK_CONDITION;
srbStatus = SRB_STATUS_ERROR;
if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_MEDIA_STATUS_ENABLED)){
deviceExtension->ErrorCount++;
}
//
// Build sense buffer
//
if (Srb->SenseInfoBuffer) {
PSENSE_DATA senseBuffer = (PSENSE_DATA)Srb->SenseInfoBuffer;
senseBuffer->ErrorCode = 0x70;
senseBuffer->Valid = 1;
senseBuffer->AdditionalSenseLength = 0xb;
senseBuffer->SenseKey = SCSI_SENSE_MEDIUM_ERROR;
senseBuffer->AdditionalSenseCode = 0;
senseBuffer->AdditionalSenseCodeQualifier = 0;
srbStatus |= SRB_STATUS_AUTOSENSE_VALID;
}
}
if (deviceExtension->ErrorCount >= MAX_ERRORS) {
deviceExtension->DWordIO = FALSE;
deviceExtension->MaximumBlockXfer[Srb->TargetId] = 0;
DebugPrint((1,
"MapError: Disabling 32-bit PIO and Multi-sector IOs\n"));
//
// Log the error.
//
ScsiPortLogError( HwDeviceExtension,
Srb,
Srb->PathId,
Srb->TargetId,
Srb->Lun,
SP_BAD_FW_WARNING,
4);
//
// Reprogram to not use Multi-sector.
//
for (i = 0; i < 4; i++) {
UCHAR statusByte;
if (deviceExtension->DeviceFlags[i] & DFLAGS_DEVICE_PRESENT &&
!(deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE)) {
//
// Select the device.
//
ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,
(UCHAR)(((i & 0x1) << 4) | 0xA0));
//
// Setup sector count to reflect the # of blocks.
//
ScsiPortWritePortUchar(&baseIoAddress1->BlockCount,
0);
//
// Issue the command.
//
ScsiPortWritePortUchar(&baseIoAddress1->Command,
IDE_COMMAND_SET_MULTIPLE);
//
// Wait for busy to drop.
//
WaitOnBaseBusy(baseIoAddress1,statusByte);
//
// Check for errors. Reset the value to 0 (disable MultiBlock) if the
// command was aborted.
//
if (statusByte & IDE_STATUS_ERROR) {
//
// Read the error register.
//
errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1);
DebugPrint((1,
"AtapiHwInitialize: Error setting multiple mode. Status %x, error byte %x\n",
statusByte,
errorByte));
//
// Adjust the devExt. value, if necessary.
//
deviceExtension->MaximumBlockXfer[i] = 0;
}
}
}
}
}
//
// Set SCSI status to indicate a check condition.
//
Srb->ScsiStatus = scsiStatus;
return srbStatus;
} // end MapError()
BOOLEAN
STDCALL
AtapiHwInitialize(
IN PVOID HwDeviceExtension
)
/*++
Routine Description:
Arguments:
HwDeviceExtension - HBA miniport driver's adapter data storage
Return Value:
TRUE - if initialization successful.
FALSE - if initialization unsuccessful.
--*/
{
PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
PIDE_REGISTERS_1 baseIoAddress;
ULONG i;
UCHAR statusByte, errorByte;
for (i = 0; i < 4; i++) {
if (deviceExtension->DeviceFlags[i] & DFLAGS_DEVICE_PRESENT) {
if (!(deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE)) {
//
// Enable media status notification
//
baseIoAddress = deviceExtension->BaseIoAddress1[i >> 1];
IdeMediaStatus(TRUE,HwDeviceExtension,i);
//
// If supported, setup Multi-block transfers.
//
if (deviceExtension->MaximumBlockXfer[i]) {
//
// Select the device.
//
ScsiPortWritePortUchar(&baseIoAddress->DriveSelect,
(UCHAR)(((i & 0x1) << 4) | 0xA0));
//
// Setup sector count to reflect the # of blocks.
//
ScsiPortWritePortUchar(&baseIoAddress->BlockCount,
deviceExtension->MaximumBlockXfer[i]);
//
// Issue the command.
//
ScsiPortWritePortUchar(&baseIoAddress->Command,
IDE_COMMAND_SET_MULTIPLE);
//
// Wait for busy to drop.
//
WaitOnBaseBusy(baseIoAddress,statusByte);
//
// Check for errors. Reset the value to 0 (disable MultiBlock) if the
// command was aborted.
//
if (statusByte & IDE_STATUS_ERROR) {
//
// Read the error register.
//
errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress + 1);
DebugPrint((1,
"AtapiHwInitialize: Error setting multiple mode. Status %x, error byte %x\n",
statusByte,
errorByte));
//
// Adjust the devExt. value, if necessary.
//
deviceExtension->MaximumBlockXfer[i] = 0;
} else {
DebugPrint((2,
"AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
i,
deviceExtension->MaximumBlockXfer[i]));
}
}
} else if (!(deviceExtension->DeviceFlags[i] & DFLAGS_CHANGER_INITED)){
ULONG j;
BOOLEAN isSanyo = FALSE;
UCHAR vendorId[26];
//
// Attempt to identify any special-case devices - psuedo-atapi changers, atapi changers, etc.
//
for (j = 0; j < 13; j += 2) {
//
// Build a buffer based on the identify data.
//
vendorId[j] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j + 1];
vendorId[j+1] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j];
}
if (!AtapiStringCmp (vendorId, "CD-ROM CDR", 11)) {
//
// Inquiry string for older model had a '-', newer is '_'
//
if (vendorId[12] == 'C') {
//
// Torisan changer. Set the bit. This will be used in several places
// acting like 1) a multi-lun device and 2) building the 'special' TUR's.
//
deviceExtension->DeviceFlags[i] |= (DFLAGS_CHANGER_INITED | DFLAGS_SANYO_ATAPI_CHANGER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -