* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
-/* $Id: atapi.c,v 1.29 2002/09/19 16:17:35 ekohl Exp $
+/* $Id: atapi.c,v 1.30 2002/11/11 21:51:33 hbirr Exp $
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS ATAPI miniport driver
#define ENABLE_PCI
#define ENABLE_ISA
+#define ENABLE_MULTIMODE // enables multiple sector commands
+#define ENABLE_32BIT // enables 32Bit I/O for disk transfer (not for ATAPI)
// -------------------------------------------------------------------------
ConfigInfo->AtdiskPrimaryClaimed = TRUE;
ChannelFound = TRUE;
- *Again = FALSE/*TRUE*/;
+ *Again = TRUE;
}
else if (ConfigInfo->AtdiskSecondaryClaimed == FALSE)
{
BOOLEAN IsAtapi;
ULONG Retries;
PUCHAR TargetAddress;
- ULONG SectorSize;
ULONG TransferSize;
DPRINT("AtapiInterrupt() called!\n");
else
{
TransferSize = DevExt->DeviceParams[Srb->TargetId].BytesPerSector;
+#ifdef ENABLE_MULTIMODE
+ if (DevExt->DeviceParams[Srb->TargetId].RWMultCurrent & 0xff)
+ {
+ TransferSize *= (DevExt->DeviceParams[Srb->TargetId].RWMultCurrent & 0xff);
+ }
+#endif
}
DPRINT("TransferLength: %lu\n", Srb->DataTransferLength);
if (Srb->DataTransferLength <= TransferSize)
{
+#ifdef ENABLE_MULTIMODE
+ if (!IsAtapi)
+ {
+ TransferSize = Srb->DataTransferLength;
+ }
+#endif
Srb->DataTransferLength = 0;
IsLastBlock = TRUE;
}
}
/* Copy the block of data */
+#ifdef ENABLE_32BIT
+ if (IsAtapi)
+ {
+ IDEReadBlock(CommandPortBase,
+ TargetAddress,
+ TransferSize);
+ }
+ else
+ {
+ IDEReadBlock32(CommandPortBase,
+ TargetAddress,
+ TransferSize);
+ }
+#else
IDEReadBlock(CommandPortBase,
TargetAddress,
TransferSize);
-
+#endif
/* check DRQ */
if (IsLastBlock)
{
else
{
/* Update SRB data */
- SectorSize = DevExt->DeviceParams[Srb->TargetId].BytesPerSector;
-
+ TransferSize = DevExt->DeviceParams[Srb->TargetId].BytesPerSector;
+#ifdef ENABLE_MULTIMODE
+ if (DevExt->DeviceParams[Srb->TargetId].RWMultCurrent & 0xff)
+ {
+ TransferSize *= (DevExt->DeviceParams[Srb->TargetId].RWMultCurrent & 0xff);
+ }
+#endif
+ if (Srb->DataTransferLength <= TransferSize)
+ {
+ TransferSize = Srb->DataTransferLength;
+ }
+
TargetAddress = Srb->DataBuffer;
- Srb->DataBuffer += SectorSize;
- Srb->DataTransferLength -= SectorSize;
+ Srb->DataBuffer += TransferSize;
+ Srb->DataTransferLength -= TransferSize;
/* Write the sector */
+#ifdef ENABLE_32BIT
+ IDEWriteBlock32(CommandPortBase,
+ TargetAddress,
+ TransferSize);
+#else
IDEWriteBlock(CommandPortBase,
TargetAddress,
- SectorSize);
+ TransferSize);
+#endif
}
Srb->SrbStatus = SRB_STATUS_SUCCESS;
DrvParms->ECCByteCnt,
DrvParms->FirmwareRev);
DPRINT("Model:[%.40s]\n", DrvParms->ModelNumber);
- DPRINT("RWMult?:%02x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n",
+ DPRINT("RWMultMax?:%02x RWMult?:%02x LBA:%d DMA:%d MinPIO:%d ns MinDMA:%d ns\n",
(DrvParms->RWMultImplemented) & 0xff,
+ (DrvParms->RWMultCurrent) & 0xff,
(DrvParms->Capabilities & IDE_DRID_LBA_SUPPORTED) ? 1 : 0,
(DrvParms->Capabilities & IDE_DRID_DMA_SUPPORTED) ? 1 : 0,
DrvParms->MinPIOTransTime,
if (Srb->SrbFlags & SRB_FLAGS_DATA_IN)
{
+#ifdef ENABLE_MULTIMODE
+ Command = DeviceParams->RWMultCurrent & 0xff ? IDE_CMD_READ_MULTIPLE : IDE_CMD_READ;
+#else
Command = IDE_CMD_READ;
+#endif
}
else
{
+#ifdef ENABLE_MULTIMODE
+ Command = DeviceParams->RWMultCurrent & 0xff ? IDE_CMD_WRITE_MULTIPLE : IDE_CMD_WRITE;
+#else
Command = IDE_CMD_WRITE;
+#endif
}
if (DrvHead & IDE_DH_LBA)
IDEWriteCommand(DeviceExtension->CommandPortBase, Command);
/* Write data block */
+#ifdef ENABLE_MULTIMODE
+ if (Command == IDE_CMD_WRITE || Command == IDE_CMD_WRITE_MULTIPLE)
+#else
if (Command == IDE_CMD_WRITE)
+#endif
{
PUCHAR TargetAddress;
ULONG SectorSize;
}
/* Update SRB data */
- SectorSize = DeviceExtension->DeviceParams[Srb->TargetId].BytesPerSector;
+ SectorSize = DeviceParams->BytesPerSector;
+#ifdef ENABLE_MULTIMODE
+ if (DeviceParams->RWMultCurrent & 0xff)
+ {
+ SectorSize *= (DeviceParams->RWMultCurrent & 0xff);
+ }
+ if (Srb->DataTransferLength < SectorSize)
+ {
+ SectorSize = Srb->DataTransferLength;
+ }
+#endif
+
TargetAddress = Srb->DataBuffer;
Srb->DataBuffer += SectorSize;
Srb->DataTransferLength -= SectorSize;
/* Write data block */
+#ifdef ENABLE_32BIT
+ IDEWriteBlock32(DeviceExtension->CommandPortBase,
+ TargetAddress,
+ SectorSize);
+#else
IDEWriteBlock(DeviceExtension->CommandPortBase,
TargetAddress,
SectorSize);
+#endif
}
#define IDE_CMD_READ_RETRY 0x21
#define IDE_CMD_WRITE 0x30
#define IDE_CMD_WRITE_RETRY 0x31
+#define IDE_CMD_READ_MULTIPLE 0xC4
+#define IDE_CMD_WRITE_MULTIPLE 0xC5
#define IDE_CMD_IDENT_ATA_DRV 0xEC
#define IDE_CMD_IDENT_ATAPI_DRV 0xA1
//
#define IDEWriteBlock(Address, Buffer, Count) \
(ScsiPortWritePortBufferUshort((PUSHORT)((Address) + IDE_REG_DATA_PORT), (PUSHORT)(Buffer), (Count) / 2))
+#define IDEReadBlock32(Address, Buffer, Count) \
+ (ScsiPortReadPortBufferUlong((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
+#define IDEWriteBlock32(Address, Buffer, Count) \
+ (ScsiPortWritePortBufferUlong((PULONG)((Address) + IDE_REG_DATA_PORT), (PULONG)(Buffer), (Count) / 4))
//
// Access macros for control registers
// Each macro takes an address of the control port blank and data
WORD TMSectorsPerTrk; /*56*/
WORD TMCapacityLo; /*57*/
WORD TMCapacityHi; /*58*/
- WORD Reserved59; /*59*/
+ WORD RWMultCurrent; /*59*/
WORD TMSectorCountLo; /*60*/
WORD TMSectorCountHi; /*61*/
WORD Reserved62[193]; /*62*/