xref: /openbmc/linux/sound/core/oss/pcm_oss.c (revision d236d361)
1 /*
2  *  Digital Audio (PCM) abstract layer / OSS compatible
3  *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
4  *
5  *
6  *   This program is free software; you can redistribute it and/or modify
7  *   it under the terms of the GNU General Public License as published by
8  *   the Free Software Foundation; either version 2 of the License, or
9  *   (at your option) any later version.
10  *
11  *   This program is distributed in the hope that it will be useful,
12  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *   GNU General Public License for more details.
15  *
16  *   You should have received a copy of the GNU General Public License
17  *   along with this program; if not, write to the Free Software
18  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19  *
20  */
21 
22 #if 0
23 #define PLUGIN_DEBUG
24 #endif
25 #if 0
26 #define OSS_DEBUG
27 #endif
28 
29 #include <linux/init.h>
30 #include <linux/slab.h>
31 #include <linux/sched/signal.h>
32 #include <linux/time.h>
33 #include <linux/vmalloc.h>
34 #include <linux/module.h>
35 #include <linux/math64.h>
36 #include <linux/string.h>
37 #include <linux/compat.h>
38 #include <sound/core.h>
39 #include <sound/minors.h>
40 #include <sound/pcm.h>
41 #include <sound/pcm_params.h>
42 #include "pcm_plugin.h"
43 #include <sound/info.h>
44 #include <linux/soundcard.h>
45 #include <sound/initval.h>
46 #include <sound/mixer_oss.h>
47 
48 #define OSS_ALSAEMULVER		_SIOR ('M', 249, int)
49 
50 static int dsp_map[SNDRV_CARDS];
51 static int adsp_map[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = 1};
52 static bool nonblock_open = 1;
53 
54 MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>, Abramo Bagnara <abramo@alsa-project.org>");
55 MODULE_DESCRIPTION("PCM OSS emulation for ALSA.");
56 MODULE_LICENSE("GPL");
57 module_param_array(dsp_map, int, NULL, 0444);
58 MODULE_PARM_DESC(dsp_map, "PCM device number assigned to 1st OSS device.");
59 module_param_array(adsp_map, int, NULL, 0444);
60 MODULE_PARM_DESC(adsp_map, "PCM device number assigned to 2nd OSS device.");
61 module_param(nonblock_open, bool, 0644);
62 MODULE_PARM_DESC(nonblock_open, "Don't block opening busy PCM devices.");
63 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM);
64 MODULE_ALIAS_SNDRV_MINOR(SNDRV_MINOR_OSS_PCM1);
65 
66 static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file);
67 static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file);
68 static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file);
69 
70 /*
71  * helper functions to process hw_params
72  */
73 static int snd_interval_refine_min(struct snd_interval *i, unsigned int min, int openmin)
74 {
75 	int changed = 0;
76 	if (i->min < min) {
77 		i->min = min;
78 		i->openmin = openmin;
79 		changed = 1;
80 	} else if (i->min == min && !i->openmin && openmin) {
81 		i->openmin = 1;
82 		changed = 1;
83 	}
84 	if (i->integer) {
85 		if (i->openmin) {
86 			i->min++;
87 			i->openmin = 0;
88 		}
89 	}
90 	if (snd_interval_checkempty(i)) {
91 		snd_interval_none(i);
92 		return -EINVAL;
93 	}
94 	return changed;
95 }
96 
97 static int snd_interval_refine_max(struct snd_interval *i, unsigned int max, int openmax)
98 {
99 	int changed = 0;
100 	if (i->max > max) {
101 		i->max = max;
102 		i->openmax = openmax;
103 		changed = 1;
104 	} else if (i->max == max && !i->openmax && openmax) {
105 		i->openmax = 1;
106 		changed = 1;
107 	}
108 	if (i->integer) {
109 		if (i->openmax) {
110 			i->max--;
111 			i->openmax = 0;
112 		}
113 	}
114 	if (snd_interval_checkempty(i)) {
115 		snd_interval_none(i);
116 		return -EINVAL;
117 	}
118 	return changed;
119 }
120 
121 static int snd_interval_refine_set(struct snd_interval *i, unsigned int val)
122 {
123 	struct snd_interval t;
124 	t.empty = 0;
125 	t.min = t.max = val;
126 	t.openmin = t.openmax = 0;
127 	t.integer = 1;
128 	return snd_interval_refine(i, &t);
129 }
130 
131 /**
132  * snd_pcm_hw_param_value_min
133  * @params: the hw_params instance
134  * @var: parameter to retrieve
135  * @dir: pointer to the direction (-1,0,1) or NULL
136  *
137  * Return the minimum value for field PAR.
138  */
139 static unsigned int
140 snd_pcm_hw_param_value_min(const struct snd_pcm_hw_params *params,
141 			   snd_pcm_hw_param_t var, int *dir)
142 {
143 	if (hw_is_mask(var)) {
144 		if (dir)
145 			*dir = 0;
146 		return snd_mask_min(hw_param_mask_c(params, var));
147 	}
148 	if (hw_is_interval(var)) {
149 		const struct snd_interval *i = hw_param_interval_c(params, var);
150 		if (dir)
151 			*dir = i->openmin;
152 		return snd_interval_min(i);
153 	}
154 	return -EINVAL;
155 }
156 
157 /**
158  * snd_pcm_hw_param_value_max
159  * @params: the hw_params instance
160  * @var: parameter to retrieve
161  * @dir: pointer to the direction (-1,0,1) or NULL
162  *
163  * Return the maximum value for field PAR.
164  */
165 static unsigned int
166 snd_pcm_hw_param_value_max(const struct snd_pcm_hw_params *params,
167 			   snd_pcm_hw_param_t var, int *dir)
168 {
169 	if (hw_is_mask(var)) {
170 		if (dir)
171 			*dir = 0;
172 		return snd_mask_max(hw_param_mask_c(params, var));
173 	}
174 	if (hw_is_interval(var)) {
175 		const struct snd_interval *i = hw_param_interval_c(params, var);
176 		if (dir)
177 			*dir = - (int) i->openmax;
178 		return snd_interval_max(i);
179 	}
180 	return -EINVAL;
181 }
182 
183 static int _snd_pcm_hw_param_mask(struct snd_pcm_hw_params *params,
184 				  snd_pcm_hw_param_t var,
185 				  const struct snd_mask *val)
186 {
187 	int changed;
188 	changed = snd_mask_refine(hw_param_mask(params, var), val);
189 	if (changed) {
190 		params->cmask |= 1 << var;
191 		params->rmask |= 1 << var;
192 	}
193 	return changed;
194 }
195 
196 static int snd_pcm_hw_param_mask(struct snd_pcm_substream *pcm,
197 				 struct snd_pcm_hw_params *params,
198 				 snd_pcm_hw_param_t var,
199 				 const struct snd_mask *val)
200 {
201 	int changed = _snd_pcm_hw_param_mask(params, var, val);
202 	if (changed < 0)
203 		return changed;
204 	if (params->rmask) {
205 		int err = snd_pcm_hw_refine(pcm, params);
206 		if (err < 0)
207 			return err;
208 	}
209 	return 0;
210 }
211 
212 static int _snd_pcm_hw_param_min(struct snd_pcm_hw_params *params,
213 				 snd_pcm_hw_param_t var, unsigned int val,
214 				 int dir)
215 {
216 	int changed;
217 	int open = 0;
218 	if (dir) {
219 		if (dir > 0) {
220 			open = 1;
221 		} else if (dir < 0) {
222 			if (val > 0) {
223 				open = 1;
224 				val--;
225 			}
226 		}
227 	}
228 	if (hw_is_mask(var))
229 		changed = snd_mask_refine_min(hw_param_mask(params, var),
230 					      val + !!open);
231 	else if (hw_is_interval(var))
232 		changed = snd_interval_refine_min(hw_param_interval(params, var),
233 						  val, open);
234 	else
235 		return -EINVAL;
236 	if (changed) {
237 		params->cmask |= 1 << var;
238 		params->rmask |= 1 << var;
239 	}
240 	return changed;
241 }
242 
243 /**
244  * snd_pcm_hw_param_min
245  * @pcm: PCM instance
246  * @params: the hw_params instance
247  * @var: parameter to retrieve
248  * @val: minimal value
249  * @dir: pointer to the direction (-1,0,1) or NULL
250  *
251  * Inside configuration space defined by PARAMS remove from PAR all
252  * values < VAL. Reduce configuration space accordingly.
253  * Return new minimum or -EINVAL if the configuration space is empty
254  */
255 static int snd_pcm_hw_param_min(struct snd_pcm_substream *pcm,
256 				struct snd_pcm_hw_params *params,
257 				snd_pcm_hw_param_t var, unsigned int val,
258 				int *dir)
259 {
260 	int changed = _snd_pcm_hw_param_min(params, var, val, dir ? *dir : 0);
261 	if (changed < 0)
262 		return changed;
263 	if (params->rmask) {
264 		int err = snd_pcm_hw_refine(pcm, params);
265 		if (err < 0)
266 			return err;
267 	}
268 	return snd_pcm_hw_param_value_min(params, var, dir);
269 }
270 
271 static int _snd_pcm_hw_param_max(struct snd_pcm_hw_params *params,
272 				 snd_pcm_hw_param_t var, unsigned int val,
273 				 int dir)
274 {
275 	int changed;
276 	int open = 0;
277 	if (dir) {
278 		if (dir < 0) {
279 			open = 1;
280 		} else if (dir > 0) {
281 			open = 1;
282 			val++;
283 		}
284 	}
285 	if (hw_is_mask(var)) {
286 		if (val == 0 && open) {
287 			snd_mask_none(hw_param_mask(params, var));
288 			changed = -EINVAL;
289 		} else
290 			changed = snd_mask_refine_max(hw_param_mask(params, var),
291 						      val - !!open);
292 	} else if (hw_is_interval(var))
293 		changed = snd_interval_refine_max(hw_param_interval(params, var),
294 						  val, open);
295 	else
296 		return -EINVAL;
297 	if (changed) {
298 		params->cmask |= 1 << var;
299 		params->rmask |= 1 << var;
300 	}
301 	return changed;
302 }
303 
304 /**
305  * snd_pcm_hw_param_max
306  * @pcm: PCM instance
307  * @params: the hw_params instance
308  * @var: parameter to retrieve
309  * @val: maximal value
310  * @dir: pointer to the direction (-1,0,1) or NULL
311  *
312  * Inside configuration space defined by PARAMS remove from PAR all
313  *  values >= VAL + 1. Reduce configuration space accordingly.
314  *  Return new maximum or -EINVAL if the configuration space is empty
315  */
316 static int snd_pcm_hw_param_max(struct snd_pcm_substream *pcm,
317 				struct snd_pcm_hw_params *params,
318 				snd_pcm_hw_param_t var, unsigned int val,
319 				int *dir)
320 {
321 	int changed = _snd_pcm_hw_param_max(params, var, val, dir ? *dir : 0);
322 	if (changed < 0)
323 		return changed;
324 	if (params->rmask) {
325 		int err = snd_pcm_hw_refine(pcm, params);
326 		if (err < 0)
327 			return err;
328 	}
329 	return snd_pcm_hw_param_value_max(params, var, dir);
330 }
331 
332 static int boundary_sub(int a, int adir,
333 			int b, int bdir,
334 			int *c, int *cdir)
335 {
336 	adir = adir < 0 ? -1 : (adir > 0 ? 1 : 0);
337 	bdir = bdir < 0 ? -1 : (bdir > 0 ? 1 : 0);
338 	*c = a - b;
339 	*cdir = adir - bdir;
340 	if (*cdir == -2) {
341 		(*c)--;
342 	} else if (*cdir == 2) {
343 		(*c)++;
344 	}
345 	return 0;
346 }
347 
348 static int boundary_lt(unsigned int a, int adir,
349 		       unsigned int b, int bdir)
350 {
351 	if (adir < 0) {
352 		a--;
353 		adir = 1;
354 	} else if (adir > 0)
355 		adir = 1;
356 	if (bdir < 0) {
357 		b--;
358 		bdir = 1;
359 	} else if (bdir > 0)
360 		bdir = 1;
361 	return a < b || (a == b && adir < bdir);
362 }
363 
364 /* Return 1 if min is nearer to best than max */
365 static int boundary_nearer(int min, int mindir,
366 			   int best, int bestdir,
367 			   int max, int maxdir)
368 {
369 	int dmin, dmindir;
370 	int dmax, dmaxdir;
371 	boundary_sub(best, bestdir, min, mindir, &dmin, &dmindir);
372 	boundary_sub(max, maxdir, best, bestdir, &dmax, &dmaxdir);
373 	return boundary_lt(dmin, dmindir, dmax, dmaxdir);
374 }
375 
376 /**
377  * snd_pcm_hw_param_near
378  * @pcm: PCM instance
379  * @params: the hw_params instance
380  * @var: parameter to retrieve
381  * @best: value to set
382  * @dir: pointer to the direction (-1,0,1) or NULL
383  *
384  * Inside configuration space defined by PARAMS set PAR to the available value
385  * nearest to VAL. Reduce configuration space accordingly.
386  * This function cannot be called for SNDRV_PCM_HW_PARAM_ACCESS,
387  * SNDRV_PCM_HW_PARAM_FORMAT, SNDRV_PCM_HW_PARAM_SUBFORMAT.
388  * Return the value found.
389   */
390 static int snd_pcm_hw_param_near(struct snd_pcm_substream *pcm,
391 				 struct snd_pcm_hw_params *params,
392 				 snd_pcm_hw_param_t var, unsigned int best,
393 				 int *dir)
394 {
395 	struct snd_pcm_hw_params *save = NULL;
396 	int v;
397 	unsigned int saved_min;
398 	int last = 0;
399 	int min, max;
400 	int mindir, maxdir;
401 	int valdir = dir ? *dir : 0;
402 	/* FIXME */
403 	if (best > INT_MAX)
404 		best = INT_MAX;
405 	min = max = best;
406 	mindir = maxdir = valdir;
407 	if (maxdir > 0)
408 		maxdir = 0;
409 	else if (maxdir == 0)
410 		maxdir = -1;
411 	else {
412 		maxdir = 1;
413 		max--;
414 	}
415 	save = kmalloc(sizeof(*save), GFP_KERNEL);
416 	if (save == NULL)
417 		return -ENOMEM;
418 	*save = *params;
419 	saved_min = min;
420 	min = snd_pcm_hw_param_min(pcm, params, var, min, &mindir);
421 	if (min >= 0) {
422 		struct snd_pcm_hw_params *params1;
423 		if (max < 0)
424 			goto _end;
425 		if ((unsigned int)min == saved_min && mindir == valdir)
426 			goto _end;
427 		params1 = kmalloc(sizeof(*params1), GFP_KERNEL);
428 		if (params1 == NULL) {
429 			kfree(save);
430 			return -ENOMEM;
431 		}
432 		*params1 = *save;
433 		max = snd_pcm_hw_param_max(pcm, params1, var, max, &maxdir);
434 		if (max < 0) {
435 			kfree(params1);
436 			goto _end;
437 		}
438 		if (boundary_nearer(max, maxdir, best, valdir, min, mindir)) {
439 			*params = *params1;
440 			last = 1;
441 		}
442 		kfree(params1);
443 	} else {
444 		*params = *save;
445 		max = snd_pcm_hw_param_max(pcm, params, var, max, &maxdir);
446 		if (max < 0) {
447 			kfree(save);
448 			return max;
449 		}
450 		last = 1;
451 	}
452  _end:
453  	kfree(save);
454 	if (last)
455 		v = snd_pcm_hw_param_last(pcm, params, var, dir);
456 	else
457 		v = snd_pcm_hw_param_first(pcm, params, var, dir);
458 	snd_BUG_ON(v < 0);
459 	return v;
460 }
461 
462 static int _snd_pcm_hw_param_set(struct snd_pcm_hw_params *params,
463 				 snd_pcm_hw_param_t var, unsigned int val,
464 				 int dir)
465 {
466 	int changed;
467 	if (hw_is_mask(var)) {
468 		struct snd_mask *m = hw_param_mask(params, var);
469 		if (val == 0 && dir < 0) {
470 			changed = -EINVAL;
471 			snd_mask_none(m);
472 		} else {
473 			if (dir > 0)
474 				val++;
475 			else if (dir < 0)
476 				val--;
477 			changed = snd_mask_refine_set(hw_param_mask(params, var), val);
478 		}
479 	} else if (hw_is_interval(var)) {
480 		struct snd_interval *i = hw_param_interval(params, var);
481 		if (val == 0 && dir < 0) {
482 			changed = -EINVAL;
483 			snd_interval_none(i);
484 		} else if (dir == 0)
485 			changed = snd_interval_refine_set(i, val);
486 		else {
487 			struct snd_interval t;
488 			t.openmin = 1;
489 			t.openmax = 1;
490 			t.empty = 0;
491 			t.integer = 0;
492 			if (dir < 0) {
493 				t.min = val - 1;
494 				t.max = val;
495 			} else {
496 				t.min = val;
497 				t.max = val+1;
498 			}
499 			changed = snd_interval_refine(i, &t);
500 		}
501 	} else
502 		return -EINVAL;
503 	if (changed) {
504 		params->cmask |= 1 << var;
505 		params->rmask |= 1 << var;
506 	}
507 	return changed;
508 }
509 
510 /**
511  * snd_pcm_hw_param_set
512  * @pcm: PCM instance
513  * @params: the hw_params instance
514  * @var: parameter to retrieve
515  * @val: value to set
516  * @dir: pointer to the direction (-1,0,1) or NULL
517  *
518  * Inside configuration space defined by PARAMS remove from PAR all
519  * values != VAL. Reduce configuration space accordingly.
520  *  Return VAL or -EINVAL if the configuration space is empty
521  */
522 static int snd_pcm_hw_param_set(struct snd_pcm_substream *pcm,
523 				struct snd_pcm_hw_params *params,
524 				snd_pcm_hw_param_t var, unsigned int val,
525 				int dir)
526 {
527 	int changed = _snd_pcm_hw_param_set(params, var, val, dir);
528 	if (changed < 0)
529 		return changed;
530 	if (params->rmask) {
531 		int err = snd_pcm_hw_refine(pcm, params);
532 		if (err < 0)
533 			return err;
534 	}
535 	return snd_pcm_hw_param_value(params, var, NULL);
536 }
537 
538 static int _snd_pcm_hw_param_setinteger(struct snd_pcm_hw_params *params,
539 					snd_pcm_hw_param_t var)
540 {
541 	int changed;
542 	changed = snd_interval_setinteger(hw_param_interval(params, var));
543 	if (changed) {
544 		params->cmask |= 1 << var;
545 		params->rmask |= 1 << var;
546 	}
547 	return changed;
548 }
549 
550 /*
551  * plugin
552  */
553 
554 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
555 static int snd_pcm_oss_plugin_clear(struct snd_pcm_substream *substream)
556 {
557 	struct snd_pcm_runtime *runtime = substream->runtime;
558 	struct snd_pcm_plugin *plugin, *next;
559 
560 	plugin = runtime->oss.plugin_first;
561 	while (plugin) {
562 		next = plugin->next;
563 		snd_pcm_plugin_free(plugin);
564 		plugin = next;
565 	}
566 	runtime->oss.plugin_first = runtime->oss.plugin_last = NULL;
567 	return 0;
568 }
569 
570 static int snd_pcm_plugin_insert(struct snd_pcm_plugin *plugin)
571 {
572 	struct snd_pcm_runtime *runtime = plugin->plug->runtime;
573 	plugin->next = runtime->oss.plugin_first;
574 	plugin->prev = NULL;
575 	if (runtime->oss.plugin_first) {
576 		runtime->oss.plugin_first->prev = plugin;
577 		runtime->oss.plugin_first = plugin;
578 	} else {
579 		runtime->oss.plugin_last =
580 		runtime->oss.plugin_first = plugin;
581 	}
582 	return 0;
583 }
584 
585 int snd_pcm_plugin_append(struct snd_pcm_plugin *plugin)
586 {
587 	struct snd_pcm_runtime *runtime = plugin->plug->runtime;
588 	plugin->next = NULL;
589 	plugin->prev = runtime->oss.plugin_last;
590 	if (runtime->oss.plugin_last) {
591 		runtime->oss.plugin_last->next = plugin;
592 		runtime->oss.plugin_last = plugin;
593 	} else {
594 		runtime->oss.plugin_last =
595 		runtime->oss.plugin_first = plugin;
596 	}
597 	return 0;
598 }
599 #endif /* CONFIG_SND_PCM_OSS_PLUGINS */
600 
601 static long snd_pcm_oss_bytes(struct snd_pcm_substream *substream, long frames)
602 {
603 	struct snd_pcm_runtime *runtime = substream->runtime;
604 	long buffer_size = snd_pcm_lib_buffer_bytes(substream);
605 	long bytes = frames_to_bytes(runtime, frames);
606 	if (buffer_size == runtime->oss.buffer_bytes)
607 		return bytes;
608 #if BITS_PER_LONG >= 64
609 	return runtime->oss.buffer_bytes * bytes / buffer_size;
610 #else
611 	{
612 		u64 bsize = (u64)runtime->oss.buffer_bytes * (u64)bytes;
613 		return div_u64(bsize, buffer_size);
614 	}
615 #endif
616 }
617 
618 static long snd_pcm_alsa_frames(struct snd_pcm_substream *substream, long bytes)
619 {
620 	struct snd_pcm_runtime *runtime = substream->runtime;
621 	long buffer_size = snd_pcm_lib_buffer_bytes(substream);
622 	if (buffer_size == runtime->oss.buffer_bytes)
623 		return bytes_to_frames(runtime, bytes);
624 	return bytes_to_frames(runtime, (buffer_size * bytes) / runtime->oss.buffer_bytes);
625 }
626 
627 static inline
628 snd_pcm_uframes_t get_hw_ptr_period(struct snd_pcm_runtime *runtime)
629 {
630 	return runtime->hw_ptr_interrupt;
631 }
632 
633 /* define extended formats in the recent OSS versions (if any) */
634 /* linear formats */
635 #define AFMT_S32_LE      0x00001000
636 #define AFMT_S32_BE      0x00002000
637 #define AFMT_S24_LE      0x00008000
638 #define AFMT_S24_BE      0x00010000
639 #define AFMT_S24_PACKED  0x00040000
640 
641 /* other supported formats */
642 #define AFMT_FLOAT       0x00004000
643 #define AFMT_SPDIF_RAW   0x00020000
644 
645 /* unsupported formats */
646 #define AFMT_AC3         0x00000400
647 #define AFMT_VORBIS      0x00000800
648 
649 static snd_pcm_format_t snd_pcm_oss_format_from(int format)
650 {
651 	switch (format) {
652 	case AFMT_MU_LAW:	return SNDRV_PCM_FORMAT_MU_LAW;
653 	case AFMT_A_LAW:	return SNDRV_PCM_FORMAT_A_LAW;
654 	case AFMT_IMA_ADPCM:	return SNDRV_PCM_FORMAT_IMA_ADPCM;
655 	case AFMT_U8:		return SNDRV_PCM_FORMAT_U8;
656 	case AFMT_S16_LE:	return SNDRV_PCM_FORMAT_S16_LE;
657 	case AFMT_S16_BE:	return SNDRV_PCM_FORMAT_S16_BE;
658 	case AFMT_S8:		return SNDRV_PCM_FORMAT_S8;
659 	case AFMT_U16_LE:	return SNDRV_PCM_FORMAT_U16_LE;
660 	case AFMT_U16_BE:	return SNDRV_PCM_FORMAT_U16_BE;
661 	case AFMT_MPEG:		return SNDRV_PCM_FORMAT_MPEG;
662 	case AFMT_S32_LE:	return SNDRV_PCM_FORMAT_S32_LE;
663 	case AFMT_S32_BE:	return SNDRV_PCM_FORMAT_S32_BE;
664 	case AFMT_S24_LE:	return SNDRV_PCM_FORMAT_S24_LE;
665 	case AFMT_S24_BE:	return SNDRV_PCM_FORMAT_S24_BE;
666 	case AFMT_S24_PACKED:	return SNDRV_PCM_FORMAT_S24_3LE;
667 	case AFMT_FLOAT:	return SNDRV_PCM_FORMAT_FLOAT;
668 	case AFMT_SPDIF_RAW:	return SNDRV_PCM_FORMAT_IEC958_SUBFRAME;
669 	default:		return SNDRV_PCM_FORMAT_U8;
670 	}
671 }
672 
673 static int snd_pcm_oss_format_to(snd_pcm_format_t format)
674 {
675 	switch (format) {
676 	case SNDRV_PCM_FORMAT_MU_LAW:	return AFMT_MU_LAW;
677 	case SNDRV_PCM_FORMAT_A_LAW:	return AFMT_A_LAW;
678 	case SNDRV_PCM_FORMAT_IMA_ADPCM:	return AFMT_IMA_ADPCM;
679 	case SNDRV_PCM_FORMAT_U8:		return AFMT_U8;
680 	case SNDRV_PCM_FORMAT_S16_LE:	return AFMT_S16_LE;
681 	case SNDRV_PCM_FORMAT_S16_BE:	return AFMT_S16_BE;
682 	case SNDRV_PCM_FORMAT_S8:		return AFMT_S8;
683 	case SNDRV_PCM_FORMAT_U16_LE:	return AFMT_U16_LE;
684 	case SNDRV_PCM_FORMAT_U16_BE:	return AFMT_U16_BE;
685 	case SNDRV_PCM_FORMAT_MPEG:		return AFMT_MPEG;
686 	case SNDRV_PCM_FORMAT_S32_LE:	return AFMT_S32_LE;
687 	case SNDRV_PCM_FORMAT_S32_BE:	return AFMT_S32_BE;
688 	case SNDRV_PCM_FORMAT_S24_LE:	return AFMT_S24_LE;
689 	case SNDRV_PCM_FORMAT_S24_BE:	return AFMT_S24_BE;
690 	case SNDRV_PCM_FORMAT_S24_3LE:	return AFMT_S24_PACKED;
691 	case SNDRV_PCM_FORMAT_FLOAT:	return AFMT_FLOAT;
692 	case SNDRV_PCM_FORMAT_IEC958_SUBFRAME: return AFMT_SPDIF_RAW;
693 	default:			return -EINVAL;
694 	}
695 }
696 
697 static int snd_pcm_oss_period_size(struct snd_pcm_substream *substream,
698 				   struct snd_pcm_hw_params *oss_params,
699 				   struct snd_pcm_hw_params *slave_params)
700 {
701 	size_t s;
702 	size_t oss_buffer_size, oss_period_size, oss_periods;
703 	size_t min_period_size, max_period_size;
704 	struct snd_pcm_runtime *runtime = substream->runtime;
705 	size_t oss_frame_size;
706 
707 	oss_frame_size = snd_pcm_format_physical_width(params_format(oss_params)) *
708 			 params_channels(oss_params) / 8;
709 
710 	oss_buffer_size = snd_pcm_plug_client_size(substream,
711 						   snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, NULL)) * oss_frame_size;
712 	oss_buffer_size = rounddown_pow_of_two(oss_buffer_size);
713 	if (atomic_read(&substream->mmap_count)) {
714 		if (oss_buffer_size > runtime->oss.mmap_bytes)
715 			oss_buffer_size = runtime->oss.mmap_bytes;
716 	}
717 
718 	if (substream->oss.setup.period_size > 16)
719 		oss_period_size = substream->oss.setup.period_size;
720 	else if (runtime->oss.fragshift) {
721 		oss_period_size = 1 << runtime->oss.fragshift;
722 		if (oss_period_size > oss_buffer_size / 2)
723 			oss_period_size = oss_buffer_size / 2;
724 	} else {
725 		int sd;
726 		size_t bytes_per_sec = params_rate(oss_params) * snd_pcm_format_physical_width(params_format(oss_params)) * params_channels(oss_params) / 8;
727 
728 		oss_period_size = oss_buffer_size;
729 		do {
730 			oss_period_size /= 2;
731 		} while (oss_period_size > bytes_per_sec);
732 		if (runtime->oss.subdivision == 0) {
733 			sd = 4;
734 			if (oss_period_size / sd > 4096)
735 				sd *= 2;
736 			if (oss_period_size / sd < 4096)
737 				sd = 1;
738 		} else
739 			sd = runtime->oss.subdivision;
740 		oss_period_size /= sd;
741 		if (oss_period_size < 16)
742 			oss_period_size = 16;
743 	}
744 
745 	min_period_size = snd_pcm_plug_client_size(substream,
746 						   snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
747 	min_period_size *= oss_frame_size;
748 	min_period_size = roundup_pow_of_two(min_period_size);
749 	if (oss_period_size < min_period_size)
750 		oss_period_size = min_period_size;
751 
752 	max_period_size = snd_pcm_plug_client_size(substream,
753 						   snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, NULL));
754 	max_period_size *= oss_frame_size;
755 	max_period_size = rounddown_pow_of_two(max_period_size);
756 	if (oss_period_size > max_period_size)
757 		oss_period_size = max_period_size;
758 
759 	oss_periods = oss_buffer_size / oss_period_size;
760 
761 	if (substream->oss.setup.periods > 1)
762 		oss_periods = substream->oss.setup.periods;
763 
764 	s = snd_pcm_hw_param_value_max(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL);
765 	if (runtime->oss.maxfrags && s > runtime->oss.maxfrags)
766 		s = runtime->oss.maxfrags;
767 	if (oss_periods > s)
768 		oss_periods = s;
769 
770 	s = snd_pcm_hw_param_value_min(slave_params, SNDRV_PCM_HW_PARAM_PERIODS, NULL);
771 	if (s < 2)
772 		s = 2;
773 	if (oss_periods < s)
774 		oss_periods = s;
775 
776 	while (oss_period_size * oss_periods > oss_buffer_size)
777 		oss_period_size /= 2;
778 
779 	if (oss_period_size < 16)
780 		return -EINVAL;
781 	runtime->oss.period_bytes = oss_period_size;
782 	runtime->oss.period_frames = 1;
783 	runtime->oss.periods = oss_periods;
784 	return 0;
785 }
786 
787 static int choose_rate(struct snd_pcm_substream *substream,
788 		       struct snd_pcm_hw_params *params, unsigned int best_rate)
789 {
790 	const struct snd_interval *it;
791 	struct snd_pcm_hw_params *save;
792 	unsigned int rate, prev;
793 
794 	save = kmalloc(sizeof(*save), GFP_KERNEL);
795 	if (save == NULL)
796 		return -ENOMEM;
797 	*save = *params;
798 	it = hw_param_interval_c(save, SNDRV_PCM_HW_PARAM_RATE);
799 
800 	/* try multiples of the best rate */
801 	rate = best_rate;
802 	for (;;) {
803 		if (it->max < rate || (it->max == rate && it->openmax))
804 			break;
805 		if (it->min < rate || (it->min == rate && !it->openmin)) {
806 			int ret;
807 			ret = snd_pcm_hw_param_set(substream, params,
808 						   SNDRV_PCM_HW_PARAM_RATE,
809 						   rate, 0);
810 			if (ret == (int)rate) {
811 				kfree(save);
812 				return rate;
813 			}
814 			*params = *save;
815 		}
816 		prev = rate;
817 		rate += best_rate;
818 		if (rate <= prev)
819 			break;
820 	}
821 
822 	/* not found, use the nearest rate */
823 	kfree(save);
824 	return snd_pcm_hw_param_near(substream, params, SNDRV_PCM_HW_PARAM_RATE, best_rate, NULL);
825 }
826 
827 static int snd_pcm_oss_change_params(struct snd_pcm_substream *substream,
828 				     bool trylock)
829 {
830 	struct snd_pcm_runtime *runtime = substream->runtime;
831 	struct snd_pcm_hw_params *params, *sparams;
832 	struct snd_pcm_sw_params *sw_params;
833 	ssize_t oss_buffer_size, oss_period_size;
834 	size_t oss_frame_size;
835 	int err;
836 	int direct;
837 	snd_pcm_format_t format, sformat;
838 	int n;
839 	const struct snd_mask *sformat_mask;
840 	struct snd_mask mask;
841 
842 	if (trylock) {
843 		if (!(mutex_trylock(&runtime->oss.params_lock)))
844 			return -EAGAIN;
845 	} else if (mutex_lock_interruptible(&runtime->oss.params_lock))
846 		return -EINTR;
847 	sw_params = kzalloc(sizeof(*sw_params), GFP_KERNEL);
848 	params = kmalloc(sizeof(*params), GFP_KERNEL);
849 	sparams = kmalloc(sizeof(*sparams), GFP_KERNEL);
850 	if (!sw_params || !params || !sparams) {
851 		err = -ENOMEM;
852 		goto failure;
853 	}
854 
855 	if (atomic_read(&substream->mmap_count))
856 		direct = 1;
857 	else
858 		direct = substream->oss.setup.direct;
859 
860 	_snd_pcm_hw_params_any(sparams);
861 	_snd_pcm_hw_param_setinteger(sparams, SNDRV_PCM_HW_PARAM_PERIODS);
862 	_snd_pcm_hw_param_min(sparams, SNDRV_PCM_HW_PARAM_PERIODS, 2, 0);
863 	snd_mask_none(&mask);
864 	if (atomic_read(&substream->mmap_count))
865 		snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_MMAP_INTERLEAVED);
866 	else {
867 		snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED);
868 		if (!direct)
869 			snd_mask_set(&mask, (__force int)SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
870 	}
871 	err = snd_pcm_hw_param_mask(substream, sparams, SNDRV_PCM_HW_PARAM_ACCESS, &mask);
872 	if (err < 0) {
873 		pcm_dbg(substream->pcm, "No usable accesses\n");
874 		err = -EINVAL;
875 		goto failure;
876 	}
877 	choose_rate(substream, sparams, runtime->oss.rate);
878 	snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_CHANNELS, runtime->oss.channels, NULL);
879 
880 	format = snd_pcm_oss_format_from(runtime->oss.format);
881 
882 	sformat_mask = hw_param_mask_c(sparams, SNDRV_PCM_HW_PARAM_FORMAT);
883 	if (direct)
884 		sformat = format;
885 	else
886 		sformat = snd_pcm_plug_slave_format(format, sformat_mask);
887 
888 	if ((__force int)sformat < 0 ||
889 	    !snd_mask_test(sformat_mask, (__force int)sformat)) {
890 		for (sformat = (__force snd_pcm_format_t)0;
891 		     (__force int)sformat <= (__force int)SNDRV_PCM_FORMAT_LAST;
892 		     sformat = (__force snd_pcm_format_t)((__force int)sformat + 1)) {
893 			if (snd_mask_test(sformat_mask, (__force int)sformat) &&
894 			    snd_pcm_oss_format_to(sformat) >= 0)
895 				break;
896 		}
897 		if ((__force int)sformat > (__force int)SNDRV_PCM_FORMAT_LAST) {
898 			pcm_dbg(substream->pcm, "Cannot find a format!!!\n");
899 			err = -EINVAL;
900 			goto failure;
901 		}
902 	}
903 	err = _snd_pcm_hw_param_set(sparams, SNDRV_PCM_HW_PARAM_FORMAT, (__force int)sformat, 0);
904 	if (err < 0)
905 		goto failure;
906 
907 	if (direct) {
908 		memcpy(params, sparams, sizeof(*params));
909 	} else {
910 		_snd_pcm_hw_params_any(params);
911 		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_ACCESS,
912 				      (__force int)SNDRV_PCM_ACCESS_RW_INTERLEAVED, 0);
913 		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_FORMAT,
914 				      (__force int)snd_pcm_oss_format_from(runtime->oss.format), 0);
915 		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_CHANNELS,
916 				      runtime->oss.channels, 0);
917 		_snd_pcm_hw_param_set(params, SNDRV_PCM_HW_PARAM_RATE,
918 				      runtime->oss.rate, 0);
919 		pdprintf("client: access = %i, format = %i, channels = %i, rate = %i\n",
920 			 params_access(params), params_format(params),
921 			 params_channels(params), params_rate(params));
922 	}
923 	pdprintf("slave: access = %i, format = %i, channels = %i, rate = %i\n",
924 		 params_access(sparams), params_format(sparams),
925 		 params_channels(sparams), params_rate(sparams));
926 
927 	oss_frame_size = snd_pcm_format_physical_width(params_format(params)) *
928 			 params_channels(params) / 8;
929 
930 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
931 	snd_pcm_oss_plugin_clear(substream);
932 	if (!direct) {
933 		/* add necessary plugins */
934 		snd_pcm_oss_plugin_clear(substream);
935 		if ((err = snd_pcm_plug_format_plugins(substream,
936 						       params,
937 						       sparams)) < 0) {
938 			pcm_dbg(substream->pcm,
939 				"snd_pcm_plug_format_plugins failed: %i\n", err);
940 			snd_pcm_oss_plugin_clear(substream);
941 			goto failure;
942 		}
943 		if (runtime->oss.plugin_first) {
944 			struct snd_pcm_plugin *plugin;
945 			if ((err = snd_pcm_plugin_build_io(substream, sparams, &plugin)) < 0) {
946 				pcm_dbg(substream->pcm,
947 					"snd_pcm_plugin_build_io failed: %i\n", err);
948 				snd_pcm_oss_plugin_clear(substream);
949 				goto failure;
950 			}
951 			if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
952 				err = snd_pcm_plugin_append(plugin);
953 			} else {
954 				err = snd_pcm_plugin_insert(plugin);
955 			}
956 			if (err < 0) {
957 				snd_pcm_oss_plugin_clear(substream);
958 				goto failure;
959 			}
960 		}
961 	}
962 #endif
963 
964 	err = snd_pcm_oss_period_size(substream, params, sparams);
965 	if (err < 0)
966 		goto failure;
967 
968 	n = snd_pcm_plug_slave_size(substream, runtime->oss.period_bytes / oss_frame_size);
969 	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, n, NULL);
970 	if (err < 0)
971 		goto failure;
972 
973 	err = snd_pcm_hw_param_near(substream, sparams, SNDRV_PCM_HW_PARAM_PERIODS,
974 				     runtime->oss.periods, NULL);
975 	if (err < 0)
976 		goto failure;
977 
978 	snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
979 
980 	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_HW_PARAMS, sparams)) < 0) {
981 		pcm_dbg(substream->pcm, "HW_PARAMS failed: %i\n", err);
982 		goto failure;
983 	}
984 
985 	if (runtime->oss.trigger) {
986 		sw_params->start_threshold = 1;
987 	} else {
988 		sw_params->start_threshold = runtime->boundary;
989 	}
990 	if (atomic_read(&substream->mmap_count) ||
991 	    substream->stream == SNDRV_PCM_STREAM_CAPTURE)
992 		sw_params->stop_threshold = runtime->boundary;
993 	else
994 		sw_params->stop_threshold = runtime->buffer_size;
995 	sw_params->tstamp_mode = SNDRV_PCM_TSTAMP_NONE;
996 	sw_params->period_step = 1;
997 	sw_params->avail_min = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
998 		1 : runtime->period_size;
999 	if (atomic_read(&substream->mmap_count) ||
1000 	    substream->oss.setup.nosilence) {
1001 		sw_params->silence_threshold = 0;
1002 		sw_params->silence_size = 0;
1003 	} else {
1004 		snd_pcm_uframes_t frames;
1005 		frames = runtime->period_size + 16;
1006 		if (frames > runtime->buffer_size)
1007 			frames = runtime->buffer_size;
1008 		sw_params->silence_threshold = frames;
1009 		sw_params->silence_size = frames;
1010 	}
1011 
1012 	if ((err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_SW_PARAMS, sw_params)) < 0) {
1013 		pcm_dbg(substream->pcm, "SW_PARAMS failed: %i\n", err);
1014 		goto failure;
1015 	}
1016 
1017 	runtime->oss.periods = params_periods(sparams);
1018 	oss_period_size = snd_pcm_plug_client_size(substream, params_period_size(sparams));
1019 	if (oss_period_size < 0) {
1020 		err = -EINVAL;
1021 		goto failure;
1022 	}
1023 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
1024 	if (runtime->oss.plugin_first) {
1025 		err = snd_pcm_plug_alloc(substream, oss_period_size);
1026 		if (err < 0)
1027 			goto failure;
1028 	}
1029 #endif
1030 	oss_period_size *= oss_frame_size;
1031 
1032 	oss_buffer_size = oss_period_size * runtime->oss.periods;
1033 	if (oss_buffer_size < 0) {
1034 		err = -EINVAL;
1035 		goto failure;
1036 	}
1037 
1038 	runtime->oss.period_bytes = oss_period_size;
1039 	runtime->oss.buffer_bytes = oss_buffer_size;
1040 
1041 	pdprintf("oss: period bytes = %i, buffer bytes = %i\n",
1042 		 runtime->oss.period_bytes,
1043 		 runtime->oss.buffer_bytes);
1044 	pdprintf("slave: period_size = %i, buffer_size = %i\n",
1045 		 params_period_size(sparams),
1046 		 params_buffer_size(sparams));
1047 
1048 	runtime->oss.format = snd_pcm_oss_format_to(params_format(params));
1049 	runtime->oss.channels = params_channels(params);
1050 	runtime->oss.rate = params_rate(params);
1051 
1052 	vfree(runtime->oss.buffer);
1053 	runtime->oss.buffer = vmalloc(runtime->oss.period_bytes);
1054 	if (!runtime->oss.buffer) {
1055 		err = -ENOMEM;
1056 		goto failure;
1057 	}
1058 
1059 	runtime->oss.params = 0;
1060 	runtime->oss.prepare = 1;
1061 	runtime->oss.buffer_used = 0;
1062 	if (runtime->dma_area)
1063 		snd_pcm_format_set_silence(runtime->format, runtime->dma_area, bytes_to_samples(runtime, runtime->dma_bytes));
1064 
1065 	runtime->oss.period_frames = snd_pcm_alsa_frames(substream, oss_period_size);
1066 
1067 	err = 0;
1068 failure:
1069 	kfree(sw_params);
1070 	kfree(params);
1071 	kfree(sparams);
1072 	mutex_unlock(&runtime->oss.params_lock);
1073 	return err;
1074 }
1075 
1076 static int snd_pcm_oss_get_active_substream(struct snd_pcm_oss_file *pcm_oss_file, struct snd_pcm_substream **r_substream)
1077 {
1078 	int idx, err;
1079 	struct snd_pcm_substream *asubstream = NULL, *substream;
1080 
1081 	for (idx = 0; idx < 2; idx++) {
1082 		substream = pcm_oss_file->streams[idx];
1083 		if (substream == NULL)
1084 			continue;
1085 		if (asubstream == NULL)
1086 			asubstream = substream;
1087 		if (substream->runtime->oss.params) {
1088 			err = snd_pcm_oss_change_params(substream, false);
1089 			if (err < 0)
1090 				return err;
1091 		}
1092 	}
1093 	if (!asubstream)
1094 		return -EIO;
1095 	if (r_substream)
1096 		*r_substream = asubstream;
1097 	return 0;
1098 }
1099 
1100 static int snd_pcm_oss_prepare(struct snd_pcm_substream *substream)
1101 {
1102 	int err;
1103 	struct snd_pcm_runtime *runtime = substream->runtime;
1104 
1105 	err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_PREPARE, NULL);
1106 	if (err < 0) {
1107 		pcm_dbg(substream->pcm,
1108 			"snd_pcm_oss_prepare: SNDRV_PCM_IOCTL_PREPARE failed\n");
1109 		return err;
1110 	}
1111 	runtime->oss.prepare = 0;
1112 	runtime->oss.prev_hw_ptr_period = 0;
1113 	runtime->oss.period_ptr = 0;
1114 	runtime->oss.buffer_used = 0;
1115 
1116 	return 0;
1117 }
1118 
1119 static int snd_pcm_oss_make_ready(struct snd_pcm_substream *substream)
1120 {
1121 	struct snd_pcm_runtime *runtime;
1122 	int err;
1123 
1124 	if (substream == NULL)
1125 		return 0;
1126 	runtime = substream->runtime;
1127 	if (runtime->oss.params) {
1128 		err = snd_pcm_oss_change_params(substream, false);
1129 		if (err < 0)
1130 			return err;
1131 	}
1132 	if (runtime->oss.prepare) {
1133 		err = snd_pcm_oss_prepare(substream);
1134 		if (err < 0)
1135 			return err;
1136 	}
1137 	return 0;
1138 }
1139 
1140 static int snd_pcm_oss_capture_position_fixup(struct snd_pcm_substream *substream, snd_pcm_sframes_t *delay)
1141 {
1142 	struct snd_pcm_runtime *runtime;
1143 	snd_pcm_uframes_t frames;
1144 	int err = 0;
1145 
1146 	while (1) {
1147 		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, delay);
1148 		if (err < 0)
1149 			break;
1150 		runtime = substream->runtime;
1151 		if (*delay <= (snd_pcm_sframes_t)runtime->buffer_size)
1152 			break;
1153 		/* in case of overrun, skip whole periods like OSS/Linux driver does */
1154 		/* until avail(delay) <= buffer_size */
1155 		frames = (*delay - runtime->buffer_size) + runtime->period_size - 1;
1156 		frames /= runtime->period_size;
1157 		frames *= runtime->period_size;
1158 		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_FORWARD, &frames);
1159 		if (err < 0)
1160 			break;
1161 	}
1162 	return err;
1163 }
1164 
1165 snd_pcm_sframes_t snd_pcm_oss_write3(struct snd_pcm_substream *substream, const char *ptr, snd_pcm_uframes_t frames, int in_kernel)
1166 {
1167 	struct snd_pcm_runtime *runtime = substream->runtime;
1168 	int ret;
1169 	while (1) {
1170 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
1171 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1172 #ifdef OSS_DEBUG
1173 			pcm_dbg(substream->pcm,
1174 				"pcm_oss: write: recovering from %s\n",
1175 				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
1176 				"XRUN" : "SUSPEND");
1177 #endif
1178 			ret = snd_pcm_oss_prepare(substream);
1179 			if (ret < 0)
1180 				break;
1181 		}
1182 		ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
1183 					 frames, in_kernel);
1184 		if (ret != -EPIPE && ret != -ESTRPIPE)
1185 			break;
1186 		/* test, if we can't store new data, because the stream */
1187 		/* has not been started */
1188 		if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
1189 			return -EAGAIN;
1190 	}
1191 	return ret;
1192 }
1193 
1194 snd_pcm_sframes_t snd_pcm_oss_read3(struct snd_pcm_substream *substream, char *ptr, snd_pcm_uframes_t frames, int in_kernel)
1195 {
1196 	struct snd_pcm_runtime *runtime = substream->runtime;
1197 	snd_pcm_sframes_t delay;
1198 	int ret;
1199 	while (1) {
1200 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
1201 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1202 #ifdef OSS_DEBUG
1203 			pcm_dbg(substream->pcm,
1204 				"pcm_oss: read: recovering from %s\n",
1205 				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
1206 				"XRUN" : "SUSPEND");
1207 #endif
1208 			ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1209 			if (ret < 0)
1210 				break;
1211 		} else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) {
1212 			ret = snd_pcm_oss_prepare(substream);
1213 			if (ret < 0)
1214 				break;
1215 		}
1216 		ret = snd_pcm_oss_capture_position_fixup(substream, &delay);
1217 		if (ret < 0)
1218 			break;
1219 		ret = __snd_pcm_lib_xfer(substream, (void *)ptr, true,
1220 					 frames, in_kernel);
1221 		if (ret == -EPIPE) {
1222 			if (runtime->status->state == SNDRV_PCM_STATE_DRAINING) {
1223 				ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
1224 				if (ret < 0)
1225 					break;
1226 			}
1227 			continue;
1228 		}
1229 		if (ret != -ESTRPIPE)
1230 			break;
1231 	}
1232 	return ret;
1233 }
1234 
1235 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
1236 snd_pcm_sframes_t snd_pcm_oss_writev3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames)
1237 {
1238 	struct snd_pcm_runtime *runtime = substream->runtime;
1239 	int ret;
1240 	while (1) {
1241 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
1242 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1243 #ifdef OSS_DEBUG
1244 			pcm_dbg(substream->pcm,
1245 				"pcm_oss: writev: recovering from %s\n",
1246 				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
1247 				"XRUN" : "SUSPEND");
1248 #endif
1249 			ret = snd_pcm_oss_prepare(substream);
1250 			if (ret < 0)
1251 				break;
1252 		}
1253 		ret = snd_pcm_kernel_writev(substream, bufs, frames);
1254 		if (ret != -EPIPE && ret != -ESTRPIPE)
1255 			break;
1256 
1257 		/* test, if we can't store new data, because the stream */
1258 		/* has not been started */
1259 		if (runtime->status->state == SNDRV_PCM_STATE_PREPARED)
1260 			return -EAGAIN;
1261 	}
1262 	return ret;
1263 }
1264 
1265 snd_pcm_sframes_t snd_pcm_oss_readv3(struct snd_pcm_substream *substream, void **bufs, snd_pcm_uframes_t frames)
1266 {
1267 	struct snd_pcm_runtime *runtime = substream->runtime;
1268 	int ret;
1269 	while (1) {
1270 		if (runtime->status->state == SNDRV_PCM_STATE_XRUN ||
1271 		    runtime->status->state == SNDRV_PCM_STATE_SUSPENDED) {
1272 #ifdef OSS_DEBUG
1273 			pcm_dbg(substream->pcm,
1274 				"pcm_oss: readv: recovering from %s\n",
1275 				runtime->status->state == SNDRV_PCM_STATE_XRUN ?
1276 				"XRUN" : "SUSPEND");
1277 #endif
1278 			ret = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1279 			if (ret < 0)
1280 				break;
1281 		} else if (runtime->status->state == SNDRV_PCM_STATE_SETUP) {
1282 			ret = snd_pcm_oss_prepare(substream);
1283 			if (ret < 0)
1284 				break;
1285 		}
1286 		ret = snd_pcm_kernel_readv(substream, bufs, frames);
1287 		if (ret != -EPIPE && ret != -ESTRPIPE)
1288 			break;
1289 	}
1290 	return ret;
1291 }
1292 #endif /* CONFIG_SND_PCM_OSS_PLUGINS */
1293 
1294 static ssize_t snd_pcm_oss_write2(struct snd_pcm_substream *substream, const char *buf, size_t bytes, int in_kernel)
1295 {
1296 	struct snd_pcm_runtime *runtime = substream->runtime;
1297 	snd_pcm_sframes_t frames, frames1;
1298 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
1299 	if (runtime->oss.plugin_first) {
1300 		struct snd_pcm_plugin_channel *channels;
1301 		size_t oss_frame_bytes = (runtime->oss.plugin_first->src_width * runtime->oss.plugin_first->src_format.channels) / 8;
1302 		if (!in_kernel) {
1303 			if (copy_from_user(runtime->oss.buffer, (const char __force __user *)buf, bytes))
1304 				return -EFAULT;
1305 			buf = runtime->oss.buffer;
1306 		}
1307 		frames = bytes / oss_frame_bytes;
1308 		frames1 = snd_pcm_plug_client_channels_buf(substream, (char *)buf, frames, &channels);
1309 		if (frames1 < 0)
1310 			return frames1;
1311 		frames1 = snd_pcm_plug_write_transfer(substream, channels, frames1);
1312 		if (frames1 <= 0)
1313 			return frames1;
1314 		bytes = frames1 * oss_frame_bytes;
1315 	} else
1316 #endif
1317 	{
1318 		frames = bytes_to_frames(runtime, bytes);
1319 		frames1 = snd_pcm_oss_write3(substream, buf, frames, in_kernel);
1320 		if (frames1 <= 0)
1321 			return frames1;
1322 		bytes = frames_to_bytes(runtime, frames1);
1323 	}
1324 	return bytes;
1325 }
1326 
1327 static ssize_t snd_pcm_oss_write1(struct snd_pcm_substream *substream, const char __user *buf, size_t bytes)
1328 {
1329 	size_t xfer = 0;
1330 	ssize_t tmp;
1331 	struct snd_pcm_runtime *runtime = substream->runtime;
1332 
1333 	if (atomic_read(&substream->mmap_count))
1334 		return -ENXIO;
1335 
1336 	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
1337 		return tmp;
1338 	mutex_lock(&runtime->oss.params_lock);
1339 	while (bytes > 0) {
1340 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
1341 			tmp = bytes;
1342 			if (tmp + runtime->oss.buffer_used > runtime->oss.period_bytes)
1343 				tmp = runtime->oss.period_bytes - runtime->oss.buffer_used;
1344 			if (tmp > 0) {
1345 				if (copy_from_user(runtime->oss.buffer + runtime->oss.buffer_used, buf, tmp)) {
1346 					tmp = -EFAULT;
1347 					goto err;
1348 				}
1349 			}
1350 			runtime->oss.buffer_used += tmp;
1351 			buf += tmp;
1352 			bytes -= tmp;
1353 			xfer += tmp;
1354 			if (substream->oss.setup.partialfrag ||
1355 			    runtime->oss.buffer_used == runtime->oss.period_bytes) {
1356 				tmp = snd_pcm_oss_write2(substream, runtime->oss.buffer + runtime->oss.period_ptr,
1357 							 runtime->oss.buffer_used - runtime->oss.period_ptr, 1);
1358 				if (tmp <= 0)
1359 					goto err;
1360 				runtime->oss.bytes += tmp;
1361 				runtime->oss.period_ptr += tmp;
1362 				runtime->oss.period_ptr %= runtime->oss.period_bytes;
1363 				if (runtime->oss.period_ptr == 0 ||
1364 				    runtime->oss.period_ptr == runtime->oss.buffer_used)
1365 					runtime->oss.buffer_used = 0;
1366 				else if ((substream->f_flags & O_NONBLOCK) != 0) {
1367 					tmp = -EAGAIN;
1368 					goto err;
1369 				}
1370 			}
1371 		} else {
1372 			tmp = snd_pcm_oss_write2(substream,
1373 						 (const char __force *)buf,
1374 						 runtime->oss.period_bytes, 0);
1375 			if (tmp <= 0)
1376 				goto err;
1377 			runtime->oss.bytes += tmp;
1378 			buf += tmp;
1379 			bytes -= tmp;
1380 			xfer += tmp;
1381 			if ((substream->f_flags & O_NONBLOCK) != 0 &&
1382 			    tmp != runtime->oss.period_bytes)
1383 				break;
1384 		}
1385 	}
1386 	mutex_unlock(&runtime->oss.params_lock);
1387 	return xfer;
1388 
1389  err:
1390 	mutex_unlock(&runtime->oss.params_lock);
1391 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
1392 }
1393 
1394 static ssize_t snd_pcm_oss_read2(struct snd_pcm_substream *substream, char *buf, size_t bytes, int in_kernel)
1395 {
1396 	struct snd_pcm_runtime *runtime = substream->runtime;
1397 	snd_pcm_sframes_t frames, frames1;
1398 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
1399 	char __user *final_dst = (char __force __user *)buf;
1400 	if (runtime->oss.plugin_first) {
1401 		struct snd_pcm_plugin_channel *channels;
1402 		size_t oss_frame_bytes = (runtime->oss.plugin_last->dst_width * runtime->oss.plugin_last->dst_format.channels) / 8;
1403 		if (!in_kernel)
1404 			buf = runtime->oss.buffer;
1405 		frames = bytes / oss_frame_bytes;
1406 		frames1 = snd_pcm_plug_client_channels_buf(substream, buf, frames, &channels);
1407 		if (frames1 < 0)
1408 			return frames1;
1409 		frames1 = snd_pcm_plug_read_transfer(substream, channels, frames1);
1410 		if (frames1 <= 0)
1411 			return frames1;
1412 		bytes = frames1 * oss_frame_bytes;
1413 		if (!in_kernel && copy_to_user(final_dst, buf, bytes))
1414 			return -EFAULT;
1415 	} else
1416 #endif
1417 	{
1418 		frames = bytes_to_frames(runtime, bytes);
1419 		frames1 = snd_pcm_oss_read3(substream, buf, frames, in_kernel);
1420 		if (frames1 <= 0)
1421 			return frames1;
1422 		bytes = frames_to_bytes(runtime, frames1);
1423 	}
1424 	return bytes;
1425 }
1426 
1427 static ssize_t snd_pcm_oss_read1(struct snd_pcm_substream *substream, char __user *buf, size_t bytes)
1428 {
1429 	size_t xfer = 0;
1430 	ssize_t tmp;
1431 	struct snd_pcm_runtime *runtime = substream->runtime;
1432 
1433 	if (atomic_read(&substream->mmap_count))
1434 		return -ENXIO;
1435 
1436 	if ((tmp = snd_pcm_oss_make_ready(substream)) < 0)
1437 		return tmp;
1438 	mutex_lock(&runtime->oss.params_lock);
1439 	while (bytes > 0) {
1440 		if (bytes < runtime->oss.period_bytes || runtime->oss.buffer_used > 0) {
1441 			if (runtime->oss.buffer_used == 0) {
1442 				tmp = snd_pcm_oss_read2(substream, runtime->oss.buffer, runtime->oss.period_bytes, 1);
1443 				if (tmp <= 0)
1444 					goto err;
1445 				runtime->oss.bytes += tmp;
1446 				runtime->oss.period_ptr = tmp;
1447 				runtime->oss.buffer_used = tmp;
1448 			}
1449 			tmp = bytes;
1450 			if ((size_t) tmp > runtime->oss.buffer_used)
1451 				tmp = runtime->oss.buffer_used;
1452 			if (copy_to_user(buf, runtime->oss.buffer + (runtime->oss.period_ptr - runtime->oss.buffer_used), tmp)) {
1453 				tmp = -EFAULT;
1454 				goto err;
1455 			}
1456 			buf += tmp;
1457 			bytes -= tmp;
1458 			xfer += tmp;
1459 			runtime->oss.buffer_used -= tmp;
1460 		} else {
1461 			tmp = snd_pcm_oss_read2(substream, (char __force *)buf,
1462 						runtime->oss.period_bytes, 0);
1463 			if (tmp <= 0)
1464 				goto err;
1465 			runtime->oss.bytes += tmp;
1466 			buf += tmp;
1467 			bytes -= tmp;
1468 			xfer += tmp;
1469 		}
1470 	}
1471 	mutex_unlock(&runtime->oss.params_lock);
1472 	return xfer;
1473 
1474  err:
1475 	mutex_unlock(&runtime->oss.params_lock);
1476 	return xfer > 0 ? (snd_pcm_sframes_t)xfer : tmp;
1477 }
1478 
1479 static int snd_pcm_oss_reset(struct snd_pcm_oss_file *pcm_oss_file)
1480 {
1481 	struct snd_pcm_substream *substream;
1482 	struct snd_pcm_runtime *runtime;
1483 	int i;
1484 
1485 	for (i = 0; i < 2; i++) {
1486 		substream = pcm_oss_file->streams[i];
1487 		if (!substream)
1488 			continue;
1489 		runtime = substream->runtime;
1490 		snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
1491 		runtime->oss.prepare = 1;
1492 		runtime->oss.buffer_used = 0;
1493 		runtime->oss.prev_hw_ptr_period = 0;
1494 		runtime->oss.period_ptr = 0;
1495 	}
1496 	return 0;
1497 }
1498 
1499 static int snd_pcm_oss_post(struct snd_pcm_oss_file *pcm_oss_file)
1500 {
1501 	struct snd_pcm_substream *substream;
1502 	int err;
1503 
1504 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
1505 	if (substream != NULL) {
1506 		if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1507 			return err;
1508 		snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_START, NULL);
1509 	}
1510 	/* note: all errors from the start action are ignored */
1511 	/* OSS apps do not know, how to handle them */
1512 	return 0;
1513 }
1514 
1515 static int snd_pcm_oss_sync1(struct snd_pcm_substream *substream, size_t size)
1516 {
1517 	struct snd_pcm_runtime *runtime;
1518 	ssize_t result = 0;
1519 	snd_pcm_state_t state;
1520 	long res;
1521 	wait_queue_t wait;
1522 
1523 	runtime = substream->runtime;
1524 	init_waitqueue_entry(&wait, current);
1525 	add_wait_queue(&runtime->sleep, &wait);
1526 #ifdef OSS_DEBUG
1527 	pcm_dbg(substream->pcm, "sync1: size = %li\n", size);
1528 #endif
1529 	while (1) {
1530 		result = snd_pcm_oss_write2(substream, runtime->oss.buffer, size, 1);
1531 		if (result > 0) {
1532 			runtime->oss.buffer_used = 0;
1533 			result = 0;
1534 			break;
1535 		}
1536 		if (result != 0 && result != -EAGAIN)
1537 			break;
1538 		result = 0;
1539 		set_current_state(TASK_INTERRUPTIBLE);
1540 		snd_pcm_stream_lock_irq(substream);
1541 		state = runtime->status->state;
1542 		snd_pcm_stream_unlock_irq(substream);
1543 		if (state != SNDRV_PCM_STATE_RUNNING) {
1544 			set_current_state(TASK_RUNNING);
1545 			break;
1546 		}
1547 		res = schedule_timeout(10 * HZ);
1548 		if (signal_pending(current)) {
1549 			result = -ERESTARTSYS;
1550 			break;
1551 		}
1552 		if (res == 0) {
1553 			pcm_err(substream->pcm,
1554 				"OSS sync error - DMA timeout\n");
1555 			result = -EIO;
1556 			break;
1557 		}
1558 	}
1559 	remove_wait_queue(&runtime->sleep, &wait);
1560 	return result;
1561 }
1562 
1563 static int snd_pcm_oss_sync(struct snd_pcm_oss_file *pcm_oss_file)
1564 {
1565 	int err = 0;
1566 	unsigned int saved_f_flags;
1567 	struct snd_pcm_substream *substream;
1568 	struct snd_pcm_runtime *runtime;
1569 	snd_pcm_format_t format;
1570 	unsigned long width;
1571 	size_t size;
1572 
1573 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
1574 	if (substream != NULL) {
1575 		runtime = substream->runtime;
1576 		if (atomic_read(&substream->mmap_count))
1577 			goto __direct;
1578 		if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1579 			return err;
1580 		format = snd_pcm_oss_format_from(runtime->oss.format);
1581 		width = snd_pcm_format_physical_width(format);
1582 		mutex_lock(&runtime->oss.params_lock);
1583 		if (runtime->oss.buffer_used > 0) {
1584 #ifdef OSS_DEBUG
1585 			pcm_dbg(substream->pcm, "sync: buffer_used\n");
1586 #endif
1587 			size = (8 * (runtime->oss.period_bytes - runtime->oss.buffer_used) + 7) / width;
1588 			snd_pcm_format_set_silence(format,
1589 						   runtime->oss.buffer + runtime->oss.buffer_used,
1590 						   size);
1591 			err = snd_pcm_oss_sync1(substream, runtime->oss.period_bytes);
1592 			if (err < 0) {
1593 				mutex_unlock(&runtime->oss.params_lock);
1594 				return err;
1595 			}
1596 		} else if (runtime->oss.period_ptr > 0) {
1597 #ifdef OSS_DEBUG
1598 			pcm_dbg(substream->pcm, "sync: period_ptr\n");
1599 #endif
1600 			size = runtime->oss.period_bytes - runtime->oss.period_ptr;
1601 			snd_pcm_format_set_silence(format,
1602 						   runtime->oss.buffer,
1603 						   size * 8 / width);
1604 			err = snd_pcm_oss_sync1(substream, size);
1605 			if (err < 0) {
1606 				mutex_unlock(&runtime->oss.params_lock);
1607 				return err;
1608 			}
1609 		}
1610 		/*
1611 		 * The ALSA's period might be a bit large than OSS one.
1612 		 * Fill the remain portion of ALSA period with zeros.
1613 		 */
1614 		size = runtime->control->appl_ptr % runtime->period_size;
1615 		if (size > 0) {
1616 			size = runtime->period_size - size;
1617 			if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED)
1618 				snd_pcm_lib_write(substream, NULL, size);
1619 			else if (runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
1620 				snd_pcm_lib_writev(substream, NULL, size);
1621 		}
1622 		mutex_unlock(&runtime->oss.params_lock);
1623 		/*
1624 		 * finish sync: drain the buffer
1625 		 */
1626 	      __direct:
1627 		saved_f_flags = substream->f_flags;
1628 		substream->f_flags &= ~O_NONBLOCK;
1629 		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DRAIN, NULL);
1630 		substream->f_flags = saved_f_flags;
1631 		if (err < 0)
1632 			return err;
1633 		runtime->oss.prepare = 1;
1634 	}
1635 
1636 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
1637 	if (substream != NULL) {
1638 		if ((err = snd_pcm_oss_make_ready(substream)) < 0)
1639 			return err;
1640 		runtime = substream->runtime;
1641 		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DROP, NULL);
1642 		if (err < 0)
1643 			return err;
1644 		runtime->oss.buffer_used = 0;
1645 		runtime->oss.prepare = 1;
1646 	}
1647 	return 0;
1648 }
1649 
1650 static int snd_pcm_oss_set_rate(struct snd_pcm_oss_file *pcm_oss_file, int rate)
1651 {
1652 	int idx;
1653 
1654 	for (idx = 1; idx >= 0; --idx) {
1655 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1656 		struct snd_pcm_runtime *runtime;
1657 		if (substream == NULL)
1658 			continue;
1659 		runtime = substream->runtime;
1660 		if (rate < 1000)
1661 			rate = 1000;
1662 		else if (rate > 192000)
1663 			rate = 192000;
1664 		if (runtime->oss.rate != rate) {
1665 			runtime->oss.params = 1;
1666 			runtime->oss.rate = rate;
1667 		}
1668 	}
1669 	return snd_pcm_oss_get_rate(pcm_oss_file);
1670 }
1671 
1672 static int snd_pcm_oss_get_rate(struct snd_pcm_oss_file *pcm_oss_file)
1673 {
1674 	struct snd_pcm_substream *substream;
1675 	int err;
1676 
1677 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1678 		return err;
1679 	return substream->runtime->oss.rate;
1680 }
1681 
1682 static int snd_pcm_oss_set_channels(struct snd_pcm_oss_file *pcm_oss_file, unsigned int channels)
1683 {
1684 	int idx;
1685 	if (channels < 1)
1686 		channels = 1;
1687 	if (channels > 128)
1688 		return -EINVAL;
1689 	for (idx = 1; idx >= 0; --idx) {
1690 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1691 		struct snd_pcm_runtime *runtime;
1692 		if (substream == NULL)
1693 			continue;
1694 		runtime = substream->runtime;
1695 		if (runtime->oss.channels != channels) {
1696 			runtime->oss.params = 1;
1697 			runtime->oss.channels = channels;
1698 		}
1699 	}
1700 	return snd_pcm_oss_get_channels(pcm_oss_file);
1701 }
1702 
1703 static int snd_pcm_oss_get_channels(struct snd_pcm_oss_file *pcm_oss_file)
1704 {
1705 	struct snd_pcm_substream *substream;
1706 	int err;
1707 
1708 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1709 		return err;
1710 	return substream->runtime->oss.channels;
1711 }
1712 
1713 static int snd_pcm_oss_get_block_size(struct snd_pcm_oss_file *pcm_oss_file)
1714 {
1715 	struct snd_pcm_substream *substream;
1716 	int err;
1717 
1718 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1719 		return err;
1720 	return substream->runtime->oss.period_bytes;
1721 }
1722 
1723 static int snd_pcm_oss_get_formats(struct snd_pcm_oss_file *pcm_oss_file)
1724 {
1725 	struct snd_pcm_substream *substream;
1726 	int err;
1727 	int direct;
1728 	struct snd_pcm_hw_params *params;
1729 	unsigned int formats = 0;
1730 	const struct snd_mask *format_mask;
1731 	int fmt;
1732 
1733 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1734 		return err;
1735 	if (atomic_read(&substream->mmap_count))
1736 		direct = 1;
1737 	else
1738 		direct = substream->oss.setup.direct;
1739 	if (!direct)
1740 		return AFMT_MU_LAW | AFMT_U8 |
1741 		       AFMT_S16_LE | AFMT_S16_BE |
1742 		       AFMT_S8 | AFMT_U16_LE |
1743 		       AFMT_U16_BE |
1744 			AFMT_S32_LE | AFMT_S32_BE |
1745 			AFMT_S24_LE | AFMT_S24_BE |
1746 			AFMT_S24_PACKED;
1747 	params = kmalloc(sizeof(*params), GFP_KERNEL);
1748 	if (!params)
1749 		return -ENOMEM;
1750 	_snd_pcm_hw_params_any(params);
1751 	err = snd_pcm_hw_refine(substream, params);
1752 	format_mask = hw_param_mask_c(params, SNDRV_PCM_HW_PARAM_FORMAT);
1753 	kfree(params);
1754 	if (err < 0)
1755 		return err;
1756 	for (fmt = 0; fmt < 32; ++fmt) {
1757 		if (snd_mask_test(format_mask, fmt)) {
1758 			int f = snd_pcm_oss_format_to(fmt);
1759 			if (f >= 0)
1760 				formats |= f;
1761 		}
1762 	}
1763 	return formats;
1764 }
1765 
1766 static int snd_pcm_oss_set_format(struct snd_pcm_oss_file *pcm_oss_file, int format)
1767 {
1768 	int formats, idx;
1769 
1770 	if (format != AFMT_QUERY) {
1771 		formats = snd_pcm_oss_get_formats(pcm_oss_file);
1772 		if (formats < 0)
1773 			return formats;
1774 		if (!(formats & format))
1775 			format = AFMT_U8;
1776 		for (idx = 1; idx >= 0; --idx) {
1777 			struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1778 			struct snd_pcm_runtime *runtime;
1779 			if (substream == NULL)
1780 				continue;
1781 			runtime = substream->runtime;
1782 			if (runtime->oss.format != format) {
1783 				runtime->oss.params = 1;
1784 				runtime->oss.format = format;
1785 			}
1786 		}
1787 	}
1788 	return snd_pcm_oss_get_format(pcm_oss_file);
1789 }
1790 
1791 static int snd_pcm_oss_get_format(struct snd_pcm_oss_file *pcm_oss_file)
1792 {
1793 	struct snd_pcm_substream *substream;
1794 	int err;
1795 
1796 	if ((err = snd_pcm_oss_get_active_substream(pcm_oss_file, &substream)) < 0)
1797 		return err;
1798 	return substream->runtime->oss.format;
1799 }
1800 
1801 static int snd_pcm_oss_set_subdivide1(struct snd_pcm_substream *substream, int subdivide)
1802 {
1803 	struct snd_pcm_runtime *runtime;
1804 
1805 	if (substream == NULL)
1806 		return 0;
1807 	runtime = substream->runtime;
1808 	if (subdivide == 0) {
1809 		subdivide = runtime->oss.subdivision;
1810 		if (subdivide == 0)
1811 			subdivide = 1;
1812 		return subdivide;
1813 	}
1814 	if (runtime->oss.subdivision || runtime->oss.fragshift)
1815 		return -EINVAL;
1816 	if (subdivide != 1 && subdivide != 2 && subdivide != 4 &&
1817 	    subdivide != 8 && subdivide != 16)
1818 		return -EINVAL;
1819 	runtime->oss.subdivision = subdivide;
1820 	runtime->oss.params = 1;
1821 	return subdivide;
1822 }
1823 
1824 static int snd_pcm_oss_set_subdivide(struct snd_pcm_oss_file *pcm_oss_file, int subdivide)
1825 {
1826 	int err = -EINVAL, idx;
1827 
1828 	for (idx = 1; idx >= 0; --idx) {
1829 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1830 		if (substream == NULL)
1831 			continue;
1832 		if ((err = snd_pcm_oss_set_subdivide1(substream, subdivide)) < 0)
1833 			return err;
1834 	}
1835 	return err;
1836 }
1837 
1838 static int snd_pcm_oss_set_fragment1(struct snd_pcm_substream *substream, unsigned int val)
1839 {
1840 	struct snd_pcm_runtime *runtime;
1841 
1842 	if (substream == NULL)
1843 		return 0;
1844 	runtime = substream->runtime;
1845 	if (runtime->oss.subdivision || runtime->oss.fragshift)
1846 		return -EINVAL;
1847 	runtime->oss.fragshift = val & 0xffff;
1848 	runtime->oss.maxfrags = (val >> 16) & 0xffff;
1849 	if (runtime->oss.fragshift < 4)		/* < 16 */
1850 		runtime->oss.fragshift = 4;
1851 	if (runtime->oss.maxfrags < 2)
1852 		runtime->oss.maxfrags = 2;
1853 	runtime->oss.params = 1;
1854 	return 0;
1855 }
1856 
1857 static int snd_pcm_oss_set_fragment(struct snd_pcm_oss_file *pcm_oss_file, unsigned int val)
1858 {
1859 	int err = -EINVAL, idx;
1860 
1861 	for (idx = 1; idx >= 0; --idx) {
1862 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1863 		if (substream == NULL)
1864 			continue;
1865 		if ((err = snd_pcm_oss_set_fragment1(substream, val)) < 0)
1866 			return err;
1867 	}
1868 	return err;
1869 }
1870 
1871 static int snd_pcm_oss_nonblock(struct file * file)
1872 {
1873 	spin_lock(&file->f_lock);
1874 	file->f_flags |= O_NONBLOCK;
1875 	spin_unlock(&file->f_lock);
1876 	return 0;
1877 }
1878 
1879 static int snd_pcm_oss_get_caps1(struct snd_pcm_substream *substream, int res)
1880 {
1881 
1882 	if (substream == NULL) {
1883 		res &= ~DSP_CAP_DUPLEX;
1884 		return res;
1885 	}
1886 #ifdef DSP_CAP_MULTI
1887 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
1888 		if (substream->pstr->substream_count > 1)
1889 			res |= DSP_CAP_MULTI;
1890 #endif
1891 	/* DSP_CAP_REALTIME is set all times: */
1892 	/* all ALSA drivers can return actual pointer in ring buffer */
1893 #if defined(DSP_CAP_REALTIME) && 0
1894 	{
1895 		struct snd_pcm_runtime *runtime = substream->runtime;
1896 		if (runtime->info & (SNDRV_PCM_INFO_BLOCK_TRANSFER|SNDRV_PCM_INFO_BATCH))
1897 			res &= ~DSP_CAP_REALTIME;
1898 	}
1899 #endif
1900 	return res;
1901 }
1902 
1903 static int snd_pcm_oss_get_caps(struct snd_pcm_oss_file *pcm_oss_file)
1904 {
1905 	int result, idx;
1906 
1907 	result = DSP_CAP_TRIGGER | DSP_CAP_MMAP	| DSP_CAP_DUPLEX | DSP_CAP_REALTIME;
1908 	for (idx = 0; idx < 2; idx++) {
1909 		struct snd_pcm_substream *substream = pcm_oss_file->streams[idx];
1910 		result = snd_pcm_oss_get_caps1(substream, result);
1911 	}
1912 	result |= 0x0001;	/* revision - same as SB AWE 64 */
1913 	return result;
1914 }
1915 
1916 static void snd_pcm_oss_simulate_fill(struct snd_pcm_substream *substream,
1917 				      snd_pcm_uframes_t hw_ptr)
1918 {
1919 	struct snd_pcm_runtime *runtime = substream->runtime;
1920 	snd_pcm_uframes_t appl_ptr;
1921 	appl_ptr = hw_ptr + runtime->buffer_size;
1922 	appl_ptr %= runtime->boundary;
1923 	runtime->control->appl_ptr = appl_ptr;
1924 }
1925 
1926 static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int trigger)
1927 {
1928 	struct snd_pcm_runtime *runtime;
1929 	struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
1930 	int err, cmd;
1931 
1932 #ifdef OSS_DEBUG
1933 	pcm_dbg(substream->pcm, "pcm_oss: trigger = 0x%x\n", trigger);
1934 #endif
1935 
1936 	psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
1937 	csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
1938 
1939 	if (psubstream) {
1940 		if ((err = snd_pcm_oss_make_ready(psubstream)) < 0)
1941 			return err;
1942 	}
1943 	if (csubstream) {
1944 		if ((err = snd_pcm_oss_make_ready(csubstream)) < 0)
1945 			return err;
1946 	}
1947       	if (psubstream) {
1948       		runtime = psubstream->runtime;
1949 		if (trigger & PCM_ENABLE_OUTPUT) {
1950 			if (runtime->oss.trigger)
1951 				goto _skip1;
1952 			if (atomic_read(&psubstream->mmap_count))
1953 				snd_pcm_oss_simulate_fill(psubstream,
1954 						get_hw_ptr_period(runtime));
1955 			runtime->oss.trigger = 1;
1956 			runtime->start_threshold = 1;
1957 			cmd = SNDRV_PCM_IOCTL_START;
1958 		} else {
1959 			if (!runtime->oss.trigger)
1960 				goto _skip1;
1961 			runtime->oss.trigger = 0;
1962 			runtime->start_threshold = runtime->boundary;
1963 			cmd = SNDRV_PCM_IOCTL_DROP;
1964 			runtime->oss.prepare = 1;
1965 		}
1966 		err = snd_pcm_kernel_ioctl(psubstream, cmd, NULL);
1967 		if (err < 0)
1968 			return err;
1969 	}
1970  _skip1:
1971 	if (csubstream) {
1972       		runtime = csubstream->runtime;
1973 		if (trigger & PCM_ENABLE_INPUT) {
1974 			if (runtime->oss.trigger)
1975 				goto _skip2;
1976 			runtime->oss.trigger = 1;
1977 			runtime->start_threshold = 1;
1978 			cmd = SNDRV_PCM_IOCTL_START;
1979 		} else {
1980 			if (!runtime->oss.trigger)
1981 				goto _skip2;
1982 			runtime->oss.trigger = 0;
1983 			runtime->start_threshold = runtime->boundary;
1984 			cmd = SNDRV_PCM_IOCTL_DROP;
1985 			runtime->oss.prepare = 1;
1986 		}
1987 		err = snd_pcm_kernel_ioctl(csubstream, cmd, NULL);
1988 		if (err < 0)
1989 			return err;
1990 	}
1991  _skip2:
1992 	return 0;
1993 }
1994 
1995 static int snd_pcm_oss_get_trigger(struct snd_pcm_oss_file *pcm_oss_file)
1996 {
1997 	struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
1998 	int result = 0;
1999 
2000 	psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2001 	csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2002 	if (psubstream && psubstream->runtime && psubstream->runtime->oss.trigger)
2003 		result |= PCM_ENABLE_OUTPUT;
2004 	if (csubstream && csubstream->runtime && csubstream->runtime->oss.trigger)
2005 		result |= PCM_ENABLE_INPUT;
2006 	return result;
2007 }
2008 
2009 static int snd_pcm_oss_get_odelay(struct snd_pcm_oss_file *pcm_oss_file)
2010 {
2011 	struct snd_pcm_substream *substream;
2012 	struct snd_pcm_runtime *runtime;
2013 	snd_pcm_sframes_t delay;
2014 	int err;
2015 
2016 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2017 	if (substream == NULL)
2018 		return -EINVAL;
2019 	if ((err = snd_pcm_oss_make_ready(substream)) < 0)
2020 		return err;
2021 	runtime = substream->runtime;
2022 	if (runtime->oss.params || runtime->oss.prepare)
2023 		return 0;
2024 	err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay);
2025 	if (err == -EPIPE)
2026 		delay = 0;	/* hack for broken OSS applications */
2027 	else if (err < 0)
2028 		return err;
2029 	return snd_pcm_oss_bytes(substream, delay);
2030 }
2031 
2032 static int snd_pcm_oss_get_ptr(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct count_info __user * _info)
2033 {
2034 	struct snd_pcm_substream *substream;
2035 	struct snd_pcm_runtime *runtime;
2036 	snd_pcm_sframes_t delay;
2037 	int fixup;
2038 	struct count_info info;
2039 	int err;
2040 
2041 	if (_info == NULL)
2042 		return -EFAULT;
2043 	substream = pcm_oss_file->streams[stream];
2044 	if (substream == NULL)
2045 		return -EINVAL;
2046 	if ((err = snd_pcm_oss_make_ready(substream)) < 0)
2047 		return err;
2048 	runtime = substream->runtime;
2049 	if (runtime->oss.params || runtime->oss.prepare) {
2050 		memset(&info, 0, sizeof(info));
2051 		if (copy_to_user(_info, &info, sizeof(info)))
2052 			return -EFAULT;
2053 		return 0;
2054 	}
2055 	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2056 		err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &delay);
2057 		if (err == -EPIPE || err == -ESTRPIPE || (! err && delay < 0)) {
2058 			err = 0;
2059 			delay = 0;
2060 			fixup = 0;
2061 		} else {
2062 			fixup = runtime->oss.buffer_used;
2063 		}
2064 	} else {
2065 		err = snd_pcm_oss_capture_position_fixup(substream, &delay);
2066 		fixup = -runtime->oss.buffer_used;
2067 	}
2068 	if (err < 0)
2069 		return err;
2070 	info.ptr = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr % runtime->buffer_size);
2071 	if (atomic_read(&substream->mmap_count)) {
2072 		snd_pcm_sframes_t n;
2073 		delay = get_hw_ptr_period(runtime);
2074 		n = delay - runtime->oss.prev_hw_ptr_period;
2075 		if (n < 0)
2076 			n += runtime->boundary;
2077 		info.blocks = n / runtime->period_size;
2078 		runtime->oss.prev_hw_ptr_period = delay;
2079 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
2080 			snd_pcm_oss_simulate_fill(substream, delay);
2081 		info.bytes = snd_pcm_oss_bytes(substream, runtime->status->hw_ptr) & INT_MAX;
2082 	} else {
2083 		delay = snd_pcm_oss_bytes(substream, delay);
2084 		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2085 			if (substream->oss.setup.buggyptr)
2086 				info.blocks = (runtime->oss.buffer_bytes - delay - fixup) / runtime->oss.period_bytes;
2087 			else
2088 				info.blocks = (delay + fixup) / runtime->oss.period_bytes;
2089 			info.bytes = (runtime->oss.bytes - delay) & INT_MAX;
2090 		} else {
2091 			delay += fixup;
2092 			info.blocks = delay / runtime->oss.period_bytes;
2093 			info.bytes = (runtime->oss.bytes + delay) & INT_MAX;
2094 		}
2095 	}
2096 	if (copy_to_user(_info, &info, sizeof(info)))
2097 		return -EFAULT;
2098 	return 0;
2099 }
2100 
2101 static int snd_pcm_oss_get_space(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct audio_buf_info __user *_info)
2102 {
2103 	struct snd_pcm_substream *substream;
2104 	struct snd_pcm_runtime *runtime;
2105 	snd_pcm_sframes_t avail;
2106 	int fixup;
2107 	struct audio_buf_info info;
2108 	int err;
2109 
2110 	if (_info == NULL)
2111 		return -EFAULT;
2112 	substream = pcm_oss_file->streams[stream];
2113 	if (substream == NULL)
2114 		return -EINVAL;
2115 	runtime = substream->runtime;
2116 
2117 	if (runtime->oss.params &&
2118 	    (err = snd_pcm_oss_change_params(substream, false)) < 0)
2119 		return err;
2120 
2121 	info.fragsize = runtime->oss.period_bytes;
2122 	info.fragstotal = runtime->periods;
2123 	if (runtime->oss.prepare) {
2124 		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2125 			info.bytes = runtime->oss.period_bytes * runtime->oss.periods;
2126 			info.fragments = runtime->oss.periods;
2127 		} else {
2128 			info.bytes = 0;
2129 			info.fragments = 0;
2130 		}
2131 	} else {
2132 		if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
2133 			err = snd_pcm_kernel_ioctl(substream, SNDRV_PCM_IOCTL_DELAY, &avail);
2134 			if (err == -EPIPE || err == -ESTRPIPE || (! err && avail < 0)) {
2135 				avail = runtime->buffer_size;
2136 				err = 0;
2137 				fixup = 0;
2138 			} else {
2139 				avail = runtime->buffer_size - avail;
2140 				fixup = -runtime->oss.buffer_used;
2141 			}
2142 		} else {
2143 			err = snd_pcm_oss_capture_position_fixup(substream, &avail);
2144 			fixup = runtime->oss.buffer_used;
2145 		}
2146 		if (err < 0)
2147 			return err;
2148 		info.bytes = snd_pcm_oss_bytes(substream, avail) + fixup;
2149 		info.fragments = info.bytes / runtime->oss.period_bytes;
2150 	}
2151 
2152 #ifdef OSS_DEBUG
2153 	pcm_dbg(substream->pcm,
2154 		"pcm_oss: space: bytes = %i, fragments = %i, fragstotal = %i, fragsize = %i\n",
2155 		info.bytes, info.fragments, info.fragstotal, info.fragsize);
2156 #endif
2157 	if (copy_to_user(_info, &info, sizeof(info)))
2158 		return -EFAULT;
2159 	return 0;
2160 }
2161 
2162 static int snd_pcm_oss_get_mapbuf(struct snd_pcm_oss_file *pcm_oss_file, int stream, struct buffmem_desc __user * _info)
2163 {
2164 	// it won't be probably implemented
2165 	// pr_debug("TODO: snd_pcm_oss_get_mapbuf\n");
2166 	return -EINVAL;
2167 }
2168 
2169 static const char *strip_task_path(const char *path)
2170 {
2171 	const char *ptr, *ptrl = NULL;
2172 	for (ptr = path; *ptr; ptr++) {
2173 		if (*ptr == '/')
2174 			ptrl = ptr + 1;
2175 	}
2176 	return ptrl;
2177 }
2178 
2179 static void snd_pcm_oss_look_for_setup(struct snd_pcm *pcm, int stream,
2180 				      const char *task_name,
2181 				      struct snd_pcm_oss_setup *rsetup)
2182 {
2183 	struct snd_pcm_oss_setup *setup;
2184 
2185 	mutex_lock(&pcm->streams[stream].oss.setup_mutex);
2186 	do {
2187 		for (setup = pcm->streams[stream].oss.setup_list; setup;
2188 		     setup = setup->next) {
2189 			if (!strcmp(setup->task_name, task_name))
2190 				goto out;
2191 		}
2192 	} while ((task_name = strip_task_path(task_name)) != NULL);
2193  out:
2194 	if (setup)
2195 		*rsetup = *setup;
2196 	mutex_unlock(&pcm->streams[stream].oss.setup_mutex);
2197 }
2198 
2199 static void snd_pcm_oss_release_substream(struct snd_pcm_substream *substream)
2200 {
2201 	struct snd_pcm_runtime *runtime;
2202 	runtime = substream->runtime;
2203 	vfree(runtime->oss.buffer);
2204 	runtime->oss.buffer = NULL;
2205 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
2206 	snd_pcm_oss_plugin_clear(substream);
2207 #endif
2208 	substream->oss.oss = 0;
2209 }
2210 
2211 static void snd_pcm_oss_init_substream(struct snd_pcm_substream *substream,
2212 				       struct snd_pcm_oss_setup *setup,
2213 				       int minor)
2214 {
2215 	struct snd_pcm_runtime *runtime;
2216 
2217 	substream->oss.oss = 1;
2218 	substream->oss.setup = *setup;
2219 	if (setup->nonblock)
2220 		substream->f_flags |= O_NONBLOCK;
2221 	else if (setup->block)
2222 		substream->f_flags &= ~O_NONBLOCK;
2223 	runtime = substream->runtime;
2224 	runtime->oss.params = 1;
2225 	runtime->oss.trigger = 1;
2226 	runtime->oss.rate = 8000;
2227 	mutex_init(&runtime->oss.params_lock);
2228 	switch (SNDRV_MINOR_OSS_DEVICE(minor)) {
2229 	case SNDRV_MINOR_OSS_PCM_8:
2230 		runtime->oss.format = AFMT_U8;
2231 		break;
2232 	case SNDRV_MINOR_OSS_PCM_16:
2233 		runtime->oss.format = AFMT_S16_LE;
2234 		break;
2235 	default:
2236 		runtime->oss.format = AFMT_MU_LAW;
2237 	}
2238 	runtime->oss.channels = 1;
2239 	runtime->oss.fragshift = 0;
2240 	runtime->oss.maxfrags = 0;
2241 	runtime->oss.subdivision = 0;
2242 	substream->pcm_release = snd_pcm_oss_release_substream;
2243 }
2244 
2245 static int snd_pcm_oss_release_file(struct snd_pcm_oss_file *pcm_oss_file)
2246 {
2247 	int cidx;
2248 	if (!pcm_oss_file)
2249 		return 0;
2250 	for (cidx = 0; cidx < 2; ++cidx) {
2251 		struct snd_pcm_substream *substream = pcm_oss_file->streams[cidx];
2252 		if (substream)
2253 			snd_pcm_release_substream(substream);
2254 	}
2255 	kfree(pcm_oss_file);
2256 	return 0;
2257 }
2258 
2259 static int snd_pcm_oss_open_file(struct file *file,
2260 				 struct snd_pcm *pcm,
2261 				 struct snd_pcm_oss_file **rpcm_oss_file,
2262 				 int minor,
2263 				 struct snd_pcm_oss_setup *setup)
2264 {
2265 	int idx, err;
2266 	struct snd_pcm_oss_file *pcm_oss_file;
2267 	struct snd_pcm_substream *substream;
2268 	fmode_t f_mode = file->f_mode;
2269 
2270 	if (rpcm_oss_file)
2271 		*rpcm_oss_file = NULL;
2272 
2273 	pcm_oss_file = kzalloc(sizeof(*pcm_oss_file), GFP_KERNEL);
2274 	if (pcm_oss_file == NULL)
2275 		return -ENOMEM;
2276 
2277 	if ((f_mode & (FMODE_WRITE|FMODE_READ)) == (FMODE_WRITE|FMODE_READ) &&
2278 	    (pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX))
2279 		f_mode = FMODE_WRITE;
2280 
2281 	file->f_flags &= ~O_APPEND;
2282 	for (idx = 0; idx < 2; idx++) {
2283 		if (setup[idx].disable)
2284 			continue;
2285 		if (! pcm->streams[idx].substream_count)
2286 			continue; /* no matching substream */
2287 		if (idx == SNDRV_PCM_STREAM_PLAYBACK) {
2288 			if (! (f_mode & FMODE_WRITE))
2289 				continue;
2290 		} else {
2291 			if (! (f_mode & FMODE_READ))
2292 				continue;
2293 		}
2294 		err = snd_pcm_open_substream(pcm, idx, file, &substream);
2295 		if (err < 0) {
2296 			snd_pcm_oss_release_file(pcm_oss_file);
2297 			return err;
2298 		}
2299 
2300 		pcm_oss_file->streams[idx] = substream;
2301 		substream->file = pcm_oss_file;
2302 		snd_pcm_oss_init_substream(substream, &setup[idx], minor);
2303 	}
2304 
2305 	if (!pcm_oss_file->streams[0] && !pcm_oss_file->streams[1]) {
2306 		snd_pcm_oss_release_file(pcm_oss_file);
2307 		return -EINVAL;
2308 	}
2309 
2310 	file->private_data = pcm_oss_file;
2311 	if (rpcm_oss_file)
2312 		*rpcm_oss_file = pcm_oss_file;
2313 	return 0;
2314 }
2315 
2316 
2317 static int snd_task_name(struct task_struct *task, char *name, size_t size)
2318 {
2319 	unsigned int idx;
2320 
2321 	if (snd_BUG_ON(!task || !name || size < 2))
2322 		return -EINVAL;
2323 	for (idx = 0; idx < sizeof(task->comm) && idx + 1 < size; idx++)
2324 		name[idx] = task->comm[idx];
2325 	name[idx] = '\0';
2326 	return 0;
2327 }
2328 
2329 static int snd_pcm_oss_open(struct inode *inode, struct file *file)
2330 {
2331 	int err;
2332 	char task_name[32];
2333 	struct snd_pcm *pcm;
2334 	struct snd_pcm_oss_file *pcm_oss_file;
2335 	struct snd_pcm_oss_setup setup[2];
2336 	int nonblock;
2337 	wait_queue_t wait;
2338 
2339 	err = nonseekable_open(inode, file);
2340 	if (err < 0)
2341 		return err;
2342 
2343 	pcm = snd_lookup_oss_minor_data(iminor(inode),
2344 					SNDRV_OSS_DEVICE_TYPE_PCM);
2345 	if (pcm == NULL) {
2346 		err = -ENODEV;
2347 		goto __error1;
2348 	}
2349 	err = snd_card_file_add(pcm->card, file);
2350 	if (err < 0)
2351 		goto __error1;
2352 	if (!try_module_get(pcm->card->module)) {
2353 		err = -EFAULT;
2354 		goto __error2;
2355 	}
2356 	if (snd_task_name(current, task_name, sizeof(task_name)) < 0) {
2357 		err = -EFAULT;
2358 		goto __error;
2359 	}
2360 	memset(setup, 0, sizeof(setup));
2361 	if (file->f_mode & FMODE_WRITE)
2362 		snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_PLAYBACK,
2363 					   task_name, &setup[0]);
2364 	if (file->f_mode & FMODE_READ)
2365 		snd_pcm_oss_look_for_setup(pcm, SNDRV_PCM_STREAM_CAPTURE,
2366 					   task_name, &setup[1]);
2367 
2368 	nonblock = !!(file->f_flags & O_NONBLOCK);
2369 	if (!nonblock)
2370 		nonblock = nonblock_open;
2371 
2372 	init_waitqueue_entry(&wait, current);
2373 	add_wait_queue(&pcm->open_wait, &wait);
2374 	mutex_lock(&pcm->open_mutex);
2375 	while (1) {
2376 		err = snd_pcm_oss_open_file(file, pcm, &pcm_oss_file,
2377 					    iminor(inode), setup);
2378 		if (err >= 0)
2379 			break;
2380 		if (err == -EAGAIN) {
2381 			if (nonblock) {
2382 				err = -EBUSY;
2383 				break;
2384 			}
2385 		} else
2386 			break;
2387 		set_current_state(TASK_INTERRUPTIBLE);
2388 		mutex_unlock(&pcm->open_mutex);
2389 		schedule();
2390 		mutex_lock(&pcm->open_mutex);
2391 		if (pcm->card->shutdown) {
2392 			err = -ENODEV;
2393 			break;
2394 		}
2395 		if (signal_pending(current)) {
2396 			err = -ERESTARTSYS;
2397 			break;
2398 		}
2399 	}
2400 	remove_wait_queue(&pcm->open_wait, &wait);
2401 	mutex_unlock(&pcm->open_mutex);
2402 	if (err < 0)
2403 		goto __error;
2404 	snd_card_unref(pcm->card);
2405 	return err;
2406 
2407       __error:
2408      	module_put(pcm->card->module);
2409       __error2:
2410       	snd_card_file_remove(pcm->card, file);
2411       __error1:
2412 	if (pcm)
2413 		snd_card_unref(pcm->card);
2414 	return err;
2415 }
2416 
2417 static int snd_pcm_oss_release(struct inode *inode, struct file *file)
2418 {
2419 	struct snd_pcm *pcm;
2420 	struct snd_pcm_substream *substream;
2421 	struct snd_pcm_oss_file *pcm_oss_file;
2422 
2423 	pcm_oss_file = file->private_data;
2424 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2425 	if (substream == NULL)
2426 		substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2427 	if (snd_BUG_ON(!substream))
2428 		return -ENXIO;
2429 	pcm = substream->pcm;
2430 	if (!pcm->card->shutdown)
2431 		snd_pcm_oss_sync(pcm_oss_file);
2432 	mutex_lock(&pcm->open_mutex);
2433 	snd_pcm_oss_release_file(pcm_oss_file);
2434 	mutex_unlock(&pcm->open_mutex);
2435 	wake_up(&pcm->open_wait);
2436 	module_put(pcm->card->module);
2437 	snd_card_file_remove(pcm->card, file);
2438 	return 0;
2439 }
2440 
2441 static long snd_pcm_oss_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
2442 {
2443 	struct snd_pcm_oss_file *pcm_oss_file;
2444 	int __user *p = (int __user *)arg;
2445 	int res;
2446 
2447 	pcm_oss_file = file->private_data;
2448 	if (cmd == OSS_GETVERSION)
2449 		return put_user(SNDRV_OSS_VERSION, p);
2450 	if (cmd == OSS_ALSAEMULVER)
2451 		return put_user(1, p);
2452 #if IS_REACHABLE(CONFIG_SND_MIXER_OSS)
2453 	if (((cmd >> 8) & 0xff) == 'M')	{	/* mixer ioctl - for OSS compatibility */
2454 		struct snd_pcm_substream *substream;
2455 		int idx;
2456 		for (idx = 0; idx < 2; ++idx) {
2457 			substream = pcm_oss_file->streams[idx];
2458 			if (substream != NULL)
2459 				break;
2460 		}
2461 		if (snd_BUG_ON(idx >= 2))
2462 			return -ENXIO;
2463 		return snd_mixer_oss_ioctl_card(substream->pcm->card, cmd, arg);
2464 	}
2465 #endif
2466 	if (((cmd >> 8) & 0xff) != 'P')
2467 		return -EINVAL;
2468 #ifdef OSS_DEBUG
2469 	pr_debug("pcm_oss: ioctl = 0x%x\n", cmd);
2470 #endif
2471 	switch (cmd) {
2472 	case SNDCTL_DSP_RESET:
2473 		return snd_pcm_oss_reset(pcm_oss_file);
2474 	case SNDCTL_DSP_SYNC:
2475 		return snd_pcm_oss_sync(pcm_oss_file);
2476 	case SNDCTL_DSP_SPEED:
2477 		if (get_user(res, p))
2478 			return -EFAULT;
2479 		if ((res = snd_pcm_oss_set_rate(pcm_oss_file, res))<0)
2480 			return res;
2481 		return put_user(res, p);
2482 	case SOUND_PCM_READ_RATE:
2483 		res = snd_pcm_oss_get_rate(pcm_oss_file);
2484 		if (res < 0)
2485 			return res;
2486 		return put_user(res, p);
2487 	case SNDCTL_DSP_STEREO:
2488 		if (get_user(res, p))
2489 			return -EFAULT;
2490 		res = res > 0 ? 2 : 1;
2491 		if ((res = snd_pcm_oss_set_channels(pcm_oss_file, res)) < 0)
2492 			return res;
2493 		return put_user(--res, p);
2494 	case SNDCTL_DSP_GETBLKSIZE:
2495 		res = snd_pcm_oss_get_block_size(pcm_oss_file);
2496 		if (res < 0)
2497 			return res;
2498 		return put_user(res, p);
2499 	case SNDCTL_DSP_SETFMT:
2500 		if (get_user(res, p))
2501 			return -EFAULT;
2502 		res = snd_pcm_oss_set_format(pcm_oss_file, res);
2503 		if (res < 0)
2504 			return res;
2505 		return put_user(res, p);
2506 	case SOUND_PCM_READ_BITS:
2507 		res = snd_pcm_oss_get_format(pcm_oss_file);
2508 		if (res < 0)
2509 			return res;
2510 		return put_user(res, p);
2511 	case SNDCTL_DSP_CHANNELS:
2512 		if (get_user(res, p))
2513 			return -EFAULT;
2514 		res = snd_pcm_oss_set_channels(pcm_oss_file, res);
2515 		if (res < 0)
2516 			return res;
2517 		return put_user(res, p);
2518 	case SOUND_PCM_READ_CHANNELS:
2519 		res = snd_pcm_oss_get_channels(pcm_oss_file);
2520 		if (res < 0)
2521 			return res;
2522 		return put_user(res, p);
2523 	case SOUND_PCM_WRITE_FILTER:
2524 	case SOUND_PCM_READ_FILTER:
2525 		return -EIO;
2526 	case SNDCTL_DSP_POST:
2527 		return snd_pcm_oss_post(pcm_oss_file);
2528 	case SNDCTL_DSP_SUBDIVIDE:
2529 		if (get_user(res, p))
2530 			return -EFAULT;
2531 		res = snd_pcm_oss_set_subdivide(pcm_oss_file, res);
2532 		if (res < 0)
2533 			return res;
2534 		return put_user(res, p);
2535 	case SNDCTL_DSP_SETFRAGMENT:
2536 		if (get_user(res, p))
2537 			return -EFAULT;
2538 		return snd_pcm_oss_set_fragment(pcm_oss_file, res);
2539 	case SNDCTL_DSP_GETFMTS:
2540 		res = snd_pcm_oss_get_formats(pcm_oss_file);
2541 		if (res < 0)
2542 			return res;
2543 		return put_user(res, p);
2544 	case SNDCTL_DSP_GETOSPACE:
2545 	case SNDCTL_DSP_GETISPACE:
2546 		return snd_pcm_oss_get_space(pcm_oss_file,
2547 			cmd == SNDCTL_DSP_GETISPACE ?
2548 				SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
2549 			(struct audio_buf_info __user *) arg);
2550 	case SNDCTL_DSP_NONBLOCK:
2551 		return snd_pcm_oss_nonblock(file);
2552 	case SNDCTL_DSP_GETCAPS:
2553 		res = snd_pcm_oss_get_caps(pcm_oss_file);
2554 		if (res < 0)
2555 			return res;
2556 		return put_user(res, p);
2557 	case SNDCTL_DSP_GETTRIGGER:
2558 		res = snd_pcm_oss_get_trigger(pcm_oss_file);
2559 		if (res < 0)
2560 			return res;
2561 		return put_user(res, p);
2562 	case SNDCTL_DSP_SETTRIGGER:
2563 		if (get_user(res, p))
2564 			return -EFAULT;
2565 		return snd_pcm_oss_set_trigger(pcm_oss_file, res);
2566 	case SNDCTL_DSP_GETIPTR:
2567 	case SNDCTL_DSP_GETOPTR:
2568 		return snd_pcm_oss_get_ptr(pcm_oss_file,
2569 			cmd == SNDCTL_DSP_GETIPTR ?
2570 				SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
2571 			(struct count_info __user *) arg);
2572 	case SNDCTL_DSP_MAPINBUF:
2573 	case SNDCTL_DSP_MAPOUTBUF:
2574 		return snd_pcm_oss_get_mapbuf(pcm_oss_file,
2575 			cmd == SNDCTL_DSP_MAPINBUF ?
2576 				SNDRV_PCM_STREAM_CAPTURE : SNDRV_PCM_STREAM_PLAYBACK,
2577 			(struct buffmem_desc __user *) arg);
2578 	case SNDCTL_DSP_SETSYNCRO:
2579 		/* stop DMA now.. */
2580 		return 0;
2581 	case SNDCTL_DSP_SETDUPLEX:
2582 		if (snd_pcm_oss_get_caps(pcm_oss_file) & DSP_CAP_DUPLEX)
2583 			return 0;
2584 		return -EIO;
2585 	case SNDCTL_DSP_GETODELAY:
2586 		res = snd_pcm_oss_get_odelay(pcm_oss_file);
2587 		if (res < 0) {
2588 			/* it's for sure, some broken apps don't check for error codes */
2589 			put_user(0, p);
2590 			return res;
2591 		}
2592 		return put_user(res, p);
2593 	case SNDCTL_DSP_PROFILE:
2594 		return 0;	/* silently ignore */
2595 	default:
2596 		pr_debug("pcm_oss: unknown command = 0x%x\n", cmd);
2597 	}
2598 	return -EINVAL;
2599 }
2600 
2601 #ifdef CONFIG_COMPAT
2602 /* all compatible */
2603 static long snd_pcm_oss_ioctl_compat(struct file *file, unsigned int cmd,
2604 				     unsigned long arg)
2605 {
2606 	return snd_pcm_oss_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
2607 }
2608 #else
2609 #define snd_pcm_oss_ioctl_compat	NULL
2610 #endif
2611 
2612 static ssize_t snd_pcm_oss_read(struct file *file, char __user *buf, size_t count, loff_t *offset)
2613 {
2614 	struct snd_pcm_oss_file *pcm_oss_file;
2615 	struct snd_pcm_substream *substream;
2616 
2617 	pcm_oss_file = file->private_data;
2618 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2619 	if (substream == NULL)
2620 		return -ENXIO;
2621 	substream->f_flags = file->f_flags & O_NONBLOCK;
2622 #ifndef OSS_DEBUG
2623 	return snd_pcm_oss_read1(substream, buf, count);
2624 #else
2625 	{
2626 		ssize_t res = snd_pcm_oss_read1(substream, buf, count);
2627 		pcm_dbg(substream->pcm,
2628 			"pcm_oss: read %li bytes (returned %li bytes)\n",
2629 			(long)count, (long)res);
2630 		return res;
2631 	}
2632 #endif
2633 }
2634 
2635 static ssize_t snd_pcm_oss_write(struct file *file, const char __user *buf, size_t count, loff_t *offset)
2636 {
2637 	struct snd_pcm_oss_file *pcm_oss_file;
2638 	struct snd_pcm_substream *substream;
2639 	long result;
2640 
2641 	pcm_oss_file = file->private_data;
2642 	substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2643 	if (substream == NULL)
2644 		return -ENXIO;
2645 	substream->f_flags = file->f_flags & O_NONBLOCK;
2646 	result = snd_pcm_oss_write1(substream, buf, count);
2647 #ifdef OSS_DEBUG
2648 	pcm_dbg(substream->pcm, "pcm_oss: write %li bytes (wrote %li bytes)\n",
2649 	       (long)count, (long)result);
2650 #endif
2651 	return result;
2652 }
2653 
2654 static int snd_pcm_oss_playback_ready(struct snd_pcm_substream *substream)
2655 {
2656 	struct snd_pcm_runtime *runtime = substream->runtime;
2657 	if (atomic_read(&substream->mmap_count))
2658 		return runtime->oss.prev_hw_ptr_period !=
2659 						get_hw_ptr_period(runtime);
2660 	else
2661 		return snd_pcm_playback_avail(runtime) >=
2662 						runtime->oss.period_frames;
2663 }
2664 
2665 static int snd_pcm_oss_capture_ready(struct snd_pcm_substream *substream)
2666 {
2667 	struct snd_pcm_runtime *runtime = substream->runtime;
2668 	if (atomic_read(&substream->mmap_count))
2669 		return runtime->oss.prev_hw_ptr_period !=
2670 						get_hw_ptr_period(runtime);
2671 	else
2672 		return snd_pcm_capture_avail(runtime) >=
2673 						runtime->oss.period_frames;
2674 }
2675 
2676 static unsigned int snd_pcm_oss_poll(struct file *file, poll_table * wait)
2677 {
2678 	struct snd_pcm_oss_file *pcm_oss_file;
2679 	unsigned int mask;
2680 	struct snd_pcm_substream *psubstream = NULL, *csubstream = NULL;
2681 
2682 	pcm_oss_file = file->private_data;
2683 
2684 	psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2685 	csubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2686 
2687 	mask = 0;
2688 	if (psubstream != NULL) {
2689 		struct snd_pcm_runtime *runtime = psubstream->runtime;
2690 		poll_wait(file, &runtime->sleep, wait);
2691 		snd_pcm_stream_lock_irq(psubstream);
2692 		if (runtime->status->state != SNDRV_PCM_STATE_DRAINING &&
2693 		    (runtime->status->state != SNDRV_PCM_STATE_RUNNING ||
2694 		     snd_pcm_oss_playback_ready(psubstream)))
2695 			mask |= POLLOUT | POLLWRNORM;
2696 		snd_pcm_stream_unlock_irq(psubstream);
2697 	}
2698 	if (csubstream != NULL) {
2699 		struct snd_pcm_runtime *runtime = csubstream->runtime;
2700 		snd_pcm_state_t ostate;
2701 		poll_wait(file, &runtime->sleep, wait);
2702 		snd_pcm_stream_lock_irq(csubstream);
2703 		if ((ostate = runtime->status->state) != SNDRV_PCM_STATE_RUNNING ||
2704 		    snd_pcm_oss_capture_ready(csubstream))
2705 			mask |= POLLIN | POLLRDNORM;
2706 		snd_pcm_stream_unlock_irq(csubstream);
2707 		if (ostate != SNDRV_PCM_STATE_RUNNING && runtime->oss.trigger) {
2708 			struct snd_pcm_oss_file ofile;
2709 			memset(&ofile, 0, sizeof(ofile));
2710 			ofile.streams[SNDRV_PCM_STREAM_CAPTURE] = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2711 			runtime->oss.trigger = 0;
2712 			snd_pcm_oss_set_trigger(&ofile, PCM_ENABLE_INPUT);
2713 		}
2714 	}
2715 
2716 	return mask;
2717 }
2718 
2719 static int snd_pcm_oss_mmap(struct file *file, struct vm_area_struct *area)
2720 {
2721 	struct snd_pcm_oss_file *pcm_oss_file;
2722 	struct snd_pcm_substream *substream = NULL;
2723 	struct snd_pcm_runtime *runtime;
2724 	int err;
2725 
2726 #ifdef OSS_DEBUG
2727 	pr_debug("pcm_oss: mmap begin\n");
2728 #endif
2729 	pcm_oss_file = file->private_data;
2730 	switch ((area->vm_flags & (VM_READ | VM_WRITE))) {
2731 	case VM_READ | VM_WRITE:
2732 		substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2733 		if (substream)
2734 			break;
2735 		/* Fall through */
2736 	case VM_READ:
2737 		substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_CAPTURE];
2738 		break;
2739 	case VM_WRITE:
2740 		substream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK];
2741 		break;
2742 	default:
2743 		return -EINVAL;
2744 	}
2745 	/* set VM_READ access as well to fix memset() routines that do
2746 	   reads before writes (to improve performance) */
2747 	area->vm_flags |= VM_READ;
2748 	if (substream == NULL)
2749 		return -ENXIO;
2750 	runtime = substream->runtime;
2751 	if (!(runtime->info & SNDRV_PCM_INFO_MMAP_VALID))
2752 		return -EIO;
2753 	if (runtime->info & SNDRV_PCM_INFO_INTERLEAVED)
2754 		runtime->access = SNDRV_PCM_ACCESS_MMAP_INTERLEAVED;
2755 	else
2756 		return -EIO;
2757 
2758 	if (runtime->oss.params) {
2759 		/* use mutex_trylock() for params_lock for avoiding a deadlock
2760 		 * between mmap_sem and params_lock taken by
2761 		 * copy_from/to_user() in snd_pcm_oss_write/read()
2762 		 */
2763 		err = snd_pcm_oss_change_params(substream, true);
2764 		if (err < 0)
2765 			return err;
2766 	}
2767 #ifdef CONFIG_SND_PCM_OSS_PLUGINS
2768 	if (runtime->oss.plugin_first != NULL)
2769 		return -EIO;
2770 #endif
2771 
2772 	if (area->vm_pgoff != 0)
2773 		return -EINVAL;
2774 
2775 	err = snd_pcm_mmap_data(substream, file, area);
2776 	if (err < 0)
2777 		return err;
2778 	runtime->oss.mmap_bytes = area->vm_end - area->vm_start;
2779 	runtime->silence_threshold = 0;
2780 	runtime->silence_size = 0;
2781 #ifdef OSS_DEBUG
2782 	pr_debug("pcm_oss: mmap ok, bytes = 0x%x\n",
2783 	       runtime->oss.mmap_bytes);
2784 #endif
2785 	/* In mmap mode we never stop */
2786 	runtime->stop_threshold = runtime->boundary;
2787 
2788 	return 0;
2789 }
2790 
2791 #ifdef CONFIG_SND_VERBOSE_PROCFS
2792 /*
2793  *  /proc interface
2794  */
2795 
2796 static void snd_pcm_oss_proc_read(struct snd_info_entry *entry,
2797 				  struct snd_info_buffer *buffer)
2798 {
2799 	struct snd_pcm_str *pstr = entry->private_data;
2800 	struct snd_pcm_oss_setup *setup = pstr->oss.setup_list;
2801 	mutex_lock(&pstr->oss.setup_mutex);
2802 	while (setup) {
2803 		snd_iprintf(buffer, "%s %u %u%s%s%s%s%s%s\n",
2804 			    setup->task_name,
2805 			    setup->periods,
2806 			    setup->period_size,
2807 			    setup->disable ? " disable" : "",
2808 			    setup->direct ? " direct" : "",
2809 			    setup->block ? " block" : "",
2810 			    setup->nonblock ? " non-block" : "",
2811 			    setup->partialfrag ? " partial-frag" : "",
2812 			    setup->nosilence ? " no-silence" : "");
2813 		setup = setup->next;
2814 	}
2815 	mutex_unlock(&pstr->oss.setup_mutex);
2816 }
2817 
2818 static void snd_pcm_oss_proc_free_setup_list(struct snd_pcm_str * pstr)
2819 {
2820 	struct snd_pcm_oss_setup *setup, *setupn;
2821 
2822 	for (setup = pstr->oss.setup_list, pstr->oss.setup_list = NULL;
2823 	     setup; setup = setupn) {
2824 		setupn = setup->next;
2825 		kfree(setup->task_name);
2826 		kfree(setup);
2827 	}
2828 	pstr->oss.setup_list = NULL;
2829 }
2830 
2831 static void snd_pcm_oss_proc_write(struct snd_info_entry *entry,
2832 				   struct snd_info_buffer *buffer)
2833 {
2834 	struct snd_pcm_str *pstr = entry->private_data;
2835 	char line[128], str[32], task_name[32];
2836 	const char *ptr;
2837 	int idx1;
2838 	struct snd_pcm_oss_setup *setup, *setup1, template;
2839 
2840 	while (!snd_info_get_line(buffer, line, sizeof(line))) {
2841 		mutex_lock(&pstr->oss.setup_mutex);
2842 		memset(&template, 0, sizeof(template));
2843 		ptr = snd_info_get_str(task_name, line, sizeof(task_name));
2844 		if (!strcmp(task_name, "clear") || !strcmp(task_name, "erase")) {
2845 			snd_pcm_oss_proc_free_setup_list(pstr);
2846 			mutex_unlock(&pstr->oss.setup_mutex);
2847 			continue;
2848 		}
2849 		for (setup = pstr->oss.setup_list; setup; setup = setup->next) {
2850 			if (!strcmp(setup->task_name, task_name)) {
2851 				template = *setup;
2852 				break;
2853 			}
2854 		}
2855 		ptr = snd_info_get_str(str, ptr, sizeof(str));
2856 		template.periods = simple_strtoul(str, NULL, 10);
2857 		ptr = snd_info_get_str(str, ptr, sizeof(str));
2858 		template.period_size = simple_strtoul(str, NULL, 10);
2859 		for (idx1 = 31; idx1 >= 0; idx1--)
2860 			if (template.period_size & (1 << idx1))
2861 				break;
2862 		for (idx1--; idx1 >= 0; idx1--)
2863 			template.period_size &= ~(1 << idx1);
2864 		do {
2865 			ptr = snd_info_get_str(str, ptr, sizeof(str));
2866 			if (!strcmp(str, "disable")) {
2867 				template.disable = 1;
2868 			} else if (!strcmp(str, "direct")) {
2869 				template.direct = 1;
2870 			} else if (!strcmp(str, "block")) {
2871 				template.block = 1;
2872 			} else if (!strcmp(str, "non-block")) {
2873 				template.nonblock = 1;
2874 			} else if (!strcmp(str, "partial-frag")) {
2875 				template.partialfrag = 1;
2876 			} else if (!strcmp(str, "no-silence")) {
2877 				template.nosilence = 1;
2878 			} else if (!strcmp(str, "buggy-ptr")) {
2879 				template.buggyptr = 1;
2880 			}
2881 		} while (*str);
2882 		if (setup == NULL) {
2883 			setup = kmalloc(sizeof(*setup), GFP_KERNEL);
2884 			if (! setup) {
2885 				buffer->error = -ENOMEM;
2886 				mutex_unlock(&pstr->oss.setup_mutex);
2887 				return;
2888 			}
2889 			if (pstr->oss.setup_list == NULL)
2890 				pstr->oss.setup_list = setup;
2891 			else {
2892 				for (setup1 = pstr->oss.setup_list;
2893 				     setup1->next; setup1 = setup1->next);
2894 				setup1->next = setup;
2895 			}
2896 			template.task_name = kstrdup(task_name, GFP_KERNEL);
2897 			if (! template.task_name) {
2898 				kfree(setup);
2899 				buffer->error = -ENOMEM;
2900 				mutex_unlock(&pstr->oss.setup_mutex);
2901 				return;
2902 			}
2903 		}
2904 		*setup = template;
2905 		mutex_unlock(&pstr->oss.setup_mutex);
2906 	}
2907 }
2908 
2909 static void snd_pcm_oss_proc_init(struct snd_pcm *pcm)
2910 {
2911 	int stream;
2912 	for (stream = 0; stream < 2; ++stream) {
2913 		struct snd_info_entry *entry;
2914 		struct snd_pcm_str *pstr = &pcm->streams[stream];
2915 		if (pstr->substream_count == 0)
2916 			continue;
2917 		if ((entry = snd_info_create_card_entry(pcm->card, "oss", pstr->proc_root)) != NULL) {
2918 			entry->content = SNDRV_INFO_CONTENT_TEXT;
2919 			entry->mode = S_IFREG | S_IRUGO | S_IWUSR;
2920 			entry->c.text.read = snd_pcm_oss_proc_read;
2921 			entry->c.text.write = snd_pcm_oss_proc_write;
2922 			entry->private_data = pstr;
2923 			if (snd_info_register(entry) < 0) {
2924 				snd_info_free_entry(entry);
2925 				entry = NULL;
2926 			}
2927 		}
2928 		pstr->oss.proc_entry = entry;
2929 	}
2930 }
2931 
2932 static void snd_pcm_oss_proc_done(struct snd_pcm *pcm)
2933 {
2934 	int stream;
2935 	for (stream = 0; stream < 2; ++stream) {
2936 		struct snd_pcm_str *pstr = &pcm->streams[stream];
2937 		snd_info_free_entry(pstr->oss.proc_entry);
2938 		pstr->oss.proc_entry = NULL;
2939 		snd_pcm_oss_proc_free_setup_list(pstr);
2940 	}
2941 }
2942 #else /* !CONFIG_SND_VERBOSE_PROCFS */
2943 #define snd_pcm_oss_proc_init(pcm)
2944 #define snd_pcm_oss_proc_done(pcm)
2945 #endif /* CONFIG_SND_VERBOSE_PROCFS */
2946 
2947 /*
2948  *  ENTRY functions
2949  */
2950 
2951 static const struct file_operations snd_pcm_oss_f_reg =
2952 {
2953 	.owner =	THIS_MODULE,
2954 	.read =		snd_pcm_oss_read,
2955 	.write =	snd_pcm_oss_write,
2956 	.open =		snd_pcm_oss_open,
2957 	.release =	snd_pcm_oss_release,
2958 	.llseek =	no_llseek,
2959 	.poll =		snd_pcm_oss_poll,
2960 	.unlocked_ioctl =	snd_pcm_oss_ioctl,
2961 	.compat_ioctl =	snd_pcm_oss_ioctl_compat,
2962 	.mmap =		snd_pcm_oss_mmap,
2963 };
2964 
2965 static void register_oss_dsp(struct snd_pcm *pcm, int index)
2966 {
2967 	if (snd_register_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
2968 				    pcm->card, index, &snd_pcm_oss_f_reg,
2969 				    pcm) < 0) {
2970 		pcm_err(pcm, "unable to register OSS PCM device %i:%i\n",
2971 			   pcm->card->number, pcm->device);
2972 	}
2973 }
2974 
2975 static int snd_pcm_oss_register_minor(struct snd_pcm *pcm)
2976 {
2977 	pcm->oss.reg = 0;
2978 	if (dsp_map[pcm->card->number] == (int)pcm->device) {
2979 		char name[128];
2980 		int duplex;
2981 		register_oss_dsp(pcm, 0);
2982 		duplex = (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream_count > 0 &&
2983 			      pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream_count &&
2984 			      !(pcm->info_flags & SNDRV_PCM_INFO_HALF_DUPLEX));
2985 		sprintf(name, "%s%s", pcm->name, duplex ? " (DUPLEX)" : "");
2986 #ifdef SNDRV_OSS_INFO_DEV_AUDIO
2987 		snd_oss_info_register(SNDRV_OSS_INFO_DEV_AUDIO,
2988 				      pcm->card->number,
2989 				      name);
2990 #endif
2991 		pcm->oss.reg++;
2992 		pcm->oss.reg_mask |= 1;
2993 	}
2994 	if (adsp_map[pcm->card->number] == (int)pcm->device) {
2995 		register_oss_dsp(pcm, 1);
2996 		pcm->oss.reg++;
2997 		pcm->oss.reg_mask |= 2;
2998 	}
2999 
3000 	if (pcm->oss.reg)
3001 		snd_pcm_oss_proc_init(pcm);
3002 
3003 	return 0;
3004 }
3005 
3006 static int snd_pcm_oss_disconnect_minor(struct snd_pcm *pcm)
3007 {
3008 	if (pcm->oss.reg) {
3009 		if (pcm->oss.reg_mask & 1) {
3010 			pcm->oss.reg_mask &= ~1;
3011 			snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
3012 						  pcm->card, 0);
3013 		}
3014 		if (pcm->oss.reg_mask & 2) {
3015 			pcm->oss.reg_mask &= ~2;
3016 			snd_unregister_oss_device(SNDRV_OSS_DEVICE_TYPE_PCM,
3017 						  pcm->card, 1);
3018 		}
3019 		if (dsp_map[pcm->card->number] == (int)pcm->device) {
3020 #ifdef SNDRV_OSS_INFO_DEV_AUDIO
3021 			snd_oss_info_unregister(SNDRV_OSS_INFO_DEV_AUDIO, pcm->card->number);
3022 #endif
3023 		}
3024 		pcm->oss.reg = 0;
3025 	}
3026 	return 0;
3027 }
3028 
3029 static int snd_pcm_oss_unregister_minor(struct snd_pcm *pcm)
3030 {
3031 	snd_pcm_oss_disconnect_minor(pcm);
3032 	snd_pcm_oss_proc_done(pcm);
3033 	return 0;
3034 }
3035 
3036 static struct snd_pcm_notify snd_pcm_oss_notify =
3037 {
3038 	.n_register =	snd_pcm_oss_register_minor,
3039 	.n_disconnect = snd_pcm_oss_disconnect_minor,
3040 	.n_unregister =	snd_pcm_oss_unregister_minor,
3041 };
3042 
3043 static int __init alsa_pcm_oss_init(void)
3044 {
3045 	int i;
3046 	int err;
3047 
3048 	/* check device map table */
3049 	for (i = 0; i < SNDRV_CARDS; i++) {
3050 		if (dsp_map[i] < 0 || dsp_map[i] >= SNDRV_PCM_DEVICES) {
3051 			pr_err("ALSA: pcm_oss: invalid dsp_map[%d] = %d\n",
3052 				   i, dsp_map[i]);
3053 			dsp_map[i] = 0;
3054 		}
3055 		if (adsp_map[i] < 0 || adsp_map[i] >= SNDRV_PCM_DEVICES) {
3056 			pr_err("ALSA: pcm_oss: invalid adsp_map[%d] = %d\n",
3057 				   i, adsp_map[i]);
3058 			adsp_map[i] = 1;
3059 		}
3060 	}
3061 	if ((err = snd_pcm_notify(&snd_pcm_oss_notify, 0)) < 0)
3062 		return err;
3063 	return 0;
3064 }
3065 
3066 static void __exit alsa_pcm_oss_exit(void)
3067 {
3068 	snd_pcm_notify(&snd_pcm_oss_notify, 1);
3069 }
3070 
3071 module_init(alsa_pcm_oss_init)
3072 module_exit(alsa_pcm_oss_exit)
3073