ReactOS 0.4.15-dev-7961-gdcf9eb0
atapi.h File Reference
#include "config.h"
#include "scsi.h"
#include "stdio.h"
#include "string.h"
Include dependency graph for atapi.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

union  _IDE_REGISTERS_1
 
struct  _IDE_REGISTERS_1::_o
 
struct  _IDE_REGISTERS_1::_i
 
union  _IDE_REGISTERS_2
 
struct  _MODE_SENSE_10
 
struct  _MODE_SELECT_10
 
struct  _MODE_PARAMETER_HEADER_10
 
union  _ATAPI_REGISTERS_1
 
struct  _ATAPI_REGISTERS_1::_o
 
struct  _ATAPI_REGISTERS_1::_i
 
struct  _IDENTIFY_DATA
 
struct  _TRIM_DATA
 

Macros

#define PRINT_PREFIX   "UniATA: "
 
#define KdPrint3(_x_)   {;}
 
#define KdPrint2(_x_)   {;}
 
#define KdPrint(_x_)   {;}
 
#define Connect_DbgPrint()   {;}
 
#define AtapiStallExecution(dt)   ScsiPortStallExecution(dt)
 
#define IDX_IO1   0
 
#define IDX_IO1_SZ   sizeof(IDE_REGISTERS_1)
 
#define IDX_IO1   0
 
#define IDX_IO1_SZ   sizeof(IDE_REGISTERS_1)
 
#define IDX_IO1_i_Data   (FIELD_OFFSET(IDE_REGISTERS_1, i.Data )+IDX_IO1)
 
#define IDX_IO1_i_Error   (FIELD_OFFSET(IDE_REGISTERS_1, i.Error )+IDX_IO1)
 
#define IDX_IO1_i_BlockCount   (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockCount )+IDX_IO1)
 
#define IDX_IO1_i_BlockNumber   (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockNumber )+IDX_IO1)
 
#define IDX_IO1_i_CylinderLow   (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderLow )+IDX_IO1)
 
#define IDX_IO1_i_CylinderHigh   (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderHigh)+IDX_IO1)
 
#define IDX_IO1_i_DriveSelect   (FIELD_OFFSET(IDE_REGISTERS_1, i.DriveSelect )+IDX_IO1)
 
#define IDX_IO1_i_Status   (FIELD_OFFSET(IDE_REGISTERS_1, i.Status )+IDX_IO1)
 
#define IDX_IO1_o   IDX_IO1_SZ
 
#define IDX_IO1_o_SZ   sizeof(IDE_REGISTERS_1)
 
#define IDX_IO1_o_Data   (FIELD_OFFSET(IDE_REGISTERS_1, o.Data )+IDX_IO1_o)
 
#define IDX_IO1_o_Feature   (FIELD_OFFSET(IDE_REGISTERS_1, o.Feature )+IDX_IO1_o)
 
#define IDX_IO1_o_BlockCount   (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockCount )+IDX_IO1_o)
 
#define IDX_IO1_o_BlockNumber   (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockNumber )+IDX_IO1_o)
 
#define IDX_IO1_o_CylinderLow   (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderLow )+IDX_IO1_o)
 
#define IDX_IO1_o_CylinderHigh   (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderHigh)+IDX_IO1_o)
 
#define IDX_IO1_o_DriveSelect   (FIELD_OFFSET(IDE_REGISTERS_1, o.DriveSelect )+IDX_IO1_o)
 
#define IDX_IO1_o_Command   (FIELD_OFFSET(IDE_REGISTERS_1, o.Command )+IDX_IO1_o)
 
#define IDX_IO2   (IDX_IO1_o+IDX_IO1_o_SZ)
 
#define IDX_IO2_SZ   sizeof(IDE_REGISTERS_2)
 
#define IDX_IO2_AltStatus   (FIELD_OFFSET(IDE_REGISTERS_2, AltStatus )+IDX_IO2)
 
#define IDX_IO2_o   (IDX_IO2+IDX_IO2_SZ)
 
#define IDX_IO2_o_SZ   sizeof(IDE_REGISTERS_2)
 
#define IDX_IO2_o_Control   (FIELD_OFFSET(IDE_REGISTERS_2, Control)+IDX_IO2_o)
 
#define DFLAGS_DEVICE_PRESENT   0x0001
 
#define DFLAGS_ATAPI_DEVICE   0x0002
 
#define DFLAGS_TAPE_DEVICE   0x0004
 
#define DFLAGS_INT_DRQ   0x0008
 
#define DFLAGS_REMOVABLE_DRIVE   0x0010
 
#define DFLAGS_MEDIA_STATUS_ENABLED   0x0020
 
#define DFLAGS_ATAPI_CHANGER   0x0040
 
#define DFLAGS_SANYO_ATAPI_CHANGER   0x0080
 
#define DFLAGS_CHANGER_INITED   0x0100
 
#define DFLAGS_LBA_ENABLED   0x0200
 
#define DFLAGS_DWORDIO_ENABLED   0x0400
 
#define DFLAGS_WCACHE_ENABLED   0x0800
 
#define DFLAGS_RCACHE_ENABLED   0x1000
 
#define DFLAGS_ORIG_GEOMETRY   0x2000
 
#define DFLAGS_REINIT_DMA   0x4000
 
#define DFLAGS_HIDDEN   0x8000
 
#define DFLAGS_MANUAL_CHS   0x10000
 
#define DFLAGS_LBA32plus   0x20000
 
#define MAX_ERRORS   4
 
#define ATAPI_MODE_SENSE   0x5A
 
#define ATAPI_MODE_SELECT   0x55
 
#define ATAPI_FORMAT_UNIT   0x24
 
#define ATA_PIO   0x00
 
#define ATA_PIO_NRDY   0x01
 
#define ATA_PIO0   0x08
 
#define ATA_PIO1   0x09
 
#define ATA_PIO2   0x0a
 
#define ATA_PIO3   0x0b
 
#define ATA_PIO4   0x0c
 
#define ATA_PIO5   0x0d
 
#define ATA_DMA   0x10
 
#define ATA_SDMA   0x10
 
#define ATA_SDMA0   0x10
 
#define ATA_SDMA1   0x11
 
#define ATA_SDMA2   0x12
 
#define ATA_WDMA   0x20
 
#define ATA_WDMA0   0x20
 
#define ATA_WDMA1   0x21
 
#define ATA_WDMA2   0x22
 
#define ATA_UDMA   0x40
 
#define ATA_UDMA0   0x40
 
#define ATA_UDMA1   0x41
 
#define ATA_UDMA2   0x42
 
#define ATA_UDMA3   0x43
 
#define ATA_UDMA4   0x44
 
#define ATA_UDMA5   0x45
 
#define ATA_UDMA6   0x46
 
#define ATA_SA150   0x47 /*0x80*/
 
#define ATA_SA300   0x48 /*0x81*/
 
#define ATA_SA600   0x49 /*0x82*/
 
#define ATA_MODE_NOT_SPEC   ((ULONG)(-1)) /*0x82*/
 
#define IDE_COMMAND_DATA_SET_MGMT   0x06
 
#define IDE_COMMAND_ATAPI_RESET   0x08
 
#define IDE_COMMAND_RECALIBRATE   0x10
 
#define IDE_COMMAND_READ   0x20
 
#define IDE_COMMAND_READ_NO_RETR   0x21
 
#define IDE_COMMAND_READ48   0x24
 
#define IDE_COMMAND_READ_DMA48   0x25
 
#define IDE_COMMAND_READ_DMA_Q48   0x26
 
#define IDE_COMMAND_READ_NATIVE_SIZE48   0x27
 
#define IDE_COMMAND_READ_MUL48   0x29
 
#define IDE_COMMAND_READ_STREAM_DMA48   0x2A
 
#define IDE_COMMAND_READ_STREAM48   0x2B
 
#define IDE_COMMAND_READ_LOG48   0x2f
 
#define IDE_COMMAND_WRITE   0x30
 
#define IDE_COMMAND_WRITE_NO_RETR   0x31
 
#define IDE_COMMAND_WRITE48   0x34
 
#define IDE_COMMAND_WRITE_DMA48   0x35
 
#define IDE_COMMAND_WRITE_DMA_Q48   0x36
 
#define IDE_COMMAND_SET_NATIVE_SIZE48   0x37
 
#define IDE_COMMAND_WRITE_MUL48   0x39
 
#define IDE_COMMAND_WRITE_STREAM_DMA48   0x3a
 
#define IDE_COMMAND_WRITE_STREAM48   0x3b
 
#define IDE_COMMAND_WRITE_FUA_DMA48   0x3d
 
#define IDE_COMMAND_WRITE_FUA_DMA_Q48   0x3e
 
#define IDE_COMMAND_WRITE_LOG48   0x3f
 
#define IDE_COMMAND_VERIFY   0x40
 
#define IDE_COMMAND_VERIFY48   0x42
 
#define IDE_COMMAND_READ_LOG_DMA48   0x47
 
#define IDE_COMMAND_WRITE_LOG_DMA48   0x57
 
#define IDE_COMMAND_TRUSTED_RCV   0x5c
 
#define IDE_COMMAND_TRUSTED_RCV_DMA   0x5d
 
#define IDE_COMMAND_TRUSTED_SEND   0x5e
 
#define IDE_COMMAND_TRUSTED_SEND_DMA   0x5f
 
#define IDE_COMMAND_SEEK   0x70
 
#define IDE_COMMAND_SET_DRIVE_PARAMETERS   0x91
 
#define IDE_COMMAND_ATAPI_PACKET   0xA0
 
#define IDE_COMMAND_ATAPI_IDENTIFY   0xA1
 
#define IDE_COMMAND_READ_MULTIPLE   0xC4
 
#define IDE_COMMAND_WRITE_MULTIPLE   0xC5
 
#define IDE_COMMAND_SET_MULTIPLE   0xC6
 
#define IDE_COMMAND_READ_DMA_Q   0xC7
 
#define IDE_COMMAND_READ_DMA   0xC8
 
#define IDE_COMMAND_WRITE_DMA   0xCA
 
#define IDE_COMMAND_WRITE_DMA_Q   0xCC
 
#define IDE_COMMAND_WRITE_MUL_FUA48   0xCE
 
#define IDE_COMMAND_GET_MEDIA_STATUS   0xDA
 
#define IDE_COMMAND_DOOR_LOCK   0xDE
 
#define IDE_COMMAND_DOOR_UNLOCK   0xDF
 
#define IDE_COMMAND_STANDBY_IMMED   0xE0
 
#define IDE_COMMAND_IDLE_IMMED   0xE1
 
#define IDE_COMMAND_STANDBY   0xE2
 
#define IDE_COMMAND_IDLE   0xE3
 
#define IDE_COMMAND_READ_PM   0xE4
 
#define IDE_COMMAND_SLEEP   0xE6
 
#define IDE_COMMAND_FLUSH_CACHE   0xE7
 
#define IDE_COMMAND_WRITE_PM   0xE8
 
#define IDE_COMMAND_IDENTIFY   0xEC
 
#define IDE_COMMAND_MEDIA_EJECT   0xED
 
#define IDE_COMMAND_FLUSH_CACHE48   0xEA
 
#define IDE_COMMAND_ENABLE_MEDIA_STATUS   0xEF
 
#define IDE_COMMAND_SET_FEATURES
 
#define IDE_COMMAND_READ_NATIVE_SIZE   0xF8
 
#define IDE_COMMAND_SET_NATIVE_SIZE   0xF9
 
#define SCSIOP_ATA_PASSTHROUGH   0xCC
 
#define IDE_STATUS_SUCCESS   0x00
 
#define IDE_STATUS_ERROR   0x01
 
#define IDE_STATUS_INDEX   0x02
 
#define IDE_STATUS_CORRECTED_ERROR   0x04
 
#define IDE_STATUS_DRQ   0x08
 
#define IDE_STATUS_DSC   0x10
 
#define IDE_STATUS_DMA   0x20 /* DMA ready */
 
#define IDE_STATUS_DWF   0x20 /* drive write fault */
 
#define IDE_STATUS_DRDY   0x40
 
#define IDE_STATUS_IDLE   0x50
 
#define IDE_STATUS_BUSY   0x80
 
#define IDE_STATUS_WRONG   0xff
 
#define IDE_STATUS_MASK   0xff
 
#define IDE_DRIVE_SELECT   0xA0
 
#define IDE_DRIVE_1   0x00
 
#define IDE_DRIVE_2   0x10
 
#define IDE_DRIVE_SELECT_1   (IDE_DRIVE_SELECT | IDE_DRIVE_1)
 
#define IDE_DRIVE_SELECT_2   (IDE_DRIVE_SELECT | IDE_DRIVE_2)
 
#define IDE_DRIVE_MASK   (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2)
 
#define IDE_USE_LBA   0x40
 
#define IDE_DC_DISABLE_INTERRUPTS   0x02
 
#define IDE_DC_RESET_CONTROLLER   0x04
 
#define IDE_DC_A_4BIT   0x80
 
#define IDE_DC_USE_HOB   0x80
 
#define IDE_DC_REENABLE_CONTROLLER   0x00
 
#define IDE_ERROR_ICRC   0x80
 
#define IDE_ERROR_BAD_BLOCK   0x80
 
#define IDE_ERROR_DATA_ERROR   0x40
 
#define IDE_ERROR_MEDIA_CHANGE   0x20
 
#define IDE_ERROR_ID_NOT_FOUND   0x10
 
#define IDE_ERROR_MEDIA_CHANGE_REQ   0x08
 
#define IDE_ERROR_COMMAND_ABORTED   0x04
 
#define IDE_ERROR_END_OF_MEDIA   0x02
 
#define IDE_ERROR_NO_MEDIA   0x02
 
#define IDE_ERROR_ILLEGAL_LENGTH   0x01
 
#define IDX_ATAPI_IO1   IDX_IO1
 
#define IDX_ATAPI_IO1_SZ   sizeof(ATAPI_REGISTERS_1)
 
#define IDX_ATAPI_IO1_i_Data   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Data )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_i_Error   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Error )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_i_InterruptReason   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.InterruptReason)+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_i_Unused1   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Unused1 )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_i_ByteCountLow   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountLow )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_i_ByteCountHigh   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountHigh )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_i_DriveSelect   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.DriveSelect )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_i_Status   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Status )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_Data   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Data )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_Feature   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Feature )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_Unused0   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused0 )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_Unused1   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused1 )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_ByteCountLow   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountLow )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_ByteCountHigh   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountHigh)+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_DriveSelect   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.DriveSelect )+IDX_ATAPI_IO1)
 
#define IDX_ATAPI_IO1_o_Command   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Command )+IDX_ATAPI_IO1)
 
#define ATAPI_IR_COD   0x01
 
#define ATAPI_IR_COD_Data   0x0
 
#define ATAPI_IR_COD_Cmd   0x1
 
#define ATAPI_IR_IO   0x02
 
#define ATAPI_IR_IO_toDev   0x00
 
#define ATAPI_IR_IO_toHost   0x02
 
#define ATAPI_IR_Mask   0x03
 
#define ATA_F_DMA   0x01 /* enable DMA */
 
#define ATA_F_OVL   0x02 /* enable overlap */
 
#define ATA_F_DMAREAD   0x04 /* DMA Packet (ATAPI) read */
 
#define ATA_C_F_SETXFER   0x03 /* set transfer mode */
 
#define ATA_C_F_ENAB_WCACHE   0x02 /* enable write cache */
 
#define ATA_C_F_DIS_WCACHE   0x82 /* disable write cache */
 
#define ATA_C_F_ENAB_RCACHE   0xaa /* enable readahead cache */
 
#define ATA_C_F_DIS_RCACHE   0x55 /* disable readahead cache */
 
#define ATA_C_F_ENAB_RELIRQ   0x5d /* enable release interrupt */
 
#define ATA_C_F_DIS_RELIRQ   0xdd /* disable release interrupt */
 
#define ATA_C_F_ENAB_SRVIRQ   0x5e /* enable service interrupt */
 
#define ATA_C_F_DIS_SRVIRQ   0xde /* disable service interrupt */
 
#define ATA_C_F_ENAB_MEDIASTAT   0x95 /* enable media status */
 
#define ATA_C_F_DIS_MEDIASTAT   0x31 /* disable media status */
 
#define ATA_C_F_ENAB_APM   0x05 /* enable advanced power management */
 
#define ATA_C_F_DIS_APM   0x85 /* disable advanced power management */
 
#define ATA_C_F_APM_CNT_MAX_PERF   0xfe /* maximum performance */
 
#define ATA_C_F_APM_CNT_MIN_NO_STANDBY   0x80 /* min. power w/o standby */
 
#define ATA_C_F_APM_CNT_MIN_STANDBY   0x01 /* min. power with standby */
 
#define ATA_C_F_ENAB_ACOUSTIC   0x42 /* enable acoustic management */
 
#define ATA_C_F_DIS_ACOUSTIC   0xc2 /* disable acoustic management */
 
#define ATA_C_F_AAM_CNT_MAX_PERF   0xfe /* maximum performance */
 
#define ATA_C_F_AAM_CNT_MAX_POWER_SAVE   0x80 /* min. power */
 
#define READ_LOG_SECTOR   0xD5
 
#define WRITE_LOG_SECTOR   0xD6
 
#define WRITE_THRESHOLDS   0xD7
 
#define AUTO_OFFLINE   0xDB
 
#define ATA_I_CMD   0x01 /* cmd (1) | data (0) */
 
#define ATA_I_IN   0x02 /* read (1) | write (0) */
 
#define ATA_I_RELEASE   0x04 /* released bus (1) */
 
#define ATA_I_TAGMASK   0xf8 /* tag mask */
 
#define ATAPI_PSIZE_12   0 /* 12 bytes */
 
#define ATAPI_PSIZE_16   1 /* 16 bytes */
 
#define ATAPI_DRQT_MPROC   0 /* cpu 3 ms delay */
 
#define ATAPI_DRQT_INTR   1 /* intr 10 ms delay */
 
#define ATAPI_DRQT_ACCEL   2 /* accel 50 us delay */
 
#define ATAPI_TYPE_DIRECT   0 /* disk/floppy */
 
#define ATAPI_TYPE_TAPE   1 /* streaming tape */
 
#define ATAPI_TYPE_CDROM   5 /* CD-ROM device */
 
#define ATAPI_TYPE_OPTICAL   7 /* optical disk */
 
#define ATAPI_PROTO_ATAPI   2
 
#define ATA_BT_SINGLEPORTSECTOR   1 /* 1 port, 1 sector buffer */
 
#define ATA_BT_DUALPORTMULTI   2 /* 2 port, mult sector buffer */
 
#define ATA_BT_DUALPORTMULTICACHE   3 /* above plus track cache */
 
#define AdvancedPIOModes_3   1
 
#define AdvancedPIOModes_4   2
 
#define AdvancedPIOModes_5   4
 
#define ATA_SATA_GEN1   0x0002
 
#define ATA_SATA_GEN2   0x0004
 
#define ATA_SATA_GEN3   0x0008
 
#define ATA_SUPPORT_NCQ   0x0100
 
#define ATA_SUPPORT_IFPWRMNGTRCV   0x0200
 
#define ATA_SUPPORT_PHY_EVENT_COUNTER   0x0400
 
#define ATA_SUPPORT_NCQ_UNLOAD   0x0800
 
#define ATA_SUPPORT_NCQ_PRI_INFO   0x1000
 
#define ATA_SUPPORT_NONZERO   0x0002
 
#define ATA_SUPPORT_AUTOACTIVATE   0x0004
 
#define ATA_SUPPORT_IFPWRMNGT   0x0008
 
#define ATA_SUPPORT_INORDERDATA   0x0010
 
#define ATA_VER_MJ_ATA4   0x0010
 
#define ATA_VER_MJ_ATA5   0x0020
 
#define ATA_VER_MJ_ATA6   0x0040
 
#define ATA_VER_MJ_ATA7   0x0080
 
#define ATA_VER_MJ_ATA8_ASC   0x0100
 
#define IDENTIFY_CABLE_ID_VALID   0x01
 
#define ATA_ChecksumValid   0xA5
 
#define IDENTIFY_DATA2   IDENTIFY_DATA
 
#define PIDENTIFY_DATA2   PIDENTIFY_DATA
 
#define IDENTIFY_DATA_SIZE   sizeof(IDENTIFY_DATA)
 
#define IDENTIFY_DMA_CYCLES_MODE_0   0x00
 
#define IDENTIFY_DMA_CYCLES_MODE_1   0x01
 
#define IDENTIFY_DMA_CYCLES_MODE_2   0x02
 
#define GetStatus(chan, Status)    Status = AtapiReadPort1(chan, IDX_IO2_AltStatus);
 
#define GetBaseStatus(chan, pStatus)    pStatus = AtapiReadPort1(chan, IDX_IO1_i_Status);
 
#define WriteCommand(chan, _Command)    AtapiWritePort1(chan, IDX_IO1_o_Command, _Command);
 
#define ReadBuffer(chan, Buffer, Count, timing)
 
#define WriteBuffer(chan, Buffer, Count, timing)
 
#define ReadBuffer2(chan, Buffer, Count, timing)
 
#define WriteBuffer2(chan, Buffer, Count, timing)
 
#define IS_RDP(OperationCode)
 
#define AtapiCopyMemory   RtlCopyMemory
 
#define AtapiStringCmp(s1, s2, n)   _strnicmp(s1, s2, n)
 
#define INTERRUPT_REASON_IGNORE   0
 
#define INTERRUPT_REASON_OUR   1
 
#define INTERRUPT_REASON_UNEXPECTED   2
 
#define UNIATA_FIND_DEV_UNHIDE   0x01
 
#define CHAN_NOT_SPECIFIED   (0xffffffffL)
 
#define CHAN_NOT_SPECIFIED_CHECK_CABLE   (0xfffffffeL)
 
#define DEVNUM_NOT_SPECIFIED   (0xffffffffL)
 
#define IOMODE_NOT_SPECIFIED   (0xffffffffL)
 
#define ATA_AT_HOME_HDD   0x01
 
#define ATA_AT_HOME_ATAPI   0x02
 
#define ATA_AT_HOME_XXX   0x04
 
#define ATA_AT_HOME_NOBODY   0x00
 
#define ATA_CMD_FLAG_LBAIOsupp   0x01
 
#define ATA_CMD_FLAG_48supp   0x02
 
#define ATA_CMD_FLAG_48   0x04
 
#define ATA_CMD_FLAG_DMA   0x08
 
#define ATA_CMD_FLAG_FUA   0x10
 
#define ATA_CMD_FLAG_In   0x40
 
#define ATA_CMD_FLAG_Out   0x80
 
#define UniAta_need_lba48(command, lba, count, supp48)
 
#define UniAtaClearAtaReq(AtaReq)
 
#define ATAPI_DEVICE(chan, dev)   ((chan->lun[dev]->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE)
 
#define PrintNtConsole(x)   {;}
 
#define IDENT_MODE_MAX   FALSE
 
#define IDENT_MODE_ACTIVE   TRUE
 

Typedefs

typedef union _IDE_REGISTERS_1 IDE_REGISTERS_1
 
typedef union _IDE_REGISTERS_1PIDE_REGISTERS_1
 
typedef union _IDE_REGISTERS_2 IDE_REGISTERS_2
 
typedef union _IDE_REGISTERS_2PIDE_REGISTERS_2
 
typedef struct _MODE_SENSE_10 MODE_SENSE_10
 
typedef struct _MODE_SENSE_10PMODE_SENSE_10
 
typedef struct _MODE_SELECT_10 MODE_SELECT_10
 
typedef struct _MODE_SELECT_10PMODE_SELECT_10
 
typedef struct _MODE_PARAMETER_HEADER_10 MODE_PARAMETER_HEADER_10
 
typedef struct _MODE_PARAMETER_HEADER_10PMODE_PARAMETER_HEADER_10
 
typedef union _ATAPI_REGISTERS_1 ATAPI_REGISTERS_1
 
typedef union _ATAPI_REGISTERS_1PATAPI_REGISTERS_1
 
typedef struct _IDENTIFY_DATA IDENTIFY_DATA
 
typedef struct _IDENTIFY_DATAPIDENTIFY_DATA
 
typedef struct _TRIM_DATA TRIM_DATA
 
typedef struct _TRIM_DATAPTRIM_DATA
 

Functions

UCHAR DDKFASTAPI SelectDrive (IN struct _HW_CHANNEL *chan, IN ULONG DeviceNumber)
 
UCHAR DDKFASTAPI WaitOnBusy (IN struct _HW_CHANNEL *chan)
 
UCHAR DDKFASTAPI WaitOnBusyLong (IN struct _HW_CHANNEL *chan)
 
UCHAR DDKFASTAPI WaitOnBaseBusy (IN struct _HW_CHANNEL *chan)
 
UCHAR DDKFASTAPI WaitOnBaseBusyLong (IN struct _HW_CHANNEL *chan)
 
UCHAR DDKFASTAPI WaitForDrq (IN struct _HW_CHANNEL *chan)
 
UCHAR DDKFASTAPI WaitShortForDrq (IN struct _HW_CHANNEL *chan)
 
VOID DDKFASTAPI AtapiSoftReset (IN struct _HW_CHANNEL *chan, IN ULONG DeviceNumber)
 
VOID DDKFASTAPI AtapiHardReset (IN struct _HW_CHANNEL *chan, IN BOOLEAN DisableInterrupts, IN ULONG Delay)
 
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI AtapiHwInitializeChanger (IN PVOID HwDeviceExtension, IN ULONG TargetId, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
 
ULONG NTAPI AtapiSendCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
 
ULONG NTAPI IdeSendCommand (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
 
VOID NTAPI AtapiHexToString (ULONG Value, PCHAR *Buffer)
 
BOOLEAN NTAPI AtapiInterrupt (IN PVOID HwDeviceExtension)
 
BOOLEAN NTAPI AtapiInterrupt__ (IN PVOID HwDeviceExtension, IN UCHAR c)
 
UCHAR NTAPI AtapiCheckInterrupt__ (IN PVOID HwDeviceExtension, IN UCHAR c)
 
BOOLEAN NTAPI AtapiHwInitialize (IN PVOID HwDeviceExtension)
 
ULONG NTAPI IdeBuildSenseBuffer (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
VOID NTAPI IdeMediaStatus (BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
 
ULONG NTAPI AtapiFindIsaController (IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
 
ULONG NTAPI AtapiReadArgumentString (IN PVOID HwDeviceExtension, IN PVOID Context, IN PVOID BusInformation, IN PCHAR ArgumentString, IN OUT PPORT_CONFIGURATION_INFORMATION ConfigInfo, OUT PBOOLEAN Again)
 
ULONG NTAPI AtapiParseArgumentString (IN PCCH String, IN PCCH KeyWord)
 
BOOLEAN NTAPI IssueIdentify (IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR Command, IN BOOLEAN NoSetup)
 
BOOLEAN NTAPI SetDriveParameters (IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel)
 
ULONG NTAPI CheckDevice (IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber, IN BOOLEAN ResetBus)
 
BOOLEAN NTAPI FindDevices (IN PVOID HwDeviceExtension, IN ULONG Flags, IN ULONG Channel)
 
BOOLEAN NTAPI AtapiResetController (IN PVOID HwDeviceExtension, IN ULONG PathId)
 
BOOLEAN NTAPI AtapiStartIo (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
 
BOOLEAN NTAPI AtapiStartIo__ (IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN BOOLEAN TopLevel)
 
UCHAR NTAPI AtaCommand48 (IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature, IN ULONG flags)
 
UCHAR NTAPI AtaCommand (IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR command, IN USHORT cylinder, IN UCHAR head, IN UCHAR sector, IN UCHAR count, IN UCHAR feature, IN ULONG flags)
 
LONG NTAPI AtaPioMode (PIDENTIFY_DATA2 ident)
 
LONG NTAPI AtaWmode (PIDENTIFY_DATA2 ident)
 
LONG NTAPI AtaUmode (PIDENTIFY_DATA2 ident)
 
VOID NTAPI AtapiDpcDispatch (IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
 
LONG NTAPI AtaPio2Mode (LONG pio)
 
VOID NTAPI AtapiEnableInterrupts (IN PVOID HwDeviceExtension, IN ULONG c)
 
VOID NTAPI AtapiDisableInterrupts (IN PVOID HwDeviceExtension, IN ULONG c)
 
VOID UniataExpectChannelInterrupt (IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
 
ULONG NTAPI AtapiRegCheckDevValue (IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
 
ULONG NTAPI AtapiRegCheckParameterValue (IN PVOID HwDeviceExtension, IN PCWSTR PathSuffix, IN PCWSTR Name, IN ULONG Default)
 
VOID _cdecl _PrintNtConsole (PCCH DebugMessage,...)
 
VOID NTAPI UniataInitMapBM (IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN struct _IDE_BUSMASTER_REGISTERS *BaseIoAddressBM_0, IN BOOLEAN MemIo)
 
VOID NTAPI UniataInitMapBase (IN struct _HW_CHANNEL *chan, IN PIDE_REGISTERS_1 BaseIoAddress1, IN PIDE_REGISTERS_2 BaseIoAddress2)
 
VOID NTAPI UniataInitSyncBaseIO (IN struct _HW_CHANNEL *chan)
 
VOID UniataInitIoRes (IN struct _HW_CHANNEL *chan, IN ULONG idx, IN ULONG addr, IN BOOLEAN MemIo, IN BOOLEAN Proc)
 
VOID UniataInitIoResEx (IN struct _IORES *IoRes, IN ULONG addr, IN BOOLEAN MemIo, IN BOOLEAN Proc)
 
UCHAR DDKFASTAPI UniataIsIdle (IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN UCHAR Status)
 
VOID NTAPI UniataDumpATARegs (IN struct _HW_CHANNEL *chan)
 
ULONG NTAPI EncodeVendorStr (OUT PWCHAR Buffer, IN PUCHAR Str, IN ULONG Length)
 
ULONGLONG NTAPI UniAtaCalculateLBARegsBack (struct _HW_LU_EXTENSION *LunExt, ULONGLONG lba)
 
ULONG NTAPI UniataAnybodyHome (IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber)
 
__inline BOOLEAN ata_is_sata (PIDENTIFY_DATA ident)
 
__inline LONG ata_cur_mode_from_ident (PIDENTIFY_DATA ident, BOOLEAN Active)
 

Variables

ULONG g_LogToDisplay
 
UCHAR const AtaCommands48 [256]
 
UCHAR const AtaCommandFlags [256]
 

Macro Definition Documentation

◆ AdvancedPIOModes_3

#define AdvancedPIOModes_3   1

Definition at line 726 of file atapi.h.

◆ AdvancedPIOModes_4

#define AdvancedPIOModes_4   2

Definition at line 727 of file atapi.h.

◆ AdvancedPIOModes_5

#define AdvancedPIOModes_5   4

Definition at line 728 of file atapi.h.

◆ ATA_AT_HOME_ATAPI

#define ATA_AT_HOME_ATAPI   0x02

Definition at line 1593 of file atapi.h.

◆ ATA_AT_HOME_HDD

#define ATA_AT_HOME_HDD   0x01

Definition at line 1592 of file atapi.h.

◆ ATA_AT_HOME_NOBODY

#define ATA_AT_HOME_NOBODY   0x00

Definition at line 1595 of file atapi.h.

◆ ATA_AT_HOME_XXX

#define ATA_AT_HOME_XXX   0x04

Definition at line 1594 of file atapi.h.

◆ ATA_BT_DUALPORTMULTI

#define ATA_BT_DUALPORTMULTI   2 /* 2 port, mult sector buffer */

Definition at line 642 of file atapi.h.

◆ ATA_BT_DUALPORTMULTICACHE

#define ATA_BT_DUALPORTMULTICACHE   3 /* above plus track cache */

Definition at line 643 of file atapi.h.

◆ ATA_BT_SINGLEPORTSECTOR

#define ATA_BT_SINGLEPORTSECTOR   1 /* 1 port, 1 sector buffer */

Definition at line 641 of file atapi.h.

◆ ATA_C_F_AAM_CNT_MAX_PERF

#define ATA_C_F_AAM_CNT_MAX_PERF   0xfe /* maximum performance */

Definition at line 586 of file atapi.h.

◆ ATA_C_F_AAM_CNT_MAX_POWER_SAVE

#define ATA_C_F_AAM_CNT_MAX_POWER_SAVE   0x80 /* min. power */

Definition at line 587 of file atapi.h.

◆ ATA_C_F_APM_CNT_MAX_PERF

#define ATA_C_F_APM_CNT_MAX_PERF   0xfe /* maximum performance */

Definition at line 580 of file atapi.h.

◆ ATA_C_F_APM_CNT_MIN_NO_STANDBY

#define ATA_C_F_APM_CNT_MIN_NO_STANDBY   0x80 /* min. power w/o standby */

Definition at line 581 of file atapi.h.

◆ ATA_C_F_APM_CNT_MIN_STANDBY

#define ATA_C_F_APM_CNT_MIN_STANDBY   0x01 /* min. power with standby */

Definition at line 582 of file atapi.h.

◆ ATA_C_F_DIS_ACOUSTIC

#define ATA_C_F_DIS_ACOUSTIC   0xc2 /* disable acoustic management */

Definition at line 585 of file atapi.h.

◆ ATA_C_F_DIS_APM

#define ATA_C_F_DIS_APM   0x85 /* disable advanced power management */

Definition at line 579 of file atapi.h.

◆ ATA_C_F_DIS_MEDIASTAT

#define ATA_C_F_DIS_MEDIASTAT   0x31 /* disable media status */

Definition at line 576 of file atapi.h.

◆ ATA_C_F_DIS_RCACHE

#define ATA_C_F_DIS_RCACHE   0x55 /* disable readahead cache */

Definition at line 567 of file atapi.h.

◆ ATA_C_F_DIS_RELIRQ

#define ATA_C_F_DIS_RELIRQ   0xdd /* disable release interrupt */

Definition at line 570 of file atapi.h.

◆ ATA_C_F_DIS_SRVIRQ

#define ATA_C_F_DIS_SRVIRQ   0xde /* disable service interrupt */

Definition at line 573 of file atapi.h.

◆ ATA_C_F_DIS_WCACHE

#define ATA_C_F_DIS_WCACHE   0x82 /* disable write cache */

Definition at line 564 of file atapi.h.

◆ ATA_C_F_ENAB_ACOUSTIC

#define ATA_C_F_ENAB_ACOUSTIC   0x42 /* enable acoustic management */

Definition at line 584 of file atapi.h.

◆ ATA_C_F_ENAB_APM

#define ATA_C_F_ENAB_APM   0x05 /* enable advanced power management */

Definition at line 578 of file atapi.h.

◆ ATA_C_F_ENAB_MEDIASTAT

#define ATA_C_F_ENAB_MEDIASTAT   0x95 /* enable media status */

Definition at line 575 of file atapi.h.

◆ ATA_C_F_ENAB_RCACHE

#define ATA_C_F_ENAB_RCACHE   0xaa /* enable readahead cache */

Definition at line 566 of file atapi.h.

◆ ATA_C_F_ENAB_RELIRQ

#define ATA_C_F_ENAB_RELIRQ   0x5d /* enable release interrupt */

Definition at line 569 of file atapi.h.

◆ ATA_C_F_ENAB_SRVIRQ

#define ATA_C_F_ENAB_SRVIRQ   0x5e /* enable service interrupt */

Definition at line 572 of file atapi.h.

◆ ATA_C_F_ENAB_WCACHE

#define ATA_C_F_ENAB_WCACHE   0x02 /* enable write cache */

Definition at line 563 of file atapi.h.

◆ ATA_C_F_SETXFER

#define ATA_C_F_SETXFER   0x03 /* set transfer mode */

Definition at line 561 of file atapi.h.

◆ ATA_ChecksumValid

#define ATA_ChecksumValid   0xA5

Definition at line 978 of file atapi.h.

◆ ATA_CMD_FLAG_48

#define ATA_CMD_FLAG_48   0x04

Definition at line 1599 of file atapi.h.

◆ ATA_CMD_FLAG_48supp

#define ATA_CMD_FLAG_48supp   0x02

Definition at line 1598 of file atapi.h.

◆ ATA_CMD_FLAG_DMA

#define ATA_CMD_FLAG_DMA   0x08

Definition at line 1600 of file atapi.h.

◆ ATA_CMD_FLAG_FUA

#define ATA_CMD_FLAG_FUA   0x10

Definition at line 1601 of file atapi.h.

◆ ATA_CMD_FLAG_In

#define ATA_CMD_FLAG_In   0x40

Definition at line 1602 of file atapi.h.

◆ ATA_CMD_FLAG_LBAIOsupp

#define ATA_CMD_FLAG_LBAIOsupp   0x01

Definition at line 1597 of file atapi.h.

◆ ATA_CMD_FLAG_Out

#define ATA_CMD_FLAG_Out   0x80

Definition at line 1603 of file atapi.h.

◆ ATA_DMA

#define ATA_DMA   0x10

Definition at line 316 of file atapi.h.

◆ ATA_F_DMA

#define ATA_F_DMA   0x01 /* enable DMA */

Definition at line 557 of file atapi.h.

◆ ATA_F_DMAREAD

#define ATA_F_DMAREAD   0x04 /* DMA Packet (ATAPI) read */

Definition at line 559 of file atapi.h.

◆ ATA_F_OVL

#define ATA_F_OVL   0x02 /* enable overlap */

Definition at line 558 of file atapi.h.

◆ ATA_I_CMD

#define ATA_I_CMD   0x01 /* cmd (1) | data (0) */

Definition at line 601 of file atapi.h.

◆ ATA_I_IN

#define ATA_I_IN   0x02 /* read (1) | write (0) */

Definition at line 602 of file atapi.h.

◆ ATA_I_RELEASE

#define ATA_I_RELEASE   0x04 /* released bus (1) */

Definition at line 603 of file atapi.h.

◆ ATA_I_TAGMASK

#define ATA_I_TAGMASK   0xf8 /* tag mask */

Definition at line 604 of file atapi.h.

◆ ATA_MODE_NOT_SPEC

#define ATA_MODE_NOT_SPEC   ((ULONG)(-1)) /*0x82*/

Definition at line 341 of file atapi.h.

◆ ATA_PIO

#define ATA_PIO   0x00

Definition at line 306 of file atapi.h.

◆ ATA_PIO0

#define ATA_PIO0   0x08

Definition at line 309 of file atapi.h.

◆ ATA_PIO1

#define ATA_PIO1   0x09

Definition at line 310 of file atapi.h.

◆ ATA_PIO2

#define ATA_PIO2   0x0a

Definition at line 311 of file atapi.h.

◆ ATA_PIO3

#define ATA_PIO3   0x0b

Definition at line 312 of file atapi.h.

◆ ATA_PIO4

#define ATA_PIO4   0x0c

Definition at line 313 of file atapi.h.

◆ ATA_PIO5

#define ATA_PIO5   0x0d

Definition at line 314 of file atapi.h.

◆ ATA_PIO_NRDY

#define ATA_PIO_NRDY   0x01

Definition at line 307 of file atapi.h.

◆ ATA_SA150

#define ATA_SA150   0x47 /*0x80*/

Definition at line 337 of file atapi.h.

◆ ATA_SA300

#define ATA_SA300   0x48 /*0x81*/

Definition at line 338 of file atapi.h.

◆ ATA_SA600

#define ATA_SA600   0x49 /*0x82*/

Definition at line 339 of file atapi.h.

◆ ATA_SATA_GEN1

#define ATA_SATA_GEN1   0x0002

Definition at line 757 of file atapi.h.

◆ ATA_SATA_GEN2

#define ATA_SATA_GEN2   0x0004

Definition at line 758 of file atapi.h.

◆ ATA_SATA_GEN3

#define ATA_SATA_GEN3   0x0008

Definition at line 759 of file atapi.h.

◆ ATA_SDMA

#define ATA_SDMA   0x10

Definition at line 317 of file atapi.h.

◆ ATA_SDMA0

#define ATA_SDMA0   0x10

Definition at line 318 of file atapi.h.

◆ ATA_SDMA1

#define ATA_SDMA1   0x11

Definition at line 319 of file atapi.h.

◆ ATA_SDMA2

#define ATA_SDMA2   0x12

Definition at line 320 of file atapi.h.

◆ ATA_SUPPORT_AUTOACTIVATE

#define ATA_SUPPORT_AUTOACTIVATE   0x0004

Definition at line 770 of file atapi.h.

◆ ATA_SUPPORT_IFPWRMNGT

#define ATA_SUPPORT_IFPWRMNGT   0x0008

Definition at line 771 of file atapi.h.

◆ ATA_SUPPORT_IFPWRMNGTRCV

#define ATA_SUPPORT_IFPWRMNGTRCV   0x0200

Definition at line 761 of file atapi.h.

◆ ATA_SUPPORT_INORDERDATA

#define ATA_SUPPORT_INORDERDATA   0x0010

Definition at line 772 of file atapi.h.

◆ ATA_SUPPORT_NCQ

#define ATA_SUPPORT_NCQ   0x0100

Definition at line 760 of file atapi.h.

◆ ATA_SUPPORT_NCQ_PRI_INFO

#define ATA_SUPPORT_NCQ_PRI_INFO   0x1000

Definition at line 764 of file atapi.h.

◆ ATA_SUPPORT_NCQ_UNLOAD

#define ATA_SUPPORT_NCQ_UNLOAD   0x0800

Definition at line 763 of file atapi.h.

◆ ATA_SUPPORT_NONZERO

#define ATA_SUPPORT_NONZERO   0x0002

Definition at line 769 of file atapi.h.

◆ ATA_SUPPORT_PHY_EVENT_COUNTER

#define ATA_SUPPORT_PHY_EVENT_COUNTER   0x0400

Definition at line 762 of file atapi.h.

◆ ATA_UDMA

#define ATA_UDMA   0x40

Definition at line 327 of file atapi.h.

◆ ATA_UDMA0

#define ATA_UDMA0   0x40

Definition at line 328 of file atapi.h.

◆ ATA_UDMA1

#define ATA_UDMA1   0x41

Definition at line 329 of file atapi.h.

◆ ATA_UDMA2

#define ATA_UDMA2   0x42

Definition at line 330 of file atapi.h.

◆ ATA_UDMA3

#define ATA_UDMA3   0x43

Definition at line 331 of file atapi.h.

◆ ATA_UDMA4

#define ATA_UDMA4   0x44

Definition at line 332 of file atapi.h.

◆ ATA_UDMA5

#define ATA_UDMA5   0x45

Definition at line 333 of file atapi.h.

◆ ATA_UDMA6

#define ATA_UDMA6   0x46

Definition at line 334 of file atapi.h.

◆ ATA_VER_MJ_ATA4

#define ATA_VER_MJ_ATA4   0x0010

Definition at line 778 of file atapi.h.

◆ ATA_VER_MJ_ATA5

#define ATA_VER_MJ_ATA5   0x0020

Definition at line 779 of file atapi.h.

◆ ATA_VER_MJ_ATA6

#define ATA_VER_MJ_ATA6   0x0040

Definition at line 780 of file atapi.h.

◆ ATA_VER_MJ_ATA7

#define ATA_VER_MJ_ATA7   0x0080

Definition at line 781 of file atapi.h.

◆ ATA_VER_MJ_ATA8_ASC

#define ATA_VER_MJ_ATA8_ASC   0x0100

Definition at line 782 of file atapi.h.

◆ ATA_WDMA

#define ATA_WDMA   0x20

Definition at line 322 of file atapi.h.

◆ ATA_WDMA0

#define ATA_WDMA0   0x20

Definition at line 323 of file atapi.h.

◆ ATA_WDMA1

#define ATA_WDMA1   0x21

Definition at line 324 of file atapi.h.

◆ ATA_WDMA2

#define ATA_WDMA2   0x22

Definition at line 325 of file atapi.h.

◆ ATAPI_DEVICE

#define ATAPI_DEVICE (   chan,
  dev 
)    ((chan->lun[dev]->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE)

Definition at line 1624 of file atapi.h.

◆ ATAPI_DRQT_ACCEL

#define ATAPI_DRQT_ACCEL   2 /* accel 50 us delay */

Definition at line 617 of file atapi.h.

◆ ATAPI_DRQT_INTR

#define ATAPI_DRQT_INTR   1 /* intr 10 ms delay */

Definition at line 616 of file atapi.h.

◆ ATAPI_DRQT_MPROC

#define ATAPI_DRQT_MPROC   0 /* cpu 3 ms delay */

Definition at line 615 of file atapi.h.

◆ ATAPI_FORMAT_UNIT

#define ATAPI_FORMAT_UNIT   0x24

Definition at line 270 of file atapi.h.

◆ ATAPI_IR_COD

#define ATAPI_IR_COD   0x01

Definition at line 543 of file atapi.h.

◆ ATAPI_IR_COD_Cmd

#define ATAPI_IR_COD_Cmd   0x1

Definition at line 545 of file atapi.h.

◆ ATAPI_IR_COD_Data

#define ATAPI_IR_COD_Data   0x0

Definition at line 544 of file atapi.h.

◆ ATAPI_IR_IO

#define ATAPI_IR_IO   0x02

Definition at line 547 of file atapi.h.

◆ ATAPI_IR_IO_toDev

#define ATAPI_IR_IO_toDev   0x00

Definition at line 548 of file atapi.h.

◆ ATAPI_IR_IO_toHost

#define ATAPI_IR_IO_toHost   0x02

Definition at line 549 of file atapi.h.

◆ ATAPI_IR_Mask

#define ATAPI_IR_Mask   0x03

Definition at line 551 of file atapi.h.

◆ ATAPI_MODE_SELECT

#define ATAPI_MODE_SELECT   0x55

Definition at line 269 of file atapi.h.

◆ ATAPI_MODE_SENSE

#define ATAPI_MODE_SENSE   0x5A

Definition at line 268 of file atapi.h.

◆ ATAPI_PROTO_ATAPI

#define ATAPI_PROTO_ATAPI   2

Definition at line 627 of file atapi.h.

◆ ATAPI_PSIZE_12

#define ATAPI_PSIZE_12   0 /* 12 bytes */

Definition at line 611 of file atapi.h.

◆ ATAPI_PSIZE_16

#define ATAPI_PSIZE_16   1 /* 16 bytes */

Definition at line 612 of file atapi.h.

◆ ATAPI_TYPE_CDROM

#define ATAPI_TYPE_CDROM   5 /* CD-ROM device */

Definition at line 623 of file atapi.h.

◆ ATAPI_TYPE_DIRECT

#define ATAPI_TYPE_DIRECT   0 /* disk/floppy */

Definition at line 621 of file atapi.h.

◆ ATAPI_TYPE_OPTICAL

#define ATAPI_TYPE_OPTICAL   7 /* optical disk */

Definition at line 624 of file atapi.h.

◆ ATAPI_TYPE_TAPE

#define ATAPI_TYPE_TAPE   1 /* streaming tape */

Definition at line 622 of file atapi.h.

◆ AtapiCopyMemory

#define AtapiCopyMemory   RtlCopyMemory

Definition at line 1247 of file atapi.h.

◆ AtapiStallExecution

#define AtapiStallExecution (   dt)    ScsiPortStallExecution(dt)

Definition at line 158 of file atapi.h.

◆ AtapiStringCmp

#define AtapiStringCmp (   s1,
  s2,
  n 
)    _strnicmp(s1, s2, n)

Definition at line 1256 of file atapi.h.

◆ AUTO_OFFLINE

#define AUTO_OFFLINE   0xDB

Definition at line 594 of file atapi.h.

◆ CHAN_NOT_SPECIFIED

#define CHAN_NOT_SPECIFIED   (0xffffffffL)

Definition at line 1481 of file atapi.h.

◆ CHAN_NOT_SPECIFIED_CHECK_CABLE

#define CHAN_NOT_SPECIFIED_CHECK_CABLE   (0xfffffffeL)

Definition at line 1482 of file atapi.h.

◆ Connect_DbgPrint

#define Connect_DbgPrint ( )    {;}

Definition at line 156 of file atapi.h.

◆ DEVNUM_NOT_SPECIFIED

#define DEVNUM_NOT_SPECIFIED   (0xffffffffL)

Definition at line 1483 of file atapi.h.

◆ DFLAGS_ATAPI_CHANGER

#define DFLAGS_ATAPI_CHANGER   0x0040

Definition at line 244 of file atapi.h.

◆ DFLAGS_ATAPI_DEVICE

#define DFLAGS_ATAPI_DEVICE   0x0002

Definition at line 237 of file atapi.h.

◆ DFLAGS_CHANGER_INITED

#define DFLAGS_CHANGER_INITED   0x0100

Definition at line 246 of file atapi.h.

◆ DFLAGS_DEVICE_PRESENT

#define DFLAGS_DEVICE_PRESENT   0x0001

Definition at line 236 of file atapi.h.

◆ DFLAGS_DWORDIO_ENABLED

#define DFLAGS_DWORDIO_ENABLED   0x0400

Definition at line 248 of file atapi.h.

◆ DFLAGS_HIDDEN

#define DFLAGS_HIDDEN   0x8000

Definition at line 253 of file atapi.h.

◆ DFLAGS_INT_DRQ

#define DFLAGS_INT_DRQ   0x0008

Definition at line 239 of file atapi.h.

◆ DFLAGS_LBA32plus

#define DFLAGS_LBA32plus   0x20000

Definition at line 256 of file atapi.h.

◆ DFLAGS_LBA_ENABLED

#define DFLAGS_LBA_ENABLED   0x0200

Definition at line 247 of file atapi.h.

◆ DFLAGS_MANUAL_CHS

#define DFLAGS_MANUAL_CHS   0x10000

Definition at line 255 of file atapi.h.

◆ DFLAGS_MEDIA_STATUS_ENABLED

#define DFLAGS_MEDIA_STATUS_ENABLED   0x0020

Definition at line 243 of file atapi.h.

◆ DFLAGS_ORIG_GEOMETRY

#define DFLAGS_ORIG_GEOMETRY   0x2000

Definition at line 251 of file atapi.h.

◆ DFLAGS_RCACHE_ENABLED

#define DFLAGS_RCACHE_ENABLED   0x1000

Definition at line 250 of file atapi.h.

◆ DFLAGS_REINIT_DMA

#define DFLAGS_REINIT_DMA   0x4000

Definition at line 252 of file atapi.h.

◆ DFLAGS_REMOVABLE_DRIVE

#define DFLAGS_REMOVABLE_DRIVE   0x0010

Definition at line 241 of file atapi.h.

◆ DFLAGS_SANYO_ATAPI_CHANGER

#define DFLAGS_SANYO_ATAPI_CHANGER   0x0080

Definition at line 245 of file atapi.h.

◆ DFLAGS_TAPE_DEVICE

#define DFLAGS_TAPE_DEVICE   0x0004

Definition at line 238 of file atapi.h.

◆ DFLAGS_WCACHE_ENABLED

#define DFLAGS_WCACHE_ENABLED   0x0800

Definition at line 249 of file atapi.h.

◆ GetBaseStatus

#define GetBaseStatus (   chan,
  pStatus 
)     pStatus = AtapiReadPort1(chan, IDX_IO1_i_Status);

Definition at line 1092 of file atapi.h.

◆ GetStatus

#define GetStatus (   chan,
  Status 
)     Status = AtapiReadPort1(chan, IDX_IO2_AltStatus);

Definition at line 1089 of file atapi.h.

◆ IDE_COMMAND_ATAPI_IDENTIFY

#define IDE_COMMAND_ATAPI_IDENTIFY   0xA1

Definition at line 383 of file atapi.h.

◆ IDE_COMMAND_ATAPI_PACKET

#define IDE_COMMAND_ATAPI_PACKET   0xA0

Definition at line 382 of file atapi.h.

◆ IDE_COMMAND_ATAPI_RESET

#define IDE_COMMAND_ATAPI_RESET   0x08

Definition at line 348 of file atapi.h.

◆ IDE_COMMAND_DATA_SET_MGMT

#define IDE_COMMAND_DATA_SET_MGMT   0x06

Definition at line 347 of file atapi.h.

◆ IDE_COMMAND_DOOR_LOCK

#define IDE_COMMAND_DOOR_LOCK   0xDE

Definition at line 393 of file atapi.h.

◆ IDE_COMMAND_DOOR_UNLOCK

#define IDE_COMMAND_DOOR_UNLOCK   0xDF

Definition at line 394 of file atapi.h.

◆ IDE_COMMAND_ENABLE_MEDIA_STATUS

#define IDE_COMMAND_ENABLE_MEDIA_STATUS   0xEF

Definition at line 406 of file atapi.h.

◆ IDE_COMMAND_FLUSH_CACHE

#define IDE_COMMAND_FLUSH_CACHE   0xE7

Definition at line 401 of file atapi.h.

◆ IDE_COMMAND_FLUSH_CACHE48

#define IDE_COMMAND_FLUSH_CACHE48   0xEA

Definition at line 405 of file atapi.h.

◆ IDE_COMMAND_GET_MEDIA_STATUS

#define IDE_COMMAND_GET_MEDIA_STATUS   0xDA

Definition at line 392 of file atapi.h.

◆ IDE_COMMAND_IDENTIFY

#define IDE_COMMAND_IDENTIFY   0xEC

Definition at line 403 of file atapi.h.

◆ IDE_COMMAND_IDLE

#define IDE_COMMAND_IDLE   0xE3

Definition at line 398 of file atapi.h.

◆ IDE_COMMAND_IDLE_IMMED

#define IDE_COMMAND_IDLE_IMMED   0xE1

Definition at line 396 of file atapi.h.

◆ IDE_COMMAND_MEDIA_EJECT

#define IDE_COMMAND_MEDIA_EJECT   0xED

Definition at line 404 of file atapi.h.

◆ IDE_COMMAND_READ

#define IDE_COMMAND_READ   0x20

Definition at line 350 of file atapi.h.

◆ IDE_COMMAND_READ48

#define IDE_COMMAND_READ48   0x24

Definition at line 352 of file atapi.h.

◆ IDE_COMMAND_READ_DMA

#define IDE_COMMAND_READ_DMA   0xC8

Definition at line 388 of file atapi.h.

◆ IDE_COMMAND_READ_DMA48

#define IDE_COMMAND_READ_DMA48   0x25

Definition at line 353 of file atapi.h.

◆ IDE_COMMAND_READ_DMA_Q

#define IDE_COMMAND_READ_DMA_Q   0xC7

Definition at line 387 of file atapi.h.

◆ IDE_COMMAND_READ_DMA_Q48

#define IDE_COMMAND_READ_DMA_Q48   0x26

Definition at line 354 of file atapi.h.

◆ IDE_COMMAND_READ_LOG48

#define IDE_COMMAND_READ_LOG48   0x2f

Definition at line 359 of file atapi.h.

◆ IDE_COMMAND_READ_LOG_DMA48

#define IDE_COMMAND_READ_LOG_DMA48   0x47

Definition at line 374 of file atapi.h.

◆ IDE_COMMAND_READ_MUL48

#define IDE_COMMAND_READ_MUL48   0x29

Definition at line 356 of file atapi.h.

◆ IDE_COMMAND_READ_MULTIPLE

#define IDE_COMMAND_READ_MULTIPLE   0xC4

Definition at line 384 of file atapi.h.

◆ IDE_COMMAND_READ_NATIVE_SIZE

#define IDE_COMMAND_READ_NATIVE_SIZE   0xF8

Definition at line 408 of file atapi.h.

◆ IDE_COMMAND_READ_NATIVE_SIZE48

#define IDE_COMMAND_READ_NATIVE_SIZE48   0x27

Definition at line 355 of file atapi.h.

◆ IDE_COMMAND_READ_NO_RETR

#define IDE_COMMAND_READ_NO_RETR   0x21

Definition at line 351 of file atapi.h.

◆ IDE_COMMAND_READ_PM

#define IDE_COMMAND_READ_PM   0xE4

Definition at line 399 of file atapi.h.

◆ IDE_COMMAND_READ_STREAM48

#define IDE_COMMAND_READ_STREAM48   0x2B

Definition at line 358 of file atapi.h.

◆ IDE_COMMAND_READ_STREAM_DMA48

#define IDE_COMMAND_READ_STREAM_DMA48   0x2A

Definition at line 357 of file atapi.h.

◆ IDE_COMMAND_RECALIBRATE

#define IDE_COMMAND_RECALIBRATE   0x10

Definition at line 349 of file atapi.h.

◆ IDE_COMMAND_SEEK

#define IDE_COMMAND_SEEK   0x70

Definition at line 380 of file atapi.h.

◆ IDE_COMMAND_SET_DRIVE_PARAMETERS

#define IDE_COMMAND_SET_DRIVE_PARAMETERS   0x91

Definition at line 381 of file atapi.h.

◆ IDE_COMMAND_SET_FEATURES

#define IDE_COMMAND_SET_FEATURES
Value:
0xEF /* features command,
IDE_COMMAND_ENABLE_MEDIA_STATUS */

Definition at line 407 of file atapi.h.

◆ IDE_COMMAND_SET_MULTIPLE

#define IDE_COMMAND_SET_MULTIPLE   0xC6

Definition at line 386 of file atapi.h.

◆ IDE_COMMAND_SET_NATIVE_SIZE

#define IDE_COMMAND_SET_NATIVE_SIZE   0xF9

Definition at line 409 of file atapi.h.

◆ IDE_COMMAND_SET_NATIVE_SIZE48

#define IDE_COMMAND_SET_NATIVE_SIZE48   0x37

Definition at line 365 of file atapi.h.

◆ IDE_COMMAND_SLEEP

#define IDE_COMMAND_SLEEP   0xE6

Definition at line 400 of file atapi.h.

◆ IDE_COMMAND_STANDBY

#define IDE_COMMAND_STANDBY   0xE2

Definition at line 397 of file atapi.h.

◆ IDE_COMMAND_STANDBY_IMMED

#define IDE_COMMAND_STANDBY_IMMED   0xE0

Definition at line 395 of file atapi.h.

◆ IDE_COMMAND_TRUSTED_RCV

#define IDE_COMMAND_TRUSTED_RCV   0x5c

Definition at line 376 of file atapi.h.

◆ IDE_COMMAND_TRUSTED_RCV_DMA

#define IDE_COMMAND_TRUSTED_RCV_DMA   0x5d

Definition at line 377 of file atapi.h.

◆ IDE_COMMAND_TRUSTED_SEND

#define IDE_COMMAND_TRUSTED_SEND   0x5e

Definition at line 378 of file atapi.h.

◆ IDE_COMMAND_TRUSTED_SEND_DMA

#define IDE_COMMAND_TRUSTED_SEND_DMA   0x5f

Definition at line 379 of file atapi.h.

◆ IDE_COMMAND_VERIFY

#define IDE_COMMAND_VERIFY   0x40

Definition at line 372 of file atapi.h.

◆ IDE_COMMAND_VERIFY48

#define IDE_COMMAND_VERIFY48   0x42

Definition at line 373 of file atapi.h.

◆ IDE_COMMAND_WRITE

#define IDE_COMMAND_WRITE   0x30

Definition at line 360 of file atapi.h.

◆ IDE_COMMAND_WRITE48

#define IDE_COMMAND_WRITE48   0x34

Definition at line 362 of file atapi.h.

◆ IDE_COMMAND_WRITE_DMA

#define IDE_COMMAND_WRITE_DMA   0xCA

Definition at line 389 of file atapi.h.

◆ IDE_COMMAND_WRITE_DMA48

#define IDE_COMMAND_WRITE_DMA48   0x35

Definition at line 363 of file atapi.h.

◆ IDE_COMMAND_WRITE_DMA_Q

#define IDE_COMMAND_WRITE_DMA_Q   0xCC

Definition at line 390 of file atapi.h.

◆ IDE_COMMAND_WRITE_DMA_Q48

#define IDE_COMMAND_WRITE_DMA_Q48   0x36

Definition at line 364 of file atapi.h.

◆ IDE_COMMAND_WRITE_FUA_DMA48

#define IDE_COMMAND_WRITE_FUA_DMA48   0x3d

Definition at line 369 of file atapi.h.

◆ IDE_COMMAND_WRITE_FUA_DMA_Q48

#define IDE_COMMAND_WRITE_FUA_DMA_Q48   0x3e

Definition at line 370 of file atapi.h.

◆ IDE_COMMAND_WRITE_LOG48

#define IDE_COMMAND_WRITE_LOG48   0x3f

Definition at line 371 of file atapi.h.

◆ IDE_COMMAND_WRITE_LOG_DMA48

#define IDE_COMMAND_WRITE_LOG_DMA48   0x57

Definition at line 375 of file atapi.h.

◆ IDE_COMMAND_WRITE_MUL48

#define IDE_COMMAND_WRITE_MUL48   0x39

Definition at line 366 of file atapi.h.

◆ IDE_COMMAND_WRITE_MUL_FUA48

#define IDE_COMMAND_WRITE_MUL_FUA48   0xCE

Definition at line 391 of file atapi.h.

◆ IDE_COMMAND_WRITE_MULTIPLE

#define IDE_COMMAND_WRITE_MULTIPLE   0xC5

Definition at line 385 of file atapi.h.

◆ IDE_COMMAND_WRITE_NO_RETR

#define IDE_COMMAND_WRITE_NO_RETR   0x31

Definition at line 361 of file atapi.h.

◆ IDE_COMMAND_WRITE_PM

#define IDE_COMMAND_WRITE_PM   0xE8

Definition at line 402 of file atapi.h.

◆ IDE_COMMAND_WRITE_STREAM48

#define IDE_COMMAND_WRITE_STREAM48   0x3b

Definition at line 368 of file atapi.h.

◆ IDE_COMMAND_WRITE_STREAM_DMA48

#define IDE_COMMAND_WRITE_STREAM_DMA48   0x3a

Definition at line 367 of file atapi.h.

◆ IDE_DC_A_4BIT

#define IDE_DC_A_4BIT   0x80

Definition at line 453 of file atapi.h.

◆ IDE_DC_DISABLE_INTERRUPTS

#define IDE_DC_DISABLE_INTERRUPTS   0x02

Definition at line 451 of file atapi.h.

◆ IDE_DC_REENABLE_CONTROLLER

#define IDE_DC_REENABLE_CONTROLLER   0x00

Definition at line 455 of file atapi.h.

◆ IDE_DC_RESET_CONTROLLER

#define IDE_DC_RESET_CONTROLLER   0x04

Definition at line 452 of file atapi.h.

◆ IDE_DC_USE_HOB

#define IDE_DC_USE_HOB   0x80

Definition at line 454 of file atapi.h.

◆ IDE_DRIVE_1

#define IDE_DRIVE_1   0x00

Definition at line 439 of file atapi.h.

◆ IDE_DRIVE_2

#define IDE_DRIVE_2   0x10

Definition at line 440 of file atapi.h.

◆ IDE_DRIVE_MASK

#define IDE_DRIVE_MASK   (IDE_DRIVE_SELECT_1 | IDE_DRIVE_SELECT_2)

Definition at line 443 of file atapi.h.

◆ IDE_DRIVE_SELECT

#define IDE_DRIVE_SELECT   0xA0

Definition at line 438 of file atapi.h.

◆ IDE_DRIVE_SELECT_1

#define IDE_DRIVE_SELECT_1   (IDE_DRIVE_SELECT | IDE_DRIVE_1)

Definition at line 441 of file atapi.h.

◆ IDE_DRIVE_SELECT_2

#define IDE_DRIVE_SELECT_2   (IDE_DRIVE_SELECT | IDE_DRIVE_2)

Definition at line 442 of file atapi.h.

◆ IDE_ERROR_BAD_BLOCK

#define IDE_ERROR_BAD_BLOCK   0x80

Definition at line 461 of file atapi.h.

◆ IDE_ERROR_COMMAND_ABORTED

#define IDE_ERROR_COMMAND_ABORTED   0x04

Definition at line 466 of file atapi.h.

◆ IDE_ERROR_DATA_ERROR

#define IDE_ERROR_DATA_ERROR   0x40

Definition at line 462 of file atapi.h.

◆ IDE_ERROR_END_OF_MEDIA

#define IDE_ERROR_END_OF_MEDIA   0x02

Definition at line 467 of file atapi.h.

◆ IDE_ERROR_ICRC

#define IDE_ERROR_ICRC   0x80

Definition at line 460 of file atapi.h.

◆ IDE_ERROR_ID_NOT_FOUND

#define IDE_ERROR_ID_NOT_FOUND   0x10

Definition at line 464 of file atapi.h.

◆ IDE_ERROR_ILLEGAL_LENGTH

#define IDE_ERROR_ILLEGAL_LENGTH   0x01

Definition at line 469 of file atapi.h.

◆ IDE_ERROR_MEDIA_CHANGE

#define IDE_ERROR_MEDIA_CHANGE   0x20

Definition at line 463 of file atapi.h.

◆ IDE_ERROR_MEDIA_CHANGE_REQ

#define IDE_ERROR_MEDIA_CHANGE_REQ   0x08

Definition at line 465 of file atapi.h.

◆ IDE_ERROR_NO_MEDIA

#define IDE_ERROR_NO_MEDIA   0x02

Definition at line 468 of file atapi.h.

◆ IDE_STATUS_BUSY

#define IDE_STATUS_BUSY   0x80

Definition at line 428 of file atapi.h.

◆ IDE_STATUS_CORRECTED_ERROR

#define IDE_STATUS_CORRECTED_ERROR   0x04

Definition at line 420 of file atapi.h.

◆ IDE_STATUS_DMA

#define IDE_STATUS_DMA   0x20 /* DMA ready */

Definition at line 424 of file atapi.h.

◆ IDE_STATUS_DRDY

#define IDE_STATUS_DRDY   0x40

Definition at line 426 of file atapi.h.

◆ IDE_STATUS_DRQ

#define IDE_STATUS_DRQ   0x08

Definition at line 421 of file atapi.h.

◆ IDE_STATUS_DSC

#define IDE_STATUS_DSC   0x10

Definition at line 422 of file atapi.h.

◆ IDE_STATUS_DWF

#define IDE_STATUS_DWF   0x20 /* drive write fault */

Definition at line 425 of file atapi.h.

◆ IDE_STATUS_ERROR

#define IDE_STATUS_ERROR   0x01

Definition at line 418 of file atapi.h.

◆ IDE_STATUS_IDLE

#define IDE_STATUS_IDLE   0x50

Definition at line 427 of file atapi.h.

◆ IDE_STATUS_INDEX

#define IDE_STATUS_INDEX   0x02

Definition at line 419 of file atapi.h.

◆ IDE_STATUS_MASK

#define IDE_STATUS_MASK   0xff

Definition at line 431 of file atapi.h.

◆ IDE_STATUS_SUCCESS

#define IDE_STATUS_SUCCESS   0x00

Definition at line 417 of file atapi.h.

◆ IDE_STATUS_WRONG

#define IDE_STATUS_WRONG   0xff

Definition at line 430 of file atapi.h.

◆ IDE_USE_LBA

#define IDE_USE_LBA   0x40

Definition at line 445 of file atapi.h.

◆ IDENT_MODE_ACTIVE

#define IDENT_MODE_ACTIVE   TRUE

Definition at line 1644 of file atapi.h.

◆ IDENT_MODE_MAX

#define IDENT_MODE_MAX   FALSE

Definition at line 1643 of file atapi.h.

◆ IDENTIFY_CABLE_ID_VALID

#define IDENTIFY_CABLE_ID_VALID   0x01

Definition at line 844 of file atapi.h.

◆ IDENTIFY_DATA2

Definition at line 989 of file atapi.h.

◆ IDENTIFY_DATA_SIZE

#define IDENTIFY_DATA_SIZE   sizeof(IDENTIFY_DATA)

Definition at line 1033 of file atapi.h.

◆ IDENTIFY_DMA_CYCLES_MODE_0

#define IDENTIFY_DMA_CYCLES_MODE_0   0x00

Definition at line 1037 of file atapi.h.

◆ IDENTIFY_DMA_CYCLES_MODE_1

#define IDENTIFY_DMA_CYCLES_MODE_1   0x01

Definition at line 1038 of file atapi.h.

◆ IDENTIFY_DMA_CYCLES_MODE_2

#define IDENTIFY_DMA_CYCLES_MODE_2   0x02

Definition at line 1039 of file atapi.h.

◆ IDX_ATAPI_IO1

#define IDX_ATAPI_IO1   IDX_IO1

Definition at line 502 of file atapi.h.

◆ IDX_ATAPI_IO1_i_ByteCountHigh

#define IDX_ATAPI_IO1_i_ByteCountHigh   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountHigh )+IDX_ATAPI_IO1)

Definition at line 510 of file atapi.h.

◆ IDX_ATAPI_IO1_i_ByteCountLow

#define IDX_ATAPI_IO1_i_ByteCountLow   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.ByteCountLow )+IDX_ATAPI_IO1)

Definition at line 509 of file atapi.h.

◆ IDX_ATAPI_IO1_i_Data

#define IDX_ATAPI_IO1_i_Data   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Data )+IDX_ATAPI_IO1)

Definition at line 505 of file atapi.h.

◆ IDX_ATAPI_IO1_i_DriveSelect

#define IDX_ATAPI_IO1_i_DriveSelect   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.DriveSelect )+IDX_ATAPI_IO1)

Definition at line 511 of file atapi.h.

◆ IDX_ATAPI_IO1_i_Error

#define IDX_ATAPI_IO1_i_Error   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Error )+IDX_ATAPI_IO1)

Definition at line 506 of file atapi.h.

◆ IDX_ATAPI_IO1_i_InterruptReason

#define IDX_ATAPI_IO1_i_InterruptReason   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.InterruptReason)+IDX_ATAPI_IO1)

Definition at line 507 of file atapi.h.

◆ IDX_ATAPI_IO1_i_Status

#define IDX_ATAPI_IO1_i_Status   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Status )+IDX_ATAPI_IO1)

Definition at line 512 of file atapi.h.

◆ IDX_ATAPI_IO1_i_Unused1

#define IDX_ATAPI_IO1_i_Unused1   (FIELD_OFFSET(ATAPI_REGISTERS_1, i.Unused1 )+IDX_ATAPI_IO1)

Definition at line 508 of file atapi.h.

◆ IDX_ATAPI_IO1_o_ByteCountHigh

#define IDX_ATAPI_IO1_o_ByteCountHigh   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountHigh)+IDX_ATAPI_IO1)

Definition at line 519 of file atapi.h.

◆ IDX_ATAPI_IO1_o_ByteCountLow

#define IDX_ATAPI_IO1_o_ByteCountLow   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.ByteCountLow )+IDX_ATAPI_IO1)

Definition at line 518 of file atapi.h.

◆ IDX_ATAPI_IO1_o_Command

#define IDX_ATAPI_IO1_o_Command   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Command )+IDX_ATAPI_IO1)

Definition at line 521 of file atapi.h.

◆ IDX_ATAPI_IO1_o_Data

#define IDX_ATAPI_IO1_o_Data   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Data )+IDX_ATAPI_IO1)

Definition at line 514 of file atapi.h.

◆ IDX_ATAPI_IO1_o_DriveSelect

#define IDX_ATAPI_IO1_o_DriveSelect   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.DriveSelect )+IDX_ATAPI_IO1)

Definition at line 520 of file atapi.h.

◆ IDX_ATAPI_IO1_o_Feature

#define IDX_ATAPI_IO1_o_Feature   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Feature )+IDX_ATAPI_IO1)

Definition at line 515 of file atapi.h.

◆ IDX_ATAPI_IO1_o_Unused0

#define IDX_ATAPI_IO1_o_Unused0   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused0 )+IDX_ATAPI_IO1)

Definition at line 516 of file atapi.h.

◆ IDX_ATAPI_IO1_o_Unused1

#define IDX_ATAPI_IO1_o_Unused1   (FIELD_OFFSET(ATAPI_REGISTERS_1, o.Unused1 )+IDX_ATAPI_IO1)

Definition at line 517 of file atapi.h.

◆ IDX_ATAPI_IO1_SZ

#define IDX_ATAPI_IO1_SZ   sizeof(ATAPI_REGISTERS_1)

Definition at line 503 of file atapi.h.

◆ IDX_IO1 [1/2]

#define IDX_IO1   0

Definition at line 194 of file atapi.h.

◆ IDX_IO1 [2/2]

#define IDX_IO1   0

Definition at line 194 of file atapi.h.

◆ IDX_IO1_i_BlockCount

#define IDX_IO1_i_BlockCount   (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockCount )+IDX_IO1)

Definition at line 198 of file atapi.h.

◆ IDX_IO1_i_BlockNumber

#define IDX_IO1_i_BlockNumber   (FIELD_OFFSET(IDE_REGISTERS_1, i.BlockNumber )+IDX_IO1)

Definition at line 199 of file atapi.h.

◆ IDX_IO1_i_CylinderHigh

#define IDX_IO1_i_CylinderHigh   (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderHigh)+IDX_IO1)

Definition at line 201 of file atapi.h.

◆ IDX_IO1_i_CylinderLow

#define IDX_IO1_i_CylinderLow   (FIELD_OFFSET(IDE_REGISTERS_1, i.CylinderLow )+IDX_IO1)

Definition at line 200 of file atapi.h.

◆ IDX_IO1_i_Data

#define IDX_IO1_i_Data   (FIELD_OFFSET(IDE_REGISTERS_1, i.Data )+IDX_IO1)

Definition at line 196 of file atapi.h.

◆ IDX_IO1_i_DriveSelect

#define IDX_IO1_i_DriveSelect   (FIELD_OFFSET(IDE_REGISTERS_1, i.DriveSelect )+IDX_IO1)

Definition at line 202 of file atapi.h.

◆ IDX_IO1_i_Error

#define IDX_IO1_i_Error   (FIELD_OFFSET(IDE_REGISTERS_1, i.Error )+IDX_IO1)

Definition at line 197 of file atapi.h.

◆ IDX_IO1_i_Status

#define IDX_IO1_i_Status   (FIELD_OFFSET(IDE_REGISTERS_1, i.Status )+IDX_IO1)

Definition at line 203 of file atapi.h.

◆ IDX_IO1_o

#define IDX_IO1_o   IDX_IO1_SZ

Definition at line 205 of file atapi.h.

◆ IDX_IO1_o_BlockCount

#define IDX_IO1_o_BlockCount   (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockCount )+IDX_IO1_o)

Definition at line 210 of file atapi.h.

◆ IDX_IO1_o_BlockNumber

#define IDX_IO1_o_BlockNumber   (FIELD_OFFSET(IDE_REGISTERS_1, o.BlockNumber )+IDX_IO1_o)

Definition at line 211 of file atapi.h.

◆ IDX_IO1_o_Command

#define IDX_IO1_o_Command   (FIELD_OFFSET(IDE_REGISTERS_1, o.Command )+IDX_IO1_o)

Definition at line 215 of file atapi.h.

◆ IDX_IO1_o_CylinderHigh

#define IDX_IO1_o_CylinderHigh   (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderHigh)+IDX_IO1_o)

Definition at line 213 of file atapi.h.

◆ IDX_IO1_o_CylinderLow

#define IDX_IO1_o_CylinderLow   (FIELD_OFFSET(IDE_REGISTERS_1, o.CylinderLow )+IDX_IO1_o)

Definition at line 212 of file atapi.h.

◆ IDX_IO1_o_Data

#define IDX_IO1_o_Data   (FIELD_OFFSET(IDE_REGISTERS_1, o.Data )+IDX_IO1_o)

Definition at line 208 of file atapi.h.

◆ IDX_IO1_o_DriveSelect

#define IDX_IO1_o_DriveSelect   (FIELD_OFFSET(IDE_REGISTERS_1, o.DriveSelect )+IDX_IO1_o)

Definition at line 214 of file atapi.h.

◆ IDX_IO1_o_Feature

#define IDX_IO1_o_Feature   (FIELD_OFFSET(IDE_REGISTERS_1, o.Feature )+IDX_IO1_o)

Definition at line 209 of file atapi.h.

◆ IDX_IO1_o_SZ

#define IDX_IO1_o_SZ   sizeof(IDE_REGISTERS_1)

Definition at line 206 of file atapi.h.

◆ IDX_IO1_SZ [1/2]

#define IDX_IO1_SZ   sizeof(IDE_REGISTERS_1)

Definition at line 195 of file atapi.h.

◆ IDX_IO1_SZ [2/2]

#define IDX_IO1_SZ   sizeof(IDE_REGISTERS_1)

Definition at line 195 of file atapi.h.

◆ IDX_IO2

#define IDX_IO2   (IDX_IO1_o+IDX_IO1_o_SZ)

Definition at line 222 of file atapi.h.

◆ IDX_IO2_AltStatus

#define IDX_IO2_AltStatus   (FIELD_OFFSET(IDE_REGISTERS_2, AltStatus )+IDX_IO2)

Definition at line 225 of file atapi.h.

◆ IDX_IO2_o

#define IDX_IO2_o   (IDX_IO2+IDX_IO2_SZ)

Definition at line 228 of file atapi.h.

◆ IDX_IO2_o_Control

#define IDX_IO2_o_Control   (FIELD_OFFSET(IDE_REGISTERS_2, Control)+IDX_IO2_o)

Definition at line 231 of file atapi.h.

◆ IDX_IO2_o_SZ

#define IDX_IO2_o_SZ   sizeof(IDE_REGISTERS_2)

Definition at line 229 of file atapi.h.

◆ IDX_IO2_SZ

#define IDX_IO2_SZ   sizeof(IDE_REGISTERS_2)

Definition at line 223 of file atapi.h.

◆ INTERRUPT_REASON_IGNORE

#define INTERRUPT_REASON_IGNORE   0

Definition at line 1278 of file atapi.h.

◆ INTERRUPT_REASON_OUR

#define INTERRUPT_REASON_OUR   1

Definition at line 1279 of file atapi.h.

◆ INTERRUPT_REASON_UNEXPECTED

#define INTERRUPT_REASON_UNEXPECTED   2

Definition at line 1280 of file atapi.h.

◆ IOMODE_NOT_SPECIFIED

#define IOMODE_NOT_SPECIFIED   (0xffffffffL)

Definition at line 1484 of file atapi.h.

◆ IS_RDP

#define IS_RDP (   OperationCode)
Value:
((OperationCode == SCSIOP_ERASE)||\
(OperationCode == SCSIOP_LOAD_UNLOAD)||\
(OperationCode == SCSIOP_LOCATE)||\
(OperationCode == SCSIOP_REWIND) ||\
(OperationCode == SCSIOP_SPACE)||\
(OperationCode == SCSIOP_SEEK)||\
/* (OperationCode == SCSIOP_FORMAT_UNIT)||\
(OperationCode == SCSIOP_BLANK)||*/ \
(OperationCode == SCSIOP_WRITE_FILEMARKS))
#define SCSIOP_LOCATE
Definition: cdrw_hw.h:909
#define SCSIOP_REWIND
Definition: cdrw_hw.h:868
#define SCSIOP_SEEK
Definition: cdrw_hw.h:908
#define SCSIOP_WRITE_FILEMARKS
Definition: cdrw_hw.h:885
#define SCSIOP_ERASE
Definition: cdrw_hw.h:895
#define SCSIOP_SPACE
Definition: cdrw_hw.h:887
#define SCSIOP_LOAD_UNLOAD
Definition: cdrw_hw.h:899

Definition at line 1197 of file atapi.h.

◆ KdPrint

#define KdPrint (   _x_)    {;}

Definition at line 155 of file atapi.h.

◆ KdPrint2

#define KdPrint2 (   _x_)    {;}

Definition at line 154 of file atapi.h.

◆ KdPrint3

#define KdPrint3 (   _x_)    {;}

Definition at line 153 of file atapi.h.

◆ MAX_ERRORS

#define MAX_ERRORS   4

Definition at line 262 of file atapi.h.

◆ PIDENTIFY_DATA2

Definition at line 990 of file atapi.h.

◆ PRINT_PREFIX

#define PRINT_PREFIX   "UniATA: "

Definition at line 150 of file atapi.h.

◆ PrintNtConsole

#define PrintNtConsole (   x)    {;}

Definition at line 1629 of file atapi.h.

◆ READ_LOG_SECTOR

#define READ_LOG_SECTOR   0xD5

Definition at line 591 of file atapi.h.

◆ ReadBuffer

#define ReadBuffer (   chan,
  Buffer,
  Count,
  timing 
)
Value:
Buffer, \
Count, \
VOID DDKFASTAPI AtapiReadBuffer2(IN PHW_CHANNEL chan, IN ULONGIO_PTR _port, IN PVOID Buffer, IN ULONG Count, IN ULONG Timing)
Definition: bufpool.h:45
int Count
Definition: noreturn.cpp:7
#define IDX_IO1_i_Data
Definition: atapi.h:196
static int timing
Definition: xmllint.c:163

Definition at line 1105 of file atapi.h.

◆ ReadBuffer2

#define ReadBuffer2 (   chan,
  Buffer,
  Count,
  timing 
)
Value:
Buffer, \
Count, \
VOID DDKFASTAPI AtapiReadBuffer4(IN PHW_CHANNEL chan, IN ULONGIO_PTR _port, IN PVOID Buffer, IN ULONG Count, IN ULONG Timing)

Definition at line 1117 of file atapi.h.

◆ SCSIOP_ATA_PASSTHROUGH

#define SCSIOP_ATA_PASSTHROUGH   0xCC

Definition at line 411 of file atapi.h.

◆ UNIATA_FIND_DEV_UNHIDE

#define UNIATA_FIND_DEV_UNHIDE   0x01

Definition at line 1360 of file atapi.h.

◆ UniAta_need_lba48

#define UniAta_need_lba48 (   command,
  lba,
  count,
  supp48 
)
Value:
( ((AtaCommandFlags[command] & ATA_CMD_FLAG_LBAIOsupp) && (supp48) && (((lba+count) >= ATA_MAX_IOLBA28) || (count > 256)) ) || \
(lba > ATA_MAX_LBA28) || (count > 255) )
#define ATA_MAX_LBA28
Definition: bsmaster.h:95
#define ATA_MAX_IOLBA28
Definition: bsmaster.h:94
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define lba
UCHAR const AtaCommandFlags[256]
Definition: atacmd_map.h:25
#define ATA_CMD_FLAG_LBAIOsupp
Definition: atapi.h:1597

Definition at line 1609 of file atapi.h.

◆ UniAtaClearAtaReq

#define UniAtaClearAtaReq (   AtaReq)
Value:
{ \
RtlZeroMemory((PCHAR)(AtaReq), FIELD_OFFSET(ATA_REQ, ata)); \
}
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
char * PCHAR
Definition: typedefs.h:51

Definition at line 1615 of file atapi.h.

◆ WRITE_LOG_SECTOR

#define WRITE_LOG_SECTOR   0xD6

Definition at line 592 of file atapi.h.

◆ WRITE_THRESHOLDS

#define WRITE_THRESHOLDS   0xD7

Definition at line 593 of file atapi.h.

◆ WriteBuffer

#define WriteBuffer (   chan,
  Buffer,
  Count,
  timing 
)
Value:
Buffer, \
Count, \
VOID DDKFASTAPI AtapiWriteBuffer2(IN PHW_CHANNEL chan, IN ULONGIO_PTR _port, IN PVOID Buffer, IN ULONG Count, IN ULONG Timing)
#define IDX_IO1_o_Data
Definition: atapi.h:208

Definition at line 1111 of file atapi.h.

◆ WriteBuffer2

#define WriteBuffer2 (   chan,
  Buffer,
  Count,
  timing 
)
Value:
Buffer, \
Count, \
VOID DDKFASTAPI AtapiWriteBuffer4(IN PHW_CHANNEL chan, IN ULONGIO_PTR _port, IN PVOID Buffer, IN ULONG Count, IN ULONG Timing)

Definition at line 1123 of file atapi.h.

◆ WriteCommand

#define WriteCommand (   chan,
  _Command 
)     AtapiWritePort1(chan, IDX_IO1_o_Command, _Command);

Definition at line 1095 of file atapi.h.

Typedef Documentation

◆ ATAPI_REGISTERS_1

◆ IDE_REGISTERS_1

◆ IDE_REGISTERS_2

◆ IDENTIFY_DATA

◆ MODE_PARAMETER_HEADER_10

◆ MODE_SELECT_10

◆ MODE_SENSE_10

◆ PATAPI_REGISTERS_1

◆ PIDE_REGISTERS_1

◆ PIDE_REGISTERS_2

◆ PIDENTIFY_DATA

◆ PMODE_PARAMETER_HEADER_10

◆ PMODE_SELECT_10

◆ PMODE_SENSE_10

◆ PTRIM_DATA

◆ TRIM_DATA

Function Documentation

◆ _PrintNtConsole()

VOID _cdecl _PrintNtConsole ( PCCH  DebugMessage,
  ... 
)

Definition at line 11689 of file id_ata.cpp.

11693{
11694 //int len;
11695 UCHAR dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE];
11696// UNICODE_STRING msgBuff;
11697 va_list ap;
11698 va_start(ap, DebugMessage);
11699
11700 /*len =*/ _vsnprintf((PCHAR)&dbg_print_tmp_buff[0], DEBUG_MSG_BUFFER_SIZE-1, DebugMessage, ap);
11701
11702 dbg_print_tmp_buff[DEBUG_MSG_BUFFER_SIZE-1] = 0;
11703
11704 //DbgPrint(((PCHAR)&(dbg_print_tmp_buff[0]))); // already done in KdPrint macro
11705 HalDisplayString(dbg_print_tmp_buff);
11706
11707#ifdef _DEBUG
11708 if(g_LogToDisplay > 1) {
11710 }
11711#endif // _DEBUG
11712
11713 va_end(ap);
11714
11715} // end PrintNtConsole()
char * va_list
Definition: acmsvcex.h:78
#define va_end(ap)
Definition: acmsvcex.h:90
#define va_start(ap, A)
Definition: acmsvcex.h:91
NTHALAPI VOID NTAPI HalDisplayString(PUCHAR String)
#define DEBUG_MSG_BUFFER_SIZE
Definition: id_ata.cpp:11684
#define AtapiStallExecution(dt)
Definition: atapi.h:158
ULONG g_LogToDisplay
void int int ULONGLONG int va_list * ap
Definition: winesup.h:36
#define _vsnprintf
Definition: xmlstorage.h:202
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by DriverEntry().

◆ ata_cur_mode_from_ident()

__inline LONG ata_cur_mode_from_ident ( PIDENTIFY_DATA  ident,
BOOLEAN  Active 
)

Definition at line 1648 of file atapi.h.

1654{
1655 USHORT mode;
1656 if(ata_is_sata(ident)) {
1657 if(ident->SataCapabilities & ATA_SATA_GEN3) {
1658 return ATA_SA600;
1659 } else
1660 if(ident->SataCapabilities & ATA_SATA_GEN2) {
1661 return ATA_SA300;
1662 } else
1663 if(ident->SataCapabilities & ATA_SATA_GEN1) {
1664 return ATA_SA150;
1665 }
1666 return ATA_SA150;
1667 }
1668
1669 if (ident->UdmaModesValid) {
1670 mode = Active ? ident->UltraDMAActive : ident->UltraDMASupport;
1671 if (mode & 0x40)
1672 return ATA_UDMA0+6;
1673 if (mode & 0x20)
1674 return ATA_UDMA0+5;
1675 if (mode & 0x10)
1676 return ATA_UDMA0+4;
1677 if (mode & 0x08)
1678 return ATA_UDMA0+3;
1679 if (mode & 0x04)
1680 return ATA_UDMA0+2;
1681 if (mode & 0x02)
1682 return ATA_UDMA0+1;
1683 if (mode & 0x01)
1684 return ATA_UDMA0+0;
1685 }
1686
1687 mode = Active ? ident->MultiWordDMAActive : ident->MultiWordDMASupport;
1688 if (ident->MultiWordDMAActive & 0x04)
1689 return ATA_WDMA0+2;
1690 if (ident->MultiWordDMAActive & 0x02)
1691 return ATA_WDMA0+1;
1692 if (ident->MultiWordDMAActive & 0x01)
1693 return ATA_WDMA0+0;
1694
1695 mode = Active ? ident->SingleWordDMAActive : ident->SingleWordDMASupport;
1696 if (ident->SingleWordDMAActive & 0x04)
1697 return ATA_SDMA0+2;
1698 if (ident->SingleWordDMAActive & 0x02)
1699 return ATA_SDMA0+1;
1700 if (ident->SingleWordDMAActive & 0x01)
1701 return ATA_SDMA0+0;
1702
1703 if (ident->PioTimingsValid) {
1704 mode = ident->AdvancedPIOModes;
1706 return ATA_PIO0+5;
1708 return ATA_PIO0+4;
1710 return ATA_PIO0+3;
1711 }
1712 mode = ident->PioCycleTimingMode;
1713 if (ident->PioCycleTimingMode == 2)
1714 return ATA_PIO0+2;
1715 if (ident->PioCycleTimingMode == 1)
1716 return ATA_PIO0+1;
1717 if (ident->PioCycleTimingMode == 0)
1718 return ATA_PIO0+0;
1719
GLenum mode
Definition: glext.h:6217
unsigned short USHORT
Definition: pedump.c:61
#define ATA_WDMA0
Definition: atapi.h:323
#define AdvancedPIOModes_3
Definition: atapi.h:726
#define ATA_SATA_GEN3
Definition: atapi.h:759
#define ATA_SATA_GEN2
Definition: atapi.h:758
#define ATA_SA150
Definition: atapi.h:337
#define ATA_SA300
Definition: atapi.h:338
#define ATA_SDMA0
Definition: atapi.h:318
#define AdvancedPIOModes_4
Definition: atapi.h:727
#define ATA_SATA_GEN1
Definition: atapi.h:757
#define ATA_SA600
Definition: atapi.h:339
#define AdvancedPIOModes_5
Definition: atapi.h:728
#define ATA_UDMA0
Definition: atapi.h:328
__inline BOOLEAN ata_is_sata(PIDENTIFY_DATA ident)
Definition: atapi.h:1636
#define ATA_PIO0
Definition: atapi.h:309
_In_ ULONG _In_ ULONG_PTR ident
Definition: winddi.h:3994
_In_ ULONG _In_ BOOLEAN Active
Definition: potypes.h:561

Referenced by ata_check_unit(), and IssueIdentify().

◆ ata_is_sata()

__inline BOOLEAN ata_is_sata ( PIDENTIFY_DATA  ident)

Definition at line 1636 of file atapi.h.

1641{

Referenced by ata_cur_mode_from_ident(), and AtapiDmaInit().

◆ AtaCommand()

UCHAR NTAPI AtaCommand ( IN struct _HW_DEVICE_EXTENSION deviceExtension,
IN ULONG  DeviceNumber,
IN ULONG  Channel,
IN UCHAR  command,
IN USHORT  cylinder,
IN UCHAR  head,
IN UCHAR  sector,
IN UCHAR  count,
IN UCHAR  feature,
IN ULONG  flags 
)

Referenced by AtaSetTransferMode().

◆ AtaCommand48()

UCHAR NTAPI AtaCommand48 ( IN struct _HW_DEVICE_EXTENSION deviceExtension,
IN ULONG  DeviceNumber,
IN ULONG  Channel,
IN UCHAR  command,
IN ULONGLONG  lba,
IN USHORT  count,
IN USHORT  feature,
IN ULONG  flags 
)

◆ AtapiCheckInterrupt__()

UCHAR NTAPI AtapiCheckInterrupt__ ( IN PVOID  HwDeviceExtension,
IN UCHAR  c 
)
  • clear interrupt and get status *‍/

Definition at line 4512 of file id_ata.cpp.

4516{
4517 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4518 PHW_CHANNEL chan = &(deviceExtension->chan[c]);
4519 PHW_LU_EXTENSION LunExt;
4520
4521 ULONG VendorID = deviceExtension->DevID & 0xffff;
4522 ULONG ChipType = deviceExtension->HwFlags & CHIPTYPE_MASK;
4523
4524 ULONG status;
4525 ULONG pr_status = 0;
4526 UCHAR dma_status = 0;
4527 UCHAR reg8 = 0;
4528 ULONG reg32 = 0;
4529 UCHAR statusByte = 0;
4530 ULONG slotNumber = deviceExtension->slotNumber;
4531 ULONG SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
4532 ULONG ChipFlags = deviceExtension->HwFlags & CHIPFLAG_MASK;
4533 UCHAR Channel;
4534 UCHAR lChannel;
4535 BOOLEAN DmaTransfer = FALSE;
4536 BOOLEAN OurInterrupt = FALSE;
4537 BOOLEAN StatusValid = FALSE;
4538// ULONG k;
4539 UCHAR interruptReason;
4540 BOOLEAN EarlyIntr = FALSE;
4541 BOOLEAN SingleBlockIntr = FALSE;
4542
4543 KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__:\n"));
4544
4545 lChannel = c;
4546 Channel = (UCHAR)(deviceExtension->Channel + lChannel);
4547 LunExt = chan->lun[chan->cur_cdev];
4548
4549 //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ chan %#x:\n", chan));
4550 //KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__ (%d/%d):\n", Channel, chan->cur_cdev));
4551
4552 if((ChipFlags & UNIATA_AHCI) &&
4553 UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4554
4555 if(!UniataAhciChanImplemented(deviceExtension, lChannel)) {
4556 return OurInterrupt;
4557 }
4558
4559 OurInterrupt = UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
4560 if((OurInterrupt == INTERRUPT_REASON_UNEXPECTED) &&
4561 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE)) {
4562 UniataAhciWaitCommandReady(chan, 2 /* ms */ );
4563 statusByte = (UCHAR)UniataAhciWaitReady(chan, 0 /* immediate */);
4564 if(!(statusByte & (IDE_STATUS_BUSY)) ) {
4565 KdPrint2((PRINT_PREFIX "ATAPI special case READY\n"));
4566 //deviceExtension->ExpectingInterrupt++; // will be updated in ISR on ReturnEnableInterrupts
4567 OurInterrupt = INTERRUPT_REASON_OUR;
4568 } else
4569 if((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRDY)) == (IDE_STATUS_BUSY | IDE_STATUS_DRDY) ) {
4570 KdPrint2((PRINT_PREFIX "ATAPI special case pre ERR-READY\n"));
4571 OurInterrupt = INTERRUPT_REASON_OUR;
4572 } else
4573 if(statusByte & IDE_STATUS_ERROR) {
4574 KdPrint2((PRINT_PREFIX "ATAPI special case ERR-READY\n"));
4575 OurInterrupt = INTERRUPT_REASON_OUR;
4576 } else {
4577 KdPrint2((PRINT_PREFIX "ATAPI special case ? %x\n", statusByte));
4578 OurInterrupt = INTERRUPT_REASON_OUR;
4579 }
4580 }
4581 return OurInterrupt;
4582 }
4583
4585 DmaTransfer = TRUE;
4586 KdPrint2((PRINT_PREFIX " cntrlr %#x:%#x, lch %#x DmaTransfer = TRUE\n", deviceExtension->DevIndex,
4587 deviceExtension->Channel + c, c));
4588 } else {
4589 KdPrint2((PRINT_PREFIX " cntrlr %#x:%#x, lch %#x DmaTransfer = FALSE\n", deviceExtension->DevIndex,
4590 deviceExtension->Channel + c, c));
4591 dma_status = GetDmaStatus(deviceExtension, lChannel);
4592 KdPrint2((PRINT_PREFIX " DMA status %#x\n", dma_status));
4593 }
4594
4595 // do controller-specific interrupt servicing staff
4596 if(deviceExtension->UnknownDev) {
4597 KdPrint2((PRINT_PREFIX " UnknownDev\n"));
4598 goto check_unknown;
4599 }
4600
4601 // Attention !
4602 // We can catch (BM_STATUS_ACTIVE + BM_STATUS_INTR) when operation is actually completed
4603 // Such behavior was observed with Intel ICH-xxx chips
4604 // This condition shall also be treated as 'our interrupt' because of BM_STATUS_INTR flag
4605
4606 switch(VendorID) {
4607
4608 case ATA_PROMISE_ID: {
4609 switch(ChipType) {
4610 case PROLD:
4611 case PRNEW:
4612 status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x1c);
4613 if (!DmaTransfer)
4614 break;
4615 if (!(status &
4616 ((Channel) ? 0x00004000 : 0x00000400))) {
4617 KdPrint2((PRINT_PREFIX " Promise old/new unexpected\n"));
4619 }
4620 break;
4621 case PRTX:
4624 if (!DmaTransfer)
4625 break;
4626 if(!(status & 0x20)) {
4627 KdPrint2((PRINT_PREFIX " Promise tx unexpected\n"));
4629 }
4630 break;
4631 case PRMIO: {
4632 ULONG stat_reg = (ChipFlags & PRG2) ? 0x60 : 0x6c;
4633 status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40);
4634 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),0x40, status);
4635
4636 if(status & (1 << (Channel+1))) {
4637 // our
4638 } else {
4639 KdPrint2((PRINT_PREFIX " Promise mio unexpected\n"));
4641 }
4642
4643 if(!(ChipFlags & UNIATA_SATA))
4644 break;
4645
4646 pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg);
4647 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressBM_0),stat_reg, (pr_status & (0x11 << Channel)));
4648 if(pr_status & (0x11 << Channel)) {
4649 // TODO: reset channel
4650 KdPrint2((PRINT_PREFIX " Promise mio unexpected + reset req\n"));
4651 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
4652 }
4653 if(!(status & (0x01 << Channel))) {
4654 // Connect event
4655 KdPrint2((PRINT_PREFIX " Promise mio unexpected attach\n"));
4656 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
4657 }
4658 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4659 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4660 } else {
4662 }
4663
4664 AtapiWritePort4(chan, IDX_BM_DeviceSpecific0, 0x00000001);
4665 break; }
4666 }
4667 break; }
4668 case ATA_NVIDIA_ID: {
4669 if(!(ChipFlags & UNIATA_SATA) || (ChipFlags & NVGEN))
4670 break;
4671
4672 KdPrint2((PRINT_PREFIX "NVIDIA\n"));
4673
4674 ULONG offs = (ChipFlags & NV4OFF) ? 0x0440 : 0x0010;
4675 ULONG shift = Channel * ((ChipFlags & NVQ) ? 4 : 16);
4676
4677 /* get and clear interrupt status */
4678 if(ChipFlags & NVQ) {
4679 pr_status = AtapiReadPortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
4680 AtapiWritePortEx4(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0fUL << shift) | 0x00f000f0);
4681 } else {
4682 pr_status = AtapiReadPortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs);
4683 AtapiWritePortEx1(chan, (ULONGIO_PTR)(&deviceExtension->BaseIoAddressSATA_0),offs, (0x0f << shift));
4684 }
4685 KdPrint2((PRINT_PREFIX " pr_status %x, shift %x\n", pr_status, shift));
4686
4687 /* check for and handle connect events */
4688 if(((pr_status & (0x0cUL << shift)) == (0x04UL << shift)) ) {
4689 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_ATTACH, 0);
4690 }
4691 /* check for and handle disconnect events */
4692 if((pr_status & (0x08UL << shift)) &&
4693 !((pr_status & (0x04UL << shift) &&
4695 UniataSataEvent(deviceExtension, lChannel, UNIATA_SATA_EVENT_DETACH, 0);
4696 }
4697 /* do we have any device action ? */
4698 if(!(pr_status & (0x01UL << shift))) {
4699 KdPrint2((PRINT_PREFIX " nVidia unexpected\n"));
4700 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4701 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4702 } else {
4704 }
4705 }
4706
4707 break; }
4708 case ATA_ATI_ID:
4709 KdPrint2((PRINT_PREFIX "ATI\n"));
4710 if(ChipType == SIIMIO) {
4711 // fall to SiI
4712 } else {
4713 break;
4714 }
4716
4717 if(ChipType == SIIMIO) {
4718
4720 KdPrint2((PRINT_PREFIX " Sii DS0 %x\n", reg32));
4721 if(reg32 == 0xffffffff) {
4722 KdPrint2((PRINT_PREFIX " Sii mio unexpected\n"));
4724 }
4726 KdPrint2((PRINT_PREFIX " Sii mio unexpected (2)\n"));
4728 }
4729
4730 if(ChipFlags & UNIATA_SATA) {
4731 if(reg32 & (BM_DS0_SII_DMA_SATA_IRQ | BM_DS0_SII_IRQ)) {
4732
4733 /* SIEN doesn't mask SATA IRQs on some 3112s. Those
4734 * controllers continue to assert IRQ as long as
4735 * SError bits are pending. Clear SError immediately.
4736 */
4737 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4738 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4739 }
4740 }
4741 }
4742
4743 if (!DmaTransfer)
4744 break;
4745 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4746 KdPrint2((PRINT_PREFIX " Sii mio unexpected (3)\n"));
4747 return OurInterrupt;
4748 }
4749 AtapiWritePort1(chan, IDX_BM_Status, dma_status & ~BM_STATUS_ERR);
4750 goto skip_dma_stat_check;
4751
4752 } else {
4753 if(!(deviceExtension->HwFlags & SIIINTR))
4754 break;
4755 GetPciConfig1(0x71, reg8);
4756 KdPrint2((PRINT_PREFIX " 0x71 = %#x\n", reg8));
4757 if (!(reg8 &
4758 (Channel ? 0x08 : 0x04))) {
4760 }
4761 if (!DmaTransfer) {
4762 KdPrint2((PRINT_PREFIX " cmd our\n"));
4763 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4764 }
4765 SetPciConfig1(0x71, (Channel ? 0x08 : 0x04));
4766 }
4767 break;
4768
4769 case ATA_ACARD_ID:
4770 if (!DmaTransfer)
4771 break;
4772 //dma_status = GetDmaStatus(deviceExtension, lChannel);
4773 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4774 KdPrint2((PRINT_PREFIX " Acard unexpected\n"));
4776 }
4777 AtapiWritePort1(chan, IDX_BM_Status, dma_status | BM_STATUS_INTR);
4781 goto skip_dma_stat_check;
4782 case ATA_INTEL_ID:
4783 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4784 if(ChipFlags & UNIATA_AHCI) {
4785 // Do nothing here
4786 } else
4787 if(ChipFlags & UNIATA_SATA) {
4788 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4789 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4790 }
4791 if(!(chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE)) {
4793 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4794 }
4795 }
4796 }
4797 }
4798 break;
4799 default:
4800 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
4801 if(ChipFlags & UNIATA_AHCI) {
4802 // Do nothing here
4803 } else
4804 if(ChipFlags & UNIATA_SATA) {
4805 if(UniataSataClearErr(HwDeviceExtension, c, UNIATA_SATA_DO_CONNECT, 0)) {
4806 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4807 }
4808 }
4809 }
4810 }
4811check_unknown:
4812 KdPrint2((PRINT_PREFIX " perform generic check\n"));
4813 if (DmaTransfer) {
4814 if (!((dma_status = GetDmaStatus(deviceExtension, lChannel)) & BM_STATUS_INTR)) {
4815 KdPrint2((PRINT_PREFIX " DmaTransfer + !BM_STATUS_INTR (%x)\n", dma_status));
4816 if(dma_status & BM_STATUS_ERR) {
4817 KdPrint2((PRINT_PREFIX " DmaTransfer + BM_STATUS_ERR -> our\n"));
4818 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4819 } else {
4820 KdPrint2((PRINT_PREFIX " getting status...\n"));
4821 GetStatus(chan, statusByte);
4822 StatusValid = 1;
4823 KdPrint2((PRINT_PREFIX " status %#x\n", statusByte));
4824 if(statusByte & IDE_STATUS_ERROR) {
4825 KdPrint2((PRINT_PREFIX " IDE_STATUS_ERROR -> our\n", statusByte));
4826 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4827 } else
4828 if ((statusByte & IDE_STATUS_DSC) &&
4829 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
4830 (dma_status == BM_STATUS_ACTIVE)) {
4831 KdPrint2((PRINT_PREFIX " special case DMA + ATAPI + IDE_STATUS_DSC -> our\n", statusByte));
4832 // some devices interrupts on each block transfer even in DMA mode
4833 if(LunExt->TransferMode >= ATA_SDMA && LunExt->TransferMode <= ATA_WDMA2) {
4834 KdPrint2((PRINT_PREFIX " wait for completion\n"));
4836 //GetBaseStatus(chan, statusByte);
4837 //return INTERRUPT_REASON_IGNORE;
4838 SingleBlockIntr = TRUE;
4839 }
4840 } else {
4842 }
4843 }
4844 }
4845 } else {
4846 if(dma_status & BM_STATUS_INTR) {
4847 // bullshit, we have DMA interrupt, but had never initiate DMA operation
4848 KdPrint2((PRINT_PREFIX " clear unexpected DMA intr\n"));
4849 AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
4850 // catch it !
4851 OurInterrupt = INTERRUPT_REASON_UNEXPECTED;
4852 }
4853 }
4854skip_dma_stat_check:
4855 if(!(ChipFlags & UNIATA_SATA) && chan->ExpectingInterrupt) {
4857 }
4858
4859 /* if drive is busy it didn't interrupt */
4860 /* the exception is DCS + BSY state of ATAPI devices */
4861 if(!StatusValid) {
4862 KdPrint2((PRINT_PREFIX " getting status...\n"));
4863 GetStatus(chan, statusByte);
4864 }
4865 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4866 KdPrint3((PRINT_PREFIX " ATAPI status %#x\n", statusByte));
4867 } else {
4868 KdPrint2((PRINT_PREFIX " IDE status %#x\n", statusByte));
4869 }
4870 if (statusByte == IDE_STATUS_WRONG) {
4871 // interrupt from empty controller ?
4872 } else
4873 if (statusByte & IDE_STATUS_BUSY) {
4874 if(!chan->ExpectingInterrupt) {
4875 KdPrint3((PRINT_PREFIX " unexpected intr + BUSY\n"));
4876 return OurInterrupt;
4877 }
4878
4879 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4880 KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
4881 } else {
4882 KdPrint2((PRINT_PREFIX " expecting intr + BUSY (3), non ATAPI\n"));
4884 }
4885 if((statusByte & ~(IDE_STATUS_DRQ | IDE_STATUS_INDEX)) !=
4887 KdPrint3((PRINT_PREFIX " unexpected status, seems it is not our\n"));
4889 }
4890 if(!(LunExt->DeviceFlags & DFLAGS_INT_DRQ) && (statusByte & IDE_STATUS_DRQ)) {
4891 KdPrint3((PRINT_PREFIX " unexpected DRQ, seems it is not our\n"));
4893 }
4894
4895 EarlyIntr = TRUE;
4896
4897 if(dma_status & BM_STATUS_INTR) {
4898 KdPrint3((PRINT_PREFIX " our interrupt with BSY set, try wait in ISR or post to DPC\n"));
4899 /* clear interrupt and get status */
4900 GetBaseStatus(chan, statusByte);
4901 if(!(dma_status & BM_STATUS_ACTIVE)) {
4902 AtapiDmaDone(deviceExtension, DEVNUM_NOT_SPECIFIED ,lChannel, NULL);
4903 }
4904 KdPrint3((PRINT_PREFIX " base status %#x (+BM_STATUS_INTR)\n", statusByte));
4905 return INTERRUPT_REASON_OUR;
4906 }
4907
4908 if(g_WaitBusyInISR) {
4909 GetStatus(chan, statusByte);
4910 KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
4911 reg8 = AtapiReadPort1(chan, IDX_IO1_i_Error);
4912 KdPrint2((PRINT_PREFIX " Error reg (%#x)\n", reg8));
4913 if (!(statusByte & IDE_STATUS_BUSY)) {
4914 KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
4915 }
4916 if (statusByte & IDE_STATUS_BUSY) {
4917 KdPrint2((PRINT_PREFIX " still BUSY, seems it is not our\n"));
4919 }
4920 }
4921
4922 }
4923
4924 /* clear interrupt and get status */
4925 GetBaseStatus(chan, statusByte);
4926 KdPrint2((PRINT_PREFIX " base status %#x\n", statusByte));
4927 if (statusByte == IDE_STATUS_WRONG) {
4928 // interrupt from empty controller ?
4929 } else
4930 if(!(statusByte & (IDE_STATUS_DRQ | IDE_STATUS_DRDY))) {
4931 KdPrint2((PRINT_PREFIX " no DRQ/DRDY set\n"));
4932 return OurInterrupt;
4933 }
4934
4935#ifndef UNIATA_PIO_ONLY
4936 if(DmaTransfer) {
4937 if(!SingleBlockIntr && (!EarlyIntr || g_WaitBusyInISR)) {
4938 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
4939 } else {
4941 PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
4942
4943 //ASSERT(AtaReq);
4944
4945 if(SingleBlockIntr) {
4946 KdPrint2((PRINT_PREFIX " set REQ_STATE_ATAPI_EXPECTING_DATA_INTR2.\n"));
4947 } else {
4948 KdPrint2((PRINT_PREFIX " set REQ_STATE_EARLY_INTR.\n"));
4949 }
4950 if(AtaReq) {
4952 }
4953 }
4954 }
4955#endif //
4956
4957 if (!(chan->ExpectingInterrupt)) {
4958
4959 KdPrint2((PRINT_PREFIX " Unexpected interrupt.\n"));
4960
4961 if(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) {
4962 KdPrint2((PRINT_PREFIX " ATAPI additional check\n"));
4963 } else {
4964 KdPrint2((PRINT_PREFIX " OurInterrupt = %d\n", OurInterrupt));
4965 return OurInterrupt;
4966 }
4968 KdPrint3((PRINT_PREFIX "AtapiCheckInterrupt__: ATAPI int reason %x\n", interruptReason));
4969 return OurInterrupt;
4970 }
4971 //ASSERT(!chan->queue_depth || chan->cur_req);
4972
4973 KdPrint2((PRINT_PREFIX "AtapiCheckInterrupt__: exit with TRUE\n"));
4974 return INTERRUPT_REASON_OUR;
4975
4976} // end AtapiCheckInterrupt__()
unsigned char BOOLEAN
#define DFLAGS_ATAPI_DEVICE
Definition: atapi.h:41
#define GetBaseStatus(BaseIoAddress, Status)
Definition: atapi.h:331
#define GetStatus(BaseIoAddress, Status)
Definition: atapi.h:328
#define DFLAGS_INT_DRQ
Definition: atapi.h:43
struct _HW_DEVICE_EXTENSION * PHW_DEVICE_EXTENSION
#define ATA_INTEL_ID
Definition: bm_devs_decl.h:184
#define NV4OFF
Definition: bm_devs_decl.h:697
#define PRNEW
Definition: bm_devs_decl.h:646
#define NVQ
Definition: bm_devs_decl.h:698
#define PRTX
Definition: bm_devs_decl.h:647
#define CHIPTYPE_MASK
Definition: bm_devs_decl.h:620
#define SIIMIO
Definition: bm_devs_decl.h:665
#define UNIATA_SATA
Definition: bm_devs_decl.h:626
#define ATA_ACARD_ID
Definition: bm_devs_decl.h:111
#define PRG2
Definition: bm_devs_decl.h:654
#define UNIATA_AHCI
Definition: bm_devs_decl.h:629
#define NVGEN
Definition: bm_devs_decl.h:699
#define PROLD
Definition: bm_devs_decl.h:645
#define ATA_PROMISE_ID
Definition: bm_devs_decl.h:454
#define PRMIO
Definition: bm_devs_decl.h:648
#define ATA_NVIDIA_ID
Definition: bm_devs_decl.h:355
#define ATA_ATI_ID
Definition: bm_devs_decl.h:147
#define SIIINTR
Definition: bm_devs_decl.h:668
#define CHIPFLAG_MASK
Definition: bm_devs_decl.h:621
#define ATA_SILICON_IMAGE_ID
Definition: bm_devs_decl.h:507
#define BM_DS0_SII_DMA_COMPLETE
Definition: bsmaster.h:160
UCHAR NTAPI AtapiDmaDone(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:685
#define BM_STATUS_ERR
Definition: bsmaster.h:143
VOID DDKFASTAPI AtapiWritePortEx1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN UCHAR data)
#define IDX_BM_DeviceSpecific1
Definition: bsmaster.h:170
#define BM_DS0_SII_DMA_ENABLE
Definition: bsmaster.h:156
#define IDX_BM_DeviceSpecific0
Definition: bsmaster.h:168
UCHAR DDKFASTAPI AtapiReadPort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
ULONG DDKFASTAPI AtapiReadPort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port)
#define GetPciConfig1(offs, op)
Definition: bsmaster.h:1620
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR2
Definition: bsmaster.h:953
#define BM_STATUS_ACTIVE
Definition: bsmaster.h:142
VOID DDKFASTAPI AtapiWritePortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs, IN ULONG data)
#define BM_DS0_SII_DMA_ERROR
Definition: bsmaster.h:159
#define IDX_BM_Status
Definition: bsmaster.h:169
#define BM_DS0_SII_IRQ
Definition: bsmaster.h:157
ULONG DDKFASTAPI AtapiReadPortEx4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
#define BM_DS0_SII_DMA_SATA_IRQ
Definition: bsmaster.h:158
VOID DDKFASTAPI AtapiWritePort4(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG data)
union _ATA_REQ * PATA_REQ
#define IDX_BM_Command
Definition: bsmaster.h:167
#define REQ_STATE_EARLY_INTR
Definition: bsmaster.h:956
#define BM_STATUS_INTR
Definition: bsmaster.h:144
VOID DDKFASTAPI AtapiWritePort1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN UCHAR data)
#define CTRFLAGS_NO_SLAVE
Definition: bsmaster.h:1139
#define IDX_SATA_SStatus
Definition: bsmaster.h:457
#define BM_COMMAND_START_STOP
Definition: bsmaster.h:150
UCHAR DDKFASTAPI AtapiReadPortEx1(IN PHW_CHANNEL chan, IN ULONGIO_PTR port, IN ULONG offs)
#define GetDmaStatus(de, c)
Definition: bsmaster.h:1711
#define SetPciConfig1(offs, op)
Definition: bsmaster.h:1630
#define CTRFLAGS_DMA_ACTIVE
Definition: bsmaster.h:1131
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define ULONGIO_PTR
Definition: config.h:102
const GLubyte * c
Definition: glext.h:8905
#define IDE_STATUS_WRONG
Definition: hwide.h:121
#define IDE_STATUS_INDEX
Definition: hwide.h:111
#define IDE_STATUS_DRDY
Definition: hwide.h:117
#define IDX_ATAPI_IO1_i_InterruptReason
Definition: hwide.h:89
#define IDE_STATUS_BUSY
Definition: hwide.h:119
#define IDE_STATUS_ERROR
Definition: hwide.h:110
#define IDE_STATUS_DRQ
Definition: hwide.h:113
#define IDE_STATUS_DSC
Definition: hwide.h:114
#define IDX_IO1_i_Error
Definition: hwide.h:42
ULONG g_WaitBusyInISR
Definition: id_ata.cpp:87
PSCSI_REQUEST_BLOCK NTAPI UniataGetCurRequest(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:358
ULONG NTAPI UniataAhciWaitReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1853
UCHAR NTAPI UniataAhciStatus(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1131
BOOLEAN NTAPI UniataSataClearErr(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN BOOLEAN do_connect, IN ULONG pm_port)
Definition: id_sata.cpp:186
UCHAR NTAPI UniataAhciWaitCommandReady(IN PHW_CHANNEL chan, IN ULONG timeout)
Definition: id_sata.cpp:1434
ULONG NTAPI UniataSataReadPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG pm_port)
Definition: id_sata.cpp:270
BOOLEAN NTAPI UniataSataEvent(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG Action, IN ULONG pm_port)
Definition: id_sata.cpp:233
#define UNIATA_SATA_IGNORE_CONNECT
Definition: id_sata.h:61
#define UNIATA_SATA_EVENT_ATTACH
Definition: id_sata.h:72
__inline BOOLEAN UniataAhciChanImplemented(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_sata.h:415
#define UNIATA_SATA_DO_CONNECT
Definition: id_sata.h:60
__inline BOOLEAN UniataIsSATARangeAvailable(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG lChannel)
Definition: id_sata.h:91
#define UNIATA_SATA_EVENT_DETACH
Definition: id_sata.h:73
#define c
Definition: ke_i.h:80
#define shift
Definition: input.c:1755
ULONG ChannelCtrlFlags
Definition: bsmaster.h:1059
ULONG cur_cdev
Definition: bsmaster.h:1022
ULONG lChannel
Definition: bsmaster.h:1064
struct _HW_LU_EXTENSION * lun[IDE_MAX_LUN_PER_CHAN]
Definition: bsmaster.h:1088
BOOLEAN ExpectingInterrupt
Definition: bsmaster.h:1032
struct _HW_DEVICE_EXTENSION * DeviceExtension
Definition: bsmaster.h:1087
PHW_CHANNEL chan
Definition: bsmaster.h:1257
UCHAR TransferMode
Definition: bsmaster.h:1171
PVOID SrbExtension
Definition: srb.h:267
Definition: ps.c:97
uint32_t ULONG
Definition: typedefs.h:59
#define INTERRUPT_REASON_UNEXPECTED
Definition: atapi.h:1280
#define ATA_SDMA
Definition: atapi.h:317
#define ATA_WDMA2
Definition: atapi.h:325
#define ATAPI_IR_Mask
Definition: atapi.h:551
#define KdPrint3(_x_)
Definition: atapi.h:153
#define KdPrint2(_x_)
Definition: atapi.h:154
#define DEVNUM_NOT_SPECIFIED
Definition: atapi.h:1483
#define INTERRUPT_REASON_IGNORE
Definition: atapi.h:1278
#define PRINT_PREFIX
Definition: atapi.h:150
#define INTERRUPT_REASON_OUR
Definition: atapi.h:1279
UCHAR ReqState
Definition: bsmaster.h:893

Referenced by AtapiInterrupt(), AtapiInterrupt2(), and IdeSendCommand().

◆ AtapiDisableInterrupts()

VOID NTAPI AtapiDisableInterrupts ( IN PVOID  HwDeviceExtension,
IN ULONG  c 
)

Definition at line 4457 of file id_ata.cpp.

4461{
4462 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4463 PHW_CHANNEL chan;
4464 if(c >= deviceExtension->NumberChannels) {
4465 KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: WRONG CHANNEL\n",c));
4466 return;
4467 }
4468 chan = &(deviceExtension->chan[c]);
4469 KdPrint2((PRINT_PREFIX "AtapiDisableInterrupts_%d: %d\n",c, chan->DisableIntr));
4470 // mark channel as busy
4471 if(InterlockedIncrement(&chan->DisableIntr)) {
4472 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4474 } else {
4475 //SelectDrive(chan, 0);
4477 IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4478 //if(chan->NumberLuns) {
4479 // SelectDrive(chan, 1);
4480 // AtapiWritePort1(chan, IDX_IO2_o_Control,
4481 // IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4482 // SelectDrive(chan, chan->cur_cdev);
4483 //}
4484 }
4486 }
4487
4488 return;
4489} // end AtapiDisableInterrupts()
#define InterlockedIncrement
Definition: armddk.h:53
#define IDX_AHCI_P_IE
Definition: bsmaster.h:685
#define CTRFLAGS_INTR_DISABLED
Definition: bsmaster.h:1134
#define IDE_DC_DISABLE_INTERRUPTS
Definition: hwide.h:138
#define IDX_IO2_o_Control
Definition: hwide.h:62
__inline VOID UniataAhciWriteChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx, IN ULONG data)
Definition: id_sata.h:302
LONG DisableIntr
Definition: bsmaster.h:1061
ULONG NumberChannels
Definition: atapi.c:68

Referenced by AtapiAdapterControl(), AtapiHwInitialize__(), AtapiInterrupt(), AtapiInterrupt__(), AtapiResetController__(), AtapiSendCommand(), AtapiStartIo__(), AtaSetTransferMode(), FindDevices(), IdeSendCommand(), IssueIdentify(), and UniataUserDeviceReset().

◆ AtapiDpcDispatch()

VOID NTAPI AtapiDpcDispatch ( IN PKDPC  Dpc,
IN PVOID  DeferredContext,
IN PVOID  SystemArgument1,
IN PVOID  SystemArgument2 
)

◆ AtapiEnableInterrupts()

VOID NTAPI AtapiEnableInterrupts ( IN PVOID  HwDeviceExtension,
IN ULONG  c 
)

Definition at line 4397 of file id_ata.cpp.

4401{
4402 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4403 PHW_CHANNEL chan;
4404 //UCHAR statusByte;
4405
4406 if(c >= deviceExtension->NumberChannels) {
4407 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: WRONG CHANNEL\n",c));
4408 return;
4409 }
4410 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
4411 !UniataAhciChanImplemented(deviceExtension, c)) {
4412 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: not imp. CHANNEL\n",c));
4413 return;
4414 }
4415
4416 chan = &(deviceExtension->chan[c]);
4417 KdPrint2((PRINT_PREFIX "AtapiEnableInterrupts_%d: %d\n",c, chan->DisableIntr));
4418 if(!InterlockedDecrement(&chan->DisableIntr)) {
4419 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4423 ((/*ch->pm_level == */0) ? ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC : 0) |
4424 ATA_AHCI_P_IX_PRC | ATA_AHCI_P_IX_PC | /* DEBUG */
4428 );
4429 } else {
4430 //SelectDrive(chan, 0);
4431 //GetBaseStatus(chan, statusByte);
4433 0 | IDE_DC_A_4BIT );
4434 //if(chan->NumberLuns) {
4435 // SelectDrive(chan, 1);
4436 // GetBaseStatus(chan, statusByte);
4437 // AtapiWritePort1(chan, IDX_IO2_o_Control,
4438 // IDE_DC_A_4BIT );
4439 // SelectDrive(chan, chan->cur_cdev);
4440 //}
4441 }
4442 chan->ChannelCtrlFlags &= ~CTRFLAGS_INTR_DISABLED;
4443 } else {
4444 if(deviceExtension->HwFlags & UNIATA_AHCI) {
4445 // keep interrupts disabled
4447 } else {
4449 IDE_DC_DISABLE_INTERRUPTS /*| IDE_DC_A_4BIT*/ );
4450 }
4451 }
4452 return;
4453} // end AtapiEnableInterrupts()
#define InterlockedDecrement
Definition: armddk.h:52
#define ATA_AHCI_P_IX_PC
Definition: bsmaster.h:505
#define ATA_AHCI_P_IX_HBD
Definition: bsmaster.h:513
#define ATA_AHCI_P_IX_DS
Definition: bsmaster.h:501
#define ATA_AHCI_P_IX_TFE
Definition: bsmaster.h:515
#define ATA_AHCI_P_IX_DI
Definition: bsmaster.h:506
#define ATA_AHCI_P_IX_HBF
Definition: bsmaster.h:514
#define ATA_AHCI_P_IX_SDB
Definition: bsmaster.h:502
#define ATA_AHCI_P_IX_IF
Definition: bsmaster.h:512
#define ATA_AHCI_P_IX_DHR
Definition: bsmaster.h:499
#define ATA_AHCI_P_IX_DP
Definition: bsmaster.h:504
#define ATA_AHCI_P_IX_INF
Definition: bsmaster.h:511
#define ATA_AHCI_P_IX_PRC
Definition: bsmaster.h:508
#define ATA_AHCI_P_IX_UF
Definition: bsmaster.h:503
#define ATA_AHCI_P_IX_CPD
Definition: bsmaster.h:516
#define ATA_AHCI_P_IX_PS
Definition: bsmaster.h:500
#define ATA_AHCI_P_IX_OF
Definition: bsmaster.h:510
#define IDE_DC_A_4BIT
Definition: hwide.h:140

Referenced by AtapiAdapterControl(), AtapiCallBack__(), AtapiEnableInterrupts__(), AtapiHwInitialize__(), AtapiInterrupt(), AtapiInterrupt__(), AtapiResetController__(), AtapiSendCommand(), AtapiStartIo__(), AtaSetTransferMode(), FindDevices(), IdeSendCommand(), IssueIdentify(), and UniataUserDeviceReset().

◆ AtapiFindIsaController()

ULONG NTAPI AtapiFindIsaController ( IN PVOID  HwDeviceExtension,
IN PVOID  Context,
IN PVOID  BusInformation,
IN PCHAR  ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
OUT PBOOLEAN  Again 
)

Definition at line 2243 of file id_probe.cpp.

2251{
2252 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2253 PHW_CHANNEL chan;
2254 PULONG adapterCount = (PULONG)Context;
2255 PUCHAR ioSpace = NULL;
2256 ULONG i;
2257 ULONG irq=0;
2258 ULONG portBase=0;
2259 ULONG retryCount;
2260// BOOLEAN atapiOnly;
2261 UCHAR statusByte, statusByte2;
2262 BOOLEAN preConfig = FALSE;
2263 //
2264 PIDE_REGISTERS_1 BaseIoAddress1;
2265 PIDE_REGISTERS_2 BaseIoAddress2 = NULL;
2266
2267 // The following table specifies the ports to be checked when searching for
2268 // an IDE controller. A zero entry terminates the search.
2269 static CONST ULONG AdapterAddresses[5] = {IO_WD1, IO_WD2, IO_WD1-8, IO_WD2-8, 0};
2270// CONST UCHAR Channels[5] = {0, 1, 0, 1, 0};
2271
2272 // The following table specifies interrupt levels corresponding to the
2273 // port addresses in the previous table.
2274 static CONST ULONG InterruptLevels[5] = {14, 15, 11, 10, 0};
2275
2276 KdPrint2((PRINT_PREFIX "AtapiFindIsaController (ISA):\n"));
2277
2278 if (!deviceExtension) {
2279 return SP_RETURN_ERROR;
2280 }
2281 RtlZeroMemory(deviceExtension, sizeof(HW_DEVICE_EXTENSION));
2282
2283 KdPrint2((PRINT_PREFIX " assume max PIO4\n"));
2284 deviceExtension->MaxTransferMode = ATA_PIO4;
2285 deviceExtension->NumberChannels = 1;
2286 deviceExtension->NumberLuns = IDE_MAX_LUN_PER_CHAN; // default
2287
2288 if(!UniataAllocateLunExt(deviceExtension, UNIATA_ALLOCATE_NEW_LUNS)) {
2289 goto exit_error;
2290 }
2291
2292 chan = &(deviceExtension->chan[0]);
2293 AtapiSetupLunPtrs(chan, deviceExtension, 0);
2294
2295 deviceExtension->AdapterInterfaceType =
2296 deviceExtension->OrigAdapterInterfaceType
2297 = ConfigInfo->AdapterInterfaceType;
2298
2299#ifndef UNIATA_CORE
2300
2301 /* do extra chipset specific setups */
2304
2305 // Check to see if this is a special configuration environment.
2306 portBase = irq = 0;
2307 if (ArgumentString) {
2308
2309 irq = AtapiParseArgumentString(ArgumentString, "Interrupt");
2310 if (irq ) {
2311
2312 // Both parameters must be present to proceed
2313 portBase = AtapiParseArgumentString(ArgumentString, "BaseAddress");
2314 if (!portBase) {
2315
2316 // Try a default search for the part.
2317 irq = 0;
2318 }
2319 }
2320 }
2321
2322#endif //UNIATA_CORE
2323/*
2324 for(i=0; i<2; i++) {
2325 if((*ConfigInfo->AccessRanges)[i].RangeStart) {
2326 KdPrint2((PRINT_PREFIX " IoRange[%d], start %#x, len %#x, mem %#x\n",
2327 i,
2328 ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[i].RangeStart),
2329 (*ConfigInfo->AccessRanges)[i].RangeLength,
2330 (*ConfigInfo->AccessRanges)[i].RangeInMemory
2331 ));
2332 }
2333 }
2334*/
2335// if((*ConfigInfo->AccessRanges)[0].RangeStart) {
2336 portBase = ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[0].RangeStart);
2337// }
2338 if(portBase) {
2339 if(!AtapiCheckIOInterference(ConfigInfo, portBase)) {
2340 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2341 ConfigInfo->AdapterInterfaceType,
2342 ConfigInfo->SystemIoBusNumber,
2343 (*ConfigInfo->AccessRanges)[0].RangeStart,
2344 (*ConfigInfo->AccessRanges)[0].RangeLength,
2345 (BOOLEAN) !((*ConfigInfo->AccessRanges)[0].RangeInMemory));
2346 } else {
2347 // do not touch resources, just fail later inside loop on next call to
2348 // AtapiCheckIOInterference()
2349 }
2350 *Again = FALSE;
2351 // Since we have pre-configured information we only need to go through this loop once
2352 preConfig = TRUE;
2353 KdPrint2((PRINT_PREFIX " preconfig, portBase=%x, len=%x\n", portBase, (*ConfigInfo->AccessRanges)[0].RangeLength));
2354 }
2355
2356 // Scan through the adapter address looking for adapters.
2357#ifndef UNIATA_CORE
2358 while (AdapterAddresses[*adapterCount] != 0) {
2359#else
2360 do {
2361#endif //UNIATA_CORE
2362
2363 retryCount = 4;
2364 deviceExtension->DevIndex = (*adapterCount); // this is used inside AtapiRegCheckDevValue()
2365 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: adapterCount=%d\n", *adapterCount));
2366
2367 for (i = 0; i < deviceExtension->NumberLuns; i++) {
2368 // Zero device fields to ensure that if earlier devices were found,
2369 // but not claimed, the fields are cleared.
2371 }
2372 // Get the system physical address for this IO range.
2373
2374 // Check if configInfo has the default information
2375 // if not, we go and find ourselves
2376 if (preConfig == FALSE) {
2377
2378 ULONG portBase_reg = 0;
2379 ULONG irq_reg = 0;
2380
2381 if (!portBase) {
2382 portBase = AdapterAddresses[*adapterCount];
2383 KdPrint2((PRINT_PREFIX "portBase[%d]=%x\n", *adapterCount, portBase));
2384 } else {
2385 KdPrint2((PRINT_PREFIX "portBase=%x\n", portBase));
2386 }
2387
2388 portBase_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"PortBase", 0);
2389 irq_reg = AtapiRegCheckDevValue(deviceExtension, CHAN_NOT_SPECIFIED, DEVNUM_NOT_SPECIFIED, L"Irq", 0);
2390 if(portBase_reg && irq_reg) {
2391 KdPrint2((PRINT_PREFIX "use registry settings portBase=%x, irq=%d\n", portBase_reg, irq_reg));
2392 portBase = portBase_reg;
2393 irq = irq_reg;
2394 }
2395 // check if Primary/Secondary Master IDE claimed
2396 if(AtapiCheckIOInterference(ConfigInfo, portBase)) {
2397 goto next_adapter;
2398 }
2399 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2400 ConfigInfo->AdapterInterfaceType,
2401 ConfigInfo->SystemIoBusNumber,
2403 ATA_IOSIZE,
2404 TRUE);
2405
2406 } else {
2407 KdPrint2((PRINT_PREFIX "preconfig portBase=%x\n", portBase));
2408 // Check if Primary/Secondary Master IDE claimed
2409 // We can also get here from preConfig branc with conflicting portBase
2410 // (and thus, w/o ioSpace allocated)
2411 if(AtapiCheckIOInterference(ConfigInfo, portBase)) {
2412 goto not_found;
2413 }
2414 }
2415 BaseIoAddress1 = (PIDE_REGISTERS_1)ioSpace;
2416next_adapter:
2417 // Update the adapter count.
2418 (*adapterCount)++;
2419
2420 // Check if ioSpace accessible.
2421 if (!ioSpace) {
2422 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: !ioSpace\n"));
2423 portBase = 0;
2424 continue;
2425 }
2426
2427 // Get the system physical address for the second IO range.
2428 if (BaseIoAddress1) {
2429 if(preConfig &&
2430 !ScsiPortConvertPhysicalAddressToUlong((*ConfigInfo->AccessRanges)[1].RangeStart)) {
2431 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: PCMCIA ?\n"));
2432 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2433 ConfigInfo->AdapterInterfaceType,
2434 ConfigInfo->SystemIoBusNumber,
2435 ScsiPortConvertUlongToPhysicalAddress((ULONGIO_PTR)BaseIoAddress1 + 0x0E),
2437 TRUE);
2438 } else {
2439 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2440 ConfigInfo->AdapterInterfaceType,
2441 ConfigInfo->SystemIoBusNumber,
2444 TRUE);
2445 }
2446 }
2447 BaseIoAddress2 = (PIDE_REGISTERS_2)ioSpace;
2448 KdPrint2((PRINT_PREFIX " BaseIoAddress1=%x\n", BaseIoAddress1));
2449 KdPrint2((PRINT_PREFIX " BaseIoAddress2=%x\n", BaseIoAddress2));
2450 if(!irq) {
2451 KdPrint2((PRINT_PREFIX " expected InterruptLevel=%x\n", InterruptLevels[*adapterCount - 1]));
2452 }
2453
2454 UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
2455 UniataInitMapBM(deviceExtension, 0, FALSE);
2456
2457#ifdef _DEBUG
2458 UniataDumpATARegs(chan);
2459#endif
2460
2461 // Select master.
2462 SelectDrive(chan, 0);
2463
2464 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status);
2465 statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2466 if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) {
2467 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Status %x vs AltStatus %x missmatch, abort init ?\n", statusByte, statusByte2));
2468
2469 if(BaseIoAddress2) {
2470 ScsiPortFreeDeviceBase(HwDeviceExtension,
2471 (PCHAR)BaseIoAddress2);
2472 BaseIoAddress2 = NULL;
2473 }
2474 BaseIoAddress2 = (PIDE_REGISTERS_2)((ULONGIO_PTR)BaseIoAddress1 + 0x0E);
2475 KdPrint2((PRINT_PREFIX " try BaseIoAddress2=%x\n", BaseIoAddress2));
2476 ioSpace = (PUCHAR)ScsiPortGetDeviceBase(HwDeviceExtension,
2477 ConfigInfo->AdapterInterfaceType,
2478 ConfigInfo->SystemIoBusNumber,
2481 TRUE);
2482 if(!ioSpace) {
2483 BaseIoAddress2 = NULL;
2484 KdPrint2((PRINT_PREFIX " abort (0)\n"));
2485 goto not_found;
2486 }
2487 UniataInitMapBase(chan, BaseIoAddress1, BaseIoAddress2);
2488 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Status);
2489 statusByte2 = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2490 if((statusByte ^ statusByte2) & ~IDE_STATUS_INDEX) {
2491 KdPrint2((PRINT_PREFIX " abort: Status %x vs AltStatus %x missmatch\n", statusByte, statusByte2));
2492 goto not_found;
2493 }
2494 }
2495
2496retryIdentifier:
2497
2498 // Select master.
2499 SelectDrive(chan, 0);
2500
2501 // Check if card at this address.
2503 statusByte = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
2504
2505 // Check if indentifier can be read back.
2506 if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
2507 statusByte == IDE_STATUS_WRONG) {
2508
2509 KdPrint2((PRINT_PREFIX "AtapiFindIsaController: Identifier read back from Master (%#x)\n",
2510 statusByte));
2511
2512 statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2513
2514 if (statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
2515
2516 i = 0;
2517
2518 // Could be the TEAC in a thinkpad. Their dos driver puts it in a sleep-mode that
2519 // warm boots don't clear.
2520 do {
2521 AtapiStallExecution(1000);
2522 statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_Status);
2524 "AtapiFindIsaController: First access to status %#x\n",
2525 statusByte));
2526 } while ((statusByte & IDE_STATUS_BUSY) && ++i < 10);
2527
2528 if (retryCount-- && (!(statusByte & IDE_STATUS_BUSY))) {
2529 goto retryIdentifier;
2530 }
2531 }
2532
2533 // Select slave.
2534 SelectDrive(chan, 1);
2535 statusByte = AtapiReadPort1(chan, IDX_IO2_AltStatus);
2536
2537 // See if slave is present.
2539
2540 if (AtapiReadPort1(chan, IDX_IO1_i_CylinderLow) != 0xAA ||
2541 statusByte == IDE_STATUS_WRONG) {
2542
2544 "AtapiFindIsaController: Identifier read back from Slave (%#x)\n",
2545 statusByte));
2546 goto not_found;
2547 }
2548 }
2549
2550 // Fill in the access array information only if default params are not in there.
2551 if (preConfig == FALSE) {
2552
2553 // An adapter has been found request another call, only if we didn't get preconfigured info.
2554 *Again = TRUE;
2555
2556 if (portBase) {
2557 (*ConfigInfo->AccessRanges)[0].RangeStart = ScsiPortConvertUlongToPhysicalAddress(portBase);
2558 } else {
2559 (*ConfigInfo->AccessRanges)[0].RangeStart =
2560 ScsiPortConvertUlongToPhysicalAddress(AdapterAddresses[*adapterCount - 1]);
2561 }
2562
2563 (*ConfigInfo->AccessRanges)[0].RangeLength = ATA_IOSIZE;
2564 (*ConfigInfo->AccessRanges)[0].RangeInMemory = FALSE;
2565
2566 if(BaseIoAddress2) {
2567 if(hasPCI) {
2568 (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress((ULONG_PTR)BaseIoAddress2);
2569 (*ConfigInfo->AccessRanges)[1].RangeLength = ATA_ALTIOSIZE;
2570 (*ConfigInfo->AccessRanges)[1].RangeInMemory = FALSE;
2571 } else {
2572 // NT4 and NT3.51 on ISA-only hardware definitly fail floppy.sys load
2573 // when this range is claimed by other driver.
2574 // However, floppy should use only 0x3f0-3f5,3f7
2575 if((ULONGIO_PTR)BaseIoAddress2 >= 0x3f0 && (ULONGIO_PTR)BaseIoAddress2 <= 0x3f7) {
2576 KdPrint2((PRINT_PREFIX "!!! Possible AltStatus vs Floppy IO range interference !!!\n"));
2577 }
2578 KdPrint2((PRINT_PREFIX "Do not expose to OS on old ISA\n"));
2579 (*ConfigInfo->AccessRanges)[1].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
2580 (*ConfigInfo->AccessRanges)[1].RangeLength = 0;
2581 }
2582 }
2583
2584 // Indicate the interrupt level corresponding to this IO range.
2585 if (irq) {
2586 ConfigInfo->BusInterruptLevel = irq;
2587 } else {
2588 ConfigInfo->BusInterruptLevel = InterruptLevels[*adapterCount - 1];
2589 }
2590
2591 if (ConfigInfo->AdapterInterfaceType == MicroChannel) {
2592 ConfigInfo->InterruptMode = LevelSensitive;
2593 } else {
2594 ConfigInfo->InterruptMode = Latched;
2595 }
2596 }
2597
2598 ConfigInfo->NumberOfBuses = 1;
2599 ConfigInfo->MaximumNumberOfTargets = IDE_MAX_LUN_PER_CHAN;
2600
2601 // Indicate maximum transfer length is 64k.
2602 ConfigInfo->MaximumTransferLength = 0x10000;
2603 deviceExtension->MaximumDmaTransferLength = ConfigInfo->MaximumTransferLength;
2604
2605 KdPrint2((PRINT_PREFIX "de %#x, Channel ???\n", deviceExtension));
2606 //PrintNtConsole("de %#x, Channel %#x, nchan %#x\n",deviceExtension, channel, deviceExtension->NumberChannels);
2607
2608 KdPrint2((PRINT_PREFIX "chan = %#x\n", chan));
2609 //PrintNtConsole("chan = %#x, c=%#x\n", chan, c);
2610/*
2611 // should be already set up in AtapiSetupLunPtrs(chan, deviceExtension, 0);
2612
2613 chan->DeviceExtension = deviceExtension;
2614 chan->lChannel = 0;
2615 chan->lun[0] = &(deviceExtension->lun[0]);
2616 chan->lun[1] = &(deviceExtension->lun[1]);*/
2617
2618 /* do extra channel-specific setups */
2619 AtapiReadChipConfig(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0);
2620 AtapiChipInit(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, 0);
2621
2623 "AtapiFindIsaController: Found IDE at %#x\n",
2624 BaseIoAddress1));
2625
2626 // For Daytona, the atdisk driver gets the first shot at the
2627 // primary and secondary controllers.
2628 if (preConfig == FALSE) {
2629
2630 if (*adapterCount - 1 < 2) {
2631
2632 // Determine whether this driver is being initialized by the
2633 // system or as a crash dump driver.
2634 if (g_Dump) {
2635#ifndef UNIATA_CORE
2636 deviceExtension->DriverMustPoll = TRUE;
2637#endif //UNIATA_CORE
2638 } else {
2639 deviceExtension->DriverMustPoll = FALSE;
2640 }
2641
2642 } else {
2643 //atapiOnly = FALSE;
2644 }
2645
2646 } else {
2647
2648 //atapiOnly = FALSE;
2649 deviceExtension->DriverMustPoll = FALSE;
2650
2651 }// preConfig check
2652
2653 // Save the Interrupe Mode for later use
2654 deviceExtension->InterruptMode = ConfigInfo->InterruptMode;
2655 deviceExtension->BusInterruptLevel = ConfigInfo->BusInterruptLevel;
2656 deviceExtension->BusInterruptVector = ConfigInfo->BusInterruptVector;
2657
2659 "AtapiFindIsaController: look for devices\n"));
2660 // Search for devices on this controller.
2661 if (FindDevices(HwDeviceExtension,
2662 0,
2663 0 /* Channel */)) {
2664
2666 "AtapiFindIsaController: detected\n"));
2667 // Claim primary or secondary ATA IO range.
2668 if (portBase) {
2669 switch (portBase) {
2670 case IO_WD2:
2671 ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2672 chan->PrimaryAddress = FALSE;
2673 break;
2674 case IO_WD1:
2675 ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2676 chan->PrimaryAddress = TRUE;
2677 break;
2678 default:
2679 break;
2680 }
2681 } else {
2682 if (*adapterCount == 1) {
2683 ConfigInfo->AtdiskPrimaryClaimed = TRUE;
2684 chan->PrimaryAddress = TRUE;
2685 } else if (*adapterCount == 2) {
2686 ConfigInfo->AtdiskSecondaryClaimed = TRUE;
2687 chan->PrimaryAddress = FALSE;
2688 }
2689 }
2690
2691 if(deviceExtension->AdapterInterfaceType == Isa) {
2692 IsaCount++;
2693 } else
2694 if(deviceExtension->AdapterInterfaceType == MicroChannel) {
2695 MCACount++;
2696 }
2697
2698 ConfigInfo->NumberOfBuses++; // add virtual channel for communication port
2700 "AtapiFindIsaController: return SP_RETURN_FOUND\n"));
2701 return(SP_RETURN_FOUND);
2702 } else {
2703not_found:
2704 // No controller at this base address.
2705 if(BaseIoAddress1) {
2706 ScsiPortFreeDeviceBase(HwDeviceExtension,
2707 (PCHAR)BaseIoAddress1);
2708 BaseIoAddress1 = NULL;
2709 }
2710 if(BaseIoAddress2) {
2711 ScsiPortFreeDeviceBase(HwDeviceExtension,
2712 (PCHAR)BaseIoAddress2);
2713 BaseIoAddress2 = NULL;
2714 }
2715 for(i=0; i<2; i++) {
2717 "AtapiFindIsaController: cleanup AccessRanges %d\n", i));
2718 (*ConfigInfo->AccessRanges)[i].RangeStart = ScsiPortConvertUlongToPhysicalAddress(0);
2719 (*ConfigInfo->AccessRanges)[i].RangeLength = 0;
2720 (*ConfigInfo->AccessRanges)[i].RangeInMemory = FALSE;
2721 }
2722 irq = 0;
2723 portBase = 0;
2724 }
2725#ifndef UNIATA_CORE
2726 }
2727#else
2728 } while(FALSE);
2729#endif //UNIATA_CORE
2730
2731 // The entire table has been searched and no adapters have been found.
2732 // There is no need to call again and the device base can now be freed.
2733 // Clear the adapter count for the next bus.
2734 *Again = FALSE;
2735 *(adapterCount) = 0;
2736
2738 "AtapiFindIsaController: return SP_RETURN_NOT_FOUND\n"));
2739 UniataFreeLunExt(deviceExtension);
2740 return(SP_RETURN_NOT_FOUND);
2741
2742exit_error:
2743 UniataFreeLunExt(deviceExtension);
2744 return SP_RETURN_ERROR;
2745
2746} // end AtapiFindIsaController()
struct _IDE_REGISTERS_2 * PIDE_REGISTERS_2
#define DFLAGS_TAPE_DEVICE
Definition: atapi.h:42
#define DFLAGS_DEVICE_PRESENT
Definition: atapi.h:40
struct _IDE_REGISTERS_1 * PIDE_REGISTERS_1
ULONG NTAPI AtapiParseArgumentString(IN PCHAR String, IN PCHAR KeyWord)
Definition: atapi.c:1852
#define IDE_MAX_LUN_PER_CHAN
Definition: bm_devs_decl.h:46
SCSI_PHYSICAL_ADDRESS NTAPI ScsiPortConvertUlongToPhysicalAddress(IN ULONG_PTR UlongAddress)
Definition: scsiport.c:529
VOID NTAPI ScsiPortFreeDeviceBase(IN PVOID HwDeviceExtension, IN PVOID MappedAddress)
Definition: scsiport.c:549
PVOID NTAPI ScsiPortGetDeviceBase(IN PVOID HwDeviceExtension, IN INTERFACE_TYPE BusType, IN ULONG SystemIoBusNumber, IN SCSI_PHYSICAL_ADDRESS IoAddress, IN ULONG NumberOfBytes, IN BOOLEAN InIoSpace)
Definition: scsiport.c:571
BOOLEAN NTAPI UniataAllocateLunExt(PHW_DEVICE_EXTENSION deviceExtension, ULONG NewNumberChannels)
Definition: id_init.cpp:2891
#define ATA_ALTOFFSET
Definition: bsmaster.h:87
VOID NTAPI AtapiSetupLunPtrs(IN PHW_CHANNEL chan, IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG c)
Definition: id_init.cpp:2846
#define UNIATA_ALLOCATE_NEW_LUNS
Definition: bsmaster.h:1398
BOOLEAN g_Dump
Definition: id_ata.cpp:108
#define ATA_IOSIZE
Definition: bsmaster.h:86
BOOLEAN NTAPI AtapiReadChipConfig(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG channel)
Definition: id_init.cpp:1782
#define IO_WD2
Definition: bsmaster.h:79
#define ATA_ALTIOSIZE
Definition: bsmaster.h:89
VOID NTAPI UniataFreeLunExt(PHW_DEVICE_EXTENSION deviceExtension)
Definition: id_init.cpp:2956
BOOLEAN NTAPI AtapiChipInit(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG c)
Definition: id_init.cpp:1879
#define IO_WD1
Definition: bsmaster.h:78
BOOLEAN hasPCI
Definition: id_ata.cpp:103
MMRESULT FindDevices()
Definition: utils.c:159
#define SP_RETURN_ERROR
Definition: srb.h:523
#define SP_RETURN_FOUND
Definition: srb.h:522
#define ScsiPortConvertPhysicalAddressToUlong(Address)
Definition: srb.h:957
#define SP_RETURN_NOT_FOUND
Definition: srb.h:521
unsigned char irq
Definition: dsp.h:13
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define IDX_IO1_i_Status
Definition: hwide.h:48
#define IDX_IO1_i_CylinderLow
Definition: hwide.h:45
#define IDX_ATAPI_IO1_i_Status
Definition: hwide.h:94
#define IDX_IO1_o_CylinderLow
Definition: hwide.h:57
@ MicroChannel
Definition: hwresource.cpp:140
@ Isa
Definition: hwresource.cpp:138
ULONG IsaCount
Definition: id_probe.cpp:55
ULONG MCACount
Definition: id_probe.cpp:56
BOOLEAN NTAPI AtapiCheckIOInterference(IN PPORT_CONFIGURATION_INFORMATION ConfigInfo, ULONG portBase)
Definition: id_probe.cpp:2203
#define L(x)
Definition: ntvdm.h:50
#define CONST
Definition: pedump.c:81
@ Latched
Definition: miniport.h:81
@ LevelSensitive
Definition: miniport.h:80
BOOLEAN PrimaryAddress
Definition: bsmaster.h:1036
BOOLEAN DriverMustPoll
Definition: atapi.c:111
PHW_LU_EXTENSION lun
Definition: bsmaster.h:1256
INTERFACE_TYPE AdapterInterfaceType
Definition: bsmaster.h:1316
ULONG MaximumDmaTransferLength
Definition: bsmaster.h:1317
INTERFACE_TYPE OrigAdapterInterfaceType
Definition: bsmaster.h:1315
ULONG InterruptMode
Definition: atapi.c:47
uint32_t * PULONG
Definition: typedefs.h:59
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG_PTR
Definition: typedefs.h:65
unsigned char * PUCHAR
Definition: typedefs.h:53
ULONG NTAPI AtapiRegCheckDevValue(IN PVOID HwDeviceExtension, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11365
VOID NTAPI UniataDumpATARegs(IN struct _HW_CHANNEL *chan)
#define ATA_PIO4
Definition: atapi.h:313
#define IDX_IO2_AltStatus
Definition: atapi.h:225
VOID NTAPI UniataInitMapBase(IN struct _HW_CHANNEL *chan, IN PIDE_REGISTERS_1 BaseIoAddress1, IN PIDE_REGISTERS_2 BaseIoAddress2)
UCHAR DDKFASTAPI SelectDrive(IN struct _HW_CHANNEL *chan, IN ULONG DeviceNumber)
VOID NTAPI UniataInitMapBM(IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN struct _IDE_BUSMASTER_REGISTERS *BaseIoAddressBM_0, IN BOOLEAN MemIo)
#define CHAN_NOT_SPECIFIED
Definition: atapi.h:1481

Referenced by DriverEntry().

◆ AtapiHardReset()

VOID DDKFASTAPI AtapiHardReset ( IN struct _HW_CHANNEL chan,
IN BOOLEAN  DisableInterrupts,
IN ULONG  Delay 
)

Definition at line 948 of file id_ata.cpp.

953{
954 KdPrint2((PRINT_PREFIX "AtapiHardReset: %d, dis=%d\n", Delay, DisableInterrupts));
956 (DisableInterrupts ? IDE_DC_DISABLE_INTERRUPTS : 0));
957 chan->last_devsel = -1;
958 AtapiStallExecution(Delay);
960} // end AtapiHardReset()
#define IDE_DC_RESET_CONTROLLER
Definition: hwide.h:139
#define IDE_DC_REENABLE_CONTROLLER
Definition: hwide.h:142

Referenced by AtapiResetController__(), CheckDevice(), and FindDevices().

◆ AtapiHexToString()

VOID NTAPI AtapiHexToString ( ULONG  Value,
PCHAR Buffer 
)

◆ AtapiHwInitialize()

BOOLEAN NTAPI AtapiHwInitialize ( IN PVOID  HwDeviceExtension)

Definition at line 1282 of file atapi.c.

1301{
1302 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
1303 PIDE_REGISTERS_1 baseIoAddress;
1304 ULONG i;
1305 UCHAR statusByte, errorByte;
1306
1307
1308 for (i = 0; i < 4; i++) {
1309 if (deviceExtension->DeviceFlags[i] & DFLAGS_DEVICE_PRESENT) {
1310
1311 if (!(deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE)) {
1312
1313 //
1314 // Enable media status notification
1315 //
1316
1317 baseIoAddress = deviceExtension->BaseIoAddress1[i >> 1];
1318
1319 IdeMediaStatus(TRUE,HwDeviceExtension,i);
1320
1321 //
1322 // If supported, setup Multi-block transfers.
1323 //
1324 if (deviceExtension->MaximumBlockXfer[i]) {
1325
1326 //
1327 // Select the device.
1328 //
1329
1330 ScsiPortWritePortUchar(&baseIoAddress->DriveSelect,
1331 (UCHAR)(((i & 0x1) << 4) | 0xA0));
1332
1333 //
1334 // Setup sector count to reflect the # of blocks.
1335 //
1336
1337 ScsiPortWritePortUchar(&baseIoAddress->BlockCount,
1338 deviceExtension->MaximumBlockXfer[i]);
1339
1340 //
1341 // Issue the command.
1342 //
1343
1344 ScsiPortWritePortUchar(&baseIoAddress->Command,
1346
1347 //
1348 // Wait for busy to drop.
1349 //
1350
1351 WaitOnBaseBusy(baseIoAddress,statusByte);
1352
1353 //
1354 // Check for errors. Reset the value to 0 (disable MultiBlock) if the
1355 // command was aborted.
1356 //
1357
1358 if (statusByte & IDE_STATUS_ERROR) {
1359
1360 //
1361 // Read the error register.
1362 //
1363
1364 errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress + 1);
1365
1366 DebugPrint((1,
1367 "AtapiHwInitialize: Error setting multiple mode. Status %x, error byte %x\n",
1368 statusByte,
1369 errorByte));
1370 //
1371 // Adjust the devExt. value, if necessary.
1372 //
1373
1374 deviceExtension->MaximumBlockXfer[i] = 0;
1375
1376 } else {
1377 DebugPrint((2,
1378 "AtapiHwInitialize: Using Multiblock on Device %d. Blocks / int - %d\n",
1379 i,
1380 deviceExtension->MaximumBlockXfer[i]));
1381 }
1382 }
1383 } else if (!(deviceExtension->DeviceFlags[i] & DFLAGS_CHANGER_INITED)){
1384
1385 ULONG j;
1386 UCHAR vendorId[26];
1387
1388 //
1389 // Attempt to identify any special-case devices - psuedo-atapi changers, atapi changers, etc.
1390 //
1391
1392 for (j = 0; j < 13; j += 2) {
1393
1394 //
1395 // Build a buffer based on the identify data.
1396 //
1397
1398 vendorId[j] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j + 1];
1399 vendorId[j+1] = ((PUCHAR)deviceExtension->IdentifyData[i].ModelNumber)[j];
1400 }
1401
1402 if (!AtapiStringCmp ((PCHAR)vendorId, "CD-ROM CDR", 11)) {
1403
1404 //
1405 // Inquiry string for older model had a '-', newer is '_'
1406 //
1407
1408 if (vendorId[12] == 'C') {
1409
1410 //
1411 // Torisan changer. Set the bit. This will be used in several places
1412 // acting like 1) a multi-lun device and 2) building the 'special' TUR's.
1413 //
1414
1416 deviceExtension->DiscsPresent[i] = 3;
1417 }
1418 }
1419 }
1420
1421 //
1422 // We need to get our device ready for action before
1423 // returning from this function
1424 //
1425 // According to the atapi spec 2.5 or 2.6, an atapi device
1426 // clears its status BSY bit when it is ready for atapi commands.
1427 // However, some devices (Panasonic SQ-TC500N) are still
1428 // not ready even when the status BSY is clear. They don't react
1429 // to atapi commands.
1430 //
1431 // Since there is really no other indication that tells us
1432 // the drive is really ready for action. We are going to check BSY
1433 // is clear and then just wait for an arbitrary amount of time!
1434 //
1435 if (deviceExtension->DeviceFlags[i] & DFLAGS_ATAPI_DEVICE) {
1436 //PIDE_REGISTERS_1 baseIoAddress1 = deviceExtension->BaseIoAddress1[i >> 1];
1437 PIDE_REGISTERS_2 baseIoAddress2 = deviceExtension->BaseIoAddress2[i >> 1];
1438 ULONG waitCount;
1439
1440 // have to get out of the loop sometime!
1441 // 10000 * 100us = 1000,000us = 1000ms = 1s
1442 waitCount = 10000;
1443 GetStatus(baseIoAddress2, statusByte);
1444 while ((statusByte & IDE_STATUS_BUSY) && waitCount) {
1445 //
1446 // Wait for Busy to drop.
1447 //
1449 GetStatus(baseIoAddress2, statusByte);
1450 waitCount--;
1451 }
1452
1453 // 5000 * 100us = 500,000us = 500ms = 0.5s
1454 waitCount = 5000;
1455 do {
1457 } while (waitCount--);
1458 }
1459 }
1460 }
1461
1462 return TRUE;
1463
1464} // end AtapiHwInitialize()
#define DFLAGS_SANYO_ATAPI_CHANGER
Definition: atapi.h:49
#define DFLAGS_CHANGER_INITED
Definition: atapi.h:50
#define WaitOnBaseBusy(BaseIoAddress, Status)
Definition: atapi.h:373
#define IDE_COMMAND_SET_MULTIPLE
Definition: atapi.h:113
VOID NTAPI IdeMediaStatus(IN BOOLEAN EnableMSN, IN PVOID HwDeviceExtension, IN ULONG Channel)
VOID NTAPI ScsiPortWritePortUchar(IN PUCHAR Port, IN UCHAR Value)
Definition: scsiport.c:1547
VOID NTAPI ScsiPortStallExecution(IN ULONG Delay)
Definition: scsiport.c:1489
UCHAR NTAPI ScsiPortReadPortUchar(IN PUCHAR Port)
Definition: scsiport.c:1390
#define DebugPrint(x)
Definition: classpnp.h:125
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
ULONG DiscsPresent[4]
Definition: atapi.c:80
PIDE_REGISTERS_2 BaseIoAddress2[2]
Definition: atapi.c:35
UCHAR MaximumBlockXfer[4]
Definition: atapi.c:93
PIDE_REGISTERS_1 BaseIoAddress1[2]
Definition: atapi.c:34
IDENTIFY_DATA2 IdentifyData[4]
Definition: atapi.c:146
USHORT DeviceFlags[4]
Definition: atapi.c:86
USHORT ModelNumber[20]
Definition: atapi.h:262
UCHAR BlockCount
Definition: atapi.h:18
UCHAR Command
Definition: atapi.h:23
UCHAR DriveSelect
Definition: atapi.h:22
#define AtapiStringCmp(s1, s2, n)
Definition: atapi.h:1256

Referenced by AtapiResetController(), and DriverEntry().

◆ AtapiHwInitializeChanger()

VOID NTAPI AtapiHwInitializeChanger ( IN PVOID  HwDeviceExtension,
IN ULONG  TargetId,
IN PMECHANICAL_STATUS_INFORMATION_HEADER  MechanismStatus 
)

Definition at line 1469 of file atapi.c.

1473{
1474 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
1475
1476 if (MechanismStatus) {
1477 deviceExtension->DiscsPresent[TargetId] = MechanismStatus->NumberAvailableSlots;
1478 if (deviceExtension->DiscsPresent[TargetId] > 1) {
1479 deviceExtension->DeviceFlags[TargetId] |= DFLAGS_ATAPI_CHANGER;
1480 }
1481 }
1482 return;
1483}
#define DFLAGS_ATAPI_CHANGER
Definition: atapi.h:48
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR TargetId
Definition: classpnp.h:1314

Referenced by AtapiInterrupt(), and AtapiSendCommand().

◆ AtapiInterrupt()

BOOLEAN NTAPI AtapiInterrupt ( IN PVOID  HwDeviceExtension)

Definition at line 3484 of file atapi.c.

3504{
3505 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
3506 PSCSI_REQUEST_BLOCK srb = deviceExtension->CurrentSrb;
3507 PATAPI_REGISTERS_1 baseIoAddress1;
3508 PATAPI_REGISTERS_2 baseIoAddress2;
3509 ULONG wordCount = 0, wordsThisInterrupt = 256;
3510 ULONG status;
3511 ULONG i;
3512 UCHAR statusByte,interruptReason;
3513 BOOLEAN atapiDev = FALSE;
3514
3515 if (srb) {
3516 baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[srb->TargetId >> 1];
3517 baseIoAddress2 = (PATAPI_REGISTERS_2)deviceExtension->BaseIoAddress2[srb->TargetId >> 1];
3518 } else {
3519 DebugPrint((2,
3520 "AtapiInterrupt: CurrentSrb is NULL\n"));
3521 //
3522 // We can only support one ATAPI IDE master on Carolina, so find
3523 // the base address that is non NULL and clear its interrupt before
3524 // returning.
3525 //
3526
3527#ifdef _PPC_
3528
3529 if ((PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0] != NULL) {
3530 baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0];
3531 } else {
3532 baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[1];
3533 }
3534
3535 GetBaseStatus(baseIoAddress1, statusByte);
3536#else
3537
3538 if (deviceExtension->InterruptMode == LevelSensitive) {
3539 if (deviceExtension->BaseIoAddress1[0] != NULL) {
3540 baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[0];
3541 GetBaseStatus(baseIoAddress1, statusByte);
3542 }
3543 if (deviceExtension->BaseIoAddress1[1] != NULL) {
3544 baseIoAddress1 = (PATAPI_REGISTERS_1)deviceExtension->BaseIoAddress1[1];
3545 GetBaseStatus(baseIoAddress1, statusByte);
3546 }
3547 }
3548#endif
3549 return FALSE;
3550 }
3551
3552 if (!(deviceExtension->ExpectingInterrupt)) {
3553
3554 DebugPrint((3,
3555 "AtapiInterrupt: Unexpected interrupt.\n"));
3556 return FALSE;
3557 }
3558
3559 //
3560 // Clear interrupt by reading status.
3561 //
3562
3563 GetBaseStatus(baseIoAddress1, statusByte);
3564
3565 DebugPrint((3,
3566 "AtapiInterrupt: Entered with status (%x)\n",
3567 statusByte));
3568
3569
3570 if (statusByte & IDE_STATUS_BUSY) {
3571 if (deviceExtension->DriverMustPoll) {
3572
3573 //
3574 // Crashdump is polling and we got caught with busy asserted.
3575 // Just go away, and we will be polled again shortly.
3576 //
3577
3578 DebugPrint((3,
3579 "AtapiInterrupt: Hit BUSY while polling during crashdump.\n"));
3580
3581 return TRUE;
3582 }
3583
3584 //
3585 // Ensure BUSY is non-asserted.
3586 //
3587
3588 for (i = 0; i < 10; i++) {
3589
3590 GetBaseStatus(baseIoAddress1, statusByte);
3591 if (!(statusByte & IDE_STATUS_BUSY)) {
3592 break;
3593 }
3595 }
3596
3597 if (i == 10) {
3598
3599 DebugPrint((2,
3600 "AtapiInterrupt: BUSY on entry. Status %x, Base IO %x\n",
3601 statusByte,
3602 baseIoAddress1));
3603
3605 HwDeviceExtension,
3607 500);
3608 return TRUE;
3609 }
3610 }
3611
3612
3613 //
3614 // Check for error conditions.
3615 //
3616
3617 if (statusByte & IDE_STATUS_ERROR) {
3618
3619 if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
3620
3621 //
3622 // Fail this request.
3623 //
3624
3626 goto CompleteRequest;
3627 }
3628 }
3629
3630 //
3631 // check reason for this interrupt.
3632 //
3633
3634 if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3635
3636 interruptReason = (ScsiPortReadPortUchar(&baseIoAddress1->InterruptReason) & 0x3);
3637 atapiDev = TRUE;
3638 wordsThisInterrupt = 256;
3639
3640 } else {
3641
3642 if (statusByte & IDE_STATUS_DRQ) {
3643
3644 if (deviceExtension->MaximumBlockXfer[srb->TargetId]) {
3645 wordsThisInterrupt = 256 * deviceExtension->MaximumBlockXfer[srb->TargetId];
3646
3647 }
3648
3649 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
3650
3651 interruptReason = 0x2;
3652
3653 } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
3654 interruptReason = 0x0;
3655
3656 } else {
3658 goto CompleteRequest;
3659 }
3660
3661 } else if (statusByte & IDE_STATUS_BUSY) {
3662
3663 return FALSE;
3664
3665 } else {
3666
3667 if (deviceExtension->WordsLeft) {
3668
3669 ULONG k;
3670
3671 //
3672 // Funky behaviour seen with PCI IDE (not all, just one).
3673 // The ISR hits with DRQ low, but comes up later.
3674 //
3675
3676 for (k = 0; k < 5000; k++) {
3677 GetStatus(baseIoAddress2,statusByte);
3678 if (!(statusByte & IDE_STATUS_DRQ)) {
3680 } else {
3681 break;
3682 }
3683 }
3684
3685 if (k == 5000) {
3686
3687 //
3688 // reset the controller.
3689 //
3690
3691 DebugPrint((1,
3692 "AtapiInterrupt: Resetting due to DRQ not up. Status %x, Base IO %x\n",
3693 statusByte,
3694 baseIoAddress1));
3695
3696 AtapiResetController(HwDeviceExtension,srb->PathId);
3697 return TRUE;
3698 } else {
3699
3700 interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? 0x2 : 0x0;
3701 }
3702
3703 } else {
3704
3705 //
3706 // Command complete - verify, write, or the SMART enable/disable.
3707 //
3708 // Also get_media_status
3709
3710 interruptReason = 0x3;
3711 }
3712 }
3713 }
3714
3715 if (interruptReason == 0x1 && (statusByte & IDE_STATUS_DRQ)) {
3716
3717 //
3718 // Write the packet.
3719 //
3720
3721 DebugPrint((2,
3722 "AtapiInterrupt: Writing Atapi packet.\n"));
3723
3724 //
3725 // Send CDB to device.
3726 //
3727
3728 WriteBuffer(baseIoAddress1,
3729 (PUSHORT)srb->Cdb,
3730 6);
3731
3732 return TRUE;
3733
3734 } else if (interruptReason == 0x0 && (statusByte & IDE_STATUS_DRQ)) {
3735
3736 //
3737 // Write the data.
3738 //
3739
3740 if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3741
3742 //
3743 // Pick up bytes to transfer and convert to words.
3744 //
3745
3746 wordCount =
3747 ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);
3748
3749 wordCount |=
3750 ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh) << 8;
3751
3752 //
3753 // Covert bytes to words.
3754 //
3755
3756 wordCount >>= 1;
3757
3758 if (wordCount != deviceExtension->WordsLeft) {
3759 DebugPrint((3,
3760 "AtapiInterrupt: %d words requested; %d words xferred\n",
3761 deviceExtension->WordsLeft,
3762 wordCount));
3763 }
3764
3765 //
3766 // Verify this makes sense.
3767 //
3768
3769 if (wordCount > deviceExtension->WordsLeft) {
3770 wordCount = deviceExtension->WordsLeft;
3771 }
3772
3773 } else {
3774
3775 //
3776 // IDE path. Check if words left is at least 256.
3777 //
3778
3779 if (deviceExtension->WordsLeft < wordsThisInterrupt) {
3780
3781 //
3782 // Transfer only words requested.
3783 //
3784
3785 wordCount = deviceExtension->WordsLeft;
3786
3787 } else {
3788
3789 //
3790 // Transfer next block.
3791 //
3792
3793 wordCount = wordsThisInterrupt;
3794 }
3795 }
3796
3797 //
3798 // Ensure that this is a write command.
3799 //
3800
3801 if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
3802
3803 DebugPrint((3,
3804 "AtapiInterrupt: Write interrupt\n"));
3805
3806 WaitOnBusy(baseIoAddress2,statusByte);
3807
3808 if (atapiDev || !deviceExtension->DWordIO) {
3809
3810 WriteBuffer(baseIoAddress1,
3811 deviceExtension->DataBuffer,
3812 wordCount);
3813 } else {
3814
3815 PIDE_REGISTERS_3 address3 = (PIDE_REGISTERS_3)baseIoAddress1;
3816
3817 WriteBuffer2(address3,
3818 (PULONG)(deviceExtension->DataBuffer),
3819 wordCount / 2);
3820 }
3821 } else {
3822
3823 DebugPrint((1,
3824 "AtapiInterrupt: Int reason %x, but srb is for a write %x.\n",
3825 interruptReason,
3826 srb));
3827
3828 //
3829 // Fail this request.
3830 //
3831
3833 goto CompleteRequest;
3834 }
3835
3836
3837 //
3838 // Advance data buffer pointer and bytes left.
3839 //
3840
3841 deviceExtension->DataBuffer += wordCount;
3842 deviceExtension->WordsLeft -= wordCount;
3843
3844 return TRUE;
3845
3846 } else if (interruptReason == 0x2 && (statusByte & IDE_STATUS_DRQ)) {
3847
3848
3849 if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3850
3851 //
3852 // Pick up bytes to transfer and convert to words.
3853 //
3854
3855 wordCount =
3856 ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);
3857
3858 wordCount |=
3859 ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh) << 8;
3860
3861 //
3862 // Covert bytes to words.
3863 //
3864
3865 wordCount >>= 1;
3866
3867 if (wordCount != deviceExtension->WordsLeft) {
3868 DebugPrint((3,
3869 "AtapiInterrupt: %d words requested; %d words xferred\n",
3870 deviceExtension->WordsLeft,
3871 wordCount));
3872 }
3873
3874 //
3875 // Verify this makes sense.
3876 //
3877
3878 if (wordCount > deviceExtension->WordsLeft) {
3879 wordCount = deviceExtension->WordsLeft;
3880 }
3881
3882 } else {
3883
3884 //
3885 // Check if words left is at least 256.
3886 //
3887
3888 if (deviceExtension->WordsLeft < wordsThisInterrupt) {
3889
3890 //
3891 // Transfer only words requested.
3892 //
3893
3894 wordCount = deviceExtension->WordsLeft;
3895
3896 } else {
3897
3898 //
3899 // Transfer next block.
3900 //
3901
3902 wordCount = wordsThisInterrupt;
3903 }
3904 }
3905
3906 //
3907 // Ensure that this is a read command.
3908 //
3909
3910 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
3911
3912 DebugPrint((3,
3913 "AtapiInterrupt: Read interrupt\n"));
3914
3915 WaitOnBusy(baseIoAddress2,statusByte);
3916
3917 if (atapiDev || !deviceExtension->DWordIO) {
3918 ReadBuffer(baseIoAddress1,
3919 deviceExtension->DataBuffer,
3920 wordCount);
3921
3922 } else {
3923 PIDE_REGISTERS_3 address3 = (PIDE_REGISTERS_3)baseIoAddress1;
3924
3925 ReadBuffer2(address3,
3926 (PULONG)(deviceExtension->DataBuffer),
3927 wordCount / 2);
3928 }
3929 } else {
3930
3931 DebugPrint((1,
3932 "AtapiInterrupt: Int reason %x, but srb is for a read %x.\n",
3933 interruptReason,
3934 srb));
3935
3936 //
3937 // Fail this request.
3938 //
3939
3941 goto CompleteRequest;
3942 }
3943
3944 //
3945 // Translate ATAPI data back to SCSI data if needed
3946 //
3947
3948 if (srb->Cdb[0] == ATAPI_MODE_SENSE &&
3949 deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3950
3951 //
3952 //convert and adjust the wordCount
3953 //
3954
3955 wordCount -= Atapi2Scsi(srb, (char *)deviceExtension->DataBuffer,
3956 wordCount << 1);
3957 }
3958 //
3959 // Advance data buffer pointer and bytes left.
3960 //
3961
3962 deviceExtension->DataBuffer += wordCount;
3963 deviceExtension->WordsLeft -= wordCount;
3964
3965 //
3966 // Check for read command complete.
3967 //
3968
3969 if (deviceExtension->WordsLeft == 0) {
3970
3971 if (deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
3972
3973 //
3974 // Work around to make many atapi devices return correct sector size
3975 // of 2048. Also certain devices will have sector count == 0x00, check
3976 // for that also.
3977 //
3978
3979 if ((srb->Cdb[0] == 0x25) &&
3980 ((deviceExtension->IdentifyData[srb->TargetId].GeneralConfiguration >> 8) & 0x1f) == 0x05) {
3981
3982 deviceExtension->DataBuffer -= wordCount;
3983 if (deviceExtension->DataBuffer[0] == 0x00) {
3984
3985 *((ULONG *) &(deviceExtension->DataBuffer[0])) = 0xFFFFFF7F;
3986
3987 }
3988
3989 *((ULONG *) &(deviceExtension->DataBuffer[2])) = 0x00080000;
3990 deviceExtension->DataBuffer += wordCount;
3991 }
3992 } else {
3993
3994 //
3995 // Completion for IDE drives.
3996 //
3997
3998
3999 if (deviceExtension->WordsLeft) {
4000
4002
4003 } else {
4004
4006
4007 }
4008
4009 goto CompleteRequest;
4010
4011 }
4012 }
4013
4014 return TRUE;
4015
4016 } else if (interruptReason == 0x3 && !(statusByte & IDE_STATUS_DRQ)) {
4017
4018 //
4019 // Command complete.
4020 //
4021
4022 if (deviceExtension->WordsLeft) {
4023
4025
4026 } else {
4027
4029
4030 }
4031
4033
4034 //
4035 // Check and see if we are processing our secret (mechanism status/request sense) srb
4036 //
4037 if (deviceExtension->OriginalSrb) {
4038
4039 ULONG srbStatus;
4040
4041 if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
4042
4043 if (status == SRB_STATUS_SUCCESS) {
4044 // Bingo!!
4045 AtapiHwInitializeChanger (HwDeviceExtension,
4046 srb->TargetId,
4048
4049 // Get ready to issue the original srb
4050 srb = deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
4051 deviceExtension->OriginalSrb = NULL;
4052
4053 } else {
4054 // failed! Get the sense key and maybe try again
4055 srb = deviceExtension->CurrentSrb = BuildRequestSenseSrb (
4056 HwDeviceExtension,
4057 deviceExtension->OriginalSrb->PathId,
4058 deviceExtension->OriginalSrb->TargetId);
4059 }
4060
4061 srbStatus = AtapiSendCommand(HwDeviceExtension, deviceExtension->CurrentSrb);
4062 if (srbStatus == SRB_STATUS_PENDING) {
4063 return TRUE;
4064 }
4065
4066 } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE)
4067
4068 PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
4069
4071 // Check to see if we at least get minimum number of bytes
4072 if ((srb->DataTransferLength - deviceExtension->WordsLeft) >
4073 (FIELD_OFFSET (SENSE_DATA, AdditionalSenseLength) + sizeof(senseData->AdditionalSenseLength))) {
4075 }
4076 }
4077
4078 if (status == SRB_STATUS_SUCCESS) {
4079 if ((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) &&
4080 deviceExtension->MechStatusRetryCount) {
4081
4082 // The sense key doesn't say the last request is illegal, so try again
4083 deviceExtension->MechStatusRetryCount--;
4084 srb = deviceExtension->CurrentSrb = BuildMechanismStatusSrb (
4085 HwDeviceExtension,
4086 deviceExtension->OriginalSrb->PathId,
4087 deviceExtension->OriginalSrb->TargetId);
4088 } else {
4089
4090 // last request was illegal. No point trying again
4091
4092 AtapiHwInitializeChanger (HwDeviceExtension,
4093 srb->TargetId,
4095
4096 // Get ready to issue the original srb
4097 srb = deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
4098 deviceExtension->OriginalSrb = NULL;
4099 }
4100
4101 srbStatus = AtapiSendCommand(HwDeviceExtension, deviceExtension->CurrentSrb);
4102 if (srbStatus == SRB_STATUS_PENDING) {
4103 return TRUE;
4104 }
4105 }
4106 }
4107
4108 // If we get here, it means AtapiSendCommand() has failed
4109 // Can't recover. Pretend the original srb has failed and complete it.
4110
4111 if (deviceExtension->OriginalSrb) {
4112 AtapiHwInitializeChanger (HwDeviceExtension,
4113 srb->TargetId,
4115 srb = deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
4116 deviceExtension->OriginalSrb = NULL;
4117 }
4118
4119 // fake an error and read no data
4121 srb->ScsiStatus = 0;
4122 deviceExtension->DataBuffer = srb->DataBuffer;
4123 deviceExtension->WordsLeft = srb->DataTransferLength;
4124 deviceExtension->RDP = FALSE;
4125
4126 } else if (status == SRB_STATUS_ERROR) {
4127
4128 //
4129 // Map error to specific SRB status and handle request sense.
4130 //
4131
4132 status = MapError(deviceExtension,
4133 srb);
4134
4135 deviceExtension->RDP = FALSE;
4136
4137 } else {
4138
4139 //
4140 // Wait for busy to drop.
4141 //
4142
4143 for (i = 0; i < 30; i++) {
4144 GetStatus(baseIoAddress2,statusByte);
4145 if (!(statusByte & IDE_STATUS_BUSY)) {
4146 break;
4147 }
4149 }
4150
4151 if (i == 30) {
4152
4153 //
4154 // reset the controller.
4155 //
4156
4157 DebugPrint((1,
4158 "AtapiInterrupt: Resetting due to BSY still up - %x. Base Io %x\n",
4159 statusByte,
4160 baseIoAddress1));
4161 AtapiResetController(HwDeviceExtension,srb->PathId);
4162 return TRUE;
4163 }
4164
4165 //
4166 // Check to see if DRQ is still up.
4167 //
4168
4169 if (statusByte & IDE_STATUS_DRQ) {
4170
4171 for (i = 0; i < 500; i++) {
4172 GetStatus(baseIoAddress2,statusByte);
4173 if (!(statusByte & IDE_STATUS_DRQ)) {
4174 break;
4175 }
4177
4178 }
4179
4180 if (i == 500) {
4181
4182 //
4183 // reset the controller.
4184 //
4185
4186 DebugPrint((1,
4187 "AtapiInterrupt: Resetting due to DRQ still up - %x\n",
4188 statusByte));
4189 AtapiResetController(HwDeviceExtension,srb->PathId);
4190 return TRUE;
4191 }
4192
4193 }
4194 }
4195
4196
4197 //
4198 // Clear interrupt expecting flag.
4199 //
4200
4201 deviceExtension->ExpectingInterrupt = FALSE;
4202
4203 //
4204 // Sanity check that there is a current request.
4205 //
4206
4207 if (srb != NULL) {
4208
4209 //
4210 // Set status in SRB.
4211 //
4212
4213 srb->SrbStatus = (UCHAR)status;
4214
4215 //
4216 // Check for underflow.
4217 //
4218
4219 if (deviceExtension->WordsLeft) {
4220
4221 //
4222 // Subtract out residual words and update if filemark hit,
4223 // setmark hit , end of data, end of media...
4224 //
4225
4226 if (!(deviceExtension->DeviceFlags[srb->TargetId] & DFLAGS_TAPE_DEVICE)) {
4228 srb->DataTransferLength -= deviceExtension->WordsLeft;
4229 } else {
4230 srb->DataTransferLength = 0;
4231 }
4232 } else {
4233 srb->DataTransferLength -= deviceExtension->WordsLeft;
4234 }
4235 }
4236
4237 if (srb->Function != SRB_FUNCTION_IO_CONTROL) {
4238
4239 //
4240 // Indicate command complete.
4241 //
4242
4243 if (!(deviceExtension->RDP)) {
4245 deviceExtension,
4246 srb);
4247
4248 }
4249 } else {
4250
4251 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
4252 UCHAR error = 0;
4253
4254 if (status != SRB_STATUS_SUCCESS) {
4255 error = ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1);
4256 }
4257
4258 //
4259 // Build the SMART status block depending upon the completion status.
4260 //
4261
4262 cmdOutParameters->cBufferSize = wordCount;
4263 cmdOutParameters->DriverStatus.bDriverError = (error) ? SMART_IDE_ERROR : 0;
4264 cmdOutParameters->DriverStatus.bIDEError = error;
4265
4266 //
4267 // If the sub-command is return smart status, jam the value from cylinder low and high, into the
4268 // data buffer.
4269 //
4270
4271 if (deviceExtension->SmartCommand == RETURN_SMART_STATUS) {
4272 cmdOutParameters->bBuffer[0] = RETURN_SMART_STATUS;
4273 cmdOutParameters->bBuffer[1] = ScsiPortReadPortUchar(&baseIoAddress1->InterruptReason);
4274 cmdOutParameters->bBuffer[2] = ScsiPortReadPortUchar(&baseIoAddress1->Unused1);
4275 cmdOutParameters->bBuffer[3] = ScsiPortReadPortUchar(&baseIoAddress1->ByteCountLow);
4276 cmdOutParameters->bBuffer[4] = ScsiPortReadPortUchar(&baseIoAddress1->ByteCountHigh);
4277 cmdOutParameters->bBuffer[5] = ScsiPortReadPortUchar(&baseIoAddress1->DriveSelect);
4278 cmdOutParameters->bBuffer[6] = SMART_CMD;
4279 cmdOutParameters->cBufferSize = 8;
4280 }
4281
4282 //
4283 // Indicate command complete.
4284 //
4285
4287 deviceExtension,
4288 srb);
4289
4290 }
4291
4292 } else {
4293
4294 DebugPrint((1,
4295 "AtapiInterrupt: No SRB!\n"));
4296 }
4297
4298 //
4299 // Indicate ready for next request.
4300 //
4301
4302 if (!(deviceExtension->RDP)) {
4303
4304 //
4305 // Clear current SRB.
4306 //
4307
4308 deviceExtension->CurrentSrb = NULL;
4309
4311 deviceExtension,
4312 NULL);
4313 } else {
4314
4316 HwDeviceExtension,
4318 2000);
4319 }
4320
4321 return TRUE;
4322
4323 } else {
4324
4325 //
4326 // Unexpected int.
4327 //
4328
4329 DebugPrint((3,
4330 "AtapiInterrupt: Unexpected interrupt. InterruptReason %x. Status %x.\n",
4331 interruptReason,
4332 statusByte));
4333 return FALSE;
4334 }
4335
4336 return TRUE;
4337
4338} // end AtapiInterrupt()
struct _IDE_REGISTERS_3 * PIDE_REGISTERS_3
#define WriteBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:344
#define ReadBuffer(BaseIoAddress, Buffer, Count)
Definition: atapi.h:339
#define WaitOnBusy(BaseIoAddress, Status)
Definition: atapi.h:359
#define WriteBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:354
#define ATAPI_MODE_SENSE
Definition: atapi.h:61
#define ReadBuffer2(BaseIoAddress, Buffer, Count)
Definition: atapi.h:349
struct _ATAPI_REGISTERS_1 * PATAPI_REGISTERS_1
VOID NTAPI AtapiCallBack(IN PVOID HwDeviceExtension)
Definition: atapi.c:3411
ULONG NTAPI MapError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:905
ULONG NTAPI Atapi2Scsi(IN PSCSI_REQUEST_BLOCK Srb, IN char *DataBuffer, IN ULONG ByteCount)
Definition: atapi.c:3360
BOOLEAN NTAPI AtapiResetController(IN PVOID HwDeviceExtension, IN ULONG PathId)
Definition: atapi.c:733
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb(IN PVOID HwDeviceExtension, IN ULONG PathId, IN ULONG TargetId)
Definition: atapi.c:6447
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb(IN PVOID HwDeviceExtension, IN ULONG PathId, IN ULONG TargetId)
Definition: atapi.c:6493
ULONG NTAPI AtapiSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:4981
VOID NTAPI AtapiHwInitializeChanger(IN PVOID HwDeviceExtension, IN ULONG TargetId, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
Definition: atapi.c:1469
#define SMART_CMD
Definition: helper.h:21
struct _SENDCMDOUTPARAMS * PSENDCMDOUTPARAMS
VOID __cdecl ScsiPortNotification(IN SCSI_NOTIFICATION_TYPE NotificationType, IN PVOID HwDeviceExtension, IN ...)
Definition: scsiport.c:1324
#define SCSIOP_REQUEST_SENSE
Definition: cdrw_hw.h:870
struct _SENSE_DATA * PSENSE_DATA
#define SCSIOP_MECHANISM_STATUS
Definition: cdrw_hw.h:966
#define SCSI_SENSE_ILLEGAL_REQUEST
Definition: cdrw_hw.h:1192
NTSTATUS NTAPI CompleteRequest(IN PIRP Irp, IN NTSTATUS Status, IN ULONG_PTR Information)
Definition: dispatch.c:19
#define SRB_FUNCTION_IO_CONTROL
Definition: srb.h:317
#define SRB_STATUS_DATA_OVERRUN
Definition: srb.h:357
#define SRB_FLAGS_DATA_OUT
Definition: srb.h:401
#define SRB_STATUS_PENDING
Definition: srb.h:340
#define SRB_FLAGS_DATA_IN
Definition: srb.h:400
#define SRB_STATUS_ERROR
Definition: srb.h:344
@ RequestTimerCall
Definition: srb.h:537
@ RequestComplete
Definition: srb.h:531
@ NextRequest
Definition: srb.h:532
#define SRB_STATUS_SUCCESS
Definition: srb.h:341
if(dx< 0)
Definition: linetemp.h:194
#define error(str)
Definition: mkdosfs.c:1605
int k
Definition: mpi.c:3369
#define RETURN_SMART_STATUS
Definition: ntdddisk.h:753
#define SMART_IDE_ERROR
Definition: ntdddisk.h:706
struct _SRB_IO_CONTROL SRB_IO_CONTROL
UCHAR ByteCountLow
Definition: atapi.h:170
UCHAR InterruptReason
Definition: atapi.h:168
UCHAR ByteCountHigh
Definition: atapi.h:171
UCHAR DriveSelect
Definition: atapi.h:172
UCHAR bIDEError
Definition: helper.h:3
UCHAR bDriverError
Definition: helper.h:2
PSCSI_REQUEST_BLOCK OriginalSrb
Definition: atapi.c:151
BOOLEAN ExpectingInterrupt
Definition: atapi.c:99
PUSHORT DataBuffer
Definition: atapi.c:53
UCHAR SmartCommand
Definition: atapi.c:131
BOOLEAN DWordIO
Definition: atapi.c:117
ULONG MechStatusRetryCount
Definition: atapi.c:155
PSCSI_REQUEST_BLOCK CurrentSrb
Definition: atapi.c:28
USHORT GeneralConfiguration
Definition: atapi.h:249
UCHAR TargetId
Definition: srb.h:254
PVOID DataBuffer
Definition: srb.h:263
UCHAR PathId
Definition: srb.h:253
UCHAR Cdb[16]
Definition: srb.h:279
UCHAR Function
Definition: srb.h:250
UCHAR ScsiStatus
Definition: srb.h:252
ULONG DataTransferLength
Definition: srb.h:261
ULONG SrbFlags
Definition: srb.h:260
UCHAR SrbStatus
Definition: srb.h:251
UCHAR bBuffer[1]
Definition: helper.h:27
ULONG cBufferSize
Definition: helper.h:25
DRIVERSTATUS DriverStatus
Definition: helper.h:26
UCHAR AdditionalSenseLength
Definition: cdrw_hw.h:1173
UCHAR SenseKey
Definition: cdrw_hw.h:1167
uint16_t * PUSHORT
Definition: typedefs.h:56

Referenced by AtapiCallBack(), and DriverEntry().

◆ AtapiInterrupt__()

BOOLEAN NTAPI AtapiInterrupt__ ( IN PVOID  HwDeviceExtension,
IN UCHAR  c 
)

atapiDev &&

deviceExtension->DWordIO

Definition at line 4981 of file id_ata.cpp.

4985{
4986 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
4987 PHW_CHANNEL chan = &(deviceExtension->chan[c]);
4988 // Get current Srb
4990 PATA_REQ AtaReq = srb ? (PATA_REQ)(srb->SrbExtension) : NULL;
4991
4992 ULONG wordCount = 0, wordsThisInterrupt = DEV_BSIZE/2;
4994 UCHAR dma_status = 0;
4995 ULONG i;
4996 ULONG k;
4997 UCHAR statusByte = 0,interruptReason;
4998
4999 BOOLEAN atapiDev = FALSE;
5000
5001#ifdef _DEBUG
5002 UCHAR Channel;
5003#endif //_DEBUG
5004 UCHAR lChannel;
5006 BOOLEAN DmaTransfer = FALSE;
5007 UCHAR error = 0;
5008 ULONG TimerValue = 1000;
5009 ULONG TotalTimerValue = 0;
5010#ifdef UNIATA_USE_XXableInterrupts
5012#else
5013 BOOLEAN InDpc = (chan->DpcState != DPC_STATE_ISR);
5014#endif // UNIATA_USE_XXableInterrupts
5015 BOOLEAN UseDpc = deviceExtension->UseDpc;
5016// BOOLEAN RestoreUseDpc = FALSE;
5017 BOOLEAN DataOverrun = FALSE;
5018 BOOLEAN NoStartIo = TRUE;
5020
5021 KdPrint2((PRINT_PREFIX "AtapiInterrupt:\n"));
5022 if(InDpc) {
5023 KdPrint2((PRINT_PREFIX " InDpc = TRUE\n"));
5024 //ASSERT((chan->ChannelCtrlFlags & CTRFLAGS_INTR_DISABLED));
5025 }
5026
5027 UCHAR PathId;
5029 UCHAR Lun;
5030 UCHAR OldReqState = REQ_STATE_NONE;
5031 //ULONG ldev;
5032 PHW_LU_EXTENSION LunExt;
5033
5034 lChannel = c;
5035
5036#ifdef _DEBUG
5037 Channel = (UCHAR)(deviceExtension->Channel + lChannel);
5038
5039 KdPrint2((PRINT_PREFIX " cntrlr %#x:%d, irql %#x, c %d\n", deviceExtension->DevIndex, Channel, KeGetCurrentIrql(), c));
5040#endif //_DEBUG
5041
5043 (AtaReq && (AtaReq->Flags & REQ_FLAG_DMA_OPERATION)) ||
5044 (deviceExtension->HwFlags & UNIATA_AHCI)) {
5045 DmaTransfer = TRUE;
5046 KdPrint2((PRINT_PREFIX " DmaTransfer = TRUE\n"));
5047 }
5048
5049 if (srb) {
5050 PathId = srb->PathId;
5051 TargetId = srb->TargetId;
5052 Lun = srb->Lun;
5053 } else {
5054 PathId = (UCHAR)c;
5055 TargetId =
5056 Lun = 0;
5057 goto enqueue_next_req;
5058 }
5059
5060 //ldev = GET_LDEV2(PathId, TargetId, Lun);
5062 LunExt = chan->lun[DeviceNumber];
5063 atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
5064 KdPrint2((PRINT_PREFIX " dev_type %s\n", atapiDev ? "ATAPI" : "IDE"));
5065
5066 // check if we are in ISR DPC
5067 if(InDpc) {
5068 KdPrint2((PRINT_PREFIX " InDpc -> CTRFLAGS_INTR_DISABLED\n"));
5069 goto ServiceInterrupt;
5070 }
5071
5072 if (DmaTransfer) {
5073 dma_status = GetDmaStatus(deviceExtension, lChannel);
5074 }
5075
5076 if (!(chan->ExpectingInterrupt)) {
5077
5078 KdPrint2((PRINT_PREFIX " Unexpected interrupt for this channel.\n"));
5079 return FALSE;
5080 }
5081
5082 // change request state
5083 if(AtaReq) {
5084 OldReqState = AtaReq->ReqState;
5086 KdPrint2((PRINT_PREFIX " OldReqState = %x\n", OldReqState));
5087 }
5088
5089 // We don't want using DPC for fast operations, like
5090 // DMA completion, sending CDB, short ATAPI transfers, etc.
5091 // !!!! BUT !!!!
5092 // We MUST use DPC, because of interprocessor synchronization
5093 // on multiprocessor platforms
5094
5095 if(DmaTransfer)
5096 goto ServiceInterrupt;
5097
5098 switch(OldReqState) {
5100 KdPrint3((PRINT_PREFIX " EXPECTING_CMD_INTR\n"));
5105 KdPrint2((PRINT_PREFIX " continue service interrupt\n"));
5106 goto ServiceInterrupt;
5108 KdPrint2((PRINT_PREFIX " do nothing on interrupt\n"));
5109 return TRUE;
5110 }
5111
5112 if((!DmaTransfer && !atapiDev) || deviceExtension->DriverMustPoll) {
5113 KdPrint2((PRINT_PREFIX " service PIO HDD\n"));
5114 UseDpc = FALSE;
5115 }
5116
5117#ifndef UNIATA_CORE
5118
5119 if(!UseDpc)
5120 goto ServiceInterrupt;
5121
5122#ifdef UNIATA_USE_XXableInterrupts
5123 if(InDpc) {
5124 KdPrint2((PRINT_PREFIX " Unexpected InDpc\n"));
5125 ASSERT(FALSE);
5126 // shall never get here
5127 TimerValue = 1;
5128 goto CallTimerDpc;
5129 }
5130
5131 KdPrint2((PRINT_PREFIX " this is direct DPC call on DRQL\n"));
5132 if(AtaReq) {
5134 KdPrint2((PRINT_PREFIX " ReqState -> REQ_STATE_DPC_INTR_REQ\n"));
5135 } else {
5136 KdPrint2((PRINT_PREFIX " DPC without AtaReq!!!\n"));
5137 }
5138#else
5139 KdPrint2((PRINT_PREFIX "call service interrupt\n"));
5140 goto ServiceInterrupt;
5141#endif // UNIATA_USE_XXableInterrupts
5142
5143PostToDpc:
5144
5145 // Attention !!!
5146 // AtapiInterruptDpc() is called on DISPATCH_LEVEL
5147 // We always get here when are called from timer callback, which is invoked on DRQL.
5148 // It is intended to lower IRQL and let other interrupts to be serviced while we are waiting for BUSY release
5149
5150 KdPrint2((PRINT_PREFIX "AtapiInterrupt: start DPC init...\n"));
5151 // disable interrupts for this channel,
5152 // but avoid recursion and double-disable
5153 if(OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5155 AtapiDisableInterrupts(deviceExtension, lChannel);
5156 }
5157 // go to ISR DPC
5159
5160#ifdef UNIATA_USE_XXableInterrupts
5161 // Will lower IRQL to DISPATCH_LEVEL
5162 ScsiPortNotification(CallEnableInterrupts, HwDeviceExtension,
5163 /*c ?*/ AtapiInterruptDpc/*_1 : AtapiInterruptDpc_0*/);
5164 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DPC inited\n"));
5165#else
5166 // Will raise IRQL to DIRQL
5167 AtapiQueueTimerDpc(HwDeviceExtension, c,
5169 TimerValue);
5170 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
5171#endif // UNIATA_USE_XXableInterrupts
5172 return TRUE;
5173
5174#ifndef UNIATA_CORE
5175CallTimerDpc:
5177CallTimerDpc2:
5178 if(!InDpc && OldReqState != REQ_STATE_DPC_WAIT_BUSY1) {
5179 // we must block interrupts from this channel
5180 // If device generate new interrupt before we get to DPC,
5181 // ISR will assume, that it is NOT our interrupt
5182 AtapiDisableInterrupts(deviceExtension, lChannel);
5183 // We should not clean ExpectingInterrupt flag on channel, since it is used in DPC
5184 }
5185 // Will raise IRQL to DIRQL
5186 AtapiQueueTimerDpc(HwDeviceExtension, c,
5188 TimerValue);
5189 return TRUE;
5190#endif //UNIATA_CORE
5191
5192ServiceInterrupt:
5193
5194 if(AtaReq && InDpc) {
5195 switch(AtaReq->ReqState) {
5197 goto PIO_wait_DRQ0;
5199 goto PIO_wait_busy;
5201 goto PIO_wait_DRQ;
5203 goto continue_err;
5206 // continue normal execution
5207 break;
5208 }
5209 }
5210#else
5211ServiceInterrupt:
5212#endif //UNIATA_CORE
5213/*
5214 // make additional delay for old devices (if we are not in DPC)
5215 if((!LunExt->IdentifyData.MajorRevision || (deviceExtension->lun[DeviceNumber].TransferMode < ATA_PIO4))
5216 &&
5217 !InDpc &&
5218 !atapiDev &&
5219 !(deviceExtension->HwFlags & UNIATA_SATA)
5220 ) {
5221 KdPrint2((PRINT_PREFIX " additional delay 10us for old devices\n"));
5222 AtapiStallExecution(10);
5223 }
5224*/
5225
5226 /* clear interrupt and get status */
5227 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5228 UniataAhciEndTransaction(HwDeviceExtension, lChannel, DeviceNumber, srb);
5229 statusByte = (UCHAR)(AtaReq->ahci.in_status & IDE_STATUS_MASK);
5230
5232 KdPrint3((PRINT_PREFIX "Err intr (%#x), SE (%#x)\n",
5234 chan->AhciLastSError));
5235 if(chan->AhciLastIS & ~ATA_AHCI_P_IX_OF) {
5236
5237 if((chan->AhciLastIS == ATA_AHCI_P_IX_INF) &&
5238 !(statusByte & IDE_STATUS_ERROR) &&
5239 !chan->AhciLastSError &&
5240 srb && (srb->SrbFlags & SRB_FLAGS_DATA_IN)
5241 ) {
5242 KdPrint3((PRINT_PREFIX "ATA_AHCI_P_IX_INF on READ, assume underflow\n"));
5243 // continue processing in regular way
5244 } else {
5245
5246 //KdPrint3((PRINT_PREFIX "Err mask (%#x)\n", chan->AhciLastIS & ~ATA_AHCI_P_IX_OF));
5247 // We have some other error except Overflow
5248 // Just signal ERROR, operation will be aborted in ERROR branch.
5249 statusByte |= IDE_STATUS_ERROR;
5250 AtaReq->ahci.in_serror = chan->AhciLastSError;
5252 KdPrint2((PRINT_PREFIX "Unrecoverable\n"));
5253 NoRetry = TRUE;
5254 }
5255 }
5256 } else {
5257 // We have only Overflow. Abort operation and continue
5258#ifdef _DEBUG
5259 UniataDumpAhciPortRegs(chan);
5260#endif
5261 if(!UniataAhciAbortOperation(chan)) {
5262 KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5263 }
5264#ifdef _DEBUG
5265 UniataDumpAhciPortRegs(chan);
5266#endif
5268 }
5269 }
5270
5271 } else {
5272 GetBaseStatus(chan, statusByte);
5273 }
5274 if(atapiDev) {
5275 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Entered with status (%#x)\n", statusByte));
5276 } else {
5277 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Entered with status (%#x)\n", statusByte));
5278 }
5279
5280 if(!UseDpc) {
5281 KdPrint2((PRINT_PREFIX " operate like in DPC\n"));
5282 InDpc = TRUE;
5283 }
5284
5285 if (!atapiDev) {
5286 // IDE
5287 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5288 KdPrint3((PRINT_PREFIX " AHCI branch (IDE)\n"));
5289 } else
5290 if (statusByte & IDE_STATUS_BUSY) {
5291 if (deviceExtension->DriverMustPoll) {
5292 // Crashdump is polling and we got caught with busy asserted.
5293 // Just go away, and we will be polled again shortly.
5294 KdPrint2((PRINT_PREFIX " Hit BUSY while polling during crashdump.\n"));
5295 goto ReturnEnableIntr;
5296 }
5297try_dpc_wait:
5298 // Ensure BUSY is non-asserted.
5299 // make a very small idle before falling to DPC
5300 k = (InDpc && UseDpc) ? 1000 : 2;
5301
5302 for (i = 0; i < k; i++) {
5303
5304 GetBaseStatus(chan, statusByte);
5305 if (!(statusByte & IDE_STATUS_BUSY)) {
5306 break;
5307 }
5309 }
5310
5311 if (!InDpc && UseDpc && i == 2) {
5312
5313 KdPrint2((PRINT_PREFIX " BUSY on entry. Status %#x, Base IO %#x\n", statusByte));
5314
5315 TimerValue = 50;
5317
5318#ifndef UNIATA_CORE
5319 goto PostToDpc;
5320#else //UNIATA_CORE
5321 AtapiStallExecution(TimerValue);
5322 goto ServiceInterrupt;
5323#endif //UNIATA_CORE
5324 } else
5325 if (InDpc && i == k) {
5326 // reset the controller.
5328 " Resetting due to BUSY on entry - %#x.\n",
5329 statusByte));
5330 goto IntrPrepareResetController;
5331 }
5332 }
5333 } else {
5334 // ATAPI
5335 if(!LunExt->IdentifyData.MajorRevision &&
5336 InDpc &&
5338 !(deviceExtension->HwFlags & UNIATA_SATA)
5339 ) {
5340 //KdPrint2((PRINT_PREFIX " additional delay 10us for old devices (2)\n"));
5341 //AtapiStallExecution(10);
5342 }
5343 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5344 KdPrint3((PRINT_PREFIX " AHCI branch (ATAPI)\n"));
5345 } else {
5347 KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5348 }
5349
5350 if (statusByte & IDE_STATUS_BUSY) {
5351 //if(chan->ChannelCtrlFlags & CTRFLAGS_DSC_BSY) {}
5352/*
5353#ifndef UNIATA_CORE
5354 // This is just workaround
5355 // We should DISABLE interrupts before entering WAIT state
5356 UniataExpectChannelInterrupt(chan, TRUE);
5357#endif //UNIATA_CORE
5358*/
5359 KdPrint3((PRINT_PREFIX " BUSY on ATAPI device, waiting %d us\n", LunExt->AtapiReadyWaitDelay));
5360#ifndef UNIATA_CORE
5361 if(LunExt->AtapiReadyWaitDelay && (LunExt->AtapiReadyWaitDelay > g_opt_MaxIsrWait) && !InDpc && UseDpc) {
5362 TimerValue = LunExt->AtapiReadyWaitDelay;
5363 KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC (0)\n"));
5365 goto CallTimerDpc2;
5366 }
5367#endif //UNIATA_CORE
5368 TimerValue = 10;
5369 for(k=20; k; k--) {
5370 GetBaseStatus(chan, statusByte);
5371 KdPrint3((PRINT_PREFIX " status re-check %#x\n", statusByte));
5372 KdPrint3((PRINT_PREFIX " Error reg (%#x)\n",
5374 if (!(statusByte & IDE_STATUS_BUSY)) {
5375 KdPrint2((PRINT_PREFIX " expecting intr + cleared BUSY\n"));
5376 break;
5377 }
5378 TotalTimerValue += TimerValue;
5379 if(k <= 1) {
5380 KdPrint3((PRINT_PREFIX " too long wait -> DPC\n"));
5381 if(!InDpc) {
5382 KdPrint2((PRINT_PREFIX " too long wait: ISR -> DPC\n"));
5383 TimerValue = 100;
5385 } else {
5386 KdPrint2((PRINT_PREFIX " too long wait: DPC -> DPC\n"));
5387 TimerValue = 1000;
5389 }
5390#ifndef UNIATA_CORE
5391 if(UseDpc) {
5392 if(!LunExt->AtapiReadyWaitDelay) {
5393 LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5394 }
5395 goto CallTimerDpc2;
5396 }
5397#endif //UNIATA_CORE
5398 }
5399
5400 AtapiStallExecution(TimerValue);
5401 TimerValue += 10;
5402 }
5403 if(!LunExt->AtapiReadyWaitDelay) {
5404 LunExt->AtapiReadyWaitDelay = TotalTimerValue*2/3;
5405 KdPrint2((PRINT_PREFIX " store AtapiReadyWaitDelay: %d\n", LunExt->AtapiReadyWaitDelay));
5406 }
5407 if (statusByte & IDE_STATUS_BUSY) {
5408 KdPrint3((PRINT_PREFIX " expecting intr + BUSY (2), try DPC wait\n"));
5409 goto try_dpc_wait;
5410 }
5411 }
5412 }
5413
5414 if(AtaReq && DmaTransfer && !(deviceExtension->HwFlags & UNIATA_AHCI)) {
5415 switch(OldReqState) {
5418
5420 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DMA still active\n"));
5421 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5422 }
5423 break;
5424 }
5425 }
5426
5427//retry_check:
5428 // Check for error conditions.
5429 if ((statusByte & IDE_STATUS_ERROR) ||
5430 (dma_status & BM_STATUS_ERR)) {
5431
5432 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5433 error = AtaReq->ahci.in_error;
5434 // wait ready
5435#ifdef _DEBUG
5436 UniataDumpAhciPortRegs(chan);
5437#endif
5438 if(!UniataAhciAbortOperation(chan)) {
5439 KdPrint2((PRINT_PREFIX "need UniataAhciReset\n"));
5440 }
5441 // clear interrupts again
5443#ifdef _DEBUG
5444 UniataDumpAhciPortRegs(chan);
5445#endif
5446 UniataAhciStatus(HwDeviceExtension, lChannel, DEVNUM_NOT_SPECIFIED);
5447 if(NoRetry) {
5448 AtaReq->retry += MAX_RETRIES;
5449 if(!error && (statusByte & IDE_STATUS_ERROR)) {
5450 KdPrint2((PRINT_PREFIX "AtapiInterrupt: force error status\n"));
5452 }
5453 }
5454#ifdef _DEBUG
5455 UniataDumpAhciPortRegs(chan);
5456#endif
5457 } else {
5459 }
5460 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Error %#x\n", error));
5461/*
5462 if(error & IDE_STATUS_CORRECTED_ERROR) {
5463 KdPrint2((PRINT_PREFIX "AtapiInterrupt: (corrected)\n"));
5464 statusByte &= ~IDE_STATUS_ERROR;
5465 goto retry_check;
5466 }
5467*/
5468 if(AtaReq) {
5469 KdPrint2((PRINT_PREFIX " Bad Lba %#I64x\n", AtaReq->lba));
5470 } else {
5471 KdPrint2((PRINT_PREFIX " Bad Lba unknown\n"));
5472 }
5473
5474 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5475 KdPrint2((PRINT_PREFIX " no wait ready after error\n"));
5476 } else
5477 if(!atapiDev) {
5478 KdPrint2((PRINT_PREFIX " wait 100 ready after IDE error\n"));
5480 } else {
5481 KdPrint2((PRINT_PREFIX " wait 10 ready after ATAPI error\n"));
5483 }
5484continue_err:
5485
5486 KdPrint3((PRINT_PREFIX " Intr on DRQ %x\n",
5487 LunExt->DeviceFlags & DFLAGS_INT_DRQ));
5488
5489 for (k = atapiDev ? 0 : 200; k; k--) {
5490 GetBaseStatus(chan, statusByte);
5491 if (!(statusByte & IDE_STATUS_DRQ)) {
5493 } else {
5494 break;
5495 }
5496 }
5497
5498 if (!atapiDev) {
5499 /* if this is a UDMA CRC error, reinject request */
5500
5501 AtaReq->retry++;
5502 if(AtaReq->retry < MAX_RETRIES) {
5503#ifdef IO_STATISTICS
5504 chan->lun[DeviceNumber]->ModeErrorCount[AtaReq->retry]++;
5505#endif //IO_STATISTICS
5506 if(DmaTransfer /*&&
5507 (error & IDE_ERROR_ICRC)*/) {
5508 KdPrint2((PRINT_PREFIX "Errors in DMA mode\n"));
5509 if(AtaReq->retry < MAX_RETRIES) {
5510//fallback_pio:
5511 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
5512 //AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5513 // Downrate will happen in AtapiDmaReinit(), try UDMA-2 for HDD only
5514 AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5515 }
5516 AtaReq->ReqState = REQ_STATE_QUEUED;
5517 goto reenqueue_req;
5518 }
5519 } else {
5520 if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5521 AtaReq->retry++;
5522 }
5523 KdPrint2((PRINT_PREFIX "Errors in PIO mode\n"));
5524 }
5525 }
5526 } else {
5528 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI Error, int reason %x\n", interruptReason));
5529
5530 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
5531 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5532 // Do nothing here
5533 } else
5534 if(deviceExtension->HwFlags & UNIATA_SATA) {
5535 UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, 0);
5536 }
5537 }
5538
5539 if(DmaTransfer && (chan->lun[DeviceNumber]->TransferMode > ATA_UDMA2) &&
5540 ((error >> 4) == SCSI_SENSE_HARDWARE_ERROR)) {
5541 if(AtaReq->retry < MAX_RETRIES) {
5542//fallback_pio:
5543 // Downrate will happen in AtapiDmaReinit(), use PIO immediately for ATAPI
5544 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
5545 AtaReq->Flags |= REQ_FLAG_FORCE_DOWNRATE;
5546// LunExt->DeviceFlags |= DFLAGS_FORCE_DOWNRATE;
5547 AtaReq->ReqState = REQ_STATE_QUEUED;
5548 goto reenqueue_req;
5549 }
5550 } else {
5551 if(!(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE)) {
5552 AtaReq->retry++;
5553 }
5554 KdPrint3((PRINT_PREFIX "Errors in PIO mode\n"));
5555 }
5556 }
5557
5558 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error\n"));
5559 if (srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
5560 // Fail this request.
5562 goto CompleteRequest;
5563 } else {
5564 KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n"));
5565 }
5566 } else
5567 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE_LBA48) {
5568 KdPrint2((PRINT_PREFIX "DMA doesn't work right with LBA48\n"));
5569 deviceExtension->HbaCtrlFlags |= HBAFLAGS_DMA_DISABLED_LBA48;
5570 } else
5571 if(AtaReq->Flags & REQ_FLAG_FORCE_DOWNRATE) {
5572#ifdef IO_STATISTICS
5573 KdPrint2((PRINT_PREFIX "Some higher mode doesn't work right :((\n"));
5574 KdPrint2((PRINT_PREFIX "Recovery stats[%d]: %d vs %d\n",
5575 AtaReq->retry,
5576 LunExt->RecoverCount[AtaReq->retry],
5577 LunExt->BlockIoCount
5578 ));
5579 LunExt->RecoverCount[AtaReq->retry]++;
5580 if(LunExt->RecoverCount[AtaReq->retry] >= LunExt->BlockIoCount/3 ||
5581 (deviceExtension->HwFlags & UNIATA_NO80CHK)
5582 ) {
5583#else
5584 if(deviceExtension->HwFlags & UNIATA_NO80CHK) {
5585#endif //IO_STATISTICS
5586 KdPrint2((PRINT_PREFIX "Limit transfer rate to %x\n", LunExt->TransferMode));
5587 LunExt->LimitedTransferMode =
5588 LunExt->TransferMode;
5589 }
5590 }
5591#ifdef IO_STATISTICS
5592 if(AtaReq->bcount) {
5593 // we need stats for Read/Write operations
5594 LunExt->BlockIoCount++;
5595 }
5596 LunExt->IoCount++;
5597#endif //IO_STATISTICS
5598
5599continue_PIO:
5600
5601 // check reason for this interrupt.
5602 if (atapiDev) {
5603
5604 KdPrint2((PRINT_PREFIX "AtapiInterrupt: ATAPI branch\n"));
5605 // ATAPI branch
5606
5608 KdPrint3((PRINT_PREFIX "AtapiInterrupt: iReason %x\n", interruptReason));
5609 if(DmaTransfer) {
5610 wordsThisInterrupt = DEV_BSIZE/2*512;
5611 } else {
5612 wordsThisInterrupt = DEV_BSIZE/2;
5613 }
5614
5615 } else {
5616
5617 // ATA branch
5618
5619 if(DmaTransfer) {
5620 // simulate DRQ for DMA transfers
5621 statusByte |= IDE_STATUS_DRQ;
5622 }
5623 if (statusByte & IDE_STATUS_DRQ) {
5624
5625 if(DmaTransfer) {
5626 wordsThisInterrupt = DEV_BSIZE/2*512;
5627 } else
5628 if (LunExt->MaximumBlockXfer) {
5629 wordsThisInterrupt = DEV_BSIZE/2 * LunExt->MaximumBlockXfer;
5630 }
5631
5632 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5633
5634 interruptReason = ATAPI_IR_IO_toHost;
5635
5636 } else if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5637 interruptReason = ATAPI_IR_IO_toDev;
5638
5639 } else {
5641 goto CompleteRequest;
5642 }
5643
5644 } else if (statusByte & IDE_STATUS_BUSY) {
5645
5646 //AtapiEnableInterrupts(deviceExtension, lChannel);
5647 KdPrint2((PRINT_PREFIX "AtapiInterrupt: return FALSE on ATA IDE_STATUS_BUSY\n"));
5648 return FALSE;
5649
5650 } else {
5651
5652 KdPrint2((PRINT_PREFIX "AtapiInterrupt: !DRQ, !BUSY, WordsLeft %#x\n", AtaReq->WordsLeft));
5653 if (AtaReq->WordsLeft) {
5654
5655 // Funky behaviour seen with PCI IDE (not all, just one).
5656PIO_wait_DRQ0:
5657 // The ISR hits with DRQ low, but comes up later.
5658 for (k = 0; k < 5000; k++) {
5659 GetBaseStatus(chan, statusByte);
5660 if (statusByte & IDE_STATUS_DRQ) {
5661 break;
5662 }
5663 if(!InDpc) {
5664 // goto DPC
5666 TimerValue = 100;
5667 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq0)\n"));
5668#ifndef UNIATA_CORE
5669 goto PostToDpc;
5670#else //UNIATA_CORE
5671 AtapiStallExecution(TimerValue);
5672 goto ServiceInterrupt;
5673#endif //UNIATA_CORE
5674 }
5676 }
5677 if (k == 5000) {
5678 // reset the controller.
5679 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ not up. Status %#x\n",
5680 statusByte));
5681IntrPrepareResetController:
5682 AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_CURRENT);
5683 goto ReturnEnableIntr;
5684
5685 } else {
5686 interruptReason = (srb->SrbFlags & SRB_FLAGS_DATA_IN) ? ATAPI_IR_IO_toHost : ATAPI_IR_IO_toDev;
5687 }
5688
5689 } else {
5690 // Command complete - verify, write, or the SMART enable/disable.
5691 // Also get_media_status
5692 interruptReason = ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd;
5693 }
5694 }
5695 }
5696
5697 KdPrint2((PRINT_PREFIX "AtapiInterrupt: i-reason=%d, status=%#x\n", interruptReason, statusByte));
5698 if(deviceExtension->HwFlags & UNIATA_AHCI) {
5699 KdPrint2((PRINT_PREFIX " AHCI path, WordsTransfered %x, WordsLeft %x\n", AtaReq->WordsTransfered, AtaReq->WordsLeft));
5700/* if(chan->AhciLastIS & ATA_AHCI_P_IX_OF) {
5701 //status = SRB_STATUS_DATA_OVERRUN;
5702 DataOverrun = TRUE;
5703 } else {
5704 status = SRB_STATUS_SUCCESS;
5705 }*/
5706 if(AtaReq->WordsTransfered >= AtaReq->WordsLeft) {
5707 AtaReq->WordsLeft = 0;
5708 } else {
5709 AtaReq->WordsLeft -= AtaReq->WordsTransfered;
5710 }
5711 //if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
5712 // status = SRB_STATUS_DATA_OVERRUN;
5713 //}
5715 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5716 goto CompleteRequest;
5717 } else
5718 if ((interruptReason == ATAPI_IR_COD_Cmd) && (statusByte & IDE_STATUS_DRQ)) {
5720 AtapiDmaDBPreSync(HwDeviceExtension, chan, srb);
5721 }
5722 // Write the packet.
5723 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Writing Atapi packet.\n"));
5724 // Send CDB to device.
5725 WriteBuffer(chan, (PUSHORT)srb->Cdb,
5726 LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
5727 /*0*/ PIO0_TIMING);
5729
5731 KdPrint2((PRINT_PREFIX "AtapiInterrupt: AtapiDmaStart().\n"));
5732 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, srb);
5733 }
5734
5735 goto ReturnEnableIntr;
5736
5737 } else if ((interruptReason == ATAPI_IR_IO_toDev) && (statusByte & IDE_STATUS_DRQ)) {
5738
5739 // Write the data.
5740 if (atapiDev) {
5741
5742 // Pick up bytes to transfer and convert to words.
5743 wordCount =
5745
5746 wordCount |=
5748
5749 // Covert bytes to words.
5750 wordCount >>= 1;
5751 KdPrint2((PRINT_PREFIX "AtapiInterrupt: get W wordCount %#x\n", wordCount));
5752
5753 if (wordCount != AtaReq->WordsLeft) {
5755 "AtapiInterrupt: %d words requested; %d words xferred\n",
5756 AtaReq->WordsLeft,
5757 wordCount));
5758 }
5759
5760 // Verify this makes sense.
5761 if (wordCount > AtaReq->WordsLeft) {
5762 wordCount = AtaReq->WordsLeft;
5764 "AtapiInterrupt: Write underrun\n"));
5765 DataOverrun = TRUE;
5766 }
5767
5768 } else {
5769
5770 // IDE path. Check if words left is at least DEV_BSIZE/2 = 256.
5771 if (AtaReq->WordsLeft < wordsThisInterrupt) {
5772 // Transfer only words requested.
5773 wordCount = AtaReq->WordsLeft;
5774 } else {
5775 // Transfer next block.
5776 wordCount = wordsThisInterrupt;
5777 }
5778 }
5779
5780 if (DmaTransfer &&
5782 //ASSERT(AtaReq->WordsLeft == wordCount);
5785 "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5786 if(AtaReq->WordsLeft > wordCount) {
5787 AtaReq->WordsLeft -= wordCount;
5788 AtaReq->WordsTransfered += wordCount;
5790 goto ReturnEnableIntr;
5791 }
5792 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5793 }
5794 AtaReq->WordsTransfered = AtaReq->WordsLeft;
5795 AtaReq->WordsLeft = 0;
5797 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5798 goto CompleteRequest;
5799 }
5800
5801 // Ensure that this is a write command.
5802 if (srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
5803
5805 "AtapiInterrupt: Write interrupt\n"));
5806
5807 statusByte = WaitOnBusy(chan);
5808
5809 if (/*atapiDev || */ !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED)
5810 || (wordCount & 1)) {
5811
5812 WriteBuffer(chan,
5813 AtaReq->DataBuffer,
5814 wordCount,
5815 UniataGetPioTiming(LunExt));
5816 } else {
5817
5818 WriteBuffer2(chan,
5819 (PULONG)(AtaReq->DataBuffer),
5820 wordCount / 2,
5821 UniataGetPioTiming(LunExt));
5822 }
5823 } else {
5824
5826 "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5827 interruptReason,
5828 srb));
5829
5830 // Fail this request.
5832 if(!wordCount && atapiDev && (srb->Cdb[0] != SCSIOP_REQUEST_SENSE)) {
5833 // some devices feel bad after incorrect commands and may need reset
5835 "AtapiInterrupt: Try ATAPI reset\n"));
5836
5837 AtapiDisableInterrupts(deviceExtension, lChannel);
5839 AtapiEnableInterrupts(deviceExtension, lChannel);
5842
5843// goto IntrPrepareResetController;
5844 }
5845 goto CompleteRequest;
5846 }
5847 // Advance data buffer pointer and bytes left.
5848 AtaReq->DataBuffer += wordCount;
5849 AtaReq->WordsLeft -= wordCount;
5850 AtaReq->WordsTransfered += wordCount;
5851
5852 if (atapiDev) {
5854 }
5855
5856 goto ReturnEnableIntr;
5857
5858 } else if (interruptReason == ATAPI_IR_IO_toHost && (statusByte & IDE_STATUS_DRQ)) {
5859
5860continue_read_drq:
5861
5862 if (atapiDev) {
5863
5864 // Pick up bytes to transfer and convert to words.
5865 wordCount =
5868
5869 // Convert bytes to words.
5870 KdPrint2((PRINT_PREFIX "AtapiInterrupt: get R byteCount %#x\n", wordCount));
5871 wordCount >>= 1;
5872 /*
5873 When ATAPI 64k PIO read is requested we may have 0xfffe byte
5874 count reported for 0x10000 bytes in single interrupt.
5875 It is not allowed to read entire 64k block with DwordIo intead of
5876 wait for last word.
5877 */
5878 if (wordCount != AtaReq->WordsLeft) {
5880 "AtapiInterrupt: %d words requested; %d words xferred\n",
5881 AtaReq->WordsLeft,
5882 wordCount));
5883 }
5884
5885 // Verify this makes sense.
5886 if (wordCount > AtaReq->WordsLeft) {
5887 wordCount = AtaReq->WordsLeft;
5888 DataOverrun = TRUE;
5889 }
5890
5891 } else {
5892
5893 // Check if words left is at least 256.
5894 if (AtaReq->WordsLeft < wordsThisInterrupt) {
5895 // Transfer only words requested.
5896 wordCount = AtaReq->WordsLeft;
5897 } else {
5898 // Transfer next block.
5899 wordCount = wordsThisInterrupt;
5900 }
5901 }
5902
5903 if(DmaTransfer &&
5907 "IdeIntr: DMA tmp INTR %#x vs %#x\n", AtaReq->WordsLeft, wordCount));
5908 if(AtaReq->WordsLeft > wordCount) {
5909 AtaReq->WordsLeft -= wordCount;
5910 AtaReq->WordsTransfered += wordCount;
5912 goto ReturnEnableIntr;
5913 }
5914 dma_status = AtapiDmaDone(HwDeviceExtension, DEVNUM_NOT_SPECIFIED, lChannel, NULL/*srb*/);
5915 }
5916 //ASSERT(AtaReq->WordsLeft == wordCount);
5917 AtaReq->WordsTransfered = AtaReq->WordsLeft;
5918 AtaReq->WordsLeft = 0;
5920 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
5921 goto CompleteRequest;
5922 }
5923 // Ensure that this is a read command.
5924 if (srb->SrbFlags & SRB_FLAGS_DATA_IN) {
5925
5926/* KdPrint2((
5927 "AtapiInterrupt: Read interrupt\n"));*/
5928
5929 statusByte = WaitOnBusy(chan);
5930
5931 if(wordCount&1 && atapiDev && (g_opt_VirtualMachine == VM_BOCHS)) {
5933 "IdeIntr: unaligned ATAPI %#x Words\n", wordCount));
5934 } else
5935 if(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) {
5937 "IdeIntr: pre-Read %#x Dwords\n", wordCount/2));
5938
5939 ReadBuffer2(chan,
5940 (PULONG)(AtaReq->DataBuffer),
5941 wordCount / 2,
5942 UniataGetPioTiming(LunExt));
5943 // Advance data buffer pointer and bytes left.
5944 AtaReq->DataBuffer += wordCount & ~1;
5945 AtaReq->WordsLeft -= wordCount & ~1;
5946 AtaReq->WordsTransfered += wordCount & ~1;
5947 wordCount &= 1;
5948 }
5949 if (wordCount) {
5951 "IdeIntr: Read %#x words\n", wordCount));
5952
5953 ReadBuffer(chan,
5954 AtaReq->DataBuffer,
5955 wordCount,
5956 UniataGetPioTiming(LunExt));
5957 }
5958
5959 KdPrint2(("IdeIntr: PIO Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x\n", AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)-1) ));
5960 //KdDump(AtaReq->DataBuffer, wordCount*2);
5961 if(srb && atapiDev && srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
5962 KdDump(AtaReq->DataBuffer, wordCount*2);
5963 }
5964
5965 GetBaseStatus(chan, statusByte);
5966 KdPrint2((PRINT_PREFIX " status re-check %#x\n", statusByte));
5967
5968 if(DataOverrun) {
5969 KdPrint2((PRINT_PREFIX " DataOverrun\n"));
5970 AtapiSuckPort2(chan);
5971 GetBaseStatus(chan, statusByte);
5972 }
5973
5974 if(statusByte & IDE_STATUS_BUSY) {
5975 for (i = 0; i < 2; i++) {
5977 GetBaseStatus(chan, statusByte);
5978 if (!(statusByte & IDE_STATUS_BUSY)) {
5979 break;
5980 }
5981 }
5982 }
5983
5984 } else {
5985
5987 "AtapiInterrupt: Int reason %#x, but srb is for a read %#x.\n",
5988 interruptReason,
5989 srb));
5990
5991 // Fail this request.
5993 goto CompleteRequest;
5994 }
5995//continue_atapi_pio_read:
5996 // Advance data buffer pointer and bytes left.
5997 AtaReq->DataBuffer += wordCount;
5998 AtaReq->WordsLeft -= wordCount;
5999 AtaReq->WordsTransfered += wordCount;
6000
6001 // Check for read command complete.
6002 if (AtaReq->WordsLeft == 0) {
6003
6004 KdPrint2((PRINT_PREFIX "AtapiInterrupt: all transferred, AtaReq->WordsLeft == 0\n"));
6005 if (atapiDev) {
6006
6007 if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM) {
6008
6009 // Work around to make many atapi devices return correct sector size
6010 // of 2048. Also certain devices will have sector count == 0x00, check
6011 // for that also.
6012 if (srb->Cdb[0] == SCSIOP_READ_CAPACITY) {
6013
6014 AtaReq->DataBuffer -= AtaReq->WordsTransfered;
6015 if (AtaReq->DataBuffer[0] == 0x00) {
6016 *((ULONG *) &(AtaReq->DataBuffer[0])) = 0xFFFFFF7F;
6017 }
6018
6019 *((ULONG *) &(AtaReq->DataBuffer[2])) = 0x00080000;
6020 AtaReq->DataBuffer += AtaReq->WordsTransfered;
6021 }
6022#ifndef UNIATA_INIT_CHANGERS
6023 else
6024 if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
6025
6026 KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
6027 // Bingo!!
6028 AtapiHwInitializeChanger (HwDeviceExtension,
6029 srb,
6032 KdPrint2((PRINT_PREFIX " set DFLAGS_CHANGER_INITED\n"));
6033 }
6034#endif // UNIATA_INIT_CHANGERS
6035 }
6036 GetStatus(chan, statusByte);
6037 if(!(statusByte & IDE_STATUS_BUSY)) {
6038 // Assume command is completed if BUSY is cleared
6039 // and all data read
6040 // Optionally, we may receive COMPLETE interrupt later and
6041 // treat it as unexpected
6042 KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete ? status %x\n", statusByte));
6043
6045 goto CompleteRequest;
6046 }
6047
6048 } else {
6049
6050 /*
6051 // Completion for IDE drives.
6052 if (AtaReq->WordsLeft) {
6053 status = SRB_STATUS_DATA_OVERRUN;
6054 } else {
6055 status = SRB_STATUS_SUCCESS;
6056 }
6057
6058 goto CompleteRequest;
6059 */
6061 goto CompleteRequest;
6062
6063 }
6064 } else {
6065 if (atapiDev) {
6067 GetStatus(chan, statusByte);
6068 if(!(statusByte & IDE_STATUS_BUSY)) {
6069 // Assume command is completed if BUSY is cleared
6070 // even if NOT all data read
6071 // Optionally, we may receive COMPLETE interrupt later and
6072 // treat it as unexpected
6073 KdPrint2((PRINT_PREFIX "AtapiInterrupt: early complete + underrun ? status %x\n", statusByte));
6074
6076 goto CompleteRequest;
6077 }
6078 } else {
6079 if(!atapiDev && !DataOverrun && (srb->SrbFlags & SRB_FLAGS_DATA_IN) &&
6080 ((statusByte & ~IDE_STATUS_INDEX) == (IDE_STATUS_IDLE | IDE_STATUS_DRQ))) {
6081 KdPrint2((PRINT_PREFIX " HDD read data ready \n"));
6082 goto continue_read_drq;
6083 }
6084 }
6085 }
6086
6087 goto ReturnEnableIntr;
6088
6089 } else if (interruptReason == (ATAPI_IR_IO_toHost | ATAPI_IR_COD_Cmd) && !(statusByte & IDE_STATUS_DRQ)) {
6090
6091 KdPrint2((PRINT_PREFIX "AtapiInterrupt: interruptReason = CompleteRequest\n"));
6092 // Command complete. We exactly know this because of IReason.
6093
6094 if(DmaTransfer) {
6095 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was DmaTransfer\n"));
6096 AtaReq->WordsTransfered += AtaReq->WordsLeft;
6097 AtaReq->WordsLeft = 0;
6098 } else {
6099 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, was PIO\n"));
6100
6101 wordCount = AtaReq->WordsLeft;
6102 // Advance data buffer pointer and bytes left.
6103 AtaReq->DataBuffer += wordCount;
6104 AtaReq->WordsLeft -= wordCount;
6105 AtaReq->WordsTransfered += wordCount;
6106
6107 KdPrint2((PRINT_PREFIX "AtapiInterrupt: wordCount %#x, WordsTransfered %#x\n", wordCount, AtaReq->WordsTransfered));
6108
6109 }
6110 //if (AtaReq->WordsLeft) {
6111 // status = SRB_STATUS_DATA_OVERRUN;
6112 //} else {
6114 //}
6115
6116#ifdef UNIATA_DUMP_ATAPI
6117 if(srb &&
6118 srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6119 UCHAR ScsiCommand;
6120 PCDB Cdb;
6121 PCHAR CdbData;
6122 PCHAR ModeSelectData;
6123 ULONG CdbDataLen;
6125
6126 Cdb = (PCDB)(Srb->Cdb);
6127 ScsiCommand = Cdb->CDB6.OperationCode;
6128 CdbData = (PCHAR)(Srb->DataBuffer);
6129 CdbDataLen = Srb->DataTransferLength;
6130
6131 if(CdbDataLen > 0x1000) {
6132 CdbDataLen = 0x1000;
6133 }
6134
6135 KdPrint(("--\n"));
6136 KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
6137 KdPrint2(("P:T:D=%d:%d:%d\n",
6138 Srb->PathId,
6139 Srb->TargetId,
6140 Srb->Lun));
6141 KdPrint(("Complete SCSI Command %2.2x\n", ScsiCommand));
6142 KdDump(Cdb, 16);
6143
6144 if(ScsiCommand == SCSIOP_MODE_SENSE) {
6145 KdPrint(("ModeSense 6\n"));
6147 ModeSelectData = CdbData+4;
6148 KdDump(CdbData, CdbDataLen);
6149 } else
6150 if(ScsiCommand == SCSIOP_MODE_SENSE10) {
6151 KdPrint(("ModeSense 10\n"));
6153 ModeSelectData = CdbData+8;
6154 KdDump(CdbData, CdbDataLen);
6155 } else {
6156 if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6157 KdPrint(("Read buffer from device:\n"));
6158 KdDump(CdbData, CdbDataLen);
6159 }
6160 }
6161 KdPrint(("--\n"));
6162 }
6163#endif //UNIATA_DUMP_ATAPI
6164
6166
6167 KdPrint2((PRINT_PREFIX "AtapiInterrupt: CompleteRequest, srbstatus %x\n", status));
6168 // Check and see if we are processing our secret (mechanism status/request sense) srb
6169
6170 if(AtaReq->WordsLeft && (status == SRB_STATUS_SUCCESS)) {
6171 KdPrint2((PRINT_PREFIX "WordsLeft %#x -> SRB_STATUS_DATA_OVERRUN\n", AtaReq->WordsLeft));
6173 }
6174
6175 if (AtaReq->OriginalSrb) {
6176
6177 ULONG srbStatus;
6178
6179 KdPrint2((PRINT_PREFIX "AtapiInterrupt: OriginalSrb != NULL\n"));
6180 if (srb->Cdb[0] == SCSIOP_MECHANISM_STATUS) {
6181#ifdef UNIATA_INIT_CHANGERS
6182 // We can get here only when UNIATA_INIT_CHANGERS is defined
6183 KdPrint3((PRINT_PREFIX "AtapiInterrupt: SCSIOP_MECHANISM_STATUS status %#x\n", status));
6184 if (status == SRB_STATUS_SUCCESS) {
6185 // Bingo!!
6186 AtapiHwInitializeChanger (HwDeviceExtension,
6187 srb,
6189
6190 // Get ready to issue the original srb
6191 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6192 AtaReq->OriginalSrb = NULL;
6193
6194 } else {
6195 // failed! Get the sense key and maybe try again
6196 srb = AtaReq->Srb = BuildRequestSenseSrb (
6197 HwDeviceExtension,
6198 AtaReq->OriginalSrb);
6199 }
6200/*
6201 // do not enable interrupts in DPC, do not waste time, do it now!
6202 if(UseDpc && chan->DisableIntr) {
6203 AtapiEnableInterrupts(HwDeviceExtension, c);
6204 UseDpc = FALSE;
6205 RestoreUseDpc = TRUE;
6206 }
6207*/
6208 srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
6209
6210 KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
6211
6212 if (srbStatus == SRB_STATUS_PENDING) {
6213 KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (1)\n"));
6214 goto ReturnEnableIntr;
6215 }
6216/*
6217 if(RestoreUseDpc) {
6218 // restore state on error
6219 UseDpc = TRUE;
6220 AtapiDisableInterrupts(HwDeviceExtension, c);
6221 }
6222*/
6223#else
6224 KdPrint((PRINT_PREFIX "AtapiInterrupt: ERROR: internal SCSIOP_MECHANISM_STATUS !!!!\n"));
6225 ASSERT(FALSE);
6226#endif // UNIATA_INIT_CHANGERS
6227 } else { // srb->Cdb[0] == SCSIOP_REQUEST_SENSE)
6228
6229 PSENSE_DATA senseData = (PSENSE_DATA) srb->DataBuffer;
6230#ifdef __REACTOS__
6231 (void)senseData;
6232#endif
6233
6234 KdPrint3((PRINT_PREFIX "AtapiInterrupt: ATAPI command status %#x\n", status));
6236 // Check to see if we at least get mininum number of bytes
6237 if ((srb->DataTransferLength - AtaReq->WordsLeft) >
6238 (FIELD_OFFSET (SENSE_DATA, AdditionalSenseLength) + sizeof(senseData->AdditionalSenseLength))) {
6240 }
6241 }
6242
6243 if (status == SRB_STATUS_SUCCESS) {
6244#ifndef UNIATA_CORE
6245#ifdef UNIATA_INIT_CHANGERS
6246 if ((senseData->SenseKey != SCSI_SENSE_ILLEGAL_REQUEST) &&
6247 FALSE &&
6248 chan->MechStatusRetryCount) {
6249
6250 KdPrint3((PRINT_PREFIX "AtapiInterrupt: MechStatusRetryCount %#x\n", chan->MechStatusRetryCount));
6251 // The sense key doesn't say the last request is illegal, so try again
6252 chan->MechStatusRetryCount--;
6253 srb = AtaReq->Srb = BuildMechanismStatusSrb (
6254 HwDeviceExtension,
6255 AtaReq->OriginalSrb);
6256 } else
6257#endif // UNIATA_INIT_CHANGERS
6258 {
6259 // Get ready to issue the original srb
6260 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6261 AtaReq->OriginalSrb = NULL;
6262 }
6263#endif //UNIATA_CORE
6264/*
6265 // do not enable interrupts in DPC, do not waste time, do it now!
6266 if(UseDpc && chan->DisableIntr) {
6267 AtapiEnableInterrupts(HwDeviceExtension, c);
6268 UseDpc = FALSE;
6269 RestoreUseDpc = TRUE;
6270 }
6271*/
6272 srbStatus = AtapiSendCommand(HwDeviceExtension, srb, CMD_ACTION_ALL);
6273
6274 KdPrint3((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (2)\n", chan->ExpectingInterrupt));
6275
6276 if (srbStatus == SRB_STATUS_PENDING) {
6277 KdPrint2((PRINT_PREFIX "AtapiInterrupt: send orig SRB_STATUS_PENDING (2)\n"));
6278 goto ReturnEnableIntr;
6279 }
6280/*
6281 if(RestoreUseDpc) {
6282 // restore state on error
6283 UseDpc = TRUE;
6284 AtapiDisableInterrupts(HwDeviceExtension, c);
6285 }
6286*/
6287 }
6288 }
6289
6290 // If we get here, it means AtapiSendCommand() has failed
6291 // Can't recover. Pretend the original srb has failed and complete it.
6292
6293 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. complete OriginalSrb\n"));
6294
6295 if (AtaReq->OriginalSrb) {
6296 srb = AtaReq->Srb = AtaReq->OriginalSrb;
6297 AtaReq->OriginalSrb = NULL;
6298 }
6299
6300 KdPrint2((PRINT_PREFIX "AtapiInterrupt: chan->ExpectingInterrupt %d (3)\n", chan->ExpectingInterrupt));
6301
6302 // fake an error and read no data
6304 srb->ScsiStatus = 0;
6305 AtaReq->DataBuffer = (PUSHORT)(srb->DataBuffer);
6306 AtaReq->WordsLeft = srb->DataTransferLength;
6307 chan->RDP = FALSE;
6308
6309 } else if (status == SRB_STATUS_ERROR) {
6310
6311 // Map error to specific SRB status and handle request sense.
6312 KdPrint3((PRINT_PREFIX "AtapiInterrupt: Error. Begin mapping...\n"));
6313 status = MapError(deviceExtension,
6314 srb);
6315
6316 chan->RDP = FALSE;
6317
6318 } else if(!DmaTransfer) {
6319
6320 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion\n"));
6321 // Command complete.
6322PIO_wait_busy:
6323 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO completion, wait BUSY\n"));
6324 // Wait for busy to drop.
6325 for (i = 0; i < 5*30; i++) {
6326 GetBaseStatus(chan, statusByte);
6327 if (!(statusByte & IDE_STATUS_BUSY)) {
6328 break;
6329 }
6330 if(!InDpc) {
6331 // goto DPC
6333 TimerValue = 200;
6334 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (busy)\n"));
6335#ifndef UNIATA_CORE
6336 goto PostToDpc;
6337#else //UNIATA_CORE
6338 AtapiStallExecution(TimerValue);
6339 goto ServiceInterrupt;
6340#endif //UNIATA_CORE
6341 }
6343 }
6344
6345 if (i == 5*30) {
6346
6347 // reset the controller.
6349 "AtapiInterrupt: Resetting due to BSY still up - %#x.\n",
6350 statusByte));
6351 goto IntrPrepareResetController;
6352 }
6353 // Check to see if DRQ is still up.
6354 if(statusByte & IDE_STATUS_DRQ) {
6355 KdPrint2((PRINT_PREFIX "AtapiInterrupt: DRQ...\n"));
6356 if(srb) {
6357 if(srb->SrbFlags & SRB_FLAGS_DATA_IN) {
6358 KdPrint2((PRINT_PREFIX "srb %x data in\n", srb));
6359 } else {
6360 KdPrint2((PRINT_PREFIX "srb %x data out\n", srb));
6361 }
6362 } else {
6363 KdPrint2((PRINT_PREFIX "srb NULL\n"));
6364 }
6365 if(AtaReq) {
6366 KdPrint2((PRINT_PREFIX "AtaReq %x AtaReq->WordsLeft=%x\n", AtaReq, AtaReq->WordsLeft));
6367 } else {
6368 KdPrint2((PRINT_PREFIX "AtaReq NULL\n"));
6369 }
6370 if(AtaReq && AtaReq->WordsLeft /*&&
6371 !(LunExt->DeviceFlags & (DFLAGS_ATAPI_DEVICE | DFLAGS_TAPE_DEVICE | DFLAGS_LBA_ENABLED))*/) {
6372 KdPrint2((PRINT_PREFIX "DRQ+AtaReq->WordsLeft -> next portion\n"));
6373 goto continue_PIO;
6374 }
6375 }
6376 //if (atapiDev && (statusByte & IDE_STATUS_DRQ)) {}
6377 //if ((statusByte & IDE_STATUS_DRQ)) {}
6378 if((statusByte & IDE_STATUS_DRQ) &&
6380
6381PIO_wait_DRQ:
6382 KdPrint2((PRINT_PREFIX "AtapiInterrupt: PIO_wait_DRQ\n"));
6383 for (i = 0; i < 200; i++) {
6384 GetBaseStatus(chan, statusByte);
6385 if (!(statusByte & IDE_STATUS_DRQ)) {
6386 break;
6387 }
6388 if(!InDpc) {
6389 // goto DPC
6390 KdPrint2((PRINT_PREFIX "AtapiInterrupt: go to DPC (drq)\n"));
6392 TimerValue = 100;
6393#ifndef UNIATA_CORE
6394 goto PostToDpc;
6395#else //UNIATA_CORE
6396 AtapiStallExecution(TimerValue);
6397 goto ServiceInterrupt;
6398#endif //UNIATA_CORE
6399 }
6401 }
6402
6403 if (i == 200) {
6404 // reset the controller.
6405 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Resetting due to DRQ still up - %#x\n",
6406 statusByte));
6407 goto IntrPrepareResetController;
6408 }
6409 }
6410 if(atapiDev) {
6411 KdPrint2(("IdeIntr: ATAPI Read AtaReq->DataBuffer %#x, srb->DataBuffer %#x, len %#x\n",
6412 AtaReq->DataBuffer, (srb ? srb->DataBuffer : (void*)(-1)), srb->DataTransferLength ));
6413 //KdDump(srb->DataBuffer, srb->DataTransferLength);
6414 }
6415 if(!AtapiDmaPioSync(HwDeviceExtension, srb, (PUCHAR)(srb->DataBuffer), srb->DataTransferLength)) {
6416 KdPrint2(("IdeIntr: Can't sync DMA and PIO buffers\n"));
6417 }
6418 }
6419
6420 // Clear interrupt expecting flag.
6422 // clear this flag now, it can be set again in sub-calls
6425
6426 // Sanity check that there is a current request.
6427 if(srb != NULL) {
6428 // Set status in SRB.
6429 srb->SrbStatus = (UCHAR)status;
6430
6431 // Check for underflow.
6432 if(AtaReq->WordsLeft) {
6433
6434 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Check for underflow, AtaReq->WordsLeft %x\n", AtaReq->WordsLeft));
6435 // Subtract out residual words and update if filemark hit,
6436 // setmark hit , end of data, end of media...
6437 if (!(LunExt->DeviceFlags & DFLAGS_TAPE_DEVICE)) {
6439 srb->DataTransferLength -= AtaReq->WordsLeft*2;
6440 } else {
6441 srb->DataTransferLength = 0;
6442 }
6443 } else {
6444 srb->DataTransferLength -= AtaReq->WordsLeft*2;
6445 }
6446 }
6447 if(status == SRB_STATUS_SUCCESS) {
6448 //if(!(deviceExtension->HwFlags & UNIATA_AHCI) && !atapiDev) {
6449 // // This should be set in UniataAhciEndTransaction() for AHCI
6450 // AtaReq->WordsTransfered += AtaReq->bcount * DEV_BSIZE/2;
6451 //}
6452 if(!atapiDev &&
6453 AtaReq->WordsTransfered*2 < AtaReq->TransferLength) {
6454 KdPrint2((PRINT_PREFIX "AtapiInterrupt: more I/O required (%x of %x bytes) -> reenqueue\n",
6455 AtaReq->WordsTransfered*2, AtaReq->TransferLength));
6456 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
6458 goto reenqueue_req;
6459 } else {
6460 KdPrint2((PRINT_PREFIX " Transfered %x, full size %x\n",
6461 AtaReq->WordsTransfered*2, AtaReq->TransferLength));
6462 }
6463 }
6464
6465 if (srb->Function != SRB_FUNCTION_IO_CONTROL) {
6466
6467CompleteRDP:
6468 // Indicate command complete.
6469 if (!(chan->RDP)) {
6470 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete\n"));
6471IntrCompleteReq:
6472
6473 if (status == SRB_STATUS_SUCCESS &&
6474 srb->SenseInfoBuffer &&
6475 srb->SenseInfoBufferLength >= sizeof(SENSE_DATA)) {
6476
6477 PSENSE_DATA senseBuffer = (PSENSE_DATA)srb->SenseInfoBuffer;
6478
6479 KdPrint2((PRINT_PREFIX "AtapiInterrupt: set AutoSense\n"));
6480 senseBuffer->ErrorCode = 0;
6481 senseBuffer->Valid = 1;
6482 senseBuffer->AdditionalSenseLength = 0xb;
6483 senseBuffer->SenseKey = 0;
6484 senseBuffer->AdditionalSenseCode = 0;
6485 senseBuffer->AdditionalSenseCodeQualifier = 0;
6486
6488 }
6489 AtapiDmaDBSync(chan, srb);
6490 KdPrint2((PRINT_PREFIX "AtapiInterrupt: remove srb %#x, status %x\n", srb, status));
6491 UniataRemoveRequest(chan, srb);
6492 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestComplete, srb %#x\n", srb));
6494 deviceExtension,
6495 srb);
6496 }
6497 } else {
6498
6499 KdPrint2((PRINT_PREFIX "AtapiInterrupt: IOCTL completion\n"));
6500
6501 if (status != SRB_STATUS_SUCCESS) {
6503 KdPrint2((PRINT_PREFIX "AtapiInterrupt: error %#x\n", error));
6504 }
6505
6506 if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(srb->DataBuffer))->Signature),"SCSIDISK",sizeof("SCSIDISK")-1)) {
6507
6508 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6509 // Build the SMART status block depending upon the completion status.
6510 cmdOutParameters->cBufferSize = wordCount;
6511 cmdOutParameters->DriverStatus.bDriverError = (error) ? SMART_IDE_ERROR : 0;
6512 cmdOutParameters->DriverStatus.bIDEError = error;
6513
6514 // If the sub-command is return smart status, jam the value from cylinder low and high, into the
6515 // data buffer.
6516 if (chan->SmartCommand == RETURN_SMART_STATUS) {
6517 PIDEREGS_EX regs = (PIDEREGS_EX)&(cmdOutParameters->bBuffer);
6518
6519 regs->bOpFlags = 0;
6520 UniataSnapAtaRegs(chan, 0, regs);
6521
6522 regs->bCommandReg = SMART_CMD;
6523 regs->bFeaturesReg = RETURN_SMART_STATUS;
6524
6525 cmdOutParameters->cBufferSize = 8;
6526 }
6527 chan->SmartCommand = 0; // cleanup after execution
6528 }
6529 // Indicate command complete.
6530 goto IntrCompleteReq;
6531 }
6532
6533 } else {
6534
6535 KdPrint2((PRINT_PREFIX "AtapiInterrupt: No SRB!\n"));
6536 }
6537
6538 if (chan->RDP) {
6539 // Check DSC
6540 for (i = 0; i < 5; i++) {
6541 GetBaseStatus(chan, statusByte);
6542 if(!(statusByte & IDE_STATUS_BUSY)) {
6543 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RDP + cleared BUSY\n"));
6544 chan->RDP = FALSE;
6545 goto CompleteRDP;
6546 } else
6547 if (statusByte & IDE_STATUS_DSC) {
6548 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Clear RDP\n"));
6549 chan->RDP = FALSE;
6550 goto CompleteRDP;
6551 }
6553 }
6554 }
6555 // RDP can be cleared since previous check
6556 if (chan->RDP) {
6557 KdPrint2((PRINT_PREFIX "AtapiInterrupt: RequestTimerCall 2000\n"));
6558
6559 TimerValue = 2000;
6560#ifndef UNIATA_CORE
6561 goto CallTimerDpc;
6562#else //UNIATA_CORE
6563 AtapiStallExecution(TimerValue);
6564 goto ServiceInterrupt;
6565#endif //UNIATA_CORE
6566 }
6567
6568// ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
6569enqueue_next_req:
6570 // Get next request
6571 srb = UniataGetCurRequest(chan);
6572
6573reenqueue_req:
6574
6575#ifndef UNIATA_CORE
6576 KdPrint2((PRINT_PREFIX "AtapiInterrupt: NextRequest, srb=%#x\n",srb));
6577 if(!srb) {
6579 deviceExtension,
6580 NULL);
6581 } else {
6583 deviceExtension,
6584 PathId,
6585 TargetId,
6586 Lun);
6587 // in simplex mode next command must NOT be sent here
6588 if(!deviceExtension->simplexOnly) {
6589 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
6590 }
6591 }
6592 // Try to get SRB fron any non-empty queue (later)
6593 if(deviceExtension->simplexOnly) {
6594 NoStartIo = FALSE;
6595 }
6596#endif //UNIATA_CORE
6597
6598 goto ReturnEnableIntr;
6599
6600 } else {
6601
6602 // Unexpected int. Catch it
6603 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Unexpected ATAPI interrupt. InterruptReason %#x. Status %#x.\n",
6604 interruptReason,
6605 statusByte));
6606
6608 if(interruptReason == ATAPI_IR_IO_toDev && !(statusByte & IDE_STATUS_DRQ) && !DmaTransfer) {
6609 statusByte = WaitForDrq(chan);
6610 if(statusByte & IDE_STATUS_DRQ) {
6611 goto continue_PIO;
6612 }
6613 }
6614 }
6615
6616 if(OldReqState == REQ_STATE_DPC_WAIT_BUSY0 &&
6617 AtaReq->WordsLeft == 0) {
6618 KdPrint2((PRINT_PREFIX "AtapiInterrupt: pending WAIT_BUSY0. Complete.\n"));
6620 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
6621 goto CompleteRequest;
6622 }
6623 }
6624
6625ReturnEnableIntr:
6626
6627 KdPrint2((PRINT_PREFIX "AtapiInterrupt: ReturnEnableIntr\n",srb));
6628 //UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
6629 deviceExtension->ExpectingInterrupt = TRUE;
6630 if(UseDpc) {
6631 if(CrNtInterlockedExchangeAdd(&(chan->DisableIntr), 0)) {
6632 KdPrint2((PRINT_PREFIX "AtapiInterrupt: call AtapiEnableInterrupts__()\n"));
6633#ifdef UNIATA_USE_XXableInterrupts
6634 //ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
6636 // must be called on DISPATCH_LEVEL
6639#else
6640 AtapiEnableInterrupts(HwDeviceExtension, c);
6643 // Will raise IRQL to DIRQL
6644#ifndef UNIATA_CORE
6645 AtapiQueueTimerDpc(HwDeviceExtension, lChannel,
6647 1);
6648#endif // UNIATA_CORE
6649 KdPrint2((PRINT_PREFIX "AtapiInterrupt: Timer DPC inited\n"));
6650#endif // UNIATA_USE_XXableInterrupts
6651 }
6652 }
6653
6655 // in simplex mode next command must be sent here if
6656 // DPC is not used
6657 KdPrint2((PRINT_PREFIX "AtapiInterrupt: exiting, UseDpc=%d, NoStartIo=%d\n", UseDpc, NoStartIo));
6658
6659#ifndef UNIATA_CORE
6660 if(!UseDpc && /*deviceExtension->simplexOnly &&*/ !NoStartIo) {
6661 chan = UniataGetNextChannel(chan);
6662 if(chan) {
6663 srb = UniataGetCurRequest(chan);
6664 } else {
6665 srb = NULL;
6666 }
6667 KdPrint2((PRINT_PREFIX "AtapiInterrupt: run srb %x\n", srb));
6668 if(srb) {
6669 AtapiStartIo__(HwDeviceExtension, srb, FALSE);
6670 }
6671 }
6672#endif //UNIATA_CORE
6673 return TRUE;
6674
6675} // end AtapiInterrupt__()
#define InterlockedExchange
Definition: armddk.h:54
#define WaitForDrq(BaseIoAddress, Status)
Definition: atapi.h:387
#define AtapiSoftReset(BaseIoAddress, DeviceNumber)
Definition: atapi.h:418
#define UNIATA_NO80CHK
Definition: bm_devs_decl.h:630
#define PIO0_TIMING
Definition: bm_devs_decl.h:53
#define UniataGetPioTiming(LunExt)
Definition: bm_devs_decl.h:56
#define REQ_STATE_PROCESSING_INTR
Definition: bsmaster.h:958
#define REQ_STATE_ATAPI_EXPECTING_DATA_INTR
Definition: bsmaster.h:952
#define ATA_SE_HANDSHAKE_ERR
Definition: bsmaster.h:421
#define CTRFLAGS_DPC_REQ
Definition: bsmaster.h:1135
BOOLEAN NTAPI AtapiDmaDBPreSync(IN PVOID HwDeviceExtension, PHW_CHANNEL chan, PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:553
#define VM_BOCHS
Definition: bsmaster.h:1906
#define REQ_STATE_DPC_WAIT_BUSY0
Definition: bsmaster.h:964
#define REQ_STATE_DPC_WAIT_DRQ
Definition: bsmaster.h:967
BOOLEAN NTAPI AtapiDmaDBSync(PHW_CHANNEL chan, PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:532
#define REQ_FLAG_DMA_OPERATION
Definition: bsmaster.h:932
#define REQ_FLAG_FORCE_DOWNRATE
Definition: bsmaster.h:931
#define CTRFLAGS_ENABLE_INTR_REQ
Definition: bsmaster.h:1136
#define REQ_STATE_DPC_WAIT_BUSY
Definition: bsmaster.h:966
#define CHECK_INTR_IDLE
Definition: bsmaster.h:1069
#define REQ_STATE_DPC_WAIT_BUSY1
Definition: bsmaster.h:965
#define REQ_STATE_NONE
Definition: bsmaster.h:943
#define REQ_FLAG_FORCE_DOWNRATE_LBA48
Definition: bsmaster.h:937
#define HBAFLAGS_DMA_DISABLED_LBA48
Definition: bsmaster.h:1359
#define VM_QEMU
Definition: bsmaster.h:1905
#define ATA_SE_LINKSEQ_ERR
Definition: bsmaster.h:422
#define REQ_STATE_ATAPI_DO_NOTHING_INTR
Definition: bsmaster.h:954
#define CTRFLAGS_DMA_OPERATION
Definition: bsmaster.h:1133
#define DEV_BSIZE
Definition: bsmaster.h:103
#define ATA_SE_UNKNOWN_FIS
Definition: bsmaster.h:424
#define REQ_STATE_ATAPI_EXPECTING_CMD_INTR
Definition: bsmaster.h:951
BOOLEAN NTAPI AtapiDmaPioSync(PVOID HwDeviceExtension, PSCSI_REQUEST_BLOCK Srb, PUCHAR data, ULONG count)
Definition: id_dma.cpp:467
#define REQ_STATE_PREPARE_TO_NEXT
Definition: bsmaster.h:947
#define ATA_SE_TRANSPORT_ERR
Definition: bsmaster.h:423
#define REQ_STATE_TRANSFER_COMPLETE
Definition: bsmaster.h:971
#define REQ_STATE_DPC_WAIT_DRQ_ERR
Definition: bsmaster.h:969
#define REQ_STATE_QUEUED
Definition: bsmaster.h:944
#define DPC_STATE_ISR
Definition: bsmaster.h:1155
#define REQ_STATE_DPC_WAIT_DRQ0
Definition: bsmaster.h:968
#define REQ_STATE_DPC_INTR_REQ
Definition: bsmaster.h:960
VOID NTAPI AtapiDmaStart(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_dma.cpp:588
#define MAX_RETRIES
Definition: bsmaster.h:72
#define CMD_ACTION_ALL
Definition: bsmaster.h:976
_In_ PSCSI_REQUEST_BLOCK Srb
Definition: cdrom.h:989
#define SCSIOP_MODE_SENSE10
Definition: cdrw_hw.h:946
#define SCSIOP_READ_CAPACITY
Definition: cdrw_hw.h:904
#define SCSIOP_MODE_SENSE
Definition: cdrw_hw.h:896
union _CDB * PCDB
#define SCSI_SENSE_HARDWARE_ERROR
Definition: cdrw_hw.h:1191
struct _MODE_PARAMETER_HEADER * PMODE_PARAMETER_HEADER
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR _In_ UCHAR _In_ UCHAR Lun
Definition: classpnp.h:1315
_In_ ULONG _In_ BOOLEAN _In_ ULONG _In_ UCHAR PathId
Definition: classpnp.h:1313
_In_ PCHAR _In_ ULONG DeviceNumber
Definition: classpnp.h:1230
#define SRB_STATUS_BUS_RESET
Definition: srb.h:353
#define SRB_STATUS_AUTOSENSE_VALID
Definition: srb.h:387
@ CallEnableInterrupts
Definition: srb.h:536
@ CallDisableInterrupts
Definition: srb.h:535
@ NextLuRequest
Definition: srb.h:533
#define KdPrint(x)
Definition: env_spec_w32.h:288
#define KdDump(a, b)
Definition: env_spec_w32.h:312
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
@ NoRetry
Definition: fxpkgpnp.hpp:202
#define IDX_ATAPI_IO1_i_ByteCountHigh
Definition: hwide.h:92
#define IDE_STATUS_MASK
Definition: hwide.h:122
#define IDX_ATAPI_IO1_i_ByteCountLow
Definition: hwide.h:91
#define IDE_STATUS_IDLE
Definition: hwide.h:118
#define IDX_ATAPI_IO1_i_Error
Definition: hwide.h:88
RETTYPE_XXableInterrupts NTAPI AtapiEnableInterrupts__(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4333
VOID NTAPI AtapiCallBack_X(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4007
BOOLEAN NTAPI AtapiResetController__(IN PVOID HwDeviceExtension, IN ULONG PathId, IN UCHAR CompleteType)
Definition: id_ata.cpp:2422
VOID NTAPI AtapiQueueTimerDpc(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN PHW_TIMER HwScsiTimer, IN ULONG MiniportTimerValue)
Definition: id_ata.cpp:1378
BOOLEAN NTAPI AtapiStartIo__(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN BOOLEAN TopLevel)
Definition: id_ata.cpp:9288
ULONG NTAPI AtapiSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
Definition: id_ata.cpp:7377
#define RESET_COMPLETE_CURRENT
Definition: id_ata.cpp:143
VOID NTAPI UniataSnapAtaRegs(IN PHW_CHANNEL chan, IN ULONG DeviceNumber, IN OUT PIDEREGS_EX regs)
Definition: id_ata.cpp:1476
PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:11251
UCHAR DDKFASTAPI AtapiSuckPort2(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:503
VOID NTAPI AtapiHwInitializeChanger(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN PMECHANICAL_STATUS_INFORMATION_HEADER MechanismStatus)
Definition: id_ata.cpp:3667
ULONG NTAPI MapError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:2951
ULONG g_opt_VirtualMachine
Definition: id_ata.cpp:105
RETTYPE_XXableInterrupts NTAPI AtapiInterruptDpc(IN PVOID HwDeviceExtension)
Definition: id_ata.cpp:4295
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4397
VOID UniataExpectChannelInterrupt(IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
Definition: id_ata.cpp:4492
ULONG g_opt_MaxIsrWait
Definition: id_ata.cpp:95
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4457
PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:11207
VOID NTAPI UniataRemoveRequest(IN PHW_CHANNEL chan, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_queue.cpp:265
PHW_CHANNEL NTAPI UniataGetNextChannel(IN PHW_CHANNEL chan)
Definition: id_queue.cpp:376
BOOLEAN NTAPI UniataAhciAbortOperation(IN PHW_CHANNEL chan)
Definition: id_sata.cpp:1765
UCHAR NTAPI UniataAhciEndTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2294
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
struct @5016 regs[]
_In_opt_ WDFREQUEST _In_ ULONG _In_ BOOLEAN _In_ PCDB Cdb
Definition: scratch.h:159
BOOLEAN RDP
Definition: bsmaster.h:1033
ULONG MechStatusRetryCount
Definition: bsmaster.h:1054
LONG CheckIntr
Definition: bsmaster.h:1062
ULONG AhciLastIS
Definition: bsmaster.h:1108
ULONG AhciLastSError
Definition: bsmaster.h:1109
UCHAR DpcState
Definition: bsmaster.h:1030
UCHAR SmartCommand
Definition: bsmaster.h:1039
IDENTIFY_DATA2 IdentifyData
Definition: bsmaster.h:1162
LONGLONG RecoverCount[MAX_RETRIES]
Definition: bsmaster.h:1230
UCHAR MaximumBlockXfer
Definition: bsmaster.h:1168
UCHAR LimitedTransferMode
Definition: bsmaster.h:1172
LONGLONG IoCount
Definition: bsmaster.h:1231
ULONG AtapiReadyWaitDelay
Definition: bsmaster.h:1191
LONGLONG BlockIoCount
Definition: bsmaster.h:1232
UCHAR SenseInfoBufferLength
Definition: srb.h:259
PVOID SenseInfoBuffer
Definition: srb.h:264
UCHAR AdditionalSenseCode
Definition: cdrw_hw.h:1175
UCHAR ErrorCode
Definition: cdrw_hw.h:1164
UCHAR AdditionalSenseCodeQualifier
Definition: cdrw_hw.h:1176
UCHAR Valid
Definition: cdrw_hw.h:1165
struct _IDEREGS_EX * PIDEREGS_EX
#define ATAPI_IR_IO_toHost
Definition: atapi.h:549
#define DFLAGS_LBA_ENABLED
Definition: atapi.h:247
#define ATA_UDMA2
Definition: atapi.h:330
#define ATAPI_TYPE_CDROM
Definition: atapi.h:623
#define DFLAGS_DWORDIO_ENABLED
Definition: atapi.h:248
#define ATAPI_IR_COD_Cmd
Definition: atapi.h:545
#define ATAPI_IR_IO_toDev
Definition: atapi.h:548
ULONG bcount
Definition: bsmaster.h:887
UCHAR retry
Definition: bsmaster.h:889
struct _ATA_REQ::@1159::@1161::@1165::@1168 ahci
ULONG WordsTransfered
Definition: bsmaster.h:886
LONGLONG lba
Definition: bsmaster.h:885
PSCSI_REQUEST_BLOCK Srb
Definition: bsmaster.h:880
PUSHORT DataBuffer
Definition: bsmaster.h:882
ULONG TransferLength
Definition: bsmaster.h:884
PSCSI_REQUEST_BLOCK OriginalSrb
Definition: bsmaster.h:895
UCHAR Flags
Definition: bsmaster.h:892
ULONG WordsLeft
Definition: bsmaster.h:883
Definition: cdrw_hw.h:28
struct _CDB::_CDB6 CDB6

Referenced by AtapiCallBack__(), AtapiEnableInterrupts__(), AtapiInterrupt(), and AtapiInterruptDpc().

◆ AtaPio2Mode()

LONG NTAPI AtaPio2Mode ( LONG  pio)

Definition at line 1205 of file id_ata.cpp.

1206{
1207 switch (pio) {
1208 default: return ATA_PIO;
1209 case 0: return ATA_PIO0;
1210 case 1: return ATA_PIO1;
1211 case 2: return ATA_PIO2;
1212 case 3: return ATA_PIO3;
1213 case 4: return ATA_PIO4;
1214 case 5: return ATA_PIO5;
1215 }
1216} // end AtaPio2Mode()
#define ATA_PIO
Definition: hwide.h:161
#define ATA_PIO1
Definition: atapi.h:310
#define ATA_PIO5
Definition: atapi.h:314
#define ATA_PIO2
Definition: atapi.h:311
#define ATA_PIO3
Definition: atapi.h:312

◆ AtaPioMode()

LONG NTAPI AtaPioMode ( PIDENTIFY_DATA2  ident)

Definition at line 1220 of file id_ata.cpp.

1221{
1222 if (ident->PioTimingsValid) {
1223 if (ident->AdvancedPIOModes & AdvancedPIOModes_5)
1224 return 5;
1225 if (ident->AdvancedPIOModes & AdvancedPIOModes_4)
1226 return 4;
1227 if (ident->AdvancedPIOModes & AdvancedPIOModes_3)
1228 return 3;
1229 }
1230 if (ident->PioCycleTimingMode == 2)
1231 return 2;
1232 if (ident->PioCycleTimingMode == 1)
1233 return 1;
1234 if (ident->PioCycleTimingMode == 0)
1235 return 0;
1236 return IOMODE_NOT_SPECIFIED;
1237} // end AtaPioMode()
#define IOMODE_NOT_SPECIFIED
Definition: atapi.h:1484

Referenced by AtapiDmaInit__(), AtapiDmaReinit(), and AtaSetTransferMode().

◆ AtapiParseArgumentString()

ULONG NTAPI AtapiParseArgumentString ( IN PCCH  String,
IN PCCH  KeyWord 
)

Definition at line 3705 of file id_ata.cpp.

3709{
3710 PCCH cptr;
3711 PCCH kptr;
3712 ULONG value;
3713 ULONG stringLength = 0;
3714 ULONG keyWordLength = 0;
3715 ULONG index;
3716
3717 if (!String) {
3718 return 0;
3719 }
3720 if (!KeyWord) {
3721 return 0;
3722 }
3723
3724 // Calculate the string length and lower case all characters.
3725 cptr = String;
3726 while (*cptr++) {
3727 stringLength++;
3728 }
3729
3730 // Calculate the keyword length.
3731 kptr = KeyWord;
3732 while (*kptr++) {
3733 keyWordLength++;
3734 }
3735
3736 if (keyWordLength > stringLength) {
3737
3738 // Can't possibly have a match.
3739 return 0;
3740 }
3741
3742 // Now setup and start the compare.
3743 cptr = String;
3744
3745ContinueSearch:
3746
3747 // The input string may start with white space. Skip it.
3748 while (*cptr == ' ' || *cptr == '\t') {
3749 cptr++;
3750 }
3751
3752 if (*cptr == '\0') {
3753 // end of string.
3754 return 0;
3755 }
3756
3757 kptr = KeyWord;
3758 while ((*cptr == *kptr) ||
3759 (*cptr >= 'A' && *cptr <= 'Z' && *cptr + ('a' - 'A') == *kptr) ||
3760 (*cptr >= 'a' && *cptr <= 'z' && *cptr - ('a' - 'A') == *kptr)) {
3761 cptr++;
3762 kptr++;
3763
3764 if (*cptr == '\0') {
3765 // end of string
3766 return 0;
3767 }
3768 }
3769
3770 if (*kptr == '\0') {
3771
3772 // May have a match backup and check for blank or equals.
3773 while (*cptr == ' ' || *cptr == '\t') {
3774 cptr++;
3775 }
3776
3777 // Found a match. Make sure there is an equals.
3778 if (*cptr != '=') {
3779
3780 // Not a match so move to the next semicolon.
3781 while (*cptr) {
3782 if (*cptr++ == ';') {
3783 goto ContinueSearch;
3784 }
3785 }
3786 return 0;
3787 }
3788 // Skip the equals sign.
3789 cptr++;
3790
3791 // Skip white space.
3792 while ((*cptr == ' ') || (*cptr == '\t')) {
3793 cptr++;
3794 }
3795
3796 if (*cptr == '\0') {
3797 // Early end of string, return not found
3798 return 0;
3799 }
3800
3801 if (*cptr == ';') {
3802 // This isn't it either.
3803 cptr++;
3804 goto ContinueSearch;
3805 }
3806
3807 value = 0;
3808 if ((*cptr == '0') && ((*(cptr + 1) == 'x') || (*(cptr + 1) == 'X'))) {
3809 // Value is in Hex. Skip the "0x"
3810 cptr += 2;
3811 for (index = 0; *(cptr + index); index++) {
3812
3813 if (*(cptr + index) == ' ' ||
3814 *(cptr + index) == '\t' ||
3815 *(cptr + index) == ';') {
3816 break;
3817 }
3818
3819 if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
3820 value = (16 * value) + (*(cptr + index) - '0');
3821 } else {
3822 if ((*(cptr + index) >= 'a') && (*(cptr + index) <= 'f')) {
3823 value = (16 * value) + (*(cptr + index) - 'a' + 10);
3824 } else if ((*(cptr + index) >= 'A') && (*(cptr + index) <= 'F')) {
3825 value = (16 * value) + (*(cptr + index) - 'A' + 10);
3826 } else {
3827 // Syntax error, return not found.
3828 return 0;
3829 }
3830 }
3831 }
3832 } else {
3833
3834 // Value is in Decimal.
3835 for (index = 0; *(cptr + index); index++) {
3836
3837 if (*(cptr + index) == ' ' ||
3838 *(cptr + index) == '\t' ||
3839 *(cptr + index) == ';') {
3840 break;
3841 }
3842
3843 if ((*(cptr + index) >= '0') && (*(cptr + index) <= '9')) {
3844 value = (10 * value) + (*(cptr + index) - '0');
3845 } else {
3846
3847 // Syntax error return not found.
3848 return 0;
3849 }
3850 }
3851 }
3852
3853 return value;
3854 } else {
3855
3856 // Not a match check for ';' to continue search.
3857 while (*cptr) {
3858 if (*cptr++ == ';') {
3859 goto ContinueSearch;
3860 }
3861 }
3862
3863 return 0;
3864 }
3865} // end AtapiParseArgumentString()_
#define index(s, c)
Definition: various.h:29
GLuint index
Definition: glext.h:6031
CONST CHAR * PCCH
Definition: ntbasedef.h:392
Definition: pdh_main.c:94
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433

◆ AtapiReadArgumentString()

ULONG NTAPI AtapiReadArgumentString ( IN PVOID  HwDeviceExtension,
IN PVOID  Context,
IN PVOID  BusInformation,
IN PCHAR  ArgumentString,
IN OUT PPORT_CONFIGURATION_INFORMATION  ConfigInfo,
OUT PBOOLEAN  Again 
)

Definition at line 2754 of file id_probe.cpp.

2762{
2763#ifndef __REACTOS__
2764 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2765#endif
2766
2767 if (AtapiParseArgumentString(ArgumentString, "dump") == 1) {
2769 "AtapiReadArgumentString: Crash dump\n"));
2770 //atapiOnly = FALSE;
2771 g_Dump = TRUE;
2772 }
2773 return(SP_RETURN_NOT_FOUND);
2774} // end AtapiReadArgumentString()

Referenced by DriverEntry().

◆ AtapiRegCheckDevValue()

ULONG NTAPI AtapiRegCheckDevValue ( IN PVOID  HwDeviceExtension,
IN ULONG  chan,
IN ULONG  dev,
IN PCWSTR  Name,
IN ULONG  Default 
)

Definition at line 11365 of file id_ata.cpp.

11372{
11373 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11374// WCHAR name0[11];
11375// WCHAR name1[11+4+5];
11376// WCHAR name2[11+4+4+10];
11377// WCHAR name3[11+4+4+5+20];
11378// WCHAR name3[11+4+4+5+20+1];
11379 WCHAR namex[160];
11380
11381 WCHAR namev[16];
11382 WCHAR named[16];
11383 WCHAR names[20];
11384
11385 IN ULONG VendorID;
11388 IN ULONG HwFlags;
11389
11390 ULONG val = Default;
11391
11392 KdPrint(( " Parameter %ws\n", Name));
11393
11394 if(deviceExtension) {
11395 VendorID = deviceExtension->DevID & 0xffff;
11396 DeviceID = (deviceExtension->DevID >> 16) & 0xffff;
11397 SlotNumber = deviceExtension->slotNumber;
11398 HwFlags = deviceExtension->HwFlags;
11399 } else {
11400 VendorID = 0xffff;
11401 DeviceID = 0xffff;
11402 SlotNumber = 0xffffffff;
11403 HwFlags = 0;
11404 }
11405
11407 HwDeviceExtension, L"Parameters", chan, dev, Name, val);
11408
11409 if(deviceExtension) {
11410
11411 if(HwFlags & UNIATA_SATA) {
11412 swprintf(namev, L"\\SATA");
11413 swprintf(namex, L"Parameters%s", namev);
11415 HwDeviceExtension, namex, chan, dev, Name, val);
11416 }
11417 if(HwFlags & UNIATA_AHCI) {
11418 swprintf(namev, L"\\AHCI");
11419 swprintf(namex, L"Parameters%s", namev);
11421 HwDeviceExtension, namex, chan, dev, Name, val);
11422 }
11423 if(!(HwFlags & (UNIATA_SATA | UNIATA_AHCI))) {
11424 swprintf(namev, L"\\PATA");
11425 swprintf(namex, L"Parameters%s", namev);
11427 HwDeviceExtension, namex, chan, dev, Name, val);
11428 }
11429
11430 if(deviceExtension->AdapterInterfaceType == PCIBus) {
11431 // PCI
11432 swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex);
11433 swprintf(namex, L"Parameters%s", namev);
11435 HwDeviceExtension, namex, chan, dev, Name, val);
11436
11437
11438 swprintf(namev, L"\\Ven_%4.4x", VendorID);
11439 swprintf(named, L"\\Dev_%4.4x", DeviceID);
11440 swprintf(names, L"\\Slot_%8.8x", SlotNumber);
11441
11442 swprintf(namex, L"Parameters%s", namev);
11444 HwDeviceExtension, namex, chan, dev, Name, val);
11445
11446 swprintf(namex, L"Parameters%s%s", namev, named);
11448 HwDeviceExtension, namex, chan, dev, Name, val);
11449
11450 swprintf(namex, L"Parameters%s%s%s", namev, named, names);
11452 HwDeviceExtension, namex, chan, dev, Name, val);
11453 } else
11454 if(deviceExtension->AdapterInterfaceType == Isa) {
11455 // Isa
11456 swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen);
11457 swprintf(namex, L"Parameters%s", namev);
11459 HwDeviceExtension, namex, chan, dev, Name, val);
11460
11461 swprintf(namev, L"\\ISA_%d", deviceExtension->DevIndex);
11462 swprintf(namex, L"Parameters%s", namev);
11464 HwDeviceExtension, namex, chan, dev, Name, val);
11465
11466 } else
11467 if(deviceExtension->AdapterInterfaceType == MicroChannel) {
11468 // MicroChannel
11469 swprintf(namev, L"\\IDE_%d", deviceExtension->DevIndex+BMListLen+IsaCount);
11470 swprintf(namex, L"Parameters%s", namev);
11472 HwDeviceExtension, namex, chan, dev, Name, val);
11473
11474 swprintf(namev, L"\\MCA_%d", deviceExtension->DevIndex);
11475 swprintf(namex, L"Parameters%s", namev);
11477 HwDeviceExtension, namex, chan, dev, Name, val);
11478
11479 }
11480 }
11481
11482 KdPrint(( " Parameter %ws = %#x\n", Name, val));
11483 return val;
11484
11485} // end AtapiRegCheckDevValue()
ULONG BMListLen
Definition: id_probe.cpp:54
ULONG IsaCount
Definition: id_probe.cpp:55
#define swprintf
Definition: precomp.h:40
GLuint GLuint * names
Definition: glext.h:11545
GLuint GLfloat * val
Definition: glext.h:7180
@ PCIBus
Definition: hwresource.cpp:142
ULONG NTAPI AtapiRegCheckDevLunValue(IN PVOID HwDeviceExtension, IN PCWCH NamePrefix, IN ULONG chan, IN ULONG dev, IN PCWSTR Name, IN ULONG Default)
Definition: id_ata.cpp:11295
@ Default
Definition: stdole2.idl:392
#define IN
Definition: typedefs.h:39
_Must_inspect_result_ _In_ PWDFDEVICE_INIT _In_ PCUNICODE_STRING DeviceID
Definition: wdfpdo.h:278
_In_ WDFIORESREQLIST _In_ ULONG SlotNumber
Definition: wdfresource.h:68
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by AtapiFindIsaController(), AtapiReadChipConfig(), DriverEntry(), UniataAhciDetect(), UniAtaAhciValidateVersion(), UniataChipDetect(), UniataChipDetectChannels(), UniataEnumBusMasterController__(), UniataFindBusMasterController(), and UniAtaReadLunConfig().

◆ AtapiRegCheckParameterValue()

ULONG NTAPI AtapiRegCheckParameterValue ( IN PVOID  HwDeviceExtension,
IN PCWSTR  PathSuffix,
IN PCWSTR  Name,
IN ULONG  Default 
)

Definition at line 11509 of file id_ata.cpp.

11515{
11516#define ITEMS_TO_QUERY 2 // always 1 greater than what is searched
11517
11518// PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11520 LONG zero = Default;
11521
11523
11524// LONG tmp = 0;
11525 LONG doRun = Default;
11526
11528
11529 UNICODE_STRING paramPath;
11530
11531 if(g_Dump) {
11532 goto failed;
11533 }
11534
11535 // <SavedRegPath><PathSuffix> -> <Name>
11536// KdPrint(( "AtapiCheckRegValue: %ws -> %ws\n", PathSuffix, Name));
11537// KdPrint(( "AtapiCheckRegValue: RegistryPath %ws\n", RegistryPath->Buffer));
11538
11539 paramPath.Length = 0;
11540 paramPath.MaximumLength = RegistryPath->Length +
11541 (wcslen(PathSuffix)+2)*sizeof(WCHAR);
11542 paramPath.Buffer = (PWCHAR)ExAllocatePool(NonPagedPool, paramPath.MaximumLength);
11543 if(!paramPath.Buffer) {
11544 KdPrint(("AtapiCheckRegValue: couldn't allocate paramPath\n"));
11545 return Default;
11546 }
11547
11548 RtlZeroMemory(paramPath.Buffer, paramPath.MaximumLength);
11549 RtlAppendUnicodeToString(&paramPath, RegistryPath->Buffer);
11550 RtlAppendUnicodeToString(&paramPath, L"\\");
11551 RtlAppendUnicodeToString(&paramPath, REGRTL_STR_PTYPE PathSuffix);
11552
11553 // Check for the Xxx value.
11555
11556 parameters[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
11557 parameters[0].Name = REGRTL_STR_PTYPE Name;
11558 parameters[0].EntryContext = &doRun;
11559 parameters[0].DefaultType = REG_DWORD;
11560 parameters[0].DefaultData = &zero;
11561 parameters[0].DefaultLength = sizeof(ULONG);
11562
11563 status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE /*| RTL_REGISTRY_OPTIONAL*/,
11564 paramPath.Buffer, parameters, NULL, NULL);
11565 if(NT_SUCCESS(status)) {
11566 KdPrint(( "AtapiCheckRegValue: %ws -> %ws is %#x\n", PathSuffix, Name, doRun));
11567 }
11568
11569 ExFreePool(paramPath.Buffer);
11570
11571 if(!NT_SUCCESS(status)) {
11572failed:
11573 doRun = Default;
11574 }
11575
11576 return doRun;
11577
11578#undef ITEMS_TO_QUERY
11579
11580} // end AtapiRegCheckParameterValue()
struct NameRec_ * Name
Definition: cdprocs.h:460
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define REGRTL_STR_PTYPE
Definition: config.h:105
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
#define ExFreePool(addr)
Definition: env_spec_w32.h:352
#define NonPagedPool
Definition: env_spec_w32.h:307
#define ExAllocatePool(type, size)
Definition: fbtusb.h:44
UNICODE_STRING SavedRegPath
Definition: id_ata.cpp:69
BOOLEAN g_Dump
Definition: id_ata.cpp:108
#define ITEMS_TO_QUERY
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
#define RTL_REGISTRY_ABSOLUTE
Definition: nt_native.h:161
#define RTL_QUERY_REGISTRY_DIRECT
Definition: nt_native.h:144
long LONG
Definition: pedump.c:60
#define REG_DWORD
Definition: sdbapi.c:596
int zero
Definition: sehframes.cpp:29
USHORT MaximumLength
Definition: env_spec_w32.h:370
uint16_t * PWCHAR
Definition: typedefs.h:56
_Must_inspect_result_ _In_ PDRIVER_OBJECT _In_ PCUNICODE_STRING RegistryPath
Definition: wdfdriver.h:215

Referenced by AtapiRegCheckDevLunValue(), and DriverEntry().

◆ AtapiResetController()

BOOLEAN NTAPI AtapiResetController ( IN PVOID  HwDeviceExtension,
IN ULONG  PathId 
)

Definition at line 733 of file atapi.c.

755{
756 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
757 ULONG numberChannels = deviceExtension->NumberChannels;
758 PIDE_REGISTERS_1 baseIoAddress1;
759 PIDE_REGISTERS_2 baseIoAddress2;
761 ULONG i,j;
762 UCHAR statusByte;
763
764 DebugPrint((2,"AtapiResetController: Reset IDE\n"));
765
766 //
767 // Check and see if we are processing an internal srb
768 //
769 if (deviceExtension->OriginalSrb) {
770 deviceExtension->CurrentSrb = deviceExtension->OriginalSrb;
771 deviceExtension->OriginalSrb = NULL;
772 }
773
774 //
775 // Check if request is in progress.
776 //
777
778 if (deviceExtension->CurrentSrb) {
779
780 //
781 // Complete outstanding request with SRB_STATUS_BUS_RESET.
782 //
783
784 ScsiPortCompleteRequest(deviceExtension,
785 deviceExtension->CurrentSrb->PathId,
786 deviceExtension->CurrentSrb->TargetId,
787 deviceExtension->CurrentSrb->Lun,
789
790 //
791 // Clear request tracking fields.
792 //
793
794 deviceExtension->CurrentSrb = NULL;
795 deviceExtension->WordsLeft = 0;
796 deviceExtension->DataBuffer = NULL;
797
798 //
799 // Indicate ready for next request.
800 //
801
803 deviceExtension,
804 NULL);
805 }
806
807 //
808 // Clear expecting interrupt flag.
809 //
810
811 deviceExtension->ExpectingInterrupt = FALSE;
812 deviceExtension->RDP = FALSE;
813
814 for (j = 0; j < numberChannels; j++) {
815
816 baseIoAddress1 = deviceExtension->BaseIoAddress1[j];
817 baseIoAddress2 = deviceExtension->BaseIoAddress2[j];
818
819 //
820 // Do special processing for ATAPI and IDE disk devices.
821 //
822
823 for (i = 0; i < 2; i++) {
824
825 //
826 // Check if device present.
827 //
828
829 if (deviceExtension->DeviceFlags[i + (j * 2)] & DFLAGS_DEVICE_PRESENT) {
830
831 //
832 // Check for ATAPI disk.
833 //
834
835 if (deviceExtension->DeviceFlags[i + (j * 2)] & DFLAGS_ATAPI_DEVICE) {
836
837 //
838 // Issue soft reset and issue identify.
839 //
840
841 GetStatus(baseIoAddress2,statusByte);
842 DebugPrint((1,
843 "AtapiResetController: Status before Atapi reset (%x).\n",
844 statusByte));
845
846 AtapiSoftReset(baseIoAddress1,i);
847
848 GetStatus(baseIoAddress2,statusByte);
849
850 if (statusByte == 0x0) {
851
852 IssueIdentify(HwDeviceExtension,
853 i,
854 j,
856 } else {
857
858 DebugPrint((1,
859 "AtapiResetController: Status after soft reset %x\n",
860 statusByte));
861 }
862
863 } else {
864
865 //
866 // Write IDE reset controller bits.
867 //
868
869 IdeHardReset(baseIoAddress2,result);
870
871 if (!result) {
872 return FALSE;
873 }
874
875 //
876 // Set disk geometry parameters.
877 //
878
879 if (!SetDriveParameters(HwDeviceExtension,
880 i,
881 j)) {
882
883 DebugPrint((1,
884 "AtapiResetController: SetDriveParameters failed\n"));
885 }
886 }
887 }
888 }
889 }
890
891 //
892 // Call the HwInitialize routine to setup multi-block.
893 //
894
895 AtapiHwInitialize(HwDeviceExtension);
896
897 return TRUE;
898
899} // end AtapiResetController()
#define IDE_COMMAND_ATAPI_IDENTIFY
Definition: atapi.h:110
#define IdeHardReset(BaseIoAddress, result)
Definition: atapi.h:432
BOOLEAN NTAPI AtapiHwInitialize(IN PVOID HwDeviceExtension)
Definition: atapi.c:1282
BOOLEAN NTAPI SetDriveParameters(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel)
Definition: atapi.c:636
BOOLEAN NTAPI IssueIdentify(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG Channel, IN UCHAR Command)
Definition: atapi.c:251
VOID NTAPI ScsiPortCompleteRequest(IN PVOID HwDeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN UCHAR SrbStatus)
Definition: scsiport.c:507
GLuint64EXT * result
Definition: glext.h:11304

Referenced by AtapiAdapterControl(), AtapiInterrupt(), AtapiStartIo(), and DriverEntry().

◆ AtapiSendCommand()

ULONG NTAPI AtapiSendCommand ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb,
IN ULONG  CmdAction 
)

Definition at line 7377 of file id_ata.cpp.

7382{
7383 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
7384 UCHAR lChannel = GET_CHANNEL(Srb);
7385 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
7386 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
7387 PHW_LU_EXTENSION LunExt;
7388 //ULONG ldev = GET_LDEV(Srb);
7390 ULONG flags;
7391 UCHAR statusByte,statusByte0,byteCountLow,byteCountHigh;
7392 UCHAR interruptReason;
7393 BOOLEAN use_dma = FALSE;
7394 BOOLEAN dma_reinited = FALSE;
7395 BOOLEAN retried = FALSE;
7396 ULONG fis_size, i;
7397 UCHAR FeatureReg=0;
7398
7399 LunExt = chan->lun[DeviceNumber];
7400
7401 KdPrint3((PRINT_PREFIX "AtapiSendCommand: req state %#x, Action %x\n", AtaReq->ReqState, CmdAction));
7404
7405
7406#ifdef UNIATA_DUMP_ATAPI
7407 if(CmdAction & CMD_ACTION_PREPARE) {
7408 UCHAR ScsiCommand;
7409 PCDB Cdb;
7410 PCHAR CdbData;
7411 PCHAR ModeSelectData;
7412 ULONG CdbDataLen;
7413
7414 Cdb = (PCDB)(Srb->Cdb);
7415 ScsiCommand = Cdb->CDB6.OperationCode;
7416 CdbData = (PCHAR)(Srb->DataBuffer);
7417 CdbDataLen = Srb->DataTransferLength;
7418
7419 if(CdbDataLen > 0x1000) {
7420 CdbDataLen = 0x1000;
7421 }
7422
7423 KdPrint(("--\n"));
7424 KdPrint2(("DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
7425 KdPrint2(("P:T:D=%d:%d:%d\n",
7426 Srb->PathId,
7427 Srb->TargetId,
7428 Srb->Lun));
7429 KdPrint(("SCSI Command %2.2x\n", ScsiCommand));
7430 KdDump(Cdb, 16);
7431
7432 if(ScsiCommand == SCSIOP_WRITE_CD) {
7433 KdPrint(("Write10, LBA %2.2x%2.2x%2.2x%2.2x\n",
7434 Cdb->WRITE_CD.LBA[0],
7435 Cdb->WRITE_CD.LBA[1],
7436 Cdb->WRITE_CD.LBA[2],
7437 Cdb->WRITE_CD.LBA[3]
7438 ));
7439 } else
7440 if(ScsiCommand == SCSIOP_WRITE12) {
7441 KdPrint(("Write12, LBA %2.2x%2.2x%2.2x%2.2x\n",
7442 Cdb->CDB12READWRITE.LBA[0],
7443 Cdb->CDB12READWRITE.LBA[1],
7444 Cdb->CDB12READWRITE.LBA[2],
7445 Cdb->CDB12READWRITE.LBA[3]
7446 ));
7447 } else
7448 if(ScsiCommand == SCSIOP_WRITE16) {
7449 KdPrint(("Write16, LBA %2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x%2.2x\n",
7450 Cdb->CDB16READWRITE.LBA[0],
7451 Cdb->CDB16READWRITE.LBA[1],
7452 Cdb->CDB16READWRITE.LBA[2],
7453 Cdb->CDB16READWRITE.LBA[3],
7454 Cdb->CDB16READWRITE.LBA[4],
7455 Cdb->CDB16READWRITE.LBA[5],
7456 Cdb->CDB16READWRITE.LBA[6],
7457 Cdb->CDB16READWRITE.LBA[7]
7458 ));
7459 } else
7460 if(ScsiCommand == SCSIOP_MODE_SELECT) {
7461 KdPrint(("ModeSelect 6\n"));
7463 ModeSelectData = CdbData+4;
7464 KdDump(CdbData, CdbDataLen);
7465 } else
7466 if(ScsiCommand == SCSIOP_MODE_SELECT10) {
7467 KdPrint(("ModeSelect 10\n"));
7469 ModeSelectData = CdbData+8;
7470 KdDump(CdbData, CdbDataLen);
7471 } else {
7473 KdPrint(("Send buffer to device:\n"));
7474 KdDump(CdbData, CdbDataLen);
7475 }
7476 }
7477 KdPrint(("--\n"));
7478 }
7479#endif //UNIATA_DUMP_ATAPI
7480
7481
7482 if(CmdAction == CMD_ACTION_PREPARE) {
7483 KdPrint2((PRINT_PREFIX "AtapiSendCommand: CMD_ACTION_PREPARE, Cdb %x\n", &(Srb->Cdb)));
7484
7485 switch (Srb->Cdb[0]) {
7486 case SCSIOP_RECEIVE:
7487 case SCSIOP_SEND:
7488 case SCSIOP_READ:
7489 case SCSIOP_WRITE:
7490 case SCSIOP_READ12:
7491 case SCSIOP_WRITE12:
7492 case SCSIOP_READ16:
7493 case SCSIOP_WRITE16:
7494 // all right
7495 break;
7496 case SCSIOP_READ_CD:
7497 case SCSIOP_READ_CD_MSF:
7498 if(deviceExtension->opt_AtapiDmaRawRead) {
7499 // all right
7500 break;
7501 }
7502 /* FALL THROUGH */
7503 default:
7504 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_BUSY\n"));
7505 return SRB_STATUS_BUSY;
7506 }
7507 //
7508#ifdef UNIATA_INIT_CHANGERS
7509 if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) &&
7510 !AtaReq->OriginalSrb) {
7511 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_BUSY (2)\n"));
7512 return SRB_STATUS_BUSY;
7513 }
7514#endif // UNIATA_INIT_CHANGERS
7515 }
7516
7517#ifndef UNIATA_CORE
7518 // standard atapi.sys claims:
7519
7520 // We need to know how many platters our atapi cd-rom device might have.
7521 // Before anyone tries to send a srb to our target for the first time,
7522 // we must "secretly" send down a separate mechanism status srb in order to
7523 // initialize our device extension changer data. That's how we know how
7524 // many platters our target has.
7525
7526 // BUT!
7527 // some devices freeze (sometimes) forever on this command
7528 // Let CD-ROM driver send this command itself, if it find it necessary
7529 // We shall just parse output (if any)
7530
7531#ifdef UNIATA_INIT_CHANGERS
7532 if (!(LunExt->DeviceFlags & DFLAGS_CHANGER_INITED) &&
7533 !AtaReq->OriginalSrb) {
7534
7535 ULONG srbStatus;
7536
7537 KdPrint3((PRINT_PREFIX "AtapiSendCommand: BuildMechanismStatusSrb()\n"));
7538 // Set this flag now. If the device hangs on the mech. status
7539 // command, we will not have the chance to set it.
7541
7542 chan->MechStatusRetryCount = 3;
7543 AtaReq->OriginalSrb = Srb;
7544 AtaReq->Srb = BuildMechanismStatusSrb (
7545 HwDeviceExtension,
7546 Srb);
7547
7548 KdPrint3((PRINT_PREFIX "AtapiSendCommand: AtapiSendCommand recursive\n"));
7549 srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL);
7550 if (srbStatus == SRB_STATUS_PENDING) {
7551 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SRB_STATUS_PENDING (2)\n"));
7552 return srbStatus;
7553 } else {
7554
7555 // failed! Get the sense key and maybe try again
7556 AtaReq->Srb = BuildRequestSenseSrb ( HwDeviceExtension,
7557 AtaReq->OriginalSrb);
7558
7559 srbStatus = AtapiSendCommand(HwDeviceExtension, AtaReq->Srb, CMD_ACTION_ALL);
7560
7561 KdPrint3((PRINT_PREFIX "AtapiSendCommand: chan->ExpectingInterrupt %d (1)\n", chan->ExpectingInterrupt));
7562
7563 if (srbStatus == SRB_STATUS_PENDING) {
7564 KdPrint2((PRINT_PREFIX "AtapiSendCommand: send orig SRB_STATUS_PENDING (2.1)\n"));
7565 return srbStatus;
7566 }
7567
7568 // failed again ? should not get here
7569 AtaReq->Srb = AtaReq->OriginalSrb;
7570 AtaReq->OriginalSrb = NULL;
7571 // fall out
7572 }
7573 }
7574#endif // UNIATA_INIT_CHANGERS
7575#endif //UNIATA_CORE
7576
7577 if((CmdAction & CMD_ACTION_PREPARE) &&
7579
7580 KdPrint2((PRINT_PREFIX "AtapiSendCommand: prepare..., ATAPI CMD %x (Cdb %x)\n", Srb->Cdb[0], &(Srb->Cdb)));
7581
7582 if(!LunExt->IdentifyData.AtapiCmdSize &&
7583 (Srb->CdbLength > 12)) {
7584 KdPrint2((PRINT_PREFIX "Cdb16 not supported\n"));
7586 }
7587
7588 // Set data buffer pointer and words left.
7589 AtaReq->DataBuffer = (PUSHORT)Srb->DataBuffer;
7590 AtaReq->WordsLeft = Srb->DataTransferLength / 2;
7592 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7593 // reset this to force PRD init. May be already setup by recursive SRB
7594 AtaReq->dma_entries = 0;
7595
7596 // check if reorderable
7597 switch(Srb->Cdb[0]) {
7598 case SCSIOP_READ16:
7599 case SCSIOP_WRITE16:
7600
7601 MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB16READWRITE.NumOfBlocks);
7602 MOV_QD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB16READWRITE.LBA);
7603 goto GetLba2;
7604
7605 case SCSIOP_READ12:
7606 case SCSIOP_WRITE12:
7607
7608 MOV_DD_SWP(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB12READWRITE.NumOfBlocks);
7609 goto GetLba;
7610
7611 case SCSIOP_READ:
7612 case SCSIOP_WRITE:
7613
7614 MOV_SWP_DW2DD(AtaReq->bcount, ((PCDB)Srb->Cdb)->CDB10.TransferBlocks);
7615GetLba:
7616 MOV_DD_SWP(AtaReq->lba, ((PCDB)Srb->Cdb)->CDB10.LBA);
7617GetLba2:
7619 AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
7620 AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
7621 Srb->Cdb[0] == SCSIOP_WRITE12 ||
7622 Srb->Cdb[0] == SCSIOP_WRITE16) ?
7624 break;
7625 default:
7626 AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
7627 if(!AtaReq->TransferLength) {
7628 KdPrint((" assume 0-transfer\n"));
7629 } else
7631 KdPrint((" assume OUT\n"));
7632 AtaReq->Flags |= REQ_FLAG_WRITE;
7633 } else
7635 KdPrint((" assume IN\n"));
7636 AtaReq->Flags |= REQ_FLAG_READ;
7637 }
7638 break;
7639 }
7640
7641 // check if DMA read/write
7642 if(g_opt_AtapiNoDma) {
7643 KdPrint2((PRINT_PREFIX "AtapiSendCommand: CTRFLAGS_DMA_BEFORE_R => no dma\n"));
7644 use_dma = FALSE;
7645 } else
7646 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7647 KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (ahci)\n"));
7648 use_dma = TRUE;
7649 goto setup_dma;
7650 } else
7651/* if((deviceExtension->HwFlags & UNIATA_SATA) && (LunExt->OrigTransferMode >= ATA_DMA)) {
7652 KdPrint2((PRINT_PREFIX "AtapiSendCommand: force use dma (sata)\n"));
7653 use_dma = TRUE;
7654 goto setup_dma;
7655 } else*/
7656 if(Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) {
7657 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE, no DMA setup\n"));
7658 } else
7659 if(AtaReq->TransferLength && !(AtaReq->TransferLength & 0x0f)) {
7660 KdPrint2((PRINT_PREFIX "AtapiSendCommand: try DMA setup\n"));
7661 // try use DMA if TransferLength is 16-byte aligned
7662 switch(Srb->Cdb[0]) {
7663 case SCSIOP_WRITE:
7664 case SCSIOP_WRITE12:
7665 case SCSIOP_WRITE16:
7666 case SCSIOP_SEND:
7668 break;
7669 /* FALLTHROUGH */
7670 case SCSIOP_RECEIVE:
7671 case SCSIOP_READ:
7672 case SCSIOP_READ12:
7673 case SCSIOP_READ16:
7674
7675 if(deviceExtension->opt_AtapiDmaReadWrite) {
7676call_dma_setup:
7677 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7678 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (ahci)\n"));
7679 use_dma = TRUE;
7680 } else
7681 if(AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7682 (PUCHAR)(AtaReq->DataBuffer),
7684 /*((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1))*/
7685 )) {
7686 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma\n"));
7687 use_dma = TRUE;
7688 }
7689 }
7690 break;
7691 case SCSIOP_READ_CD:
7692 case SCSIOP_READ_CD_MSF:
7693 if(deviceExtension->opt_AtapiDmaRawRead)
7694 goto call_dma_setup;
7695 break;
7696 default:
7697
7698 if(deviceExtension->opt_AtapiDmaControlCmd) {
7700 // read operation
7701 use_dma = TRUE;
7702 } else {
7703 // write operation
7704 if(chan->ChannelCtrlFlags & CTRFLAGS_DMA_RO) {
7705 KdPrint2((PRINT_PREFIX "dma RO\n"));
7706 use_dma = FALSE;
7707 } else {
7708 use_dma = TRUE;
7709 }
7710 }
7711 }
7712 break;
7713 }
7714 // try setup DMA
7715setup_dma:
7716 if(use_dma) {
7717 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7718 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (ahci)\n"));
7719 //use_dma = TRUE;
7720 } else
7721 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7722 (PUCHAR)(AtaReq->DataBuffer),
7724 KdPrint2((PRINT_PREFIX "AtapiSendCommand: no dma\n"));
7725 use_dma = FALSE;
7726 } else {
7727 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma\n"));
7728 }
7729 }
7730 } else {
7731 KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero/unaligned transfer %x, no DMA setup\n", AtaReq->TransferLength));
7732 }
7733
7734
7735 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7736
7737 UniataAhciSetupCmdPtr(AtaReq);
7738
7739 if(!Srb->DataTransferLength) {
7740 KdPrint2((PRINT_PREFIX "zero-transfer\n"));
7741 use_dma = FALSE;
7742 } else
7743 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
7744 (PUCHAR)(AtaReq->DataBuffer),
7746 KdPrint2((PRINT_PREFIX "AtapiSendCommand: no AHCI dma!\n"));
7747 return SRB_STATUS_ERROR;
7748 }
7749 if(!use_dma) {
7750 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7751 } else {
7752 FeatureReg |= ATA_F_DMA;
7753 if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) {
7755 KdPrint2((PRINT_PREFIX "Set DMADir.\n"));
7756 FeatureReg |= ATA_F_DMAREAD;
7757 }
7758 }
7759 }
7760
7761 KdPrint2((PRINT_PREFIX "AtapiSendCommand: setup AHCI FIS\n"));
7762 // this is done in UniataAhciSetupFIS_H2D()
7763 //RtlZeroMemory(&(AtaReq->ahci.ahci_cmd_ptr->cfis), sizeof(AtaReq->ahci_cmd0.cfis));
7764 RtlCopyMemory(&(AtaReq->ahci.ahci_cmd_ptr->acmd), Srb->Cdb, Srb->CdbLength);
7765
7766 fis_size = UniataAhciSetupFIS_H2D(deviceExtension, DeviceNumber, lChannel,
7767 &(AtaReq->ahci.ahci_cmd_ptr->cfis[0]),
7768 IDE_COMMAND_ATAPI_PACKET /* command */,
7769 0 /* lba */,
7770 (Srb->DataTransferLength >= 0x10000) ? (USHORT)(0xffff) : (USHORT)(Srb->DataTransferLength),
7771 FeatureReg/* feature */
7772 );
7773
7774 if(!fis_size) {
7775 KdPrint3((PRINT_PREFIX "AtapiSendCommand: AHCI !FIS\n"));
7776 return SRB_STATUS_ERROR;
7777 }
7778
7779 AtaReq->ahci.io_cmd_flags = UniAtaAhciAdjustIoFlags(0,
7782 fis_size, DeviceNumber);
7783
7784 KdPrint2((PRINT_PREFIX "AtapiSendCommand ahci io flags %x: \n", AtaReq->ahci.io_cmd_flags));
7785 }
7786
7787 } else {
7788 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
7789 // if this is queued request, reinit DMA and check
7790 // if DMA mode is still available
7791 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit() (1)\n"));
7792 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7793 if (/*EnableDma &&*/
7794 (LunExt->TransferMode >= ATA_DMA)) {
7795 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use dma (2)\n"));
7796 use_dma = TRUE;
7797 } else {
7798 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7799 KdPrint2((PRINT_PREFIX "AtapiSendCommand: no dma (2)\n"));
7800 use_dma = FALSE;
7801 }
7802 dma_reinited = TRUE;
7803 }
7804 }
7805
7806 if(!(CmdAction & CMD_ACTION_EXEC)) {
7807 KdPrint2((PRINT_PREFIX "AtapiSendCommand: !CMD_ACTION_EXEC => SRB_STATUS_PENDING\n"));
7808 return SRB_STATUS_PENDING;
7809 }
7810 KdPrint3((PRINT_PREFIX "AtapiSendCommand: use_dma=%d, Cmd %x\n", use_dma, Srb->Cdb[0]));
7811 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
7812 KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n"));
7813 }
7814
7815 if((Srb->Cdb[0] == SCSIOP_REQUEST_SENSE) && !(deviceExtension->HwFlags & UNIATA_SATA)) {
7816 KdPrint2((PRINT_PREFIX "AtapiSendCommand: SCSIOP_REQUEST_SENSE -> no dma setup (2)\n"));
7817 use_dma = FALSE;
7818 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7819 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7820 } if(AtaReq->TransferLength) {
7821 if(!dma_reinited) {
7822 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit()\n"));
7823 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7824 if (/*EnableDma &&*/
7825 (LunExt->TransferMode >= ATA_DMA)) {
7826 use_dma = TRUE;
7827 } else {
7828 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7829 use_dma = FALSE;
7830 }
7831 }
7832 } else {
7833 KdPrint2((PRINT_PREFIX "AtapiSendCommand: zero transfer\n"));
7834 use_dma = FALSE;
7835 AtaReq->Flags &= ~REQ_FLAG_DMA_OPERATION;
7836 if(!deviceExtension->opt_AtapiDmaZeroTransfer && !(deviceExtension->HwFlags & UNIATA_SATA)) {
7837 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AtapiDmaReinit() to PIO\n"));
7838 AtapiDmaReinit(deviceExtension, LunExt, AtaReq);
7839 }
7840 }
7841 KdPrint2((PRINT_PREFIX "AtapiSendCommand: use_dma=%d\n", use_dma));
7842 if(AtaReq->Flags & REQ_FLAG_DMA_OPERATION) {
7843 KdPrint2((PRINT_PREFIX " REQ_FLAG_DMA_OPERATION\n"));
7844 }
7845
7846 KdPrint2((PRINT_PREFIX "AtapiSendCommand: CMD_ACTION_EXEC\n"));
7847
7848 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Cdb %x Command %#x to TargetId %d lun %d\n",
7849 &(Srb->Cdb), Srb->Cdb[0], Srb->TargetId, Srb->Lun));
7850
7851 // Make sure command is to ATAPI device.
7852 flags = LunExt->DeviceFlags;
7854 if((Srb->Lun) > (LunExt->DiscsPresent - 1)) {
7855
7856 // Indicate no device found at this address.
7859 }
7860 } else if(Srb->Lun > 0) {
7863 }
7864
7865 if(!(flags & DFLAGS_ATAPI_DEVICE)) {
7868 }
7869retry:
7870 // Select device 0 or 1. Or more for PM
7872
7873 // Verify that controller is ready for next command.
7874 GetStatus(chan, statusByte);
7875 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status %#x\n", statusByte));
7876
7877 if(statusByte == IDE_STATUS_WRONG) {
7878 KdPrint2((PRINT_PREFIX "AtapiSendCommand: bad status 0xff on entry\n"));
7879 goto make_reset;
7880 }
7881 if(statusByte & IDE_STATUS_BUSY) {
7882 if(statusByte & IDE_STATUS_DSC) {
7883 KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC on entry (%#x), try exec\n", statusByte));
7884 } else {
7885 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Device busy (%#x) -> reset\n", statusByte));
7886 // We have to make reset here, since we are expecting device to be available
7887 //return SRB_STATUS_BUSY; // this cause queue freeze
7888 goto make_reset;
7889 }
7890 }
7891 if(deviceExtension->HwFlags & UNIATA_AHCI) {
7892 ULONG CI;
7893 // Check if command list is free
7895 if(CI) {
7896 // controller is busy, however we expect it to be free
7897 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Controller busy (CI=%#x) -> reset\n", CI));
7898 goto make_reset;
7899 }
7900 }
7901 if(statusByte & IDE_STATUS_ERROR) {
7902 if (Srb->Cdb[0] != SCSIOP_REQUEST_SENSE) {
7903
7904 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on entry: (%#x)\n", statusByte));
7905 // Read the error reg. to clear it and fail this request.
7907 return MapError(deviceExtension, Srb);
7908 } else {
7909 KdPrint2((PRINT_PREFIX " continue with SCSIOP_REQUEST_SENSE\n", statusByte));
7910 }
7911 }
7912 // If a tape drive doesn't have DSC set and the last command is restrictive, don't send
7913 // the next command. See discussion of Restrictive Delayed Process commands in QIC-157.
7914 if((!(statusByte & IDE_STATUS_DSC)) &&
7916
7918 KdPrint2((PRINT_PREFIX "AtapiSendCommand: DSC not set. %#x => SRB_STATUS_PENDING\n",statusByte));
7919 AtaReq->ReqState = REQ_STATE_QUEUED;
7920 return SRB_STATUS_PENDING;
7921 }
7922
7923 if(IS_RDP(Srb->Cdb[0])) {
7924 chan->RDP = TRUE;
7925 KdPrint2((PRINT_PREFIX "AtapiSendCommand: %#x mapped as DSC restrictive\n", Srb->Cdb[0]));
7926 } else {
7927 chan->RDP = FALSE;
7928 }
7929 if(statusByte & IDE_STATUS_DRQ) {
7930
7931 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entered with status (%#x). Attempting to recover.\n",
7932 statusByte));
7933 // Try to drain the data that one preliminary device thinks that it has
7934 // to transfer. Hopefully this random assertion of DRQ will not be present
7935 // in production devices.
7936 statusByte = AtapiSuckPort2(chan);
7937/*
7938 for (i = 0; i < 0x10000; i++) {
7939 GetStatus(chan, statusByte);
7940 if(statusByte & IDE_STATUS_DRQ) {
7941 AtapiReadPort2(chan, IDX_IO1_i_Data);
7942 } else {
7943 break;
7944 }
7945 }
7946*/
7947 if (statusByte & IDE_STATUS_DRQ) {
7948 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ still asserted. Status (%#x)\n", statusByte));
7949make_reset:
7950 AtapiDisableInterrupts(deviceExtension, lChannel);
7951
7953
7954 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Issued soft reset to Atapi device. \n"));
7955 // Re-initialize Atapi device.
7956 CheckDevice(HwDeviceExtension, GET_CHANNEL(Srb), DeviceNumber, TRUE);
7957/*
7958 IssueIdentify(HwDeviceExtension, DeviceNumber, GET_CHANNEL(Srb),
7959 IDE_COMMAND_ATAPI_IDENTIFY, FALSE);
7960*/
7961 // Inform the port driver that the bus has been reset.
7962 ScsiPortNotification(ResetDetected, HwDeviceExtension, 0);
7963 // Clean up device extension fields that AtapiStartIo won't.
7965 chan->RDP = FALSE;
7966 InterlockedExchange(&(deviceExtension->chan[GET_CHANNEL(Srb)].CheckIntr),
7968
7969 AtapiEnableInterrupts(deviceExtension, lChannel);
7970/*
7971 AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
7972 return SRB_STATUS_BUS_RESET;
7973*/
7974 if(!retried) {
7975 KdPrint3((PRINT_PREFIX "AtapiSendCommand: retry after reset.\n"));
7976 retried = TRUE;
7977 goto retry;
7978 }
7979 KdPrint3((PRINT_PREFIX "AtapiSendCommand: selection timeout.\n"));
7982 }
7983 }
7984
7986 // As the cdrom driver sets the LUN field in the cdb, it must be removed.
7987 Srb->Cdb[1] &= ~0xE0;
7989 // Torisan changer. TUR's are overloaded to be platter switches.
7990 Srb->Cdb[7] = Srb->Lun;
7991 }
7992 }
7993
7994 // SETUP DMA !!!!!
7995
7996 if(use_dma) {
7998 } else {
7999 chan->ChannelCtrlFlags &= ~CTRFLAGS_DMA_OPERATION;
8000 }
8001
8002 if(deviceExtension->HwFlags & UNIATA_AHCI) {
8003 KdPrint2((PRINT_PREFIX "AtapiSendCommand: AHCI, begin transaction\n"));
8004 //AtaReq->Flags = ~REQ_FLAG_DMA_OPERATION; // keep proped DMA flag for proper RETRY handling
8006 UniataAhciBeginTransaction(HwDeviceExtension, lChannel, DeviceNumber, Srb);
8007 return SRB_STATUS_PENDING;
8008 }
8009
8010 statusByte = WaitOnBusy(chan);
8011 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Entry Status (%#x)\n",
8012 statusByte));
8013
8014 if(use_dma) {
8015 FeatureReg |= ATA_F_DMA;
8016 if(LunExt->IdentifyData.AtapiDMA.DMADirRequired) {
8018 FeatureReg |= ATA_F_DMAREAD;
8019 }
8020 }
8021 }
8022
8023 // Write transfer byte count to registers.
8024 if (Srb->DataTransferLength >= 0x10000) {
8025 byteCountLow = byteCountHigh = 0xFF;
8026 } else {
8027 byteCountLow = (UCHAR)(Srb->DataTransferLength & 0xFF);
8028 byteCountHigh = (UCHAR)(Srb->DataTransferLength >> 8);
8029 }
8030
8031 KdPrint3((PRINT_PREFIX "AtapiSendCommand: F:%#x, CntHL:%#x:%#x.\n", FeatureReg, byteCountHigh, byteCountLow));
8032
8033 if (flags & DFLAGS_INT_DRQ) {
8034 // This device interrupts when ready to receive the packet.
8035 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Wait for int. to send packet. Status (%#x)\n",
8036 statusByte));
8037
8042 // inform driver that packet command must be sent in ISR
8044 } else {
8045 // This device quickly sets DRQ when ready to receive the packet.
8046 KdPrint2((PRINT_PREFIX "AtapiSendCommand: Poll for int. to send packet. Status (%#x)\n",
8047 statusByte));
8048
8053
8055 AtapiDisableInterrupts(deviceExtension, lChannel);
8056 }
8057 // remember status. Later we may check if error appeared after cmd packet
8058 statusByte0 = statusByte;
8059 }
8060
8061 // must be already selected, experimental for ROS BUG-9119
8062 //AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, IDE_USE_LBA | (DeviceNumber ? IDE_DRIVE_2 : IDE_DRIVE_1) );
8064 AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Feature /*IDX_IO1_o_Feature*/, FeatureReg);
8065 //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused0, 0); // experimental for ROS BUG-9119
8066 //AtapiWritePort1(chan, IDX_ATAPI_IO1_o_Unused1, 0); // experimental for ROS BUG-9119
8067 AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountLow, byteCountLow);
8068 AtapiWritePort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh, byteCountHigh);
8069 // Write ATAPI packet command.
8071
8072 if (flags & DFLAGS_INT_DRQ) {
8073 // Wait for interrupt and send PACKET there
8074 KdPrint3((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (DRQ)\n"));
8075 return SRB_STATUS_PENDING;
8076 }
8077
8078 WaitOnBusy(chan);
8079/*
8080 // Wait for DRQ.
8081 statusByte = WaitForDrq(chan);
8082
8083 // Need to read status register and clear interrupt (if any)
8084 GetBaseStatus(chan, statusByte);
8085
8086 if (!(statusByte & IDE_STATUS_DRQ)) {
8087 if(g_opt_AtapiSendDisableIntr) {
8088 AtapiEnableInterrupts(deviceExtension, lChannel);
8089 }
8090 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ never asserted (%#x)\n", statusByte));
8091 AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
8092 return SRB_STATUS_ERROR;
8093 }
8094*/
8095 GetStatus(chan, statusByte);
8096 KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
8097
8098 //statusByte = WaitOnBaseBusy(chan);
8099
8100 // Indicate expecting an interrupt and wait for it.
8102
8103 for(i=0; i<5000; i++) {
8105 GetStatus(chan, statusByte);
8106 } else {
8107 GetBaseStatus(chan, statusByte);
8108 }
8109 interruptReason = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_InterruptReason);
8110 //KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i));
8111 if(((interruptReason & ATAPI_IR_COD) == ATAPI_IR_COD_Cmd) &&
8112 (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) == IDE_STATUS_DRQ))) {
8113 break;
8114 }
8116#ifdef _DEBUG
8117// KdPrint3((PRINT_PREFIX "AtapiSendCommand: wait CoD, status (%#x)\n", interruptReason));
8118#endif // _DEBUG
8119 }
8120 if(((interruptReason & ATAPI_IR_COD) != ATAPI_IR_COD_Cmd) ||
8121 (((statusByte & (IDE_STATUS_BUSY | IDE_STATUS_DRQ)) != IDE_STATUS_DRQ)) ) {
8122 KdPrint3((PRINT_PREFIX "AtapiSendCommand: no CoD raised, abort cmd\n"));
8123 KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x (%d)\n", interruptReason, i));
8124 KdPrint3((PRINT_PREFIX "AtapiSendCommand: status (%#x)\n", statusByte));
8126 AtapiEnableInterrupts(deviceExtension, lChannel);
8127 }
8128 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ+CoD never asserted\n"));
8129 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8130 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte));
8131 if(statusByte >> 4) {
8132 GetBaseStatus(chan, statusByte);
8134 return MapError(deviceExtension, Srb);
8135 }
8136 goto make_reset;
8137// AtaReq->ReqState = REQ_STATE_TRANSFER_COMPLETE;
8138// return SRB_STATUS_ERROR;
8139 } else {
8140 KdPrint3((PRINT_PREFIX "AtapiSendCommand: ready for packet, status %#x, i=%d\n", interruptReason, i));
8141 }
8142 // clear interrupt
8143 GetBaseStatus(chan, statusByte);
8144
8146 AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
8147 }
8149 AtapiEnableInterrupts(deviceExtension, lChannel);
8150 }
8151
8152 // Send CDB to device.
8153 WriteBuffer(chan,
8154 (PUSHORT)Srb->Cdb,
8155 LunExt->IdentifyData.AtapiCmdSize ? 8 : 6,
8156 /*0*/ PIO0_TIMING);
8157
8158 GetStatus(chan, statusByte);
8159 KdPrint3((PRINT_PREFIX "AtapiSendCommand: cmd status (%#x)\n", statusByte));
8160
8161 // When we operate in DMA mode, we should not start transfer when there is an error on entry
8162 // Interrupt may never come in such case.
8163 if(statusByte & IDE_STATUS_ERROR) {
8164
8165 GetBaseStatus(chan, statusByte);
8166 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Error on cmd: (%#x)\n", statusByte));
8167
8169 KdPrint3((PRINT_PREFIX "AtapiSendCommand: iReason %x\n", interruptReason));
8170
8171 // TODO: we should check interruptReason and decide what to do now
8172
8173 // Read the error reg. to clear it and fail this request.
8175 return MapError(deviceExtension, Srb);
8176 }
8177 if(statusByte & IDE_STATUS_DRQ) {
8178 // Some devices require this. If error condition is not checked in such a way,
8179 // device may not operate correctly and would be treated as failed
8180 // (and finally invisible for OS)
8181 KdPrint3((PRINT_PREFIX "AtapiSendCommand: DRQ on cmd: (%#x)\n", statusByte));
8182 // Read the error reg. to clear it and fail this request.
8183 statusByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8184 KdPrint3((PRINT_PREFIX "AtapiSendCommand: Err on cmd: (%#x)\n", statusByte));
8185 if(statusByte >> 4) {
8186 GetBaseStatus(chan, statusByte);
8188 return MapError(deviceExtension, Srb);
8189 }
8190 }
8191
8193 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
8194 }
8195
8199
8200 KdPrint3((PRINT_PREFIX "AtapiSendCommand: ExpectingInterrupt (%#x)\n", chan->ExpectingInterrupt));
8201
8202 KdPrint2((PRINT_PREFIX "AtapiSendCommand: return SRB_STATUS_PENDING (3)\n"));
8203 return SRB_STATUS_PENDING;
8204
8205} // end AtapiSendCommand()
#define MOV_DD_SWP(a, b)
Definition: atactl.cpp:27
#define ATAPI_IR_COD
Definition: atapi.h:185
#define IDE_COMMAND_ATAPI_PACKET
Definition: atapi.h:109
#define IS_RDP(OperationCode)
Definition: atapi.h:453
#define REQ_STATE_PREPARE_TO_TRANSFER
Definition: bsmaster.h:946
#define REQ_STATE_READY_TO_TRANSFER
Definition: bsmaster.h:948
#define ATA_AHCI_CMD_PREFETCH
Definition: bsmaster.h:817
BOOLEAN NTAPI AtapiDmaSetup(IN PVOID HwDeviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG count)
Definition: id_dma.cpp:247
#define ATA_AHCI_CMD_WRITE
Definition: bsmaster.h:816
#define ATA_AHCI_CMD_ATAPI
Definition: bsmaster.h:815
#define REQ_FLAG_WRITE
Definition: bsmaster.h:936
#define REQ_FLAG_REORDERABLE_CMD
Definition: bsmaster.h:933
#define GET_CDEV(Srb)
Definition: bsmaster.h:1850
#define GET_CHANNEL(Srb)
Definition: bsmaster.h:1847
#define CMD_ACTION_PREPARE
Definition: bsmaster.h:974
#define IDX_AHCI_P_CI
Definition: bsmaster.h:686
VOID NTAPI AtapiDmaReinit(IN PHW_DEVICE_EXTENSION deviceExtension, IN PHW_LU_EXTENSION LunExt, IN PATA_REQ AtaReq)
Definition: id_dma.cpp:754
#define REQ_FLAG_READ
Definition: bsmaster.h:935
#define CTRFLAGS_DMA_RO
Definition: bsmaster.h:1132
#define CMD_ACTION_EXEC
Definition: bsmaster.h:975
#define SCSIOP_READ_CD
Definition: cdrw_hw.h:967
#define SCSIOP_WRITE_CD
Definition: cdrw_hw.h:907
#define SCSIOP_TEST_UNIT_READY
Definition: cdrw_hw.h:866
#define SCSIOP_RECEIVE
Definition: cdrw_hw.h:875
#define SCSIOP_WRITE
Definition: cdrw_hw.h:906
#define SCSIOP_READ12
Definition: cdrw_hw.h:956
#define SCSIOP_WRITE12
Definition: cdrw_hw.h:957
#define SCSIOP_READ_CD_MSF
Definition: cdrw_hw.h:964
#define SCSIOP_SEND
Definition: cdrw_hw.h:878
#define SCSIOP_MODE_SELECT10
Definition: cdrw_hw.h:943
#define SCSIOP_READ
Definition: cdrw_hw.h:905
#define SCSIOP_MODE_SELECT
Definition: cdrw_hw.h:891
#define CI(cs)
Definition: fontdlg.c:68
#define MOV_SWP_DW2DD(a, b)
Definition: misc.h:131
#define MOV_QD_SWP(a, b)
Definition: misc.h:63
#define SCSIOP_READ16
Definition: scsi.h:914
#define SCSIOP_WRITE16
Definition: scsi.h:915
#define SRB_STATUS_SELECTION_TIMEOUT
Definition: srb.h:350
@ ResetDetected
Definition: srb.h:534
#define SRB_STATUS_BUSY
Definition: srb.h:345
#define SRB_STATUS_INVALID_REQUEST
Definition: srb.h:346
GLbitfield flags
Definition: glext.h:7161
#define IDX_ATAPI_IO1_o_Command
Definition: hwide.h:103
#define IDX_ATAPI_IO1_o_ByteCountHigh
Definition: hwide.h:101
#define IDX_ATAPI_IO1_o_ByteCountLow
Definition: hwide.h:100
#define IDX_ATAPI_IO1_o_Feature
Definition: hwide.h:97
BOOLEAN g_opt_AtapiNoDma
Definition: id_ata.cpp:101
UCHAR DDKFASTAPI SelectDrive(IN PHW_CHANNEL chan, IN ULONG DeviceNumber)
Definition: id_ata.cpp:621
ULONG g_opt_WaitDrqDelay
Definition: id_ata.cpp:92
BOOLEAN g_opt_AtapiSendDisableIntr
Definition: id_ata.cpp:99
ULONG NTAPI UniataAhciSetupFIS_H2D(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, OUT PUCHAR fis, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature)
Definition: id_sata.cpp:1241
UCHAR NTAPI UniataAhciBeginTransaction(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_sata.cpp:2171
VOID UniataAhciSetupCmdPtr(IN OUT PATA_REQ AtaReq)
Definition: id_sata.cpp:2611
__inline ULONG UniataAhciReadChannelPort4(IN PHW_CHANNEL chan, IN ULONG io_port_ndx)
Definition: id_sata.h:290
__inline USHORT UniAtaAhciAdjustIoFlags(IN UCHAR command, IN USHORT ahci_flags, IN ULONG fis_size, IN ULONG DeviceNumber)
Definition: id_sata.h:357
BOOLEAN opt_AtapiDmaReadWrite
Definition: bsmaster.h:1339
BOOLEAN opt_AtapiDmaRawRead
Definition: bsmaster.h:1338
BOOLEAN opt_AtapiDmaControlCmd
Definition: bsmaster.h:1337
BOOLEAN opt_AtapiDmaZeroTransfer
Definition: bsmaster.h:1336
ULONG DiscsPresent
Definition: bsmaster.h:1165
UCHAR CdbLength
Definition: srb.h:258
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define ATA_DMA
Definition: atapi.h:316
#define ATA_F_DMA
Definition: atapi.h:557
#define ATA_F_DMAREAD
Definition: atapi.h:559
ULONG NTAPI CheckDevice(IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber, IN BOOLEAN ResetBus)
Definition: id_probe.cpp:2897
ULONG dma_entries
Definition: bsmaster.h:897
struct _CDB::_CDB16READWRITE CDB16READWRITE
struct _CDB::_WRITE_CD WRITE_CD
struct _CDB::_CDB12READWRITE CDB12READWRITE

Referenced by AtapiInterrupt__(), AtapiSendCommand(), and AtapiStartIo__().

◆ AtapiSoftReset()

VOID DDKFASTAPI AtapiSoftReset ( IN struct _HW_CHANNEL chan,
IN ULONG  DeviceNumber 
)

◆ AtapiStartIo()

BOOLEAN NTAPI AtapiStartIo ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 5811 of file atapi.c.

5834{
5835 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
5836 ULONG status;
5837
5838 //
5839 // Determine which function.
5840 //
5841
5842 switch (Srb->Function) {
5843
5845
5846 //
5847 // Sanity check. Only one request can be outstanding on a
5848 // controller.
5849 //
5850
5851 if (deviceExtension->CurrentSrb) {
5852
5853 DebugPrint((1,
5854 "AtapiStartIo: Already have a request!\n"));
5857 deviceExtension,
5858 Srb);
5859 return FALSE;
5860 }
5861
5862 //
5863 // Indicate that a request is active on the controller.
5864 //
5865
5866 deviceExtension->CurrentSrb = Srb;
5867
5868 //
5869 // Send command to device.
5870 //
5871
5872 if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE) {
5873
5874 status = AtapiSendCommand(HwDeviceExtension,
5875 Srb);
5876
5877 } else if (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) {
5878
5879 status = IdeSendCommand(HwDeviceExtension,
5880 Srb);
5881 } else {
5882
5884 }
5885
5886 break;
5887
5889
5890 //
5891 // Verify that SRB to abort is still outstanding.
5892 //
5893
5894 if (!deviceExtension->CurrentSrb) {
5895
5896 DebugPrint((1, "AtapiStartIo: SRB to abort already completed\n"));
5897
5898 //
5899 // Complete abort SRB.
5900 //
5901
5903
5904 break;
5905 }
5906
5907 //
5908 // Abort function indicates that a request timed out.
5909 // Call reset routine. Card will only be reset if
5910 // status indicates something is wrong.
5911 // Fall through to reset code.
5912 //
5913
5915
5916 //
5917 // Reset Atapi and SCSI bus.
5918 //
5919
5920 DebugPrint((1, "AtapiStartIo: Reset bus request received\n"));
5921
5922 if (!AtapiResetController(deviceExtension,
5923 Srb->PathId)) {
5924
5925 DebugPrint((1,"AtapiStartIo: Reset bus failed\n"));
5926
5927 //
5928 // Log reset failure.
5929 //
5930
5932 HwDeviceExtension,
5933 NULL,
5934 0,
5935 0,
5936 0,
5938 5 << 8
5939 );
5940
5942
5943 } else {
5944
5946 }
5947
5948 break;
5949
5951
5952 if (deviceExtension->CurrentSrb) {
5953
5954 DebugPrint((1,
5955 "AtapiStartIo: Already have a request!\n"));
5958 deviceExtension,
5959 Srb);
5960 return FALSE;
5961 }
5962
5963 //
5964 // Indicate that a request is active on the controller.
5965 //
5966
5967 deviceExtension->CurrentSrb = Srb;
5968
5969 if (AtapiStringCmp( (PCHAR)((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,"SCSIDISK",strlen("SCSIDISK"))) {
5970
5971 DebugPrint((1,
5972 "AtapiStartIo: IoControl signature incorrect. Send %s, expected %s\n",
5973 ((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,
5974 "SCSIDISK"));
5975
5977 break;
5978 }
5979
5980 switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
5981
5983
5984 PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
5985 UCHAR deviceNumber;
5986
5987 //
5988 // Version and revision per SMART 1.03
5989 //
5990
5991 versionParameters->bVersion = 1;
5992 versionParameters->bRevision = 1;
5993 versionParameters->bReserved = 0;
5994
5995 //
5996 // Indicate that support for IDE IDENTIFY, ATAPI IDENTIFY and SMART commands.
5997 //
5998
6000
6001 //
6002 // This is done because of how the IOCTL_SCSI_MINIPORT
6003 // determines 'targetid's'. Disk.sys places the real target id value
6004 // in the DeviceMap field. Once we do some parameter checking, the value passed
6005 // back to the application will be determined.
6006 //
6007
6008 deviceNumber = versionParameters->bIDEDeviceMap;
6009
6010 if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) ||
6011 (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE)) {
6012
6014 break;
6015 }
6016
6017 //
6018 // NOTE: This will only set the bit
6019 // corresponding to this drive's target id.
6020 // The bit mask is as follows:
6021 //
6022 // Sec Pri
6023 // S M S M
6024 // 3 2 1 0
6025 //
6026
6027 if (deviceExtension->NumberChannels == 1) {
6028 if (deviceExtension->PrimaryAddress) {
6029 deviceNumber = 1 << Srb->TargetId;
6030 } else {
6031 deviceNumber = 4 << Srb->TargetId;
6032 }
6033 } else {
6034 deviceNumber = 1 << Srb->TargetId;
6035 }
6036
6037 versionParameters->bIDEDeviceMap = deviceNumber;
6038
6040 break;
6041 }
6042
6044
6045 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6046 SENDCMDINPARAMS cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
6047 ULONG i;
6048 UCHAR targetId;
6049
6050
6051 if (cmdInParameters.irDriveRegs.bCommandReg == ID_CMD) {
6052
6053 //
6054 // Extract the target.
6055 //
6056
6057 targetId = cmdInParameters.bDriveNumber;
6058
6059 if (!(deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_DEVICE_PRESENT) ||
6060 (deviceExtension->DeviceFlags[Srb->TargetId] & DFLAGS_ATAPI_DEVICE)) {
6061
6063 break;
6064 }
6065
6066 //
6067 // Zero the output buffer
6068 //
6069
6070 for (i = 0; i < (sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1); i++) {
6071 ((PUCHAR)cmdOutParameters)[i] = 0;
6072 }
6073
6074 //
6075 // Build status block.
6076 //
6077
6078 cmdOutParameters->cBufferSize = IDENTIFY_BUFFER_SIZE;
6079 cmdOutParameters->DriverStatus.bDriverError = 0;
6080 cmdOutParameters->DriverStatus.bIDEError = 0;
6081
6082 //
6083 // Extract the identify data from the device extension.
6084 //
6085
6086 ScsiPortMoveMemory (cmdOutParameters->bBuffer, &deviceExtension->IdentifyData[targetId], IDENTIFY_DATA_SIZE);
6087
6089
6090
6091 } else {
6093 }
6094 break;
6095 }
6096
6105
6106 status = IdeSendSmartCommand(HwDeviceExtension,Srb);
6107 break;
6108
6109 default :
6110
6112 break;
6113
6114 }
6115
6116 break;
6117
6118 default:
6119
6120 //
6121 // Indicate unsupported command.
6122 //
6123
6125
6126 break;
6127
6128 } // end switch
6129
6130 //
6131 // Check if command complete.
6132 //
6133
6134 if (status != SRB_STATUS_PENDING) {
6135
6136 DebugPrint((2,
6137 "AtapiStartIo: Srb %x complete with status %x\n",
6138 Srb,
6139 status));
6140
6141 //
6142 // Clear current SRB.
6143 //
6144
6145 deviceExtension->CurrentSrb = NULL;
6146
6147 //
6148 // Set status in SRB.
6149 //
6150
6152
6153 //
6154 // Indicate command complete.
6155 //
6156
6158 deviceExtension,
6159 Srb);
6160
6161 //
6162 // Indicate ready for next request.
6163 //
6164
6166 deviceExtension,
6167 NULL);
6168 }
6169
6170 return TRUE;
6171
6172} // end AtapiStartIo()
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
ULONG NTAPI IdeSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:5336
ULONG NTAPI IdeSendSmartCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: atapi.c:4343
#define ID_CMD
Definition: helper.h:20
struct _SENDCMDOUTPARAMS SENDCMDOUTPARAMS
struct _SENDCMDINPARAMS * PSENDCMDINPARAMS
VOID NTAPI ScsiPortLogError(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb OPTIONAL, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN ULONG ErrorCode, IN ULONG UniqueId)
Definition: scsiport.c:1299
VOID NTAPI ScsiPortMoveMemory(IN PVOID WriteBuffer, IN PVOID ReadBuffer, IN ULONG Length)
Definition: scsiport.c:1314
#define IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES
Definition: cdrw_hw.h:1465
#define IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS
Definition: cdrw_hw.h:1459
#define IOCTL_SCSI_MINIPORT_DISABLE_SMART
Definition: cdrw_hw.h:1462
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE
Definition: cdrw_hw.h:1464
#define IOCTL_SCSI_MINIPORT_IDENTIFY
Definition: cdrw_hw.h:1458
#define IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS
Definition: cdrw_hw.h:1466
#define IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS
Definition: cdrw_hw.h:1460
#define IOCTL_SCSI_MINIPORT_ENABLE_SMART
Definition: cdrw_hw.h:1461
#define IOCTL_SCSI_MINIPORT_RETURN_STATUS
Definition: cdrw_hw.h:1463
#define IOCTL_SCSI_MINIPORT_SMART_VERSION
Definition: cdrw_hw.h:1457
#define SRB_FUNCTION_EXECUTE_SCSI
Definition: srb.h:315
#define SRB_FUNCTION_RESET_BUS
Definition: srb.h:326
#define SP_INTERNAL_ADAPTER_ERROR
Definition: srb.h:509
#define SRB_STATUS_ABORT_FAILED
Definition: srb.h:343
#define SRB_FUNCTION_ABORT_COMMAND
Definition: srb.h:324
#define IDENTIFY_DATA_SIZE
Definition: hwide.h:284
#define CAP_ATAPI_ID_CMD
Definition: ntdddisk.h:662
#define IDENTIFY_BUFFER_SIZE
Definition: ntdddisk.h:732
struct _GETVERSIONINPARAMS * PGETVERSIONINPARAMS
#define CAP_ATA_ID_CMD
Definition: ntdddisk.h:661
#define CAP_SMART_CMD
Definition: ntdddisk.h:663
BOOLEAN PrimaryAddress
Definition: atapi.c:124
UCHAR bCommandReg
Definition: helper.h:15
UCHAR bDriveNumber
Definition: helper.h:33
IDEREGS irDriveRegs
Definition: helper.h:32

Referenced by DriverEntry().

◆ AtapiStartIo__()

BOOLEAN NTAPI AtapiStartIo__ ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb,
IN BOOLEAN  TopLevel 
)

Definition at line 9288 of file id_ata.cpp.

9293{
9294 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
9295 UCHAR lChannel;
9296 PHW_CHANNEL chan;
9297 PHW_LU_EXTENSION LunExt;
9298 ULONG status;
9299 //ULONG ldev;
9301 UCHAR PathId;
9303 UCHAR Lun;
9304 PATA_REQ AtaReq;
9305 PSCSI_REQUEST_BLOCK tmpSrb;
9306 BOOLEAN PostReq = FALSE;
9307 BOOLEAN atapiDev;
9308 BOOLEAN commPort = FALSE;
9309
9310 // deviceExtension->Isr2DevObj must always be NULL for non-PCI
9311 if(deviceExtension->Isr2DevObj && !BMList[deviceExtension->DevIndex].Isr2Enable) {
9312 KdPrint2((PRINT_PREFIX "Isr2Enable -> 1\n"));
9313 BMList[deviceExtension->DevIndex].Isr2Enable = TRUE;
9314 }
9315// deviceExtension->QueueNewIrql = max(deviceExtension->QueueNewIrql, KeGetCurrentIrql());
9316
9317/* KeBugCheckEx(0xc000000e,
9318 (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
9319 Srb->Function,
9320 TopLevel, 0x80000001);
9321*/
9322 if(TopLevel && Srb && Srb->SrbExtension) {
9323 KdPrint2((PRINT_PREFIX "TopLevel\n"));
9324 //RtlZeroMemory(Srb->SrbExtension, sizeof(ATA_REQ));
9326 }
9327
9328 do { // fetch all queued commands for the channel (if valid)
9329
9330 lChannel = GET_CHANNEL(Srb);
9331 //ldev = GET_LDEV(Srb);
9332 chan = NULL;
9333 LunExt = NULL;
9335 commPort = FALSE;
9336
9337 //ASSERT(deviceExtension);
9338 //ASSERT(chan);
9339
9341 "** AtapiStartIo: Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
9343 KdPrint2((PRINT_PREFIX " DeviceID+VendorID/Rev %#x/%#x\n", deviceExtension->DevID, deviceExtension->RevID));
9344
9345 if(lChannel == deviceExtension->NumberChannels &&
9346 !Srb->Lun && !Srb->TargetId &&
9349 ) {
9350 // This is our virtual device
9352 "AtapiStartIo: Communication port\n"));
9354
9355 if(Srb->DataTransferLength < sizeof(PINQUIRYDATA)) {
9356 KdPrint2((PRINT_PREFIX "AtapiStartIo: Buffer too small: %#x < %#x\n", Srb->DataTransferLength,
9357 sizeof(PINQUIRYDATA) ));
9358wrong_buffer_size:
9360 goto complete_req;
9361 }
9362
9363 PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
9364
9366 " INQUIRY\n"));
9367 // Zero INQUIRY data structure.
9369
9370 inquiryData->DeviceType = COMMUNICATION_DEVICE;
9371
9372 // Fill in vendor identification fields.
9373 RtlCopyMemory(&inquiryData->VendorId, &uniata_comm_name, 28);
9374
9376 goto complete_req;
9377 }
9378 commPort = TRUE;
9379 /* Pass IOCTL request down */
9380 } else
9381 if(lChannel >= deviceExtension->NumberChannels ||
9382 Srb->TargetId /*DeviceNumber*/ >= deviceExtension->NumberLuns ||
9383 Srb->Lun) {
9384
9385 if(lChannel >= deviceExtension->NumberChannels) {
9386 chan = NULL;
9387 }
9388
9389reject_srb:
9390 //if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
9392 "AtapiStartIo: SRB rejected\n"));
9393 // Indicate no device found at this address.
9394 KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
9396 goto complete_req;
9397 //}
9398 } else
9399 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
9400 !UniataAhciChanImplemented(deviceExtension, lChannel)) {
9401 chan = NULL;
9402 }
9403
9404 if(!commPort) {
9405 chan = &(deviceExtension->chan[lChannel]);
9406 LunExt = chan->lun[DeviceNumber];
9407 if(!LunExt) {
9408 goto reject_srb;
9409 }
9410 atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
9411 } else {
9412 atapiDev = FALSE;
9413 }
9414
9415#ifdef _DEBUG
9416 if(!commPort && !LunExt) {
9417#if 0
9418 PrintNtConsole("de = %#x, chan = %#x , dev %#x, nchan %#x\n",
9419 deviceExtension,
9420 chan, DeviceNumber,
9421 deviceExtension->NumberChannels);
9422 PrintNtConsole("lchan = %#x, cdev %#x, lun0 %#x\n",
9423 lChannel, GET_CDEV(Srb), deviceExtension->chan[0].lun[0]);
9424 PrintNtConsole("Function %#x, PATH:LUN:TID = %#x:%#x:%#x\n",
9426#endif //0
9427/*
9428 int i;
9429 for(i=0; i<1000; i++) {
9430 AtapiStallExecution(3*1000);
9431 }
9432*/
9433 goto reject_srb;
9434 }
9435#endif //_DEBUG
9436
9437 // Determine which function.
9438 switch (Srb->Function) {
9439
9441
9442 if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9443 if(Srb->Cdb[0] == SCSIOP_ATA_PASSTHROUGH) {
9444 // let passthrough go
9445 } else
9446 if(Srb->Cdb[0] == SCSIOP_INQUIRY) {
9447 // let INQUIRY go
9448 } else {
9449
9450 //if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
9452 "AtapiStartIo: EXECUTE_SCSI rejected (2)\n"));
9453 // Indicate no device found at this address.
9454 KdPrint2((PRINT_PREFIX "SRB_STATUS_SELECTION_TIMEOUT\n"));
9456 break;
9457 //}
9458 }
9459 } else {
9461 " SRB %#x, CDB %#x, AtaReq %#x, SCmd %#x\n", Srb, &(Srb->Cdb), Srb->SrbExtension, Srb->Cdb[0]));
9462 }
9463/*
9464 __try {
9465 if(Srb->DataTransferLength) {
9466 UCHAR a;
9467 a = ((PUCHAR)(Srb->DataBuffer))[0];
9468 g_foo += a;
9469 }
9470 } __except(EXCEPTION_EXECUTE_HANDLER) {
9471 KdPrint3((PRINT_PREFIX
9472 "AtapiStartIo: Bad data buffer -> EXECUTE_SCSI rejected\n"));
9473 // Indicate no device found at this address.
9474 KdPrint3((PRINT_PREFIX "SRB_STATUS_ERROR\n"));
9475 status = SRB_STATUS_ERROR;
9476 KdPrint2((PRINT_PREFIX " *** Exception...\n"));
9477 ASSERT(FALSE);
9478 break;
9479 }
9480*/
9481 PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
9482
9483 if(PostReq) {
9484
9485 KdPrint3((PRINT_PREFIX "Non-empty queue\n"));
9486 if (atapiDev &&
9487 (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)) {
9488 KdPrint3((PRINT_PREFIX "Try ATAPI prepare\n"));
9489
9490 status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE);
9491 } else {
9492 KdPrint2((PRINT_PREFIX "Try IDE prepare\n"));
9493 status = IdeSendCommand(HwDeviceExtension, Srb, CMD_ACTION_PREPARE);
9494 }
9495 /*KeBugCheckEx(0xc000000e,
9496 (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
9497 Srb->Function,
9498 status, 0x80000001);*/
9499 if(status == SRB_STATUS_BUSY)
9501 // Insert requests AFTER they have been initialized on
9502 // CMD_ACTION_PREPARE stage
9503 // we should not check TopLevel here (it is always TRUE)
9504 //ASSERT(chan->lun[GET_CDEV(Srb)]);
9505 UniataQueueRequest(chan, Srb);
9506
9507 KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
9508
9509 } else {
9510
9511 // Send command to device.
9512 KdPrint2((PRINT_PREFIX "Send to device %x\n", Srb->Cdb[0]));
9513 if(TopLevel) {
9514 KdPrint2((PRINT_PREFIX "TopLevel (2), srb %#x\n", Srb));
9515 AtaReq = (PATA_REQ)(Srb->SrbExtension);
9516 KdPrint2((PRINT_PREFIX "TopLevel (3), AtaReq %#x\n", AtaReq));
9517 //ASSERT(!AtaReq->Flags);
9518 //ASSERT(chan->lun[GET_CDEV(Srb)]);
9519 UniataQueueRequest(chan, Srb);
9520// AtaReq = (PATA_REQ)(Srb->SrbExtension);
9521 //ASSERT(!AtaReq->Flags);
9522 AtaReq->ReqState = REQ_STATE_QUEUED;
9523 //ASSERT(!AtaReq->Flags);
9524 }
9525
9526#ifndef NAVO_TEST
9527 if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9528 if(!LunExt) {
9529 goto reject_srb;
9530 }
9531 if(Srb->Cdb[0] == SCSIOP_INQUIRY) {
9532 if(UniataAnybodyHome(deviceExtension, chan->lChannel, DeviceNumber)) {
9533 if(!CheckDevice(HwDeviceExtension, chan->lChannel, DeviceNumber, TRUE)) {
9534 goto reject_srb;
9535 }
9536 }
9537 if(!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9538 goto reject_srb;
9539 }
9540 } else
9541 if(Srb->Cdb[0] == SCSIOP_ATA_PASSTHROUGH) {
9542 // allow
9543 } else {
9544 goto reject_srb;
9545 }
9546 }
9547#endif //NAVO_TEST
9548
9549 if(atapiDev &&
9550 (Srb->Cdb[0] != SCSIOP_ATA_PASSTHROUGH)/* &&
9551 (Srb->Cdb[0] != SCSIOP_REPORT_LUNS)*/) {
9552 KdPrint3((PRINT_PREFIX "Try ATAPI send %x\n", Srb->Cdb[0]));
9553#ifdef __REACTOS__
9555
9556 if (Srb->Cdb[0] == SCSIOP_INQUIRY &&
9557 (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) &&
9558 (LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM ||
9559 LunExt->IdentifyData.DeviceType == ATAPI_TYPE_OPTICAL) &&
9560 LunExt->IdentifyData.ModelNumber[0])
9561 {
9562 ULONG j;
9563 CCHAR vendorId[26];
9564
9565 // Attempt to identify known broken CD/DVD drives
9566 for (j = 0; j < sizeof(vendorId); j += 2)
9567 {
9568 // Build a buffer based on the identify data.
9569 MOV_DW_SWP(vendorId[j], ((PUCHAR)LunExt->IdentifyData.ModelNumber)[j]);
9570 }
9571
9572 // Emulate INQUIRY support for broken CD/DVD drives (e.g. Microsoft Xbox).
9573 // Currently we implement it by explicitly checking the drive name from ATA IDENTIFY PACKET.
9574 if (!AtapiStringCmp(vendorId, "THOMSON-DVD", 11) ||
9575 !AtapiStringCmp(vendorId, "PHILIPS XBOX DVD DRIVE", 22) ||
9576 !AtapiStringCmp(vendorId, "PHILIPS J5 3235C", 16) ||
9577 !AtapiStringCmp(vendorId, "SAMSUNG DVD-ROM SDG-605B", 24))
9578 {
9579 // TODO:
9580 // Better send INQUIRY and then check for chan->ReturningMediaStatus >> 4 == SCSI_SENSE_ILLEGAL_REQUEST
9581 // in AtapiInterrupt__() and emulate the response only in this case.
9582
9583 // If this hack stays for long enough, consider adding Xbox 360 drive names to the condition,
9584 // as they are affected by the same problem.
9585
9586 // See https://jira.reactos.org/browse/CORE-16692
9587 ULONG i;
9588 PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
9589 PIDENTIFY_DATA2 identifyData = &(LunExt->IdentifyData);
9590
9591 // Zero INQUIRY data structure.
9593
9594 // This is ATAPI CD- or DVD-ROM.
9596
9597 // Set the removable bit, if applicable.
9598 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
9600 "RemovableMedia\n"));
9601 inquiryData->RemovableMedia = 1;
9602 }
9603 // Set the Relative Addressing (LBA) bit, if applicable.
9604 if (LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
9605 inquiryData->RelativeAddressing = 1;
9607 "RelativeAddressing\n"));
9608 }
9609 // Set the CommandQueue bit
9610 inquiryData->CommandQueue = 1;
9611
9612 // Fill in vendor identification fields.
9613#ifdef __REACTOS__
9614 FillDeviceIdentificationString(inquiryData, identifyData);
9615#else
9616 for (i = 0; i < 24; i += 2) {
9617 MOV_DW_SWP(inquiryData->DeviceIdentificationString[i], ((PUCHAR)identifyData->ModelNumber)[i]);
9618 }
9619#endif
9620
9621 // Move firmware revision from IDENTIFY data to
9622 // product revision in INQUIRY data.
9623 for (i = 0; i < 4; i += 2) {
9624 MOV_DW_SWP(inquiryData->ProductRevisionLevel[i], ((PUCHAR)identifyData->FirmwareRevision)[i]);
9625 }
9626
9628 }
9629 }
9630
9632#endif
9633 status = AtapiSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
9634 } else {
9635 KdPrint2((PRINT_PREFIX "Try IDE send\n"));
9636/* {
9637 ULONG __ebp__ = 0;
9638 ULONG __esp__ = 0;
9639
9640 KdPrint2((PRINT_PREFIX "** before IdeSendCommand:\n"));
9641 __asm {
9642 mov eax,ebp
9643 mov __ebp__, eax
9644 mov eax,esp
9645 mov __esp__, eax
9646 }
9647 KdPrint2((PRINT_PREFIX "** before Ide: EBP:%#x ESP:%#x\n", __ebp__, __esp__));
9648 }*/
9649 status = IdeSendCommand(HwDeviceExtension, Srb, CMD_ACTION_ALL);
9650 }
9651/* KeBugCheckEx(0xc000000e,
9652 (Srb->PathId<<16) | (Srb->TargetId<<8) | (Srb->Lun),
9653 Srb->Function,
9654 status, 0x80000002);*/
9655
9656 }
9657//skip_exec:
9658 TopLevel = FALSE;
9659
9660 break;
9661
9663
9664 tmpSrb = ScsiPortGetSrb(HwDeviceExtension, Srb->PathId, Srb->TargetId, Srb->Lun,
9665 Srb->QueueTag);
9666 // Verify that SRB to abort is still outstanding.
9667 if((tmpSrb != Srb->NextSrb) ||
9668 !chan->queue_depth) {
9669
9670 KdPrint2((PRINT_PREFIX "AtapiStartIo: SRB to abort already completed\n"));
9671
9672 // Complete abort SRB.
9674 break;
9675 }
9676
9677 AtaReq = (PATA_REQ)(tmpSrb->SrbExtension);
9679 if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_CURRENT)) {
9680 KdPrint2((PRINT_PREFIX "AtapiStartIo: Abort command failed\n"));
9681 // Log reset failure.
9683 "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d)\n",
9684 HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
9685 ));
9686 ScsiPortLogError(HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8);
9688
9689 } else {
9691 }
9692 } else {
9693 KdPrint2((PRINT_PREFIX "AtapiInterrupt: remove aborted srb %#x\n", tmpSrb));
9694 if (tmpSrb->SenseInfoBuffer &&
9695 tmpSrb->SenseInfoBufferLength >= sizeof(SENSE_DATA)) {
9696
9697 PSENSE_DATA senseBuffer = (PSENSE_DATA)tmpSrb->SenseInfoBuffer;
9698
9699 senseBuffer->ErrorCode = 0;
9700 senseBuffer->Valid = 1;
9701 senseBuffer->AdditionalSenseLength = 0xb;
9702 senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
9703 senseBuffer->AdditionalSenseCode = 0;
9704 senseBuffer->AdditionalSenseCodeQualifier = 0;
9705
9707 }
9708 AtapiDmaDBSync(chan, tmpSrb);
9709 UniataRemoveRequest(chan, tmpSrb);
9710 // Indicate command complete.
9712 deviceExtension,
9713 tmpSrb);
9715 }
9716 break;
9717
9718 // Abort function indicates that a request timed out.
9719 // Call reset routine. Card will only be reset if
9720 // status indicates something is wrong.
9721 // Fall through to reset code.
9722
9725
9726 // Reset single device.
9727 // For now we support only Lun=0
9728
9729 // Note: reset is immediate command, it cannot be queued since it is usually used to
9730 // revert not-responding device to operational state
9731 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device request received\n"));
9732 UniataUserDeviceReset(deviceExtension, LunExt, lChannel);
9734 break;
9735
9737do_bus_reset:
9738 // Reset Atapi and SCSI bus.
9739
9740 // Note: reset is immediate command, it cannot be queued since it is usually used to
9741 // revert not- responding device to operational state
9742 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus request received\n"));
9743 if (!AtapiResetController__(deviceExtension, lChannel, RESET_COMPLETE_ALL)) {
9744 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset bus failed\n"));
9745 // Log reset failure.
9747 "ScsiPortLogError: devExt %#x, Srb %#x, P:T:D=%d:%d:%d, MsgId %#x (%d) - (2)\n",
9748 HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8
9749 ));
9750 ScsiPortLogError(HwDeviceExtension, NULL, 0, 0, 0, SP_INTERNAL_ADAPTER_ERROR, 5 << 8);
9752
9753 } else {
9755 }
9756
9757 break;
9758
9760
9761 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown\n"));
9762 if(!LunExt || !(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9763 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - no such device\n"));
9764 } else
9765 if(atapiDev) {
9766 // FLUSH ATAPI device - do nothing
9767 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - ATAPI device\n"));
9768 } else {
9769 // FLUSH IDE/ATA device
9770 KdPrint2((PRINT_PREFIX "AtapiStartIo: Shutdown - IDE device\n"));
9771 AtapiDisableInterrupts(deviceExtension, lChannel);
9772 status = AtaCommand(deviceExtension, DeviceNumber, GET_CHANNEL(Srb),
9773 IDE_COMMAND_FLUSH_CACHE, 0, 0, 0, 0, 0, ATA_WAIT_IDLE);
9774 // If supported & allowed, reset write cacheing
9775 if(LunExt->DeviceFlags & DFLAGS_WCACHE_ENABLED) {
9776
9777 // Disable write cache
9778 status = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9779 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9781 // Check for errors.
9782 if (status & IDE_STATUS_ERROR) {
9784 "AtapiHwInitialize: Disable write cacheing on Device %d failed\n",
9785 DeviceNumber));
9786 }
9787 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
9788
9789 // Re-enable write cache
9790 status = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9791 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9793 // Check for errors.
9794 if (status & IDE_STATUS_ERROR) {
9796 "AtapiHwInitialize: Enable write cacheing on Device %d failed\n",
9797 DeviceNumber));
9798 LunExt->DeviceFlags &= ~DFLAGS_WCACHE_ENABLED;
9799 } else {
9801 }
9802 }
9803
9804 AtapiEnableInterrupts(deviceExtension, lChannel);
9805 }
9807
9808 break;
9809
9810 case SRB_FUNCTION_FLUSH:
9811
9812 KdPrint2((PRINT_PREFIX "AtapiStartIo: Flush (do nothing)\n"));
9814 break;
9815
9817
9818 ULONG len;
9819
9820 KdPrint2((PRINT_PREFIX "AtapiStartIo: SRB_FUNCTION_IO_CONTROL\n"));
9821
9823
9824 if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature),"SCSIDISK",sizeof("SCSIDISK")-1)) {
9825
9826 ULONG targetId = (ULONG)(-1);
9827
9828 if(len < sizeof(SRB_IO_CONTROL)) {
9829 goto wrong_buffer_size;
9830 }
9831
9832 // extract bogus bus address
9833 switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
9835 PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9836
9837 if(len < sizeof(SRB_IO_CONTROL)+sizeof(GETVERSIONINPARAMS)) {
9838 goto wrong_buffer_size;
9839 }
9840
9841 targetId = versionParameters->bIDEDeviceMap;
9842 KdPrint2((PRINT_PREFIX "targetId (smart ver) %d\n", targetId));
9843 break; }
9856 {
9857 PSENDCMDINPARAMS cmdInParameters = (PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9858
9859 if(len < sizeof(SRB_IO_CONTROL)+sizeof(SENDCMDINPARAMS) - 1) {
9860 goto wrong_buffer_size;
9861 }
9862
9863 targetId = cmdInParameters->bDriveNumber;
9864 KdPrint2((PRINT_PREFIX "targetId (smart/ident) %d\n", targetId));
9865 break; }
9866 default:
9867invalid_request:
9868 KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for SCSIDISK signature\n",
9869 ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode ));
9871 goto complete_req;
9872 } // end switch()
9873
9874 // adjust (if necessary) bus address
9875 if(targetId != (ULONG)(-1)) {
9876
9877 // This is done because of how the IOCTL_SCSI_MINIPORT
9878 // determines 'targetid's'. Disk.sys places the real target id value
9879 // in the DeviceMap field. Once we do some parameter checking, the value passed
9880 // back to the application will be determined.
9881
9882 if (deviceExtension->NumberChannels == 1) {
9883 // do this for legacy controllers and legacy callers
9884 KdPrint2((PRINT_PREFIX "AtapiStartIo: legacy call\n"));
9885 DeviceNumber = (targetId & 0x01);
9886 lChannel = 0;
9887 } else
9888 if(commPort) {
9889 // do this for smartmontools, sending IOCTLs to PhysicalDrive%d
9890 // due to DISK.SYS design bug, we have invalid SCSI address in SRB
9891 KdPrint2((PRINT_PREFIX "AtapiStartIo: legacy call (2)\n"));
9892 if(deviceExtension->HwFlags & UNIATA_AHCI) {
9893 lChannel = (UCHAR)targetId / 2;
9894 DeviceNumber = 0;
9895 } else {
9896 lChannel = (UCHAR)(targetId / 2);
9897 DeviceNumber = targetId & 0x01;
9898 }
9899 } else {
9900 // otherwise assume lChannel and DeviceNumber from Srb are ok
9901 }
9902 if(lChannel >= deviceExtension->NumberChannels ||
9903 DeviceNumber >= deviceExtension->NumberLuns) {
9905 "AtapiStartIo: SCSIDISK IOCTL for non-exestent drive %d -> EXECUTE_SCSI rejected (2)\n",
9906 targetId));
9907 // Indicate no device found at this address.
9908 goto reject_srb;
9909 }
9910 targetId = lChannel*deviceExtension->NumberLuns+DeviceNumber;
9911 chan = &(deviceExtension->chan[lChannel]);
9912 LunExt = chan->lun[DeviceNumber];
9913 if(!LunExt) {
9914 goto reject_srb;
9915 }
9916 atapiDev = (LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) ? TRUE : FALSE;
9917
9918 if (!(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
9919 goto reject_srb;
9920 }
9921 }
9922
9923 switch (((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode) {
9925
9926 PGETVERSIONINPARAMS versionParameters = (PGETVERSIONINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9927 UCHAR deviceNumberMap;
9928
9929 KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_SMART_VERSION\n"));
9930
9931 // Version and revision per SMART 1.03
9932
9933 versionParameters->bVersion = 1;
9934 versionParameters->bRevision = 1;
9935 versionParameters->bReserved = 0;
9936
9937 // Indicate that support for IDE IDENTIFY, ATAPI IDENTIFY and SMART commands.
9939
9940 if (atapiDev) {
9941 goto invalid_request;
9942 }
9943
9944 // NOTE: This will only set the bit
9945 // corresponding to this drive's target id.
9946 // The bit mask is as follows:
9947 //
9948 // -Sec Pri
9949 // S M S M
9950 // 3 2 1 0
9951
9952 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
9953 deviceNumberMap = 1 << lChannel;
9954 DeviceNumber = 0;
9955 } else
9956 if (deviceExtension->NumberChannels == 1) {
9957 if (chan->PrimaryAddress) {
9958 deviceNumberMap = 1 << DeviceNumber;
9959 } else {
9960 deviceNumberMap = 4 << DeviceNumber;
9961 }
9962 } else {
9963 deviceNumberMap = 1 << (DeviceNumber+lChannel*2);
9964 }
9965
9966 versionParameters->bIDEDeviceMap = deviceNumberMap;
9967
9969 break;
9970 }
9971
9973
9974 PSENDCMDOUTPARAMS cmdOutParameters = (PSENDCMDOUTPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9975 SENDCMDINPARAMS cmdInParameters = *(PSENDCMDINPARAMS)(((PUCHAR)Srb->DataBuffer) + sizeof(SRB_IO_CONTROL));
9976
9977 KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_IDENTIFY\n"));
9978 // Extract the target.
9979 KdPrint2((PRINT_PREFIX "targetId %d\n", targetId));
9980
9981 switch(cmdInParameters.irDriveRegs.bCommandReg) {
9982 case ID_CMD:
9983 if(atapiDev) {
9984 KdPrint2((PRINT_PREFIX "Error: ID_CMD for ATAPI\n"));
9985 goto invalid_request;
9986 }
9987 /* FALL THROUGH */
9988 case ATAPI_ID_CMD:
9989
9990 if(!atapiDev &&
9991 (cmdInParameters.irDriveRegs.bCommandReg == ATAPI_ID_CMD)) {
9992 KdPrint2((PRINT_PREFIX "Error: ATAPI_ID_CMD for non-ATAPI\n"));
9993 goto invalid_request;
9994 }
9995
9997 // Zero the output buffer
9998 RtlZeroMemory(cmdOutParameters, len);
9999/* for (i = 0; i < (sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1); i++) {
10000 ((PUCHAR)cmdOutParameters)[i] = 0;
10001 }*/
10002
10003 // Build status block.
10004 cmdOutParameters->cBufferSize = min(IDENTIFY_BUFFER_SIZE, len - sizeof(SENDCMDOUTPARAMS) + 1);
10005 cmdOutParameters->DriverStatus.bDriverError = 0;
10006 cmdOutParameters->DriverStatus.bIDEError = 0;
10007
10008 // Extract the identify data from the device extension.
10009 ScsiPortMoveMemory (cmdOutParameters->bBuffer, &(LunExt->IdentifyData),
10010 cmdOutParameters->cBufferSize);
10011
10012 if((cmdOutParameters->cBufferSize == IDENTIFY_BUFFER_SIZE) &&
10013 (LunExt->IdentifyData.ChecksumValid == ATA_ChecksumValid)) {
10014 // adjust checksum if it is possible
10015 CHAR csum = 0;
10016 ULONG i;
10017
10018 for(i=0; i < IDENTIFY_BUFFER_SIZE-1; i++) {
10019 csum += (CHAR)(cmdOutParameters->bBuffer[i]);
10020 }
10021 cmdOutParameters->bBuffer[i] = -csum;
10022 KdPrint2((PRINT_PREFIX "AtapiStartIo: adjust checksum %d\n"));
10023 }
10024 KdPrint2((PRINT_PREFIX "AtapiStartIo: IOCTL_SCSI_MINIPORT_IDENTIFY Ok\n"));
10025
10027
10028 break;
10029 default:
10030 KdPrint2((PRINT_PREFIX "AtapiStartIo: not supported ID code %x\n",
10031 cmdInParameters.irDriveRegs.bCommandReg));
10033 break;
10034 }
10035 break;
10036 }
10037/*
10038 case IOCTL_SCSI_MINIPORT_READ_SMART_ATTRIBS:
10039 case IOCTL_SCSI_MINIPORT_READ_SMART_THRESHOLDS:
10040 case IOCTL_SCSI_MINIPORT_ENABLE_SMART:
10041 case IOCTL_SCSI_MINIPORT_DISABLE_SMART:
10042 case IOCTL_SCSI_MINIPORT_RETURN_STATUS:
10043 case IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTOSAVE:
10044 case IOCTL_SCSI_MINIPORT_SAVE_ATTRIBUTE_VALUES:
10045 case IOCTL_SCSI_MINIPORT_EXECUTE_OFFLINE_DIAGS:
10046*/
10047 default:
10048 // *all* IOCTLs here are SMART
10049 if(commPort) {
10051 "AtapiStartIo: SCSIDISK Smart IOCTL for commPort -> EXECUTE_SCSI rejected (3)\n"));
10052 }
10053 if (atapiDev) {
10054 goto invalid_request;
10055 }
10056
10057 PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
10058
10059 if(PostReq || TopLevel) {
10060 UniataQueueRequest(chan, Srb);
10061 AtaReq = (PATA_REQ)(Srb->SrbExtension);
10062 AtaReq->ReqState = REQ_STATE_QUEUED;
10063 }
10064
10065 if(PostReq) {
10066
10067 KdPrint2((PRINT_PREFIX "Non-empty queue (SMART)\n"));
10069
10070 KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
10071 } else {
10072
10073 status = IdeSendSmartCommand(HwDeviceExtension, Srb, targetId);
10074 }
10075 break;
10076
10077 // we should not get here, checked above
10078/* default :
10079 KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for SCSIDISK signature\n",
10080 ((PSRB_IO_CONTROL)(Srb->DataBuffer))->ControlCode ));
10081 status = SRB_STATUS_INVALID_REQUEST;
10082 break;
10083*/
10084 }
10085 } else
10086 if(!AtapiStringCmp( (PCHAR)(((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature),"-UNIATA-", sizeof("-UNIATA-")-1)) {
10087
10089 //ULONG ldev = GET_LDEV2(AtaCtl->addr.PathId, AtaCtl->addr.TargetId, 0);
10090 ULONG DeviceNumber = AtaCtl->addr.TargetId;
10091 BOOLEAN bad_ldev;
10092 ULONG i, pos;
10093
10094 pos = FIELD_OFFSET(UNIATA_CTL, RawData);
10095 //chan = &(deviceExtension->chan[lChannel]);
10096 if(len < pos) {
10097 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10098 FIELD_OFFSET(UNIATA_CTL, RawData) ));
10099 goto wrong_buffer_size;
10100 }
10101
10102 if(AtaCtl->addr.Lun ||
10103 AtaCtl->addr.TargetId >= deviceExtension->NumberLuns ||
10104 AtaCtl->addr.PathId >= deviceExtension->NumberChannels) {
10105
10106 chan = NULL;
10107 bad_ldev = TRUE;
10108 LunExt = NULL;
10109
10110 } else {
10111 bad_ldev = FALSE;
10112 lChannel = AtaCtl->addr.PathId;
10113 chan = &(deviceExtension->chan[lChannel]);
10114 LunExt = chan->lun[DeviceNumber];
10115 }
10116
10117 KdPrint2((PRINT_PREFIX "AtapiStartIo: -UNIATA- %#x, dev %#x\n", AtaCtl->hdr.ControlCode, DeviceNumber));
10118
10119 /* check for valid LUN */
10120 switch (AtaCtl->hdr.ControlCode) {
10123 // this would be BUS reset
10124 if(bad_ldev &&
10125 (AtaCtl->addr.PathId >= deviceExtension->NumberChannels ||
10126 AtaCtl->addr.TargetId != 0xff ||
10127 AtaCtl->addr.Lun != 0
10128 )) {
10130 DeviceNumber < deviceExtension->NumberLuns) { // AtaCtl->addr.TargetId != 0xff
10131 lChannel = AtaCtl->addr.PathId;
10132 chan = &(deviceExtension->chan[lChannel]);
10133 LunExt = chan->lun[DeviceNumber];
10134 // OK
10135 } else {
10136 goto handle_bad_ldev;
10137 }
10138 } else {
10139 lChannel = AtaCtl->addr.PathId;
10140 chan = &(deviceExtension->chan[lChannel]);
10141 }
10142 break;
10147// case IOCTL_SCSI_MINIPORT_UNIATA_REG_IO:
10148 if(bad_ldev) {
10149handle_bad_ldev:
10151 "AtapiStartIo: bad_ldev -> IOCTL SRB rejected\n"));
10152 // Indicate no device found at this address.
10153 goto reject_srb;
10154 }
10155 }
10156
10157 /* check if queueing is necessary */
10158 switch (AtaCtl->hdr.ControlCode) {
10160 if(!LunExt->nBadBlocks) {
10161 break;
10162 }
10163 goto uata_ctl_queue;
10165 if(len < pos+sizeof(AtaCtl->SetMode)) {
10166 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10167 pos+sizeof(AtaCtl->SetMode) ));
10168 goto wrong_buffer_size;
10169 }
10170 if(!AtaCtl->SetMode.ApplyImmediately) {
10171 break;
10172 }
10173 goto uata_ctl_queue;
10175 //case IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE: reset must be processed immediately
10176uata_ctl_queue:
10177 KdPrint2((PRINT_PREFIX "put to queue (UNIATA)\n"));
10178 PostReq = UniataNeedQueueing(deviceExtension, chan, TopLevel);
10179
10180 if(PostReq || TopLevel) {
10181 UniataQueueRequest(chan, Srb);
10182 AtaReq = (PATA_REQ)(Srb->SrbExtension);
10183 AtaReq->ReqState = REQ_STATE_QUEUED;
10184 }
10185 if(PostReq) {
10186 KdPrint2((PRINT_PREFIX "Non-empty queue (UNIATA)\n"));
10188
10189 KdPrint2((PRINT_PREFIX "AtapiStartIo: Already have %d request(s)!\n", chan->queue_depth));
10190 goto complete_req;
10191 }
10192 } // end switch (AtaCtl->hdr.ControlCode)
10193
10194 /* process request */
10195 switch (AtaCtl->hdr.ControlCode) {
10197
10198 KdPrint2((PRINT_PREFIX "AtapiStartIo: rescan bus\n"));
10199
10200 if(len < pos+sizeof(AtaCtl->FindDelDev)) {
10201 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10202 pos+sizeof(AtaCtl->FindDelDev) ));
10203 goto wrong_buffer_size;
10204 }
10206 KdPrint2((PRINT_PREFIX "AtapiStartIo: unhide from further detection\n"));
10207 if(AtaCtl->addr.TargetId != 0xff) {
10208 LunExt->DeviceFlags &= ~DFLAGS_HIDDEN;
10209 } else {
10210 }
10211 }
10212
10213 for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
10214 AtapiStallExecution(1000 * 1000);
10215 }
10216
10217 FindDevices(HwDeviceExtension,
10218 ((AtaCtl->addr.TargetId == 0xff) && (AtaCtl->FindDelDev.Flags & UNIATA_ADD_FLAGS_UNHIDE))
10220 AtaCtl->addr.PathId);
10222
10223 break;
10224
10226
10227 KdPrint2((PRINT_PREFIX "AtapiStartIo: remove %#x:%#x\n", AtaCtl->addr.PathId, AtaCtl->addr.TargetId));
10228
10229 if(len < pos+sizeof(AtaCtl->FindDelDev)) {
10230 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10231 pos+sizeof(AtaCtl->FindDelDev) ));
10232 goto wrong_buffer_size;
10233 }
10234 LunExt->DeviceFlags = 0;
10236 KdPrint2((PRINT_PREFIX "AtapiStartIo: hide from further detection\n"));
10237 //LunExt->DeviceFlags |= DFLAGS_HIDDEN;
10238 UniataForgetDevice(LunExt);
10239 }
10240
10241 for(i=0; i<AtaCtl->FindDelDev.WaitForPhysicalLink && i<30; i++) {
10242 AtapiStallExecution(1000 * 1000);
10243 }
10244
10246 break;
10247 }
10249
10250 KdPrint2((PRINT_PREFIX "AtapiStartIo: Set transfer mode\n"));
10251
10252 if(len < pos+sizeof(AtaCtl->SetMode)) {
10253 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10254 pos+sizeof(AtaCtl->SetMode) ));
10255 goto wrong_buffer_size;
10256 }
10257 if(AtaCtl->SetMode.OrigMode != IOMODE_NOT_SPECIFIED) {
10258 LunExt->OrigTransferMode = (UCHAR)(AtaCtl->SetMode.OrigMode);
10259 }
10260 if(AtaCtl->SetMode.MaxMode != IOMODE_NOT_SPECIFIED) {
10261 LunExt->LimitedTransferMode = (UCHAR)(AtaCtl->SetMode.MaxMode);
10262 if(LunExt->LimitedTransferMode >
10263 LunExt->OrigTransferMode) {
10264 // check for incorrect value
10265 LunExt->LimitedTransferMode =
10266 LunExt->OrigTransferMode;
10267 }
10268 }
10269 LunExt->TransferMode = min(LunExt->LimitedTransferMode, LunExt->OrigTransferMode);
10270
10271 LunExt->DeviceFlags |= DFLAGS_REINIT_DMA; // force PIO/DMA reinit
10272 if(AtaCtl->SetMode.ApplyImmediately) {
10273 AtapiDmaInit__(deviceExtension, LunExt);
10274 }
10275/* LunExt->TransferMode =
10276 LunExt->LimitedTransferMode = (UCHAR)(setTransferMode->Mode);*/
10278 break;
10279 }
10281
10282 KdPrint2((PRINT_PREFIX "AtapiStartIo: Get transfer mode\n"));
10283
10284 if(len < pos+sizeof(AtaCtl->GetMode)) {
10285 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10286 pos+sizeof(AtaCtl->GetMode) ));
10287 goto wrong_buffer_size;
10288 }
10289 AtaCtl->GetMode.OrigMode = LunExt->OrigTransferMode;
10290 AtaCtl->GetMode.MaxMode = LunExt->LimitedTransferMode;
10291 AtaCtl->GetMode.CurrentMode = LunExt->TransferMode;
10292 AtaCtl->GetMode.PhyMode = LunExt->PhyTransferMode;
10293
10295 break;
10296 }
10298
10299 KdPrint2((PRINT_PREFIX "AtapiStartIo: Get version\n"));
10300
10301 if(len < pos+sizeof(AtaCtl->Version)) {
10302 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10303 pos+sizeof(AtaCtl->Version) ));
10304 goto wrong_buffer_size;
10305 }
10306 AtaCtl->Version.Length = sizeof(GETDRVVERSION);
10311
10313 break;
10314 }
10316
10317 KdPrint2((PRINT_PREFIX "AtapiStartIo: Get adapter info\n"));
10318
10319 if(len < pos+sizeof(AtaCtl->AdapterInfo)) {
10320 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtaCtl Buffer too small: %#x < %#x\n", len,
10321 pos+sizeof(AtaCtl->AdapterInfo) ));
10322 goto wrong_buffer_size;
10323 }
10324 AtaCtl->AdapterInfo.HeaderLength = sizeof(ADAPTERINFO);
10325
10326 AtaCtl->AdapterInfo.DevID = deviceExtension->DevID;
10327 AtaCtl->AdapterInfo.RevID = deviceExtension->RevID;
10328 AtaCtl->AdapterInfo.slotNumber = deviceExtension->slotNumber;
10329 AtaCtl->AdapterInfo.SystemIoBusNumber = deviceExtension->SystemIoBusNumber;
10330 AtaCtl->AdapterInfo.DevIndex = deviceExtension->DevIndex;
10331 AtaCtl->AdapterInfo.Channel = deviceExtension->Channel;
10332 AtaCtl->AdapterInfo.HbaCtrlFlags = deviceExtension->HbaCtrlFlags;
10333 AtaCtl->AdapterInfo.simplexOnly= deviceExtension->simplexOnly;
10334 AtaCtl->AdapterInfo.MemIo = FALSE;/*deviceExtension->MemIo;*/
10335 AtaCtl->AdapterInfo.UnknownDev = deviceExtension->UnknownDev;
10336 AtaCtl->AdapterInfo.MasterDev = deviceExtension->MasterDev;
10337 AtaCtl->AdapterInfo.MaxTransferMode = deviceExtension->MaxTransferMode;
10338 AtaCtl->AdapterInfo.HwFlags = deviceExtension->HwFlags;
10340 AtaCtl->AdapterInfo.BusInterruptLevel = deviceExtension->BusInterruptLevel;
10341 AtaCtl->AdapterInfo.InterruptMode = deviceExtension->InterruptMode;
10342 AtaCtl->AdapterInfo.BusInterruptVector = deviceExtension->BusInterruptVector;
10343 AtaCtl->AdapterInfo.NumberChannels = deviceExtension->NumberChannels;
10344 AtaCtl->AdapterInfo.NumberLuns = (UCHAR)deviceExtension->NumberLuns;
10345 AtaCtl->AdapterInfo.AdapterInterfaceType = deviceExtension->AdapterInterfaceType;
10346 if(deviceExtension->FullDevName) {
10347 strncpy(AtaCtl->AdapterInfo.DeviceName, deviceExtension->FullDevName, 64);
10348 }
10350 AtaCtl->AdapterInfo.LunInfoValid = FALSE;
10352
10353 pos += AtaCtl->AdapterInfo.HeaderLength;
10354
10355 // zero tail
10356 RtlZeroMemory(((PCHAR)AtaCtl)+pos,
10357 len-pos);
10358
10359 if(len >= pos+AtaCtl->AdapterInfo.NumberChannels*sizeof(CHANINFO)) {
10360 PCHANINFO ChanInfo = (PCHANINFO)( ((PCHAR)AtaCtl)+pos );
10361 PHW_CHANNEL cur_chan;
10362 KdPrint2((PRINT_PREFIX "AtapiStartIo: Fill channel info\n"));
10363 for(i=0;i<AtaCtl->AdapterInfo.NumberChannels;i++) {
10364 KdPrint2((PRINT_PREFIX "chan[%d] %x\n", i, cur_chan));
10365 cur_chan = &(deviceExtension->chan[i]);
10366 ChanInfo->MaxTransferMode = cur_chan->MaxTransferMode;
10367 ChanInfo->ChannelCtrlFlags = cur_chan->ChannelCtrlFlags;
10368 RtlCopyMemory(&(ChanInfo->QueueStat), &(cur_chan->QueueStat), sizeof(ChanInfo->QueueStat));
10369 ChanInfo->ReorderCount = cur_chan->ReorderCount;
10370 ChanInfo->IntersectCount = cur_chan->IntersectCount;
10371 ChanInfo->TryReorderCount = cur_chan->TryReorderCount;
10372 ChanInfo->TryReorderHeadCount = cur_chan->TryReorderHeadCount;
10373 ChanInfo->TryReorderTailCount = cur_chan->TryReorderTailCount;
10374 //ChanInfo->opt_MaxTransferMode = cur_chan->opt_MaxTransferMode;
10375 ChanInfo++;
10376 }
10377 AtaCtl->AdapterInfo.ChanInfoValid = TRUE;
10378 AtaCtl->AdapterInfo.ChanHeaderLength = sizeof(*ChanInfo);
10379 }
10380
10382 break;
10383 }
10385
10386 KdPrint2((PRINT_PREFIX "AtapiStartIo: Forget BB list\n"));
10387
10388 ForgetBadBlocks(LunExt);
10389
10391 break;
10392 }
10394
10395 KdPrint2((PRINT_PREFIX "AtapiStartIo: Reset device\n"));
10396
10397 if(bad_ldev) {
10398 goto do_bus_reset;
10399 } else {
10400 UniataUserDeviceReset(deviceExtension, LunExt, AtaCtl->addr.PathId);
10401 }
10402
10404 break;
10405 }
10406 default :
10407 KdPrint2((PRINT_PREFIX "AtapiStartIo: invalid IoControl %#x for -UNIATA- signature\n",
10408 AtaCtl->hdr.ControlCode ));
10410 break;
10411 }
10412
10413 } else {
10414 KdPrint2((PRINT_PREFIX "AtapiStartIo: IoControl signature incorrect. Send %s, expected %s or %s\n",
10415 ((PSRB_IO_CONTROL)(Srb->DataBuffer))->Signature,
10416 "SCSIDISK", "-UNIATA-"));
10417
10419 break;
10420 }
10421
10422 break;
10423 } // end SRB_FUNCTION_IO_CONTROL
10424 default:
10425
10426 KdPrint2((PRINT_PREFIX "AtapiStartIo: Unknown IOCTL\n"));
10427 // Indicate unsupported command.
10429
10430// break;
10431
10432 } // end switch
10433
10434complete_req:
10435
10436 PathId = Srb->PathId;
10438 Lun = Srb->Lun;
10439
10440 if (status != SRB_STATUS_PENDING) {
10441
10443 "AtapiStartIo: Srb %#x complete with status %#x\n",
10444 Srb,
10445 status));
10446
10447 // Set status in SRB.
10449
10450 if(chan && Srb) {
10451 KdPrint2((PRINT_PREFIX "AtapiStartIo: AtapiDmaDBSync(%x, %x)\n", chan, Srb));
10452 AtapiDmaDBSync(chan, Srb);
10453 }
10454 KdPrint2((PRINT_PREFIX "AtapiStartIo: UniataRemoveRequest(%x, %x)\n", chan, Srb));
10455 UniataRemoveRequest(chan, Srb);
10456 // Indicate command complete.
10457 KdPrint2((PRINT_PREFIX "AtapiStartIo: ScsiPortNotification\n"));
10459 deviceExtension,
10460 Srb);
10461
10462 KdPrint2((PRINT_PREFIX "AtapiStartIo: UniataGetCurRequest\n"));
10463 // Remove current Srb & get next one
10464 if((Srb = UniataGetCurRequest(chan))) {
10465 AtaReq = (PATA_REQ)(Srb->SrbExtension);
10466 if(AtaReq->ReqState > REQ_STATE_QUEUED) {
10467 // current request is under precessing, thus
10468 // we should do nothing here
10469 Srb = NULL;
10470 }
10471 }
10472 KdPrint2((PRINT_PREFIX "AtapiStartIo: chan %x, Src %x\n", chan, Srb));
10473 if(!chan) {
10474 //ASSERT(TopLevel);
10475 }
10476 }
10477 KdPrint2((PRINT_PREFIX "AtapiStartIo: next Srb %x\n", Srb));
10478
10479 } while (Srb && (status != SRB_STATUS_PENDING));
10480
10481 KdPrint2((PRINT_PREFIX "AtapiStartIo: query PORT for next request\n"));
10482 // Indicate ready for next request.
10484 deviceExtension,
10485 NULL);
10486
10488 deviceExtension,
10489 PathId,
10490 TargetId,
10491 Lun);
10492
10493 return TRUE;
10494
10495} // end AtapiStartIo__()
char * strncpy(char *DstString, const char *SrcString, ACPI_SIZE Count)
Definition: utclib.c:427
#define MOV_DW_SWP(a, b)
Definition: atactl.cpp:20
#define DFLAGS_REMOVABLE_DRIVE
Definition: atapi.h:45
void NTAPI ForgetBadBlocks(IN PHW_LU_EXTENSION LunExt)
struct _SENDCMDINPARAMS SENDCMDINPARAMS
#define ATAPI_ID_CMD
Definition: helper.h:19
#define CHAR(Char)
PSCSI_REQUEST_BLOCK NTAPI ScsiPortGetSrb(IN PVOID DeviceExtension, IN UCHAR PathId, IN UCHAR TargetId, IN UCHAR Lun, IN LONG QueueTag)
Definition: scsiport.c:658
VOID NTAPI AtapiDmaInit__(IN PHW_DEVICE_EXTENSION deviceExtension, IN PHW_LU_EXTENSION LunExt)
Definition: id_dma.cpp:857
#define ATA_WAIT_IDLE
Definition: bsmaster.h:63
#define ATA_WAIT_BASE_READY
Definition: bsmaster.h:62
PBUSMASTER_CONTROLLER_INFORMATION BMList
Definition: id_probe.cpp:53
#define COMMUNICATION_DEVICE
Definition: cdrw_hw.h:1153
struct _INQUIRYDATA * PINQUIRYDATA
#define SCSIOP_INQUIRY
Definition: cdrw_hw.h:888
#define READ_ONLY_DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1149
#define SCSI_SENSE_ABORTED_COMMAND
Definition: cdrw_hw.h:1198
#define IOCTL_SCSI_MINIPORT_WRITE_SMART_LOG
Definition: scsi.h:1421
#define IOCTL_SCSI_MINIPORT_READ_SMART_LOG
Definition: scsi.h:1420
#define IOCTL_SCSI_MINIPORT_ENABLE_DISABLE_AUTO_OFFLINE
Definition: scsi.h:1419
#define SRB_FUNCTION_RESET_DEVICE
Definition: srb.h:327
#define SRB_FUNCTION_RESET_LOGICAL_UNIT
Definition: srb.h:334
#define SRB_FUNCTION_FLUSH
Definition: srb.h:323
#define SRB_FUNCTION_SHUTDOWN
Definition: srb.h:322
IN PFCB IN PCCB IN TYPE_OF_OPEN IN BOOLEAN IN BOOLEAN TopLevel
Definition: fatprocs.h:2417
GLenum GLsizei len
Definition: glext.h:6722
VOID NTAPI UniataForgetDevice(PHW_LU_EXTENSION LunExt)
Definition: id_ata.cpp:2385
ULONG NTAPI IdeSendSmartCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG targetId)
Definition: id_ata.cpp:6697
UCHAR NTAPI AtaCommand(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN USHORT cylinder, IN UCHAR head, IN UCHAR sector, IN UCHAR count, IN UCHAR feature, IN ULONG wait_flags)
Definition: id_ata.cpp:1168
VOID NTAPI UniataUserDeviceReset(PHW_DEVICE_EXTENSION deviceExtension, PHW_LU_EXTENSION LunExt, ULONG lChannel)
Definition: id_ata.cpp:9198
ULONG NTAPI IdeSendCommand(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
Definition: id_ata.cpp:8233
BOOLEAN NTAPI UniataNeedQueueing(PHW_DEVICE_EXTENSION deviceExtension, PHW_CHANNEL chan, BOOLEAN TopLevel)
Definition: id_ata.cpp:9224
#define RESET_COMPLETE_ALL
Definition: id_ata.cpp:144
static const CHAR uniata_comm_name[]
Definition: id_ata.cpp:67
VOID NTAPI UniataQueueRequest(IN PHW_CHANNEL chan, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_queue.cpp:93
#define min(a, b)
Definition: monoChain.cc:55
struct _GETVERSIONINPARAMS GETVERSIONINPARAMS
ULONG Channel
Definition: uata_ctl.h:124
CHAR DeviceName[64]
Definition: uata_ctl.h:136
ULONG BusInterruptLevel
Definition: uata_ctl.h:138
ULONG DevID
Definition: uata_ctl.h:118
BOOLEAN ChanHeaderLengthValid
Definition: uata_ctl.h:150
ULONG MaxTransferMode
Definition: uata_ctl.h:132
UCHAR NumberLuns
Definition: uata_ctl.h:148
ULONG NumberChannels
Definition: uata_ctl.h:145
ULONG RevID
Definition: uata_ctl.h:119
BOOLEAN MemIo
Definition: uata_ctl.h:128
ULONG InterruptMode
Definition: uata_ctl.h:139
BOOLEAN UnknownDev
Definition: uata_ctl.h:129
BOOLEAN MasterDev
Definition: uata_ctl.h:130
ULONG HwFlags
Definition: uata_ctl.h:133
BOOLEAN ChanInfoValid
Definition: uata_ctl.h:146
ULONG DevIndex
Definition: uata_ctl.h:122
ULONG HbaCtrlFlags
Definition: uata_ctl.h:126
ULONG slotNumber
Definition: uata_ctl.h:120
BOOLEAN LunInfoValid
Definition: uata_ctl.h:149
ULONG OrigAdapterInterfaceType
Definition: uata_ctl.h:134
ULONG AdapterInterfaceType
Definition: uata_ctl.h:152
ULONG SystemIoBusNumber
Definition: uata_ctl.h:121
BOOLEAN simplexOnly
Definition: uata_ctl.h:127
ULONG HeaderLength
Definition: uata_ctl.h:117
ULONG BusInterruptVector
Definition: uata_ctl.h:140
ULONG Flags
Definition: uata_ctl.h:73
ULONG WaitForPhysicalLink
Definition: uata_ctl.h:72
ULONG MaxTransferMode
Definition: uata_ctl.h:104
LONGLONG ReorderCount
Definition: uata_ctl.h:107
LONGLONG QueueStat[MAX_QUEUE_STAT]
Definition: uata_ctl.h:106
LONGLONG TryReorderHeadCount
Definition: uata_ctl.h:110
LONGLONG IntersectCount
Definition: uata_ctl.h:108
LONGLONG TryReorderTailCount
Definition: uata_ctl.h:111
LONGLONG TryReorderCount
Definition: uata_ctl.h:109
ULONG ChannelCtrlFlags
Definition: uata_ctl.h:105
USHORT VersionMj
Definition: uata_ctl.h:96
USHORT SubVerMn
Definition: uata_ctl.h:99
USHORT SubVerMj
Definition: uata_ctl.h:98
USHORT VersionMn
Definition: uata_ctl.h:97
ULONG Length
Definition: uata_ctl.h:95
ULONG OrigMode
Definition: uata_ctl.h:89
ULONG CurrentMode
Definition: uata_ctl.h:90
ULONG queue_depth
Definition: bsmaster.h:1027
LONGLONG TryReorderHeadCount
Definition: bsmaster.h:1121
LONGLONG IntersectCount
Definition: bsmaster.h:1119
LONGLONG ReorderCount
Definition: bsmaster.h:1118
LONGLONG TryReorderTailCount
Definition: bsmaster.h:1122
LONGLONG TryReorderCount
Definition: bsmaster.h:1120
LONGLONG QueueStat[MAX_QUEUE_STAT]
Definition: bsmaster.h:1117
ULONG MaxTransferMode
Definition: bsmaster.h:1057
PDEVICE_OBJECT Isr2DevObj
Definition: bsmaster.h:1281
UCHAR OrigTransferMode
Definition: bsmaster.h:1173
UCHAR PhyTransferMode
Definition: bsmaster.h:1174
USHORT FirmwareRevision[4]
Definition: atapi.h:261
UCHAR CommandQueue
Definition: cdrw_hw.h:1125
UCHAR RemovableMedia
Definition: cdrw_hw.h:1119
UCHAR ProductRevisionLevel[4]
Definition: cdrw_hw.h:1134
UCHAR DeviceIdentificationString[28]
Definition: scsi.h:1104
UCHAR RelativeAddressing
Definition: cdrw_hw.h:1131
UCHAR VendorId[8]
Definition: cdrw_hw.h:1132
UCHAR DeviceType
Definition: cdrw_hw.h:1116
UCHAR PathId
Definition: scsi_port.h:149
UCHAR TargetId
Definition: scsi_port.h:150
UCHAR QueueTag
Definition: srb.h:256
struct _SCSI_REQUEST_BLOCK * NextSrb
Definition: srb.h:265
BOOLEAN ApplyImmediately
Definition: uata_ctl.h:83
ULONG OrigMode
Definition: uata_ctl.h:82
ULONG ControlCode
Definition: scsi_port.h:128
SCSI_ADDRESS addr
Definition: uata_ctl.h:296
ADDREMOVEDEV FindDelDev
Definition: uata_ctl.h:300
SRB_IO_CONTROL hdr
Definition: uata_ctl.h:295
GETDRVVERSION Version
Definition: uata_ctl.h:306
ADAPTERINFO AdapterInfo
Definition: uata_ctl.h:303
SETTRANSFERMODE SetMode
Definition: uata_ctl.h:301
GETTRANSFERMODE GetMode
Definition: uata_ctl.h:302
Definition: ffs.h:52
char CCHAR
Definition: typedefs.h:51
#define IOCTL_SCSI_MINIPORT_UNIATA_GET_VERSION
Definition: uata_ctl.h:69
struct _ADAPTERINFO ADAPTERINFO
#define IOCTL_SCSI_MINIPORT_UNIATA_SET_MAX_MODE
Definition: uata_ctl.h:62
#define UNIATA_REMOVE_FLAGS_HIDE
Definition: uata_ctl.h:75
#define UNIATA_ADD_FLAGS_UNHIDE
Definition: uata_ctl.h:76
#define IOCTL_SCSI_MINIPORT_UNIATA_DELETE_DEVICE
Definition: uata_ctl.h:61
#define IOCTL_SCSI_MINIPORT_UNIATA_FIND_DEVICES
Definition: uata_ctl.h:60
#define IOCTL_SCSI_MINIPORT_UNIATA_RESETBB
Definition: uata_ctl.h:66
#define IOCTL_SCSI_MINIPORT_UNIATA_GET_MODE
Definition: uata_ctl.h:63
struct _UNIATA_CTL * PUNIATA_CTL
#define IOCTL_SCSI_MINIPORT_UNIATA_RESET_DEVICE
Definition: uata_ctl.h:67
struct _CHANINFO * PCHANINFO
#define IOCTL_SCSI_MINIPORT_UNIATA_ADAPTER_INFO
Definition: uata_ctl.h:64
struct _GETDRVVERSION GETDRVVERSION
#define SCSIOP_ATA_PASSTHROUGH
Definition: atapi.h:411
#define PrintNtConsole(x)
Definition: atapi.h:1629
#define ATA_C_F_DIS_WCACHE
Definition: atapi.h:564
#define UNIATA_FIND_DEV_UNHIDE
Definition: atapi.h:1360
#define ATA_ChecksumValid
Definition: atapi.h:978
#define DFLAGS_WCACHE_ENABLED
Definition: atapi.h:249
#define IDE_COMMAND_SET_FEATURES
Definition: atapi.h:407
#define DFLAGS_REINIT_DMA
Definition: atapi.h:252
#define IDE_COMMAND_FLUSH_CACHE
Definition: atapi.h:401
ULONG NTAPI UniataAnybodyHome(IN PVOID HwDeviceExtension, IN ULONG Channel, IN ULONG deviceNumber)
Definition: id_probe.cpp:2778
#define UniAtaClearAtaReq(AtaReq)
Definition: atapi.h:1615
#define ATAPI_TYPE_OPTICAL
Definition: atapi.h:624
#define ATA_C_F_ENAB_WCACHE
Definition: atapi.h:563
#define UNIATA_VER_MN
Definition: uniata_ver.h:4
#define UNIATA_VER_MJ
Definition: uniata_ver.h:3
#define UNIATA_VER_SUB_MN
Definition: uniata_ver.h:6
#define UNIATA_VER_SUB_MJ
Definition: uniata_ver.h:5
char CHAR
Definition: xmlstorage.h:175

Referenced by AtapiCallBack__(), AtapiEnableInterrupts__(), AtapiInterrupt__(), and AtapiStartIo().

◆ AtaUmode()

LONG NTAPI AtaUmode ( PIDENTIFY_DATA2  ident)

Definition at line 1254 of file id_ata.cpp.

1255{
1256 if (!ident->UdmaModesValid)
1257 return IOMODE_NOT_SPECIFIED;
1258 if (ident->UltraDMASupport & 0x40)
1259 return 6;
1260 if (ident->UltraDMASupport & 0x20)
1261 return 5;
1262 if (ident->UltraDMASupport & 0x10)
1263 return 4;
1264 if (ident->UltraDMASupport & 0x08)
1265 return 3;
1266 if (ident->UltraDMASupport & 0x04)
1267 return 2;
1268 if (ident->UltraDMASupport & 0x02)
1269 return 1;
1270 if (ident->UltraDMASupport & 0x01)
1271 return 0;
1272 return IOMODE_NOT_SPECIFIED;
1273} // end AtaUmode()

Referenced by AtapiDmaInit__(), AtapiDmaReinit(), and AtaSetTransferMode().

◆ AtaWmode()

LONG NTAPI AtaWmode ( PIDENTIFY_DATA2  ident)

Definition at line 1241 of file id_ata.cpp.

1242{
1243 if (ident->MultiWordDMASupport & 0x04)
1244 return 2;
1245 if (ident->MultiWordDMASupport & 0x02)
1246 return 1;
1247 if (ident->MultiWordDMASupport & 0x01)
1248 return 0;
1249 return IOMODE_NOT_SPECIFIED;
1250} // end AtaWmode()

Referenced by AtapiDmaInit__(), AtapiDmaReinit(), and AtaSetTransferMode().

◆ BuildMechanismStatusSrb()

PSCSI_REQUEST_BLOCK NTAPI BuildMechanismStatusSrb ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 11207 of file id_ata.cpp.

11211{
11212 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11214 PCDB cdb;
11215 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
11216
11217 srb = &(deviceExtension->chan[GET_CHANNEL(Srb)].InternalSrb);
11218
11219 RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
11220
11221 srb->PathId = (UCHAR)(Srb->PathId);
11222 srb->TargetId = (UCHAR)(Srb->TargetId);
11223 srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
11224 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
11225
11226 // Set flags to disable synchronous negociation.
11228
11229 // Set timeout to 4 seconds.
11230 srb->TimeOutValue = 4;
11231
11232 srb->CdbLength = 6;
11233 srb->DataBuffer = &(deviceExtension->chan[GET_CHANNEL(Srb)].MechStatusData);
11234 srb->DataTransferLength = sizeof(MECHANICAL_STATUS_INFORMATION_HEADER);
11235 srb->SrbExtension = AtaReq;
11236
11237 // Set CDB operation code.
11238 cdb = (PCDB)srb->Cdb;
11239 cdb->MECH_STATUS.OperationCode = SCSIOP_MECHANISM_STATUS;
11240 cdb->MECH_STATUS.AllocationLength[1] = sizeof(MECHANICAL_STATUS_INFORMATION_HEADER);
11241
11242 KdPrint2((PRINT_PREFIX " MechanismStatusSrb %#x\n", srb));
11243
11244 return srb;
11245} // end BuildMechanismStatusSrb()
struct _MECHANICAL_STATUS_INFORMATION_HEADER MECHANICAL_STATUS_INFORMATION_HEADER
struct _SCSI_REQUEST_BLOCK SCSI_REQUEST_BLOCK
#define SRB_FLAGS_DISABLE_SYNCH_TRANSFER
Definition: srb.h:397
SCSI_REQUEST_BLOCK InternalSrb
Definition: bsmaster.h:1055
MECHANICAL_STATUS_INFORMATION_HEADER MechStatusData
Definition: bsmaster.h:1052
struct _CDB::_MECH_STATUS MECH_STATUS

Referenced by AtapiInterrupt__(), and AtapiSendCommand().

◆ BuildRequestSenseSrb()

PSCSI_REQUEST_BLOCK NTAPI BuildRequestSenseSrb ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 11251 of file id_ata.cpp.

11255{
11256 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
11258 PCDB cdb;
11259 PATA_REQ AtaReq = (PATA_REQ)(Srb->SrbExtension);
11260
11261 srb = &(deviceExtension->chan[GET_CHANNEL(Srb)].InternalSrb);
11262
11263 RtlZeroMemory((PCHAR) srb, sizeof(SCSI_REQUEST_BLOCK));
11264
11265 srb->PathId = (UCHAR)(Srb->PathId);
11266 srb->TargetId = (UCHAR)(Srb->TargetId);
11267 srb->Function = SRB_FUNCTION_EXECUTE_SCSI;
11268 srb->Length = sizeof(SCSI_REQUEST_BLOCK);
11269
11270 // Set flags to disable synchronous negociation.
11272
11273 // Set timeout to 2 seconds.
11274 srb->TimeOutValue = 4;
11275
11276 srb->CdbLength = 6;
11277 srb->DataBuffer = &(deviceExtension->chan[GET_CHANNEL(Srb)].MechStatusSense);
11278 srb->DataTransferLength = sizeof(SENSE_DATA);
11279 srb->SrbExtension = AtaReq;
11280
11281 // Set CDB operation code.
11282 cdb = (PCDB)srb->Cdb;
11283 cdb->CDB6INQUIRY.OperationCode = SCSIOP_REQUEST_SENSE;
11284 cdb->CDB6INQUIRY.AllocationLength = sizeof(SENSE_DATA);
11285
11286 KdPrint2((PRINT_PREFIX " RequestSenseSrb %#x\n", srb));
11287
11288 return srb;
11289} // end BuildRequestSenseSrb()
struct _SENSE_DATA SENSE_DATA
SENSE_DATA MechStatusSense
Definition: bsmaster.h:1053
struct _CDB::_CDB6INQUIRY CDB6INQUIRY

Referenced by AtapiInterrupt__(), and AtapiSendCommand().

◆ CheckDevice()

ULONG NTAPI CheckDevice ( IN PVOID  HwDeviceExtension,
IN ULONG  Channel,
IN ULONG  deviceNumber,
IN BOOLEAN  ResetBus 
)

Definition at line 2897 of file id_probe.cpp.

2903{
2904 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2905 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
2906 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2907 PHW_LU_EXTENSION LunExt;
2908
2909 UCHAR signatureLow,
2910 signatureHigh;
2911 UCHAR statusByte;
2912 ULONG RetVal=0;
2913 ULONG waitCount = g_opt_WaitBusyResetCount;
2914 ULONG at_home = 0;
2915
2916 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x\n",
2917 deviceNumber));
2918
2919 if(deviceNumber >= chan->NumberLuns) {
2920 return 0;
2921 }
2922 if(deviceExtension->HwFlags & UNIATA_AHCI) {
2923 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
2924 return 0;
2925 }
2926 }
2927 LunExt = chan->lun[deviceNumber];
2928
2929 if(ResetDev) {
2930 LunExt->PowerState = 0;
2931 }
2932
2933 if((deviceExtension->HwFlags & UNIATA_SATA) &&
2934 !UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
2935 deviceNumber) {
2936 KdPrint2((PRINT_PREFIX " SATA w/o i/o registers, check slave presence\n"));
2937 SelectDrive(chan, deviceNumber & 0x01);
2938 statusByte = AtapiReadPort1(chan, IDX_ATAPI_IO1_i_DriveSelect);
2939 KdPrint2((PRINT_PREFIX " DriveSelect: %#x\n", statusByte));
2940 if((statusByte & IDE_DRIVE_MASK) != IDE_DRIVE_SELECT_2) {
2941 KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
2942 UniataForgetDevice(LunExt);
2943 return 0;
2944 }
2945 }
2946
2947 if(ResetDev && (deviceExtension->HwFlags & UNIATA_AHCI)) {
2948 KdPrint2((PRINT_PREFIX "CheckDevice: reset AHCI dev\n"));
2949 if(UniataAhciSoftReset(HwDeviceExtension, chan->lChannel, deviceNumber) == (ULONG)(-1)) {
2950 KdPrint2((PRINT_PREFIX "CheckDevice: (no dev)\n"));
2951 UniataForgetDevice(LunExt);
2952 return 0;
2953 }
2954 } else
2955 if(ResetDev) {
2956 KdPrint2((PRINT_PREFIX "CheckDevice: reset dev\n"));
2957
2958 // Reset device
2959 AtapiSoftReset(chan, deviceNumber);
2960
2961 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
2962 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 1\n"));
2963 return 0;
2964 }
2965 statusByte = WaitOnBusy(chan);
2966
2967 if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
2969 "CheckDevice: bad status %x\n", statusByte));
2970 } else
2971 if(statusByte != IDE_STATUS_WRONG && (statusByte & IDE_STATUS_BUSY)) {
2972 // Perform hard-reset.
2974 "CheckDevice: BUSY\n"));
2975
2976 AtapiHardReset(chan, FALSE, 500 * 1000);
2977/*
2978 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
2979 chan->last_devsel = -1;
2980 AtapiStallExecution(500 * 1000);
2981 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
2982*/
2983 SelectDrive(chan, deviceNumber & 0x01);
2984
2985 do {
2986 // Wait for Busy to drop.
2988 GetStatus(chan, statusByte);
2989
2990 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
2991
2992 GetBaseStatus(chan, statusByte);
2994 "CheckDevice: status after hard reset %x\n", statusByte));
2995 }
2996
2997 if((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) {
2999 "CheckDevice: no dev ?\n"));
3000 UniataForgetDevice(LunExt);
3001 return 0;
3002 } else
3003 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
3004 //if(deviceExtension->HwFlags & UNIATA_SATA) {
3006 "CheckDevice: try enable SATA Phy\n"));
3007 statusByte = UniataSataPhyEnable(HwDeviceExtension, lChannel, deviceNumber);
3008 if(statusByte == IDE_STATUS_WRONG) {
3009 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x (no dev)\n", statusByte));
3010 UniataForgetDevice(LunExt);
3011 return 0;
3012 }
3013 }
3014 }
3015
3016 if(deviceExtension->HwFlags & UNIATA_AHCI) {
3017 RetVal = LunExt->DeviceFlags;
3018 signatureLow = signatureHigh = 0; // make GCC happy
3019 } else {
3020 // Select the device.
3021 SelectDrive(chan, deviceNumber);
3022
3023 if(!(at_home = UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber))) {
3024 //KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home 2\n"));
3025 return 0;
3026 }
3027
3028 statusByte = WaitOnBaseBusyLong(chan);
3029
3030 GetBaseStatus(chan, statusByte);
3031 if(deviceExtension->HwFlags & UNIATA_SATA) {
3032 UniataSataClearErr(HwDeviceExtension, lChannel, UNIATA_SATA_IGNORE_CONNECT, deviceNumber);
3033 }
3034
3035 KdPrint2((PRINT_PREFIX "CheckDevice: status %#x\n", statusByte));
3036 if(((statusByte | IDE_STATUS_BUSY) == IDE_STATUS_WRONG) ||
3037 (statusByte & IDE_STATUS_BUSY)) {
3038 KdPrint2((PRINT_PREFIX "CheckDevice: busy => return\n"));
3039 UniataForgetDevice(LunExt);
3040 return 0;
3041 }
3042
3043 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
3044 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
3045 }
3046
3047 // set default costs
3051 LunExt->AtapiReadyWaitDelay = 0;
3052
3053 if(deviceExtension->HwFlags & UNIATA_AHCI) {
3054 if(RetVal & DFLAGS_DEVICE_PRESENT) {
3055 if(IssueIdentify(HwDeviceExtension,
3056 deviceNumber,
3057 lChannel,
3059 FALSE)) {
3060 // OK
3061 KdPrint2((PRINT_PREFIX "CheckDevice: detected AHCI Device %#x\n",
3062 deviceNumber));
3063 } else {
3064 //RetVal &= ~DFLAGS_ATAPI_DEVICE;
3065 //LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3066
3067 UniataForgetDevice(LunExt);
3068 RetVal = 0;
3069 }
3070 }
3071 } else
3072 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
3073
3074 KdPrint2((PRINT_PREFIX "CheckDevice: ATAPI signature found\n"));
3075 // ATAPI signature found.
3076 // Issue the ATAPI identify command if this
3077 // is not for the crash dump utility.
3078try_atapi:
3079 if (!g_Dump) {
3080
3081 // Issue ATAPI packet identify command.
3082 if (IssueIdentify(HwDeviceExtension,
3083 deviceNumber,
3084 lChannel,
3086
3087 // Indicate ATAPI device.
3088 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is ATAPI\n",
3089 deviceNumber));
3090
3093
3094 // some ATAPI devices doesn't work with DPC on CMD-649
3095 // and probably some other controllers
3096 if(deviceExtension->HwFlags & UNIATA_NO_DPC_ATAPI) {
3097 /* CMD 649, ROSB SWK33, ICH4 */
3098 KdPrint2((PRINT_PREFIX "CheckDevice: UNIATA_NO_DPC_ATAPI\n"));
3099 deviceExtension->UseDpc = FALSE;
3100 }
3101
3102 GetStatus(chan, statusByte);
3103 if (statusByte & IDE_STATUS_ERROR) {
3104 AtapiSoftReset(chan, deviceNumber);
3105 }
3106
3107 } else {
3108forget_device:
3109 // Indicate no working device.
3110 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x not responding\n",
3111 deviceNumber));
3112
3113 UniataForgetDevice(LunExt);
3114 RetVal = 0;
3115 }
3116 GetBaseStatus(chan, statusByte);
3117
3118 }
3119
3120 } else {
3121
3122 KdPrint2((PRINT_PREFIX "CheckDevice: IDE device check\n"));
3123 // Issue IDE Identify. If an Atapi device is actually present, the signature
3124 // will be asserted, and the drive will be recognized as such.
3125 if(deviceExtension->DWordIO) {
3126 KdPrint2((PRINT_PREFIX " try 32bit IO\n"));
3128 }
3129 if (IssueIdentify(HwDeviceExtension,
3130 deviceNumber,
3131 lChannel,
3133
3134 // IDE drive found.
3135 KdPrint2((PRINT_PREFIX "CheckDevice: Device %#x is IDE\n",
3136 deviceNumber));
3137
3138 // Indicate IDE - not ATAPI device.
3139 RetVal = DFLAGS_DEVICE_PRESENT;
3141 LunExt->DeviceFlags &= ~DFLAGS_ATAPI_DEVICE;
3142 } else
3144 // This can be ATAPI on broken hardware
3145 GetBaseStatus(chan, statusByte);
3146 if(!at_home && UniataAnybodyHome(HwDeviceExtension, lChannel, deviceNumber)) {
3147 KdPrint2((PRINT_PREFIX "CheckDevice: nobody at home post IDE\n"));
3148 goto forget_device;
3149 }
3150 KdPrint2((PRINT_PREFIX "CheckDevice: try ATAPI %#x, status %#x\n",
3151 deviceNumber, statusByte));
3152 goto try_atapi;
3153 } else {
3154 KdPrint2((PRINT_PREFIX "CheckDevice: VM Device %#x not present\n",
3155 deviceNumber));
3156 }
3157 GetBaseStatus(chan, statusByte);
3158 }
3159 KdPrint2((PRINT_PREFIX "CheckDevice: check status: %sfound\n", RetVal ? "" : "not "));
3160 return RetVal;
3161} // end CheckDevice()
#define IDE_COMMAND_IDENTIFY
Definition: atapi.h:118
#define UNIATA_NO_DPC_ATAPI
Definition: bm_devs_decl.h:628
#define REORDER_MCOST_SWITCH_RW_HDD
Definition: bsmaster.h:990
#define REORDER_COST_SWITCH_RW_HDD
Definition: bsmaster.h:989
ULONG g_opt_WaitBusyResetCount
Definition: id_ata.cpp:89
VOID NTAPI UniataForgetDevice(PHW_LU_EXTENSION LunExt)
Definition: id_ata.cpp:2385
#define VM_NONE
Definition: bsmaster.h:1902
#define REORDER_MCOST_SEEK_BACK_HDD
Definition: bsmaster.h:991
ULONG g_opt_VirtualMachine
Definition: id_ata.cpp:105
#define ATAPI_MAGIC_MSB
Definition: hwide.h:287
#define IDE_DRIVE_MASK
Definition: hwide.h:132
#define IDX_IO1_i_CylinderHigh
Definition: hwide.h:46
#define IDE_DRIVE_SELECT_2
Definition: hwide.h:131
#define IDX_ATAPI_IO1_i_DriveSelect
Definition: hwide.h:93
#define ATAPI_MAGIC_LSB
Definition: hwide.h:286
ULONG NTAPI UniataAnybodyHome(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG deviceNumber)
Definition: id_probe.cpp:2778
UCHAR NTAPI UniataSataPhyEnable(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG pm_port, IN BOOLEAN doReset)
Definition: id_sata.cpp:124
ULONG NTAPI UniataAhciSoftReset(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber)
Definition: id_sata.cpp:1787
ULONG NumberLuns
Definition: bsmaster.h:1090
LONGLONG RwSwitchMCost
Definition: bsmaster.h:1182
LONGLONG RwSwitchCost
Definition: bsmaster.h:1181
LONGLONG SeekBackMCost
Definition: bsmaster.h:1183
UCHAR DDKFASTAPI WaitOnBaseBusyLong(IN struct _HW_CHANNEL *chan)
VOID DDKFASTAPI AtapiHardReset(IN struct _HW_CHANNEL *chan, IN BOOLEAN DisableInterrupts, IN ULONG Delay)
Definition: id_ata.cpp:948

Referenced by AtapiResetController__(), AtapiSendCommand(), AtapiStartIo__(), FindDevices(), IdeSendCommand(), and UniataSataEvent().

◆ EncodeVendorStr()

ULONG NTAPI EncodeVendorStr ( OUT PWCHAR  Buffer,
IN PUCHAR  Str,
IN ULONG  Length 
)

Definition at line 11325 of file id_ata.cpp.

11330{
11331 ULONG i,j;
11332 WCHAR a;
11333
11334 for(i=0, j=0; i<Length; i++, j++) {
11335 // fix byte-order
11336 a = Str[i ^ 0x01];
11337 if(!a) {
11338 Buffer[j] = 0;
11339 return j;
11340 } else
11341 if(a == ' ') {
11342 Buffer[j] = '_';
11343 } else
11344 if((a == '_') ||
11345 (a == '#') ||
11346 (a == '\\') ||
11347 (a == '\"') ||
11348 (a == '\'') ||
11349 (a < ' ') ||
11350 (a >= 127)) {
11351 Buffer[j] = '#';
11352 j++;
11353 swprintf(Buffer+j, L"%2.2x", a);
11354 j++;
11355 } else {
11356 Buffer[j] = a;
11357 }
11358 }
11359 Buffer[j] = 0;
11360 return j;
11361} // end EncodeVendorStr()
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
#define a
Definition: ke_i.h:78
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102

◆ FindDevices()

BOOLEAN NTAPI FindDevices ( IN PVOID  HwDeviceExtension,
IN ULONG  Flags,
IN ULONG  Channel 
)

Definition at line 3184 of file id_probe.cpp.

3189{
3190 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
3191 PHW_CHANNEL chan = &(deviceExtension->chan[Channel]);
3192 PHW_LU_EXTENSION LunExt;
3193 BOOLEAN deviceResponded = FALSE,
3194 skipSetParameters = FALSE;
3195 ULONG waitCount = 10000;
3196 //ULONG deviceNumber;
3197 ULONG i;
3198 UCHAR statusByte;
3199 ULONG max_ldev;
3200 BOOLEAN AtapiOnly = FALSE;
3201
3202 KdPrint2((PRINT_PREFIX "FindDevices:\n"));
3203
3204 // Disable interrupts
3205 AtapiDisableInterrupts(deviceExtension, Channel);
3206// AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_DISABLE_INTERRUPTS | IDE_DC_A_4BIT );
3207
3208 // Clear expecting interrupt flag and current SRB field.
3210// chan->CurrentSrb = NULL;
3211// max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : IDE_MAX_LUN_PER_CHAN;
3212 max_ldev = (chan->ChannelCtrlFlags & CTRFLAGS_NO_SLAVE) ? 1 : deviceExtension->NumberLuns;
3213 KdPrint2((PRINT_PREFIX " max_ldev %d\n", max_ldev));
3214
3215 // Search for devices.
3216 for (i = 0; i < max_ldev; i++) {
3217 //AtapiDisableInterrupts(deviceExtension, Channel);
3219 chan->lun[i]->DeviceFlags &= ~DFLAGS_HIDDEN;
3220 }
3221 deviceResponded |=
3222 (CheckDevice(HwDeviceExtension, Channel, i, TRUE) != 0);
3223 //AtapiEnableInterrupts(deviceExtension, Channel);
3224 }
3225
3226 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
3227 AtapiEnableInterrupts(deviceExtension, Channel);
3229 "FindDevices: returning %d (AHCI)\n",
3230 deviceResponded));
3231 return deviceResponded;
3232 }
3233
3234 for (i = 0; i < max_ldev; i++) {
3235 LunExt = chan->lun[i];
3236
3237 if (( LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) &&
3238 !(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) &&
3239 !(LunExt->DeviceFlags & DFLAGS_ATAPI_DEVICE) && deviceResponded) {
3240
3241 // This hideous hack is to deal with ESDI devices that return
3242 // garbage geometry in the IDENTIFY data.
3243 // This is ONLY for the crashdump environment as
3244 // these are ESDI devices.
3245 if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
3246 LunExt->IdentifyData.NumberOfHeads == 0x07) {
3247
3248 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
3249
3250 // Change these values to something reasonable.
3251 LunExt->IdentifyData.SectorsPerTrack = 0x34;
3252 LunExt->IdentifyData.NumberOfHeads = 0x0E;
3253 }
3254
3255 if (LunExt->IdentifyData.SectorsPerTrack == 0x35 &&
3256 LunExt->IdentifyData.NumberOfHeads == 0x0F) {
3257
3258 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty Compaq ESDI!\n"));
3259
3260 // Change these values to something reasonable.
3261 LunExt->IdentifyData.SectorsPerTrack = 0x34;
3262 LunExt->IdentifyData.NumberOfHeads = 0x0F;
3263 }
3264
3265
3266 if (LunExt->IdentifyData.SectorsPerTrack == 0x36 &&
3267 LunExt->IdentifyData.NumberOfHeads == 0x07) {
3268
3269 KdPrint2((PRINT_PREFIX "FindDevices: Found nasty UltraStor ESDI!\n"));
3270
3271 // Change these values to something reasonable.
3272 LunExt->IdentifyData.SectorsPerTrack = 0x3F;
3273 LunExt->IdentifyData.NumberOfHeads = 0x10;
3274 skipSetParameters = TRUE;
3275 }
3276
3277
3278 if (skipSetParameters)
3279 continue;
3280
3281 statusByte = WaitOnBusy(chan);
3282
3283 // Select the device.
3284 SelectDrive(chan, i & 0x01);
3285 GetStatus(chan, statusByte);
3286
3287 if (statusByte & IDE_STATUS_ERROR) {
3288
3289 // Reset the device.
3291 "FindDevices: Resetting controller before SetDriveParameters.\n"));
3292
3293 AtapiHardReset(chan, FALSE, 500 * 1000);
3294/*
3295 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_RESET_CONTROLLER );
3296 chan->last_devsel = -1;
3297 AtapiStallExecution(500 * 1000);
3298 AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_REENABLE_CONTROLLER);
3299*/
3300 SelectDrive(chan, i & 0x01);
3301
3302 do {
3303 // Wait for Busy to drop.
3305 GetStatus(chan, statusByte);
3306
3307 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
3308 }
3309
3310 statusByte = WaitOnBusy(chan);
3311
3313 "FindDevices: Status before SetDriveParameters: (%#x) (%#x)\n",
3314 statusByte,
3316
3317 GetBaseStatus(chan, statusByte);
3318
3319 // Use the IDENTIFY data to set drive parameters.
3320 if (!SetDriveParameters(HwDeviceExtension,i,Channel)) {
3321
3323 "FindDevices: Set drive parameters for device %d failed\n",
3324 i));
3325 // Don't use this device as writes could cause corruption.
3326 LunExt->DeviceFlags &= ~DFLAGS_DEVICE_PRESENT;
3327 UniataForgetDevice(LunExt);
3328 continue;
3329
3330 }
3331 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
3332
3333 // Pick up ALL IDE removable drives that conform to Yosemite V0.2...
3334 AtapiOnly = FALSE;
3335 }
3336
3337 // Indicate that a device was found.
3338 if (!AtapiOnly) {
3339 deviceResponded = TRUE;
3340 }
3341 }
3342 }
3343
3344/* // Reset the controller. This is a feeble attempt to leave the ESDI
3345 // controllers in a state that ATDISK driver will recognize them.
3346 // The problem in ATDISK has to do with timings as it is not reproducible
3347 // in debug. The reset should restore the controller to its poweron state
3348 // and give the system enough time to settle.
3349 if (!deviceResponded) {
3350
3351 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_RESET_CONTROLLER );
3352 AtapiStallExecution(50 * 1000);
3353 AtapiWritePort1(chan, IDX_IO2_o_Control,IDE_DC_REENABLE_CONTROLLER);
3354 }
3355*/
3356 if(deviceResponded) {
3357 for (i = 0; i < max_ldev; i++) {
3358 LunExt = chan->lun[i];
3359
3361 "FindDevices: select %d dev to clear INTR\n", i));
3362 SelectDrive(chan, i);
3363 GetBaseStatus(chan, statusByte);
3365 "FindDevices: statusByte=%#x\n", statusByte));
3366 }
3367 for (i = 0; i < max_ldev; i++) {
3368 LunExt = chan->lun[i];
3369
3370 if(LunExt->DeviceFlags & DFLAGS_DEVICE_PRESENT) {
3371 // Make sure some device (master is preferred) is selected on exit.
3373 "FindDevices: select %d dev on exit\n", i));
3374 SelectDrive(chan, i);
3375 break;
3376 }
3377 }
3378 }
3379
3380 GetBaseStatus(chan, statusByte);
3381 // Enable interrupts
3382 AtapiEnableInterrupts(deviceExtension, Channel);
3383// AtapiWritePort1(chan, IDX_IO2_o_Control, IDE_DC_A_4BIT );
3384 GetBaseStatus(chan, statusByte);
3385
3387 "FindDevices: returning %d\n",
3388 deviceResponded));
3389
3390 return deviceResponded;
3391
3392} // end FindDevices()
#define IDX_IO1_i_DriveSelect
Definition: hwide.h:47
ULONG NTAPI CheckDevice(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG deviceNumber, IN BOOLEAN ResetDev)
Definition: id_probe.cpp:2897
USHORT NumberOfHeads
Definition: atapi.h:252
USHORT SectorsPerTrack
Definition: atapi.h:255
VOID NTAPI AtapiEnableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4397
VOID UniataExpectChannelInterrupt(IN struct _HW_CHANNEL *chan, IN BOOLEAN Expecting)
Definition: id_ata.cpp:4492
VOID NTAPI AtapiDisableInterrupts(IN PVOID HwDeviceExtension, IN ULONG c)
Definition: id_ata.cpp:4457
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170

◆ IdeBuildSenseBuffer()

ULONG NTAPI IdeBuildSenseBuffer ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb 
)

Definition at line 5737 of file atapi.c.

5759{
5760 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
5761 PSENSE_DATA senseBuffer = (PSENSE_DATA)Srb->DataBuffer;
5762
5763
5764 if (senseBuffer){
5765
5766
5767 if(deviceExtension->ReturningMediaStatus & IDE_ERROR_MEDIA_CHANGE) {
5768
5769 senseBuffer->ErrorCode = 0x70;
5770 senseBuffer->Valid = 1;
5771 senseBuffer->AdditionalSenseLength = 0xb;
5772 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
5774 senseBuffer->AdditionalSenseCodeQualifier = 0;
5775 } else if(deviceExtension->ReturningMediaStatus & IDE_ERROR_MEDIA_CHANGE_REQ) {
5776
5777 senseBuffer->ErrorCode = 0x70;
5778 senseBuffer->Valid = 1;
5779 senseBuffer->AdditionalSenseLength = 0xb;
5780 senseBuffer->SenseKey = SCSI_SENSE_UNIT_ATTENTION;
5782 senseBuffer->AdditionalSenseCodeQualifier = 0;
5783 } else if(deviceExtension->ReturningMediaStatus & IDE_ERROR_END_OF_MEDIA) {
5784
5785 senseBuffer->ErrorCode = 0x70;
5786 senseBuffer->Valid = 1;
5787 senseBuffer->AdditionalSenseLength = 0xb;
5788 senseBuffer->SenseKey = SCSI_SENSE_NOT_READY;
5790 senseBuffer->AdditionalSenseCodeQualifier = 0;
5791 } else if(deviceExtension->ReturningMediaStatus & IDE_ERROR_DATA_ERROR) {
5792
5793 senseBuffer->ErrorCode = 0x70;
5794 senseBuffer->Valid = 1;
5795 senseBuffer->AdditionalSenseLength = 0xb;
5796 senseBuffer->SenseKey = SCSI_SENSE_DATA_PROTECT;
5797 senseBuffer->AdditionalSenseCode = 0;
5798 senseBuffer->AdditionalSenseCodeQualifier = 0;
5799 }
5800 return SRB_STATUS_SUCCESS;
5801 }
5802 return SRB_STATUS_ERROR;
5803
5804}// End of IdeBuildSenseBuffer
#define SCSI_SENSE_DATA_PROTECT
Definition: cdrw_hw.h:1194
#define SCSI_SENSE_UNIT_ATTENTION
Definition: cdrw_hw.h:1193
#define SCSI_ADSENSE_NO_MEDIA_IN_DEVICE
Definition: cdrw_hw.h:1221
#define SCSI_ADSENSE_MEDIUM_CHANGED
Definition: cdrw_hw.h:1288
#define SCSI_SENSE_NOT_READY
Definition: cdrw_hw.h:1189
#define IDE_ERROR_END_OF_MEDIA
Definition: hwide.h:154
#define IDE_ERROR_MEDIA_CHANGE
Definition: hwide.h:150
#define IDE_ERROR_MEDIA_CHANGE_REQ
Definition: hwide.h:152
#define IDE_ERROR_DATA_ERROR
Definition: hwide.h:149
UCHAR ReturningMediaStatus
Definition: atapi.c:137

Referenced by IdeSendCommand().

◆ IdeMediaStatus()

VOID NTAPI IdeMediaStatus ( BOOLEAN  EnableMSN,
IN PVOID  HwDeviceExtension,
IN ULONG  lChannel,
IN ULONG  DeviceNumber 
)

Definition at line 9069 of file id_ata.cpp.

9075{
9076 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
9077 PHW_CHANNEL chan;
9078 UCHAR statusByte,errorByte;
9079
9080 chan = &(deviceExtension->chan[lChannel]);
9082
9083 if (EnableMSN == TRUE){
9084
9085 // If supported enable Media Status Notification support
9086 if ((chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_REMOVABLE_DRIVE)) {
9087
9088 // enable
9089 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9090 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9092
9093 if (statusByte & IDE_STATUS_ERROR) {
9094 // Read the error register.
9095 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
9096
9098 "IdeMediaStatus: Error enabling media status. Status %#x, error byte %#x\n",
9099 statusByte,
9100 errorByte));
9101 } else {
9102 chan->lun[DeviceNumber]->DeviceFlags |= DFLAGS_MEDIA_STATUS_ENABLED;
9103 KdPrint2((PRINT_PREFIX "IdeMediaStatus: Media Status Notification Supported\n"));
9104 chan->ReturningMediaStatus = 0;
9105
9106 }
9107
9108 }
9109 } else { // end if EnableMSN == TRUE
9110
9111 // disable if previously enabled
9112 if ((chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED)) {
9113
9114 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel,
9115 IDE_COMMAND_SET_FEATURES, 0, 0, 0,
9117 chan->lun[DeviceNumber]->DeviceFlags &= ~DFLAGS_MEDIA_STATUS_ENABLED;
9118 }
9119
9120
9121 }
9122
9123
9124} // end IdeMediaStatus()
#define DFLAGS_MEDIA_STATUS_ENABLED
Definition: atapi.h:47
UCHAR ReturningMediaStatus
Definition: bsmaster.h:1043
#define ATA_C_F_DIS_MEDIASTAT
Definition: atapi.h:576
#define ATA_C_F_ENAB_MEDIASTAT
Definition: atapi.h:575

Referenced by AtapiHwInitialize__().

◆ IdeSendCommand()

ULONG NTAPI IdeSendCommand ( IN PVOID  HwDeviceExtension,
IN PSCSI_REQUEST_BLOCK  Srb,
IN ULONG  CmdAction 
)

Definition at line 8233 of file id_ata.cpp.

8238{
8239 SetCheckPoint(1);
8240 KdPrint2((PRINT_PREFIX "** Ide: Command: entryway\n"));
8241 SetCheckPoint(2);
8242
8243 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
8244 SetCheckPoint(3);
8245 UCHAR lChannel;
8246 PHW_CHANNEL chan;
8247 PCDB cdb;
8248 PHW_LU_EXTENSION LunExt;
8249
8250 SetCheckPoint(4);
8251
8252 UCHAR statusByte,errorByte;
8254 ULONG i;
8255 ULONGLONG lba;
8256 PMODE_PARAMETER_HEADER modeData;
8257 //ULONG ldev;
8259 PATA_REQ AtaReq;
8260 UCHAR command;
8261
8262 SetCheckPoint(5);
8263 //ULONG __ebp__ = 0;
8264
8265 SetCheckPoint(0x20);
8266 KdPrint2((PRINT_PREFIX "** Ide: Command:\n\n"));
8267/* __asm {
8268 mov eax,ebp
8269 mov __ebp__, eax
8270 }*/
8271 /*KdPrint2((PRINT_PREFIX "** Ide: Command EBP %#x, pCdb %#x, cmd %#x\n",
8272 __ebp__, &(Srb->Cdb[0]), Srb->Cdb[0]));
8273 KdPrint2((PRINT_PREFIX "** Ide: Command %s\n",
8274 (CmdAction == CMD_ACTION_PREPARE) ? "Prep " : ""));
8275 KdPrint2((PRINT_PREFIX "** Ide: Command Srb %#x\n",
8276 Srb));
8277 KdPrint2((PRINT_PREFIX "** Ide: Command SrbExt %#x\n",
8278 Srb->SrbExtension));
8279 KdPrint2((PRINT_PREFIX "** Ide: Command to device %d\n",
8280 Srb->TargetId));*/
8281
8282 SetCheckPoint(0x30);
8283 AtaReq = (PATA_REQ)(Srb->SrbExtension);
8284
8285 KdPrint2((PRINT_PREFIX "** Ide: Command &AtaReq %#x\n",
8286 &AtaReq));
8287 KdPrint2((PRINT_PREFIX "** Ide: Command AtaReq %#x\n",
8288 AtaReq));
8289 KdPrint2((PRINT_PREFIX "** --- **\n"));
8290
8291 lChannel = GET_CHANNEL(Srb);
8292 chan = &(deviceExtension->chan[lChannel]);
8293 //ldev = GET_LDEV(Srb);
8295 LunExt = chan->lun[DeviceNumber];
8296
8297 SetCheckPoint(0x40);
8300
8301 cdb = (PCDB)(Srb->Cdb);
8302
8303 if(CmdAction == CMD_ACTION_PREPARE) {
8304 switch (Srb->Cdb[0]) {
8306 if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
8307 // ok
8308 } else {
8309 goto default_no_prep;
8310 }
8311#ifdef NAVO_TEST
8312 case SCSIOP_INQUIRY: // now it requires device access
8313#endif //NAVO_TEST
8315 case SCSIOP_READ:
8316 case SCSIOP_WRITE:
8317 case SCSIOP_READ12:
8318 case SCSIOP_WRITE12:
8319 case SCSIOP_READ16:
8320 case SCSIOP_WRITE16:
8322 // all right
8323 KdPrint2((PRINT_PREFIX "** Ide: Command continue prep\n"));
8324 SetCheckPoint(50);
8325 break;
8326 default:
8327default_no_prep:
8328 SetCheckPoint(0);
8329 KdPrint2((PRINT_PREFIX "** Ide: Command break prep\n"));
8330 return SRB_STATUS_BUSY;
8331 }
8332 }
8333
8334 SetCheckPoint(0x100 | Srb->Cdb[0]);
8335 switch (Srb->Cdb[0]) {
8336 case SCSIOP_INQUIRY:
8337
8339 "IdeSendCommand: SCSIOP_INQUIRY PATH:LUN:TID = %#x:%#x:%#x\n",
8340 Srb->PathId, Srb->Lun, Srb->TargetId));
8341 // Filter out wrong TIDs.
8342 if ((Srb->Lun != 0) ||
8343 (Srb->PathId >= deviceExtension->NumberChannels) ||
8344 (Srb->TargetId >= deviceExtension->NumberLuns)) {
8345
8347 "IdeSendCommand: SCSIOP_INQUIRY rejected\n"));
8348 // Indicate no device found at this address.
8350 break;
8351
8352 } else {
8353
8355 "IdeSendCommand: SCSIOP_INQUIRY ok\n"));
8356 PINQUIRYDATA inquiryData = (PINQUIRYDATA)(Srb->DataBuffer);
8357 PIDENTIFY_DATA2 identifyData = &(LunExt->IdentifyData);
8358
8359 if (!(chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_DEVICE_PRESENT)) {
8360
8361 if(!CheckDevice(HwDeviceExtension, lChannel, DeviceNumber, FALSE)) {
8363 "IdeSendCommand: SCSIOP_INQUIRY rejected (2)\n"));
8364 // Indicate no device found at this address.
8365#ifndef NAVO_TEST
8367 break;
8368 }
8369 } else {
8370 if(!UniataAnybodyHome(HwDeviceExtension, lChannel, DeviceNumber)) {
8372 "IdeSendCommand: SCSIOP_INQUIRY device have gone\n"));
8373 // Indicate no device found at this address.
8375#endif //NAVO_TEST
8377 break;
8378 }
8379 }
8380
8381 // Zero INQUIRY data structure.
8383
8384 // Standard IDE interface only supports disks.
8385 inquiryData->DeviceType = DIRECT_ACCESS_DEVICE;
8386
8387 // Set the removable bit, if applicable.
8388 if (LunExt->DeviceFlags & DFLAGS_REMOVABLE_DRIVE) {
8390 "RemovableMedia\n"));
8391 inquiryData->RemovableMedia = 1;
8392 }
8393 // Set the Relative Addressing (LBA) bit, if applicable.
8394 if (LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
8395 inquiryData->RelativeAddressing = 1;
8397 "RelativeAddressing\n"));
8398 }
8399 // Set the CommandQueue bit
8400 inquiryData->CommandQueue = 1;
8401
8402 // Fill in vendor identification fields.
8403#ifdef __REACTOS__
8404 FillDeviceIdentificationString(inquiryData, identifyData);
8405#else
8406 for (i = 0; i < 24; i += 2) {
8407 MOV_DW_SWP(inquiryData->DeviceIdentificationString[i], ((PUCHAR)identifyData->ModelNumber)[i]);
8408 }
8409#endif
8410/*
8411 // Initialize unused portion of product id.
8412 for (i = 0; i < 4; i++) {
8413 inquiryData->ProductId[12+i] = ' ';
8414 }
8415*/
8416 // Move firmware revision from IDENTIFY data to
8417 // product revision in INQUIRY data.
8418 for (i = 0; i < 4; i += 2) {
8419 MOV_DW_SWP(inquiryData->ProductRevisionLevel[i], ((PUCHAR)identifyData->FirmwareRevision)[i]);
8420 }
8421
8423 }
8424
8425 break;
8426
8427 case SCSIOP_REPORT_LUNS: {
8428
8429 ULONG alen;
8430 PREPORT_LUNS_INFO_HDR LunInfo;
8431
8433 "IdeSendCommand: SCSIOP_REPORT_LUNS PATH:LUN:TID = %#x:%#x:%#x\n",
8434 Srb->PathId, Srb->Lun, Srb->TargetId));
8435
8436 MOV_DD_SWP(alen, cdb->REPORT_LUNS.AllocationLength);
8437
8438 if(alen < 16) {
8439 goto invalid_cdb;
8440 }
8441 alen = 8;
8442
8443 LunInfo = (PREPORT_LUNS_INFO_HDR)(Srb->DataBuffer);
8444 RtlZeroMemory(LunInfo, 16);
8445
8446 MOV_DD_SWP( LunInfo->ListLength, alen );
8447 Srb->DataTransferLength = 16;
8449
8450 break; }
8451
8452 case SCSIOP_MODE_SENSE:
8453
8455 "IdeSendCommand: SCSIOP_MODE_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
8456 Srb->PathId, Srb->Lun, Srb->TargetId));
8457
8458 if(cdb->MODE_SENSE.PageCode == MODE_PAGE_POWER_CONDITION) {
8460
8461 KdPrint2((PRINT_PREFIX "MODE_PAGE_POWER_CONDITION\n"));
8463 if(cdb->MODE_SENSE.AllocationLength < sizeof(MODE_POWER_CONDITION_PAGE)) {
8465 } else {
8466 RtlZeroMemory(modeData, sizeof(MODE_POWER_CONDITION_PAGE));
8468#ifdef __REACTOS__
8470#else
8472#endif
8473 modeData->Byte3.Fields.Idle = LunExt->PowerState <= StartStop_Power_Idle;
8474 modeData->Byte3.Fields.Standby = LunExt->PowerState == StartStop_Power_Standby;
8477 }
8478 } else
8479 if(cdb->MODE_SENSE.PageCode == MODE_PAGE_CACHING) {
8480 PMODE_CACHING_PAGE modeData;
8481
8482 KdPrint2((PRINT_PREFIX "MODE_PAGE_CACHING\n"));
8483 modeData = (PMODE_CACHING_PAGE)(Srb->DataBuffer);
8484 if(cdb->MODE_SENSE.AllocationLength < sizeof(MODE_CACHING_PAGE)) {
8486 } else {
8487 RtlZeroMemory(modeData, sizeof(MODE_CACHING_PAGE));
8488 modeData->PageCode = MODE_PAGE_CACHING;
8489 modeData->PageLength = sizeof(MODE_CACHING_PAGE)-sizeof(MODE_PARAMETER_HEADER);
8490 modeData->ReadDisableCache = (LunExt->DeviceFlags & DFLAGS_RCACHE_ENABLED) ? 0 : 1;
8491 modeData->WriteCacheEnable = (LunExt->DeviceFlags & DFLAGS_WCACHE_ENABLED) ? 1 : 0;
8494 }
8495 } else
8497
8498 // This is used to determine if the media is write-protected.
8499 // Since IDE does not support mode sense then we will modify just the portion we need
8500 // so the higher level driver can determine if media is protected.
8501
8502 //SelectDrive(chan, DeviceNumber);
8503 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_GET_MEDIA_STATUS);
8504 //statusByte = WaitOnBusy(chan);
8505 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_GET_MEDIA_STATUS, 0, 0, 0, 0, 0, ATA_WAIT_READY);
8506
8507 if (!(statusByte & IDE_STATUS_ERROR)) {
8508
8509 // no error occured return success, media is not protected
8514
8515 } else {
8516
8517 // error occured, handle it locally, clear interrupt
8518 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8519
8520 GetBaseStatus(chan, statusByte);
8525
8526 if (errorByte & IDE_ERROR_DATA_ERROR) {
8527
8528 //media is write-protected, set bit in mode sense buffer
8530
8532 modeData->DeviceSpecificParameter |= MODE_DSP_WRITE_PROTECT;
8533 }
8534 }
8536 } else {
8538 }
8539 break;
8540
8542
8544 "IdeSendCommand: SCSIOP_TEST_UNIT_READY PATH:LUN:TID = %#x:%#x:%#x\n",
8545 Srb->PathId, Srb->Lun, Srb->TargetId));
8546 if (chan->lun[DeviceNumber]->DeviceFlags & DFLAGS_MEDIA_STATUS_ENABLED) {
8547
8548 // Select device 0 or 1.
8549 //SelectDrive(chan, DeviceNumber);
8550 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_GET_MEDIA_STATUS);
8551 // Wait for busy. If media has not changed, return success
8552 //statusByte = WaitOnBusy(chan);
8553 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_GET_MEDIA_STATUS, 0, 0, 0, 0, 0, ATA_WAIT_READY);
8554
8555 if (!(statusByte & IDE_STATUS_ERROR)){
8560 } else {
8561 errorByte = AtapiReadPort1(chan, IDX_IO1_i_Error);
8562 if (errorByte == IDE_ERROR_DATA_ERROR){
8563
8564 // Special case: If current media is write-protected,
8565 // the 0xDA command will always fail since the write-protect bit
8566 // is sticky,so we can ignore this error
8567 GetBaseStatus(chan, statusByte);
8572
8573 } else {
8574
8575 // Request sense buffer to be build
8580 }
8581 }
8582 } else {
8584 }
8585
8586 break;
8587
8589
8591 "** IdeSendCommand: SCSIOP_READ_CAPACITY PATH:LUN:TID = %#x:%#x:%#x\n",
8592 Srb->PathId, Srb->Lun, Srb->TargetId));
8593 // Claim 512 byte blocks (big-endian).
8594 //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
8595 i = DEV_BSIZE;
8597 MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock, i );
8598
8599 // Calculate last sector.
8600 if(!(i = (ULONG)LunExt->NumOfSectors)) {
8601 i = LunExt->IdentifyData.SectorsPerTrack *
8602 LunExt->IdentifyData.NumberOfHeads *
8604 }
8605 i--;
8606
8607 //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress =
8608 // (((PUCHAR)&i)[0] << 24) | (((PUCHAR)&i)[1] << 16) |
8609 // (((PUCHAR)&i)[2] << 8) | ((PUCHAR)&i)[3];
8610
8611 MOV_DD_SWP( ((PREAD_CAPACITY_DATA)Srb->DataBuffer)->LogicalBlockAddress, i );
8612
8614 "** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x\n",
8615 Srb->TargetId,
8619
8620
8622 break;
8623
8625
8626 if( cdb->SERVICE_ACTION16.ServiceAction==SCSIOP_SA_READ_CAPACITY16 ) {
8628 "** IdeSendCommand: SCSIOP_READ_CAPACITY PATH:LUN:TID = %#x:%#x:%#x\n",
8629 Srb->PathId, Srb->Lun, Srb->TargetId));
8630 // Claim 512 byte blocks (big-endian).
8631 //((PREAD_CAPACITY_DATA)Srb->DataBuffer)->BytesPerBlock = 0x20000;
8632 i = DEV_BSIZE;
8634 MOV_DD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->BytesPerBlock, i );
8635
8636 // Calculate last sector.
8637 if(!(lba = LunExt->NumOfSectors)) {
8638 lba = LunExt->IdentifyData.SectorsPerTrack *
8639 LunExt->IdentifyData.NumberOfHeads *
8641 }
8642 lba--;
8643 MOV_QD_SWP( ((PREAD_CAPACITY16_DATA)Srb->DataBuffer)->LogicalBlockAddress, lba );
8644
8646 "** IDE disk %#x - #sectors %#x, #heads %#x, #cylinders %#x (16)\n",
8647 Srb->TargetId,
8651
8653 } else {
8654 goto default_abort;
8655 }
8656 break;
8657
8658 case SCSIOP_VERIFY:
8659 case SCSIOP_VERIFY12:
8660 case SCSIOP_VERIFY16:
8661
8663 "IdeSendCommand: SCSIOP_VERIFY PATH:LUN:TID = %#x:%#x:%#x\n",
8664 Srb->PathId, Srb->Lun, Srb->TargetId));
8665 status = IdeVerify(HwDeviceExtension,Srb);
8666
8667 break;
8668
8669 case SCSIOP_READ:
8670 case SCSIOP_WRITE:
8671 case SCSIOP_READ12:
8672 case SCSIOP_WRITE12:
8673 case SCSIOP_READ16:
8674 case SCSIOP_WRITE16:
8675
8677 "IdeSendCommand: SCSIOP_%s PATH:LUN:TID = %#x:%#x:%#x\n",
8678 (Srb->Cdb[0] == SCSIOP_WRITE) ? "WRITE" : "READ",
8679 Srb->PathId, Srb->Lun, Srb->TargetId));
8680 AtaReq->Flags &= ~REQ_FLAG_RW_MASK;
8681 AtaReq->Flags |= (Srb->Cdb[0] == SCSIOP_WRITE ||
8682 Srb->Cdb[0] == SCSIOP_WRITE12 ||
8684 status = IdeReadWrite(HwDeviceExtension,
8685 Srb, CmdAction);
8686 break;
8687
8689
8691 "IdeSendCommand: SCSIOP_START_STOP_UNIT immed %d PATH:LUN:TID = %#x:%#x:%#x\n",
8692 cdb->START_STOP.Immediate, Srb->PathId, Srb->Lun, Srb->TargetId));
8693 //Determine what type of operation we should perform
8694
8695 command = 0;
8696
8697 if(cdb->START_STOP.FL ||
8698 cdb->START_STOP.FormatLayerNumber ||
8699 cdb->START_STOP.Reserved2 ||
8700 cdb->START_STOP.Reserved2_2 ||
8701 cdb->START_STOP.Reserved3 ||
8702 FALSE) {
8703 goto invalid_cdb;
8704 }
8705
8706 if (cdb->START_STOP.PowerConditions) {
8707 KdPrint2((PRINT_PREFIX "START_STOP Power %d\n", cdb->START_STOP.PowerConditions));
8708 switch(cdb->START_STOP.PowerConditions) {
8711 break;
8714 break;
8716 // TODO: we should save power state in order to know
8717 // that RESET sould be issued to revert device into
8718 // operable state
8719
8721 break;
8722 default:
8723 goto invalid_cdb;
8724 }
8725 LunExt->PowerState = cdb->START_STOP.PowerConditions;
8726 } else
8727 if (cdb->START_STOP.LoadEject == 1) {
8728 KdPrint2((PRINT_PREFIX "START_STOP eject\n"));
8729 // Eject media,
8730 // first select device 0 or 1.
8731 //SelectDrive(chan, DeviceNumber);
8732 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_MEDIA_EJECT);
8734 } else
8735 if (cdb->START_STOP.Start == 0) {
8736 KdPrint2((PRINT_PREFIX "START_STOP standby\n"));
8738 } else {
8739 // TODO: we may need to perform hard reset (after sleep) or
8740 // issue IDE_COMMAND_IDLE_IMMED in order to activate device
8741 KdPrint2((PRINT_PREFIX "START_STOP activate\n"));
8742
8743 if(LunExt->PowerState == StartStop_Power_Sleep) {
8744 UniataUserDeviceReset(deviceExtension, LunExt, lChannel);
8746 break;
8747 } else
8748 if(LunExt->PowerState > StartStop_Power_Idle) {
8749 KdPrint2((PRINT_PREFIX " issue IDLE\n"));
8751 } else {
8752 KdPrint2((PRINT_PREFIX " do nothing\n"));
8754 break;
8755 }
8756 }
8757 if(command) {
8758 statusByte = WaitOnBaseBusy(chan);
8759 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, command, 0, 0, 0, 0, 0,
8760 cdb->START_STOP.Immediate ? ATA_IMMEDIATE : ATA_WAIT_READY);
8762 //UniataExpectChannelInterrupt(chan, TRUE); // device may interrupt
8763
8764 } else {
8765invalid_cdb:
8766 KdPrint2((PRINT_PREFIX "START_STOP invalid\n"));
8767 if (Srb->SenseInfoBuffer) {
8768
8770
8771 senseBuffer->ErrorCode = 0x70;
8772 senseBuffer->Valid = 1;
8773 senseBuffer->AdditionalSenseLength = 0xb;
8774 senseBuffer->SenseKey = SCSI_SENSE_ILLEGAL_REQUEST;
8776 senseBuffer->AdditionalSenseCodeQualifier = 0;
8777
8780 }
8782 }
8783 break;
8784
8786
8787 cdb = (PCDB)Srb->Cdb;
8788
8789 if(LunExt->IdentifyData.Removable) {
8790 statusByte = WaitOnBaseBusy(chan);
8791
8792 //SelectDrive(chan, DeviceNumber);
8793 if (cdb->MEDIA_REMOVAL.Prevent == TRUE) {
8794 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_DOOR_LOCK);
8795 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_DOOR_LOCK, 0, 0, 0, 0, 0, ATA_IMMEDIATE);
8796 } else {
8797 //AtapiWritePort1(chan, IDX_IO1_o_Command,IDE_COMMAND_DOOR_UNLOCK);
8798 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_DOOR_UNLOCK, 0, 0, 0, 0, 0, ATA_IMMEDIATE);
8799 }
8801 } else {
8803 }
8804 break;
8805
8806#if 0
8807 // Note: I don't implement this, because NTFS driver too often issues this command
8808 // It causes awful performance degrade. However, if somebody wants, I will implement
8809 // SCSIOP_FLUSH_BUFFER/SCSIOP_SYNCHRONIZE_CACHE optionally.
8812
8816// status = SRB_STATUS_PENDING;
8817 statusByte = WaitOnBusy(chan);
8818 break;
8819#endif
8820
8822 // this function makes sense buffers to report the results
8823 // of the original GET_MEDIA_STATUS command
8824
8826 "IdeSendCommand: SCSIOP_REQUEST_SENSE PATH:LUN:TID = %#x:%#x:%#x\n",
8827 Srb->PathId, Srb->Lun, Srb->TargetId));
8829 status = IdeBuildSenseBuffer(HwDeviceExtension,Srb);
8830 break;
8831 }
8833 break;
8834
8835 // ATA_PASSTHORUGH
8837 {
8839 BOOLEAN use_dma = FALSE;
8840 ULONG to_lim;
8841
8842 regs = (PIDEREGS_EX) &(Srb->Cdb[2]);
8843
8844 if(chan->DeviceExtension->HwFlags & UNIATA_SATA) {
8845 //lChannel = Srb->TargetId >> 1;
8846 } else {
8848 regs->bDriveHeadReg &= 0x0f;
8849 regs->bDriveHeadReg |= (UCHAR) (((DeviceNumber & 0x1) << 4) | 0xA0);
8850 }
8851
8852 if((regs->bOpFlags & 1) == 0) { // execute ATA command
8853
8855 "IdeSendCommand: SCSIOP_ATA_PASSTHROUGH (exec) PATH:LUN:TID = %#x:%#x:%#x\n",
8856 Srb->PathId, Srb->Lun, Srb->TargetId));
8857
8859 to_lim = Srb->TimeOutValue;
8860 } else {
8861 if(Srb->TimeOutValue <= 2) {
8862 to_lim = Srb->TimeOutValue*900;
8863 } else {
8864 to_lim = (Srb->TimeOutValue*999) - 500;
8865 }
8866 }
8867
8868 AtapiDisableInterrupts(deviceExtension, lChannel);
8869
8870 if(chan->DeviceExtension->HwFlags & UNIATA_AHCI) {
8871 // AHCI
8872 statusByte = UniataAhciSendPIOCommandDirect(
8873 deviceExtension,
8874 lChannel,
8876 Srb,
8877 regs,
8879 to_lim
8880 );
8881 if(statusByte == IDE_STATUS_WRONG) {
8882 goto passthrough_err;
8883 }
8884 if(statusByte & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
8886 goto passthrough_err;
8887 }
8888 goto passthrough_done;
8889 }
8890
8891 // SATA/PATA
8892 if((AtaCommandFlags[regs->bCommandReg] & ATA_CMD_FLAG_DMA) || (regs->bOpFlags & UNIATA_SPTI_EX_USE_DMA)) {
8893 if((chan->lun[DeviceNumber]->LimitedTransferMode >= ATA_DMA)) {
8894 use_dma = TRUE;
8895 // this will set REQ_FLAG_DMA_OPERATION in AtaReq->Flags on success
8896 if(!AtapiDmaSetup(HwDeviceExtension, DeviceNumber, lChannel, Srb,
8897 (PUCHAR)(Srb->DataBuffer),
8898 ((Srb->DataTransferLength + DEV_BSIZE-1) & ~(DEV_BSIZE-1)))) {
8899 use_dma = FALSE;
8900 }
8901 }
8902 }
8903
8904 AtapiWritePort1(chan, IDX_IO1_o_DriveSelect, regs->bDriveHeadReg);
8906 if(use_dma) {
8907 AtapiDmaDBPreSync(HwDeviceExtension, chan, Srb);
8908 }
8909
8910 if((regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND) == 0) { // execute ATA command
8911 AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesReg);
8912 AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountReg);
8913 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberReg);
8914 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, regs->bCylLowReg);
8915 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighReg);
8916 } else {
8917 AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesRegH);
8918 AtapiWritePort1(chan, IDX_IO1_o_Feature, regs->bFeaturesReg);
8919 AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountRegH);
8920 AtapiWritePort1(chan, IDX_IO1_o_BlockCount, regs->bSectorCountReg);
8921 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberRegH);
8922 AtapiWritePort1(chan, IDX_IO1_o_BlockNumber, regs->bSectorNumberReg);
8923 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, regs->bCylLowRegH);
8924 AtapiWritePort1(chan, IDX_IO1_o_CylinderLow, regs->bCylLowReg);
8925 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighRegH);
8926 AtapiWritePort1(chan, IDX_IO1_o_CylinderHigh, regs->bCylHighReg);
8927 }
8928 AtapiWritePort1(chan, IDX_IO1_o_Command, regs->bCommandReg);
8929
8930 if(use_dma) {
8931 GetBaseStatus(chan, statusByte);
8932 if(statusByte & IDE_STATUS_ERROR) {
8933 goto passthrough_err;
8934 }
8935 AtapiDmaStart(HwDeviceExtension, DeviceNumber, lChannel, Srb);
8936 }
8937
8938 ScsiPortStallExecution(1); // wait for busy to be set
8939
8940 for(i=0; i<to_lim;i+=2) { // 2 msec from WaitOnBaseBusy()
8941 statusByte = WaitOnBaseBusy(chan); // wait for busy to be clear, up to 2 msec
8942 GetBaseStatus(chan, statusByte);
8943 if(statusByte & IDE_STATUS_ERROR) {
8944 break;
8945 }
8946 if(!(statusByte & IDE_STATUS_BUSY)) {
8947 break;
8948 }
8949 }
8950 if(i >= to_lim) {
8951 //if(regs->bOpFlags & UNIATA_SPTI_EX_FREEZE_TO) {
8952 //}
8953 AtapiResetController__(HwDeviceExtension, lChannel, RESET_COMPLETE_NONE);
8954 goto passthrough_err;
8955 }
8956
8957 if(use_dma) {
8958 AtapiCheckInterrupt__(deviceExtension, (UCHAR)lChannel);
8959 }
8960 AtapiDmaDone(deviceExtension, DeviceNumber, lChannel, NULL);
8961 GetBaseStatus(chan, statusByte);
8962
8963 if(statusByte & (IDE_STATUS_BUSY | IDE_STATUS_ERROR)) {
8964 AtapiSuckPort2(chan);
8965passthrough_err:
8966 if (Srb->SenseInfoBuffer) {
8967
8969
8970 senseBuffer->ErrorCode = 0x70;
8971 senseBuffer->Valid = 1;
8972 senseBuffer->AdditionalSenseLength = 0xb;
8973 senseBuffer->SenseKey = SCSI_SENSE_ABORTED_COMMAND;
8974 senseBuffer->AdditionalSenseCode = 0;
8975 senseBuffer->AdditionalSenseCodeQualifier = 0;
8976
8979 }
8981 } else {
8982
8983 if(!use_dma) {
8984 if (statusByte & IDE_STATUS_DRQ) {
8986 ReadBuffer(chan,
8989 0);
8990 } else if (Srb->SrbFlags & SRB_FLAGS_DATA_OUT) {
8991 WriteBuffer(chan,
8994 0);
8995 }
8996 }
8997 }
8999 }
9000passthrough_done:;
9001 AtapiEnableInterrupts(deviceExtension, lChannel);
9002
9003 } else { // read task register
9004
9005 BOOLEAN use48;
9007
9009 "IdeSendCommand: SCSIOP_ATA_PASSTHROUGH (snap) PATH:LUN:TID = %#x:%#x:%#x\n",
9010 Srb->PathId, Srb->Lun, Srb->TargetId));
9011
9012 if((Srb->DataTransferLength >= sizeof(IDEREGS_EX)) &&
9013 (regs->bOpFlags & ATA_FLAGS_48BIT_COMMAND)) {
9014 use48 = TRUE;
9015 } else
9016 if(Srb->DataTransferLength >= sizeof(IDEREGS)) {
9017 use48 = FALSE;
9018 } else {
9019 KdPrint2((PRINT_PREFIX " buffer too small \n"));
9021 break;
9022 }
9023 RtlZeroMemory(regs, use48 ? sizeof(IDEREGS_EX) : sizeof(IDEREGS));
9024 regs->bOpFlags = use48 ? ATA_FLAGS_48BIT_COMMAND : 0;
9025 UniataSnapAtaRegs(chan, 0, regs);
9026
9028 }
9029 break;
9030 }
9031
9032 default:
9033default_abort:
9035 "IdeSendCommand: Unsupported command %#x\n",
9036 Srb->Cdb[0]));
9037
9039
9040 } // end switch
9041
9042 if(status == SRB_STATUS_PENDING) {
9043 KdPrint2((PRINT_PREFIX "IdeSendCommand: SRB_STATUS_PENDING\n"));
9044 if(CmdAction & CMD_ACTION_EXEC) {
9045 KdPrint2((PRINT_PREFIX "IdeSendCommand: REQ_STATE_EXPECTING_INTR\n"));
9047 }
9048 } else {
9049 KdPrint2((PRINT_PREFIX "IdeSendCommand: REQ_STATE_TRANSFER_COMPLETE\n"));
9051 }
9052
9053 return status;
9054
9055} // end IdeSendCommand()
UCHAR const AtaCommandFlags[256]
Definition: atacmd_map.h:25
#define IDE_COMMAND_GET_MEDIA_STATUS
Definition: atapi.h:116
#define IDE_COMMAND_MEDIA_EJECT
Definition: atapi.h:119
#define ATA_WAIT_READY
Definition: bsmaster.h:57
#define REQ_STATE_EXPECTING_INTR
Definition: bsmaster.h:950
#define ATA_IMMEDIATE
Definition: bsmaster.h:55
#define ATA_WAIT_INTR
Definition: bsmaster.h:56
#define SCSISTAT_CHECK_CONDITION
Definition: cdrw_hw.h:1079
struct _MODE_POWER_CONDITION_PAGE * PMODE_POWER_CONDITION_PAGE
struct _MODE_CACHING_PAGE * PMODE_CACHING_PAGE
#define SCSI_ADSENSE_INVALID_CDB
Definition: cdrw_hw.h:1265
struct _MODE_POWER_CONDITION_PAGE MODE_POWER_CONDITION_PAGE
#define SCSIOP_MEDIUM_REMOVAL
Definition: cdrw_hw.h:902
#define DIRECT_ACCESS_DEVICE
Definition: cdrw_hw.h:1144
struct _MODE_CACHING_PAGE MODE_CACHING_PAGE
#define MODE_PAGE_CACHING
Definition: cdrw_hw.h:846
#define SCSIOP_VERIFY12
Definition: cdrw_hw.h:962
#define SCSIOP_FLUSH_BUFFER
Definition: cdrw_hw.h:886
#define SCSIOP_VERIFY
Definition: cdrw_hw.h:912
#define MODE_PAGE_POWER_CONDITION
Definition: cdrw_hw.h:850
#define MODE_DSP_WRITE_PROTECT
Definition: cdrw_hw.h:2523
#define SCSIOP_START_STOP_UNIT
Definition: cdrw_hw.h:897
#define SCSIOP_SYNCHRONIZE_CACHE
Definition: cdrw_hw.h:918
#define SCSIOP_REPORT_LUNS
Definition: scsi.h:921
#define SCSIOP_SA_READ_CAPACITY16
Definition: scsi.h:919
#define StartStop_Power_Sleep
Definition: scsi.h:409
#define SCSIOP_SERVICE_ACTION16
Definition: scsi.h:917
#define SCSIOP_VERIFY16
Definition: scsi.h:916
#define StartStop_Power_Idle
Definition: scsi.h:407
struct _REPORT_LUNS_INFO_HDR * PREPORT_LUNS_INFO_HDR
#define StartStop_Power_Standby
Definition: scsi.h:408
#define IDX_IO1_o_BlockNumber
Definition: hwide.h:56
#define IDX_IO1_o_CylinderHigh
Definition: hwide.h:58
#define IDX_IO1_o_Feature
Definition: hwide.h:54
#define IDX_IO1_o_DriveSelect
Definition: hwide.h:59
#define IDX_IO1_o_Command
Definition: hwide.h:60
#define IDX_IO1_o_BlockCount
Definition: hwide.h:55
ULONG NTAPI IdeBuildSenseBuffer(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:9145
#define SetCheckPoint(cp)
Definition: id_ata.cpp:8228
ULONG NTAPI IdeReadWrite(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb, IN ULONG CmdAction)
Definition: id_ata.cpp:6905
BOOLEAN NTAPI AtapiCheckInterrupt__(IN PVOID HwDeviceExtension, IN UCHAR c)
Definition: id_ata.cpp:4512
ULONG NTAPI IdeVerify(IN PVOID HwDeviceExtension, IN PSCSI_REQUEST_BLOCK Srb)
Definition: id_ata.cpp:7261
#define RESET_COMPLETE_NONE
Definition: id_ata.cpp:145
UCHAR NTAPI UniataAhciSendPIOCommandDirect(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PIDEREGS_EX regs, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1655
ULONGLONG NumOfSectors
Definition: bsmaster.h:1163
USHORT NumberOfCylinders
Definition: atapi.h:250
Definition: helper.h:8
UCHAR WriteCacheEnable
Definition: cdrw_hw.h:2779
UCHAR ReadDisableCache
Definition: cdrw_hw.h:2777
union _MODE_POWER_CONDITION_PAGE::@894 Byte3
struct _MODE_POWER_CONDITION_PAGE::@894::@895 Fields
UCHAR ListLength[4]
Definition: scsi.h:2932
ULONG TimeOutValue
Definition: srb.h:262
#define max(a, b)
Definition: svc.c:63
uint64_t ULONGLONG
Definition: typedefs.h:67
#define UNIATA_SPTI_EX_USE_DMA
Definition: uata_ctl.h:258
#define UNIATA_SPTI_EX_SPEC_TO
Definition: uata_ctl.h:261
#define ATA_FLAGS_48BIT_COMMAND
Definition: uata_ctl.h:223
#define IDE_COMMAND_IDLE_IMMED
Definition: atapi.h:396
#define ATA_CMD_FLAG_DMA
Definition: atapi.h:1600
#define DFLAGS_RCACHE_ENABLED
Definition: atapi.h:250
#define IDE_COMMAND_SLEEP
Definition: atapi.h:400
#define IDE_COMMAND_STANDBY_IMMED
Definition: atapi.h:395
#define IDE_COMMAND_DOOR_UNLOCK
Definition: atapi.h:394
#define IDE_COMMAND_DOOR_LOCK
Definition: atapi.h:393
struct _CDB::_SERVICE_ACTION16 SERVICE_ACTION16
struct _CDB::_MEDIA_REMOVAL MEDIA_REMOVAL
struct _CDB::_START_STOP START_STOP
struct _CDB::_MODE_SENSE MODE_SENSE
struct _CDB::_REPORT_LUNS REPORT_LUNS

Referenced by AtapiStartIo__().

◆ IssueIdentify()

BOOLEAN NTAPI IssueIdentify ( IN PVOID  HwDeviceExtension,
IN ULONG  DeviceNumber,
IN ULONG  Channel,
IN UCHAR  Command,
IN BOOLEAN  NoSetup 
)

deviceExtension->DWordIO

Definition at line 1529 of file id_ata.cpp.

1536{
1537 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
1538 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
1539 ULONG waitCount = 50000;
1540 ULONG j;
1541 UCHAR statusByte;
1542 //UCHAR statusByte2;
1543 UCHAR signatureLow,
1544 signatureHigh;
1545 BOOLEAN atapiDev = FALSE;
1546 BOOLEAN use_ahci = FALSE;
1547 PHW_LU_EXTENSION LunExt = chan->lun[DeviceNumber];
1548
1549 use_ahci = UniataIsSATARangeAvailable(deviceExtension, lChannel) &&
1550 (deviceExtension->HwFlags & UNIATA_AHCI);
1551
1553 if(chan->PmLunMap & (1 << DeviceNumber)) {
1554 // OK
1555 } else {
1556 KdPrint2((PRINT_PREFIX "IssueIdentify: PM empty port\n"));
1557 return FALSE;
1558 }
1559 } else
1561 KdPrint2((PRINT_PREFIX "IssueIdentify: NO SLAVE\n"));
1562 return FALSE;
1563 }
1564 if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
1565 KdPrint2((PRINT_PREFIX "IssueIdentify: HIDDEN\n"));
1566 return FALSE;
1567 }
1568
1569 if(use_ahci) {
1570 statusByte = WaitOnBusyLong(chan);
1571#ifdef _DEBUG
1572 if(!chan->AhciInternalAtaReq) {
1573 KdPrint2((PRINT_PREFIX "!AhciInternalAtaReq\n"));
1574 }
1575#endif
1576 } else {
1579 statusByte = WaitOnBusyLong(chan);
1580 // Check that the status register makes sense.
1581 GetBaseStatus(chan, statusByte);
1582 /*
1583 // unnecessary
1584 if(!hasPCI) {
1585 // original atapi.sys behavior for old ISA-only hardware
1586 AtapiStallExecution(100);
1587 }
1588 */
1589 }
1590
1592 // Mask status byte ERROR bits.
1593 statusByte = UniataIsIdle(deviceExtension, statusByte & ~(IDE_STATUS_ERROR | IDE_STATUS_INDEX));
1594 KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for IDE. Status (%#x)\n", statusByte));
1595 // Check if register value is reasonable.
1596
1597 if(statusByte != IDE_STATUS_IDLE) {
1598
1599 // No reset here !!!
1600 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte != IDE_STATUS_IDLE\n"));
1601
1602 //if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
1603 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1605 WaitOnBusyLong(chan);
1606
1607 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1608 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1609
1610 if (signatureLow == ATAPI_MAGIC_LSB &&
1611 signatureHigh == ATAPI_MAGIC_MSB) {
1612 // Device is Atapi.
1613 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (dev %d)\n", DeviceNumber));
1614 return FALSE;
1615 }
1616
1617 // We really should wait up to 31 seconds
1618 // The ATA spec. allows device 0 to come back from BUSY in 31 seconds!
1619 // (30 seconds for device 1)
1620 do {
1621 // Wait for Busy to drop.
1623 GetStatus(chan, statusByte);
1624 if(statusByte == IDE_STATUS_WRONG) {
1625 KdPrint2((PRINT_PREFIX "IssueIdentify: IDE_STATUS_WRONG (dev %d)\n", DeviceNumber));
1626 return FALSE;
1627 }
1628
1629 } while ((statusByte & IDE_STATUS_BUSY) && waitCount--);
1630 GetBaseStatus(chan, statusByte);
1631
1633 } else {
1634 GetBaseStatus(chan, statusByte);
1635 }
1636 // Another check for signature, to deal with one model Atapi that doesn't assert signature after
1637 // a soft reset.
1638 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1639 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1640
1641 if (signatureLow == ATAPI_MAGIC_LSB &&
1642 signatureHigh == ATAPI_MAGIC_MSB) {
1643 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (2) (dev %d)\n", DeviceNumber));
1644 // Device is Atapi.
1645 return FALSE;
1646 }
1647
1648 statusByte = UniataIsIdle(deviceExtension, statusByte) & ~IDE_STATUS_INDEX;
1649 if (statusByte != IDE_STATUS_IDLE) {
1650 // Give up on this.
1651 KdPrint2((PRINT_PREFIX "IssueIdentify: no dev (dev %d)\n", DeviceNumber));
1652 return FALSE;
1653 }
1654 }
1655 } else {
1656 KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI. Status (%#x)\n", statusByte));
1657 if(statusByte == IDE_STATUS_WRONG) {
1658 return FALSE;
1659 }
1660 //if(!(deviceExtension->HwFlags & UNIATA_SATA)) {
1661 if(!UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1662 statusByte = WaitForIdleLong(chan);
1663 KdPrint2((PRINT_PREFIX "IssueIdentify: Checking for ATAPI (2). Status (%#x)\n", statusByte));
1664 }
1665 atapiDev = TRUE;
1666 }
1667
1668// if(deviceExtension->HwFlags & UNIATA_SATA) {
1669 if(use_ahci) {
1670 statusByte = UniataAhciSendPIOCommand(HwDeviceExtension, lChannel, DeviceNumber,
1672 (PUCHAR)(&deviceExtension->FullIdentifyData),
1673 DEV_BSIZE,
1674 Command,
1675 0, 0,
1676 0,
1677 0 /* ahci flags */ ,
1679 1000 /* timeout 1 sec */
1680 );
1681 j = 9; // AHCI is rather different, skip loop at all
1682 } else
1683 if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
1684 j = 9; // don't send IDENTIFY, assume it is not supported
1685 KdPrint2((PRINT_PREFIX "IssueIdentify: Manual CHS\n"));
1686 RtlZeroMemory(&(deviceExtension->FullIdentifyData), sizeof(deviceExtension->FullIdentifyData));
1687 RtlCopyMemory(&(deviceExtension->FullIdentifyData), &(LunExt->IdentifyData), sizeof(LunExt->IdentifyData));
1688 } else
1689 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
1690 j = 4; // skip old-style checks
1691 } else {
1692 j = 0;
1693 }
1694 for (; j < 4*2; j++) {
1695 // Send IDENTIFY command.
1696
1697 // Load CylinderHigh and CylinderLow with number bytes to transfer for old devices, use 0 for newer.
1698
1699 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, Command, (j < 4) ? DEV_BSIZE : 0 /* cyl */, 0, 0, 0, 0, ATA_WAIT_INTR);
1700 // Clear interrupt
1701
1702 if (!statusByte) {
1703 KdPrint2((PRINT_PREFIX "IssueIdentify: 0-status, not present\n"));
1704 return FALSE;
1705 } else
1706 if (statusByte & IDE_STATUS_DRQ) {
1707 // Read status to acknowledge any interrupts generated.
1708 KdPrint2((PRINT_PREFIX "IssueIdentify: IDE_STATUS_DRQ (%#x)\n", statusByte));
1709 GetBaseStatus(chan, statusByte);
1710 // One last check for Atapi.
1712 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1713 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1714
1715 if (signatureLow == ATAPI_MAGIC_LSB &&
1716 signatureHigh == ATAPI_MAGIC_MSB) {
1717 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (3) (dev %d)\n", DeviceNumber));
1718 // Device is Atapi.
1719 return FALSE;
1720 }
1721 }
1722 break;
1723 } else {
1724 KdPrint2((PRINT_PREFIX "IssueIdentify: !IDE_STATUS_DRQ (%#x)\n", statusByte));
1726 // Check the signature. If DRQ didn't come up it's likely Atapi.
1727 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
1728 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
1729
1730 if (signatureLow == ATAPI_MAGIC_LSB &&
1731 signatureHigh == ATAPI_MAGIC_MSB) {
1732 // Device is Atapi.
1733 KdPrint2((PRINT_PREFIX "IssueIdentify: this is ATAPI (4) (dev %d)\n", DeviceNumber));
1734 return FALSE;
1735 }
1736 } else {
1737 if(!(statusByte & IDE_STATUS_ERROR) && (statusByte & IDE_STATUS_BUSY)) {
1738 KdPrint2((PRINT_PREFIX "IssueIdentify: DRQ not asserted immediately, BUSY -> WaitForDrq\n"));
1739 break;
1740 }
1741 }
1742 // Device didn't respond correctly. It will be given one more chance.
1743 KdPrint2((PRINT_PREFIX "IssueIdentify: DRQ never asserted (%#x). Error reg (%#x)\n",
1744 statusByte, AtapiReadPort1(chan, IDX_IO1_i_Error)));
1745 GetBaseStatus(chan, statusByte);
1747
1748 AtapiDisableInterrupts(deviceExtension, lChannel);
1749 AtapiEnableInterrupts(deviceExtension, lChannel);
1750
1751 GetBaseStatus(chan, statusByte);
1752 //GetStatus(chan, statusByte);
1753 KdPrint2((PRINT_PREFIX "IssueIdentify: Status after soft reset (%#x)\n", statusByte));
1754 }
1755 }
1756 // Check for error on really stupid master devices that assert random
1757 // patterns of bits in the status register at the slave address.
1758 if ((Command == IDE_COMMAND_IDENTIFY) && (statusByte & IDE_STATUS_ERROR)) {
1759 KdPrint2((PRINT_PREFIX "IssueIdentify: Exit on error (%#x)\n", statusByte));
1760 return FALSE;
1761 }
1762
1763 if(use_ahci) {
1764 // everything should already be done by controller
1765 } else
1766 if(LunExt->DeviceFlags & DFLAGS_MANUAL_CHS) {
1767 j = 9; // don't send IDENTIFY, assume it is not supported
1768 KdPrint2((PRINT_PREFIX "IssueIdentify: Manual CHS (2)\n"));
1769 statusByte = WaitForDrq(chan);
1770 statusByte = WaitOnBusyLong(chan);
1771 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1772 GetBaseStatus(chan, statusByte);
1773 } else {
1774
1775 KdPrint2((PRINT_PREFIX "IssueIdentify: Status before read words %#x\n", statusByte));
1776 // Suck out 256 words. After waiting for one model that asserts busy
1777 // after receiving the Packet Identify command.
1778 statusByte = WaitForDrq(chan);
1779 statusByte = WaitOnBusyLong(chan);
1780 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1781
1782 if (!(statusByte & IDE_STATUS_DRQ)) {
1783 KdPrint2((PRINT_PREFIX "IssueIdentify: !IDE_STATUS_DRQ (2) (%#x)\n", statusByte));
1784 GetBaseStatus(chan, statusByte);
1785 return FALSE;
1786 }
1787 GetBaseStatus(chan, statusByte);
1788 KdPrint2((PRINT_PREFIX "IssueIdentify: BASE statusByte %#x\n", statusByte));
1789
1790#ifdef _DEBUG
1791 if(atapiDev) {
1793 KdPrint3((PRINT_PREFIX "IssueIdentify: iReason %x\n", j));
1794
1795 j =
1797
1798 j |=
1800 KdPrint3((PRINT_PREFIX "IssueIdentify: wCount %x\n", j));
1801
1802 }
1803#endif //_DEBUG
1804
1805 if (atapiDev || !(LunExt->DeviceFlags & DFLAGS_DWORDIO_ENABLED) ) {
1806
1807 KdPrint2((PRINT_PREFIX " use 16bit IO\n"));
1808 // ATI/SII chipsets with memory-mapped IO hangs when
1809 // I call ReadBuffer(), probably due to PCI burst/prefetch enabled
1810 // Unfortunately, I don't know yet how to workaround it except
1811 // spacifying manual delay in the way you see below.
1812 ReadBuffer(chan, (PUSHORT)&deviceExtension->FullIdentifyData, 256, PIO0_TIMING);
1813
1814 // Work around for some IDE and one model Atapi that will present more than
1815 // 256 bytes for the Identify data.
1816 KdPrint2((PRINT_PREFIX "IssueIdentify: suck data port\n", statusByte));
1817 statusByte = AtapiSuckPort2(chan);
1818 } else {
1819 KdPrint2((PRINT_PREFIX " use 32bit IO\n"));
1820 ReadBuffer2(chan, (PULONG)&deviceExtension->FullIdentifyData, 256/2, PIO0_TIMING);
1821 }
1822
1823 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1824 statusByte = WaitForDrq(chan);
1825 KdPrint2((PRINT_PREFIX "IssueIdentify: statusByte %#x\n", statusByte));
1826 GetBaseStatus(chan, statusByte);
1827 }
1828 KdPrint2((PRINT_PREFIX "IssueIdentify: Status after read words %#x\n", statusByte));
1829
1830 if(NoSetup) {
1831 KdPrint2((PRINT_PREFIX "IssueIdentify: no setup, exiting\n"));
1832 return TRUE;
1833 }
1834
1835 KdPrint2((PRINT_PREFIX "Model: %20.20s\n", deviceExtension->FullIdentifyData.ModelNumber));
1836 KdPrint2((PRINT_PREFIX "FW: %4.4s\n", deviceExtension->FullIdentifyData.FirmwareRevision));
1837 KdPrint2((PRINT_PREFIX "S/N: %20.20s\n", deviceExtension->FullIdentifyData.SerialNumber));
1839 if((deviceExtension->FullIdentifyData.FirmwareRevision[0] == 0 ||
1840 deviceExtension->FullIdentifyData.FirmwareRevision[0] == ' ') &&
1841 (deviceExtension->FullIdentifyData.FirmwareRevision[1] == 0 ||
1842 deviceExtension->FullIdentifyData.FirmwareRevision[1] == ' ')) {
1843 // Check for BOCHS VM signature. If no additional PCI devices (e.g. VGA)
1844 // are declared BOCHS looks like regular PC
1845 if (!atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDH00", 6)) {
1846 KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS HDD\n"));
1848 } else
1849 if (atapiDev && !AtapiStringCmp ((PCCHAR)(deviceExtension->FullIdentifyData.SerialNumber), "XBDC00", 6)) {
1850 KdPrint2((PRINT_PREFIX "IssueIdentify: BOCHS CD\n"));
1852 }
1853 }
1854 }
1855
1856 KdPrint2((PRINT_PREFIX "Pio: %x\n", deviceExtension->FullIdentifyData.PioCycleTimingMode));
1857 if(deviceExtension->FullIdentifyData.PioTimingsValid) {
1858 KdPrint2((PRINT_PREFIX "APio: %x\n", deviceExtension->FullIdentifyData.AdvancedPIOModes));
1859 }
1860 KdPrint2((PRINT_PREFIX "SWDMA: %x\n", deviceExtension->FullIdentifyData.SingleWordDMAActive));
1861 KdPrint2((PRINT_PREFIX "MWDMA: %x\n", deviceExtension->FullIdentifyData.MultiWordDMAActive));
1862 if(deviceExtension->FullIdentifyData.UdmaModesValid) {
1863 KdPrint2((PRINT_PREFIX "UDMA: %x/%x\n", deviceExtension->FullIdentifyData.UltraDMAActive, deviceExtension->FullIdentifyData.UltraDMASupport));
1864 }
1865 KdPrint2((PRINT_PREFIX "SATA: %x\n", deviceExtension->FullIdentifyData.SataEnable));
1866 KdPrint2((PRINT_PREFIX "SATA support: %x, CAPs %#x\n",
1867 deviceExtension->FullIdentifyData.SataSupport,
1868 deviceExtension->FullIdentifyData.SataCapabilities));
1869
1870 LunExt->LimitedTransferMode =
1871 LunExt->OrigTransferMode =
1873 LunExt->TransferMode =
1875
1876 KdPrint2((PRINT_PREFIX "OrigTransferMode: %x, Active: %x\n", LunExt->OrigTransferMode, LunExt->TransferMode));
1877 KdPrint2((PRINT_PREFIX "Accoustic %d, cur %d\n",
1878 deviceExtension->FullIdentifyData.VendorAcoustic,
1879 deviceExtension->FullIdentifyData.CurrentAcoustic
1880 ));
1881 KdPrint2((PRINT_PREFIX "AdvPowerMode %d\n",
1882 deviceExtension->FullIdentifyData.CfAdvPowerMode
1883 ));
1884
1885 KdPrint2((PRINT_PREFIX "PowerMngt %d/%d, APM %d/%d\n",
1886 deviceExtension->FullIdentifyData.FeaturesEnabled.PowerMngt,
1887 deviceExtension->FullIdentifyData.FeaturesSupport.PowerMngt,
1888 deviceExtension->FullIdentifyData.FeaturesEnabled.APM,
1889 deviceExtension->FullIdentifyData.FeaturesSupport.APM
1890 ));
1891
1892 // Check out a few capabilities / limitations of the device.
1893 if (deviceExtension->FullIdentifyData.RemovableStatus & 1) {
1894 // Determine if this drive supports the MSN functions.
1895 KdPrint2((PRINT_PREFIX "IssueIdentify: Marking drive %d as removable. SFE = %d\n",
1897 deviceExtension->FullIdentifyData.RemovableStatus));
1899 }
1900 if(use_ahci) {
1901 // AHCI doesn't recommend using PIO and multiblock
1902 LunExt->MaximumBlockXfer = 0;
1903 } else
1904 if (deviceExtension->FullIdentifyData.MaximumBlockTransfer) {
1905 // Determine max. block transfer for this device.
1906 LunExt->MaximumBlockXfer =
1907 (UCHAR)(deviceExtension->FullIdentifyData.MaximumBlockTransfer & 0xFF);
1908 }
1909 LunExt->NumOfSectors = 0;
1911 ULONGLONG NumOfSectors=0;
1912 ULONGLONG NativeNumOfSectors=0;
1913 ULONGLONG cylinders=0;
1914 ULONGLONG tmp_cylinders=0;
1915
1916 KdPrint2((PRINT_PREFIX "PhysLogSectorSize %#x, %#x, offset %#x\n",
1917 deviceExtension->FullIdentifyData.PhysLogSectorSize,
1918 deviceExtension->FullIdentifyData.LargeSectorSize,
1919 deviceExtension->FullIdentifyData.LogicalSectorOffset
1920 ));
1921
1922 KdPrint2((PRINT_PREFIX "NV PM_Sup %d, PM_En %d, En %d, PM ver %#x ver %#x\n",
1923 deviceExtension->FullIdentifyData.NVCache_PM_Supported,
1924 deviceExtension->FullIdentifyData.NVCache_PM_Enabled,
1925 deviceExtension->FullIdentifyData.NVCache_Enabled,
1926 deviceExtension->FullIdentifyData.NVCache_PM_Version,
1927 deviceExtension->FullIdentifyData.NVCache_Version
1928 ));
1929
1930 KdPrint2((PRINT_PREFIX "R-rate %d\n",
1932 ));
1933 KdPrint2((PRINT_PREFIX "WC %d/%d, LA %d/%d, WB %d/%d, RB %d/%d, Q %d/%d\n",
1934 deviceExtension->FullIdentifyData.FeaturesEnabled.WriteCache,
1935 deviceExtension->FullIdentifyData.FeaturesSupport.WriteCache,
1936 deviceExtension->FullIdentifyData.FeaturesEnabled.LookAhead,
1937 deviceExtension->FullIdentifyData.FeaturesSupport.LookAhead,
1938 deviceExtension->FullIdentifyData.FeaturesEnabled.WriteBuffer,
1939 deviceExtension->FullIdentifyData.FeaturesSupport.WriteBuffer,
1940 deviceExtension->FullIdentifyData.FeaturesEnabled.ReadBuffer,
1941 deviceExtension->FullIdentifyData.FeaturesSupport.ReadBuffer,
1942 deviceExtension->FullIdentifyData.FeaturesEnabled.Queued,
1943 deviceExtension->FullIdentifyData.FeaturesSupport.Queued
1944 ));
1945
1946 KdPrint2((PRINT_PREFIX "Protected %d/%d status %#x, rev %#x\n",
1947 deviceExtension->FullIdentifyData.FeaturesEnabled.Protected,
1948 deviceExtension->FullIdentifyData.FeaturesSupport.Protected,
1949 deviceExtension->FullIdentifyData.SecurityStatus,
1950 deviceExtension->FullIdentifyData.MasterPasswdRevision
1951 ));
1952
1953 // Read very-old-style drive geometry
1954 KdPrint2((PRINT_PREFIX "CHS %#x:%#x:%#x\n",
1955 deviceExtension->FullIdentifyData.NumberOfCylinders,
1956 deviceExtension->FullIdentifyData.NumberOfHeads,
1957 deviceExtension->FullIdentifyData.SectorsPerTrack
1958 ));
1959 NumOfSectors = deviceExtension->FullIdentifyData.NumberOfCylinders *
1960 deviceExtension->FullIdentifyData.NumberOfHeads *
1961 deviceExtension->FullIdentifyData.SectorsPerTrack;
1962 KdPrint2((PRINT_PREFIX "NumOfSectors %#I64x\n", NumOfSectors));
1963 // Check for HDDs > 8Gb
1964 if ((deviceExtension->FullIdentifyData.NumberOfCylinders == 0x3fff) &&
1965/* (deviceExtension->FullIdentifyData.TranslationFieldsValid) &&*/
1966 deviceExtension->FullIdentifyData.NumberOfHeads &&
1967 deviceExtension->FullIdentifyData.SectorsPerTrack &&
1968 (NumOfSectors < deviceExtension->FullIdentifyData.UserAddressableSectors)) {
1969 KdPrint2((PRINT_PREFIX "NumberOfCylinders == 0x3fff\n"));
1970 cylinders =
1971 (deviceExtension->FullIdentifyData.UserAddressableSectors /
1972 (deviceExtension->FullIdentifyData.NumberOfHeads *
1973 deviceExtension->FullIdentifyData.SectorsPerTrack));
1974
1975 KdPrint2((PRINT_PREFIX "cylinders %#I64x\n", cylinders));
1976
1977 NumOfSectors = cylinders *
1978 deviceExtension->FullIdentifyData.NumberOfHeads *
1979 deviceExtension->FullIdentifyData.SectorsPerTrack;
1980
1981 KdPrint2((PRINT_PREFIX "NumOfSectors %#I64x\n", NumOfSectors));
1982 } else {
1983
1984 }
1985 // Check for LBA mode
1986 KdPrint2((PRINT_PREFIX "SupportLba flag %#x\n", deviceExtension->FullIdentifyData.SupportLba));
1987 KdPrint2((PRINT_PREFIX "SupportDMA flag %#x\n", deviceExtension->FullIdentifyData.SupportDma));
1988 KdPrint2((PRINT_PREFIX "SoftReset %#x\n", deviceExtension->FullIdentifyData.SoftReset));
1989 KdPrint2((PRINT_PREFIX "SupportIordy %#x, DisableIordy %#x\n",
1990 deviceExtension->FullIdentifyData.SupportIordy,
1991 deviceExtension->FullIdentifyData.DisableIordy
1992 ));
1993 KdPrint2((PRINT_PREFIX "MajorRevision %#x\n", deviceExtension->FullIdentifyData.MajorRevision));
1994 KdPrint2((PRINT_PREFIX "UserAddressableSectors %#x\n", deviceExtension->FullIdentifyData.UserAddressableSectors));
1995 if ( deviceExtension->FullIdentifyData.SupportLba
1996 ||
1997 (deviceExtension->FullIdentifyData.MajorRevision &&
1998/* deviceExtension->FullIdentifyData.TranslationFieldsValid &&*/
1999 deviceExtension->FullIdentifyData.UserAddressableSectors)) {
2000 KdPrint2((PRINT_PREFIX "LBA mode\n"));
2002 } else {
2003 KdPrint2((PRINT_PREFIX "Keep orig geometry\n"));
2005 goto skip_lba_staff;
2006 }
2007 // Check for LBA48 support
2008 if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED) {
2009 if(deviceExtension->FullIdentifyData.FeaturesSupport.Address48 &&
2010 deviceExtension->FullIdentifyData.FeaturesEnabled.Address48 &&
2011 deviceExtension->FullIdentifyData.NumberOfHeads &&
2012 deviceExtension->FullIdentifyData.SectorsPerTrack &&
2013 (deviceExtension->FullIdentifyData.UserAddressableSectors48 > NumOfSectors)
2014 ) {
2015 KdPrint2((PRINT_PREFIX "LBA48\n"));
2016 cylinders =
2017 (deviceExtension->FullIdentifyData.UserAddressableSectors48 /
2018 (deviceExtension->FullIdentifyData.NumberOfHeads *
2019 deviceExtension->FullIdentifyData.SectorsPerTrack));
2020
2021 KdPrint2((PRINT_PREFIX "cylinders %#I64x\n", cylinders));
2022
2023 NativeNumOfSectors = cylinders *
2024 deviceExtension->FullIdentifyData.NumberOfHeads *
2025 deviceExtension->FullIdentifyData.SectorsPerTrack;
2026
2027 KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
2028
2029 if(NativeNumOfSectors > NumOfSectors) {
2030 KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
2031 NumOfSectors = NativeNumOfSectors;
2032 }
2033 }
2034
2035 // Check drive capacity report for LBA48-capable drives.
2036 if(deviceExtension->FullIdentifyData.FeaturesSupport.Address48) {
2037 ULONG hNativeNumOfSectors;
2038 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_READ_NATIVE_SIZE48\n"));
2039
2040 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2042
2043 if(!(statusByte & IDE_STATUS_ERROR)) {
2044 if(use_ahci) {
2045 NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
2046 } else {
2047 NativeNumOfSectors = (ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
2050
2053
2054 KdPrint2((PRINT_PREFIX "Read high order bytes\n"));
2055 NativeNumOfSectors |=
2057 hNativeNumOfSectors=
2060 ((PULONG)&NativeNumOfSectors)[1] = hNativeNumOfSectors;
2061 }
2062 KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
2063
2064 // Some drives report LBA48 capability while has capacity below 128Gb
2065 // Probably they support large block-counters.
2066 // But the problem is that some of them reports higher part of Max LBA equal to lower part.
2067 // Here we check this
2068 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2069 KdPrint2((PRINT_PREFIX "High-order bytes == Low-order bytes !!!\n"));
2070
2071 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2073
2074 if(!(statusByte & IDE_STATUS_ERROR)) {
2075 if(use_ahci) {
2076 NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
2077 } else {
2078 NativeNumOfSectors = (ULONGLONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
2084 ;
2085 }
2086 }
2087
2088 if((NativeNumOfSectors & 0xffffff) == ((NativeNumOfSectors >> 24) & 0xffffff)) {
2089 KdPrint2((PRINT_PREFIX "High-order bytes == Low-order bytes !!! (2)\n"));
2090 NativeNumOfSectors = 0;
2091 }
2092 }
2093
2094 if(NumOfSectors <= ATA_MAX_LBA28 &&
2095 NativeNumOfSectors > NumOfSectors) {
2096
2097 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_SET_NATIVE_SIZE48\n"));
2098 KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
2099
2100 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2101 IDE_COMMAND_SET_NATIVE_SIZE, NativeNumOfSectors, 0, 0, ATA_WAIT_READY);
2102 if(!(statusByte & IDE_STATUS_ERROR)) {
2103 NumOfSectors = NativeNumOfSectors;
2104 }
2105 }
2106 } // !error
2107 }
2108
2109 if(NumOfSectors < 0x2100000 /*&& NumOfSectors > 31*1000*1000*/) {
2110 // check for native LBA size
2111 // some drives report ~32Gb in Identify Block
2112 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_READ_NATIVE_SIZE\n"));
2113
2114 statusByte = AtaCommand(deviceExtension, DeviceNumber, lChannel, IDE_COMMAND_READ_NATIVE_SIZE,
2115 0, IDE_USE_LBA, 0, 0, 0, ATA_WAIT_READY);
2116
2117 if(!(statusByte & IDE_STATUS_ERROR)) {
2118 if(use_ahci) {
2119 NativeNumOfSectors = chan->AhciInternalAtaReq->ahci.in_lba;
2120 } else {
2121 NativeNumOfSectors = (ULONG)AtapiReadPort1(chan, IDX_IO1_i_BlockNumber) |
2124 (((ULONG)AtapiReadPort1(chan, IDX_IO1_i_DriveSelect) & 0xf) << 24);
2125 }
2126 KdPrint2((PRINT_PREFIX "NativeNumOfSectors %#I64x\n", NativeNumOfSectors));
2127
2128 if(NativeNumOfSectors > NumOfSectors) {
2129
2130 KdPrint2((PRINT_PREFIX "Use IDE_COMMAND_SET_NATIVE_SIZE\n"));
2131 KdPrint2((PRINT_PREFIX "Update NumOfSectors to %#I64x\n", NativeNumOfSectors));
2132
2133 statusByte = AtaCommand48(deviceExtension, DeviceNumber, lChannel,
2134 IDE_COMMAND_SET_NATIVE_SIZE, NativeNumOfSectors, 0, 0, ATA_WAIT_READY);
2135 if(!(statusByte & IDE_STATUS_ERROR)) {
2136 NumOfSectors = NativeNumOfSectors;
2137 }
2138 }
2139 }
2140 }
2141
2142 if(NumOfSectors > ATA_MAX_IOLBA28) {
2143 KdPrint2((PRINT_PREFIX "2TB threshold, force LBA64 WRITE requirement\n"));
2144 LunExt->DeviceFlags |= DFLAGS_LBA32plus;
2145 }
2146 } // if(LunExt->DeviceFlags & DFLAGS_LBA_ENABLED)
2147
2148 // fill IdentifyData with bogus geometry
2149 KdPrint2((PRINT_PREFIX "requested LunExt->GeomType=%x\n", LunExt->opt_GeomType));
2150 if(deviceExtension->FullIdentifyData.CurrentSectorsPerTrack &&
2151 deviceExtension->FullIdentifyData.NumberOfCurrentHeads) {
2152 tmp_cylinders = NumOfSectors / (deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *
2153 deviceExtension->FullIdentifyData.NumberOfCurrentHeads);
2154 } else
2155 if(deviceExtension->FullIdentifyData.SectorsPerTrack &&
2156 deviceExtension->FullIdentifyData.NumberOfHeads) {
2157 KdPrint2((PRINT_PREFIX "Current C/H = %#I64x/%#I64x\n",
2159 deviceExtension->FullIdentifyData.NumberOfCurrentHeads));
2160 tmp_cylinders = NumOfSectors / (deviceExtension->FullIdentifyData.SectorsPerTrack *
2161 deviceExtension->FullIdentifyData.NumberOfHeads);
2162 } else {
2163 tmp_cylinders = 0;
2164 }
2165 KdPrint2((PRINT_PREFIX "tmp_cylinders = %#I64x\n", tmp_cylinders));
2166 if((tmp_cylinders < 0xffff) || (LunExt->opt_GeomType == GEOM_ORIG)) {
2167 // ok, we can keep original values
2168 if(LunExt->opt_GeomType == GEOM_AUTO) {
2169 LunExt->opt_GeomType = GEOM_ORIG;
2170 }
2171 } else {
2172 tmp_cylinders = NumOfSectors / (255*63);
2173 if(tmp_cylinders < 0xffff) {
2174 // we can use generic values for H/S for generic geometry approach
2175 if(LunExt->opt_GeomType == GEOM_AUTO) {
2176 LunExt->opt_GeomType = GEOM_STD;
2177 }
2178 } else {
2179 // we should use UNIATA geometry approach
2180 if(LunExt->opt_GeomType == GEOM_AUTO) {
2181 LunExt->opt_GeomType = GEOM_UNIATA;
2182 }
2183 }
2184 }
2185
2186 if(!deviceExtension->FullIdentifyData.SectorsPerTrack ||
2187 !deviceExtension->FullIdentifyData.NumberOfHeads) {
2188 KdPrint2((PRINT_PREFIX "Zero S/H -> Force Use GEOM_STD\n"));
2189 }
2190
2191 if(LunExt->opt_GeomType == GEOM_STD) {
2192 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack =
2193 deviceExtension->FullIdentifyData.SectorsPerTrack = 63;
2194
2195 deviceExtension->FullIdentifyData.NumberOfCurrentHeads =
2196 deviceExtension->FullIdentifyData.NumberOfHeads = 255;
2197
2198 cylinders = NumOfSectors / (255*63);
2199 KdPrint2((PRINT_PREFIX "Use GEOM_STD, CHS=%I64x/%x/%x\n", cylinders, 255, 63));
2200 } else
2201 if(LunExt->opt_GeomType == GEOM_UNIATA) {
2202 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.SectorsPerTrack < 0x80)) {
2203 cylinders /= 2;
2204 KdPrint2((PRINT_PREFIX "cylinders /= 2\n"));
2205 deviceExtension->FullIdentifyData.SectorsPerTrack *= 2;
2206 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *= 2;
2207 }
2208 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.NumberOfHeads < 0x80)) {
2209 cylinders /= 2;
2210 KdPrint2((PRINT_PREFIX "cylinders /= 2 (2)\n"));
2211 deviceExtension->FullIdentifyData.NumberOfHeads *= 2;
2212 deviceExtension->FullIdentifyData.NumberOfCurrentHeads *= 2;
2213 }
2214 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.SectorsPerTrack < 0x8000)) {
2215 cylinders /= 2;
2216 KdPrint2((PRINT_PREFIX "cylinders /= 2 (3)\n"));
2217 deviceExtension->FullIdentifyData.SectorsPerTrack *= 2;
2218 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack *= 2;
2219 }
2220 while ((cylinders > 0xffff) && (deviceExtension->FullIdentifyData.NumberOfHeads < 0x8000)) {
2221 cylinders /= 2;
2222 KdPrint2((PRINT_PREFIX "cylinders /= 2 (4)\n"));
2223 deviceExtension->FullIdentifyData.NumberOfHeads *= 2;
2224 deviceExtension->FullIdentifyData.NumberOfCurrentHeads *= 2;
2225 }
2226 KdPrint2((PRINT_PREFIX "Use GEOM_UNIATA, CHS=%I64x/%x/%x\n", cylinders,
2227 deviceExtension->FullIdentifyData.NumberOfCurrentHeads,
2228 deviceExtension->FullIdentifyData.CurrentSectorsPerTrack));
2229 }
2230 if(!cylinders) {
2231 KdPrint2((PRINT_PREFIX "cylinders = tmp_cylinders (%x = %x)\n", cylinders, tmp_cylinders));
2232 cylinders = tmp_cylinders;
2233 }
2235 deviceExtension->FullIdentifyData.NumberOfCylinders = (USHORT)cylinders;
2236
2237skip_lba_staff:
2238
2239 KdPrint2((PRINT_PREFIX "Geometry: C %#x (%#x)\n",
2240 deviceExtension->FullIdentifyData.NumberOfCylinders,
2242 ));
2243 KdPrint2((PRINT_PREFIX "Geometry: H %#x (%#x)\n",
2244 deviceExtension->FullIdentifyData.NumberOfHeads,
2245 deviceExtension->FullIdentifyData.NumberOfCurrentHeads
2246 ));
2247 KdPrint2((PRINT_PREFIX "Geometry: S %#x (%#x)\n",
2248 deviceExtension->FullIdentifyData.SectorsPerTrack,
2250 ));
2251
2252 if(NumOfSectors) {
2253 LunExt->NumOfSectors = NumOfSectors;
2254 }
2255 if(deviceExtension->FullIdentifyData.MajorRevision &&
2256 deviceExtension->FullIdentifyData.DoubleWordIo) {
2258 KdPrint2((PRINT_PREFIX "IssueIdentify: DWORDIO supported\n"));
2259 }
2260 } else {
2261 // ATAPI
2262 if(deviceExtension->FullIdentifyData.MajorRevision &&
2263 deviceExtension->FullIdentifyData.DoubleWordIo) {
2265 KdPrint2((PRINT_PREFIX "IssueIdentify: DFLAGS_DWORDIO_ENABLED.\n"));
2266 }
2267 if(deviceExtension->FullIdentifyData.AtapiDMA.DMADirRequired) {
2268 KdPrint2((PRINT_PREFIX "DMADirRequired.\n"));
2269 }
2270 if(deviceExtension->FullIdentifyData.AtapiByteCount0) {
2271 KdPrint2((PRINT_PREFIX "AtapiByteCount0=%x\n", deviceExtension->FullIdentifyData.AtapiByteCount0));
2272 }
2273 }
2274
2276 &deviceExtension->FullIdentifyData,sizeof(IDENTIFY_DATA2));
2277
2278 InitBadBlocks(LunExt);
2279
2280 if ((LunExt->IdentifyData.DrqType & ATAPI_DRQT_INTR) &&
2282
2283 // This device interrupts with the assertion of DRQ after receiving
2284 // Atapi Packet Command
2285 LunExt->DeviceFlags |= DFLAGS_INT_DRQ;
2286 KdPrint2((PRINT_PREFIX "IssueIdentify: Device interrupts on assertion of DRQ.\n"));
2287
2288 } else {
2289 KdPrint2((PRINT_PREFIX "IssueIdentify: Device does not interrupt on assertion of DRQ.\n"));
2290 }
2291
2293 // ATAPI branch
2294 if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_TAPE) {
2295 // This is a tape.
2297 KdPrint2((PRINT_PREFIX "IssueIdentify: Device is a tape drive.\n"));
2298 } else
2299 if(LunExt->IdentifyData.DeviceType == ATAPI_TYPE_CDROM ||
2300 LunExt->IdentifyData.DeviceType == ATAPI_TYPE_OPTICAL) {
2301 KdPrint2((PRINT_PREFIX "IssueIdentify: Device is CD/Optical drive.\n"));
2302 // set CD default costs
2306 statusByte = WaitForDrq(chan);
2307 } else {
2308 KdPrint2((PRINT_PREFIX "IssueIdentify: ATAPI drive type %#x.\n",
2309 LunExt->IdentifyData.DeviceType));
2310 }
2311 KdPrint2((PRINT_PREFIX "IssueIdentify: AtapiCmdSize %#x\n", deviceExtension->FullIdentifyData.AtapiCmdSize));
2312 } else {
2313 KdPrint2((PRINT_PREFIX "IssueIdentify: hard drive.\n"));
2314 }
2315
2316 GetBaseStatus(chan, statusByte);
2317 KdPrint2((PRINT_PREFIX "IssueIdentify: final Status on exit (%#x)\n", statusByte));
2318 return TRUE;
2319
2320} // end IssueIdentify()
void NTAPI InitBadBlocks(IN PHW_LU_EXTENSION LunExt)
#define CTRFLAGS_AHCI_PM
Definition: bsmaster.h:1143
#define REORDER_MCOST_SWITCH_RW_CD
Definition: bsmaster.h:986
#define VM_AUTO
Definition: bsmaster.h:1901
#define REORDER_COST_SWITCH_RW_CD
Definition: bsmaster.h:985
#define REORDER_MCOST_SEEK_BACK_CD
Definition: bsmaster.h:987
#define GEOM_STD
Definition: bsmaster.h:1149
#define GEOM_AUTO
Definition: bsmaster.h:1148
#define GEOM_UNIATA
Definition: bsmaster.h:1150
#define GEOM_ORIG
Definition: bsmaster.h:1151
#define IDE_DC_USE_HOB
Definition: hwide.h:141
#define IDX_IO1_i_BlockNumber
Definition: hwide.h:44
#define IDE_USE_LBA
Definition: hwide.h:133
UCHAR DDKFASTAPI UniataIsIdle(IN struct _HW_DEVICE_EXTENSION *deviceExtension, IN UCHAR Status)
Definition: id_ata.cpp:742
UCHAR DDKFASTAPI WaitOnBusyLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:674
UCHAR NTAPI AtaCommand48(IN PHW_DEVICE_EXTENSION deviceExtension, IN ULONG DeviceNumber, IN ULONG lChannel, IN UCHAR command, IN ULONGLONG lba, IN USHORT count, IN USHORT feature, IN ULONG wait_flags)
Definition: id_ata.cpp:968
UCHAR DDKFASTAPI WaitForIdleLong(IN PHW_CHANNEL chan)
Definition: id_ata.cpp:772
UCHAR NTAPI UniataAhciSendPIOCommand(IN PVOID HwDeviceExtension, IN ULONG lChannel, IN ULONG DeviceNumber, IN PSCSI_REQUEST_BLOCK Srb, IN PUCHAR data, IN ULONG length, IN UCHAR command, IN ULONGLONG lba, IN USHORT bcount, IN USHORT feature, IN USHORT ahci_flags, IN ULONG wait_flags, IN ULONG timeout)
Definition: id_sata.cpp:1538
Definition: shell.h:41
PATA_REQ AhciInternalAtaReq
Definition: bsmaster.h:1113
ULONG PmLunMap
Definition: bsmaster.h:1091
IDENTIFY_DATA FullIdentifyData
Definition: atapi.c:145
ULONG opt_GeomType
Definition: bsmaster.h:1194
USHORT NumberOfCurrentCylinders
Definition: hwide.h:208
USHORT NVCache_PM_Enabled
Definition: atapi.h:928
USHORT SoftReset
Definition: hwide.h:197
USHORT UltraDMASupport
Definition: atapi.h:830
USHORT VendorAcoustic
Definition: atapi.h:847
USHORT NumberOfCurrentHeads
Definition: hwide.h:209
ULONG UserAddressableSectors
Definition: hwide.h:213
USHORT SataSupport
Definition: hwide.h:232
USHORT CurrentAcoustic
Definition: atapi.h:846
USHORT NominalMediaRotationRate
Definition: atapi.h:936
USHORT SupportIordy
Definition: hwide.h:196
USHORT SataEnable
Definition: hwide.h:233
USHORT NumberOfHeads
Definition: hwide.h:178
UCHAR PioCycleTimingMode
Definition: hwide.h:203
USHORT SerialNumber[10]
Definition: hwide.h:183
USHORT UdmaModesValid
Definition: atapi.h:688
USHORT NumberOfCylinders
Definition: hwide.h:176
USHORT AtapiByteCount0
Definition: atapi.h:878
ULONGLONG UserAddressableSectors48
Definition: hwide.h:280
struct _IDENTIFY_DATA::@182 FeaturesEnabled
ULONG LargeSectorSize
Definition: atapi.h:872
USHORT PioTimingsValid
Definition: atapi.h:687
USHORT CurrentSectorsPerTrack
Definition: hwide.h:210
USHORT DoubleWordIo
Definition: hwide.h:191
USHORT SecurityStatus
Definition: atapi.h:883
USHORT MasterPasswdRevision
Definition: atapi.h:837
USHORT PhysLogSectorSize
Definition: atapi.h:859
USHORT SataCapabilities
Definition: hwide.h:230
USHORT MajorRevision
Definition: hwide.h:234
USHORT UltraDMAActive
Definition: atapi.h:831
struct _IDENTIFY_DATA::@182 FeaturesSupport
UCHAR AtapiCmdSize
Definition: hwide.h:169
USHORT NVCache_Version
Definition: atapi.h:933
USHORT SupportDma
Definition: hwide.h:193
USHORT SingleWordDMAActive
Definition: hwide.h:215
USHORT AdvancedPIOModes
Definition: hwide.h:218
struct _IDENTIFY_DATA::@1060::@1075 AtapiDMA
USHORT FirmwareRevision[4]
Definition: hwide.h:187
USHORT NVCache_PM_Supported
Definition: atapi.h:927
USHORT NVCache_Enabled
Definition: atapi.h:930
USHORT NVCache_PM_Version
Definition: atapi.h:932
USHORT SectorsPerTrack
Definition: hwide.h:181
UCHAR MaximumBlockTransfer
Definition: atapi.h:207
USHORT RemovableStatus
Definition: atapi.h:881
USHORT MultiWordDMAActive
Definition: hwide.h:217
USHORT SupportLba
Definition: hwide.h:194
USHORT CfAdvPowerMode
Definition: atapi.h:898
USHORT LogicalSectorOffset
Definition: atapi.h:920
USHORT DisableIordy
Definition: hwide.h:195
USHORT ModelNumber[20]
Definition: hwide.h:188
#define DFLAGS_ORIG_GEOMETRY
Definition: atapi.h:251
#define ATAPI_TYPE_TAPE
Definition: atapi.h:622
#define DFLAGS_LBA32plus
Definition: atapi.h:256
#define DFLAGS_MANUAL_CHS
Definition: atapi.h:255
#define DFLAGS_HIDDEN
Definition: atapi.h:253
#define ATAPI_DRQT_INTR
Definition: atapi.h:616
#define IDE_COMMAND_READ_NATIVE_SIZE
Definition: atapi.h:408
#define IDE_COMMAND_READ_NATIVE_SIZE48
Definition: atapi.h:355
__inline LONG ata_cur_mode_from_ident(PIDENTIFY_DATA ident, BOOLEAN Active)
Definition: atapi.h:1648
#define IDE_COMMAND_SET_NATIVE_SIZE
Definition: atapi.h:409
#define IDENT_MODE_ACTIVE
Definition: atapi.h:1644
#define IDENT_MODE_MAX
Definition: atapi.h:1643

Referenced by AtapiResetController__().

◆ SelectDrive()

◆ SetDriveParameters()

BOOLEAN NTAPI SetDriveParameters ( IN PVOID  HwDeviceExtension,
IN ULONG  DeviceNumber,
IN ULONG  Channel 
)

Definition at line 636 of file atapi.c.

660{
661 PHW_DEVICE_EXTENSION deviceExtension = HwDeviceExtension;
662 PIDE_REGISTERS_1 baseIoAddress1 = deviceExtension->BaseIoAddress1[Channel];
663 PIDE_REGISTERS_2 baseIoAddress2 = deviceExtension->BaseIoAddress2[Channel];
664 PIDENTIFY_DATA2 identifyData = &deviceExtension->IdentifyData[(Channel * 2) + DeviceNumber];
665 ULONG i;
666 UCHAR statusByte;
667
668 DebugPrint((1,
669 "SetDriveParameters: Number of heads %x\n",
670 identifyData->NumberOfHeads));
671
672 DebugPrint((1,
673 "SetDriveParameters: Sectors per track %x\n",
674 identifyData->SectorsPerTrack));
675
676 //
677 // Set up registers for SET PARAMETER command.
678 //
679
680 ScsiPortWritePortUchar(&baseIoAddress1->DriveSelect,
681 (UCHAR)(((DeviceNumber << 4) | 0xA0) | (identifyData->NumberOfHeads - 1)));
682
683 ScsiPortWritePortUchar(&baseIoAddress1->BlockCount,
684 (UCHAR)identifyData->SectorsPerTrack);
685
686 //
687 // Send SET PARAMETER command.
688 //
689
690 ScsiPortWritePortUchar(&baseIoAddress1->Command,
692
693 //
694 // Wait for up to 30 milliseconds for ERROR or command complete.
695 //
696
697 for (i=0; i<30 * 1000; i++) {
698
699 UCHAR errorByte;
700
701 GetStatus(baseIoAddress2, statusByte);
702
703 if (statusByte & IDE_STATUS_ERROR) {
704 errorByte = ScsiPortReadPortUchar((PUCHAR)baseIoAddress1 + 1);
705 DebugPrint((1,
706 "SetDriveParameters: Error bit set. Status %x, error %x\n",
707 errorByte,
708 statusByte));
709
710 return FALSE;
711 } else if ((statusByte & ~IDE_STATUS_INDEX ) == IDE_STATUS_IDLE) {
712 break;
713 } else {
715 }
716 }
717
718 //
719 // Check for timeout.
720 //
721
722 if (i == 30 * 1000) {
723 return FALSE;
724 } else {
725 return TRUE;
726 }
727
728} // end SetDriveParameters()
#define IDE_COMMAND_SET_DRIVE_PARAMETERS
Definition: atapi.h:108

Referenced by AtapiResetController(), AtapiResetController__(), and FindDevices().

◆ UniataAnybodyHome()

ULONG NTAPI UniataAnybodyHome ( IN PVOID  HwDeviceExtension,
IN ULONG  Channel,
IN ULONG  deviceNumber 
)

Definition at line 2778 of file id_probe.cpp.

2783{
2784 PHW_DEVICE_EXTENSION deviceExtension = (PHW_DEVICE_EXTENSION)HwDeviceExtension;
2785 PHW_CHANNEL chan = &(deviceExtension->chan[lChannel]);
2786 //ULONG ldev = GET_LDEV2(lChannel, deviceNumber, 0);
2787 PHW_LU_EXTENSION LunExt = chan->lun[deviceNumber];
2788
2789 SATA_SSTATUS_REG SStatus;
2790 UCHAR signatureLow;
2791 UCHAR signatureHigh;
2792
2793 if(LunExt->DeviceFlags & DFLAGS_HIDDEN) {
2794 KdPrint2((PRINT_PREFIX " hidden\n"));
2795 UniataForgetDevice(LunExt);
2796 return ATA_AT_HOME_NOBODY;
2797 }
2798 if(UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
2799
2800 SStatus.Reg = UniataSataReadPort4(chan, IDX_SATA_SStatus, deviceNumber);
2801 KdPrint2((PRINT_PREFIX "SStatus %x\n", SStatus.Reg));
2802 if(SStatus.DET <= SStatus_DET_Dev_NoPhy) {
2803 KdPrint2((PRINT_PREFIX " SATA DET <= SStatus_DET_Dev_NoPhy\n"));
2804 return ATA_AT_HOME_NOBODY;
2805 }
2806 if(SStatus.SPD < SStatus_SPD_Gen1) {
2807 KdPrint2((PRINT_PREFIX " SATA SPD < SStatus_SPD_Gen1\n"));
2808 return ATA_AT_HOME_NOBODY;
2809 }
2810 if(SStatus.IPM == SStatus_IPM_NoDev) {
2811 KdPrint2((PRINT_PREFIX " SATA IPN == SStatus_IPM_NoDev\n"));
2812 return ATA_AT_HOME_NOBODY;
2813 }
2814 if(!(deviceExtension->HwFlags & UNIATA_AHCI)) {
2815 // Select the device for legacy.
2816 goto legacy_select;
2817 }
2818
2819 } else {
2820legacy_select:
2821 // Select the device.
2822 SelectDrive(chan, deviceNumber);
2824 }
2825
2826 if((deviceExtension->HwFlags & UNIATA_AHCI) &&
2827 UniataIsSATARangeAvailable(deviceExtension, lChannel)) {
2828 KdPrint2((PRINT_PREFIX " AHCI check\n"));
2830 signatureLow = (UCHAR)(SIG >> 16);
2831 signatureHigh = (UCHAR)(SIG >> 24);
2832 } else {
2833 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_CylinderLow);
2834 signatureHigh = AtapiReadPort1(chan, IDX_IO1_i_CylinderHigh);
2835 }
2836
2837 if (signatureLow == ATAPI_MAGIC_LSB && signatureHigh == ATAPI_MAGIC_MSB) {
2838 KdPrint2((PRINT_PREFIX " ATAPI at home\n"));
2839 return ATA_AT_HOME_ATAPI;
2840 }
2841 if(deviceExtension->HwFlags & UNIATA_AHCI) {
2842 KdPrint2((PRINT_PREFIX " AHCI HDD at home\n"));
2843 return ATA_AT_HOME_HDD;
2844 }
2845 if(g_opt_VirtualMachine > VM_NONE /*== VM_BOCHS ||
2846 g_opt_VirtualMachine == VM_VBOX*/) {
2847 GetStatus(chan, signatureLow);
2848 if(!signatureLow) {
2849 KdPrint2((PRINT_PREFIX " 0-status VM - not present\n"));
2850 UniataForgetDevice(LunExt);
2851 return ATA_AT_HOME_NOBODY;
2852 }
2853 }
2854
2856
2860 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
2861 if(signatureLow != 0x55) {
2862 if(signatureLow == 0xff || signatureLow == 0) {
2863 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0x55\n", signatureLow));
2864 UniataForgetDevice(LunExt);
2865 return ATA_AT_HOME_NOBODY;
2866 }
2867 // another chance
2868 signatureLow = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
2869 signatureLow += 2;
2872 signatureHigh = AtapiReadPort1(chan, IDX_ATAPI_IO1_o_ByteCountHigh);
2873 if(signatureLow != signatureHigh) {
2874 KdPrint2((PRINT_PREFIX " nobody home! last chance failed %#x != %#x\n", signatureLow, signatureHigh));
2875 UniataForgetDevice(LunExt);
2876 return ATA_AT_HOME_NOBODY;
2877 }
2878 return ATA_AT_HOME_XXX;
2879 }
2880
2884 signatureLow = AtapiReadPort1(chan, IDX_IO1_i_BlockNumber);
2885 if(signatureLow != 0xAA) {
2886 KdPrint2((PRINT_PREFIX " nobody home! %#x != 0xAA\n", signatureLow));
2887 UniataForgetDevice(LunExt);
2888 return ATA_AT_HOME_NOBODY;
2889 }
2890
2891 KdPrint2((PRINT_PREFIX " HDD at home\n"));
2892 return ATA_AT_HOME_HDD;
2893} // end UniataAnybodyHome()
#define SStatus_DET_Dev_NoPhy
Definition: bsmaster.h:285
#define SStatus_SPD_Gen1
Definition: bsmaster.h:292
#define SStatus_IPM_NoDev
Definition: bsmaster.h:298
#define IDX_AHCI_P_SIG
Definition: bsmaster.h:688
#define ATA_AT_HOME_HDD
Definition: atapi.h:1592
#define ATA_AT_HOME_NOBODY
Definition: atapi.h:1595
#define ATA_AT_HOME_ATAPI
Definition: atapi.h:1593
#define ATA_AT_HOME_XXX
Definition: atapi.h:1594

Referenced by AtapiResetController__(), AtapiStartIo__(), CheckDevice(), and IdeSendCommand().

◆ UniAtaCalculateLBARegsBack()

ULONGLONG NTAPI UniAtaCalculateLBARegsBack ( struct _HW_LU_EXTENSION LunExt,
ULONGLONG  lba 
)

Referenced by CheckIfBadBlock().

◆ UniataDumpATARegs()

VOID NTAPI UniataDumpATARegs ( IN struct _HW_CHANNEL chan)

◆ UniataExpectChannelInterrupt()

VOID UniataExpectChannelInterrupt ( IN struct _HW_CHANNEL chan,
IN BOOLEAN  Expecting 
)

Definition at line 4492 of file id_ata.cpp.

4496{
4497 chan->ExpectingInterrupt = Expecting;
4498 if(Expecting) {
4499 chan->DeviceExtension->ExpectingInterrupt++;
4500 } else
4501 if(chan->DeviceExtension->ExpectingInterrupt) {
4502 chan->DeviceExtension->ExpectingInterrupt--;
4503 }
4504 return;
4505} // end UniataExpectChannelInterrupt()

Referenced by AtaCommand48(), AtapiInterrupt__(), AtapiResetController__(), AtapiSendCommand(), FindDevices(), IdeReadWrite(), IdeSendCommand(), IdeSendSmartCommand(), and IdeVerify().

◆ UniataInitIoRes()

VOID UniataInitIoRes ( IN struct _HW_CHANNEL chan,
IN ULONG  idx,
IN ULONG  addr,
IN BOOLEAN  MemIo,
IN BOOLEAN  Proc 
)

◆ UniataInitIoResEx()

VOID UniataInitIoResEx ( IN struct _IORES IoRes,
IN ULONG  addr,
IN BOOLEAN  MemIo,
IN BOOLEAN  Proc 
)

◆ UniataInitMapBase()

VOID NTAPI UniataInitMapBase ( IN struct _HW_CHANNEL chan,
IN PIDE_REGISTERS_1  BaseIoAddress1,
IN PIDE_REGISTERS_2  BaseIoAddress2 
)

◆ UniataInitMapBM()

VOID NTAPI UniataInitMapBM ( IN struct _HW_DEVICE_EXTENSION deviceExtension,
IN struct _IDE_BUSMASTER_REGISTERS BaseIoAddressBM_0,
IN BOOLEAN  MemIo 
)

◆ UniataInitSyncBaseIO()

VOID NTAPI UniataInitSyncBaseIO ( IN struct _HW_CHANNEL chan)

Referenced by UniataAhciInit().

◆ UniataIsIdle()

UCHAR DDKFASTAPI UniataIsIdle ( IN struct _HW_DEVICE_EXTENSION deviceExtension,
IN UCHAR  Status 
)

Definition at line 742 of file id_ata.cpp.

746{
747 UCHAR Status2;
748
749 if(Status == IDE_STATUS_WRONG) {
750 return IDE_STATUS_WRONG;
751 }
752 if(Status & IDE_STATUS_BUSY) {
753 return Status;
754 }
755// if(deviceExtension->HwFlags & UNIATA_SATA) {
756 if(UniataIsSATARangeAvailable(deviceExtension, 0)) {
758 return Status;
759 }
760 } else {
762 if ((Status & IDE_STATUS_BUSY) ||
763 (Status2 != IDE_STATUS_IDLE && Status2 != IDE_STATUS_DRDY)) {
764 return Status;
765 }
766 }
767 return IDE_STATUS_IDLE;
768} // end UniataIsIdle()
Status
Definition: gdiplustypes.h:25

Referenced by AtaCommand48(), AtapiDmaInit(), AtapiResetController__(), IssueIdentify(), SetDriveParameters(), and WaitForIdleLong().

◆ WaitForDrq()

UCHAR DDKFASTAPI WaitForDrq ( IN struct _HW_CHANNEL chan)

◆ WaitOnBaseBusy()

UCHAR DDKFASTAPI WaitOnBaseBusy ( IN struct _HW_CHANNEL chan)

◆ WaitOnBaseBusyLong()

UCHAR DDKFASTAPI WaitOnBaseBusyLong ( IN struct _HW_CHANNEL chan)

Referenced by CheckDevice(), and UniataSataConnect().

◆ WaitOnBusy()

UCHAR DDKFASTAPI WaitOnBusy ( IN struct _HW_CHANNEL chan)

◆ WaitOnBusyLong()

UCHAR DDKFASTAPI WaitOnBusyLong ( IN struct _HW_CHANNEL chan)

◆ WaitShortForDrq()

UCHAR DDKFASTAPI WaitShortForDrq ( IN struct _HW_CHANNEL chan)

Variable Documentation

◆ AtaCommandFlags

◆ AtaCommands48

UCHAR const AtaCommands48[256]
extern

Definition at line 5 of file atacmd_map.h.

Referenced by AtaCommand48(), UniataAhciSetupFIS_H2D(), and UniataAhciSetupFIS_H2D_Direct().

◆ g_LogToDisplay

ULONG g_LogToDisplay
extern

Referenced by _PrintNtConsole(), and DriverEntry().