diff options
Diffstat (limited to 'drivers/ata/sata_mv.c')
-rw-r--r-- | drivers/ata/sata_mv.c | 37 |
1 files changed, 26 insertions, 11 deletions
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 3acf65e75eb2..cb7dec97fee6 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -72,7 +72,7 @@ | |||
72 | #include <linux/libata.h> | 72 | #include <linux/libata.h> |
73 | 73 | ||
74 | #define DRV_NAME "sata_mv" | 74 | #define DRV_NAME "sata_mv" |
75 | #define DRV_VERSION "0.81" | 75 | #define DRV_VERSION "1.0" |
76 | 76 | ||
77 | enum { | 77 | enum { |
78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ | 78 | /* BAR's are enumerated in terms of pci_resource_start() terms */ |
@@ -313,7 +313,10 @@ enum { | |||
313 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) | 313 | #define IS_GEN_IIE(hpriv) ((hpriv)->hp_flags & MV_HP_GEN_IIE) |
314 | 314 | ||
315 | enum { | 315 | enum { |
316 | MV_DMA_BOUNDARY = 0xffffffffU, | 316 | /* DMA boundary 0xffff is required by the s/g splitting |
317 | * we need on /length/ in mv_fill-sg(). | ||
318 | */ | ||
319 | MV_DMA_BOUNDARY = 0xffffU, | ||
317 | 320 | ||
318 | /* mask of register bits containing lower 32 bits | 321 | /* mask of register bits containing lower 32 bits |
319 | * of EDMA request queue DMA address | 322 | * of EDMA request queue DMA address |
@@ -448,7 +451,7 @@ static struct scsi_host_template mv5_sht = { | |||
448 | .queuecommand = ata_scsi_queuecmd, | 451 | .queuecommand = ata_scsi_queuecmd, |
449 | .can_queue = ATA_DEF_QUEUE, | 452 | .can_queue = ATA_DEF_QUEUE, |
450 | .this_id = ATA_SHT_THIS_ID, | 453 | .this_id = ATA_SHT_THIS_ID, |
451 | .sg_tablesize = MV_MAX_SG_CT, | 454 | .sg_tablesize = MV_MAX_SG_CT / 2, |
452 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 455 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
453 | .emulated = ATA_SHT_EMULATED, | 456 | .emulated = ATA_SHT_EMULATED, |
454 | .use_clustering = 1, | 457 | .use_clustering = 1, |
@@ -466,7 +469,7 @@ static struct scsi_host_template mv6_sht = { | |||
466 | .queuecommand = ata_scsi_queuecmd, | 469 | .queuecommand = ata_scsi_queuecmd, |
467 | .can_queue = ATA_DEF_QUEUE, | 470 | .can_queue = ATA_DEF_QUEUE, |
468 | .this_id = ATA_SHT_THIS_ID, | 471 | .this_id = ATA_SHT_THIS_ID, |
469 | .sg_tablesize = MV_MAX_SG_CT, | 472 | .sg_tablesize = MV_MAX_SG_CT / 2, |
470 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, | 473 | .cmd_per_lun = ATA_SHT_CMD_PER_LUN, |
471 | .emulated = ATA_SHT_EMULATED, | 474 | .emulated = ATA_SHT_EMULATED, |
472 | .use_clustering = 1, | 475 | .use_clustering = 1, |
@@ -1139,15 +1142,27 @@ static unsigned int mv_fill_sg(struct ata_queued_cmd *qc) | |||
1139 | dma_addr_t addr = sg_dma_address(sg); | 1142 | dma_addr_t addr = sg_dma_address(sg); |
1140 | u32 sg_len = sg_dma_len(sg); | 1143 | u32 sg_len = sg_dma_len(sg); |
1141 | 1144 | ||
1142 | mv_sg->addr = cpu_to_le32(addr & 0xffffffff); | 1145 | while (sg_len) { |
1143 | mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); | 1146 | u32 offset = addr & 0xffff; |
1144 | mv_sg->flags_size = cpu_to_le32(sg_len & 0xffff); | 1147 | u32 len = sg_len; |
1148 | |||
1149 | if ((offset + sg_len > 0x10000)) | ||
1150 | len = 0x10000 - offset; | ||
1151 | |||
1152 | mv_sg->addr = cpu_to_le32(addr & 0xffffffff); | ||
1153 | mv_sg->addr_hi = cpu_to_le32((addr >> 16) >> 16); | ||
1154 | mv_sg->flags_size = cpu_to_le32(len); | ||
1145 | 1155 | ||
1146 | if (ata_sg_is_last(sg, qc)) | 1156 | sg_len -= len; |
1147 | mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); | 1157 | addr += len; |
1158 | |||
1159 | if (!sg_len && ata_sg_is_last(sg, qc)) | ||
1160 | mv_sg->flags_size |= cpu_to_le32(EPRD_FLAG_END_OF_TBL); | ||
1161 | |||
1162 | mv_sg++; | ||
1163 | n_sg++; | ||
1164 | } | ||
1148 | 1165 | ||
1149 | mv_sg++; | ||
1150 | n_sg++; | ||
1151 | } | 1166 | } |
1152 | 1167 | ||
1153 | return n_sg; | 1168 | return n_sg; |