+
+/*
+ * Reset driver after UBA init.
+ * Cancel software state of all pending transfers
+ * and restart all units and the controller.
+ */
+upreset()
+{
+ int unit;
+
+ printf(" up");
+ uptab.b_active = 0;
+ uptab.b_actf = uptab.b_actl = 0;
+ if (DK_N+NUP == DK_NMAX)
+ dk_busy &= ~(1<<(DK_N+NUP));
+ if (up_ubinfo) {
+ printf("<%d>", (up_ubinfo>>28)&0xf);
+ ubafree(up_ubinfo), up_ubinfo = 0;
+ }
+ UPADDR->upcs2 = CLR; /* clear controller */
+ DELAY(idelay);
+ for (unit = 0; unit < NUP; unit++) {
+ uputab[unit].b_active = 0;
+ (void) upustart(unit);
+ }
+ (void) upstart();
+}
+
+/*
+ * Wake up every second and if an interrupt is pending
+ * but nothing has happened increment a counter.
+ * If nothing happens for 20 seconds, reset the controller
+ * and begin anew.
+ */
+upwatch()
+{
+ int i;
+
+ timeout((caddr_t)upwatch, 0, HZ);
+ if (uptab.b_active == 0) {
+ for (i = 0; i < NUP; i++)
+ if (uputab[i].b_active)
+ goto active;
+ up_wticks = 0; /* idling */
+ return;
+ }
+active:
+ up_wticks++;
+ if (up_wticks >= 20) {
+ up_wticks = 0;
+ printf("LOST INTERRUPT RESET");
+ upreset();
+ printf("\n");
+ }
+}