hrev45217 adds 4 changesets to branch 'master' old head: 157ec8a798891d41b9ed65c4515cbd8b84832dfc new head: 7775bfeb6bb0d4b71d9436a6e33e112d53878ee4 overview: http://cgit.haiku-os.org/haiku/log/?qt=range&q=7775bfe+%5E157ec8a ---------------------------------------------------------------------------- 5ec5667: 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. 403869b: DriveSetup: improved error reporting. 9e8f937: gpt: Added some missing pieces of supporting the backup header. * The alternate block was not set correctly. * The CRC of the backup header was never updated. * We now dump both headers. 7775bfe: gpt: Always use at least 4K to align partitions. * Many of today's disks that use 4K internally don't advertize this. [ Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> ] ---------------------------------------------------------------------------- 7 files changed, 109 insertions(+), 67 deletions(-) .../kernel/bus_managers/ata/ATADevice.cpp | 27 ++-------- .../kernel/bus_managers/ata/ATAInfoBlock.h | 47 ++++++++++++++++- .../kernel/busses/scsi/ahci/ahci_port.cpp | 29 +++++------ .../kernel/partitioning_systems/gpt/Header.cpp | 55 +++++++++++++------- .../kernel/partitioning_systems/gpt/Header.h | 3 +- .../kernel/partitioning_systems/gpt/efi_gpt.cpp | 11 ++-- src/apps/drivesetup/MainWindow.cpp | 4 +- ############################################################################ Commit: 5ec5667de7fe0bdf67aa4ae52a21103162807f10 URL: http://cgit.haiku-os.org/haiku/commit/?id=5ec5667 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Mon Jan 28 21:38:55 2013 UTC 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. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp b/src/add-ons/kernel/bus_managers/ata/ATADevice.cpp index 323b30f..41f633d 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 197696f..402fd20 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@xxxxxxxxxxxxxxxx. + * Copyright 2010-2013, Axel Dörfler, axeld@xxxxxxxxxxxxxxxx. * Copyright 2009, Michael Lotz, mmlr@xxxxxxxx. * 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 3d51f71..e88a1a4 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; ############################################################################ Commit: 403869b9fe4c2b40f24e69033a8936d265840fcd URL: http://cgit.haiku-os.org/haiku/commit/?id=403869b Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Mon Jan 28 21:41:20 2013 UTC DriveSetup: improved error reporting. ---------------------------------------------------------------------------- diff --git a/src/apps/drivesetup/MainWindow.cpp b/src/apps/drivesetup/MainWindow.cpp index e0cc9ff..e6ebcc0 100644 --- a/src/apps/drivesetup/MainWindow.cpp +++ b/src/apps/drivesetup/MainWindow.cpp @@ -1066,7 +1066,7 @@ MainWindow::_Create(BDiskDevice* disk, partition_id selectedPartition) if (ret != B_OK) { _DisplayPartitionError(B_TRANSLATE("Creation of the partition has " - "failed.")); + "failed."), NULL, ret); return; } @@ -1075,7 +1075,7 @@ MainWindow::_Create(BDiskDevice* disk, partition_id selectedPartition) if (ret != B_OK) { _DisplayPartitionError(B_TRANSLATE("Failed to format the " - "partition. No changes have been written to disk.")); + "partition. No changes have been written to disk."), NULL, ret); return; } ############################################################################ Commit: 9e8f937437083a330f440629007ec1ce13221d5b URL: http://cgit.haiku-os.org/haiku/commit/?id=9e8f937 Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Mon Jan 28 21:42:01 2013 UTC gpt: Added some missing pieces of supporting the backup header. * The alternate block was not set correctly. * The CRC of the backup header was never updated. * We now dump both headers. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/partitioning_systems/gpt/Header.cpp b/src/add-ons/kernel/partitioning_systems/gpt/Header.cpp index 96a952c..289f926 100644 --- a/src/add-ons/kernel/partitioning_systems/gpt/Header.cpp +++ b/src/add-ons/kernel/partitioning_systems/gpt/Header.cpp @@ -55,6 +55,12 @@ Header::Header(int fd, uint64 lastBlock, uint32 blockSize) fStatus = B_BAD_DATA; } + if (fStatus == B_OK && lastBlock != fHeader.AlternateBlock()) { + dprintf("gpt: alternate header not in last block (%" B_PRIu64 " vs. %" + B_PRIu64 ")\n", fHeader.AlternateBlock(), lastBlock); + lastBlock = fHeader.AlternateBlock(); + } + // Read backup header, too status_t status = _Read(fd, lastBlock * blockSize, &fBackupHeader, sizeof(efi_table_header)); @@ -72,6 +78,7 @@ Header::Header(int fd, uint64 lastBlock, uint32 blockSize) fHeader = fBackupHeader; fHeader.SetAbsoluteBlock(EFI_HEADER_LOCATION); fHeader.SetEntriesBlock(EFI_PARTITION_ENTRIES_BLOCK); + fHeader.SetAlternateBlock(lastBlock); } else if (status != B_OK) { // Recreate backup header from primary _SetBackupHeaderFromPrimary(lastBlock); @@ -105,7 +112,8 @@ Header::Header(int fd, uint64 lastBlock, uint32 blockSize) // TODO: check overlapping or out of range partitions #ifdef TRACE_EFI_GPT - _Dump(); + _Dump(fHeader); + _Dump(fBackupHeader); _DumpPartitions(); #endif @@ -153,7 +161,7 @@ Header::Header(uint64 lastBlock, uint32 blockSize) _SetBackupHeaderFromPrimary(lastBlock); #ifdef TRACE_EFI_GPT - _Dump(); + _Dump(fHeader); _DumpPartitions(); #endif @@ -253,9 +261,17 @@ Header::_Write(int fd, off_t offset, const void* data, size_t size) const void Header::_UpdateCRC() { - fHeader.SetEntriesCRC(crc32(fEntries, _EntryArraySize())); - fHeader.SetHeaderCRC(0); - fHeader.SetHeaderCRC(crc32((uint8*)&fHeader, sizeof(efi_table_header))); + _UpdateCRC(fHeader); + _UpdateCRC(fBackupHeader); +} + + +void +Header::_UpdateCRC(efi_table_header& header) +{ + header.SetEntriesCRC(crc32(fEntries, _EntryArraySize())); + header.SetHeaderCRC(0); + header.SetHeaderCRC(crc32((uint8*)&header, sizeof(efi_table_header))); } #endif // !_BOOT_MODE @@ -310,6 +326,7 @@ Header::_SetBackupHeaderFromPrimary(uint64 lastBlock) fBackupHeader.SetAbsoluteBlock(lastBlock); fBackupHeader.SetEntriesBlock( lastBlock - _EntryArraySize() / fBlockSize); + fBackupHeader.SetAlternateBlock(1); } @@ -329,21 +346,21 @@ Header::_PrintGUID(const guid_t &id) void -Header::_Dump() +Header::_Dump(const efi_table_header& header) { - dprintf("EFI header: %.8s\n", fHeader.header); - dprintf("EFI revision: %" B_PRIx32 "\n", fHeader.Revision()); - dprintf("header size: %ld\n", fHeader.HeaderSize()); - dprintf("header CRC: %ld\n", fHeader.HeaderCRC()); - dprintf("absolute block: %Ld\n", fHeader.AbsoluteBlock()); - dprintf("alternate block: %Ld\n", fHeader.AlternateBlock()); - dprintf("first usable block: %Ld\n", fHeader.FirstUsableBlock()); - dprintf("last usable block: %Ld\n", fHeader.LastUsableBlock()); - dprintf("disk GUID: %s\n", _PrintGUID(fHeader.disk_guid)); - dprintf("entries block: %Ld\n", fHeader.EntriesBlock()); - dprintf("entry size: %ld\n", fHeader.EntrySize()); - dprintf("entry count: %ld\n", fHeader.EntryCount()); - dprintf("entries CRC: %ld\n", fHeader.EntriesCRC()); + dprintf("EFI header: %.8s\n", header.header); + dprintf("EFI revision: %" B_PRIx32 "\n", header.Revision()); + dprintf("header size: %ld\n", header.HeaderSize()); + dprintf("header CRC: %ld\n", header.HeaderCRC()); + dprintf("absolute block: %Ld\n", header.AbsoluteBlock()); + dprintf("alternate block: %Ld\n", header.AlternateBlock()); + dprintf("first usable block: %Ld\n", header.FirstUsableBlock()); + dprintf("last usable block: %Ld\n", header.LastUsableBlock()); + dprintf("disk GUID: %s\n", _PrintGUID(header.disk_guid)); + dprintf("entries block: %Ld\n", header.EntriesBlock()); + dprintf("entry size: %ld\n", header.EntrySize()); + dprintf("entry count: %ld\n", header.EntryCount()); + dprintf("entries CRC: %ld\n", header.EntriesCRC()); } diff --git a/src/add-ons/kernel/partitioning_systems/gpt/Header.h b/src/add-ons/kernel/partitioning_systems/gpt/Header.h index e1bb020..f6781c6 100644 --- a/src/add-ons/kernel/partitioning_systems/gpt/Header.h +++ b/src/add-ons/kernel/partitioning_systems/gpt/Header.h @@ -48,6 +48,7 @@ private: status_t _Write(int fd, off_t offset, const void* data, size_t size) const; void _UpdateCRC(); + void _UpdateCRC(efi_table_header& header); #endif status_t _Read(int fd, off_t offset, void* data, @@ -62,7 +63,7 @@ private: * fHeader.EntryCount(); } const char* _PrintGUID(const guid_t& id); - void _Dump(); + void _Dump(const efi_table_header& header); void _DumpPartitions(); private: ############################################################################ Revision: hrev45217 Commit: 7775bfeb6bb0d4b71d9436a6e33e112d53878ee4 URL: http://cgit.haiku-os.org/haiku/commit/?id=7775bfe Author: Axel Dörfler <axeld@xxxxxxxxxxxxxxxx> Date: Mon Jan 28 21:47:30 2013 UTC gpt: Always use at least 4K to align partitions. * Many of today's disks that use 4K internally don't advertize this. ---------------------------------------------------------------------------- diff --git a/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp b/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp index 248de68..7b87a29 100644 --- a/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp +++ b/src/add-ons/kernel/partitioning_systems/gpt/efi_gpt.cpp @@ -42,12 +42,13 @@ static off_t block_align(partition_data* partition, off_t offset, bool upwards) { - if (upwards) { - return ((offset + partition->block_size - 1) / partition->block_size) - * partition->block_size; - } + // Take HDs into account that hide the fact they are using a + // block size of 4096 bytes, and round to that. + uint32 blockSize = max_c(partition->block_size, 4096); + if (upwards) + return ((offset + blockSize - 1) / blockSize) * blockSize; - return (offset / partition->block_size) * partition->block_size; + return (offset / blockSize) * blockSize; } #endif // !_BOOT_MODE