[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [cdi-devel] Proposed Sound Infrastructure



On Mon, Nov 23, 2009 at 12:10:47PM +1000, Matthew Iselin wrote:
> Right, and I think a method to access other devices from CDI drivers
> would be rather handy at times as well. This should be another CDI
> "system call", in my opinion. How that call looks is probably
> something to be discussed - it needs to be generic for driver code but
> at the same time able to cater to many different ways for an OS to
> handle devices. Any ideas?

We found that getting this IDC (Inter Driver Communication) part right
is the most important thing for now, so I'm ignoring the whole audio
stuff for now.

I have tried to write down some header file fragments that would make up
a suitable framework, both for monolithic kernels and microkernel
systems. Basically the only new thing is the abstraction of memory areas
that allows a (microkernel) OS to use shared memory for the actual sound
data, so that the user application can create the buffer and it doesn't
need to be copied anywhere. Other OSes might decide not to implement
this but rather do a copy. Monolithic kernels will probably just pass
pointers around.

I'm attaching a first attempt of the header. Comments are appreciated.

Kevin
/* cdi-idc.h */

struct cdi_memory_area;
struct cdi_idc_endpoint;

cdi_list_t cdi_idc_list_endpoints(void);
cdi_device_t cdi_idc_endpoint_type(struct cdi_idc_endpoint* ep);


typedef enum {
    CDI_MEM_PHYS_CONTIGUOUS,
} cdi_malloc_flags_t;

struct cdi_memory_area* cdi_idc_malloc(size_t size, cdi_malloc_flags_t flags);
void cdi_idc_free(struct cdi_memory_area* p);


typedef void (*cdi_idc_handler_t)(
    struct cdi_device* dev,
    void* metadata,
    size_t metadata_size,
    struct cdi_memory_area *data);

int cdi_idc_send_message(
    struct cdi_idc_endpoint* endpoint,
    void* metadata,
    size_t metadata_size,
    struct cdi_memory_area* data);
void cdi_idc_set_message_handler(cdi_idc_handler_t handler);


/* cdi-osdep.h */

struct cdi_memory_area {
    /* Common part */
    size_t size;
    void* vaddr;
    uintptr_t paddr;

    /* OS specific part */
    int shm_id;
};

struct cdi_idc_endpoint {
    pid_t driver_pid;
    int device_id;
};


/* cdi-mixer.h */

struct cdi_mixer_driver {
    int (*play)(int device_id, int channel, struct cdi_memory_area* data);
};


/* cdi-audio.h */

typedef enum {
    CDI_AUDIO_PLAY,
    CDI_AUDIO_RECORD,
    CDI_AUDIO_SETVOLUME,
} cdi_audio_cmd_t;

struct cdi_audio_idc_header {
    cdi_audio_cmd_t cmd;
};

static void cdi_audio_idc_handler(
    struct cdi_device* dev,
    void* metadata,
    size_t metadata_size,
    struct cdi_memory_area *data)
{
    struct cdi_audio_idc_header* header = metadata;
    switch (header->cmd) {
        case PLAY:
            cdi_audio_play(dev, data->vaddr, data->size);
            break;
    }
}