* 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:
@@ -867,11 +867,16 @@ auich_buffer_exchange(auich_dev *card, multi_buffer_info *data)
|
|||||||
{
|
{
|
||||||
cpu_status status;
|
cpu_status status;
|
||||||
auich_stream *pstream, *rstream;
|
auich_stream *pstream, *rstream;
|
||||||
bigtime_t played_real_time, recorded_real_time;
|
multi_buffer_info buffer_info;
|
||||||
uint64 played_frames_count, recorded_frames_count;
|
|
||||||
int32 playback_buffer_cycle, record_buffer_cycle, _reserved_0, _reserved_1;
|
#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))
|
if (!(card->pstream->state & AUICH_STATE_STARTED))
|
||||||
auich_stream_start(card->pstream, auich_play_inth, card->pstream);
|
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;
|
rstream = card->rstream;
|
||||||
|
|
||||||
/* do playback */
|
/* do playback */
|
||||||
playback_buffer_cycle = pstream->buffer_cycle;
|
buffer_info.playback_buffer_cycle = pstream->buffer_cycle;
|
||||||
played_real_time = pstream->real_time;
|
buffer_info.played_real_time = pstream->real_time;
|
||||||
played_frames_count = pstream->frames_count;
|
buffer_info.played_frames_count = pstream->frames_count;
|
||||||
_reserved_0 = pstream->first_channel;
|
buffer_info._reserved_0 = pstream->first_channel;
|
||||||
pstream->update_needed = false;
|
pstream->update_needed = false;
|
||||||
|
|
||||||
/* do record */
|
/* do record */
|
||||||
record_buffer_cycle = rstream->buffer_cycle;
|
buffer_info.record_buffer_cycle = rstream->buffer_cycle;
|
||||||
recorded_frames_count = rstream->frames_count;
|
buffer_info.recorded_frames_count = rstream->frames_count;
|
||||||
recorded_real_time = rstream->real_time;
|
buffer_info.recorded_real_time = rstream->real_time;
|
||||||
_reserved_1 = rstream->first_channel;
|
buffer_info._reserved_1 = rstream->first_channel;
|
||||||
rstream->update_needed = false;
|
rstream->update_needed = false;
|
||||||
unlock(status);
|
unlock(status);
|
||||||
|
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
#define copy_to_user(x, y) if (user_memcpy(&x, &y, sizeof(x)) < B_OK) \
|
if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
|
||||||
return B_BAD_ADDRESS
|
return B_BAD_ADDRESS;
|
||||||
#else
|
#else
|
||||||
#define copy_to_user(x, y) x = y
|
memcpy(data, &buffer_info, sizeof(buffer_info));
|
||||||
#endif
|
#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"));
|
//TRACE(("buffer_exchange ended\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|||||||
@@ -861,8 +861,16 @@ auvia_buffer_exchange(auvia_dev *card, multi_buffer_info *data)
|
|||||||
{
|
{
|
||||||
cpu_status status;
|
cpu_status status;
|
||||||
auvia_stream *pstream, *rstream;
|
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))
|
if (!(card->pstream->state & AUVIA_STATE_STARTED))
|
||||||
auvia_stream_start(card->pstream, auvia_play_inth, card->pstream);
|
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;
|
rstream = card->rstream;
|
||||||
|
|
||||||
/* do playback */
|
/* do playback */
|
||||||
data->playback_buffer_cycle = pstream->buffer_cycle;
|
buffer_info.playback_buffer_cycle = pstream->buffer_cycle;
|
||||||
data->played_real_time = pstream->real_time;
|
buffer_info.played_real_time = pstream->real_time;
|
||||||
data->played_frames_count = pstream->frames_count;
|
buffer_info.played_frames_count = pstream->frames_count;
|
||||||
data->_reserved_0 = pstream->first_channel;
|
buffer_info._reserved_0 = pstream->first_channel;
|
||||||
pstream->update_needed = false;
|
pstream->update_needed = false;
|
||||||
|
|
||||||
/* do record */
|
/* do record */
|
||||||
data->record_buffer_cycle = rstream->buffer_cycle;
|
buffer_info.record_buffer_cycle = rstream->buffer_cycle;
|
||||||
data->recorded_frames_count = rstream->frames_count;
|
buffer_info.recorded_frames_count = rstream->frames_count;
|
||||||
data->recorded_real_time = rstream->real_time;
|
buffer_info.recorded_real_time = rstream->real_time;
|
||||||
data->_reserved_1 = rstream->first_channel;
|
buffer_info._reserved_1 = rstream->first_channel;
|
||||||
rstream->update_needed = false;
|
rstream->update_needed = false;
|
||||||
unlock(status);
|
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"));
|
//TRACE(("buffer_exchange ended\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -725,9 +725,17 @@ echo_buffer_exchange(echo_dev *card, multi_buffer_info *data)
|
|||||||
{
|
{
|
||||||
cpu_status status;
|
cpu_status status;
|
||||||
echo_stream *pstream, *rstream, *stream;
|
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) {
|
LIST_FOREACH(stream, &card->streams, next) {
|
||||||
if ((stream->state & ECHO_STATE_STARTED) != 0)
|
if ((stream->state & ECHO_STATE_STARTED) != 0)
|
||||||
continue;
|
continue;
|
||||||
@@ -764,20 +772,27 @@ echo_buffer_exchange(echo_dev *card, multi_buffer_info *data)
|
|||||||
rstream = card->rstream;
|
rstream = card->rstream;
|
||||||
|
|
||||||
/* do playback */
|
/* do playback */
|
||||||
data->playback_buffer_cycle = pstream->buffer_cycle;
|
buffer_info.playback_buffer_cycle = pstream->buffer_cycle;
|
||||||
data->played_real_time = pstream->real_time;
|
buffer_info.played_real_time = pstream->real_time;
|
||||||
data->played_frames_count = pstream->frames_count;
|
buffer_info.played_frames_count = pstream->frames_count;
|
||||||
data->_reserved_0 = pstream->first_channel;
|
buffer_info._reserved_0 = pstream->first_channel;
|
||||||
pstream->update_needed = false;
|
pstream->update_needed = false;
|
||||||
|
|
||||||
/* do record */
|
/* do record */
|
||||||
data->record_buffer_cycle = rstream->buffer_cycle;
|
buffer_info.record_buffer_cycle = rstream->buffer_cycle;
|
||||||
data->recorded_frames_count = rstream->frames_count;
|
buffer_info.recorded_frames_count = rstream->frames_count;
|
||||||
data->recorded_real_time = rstream->real_time;
|
buffer_info.recorded_real_time = rstream->real_time;
|
||||||
data->_reserved_1 = rstream->first_channel;
|
buffer_info._reserved_1 = rstream->first_channel;
|
||||||
rstream->update_needed = false;
|
rstream->update_needed = false;
|
||||||
unlock(status);
|
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"));
|
//TRACE(("buffer_exchange ended\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -997,8 +997,16 @@ emuxki_buffer_exchange(emuxki_dev *card, multi_buffer_info *data)
|
|||||||
{
|
{
|
||||||
cpu_status status;
|
cpu_status status;
|
||||||
emuxki_stream *pstream, *rstream;
|
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))
|
if (!(card->pstream->state & EMU_STATE_STARTED))
|
||||||
emuxki_stream_start(card->pstream, emuxki_play_inth, card->pstream);
|
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;
|
rstream = card->rstream;
|
||||||
|
|
||||||
/* do playback */
|
/* do playback */
|
||||||
data->playback_buffer_cycle = pstream->buffer_cycle;
|
buffer_info.playback_buffer_cycle = pstream->buffer_cycle;
|
||||||
data->played_real_time = pstream->real_time;
|
buffer_info.played_real_time = pstream->real_time;
|
||||||
data->played_frames_count = pstream->frames_count;
|
buffer_info.played_frames_count = pstream->frames_count;
|
||||||
data->_reserved_0 = pstream->first_channel;
|
buffer_info._reserved_0 = pstream->first_channel;
|
||||||
pstream->update_needed = false;
|
pstream->update_needed = false;
|
||||||
|
|
||||||
/* do record */
|
/* do record */
|
||||||
data->record_buffer_cycle = rstream->buffer_cycle;
|
buffer_info.record_buffer_cycle = rstream->buffer_cycle;
|
||||||
data->recorded_frames_count = rstream->frames_count;
|
buffer_info.recorded_frames_count = rstream->frames_count;
|
||||||
data->recorded_real_time = rstream->real_time;
|
buffer_info.recorded_real_time = rstream->real_time;
|
||||||
data->_reserved_1 = rstream->first_channel;
|
buffer_info._reserved_1 = rstream->first_channel;
|
||||||
rstream->update_needed = false;
|
rstream->update_needed = false;
|
||||||
unlock(status);
|
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"));
|
//TRACE(("buffer_exchange ended\n"));
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -793,11 +793,8 @@ buffer_exchange(hda_audio_group* audioGroup, multi_buffer_info* data)
|
|||||||
static int debug_buffers_exchanged = 0;
|
static int debug_buffers_exchanged = 0;
|
||||||
cpu_status status;
|
cpu_status status;
|
||||||
status_t err;
|
status_t err;
|
||||||
bigtime_t played_real_time, recorded_real_time;
|
multi_buffer_info buffer_info;
|
||||||
uint64 played_frames_count, recorded_frames_count;
|
|
||||||
int32 playback_buffer_cycle, record_buffer_cycle;
|
|
||||||
|
|
||||||
// TODO: support recording!
|
|
||||||
if (audioGroup->playback_stream == NULL)
|
if (audioGroup->playback_stream == NULL)
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
|
|
||||||
@@ -810,6 +807,13 @@ buffer_exchange(hda_audio_group* audioGroup, multi_buffer_info* data)
|
|||||||
audioGroup->record_stream);
|
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 */
|
/* do playback */
|
||||||
err = acquire_sem_etc(audioGroup->playback_stream->buffer_ready_sem,
|
err = acquire_sem_etc(audioGroup->playback_stream->buffer_ready_sem,
|
||||||
1, B_CAN_INTERRUPT, 0);
|
1, B_CAN_INTERRUPT, 0);
|
||||||
@@ -822,36 +826,29 @@ buffer_exchange(hda_audio_group* audioGroup, multi_buffer_info* data)
|
|||||||
status = disable_interrupts();
|
status = disable_interrupts();
|
||||||
acquire_spinlock(&audioGroup->playback_stream->lock);
|
acquire_spinlock(&audioGroup->playback_stream->lock);
|
||||||
|
|
||||||
playback_buffer_cycle = audioGroup->playback_stream->buffer_cycle;
|
buffer_info.playback_buffer_cycle = audioGroup->playback_stream->buffer_cycle;
|
||||||
played_real_time = audioGroup->playback_stream->real_time;
|
buffer_info.played_real_time = audioGroup->playback_stream->real_time;
|
||||||
played_frames_count = audioGroup->playback_stream->frames_count;
|
buffer_info.played_frames_count = audioGroup->playback_stream->frames_count;
|
||||||
|
|
||||||
release_spinlock(&audioGroup->playback_stream->lock);
|
release_spinlock(&audioGroup->playback_stream->lock);
|
||||||
|
|
||||||
if (audioGroup->record_stream) {
|
if (audioGroup->record_stream) {
|
||||||
acquire_spinlock(&audioGroup->record_stream->lock);
|
acquire_spinlock(&audioGroup->record_stream->lock);
|
||||||
record_buffer_cycle = audioGroup->record_stream->buffer_cycle;
|
buffer_info.record_buffer_cycle = audioGroup->record_stream->buffer_cycle;
|
||||||
recorded_real_time = audioGroup->record_stream->real_time;
|
buffer_info.recorded_real_time = audioGroup->record_stream->real_time;
|
||||||
recorded_frames_count = audioGroup->record_stream->frames_count;
|
buffer_info.recorded_frames_count = audioGroup->record_stream->frames_count;
|
||||||
release_spinlock(&audioGroup->record_stream->lock);
|
release_spinlock(&audioGroup->record_stream->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
restore_interrupts(status);
|
restore_interrupts(status);
|
||||||
|
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
#define copy_to_user(x, y) if (user_memcpy(&x, &y, sizeof(x)) < B_OK) \
|
if (user_memcpy(data, &buffer_info, sizeof(buffer_info)) < B_OK)
|
||||||
return B_BAD_ADDRESS
|
return B_BAD_ADDRESS;
|
||||||
#else
|
#else
|
||||||
#define copy_to_user(x, y) x = y
|
memcpy(data, &buffer_info, sizeof(buffer_info));
|
||||||
#endif
|
#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++;
|
debug_buffers_exchanged++;
|
||||||
if (((debug_buffers_exchanged % 100) == 1) && (debug_buffers_exchanged < 1111)) {
|
if (((debug_buffers_exchanged % 100) == 1) && (debug_buffers_exchanged < 1111)) {
|
||||||
dprintf("%s: %d buffers processed\n", __func__, debug_buffers_exchanged);
|
dprintf("%s: %d buffers processed\n", __func__, debug_buffers_exchanged);
|
||||||
|
|||||||
Reference in New Issue
Block a user