⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 z90main.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	PDEBUG("function: %04x\n", function);	rv = build_caller(we_p, function);	PDEBUG("rv from build_caller = %d\n", rv);	return rv;}static inline intz90crypt_prepare(struct work_element *we_p, unsigned int funccode,		 const char __user *buffer){	int rv;	we_p->devindex = -1;	if (funccode == ICARSAMODEXPO)		we_p->buff_size = sizeof(struct ica_rsa_modexpo);	else		we_p->buff_size = sizeof(struct ica_rsa_modexpo_crt);	if (copy_from_user(we_p->buffer, buffer, we_p->buff_size))		return -EFAULT;	we_p->audit[0] |= FP_COPYFROM;	SET_RDWRMASK(we_p->status[0], STAT_WRITTEN);	we_p->funccode = funccode;	we_p->devtype = -1;	we_p->audit[0] |= FP_BUFFREQ;	rv = get_crypto_request_buffer(we_p);	switch (rv) {	case 0:		we_p->audit[0] |= FP_BUFFGOT;		break;	case SEN_USER_ERROR:		rv = -EINVAL;		break;	case SEN_QUEUE_FULL:		rv = 0;		break;	case SEN_RELEASED:		rv = -EFAULT;		break;	case REC_NO_RESPONSE:		rv = -ENODEV;		break;	case SEN_NOT_AVAIL:		rv = -EGETBUFF;		break;	default:		PRINTK("rv = %d\n", rv);		rv = -EGETBUFF;		break;	}	if (CHK_RDWRMASK(we_p->status[0]) == STAT_WRITTEN)		SET_RDWRMASK(we_p->status[0], STAT_DEFAULT);	return rv;}static inline voidpurge_work_element(struct work_element *we_p){	struct list_head *lptr;	spin_lock_irq(&queuespinlock);	list_for_each(lptr, &request_list) {		if (lptr == &we_p->liste) {			list_del(lptr);			requestq_count--;			break;		}	}	list_for_each(lptr, &pending_list) {		if (lptr == &we_p->liste) {			list_del(lptr);			pendingq_count--;			break;		}	}	spin_unlock_irq(&queuespinlock);}/** * Build the request and send it. */static inline intz90crypt_rsa(struct priv_data *private_data_p, pid_t pid,	     unsigned int cmd, unsigned long arg){	struct work_element *we_p;	int rv;	if ((rv = allocate_work_element(&we_p, private_data_p, pid))) {		PDEBUG("PID %d: allocate_work_element returned ENOMEM\n", pid);		return rv;	}	if ((rv = z90crypt_prepare(we_p, cmd, (const char __user *)arg)))		PDEBUG("PID %d: rv = %d from z90crypt_prepare\n", pid, rv);	if (!rv)		if ((rv = z90crypt_send(we_p, (const char *)arg)))			PDEBUG("PID %d: rv %d from z90crypt_send.\n", pid, rv);	if (!rv) {		we_p->audit[0] |= FP_ASLEEP;		wait_event(we_p->waitq, atomic_read(&we_p->alarmrung));		we_p->audit[0] |= FP_AWAKE;		rv = we_p->retcode;	}	if (!rv)		rv = z90crypt_process_results(we_p, (char __user *)arg);	if ((we_p->status[0] & STAT_FAILED)) {		switch (rv) {		/**		 * EINVAL *after* receive is almost always padding		 * error issued by a PCICC or PCIXCC. We convert this		 * return value to -EGETBUFF which should trigger a		 * fallback to software.		 */		case -EINVAL:			if ((we_p->devtype == PCICC) ||			    (we_p->devtype == PCIXCC))				rv = -EGETBUFF;			break;		case -ETIMEOUT:			if (z90crypt.mask.st_count > 0)				rv = -ERESTARTSYS; // retry with another			else				rv = -ENODEV; // no cards left		/* fall through to clean up request queue */		case -ERESTARTSYS:		case -ERELEASED:			switch (CHK_RDWRMASK(we_p->status[0])) {			case STAT_WRITTEN:				purge_work_element(we_p);				break;			case STAT_READPEND:			case STAT_NOWORK:			default:				break;			}			break;		default:			we_p->status[0] ^= STAT_FAILED;			break;		}	}	free_page((long)we_p);	return rv;}/** * This function is a little long, but it's really just one large switch * statement. */static intz90crypt_ioctl(struct inode *inode, struct file *filp,	       unsigned int cmd, unsigned long arg){	struct priv_data *private_data_p = filp->private_data;	unsigned char *status;	unsigned char *qdepth;	unsigned int *reqcnt;	struct ica_z90_status *pstat;	int ret, i, loopLim, tempstat;	static int deprecated_msg_count = 0;	PDEBUG("filp %p (PID %d), cmd 0x%08X\n", filp, PID(), cmd);	PDEBUG("cmd 0x%08X: dir %s, size 0x%04X, type 0x%02X, nr 0x%02X\n",		cmd,		!_IOC_DIR(cmd) ? "NO"		: ((_IOC_DIR(cmd) == (_IOC_READ|_IOC_WRITE)) ? "RW"		: ((_IOC_DIR(cmd) == _IOC_READ) ? "RD"		: "WR")),		_IOC_SIZE(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd));	if (_IOC_TYPE(cmd) != Z90_IOCTL_MAGIC) {		PRINTK("cmd 0x%08X contains bad magic\n", cmd);		return -ENOTTY;	}	ret = 0;	switch (cmd) {	case ICARSAMODEXPO:	case ICARSACRT:		if (quiesce_z90crypt) {			ret = -EQUIESCE;			break;		}		ret = -ENODEV; // Default if no devices		loopLim = z90crypt.hdware_info->hdware_mask.st_count -			(z90crypt.hdware_info->hdware_mask.disabled_count +			 z90crypt.hdware_info->hdware_mask.user_disabled_count);		for (i = 0; i < loopLim; i++) {			ret = z90crypt_rsa(private_data_p, PID(), cmd, arg);			if (ret != -ERESTARTSYS)				break;		}		if (ret == -ERESTARTSYS)			ret = -ENODEV;		break;	case Z90STAT_TOTALCOUNT:		tempstat = get_status_totalcount();		if (copy_to_user((int __user *)arg, &tempstat,sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PCICACOUNT:		tempstat = get_status_PCICAcount();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PCICCCOUNT:		tempstat = get_status_PCICCcount();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PCIXCCCOUNT:		tempstat = get_status_PCIXCCcount();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_REQUESTQ_COUNT:		tempstat = get_status_requestq_count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_PENDINGQ_COUNT:		tempstat = get_status_pendingq_count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_TOTALOPEN_COUNT:		tempstat = get_status_totalopen_count();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_DOMAIN_INDEX:		tempstat = get_status_domain_index();		if (copy_to_user((int __user *)arg, &tempstat, sizeof(int)) != 0)			ret = -EFAULT;		break;	case Z90STAT_STATUS_MASK:		status = kmalloc(Z90CRYPT_NUM_APS, GFP_KERNEL);		if (!status) {			PRINTK("kmalloc for status failed!\n");			ret = -ENOMEM;			break;		}		get_status_status_mask(status);		if (copy_to_user((char __user *) arg, status, Z90CRYPT_NUM_APS)									!= 0)			ret = -EFAULT;		kfree(status);		break;	case Z90STAT_QDEPTH_MASK:		qdepth = kmalloc(Z90CRYPT_NUM_APS, GFP_KERNEL);		if (!qdepth) {			PRINTK("kmalloc for qdepth failed!\n");			ret = -ENOMEM;			break;		}		get_status_qdepth_mask(qdepth);		if (copy_to_user((char __user *) arg, qdepth, Z90CRYPT_NUM_APS) != 0)			ret = -EFAULT;		kfree(qdepth);		break;	case Z90STAT_PERDEV_REQCNT:		reqcnt = kmalloc(sizeof(int) * Z90CRYPT_NUM_APS, GFP_KERNEL);		if (!reqcnt) {			PRINTK("kmalloc for reqcnt failed!\n");			ret = -ENOMEM;			break;		}		get_status_perdevice_reqcnt(reqcnt);		if (copy_to_user((char __user *) arg, reqcnt,				 Z90CRYPT_NUM_APS * sizeof(int)) != 0)			ret = -EFAULT;		kfree(reqcnt);		break;		/* THIS IS DEPRECATED.	USE THE NEW STATUS CALLS */	case ICAZ90STATUS:		if (deprecated_msg_count < 100) {			PRINTK("deprecated call to ioctl (ICAZ90STATUS)!\n");			deprecated_msg_count++;			if (deprecated_msg_count == 100)				PRINTK("No longer issuing messages related to "				       "deprecated call to ICAZ90STATUS.\n");		}		pstat = kmalloc(sizeof(struct ica_z90_status), GFP_KERNEL);		if (!pstat) {			PRINTK("kmalloc for pstat failed!\n");			ret = -ENOMEM;			break;		}		pstat->totalcount	 = get_status_totalcount();		pstat->leedslitecount	 = get_status_PCICAcount();		pstat->leeds2count	 = get_status_PCICCcount();		pstat->requestqWaitCount = get_status_requestq_count();		pstat->pendingqWaitCount = get_status_pendingq_count();		pstat->totalOpenCount	 = get_status_totalopen_count();		pstat->cryptoDomain	 = get_status_domain_index();		get_status_status_mask(pstat->status);		get_status_qdepth_mask(pstat->qdepth);		if (copy_to_user((struct ica_z90_status __user *) arg, pstat,				 sizeof(struct ica_z90_status)) != 0)			ret = -EFAULT;		kfree(pstat);		break;	case Z90QUIESCE:		if (current->euid != 0) {			PRINTK("QUIESCE fails: euid %d\n",			       current->euid);			ret = -EACCES;		} else {			PRINTK("QUIESCE device from PID %d\n", PID());			quiesce_z90crypt = 1;		}		break;	default:		/* user passed an invalid IOCTL number */		PDEBUG("cmd 0x%08X contains invalid ioctl code\n", cmd);		ret = -ENOTTY;		break;	}	return ret;}static inline intsprintcl(unsigned char *outaddr, unsigned char *addr, unsigned int len){	int hl, i;	hl = 0;	for (i = 0; i < len; i++)		hl += sprintf(outaddr+hl, "%01x", (unsigned int) addr[i]);	hl += sprintf(outaddr+hl, " ");	return hl;}static inline intsprintrw(unsigned char *outaddr, unsigned char *addr, unsigned int len){	int hl, inl, c, cx;	hl = sprintf(outaddr, "	   ");	inl = 0;	for (c = 0; c < (len / 16); c++) {		hl += sprintcl(outaddr+hl, addr+inl, 16);		inl += 16;	}	cx = len%16;	if (cx) {		hl += sprintcl(outaddr+hl, addr+inl, cx);		inl += cx;	}	hl += sprintf(outaddr+hl, "\n");	return hl;}static inline intsprinthx(unsigned char *title, unsigned char *outaddr,	 unsigned char *addr, unsigned int len){	int hl, inl, r, rx;	hl = sprintf(outaddr, "\n%s\n", title);	inl = 0;	for (r = 0; r < (len / 64); r++) {		hl += sprintrw(outaddr+hl, addr+inl, 64);		inl += 64;	}	rx = len % 64;	if (rx) {		hl += sprintrw(outaddr+hl, addr+inl, rx);		inl += rx;	}	hl += sprintf(outaddr+hl, "\n");	return hl;}static inline intsprinthx4(unsigned char *title, unsigned char *outaddr,	  unsigned int *array, unsigned int len){	int hl, r;	hl = sprintf(outaddr, "\n%s\n", title);	for (r = 0; r < len; r++) {		if ((r % 8) == 0)			hl += sprintf(outaddr+hl, "    ");		hl += sprintf(outaddr+hl, "%08X ", array[r]);		if ((r % 8) == 7)			hl += sprintf(outaddr+hl, "\n");	}	hl += sprintf(outaddr+hl, "\n");	return hl;}static intz90crypt_status(char *resp_buff, char **start, off_t offset,		int count, int *eof, void *data){	unsigned char *workarea;	int len;	/* resp_buff is a page. Use the right half for a work area */	workarea = resp_buff+2000;	len = 0;	len += sprintf(resp_buff+len, "\nz90crypt version: %d.%d.%d\n",		z90crypt_VERSION, z90crypt_RELEASE, z90crypt_VARIANT);	len += sprintf(resp_buff+len, "Cryptographic domain: %d\n",		get_status_domain_index());	len += sprintf(resp_buff+len, "Total device count: %d\n",		get_status_totalcount());	len += sprintf(resp_buff+len, "PCICA count: %d\n",		get_status_PCICAcount());	len += sprintf(resp_buff+len, "PCICC count: %d\n",		get_status_PCICCcount());	len += sprintf(resp_buff+len, "PCIXCC count: %d\n",		get_status_PCIXCCcount());	len += sprintf(resp_buff+len, "requestq count: %d\n",		get_status_requestq_count());	len += sprintf(resp_buff+len, "pendingq count: %d\n",		get_status_pendingq_count());	len += sprintf(resp_buff+len, "Total open handles: %d\n\n",		get_status_totalopen_count());	len += sprinthx(		"Online devices: 1 means PCICA, 2 means PCICC, 3 means PCIXCC",		resp_buff+len,		get_status_status_mask(workarea),		Z90CRYPT_NUM_APS);	len += sprinthx("Waiting work element counts",		resp_buff+len,		get_status_qdepth_mask(workarea),		Z90CRYPT_NUM_APS);	len += sprinthx4(		"Per-device successfully completed request counts",		resp_buff+len,		get_status_perdevice_reqcnt((unsigned int *)workarea),		Z90CRYPT_NUM_APS);	*eof = 1;	memset(workarea, 0, Z90CRYPT_NUM_APS * sizeof(unsigned int));	return len;}static inline voiddisable_card(int card_index){	struct device *devp;	devp = LONG2DEVPTR(card_index);	if (!devp || devp->user_disabled)		return;	devp->user_disabled = 1;	z90crypt.hdware_info->hdware_mask.user_disabled_count++;	if (devp->dev_type == -1)		return;	z90crypt.hdware_info->type_mask[devp->dev_type].user_disabled_count++;}static inline voidenable_card(int card_index){	struct device *devp;	devp = LONG2DEVPTR(card_index);	if (!devp || !devp->user_disabled)		return;	devp->user_disabled = 0;	z90crypt.hdware_info->hdware_mask.user_disabled_count--;	if (devp->dev_type == -1)		return;	z90crypt.hdware_info->type_mask[devp->dev_type].user_disabled_count--;}static inline intscan_char(unsigned char *bf, unsigned int len,	  unsigned int *offs, unsigned int *p_eof, unsigned char c){	unsigned int i, found;	found = 0;	for (i = 0; i < len; i++) {		if (bf[i] == c) {			found = 1;			break;		}		if (bf[i] == '\0') {			*p_eof = 1;			break;		}		if (bf[i] == '\n') {			break;		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -