[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[tyndur-devel] [PATCH] Meiner erste Commit ins Git Repo von tyndur. Und ahm nunja. AC97 Treiber unvollständig hinzugefügt. Wichtig sind mir die Kommentare zu der CDI/Sound definition
- Date: Tue, 11 Aug 2009 01:22:15 +0200
- From: Patrick Steinmüller
- To: tyndur-devel@xxxxxxxxxx
- Subject: [tyndur-devel] [PATCH] Meiner erste Commit ins Git Repo von tyndur. Und ahm nunja. AC97 Treiber unvollständig hinzugefügt. Wichtig sind mir die Kommentare zu der CDI/Sound definition
- Message-id: <1249946535-15187-1-git-send-email-user@Cazad-Dum>
From: deathly-sequences@xxxxxx <snake707@Cazad-Dum.(none)>
---
src/modules/cdi/ac97/Makefile.all | 6 +
src/modules/cdi/ac97/ac97.c | 189 ++++++++++++++++++++++++++++++++++
src/modules/cdi/ac97/includes/ac97.h | 80 ++++++++++++++
src/modules/cdi/ac97/main.c | 123 ++++++++++++++++++++++
src/modules/cdi/include/cdi.h | 1 +
src/modules/cdi/include/cdi/sound.h | 151 +++++++++++++++++++++++++++
6 files changed, 550 insertions(+), 0 deletions(-)
create mode 100644 src/modules/cdi/ac97/Makefile.all
create mode 100644 src/modules/cdi/ac97/ac97.c
create mode 100644 src/modules/cdi/ac97/includes/ac97.h
create mode 100644 src/modules/cdi/ac97/main.c
create mode 100644 src/modules/cdi/include/cdi/sound.h
diff --git a/src/modules/cdi/ac97/Makefile.all b/src/modules/cdi/ac97/Makefile.all
new file mode 100644
index 0000000..d231938
--- /dev/null
+++ b/src/modules/cdi/ac97/Makefile.all
@@ -0,0 +1,6 @@
+shopt -s extglob
+source $LOST_BUILDMK_ROOT/config.sh
+
+echo "LD $1/modules/ac97"
+$LOST_TOOLS_LD -Ttext=0x40000000 -oac97.mod *.o --start-group $2 --end-group
+$LOST_TOOLS_STRIP -s ac97.mod -o $1/modules/ac97
diff --git a/src/modules/cdi/ac97/ac97.c b/src/modules/cdi/ac97/ac97.c
new file mode 100644
index 0000000..25ec1cd
--- /dev/null
+++ b/src/modules/cdi/ac97/ac97.c
@@ -0,0 +1,189 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <math.h>
+
+#include "cdi/pci.h"
+#include "cdi/io.h"
+#include "cdi/misc.h"
+
+#include "includes/ac97.h"
+
+/*NOTE: Code kommt zum Teil aus lowlevel.brainsware.org/wiki/AC97 Stand:
+ 3.8.2009*/
+
+/*FIXME: This Code sucks ass!*/
+
+static void ac97_handle_interrupt(struct cdi_device* device);
+static void play_smpl(struct cdi_device* dev);
+
+/*FIXME: Code Struktur verbessern*/
+
+void ac97_init_device(struct cdi_device* device){
+ struct ac97_device *codec;
+ int i,j;
+ j=0;
+ codec=(struct ac97_device*)device;
+ /*PCI Strukturen initialisieren*/
+ DEBUG_MSG("AC97:- Interrupthandler und Ports initialisieren");
+ cdi_register_irq(codec->pci->irq,ac97_handle_interrupt,device);
+ cdi_pci_alloc_ioports(codec->pci);
+ /*IO-Räume finden: nambar und nabmbar, diese Stehen in der reslist*/
+ cdi_list_t reslist=codec->pci->resources;
+ struct cdi_pci_resource* res;/*zum Reslist traversieren*/
+ codec->nambar=0;
+ codec->nabmbar=0;
+ /*Reslist wird traversiert*/
+ for(i=0; (res=cdi_list_get(reslist,i));i++){
+ if((res->type==CDI_PCI_IOPORTS)&&(codec->nabmbar==0)){
+ /*Nabmbar steht vor Nambar in der Liste!*/
+ codec->nabmbar=res->start;
+ DEBUG_MSG("verm. Nabmbar");
+ }
+ else if((res->type==CDI_PCI_IOPORTS)&&(codec->nambar==0)){
+ /*Nambar eintragen*/
+ DEBUG_MSG("verm. Nambar");
+ codec->nambar=res->start;
+ }
+ else if(res->type==CDI_PCI_IOPORTS){
+ DEBUG_MSG("IOPORT unbekannt");
+ }
+ else{
+ DEBUG_MSG("res->type unbekannt");
+ }
+ }
+ cdi_sleep_ms(1000);
+ /* Karte Resetten */
+ DEBUG_MSG("Karte resetten");
+ cdi_outw(codec->nambar+NAM_RESET,42);/*Reset der Karte durchführen*/
+ cdi_outb(codec->nabmbar+NABM_GLB_CTRL_STAT,0x02);/*wird auch zum Resetten
+benötigt*/
+ cdi_sleep_ms(1000); /*1sec warten*/
+
+ /* Lautstärke einstellen */
+ DEBUG_MSG("Lautstärke einstellen");
+ /*Lautstärke geht von 0x00 bis 0x1f, wobei 0x00 laut und 0x1f leise ist*/
+ /*Funktioniert anscheinend nicht unter qemu*/
+ uint16_t volume=0x1f;
+ /*Allgemeine Laustärke für Links und Rechts*/
+ cdi_outw(codec->nambar+NAM_MASTER_VOLUME,(volume<<8)|volume);
+ cdi_outw(codec->nambar+NAM_MONO_VOLUME,volume);/*Mono Lautstärke*/
+ cdi_outw(codec->nambar+NAM_PC_BEEP,volume);/*PC BEEP Lautstärke*/
+ /*PCM Lautstärke für links und rechts*/
+ cdi_outw(codec->nambar+NAM_PCM_VOLUME,(volume<<8)|volume);
+ cdi_sleep_ms(1000); /*1sec warten*/
+
+ /*Sample rate einstellen*/
+ DEBUG_MSG("Sample Rates Einstellen");
+ if(!((cdi_inw(codec->nambar+NAM_EXT_AUDIO_ID)&0x01))){
+ /* Hier liegt die Spl Rate auf fix bei 48kHz*/}
+ else
+ {
+ DEBUG_MSG("Sample Rates Konfigurieren");
+ cdi_outw(codec->nambar+NAM_EXT_AUDIO_STC,cdi_inw(codec->nambar+
+NAM_EXT_AUDIO_ID)|1); /*Variable Sample Rate einstellen*/
+ cdi_sleep_ms(1000);/*Warten!*/
+ /*FIXME: Aus Parametern auslesen!*/
+ /*Front Sample Rate*/
+ cdi_outw(codec->nambar+NAM_FRONT_SPLRATE,44100);
+ /*Links Rechts Sample Rate*/
+ cdi_outw(codec->nambar+NAM_LR_SPLRATE,44100);
+ cdi_sleep_ms(1000);/*Warten!*/
+ }
+ /*Buffer initialisieren.*/
+ DEBUG_MSG("Bufferlist initialisieren - Nur zum Test,\
+gehört hier nicht hin!");
+ /*FIXME: Bitmap bringt glaub ich nichts.*/
+ codec->valid_buffs=0x00;/*Bisher ist keiner der Buffer gültig*/
+ /* Buffer list anlegen*/
+ if(cdi_alloc_phys_mem(32*sizeof(buf),(void **)&codec->buffer_list,
+ &codec->paddr_buf_list)==-1){
+ DEBUG_MSG("MEMALLOC FEHLGESCHLAGEN!");
+ return;
+ }
+ /* Buffer anlegen, eintragen und mit Werten füllen*/
+ /*Letzteres nur zum Test*/
+ DEBUG_MSG("Buffer anlegen und eintragen");
+ for(i=0;i<32;i++)
+ {
+ void* vbuf=0;/*virtuelle Adresse des Buffers*/
+ void* pbuf=0;/*physische Adresse*/
+ if(cdi_alloc_phys_mem(0x10000,&vbuf,&pbuf)==-1){
+ /*0x20000 funzt hier offensichtlich nich*/
+ DEBUG_MSG("MEMALLOC FEHLGESCHLAGEN -- BUFFER INITIALISIEREN");
+ return;
+ }
+ /*Buffer füllen -- Nur zu Testzwecken*/
+ else{
+ codec->buffer_list[i].buffer=pbuf;/*Physikalische Adresse*/
+ /*Maximale Sample Länge.*/
+ codec->buffer_list[i].sample_length=0x7ffe;
+ if(i==31){
+ codec->buffer_list[i].bup=1; /*Buffer underrun Policy setzen.*/
+ }
+ else{
+ codec->buffer_list[i].bup=0; /*Buffer underrun Policy setzen.*/
+ }
+ codec->buffer_list[i].ioc=1; /*Interrupt on completion bit setzen.*/
+ codec->buf_virt[i]=(uint16_t*)vbuf;
+ codec->buf_phys[i]=(uint16_t*)pbuf;
+ uint16_t* xbuf=(uint16_t*)vbuf;
+ for(j=0;j<0x8000;j+=2)
+ {
+ xbuf[j]=0;
+ xbuf[j+1]=0;
+ }
+ }
+ }
+ play_smpl((struct cdi_device*) codec);
+ DEBUG_MSG("Abspielen!");
+ cdi_sleep_ms(1000);/*Warten! Dieses hat aber keinen besonderen Grund*/
+ /*Lister der Buffer Deskriptoren an das Gerät übergeben*/
+ cdi_outl(codec->nabmbar+NABM_POBDBAR,(uint32_t)codec->paddr_buf_list);
+ /*Letzten gültigen Buffer eintragen.*/
+ cdi_outb(codec->nabmbar+NABM_POLVI,31);
+ /*Das Gerät die Buffer abspielen lassen.*/
+ /*Hierzu wird das letzte Bit in nabmbar+NABM_POCONTROL gesetzt.*/
+ cdi_outb(codec->nabmbar+NABM_POCONTROL,0x01);
+}
+
+static void play_smpl(struct cdi_device* dev){
+ struct ac97_device *codec;
+ codec=(struct ac97_device*)dev;
+ FILE *pf;
+ pf=fopen("startup.wav","br");
+ char c,d;
+ int i;
+ if(!pf){
+ DEBUG_MSG("Fehler beim öffnen!");
+ return;
+ }
+ /*Header überspringen. Nervt grad nur.*/
+ for(i=0;i<52;i++){
+ c=fgetc(pf);
+ }
+ DEBUG_MSG("Header uebersprungen");
+ /*sooo :) dinge auslesen*/
+ i=0;
+ uint16_t *xbuf=(uint16_t *)codec->buf_virt[0];
+ while((!feof(pf))&&(i<0x10000)){
+ d=c;
+ c=fgetc(pf);
+ i++;
+ if(i%2==0){xbuf[(i-i%2)/2]=(c<<8)+d;};
+ if(c==d){printf("\r FUCK IT!%d %x %x",i,c,d);}
+ }
+ DEBUG_MSG("SOO LONG!");
+ fclose(pf);
+}
+
+void ac97_remove_device(struct cdi_device* device){
+ ;
+}
+
+static void ac97_handle_interrupt(struct cdi_device* device){
+ DEBUG_MSG("Interrupts");
+}
+
+/* EOF */
diff --git a/src/modules/cdi/ac97/includes/ac97.h b/src/modules/cdi/ac97/includes/ac97.h
new file mode 100644
index 0000000..5cd0a43
--- /dev/null
+++ b/src/modules/cdi/ac97/includes/ac97.h
@@ -0,0 +1,80 @@
+
+#ifndef __ac97_h__
+#define __ac97_h__
+
+#include <stdint.h>
+
+#include "cdi.h"
+#include "cdi/net.h"
+#include "cdi/pci.h"
+
+/* Benötigte Konstanten */
+/* Quelle: lowlevel.brainsware.org/wiki/AC97: Stand: 3.8.2009 */
+
+#define NAM_RESET 0x0000
+#define NAM_MASTER_VOLUME 0x0002
+#define NAM_MONO_VOLUME 0x0006
+#define NAM_PC_BEEP 0x000A
+#define NAM_PCM_VOLUME 0x0018
+#define NAM_EXT_AUDIO_ID 0x0028
+#define NAM_EXT_AUDIO_STC 0x002A
+#define NAM_FRONT_SPLRATE 0x002C
+#define NAM_LR_SPLRATE 0x0032
+#define NABM_POBDBAR 0x0010
+#define NABM_POLVI 0x0015
+#define NABM_POCONTROL 0x001B
+#define NABM_GLB_CTRL_STAT 0x0060
+
+/* Makros */
+
+#define DEBUG_MSG(s) printf("[AC97] debug: %s() '%s'\n", __FUNCTION__, s)
+
+struct ac97_buffer_desc_t{
+ void* buffer;
+ uint16_t sample_length;
+ uint16_t reserved:14;
+ uint16_t bup:1;
+ uint16_t ioc:1;
+
+}__attribute__((packed));
+
+typedef struct ac97_buffer_desc_t buf;
+
+struct ac97_device{
+ struct cdi_device cdi;
+ struct cdi_pci_device* pci;
+ void* phys;
+ buf* buffer_list; /*Liste der Buffer*/
+ void* paddr_buf_list;/*phyisische Adresse der Buffer Descriptor list*/
+ uint32_t valid_buffs; /*mini bitmap welche buffer gerade gültig sind :)*/
+ uint16_t* buf_virt[32];/*Virtuelle Adressen der einzelnen buffer*/
+ uint16_t* buf_phys[32];/*Physische Adressen der einzelnen buffer*/
+
+ uint32_t nambar; /*Native Audio Mixer Base Address Register*/
+ uint32_t nabmbar; /*Native Audio Bus Master Base Address Register*/
+
+ uint16_t vol;/*Lautstärke*/
+ uint16_t splrate;/*Samplerate*/
+
+ //TODO: Volume, Sample Rates etc.
+};
+
+/**
+ * Initialisiert das AC97 Gerät.
+ *
+ * @param device Struktur zur Verwaltung des Gerätes. Elterklasse von ac97_device
+ **/
+
+void ac97_init_device(struct cdi_device* device);
+
+/**
+ * Führt die Aufraumaurbeiten durch. Wie zum Beispiel: Speicherfreigabe.
+ *
+ * @param device Struktur zur Verwaltung des Gerätes. Elterklasse von ac97_device
+ **/
+void ac97_remove_device(struct cdi_device* device);
+
+#endif
+
+/* EOF */
+
diff --git a/src/modules/cdi/ac97/main.c b/src/modules/cdi/ac97/main.c
new file mode 100644
index 0000000..f8aa1b2
--- /dev/null
+++ b/src/modules/cdi/ac97/main.c
@@ -0,0 +1,123 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "cdi/pci.h"
+#include "cdi/io.h"
+#include "cdi/misc.h"
+
+#include "includes/ac97.h"
+
+struct ac97_options{
+ uint32_t mode;
+ uint16_t vol;/*Lautstärke*/
+ uint16_t splr;/*Sample Rate*/
+};
+
+typedef struct ac97_options dro;
+
+struct ac97_driver {
+ struct cdi_driver drv;
+};
+
+static struct ac97_driver ac97;
+
+static const char* driver_name="ac97";
+
+static void ac97_parameters(dro* modi, int argc, char *argv[]);
+static void ac97driver_init(int argc, char *argv[]);
+static void ac97driver_destroy(struct cdi_driver* driver);
+
+#ifdef CDI_STANDALONE
+int main(int argc, char* argv[])
+#else
+int init_ac97(int argc, char* argv[])
+#endif
+{
+ cdi_init();
+ ac97driver_init(argc,argv);
+ cdi_driver_register((struct cdi_driver*) &ac97);
+#ifdef CDI_STANDALONE
+ cdi_run_drivers();
+#endif
+ return 0;
+}
+
+static void ac97driver_init(int argc, char *argv[]){
+ dro options={
+ /*Standardwerte setzen*/
+ .mode=0x00,
+ .vol=0x0f,
+ .splr=44100
+ };
+
+ ac97_parameters(&options, argc,argv);
+ ac97.drv.name=driver_name;
+ ac97.drv.type=CDI_SOUND;
+ ac97.drv.init_device=ac97_init_device;
+ ac97.drv.remove_device=ac97_remove_device;
+ ac97.drv.destroy=ac97driver_destroy;
+
+ cdi_list_t pci_devices=cdi_list_create();
+ cdi_pci_get_all_devices(pci_devices);
+ struct cdi_pci_device* get=0;
+ int i;
+ for(i=0;(get=cdi_list_get(pci_devices,i));i++){
+ printf("PCI_DEVICE: %x\n",get->device_id);
+ if((get->vendor_id==0x8086)&&(get->device_id==0x2415)){
+ void* p_phys_device;
+ struct ac97_device* ac97_d;
+ if((cdi_alloc_phys_mem(sizeof(*ac97_d),(void**) &ac97_d,
+&p_phys_device))==-1){
+ DEBUG_MSG("Memalloc fehlgeschlagen!");
+ }
+ memset(ac97_d,0,sizeof(struct ac97_device));
+ ac97_d->phys=p_phys_device;
+ ac97_d->pci=get;
+ ac97_d->vol=options.vol;
+ ac97_d->splrate=options.splr;
+ ac97_init_device((struct cdi_device*)ac97_d);
+ }
+ else{
+ cdi_pci_device_destroy(get);
+ }
+ }
+ cdi_list_destroy(pci_devices);
+}
+
+
+/*TODO: Debugging, einfach überprüfen ob alles funzt*/
+static void ac97_parameters(dro* options, int argc, char *argv[]){
+ int i,j;
+ uint32_t flags=0;
+ for( i=1;i<argc;i++){
+ if(!(strcmp("--volume",argv[i])&&strcmp("-v",argv[i])&&
+ (flags&0x00000001))){
+ options->vol=(uint16_t)strtoul(argv[i+1],NULL,0);
+ flags|=0x00000001;
+ i++; /*Index muss sich noch um eins erhöhen.*/
+ continue;
+ }
+ else if(!(strcmp("--sample-rate",argv[i])&&strcmp("-s",argv[i])&&
+ (flags&0x00000010))){
+ options->splr=(uint16_t)strtoul(argv[i+1],NULL,0);
+ flags|=0x00000010;
+ i++;
+ continue;
+ }
+ else{
+ DEBUG_MSG("Unbekannte oder Wiederhohlte Argumente!");
+ printf("Argumentenliste:\n");
+ for(j=0;j<argc;j++){
+ printf("\t %s", argv[j]);
+ }
+ }
+ }
+}
+
+static void ac97driver_destroy(struct cdi_driver* driver){
+}
+
+/* EOF */
diff --git a/src/modules/cdi/include/cdi.h b/src/modules/cdi/include/cdi.h
index c6215a6..c3a48ee 100644
--- a/src/modules/cdi/include/cdi.h
+++ b/src/modules/cdi/include/cdi.h
@@ -25,6 +25,7 @@ typedef enum {
CDI_NETWORK = 1,
CDI_STORAGE = 2,
CDI_SCSI = 3,
+ CDI_SOUND = 4,
} cdi_device_type_t;
struct cdi_driver;
diff --git a/src/modules/cdi/include/cdi/sound.h b/src/modules/cdi/include/cdi/sound.h
new file mode 100644
index 0000000..680553a
--- /dev/null
+++ b/src/modules/cdi/include/cdi/sound.h
@@ -0,0 +1,151 @@
+
+/** @file sound.h
+ *
+ * Diese Datei enthält die Datenstrukturen, von denen die Datenstrukturen der
+ * Treiber abgeleitet werden. Außerdem werden hier die Funktionsprototypen für
+ * die Schnittstelle Soundtreiber, CDI definiert.
+ **/
+
+/**
+ * Treiber für die Soundkarten.
+ *
+ * @defgroup sound
+ **/
+
+#ifndef __sound_h__
+#define __sound_h__
+
+#include <stdint.h>
+#include <stddef.h>
+
+#include "cdi.h"
+
+/* Angelehnt an net.h */
+
+struct cdi_sound_device{
+ struct cdi_device dev;
+ /* Im folgenden bezeichnet driver immer das Gerät. */
+ /* Ausführlichere Kommentare/Dokumentation findet man in den jeweiligen
+ Implementationen der Treiber. Hier werden nur Funktionszeiger
+ definiert. */
+
+ /** @brief Damit das Gerät auch beginnt Daten abzuspielen.
+ *
+ * Weißt den Treiber an, Daten abzuspielen, wenn neue vorhanden sind.
+ *
+ * @param driver Treiber, der die Daten abspielen soll.
+ *
+ */
+ void (*cdi_sound_play)(struct cdi_sound_driver *driver);
+
+ /** @brief Hält die Audioausgabe des Treibers an.
+ *
+ * Wenn der Treiber nicht gerade von einer anderen Anwendung blockiert wird,
+ * wird die Audioausgabe angehalten. Wird ignoriert, wenn der Treiber
+ * 'in use' ist.
+ *
+ * @param driver Treiber, der die Audioausgabe anhalten soll.
+ */
+ void (*cdi_sound_stop)(struct cdi_sound_driver *driver);
+
+ /** @brief Ein Prozess darf die in_use Option betätigen.
+ *
+ * Die in use Option ist mir eingefallen, als ich mir das Zusammenspiel
+ * Amarok, Firefox mit flashplayer plugin und der rest des Systems angesehen
+ * habe. Die schließen sich gegenseitig aus. Sobald Amarok an ist, kann
+ * der Rest nichts mehr abspielen. Hat auch gute Seiten. Funktionszeiger ...
+ *
+ * @param driver Treiber der in use gestellt werden soll.
+ * @param pid Prozess ID des Prozesses. Dient später nur zur Überprüfung.
+ *
+ * @return 0 bei Erfolg. 1 bei Misserfolg.
+ *
+ */
+ uint32_t (*cdi_sound_in_use_enable)(struct cdi_sound_driver *driver,
+ uint32_t pid);
+
+ /** @brief Der gleiche Prozess darf das in_use Privileg abgeben.
+ *
+ * Anhand von pid wird nur überprüft ob der richtige Prozess die in use
+ * Option abstellt. Funktionszeiger ...
+ *
+ * @param driver Treiber der die in use Option abschalten soll.
+ * @param pid Prozessnummer.
+ *
+ * @return 0 bei Erfolg. 1 bei Misserfolg.
+ */
+ uint32_t (*cdi_sound_in_use_disable)(struct cdi_sound_driver *driver,
+ uint32_t pid);
+
+ /** @brief Funktionszeiger für eine Schnittstelle, in der man den aktuellen
+ * Status des Treibers/Gerätes abrufen kann.
+ *
+ * Diese Funktion ist dafür gedacht um herauszufinden ob der Treiber gerade
+ * Daten abspielt oder nicht. Hier ist die Schnittstelle Treiber/CDI
+ *
+ * @param driver Soundtreiber, dessen Zustand ermittelt werden soll.
+ *
+ * @return Die Returncodes können von Treiber zu Treiber variieren. Hier
+ * ist eine Liste, von Codes, die auf jeden Fall genauso
+ * implementiert werden sollen (Zusätzliche können angehangen
+ * werden): 0 - Treiber/Gerät nicht arbeitsbereit/initialisiert.
+ * 1 - Gerät arbeitsbereit. Spielt keine Daten ab. 2 - Treiber
+ * erhält Daten. 4 - Gerät spielt Daten ab. Datenempfang möglich.
+ * 8 - Gerät ist gestoppt, aber es sind noch Daten zum spielen
+ * übrig. Neue Daten können jederzeit hinzugefügt werden.
+ * 16 - Bit ist gesetzt, wenn Qucik Mixing (lineare Superposition
+ * mit Clippingunterdrückung) erlaubt ist. 32 - Dieses Bit zeigt an
+ * ob der Treiber gerade von einem Prozess "blockiert" wird.
+ *
+ */
+ uint32_t (*cdi_sound_driver_state)(struct cdi_sound_driver *driver);
+
+ /** @brief Funktionszeiger für eine Schnittstelle, die dem Treiber die
+ * als nächstes abzuspielenden Daten übergibt.
+ *
+ * Dies ist ein Funktionszeiger und für die Schnittstelle Treiber CDI
+ * gedacht.
+ *
+ * @param driver Soundtreiber an den die Daten geschickt werden sollen.
+ * @param data_start Zeiger auf den Beginn der Daten. Es wird angenommen,
+ * dass alle Daten hintereinander liegen.
+ * @param data_length Länge des Datenblockes.
+ * @param pid Datenbereiche werden Treiberintern mit einer PID versehen, um
+ * diese z.B. noch zurückziehen zu können. Prozess beendet.
+ * Datenbereiche wurden deallokiert.
+ *
+ * @return 0 - bei Erfolg, 1 - bei Fehler, wiederhohlung kann ihn beheben
+ * 2 - Fehler nicht durch wiederhohlte Ausführung behebbar
+ * kann. Wenn Gerät z.B. von einem Prozess benutzt wird, der Mixing
+ * nicht zulassen will. Ansonnsten, werden Daten von verschiednen
+ * Geräten linear superponiert, oder einfach nacheinander
+ * abgespielt (Flags beachten).
+ */
+ uint32_t (*cdi_sound_input_data)(struct cdi_sound_driver *driver,
+ uint32_t* data_start,
+ uint32_t data_length,
+ uint32_t pid);
+
+ /** @brief Funktionszeiger für eine Schnittstelle, damit ein Prozess die an
+ * den Treiber übergebenen Daten zurückziehen kann.
+ *
+ * Diese Funktion ist dafür Gedacht, damit ein Prozess alle Daten, die in
+ * noch nicht fertiggestellten Buffer vorliegen, löschen kann, falls er z.B.
+ * beendet wird. Funktionszeiger für die Schnittstelle Treiber CDI.
+ *
+ * @param driver Treiber, der die entsprechenden Daten nicht mehr benutzen
+ * soll.
+ * @param pid Prozess ID, des entsprechenden Prozesses.
+ */
+ void (*cdi_sound_remove_data)(struct cdi_sound_driver *driver,
+ uint32_t pid);
+
+}
+
+struct cdi_sound_driver{
+ struct cdi_driver *drv;
+}
+
+#endif
+
+/* EOF */
--
1.6.0.4