mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 14:48:57 +00:00
Ensure that DMA mappings are freed in error situations.
This commit is contained in:
parent
c34532be04
commit
3ee23c43ff
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=56064
@ -407,6 +407,7 @@ fore_buf_supply_1s(fup)
|
||||
* an entry, free up what's been partially built
|
||||
*/
|
||||
if (i != BUF1_SM_ENTSIZE) {
|
||||
caddr_t cp;
|
||||
|
||||
/*
|
||||
* Clean up each used descriptor
|
||||
@ -420,6 +421,8 @@ fore_buf_supply_1s(fup)
|
||||
|
||||
m = (KBuffer *)
|
||||
((caddr_t)bhp - BUF1_SM_HOFF);
|
||||
KB_DATASTART(m, cp, caddr_t);
|
||||
DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_SM_SIZE, 0);
|
||||
KB_FREEALL(m);
|
||||
}
|
||||
break;
|
||||
@ -546,6 +549,7 @@ fore_buf_supply_1l(fup)
|
||||
* an entry, free up what's been partially built
|
||||
*/
|
||||
if (i != BUF1_LG_ENTSIZE) {
|
||||
caddr_t cp;
|
||||
|
||||
/*
|
||||
* Clean up each used descriptor
|
||||
@ -558,6 +562,8 @@ fore_buf_supply_1l(fup)
|
||||
|
||||
m = (KBuffer *)
|
||||
((caddr_t)bhp - BUF1_LG_HOFF);
|
||||
KB_DATASTART(m, cp, caddr_t);
|
||||
DMA_FREE_ADDR(cp, bhp->bh_dma, BUF1_LG_SIZE, 0);
|
||||
KB_FREEALL(m);
|
||||
}
|
||||
break;
|
||||
|
@ -46,7 +46,8 @@ __RCSID("@(#) $FreeBSD$");
|
||||
* Local functions
|
||||
*/
|
||||
static KBuffer * fore_xmit_segment __P((Fore_unit *, KBuffer *,
|
||||
H_xmit_queue *, u_int *, u_int *));
|
||||
H_xmit_queue *, int *, int *));
|
||||
static void fore_seg_dma_free __P((H_xmit_queue *, KBuffer *, int));
|
||||
|
||||
|
||||
/*
|
||||
@ -79,7 +80,7 @@ fore_output(cup, cvp, m)
|
||||
H_xmit_queue *hxp;
|
||||
Xmit_queue *cqp;
|
||||
Xmit_descr *xdp;
|
||||
u_int retry, nsegs, pdulen;
|
||||
int retry, nsegs, pdulen;
|
||||
int s;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
@ -229,8 +230,8 @@ fore_xmit_segment(fup, m, hxp, segp, lenp)
|
||||
Fore_unit *fup;
|
||||
KBuffer *m;
|
||||
H_xmit_queue *hxp;
|
||||
u_int *segp;
|
||||
u_int *lenp;
|
||||
int *segp;
|
||||
int *lenp;
|
||||
{
|
||||
Xmit_descr *xdp = hxp->hxq_descr;
|
||||
Xmit_seg_descr *xsp;
|
||||
@ -238,7 +239,7 @@ fore_xmit_segment(fup, m, hxp, segp, lenp)
|
||||
KBuffer *m0, *m1, *mprev;
|
||||
caddr_t cp, bfr;
|
||||
void *dma;
|
||||
u_int pdulen, nsegs, len, align;
|
||||
int pdulen, nsegs, len, align;
|
||||
int compressed = 0;
|
||||
|
||||
m0 = m;
|
||||
@ -274,6 +275,11 @@ retry:
|
||||
* Make sure we don't try to use too many segments
|
||||
*/
|
||||
if (nsegs >= XMIT_MAX_SEGS) {
|
||||
/*
|
||||
* First, free already allocated DMA addresses
|
||||
*/
|
||||
fore_seg_dma_free(hxp, m0, nsegs);
|
||||
|
||||
/*
|
||||
* Try to compress buffer chain (but only once)
|
||||
*/
|
||||
@ -327,7 +333,7 @@ retry:
|
||||
* Have to move some data from following buffer(s)
|
||||
* to word-fill this buffer
|
||||
*/
|
||||
u_int ncopy = MIN(XMIT_SEG_ALIGN - align, KB_LEN(m1));
|
||||
int ncopy = MIN(XMIT_SEG_ALIGN - align, KB_LEN(m1));
|
||||
|
||||
if (ncopy) {
|
||||
/*
|
||||
@ -374,8 +380,8 @@ retry:
|
||||
*/
|
||||
dma = DMA_GET_ADDR(bfr, xsp->xsd_len, XMIT_SEG_ALIGN, 0);
|
||||
if (dma == NULL) {
|
||||
|
||||
fup->fu_stats->st_drv.drv_xm_segdma++;
|
||||
fore_seg_dma_free(hxp, m0, nsegs);
|
||||
KB_FREEALL(m0);
|
||||
return (NULL);
|
||||
}
|
||||
@ -400,6 +406,7 @@ retry:
|
||||
*/
|
||||
if (pdulen > XMIT_MAX_PDULEN) {
|
||||
fup->fu_stats->st_drv.drv_xm_maxpdu++;
|
||||
fore_seg_dma_free(hxp, m0, nsegs);
|
||||
KB_FREEALL(m0);
|
||||
return (NULL);
|
||||
}
|
||||
@ -413,3 +420,35 @@ retry:
|
||||
return (m0);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Free Transmit Segment Queue DMA addresses
|
||||
*
|
||||
* Arguments:
|
||||
* hxp pointer to host transmit queue entry
|
||||
* m0 pointer to output PDU buffer chain head
|
||||
* nsegs number of processed transmit segments
|
||||
*
|
||||
* Returns:
|
||||
* none
|
||||
*
|
||||
*/
|
||||
static void
|
||||
fore_seg_dma_free(hxp, m0, nsegs)
|
||||
H_xmit_queue *hxp;
|
||||
KBuffer *m0;
|
||||
int nsegs;
|
||||
{
|
||||
KBuffer *m = m0;
|
||||
H_dma *sdmap = hxp->hxq_dma;
|
||||
caddr_t cp;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nsegs; i++) {
|
||||
KB_DATASTART(m, cp, caddr_t);
|
||||
DMA_FREE_ADDR(cp, *sdmap, KB_LEN(m), 0);
|
||||
m = KB_NEXT(m);
|
||||
sdmap++;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user