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
@ -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, (struct command *cmd) );
|
||||||
FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd) );
|
FORWARD _PROTOTYPE( int com_out_ext, (struct command *cmd) );
|
||||||
FORWARD _PROTOTYPE( void setup_dma, (unsigned *sizep, int proc_nr,
|
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 w_need_reset, (void) );
|
||||||
FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) );
|
FORWARD _PROTOTYPE( void ack_irqs, (unsigned int) );
|
||||||
FORWARD _PROTOTYPE( int w_do_close, (struct driver *dp, message *m_ptr) );
|
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)
|
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
|
#if 0
|
||||||
printf("nbytes = %d\n", nbytes);
|
printf("nbytes = %d\n", nbytes);
|
||||||
#endif
|
#endif
|
||||||
@ -1453,6 +1455,7 @@ int safe; /* iov contains addresses (0) or grants? */
|
|||||||
/* Book the bytes successfully transferred. */
|
/* Book the bytes successfully transferred. */
|
||||||
nbytes -= n;
|
nbytes -= n;
|
||||||
position= add64ul(position, n);
|
position= add64ul(position, n);
|
||||||
|
addr_offset += n;
|
||||||
if ((iov->iov_size -= n) == 0) {
|
if ((iov->iov_size -= n) == 0) {
|
||||||
iov++; nr_req--; addr_offset = 0;
|
iov++; nr_req--; addr_offset = 0;
|
||||||
}
|
}
|
||||||
@ -1664,10 +1667,12 @@ struct command *cmd; /* Command block */
|
|||||||
/*===========================================================================*
|
/*===========================================================================*
|
||||||
* setup_dma *
|
* 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;
|
unsigned *sizep;
|
||||||
int proc_nr;
|
int proc_nr;
|
||||||
iovec_t *iov;
|
iovec_t *iov;
|
||||||
|
size_t addr_offset;
|
||||||
int do_write;
|
int do_write;
|
||||||
int *do_copyoutp;
|
int *do_copyoutp;
|
||||||
int safe;
|
int safe;
|
||||||
@ -1706,9 +1711,10 @@ int safe;
|
|||||||
r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,&user_phys);
|
r= sys_umap(proc_nr, VM_GRANT, iov[i].iov_addr, n,&user_phys);
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
panic("at_wini", "can't map user buffer (VM_GRANT)", r);
|
panic("at_wini", "can't map user buffer (VM_GRANT)", r);
|
||||||
user_phys += offset;
|
user_phys += offset + addr_offset;
|
||||||
} else {
|
} 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)
|
if (r != 0)
|
||||||
panic("at_wini", "can't map user buffer (VM_D)", r);
|
panic("at_wini", "can't map user buffer (VM_D)", r);
|
||||||
}
|
}
|
||||||
@ -1746,6 +1752,7 @@ int safe;
|
|||||||
{
|
{
|
||||||
i++;
|
i++;
|
||||||
offset= 0;
|
offset= 0;
|
||||||
|
addr_offset= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size -= n;
|
size -= n;
|
||||||
@ -1791,11 +1798,12 @@ int safe;
|
|||||||
|
|
||||||
if(safe) {
|
if(safe) {
|
||||||
r= sys_safecopyfrom(proc_nr, iov->iov_addr,
|
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 {
|
} else {
|
||||||
r= sys_vircopy(proc_nr, D, iov->iov_addr,
|
r= sys_vircopy(proc_nr, D,
|
||||||
SELF, D, (vir_bytes)dma_buf+offset,
|
iov->iov_addr+addr_offset, SELF, D,
|
||||||
n);
|
(vir_bytes)dma_buf+offset, n);
|
||||||
}
|
}
|
||||||
if (r != OK)
|
if (r != OK)
|
||||||
{
|
{
|
||||||
@ -1804,6 +1812,7 @@ int safe;
|
|||||||
r);
|
r);
|
||||||
}
|
}
|
||||||
iov++;
|
iov++;
|
||||||
|
addr_offset= 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user