Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/misc/ibmasm/dot_command.c
17305 views
1
/*
2
* IBM ASM Service Processor Device Driver
3
*
4
* This program is free software; you can redistribute it and/or modify
5
* it under the terms of the GNU General Public License as published by
6
* the Free Software Foundation; either version 2 of the License, or
7
* (at your option) any later version.
8
*
9
* This program is distributed in the hope that it will be useful,
10
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
* GNU General Public License for more details.
13
*
14
* You should have received a copy of the GNU General Public License
15
* along with this program; if not, write to the Free Software
16
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17
*
18
* Copyright (C) IBM Corporation, 2004
19
*
20
* Author: Max Asb�ck <[email protected]>
21
*
22
*/
23
24
#include "ibmasm.h"
25
#include "dot_command.h"
26
27
/**
28
* Dispatch an incoming message to the specific handler for the message.
29
* Called from interrupt context.
30
*/
31
void ibmasm_receive_message(struct service_processor *sp, void *message, int message_size)
32
{
33
u32 size;
34
struct dot_command_header *header = (struct dot_command_header *)message;
35
36
if (message_size == 0)
37
return;
38
39
size = get_dot_command_size(message);
40
if (size == 0)
41
return;
42
43
if (size > message_size)
44
size = message_size;
45
46
switch (header->type) {
47
case sp_event:
48
ibmasm_receive_event(sp, message, size);
49
break;
50
case sp_command_response:
51
ibmasm_receive_command_response(sp, message, size);
52
break;
53
case sp_heartbeat:
54
ibmasm_receive_heartbeat(sp, message, size);
55
break;
56
default:
57
dev_err(sp->dev, "Received unknown message from service processor\n");
58
}
59
}
60
61
62
#define INIT_BUFFER_SIZE 32
63
64
65
/**
66
* send the 4.3.5.10 dot command (driver VPD) to the service processor
67
*/
68
int ibmasm_send_driver_vpd(struct service_processor *sp)
69
{
70
struct command *command;
71
struct dot_command_header *header;
72
u8 *vpd_command;
73
u8 *vpd_data;
74
int result = 0;
75
76
command = ibmasm_new_command(sp, INIT_BUFFER_SIZE);
77
if (command == NULL)
78
return -ENOMEM;
79
80
header = (struct dot_command_header *)command->buffer;
81
header->type = sp_write;
82
header->command_size = 4;
83
header->data_size = 16;
84
header->status = 0;
85
header->reserved = 0;
86
87
vpd_command = command->buffer + sizeof(struct dot_command_header);
88
vpd_command[0] = 0x4;
89
vpd_command[1] = 0x3;
90
vpd_command[2] = 0x5;
91
vpd_command[3] = 0xa;
92
93
vpd_data = vpd_command + header->command_size;
94
vpd_data[0] = 0;
95
strcat(vpd_data, IBMASM_DRIVER_VPD);
96
vpd_data[10] = 0;
97
vpd_data[15] = 0;
98
99
ibmasm_exec_command(sp, command);
100
ibmasm_wait_for_response(command, IBMASM_CMD_TIMEOUT_NORMAL);
101
102
if (command->status != IBMASM_CMD_COMPLETE)
103
result = -ENODEV;
104
105
command_put(command);
106
107
return result;
108
}
109
110
struct os_state_command {
111
struct dot_command_header header;
112
unsigned char command[3];
113
unsigned char data;
114
};
115
116
/**
117
* send the 4.3.6 dot command (os state) to the service processor
118
* During driver init this function is called with os state "up".
119
* This causes the service processor to start sending heartbeats the
120
* driver.
121
* During driver exit the function is called with os state "down",
122
* causing the service processor to stop the heartbeats.
123
*/
124
int ibmasm_send_os_state(struct service_processor *sp, int os_state)
125
{
126
struct command *cmd;
127
struct os_state_command *os_state_cmd;
128
int result = 0;
129
130
cmd = ibmasm_new_command(sp, sizeof(struct os_state_command));
131
if (cmd == NULL)
132
return -ENOMEM;
133
134
os_state_cmd = (struct os_state_command *)cmd->buffer;
135
os_state_cmd->header.type = sp_write;
136
os_state_cmd->header.command_size = 3;
137
os_state_cmd->header.data_size = 1;
138
os_state_cmd->header.status = 0;
139
os_state_cmd->command[0] = 4;
140
os_state_cmd->command[1] = 3;
141
os_state_cmd->command[2] = 6;
142
os_state_cmd->data = os_state;
143
144
ibmasm_exec_command(sp, cmd);
145
ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
146
147
if (cmd->status != IBMASM_CMD_COMPLETE)
148
result = -ENODEV;
149
150
command_put(cmd);
151
return result;
152
}
153
154