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; }