* Wrote a new infoblock header according to ATA/ATAPI-6 that is cleaner and more

verbose than the old one. Removed the latter.
* Put some of the hardcoded values into defines for more clearity.
* Report more detailed device type for ATAPI devices and report removable
  media based on the bit in the infoblock as well.
* Rename the channel ID attributes back to ide to let the hack in scsi_periph
  work that then publishes the devices under the disk/ata[pi] tree.
* Also disable command queueing for ATAPI devices.
* Remove remnants of CHS support.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30270 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Lotz
2009-04-19 22:15:29 +00:00
parent 4f65f5dca0
commit ca68245eb7
5 changed files with 424 additions and 299 deletions
+79 -104
View File
@@ -17,7 +17,6 @@ ATADevice::ATADevice(ATAChannel *channel, uint8 index)
fDMAMode(0),
fDMAFailures(0),
fIndex(index),
fUseLBA(false),
fUse48Bits(false),
fTotalSectors(0)
{
@@ -114,11 +113,12 @@ ATADevice::Inquiry(ATARequest *request)
scsi_res_inquiry data;
memset(&data, 0, sizeof(data));
data.device_type = scsi_dev_direct_access;
data.device_type = IsATAPI()
? fInfoBlock.word_0.atapi.command_packet_set : scsi_dev_direct_access;
data.device_qualifier = scsi_periph_qual_connected;
data.device_type_modifier = 0;
data.removable_medium = false;
data.removable_medium = fInfoBlock.word_0.ata.removable_media_device;
data.ansi_version = 2;
data.ecma_version = 0;
@@ -341,10 +341,10 @@ ATADevice::SetFeature(int feature)
status_t
ATADevice::DisableCommandQueueing()
{
if (!fInfoBlock.DMA_QUEUED_supported)
if (!fInfoBlock.read_write_dma_queued_supported)
return B_OK;
if (fInfoBlock.RELEASE_irq_supported) {
if (fInfoBlock.release_interrupt_supported) {
status_t result = SetFeature(
ATA_COMMAND_SET_FEATURES_DISABLE_RELEASE_INT);
if (result != B_OK) {
@@ -353,7 +353,7 @@ ATADevice::DisableCommandQueueing()
}
}
if (fInfoBlock.SERVICE_irq_supported) {
if (fInfoBlock.service_interrupt_supported) {
status_t result = SetFeature(
ATA_COMMAND_SET_FEATURES_DISABLE_SERVICE_INT);
if (result != B_OK) {
@@ -372,7 +372,7 @@ ATADevice::ConfigureDMA()
if (!fUseDMA)
return B_OK;
if (!fInfoBlock.DMA_supported) {
if (!fInfoBlock.dma_supported) {
TRACE_ALWAYS("DMA not supported by device\n");
fUseDMA = false;
return B_OK;
@@ -386,18 +386,18 @@ ATADevice::ConfigureDMA()
uint32 modeCount = 0;
CHECK_DMA_MODE(MDMA0_selected, 0x00);
CHECK_DMA_MODE(MDMA1_selected, 0x01);
CHECK_DMA_MODE(MDMA2_selected, 0x02);
CHECK_DMA_MODE(multiword_dma_0_selected, 0x00);
CHECK_DMA_MODE(multiword_dma_1_selected, 0x01);
CHECK_DMA_MODE(multiword_dma_2_selected, 0x02);
if (fInfoBlock._88_valid) {
CHECK_DMA_MODE(UDMA0_selected, 0x10);
CHECK_DMA_MODE(UDMA1_selected, 0x11);
CHECK_DMA_MODE(UDMA2_selected, 0x12);
CHECK_DMA_MODE(UDMA3_selected, 0x13);
CHECK_DMA_MODE(UDMA4_selected, 0x14);
CHECK_DMA_MODE(UDMA5_selected, 0x15);
CHECK_DMA_MODE(UDMA6_selected, 0x16);
if (fInfoBlock.word_88_valid) {
CHECK_DMA_MODE(ultra_dma_0_selected, 0x10);
CHECK_DMA_MODE(ultra_dma_1_selected, 0x11);
CHECK_DMA_MODE(ultra_dma_2_selected, 0x12);
CHECK_DMA_MODE(ultra_dma_3_selected, 0x13);
CHECK_DMA_MODE(ultra_dma_4_selected, 0x14);
CHECK_DMA_MODE(ultra_dma_5_selected, 0x15);
CHECK_DMA_MODE(ultra_dma_6_selected, 0x16);
}
#undef CHECK_DMA_MODE
@@ -417,50 +417,32 @@ status_t
ATADevice::Configure()
{
// warning: ata == 0 means "this is ata"...
if (fInfoBlock._0.ata.ATA != 0) {
if (fInfoBlock.word_0.ata.ata_device != ATA_WORD_0_ATA_DEVICE) {
// CF has either magic header or CFA bit set
// we merge it to "CFA bit set" for easier (later) testing
if (*(uint16 *)&fInfoBlock == 0x848a)
fInfoBlock.CFA_supported = true;
else
if (fInfoBlock.word_0.raw == ATA_WORD_0_CFA_MAGIC)
fInfoBlock.compact_flash_assoc_supported = true;
else {
TRACE_ERROR("infoblock indicates non-ata device\n");
return B_ERROR;
}
}
if (!fInfoBlock._54_58_valid) {
// normally, current_xxx contains active CHS mapping,
// but if BIOS didn't call INITIALIZE DEVICE PARAMETERS
// the default mapping is used
fInfoBlock.current_sectors = fInfoBlock.sectors;
fInfoBlock.current_cylinders = fInfoBlock.cylinders;
fInfoBlock.current_heads = fInfoBlock.heads;
if (!fInfoBlock.lba_supported || fInfoBlock.lba_sector_count == 0) {
TRACE_ERROR("non-lba devices not supported\n");
return B_ERROR;
}
// just in case capacity_xxx isn't initialized - calculate it manually
// (seems that this information is really redundant; hopefully)
uint32 chsCapacity = fInfoBlock.current_sectors
* fInfoBlock.current_cylinders * fInfoBlock.current_heads;
fTotalSectors = fInfoBlock.lba_sector_count;
fTaskFile.lba.mode = ATA_MODE_LBA;
fTaskFile.lba.device = fIndex;
fInfoBlock.capacity_low = chsCapacity & 0xff;
fInfoBlock.capacity_high = chsCapacity >> 8;
// checking LBA_supported flag should be sufficient, but it seems
// that checking LBA_total_sectors is a good idea
fUseLBA = fInfoBlock.LBA_supported && fInfoBlock.LBA_total_sectors != 0;
if (fUseLBA) {
fTotalSectors = fInfoBlock.LBA_total_sectors;
fTaskFile.lba.mode = ATA_MODE_LBA;
fTaskFile.lba.device = fIndex;
} else {
fTotalSectors = chsCapacity;
fTaskFile.chs.mode = ATA_MODE_CHS;
fTaskFile.chs.device = fIndex;
if (fInfoBlock.lba48_supported
&& fInfoBlock.lba48_sector_count >= fInfoBlock.lba_sector_count) {
fUse48Bits = true;
fTotalSectors = fInfoBlock.lba48_sector_count;
}
fUse48Bits = fInfoBlock._48_bit_addresses_supported;
if (fUse48Bits)
fTotalSectors = fInfoBlock.LBA48_total_sectors;
status_t result = ConfigureDMA();
if (result != B_OK)
return result;
@@ -611,60 +593,53 @@ ATADevice::_FillTaskFile(ATARequest *request, uint64 address)
uint32 sectorCount = *request->BytesLeft() / ATA_BLOCK_SIZE;
TRACE("about to transfer %lu sectors\n", sectorCount);
if (fUseLBA) {
if (fUse48Bits
&& (address + sectorCount > 0xfffffff || sectorCount > 0x100)) {
// use LBA48 only if necessary
if (sectorCount > 0xffff) {
TRACE_ERROR("invalid sector count %lu\n", sectorCount);
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
SCSIS_ASC_INV_CDB_FIELD);
return B_ERROR;
}
fRegisterMask = ATA_MASK_SECTOR_COUNT_48
| ATA_MASK_LBA_LOW_48
| ATA_MASK_LBA_MID_48
| ATA_MASK_LBA_HIGH_48;
fTaskFile.lba48.sector_count_0_7 = sectorCount & 0xff;
fTaskFile.lba48.sector_count_8_15 = (sectorCount >> 8) & 0xff;
fTaskFile.lba48.lba_0_7 = address & 0xff;
fTaskFile.lba48.lba_8_15 = (address >> 8) & 0xff;
fTaskFile.lba48.lba_16_23 = (address >> 16) & 0xff;
fTaskFile.lba48.lba_24_31 = (address >> 24) & 0xff;
fTaskFile.lba48.lba_32_39 = (address >> 32) & 0xff;
fTaskFile.lba48.lba_40_47 = (address >> 40) & 0xff;
fTaskFile.lba48.command = s48BitCommands[request->UseDMA()
? 1 : 0][request->IsWrite() ? 1 : 0];
} else {
// normal LBA
if (sectorCount > 0x100) {
TRACE_ERROR("invalid sector count %lu\n", sectorCount);
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
SCSIS_ASC_INV_CDB_FIELD);
return B_ERROR;
}
fRegisterMask = ATA_MASK_SECTOR_COUNT
| ATA_MASK_LBA_LOW
| ATA_MASK_LBA_MID
| ATA_MASK_LBA_HIGH
| ATA_MASK_DEVICE_HEAD;
fTaskFile.lba.sector_count = sectorCount & 0xff;
fTaskFile.lba.lba_0_7 = address & 0xff;
fTaskFile.lba.lba_8_15 = (address >> 8) & 0xff;
fTaskFile.lba.lba_16_23 = (address >> 16) & 0xff;
fTaskFile.lba.lba_24_27 = (address >> 24) & 0xf;
fTaskFile.lba.command = s28BitCommands[request->UseDMA()
? 1 : 0][request->IsWrite() ? 1 : 0];
if (fUse48Bits
&& (address + sectorCount > 0xfffffff || sectorCount > 0x100)) {
// use LBA48 only if necessary
if (sectorCount > 0xffff) {
TRACE_ERROR("invalid sector count %lu\n", sectorCount);
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
SCSIS_ASC_INV_CDB_FIELD);
return B_ERROR;
}
fRegisterMask = ATA_MASK_SECTOR_COUNT_48
| ATA_MASK_LBA_LOW_48
| ATA_MASK_LBA_MID_48
| ATA_MASK_LBA_HIGH_48;
fTaskFile.lba48.sector_count_0_7 = sectorCount & 0xff;
fTaskFile.lba48.sector_count_8_15 = (sectorCount >> 8) & 0xff;
fTaskFile.lba48.lba_0_7 = address & 0xff;
fTaskFile.lba48.lba_8_15 = (address >> 8) & 0xff;
fTaskFile.lba48.lba_16_23 = (address >> 16) & 0xff;
fTaskFile.lba48.lba_24_31 = (address >> 24) & 0xff;
fTaskFile.lba48.lba_32_39 = (address >> 32) & 0xff;
fTaskFile.lba48.lba_40_47 = (address >> 40) & 0xff;
fTaskFile.lba48.command = s48BitCommands[request->UseDMA()
? 1 : 0][request->IsWrite() ? 1 : 0];
} else {
// CHS mode - we do not support it anymore
TRACE_ERROR("chs mode not supported\n");
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD);
return B_ERROR;
// normal LBA
if (sectorCount > 0x100) {
TRACE_ERROR("invalid sector count %lu\n", sectorCount);
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
SCSIS_ASC_INV_CDB_FIELD);
return B_ERROR;
}
fRegisterMask = ATA_MASK_SECTOR_COUNT
| ATA_MASK_LBA_LOW
| ATA_MASK_LBA_MID
| ATA_MASK_LBA_HIGH
| ATA_MASK_DEVICE_HEAD;
fTaskFile.lba.sector_count = sectorCount & 0xff;
fTaskFile.lba.lba_0_7 = address & 0xff;
fTaskFile.lba.lba_8_15 = (address >> 8) & 0xff;
fTaskFile.lba.lba_16_23 = (address >> 16) & 0xff;
fTaskFile.lba.lba_24_27 = (address >> 24) & 0xf;
fTaskFile.lba.command = s28BitCommands[request->UseDMA()
? 1 : 0][request->IsWrite() ? 1 : 0];
}
return B_OK;
@@ -0,0 +1,333 @@
/*
* Copyright 2009, Michael Lotz, [email protected].
* Distributed under the terms of the MIT License.
*/
#ifndef ATA_INFOBLOCK_H
#define ATA_INFOBLOCK_H
#include <lendian_bitfield.h>
#define ATA_WORD_0_ATA_DEVICE 0
#define ATA_WORD_0_ATAPI_DEVICE 2
#define ATA_WORD_0_CFA_MAGIC 0x848a
typedef struct ata_device_infoblock {
union {
struct {
LBITFIELD8(
word_0_bit_0_reserved : 1,
word_0_bit_1_retired : 1,
response_incomplete : 1,
word_0_bit_3_5_retired : 3,
word_0_bit_6_obsolete : 1,
removable_media_device : 1,
word_0_bit_8_14_retired : 7,
ata_device : 1 // 0 means ATA
);
} ata;
struct {
LBITFIELD8(
packet_length : 2, // 0 = 12, 1 = 16 bytes
response_incomplete : 1,
word_0_bit_3_4_reserved : 2,
data_request_delay : 2, // 0 = 3ms, 2 = 50us
removable_media_device : 1,
command_packet_set : 5,
word_0_bit_13_reserved : 1,
atapi_device : 2 // 2 means ATAPI
);
} atapi;
uint16 raw;
} word_0;
uint16 word_1_obsolete;
uint16 specific_configuration;
uint16 word_3_obsolete;
uint16 word_4_5_retired[2];
uint16 word_6_obsolete;
uint16 word_7_8_reserved_compact_flash_assoc[2];
uint16 word_9_retired;
char serial_number[20];
uint16 word_20_21_retired[2];
uint16 word_22_obsolete;
char firmware_revision[8];
char model_number[40];
LBITFIELD2(
max_sectors_per_interrupt : 8,
word_47_bit_8_15_80h : 8 // should be 0x80
);
uint16 word_48_reserved;
LBITFIELD9(
word_49_bit_0_7_retired : 8,
dma_supported : 1,
lba_supported : 1,
io_ready_disable : 1,
io_ready_supported : 1,
word_19_bit_12_obsolete : 1,
standby_timer_standard : 1,
atapi_command_queuing_supported : 1,
atapi_interleaved_dma_supported : 1
);
LBITFIELD5(
standby_timer_value_min : 1,
word_50_bit_1_obsolete : 1,
word_50_bit_2_13_reserved : 12,
word_50_bit_14_one : 1,
word_50_bit_15_zero : 1
);
uint16 word_51_52_obsolete[2];
LBITFIELD4(
word_53_bit_0_obsolete : 1,
word_64_70_valid : 1,
word_88_valid : 1,
word_53_bit_3_15 : 13
);
uint16 word_54_58_obsolete[5];
LBITFIELD3(
current_sectors_per_interrupt : 8,
multiple_sector_setting_valid : 1,
word_59_bit_9_15_reserved : 7
);
uint32 lba_sector_count;
uint16 word_62_obsolete;
LBITFIELD8(
multiword_dma_0_supported : 1,
multiword_dma_1_supported : 1,
multiword_dma_2_supported : 1,
word_63_bit_3_7_resereved : 5,
multiword_dma_0_selected : 1,
multiword_dma_1_selected : 1,
multiword_dma_2_selected : 1,
word_63_bit_11_15_reserved : 5
);
LBITFIELD2(
pio_modes_supported : 8,
word_64_bit_8_15_reserved : 8
);
uint16 min_multiword_dma_cycle_time;
uint16 recommended_multiword_dma_cycle_time;
uint16 min_pio_cycle_time;
uint16 min_pio_cycle_time_io_ready;
uint16 word_69_70_reserved[2];
uint16 atapi_packet_received_to_bus_release_time_ns;
uint16 atapi_service_command_to_busy_clear_time_ns;
uint16 word_71_74_reserved[2];
LBITFIELD2(
max_queue_depth_minus_one : 5,
word_75_bit_5_15_reserved : 11
);
uint16 word_76_79_reserved[4];
LBITFIELD15(
word_80_bit_0_reserved : 1,
word_80_bot_1_2_obsolete : 2,
supports_ata_3 : 1,
supports_ata_atapi_4 : 1,
supports_ata_atapi_5 : 1,
supports_ata_atapi_6 : 1,
supports_ata_atapi_7 : 1,
supports_ata_atapi_8 : 1,
supports_ata_atapi_9 : 1,
supports_ata_atapi_10 : 1,
supports_ata_atapi_11 : 1,
supports_ata_atapi_12 : 1,
supports_ata_atapi_13 : 1,
supports_ata_atapi_14 : 1,
word_80_bit_15_reserved : 1
);
uint16 minor_version;
LBITFIELD16(
smart_supported : 1,
security_mode_supported : 1,
removable_media_supported : 1,
mandatory_power_management_supported : 1,
packet_supported : 1,
write_cache_supported : 1,
look_ahead_supported : 1,
release_interrupt_supported : 1,
service_interrupt_supported : 1,
device_reset_supported : 1,
host_protected_area_supported : 1,
word_82_bit_11_obsolete : 1,
write_buffer_command_supported : 1,
read_buffer_command_supported : 1,
nop_supported : 1,
word_82_bit_15_obsolete : 1
);
LBITFIELD16(
download_microcode_supported : 1,
read_write_dma_queued_supported : 1,
compact_flash_assoc_supported : 1,
advanced_power_management_supported : 1,
removable_media_status_supported : 1,
power_up_in_standby_supported : 1,
set_features_required_for_spinup : 1,
word_83_bit_7_reserved : 1,
set_max_security_extension_supported : 1,
automatic_acoustic_management_supported : 1,
lba48_supported : 1,
device_configuration_overlay_supported : 1,
mandatory_flush_cache_supported : 1,
flush_cache_ext_supported : 1,
word_83_bit_14_one : 1,
word_83_bit_15_zero : 1
);
LBITFIELD9(
smart_error_logging_supported : 1,
smart_self_test_supported : 1,
media_serial_number_supported : 1,
media_card_pass_through_supported : 1,
word_84_bit_4_reserved : 1,
general_purpose_logging_supported : 1,
word_84_bit_6_13_reserved : 8,
word_84_bit_14_one : 1,
word_84_bit_15_zero : 1
);
LBITFIELD16(
smart_enabled : 1,
security_mode_enabled : 1,
removable_media_enabled : 1,
mandatory_power_management_enabled : 1,
packet_enabled : 1,
write_cache_enabled : 1,
look_ahead_enabled : 1,
release_interrupt_enabled : 1,
service_interrupt_enabled : 1,
device_reset_enabled : 1,
host_protected_area_enabled : 1,
word_85_bit_11_obsolete : 1,
write_buffer_command_enabled : 1,
read_buffer_command_enabled : 1,
nop_enabled : 1,
word_85_bit_15_obsolete : 1
);
LBITFIELD15(
download_microcode_supported_2 : 1,
read_write_dma_queued_supported_2 : 1,
compact_flash_assoc_enabled : 1,
advanced_power_management_enabled : 1,
removable_media_status_enabled : 1,
power_up_in_standby_enabled : 1,
set_features_required_for_spinup_2 : 1,
word_86_bit_7_reserved : 1,
set_max_security_extension_enabled : 1,
automatic_acoustic_management_enabled : 1,
lba48_supported_2 : 1,
device_configuration_overlay_supported_2: 1,
mandatory_flush_cache_supported_2 : 1,
flush_cache_ext_supported_2 : 1,
word_86_bit_14_15_reserved : 2
);
LBITFIELD9(
smart_error_logging_supported_2 : 1,
smart_self_test_supported_2 : 1,
media_serial_number_valid : 1,
media_card_pass_through_enabled : 1,
word_87_bit_4_reserved : 1,
general_purpose_logging_supported_2 : 1,
word_87_bit_6_13_reserved : 8,
word_87_bit_14_one : 1,
word_87_bit_15_zero : 1
);
LBITFIELD16(
ultra_dma_0_supported : 1,
ultra_dma_1_supported : 1,
ultra_dma_2_supported : 1,
ultra_dma_3_supported : 1,
ultra_dma_4_supported : 1,
ultra_dma_5_supported : 1,
ultra_dma_6_supported : 1,
word_88_bit_7_reserved : 1,
ultra_dma_0_selected : 1,
ultra_dma_1_selected : 1,
ultra_dma_2_selected : 1,
ultra_dma_3_selected : 1,
ultra_dma_4_selected : 1,
ultra_dma_5_selected : 1,
ultra_dma_6_selected : 1,
word_88_bit_15_reserved : 1
);
uint16 security_erase_unit_duration;
uint16 enhanced_security_erase_duration;
uint16 current_advanced_power_management_value;
uint16 master_password_revision_code;
LBITFIELD5(
device_0_hardware_reset_result : 8,
device_1_hardware_reset_result : 5,
cable_id_detected : 1,
word_93_bit_14_one : 1,
word_93_bit_15_zero : 1
);
LBITFIELD2(
current_acoustic_management_value : 8,
recommended_acoustic_management_value : 8
);
uint16 word_95_99_reserved[5];
uint64 lba48_sector_count;
uint16 word_104_126_reserved[23];
LBITFIELD2(
removable_media_status_supported_2 : 2, // 1 = supported
word_127_bit_2_15_reserved : 14
);
LBITFIELD9(
security_supported : 1,
security_enabled : 1,
security_locked : 1,
security_frozen : 1,
security_count_expired : 1,
ehnaced_security_erase_supported : 1,
word_128_bit_6_7_reserved : 2,
security_level : 1, // 0 = high, 1 = max
word_128_bit_9_15 : 7
);
uint16 word_129_159_vendor_specific[31];
LBITFIELD5(
cfa_max_current_milli_ampers : 12,
cfa_power_mode_1_disabled : 1,
cfa_power_mode_1_required : 1,
word_160_bit_14_reserved : 1,
word_160_supported : 1
);
uint16 word_161_175_reserved_compact_flash_assoc[15];
uint16 current_media_serial_number[30];
uint16 word_206_254_reserved[49];
LBITFIELD2(
signature : 8,
checksum : 8
);
} _PACKED ata_device_infoblock;
#endif // ATA_INFOBLOCK_H
@@ -188,9 +188,8 @@ status_t
ATAPIDevice::ExecuteIO(ATARequest *request)
{
scsi_ccb *ccb = request->CCB();
if (ccb->target_lun > fInfoBlock.last_lun) {
TRACE_ERROR("invalid target lun %d, last lun is %d\n", ccb->target_lun,
fInfoBlock.last_lun);
if (ccb->target_lun != 0) {
TRACE_ERROR("invalid target lun %d\n", ccb->target_lun);
request->SetStatus(SCSI_SEL_TIMEOUT);
return B_BAD_INDEX;
}
@@ -209,8 +208,10 @@ ATAPIDevice::ExecuteIO(ATARequest *request)
status_t
ATAPIDevice::Configure()
{
if (fInfoBlock._0.atapi.ATAPI != 2)
if (fInfoBlock.word_0.atapi.atapi_device != ATA_WORD_0_ATAPI_DEVICE) {
TRACE_ERROR("infoblock indicates non-atapi device\n");
return B_ERROR;
}
fTaskFile.packet.lun = 0;
@@ -218,6 +219,10 @@ ATAPIDevice::Configure()
if (result != B_OK)
return result;
result = DisableCommandQueueing();
if (result != B_OK)
return result;
return B_OK;
}
@@ -22,8 +22,8 @@
#include <util/AutoLock.h>
#include "ATACommands.h"
#include "ATAInfoblock.h"
#include "ATATracing.h"
#include "ata_device_infoblock.h"
#define ATA_BLOCK_SIZE 512 /* TODO: retrieve */
#define ATA_MAX_DMA_FAILURES 3
@@ -33,8 +33,8 @@
#define ATA_SIGNATURE_ATAPI 0xeb140101
#define ATA_SIGNATURE_SATA 0xc33c0101
#define ATA_SIM_MODULE_NAME "bus_managers/ata/sim/driver_v1"
#define ATA_CHANNEL_ID_GENERATOR "ata/channel_id"
#define ATA_CHANNEL_ID_ITEM "ata/channel_id"
#define ATA_CHANNEL_ID_GENERATOR "ide/channel_id"
#define ATA_CHANNEL_ID_ITEM "ide/channel_id"
enum {
ATA_DEVICE_READY_REQUIRED = 0x01,
@@ -180,7 +180,6 @@ virtual status_t ExecuteIO(ATARequest *request);
virtual bool IsATAPI() { return false; };
bool UseDMA() { return fUseDMA; };
bool UseLBA() { return fUseLBA; };
bool Use48Bits() { return fUse48Bits; };
status_t Select();
@@ -215,7 +214,6 @@ private:
uint64 address);
uint8 fIndex;
bool fUseLBA;
bool fUse48Bits;
uint64 fTotalSectors;
@@ -1,186 +0,0 @@
/*
* Copyright 2004-2009, Haiku, Inc.
* Copyright 2002/03, Thomas Kurschel.
*
* Distributed under the terms of the MIT License.
*/
#ifndef _ATA_DEVICE_INFOBLOCK_H_
#define _ATA_DEVICE_INFOBLOCK_H_
/*
Definition of response to ATA_COMMAND_IDENTIFY_DEVICE or
ATA_COMMAND_IDENTIFY_PACKET_DEVICE
When a new entry is inserted, add its offset in hex
and its index in decimal as a remark. Without that, you
have a rough time when you messed up the offsets.
*/
#include <lendian_bitfield.h>
#define ATA_GET_INFO_BLOCK 0x2710
#define ATA_GET_STATUS 0x2711
// must be 512 bytes!!!
typedef struct tagdevice_infoblock {
union { // 0 general configuration
struct {
LBITFIELD8 (
_0_res1 : 1,
_0_ret1 : 1,
response_incomplete : 1,
_0_ret2 : 3,
removable_controller_or_media : 1,
removable_media : 1,
_0_ret3 : 7,
ATA : 1 // 0 - is ATA!
);
} ata;
struct {
LBITFIELD8 (
packet_size : 2, // 0 - 12 bytes, 1 - 16 bytes
response_incomplete : 1,
_0_res2 : 2,
drq_speed : 2, // 0 - 3ms, 1 - IRQ, 2 - 50µs
removable_media : 1,
type : 5,
_0_res13 : 1,
ATAPI : 2 // 2 - is ATAPI
);
} atapi;
} _0;
uint16 cylinders; // 2
uint16 dummy1; // 4
uint16 heads; // 6
uint16 dummy2[2]; // 8
uint16 sectors; // 0c
uint16 dummy3[3]; // 0e
char serial_number[20]; // 14
uint16 dummy4[3]; // 28
char firmware_version[8]; // 2e
char model_number[40]; // 36
uint16 dummy5[2]; // 5e
LBITFIELD5 ( // 62 (49) capabilities
_49_ret1 : 8,
DMA_supported : 1,
LBA_supported : 1,
IORDY_can_disable : 1,
IORDY_supported : 1
);
uint16 dummy6[1]; // 64
LBITFIELD2 ( // 66 (51) obsolete: PIO modes?
_51_obs1 : 8,
PIO_mode : 8
);
uint16 dummy7[1]; // 68
LBITFIELD3 ( // 6a (53) validity
_54_58_valid : 1,
_64_70_valid : 1,
_88_valid : 1
);
uint16 current_cylinders; // 6c (54)
uint16 current_heads; // 6e
uint16 current_sectors; // 70
uint16 capacity_low; // 72 (57) ALIGNMENT SPLIT - don't merge
uint16 capacity_high;
uint16 dummy8[1];
uint32 LBA_total_sectors; // 78 (60)
uint16 dummy9[1]; // 7c
LBITFIELD7 ( // 7e (63) MDMA modes
MDMA0_supported : 1,
MDMA1_supported : 1,
MDMA2_supported : 1,
_63_res1 : 5,
MDMA0_selected : 1,
MDMA1_selected : 1,
MDMA2_selected : 1
);
uint16 dummy10[11]; // 80
LBITFIELD2 ( // 96 (75)
queue_depth : 5,
_75_res1 : 9
);
uint16 dummy11[6]; // 98
LBITFIELD16 ( // a4 (82) supported_command_set
SMART_supported : 1,
security_mode_supported : 1,
removable_media_supported : 1,
PM_supported : 1,
_81_fixed : 1, // must be 0
write_cache_supported : 1,
look_ahead_supported : 1,
RELEASE_irq_supported : 1,
SERVICE_irq_supported : 1,
DEVICE_RESET_supported : 1,
HPA_supported : 1,
_81_obs1 : 1,
WRITE_BUFFER_supported : 1,
READ_BUFFER_supported : 1,
NOP_supported : 1,
_81_obs2 : 1
);
LBITFIELD15 ( // a6 (83) supported_command_sets
DOWNLOAD_MICROCODE_supported : 1,
DMA_QUEUED_supported : 1,
CFA_supported : 1,
APM_supported : 1,
RMSN_supported : 1,
power_up_in_stand_by_supported : 1,
SET_FEATURES_on_power_up_required : 1,
reserved_boot_area_supported : 1,
SET_MAX_security_supported : 1,
auto_acustic_managemene_supported : 1,
_48_bit_addresses_supported : 1,
device_conf_overlay_supported : 1,
FLUSH_CACHE_supported : 1,
FLUSH_CACHE_EXT_supported : 1,
_83_fixed : 2 // must be 1
);
uint16 dummy12[4]; // a8 (84)
LBITFIELD15 ( // b0 (88) UDMA modes
UDMA0_supported : 1,
UDMA1_supported : 1,
UDMA2_supported : 1,
UDMA3_supported : 1,
UDMA4_supported : 1,
UDMA5_supported : 1,
UDMA6_supported : 1, // !guessed
_88_res1 : 1,
UDMA0_selected : 1,
UDMA1_selected : 1,
UDMA2_selected : 1,
UDMA3_selected : 1,
UDMA4_selected : 1,
UDMA5_selected : 1,
UDMA6_selected : 1
);
uint16 dummy89[11]; // b2 (89)
uint64 LBA48_total_sectors; // c8 (100)
uint16 dummy102[22]; // cc (104)
LBITFIELD2 ( // fc (126)
last_lun : 2,
_126_res2 : 14
);
LBITFIELD4 ( // fe (127) RMSN support
_127_RMSN_support : 2,// 0 = not supported, 1 = supported, 3, 4 = reserved
_127_res2 : 6,
device_write_protect: 2,
_127_res9 : 6
);
uint16 dummy14[128]; // 100 (128)
} ata_device_infoblock;
#endif /* _ATA_DEVICE_INFOBLOCK_H_ */