@@ -1517,66 +1517,68 @@ impl DmaTxStreamBufView {
15171517 head. iter ( )
15181518 . chain ( tail)
15191519 . take_while ( |d| d. owner ( ) == Owner :: Cpu )
1520- . map ( |d| d. len ( ) )
1520+ . map ( |d| d. size ( ) )
15211521 . sum :: < usize > ( )
15221522 - self . descriptor_offset
15231523 }
15241524
15251525 /// Pushes a buffer into the stream buffer.
15261526 /// Returns the number of bytes pushed.
15271527 pub fn push ( & mut self , buf : & [ u8 ] ) -> usize {
1528+ let bytes_to_fill = buf. len ( ) . min ( self . available_bytes ( ) ) ;
1529+ let buf = & buf[ ..bytes_to_fill] ;
1530+
1531+ fn truncate_by ( n : usize , by : usize ) -> usize {
1532+ ( n >= by) . then_some ( n - by) . unwrap_or ( n)
1533+ }
1534+
1535+ let n_chunks = self . buf . descriptors . len ( ) ;
15281536 let chunk_size = self . buf . descriptors [ 0 ] . size ( ) ;
1529- let n_descs = self . buf . descriptors . len ( ) ;
1537+ let dma_size = self . buf . buffer . len ( ) ;
1538+ let dma_start = self . descriptor_idx * chunk_size + self . descriptor_offset ;
1539+ let dma_end = truncate_by ( dma_start + buf. len ( ) , dma_size) ;
15301540
1531- // Prepare descriptors and reorganize link list
1532- let buf_start = chunk_size * self . descriptor_idx + self . descriptor_offset ;
1533- let desc_start = self . descriptor_idx ;
1534- let mut buf_idx = 0 ;
1535- loop {
1536- let d = & mut self . buf . descriptors [ self . descriptor_idx ] ;
1537- if d. owner ( ) == Owner :: Dma {
1538- break ;
1539- }
1541+ if dma_start < dma_end {
1542+ self . buf . buffer [ dma_start..dma_end] . copy_from_slice ( buf) ;
1543+ } else {
1544+ self . buf . buffer [ dma_start..] . copy_from_slice ( & buf[ ..dma_size - dma_start] ) ;
1545+ self . buf . buffer [ ..dma_end] . copy_from_slice ( & buf[ dma_size - dma_start..] ) ;
1546+ }
15401547
1541- let desc_remain = d. len ( ) - self . descriptor_offset ;
1542- if buf_idx + desc_remain >= buf. len ( ) {
1543- self . descriptor_offset += desc_remain;
1548+ let descs = ( self . descriptor_idx ..n_chunks) . chain ( 0 ..self . descriptor_idx ) ;
1549+ let mut offset = self . descriptor_offset ;
1550+ let mut bytes_filled = 0 ;
1551+
1552+ for d in descs {
1553+ let desc = & mut self . buf . descriptors [ d] ;
1554+ let bytes_in_d = desc. size ( ) - offset;
1555+ if bytes_in_d + bytes_filled > buf. len ( ) {
1556+ // I will have empty space in `desc`
1557+ self . descriptor_idx = d;
1558+ self . descriptor_offset = offset + buf. len ( ) - bytes_filled;
15441559 break ;
15451560 }
1546- buf_idx += desc_remain;
1547-
1548- d. next = null_mut ( ) ;
1549- let prev = self . descriptor_idx . checked_sub ( 1 ) . unwrap_or ( n_descs - 1 ) ;
1550- self . buf . descriptors [ prev] . next = d;
1561+ // fill `desc` with data from `buf`
1562+ bytes_filled += bytes_in_d;
1563+ offset = 0 ;
15511564
1552- self . descriptor_idx += 1 ;
1553- if self . descriptor_idx > n_descs {
1554- self . descriptor_idx = 0 ;
1565+ desc. set_owner ( Owner :: Dma ) ;
1566+ desc. set_length ( desc. size ( ) ) ;
1567+ desc. set_suc_eof ( true ) ;
1568+ let p = d. checked_sub ( 1 ) . unwrap_or ( n_chunks - 1 ) ;
1569+ if p != d {
1570+ let [ prev, desc] = self . buf . descriptors . get_disjoint_mut ( [ p, d] ) . unwrap ( ) ;
1571+ desc. next = null_mut ( ) ;
1572+ prev. next = desc;
15551573 }
1556- self . descriptor_offset = 0 ;
15571574 }
1558- let buf_end = chunk_size * self . descriptor_idx + self . descriptor_offset ;
1559- let desc_end = self . descriptor_idx ;
15601575
1561- // Actually copy buffers
1562- if buf_start < buf_end {
1563- self . buf . buffer [ buf_start..buf_end] . copy_from_slice ( & buf[ ..buf_end - buf_start] ) ;
1564- self . buf . descriptors [ desc_start..desc_end]
1565- . iter_mut ( )
1566- . for_each ( |d| d. set_owner ( Owner :: Dma ) ) ;
1567- buf_end - buf_start
1568- } else {
1569- let buf_len = self . buf . buffer . len ( ) ;
1570- self . buf . buffer [ buf_start..] . copy_from_slice ( & buf[ ..buf_len - buf_start] ) ;
1571- self . buf . buffer [ ..buf_end] . copy_from_slice ( & buf[ buf_len - buf_start..] ) ;
1572- self . buf . descriptors [ desc_start..]
1573- . iter_mut ( )
1574- . for_each ( |d| d. set_owner ( Owner :: Dma ) ) ;
1575- self . buf . descriptors [ ..desc_end]
1576- . iter_mut ( )
1577- . for_each ( |d| d. set_owner ( Owner :: Dma ) ) ;
1578- buf_len + buf_end - buf_start
1579- }
1576+ info ! (
1577+ "self.descriptor_idx: {}, self.descriptor_offset: {}, dma_start: {}, dma_end: {}" ,
1578+ self . descriptor_idx, self . descriptor_offset, dma_start, dma_end
1579+ ) ;
1580+
1581+ bytes_to_fill
15801582 }
15811583}
15821584
0 commit comments