Apply various fixes for HPA handling from Tejun Heo
SCSI/libata: Disable HPA if it overlaps a partition (Closes: #572618) partitions: Rescan partition tables after HPA is disabled libata: Disable HPA if it is only enabled after suspend svn path=/dists/sid/linux-2.6/; revision=15682
This commit is contained in:
parent
6ebfd76559
commit
426e0050f9
|
@ -29,6 +29,9 @@ linux-2.6 (2.6.32-13) UNRELEASED; urgency=low
|
|||
(Closes: #580710; works-around: #581173)
|
||||
* rtl8192su: Add IDs for several more devices (Closes: #580740)
|
||||
* Add drm and sfc changes from stable 2.6.33.4
|
||||
* SCSI/libata: Disable HPA if it overlaps a partition (Closes: #572618)
|
||||
* partitions: Rescan partition tables after HPA is disabled
|
||||
* libata: Disable HPA if it is only enabled after suspend
|
||||
|
||||
[ Aurelien Jarno ]
|
||||
* mips/swarm: fix boot from IDE based media (Sebastian Andrzej Siewior)
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
From: Tejun Heo <tj@kernel.org>
|
||||
To: jeff@garzik.org, linux-ide@vger.kernel.org, jens.axboe@oracle.com, linux-scsi@vger.kernel.org, James.Bottomley@suse.de, linux-kernel@vger.kernel.org
|
||||
Cc: ben@decadent.org.uk, Tejun Heo <tj@kernel.org>
|
||||
Date: Thu, 13 May 2010 17:56:44 +0200
|
||||
Subject: [PATCH 2/4] SCSI: implement sd_set_capacity()
|
||||
|
||||
Implement sd_set_capacity() method which calls into
|
||||
hostt->set_capacity() if implemented. This will be invoked by block
|
||||
layer if partitions extend beyond the end of the device and can be
|
||||
used to implement, for example, on-demand ATA host protected area
|
||||
unlocking.
|
||||
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
Cc: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
drivers/scsi/sd.c | 26 ++++++++++++++++++++++++++
|
||||
include/scsi/scsi_host.h | 11 +++++++++++
|
||||
2 files changed, 37 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
|
||||
index 8b827f3..59d5e8f 100644
|
||||
--- a/drivers/scsi/sd.c
|
||||
+++ b/drivers/scsi/sd.c
|
||||
@@ -97,6 +97,8 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC);
|
||||
#endif
|
||||
|
||||
static int sd_revalidate_disk(struct gendisk *);
|
||||
+static unsigned long long sd_set_capacity(struct gendisk *disk,
|
||||
+ unsigned long long new_capacity);
|
||||
static int sd_probe(struct device *);
|
||||
static int sd_remove(struct device *);
|
||||
static void sd_shutdown(struct device *);
|
||||
@@ -1100,6 +1102,7 @@ static const struct block_device_operations sd_fops = {
|
||||
#endif
|
||||
.media_changed = sd_media_changed,
|
||||
.revalidate_disk = sd_revalidate_disk,
|
||||
+ .set_capacity = sd_set_capacity,
|
||||
};
|
||||
|
||||
static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
|
||||
@@ -2101,6 +2104,29 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
||||
}
|
||||
|
||||
/**
|
||||
+ * sd_set_capacity - set disk capacity
|
||||
+ * @disk: struct gendisk to set capacity for
|
||||
+ * @new_capacity: new target capacity
|
||||
+ *
|
||||
+ * Block layer calls this function if it detects that partitions
|
||||
+ * on @disk reach beyond the end of the device. If the SCSI host
|
||||
+ * implements set_capacity method, it's invoked to give it a
|
||||
+ * chance to adjust the device capacity.
|
||||
+ *
|
||||
+ * CONTEXT:
|
||||
+ * Defined by block layer. Might sleep.
|
||||
+ */
|
||||
+static unsigned long long sd_set_capacity(struct gendisk *disk,
|
||||
+ unsigned long long new_capacity)
|
||||
+{
|
||||
+ struct scsi_device *sdev = scsi_disk(disk)->device;
|
||||
+
|
||||
+ if (sdev->host->hostt->set_capacity)
|
||||
+ return sdev->host->hostt->set_capacity(sdev, new_capacity);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* sd_format_disk_name - format disk name
|
||||
* @prefix: name prefix - ie. "sd" for SCSI disks
|
||||
* @index: index of the disk to format name for
|
||||
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
|
||||
index c50a97f..31dba89 100644
|
||||
--- a/include/scsi/scsi_host.h
|
||||
+++ b/include/scsi/scsi_host.h
|
||||
@@ -327,6 +327,17 @@ struct scsi_host_template {
|
||||
sector_t, int []);
|
||||
|
||||
/*
|
||||
+ * This function is called when one or more partitions on the
|
||||
+ * device reach beyond the end of the device. This function
|
||||
+ * should return the new capacity if disk was successfully
|
||||
+ * enlarged. Return values smaller than the current capacity
|
||||
+ * are ignored.
|
||||
+ *
|
||||
+ * Status: OPTIONAL
|
||||
+ */
|
||||
+ sector_t (*set_capacity)(struct scsi_device *, sector_t);
|
||||
+
|
||||
+ /*
|
||||
* Can be used to export driver statistics and other infos to the
|
||||
* world outside the kernel ie. userspace and it also provides an
|
||||
* interface to feed the driver with information.
|
||||
--
|
||||
1.6.4.2
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
From: Tejun Heo <tj@kernel.org>
|
||||
To: jeff@garzik.org, linux-ide@vger.kernel.org, jens.axboe@oracle.com, linux-scsi@vger.kernel.org, James.Bottomley@suse.de, linux-kernel@vger.kernel.org
|
||||
Cc: ben@decadent.org.uk, Tejun Heo <tj@kernel.org>
|
||||
Date: Thu, 13 May 2010 17:56:43 +0200
|
||||
Subject: [PATCH 1/4] block: restart partition scan after resizing a device
|
||||
|
||||
Device resize via ->set_capacity() can reveal new partitions (e.g. in
|
||||
chained partition table formats such as dos extended parts). Restart
|
||||
partition scan from the beginning after resizing a device.
|
||||
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
Reported-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
fs/partitions/check.c | 7 ++++---
|
||||
1 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
|
||||
index e238ab2..f80a58d 100644
|
||||
--- a/fs/partitions/check.c
|
||||
+++ b/fs/partitions/check.c
|
||||
@@ -550,7 +550,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
|
||||
res = invalidate_partition(disk, 0);
|
||||
if (res)
|
||||
return res;
|
||||
-
|
||||
+rescan:
|
||||
disk_part_iter_init(&piter, disk, DISK_PITER_INCL_EMPTY);
|
||||
while ((part = disk_part_iter_next(&piter)))
|
||||
delete_partition(disk, part->partno);
|
||||
@@ -581,7 +581,7 @@ int rescan_partitions(struct gendisk *disk, struct block_device *bdev)
|
||||
/* add partitions */
|
||||
for (p = 1; p < state->limit; p++) {
|
||||
sector_t size, from;
|
||||
-try_scan:
|
||||
+
|
||||
size = state->parts[p].size;
|
||||
if (!size)
|
||||
continue;
|
||||
@@ -612,7 +612,8 @@ try_scan:
|
||||
check_disk_size_change(disk, bdev);
|
||||
bdev->bd_invalidated = 0;
|
||||
}
|
||||
- goto try_scan;
|
||||
+ kfree(state);
|
||||
+ goto rescan;
|
||||
} else {
|
||||
/*
|
||||
* we can not ignore partitions of broken tables
|
||||
--
|
||||
1.6.4.2
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
From: Tejun Heo <tj@kernel.org>
|
||||
To: jeff@garzik.org, linux-ide@vger.kernel.org, jens.axboe@oracle.com, linux-scsi@vger.kernel.org, James.Bottomley@suse.de, linux-kernel@vger.kernel.org
|
||||
Cc: ben@decadent.org.uk, Tejun Heo <tj@kernel.org>
|
||||
Date: Thu, 13 May 2010 17:56:46 +0200
|
||||
Subject: [PATCH 4/4] libata: implement on-demand HPA unlocking
|
||||
|
||||
Implement ata_scsi_set_capacity() which will be called through SCSI
|
||||
layer when block layer notices that partitions on a device extend
|
||||
beyond the end of the device. ata_scsi_set_capacity() requests EH to
|
||||
unlock HPA, waits for completion and returns the current device
|
||||
capacity.
|
||||
|
||||
This allows libata to unlock HPA on demand instead of having to decide
|
||||
whether to unlock upfront. Unlocking on demand is safer than
|
||||
unlocking by upfront because some BIOSes write private data to the
|
||||
area beyond HPA limit. This was suggested by Ben Hutchings.
|
||||
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
Suggested-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
drivers/ata/libata-core.c | 1 +
|
||||
drivers/ata/libata-scsi.c | 42 ++++++++++++++++++++++++++++++++++++++++++
|
||||
include/linux/libata.h | 3 +++
|
||||
3 files changed, 46 insertions(+), 0 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
|
||||
index 9d6e92d..56badb4 100644
|
||||
--- a/drivers/ata/libata-core.c
|
||||
+++ b/drivers/ata/libata-core.c
|
||||
@@ -6797,6 +6797,7 @@ EXPORT_SYMBOL_GPL(ata_dummy_port_info);
|
||||
EXPORT_SYMBOL_GPL(ata_link_next);
|
||||
EXPORT_SYMBOL_GPL(ata_dev_next);
|
||||
EXPORT_SYMBOL_GPL(ata_std_bios_param);
|
||||
+EXPORT_SYMBOL_GPL(ata_scsi_set_capacity);
|
||||
EXPORT_SYMBOL_GPL(ata_host_init);
|
||||
EXPORT_SYMBOL_GPL(ata_host_alloc);
|
||||
EXPORT_SYMBOL_GPL(ata_host_alloc_pinfo);
|
||||
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
|
||||
index 0088cde..2523943 100644
|
||||
--- a/drivers/ata/libata-scsi.c
|
||||
+++ b/drivers/ata/libata-scsi.c
|
||||
@@ -415,6 +415,48 @@ int ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev,
|
||||
}
|
||||
|
||||
/**
|
||||
+ * ata_scsi_set_capacity - adjust device capacity
|
||||
+ * @sdev: SCSI device to adjust device capacity for
|
||||
+ * @new_capacity: new target capacity
|
||||
+ *
|
||||
+ * This function is called if a partition on @sdev extends beyond
|
||||
+ * the end of the device. It requests EH to unlock HPA and
|
||||
+ * returns the possibly adjusted capacity.
|
||||
+ *
|
||||
+ * LOCKING:
|
||||
+ * Defined by the SCSI layer. Might sleep.
|
||||
+ *
|
||||
+ * RETURNS:
|
||||
+ * New capacity if adjusted successfully. 0 if device is not
|
||||
+ * found.
|
||||
+ */
|
||||
+sector_t ata_scsi_set_capacity(struct scsi_device *sdev, sector_t new_capacity)
|
||||
+{
|
||||
+ struct ata_port *ap = ata_shost_to_port(sdev->host);
|
||||
+ sector_t capacity = 0;
|
||||
+ struct ata_device *dev;
|
||||
+ unsigned long flags;
|
||||
+
|
||||
+ spin_lock_irqsave(ap->lock, flags);
|
||||
+
|
||||
+ dev = ata_scsi_find_dev(ap, sdev);
|
||||
+ if (dev && dev->n_sectors < new_capacity &&
|
||||
+ dev->n_sectors < dev->n_native_sectors) {
|
||||
+ struct ata_eh_info *ehi = &dev->link->eh_info;
|
||||
+
|
||||
+ dev->flags |= ATA_DFLAG_UNLOCK_HPA;
|
||||
+ ehi->action |= ATA_EH_RESET;
|
||||
+ ata_port_schedule_eh(ap);
|
||||
+ spin_unlock_irqrestore(ap->lock, flags);
|
||||
+ ata_port_wait_eh(ap);
|
||||
+ capacity = dev->n_sectors;
|
||||
+ } else
|
||||
+ spin_unlock_irqrestore(ap->lock, flags);
|
||||
+
|
||||
+ return capacity;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
* ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl
|
||||
* @ap: target port
|
||||
* @sdev: SCSI device to get identify data for
|
||||
diff --git a/include/linux/libata.h b/include/linux/libata.h
|
||||
index 242eb26..1082956 100644
|
||||
--- a/include/linux/libata.h
|
||||
+++ b/include/linux/libata.h
|
||||
@@ -1027,6 +1027,8 @@ extern void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd,
|
||||
extern int ata_std_bios_param(struct scsi_device *sdev,
|
||||
struct block_device *bdev,
|
||||
sector_t capacity, int geom[]);
|
||||
+extern sector_t ata_scsi_set_capacity(struct scsi_device *sdev,
|
||||
+ sector_t new_capacity);
|
||||
extern int ata_scsi_slave_config(struct scsi_device *sdev);
|
||||
extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
|
||||
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
|
||||
@@ -1181,6 +1183,7 @@ extern struct device_attribute *ata_common_sdev_attrs[];
|
||||
.slave_configure = ata_scsi_slave_config, \
|
||||
.slave_destroy = ata_scsi_slave_destroy, \
|
||||
.bios_param = ata_std_bios_param, \
|
||||
+ .set_capacity = ata_scsi_set_capacity, \
|
||||
.sdev_attrs = ata_common_sdev_attrs
|
||||
|
||||
#define ATA_NCQ_SHT(drv_name) \
|
||||
--
|
||||
1.6.4.2
|
||||
|
|
@ -0,0 +1,151 @@
|
|||
From 445d211b0da4e9a6e6d576edff85085c2aaf53df Mon Sep 17 00:00:00 2001
|
||||
From: Tejun Heo <tj@kernel.org>
|
||||
Date: Mon, 5 Apr 2010 10:33:13 +0900
|
||||
Subject: [PATCH] libata: unlock HPA if device shrunk
|
||||
|
||||
Some BIOSes don't configure HPA during boot but do so while resuming.
|
||||
This causes harddrives to shrink during resume making libata detach
|
||||
and reattach them. This can be worked around by unlocking HPA if old
|
||||
size equals native size.
|
||||
|
||||
Add ATA_DFLAG_UNLOCK_HPA so that HPA unlocking can be controlled
|
||||
per-device and update ata_dev_revalidate() such that it sets
|
||||
ATA_DFLAG_UNLOCK_HPA and fails with -EIO when the above condition is
|
||||
detected.
|
||||
|
||||
This patch fixes the following bug.
|
||||
|
||||
https://bugzilla.kernel.org/show_bug.cgi?id=15396
|
||||
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
Reported-by: Oleksandr Yermolenko <yaa.bta@gmail.com>
|
||||
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
|
||||
---
|
||||
drivers/ata/libata-core.c | 74 +++++++++++++++++++++++++++-----------------
|
||||
include/linux/libata.h | 1 +
|
||||
2 files changed, 46 insertions(+), 29 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
|
||||
index 2ab34dc..49cffb6 100644
|
||||
--- a/drivers/ata/libata-core.c
|
||||
+++ b/drivers/ata/libata-core.c
|
||||
@@ -1494,6 +1494,7 @@ static int ata_hpa_resize(struct ata_device *dev)
|
||||
{
|
||||
struct ata_eh_context *ehc = &dev->link->eh_context;
|
||||
int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
|
||||
+ bool unlock_hpa = ata_ignore_hpa || dev->flags & ATA_DFLAG_UNLOCK_HPA;
|
||||
u64 sectors = ata_id_n_sectors(dev->id);
|
||||
u64 native_sectors;
|
||||
int rc;
|
||||
@@ -1510,7 +1511,7 @@ static int ata_hpa_resize(struct ata_device *dev)
|
||||
/* If device aborted the command or HPA isn't going to
|
||||
* be unlocked, skip HPA resizing.
|
||||
*/
|
||||
- if (rc == -EACCES || !ata_ignore_hpa) {
|
||||
+ if (rc == -EACCES || !unlock_hpa) {
|
||||
ata_dev_printk(dev, KERN_WARNING, "HPA support seems "
|
||||
"broken, skipping HPA handling\n");
|
||||
dev->horkage |= ATA_HORKAGE_BROKEN_HPA;
|
||||
@@ -1525,7 +1526,7 @@ static int ata_hpa_resize(struct ata_device *dev)
|
||||
dev->n_native_sectors = native_sectors;
|
||||
|
||||
/* nothing to do? */
|
||||
- if (native_sectors <= sectors || !ata_ignore_hpa) {
|
||||
+ if (native_sectors <= sectors || !unlock_hpa) {
|
||||
if (!print_info || native_sectors == sectors)
|
||||
return 0;
|
||||
|
||||
@@ -4186,36 +4187,51 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
|
||||
goto fail;
|
||||
|
||||
/* verify n_sectors hasn't changed */
|
||||
- if (dev->class == ATA_DEV_ATA && n_sectors &&
|
||||
- dev->n_sectors != n_sectors) {
|
||||
- ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch "
|
||||
- "%llu != %llu\n",
|
||||
- (unsigned long long)n_sectors,
|
||||
- (unsigned long long)dev->n_sectors);
|
||||
- /*
|
||||
- * 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;
|
||||
- }
|
||||
+ if (dev->class != ATA_DEV_ATA || !n_sectors ||
|
||||
+ dev->n_sectors == n_sectors)
|
||||
+ return 0;
|
||||
+
|
||||
+ /* n_sectors has changed */
|
||||
+ ata_dev_printk(dev, KERN_WARNING, "n_sectors mismatch %llu != %llu\n",
|
||||
+ (unsigned long long)n_sectors,
|
||||
+ (unsigned long long)dev->n_sectors);
|
||||
+
|
||||
+ /*
|
||||
+ * 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;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
- return 0;
|
||||
+ /*
|
||||
+ * Some BIOSes boot w/o HPA but resume w/ HPA locked. Try
|
||||
+ * unlocking HPA in those cases.
|
||||
+ *
|
||||
+ * https://bugzilla.kernel.org/show_bug.cgi?id=15396
|
||||
+ */
|
||||
+ if (dev->n_native_sectors == n_native_sectors &&
|
||||
+ dev->n_sectors < n_sectors && n_sectors == n_native_sectors &&
|
||||
+ !(dev->horkage & ATA_HORKAGE_BROKEN_HPA)) {
|
||||
+ ata_dev_printk(dev, KERN_WARNING,
|
||||
+ "old n_sectors matches native, probably "
|
||||
+ "late HPA lock, will try to unlock HPA\n");
|
||||
+ /* try unlocking HPA */
|
||||
+ dev->flags |= ATA_DFLAG_UNLOCK_HPA;
|
||||
+ rc = -EIO;
|
||||
+ } else
|
||||
+ rc = -ENODEV;
|
||||
|
||||
+ /* restore original n_[native_]sectors and fail */
|
||||
+ dev->n_native_sectors = n_native_sectors;
|
||||
+ dev->n_sectors = n_sectors;
|
||||
fail:
|
||||
ata_dev_printk(dev, KERN_ERR, "revalidation failed (errno=%d)\n", rc);
|
||||
return rc;
|
||||
diff --git a/include/linux/libata.h b/include/linux/libata.h
|
||||
index f8ea71e..b2f2003 100644
|
||||
--- a/include/linux/libata.h
|
||||
+++ b/include/linux/libata.h
|
||||
@@ -146,6 +146,7 @@ enum {
|
||||
ATA_DFLAG_SLEEPING = (1 << 15), /* device is sleeping */
|
||||
ATA_DFLAG_DUBIOUS_XFER = (1 << 16), /* data transfer not verified */
|
||||
ATA_DFLAG_NO_UNLOAD = (1 << 17), /* device doesn't support unload */
|
||||
+ ATA_DFLAG_UNLOCK_HPA = (1 << 18), /* unlock HPA */
|
||||
ATA_DFLAG_INIT_MASK = (1 << 24) - 1,
|
||||
|
||||
ATA_DFLAG_DETACH = (1 << 24),
|
||||
--
|
||||
1.7.1
|
||||
|
36
debian/patches/bugfix/all/libata-use-enlarged-capacity-after-late-HPA-unlock.patch
vendored
Normal file
36
debian/patches/bugfix/all/libata-use-enlarged-capacity-after-late-HPA-unlock.patch
vendored
Normal file
|
@ -0,0 +1,36 @@
|
|||
From: Tejun Heo <tj@kernel.org>
|
||||
To: jeff@garzik.org, linux-ide@vger.kernel.org, jens.axboe@oracle.com, linux-scsi@vger.kernel.org, James.Bottomley@suse.de, linux-kernel@vger.kernel.org
|
||||
Cc: ben@decadent.org.uk, Tejun Heo <tj@kernel.org>
|
||||
Date: Thu, 13 May 2010 17:56:45 +0200
|
||||
Subject: [PATCH 3/4] libata: use the enlarged capacity after late HPA unlock
|
||||
|
||||
After late HPA unlock, libata kept using the original capacity
|
||||
ignoring the new larger native capacity. Enlarging device on the fly
|
||||
doesn't cause any harm. Use the larger native capacity instead. This
|
||||
will enable on-demand HPA unlocking.
|
||||
|
||||
Signed-off-by: Tejun Heo <tj@kernel.org>
|
||||
Cc: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
drivers/ata/libata-core.c | 5 ++---
|
||||
1 files changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
|
||||
index 86f405b..9d6e92d 100644
|
||||
--- a/drivers/ata/libata-core.c
|
||||
+++ b/drivers/ata/libata-core.c
|
||||
@@ -4212,9 +4212,8 @@ int ata_dev_revalidate(struct ata_device *dev, unsigned int new_class,
|
||||
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;
|
||||
+ "late HPA unlock, n_sectors updated\n");
|
||||
+ /* use the larger n_sectors */
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
1.6.4.2
|
||||
|
|
@ -23,3 +23,9 @@
|
|||
+ bugfix/all/stable/2.6.33.4.patch
|
||||
+ bugfix/all/drm-i915-Stop-trying-to-use-ACPI-lid-status-to-deter-2.patch
|
||||
+ features/arm/guruplug.patch
|
||||
+ bugfix/all/block-restart-partition-scan-after-resizing.patch
|
||||
- debian/sd-libata-set-capacity-abi-changes.patch
|
||||
+ bugfix/all/SCSI-implement-sd_set_capacity.patch
|
||||
+ bugfix/all/libata-unlock-HPA-if-device-shrunk.patch
|
||||
+ bugfix/all/libata-use-enlarged-capacity-after-late-HPA-unlock.patch
|
||||
+ bugfix/all/libata-implement-on-demand-HPA-unlocking.patch
|
||||
|
|
Loading…
Reference in New Issue