Rev 9 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 9 | Rev 11 | ||
|---|---|---|---|
| Line 347... | Line 347... | ||
| 347 | static int CmdMachine(DEVICE_OBJ *pd, const PCIVME_INIT_ELEMENT *psInitElement) |
347 | static int CmdMachine(DEVICE_OBJ *pd, const PCIVME_INIT_ELEMENT *psInitElement) |
| 348 | { |
348 | { |
| 349 | u32 adr; |
349 | u32 adr; |
| 350 | int err; |
350 | int err; |
| 351 | 351 | ||
| 352 | PRINTK |
352 | //PRINTK(KERN_DEBUG "%s : CmdMachine()\n", DEVICE_NAME); |
| 353 | 353 | ||
| 354 | // loop through the init (or deinit) list |
354 | // loop through the init (or deinit) list |
| 355 | while (psInitElement->bDestination != STOP) |
355 | while (psInitElement->bDestination != STOP) |
| 356 | { |
356 | { |
| 357 | err = check_command(psInitElement); |
357 | err = check_command(psInitElement); |
| Line 400... | Line 400... | ||
| 400 | static int init_hardware(PATH_OBJ *pp, DEVICE_OBJ *pd, PCIVME_INIT_COMMAND *init) |
400 | static int init_hardware(PATH_OBJ *pp, DEVICE_OBJ *pd, PCIVME_INIT_COMMAND *init) |
| 401 | { |
401 | { |
| 402 | int err; |
402 | int err; |
| 403 | PCIVME_INIT_ELEMENT *element = init->sVie; |
403 | PCIVME_INIT_ELEMENT *element = init->sVie; |
| 404 | 404 | ||
| 405 | PRINTK( |
405 | PRINTK(KERN_INFO "%s : init_hardware()\n", DEVICE_NAME); |
| 406 | 406 | ||
| 407 | err = CmdMachine(pd, element); |
407 | err = CmdMachine(pd, element); |
| 408 | if (err) |
408 | if (err) |
| 409 | { |
409 | { |
| 410 | PRINTK(KERN_DEBUG "%s : init failed with err = %d!\n", DEVICE_NAME, err); |
410 | PRINTK(KERN_DEBUG "%s : init failed with err = %d!\n", DEVICE_NAME, err); |
| Line 619... | Line 619... | ||
| 619 | { |
619 | { |
| 620 | u16 cntrl = readw((const volatile void *) pd->pPCIADACntrl); |
620 | u16 cntrl = readw((const volatile void *) pd->pPCIADACntrl); |
| 621 | u16 intCSR = readw((const volatile void *) pd->pPCIADAIntCSR); |
621 | u16 intCSR = readw((const volatile void *) pd->pPCIADAIntCSR); |
| 622 | int status = 0; |
622 | int status = 0; |
| 623 | 623 | ||
| 624 | PRINTK( |
624 | PRINTK(KERN_INFO "%s : VMEMM_RESET()\n", DEVICE_NAME); |
| 625 | 625 | ||
| 626 | // am I connected and switched on?? |
626 | // am I connected and switched on?? |
| 627 | if ((cntrl & 0x0980) == 0x0980) |
627 | if ((cntrl & 0x0980) == 0x0980) |
| 628 | { |
628 | { |
| 629 | // do command |
629 | // do command |
| Line 798... | Line 798... | ||
| 798 | return -EINVAL; |
798 | return -EINVAL; |
| 799 | } |
799 | } |
| 800 | 800 | ||
| 801 | return 0; |
801 | return 0; |
| 802 | } |
802 | } |
| - | 803 | ||
| - | 804 | /* |
|
| - | 805 | static long pcivme_compat_ioctl(struct file *pFile, unsigned int cmd, unsigned long arg){ |
|
| - | 806 | PRINTK(KERN_DEBUG "%s : pcivme_compat_ioctl(0x%08x), size = %d\n", DEVICE_NAME, cmd, _IOC_SIZE(cmd)); |
|
| - | 807 | return pcivme_ioctl(NULL, pFile, cmd,arg); |
|
| - | 808 | } |
|
| - | 809 | */ |
|
| 803 | 810 | ||
| 804 | static long pcivme_unlocked_ioctl(struct file *pFile, unsigned int cmd, unsigned long arg){ |
811 | static long pcivme_unlocked_ioctl(struct file *pFile, unsigned int cmd, unsigned long arg){ |
| 805 | long retval=0; |
812 | long retval=0; |
| - | 813 | ||
| - | 814 | ||
| 806 | #if HAVE_UNLOCKED_IOCTL |
815 | #if HAVE_UNLOCKED_IOCTL |
| 807 | struct mutex fs_mutex; |
816 | struct mutex fs_mutex; |
| 808 | mutex_init(&fs_mutex); |
817 | mutex_init(&fs_mutex); |
| 809 | mutex_lock(&fs_mutex); |
818 | mutex_lock(&fs_mutex); |
| 810 | #else |
819 | #else |
| 811 | lock_kernel(); |
820 | lock_kernel(); |
| 812 | #endif |
821 | #endif |
| 813 | 822 | ||
| - | 823 | PRINTK(KERN_DEBUG "%s : pcivme_unlocked_ioctl(0x%08x), size = %d\n", DEVICE_NAME, cmd, _IOC_SIZE(cmd)); |
|
| 814 | retval = pcivme_ioctl(NULL, pFile, cmd,arg); |
824 | retval = pcivme_ioctl(NULL, pFile, cmd,arg); |
| 815 | 825 | ||
| 816 | #if HAVE_UNLOCKED_IOCTL |
826 | #if HAVE_UNLOCKED_IOCTL |
| 817 | mutex_unlock(&fs_mutex); |
827 | mutex_unlock(&fs_mutex); |
| 818 | #else |
828 | #else |
| 819 | unlock_kernel(); |
829 | unlock_kernel(); |
| 820 | #endif |
830 | #endif |
| - | 831 | ||
| 821 | return retval; |
832 | return retval; |
| 822 | } |
833 | } |
| 823 | 834 | ||
| 824 | int pcivme_open(struct inode *pInode, struct file *pFile) |
835 | int pcivme_open(struct inode *pInode, struct file *pFile) |
| 825 | { |
836 | { |
| 826 | DEVICE_OBJ *pd = 0; |
837 | DEVICE_OBJ *pd = 0; |
| 827 | DEVICE_OBJ *desc = 0; |
838 | DEVICE_OBJ *desc = 0; |
| 828 |
|
839 | int nMinor = MINOR(pInode->i_rdev); |
| 829 | struct list_head *ptr; |
840 | struct list_head *ptr; |
| 830 | 841 | ||
| 831 | PRINTK(KERN_DEBUG "%s : pcivme_open(), |
842 | PRINTK(KERN_DEBUG "%s : pcivme_open(), %d, scanning %d devices\n", DEVICE_NAME, nMinor, drv.count); |
| 832 | 843 | ||
| 833 | /* search for device */ |
844 | /* search for device */ |
| 834 | for (ptr = drv.devList.next; ptr != &drv.devList; ptr = ptr->next) |
845 | for (ptr = drv.devList.next; ptr != &drv.devList; ptr = ptr->next) |
| 835 | { |
846 | { |
| 836 | pd = list_entry(ptr, DEVICE_OBJ, list); |
847 | pd = list_entry(ptr, DEVICE_OBJ, list); |
| 837 | pd->bConnected = get_module_info(pd); |
848 | pd->bConnected = get_module_info(pd); |
| 838 | if (pd->bConnected) |
849 | if (pd->bConnected) |
| 839 | { |
850 | { |
| 840 | if (test_connection(pd)) |
851 | if (test_connection(pd)) |
| 841 | { |
852 | { |
| 842 | printk(KERN_ERR "%s : connection test for module %d failed!\n", DEVICE_NAME, pd->cModuleNumber); |
853 | printk(KERN_ERR "%s : pcivme_open() connection test for module %d failed!\n", DEVICE_NAME, pd->cModuleNumber); |
| 843 | pd->bConnected = 0; |
854 | pd->bConnected = 0; |
| 844 | } |
855 | } |
| 845 | else |
856 | else |
| 846 | if (pd->cModuleNumber == nMinor) |
857 | if (pd->cModuleNumber == nMinor) |
| 847 | { |
858 | { |
| 848 | desc = pd; |
859 | desc = pd; |
| 849 | break; |
860 | break; |
| 850 | } |
861 | } |
| 851 | } |
862 | } |
| 852 | else |
863 | else |
| 853 | PRINTK(KERN_DEBUG "%s : module %d not connected!\n", DEVICE_NAME, nMinor); |
864 | PRINTK(KERN_DEBUG "%s pcivme_open(): module %d not connected!\n", DEVICE_NAME, nMinor); |
| 854 | } |
865 | } |
| 855 | 866 | ||
| 856 | if (desc) |
867 | if (desc) |
| 857 | { |
868 | { |
| 858 | int err; |
869 | int err; |
| Line 869... | Line 880... | ||
| 869 | pp->read = readByte; |
880 | pp->read = readByte; |
| 870 | pp->write = writeByte; |
881 | pp->write = writeByte; |
| 871 | pp->AlignmentCheck = MisalignmentForByteAccess; |
882 | pp->AlignmentCheck = MisalignmentForByteAccess; |
| 872 | pFile->private_data = (void *)pp; |
883 | pFile->private_data = (void *)pp; |
| 873 | 884 | ||
| 874 | PRINTK(KERN_DEBUG "%s : found VMEMM module with number %d.\n", DEVICE_NAME, nMinor); |
885 | PRINTK(KERN_DEBUG "%s : pcivme_open() found VMEMM module with number %d.\n", DEVICE_NAME, nMinor); |
| 875 | 886 | ||
| 876 | if (!pd->nOpenCounter) |
887 | if (!pd->nOpenCounter) |
| 877 | { |
888 | { |
| 878 | err = CmdMachine(pd, init_element); |
889 | err = CmdMachine(pd, init_element); |
| 879 | if (err) |
890 | if (err) |
| 880 | { |
891 | { |
| 881 | printk(KERN_ERR "%s : default init failed with err = %d!\n", DEVICE_NAME, err); |
892 | printk(KERN_ERR "%s : pcivme_open() default init failed with err = %d!\n", DEVICE_NAME, err); |
| 882 | kfree_s(pp, sizeof(*pp)); // FREE(pFile->private_data); |
893 | kfree_s(pp, sizeof(*pp)); // FREE(pFile->private_data); |
| 883 | return err; |
894 | return err; |
| 884 | } |
895 | } |
| 885 | } |
896 | } |
| 886 | 897 | ||
| 887 | pd->nOpenCounter++; |
898 | pd->nOpenCounter++; |
| 888 | } |
899 | } |
| 889 | else |
900 | else |
| 890 | { |
901 | { |
| 891 | printk(KERN_ERR "%s : No VMEMM module found.\n", DEVICE_NAME); |
902 | printk(KERN_ERR "%s pcivme_open(): No VMEMM module found.\n", DEVICE_NAME); |
| 892 | return -ENODEV; |
903 | return -ENODEV; |
| 893 | } |
904 | } |
| 894 | 905 | ||
| 895 | __MOD_INC_USE_COUNT__; |
906 | __MOD_INC_USE_COUNT__; |
| 896 | return 0; |
907 | return 0; |
| Line 898... | Line 909... | ||
| 898 | 909 | ||
| 899 | int pcivme_release(struct inode *pInode, struct file *pFile) |
910 | int pcivme_release(struct inode *pInode, struct file *pFile) |
| 900 | { |
911 | { |
| 901 | PATH_OBJ *pp; |
912 | PATH_OBJ *pp; |
| 902 | 913 | ||
| 903 | PRINTK(KERN_DEBUG "%s : |
914 | PRINTK(KERN_DEBUG "%s : pcivme_release()\n", DEVICE_NAME); |
| 904 | 915 | ||
| 905 | if (pFile->private_data) |
916 | if (pFile->private_data) |
| 906 | { |
917 | { |
| 907 | pp = (PATH_OBJ *)pFile->private_data; |
918 | pp = (PATH_OBJ *)pFile->private_data; |
| 908 | if (pp && pp->pDo ) |
919 | if (pp && pp->pDo ) |
| Line 1014... | Line 1025... | ||
| 1014 | 1025 | ||
| 1015 | return dwLocalCount - count; |
1026 | return dwLocalCount - count; |
| 1016 | } |
1027 | } |
| 1017 | 1028 | ||
| 1018 | 1029 | ||
| 1019 |
|
1030 | // http://learninglinuxkernel.in/writing-char-driver-for-linux-kernel-2-6/ |
| - | 1031 | // http://appusajeev.wordpress.com/2011/06/18/writing-a-linux-character-device-driver/ |
|
| 1020 |
|
1032 | loff_t pcivme_lseek(struct file* filep, loff_t offset, int whence) |
| 1021 | { |
1033 | { |
| - | 1034 | ||
| 1022 |
|
1035 | PRINTK(KERN_DEBUG "%s : pcivme_lseek(0x%08x, %d)\n", DEVICE_NAME, (u32) offset, whence); |
| 1023 |
|
1036 | switch (whence) { |
| 1024 |
|
1037 | case 0: /* SEEK_SET */ |
| 1025 |
|
1038 | filep->f_pos = offset; |
| - | 1039 | break; |
|
| 1026 |
|
1040 | case 1: /* SEEK_CUR */ |
| 1027 |
|
1041 | filep->f_pos += offset; |
| - | 1042 | break; |
|
| 1028 |
|
1043 | case 2: /* SEEK_END */ |
| 1029 |
|
1044 | return -EINVAL; |
| 1030 |
|
1045 | default: |
| - | 1046 | return -EINVAL; |
|
| - | 1047 | }; |
|
| - | 1048 | ||
| 1031 |
|
1049 | return filep->f_pos; |
| 1032 | } |
1050 | } |
| - | 1051 | ||
| - | 1052 | ||
| 1033 | #else |
1053 | |
| 1034 | struct file_operations pcivme_fops = |
1054 | struct file_operations pcivme_fops = |
| 1035 | { |
1055 | { |
| - | 1056 | .llseek = pcivme_lseek, /* lseek */ |
|
| 1036 | .read = pcivme_read, /* read */ |
1057 | .read = pcivme_read, /* read */ |
| 1037 | .write = pcivme_write, /* write */ |
1058 | .write = pcivme_write, /* write */ |
| - | 1059 | // .compat_ioctl = pcivme_compat_ioctl, /* ioctl */ |
|
| 1038 | .unlocked_ioctl = pcivme_unlocked_ioctl, /* ioctl */ |
1060 | .unlocked_ioctl = pcivme_unlocked_ioctl, /* ioctl */ |
| 1039 | .open = pcivme_open, /* open */ |
1061 | .open = pcivme_open, /* open */ |
| 1040 | .release = pcivme_release, /* release */ |
1062 | .release = pcivme_release, /* release */ |
| 1041 | }; |
1063 | }; |
| 1042 | #endif |
1064 | |
| 1043 | 1065 | ||
| 1044 | 1066 | ||
| 1045 | 1067 | ||
| 1046 | 1068 | ||
| 1047 | 1069 | ||