source: GPL/trunk/lib32/misc.c@ 522

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

flush_workqueue hack, compiler warnings

File size: 14.3 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 short sDAZ;
272
273 if (wq->task == current) {
274 run_workqueue(wq);
275 } else {
276 wait_queue_t wait;
277
278 init_waitqueue_entry(&wait, current);
279 set_current_state(TASK_UNINTERRUPTIBLE);
280 spin_lock_irq(&wq->lock);
281 add_wait_queue(&wq->work_done, &wait);
282 sDAZ = 0;
283 while (!list_empty(&wq->worklist)) {
284 if (sDAZ++ > 20) { // Temporary hack to prevent system hangs
285 rprintf(("flush_workqueue: can't empty list"));
286 break;
287 }
288 spin_unlock_irq(&wq->lock);
289 schedule(); // DAZ system hangs here because this function does nothing
290 spin_lock_irq(&wq->lock);
291 }
292 set_current_state(TASK_RUNNING);
293 remove_wait_queue(&wq->work_done, &wait);
294 spin_unlock_irq(&wq->lock);
295 }
296}
297//******************************************************************************
298//******************************************************************************
299struct workqueue_struct *create_workqueue(const char *name)
300{
301 struct workqueue_struct *wq;
302
303 BUG_ON(strlen(name) > 10);
304
305 wq = kmalloc(sizeof(*wq), GFP_KERNEL);
306 if (!wq)
307 return NULL;
308 memset(wq, 0, sizeof(*wq));
309
310 spin_lock_init(&wq->lock);
311 INIT_LIST_HEAD(&wq->worklist);
312 init_waitqueue_head(&wq->more_work);
313 init_waitqueue_head(&wq->work_done);
314#ifndef TARGET_OS2
315 init_completion(&wq->thread_exited);
316 wq->name = name;
317 wq->task_pid = kernel_thread(xworker_thread, wq, 0);
318 if (wq->task_pid < 0) {
319 printk(KERN_ERR "snd: failed to start thread %s\n", name);
320 snd_compat_destroy_workqueue(wq);
321 wq = NULL;
322 }
323 wq->task = find_task_by_pid(wq->task_pid);
324#endif
325 return wq;
326}
327//******************************************************************************
328//******************************************************************************
329void destroy_workqueue(struct workqueue_struct *wq)
330{
331#ifndef TARGET_OS2
332 snd_compat_flush_workqueue(wq);
333 kill_proc(wq->task_pid, SIGKILL, 1);
334 if (wq->task_pid >= 0)
335 wait_for_completion(&wq->thread_exited);
336#endif
337 kfree(wq);
338}
339
340//******************************************************************************
341//******************************************************************************
342char *kstrdup(const char *s, unsigned int __nocast gfp_flags)
343{
344 int len;
345 char *buf;
346
347 if (!s) return NULL;
348
349 len = strlen(s) + 1;
350 buf = kmalloc(len, gfp_flags);
351 if (buf)
352 memcpy(buf, s, len);
353 return buf;
354}
355//******************************************************************************
356//******************************************************************************
357int mod_firmware_load(const char *fn, char **fp)
358{
359 return 0;
360}
361//******************************************************************************
362//******************************************************************************
363static int snd_try_load_firmware(const char *path, const char *name,
364 struct firmware *firmware)
365{
366 char filename[30 + FIRMWARE_NAME_MAX];
367
368 sprintf(filename, "%s/%s", path, name);
369 firmware->size = mod_firmware_load(filename, (char **)&firmware->data);
370 if (firmware->size)
371 printk(KERN_INFO "Loaded '%s'.", filename);
372 return firmware->size;
373}
374//******************************************************************************
375//******************************************************************************
376int request_firmware(const struct firmware **fw, const char *name,
377 struct device *device)
378{
379 struct firmware *firmware;
380
381 *fw = NULL;
382 firmware = kmalloc(sizeof *firmware, GFP_KERNEL);
383 if (!firmware)
384 return -ENOMEM;
385 if (!snd_try_load_firmware("/lib/firmware", name, firmware) &&
386 !snd_try_load_firmware("/lib/hotplug/firmware", name, firmware) &&
387 !snd_try_load_firmware("/usr/lib/hotplug/firmware", name, firmware)) {
388 kfree(firmware);
389 return -EIO;
390 }
391 *fw = firmware;
392 return 0;
393}
394//******************************************************************************
395//******************************************************************************
396void release_firmware(const struct firmware *fw)
397{
398 if (fw) {
399 vfree(fw->data);
400 kfree(fw);
401 }
402}
403//******************************************************************************
404//******************************************************************************
405void *memdup_user(void __user *src, size_t len)
406{
407 void *p = kmalloc(len, GFP_KERNEL);
408 if (!p)
409 return ERR_PTR(-ENOMEM);
410 if (copy_from_user(p, src, len)) {
411 kfree(p);
412 return ERR_PTR(-EFAULT);
413 }
414 return p;
415}
416//******************************************************************************
417//******************************************************************************
418
Note: See TracBrowser for help on using the repository browser.