Path: blob/master/drivers/misc/ibmasm/dot_command.c
17305 views
/*1* IBM ASM Service Processor Device Driver2*3* This program is free software; you can redistribute it and/or modify4* it under the terms of the GNU General Public License as published by5* the Free Software Foundation; either version 2 of the License, or6* (at your option) any later version.7*8* This program is distributed in the hope that it will be useful,9* but WITHOUT ANY WARRANTY; without even the implied warranty of10* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the11* GNU General Public License for more details.12*13* You should have received a copy of the GNU General Public License14* along with this program; if not, write to the Free Software15* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.16*17* Copyright (C) IBM Corporation, 200418*19* Author: Max Asb�ck <[email protected]>20*21*/2223#include "ibmasm.h"24#include "dot_command.h"2526/**27* Dispatch an incoming message to the specific handler for the message.28* Called from interrupt context.29*/30void ibmasm_receive_message(struct service_processor *sp, void *message, int message_size)31{32u32 size;33struct dot_command_header *header = (struct dot_command_header *)message;3435if (message_size == 0)36return;3738size = get_dot_command_size(message);39if (size == 0)40return;4142if (size > message_size)43size = message_size;4445switch (header->type) {46case sp_event:47ibmasm_receive_event(sp, message, size);48break;49case sp_command_response:50ibmasm_receive_command_response(sp, message, size);51break;52case sp_heartbeat:53ibmasm_receive_heartbeat(sp, message, size);54break;55default:56dev_err(sp->dev, "Received unknown message from service processor\n");57}58}596061#define INIT_BUFFER_SIZE 32626364/**65* send the 4.3.5.10 dot command (driver VPD) to the service processor66*/67int ibmasm_send_driver_vpd(struct service_processor *sp)68{69struct command *command;70struct dot_command_header *header;71u8 *vpd_command;72u8 *vpd_data;73int result = 0;7475command = ibmasm_new_command(sp, INIT_BUFFER_SIZE);76if (command == NULL)77return -ENOMEM;7879header = (struct dot_command_header *)command->buffer;80header->type = sp_write;81header->command_size = 4;82header->data_size = 16;83header->status = 0;84header->reserved = 0;8586vpd_command = command->buffer + sizeof(struct dot_command_header);87vpd_command[0] = 0x4;88vpd_command[1] = 0x3;89vpd_command[2] = 0x5;90vpd_command[3] = 0xa;9192vpd_data = vpd_command + header->command_size;93vpd_data[0] = 0;94strcat(vpd_data, IBMASM_DRIVER_VPD);95vpd_data[10] = 0;96vpd_data[15] = 0;9798ibmasm_exec_command(sp, command);99ibmasm_wait_for_response(command, IBMASM_CMD_TIMEOUT_NORMAL);100101if (command->status != IBMASM_CMD_COMPLETE)102result = -ENODEV;103104command_put(command);105106return result;107}108109struct os_state_command {110struct dot_command_header header;111unsigned char command[3];112unsigned char data;113};114115/**116* send the 4.3.6 dot command (os state) to the service processor117* During driver init this function is called with os state "up".118* This causes the service processor to start sending heartbeats the119* driver.120* During driver exit the function is called with os state "down",121* causing the service processor to stop the heartbeats.122*/123int ibmasm_send_os_state(struct service_processor *sp, int os_state)124{125struct command *cmd;126struct os_state_command *os_state_cmd;127int result = 0;128129cmd = ibmasm_new_command(sp, sizeof(struct os_state_command));130if (cmd == NULL)131return -ENOMEM;132133os_state_cmd = (struct os_state_command *)cmd->buffer;134os_state_cmd->header.type = sp_write;135os_state_cmd->header.command_size = 3;136os_state_cmd->header.data_size = 1;137os_state_cmd->header.status = 0;138os_state_cmd->command[0] = 4;139os_state_cmd->command[1] = 3;140os_state_cmd->command[2] = 6;141os_state_cmd->data = os_state;142143ibmasm_exec_command(sp, cmd);144ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);145146if (cmd->status != IBMASM_CMD_COMPLETE)147result = -ENODEV;148149command_put(cmd);150return result;151}152153154