Module Name:    src
Committed By:   mrg
Date:           Mon Aug 24 23:32:07 UTC 2015

Modified Files:
        src/sys/arch/sparc64/dev: auxio.c

Log Message:
convert auxio(4) to use a mutex for exclusion (this existing code didn't
really work for MP systems, anyway -- it only went to splhigh.)

various cleanups:
- remove unused AUXIO_SBUS
- make most functions static
- introduce auxio_{read,write}_led() frontends
- avoid a potential NULL deref in auxio_fd_control()

the text is 32 bytes smaller.


To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/sparc64/dev/auxio.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/arch/sparc64/dev/auxio.c
diff -u src/sys/arch/sparc64/dev/auxio.c:1.23 src/sys/arch/sparc64/dev/auxio.c:1.24
--- src/sys/arch/sparc64/dev/auxio.c:1.23	Sat Jul 11 10:32:46 2015
+++ src/sys/arch/sparc64/dev/auxio.c	Mon Aug 24 23:32:07 2015
@@ -1,7 +1,7 @@
-/*	$NetBSD: auxio.c,v 1.23 2015/07/11 10:32:46 kamil Exp $	*/
+/*	$NetBSD: auxio.c,v 1.24 2015/08/24 23:32:07 mrg Exp $	*/
 
 /*
- * Copyright (c) 2000, 2001 Matthew R. Green
+ * Copyright (c) 2000, 2001, 2015 Matthew R. Green
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: auxio.c,v 1.23 2015/07/11 10:32:46 kamil Exp $");
+__KERNEL_RCSID(0, "$NetBSD: auxio.c,v 1.24 2015/08/24 23:32:07 mrg Exp $");
 
 #include "opt_auxio.h"
 
@@ -62,6 +62,8 @@ __KERNEL_RCSID(0, "$NetBSD: auxio.c,v 1.
 struct auxio_softc {
 	device_t		sc_dev;
 
+	kmutex_t		sc_lock;
+
 	/* parent's tag */
 	bus_space_tag_t		sc_tag;
 
@@ -73,18 +75,20 @@ struct auxio_softc {
 	bus_space_handle_t	sc_temp;
 
 	int			sc_flags;
-#define	AUXIO_LEDONLY		0x1
+#define	AUXIO_LEDONLY		0x1	// only sc_led is valid
 #define	AUXIO_EBUS		0x2
-#define	AUXIO_SBUS		0x4
 };
 
 #define	AUXIO_ROM_NAME		"auxio"
 
-void	auxio_attach_common(struct auxio_softc *);
-int	auxio_ebus_match(device_t, cfdata_t, void *);
-void	auxio_ebus_attach(device_t, device_t, void *);
-int	auxio_sbus_match(device_t, cfdata_t, void *);
-void	auxio_sbus_attach(device_t, device_t, void *);
+
+static uint32_t	auxio_read_led(struct auxio_softc *);
+static void	auxio_write_led(struct auxio_softc *, uint32_t);
+static void	auxio_attach_common(struct auxio_softc *);
+static int	auxio_ebus_match(device_t, cfdata_t, void *);
+static void	auxio_ebus_attach(device_t, device_t, void *);
+static int	auxio_sbus_match(device_t, cfdata_t, void *);
+static void	auxio_sbus_attach(device_t, device_t, void *);
 
 CFATTACH_DECL_NEW(auxio_ebus, sizeof(struct auxio_softc),
     auxio_ebus_match, auxio_ebus_attach, NULL, NULL);
@@ -94,6 +98,29 @@ CFATTACH_DECL_NEW(auxio_sbus, sizeof(str
 
 extern struct cfdriver auxio_cd;
 
+static __inline__ uint32_t
+auxio_read_led(struct auxio_softc *sc)
+{
+	uint32_t led;
+
+	if (sc->sc_flags & AUXIO_EBUS)
+		led = le32toh(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
+	else
+		led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
+
+	return led;
+}
+
+static __inline__ void
+auxio_write_led(struct auxio_softc *sc, uint32_t led)
+{
+
+	if (sc->sc_flags & AUXIO_EBUS)
+		bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
+	else
+		bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
+}
+
 #ifdef BLINK
 static callout_t blink_ch;
 static void auxio_blink(void *);
@@ -111,18 +138,11 @@ auxio_blink(void *x)
 	if (do_blink == 0)
 		return;
 
-	s = splhigh();
-	if (sc->sc_flags & AUXIO_EBUS)
-		led = le32toh(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
-	else
-		led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
-
+	mutex_enter(&sc->sc_lock);
+	led = auxio_read_led(sc);
 	led = led ^ AUXIO_LED_LED;
-	if (sc->sc_flags & AUXIO_EBUS)
-		bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
-	else
-		bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
-	splx(s);
+	auxio_write_led(sc, led);
+	mutex_exit(&sc->sc_lock);
 
 	/*
 	 * Blink rate is:
@@ -136,7 +156,7 @@ auxio_blink(void *x)
 }
 #endif
 
-void
+static void
 auxio_attach_common(struct auxio_softc *sc)
 {
 #ifdef BLINK
@@ -144,7 +164,8 @@ auxio_attach_common(struct auxio_softc *
 
 	/* only start one blinker */
 	if (do_once) {
-		callout_init(&blink_ch, 0);
+		mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_HIGH);
+		callout_init(&blink_ch, CALLOUT_MPSAFE);
 		auxio_blink(sc);
 		do_once = 0;
 	}
@@ -152,7 +173,7 @@ auxio_attach_common(struct auxio_softc *
 	printf("\n");
 }
 
-int
+static int
 auxio_ebus_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct ebus_attach_args *ea = aux;
@@ -160,7 +181,7 @@ auxio_ebus_match(device_t parent, cfdata
 	return (strcmp(AUXIO_ROM_NAME, ea->ea_name) == 0);
 }
 
-void
+static void
 auxio_ebus_attach(device_t parent, device_t self, void *aux)
 {
 	struct auxio_softc *sc = device_private(self);
@@ -174,13 +195,12 @@ auxio_ebus_attach(device_t parent, devic
 		return;
 	}
 
+	sc->sc_flags = AUXIO_EBUS;
 	if (ea->ea_nreg != 5) {
 		printf(": not 5 (%d) registers, only setting led",
 		    ea->ea_nreg);
-		sc->sc_flags = AUXIO_LEDONLY|AUXIO_EBUS;
+		sc->sc_flags |= AUXIO_LEDONLY;
 	} else if (ea->ea_nvaddr == 5) {
-		sc->sc_flags = AUXIO_EBUS;
-
 		sparc_promaddr_to_handle(sc->sc_tag, 
 			ea->ea_vaddr[1], &sc->sc_pci);
 		sparc_promaddr_to_handle(sc->sc_tag, 
@@ -190,7 +210,6 @@ auxio_ebus_attach(device_t parent, devic
 		sparc_promaddr_to_handle(sc->sc_tag, 
 			ea->ea_vaddr[4], &sc->sc_temp);
 	} else {
-		sc->sc_flags = AUXIO_EBUS;
 		bus_space_map(sc->sc_tag, EBUS_ADDR_FROM_REG(&ea->ea_reg[1]),
 			ea->ea_reg[1].size, 0, &sc->sc_pci);
 		bus_space_map(sc->sc_tag, EBUS_ADDR_FROM_REG(&ea->ea_reg[2]),
@@ -212,7 +231,7 @@ auxio_ebus_attach(device_t parent, devic
 	auxio_attach_common(sc);
 }
 
-int
+static int
 auxio_sbus_match(device_t parent, cfdata_t cf, void *aux)
 {
 	struct sbus_attach_args *sa = aux;
@@ -220,7 +239,7 @@ auxio_sbus_match(device_t parent, cfdata
 	return strcmp(AUXIO_ROM_NAME, sa->sa_name) == 0;
 }
 
-void
+static void
 auxio_sbus_attach(device_t parent, device_t self, void *aux)
 {
 	struct auxio_softc *sc = device_private(self);
@@ -241,7 +260,7 @@ auxio_sbus_attach(device_t parent, devic
 	}
 
 	/* sbus auxio only has one set of registers */
-	sc->sc_flags = AUXIO_LEDONLY|AUXIO_SBUS;
+	sc->sc_flags = AUXIO_LEDONLY;
 	if (sa->sa_npromvaddrs > 0) {
 		sbus_promaddr_to_handle(sc->sc_tag,
 			sa->sa_promvaddr, &sc->sc_led);
@@ -268,17 +287,15 @@ auxio_fd_control(u_int32_t bits)
 	 * We'll assume the floppy drive is tied to first auxio found.
 	 */
 	sc = device_lookup_private(&auxio_cd, 0);
-	if (sc->sc_flags & AUXIO_EBUS)
-		led = le32toh(bus_space_read_4(sc->sc_tag, sc->sc_led, 0));
-	else
-		led = bus_space_read_1(sc->sc_tag, sc->sc_led, 0);
+	if (!sc) {
+		return ENXIO;
+	}
 
+	mutex_enter(&sc->sc_lock);
+	led = auxio_read_led(sc);
 	led = (led & ~AUXIO_LED_FLOPPY_MASK) | bits;
-
-	if (sc->sc_flags & AUXIO_EBUS)
-		bus_space_write_4(sc->sc_tag, sc->sc_led, 0, htole32(led));
-	else
-		bus_space_write_1(sc->sc_tag, sc->sc_led, 0, led);
+	auxio_write_led(sc, led);
+	mutex_exit(&sc->sc_lock);
 
 	return 0;
 }

Reply via email to