From 7f2d1a266efede46393a6f129f37ac3d3aa81e3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sun, 11 Jan 2009 22:55:55 +0000 Subject: [PATCH] * for user_memcpy, use an on-stack structure and copy that at once, as suggested by Axel. * apply to auvia, emuxki and echo*. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@28887 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../kernel/drivers/audio/ac97/auich/multi.c | 44 +++++++++---------- .../kernel/drivers/audio/ac97/auvia/multi.c | 35 ++++++++++----- .../kernel/drivers/audio/echo/multi.cpp | 37 +++++++++++----- .../kernel/drivers/audio/emuxki/multi.c | 33 ++++++++++---- .../drivers/audio/hda/hda_multi_audio.cpp | 41 ++++++++--------- 5 files changed, 114 insertions(+), 76 deletions(-) diff --git a/src/add-ons/kernel/drivers/audio/ac97/auich/multi.c b/src/add-ons/kernel/drivers/audio/ac97/auich/multi.c index c9c9f3b0f9..203117dba3 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/auich/multi.c +++ b/src/add-ons/kernel/drivers/audio/ac97/auich/multi.c @@ -867,11 +867,16 @@ auich_buffer_exchange(auich_dev *card, multi_buffer_info *data) { cpu_status status; auich_stream *pstream, *rstream; - bigtime_t played_real_time, recorded_real_time; - uint64 played_frames_count, recorded_frames_count; - int32 playback_buffer_cycle, record_buffer_cycle, _reserved_0, _reserved_1; + multi_buffer_info buffer_info; + +#ifdef __HAIKU__ + if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(&buffer_info, data, sizeof(buffer_info)); +#endif - data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; + buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; if (!(card->pstream->state & AUICH_STATE_STARTED)) auich_stream_start(card->pstream, auich_play_inth, card->pstream); @@ -908,35 +913,26 @@ auich_buffer_exchange(auich_dev *card, multi_buffer_info *data) rstream = card->rstream; /* do playback */ - playback_buffer_cycle = pstream->buffer_cycle; - played_real_time = pstream->real_time; - played_frames_count = pstream->frames_count; - _reserved_0 = pstream->first_channel; + buffer_info.playback_buffer_cycle = pstream->buffer_cycle; + buffer_info.played_real_time = pstream->real_time; + buffer_info.played_frames_count = pstream->frames_count; + buffer_info._reserved_0 = pstream->first_channel; pstream->update_needed = false; /* do record */ - record_buffer_cycle = rstream->buffer_cycle; - recorded_frames_count = rstream->frames_count; - recorded_real_time = rstream->real_time; - _reserved_1 = rstream->first_channel; + buffer_info.record_buffer_cycle = rstream->buffer_cycle; + buffer_info.recorded_frames_count = rstream->frames_count; + buffer_info.recorded_real_time = rstream->real_time; + buffer_info._reserved_1 = rstream->first_channel; rstream->update_needed = false; unlock(status); #ifdef __HAIKU__ -#define copy_to_user(x, y) if (user_memcpy(&x, &y, sizeof(x)) < B_OK) \ - return B_BAD_ADDRESS + if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; #else -#define copy_to_user(x, y) x = y + memcpy(data, &buffer_info, sizeof(buffer_info)); #endif - - copy_to_user(data->playback_buffer_cycle, playback_buffer_cycle); - copy_to_user(data->played_real_time, played_real_time); - copy_to_user(data->played_frames_count, played_frames_count); - copy_to_user(data->_reserved_0, _reserved_0); - copy_to_user(data->record_buffer_cycle, record_buffer_cycle); - copy_to_user(data->recorded_real_time, recorded_real_time); - copy_to_user(data->recorded_frames_count, recorded_frames_count); - copy_to_user(data->_reserved_1, _reserved_1); //TRACE(("buffer_exchange ended\n")); return B_OK; diff --git a/src/add-ons/kernel/drivers/audio/ac97/auvia/multi.c b/src/add-ons/kernel/drivers/audio/ac97/auvia/multi.c index c1a7a53484..eb78b4983d 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/auvia/multi.c +++ b/src/add-ons/kernel/drivers/audio/ac97/auvia/multi.c @@ -861,8 +861,16 @@ auvia_buffer_exchange(auvia_dev *card, multi_buffer_info *data) { cpu_status status; auvia_stream *pstream, *rstream; + multi_buffer_info buffer_info; + +#ifdef __HAIKU__ + if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(&buffer_info, data, sizeof(buffer_info)); +#endif - data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; + buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; if (!(card->pstream->state & AUVIA_STATE_STARTED)) auvia_stream_start(card->pstream, auvia_play_inth, card->pstream); @@ -899,20 +907,27 @@ auvia_buffer_exchange(auvia_dev *card, multi_buffer_info *data) rstream = card->rstream; /* do playback */ - data->playback_buffer_cycle = pstream->buffer_cycle; - data->played_real_time = pstream->real_time; - data->played_frames_count = pstream->frames_count; - data->_reserved_0 = pstream->first_channel; + buffer_info.playback_buffer_cycle = pstream->buffer_cycle; + buffer_info.played_real_time = pstream->real_time; + buffer_info.played_frames_count = pstream->frames_count; + buffer_info._reserved_0 = pstream->first_channel; pstream->update_needed = false; /* do record */ - data->record_buffer_cycle = rstream->buffer_cycle; - data->recorded_frames_count = rstream->frames_count; - data->recorded_real_time = rstream->real_time; - data->_reserved_1 = rstream->first_channel; + buffer_info.record_buffer_cycle = rstream->buffer_cycle; + buffer_info.recorded_frames_count = rstream->frames_count; + buffer_info.recorded_real_time = rstream->real_time; + buffer_info._reserved_1 = rstream->first_channel; rstream->update_needed = false; unlock(status); - + +#ifdef __HAIKU__ + if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(data, &buffer_info, sizeof(buffer_info)); +#endif + //TRACE(("buffer_exchange ended\n")); return B_OK; } diff --git a/src/add-ons/kernel/drivers/audio/echo/multi.cpp b/src/add-ons/kernel/drivers/audio/echo/multi.cpp index 5d227074d5..0fbfb093f6 100644 --- a/src/add-ons/kernel/drivers/audio/echo/multi.cpp +++ b/src/add-ons/kernel/drivers/audio/echo/multi.cpp @@ -725,9 +725,17 @@ echo_buffer_exchange(echo_dev *card, multi_buffer_info *data) { cpu_status status; echo_stream *pstream, *rstream, *stream; + multi_buffer_info buffer_info; + +#ifdef __HAIKU__ + if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(&buffer_info, data, sizeof(buffer_info)); +#endif - data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; - + buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; + LIST_FOREACH(stream, &card->streams, next) { if ((stream->state & ECHO_STATE_STARTED) != 0) continue; @@ -764,20 +772,27 @@ echo_buffer_exchange(echo_dev *card, multi_buffer_info *data) rstream = card->rstream; /* do playback */ - data->playback_buffer_cycle = pstream->buffer_cycle; - data->played_real_time = pstream->real_time; - data->played_frames_count = pstream->frames_count; - data->_reserved_0 = pstream->first_channel; + buffer_info.playback_buffer_cycle = pstream->buffer_cycle; + buffer_info.played_real_time = pstream->real_time; + buffer_info.played_frames_count = pstream->frames_count; + buffer_info._reserved_0 = pstream->first_channel; pstream->update_needed = false; /* do record */ - data->record_buffer_cycle = rstream->buffer_cycle; - data->recorded_frames_count = rstream->frames_count; - data->recorded_real_time = rstream->real_time; - data->_reserved_1 = rstream->first_channel; + buffer_info.record_buffer_cycle = rstream->buffer_cycle; + buffer_info.recorded_frames_count = rstream->frames_count; + buffer_info.recorded_real_time = rstream->real_time; + buffer_info._reserved_1 = rstream->first_channel; rstream->update_needed = false; unlock(status); - + +#ifdef __HAIKU__ + if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(data, &buffer_info, sizeof(buffer_info)); +#endif + //TRACE(("buffer_exchange ended\n")); return B_OK; } diff --git a/src/add-ons/kernel/drivers/audio/emuxki/multi.c b/src/add-ons/kernel/drivers/audio/emuxki/multi.c index 5fad2b3e51..b7364d87f3 100644 --- a/src/add-ons/kernel/drivers/audio/emuxki/multi.c +++ b/src/add-ons/kernel/drivers/audio/emuxki/multi.c @@ -997,8 +997,16 @@ emuxki_buffer_exchange(emuxki_dev *card, multi_buffer_info *data) { cpu_status status; emuxki_stream *pstream, *rstream; + multi_buffer_info buffer_info; + +#ifdef __HAIKU__ + if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(&buffer_info, data, sizeof(buffer_info)); +#endif - data->flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; + buffer_info.flags = B_MULTI_BUFFER_PLAYBACK | B_MULTI_BUFFER_RECORD; if (!(card->pstream->state & EMU_STATE_STARTED)) emuxki_stream_start(card->pstream, emuxki_play_inth, card->pstream); @@ -1045,20 +1053,27 @@ emuxki_buffer_exchange(emuxki_dev *card, multi_buffer_info *data) rstream = card->rstream; /* do playback */ - data->playback_buffer_cycle = pstream->buffer_cycle; - data->played_real_time = pstream->real_time; - data->played_frames_count = pstream->frames_count; - data->_reserved_0 = pstream->first_channel; + buffer_info.playback_buffer_cycle = pstream->buffer_cycle; + buffer_info.played_real_time = pstream->real_time; + buffer_info.played_frames_count = pstream->frames_count; + buffer_info._reserved_0 = pstream->first_channel; pstream->update_needed = false; /* do record */ - data->record_buffer_cycle = rstream->buffer_cycle; - data->recorded_frames_count = rstream->frames_count; - data->recorded_real_time = rstream->real_time; - data->_reserved_1 = rstream->first_channel; + buffer_info.record_buffer_cycle = rstream->buffer_cycle; + buffer_info.recorded_frames_count = rstream->frames_count; + buffer_info.recorded_real_time = rstream->real_time; + buffer_info._reserved_1 = rstream->first_channel; rstream->update_needed = false; unlock(status); +#ifdef __HAIKU__ + if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(data, &buffer_info, sizeof(buffer_info)); +#endif + //TRACE(("buffer_exchange ended\n")); return B_OK; } diff --git a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp index cae84a8d35..ddd18d1601 100644 --- a/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp +++ b/src/add-ons/kernel/drivers/audio/hda/hda_multi_audio.cpp @@ -793,11 +793,8 @@ buffer_exchange(hda_audio_group* audioGroup, multi_buffer_info* data) static int debug_buffers_exchanged = 0; cpu_status status; status_t err; - bigtime_t played_real_time, recorded_real_time; - uint64 played_frames_count, recorded_frames_count; - int32 playback_buffer_cycle, record_buffer_cycle; - - // TODO: support recording! + multi_buffer_info buffer_info; + if (audioGroup->playback_stream == NULL) return B_ERROR; @@ -810,6 +807,13 @@ buffer_exchange(hda_audio_group* audioGroup, multi_buffer_info* data) audioGroup->record_stream); } +#ifdef __HAIKU__ + if (user_memcpy(&buffer_info, data, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; +#else + memcpy(&buffer_info, data, sizeof(buffer_info)); +#endif + /* do playback */ err = acquire_sem_etc(audioGroup->playback_stream->buffer_ready_sem, 1, B_CAN_INTERRUPT, 0); @@ -822,36 +826,29 @@ buffer_exchange(hda_audio_group* audioGroup, multi_buffer_info* data) status = disable_interrupts(); acquire_spinlock(&audioGroup->playback_stream->lock); - playback_buffer_cycle = audioGroup->playback_stream->buffer_cycle; - played_real_time = audioGroup->playback_stream->real_time; - played_frames_count = audioGroup->playback_stream->frames_count; + buffer_info.playback_buffer_cycle = audioGroup->playback_stream->buffer_cycle; + buffer_info.played_real_time = audioGroup->playback_stream->real_time; + buffer_info.played_frames_count = audioGroup->playback_stream->frames_count; release_spinlock(&audioGroup->playback_stream->lock); if (audioGroup->record_stream) { acquire_spinlock(&audioGroup->record_stream->lock); - record_buffer_cycle = audioGroup->record_stream->buffer_cycle; - recorded_real_time = audioGroup->record_stream->real_time; - recorded_frames_count = audioGroup->record_stream->frames_count; + buffer_info.record_buffer_cycle = audioGroup->record_stream->buffer_cycle; + buffer_info.recorded_real_time = audioGroup->record_stream->real_time; + buffer_info.recorded_frames_count = audioGroup->record_stream->frames_count; release_spinlock(&audioGroup->record_stream->lock); } restore_interrupts(status); #ifdef __HAIKU__ -#define copy_to_user(x, y) if (user_memcpy(&x, &y, sizeof(x)) < B_OK) \ - return B_BAD_ADDRESS + if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK) + return B_BAD_ADDRESS; #else -#define copy_to_user(x, y) x = y + memcpy(data, &buffer_info, sizeof(buffer_info)); #endif - - copy_to_user(data->playback_buffer_cycle, playback_buffer_cycle); - copy_to_user(data->played_real_time, played_real_time); - copy_to_user(data->played_frames_count, played_frames_count); - copy_to_user(data->record_buffer_cycle, record_buffer_cycle); - copy_to_user(data->recorded_real_time, recorded_real_time); - copy_to_user(data->recorded_frames_count, recorded_frames_count); - + debug_buffers_exchanged++; if (((debug_buffers_exchanged % 100) == 1) && (debug_buffers_exchanged < 1111)) { dprintf("%s: %d buffers processed\n", __func__, debug_buffers_exchanged);