ata/ahci: Move some ATA functionality into the ATAInfoBlock.
* The AHCI driver was actually ignoring sector size information, and always set the size to 512. * Now both, the AHCI driver, and the ATA bus manager, use the same method of retrieving the sector count, and size.
This commit is contained in:
@@ -532,33 +532,14 @@ ATADevice::Configure()
|
|||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
fTotalSectors = fInfoBlock.lba_sector_count;
|
fTotalSectors = fInfoBlock.SectorCount(fUse48Bits, false);
|
||||||
|
fBlockSize = fInfoBlock.SectorSize();
|
||||||
if (fInfoBlock.word_106_bit_14_one && !fInfoBlock.word_106_bit_15_zero) {
|
fPhysicalBlockSize = fInfoBlock.PhysicalSectorSize();
|
||||||
// contains a valid block size configuration
|
fBlockOffset = fInfoBlock.BlockOffset();
|
||||||
if (fInfoBlock.logical_sector_not_512_bytes)
|
|
||||||
fBlockSize = fInfoBlock.logical_sector_size * 2;
|
|
||||||
|
|
||||||
if (fInfoBlock.multiple_logical_per_physical_sectors) {
|
|
||||||
fPhysicalBlockSize
|
|
||||||
= fBlockSize << fInfoBlock.logical_sectors_per_physical_sector;
|
|
||||||
} else
|
|
||||||
fPhysicalBlockSize = fBlockSize;
|
|
||||||
}
|
|
||||||
if (fInfoBlock.word_209_bit_14_one && !fInfoBlock.word_209_bit_15_zero) {
|
|
||||||
// contains a valid logical block offset configuration
|
|
||||||
fBlockOffset = fInfoBlock.logical_sector_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
fTaskFile.lba.mode = ATA_MODE_LBA;
|
fTaskFile.lba.mode = ATA_MODE_LBA;
|
||||||
fTaskFile.lba.device = fIndex;
|
fTaskFile.lba.device = fIndex;
|
||||||
|
|
||||||
if (fInfoBlock.lba48_supported
|
|
||||||
&& fInfoBlock.lba48_sector_count >= fInfoBlock.lba_sector_count) {
|
|
||||||
fUse48Bits = true;
|
|
||||||
fTotalSectors = fInfoBlock.lba48_sector_count;
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t result = ConfigureDMA();
|
status_t result = ConfigureDMA();
|
||||||
if (result != B_OK)
|
if (result != B_OK)
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010, Axel Dörfler, [email protected].
|
* Copyright 2010-2013, Axel Dörfler, [email protected].
|
||||||
* Copyright 2009, Michael Lotz, [email protected].
|
* Copyright 2009, Michael Lotz, [email protected].
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
@@ -364,6 +364,51 @@ typedef struct ata_device_infoblock {
|
|||||||
signature : 8,
|
signature : 8,
|
||||||
checksum : 8
|
checksum : 8
|
||||||
);
|
);
|
||||||
|
|
||||||
|
uint64 SectorCount(bool& use48Bits, bool force)
|
||||||
|
{
|
||||||
|
if (lba48_supported && lba48_sector_count >= lba_sector_count) {
|
||||||
|
use48Bits = true;
|
||||||
|
return lba48_sector_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
use48Bits = force ? lba48_supported : false;
|
||||||
|
return lba_sector_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 PhysicalSectorSize()
|
||||||
|
{
|
||||||
|
uint32 blockSize = 512;
|
||||||
|
if (word_106_bit_14_one && !word_106_bit_15_zero) {
|
||||||
|
// contains a valid block size configuration
|
||||||
|
if (logical_sector_not_512_bytes)
|
||||||
|
blockSize = logical_sector_size * 2;
|
||||||
|
|
||||||
|
if (multiple_logical_per_physical_sectors)
|
||||||
|
return blockSize << logical_sectors_per_physical_sector;
|
||||||
|
}
|
||||||
|
return blockSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 SectorSize()
|
||||||
|
{
|
||||||
|
if (word_106_bit_14_one && !word_106_bit_15_zero) {
|
||||||
|
// contains a valid block size configuration
|
||||||
|
if (logical_sector_not_512_bytes)
|
||||||
|
return logical_sector_size * 2;
|
||||||
|
}
|
||||||
|
return 512;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 BlockOffset()
|
||||||
|
{
|
||||||
|
if (word_209_bit_14_one && !word_209_bit_15_zero) {
|
||||||
|
// contains a valid logical block offset configuration
|
||||||
|
return logical_sector_offset;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
} _PACKED ata_device_infoblock;
|
} _PACKED ata_device_infoblock;
|
||||||
|
|
||||||
|
|
||||||
#endif // ATA_INFOBLOCK_H
|
#endif // ATA_INFOBLOCK_H
|
||||||
|
|||||||
@@ -471,10 +471,10 @@ AHCIPort::FillPrdTable(volatile prd *prdTable, int *prdCount, int prdMax,
|
|||||||
FLOW("FillPrdTable: prd-entry %u, addr %p, size %lu\n",
|
FLOW("FillPrdTable: prd-entry %u, addr %p, size %lu\n",
|
||||||
*prdCount, address, bytes);
|
*prdCount, address, bytes);
|
||||||
|
|
||||||
prdTable->dba = LO32(address);
|
prdTable->dba = LO32(address);
|
||||||
prdTable->dbau = HI32(address);
|
prdTable->dbau = HI32(address);
|
||||||
prdTable->res = 0;
|
prdTable->res = 0;
|
||||||
prdTable->dbc = bytes - 1;
|
prdTable->dbc = bytes - 1;
|
||||||
*prdCount += 1;
|
*prdCount += 1;
|
||||||
prdTable++;
|
prdTable++;
|
||||||
address = address + bytes;
|
address = address + bytes;
|
||||||
@@ -582,16 +582,17 @@ AHCIPort::ScsiInquiry(scsi_ccb *request)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
scsiData.device_type = fIsATAPI ? scsi_dev_CDROM : scsi_dev_direct_access;
|
scsiData.device_type = fIsATAPI
|
||||||
|
? ataData.word_0.atapi.command_packet_set : scsi_dev_direct_access;
|
||||||
scsiData.device_qualifier = scsi_periph_qual_connected;
|
scsiData.device_qualifier = scsi_periph_qual_connected;
|
||||||
scsiData.device_type_modifier = 0;
|
scsiData.device_type_modifier = 0;
|
||||||
scsiData.removable_medium = fIsATAPI;
|
scsiData.removable_medium = ataData.word_0.ata.removable_media_device;
|
||||||
scsiData.ansi_version = 2;
|
scsiData.ansi_version = 2;
|
||||||
scsiData.ecma_version = 0;
|
scsiData.ecma_version = 0;
|
||||||
scsiData.iso_version = 0;
|
scsiData.iso_version = 0;
|
||||||
scsiData.response_data_format = 2;
|
scsiData.response_data_format = 2;
|
||||||
scsiData.term_iop = false;
|
scsiData.term_iop = false;
|
||||||
scsiData.additional_length = sizeof(scsiData) - 4;
|
scsiData.additional_length = sizeof(scsi_res_inquiry) - 4;
|
||||||
scsiData.soft_reset = false;
|
scsiData.soft_reset = false;
|
||||||
scsiData.cmd_queue = false;
|
scsiData.cmd_queue = false;
|
||||||
scsiData.linked = false;
|
scsiData.linked = false;
|
||||||
@@ -601,18 +602,14 @@ AHCIPort::ScsiInquiry(scsi_ccb *request)
|
|||||||
scsiData.relative_address = false;
|
scsiData.relative_address = false;
|
||||||
|
|
||||||
if (!fIsATAPI) {
|
if (!fIsATAPI) {
|
||||||
bool lba = ataData.dma_supported != 0;
|
fSectorCount = ataData.SectorCount(fUse48BitCommands, true);
|
||||||
bool lba48 = ataData.lba48_supported != 0;
|
fSectorSize = ataData.SectorSize();
|
||||||
uint32 sectors = ataData.lba_sector_count;
|
|
||||||
uint64 sectors48 = ataData.lba48_sector_count;
|
|
||||||
fUse48BitCommands = lba && lba48;
|
|
||||||
fSectorSize = 512;
|
|
||||||
fSectorCount = !(lba || sectors) ? 0 : lba48 ? sectors48 : sectors;
|
|
||||||
fTrim = ataData.data_set_management_support;
|
fTrim = ataData.data_set_management_support;
|
||||||
TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %" B_PRIu32
|
TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %" B_PRIu32
|
||||||
", sectors48 %" B_PRIu64 ", size %" B_PRIu64 "\n",
|
", sectors48 %" B_PRIu64 ", size %" B_PRIu64 "\n",
|
||||||
lba, lba48, fUse48BitCommands, sectors, sectors48,
|
ataData.dma_supported != 0, ataData.lba48_supported != 0,
|
||||||
fSectorCount * fSectorSize);
|
fUse48BitCommands, ataData.lba_sector_count,
|
||||||
|
ataData.lba48_sector_count, fSectorCount * fSectorSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -955,7 +952,7 @@ AHCIPort::ScsiExecuteRequest(scsi_ccb *request)
|
|||||||
request->subsys_status = SCSI_REQ_INVALID;
|
request->subsys_status = SCSI_REQ_INVALID;
|
||||||
gSCSI->finished(request, 1);
|
gSCSI->finished(request, 1);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_OP_SYNCHRONIZE_CACHE:
|
case SCSI_OP_SYNCHRONIZE_CACHE:
|
||||||
ScsiSynchronizeCache(request);
|
ScsiSynchronizeCache(request);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user