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

Last change on this file since 499 was 499, checked in by Paul Smedley, 15 years ago

Update Uniaud32-2.1.x branch with necessary changes for ALSA 1.0.23

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