diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index be125ba..63f018d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c @@ -968,29 +968,6 @@ static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors) } /** - * ata_hpa_native_size - Get the native size of a disk - * @dev: Device to get the size for - * - * Read the size of an LBA28 or LBA48 disk with HPA features and - * return the native size. Caller must check that the drive has HPA - * feature set enabled. - */ -static u64 ata_hpa_native_size(struct ata_device *dev) -{ - if (ata_id_has_lba48(dev->id)) - return ata_read_native_max_address_ext(dev); - else - return ata_read_native_max_address(dev); -} - -static unsigned long long sectors_to_MB(unsigned long long n) -{ - n <<= 9; /* make it bytes */ - do_div(n, 1000000); /* make it MB */ - return n; -} - -/** * ata_hpa_resize - Resize a device with an HPA set * @dev: Device to resize * @@ -1002,19 +979,23 @@ static unsigned long long sectors_to_MB(unsigned long long n) static u64 ata_hpa_resize(struct ata_device *dev) { u64 sectors = dev->n_sectors; - u64 hpa_sectors = ata_hpa_native_size(dev); + u64 hpa_sectors; + if (ata_id_has_lba48(dev->id)) + hpa_sectors = ata_read_native_max_address_ext(dev); + else + hpa_sectors = ata_read_native_max_address(dev); + /* if no hpa, both should be equal */ ata_dev_printk(dev, KERN_INFO, "%s 1: sectors = %lld, hpa_sectors = %lld\n", __FUNCTION__, sectors, hpa_sectors); if (hpa_sectors > sectors) { ata_dev_printk(dev, KERN_INFO, - "Host Protected Area detected.\n" - "\tcurrent size : %llu sectors (%llu MB)\n" - "\tnative size : %llu sectors (%llu MB)\n", - sectors, sectors_to_MB(sectors), - hpa_sectors, sectors_to_MB(hpa_sectors)); + "Host Protected Area detected:\n" + "\tcurrent size: %lld sectors\n" + "\tnative size: %lld sectors\n", + sectors, hpa_sectors); if (ata_ignore_hpa) { if (ata_id_has_lba48(dev->id)) @@ -1882,6 +1863,7 @@ int ata_dev_configure(struct ata_device *dev) snprintf(revbuf, 7, "ATA-%d", ata_id_major_version(id)); dev->n_sectors = ata_id_n_sectors(id); + dev->n_sectors_boot = dev->n_sectors; /* SCSI only uses 4-char revisions, dump full 8 chars from ATA */ ata_id_c_string(dev->id, fwrevbuf, ATA_ID_FW_REV, @@ -3542,15 +3524,8 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, ata_id_c_string(new_id, model[1], ATA_ID_PROD, sizeof(model[1])); ata_id_c_string(old_id, serial[0], ATA_ID_SERNO, sizeof(serial[0])); ata_id_c_string(new_id, serial[1], ATA_ID_SERNO, sizeof(serial[1])); - new_n_sectors = ata_id_n_sectors(new_id); - if (ata_ignore_hpa && ata_id_hpa_enabled(new_id)) { - u64 hpa_sectors = ata_hpa_native_size(dev); - if (hpa_sectors > new_n_sectors) - new_n_sectors = hpa_sectors; - } - if (strcmp(model[0], model[1])) { ata_dev_printk(dev, KERN_INFO, "model number mismatch " "'%s' != '%s'\n", model[0], model[1]); @@ -3568,6 +3543,11 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class, "%llu != %llu\n", (unsigned long long)dev->n_sectors, (unsigned long long)new_n_sectors); + /* Are we the boot time size - if so we appear to be the + same disk at this point and our HPA got reapplied */ + if (ata_ignore_hpa && dev->n_sectors_boot == new_n_sectors + && ata_id_hpa_enabled(new_id)) + return 1; return 0; } diff --git a/include/linux/libata.h b/include/linux/libata.h index 3869aa3..067d12f 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h @@ -470,6 +470,7 @@ struct ata_device { struct scsi_device *sdev; /* attached SCSI device */ /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */ u64 n_sectors; /* size of device, if ATA */ + u64 n_sectors_boot; /* size of ATA device at startup */ unsigned int class; /* ATA_DEV_xxx */ u16 id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */ u8 pio_mode;