Tue Mar 17 19:38:34 2009 UTC ()
Handle child-detachment by NULL'ing the child pointer so that
auich_detach() does not subsequently dereference a dangling pointer.


(dyoung)
diff -r1.128 -r1.129 src/sys/dev/pci/auich.c

cvs diff -r1.128 -r1.129 src/sys/dev/pci/auich.c (expand / switch to unified diff)

--- src/sys/dev/pci/auich.c 2008/11/08 00:26:35 1.128
+++ src/sys/dev/pci/auich.c 2009/03/17 19:38:34 1.129
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: auich.c,v 1.128 2008/11/08 00:26:35 dyoung Exp $ */ 1/* $NetBSD: auich.c,v 1.129 2009/03/17 19:38:34 dyoung Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2000, 2004, 2005 The NetBSD Foundation, Inc. 4 * Copyright (c) 2000, 2004, 2005 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe and by Charles M. Hannum. 8 * by Jason R. Thorpe and by Charles M. Hannum.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -101,27 +101,27 @@ @@ -101,27 +101,27 @@
101 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24674.pdf 101 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/24674.pdf
102 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25720.pdf 102 * http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/25720.pdf
103 * 103 *
104 * TODO: 104 * TODO:
105 * - Add support for the dedicated microphone input. 105 * - Add support for the dedicated microphone input.
106 * 106 *
107 * NOTE: 107 * NOTE:
108 * - The 440MX B-stepping at running 100MHz has a hardware erratum. 108 * - The 440MX B-stepping at running 100MHz has a hardware erratum.
109 * It causes PCI master abort and hangups until cold reboot. 109 * It causes PCI master abort and hangups until cold reboot.
110 * http://www.intel.com/design/chipsets/specupdt/245051.htm 110 * http://www.intel.com/design/chipsets/specupdt/245051.htm
111 */ 111 */
112 112
113#include <sys/cdefs.h> 113#include <sys/cdefs.h>
114__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.128 2008/11/08 00:26:35 dyoung Exp $"); 114__KERNEL_RCSID(0, "$NetBSD: auich.c,v 1.129 2009/03/17 19:38:34 dyoung Exp $");
115 115
116#include <sys/param.h> 116#include <sys/param.h>
117#include <sys/systm.h> 117#include <sys/systm.h>
118#include <sys/kernel.h> 118#include <sys/kernel.h>
119#include <sys/malloc.h> 119#include <sys/malloc.h>
120#include <sys/device.h> 120#include <sys/device.h>
121#include <sys/fcntl.h> 121#include <sys/fcntl.h>
122#include <sys/proc.h> 122#include <sys/proc.h>
123#include <sys/sysctl.h> 123#include <sys/sysctl.h>
124 124
125#include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 125#include <uvm/uvm_extern.h> /* for PAGE_SIZE */
126 126
127#include <dev/pci/pcidevs.h> 127#include <dev/pci/pcidevs.h>
@@ -231,31 +231,33 @@ struct auich_softc { @@ -231,31 +231,33 @@ struct auich_softc {
231#ifdef AUICH_DEBUG 231#ifdef AUICH_DEBUG
232#define DPRINTF(l,x) do { if (auich_debug & (l)) printf x; } while(0) 232#define DPRINTF(l,x) do { if (auich_debug & (l)) printf x; } while(0)
233int auich_debug = 0xfffe; 233int auich_debug = 0xfffe;
234#define ICH_DEBUG_CODECIO 0x0001 234#define ICH_DEBUG_CODECIO 0x0001
235#define ICH_DEBUG_DMA 0x0002 235#define ICH_DEBUG_DMA 0x0002
236#define ICH_DEBUG_INTR 0x0004 236#define ICH_DEBUG_INTR 0x0004
237#else 237#else
238#define DPRINTF(x,y) /* nothing */ 238#define DPRINTF(x,y) /* nothing */
239#endif 239#endif
240 240
241static int auich_match(device_t, cfdata_t, void *); 241static int auich_match(device_t, cfdata_t, void *);
242static void auich_attach(device_t, device_t, void *); 242static void auich_attach(device_t, device_t, void *);
243static int auich_detach(device_t, int); 243static int auich_detach(device_t, int);
 244static void auich_childdet(device_t, device_t);
244static int auich_activate(device_t, enum devact); 245static int auich_activate(device_t, enum devact);
245static int auich_intr(void *); 246static int auich_intr(void *);
246 247
247CFATTACH_DECL_NEW(auich, sizeof(struct auich_softc), 248CFATTACH_DECL2_NEW(auich, sizeof(struct auich_softc),
248 auich_match, auich_attach, auich_detach, auich_activate); 249 auich_match, auich_attach, auich_detach, auich_activate, NULL,
 250 auich_childdet);
249 251
250static int auich_open(void *, int); 252static int auich_open(void *, int);
251static void auich_close(void *); 253static void auich_close(void *);
252static int auich_query_encoding(void *, struct audio_encoding *); 254static int auich_query_encoding(void *, struct audio_encoding *);
253static int auich_set_params(void *, int, int, audio_params_t *, 255static int auich_set_params(void *, int, int, audio_params_t *,
254 audio_params_t *, stream_filter_list_t *, 256 audio_params_t *, stream_filter_list_t *,
255 stream_filter_list_t *); 257 stream_filter_list_t *);
256static int auich_round_blocksize(void *, int, int, const audio_params_t *); 258static int auich_round_blocksize(void *, int, int, const audio_params_t *);
257static void auich_halt_pipe(struct auich_softc *, int); 259static void auich_halt_pipe(struct auich_softc *, int);
258static int auich_halt_output(void *); 260static int auich_halt_output(void *);
259static int auich_halt_input(void *); 261static int auich_halt_input(void *);
260static int auich_getdev(void *, struct audio_device *); 262static int auich_getdev(void *, struct audio_device *);
261static int auich_set_port(void *, mixer_ctrl_t *); 263static int auich_set_port(void *, mixer_ctrl_t *);
@@ -680,26 +682,35 @@ auich_activate(device_t self, enum devac @@ -680,26 +682,35 @@ auich_activate(device_t self, enum devac
680 int ret; 682 int ret;
681 683
682 ret = 0; 684 ret = 0;
683 switch (act) { 685 switch (act) {
684 case DVACT_ACTIVATE: 686 case DVACT_ACTIVATE:
685 return EOPNOTSUPP; 687 return EOPNOTSUPP;
686 case DVACT_DEACTIVATE: 688 case DVACT_DEACTIVATE:
687 if (sc->sc_audiodev != NULL) 689 if (sc->sc_audiodev != NULL)
688 ret = config_deactivate(sc->sc_audiodev); 690 ret = config_deactivate(sc->sc_audiodev);
689 return ret; 691 return ret;
690 } 692 }
691 return EOPNOTSUPP; 693 return EOPNOTSUPP;
692} 694}
 695
 696static void
 697auich_childdet(device_t self, device_t child)
 698{
 699 struct auich_softc *sc = device_private(self);
 700
 701 KASSERT(sc->sc_audiodev == child);
 702 sc->sc_audiodev = NULL;
 703}
693 704
694static int 705static int
695auich_detach(device_t self, int flags) 706auich_detach(device_t self, int flags)
696{ 707{
697 struct auich_softc *sc = device_private(self); 708 struct auich_softc *sc = device_private(self);
698 709
699 /* audio */ 710 /* audio */
700 if (sc->sc_audiodev != NULL) 711 if (sc->sc_audiodev != NULL)
701 config_detach(sc->sc_audiodev, flags); 712 config_detach(sc->sc_audiodev, flags);
702 713
703 /* sysctl */ 714 /* sysctl */
704 sysctl_teardown(&sc->sc_log); 715 sysctl_teardown(&sc->sc_log);
705 716