source: GPL/branches/uniaud32-linux-3.2.102/lib32/misc.c@ 614

Last change on this file since 614 was 614, checked in by Paul Smedley, 5 years ago

Fix some warnings

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