Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Dec 2012 10:46:58 +0000 (UTC)
From:      Alexander Motin <mav@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r244250 - projects/calloutng/sys/dev/atkbdc
Message-ID:  <201212151046.qBFAkwdB040142@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mav
Date: Sat Dec 15 10:46:57 2012
New Revision: 244250
URL: http://svnweb.freebsd.org/changeset/base/244250

Log:
  Switch atkbd watchdog from timeout() to callout_reset_flags() and specify
  that precision is not important there.

Modified:
  projects/calloutng/sys/dev/atkbdc/atkbd.c
  projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c

Modified: projects/calloutng/sys/dev/atkbdc/atkbd.c
==============================================================================
--- projects/calloutng/sys/dev/atkbdc/atkbd.c	Sat Dec 15 10:44:16 2012	(r244249)
+++ projects/calloutng/sys/dev/atkbdc/atkbd.c	Sat Dec 15 10:46:57 2012	(r244250)
@@ -62,7 +62,6 @@ __FBSDID("$FreeBSD$");
 #include <dev/atkbdc/atkbdreg.h>
 #include <dev/atkbdc/atkbdcreg.h>
 
-static timeout_t	atkbd_timeout;
 static void		atkbd_shutdown_final(void *v);
 
 int
@@ -114,12 +113,6 @@ atkbd_attach_unit(int unit, keyboard_t *
 		return error;
 #endif
 
-	/*
-	 * This is a kludge to compensate for lost keyboard interrupts.
-	 * A similar code used to be in syscons. See below. XXX
-	 */
-	atkbd_timeout(*kbd);
-
 	if (bootverbose)
 		(*sw->diag)(*kbd, bootverbose);
 
@@ -129,53 +122,6 @@ atkbd_attach_unit(int unit, keyboard_t *
 	return 0;
 }
 
-static void
-atkbd_timeout(void *arg)
-{
-	keyboard_t *kbd;
-	int s;
-
-	/*
-	 * The original text of the following comments are extracted 
-	 * from syscons.c (1.287)
-	 * 
-	 * With release 2.1 of the Xaccel server, the keyboard is left
-	 * hanging pretty often. Apparently an interrupt from the
-	 * keyboard is lost, and I don't know why (yet).
-	 * This ugly hack calls the low-level interrupt routine if input
-	 * is ready for the keyboard and conveniently hides the problem. XXX
-	 *
-	 * Try removing anything stuck in the keyboard controller; whether
-	 * it's a keyboard scan code or mouse data. The low-level
-	 * interrupt routine doesn't read the mouse data directly, 
-	 * but the keyboard controller driver will, as a side effect.
-	 */
-	/*
-	 * And here is bde's original comment about this:
-	 *
-	 * This is necessary to handle edge triggered interrupts - if we
-	 * returned when our IRQ is high due to unserviced input, then there
-	 * would be no more keyboard IRQs until the keyboard is reset by
-	 * external powers.
-	 *
-	 * The keyboard apparently unwedges the irq in most cases.
-	 */
-	s = spltty();
-	kbd = (keyboard_t *)arg;
-	if (kbdd_lock(kbd, TRUE)) {
-		/*
-		 * We have seen the lock flag is not set. Let's reset
-		 * the flag early, otherwise the LED update routine fails
-		 * which may want the lock during the interrupt routine.
-		 */
-		kbdd_lock(kbd, FALSE);
-		if (kbdd_check_char(kbd))
-			kbdd_intr(kbd, NULL);
-	}
-	splx(s);
-	timeout(atkbd_timeout, arg, hz/10);
-}
-
 /* LOW-LEVEL */
 
 #define ATKBD_DEFAULT	0

Modified: projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c
==============================================================================
--- projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c	Sat Dec 15 10:44:16 2012	(r244249)
+++ projects/calloutng/sys/dev/atkbdc/atkbd_atkbdc.c	Sat Dec 15 10:46:57 2012	(r244250)
@@ -47,6 +47,8 @@ __FBSDID("$FreeBSD$");
 typedef struct {
 	struct resource	*intr;
 	void		*ih;
+	keyboard_t	*kbd;
+	struct callout	callout;
 } atkbd_softc_t;
 
 static devclass_t	atkbd_devclass;
@@ -56,6 +58,7 @@ static int	atkbdprobe(device_t dev);
 static int	atkbdattach(device_t dev);
 static int	atkbdresume(device_t dev);
 static void	atkbdintr(void *arg);
+static timeout_t atkbdtimeout;
 
 static device_method_t atkbd_methods[] = {
 	DEVMETHOD(device_identify,	atkbdidentify),
@@ -113,18 +116,18 @@ static int
 atkbdattach(device_t dev)
 {
 	atkbd_softc_t *sc;
-	keyboard_t *kbd;
 	u_long irq;
 	int flags;
 	int rid;
 	int error;
 
 	sc = device_get_softc(dev);
+	callout_init(&sc->callout, TRUE);
 
 	rid = KBDC_RID_KBD;
 	irq = bus_get_resource_start(dev, SYS_RES_IRQ, rid);
 	flags = device_get_flags(dev);
-	error = atkbd_attach_unit(device_get_unit(dev), &kbd,
+	error = atkbd_attach_unit(device_get_unit(dev), &sc->kbd,
 				  device_get_unit(device_get_parent(dev)),
 				  irq, flags);
 	if (error)
@@ -135,11 +138,17 @@ atkbdattach(device_t dev)
 	if (sc->intr == NULL)
 		return ENXIO;
 	error = bus_setup_intr(dev, sc->intr, INTR_TYPE_TTY, NULL, atkbdintr,
-			       kbd, &sc->ih);
-	if (error)
+			       sc->kbd, &sc->ih);
+	if (error) {
 		bus_release_resource(dev, SYS_RES_IRQ, rid, sc->intr);
+		return (error);
+	}
 
-	return error;
+	/*
+	 * This is a kludge to compensate for lost keyboard interrupts.
+	 */
+	atkbdtimeout(dev);
+	return (0);
 }
 
 static int
@@ -150,16 +159,14 @@ atkbdresume(device_t dev)
 	int args[2];
 
 	sc = device_get_softc(dev);
-	kbd = kbd_get_keyboard(kbd_find_keyboard(ATKBD_DRIVER_NAME,
-						 device_get_unit(dev)));
-	if (kbd) {
-		kbd->kb_flags &= ~KB_INITIALIZED;
-		args[0] = device_get_unit(device_get_parent(dev));
-		args[1] = rman_get_start(sc->intr);
-		kbdd_init(kbd, device_get_unit(dev), &kbd, args,
-		    device_get_flags(dev));
-		kbdd_clear_state(kbd);
-	}
+	kbd = sc->kbd;
+	kbd->kb_flags &= ~KB_INITIALIZED;
+	args[0] = device_get_unit(device_get_parent(dev));
+	args[1] = rman_get_start(sc->intr);
+	kbdd_init(kbd, device_get_unit(dev), &kbd, args,
+	    device_get_flags(dev));
+	kbdd_clear_state(kbd);
+
 	return 0;
 }
 
@@ -172,4 +179,26 @@ atkbdintr(void *arg)
 	kbdd_intr(kbd, NULL);
 }
 
+static void
+atkbdtimeout(void *arg)
+{
+	device_t dev = (device_t)arg;
+	atkbd_softc_t *sc;
+	keyboard_t *kbd;
+
+	sc = device_get_softc(dev);
+	kbd = sc->kbd;
+	if (kbdd_lock(kbd, TRUE)) {
+		/*
+		 * We have seen the lock flag is not set. Let's reset
+		 * the flag early, otherwise the LED update routine fails
+		 * which may want the lock during the interrupt routine.
+		 */
+		kbdd_lock(kbd, FALSE);
+		if (kbdd_check_char(kbd))
+			kbdd_intr(kbd, NULL);
+	}
+	callout_reset_flags(&sc->callout, hz, atkbdtimeout, dev, C_PRELSET(0));
+}
+
 DRIVER_MODULE(atkbd, atkbdc, atkbd_driver, atkbd_devclass, 0, 0);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201212151046.qBFAkwdB040142>