* 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),
|
fDMAMode(0),
|
||||||
fDMAFailures(0),
|
fDMAFailures(0),
|
||||||
fIndex(index),
|
fIndex(index),
|
||||||
fUseLBA(false),
|
|
||||||
fUse48Bits(false),
|
fUse48Bits(false),
|
||||||
fTotalSectors(0)
|
fTotalSectors(0)
|
||||||
{
|
{
|
||||||
@@ -114,11 +113,12 @@ ATADevice::Inquiry(ATARequest *request)
|
|||||||
scsi_res_inquiry data;
|
scsi_res_inquiry data;
|
||||||
memset(&data, 0, sizeof(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_qualifier = scsi_periph_qual_connected;
|
||||||
|
|
||||||
data.device_type_modifier = 0;
|
data.device_type_modifier = 0;
|
||||||
data.removable_medium = false;
|
data.removable_medium = fInfoBlock.word_0.ata.removable_media_device;
|
||||||
|
|
||||||
data.ansi_version = 2;
|
data.ansi_version = 2;
|
||||||
data.ecma_version = 0;
|
data.ecma_version = 0;
|
||||||
@@ -341,10 +341,10 @@ ATADevice::SetFeature(int feature)
|
|||||||
status_t
|
status_t
|
||||||
ATADevice::DisableCommandQueueing()
|
ATADevice::DisableCommandQueueing()
|
||||||
{
|
{
|
||||||
if (!fInfoBlock.DMA_QUEUED_supported)
|
if (!fInfoBlock.read_write_dma_queued_supported)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
if (fInfoBlock.RELEASE_irq_supported) {
|
if (fInfoBlock.release_interrupt_supported) {
|
||||||
status_t result = SetFeature(
|
status_t result = SetFeature(
|
||||||
ATA_COMMAND_SET_FEATURES_DISABLE_RELEASE_INT);
|
ATA_COMMAND_SET_FEATURES_DISABLE_RELEASE_INT);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
@@ -353,7 +353,7 @@ ATADevice::DisableCommandQueueing()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fInfoBlock.SERVICE_irq_supported) {
|
if (fInfoBlock.service_interrupt_supported) {
|
||||||
status_t result = SetFeature(
|
status_t result = SetFeature(
|
||||||
ATA_COMMAND_SET_FEATURES_DISABLE_SERVICE_INT);
|
ATA_COMMAND_SET_FEATURES_DISABLE_SERVICE_INT);
|
||||||
if (result != B_OK) {
|
if (result != B_OK) {
|
||||||
@@ -372,7 +372,7 @@ ATADevice::ConfigureDMA()
|
|||||||
if (!fUseDMA)
|
if (!fUseDMA)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
if (!fInfoBlock.DMA_supported) {
|
if (!fInfoBlock.dma_supported) {
|
||||||
TRACE_ALWAYS("DMA not supported by device\n");
|
TRACE_ALWAYS("DMA not supported by device\n");
|
||||||
fUseDMA = false;
|
fUseDMA = false;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -386,18 +386,18 @@ ATADevice::ConfigureDMA()
|
|||||||
|
|
||||||
uint32 modeCount = 0;
|
uint32 modeCount = 0;
|
||||||
|
|
||||||
CHECK_DMA_MODE(MDMA0_selected, 0x00);
|
CHECK_DMA_MODE(multiword_dma_0_selected, 0x00);
|
||||||
CHECK_DMA_MODE(MDMA1_selected, 0x01);
|
CHECK_DMA_MODE(multiword_dma_1_selected, 0x01);
|
||||||
CHECK_DMA_MODE(MDMA2_selected, 0x02);
|
CHECK_DMA_MODE(multiword_dma_2_selected, 0x02);
|
||||||
|
|
||||||
if (fInfoBlock._88_valid) {
|
if (fInfoBlock.word_88_valid) {
|
||||||
CHECK_DMA_MODE(UDMA0_selected, 0x10);
|
CHECK_DMA_MODE(ultra_dma_0_selected, 0x10);
|
||||||
CHECK_DMA_MODE(UDMA1_selected, 0x11);
|
CHECK_DMA_MODE(ultra_dma_1_selected, 0x11);
|
||||||
CHECK_DMA_MODE(UDMA2_selected, 0x12);
|
CHECK_DMA_MODE(ultra_dma_2_selected, 0x12);
|
||||||
CHECK_DMA_MODE(UDMA3_selected, 0x13);
|
CHECK_DMA_MODE(ultra_dma_3_selected, 0x13);
|
||||||
CHECK_DMA_MODE(UDMA4_selected, 0x14);
|
CHECK_DMA_MODE(ultra_dma_4_selected, 0x14);
|
||||||
CHECK_DMA_MODE(UDMA5_selected, 0x15);
|
CHECK_DMA_MODE(ultra_dma_5_selected, 0x15);
|
||||||
CHECK_DMA_MODE(UDMA6_selected, 0x16);
|
CHECK_DMA_MODE(ultra_dma_6_selected, 0x16);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef CHECK_DMA_MODE
|
#undef CHECK_DMA_MODE
|
||||||
@@ -417,50 +417,32 @@ status_t
|
|||||||
ATADevice::Configure()
|
ATADevice::Configure()
|
||||||
{
|
{
|
||||||
// warning: ata == 0 means "this is ata"...
|
// 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
|
// CF has either magic header or CFA bit set
|
||||||
// we merge it to "CFA bit set" for easier (later) testing
|
// we merge it to "CFA bit set" for easier (later) testing
|
||||||
if (*(uint16 *)&fInfoBlock == 0x848a)
|
if (fInfoBlock.word_0.raw == ATA_WORD_0_CFA_MAGIC)
|
||||||
fInfoBlock.CFA_supported = true;
|
fInfoBlock.compact_flash_assoc_supported = true;
|
||||||
else
|
else {
|
||||||
|
TRACE_ERROR("infoblock indicates non-ata device\n");
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fInfoBlock._54_58_valid) {
|
if (!fInfoBlock.lba_supported || fInfoBlock.lba_sector_count == 0) {
|
||||||
// normally, current_xxx contains active CHS mapping,
|
TRACE_ERROR("non-lba devices not supported\n");
|
||||||
// but if BIOS didn't call INITIALIZE DEVICE PARAMETERS
|
return B_ERROR;
|
||||||
// the default mapping is used
|
|
||||||
fInfoBlock.current_sectors = fInfoBlock.sectors;
|
|
||||||
fInfoBlock.current_cylinders = fInfoBlock.cylinders;
|
|
||||||
fInfoBlock.current_heads = fInfoBlock.heads;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// just in case capacity_xxx isn't initialized - calculate it manually
|
fTotalSectors = fInfoBlock.lba_sector_count;
|
||||||
// (seems that this information is really redundant; hopefully)
|
fTaskFile.lba.mode = ATA_MODE_LBA;
|
||||||
uint32 chsCapacity = fInfoBlock.current_sectors
|
fTaskFile.lba.device = fIndex;
|
||||||
* fInfoBlock.current_cylinders * fInfoBlock.current_heads;
|
|
||||||
|
|
||||||
fInfoBlock.capacity_low = chsCapacity & 0xff;
|
if (fInfoBlock.lba48_supported
|
||||||
fInfoBlock.capacity_high = chsCapacity >> 8;
|
&& fInfoBlock.lba48_sector_count >= fInfoBlock.lba_sector_count) {
|
||||||
|
fUse48Bits = true;
|
||||||
// checking LBA_supported flag should be sufficient, but it seems
|
fTotalSectors = fInfoBlock.lba48_sector_count;
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fUse48Bits = fInfoBlock._48_bit_addresses_supported;
|
|
||||||
if (fUse48Bits)
|
|
||||||
fTotalSectors = fInfoBlock.LBA48_total_sectors;
|
|
||||||
|
|
||||||
status_t result = ConfigureDMA();
|
status_t result = ConfigureDMA();
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
@@ -611,60 +593,53 @@ ATADevice::_FillTaskFile(ATARequest *request, uint64 address)
|
|||||||
uint32 sectorCount = *request->BytesLeft() / ATA_BLOCK_SIZE;
|
uint32 sectorCount = *request->BytesLeft() / ATA_BLOCK_SIZE;
|
||||||
TRACE("about to transfer %lu sectors\n", sectorCount);
|
TRACE("about to transfer %lu sectors\n", sectorCount);
|
||||||
|
|
||||||
if (fUseLBA) {
|
if (fUse48Bits
|
||||||
if (fUse48Bits
|
&& (address + sectorCount > 0xfffffff || sectorCount > 0x100)) {
|
||||||
&& (address + sectorCount > 0xfffffff || sectorCount > 0x100)) {
|
// use LBA48 only if necessary
|
||||||
// use LBA48 only if necessary
|
if (sectorCount > 0xffff) {
|
||||||
if (sectorCount > 0xffff) {
|
TRACE_ERROR("invalid sector count %lu\n", sectorCount);
|
||||||
TRACE_ERROR("invalid sector count %lu\n", sectorCount);
|
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
|
||||||
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST,
|
SCSIS_ASC_INV_CDB_FIELD);
|
||||||
SCSIS_ASC_INV_CDB_FIELD);
|
return B_ERROR;
|
||||||
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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
} else {
|
||||||
// CHS mode - we do not support it anymore
|
// normal LBA
|
||||||
TRACE_ERROR("chs mode not supported\n");
|
if (sectorCount > 0x100) {
|
||||||
request->SetSense(SCSIS_KEY_ILLEGAL_REQUEST, SCSIS_ASC_INV_CDB_FIELD);
|
TRACE_ERROR("invalid sector count %lu\n", sectorCount);
|
||||||
return B_ERROR;
|
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;
|
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)
|
ATAPIDevice::ExecuteIO(ATARequest *request)
|
||||||
{
|
{
|
||||||
scsi_ccb *ccb = request->CCB();
|
scsi_ccb *ccb = request->CCB();
|
||||||
if (ccb->target_lun > fInfoBlock.last_lun) {
|
if (ccb->target_lun != 0) {
|
||||||
TRACE_ERROR("invalid target lun %d, last lun is %d\n", ccb->target_lun,
|
TRACE_ERROR("invalid target lun %d\n", ccb->target_lun);
|
||||||
fInfoBlock.last_lun);
|
|
||||||
request->SetStatus(SCSI_SEL_TIMEOUT);
|
request->SetStatus(SCSI_SEL_TIMEOUT);
|
||||||
return B_BAD_INDEX;
|
return B_BAD_INDEX;
|
||||||
}
|
}
|
||||||
@@ -209,8 +208,10 @@ ATAPIDevice::ExecuteIO(ATARequest *request)
|
|||||||
status_t
|
status_t
|
||||||
ATAPIDevice::Configure()
|
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;
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
fTaskFile.packet.lun = 0;
|
fTaskFile.packet.lun = 0;
|
||||||
|
|
||||||
@@ -218,6 +219,10 @@ ATAPIDevice::Configure()
|
|||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
|
result = DisableCommandQueueing();
|
||||||
|
if (result != B_OK)
|
||||||
|
return result;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,8 +22,8 @@
|
|||||||
#include <util/AutoLock.h>
|
#include <util/AutoLock.h>
|
||||||
|
|
||||||
#include "ATACommands.h"
|
#include "ATACommands.h"
|
||||||
|
#include "ATAInfoblock.h"
|
||||||
#include "ATATracing.h"
|
#include "ATATracing.h"
|
||||||
#include "ata_device_infoblock.h"
|
|
||||||
|
|
||||||
#define ATA_BLOCK_SIZE 512 /* TODO: retrieve */
|
#define ATA_BLOCK_SIZE 512 /* TODO: retrieve */
|
||||||
#define ATA_MAX_DMA_FAILURES 3
|
#define ATA_MAX_DMA_FAILURES 3
|
||||||
@@ -33,8 +33,8 @@
|
|||||||
#define ATA_SIGNATURE_ATAPI 0xeb140101
|
#define ATA_SIGNATURE_ATAPI 0xeb140101
|
||||||
#define ATA_SIGNATURE_SATA 0xc33c0101
|
#define ATA_SIGNATURE_SATA 0xc33c0101
|
||||||
#define ATA_SIM_MODULE_NAME "bus_managers/ata/sim/driver_v1"
|
#define ATA_SIM_MODULE_NAME "bus_managers/ata/sim/driver_v1"
|
||||||
#define ATA_CHANNEL_ID_GENERATOR "ata/channel_id"
|
#define ATA_CHANNEL_ID_GENERATOR "ide/channel_id"
|
||||||
#define ATA_CHANNEL_ID_ITEM "ata/channel_id"
|
#define ATA_CHANNEL_ID_ITEM "ide/channel_id"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
ATA_DEVICE_READY_REQUIRED = 0x01,
|
ATA_DEVICE_READY_REQUIRED = 0x01,
|
||||||
@@ -180,7 +180,6 @@ virtual status_t ExecuteIO(ATARequest *request);
|
|||||||
virtual bool IsATAPI() { return false; };
|
virtual bool IsATAPI() { return false; };
|
||||||
|
|
||||||
bool UseDMA() { return fUseDMA; };
|
bool UseDMA() { return fUseDMA; };
|
||||||
bool UseLBA() { return fUseLBA; };
|
|
||||||
bool Use48Bits() { return fUse48Bits; };
|
bool Use48Bits() { return fUse48Bits; };
|
||||||
|
|
||||||
status_t Select();
|
status_t Select();
|
||||||
@@ -215,7 +214,6 @@ private:
|
|||||||
uint64 address);
|
uint64 address);
|
||||||
|
|
||||||
uint8 fIndex;
|
uint8 fIndex;
|
||||||
bool fUseLBA;
|
|
||||||
bool fUse48Bits;
|
bool fUse48Bits;
|
||||||
uint64 fTotalSectors;
|
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