mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 16:02:56 +00:00
Fix the reset sequence in AtapiFindDevices to work correctly in VMware.
svn path=/trunk/; revision=10813
This commit is contained in:
parent
fb16e656c4
commit
9a4721af9c
1 changed files with 77 additions and 43 deletions
|
@ -16,7 +16,7 @@
|
|||
* 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.51 2004/09/03 04:44:45 navaraf Exp $
|
||||
/* $Id: atapi.c,v 1.52 2004/09/10 23:17:45 navaraf Exp $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS ATAPI miniport driver
|
||||
|
@ -56,7 +56,7 @@
|
|||
|
||||
#include "atapi.h"
|
||||
|
||||
#define NDEBUG
|
||||
//#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
#define VERSION "0.0.1"
|
||||
|
@ -294,7 +294,10 @@ AtapiErrorToScsi(PVOID DeviceExtension,
|
|||
PSCSI_REQUEST_BLOCK Srb);
|
||||
|
||||
static VOID
|
||||
AtapiScsiSrbToAtapi (PSCSI_REQUEST_BLOCK Srb);
|
||||
AtapiScsiSrbToAtapi(PSCSI_REQUEST_BLOCK Srb);
|
||||
|
||||
static BOOLEAN
|
||||
AtapiWaitForStatus(ULONG CommandPort, ULONG Mask, ULONG Value, ULONG Timeout);
|
||||
|
||||
// ---------------------------------------------------------------- Inlines
|
||||
|
||||
|
@ -1094,9 +1097,10 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
|||
ULONG CommandPortBase;
|
||||
ULONG ControlPortBase;
|
||||
ULONG UnitNumber;
|
||||
ULONG Retries;
|
||||
ULONG Status;
|
||||
UCHAR High;
|
||||
UCHAR Low;
|
||||
BOOL UnitPresent[2];
|
||||
|
||||
DPRINT("AtapiFindDevices() called\n");
|
||||
|
||||
|
@ -1109,51 +1113,65 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
|||
for (UnitNumber = 0; UnitNumber < 2; UnitNumber++)
|
||||
{
|
||||
/* Select drive */
|
||||
IDEWriteDriveHead(CommandPortBase,
|
||||
IDE_DH_FIXED | (UnitNumber ? IDE_DH_DRV1 : 0));
|
||||
IDEWriteDriveControl(ControlPortBase, 0);
|
||||
IDEWriteDriveHead(CommandPortBase, IDE_DH_FIXED |
|
||||
(UnitNumber ? IDE_DH_DRV1 : IDE_DH_DRV0));
|
||||
ScsiPortStallExecution(500);
|
||||
|
||||
/* Disable interrupts */
|
||||
IDEWriteDriveControl(ControlPortBase,
|
||||
IDE_DC_nIEN);
|
||||
ScsiPortStallExecution(500);
|
||||
|
||||
/* Check if a device is attached to the interface */
|
||||
IDEWriteCylinderHigh(CommandPortBase, 0xaa);
|
||||
IDEWriteCylinderLow(CommandPortBase, 0x55);
|
||||
|
||||
High = IDEReadCylinderHigh(CommandPortBase);
|
||||
Low = IDEReadCylinderLow(CommandPortBase);
|
||||
|
||||
IDEWriteCylinderHigh(CommandPortBase, 0);
|
||||
IDEWriteCylinderLow(CommandPortBase, 0);
|
||||
|
||||
UnitPresent[UnitNumber] = (Low == 0x55 || High == 0xaa);
|
||||
#ifndef NDEBUG
|
||||
if (Low != 0x55 || High != 0xaa)
|
||||
{
|
||||
DPRINT("No Drive found. UnitNumber %d CommandPortBase %x\n", UnitNumber, CommandPortBase);
|
||||
continue;
|
||||
}
|
||||
{
|
||||
DPRINT("No Drive found. UnitNumber %d CommandPortBase %x\n", UnitNumber, CommandPortBase);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Soft reset */
|
||||
IDEWriteDriveControl(ControlPortBase, IDE_DC_nIEN | IDE_DC_SRST);
|
||||
ScsiPortStallExecution(500);
|
||||
IDEWriteDriveControl(ControlPortBase, IDE_DC_nIEN);
|
||||
ScsiPortStallExecution(500);
|
||||
/* Check if any unit was found. */
|
||||
if (UnitPresent[0] == FALSE && UnitPresent[1] == FALSE)
|
||||
{
|
||||
DPRINT("No device found\n");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
for (Retries = 0; Retries < 20000; Retries++)
|
||||
{
|
||||
if (!(IDEReadStatus(CommandPortBase) & IDE_SR_BUSY))
|
||||
{
|
||||
break;
|
||||
}
|
||||
ScsiPortStallExecution(150);
|
||||
}
|
||||
if (Retries >= 20000)
|
||||
{
|
||||
DPRINT("Timeout on drive %lu\n", UnitNumber);
|
||||
DeviceExtension->DeviceFlags[UnitNumber] &= ~DEVICE_PRESENT;
|
||||
continue;
|
||||
}
|
||||
/* Soft reset */
|
||||
IDEWriteDriveHead(CommandPortBase, IDE_DH_FIXED);
|
||||
IDEWriteDriveControl(ControlPortBase, IDE_DC_SRST);
|
||||
ScsiPortStallExecution(500);
|
||||
IDEWriteDriveControl(ControlPortBase, IDE_DC_nIEN);
|
||||
ScsiPortStallExecution(200);
|
||||
|
||||
/* Wait for busy to clear */
|
||||
if (!AtapiWaitForStatus(CommandPortBase, IDE_SR_BUSY, 0, 20000))
|
||||
{
|
||||
DPRINT("Timeout on drive %lu\n", UnitNumber);
|
||||
return FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
Status = IDEReadStatus(DeviceExtension->CommandPortBase);
|
||||
if (Status & IDE_SR_ERR)
|
||||
{
|
||||
DPRINT("Error while doing software reset\n");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
for (UnitNumber = 0; UnitNumber < 2; UnitNumber++)
|
||||
{
|
||||
/* Skip initilization of non-existent units */
|
||||
if (!UnitPresent[UnitNumber])
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Select drive */
|
||||
IDEWriteDriveHead(CommandPortBase, IDE_DH_FIXED |
|
||||
(UnitNumber ? IDE_DH_DRV1 : IDE_DH_DRV0));
|
||||
|
||||
High = IDEReadCylinderHigh(CommandPortBase);
|
||||
Low = IDEReadCylinderLow(CommandPortBase);
|
||||
|
@ -1239,9 +1257,6 @@ AtapiFindDevices(PATAPI_MINIPORT_EXTENSION DeviceExtension,
|
|||
/* Reenable interrupts */
|
||||
IDEWriteDriveControl(ControlPortBase, 0);
|
||||
ScsiPortStallExecution(500);
|
||||
/* Return with drive 0 selected */
|
||||
IDEWriteDriveHead(CommandPortBase, IDE_DH_FIXED);
|
||||
ScsiPortStallExecution(500);
|
||||
|
||||
DPRINT("AtapiFindDrives() done (DeviceFound %s)\n", (DeviceFound) ? "TRUE" : "FALSE");
|
||||
|
||||
|
@ -3046,4 +3061,23 @@ AtapiInitDma(PATAPI_MINIPORT_EXTENSION DevExt,
|
|||
}
|
||||
#endif
|
||||
|
||||
static BOOLEAN
|
||||
AtapiWaitForStatus( ULONG CommandPort, ULONG Mask, ULONG Value, ULONG Timeout )
|
||||
{
|
||||
ULONG RetryCount, Status;
|
||||
|
||||
for (RetryCount = 0; RetryCount < Timeout; RetryCount++)
|
||||
{
|
||||
Status = IDEReadStatus(CommandPort);
|
||||
if ((Status & Mask) == Value)
|
||||
{
|
||||
return TRUE;
|
||||
}
|
||||
ScsiPortStallExecution(10);
|
||||
}
|
||||
DPRINT("status=%02x\n", Status);
|
||||
DPRINT("waited %ld usecs\n", RetryCount * 10);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue