* The patch maneger interface for the /dev/sequencer
* Copyright by Hannu Savolainen 1993
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met: 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer. 2.
* Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
#include "sound_config.h"
#if defined(CONFIGURE_SOUNDCARD) && !defined(EXCLUDE_SEQUENCER)
DEFINE_WAIT_QUEUES (server_procs
[MAX_SYNTH_DEV
],
server_wait_flag
[MAX_SYNTH_DEV
]);
static struct patmgr_info
*mbox
[MAX_SYNTH_DEV
] =
static volatile int msg_direction
[MAX_SYNTH_DEV
] =
static int pmgr_opened
[MAX_SYNTH_DEV
] =
DEFINE_WAIT_QUEUE (appl_proc
, appl_wait_flag
);
if (dev
< 0 || dev
>= num_synths
)
return RET_ERROR (ENXIO
);
return RET_ERROR (EBUSY
);
RESET_WAIT_QUEUE (server_procs
[dev
], server_wait_flag
[dev
]);
if (mbox
[dev
]) /* Killed in action. Inform the client */
mbox
[dev
]->key
= PM_ERROR
;
mbox
[dev
]->parm1
= RET_ERROR (EIO
);
if (SOMEONE_WAITING (appl_proc
, appl_wait_flag
))
WAKE_UP (appl_proc
, appl_wait_flag
);
pmgr_read (int dev
, struct fileinfo
*file
, snd_rw_buf
* buf
, int count
)
if (count
!= sizeof (struct patmgr_info
))
printk ("PATMGR%d: Invalid read count\n", dev
);
while (!ok
&& !PROCESS_ABORTING (server_procs
[dev
], server_wait_flag
[dev
]))
while (!(mbox
[dev
] && msg_direction
[dev
] == A_TO_S
) &&
!PROCESS_ABORTING (server_procs
[dev
], server_wait_flag
[dev
]))
DO_SLEEP (server_procs
[dev
], server_wait_flag
[dev
], 0);
if (mbox
[dev
] && msg_direction
[dev
] == A_TO_S
)
COPY_TO_USER (buf
, 0, (char *) mbox
[dev
], count
);
return RET_ERROR (EINTR
);
pmgr_write (int dev
, struct fileinfo
*file
, snd_rw_buf
* buf
, int count
)
printk ("PATMGR%d: Write count < 4\n", dev
);
COPY_FROM_USER (mbox
[dev
], buf
, 0, 4);
if (*(unsigned char *) mbox
[dev
] == SEQ_FULLSIZE
)
tmp_dev
= ((unsigned short *) mbox
[dev
])[2];
return RET_ERROR (ENXIO
);
return synth_devs
[dev
]->load_patch (dev
, *(unsigned short *) mbox
[dev
],
if (count
!= sizeof (struct patmgr_info
))
printk ("PATMGR%d: Invalid write count\n", dev
);
* If everything went OK, there should be a preallocated buffer in the
* mailbox and a client waiting.
if (mbox
[dev
] && !msg_direction
[dev
])
COPY_FROM_USER (&((char *) mbox
[dev
])[4], buf
, 4, count
- 4);
msg_direction
[dev
] = S_TO_A
;
if (SOMEONE_WAITING (appl_proc
, appl_wait_flag
))
WAKE_UP (appl_proc
, appl_wait_flag
);
pmgr_access (int dev
, struct patmgr_info
*rec
)
printk (" PATMGR: Server %d mbox full. Why?\n", dev
);
msg_direction
[dev
] = A_TO_S
;
if (SOMEONE_WAITING (server_procs
[dev
], server_wait_flag
[dev
]))
WAKE_UP (server_procs
[dev
], server_wait_flag
[dev
]);
DO_SLEEP (appl_proc
, appl_wait_flag
, 0);
if (msg_direction
[dev
] != S_TO_A
)
rec
->parm1
= RET_ERROR (EIO
);
else if (rec
->key
== PM_ERROR
)
pmgr_inform (int dev
, int event
, unsigned long p1
, unsigned long p2
,
unsigned long p3
, unsigned long p4
)
printk (" PATMGR: Server %d mbox full. Why?\n", dev
);
(struct patmgr_info
*) KERNEL_MALLOC (sizeof (struct patmgr_info
));
mbox
[dev
]->key
= PM_K_EVENT
;
mbox
[dev
]->command
= event
;
msg_direction
[dev
] = A_TO_S
;
if (SOMEONE_WAITING (server_procs
[dev
], server_wait_flag
[dev
]))
WAKE_UP (server_procs
[dev
], server_wait_flag
[dev
]);
DO_SLEEP (appl_proc
, appl_wait_flag
, 0);