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 |