|
@@ -1515,6 +1515,7 @@ static int ata_hpa_resize(struct ata_device *dev)
|
|
|
|
|
|
return rc;
|
|
|
}
|
|
|
+ dev->n_native_sectors = native_sectors;
|
|
|
|
|
|
/* nothing to do? */
|
|
|
if (native_sectors <= sectors || !ata_ignore_hpa) {
|
|
@@ -4099,6 +4100,7 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
|
|
|
unsigned int readid_flags)
|
|
|
{
|
|
|
u64 n_sectors = dev->n_sectors;
|
|
|
+ u64 n_native_sectors = dev->n_native_sectors;
|
|
|
int rc;
|
|
|
|
|
|
if (!ata_dev_enabled(dev))
|
|
@@ -4128,16 +4130,30 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
|
|
|
/* verify n_sectors hasn't changed */
|
|
|
if (dev->class == ATA_DEV_ATA && n_sectors &&
|
|
|
dev->n_sectors != n_sectors) {
|
|
|
- ata_dev_printk(dev, KERN_INFO, "n_sectors mismatch "
|
|
|
+ ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch "
|
|
|
"%llu != %llu\n",
|
|
|
(unsigned long long)n_sectors,
|
|
|
(unsigned long long)dev->n_sectors);
|
|
|
-
|
|
|
- /* restore original n_sectors */
|
|
|
- dev->n_sectors = n_sectors;
|
|
|
-
|
|
|
- rc = -ENODEV;
|
|
|
- goto fail;
|
|
|
+ /*
|
|
|
+ * Something could have caused HPA to be unlocked
|
|
|
+ * involuntarily. If n_native_sectors hasn't changed
|
|
|
+ * and the new size matches it, keep the device.
|
|
|
+ */
|
|
|
+ if (dev->n_native_sectors == n_native_sectors &&
|
|
|
+ dev->n_sectors > n_sectors &&
|
|
|
+ dev->n_sectors == n_native_sectors) {
|
|
|
+ ata_dev_printk(dev, KERN_WARNING,
|
|
|
+ "new n_sectors matches native, probably "
|
|
|
+ "late HPA unlock, continuing\n");
|
|
|
+ /* keep using the old n_sectors */
|
|
|
+ dev->n_sectors = n_sectors;
|
|
|
+ } else {
|
|
|
+ /* restore original n_[native]_sectors and fail */
|
|
|
+ dev->n_native_sectors = n_native_sectors;
|
|
|
+ dev->n_sectors = n_sectors;
|
|
|
+ rc = -ENODEV;
|
|
|
+ goto fail;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
return 0;
|