]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - net/irda/irlap_event.c
PM: Suspend/hibernation debug documentation update (rev. 2)
[linux-2.6-omap-h63xx.git] / net / irda / irlap_event.c
index 7b6433fe1dc23d4bacbff6eed1efd7937d201583..6af86eba7463259522b8530dfbf361e4624d464b 100644 (file)
@@ -19,7 +19,7 @@
  *     published by the Free Software Foundation; either version 2 of
  *     the License, or (at your option) any later version.
  *
- *     Neither Dag Brattli nor University of Tromsø admit liability nor
+ *     Neither Dag Brattli nor University of Tromsø admit liability nor
  *     provide warranty for any of this software. This material is
  *     provided "AS-IS" and at no charge.
  *
@@ -316,23 +316,6 @@ void irlap_do_event(struct irlap_cb *self, IRLAP_EVENT event,
        }
 }
 
-/*
- * Function irlap_next_state (self, state)
- *
- *    Switches state and provides debug information
- *
- */
-static inline void irlap_next_state(struct irlap_cb *self, IRLAP_STATE state)
-{
-       /*
-       if (!self || self->magic != LAP_MAGIC)
-               return;
-
-       IRDA_DEBUG(4, "next LAP state = %s\n", irlap_state[state]);
-       */
-       self->state = state;
-}
-
 /*
  * Function irlap_state_ndm (event, skb, frame)
  *
@@ -590,7 +573,7 @@ static int irlap_state_query(struct irlap_cb *self, IRLAP_EVENT event,
                if (!self->discovery_log) {
                        IRDA_WARNING("%s: discovery log is gone! "
                                     "maybe the discovery timeout has been set"
-                                    " to short?\n", __FUNCTION__);
+                                    " too short?\n", __FUNCTION__);
                        break;
                }
                hashbin_insert(self->discovery_log,
@@ -1086,7 +1069,6 @@ static int irlap_state_xmit_p(struct irlap_cb *self, IRLAP_EVENT event,
                        } else {
                                /* Final packet of window */
                                irlap_send_data_primary_poll(self, skb);
-                               irlap_next_state(self, LAP_NRM_P);
 
                                /*
                                 * Make sure state machine does not try to send
@@ -1217,6 +1199,19 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
 
        switch (event) {
        case RECV_I_RSP: /* Optimize for the common case */
+               if (unlikely(skb->len <= LAP_ADDR_HEADER + LAP_CTRL_HEADER)) {
+                       /*
+                        * Input validation check: a stir4200/mcp2150
+                        * combination sometimes results in an empty i:rsp.
+                        * This makes no sense; we can just ignore the frame
+                        * and send an rr:cmd immediately. This happens before
+                        * changing nr or ns so triggers a retransmit
+                        */
+                       irlap_wait_min_turn_around(self, &self->qos_tx);
+                       irlap_send_rr_frame(self, CMD_FRAME);
+                       /* Keep state */
+                       break;
+               }
                /* FIXME: must check for remote_busy below */
 #ifdef CONFIG_IRDA_FAST_RR
                /*
@@ -1436,14 +1431,14 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
                 */
                self->remote_busy = FALSE;
 
+               /* Stop final timer */
+               del_timer(&self->final_timer);
+
                /*
                 *  Nr as expected?
                 */
                ret = irlap_validate_nr_received(self, info->nr);
                if (ret == NR_EXPECTED) {
-                       /* Stop final timer */
-                       del_timer(&self->final_timer);
-
                        /* Update Nr received */
                        irlap_update_nr_received(self, info->nr);
 
@@ -1475,14 +1470,12 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
 
                        /* Resend rejected frames */
                        irlap_resend_rejected_frames(self, CMD_FRAME);
-
-                       /* Final timer ??? Jean II */
+                       irlap_start_final_timer(self, self->final_timeout * 2);
 
                        irlap_next_state(self, LAP_NRM_P);
                } else if (ret == NR_INVALID) {
                        IRDA_DEBUG(1, "%s(), Received RR with "
                                   "invalid nr !\n", __FUNCTION__);
-                       del_timer(&self->final_timer);
 
                        irlap_next_state(self, LAP_RESET_WAIT);
 
@@ -1534,9 +1527,15 @@ static int irlap_state_nrm_p(struct irlap_cb *self, IRLAP_EVENT event,
 
                /* N2 is the disconnect timer. Until we reach it, we retry */
                if (self->retry_count < self->N2) {
-                       /* Retry sending the pf bit to the secondary */
-                       irlap_wait_min_turn_around(self, &self->qos_tx);
-                       irlap_send_rr_frame(self, CMD_FRAME);
+                       if (skb_peek(&self->wx_list) == NULL) {
+                               /* Retry sending the pf bit to the secondary */
+                               IRDA_DEBUG(4, "nrm_p: resending rr");
+                               irlap_wait_min_turn_around(self, &self->qos_tx);
+                               irlap_send_rr_frame(self, CMD_FRAME);
+                       } else {
+                               IRDA_DEBUG(4, "nrm_p: resend frames");
+                               irlap_resend_rejected_frames(self, CMD_FRAME);
+                       }
 
                        irlap_start_final_timer(self, self->final_timeout);
                        self->retry_count++;