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

📄 z90main.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 5 页
字号:
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 MCL2 count: %d\n",		get_status_PCIXCCMCL2count());	len += sprintf(resp_buff+len, "PCIXCC MCL3 count: %d\n",		get_status_PCIXCCMCL3count());	len += sprintf(resp_buff+len, "CEX2C count: %d\n",		get_status_CEX2Ccount());	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: PCICA, 2: PCICC, 3: PCIXCC (MCL2), "		"4: PCIXCC (MCL3), 5: CEX2C",		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 intz90crypt_status_write(struct file *file, const char __user *buffer,		      unsigned long count, void *data){	int j, eol;	unsigned char *lbuf, *ptr;	unsigned int local_count;#define LBUFSIZE 1200	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] = '\0';	ptr = strstr(lbuf, "Online devices");	if (ptr == 0) {		PRINTK("Unable to parse data (missing \"Online devices\")\n");		kfree(lbuf);		return count;	}	ptr = strstr(ptr, "\n");	if (ptr == 0) {		PRINTK("Unable to parse data (missing newline after \"Online devices\")\n");		kfree(lbuf);		return count;	}	ptr++;	if (strstr(ptr, "Waiting work element counts") == NULL) {		PRINTK("Unable to parse data (missing \"Waiting work element counts\")\n");		kfree(lbuf);		return count;	}	j = 0;	eol = 0;	while ((j < 64) && (*ptr != '\0')) {		switch (*ptr) {		case '\t':		case ' ':			break;		case '\n':		default:			eol = 1;			break;		case '0':	// no device		case '1':	// PCICA		case '2':	// PCICC		case '3':	// PCIXCC_MCL2		case '4':	// PCIXCC_MCL3		case '5':	// CEX2C			j++;			break;		case 'd':		case 'D':			disable_card(j);			j++;			break;		case 'e':		case 'E':			enable_card(j);			j++;			break;		}		if (eol)			break;		ptr++;	}	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 {		if (!dev_ptr || dev_ptr->disabled) {			rv = REC_NO_WORK; // a disabled device can't return work			break;		}		if (dev_ptr->dev_self_x != index) {			PRINTKC("Corrupt dev ptr\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 {			PDEBUG("Dequeue called for device %d\n", index);			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_init(ptr);					dev_ptr->dev_caller_count--;					break;				}			}			caller_p = 0;		}		if (!caller_p) {			PRINTKW("Unable to locate PSMID %02X%02X%02X%02X%02X"				"%02X%02X%02X in device list\n",				psmid[0], psmid[1], psmid[2], psmid[3],				psmid[4], psmid[5], psmid[6], psmid[7]);			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_USE_PCICA:			break;		case REC_OPERAND_INV:		case REC_OPERAND_SIZE:		case REC_EVEN_MOD:		case REC_INVALID_PAD:			PDEBUG("device %d: 'user error' %d\n", index, rv);			break;		case WRONG_DEVICE_TYPE:		case REC_HARDWAR_ERR:		case REC_BAD_MESSAGE:			PRINTKW("device %d: hardware error %d\n", index, rv);			rv = REC_NO_RESPONSE;			break;		default:			PDEBUG("device %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:		PRINTKW("Removing device %d from availability\n", index);		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_init(&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_init(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_USE_PCICA:			pq_p->retcode = -ERESTARTSYS;			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){	switch (*rc_p) {	case 0:	case REC_OPERAND_INV:	case REC_OPERAND_SIZE:	case REC_EVEN_MOD:	case REC_INVALID_PAD:	case REC_USE_PCICA:		break;	case REC_BUSY:	case REC_NO_WORK:	case REC_EMPTY:	case REC_RETRY_DEV:	case REC_FATAL_ERROR:		return 0;	case REC_NO_RESPONSE:		break;	default:		PRINTK("rc %d, device %d converted to REC_NO_RESPONSE\n",		       *rc_p, SHRT2LONG(index));		*rc_p = REC_NO_RESPONSE;		break;	}	return 1;}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, index, rc, buff_len;	unsigned char	psmid[8];	unsigned char __user *resp_addr;	static unsigned char buff[1024];	/**	 * we use workavail = 2 to ensure 2 passes with nothing dequeued before	 *

⌨️ 快捷键说明

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