diff options
Diffstat (limited to 'usr.sbin')
31 files changed, 1 insertions, 9172 deletions
diff --git a/usr.sbin/Makefile b/usr.sbin/Makefile index d52364bac84e..508573b23bc1 100644 --- a/usr.sbin/Makefile +++ b/usr.sbin/Makefile @@ -166,8 +166,6 @@ SUBDIR.${MK_NS_CACHING}+= nscd SUBDIR.${MK_LPR}+= lpr SUBDIR.${MK_MAN_UTILS}+= manctl SUBDIR.${MK_MLX5TOOL}+= mlx5tool -SUBDIR.${MK_NAND}+= nandsim -SUBDIR.${MK_NAND}+= nandtool SUBDIR.${MK_NETGRAPH}+= flowctl SUBDIR.${MK_NETGRAPH}+= ngctl SUBDIR.${MK_NETGRAPH}+= nghook diff --git a/usr.sbin/bhyve/Makefile b/usr.sbin/bhyve/Makefile index e203a57c18a3..85fdf11928b1 100644 --- a/usr.sbin/bhyve/Makefile +++ b/usr.sbin/bhyve/Makefile @@ -16,7 +16,6 @@ BHYVE_SYSDIR?=${SRCTOP} SRCS= \ atkbdc.c \ acpi.c \ - audio.c \ bhyvegc.c \ bhyverun.c \ block_if.c \ @@ -28,7 +27,6 @@ SRCS= \ dbgport.c \ fwctl.c \ gdb.c \ - hda_codec.c \ inout.c \ ioapic.c \ mem.c \ @@ -38,7 +36,6 @@ SRCS= \ pci_ahci.c \ pci_e82545.c \ pci_emul.c \ - pci_hda.c \ pci_fbuf.c \ pci_hostbridge.c \ pci_irq.c \ diff --git a/usr.sbin/bhyve/audio.c b/usr.sbin/bhyve/audio.c deleted file mode 100644 index 6a288cbded63..000000000000 --- a/usr.sbin/bhyve/audio.c +++ /dev/null @@ -1,282 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#ifndef WITHOUT_CAPSICUM -#include <sys/capsicum.h> -#include <capsicum_helpers.h> -#endif - -#include <stdio.h> -#include <stdlib.h> -#include <fcntl.h> -#include <sys/ioctl.h> -#include <unistd.h> -#include <assert.h> -#include <errno.h> -#include <err.h> -#include <sysexits.h> - -#include "audio.h" -#include "pci_hda.h" - -/* - * Audio Player internal data structures - */ - -struct audio { - int fd; - uint8_t dir; - uint8_t inited; - char dev_name[64]; -}; - -/* - * Audio Player module function definitions - */ - -/* - * audio_init - initialize an instance of audio player - * @dev_name - the backend sound device used to play / capture - * @dir - dir = 1 for write mode, dir = 0 for read mode - */ -struct audio * -audio_init(const char *dev_name, uint8_t dir) -{ - struct audio *aud = NULL; -#ifndef WITHOUT_CAPSICUM - cap_rights_t rights; - cap_ioctl_t cmds[] = { - SNDCTL_DSP_RESET, SNDCTL_DSP_SETFMT, SNDCTL_DSP_CHANNELS, - SNDCTL_DSP_SPEED, -#ifdef DEBUG_HDA - SNDCTL_DSP_GETOSPACE, SNDCTL_DSP_GETISPACE, -#endif - }; -#endif - - assert(dev_name); - - aud = calloc(1, sizeof(*aud)); - if (!aud) - return NULL; - - if (strlen(dev_name) < sizeof(aud->dev_name)) - memcpy(aud->dev_name, dev_name, strlen(dev_name) + 1); - else { - DPRINTF("dev_name too big\n"); - free(aud); - return NULL; - } - - aud->dir = dir; - - aud->fd = open(aud->dev_name, aud->dir ? O_WRONLY : O_RDONLY, 0); - if (aud->fd == -1) { - DPRINTF("Failed to open dev: %s, errno: %d\n", - aud->dev_name, errno); - return (NULL); - } - -#ifndef WITHOUT_CAPSICUM - cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_WRITE); - if (caph_rights_limit(aud->fd, &rights) == -1) - errx(EX_OSERR, "Unable to apply rights for sandbox"); - if (caph_ioctls_limit(aud->fd, cmds, nitems(cmds)) == -1) - errx(EX_OSERR, "Unable to limit ioctl rights for sandbox"); -#endif - - return aud; -} - -/* - * audio_set_params - reset the sound device and set the audio params - * @aud - the audio player to be configured - * @params - the audio parameters to be set - */ -int -audio_set_params(struct audio *aud, struct audio_params *params) -{ - int audio_fd; - int format, channels, rate; - int err; -#if DEBUG_HDA == 1 - audio_buf_info info; -#endif - - assert(aud); - assert(params); - - if ((audio_fd = aud->fd) < 0) { - DPRINTF("Incorrect audio device descriptor for %s\n", - aud->dev_name); - return (-1); - } - - /* Reset the device if it was previously opened */ - if (aud->inited) { - err = ioctl(audio_fd, SNDCTL_DSP_RESET, NULL); - if (err == -1) { - DPRINTF("Failed to reset fd: %d, errno: %d\n", - aud->fd, errno); - return (-1); - } - } else - aud->inited = 1; - - /* Set the Format (Bits per Sample) */ - format = params->format; - err = ioctl(audio_fd, SNDCTL_DSP_SETFMT, &format); - if (err == -1) { - DPRINTF("Fail to set fmt: 0x%x errno: %d\n", - params->format, errno); - return -1; - } - - /* The device does not support the requested audio format */ - if (format != params->format) { - DPRINTF("Mismatch format: 0x%x params->format: 0x%x\n", - format, params->format); - return -1; - } - - /* Set the Number of Channels */ - channels = params->channels; - err = ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &channels); - if (err == -1) { - DPRINTF("Fail to set channels: %d errno: %d\n", - params->channels, errno); - return -1; - } - - /* The device does not support the requested no. of channels */ - if (channels != params->channels) { - DPRINTF("Mismatch channels: %d params->channels: %d\n", - channels, params->channels); - return -1; - } - - /* Set the Sample Rate / Speed */ - rate = params->rate; - err = ioctl(audio_fd, SNDCTL_DSP_SPEED, &rate); - if (err == -1) { - DPRINTF("Fail to set speed: %d errno: %d\n", - params->rate, errno); - return -1; - } - - /* The device does not support the requested rate / speed */ - if (rate != params->rate) { - DPRINTF("Mismatch rate: %d params->rate: %d\n", - rate, params->rate); - return -1; - } - -#if DEBUG_HDA == 1 - err = ioctl(audio_fd, aud->dir ? SNDCTL_DSP_GETOSPACE : - SNDCTL_DSP_GETISPACE, &info); - if (err == -1) { - DPRINTF("Fail to get audio buf info errno: %d\n", errno); - return -1; - } - DPRINTF("fragstotal: 0x%x fragsize: 0x%x\n", - info.fragstotal, info.fragsize); -#endif - return 0; -} - -/* - * audio_playback - plays samples to the sound device using blocking operations - * @aud - the audio player used to play the samples - * @buf - the buffer containing the samples - * @count - the number of bytes in buffer - */ -int -audio_playback(struct audio *aud, const void *buf, size_t count) -{ - int audio_fd = -1; - ssize_t len = 0, total = 0; - - assert(aud); - assert(aud->dir); - assert(buf); - - audio_fd = aud->fd; - assert(audio_fd != -1); - - total = 0; - while (total < count) { - len = write(audio_fd, buf + total, count - total); - if (len == -1) { - DPRINTF("Fail to write to fd: %d, errno: %d\n", - audio_fd, errno); - return -1; - } - - total += len; - } - - return 0; -} - -/* - * audio_record - records samples from the sound device using - * blocking operations. - * @aud - the audio player used to capture the samples - * @buf - the buffer to receive the samples - * @count - the number of bytes to capture in buffer - * Returns -1 on error and 0 on success - */ -int -audio_record(struct audio *aud, void *buf, size_t count) -{ - int audio_fd = -1; - ssize_t len = 0, total = 0; - - assert(aud); - assert(!aud->dir); - assert(buf); - - audio_fd = aud->fd; - assert(audio_fd != -1); - - total = 0; - while (total < count) { - len = read(audio_fd, buf + total, count - total); - if (len == -1) { - DPRINTF("Fail to write to fd: %d, errno: %d\n", - audio_fd, errno); - return -1; - } - - total += len; - } - - return 0; -} diff --git a/usr.sbin/bhyve/audio.h b/usr.sbin/bhyve/audio.h deleted file mode 100644 index 01ef17071b14..000000000000 --- a/usr.sbin/bhyve/audio.h +++ /dev/null @@ -1,86 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _AUDIO_EMUL_H_ -#define _AUDIO_EMUL_H_ - -#include <sys/types.h> -#include <sys/soundcard.h> - -/* - * Audio Player data structures - */ - -struct audio; - -struct audio_params { - int channels; - int format; - int rate; -}; - -/* - * Audio Player API - */ - -/* - * audio_init - initialize an instance of audio player - * @dev_name - the backend sound device used to play / capture - * @dir - dir = 1 for write mode, dir = 0 for read mode - * Returns NULL on error and the address of the audio player instance - */ -struct audio *audio_init(const char *dev_name, uint8_t dir); - -/* - * audio_set_params - reset the sound device and set the audio params - * @aud - the audio player to be configured - * @params - the audio parameters to be set - * Returns -1 on error and 0 on success - */ -int audio_set_params(struct audio *aud, struct audio_params *params); - -/* - * audio_playback - plays samples to the sound device using blocking operations - * @aud - the audio player used to play the samples - * @buf - the buffer containing the samples - * @count - the number of bytes in buffer - * Returns -1 on error and 0 on success - */ -int audio_playback(struct audio *aud, const void *buf, size_t count); - -/* - * audio_record - records samples from the sound device using blocking - * operations. - * @aud - the audio player used to capture the samples - * @buf - the buffer to receive the samples - * @count - the number of bytes to capture in buffer - * Returns -1 on error and 0 on success - */ -int audio_record(struct audio *aud, void *buf, size_t count); - -#endif /* _AUDIO_EMUL_H_ */ diff --git a/usr.sbin/bhyve/bhyve.8 b/usr.sbin/bhyve/bhyve.8 index 3ab9e4e67dde..2f2236e8ce38 100644 --- a/usr.sbin/bhyve/bhyve.8 +++ b/usr.sbin/bhyve/bhyve.8 @@ -24,7 +24,7 @@ .\" .\" $FreeBSD$ .\" -.Dd June 24, 2019 +.Dd December 11, 2018 .Dt BHYVE 8 .Os .Sh NAME @@ -248,8 +248,6 @@ Raw framebuffer device attached to VNC server. eXtensible Host Controller Interface (xHCI) USB controller. .It Li nvme NVM Express (NVMe) controller. -.It Li hda -High Definition Audio Controller. .El .It Op Ar conf This optional parameter describes the backend for device emulations. @@ -477,16 +475,6 @@ Sector size (defaults to blockif sector size). .It Li ser Serial number with maximum 20 characters. .El -.Pp -HD Audio devices: -.Bl -tag -width 10n -.It Li play -Playback device, typically -.Ar /dev/dsp0 . -.It Li rec -Recording device, typically -.Ar /dev/dsp0 . -.El .El .It Fl S Wire guest memory. diff --git a/usr.sbin/bhyve/hda_codec.c b/usr.sbin/bhyve/hda_codec.c deleted file mode 100644 index ab53eb036e9f..000000000000 --- a/usr.sbin/bhyve/hda_codec.c +++ /dev/null @@ -1,950 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <pthread.h> -#include <pthread_np.h> -#include <unistd.h> - -#include "pci_hda.h" -#include "audio.h" - -/* - * HDA Codec defines - */ -#define INTEL_VENDORID 0x8086 - -#define HDA_CODEC_SUBSYSTEM_ID ((INTEL_VENDORID << 16) | 0x01) -#define HDA_CODEC_ROOT_NID 0x00 -#define HDA_CODEC_FG_NID 0x01 -#define HDA_CODEC_AUDIO_OUTPUT_NID 0x02 -#define HDA_CODEC_PIN_OUTPUT_NID 0x03 -#define HDA_CODEC_AUDIO_INPUT_NID 0x04 -#define HDA_CODEC_PIN_INPUT_NID 0x05 - -#define HDA_CODEC_STREAMS_COUNT 0x02 -#define HDA_CODEC_STREAM_OUTPUT 0x00 -#define HDA_CODEC_STREAM_INPUT 0x01 - -#define HDA_CODEC_PARAMS_COUNT 0x14 -#define HDA_CODEC_CONN_LIST_COUNT 0x01 -#define HDA_CODEC_RESPONSE_EX_UNSOL 0x10 -#define HDA_CODEC_RESPONSE_EX_SOL 0x00 -#define HDA_CODEC_AMP_NUMSTEPS 0x4a - -#define HDA_CODEC_SUPP_STREAM_FORMATS_PCM \ - (1 << HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT) - -#define HDA_CODEC_FMT_BASE_MASK (0x01 << 14) - -#define HDA_CODEC_FMT_MULT_MASK (0x07 << 11) -#define HDA_CODEC_FMT_MULT_2 (0x01 << 11) -#define HDA_CODEC_FMT_MULT_3 (0x02 << 11) -#define HDA_CODEC_FMT_MULT_4 (0x03 << 11) - -#define HDA_CODEC_FMT_DIV_MASK 0x07 -#define HDA_CODEC_FMT_DIV_SHIFT 8 - -#define HDA_CODEC_FMT_BITS_MASK (0x07 << 4) -#define HDA_CODEC_FMT_BITS_8 (0x00 << 4) -#define HDA_CODEC_FMT_BITS_16 (0x01 << 4) -#define HDA_CODEC_FMT_BITS_24 (0x03 << 4) -#define HDA_CODEC_FMT_BITS_32 (0x04 << 4) - -#define HDA_CODEC_FMT_CHAN_MASK (0x0f << 0) - -#define HDA_CODEC_AUDIO_WCAP_OUTPUT \ - (0x00 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_INPUT \ - (0x01 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_PIN \ - (0x04 << HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_CONN_LIST \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_FORMAT_OVR \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_AMP_OVR \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_OUT_AMP \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_IN_AMP \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT) -#define HDA_CODEC_AUDIO_WCAP_STEREO \ - (1 << HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT) - -#define HDA_CODEC_PIN_CAP_OUTPUT \ - (1 << HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT) -#define HDA_CODEC_PIN_CAP_INPUT \ - (1 << HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT) -#define HDA_CODEC_PIN_CAP_PRESENCE_DETECT \ - (1 << HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT) - -#define HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP \ - (1 << HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT) -#define HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE \ - (0x03 << HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) -#define HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS \ - (HDA_CODEC_AMP_NUMSTEPS << HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) -#define HDA_CODEC_OUTPUT_AMP_CAP_OFFSET \ - (HDA_CODEC_AMP_NUMSTEPS << HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT) - -#define HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE 0x80 -#define HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK 0x7f - -#define HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED (1 << 31) -#define HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE \ - (1 << HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT) -#define HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE \ - (1 << HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT) - -#define HDA_CONFIG_DEFAULTCONF_COLOR_BLACK \ - (0x01 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_COLOR_RED \ - (0x05 << HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) - -#define HDA_CODEC_BUF_SIZE HDA_FIFO_SIZE - -#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) - - -/* - * HDA Audio Context data structures - */ - -typedef void (*transfer_func_t)(void *arg); -typedef int (*setup_func_t)(void *arg); - -struct hda_audio_ctxt { - char name[64]; - uint8_t run; - uint8_t started; - void *priv; - pthread_t tid; - pthread_mutex_t mtx; - pthread_cond_t cond; - setup_func_t do_setup; - transfer_func_t do_transfer; -}; - -/* - * HDA Audio Context module function declarations - */ - -static void *hda_audio_ctxt_thr(void *arg); -static int hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, - transfer_func_t do_transfer, setup_func_t do_setup, void *priv); -static int hda_audio_ctxt_start(struct hda_audio_ctxt *actx); -static int hda_audio_ctxt_stop(struct hda_audio_ctxt *actx); - -/* - * HDA Codec data structures - */ - -struct hda_codec_softc; - -typedef uint32_t (*verb_func_t)(struct hda_codec_softc *sc, uint16_t verb, - uint16_t payload); - -struct hda_codec_stream { - uint8_t buf[HDA_CODEC_BUF_SIZE]; - uint8_t channel; - uint16_t fmt; - uint8_t stream; - - uint8_t left_gain; - uint8_t right_gain; - uint8_t left_mute; - uint8_t right_mute; - - struct audio *aud; - struct hda_audio_ctxt actx; -}; - -struct hda_codec_softc { - uint32_t no_nodes; - uint32_t subsystem_id; - const uint32_t (*get_parameters)[HDA_CODEC_PARAMS_COUNT]; - const uint8_t (*conn_list)[HDA_CODEC_CONN_LIST_COUNT]; - const uint32_t *conf_default; - const uint8_t *pin_ctrl_default; - const verb_func_t *verb_handlers; - - struct hda_codec_inst *hci; - struct hda_codec_stream streams[HDA_CODEC_STREAMS_COUNT]; -}; - -/* - * HDA Codec module function declarations - */ -static int hda_codec_init(struct hda_codec_inst *hci, const char *play, - const char *rec, const char *opts); -static int hda_codec_reset(struct hda_codec_inst *hci); -static int hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data); -static int hda_codec_notify(struct hda_codec_inst *hci, uint8_t run, - uint8_t stream, uint8_t dir); - -static int hda_codec_parse_format(uint16_t fmt, struct audio_params *params); - -static uint32_t hda_codec_audio_output_nid(struct hda_codec_softc *sc, - uint16_t verb, uint16_t payload); -static void hda_codec_audio_output_do_transfer(void *arg); -static int hda_codec_audio_output_do_setup(void *arg); -static uint32_t hda_codec_audio_input_nid(struct hda_codec_softc *sc, - uint16_t verb, uint16_t payload); -static void hda_codec_audio_input_do_transfer(void *arg); -static int hda_codec_audio_input_do_setup(void *arg); - -static uint32_t hda_codec_audio_inout_nid(struct hda_codec_stream *st, - uint16_t verb, uint16_t payload); - -/* - * HDA Codec global data - */ - -#define HDA_CODEC_ROOT_DESC \ - [HDA_CODEC_ROOT_NID] = { \ - [HDA_PARAM_VENDOR_ID] = INTEL_VENDORID, \ - [HDA_PARAM_REVISION_ID] = 0xffff, \ - /* 1 Subnode, StartNid = 1 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00010001, \ - }, \ - -#define HDA_CODEC_FG_COMMON_DESC \ - [HDA_PARAM_FCT_GRP_TYPE] = HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO,\ - /* B8 - B32, 8.0 - 192.0kHz */ \ - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x1f << 16) | 0x7ff, \ - [HDA_PARAM_SUPP_STREAM_FORMATS] = HDA_CODEC_SUPP_STREAM_FORMATS_PCM,\ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_GPIO_COUNT] = 0x00, \ - -#define HDA_CODEC_FG_OUTPUT_DESC \ - [HDA_CODEC_FG_NID] = { \ - /* 2 Subnodes, StartNid = 2 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00020002, \ - HDA_CODEC_FG_COMMON_DESC \ - }, \ - -#define HDA_CODEC_FG_INPUT_DESC \ - [HDA_CODEC_FG_NID] = { \ - /* 2 Subnodes, StartNid = 4 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00040002, \ - HDA_CODEC_FG_COMMON_DESC \ - }, \ - -#define HDA_CODEC_FG_DUPLEX_DESC \ - [HDA_CODEC_FG_NID] = { \ - /* 4 Subnodes, StartNid = 2 */ \ - [HDA_PARAM_SUB_NODE_COUNT] = 0x00020004, \ - HDA_CODEC_FG_COMMON_DESC \ - }, \ - -#define HDA_CODEC_OUTPUT_DESC \ - [HDA_CODEC_AUDIO_OUTPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_OUTPUT | \ - HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | \ - HDA_CODEC_AUDIO_WCAP_AMP_OVR | \ - HDA_CODEC_AUDIO_WCAP_OUT_AMP | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - /* B16, 16.0 - 192.0kHz */ \ - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, \ - [HDA_PARAM_SUPP_STREAM_FORMATS] = \ - HDA_CODEC_SUPP_STREAM_FORMATS_PCM, \ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x00, \ - [HDA_PARAM_OUTPUT_AMP_CAP] = \ - HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | \ - HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | \ - HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | \ - HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, \ - }, \ - [HDA_CODEC_PIN_OUTPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_PIN | \ - HDA_CODEC_AUDIO_WCAP_CONN_LIST | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_OUTPUT | \ - HDA_CODEC_PIN_CAP_PRESENCE_DETECT,\ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - }, \ - -#define HDA_CODEC_INPUT_DESC \ - [HDA_CODEC_AUDIO_INPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_INPUT | \ - HDA_CODEC_AUDIO_WCAP_CONN_LIST | \ - HDA_CODEC_AUDIO_WCAP_FORMAT_OVR | \ - HDA_CODEC_AUDIO_WCAP_AMP_OVR | \ - HDA_CODEC_AUDIO_WCAP_IN_AMP | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - /* B16, 16.0 - 192.0kHz */ \ - [HDA_PARAM_SUPP_PCM_SIZE_RATE] = (0x02 << 16) | 0x7fc, \ - [HDA_PARAM_SUPP_STREAM_FORMATS] = \ - HDA_CODEC_SUPP_STREAM_FORMATS_PCM, \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_CONN_LIST_LENGTH] = 0x01, \ - [HDA_PARAM_INPUT_AMP_CAP] = \ - HDA_CODEC_OUTPUT_AMP_CAP_MUTE_CAP | \ - HDA_CODEC_OUTPUT_AMP_CAP_STEPSIZE | \ - HDA_CODEC_OUTPUT_AMP_CAP_NUMSTEPS | \ - HDA_CODEC_OUTPUT_AMP_CAP_OFFSET, \ - }, \ - [HDA_CODEC_PIN_INPUT_NID] = { \ - [HDA_PARAM_AUDIO_WIDGET_CAP] = \ - HDA_CODEC_AUDIO_WCAP_PIN | \ - HDA_CODEC_AUDIO_WCAP_STEREO, \ - [HDA_PARAM_PIN_CAP] = HDA_CODEC_PIN_CAP_INPUT | \ - HDA_CODEC_PIN_CAP_PRESENCE_DETECT, \ - [HDA_PARAM_INPUT_AMP_CAP] = 0x00, /* None */ \ - [HDA_PARAM_OUTPUT_AMP_CAP] = 0x00, /* None */ \ - }, \ - -static const uint32_t -hda_codec_output_parameters[][HDA_CODEC_PARAMS_COUNT] = { - HDA_CODEC_ROOT_DESC - HDA_CODEC_FG_OUTPUT_DESC - HDA_CODEC_OUTPUT_DESC -}; - -static const uint32_t -hda_codec_input_parameters[][HDA_CODEC_PARAMS_COUNT] = { - HDA_CODEC_ROOT_DESC - HDA_CODEC_FG_INPUT_DESC - HDA_CODEC_INPUT_DESC -}; - -static const uint32_t -hda_codec_duplex_parameters[][HDA_CODEC_PARAMS_COUNT] = { - HDA_CODEC_ROOT_DESC - HDA_CODEC_FG_DUPLEX_DESC - HDA_CODEC_OUTPUT_DESC - HDA_CODEC_INPUT_DESC -}; - -#define HDA_CODEC_NODES_COUNT (ARRAY_SIZE(hda_codec_duplex_parameters)) - -static const uint8_t -hda_codec_conn_list[HDA_CODEC_NODES_COUNT][HDA_CODEC_CONN_LIST_COUNT] = { - [HDA_CODEC_PIN_OUTPUT_NID] = {HDA_CODEC_AUDIO_OUTPUT_NID}, - [HDA_CODEC_AUDIO_INPUT_NID] = {HDA_CODEC_PIN_INPUT_NID}, -}; - -static const uint32_t -hda_codec_conf_default[HDA_CODEC_NODES_COUNT] = { - [HDA_CODEC_PIN_OUTPUT_NID] = \ - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK | - HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT | - HDA_CONFIG_DEFAULTCONF_COLOR_BLACK | - (0x01 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT), - [HDA_CODEC_PIN_INPUT_NID] = HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK | - HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN | - HDA_CONFIG_DEFAULTCONF_COLOR_RED | - (0x02 << HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT), -}; - -static const uint8_t -hda_codec_pin_ctrl_default[HDA_CODEC_NODES_COUNT] = { - [HDA_CODEC_PIN_OUTPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_OUT_ENABLE, - [HDA_CODEC_PIN_INPUT_NID] = HDA_CODEC_PIN_WIDGET_CTRL_IN_ENABLE, -}; - -static const -verb_func_t hda_codec_verb_handlers[HDA_CODEC_NODES_COUNT] = { - [HDA_CODEC_AUDIO_OUTPUT_NID] = hda_codec_audio_output_nid, - [HDA_CODEC_AUDIO_INPUT_NID] = hda_codec_audio_input_nid, -}; - -/* - * HDA Codec module function definitions - */ - -static int -hda_codec_init(struct hda_codec_inst *hci, const char *play, - const char *rec, const char *opts) -{ - struct hda_codec_softc *sc = NULL; - struct hda_codec_stream *st = NULL; - int err; - - if (!(play || rec)) - return (-1); - - DPRINTF("cad: 0x%x opts: %s\n", hci->cad, opts); - - sc = calloc(1, sizeof(*sc)); - if (!sc) - return (-1); - - if (play && rec) - sc->get_parameters = hda_codec_duplex_parameters; - else { - if (play) - sc->get_parameters = hda_codec_output_parameters; - else - sc->get_parameters = hda_codec_input_parameters; - } - sc->subsystem_id = HDA_CODEC_SUBSYSTEM_ID; - sc->no_nodes = HDA_CODEC_NODES_COUNT; - sc->conn_list = hda_codec_conn_list; - sc->conf_default = hda_codec_conf_default; - sc->pin_ctrl_default = hda_codec_pin_ctrl_default; - sc->verb_handlers = hda_codec_verb_handlers; - DPRINTF("HDA Codec nodes: %d\n", sc->no_nodes); - - /* - * Initialize the Audio Output stream - */ - if (play) { - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - - err = hda_audio_ctxt_init(&st->actx, "hda-audio-output", - hda_codec_audio_output_do_transfer, - hda_codec_audio_output_do_setup, sc); - assert(!err); - - st->aud = audio_init(play, 1); - if (!st->aud) { - DPRINTF("Fail to init the output audio player\n"); - return (-1); - } - } - - /* - * Initialize the Audio Input stream - */ - if (rec) { - st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - - err = hda_audio_ctxt_init(&st->actx, "hda-audio-input", - hda_codec_audio_input_do_transfer, - hda_codec_audio_input_do_setup, sc); - assert(!err); - - st->aud = audio_init(rec, 0); - if (!st->aud) { - DPRINTF("Fail to init the input audio player\n"); - return (-1); - } - } - - sc->hci = hci; - hci->priv = sc; - - return (0); -} - -static int -hda_codec_reset(struct hda_codec_inst *hci) -{ - struct hda_ops *hops = NULL; - struct hda_codec_softc *sc = NULL; - struct hda_codec_stream *st = NULL; - int i; - - assert(hci); - - hops = hci->hops; - assert(hops); - - sc = (struct hda_codec_softc *)hci->priv; - assert(sc); - - for (i = 0; i < HDA_CODEC_STREAMS_COUNT; i++) { - st = &sc->streams[i]; - st->left_gain = HDA_CODEC_AMP_NUMSTEPS; - st->right_gain = HDA_CODEC_AMP_NUMSTEPS; - st->left_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; - st->right_mute = HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; - } - - DPRINTF("cad: 0x%x\n", hci->cad); - - if (!hops->signal) { - DPRINTF("The controller ops does not implement \ - the signal function\n"); - return (-1); - } - - return (hops->signal(hci)); -} - -static int -hda_codec_command(struct hda_codec_inst *hci, uint32_t cmd_data) -{ - struct hda_codec_softc *sc = NULL; - struct hda_ops *hops = NULL; - uint8_t cad = 0, nid = 0; - uint16_t verb = 0, payload = 0; - uint32_t res = 0; - - /* 4 bits */ - cad = (cmd_data >> HDA_CMD_CAD_SHIFT) & 0x0f; - /* 8 bits */ - nid = (cmd_data >> HDA_CMD_NID_SHIFT) & 0xff; - - if ((cmd_data & 0x70000) == 0x70000) { - /* 12 bits */ - verb = (cmd_data >> HDA_CMD_VERB_12BIT_SHIFT) & 0x0fff; - /* 8 bits */ - payload = cmd_data & 0xff; - } else { - /* 4 bits */ - verb = (cmd_data >> HDA_CMD_VERB_4BIT_SHIFT) & 0x0f; - /* 16 bits */ - payload = cmd_data & 0xffff; - } - - assert(cad == hci->cad); - assert(hci); - - hops = hci->hops; - assert(hops); - - sc = (struct hda_codec_softc *)hci->priv; - assert(sc); - - assert(nid < sc->no_nodes); - - if (!hops->response) { - DPRINTF("The controller ops does not implement \ - the response function\n"); - return (-1); - } - - switch (verb) { - case HDA_CMD_VERB_GET_PARAMETER: - res = sc->get_parameters[nid][payload]; - break; - case HDA_CMD_VERB_GET_CONN_LIST_ENTRY: - res = sc->conn_list[nid][0]; - break; - case HDA_CMD_VERB_GET_PIN_WIDGET_CTRL: - res = sc->pin_ctrl_default[nid]; - break; - case HDA_CMD_VERB_GET_PIN_SENSE: - res = HDA_CODEC_PIN_SENSE_PRESENCE_PLUGGED; - break; - case HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT: - res = sc->conf_default[nid]; - break; - case HDA_CMD_VERB_GET_SUBSYSTEM_ID: - res = sc->subsystem_id; - break; - default: - assert(sc->verb_handlers); - if (sc->verb_handlers[nid]) - res = sc->verb_handlers[nid](sc, verb, payload); - else - DPRINTF("Unknown VERB: 0x%x\n", verb); - break; - } - - DPRINTF("cad: 0x%x nid: 0x%x verb: 0x%x payload: 0x%x response: 0x%x\n", - cad, nid, verb, payload, res); - - return (hops->response(hci, res, HDA_CODEC_RESPONSE_EX_SOL)); -} - -static int -hda_codec_notify(struct hda_codec_inst *hci, uint8_t run, - uint8_t stream, uint8_t dir) -{ - struct hda_codec_softc *sc = NULL; - struct hda_codec_stream *st = NULL; - struct hda_audio_ctxt *actx = NULL; - int i; - int err; - - assert(hci); - assert(stream); - - sc = (struct hda_codec_softc *)hci->priv; - assert(sc); - - i = dir ? HDA_CODEC_STREAM_OUTPUT : HDA_CODEC_STREAM_INPUT; - st = &sc->streams[i]; - - DPRINTF("run: %d, stream: 0x%x, st->stream: 0x%x dir: %d\n", - run, stream, st->stream, dir); - - if (stream != st->stream) { - DPRINTF("Stream not found\n"); - return (0); - } - - actx = &st->actx; - - if (run) - err = hda_audio_ctxt_start(actx); - else - err = hda_audio_ctxt_stop(actx); - - return (err); -} - -static int -hda_codec_parse_format(uint16_t fmt, struct audio_params *params) -{ - uint8_t div = 0; - - assert(params); - - /* Compute the Sample Rate */ - params->rate = (fmt & HDA_CODEC_FMT_BASE_MASK) ? 44100 : 48000; - - switch (fmt & HDA_CODEC_FMT_MULT_MASK) { - case HDA_CODEC_FMT_MULT_2: - params->rate *= 2; - break; - case HDA_CODEC_FMT_MULT_3: - params->rate *= 3; - break; - case HDA_CODEC_FMT_MULT_4: - params->rate *= 4; - break; - } - - div = (fmt >> HDA_CODEC_FMT_DIV_SHIFT) & HDA_CODEC_FMT_DIV_MASK; - params->rate /= (div + 1); - - /* Compute the Bits per Sample */ - switch (fmt & HDA_CODEC_FMT_BITS_MASK) { - case HDA_CODEC_FMT_BITS_8: - params->format = AFMT_U8; - break; - case HDA_CODEC_FMT_BITS_16: - params->format = AFMT_S16_LE; - break; - case HDA_CODEC_FMT_BITS_24: - params->format = AFMT_S24_LE; - break; - case HDA_CODEC_FMT_BITS_32: - params->format = AFMT_S32_LE; - break; - default: - DPRINTF("Unknown format bits: 0x%x\n", - fmt & HDA_CODEC_FMT_BITS_MASK); - return (-1); - } - - /* Compute the Number of Channels */ - params->channels = (fmt & HDA_CODEC_FMT_CHAN_MASK) + 1; - - return (0); -} - -static uint32_t -hda_codec_audio_output_nid(struct hda_codec_softc *sc, uint16_t verb, - uint16_t payload) -{ - struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - int res; - - res = hda_codec_audio_inout_nid(st, verb, payload); - - return (res); -} - -static void -hda_codec_audio_output_do_transfer(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_inst *hci = NULL; - struct hda_ops *hops = NULL; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - int err; - - hci = sc->hci; - assert(hci); - - hops = hci->hops; - assert(hops); - - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - aud = st->aud; - - err = hops->transfer(hci, st->stream, 1, st->buf, sizeof(st->buf)); - if (err) - return; - - err = audio_playback(aud, st->buf, sizeof(st->buf)); - assert(!err); -} - -static int -hda_codec_audio_output_do_setup(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - struct audio_params params; - int err; - - st = &sc->streams[HDA_CODEC_STREAM_OUTPUT]; - aud = st->aud; - - err = hda_codec_parse_format(st->fmt, ¶ms); - if (err) - return (-1); - - DPRINTF("rate: %d, channels: %d, format: 0x%x\n", - params.rate, params.channels, params.format); - - return (audio_set_params(aud, ¶ms)); -} - -static uint32_t -hda_codec_audio_input_nid(struct hda_codec_softc *sc, uint16_t verb, - uint16_t payload) -{ - struct hda_codec_stream *st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - int res; - - res = hda_codec_audio_inout_nid(st, verb, payload); - - return (res); -} - -static void -hda_codec_audio_input_do_transfer(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_inst *hci = NULL; - struct hda_ops *hops = NULL; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - int err; - - hci = sc->hci; - assert(hci); - - hops = hci->hops; - assert(hops); - - st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - aud = st->aud; - - err = audio_record(aud, st->buf, sizeof(st->buf)); - assert(!err); - - hops->transfer(hci, st->stream, 0, st->buf, sizeof(st->buf)); -} - -static int -hda_codec_audio_input_do_setup(void *arg) -{ - struct hda_codec_softc *sc = (struct hda_codec_softc *)arg; - struct hda_codec_stream *st = NULL; - struct audio *aud = NULL; - struct audio_params params; - int err; - - st = &sc->streams[HDA_CODEC_STREAM_INPUT]; - aud = st->aud; - - err = hda_codec_parse_format(st->fmt, ¶ms); - if (err) - return (-1); - - DPRINTF("rate: %d, channels: %d, format: 0x%x\n", - params.rate, params.channels, params.format); - - return (audio_set_params(aud, ¶ms)); -} - -static uint32_t -hda_codec_audio_inout_nid(struct hda_codec_stream *st, uint16_t verb, - uint16_t payload) -{ - uint32_t res = 0; - uint8_t mute = 0; - uint8_t gain = 0; - - DPRINTF("%s verb: 0x%x, payload, 0x%x\n", st->actx.name, verb, payload); - - switch (verb) { - case HDA_CMD_VERB_GET_CONV_FMT: - res = st->fmt; - break; - case HDA_CMD_VERB_SET_CONV_FMT: - st->fmt = payload; - break; - case HDA_CMD_VERB_GET_AMP_GAIN_MUTE: - if (payload & HDA_CMD_GET_AMP_GAIN_MUTE_LEFT) { - res = st->left_gain | st->left_mute; - DPRINTF("GET_AMP_GAIN_MUTE_LEFT: 0x%x\n", res); - } else { - res = st->right_gain | st->right_mute; - DPRINTF("GET_AMP_GAIN_MUTE_RIGHT: 0x%x\n", res); - } - break; - case HDA_CMD_VERB_SET_AMP_GAIN_MUTE: - mute = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_MUTE; - gain = payload & HDA_CODEC_SET_AMP_GAIN_MUTE_GAIN_MASK; - - if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_LEFT) { - st->left_mute = mute; - st->left_gain = gain; - DPRINTF("SET_AMP_GAIN_MUTE_LEFT: \ - mute: 0x%x gain: 0x%x\n", mute, gain); - } - - if (payload & HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT) { - st->right_mute = mute; - st->right_gain = gain; - DPRINTF("SET_AMP_GAIN_MUTE_RIGHT: \ - mute: 0x%x gain: 0x%x\n", mute, gain); - } - break; - case HDA_CMD_VERB_GET_CONV_STREAM_CHAN: - res = (st->stream << 4) | st->channel; - break; - case HDA_CMD_VERB_SET_CONV_STREAM_CHAN: - st->channel = payload & 0x0f; - st->stream = (payload >> 4) & 0x0f; - DPRINTF("st->channel: 0x%x st->stream: 0x%x\n", - st->channel, st->stream); - if (!st->stream) - hda_audio_ctxt_stop(&st->actx); - break; - default: - DPRINTF("Unknown VERB: 0x%x\n", verb); - break; - } - - return (res); -} - -struct hda_codec_class hda_codec = { - .name = "hda_codec", - .init = hda_codec_init, - .reset = hda_codec_reset, - .command = hda_codec_command, - .notify = hda_codec_notify, -}; - -HDA_EMUL_SET(hda_codec); - - -/* - * HDA Audio Context module function definitions - */ - -static void * -hda_audio_ctxt_thr(void *arg) -{ - struct hda_audio_ctxt *actx = arg; - - DPRINTF("Start Thread: %s\n", actx->name); - - pthread_mutex_lock(&actx->mtx); - while (1) { - while (!actx->run) - pthread_cond_wait(&actx->cond, &actx->mtx); - - actx->do_transfer(actx->priv); - } - pthread_mutex_unlock(&actx->mtx); - - pthread_exit(NULL); - return (NULL); -} - -static int -hda_audio_ctxt_init(struct hda_audio_ctxt *actx, const char *tname, - transfer_func_t do_transfer, setup_func_t do_setup, void *priv) -{ - int err; - - assert(actx); - assert(tname); - assert(do_transfer); - assert(do_setup); - assert(priv); - - memset(actx, 0, sizeof(*actx)); - - actx->run = 0; - actx->do_transfer = do_transfer; - actx->do_setup = do_setup; - actx->priv = priv; - if (strlen(tname) < sizeof(actx->name)) - memcpy(actx->name, tname, strlen(tname) + 1); - else - strcpy(actx->name, "unknown"); - - err = pthread_mutex_init(&actx->mtx, NULL); - assert(!err); - - err = pthread_cond_init(&actx->cond, NULL); - assert(!err); - - err = pthread_create(&actx->tid, NULL, hda_audio_ctxt_thr, actx); - assert(!err); - - pthread_set_name_np(actx->tid, tname); - - actx->started = 1; - - return (0); -} - -static int -hda_audio_ctxt_start(struct hda_audio_ctxt *actx) -{ - int err = 0; - - assert(actx); - assert(actx->started); - - /* The stream is supposed to be stopped */ - if (actx->run) - return (-1); - - pthread_mutex_lock(&actx->mtx); - err = (* actx->do_setup)(actx->priv); - if (!err) { - actx->run = 1; - pthread_cond_signal(&actx->cond); - } - pthread_mutex_unlock(&actx->mtx); - - return (err); -} - -static int -hda_audio_ctxt_stop(struct hda_audio_ctxt *actx) -{ - actx->run = 0; - return (0); -} diff --git a/usr.sbin/bhyve/hda_reg.h b/usr.sbin/bhyve/hda_reg.h deleted file mode 100644 index dd7098524537..000000000000 --- a/usr.sbin/bhyve/hda_reg.h +++ /dev/null @@ -1,1367 +0,0 @@ -/*- - * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _HDA_REG_H_ -#define _HDA_REG_H_ - -/**************************************************************************** - * HDA Device Verbs - ****************************************************************************/ - -/* HDA Command */ -#define HDA_CMD_VERB_MASK 0x000fffff -#define HDA_CMD_VERB_SHIFT 0 -#define HDA_CMD_NID_MASK 0x0ff00000 -#define HDA_CMD_NID_SHIFT 20 -#define HDA_CMD_CAD_MASK 0xf0000000 -#define HDA_CMD_CAD_SHIFT 28 - -#define HDA_CMD_VERB_4BIT_SHIFT 16 -#define HDA_CMD_VERB_12BIT_SHIFT 8 - -#define HDA_CMD_VERB_4BIT(verb, payload) \ - (((verb) << HDA_CMD_VERB_4BIT_SHIFT) | (payload)) -#define HDA_CMD_4BIT(cad, nid, verb, payload) \ - (((cad) << HDA_CMD_CAD_SHIFT) | \ - ((nid) << HDA_CMD_NID_SHIFT) | \ - (HDA_CMD_VERB_4BIT((verb), (payload)))) - -#define HDA_CMD_VERB_12BIT(verb, payload) \ - (((verb) << HDA_CMD_VERB_12BIT_SHIFT) | (payload)) -#define HDA_CMD_12BIT(cad, nid, verb, payload) \ - (((cad) << HDA_CMD_CAD_SHIFT) | \ - ((nid) << HDA_CMD_NID_SHIFT) | \ - (HDA_CMD_VERB_12BIT((verb), (payload)))) - -/* Get Parameter */ -#define HDA_CMD_VERB_GET_PARAMETER 0xf00 - -#define HDA_CMD_GET_PARAMETER(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PARAMETER, (payload))) - -/* Connection Select Control */ -#define HDA_CMD_VERB_GET_CONN_SELECT_CONTROL 0xf01 -#define HDA_CMD_VERB_SET_CONN_SELECT_CONTROL 0x701 - -#define HDA_CMD_GET_CONN_SELECT_CONTROL(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONN_SELECT_CONTROL, 0x0)) -#define HDA_CMD_SET_CONNECTION_SELECT_CONTROL(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONN_SELECT_CONTROL, (payload))) - -/* Connection List Entry */ -#define HDA_CMD_VERB_GET_CONN_LIST_ENTRY 0xf02 - -#define HDA_CMD_GET_CONN_LIST_ENTRY(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONN_LIST_ENTRY, (payload))) - -#define HDA_CMD_GET_CONN_LIST_ENTRY_SIZE_SHORT 1 -#define HDA_CMD_GET_CONN_LIST_ENTRY_SIZE_LONG 2 - -/* Processing State */ -#define HDA_CMD_VERB_GET_PROCESSING_STATE 0xf03 -#define HDA_CMD_VERB_SET_PROCESSING_STATE 0x703 - -#define HDA_CMD_GET_PROCESSING_STATE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PROCESSING_STATE, 0x0)) -#define HDA_CMD_SET_PROCESSING_STATE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PROCESSING_STATE, (payload))) - -#define HDA_CMD_GET_PROCESSING_STATE_STATE_OFF 0x00 -#define HDA_CMD_GET_PROCESSING_STATE_STATE_ON 0x01 -#define HDA_CMD_GET_PROCESSING_STATE_STATE_BENIGN 0x02 - -/* Coefficient Index */ -#define HDA_CMD_VERB_GET_COEFF_INDEX 0xd -#define HDA_CMD_VERB_SET_COEFF_INDEX 0x5 - -#define HDA_CMD_GET_COEFF_INDEX(cad, nid) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_COEFF_INDEX, 0x0)) -#define HDA_CMD_SET_COEFF_INDEX(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_COEFF_INDEX, (payload))) - -/* Processing Coefficient */ -#define HDA_CMD_VERB_GET_PROCESSING_COEFF 0xc -#define HDA_CMD_VERB_SET_PROCESSING_COEFF 0x4 - -#define HDA_CMD_GET_PROCESSING_COEFF(cad, nid) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PROCESSING_COEFF, 0x0)) -#define HDA_CMD_SET_PROCESSING_COEFF(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PROCESSING_COEFF, (payload))) - -/* Amplifier Gain/Mute */ -#define HDA_CMD_VERB_GET_AMP_GAIN_MUTE 0xb -#define HDA_CMD_VERB_SET_AMP_GAIN_MUTE 0x3 - -#define HDA_CMD_GET_AMP_GAIN_MUTE(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_AMP_GAIN_MUTE, (payload))) -#define HDA_CMD_SET_AMP_GAIN_MUTE(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_AMP_GAIN_MUTE, (payload))) - -#define HDA_CMD_GET_AMP_GAIN_MUTE_INPUT 0x0000 -#define HDA_CMD_GET_AMP_GAIN_MUTE_OUTPUT 0x8000 -#define HDA_CMD_GET_AMP_GAIN_MUTE_RIGHT 0x0000 -#define HDA_CMD_GET_AMP_GAIN_MUTE_LEFT 0x2000 - -#define HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_MASK 0x00000008 -#define HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_SHIFT 7 -#define HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_MASK 0x00000007 -#define HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_SHIFT 0 - -#define HDA_CMD_GET_AMP_GAIN_MUTE_MUTE(rsp) \ - (((rsp) & HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_MASK) >> \ - HDA_CMD_GET_AMP_GAIN_MUTE_MUTE_SHIFT) -#define HDA_CMD_GET_AMP_GAIN_MUTE_GAIN(rsp) \ - (((rsp) & HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_MASK) >> \ - HDA_CMD_GET_AMP_GAIN_MUTE_GAIN_SHIFT) - -#define HDA_CMD_SET_AMP_GAIN_MUTE_OUTPUT 0x8000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_INPUT 0x4000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_LEFT 0x2000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_RIGHT 0x1000 -#define HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_MASK 0x0f00 -#define HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_SHIFT 8 -#define HDA_CMD_SET_AMP_GAIN_MUTE_MUTE 0x0080 -#define HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_MASK 0x0007 -#define HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_SHIFT 0 - -#define HDA_CMD_SET_AMP_GAIN_MUTE_INDEX(index) \ - (((index) << HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_SHIFT) & \ - HDA_CMD_SET_AMP_GAIN_MUTE_INDEX_MASK) -#define HDA_CMD_SET_AMP_GAIN_MUTE_GAIN(index) \ - (((index) << HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_SHIFT) & \ - HDA_CMD_SET_AMP_GAIN_MUTE_GAIN_MASK) - -/* Converter format */ -#define HDA_CMD_VERB_GET_CONV_FMT 0xa -#define HDA_CMD_VERB_SET_CONV_FMT 0x2 - -#define HDA_CMD_GET_CONV_FMT(cad, nid) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONV_FMT, 0x0)) -#define HDA_CMD_SET_CONV_FMT(cad, nid, payload) \ - (HDA_CMD_4BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONV_FMT, (payload))) - -/* Digital Converter Control */ -#define HDA_CMD_VERB_GET_DIGITAL_CONV_FMT1 0xf0d -#define HDA_CMD_VERB_GET_DIGITAL_CONV_FMT2 0xf0e -#define HDA_CMD_VERB_SET_DIGITAL_CONV_FMT1 0x70d -#define HDA_CMD_VERB_SET_DIGITAL_CONV_FMT2 0x70e - -#define HDA_CMD_GET_DIGITAL_CONV_FMT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_DIGITAL_CONV_FMT1, 0x0)) -#define HDA_CMD_SET_DIGITAL_CONV_FMT1(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_DIGITAL_CONV_FMT1, (payload))) -#define HDA_CMD_SET_DIGITAL_CONV_FMT2(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_DIGITAL_CONV_FMT2, (payload))) - -#define HDA_CMD_GET_DIGITAL_CONV_FMT_CC_MASK 0x7f00 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_CC_SHIFT 8 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_L_MASK 0x0080 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_L_SHIFT 7 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_MASK 0x0040 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_SHIFT 6 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_MASK 0x0020 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_SHIFT 5 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_MASK 0x0010 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_SHIFT 4 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_MASK 0x0008 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_SHIFT 3 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_MASK 0x0004 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_SHIFT 2 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_V_MASK 0x0002 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_V_SHIFT 1 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_MASK 0x0001 -#define HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_SHIFT 0 - -#define HDA_CMD_GET_DIGITAL_CONV_FMT_CC(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_CC_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_CC_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_L(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_L_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_L_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRO(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_PRO_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_NAUDIO_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_COPY(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_COPY_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_PRE(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_PRE_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_VCFG_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_V(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_V_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_V_SHIFT) -#define HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN(rsp) \ - (((rsp) & HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_MASK) >> \ - HDA_CMD_GET_DIGITAL_CONV_FMT_DIGEN_SHIFT) - -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_L 0x80 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_PRO 0x40 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_NAUDIO 0x20 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_COPY 0x10 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_PRE 0x08 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_VCFG 0x04 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_V 0x02 -#define HDA_CMD_SET_DIGITAL_CONV_FMT1_DIGEN 0x01 - -/* Power State */ -#define HDA_CMD_VERB_GET_POWER_STATE 0xf05 -#define HDA_CMD_VERB_SET_POWER_STATE 0x705 - -#define HDA_CMD_GET_POWER_STATE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_POWER_STATE, 0x0)) -#define HDA_CMD_SET_POWER_STATE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_POWER_STATE, (payload))) - -#define HDA_CMD_POWER_STATE_D0 0x00 -#define HDA_CMD_POWER_STATE_D1 0x01 -#define HDA_CMD_POWER_STATE_D2 0x02 -#define HDA_CMD_POWER_STATE_D3 0x03 - -#define HDA_CMD_POWER_STATE_ACT_MASK 0x000000f0 -#define HDA_CMD_POWER_STATE_ACT_SHIFT 4 -#define HDA_CMD_POWER_STATE_SET_MASK 0x0000000f -#define HDA_CMD_POWER_STATE_SET_SHIFT 0 - -#define HDA_CMD_GET_POWER_STATE_ACT(rsp) \ - (((rsp) & HDA_CMD_POWER_STATE_ACT_MASK) >> \ - HDA_CMD_POWER_STATE_ACT_SHIFT) -#define HDA_CMD_GET_POWER_STATE_SET(rsp) \ - (((rsp) & HDA_CMD_POWER_STATE_SET_MASK) >> \ - HDA_CMD_POWER_STATE_SET_SHIFT) - -#define HDA_CMD_SET_POWER_STATE_ACT(ps) \ - (((ps) << HDA_CMD_POWER_STATE_ACT_SHIFT) & \ - HDA_CMD_POWER_STATE_ACT_MASK) -#define HDA_CMD_SET_POWER_STATE_SET(ps) \ - (((ps) << HDA_CMD_POWER_STATE_SET_SHIFT) & \ - HDA_CMD_POWER_STATE_ACT_MASK) - -/* Converter Stream, Channel */ -#define HDA_CMD_VERB_GET_CONV_STREAM_CHAN 0xf06 -#define HDA_CMD_VERB_SET_CONV_STREAM_CHAN 0x706 - -#define HDA_CMD_GET_CONV_STREAM_CHAN(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONV_STREAM_CHAN, 0x0)) -#define HDA_CMD_SET_CONV_STREAM_CHAN(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONV_STREAM_CHAN, (payload))) - -#define HDA_CMD_CONV_STREAM_CHAN_STREAM_MASK 0x000000f0 -#define HDA_CMD_CONV_STREAM_CHAN_STREAM_SHIFT 4 -#define HDA_CMD_CONV_STREAM_CHAN_CHAN_MASK 0x0000000f -#define HDA_CMD_CONV_STREAM_CHAN_CHAN_SHIFT 0 - -#define HDA_CMD_GET_CONV_STREAM_CHAN_STREAM(rsp) \ - (((rsp) & HDA_CMD_CONV_STREAM_CHAN_STREAM_MASK) >> \ - HDA_CMD_CONV_STREAM_CHAN_STREAM_SHIFT) -#define HDA_CMD_GET_CONV_STREAM_CHAN_CHAN(rsp) \ - (((rsp) & HDA_CMD_CONV_STREAM_CHAN_CHAN_MASK) >> \ - HDA_CMD_CONV_STREAM_CHAN_CHAN_SHIFT) - -#define HDA_CMD_SET_CONV_STREAM_CHAN_STREAM(param) \ - (((param) << HDA_CMD_CONV_STREAM_CHAN_STREAM_SHIFT) & \ - HDA_CMD_CONV_STREAM_CHAN_STREAM_MASK) -#define HDA_CMD_SET_CONV_STREAM_CHAN_CHAN(param) \ - (((param) << HDA_CMD_CONV_STREAM_CHAN_CHAN_SHIFT) & \ - HDA_CMD_CONV_STREAM_CHAN_CHAN_MASK) - -/* Input Converter SDI Select */ -#define HDA_CMD_VERB_GET_INPUT_CONVERTER_SDI_SELECT 0xf04 -#define HDA_CMD_VERB_SET_INPUT_CONVERTER_SDI_SELECT 0x704 - -#define HDA_CMD_GET_INPUT_CONVERTER_SDI_SELECT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_INPUT_CONVERTER_SDI_SELECT, 0x0)) -#define HDA_CMD_SET_INPUT_CONVERTER_SDI_SELECT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_INPUT_CONVERTER_SDI_SELECT, (payload))) - -/* Pin Widget Control */ -#define HDA_CMD_VERB_GET_PIN_WIDGET_CTRL 0xf07 -#define HDA_CMD_VERB_SET_PIN_WIDGET_CTRL 0x707 - -#define HDA_CMD_GET_PIN_WIDGET_CTRL(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PIN_WIDGET_CTRL, 0x0)) -#define HDA_CMD_SET_PIN_WIDGET_CTRL(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PIN_WIDGET_CTRL, (payload))) - -#define HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_MASK 0x00000080 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_SHIFT 7 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_MASK 0x00000040 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT 6 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_MASK 0x00000020 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT 5 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK 0x00000007 -#define HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT 0 - -#define HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_MASK) >> \ - HDA_CMD_GET_PIN_WIDGET_CTRL_HPHN_ENABLE_SHIFT) -#define HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_OUT_ENABLE_MASK) >> \ - HDA_GET_CMD_PIN_WIDGET_CTRL_OUT_ENABLE_SHIFT) -#define HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_MASK) >> \ - HDA_CMD_GET_PIN_WIDGET_CTRL_IN_ENABLE_SHIFT) -#define HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK) >> \ - HDA_CMD_GET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT) - -#define HDA_CMD_SET_PIN_WIDGET_CTRL_HPHN_ENABLE 0x80 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_OUT_ENABLE 0x40 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_IN_ENABLE 0x20 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK 0x07 -#define HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT 0 - -#define HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE(param) \ - (((param) << HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_SHIFT) & \ - HDA_CMD_SET_PIN_WIDGET_CTRL_VREF_ENABLE_MASK) - -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_HIZ 0 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_50 1 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_GROUND 2 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_80 4 -#define HDA_CMD_PIN_WIDGET_CTRL_VREF_ENABLE_100 5 - -/* Unsolicited Response */ -#define HDA_CMD_VERB_GET_UNSOLICITED_RESPONSE 0xf08 -#define HDA_CMD_VERB_SET_UNSOLICITED_RESPONSE 0x708 - -#define HDA_CMD_GET_UNSOLICITED_RESPONSE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_UNSOLICITED_RESPONSE, 0x0)) -#define HDA_CMD_SET_UNSOLICITED_RESPONSE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_UNSOLICITED_RESPONSE, (payload))) - -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_MASK 0x00000080 -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_SHIFT 7 -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_MASK 0x0000001f -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_SHIFT 0 - -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE(rsp) \ - (((rsp) & HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_MASK) >> \ - HDA_CMD_GET_UNSOLICITED_RESPONSE_ENABLE_SHIFT) -#define HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG(rsp) \ - (((rsp) & HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_MASK) >> \ - HDA_CMD_GET_UNSOLICITED_RESPONSE_TAG_SHIFT) - -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_ENABLE 0x80 -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK 0x3f -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_SHIFT 0 - -#define HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG(param) \ - (((param) << HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_SHIFT) & \ - HDA_CMD_SET_UNSOLICITED_RESPONSE_TAG_MASK) - -/* Pin Sense */ -#define HDA_CMD_VERB_GET_PIN_SENSE 0xf09 -#define HDA_CMD_VERB_SET_PIN_SENSE 0x709 - -#define HDA_CMD_GET_PIN_SENSE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_PIN_SENSE, 0x0)) -#define HDA_CMD_SET_PIN_SENSE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_PIN_SENSE, (payload))) - -#define HDA_CMD_GET_PIN_SENSE_PRESENCE_DETECT 0x80000000 -#define HDA_CMD_GET_PIN_SENSE_ELD_VALID 0x40000000 -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK 0x7fffffff -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT 0 - -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE(rsp) \ - (((rsp) & HDA_CMD_GET_PIN_SENSE_IMP_SENSE_MASK) >> \ - HDA_CMD_GET_PIN_SENSE_IMP_SENSE_SHIFT) - -#define HDA_CMD_GET_PIN_SENSE_IMP_SENSE_INVALID 0x7fffffff - -#define HDA_CMD_SET_PIN_SENSE_LEFT_CHANNEL 0x00 -#define HDA_CMD_SET_PIN_SENSE_RIGHT_CHANNEL 0x01 - -/* EAPD/BTL Enable */ -#define HDA_CMD_VERB_GET_EAPD_BTL_ENABLE 0xf0c -#define HDA_CMD_VERB_SET_EAPD_BTL_ENABLE 0x70c - -#define HDA_CMD_GET_EAPD_BTL_ENABLE(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_EAPD_BTL_ENABLE, 0x0)) -#define HDA_CMD_SET_EAPD_BTL_ENABLE(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_EAPD_BTL_ENABLE, (payload))) - -#define HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_MASK 0x00000004 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_SHIFT 2 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_MASK 0x00000002 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_SHIFT 1 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_MASK 0x00000001 -#define HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_SHIFT 0 - -#define HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP(rsp) \ - (((rsp) & HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_MASK) >> \ - HDA_CMD_GET_EAPD_BTL_ENABLE_LR_SWAP_SHIFT) -#define HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD(rsp) \ - (((rsp) & HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_MASK) >> \ - HDA_CMD_GET_EAPD_BTL_ENABLE_EAPD_SHIFT) -#define HDA_CMD_GET_EAPD_BTL_ENABLE_BTL(rsp) \ - (((rsp) & HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_MASK) >> \ - HDA_CMD_GET_EAPD_BTL_ENABLE_BTL_SHIFT) - -#define HDA_CMD_SET_EAPD_BTL_ENABLE_LR_SWAP 0x04 -#define HDA_CMD_SET_EAPD_BTL_ENABLE_EAPD 0x02 -#define HDA_CMD_SET_EAPD_BTL_ENABLE_BTL 0x01 - -/* GPI Data */ -#define HDA_CMD_VERB_GET_GPI_DATA 0xf10 -#define HDA_CMD_VERB_SET_GPI_DATA 0x710 - -#define HDA_CMD_GET_GPI_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_DATA, 0x0)) -#define HDA_CMD_SET_GPI_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_DATA, (payload))) - -/* GPI Wake Enable Mask */ -#define HDA_CMD_VERB_GET_GPI_WAKE_ENABLE_MASK 0xf11 -#define HDA_CMD_VERB_SET_GPI_WAKE_ENABLE_MASK 0x711 - -#define HDA_CMD_GET_GPI_WAKE_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_WAKE_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPI_WAKE_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_WAKE_ENABLE_MASK, (payload))) - -/* GPI Unsolicited Enable Mask */ -#define HDA_CMD_VERB_GET_GPI_UNSOLICITED_ENABLE_MASK 0xf12 -#define HDA_CMD_VERB_SET_GPI_UNSOLICITED_ENABLE_MASK 0x712 - -#define HDA_CMD_GET_GPI_UNSOLICITED_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_UNSOLICITED_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPI_UNSOLICITED_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_UNSOLICITED_ENABLE_MASK, (payload))) - -/* GPI Sticky Mask */ -#define HDA_CMD_VERB_GET_GPI_STICKY_MASK 0xf13 -#define HDA_CMD_VERB_SET_GPI_STICKY_MASK 0x713 - -#define HDA_CMD_GET_GPI_STICKY_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPI_STICKY_MASK, 0x0)) -#define HDA_CMD_SET_GPI_STICKY_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPI_STICKY_MASK, (payload))) - -/* GPO Data */ -#define HDA_CMD_VERB_GET_GPO_DATA 0xf14 -#define HDA_CMD_VERB_SET_GPO_DATA 0x714 - -#define HDA_CMD_GET_GPO_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPO_DATA, 0x0)) -#define HDA_CMD_SET_GPO_DATA(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPO_DATA, (payload))) - -/* GPIO Data */ -#define HDA_CMD_VERB_GET_GPIO_DATA 0xf15 -#define HDA_CMD_VERB_SET_GPIO_DATA 0x715 - -#define HDA_CMD_GET_GPIO_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_DATA, 0x0)) -#define HDA_CMD_SET_GPIO_DATA(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_DATA, (payload))) - -/* GPIO Enable Mask */ -#define HDA_CMD_VERB_GET_GPIO_ENABLE_MASK 0xf16 -#define HDA_CMD_VERB_SET_GPIO_ENABLE_MASK 0x716 - -#define HDA_CMD_GET_GPIO_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_ENABLE_MASK, (payload))) - -/* GPIO Direction */ -#define HDA_CMD_VERB_GET_GPIO_DIRECTION 0xf17 -#define HDA_CMD_VERB_SET_GPIO_DIRECTION 0x717 - -#define HDA_CMD_GET_GPIO_DIRECTION(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_DIRECTION, 0x0)) -#define HDA_CMD_SET_GPIO_DIRECTION(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_DIRECTION, (payload))) - -/* GPIO Wake Enable Mask */ -#define HDA_CMD_VERB_GET_GPIO_WAKE_ENABLE_MASK 0xf18 -#define HDA_CMD_VERB_SET_GPIO_WAKE_ENABLE_MASK 0x718 - -#define HDA_CMD_GET_GPIO_WAKE_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_WAKE_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_WAKE_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_WAKE_ENABLE_MASK, (payload))) - -/* GPIO Unsolicited Enable Mask */ -#define HDA_CMD_VERB_GET_GPIO_UNSOLICITED_ENABLE_MASK 0xf19 -#define HDA_CMD_VERB_SET_GPIO_UNSOLICITED_ENABLE_MASK 0x719 - -#define HDA_CMD_GET_GPIO_UNSOLICITED_ENABLE_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_UNSOLICITED_ENABLE_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_UNSOLICITED_ENABLE_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_UNSOLICITED_ENABLE_MASK, (payload))) - -/* GPIO_STICKY_MASK */ -#define HDA_CMD_VERB_GET_GPIO_STICKY_MASK 0xf1a -#define HDA_CMD_VERB_SET_GPIO_STICKY_MASK 0x71a - -#define HDA_CMD_GET_GPIO_STICKY_MASK(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_GPIO_STICKY_MASK, 0x0)) -#define HDA_CMD_SET_GPIO_STICKY_MASK(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_GPIO_STICKY_MASK, (payload))) - -/* Beep Generation */ -#define HDA_CMD_VERB_GET_BEEP_GENERATION 0xf0a -#define HDA_CMD_VERB_SET_BEEP_GENERATION 0x70a - -#define HDA_CMD_GET_BEEP_GENERATION(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_BEEP_GENERATION, 0x0)) -#define HDA_CMD_SET_BEEP_GENERATION(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_BEEP_GENERATION, (payload))) - -/* Volume Knob */ -#define HDA_CMD_VERB_GET_VOLUME_KNOB 0xf0f -#define HDA_CMD_VERB_SET_VOLUME_KNOB 0x70f - -#define HDA_CMD_GET_VOLUME_KNOB(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_VOLUME_KNOB, 0x0)) -#define HDA_CMD_SET_VOLUME_KNOB(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_VOLUME_KNOB, (payload))) - -/* Subsystem ID */ -#define HDA_CMD_VERB_GET_SUBSYSTEM_ID 0xf20 -#define HDA_CMD_VERB_SET_SUSBYSTEM_ID1 0x720 -#define HDA_CMD_VERB_SET_SUBSYSTEM_ID2 0x721 -#define HDA_CMD_VERB_SET_SUBSYSTEM_ID3 0x722 -#define HDA_CMD_VERB_SET_SUBSYSTEM_ID4 0x723 - -#define HDA_CMD_GET_SUBSYSTEM_ID(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_SUBSYSTEM_ID, 0x0)) -#define HDA_CMD_SET_SUBSYSTEM_ID1(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID1, (payload))) -#define HDA_CMD_SET_SUBSYSTEM_ID2(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID2, (payload))) -#define HDA_CMD_SET_SUBSYSTEM_ID3(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID3, (payload))) -#define HDA_CMD_SET_SUBSYSTEM_ID4(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_SUSBYSTEM_ID4, (payload))) - -/* Configuration Default */ -#define HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT 0xf1c -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT1 0x71c -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT2 0x71d -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT3 0x71e -#define HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT4 0x71f - -#define HDA_CMD_GET_CONFIGURATION_DEFAULT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONFIGURATION_DEFAULT, 0x0)) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT1(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT1, (payload))) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT2(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT2, (payload))) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT3(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT3, (payload))) -#define HDA_CMD_SET_CONFIGURATION_DEFAULT4(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONFIGURATION_DEFAULT4, (payload))) - -/* Stripe Control */ -#define HDA_CMD_VERB_GET_STRIPE_CONTROL 0xf24 -#define HDA_CMD_VERB_SET_STRIPE_CONTROL 0x724 - -#define HDA_CMD_GET_STRIPE_CONTROL(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_STRIPE_CONTROL, 0x0)) -#define HDA_CMD_SET_STRIPE_CONTROL(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_STRIPE_CONTROL, (payload))) - -/* Channel Count Control */ -#define HDA_CMD_VERB_GET_CONV_CHAN_COUNT 0xf2d -#define HDA_CMD_VERB_SET_CONV_CHAN_COUNT 0x72d - -#define HDA_CMD_GET_CONV_CHAN_COUNT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_CONV_CHAN_COUNT, 0x0)) -#define HDA_CMD_SET_CONV_CHAN_COUNT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_CONV_CHAN_COUNT, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_SIZE 0xf2e - -#define HDA_CMD_GET_HDMI_DIP_SIZE(cad, nid, arg) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_SIZE, (arg))) - -#define HDA_CMD_VERB_GET_HDMI_ELDD 0xf2f - -#define HDA_CMD_GET_HDMI_ELDD(cad, nid, off) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_ELDD, (off))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_INDEX 0xf30 -#define HDA_CMD_VERB_SET_HDMI_DIP_INDEX 0x730 - -#define HDA_CMD_GET_HDMI_DIP_INDEX(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_INDEX, 0x0)) -#define HDA_CMD_SET_HDMI_DIP_INDEX(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_DIP_INDEX, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_DATA 0xf31 -#define HDA_CMD_VERB_SET_HDMI_DIP_DATA 0x731 - -#define HDA_CMD_GET_HDMI_DIP_DATA(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_DATA, 0x0)) -#define HDA_CMD_SET_HDMI_DIP_DATA(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_DIP_DATA, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_DIP_XMIT 0xf32 -#define HDA_CMD_VERB_SET_HDMI_DIP_XMIT 0x732 - -#define HDA_CMD_GET_HDMI_DIP_XMIT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_DIP_XMIT, 0x0)) -#define HDA_CMD_SET_HDMI_DIP_XMIT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_DIP_XMIT, (payload))) - -#define HDA_CMD_VERB_GET_HDMI_CP_CTRL 0xf33 -#define HDA_CMD_VERB_SET_HDMI_CP_CTRL 0x733 - -#define HDA_CMD_VERB_GET_HDMI_CHAN_SLOT 0xf34 -#define HDA_CMD_VERB_SET_HDMI_CHAN_SLOT 0x734 - -#define HDA_CMD_GET_HDMI_CHAN_SLOT(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_GET_HDMI_CHAN_SLOT, 0x0)) -#define HDA_CMD_SET_HDMI_CHAN_SLOT(cad, nid, payload) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_SET_HDMI_CHAN_SLOT, (payload))) - -#define HDA_HDMI_CODING_TYPE_REF_STREAM_HEADER 0 -#define HDA_HDMI_CODING_TYPE_LPCM 1 -#define HDA_HDMI_CODING_TYPE_AC3 2 -#define HDA_HDMI_CODING_TYPE_MPEG1 3 -#define HDA_HDMI_CODING_TYPE_MP3 4 -#define HDA_HDMI_CODING_TYPE_MPEG2 5 -#define HDA_HDMI_CODING_TYPE_AACLC 6 -#define HDA_HDMI_CODING_TYPE_DTS 7 -#define HDA_HDMI_CODING_TYPE_ATRAC 8 -#define HDA_HDMI_CODING_TYPE_SACD 9 -#define HDA_HDMI_CODING_TYPE_EAC3 10 -#define HDA_HDMI_CODING_TYPE_DTS_HD 11 -#define HDA_HDMI_CODING_TYPE_MLP 12 -#define HDA_HDMI_CODING_TYPE_DST 13 -#define HDA_HDMI_CODING_TYPE_WMAPRO 14 -#define HDA_HDMI_CODING_TYPE_REF_CTX 15 - -/* Function Reset */ -#define HDA_CMD_VERB_FUNCTION_RESET 0x7ff - -#define HDA_CMD_FUNCTION_RESET(cad, nid) \ - (HDA_CMD_12BIT((cad), (nid), \ - HDA_CMD_VERB_FUNCTION_RESET, 0x0)) - - -/**************************************************************************** - * HDA Device Parameters - ****************************************************************************/ - -/* Vendor ID */ -#define HDA_PARAM_VENDOR_ID 0x00 - -#define HDA_PARAM_VENDOR_ID_VENDOR_ID_MASK 0xffff0000 -#define HDA_PARAM_VENDOR_ID_VENDOR_ID_SHIFT 16 -#define HDA_PARAM_VENDOR_ID_DEVICE_ID_MASK 0x0000ffff -#define HDA_PARAM_VENDOR_ID_DEVICE_ID_SHIFT 0 - -#define HDA_PARAM_VENDOR_ID_VENDOR_ID(param) \ - (((param) & HDA_PARAM_VENDOR_ID_VENDOR_ID_MASK) >> \ - HDA_PARAM_VENDOR_ID_VENDOR_ID_SHIFT) -#define HDA_PARAM_VENDOR_ID_DEVICE_ID(param) \ - (((param) & HDA_PARAM_VENDOR_ID_DEVICE_ID_MASK) >> \ - HDA_PARAM_VENDOR_ID_DEVICE_ID_SHIFT) - -/* Revision ID */ -#define HDA_PARAM_REVISION_ID 0x02 - -#define HDA_PARAM_REVISION_ID_MAJREV_MASK 0x00f00000 -#define HDA_PARAM_REVISION_ID_MAJREV_SHIFT 20 -#define HDA_PARAM_REVISION_ID_MINREV_MASK 0x000f0000 -#define HDA_PARAM_REVISION_ID_MINREV_SHIFT 16 -#define HDA_PARAM_REVISION_ID_REVISION_ID_MASK 0x0000ff00 -#define HDA_PARAM_REVISION_ID_REVISION_ID_SHIFT 8 -#define HDA_PARAM_REVISION_ID_STEPPING_ID_MASK 0x000000ff -#define HDA_PARAM_REVISION_ID_STEPPING_ID_SHIFT 0 - -#define HDA_PARAM_REVISION_ID_MAJREV(param) \ - (((param) & HDA_PARAM_REVISION_ID_MAJREV_MASK) >> \ - HDA_PARAM_REVISION_ID_MAJREV_SHIFT) -#define HDA_PARAM_REVISION_ID_MINREV(param) \ - (((param) & HDA_PARAM_REVISION_ID_MINREV_MASK) >> \ - HDA_PARAM_REVISION_ID_MINREV_SHIFT) -#define HDA_PARAM_REVISION_ID_REVISION_ID(param) \ - (((param) & HDA_PARAM_REVISION_ID_REVISION_ID_MASK) >> \ - HDA_PARAM_REVISION_ID_REVISION_ID_SHIFT) -#define HDA_PARAM_REVISION_ID_STEPPING_ID(param) \ - (((param) & HDA_PARAM_REVISION_ID_STEPPING_ID_MASK) >> \ - HDA_PARAM_REVISION_ID_STEPPING_ID_SHIFT) - -/* Subordinate Node Cound */ -#define HDA_PARAM_SUB_NODE_COUNT 0x04 - -#define HDA_PARAM_SUB_NODE_COUNT_START_MASK 0x00ff0000 -#define HDA_PARAM_SUB_NODE_COUNT_START_SHIFT 16 -#define HDA_PARAM_SUB_NODE_COUNT_TOTAL_MASK 0x000000ff -#define HDA_PARAM_SUB_NODE_COUNT_TOTAL_SHIFT 0 - -#define HDA_PARAM_SUB_NODE_COUNT_START(param) \ - (((param) & HDA_PARAM_SUB_NODE_COUNT_START_MASK) >> \ - HDA_PARAM_SUB_NODE_COUNT_START_SHIFT) -#define HDA_PARAM_SUB_NODE_COUNT_TOTAL(param) \ - (((param) & HDA_PARAM_SUB_NODE_COUNT_TOTAL_MASK) >> \ - HDA_PARAM_SUB_NODE_COUNT_TOTAL_SHIFT) - -/* Function Group Type */ -#define HDA_PARAM_FCT_GRP_TYPE 0x05 - -#define HDA_PARAM_FCT_GRP_TYPE_UNSOL_MASK 0x00000100 -#define HDA_PARAM_FCT_GRP_TYPE_UNSOL_SHIFT 8 -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MASK 0x000000ff -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_SHIFT 0 - -#define HDA_PARAM_FCT_GRP_TYPE_UNSOL(param) \ - (((param) & HDA_PARAM_FCT_GRP_TYPE_UNSOL_MASK) >> \ - HDA_PARAM_FCT_GROUP_TYPE_UNSOL_SHIFT) -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE(param) \ - (((param) & HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MASK) >> \ - HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_SHIFT) - -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_AUDIO 0x01 -#define HDA_PARAM_FCT_GRP_TYPE_NODE_TYPE_MODEM 0x02 - -/* Audio Function Group Capabilities */ -#define HDA_PARAM_AUDIO_FCT_GRP_CAP 0x08 - -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_MASK 0x00010000 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_SHIFT 16 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_MASK 0x00000f00 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_SHIFT 8 -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_MASK 0x0000000f -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_SHIFT 0 - -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN(param) \ - (((param) & HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_MASK) >> \ - HDA_PARAM_AUDIO_FCT_GRP_CAP_BEEP_GEN_SHIFT) -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY(param) \ - (((param) & HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_MASK) >> \ - HDA_PARAM_AUDIO_FCT_GRP_CAP_INPUT_DELAY_SHIFT) -#define HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY(param) \ - (((param) & HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_MASK) >> \ - HDA_PARAM_AUDIO_FCT_GRP_CAP_OUTPUT_DELAY_SHIFT) - -/* Audio Widget Capabilities */ -#define HDA_PARAM_AUDIO_WIDGET_CAP 0x09 - -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK 0x00f00000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT 20 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK 0x000f0000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT 16 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK 0x0000e000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT 13 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK 0x00001000 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT 12 -#define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK 0x00000800 -#define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT 11 -#define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_MASK 0x00000400 -#define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_SHIFT 10 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK 0x00000200 -#define HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_SHIFT 9 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_MASK 0x00000100 -#define HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT 8 -#define HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_MASK 0x00000080 -#define HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_SHIFT 7 -#define HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_MASK 0x00000040 -#define HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_SHIFT 6 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_MASK 0x00000020 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_SHIFT 5 -#define HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_MASK 0x00000010 -#define HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT 4 -#define HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_MASK 0x00000008 -#define HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT 3 -#define HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_MASK 0x00000004 -#define HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT 2 -#define HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_MASK 0x00000002 -#define HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT 1 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK 0x00000001 -#define HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT 0 - -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_DELAY(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_DELAY_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_CC(param) \ - ((((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_MASK) >> \ - (HDA_PARAM_AUDIO_WIDGET_CAP_CC_EXT_SHIFT - 1)) | \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT)) -#define HDA_PARAM_AUDIO_WIDGET_CAP_CP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_CP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_LR_SWAP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_POWER_CTRL_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_DIGITAL_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_CONN_LIST_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_UNSOL_CAP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_PROC_WIDGET_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_STRIPE_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_FORMAT_OVR_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_AMP_OVR_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_OUT_AMP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_IN_AMP_SHIFT) -#define HDA_PARAM_AUDIO_WIDGET_CAP_STEREO(param) \ - (((param) & HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_MASK) >> \ - HDA_PARAM_AUDIO_WIDGET_CAP_STEREO_SHIFT) - -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_OUTPUT 0x0 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_INPUT 0x1 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_MIXER 0x2 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_AUDIO_SELECTOR 0x3 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_PIN_COMPLEX 0x4 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_POWER_WIDGET 0x5 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VOLUME_WIDGET 0x6 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_BEEP_WIDGET 0x7 -#define HDA_PARAM_AUDIO_WIDGET_CAP_TYPE_VENDOR_WIDGET 0xf - -/* Supported PCM Size, Rates */ - -#define HDA_PARAM_SUPP_PCM_SIZE_RATE 0x0a - -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_MASK 0x00100000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_SHIFT 20 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_MASK 0x00080000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_SHIFT 19 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_MASK 0x00040000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_SHIFT 18 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_MASK 0x00020000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_SHIFT 17 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_MASK 0x00010000 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_SHIFT 16 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_MASK 0x00000001 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_SHIFT 0 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_MASK 0x00000002 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_SHIFT 1 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_MASK 0x00000004 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_SHIFT 2 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_MASK 0x00000008 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_SHIFT 3 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_MASK 0x00000010 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_SHIFT 4 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_MASK 0x00000020 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_SHIFT 5 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_MASK 0x00000040 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_SHIFT 6 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_MASK 0x00000080 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_SHIFT 7 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_MASK 0x00000100 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_SHIFT 8 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_MASK 0x00000200 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_SHIFT 9 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_MASK 0x00000400 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_SHIFT 10 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_MASK 0x00000800 -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_SHIFT 11 - -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_32BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_24BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_20BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_16BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_8BIT_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_8KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_11KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_16KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_22KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_32KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_44KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_48KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_88KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_96KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_176KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_192KHZ_SHIFT) -#define HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ(param) \ - (((param) & HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_MASK) >> \ - HDA_PARAM_SUPP_PCM_SIZE_RATE_384KHZ_SHIFT) - -/* Supported Stream Formats */ -#define HDA_PARAM_SUPP_STREAM_FORMATS 0x0b - -#define HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK 0x00000004 -#define HDA_PARAM_SUPP_STREAM_FORMATS_AC3_SHIFT 2 -#define HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_MASK 0x00000002 -#define HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_SHIFT 1 -#define HDA_PARAM_SUPP_STREAM_FORMATS_PCM_MASK 0x00000001 -#define HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT 0 - -#define HDA_PARAM_SUPP_STREAM_FORMATS_AC3(param) \ - (((param) & HDA_PARAM_SUPP_STREAM_FORMATS_AC3_MASK) >> \ - HDA_PARAM_SUPP_STREAM_FORMATS_AC3_SHIFT) -#define HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32(param) \ - (((param) & HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_MASK) >> \ - HDA_PARAM_SUPP_STREAM_FORMATS_FLOAT32_SHIFT) -#define HDA_PARAM_SUPP_STREAM_FORMATS_PCM(param) \ - (((param) & HDA_PARAM_SUPP_STREAM_FORMATS_PCM_MASK) >> \ - HDA_PARAM_SUPP_STREAM_FORMATS_PCM_SHIFT) - -/* Pin Capabilities */ -#define HDA_PARAM_PIN_CAP 0x0c - -#define HDA_PARAM_PIN_CAP_HBR_MASK 0x08000000 -#define HDA_PARAM_PIN_CAP_HBR_SHIFT 27 -#define HDA_PARAM_PIN_CAP_DP_MASK 0x01000000 -#define HDA_PARAM_PIN_CAP_DP_SHIFT 24 -#define HDA_PARAM_PIN_CAP_EAPD_CAP_MASK 0x00010000 -#define HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT 16 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_MASK 0x0000ff00 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_SHIFT 8 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK 0x00002000 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_100_SHIFT 13 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK 0x00001000 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_80_SHIFT 12 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_MASK 0x00000400 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_SHIFT 10 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK 0x00000200 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_50_SHIFT 9 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK 0x00000100 -#define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT 8 -#define HDA_PARAM_PIN_CAP_HDMI_MASK 0x00000080 -#define HDA_PARAM_PIN_CAP_HDMI_SHIFT 7 -#define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK 0x00000040 -#define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT 6 -#define HDA_PARAM_PIN_CAP_INPUT_CAP_MASK 0x00000020 -#define HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT 5 -#define HDA_PARAM_PIN_CAP_OUTPUT_CAP_MASK 0x00000010 -#define HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT 4 -#define HDA_PARAM_PIN_CAP_HEADPHONE_CAP_MASK 0x00000008 -#define HDA_PARAM_PIN_CAP_HEADPHONE_CAP_SHIFT 3 -#define HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_MASK 0x00000004 -#define HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT 2 -#define HDA_PARAM_PIN_CAP_TRIGGER_REQD_MASK 0x00000002 -#define HDA_PARAM_PIN_CAP_TRIGGER_REQD_SHIFT 1 -#define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_MASK 0x00000001 -#define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_SHIFT 0 - -#define HDA_PARAM_PIN_CAP_HBR(param) \ - (((param) & HDA_PARAM_PIN_CAP_HBR_MASK) >> \ - HDA_PARAM_PIN_CAP_HBR_SHIFT) -#define HDA_PARAM_PIN_CAP_DP(param) \ - (((param) & HDA_PARAM_PIN_CAP_DP_MASK) >> \ - HDA_PARAM_PIN_CAP_DP_SHIFT) -#define HDA_PARAM_PIN_CAP_EAPD_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_EAPD_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_EAPD_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_100(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_100_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_100_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_80(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_80_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_80_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_GROUND_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_50(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_50_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_50_SHIFT) -#define HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ(param) \ - (((param) & HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_MASK) >> \ - HDA_PARAM_PIN_CAP_VREF_CTRL_HIZ_SHIFT) -#define HDA_PARAM_PIN_CAP_HDMI(param) \ - (((param) & HDA_PARAM_PIN_CAP_HDMI_MASK) >> \ - HDA_PARAM_PIN_CAP_HDMI_SHIFT) -#define HDA_PARAM_PIN_CAP_BALANCED_IO_PINS(param) \ - (((param) & HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_MASK) >> \ - HDA_PARAM_PIN_CAP_BALANCED_IO_PINS_SHIFT) -#define HDA_PARAM_PIN_CAP_INPUT_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_INPUT_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_INPUT_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_OUTPUT_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_OUTPUT_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_OUTPUT_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_HEADPHONE_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_HEADPHONE_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_HEADPHONE_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_PRESENCE_DETECT_CAP_SHIFT) -#define HDA_PARAM_PIN_CAP_TRIGGER_REQD(param) \ - (((param) & HDA_PARAM_PIN_CAP_TRIGGER_REQD_MASK) >> \ - HDA_PARAM_PIN_CAP_TRIGGER_REQD_SHIFT) -#define HDA_PARAM_PIN_CAP_IMP_SENSE_CAP(param) \ - (((param) & HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_MASK) >> \ - HDA_PARAM_PIN_CAP_IMP_SENSE_CAP_SHIFT) - -/* Input Amplifier Capabilities */ -#define HDA_PARAM_INPUT_AMP_CAP 0x0d - -#define HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_MASK 0x80000000 -#define HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_SHIFT 31 -#define HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_MASK 0x007f0000 -#define HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_SHIFT 16 -#define HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_MASK 0x00007f00 -#define HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_SHIFT 8 -#define HDA_PARAM_INPUT_AMP_CAP_OFFSET_MASK 0x0000007f -#define HDA_PARAM_INPUT_AMP_CAP_OFFSET_SHIFT 0 - -#define HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_MUTE_CAP_SHIFT) -#define HDA_PARAM_INPUT_AMP_CAP_STEPSIZE(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_STEPSIZE_SHIFT) -#define HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_NUMSTEPS_SHIFT) -#define HDA_PARAM_INPUT_AMP_CAP_OFFSET(param) \ - (((param) & HDA_PARAM_INPUT_AMP_CAP_OFFSET_MASK) >> \ - HDA_PARAM_INPUT_AMP_CAP_OFFSET_SHIFT) - -/* Output Amplifier Capabilities */ -#define HDA_PARAM_OUTPUT_AMP_CAP 0x12 - -#define HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_MASK 0x80000000 -#define HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT 31 -#define HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_MASK 0x007f0000 -#define HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT 16 -#define HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_MASK 0x00007f00 -#define HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT 8 -#define HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_MASK 0x0000007f -#define HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT 0 - -#define HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_MUTE_CAP_SHIFT) -#define HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_STEPSIZE_SHIFT) -#define HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_NUMSTEPS_SHIFT) -#define HDA_PARAM_OUTPUT_AMP_CAP_OFFSET(param) \ - (((param) & HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_MASK) >> \ - HDA_PARAM_OUTPUT_AMP_CAP_OFFSET_SHIFT) - -/* Connection List Length */ -#define HDA_PARAM_CONN_LIST_LENGTH 0x0e - -#define HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_MASK 0x00000080 -#define HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_SHIFT 7 -#define HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_MASK 0x0000007f -#define HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_SHIFT 0 - -#define HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM(param) \ - (((param) & HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_MASK) >> \ - HDA_PARAM_CONN_LIST_LENGTH_LONG_FORM_SHIFT) -#define HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH(param) \ - (((param) & HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_MASK) >> \ - HDA_PARAM_CONN_LIST_LENGTH_LIST_LENGTH_SHIFT) - -/* Supported Power States */ -#define HDA_PARAM_SUPP_POWER_STATES 0x0f - -#define HDA_PARAM_SUPP_POWER_STATES_D3_MASK 0x00000008 -#define HDA_PARAM_SUPP_POWER_STATES_D3_SHIFT 3 -#define HDA_PARAM_SUPP_POWER_STATES_D2_MASK 0x00000004 -#define HDA_PARAM_SUPP_POWER_STATES_D2_SHIFT 2 -#define HDA_PARAM_SUPP_POWER_STATES_D1_MASK 0x00000002 -#define HDA_PARAM_SUPP_POWER_STATES_D1_SHIFT 1 -#define HDA_PARAM_SUPP_POWER_STATES_D0_MASK 0x00000001 -#define HDA_PARAM_SUPP_POWER_STATES_D0_SHIFT 0 - -#define HDA_PARAM_SUPP_POWER_STATES_D3(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D3_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D3_SHIFT) -#define HDA_PARAM_SUPP_POWER_STATES_D2(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D2_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D2_SHIFT) -#define HDA_PARAM_SUPP_POWER_STATES_D1(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D1_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D1_SHIFT) -#define HDA_PARAM_SUPP_POWER_STATES_D0(param) \ - (((param) & HDA_PARAM_SUPP_POWER_STATES_D0_MASK) >> \ - HDA_PARAM_SUPP_POWER_STATES_D0_SHIFT) - -/* Processing Capabilities */ -#define HDA_PARAM_PROCESSING_CAP 0x10 - -#define HDA_PARAM_PROCESSING_CAP_NUMCOEFF_MASK 0x0000ff00 -#define HDA_PARAM_PROCESSING_CAP_NUMCOEFF_SHIFT 8 -#define HDA_PARAM_PROCESSING_CAP_BENIGN_MASK 0x00000001 -#define HDA_PARAM_PROCESSING_CAP_BENIGN_SHIFT 0 - -#define HDA_PARAM_PROCESSING_CAP_NUMCOEFF(param) \ - (((param) & HDA_PARAM_PROCESSING_CAP_NUMCOEFF_MASK) >> \ - HDA_PARAM_PROCESSING_CAP_NUMCOEFF_SHIFT) -#define HDA_PARAM_PROCESSING_CAP_BENIGN(param) \ - (((param) & HDA_PARAM_PROCESSING_CAP_BENIGN_MASK) >> \ - HDA_PARAM_PROCESSING_CAP_BENIGN_SHIFT) - -/* GPIO Count */ -#define HDA_PARAM_GPIO_COUNT 0x11 - -#define HDA_PARAM_GPIO_COUNT_GPI_WAKE_MASK 0x80000000 -#define HDA_PARAM_GPIO_COUNT_GPI_WAKE_SHIFT 31 -#define HDA_PARAM_GPIO_COUNT_GPI_UNSOL_MASK 0x40000000 -#define HDA_PARAM_GPIO_COUNT_GPI_UNSOL_SHIFT 30 -#define HDA_PARAM_GPIO_COUNT_NUM_GPI_MASK 0x00ff0000 -#define HDA_PARAM_GPIO_COUNT_NUM_GPI_SHIFT 16 -#define HDA_PARAM_GPIO_COUNT_NUM_GPO_MASK 0x0000ff00 -#define HDA_PARAM_GPIO_COUNT_NUM_GPO_SHIFT 8 -#define HDA_PARAM_GPIO_COUNT_NUM_GPIO_MASK 0x000000ff -#define HDA_PARAM_GPIO_COUNT_NUM_GPIO_SHIFT 0 - -#define HDA_PARAM_GPIO_COUNT_GPI_WAKE(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_GPI_WAKE_MASK) >> \ - HDA_PARAM_GPIO_COUNT_GPI_WAKE_SHIFT) -#define HDA_PARAM_GPIO_COUNT_GPI_UNSOL(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_GPI_UNSOL_MASK) >> \ - HDA_PARAM_GPIO_COUNT_GPI_UNSOL_SHIFT) -#define HDA_PARAM_GPIO_COUNT_NUM_GPI(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_NUM_GPI_MASK) >> \ - HDA_PARAM_GPIO_COUNT_NUM_GPI_SHIFT) -#define HDA_PARAM_GPIO_COUNT_NUM_GPO(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_NUM_GPO_MASK) >> \ - HDA_PARAM_GPIO_COUNT_NUM_GPO_SHIFT) -#define HDA_PARAM_GPIO_COUNT_NUM_GPIO(param) \ - (((param) & HDA_PARAM_GPIO_COUNT_NUM_GPIO_MASK) >> \ - HDA_PARAM_GPIO_COUNT_NUM_GPIO_SHIFT) - -/* Volume Knob Capabilities */ -#define HDA_PARAM_VOLUME_KNOB_CAP 0x13 - -#define HDA_PARAM_VOLUME_KNOB_CAP_DELTA_MASK 0x00000080 -#define HDA_PARAM_VOLUME_KNOB_CAP_DELTA_SHIFT 7 -#define HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_MASK 0x0000007f -#define HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_SHIFT 0 - -#define HDA_PARAM_VOLUME_KNOB_CAP_DELTA(param) \ - (((param) & HDA_PARAM_VOLUME_KNOB_CAP_DELTA_MASK) >> \ - HDA_PARAM_VOLUME_KNOB_CAP_DELTA_SHIFT) -#define HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS(param) \ - (((param) & HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_MASK) >> \ - HDA_PARAM_VOLUME_KNOB_CAP_NUM_STEPS_SHIFT) - - -#define HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK 0x0000000f -#define HDA_CONFIG_DEFAULTCONF_SEQUENCE_SHIFT 0 -#define HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK 0x000000f0 -#define HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT 4 -#define HDA_CONFIG_DEFAULTCONF_MISC_MASK 0x00000f00 -#define HDA_CONFIG_DEFAULTCONF_MISC_SHIFT 8 -#define HDA_CONFIG_DEFAULTCONF_COLOR_MASK 0x0000f000 -#define HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT 12 -#define HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK 0x000f0000 -#define HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT 16 -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MASK 0x00f00000 -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT 20 -#define HDA_CONFIG_DEFAULTCONF_LOCATION_MASK 0x3f000000 -#define HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT 24 -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK 0xc0000000 -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT 30 - -#define HDA_CONFIG_DEFAULTCONF_SEQUENCE(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_SEQUENCE_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_SEQUENCE_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_ASSOCIATION(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_ASSOCIATION_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_ASSOCIATION_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_MISC(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_MISC_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_MISC_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_COLOR(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_COLOR_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_COLOR_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_CONNECTION_TYPE_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_DEVICE(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_DEVICE_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_DEVICE_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_LOCATION(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_LOCATION_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_LOCATION_SHIFT) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY(conf) \ - (((conf) & HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_MASK) >> \ - HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_SHIFT) - -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_JACK (0<<30) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_NONE (1<<30) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_FIXED (2<<30) -#define HDA_CONFIG_DEFAULTCONF_CONNECTIVITY_BOTH (3<<30) - -#define HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_OUT (0<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPEAKER (1<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_HP_OUT (2<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_CD (3<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_OUT (4<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_OUT (5<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_LINE (6<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MODEM_HANDSET (7<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_LINE_IN (8<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_AUX (9<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_MIC_IN (10<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_TELEPHONY (11<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_SPDIF_IN (12<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_DIGITAL_OTHER_IN (13<<20) -#define HDA_CONFIG_DEFAULTCONF_DEVICE_OTHER (15<<20) - -#endif /* _HDA_REG_H_ */ diff --git a/usr.sbin/bhyve/hdac_reg.h b/usr.sbin/bhyve/hdac_reg.h deleted file mode 100644 index 2bef0d0edc35..000000000000 --- a/usr.sbin/bhyve/hdac_reg.h +++ /dev/null @@ -1,269 +0,0 @@ -/*- - * Copyright (c) 2006 Stephane E. Potvin <sepotvin@videotron.ca> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _HDAC_REG_H_ -#define _HDAC_REG_H_ - -/**************************************************************************** - * HDA Controller Register Set - ****************************************************************************/ -#define HDAC_GCAP 0x00 /* 2 - Global Capabilities*/ -#define HDAC_VMIN 0x02 /* 1 - Minor Version */ -#define HDAC_VMAJ 0x03 /* 1 - Major Version */ -#define HDAC_OUTPAY 0x04 /* 2 - Output Payload Capability */ -#define HDAC_INPAY 0x06 /* 2 - Input Payload Capability */ -#define HDAC_GCTL 0x08 /* 4 - Global Control */ -#define HDAC_WAKEEN 0x0c /* 2 - Wake Enable */ -#define HDAC_STATESTS 0x0e /* 2 - State Change Status */ -#define HDAC_GSTS 0x10 /* 2 - Global Status */ -#define HDAC_OUTSTRMPAY 0x18 /* 2 - Output Stream Payload Capability */ -#define HDAC_INSTRMPAY 0x1a /* 2 - Input Stream Payload Capability */ -#define HDAC_INTCTL 0x20 /* 4 - Interrupt Control */ -#define HDAC_INTSTS 0x24 /* 4 - Interrupt Status */ -#define HDAC_WALCLK 0x30 /* 4 - Wall Clock Counter */ -#define HDAC_SSYNC 0x38 /* 4 - Stream Synchronization */ -#define HDAC_CORBLBASE 0x40 /* 4 - CORB Lower Base Address */ -#define HDAC_CORBUBASE 0x44 /* 4 - CORB Upper Base Address */ -#define HDAC_CORBWP 0x48 /* 2 - CORB Write Pointer */ -#define HDAC_CORBRP 0x4a /* 2 - CORB Read Pointer */ -#define HDAC_CORBCTL 0x4c /* 1 - CORB Control */ -#define HDAC_CORBSTS 0x4d /* 1 - CORB Status */ -#define HDAC_CORBSIZE 0x4e /* 1 - CORB Size */ -#define HDAC_RIRBLBASE 0x50 /* 4 - RIRB Lower Base Address */ -#define HDAC_RIRBUBASE 0x54 /* 4 - RIRB Upper Base Address */ -#define HDAC_RIRBWP 0x58 /* 2 - RIRB Write Pointer */ -#define HDAC_RINTCNT 0x5a /* 2 - Response Interrupt Count */ -#define HDAC_RIRBCTL 0x5c /* 1 - RIRB Control */ -#define HDAC_RIRBSTS 0x5d /* 1 - RIRB Status */ -#define HDAC_RIRBSIZE 0x5e /* 1 - RIRB Size */ -#define HDAC_ICOI 0x60 /* 4 - Immediate Command Output Interface */ -#define HDAC_ICII 0x64 /* 4 - Immediate Command Input Interface */ -#define HDAC_ICIS 0x68 /* 2 - Immediate Command Status */ -#define HDAC_DPIBLBASE 0x70 /* 4 - DMA Position Buffer Lower Base */ -#define HDAC_DPIBUBASE 0x74 /* 4 - DMA Position Buffer Upper Base */ -#define HDAC_SDCTL0 0x80 /* 3 - Stream Descriptor Control */ -#define HDAC_SDCTL1 0x81 /* 3 - Stream Descriptor Control */ -#define HDAC_SDCTL2 0x82 /* 3 - Stream Descriptor Control */ -#define HDAC_SDSTS 0x83 /* 1 - Stream Descriptor Status */ -#define HDAC_SDLPIB 0x84 /* 4 - Link Position in Buffer */ -#define HDAC_SDCBL 0x88 /* 4 - Cyclic Buffer Length */ -#define HDAC_SDLVI 0x8C /* 2 - Last Valid Index */ -#define HDAC_SDFIFOS 0x90 /* 2 - FIFOS */ -#define HDAC_SDFMT 0x92 /* 2 - fmt */ -#define HDAC_SDBDPL 0x98 /* 4 - Buffer Descriptor Pointer Lower Base */ -#define HDAC_SDBDPU 0x9C /* 4 - Buffer Descriptor Pointer Upper Base */ - -#define _HDAC_ISDOFFSET(n, iss, oss) (0x80 + ((n) * 0x20)) -#define _HDAC_ISDCTL(n, iss, oss) (0x00 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDSTS(n, iss, oss) (0x03 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDPICB(n, iss, oss) (0x04 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDCBL(n, iss, oss) (0x08 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDLVI(n, iss, oss) (0x0c + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDFIFOD(n, iss, oss) (0x10 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDFMT(n, iss, oss) (0x12 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDBDPL(n, iss, oss) (0x18 + _HDAC_ISDOFFSET(n, iss, oss)) -#define _HDAC_ISDBDPU(n, iss, oss) (0x1c + _HDAC_ISDOFFSET(n, iss, oss)) - -#define _HDAC_OSDOFFSET(n, iss, oss) (0x80 + ((iss) * 0x20) + ((n) * 0x20)) -#define _HDAC_OSDCTL(n, iss, oss) (0x00 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDSTS(n, iss, oss) (0x03 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDPICB(n, iss, oss) (0x04 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDCBL(n, iss, oss) (0x08 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDLVI(n, iss, oss) (0x0c + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDFIFOD(n, iss, oss) (0x10 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDFMT(n, iss, oss) (0x12 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDBDPL(n, iss, oss) (0x18 + _HDAC_OSDOFFSET(n, iss, oss)) -#define _HDAC_OSDBDPU(n, iss, oss) (0x1c + _HDAC_OSDOFFSET(n, iss, oss)) - -#define _HDAC_BSDOFFSET(n, iss, oss) \ - (0x80 + ((iss) * 0x20) + ((oss) * 0x20) + ((n) * 0x20)) -#define _HDAC_BSDCTL(n, iss, oss) (0x00 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDSTS(n, iss, oss) (0x03 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDPICB(n, iss, oss) (0x04 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDCBL(n, iss, oss) (0x08 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDLVI(n, iss, oss) (0x0c + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDFIFOD(n, iss, oss) (0x10 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDFMT(n, iss, oss) (0x12 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDBDPL(n, iss, oss) (0x18 + _HDAC_BSDOFFSET(n, iss, oss)) -#define _HDAC_BSDBDBU(n, iss, oss) (0x1c + _HDAC_BSDOFFSET(n, iss, oss)) - -/**************************************************************************** - * HDA Controller Register Fields - ****************************************************************************/ - -/* GCAP - Global Capabilities */ -#define HDAC_GCAP_64OK 0x0001 -#define HDAC_GCAP_NSDO_MASK 0x0006 -#define HDAC_GCAP_NSDO_SHIFT 1 -#define HDAC_GCAP_BSS_MASK 0x00f8 -#define HDAC_GCAP_BSS_SHIFT 3 -#define HDAC_GCAP_ISS_MASK 0x0f00 -#define HDAC_GCAP_ISS_SHIFT 8 -#define HDAC_GCAP_OSS_MASK 0xf000 -#define HDAC_GCAP_OSS_SHIFT 12 - -#define HDAC_GCAP_NSDO_1SDO 0x00 -#define HDAC_GCAP_NSDO_2SDO 0x02 -#define HDAC_GCAP_NSDO_4SDO 0x04 - -#define HDAC_GCAP_BSS(gcap) \ - (((gcap) & HDAC_GCAP_BSS_MASK) >> HDAC_GCAP_BSS_SHIFT) -#define HDAC_GCAP_ISS(gcap) \ - (((gcap) & HDAC_GCAP_ISS_MASK) >> HDAC_GCAP_ISS_SHIFT) -#define HDAC_GCAP_OSS(gcap) \ - (((gcap) & HDAC_GCAP_OSS_MASK) >> HDAC_GCAP_OSS_SHIFT) -#define HDAC_GCAP_NSDO(gcap) \ - (((gcap) & HDAC_GCAP_NSDO_MASK) >> HDAC_GCAP_NSDO_SHIFT) - -/* GCTL - Global Control */ -#define HDAC_GCTL_CRST 0x00000001 -#define HDAC_GCTL_FCNTRL 0x00000002 -#define HDAC_GCTL_UNSOL 0x00000100 - -/* WAKEEN - Wake Enable */ -#define HDAC_WAKEEN_SDIWEN_MASK 0x7fff -#define HDAC_WAKEEN_SDIWEN_SHIFT 0 - -/* STATESTS - State Change Status */ -#define HDAC_STATESTS_SDIWAKE_MASK 0x7fff -#define HDAC_STATESTS_SDIWAKE_SHIFT 0 - -#define HDAC_STATESTS_SDIWAKE(statests, n) \ - (((((statests) & HDAC_STATESTS_SDIWAKE_MASK) >> \ - HDAC_STATESTS_SDIWAKE_SHIFT) >> (n)) & 0x0001) - -/* GSTS - Global Status */ -#define HDAC_GSTS_FSTS 0x0002 - -/* INTCTL - Interrut Control */ -#define HDAC_INTCTL_SIE_MASK 0x3fffffff -#define HDAC_INTCTL_SIE_SHIFT 0 -#define HDAC_INTCTL_CIE 0x40000000 -#define HDAC_INTCTL_GIE 0x80000000 - -/* INTSTS - Interrupt Status */ -#define HDAC_INTSTS_SIS_MASK 0x3fffffff -#define HDAC_INTSTS_SIS_SHIFT 0 -#define HDAC_INTSTS_CIS 0x40000000 -#define HDAC_INTSTS_GIS 0x80000000 - -/* SSYNC - Stream Synchronization */ -#define HDAC_SSYNC_SSYNC_MASK 0x3fffffff -#define HDAC_SSYNC_SSYNC_SHIFT 0 - -/* CORBWP - CORB Write Pointer */ -#define HDAC_CORBWP_CORBWP_MASK 0x00ff -#define HDAC_CORBWP_CORBWP_SHIFT 0 - -/* CORBRP - CORB Read Pointer */ -#define HDAC_CORBRP_CORBRP_MASK 0x00ff -#define HDAC_CORBRP_CORBRP_SHIFT 0 -#define HDAC_CORBRP_CORBRPRST 0x8000 - -/* CORBCTL - CORB Control */ -#define HDAC_CORBCTL_CMEIE 0x01 -#define HDAC_CORBCTL_CORBRUN 0x02 - -/* CORBSTS - CORB Status */ -#define HDAC_CORBSTS_CMEI 0x01 - -/* CORBSIZE - CORB Size */ -#define HDAC_CORBSIZE_CORBSIZE_MASK 0x03 -#define HDAC_CORBSIZE_CORBSIZE_SHIFT 0 -#define HDAC_CORBSIZE_CORBSZCAP_MASK 0xf0 -#define HDAC_CORBSIZE_CORBSZCAP_SHIFT 4 - -#define HDAC_CORBSIZE_CORBSIZE_2 0x00 -#define HDAC_CORBSIZE_CORBSIZE_16 0x01 -#define HDAC_CORBSIZE_CORBSIZE_256 0x02 - -#define HDAC_CORBSIZE_CORBSZCAP_2 0x10 -#define HDAC_CORBSIZE_CORBSZCAP_16 0x20 -#define HDAC_CORBSIZE_CORBSZCAP_256 0x40 - -#define HDAC_CORBSIZE_CORBSIZE(corbsize) \ - (((corbsize) & HDAC_CORBSIZE_CORBSIZE_MASK) >> HDAC_CORBSIZE_CORBSIZE_SHIFT) - -/* RIRBWP - RIRB Write Pointer */ -#define HDAC_RIRBWP_RIRBWP_MASK 0x00ff -#define HDAC_RIRBWP_RIRBWP_SHIFT 0 -#define HDAC_RIRBWP_RIRBWPRST 0x8000 - -/* RINTCTN - Response Interrupt Count */ -#define HDAC_RINTCNT_MASK 0x00ff -#define HDAC_RINTCNT_SHIFT 0 - -/* RIRBCTL - RIRB Control */ -#define HDAC_RIRBCTL_RINTCTL 0x01 -#define HDAC_RIRBCTL_RIRBDMAEN 0x02 -#define HDAC_RIRBCTL_RIRBOIC 0x04 - -/* RIRBSTS - RIRB Status */ -#define HDAC_RIRBSTS_RINTFL 0x01 -#define HDAC_RIRBSTS_RIRBOIS 0x04 - -/* RIRBSIZE - RIRB Size */ -#define HDAC_RIRBSIZE_RIRBSIZE_MASK 0x03 -#define HDAC_RIRBSIZE_RIRBSIZE_SHIFT 0 -#define HDAC_RIRBSIZE_RIRBSZCAP_MASK 0xf0 -#define HDAC_RIRBSIZE_RIRBSZCAP_SHIFT 4 - -#define HDAC_RIRBSIZE_RIRBSIZE_2 0x00 -#define HDAC_RIRBSIZE_RIRBSIZE_16 0x01 -#define HDAC_RIRBSIZE_RIRBSIZE_256 0x02 - -#define HDAC_RIRBSIZE_RIRBSZCAP_2 0x10 -#define HDAC_RIRBSIZE_RIRBSZCAP_16 0x20 -#define HDAC_RIRBSIZE_RIRBSZCAP_256 0x40 - -#define HDAC_RIRBSIZE_RIRBSIZE(rirbsize) \ - (((rirbsize) & HDAC_RIRBSIZE_RIRBSIZE_MASK) >> HDAC_RIRBSIZE_RIRBSIZE_SHIFT) - -/* DPLBASE - DMA Position Lower Base Address */ -#define HDAC_DPLBASE_DPLBASE_MASK 0xffffff80 -#define HDAC_DPLBASE_DPLBASE_SHIFT 7 -#define HDAC_DPLBASE_DPLBASE_DMAPBE 0x00000001 - -/* SDCTL - Stream Descriptor Control */ -#define HDAC_SDCTL_SRST 0x000001 -#define HDAC_SDCTL_RUN 0x000002 -#define HDAC_SDCTL_IOCE 0x000004 -#define HDAC_SDCTL_FEIE 0x000008 -#define HDAC_SDCTL_DEIE 0x000010 -#define HDAC_SDCTL2_STRIPE_MASK 0x03 -#define HDAC_SDCTL2_STRIPE_SHIFT 0 -#define HDAC_SDCTL2_TP 0x04 -#define HDAC_SDCTL2_DIR 0x08 -#define HDAC_SDCTL2_STRM_MASK 0xf0 -#define HDAC_SDCTL2_STRM_SHIFT 4 - -#define HDAC_SDSTS_DESE (1 << 4) -#define HDAC_SDSTS_FIFOE (1 << 3) -#define HDAC_SDSTS_BCIS (1 << 2) - -#endif /* _HDAC_REG_H_ */ diff --git a/usr.sbin/bhyve/pci_hda.c b/usr.sbin/bhyve/pci_hda.c deleted file mode 100644 index 99f8aec31c6e..000000000000 --- a/usr.sbin/bhyve/pci_hda.c +++ /dev/null @@ -1,1330 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <time.h> - -#include "pci_hda.h" -#include "bhyverun.h" -#include "pci_emul.h" -#include "hdac_reg.h" - -/* - * HDA defines - */ -#define PCIR_HDCTL 0x40 -#define INTEL_VENDORID 0x8086 -#define HDA_INTEL_82801G 0x27d8 - -#define HDA_IOSS_NO 0x08 -#define HDA_OSS_NO 0x04 -#define HDA_ISS_NO 0x04 -#define HDA_CODEC_MAX 0x0f -#define HDA_LAST_OFFSET \ - (0x2084 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20)) -#define HDA_SET_REG_TABLE_SZ \ - (0x80 + ((HDA_ISS_NO) * 0x20) + ((HDA_OSS_NO) * 0x20)) -#define HDA_CORB_ENTRY_LEN 0x04 -#define HDA_RIRB_ENTRY_LEN 0x08 -#define HDA_BDL_ENTRY_LEN 0x10 -#define HDA_DMA_PIB_ENTRY_LEN 0x08 -#define HDA_STREAM_TAGS_CNT 0x10 -#define HDA_STREAM_REGS_BASE 0x80 -#define HDA_STREAM_REGS_LEN 0x20 - -#define HDA_DMA_ACCESS_LEN (sizeof(uint32_t)) -#define HDA_BDL_MAX_LEN 0x0100 - -#define HDAC_SDSTS_FIFORDY (1 << 5) - -#define HDA_RIRBSTS_IRQ_MASK (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS) -#define HDA_STATESTS_IRQ_MASK ((1 << HDA_CODEC_MAX) - 1) -#define HDA_SDSTS_IRQ_MASK \ - (HDAC_SDSTS_DESE | HDAC_SDSTS_FIFOE | HDAC_SDSTS_BCIS) - -/* - * HDA data structures - */ - -struct hda_softc; - -typedef void (*hda_set_reg_handler)(struct hda_softc *sc, uint32_t offset, - uint32_t old); - -struct hda_bdle { - uint32_t addrh; - uint32_t addrl; - uint32_t ioc; - uint32_t len; -} __packed; - -struct hda_bdle_desc { - void *addr; - uint8_t ioc; - uint32_t len; -}; - -struct hda_codec_cmd_ctl { - char *name; - void *dma_vaddr; - uint8_t run; - uint16_t rp; - uint16_t size; - uint16_t wp; -}; - -struct hda_stream_desc { - uint8_t dir; - uint8_t run; - uint8_t stream; - - /* bp is the no. of bytes transferred in the current bdle */ - uint32_t bp; - /* be is the no. of bdles transferred in the bdl */ - uint32_t be; - - uint32_t bdl_cnt; - struct hda_bdle_desc bdl[HDA_BDL_MAX_LEN]; -}; - -struct hda_softc { - struct pci_devinst *pci_dev; - uint32_t regs[HDA_LAST_OFFSET]; - - uint8_t lintr; - uint8_t rirb_cnt; - uint64_t wall_clock_start; - - struct hda_codec_cmd_ctl corb; - struct hda_codec_cmd_ctl rirb; - - uint8_t codecs_no; - struct hda_codec_inst *codecs[HDA_CODEC_MAX]; - - /* Base Address of the DMA Position Buffer */ - void *dma_pib_vaddr; - - struct hda_stream_desc streams[HDA_IOSS_NO]; - /* 2 tables for output and input */ - uint8_t stream_map[2][HDA_STREAM_TAGS_CNT]; -}; - -/* - * HDA module function declarations - */ -static inline void hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, - uint32_t value); -static inline uint32_t hda_get_reg_by_offset(struct hda_softc *sc, - uint32_t offset); -static inline void hda_set_field_by_offset(struct hda_softc *sc, - uint32_t offset, uint32_t mask, uint32_t value); - -static uint8_t hda_parse_config(const char *opts, const char *key, char *val); -static struct hda_softc *hda_init(const char *opts); -static void hda_update_intr(struct hda_softc *sc); -static void hda_response_interrupt(struct hda_softc *sc); -static int hda_codec_constructor(struct hda_softc *sc, - struct hda_codec_class *codec, const char *play, const char *rec, - const char *opts); -static struct hda_codec_class *hda_find_codec_class(const char *name); - -static int hda_send_command(struct hda_softc *sc, uint32_t verb); -static int hda_notify_codecs(struct hda_softc *sc, uint8_t run, - uint8_t stream, uint8_t dir); -static void hda_reset(struct hda_softc *sc); -static void hda_reset_regs(struct hda_softc *sc); -static void hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind); -static int hda_stream_start(struct hda_softc *sc, uint8_t stream_ind); -static int hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind); -static uint32_t hda_read(struct hda_softc *sc, uint32_t offset); -static int hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, - uint32_t value); - -static inline void hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p); -static int hda_corb_start(struct hda_softc *sc); -static int hda_corb_run(struct hda_softc *sc); -static int hda_rirb_start(struct hda_softc *sc); - -static void *hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, - size_t len); -static void hda_dma_st_dword(void *dma_vaddr, uint32_t data); -static uint32_t hda_dma_ld_dword(void *dma_vaddr); - -static inline uint8_t hda_get_stream_by_offsets(uint32_t offset, - uint8_t reg_offset); -static inline uint32_t hda_get_offset_stream(uint8_t stream_ind); - -static void hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_statests(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_corbctl(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, - uint32_t old); -static void hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old); -static void hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old); - -static int hda_signal_state_change(struct hda_codec_inst *hci); -static int hda_response(struct hda_codec_inst *hci, uint32_t response, - uint8_t unsol); -static int hda_transfer(struct hda_codec_inst *hci, uint8_t stream, - uint8_t dir, void *buf, size_t count); - -static void hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib); -static uint64_t hda_get_clock_ns(void); - -/* - * PCI HDA function declarations - */ -static int pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts); -static void pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value); -static uint64_t pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size); -/* - * HDA global data - */ - -static const hda_set_reg_handler hda_set_reg_table[] = { - [HDAC_GCTL] = hda_set_gctl, - [HDAC_STATESTS] = hda_set_statests, - [HDAC_CORBWP] = hda_set_corbwp, - [HDAC_CORBCTL] = hda_set_corbctl, - [HDAC_RIRBCTL] = hda_set_rirbctl, - [HDAC_RIRBSTS] = hda_set_rirbsts, - [HDAC_DPIBLBASE] = hda_set_dpiblbase, - -#define HDAC_ISTREAM(n, iss, oss) \ - [_HDAC_ISDCTL(n, iss, oss)] = hda_set_sdctl, \ - [_HDAC_ISDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \ - [_HDAC_ISDSTS(n, iss, oss)] = hda_set_sdsts, \ - -#define HDAC_OSTREAM(n, iss, oss) \ - [_HDAC_OSDCTL(n, iss, oss)] = hda_set_sdctl, \ - [_HDAC_OSDCTL(n, iss, oss) + 2] = hda_set_sdctl2, \ - [_HDAC_OSDSTS(n, iss, oss)] = hda_set_sdsts, \ - - HDAC_ISTREAM(0, HDA_ISS_NO, HDA_OSS_NO) - HDAC_ISTREAM(1, HDA_ISS_NO, HDA_OSS_NO) - HDAC_ISTREAM(2, HDA_ISS_NO, HDA_OSS_NO) - HDAC_ISTREAM(3, HDA_ISS_NO, HDA_OSS_NO) - - HDAC_OSTREAM(0, HDA_ISS_NO, HDA_OSS_NO) - HDAC_OSTREAM(1, HDA_ISS_NO, HDA_OSS_NO) - HDAC_OSTREAM(2, HDA_ISS_NO, HDA_OSS_NO) - HDAC_OSTREAM(3, HDA_ISS_NO, HDA_OSS_NO) - - [HDA_SET_REG_TABLE_SZ] = NULL, -}; - -static const uint16_t hda_corb_sizes[] = { - [HDAC_CORBSIZE_CORBSIZE_2] = 2, - [HDAC_CORBSIZE_CORBSIZE_16] = 16, - [HDAC_CORBSIZE_CORBSIZE_256] = 256, - [HDAC_CORBSIZE_CORBSIZE_MASK] = 0, -}; - -static const uint16_t hda_rirb_sizes[] = { - [HDAC_RIRBSIZE_RIRBSIZE_2] = 2, - [HDAC_RIRBSIZE_RIRBSIZE_16] = 16, - [HDAC_RIRBSIZE_RIRBSIZE_256] = 256, - [HDAC_RIRBSIZE_RIRBSIZE_MASK] = 0, -}; - -static struct hda_ops hops = { - .signal = hda_signal_state_change, - .response = hda_response, - .transfer = hda_transfer, -}; - -struct pci_devemu pci_de_hda = { - .pe_emu = "hda", - .pe_init = pci_hda_init, - .pe_barwrite = pci_hda_write, - .pe_barread = pci_hda_read -}; - -PCI_EMUL_SET(pci_de_hda); - -SET_DECLARE(hda_codec_class_set, struct hda_codec_class); - -#if DEBUG_HDA == 1 -FILE *dbg; -#endif - -/* - * HDA module function definitions - */ - -static inline void -hda_set_reg_by_offset(struct hda_softc *sc, uint32_t offset, uint32_t value) -{ - assert(offset < HDA_LAST_OFFSET); - sc->regs[offset] = value; -} - -static inline uint32_t -hda_get_reg_by_offset(struct hda_softc *sc, uint32_t offset) -{ - assert(offset < HDA_LAST_OFFSET); - return sc->regs[offset]; -} - -static inline void -hda_set_field_by_offset(struct hda_softc *sc, uint32_t offset, - uint32_t mask, uint32_t value) -{ - uint32_t reg_value = 0; - - reg_value = hda_get_reg_by_offset(sc, offset); - - reg_value &= ~mask; - reg_value |= (value & mask); - - hda_set_reg_by_offset(sc, offset, reg_value); -} - -static uint8_t -hda_parse_config(const char *opts, const char *key, char *val) -{ - char buf[64]; - char *s = buf; - char *tmp = NULL; - int len; - int i; - - if (!opts) - return (0); - - len = strlen(opts); - - if (len >= 64) { - DPRINTF("Opts too big\n"); - return (0); - } - - DPRINTF("opts: %s\n", opts); - - strcpy(buf, opts); - - for (i = 0; i < len; i++) - if (buf[i] == ',') { - buf[i] = 0; - tmp = buf + i + 1; - break; - } - - if (!memcmp(s, key, strlen(key))) { - strncpy(val, s + strlen(key), 64); - return (1); - } - - if (!tmp) - return (0); - - s = tmp; - if (!memcmp(s, key, strlen(key))) { - strncpy(val, s + strlen(key), 64); - return (1); - } - - return (0); -} - -static struct hda_softc * -hda_init(const char *opts) -{ - struct hda_softc *sc = NULL; - struct hda_codec_class *codec = NULL; - char play[64]; - char rec[64]; - int err, p, r; - -#if DEBUG_HDA == 1 - dbg = fopen("/tmp/bhyve_hda.log", "w+"); -#endif - - DPRINTF("opts: %s\n", opts); - - sc = calloc(1, sizeof(*sc)); - if (!sc) - return (NULL); - - hda_reset_regs(sc); - - /* - * TODO search all the codecs declared in opts - * For now we play with one single codec - */ - codec = hda_find_codec_class("hda_codec"); - if (codec) { - p = hda_parse_config(opts, "play=", play); - r = hda_parse_config(opts, "rec=", rec); - DPRINTF("play: %s rec: %s\n", play, rec); - if (p | r) { - err = hda_codec_constructor(sc, codec, p ? \ - play : NULL, r ? rec : NULL, NULL); - assert(!err); - } - } - - return (sc); -} - -static void -hda_update_intr(struct hda_softc *sc) -{ - struct pci_devinst *pi = sc->pci_dev; - uint32_t intctl = hda_get_reg_by_offset(sc, HDAC_INTCTL); - uint32_t intsts = 0; - uint32_t sdsts = 0; - uint32_t rirbsts = 0; - uint32_t wakeen = 0; - uint32_t statests = 0; - uint32_t off = 0; - int i; - - /* update the CIS bits */ - rirbsts = hda_get_reg_by_offset(sc, HDAC_RIRBSTS); - if (rirbsts & (HDAC_RIRBSTS_RINTFL | HDAC_RIRBSTS_RIRBOIS)) - intsts |= HDAC_INTSTS_CIS; - - wakeen = hda_get_reg_by_offset(sc, HDAC_WAKEEN); - statests = hda_get_reg_by_offset(sc, HDAC_STATESTS); - if (statests & wakeen) - intsts |= HDAC_INTSTS_CIS; - - /* update the SIS bits */ - for (i = 0; i < HDA_IOSS_NO; i++) { - off = hda_get_offset_stream(i); - sdsts = hda_get_reg_by_offset(sc, off + HDAC_SDSTS); - if (sdsts & HDAC_SDSTS_BCIS) - intsts |= (1 << i); - } - - /* update the GIS bit */ - if (intsts) - intsts |= HDAC_INTSTS_GIS; - - hda_set_reg_by_offset(sc, HDAC_INTSTS, intsts); - - if ((intctl & HDAC_INTCTL_GIE) && ((intsts & \ - ~HDAC_INTSTS_GIS) & intctl)) { - if (!sc->lintr) { - pci_lintr_assert(pi); - sc->lintr = 1; - } - } else { - if (sc->lintr) { - pci_lintr_deassert(pi); - sc->lintr = 0; - } - } -} - -static void -hda_response_interrupt(struct hda_softc *sc) -{ - uint8_t rirbctl = hda_get_reg_by_offset(sc, HDAC_RIRBCTL); - - if ((rirbctl & HDAC_RIRBCTL_RINTCTL) && sc->rirb_cnt) { - sc->rirb_cnt = 0; - hda_set_field_by_offset(sc, HDAC_RIRBSTS, HDAC_RIRBSTS_RINTFL, - HDAC_RIRBSTS_RINTFL); - hda_update_intr(sc); - } -} - -static int -hda_codec_constructor(struct hda_softc *sc, struct hda_codec_class *codec, - const char *play, const char *rec, const char *opts) -{ - struct hda_codec_inst *hci = NULL; - - if (sc->codecs_no >= HDA_CODEC_MAX) - return (-1); - - hci = calloc(1, sizeof(struct hda_codec_inst)); - if (!hci) - return (-1); - - hci->hda = sc; - hci->hops = &hops; - hci->cad = sc->codecs_no; - hci->codec = codec; - - sc->codecs[sc->codecs_no++] = hci; - - if (!codec->init) { - DPRINTF("This codec does not implement the init function\n"); - return (-1); - } - - return (codec->init(hci, play, rec, opts)); -} - -static struct hda_codec_class * -hda_find_codec_class(const char *name) -{ - struct hda_codec_class **pdpp = NULL, *pdp = NULL; - - SET_FOREACH(pdpp, hda_codec_class_set) { - pdp = *pdpp; - if (!strcmp(pdp->name, name)) { - return (pdp); - } - } - - return (NULL); -} - -static int -hda_send_command(struct hda_softc *sc, uint32_t verb) -{ - struct hda_codec_inst *hci = NULL; - struct hda_codec_class *codec = NULL; - uint8_t cad = (verb >> HDA_CMD_CAD_SHIFT) & 0x0f; - - hci = sc->codecs[cad]; - if (!hci) - return (-1); - - DPRINTF("cad: 0x%x verb: 0x%x\n", cad, verb); - - codec = hci->codec; - assert(codec); - - if (!codec->command) { - DPRINTF("This codec does not implement the command function\n"); - return (-1); - } - - return (codec->command(hci, verb)); -} - -static int -hda_notify_codecs(struct hda_softc *sc, uint8_t run, uint8_t stream, - uint8_t dir) -{ - struct hda_codec_inst *hci = NULL; - struct hda_codec_class *codec = NULL; - int err; - int i; - - /* Notify each codec */ - for (i = 0; i < sc->codecs_no; i++) { - hci = sc->codecs[i]; - assert(hci); - - codec = hci->codec; - assert(codec); - - if (codec->notify) { - err = codec->notify(hci, run, stream, dir); - if (!err) - break; - } - } - - return (i == sc->codecs_no ? (-1) : 0); -} - -static void -hda_reset(struct hda_softc *sc) -{ - int i; - struct hda_codec_inst *hci = NULL; - struct hda_codec_class *codec = NULL; - - hda_reset_regs(sc); - - /* Reset each codec */ - for (i = 0; i < sc->codecs_no; i++) { - hci = sc->codecs[i]; - assert(hci); - - codec = hci->codec; - assert(codec); - - if (codec->reset) - codec->reset(hci); - } - - sc->wall_clock_start = hda_get_clock_ns(); -} - -static void -hda_reset_regs(struct hda_softc *sc) -{ - uint32_t off = 0; - uint8_t i; - - DPRINTF("Reset the HDA controller registers ...\n"); - - memset(sc->regs, 0, sizeof(sc->regs)); - - hda_set_reg_by_offset(sc, HDAC_GCAP, - HDAC_GCAP_64OK | - (HDA_ISS_NO << HDAC_GCAP_ISS_SHIFT) | - (HDA_OSS_NO << HDAC_GCAP_OSS_SHIFT)); - hda_set_reg_by_offset(sc, HDAC_VMAJ, 0x01); - hda_set_reg_by_offset(sc, HDAC_OUTPAY, 0x3c); - hda_set_reg_by_offset(sc, HDAC_INPAY, 0x1d); - hda_set_reg_by_offset(sc, HDAC_CORBSIZE, - HDAC_CORBSIZE_CORBSZCAP_256 | HDAC_CORBSIZE_CORBSIZE_256); - hda_set_reg_by_offset(sc, HDAC_RIRBSIZE, - HDAC_RIRBSIZE_RIRBSZCAP_256 | HDAC_RIRBSIZE_RIRBSIZE_256); - - for (i = 0; i < HDA_IOSS_NO; i++) { - off = hda_get_offset_stream(i); - hda_set_reg_by_offset(sc, off + HDAC_SDFIFOS, HDA_FIFO_SIZE); - } -} - -static void -hda_stream_reset(struct hda_softc *sc, uint8_t stream_ind) -{ - struct hda_stream_desc *st = &sc->streams[stream_ind]; - uint32_t off = hda_get_offset_stream(stream_ind); - - DPRINTF("Reset the HDA stream: 0x%x\n", stream_ind); - - /* Reset the Stream Descriptor registers */ - memset(sc->regs + HDA_STREAM_REGS_BASE + off, 0, HDA_STREAM_REGS_LEN); - - /* Reset the Stream Descriptor */ - memset(st, 0, sizeof(*st)); - - hda_set_field_by_offset(sc, off + HDAC_SDSTS, - HDAC_SDSTS_FIFORDY, HDAC_SDSTS_FIFORDY); - hda_set_field_by_offset(sc, off + HDAC_SDCTL0, - HDAC_SDCTL_SRST, HDAC_SDCTL_SRST); -} - -static int -hda_stream_start(struct hda_softc *sc, uint8_t stream_ind) -{ - struct hda_stream_desc *st = &sc->streams[stream_ind]; - struct hda_bdle_desc *bdle_desc = NULL; - struct hda_bdle *bdle = NULL; - uint32_t lvi = 0; - uint32_t bdl_cnt = 0; - uint64_t bdpl = 0; - uint64_t bdpu = 0; - uint64_t bdl_paddr = 0; - void *bdl_vaddr = NULL; - uint32_t bdle_sz = 0; - uint64_t bdle_addrl = 0; - uint64_t bdle_addrh = 0; - uint64_t bdle_paddr = 0; - void *bdle_vaddr = NULL; - uint32_t off = hda_get_offset_stream(stream_ind); - uint32_t sdctl = 0; - uint8_t strm = 0; - uint8_t dir = 0; - int i; - - assert(!st->run); - - lvi = hda_get_reg_by_offset(sc, off + HDAC_SDLVI); - bdpl = hda_get_reg_by_offset(sc, off + HDAC_SDBDPL); - bdpu = hda_get_reg_by_offset(sc, off + HDAC_SDBDPU); - - bdl_cnt = lvi + 1; - assert(bdl_cnt <= HDA_BDL_MAX_LEN); - - bdl_paddr = bdpl | (bdpu << 32); - bdl_vaddr = hda_dma_get_vaddr(sc, bdl_paddr, - HDA_BDL_ENTRY_LEN * bdl_cnt); - if (!bdl_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - DPRINTF("stream: 0x%x bdl_cnt: 0x%x bdl_paddr: 0x%lx\n", - stream_ind, bdl_cnt, bdl_paddr); - - st->bdl_cnt = bdl_cnt; - - bdle = (struct hda_bdle *)bdl_vaddr; - for (i = 0; i < bdl_cnt; i++, bdle++) { - bdle_sz = bdle->len; - assert(!(bdle_sz % HDA_DMA_ACCESS_LEN)); - - bdle_addrl = bdle->addrl; - bdle_addrh = bdle->addrh; - - bdle_paddr = bdle_addrl | (bdle_addrh << 32); - bdle_vaddr = hda_dma_get_vaddr(sc, bdle_paddr, bdle_sz); - if (!bdle_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - bdle_desc = &st->bdl[i]; - bdle_desc->addr = bdle_vaddr; - bdle_desc->len = bdle_sz; - bdle_desc->ioc = bdle->ioc; - - DPRINTF("bdle: 0x%x bdle_sz: 0x%x\n", i, bdle_sz); - } - - sdctl = hda_get_reg_by_offset(sc, off + HDAC_SDCTL0); - strm = (sdctl >> 20) & 0x0f; - dir = stream_ind >= HDA_ISS_NO; - - DPRINTF("strm: 0x%x, dir: 0x%x\n", strm, dir); - - sc->stream_map[dir][strm] = stream_ind; - st->stream = strm; - st->dir = dir; - st->bp = 0; - st->be = 0; - - hda_set_pib(sc, stream_ind, 0); - - st->run = 1; - - hda_notify_codecs(sc, 1, strm, dir); - - return (0); -} - -static int -hda_stream_stop(struct hda_softc *sc, uint8_t stream_ind) -{ - struct hda_stream_desc *st = &sc->streams[stream_ind]; - uint8_t strm = st->stream; - uint8_t dir = st->dir; - - DPRINTF("stream: 0x%x, strm: 0x%x, dir: 0x%x\n", stream_ind, strm, dir); - - st->run = 0; - - hda_notify_codecs(sc, 0, strm, dir); - - return (0); -} - -static uint32_t -hda_read(struct hda_softc *sc, uint32_t offset) -{ - if (offset == HDAC_WALCLK) - return (24 * (hda_get_clock_ns() - \ - sc->wall_clock_start) / 1000); - - return (hda_get_reg_by_offset(sc, offset)); -} - -static int -hda_write(struct hda_softc *sc, uint32_t offset, uint8_t size, uint32_t value) -{ - uint32_t old = hda_get_reg_by_offset(sc, offset); - uint32_t masks[] = {0x00000000, 0x000000ff, 0x0000ffff, - 0x00ffffff, 0xffffffff}; - hda_set_reg_handler set_reg_handler = hda_set_reg_table[offset]; - - hda_set_field_by_offset(sc, offset, masks[size], value); - - if (set_reg_handler) - set_reg_handler(sc, offset, old); - - return (0); -} - -static inline void -hda_print_cmd_ctl_data(struct hda_codec_cmd_ctl *p) -{ -#if DEBUG_HDA == 1 - char *name = p->name; -#endif - DPRINTF("%s size: %d\n", name, p->size); - DPRINTF("%s dma_vaddr: %p\n", name, p->dma_vaddr); - DPRINTF("%s wp: 0x%x\n", name, p->wp); - DPRINTF("%s rp: 0x%x\n", name, p->rp); -} - -static int -hda_corb_start(struct hda_softc *sc) -{ - struct hda_codec_cmd_ctl *corb = &sc->corb; - uint8_t corbsize = 0; - uint64_t corblbase = 0; - uint64_t corbubase = 0; - uint64_t corbpaddr = 0; - - corb->name = "CORB"; - - corbsize = hda_get_reg_by_offset(sc, HDAC_CORBSIZE) & \ - HDAC_CORBSIZE_CORBSIZE_MASK; - corb->size = hda_corb_sizes[corbsize]; - - if (!corb->size) { - DPRINTF("Invalid corb size\n"); - return (-1); - } - - corblbase = hda_get_reg_by_offset(sc, HDAC_CORBLBASE); - corbubase = hda_get_reg_by_offset(sc, HDAC_CORBUBASE); - - corbpaddr = corblbase | (corbubase << 32); - DPRINTF("CORB dma_paddr: %p\n", (void *)corbpaddr); - - corb->dma_vaddr = hda_dma_get_vaddr(sc, corbpaddr, - HDA_CORB_ENTRY_LEN * corb->size); - if (!corb->dma_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP); - corb->rp = hda_get_reg_by_offset(sc, HDAC_CORBRP); - - corb->run = 1; - - hda_print_cmd_ctl_data(corb); - - return (0); -} - -static int -hda_corb_run(struct hda_softc *sc) -{ - struct hda_codec_cmd_ctl *corb = &sc->corb; - uint32_t verb = 0; - int err; - - corb->wp = hda_get_reg_by_offset(sc, HDAC_CORBWP); - - while (corb->rp != corb->wp && corb->run) { - corb->rp++; - corb->rp %= corb->size; - - verb = hda_dma_ld_dword(corb->dma_vaddr + \ - HDA_CORB_ENTRY_LEN * corb->rp); - - err = hda_send_command(sc, verb); - assert(!err); - } - - hda_set_reg_by_offset(sc, HDAC_CORBRP, corb->rp); - - if (corb->run) - hda_response_interrupt(sc); - - return (0); -} - -static int -hda_rirb_start(struct hda_softc *sc) -{ - struct hda_codec_cmd_ctl *rirb = &sc->rirb; - uint8_t rirbsize = 0; - uint64_t rirblbase = 0; - uint64_t rirbubase = 0; - uint64_t rirbpaddr = 0; - - rirb->name = "RIRB"; - - rirbsize = hda_get_reg_by_offset(sc, HDAC_RIRBSIZE) & \ - HDAC_RIRBSIZE_RIRBSIZE_MASK; - rirb->size = hda_rirb_sizes[rirbsize]; - - if (!rirb->size) { - DPRINTF("Invalid rirb size\n"); - return (-1); - } - - rirblbase = hda_get_reg_by_offset(sc, HDAC_RIRBLBASE); - rirbubase = hda_get_reg_by_offset(sc, HDAC_RIRBUBASE); - - rirbpaddr = rirblbase | (rirbubase << 32); - DPRINTF("RIRB dma_paddr: %p\n", (void *)rirbpaddr); - - rirb->dma_vaddr = hda_dma_get_vaddr(sc, rirbpaddr, - HDA_RIRB_ENTRY_LEN * rirb->size); - if (!rirb->dma_vaddr) { - DPRINTF("Fail to get the guest virtual address\n"); - return (-1); - } - - rirb->wp = hda_get_reg_by_offset(sc, HDAC_RIRBWP); - rirb->rp = 0x0000; - - rirb->run = 1; - - hda_print_cmd_ctl_data(rirb); - - return (0); -} - -static void * -hda_dma_get_vaddr(struct hda_softc *sc, uint64_t dma_paddr, size_t len) -{ - struct pci_devinst *pi = sc->pci_dev; - - assert(pi); - - return (paddr_guest2host(pi->pi_vmctx, (uintptr_t)dma_paddr, len)); -} - -static void -hda_dma_st_dword(void *dma_vaddr, uint32_t data) -{ - *(uint32_t*)dma_vaddr = data; -} - -static uint32_t -hda_dma_ld_dword(void *dma_vaddr) -{ - return (*(uint32_t*)dma_vaddr); -} - -static inline uint8_t -hda_get_stream_by_offsets(uint32_t offset, uint8_t reg_offset) -{ - uint8_t stream_ind = (offset - reg_offset) >> 5; - - assert(stream_ind < HDA_IOSS_NO); - - return (stream_ind); -} - -static inline uint32_t -hda_get_offset_stream(uint8_t stream_ind) -{ - return (stream_ind << 5); -} - -static void -hda_set_gctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - if (!(value & HDAC_GCTL_CRST)) { - hda_reset(sc); - } -} - -static void -hda_set_statests(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_reg_by_offset(sc, offset, old); - - /* clear the corresponding bits written by the software (guest) */ - hda_set_field_by_offset(sc, offset, value & HDA_STATESTS_IRQ_MASK, 0); - - hda_update_intr(sc); -} - -static void -hda_set_corbwp(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - hda_corb_run(sc); -} - -static void -hda_set_corbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - int err; - struct hda_codec_cmd_ctl *corb = NULL; - - if (value & HDAC_CORBCTL_CORBRUN) { - if (!(old & HDAC_CORBCTL_CORBRUN)) { - err = hda_corb_start(sc); - assert(!err); - } - } else { - corb = &sc->corb; - memset(corb, 0, sizeof(*corb)); - } - - hda_corb_run(sc); -} - -static void -hda_set_rirbctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - int err; - struct hda_codec_cmd_ctl *rirb = NULL; - - if (value & HDAC_RIRBCTL_RIRBDMAEN) { - err = hda_rirb_start(sc); - assert(!err); - } else { - rirb = &sc->rirb; - memset(rirb, 0, sizeof(*rirb)); - } -} - -static void -hda_set_rirbsts(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_reg_by_offset(sc, offset, old); - - /* clear the corresponding bits written by the software (guest) */ - hda_set_field_by_offset(sc, offset, value & HDA_RIRBSTS_IRQ_MASK, 0); - - hda_update_intr(sc); -} - -static void -hda_set_dpiblbase(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - uint64_t dpiblbase = 0; - uint64_t dpibubase = 0; - uint64_t dpibpaddr = 0; - - if ((value & HDAC_DPLBASE_DPLBASE_DMAPBE) != (old & \ - HDAC_DPLBASE_DPLBASE_DMAPBE)) { - if (value & HDAC_DPLBASE_DPLBASE_DMAPBE) { - dpiblbase = value & HDAC_DPLBASE_DPLBASE_MASK; - dpibubase = hda_get_reg_by_offset(sc, HDAC_DPIBUBASE); - - dpibpaddr = dpiblbase | (dpibubase << 32); - DPRINTF("DMA Position In Buffer dma_paddr: %p\n", - (void *)dpibpaddr); - - sc->dma_pib_vaddr = hda_dma_get_vaddr(sc, dpibpaddr, - HDA_DMA_PIB_ENTRY_LEN * HDA_IOSS_NO); - if (!sc->dma_pib_vaddr) { - DPRINTF("Fail to get the guest \ - virtual address\n"); - assert(0); - } - } else { - DPRINTF("DMA Position In Buffer Reset\n"); - sc->dma_pib_vaddr = NULL; - } - } -} - -static void -hda_set_sdctl(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint8_t stream_ind = hda_get_stream_by_offsets(offset, HDAC_SDCTL0); - uint32_t value = hda_get_reg_by_offset(sc, offset); - int err; - - DPRINTF("stream_ind: 0x%x old: 0x%x value: 0x%x\n", - stream_ind, old, value); - - if (value & HDAC_SDCTL_SRST) { - hda_stream_reset(sc, stream_ind); - } - - if ((value & HDAC_SDCTL_RUN) != (old & HDAC_SDCTL_RUN)) { - if (value & HDAC_SDCTL_RUN) { - err = hda_stream_start(sc, stream_ind); - assert(!err); - } else { - err = hda_stream_stop(sc, stream_ind); - assert(!err); - } - } -} - -static void -hda_set_sdctl2(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_field_by_offset(sc, offset - 2, 0x00ff0000, value << 16); -} - -static void -hda_set_sdsts(struct hda_softc *sc, uint32_t offset, uint32_t old) -{ - uint32_t value = hda_get_reg_by_offset(sc, offset); - - hda_set_reg_by_offset(sc, offset, old); - - /* clear the corresponding bits written by the software (guest) */ - hda_set_field_by_offset(sc, offset, value & HDA_SDSTS_IRQ_MASK, 0); - - hda_update_intr(sc); -} - -static int -hda_signal_state_change(struct hda_codec_inst *hci) -{ - struct hda_softc *sc = NULL; - uint32_t sdiwake = 0; - - assert(hci); - assert(hci->hda); - - DPRINTF("cad: 0x%x\n", hci->cad); - - sc = hci->hda; - sdiwake = 1 << hci->cad; - - hda_set_field_by_offset(sc, HDAC_STATESTS, sdiwake, sdiwake); - hda_update_intr(sc); - - return (0); -} - -static int -hda_response(struct hda_codec_inst *hci, uint32_t response, uint8_t unsol) -{ - struct hda_softc *sc = NULL; - struct hda_codec_cmd_ctl *rirb = NULL; - uint32_t response_ex = 0; - uint8_t rintcnt = 0; - - assert(hci); - assert(hci->cad <= HDA_CODEC_MAX); - - response_ex = hci->cad | unsol; - - sc = hci->hda; - assert(sc); - - rirb = &sc->rirb; - - if (rirb->run) { - rirb->wp++; - rirb->wp %= rirb->size; - - hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \ - rirb->wp, response); - hda_dma_st_dword(rirb->dma_vaddr + HDA_RIRB_ENTRY_LEN * \ - rirb->wp + 0x04, response_ex); - - hda_set_reg_by_offset(sc, HDAC_RIRBWP, rirb->wp); - - sc->rirb_cnt++; - } - - rintcnt = hda_get_reg_by_offset(sc, HDAC_RINTCNT); - if (sc->rirb_cnt == rintcnt) - hda_response_interrupt(sc); - - return (0); -} - -static int -hda_transfer(struct hda_codec_inst *hci, uint8_t stream, uint8_t dir, - void *buf, size_t count) -{ - struct hda_softc *sc = NULL; - struct hda_stream_desc *st = NULL; - struct hda_bdle_desc *bdl = NULL; - struct hda_bdle_desc *bdle_desc = NULL; - uint8_t stream_ind = 0; - uint32_t lpib = 0; - uint32_t off = 0; - size_t left = 0; - uint8_t irq = 0; - - assert(hci); - assert(hci->hda); - assert(buf); - assert(!(count % HDA_DMA_ACCESS_LEN)); - - if (!stream) { - DPRINTF("Invalid stream\n"); - return (-1); - } - - sc = hci->hda; - - assert(stream < HDA_STREAM_TAGS_CNT); - stream_ind = sc->stream_map[dir][stream]; - - if (!dir) - assert(stream_ind < HDA_ISS_NO); - else - assert(stream_ind >= HDA_ISS_NO && stream_ind < HDA_IOSS_NO); - - st = &sc->streams[stream_ind]; - if (!st->run) { - DPRINTF("Stream 0x%x stopped\n", stream); - return (-1); - } - - assert(st->stream == stream); - - off = hda_get_offset_stream(stream_ind); - - lpib = hda_get_reg_by_offset(sc, off + HDAC_SDLPIB); - - bdl = st->bdl; - - assert(st->be < st->bdl_cnt); - assert(st->bp < bdl[st->be].len); - - left = count; - while (left) { - bdle_desc = &bdl[st->be]; - - if (dir) - *(uint32_t *)buf = \ - hda_dma_ld_dword(bdle_desc->addr + st->bp); - else - hda_dma_st_dword(bdle_desc->addr + st->bp, - *(uint32_t *)buf); - - buf += HDA_DMA_ACCESS_LEN; - st->bp += HDA_DMA_ACCESS_LEN; - lpib += HDA_DMA_ACCESS_LEN; - left -= HDA_DMA_ACCESS_LEN; - - if (st->bp == bdle_desc->len) { - st->bp = 0; - if (bdle_desc->ioc) - irq = 1; - st->be++; - if (st->be == st->bdl_cnt) { - st->be = 0; - lpib = 0; - } - bdle_desc = &bdl[st->be]; - } - } - - hda_set_pib(sc, stream_ind, lpib); - - if (irq) { - hda_set_field_by_offset(sc, off + HDAC_SDSTS, - HDAC_SDSTS_BCIS, HDAC_SDSTS_BCIS); - hda_update_intr(sc); - } - - return (0); -} - -static void -hda_set_pib(struct hda_softc *sc, uint8_t stream_ind, uint32_t pib) -{ - uint32_t off = hda_get_offset_stream(stream_ind); - - hda_set_reg_by_offset(sc, off + HDAC_SDLPIB, pib); - /* LPIB Alias */ - hda_set_reg_by_offset(sc, 0x2000 + off + HDAC_SDLPIB, pib); - if (sc->dma_pib_vaddr) - *(uint32_t *)(sc->dma_pib_vaddr + stream_ind * \ - HDA_DMA_PIB_ENTRY_LEN) = pib; -} - -static uint64_t hda_get_clock_ns(void) -{ - struct timespec ts; - int err; - - err = clock_gettime(CLOCK_MONOTONIC, &ts); - assert(!err); - - return (ts.tv_sec * 1000000000LL + ts.tv_nsec); -} - -/* - * PCI HDA function definitions - */ -static int -pci_hda_init(struct vmctx *ctx, struct pci_devinst *pi, char *opts) -{ - struct hda_softc *sc = NULL; - - assert(ctx != NULL); - assert(pi != NULL); - - pci_set_cfgdata16(pi, PCIR_VENDOR, INTEL_VENDORID); - pci_set_cfgdata16(pi, PCIR_DEVICE, HDA_INTEL_82801G); - - pci_set_cfgdata8(pi, PCIR_SUBCLASS, PCIS_MULTIMEDIA_HDA); - pci_set_cfgdata8(pi, PCIR_CLASS, PCIC_MULTIMEDIA); - - /* select the Intel HDA mode */ - pci_set_cfgdata8(pi, PCIR_HDCTL, 0x01); - - /* allocate one BAR register for the Memory address offsets */ - pci_emul_alloc_bar(pi, 0, PCIBAR_MEM32, HDA_LAST_OFFSET); - - /* allocate an IRQ pin for our slot */ - pci_lintr_request(pi); - - sc = hda_init(opts); - if (!sc) - return (-1); - - sc->pci_dev = pi; - pi->pi_arg = sc; - - return (0); -} - -static void -pci_hda_write(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size, uint64_t value) -{ - struct hda_softc *sc = pi->pi_arg; - int err; - - assert(sc); - assert(baridx == 0); - assert(size <= 4); - - DPRINTF("offset: 0x%lx value: 0x%lx\n", offset, value); - - err = hda_write(sc, offset, size, value); - assert(!err); -} - -static uint64_t -pci_hda_read(struct vmctx *ctx, int vcpu, struct pci_devinst *pi, - int baridx, uint64_t offset, int size) -{ - struct hda_softc *sc = pi->pi_arg; - uint64_t value = 0; - - assert(sc); - assert(baridx == 0); - assert(size <= 4); - - value = hda_read(sc, offset); - - DPRINTF("offset: 0x%lx value: 0x%lx\n", offset, value); - - return (value); -} diff --git a/usr.sbin/bhyve/pci_hda.h b/usr.sbin/bhyve/pci_hda.h deleted file mode 100644 index 038a1da8dee6..000000000000 --- a/usr.sbin/bhyve/pci_hda.h +++ /dev/null @@ -1,90 +0,0 @@ -/*- - * Copyright (c) 2016 Alex Teaca <iateaca@FreeBSD.org> - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _HDA_EMUL_H_ -#define _HDA_EMUL_H_ - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <sys/types.h> -#include <assert.h> - -#include <sys/types.h> -#include <sys/queue.h> -#include <sys/kernel.h> - -#include "hda_reg.h" - -/* - * HDA Debug Log - */ -#define DEBUG_HDA 1 -#if DEBUG_HDA == 1 -extern FILE *dbg; -#define DPRINTF(fmt, arg...) \ -do {fprintf(dbg, "%s-%d: " fmt, __func__, __LINE__, ##arg); \ -fflush(dbg); } while (0) -#else -#define DPRINTF(fmt, arg...) -#endif - -#define HDA_FIFO_SIZE 0x100 - -struct hda_softc; -struct hda_codec_class; - -struct hda_codec_inst { - uint8_t cad; - struct hda_codec_class *codec; - struct hda_softc *hda; - struct hda_ops *hops; - void *priv; -}; - -struct hda_codec_class { - char *name; - int (*init)(struct hda_codec_inst *hci, const char *play, - const char *rec, const char *opts); - int (*reset)(struct hda_codec_inst *hci); - int (*command)(struct hda_codec_inst *hci, uint32_t cmd_data); - int (*notify)(struct hda_codec_inst *hci, uint8_t run, uint8_t stream, - uint8_t dir); -}; - -struct hda_ops { - int (*signal)(struct hda_codec_inst *hci); - int (*response)(struct hda_codec_inst *hci, uint32_t response, - uint8_t unsol); - int (*transfer)(struct hda_codec_inst *hci, uint8_t stream, - uint8_t dir, void *buf, size_t count); -}; - -#define HDA_EMUL_SET(x) DATA_SET(hda_codec_class_set, x); - -#endif /* _HDA_EMUL_H_ */ diff --git a/usr.sbin/nandsim/Makefile b/usr.sbin/nandsim/Makefile deleted file mode 100644 index 9269ab5de34f..000000000000 --- a/usr.sbin/nandsim/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# $FreeBSD$ - -PROG= nandsim -SRCS= nandsim.c nandsim_rcfile.c nandsim_cfgparse.c -BINDIR= /usr/sbin -MAN= nandsim.8 - -.include <bsd.prog.mk> diff --git a/usr.sbin/nandsim/Makefile.depend b/usr.sbin/nandsim/Makefile.depend deleted file mode 100644 index 6cfaab1c3644..000000000000 --- a/usr.sbin/nandsim/Makefile.depend +++ /dev/null @@ -1,17 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/usr.sbin/nandsim/nandsim.8 b/usr.sbin/nandsim/nandsim.8 deleted file mode 100644 index 0951cc7a1aac..000000000000 --- a/usr.sbin/nandsim/nandsim.8 +++ /dev/null @@ -1,229 +0,0 @@ -.\" Copyright (c) 2010 Semihalf -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd August 10, 2010 -.Dt NANDSIM 8 -.Os -.Sh NAME -.Nm nandsim -.Nd NAND simulator control program -.Sh SYNOPSIS -.Nm -.Ic status -.Aq ctrl_no | Fl -all | Fl a -.Op Fl v -.Nm -.Ic conf -.Aq filename -.Nm -.Ic start -.Aq ctrl_no -.Nm -.Ic mod -.Aq ctrl_no:cs_no | Fl l Aq loglevel -.Op Fl p Aq prog_time -.Op Fl e Aq erase_time -.Op Fl r Aq read_time -.Op Fl E Aq error_ratio -.Op Fl h -.Nm -.Ic stop -.Aq ctrl_no -.Nm -.Ic error -.Aq ctrl_no:cs_no -.Aq page_num -.Aq column -.Aq length -.Aq pattern -.Nm -.Ic bb -.Aq ctrl_no:cs_no -.Op blk_num,blk_num2,... -.Op Fl U -.Op Fl L -.Nm -.Ic freeze -.Op ctrl_no -.Nm -.Ic log -.Aq ctrl_no | Fl -all | Fl a -.Nm -.Ic stats -.Aq ctrl_no:cs_no -.Aq page_num -.Nm -.Ic dump -.Aq ctrl_no:cs_no -.Aq filename -.Nm -.Ic restore -.Aq ctrl_no:chip_no -.Aq filename -.Nm -.Ic destroy -.Aq ctrl_no[:cs_no] | Fl -all | Fl a -.Nm -.Ic help -.Op Fl v -.Sh COMMAND DESCRIPTION -Controllers and chips are arranged into a simple hierarchy. -There can be up to 4 controllers configured, each with 4 chip select (CS) lines. -A given chip is connected to one of the chip selects. -.Pp -Controllers are specified as -.Aq ctrl_no ; -chip selects are specified as -.Aq cs_no . -.Bl -tag -width periphlist -.It Ic status -Gets controller(s) status. If -.Fl a -or -.Fl -all -flag is specified - command will print status of every controller -currently available. -Optional flag -.Fl v -causes printing complete information about the controller, and all -chips attached to it. -.It Ic conf -Reads simulator configuration from a specified file (this includes -the simulation "layout" i.e. controllers-chips assignments). -Configuration changes for an already started simulation require a -full stop-start cycle in order to take effect i.e.: -.Bl -column -.It nandsim stop ... -.It nandsim destroy ... -.Pp -.It << edit config file >> -.Pp -.It nandsim conf ... -.It nandsim start ... -.El -.It Ic mod -Alters simulator parameters on-the-fly. -If controller number and CS pair is not specified, the general -simulator parameters (not specific to a controller or a chip) will be modified. -Changing chip's parameters requires specifying both controller number and CS -to which the given chip is connected. -Parameters which can be altered: -.Pp -General simulator related: -.Bl -tag -width flag -.It Fl l Aq log_level -change logging level to -.Aq log_level -.El -.Pp -Chip related: -.Bl -tag -width flag -.It Fl p Aq prog_time -change prog time for specified chip to -.Aq prog_time -.It Fl e Aq erase_time -change erase time for specified chip to -.Aq erase_time -.It Fl r Aq read_time -change read time for specified chip to -.Aq read_time -.It Fl E Aq error_ratio -change error ratio for specified chip to -.Aq error_ratio . -Error ratio is a number of errors per million read/write bytes. -.El -.Pp -Additionally, flag -.Fl h -will list parameters which can be altered. -.El -.Bl -tag -width periphlist -.It Ic bb -Marks/unmarks a specified block as bad. -To mark/unmark the bad condition an a block, the following parameters -have to be supplied: controller number, CS number, and at least one -block number. -It is possible to specify multiple blocks, by separating blocks numbers -with a comma. -The following options can be used for the 'bb' command: -.Bl -tag -width flag -.It Fl U -unmark the bad previously marked block as bad. -.It Fl L -list all blocks marked as bad on a given chip. -.El -.It Ic log -Prints activity log of the specified controller to stdout; if -controller number is not specified, logs for all available -controllers are printed. -.It Ic stats -Print statistics of the selected controller, chip and page. -Statistics includes read count, write count, raw read count, raw -write count, ECC stats (succeeded corrections, failed correction). -.It Ic dump -Dumps a snaphot of a single chip (including data and bad blocks -information, wearout level) into the file. -.It Ic restore -Restores chip state from a dump-file snapshot (produced previously -with the 'dump' command). -.It Ic start -Starts a controller i.e. the simulation. -.It Ic stop -Stops an already started controller; if the controller number is not -supplied, attempts to stop all currently working controllers. -.It Ic destroy -Removes existing active chip/controller and its configuration from -memory and releases the resources. -Specifying flag -.Fl a -or -.Fl -all -causes removal of every chip and controller. -Controller must be stopped in order to be destroyed. -.It Ic error -Directly overwrites a certain number of bytes in the specified page -at a given offset with a supplied pattern (which mimics the -corruption of flash contents). -.It Ic help -Prints synopsis, -.Fl v -gives more verbose output. -.It Ic freeze -Stops simulation of given controller (simulates power-loss). -All commands issues to any chip on this controller are ignored. -.El -.Sh SEE ALSO -.Xr nand 4 , -.Xr nandsim 4 , -.Xr nandsim.conf 5 -.Sh HISTORY -The -.Nm -utility first appeared in -.Fx 10.0 . -.Sh AUTHORS -This utility was written by -.An Lukasz Wojcik . diff --git a/usr.sbin/nandsim/nandsim.c b/usr.sbin/nandsim/nandsim.c deleted file mode 100644 index 10eadcbc940d..000000000000 --- a/usr.sbin/nandsim/nandsim.c +++ /dev/null @@ -1,1399 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* - * Control application for the NAND simulator. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/errno.h> -#include <sys/ioctl.h> -#include <sys/mman.h> -#include <sys/stat.h> -#include <sys/types.h> - -#include <dev/nand/nandsim.h> -#include <dev/nand/nand_dev.h> - -#include <ctype.h> -#include <fcntl.h> -#include <getopt.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <unistd.h> -#include <stdlib.h> -#include <limits.h> -#include <sysexits.h> - -#include "nandsim_cfgparse.h" - -#define SIMDEVICE "/dev/nandsim.ioctl" - -#define error(fmt, args...) do { \ - printf("ERROR: " fmt "\n", ##args); } while (0) - -#define warn(fmt, args...) do { \ - printf("WARNING: " fmt "\n", ##args); } while (0) - -#define DEBUG -#undef DEBUG - -#ifdef DEBUG -#define debug(fmt, args...) do { \ - printf("NANDSIM_CONF:" fmt "\n", ##args); } while (0) -#else -#define debug(fmt, args...) do {} while(0) -#endif - -#define NANDSIM_RAM_LOG_SIZE 16384 - -#define MSG_NOTRUNNING "Controller#%d is not running.Please start" \ - " it first." -#define MSG_RUNNING "Controller#%d is already running!" -#define MSG_CTRLCHIPNEEDED "You have to specify ctrl_no:cs_no pair!" -#define MSG_STATUSACQCTRLCHIP "Could not acquire status for ctrl#%d chip#%d" -#define MSG_STATUSACQCTRL "Could not acquire status for ctrl#%d" -#define MSG_NOCHIP "There is no such chip configured (chip#%d "\ - "at ctrl#%d)!" - -#define MSG_NOCTRL "Controller#%d is not configured!" -#define MSG_NOTCONFIGDCTRLCHIP "Chip connected to ctrl#%d at cs#%d " \ - "is not configured." - -typedef int (commandfunc_t)(int , char **); - -static struct nandsim_command *getcommand(char *); -static int parse_devstring(char *, int *, int *); -static void printchip(struct sim_chip *, uint8_t); -static void printctrl(struct sim_ctrl *); -static int opendev(int *); -static commandfunc_t cmdstatus; -static commandfunc_t cmdconf; -static commandfunc_t cmdstart; -static commandfunc_t cmdstop; -static commandfunc_t cmdmod; -static commandfunc_t cmderror; -static commandfunc_t cmdbb; -static commandfunc_t cmdfreeze; -static commandfunc_t cmdlog; -static commandfunc_t cmdstats; -static commandfunc_t cmddump; -static commandfunc_t cmdrestore; -static commandfunc_t cmddestroy; -static commandfunc_t cmdhelp; -static int checkusage(int, int, char **); -static int is_chip_created(int, int, int *); -static int is_ctrl_created(int, int *); -static int is_ctrl_running(int, int *); -static int assert_chip_connected(int , int); -static int printstats(int, int, uint32_t, int); - -struct nandsim_command { - const char *cmd_name; /* Command name */ - commandfunc_t *commandfunc; /* Ptr to command function */ - uint8_t req_argc; /* Mandatory arguments count */ - const char *usagestring; /* Usage string */ -}; - -static struct nandsim_command commands[] = { - {"status", cmdstatus, 1, - "status <ctl_no|--all|-a> [-v]\n" }, - {"conf", cmdconf, 1, - "conf <filename>\n" }, - {"start", cmdstart, 1, - "start <ctrl_no>\n" }, - {"mod", cmdmod, 2, - "mod [-l <loglevel>] | <ctl_no:cs_no> [-p <prog_time>]\n" - "\t[-e <erase_time>] [-r <read_time>]\n" - "\t[-E <error_ratio>] | [-h]\n" }, - {"stop", cmdstop, 1, - "stop <ctrl_no>\n" }, - {"error", cmderror, 5, - "error <ctrl_no:cs_no> <page_num> <column> <length> <pattern>\n" }, - {"bb", cmdbb, 2, - "bb <ctl_no:cs_no> [blk_num1,blk_num2,..] [-U] [-L]\n" }, - {"freeze", cmdfreeze, 1, - "freeze [ctrl_no]\n" }, - {"log", cmdlog, 1, - "log <ctrl_no|--all|-a>\n" }, - {"stats", cmdstats, 2, - "stats <ctrl_no:cs_no> <pagenumber>\n" }, - {"dump", cmddump, 2, - "dump <ctrl_no:cs_no> <filename>\n" }, - {"restore", cmdrestore, 2, - "restore <ctrl_no:chip_no> <filename>\n" }, - {"destroy", cmddestroy, 1, - "destroy <ctrl_no[:cs_no]|--all|-a>\n" }, - {"help", cmdhelp, 0, - "help [-v]" }, - {NULL, NULL, 0, NULL}, -}; - - -/* Parse command name, and start appropriate function */ -static struct nandsim_command* -getcommand(char *arg) -{ - struct nandsim_command *opts; - - for (opts = commands; (opts != NULL) && - (opts->cmd_name != NULL); opts++) { - if (strcmp(opts->cmd_name, arg) == 0) - return (opts); - } - return (NULL); -} - -/* - * Parse given string in format <ctrl_no>:<cs_no>, if possible -- set - * ctrl and/or cs, and return 0 (success) or 1 (in case of error). - * - * ctrl == 0xff && chip == 0xff : '--all' flag specified - * ctrl != 0xff && chip != 0xff : both ctrl & chip were specified - * ctrl != 0xff && chip == 0xff : only ctrl was specified - */ -static int -parse_devstring(char *str, int *ctrl, int *cs) -{ - char *tmpstr; - unsigned int num = 0; - - /* Ignore white spaces at the beginning */ - while (isspace(*str) && (*str != '\0')) - str++; - - *ctrl = 0xff; - *cs = 0xff; - if (strcmp(str, "--all") == 0 || - strcmp(str, "-a") == 0) { - /* If --all or -a is specified, ctl==chip==0xff */ - debug("CTRL=%d CHIP=%d\n", *ctrl, *cs); - return (0); - } - /* Separate token and try to convert it to int */ - tmpstr = (char *)strtok(str, ":"); - if ((tmpstr != NULL) && (*tmpstr != '\0')) { - if (convert_arguint(tmpstr, &num) != 0) - return (1); - - if (num > MAX_SIM_DEV - 1) { - error("Invalid ctrl_no supplied: %s. Valid ctrl_no " - "value must lie between 0 and 3!", tmpstr); - return (1); - } - - *ctrl = num; - tmpstr = (char *)strtok(NULL, ":"); - - if ((tmpstr != NULL) && (*tmpstr != '\0')) { - if (convert_arguint(tmpstr, &num) != 0) - return (1); - - /* Check if chip_no is valid */ - if (num > MAX_CTRL_CS - 1) { - error("Invalid chip_no supplied: %s. Valid " - "chip_no value must lie between 0 and 3!", - tmpstr); - return (1); - } - *cs = num; - } - } else - /* Empty devstring supplied */ - return (1); - - debug("CTRL=%d CHIP=%d\n", *ctrl, *cs); - return (0); -} - -static int -opendev(int *fd) -{ - - *fd = open(SIMDEVICE, O_RDWR); - if (*fd == -1) { - error("Could not open simulator device file (%s)!", - SIMDEVICE); - return (EX_OSFILE); - } - return (EX_OK); -} - -static int -opencdev(int *cdevd, int ctrl, int chip) -{ - char fname[255]; - - sprintf(fname, "/dev/nandsim%d.%d", ctrl, chip); - *cdevd = open(fname, O_RDWR); - if (*cdevd == -1) - return (EX_NOINPUT); - - return (EX_OK); -} - -/* - * Check if given arguments count match requirements. If no, or - * --help (-h) flag is specified -- return 1 (print usage) - */ -static int -checkusage(int gargc, int argsreqd, char **gargv) -{ - - if (gargc < argsreqd + 2 || (gargc >= (argsreqd + 2) && - (strcmp(gargv[1], "--help") == 0 || - strcmp(gargv[1], "-h") == 0))) - return (1); - - return (0); -} - -static int -cmdstatus(int gargc, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, idx, idx2, start, stop; - uint8_t verbose = 0; - struct sim_ctrl ctrlconf; - struct sim_chip chipconf; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) { - return (EX_USAGE); - } else if (ctl == 0xff) { - /* Every controller */ - start = 0; - stop = MAX_SIM_DEV-1; - } else { - /* Specified controller only */ - start = ctl; - stop = ctl; - } - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - for (idx = 0; idx < gargc; idx ++) - if (strcmp(gargv[idx], "-v") == 0 || - strcmp(gargv[idx], "--verbose") == 0) - verbose = 1; - - for (idx = start; idx <= stop; idx++) { - ctrlconf.num = idx; - err = ioctl(fd, NANDSIM_STATUS_CTRL, &ctrlconf); - if (err) { - err = EX_SOFTWARE; - error(MSG_STATUSACQCTRL, idx); - continue; - } - - printctrl(&ctrlconf); - - for (idx2 = 0; idx2 < MAX_CTRL_CS; idx2++) { - chipconf.num = idx2; - chipconf.ctrl_num = idx; - - err = ioctl(fd, NANDSIM_STATUS_CHIP, &chipconf); - if (err) { - err = EX_SOFTWARE; - error(MSG_STATUSACQCTRL, idx); - continue; - } - - printchip(&chipconf, verbose); - } - } - close(fd); - return (err); -} - -static int -cmdconf(int gargc __unused, char **gargv) -{ - int err; - - err = parse_config(gargv[2], SIMDEVICE); - if (err) - return (EX_DATAERR); - - return (EX_OK); -} - -static int -cmdstart(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, running, state; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - err = is_ctrl_created(ctl, &state); - if (err) { - return (EX_SOFTWARE); - } else if (state == 0) { - error(MSG_NOCTRL, ctl); - return (EX_SOFTWARE); - } - - err = is_ctrl_running(ctl, &running); - if (err) - return (EX_SOFTWARE); - - if (running) { - warn(MSG_RUNNING, ctl); - } else { - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_START_CTRL, &ctl); - close(fd); - if (err) { - error("Cannot start controller#%d", ctl); - err = EX_SOFTWARE; - } - } - return (err); -} - -static int -cmdstop(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, running; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - err = is_ctrl_running(ctl, &running); - if (err) - return (EX_SOFTWARE); - - if (!running) { - error(MSG_NOTRUNNING, ctl); - } else { - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STOP_CTRL, &ctl); - close(fd); - if (err) { - error("Cannot stop controller#%d", ctl); - err = EX_SOFTWARE; - } - } - - return (err); -} - -static int -cmdmod(int gargc __unused, char **gargv) -{ - int chip, ctl, err = 0, fd = -1, i; - struct sim_mod mods; - - if (gargc >= 4) { - if (strcmp(gargv[2], "--loglevel") == 0 || strcmp(gargv[2], - "-l") == 0) { - /* Set loglevel (ctrl:chip pair independent) */ - mods.field = SIM_MOD_LOG_LEVEL; - - if (convert_arguint(gargv[3], &mods.new_value) != 0) - return (EX_SOFTWARE); - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_MODIFY, &mods); - if (err) { - error("simulator parameter %s could not be " - "modified !", gargv[3]); - close(fd); - return (EX_SOFTWARE); - } - - debug("request : loglevel = %d\n", mods.new_value); - close(fd); - return (EX_OK); - } - } - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - else if (chip == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - /* Find out which flags were passed */ - for (i = 3; i < gargc; i++) { - - if (convert_arguint(gargv[i + 1], &mods.new_value) != 0) - continue; - - if (strcmp(gargv[i], "--prog-time") == 0 || - strcmp(gargv[i], "-p") == 0) { - - mods.field = SIM_MOD_PROG_TIME; - debug("request : progtime = %d\n", mods.new_value); - - } else if (strcmp(gargv[i], "--erase-time") == 0 || - strcmp(gargv[i], "-e") == 0) { - - mods.field = SIM_MOD_ERASE_TIME; - debug("request : eraseime = %d\n", mods.new_value); - - } else if (strcmp(gargv[i], "--read-time") == 0 || - strcmp(gargv[i], "-r") == 0) { - - mods.field = SIM_MOD_READ_TIME; - debug("request : read_time = %d\n", mods.new_value); - - } else if (strcmp(gargv[i], "--error-ratio") == 0 || - strcmp(gargv[i], "-E") == 0) { - - mods.field = SIM_MOD_ERROR_RATIO; - debug("request : error_ratio = %d\n", mods.new_value); - - } else { - /* Flag not recognized, or nothing specified. */ - error("Unrecognized flag:%s\n", gargv[i]); - if (fd >= 0) - close(fd); - return (EX_USAGE); - } - - mods.chip_num = chip; - mods.ctrl_num = ctl; - - /* Call appropriate ioctl */ - err = ioctl(fd, NANDSIM_MODIFY, &mods); - if (err) { - error("simulator parameter %s could not be modified! ", - gargv[i]); - continue; - } - i++; - } - close(fd); - return (EX_OK); -} - -static int -cmderror(int gargc __unused, char **gargv) -{ - uint32_t page, column, len, pattern; - int chip = 0, ctl = 0, err = 0, fd; - struct sim_error sim_err; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - if (chip == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (convert_arguint(gargv[3], &page) || - convert_arguint(gargv[4], &column) || - convert_arguint(gargv[5], &len) || - convert_arguint(gargv[6], &pattern)) - return (EX_SOFTWARE); - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - sim_err.page_num = page; - sim_err.column = column; - sim_err.len = len; - sim_err.pattern = pattern; - sim_err.ctrl_num = ctl; - sim_err.chip_num = chip; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_INJECT_ERROR, &sim_err); - - close(fd); - if (err) { - error("Could not inject error !"); - return (EX_SOFTWARE); - } - return (EX_OK); -} - -static int -cmdbb(int gargc, char **gargv) -{ - struct sim_block_state bs; - struct chip_param_io cparams; - uint32_t blkidx; - int c, cdevd, chip = 0, ctl = 0, err = 0, fd, idx; - uint8_t flagL = 0, flagU = 0; - int *badblocks = NULL; - - /* Check for --list/-L or --unmark/-U flags */ - for (idx = 3; idx < gargc; idx++) { - if (strcmp(gargv[idx], "--list") == 0 || - strcmp(gargv[idx], "-L") == 0) - flagL = idx; - if (strcmp(gargv[idx], "--unmark") == 0 || - strcmp(gargv[idx], "-U") == 0) - flagU = idx; - } - - if (flagL == 2 || flagU == 2 || flagU == 3) - return (EX_USAGE); - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) { - return (EX_USAGE); - } - if (chip == 0xff || ctl == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - bs.ctrl_num = ctl; - bs.chip_num = chip; - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opencdev(&cdevd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = ioctl(cdevd, NAND_IO_GET_CHIP_PARAM, &cparams); - if (err) - return (EX_SOFTWARE); - - close(cdevd); - - bs.ctrl_num = ctl; - bs.chip_num = chip; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - if (flagL != 3) { - /* - * Flag -L was specified either after blocklist or was not - * specified at all. - */ - c = parse_intarray(gargv[3], &badblocks); - - for (idx = 0; idx < c; idx++) { - bs.block_num = badblocks[idx]; - /* Do not change wearout */ - bs.wearout = -1; - bs.state = (flagU == 0) ? NANDSIM_BAD_BLOCK : - NANDSIM_GOOD_BLOCK; - - err = ioctl(fd, NANDSIM_SET_BLOCK_STATE, &bs); - if (err) { - error("Could not set bad block(%d) for " - "controller (%d)!", - badblocks[idx], ctl); - err = EX_SOFTWARE; - break; - } - } - } - if (flagL != 0) { - /* If flag -L was specified (anywhere) */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - bs.block_num = blkidx; - /* Do not change the wearout */ - bs.wearout = -1; - err = ioctl(fd, NANDSIM_GET_BLOCK_STATE, &bs); - if (err) { - error("Could not acquire block state"); - err = EX_SOFTWARE; - continue; - } - printf("Block#%d: wear count: %d %s\n", blkidx, - bs.wearout, - (bs.state == NANDSIM_BAD_BLOCK) ? "BAD":"GOOD"); - } - } - close(fd); - return (err); -} - -static int -cmdfreeze(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, i, start = 0, state, stop = 0; - struct sim_ctrl_chip ctrlchip; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - if (ctl == 0xff) { - error("You have to specify at least controller number"); - return (EX_USAGE); - } - - if (ctl != 0xff && chip == 0xff) { - start = 0; - stop = MAX_CTRL_CS - 1; - } else { - start = chip; - stop = chip; - } - - ctrlchip.ctrl_num = ctl; - - err = is_ctrl_running(ctl, &state); - if (err) - return (EX_SOFTWARE); - if (state == 0) { - error(MSG_NOTRUNNING, ctl); - return (EX_SOFTWARE); - } - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - for (i = start; i <= stop; i++) { - err = is_chip_created(ctl, i, &state); - if (err) - return (EX_SOFTWARE); - else if (state == 0) { - continue; - } - - ctrlchip.chip_num = i; - err = ioctl(fd, NANDSIM_FREEZE, &ctrlchip); - if (err) { - error("Could not freeze ctrl#%d chip#%d", ctl, i); - close(fd); - return (EX_SOFTWARE); - } - } - close(fd); - return (EX_OK); -} - -static int -cmdlog(int gargc __unused, char **gargv) -{ - struct sim_log log; - int chip = 0, ctl = 0, err = 0, fd, idx, start = 0, stop = 0; - char *logbuf; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - logbuf = (char *)malloc(sizeof(char) * NANDSIM_RAM_LOG_SIZE); - if (logbuf == NULL) { - error("Not enough memory to create log buffer"); - return (EX_SOFTWARE); - } - - memset(logbuf, 0, NANDSIM_RAM_LOG_SIZE); - log.log = logbuf; - log.len = NANDSIM_RAM_LOG_SIZE; - - if (ctl == 0xff) { - start = 0; - stop = MAX_SIM_DEV-1; - } else { - start = ctl; - stop = ctl; - } - - if (opendev(&fd) != EX_OK) { - free(logbuf); - return (EX_OSFILE); - } - - /* Print logs for selected controller(s) */ - for (idx = start; idx <= stop; idx++) { - log.ctrl_num = idx; - - err = ioctl(fd, NANDSIM_PRINT_LOG, &log); - if (err) { - error("Could not get log for controller %d!", idx); - continue; - } - - printf("Logs for controller#%d:\n%s\n", idx, logbuf); - } - - free(logbuf); - close(fd); - return (EX_OK); -} - -static int -cmdstats(int gargc __unused, char **gargv) -{ - int cdevd, chip = 0, ctl = 0, err = 0; - uint32_t pageno = 0; - - err = parse_devstring(gargv[2], &ctl, &chip); - - if (err) - return (EX_USAGE); - - if (chip == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (convert_arguint(gargv[3], &pageno) != 0) - return (EX_USAGE); - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opencdev(&cdevd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = printstats(ctl, chip, pageno, cdevd); - if (err) { - close(cdevd); - return (EX_SOFTWARE); - } - close(cdevd); - return (EX_OK); -} - -static int -cmddump(int gargc __unused, char **gargv) -{ - struct sim_dump dump; - struct sim_block_state bs; - struct chip_param_io cparams; - int chip = 0, ctl = 0, err = EX_OK, fd, dumpfd; - uint32_t blkidx, bwritten = 0, totalwritten = 0; - void *buf; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - - if (chip == 0xff || ctl == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - if (opencdev(&fd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NAND_IO_GET_CHIP_PARAM, &cparams); - if (err) { - error("Cannot get parameters for chip %d:%d", ctl, chip); - close(fd); - return (EX_SOFTWARE); - } - close(fd); - - dump.ctrl_num = ctl; - dump.chip_num = chip; - - dump.len = cparams.pages_per_block * (cparams.page_size + - cparams.oob_size); - - buf = malloc(dump.len); - if (buf == NULL) { - error("Could not allocate memory!"); - return (EX_SOFTWARE); - } - dump.data = buf; - - errno = 0; - dumpfd = open(gargv[3], O_WRONLY | O_CREAT, 0666); - if (dumpfd == -1) { - error("Cannot create dump file."); - free(buf); - return (EX_SOFTWARE); - } - - if (opendev(&fd)) { - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - - bs.ctrl_num = ctl; - bs.chip_num = chip; - - /* First uint32_t in file shall contain block count */ - if (write(dumpfd, &cparams, sizeof(cparams)) < (int)sizeof(cparams)) { - error("Error writing to dumpfile!"); - close(fd); - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - - /* - * First loop acquires blocks states and writes them to - * the dump file. - */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - bs.block_num = blkidx; - err = ioctl(fd, NANDSIM_GET_BLOCK_STATE, &bs); - if (err) { - error("Could not get bad block(%d) for " - "controller (%d)!", blkidx, ctl); - close(fd); - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - - bwritten = write(dumpfd, &bs, sizeof(bs)); - if (bwritten != sizeof(bs)) { - error("Error writing to dumpfile"); - close(fd); - close(dumpfd); - free(buf); - return (EX_SOFTWARE); - } - } - - /* Second loop dumps the data */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - debug("Block#%d...", blkidx); - dump.block_num = blkidx; - - err = ioctl(fd, NANDSIM_DUMP, &dump); - if (err) { - error("Could not dump ctrl#%d chip#%d " - "block#%d", ctl, chip, blkidx); - err = EX_SOFTWARE; - break; - } - - bwritten = write(dumpfd, dump.data, dump.len); - if (bwritten != dump.len) { - error("Error writing to dumpfile"); - err = EX_SOFTWARE; - break; - } - debug("OK!\n"); - totalwritten += bwritten; - } - printf("%d out of %d B written.\n", totalwritten, dump.len * blkidx); - - close(fd); - close(dumpfd); - free(buf); - return (err); -} - -static int -cmdrestore(int gargc __unused, char **gargv) -{ - struct sim_dump dump; - struct sim_block_state bs; - struct stat filestat; - int chip = 0, ctl = 0, err = 0, fd, dumpfd = -1; - uint32_t blkidx, blksz, fsize = 0, expfilesz; - void *buf; - struct chip_param_io cparams, dumpcparams; - - err = parse_devstring(gargv[2], &ctl, &chip); - if (err) - return (EX_USAGE); - else if (ctl == 0xff) { - error(MSG_CTRLCHIPNEEDED); - return (EX_USAGE); - } - - if (!assert_chip_connected(ctl, chip)) - return (EX_SOFTWARE); - - /* Get chip geometry */ - if (opencdev(&fd, ctl, chip) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NAND_IO_GET_CHIP_PARAM, &cparams); - if (err) { - error("Cannot get parameters for chip %d:%d", ctl, chip); - close(fd); - return (err); - } - close(fd); - - /* Obtain dump file size */ - errno = 0; - if (stat(gargv[3], &filestat) != 0) { - error("Could not acquire file size! : %s", - strerror(errno)); - return (EX_IOERR); - } - - fsize = filestat.st_size; - blksz = cparams.pages_per_block * (cparams.page_size + - cparams.oob_size); - - /* Expected dump file size for chip */ - expfilesz = cparams.blocks * (blksz + sizeof(bs)) + sizeof(cparams); - - if (fsize != expfilesz) { - error("File size does not match chip geometry (file size: %d" - ", dump size: %d)", fsize, expfilesz); - return (EX_SOFTWARE); - } - - dumpfd = open(gargv[3], O_RDONLY); - if (dumpfd == -1) { - error("Could not open dump file!"); - return (EX_IOERR); - } - - /* Read chip params saved in dumpfile */ - read(dumpfd, &dumpcparams, sizeof(dumpcparams)); - - /* XXX */ - if (bcmp(&dumpcparams, &cparams, sizeof(cparams)) != 0) { - error("Supplied dump is created for a chip with different " - "chip configuration!"); - close(dumpfd); - return (EX_SOFTWARE); - } - - if (opendev(&fd) != EX_OK) { - close(dumpfd); - return (EX_OSFILE); - } - - buf = malloc(blksz); - if (buf == NULL) { - error("Could not allocate memory for block buffer"); - close(dumpfd); - close(fd); - return (EX_SOFTWARE); - } - - dump.ctrl_num = ctl; - dump.chip_num = chip; - dump.data = buf; - /* Restore block states and wearouts */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - dump.block_num = blkidx; - if (read(dumpfd, &bs, sizeof(bs)) != sizeof(bs)) { - error("Error reading dumpfile"); - close(dumpfd); - close(fd); - free(buf); - return (EX_SOFTWARE); - } - bs.ctrl_num = ctl; - bs.chip_num = chip; - debug("BLKIDX=%d BLOCKS=%d CTRL=%d CHIP=%d STATE=%d\n" - "WEAROUT=%d BS.CTRL_NUM=%d BS.CHIP_NUM=%d\n", - blkidx, cparams.blocks, dump.ctrl_num, dump.chip_num, - bs.state, bs.wearout, bs.ctrl_num, bs.chip_num); - - err = ioctl(fd, NANDSIM_SET_BLOCK_STATE, &bs); - if (err) { - error("Could not set bad block(%d) for " - "controller: %d, chip: %d!", blkidx, ctl, chip); - close(dumpfd); - close(fd); - free(buf); - return (EX_SOFTWARE); - } - } - /* Restore data */ - for (blkidx = 0; blkidx < cparams.blocks; blkidx++) { - errno = 0; - dump.len = read(dumpfd, buf, blksz); - if (errno) { - error("Failed to read block#%d from dumpfile.", blkidx); - err = EX_SOFTWARE; - break; - } - dump.block_num = blkidx; - err = ioctl(fd, NANDSIM_RESTORE, &dump); - if (err) { - error("Could not restore block#%d of ctrl#%d chip#%d" - ": %s", blkidx, ctl, chip, strerror(errno)); - err = EX_SOFTWARE; - break; - } - } - - free(buf); - close(dumpfd); - close(fd); - return (err); - -} - -static int -cmddestroy(int gargc __unused, char **gargv) -{ - int chip = 0, ctl = 0, err = 0, fd, idx, idx2, state; - int chipstart, chipstop, ctrlstart, ctrlstop; - struct sim_chip_destroy chip_destroy; - - err = parse_devstring(gargv[2], &ctl, &chip); - - if (err) - return (EX_USAGE); - - if (ctl == 0xff) { - /* Every chip at every controller */ - ctrlstart = chipstart = 0; - ctrlstop = MAX_SIM_DEV - 1; - chipstop = MAX_CTRL_CS - 1; - } else { - ctrlstart = ctrlstop = ctl; - if (chip == 0xff) { - /* Every chip at selected controller */ - chipstart = 0; - chipstop = MAX_CTRL_CS - 1; - } else - /* Selected chip at selected controller */ - chipstart = chipstop = chip; - } - debug("CTRLSTART=%d CTRLSTOP=%d CHIPSTART=%d CHIPSTOP=%d\n", - ctrlstart, ctrlstop, chipstart, chipstop); - for (idx = ctrlstart; idx <= ctrlstop; idx++) { - err = is_ctrl_created(idx, &state); - if (err) { - error("Could not acquire ctrl#%d state. Cannot " - "destroy controller.", idx); - return (EX_SOFTWARE); - } - if (state == 0) { - continue; - } - err = is_ctrl_running(idx, &state); - if (err) { - error(MSG_STATUSACQCTRL, idx); - return (EX_SOFTWARE); - } - if (state != 0) { - error(MSG_RUNNING, ctl); - return (EX_SOFTWARE); - } - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - for (idx2 = chipstart; idx2 <= chipstop; idx2++) { - err = is_chip_created(idx, idx2, &state); - if (err) { - error(MSG_STATUSACQCTRLCHIP, idx2, idx); - continue; - } - if (state == 0) - /* There is no such chip running */ - continue; - chip_destroy.ctrl_num = idx; - chip_destroy.chip_num = idx2; - ioctl(fd, NANDSIM_DESTROY_CHIP, - &chip_destroy); - } - /* If chip isn't explicitly specified -- destroy ctrl */ - if (chip == 0xff) { - err = ioctl(fd, NANDSIM_DESTROY_CTRL, &idx); - if (err) { - error("Could not destroy ctrl#%d", idx); - continue; - } - } - close(fd); - } - return (err); -} - -int -main(int argc, char **argv) -{ - struct nandsim_command *cmdopts; - int retcode = 0; - - if (argc < 2) { - cmdhelp(argc, argv); - retcode = EX_USAGE; - } else { - cmdopts = getcommand(argv[1]); - if (cmdopts != NULL && cmdopts->commandfunc != NULL) { - if (checkusage(argc, cmdopts->req_argc, argv) == 1) { - /* Print command specific usage */ - printf("nandsim %s", cmdopts->usagestring); - return (EX_USAGE); - } - retcode = cmdopts->commandfunc(argc, argv); - - if (retcode == EX_USAGE) { - /* Print command-specific usage */ - printf("nandsim %s", cmdopts->usagestring); - } else if (retcode == EX_OSFILE) { - error("Could not open device file"); - } - - } else { - error("Unknown command!"); - retcode = EX_USAGE; - } - } - return (retcode); -} - -static int -cmdhelp(int gargc __unused, char **gargv __unused) -{ - struct nandsim_command *opts; - - printf("usage: nandsim <command> [command params] [params]\n\n"); - - for (opts = commands; (opts != NULL) && - (opts->cmd_name != NULL); opts++) - printf("nandsim %s", opts->usagestring); - - printf("\n"); - return (EX_OK); -} - -static void -printchip(struct sim_chip *chip, uint8_t verbose) -{ - - if (chip->created == 0) - return; - if (verbose > 0) { - printf("\n[Chip info]\n"); - printf("num= %d\nctrl_num=%d\ndevice_id=%02x" - "\tmanufacturer_id=%02x\ndevice_model=%s\nmanufacturer=" - "%s\ncol_addr_cycles=%d\nrow_addr_cycles=%d" - "\npage_size=%d\noob_size=%d\npages_per_block=%d\n" - "blocks_per_lun=%d\nluns=%d\n\nprog_time=%d\n" - "erase_time=%d\nread_time=%d\n" - "error_ratio=%d\nwear_level=%d\nwrite_protect=%c\n" - "chip_width=%db\n", chip->num, chip->ctrl_num, - chip->device_id, chip->manufact_id,chip->device_model, - chip->manufacturer, chip->col_addr_cycles, - chip->row_addr_cycles, chip->page_size, - chip->oob_size, chip->pgs_per_blk, chip->blks_per_lun, - chip->luns,chip->prog_time, chip->erase_time, - chip->read_time, chip->error_ratio, chip->wear_level, - (chip->is_wp == 0) ? 'N':'Y', chip->width); - } else { - printf("[Chip info]\n"); - printf("\tnum=%d\n\tdevice_model=%s\n\tmanufacturer=%s\n" - "\tpage_size=%d\n\twrite_protect=%s\n", - chip->num, chip->device_model, chip->manufacturer, - chip->page_size, (chip->is_wp == 0) ? "NO":"YES"); - } -} - -static void -printctrl(struct sim_ctrl *ctrl) -{ - int i; - - if (ctrl->created == 0) { - printf(MSG_NOCTRL "\n", ctrl->num); - return; - } - printf("\n[Controller info]\n"); - printf("\trunning: %s\n", ctrl->running ? "yes" : "no"); - printf("\tnum cs: %d\n", ctrl->num_cs); - printf("\tecc: %d\n", ctrl->ecc); - printf("\tlog_filename: %s\n", ctrl->filename); - printf("\tecc_layout:"); - for (i = 0; i < MAX_ECC_BYTES; i++) { - if (ctrl->ecc_layout[i] == 0xffff) - break; - else - printf("%c%d", i%16 ? ' ' : '\n', - ctrl->ecc_layout[i]); - } - printf("\n"); -} - -static int -is_ctrl_running(int ctrl_no, int *running) -{ - struct sim_ctrl ctrl; - int err, fd; - - ctrl.num = ctrl_no; - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STATUS_CTRL, &ctrl); - if (err) { - error(MSG_STATUSACQCTRL, ctrl_no); - close(fd); - return (err); - } - *running = ctrl.running; - close(fd); - return (0); -} - -static int -is_ctrl_created(int ctrl_no, int *created) -{ - struct sim_ctrl ctrl; - int err, fd; - - ctrl.num = ctrl_no; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STATUS_CTRL, &ctrl); - if (err) { - error("Could not acquire conf for ctrl#%d", ctrl_no); - close(fd); - return (err); - } - *created = ctrl.created; - close(fd); - return (0); -} - -static int -is_chip_created(int ctrl_no, int chip_no, int *created) -{ - struct sim_chip chip; - int err, fd; - - chip.ctrl_num = ctrl_no; - chip.num = chip_no; - - if (opendev(&fd) != EX_OK) - return (EX_OSFILE); - - err = ioctl(fd, NANDSIM_STATUS_CHIP, &chip); - if (err) { - error("Could not acquire conf for chip#%d", chip_no); - close(fd); - return (err); - } - *created = chip.created; - close(fd); - return (0); -} - -static int -assert_chip_connected(int ctrl_no, int chip_no) -{ - int created, running; - - if (is_ctrl_created(ctrl_no, &created)) - return (0); - - if (!created) { - error(MSG_NOCTRL, ctrl_no); - return (0); - } - - if (is_chip_created(ctrl_no, chip_no, &created)) - return (0); - - if (!created) { - error(MSG_NOTCONFIGDCTRLCHIP, ctrl_no, chip_no); - return (0); - } - - if (is_ctrl_running(ctrl_no, &running)) - return (0); - - if (!running) { - error(MSG_NOTRUNNING, ctrl_no); - return (0); - } - - return (1); -} - -static int -printstats(int ctrlno, int chipno, uint32_t pageno, int cdevd) -{ - struct page_stat_io pstats; - struct block_stat_io bstats; - struct chip_param_io cparams; - uint32_t blkidx; - int err; - - /* Gather information about chip */ - err = ioctl(cdevd, NAND_IO_GET_CHIP_PARAM, &cparams); - - if (err) { - error("Could not acquire chip info for chip attached to cs#" - "%d, ctrl#%d", chipno, ctrlno); - return (EX_SOFTWARE); - } - - blkidx = (pageno / cparams.pages_per_block); - bstats.block_num = blkidx; - - err = ioctl(cdevd, NAND_IO_BLOCK_STAT, &bstats); - if (err) { - error("Could not acquire block#%d statistics!", blkidx); - return (ENXIO); - } - - printf("Block #%d erased: %d\n", blkidx, bstats.block_erased); - pstats.page_num = pageno; - - err = ioctl(cdevd, NAND_IO_PAGE_STAT, &pstats); - if (err) { - error("Could not acquire page statistics!"); - return (ENXIO); - } - - debug("BLOCKIDX = %d PAGENO (REL. TO BLK) = %d\n", blkidx, - pstats.page_num); - - printf("Page#%d : reads:%d writes:%d \n\traw reads:%d raw writes:%d " - "\n\tecc_succeeded:%d ecc_corrected:%d ecc_failed:%d\n", - pstats.page_num, pstats.page_read, pstats.page_written, - pstats.page_raw_read, pstats.page_raw_written, - pstats.ecc_succeded, pstats.ecc_corrected, pstats.ecc_failed); - return (0); -} diff --git a/usr.sbin/nandsim/nandsim_cfgparse.c b/usr.sbin/nandsim/nandsim_cfgparse.c deleted file mode 100644 index 4a310fb58a0f..000000000000 --- a/usr.sbin/nandsim/nandsim_cfgparse.c +++ /dev/null @@ -1,961 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <sys/errno.h> -#include <sys/ioctl.h> -#include <sys/types.h> - -#include <dev/nand/nandsim.h> - -#include <ctype.h> -#include <fcntl.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <sysexits.h> -#include <unistd.h> - -#include "nandsim_cfgparse.h" - -#define warn(fmt, args...) do { \ - printf("WARNING: " fmt "\n", ##args); } while (0) - -#define error(fmt, args...) do { \ - printf("ERROR: " fmt "\n", ##args); } while (0) - -#define MSG_MANDATORYKEYMISSING "mandatory key \"%s\" value belonging to " \ - "section \"%s\" is missing!\n" - -#define DEBUG -#undef DEBUG - -#ifdef DEBUG -#define debug(fmt, args...) do { \ - printf("NANDSIM_CONF:" fmt "\n", ##args); } while (0) -#else -#define debug(fmt, args...) do {} while(0) -#endif - -#define STRBUFSIZ 2000 - -/* Macros extracts type and type size */ -#define TYPE(x) ((x) & 0xf8) -#define SIZE(x) (((x) & 0x07)) - -/* Erase/Prog/Read time max and min values */ -#define DELAYTIME_MIN 10000 -#define DELAYTIME_MAX 10000000 - -/* Structure holding configuration for controller. */ -static struct sim_ctrl ctrl_conf; -/* Structure holding configuration for chip. */ -static struct sim_chip chip_conf; - -static struct nandsim_key nandsim_ctrl_keys[] = { - {"num_cs", 1, VALUE_UINT | SIZE_8, (void *)&ctrl_conf.num_cs, 0}, - {"ctrl_num", 1, VALUE_UINT | SIZE_8, (void *)&ctrl_conf.num, 0}, - - {"ecc_layout", 1, VALUE_UINTARRAY | SIZE_16, - (void *)&ctrl_conf.ecc_layout, MAX_ECC_BYTES}, - - {"filename", 0, VALUE_STRING, - (void *)&ctrl_conf.filename, FILENAME_SIZE}, - - {"ecc", 0, VALUE_BOOL, (void *)&ctrl_conf.ecc, 0}, - {NULL, 0, 0, NULL, 0}, -}; - -static struct nandsim_key nandsim_chip_keys[] = { - {"chip_cs", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.num, 0}, - {"chip_ctrl", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.ctrl_num, - 0}, - {"device_id", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.device_id, - 0}, - {"manufacturer_id", 1, VALUE_UINT | SIZE_8, - (void *)&chip_conf.manufact_id, 0}, - {"model", 0, VALUE_STRING, (void *)&chip_conf.device_model, - DEV_MODEL_STR_SIZE}, - {"manufacturer", 0, VALUE_STRING, (void *)&chip_conf.manufacturer, - MAN_STR_SIZE}, - {"page_size", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.page_size, - 0}, - {"oob_size", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.oob_size, - 0}, - {"pages_per_block", 1, VALUE_UINT | SIZE_32, - (void *)&chip_conf.pgs_per_blk, 0}, - {"blocks_per_lun", 1, VALUE_UINT | SIZE_32, - (void *)&chip_conf.blks_per_lun, 0}, - {"luns", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.luns, 0}, - {"column_addr_cycle", 1,VALUE_UINT | SIZE_8, - (void *)&chip_conf.col_addr_cycles, 0}, - {"row_addr_cycle", 1, VALUE_UINT | SIZE_8, - (void *)&chip_conf.row_addr_cycles, 0}, - {"program_time", 0, VALUE_UINT | SIZE_32, - (void *)&chip_conf.prog_time, 0}, - {"erase_time", 0, VALUE_UINT | SIZE_32, - (void *)&chip_conf.erase_time, 0}, - {"read_time", 0, VALUE_UINT | SIZE_32, - (void *)&chip_conf.read_time, 0}, - {"width", 1, VALUE_UINT | SIZE_8, (void *)&chip_conf.width, 0}, - {"wear_out", 1, VALUE_UINT | SIZE_32, (void *)&chip_conf.wear_level, - 0}, - {"bad_block_map", 0, VALUE_UINTARRAY | SIZE_32, - (void *)&chip_conf.bad_block_map, MAX_BAD_BLOCKS}, - {NULL, 0, 0, NULL, 0}, -}; - -static struct nandsim_section sections[] = { - {"ctrl", (struct nandsim_key *)&nandsim_ctrl_keys}, - {"chip", (struct nandsim_key *)&nandsim_chip_keys}, - {NULL, NULL}, -}; - -static uint8_t logoutputtoint(char *, int *); -static uint8_t validate_chips(struct sim_chip *, int, struct sim_ctrl *, int); -static uint8_t validate_ctrls(struct sim_ctrl *, int); -static int configure_sim(const char *, struct rcfile *); -static int create_ctrls(struct rcfile *, struct sim_ctrl **, int *); -static int create_chips(struct rcfile *, struct sim_chip **, int *); -static void destroy_ctrls(struct sim_ctrl *); -static void destroy_chips(struct sim_chip *); -static int validate_section_config(struct rcfile *, const char *, int); - -int -convert_argint(char *arg, int *value) -{ - - if (arg == NULL || value == NULL) - return (EINVAL); - - errno = 0; - *value = (int)strtol(arg, NULL, 0); - if (*value == 0 && errno != 0) { - error("Cannot convert to number argument \'%s\'", arg); - return (EINVAL); - } - return (0); -} - -int -convert_arguint(char *arg, unsigned int *value) -{ - - if (arg == NULL || value == NULL) - return (EINVAL); - - errno = 0; - *value = (unsigned int)strtol(arg, NULL, 0); - if (*value == 0 && errno != 0) { - error("Cannot convert to number argument \'%s\'", arg); - return (EINVAL); - } - return (0); -} - -/* Parse given ',' separated list of bytes into buffer. */ -int -parse_intarray(char *array, int **buffer) -{ - char *tmp, *tmpstr, *origstr; - unsigned int currbufp = 0, i; - unsigned int count = 0, from = 0, to = 0; - - /* Remove square braces */ - if (array[0] == '[') - array ++; - if (array[strlen(array)-1] == ']') - array[strlen(array)-1] = ','; - - from = strlen(array); - origstr = (char *)malloc(sizeof(char) * from); - strcpy(origstr, array); - - tmpstr = (char *)strtok(array, ","); - /* First loop checks for how big int array we need to allocate */ - while (tmpstr != NULL) { - errno = 0; - if ((tmp = strchr(tmpstr, '-')) != NULL) { - *tmp = ' '; - if (convert_arguint(tmpstr, &from) || - convert_arguint(tmp, &to)) { - free(origstr); - return (EINVAL); - } - - count += to - from + 1; - } else { - if (convert_arguint(tmpstr, &from)) { - free(origstr); - return (EINVAL); - } - count++; - } - tmpstr = (char *)strtok(NULL, ","); - } - - if (count == 0) - goto out; - - /* Allocate buffer of ints */ - tmpstr = (char *)strtok(origstr, ","); - *buffer = malloc(count * sizeof(int)); - - /* Second loop is just inserting converted values into int array */ - while (tmpstr != NULL) { - errno = 0; - if ((tmp = strchr(tmpstr, '-')) != NULL) { - *tmp = ' '; - from = strtol(tmpstr, NULL, 0); - to = strtol(tmp, NULL, 0); - tmpstr = strtok(NULL, ","); - for (i = from; i <= to; i ++) - (*buffer)[currbufp++] = i; - continue; - } - errno = 0; - from = (int)strtol(tmpstr, NULL, 0); - (*buffer)[currbufp++] = from; - tmpstr = (char *)strtok(NULL, ","); - } -out: - free(origstr); - return (count); -} - -/* Convert logoutput strings literals into appropriate ints. */ -static uint8_t -logoutputtoint(char *logoutput, int *output) -{ - int out; - - if (strcmp(logoutput, "file") == 0) - out = NANDSIM_OUTPUT_FILE; - - else if (strcmp(logoutput, "console") == 0) - out = NANDSIM_OUTPUT_CONSOLE; - - else if (strcmp(logoutput, "ram") == 0) - out = NANDSIM_OUTPUT_RAM; - - else if (strcmp(logoutput, "none") == 0) - out = NANDSIM_OUTPUT_NONE; - else - out = -1; - - *output = out; - - if (out == -1) - return (EINVAL); - else - return (0); -} - -static int -configure_sim(const char *devfname, struct rcfile *f) -{ - struct sim_param sim_conf; - char buf[255]; - int err, tmpv, fd; - - err = rc_getint(f, "sim", 0, "log_level", &tmpv); - - if (tmpv < 0 || tmpv > 255 || err) { - error("Bad log level specified (%d)\n", tmpv); - return (ENOTSUP); - } else - sim_conf.log_level = tmpv; - - rc_getstring(f, "sim", 0, "log_output", 255, (char *)&buf); - - tmpv = -1; - err = logoutputtoint((char *)&buf, &tmpv); - if (err) { - error("Log output specified in config file does not seem to " - "be valid (%s)!", (char *)&buf); - return (ENOTSUP); - } - - sim_conf.log_output = tmpv; - - fd = open(devfname, O_RDWR); - if (fd == -1) { - error("could not open simulator device file (%s)!", - devfname); - return (EX_OSFILE); - } - - err = ioctl(fd, NANDSIM_SIM_PARAM, &sim_conf); - if (err) { - error("simulator parameters could not be modified: %s", - strerror(errno)); - close(fd); - return (ENXIO); - } - - close(fd); - return (EX_OK); -} - -static int -create_ctrls(struct rcfile *f, struct sim_ctrl **ctrls, int *cnt) -{ - int count, i; - struct sim_ctrl *ctrlsptr; - - count = rc_getsectionscount(f, "ctrl"); - if (count > MAX_SIM_DEV) { - error("Too many CTRL sections specified(%d)", count); - return (ENOTSUP); - } else if (count == 0) { - error("No ctrl sections specified"); - return (ENOENT); - } - - ctrlsptr = (struct sim_ctrl *)malloc(sizeof(struct sim_ctrl) * count); - if (ctrlsptr == NULL) { - error("Could not allocate memory for ctrl configuration"); - return (ENOMEM); - } - - for (i = 0; i < count; i++) { - bzero((void *)&ctrl_conf, sizeof(ctrl_conf)); - - /* - * ECC layout have to end up with 0xffff, so - * we're filling buffer with 0xff. If ecc_layout is - * defined in config file, values will be overridden. - */ - memset((void *)&ctrl_conf.ecc_layout, 0xff, - sizeof(ctrl_conf.ecc_layout)); - - if (validate_section_config(f, "ctrl", i) != 0) { - free(ctrlsptr); - return (EINVAL); - } - - if (parse_section(f, "ctrl", i) != 0) { - free(ctrlsptr); - return (EINVAL); - } - - memcpy(&ctrlsptr[i], &ctrl_conf, sizeof(ctrl_conf)); - /* Try to create ctrl with config parsed */ - debug("NUM=%d\nNUM_CS=%d\nECC=%d\nFILENAME=%s\nECC_LAYOUT[0]" - "=%d\nECC_LAYOUT[1]=%d\n\n", - ctrlsptr[i].num, ctrlsptr[i].num_cs, ctrlsptr[i].ecc, - ctrlsptr[i].filename, ctrlsptr[i].ecc_layout[0], - ctrlsptr[i].ecc_layout[1]); - } - *cnt = count; - *ctrls = ctrlsptr; - return (0); -} - -static void -destroy_ctrls(struct sim_ctrl *ctrls) -{ - - free(ctrls); -} - -static int -create_chips(struct rcfile *f, struct sim_chip **chips, int *cnt) -{ - struct sim_chip *chipsptr; - int count, i; - - count = rc_getsectionscount(f, "chip"); - if (count > (MAX_CTRL_CS * MAX_SIM_DEV)) { - error("Too many chip sections specified(%d)", count); - return (ENOTSUP); - } else if (count == 0) { - error("No chip sections specified"); - return (ENOENT); - } - - chipsptr = (struct sim_chip *)malloc(sizeof(struct sim_chip) * count); - if (chipsptr == NULL) { - error("Could not allocate memory for chip configuration"); - return (ENOMEM); - } - - for (i = 0; i < count; i++) { - bzero((void *)&chip_conf, sizeof(chip_conf)); - - /* - * Bad block map have to end up with 0xffff, so - * we're filling array with 0xff. If bad block map is - * defined in config file, values will be overridden. - */ - memset((void *)&chip_conf.bad_block_map, 0xff, - sizeof(chip_conf.bad_block_map)); - - if (validate_section_config(f, "chip", i) != 0) { - free(chipsptr); - return (EINVAL); - } - - if (parse_section(f, "chip", i) != 0) { - free(chipsptr); - return (EINVAL); - } - - memcpy(&chipsptr[i], &chip_conf, sizeof(chip_conf)); - - /* Try to create chip with config parsed */ - debug("CHIP:\nNUM=%d\nCTRL_NUM=%d\nDEVID=%d\nMANID=%d\n" - "PAGE_SZ=%d\nOOBSZ=%d\nREAD_T=%d\nDEVMODEL=%s\n" - "MAN=%s\nCOLADDRCYCLES=%d\nROWADDRCYCLES=%d\nCHWIDTH=%d\n" - "PGS/BLK=%d\nBLK/LUN=%d\nLUNS=%d\nERR_RATIO=%d\n" - "WEARLEVEL=%d\nISWP=%d\n\n\n\n", - chipsptr[i].num, chipsptr[i].ctrl_num, - chipsptr[i].device_id, chipsptr[i].manufact_id, - chipsptr[i].page_size, chipsptr[i].oob_size, - chipsptr[i].read_time, chipsptr[i].device_model, - chipsptr[i].manufacturer, chipsptr[i].col_addr_cycles, - chipsptr[i].row_addr_cycles, chipsptr[i].width, - chipsptr[i].pgs_per_blk, chipsptr[i].blks_per_lun, - chipsptr[i].luns, chipsptr[i].error_ratio, - chipsptr[i].wear_level, chipsptr[i].is_wp); - } - *cnt = count; - *chips = chipsptr; - return (0); -} - -static void -destroy_chips(struct sim_chip *chips) -{ - - free(chips); -} - -int -parse_config(char *cfgfname, const char *devfname) -{ - int err = 0, fd; - unsigned int chipsectionscnt, ctrlsectionscnt, i; - struct rcfile *f; - struct sim_chip *chips; - struct sim_ctrl *ctrls; - - err = rc_open(cfgfname, "r", &f); - if (err) { - error("could not open configuration file (%s)", cfgfname); - return (EX_NOINPUT); - } - - /* First, try to configure simulator itself. */ - if (configure_sim(devfname, f) != EX_OK) { - rc_close(f); - return (EINVAL); - } - - debug("SIM CONFIGURED!\n"); - /* Then create controllers' configs */ - if (create_ctrls(f, &ctrls, &ctrlsectionscnt) != 0) { - rc_close(f); - return (ENXIO); - } - debug("CTRLS CONFIG READ!\n"); - - /* Then create chips' configs */ - if (create_chips(f, &chips, &chipsectionscnt) != 0) { - destroy_ctrls(ctrls); - rc_close(f); - return (ENXIO); - } - debug("CHIPS CONFIG READ!\n"); - - if (validate_ctrls(ctrls, ctrlsectionscnt) != 0) { - destroy_ctrls(ctrls); - destroy_chips(chips); - rc_close(f); - return (EX_SOFTWARE); - } - if (validate_chips(chips, chipsectionscnt, ctrls, - ctrlsectionscnt) != 0) { - destroy_ctrls(ctrls); - destroy_chips(chips); - rc_close(f); - return (EX_SOFTWARE); - } - - /* Open device */ - fd = open(devfname, O_RDWR); - if (fd == -1) { - error("could not open simulator device file (%s)!", - devfname); - rc_close(f); - destroy_chips(chips); - destroy_ctrls(ctrls); - return (EX_OSFILE); - } - - debug("SIM CONFIG STARTED!\n"); - - /* At this stage, both ctrls' and chips' configs should be valid */ - for (i = 0; i < ctrlsectionscnt; i++) { - err = ioctl(fd, NANDSIM_CREATE_CTRL, &ctrls[i]); - if (err) { - if (err == EEXIST) - error("Controller#%d already created\n", - ctrls[i].num); - else if (err == EINVAL) - error("Incorrect controller number (%d)\n", - ctrls[i].num); - else - error("Could not created controller#%d\n", - ctrls[i].num); - /* Errors during controller creation stops parsing */ - close(fd); - rc_close(f); - destroy_ctrls(ctrls); - destroy_chips(chips); - return (ENXIO); - } - debug("CTRL#%d CONFIG STARTED!\n", i); - } - - for (i = 0; i < chipsectionscnt; i++) { - err = ioctl(fd, NANDSIM_CREATE_CHIP, &chips[i]); - if (err) { - if (err == EEXIST) - error("Chip#%d for controller#%d already " - "created\n", chips[i].num, - chips[i].ctrl_num); - else if (err == EINVAL) - error("Incorrect chip number (%d:%d)\n", - chips[i].num, chips[i].ctrl_num); - else - error("Could not create chip (%d:%d)\n", - chips[i].num, chips[i].ctrl_num); - error("Could not start chip#%d\n", i); - destroy_chips(chips); - destroy_ctrls(ctrls); - close(fd); - rc_close(f); - return (ENXIO); - } - } - debug("CHIPS CONFIG STARTED!\n"); - - close(fd); - rc_close(f); - destroy_chips(chips); - destroy_ctrls(ctrls); - return (0); -} - -/* - * Function tries to get appropriate value for given key, convert it to - * array of ints (of given size), and perform all the necessary checks and - * conversions. - */ -static int -get_argument_intarray(const char *sect_name, int sectno, - struct nandsim_key *key, struct rcfile *f) -{ - char strbuf[STRBUFSIZ]; - int *intbuf; - int getres; - uint32_t cnt, i = 0; - - getres = rc_getstring(f, sect_name, sectno, key->keyname, STRBUFSIZ, - (char *)&strbuf); - - if (getres != 0) { - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - return (EINVAL); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - cnt = parse_intarray((char *)&strbuf, &intbuf); - cnt = (cnt <= key->maxlength) ? cnt : key->maxlength; - - for (i = 0; i < cnt; i++) { - if (SIZE(key->valuetype) == SIZE_8) - *((uint8_t *)(key->field) + i) = - (uint8_t)intbuf[i]; - else if (SIZE(key->valuetype) == SIZE_16) - *((uint16_t *)(key->field) + i) = - (uint16_t)intbuf[i]; - else - *((uint32_t *)(key->field) + i) = - (uint32_t)intbuf[i]; - } - free(intbuf); - return (0); -} - -/* - * Function tries to get appropriate value for given key, convert it to - * int of certain length. - */ -static int -get_argument_int(const char *sect_name, int sectno, struct nandsim_key *key, - struct rcfile *f) -{ - int getres; - uint32_t val; - - getres = rc_getint(f, sect_name, sectno, key->keyname, &val); - if (getres != 0) { - - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - - return (EINVAL); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - if (SIZE(key->valuetype) == SIZE_8) - *(uint8_t *)(key->field) = (uint8_t)val; - else if (SIZE(key->valuetype) == SIZE_16) - *(uint16_t *)(key->field) = (uint16_t)val; - else - *(uint32_t *)(key->field) = (uint32_t)val; - return (0); -} - -/* Function tries to get string value for given key */ -static int -get_argument_string(const char *sect_name, int sectno, - struct nandsim_key *key, struct rcfile *f) -{ - char strbuf[STRBUFSIZ]; - int getres; - - getres = rc_getstring(f, sect_name, sectno, key->keyname, STRBUFSIZ, - strbuf); - - if (getres != 0) { - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - return (1); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - strncpy(key->field, (char *)&strbuf, (size_t)(key->maxlength - 1)); - return (0); -} - -/* Function tries to get on/off value for given key */ -static int -get_argument_bool(const char *sect_name, int sectno, struct nandsim_key *key, - struct rcfile *f) -{ - int getres, val; - - getres = rc_getbool(f, sect_name, sectno, key->keyname, &val); - if (getres != 0) { - if (key->mandatory != 0) { - error(MSG_MANDATORYKEYMISSING, key->keyname, - sect_name); - return (1); - } else - /* Non-mandatory key, not present -- skip */ - return (0); - } - *(uint8_t *)key->field = (uint8_t)val; - return (0); -} - -int -parse_section(struct rcfile *f, const char *sect_name, int sectno) -{ - struct nandsim_key *key; - struct nandsim_section *sect = (struct nandsim_section *)§ions; - int getres = 0; - - while (1) { - if (sect == NULL) - return (EINVAL); - - if (strcmp(sect->name, sect_name) == 0) - break; - else - sect++; - } - key = sect->keys; - do { - debug("->Section: %s, Key: %s, type: %d, size: %d", - sect_name, key->keyname, TYPE(key->valuetype), - SIZE(key->valuetype)/2); - - switch (TYPE(key->valuetype)) { - case VALUE_UINT: - /* Single int value */ - getres = get_argument_int(sect_name, sectno, key, f); - - if (getres != 0) - return (getres); - - break; - case VALUE_UINTARRAY: - /* Array of ints */ - getres = get_argument_intarray(sect_name, - sectno, key, f); - - if (getres != 0) - return (getres); - - break; - case VALUE_STRING: - /* Array of chars */ - getres = get_argument_string(sect_name, sectno, key, - f); - - if (getres != 0) - return (getres); - - break; - case VALUE_BOOL: - /* Boolean value (true/false/on/off/yes/no) */ - getres = get_argument_bool(sect_name, sectno, key, - f); - - if (getres != 0) - return (getres); - - break; - } - } while ((++key)->keyname != NULL); - - return (0); -} - -static uint8_t -validate_chips(struct sim_chip *chips, int chipcnt, - struct sim_ctrl *ctrls, int ctrlcnt) -{ - int cchipcnt, i, width, j, id, max; - - cchipcnt = chipcnt; - for (chipcnt -= 1; chipcnt >= 0; chipcnt--) { - if (chips[chipcnt].num >= MAX_CTRL_CS) { - error("chip no. too high (%d)!!\n", - chips[chipcnt].num); - return (EINVAL); - } - - if (chips[chipcnt].ctrl_num >= MAX_SIM_DEV) { - error("controller no. too high (%d)!!\n", - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - if (chips[chipcnt].width != 8 && - chips[chipcnt].width != 16) { - error("invalid width:%d for chip#%d", - chips[chipcnt].width, chips[chipcnt].num); - return (EINVAL); - } - - /* Check if page size is > 512 and if its power of 2 */ - if (chips[chipcnt].page_size < 512 || - (chips[chipcnt].page_size & - (chips[chipcnt].page_size - 1)) != 0) { - error("invalid page size:%d for chip#%d at ctrl#%d!!" - "\n", chips[chipcnt].page_size, - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - /* Check if controller no. ctrl_num is configured */ - for (i = 0, id = -1; i < ctrlcnt && id == -1; i++) - if (ctrls[i].num == chips[chipcnt].ctrl_num) - id = i; - - if (i == ctrlcnt && id == -1) { - error("Missing configuration for controller %d" - " (at least one chip is connected to it)", - chips[chipcnt].ctrl_num); - return (EINVAL); - } else { - /* - * Controller is configured -> check oob_size - * validity - */ - i = 0; - max = ctrls[id].ecc_layout[0]; - while (i < MAX_ECC_BYTES && - ctrls[id].ecc_layout[i] != 0xffff) { - - if (ctrls[id].ecc_layout[i] > max) - max = ctrls[id].ecc_layout[i]; - i++; - } - - if (chips[chipcnt].oob_size < (unsigned)i) { - error("OOB size for chip#%d at ctrl#%d is " - "smaller than ecc layout length!", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - exit(EINVAL); - } - - if (chips[chipcnt].oob_size < (unsigned)max) { - error("OOB size for chip#%d at ctrl#%d is " - "smaller than maximal ecc position in " - "defined layout!", chips[chipcnt].num, - chips[chipcnt].ctrl_num); - exit(EINVAL); - } - - - } - - if ((chips[chipcnt].erase_time < DELAYTIME_MIN || - chips[chipcnt].erase_time > DELAYTIME_MAX) && - chips[chipcnt].erase_time != 0) { - error("Invalid erase time value for chip#%d at " - "ctrl#%d", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - if ((chips[chipcnt].prog_time < DELAYTIME_MIN || - chips[chipcnt].prog_time > DELAYTIME_MAX) && - chips[chipcnt].prog_time != 0) { - error("Invalid prog time value for chip#%d at " - "ctr#%d!", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - - if ((chips[chipcnt].read_time < DELAYTIME_MIN || - chips[chipcnt].read_time > DELAYTIME_MAX) && - chips[chipcnt].read_time != 0) { - error("Invalid read time value for chip#%d at " - "ctrl#%d!", - chips[chipcnt].num, - chips[chipcnt].ctrl_num); - return (EINVAL); - } - } - /* Check if chips attached to the same controller, have same width */ - for (i = 0; i < ctrlcnt; i++) { - width = -1; - for (j = 0; j < cchipcnt; j++) { - if (chips[j].ctrl_num == i) { - if (width == -1) { - width = chips[j].width; - } else { - if (width != chips[j].width) { - error("Chips attached to " - "ctrl#%d have different " - "widths!\n", i); - return (EINVAL); - } - } - } - } - } - - return (0); -} - -static uint8_t -validate_ctrls(struct sim_ctrl *ctrl, int ctrlcnt) -{ - for (ctrlcnt -= 1; ctrlcnt >= 0; ctrlcnt--) { - if (ctrl[ctrlcnt].num > MAX_SIM_DEV) { - error("Controller no. too high (%d)!!\n", - ctrl[ctrlcnt].num); - return (EINVAL); - } - if (ctrl[ctrlcnt].num_cs > MAX_CTRL_CS) { - error("Too many CS (%d)!!\n", ctrl[ctrlcnt].num_cs); - return (EINVAL); - } - if (ctrl[ctrlcnt].ecc != 0 && ctrl[ctrlcnt].ecc != 1) { - error("ECC is set to neither 0 nor 1 !\n"); - return (EINVAL); - } - } - - return (0); -} - -static int validate_section_config(struct rcfile *f, const char *sect_name, - int sectno) -{ - struct nandsim_key *key; - struct nandsim_section *sect; - char **keys_tbl; - int i, match; - - for (match = 0, sect = (struct nandsim_section *)§ions; - sect != NULL; sect++) { - if (strcmp(sect->name, sect_name) == 0) { - match = 1; - break; - } - } - - if (match == 0) - return (EINVAL); - - keys_tbl = rc_getkeys(f, sect_name, sectno); - if (keys_tbl == NULL) - return (ENOMEM); - - for (i = 0; keys_tbl[i] != NULL; i++) { - key = sect->keys; - match = 0; - do { - if (strcmp(keys_tbl[i], key->keyname) == 0) { - match = 1; - break; - } - } while ((++key)->keyname != NULL); - - if (match == 0) { - error("Invalid key in config file: %s\n", keys_tbl[i]); - free(keys_tbl); - return (EINVAL); - } - } - - free(keys_tbl); - return (0); -} diff --git a/usr.sbin/nandsim/nandsim_cfgparse.h b/usr.sbin/nandsim/nandsim_cfgparse.h deleted file mode 100644 index 12365666ad93..000000000000 --- a/usr.sbin/nandsim/nandsim_cfgparse.h +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (C) 2009-2012 Semihalf - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef _NANDSIM_CONFPARSER_H_ -#define _NANDSIM_CONFPARSER_H_ - -#define VALUE_UINT 0x08 -#define VALUE_INT 0x10 -#define VALUE_UINTARRAY 0x18 -#define VALUE_INTARRAY 0x20 -#define VALUE_STRING 0x28 -#define VALUE_CHAR 0x40 -#define VALUE_BOOL 0x48 - -#define SIZE_8 0x01 -#define SIZE_16 0x02 -#define SIZE_32 0x04 - -#include "nandsim_rcfile.h" - -/* - * keyname = name of a key, - * mandatory = is key mandatory in section belonging to, 0=false 1=true - * valuetype = what kind of value is assigned to that key, e.g. - * VALUE_UINT | SIZE_8 -- unsigned uint size 8 bits; - * VALUE_UINTARRAY | SIZE_8 -- array of uints 8-bit long; - * VALUE_BOOL -- 'on', 'off','true','false','yes' or 'no' - * literals; - * VALUE_STRING -- strings - * field = ptr to the field that should hold value for parsed value - * maxlength = contains maximum length of an array (used only with either - * VALUE_STRING or VALUE_(U)INTARRAY value types. - */ -struct nandsim_key { - const char *keyname; - uint8_t mandatory; - uint8_t valuetype; - void *field; - uint32_t maxlength; -}; -struct nandsim_section { - const char *name; - struct nandsim_key *keys; -}; - -struct nandsim_config { - struct sim_param **simparams; - struct sim_chip **simchips; - struct sim_ctrl **simctrls; - int chipcnt; - int ctrlcnt; -}; - -int parse_intarray(char *, int **); -int parse_config(char *, const char *); -int parse_section(struct rcfile *, const char *, int); -int compare_configs(struct nandsim_config *, struct nandsim_config *); -int convert_argint(char *, int *); -int convert_arguint(char *, unsigned int *); - -#endif /* _NANDSIM_CONFPARSER_H_ */ diff --git a/usr.sbin/nandsim/nandsim_rcfile.c b/usr.sbin/nandsim/nandsim_rcfile.c deleted file mode 100644 index 8e9cca17f37b..000000000000 --- a/usr.sbin/nandsim/nandsim_rcfile.c +++ /dev/null @@ -1,442 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1999, Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * from: FreeBSD: src/lib/libncp/ncpl_rcfile.c,v 1.5 2007/01/09 23:27:39 imp Exp - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); -#include <sys/types.h> -#include <sys/queue.h> -#include <ctype.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> -#include <pwd.h> -#include <unistd.h> - -#include "nandsim_rcfile.h" - -SLIST_HEAD(rcfile_head, rcfile); -static struct rcfile_head pf_head = {NULL}; -static struct rcsection *rc_findsect(struct rcfile *rcp, - const char *sectname, int sect_id); -static struct rcsection *rc_addsect(struct rcfile *rcp, - const char *sectname); -static int rc_sect_free(struct rcsection *rsp); -static struct rckey *rc_sect_findkey(struct rcsection *rsp, - const char *keyname); -static struct rckey *rc_sect_addkey(struct rcsection *rsp, const char *name, - char *value); -static void rc_key_free(struct rckey *p); -static void rc_parse(struct rcfile *rcp); - -static struct rcfile* rc_find(const char *filename); - -/* - * open rcfile and load its content, if already open - return previous handle - */ -int -rc_open(const char *filename, const char *mode,struct rcfile **rcfile) -{ - struct rcfile *rcp; - FILE *f; - rcp = rc_find(filename); - if (rcp) { - *rcfile = rcp; - return (0); - } - f = fopen (filename, mode); - if (f == NULL) - return errno; - rcp = malloc(sizeof(struct rcfile)); - if (rcp == NULL) { - fclose(f); - return ENOMEM; - } - bzero(rcp, sizeof(struct rcfile)); - rcp->rf_name = strdup(filename); - rcp->rf_f = f; - SLIST_INSERT_HEAD(&pf_head, rcp, rf_next); - rc_parse(rcp); - *rcfile = rcp; - return (0); -} - -int -rc_close(struct rcfile *rcp) -{ - struct rcsection *p,*n; - - fclose(rcp->rf_f); - for (p = SLIST_FIRST(&rcp->rf_sect); p; ) { - n = p; - p = SLIST_NEXT(p,rs_next); - rc_sect_free(n); - } - free(rcp->rf_name); - SLIST_REMOVE(&pf_head, rcp, rcfile, rf_next); - free(rcp); - return (0); -} - -static struct rcfile* -rc_find(const char *filename) -{ - struct rcfile *p; - - SLIST_FOREACH(p, &pf_head, rf_next) - if (strcmp (filename, p->rf_name) == 0) - return (p); - return (0); -} - -/* Find section with given name and id */ -static struct rcsection * -rc_findsect(struct rcfile *rcp, const char *sectname, int sect_id) -{ - struct rcsection *p; - - SLIST_FOREACH(p, &rcp->rf_sect, rs_next) - if (strcmp(p->rs_name, sectname) == 0 && p->rs_id == sect_id) - return (p); - return (NULL); -} - -static struct rcsection * -rc_addsect(struct rcfile *rcp, const char *sectname) -{ - struct rcsection *p; - int id = 0; - p = rc_findsect(rcp, sectname, 0); - if (p) { - /* - * If section with that name already exists -- add one more, - * same named, but with different id (higher by one) - */ - while (p != NULL) { - id = p->rs_id + 1; - p = rc_findsect(rcp, sectname, id); - } - } - p = malloc(sizeof(*p)); - if (!p) - return (NULL); - p->rs_name = strdup(sectname); - p->rs_id = id; - SLIST_INIT(&p->rs_keys); - SLIST_INSERT_HEAD(&rcp->rf_sect, p, rs_next); - return (p); -} - -static int -rc_sect_free(struct rcsection *rsp) -{ - struct rckey *p,*n; - - for (p = SLIST_FIRST(&rsp->rs_keys); p; ) { - n = p; - p = SLIST_NEXT(p,rk_next); - rc_key_free(n); - } - free(rsp->rs_name); - free(rsp); - return (0); -} - -static struct rckey * -rc_sect_findkey(struct rcsection *rsp, const char *keyname) -{ - struct rckey *p; - - SLIST_FOREACH(p, &rsp->rs_keys, rk_next) - if (strcmp(p->rk_name, keyname)==0) - return (p); - return (NULL); -} - -static struct rckey * -rc_sect_addkey(struct rcsection *rsp, const char *name, char *value) -{ - struct rckey *p; - p = rc_sect_findkey(rsp, name); - if (p) { - free(p->rk_value); - } else { - p = malloc(sizeof(*p)); - if (!p) - return (NULL); - SLIST_INSERT_HEAD(&rsp->rs_keys, p, rk_next); - p->rk_name = strdup(name); - } - p->rk_value = value ? strdup(value) : strdup(""); - return (p); -} - -static void -rc_key_free(struct rckey *p) -{ - free(p->rk_value); - free(p->rk_name); - free(p); -} - -enum { stNewLine, stHeader, stSkipToEOL, stGetKey, stGetValue}; - -static void -rc_parse(struct rcfile *rcp) -{ - FILE *f = rcp->rf_f; - int state = stNewLine, c; - struct rcsection *rsp = NULL; - struct rckey *rkp = NULL; - char buf[2048]; - char *next = buf, *last = &buf[sizeof(buf)-1]; - - while ((c = getc (f)) != EOF) { - if (c == '\r') - continue; - if (state == stNewLine) { - next = buf; - if (isspace(c)) - continue; /* skip leading junk */ - if (c == '[') { - state = stHeader; - rsp = NULL; - continue; - } - if (c == '#' || c == ';') { - state = stSkipToEOL; - } else { /* something meaningful */ - state = stGetKey; - } - } - if (state == stSkipToEOL || next == last) {/* ignore long lines */ - if (c == '\n') { - state = stNewLine; - next = buf; - } - continue; - } - if (state == stHeader) { - if (c == ']') { - *next = 0; - next = buf; - rsp = rc_addsect(rcp, buf); - state = stSkipToEOL; - } else - *next++ = c; - continue; - } - if (state == stGetKey) { - if (c == ' ' || c == '\t')/* side effect: 'key name='*/ - continue; /* become 'keyname=' */ - if (c == '\n') { /* silently ignore ... */ - state = stNewLine; - continue; - } - if (c != '=') { - *next++ = c; - continue; - } - *next = 0; - if (rsp == NULL) { - fprintf(stderr, "Key '%s' defined before " - "section\n", buf); - state = stSkipToEOL; - continue; - } - rkp = rc_sect_addkey(rsp, buf, NULL); - next = buf; - state = stGetValue; - continue; - } - /* only stGetValue left */ - if (state != stGetValue) { - fprintf(stderr, "Well, I can't parse file " - "'%s'\n",rcp->rf_name); - state = stSkipToEOL; - } - if (c != '\n') { - *next++ = c; - continue; - } - *next = 0; - rkp->rk_value = strdup(buf); - state = stNewLine; - rkp = NULL; - } /* while */ - if (c == EOF && state == stGetValue) { - *next = 0; - rkp->rk_value = strdup(buf); - } -} - -int -rc_getstringptr(struct rcfile *rcp, const char *section, int sect_id, - const char *key, char **dest) -{ - struct rcsection *rsp; - struct rckey *rkp; - - *dest = NULL; - rsp = rc_findsect(rcp, section, sect_id); - if (!rsp) - return (ENOENT); - rkp = rc_sect_findkey(rsp,key); - if (!rkp) - return (ENOENT); - *dest = rkp->rk_value; - return (0); -} - -int -rc_getstring(struct rcfile *rcp, const char *section, int sect_id, - const char *key, unsigned int maxlen, char *dest) -{ - char *value; - int error; - - error = rc_getstringptr(rcp, section, sect_id, key, &value); - if (error) - return (error); - if (strlen(value) >= maxlen) { - fprintf(stderr, "line too long for key '%s' in section '%s'," - "max = %d\n",key, section, maxlen); - return (EINVAL); - } - strcpy(dest,value); - return (0); -} - -int -rc_getint(struct rcfile *rcp, const char *section, int sect_id, - const char *key, int *value) -{ - struct rcsection *rsp; - struct rckey *rkp; - - rsp = rc_findsect(rcp, section, sect_id); - if (!rsp) - return (ENOENT); - rkp = rc_sect_findkey(rsp,key); - if (!rkp) - return (ENOENT); - errno = 0; - *value = strtol(rkp->rk_value,NULL,0); - if (errno) { - fprintf(stderr, "invalid int value '%s' for key '%s' in " - "section '%s'\n",rkp->rk_value,key,section); - return (errno); - } - return (0); -} - -/* - * 1,yes,true - * 0,no,false - */ -int -rc_getbool(struct rcfile *rcp, const char *section, int sect_id, - const char *key, int *value) -{ - struct rcsection *rsp; - struct rckey *rkp; - char *p; - - rsp = rc_findsect(rcp, section, sect_id); - if (!rsp) - return (ENOENT); - rkp = rc_sect_findkey(rsp,key); - if (!rkp) - return (ENOENT); - p = rkp->rk_value; - while (*p && isspace(*p)) p++; - if (*p == '0' || strcasecmp(p,"no") == 0 || - strcasecmp(p, "false") == 0 || - strcasecmp(p, "off") == 0) { - *value = 0; - return (0); - } - if (*p == '1' || strcasecmp(p,"yes") == 0 || - strcasecmp(p, "true") == 0 || - strcasecmp(p, "on") == 0) { - *value = 1; - return (0); - } - fprintf(stderr, "invalid boolean value '%s' for key '%s' in section " - "'%s' \n",p, key, section); - return (EINVAL); -} - -/* Count how many sections with given name exists in configuration. */ -int rc_getsectionscount(struct rcfile *f, const char *sectname) -{ - struct rcsection *p; - int count = 0; - - p = rc_findsect(f, sectname, 0); - if (p) { - while (p != NULL) { - count = p->rs_id + 1; - p = rc_findsect(f, sectname, count); - } - return (count); - } else - return (0); -} - -char ** -rc_getkeys(struct rcfile *rcp, const char *sectname, int sect_id) -{ - struct rcsection *rsp; - struct rckey *p; - char **names_tbl; - int i = 0, count = 0; - - rsp = rc_findsect(rcp, sectname, sect_id); - if (rsp == NULL) - return (NULL); - - SLIST_FOREACH(p, &rsp->rs_keys, rk_next) - count++; - - names_tbl = malloc(sizeof(char *) * (count + 1)); - if (names_tbl == NULL) - return (NULL); - - SLIST_FOREACH(p, &rsp->rs_keys, rk_next) - names_tbl[i++] = p->rk_name; - - names_tbl[i] = NULL; - return (names_tbl); -} - diff --git a/usr.sbin/nandsim/nandsim_rcfile.h b/usr.sbin/nandsim/nandsim_rcfile.h deleted file mode 100644 index d92ae870f0fc..000000000000 --- a/usr.sbin/nandsim/nandsim_rcfile.h +++ /dev/null @@ -1,72 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-3-Clause - * - * Copyright (c) 1999, Boris Popov - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the author nor the names of any co-contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - * - * from: FreeBSD: src/lib/libncp/ncpl_rcfile.c,v 1.5 2007/01/09 23:27:39 imp Exp - */ - -#ifndef _SIMRC_H_ -#define _SIMRC_H_ - -#include <sys/queue.h> - -struct rckey { - SLIST_ENTRY(rckey) rk_next; - char *rk_name; /* key name */ - char *rk_value; /* key value */ -}; - -struct rcsection { - SLIST_ENTRY(rcsection) rs_next; - SLIST_HEAD(rckey_head,rckey) rs_keys; /* key list */ - char *rs_name; /* section name */ - int rs_id; /* allow few same named */ -}; - -struct rcfile { - SLIST_ENTRY(rcfile) rf_next; - SLIST_HEAD(rcsec_head, rcsection) rf_sect; /* sections list */ - char *rf_name; /* file name */ - FILE *rf_f; /* file desc */ -}; - -int rc_open(const char *, const char *,struct rcfile **); -int rc_close(struct rcfile *); -int rc_getstringptr(struct rcfile *, const char *, int, const char *, - char **); -int rc_getstring(struct rcfile *, const char *, int, const char *, - unsigned int, char *); -int rc_getint(struct rcfile *, const char *, int, const char *, int *); -int rc_getbool(struct rcfile *, const char *, int, const char *, int *); -int rc_getsectionscount(struct rcfile *, const char *); -char **rc_getkeys(struct rcfile *, const char *, int); - -#endif /* _SIMRC_H_ */ diff --git a/usr.sbin/nandsim/sample.conf b/usr.sbin/nandsim/sample.conf deleted file mode 100644 index bc534e109fe5..000000000000 --- a/usr.sbin/nandsim/sample.conf +++ /dev/null @@ -1,174 +0,0 @@ -#- -# Copyright (C) 2009-2012 Semihalf -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions -# are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -# SUCH DAMAGE. -# -# $FreeBSD$ - -# -# Sample NANDsim configuration file. -# - -############################################################################# -# -# [sim] General (common) simulator configuration section. -# -[sim] -# log_level=0..255 -log_level=11 - -# log_output=[none, console, ram, file] -# -# When log_output=file is specified, each [ctrl] section must have a -# corresponding 'log_filename' field provided, which specifies log file name -# to be used. -log_output=none - -############################################################################# -# -# [ctrl] Controller configuration section. -# -# There can be a number of controllers defined for simulation, each has a -# dedicated [ctrl] section. With a given controller there are associated -# subordinate NAND chips, which are tied to chip select lines. -# -[ctrl] -# The number of this controller. -# ctrl_num=0..3 -ctrl_num=0 - -# The number of chip selects available at this controller. -# num_cs=1..4 -num_cs=1 - -# ECC enable flag. -# ecc=[on|off] -ecc=on - -# ECC layout. This is the list of byte offsets within OOB area, which comprise -# the ECC contents set. -# -# ecc_layout=[byte1, byte2-byte3, ..byten] -ecc_layout=[0-53] - -# Absolute path to the log file for this controller. -#log_filename=/var/log/nandsim-ctl0.log - - -############################################################################# -# -# [chip] Chip configuration section. -# -# There can be a number of individual NAND chip devices defined for -# simulation, and each has a dedicated [chip] section. -# -# A particular chip needs to be associated with its parent NAND controller by -# specifying the following fields: controller number (chip_ctrl) and the chip -# select line it is connected to (chip_cs). The chip can be connected to only -# a single (and unique) controller:cs pair. -# -[chip] -# The number of parent controller. This has to fit one of the controller -# instance number (ctrl_num from [ctrl] section). -# chip_ctrl=0..3 -chip_ctrl=0 - -# Chip select line. -# chip_cs=0..3 -chip_cs=0 - -# ONFI device identifier. -# device_id=0x00..0xff -device_id=0xd3 - -# ONFI manufacturer identifier. -# manufacturer_id=0x00..0xff -manufacturer_id=0xec - -# Textual description of the chip. -# model="model_name" -model="k9xxg08uxM:1GiB 3,3V 8-bit" - -# Textual name of the chip manufacturer. -# manufacturer="manufacturer name" -manufacturer="SAMSUNG" - -# page_size=[must be power of 2 and >= 512] (in bytes) -page_size=2048 -# oob_size=[>0] -oob_size=64 -# pages_per_block=n*32 -pages_per_block=64 -# blocks_per_lun=[>0] -blocks_per_lun=4096 -# luns=1..N -luns=1 -# column_addr_cycle=[1,2] -column_addr_cycle=2 -# row_addr_cycle=[1,2,3] -row_addr_cycle=3 - -# program_time= (in us) -program_time=0 -# erase_time= (in us) -erase_time=0 -# read_time= (in us) -read_time=0 -# ccs_time= (in us) -#ccs_time=200 - -# Simulate write-protect on the chip. -# write_protect=[yes|no] -#write_protect=no - -# Blocks wear-out threshold. Each block has a counter of program-erase cycles; -# when this counter reaches 'wear_out' value a given block is treated as a bad -# block (access will report error). -# -# Setting wear_out to 0 means that blocks will never wear out. -# -# wear_out=0..100000 -wear_out=50000 - -# Errors per million read/write bytes. This simulates an accidental read/write -# block error, which can happen in real devices with certain probability. Note -# this isn't a bad block condition i.e. the block at which the read/write -# operation is simulated to fail here remains usable, only the operation has -# not succeeded (this is where ECC comes into play and is supposed to correct -# such problems). -# -# error_ratio=0..1000000 -#error_ratio=50 - -# Chip data bus width. All chips connected to the same controller must have -# the same bus width. -# -# width=[8|16] -width=8 - -# Bad block map. NANDsim emulates bad block behavior upon accessing a block -# with number from the specified list. -# -# bad_block_map=[bad_block1, bad_block2-bad_block3, ..bad_blockn] -bad_block_map=[100-200] - diff --git a/usr.sbin/nandtool/Makefile b/usr.sbin/nandtool/Makefile deleted file mode 100644 index c01c2fdedbbf..000000000000 --- a/usr.sbin/nandtool/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# $FreeBSD$ - -PROG= nandtool -SRCS= nandtool.c nand_read.c nand_write.c nand_erase.c nand_info.c -SRCS+= nand_readoob.c nand_writeoob.c -BINDIR= /usr/sbin -LIBADD= geom -MAN= nandtool.8 - -.include <bsd.prog.mk> diff --git a/usr.sbin/nandtool/Makefile.depend b/usr.sbin/nandtool/Makefile.depend deleted file mode 100644 index 0220673c9076..000000000000 --- a/usr.sbin/nandtool/Makefile.depend +++ /dev/null @@ -1,20 +0,0 @@ -# $FreeBSD$ -# Autogenerated - do NOT edit! - -DIRDEPS = \ - gnu/lib/csu \ - include \ - include/xlocale \ - lib/${CSU_DIR} \ - lib/libc \ - lib/libcompiler_rt \ - lib/libexpat \ - lib/libgeom \ - lib/libsbuf \ - - -.include <dirdeps.mk> - -.if ${DEP_RELDIR} == ${_DEP_RELDIR} -# local dependencies - needed for -jN in clean tree -.endif diff --git a/usr.sbin/nandtool/nand_erase.c b/usr.sbin/nandtool/nand_erase.c deleted file mode 100644 index e9742d15ddf9..000000000000 --- a/usr.sbin/nandtool/nand_erase.c +++ /dev/null @@ -1,116 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <sys/types.h> -#include <sys/disk.h> -#include <libgeom.h> -#include <dev/nand/nand_dev.h> -#include "nandtool.h" - -int nand_erase(struct cmd_param *params) -{ - struct chip_param_io chip_params; - char *dev; - int fd = -1, ret = 0; - off_t pos, count; - off_t start, nblocks, i; - int block_size, mult; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "Please supply valid 'dev' parameter.\n"); - return (1); - } - - if (param_has_value(params, "count")) - count = param_get_intx(params, "count"); - else - count = 1; - - if ((fd = g_open(dev, 1)) < 0) { - perrorf("Cannot open %s", dev); - return (1); - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - - if (param_has_value(params, "page")) { - pos = chip_params.page_size * param_get_intx(params, "page"); - mult = chip_params.page_size; - } else if (param_has_value(params, "block")) { - pos = block_size * param_get_intx(params, "block"); - mult = block_size; - } else if (param_has_value(params, "pos")) { - pos = param_get_intx(params, "pos"); - mult = 1; - } else { - /* Erase whole chip */ - if (ioctl(fd, DIOCGMEDIASIZE, &count) == -1) { - ret = 1; - goto out; - } - - pos = 0; - mult = 1; - } - - if (pos % block_size) { - fprintf(stderr, "Position must be block-size aligned!\n"); - ret = 1; - goto out; - } - - count *= mult; - start = pos / block_size; - nblocks = count / block_size; - - for (i = 0; i < nblocks; i++) { - if (g_delete(fd, (start + i) * block_size, block_size) == -1) { - perrorf("Cannot erase block %d - probably a bad block", - start + i); - ret = 1; - } - } - -out: - g_close(fd); - - return (ret); -} - diff --git a/usr.sbin/nandtool/nand_info.c b/usr.sbin/nandtool/nand_info.c deleted file mode 100644 index 79f84abd1136..000000000000 --- a/usr.sbin/nandtool/nand_info.c +++ /dev/null @@ -1,88 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <stdlib.h> -#include <stdint.h> -#include <string.h> -#include <libgeom.h> -#include <sys/disk.h> -#include <dev/nand/nand_dev.h> -#include "nandtool.h" - -int nand_info(struct cmd_param *params) -{ - struct chip_param_io chip_params; - int fd = -1, ret = 0; - int block_size; - off_t chip_size, media_size; - const char *dev; - - if ((dev = param_get_string(params, "dev")) == NULL) { - fprintf(stderr, "Please supply 'dev' parameter, eg. " - "'dev=/dev/gnand0'\n"); - return (1); - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - return (1); - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - if (ioctl(fd, DIOCGMEDIASIZE, &media_size) == -1) { - perrorf("Cannot ioctl(DIOCGMEDIASIZE)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - chip_size = block_size * chip_params.blocks; - - printf("Device:\t\t\t%s\n", dev); - printf("Page size:\t\t%d bytes\n", chip_params.page_size); - printf("Block size:\t\t%d bytes (%d KB)\n", block_size, - block_size / 1024); - printf("OOB size per page:\t%d bytes\n", chip_params.oob_size); - printf("Chip size:\t\t%jd MB\n", (uintmax_t)(chip_size / 1024 / 1024)); - printf("Slice size:\t\t%jd MB\n", - (uintmax_t)(media_size / 1024 / 1024)); - -out: - g_close(fd); - - return (ret); -} diff --git a/usr.sbin/nandtool/nand_read.c b/usr.sbin/nandtool/nand_read.c deleted file mode 100644 index 395b0c3fa7f5..000000000000 --- a/usr.sbin/nandtool/nand_read.c +++ /dev/null @@ -1,141 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <libgeom.h> -#include <sys/disk.h> -#include <dev/nand/nand_dev.h> -#include "nandtool.h" - -int nand_read(struct cmd_param *params) -{ - struct chip_param_io chip_params; - int fd = -1, out_fd = -1, done = 0, ret = 0; - char *dev, *out; - int pos, count, mult, block_size; - uint8_t *buf = NULL; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "You must specify 'dev' parameter\n"); - return (1); - } - - if ((out = param_get_string(params, "out"))) { - out_fd = open(out, O_WRONLY|O_CREAT, 0666); - if (out_fd == -1) { - perrorf("Cannot open %s for writing", out); - return (1); - } - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - - if (param_has_value(params, "page")) { - pos = chip_params.page_size * param_get_int(params, "page"); - mult = chip_params.page_size; - } else if (param_has_value(params, "block")) { - pos = block_size * param_get_int(params, "block"); - mult = block_size; - } else if (param_has_value(params, "pos")) { - pos = param_get_int(params, "pos"); - mult = 1; - if (pos % chip_params.page_size) { - fprintf(stderr, "Position must be page-size aligned!\n"); - ret = 1; - goto out; - } - } else { - fprintf(stderr, "You must specify one of: 'block', 'page'," - "'pos' arguments\n"); - ret = 1; - goto out; - } - - if (!(param_has_value(params, "count"))) - count = mult; - else - count = param_get_int(params, "count") * mult; - - if (!(buf = malloc(chip_params.page_size))) { - perrorf("Cannot allocate buffer [size %x]", - chip_params.page_size); - ret = 1; - goto out; - } - - lseek(fd, pos, SEEK_SET); - - while (done < count) { - if ((ret = read(fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - perrorf("read error (read %d bytes)", ret); - goto out; - } - - if (out_fd != -1) { - done += ret; - if ((ret = write(out_fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - perrorf("write error (written %d bytes)", ret); - ret = 1; - goto out; - } - } else { - hexdumpoffset(buf, chip_params.page_size, done); - done += ret; - } - } - -out: - g_close(fd); - if (out_fd != -1) - close(out_fd); - if (buf) - free(buf); - - return (ret); -} - diff --git a/usr.sbin/nandtool/nand_readoob.c b/usr.sbin/nandtool/nand_readoob.c deleted file mode 100644 index 6c5bb372c3e0..000000000000 --- a/usr.sbin/nandtool/nand_readoob.c +++ /dev/null @@ -1,113 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <libgeom.h> -#include <sys/types.h> -#include <sys/disk.h> -#include <dev/nand/nand_dev.h> -#include "nandtool.h" - -int nand_read_oob(struct cmd_param *params) -{ - struct chip_param_io chip_params; - struct nand_oob_rw req; - char *dev, *out; - int fd = -1, fd_out = -1, ret = 0; - int page; - uint8_t *buf = NULL; - - if ((page = param_get_int(params, "page")) < 0) { - fprintf(stderr, "You must supply valid 'page' argument.\n"); - return (1); - } - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "You must supply 'dev' argument.\n"); - return (1); - } - - if ((out = param_get_string(params, "out"))) { - if ((fd_out = open(out, O_WRONLY | O_CREAT, 0666)) == -1) { - perrorf("Cannot open %s", out); - ret = 1; - goto out; - } - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - buf = malloc(chip_params.oob_size); - if (buf == NULL) { - perrorf("Cannot allocate %d bytes\n", chip_params.oob_size); - ret = 1; - goto out; - } - - req.page = page; - req.len = chip_params.oob_size; - req.data = buf; - - if (ioctl(fd, NAND_IO_OOB_READ, &req) == -1) { - perrorf("Cannot read OOB from %s", dev); - ret = 1; - goto out; - } - - if (fd_out != -1) - write(fd_out, buf, chip_params.oob_size); - else - hexdump(buf, chip_params.oob_size); - -out: - close(fd_out); - - if (fd != -1) - g_close(fd); - if (buf) - free(buf); - - return (ret); -} - diff --git a/usr.sbin/nandtool/nand_write.c b/usr.sbin/nandtool/nand_write.c deleted file mode 100644 index 481f1a453538..000000000000 --- a/usr.sbin/nandtool/nand_write.c +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <libgeom.h> -#include <sys/disk.h> -#include <dev/nand/nand_dev.h> -#include "nandtool.h" - -int nand_write(struct cmd_param *params) -{ - struct chip_param_io chip_params; - char *dev, *file; - int in_fd = -1, ret = 0, done = 0; - int fd, block_size, mult, pos, count; - uint8_t *buf = NULL; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "Please supply 'dev' argument.\n"); - return (1); - } - - if (!(file = param_get_string(params, "in"))) { - fprintf(stderr, "Please supply 'in' argument.\n"); - return (1); - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - return (1); - } - - if ((in_fd = open(file, O_RDONLY)) == -1) { - perrorf("Cannot open file %s", file); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - block_size = chip_params.page_size * chip_params.pages_per_block; - - if (param_has_value(params, "page")) { - pos = chip_params.page_size * param_get_int(params, "page"); - mult = chip_params.page_size; - } else if (param_has_value(params, "block")) { - pos = block_size * param_get_int(params, "block"); - mult = block_size; - } else if (param_has_value(params, "pos")) { - pos = param_get_int(params, "pos"); - mult = 1; - if (pos % chip_params.page_size) { - fprintf(stderr, "Position must be page-size " - "aligned!\n"); - ret = 1; - goto out; - } - } else { - fprintf(stderr, "You must specify one of: 'block', 'page'," - "'pos' arguments\n"); - ret = 1; - goto out; - } - - if (!(param_has_value(params, "count"))) - count = mult; - else - count = param_get_int(params, "count") * mult; - - if (!(buf = malloc(chip_params.page_size))) { - perrorf("Cannot allocate buffer [size %x]", - chip_params.page_size); - ret = 1; - goto out; - } - - lseek(fd, pos, SEEK_SET); - - while (done < count) { - if ((ret = read(in_fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - if (ret > 0) { - /* End of file ahead, truncate here */ - break; - } else { - perrorf("Cannot read from %s", file); - ret = 1; - goto out; - } - } - - if ((ret = write(fd, buf, chip_params.page_size)) != - (int32_t)chip_params.page_size) { - ret = 1; - goto out; - } - - done += ret; - } - -out: - g_close(fd); - if (in_fd != -1) - close(in_fd); - if (buf) - free(buf); - - return (ret); -} - diff --git a/usr.sbin/nandtool/nand_writeoob.c b/usr.sbin/nandtool/nand_writeoob.c deleted file mode 100644 index f1143b8a382a..000000000000 --- a/usr.sbin/nandtool/nand_writeoob.c +++ /dev/null @@ -1,115 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#include <fcntl.h> -#include <libgeom.h> -#include <sys/disk.h> -#include <dev/nand/nand_dev.h> -#include "nandtool.h" - -int nand_write_oob(struct cmd_param *params) -{ - struct chip_param_io chip_params; - struct nand_oob_rw req; - char *dev, *in; - int fd = -1, fd_in = -1, ret = 0; - uint8_t *buf = NULL; - int page; - - if (!(dev = param_get_string(params, "dev"))) { - fprintf(stderr, "Please supply valid 'dev' parameter.\n"); - return (1); - } - - if (!(in = param_get_string(params, "in"))) { - fprintf(stderr, "Please supply valid 'in' parameter.\n"); - return (1); - } - - if ((page = param_get_int(params, "page")) < 0) { - fprintf(stderr, "Please supply valid 'page' parameter.\n"); - return (1); - } - - if ((fd = g_open(dev, 1)) == -1) { - perrorf("Cannot open %s", dev); - return (1); - } - - if ((fd_in = open(in, O_RDONLY)) == -1) { - perrorf("Cannot open %s", in); - ret = 1; - goto out; - } - - if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { - perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); - ret = 1; - goto out; - } - - buf = malloc(chip_params.oob_size); - if (buf == NULL) { - perrorf("Cannot allocate %d bytes\n", chip_params.oob_size); - ret = 1; - goto out; - } - - if (read(fd_in, buf, chip_params.oob_size) == -1) { - perrorf("Cannot read from %s", in); - ret = 1; - goto out; - } - - req.page = page; - req.len = chip_params.oob_size; - req.data = buf; - - if (ioctl(fd, NAND_IO_OOB_PROG, &req) == -1) { - perrorf("Cannot write OOB to %s", dev); - ret = 1; - goto out; - } - -out: - g_close(fd); - if (fd_in != -1) - close(fd_in); - if (buf) - free(buf); - - return (ret); -} - - diff --git a/usr.sbin/nandtool/nandtool.8 b/usr.sbin/nandtool/nandtool.8 deleted file mode 100644 index 8f8f1deffddf..000000000000 --- a/usr.sbin/nandtool/nandtool.8 +++ /dev/null @@ -1,184 +0,0 @@ -.\" Copyright (c) 2010 Semihalf -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" $FreeBSD$ -.\" -.Dd April 10, 2012 -.Dt NANDTOOL 8 -.Os -.Sh NAME -.Nm nandtool -.Nd NAND devices swiss army knife -.Sh SYNOPSIS -.Nm -.Ar command -.Op Ar operands ... -.Sh DESCRIPTION -The -.Nm -utility can be used to perform various operations on -.Xr gnand 4 -devices (read, write, erase, -read and write OOB area and to get info about NAND flash chip). -.Pp -The following commands are available: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm read Ns -Read pages from NAND device. -.It Cm write Ns -Write pages to NAND device. -.It Cm erase Ns -Erase blocks. -Requires offset aligned to block granularity. -.It Cm info Ns -Get information about NAND chip (page size, block size, OOB area size, chip size -and media size) -.It Cm readoob Ns -Read OOB area from specified page. -.It Cm writeoob Ns -Write OOB area bound to specified page. -.It Cm help Ns -Get usage info. -.El -.Sh COMMAND read -The following operands are available for -.Nm -.Cm read -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar <path> -Path to a -.Xr gnand 4 -device node, required for all operations. -.It Cm out Ns = Ns Ar <file> -Output file path. If not specified, page contents -will be dumped to stdout in format similar to -.Xr hexdump 1 -.It Cm page Ns = Ns Ar <n> -Offset on device, expressed as page number. -.It Cm block Ns = Ns Ar <n> -Offset on device, expressed as block number. -.It Cm pos Ns = Ns Ar <n> -Offset on device, expressed in bytes (however, must be aligned -to page granularity). -.It Cm count Ns = Ns Ar <n> -Count of objects (pages, blocks, bytes). -.El -.Sh COMMAND readoob -The following operands are available for -.Nm -.Cm readoob -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar <path> -Path to NAND device node. -.It Cm page Ns = Ns Ar <n> -Offset on device, expressed as page number. -.It Cm out Ns = Ns Ar <file> -Output file path, optional. -.El -.Sh COMMAND write -The following operands are available for -.Nm -.Cm write -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar <path> -Path to NAND device node. -.It Cm page Ns = Ns Ar <n> -Offset on device, expressed as page number. -.It Cm block Ns = Ns Ar <n> -Offset on device, expressed as block number. -.It Cm pos Ns = Ns Ar <n> -Offset on device, expressed in bytes (however, must be aligned -to page granularity). -.It Cm in Ns = Ns Ar <file> -Input file path. -.El -.Sh COMMAND writeoob -The following operands are available for -.Nm -.Cm writeoob -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar <path> -Path to NAND device node. -.It Cm page Ns = Ns Ar <n> -Offset on device, expressed as page number. -.It Cm in Ns = Ns Ar <file> -Input file path. -.El -.Sh COMMAND erase -The following operands are available for -.Nm -.Cm erase -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar <path> -Path to NAND device node. -.It Cm page Ns = Ns Ar <n> -Offset on device, expressed as page number. -.It Cm block Ns = Ns Ar <n> -Offset on device, expressed as block number. -.It Cm pos Ns = Ns Ar <n> -Offset on device, epressed in bytes (however, must be aligned -to block granularity). -.It Cm count Ns = Ns Ar <n> -Count of objects (pages, blocks, bytes). -.El -.Pp -WARNING: The only required parameter for the \fBerase\fP command is -.Ar dev . -When no other arguments are provided the whole device is erased! -.Sh COMMAND info -There is only one operand available for -.Nm -.Cm info -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm dev Ns = Ns Ar <path> -Path to NAND device node. -.El -.Sh COMMAND help -There is only one operand available for -.Nm -.Cm help -command: -.Bl -tag -width ".Cm of Ns = Ns Ar file" -.It Cm topic Ns = Ns Ar <name> -Help topic. -.El -.Sh EXIT STATUS -.Ex -std -If the supplied argument -.Ar dev -points to a device node other than gnand<num> or gnand.raw<num> both -.Nm -.Cm readoob -and -.Nm -.Cm writeoob -return error. -.Sh SEE ALSO -.Xr gnand 4 diff --git a/usr.sbin/nandtool/nandtool.c b/usr.sbin/nandtool/nandtool.c deleted file mode 100644 index e87ed7342e6d..000000000000 --- a/usr.sbin/nandtool/nandtool.c +++ /dev/null @@ -1,285 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <sys/cdefs.h> -__FBSDID("$FreeBSD$"); - -#include <errno.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <stdarg.h> -#include <ctype.h> -#include <sysexits.h> -#include <libgeom.h> -#include "nandtool.h" -#include "usage.h" - -int usage(struct cmd_param *); - -static const struct { - const char *name; - const char *usage; - int (*handler)(struct cmd_param *); -} commands[] = { - { "help", nand_help_usage, usage }, - { "read", nand_read_usage, nand_read }, - { "write", nand_write_usage, nand_write }, - { "erase", nand_erase_usage, nand_erase }, - { "readoob", nand_read_oob_usage, nand_read_oob }, - { "writeoob", nand_write_oob_usage, nand_write_oob }, - { "info", nand_info_usage, nand_info }, - { NULL, NULL, NULL }, -}; - -static char * -_param_get_stringx(struct cmd_param *params, const char *name, int doexit) -{ - int i; - - for (i = 0; params[i].name[0] != '\0'; i++) { - if (!strcmp(params[i].name, name)) - return params[i].value; - } - - if (doexit) { - perrorf("Missing parameter %s", name); - exit(1); - } - return (NULL); -} - -char * -param_get_string(struct cmd_param *params, const char *name) -{ - - return (_param_get_stringx(params, name, 0)); -} - -static int -_param_get_intx(struct cmd_param *params, const char *name, int doexit) -{ - int ret; - char *str = _param_get_stringx(params, name, doexit); - - if (!str) - return (-1); - - errno = 0; - ret = (int)strtol(str, (char **)NULL, 10); - if (errno) { - if (doexit) { - perrorf("Invalid value for parameter %s", name); - exit(1); - } - return (-1); - } - - return (ret); -} - -int -param_get_intx(struct cmd_param *params, const char *name) -{ - - return (_param_get_intx(params, name, 1)); -} - -int -param_get_int(struct cmd_param *params, const char *name) -{ - - return (_param_get_intx(params, name, 0)); -} - -int -param_get_boolean(struct cmd_param *params, const char *name) -{ - char *str = param_get_string(params, name); - - if (!str) - return (0); - - if (!strcmp(str, "true") || !strcmp(str, "yes")) - return (1); - - return (0); -} - -int -param_has_value(struct cmd_param *params, const char *name) -{ - int i; - - for (i = 0; params[i].name[0] != '\0'; i++) { - if (!strcmp(params[i].name, name)) - return (1); - } - - return (0); -} - -int -param_get_count(struct cmd_param *params) -{ - int i; - - for (i = 0; params[i].name[0] != '\0'; i++); - - return (i); -} - -void -hexdumpoffset(uint8_t *buf, int length, int off) -{ - int i, j; - for (i = 0; i < length; i += 16) { - printf("%08x: ", off + i); - - for (j = 0; j < 16; j++) - printf("%02x ", buf[i+j]); - - printf("| "); - - for (j = 0; j < 16; j++) { - printf("%c", isalnum(buf[i+j]) - ? buf[i+j] - : '.'); - } - - printf("\n"); - } -} - -void -hexdump(uint8_t *buf, int length) -{ - - hexdumpoffset(buf, length, 0); -} - -void * -xmalloc(size_t len) -{ - void *ret = malloc(len); - - if (!ret) { - fprintf(stderr, "Cannot allocate buffer of %zd bytes. " - "Exiting.\n", len); - exit(EX_OSERR); - } - - return (ret); -} - -void -perrorf(const char *format, ...) -{ - va_list args; - - va_start(args, format); - vfprintf(stderr, format, args); - va_end(args); - fprintf(stderr, ": %s\n", strerror(errno)); -} - -int -usage(struct cmd_param *params) -{ - int i; - - if (!params || !param_get_count(params)) { - fprintf(stderr, "Usage: nandtool <command> [arguments...]\n"); - fprintf(stderr, "Arguments are in form 'name=value'.\n\n"); - fprintf(stderr, "Available commands:\n"); - - for (i = 0; commands[i].name != NULL; i++) - fprintf(stderr, "\t%s\n", commands[i].name); - - fprintf(stderr, "\n"); - fprintf(stderr, "For information about particular command, " - "type:\n"); - fprintf(stderr, "'nandtool help topic=<command>'\n"); - } else if (param_has_value(params, "topic")) { - for (i = 0; commands[i].name != NULL; i++) { - if (!strcmp(param_get_string(params, "topic"), - commands[i].name)) { - fprintf(stderr, commands[i].usage, "nandtool"); - return (0); - } - } - - fprintf(stderr, "No such command\n"); - return (EX_SOFTWARE); - } else { - fprintf(stderr, "Wrong arguments given. Try: 'nandtool help'\n"); - } - - return (EX_USAGE); -} - -int -main(int argc, const char *argv[]) -{ - struct cmd_param *params; - int i, ret, idx; - - if (argc < 2) { - usage(NULL); - return (0); - } - - params = malloc(sizeof(struct cmd_param) * (argc - 1)); - - for (i = 2, idx = 0; i < argc; i++, idx++) { - if (sscanf(argv[i], "%63[^=]=%63s", params[idx].name, - params[idx].value) < 2) { - fprintf(stderr, "Syntax error in argument %d. " - "Argument should be in form 'name=value'.\n", i); - free(params); - return (-1); - } - } - - params[idx].name[0] = '\0'; - params[idx].value[0] = '\0'; - - for (i = 0; commands[i].name != NULL; i++) { - if (!strcmp(commands[i].name, argv[1])) { - ret = commands[i].handler(params); - free(params); - return (ret); - } - } - - free(params); - fprintf(stderr, "Unknown command. Try '%s help'\n", argv[0]); - - return (-1); -} - diff --git a/usr.sbin/nandtool/nandtool.h b/usr.sbin/nandtool/nandtool.h deleted file mode 100644 index c0dd1c095444..000000000000 --- a/usr.sbin/nandtool/nandtool.h +++ /dev/null @@ -1,59 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef __UTILS_H -#define __UTILS_H - -struct cmd_param -{ - char name[64]; - char value[64]; -}; - -char *param_get_string(struct cmd_param *, const char *); -int param_get_int(struct cmd_param *, const char *); -int param_get_intx(struct cmd_param *, const char *); -int param_get_boolean(struct cmd_param *, const char *); -int param_has_value(struct cmd_param *, const char *); -int param_get_count(struct cmd_param *); -void perrorf(const char *, ...); -void hexdumpoffset(uint8_t *, int, int); -void hexdump(uint8_t *, int); -void *xmalloc(size_t); - -/* Command handlers */ -int nand_read(struct cmd_param *); -int nand_write(struct cmd_param *); -int nand_read_oob(struct cmd_param *); -int nand_write_oob(struct cmd_param *); -int nand_erase(struct cmd_param *); -int nand_info(struct cmd_param *); - -#endif /* __UTILS_H */ diff --git a/usr.sbin/nandtool/usage.h b/usr.sbin/nandtool/usage.h deleted file mode 100644 index 0dbb70a2c99d..000000000000 --- a/usr.sbin/nandtool/usage.h +++ /dev/null @@ -1,114 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 2010-2012 Semihalf. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#ifndef __USAGE_H -#define __USAGE_H - -static const char nand_help_usage[] = - "Usage: %s help topic=<cmd>\n" - "\n" - "Arguments:\n" - "\tcmd\t- [help|read|write|erase|readoob|writeoob|info]\n" - "\n"; - -static const char nand_read_usage[] = - "Usage: %s read dev=<gnand_device> (block|page|pos)=n [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tblock\t- starting block or\n" - "\tpage\t- starting page or\n" - "\tpos\t- starting position (in bytes, must be page-aligned)\n" - "\tout\t- output file (hexdump to stdout if not supplied)\n" - "\n" - "Note that you can only specify only one of: 'block', 'page', 'pos'\n" - "parameters at once. 'count' parameter is meaningful in terms of used\n" - "unit (page, block or byte).\n"; - -static const char nand_write_usage[] = - "Usage: %s write dev=<gnand_device> in=<file> (block|page|pos)=n [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tin\t- path to input file which be writed to gnand\n" - "\tblock\t- starting block or\n" - "\tpage\t- starting page or\n" - "\tpos\t- starting position (in bytes, must be page-aligned)\n" - "\tcount\t- byte/page/block count\n" - "\n" - ""; - -static const char nand_erase_usage[] = - "Usage: %s erase dev=<gnand_device> (block|page|pos)=n [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tblock\t- starting block or\n" - "\tpage\t- starting page or\n" - "\tpos\t- starting position (in bytes, muse be block-aligned)\n" - "\tcount\t- byte/page/block count\n" - "\n" - "NOTE: position and count for erase operation MUST be block-aligned\n"; - -static const char nand_read_oob_usage[] = - "Usage: %s readoob dev=<gnand_device> page=n [out=file] [count=n]\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n" - "\tpage\t- page (page) number\n" - "\tout\t- outut file (hexdump to stdout if not supplied)\n" - "\tcount\t- page count (default is 1)\n" - "\n" - "If you supply count parameter with value other than 1, data will be\n" - "read from subsequent page's OOB areas\n"; - -static const char nand_write_oob_usage[] = - "Usage: %s writeoob dev=<gnand_device> in=<file> page=n [count=n]\n" - "\n" - "\tdev\t- path to gnand device node\n" - "\tin\t- path to file containing data which will be written\n" - "\tpage\t- page (page) number\n" - "\n" - "If you supply count parameter with value other than 1, data will be\n" - "written to subsequent page's OOB areas\n"; - -static const char nand_info_usage[] = - "Usage: %s info dev=<gnand_device>\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n"; - -static const char nand_stats_usage[] = - "Usage: %s stats dev=<gnand_device> (page|block)=<n>\n" - "\n" - "Arguments:\n" - "\tdev\t- path to gnand device node\n"; - -#endif /* __USAGE_H */ |
