fiq_fsm: Use correct states when starting isoc OUT transfers (#1991)
authorP33M <P33M@users.noreply.github.com>
Thu, 4 May 2017 13:56:08 +0000 (14:56 +0100)
committerRaspbian kernel package updater <root@raspbian.org>
Sun, 8 Oct 2017 01:08:03 +0000 (01:08 +0000)
* fiq_fsm: Use correct states when starting isoc OUT transfers

In fiq_fsm_start_next_periodic() if an isochronous OUT transfer
was selected, no regard was given as to whether this was a single-packet
transfer or a multi-packet staged transfer.

For single-packet transfers, this had the effect of repeatedly sending
OUT packets with bogus data and lengths.

Eventually if the channel was repeatedly enabled enough times, this
would lock up the OTG core and no further bus transfers would happen.

Set the FSM state up properly if we select a single-packet transfer.

Fixes https://github.com/raspberrypi/linux/issues/1842

drivers/usb/host/dwc_otg/dwc_otg_fiq_fsm.c

index 9304279592cb5b388086ef91cb52f1e9f94868ce..208252645c09d1d17bf07673989f91b7f4b3ef7a 100644 (file)
@@ -491,7 +491,10 @@ static void notrace noinline fiq_fsm_start_next_periodic(struct fiq_state *st, i
                if (st->channel[n].fsm == FIQ_PER_ISO_OUT_PENDING) {
                        if (!fiq_fsm_tt_in_use(st, num_channels, n)) {
                                fiq_print(FIQDBG_INT, st, "NEXTISO ");
-                               st->channel[n].fsm = FIQ_PER_ISO_OUT_ACTIVE;
+                               if (st->channel[n].nrpackets == 1)
+                                       st->channel[n].fsm = FIQ_PER_ISO_OUT_LAST;
+                               else
+                                       st->channel[n].fsm = FIQ_PER_ISO_OUT_ACTIVE;
                                fiq_fsm_restart_channel(st, n, 0);
                                break;
                        }