📄 sci_inf.c
字号:
} return (rc);}/****************************************************************************** Name: sci_inf_ioctl**** Purpose: POSIX ioctl**** Parameters: inode:** file:** ioctl_num: special operation number of this device** ioctl_param: input/output parameters of ioctl**** Returns =0: success** <0: if any error occur****************************************************************************/int sci_inf_ioctl(struct inode *inode, struct file *file, unsigned int ioctl_num, /* The number of ioctl */ unsigned long ioctl_param /* The parameter to it */){ ULONG sci_id; int rc; SCI_MODES sci_mode; SCI_PARAMETERS sci_param; SCI_ERROR sci_rc; PDEBUG("enter ioctl\n"); sci_id = MINOR(inode->i_rdev); switch (ioctl_num) { case IOCTL_SET_RESET: if (sci_osd_reset(sci_id) == SCI_ERROR_OK) { rc = 0; } else { rc = -1; } break; case IOCTL_SET_MODES: copy_from_user((void *) &sci_mode, (const void *) ioctl_param, sizeof(SCI_MODES)); if (sci_osi_set_modes(sci_id, &sci_mode) == SCI_ERROR_OK) { rc = 0; } else { rc = -1; } break; case IOCTL_GET_MODES: if (sci_osi_get_modes(sci_id, &sci_mode) == SCI_ERROR_OK) { copy_to_user((void *) ioctl_param, (const void *) &sci_mode, sizeof(SCI_MODES)); rc = 0; } else { rc = -1; } break; case IOCTL_SET_PARAMETERS: copy_from_user((void *) &sci_param, (const void *) ioctl_param, sizeof(SCI_PARAMETERS)); if (sci_osi_set_parameters(sci_id, &sci_param) == SCI_ERROR_OK) { rc = 0; } else { rc = -1; } break; case IOCTL_GET_PARAMETERS: if (sci_osi_get_parameters(sci_id, &sci_param) == SCI_ERROR_OK) { copy_to_user((void *) ioctl_param, (const void *) &sci_param, sizeof(SCI_PARAMETERS)); rc = 0; } else { rc = -1; } break; case IOCTL_SET_CLOCK_START: if (sci_osi_clock_start(sci_id) == SCI_ERROR_OK) { rc = 0; } else { rc = -1; } break; case IOCTL_SET_CLOCK_STOP: if (sci_osi_clock_stop(sci_id) == SCI_ERROR_OK) { rc = 0; } else { rc = -1; } break; case IOCTL_GET_IS_CARD_PRESENT: sci_rc = sci_osi_is_card_present(sci_id); put_user(sci_rc, (unsigned long *) ioctl_param); rc = 0; break; case IOCTL_GET_IS_CARD_ACTIVATED: sci_rc = sci_osi_is_card_activated(sci_id); put_user(sci_rc, (unsigned long *) ioctl_param); rc = 0; break; case IOCTL_SET_DEACTIVATE: if (sci_osd_deactivate(sci_id) == SCI_ERROR_OK) { rc = 0; } else { rc = -1; } break; case IOCTL_DUMP_REGS: sci_dump_regs(sci_id); rc = 0; break; case IOCTL_SET_ATR_READY: sci_cb[sci_id].atr_status = SCI_ATR_READY; rc = 0; break; case IOCTL_GET_ATR_STATUS: put_user(sci_cb[sci_id].atr_status, (unsigned long *) ioctl_param); rc = 0; break; default: PDEBUG("error ioctl_num %d\n", ioctl_num); rc = -1; } if (rc != 0) { PDEBUG("ioctl failed\n"); } PDEBUG("ioctl exit\n"); return rc;}/******************************************************************************** POSIX Module Declarations******************************************************************************/static struct { char *name; int minor; struct file_operations *fops; devfs_handle_t devfs_handle; } devnodes[] = { {"sci0",0,&Fops,0}, {"sci1",1,&Fops,0}, };static int no_devnodes = sizeof(devnodes)/sizeof(devnodes[0]);/* init module */int __init sci_module_init(void){ int rc; devfs_handle_t devfs_handle; int i; if (sci_osd_init(detect_p, vcc_p) == SCI_ERROR_OK) { /* Register the character device (at least try) */ if ((rc = devfs_register_chrdev(MAJOR_NUM, DEVICE_NAME, &Fops)) >= 0) { PDEBUG("success\n"); rc = 0; } for(i=0; i < no_devnodes; i++) { devfs_handle = devfs_find_handle(NULL, devnodes[i].name, 0, 0, DEVFS_SPECIAL_CHR,0); if(devfs_handle == NULL) { devfs_handle = devfs_register(NULL, devnodes[i].name, DEVFS_FL_DEFAULT, MAJOR_NUM, devnodes[i].minor, S_IFCHR | S_IRUSR | S_IWUSR, devnodes[i].fops, NULL); devnodes[i].devfs_handle = devfs_handle; } else { devnodes[i].devfs_handle = NULL; } } } else { PDEBUG("failed\n"); rc = -1; } return (rc);}/* cleanup module */void __exit sci_module_cleanup(void){ int i; sci_osd_uninit(); /* unregister the device */ if (devfs_unregister_chrdev(MAJOR_NUM, DEVICE_NAME) < 0) { PDEBUG("error in module_unregister_chrdev\n"); } for(i = 0; i < no_devnodes; i++) { if(devnodes[i].devfs_handle != NULL) devfs_unregister(devnodes[i].devfs_handle); }}/* Module loading/unloading */module_init(sci_module_init);module_exit(sci_module_cleanup);/****************************************************************************** Function: sci_dump_regs**** Purpose: Print contents of all SCI registers**** Parameters: sci_id: zero-based number to identify smart card controller****************************************************************************/void sci_dump_regs(ULONG sci_id){ printk("\n"); printk("Smart Card Interface %x Registers:\n", (UINT) sci_id); printk("------------------------------------"); printk("------------------------------------\n"); printk("SCCTL0 (0x04) 0x%02x | ", *(UCHAR *) sci_cb[sci_id].scctl0); printk("SCCTL1 (0x05) 0x%02x\n", *(UCHAR *) sci_cb[sci_id].scctl1); printk("SCINTEN01 (0x06) 0x%04x | ", *(USHORT *) sci_cb[sci_id].scinten); printk("SCINT01 (0x08) 0x%04x\n", *(USHORT *) sci_cb[sci_id].scint); printk("SCSTAT (0x0A) 0x%02x | ", *(UCHAR *) sci_cb[sci_id].scstat); printk("SCBMR (0x0B) 0x%02x\n", *(UCHAR *) sci_cb[sci_id].scbmr); printk("SCCLK_CNT0 (0x0C) 0x%02x | ", *(UCHAR *) sci_cb[sci_id].scclk_cnt0); printk("SCCTL3 (0x0D) 0x%02x\n", *(UCHAR *) sci_cb[sci_id].scctl3); printk("SCETU (0x0E) 0x%04x | ", *(USHORT *) sci_cb[sci_id].scetu); printk("SCRXLEN (0x10) 0x%04x\n", *(USHORT *) sci_cb[sci_id].scrxlen); printk("SCTXLEN (0x12) 0x%04x | ", *(USHORT *) sci_cb[sci_id].sctxlen); printk("SCCWT (0x14) 0x%04x\n", *(USHORT *) sci_cb[sci_id].sccwt); printk("SCEGT (0x16) 0x%02x | ", *(UCHAR *) sci_cb[sci_id].scegt); printk("SCBWT (0x18) 0x%08x\n", *(UINT *) sci_cb[sci_id].scbwt); printk("------------------------------------"); printk("------------------------------------\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -