Skip to content

Commit e18086d

Browse files
Mark LordJeff Garzik
authored andcommitted
[libata] More robust parsing for IDENTIFY DEVICE multi_count field
Make libata more robust when parsing the multi_count field from a drive's identify data. This prevents us from attempting to use dubious multi_count values ad infinitum. Reset dev->multi_count to zero and reprobe it each time through this routine, as it can change on device reset. Also ensure that the reported "maximum" value is valid and is a power of two, and that the reported "count" value is valid and also a power of two. And that the "count" value is not greater than the "maximum" value. Signed-off-by: Mark Lord <mlord@pobox.com> Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
1 parent 000b344 commit e18086d

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

drivers/ata/libata-core.c

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include <linux/scatterlist.h>
5858
#include <linux/io.h>
5959
#include <linux/async.h>
60+
#include <linux/log2.h>
6061
#include <scsi/scsi.h>
6162
#include <scsi/scsi_cmnd.h>
6263
#include <scsi/scsi_host.h>
@@ -2389,6 +2390,7 @@ int ata_dev_configure(struct ata_device *dev)
23892390
dev->cylinders = 0;
23902391
dev->heads = 0;
23912392
dev->sectors = 0;
2393+
dev->multi_count = 0;
23922394

23932395
/*
23942396
* common ATA, ATAPI feature tests
@@ -2426,8 +2428,15 @@ int ata_dev_configure(struct ata_device *dev)
24262428

24272429
dev->n_sectors = ata_id_n_sectors(id);
24282430

2429-
if (dev->id[59] & 0x100)
2430-
dev->multi_count = dev->id[59] & 0xff;
2431+
/* get current R/W Multiple count setting */
2432+
if ((dev->id[47] >> 8) == 0x80 && (dev->id[59] & 0x100)) {
2433+
unsigned int max = dev->id[47] & 0xff;
2434+
unsigned int cnt = dev->id[59] & 0xff;
2435+
/* only recognize/allow powers of two here */
2436+
if (is_power_of_2(max) && is_power_of_2(cnt))
2437+
if (cnt <= max)
2438+
dev->multi_count = cnt;
2439+
}
24312440

24322441
if (ata_id_has_lba(id)) {
24332442
const char *lba_desc;

0 commit comments

Comments
 (0)