Module Name: src Committed By: sborrill Date: Sun Oct 11 08:50:12 UTC 2009
Modified Files: src/sys/dev/pci/hdaudio: hdaudio.c hdaudio_afg.c hdaudioio.h hdaudiovar.h Log Message: Add ioctls required by hdaudioctl. This involves some refactoring of the hdaudio_afg ioctl code. To generate a diff of this commit: cvs rdiff -u -r1.4 -r1.5 src/sys/dev/pci/hdaudio/hdaudio.c \ src/sys/dev/pci/hdaudio/hdaudiovar.h cvs rdiff -u -r1.16 -r1.17 src/sys/dev/pci/hdaudio/hdaudio_afg.c cvs rdiff -u -r1.2 -r1.3 src/sys/dev/pci/hdaudio/hdaudioio.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/dev/pci/hdaudio/hdaudio.c diff -u src/sys/dev/pci/hdaudio/hdaudio.c:1.4 src/sys/dev/pci/hdaudio/hdaudio.c:1.5 --- src/sys/dev/pci/hdaudio/hdaudio.c:1.4 Mon Sep 7 16:35:02 2009 +++ src/sys/dev/pci/hdaudio/hdaudio.c Sun Oct 11 08:50:11 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: hdaudio.c,v 1.4 2009/09/07 16:35:02 jmcneill Exp $ */ +/* $NetBSD: hdaudio.c,v 1.5 2009/10/11 08:50:11 sborrill Exp $ */ /* * Copyright (c) 2009 Precedence Technologies Ltd <supp...@precedence.co.uk> @@ -30,7 +30,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.4 2009/09/07 16:35:02 jmcneill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hdaudio.c,v 1.5 2009/10/11 08:50:11 sborrill Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -1339,6 +1339,48 @@ return 0; } +static int +hdaudio_dispatch_fgrp_ioctl(struct hdaudio_softc *sc, u_long cmd, + prop_dictionary_t request, prop_dictionary_t response) +{ + struct hdaudio_function_group *fg; + int16_t codecid, nid; + void *fgrp_sc; + int err; + + if (!prop_dictionary_get_int16(request, "codecid", &codecid) || + !prop_dictionary_get_int16(request, "nid", &nid)) + return EINVAL; + + fg = hdaudioioctl_fgrp_lookup(sc, codecid, nid); + if (fg == NULL) + return ENODEV; + fgrp_sc = device_private(fg->fg_device); + + switch (fg->fg_type) { + case HDAUDIO_GROUP_TYPE_AFG: + switch (cmd) { + case HDAUDIO_FGRP_CODEC_INFO: + err = hdaudio_afg_codec_info(fgrp_sc, + request, response); + break; + case HDAUDIO_FGRP_WIDGET_INFO: + err = hdaudio_afg_widget_info(fgrp_sc, + request, response); + break; + default: + err = EINVAL; + break; + } + break; + + default: + err = EINVAL; + break; + } + return err; +} + int hdaudioopen(dev_t dev, int flag, int mode, struct lwp *l) { @@ -1389,6 +1431,10 @@ case HDAUDIO_FGRP_SETCONFIG: err = hdaudioioctl_fgrp_setconfig(sc, request, response); break; + case HDAUDIO_FGRP_CODEC_INFO: + case HDAUDIO_FGRP_WIDGET_INFO: + err = hdaudio_dispatch_fgrp_ioctl(sc, cmd, request, response); + break; default: err = EINVAL; break; Index: src/sys/dev/pci/hdaudio/hdaudiovar.h diff -u src/sys/dev/pci/hdaudio/hdaudiovar.h:1.4 src/sys/dev/pci/hdaudio/hdaudiovar.h:1.5 --- src/sys/dev/pci/hdaudio/hdaudiovar.h:1.4 Mon Sep 7 16:21:08 2009 +++ src/sys/dev/pci/hdaudio/hdaudiovar.h Sun Oct 11 08:50:12 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: hdaudiovar.h,v 1.4 2009/09/07 16:21:08 jmcneill Exp $ */ +/* $NetBSD: hdaudiovar.h,v 1.5 2009/10/11 08:50:12 sborrill Exp $ */ /* * Copyright (c) 2009 Precedence Technologies Ltd <supp...@precedence.co.uk> @@ -178,4 +178,7 @@ int hdaudio_stream_tag(struct hdaudio_stream *); uint16_t hdaudio_stream_param(struct hdaudio_stream *, const audio_params_t *); +int hdaudio_afg_widget_info(void *, prop_dictionary_t, prop_dictionary_t); +int hdaudio_afg_codec_info(void *, prop_dictionary_t, prop_dictionary_t); + #endif /* !_HDAUDIOVAR_H */ Index: src/sys/dev/pci/hdaudio/hdaudio_afg.c diff -u src/sys/dev/pci/hdaudio/hdaudio_afg.c:1.16 src/sys/dev/pci/hdaudio/hdaudio_afg.c:1.17 --- src/sys/dev/pci/hdaudio/hdaudio_afg.c:1.16 Tue Sep 29 15:58:54 2009 +++ src/sys/dev/pci/hdaudio/hdaudio_afg.c Sun Oct 11 08:50:11 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: hdaudio_afg.c,v 1.16 2009/09/29 15:58:54 sborrill Exp $ */ +/* $NetBSD: hdaudio_afg.c,v 1.17 2009/10/11 08:50:11 sborrill Exp $ */ /* * Copyright (c) 2009 Precedence Technologies Ltd <supp...@precedence.co.uk> @@ -60,7 +60,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.16 2009/09/29 15:58:54 sborrill Exp $"); +__KERNEL_RCSID(0, "$NetBSD: hdaudio_afg.c,v 1.17 2009/10/11 08:50:11 sborrill Exp $"); #include <sys/types.h> #include <sys/param.h> @@ -3644,19 +3644,71 @@ return 0; } +int +hdaudio_afg_widget_info(void *opaque, prop_dictionary_t request, + prop_dictionary_t response) +{ + struct hdaudio_afg_softc *sc = opaque; + struct hdaudio_widget *w; + prop_array_t connlist; + uint32_t config, wcap; + uint16_t index; + int nid; + int i; + + if (prop_dictionary_get_uint16(request, "index", &index) == false) + return EINVAL; + + nid = sc->sc_startnode + index; + if (nid >= sc->sc_endnode) + return EINVAL; + + w = hdaudio_afg_widget_lookup(sc, nid); + if (w == NULL) + return ENXIO; + wcap = hda_get_wparam(w, PIN_CAPABILITIES); + config = hdaudio_command(sc->sc_codec, w->w_nid, + CORB_GET_CONFIGURATION_DEFAULT, 0); + prop_dictionary_set_cstring_nocopy(response, "name", w->w_name); + prop_dictionary_set_bool(response, "enable", w->w_enable); + prop_dictionary_set_uint8(response, "nid", w->w_nid); + prop_dictionary_set_uint8(response, "type", w->w_type); + prop_dictionary_set_uint32(response, "config", config); + prop_dictionary_set_uint32(response, "cap", wcap); + if (w->w_nconns == 0) + return 0; + connlist = prop_array_create(); + for (i = 0; i < w->w_nconns; i++) { + if (w->w_conns[i] == 0) + continue; + prop_array_add(connlist, + prop_number_create_unsigned_integer(w->w_conns[i])); + } + prop_dictionary_set(response, "connlist", connlist); + prop_object_release(connlist); + return 0; +} + +int +hdaudio_afg_codec_info(void *opaque, prop_dictionary_t request, + prop_dictionary_t response) +{ + struct hdaudio_afg_softc *sc = opaque; + prop_dictionary_set_uint16(response, "vendor-id", + sc->sc_vendor); + prop_dictionary_set_uint16(response, "product-id", + sc->sc_product); + return 0; +} + static int hdaudio_afg_dev_ioctl(void *opaque, u_long cmd, void *addr, int flag, lwp_t *l) { struct hdaudio_audiodev *ad = opaque; struct hdaudio_afg_softc *sc = ad->ad_sc; struct plistref *pref = addr; - struct hdaudio_widget *w; prop_dictionary_t request, response; - prop_array_t connlist; - uint32_t config, wcap; - uint16_t index; - int err, nid; - int i; + int err; response = prop_dictionary_create(); if (response == NULL) @@ -3667,60 +3719,22 @@ prop_object_release(response); return err; } - - if (prop_dictionary_get_uint16(request, "index", &index) == false) { - err = EINVAL; - goto out; - } - - nid = sc->sc_startnode + index; - if (nid >= sc->sc_endnode) { - err = EINVAL; - goto out; - } - + err = 0; switch (cmd) { case HDAUDIO_AFG_WIDGET_INFO: - w = hdaudio_afg_widget_lookup(sc, nid); - if (w == NULL) { - err = ENXIO; - goto out; - } - wcap = hda_get_wparam(w, PIN_CAPABILITIES); - config = hdaudio_command(sc->sc_codec, w->w_nid, - CORB_GET_CONFIGURATION_DEFAULT, 0); - prop_dictionary_set_cstring_nocopy(response, "name", w->w_name); - prop_dictionary_set_bool(response, "enable", w->w_enable); - prop_dictionary_set_uint8(response, "nid", w->w_nid); - prop_dictionary_set_uint8(response, "type", w->w_type); - prop_dictionary_set_uint32(response, "config", config); - prop_dictionary_set_uint32(response, "cap", wcap); - if (w->w_nconns == 0) - break; - connlist = prop_array_create(); - for (i = 0; i < w->w_nconns; i++) { - if (w->w_conns[i] == 0) - continue; - prop_array_add(connlist, - prop_number_create_unsigned_integer(w->w_conns[i])); - } - prop_dictionary_set(response, "connlist", connlist); - prop_object_release(connlist); + err = hdaudio_afg_widget_info(sc, request, response); break; case HDAUDIO_AFG_CODEC_INFO: - prop_dictionary_set_uint16(response, "vendor-id", - sc->sc_vendor); - prop_dictionary_set_uint16(response, "product-id", - sc->sc_product); + err = hdaudio_afg_codec_info(sc, request, response); break; default: err = EINVAL; - goto out; + break; } - err = prop_dictionary_copyout_ioctl(pref, cmd, response); + if (!err) + err = prop_dictionary_copyout_ioctl(pref, cmd, response); -out: if (response) prop_object_release(response); prop_object_release(request); Index: src/sys/dev/pci/hdaudio/hdaudioio.h diff -u src/sys/dev/pci/hdaudio/hdaudioio.h:1.2 src/sys/dev/pci/hdaudio/hdaudioio.h:1.3 --- src/sys/dev/pci/hdaudio/hdaudioio.h:1.2 Sun Sep 6 17:33:53 2009 +++ src/sys/dev/pci/hdaudio/hdaudioio.h Sun Oct 11 08:50:12 2009 @@ -1,4 +1,4 @@ -/* $NetBSD: hdaudioio.h,v 1.2 2009/09/06 17:33:53 sborrill Exp $ */ +/* $NetBSD: hdaudioio.h,v 1.3 2009/10/11 08:50:12 sborrill Exp $ */ /* * Copyright (c) 2009 Precedence Technologies Ltd <supp...@precedence.co.uk> @@ -38,6 +38,8 @@ #define HDAUDIO_FGRP_INFO _IOWR('h', 0, struct plistref) #define HDAUDIO_FGRP_GETCONFIG _IOWR('h', 1, struct plistref) #define HDAUDIO_FGRP_SETCONFIG _IOWR('h', 2, struct plistref) +#define HDAUDIO_FGRP_WIDGET_INFO _IOWR('h', 3, struct plistref) +#define HDAUDIO_FGRP_CODEC_INFO _IOWR('h', 4, struct plistref) #define HDAUDIO_AFG_WIDGET_INFO _IOWR('H', 0, struct plistref) #define HDAUDIO_AFG_CODEC_INFO _IOWR('H', 1, struct plistref)