/// Handle a recieved byte, and optionally return a byte to be sent to the device
Handle a recieved byte, and optionally return a byte to be sent to the device
Handle a recieved byte and optionally return a byte to be sent to the device
pub fn recv_byte(&mut self, byte: u8) -> Option<u8> {
		let (rv, new_state): (Option<_>,Option<_>) = match *self
			{
			PS2Dev::None =>
				// TODO: Clean this section up, the OSDev.org wiki is a little hazy on the ordering
				if byte == 0xFA {
					(None, None)
				}
				else if byte == 0xAA {
					// Send 0xF5 "Disable Scanning" and wait for ACK
					(Some(0xF5), Some(PS2Dev::Enumerating(EnumWaitState::DSAck)))
				}
				else {
					(None, None)
				},
			PS2Dev::Unknown => (None, None),
			PS2Dev::Enumerating(state) => match state
				{
				EnumWaitState::DSAck =>
					if byte == 0xFA {
						// Send 0xF2 "Identify"
						(Some(0xF2), Some(PS2Dev::Enumerating(EnumWaitState::IdentAck)))
					}
					else if byte == 0x00 {
						// XXX: Ignore spurrious NUL byte
						(None, None)
					}
					else {
						(None, Some(PS2Dev::Unknown))
					},
				EnumWaitState::IdentAck =>
					if byte == 0xFA {
						// TODO: Start a timeout if not enough bytes are sent
						(None, Some(PS2Dev::Enumerating(EnumWaitState::IdentB1)))
					}
					else {
						(None, Some(PS2Dev::Unknown))
					},
				EnumWaitState::IdentB1 =>
					match byte
					{
					0x00 => {
						let mut res = Self::new_mouse(&mouse_std);
						*MOUSE_DEV.lock() = res.1;
						res
						},
					0x03 => {
						let res = Self::new_mouse(&mouse_scr);
						*MOUSE_DEV.lock() = res.1;
						res
						},
					0x04 => {
						let res = Self::new_mouse(&mouse_qbt);
						*MOUSE_DEV.lock() = res.1;
						res
						},
					0xAB => (None, Some(PS2Dev::Enumerating(EnumWaitState::IdentB2(byte)))),
					_ => {
						debug!("Unknown PS/2 device {:#02x}", byte);
						(None, Some(PS2Dev::Unknown))
						},
					},
				EnumWaitState::IdentB2(b1) =>
					match (b1,byte)
					{
					(0xAB, 0x83) => {
						let res = Self::new_keyboard(&kbd_MF2);
						*KBD_DEV.lock() = res.1;
						res
						},
					(0xAB, 0x41) => {
						let res = Self::new_keyboard(&kbd_MF2Emul);
						*KBD_DEV.lock() = res.1;
						res
						},
					(0xAB, 0xC1) => {
						let res = Self::new_keyboard(&kbd_MF2Emul);
						*KBD_DEV.lock() = res.1;
						res
						},
					_ => {
						debug!("Unknown PS/2 device {:#02x} {:#02x}", b1, byte);
						(None, Some(PS2Dev::Unknown))
						},
					},
				},
			PS2Dev::Keyboard(ref mut dev) => {
				(dev.recv_byte(byte), None)
				},
			PS2Dev::Mouse(ref mut dev) => {
				(dev.recv_byte(byte), None)
				},
			};
		if let Some(ns) = new_state
		{
			debug!("Byte {:#02x} caused State transition {:?} to {:?}", byte, *self, ns);
			*self = ns;
		}
		rv
	}
pub fn recv_byte ( & mut self , byte : u8 ) -> Option < u8 > { let ( rv , new_state ) : ( Option < _ > , Option < _ > ) = match * self { PS2Dev :: None => // TODO: Clean this section up, the OSDev.org wiki is a little hazy on the ordering if byte == 0xFA { ( None , None ) } else if byte == 0xAA { // Send 0xF5 "Disable Scanning" and wait for ACK ( Some ( 0xF5 ) , Some ( PS2Dev :: Enumerating ( EnumWaitState :: DSAck ) ) ) } else { ( None , None ) } , PS2Dev :: Unknown => ( None , None ) , PS2Dev :: Enumerating ( state ) => match state { EnumWaitState :: DSAck => if byte == 0xFA { // Send 0xF2 "Identify" ( Some ( 0xF2 ) , Some ( PS2Dev :: Enumerating ( EnumWaitState :: IdentAck ) ) ) } else if byte == 0x00 { // XXX: Ignore spurrious NUL byte ( None , None ) } else { ( None , Some ( PS2Dev :: Unknown ) ) } , EnumWaitState :: IdentAck => if byte == 0xFA { // TODO: Start a timeout if not enough bytes are sent ( None , Some ( PS2Dev :: Enumerating ( EnumWaitState :: IdentB1 ) ) ) } else { ( None , Some ( PS2Dev :: Unknown ) ) } , EnumWaitState :: IdentB1 => match byte { 0x00 => { let mut res = Self :: new_mouse ( & mouse_std ) ; * MOUSE_DEV . lock ( ) = res . 1 ; res } , 0x03 => { let res = Self :: new_mouse ( & mouse_scr ) ; * MOUSE_DEV . lock ( ) = res . 1 ; res } , 0x04 => { let res = Self :: new_mouse ( & mouse_qbt ) ; * MOUSE_DEV . lock ( ) = res . 1 ; res } , 0xAB => ( None , Some ( PS2Dev :: Enumerating ( EnumWaitState :: IdentB2 ( byte ) ) ) ) , _ => { debug ! ( " " byte ) ; ( None , Some ( PS2Dev :: Unknown ) ) } , } , EnumWaitState :: IdentB2 ( b1 ) => match ( b1 , byte ) { ( 0xAB , 0x83 ) => { let res = Self :: new_keyboard ( & kbd_MF2 ) ; * KBD_DEV . lock ( ) = res . 1 ; res } , ( 0xAB , 0x41 ) => { let res = Self :: new_keyboard ( & kbd_MF2Emul ) ; * KBD_DEV . lock ( ) = res . 1 ; res } , ( 0xAB , 0xC1 ) => { let res = Self :: new_keyboard ( & kbd_MF2Emul ) ; * KBD_DEV . lock ( ) = res . 1 ; res } , _ => { debug ! ( " " b1 byte ) ; ( None , Some ( PS2Dev :: Unknown ) ) } , } , } , PS2Dev :: Keyboard ( ref mut dev ) => { ( dev . recv_byte ( byte ) , None ) } , PS2Dev :: Mouse ( ref mut dev ) => { ( dev . recv_byte ( byte ) , None ) } , } ; if let Some ( ns ) = new_state { debug ! ( " " byte self ns ) ; * self = ns ; } rv }
Handle a recieved byte, and optionally return a byte to be sent to the device
Handle a recieved byte and optionally return a byte to be sent to the device
&mut self
byte
u8