1 /* $NetBSD: radio.c,v 1.21 2008/06/08 18:18:33 tsutsui Exp $ */
2 /* $OpenBSD: radio.c,v 1.2 2001/12/05 10:27:06 mickey Exp $ */
3 /* $RuOBSD: radio.c,v 1.7 2001/12/04 06:03:05 tm Exp $ */
6 * Copyright (c) 2001 Maxim Tsyplakov <tm@oganer.net>
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 /* This is the /dev/radio driver from OpenBSD */
32 #include <sys/cdefs.h>
33 __KERNEL_RCSID(0, "$NetBSD: radio.c,v 1.21 2008/06/08 18:18:33 tsutsui Exp $");
35 #include <sys/param.h>
36 #include <sys/systm.h>
38 #include <sys/errno.h>
39 #include <sys/ioctl.h>
40 #include <sys/device.h>
41 #include <sys/vnode.h>
42 #include <sys/radioio.h>
45 #include <dev/radio_if.h>
48 void *hw_hdl
; /* hardware driver handle */
49 device_t sc_dev
; /* hardware device struct */
50 const struct radio_hw_if
*hw_if
; /* hardware interface */
51 char sc_dying
; /* device detached */
54 static int radioprobe(device_t
, cfdata_t
, void *);
55 static void radioattach(device_t
, device_t
, void *);
56 static int radioprint(void *, const char *);
57 static int radiodetach(device_t
, int);
58 static int radioactivate(device_t
, enum devact
);
60 CFATTACH_DECL_NEW(radio
, sizeof(struct radio_softc
),
61 radioprobe
, radioattach
, radiodetach
, radioactivate
);
63 static dev_type_open(radioopen
);
64 static dev_type_close(radioclose
);
65 static dev_type_ioctl(radioioctl
);
67 const struct cdevsw radio_cdevsw
= {
68 radioopen
, radioclose
, noread
, nowrite
, radioioctl
,
69 nostop
, notty
, nopoll
, nommap
, nokqfilter
, D_OTHER
,
72 extern struct cfdriver radio_cd
;
75 radioprobe(device_t parent
, cfdata_t match
, void *aux
)
81 radioattach(device_t parent
, device_t self
, void *aux
)
83 struct radio_softc
*sc
= (void *)self
;
84 struct radio_attach_args
*sa
= aux
;
85 const struct radio_hw_if
*hwp
= sa
->hwif
;
96 radioopen(dev_t dev
, int flags
, int fmt
, struct lwp
*l
)
99 struct radio_softc
*sc
;
101 unit
= RADIOUNIT(dev
);
102 sc
= device_lookup_private(&radio_cd
, unit
);
103 if (sc
== NULL
|| sc
->hw_if
== NULL
)
106 if (sc
->hw_if
->open
!= NULL
)
107 return (sc
->hw_if
->open(sc
->hw_hdl
, flags
, fmt
, l
->l_proc
));
113 radioclose(dev_t dev
, int flags
, int fmt
, struct lwp
*l
)
115 struct radio_softc
*sc
;
117 sc
= device_lookup_private(&radio_cd
, RADIOUNIT(dev
));
119 if (sc
->hw_if
->close
!= NULL
)
120 return (sc
->hw_if
->close(sc
->hw_hdl
, flags
, fmt
, l
->l_proc
));
126 radioioctl(dev_t dev
, u_long cmd
, void *data
, int flags
,
129 struct radio_softc
*sc
;
132 unit
= RADIOUNIT(dev
);
133 sc
= device_lookup_private(&radio_cd
, unit
);
134 if (sc
== NULL
|| sc
->hw_if
== NULL
)
140 if (sc
->hw_if
->get_info
)
141 error
= (sc
->hw_if
->get_info
)(sc
->hw_hdl
,
142 (struct radio_info
*)data
);
145 if (sc
->hw_if
->set_info
)
146 error
= (sc
->hw_if
->set_info
)(sc
->hw_hdl
,
147 (struct radio_info
*)data
);
150 if (sc
->hw_if
->search
)
151 error
= (sc
->hw_if
->search
)(sc
->hw_hdl
,
162 * Called from hardware driver. This is where the MI radio driver gets
163 * probed/attached to the hardware driver
166 radio_attach_mi(const struct radio_hw_if
*rhwp
, void *hdlp
, device_t dev
)
168 struct radio_attach_args arg
;
172 return (config_found(dev
, &arg
, radioprint
));
176 radioprint(void *aux
, const char *pnp
)
179 aprint_normal("radio at %s", pnp
);
184 radiodetach(device_t self
, int flags
)
186 /*struct radio_softc *sc = (struct radio_softc *)self;*/
189 /* locate the major number */
190 maj
= cdevsw_lookup_major(&radio_cdevsw
);
192 /* Nuke the vnodes for any open instances (calls close). */
193 mn
= device_unit(self
);
194 vdevgone(maj
, mn
, mn
, VCHR
);
200 radioactivate(device_t self
, enum devact act
)
202 struct radio_softc
*sc
= device_private(self
);
208 case DVACT_DEACTIVATE
: