亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tpm_infineon.c

?? linux2.6.16版本
?? C
字號:
/* * Description: * Device Driver for the Infineon Technologies * SLD 9630 TT 1.1 and SLB 9635 TT 1.2 Trusted Platform Module * Specifications at www.trustedcomputinggroup.org * * Copyright (C) 2005, Marcel Selhorst <selhorst@crypto.rub.de> * Sirrix AG - security technologies, http://www.sirrix.com and * Applied Data Security Group, Ruhr-University Bochum, Germany * Project-Homepage: http://www.prosec.rub.de/tpm * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, version 2 of the * License. */#include <linux/pnp.h>#include "tpm.h"/* Infineon specific definitions *//* maximum number of WTX-packages */#define	TPM_MAX_WTX_PACKAGES 	50/* msleep-Time for WTX-packages */#define	TPM_WTX_MSLEEP_TIME 	20/* msleep-Time --> Interval to check status register */#define	TPM_MSLEEP_TIME 	3/* gives number of max. msleep()-calls before throwing timeout */#define	TPM_MAX_TRIES		5000#define	TPM_INFINEON_DEV_VEN_VALUE	0x15D1/* These values will be filled after PnP-call */static int TPM_INF_DATA;static int TPM_INF_ADDR;static int TPM_INF_BASE;static int TPM_INF_ADDR_LEN;static int TPM_INF_PORT_LEN;/* TPM header definitions */enum infineon_tpm_header {	TPM_VL_VER = 0x01,	TPM_VL_CHANNEL_CONTROL = 0x07,	TPM_VL_CHANNEL_PERSONALISATION = 0x0A,	TPM_VL_CHANNEL_TPM = 0x0B,	TPM_VL_CONTROL = 0x00,	TPM_INF_NAK = 0x15,	TPM_CTRL_WTX = 0x10,	TPM_CTRL_WTX_ABORT = 0x18,	TPM_CTRL_WTX_ABORT_ACK = 0x18,	TPM_CTRL_ERROR = 0x20,	TPM_CTRL_CHAININGACK = 0x40,	TPM_CTRL_CHAINING = 0x80,	TPM_CTRL_DATA = 0x04,	TPM_CTRL_DATA_CHA = 0x84,	TPM_CTRL_DATA_CHA_ACK = 0xC4};enum infineon_tpm_register {	WRFIFO = 0x00,	RDFIFO = 0x01,	STAT = 0x02,	CMD = 0x03};enum infineon_tpm_command_bits {	CMD_DIS = 0x00,	CMD_LP = 0x01,	CMD_RES = 0x02,	CMD_IRQC = 0x06};enum infineon_tpm_status_bits {	STAT_XFE = 0x00,	STAT_LPA = 0x01,	STAT_FOK = 0x02,	STAT_TOK = 0x03,	STAT_IRQA = 0x06,	STAT_RDA = 0x07};/* some outgoing values */enum infineon_tpm_values {	CHIP_ID1 = 0x20,	CHIP_ID2 = 0x21,	TPM_DAR = 0x30,	RESET_LP_IRQC_DISABLE = 0x41,	ENABLE_REGISTER_PAIR = 0x55,	IOLIMH = 0x60,	IOLIML = 0x61,	DISABLE_REGISTER_PAIR = 0xAA,	IDVENL = 0xF1,	IDVENH = 0xF2,	IDPDL = 0xF3,	IDPDH = 0xF4};static int number_of_wtx;static int empty_fifo(struct tpm_chip *chip, int clear_wrfifo){	int status;	int check = 0;	int i;	if (clear_wrfifo) {		for (i = 0; i < 4096; i++) {			status = inb(chip->vendor->base + WRFIFO);			if (status == 0xff) {				if (check == 5)					break;				else					check++;			}		}	}	/* Note: The values which are currently in the FIFO of the TPM	   are thrown away since there is no usage for them. Usually,	   this has nothing to say, since the TPM will give its answer	   immediately or will be aborted anyway, so the data here is	   usually garbage and useless.	   We have to clean this, because the next communication with	   the TPM would be rubbish, if there is still some old data	   in the Read FIFO.	 */	i = 0;	do {		status = inb(chip->vendor->base + RDFIFO);		status = inb(chip->vendor->base + STAT);		i++;		if (i == TPM_MAX_TRIES)			return -EIO;	} while ((status & (1 << STAT_RDA)) != 0);	return 0;}static int wait(struct tpm_chip *chip, int wait_for_bit){	int status;	int i;	for (i = 0; i < TPM_MAX_TRIES; i++) {		status = inb(chip->vendor->base + STAT);		/* check the status-register if wait_for_bit is set */		if (status & 1 << wait_for_bit)			break;		msleep(TPM_MSLEEP_TIME);	}	if (i == TPM_MAX_TRIES) {	/* timeout occurs */		if (wait_for_bit == STAT_XFE)			dev_err(chip->dev, "Timeout in wait(STAT_XFE)\n");		if (wait_for_bit == STAT_RDA)			dev_err(chip->dev, "Timeout in wait(STAT_RDA)\n");		return -EIO;	}	return 0;};static void wait_and_send(struct tpm_chip *chip, u8 sendbyte){	wait(chip, STAT_XFE);	outb(sendbyte, chip->vendor->base + WRFIFO);}    /* Note: WTX means Waiting-Time-Extension. Whenever the TPM needs more       calculation time, it sends a WTX-package, which has to be acknowledged       or aborted. This usually occurs if you are hammering the TPM with key       creation. Set the maximum number of WTX-packages in the definitions       above, if the number is reached, the waiting-time will be denied       and the TPM command has to be resend.     */static void tpm_wtx(struct tpm_chip *chip){	number_of_wtx++;	dev_info(chip->dev, "Granting WTX (%02d / %02d)\n",		 number_of_wtx, TPM_MAX_WTX_PACKAGES);	wait_and_send(chip, TPM_VL_VER);	wait_and_send(chip, TPM_CTRL_WTX);	wait_and_send(chip, 0x00);	wait_and_send(chip, 0x00);	msleep(TPM_WTX_MSLEEP_TIME);}static void tpm_wtx_abort(struct tpm_chip *chip){	dev_info(chip->dev, "Aborting WTX\n");	wait_and_send(chip, TPM_VL_VER);	wait_and_send(chip, TPM_CTRL_WTX_ABORT);	wait_and_send(chip, 0x00);	wait_and_send(chip, 0x00);	number_of_wtx = 0;	msleep(TPM_WTX_MSLEEP_TIME);}static int tpm_inf_recv(struct tpm_chip *chip, u8 * buf, size_t count){	int i;	int ret;	u32 size = 0;	number_of_wtx = 0;recv_begin:	/* start receiving header */	for (i = 0; i < 4; i++) {		ret = wait(chip, STAT_RDA);		if (ret)			return -EIO;		buf[i] = inb(chip->vendor->base + RDFIFO);	}	if (buf[0] != TPM_VL_VER) {		dev_err(chip->dev,			"Wrong transport protocol implementation!\n");		return -EIO;	}	if (buf[1] == TPM_CTRL_DATA) {		/* size of the data received */		size = ((buf[2] << 8) | buf[3]);		for (i = 0; i < size; i++) {			wait(chip, STAT_RDA);			buf[i] = inb(chip->vendor->base + RDFIFO);		}		if ((size == 0x6D00) && (buf[1] == 0x80)) {			dev_err(chip->dev, "Error handling on vendor layer!\n");			return -EIO;		}		for (i = 0; i < size; i++)			buf[i] = buf[i + 6];		size = size - 6;		return size;	}	if (buf[1] == TPM_CTRL_WTX) {		dev_info(chip->dev, "WTX-package received\n");		if (number_of_wtx < TPM_MAX_WTX_PACKAGES) {			tpm_wtx(chip);			goto recv_begin;		} else {			tpm_wtx_abort(chip);			goto recv_begin;		}	}	if (buf[1] == TPM_CTRL_WTX_ABORT_ACK) {		dev_info(chip->dev, "WTX-abort acknowledged\n");		return size;	}	if (buf[1] == TPM_CTRL_ERROR) {		dev_err(chip->dev, "ERROR-package received:\n");		if (buf[4] == TPM_INF_NAK)			dev_err(chip->dev,				"-> Negative acknowledgement"				" - retransmit command!\n");		return -EIO;	}	return -EIO;}static int tpm_inf_send(struct tpm_chip *chip, u8 * buf, size_t count){	int i;	int ret;	u8 count_high, count_low, count_4, count_3, count_2, count_1;	/* Disabling Reset, LP and IRQC */	outb(RESET_LP_IRQC_DISABLE, chip->vendor->base + CMD);	ret = empty_fifo(chip, 1);	if (ret) {		dev_err(chip->dev, "Timeout while clearing FIFO\n");		return -EIO;	}	ret = wait(chip, STAT_XFE);	if (ret)		return -EIO;	count_4 = (count & 0xff000000) >> 24;	count_3 = (count & 0x00ff0000) >> 16;	count_2 = (count & 0x0000ff00) >> 8;	count_1 = (count & 0x000000ff);	count_high = ((count + 6) & 0xffffff00) >> 8;	count_low = ((count + 6) & 0x000000ff);	/* Sending Header */	wait_and_send(chip, TPM_VL_VER);	wait_and_send(chip, TPM_CTRL_DATA);	wait_and_send(chip, count_high);	wait_and_send(chip, count_low);	/* Sending Data Header */	wait_and_send(chip, TPM_VL_VER);	wait_and_send(chip, TPM_VL_CHANNEL_TPM);	wait_and_send(chip, count_4);	wait_and_send(chip, count_3);	wait_and_send(chip, count_2);	wait_and_send(chip, count_1);	/* Sending Data */	for (i = 0; i < count; i++) {		wait_and_send(chip, buf[i]);	}	return count;}static void tpm_inf_cancel(struct tpm_chip *chip){	/*	   Since we are using the legacy mode to communicate	   with the TPM, we have no cancel functions, but have	   a workaround for interrupting the TPM through WTX.	 */}static u8 tpm_inf_status(struct tpm_chip *chip){	return inb(chip->vendor->base + STAT);}static DEVICE_ATTR(pubek, S_IRUGO, tpm_show_pubek, NULL);static DEVICE_ATTR(pcrs, S_IRUGO, tpm_show_pcrs, NULL);static DEVICE_ATTR(caps, S_IRUGO, tpm_show_caps, NULL);static DEVICE_ATTR(cancel, S_IWUSR | S_IWGRP, NULL, tpm_store_cancel);static struct attribute *inf_attrs[] = {	&dev_attr_pubek.attr,	&dev_attr_pcrs.attr,	&dev_attr_caps.attr,	&dev_attr_cancel.attr,	NULL,};static struct attribute_group inf_attr_grp = {.attrs = inf_attrs };static struct file_operations inf_ops = {	.owner = THIS_MODULE,	.llseek = no_llseek,	.open = tpm_open,	.read = tpm_read,	.write = tpm_write,	.release = tpm_release,};static struct tpm_vendor_specific tpm_inf = {	.recv = tpm_inf_recv,	.send = tpm_inf_send,	.cancel = tpm_inf_cancel,	.status = tpm_inf_status,	.req_complete_mask = 0,	.req_complete_val = 0,	.attr_group = &inf_attr_grp,	.miscdev = {.fops = &inf_ops,},};static const struct pnp_device_id tpm_pnp_tbl[] = {	/* Infineon TPMs */	{"IFX0101", 0},	{"IFX0102", 0},	{"", 0}};MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl);static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev,				       const struct pnp_device_id *dev_id){	int rc = 0;	u8 iol, ioh;	int vendorid[2];	int version[2];	int productid[2];	char chipname[20];	/* read IO-ports through PnP */	if (pnp_port_valid(dev, 0) && pnp_port_valid(dev, 1) &&	    !(pnp_port_flags(dev, 0) & IORESOURCE_DISABLED)) {		TPM_INF_ADDR = pnp_port_start(dev, 0);		TPM_INF_ADDR_LEN = pnp_port_len(dev, 0);		TPM_INF_DATA = (TPM_INF_ADDR + 1);		TPM_INF_BASE = pnp_port_start(dev, 1);		TPM_INF_PORT_LEN = pnp_port_len(dev, 1);		if ((TPM_INF_PORT_LEN < 4) || (TPM_INF_ADDR_LEN < 2)) {			rc = -EINVAL;			goto err_last;		}		dev_info(&dev->dev, "Found %s with ID %s\n",			 dev->name, dev_id->id);		if (!((TPM_INF_BASE >> 8) & 0xff)) {			rc = -EINVAL;			goto err_last;		}		/* publish my base address and request region */		tpm_inf.base = TPM_INF_BASE;		if (request_region		    (tpm_inf.base, TPM_INF_PORT_LEN, "tpm_infineon0") == NULL) {			rc = -EINVAL;			goto err_last;		}		if (request_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN,				"tpm_infineon0") == NULL) {			rc = -EINVAL;			goto err_last;		}	} else {		rc = -EINVAL;		goto err_last;	}	/* query chip for its vendor, its version number a.s.o. */	outb(ENABLE_REGISTER_PAIR, TPM_INF_ADDR);	outb(IDVENL, TPM_INF_ADDR);	vendorid[1] = inb(TPM_INF_DATA);	outb(IDVENH, TPM_INF_ADDR);	vendorid[0] = inb(TPM_INF_DATA);	outb(IDPDL, TPM_INF_ADDR);	productid[1] = inb(TPM_INF_DATA);	outb(IDPDH, TPM_INF_ADDR);	productid[0] = inb(TPM_INF_DATA);	outb(CHIP_ID1, TPM_INF_ADDR);	version[1] = inb(TPM_INF_DATA);	outb(CHIP_ID2, TPM_INF_ADDR);	version[0] = inb(TPM_INF_DATA);	switch ((productid[0] << 8) | productid[1]) {	case 6:		snprintf(chipname, sizeof(chipname), " (SLD 9630 TT 1.1)");		break;	case 11:		snprintf(chipname, sizeof(chipname), " (SLB 9635 TT 1.2)");		break;	default:		snprintf(chipname, sizeof(chipname), " (unknown chip)");		break;	}	if ((vendorid[0] << 8 | vendorid[1]) == (TPM_INFINEON_DEV_VEN_VALUE)) {		/* configure TPM with IO-ports */		outb(IOLIMH, TPM_INF_ADDR);		outb(((tpm_inf.base >> 8) & 0xff), TPM_INF_DATA);		outb(IOLIML, TPM_INF_ADDR);		outb((tpm_inf.base & 0xff), TPM_INF_DATA);		/* control if IO-ports are set correctly */		outb(IOLIMH, TPM_INF_ADDR);		ioh = inb(TPM_INF_DATA);		outb(IOLIML, TPM_INF_ADDR);		iol = inb(TPM_INF_DATA);		if ((ioh << 8 | iol) != tpm_inf.base) {			dev_err(&dev->dev,				"Could not set IO-ports to 0x%lx\n",				tpm_inf.base);			rc = -EIO;			goto err_release_region;		}		/* activate register */		outb(TPM_DAR, TPM_INF_ADDR);		outb(0x01, TPM_INF_DATA);		outb(DISABLE_REGISTER_PAIR, TPM_INF_ADDR);		/* disable RESET, LP and IRQC */		outb(RESET_LP_IRQC_DISABLE, tpm_inf.base + CMD);		/* Finally, we're done, print some infos */		dev_info(&dev->dev, "TPM found: "			 "config base 0x%x, "			 "io base 0x%x, "			 "chip version %02x%02x, "			 "vendor id %x%x (Infineon), "			 "product id %02x%02x"			 "%s\n",			 TPM_INF_ADDR,			 TPM_INF_BASE,			 version[0], version[1],			 vendorid[0], vendorid[1],			 productid[0], productid[1], chipname);		rc = tpm_register_hardware(&dev->dev, &tpm_inf);		if (rc < 0) {			rc = -ENODEV;			goto err_release_region;		}		return 0;	} else {		rc = -ENODEV;		goto err_release_region;	}err_release_region:	release_region(tpm_inf.base, TPM_INF_PORT_LEN);	release_region(TPM_INF_ADDR, TPM_INF_ADDR_LEN);err_last:	return rc;}static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev){	struct tpm_chip *chip = pnp_get_drvdata(dev);	if (chip) {		release_region(chip->vendor->base, TPM_INF_PORT_LEN);		tpm_remove_hardware(chip->dev);	}}static struct pnp_driver tpm_inf_pnp = {	.name = "tpm_inf_pnp",	.driver = {		.owner = THIS_MODULE,		.suspend = tpm_pm_suspend,		.resume = tpm_pm_resume,	},	.id_table = tpm_pnp_tbl,	.probe = tpm_inf_pnp_probe,	.remove = tpm_inf_pnp_remove,};static int __init init_inf(void){	return pnp_register_driver(&tpm_inf_pnp);}static void __exit cleanup_inf(void){	pnp_unregister_driver(&tpm_inf_pnp);}module_init(init_inf);module_exit(cleanup_inf);MODULE_AUTHOR("Marcel Selhorst <selhorst@crypto.rub.de>");MODULE_DESCRIPTION("Driver for Infineon TPM SLD 9630 TT 1.1 / SLB 9635 TT 1.2");MODULE_VERSION("1.7");MODULE_LICENSE("GPL");

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人av免费在线| 欧美亚洲禁片免费| 国产伦理精品不卡| 免费在线观看一区二区三区| 亚洲精品乱码久久久久久| 国产精品国产三级国产普通话三级| 91福利精品第一导航| 在线观看视频一区二区欧美日韩| 色综合久久久网| 精品视频免费在线| 欧美mv和日韩mv国产网站| 欧美不卡视频一区| 日本一区二区三区视频视频| 欧美国产精品专区| 日韩精品每日更新| 日韩电影一区二区三区四区| 亚洲一区二区3| 另类的小说在线视频另类成人小视频在线 | 国产日韩视频一区二区三区| 日韩一区二区精品在线观看| 精品成人免费观看| 午夜伊人狠狠久久| 国内精品不卡在线| 色av综合在线| 中文字幕免费不卡在线| 一区二区三区影院| 国内精品写真在线观看| 欧美在线free| 国产精品激情偷乱一区二区∴| 午夜精品影院在线观看| 盗摄精品av一区二区三区| 欧美日韩免费不卡视频一区二区三区| 日韩欧美精品三级| 国内精品在线播放| caoporm超碰国产精品| 3d成人动漫网站| 亚洲黄色尤物视频| 在线观看日韩一区| 国产精品九色蝌蚪自拍| 狠狠色丁香久久婷婷综合_中| www.99精品| 日本一区二区三区免费乱视频 | 亚洲影院免费观看| 91丝袜呻吟高潮美腿白嫩在线观看| 日韩欧美在线影院| 日本色综合中文字幕| 欧美日韩精品一区视频| 国产精品久久久久三级| 国产精品一区二区视频| 久久影视一区二区| 成人综合在线网站| 亚洲精品videosex极品| 91精品国产乱| 蜜桃av一区二区| 亚洲精品一区二区三区福利| 国产精品一品二品| 亚洲欧美另类小说| 911精品国产一区二区在线| 日本成人在线一区| 亚洲视频香蕉人妖| 国产一区二区三区在线观看免费| 日韩欧美你懂的| 91网上在线视频| 蜜桃视频第一区免费观看| 久久久精品免费观看| 一本一道波多野结衣一区二区| 肉丝袜脚交视频一区二区| 久久久夜色精品亚洲| 91久久免费观看| 东方欧美亚洲色图在线| 午夜av一区二区三区| 国产欧美一区二区三区在线老狼| 欧美视频精品在线| fc2成人免费人成在线观看播放| 日韩国产一区二| 亚洲理论在线观看| 国产精品美女久久久久久久久| 欧美一区二区精美| 在线观看一区不卡| 一本色道久久综合亚洲精品按摩| 国产永久精品大片wwwapp | 精品一区二区三区在线观看国产 | 91麻豆国产在线观看| 国产河南妇女毛片精品久久久| 午夜激情一区二区| 奇米影视7777精品一区二区| 午夜激情久久久| 日韩激情中文字幕| 精品一区二区三区欧美| 久久国产精品99久久久久久老狼| 捆绑调教一区二区三区| 青青草国产精品97视觉盛宴 | 色丁香久综合在线久综合在线观看 | 亚洲一区二区成人在线观看| 天天射综合影视| 免费人成在线不卡| 91丨九色丨蝌蚪丨老版| 久久综合九色综合欧美亚洲| 亚洲图片欧美色图| 色悠久久久久综合欧美99| 日本一区二区三区四区| 精品一区二区免费视频| 日韩一卡二卡三卡国产欧美| 亚洲国产另类精品专区| 欧美综合欧美视频| 亚洲地区一二三色| 欧美日韩和欧美的一区二区| 亚洲欧美日韩久久精品| 日本国产一区二区| 香港成人在线视频| 久久久久99精品国产片| 亚洲一区二区三区在线看| 欧洲av一区二区嗯嗯嗯啊| 亚洲制服丝袜av| 在线成人av网站| 国产在线精品不卡| 中文字幕乱码亚洲精品一区| 欧美伊人精品成人久久综合97| 成人精品国产一区二区4080 | 欧美一区二区三区四区高清| 国产精品色哟哟| 久久国产尿小便嘘嘘尿| 欧美高清视频一二三区| 亚洲一二三四在线| 色天天综合久久久久综合片| 国产精品丝袜久久久久久app| 经典三级在线一区| 8v天堂国产在线一区二区| 亚洲一二三四区| 欧美性猛交一区二区三区精品| 亚洲欧美一区二区三区久本道91| 成人综合婷婷国产精品久久| 日韩欧美国产1| 麻豆精品新av中文字幕| 91麻豆精品国产91久久久使用方法| 亚洲精品美国一| 欧美卡1卡2卡| 国产一区二区三区国产| 国产精品美女久久久久久久久久久| 成人h动漫精品| 一级日本不卡的影视| 欧美精品亚洲二区| 久久国产精品99久久人人澡| 国产日产欧美一区二区视频| 91免费在线视频观看| 亚洲成年人影院| 国产视频一区二区三区在线观看| 成人h动漫精品| 午夜精品福利一区二区三区av | 日韩美女视频19| 日韩一区二区中文字幕| 在线观看www91| 亚洲免费观看高清完整版在线| 91国偷自产一区二区使用方法| 欧美一区二区三区四区视频| 日韩国产一二三区| 欧美在线观看禁18| 一区二区激情视频| 91精品久久久久久久99蜜桃| 免费日本视频一区| 欧美国产激情一区二区三区蜜月| 国产另类ts人妖一区二区| 亚洲色图都市小说| www久久精品| 欧美tk—视频vk| 欧美精品免费视频| 成人sese在线| 成人黄色大片在线观看| 国内精品伊人久久久久av影院 | 精品一区二区在线免费观看| 亚洲一级二级三级| 一区二区三区日韩欧美| 亚洲人成网站色在线观看| 国产精品欧美久久久久一区二区| 日韩一区二区电影网| 欧美成人一区二区三区片免费 | 亚洲一区二区三区四区在线观看| 国产精品乱人伦| 最好看的中文字幕久久| 1区2区3区精品视频| 亚洲视频中文字幕| 亚洲色图在线播放| 亚洲综合精品久久| 日本不卡在线视频| 麻豆精品精品国产自在97香蕉| 蜜臀av性久久久久蜜臀av麻豆| 天天综合色天天| 国产一区二区三区在线观看免费| 国产精品自拍网站| 欧美自拍丝袜亚洲| 日韩美一区二区三区| 久久精品视频在线免费观看| 国产日韩一级二级三级| 一区二区三区成人在线视频| 视频一区在线播放| 成人av免费在线| 日韩一区二区三区在线| 国产欧美视频一区二区| 亚洲国产精品一区二区久久恐怖片| 亚洲第一久久影院|