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

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

Changes to PCI bus scan, malloc, cleanup all warnings, misc other changes

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
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//******************************************************************************
207static 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 if (wq->task == current) {
272 run_workqueue(wq);
273 } else {
274 wait_queue_t wait;
275
276 init_waitqueue_entry(&wait, current);
277 set_current_state(TASK_UNINTERRUPTIBLE);
278 spin_lock_irq(&wq->lock);
279 add_wait_queue(&wq->work_done, &wait);
280 while (!list_empty(&wq->worklist)) {
281 spin_unlock_irq(&wq->lock);
282 schedule();
283 spin_lock_irq(&wq->lock);
284 }
285 set_current_state(TASK_RUNNING);
286 remove_wait_queue(&wq->work_done, &wait);
287 spin_unlock_irq(&wq->lock);
288 }
289}
290//******************************************************************************
291//******************************************************************************
292struct workqueue_struct *create_workqueue(const char *name)
293{
294 struct workqueue_struct *wq;
295
296 BUG_ON(strlen(name) > 10);
297
298 wq = kmalloc(sizeof(*wq), GFP_KERNEL);
299 if (!wq)
300 return NULL;
301 memset(wq, 0, sizeof(*wq));
302
303 spin_lock_init(&wq->lock);
304 INIT_LIST_HEAD(&wq->worklist);
305 init_waitqueue_head(&wq->more_work);
306 init_waitqueue_head(&wq->work_done);
307#ifndef TARGET_OS2
308 init_completion(&wq->thread_exited);
309 wq->name = name;
310 wq->task_pid = kernel_thread(xworker_thread, wq, 0);
311 if (wq->task_pid < 0) {
312 printk(KERN_ERR "snd: failed to start thread %s\n", name);
313 snd_compat_destroy_workqueue(wq);
314 wq = NULL;
315 }
316 wq->task = find_task_by_pid(wq->task_pid);
317#endif
318 return wq;
319}
320//******************************************************************************
321//******************************************************************************
322void destroy_workqueue(struct workqueue_struct *wq)
323{
324#ifndef TARGET_OS2
325 snd_compat_flush_workqueue(wq);
326 kill_proc(wq->task_pid, SIGKILL, 1);
327 if (wq->task_pid >= 0)
328 wait_for_completion(&wq->thread_exited);
329#endif
330 kfree(wq);
331}
332
333//******************************************************************************
334//******************************************************************************
335char *kstrdup(const char *s, unsigned int __nocast gfp_flags)
336{
337 int len;
338 char *buf;
339
340 if (!s) return NULL;
341
342 len = strlen(s) + 1;
343 buf = kmalloc(len, gfp_flags);
344 if (buf)
345 memcpy(buf, s, len);
346 return buf;
347}
348//******************************************************************************
349//******************************************************************************
350int mod_firmware_load(const char *fn, char **fp)
351{
352 return 0;
353}
354//******************************************************************************
355//******************************************************************************
356static int snd_try_load_firmware(const char *path, const char *name,
357 struct firmware *firmware)
358{
359 char filename[30 + FIRMWARE_NAME_MAX];
360
361 sprintf(filename, "%s/%s", path, name);
362 firmware->size = mod_firmware_load(filename, (char **)&firmware->data);
363 if (firmware->size)
364 printk(KERN_INFO "Loaded '%s'.", filename);
365 return firmware->size;
366}
367//******************************************************************************
368//******************************************************************************
369int request_firmware(const struct firmware **fw, const char *name,
370 struct device *device)
371{
372 struct firmware *firmware;
373
374 *fw = NULL;
375 firmware = kmalloc(sizeof *firmware, GFP_KERNEL);
376 if (!firmware)
377 return -ENOMEM;
378 if (!snd_try_load_firmware("/lib/firmware", name, firmware) &&
379 !snd_try_load_firmware("/lib/hotplug/firmware", name, firmware) &&
380 !snd_try_load_firmware("/usr/lib/hotplug/firmware", name, firmware)) {
381 kfree(firmware);
382 return -EIO;
383 }
384 *fw = firmware;
385 return 0;
386}
387//******************************************************************************
388//******************************************************************************
389void release_firmware(const struct firmware *fw)
390{
391 if (fw) {
392 vfree(fw->data);
393 kfree(fw);
394 }
395}
396//******************************************************************************
397//******************************************************************************
398void *memdup_user(void __user *src, size_t len)
399{
400 void *p = kmalloc(len, GFP_KERNEL);
401 if (!p)
402 return ERR_PTR(-ENOMEM);
403 if (copy_from_user(p, src, len)) {
404 kfree(p);
405 return ERR_PTR(-EFAULT);
406 }
407 return p;
408}
409//******************************************************************************
410//******************************************************************************
411#define del_timer_sync(t) del_timer(t) /* FIXME: not quite correct on SMP */
412int cancel_delayed_work(struct delayed_work *dwork)
413{
414 struct work_struct *work = &dwork->work;
415 int ret;
416
417 ret = del_timer_sync(&work->timer);
418 if (ret)
419 clear_bit(0, &work->pending);
420 return ret;
421}
422//******************************************************************************
423//******************************************************************************
424int schedule_work(struct work_struct *works)
425{
426#ifndef TARGET_OS2
427 return kernel_thread(work_caller, works, 0) >= 0;
428#else
429 return 1;
430#endif
431}
432//******************************************************************************
433//******************************************************************************
434static void delayed_work_timer_fn(unsigned long __data)
435{
436 struct work_struct *work = (struct work_struct *)__data;
437 struct workqueue_struct *wq = work->wq_data;
438
439 if (wq)
440 __x_queue_work(wq, work);
441 else
442 schedule_work(work);
443}
444//******************************************************************************
445//******************************************************************************
446int queue_delayed_work(struct workqueue_struct *wq, struct delayed_work *dwork, unsigned long delay)
447{
448 struct work_struct *work = &dwork->work;
449 struct timer_list *timer = &work->timer;
450
451 if (!test_and_set_bit(0, &work->pending)) {
452 work->wq_data = wq;
453 timer->expires = jiffies + delay;
454 timer->data = (unsigned long)work;
455 timer->function = delayed_work_timer_fn;
456 add_timer(timer);
457 return 1;
458 }
459 return 0;
460}
461//******************************************************************************
462//******************************************************************************
463/* Greatest common divisor */
464unsigned long gcd(unsigned long a, unsigned long b)
465{
466 unsigned long r;
467 if (a < b) {
468 r = a;
469 a = b;
470 b = r;
471 }
472 while ((r = a % b) != 0) {
473 a = b;
474 b = r;
475 }
476 return b;
477}
478
479//******************************************************************************
480//******************************************************************************
481int strict_strtoul(const char *cp, unsigned int base, unsigned long *res)
482{
483 char *tail;
484 unsigned long val;
485 size_t len;
486
487 *res = 0;
488 len = strlen(cp);
489 if (len == 0)
490 return -EINVAL;
491
492 val = simple_strtoul(cp, &tail, base);
493 if (tail == cp)
494 return -EINVAL;
495
496 if ((*tail == '\0') ||
497 ((len == (size_t)(tail - cp) + 1) && (*tail == '\n'))) {
498 *res = val;
499 return 0;
500 }
501
502 return -EINVAL;
503}
Note: See TracBrowser for help on using the repository browser.