@@ -13,7 +13,7 @@ use utils::eventfd::EventFd;
1313
1414use crate :: bus:: { BusDevice , RawIOHandler } ;
1515
16- const LOOP_SIZE : usize = 0x40 ;
16+ const FIFO_SIZE : usize = 64 ;
1717
1818const DATA : u8 = 0 ;
1919const IER : u8 = 1 ;
@@ -59,6 +59,7 @@ pub struct Serial {
5959 interrupt_enable : u8 ,
6060 interrupt_identification : u8 ,
6161 interrupt_evt : EventFd ,
62+ buffer_ready_evt : Option < EventFd > ,
6263 line_control : u8 ,
6364 line_status : u8 ,
6465 modem_control : u8 ,
@@ -70,11 +71,16 @@ pub struct Serial {
7071}
7172
7273impl Serial {
73- fn new ( interrupt_evt : EventFd , out : Option < Box < dyn io:: Write + Send > > ) -> Serial {
74+ fn new (
75+ interrupt_evt : EventFd ,
76+ buffer_ready_evt : Option < EventFd > ,
77+ out : Option < Box < dyn io:: Write + Send > > ,
78+ ) -> Serial {
7479 Serial {
7580 interrupt_enable : 0 ,
7681 interrupt_identification : DEFAULT_INTERRUPT_IDENTIFICATION ,
7782 interrupt_evt,
83+ buffer_ready_evt,
7884 line_control : DEFAULT_LINE_CONTROL ,
7985 line_status : DEFAULT_LINE_STATUS ,
8086 modem_control : DEFAULT_MODEM_CONTROL ,
@@ -87,13 +93,17 @@ impl Serial {
8793 }
8894
8995 /// Constructs a Serial port ready for output.
90- pub fn new_out ( interrupt_evt : EventFd , out : Box < dyn io:: Write + Send > ) -> Serial {
91- Self :: new ( interrupt_evt, Some ( out) )
96+ pub fn new_out (
97+ interrupt_evt : EventFd ,
98+ buffer_ready_evt : Option < EventFd > ,
99+ out : Box < dyn io:: Write + Send > ,
100+ ) -> Serial {
101+ Self :: new ( interrupt_evt, buffer_ready_evt, Some ( out) )
92102 }
93103
94104 /// Constructs a Serial port with no connected output.
95- pub fn new_sink ( interrupt_evt : EventFd ) -> Serial {
96- Self :: new ( interrupt_evt, None )
105+ pub fn new_sink ( interrupt_evt : EventFd , buffer_ready_evt : Option < EventFd > ) -> Serial {
106+ Self :: new ( interrupt_evt, buffer_ready_evt , None )
97107 }
98108
99109 fn is_dlab_set ( & self ) -> bool {
@@ -160,7 +170,7 @@ impl Serial {
160170 }
161171 DATA => {
162172 if self . is_loop ( ) {
163- if self . in_buffer . len ( ) < LOOP_SIZE {
173+ if self . in_buffer . len ( ) < FIFO_SIZE {
164174 self . in_buffer . push_back ( value) ;
165175 self . recv_data ( ) ?;
166176 }
@@ -192,6 +202,12 @@ impl Serial {
192202 self . del_intr_bit ( IIR_RECV_BIT ) ;
193203 if self . in_buffer . len ( ) <= 1 {
194204 self . line_status &= !LSR_DATA_BIT ;
205+ if !self . is_loop ( ) && self . in_buffer . len ( ) == 1 {
206+ if let Some ( evt) = self . buffer_ready_evt . as_ref ( ) {
207+ evt. write ( 1 )
208+ . expect ( "Couldn't signal that the serial device buffer is ready." ) ;
209+ }
210+ }
195211 }
196212 METRICS . uart . read_count . inc ( ) ;
197213 self . in_buffer . pop_front ( ) . unwrap_or_default ( )
@@ -214,12 +230,27 @@ impl Serial {
214230
215231impl RawIOHandler for Serial {
216232 fn raw_input ( & mut self , data : & [ u8 ] ) -> io:: Result < ( ) > {
233+ // Fail fast if the serial is serviced with more data than it can buffer.
234+ if data. len ( ) > self . avail_buffer_capacity ( ) {
235+ return Err ( io:: Error :: from_raw_os_error ( libc:: ENOBUFS ) ) ;
236+ }
237+
217238 if !self . is_loop ( ) {
218239 self . in_buffer . extend ( data) ;
219240 self . recv_data ( ) ?;
220241 }
221242 Ok ( ( ) )
222243 }
244+
245+ fn avail_buffer_capacity ( & mut self ) -> usize {
246+ FIFO_SIZE . checked_sub ( self . in_buffer . len ( ) ) . unwrap_or_else ( ||
247+ panic ! (
248+ "Errored out due to serial device buffer size greater than the maximum expected size: {} > {}." ,
249+ self . in_buffer. len( ) ,
250+ FIFO_SIZE
251+ )
252+ )
253+ }
223254}
224255
225256impl BusDevice for Serial {
@@ -277,7 +308,7 @@ mod tests {
277308 let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
278309 let serial_out = SharedBuffer :: new ( ) ;
279310
280- let mut serial = Serial :: new_out ( intr_evt, Box :: new ( serial_out. clone ( ) ) ) ;
311+ let mut serial = Serial :: new_out ( intr_evt, None , Box :: new ( serial_out. clone ( ) ) ) ;
281312
282313 serial. write ( u64:: from ( DATA ) , & [ b'x' , b'y' ] ) ;
283314 serial. write ( u64:: from ( DATA ) , & [ b'a' ] ) ;
@@ -289,14 +320,47 @@ mod tests {
289320 ) ;
290321 }
291322
323+ #[ test]
324+ fn test_serial_buffer_ready ( ) {
325+ let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
326+ let buffer_ready_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
327+ let serial_out = SharedBuffer :: new ( ) ;
328+
329+ let mut serial = Serial :: new_out (
330+ intr_evt,
331+ Some ( buffer_ready_evt. try_clone ( ) . unwrap ( ) ) ,
332+ Box :: new ( serial_out. clone ( ) ) ,
333+ ) ;
334+
335+ let byte = 5u8 ;
336+ serial. in_buffer . push_back ( byte) ;
337+ let mut _dummy = [ 0u8 ; 1 ] ;
338+ serial. read ( DATA as u64 , & mut _dummy) ;
339+ assert_eq ! ( serial. buffer_ready_evt. as_ref( ) . unwrap( ) . read( ) . unwrap( ) , 1 ) ;
340+
341+ let byte = 5u8 ;
342+ serial. in_buffer . push_back ( byte) ;
343+ serial. in_buffer . push_back ( byte) ;
344+ serial. in_buffer . push_back ( byte) ;
345+ serial. read ( DATA as u64 , & mut _dummy) ;
346+ assert ! ( serial. buffer_ready_evt. as_ref( ) . unwrap( ) . read( ) . is_err( ) ) ;
347+ serial. read ( DATA as u64 , & mut _dummy) ;
348+ assert ! ( serial. buffer_ready_evt. as_ref( ) . unwrap( ) . read( ) . is_err( ) ) ;
349+ serial. read ( DATA as u64 , & mut _dummy) ;
350+ assert_eq ! ( serial. buffer_ready_evt. as_ref( ) . unwrap( ) . read( ) . unwrap( ) , 1 ) ;
351+ }
352+
292353 #[ test]
293354 fn serial_input ( ) {
294355 let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
295356 let serial_out = SharedBuffer :: new ( ) ;
296357 let mut buffer: Vec < u8 > = Vec :: with_capacity ( 16 ) ;
297358
298- let mut serial =
299- Serial :: new_out ( intr_evt. try_clone ( ) . unwrap ( ) , Box :: new ( serial_out. clone ( ) ) ) ;
359+ let mut serial = Serial :: new_out (
360+ intr_evt. try_clone ( ) . unwrap ( ) ,
361+ None ,
362+ Box :: new ( serial_out. clone ( ) ) ,
363+ ) ;
300364
301365 // write 1 to the interrupt event fd, so that read doesn't block in case the event fd
302366 // counter doesn't change (for 0 it blocks)
@@ -325,12 +389,16 @@ mod tests {
325389 // check if reading from the largest u8 offset returns 0
326390 serial. read ( 0xff , & mut data[ ..] ) ;
327391 assert_eq ! ( data[ 0 ] , 0 ) ;
392+
393+ // Check if the serial buffer can hold more than FIFO_SIZE bytes.
394+ let bytes = vec ! [ 0u8 ; FIFO_SIZE + 1 ] ;
395+ serial. raw_input ( bytes. as_slice ( ) ) . unwrap_err ( ) ;
328396 }
329397
330398 #[ test]
331399 fn serial_thr ( ) {
332400 let intr_evt = EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ;
333- let mut serial = Serial :: new_sink ( intr_evt. try_clone ( ) . unwrap ( ) ) ;
401+ let mut serial = Serial :: new_sink ( intr_evt. try_clone ( ) . unwrap ( ) , None ) ;
334402
335403 // write 1 to the interrupt event fd, so that read doesn't block in case the event fd
336404 // counter doesn't change (for 0 it blocks)
@@ -348,7 +416,7 @@ mod tests {
348416
349417 #[ test]
350418 fn serial_dlab ( ) {
351- let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ) ;
419+ let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) , None ) ;
352420
353421 serial. write ( u64:: from ( LCR ) , & [ LCR_DLAB_BIT as u8 ] ) ;
354422 serial. write ( u64:: from ( DLAB_LOW ) , & [ 0x12 as u8 ] ) ;
@@ -365,7 +433,7 @@ mod tests {
365433
366434 #[ test]
367435 fn serial_modem ( ) {
368- let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ) ;
436+ let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) , None ) ;
369437
370438 serial. write ( u64:: from ( MCR ) , & [ MCR_LOOP_BIT as u8 ] ) ;
371439 serial. write ( u64:: from ( DATA ) , & [ b'a' ] ) ;
@@ -387,7 +455,7 @@ mod tests {
387455
388456 #[ test]
389457 fn serial_scratch ( ) {
390- let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ) ;
458+ let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) , None ) ;
391459
392460 serial. write ( u64:: from ( SCR ) , & [ 0x12 as u8 ] ) ;
393461
@@ -399,7 +467,7 @@ mod tests {
399467 #[ test]
400468 fn test_serial_data_len ( ) {
401469 const LEN : usize = 1 ;
402- let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) ) ;
470+ let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) , None ) ;
403471
404472 let missed_writes_before = METRICS . uart . missed_write_count . count ( ) ;
405473 // Trying to write data of length different than the one that we initialized the device with
@@ -414,4 +482,31 @@ mod tests {
414482 // metric stays the same.
415483 assert_eq ! ( missed_writes_before, missed_writes_after - 1 ) ;
416484 }
485+
486+ #[ test]
487+ fn test_serial_avail_buffer_capacity ( ) {
488+ let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) , None ) ;
489+
490+ let bytes = vec ! [ 0u8 ; FIFO_SIZE ] ;
491+ serial. in_buffer . extend ( bytes. clone ( ) ) ;
492+ assert_eq ! ( serial. avail_buffer_capacity( ) , 0 ) ;
493+
494+ let mut data = [ 0u8 ; 1 ] ;
495+ for i in 0 ..FIFO_SIZE {
496+ assert_eq ! ( serial. avail_buffer_capacity( ) , i) ;
497+ serial. read ( DATA as u64 , & mut data) ;
498+ }
499+ assert_eq ! ( serial. avail_buffer_capacity( ) , FIFO_SIZE ) ;
500+ }
501+
502+ #[ test]
503+ #[ should_panic]
504+ fn test_serial_avail_buffer_capacity_overflow ( ) {
505+ let mut serial = Serial :: new_sink ( EventFd :: new ( libc:: EFD_NONBLOCK ) . unwrap ( ) , None ) ;
506+
507+ let bytes = vec ! [ 0u8 ; FIFO_SIZE + 1 ] ;
508+ serial. in_buffer . extend ( bytes) ;
509+ // Panic since serial device buffer size its greater than what is expected.
510+ serial. avail_buffer_capacity ( ) ;
511+ }
417512}
0 commit comments