ide: cleanup ide_build_dmatable()

- use for_each_sg()
- move printing 'DMA table too small' message below use_pio_instead label
- merge '64KB bug' comment with function documentation
- fix intendation

There should be no functional changes caused by this patch.
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent c19f7f22
...@@ -153,8 +153,11 @@ EXPORT_SYMBOL_GPL(ide_build_sglist); ...@@ -153,8 +153,11 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
* *
* ide_build_dmatable() prepares a dma request. We map the command * ide_build_dmatable() prepares a dma request. We map the command
* to get the pci bus addresses of the buffers and then build up * to get the pci bus addresses of the buffers and then build up
* the PRD table that the IDE layer wants to be fed. The code * the PRD table that the IDE layer wants to be fed.
* knows about the 64K wrap bug in the CS5530. *
* Most chipsets correctly interpret a length of 0x0000 as 64KB,
* but at least one (e.g. CS5530) misinterprets it as zero (!).
* So we break the 64KB entry into two 32KB entries instead.
* *
* Returns the number of built PRD entries if all went okay, * Returns the number of built PRD entries if all went okay,
* returns 0 otherwise. * returns 0 otherwise.
...@@ -171,15 +174,12 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq) ...@@ -171,15 +174,12 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
int i; int i;
struct scatterlist *sg; struct scatterlist *sg;
hwif->sg_nents = i = ide_build_sglist(drive, rq); hwif->sg_nents = ide_build_sglist(drive, rq);
if (hwif->sg_nents == 0)
if (!i)
return 0; return 0;
sg = hwif->sg_table; for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
while (i) { u32 cur_addr, cur_len, xcount, bcount;
u32 cur_addr;
u32 cur_len;
cur_addr = sg_dma_address(sg); cur_addr = sg_dma_address(sg);
cur_len = sg_dma_len(sg); cur_len = sg_dma_len(sg);
...@@ -191,40 +191,27 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq) ...@@ -191,40 +191,27 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
*/ */
while (cur_len) { while (cur_len) {
if (count++ >= PRD_ENTRIES) { if (count++ >= PRD_ENTRIES)
printk(KERN_ERR "%s: DMA table too small\n", drive->name);
goto use_pio_instead; goto use_pio_instead;
} else {
u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff); bcount = 0x10000 - (cur_addr & 0xffff);
if (bcount > cur_len)
if (bcount > cur_len) bcount = cur_len;
bcount = cur_len; *table++ = cpu_to_le32(cur_addr);
*table++ = cpu_to_le32(cur_addr); xcount = bcount & 0xffff;
xcount = bcount & 0xffff; if (is_trm290)
if (is_trm290) xcount = ((xcount >> 2) - 1) << 16;
xcount = ((xcount >> 2) - 1) << 16; if (xcount == 0x0000) {
else if (xcount == 0x0000) { if (count++ >= PRD_ENTRIES)
/* goto use_pio_instead;
* Most chipsets correctly interpret a length of 0x0000 as 64KB, *table++ = cpu_to_le32(0x8000);
* but at least one (e.g. CS5530) misinterprets it as zero (!). *table++ = cpu_to_le32(cur_addr + 0x8000);
* So here we break the 64KB entry into two 32KB entries instead. xcount = 0x8000;
*/
if (count++ >= PRD_ENTRIES) {
printk(KERN_ERR "%s: DMA table too small\n", drive->name);
goto use_pio_instead;
}
*table++ = cpu_to_le32(0x8000);
*table++ = cpu_to_le32(cur_addr + 0x8000);
xcount = 0x8000;
}
*table++ = cpu_to_le32(xcount);
cur_addr += bcount;
cur_len -= bcount;
} }
*table++ = cpu_to_le32(xcount);
cur_addr += bcount;
cur_len -= bcount;
} }
sg = sg_next(sg);
i--;
} }
if (count) { if (count) {
...@@ -233,14 +220,14 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq) ...@@ -233,14 +220,14 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
return count; return count;
} }
printk(KERN_ERR "%s: empty DMA table?\n", drive->name);
use_pio_instead: use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");
ide_destroy_dmatable(drive); ide_destroy_dmatable(drive);
return 0; /* revert to PIO for this request */ return 0; /* revert to PIO for this request */
} }
EXPORT_SYMBOL_GPL(ide_build_dmatable); EXPORT_SYMBOL_GPL(ide_build_dmatable);
#endif #endif
......
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