1 /*
2 * lanserv_force_oem.c
3 *
4 * MontaVista IPMI IPMI LAN code for OEM Force Computers board handling
5 *
6 * Author: MontaVista Software, Inc.
7 * Corey Minyard <minyard@mvista.com>
8 * source@mvista.com
9 *
10 * Copyright 2003 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
26 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
27 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 *
29 * You should have received a copy of the GNU Lesser General Public
30 * License along with this program; if not, write to the Free
31 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
32 *
33 * Modified BSD Licence
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 *
39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above
42 * copyright notice, this list of conditions and the following
43 * disclaimer in the documentation and/or other materials provided
44 * with the distribution.
45 * 3. The name of the author may not be used to endorse or promote
46 * products derived from this software without specific prior
47 * written permission.
48 */
49
50 #include <stdlib.h>
51
52 #include <OpenIPMI/ipmi_auth.h>
53 #include <OpenIPMI/serv.h>
54
55 typedef struct force_oem_data_s
56 {
57 unsigned char slave_addr;
58 unsigned char curr_addr;
59 } force_oem_data_t;
60
61 static int
force_rsp_handler(channel_t * chan,msg_t * msg,rsp_msg_t * rsp)62 force_rsp_handler(channel_t *chan, msg_t *msg, rsp_msg_t *rsp)
63 {
64 unsigned char new_addr;
65
66 if (rsp->netfn == 0x31) {
67 /* A force OEM response. */
68 force_oem_data_t *fdata = chan->oem.oem_data;
69
70 switch (rsp->cmd)
71 {
72 case 3:
73 /* A response to a change mode. */
74
75 /* Ignore errors. */
76 if (rsp->data_len < 1)
77 return 0;
78 if (rsp->data[0] != 0)
79 return 0;
80
81 /* See what it was changed to. */
82 if (msg->data[0] == 0)
83 /* Changed to master, address is 0x20 */
84 new_addr = 0x20;
85 else
86 new_addr = fdata->slave_addr;
87
88 if (new_addr != fdata->curr_addr) {
89 fdata->curr_addr = fdata->slave_addr;
90 chan->log(chan, INFO, NULL,
91 "Change Force MC address to 0x%x", new_addr);
92 if (chan->oem.ipmb_addr_change)
93 chan->oem.ipmb_addr_change(chan, fdata->curr_addr);
94 }
95 break;
96
97 case 4:
98 /* A request for the IPMB address. */
99
100 /* Ignore errors. */
101 if (rsp->data_len < 4)
102 return 0;
103 if (rsp->data[0] != 0)
104 return 0;
105
106 fdata->slave_addr = rsp->data[3];
107 if (fdata->curr_addr != rsp->data[2]) {
108 fdata->curr_addr = rsp->data[2];
109 if (chan->oem.ipmb_addr_change)
110 chan->oem.ipmb_addr_change(chan, fdata->curr_addr);
111 }
112
113 return msg->oem_data;
114 }
115 }
116
117 return 0;
118 }
119
120 static int
force_check_permitted(unsigned char priv,unsigned char netfn,unsigned char cmd)121 force_check_permitted(unsigned char priv,
122 unsigned char netfn,
123 unsigned char cmd)
124 {
125 int req_priv = IPMI_PRIVILEGE_ADMIN;
126
127 if (netfn != 0x30)
128 return IPMI_PRIV_INVALID;
129
130 switch (cmd)
131 {
132 case 3:
133 req_priv = IPMI_PRIVILEGE_OPERATOR;
134 break;
135
136 case 4:
137 req_priv = IPMI_PRIVILEGE_USER;
138 break;
139
140 case 5:
141 req_priv = IPMI_PRIVILEGE_USER;
142 break;
143
144 case 6:
145 req_priv = IPMI_PRIVILEGE_OPERATOR;
146 break;
147 }
148
149 if (priv >= req_priv)
150 return IPMI_PRIV_PERMITTED;
151 else
152 return IPMI_PRIV_DENIED;
153 }
154
155 static force_oem_data_t force_data =
156 {
157 .slave_addr = 0,
158 .curr_addr = 0,
159 };
160
161 static void
force_oem_installer(channel_t * chan,void * cb_data)162 force_oem_installer(channel_t *chan, void *cb_data)
163 {
164 chan->oem.oem_handle_rsp = force_rsp_handler;
165 chan->oem.oem_check_permitted = force_check_permitted;
166 chan->oem.oem_data = &force_data;
167
168 /* Set a command to get the current address. */
169 ipmi_oem_send_msg(chan, 0x30, 4, NULL, 0, 1);
170 }
171
172 static oem_handler_t force_735_oem =
173 {
174 .manufacturer_id = 0x000e48,
175 .product_id = 0x0804,
176 .handler = force_oem_installer,
177 .cb_data = NULL,
178 };
179
180 static oem_handler_t force_740_oem =
181 {
182 .manufacturer_id = 0x000e48,
183 .product_id = 0x0808,
184 .handler = force_oem_installer,
185 .cb_data = NULL,
186 };
187
188 static oem_handler_t force_786_oem =
189 {
190 .manufacturer_id = 0x000e48,
191 .product_id = 0x0810,
192 .handler = force_oem_installer,
193 .cb_data = NULL,
194 };
195
196 static oem_handler_t force_550_oem =
197 {
198 .manufacturer_id = 0x000e48,
199 .product_id = 0x0880,
200 .handler = force_oem_installer,
201 .cb_data = NULL,
202 };
203
204 static oem_handler_t force_560_oem =
205 {
206 .manufacturer_id = 0x000e48,
207 .product_id = 0x0888,
208 .handler = force_oem_installer,
209 .cb_data = NULL,
210 };
211
212 static oem_handler_t force_690_oem =
213 {
214 .manufacturer_id = 0x000e48,
215 .product_id = 0x0900,
216 .handler = force_oem_installer,
217 .cb_data = NULL,
218 };
219
220 static oem_handler_t force_695_oem =
221 {
222 .manufacturer_id = 0x000e48,
223 .product_id = 0x0904,
224 .handler = force_oem_installer,
225 .cb_data = NULL,
226 };
227
228
229 void
init_oem_force(void)230 init_oem_force(void)
231 {
232 ipmi_register_oem(&force_735_oem);
233 ipmi_register_oem(&force_740_oem);
234 ipmi_register_oem(&force_786_oem);
235 ipmi_register_oem(&force_550_oem);
236 ipmi_register_oem(&force_560_oem);
237 ipmi_register_oem(&force_690_oem);
238 ipmi_register_oem(&force_695_oem);
239 }
240
241 #if 0
242 /* If you include this as a module under Linux, you can use the
243 following code to initialize it. Otherwise, something has to call
244 init_oem_force(). */
245 static void (*const __init_patch_debug[1]) \
246 (void) __attribute__ ((section(".ctors"))) = { init_oem_force };
247 #endif
248