aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/ahci.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2007-12-05 02:43:11 -0500
committerJeff Garzik <jeff@garzik.org>2008-01-23 05:24:14 -0500
commitff2aeb1eb64c8a4770a6304f9addbae9f9828646 (patch)
treec6febbec290ec6c40bf3abc7bcdb7188f5039443 /drivers/ata/ahci.c
parentf92a26365a72333f418abe82700c6030d4a1a807 (diff)
libata: convert to chained sg
libata used private sg iterator to handle padding sg. Now that sg can be chained, padding can be handled using standard sg ops. Convert to chained sg. * s/qc->__sg/qc->sg/ * s/qc->pad_sgent/qc->extra_sg[]/. Because chaining consumes one sg entry. There need to be two extra sg entries. The renaming is also for future addition of other extra sg entries. * Padding setup is moved into ata_sg_setup_extra() which is organized in a way that future addition of other extra sg entries is easy. * qc->orig_n_elem is unused and removed. * qc->n_elem now contains the number of sg entries that LLDs should map. qc->mapped_n_elem is added to carry the original number of mapped sgs for unmapping. * The last sg of the original sg list is used to chain to extra sg list. The original last sg is pointed to by qc->last_sg and the content is stored in qc->saved_last_sg. It's restored during ata_sg_clean(). * All sg walking code has been updated. Unnecessary assertions and checks for conditions the core layer already guarantees are removed. Signed-off-by: Tejun Heo <htejun@gmail.com> Cc: Jens Axboe <jens.axboe@oracle.com> Signed-off-by: Jeff Garzik <jeff@garzik.org>
Diffstat (limited to 'drivers/ata/ahci.c')
-rw-r--r--drivers/ata/ahci.c18
1 files changed, 7 insertions, 11 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index 5eee91c73c90..cffad07c65bf 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -1483,28 +1483,24 @@ static void ahci_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
1483static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl) 1483static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl)
1484{ 1484{
1485 struct scatterlist *sg; 1485 struct scatterlist *sg;
1486 struct ahci_sg *ahci_sg; 1486 struct ahci_sg *ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ;
1487 unsigned int n_sg = 0; 1487 unsigned int si;
1488 1488
1489 VPRINTK("ENTER\n"); 1489 VPRINTK("ENTER\n");
1490 1490
1491 /* 1491 /*
1492 * Next, the S/G list. 1492 * Next, the S/G list.
1493 */ 1493 */
1494 ahci_sg = cmd_tbl + AHCI_CMD_TBL_HDR_SZ; 1494 for_each_sg(qc->sg, sg, qc->n_elem, si) {
1495 ata_for_each_sg(sg, qc) {
1496 dma_addr_t addr = sg_dma_address(sg); 1495 dma_addr_t addr = sg_dma_address(sg);
1497 u32 sg_len = sg_dma_len(sg); 1496 u32 sg_len = sg_dma_len(sg);
1498 1497
1499 ahci_sg->addr = cpu_to_le32(addr & 0xffffffff); 1498 ahci_sg[si].addr = cpu_to_le32(addr & 0xffffffff);
1500 ahci_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); 1499 ahci_sg[si].addr_hi = cpu_to_le32((addr >> 16) >> 16);
1501 ahci_sg->flags_size = cpu_to_le32(sg_len - 1); 1500 ahci_sg[si].flags_size = cpu_to_le32(sg_len - 1);
1502
1503 ahci_sg++;
1504 n_sg++;
1505 } 1501 }
1506 1502
1507 return n_sg; 1503 return si;
1508} 1504}
1509 1505
1510static void ahci_qc_prep(struct ata_queued_cmd *qc) 1506static void ahci_qc_prep(struct ata_queued_cmd *qc)