* 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:
@@ -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_ */
|
||||
Reference in New Issue
Block a user