diff --git a/src/add-ons/kernel/drivers/audio/ac97/auich/Jamfile b/src/add-ons/kernel/drivers/audio/ac97/auich/Jamfile index 9d056c3923..de1981308a 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/auich/Jamfile +++ b/src/add-ons/kernel/drivers/audio/ac97/auich/Jamfile @@ -1,8 +1,9 @@ SubDir HAIKU_TOP src add-ons kernel drivers audio ac97 auich ; SetSubDirSupportedPlatformsBeOSCompatible ; -UsePrivateSystemHeaders ; +UsePrivateKernelHeaders ; UsePrivateHeaders media ; + SubDirHdrs [ FDirName $(SUBDIR) $(DOTDOT) ] ; SEARCH_SOURCE += [ FDirName $(SUBDIR) $(DOTDOT) ] ; diff --git a/src/add-ons/kernel/drivers/audio/ac97/auich/auich.c b/src/add-ons/kernel/drivers/audio/ac97/auich/auich.c index 7c1da40f78..47f5df2e53 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/auich/auich.c +++ b/src/add-ons/kernel/drivers/audio/ac97/auich/auich.c @@ -102,7 +102,8 @@ auich_mem_new(auich_dev *card, size_t size) if ((mem = malloc(sizeof(*mem))) == NULL) return (NULL); - mem->area = alloc_mem(&mem->phy_base, &mem->log_base, size, "auich buffer"); + mem->area = alloc_mem(&mem->phy_base, &mem->log_base, size, "auich buffer", + true); mem->size = size; if (mem->area < B_OK) { free(mem); @@ -345,7 +346,7 @@ auich_stream_new(auich_dev *card, uint8 use, uint32 bufframes, uint8 bufcount) /* allocate memory for our dma ops */ stream->dmaops_area = alloc_mem(&stream->dmaops_phy_base, &stream->dmaops_log_base, - sizeof(auich_dmalist) * AUICH_DMALIST_MAX, "auich dmaops"); + sizeof(auich_dmalist) * AUICH_DMALIST_MAX, "auich dmaops", false); if (stream->dmaops_area < B_OK) { PRINT(("couldn't allocate memory\n")); 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 b12b64631b..ec5d99ac05 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/auich/multi.c +++ b/src/add-ons/kernel/drivers/audio/ac97/auich/multi.c @@ -32,7 +32,11 @@ #include #include #include +#include #include + +#include + #include "hmulti_audio.h" #include "multi.h" #include "ac97.h" @@ -726,17 +730,6 @@ auich_get_enabled_channels(auich_dev *card, multi_channel_enable *data) } -static status_t -auich_set_enabled_channels(auich_dev *card, multi_channel_enable *data) -{ - PRINT(("set_enabled_channels 0 : %s\n", B_TEST_CHANNEL(data->enable_bits, 0) ? "enabled": "disabled")); - PRINT(("set_enabled_channels 1 : %s\n", B_TEST_CHANNEL(data->enable_bits, 1) ? "enabled": "disabled")); - PRINT(("set_enabled_channels 2 : %s\n", B_TEST_CHANNEL(data->enable_bits, 2) ? "enabled": "disabled")); - PRINT(("set_enabled_channels 3 : %s\n", B_TEST_CHANNEL(data->enable_bits, 3) ? "enabled": "disabled")); - return B_OK; -} - - static status_t auich_get_global_format(auich_dev *card, multi_format_info *data) { @@ -758,6 +751,14 @@ auich_get_global_format(auich_dev *card, multi_format_info *data) } +static status_t +auich_set_global_format(auich_dev *card, multi_format_info* data) +{ + // TODO: it looks like we're not supposed to fail; fix this! + return B_OK; +} + + static status_t auich_get_buffers(auich_dev *card, multi_buffer_list *data) { @@ -794,12 +795,18 @@ auich_get_buffers(auich_dev *card, multi_buffer_list *data) if (bufcount > data->request_playback_buffers) bufcount = data->request_playback_buffers; - for (i = 0; i < bufcount; i++) + for (i = 0; i < bufcount; i++) { + struct buffer_desc descs[data->return_playback_channels]; for (j=0; jpstream, j, i, - &data->playback_buffers[i][j].base, - &data->playback_buffers[i][j].stride); - + &descs[j].base, + &descs[j].stride); + if (!IS_USER_ADDRESS(data->playback_buffers[i]) + || user_memcpy(data->playback_buffers[i], descs, sizeof(descs)) + < B_OK) { + return B_BAD_ADDRESS; + } + } data->return_record_buffers = current_settings.buffer_count; data->return_record_channels = rchannels; data->return_record_buffer_size = current_settings.buffer_frames; /* frames */ @@ -808,12 +815,18 @@ auich_get_buffers(auich_dev *card, multi_buffer_list *data) if (bufcount > data->request_record_buffers) bufcount = data->request_record_buffers; - for (i = 0; i < bufcount; i++) + for (i = 0; i < bufcount; i++) { + struct buffer_desc descs[data->return_record_channels]; for (j=0; jrstream, j, i, - &data->record_buffers[i][j].base, - &data->record_buffers[i][j].stride); - + &descs[j].base, + &descs[j].stride); + if (!IS_USER_ADDRESS(data->record_buffers[i]) + || user_memcpy(data->record_buffers[i], descs, sizeof(descs)) + < B_OK) { + return B_BAD_ADDRESS; + } + } return B_OK; } @@ -947,77 +960,28 @@ auich_buffer_force_stop(auich_dev *card) } +#define cookie_type auich_dev +#define get_description auich_get_description +#define get_enabled_channels auich_get_enabled_channels +#define get_global_format auich_get_global_format +#define set_global_format auich_set_global_format +#define list_mix_channels auich_list_mix_channels +#define list_mix_controls auich_list_mix_controls +#define list_mix_connections auich_list_mix_connections +#define get_mix auich_get_mix +#define set_mix auich_set_mix +#define get_buffers auich_get_buffers +#define buffer_exchange auich_buffer_exchange +#define buffer_force_stop auich_buffer_force_stop +#include "../generic/multi.c" + + static status_t -auich_multi_control(void *cookie, uint32 op, void *data, size_t length) +auich_multi_control(void *cookie, uint32 op, void *arg, size_t length) { auich_dev *card = (auich_dev *)cookie; - switch (op) { - case B_MULTI_GET_DESCRIPTION: - LOG(("B_MULTI_GET_DESCRIPTION\n")); - return auich_get_description(card, (multi_description *)data); - case B_MULTI_GET_EVENT_INFO: - LOG(("B_MULTI_GET_EVENT_INFO\n")); - return B_ERROR; - case B_MULTI_SET_EVENT_INFO: - LOG(("B_MULTI_SET_EVENT_INFO\n")); - return B_ERROR; - case B_MULTI_GET_EVENT: - LOG(("B_MULTI_GET_EVENT\n")); - return B_ERROR; - case B_MULTI_GET_ENABLED_CHANNELS: - LOG(("B_MULTI_GET_ENABLED_CHANNELS\n")); - return auich_get_enabled_channels(card, (multi_channel_enable *)data); - case B_MULTI_SET_ENABLED_CHANNELS: - LOG(("B_MULTI_SET_ENABLED_CHANNELS\n")); - return auich_set_enabled_channels(card, (multi_channel_enable *)data); - case B_MULTI_GET_GLOBAL_FORMAT: - LOG(("B_MULTI_GET_GLOBAL_FORMAT\n")); - return auich_get_global_format(card, (multi_format_info *)data); - case B_MULTI_SET_GLOBAL_FORMAT: - LOG(("B_MULTI_SET_GLOBAL_FORMAT\n")); - return B_OK; /* XXX BUG! we *MUST* return B_OK, returning B_ERROR will prevent - * BeOS to accept the format returned in B_MULTI_GET_GLOBAL_FORMAT - */ - case B_MULTI_GET_CHANNEL_FORMATS: - LOG(("B_MULTI_GET_CHANNEL_FORMATS\n")); - return B_ERROR; - case B_MULTI_SET_CHANNEL_FORMATS: /* only implemented if possible */ - LOG(("B_MULTI_SET_CHANNEL_FORMATS\n")); - return B_ERROR; - case B_MULTI_GET_MIX: - LOG(("B_MULTI_GET_MIX\n")); - return auich_get_mix(card, (multi_mix_value_info *)data); - case B_MULTI_SET_MIX: - LOG(("B_MULTI_SET_MIX\n")); - return auich_set_mix(card, (multi_mix_value_info *)data); - case B_MULTI_LIST_MIX_CHANNELS: - LOG(("B_MULTI_LIST_MIX_CHANNELS\n")); - return auich_list_mix_channels(card, (multi_mix_channel_info *)data); - case B_MULTI_LIST_MIX_CONTROLS: - LOG(("B_MULTI_LIST_MIX_CONTROLS\n")); - return auich_list_mix_controls(card, (multi_mix_control_info *)data); - case B_MULTI_LIST_MIX_CONNECTIONS: - LOG(("B_MULTI_LIST_MIX_CONNECTIONS\n")); - return auich_list_mix_connections(card, (multi_mix_connection_info *)data); - case B_MULTI_GET_BUFFERS: /* Fill out the struct for the first time; doesn't start anything. */ - LOG(("B_MULTI_GET_BUFFERS\n")); - return auich_get_buffers(card, data); - case B_MULTI_SET_BUFFERS: /* Set what buffers to use, if the driver supports soft buffers. */ - LOG(("B_MULTI_SET_BUFFERS\n")); - return B_ERROR; /* we do not support soft buffers */ - case B_MULTI_SET_START_TIME: /* When to actually start */ - LOG(("B_MULTI_SET_START_TIME\n")); - return B_ERROR; - case B_MULTI_BUFFER_EXCHANGE: /* stop and go are derived from this being called */ - //TRACE(("B_MULTI_BUFFER_EXCHANGE\n")); - return auich_buffer_exchange(card, (multi_buffer_info *)data); - case B_MULTI_BUFFER_FORCE_STOP: /* force stop of playback, nothing in data */ - LOG(("B_MULTI_BUFFER_FORCE_STOP\n")); - return auich_buffer_force_stop(card); - } - LOG(("ERROR: unknown multi_control %#x\n",op)); - return B_ERROR; + return multi_audio_control_generic(card, op, arg, length); } static status_t auich_open(const char *name, uint32 flags, void** cookie); diff --git a/src/add-ons/kernel/drivers/audio/ac97/auich/util.c b/src/add-ons/kernel/drivers/audio/ac97/auich/util.c index 6d9c4ad56d..827728bd3d 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/auich/util.c +++ b/src/add-ons/kernel/drivers/audio/ac97/auich/util.c @@ -64,18 +64,22 @@ round_to_pagesize(uint32 size) area_id -alloc_mem(phys_addr_t *phy, void **log, size_t size, const char *name) +alloc_mem(phys_addr_t *phy, void **log, size_t size, const char *name, bool user) { physical_entry pe; void * logadr; area_id area; status_t rv; + uint32 protection; LOG(("allocating %d bytes for %s\n",size,name)); + protection = B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA; + if (user) + protection = B_READ_AREA | B_WRITE_AREA; size = round_to_pagesize(size); area = create_area(name, &logadr, B_ANY_KERNEL_ADDRESS, size, - B_32_BIT_CONTIGUOUS, B_READ_AREA | B_WRITE_AREA); + B_32_BIT_CONTIGUOUS, protection); // TODO: The rest of the code doesn't deal correctly with physical // addresses > 4 GB, so we have to force 32 bit addresses here. if (area < B_OK) { @@ -88,7 +92,10 @@ alloc_mem(phys_addr_t *phy, void **log, size_t size, const char *name) PRINT(("couldn't map %s\n",name)); return B_ERROR; } - memset(logadr, 0, size); + if (user) + user_memset(logadr, 0, size); + else + memset(logadr, 0, size); if (log) *log = logadr; if (phy) @@ -113,7 +120,7 @@ map_mem(void **log, phys_addr_t phy, size_t size, const char *name) phyadr = phy - offset; size = round_to_pagesize(size + offset); area = map_physical_memory(name, phyadr, size, B_ANY_KERNEL_ADDRESS, - 0, &mapadr); + B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA, &mapadr); *log = mapadr + offset; LOG(("physical = %p, logical = %p, offset = %#x, phyadr = %p, mapadr = %p, size = %#x, area = %#x\n", diff --git a/src/add-ons/kernel/drivers/audio/ac97/auich/util.h b/src/add-ons/kernel/drivers/audio/ac97/auich/util.h index 933c1fcb7c..c03433a966 100644 --- a/src/add-ons/kernel/drivers/audio/ac97/auich/util.h +++ b/src/add-ons/kernel/drivers/audio/ac97/auich/util.h @@ -30,7 +30,8 @@ #include -area_id alloc_mem(phys_addr_t *phy, void **log, size_t size, const char *name); +area_id alloc_mem(phys_addr_t *phy, void **log, size_t size, const char *name, + bool user); area_id map_mem(void **log, phys_addr_t phy, size_t size, const char *name); cpu_status lock(void);