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

📄 system-bus.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  PS3 system bus driver. * *  Copyright (C) 2006 Sony Computer Entertainment Inc. *  Copyright 2006 Sony Corp. * *  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. * *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. * *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include <linux/kernel.h>#include <linux/init.h>#include <linux/module.h>#include <linux/dma-mapping.h>#include <linux/err.h>#include <asm/udbg.h>#include <asm/lv1call.h>#include <asm/firmware.h>#include "platform.h"static struct device ps3_system_bus = {	.bus_id = "ps3_system",};/* FIXME: need device usage counters! */struct {	struct mutex mutex;	int sb_11; /* usb 0 */	int sb_12; /* usb 0 */	int gpu;} static usage_hack;static int ps3_is_device(struct ps3_system_bus_device *dev,			 unsigned int bus_id, unsigned int dev_id){	return dev->bus_id == bus_id && dev->dev_id == dev_id;}static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev){	int result;	BUG_ON(!dev->bus_id);	mutex_lock(&usage_hack.mutex);	if (ps3_is_device(dev, 1, 1)) {		usage_hack.sb_11++;		if (usage_hack.sb_11 > 1) {			result = 0;			goto done;		}	}	if (ps3_is_device(dev, 1, 2)) {		usage_hack.sb_12++;		if (usage_hack.sb_12 > 1) {			result = 0;			goto done;		}	}	result = lv1_open_device(dev->bus_id, dev->dev_id, 0);	if (result) {		pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,			__LINE__, ps3_result(result));			result = -EPERM;	}done:	mutex_unlock(&usage_hack.mutex);	return result;}static int ps3_close_hv_device_sb(struct ps3_system_bus_device *dev){	int result;	BUG_ON(!dev->bus_id);	mutex_lock(&usage_hack.mutex);	if (ps3_is_device(dev, 1, 1)) {		usage_hack.sb_11--;		if (usage_hack.sb_11) {			result = 0;			goto done;		}	}	if (ps3_is_device(dev, 1, 2)) {		usage_hack.sb_12--;		if (usage_hack.sb_12) {			result = 0;			goto done;		}	}	result = lv1_close_device(dev->bus_id, dev->dev_id);	BUG_ON(result);done:	mutex_unlock(&usage_hack.mutex);	return result;}static int ps3_open_hv_device_gpu(struct ps3_system_bus_device *dev){	int result;	mutex_lock(&usage_hack.mutex);	usage_hack.gpu++;	if (usage_hack.gpu > 1) {		result = 0;		goto done;	}	result = lv1_gpu_open(0);	if (result) {		pr_debug("%s:%d: lv1_gpu_open failed: %s\n", __func__,			__LINE__, ps3_result(result));			result = -EPERM;	}done:	mutex_unlock(&usage_hack.mutex);	return result;}static int ps3_close_hv_device_gpu(struct ps3_system_bus_device *dev){	int result;	mutex_lock(&usage_hack.mutex);	usage_hack.gpu--;	if (usage_hack.gpu) {		result = 0;		goto done;	}	result = lv1_gpu_close();	BUG_ON(result);done:	mutex_unlock(&usage_hack.mutex);	return result;}int ps3_open_hv_device(struct ps3_system_bus_device *dev){	BUG_ON(!dev);	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);	switch (dev->match_id) {	case PS3_MATCH_ID_EHCI:	case PS3_MATCH_ID_OHCI:	case PS3_MATCH_ID_GELIC:	case PS3_MATCH_ID_STOR_DISK:	case PS3_MATCH_ID_STOR_ROM:	case PS3_MATCH_ID_STOR_FLASH:		return ps3_open_hv_device_sb(dev);	case PS3_MATCH_ID_SOUND:	case PS3_MATCH_ID_GRAPHICS:		return ps3_open_hv_device_gpu(dev);	case PS3_MATCH_ID_AV_SETTINGS:	case PS3_MATCH_ID_SYSTEM_MANAGER:		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,			__LINE__, dev->match_id);		pr_debug("%s:%d: bus_id: %u\n", __func__,			__LINE__, dev->bus_id);		BUG();		return -EINVAL;	default:		break;	}	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,		dev->match_id);	BUG();	return -ENODEV;}EXPORT_SYMBOL_GPL(ps3_open_hv_device);int ps3_close_hv_device(struct ps3_system_bus_device *dev){	BUG_ON(!dev);	pr_debug("%s:%d: match_id: %u\n", __func__, __LINE__, dev->match_id);	switch (dev->match_id) {	case PS3_MATCH_ID_EHCI:	case PS3_MATCH_ID_OHCI:	case PS3_MATCH_ID_GELIC:	case PS3_MATCH_ID_STOR_DISK:	case PS3_MATCH_ID_STOR_ROM:	case PS3_MATCH_ID_STOR_FLASH:		return ps3_close_hv_device_sb(dev);	case PS3_MATCH_ID_SOUND:	case PS3_MATCH_ID_GRAPHICS:		return ps3_close_hv_device_gpu(dev);	case PS3_MATCH_ID_AV_SETTINGS:	case PS3_MATCH_ID_SYSTEM_MANAGER:		pr_debug("%s:%d: unsupported match_id: %u\n", __func__,			__LINE__, dev->match_id);		pr_debug("%s:%d: bus_id: %u\n", __func__,			__LINE__, dev->bus_id);		BUG();		return -EINVAL;	default:		break;	}	pr_debug("%s:%d: unknown match_id: %u\n", __func__, __LINE__,		dev->match_id);	BUG();	return -ENODEV;}EXPORT_SYMBOL_GPL(ps3_close_hv_device);#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)static void _dump_mmio_region(const struct ps3_mmio_region* r,	const char* func, int line){	pr_debug("%s:%d: dev       %u:%u\n", func, line, r->dev->bus_id,		r->dev->dev_id);	pr_debug("%s:%d: bus_addr  %lxh\n", func, line, r->bus_addr);	pr_debug("%s:%d: len       %lxh\n", func, line, r->len);	pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);}static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r){	int result;	result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,		r->bus_addr, r->len, r->page_size, &r->lpar_addr);	if (result) {		pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",			__func__, __LINE__, ps3_result(result));		r->lpar_addr = 0;	}	dump_mmio_region(r);	return result;}static int ps3_ioc0_mmio_region_create(struct ps3_mmio_region *r){	/* device specific; do nothing currently */	return 0;}int ps3_mmio_region_create(struct ps3_mmio_region *r){	return r->mmio_ops->create(r);}EXPORT_SYMBOL_GPL(ps3_mmio_region_create);static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r){	int result;	dump_mmio_region(r);;	result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,		r->lpar_addr);	if (result)		pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",			__func__, __LINE__, ps3_result(result));	r->lpar_addr = 0;	return result;}static int ps3_ioc0_free_mmio_region(struct ps3_mmio_region *r){	/* device specific; do nothing currently */	return 0;}int ps3_free_mmio_region(struct ps3_mmio_region *r){	return r->mmio_ops->free(r);}EXPORT_SYMBOL_GPL(ps3_free_mmio_region);static const struct ps3_mmio_region_ops ps3_mmio_sb_region_ops = {	.create = ps3_sb_mmio_region_create,	.free = ps3_sb_free_mmio_region};static const struct ps3_mmio_region_ops ps3_mmio_ioc0_region_ops = {	.create = ps3_ioc0_mmio_region_create,	.free = ps3_ioc0_free_mmio_region};int ps3_mmio_region_init(struct ps3_system_bus_device *dev,	struct ps3_mmio_region *r, unsigned long bus_addr, unsigned long len,	enum ps3_mmio_page_size page_size){	r->dev = dev;	r->bus_addr = bus_addr;	r->len = len;	r->page_size = page_size;	switch (dev->dev_type) {	case PS3_DEVICE_TYPE_SB:		r->mmio_ops = &ps3_mmio_sb_region_ops;		break;	case PS3_DEVICE_TYPE_IOC0:		r->mmio_ops = &ps3_mmio_ioc0_region_ops;		break;	default:		BUG();		return -EINVAL;	}	return 0;}EXPORT_SYMBOL_GPL(ps3_mmio_region_init);static int ps3_system_bus_match(struct device *_dev,	struct device_driver *_drv){	int result;	struct ps3_system_bus_driver *drv = ps3_drv_to_system_bus_drv(_drv);	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);	result = dev->match_id == drv->match_id;	pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__,		dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name,		(result ? "match" : "miss"));	return result;}static int ps3_system_bus_probe(struct device *_dev){	int result = 0;	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);	struct ps3_system_bus_driver *drv;	BUG_ON(!dev);	pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);	drv = ps3_system_bus_dev_to_system_bus_drv(dev);	BUG_ON(!drv);	if (drv->probe)		result = drv->probe(dev);	else		pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,			dev->core.bus_id);	pr_info(" <- %s:%d: %s\n", __func__, __LINE__, dev->core.bus_id);	return result;}static int ps3_system_bus_remove(struct device *_dev){	int result = 0;	struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);	struct ps3_system_bus_driver *drv;	BUG_ON(!dev);	pr_info(" -> %s:%d: %s\n", __func__, __LINE__, _dev->bus_id);	drv = ps3_system_bus_dev_to_system_bus_drv(dev);	BUG_ON(!drv);

⌨️ 快捷键说明

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