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

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

?? portdrv_core.c

?? 底層驅動開發
?? C
字號:
/* * File:	portdrv_core.c * Purpose:	PCI Express Port Bus Driver's Core Functions * * Copyright (C) 2004 Intel * Copyright (C) Tom Long Nguyen (tom.l.nguyen@intel.com) */#include <linux/module.h>#include <linux/pci.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/pm.h>#include <linux/pcieport_if.h>#include "portdrv.h"extern int pcie_mch_quirk;	/* MSI-quirk Indicator */static int pcie_port_probe_service(struct device *dev){	struct pcie_device *pciedev;	struct pcie_port_service_driver *driver;	int status = -ENODEV;	if (!dev || !dev->driver)		return status; 	driver = to_service_driver(dev->driver);	if (!driver || !driver->probe)		return status;	pciedev = to_pcie_device(dev);	status = driver->probe(pciedev, driver->id_table);	if (!status) {		printk(KERN_DEBUG "Load service driver %s on pcie device %s\n",			driver->name, dev->bus_id);		get_device(dev);	}	return status;}static int pcie_port_remove_service(struct device *dev){	struct pcie_device *pciedev;	struct pcie_port_service_driver *driver;	if (!dev || !dev->driver)		return 0;	pciedev = to_pcie_device(dev); 	driver = to_service_driver(dev->driver);	if (driver && driver->remove) { 		printk(KERN_DEBUG "Unload service driver %s on pcie device %s\n",			driver->name, dev->bus_id);		driver->remove(pciedev);		put_device(dev);	}	return 0;}static void pcie_port_shutdown_service(struct device *dev) {}static int pcie_port_suspend_service(struct device *dev, pm_message_t state, u32 level){	struct pcie_device *pciedev;	struct pcie_port_service_driver *driver;	if (!dev || !dev->driver)		return 0;	pciedev = to_pcie_device(dev); 	driver = to_service_driver(dev->driver);	if (driver && driver->suspend)		driver->suspend(pciedev, state);	return 0;}static int pcie_port_resume_service(struct device *dev, u32 level){	struct pcie_device *pciedev;	struct pcie_port_service_driver *driver;	if (!dev || !dev->driver)		return 0;	pciedev = to_pcie_device(dev); 	driver = to_service_driver(dev->driver);	if (driver && driver->resume)		driver->resume(pciedev);	return 0;}/* * release_pcie_device *	 *	Being invoked automatically when device is being removed  *	in response to device_unregister(dev) call. *	Release all resources being claimed. */static void release_pcie_device(struct device *dev){	printk(KERN_DEBUG "Free Port Service[%s]\n", dev->bus_id);	kfree(to_pcie_device(dev));			}static int is_msi_quirked(struct pci_dev *dev){	int port_type, quirk = 0;	u16 reg16;	pci_read_config_word(dev, 		pci_find_capability(dev, PCI_CAP_ID_EXP) + 		PCIE_CAPABILITIES_REG, &reg16);	port_type = (reg16 >> 4) & PORT_TYPE_MASK;	switch(port_type) {	case PCIE_RC_PORT:		if (pcie_mch_quirk == 1)			quirk = 1;		break;	case PCIE_SW_UPSTREAM_PORT:	case PCIE_SW_DOWNSTREAM_PORT:	default:		break;		}	return quirk;}	static int assign_interrupt_mode(struct pci_dev *dev, int *vectors, int mask){	int i, pos, nvec, status = -EINVAL;	int interrupt_mode = PCIE_PORT_INTx_MODE;	/* Set INTx as default */	for (i = 0, nvec = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {		if (mask & (1 << i)) 			nvec++;		vectors[i] = dev->irq;	}		/* Check MSI quirk */	if (is_msi_quirked(dev))		return interrupt_mode;	/* Select MSI-X over MSI if supported */			pos = pci_find_capability(dev, PCI_CAP_ID_MSIX);	if (pos) {		struct msix_entry msix_entries[PCIE_PORT_DEVICE_MAXSERVICES] = 			{{0, 0}, {0, 1}, {0, 2}, {0, 3}};		printk("%s Found MSIX capability\n", __FUNCTION__);		status = pci_enable_msix(dev, msix_entries, nvec);		if (!status) {			int j = 0;			interrupt_mode = PCIE_PORT_MSIX_MODE;			for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {				if (mask & (1 << i)) 					vectors[i] = msix_entries[j++].vector;			}		}	} 	if (status) {		pos = pci_find_capability(dev, PCI_CAP_ID_MSI);		if (pos) {			printk("%s Found MSI capability\n", __FUNCTION__);			status = pci_enable_msi(dev);			if (!status) {				interrupt_mode = PCIE_PORT_MSI_MODE;				for (i = 0;i < PCIE_PORT_DEVICE_MAXSERVICES;i++)					vectors[i] = dev->irq;			}		}	} 	return interrupt_mode;}static int get_port_device_capability(struct pci_dev *dev){	int services = 0, pos;	u16 reg16;	u32 reg32;	pos = pci_find_capability(dev, PCI_CAP_ID_EXP);	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg16);	/* Hot-Plug Capable */	if (reg16 & PORT_TO_SLOT_MASK) {		pci_read_config_dword(dev, 			pos + PCIE_SLOT_CAPABILITIES_REG, &reg32);		if (reg32 & SLOT_HP_CAPABLE_MASK)			services |= PCIE_PORT_SERVICE_HP;	} 	/* PME Capable */	pos = pci_find_capability(dev, PCI_CAP_ID_PME);	if (pos) 		services |= PCIE_PORT_SERVICE_PME;		pos = PCI_CFG_SPACE_SIZE;	while (pos) {		pci_read_config_dword(dev, pos, &reg32);		switch (reg32 & 0xffff) {		case PCI_EXT_CAP_ID_ERR:			services |= PCIE_PORT_SERVICE_AER;			pos = reg32 >> 20;			break;		case PCI_EXT_CAP_ID_VC:			services |= PCIE_PORT_SERVICE_VC;			pos = reg32 >> 20;			break;		default:			pos = 0;			break;		}	}	return services;}static void pcie_device_init(struct pci_dev *parent, struct pcie_device *dev, 	int port_type, int service_type, int irq, int irq_mode){	struct device *device;	dev->port = parent;	dev->interrupt_mode = irq_mode;	dev->irq = irq;	dev->id.vendor = parent->vendor;	dev->id.device = parent->device;	dev->id.port_type = port_type;	dev->id.service_type = (1 << service_type);	/* Initialize generic device interface */	device = &dev->device;	memset(device, 0, sizeof(struct device));	device->bus = &pcie_port_bus_type;	device->driver = NULL;	device->driver_data = NULL;	device->release = release_pcie_device;	/* callback to free pcie dev */	sprintf(&device->bus_id[0], "pcie%02x",		get_descriptor_id(port_type, service_type));	device->parent = &parent->dev;}static struct pcie_device* alloc_pcie_device(struct pci_dev *parent,	int port_type, int service_type, int irq, int irq_mode){	struct pcie_device *device;	device = kmalloc(sizeof(struct pcie_device), GFP_KERNEL);	if (!device)		return NULL;	memset(device, 0, sizeof(struct pcie_device));	pcie_device_init(parent, device, port_type, service_type, irq,irq_mode);	printk(KERN_DEBUG "Allocate Port Service[%s]\n", device->device.bus_id);	return device;}int pcie_port_device_probe(struct pci_dev *dev){	int pos, type;	u16 reg;	if (!(pos = pci_find_capability(dev, PCI_CAP_ID_EXP)))		return -ENODEV;	pci_read_config_word(dev, pos + PCIE_CAPABILITIES_REG, &reg);	type = (reg >> 4) & PORT_TYPE_MASK;	if (	type == PCIE_RC_PORT || type == PCIE_SW_UPSTREAM_PORT ||		type == PCIE_SW_DOWNSTREAM_PORT )		return 0;	return -ENODEV;}int pcie_port_device_register(struct pci_dev *dev){	struct pcie_port_device_ext *p_ext;	int status, type, capabilities, irq_mode, i;	int vectors[PCIE_PORT_DEVICE_MAXSERVICES];	u16 reg16;	/* Allocate port device extension */	if (!(p_ext = kmalloc(sizeof(struct pcie_port_device_ext), GFP_KERNEL)))		return -ENOMEM;	pci_set_drvdata(dev, p_ext);	/* Get port type */	pci_read_config_word(dev,		pci_find_capability(dev, PCI_CAP_ID_EXP) +		PCIE_CAPABILITIES_REG, &reg16);	type = (reg16 >> 4) & PORT_TYPE_MASK;	/* Now get port services */	capabilities = get_port_device_capability(dev);	irq_mode = assign_interrupt_mode(dev, vectors, capabilities);	p_ext->interrupt_mode = irq_mode;	/* Allocate child services if any */	for (i = 0; i < PCIE_PORT_DEVICE_MAXSERVICES; i++) {		struct pcie_device *child;		if (capabilities & (1 << i)) {			child = alloc_pcie_device(				dev, 		/* parent */				type,		/* port type */				i,		/* service type */				vectors[i],	/* irq */				irq_mode	/* interrupt mode */);			if (child) {				status = device_register(&child->device);				if (status) {					kfree(child);					continue;				}				get_device(&child->device);			}		}	}	return 0;}#ifdef CONFIG_PMstatic int suspend_iter(struct device *dev, void *data){	struct pcie_port_service_driver *service_driver;	pm_message_t state = * (pm_message_t *) data; 	if ((dev->bus == &pcie_port_bus_type) && 	    (dev->driver)) { 		service_driver = to_service_driver(dev->driver); 		if (service_driver->suspend) 			service_driver->suspend(to_pcie_device(dev), state);  	}	return 0;}int pcie_port_device_suspend(struct pci_dev *dev, pm_message_t state){	device_for_each_child(&dev->dev, &state, suspend_iter);	return 0;}static int resume_iter(struct device *dev, void *data){	struct pcie_port_service_driver *service_driver;	if ((dev->bus == &pcie_port_bus_type) &&	    (dev->driver)) {		service_driver = to_service_driver(dev->driver);		if (service_driver->resume)			service_driver->resume(to_pcie_device(dev));	}	return 0;}int pcie_port_device_resume(struct pci_dev *dev){	device_for_each_child(&dev->dev, NULL, resume_iter);	return 0;}#endifstatic int remove_iter(struct device *dev, void *data){	struct pcie_port_service_driver *service_driver;	if (dev->bus == &pcie_port_bus_type) {		if (dev->driver) {			service_driver = to_service_driver(dev->driver);			if (service_driver->remove)				service_driver->remove(to_pcie_device(dev));		}		*(unsigned long*)data = (unsigned long)dev;		return 1;	}	return 0;}void pcie_port_device_remove(struct pci_dev *dev){	struct device *device;	unsigned long device_addr;	int interrupt_mode = PCIE_PORT_INTx_MODE;	int status;	do {		status = device_for_each_child(&dev->dev, &device_addr, remove_iter);		if (status) {			device = (struct device*)device_addr;			interrupt_mode = (to_pcie_device(device))->interrupt_mode;			put_device(device);			device_unregister(device);		}	} while (status);	/* Switch to INTx by default if MSI enabled */	if (interrupt_mode == PCIE_PORT_MSIX_MODE)		pci_disable_msix(dev);	else if (interrupt_mode == PCIE_PORT_MSI_MODE)		pci_disable_msi(dev);}void pcie_port_bus_register(void){	bus_register(&pcie_port_bus_type);}void pcie_port_bus_unregister(void){	bus_unregister(&pcie_port_bus_type);}int pcie_port_service_register(struct pcie_port_service_driver *new){	new->driver.name = (char *)new->name;	new->driver.bus = &pcie_port_bus_type;	new->driver.probe = pcie_port_probe_service;	new->driver.remove = pcie_port_remove_service;	new->driver.shutdown = pcie_port_shutdown_service;	new->driver.suspend = pcie_port_suspend_service;	new->driver.resume = pcie_port_resume_service;	return driver_register(&new->driver);}void pcie_port_service_unregister(struct pcie_port_service_driver *new){	driver_unregister(&new->driver);}EXPORT_SYMBOL(pcie_port_service_register);EXPORT_SYMBOL(pcie_port_service_unregister);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
caoporen国产精品视频| 亚洲a一区二区| 99免费精品视频| 中文字幕中文字幕中文字幕亚洲无线| 成人黄色777网| 亚洲美女精品一区| 欧美精品日韩一区| 久草中文综合在线| 中文无字幕一区二区三区| 99久久综合狠狠综合久久| 亚洲精选一二三| 91精品国产色综合久久ai换脸| 国产一区二三区| 亚洲天堂精品在线观看| 欧美日韩午夜在线视频| 精品一区二区国语对白| 国产精品不卡一区二区三区| 欧美视频一区在线| 韩国女主播一区| 1区2区3区国产精品| 欧美日本高清视频在线观看| 国产精品1区2区| 一区二区视频在线看| 欧美成人三级电影在线| 91麻豆6部合集magnet| 日韩国产精品久久| 亚洲欧洲精品一区二区精品久久久 | 欧美日韩国产大片| 精品一区二区精品| 亚洲午夜羞羞片| 国产婷婷色一区二区三区| 在线视频欧美区| 国内成+人亚洲+欧美+综合在线| 日韩理论片在线| 久久综合九色综合欧美亚洲| 91久久精品国产91性色tv | 性做久久久久久久免费看| 久久久91精品国产一区二区精品| 欧美日韩色综合| 成人黄色一级视频| 久久99精品一区二区三区 | 一色桃子久久精品亚洲| 欧美一区二区久久| 欧美制服丝袜第一页| 国产精品主播直播| 日产国产高清一区二区三区 | 亚洲第一电影网| 国产精品美日韩| 精品福利av导航| 欧美日韩免费视频| 成人免费va视频| 国产大陆精品国产| 九九久久精品视频| 日韩av一级电影| 亚洲va在线va天堂| 一区二区在线看| 国产精品久久久久久久久果冻传媒| 精品久久久久一区二区国产| 91精品国产综合久久久蜜臀粉嫩 | 国产精品乱子久久久久| 欧美va亚洲va香蕉在线| 5566中文字幕一区二区电影| 在线影院国内精品| 91一区二区在线观看| 东方aⅴ免费观看久久av| 极品美女销魂一区二区三区免费| 午夜精品免费在线| 午夜精品福利在线| 视频一区二区中文字幕| 一区二区高清在线| 亚洲第一激情av| 视频在线观看一区| 日韩va亚洲va欧美va久久| 三级不卡在线观看| 麻豆精品在线播放| 久久精品国产免费| 国内精品久久久久影院薰衣草| 久久99这里只有精品| 久久av中文字幕片| 国产999精品久久久久久绿帽| 国产suv精品一区二区三区| 国产真实乱子伦精品视频| 国产一区二区在线视频| 国产成人精品aa毛片| 成人美女在线视频| 在线精品视频免费播放| 欧美日韩在线播放| 欧美日韩一区视频| 欧美一级欧美三级在线观看| 日韩视频一区二区三区在线播放| 欧美精品一区二区三区在线播放| 久久奇米777| 国产精品久久久久久久久动漫| 亚洲女子a中天字幕| 香港成人在线视频| 久久精品国产亚洲5555| 成人激情动漫在线观看| 在线观看视频一区二区欧美日韩| 欧美高清视频一二三区 | 91视频国产资源| 欧美日韩国产首页在线观看| 日韩视频在线一区二区| 中文字幕第一区| 亚洲国产裸拍裸体视频在线观看乱了| 日韩av网站在线观看| 国产一区二区三区免费看| 91在线国产观看| 欧美精品九九99久久| 国产亚洲婷婷免费| 亚洲午夜影视影院在线观看| 老司机午夜精品| 91丨九色丨尤物| 日韩一区二区在线观看| 国产精品久久久久四虎| 婷婷国产在线综合| 成人免费毛片片v| 91 com成人网| 国产精品久久久久久久裸模| 无码av中文一区二区三区桃花岛| 国产1区2区3区精品美女| 欧美偷拍一区二区| 国产欧美日韩麻豆91| 日韩成人免费看| 99国产精品国产精品久久| 日韩一区二区免费视频| 亚洲欧洲www| 国产一区二区视频在线| 在线观看91视频| 国产精品婷婷午夜在线观看| 男人的j进女人的j一区| 色视频一区二区| 中文字幕不卡在线| 久久精品国产网站| 欧美日韩一级二级三级| 国产精品久久久久一区二区三区 | 26uuu久久综合| 亚洲电影在线播放| 99免费精品在线| 国产日产欧美精品一区二区三区| 日韩电影在线免费看| 一本一道波多野结衣一区二区| 久久亚洲精华国产精华液| 日本亚洲免费观看| 色婷婷一区二区| 国产精品久久久久久久久动漫 | 香蕉av福利精品导航| 一本到一区二区三区| 国产精品久久久久7777按摩| 国产专区综合网| 日韩欧美美女一区二区三区| 亚洲超碰精品一区二区| 在线影院国内精品| 亚洲综合久久久| 日本韩国精品在线| 亚洲免费观看高清完整版在线观看| 国产99久久久国产精品潘金| 久久久久久久久久久久久女国产乱 | 亚洲欧洲国产日本综合| 成人激情小说网站| 日本一区二区视频在线| 大尺度一区二区| 国产视频一区二区在线观看| 国产专区综合网| 精品电影一区二区| 国产在线精品视频| 久久久高清一区二区三区| 国内精品自线一区二区三区视频| 久久综合久久综合亚洲| 国产酒店精品激情| 国产日韩欧美不卡在线| 高清shemale亚洲人妖| 国产欧美一区二区精品性| 国产成人一区在线| 最新久久zyz资源站| 色88888久久久久久影院按摩| 亚洲激情图片小说视频| 欧美日韩你懂得| 久久99热这里只有精品| 国产欧美中文在线| 99国产精品99久久久久久| 夜夜精品视频一区二区 | 欧美体内she精高潮| 日韩国产欧美在线视频| 欧美大黄免费观看| 91精品婷婷国产综合久久性色| 91福利在线看| 亚洲一区二区四区蜜桃| 欧美情侣在线播放| 美女被吸乳得到大胸91| 国产亚洲欧美一级| 99久久久精品免费观看国产蜜| 一区二区在线看| 7777精品伊人久久久大香线蕉完整版 | 成人免费av资源| 亚洲国产精品精华液网站| 日韩欧美区一区二| 成人国产精品免费观看视频| 亚洲国产精品一区二区久久恐怖片| 日韩一级高清毛片| 成人国产亚洲欧美成人综合网 |