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

📄 ps3-sys-manager.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
}/** * ps3_sys_manager_send_response - Send a 'response' to the system manager. * @status: zero = success, others fail. * * The guest sends this message to the system manager to acnowledge success or * failure of a command sent by the system manager. */static int ps3_sys_manager_send_response(struct ps3_system_bus_device *dev,	u64 status){	struct ps3_sys_manager_header header;	struct {		u8 version;		u8 reserved_1[3];		u8 status;		u8 reserved_2[11];	} payload;	BUILD_BUG_ON(sizeof(payload) != 16);	dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__,		(status ? "nak" : "ack"));	memset(&header, 0, sizeof(header));	header.version = 1;	header.size = 16;	header.payload_size = 16;	header.service_id = PS3_SM_SERVICE_ID_RESPONSE;	memset(&payload, 0, sizeof(payload));	payload.version = 1;	payload.status = status;	return ps3_sys_manager_write(dev, &header, &payload);}/** * ps3_sys_manager_handle_event - Second stage event msg handler. * */static int ps3_sys_manager_handle_event(struct ps3_system_bus_device *dev){	int result;	struct {		u8 version;		u8 type;		u8 reserved_1[2];		u32 value;		u8 reserved_2[8];	} event;	BUILD_BUG_ON(sizeof(event) != 16);	result = ps3_vuart_read(dev, &event, sizeof(event));	BUG_ON(result && "need to retry here");	if (event.version != 1) {		dev_dbg(&dev->core, "%s:%d: unsupported event version (%u)\n",			__func__, __LINE__, event.version);		return -EIO;	}	switch (event.type) {	case PS3_SM_EVENT_POWER_PRESSED:		dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n",			__func__, __LINE__);		ps3_sm_force_power_off = 1;		/*		 * A memory barrier is use here to sync memory since		 * ps3_sys_manager_final_restart() could be called on		 * another cpu.		 */		wmb();		kill_cad_pid(SIGINT, 1); /* ctrl_alt_del */		break;	case PS3_SM_EVENT_POWER_RELEASED:		dev_dbg(&dev->core, "%s:%d: POWER_RELEASED (%u ms)\n",			__func__, __LINE__, event.value);		break;	case PS3_SM_EVENT_RESET_PRESSED:		dev_dbg(&dev->core, "%s:%d: RESET_PRESSED\n",			__func__, __LINE__);		ps3_sm_force_power_off = 0;		/*		 * A memory barrier is use here to sync memory since		 * ps3_sys_manager_final_restart() could be called on		 * another cpu.		 */		wmb();		kill_cad_pid(SIGINT, 1); /* ctrl_alt_del */		break;	case PS3_SM_EVENT_RESET_RELEASED:		dev_dbg(&dev->core, "%s:%d: RESET_RELEASED (%u ms)\n",			__func__, __LINE__, event.value);		break;	case PS3_SM_EVENT_THERMAL_ALERT:		dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n",			__func__, __LINE__, event.value);		printk(KERN_INFO "PS3 Thermal Alert Zone %u\n", event.value);		break;	case PS3_SM_EVENT_THERMAL_CLEARED:		dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n",			__func__, __LINE__, event.value);		break;	default:		dev_dbg(&dev->core, "%s:%d: unknown event (%u)\n",			__func__, __LINE__, event.type);		return -EIO;	}	return 0;}/** * ps3_sys_manager_handle_cmd - Second stage command msg handler. * * The system manager sends this in reply to a 'request' message from the guest. */static int ps3_sys_manager_handle_cmd(struct ps3_system_bus_device *dev){	int result;	struct {		u8 version;		u8 type;		u8 reserved_1[14];	} cmd;	BUILD_BUG_ON(sizeof(cmd) != 16);	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);	result = ps3_vuart_read(dev, &cmd, sizeof(cmd));	BUG_ON(result && "need to retry here");	if(result)		return result;	if (cmd.version != 1) {		dev_dbg(&dev->core, "%s:%d: unsupported cmd version (%u)\n",			__func__, __LINE__, cmd.version);		return -EIO;	}	if (cmd.type != PS3_SM_CMD_SHUTDOWN) {		dev_dbg(&dev->core, "%s:%d: unknown cmd (%u)\n",			__func__, __LINE__, cmd.type);		return -EIO;	}	ps3_sys_manager_send_response(dev, 0);	return 0;}/** * ps3_sys_manager_handle_msg - First stage msg handler. * * Can be called directly to manually poll vuart and pump message handler. */static int ps3_sys_manager_handle_msg(struct ps3_system_bus_device *dev){	int result;	struct ps3_sys_manager_header header;	result = ps3_vuart_read(dev, &header,		sizeof(struct ps3_sys_manager_header));	if(result)		return result;	if (header.version != 1) {		dev_dbg(&dev->core, "%s:%d: unsupported header version (%u)\n",			__func__, __LINE__, header.version);		dump_sm_header(&header);		goto fail_header;	}	BUILD_BUG_ON(sizeof(header) != 16);	if (header.size != 16 || (header.payload_size != 8		&& header.payload_size != 16)) {		dump_sm_header(&header);		BUG();	}	switch (header.service_id) {	case PS3_SM_SERVICE_ID_EXTERN_EVENT:		dev_dbg(&dev->core, "%s:%d: EVENT\n", __func__, __LINE__);		return ps3_sys_manager_handle_event(dev);	case PS3_SM_SERVICE_ID_COMMAND:		dev_dbg(&dev->core, "%s:%d: COMMAND\n", __func__, __LINE__);		return ps3_sys_manager_handle_cmd(dev);	case PS3_SM_SERVICE_ID_REQUEST_ERROR:		dev_dbg(&dev->core, "%s:%d: REQUEST_ERROR\n", __func__,			__LINE__);		dump_sm_header(&header);		break;	default:		dev_dbg(&dev->core, "%s:%d: unknown service_id (%u)\n",			__func__, __LINE__, header.service_id);		break;	}	goto fail_id;fail_header:	ps3_vuart_clear_rx_bytes(dev, 0);	return -EIO;fail_id:	ps3_vuart_clear_rx_bytes(dev, header.payload_size);	return -EIO;}/** * ps3_sys_manager_final_power_off - The final platform machine_power_off routine. * * This routine never returns.  The routine disables asynchronous vuart reads * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge * the shutdown command sent from the system manager.  Soon after the * acknowledgement is sent the lpar is destroyed by the HV.  This routine * should only be called from ps3_power_off() through * ps3_sys_manager_ops.power_off. */static void ps3_sys_manager_final_power_off(struct ps3_system_bus_device *dev){	BUG_ON(!dev);	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);	ps3_vuart_cancel_async(dev);	ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN,		PS3_SM_WAKE_DEFAULT);	ps3_sys_manager_send_request_shutdown(dev);	printk(KERN_EMERG "System Halted, OK to turn off power\n");	while(1)		ps3_sys_manager_handle_msg(dev);}/** * ps3_sys_manager_final_restart - The final platform machine_restart routine. * * This routine never returns.  The routine disables asynchronous vuart reads * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge * the shutdown command sent from the system manager.  Soon after the * acknowledgement is sent the lpar is destroyed by the HV.  This routine * should only be called from ps3_restart() through ps3_sys_manager_ops.restart. */static void ps3_sys_manager_final_restart(struct ps3_system_bus_device *dev){	BUG_ON(!dev);	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);	/* Check if we got here via a power button event. */	if (ps3_sm_force_power_off) {		dev_dbg(&dev->core, "%s:%d: forcing poweroff\n",			__func__, __LINE__);		ps3_sys_manager_final_power_off(dev);	}	ps3_vuart_cancel_async(dev);	ps3_sys_manager_send_attr(dev, 0);	ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT,		PS3_SM_WAKE_DEFAULT);	ps3_sys_manager_send_request_shutdown(dev);	printk(KERN_EMERG "System Halted, OK to turn off power\n");	while(1)		ps3_sys_manager_handle_msg(dev);}/** * ps3_sys_manager_work - Asynchronous read handler. * * Signaled when PS3_SM_RX_MSG_LEN_MIN bytes arrive at the vuart port. */static void ps3_sys_manager_work(struct ps3_system_bus_device *dev){	ps3_sys_manager_handle_msg(dev);	ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);}static int ps3_sys_manager_probe(struct ps3_system_bus_device *dev){	int result;	struct ps3_sys_manager_ops ops;	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);	ops.power_off = ps3_sys_manager_final_power_off;	ops.restart = ps3_sys_manager_final_restart;	ops.dev = dev;	/* ps3_sys_manager_register_ops copies ops. */	ps3_sys_manager_register_ops(&ops);	result = ps3_sys_manager_send_attr(dev, PS3_SM_ATTR_ALL);	BUG_ON(result);	result = ps3_vuart_read_async(dev, PS3_SM_RX_MSG_LEN_MIN);	BUG_ON(result);	return result;}static int ps3_sys_manager_remove(struct ps3_system_bus_device *dev){	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);	return 0;}static void ps3_sys_manager_shutdown(struct ps3_system_bus_device *dev){	dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);}static struct ps3_vuart_port_driver ps3_sys_manager = {	.core.match_id = PS3_MATCH_ID_SYSTEM_MANAGER,	.core.core.name = "ps3_sys_manager",	.probe = ps3_sys_manager_probe,	.remove = ps3_sys_manager_remove,	.shutdown = ps3_sys_manager_shutdown,	.work = ps3_sys_manager_work,};static int __init ps3_sys_manager_init(void){	if (!firmware_has_feature(FW_FEATURE_PS3_LV1))		return -ENODEV;	return ps3_vuart_port_driver_register(&ps3_sys_manager);}module_init(ps3_sys_manager_init);/* Module remove not supported. */MODULE_ALIAS(PS3_MODULE_ALIAS_SYSTEM_MANAGER);

⌨️ 快捷键说明

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