Lynx framebuffers multidomain implementation.
[linux/elbrus.git] / drivers / mcst / msps / msps.c
blobc244f67443d465524e8ee2c0998d9412a8b893ab
1 #include <asm/io.h>
2 #include <asm/uaccess.h>
4 #include <linux/errno.h>
5 #include <linux/fcntl.h>
6 #include <linux/interrupt.h>
7 #include <linux/cdev.h>
8 #include <linux/ioctl.h>
9 #include <linux/irq.h>
10 #include <linux/kernel.h>
11 #include <linux/major.h>
12 #include <linux/mm.h>
13 #include <linux/module.h>
14 #include <linux/pci.h>
15 #include <linux/poll.h>
16 #include <linux/proc_fs.h>
17 #include <linux/sched.h>
18 #include <linux/spinlock.h>
19 #include <linux/string.h>
20 #include <linux/types.h>
22 #include <asm/e2k.h>
23 #include <asm/sic_regs.h>
25 /* /proc/sys/debug/msps_debug trigger */
26 int msps_debug = 0;
28 #include "msps.h"
30 #define MSPS_VERSION "0.0.4.03"
32 #ifdef CONFIG_MSPS_MODULE
34 #include <linux/audit.h>
35 #include <linux/err.h>
36 #include <linux/fs_struct.h>
37 #include <linux/mount.h>
38 #include <linux/namei.h>
39 #include <linux/security.h>
41 #endif
43 //#define _PRINT_IOAPIC_REGS_ /* for special kernel with export: print_IPs() */
45 #define MSPS_PRINT_FULL_REGS_OFF /* for on - remove suffix _OFF */
46 #define MSPS_SWITCH_BUFFER_OFF /* for on - remove suffix _OFF */
47 #define MSPS_FILL_DBG_MODE_OFF /* for on - remove suffix _OFF */
49 #define MSPS_USING_IRQ
51 #define __USE_PROC__
53 #define MCST_INCLUDE_IOCTL
54 #ifdef MCST_INCLUDE_IOCTL
55 #include <linux/mcst/mcst_selftest.h>
56 #endif
59 #define MSPS_WAIT 0
60 #define MSPS_NON_WAIT 1
61 #define MSPS_USER 1
63 /* Globals */
65 #define MSPS_NUMBERS 64
66 #define MSPS_PCI_BAR 0x5
68 static char msps_dev_name[] = "MCST,msps";
69 static const char msps_fs_dev_name[] = "msps"; /*for mknod*/
70 #ifndef MSPS_MAJOR
71 #define MSPS_MAJOR 45
72 #endif
73 static int major = MSPS_MAJOR;
74 static msps_dev_t *msps_devices[MAX_MSPS] = {0}; /* all devices */
75 static unsigned long phys_addr; /* phys mem */
76 static unsigned char *base_addr = NULL; /* virt mem */
77 static unsigned long pci_src_len;
78 static int irq;
79 static struct cdev cdev;
80 static int msps_probe_result = 0; /* if < 0 - driver unregister */
82 #define UDEV_ON
83 #undef UDEV_ON
84 #ifdef UDEV_ON
85 static struct class *msps_class;
86 #endif
88 SPINLOCK_T dma_lock;
90 /********************/
91 msps_hrtime_t msps_gethrtime(void) {
92 struct timeval tv;
93 msps_hrtime_t retval;
95 do_gettimeofday(&tv);
97 retval = (msps_hrtime_t)((msps_hrtime_t)tv.tv_sec * 1000000000l)
98 + (msps_hrtime_t)((msps_hrtime_t)tv.tv_usec * 1000);
100 return retval;
102 /******************/
105 MODULE_AUTHOR ("Alexey A. Mukhin");
106 MODULE_LICENSE ("GPL");
107 MODULE_DESCRIPTION("driver for MSPS v. " MSPS_VERSION);
109 static const struct pci_device_id msps_pci_table[] = {
111 .vendor = PCI_VENDOR_ID_MSPS,
112 .device = PCI_DEVICE_ID_MSPS,
113 .class = 0x118000, /* get from developers */
115 {0, }
118 MODULE_DEVICE_TABLE (pci, msps_pci_table);
121 static struct pci_driver msps_driver = {
122 .name = msps_dev_name,
123 .id_table = msps_pci_table,
124 .probe = msps_probe_pci,
125 .remove = msps_remove_one,
128 #if defined(CONFIG_SYSCTL)
129 #include <linux/sysctl.h>
131 static ctl_table msps_table[] = {
133 .procname = "msps_debug",
134 .data = &msps_debug,
135 .maxlen = sizeof(msps_debug),
136 .mode = 0666,
137 .proc_handler = proc_dointvec,
142 static ctl_table msps_root_table[] = {
144 .procname = "debug",
145 .maxlen = 0,
146 .mode = 0555,
147 .child = msps_table,
152 static struct ctl_table_header *msps_sysctl_header;
154 static void __init msps_sysctl_register(void)
156 msps_sysctl_header = register_sysctl_table(msps_root_table);
159 static void msps_sysctl_unregister(void)
161 if (msps_sysctl_header)
162 unregister_sysctl_table(msps_sysctl_header);
165 #else /* CONFIG_SYSCTL */
167 static void __init msps_sysctl_register(void)
171 static void msps_sysctl_unregister(void)
174 #endif
176 #ifdef __USE_PROC__
177 #ifndef CONFIG_PROC_FS
179 static int create_msps_proc(void)
181 return 0;
184 static void remove_msps_proc(void)
188 #else
190 struct proc_dir_entry *msps_proc_entry = NULL;
192 static ssize_t
193 msps_read_proc(struct file *file, char __user *buf, size_t count, loff_t *off)
195 int i = 0;
196 #if DEBUG_MODE
197 int j = 0;
198 #endif
199 ssize_t len = 0;
200 char tmpstr[256];
201 msps_dev_t *dev = NULL;
203 snprintf(tmpstr, 256, "MSPS driver info (v. %s):\n", MSPS_VERSION);
204 if ((strlen(tmpstr) + len) > count)
205 goto end_proc;
206 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
207 return -EFAULT;
208 len += strlen(tmpstr);
210 if (msps_debug) {
211 snprintf(tmpstr, 256, "Debug print mode: ON.\n");
212 if ((strlen(tmpstr) + len) > count)
213 goto end_proc;
214 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
215 return -EFAULT;
216 len += strlen(tmpstr);
219 #if ERROR_MODE == 0
220 snprintf(tmpstr, 256, "Driver was compiled without ERROR print !\n");
221 if ((strlen(tmpstr) + len) > count)
222 goto end_proc;
223 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
224 return -EFAULT;
225 len += strlen(tmpstr);
226 #endif
228 #if DEBUG_MODE
229 snprintf(tmpstr, 256, "Driver was compiled with DEBUG print.\n");
230 if ((strlen(tmpstr) + len) > count)
231 goto end_proc;
232 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
233 return -EFAULT;
234 len += strlen(tmpstr);
235 #endif
237 #if DEBUG_DETAIL_MODE
238 snprintf(tmpstr, 256, "Driver was compiled with DETAIL DEBUG print.\n");
239 if ((strlen(tmpstr) + len) > count)
240 goto end_proc;
241 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
242 return -EFAULT;
243 len += strlen(tmpstr);
244 #endif
246 #ifndef __ALL_ONLINE_NODE__
247 snprintf(tmpstr, 256,
248 "All nodes (except zero-node) are off manually in driver.\n");
249 if ((strlen(tmpstr) + len) > count)
250 goto end_proc;
251 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
252 return -EFAULT;
253 len += strlen(tmpstr);
254 #endif
256 snprintf(tmpstr, 256,
257 "major:\t%d\n"
258 "irq:\t%d\n"
259 "pci phys area: 0x%x\n"
260 "pci mmap area: 0x%x\n",
261 major, irq, phys_addr, BASE);
262 if ((strlen(tmpstr) + len) > count)
263 goto end_proc;
264 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
265 return -EFAULT;
266 len += strlen(tmpstr);
267 for (i = 0; i < MAX_MSPS; i++) {
268 dev = msps_devices[i];
269 if (dev != NULL) {
270 snprintf(tmpstr, 256,
271 "\ndevice for %s data\n",
272 "minor:\t\t%d\n"
273 "present:\t%s\n"
274 "opened:\t\t%s\n"
275 "mknod /dev/%s%d c %d %d\n",
276 (i%2) ? "output" : " input",
277 dev->minor,
278 dev->present ? "yes" : "no",
279 dev->open ? "yes" : "no",
280 msps_fs_dev_name, dev->minor,
281 major, dev->minor);
282 if ((strlen(tmpstr) + len) > count)
283 goto end_proc;
284 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
285 return -EFAULT;
286 len += strlen(tmpstr);
287 #if DEBUG_MODE
288 for (j = 0; j < 2; j++) {
289 snprintf(tmpstr, 256,
290 "\tDMA channel %d: virt 0x%p, "
291 "phys 0x%lx size %d rsize %d\n",
293 dev->dma.mem[j].virt,
294 dev->dma.mem[j].phys,
295 dev->dma.mem[j].size,
296 dev->dma.mem[j].real_size);
297 if ((strlen(tmpstr) + len) > count)
298 goto end_proc;
299 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
300 return -EFAULT;
301 len += strlen(tmpstr);
303 #endif
307 snprintf(tmpstr, 256, "\n");
308 if ((strlen(tmpstr) + len) > count)
309 goto end_proc;
310 if (copy_to_user(buf + len, &tmpstr, strlen(tmpstr)))
311 return -EFAULT;
312 len += strlen(tmpstr);
314 end_proc:
315 *off += len;
316 return len;
319 static ssize_t
320 msps_write_proc(struct file *file, const char __user *buf,
321 size_t count, loff_t *off)
323 return -ENODEV;
326 static unsigned int msps_poll_proc(struct file *file, poll_table *wait)
328 return POLLERR;
331 static int msps_open_proc(struct inode *inode, struct file *file)
333 return nonseekable_open(inode, file);
336 static int msps_close_proc(struct inode *inode, struct file *file)
338 return 0;
341 static const struct file_operations msps_proc_fops = {
342 .owner = THIS_MODULE,
343 .llseek = no_llseek,
344 .read = msps_read_proc,
345 .write = msps_write_proc,
346 .poll = msps_poll_proc,
347 .open = msps_open_proc,
348 .release = msps_close_proc
351 static int create_msps_proc(void)
353 msps_proc_entry = proc_create("driver/msps", 0, NULL, &msps_proc_fops);
354 if (!msps_proc_entry) {
355 return 0;
357 return 1;
360 static void remove_msps_proc(void)
362 if (msps_proc_entry) {
363 remove_proc_entry("driver/msps", NULL);
364 msps_proc_entry = NULL;
368 #endif /* CONFIG_PROC_FS */
369 #endif /* __USE_PROC__ */
371 #define MY_VM_RESERVED (VM_DONTEXPAND | VM_DONTDUMP)
373 static int msps_mmap(struct file *filp, struct vm_area_struct *vma)
376 msps_dev_t *dev;
377 unsigned long off;
378 dma_addr_t phys;
379 dma_addr_t *virt;
380 int choice;
381 int pminor;
382 #ifdef MSPS_FILL_DBG_MODE
383 unsigned char *tmpbuf;
384 int i; /* for dbg */
385 #endif
387 dev = (msps_dev_t *)filp->private_data;
388 pminor = dev->minor;
390 off = vma->vm_pgoff << PAGE_SHIFT;
392 vma->vm_pgoff = 0;
393 vma->vm_flags |= (VM_READ | VM_WRITE | VM_IO | MY_VM_RESERVED);
394 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
396 switch (off) {
397 /* remap read DMA buffer to user */
398 case MSPS_DMA_MMAP_0:
399 phys = dev->dma.mem[0].phys;
400 virt = dev->dma.mem[0].virt;
402 #ifdef MSPS_FILL_DBG_MODE
403 tmpbuf = (unsigned char *)dev->dma.mem[0].virt;
404 for (i = 0; i < MSPS_DMA_SIZE; i++) {
405 tmpbuf[i] = 0x10;
407 #endif
408 choice = 1;
409 break;
410 case MSPS_DMA_MMAP_1:
411 phys = dev->dma.mem[1].phys;
412 virt = dev->dma.mem[1].virt;
414 #ifdef MSPS_FILL_DBG_MODE
415 tmpbuf = (unsigned char *)dev->dma.mem[1].virt;
416 for (i = 0; i < MSPS_DMA_SIZE; i++) {
417 tmpbuf[i] = 0x21;
419 #endif
420 choice = 2;
421 break;
422 default:
423 ERROR_PRINT("mmap:\terror mmap page choice\n");
424 return -EAGAIN;
425 break;
428 DETAIL_PRINT("mmap:\tMSPS_DMA_MMAP: "
429 "vm_off [%d] 0x%p, off 0x%lx >> 0x%lx\n",
430 choice,
431 virt,
432 phys,
433 phys >> PAGE_SHIFT);
435 if ( remap_pfn_range(vma,
436 vma->vm_start,
437 phys >> PAGE_SHIFT,
438 MSPS_DMA_SIZE,
439 vma->vm_page_prot) < 0)
441 ERROR_PRINT("mmap:\terror mmap DMA memory to user\n");
442 return -EAGAIN;
445 return 0;
450 * write bit 24 in register MSPS_TEST
451 * after reset done - bit 24 must be 0x0
452 * we wait that
453 * warning: must be mutex external
455 int msps_reset_channels()
457 volatile union test_register test;
458 int dbg_count = 0;
459 test.b.reset = 1;
460 SET_MSPS_REG(MSPS_TEST, test.r);
461 while (test.b.reset != 0 && dbg_count < 999999) {
462 test.r = GET_MSPS_REG(MSPS_TEST);
463 dbg_count++;
465 return dbg_count;
470 * reset 3 registers and all channels
472 int msps_reset(msps_dev_t *dev)
474 int dbg_count;
475 int pminor, i;
476 unsigned int treg;
477 pminor = dev->minor;
478 /* warning: !!!
479 stop DMA exchange at all channels
481 MLOCK(&dev->mutex);
482 SET_MSPS_REG(MSPS_LCTL, 0x0);
483 treg = GET_MSPS_REG(MSPS_INTR);
484 for (i = 0; i < MAX_MSPS; i++) {
485 SET_MSPS_REG(MSPS_C(i), 0x0);
487 dbg_count = msps_reset_channels();
488 SET_MSPS_REG(MSPS_TEST, 0);
489 MUNLOCK(&dev->mutex);
491 DBG_PRINT("MSPS_RESET (%d) [0x%x]\n",
492 dbg_count, treg);
493 return 0;
498 * stoped target DMA exchange
500 void msps_stop_dma(u_int chn_num)
502 volatile union lctl_byte lbyte;
503 lbyte.r = GET_MSPS_REG_B(MSPS_LCTL, PAIR_NUMBER(chn_num));
504 if (chn_num%2) {
505 lbyte.b.chn1 = 0;
506 } else {
507 lbyte.b.chn0 = 0;
509 SET_MSPS_REG_B(MSPS_LCTL, PAIR_NUMBER(chn_num), lbyte.r);
510 SET_MSPS_REG(MSPS_C(chn_num), 0);
511 msps_devices[chn_num]->dma.start = 0;
515 static unsigned int msps_poll(struct file *filp, struct poll_table_struct *wait)
517 msps_dev_t *dev;
518 unsigned int mask = 0;
519 int pminor;
521 dev = (msps_dev_t *)filp->private_data;
522 pminor = dev->minor;
524 MLOCK(&dev->mutex);
526 if (dev->dma.done) {
527 DBG_PRINT("poll - dma done\n");
528 dev->poll_flag = 0;
529 if (dev->minor == 1 || dev->minor == 3 || dev->minor == 5)
530 mask |= POLLOUT;
531 else
532 mask |= POLLIN;
533 dev->dma.e = msps_gethrtime();
534 dev->dma.wtime = (dev->dma.e - dev->dma.s)/1000;
535 } else {
536 if (dev->poll_flag) {
537 DBG_PRINT("poll timeout\n");
538 dev->poll_flag = 0;
539 SLOCK(&dma_lock);
540 dev->dma.done = MSPS_DMA_TIMEOUT;
541 msps_stop_dma(dev->minor);
542 SUNLOCK(&dma_lock);
544 dev->dma.e = msps_gethrtime();
545 dev->dma.wtime = (dev->dma.e - dev->dma.s)/1000;
546 } else {
547 DBG_PRINT("poll wait\n");
548 dev->poll_flag = 1;
552 MUNLOCK(&dev->mutex);
554 if (mask == 0)
555 poll_wait(filp, &dev->dma.wait_queue, wait);
557 DBG_PRINT("msps: poll: mask - %d, flag %d\n", mask, dev->poll_flag);
559 return mask;
563 static int msps_open(struct inode *inode, struct file *filp)
565 msps_dev_t *dev;
566 int minor = MINOR(inode->i_rdev);
567 int pminor;
568 pminor = minor;
570 dev = (msps_dev_t *)filp->private_data;
571 if (!dev) {
572 dev = msps_devices[minor];
573 if (dev->present) {
574 if (dev->open) {
575 WARNING_PRINT("open:\tre-open device\n");
576 return -EBUSY;
577 } else {
578 dev->open = 1;
581 filp->private_data = dev;
582 } else {
583 WARNING_PRINT("open:\tdevice is absent\n");
584 return -EBUSY;
588 DBG_PRINT("open.\n");
590 return 0;
593 static int msps_release(struct inode *inode, struct file *filp)
595 msps_dev_t *dev;
596 int pminor;
597 dev = (msps_dev_t *)filp->private_data;
598 pminor = dev->minor;
599 SLOCK(&dma_lock);
600 if (dev->dma.start) {
601 dev->dma.done = MSPS_DMA_ABORT;
602 msps_stop_dma(dev->minor);
604 SUNLOCK(&dma_lock);
605 dev->open = 0;
606 DBG_PRINT("close.\n");
608 return 0;
612 static ssize_t msps_read(struct file *filp, char *buf,
613 size_t count, loff_t *f_pos)
615 msps_dev_t *dev;
616 int pminor;
617 dev = (msps_dev_t *)filp->private_data;
618 pminor = dev->minor;
619 WARNING_PRINT("read[%d]: Read not implemented.\n", dev->minor);
620 return -EINVAL;
624 static ssize_t msps_write(struct file *filp, const char *buf,
625 size_t count, loff_t *f_pos)
627 msps_dev_t *dev;
628 int pminor;
629 dev = (msps_dev_t *)filp->private_data;
630 pminor = dev->minor;
631 WARNING_PRINT("write[%d]: Write not implemented.\n", dev->minor);
632 return -EINVAL;
636 static int msps_exchange(int who, msps_setup_t *task, int *time,
637 int non_wait, int user_flag)
639 volatile union lctl_register lctl;
640 union lctl_register reg_lctl;
641 union intr_register reg_intr;
642 volatile union lctl_byte lbyte;
643 volatile union lctl_byte lext;
644 u_int chn_num = 0, size = 0, size_in_words = 0, dec = 0;
645 u_long t_count = 0;
646 u_long reg = 0;
647 dma_pool_t *dma;
648 int ret = 0;
649 int pminor;
651 msps_dev_t *dev = msps_devices[who];
653 pminor = dev->minor;
655 if (time == NULL)
656 DETAIL_PRINT("exchange with interrupt.\n");
657 else
658 DETAIL_PRINT("exchange without interrupt.\n");
660 if (non_wait)
661 DETAIL_PRINT("exchange without waiting: minor: %d.\n", who);
663 dev->dma.key = task->key; /* for dbg */
665 /* setup cfg */
666 size = task->size;
667 if (task->size > MSPS_DMA_SIZE)
668 size = MSPS_DMA_SIZE;
670 chn_num = dev->minor;
671 dma = &dev->dma;
672 dma->mem[dma->buffer].user_size = size;
674 if (size%4) dec++;
675 size_in_words = size/4 + dec;
677 task->status.state = 1;
679 task->status.size = size;
680 task->status.buffer = dma->buffer;
682 MLOCK(&dev->mutex);
684 #if DEBUG_MODE
685 reg = GET_MSPS_REG(MSPS_II(chn_num));
686 DETAIL_PRINT("register II%d before write: 0x%x\n", chn_num, reg);
687 #endif
689 /* set buf address */
690 SET_MSPS_REG(MSPS_II(chn_num), dma->mem[dma->buffer].phys);
692 #if DEBUG_MODE
693 reg = GET_MSPS_REG(MSPS_II(chn_num));
694 DETAIL_PRINT("register II%d after write: 0x%x\n", chn_num, reg);
695 #endif
698 #ifdef MSPS_SWITCH_BUFFER
699 /* switch buffers for get data */
700 if (dma->buffer)
701 dma->buffer = 0;
702 else
703 dma->buffer = 1;
704 #endif
706 SET_MSPS_REG(MSPS_C(chn_num), 0);
707 #if DEBUG_MODE
708 reg = GET_MSPS_REG(MSPS_C(chn_num));
709 DETAIL_PRINT("register C%d before write: 0x%x, siw: 0x%x\n",
710 chn_num,
711 reg,
712 size_in_words);
713 #endif
715 /* set size */
716 SET_MSPS_REG(MSPS_C(chn_num), size_in_words);
718 #if DEBUG_MODE
719 reg = GET_MSPS_REG(MSPS_C(chn_num));
720 DETAIL_PRINT("register C%d after write: 0x%x\n", chn_num, reg);
721 #endif
723 /* start exchange */
724 dma->done = 0;
725 SLOCK(&dma_lock);
727 if (user_flag) {
728 dma->start = dev->dma.rele;
729 if (dev->dma.rele == 1)
730 dev->dma.rele = 2;
731 else
732 dev->dma.rele = 1;
735 lctl.r = GET_MSPS_REG(MSPS_LCTL);
736 lbyte.r = GET_MSPS_REG_B(MSPS_LCTL, PAIR_NUMBER(chn_num));
737 lext.r = GET_MSPS_REG_B(MSPS_LCTL, MSPS_LCTL_EXT);
739 #if DEBUG_MODE
740 DETAIL_PRINT("get resgister lctl: %d 0x%x (%x %x %x %x %x %x) b: %x e: %x\n",
741 dev->minor, lctl.r,
742 lctl.b.chn0, lctl.b.chn1, lctl.b.chn2,
743 lctl.b.chn3, lctl.b.chn4, lctl.b.chn5,
744 lbyte.r, lext.r);
745 #endif
747 if (chn_num%2)
748 lbyte.b.chn1 = MSPS_START_DMA;
749 else
750 lbyte.b.chn0 = MSPS_START_DMA;
752 if (task->extended_flag)
753 lext.r |= (1 << chn_num);
754 else
755 lext.r &= ~(1 << chn_num);
757 SET_MSPS_REG_B(MSPS_LCTL, MSPS_LCTL_EXT, lext.r);
758 SET_MSPS_REG_B(MSPS_LCTL, PAIR_NUMBER(chn_num), lbyte.r);
759 SUNLOCK(&dma_lock);
761 #if DEBUG_MODE
762 lctl.r = GET_MSPS_REG(MSPS_LCTL);
763 lbyte.r = GET_MSPS_REG_B(MSPS_LCTL, PAIR_NUMBER(chn_num));
764 lext.r = GET_MSPS_REG_B(MSPS_LCTL, MSPS_LCTL_EXT);
766 DETAIL_PRINT("set resgister lctl: %d 0x%x (%x %x %x %x %x %x) b: %x e: %x\n",
767 dev->minor, lctl.r,
768 lctl.b.chn0, lctl.b.chn1, lctl.b.chn2,
769 lctl.b.chn3, lctl.b.chn4, lctl.b.chn5,
770 lbyte.r, lext.r);
771 #endif
773 dma->s = msps_gethrtime();
775 if (non_wait) {
776 MUNLOCK(&dev->mutex);
777 task->status.state = 0;
778 goto end_exch;
781 if (time != NULL) {
782 int work = 1;
783 dma->done = MSPS_DMA_DONE;
784 DETAIL_PRINT("time wait: %ld microseconds\n", *time);
785 dma->s = msps_gethrtime();
786 do {
787 lbyte.r = GET_MSPS_REG_B(MSPS_LCTL, PAIR_NUMBER(chn_num));
788 if (chn_num%2)
789 work = lbyte.b.chn1 & MSPS_START_DMA;
790 else
791 work = lbyte.b.chn0 & MSPS_START_DMA;
793 dma->e = msps_gethrtime();
794 reg = GET_MSPS_REG(MSPS_C(chn_num));
795 t_count++;
796 if (t_count > 999999 || ((dma->e - dma->s)/1000) >= *time) {
797 dma->done = MSPS_DMA_TIMEOUT;
798 break;
800 } while (work);
801 dma->e = msps_gethrtime();
802 } else {
803 int r;
804 long timeout = 0;
805 int needed_print = 0;
807 while (dma->done == 0) {
808 MUNLOCK(&dev->mutex);
810 dma->twice = 0;
812 * I assume that timeout is set in microseconds,
813 * but not know how correct
814 * translate it for wait..interruptible()
815 * let it be as it is
817 if (task->timeout > 0) {
818 timeout = task->timeout;
819 DBG_PRINT("waiting interrupt and timeout: %d\n", timeout);
820 r = wait_event_interruptible_timeout(dma->wait_queue, (dma->done != 0), timeout/10);
821 } else {
822 DBG_PRINT("waiting only interrupt\n");
823 r = wait_event_interruptible(dma->wait_queue, dma->done);
826 SLOCK(&dma_lock);
827 reg = GET_MSPS_REG(MSPS_C(chn_num));
828 reg_lctl.r = GET_MSPS_REG(MSPS_LCTL);
829 SUNLOCK(&dma_lock);
831 if (r == 0 && timeout) {
832 needed_print = 1;
833 SLOCK(&dma_lock);
834 /* ATTETNTION: this read cleared ALL bits */
835 reg_intr.r = GET_MSPS_REG(MSPS_INTR);
836 dma->done = MSPS_DMA_TIMEOUT;
837 msps_stop_dma(chn_num);
838 SUNLOCK(&dma_lock);
839 DBG_PRINT("timeout was reached: %d\n", timeout);
840 ret = -ETIMEDOUT;
841 } else if (r == -ERESTARTSYS && dma->done == 0) {
842 needed_print = 1;
843 SLOCK(&dma_lock);
844 /* ATTETNTION: this read cleared ALL bits */
845 reg_intr.r = GET_MSPS_REG(MSPS_INTR);
846 dma->done = MSPS_DMA_ABORT;
847 msps_stop_dma(chn_num);
848 SUNLOCK(&dma_lock);
849 DBG_PRINT("get other interrupt\n");
850 ret = -ERESTARTSYS;
853 if (needed_print) {
854 needed_print = 0;
855 unsigned int ii;
856 int start[MAX_MSPS];
857 int key[MAX_MSPS];
859 for (ii = 0; ii < MAX_MSPS; ii++) {
860 start[ii] = msps_devices[ii]->dma.start;
861 key[ii] = msps_devices[ii]->dma.key;
864 #ifdef _PRINT_IOAPIC_REGS_
865 /* for print IOAPIC registers */
866 DBG_PRINT("must be print IOAPIC\n");
867 print_ICs();
868 #endif
870 #if DEBUG_MODE
871 DBG_PRINT("**********: lctl: 0x%x intr: 0x%x\n"
872 " [0 1 2 3 4 5]\n"
873 "start: [%d %d %d %d %d %d]\n"
874 "key : {%4d %4d %4d %4d %4d %4d}\n",
875 reg_lctl.r, reg_intr.r,
876 start[0], start[1], start[2],
877 start[3], start[4], start[5],
878 key[0], key[1], key[2],
879 key[3], key[4], key[5]);
880 #endif
882 MLOCK(&dev->mutex);
884 t_count = 0;
885 dma->e = msps_gethrtime();
888 dma->start = 0;
890 MUNLOCK(&dev->mutex);
892 #if DEBUG_MODE
893 lctl.r = GET_MSPS_REG(MSPS_LCTL);
894 lbyte.r = GET_MSPS_REG_B(MSPS_LCTL, PAIR_NUMBER(chn_num));
895 lext.r = GET_MSPS_REG_B(MSPS_LCTL, MSPS_LCTL_EXT);
896 DETAIL_PRINT("register C%d after work: 0x%x\n", chn_num, reg);
897 DETAIL_PRINT("end resgister lctl: %d 0x%x (%x %x %x %x %x %x) b: %x e: %x\n",
898 dev->minor, lctl.r,
899 lctl.b.chn0, lctl.b.chn1, lctl.b.chn2,
900 lctl.b.chn3, lctl.b.chn4, lctl.b.chn5,
901 lbyte.r,
902 lext.r);
903 #endif
905 task->status.state = dma->done;
906 dma->wtime = (dma->e - dma->s)/1000;
907 task->status.wtime = dma->wtime;
908 task->status.Cx = reg; /* only for dbg */
909 task->status.Lctl = reg_lctl.r; /* only for dbg */
910 task->status.Intr = reg_intr.r; /* only for dbg */
911 task->status.twice = dma->twice;
912 dma->twice = 0;
913 if (time != NULL)
914 *time = (int)((dma->e - dma->s)/1000000);
916 DETAIL_PRINT("%s: count: %03ld, %ld nanosec, buf: %d size: %d\n",
917 __func__,
918 t_count,
919 dma->e - dma->s,
920 task->status.buffer,
921 task->status.size);
923 DETAIL_PRINT("mem 0: [0x%016lx 0x%016lx]\n",
924 *((u64 *)(dma->mem[0].virt + 0)),
925 *((u64 *)(dma->mem[0].virt + 1)));
926 DETAIL_PRINT("mem 1: [0x%016lx 0x%016lx]\n",
927 *((u64 *)(dma->mem[1].virt + 0)),
928 *((u64 *)(dma->mem[1].virt + 1)));
930 DETAIL_PRINT("mem: {0x%lx 0x%lx}\n",
931 __cpu_to_be64(*((u64 *)(dma->mem[dma->buffer].virt + 0))),
932 __cpu_to_be64(*((u64 *)(dma->mem[dma->buffer].virt + 1))));
935 end_exch:
936 return ret;
940 #ifdef __DEVELOPMENT__
941 static int msps_batch_exchange(msps_dev_t *dev, msps_batch_t batch)
945 * 1 string = 64 bytes
946 * 64 string = 4096 bytes = 1 page
947 * all pages = 4
948 * MSPS_MAX_BATCH_SIZE 1024*256 = 4096*64 = 4096*4*16
949 * batch = N in Kbytes
952 msps_setup_t task;
953 int i = 0;
954 int pages = batch/4;
955 int count = 0, tmp;
956 char *begin_array = (char *)dev->user_array;
958 if (batch%4) pages++; /* count numbers of pages for exchange */
960 memset(dev->user_array, 0, MSPS_MAX_BATCH_SIZE);
961 DETAIL_PRINT(" * msps_batch_exchange: batch: %d (Kb), pages: %d \n",
962 batch, pages);
963 /*not needed*/
964 task.status.strings = -1;
965 task.status.page = -1;
967 while (count < pages) {
968 task.start_page = 0;
969 tmp = pages - count;
970 if (tmp > 3) {
971 task.strings = 63 * 4;
972 task.stop_page = 3;
973 } else {
974 task.strings = 63 * tmp;
975 task.stop_page = tmp - 1;
977 msps_exchange(dev->minor, &task, NULL, MSPS_WAIT, MSPS_USER);
978 memcpy(begin_array + count*PAGE_SIZE, dev->virt_dma[0], PAGE_SIZE * 4);
979 /*memcpy(&begin_array[count * PAGE_SIZE], dev->virt_dma[0], PAGE_SIZE * 4);*/
980 count = count + 4;
981 i++;
983 return 0;
985 #endif
988 #ifdef MSPS_PRINT_FULL_REGS
989 void print_full_regs()
991 volatile union lctl_register lctl;
992 volatile u_long test_reg = 0;
993 int i;
994 volatile u_long ii, im, c, cp;
995 int pminor = 9;
997 lctl.r = GET_MSPS_REG(MSPS_LCTL);
998 test_reg = GET_MSPS_REG(MSPS_TEST);
1000 DETAIL_PRINT("registers:\n"
1001 "\tlctl: 0x%x (0x%x 0x%x 0x%x 0x%x 0x%x 0x%x)\n"
1002 "\ttest: 0x%x\n",
1003 lctl.r,
1004 lctl.b.chn0,
1005 lctl.b.chn1,
1006 lctl.b.chn2,
1007 lctl.b.chn3,
1008 lctl.b.chn4,
1009 lctl.b.chn5,
1010 test_reg);
1011 for (i = 0; i < MAX_MSPS; i++) {
1012 ii = GET_MSPS_REG(MSPS_II(i));
1013 im = GET_MSPS_REG(MSPS_IM(i));
1014 c = GET_MSPS_REG(MSPS_C(i));
1015 cp = GET_MSPS_REG(MSPS_CP(i));
1016 DETAIL_PRINT("\tII%d: 0x%x IM%d: 0x%x C%d: 0x%x CP%d: 0x%x\n",
1017 i, ii, i, im, i, c, i, cp);
1020 #endif
1023 * 0X[31-16][14 ][13-8][6 ][5-0]
1024 * 0X[ cntr][masktimeout][mask][intrtimeout][intr]
1025 * if set masktimeout then double interrupt are off
1027 void msps_twice_intr_on()
1029 union intr_register reg;
1030 #if DEBUG_DETAIL_MODE
1031 int pminor = 8;
1032 #endif
1033 SLOCK(&dma_lock);
1034 reg.r = GET_MSPS_REG(MSPS_INTR);
1035 reg.b.masktimeout = 0;
1036 SET_MSPS_REG(MSPS_INTR, reg.r);
1037 SUNLOCK(&dma_lock);
1038 DETAIL_PRINT("MSPS_TWICE_INTR_ON : 0x%08x\n", reg.r);
1042 void msps_twice_intr_off()
1044 union intr_register reg;
1045 #if DEBUG_DETAIL_MODE
1046 int pminor = 8;
1047 #endif
1048 SLOCK(&dma_lock);
1049 reg.r = GET_MSPS_REG(MSPS_INTR);
1050 reg.b.masktimeout = 1;
1051 SET_MSPS_REG(MSPS_INTR, reg.r);
1052 SUNLOCK(&dma_lock);
1053 DETAIL_PRINT("MSPS_TWICE_INTR_ON : 0x%08x\n", reg.r);
1057 void msps_test_mode_on(msps_dev_t *dev)
1059 volatile int reg = 0;
1060 int offset = 0;
1061 #if DEBUG_DETAIL_MODE
1062 int pminor;
1063 pminor = dev->minor;
1064 #endif
1065 offset = (int)(dev->minor / 2);
1066 MLOCK(&dev->mutex);
1067 reg = GET_MSPS_REG(MSPS_TEST);
1068 reg |= (1 << (offset * 8));
1069 SET_MSPS_REG(MSPS_TEST, reg);
1070 MUNLOCK(&dev->mutex);
1071 DETAIL_PRINT("MSPS_TEST_MODE_ON : 0x%08x [%d]\n", reg, offset);
1075 void msps_test_mode_off(msps_dev_t *dev)
1077 volatile int reg = 0, oreg = 0;
1078 int offset = 0;
1079 #if DEBUG_DETAIL_MODE
1080 int pminor;
1081 pminor = dev->minor;
1082 #endif
1083 offset = (int)(dev->minor / 2);
1084 MLOCK(&dev->mutex);
1085 reg = GET_MSPS_REG(MSPS_TEST);
1086 reg &= ~(1 << (offset * 8));
1087 SET_MSPS_REG(MSPS_TEST, reg);
1088 MUNLOCK(&dev->mutex);
1089 DETAIL_PRINT("MSPS_TEST_MODE_OFF: 0x%08x [%d]\n", reg, offset);
1093 static long msps_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1095 int err = 0;
1096 msps_dev_t *dev = (msps_dev_t *)filp->private_data;
1097 int retval = 0;
1098 int pminor;
1099 pminor = dev->minor;
1101 //DBG_PRINT("ioctl:\tdev[%d, %d]: cpu: node: %d, id: %d\n",
1102 DETAIL_PRINT("ioctl:\tdev[%d, %d]: cpu: node: %d, id: %d\n",
1103 major, (dev->minor & 0x0f),
1104 numa_node_id(), raw_smp_processor_id());
1106 MLOCK(&dev->ioctl_mutex);
1108 #ifdef MCST_INCLUDE_IOCTL
1109 if ( cmd == MCST_SELFTEST_MAGIC ) {
1110 selftest_t st;
1111 selftest_pci_t *st_pci = &st.info.pci;
1112 struct pci_dev *pdev = dev->pdev;
1114 DETAIL_PRINT("ioctl:\tSELFTEST\n");
1116 st.bus_type = BUS_PCI;
1117 st.error = 0; /* temporary unused */
1119 st_pci->vendor = pdev->vendor;
1120 st_pci->device = pdev->device;
1122 st_pci->major = major;
1123 st_pci->minor = dev->minor;
1125 st_pci->bus = pdev->bus->number;
1126 st_pci->slot = PCI_SLOT(pdev->devfn);
1127 st_pci->func = PCI_FUNC(pdev->devfn);
1128 st_pci->class = pdev->class;
1130 strncpy(st_pci->name, msps_dev_name, 255);
1131 DBG_PRINT("%s: [%d][%d][%s]. vendor: %#x, device: %#x, bus: %d, slot: %d, func: %d, class: %#x\n",
1132 __func__,
1133 st_pci->major, st_pci->minor,
1134 st_pci->name, st_pci->vendor, st_pci->device,
1135 st_pci->bus, st_pci->slot,
1136 st_pci->func, st_pci->class);
1138 if (copy_to_user((selftest_t __user *)arg,
1139 &st,
1140 sizeof(selftest_t))) {
1141 ERROR_PRINT( "%s: MCST_SELFTEST_MAGIC: copy_to_user() failed\n",
1142 __func__);
1143 retval = -EFAULT;
1145 goto ioctl_end;
1147 #endif
1149 if (_IOC_TYPE(cmd) != MSPS_IOC_MAGIC) {retval = -ENOTTY; goto ioctl_end;}
1150 if (_IOC_NR(cmd) > MSPS_IOC_MAXNR) {retval = -ENOTTY; goto ioctl_end;}
1151 if (_IOC_DIR(cmd) & _IOC_READ)
1152 err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
1153 else if (_IOC_DIR(cmd) & _IOC_WRITE)
1154 err = !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
1155 if (err) {retval = -EFAULT; goto ioctl_end;}
1158 switch(cmd)
1161 case MSPS_GET_STATUS:
1163 volatile union lctl_register lctl;
1164 u_long test_reg = 0;
1166 msps_status_t s;
1167 DETAIL_PRINT("ioctl:\tMSPS_GET_STATUS\n");
1169 MLOCK(&dev->mutex);
1171 lctl.r = GET_MSPS_REG(MSPS_LCTL);
1172 test_reg = GET_MSPS_REG(MSPS_TEST);
1174 s.state = dev->dma.done;
1175 s.buffer = dev->dma.buffer;
1176 s.size = dev->dma.mem[dev->dma.buffer].user_size;
1177 s.wtime = dev->dma.wtime;
1179 if (copy_to_user((msps_status_t __user *)arg,
1181 sizeof(msps_status_t))) {
1182 MUNLOCK(&dev->mutex);
1183 ERROR_PRINT("ioctl: MSPS_GET_STATUS\n");
1184 retval = -EFAULT;
1185 break;
1187 MUNLOCK(&dev->mutex);
1188 DETAIL_PRINT("resgister lctl for stat: %d 0x%x (%x %x %x %x %x %x) test: 0x%x\n",
1189 dev->minor, lctl.r,
1190 lctl.b.chn0, lctl.b.chn1, lctl.b.chn2,
1191 lctl.b.chn3, lctl.b.chn4, lctl.b.chn5,
1192 test_reg);
1194 break;
1197 case MSPS_GET_DATA_BY_REGS:
1199 msps_get_by_regs_t task;
1201 DETAIL_PRINT("ioctl:\tMSPS_GET_DATA_BY_REGS\n");
1202 if (copy_from_user(&task,
1203 (msps_get_by_regs_t __user *)arg,
1204 sizeof(msps_get_by_regs_t)))
1206 ERROR_PRINT("ioctl: GET_BY_REGS copy from user\n");
1207 retval = -EFAULT;
1208 break;
1211 DETAIL_PRINT("ioctl:\tMSPS_GET_DATA_BY_REGS: buf: %d, size %d.\n",
1212 task.buf_number, task.size);
1213 #ifdef __DEVELOPMENT__
1214 /* setup and run exchange */
1215 if (msps_exchange_by_regs(dev, &task, NULL)) {
1216 retval = -EFAULT;
1217 break;
1219 #endif
1221 break;
1223 case MSPS_EXCH_DATA:
1225 msps_setup_t task;
1227 DETAIL_PRINT("ioctl:\tMSPS_EXCH_DATA\n");
1228 if (copy_from_user(&task,
1229 (msps_setup_t __user *)arg,
1230 sizeof(msps_setup_t)))
1232 ERROR_PRINT("ioctl: GET copy from user\n");
1233 retval = -EFAULT;
1234 break;
1237 DBG_PRINT("ioctl:\tMSPS_EXCH_DATA: size %d.\n", task.size);
1238 if (dev->minor == 1 || dev->minor == 3 || dev->minor == 5)
1239 DBG_PRINT("ioctl:\twrite data\n");
1240 else
1241 DBG_PRINT("ioctl:\tread data\n");
1243 /* setup and run exchange */
1244 if (msps_exchange(dev->minor, &task, NULL, MSPS_WAIT, MSPS_USER)) {
1245 retval = -EFAULT;
1246 break;
1249 /* return bufer number, who used, and time exchange */
1250 /* if task.size more than dma array - > set flag override
1251 and bufers used as circle */
1252 if (copy_to_user((msps_setup_t __user *)arg,
1253 &task,
1254 sizeof(msps_setup_t)))
1256 ERROR_PRINT("ioctl: MSPS_GET_DATA copy to user\n");
1257 retval = -EFAULT;
1258 break;
1261 break;
1264 case MSPS_EXCH_DATA_NW:
1266 msps_setup_t task;
1268 DETAIL_PRINT("ioctl:\tMSPS_EXCH_DATA without waiting\n");
1269 if (copy_from_user(&task,
1270 (msps_setup_t __user *)arg,
1271 sizeof(msps_setup_t)))
1273 ERROR_PRINT("ioctl: GET copy from user\n");
1274 retval = -EFAULT;
1275 break;
1278 DBG_PRINT("ioctl:\tMSPS_EXCH_DATA: size %d.\n", task.size);
1279 if (dev->minor == 1 || dev->minor == 3 || dev->minor == 5)
1280 DBG_PRINT("ioctl:\twrite data\n");
1281 else
1282 DBG_PRINT("ioctl:\tread data\n");
1284 /* setup and run exchange */
1285 if (msps_exchange(dev->minor, &task, NULL, MSPS_NON_WAIT, MSPS_USER)) {
1286 retval = -EFAULT;
1287 break;
1290 break;
1293 case MSPS_EXCH_DATA_ACTIVE:
1295 msps_setup_a_t task;
1297 DETAIL_PRINT("ioctl:\tMSPS_EXCH_DATA_ACTIVE\n");
1299 task.s.size = 8;
1300 task.time = 1000;
1302 if (copy_from_user(&task,
1303 (msps_setup_a_t __user *)arg,
1304 sizeof(msps_setup_a_t)))
1306 ERROR_PRINT("ioctl: GET copy from user\n");
1307 retval = -EFAULT;
1308 break;
1311 DBG_PRINT("ioctl:\tMSPS_EXCH_DATA_ACTIVE: size %d.\n", task.s.size);
1312 if (dev->minor == 1 || dev->minor == 3 || dev->minor == 5)
1313 DBG_PRINT("ioctl:\twrite data\n");
1314 else
1315 DBG_PRINT("ioctl:\tread data\n");
1317 /* setup and run exchange */
1318 if (msps_exchange(dev->minor, &task.s, &task.time, MSPS_WAIT, MSPS_USER)) {
1319 retval = -EFAULT;
1320 break;
1323 /* return bufer number, who used, and time exchange */
1324 /* if task.size more than dma array - > set flag override
1325 and bufers used as circle */
1326 if (copy_to_user((msps_setup_a_t __user *)arg,
1327 &task,
1328 sizeof(msps_setup_a_t)))
1330 ERROR_PRINT("ioctl: MSPS_GET_DATA_ACTIVE copy to user\n");
1331 retval = -EFAULT;
1332 break;
1335 break;
1338 case MSPS_GET_BATCH:
1340 retval = -EFAULT;
1341 #ifdef __DEVELOPMENT__
1342 msps_batch_t batch;
1344 DETAIL_PRINT("ioctl:\tMSPS_GET_BATCH\n\n");
1345 if (copy_from_user(&batch,
1346 (msps_batch_t __user *)arg,
1347 sizeof(msps_batch_t)))
1349 ERROR_PRINT("ioctl: GET_BATCH copy from user\n");
1350 retval = -EFAULT;
1351 break;
1355 if (batch <= 0 || batch*1024 > MSPS_MAX_BATCH_SIZE) {
1356 ERROR_PRINT("ioctl: MSPS_GET_BATCH error in "
1357 "msps_batch_t: out of boundares\n");
1358 retval = -EFAULT;
1359 break;
1363 /* setup and run exchange */
1364 if (msps_batch_exchange(dev, batch)) {
1365 retval = -EFAULT;
1366 break;
1368 #endif
1370 break;
1372 case MSPS_RESET:
1374 msps_reset(dev);
1376 break;
1378 case MSPS_TEST_MODE_ON:
1380 msps_test_mode_on(dev);
1382 break;
1384 case MSPS_TEST_MODE_OFF:
1386 msps_test_mode_off(dev);
1388 break;
1390 case MSPS_TWICE_INTR_ON:
1392 msps_twice_intr_on();
1394 break;
1396 case MSPS_TWICE_INTR_OFF:
1398 msps_twice_intr_off();
1400 break;
1402 case MSPS_TEST_EXCH:
1404 msps_setup_t task;
1405 msps_setup_t task_tmp;
1406 int wrnum = 0, rdnum = 0;
1407 unsigned char *wrbuf, *rdbuf;
1408 int nbuf = 0;
1409 #ifdef MSPS_FILL_DBG_MODE
1410 int i;
1411 #endif
1413 DETAIL_PRINT("ioctl:\tMSPS_EXCH_DATA - internal test\n");
1414 if (copy_from_user(&task,
1415 (msps_setup_t __user *)arg,
1416 sizeof(msps_setup_t)))
1418 ERROR_PRINT("ioctl: GET copy from user\n");
1419 retval = -EFAULT;
1420 break;
1423 DETAIL_PRINT("ioctl:\tMSPS_EXCH_DATA: size %d.\n", task.size);
1425 switch (dev->minor) {
1426 case 0:
1427 case 1:
1428 wrnum = 1;
1429 rdnum = 0;
1430 break;
1431 case 2:
1432 case 3:
1433 wrnum = 3;
1434 rdnum = 2;
1435 break;
1436 case 4:
1437 case 5:
1438 wrnum = 5;
1439 rdnum = 4;
1440 break;
1443 nbuf = msps_devices[wrnum]->dma.buffer;
1444 wrbuf = (unsigned char *)(msps_devices[wrnum]->dma.mem[nbuf].virt);
1445 rdbuf = (unsigned char *)(msps_devices[rdnum]->dma.mem[nbuf].virt);
1446 #ifdef MSPS_FILL_DBG_MODE
1447 for (i = 0; i < 64; i++) {
1448 wrbuf[i] = 0x80 + i;
1449 rdbuf[i] = 0x50 + i;
1451 #endif
1452 DETAIL_PRINT("dev %d: [0: 0x%016lx 0x%016lx | 1: 0x%016lx 0x%016lx]\n",
1453 rdnum,
1454 *((u64 *)(msps_devices[rdnum]->dma.mem[0].virt + 0)),
1455 *((u64 *)(msps_devices[rdnum]->dma.mem[0].virt + 1)),
1456 *((u64 *)(msps_devices[rdnum]->dma.mem[1].virt + 0)),
1457 *((u64 *)(msps_devices[rdnum]->dma.mem[1].virt + 1)));
1458 DETAIL_PRINT("dev %d: [0: 0x%016lx 0x%016lx | 1: 0x%016lx 0x%016lx]\n",
1459 wrnum,
1460 *((u64 *)(msps_devices[wrnum]->dma.mem[0].virt + 0)),
1461 *((u64 *)(msps_devices[wrnum]->dma.mem[0].virt + 1)),
1462 *((u64 *)(msps_devices[wrnum]->dma.mem[1].virt + 0)),
1463 *((u64 *)(msps_devices[wrnum]->dma.mem[1].virt + 1)));
1465 msps_test_mode_on(dev);
1467 DETAIL_PRINT("test exch: /dev/msps%d -> /dev/msps%d [48: %s]\n",
1468 wrnum, rdnum,
1469 task.extended_flag ? "YES" : "NO");
1471 /* setup and run exchange */
1473 #ifdef MSPS_PRINT_FULL_REGS
1474 print_full_regs();
1475 #endif
1477 task_tmp.size = task.size;
1478 task_tmp.extended_flag = task.extended_flag;
1479 task_tmp.key = task.key; /* for dbg */
1481 #ifdef __DEVELOPMENT_DBG_
1482 /* dbg: mask all intr, except read channel */
1483 if (0) {
1484 unsigned int rintr = GET_MSPS_REG(MSPS_INTR);
1485 unsigned int wintr = 0x0;
1486 int q;
1487 wintr = rintr;
1488 for (q = 0; q < 6; q++) {
1489 if (q != rdnum) {
1490 wintr |= (1 << (8 + q));
1493 DBG_PRINT("intr reg: 0x%08x -> 0x%08x\n",
1494 rintr, wintr);
1495 SET_MSPS_REG(MSPS_INTR, wintr);
1497 #endif
1498 //if (msps_exchange(wrnum, &task_tmp, NULL, MSPS_NON_WAIT, 0)) {
1499 if (msps_exchange(wrnum, &task_tmp, NULL, MSPS_NON_WAIT, MSPS_USER)) {
1500 ERROR_PRINT("WTF in test exch?\n");
1503 #ifdef MSPS_PRINT_FULL_REGS
1504 print_full_regs();
1505 #endif
1507 if (msps_exchange(rdnum, &task, NULL, MSPS_WAIT, MSPS_USER)) {
1508 retval = -EFAULT;
1509 break;
1512 #ifdef MSPS_PRINT_FULL_REGS
1513 print_full_regs();
1514 #endif
1516 DETAIL_PRINT("dev %d: [0: 0x%016lx 0x%016lx | 1: 0x%016lx 0x%016lx]\n",
1517 rdnum,
1518 *((u64 *)(msps_devices[rdnum]->dma.mem[0].virt + 0)),
1519 *((u64 *)(msps_devices[rdnum]->dma.mem[0].virt + 1)),
1520 *((u64 *)(msps_devices[rdnum]->dma.mem[1].virt + 0)),
1521 *((u64 *)(msps_devices[rdnum]->dma.mem[1].virt + 1)));
1522 DETAIL_PRINT("dev %d: [0: 0x%016lx 0x%016lx | 1: 0x%016lx 0x%016lx]\n",
1523 wrnum,
1524 *((u64 *)(msps_devices[wrnum]->dma.mem[0].virt + 0)),
1525 *((u64 *)(msps_devices[wrnum]->dma.mem[0].virt + 1)),
1526 *((u64 *)(msps_devices[wrnum]->dma.mem[1].virt + 0)),
1527 *((u64 *)(msps_devices[wrnum]->dma.mem[1].virt + 1)));
1529 msps_test_mode_off(dev);
1531 /* return bufer number, who used, and time exchange */
1532 /* if task.size more than dma array - > set flag override
1533 and bufers used as circle */
1534 if (copy_to_user((msps_setup_t __user *)arg,
1535 &task,
1536 sizeof(msps_setup_t)))
1538 ERROR_PRINT("ioctl: MSPS_GET_DATA copy to user\n");
1539 retval = -EFAULT;
1540 break;
1543 break;
1545 default:
1546 ERROR_PRINT("ioctl:\tUnknown command: 0x%08x\n", cmd);
1547 retval = -EINVAL;
1550 ioctl_end:
1551 MUNLOCK(&dev->ioctl_mutex);
1553 //DBG_PRINT("ioctl:\tend\n");
1554 DETAIL_PRINT("ioctl:\tend\n");
1556 return retval;
1559 static struct file_operations msps_fops = {
1560 .owner = THIS_MODULE,
1561 .open = msps_open,
1562 .release = msps_release,
1563 .read = msps_read, /*not implemented*/
1564 .write = msps_write, /*not implemented*/
1565 .unlocked_ioctl = msps_ioctl,
1566 .poll = msps_poll,
1567 .mmap = msps_mmap,
1571 #ifdef __CATCH_INTERRUPT_ON__
1572 #endif
1575 static inline void remove_msps(struct pci_dev *pdev, int step)
1577 int i, j, k;
1578 int pminor = 9;
1580 DBG_PRINT("remove_msps\n");
1582 switch (step) {
1583 default:
1584 case 9:
1585 DBG_PRINT("step 9\n");
1586 #ifdef MSPS_USING_IRQ
1587 free_irq(irq, (void *)msps_devices[0]);
1588 #endif
1589 /* pci_set_drvdata(dev->pdev, NULL); - needed ? */
1590 cdev_del(&cdev);
1591 case 8:
1592 DBG_PRINT("step 8\n");
1593 case 7:
1594 DBG_PRINT("step 7\n");
1595 unregister_chrdev_region(MKDEV(major, 0), MSPS_NUMBERS);
1596 case 6:
1597 DBG_PRINT("step 6\n");
1598 case 5:
1600 DBG_PRINT("step 5\n");
1601 /* free DMA buffers, if set */
1602 struct page *map, *mapend;
1603 int order = get_order(MSPS_DMA_SIZE);
1604 msps_dev_t *dev;
1606 for (j = 0; j < MAX_MSPS; j++) {
1607 dev = msps_devices[j];
1608 if (dev != NULL) {
1609 for (k = 0; k < 2; k++) {
1610 if (dev->dma.mem[k].page != 0) {
1611 mapend = virt_to_page(dev->dma.mem[k].page +
1612 (PAGE_SIZE << order) - 1);
1613 for (map = virt_to_page(dev->dma.mem[k].page);
1614 map <= mapend;
1615 map++)
1616 ClearPageReserved(map);
1618 free_pages(dev->dma.mem[k].page, order);
1619 } else {
1620 break;
1626 case 4:
1627 DBG_PRINT("step 4\n");
1628 iounmap(BASE);
1629 case 3:
1630 DBG_PRINT("step 3\n");
1631 release_mem_region(phys_addr, pci_src_len);
1632 case 2:
1633 DBG_PRINT("step 2\n");
1634 pci_disable_device(pdev);
1636 for (i = 0; i < MAX_MSPS; i++) {
1637 #ifdef UDEV_ON
1638 device_destroy(msps_class, MKDEV(major, i));
1639 #endif
1640 kfree(msps_devices[i]);
1641 msps_devices[i] = NULL;
1643 #ifdef UDEV_ON
1644 class_destroy(msps_class);
1645 #endif
1646 case 1:
1647 DBG_PRINT("step 1\n");
1648 case 0:
1649 DBG_PRINT("step 0\n");
1650 break;
1655 static irqreturn_t msps_interrupt(int irq, void *dev_id, struct pt_regs *regs)
1658 union lctl_register lctl;
1659 union intr_register intr;
1660 static long count = 0;
1661 unsigned int i, tmp = 0;
1662 msps_dev_t *dev;
1663 unsigned long flags;
1664 int pminor = 9;
1666 int start[MAX_MSPS];
1667 int end[MAX_MSPS];
1668 int key[MAX_MSPS];
1670 int twice = 0;
1672 DBG_PRINT("Interrupt count: %d\n", count);
1673 SLOCK_IRQSAVE(&dma_lock, flags);
1674 lctl.r = GET_MSPS_REG(MSPS_LCTL);
1675 intr.r = GET_MSPS_REG(MSPS_INTR);
1677 for (i = 0; i < MAX_MSPS; i++) {
1678 start[i] = msps_devices[i]->dma.start;
1679 key[i] = msps_devices[i]->dma.key;
1681 SUNLOCK_IRQREST(&dma_lock, flags);
1683 if (intr.r == 0) {
1684 DBG_PRINT("Get double interrupt: lctl: 0x%x intr: 0x%x\n",
1685 lctl.r, intr.r);
1686 return IRQ_HANDLED;
1689 twice = 0;
1690 for (i = 0; i < MAX_MSPS; i++) { /* each device */
1691 dev = msps_devices[i];
1692 end[i] = 0;
1693 if (start[i]) {
1694 tmp = intr.r & (1 << i);
1695 if (tmp) { /* dma end */
1696 end[i] = 1;
1697 if (intr.b.intrtimeout) {
1698 dev->dma.twice = 1;
1699 twice = 1;
1701 dev->dma.start = 0;
1702 dev->dma.done = MSPS_DMA_DONE;
1703 wake_up_interruptible(&dev->dma.wait_queue);
1707 count++;
1709 #if DEBUG_MODE
1710 DBG_PRINT("interrupt twice: %s\n", twice ? "YES" : "NO");
1711 DBG_PRINT("get interrupt: lctl: 0x%x intr: 0x%x count: %d\n"
1712 " [0 1 2 3 4 5]\n"
1713 "start: [%d %d %d %d %d %d]\n"
1714 "end : [%d %d %d %d %d %d]\n"
1715 "key : {%4d %4d %4d %4d %4d %4d}\n",
1716 lctl.r, intr.r, count,
1717 start[0], start[1], start[2],
1718 start[3], start[4], start[5],
1719 end[0], end[1], end[2],
1720 end[3], end[4], end[5],
1721 key[0], key[1], key[2],
1722 key[3], key[4], key[5]);
1723 #endif
1725 return IRQ_HANDLED;
1729 static int create_msps_device(msps_dev_t *dev, struct pci_dev *pdev, int minor)
1731 int order, i;
1732 struct page *map, *mapend;
1733 int pminor = minor;
1734 memset((void*)dev, 0, sizeof(msps_dev_t));
1736 dev->minor = minor;
1737 MINIT(&dev->mutex);
1739 DBG_PRINT("Allocate memory for DMA, minor: %d\n", dev->minor);
1741 /* input buffers */
1742 for (i = 0; i < 2; i++) {
1743 order = get_order(MSPS_DMA_SIZE);
1744 dev->dma.mem[i].page = __get_free_pages(GFP_KERNEL | GFP_DMA, order);
1745 if (!dev->dma.mem[i].page) {
1746 ERROR_PRINT("init: MSPS: error allocate DMA buffer, %2d - %2d\n",
1747 minor, i);
1748 return -ENOMEM;
1751 mapend = virt_to_page(dev->dma.mem[i].page + (PAGE_SIZE << order) - 1);
1752 for (map = virt_to_page(dev->dma.mem[i].page); map <= mapend; map++)
1753 SetPageReserved(map);
1755 dev->dma.mem[i].virt = (dma_addr_t *)dev->dma.mem[i].page;
1756 dev->dma.mem[i].phys = virt_to_phys((char *)(dev->dma.mem[i].virt));
1758 memset(dev->dma.mem[i].virt, 0, MSPS_DMA_SIZE);
1759 dev->dma.mem[i].size = MSPS_DMA_SIZE;
1760 dev->dma.mem[i].real_size = PAGE_SIZE << order;
1762 DETAIL_PRINT("msps: DMA channel %d:%d: virt 0x%p, phys 0x%lx size %d rsize %d\n",
1763 minor, i,
1764 dev->dma.mem[i].virt,
1765 dev->dma.mem[i].phys,
1766 dev->dma.mem[i].size,
1767 dev->dma.mem[i].real_size);
1770 #ifndef MSPS_SWITCH_BUFFER
1771 dev->dma.buffer = 0;
1772 #endif
1773 init_waitqueue_head(&dev->dma.wait_queue);
1775 dev->pdev = pdev;
1777 return 0;
1781 static int msps_probe_pci(struct pci_dev *pdev, const struct pci_device_id *ent)
1783 msps_dev_t *dev;
1784 dev_t dev_number;
1785 int err = 0;
1786 int step = 0;
1787 int i = 0;
1788 unsigned int irq_flags = 0;
1789 int pminor = 9;
1791 DBG_PRINT("msps: step: %d.\n", step);
1793 err = pci_enable_device(pdev);
1794 if (err < 0) {
1795 ERROR_PRINT("msps: failed to enable device: err = %d\n", err);
1796 return err;
1799 step = 2;
1800 DBG_PRINT("msps: step: %d.\n", step);
1802 pci_set_master(pdev);
1804 phys_addr = pci_resource_start(pdev, MSPS_PCI_BAR);
1805 if (!phys_addr) {
1806 ERROR_PRINT("msps: card has no PCI IO resources, aborting\n");
1807 err = -ENODEV;
1808 goto error;
1811 irq = pdev->irq;
1813 if (!pci_dma_supported(pdev, MSPS_DMA_MASK)) {
1814 ERROR_PRINT("msps: architecture does not "
1815 "support 32bit PCI busmaster DMA\n");
1816 err = -ENODEV;
1817 goto error;
1820 pci_src_len = pci_resource_len(pdev, MSPS_PCI_BAR);
1821 if (request_mem_region(phys_addr, pci_src_len, "msps_probe_pci") == NULL) {
1822 ERROR_PRINT("msps: memio address range already allocated\n");
1823 err = -EBUSY;
1824 goto error;
1827 step = 3;
1828 DBG_PRINT("msps: step: %d.\n", step);
1830 BASE = ioremap(phys_addr, pci_src_len);
1831 if (BASE == NULL) {
1832 ERROR_PRINT("msps: Unable to map base addr = 0x%lx\n",
1833 phys_addr);
1834 err = -ENOMEM;
1835 goto error;
1836 } else {
1837 DETAIL_PRINT("msps: map base addr: phys = 0x%x, virt = 0x%p\n",
1838 phys_addr, BASE);
1841 step = 4;
1842 DBG_PRINT("msps: step: %d.\n", step);
1844 for (i = 0; i < MAX_MSPS; i++) {
1845 dev = kmalloc(sizeof(msps_dev_t), GFP_KERNEL);
1846 if ( dev < 0 ) {
1847 ERROR_PRINT("msps: Cannot allocate memory for msps_dev_t.\n");
1848 pci_disable_device(pdev);
1849 err = -ENOMEM;
1850 goto error;
1852 memset(dev, 0, sizeof(msps_dev_t));
1853 msps_devices[i] = dev;
1854 err = create_msps_device(dev, pdev, i);
1855 if (err)
1856 goto error;
1858 step = 5;
1859 DBG_PRINT("msps: step: %d.%d .\n", step, i);
1862 step = 6;
1863 DBG_PRINT("msps: step: %d.\n", step);
1865 SINIT(&dma_lock);
1867 if (!major) {
1868 err = alloc_chrdev_region(&dev_number,
1870 MSPS_NUMBERS,
1871 msps_dev_name);
1872 if (!err) {
1873 major = MAJOR(dev_number);
1875 } else {
1876 dev_number = MKDEV(major, 0);
1877 err = register_chrdev_region(dev_number,
1878 MSPS_NUMBERS,
1879 msps_dev_name);
1882 if ( err < 0 ) {
1883 ERROR_PRINT("msps: Can not register char device region.\n");
1884 goto error;
1887 step = 7;
1888 DBG_PRINT("msps: step: %d.\n", step);
1890 #ifdef MSPS_USING_IRQ
1891 irq_flags = IRQF_SHARED;
1893 #ifdef CONFIG_MCST_RT
1894 irq_flags |= IRQF_DISABLED;
1895 #endif
1898 if (request_irq(irq,
1899 (void *)msps_interrupt,
1900 irq_flags,
1901 msps_dev_name,
1902 (void *)msps_devices[0])) {
1903 ERROR_PRINT("msps: cannot register IRQ %d\n", irq);
1904 err = -ENOMEM;
1905 goto error;
1906 } else
1907 DBG_PRINT("msps: assigned IRQ %d\n", irq);
1908 #else
1909 WARNING_PRINT("msps: IRQ disabled\n");
1910 #endif
1912 step = 8;
1913 DBG_PRINT("msps: step: %d.\n", step);
1915 cdev_init(&cdev, &msps_fops);
1916 cdev.owner = THIS_MODULE;
1917 cdev.ops = &msps_fops; /* needed ??? */
1918 err = cdev_add(&cdev, dev_number, MSPS_NUMBERS);
1919 if (err) {
1920 printk("msps: Can not added char device.\n");
1921 goto error;
1924 /* pci_set_drvdata(pdev, dev); */ /* not needed - using global info */
1926 step = 9;
1927 DBG_PRINT("msps: step: %d.\n", step);
1929 /* clear registers */
1930 msps_reset(msps_devices[0]);
1932 /* check devices for realy present */
1933 for (i = 0; i < MAX_MSPS; i++) {
1934 msps_setup_a_t t;
1935 t.s.size = 80;
1936 t.s.extended_flag = 1;
1937 t.time = 10000; /* wait 10 milisec*/
1938 msps_devices[i]->dma.rele = 1; /* only for dbg */
1939 if (i == 1 || i == 3 || i == 5) {
1940 DBG_PRINT("init:\tMSPS check device: %d\n", i);
1941 if (msps_exchange(i, &t.s, &t.time, MSPS_WAIT, 0)) {
1942 ERROR_PRINT("init:\terror at check channel: %d\n", i);
1943 continue;
1946 if (msps_devices[i]->dma.done == MSPS_DMA_DONE) {
1947 NOTE_PRINT("init:\tchannels: %d and %d - present\n",
1948 i-1, i);
1949 msps_devices[i]->present = 1;
1950 msps_devices[i-1]->present = 1;
1951 } else {
1952 WARNING_PRINT("init:\tchannels: %d and %d - absent\n",
1953 i-1, i);
1956 msps_devices[i]->dma.key = 0; /* for dbg */
1959 /* clear registers */
1960 msps_reset(msps_devices[0]);
1962 DBG_PRINT("msps: attached: major: %d.\n", major);
1964 #ifdef MSPS_SWITCH_BUFFER
1965 DBG_PRINT("msps: switched dma buffer - ON\n");
1966 #else
1967 DBG_PRINT("msps: switched dma buffer - OFF: %d\n",
1968 msps_devices[0]->dma.buffer);
1969 #endif
1971 #ifdef MCST_MKNOD_INSIDE
1973 /* Create nodes */
1975 int mode;
1976 dev_t devt;
1977 char nod[128];
1979 #ifdef UDEV_ON
1980 DBG_PRINT("init:\tcreate nodes\n");
1982 msps_class = class_create(THIS_MODULE, "msps");
1983 if (IS_ERR(msps_class)) {
1984 pr_err("Error creating class: /sys/class/msps.\n");
1987 for (i = 0; i < MAX_MSPS; i++) {
1988 sprintf(nod, "%s%d", msps_fs_dev_name, i);
1989 if (!IS_ERR(msps_class)) {
1990 pr_info("make node /sys/class/msps/%s\n", nod);
1991 if (device_create(msps_class, NULL,
1992 MKDEV(major, i), NULL, nod) == NULL)
1993 pr_err("create a node %d failed\n", i);
1997 #endif
1999 #endif
2001 #ifdef __USE_PROC__
2002 DBG_PRINT("init:\tcreate file in /proc/driver/msps\n");
2003 if (!create_msps_proc()) {
2004 ERROR_PRINT("init: can't create /proc/driver/msps\n");
2006 #endif
2008 return 0;
2010 error:
2011 DBG_PRINT("step: %d\n", step);
2012 remove_msps(pdev, step);
2013 msps_probe_result = -1;
2014 return err;
2018 static void msps_remove_one(struct pci_dev *pdev)
2021 #ifdef __USE_PROC__
2022 remove_msps_proc();
2023 #endif
2025 remove_msps(pdev, 99); /* just max number for step */
2029 static int __init msps_init (void)
2031 int result;
2032 int pminor = 9;
2034 NOTE_PRINT("Hello world from MSPS driver. cpu: node: %d, id: %d.\n",
2035 numa_node_id(), raw_smp_processor_id());
2037 msps_sysctl_register();
2039 if (! IS_MACHINE_ES2) {
2040 ERROR_PRINT("init:\tCan not find MSPS.\n");
2041 return -ENXIO;
2043 else
2044 DBG_PRINT ("CPU's numbers: x, node: %d.\n",
2045 num_online_nodes());
2047 result = pci_register_driver(&msps_driver);
2048 if (result != 0) {
2049 ERROR_PRINT("init:\tCan not register MSPS: %d.\n", result);
2050 return -ENODEV;
2053 if (msps_devices[0] == NULL || msps_probe_result < 0) {
2054 ERROR_PRINT("init:\tDevice MSPS did not attached.\n");
2055 pci_unregister_driver(&msps_driver);
2056 DBG_PRINT("init:\tUnregister device driver.\n");
2057 return -ENODEV;
2060 return result;
2064 static void __exit msps_cleanup(void)
2066 int pminor = 9;
2067 DBG_PRINT("exit:\tunregister device driver\n");
2068 pci_unregister_driver(&msps_driver);
2069 msps_sysctl_unregister();
2073 module_init(msps_init);
2074 module_exit(msps_cleanup);