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

📄 z90main.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	}	*offs = i+1;	return found;}static inline intscan_string(unsigned char *bf, unsigned int len,	    unsigned int *offs, unsigned int *p_eof, unsigned char *s){	unsigned int temp_len, temp_offs, found, eof;	temp_len = temp_offs = found = eof = 0;	while (!eof && !found) {		found = scan_char(bf+temp_len, len-temp_len,				  &temp_offs, &eof, *s);		temp_len += temp_offs;		if (eof) {			found = 0;			break;		}		if (found) {			if (len >= temp_offs+strlen(s)) {				found = !strncmp(bf+temp_len-1, s, strlen(s));				if (found) {					*offs = temp_len+strlen(s)-1;					break;				}			} else {				found = 0;				*p_eof = 1;				break;			}		}	}	return found;}static intz90crypt_status_write(struct file *file, const char __user *buffer,		      unsigned long count, void *data){	int i, j, len, offs, found, eof;	unsigned char *lbuf;	unsigned int local_count;#define LBUFSIZE 600	lbuf = kmalloc(LBUFSIZE, GFP_KERNEL);	if (!lbuf) {		PRINTK("kmalloc failed!\n");		return 0;	}	if (count <= 0)		return 0;	local_count = UMIN((unsigned int)count, LBUFSIZE-1);	if (copy_from_user(lbuf, buffer, local_count) != 0) {		kfree(lbuf);		return -EFAULT;	}	lbuf[local_count-1] = '\0';	len = 0;	eof = 0;	found = 0;	while (!eof) {		found = scan_string(lbuf+len, local_count-len, &offs, &eof,				    "Online devices");		len += offs;		if (found == 1)			break;	}	if (eof) {		kfree(lbuf);		return count;	}	if (found)		found = scan_char(lbuf+len, local_count-len, &offs, &eof, '\n');	if (!found || eof) {		kfree(lbuf);		return count;	}	len += offs;	j = 0;	for (i = 0; i < 80; i++) {		switch (*(lbuf+len+i)) {		case '\t':		case ' ':			break;		case '\n':		default:			eof = 1;			break;		case '0':		case '1':		case '2':		case '3':			j++;			break;		case 'd':		case 'D':			disable_card(j);			j++;			break;		case 'e':		case 'E':			enable_card(j);			j++;			break;		}		if (eof)			break;	}	kfree(lbuf);	return count;}/** * Functions that run under a timer, with no process id * * The task functions: *     z90crypt_reader_task *	 helper_send_work *	 helper_handle_work_element *	 helper_receive_rc *     z90crypt_config_task *     z90crypt_cleanup_task * * Helper functions: *     z90crypt_schedule_reader_timer *     z90crypt_schedule_reader_task *     z90crypt_schedule_config_task *     z90crypt_schedule_cleanup_task */static inline intreceive_from_crypto_device(int index, unsigned char *psmid, int *buff_len_p,			   unsigned char *buff, unsigned char __user **dest_p_p){	int dv, rv;	struct device *dev_ptr;	struct caller *caller_p;	struct ica_rsa_modexpo *icaMsg_p;	struct list_head *ptr, *tptr;	memcpy(psmid, NULL_psmid, sizeof(NULL_psmid));	if (z90crypt.terminating)		return REC_FATAL_ERROR;	caller_p = 0;	dev_ptr = z90crypt.device_p[index];	rv = 0;	do {		PDEBUG("Dequeue called for device %d\n", index);		if (!dev_ptr || dev_ptr->disabled) {			rv = REC_NO_RESPONSE;			break;		}		if (dev_ptr->dev_self_x != index) {			PRINTK("Corrupt dev ptr in receive_from_AP\n");			z90crypt.terminating = 1;			rv = REC_FATAL_ERROR;			break;		}		if (!dev_ptr->dev_resp_l || !dev_ptr->dev_resp_p) {			dv = DEV_REC_EXCEPTION;			PRINTK("dev_resp_l = %d, dev_resp_p = %p\n",			       dev_ptr->dev_resp_l, dev_ptr->dev_resp_p);		} else {			dv = receive_from_AP(index, z90crypt.cdx,					     dev_ptr->dev_resp_l,					     dev_ptr->dev_resp_p, psmid);		}		switch (dv) {		case DEV_REC_EXCEPTION:			rv = REC_FATAL_ERROR;			z90crypt.terminating = 1;			PRINTKC("Exception in receive from device %d\n",				index);			break;		case DEV_ONLINE:			rv = 0;			break;		case DEV_EMPTY:			rv = REC_EMPTY;			break;		case DEV_NO_WORK:			rv = REC_NO_WORK;			break;		case DEV_BAD_MESSAGE:		case DEV_GONE:		case REC_HARDWAR_ERR:		default:			rv = REC_NO_RESPONSE;			break;		}		if (rv)			break;		if (dev_ptr->dev_caller_count <= 0) {			rv = REC_USER_GONE;			break;	        }		list_for_each_safe(ptr, tptr, &dev_ptr->dev_caller_list) {			caller_p = list_entry(ptr, struct caller, caller_liste);			if (!memcmp(caller_p->caller_id, psmid,				    sizeof(caller_p->caller_id))) {				if (!list_empty(&caller_p->caller_liste)) {					list_del(ptr);					dev_ptr->dev_caller_count--;					INIT_LIST_HEAD(&caller_p->caller_liste);					break;				}			}			caller_p = 0;		}		if (!caller_p) {			rv = REC_USER_GONE;			break;		}		PDEBUG("caller_p after successful receive: %p\n", caller_p);		rv = convert_response(dev_ptr->dev_resp_p,				      caller_p->caller_buf_p, buff_len_p, buff);		switch (rv) {		case REC_OPERAND_INV:			PDEBUG("dev %d: user error %d\n", index, rv);			break;		case WRONG_DEVICE_TYPE:		case REC_HARDWAR_ERR:		case REC_BAD_MESSAGE:			PRINTK("dev %d: hardware error %d\n",			       index, rv);			rv = REC_NO_RESPONSE;			break;		case REC_RELEASED:			PDEBUG("dev %d: REC_RELEASED = %d\n",			       index, rv);			break;		default:			PDEBUG("dev %d: rv = %d\n", index, rv);			break;		}	} while (0);	switch (rv) {	case 0:		PDEBUG("Successful receive from device %d\n", index);		icaMsg_p = (struct ica_rsa_modexpo *)caller_p->caller_buf_p;		*dest_p_p = icaMsg_p->outputdata;		if (*buff_len_p == 0)			PRINTK("Zero *buff_len_p\n");		break;	case REC_NO_RESPONSE:		remove_device(dev_ptr);		break;	}	if (caller_p)		unbuild_caller(dev_ptr, caller_p);	return rv;}static inline voidhelper_send_work(int index){	struct work_element *rq_p;	int rv;	if (list_empty(&request_list))		return;	requestq_count--;	rq_p = list_entry(request_list.next, struct work_element, liste);	list_del(&rq_p->liste);	rq_p->audit[1] |= FP_REMREQUEST;	if (rq_p->devtype == SHRT2DEVPTR(index)->dev_type) {		rq_p->devindex = SHRT2LONG(index);		rv = send_to_crypto_device(rq_p);		if (rv == 0) {			rq_p->requestsent = jiffies;			rq_p->audit[0] |= FP_SENT;			list_add_tail(&rq_p->liste, &pending_list);			++pendingq_count;			rq_p->audit[0] |= FP_PENDING;		} else {			switch (rv) {			case REC_OPERAND_INV:			case REC_OPERAND_SIZE:			case REC_EVEN_MOD:			case REC_INVALID_PAD:				rq_p->retcode = -EINVAL;				break;			case SEN_NOT_AVAIL:			case SEN_RETRY:			case REC_NO_RESPONSE:			default:				if (z90crypt.mask.st_count > 1)					rq_p->retcode =						-ERESTARTSYS;				else					rq_p->retcode = -ENODEV;				break;			}			rq_p->status[0] |= STAT_FAILED;			rq_p->audit[1] |= FP_AWAKENING;			atomic_set(&rq_p->alarmrung, 1);			wake_up(&rq_p->waitq);		}	} else {		if (z90crypt.mask.st_count > 1)			rq_p->retcode = -ERESTARTSYS;		else			rq_p->retcode = -ENODEV;		rq_p->status[0] |= STAT_FAILED;		rq_p->audit[1] |= FP_AWAKENING;		atomic_set(&rq_p->alarmrung, 1);		wake_up(&rq_p->waitq);	}}static inline voidhelper_handle_work_element(int index, unsigned char psmid[8], int rc,			   int buff_len, unsigned char *buff,			   unsigned char __user *resp_addr){	struct work_element *pq_p;	struct list_head *lptr, *tptr;	pq_p = 0;	list_for_each_safe(lptr, tptr, &pending_list) {		pq_p = list_entry(lptr, struct work_element, liste);		if (!memcmp(pq_p->caller_id, psmid, sizeof(pq_p->caller_id))) {			list_del(lptr);			pendingq_count--;			pq_p->audit[1] |= FP_NOTPENDING;			break;		}		pq_p = 0;	}	if (!pq_p) {		PRINTK("device %d has work but no caller exists on pending Q\n",		       SHRT2LONG(index));		return;	}	switch (rc) {		case 0:			pq_p->resp_buff_size = buff_len;			pq_p->audit[1] |= FP_RESPSIZESET;			if (buff_len) {				pq_p->resp_addr = resp_addr;				pq_p->audit[1] |= FP_RESPADDRCOPIED;				memcpy(pq_p->resp_buff, buff, buff_len);				pq_p->audit[1] |= FP_RESPBUFFCOPIED;			}			break;		case REC_OPERAND_INV:		case REC_OPERAND_SIZE:		case REC_EVEN_MOD:		case REC_INVALID_PAD:			PDEBUG("-EINVAL after application error %d\n", rc);			pq_p->retcode = -EINVAL;			pq_p->status[0] |= STAT_FAILED;			break;		case REC_NO_RESPONSE:		default:			if (z90crypt.mask.st_count > 1)				pq_p->retcode = -ERESTARTSYS;			else				pq_p->retcode = -ENODEV;			pq_p->status[0] |= STAT_FAILED;			break;	}	if ((pq_p->status[0] != STAT_FAILED) || (pq_p->retcode != -ERELEASED)) {		pq_p->audit[1] |= FP_AWAKENING;		atomic_set(&pq_p->alarmrung, 1);		wake_up(&pq_p->waitq);	}}/** * return TRUE if the work element should be removed from the queue */static inline inthelper_receive_rc(int index, int *rc_p, int *workavail_p){	switch (*rc_p) {	case 0:	case REC_OPERAND_INV:	case REC_OPERAND_SIZE:	case REC_EVEN_MOD:	case REC_INVALID_PAD:		return 1;	case REC_BUSY:	case REC_NO_WORK:	case REC_EMPTY:	case REC_RETRY_DEV:	case REC_FATAL_ERROR:		break;	case REC_NO_RESPONSE:		*workavail_p = 0;		break;	default:		PRINTK("rc %d, device %d\n", *rc_p, SHRT2LONG(index));		*rc_p = REC_NO_RESPONSE;		*workavail_p = 0;		break;	}	return 0;}static inline voidz90crypt_schedule_reader_timer(void){	if (timer_pending(&reader_timer))		return;	if (mod_timer(&reader_timer, jiffies+(READERTIME*HZ/1000)) != 0)		PRINTK("Timer pending while modifying reader timer\n");}static voidz90crypt_reader_task(unsigned long ptr){	int workavail, remaining, index, rc, buff_len;	unsigned char	psmid[8];	unsigned char __user *resp_addr;	static unsigned char buff[1024];	PDEBUG("jiffies %ld\n", jiffies);	/**	 * we use workavail = 2 to ensure 2 passes with nothing dequeued before	 * exiting the loop. If remaining == 0 after the loop, there is no work	 * remaining on the queues.	 */	resp_addr = 0;	workavail = 2;	remaining = 0;	buff_len = 0;	while (workavail) {		workavail--;		rc = 0;		spin_lock_irq(&queuespinlock);		memset(buff, 0x00, sizeof(buff));		/* Dequeue once from each device in round robin. */		for (index = 0; index < z90crypt.mask.st_count; index++) {			PDEBUG("About to receive.\n");			rc = receive_from_crypto_device(SHRT2LONG(index),							psmid,							&buff_len,							buff,							&resp_addr);			PDEBUG("Dequeued: rc = %d.\n", rc);			if (helper_receive_rc(index, &rc, &workavail)) {				if (rc != REC_NO_RESPONSE) {					helper_send_work(index);					workavail = 2;				}				helper_handle_work_element(index, psmid, rc,							   buff_len, buff,							   resp_addr);			}			if (rc == REC_FATAL_ERROR)				remaining = 0;			else if (rc != REC_NO_RESPONSE)				remaining +=					SHRT2DEVPTR(index)->dev_caller_count;		}		spin_unlock_irq(&queuespinlock);	}	if (remaining) {		spin_lock_irq(&queuespinlock);		z90crypt_schedule_reader_timer();		spin_unlock_irq(&queuespinlock);	}}static inline voidz90crypt_schedule_config_task(unsigned int expiration){	if (timer_pending(&config_timer))		return;	if (mod_timer(&config_timer, jiffies+(expiration*HZ)) != 0)		PRINTK("Timer pending while modifying config timer\n");}static voidz90crypt_config_task(unsigned long ptr){	int rc;	PDEBUG("jiffies %ld\n", jiffies);	if ((rc = refresh_z90crypt(&z90crypt.cdx)))		PRINTK("Error %d detected in refr

⌨️ 快捷键说明

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