URL
https://opencores.org/ocsvn/or1k_old/or1k_old/trunk
Subversion Repositories or1k_old
[/] [or1k_old/] [trunk/] [uclinux/] [uClinux-2.0.x/] [drivers/] [sound/] [patmgr.c] - Rev 1765
Go to most recent revision | Compare with Previous | Blame | View Log
/* * sound/patmgr.c * * The patch manager interface for the /dev/sequencer */ /* * Copyright (C) by Hannu Savolainen 1993-1996 * * USS/Lite for Linux is distributed under the GNU GENERAL PUBLIC LICENSE (GPL) * Version 2 (June 1991). See the "COPYING" file distributed with this software * for more info. */ #include <linux/config.h> #define PATMGR_C #include "sound_config.h" #if defined(CONFIG_SEQUENCER) static wait_handle *server_procs[MAX_SYNTH_DEV] = {NULL}; static volatile struct snd_wait server_wait_flag[MAX_SYNTH_DEV] = { {0}}; static struct patmgr_info *mbox[MAX_SYNTH_DEV] = {NULL}; static volatile int msg_direction[MAX_SYNTH_DEV] = {0}; static int pmgr_opened[MAX_SYNTH_DEV] = {0}; #define A_TO_S 1 #define S_TO_A 2 static wait_handle *appl_proc = NULL; static volatile struct snd_wait appl_wait_flag = {0}; int pmgr_open (int dev) { if (dev < 0 || dev >= num_synths) return -(ENXIO); if (pmgr_opened[dev]) return -(EBUSY); pmgr_opened[dev] = 1; server_wait_flag[dev].flags = WK_NONE; return 0; } void pmgr_release (int dev) { if (mbox[dev]) /* * Killed in action. Inform the client */ { mbox[dev]->key = PM_ERROR; mbox[dev]->parm1 = -(EIO); if ((appl_wait_flag.flags & WK_SLEEP)) { appl_wait_flag.flags = WK_WAKEUP; module_wake_up (&appl_proc); }; } pmgr_opened[dev] = 0; } int pmgr_read (int dev, struct fileinfo *file, char *buf, int count) { unsigned long flags; int ok = 0; if (count != sizeof (struct patmgr_info)) { printk ("PATMGR%d: Invalid read count\n", dev); return -(EIO); } while (!ok && !current_got_fatal_signal ()) { save_flags (flags); cli (); while (!(mbox[dev] && msg_direction[dev] == A_TO_S) && !current_got_fatal_signal ()) { server_wait_flag[dev].flags = WK_SLEEP; module_interruptible_sleep_on (&server_procs[dev]); server_wait_flag[dev].flags &= ~WK_SLEEP;; } if (mbox[dev] && msg_direction[dev] == A_TO_S) { memcpy_tofs (&(buf)[0], (char *) mbox[dev], count); msg_direction[dev] = 0; ok = 1; } restore_flags (flags); } if (!ok) return -(EINTR); return count; } int pmgr_write (int dev, struct fileinfo *file, const char *buf, int count) { unsigned long flags; if (count < 4) { printk ("PATMGR%d: Write count < 4\n", dev); return -(EIO); } memcpy_fromfs ((char *) mbox[dev], &(buf)[0], 4); if (*(unsigned char *) mbox[dev] == SEQ_FULLSIZE) { int tmp_dev; tmp_dev = ((unsigned short *) mbox[dev])[2]; if (tmp_dev != dev) return -(ENXIO); return synth_devs[dev]->load_patch (dev, *(unsigned short *) mbox[dev], buf, 4, count, 1); } if (count != sizeof (struct patmgr_info)) { printk ("PATMGR%d: Invalid write count\n", dev); return -(EIO); } /* * If everything went OK, there should be a preallocated buffer in the * mailbox and a client waiting. */ save_flags (flags); cli (); if (mbox[dev] && !msg_direction[dev]) { memcpy_fromfs (&((char *) mbox[dev])[4], &(buf)[4], count - 4); msg_direction[dev] = S_TO_A; if ((appl_wait_flag.flags & WK_SLEEP)) { { appl_wait_flag.flags = WK_WAKEUP; module_wake_up (&appl_proc); }; } } restore_flags (flags); return count; } int pmgr_access (int dev, struct patmgr_info *rec) { unsigned long flags; int err = 0; save_flags (flags); cli (); if (mbox[dev]) printk (" PATMGR: Server %d mbox full. Why?\n", dev); else { rec->key = PM_K_COMMAND; mbox[dev] = rec; msg_direction[dev] = A_TO_S; if ((server_wait_flag[dev].flags & WK_SLEEP)) { { server_wait_flag[dev].flags = WK_WAKEUP; module_wake_up (&server_procs[dev]); }; } appl_wait_flag.flags = WK_SLEEP; module_interruptible_sleep_on (&appl_proc); appl_wait_flag.flags &= ~WK_SLEEP;; if (msg_direction[dev] != S_TO_A) { rec->key = PM_ERROR; rec->parm1 = -(EIO); } else if (rec->key == PM_ERROR) { err = rec->parm1; if (err > 0) err = -err; } mbox[dev] = NULL; msg_direction[dev] = 0; } restore_flags (flags); return err; } int pmgr_inform (int dev, int event, unsigned long p1, unsigned long p2, unsigned long p3, unsigned long p4) { unsigned long flags; int err = 0; struct patmgr_info *tmp_mbox; if (!pmgr_opened[dev]) return 0; tmp_mbox = (struct patmgr_info *) vmalloc (sizeof (struct patmgr_info)); if (tmp_mbox == NULL) { printk ("pmgr: Couldn't allocate memory for a message\n"); return 0; } save_flags (flags); cli (); if (mbox[dev]) printk (" PATMGR: Server %d mbox full. Why?\n", dev); else { mbox[dev] = tmp_mbox; mbox[dev]->key = PM_K_EVENT; mbox[dev]->command = event; mbox[dev]->parm1 = p1; mbox[dev]->parm2 = p2; mbox[dev]->parm3 = p3; msg_direction[dev] = A_TO_S; if ((server_wait_flag[dev].flags & WK_SLEEP)) { { server_wait_flag[dev].flags = WK_WAKEUP; module_wake_up (&server_procs[dev]); }; } appl_wait_flag.flags = WK_SLEEP; module_interruptible_sleep_on (&appl_proc); appl_wait_flag.flags &= ~WK_SLEEP;; mbox[dev] = NULL; msg_direction[dev] = 0; } restore_flags (flags); vfree (tmp_mbox); return err; } #endif
Go to most recent revision | Compare with Previous | Blame | View Log