Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pad Revert to rev.1.53.
details: https://anonhg.NetBSD.org/src/rev/1f4657028661
branches: trunk
changeset: 433642:1f4657028661
user: nakayama <nakayama%NetBSD.org@localhost>
date: Tue Sep 25 06:53:49 2018 +0000
description:
Revert to rev.1.53.
I accidentally committed the netbsd-8 branch file in rev.1.54.
diffstat:
sys/dev/pad/pad.c | 461 +++++++++++++++++++++++++++++++++++++----------------
1 files changed, 318 insertions(+), 143 deletions(-)
diffs (truncated from 684 to 300 lines):
diff -r bf6b83fee7ca -r 1f4657028661 sys/dev/pad/pad.c
--- a/sys/dev/pad/pad.c Tue Sep 25 05:57:46 2018 +0000
+++ b/sys/dev/pad/pad.c Tue Sep 25 06:53:49 2018 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pad.c,v 1.56 2018/09/23 23:34:45 kre Exp $ */
+/* $NetBSD: pad.c,v 1.57 2018/09/25 06:53:49 nakayama Exp $ */
/*-
* Copyright (c) 2007 Jared D. McNeill <jmcneill%invisible.ca@localhost>
@@ -27,18 +27,23 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.56 2018/09/23 23:34:45 kre Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pad.c,v 1.57 2018/09/25 06:53:49 nakayama Exp $");
#include <sys/types.h>
#include <sys/param.h>
#include <sys/conf.h>
#include <sys/buf.h>
+#include <sys/file.h>
+#include <sys/filedesc.h>
+#include <sys/vnode.h>
+#include <sys/kauth.h>
#include <sys/kmem.h>
#include <sys/kernel.h>
#include <sys/device.h>
#include <sys/proc.h>
#include <sys/condvar.h>
#include <sys/select.h>
+#include <sys/stat.h>
#include <sys/audioio.h>
#include <sys/vnode.h>
#include <sys/module.h>
@@ -52,9 +57,17 @@
#include <dev/pad/padvar.h>
+#define MAXDEVS 128
+#define PADCLONER 254
#define PADUNIT(x) minor(x)
+#define PADFREQ 44100
+#define PADCHAN 2
+#define PADPREC 16
+#define PADENC AUDIO_ENCODING_SLINEAR_LE
+
extern struct cfdriver pad_cd;
+kmutex_t padconfig;
typedef struct pad_block {
uint8_t *pb_ptr;
@@ -99,7 +112,18 @@
const audio_params_t *, const audio_params_t *);
static void pad_swvol_dtor(stream_filter_t *);
-static bool pad_is_attached; /* Do we have an audio* child? */
+static int pad_close(struct pad_softc *);
+static int pad_read(struct pad_softc *, off_t *, struct uio *, kauth_cred_t, int);
+
+static int fops_pad_close(struct file *);
+static int fops_pad_read(struct file *, off_t *, struct uio *, kauth_cred_t, int);
+static int pad_write(struct file *, off_t *, struct uio *, kauth_cred_t, int);
+static int pad_ioctl(struct file *, u_long, void *);
+static int pad_kqfilter(struct file *, struct knote *);
+static int pad_poll(struct file *, int);
+static int pad_stat(struct file *, struct stat *);
+static int pad_mmap(struct file *, off_t *, size_t, int, int *, int *,
+ struct uvm_object **, int *);
static const struct audio_hw_if pad_hw_if = {
.open = pad_audio_open,
@@ -120,8 +144,8 @@
#define PAD_NFORMATS 1
static const struct audio_format pad_formats[PAD_NFORMATS] = {
- { NULL, AUMODE_PLAY|AUMODE_RECORD, AUDIO_ENCODING_SLINEAR_LE, 16, 16,
- 2, AUFMT_STEREO, 1, { 44100 } },
+ { NULL, AUMODE_PLAY|AUMODE_RECORD, PADENC, PADPREC, PADPREC,
+ PADCHAN, AUFMT_STEREO, 1, { PADFREQ } },
};
extern void padattach(int);
@@ -130,13 +154,13 @@
static int pad_get_block(pad_softc_t *, pad_block_t *, int);
dev_type_open(pad_open);
-dev_type_close(pad_close);
-dev_type_read(pad_read);
+dev_type_close(cdev_pad_close);
+dev_type_read(cdev_pad_read);
const struct cdevsw pad_cdevsw = {
.d_open = pad_open,
- .d_close = pad_close,
- .d_read = pad_read,
+ .d_close = cdev_pad_close,
+ .d_read = cdev_pad_read,
.d_write = nowrite,
.d_ioctl = noioctl,
.d_stop = nostop,
@@ -148,34 +172,36 @@
.d_flag = D_OTHER | D_MPSAFE,
};
+const struct fileops pad_fileops = {
+ .fo_name = "pad",
+ .fo_read = fops_pad_read,
+ .fo_write = pad_write,
+ .fo_ioctl = pad_ioctl,
+ .fo_fcntl = fnullop_fcntl,
+ .fo_stat = pad_stat,
+ .fo_poll = pad_poll,
+ .fo_close = fops_pad_close,
+ .fo_mmap = pad_mmap,
+ .fo_kqfilter = pad_kqfilter,
+ .fo_restart = fnullop_restart
+};
+
CFATTACH_DECL2_NEW(pad, sizeof(pad_softc_t), pad_match, pad_attach, pad_detach,
NULL, NULL, pad_childdet);
void
padattach(int n)
{
- int i, err;
- cfdata_t cf;
-
- aprint_debug("pad: requested %d units\n", n);
+ int error;
- err = config_cfattach_attach(pad_cd.cd_name, &pad_ca);
- if (err) {
+ error = config_cfattach_attach(pad_cd.cd_name, &pad_ca);
+ if (error) {
aprint_error("%s: couldn't register cfattach: %d\n",
- pad_cd.cd_name, err);
+ pad_cd.cd_name, error);
config_cfdriver_detach(&pad_cd);
return;
}
-
- for (i = 0; i < n; i++) {
- cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP);
- cf->cf_name = pad_cd.cd_name;
- cf->cf_atname = pad_cd.cd_name;
- cf->cf_unit = i;
- cf->cf_fstate = FSTATE_STAR;
-
- (void)config_attach_pseudo(cf);
- }
+ mutex_init(&padconfig, MUTEX_DEFAULT, IPL_NONE);
return;
}
@@ -218,7 +244,7 @@
KASSERT(mutex_owned(&sc->sc_lock));
KASSERT(pb != NULL);
- if (sc->sc_buflen < blksize)
+ if (sc->sc_buflen < (uint)blksize)
return ERESTART;
pb->pb_ptr = (sc->sc_audiobuf + sc->sc_rpos);
@@ -253,51 +279,149 @@
static void
pad_attach(device_t parent, device_t self, void *opaque)
{
- pad_softc_t *sc = device_private(self);
-
aprint_normal_dev(self, "outputs: 44100Hz, 16-bit, stereo\n");
- sc->sc_dev = self;
- sc->sc_open = 0;
+ return;
+}
+
+static int
+pad_detach(device_t self, int flags)
+{
+ pad_softc_t *sc;
+ int cmaj, mn;
+
+ sc = device_private(self);
+ cmaj = cdevsw_lookup_major(&pad_cdevsw);
+ mn = device_unit(sc->sc_dev);
+ if (!sc->sc_dying)
+ vdevgone(cmaj, mn, mn, VCHR);
+
+ return 0;
+}
+
+int
+pad_open(dev_t dev, int flags, int fmt, struct lwp *l)
+{
+ pad_softc_t *sc;
+ struct file *fp;
+ device_t paddev;
+ cfdata_t cf;
+ int error, fd, i;
+
+ error = 0;
+
+ mutex_enter(&padconfig);
+ if (PADUNIT(dev) == PADCLONER) {
+ for (i = 0; i < MAXDEVS; i++) {
+ if (device_lookup(&pad_cd, i) == NULL)
+ break;
+ }
+ if (i == MAXDEVS)
+ goto bad;
+ } else {
+ if (PADUNIT(dev) >= MAXDEVS)
+ goto bad;
+ i = PADUNIT(dev);
+ }
+
+ cf = kmem_alloc(sizeof(struct cfdata), KM_SLEEP);
+ cf->cf_name = pad_cd.cd_name;
+ cf->cf_atname = pad_cd.cd_name;
+ cf->cf_unit = i;
+ cf->cf_fstate = FSTATE_STAR;
+
+ bool existing = false;
+ paddev = device_lookup(&pad_cd, minor(dev));
+ if (paddev == NULL)
+ paddev = config_attach_pseudo(cf);
+ else
+ existing = true;
+ if (paddev == NULL)
+ goto bad;
+
+ sc = device_private(paddev);
+ if (sc == NULL)
+ goto bad;
+
+ if (sc->sc_open == 1) {
+ mutex_exit(&padconfig);
+ return EBUSY;
+ }
+
+ sc->sc_dev = paddev;
+ sc->sc_dying = false;
+
+ if (PADUNIT(dev) == PADCLONER) {
+ error = fd_allocfile(&fp, &fd);
+ if (error) {
+ if (existing == false)
+ config_detach(sc->sc_dev, 0);
+ mutex_exit(&padconfig);
+ return error;
+ }
+ }
+
if (auconv_create_encodings(pad_formats, PAD_NFORMATS,
&sc->sc_encodings) != 0) {
- aprint_error_dev(self, "couldn't create encodings\n");
- return;
+ aprint_error_dev(sc->sc_dev, "couldn't create encodings\n");
+ if (existing == false)
+ config_detach(sc->sc_dev, 0);
+ mutex_exit(&padconfig);
+ return EINVAL;
}
- cv_init(&sc->sc_condvar, device_xname(self));
+ cv_init(&sc->sc_condvar, device_xname(sc->sc_dev));
mutex_init(&sc->sc_lock, MUTEX_DEFAULT, IPL_NONE);
mutex_init(&sc->sc_intr_lock, MUTEX_DEFAULT, IPL_NONE);
sc->sc_swvol = 255;
sc->sc_buflen = 0;
sc->sc_rpos = sc->sc_wpos = 0;
- sc->sc_audiodev = (void *)audio_attach_mi(&pad_hw_if, sc, sc->sc_dev);
+ sc->sc_audiodev = audio_attach_mi(&pad_hw_if, sc, sc->sc_dev);
+
+ if (!pmf_device_register(sc->sc_dev, NULL, NULL))
+ aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n");
- if (!pmf_device_register(self, NULL, NULL))
- aprint_error_dev(self, "couldn't establish power handler\n");
+ if (PADUNIT(dev) == PADCLONER) {
+ error = fd_clone(fp, fd, flags, &pad_fileops, sc);
+ KASSERT(error == EMOVEFD);
+ }
+ sc->sc_open = 1;
+ mutex_exit(&padconfig);
- pad_is_attached = true;
- return;
+ return error;
+bad:
+ mutex_exit(&padconfig);
+ return ENXIO;
}
static int
-pad_detach(device_t self, int flags)
+pad_close(struct pad_softc *sc)
{
Home |
Main Index |
Thread Index |
Old Index