source: GPL/branches/uniaud32-2.1.x/lib32/misc.c@ 506

Last change on this file since 506 was 506, checked in by David Azarewicz, 15 years ago

work on volume problem for capture

File size: 16.7 KB
Line 
1/* $Id: misc.c,v 1.1.1.1 2003/07/02 13:57:02 eleph Exp $ */
2/*
3 * OS/2 implementation of misc. Linux kernel services
4 *
5 * (C) 2000-2002 InnoTek Systemberatung GmbH
6 * (C) 2000-2001 Sander van Leeuwen (sandervl@xs4all.nl)
7 *
8 * hweight32 based on Linux code (bitops.h)
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License as
12 * published by the Free Software Foundation; either version 2 of
13 * the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public
21 * License along with this program; if not, write to the Free
22 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
23 * USA.
24 *
25 */
26#include <limits.h>
27#include "linux.h"
28#include <linux/init.h>
29#include <linux/fs.h>
30#include <linux/poll.h>
31#define CONFIG_PROC_FS
32#include <linux/proc_fs.h>
33#include <asm/uaccess.h>
34#include <asm/hardirq.h>
35#include <linux\ioport.h>
36#include <linux\utsname.h>
37#include <linux\module.h>
38#include <linux/workqueue.h>
39#include <linux/firmware.h>
40#include <dbgos2.h>
41
42struct new_utsname system_utsname = {0};
43struct resource ioport_resource = {NULL, 0, 0, IORESOURCE_IO, NULL, NULL, NULL};
44struct resource iomem_resource = {NULL, 0, 0, IORESOURCE_MEM, NULL, NULL, NULL};
45mem_map_t *mem_map = 0;
46int this_module[64] = {0};
47
48#include <stdarg.h>
49
50char szLastALSAError1[128] = {0};
51char szOverrunTest1 = 0xCC;
52char szLastALSAError2[128] = {0};
53char szOverrunTest2 = 0xCC;
54int iLastError = 0;
55
56//******************************************************************************
57//Save error message in szLastALSAError; if card init failed, then we will
58//print it in drv32\init.cpp
59//******************************************************************************
60int printk(const char * fmt, ...)
61{
62 va_list argptr; /* -> variable argument list */
63
64 char *pszLastALSAError;
65
66 pszLastALSAError= iLastError ? szLastALSAError2 : szLastALSAError1;
67
68 va_start(argptr, fmt); /* get pointer to argument list */
69 vsprintf(pszLastALSAError, fmt, argptr);
70// strcat(pszLastALSAError, "\r");
71 va_end(argptr); /* done with variable arguments */
72
73 if(szOverrunTest1 != 0xCC || szOverrunTest2 != 0xCC) {
74 DebugInt3();
75 }
76
77 dprintf( (pszLastALSAError) );
78 if(++iLastError > 1) {
79 iLastError = 0;
80 }
81 return 0;
82}
83//******************************************************************************
84//******************************************************************************
85void schedule(void)
86{
87
88}
89//******************************************************************************
90//******************************************************************************
91void poll_wait(struct file * filp, wait_queue_head_t * wait_address, poll_table *p)
92{
93
94}
95//******************************************************************************
96//******************************************************************************
97int __check_region(struct resource *a, unsigned long b, unsigned long c)
98{
99 DebugInt3();
100 return 0;
101}
102
103/* --------------------------------------------------------------------- */
104/*
105 * hweightN: returns the hamming weight (i.e. the number
106 * of bits set) of a N-bit word
107 */
108
109#ifdef hweight32
110#undef hweight32
111#endif
112
113unsigned int hweight32(unsigned int w)
114{
115 unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
116 res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
117 res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
118 res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
119 return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
120}
121//******************************************************************************
122//******************************************************************************
123#if 0
124mem_map_t *virt_to_page(int x)
125{
126 static mem_map_t map = {0};
127 return &map;
128}
129#endif
130//******************************************************************************
131//******************************************************************************
132struct proc_dir_entry proc_root = {0};
133//******************************************************************************
134//******************************************************************************
135struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,
136 struct proc_dir_entry *parent)
137{
138 struct proc_dir_entry *proc;
139 proc = (struct proc_dir_entry *)kmalloc(sizeof(struct proc_dir_entry), 0);
140 memset(proc, 0, sizeof(struct proc_dir_entry));
141
142 proc->name = name;
143 proc->mode = mode;
144 proc->parent = parent;
145
146 return proc;
147}
148//******************************************************************************
149//******************************************************************************
150void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
151{
152 return; //memory leak
153}
154//******************************************************************************
155//******************************************************************************
156int proc_register(struct proc_dir_entry *parent, struct proc_dir_entry *proc)
157{
158 return 0;
159}
160//******************************************************************************
161//******************************************************************************
162int proc_unregister(struct proc_dir_entry *proc, int bla)
163{
164 return 0;
165}
166//******************************************************************************
167//******************************************************************************
168int fasync_helper(int a, struct file *b, int c, struct fasync_struct **d)
169{
170 return 0;
171}
172//******************************************************************************
173//******************************************************************************
174void kill_fasync(struct fasync_struct *a, int b, int c)
175{
176}
177//******************************************************************************
178//******************************************************************************
179int request_dma(unsigned int dmanr, const char * device_id) /* reserve a DMA channel */
180{
181 DebugInt3();
182 return 0;
183}
184//******************************************************************************
185//******************************************************************************
186void free_dma(unsigned int dmanr)
187{
188 DebugInt3();
189}
190//******************************************************************************
191/* enable/disable a specific DMA channel */
192//******************************************************************************
193void enable_dma(unsigned int dmanr)
194{
195 DebugInt3();
196}
197//******************************************************************************
198//******************************************************************************
199void disable_dma(unsigned int dmanr)
200{
201 DebugInt3();
202}
203//******************************************************************************
204static struct notifier_block *reboot_notify_list = NULL;
205// No need to implement this right now. The ESS Maestro 3 driver uses it
206// to call pci_unregister_driver, which is always called from the shutdown
207// notification sent by OS2.
208// Same goes for es1968 & Yamaha's DS1/DS1E.
209//******************************************************************************
210int register_reboot_notifier(struct notifier_block *pnblock)
211{
212 return 0;
213}
214//******************************************************************************
215//******************************************************************************
216int unregister_reboot_notifier(struct notifier_block *pnblock)
217{
218 return 0;
219}
220//******************************************************************************
221//******************************************************************************
222static void __x_queue_work(struct workqueue_struct *wq, struct work_struct *work)
223{
224 unsigned long flags;
225
226 spin_lock_irqsave(&wq->lock, flags);
227 work->wq_data = wq;
228 list_add_tail(&work->entry, &wq->worklist);
229 wake_up(&wq->more_work);
230 spin_unlock_irqrestore(&wq->lock, flags);
231}
232//******************************************************************************
233//******************************************************************************
234int queue_work(struct workqueue_struct *wq, struct work_struct *work)
235{
236 if (!test_and_set_bit(0, &work->pending)) {
237 __x_queue_work(wq, work);
238 return 1;
239 }
240 return 0;
241}
242//******************************************************************************
243//******************************************************************************
244static void run_workqueue(struct workqueue_struct *wq)
245{
246 unsigned long flags;
247
248 spin_lock_irqsave(&wq->lock, flags);
249 while (!list_empty(&wq->worklist)) {
250 struct work_struct *work = list_entry(wq->worklist.next,
251 struct work_struct, entry);
252 void (*f) (void *) = work->func;
253 void *data = work->data;
254
255 list_del_init(wq->worklist.next);
256 spin_unlock_irqrestore(&wq->lock, flags);
257 clear_bit(0, &work->pending);
258 f(data);
259 spin_lock_irqsave(&wq->lock, flags);
260 wake_up(&wq->work_done);
261 }
262 spin_unlock_irqrestore(&wq->lock, flags);
263}
264//******************************************************************************
265//******************************************************************************
266void flush_workqueue(struct workqueue_struct *wq)
267{
268 if (wq->task == current) {
269 run_workqueue(wq);
270 } else {
271 wait_queue_t wait;
272
273 init_waitqueue_entry(&wait, current);
274 set_current_state(TASK_UNINTERRUPTIBLE);
275 spin_lock_irq(&wq->lock);
276 add_wait_queue(&wq->work_done, &wait);
277 while (!list_empty(&wq->worklist)) {
278 spin_unlock_irq(&wq->lock);
279 schedule();
280 spin_lock_irq(&wq->lock);
281 }
282 set_current_state(TASK_RUNNING);
283 remove_wait_queue(&wq->work_done, &wait);
284 spin_unlock_irq(&wq->lock);
285 }
286}
287//******************************************************************************
288//******************************************************************************
289struct workqueue_struct *create_workqueue(const char *name)
290{
291 struct workqueue_struct *wq;
292
293 BUG_ON(strlen(name) > 10);
294
295 wq = kmalloc(sizeof(*wq), GFP_KERNEL);
296 if (!wq)
297 return NULL;
298 memset(wq, 0, sizeof(*wq));
299
300 spin_lock_init(&wq->lock);
301 INIT_LIST_HEAD(&wq->worklist);
302 init_waitqueue_head(&wq->more_work);
303 init_waitqueue_head(&wq->work_done);
304#ifndef TARGET_OS2
305 init_completion(&wq->thread_exited);
306 wq->name = name;
307 wq->task_pid = kernel_thread(xworker_thread, wq, 0);
308 if (wq->task_pid < 0) {
309 printk(KERN_ERR "snd: failed to start thread %s\n", name);
310 snd_compat_destroy_workqueue(wq);
311 wq = NULL;
312 }
313 wq->task = find_task_by_pid(wq->task_pid);
314#endif
315 return wq;
316}
317//******************************************************************************
318//******************************************************************************
319void destroy_workqueue(struct workqueue_struct *wq)
320{
321#ifndef TARGET_OS2
322 snd_compat_flush_workqueue(wq);
323 kill_proc(wq->task_pid, SIGKILL, 1);
324 if (wq->task_pid >= 0)
325 wait_for_completion(&wq->thread_exited);
326#endif
327 kfree(wq);
328}
329
330//******************************************************************************
331//******************************************************************************
332char *kstrdup(const char *s, unsigned int __nocast gfp_flags)
333{
334 int len;
335 char *buf;
336
337 if (!s) return NULL;
338
339 len = strlen(s) + 1;
340 buf = kmalloc(len, gfp_flags);
341 if (buf)
342 memcpy(buf, s, len);
343 return buf;
344}
345//******************************************************************************
346//******************************************************************************
347int mod_firmware_load(const char *fn, char **fp)
348{
349 return 0;
350}
351//******************************************************************************
352//******************************************************************************
353static int snd_try_load_firmware(const char *path, const char *name,
354 struct firmware *firmware)
355{
356 char filename[30 + FIRMWARE_NAME_MAX];
357
358 sprintf(filename, "%s/%s", path, name);
359 firmware->size = mod_firmware_load(filename, (char **)&firmware->data);
360 if (firmware->size)
361 printk(KERN_INFO "Loaded '%s'.", filename);
362 return firmware->size;
363}
364//******************************************************************************
365//******************************************************************************
366int request_firmware(const struct firmware **fw, const char *name,
367 struct device *device)
368{
369 struct firmware *firmware;
370
371 *fw = NULL;
372 firmware = kmalloc(sizeof *firmware, GFP_KERNEL);
373 if (!firmware)
374 return -ENOMEM;
375 if (!snd_try_load_firmware("/lib/firmware", name, firmware) &&
376 !snd_try_load_firmware("/lib/hotplug/firmware", name, firmware) &&
377 !snd_try_load_firmware("/usr/lib/hotplug/firmware", name, firmware)) {
378 kfree(firmware);
379 return -EIO;
380 }
381 *fw = firmware;
382 return 0;
383}
384//******************************************************************************
385//******************************************************************************
386void release_firmware(const struct firmware *fw)
387{
388 if (fw) {
389 vfree(fw->data);
390 kfree(fw);
391 }
392}
393//******************************************************************************
394//******************************************************************************
395void *memdup_user(void __user *src, size_t len)
396{
397 void *p = kmalloc(len, GFP_KERNEL);
398 if (!p)
399 return ERR_PTR(-ENOMEM);
400 if (copy_from_user(p, src, len)) {
401 kfree(p);
402 return ERR_PTR(-EFAULT);
403 }
404 return p;
405}
406//******************************************************************************
407//******************************************************************************
408#define del_timer_sync(t) del_timer(t) /* FIXME: not quite correct on SMP */
409int cancel_delayed_work(struct delayed_work *dwork)
410{
411 struct work_struct *work = &dwork->work;
412 int ret;
413
414 ret = del_timer_sync(&work->timer);
415 if (ret)
416 clear_bit(0, &work->pending);
417 return ret;
418}
419//******************************************************************************
420//******************************************************************************
421int schedule_work(struct work_struct *works)
422{
423#ifndef TARGET_OS2
424 return kernel_thread(work_caller, works, 0) >= 0;
425#else
426 return 1;
427#endif
428}
429//******************************************************************************
430//******************************************************************************
431static void delayed_work_timer_fn(unsigned long __data)
432{
433 struct work_struct *work = (struct work_struct *)__data;
434 struct workqueue_struct *wq = work->wq_data;
435
436 if (wq)
437 __x_queue_work(wq, work);
438 else
439 schedule_work(work);
440}
441//******************************************************************************
442//******************************************************************************
443int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay)
444{
445 struct work_struct *work = &dwork->work;
446 struct timer_list *timer = &work->timer;
447
448 if (!test_and_set_bit(0, &work->pending)) {
449 work->wq_data = wq;
450 timer->expires = jiffies + delay;
451 timer->data = (unsigned long)work;
452 timer->function = delayed_work_timer_fn;
453 add_timer(timer);
454 return 1;
455 }
456 return 0;
457}
458//******************************************************************************
459//******************************************************************************
460/* Greatest common divisor */
461unsigned long gcd(unsigned long a, unsigned long b)
462{
463 unsigned long r;
464 if (a < b) {
465 r = a;
466 a = b;
467 b = r;
468 }
469 while ((r = a % b) != 0) {
470 a = b;
471 b = r;
472 }
473 return b;
474}
475
476//******************************************************************************
477//******************************************************************************
478int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
479{
480 char *tail;
481 unsigned long val;
482 size_t len;
483
484 *res = 0;
485 len = strlen(cp);
486 if (len == 0)
487 return -EINVAL;
488
489 val = simple_strtoul(cp, &tail, base);
490 if (tail == cp)
491 return -EINVAL;
492
493 if ((*tail == '\0') ||
494 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
495 *res = val;
496 return 0;
497 }
498
499 return -EINVAL;
500}
Note: See TracBrowser for help on using the repository browser.