Commit 489797e7 authored by Pete Zaitcev's avatar Pete Zaitcev Committed by David S. Miller

[sparc] Fix off-by-one in s/g handling

parent eaf3a1b6
......@@ -135,7 +135,8 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
/* FIXME: Cache some resolved pages - often several sg entries are to the same page */
spin_lock_irqsave(&iounit->lock, flags);
for (; sz >= 0; sz--) {
while (sz != 0) {
--sz;
sg[sz].dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg[sz].page) + sg[sz].offset, sg[sz].length);
sg[sz].dvma_length = sg[sz].length;
}
......@@ -163,7 +164,8 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_
struct iounit_struct *iounit = (struct iounit_struct *)sbus->iommu;
spin_lock_irqsave(&iounit->lock, flags);
for (; sz >= 0; sz--) {
while (sz != 0) {
--sz;
len = ((sg[sz].dvma_address & ~PAGE_MASK) + sg[sz].length + (PAGE_SIZE-1)) >> PAGE_SHIFT;
vaddr = (sg[sz].dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr));
......
......@@ -171,7 +171,8 @@ static __u32 iommu_get_scsi_one_pflush(char *vaddr, unsigned long len, struct sb
static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus)
{
for (; sz >= 0; sz--) {
while (sz != 0) {
--sz;
sg[sz].dvma_address = (__u32) (page_address(sg[sz].page) + sg[sz].offset);
sg[sz].dvma_length = (__u32) (sg[sz].length);
}
......@@ -180,7 +181,8 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbus_bus *sbus)
{
flush_page_for_dma(0);
for (; sz >= 0; sz--) {
while (sz != 0) {
--sz;
sg[sz].dvma_address = (__u32) (page_address(sg[sz].page) + sg[sz].offset);
sg[sz].dvma_length = (__u32) (sg[sz].length);
}
......@@ -191,6 +193,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
unsigned long page, oldpage = 0;
while(sz >= 0) {
--sz;
page = ((unsigned long) sg[sz].offset) & PAGE_MASK;
if (oldpage == page)
page += PAGE_SIZE; /* We flushed that page already */
......@@ -200,7 +203,6 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
}
sg[sz].dvma_address = (__u32) (page_address(sg[sz].page) + sg[sz].offset);
sg[sz].dvma_length = (__u32) (sg[sz].length);
sz--;
oldpage = page - PAGE_SIZE;
}
}
......
......@@ -1219,10 +1219,10 @@ static __u32 sun4c_get_scsi_one(char *bufptr, unsigned long len, struct sbus_bus
static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus)
{
while (sz >= 0) {
while (sz != 0) {
--sz;
sg[sz].dvma_address = (__u32)sun4c_lockarea(page_address(sg[sz].page) + sg[sz].offset, sg[sz].length);
sg[sz].dvma_length = sg[sz].length;
sz--;
}
}
......@@ -1235,9 +1235,9 @@ static void sun4c_release_scsi_one(__u32 bufptr, unsigned long len, struct sbus_
static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *sbus)
{
while (sz >= 0) {
while (sz != 0) {
--sz;
sun4c_unlockarea((char *)sg[sz].dvma_address, sg[sz].length);
sz--;
}
}
......
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