aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ata/libata-core.c43
-rw-r--r--drivers/ata/libata.h1
2 files changed, 44 insertions, 0 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 13dcef809e5c..3fd7c7932707 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -240,6 +240,49 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
240} 240}
241 241
242/** 242/**
243 * ata_tf_read_block - Read block address from ATA taskfile
244 * @tf: ATA taskfile of interest
245 * @dev: ATA device @tf belongs to
246 *
247 * LOCKING:
248 * None.
249 *
250 * Read block address from @tf. This function can handle all
251 * three address formats - LBA, LBA48 and CHS. tf->protocol and
252 * flags select the address format to use.
253 *
254 * RETURNS:
255 * Block address read from @tf.
256 */
257u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
258{
259 u64 block = 0;
260
261 if (tf->flags & ATA_TFLAG_LBA) {
262 if (tf->flags & ATA_TFLAG_LBA48) {
263 block |= (u64)tf->hob_lbah << 40;
264 block |= (u64)tf->hob_lbam << 32;
265 block |= tf->hob_lbal << 24;
266 } else
267 block |= (tf->device & 0xf) << 24;
268
269 block |= tf->lbah << 16;
270 block |= tf->lbam << 8;
271 block |= tf->lbal;
272 } else {
273 u32 cyl, head, sect;
274
275 cyl = tf->lbam | (tf->lbah << 8);
276 head = tf->device & 0xf;
277 sect = tf->lbal;
278
279 block = (cyl * dev->heads + head) * dev->sectors + sect;
280 }
281
282 return block;
283}
284
285/**
243 * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask 286 * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
244 * @pio_mask: pio_mask 287 * @pio_mask: pio_mask
245 * @mwdma_mask: mwdma_mask 288 * @mwdma_mask: mwdma_mask
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index be2ac39f013b..2d532da8c398 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -52,6 +52,7 @@ extern int atapi_dmadir;
52extern int libata_fua; 52extern int libata_fua;
53extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); 53extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
54extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); 54extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc);
55extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
55extern void ata_dev_disable(struct ata_device *dev); 56extern void ata_dev_disable(struct ata_device *dev);
56extern void ata_port_flush_task(struct ata_port *ap); 57extern void ata_port_flush_task(struct ata_port *ap);
57extern unsigned ata_exec_internal(struct ata_device *dev, 58extern unsigned ata_exec_internal(struct ata_device *dev,