[alsa-devel] [snd-asihpi 0/8] Updates to snd-asihpi driver
Patch 4 is main change, allowing older cards to be accessed using mmap, incidentally simplifying the driver by removing copy&silence callbacks.
Others are small improvements and updates.
This version has been tested with aplay/arecord, and with portaudio applications.
pci/asihpi/asihpi.c | 328 +++++++++++++++++++------------------------- pci/asihpi/hpi.h | 15 +- pci/asihpi/hpi6000.c | 39 ++---- pci/asihpi/hpi6205.c | 97 +++++++------- pci/asihpi/hpi_internal.h | 19 +-- pci/asihpi/hpicmn.c | 10 +- pci/asihpi/hpicmn.h | 2 + pci/asihpi/hpifunc.c | 27 ---- pci/asihpi/hpimsgx.c | 31 ++--- pci/asihpi/hpioctl.c | 63 +++++----- pci/asihpi/hpios.h | 2 +
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/asihpi.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index f53a31e..edcbe39 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -1413,14 +1413,16 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, struct hpi_control *hpi_ctl, char *name) { - char *dir = ""; + char *dir; memset(snd_control, 0, sizeof(*snd_control)); snd_control->name = hpi_ctl->name; snd_control->private_value = hpi_ctl->h_control; snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; snd_control->index = 0;
- if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) + if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE) + dir = ""; /* clock is neither capture nor playback */ + else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) dir = "Capture "; /* On or towards a PCM capture destination*/ else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && (!hpi_ctl->dst_node_type)) @@ -1433,7 +1435,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, dir = "Playback "; /* PCM Playback source, or output node */
if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) - sprintf(hpi_ctl->name, "%s%d %s%d %s%s", + sprintf(hpi_ctl->name, "%s %d %s %d %s%s", asihpi_src_names[hpi_ctl->src_node_type], hpi_ctl->src_node_index, asihpi_dst_names[hpi_ctl->dst_node_type],
At Fri, 01 Apr 2011 15:59:45 +1300, linux@audioscience.com wrote:
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com
In general to all your patches, please reduce the summary line, i.e. a concise headline and more details in the changelog.
thanks,
Takashi
pci/asihpi/asihpi.c | 8 +++++--- 1 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index f53a31e..edcbe39 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -1413,14 +1413,16 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, struct hpi_control *hpi_ctl, char *name) {
- char *dir = "";
- char *dir; memset(snd_control, 0, sizeof(*snd_control)); snd_control->name = hpi_ctl->name; snd_control->private_value = hpi_ctl->h_control; snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; snd_control->index = 0;
- if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM)
- if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE)
dir = ""; /* clock is neither capture nor playback */
- else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) dir = "Capture "; /* On or towards a PCM capture destination*/ else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && (!hpi_ctl->dst_node_type))
@@ -1433,7 +1435,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, dir = "Playback "; /* PCM Playback source, or output node */
if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type)
sprintf(hpi_ctl->name, "%s%d %s%d %s%s",
sprintf(hpi_ctl->name, "%s %d %s %d %s%s", asihpi_src_names[hpi_ctl->src_node_type], hpi_ctl->src_node_index, asihpi_dst_names[hpi_ctl->dst_node_type],
-- 1.7.0.4
On 02/04/11 02:09, Takashi Iwai wrote:
At Fri, 01 Apr 2011 15:59:45 +1300, linux@audioscience.com wrote:
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com
In general to all your patches, please reduce the summary line, i.e. a concise headline and more details in the changelog.
Hi Takashi,
is this a request to regenerate my patchset, or just general advice?
regards
Eliot
At Tue, 05 Apr 2011 11:58:49 +1200, Eliot Blennerhassett wrote:
On 02/04/11 02:09, Takashi Iwai wrote:
At Fri, 01 Apr 2011 15:59:45 +1300, linux@audioscience.com wrote:
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com
In general to all your patches, please reduce the summary line, i.e. a concise headline and more details in the changelog.
Hi Takashi,
is this a request to regenerate my patchset, or just general advice?
Please resend the patches.
thanks,
Takashi
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/asihpi.c | 102 ++++++++++++++++++++++++++++----------------------- 1 files changed, 56 insertions(+), 46 deletions(-)
diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index edcbe39..434342f 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -57,8 +57,25 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); */ #define snd_printddd(format, args...) \ __snd_printk(3, __FILE__, __LINE__, format, ##args) + +/* copied from pcm_lib.c, hope later patch will make that version public +and this copy can be removed */ +static void pcm_debug_name(struct snd_pcm_substream *substream, + char *name, size_t len) +{ + snprintf(name, len, "pcmC%dD%d%c:%d", + substream->pcm->card->number, + substream->pcm->device, + substream->stream ? 'c' : 'p', + substream->number); +} +#define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name)) + #else -#define snd_printddd(format, args...) do { } while (0) +#define snd_printddd(format, args...) do { } while (0) +#define pcm_debug_name(s, n, l) do { } while (0) +#define DEBUG_NAME(name, substream) do { } while (0) + #endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ @@ -101,13 +118,6 @@ static int adapter_fs = DEFAULT_SAMPLERATE; #define PERIOD_BYTES_MIN 2048 #define BUFFER_BYTES_MAX (512 * 1024)
-/* convert stream to character */ -#define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C') - -/*#define TIMER_MILLISECONDS 20 -#define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000) -*/ - #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7)
struct clk_source { @@ -288,19 +298,26 @@ static u16 handle_error(u16 err, int line, char *filename) #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__)
/***************************** GENERAL PCM ****************/ -static void print_hwparams(struct snd_pcm_hw_params *p) + +static void print_hwparams(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *p) { - snd_printd("HWPARAMS \n"); - snd_printd("samplerate %d \n", params_rate(p)); - snd_printd("Channels %d \n", params_channels(p)); - snd_printd("Format %d \n", params_format(p)); - snd_printd("subformat %d \n", params_subformat(p)); - snd_printd("Buffer bytes %d \n", params_buffer_bytes(p)); - snd_printd("Period bytes %d \n", params_period_bytes(p)); - snd_printd("access %d \n", params_access(p)); - snd_printd("period_size %d \n", params_period_size(p)); - snd_printd("periods %d \n", params_periods(p)); - snd_printd("buffer_size %d \n", params_buffer_size(p)); + DEBUG_NAME(substream, name); + snd_printd("%s HWPARAMS\n", name); + snd_printd(" samplerate %d Hz\n", params_rate(p)); + snd_printd(" channels %d\n", params_channels(p)); + snd_printd(" format %d\n", params_format(p)); + snd_printd(" subformat %d\n", params_subformat(p)); + snd_printd(" buffer %d B\n", params_buffer_bytes(p)); + snd_printd(" period %d B\n", params_period_bytes(p)); + snd_printd(" access %d\n", params_access(p)); + snd_printd(" period_size %d\n", params_period_size(p)); + snd_printd(" periods %d\n", params_periods(p)); + snd_printd(" buffer_size %d\n", params_buffer_size(p)); + snd_printd(" %d B/s\n", params_rate(p) * + params_channels(p) * + snd_pcm_format_width(params_format(p)) / 8); + }
static snd_pcm_format_t hpi_to_alsa_formats[] = { @@ -451,7 +468,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, int width; unsigned int bytes_per_sec;
- print_hwparams(params); + print_hwparams(substream, params); err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); if (err < 0) return err; @@ -459,10 +476,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, if (err) return err;
- snd_printdd("format %d, %d chans, %d_hz\n", - format, params_channels(params), - params_rate(params)); - hpi_handle_error(hpi_format_create(&dpcm->format, params_channels(params), format, params_rate(params), 0, 0)); @@ -509,8 +522,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, dpcm->bytes_per_sec = bytes_per_sec; dpcm->buffer_bytes = params_buffer_bytes(params); dpcm->period_bytes = params_period_bytes(params); - snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n", - dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec);
return 0; } @@ -564,9 +575,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); struct snd_pcm_substream *s; u16 e; + DEBUG_NAME(substream, name); + + snd_printdd("%s trigger\n", name);
- snd_printdd("%c%d trigger\n", - SCHR(substream->stream), substream->number); switch (cmd) { case SNDRV_PCM_TRIGGER_START: snd_pcm_group_for_each_entry(s, substream) { @@ -599,9 +611,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, }
if (card->support_grouping) { - snd_printdd("\t%c%d group\n", - SCHR(s->stream), - s->number); + snd_printdd("%d group\n", s->number); e = hpi_stream_group_add( dpcm->h_stream, ds->h_stream); @@ -636,9 +646,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, s->runtime->status->state = SNDRV_PCM_STATE_SETUP;
if (card->support_grouping) { - snd_printdd("\t%c%d group\n", - SCHR(s->stream), - s->number); + snd_printdd("%d group\n", s->number); snd_pcm_trigger_done(s, substream); } else break; @@ -732,9 +740,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) int loops = 0; u16 state; u32 buffer_size, bytes_avail, samples_played, on_card_bytes; + DEBUG_NAME(substream, name);
- snd_printdd("%c%d snd_card_asihpi_timer_function\n", - SCHR(substream->stream), substream->number); + snd_printdd("%s snd_card_asihpi_timer_function\n", name);
/* find minimum newdata and buffer pos in group */ snd_pcm_group_for_each_entry(s, substream) { @@ -786,16 +794,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) newdata); }
- snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", + snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n", (unsigned long)frames_to_bytes(runtime, runtime->status->hw_ptr), (unsigned long)frames_to_bytes(runtime, runtime->control->appl_ptr));
- snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," - " aux=x%04X space=x%04X\n", - loops, SCHR(s->stream), s->number, - state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, + snd_printdd("%d S=%d, " + "rw=0x%04X, dma=0x%04X, left=0x%04X, " + "aux=0x%04X space=0x%04X\n", + s->number, state, + ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, + (int)bytes_avail, (int)on_card_bytes, buffer_size-bytes_avail); loops++; } @@ -814,7 +824,7 @@ static void snd_card_asihpi_timer_function(unsigned long data)
next_jiffies = max(next_jiffies, 1U); dpcm->timer.expires = jiffies + next_jiffies; - snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", + snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n", next_jiffies, pcm_buf_dma_ofs, newdata, xfercount);
snd_pcm_group_for_each_entry(s, substream) { @@ -863,7 +873,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) { - snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); + snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd); return snd_pcm_lib_ioctl(substream, cmd, arg); }
@@ -873,7 +883,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * struct snd_pcm_runtime *runtime = substream->runtime; struct snd_card_asihpi_pcm *dpcm = runtime->private_data;
- snd_printdd("playback prepare %d\n", substream->number); + snd_printdd("P%d prepare\n", substream->number);
hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); dpcm->pcm_buf_host_rw_ofs = 0; @@ -890,7 +900,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) snd_pcm_uframes_t ptr;
ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); - snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); + snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr); return ptr; }
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/asihpi.c | 12 ++++++++++-- 1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index 434342f..a5226e3 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -165,6 +165,7 @@ struct snd_card_asihpi_pcm { unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ + unsigned int drained_count; struct snd_pcm_substream *substream; u32 h_stream; struct hpi_format format; @@ -592,6 +593,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, if (substream->stream != s->stream) continue;
+ ds->drained_count = 0; if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && (card->support_mmap)) { /* How do I know how much valid data is present @@ -771,12 +773,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { hpi_handle_error(hpi_stream_start(ds->h_stream)); snd_printdd("P%d start\n", s->number); + ds->drained_count = 0; } } else if (state == HPI_STATE_DRAINED) { snd_printd(KERN_WARNING "P%d drained\n", s->number); - /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); - continue; */ + ds->drained_count++; + if (ds->drained_count > 2) { + snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); + continue; + } + } else { + ds->drained_count = 0; } } else pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs;
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/asihpi.c | 205 +++++++++++++++++--------------------------------- 1 files changed, 70 insertions(+), 135 deletions(-)
diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index a5226e3..d5258aa 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -42,6 +42,7 @@ #include <sound/tlv.h> #include <sound/hwdep.h>
+ MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. support@audioscience.com"); MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); @@ -146,7 +147,7 @@ struct snd_card_asihpi { u32 h_mixer; struct clk_cache cc;
- u16 support_mmap; + u16 can_dma; u16 support_grouping; u16 support_mrx; u16 update_interval_frames; @@ -491,8 +492,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, }
dpcm->hpi_buffer_attached = 0; - if (card->support_mmap) { - + if (card->can_dma) { err = hpi_stream_host_buffer_attach(dpcm->h_stream, params_buffer_bytes(params), runtime->dma_addr); if (err == 0) { @@ -594,8 +594,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, continue;
ds->drained_count = 0; - if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && - (card->support_mmap)) { + if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { /* How do I know how much valid data is present * in buffer? Must be at least one period! * Guessing 2 periods, but if @@ -630,7 +629,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, /* start the master stream */ snd_card_asihpi_pcm_timer_start(substream); if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || - !card->support_mmap) + !card->can_dma) hpi_handle_error(hpi_stream_start(dpcm->h_stream)); break;
@@ -766,6 +765,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) /* number of bytes in on-card buffer */ runtime->delay = on_card_bytes;
+ if (!card->can_dma) + on_card_bytes = bytes_avail; + if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; if (state == HPI_STATE_STOPPED) { @@ -844,30 +846,63 @@ static void snd_card_asihpi_timer_function(unsigned long data)
ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs;
- if (xfercount && (on_card_bytes <= ds->period_bytes)) { - if (card->support_mmap) { - if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { - snd_printddd("P%d write x%04x\n", + if (xfercount && + /* Limit use of on card fifo for playback */ + ((on_card_bytes <= ds->period_bytes) || + (s->stream == SNDRV_PCM_STREAM_CAPTURE))) + + { + + unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes; + unsigned int xfer1, xfer2; + char *pd = &s->runtime->dma_area[buf_ofs]; + + if (card->can_dma) { + xfer1 = xfercount; + xfer2 = 0; + } else { + xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs); + xfer2 = xfercount - xfer1; + } + + if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { + snd_printddd("P%d write1 0x%04X 0x%04X\n", + s->number, xfer1, buf_ofs); + hpi_handle_error( + hpi_outstream_write_buf( + ds->h_stream, pd, xfer1, + &ds->format)); + + if (xfer2) { + pd = s->runtime->dma_area; + + snd_printddd("P%d write2 0x%04X 0x%04X\n", s->number, - ds->period_bytes); + xfercount - xfer1, buf_ofs); hpi_handle_error( hpi_outstream_write_buf( - ds->h_stream, - &s->runtime-> - dma_area[0], - xfercount, + ds->h_stream, pd, + xfercount - xfer1, &ds->format)); - } else { - snd_printddd("C%d read x%04x\n", - s->number, - xfercount); + } + } else { + snd_printddd("C%d read1 0x%04x\n", + s->number, xfer1); + hpi_handle_error( + hpi_instream_read_buf( + ds->h_stream, + pd, xfer1)); + if (xfer2) { + pd = s->runtime->dma_area; + snd_printddd("C%d read2 0x%04x\n", + s->number, xfer2); hpi_handle_error( hpi_instream_read_buf( ds->h_stream, - NULL, xfercount)); + pd, xfer2)); } - ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; - } /* else R/W will be handled by read/write callbacks */ + } + ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; snd_pcm_period_elapsed(s); } @@ -1004,11 +1039,9 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) SNDRV_PCM_INFO_DOUBLE | SNDRV_PCM_INFO_BATCH | SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_PAUSE; - - if (card->support_mmap) - snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID; + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID;
if (card->support_grouping) snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; @@ -1016,7 +1049,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) /* struct is copied, so can create initializer dynamically */ runtime->hw = snd_card_asihpi_playback;
- if (card->support_mmap) + if (card->can_dma) err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); if (err < 0) @@ -1046,58 +1079,6 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) return 0; }
-static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream, - int channel, - snd_pcm_uframes_t pos, - void __user *src, - snd_pcm_uframes_t count) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - unsigned int len; - - len = frames_to_bytes(runtime, count); - - if (copy_from_user(runtime->dma_area, src, len)) - return -EFAULT; - - snd_printddd("playback copy%d %u bytes\n", - substream->number, len); - - hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, - runtime->dma_area, len, &dpcm->format)); - - dpcm->pcm_buf_host_rw_ofs += len; - - return 0; -} - -static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * - substream, int channel, - snd_pcm_uframes_t pos, - snd_pcm_uframes_t count) -{ - /* Usually writes silence to DMA buffer, which should be overwritten - by real audio later. Our fifos cannot be overwritten, and are not - free-running DMAs. Silence is output on fifo underflow. - This callback is still required to allow the copy callback to be used. - */ - return 0; -} - -static struct snd_pcm_ops snd_card_asihpi_playback_ops = { - .open = snd_card_asihpi_playback_open, - .close = snd_card_asihpi_playback_close, - .ioctl = snd_card_asihpi_playback_ioctl, - .hw_params = snd_card_asihpi_pcm_hw_params, - .hw_free = snd_card_asihpi_hw_free, - .prepare = snd_card_asihpi_playback_prepare, - .trigger = snd_card_asihpi_trigger, - .pointer = snd_card_asihpi_playback_pointer, - .copy = snd_card_asihpi_playback_copy, - .silence = snd_card_asihpi_playback_silence, -}; - static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { .open = snd_card_asihpi_playback_open, .close = snd_card_asihpi_playback_close, @@ -1229,18 +1210,16 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) snd_card_asihpi_capture_format(card, dpcm->h_stream, &snd_card_asihpi_capture); snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); - snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; - - if (card->support_mmap) - snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID; + snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID;
if (card->support_grouping) snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START;
runtime->hw = snd_card_asihpi_capture;
- if (card->support_mmap) + if (card->can_dma) err = snd_pcm_hw_constraint_pow2(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_BYTES); if (err < 0) @@ -1264,28 +1243,6 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream) return 0; }
-static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, - int channel, snd_pcm_uframes_t pos, - void __user *dst, snd_pcm_uframes_t count) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_card_asihpi_pcm *dpcm = runtime->private_data; - u32 len; - - len = frames_to_bytes(runtime, count); - - snd_printddd("capture copy%d %d bytes\n", substream->number, len); - hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, - runtime->dma_area, len)); - - dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; - - if (copy_to_user(dst, runtime->dma_area, len)) - return -EFAULT; - - return 0; -} - static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { .open = snd_card_asihpi_capture_open, .close = snd_card_asihpi_capture_close, @@ -1297,18 +1254,6 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { .pointer = snd_card_asihpi_capture_pointer, };
-static struct snd_pcm_ops snd_card_asihpi_capture_ops = { - .open = snd_card_asihpi_capture_open, - .close = snd_card_asihpi_capture_close, - .ioctl = snd_card_asihpi_capture_ioctl, - .hw_params = snd_card_asihpi_pcm_hw_params, - .hw_free = snd_card_asihpi_hw_free, - .prepare = snd_card_asihpi_capture_prepare, - .trigger = snd_card_asihpi_trigger, - .pointer = snd_card_asihpi_capture_pointer, - .copy = snd_card_asihpi_capture_copy -}; - static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, int device, int substreams) { @@ -1321,17 +1266,10 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, if (err < 0) return err; /* pointer to ops struct is stored, dont change ops afterwards! */ - if (asihpi->support_mmap) { snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_card_asihpi_playback_mmap_ops); snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_card_asihpi_capture_mmap_ops); - } else { - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_card_asihpi_playback_ops); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, - &snd_card_asihpi_capture_ops); - }
pcm->private_data = asihpi; pcm->info_flags = 0; @@ -2895,14 +2833,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, if (err) asihpi->update_interval_frames = 512;
- if (!asihpi->support_mmap) + if (!asihpi->can_dma) asihpi->update_interval_frames *= 2;
hpi_handle_error(hpi_instream_open(asihpi->adapter_index, 0, &h_stream));
err = hpi_instream_host_buffer_free(h_stream); - asihpi->support_mmap = (!err); + asihpi->can_dma = (!err);
hpi_handle_error(hpi_instream_close(h_stream));
@@ -2914,8 +2852,8 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, asihpi->out_max_chans = 2; }
- snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n", - asihpi->support_mmap, + snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n", + asihpi->can_dma, asihpi->support_grouping, asihpi->support_mrx ); @@ -2945,10 +2883,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, by enable_hwdep module param*/ snd_asihpi_hpi_new(asihpi, 0, NULL);
- if (asihpi->support_mmap) - strcpy(card->driver, "ASIHPI-MMAP"); - else - strcpy(card->driver, "ASIHPI"); + strcpy(card->driver, "ASIHPI");
sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); sprintf(card->longname, "%s %i",
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/hpifunc.c | 27 --------------------------- 1 files changed, 0 insertions(+), 27 deletions(-)
diff --git a/pci/asihpi/hpifunc.c b/pci/asihpi/hpifunc.c index c38fc94..7397b16 100644 --- a/pci/asihpi/hpifunc.c +++ b/pci/asihpi/hpifunc.c @@ -105,33 +105,6 @@ u16 hpi_subsys_get_version_ex(u32 *pversion_ex) return hr.error; }
-u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, - u16 *pw_adapter_index) -{ - struct hpi_message hm; - struct hpi_response hr; - - hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, - HPI_SUBSYS_CREATE_ADAPTER); - hm.u.s.resource = *p_resource; - - hpi_send_recv(&hm, &hr); - - *pw_adapter_index = hr.u.s.adapter_index; - return hr.error; -} - -u16 hpi_subsys_delete_adapter(u16 adapter_index) -{ - struct hpi_message hm; - struct hpi_response hr; - hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, - HPI_SUBSYS_DELETE_ADAPTER); - hm.obj_index = adapter_index; - hpi_send_recv(&hm, &hr); - return hr.error; -} - u16 hpi_subsys_get_num_adapters(int *pn_num_adapters) { struct hpi_message hm;
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/asihpi.c | 31 ++++++++++++++++--------------- 1 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/pci/asihpi/asihpi.c b/pci/asihpi/asihpi.c index d5258aa..eac7b08 100644 --- a/pci/asihpi/asihpi.c +++ b/pci/asihpi/asihpi.c @@ -47,18 +47,7 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("AudioScience inc. support@audioscience.com"); MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx");
-#if defined CONFIG_SND_DEBUG_VERBOSE -/** - * snd_printddd - very verbose debug printk - * @format: format string - * - * Works like snd_printk() for debugging purposes. - * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. - * Must set snd module debug parameter to 3 to enable at runtime. - */ -#define snd_printddd(format, args...) \ - __snd_printk(3, __FILE__, __LINE__, format, ##args) - +#if defined CONFIG_SND_DEBUG /* copied from pcm_lib.c, hope later patch will make that version public and this copy can be removed */ static void pcm_debug_name(struct snd_pcm_substream *substream, @@ -71,12 +60,24 @@ static void pcm_debug_name(struct snd_pcm_substream *substream, substream->number); } #define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name)) - #else -#define snd_printddd(format, args...) do { } while (0) #define pcm_debug_name(s, n, l) do { } while (0) #define DEBUG_NAME(name, substream) do { } while (0) +#endif
+#if defined CONFIG_SND_DEBUG_VERBOSE +/** + * snd_printddd - very verbose debug printk + * @format: format string + * + * Works like snd_printk() for debugging purposes. + * Ignored when CONFIG_SND_DEBUG_VERBOSE is not set. + * Must set snd module debug parameter to 3 to enable at runtime. + */ +#define snd_printddd(format, args...) \ + __snd_printk(3, __FILE__, __LINE__, format, ##args) +#else +#define snd_printddd(format, args...) do { } while (0) #endif
static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ @@ -857,7 +858,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) unsigned int xfer1, xfer2; char *pd = &s->runtime->dma_area[buf_ofs];
- if (card->can_dma) { + if (card->can_dma) { /* buffer wrap is handled at lower level */ xfer1 = xfercount; xfer2 = 0; } else {
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/hpi6000.c | 39 +++++++----------- pci/asihpi/hpi6205.c | 97 +++++++++++++++++++++++---------------------- pci/asihpi/hpi_internal.h | 17 ++++---- pci/asihpi/hpicmn.c | 1 - pci/asihpi/hpimsgx.c | 31 ++++++-------- pci/asihpi/hpioctl.c | 54 +++++++++++++------------ 6 files changed, 113 insertions(+), 126 deletions(-)
diff --git a/pci/asihpi/hpi6000.c b/pci/asihpi/hpi6000.c index 3e3c2ef..09befda 100644 --- a/pci/asihpi/hpi6000.c +++ b/pci/asihpi/hpi6000.c @@ -200,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata, static void subsys_create_adapter(struct hpi_message *phm, struct hpi_response *phr);
-static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr); +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr);
static void adapter_get_asserts(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr); @@ -222,9 +222,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) case HPI_SUBSYS_CREATE_ADAPTER: subsys_create_adapter(phm, phr); break; - case HPI_SUBSYS_DELETE_ADAPTER: - subsys_delete_adapter(phm, phr); - break; default: phr->error = HPI_ERROR_INVALID_FUNC; break; @@ -279,6 +276,10 @@ static void adapter_message(struct hpi_adapter_obj *pao, adapter_get_asserts(pao, phm, phr); break;
+ case HPI_ADAPTER_DELETE: + adapter_delete(pao, phm, phr); + break; + default: hw_message(pao, phm, phr); break; @@ -333,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) { struct hpi_adapter_obj *pao = NULL;
- /* subsytem messages get executed by every HPI. */ - /* All other messages are ignored unless the adapter index matches */ - /* an adapter in the HPI */ - /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */ - - /* if Dsp has crashed then do not communicate with it any more */ if (phm->object != HPI_OBJ_SUBSYSTEM) { pao = hpi_find_adapter(phm->adapter_index); if (!pao) { - HPI_DEBUG_LOG(DEBUG, - " %d,%d refused, for another HPI?\n", - phm->object, phm->function); + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_BAD_ADAPTER_NUMBER); + HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n", + phm->adapter_index); return; }
+ /* Don't even try to communicate with crashed DSP */ if (pao->dsp_crashed >= 10) { hpi_init_response(phr, phm->object, phm->function, HPI_ERROR_DSP_HARDWARE); - HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", - phm->object, phm->function); + HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n", + phm->adapter_index); return; } } @@ -463,15 +460,9 @@ static void subsys_create_adapter(struct hpi_message *phm, phr->error = 0; }
-static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr) +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { - struct hpi_adapter_obj *pao = NULL; - - pao = hpi_find_adapter(phm->obj_index); - if (!pao) - return; - delete_adapter_obj(pao); hpi_delete_adapter(pao); phr->error = 0; diff --git a/pci/asihpi/hpi6205.c b/pci/asihpi/hpi6205.c index 620525b..5303734 100644 --- a/pci/asihpi/hpi6205.c +++ b/pci/asihpi/hpi6205.c @@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm,
static void subsys_create_adapter(struct hpi_message *phm, struct hpi_response *phr); -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr); +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr);
static u16 create_adapter_obj(struct hpi_adapter_obj *pao, u32 *pos_error_code); @@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index);
/*****************************************************************************/
-static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) +static void subsys_message(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { switch (phm->function) { case HPI_SUBSYS_CREATE_ADAPTER: subsys_create_adapter(phm, phr); break; - case HPI_SUBSYS_DELETE_ADAPTER: - subsys_delete_adapter(phm, phr); - break; default: phr->error = HPI_ERROR_INVALID_FUNC; break; @@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, struct hpi_response *phr) { switch (phm->function) { + case HPI_ADAPTER_DELETE: + adapter_delete(pao, phm, phr); + break; + default: hw_message(pao, phm, phr); break; @@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao, /** Entry point to this HPI backend * All calls to the HPI start here */ -void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) +void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, + struct hpi_response *phr) { - struct hpi_adapter_obj *pao = NULL; - - /* subsytem messages are processed by every HPI. - * All other messages are ignored unless the adapter index matches - * an adapter in the HPI - */ - /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, - phm->wFunction); */ - - /* if Dsp has crashed then do not communicate with it any more */ - if (phm->object != HPI_OBJ_SUBSYSTEM) { - pao = hpi_find_adapter(phm->adapter_index); - if (!pao) { - HPI_DEBUG_LOG(DEBUG, - " %d,%d refused, for another HPI?\n", - phm->object, phm->function); - return; - } - - if ((pao->dsp_crashed >= 10) - && (phm->function != HPI_ADAPTER_DEBUG_READ)) { - /* allow last resort debug read even after crash */ - hpi_init_response(phr, phm->object, phm->function, - HPI_ERROR_DSP_HARDWARE); - HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", - phm->object, phm->function); - return; - } + if (pao && (pao->dsp_crashed >= 10) + && (phm->function != HPI_ADAPTER_DEBUG_READ)) { + /* allow last resort debug read even after crash */ + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_DSP_HARDWARE); + HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object, + phm->function); + return; }
/* Init default response */ @@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) case HPI_TYPE_MESSAGE: switch (phm->object) { case HPI_OBJ_SUBSYSTEM: - subsys_message(phm, phr); + subsys_message(pao, phm, phr); break;
case HPI_OBJ_ADAPTER: @@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) } }
+void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) +{ + struct hpi_adapter_obj *pao = NULL; + + if (phm->object != HPI_OBJ_SUBSYSTEM) { + /* normal messages must have valid adapter index */ + pao = hpi_find_adapter(phm->adapter_index); + } else { + /* subsys messages don't address an adapter */ + _HPI_6205(NULL, phm, phr); + return; + } + + if (pao) + _HPI_6205(pao, phm, phr); + else + hpi_init_response(phr, phm->object, phm->function, + HPI_ERROR_BAD_ADAPTER_NUMBER); +} + /*****************************************************************************/ /* SUBSYSTEM */
@@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm, }
/** delete an adapter - required by WDM driver */ -static void subsys_delete_adapter(struct hpi_message *phm, - struct hpi_response *phr) +static void adapter_delete(struct hpi_adapter_obj *pao, + struct hpi_message *phm, struct hpi_response *phr) { - struct hpi_adapter_obj *pao; struct hpi_hw_obj *phw;
- pao = hpi_find_adapter(phm->obj_index); if (!pao) { phr->error = HPI_ERROR_INVALID_OBJ_INDEX; return; @@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, }
err = adapter_boot_load_dsp(pao, pos_error_code); - if (err) + if (err) { + HPI_DEBUG_LOG(ERROR, "DSP code load failed\n"); /* no need to clean up as SubSysCreateAdapter */ /* calls DeleteAdapter on error. */ return err; - + } HPI_DEBUG_LOG(INFO, "load DSP code OK\n");
/* allow boot load even if mem alloc wont work */ @@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, control_cache.number_of_controls, interface->control_cache.size_in_bytes, p_control_cache_virtual); + if (!phw->p_cache) err = HPI_ERROR_MEMORY_ALLOC; } @@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, }
/** Free memory areas allocated by adapter - * this routine is called from SubSysDeleteAdapter, + * this routine is called from AdapterDelete, * and SubSysCreateAdapter if duplicate index */ static void delete_adapter_obj(struct hpi_adapter_obj *pao) { - struct hpi_hw_obj *phw; + struct hpi_hw_obj *phw = pao->priv; int i;
- phw = pao->priv; - if (hpios_locked_mem_valid(&phw->h_control_cache)) { hpios_locked_mem_free(&phw->h_control_cache); hpi_free_control_cache(phw->p_cache); @@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, case HPI_ADAPTER_FAMILY_ASI(0x6300): boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); break; + case HPI_ADAPTER_FAMILY_ASI(0x5500): case HPI_ADAPTER_FAMILY_ASI(0x5600): case HPI_ADAPTER_FAMILY_ASI(0x6500): boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); @@ -2059,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us) static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) { struct bus_master_interface *interface = phw->p_interface_buffer; - u32 r;
interface->host_cmd = cmd; @@ -2088,7 +2089,7 @@ static u16 message_response_sequence(struct hpi_adapter_obj *pao, phr->specific_error = sizeof(interface->u); phr->size = sizeof(struct hpi_response_header); HPI_DEBUG_LOG(ERROR, - "message len %d too big for buffer %zd \n", phm->size, + "message len %d too big for buffer %ld \n", phm->size, sizeof(interface->u)); return 0; } diff --git a/pci/asihpi/hpi_internal.h b/pci/asihpi/hpi_internal.h index af678be..d829a65 100644 --- a/pci/asihpi/hpi_internal.h +++ b/pci/asihpi/hpi_internal.h @@ -294,7 +294,7 @@ enum HPI_CONTROL_ATTRIBUTES {
/* These defines are used to fill in protocol information for an Ethernet packet sent using HMI on CS18102 */ -/** ID supplied by Cirrius for ASI packets. */ +/** ID supplied by Cirrus for ASI packets. */ #define HPI_ETHERNET_PACKET_ID 0x85 /** Simple packet - no special routing required */ #define HPI_ETHERNET_PACKET_V1 0x01 @@ -307,7 +307,7 @@ enum HPI_CONTROL_ATTRIBUTES { /** This packet must make its way to the host across the HPI interface */ #define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41
-#define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ +#define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */
/** Default network timeout in milli-seconds. */ #define HPI_ETHERNET_TIMEOUT_MS 500 @@ -397,14 +397,14 @@ enum HPI_FUNCTION_IDS { HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), - HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), + /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */ HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), - HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), + /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */ HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), - HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), - HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), + /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */ + /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */ HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), @@ -433,7 +433,8 @@ enum HPI_FUNCTION_IDS { HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), -#define HPI_ADAPTER_FUNCTION_COUNT 20 + HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21), +#define HPI_ADAPTER_FUNCTION_COUNT 21
HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), @@ -1561,8 +1562,6 @@ void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr); u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, u16 *pw_adapter_index);
-u16 hpi_subsys_delete_adapter(u16 adapter_index); - u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, struct hpi_hostbuffer_status **pp_status);
diff --git a/pci/asihpi/hpicmn.c b/pci/asihpi/hpicmn.c index 3e9c5c2..0428f28 100644 --- a/pci/asihpi/hpicmn.c +++ b/pci/asihpi/hpicmn.c @@ -667,7 +667,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) phr->u.s.num_adapters = adapters.gw_num_adapters; break; case HPI_SUBSYS_CREATE_ADAPTER: - case HPI_SUBSYS_DELETE_ADAPTER: break; default: phr->error = HPI_ERROR_INVALID_FUNC; diff --git a/pci/asihpi/hpimsgx.c b/pci/asihpi/hpimsgx.c index bcbdf30..888e379 100644 --- a/pci/asihpi/hpimsgx.c +++ b/pci/asihpi/hpimsgx.c @@ -211,24 +211,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, HPIMSGX__init(phm, phr); break;
- case HPI_SUBSYS_DELETE_ADAPTER: - HPIMSGX__cleanup(phm->obj_index, h_owner); - { - struct hpi_message hm; - struct hpi_response hr; - hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, - HPI_ADAPTER_CLOSE); - hm.adapter_index = phm->obj_index; - hw_entry_point(&hm, &hr); - } - if ((phm->obj_index < HPI_MAX_ADAPTERS) - && hpi_entry_points[phm->obj_index]) { - hpi_entry_points[phm->obj_index] (phm, phr); - hpi_entry_points[phm->obj_index] = NULL; - } else - phr->error = HPI_ERROR_INVALID_OBJ_INDEX; - - break; default: /* Must explicitly handle every subsys message in this switch */ hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, @@ -247,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr, case HPI_ADAPTER_CLOSE: adapter_close(phm, phr); break; + case HPI_ADAPTER_DELETE: + HPIMSGX__cleanup(phm->adapter_index, h_owner); + { + struct hpi_message hm; + struct hpi_response hr; + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_CLOSE); + hm.adapter_index = phm->adapter_index; + hw_entry_point(&hm, &hr); + } + hw_entry_point(phm, phr); + break; + default: hw_entry_point(phm, phr); break; diff --git a/pci/asihpi/hpioctl.c b/pci/asihpi/hpioctl.c index 26186be..844295e 100644 --- a/pci/asihpi/hpioctl.c +++ b/pci/asihpi/hpioctl.c @@ -25,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions #include "hpidebug.h" #include "hpimsgx.h" #include "hpioctl.h" +#include "hpicmn.h"
#include <linux/fs.h> #include <linux/slab.h> @@ -156,26 +157,24 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) goto out; }
- pa = &adapters[hm->h.adapter_index]; + switch (hm->h.function) { + case HPI_SUBSYS_CREATE_ADAPTER: + case HPI_ADAPTER_DELETE: + /* Application must not use these functions! */ + hr->h.size = sizeof(hr->h); + hr->h.error = HPI_ERROR_INVALID_OPERATION; + hr->h.function = hm->h.function; + uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); + if (uncopied_bytes) + err = -EFAULT; + else + err = 0; + goto out; + } + hr->h.size = res_max_size; if (hm->h.object == HPI_OBJ_SUBSYSTEM) { - switch (hm->h.function) { - case HPI_SUBSYS_CREATE_ADAPTER: - case HPI_SUBSYS_DELETE_ADAPTER: - /* Application must not use these functions! */ - hr->h.size = sizeof(hr->h); - hr->h.error = HPI_ERROR_INVALID_OPERATION; - hr->h.function = hm->h.function; - uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); - if (uncopied_bytes) - err = -EFAULT; - else - err = 0; - goto out; - - default: - hpi_send_recv_f(&hm->m0, &hr->r0, file); - } + hpi_send_recv_f(&hm->m0, &hr->r0, file); } else { u16 __user *ptr = NULL; u32 size = 0; @@ -183,8 +182,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) /* -1=no data 0=read from user mem, 1=write to user mem */ int wrflag = -1; u32 adapter = hm->h.adapter_index; + pa = &adapters[adapter];
- if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { + if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) { hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, HPI_ADAPTER_OPEN, HPI_ERROR_BAD_ADAPTER_NUMBER); @@ -390,17 +390,20 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev,
adapter.index = hr.u.s.adapter_index; adapter.type = hr.u.s.adapter_type; + + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_OPEN); hm.adapter_index = adapter.index; + hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
- err = hpi_adapter_open(adapter.index); - if (err) + if (hr.error) goto err;
adapter.snd_card_asihpi = NULL; /* WARNING can't init mutex in 'adapter' * and then copy it to adapters[] ?!?! */ - adapters[hr.u.s.adapter_index] = adapter; + adapters[adapter.index] = adapter; mutex_init(&adapters[adapter.index].mutex); pci_set_drvdata(pci_dev, &adapters[adapter.index]);
@@ -435,10 +438,9 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) struct hpi_adapter *pa; pa = pci_get_drvdata(pci_dev);
- hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, - HPI_SUBSYS_DELETE_ADAPTER); - hm.obj_index = pa->index; - hm.adapter_index = HPI_ADAPTER_INDEX_INVALID; + hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, + HPI_ADAPTER_DELETE); + hm.adapter_index = pa->index; hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL);
/* unmap PCI memory space, mapped during device init. */
From: Eliot Blennerhassett eblennerhassett@audioscience.com
Signed-off-by: Eliot Blennerhassett eblennerhassett@audioscience.com --- pci/asihpi/hpi_internal.h | 2 -- pci/asihpi/hpicmn.c | 9 +++++++-- pci/asihpi/hpicmn.h | 2 ++ pci/asihpi/hpioctl.c | 9 +++------ 4 files changed, 12 insertions(+), 10 deletions(-)
diff --git a/pci/asihpi/hpi_internal.h b/pci/asihpi/hpi_internal.h index d829a65..4fab159 100644 --- a/pci/asihpi/hpi_internal.h +++ b/pci/asihpi/hpi_internal.h @@ -1583,9 +1583,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR);
/*////////////////////////////////////////////////////////////////////////// */ /* declarations for individual HPI entry points */ -hpi_handler_func HPI_1000; hpi_handler_func HPI_6000; hpi_handler_func HPI_6205; -hpi_handler_func HPI_COMMON;
#endif /* _HPI_INTERNAL_H_ */ diff --git a/pci/asihpi/hpicmn.c b/pci/asihpi/hpicmn.c index 0428f28..b15a02e 100644 --- a/pci/asihpi/hpicmn.c +++ b/pci/asihpi/hpicmn.c @@ -227,8 +227,9 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) if (info->control_type) { pC->p_info[info->control_index] = info; cached++; - } else /* dummy cache entry */ + } else { /* dummy cache entry */ pC->p_info[info->control_index] = NULL; + }
byte_count += info->size_in32bit_words * 4;
@@ -298,7 +299,7 @@ struct pad_ofs_size { unsigned int field_size; };
-static struct pad_ofs_size pad_desc[] = { +static const struct pad_ofs_size pad_desc[] = { HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ @@ -617,6 +618,10 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, } }
+/** Allocate control cache. + +\return Cache pointer, or NULL if allocation fails. +*/ struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, const u32 size_in_bytes, u8 *p_dsp_control_buffer) { diff --git a/pci/asihpi/hpicmn.h b/pci/asihpi/hpicmn.h index 590f0b6..d53cdf6 100644 --- a/pci/asihpi/hpicmn.h +++ b/pci/asihpi/hpicmn.h @@ -60,3 +60,5 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC, struct hpi_message *phm, struct hpi_response *phr);
u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); + +hpi_handler_func HPI_COMMON; diff --git a/pci/asihpi/hpioctl.c b/pci/asihpi/hpioctl.c index 844295e..14bbb94 100644 --- a/pci/asihpi/hpioctl.c +++ b/pci/asihpi/hpioctl.c @@ -312,7 +312,7 @@ out: int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id) { - int err, idx, nm; + int idx, nm; unsigned int memlen; struct hpi_message hm; struct hpi_response hr; @@ -346,11 +346,8 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, nm = HPI_MAX_ADAPTER_MEM_SPACES;
for (idx = 0; idx < nm; idx++) { - HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n", - idx, pci_dev->resource[idx].name, - (unsigned long long)pci_resource_start(pci_dev, idx), - (unsigned long long)pci_resource_end(pci_dev, idx), - (unsigned long long)pci_resource_flags(pci_dev, idx)); + HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx, + &pci_dev->resource[idx]);
if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { memlen = pci_resource_len(pci_dev, idx);
participants (3)
-
Eliot Blennerhassett
-
linux@audioscience.com
-
Takashi Iwai