Fix for large transfer operations not advancing buffer address
offset when DMA transfer unit is smaller than given buffer size. Bug tracker item #82.
This commit is contained in:
parent
4af032bbfe
commit
e9e347f5b6
1 changed files with 18 additions and 9 deletions
|
@ -358,7 +358,8 @@ FORWARD _PROTOTYPE( int w_transfer, (int proc_nr, int opcode, u64_t position,
|
|||
FORWARD _PROTOTYPE( int com_out, (struct command *cmd) );
|
||||
FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd) );
|
||||
FORWARD _PROTOTYPE( void setup_dma, (unsigned *sizep, int proc_nr,
|
||||
iovec_t *iov, int do_write, int *do_copyoutp, int safe) );
|
||||
iovec_t *iov, size_t addr_offset, int do_write,
|
||||
int *do_copyoutp, int safe) );
|
||||
FORWARD _PROTOTYPE( void w_need_reset, (void) );
|
||||
FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) );
|
||||
FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
|
||||
|
@ -1352,7 +1353,8 @@ int safe; /* iov contains addresses (0) or grants? */
|
|||
|
||||
if (do_dma)
|
||||
{
|
||||
setup_dma(&nbytes, proc_nr, iov, do_write, &do_copyout, safe);
|
||||
setup_dma(&nbytes, proc_nr, iov, addr_offset, do_write,
|
||||
&do_copyout, safe);
|
||||
#if 0
|
||||
printf("nbytes = %d\n", nbytes);
|
||||
#endif
|
||||
|
@ -1453,6 +1455,7 @@ int safe; /* iov contains addresses (0) or grants? */
|
|||
/* Book the bytes successfully transferred. */
|
||||
nbytes -= n;
|
||||
position= add64ul(position, n);
|
||||
addr_offset += n;
|
||||
if ((iov->iov_size -= n) == 0) {
|
||||
iov++; nr_req--; addr_offset = 0;
|
||||
}
|
||||
|
@ -1664,10 +1667,12 @@ struct command *cmd; /* Command block */
|
|||
/*===========================================================================*
|
||||
* setup_dma *
|
||||
*===========================================================================*/
|
||||
PRIVATE void setup_dma(sizep, proc_nr, iov, do_write, do_copyoutp, safe)
|
||||
PRIVATE void setup_dma(sizep, proc_nr, iov, addr_offset, do_write,
|
||||
do_copyoutp, safe)
|
||||
unsigned *sizep;
|
||||
int proc_nr;
|
||||
iovec_t *iov;
|
||||
size_t addr_offset;
|
||||
int do_write;
|
||||
int *do_copyoutp;
|
||||
int safe;
|
||||
|
@ -1706,9 +1711,10 @@ int safe;
|
|||
r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,&user_phys);
|
||||
if (r != 0)
|
||||
panic("at_wini", "can't map user buffer (VM_GRANT)", r);
|
||||
user_phys += offset;
|
||||
user_phys += offset + addr_offset;
|
||||
} else {
|
||||
r= sys_umap(proc_nr, VM_D, iov[i].iov_addr+offset, n, &user_phys);
|
||||
r= sys_umap(proc_nr, VM_D, iov[i].iov_addr+offset+addr_offset,
|
||||
n, &user_phys);
|
||||
if (r != 0)
|
||||
panic("at_wini", "can't map user buffer (VM_D)", r);
|
||||
}
|
||||
|
@ -1746,6 +1752,7 @@ int safe;
|
|||
{
|
||||
i++;
|
||||
offset= 0;
|
||||
addr_offset= 0;
|
||||
}
|
||||
|
||||
size -= n;
|
||||
|
@ -1791,11 +1798,12 @@ int safe;
|
|||
|
||||
if(safe) {
|
||||
r= sys_safecopyfrom(proc_nr, iov->iov_addr,
|
||||
0, (vir_bytes)dma_buf+offset, n, D);
|
||||
addr_offset, (vir_bytes)dma_buf+offset,
|
||||
n, D);
|
||||
} else {
|
||||
r= sys_vircopy(proc_nr, D, iov->iov_addr,
|
||||
SELF, D, (vir_bytes)dma_buf+offset,
|
||||
n);
|
||||
r= sys_vircopy(proc_nr, D,
|
||||
iov->iov_addr+addr_offset, SELF, D,
|
||||
(vir_bytes)dma_buf+offset, n);
|
||||
}
|
||||
if (r != OK)
|
||||
{
|
||||
|
@ -1804,6 +1812,7 @@ int safe;
|
|||
r);
|
||||
}
|
||||
iov++;
|
||||
addr_offset= 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue