Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/usb Handle packet scheduling for high/super speed.
details: https://anonhg.NetBSD.org/src/rev/d6f27f7f8638
branches: trunk
changeset: 374279:d6f27f7f8638
user: mlelstv <mlelstv%NetBSD.org@localhost>
date: Sun Apr 16 19:26:20 2023 +0000
description:
Handle packet scheduling for high/super speed.
More UAC2 handling for input/output/feature/selector units.
Setting sample rate for UAC2 now works, still no support for clock selectors
and multipliers.
Added sysctl to set debug level.
Minor fixes.
diffstat:
sys/dev/usb/uaudio.c | 905 ++++++++++++++++++++++++++++++++---------------
sys/dev/usb/uaudioreg.h | 44 ++-
2 files changed, 647 insertions(+), 302 deletions(-)
diffs (truncated from 1790 to 300 lines):
diff -r db46fc1851d4 -r d6f27f7f8638 sys/dev/usb/uaudio.c
--- a/sys/dev/usb/uaudio.c Sun Apr 16 18:37:16 2023 +0000
+++ b/sys/dev/usb/uaudio.c Sun Apr 16 19:26:20 2023 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: uaudio.c,v 1.178 2023/04/10 15:14:50 mlelstv Exp $ */
+/* $NetBSD: uaudio.c,v 1.179 2023/04/16 19:26:20 mlelstv Exp $ */
/*
* Copyright (c) 1999, 2012 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.178 2023/04/10 15:14:50 mlelstv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uaudio.c,v 1.179 2023/04/16 19:26:20 mlelstv Exp $");
#ifdef _KERNEL_OPT
#include "opt_usb.h"
@@ -59,6 +59,7 @@
#include <sys/bus.h>
#include <sys/cpu.h>
#include <sys/atomic.h>
+#include <sys/sysctl.h>
#include <sys/audioio.h>
#include <dev/audio/audio_if.h>
@@ -99,8 +100,12 @@ int uaudiodebug = 0;
#define DPRINTFN(n,x,y...)
#endif
-#define UAUDIO_NCHANBUFS 6 /* number of outstanding request */
-#define UAUDIO_NFRAMES 10 /* ms of sound in each request */
+/* number of outstanding requests */
+#define UAUDIO_NCHANBUFS 6
+/* number of USB frames per request, also the number of ms */
+#define UAUDIO_NFRAMES 10
+/* number of microframes per requewst (high, super) */
+#define UAUDIO_NFRAMES_HI (UAUDIO_NFRAMES * USB_UFRAMES_PER_FRAME)
#define MIX_MAX_CHAN 8
@@ -133,7 +138,6 @@ struct mixerctl {
u_int nranges;
u_int delta;
u_int mul;
- u_int high;
uint8_t class;
char ctlname[MAX_AUDIO_DEV_LEN];
const char *ctlunit;
@@ -147,6 +151,7 @@ struct as_info {
uint8_t attributes; /* Copy of bmAttributes of
* usb_audio_streaming_endpoint_descriptor
*/
+ uint8_t terminal; /* connected Terminal ID */
struct usbd_interface * ifaceh;
const usb_interface_descriptor_t *idesc;
const usb_endpoint_descriptor_audio_t *edesc;
@@ -177,12 +182,14 @@ struct chan {
int altidx; /* currently used altidx */
int curchanbuf;
+ u_int nframes; /* UAUDIO_NFRAMES or UAUDIO_NFRAMES_HI */
+ u_int nchanbufs; /* 1..UAUDIO_NCHANBUFS */
struct chanbuf {
struct chan *chan;
struct usbd_xfer *xfer;
u_char *buffer;
- uint16_t sizes[UAUDIO_NFRAMES];
- uint16_t offsets[UAUDIO_NFRAMES];
+ uint16_t sizes[UAUDIO_NFRAMES_HI];
+ uint16_t offsets[UAUDIO_NFRAMES_HI];
uint16_t size;
} chanbufs[UAUDIO_NCHANBUFS];
@@ -223,9 +230,13 @@ struct uaudio_softc {
int sc_nratectls; /* V2 sample rates */
int sc_ratectls[AUFMT_MAX_FREQUENCIES];
int sc_ratemode[AUFMT_MAX_FREQUENCIES];
+ int sc_playclock;
+ int sc_recclock;
struct audio_format *sc_formats;
int sc_nformats;
+ uint8_t sc_clock[256]; /* map terminals to clocks */
u_int sc_channel_config;
+ u_int sc_usb_frames_per_second;
char sc_dying;
struct audio_device sc_adev;
};
@@ -244,7 +255,7 @@ struct io_terminal {
const union usb_audio_output_terminal *ot;
const struct usb_audio_mixer_unit *mu;
const struct usb_audio_selector_unit *su;
- const struct usb_audio_feature_unit *fu;
+ const union usb_audio_feature_unit *fu;
const struct usb_audio_processing_unit *pu;
const struct usb_audio_extension_unit *eu;
const struct usb_audio_clksrc_unit *cu;
@@ -254,6 +265,7 @@ struct io_terminal {
struct terminal_list **inputs; /* list of source input terminals */
struct terminal_list *output; /* list of destination output terminals */
int direct; /* directly connected to an output terminal */
+ uint8_t clock;
};
#define UAC_OUTPUT 0
@@ -286,7 +298,7 @@ Static const usb_interface_descriptor_t
Static void uaudio_mixer_add_ctl(struct uaudio_softc *, struct mixerctl *);
Static char *uaudio_id_name
- (struct uaudio_softc *, const struct io_terminal *, int);
+ (struct uaudio_softc *, const struct io_terminal *, uint8_t);
#ifdef UAUDIO_DEBUG
Static void uaudio_dump_cluster
(struct uaudio_softc *, const union usb_audio_cluster *);
@@ -307,7 +319,7 @@ Static const char *uaudio_get_terminal_n
Static int uaudio_determine_class
(const struct io_terminal *, struct mixerctl *);
Static const char *uaudio_feature_name
- (const struct io_terminal *, struct mixerctl *);
+ (const struct io_terminal *, uint8_t, int);
Static void uaudio_add_feature
(struct uaudio_softc *, const struct io_terminal *, int);
Static void uaudio_add_processing_updown
@@ -348,6 +360,7 @@ Static void uaudio_set
Static void uaudio_ctl_set
(struct uaudio_softc *, int, struct mixerctl *, int, int);
+Static usbd_status uaudio_speed(struct uaudio_softc *, int, int, uint8_t *, int);
Static usbd_status uaudio_set_speed(struct uaudio_softc *, int, int, u_int);
Static usbd_status uaudio_chan_open(struct uaudio_softc *, struct chan *);
@@ -357,7 +370,7 @@ Static usbd_status uaudio_chan_alloc_buf
(struct uaudio_softc *, struct chan *);
Static void uaudio_chan_free_buffers(struct uaudio_softc *, struct chan *);
Static void uaudio_chan_init
- (struct chan *, int, const struct audio_params *, int);
+ (struct chan *, int, const struct audio_params *, int, bool);
Static void uaudio_chan_set_param(struct chan *, u_char *, u_char *, int);
Static void uaudio_chan_ptransfer(struct chan *);
Static void uaudio_chan_pintr
@@ -414,7 +427,6 @@ static void uaudio_childdet(device_t, de
static int uaudio_activate(device_t, enum devact);
-
CFATTACH_DECL2_NEW(uaudio, sizeof(struct uaudio_softc),
uaudio_match, uaudio_attach, uaudio_detach, uaudio_activate, NULL,
uaudio_childdet);
@@ -510,6 +522,25 @@ uaudio_attach(device_t parent, device_t
sc->sc_playchan.altidx = -1;
sc->sc_recchan.altidx = -1;
+ switch (sc->sc_udev->ud_speed) {
+ case USB_SPEED_LOW:
+ case USB_SPEED_FULL:
+ sc->sc_usb_frames_per_second = USB_FRAMES_PER_SECOND;
+ sc->sc_playchan.nframes =
+ sc->sc_recchan.nframes = UAUDIO_NFRAMES;
+ break;
+ default: /* HIGH, SUPER, SUPER_PLUS, more ? */
+ sc->sc_usb_frames_per_second = USB_FRAMES_PER_SECOND * USB_UFRAMES_PER_FRAME;
+ sc->sc_playchan.nframes =
+ sc->sc_recchan.nframes = UAUDIO_NFRAMES_HI;
+ break;
+ }
+ sc->sc_playchan.nchanbufs =
+ sc->sc_recchan.nchanbufs = UAUDIO_NCHANBUFS;
+
+ DPRINTF("usb fps %u, max channel frames %u, max channel buffers %u\n",
+ sc->sc_usb_frames_per_second, sc->sc_playchan.nframes, sc->sc_playchan.nchanbufs);
+
if (usbd_get_quirks(sc->sc_udev)->uq_flags & UQ_AU_NO_FRAC)
sc->sc_altflags |= UA_NOFRAC;
@@ -785,11 +816,8 @@ uaudio_mixer_add_ctl(struct uaudio_softc
if (mc->mul == 0)
mc->mul = 1;
- mc->delta = res * 255 / mc->mul;
- if (mc->delta > 0 && mc->delta < 255)
- mc->high = 255 / mc->delta * mc->delta;
- else
- mc->high = 255;
+
+ mc->delta = (res * 255 + mc->mul - 1) / mc->mul;
#ifdef UAUDIO_DEBUG
if (uaudiodebug > 2) {
@@ -811,11 +839,12 @@ uaudio_mixer_add_ctl(struct uaudio_softc
Static char *
uaudio_id_name(struct uaudio_softc *sc,
- const struct io_terminal *iot, int id)
+ const struct io_terminal *iot, uint8_t id)
{
static char tbuf[32];
- snprintf(tbuf, sizeof(tbuf), "i%d", id);
+ snprintf(tbuf, sizeof(tbuf), "i%u", id);
+
return tbuf;
}
@@ -879,6 +908,7 @@ uaudio_get_cluster(struct uaudio_softc *
{
union usb_audio_cluster r;
const uaudio_cs_descriptor_t *dp;
+ u_int pins;
int i;
for (i = 0; i < 25; i++) { /* avoid infinite loops */
@@ -891,37 +921,78 @@ uaudio_get_cluster(struct uaudio_softc *
switch (sc->sc_version) {
case UAUDIO_VERSION1:
r.v1.bNrChannels = iot[id].d.it->v1.bNrChannels;
- USETW(r.v1.wChannelConfig, UGETW(iot[id].d.it->v1.wChannelConfig));
+ USETW(r.v1.wChannelConfig,
+ UGETW(iot[id].d.it->v1.wChannelConfig));
r.v1.iChannelNames = iot[id].d.it->v1.iChannelNames;
break;
case UAUDIO_VERSION2:
r.v2.bNrChannels = iot[id].d.it->v2.bNrChannels;
- USETDW(r.v2.bmChannelConfig, UGETW(iot[id].d.it->v2.bmChannelConfig));
+ USETDW(r.v2.bmChannelConfig,
+ UGETW(iot[id].d.it->v2.bmChannelConfig));
r.v2.iChannelNames = iot[id].d.it->v2.iChannelNames;
break;
}
return r;
case UDESCSUB_AC_OUTPUT:
+ /* XXX This is not really right */
id = iot[id].d.ot->v1.bSourceId;
break;
case UDESCSUB_AC_MIXER:
- r = *(const union usb_audio_cluster *)
- &iot[id].d.mu->baSourceId[iot[id].d.mu->bNrInPins];
+ switch (sc->sc_version) {
+ case UAUDIO_VERSION1:
+ pins = iot[id].d.mu->bNrInPins;
+ r.v1 = *(const struct usb_audio_v1_cluster *)
+ &iot[id].d.mu->baSourceId[pins];
+ break;
+ case UAUDIO_VERSION2:
+ pins = iot[id].d.mu->bNrInPins;
+ r.v2 = *(const struct usb_audio_v2_cluster *)
+ &iot[id].d.mu->baSourceId[pins];
+ break;
+ }
return r;
case UDESCSUB_AC_SELECTOR:
/* XXX This is not really right */
id = iot[id].d.su->baSourceId[0];
break;
case UDESCSUB_AC_FEATURE:
- id = iot[id].d.fu->bSourceId;
+ /* XXX This is not really right */
+ switch (sc->sc_version) {
+ case UAUDIO_VERSION1:
+ id = iot[id].d.fu->v1.bSourceId;
+ break;
+ case UAUDIO_VERSION2:
+ id = iot[id].d.fu->v2.bSourceId;
+ break;
+ }
break;
case UDESCSUB_AC_PROCESSING:
- r = *(const union usb_audio_cluster *)
- &iot[id].d.pu->baSourceId[iot[id].d.pu->bNrInPins];
+ switch (sc->sc_version) {
+ case UAUDIO_VERSION1:
+ pins = iot[id].d.pu->bNrInPins;
+ r.v1 = *(const struct usb_audio_v1_cluster *)
+ &iot[id].d.pu->baSourceId[pins];
+ break;
+ case UAUDIO_VERSION2:
+ pins = iot[id].d.pu->bNrInPins;
+ r.v2 = *(const struct usb_audio_v2_cluster *)
+ &iot[id].d.pu->baSourceId[pins];
+ break;
+ }
return r;
case UDESCSUB_AC_EXTENSION:
- r = *(const union usb_audio_cluster *)
- &iot[id].d.eu->baSourceId[iot[id].d.eu->bNrInPins];
+ switch (sc->sc_version) {
+ case UAUDIO_VERSION1:
+ pins = iot[id].d.eu->bNrInPins;
+ r.v1 = *(const struct usb_audio_v1_cluster *)
+ &iot[id].d.eu->baSourceId[pins];
+ break;
+ case UAUDIO_VERSION2:
+ pins = iot[id].d.eu->bNrInPins;
+ r.v2 = *(const struct usb_audio_v2_cluster *)
+ &iot[id].d.eu->baSourceId[pins];
+ break;
+ }
return r;
default:
goto bad;
@@ -951,9 +1022,10 @@ uaudio_add_input(struct uaudio_softc *sc
Home |
Main Index |
Thread Index |
Old Index