Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/pci add detach support



details:   https://anonhg.NetBSD.org/src/rev/9c6802b95f59
branches:  trunk
changeset: 767304:9c6802b95f59
user:      jmcneill <jmcneill%NetBSD.org@localhost>
date:      Fri Jul 15 00:21:26 2011 +0000

description:
add detach support

diffstat:

 sys/dev/pci/cxdtv.c    |  91 +++++++++++++++++++++++++++++++++++++++++++------
 sys/dev/pci/cxdtvvar.h |   4 +-
 2 files changed, 83 insertions(+), 12 deletions(-)

diffs (175 lines):

diff -r 7c80d6caf3a9 -r 9c6802b95f59 sys/dev/pci/cxdtv.c
--- a/sys/dev/pci/cxdtv.c       Thu Jul 14 23:50:12 2011 +0000
+++ b/sys/dev/pci/cxdtv.c       Fri Jul 15 00:21:26 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cxdtv.c,v 1.2 2011/07/14 23:47:45 jmcneill Exp $ */
+/* $NetBSD: cxdtv.c,v 1.3 2011/07/15 00:21:26 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2008, 2011 Jonathan A. Kollasch
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cxdtv.c,v 1.2 2011/07/14 23:47:45 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cxdtv.c,v 1.3 2011/07/15 00:21:26 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -65,6 +65,7 @@
 static int cxdtv_match(struct device *, struct cfdata *, void *);
 static void cxdtv_attach(struct device *, struct device *, void *);
 static int cxdtv_detach(struct device *, int);
+static void cxdtv_childdet(struct device *, struct device *);
 static int cxdtv_intr(void *);
 
 static bool cxdtv_resume(device_t, const pmf_qual_t *);
@@ -90,6 +91,7 @@
 static int     cxdtv_risc_field(struct cxdtv_softc *, uint32_t *, uint32_t);
 
 static int     cxdtv_mpeg_attach(struct cxdtv_softc *);
+static int     cxdtv_mpeg_detach(struct cxdtv_softc *, int flags);
 static int     cxdtv_mpeg_intr(struct cxdtv_softc *);
 static int     cxdtv_mpeg_reset(struct cxdtv_softc *);
 
@@ -127,8 +129,8 @@
        },
 };
 
-CFATTACH_DECL_NEW(cxdtv, sizeof(struct cxdtv_softc),
-    cxdtv_match, cxdtv_attach, cxdtv_detach, NULL);
+CFATTACH_DECL2_NEW(cxdtv, sizeof(struct cxdtv_softc),
+    cxdtv_match, cxdtv_attach, cxdtv_detach, NULL, NULL, cxdtv_childdet);
 
 static int
 cxdtv_match(device_t parent, cfdata_t match, void *aux)
@@ -164,6 +166,7 @@
        sc = device_private(self);
 
        sc->sc_dev = self;
+       sc->sc_pc = pa->pa_pc;
 
        aprint_naive("\n");
 
@@ -249,7 +252,33 @@
 static int
 cxdtv_detach(device_t self, int flags)
 {
-       return EBUSY;
+       struct cxdtv_softc *sc = device_private(self);
+       int error;
+
+       error = cxdtv_mpeg_detach(sc, flags);
+       if (error)
+               return error;
+
+       if (sc->sc_ih)
+               pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
+
+       if (sc->sc_mems)
+               bus_space_unmap(sc->sc_memt, sc->sc_memh, sc->sc_mems);
+
+       mutex_destroy(&sc->sc_i2c_buslock);
+       mutex_destroy(&sc->sc_delaylock);
+       cv_destroy(&sc->sc_delaycv);
+
+       return 0;
+}
+
+static void
+cxdtv_childdet(device_t self, device_t child)
+{
+       struct cxdtv_softc *sc = device_private(self);
+
+       if (child == sc->sc_dtvdev)
+               sc->sc_dtvdev = NULL;
 }
 
 static bool
@@ -463,6 +492,50 @@
        return (sc->sc_dtvdev != NULL);
 }
 
+int
+cxdtv_mpeg_detach(struct cxdtv_softc *sc, int flags)
+{
+       int error = 0;
+
+       if (sc->sc_dtvdev) {
+               error = config_detach(sc->sc_dtvdev, flags);
+               if (error)
+                       return error;
+       }
+
+       if (sc->sc_demod) {
+               switch (sc->sc_board->cb_demod) {
+               case CXDTV_DEMOD_NXT2004:
+                       nxt2k_close(sc->sc_demod);
+                       break;
+               case CXDTV_DEMOD_LG3303:
+                       lg3303_close(sc->sc_demod);
+                       break;
+               default:
+                       break;
+               }
+               sc->sc_demod = NULL;
+       }
+       if (sc->sc_tuner) {
+               switch (sc->sc_board->cb_tuner) {
+               case CXDTV_TUNER_PLL:
+                       tvpll_close(sc->sc_tuner);
+                       break;
+               default:
+                       break;
+               }
+               sc->sc_tuner = NULL;
+       }
+
+       if (sc->sc_riscbuf) {
+               kmem_free(sc->sc_riscbuf, sc->sc_riscbufsz);
+               sc->sc_riscbuf = NULL;
+               sc->sc_riscbufsz = 0;
+       }
+
+       return error;
+}
+
 static void
 cxdtv_dtv_get_devinfo(void *priv, struct dvb_frontend_info *info)
 {
@@ -1076,15 +1149,11 @@
 
        val &= ~1;
        bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_GP0_IO, val);
-       mutex_enter(&sc->sc_delaylock);
-       cv_timedwait(&sc->sc_delaycv, &sc->sc_delaylock, mstohz(10));
-       mutex_exit(&sc->sc_delaylock);
+       delay(100000);
 
        val |= 1;
        bus_space_write_4(sc->sc_memt, sc->sc_memh, CXDTV_GP0_IO, val);
-       mutex_enter(&sc->sc_delaylock);
-       cv_timedwait(&sc->sc_delaycv, &sc->sc_delaylock, mstohz(15));
-       mutex_exit(&sc->sc_delaylock);
+       delay(200000);
 }
 
 MODULE(MODULE_CLASS_DRIVER, cxdtv, "dtv,tvpll,nxt2k,lg3303");
diff -r 7c80d6caf3a9 -r 9c6802b95f59 sys/dev/pci/cxdtvvar.h
--- a/sys/dev/pci/cxdtvvar.h    Thu Jul 14 23:50:12 2011 +0000
+++ b/sys/dev/pci/cxdtvvar.h    Fri Jul 15 00:21:26 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: cxdtvvar.h,v 1.1 2011/07/11 00:46:04 jakllsch Exp $ */
+/* $NetBSD: cxdtvvar.h,v 1.2 2011/07/15 00:21:26 jmcneill Exp $ */
 
 /*
  * Copyright (c) 2008, 2011 Jonathan A. Kollasch
@@ -76,6 +76,8 @@
        device_t                sc_dev;
        device_t                sc_dtvdev;
 
+       pci_chipset_tag_t       sc_pc;
+
        bus_space_tag_t         sc_memt;
        bus_space_handle_t      sc_memh;
        bus_size_t              sc_mems;



Home | Main Index | Thread Index | Old Index