"SfR Fresh" - the SfR Freeware/Shareware Archive 
As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers.
Alternatively you can here view or download the uninterpreted source code file.
That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
1 /*
2 * Purpose: Linux kernel version specific wrapper routines.
3 *
4 * This file will be shipped in source format and compiled in the target
5 * (customer) system. In this way minor changes between Linux versions
6 * can be fixed by the customer.
7 */
8
9 /*
10 * Copyright (C) 4Front Technologies 2005-2007. Released under GPL2 license.
11 */
12 //#include <linux/config.h>
13 typedef int *ioctl_arg;
14 #include <linux/init.h>
15 #include <linux/module.h>
16 #include <linux/delay.h>
17 #include <stdarg.h>
18 #include <linux/vmalloc.h>
19 #include "../include/internals/timestamp.h"
20 #include "ossddk/oss_exports.h"
21 #include "wrap.h"
22 #include "ossdip.h"
23 #include <linux/version.h>
24 #include <linux/fs.h>
25 #include <linux/poll.h>
26 #include <linux/time.h>
27 #include <linux/proc_fs.h>
28 #include <linux/spinlock.h>
29 #include <linux/pci.h>
30 #include <linux/irq.h>
31 #include <linux/interrupt.h>
32 #undef strlen
33 #undef strcpy
34 #define strlen oss_strlen
35 #define strcpy oss_strcpy
36
37 typedef struct _smap_t dmap_t;
38
39 #include "../include/sys/soundcard.h"
40 #include "../include/internals/audio_core.h"
41 #include "../include/internals/mixer_core.h"
42
43 extern int flat_device_model;
44
45 MODULE_LICENSE ("GPL v2");
46 MODULE_DESCRIPTION ("Open Sound System core services");
47 MODULE_AUTHOR ("4Front Technologies (support@opensound.com)");
48
49 struct _oss_mutex_t
50 {
51 /* Caution! This definition must match cuckoo.h */
52 spinlock_t lock;
53 int filler; /* Make sure this structure doesn't become zero length */
54 };
55
56 static oss_device_t *core_osdev = NULL;
57 /*
58 * Minor device list
59 */
60 #define MAX_MINOR 256
61 typedef struct
62 {
63 int major, minor;
64 char name[32];
65 } oss_minor_t;
66
67 static oss_minor_t minors[MAX_MINOR];
68 static int nminors = 0;
69
70 /*
71 * Sleep flags. Make sure these definitions match oss_config.h.
72 */
73 #define WK_NONE 0x00
74 #define WK_WAKEUP 0x01
75 #define WK_TIMEOUT 0x02
76 #define WK_SIGNAL 0x04
77 #define WK_SLEEP 0x08
78 #define WK_SELECT 0x10
79
80 time_t
81 oss_get_time (void)
82 {
83 #if 1
84 return get_seconds ();
85 #else
86 return xtime.tv_sec;
87 #endif
88 }
89
90 void *oss_memset (void *t, int val, size_t l);
91
92 void *
93 oss_kmem_alloc (size_t size)
94 {
95 void *ptr;
96 if ((ptr = vmalloc (size)) == NULL)
97 {
98 oss_cmn_err (CE_WARN, "vmalloc(%d) failed\n", size);
99 return NULL;
100 }
101 memset (ptr, 0, size);
102 return ptr;
103 }
104
105 void
106 oss_kmem_free (void *addr)
107 {
108 vfree (addr);
109 }
110
111 #define MAX_MEMBLOCK 4096
112 static void *memblocks[MAX_MEMBLOCK];
113 static int n_memblocks = 0;
114
115 void *
116 oss_pmalloc (size_t sz)
117 {
118 void *ptr;
119
120 if ((ptr = vmalloc (sz)) == NULL)
121 {
122 oss_cmn_err (CE_WARN, "vmalloc(%d) failed (PMALLOC)\n", sz);
123 return NULL;
124 }
125 memset (ptr, 0, sz);
126
127 if (n_memblocks <= MAX_MEMBLOCK)
128 memblocks[n_memblocks++] = ptr;
129
130 return ptr;
131 }
132
133 extern oss_native_word
134 oss_virt_to_bus (void *addr)
135 {
136 return virt_to_bus (addr);
137 }
138
139 void *
140 oss_memcpy (void *t_, const void *f_, size_t l)
141 {
142 unsigned char *t = t_;
143 unsigned const char *f = f_;
144 int i;
145
146 for (i = 0; i < l; i++)
147 *t++ = *f++;
148
149 return t;
150 }
151
152 void *
153 oss_memset (void *t, int val, size_t l)
154 {
155 char *c = t;
156 while (l-- > 0)
157 *c++ = val;
158
159 return t;
160 }
161
162 int
163 oss_strcmp (const char *s1, const char *s2)
164 {
165 while (*s1 && *s2)
166 {
167 if (*s1 != *s2)
168 return *s1 - *s2;
169 s1++;
170 s2++;
171 }
172
173 return *s1 - *s2;
174 }
175
176 int
177 oss_strncmp (const char *s1, const char *s2, size_t len)
178 {
179 while (*s1 && *s2 && len--)
180 {
181 if (*s1 != *s2)
182 return *s1 - *s2;
183 s1++;
184 s2++;
185 }
186
187 return *s1 - *s2;
188 }
189
190 char *
191 oss_strcpy (char *s1, const char *s2)
192 {
193 char *s = s1;
194
195 while (*s2)
196 *s1++ = *s2++;
197 *s1++ = 0;
198 return s;
199 }
200
201 size_t
202 oss_strlen (const char *s)
203 {
204 int i;
205
206 for (i = 0; s[i]; i++);
207
208 return i;
209 }
210
211 char *
212 oss_strncpy (char *s1, const char *s2, size_t l)
213 {
214 char *s = s1;
215 int n = 0;
216
217 while (*s2)
218 {
219 if (n++ >= l)
220 return s;
221
222 *s1++ = *s2++;
223 }
224 *s1++ = 0;
225 return s;
226 }
227
228 int oss_hz = HZ;
229 extern int max_intrate;
230 extern int detect_trace;
231 extern int src_quality;
232
233 module_param (oss_hz, int, S_IRUGO);
234 module_param (max_intrate, int, S_IRUGO);
235 module_param (detect_trace, int, S_IRUGO);
236 module_param (src_quality, int, S_IRUGO);
237
238 static struct proc_dir_entry *oss_proc_root = NULL;
239 static struct proc_dir_entry *oss_proc_devfiles = NULL;
240
241 static ssize_t
242 oss_read_devfiles (struct file *file, char __user * buf, size_t count,
243 loff_t * ppos)
244 {
245 static char tmp[4096];
246 char *s;
247 static int eof = 0;
248 int i;
249
250 if (eof)
251 {
252 eof = 0;
253 return 0;
254 }
255
256 *tmp = 0;
257 s = tmp;
258
259 for (i = 0; i < nminors; i++)
260 {
261 if (strlen (tmp) > sizeof (tmp) - 20)
262 {
263 printk (KERN_ALERT "osscore: Procfs buffer too small\n");
264 return -ENOMEM;
265 }
266
267 s += sprintf (s, "%s %d %d\n",
268 minors[i].name, minors[i].major, minors[i].minor);
269 }
270
271 if (copy_to_user (buf, (void *) tmp, strlen (tmp)))
272 return -EFAULT;
273
274 eof = 1;
275 return strlen (tmp);
276 }
277
278 static struct file_operations oss_proc_operations = {
279 .read = oss_read_devfiles,
280 };
281
282 static void
283 init_proc_fs (void)
284 {
285 if ((oss_proc_root =
286 create_proc_entry ("opensound", 0700 | S_IFDIR, &proc_root)) == NULL)
287 {
288 oss_cmn_err (CE_CONT, "Cannot create /proc/opensound\n");
289 return;
290 }
291
292 if ((oss_proc_devfiles =
293 create_proc_entry ("devfiles", 0600, oss_proc_root)) == NULL)
294 {
295 oss_cmn_err (CE_CONT, "Cannot create /proc/opensound/devfiles\n");
296 return;
297 }
298
299 oss_proc_devfiles->proc_fops = &oss_proc_operations;
300 }
301
302 static void
303 uninit_proc_fs (void)
304 {
305 if (oss_proc_root)
306 {
307 if (oss_proc_devfiles)
308 remove_proc_entry ("devfiles", oss_proc_root);
309 remove_proc_entry ("opensound", &proc_root);
310 }
311 }
312
313 static int
314 osscore_init (void)
315 {
316 if ((core_osdev =
317 osdev_create (NULL, DRV_UNKNOWN, 0, "osscore", NULL)) == NULL)
318 {
319 oss_cmn_err (CE_WARN, "Failed to allocate OSDEV structure\n");
320 return -ENOMEM;
321 }
322
323 osdev_set_owner (core_osdev, THIS_MODULE);
324
325 init_proc_fs ();
326
327 return oss_init_osscore (core_osdev);
328 }
329
330 static void
331 osscore_exit (void)
332 {
333 int i;
334
335 uninit_proc_fs ();
336 oss_uninit_osscore (core_osdev);
337
338 for (i = 0; i < n_memblocks; i++)
339 if (memblocks[i] != NULL)
340 {
341 vfree (memblocks[i]);
342 memblocks[i] = NULL;
343 }
344 }
345
346 void
347 oss_udelay (unsigned long d)
348 {
349 udelay (d);
350 }
351
352 oss_mutex_t
353 oss_mutex_init (void)
354 {
355 oss_mutex_t mutex;
356
357 if ((mutex = vmalloc (sizeof (*mutex))) == NULL)
358 {
359 oss_cmn_err (CE_WARN, "vmalloc(%d) failed (mutex)\n", sizeof (*mutex));
360 return NULL;
361 }
362
363 spin_lock_init (&(mutex->lock));
364
365 return mutex;
366 }
367
368 void
369 oss_mutex_cleanup (oss_mutex_t mutex)
370 {
371 vfree (mutex);
372 }
373
374 void
375 oss_spin_lock_irqsave (oss_mutex_t mutex, oss_native_word * flags)
376 {
377 unsigned long flag;
378 if (mutex == NULL)
379 return;
380 spin_lock_irqsave (&mutex->lock, flag);
381 *flags = flag;
382 }
383
384 void
385 oss_spin_unlock_irqrestore (oss_mutex_t mutex, oss_native_word flags)
386 {
387 if (mutex == NULL)
388 return;
389 spin_unlock_irqrestore (&mutex->lock, flags);
390 }
391
392 void
393 oss_spin_lock (oss_mutex_t mutex)
394 {
395 if (mutex == NULL)
396 return;
397 spin_lock (&mutex->lock);
398 }
399
400 void
401 oss_spin_unlock (oss_mutex_t mutex)
402 {
403 if (mutex == NULL)
404 return;
405 spin_unlock (&mutex->lock);
406 }
407
408 void *
409 oss_map_pci_mem (oss_device_t * osdev, int size, unsigned long offset)
410 {
411 return ioremap (offset, size);
412 }
413
414 void
415 oss_unmap_pci_mem (void *addr)
416 {
417 iounmap (addr);
418 }
419
420 unsigned long long
421 oss_get_jiffies (void)
422 {
423 return jiffies_64;
424 }
425
426 char *
427 oss_get_procname (void)
428 {
429 return current->comm;
430 }
431
432 int
433 oss_get_pid (void)
434 {
435 return current->pid;
436 }
437
438 int
439 oss_get_uid (void)
440 {
441 return current->uid;
442 }
443
444 typedef struct tmout_desc
445 {
446 volatile int active;
447 int timestamp;
448 void (*func) (void *);
449 void *arg;
450
451 struct timer_list timer;
452 } tmout_desc_t;
453
454 static volatile int next_id = 0;
455 #define MAX_TMOUTS 128
456
457 tmout_desc_t tmouts[MAX_TMOUTS] = { {0} };
458
459 int timeout_random = 0x12123400;
460
461 void
462 oss_timer_callback (unsigned long id)
463 {
464 tmout_desc_t *tmout;
465 int ix;
466 void *arg;
467
468 timeout_random++;
469
470 ix = id & 0xff;
471 if (ix < 0 || ix >= MAX_TMOUTS)
472 return;
473 tmout = &tmouts[ix];
474
475 if (tmout->timestamp != id) /* Expired timer */
476 return;
477
478 if (!tmout->active)
479 return;
480
481 arg = tmout->arg;
482 tmout->active = 0;
483 tmout->timestamp = 0;
484
485 tmout->func (arg);
486 }
487
488 timeout_id_t
489 oss_timeout (void (*func) (void *), void *arg, unsigned long long ticks)
490 {
491 tmout_desc_t *tmout = NULL;
492 int id, n;
493
494 timeout_random++;
495
496 n = 0;
497 id = -1;
498
499 while (id == -1 && n < MAX_TMOUTS)
500 {
501 if (!tmouts[next_id].active)
502 {
503 tmouts[next_id].active = 1;
504 id = next_id++;
505 tmout = &tmouts[id];
506 break;
507 }
508
509 next_id = (next_id + 1) % MAX_TMOUTS;
510 }
511
512 if (id == -1) /* No timer slots available */
513 {
514 oss_cmn_err (CE_WARN, "Timeout table full\n");
515 return 0;
516 }
517
518 tmout->func = func;
519 tmout->arg = arg;
520 tmout->timestamp = id | (timeout_random & ~0xff);
521
522 init_timer (&tmout->timer);
523 tmout->timer.expires = jiffies + ticks;
524 tmout->timer.data = id | (timeout_random & ~0xff);
525 tmout->timer.function = oss_timer_callback;
526 add_timer (&tmout->timer);
527
528 return id | (timeout_random & ~0xff);
529 }
530
531 void
532 oss_untimeout (timeout_id_t id)
533 {
534 tmout_desc_t *tmout;
535 int ix;
536
537 ix = id & 0xff;
538 if (ix < 0 || ix >= MAX_TMOUTS)
539 return;
540
541 timeout_random++;
542 tmout = &tmouts[ix];
543
544 if (tmout->timestamp != id) /* Expired timer */
545 return;
546 if (tmout->active)
547 del_timer (&tmout->timer);
548 tmout->active = 0;
549 tmout->timestamp = 0;
550 }
551
552 int
553 oss_uiomove (void *addr, size_t nbytes, enum uio_rw rwflag, uio_t * uio)
554 {
555 /*
556 * NOTE! Returns 0 upon success and EFAULT on failure (instead of -EFAULT
557 * (for Solaris/BSD compatibilityi)).
558 */
559
560 int c;
561 char *address = addr;
562
563 if (rwflag != uio->rw)
564 {
565 oss_cmn_err (CE_WARN, "uiomove: Bad direction\n");
566 return EFAULT;
567 }
568
569 if (uio->resid < nbytes)
570 {
571 oss_cmn_err (CE_WARN, "uiomove: Bad count %d (%d)\n", nbytes,
572 uio->resid);
573 return EFAULT;
574 }
575
576 if (uio->kernel_space)
577 return EFAULT;
578
579 switch (rwflag)
580 {
581 case UIO_READ:
582 c = nbytes;
583 if (c > 10)
584 c = 0;
585
586 if ((c = copy_to_user (uio->ptr, address, nbytes) != 0))
587 {
588 uio->resid -= nbytes;
589 oss_cmn_err (CE_CONT, "copy_to_user(%d) failed (%d)\n", nbytes, c);
590 return EFAULT;
591 }
592 break;
593
594 case UIO_WRITE:
595 if (copy_from_user (address, uio->ptr, nbytes) != 0)
596 {
597 oss_cmn_err (CE_CONT, "copy_from_user failed\n");
598 uio->resid -= nbytes;
599 return EFAULT;
600 }
601 break;
602 }
603
604 uio->resid -= nbytes;
605 uio->ptr += nbytes;
606
607 return 0;
608 }
609
610 int
611 oss_create_uio (uio_t * uio, char *buf, size_t count, uio_rw_t rw,
612 int is_kernel)
613 {
614 memset (uio, 0, sizeof (*uio));
615
616 if (is_kernel)
617 {
618 oss_cmn_err (CE_CONT,
619 "oss_create_uio: Kernel space buffers not supported\n");
620 return -EIO;
621 }
622
623 uio->ptr = buf;
624 uio->resid = count;
625 uio->kernel_space = is_kernel;
626 uio->rw = rw;
627
628 return 0;
629 }
630
631 void
632 oss_cmn_err (int level, char *s, ...)
633 {
634 char tmp[1024], *a[6];
635 va_list ap;
636 int i, n = 0;
637
638 va_start (ap, s);
639
640 for (i = 0; i < strlen (s); i++)
641 if (s[i] == '%')
642 n++;
643
644 for (i = 0; i < n && i < 6; i++)
645 a[i] = va_arg (ap, char *);
646
647 for (i = n; i < 6; i++)
648 a[i] = NULL;
649
650 if (level == CE_CONT)
651 {
652 sprintf (tmp, s, a[0], a[1], a[2], a[3], a[4], a[5], NULL,
653 NULL, NULL, NULL);
654 printk ("%s", tmp);
655 }
656 else
657 {
658 strcpy (tmp, "osscore: ");
659 sprintf (tmp + strlen (tmp), s, a[0], a[1], a[2], a[3], a[4], a[5],
660 NULL, NULL, NULL, NULL);
661 if (level == CE_PANIC)
662 panic (tmp);
663
664 printk (KERN_ALERT "%s", tmp);
665 }
666 #if 0
667 /* This may cause a crash under SMP */
668 if (sound_started)
669 store_msg (tmp);
670 #endif
671
672 va_end (ap);
673 }
674
675 /*
676 * Sleep/wakeup
677 */
678
679 struct oss_wait_queue
680 {
681 volatile int flags;
682 wait_queue_head_t wq;
683 };
684
685 struct oss_wait_queue *
686 oss_create_wait_queue (oss_device_t * osdev, const char *name)
687 {
688 struct oss_wait_queue *wq;
689
690 if ((wq = vmalloc (sizeof (*wq))) == NULL)
691 {
692 oss_cmn_err (CE_WARN, "vmalloc(%d) failed (wq)\n", sizeof (*wq));
693 return NULL;
694 }
695 init_waitqueue_head (&wq->wq);
696
697 return wq;
698 }
699
700 void
701 oss_reset_wait_queue (struct oss_wait_queue *wq)
702 {
703 wq->flags = 0;
704 }
705
706 void
707 oss_remove_wait_queue (struct oss_wait_queue *wq)
708 {
709 vfree (wq);
710 }
711
712 int
713 oss_sleep (struct oss_wait_queue *wq, oss_mutex_t * mutex, int ticks,
714 oss_native_word * flags, unsigned int *status)
715 {
716 int result = 0;
717 *status = 0;
718
719 if (wq == NULL)
720 return 0;
721
722 wq->flags = 0;
723 oss_spin_unlock_irqrestore (*mutex, *flags);
724
725 if (ticks <= 0)
726 result = wait_event_interruptible (wq->wq, (wq->flags & WK_WAKEUP));
727 else
728 result =
729 wait_event_interruptible_timeout (wq->wq, (wq->flags & WK_WAKEUP),
730 ticks);
731
732 oss_spin_lock_irqsave (*mutex, flags);
733
734 if (result < 0) /* Signal received */
735 {
736 *status |= WK_SIGNAL;
737 return 1;
738 }
739
740 if (!(wq->flags & WK_WAKEUP)) /* Timeout */
741 {
742 return 0;
743 }
744
745 return 1;
746 }
747
748 int
749 oss_register_poll (struct oss_wait_queue *wq, oss_mutex_t * mutex,
750 oss_native_word * flags, oss_poll_event_t * ev)
751 {
752 oss_spin_unlock_irqrestore (*mutex, *flags);
753 poll_wait ((struct file *) ev->file, &wq->wq,
754 (struct poll_table_struct *) ev->wait);
755 oss_spin_lock_irqsave (*mutex, flags);
756 return 0;
757 }
758
759 void
760 oss_wakeup (struct oss_wait_queue *wq, oss_mutex_t * mutex,
761 oss_native_word * flags, short events)
762 {
763 if (wq == NULL)
764 return;
765
766 wq->flags |= WK_WAKEUP;
767 oss_spin_unlock_irqrestore (*mutex, *flags);
768 wake_up (&wq->wq);
769 oss_spin_lock_irqsave (*mutex, flags);
770 }
771
772 void
773 oss_reserve_pages (oss_native_word start_addr, oss_native_word end_addr)
774 {
775 struct page *page, *lastpage;
776
777 lastpage = virt_to_page (end_addr);
778
779 for (page = virt_to_page (start_addr); page <= lastpage; page++)
780 set_bit (PG_reserved, &page->flags);
781 }
782
783 void
784 oss_unreserve_pages (oss_native_word start_addr, oss_native_word end_addr)
785 {
786 struct page *page, *lastpage;
787
788 lastpage = virt_to_page (end_addr);
789
790 for (page = virt_to_page (start_addr); page <= lastpage; page++)
791 clear_bit (PG_reserved, &page->flags);
792 }
793
794 void *
795 oss_contig_malloc (oss_device_t * osdev, int buffsize, oss_uint64_t memlimit,
796 oss_native_word * phaddr)
797 {
798 char *start_addr, *end_addr;
799 int sz, size;
800 int flags = 0;
801
802 *phaddr = 0;
803
804 if (memlimit <= 0x00000000ffffffffLL)
805 flags |= GFP_DMA;
806
807 start_addr = NULL;
808
809 for (sz = 0, size = PAGE_SIZE; size < buffsize; sz++, size <<= 1);
810
811 if (buffsize != (PAGE_SIZE * (1 << sz)))
812 {
813 #if 0
814 printk
815 ("Contig_malloc: Invalid size %d != %ld\n", buffsize,
816 PAGE_SIZE * (1 << sz));
817 #endif
818 }
819
820 start_addr = (char *) __get_free_pages (GFP_KERNEL | flags, sz);
821
822 if (start_addr == NULL)
823 {
824 cmn_err (CE_NOTE, "Failed to allocate memory buffer of %d bytes\n",
825 buffsize);
826 return NULL;
827 }
828 else
829 {
830 /* make some checks */
831 end_addr = start_addr + buffsize - 1;
832
833 oss_reserve_pages ((oss_native_word) start_addr,
834 (oss_native_word) end_addr);
835 }
836
837 *phaddr = virt_to_bus (start_addr);
838 return start_addr;
839 }
840
841 void
842 oss_contig_free (oss_device_t * osdev, void *p, int buffsize)
843 {
844 int sz, size;
845 caddr_t start_addr, end_addr;
846
847 if (p == NULL)
848 return;
849
850 for (sz = 0, size = PAGE_SIZE; size < buffsize; sz++, size <<= 1);
851
852 start_addr = p;
853 end_addr = p + buffsize - 1;
854
855 oss_unreserve_pages ((oss_native_word) start_addr,
856 (oss_native_word) end_addr);
857 free_pages ((unsigned long) p, sz);
858 }
859
860 /*
861 * These typedefs must match definition of struct file_operations.
862 * (See notes in routine oss_register_chrdev).
863 */
864 typedef ssize_t (*read_t) (struct file *, char *, size_t, loff_t *);
865 typedef ssize_t (*write_t) (struct file *, const char *, size_t, loff_t *);
866 typedef unsigned int (*poll_t) (struct file *, poll_table *);
867 typedef poll_table select_table;
868
869 typedef int (*readdir_t) (struct inode *, struct file *, void *, filldir_t);
870 typedef int (*ioctl_t) (struct inode *, struct file *, unsigned int,
871 unsigned long);
872 typedef int (*mmap_t) (struct file *, struct vm_area_struct *);
873 typedef int (*open_t) (struct inode *, struct file *);
874
875 typedef int (*release_t) (struct inode *, struct file *);
876 typedef int (*fasync_t) (int, struct file *, int);
877 typedef int (*fsync_t) (struct inode *, struct file *);
878
879 static loff_t
880 oss_no_llseek (struct file *file, loff_t offset, int orig)
881 {
882 return -EINVAL;
883 }
884
885 static int
886 oss_no_fsync (struct file *f, struct dentry *d, int datasync)
887 {
888 return -EINVAL;
889 }
890
891 static int
892 oss_no_fasync (int x, struct file *f, int m)
893 {
894 return -EINVAL;
895 }
896
897 /*
898 * Wrappers for installing and uninstalling character and block devices.
899 *
900 * The oss_file_operation_handle structure differs from kernel's
901 * file_operations structure in parameters of the driver entry points.
902 * Kernel inode, file, wait_struct, vm_are_struct etc. typed arguments
903 * are replaced by wrapper handles.
904 */
905
906 static struct file_operations *
907 alloc_fop (oss_device_t * osdev, struct oss_file_operation_handle *op)
908 {
909 /*
910 * This routine performs initialization of kernel file_operations structure
911 * from oss_file_operation_handle structure. Each procedure pointer is copied
912 * to a temporary variable before doing the actual assignment. This
913 * prevents unnecessary warnings while it still enables compatibility
914 * warnings.
915 *
916 * Any warning given by this routine may indicate that kernel fs
917 * call interface has changed significantly (added parameters to the routines).
918 * In this case definition routine in oss_file_operation_handle must be updated
919 * and WRAPPER_VERSION must be incremented.
920 */
921
922 struct file_operations *fop;
923
924 poll_t tmp_poll = (poll_t) op->poll;
925 read_t tmp_read = (read_t) op->read;
926 write_t tmp_write = (write_t) op->write;
927 /* readdir_t tmp_readdir = (readdir_t)op->readdir; */
928 ioctl_t tmp_ioctl = (ioctl_t) op->ioctl;
929 mmap_t tmp_mmap = (mmap_t) op->mmap;
930 open_t tmp_open = (open_t) op->open;
931 release_t tmp_release = (release_t) op->release;
932
933 fop = (struct file_operations *)
934 oss_kmem_alloc (sizeof (struct file_operations));
935
936 memset ((char *) fop, 0, sizeof (struct file_operations));
937
938 /*
939 * Now the assignment
940 */
941 fop->llseek = oss_no_llseek;
942 fop->read = tmp_read;
943 fop->write = tmp_write;
944 fop->readdir = NULL; /* tmp_readdir; */
945 fop->poll = tmp_poll;
946 fop->ioctl = tmp_ioctl;
947 fop->mmap = tmp_mmap;
948 fop->open = tmp_open;
949 fop->release = tmp_release;
950 fop->fsync = oss_no_fsync;
951 fop->fasync = oss_no_fasync;
952 fop->lock = NULL;
953 fop->flush = NULL;
954 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0)
955 fop->owner = osdev_get_owner (osdev);
956 #endif
957
958 return fop;
959 }
960
961 int
962 oss_register_chrdev (oss_device_t * osdev, unsigned int major,
963 const char *name, struct oss_file_operation_handle *op)
964 {
965 int maj;
966 maj = register_chrdev (major, name, alloc_fop (osdev, op));
967
968 return maj;
969 }
970
971 void
972 oss_register_minor (int major, int minor, char *name)
973 {
974 if (nminors >= MAX_MINOR)
975 {
976 oss_cmn_err (CE_WARN, "Too many device files\n");
977 return;
978 }
979
980 minors[nminors].major = major;
981 minors[nminors].minor = minor;
982 strcpy (minors[nminors].name, name);
983 nminors++;
984 }
985
986 int
987 oss_unregister_chrdev (unsigned int major, const char *name)
988 {
989 unregister_chrdev (major, name);
990 return 0;
991 }
992
993 int
994 oss_inode_get_minor (oss_inode_handle_t * inode)
995 {
996 return MINOR (((struct inode *) inode)->i_rdev);
997 }
998
999 int
1000 oss_file_get_flags (oss_file_handle_t * file)
1001 {
1002 return ((struct file *) file)->f_flags;
1003 }
1004
1005 void *
1006 oss_file_get_private (oss_file_handle_t * file)
1007 {
1008 return ((struct file *) file)->private_data;
1009 }
1010
1011 void
1012 oss_file_set_private (oss_file_handle_t * file, void *v)
1013 {
1014 ((struct file *) file)->private_data = v;
1015 }
1016
1017 int
1018 oss_vma_get_flags (oss_vm_area_handle_t * vma)
1019 {
1020 return ((struct vm_area_struct *) vma)->vm_flags;
1021 }
1022
1023 int
1024 oss_do_mmap (oss_vm_area_handle_t * v, oss_native_word dmabuf_phys,
1025 int bytes_in_use)
1026 {
1027 struct vm_area_struct *vma = (struct vm_area_struct *) v;
1028 int res, size;
1029
1030 if (vma->vm_pgoff != 0)
1031 {
1032 oss_cmn_err (CE_WARN, "mmap() offset must be 0.\n");
1033 return -EINVAL;
1034 }
1035