* 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
This commit is contained in:
Jérôme Duval 2009-01-11 22:55:55 +00:00
parent 168353694e
commit 7f2d1a266e
5 changed files with 114 additions and 76 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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);