[haiku-commits] haiku: hrev45217 - in src/add-ons/kernel: partitioning_systems/gpt bus_managers/ata busses/scsi/ahci

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 28 Jan 2013 22:52:43 +0100 (CET)

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
 


Other related posts:

  • » [haiku-commits] haiku: hrev45217 - in src/add-ons/kernel: partitioning_systems/gpt bus_managers/ata busses/scsi/ahci - axeld