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

📄 device-init.c

📁 linux内核源码
💻 C
📖 第 1 页 / 共 2 页
字号:
}static int ps3_setup_storage_dev(const struct ps3_repository_device *repo,				 enum ps3_match_id match_id){	int result;	struct ps3_storage_device *p;	u64 port, blk_size, num_blocks;	unsigned int num_regions, i;	pr_debug(" -> %s:%u: match_id %u\n", __func__, __LINE__, match_id);	result = ps3_repository_read_stor_dev_info(repo->bus_index,						   repo->dev_index, &port,						   &blk_size, &num_blocks,						   &num_regions);	if (result) {		printk(KERN_ERR "%s:%u: _read_stor_dev_info failed %d\n",		       __func__, __LINE__, result);		return -ENODEV;	}	pr_debug("%s:%u: (%u:%u:%u): port %lu blk_size %lu num_blocks %lu "		 "num_regions %u\n", __func__, __LINE__, repo->bus_index,		 repo->dev_index, repo->dev_type, port, blk_size, num_blocks,		 num_regions);	p = kzalloc(sizeof(struct ps3_storage_device) +		    num_regions * sizeof(struct ps3_storage_region),		    GFP_KERNEL);	if (!p) {		result = -ENOMEM;		goto fail_malloc;	}	p->sbd.match_id = match_id;	p->sbd.dev_type = PS3_DEVICE_TYPE_SB;	p->sbd.bus_id = repo->bus_id;	p->sbd.dev_id = repo->dev_id;	p->sbd.d_region = &p->dma_region;	p->blk_size = blk_size;	p->num_regions = num_regions;	result = ps3_repository_find_interrupt(repo,					       PS3_INTERRUPT_TYPE_EVENT_PORT,					       &p->sbd.interrupt_id);	if (result) {		printk(KERN_ERR "%s:%u: find_interrupt failed %d\n", __func__,		       __LINE__, result);		result = -ENODEV;		goto fail_find_interrupt;	}	/* FIXME: Arrange to only do this on a 'cold' boot */	result = ps3_storage_wait_for_device(repo);	if (result) {		printk(KERN_ERR "%s:%u: storage_notification failed %d\n",		       __func__, __LINE__, result);		result = -ENODEV;		goto fail_probe_notification;	}	for (i = 0; i < num_regions; i++) {		unsigned int id;		u64 start, size;		result = ps3_repository_read_stor_dev_region(repo->bus_index,							     repo->dev_index,							     i, &id, &start,							     &size);		if (result) {			printk(KERN_ERR			       "%s:%u: read_stor_dev_region failed %d\n",			       __func__, __LINE__, result);			result = -ENODEV;			goto fail_read_region;		}		pr_debug("%s:%u: region %u: id %u start %lu size %lu\n",			 __func__, __LINE__, i, id, start, size);		p->regions[i].id = id;		p->regions[i].start = start;		p->regions[i].size = size;	}	result = ps3_system_bus_device_register(&p->sbd);	if (result) {		pr_debug("%s:%u ps3_system_bus_device_register failed\n",			 __func__, __LINE__);		goto fail_device_register;	}	pr_debug(" <- %s:%u\n", __func__, __LINE__);	return 0;fail_device_register:fail_read_region:fail_probe_notification:fail_find_interrupt:	kfree(p);fail_malloc:	pr_debug(" <- %s:%u: fail.\n", __func__, __LINE__);	return result;}static int __init ps3_register_vuart_devices(void){	int result;	unsigned int port_number;	pr_debug(" -> %s:%d\n", __func__, __LINE__);	result = ps3_repository_read_vuart_av_port(&port_number);	if (result)		port_number = 0; /* av default */	result = ps3_setup_vuart_device(PS3_MATCH_ID_AV_SETTINGS, port_number);	WARN_ON(result);	result = ps3_repository_read_vuart_sysmgr_port(&port_number);	if (result)		port_number = 2; /* sysmgr default */	result = ps3_setup_vuart_device(PS3_MATCH_ID_SYSTEM_MANAGER,		port_number);	WARN_ON(result);	pr_debug(" <- %s:%d\n", __func__, __LINE__);	return result;}static int __init ps3_register_sound_devices(void){	int result;	struct layout {		struct ps3_system_bus_device dev;		struct ps3_dma_region d_region;		struct ps3_mmio_region m_region;	} *p;	pr_debug(" -> %s:%d\n", __func__, __LINE__);	p = kzalloc(sizeof(*p), GFP_KERNEL);	if (!p)		return -ENOMEM;	p->dev.match_id = PS3_MATCH_ID_SOUND;	p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;	p->dev.d_region = &p->d_region;	p->dev.m_region = &p->m_region;	result = ps3_system_bus_device_register(&p->dev);	if (result)		pr_debug("%s:%d ps3_system_bus_device_register failed\n",			__func__, __LINE__);	pr_debug(" <- %s:%d\n", __func__, __LINE__);	return result;}static int __init ps3_register_graphics_devices(void){	int result;	struct layout {		struct ps3_system_bus_device dev;	} *p;	pr_debug(" -> %s:%d\n", __func__, __LINE__);	p = kzalloc(sizeof(struct layout), GFP_KERNEL);	if (!p)		return -ENOMEM;	p->dev.match_id = PS3_MATCH_ID_GRAPHICS;	p->dev.dev_type = PS3_DEVICE_TYPE_IOC0;	result = ps3_system_bus_device_register(&p->dev);	if (result)		pr_debug("%s:%d ps3_system_bus_device_register failed\n",			__func__, __LINE__);	pr_debug(" <- %s:%d\n", __func__, __LINE__);	return result;}/** * ps3_register_repository_device - Register a device from the repositiory info. * */static int ps3_register_repository_device(	const struct ps3_repository_device *repo){	int result;	switch (repo->dev_type) {	case PS3_DEV_TYPE_SB_GELIC:		result = ps3_setup_gelic_device(repo);		if (result) {			pr_debug("%s:%d ps3_setup_gelic_device failed\n",				__func__, __LINE__);		}		break;	case PS3_DEV_TYPE_SB_USB:		/* Each USB device has both an EHCI and an OHCI HC */		result = ps3_setup_ehci_device(repo);		if (result) {			pr_debug("%s:%d ps3_setup_ehci_device failed\n",				__func__, __LINE__);		}		result = ps3_setup_ohci_device(repo);		if (result) {			pr_debug("%s:%d ps3_setup_ohci_device failed\n",				__func__, __LINE__);		}		break;	case PS3_DEV_TYPE_STOR_DISK:		result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_DISK);		/* Some devices are not accessable from the Other OS lpar. */		if (result == -ENODEV) {			result = 0;			pr_debug("%s:%u: not accessable\n", __func__,				 __LINE__);		}		if (result)			pr_debug("%s:%u ps3_setup_storage_dev failed\n",				 __func__, __LINE__);		break;	case PS3_DEV_TYPE_STOR_ROM:		result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_ROM);		if (result)			pr_debug("%s:%u ps3_setup_storage_dev failed\n",				 __func__, __LINE__);		break;	case PS3_DEV_TYPE_STOR_FLASH:		result = ps3_setup_storage_dev(repo, PS3_MATCH_ID_STOR_FLASH);		if (result)			pr_debug("%s:%u ps3_setup_storage_dev failed\n",				 __func__, __LINE__);		break;	default:		result = 0;		pr_debug("%s:%u: unsupported dev_type %u\n", __func__, __LINE__,			repo->dev_type);	}	return result;}/** * ps3_probe_thread - Background repository probing at system startup. * * This implementation only supports background probing on a single bus. */static int ps3_probe_thread(void *data){	struct ps3_repository_device *repo = data;	int result;	unsigned int ms = 250;	pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);	do {		try_to_freeze();		pr_debug("%s:%u: probing...\n", __func__, __LINE__);		do {			result = ps3_repository_find_device(repo);			if (result == -ENODEV)				pr_debug("%s:%u: nothing new\n", __func__,					__LINE__);			else if (result)				pr_debug("%s:%u: find device error.\n",					__func__, __LINE__);			else {				pr_debug("%s:%u: found device (%u:%u:%u)\n",					 __func__, __LINE__, repo->bus_index,					 repo->dev_index, repo->dev_type);				ps3_register_repository_device(repo);				ps3_repository_bump_device(repo);				ms = 250;			}		} while (!result);		pr_debug("%s:%u: ms %u\n", __func__, __LINE__, ms);		if ( ms > 60000)			break;		msleep_interruptible(ms);		/* An exponential backoff. */		ms <<= 1;	} while (!kthread_should_stop());	pr_debug(" <- %s:%u: kthread finished\n", __func__, __LINE__);	return 0;}/** * ps3_start_probe_thread - Starts the background probe thread. * */static int __init ps3_start_probe_thread(enum ps3_bus_type bus_type){	int result;	struct task_struct *task;	static struct ps3_repository_device repo; /* must be static */	pr_debug(" -> %s:%d\n", __func__, __LINE__);	memset(&repo, 0, sizeof(repo));	repo.bus_type = bus_type;	result = ps3_repository_find_bus(repo.bus_type, 0, &repo.bus_index);	if (result) {		printk(KERN_ERR "%s: Cannot find bus (%d)\n", __func__, result);		return -ENODEV;	}	result = ps3_repository_read_bus_id(repo.bus_index, &repo.bus_id);	if (result) {		printk(KERN_ERR "%s: read_bus_id failed %d\n", __func__,			result);		return -ENODEV;	}	task = kthread_run(ps3_probe_thread, &repo, "ps3-probe-%u", bus_type);	if (IS_ERR(task)) {		result = PTR_ERR(task);		printk(KERN_ERR "%s: kthread_run failed %d\n", __func__,		       result);		return result;	}	pr_debug(" <- %s:%d\n", __func__, __LINE__);	return 0;}/** * ps3_register_devices - Probe the system and register devices found. * * A device_initcall() routine. */static int __init ps3_register_devices(void){	int result;	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))		return -ENODEV;	pr_debug(" -> %s:%d\n", __func__, __LINE__);	/* ps3_repository_dump_bus_info(); */	result = ps3_start_probe_thread(PS3_BUS_TYPE_STORAGE);	ps3_register_vuart_devices();	ps3_register_graphics_devices();	ps3_repository_find_devices(PS3_BUS_TYPE_SB,		ps3_register_repository_device);	ps3_register_sound_devices();	pr_debug(" <- %s:%d\n", __func__, __LINE__);	return 0;}device_initcall(ps3_register_devices);

⌨️ 快捷键说明

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