diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/ata/sata_mv.c | 26 |
1 files changed, 19 insertions, 7 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 11bf6c7ac122..1a82e22b3efd 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -1139,15 +1139,27 @@ static unsigned int mv_fill_sg(struct ata_queued_cmd *qc) | |||
1139 | dma_addr_t addr = sg_dma_address(sg); | 1139 | dma_addr_t addr = sg_dma_address(sg); |
1140 | u32 sg_len = sg_dma_len(sg); | 1140 | u32 sg_len = sg_dma_len(sg); |
1141 | 1141 | ||
1142 | mv_sg->addr = cpu_to_le32(addr & 0xffffffff); | 1142 | while (sg_len) { |
1143 | mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); | 1143 | u32 offset = addr & 0xffff; |
1144 | mv_sg->flags_size = cpu_to_le32(sg_len & 0xffff); | 1144 | u32 len = sg_len; |
1145 | 1145 | ||
1146 | if (ata_sg_is_last(sg, qc)) | 1146 | if ((offset + sg_len > 0x10000)) |
1147 | mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); | 1147 | len = 0x10000 - offset; |
1148 | |||
1149 | mv_sg->addr = cpu_to_le32(addr & 0xffffffff); | ||
1150 | mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); | ||
1151 | mv_sg->flags_size = cpu_to_le32(len); | ||
1152 | |||
1153 | sg_len -= len; | ||
1154 | addr += len; | ||
1155 | |||
1156 | if (!sg_len && ata_sg_is_last(sg, qc)) | ||
1157 | mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); | ||
1158 | |||
1159 | mv_sg++; | ||
1160 | n_sg++; | ||
1161 | } | ||
1148 | 1162 | ||
1149 | mv_sg++; | ||
1150 | n_sg++; | ||
1151 | } | 1163 | } |
1152 | 1164 | ||
1153 | return n_sg; | 1165 | return n_sg; |