From 5ec5667de7fe0bdf67aa4ae52a21103162807f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 28 Jan 2013 22:38:55 +0100 Subject: [PATCH] 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. --- .../kernel/bus_managers/ata/ATADevice.cpp | 27 ++--------- .../kernel/bus_managers/ata/ATAInfoBlock.h | 47 ++++++++++++++++++- .../kernel/busses/scsi/ahci/ahci_port.cpp | 29 +++++------- 3 files changed, 63 insertions(+), 40 deletions(-) diff --git a/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp b/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp index 323b30fd8b..41f633da5a 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp +++ b/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp @@ -532,33 +532,14 @@ ATADevice::Configure() return B_ERROR; } - fTotalSectors = fInfoBlock.lba_sector_count; - - if (fInfoBlock.word_106_bit_14_one && !fInfoBlock.word_106_bit_15_zero) { - // contains a valid block size configuration - 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; - } + fTotalSectors = fInfoBlock.SectorCount(fUse48Bits, false); + fBlockSize = fInfoBlock.SectorSize(); + fPhysicalBlockSize = fInfoBlock.PhysicalSectorSize(); + fBlockOffset = fInfoBlock.BlockOffset(); fTaskFile.lba.mode = ATA_MODE_LBA; 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(); if (result != B_OK) return result; diff --git a/src/add-ons/kernel/bus_managers/ata/ATAInfoBlock.h b/src/add-ons/kernel/bus_managers/ata/ATAInfoBlock.h index 197696f913..402fd20323 100644 --- a/src/add-ons/kernel/bus_managers/ata/ATAInfoBlock.h +++ b/src/add-ons/kernel/bus_managers/ata/ATAInfoBlock.h @@ -1,5 +1,5 @@ /* - * Copyright 2010, Axel Dörfler, axeld@pinc-software.de. + * Copyright 2010-2013, Axel Dörfler, axeld@pinc-software.de. * Copyright 2009, Michael Lotz, mmlr@mlotz.ch. * Distributed under the terms of the MIT License. */ @@ -364,6 +364,51 @@ typedef struct ata_device_infoblock { signature : 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; + #endif // ATA_INFOBLOCK_H diff --git a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp index 3d51f71281..e88a1a4690 100644 --- a/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp +++ b/src/add-ons/kernel/busses/scsi/ahci/ahci_port.cpp @@ -471,10 +471,10 @@ AHCIPort::FillPrdTable(volatile prd *prdTable, int *prdCount, int prdMax, FLOW("FillPrdTable: prd-entry %u, addr %p, size %lu\n", *prdCount, address, bytes); - prdTable->dba = LO32(address); + prdTable->dba = LO32(address); prdTable->dbau = HI32(address); - prdTable->res = 0; - prdTable->dbc = bytes - 1; + prdTable->res = 0; + prdTable->dbc = bytes - 1; *prdCount += 1; prdTable++; 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_type_modifier = 0; - scsiData.removable_medium = fIsATAPI; + scsiData.removable_medium = ataData.word_0.ata.removable_media_device; scsiData.ansi_version = 2; scsiData.ecma_version = 0; scsiData.iso_version = 0; scsiData.response_data_format = 2; scsiData.term_iop = false; - scsiData.additional_length = sizeof(scsiData) - 4; + scsiData.additional_length = sizeof(scsi_res_inquiry) - 4; scsiData.soft_reset = false; scsiData.cmd_queue = false; scsiData.linked = false; @@ -601,18 +602,14 @@ AHCIPort::ScsiInquiry(scsi_ccb *request) scsiData.relative_address = false; if (!fIsATAPI) { - bool lba = ataData.dma_supported != 0; - bool lba48 = ataData.lba48_supported != 0; - uint32 sectors = ataData.lba_sector_count; - uint64 sectors48 = ataData.lba48_sector_count; - fUse48BitCommands = lba && lba48; - fSectorSize = 512; - fSectorCount = !(lba || sectors) ? 0 : lba48 ? sectors48 : sectors; + fSectorCount = ataData.SectorCount(fUse48BitCommands, true); + fSectorSize = ataData.SectorSize(); fTrim = ataData.data_set_management_support; TRACE("lba %d, lba48 %d, fUse48BitCommands %d, sectors %" B_PRIu32 ", sectors48 %" B_PRIu64 ", size %" B_PRIu64 "\n", - lba, lba48, fUse48BitCommands, sectors, sectors48, - fSectorCount * fSectorSize); + ataData.dma_supported != 0, ataData.lba48_supported != 0, + fUse48BitCommands, ataData.lba_sector_count, + ataData.lba48_sector_count, fSectorCount * fSectorSize); } #if 0 @@ -955,7 +952,7 @@ AHCIPort::ScsiExecuteRequest(scsi_ccb *request) request->subsys_status = SCSI_REQ_INVALID; gSCSI->finished(request, 1); } - break; + break; case SCSI_OP_SYNCHRONIZE_CACHE: ScsiSynchronizeCache(request); break;