diff options
| -rw-r--r-- | drivers/ata/libata-core.c | 30 | ||||
| -rw-r--r-- | include/linux/libata.h | 1 |
2 files changed, 24 insertions, 7 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 2c6aedaef718..8ac98ff16d7d 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
| @@ -1515,6 +1515,7 @@ static int ata_hpa_resize(struct ata_device *dev) | |||
| 1515 | 1515 | ||
| 1516 | return rc; | 1516 | return rc; |
| 1517 | } | 1517 | } |
| 1518 | dev->n_native_sectors = native_sectors; | ||
| 1518 | 1519 | ||
| 1519 | /* nothing to do? */ | 1520 | /* nothing to do? */ |
| 1520 | if (native_sectors <= sectors || !ata_ignore_hpa) { | 1521 | if (native_sectors <= sectors || !ata_ignore_hpa) { |
| @@ -4099,6 +4100,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | |||
| 4099 | unsigned int readid_flags) | 4100 | unsigned int readid_flags) |
| 4100 | { | 4101 | { |
| 4101 | u64 n_sectors = dev->n_sectors; | 4102 | u64 n_sectors = dev->n_sectors; |
| 4103 | u64 n_native_sectors = dev->n_native_sectors; | ||
| 4102 | int rc; | 4104 | int rc; |
| 4103 | 4105 | ||
| 4104 | if (!ata_dev_enabled(dev)) | 4106 | if (!ata_dev_enabled(dev)) |
| @@ -4128,16 +4130,30 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class, | |||
| 4128 | /* verify n_sectors hasn't changed */ | 4130 | /* verify n_sectors hasn't changed */ |
| 4129 | if (dev->class == ATA_DEV_ATA && n_sectors && | 4131 | if (dev->class == ATA_DEV_ATA && n_sectors && |
| 4130 | dev->n_sectors != n_sectors) { | 4132 | dev->n_sectors != n_sectors) { |
| 4131 | ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch " | 4133 | ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch " |
| 4132 | "%llu != %llu\n", | 4134 | "%llu != %llu\n", |
| 4133 | (unsigned long long)n_sectors, | 4135 | (unsigned long long)n_sectors, |
| 4134 | (unsigned long long)dev->n_sectors); | 4136 | (unsigned long long)dev->n_sectors); |
| 4135 | 4137 | /* | |
| 4136 | /* restore original n_sectors */ | 4138 | * Something could have caused HPA to be unlocked |
| 4137 | dev->n_sectors = n_sectors; | 4139 | * involuntarily. If n_native_sectors hasn't changed |
| 4138 | 4140 | * and the new size matches it, keep the device. | |
| 4139 | rc = -ENODEV; | 4141 | */ |
| 4140 | goto fail; | 4142 | if (dev->n_native_sectors == n_native_sectors && |
| 4143 | dev->n_sectors > n_sectors && | ||
| 4144 | dev->n_sectors == n_native_sectors) { | ||
| 4145 | ata_dev_printk(dev, KERN_WARNING, | ||
| 4146 | "new n_sectors matches native, probably " | ||
| 4147 | "late HPA unlock, continuing\n"); | ||
| 4148 | /* keep using the old n_sectors */ | ||
| 4149 | dev->n_sectors = n_sectors; | ||
| 4150 | } else { | ||
| 4151 | /* restore original n_[native]_sectors and fail */ | ||
| 4152 | dev->n_native_sectors = n_native_sectors; | ||
| 4153 | dev->n_sectors = n_sectors; | ||
| 4154 | rc = -ENODEV; | ||
| 4155 | goto fail; | ||
| 4156 | } | ||
| 4141 | } | 4157 | } |
| 4142 | 4158 | ||
| 4143 | return 0; | 4159 | return 0; |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 79b6d7fd4ac2..e5b6e33c6571 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -589,6 +589,7 @@ struct ata_device { | |||
| 589 | #endif | 589 | #endif |
| 590 | /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */ | 590 | /* n_sector is CLEAR_BEGIN, read comment above CLEAR_BEGIN */ |
| 591 | u64 n_sectors; /* size of device, if ATA */ | 591 | u64 n_sectors; /* size of device, if ATA */ |
| 592 | u64 n_native_sectors; /* native size, if ATA */ | ||
| 592 | unsigned int class; /* ATA_DEV_xxx */ | 593 | unsigned int class; /* ATA_DEV_xxx */ |
| 593 | unsigned long unpark_deadline; | 594 | unsigned long unpark_deadline; |
| 594 | 595 | ||
