Hi Shakeel,
There is no way to do that. The IDE controllers have one DMA controller per
channel
and once the DMA is active you should not touch the channel till yu issue a
STOP_TRANSFER
in ISR to that channel’s Bus Master DMA. So since you can fire only one
command per channel
it will be your internal logic that determines which command is current. You
will still be able to
fire commands simultaneously on different channels. So, For IDE RAID
controller the best performance
can only be obtained when the drives are placed on two different channels.
Also remember that equations change for SATA.
Thanks,
Ajitabh
-----Original Message-----
From: shakeel [mailto:xxxxx@yahoo.com]
Sent: Thursday, June 10, 2004 4:12 PM
To: Windows System Software Devs Interest List
Subject: Re:[ntdev] Performance of SCSI miniport for IDE RAID
Thanks Maxim,
Good point. Currently in miniport I won’t allow more than one outstanding
request for controller. If the miniport driver is processing SRB it returns
status SRB_STATUS_BUSY. I took atapi.sys code from NT 4.0 and modified it to
work for 2K/XP. I think the reason being is, Since there is one interrupt
handler for the controller how will it know which disk drive completed the
transfer if multiple outstanding requests are allowed. I may be wrong here,
Is there way to send request to other drives while the first one is still in
middle of transfer for an IDE RAID controller.
Thanks in advance,
Shakeel.
BOOLEAN
AtapiStartIo(
IN PVOID HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK Srb
)
/*++
Routine Description:
This routine is called from the SCSI port driver synchronized
with the kernel to start an IO request.
Arguments:
HwDeviceExtension - HBA miniport driver’s adapter data storage
Srb - IO request packet
Return Value:
TRUE
–*/
{
PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
ULONG status;
//
// Determine which function.
//
switch (Srb->Function) {
case SRB_FUNCTION_EXECUTE_SCSI:
//
// Sanity check. Only one request can be outstanding on a
// controller.
//
if (deviceExtension->CurrentSrb) {
DebugPrint((1,
“AtapiStartIo: Already have a request!\n”));
Srb->SrbStatus = SRB_STATUS_BUSY;
ScsiPortNotification(RequestComplete,
deviceExtension,
Srb);
return FALSE;
}
//
// Indicate that a request is active on the controller.
//
deviceExtension->CurrentSrb = Srb;
//
// Send command to device.
//
if (deviceExtension->DeviceFlags[Srb->TargetId] &
DFLAGS_ATAPI_DEVICE) {
status = AtapiSendCommand(HwDeviceExtension,
Srb);
} else if (deviceExtension->DeviceFlags[Srb->TargetId] &
DFLAGS_DEVICE_PRESENT) {
status = IdeSendCommand(HwDeviceExtension,
Srb);
} else {
status = SRB_STATUS_SELECTION_TIMEOUT;
}
break;
case SRB_FUNCTION_ABORT_COMMAND:
//
// Verify that SRB to abort is still outstanding.
//
if (!deviceExtension->CurrentSrb) {
DebugPrint((1, “AtapiStartIo: SRB to abort already
completed\n”));
//
// Complete abort SRB.
//
status = SRB_STATUS_ABORT_FAILED;
break;
}
//
// Abort function indicates that a request timed out.
// Call reset routine. Card will only be reset if
// status indicates something is wrong.
// Fall through to reset code.
//
case SRB_FUNCTION_RESET_BUS:
//
// Reset Atapi and SCSI bus.
//
DebugPrint((1, “AtapiStartIo: Reset bus request received\n”));
if (!AtapiResetController(deviceExtension,
Srb->PathId)) {
DebugPrint((1,“AtapiStartIo: Reset bus failed\n”));
//
// Log reset failure.
//
ScsiPortLogError(
HwDeviceExtension,
NULL,
0,
0,
0,
SP_INTERNAL_ADAPTER_ERROR,
5 << 8
);
status = SRB_STATUS_ERROR;
} else {
status = SRB_STATUS_SUCCESS;
}
break;
default :
status = SRB_STATUS_INVALID_REQUEST;
break;
}
break;
default:
//
// Indicate unsupported command.
//
status = SRB_STATUS_INVALID_REQUEST;
break;
} // end switch
//
// Check if command complete.
//
if (status != SRB_STATUS_PENDING) {
DebugPrint((2,
“AtapiStartIo: Srb %x complete with status %x\n”,
Srb,
status));
//
// Clear current SRB.
//
deviceExtension->CurrentSrb = NULL;
//
// Set status in SRB.
//
Srb->SrbStatus = (UCHAR)status;
//
// Indicate command complete.
//
ScsiPortNotification(RequestComplete,
deviceExtension,
Srb);
//
// Indicate ready for next request.
//
ScsiPortNotification(NextRequest,
deviceExtension,
NULL);
}
return TRUE;
} // end AtapiStartIo()
“Maxim S. Shatskih” wrote in message
news:xxxxx@ntdev…
> > Is Implementing a QUEUE in miniport driver gives any performance
> > improvements?
>
> No. It is absolutely irrelevant where the queue is - in SCSIPORT or in
your
> miniport.
>
> The firmware queue in the disk is better since the disk firmware can
reorder
> requests to reduce unnecessary head seeks and revolutions, and only due to
> this.
>
> Your miniport has no head/revolutions knowledge, and thus cannot do the
same.
>
> In a RAID, you can do the following though. If the request can be serviced
off
> 1 disk - then it is not necessary to block the whole RAID for its
duration. You
> can allow requests to other disks.
>
> Maxim Shatskih, Windows DDK MVP
> StorageCraft Corporation
> xxxxx@storagecraft.com
> http://www.storagecraft.com
>
>
—
Questions? First check the Kernel Driver FAQ at
http://www.osronline.com/article.cfm?id=256
You are currently subscribed to ntdev as: xxxxx@lsil.com
To unsubscribe send a blank email to xxxxx@lists.osr.com