Skip to content

Commit

Permalink
libata: Media rotation rate and form factor heuristics
Browse files Browse the repository at this point in the history
This patch provides new heuristics for parsing both the form factor and
media rotation rate ATA IDENFITY words.

The reported ATA version must be 7 or greater and the device must return
values defined as valid in the standard.  Only then are the
characteristics reported to SCSI via the VPD B1 page.

This seems like a reasonable compromise to me considering that we have
been shipping several kernel releases that key off the rotation rate bit
without any version checking whatsoever.  With no complaints so far.

Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
  • Loading branch information
Martin K. Petersen authored and Jeff Garzik committed May 15, 2009
1 parent 61d79a8 commit 4bca328
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 5 deletions.
11 changes: 6 additions & 5 deletions drivers/ata/libata-scsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -2142,13 +2142,14 @@ static unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf)

static unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf)
{
int form_factor = ata_id_form_factor(args->id);
int media_rotation_rate = ata_id_rotation_rate(args->id);

rbuf[1] = 0xb1;
rbuf[3] = 0x3c;
if (ata_id_major_version(args->id) > 7) {
rbuf[4] = args->id[217] >> 8;
rbuf[5] = args->id[217];
rbuf[7] = args->id[168] & 0xf;
}
rbuf[4] = media_rotation_rate >> 8;
rbuf[5] = media_rotation_rate;
rbuf[7] = form_factor;

return 0;
}
Expand Down
28 changes: 28 additions & 0 deletions include/linux/ata.h
Original file line number Diff line number Diff line change
Expand Up @@ -730,6 +730,34 @@ static inline int ata_id_has_unload(const u16 *id)
return 0;
}

static inline int ata_id_form_factor(const u16 *id)
{
u16 val = id[168];

if (ata_id_major_version(id) < 7 || val == 0 || val == 0xffff)
return 0;

val &= 0xf;

if (val > 5)
return 0;

return val;
}

static inline int ata_id_rotation_rate(const u16 *id)
{
u16 val = id[217];

if (ata_id_major_version(id) < 7 || val == 0 || val == 0xffff)
return 0;

if (val > 1 && val < 0x401)
return 0;

return val;
}

static inline int ata_id_has_trim(const u16 *id)
{
if (ata_id_major_version(id) >= 7 &&
Expand Down

0 comments on commit 4bca328

Please sign in to comment.