Commit 35b649fe authored by Tejun Heo's avatar Tejun Heo Committed by Jeff Garzik

[PATCH] libata: implement ata_tf_read_block()

Implement ata_tf_read_block().
Signed-off-by: default avatarTejun Heo <htejun@gmail.com>
Signed-off-by: default avatarJeff Garzik <jeff@garzik.org>
parent 750426aa
...@@ -239,6 +239,49 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc) ...@@ -239,6 +239,49 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
return -1; return -1;
} }
/**
* ata_tf_read_block - Read block address from ATA taskfile
* @tf: ATA taskfile of interest
* @dev: ATA device @tf belongs to
*
* LOCKING:
* None.
*
* Read block address from @tf. This function can handle all
* three address formats - LBA, LBA48 and CHS. tf->protocol and
* flags select the address format to use.
*
* RETURNS:
* Block address read from @tf.
*/
u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
{
u64 block = 0;
if (tf->flags & ATA_TFLAG_LBA) {
if (tf->flags & ATA_TFLAG_LBA48) {
block |= (u64)tf->hob_lbah << 40;
block |= (u64)tf->hob_lbam << 32;
block |= tf->hob_lbal << 24;
} else
block |= (tf->device & 0xf) << 24;
block |= tf->lbah << 16;
block |= tf->lbam << 8;
block |= tf->lbal;
} else {
u32 cyl, head, sect;
cyl = tf->lbam | (tf->lbah << 8);
head = tf->device & 0xf;
sect = tf->lbal;
block = (cyl * dev->heads + head) * dev->sectors + sect;
}
return block;
}
/** /**
* ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
* @pio_mask: pio_mask * @pio_mask: pio_mask
......
...@@ -52,6 +52,7 @@ extern int atapi_dmadir; ...@@ -52,6 +52,7 @@ extern int atapi_dmadir;
extern int libata_fua; extern int libata_fua;
extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
extern void ata_dev_disable(struct ata_device *dev); extern void ata_dev_disable(struct ata_device *dev);
extern void ata_port_flush_task(struct ata_port *ap); extern void ata_port_flush_task(struct ata_port *ap);
extern unsigned ata_exec_internal(struct ata_device *dev, extern unsigned ata_exec_internal(struct ata_device *dev,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment