@@ -168,6 +168,36 @@ static void h5_timed_event(unsigned long arg)
168168 hci_uart_tx_wakeup (hu );
169169}
170170
171+ static void h5_peer_reset (struct hci_uart * hu )
172+ {
173+ struct h5 * h5 = hu -> priv ;
174+ struct sk_buff * skb ;
175+ const unsigned char hard_err [] = { 0x10 , 0x01 , 0x00 };
176+
177+ BT_ERR ("Peer device has reset" );
178+
179+ h5 -> state = H5_UNINITIALIZED ;
180+
181+ del_timer (& h5 -> timer );
182+
183+ skb_queue_purge (& h5 -> rel );
184+ skb_queue_purge (& h5 -> unrel );
185+ skb_queue_purge (& h5 -> unack );
186+
187+ h5 -> tx_seq = 0 ;
188+ h5 -> tx_ack = 0 ;
189+
190+ skb = bt_skb_alloc (3 , GFP_ATOMIC );
191+ if (!skb )
192+ return ;
193+
194+ bt_cb (skb )-> pkt_type = HCI_EVENT_PKT ;
195+ memcpy (skb_put (skb , 3 ), hard_err , 3 );
196+
197+ /* Send Hardware Error to upper stack */
198+ hci_recv_frame (hu -> hdev , skb );
199+ }
200+
171201static int h5_open (struct hci_uart * hu )
172202{
173203 struct h5 * h5 ;
@@ -283,8 +313,12 @@ static void h5_handle_internal_rx(struct hci_uart *hu)
283313 conf_req [2 ] = h5_cfg_field (h5 );
284314
285315 if (memcmp (data , sync_req , 2 ) == 0 ) {
316+ if (h5 -> state == H5_ACTIVE )
317+ h5_peer_reset (hu );
286318 h5_link_control (hu , sync_rsp , 2 );
287319 } else if (memcmp (data , sync_rsp , 2 ) == 0 ) {
320+ if (h5 -> state == H5_ACTIVE )
321+ h5_peer_reset (hu );
288322 h5 -> state = H5_INITIALIZED ;
289323 h5_link_control (hu , conf_req , 3 );
290324 } else if (memcmp (data , conf_req , 2 ) == 0 ) {
0 commit comments