Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 68100
b: refs/heads/master
c: c728a91
h: refs/heads/master
v: v3
  • Loading branch information
Tejun Heo authored and Jeff Garzik committed Oct 12, 2007
1 parent 0128116 commit 154e2b5
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 98 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: db6f8759d05d2082f09a45b5674edc0fb5e92b1b
refs/heads/master: c728a9149f519cbb9f610962873f4e22ed4a6efd
174 changes: 77 additions & 97 deletions trunk/drivers/ata/libata-core.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,129 +863,113 @@ static u64 ata_tf_to_lba(struct ata_taskfile *tf)
}

/**
* ata_read_native_max_address_ext - LBA48 native max query
* @dev: Device to query
* ata_read_native_max_address - Read native max address
* @dev: target device
* @max_sectors: out parameter for the result native max address
*
* Perform an LBA48 size query upon the device in question. Return the
* actual LBA48 size or zero if the command fails.
*/

static u64 ata_read_native_max_address_ext(struct ata_device *dev)
{
unsigned int err;
struct ata_taskfile tf;

ata_tf_init(dev, &tf);

tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
tf.protocol |= ATA_PROT_NODATA;
tf.device |= 0x40;

err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err)
return 0;

return ata_tf_to_lba48(&tf);
}

/**
* ata_read_native_max_address - LBA28 native max query
* @dev: Device to query
* Perform an LBA48 or LBA28 native size query upon the device in
* question.
*
* Performa an LBA28 size query upon the device in question. Return the
* actual LBA28 size or zero if the command fails.
* RETURNS:
* 0 on success, -EACCES if command is aborted by the drive.
* -EIO on other errors.
*/

static u64 ata_read_native_max_address(struct ata_device *dev)
static int ata_read_native_max_address(struct ata_device *dev, u64 *max_sectors)
{
unsigned int err;
unsigned int err_mask;
struct ata_taskfile tf;
int lba48 = ata_id_has_lba48(dev->id);

ata_tf_init(dev, &tf);

tf.command = ATA_CMD_READ_NATIVE_MAX;
/* always clear all address registers */
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;
tf.protocol |= ATA_PROT_NODATA;
tf.device |= 0x40;

err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err)
return 0;

return ata_tf_to_lba(&tf);
}

/**
* ata_set_native_max_address_ext - LBA48 native max set
* @dev: Device to query
* @new_sectors: new max sectors value to set for the device
*
* Perform an LBA48 size set max upon the device in question. Return the
* actual LBA48 size or zero if the command fails.
*/

static u64 ata_set_native_max_address_ext(struct ata_device *dev, u64 new_sectors)
{
unsigned int err;
struct ata_taskfile tf;

new_sectors--;

ata_tf_init(dev, &tf);
if (lba48) {
tf.command = ATA_CMD_READ_NATIVE_MAX_EXT;
tf.flags |= ATA_TFLAG_LBA48;
} else
tf.command = ATA_CMD_READ_NATIVE_MAX;

tf.command = ATA_CMD_SET_MAX_EXT;
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | ATA_TFLAG_ISADDR;
tf.protocol |= ATA_PROT_NODATA;
tf.device |= 0x40;

tf.lbal = (new_sectors >> 0) & 0xff;
tf.lbam = (new_sectors >> 8) & 0xff;
tf.lbah = (new_sectors >> 16) & 0xff;
tf.device |= ATA_LBA;

tf.hob_lbal = (new_sectors >> 24) & 0xff;
tf.hob_lbam = (new_sectors >> 32) & 0xff;
tf.hob_lbah = (new_sectors >> 40) & 0xff;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err_mask) {
ata_dev_printk(dev, KERN_WARNING, "failed to read native "
"max address (err_mask=0x%x)\n", err_mask);
if (err_mask == AC_ERR_DEV && (tf.feature & ATA_ABORTED))
return -EACCES;
return -EIO;
}

err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err)
return 0;
if (lba48)
*max_sectors = ata_tf_to_lba48(&tf);
else
*max_sectors = ata_tf_to_lba(&tf);

return ata_tf_to_lba48(&tf);
return 0;
}

/**
* ata_set_native_max_address - LBA28 native max set
* @dev: Device to query
* ata_set_max_sectors - Set max sectors
* @dev: target device
* @new_sectors: new max sectors value to set for the device
* @res_sectors: result max sectors
*
* Perform an LBA28 size set max upon the device in question. Return the
* actual LBA28 size or zero if the command fails.
* Set max sectors of @dev to @new_sectors.
*
* RETURNS:
* 0 on success, -EACCES if command is aborted or denied (due to
* previous non-volatile SET_MAX) by the drive. -EIO on other
* errors.
*/

static u64 ata_set_native_max_address(struct ata_device *dev, u64 new_sectors)
static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors,
u64 *res_sectors)
{
unsigned int err;
unsigned int err_mask;
struct ata_taskfile tf;
int lba48 = ata_id_has_lba48(dev->id);

new_sectors--;

ata_tf_init(dev, &tf);

tf.command = ATA_CMD_SET_MAX;
tf.flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR;

if (lba48) {
tf.command = ATA_CMD_SET_MAX_EXT;
tf.flags |= ATA_TFLAG_LBA48;

tf.hob_lbal = (new_sectors >> 24) & 0xff;
tf.hob_lbam = (new_sectors >> 32) & 0xff;
tf.hob_lbah = (new_sectors >> 40) & 0xff;
} else
tf.command = ATA_CMD_SET_MAX;

tf.protocol |= ATA_PROT_NODATA;
tf.device |= ATA_LBA;

tf.lbal = (new_sectors >> 0) & 0xff;
tf.lbam = (new_sectors >> 8) & 0xff;
tf.lbah = (new_sectors >> 16) & 0xff;
tf.device |= ((new_sectors >> 24) & 0x0f) | 0x40;

err = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err)
return 0;
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0);
if (err_mask) {
ata_dev_printk(dev, KERN_WARNING, "failed to set "
"max address (err_mask=0x%x)\n", err_mask);
if (err_mask == AC_ERR_DEV &&
(tf.feature & (ATA_ABORTED | ATA_IDNF)))
return -EACCES;
return -EIO;
}

return ata_tf_to_lba(&tf);
if (lba48)
*res_sectors = ata_tf_to_lba48(&tf);
else
*res_sectors = ata_tf_to_lba(&tf);

return 0;
}

/**
Expand All @@ -1001,11 +985,11 @@ static u64 ata_hpa_resize(struct ata_device *dev)
{
u64 sectors = dev->n_sectors;
u64 hpa_sectors;
int rc;

if (ata_id_has_lba48(dev->id))
hpa_sectors = ata_read_native_max_address_ext(dev);
else
hpa_sectors = ata_read_native_max_address(dev);
rc = ata_read_native_max_address(dev, &hpa_sectors);
if (rc)
return 0;

if (hpa_sectors > sectors) {
ata_dev_printk(dev, KERN_INFO,
Expand All @@ -1015,13 +999,9 @@ static u64 ata_hpa_resize(struct ata_device *dev)
(long long)sectors, (long long)hpa_sectors);

if (ata_ignore_hpa) {
if (ata_id_has_lba48(dev->id))
hpa_sectors = ata_set_native_max_address_ext(dev, hpa_sectors);
else
hpa_sectors = ata_set_native_max_address(dev,
hpa_sectors);
rc = ata_set_max_sectors(dev, hpa_sectors, &hpa_sectors);

if (hpa_sectors) {
if (rc == 0) {
ata_dev_printk(dev, KERN_INFO, "native size "
"increased to %lld sectors\n",
(long long)hpa_sectors);
Expand Down

0 comments on commit 154e2b5

Please sign in to comment.