Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 114215
b: refs/heads/master
c: 14c123f
h: refs/heads/master
i:
  114213: 7a4e036
  114211: f8a6db0
  114207: a08a7cc
v: v3
  • Loading branch information
Bartlomiej Zolnierkiewicz committed Oct 13, 2008
1 parent 8c87829 commit e78b7bb
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 44 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c19f7f226ba011843a31ee4f21a19c36fa5a3ead
refs/heads/master: 14c123f37187aba0b4e0e893a969efc6820c4170
73 changes: 30 additions & 43 deletions trunk/drivers/ide/ide-dma.c
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,11 @@ EXPORT_SYMBOL_GPL(ide_build_sglist);
*
* ide_build_dmatable() prepares a dma request. We map the command
* 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
* knows about the 64K wrap bug in the CS5530.
* the PRD table that the IDE layer wants to be fed.
*
* 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 0 otherwise.
Expand All @@ -171,15 +174,12 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
int i;
struct scatterlist *sg;

hwif->sg_nents = i = ide_build_sglist(drive, rq);

if (!i)
hwif->sg_nents = ide_build_sglist(drive, rq);
if (hwif->sg_nents == 0)
return 0;

sg = hwif->sg_table;
while (i) {
u32 cur_addr;
u32 cur_len;
for_each_sg(hwif->sg_table, sg, hwif->sg_nents, i) {
u32 cur_addr, cur_len, xcount, bcount;

cur_addr = sg_dma_address(sg);
cur_len = sg_dma_len(sg);
Expand All @@ -191,40 +191,27 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
*/

while (cur_len) {
if (count++ >= PRD_ENTRIES) {
printk(KERN_ERR "%s: DMA table too small\n", drive->name);
if (count++ >= PRD_ENTRIES)
goto use_pio_instead;
} else {
u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);

if (bcount > cur_len)
bcount = cur_len;
*table++ = cpu_to_le32(cur_addr);
xcount = bcount & 0xffff;
if (is_trm290)
xcount = ((xcount >> 2) - 1) << 16;
else if (xcount == 0x0000) {
/*
* Most chipsets correctly interpret a length of 0x0000 as 64KB,
* but at least one (e.g. CS5530) misinterprets it as zero (!).
* So here we break the 64KB entry into two 32KB entries instead.
*/
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;

bcount = 0x10000 - (cur_addr & 0xffff);
if (bcount > cur_len)
bcount = cur_len;
*table++ = cpu_to_le32(cur_addr);
xcount = bcount & 0xffff;
if (is_trm290)
xcount = ((xcount >> 2) - 1) << 16;
if (xcount == 0x0000) {
if (count++ >= PRD_ENTRIES)
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;
}

sg = sg_next(sg);
i--;
}

if (count) {
Expand All @@ -233,14 +220,14 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
return count;
}

printk(KERN_ERR "%s: empty DMA table?\n", drive->name);

use_pio_instead:
printk(KERN_ERR "%s: %s\n", drive->name,
count ? "DMA table too small" : "empty DMA table?");

ide_destroy_dmatable(drive);

return 0; /* revert to PIO for this request */
}

EXPORT_SYMBOL_GPL(ide_build_dmatable);
#endif

Expand Down

0 comments on commit e78b7bb

Please sign in to comment.