diff options
author | Corey Minyard <cminyard@mvista.com> | 2012-03-19 17:00:55 -0400 |
---|---|---|
committer | Corey Minyard <cminyard@mvista.com> | 2014-12-11 16:04:11 -0500 |
commit | 259307074bfcf1ff88016e12c68f057aee6cb694 (patch) | |
tree | e664a8546fe3ba25663fb6d3e821a0e328be52e9 | |
parent | 99ab32f3b5d705be562b8c4d9dca7c1ae3dc2cdf (diff) |
ipmi: Add SMBus interface driver (SSIF)
This patch adds the SMBus interface to the IPMI driver.
Signed-off-by: Corey Minyard <minyard@acm.org>
Documentation/IPMI.txt | 32
drivers/char/ipmi/Kconfig | 11
drivers/char/ipmi/Makefile | 1
drivers/char/ipmi/ipmi_smb.c | 1737 +++++++++++++++++++++++++++++++++++++++++++
4 files changed, 1769 insertions(+), 12 deletions(-)
-rw-r--r-- | Documentation/IPMI.txt | 74 | ||||
-rw-r--r-- | drivers/char/ipmi/Kconfig | 8 | ||||
-rw-r--r-- | drivers/char/ipmi/Makefile | 1 | ||||
-rw-r--r-- | drivers/char/ipmi/ipmi_ssif.c | 1870 |
4 files changed, 1950 insertions, 3 deletions
diff --git a/Documentation/IPMI.txt b/Documentation/IPMI.txt index f13c9132e9f2..653d5d739d7f 100644 --- a/Documentation/IPMI.txt +++ b/Documentation/IPMI.txt | |||
@@ -42,7 +42,13 @@ The driver interface depends on your hardware. If your system | |||
42 | properly provides the SMBIOS info for IPMI, the driver will detect it | 42 | properly provides the SMBIOS info for IPMI, the driver will detect it |
43 | and just work. If you have a board with a standard interface (These | 43 | and just work. If you have a board with a standard interface (These |
44 | will generally be either "KCS", "SMIC", or "BT", consult your hardware | 44 | will generally be either "KCS", "SMIC", or "BT", consult your hardware |
45 | manual), choose the 'IPMI SI handler' option. | 45 | manual), choose the 'IPMI SI handler' option. A driver also exists |
46 | for direct I2C access to the IPMI management controller. Some boards | ||
47 | support this, but it is unknown if it will work on every board. For | ||
48 | this, choose 'IPMI SMBus handler', but be ready to try to do some | ||
49 | figuring to see if it will work on your system if the SMBIOS/APCI | ||
50 | information is wrong or not present. It is fairly safe to have both | ||
51 | these enabled and let the drivers auto-detect what is present. | ||
46 | 52 | ||
47 | You should generally enable ACPI on your system, as systems with IPMI | 53 | You should generally enable ACPI on your system, as systems with IPMI |
48 | can have ACPI tables describing them. | 54 | can have ACPI tables describing them. |
@@ -52,7 +58,8 @@ their job correctly, the IPMI controller should be automatically | |||
52 | detected (via ACPI or SMBIOS tables) and should just work. Sadly, | 58 | detected (via ACPI or SMBIOS tables) and should just work. Sadly, |
53 | many boards do not have this information. The driver attempts | 59 | many boards do not have this information. The driver attempts |
54 | standard defaults, but they may not work. If you fall into this | 60 | standard defaults, but they may not work. If you fall into this |
55 | situation, you need to read the section below named 'The SI Driver'. | 61 | situation, you need to read the section below named 'The SI Driver' or |
62 | "The SMBus Driver" on how to hand-configure your system. | ||
56 | 63 | ||
57 | IPMI defines a standard watchdog timer. You can enable this with the | 64 | IPMI defines a standard watchdog timer. You can enable this with the |
58 | 'IPMI Watchdog Timer' config option. If you compile the driver into | 65 | 'IPMI Watchdog Timer' config option. If you compile the driver into |
@@ -97,7 +104,12 @@ driver, each open file for this device ties in to the message handler | |||
97 | as an IPMI user. | 104 | as an IPMI user. |
98 | 105 | ||
99 | ipmi_si - A driver for various system interfaces. This supports KCS, | 106 | ipmi_si - A driver for various system interfaces. This supports KCS, |
100 | SMIC, and BT interfaces. | 107 | SMIC, and BT interfaces. Unless you have an SMBus interface or your |
108 | own custom interface, you probably need to use this. | ||
109 | |||
110 | ipmi_ssif - A driver for accessing BMCs on the SMBus. It uses the | ||
111 | I2C kernel driver's SMBus interfaces to send and receive IPMI messages | ||
112 | over the SMBus. | ||
101 | 113 | ||
102 | ipmi_watchdog - IPMI requires systems to have a very capable watchdog | 114 | ipmi_watchdog - IPMI requires systems to have a very capable watchdog |
103 | timer. This driver implements the standard Linux watchdog timer | 115 | timer. This driver implements the standard Linux watchdog timer |
@@ -476,6 +488,62 @@ for specifying an interface. Note that when removing an interface, | |||
476 | only the first three parameters (si type, address type, and address) | 488 | only the first three parameters (si type, address type, and address) |
477 | are used for the comparison. Any options are ignored for removing. | 489 | are used for the comparison. Any options are ignored for removing. |
478 | 490 | ||
491 | The SMBus Driver (SSIF) | ||
492 | ----------------------- | ||
493 | |||
494 | The SMBus driver allows up to 4 SMBus devices to be configured in the | ||
495 | system. By default, the driver will only register with something it | ||
496 | finds in DMI or ACPI tables. You can change this | ||
497 | at module load time (for a module) with: | ||
498 | |||
499 | modprobe ipmi_ssif.o | ||
500 | addr=<i2caddr1>[,<i2caddr2>[,...]] | ||
501 | adapter=<adapter1>[,<adapter2>[...]] | ||
502 | dbg=<flags1>,<flags2>... | ||
503 | slave_addrs=<addr1>,<addr2>,... | ||
504 | [dbg_probe=1] | ||
505 | |||
506 | The addresses are normal I2C addresses. The adapter is the string | ||
507 | name of the adapter, as shown in /sys/class/i2c-adapter/i2c-<n>/name. | ||
508 | It is *NOT* i2c-<n> itself. | ||
509 | |||
510 | The debug flags are bit flags for each BMC found, they are: | ||
511 | IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8 | ||
512 | |||
513 | Setting dbg_probe to 1 will enable debugging of the probing and | ||
514 | detection process for BMCs on the SMBusses. | ||
515 | |||
516 | The slave_addrs specifies the IPMI address of the local BMC. This is | ||
517 | usually 0x20 and the driver defaults to that, but in case it's not, it | ||
518 | can be specified when the driver starts up. | ||
519 | |||
520 | Discovering the IPMI compliant BMC on the SMBus can cause devices on | ||
521 | the I2C bus to fail. The SMBus driver writes a "Get Device ID" IPMI | ||
522 | message as a block write to the I2C bus and waits for a response. | ||
523 | This action can be detrimental to some I2C devices. It is highly | ||
524 | recommended that the known I2C address be given to the SMBus driver in | ||
525 | the smb_addr parameter unless you have DMI or ACPI data to tell the | ||
526 | driver what to use. | ||
527 | |||
528 | When compiled into the kernel, the addresses can be specified on the | ||
529 | kernel command line as: | ||
530 | |||
531 | ipmb_ssif.addr=<i2caddr1>[,<i2caddr2>[...]] | ||
532 | ipmi_ssif.adapter=<adapter1>[,<adapter2>[...]] | ||
533 | ipmi_ssif.dbg=<flags1>[,<flags2>[...]] | ||
534 | ipmi_ssif.dbg_probe=1 | ||
535 | ipmi_ssif.slave_addrs=<addr1>[,<addr2>[...]] | ||
536 | |||
537 | These are the same options as on the module command line. | ||
538 | |||
539 | The I2C driver does not support non-blocking access or polling, so | ||
540 | this driver cannod to IPMI panic events, extend the watchdog at panic | ||
541 | time, or other panic-related IPMI functions without special kernel | ||
542 | patches and driver modifications. You can get those at the openipmi | ||
543 | web page. | ||
544 | |||
545 | The driver supports a hot add and remove of interfaces through the I2C | ||
546 | sysfs interface. | ||
479 | 547 | ||
480 | Other Pieces | 548 | Other Pieces |
481 | ------------ | 549 | ------------ |
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index db1c9b7adaa6..809d28328c6f 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig | |||
@@ -62,6 +62,14 @@ config IPMI_SI_PROBE_DEFAULTS | |||
62 | only be available on older systems if the "ipmi_si_intf.trydefaults=1" | 62 | only be available on older systems if the "ipmi_si_intf.trydefaults=1" |
63 | boot argument is passed. | 63 | boot argument is passed. |
64 | 64 | ||
65 | config IPMI_SSIF | ||
66 | tristate 'IPMI SMBus handler (SSIF)' | ||
67 | select I2C | ||
68 | help | ||
69 | Provides a driver for a SMBus interface to a BMC, meaning that you | ||
70 | have a driver that must be accessed over an I2C bus instead of a | ||
71 | standard interface. This module requires I2C support. | ||
72 | |||
65 | config IPMI_WATCHDOG | 73 | config IPMI_WATCHDOG |
66 | tristate 'IPMI Watchdog Timer' | 74 | tristate 'IPMI Watchdog Timer' |
67 | help | 75 | help |
diff --git a/drivers/char/ipmi/Makefile b/drivers/char/ipmi/Makefile index 16a93648d54e..115c08da7117 100644 --- a/drivers/char/ipmi/Makefile +++ b/drivers/char/ipmi/Makefile | |||
@@ -7,5 +7,6 @@ ipmi_si-y := ipmi_si_intf.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o | |||
7 | obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o | 7 | obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o |
8 | obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o | 8 | obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o |
9 | obj-$(CONFIG_IPMI_SI) += ipmi_si.o | 9 | obj-$(CONFIG_IPMI_SI) += ipmi_si.o |
10 | obj-$(CONFIG_IPMI_SSIF) += ipmi_ssif.o | ||
10 | obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o | 11 | obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o |
11 | obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o | 12 | obj-$(CONFIG_IPMI_POWEROFF) += ipmi_poweroff.o |
diff --git a/drivers/char/ipmi/ipmi_ssif.c b/drivers/char/ipmi/ipmi_ssif.c new file mode 100644 index 000000000000..e178ac27e73c --- /dev/null +++ b/drivers/char/ipmi/ipmi_ssif.c | |||
@@ -0,0 +1,1870 @@ | |||
1 | /* | ||
2 | * ipmi_ssif.c | ||
3 | * | ||
4 | * The interface to the IPMI driver for SMBus access to a SMBus | ||
5 | * compliant device. Called SSIF by the IPMI spec. | ||
6 | * | ||
7 | * Author: Intel Corporation | ||
8 | * Todd Davis <todd.c.davis@intel.com> | ||
9 | * | ||
10 | * Rewritten by Corey Minyard <minyard@acm.org> to support the | ||
11 | * non-blocking I2C interface, add support for multi-part | ||
12 | * transactions, add PEC support, and general clenaup. | ||
13 | * | ||
14 | * Copyright 2003 Intel Corporation | ||
15 | * Copyright 2005 MontaVista Software | ||
16 | * | ||
17 | * This program is free software; you can redistribute it and/or modify it | ||
18 | * under the terms of the GNU General Public License as published by the | ||
19 | * Free Software Foundation; either version 2 of the License, or (at your | ||
20 | * option) any later version. | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * This file holds the "policy" for the interface to the SSIF state | ||
25 | * machine. It does the configuration, handles timers and interrupts, | ||
26 | * and drives the real SSIF state machine. | ||
27 | */ | ||
28 | |||
29 | /* | ||
30 | * TODO: Figure out how to use SMB alerts. This will require a new | ||
31 | * interface into the I2C driver, I believe. | ||
32 | */ | ||
33 | |||
34 | #include <linux/version.h> | ||
35 | #if defined(MODVERSIONS) | ||
36 | #include <linux/modversions.h> | ||
37 | #endif | ||
38 | |||
39 | #include <linux/module.h> | ||
40 | #include <linux/moduleparam.h> | ||
41 | #include <linux/sched.h> | ||
42 | #include <linux/seq_file.h> | ||
43 | #include <linux/timer.h> | ||
44 | #include <linux/delay.h> | ||
45 | #include <linux/errno.h> | ||
46 | #include <linux/spinlock.h> | ||
47 | #include <linux/slab.h> | ||
48 | #include <linux/list.h> | ||
49 | #include <linux/i2c.h> | ||
50 | #include <linux/ipmi_smi.h> | ||
51 | #include <linux/init.h> | ||
52 | #include <linux/dmi.h> | ||
53 | #include <linux/kthread.h> | ||
54 | #include <linux/acpi.h> | ||
55 | |||
56 | #define PFX "ipmi_ssif: " | ||
57 | #define DEVICE_NAME "ipmi_ssif" | ||
58 | |||
59 | #define IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD 0x57 | ||
60 | |||
61 | #define SSIF_IPMI_REQUEST 2 | ||
62 | #define SSIF_IPMI_MULTI_PART_REQUEST_START 6 | ||
63 | #define SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE 7 | ||
64 | #define SSIF_IPMI_RESPONSE 3 | ||
65 | #define SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE 9 | ||
66 | |||
67 | /* ssif_debug is a bit-field | ||
68 | * SSIF_DEBUG_MSG - commands and their responses | ||
69 | * SSIF_DEBUG_STATES - message states | ||
70 | * SSIF_DEBUG_TIMING - Measure times between events in the driver | ||
71 | */ | ||
72 | #define SSIF_DEBUG_TIMING 4 | ||
73 | #define SSIF_DEBUG_STATE 2 | ||
74 | #define SSIF_DEBUG_MSG 1 | ||
75 | #define SSIF_NODEBUG 0 | ||
76 | #define SSIF_DEFAULT_DEBUG (SSIF_NODEBUG) | ||
77 | |||
78 | /* | ||
79 | * Timer values | ||
80 | */ | ||
81 | #define SSIF_MSG_USEC 20000 /* 20ms between message tries. */ | ||
82 | #define SSIF_MSG_PART_USEC 5000 /* 5ms for a message part */ | ||
83 | |||
84 | /* How many times to we retry sending/receiving the message. */ | ||
85 | #define SSIF_SEND_RETRIES 5 | ||
86 | #define SSIF_RECV_RETRIES 250 | ||
87 | |||
88 | #define SSIF_MSG_MSEC (SSIF_MSG_USEC / 1000) | ||
89 | #define SSIF_MSG_JIFFIES ((SSIF_MSG_USEC * 1000) / TICK_NSEC) | ||
90 | #define SSIF_MSG_PART_JIFFIES ((SSIF_MSG_PART_USEC * 1000) / TICK_NSEC) | ||
91 | |||
92 | enum ssif_intf_state { | ||
93 | SSIF_NORMAL, | ||
94 | SSIF_GETTING_FLAGS, | ||
95 | SSIF_GETTING_EVENTS, | ||
96 | SSIF_CLEARING_FLAGS, | ||
97 | SSIF_GETTING_MESSAGES, | ||
98 | /* FIXME - add watchdog stuff. */ | ||
99 | }; | ||
100 | |||
101 | #define SSIF_IDLE(ssif) ((ssif)->ssif_state == SSIF_NORMAL \ | ||
102 | && (ssif)->curr_msg == NULL) | ||
103 | |||
104 | /* | ||
105 | * Indexes into stats[] in ssif_info below. | ||
106 | */ | ||
107 | enum ssif_stat_indexes { | ||
108 | /* Number of total messages sent. */ | ||
109 | SSIF_STAT_sent_messages = 0, | ||
110 | |||
111 | /* | ||
112 | * Number of message parts sent. Messages may be broken into | ||
113 | * parts if they are long. | ||
114 | */ | ||
115 | SSIF_STAT_sent_messages_parts, | ||
116 | |||
117 | /* | ||
118 | * Number of time a message was retried. | ||
119 | */ | ||
120 | SSIF_STAT_send_retries, | ||
121 | |||
122 | /* | ||
123 | * Number of times the send of a message failed. | ||
124 | */ | ||
125 | SSIF_STAT_send_errors, | ||
126 | |||
127 | /* | ||
128 | * Number of message responses received. | ||
129 | */ | ||
130 | SSIF_STAT_received_messages, | ||
131 | |||
132 | /* | ||
133 | * Number of message fragments received. | ||
134 | */ | ||
135 | SSIF_STAT_received_message_parts, | ||
136 | |||
137 | /* | ||
138 | * Number of times the receive of a message was retried. | ||
139 | */ | ||
140 | SSIF_STAT_receive_retries, | ||
141 | |||
142 | /* | ||
143 | * Number of errors receiving messages. | ||
144 | */ | ||
145 | SSIF_STAT_receive_errors, | ||
146 | |||
147 | /* | ||
148 | * Number of times a flag fetch was requested. | ||
149 | */ | ||
150 | SSIF_STAT_flag_fetches, | ||
151 | |||
152 | /* | ||
153 | * Number of times the hardware didn't follow the state machine. | ||
154 | */ | ||
155 | SSIF_STAT_hosed, | ||
156 | |||
157 | /* | ||
158 | * Number of received events. | ||
159 | */ | ||
160 | SSIF_STAT_events, | ||
161 | |||
162 | /* Number of asyncronous messages received. */ | ||
163 | SSIF_STAT_incoming_messages, | ||
164 | |||
165 | /* Number of watchdog pretimeouts. */ | ||
166 | SSIF_STAT_watchdog_pretimeouts, | ||
167 | |||
168 | /* Always add statistics before this value, it must be last. */ | ||
169 | SSIF_NUM_STATS | ||
170 | }; | ||
171 | |||
172 | struct ssif_addr_info { | ||
173 | unsigned short addr; | ||
174 | struct i2c_board_info binfo; | ||
175 | char *adapter_name; | ||
176 | int debug; | ||
177 | int slave_addr; | ||
178 | enum ipmi_addr_src addr_src; | ||
179 | union ipmi_smi_info_union addr_info; | ||
180 | |||
181 | struct mutex clients_mutex; | ||
182 | struct list_head clients; | ||
183 | |||
184 | struct list_head link; | ||
185 | }; | ||
186 | |||
187 | struct ssif_info; | ||
188 | |||
189 | typedef void (*ssif_i2c_done)(struct ssif_info *ssif_info, int result, | ||
190 | unsigned char *data, unsigned int len); | ||
191 | |||
192 | struct ssif_info { | ||
193 | ipmi_smi_t intf; | ||
194 | int intf_num; | ||
195 | spinlock_t lock; | ||
196 | struct ipmi_smi_msg *waiting_msg; | ||
197 | struct ipmi_smi_msg *curr_msg; | ||
198 | enum ssif_intf_state ssif_state; | ||
199 | unsigned long ssif_debug; | ||
200 | |||
201 | struct ipmi_smi_handlers handlers; | ||
202 | |||
203 | enum ipmi_addr_src addr_source; /* ACPI, PCI, SMBIOS, hardcode, etc. */ | ||
204 | union ipmi_smi_info_union addr_info; | ||
205 | |||
206 | /* | ||
207 | * Flags from the last GET_MSG_FLAGS command, used when an ATTN | ||
208 | * is set to hold the flags until we are done handling everything | ||
209 | * from the flags. | ||
210 | */ | ||
211 | #define RECEIVE_MSG_AVAIL 0x01 | ||
212 | #define EVENT_MSG_BUFFER_FULL 0x02 | ||
213 | #define WDT_PRE_TIMEOUT_INT 0x08 | ||
214 | unsigned char msg_flags; | ||
215 | |||
216 | bool has_event_buffer; | ||
217 | |||
218 | /* | ||
219 | * If set to true, this will request events the next time the | ||
220 | * state machine is idle. | ||
221 | */ | ||
222 | bool req_events; | ||
223 | |||
224 | /* | ||
225 | * If set to true, this will request flags the next time the | ||
226 | * state machine is idle. | ||
227 | */ | ||
228 | bool req_flags; | ||
229 | |||
230 | /* | ||
231 | * Used to perform timer operations when run-to-completion | ||
232 | * mode is on. This is a countdown timer. | ||
233 | */ | ||
234 | int rtc_us_timer; | ||
235 | |||
236 | /* Used for sending/receiving data. +1 for the length. */ | ||
237 | unsigned char data[IPMI_MAX_MSG_LENGTH + 1]; | ||
238 | unsigned int data_len; | ||
239 | |||
240 | /* Temp receive buffer, gets copied into data. */ | ||
241 | unsigned char recv[I2C_SMBUS_BLOCK_MAX]; | ||
242 | |||
243 | struct i2c_client *client; | ||
244 | ssif_i2c_done done_handler; | ||
245 | |||
246 | /* Thread interface handling */ | ||
247 | struct task_struct *thread; | ||
248 | struct completion wake_thread; | ||
249 | bool stopping; | ||
250 | int i2c_read_write; | ||
251 | int i2c_command; | ||
252 | unsigned char *i2c_data; | ||
253 | unsigned int i2c_size; | ||
254 | |||
255 | /* From the device id response. */ | ||
256 | struct ipmi_device_id device_id; | ||
257 | |||
258 | struct timer_list retry_timer; | ||
259 | int retries_left; | ||
260 | |||
261 | /* Info from SSIF cmd */ | ||
262 | unsigned char max_xmit_msg_size; | ||
263 | unsigned char max_recv_msg_size; | ||
264 | unsigned int multi_support; | ||
265 | int supports_pec; | ||
266 | |||
267 | #define SSIF_NO_MULTI 0 | ||
268 | #define SSIF_MULTI_2_PART 1 | ||
269 | #define SSIF_MULTI_n_PART 2 | ||
270 | unsigned char *multi_data; | ||
271 | unsigned int multi_len; | ||
272 | unsigned int multi_pos; | ||
273 | |||
274 | atomic_t stats[SSIF_NUM_STATS]; | ||
275 | }; | ||
276 | |||
277 | #define ssif_inc_stat(ssif, stat) \ | ||
278 | atomic_inc(&(ssif)->stats[SSIF_STAT_ ## stat]) | ||
279 | #define ssif_get_stat(ssif, stat) \ | ||
280 | ((unsigned int) atomic_read(&(ssif)->stats[SSIF_STAT_ ## stat])) | ||
281 | |||
282 | static bool initialized; | ||
283 | |||
284 | static atomic_t next_intf = ATOMIC_INIT(0); | ||
285 | |||
286 | static void return_hosed_msg(struct ssif_info *ssif_info, | ||
287 | struct ipmi_smi_msg *msg); | ||
288 | static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags); | ||
289 | static int start_send(struct ssif_info *ssif_info, | ||
290 | unsigned char *data, | ||
291 | unsigned int len); | ||
292 | |||
293 | static unsigned long *ipmi_ssif_lock_cond(struct ssif_info *ssif_info, | ||
294 | unsigned long *flags) | ||
295 | { | ||
296 | spin_lock_irqsave(&ssif_info->lock, *flags); | ||
297 | return flags; | ||
298 | } | ||
299 | |||
300 | static void ipmi_ssif_unlock_cond(struct ssif_info *ssif_info, | ||
301 | unsigned long *flags) | ||
302 | { | ||
303 | spin_unlock_irqrestore(&ssif_info->lock, *flags); | ||
304 | } | ||
305 | |||
306 | static void deliver_recv_msg(struct ssif_info *ssif_info, | ||
307 | struct ipmi_smi_msg *msg) | ||
308 | { | ||
309 | ipmi_smi_t intf = ssif_info->intf; | ||
310 | |||
311 | if (!intf) { | ||
312 | ipmi_free_smi_msg(msg); | ||
313 | } else if (msg->rsp_size < 0) { | ||
314 | return_hosed_msg(ssif_info, msg); | ||
315 | pr_err(PFX | ||
316 | "Malformed message in deliver_recv_msg: rsp_size = %d\n", | ||
317 | msg->rsp_size); | ||
318 | } else { | ||
319 | ipmi_smi_msg_received(intf, msg); | ||
320 | } | ||
321 | } | ||
322 | |||
323 | static void return_hosed_msg(struct ssif_info *ssif_info, | ||
324 | struct ipmi_smi_msg *msg) | ||
325 | { | ||
326 | ssif_inc_stat(ssif_info, hosed); | ||
327 | |||
328 | /* Make it a response */ | ||
329 | msg->rsp[0] = msg->data[0] | 4; | ||
330 | msg->rsp[1] = msg->data[1]; | ||
331 | msg->rsp[2] = 0xFF; /* Unknown error. */ | ||
332 | msg->rsp_size = 3; | ||
333 | |||
334 | deliver_recv_msg(ssif_info, msg); | ||
335 | } | ||
336 | |||
337 | /* | ||
338 | * Must be called with the message lock held. This will release the | ||
339 | * message lock. Note that the caller will check SSIF_IDLE and start a | ||
340 | * new operation, so there is no need to check for new messages to | ||
341 | * start in here. | ||
342 | */ | ||
343 | static void start_clear_flags(struct ssif_info *ssif_info, unsigned long *flags) | ||
344 | { | ||
345 | unsigned char msg[3]; | ||
346 | |||
347 | ssif_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT; | ||
348 | ssif_info->ssif_state = SSIF_CLEARING_FLAGS; | ||
349 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
350 | |||
351 | /* Make sure the watchdog pre-timeout flag is not set at startup. */ | ||
352 | msg[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
353 | msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD; | ||
354 | msg[2] = WDT_PRE_TIMEOUT_INT; | ||
355 | |||
356 | if (start_send(ssif_info, msg, 3) != 0) { | ||
357 | /* Error, just go to normal state. */ | ||
358 | ssif_info->ssif_state = SSIF_NORMAL; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | static void start_flag_fetch(struct ssif_info *ssif_info, unsigned long *flags) | ||
363 | { | ||
364 | unsigned char mb[2]; | ||
365 | |||
366 | ssif_info->req_flags = false; | ||
367 | ssif_info->ssif_state = SSIF_GETTING_FLAGS; | ||
368 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
369 | |||
370 | mb[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
371 | mb[1] = IPMI_GET_MSG_FLAGS_CMD; | ||
372 | if (start_send(ssif_info, mb, 2) != 0) | ||
373 | ssif_info->ssif_state = SSIF_NORMAL; | ||
374 | } | ||
375 | |||
376 | static void check_start_send(struct ssif_info *ssif_info, unsigned long *flags, | ||
377 | struct ipmi_smi_msg *msg) | ||
378 | { | ||
379 | if (start_send(ssif_info, msg->data, msg->data_size) != 0) { | ||
380 | unsigned long oflags; | ||
381 | |||
382 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
383 | ssif_info->curr_msg = NULL; | ||
384 | ssif_info->ssif_state = SSIF_NORMAL; | ||
385 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
386 | ipmi_free_smi_msg(msg); | ||
387 | } | ||
388 | } | ||
389 | |||
390 | static void start_event_fetch(struct ssif_info *ssif_info, unsigned long *flags) | ||
391 | { | ||
392 | struct ipmi_smi_msg *msg; | ||
393 | |||
394 | ssif_info->req_events = false; | ||
395 | |||
396 | msg = ipmi_alloc_smi_msg(); | ||
397 | if (!msg) { | ||
398 | ssif_info->ssif_state = SSIF_NORMAL; | ||
399 | return; | ||
400 | } | ||
401 | |||
402 | ssif_info->curr_msg = msg; | ||
403 | ssif_info->ssif_state = SSIF_GETTING_EVENTS; | ||
404 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
405 | |||
406 | msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
407 | msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD; | ||
408 | msg->data_size = 2; | ||
409 | |||
410 | check_start_send(ssif_info, flags, msg); | ||
411 | } | ||
412 | |||
413 | static void start_recv_msg_fetch(struct ssif_info *ssif_info, | ||
414 | unsigned long *flags) | ||
415 | { | ||
416 | struct ipmi_smi_msg *msg; | ||
417 | |||
418 | msg = ipmi_alloc_smi_msg(); | ||
419 | if (!msg) { | ||
420 | ssif_info->ssif_state = SSIF_NORMAL; | ||
421 | return; | ||
422 | } | ||
423 | |||
424 | ssif_info->curr_msg = msg; | ||
425 | ssif_info->ssif_state = SSIF_GETTING_MESSAGES; | ||
426 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
427 | |||
428 | msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2); | ||
429 | msg->data[1] = IPMI_GET_MSG_CMD; | ||
430 | msg->data_size = 2; | ||
431 | |||
432 | check_start_send(ssif_info, flags, msg); | ||
433 | } | ||
434 | |||
435 | /* | ||
436 | * Must be called with the message lock held. This will release the | ||
437 | * message lock. Note that the caller will check SSIF_IDLE and start a | ||
438 | * new operation, so there is no need to check for new messages to | ||
439 | * start in here. | ||
440 | */ | ||
441 | static void handle_flags(struct ssif_info *ssif_info, unsigned long *flags) | ||
442 | { | ||
443 | if (ssif_info->msg_flags & WDT_PRE_TIMEOUT_INT) { | ||
444 | ipmi_smi_t intf = ssif_info->intf; | ||
445 | /* Watchdog pre-timeout */ | ||
446 | ssif_inc_stat(ssif_info, watchdog_pretimeouts); | ||
447 | start_clear_flags(ssif_info, flags); | ||
448 | if (intf) | ||
449 | ipmi_smi_watchdog_pretimeout(intf); | ||
450 | } else if (ssif_info->msg_flags & RECEIVE_MSG_AVAIL) | ||
451 | /* Messages available. */ | ||
452 | start_recv_msg_fetch(ssif_info, flags); | ||
453 | else if (ssif_info->msg_flags & EVENT_MSG_BUFFER_FULL) | ||
454 | /* Events available. */ | ||
455 | start_event_fetch(ssif_info, flags); | ||
456 | else { | ||
457 | ssif_info->ssif_state = SSIF_NORMAL; | ||
458 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
459 | } | ||
460 | } | ||
461 | |||
462 | static int ipmi_ssif_thread(void *data) | ||
463 | { | ||
464 | struct ssif_info *ssif_info = data; | ||
465 | |||
466 | while (!kthread_should_stop()) { | ||
467 | int result; | ||
468 | |||
469 | /* Wait for something to do */ | ||
470 | wait_for_completion(&ssif_info->wake_thread); | ||
471 | init_completion(&ssif_info->wake_thread); | ||
472 | |||
473 | if (ssif_info->stopping) | ||
474 | break; | ||
475 | |||
476 | if (ssif_info->i2c_read_write == I2C_SMBUS_WRITE) { | ||
477 | result = i2c_smbus_write_block_data( | ||
478 | ssif_info->client, SSIF_IPMI_REQUEST, | ||
479 | ssif_info->i2c_data[0], | ||
480 | ssif_info->i2c_data + 1); | ||
481 | ssif_info->done_handler(ssif_info, result, NULL, 0); | ||
482 | } else { | ||
483 | result = i2c_smbus_read_block_data( | ||
484 | ssif_info->client, SSIF_IPMI_RESPONSE, | ||
485 | ssif_info->i2c_data); | ||
486 | if (result < 0) | ||
487 | ssif_info->done_handler(ssif_info, result, | ||
488 | NULL, 0); | ||
489 | else | ||
490 | ssif_info->done_handler(ssif_info, 0, | ||
491 | ssif_info->i2c_data, | ||
492 | result); | ||
493 | } | ||
494 | } | ||
495 | |||
496 | return 0; | ||
497 | } | ||
498 | |||
499 | static int ssif_i2c_send(struct ssif_info *ssif_info, | ||
500 | ssif_i2c_done handler, | ||
501 | int read_write, int command, | ||
502 | unsigned char *data, unsigned int size) | ||
503 | { | ||
504 | ssif_info->done_handler = handler; | ||
505 | |||
506 | ssif_info->i2c_read_write = read_write; | ||
507 | ssif_info->i2c_command = command; | ||
508 | ssif_info->i2c_data = data; | ||
509 | ssif_info->i2c_size = size; | ||
510 | complete(&ssif_info->wake_thread); | ||
511 | return 0; | ||
512 | } | ||
513 | |||
514 | |||
515 | static void msg_done_handler(struct ssif_info *ssif_info, int result, | ||
516 | unsigned char *data, unsigned int len); | ||
517 | |||
518 | static void retry_timeout(unsigned long data) | ||
519 | { | ||
520 | struct ssif_info *ssif_info = (void *) data; | ||
521 | int rv; | ||
522 | |||
523 | if (ssif_info->stopping) | ||
524 | return; | ||
525 | |||
526 | ssif_info->rtc_us_timer = 0; | ||
527 | |||
528 | rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, | ||
529 | SSIF_IPMI_RESPONSE, | ||
530 | ssif_info->recv, I2C_SMBUS_BLOCK_DATA); | ||
531 | if (rv < 0) { | ||
532 | /* request failed, just return the error. */ | ||
533 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
534 | pr_info("Error from i2c_non_blocking_op(5)\n"); | ||
535 | |||
536 | msg_done_handler(ssif_info, -EIO, NULL, 0); | ||
537 | } | ||
538 | } | ||
539 | |||
540 | static int start_resend(struct ssif_info *ssif_info); | ||
541 | |||
542 | static void msg_done_handler(struct ssif_info *ssif_info, int result, | ||
543 | unsigned char *data, unsigned int len) | ||
544 | { | ||
545 | struct ipmi_smi_msg *msg; | ||
546 | unsigned long oflags, *flags; | ||
547 | int rv; | ||
548 | |||
549 | /* | ||
550 | * We are single-threaded here, so no need for a lock until we | ||
551 | * start messing with driver states or the queues. | ||
552 | */ | ||
553 | |||
554 | if (result < 0) { | ||
555 | ssif_info->retries_left--; | ||
556 | if (ssif_info->retries_left > 0) { | ||
557 | ssif_inc_stat(ssif_info, receive_retries); | ||
558 | |||
559 | mod_timer(&ssif_info->retry_timer, | ||
560 | jiffies + SSIF_MSG_JIFFIES); | ||
561 | ssif_info->rtc_us_timer = SSIF_MSG_USEC; | ||
562 | return; | ||
563 | } | ||
564 | |||
565 | ssif_inc_stat(ssif_info, receive_errors); | ||
566 | |||
567 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
568 | pr_info("Error in msg_done_handler: %d\n", result); | ||
569 | len = 0; | ||
570 | goto continue_op; | ||
571 | } | ||
572 | |||
573 | if ((len > 1) && (ssif_info->multi_pos == 0) | ||
574 | && (data[0] == 0x00) && (data[1] == 0x01)) { | ||
575 | /* Start of multi-part read. Start the next transaction. */ | ||
576 | int i; | ||
577 | |||
578 | ssif_inc_stat(ssif_info, received_message_parts); | ||
579 | |||
580 | /* Remove the multi-part read marker. */ | ||
581 | for (i = 0; i < (len-2); i++) | ||
582 | ssif_info->data[i] = data[i+2]; | ||
583 | len -= 2; | ||
584 | ssif_info->multi_len = len; | ||
585 | ssif_info->multi_pos = 1; | ||
586 | |||
587 | rv = ssif_i2c_send(ssif_info, msg_done_handler, I2C_SMBUS_READ, | ||
588 | SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, | ||
589 | ssif_info->recv, I2C_SMBUS_BLOCK_DATA); | ||
590 | if (rv < 0) { | ||
591 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
592 | pr_info("Error from i2c_non_blocking_op(1)\n"); | ||
593 | |||
594 | result = -EIO; | ||
595 | } else | ||
596 | return; | ||
597 | } else if (ssif_info->multi_pos) { | ||
598 | /* Middle of multi-part read. Start the next transaction. */ | ||
599 | int i; | ||
600 | unsigned char blocknum; | ||
601 | |||
602 | if (len == 0) { | ||
603 | result = -EIO; | ||
604 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
605 | pr_info(PFX "Middle message with no data\n"); | ||
606 | |||
607 | goto continue_op; | ||
608 | } | ||
609 | |||
610 | blocknum = data[ssif_info->multi_len]; | ||
611 | |||
612 | if (ssif_info->multi_len+len-1 > IPMI_MAX_MSG_LENGTH) { | ||
613 | /* Received message too big, abort the operation. */ | ||
614 | result = -E2BIG; | ||
615 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
616 | pr_info("Received message too big\n"); | ||
617 | |||
618 | goto continue_op; | ||
619 | } | ||
620 | |||
621 | /* Remove the blocknum from the data. */ | ||
622 | for (i = 0; i < (len-1); i++) | ||
623 | ssif_info->data[i+ssif_info->multi_len] = data[i+1]; | ||
624 | len--; | ||
625 | ssif_info->multi_len += len; | ||
626 | if (blocknum == 0xff) { | ||
627 | /* End of read */ | ||
628 | len = ssif_info->multi_len; | ||
629 | data = ssif_info->data; | ||
630 | } else if ((blocknum+1) != ssif_info->multi_pos) { | ||
631 | /* | ||
632 | * Out of sequence block, just abort. Block | ||
633 | * numbers start at zero for the second block, | ||
634 | * but multi_pos starts at one, so the +1. | ||
635 | */ | ||
636 | result = -EIO; | ||
637 | } else { | ||
638 | ssif_inc_stat(ssif_info, received_message_parts); | ||
639 | |||
640 | ssif_info->multi_pos++; | ||
641 | |||
642 | rv = ssif_i2c_send(ssif_info, msg_done_handler, | ||
643 | I2C_SMBUS_READ, | ||
644 | SSIF_IPMI_MULTI_PART_RESPONSE_MIDDLE, | ||
645 | ssif_info->recv, | ||
646 | I2C_SMBUS_BLOCK_DATA); | ||
647 | if (rv < 0) { | ||
648 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
649 | pr_info(PFX | ||
650 | "Error from i2c_non_blocking_op(2)\n"); | ||
651 | |||
652 | result = -EIO; | ||
653 | } else | ||
654 | return; | ||
655 | } | ||
656 | } | ||
657 | |||
658 | if (result < 0) { | ||
659 | ssif_inc_stat(ssif_info, receive_errors); | ||
660 | } else { | ||
661 | ssif_inc_stat(ssif_info, received_messages); | ||
662 | ssif_inc_stat(ssif_info, received_message_parts); | ||
663 | } | ||
664 | |||
665 | |||
666 | continue_op: | ||
667 | if (ssif_info->ssif_debug & SSIF_DEBUG_STATE) | ||
668 | pr_info(PFX "DONE 1: state = %d, result=%d.\n", | ||
669 | ssif_info->ssif_state, result); | ||
670 | |||
671 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
672 | msg = ssif_info->curr_msg; | ||
673 | if (msg) { | ||
674 | msg->rsp_size = len; | ||
675 | if (msg->rsp_size > IPMI_MAX_MSG_LENGTH) | ||
676 | msg->rsp_size = IPMI_MAX_MSG_LENGTH; | ||
677 | memcpy(msg->rsp, data, msg->rsp_size); | ||
678 | ssif_info->curr_msg = NULL; | ||
679 | } | ||
680 | |||
681 | switch (ssif_info->ssif_state) { | ||
682 | case SSIF_NORMAL: | ||
683 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
684 | if (!msg) | ||
685 | break; | ||
686 | |||
687 | if (result < 0) | ||
688 | return_hosed_msg(ssif_info, msg); | ||
689 | else | ||
690 | deliver_recv_msg(ssif_info, msg); | ||
691 | break; | ||
692 | |||
693 | case SSIF_GETTING_FLAGS: | ||
694 | /* We got the flags from the SSIF, now handle them. */ | ||
695 | if ((result < 0) || (len < 4) || (data[2] != 0)) { | ||
696 | /* | ||
697 | * Error fetching flags, or invalid length, | ||
698 | * just give up for now. | ||
699 | */ | ||
700 | ssif_info->ssif_state = SSIF_NORMAL; | ||
701 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
702 | pr_warn(PFX "Error getting flags: %d %d, %x\n", | ||
703 | result, len, data[2]); | ||
704 | } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 | ||
705 | || data[1] != IPMI_GET_MSG_FLAGS_CMD) { | ||
706 | pr_warn(PFX "Invalid response getting flags: %x %x\n", | ||
707 | data[0], data[1]); | ||
708 | } else { | ||
709 | ssif_inc_stat(ssif_info, flag_fetches); | ||
710 | ssif_info->msg_flags = data[3]; | ||
711 | handle_flags(ssif_info, flags); | ||
712 | } | ||
713 | break; | ||
714 | |||
715 | case SSIF_CLEARING_FLAGS: | ||
716 | /* We cleared the flags. */ | ||
717 | if ((result < 0) || (len < 3) || (data[2] != 0)) { | ||
718 | /* Error clearing flags */ | ||
719 | pr_warn(PFX "Error clearing flags: %d %d, %x\n", | ||
720 | result, len, data[2]); | ||
721 | } else if (data[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 | ||
722 | || data[1] != IPMI_CLEAR_MSG_FLAGS_CMD) { | ||
723 | pr_warn(PFX "Invalid response clearing flags: %x %x\n", | ||
724 | data[0], data[1]); | ||
725 | } | ||
726 | ssif_info->ssif_state = SSIF_NORMAL; | ||
727 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
728 | break; | ||
729 | |||
730 | case SSIF_GETTING_EVENTS: | ||
731 | if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { | ||
732 | /* Error getting event, probably done. */ | ||
733 | msg->done(msg); | ||
734 | |||
735 | /* Take off the event flag. */ | ||
736 | ssif_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; | ||
737 | handle_flags(ssif_info, flags); | ||
738 | } else if (msg->rsp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 | ||
739 | || msg->rsp[1] != IPMI_READ_EVENT_MSG_BUFFER_CMD) { | ||
740 | pr_warn(PFX "Invalid response getting events: %x %x\n", | ||
741 | msg->rsp[0], msg->rsp[1]); | ||
742 | msg->done(msg); | ||
743 | /* Take off the event flag. */ | ||
744 | ssif_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL; | ||
745 | handle_flags(ssif_info, flags); | ||
746 | } else { | ||
747 | handle_flags(ssif_info, flags); | ||
748 | ssif_inc_stat(ssif_info, events); | ||
749 | deliver_recv_msg(ssif_info, msg); | ||
750 | } | ||
751 | break; | ||
752 | |||
753 | case SSIF_GETTING_MESSAGES: | ||
754 | if ((result < 0) || (len < 3) || (msg->rsp[2] != 0)) { | ||
755 | /* Error getting event, probably done. */ | ||
756 | msg->done(msg); | ||
757 | |||
758 | /* Take off the msg flag. */ | ||
759 | ssif_info->msg_flags &= ~RECEIVE_MSG_AVAIL; | ||
760 | handle_flags(ssif_info, flags); | ||
761 | } else if (msg->rsp[0] != (IPMI_NETFN_APP_REQUEST | 1) << 2 | ||
762 | || msg->rsp[1] != IPMI_GET_MSG_CMD) { | ||
763 | pr_warn(PFX "Invalid response clearing flags: %x %x\n", | ||
764 | msg->rsp[0], msg->rsp[1]); | ||
765 | msg->done(msg); | ||
766 | |||
767 | /* Take off the msg flag. */ | ||
768 | ssif_info->msg_flags &= ~RECEIVE_MSG_AVAIL; | ||
769 | handle_flags(ssif_info, flags); | ||
770 | } else { | ||
771 | ssif_inc_stat(ssif_info, incoming_messages); | ||
772 | handle_flags(ssif_info, flags); | ||
773 | deliver_recv_msg(ssif_info, msg); | ||
774 | } | ||
775 | break; | ||
776 | } | ||
777 | |||
778 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
779 | if (SSIF_IDLE(ssif_info) && !ssif_info->stopping) { | ||
780 | if (ssif_info->req_events) | ||
781 | start_event_fetch(ssif_info, flags); | ||
782 | else if (ssif_info->req_flags) | ||
783 | start_flag_fetch(ssif_info, flags); | ||
784 | else | ||
785 | start_next_msg(ssif_info, flags); | ||
786 | } else | ||
787 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
788 | |||
789 | if (ssif_info->ssif_debug & SSIF_DEBUG_STATE) | ||
790 | pr_info(PFX "DONE 2: state = %d.\n", ssif_info->ssif_state); | ||
791 | } | ||
792 | |||
793 | static void msg_written_handler(struct ssif_info *ssif_info, int result, | ||
794 | unsigned char *data, unsigned int len) | ||
795 | { | ||
796 | int rv; | ||
797 | |||
798 | /* We are single-threaded here, so no need for a lock. */ | ||
799 | if (result < 0) { | ||
800 | ssif_info->retries_left--; | ||
801 | if (ssif_info->retries_left > 0) { | ||
802 | if (!start_resend(ssif_info)) { | ||
803 | ssif_inc_stat(ssif_info, send_retries); | ||
804 | return; | ||
805 | } | ||
806 | /* request failed, just return the error. */ | ||
807 | ssif_inc_stat(ssif_info, send_errors); | ||
808 | |||
809 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
810 | pr_info(PFX | ||
811 | "Out of retries in msg_written_handler\n"); | ||
812 | msg_done_handler(ssif_info, -EIO, NULL, 0); | ||
813 | return; | ||
814 | } | ||
815 | |||
816 | ssif_inc_stat(ssif_info, send_errors); | ||
817 | |||
818 | /* | ||
819 | * Got an error on transmit, let the done routine | ||
820 | * handle it. | ||
821 | */ | ||
822 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
823 | pr_info("Error in msg_written_handler: %d\n", result); | ||
824 | |||
825 | msg_done_handler(ssif_info, result, NULL, 0); | ||
826 | return; | ||
827 | } | ||
828 | |||
829 | if (ssif_info->multi_data) { | ||
830 | /* In the middle of a multi-data write. */ | ||
831 | int left; | ||
832 | |||
833 | ssif_inc_stat(ssif_info, sent_messages_parts); | ||
834 | |||
835 | left = ssif_info->multi_len - ssif_info->multi_pos; | ||
836 | if (left > 32) | ||
837 | left = 32; | ||
838 | /* Length byte. */ | ||
839 | ssif_info->multi_data[ssif_info->multi_pos] = left; | ||
840 | ssif_info->multi_pos += left; | ||
841 | if (left < 32) | ||
842 | /* | ||
843 | * Write is finished. Note that we must end | ||
844 | * with a write of less than 32 bytes to | ||
845 | * complete the transaction, even if it is | ||
846 | * zero bytes. | ||
847 | */ | ||
848 | ssif_info->multi_data = NULL; | ||
849 | |||
850 | rv = ssif_i2c_send(ssif_info, msg_written_handler, | ||
851 | I2C_SMBUS_WRITE, | ||
852 | SSIF_IPMI_MULTI_PART_REQUEST_MIDDLE, | ||
853 | ssif_info->multi_data + ssif_info->multi_pos, | ||
854 | I2C_SMBUS_BLOCK_DATA); | ||
855 | if (rv < 0) { | ||
856 | /* request failed, just return the error. */ | ||
857 | ssif_inc_stat(ssif_info, send_errors); | ||
858 | |||
859 | if (ssif_info->ssif_debug & SSIF_DEBUG_MSG) | ||
860 | pr_info("Error from i2c_non_blocking_op(3)\n"); | ||
861 | msg_done_handler(ssif_info, -EIO, NULL, 0); | ||
862 | } | ||
863 | } else { | ||
864 | ssif_inc_stat(ssif_info, sent_messages); | ||
865 | ssif_inc_stat(ssif_info, sent_messages_parts); | ||
866 | |||
867 | /* Wait a jiffie then request the next message */ | ||
868 | ssif_info->retries_left = SSIF_RECV_RETRIES; | ||
869 | ssif_info->rtc_us_timer = SSIF_MSG_PART_USEC; | ||
870 | mod_timer(&ssif_info->retry_timer, | ||
871 | jiffies + SSIF_MSG_PART_JIFFIES); | ||
872 | return; | ||
873 | } | ||
874 | } | ||
875 | |||
876 | static int start_resend(struct ssif_info *ssif_info) | ||
877 | { | ||
878 | int rv; | ||
879 | int command; | ||
880 | |||
881 | if (ssif_info->data_len > 32) { | ||
882 | command = SSIF_IPMI_MULTI_PART_REQUEST_START; | ||
883 | ssif_info->multi_data = ssif_info->data; | ||
884 | ssif_info->multi_len = ssif_info->data_len; | ||
885 | /* | ||
886 | * Subtle thing, this is 32, not 33, because we will | ||
887 | * overwrite the thing at position 32 (which was just | ||
888 | * transmitted) with the new length. | ||
889 | */ | ||
890 | ssif_info->multi_pos = 32; | ||
891 | ssif_info->data[0] = 32; | ||
892 | } else { | ||
893 | ssif_info->multi_data = NULL; | ||
894 | command = SSIF_IPMI_REQUEST; | ||
895 | ssif_info->data[0] = ssif_info->data_len; | ||
896 | } | ||
897 | |||
898 | rv = ssif_i2c_send(ssif_info, msg_written_handler, I2C_SMBUS_WRITE, | ||
899 | command, ssif_info->data, I2C_SMBUS_BLOCK_DATA); | ||
900 | if (rv && (ssif_info->ssif_debug & SSIF_DEBUG_MSG)) | ||
901 | pr_info("Error from i2c_non_blocking_op(4)\n"); | ||
902 | return rv; | ||
903 | } | ||
904 | |||
905 | static int start_send(struct ssif_info *ssif_info, | ||
906 | unsigned char *data, | ||
907 | unsigned int len) | ||
908 | { | ||
909 | if (len > IPMI_MAX_MSG_LENGTH) | ||
910 | return -E2BIG; | ||
911 | if (len > ssif_info->max_xmit_msg_size) | ||
912 | return -E2BIG; | ||
913 | |||
914 | ssif_info->retries_left = SSIF_SEND_RETRIES; | ||
915 | memcpy(ssif_info->data+1, data, len); | ||
916 | ssif_info->data_len = len; | ||
917 | return start_resend(ssif_info); | ||
918 | } | ||
919 | |||
920 | /* Must be called with the message lock held. */ | ||
921 | static void start_next_msg(struct ssif_info *ssif_info, unsigned long *flags) | ||
922 | { | ||
923 | struct ipmi_smi_msg *msg; | ||
924 | unsigned long oflags; | ||
925 | |||
926 | restart: | ||
927 | if (!SSIF_IDLE(ssif_info)) { | ||
928 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
929 | return; | ||
930 | } | ||
931 | |||
932 | if (!ssif_info->waiting_msg) { | ||
933 | ssif_info->curr_msg = NULL; | ||
934 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
935 | } else { | ||
936 | int rv; | ||
937 | |||
938 | ssif_info->curr_msg = ssif_info->waiting_msg; | ||
939 | ssif_info->waiting_msg = NULL; | ||
940 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
941 | rv = start_send(ssif_info, | ||
942 | ssif_info->curr_msg->data, | ||
943 | ssif_info->curr_msg->data_size); | ||
944 | if (rv) { | ||
945 | msg = ssif_info->curr_msg; | ||
946 | ssif_info->curr_msg = NULL; | ||
947 | return_hosed_msg(ssif_info, msg); | ||
948 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
949 | goto restart; | ||
950 | } | ||
951 | } | ||
952 | } | ||
953 | |||
954 | static void sender(void *send_info, | ||
955 | struct ipmi_smi_msg *msg) | ||
956 | { | ||
957 | struct ssif_info *ssif_info = (struct ssif_info *) send_info; | ||
958 | unsigned long oflags, *flags; | ||
959 | |||
960 | BUG_ON(ssif_info->waiting_msg); | ||
961 | ssif_info->waiting_msg = msg; | ||
962 | |||
963 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
964 | start_next_msg(ssif_info, flags); | ||
965 | |||
966 | if (ssif_info->ssif_debug & SSIF_DEBUG_TIMING) { | ||
967 | struct timeval t; | ||
968 | |||
969 | do_gettimeofday(&t); | ||
970 | pr_info("**Enqueue %02x %02x: %ld.%6.6ld\n", | ||
971 | msg->data[0], msg->data[1], t.tv_sec, t.tv_usec); | ||
972 | } | ||
973 | } | ||
974 | |||
975 | static int get_smi_info(void *send_info, struct ipmi_smi_info *data) | ||
976 | { | ||
977 | struct ssif_info *ssif_info = send_info; | ||
978 | |||
979 | data->addr_src = ssif_info->addr_source; | ||
980 | data->dev = &ssif_info->client->dev; | ||
981 | data->addr_info = ssif_info->addr_info; | ||
982 | get_device(data->dev); | ||
983 | |||
984 | return 0; | ||
985 | } | ||
986 | |||
987 | /* | ||
988 | * Instead of having our own timer to periodically check the message | ||
989 | * flags, we let the message handler drive us. | ||
990 | */ | ||
991 | static void request_events(void *send_info) | ||
992 | { | ||
993 | struct ssif_info *ssif_info = (struct ssif_info *) send_info; | ||
994 | unsigned long oflags, *flags; | ||
995 | |||
996 | if (!ssif_info->has_event_buffer) | ||
997 | return; | ||
998 | |||
999 | flags = ipmi_ssif_lock_cond(ssif_info, &oflags); | ||
1000 | /* | ||
1001 | * Request flags first, not events, because the lower layer | ||
1002 | * doesn't have a way to send an attention. But make sure | ||
1003 | * event checking still happens. | ||
1004 | */ | ||
1005 | ssif_info->req_events = true; | ||
1006 | if (SSIF_IDLE(ssif_info)) | ||
1007 | start_flag_fetch(ssif_info, flags); | ||
1008 | else { | ||
1009 | ssif_info->req_flags = true; | ||
1010 | ipmi_ssif_unlock_cond(ssif_info, flags); | ||
1011 | } | ||
1012 | } | ||
1013 | |||
1014 | static int inc_usecount(void *send_info) | ||
1015 | { | ||
1016 | struct ssif_info *ssif_info = send_info; | ||
1017 | |||
1018 | if (!i2c_get_adapter(ssif_info->client->adapter->nr)) | ||
1019 | return -ENODEV; | ||
1020 | |||
1021 | i2c_use_client(ssif_info->client); | ||
1022 | return 0; | ||
1023 | } | ||
1024 | |||
1025 | static void dec_usecount(void *send_info) | ||
1026 | { | ||
1027 | struct ssif_info *ssif_info = send_info; | ||
1028 | |||
1029 | i2c_release_client(ssif_info->client); | ||
1030 | i2c_put_adapter(ssif_info->client->adapter); | ||
1031 | } | ||
1032 | |||
1033 | static int ssif_start_processing(void *send_info, | ||
1034 | ipmi_smi_t intf) | ||
1035 | { | ||
1036 | struct ssif_info *ssif_info = send_info; | ||
1037 | |||
1038 | ssif_info->intf = intf; | ||
1039 | |||
1040 | return 0; | ||
1041 | } | ||
1042 | |||
1043 | #define MAX_SSIF_BMCS 4 | ||
1044 | |||
1045 | static unsigned short addr[MAX_SSIF_BMCS]; | ||
1046 | static int num_addrs; | ||
1047 | module_param_array(addr, ushort, &num_addrs, 0); | ||
1048 | MODULE_PARM_DESC(addr, "The addresses to scan for IPMI BMCs on the SSIFs."); | ||
1049 | |||
1050 | static char *adapter_name[MAX_SSIF_BMCS]; | ||
1051 | static int num_adapter_names; | ||
1052 | module_param_array(adapter_name, charp, &num_adapter_names, 0); | ||
1053 | MODULE_PARM_DESC(adapter_name, "The string name of the I2C device that has the BMC. By default all devices are scanned."); | ||
1054 | |||
1055 | static int slave_addrs[MAX_SSIF_BMCS]; | ||
1056 | static int num_slave_addrs; | ||
1057 | module_param_array(slave_addrs, int, &num_slave_addrs, 0); | ||
1058 | MODULE_PARM_DESC(slave_addrs, | ||
1059 | "The default IPMB slave address for the controller."); | ||
1060 | |||
1061 | /* | ||
1062 | * Bit 0 enables message debugging, bit 1 enables state debugging, and | ||
1063 | * bit 2 enables timing debugging. This is an array indexed by | ||
1064 | * interface number" | ||
1065 | */ | ||
1066 | static int dbg[MAX_SSIF_BMCS]; | ||
1067 | static int num_dbg; | ||
1068 | module_param_array(dbg, int, &num_dbg, 0); | ||
1069 | MODULE_PARM_DESC(dbg, "Turn on debugging."); | ||
1070 | |||
1071 | static bool ssif_dbg_probe; | ||
1072 | module_param_named(dbg_probe, ssif_dbg_probe, bool, 0); | ||
1073 | MODULE_PARM_DESC(dbg_probe, "Enable debugging of probing of adapters."); | ||
1074 | |||
1075 | static int use_thread; | ||
1076 | module_param(use_thread, int, 0); | ||
1077 | MODULE_PARM_DESC(use_thread, "Use the thread interface."); | ||
1078 | |||
1079 | static bool ssif_tryacpi = 1; | ||
1080 | module_param_named(tryacpi, ssif_tryacpi, bool, 0); | ||
1081 | MODULE_PARM_DESC(tryacpi, "Setting this to zero will disable the default scan of the interfaces identified via ACPI"); | ||
1082 | |||
1083 | static bool ssif_trydmi = 1; | ||
1084 | module_param_named(trydmi, ssif_trydmi, bool, 0); | ||
1085 | MODULE_PARM_DESC(trydmi, "Setting this to zero will disable the default scan of the interfaces identified via DMI (SMBIOS)"); | ||
1086 | |||
1087 | static DEFINE_MUTEX(ssif_infos_mutex); | ||
1088 | static LIST_HEAD(ssif_infos); | ||
1089 | |||
1090 | static int ssif_remove(struct i2c_client *client) | ||
1091 | { | ||
1092 | struct ssif_info *ssif_info = i2c_get_clientdata(client); | ||
1093 | int rv; | ||
1094 | |||
1095 | if (!ssif_info) | ||
1096 | return 0; | ||
1097 | |||
1098 | i2c_set_clientdata(client, NULL); | ||
1099 | |||
1100 | /* | ||
1101 | * After this point, we won't deliver anything asychronously | ||
1102 | * to the message handler. We can unregister ourself. | ||
1103 | */ | ||
1104 | rv = ipmi_unregister_smi(ssif_info->intf); | ||
1105 | if (rv) { | ||
1106 | pr_err(PFX "Unable to unregister device: errno=%d\n", rv); | ||
1107 | return rv; | ||
1108 | } | ||
1109 | ssif_info->intf = NULL; | ||
1110 | |||
1111 | /* make sure the driver is not looking for flags any more. */ | ||
1112 | while (ssif_info->ssif_state != SSIF_NORMAL) | ||
1113 | schedule_timeout(1); | ||
1114 | |||
1115 | ssif_info->stopping = true; | ||
1116 | del_timer_sync(&ssif_info->retry_timer); | ||
1117 | if (ssif_info->thread) { | ||
1118 | complete(&ssif_info->wake_thread); | ||
1119 | kthread_stop(ssif_info->thread); | ||
1120 | } | ||
1121 | |||
1122 | /* | ||
1123 | * No message can be outstanding now, we have removed the | ||
1124 | * upper layer and it permitted us to do so. | ||
1125 | */ | ||
1126 | kfree(ssif_info); | ||
1127 | return 0; | ||
1128 | } | ||
1129 | |||
1130 | static int do_cmd(struct i2c_client *client, int len, unsigned char *msg, | ||
1131 | int *resp_len, unsigned char *resp) | ||
1132 | { | ||
1133 | int retry_cnt; | ||
1134 | int ret; | ||
1135 | |||
1136 | retry_cnt = SSIF_SEND_RETRIES; | ||
1137 | retry1: | ||
1138 | ret = i2c_smbus_write_block_data(client, SSIF_IPMI_REQUEST, len, msg); | ||
1139 | if (ret) { | ||
1140 | retry_cnt--; | ||
1141 | if (retry_cnt > 0) | ||
1142 | goto retry1; | ||
1143 | return -ENODEV; | ||
1144 | } | ||
1145 | |||
1146 | ret = -ENODEV; | ||
1147 | retry_cnt = SSIF_RECV_RETRIES; | ||
1148 | while (retry_cnt > 0) { | ||
1149 | ret = i2c_smbus_read_block_data(client, SSIF_IPMI_RESPONSE, | ||
1150 | resp); | ||
1151 | if (ret > 0) | ||
1152 | break; | ||
1153 | msleep(SSIF_MSG_MSEC); | ||
1154 | retry_cnt--; | ||
1155 | if (retry_cnt <= 0) | ||
1156 | break; | ||
1157 | } | ||
1158 | |||
1159 | if (ret > 0) { | ||
1160 | /* Validate that the response is correct. */ | ||
1161 | if (ret < 3 || | ||
1162 | (resp[0] != (msg[0] | (1 << 2))) || | ||
1163 | (resp[1] != msg[1])) | ||
1164 | ret = -EINVAL; | ||
1165 | else { | ||
1166 | *resp_len = ret; | ||
1167 | ret = 0; | ||
1168 | } | ||
1169 | } | ||
1170 | |||
1171 | return ret; | ||
1172 | } | ||
1173 | |||
1174 | static int ssif_detect(struct i2c_client *client, struct i2c_board_info *info) | ||
1175 | { | ||
1176 | unsigned char *resp; | ||
1177 | unsigned char msg[3]; | ||
1178 | int rv; | ||
1179 | int len; | ||
1180 | |||
1181 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | ||
1182 | if (!resp) | ||
1183 | return -ENOMEM; | ||
1184 | |||
1185 | /* Do a Get Device ID command, since it is required. */ | ||
1186 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
1187 | msg[1] = IPMI_GET_DEVICE_ID_CMD; | ||
1188 | rv = do_cmd(client, 2, msg, &len, resp); | ||
1189 | if (rv) | ||
1190 | rv = -ENODEV; | ||
1191 | else | ||
1192 | strlcpy(info->type, DEVICE_NAME, I2C_NAME_SIZE); | ||
1193 | kfree(resp); | ||
1194 | return rv; | ||
1195 | } | ||
1196 | |||
1197 | static int smi_type_proc_show(struct seq_file *m, void *v) | ||
1198 | { | ||
1199 | return seq_puts(m, "ssif\n"); | ||
1200 | } | ||
1201 | |||
1202 | static int smi_type_proc_open(struct inode *inode, struct file *file) | ||
1203 | { | ||
1204 | return single_open(file, smi_type_proc_show, inode->i_private); | ||
1205 | } | ||
1206 | |||
1207 | static const struct file_operations smi_type_proc_ops = { | ||
1208 | .open = smi_type_proc_open, | ||
1209 | .read = seq_read, | ||
1210 | .llseek = seq_lseek, | ||
1211 | .release = single_release, | ||
1212 | }; | ||
1213 | |||
1214 | static int smi_stats_proc_show(struct seq_file *m, void *v) | ||
1215 | { | ||
1216 | struct ssif_info *ssif_info = m->private; | ||
1217 | |||
1218 | seq_printf(m, "sent_messages: %u\n", | ||
1219 | ssif_get_stat(ssif_info, sent_messages)); | ||
1220 | seq_printf(m, "sent_messages_parts: %u\n", | ||
1221 | ssif_get_stat(ssif_info, sent_messages_parts)); | ||
1222 | seq_printf(m, "send_retries: %u\n", | ||
1223 | ssif_get_stat(ssif_info, send_retries)); | ||
1224 | seq_printf(m, "send_errors: %u\n", | ||
1225 | ssif_get_stat(ssif_info, send_errors)); | ||
1226 | seq_printf(m, "received_messages: %u\n", | ||
1227 | ssif_get_stat(ssif_info, received_messages)); | ||
1228 | seq_printf(m, "received_message_parts: %u\n", | ||
1229 | ssif_get_stat(ssif_info, received_message_parts)); | ||
1230 | seq_printf(m, "receive_retries: %u\n", | ||
1231 | ssif_get_stat(ssif_info, receive_retries)); | ||
1232 | seq_printf(m, "receive_errors: %u\n", | ||
1233 | ssif_get_stat(ssif_info, receive_errors)); | ||
1234 | seq_printf(m, "flag_fetches: %u\n", | ||
1235 | ssif_get_stat(ssif_info, flag_fetches)); | ||
1236 | seq_printf(m, "hosed: %u\n", | ||
1237 | ssif_get_stat(ssif_info, hosed)); | ||
1238 | seq_printf(m, "events: %u\n", | ||
1239 | ssif_get_stat(ssif_info, events)); | ||
1240 | seq_printf(m, "watchdog_pretimeouts: %u\n", | ||
1241 | ssif_get_stat(ssif_info, watchdog_pretimeouts)); | ||
1242 | return 0; | ||
1243 | } | ||
1244 | |||
1245 | static int smi_stats_proc_open(struct inode *inode, struct file *file) | ||
1246 | { | ||
1247 | return single_open(file, smi_stats_proc_show, PDE_DATA(inode)); | ||
1248 | } | ||
1249 | |||
1250 | static const struct file_operations smi_stats_proc_ops = { | ||
1251 | .open = smi_stats_proc_open, | ||
1252 | .read = seq_read, | ||
1253 | .llseek = seq_lseek, | ||
1254 | .release = single_release, | ||
1255 | }; | ||
1256 | |||
1257 | static struct ssif_addr_info *ssif_info_find(unsigned short addr, | ||
1258 | char *adapter_name, | ||
1259 | bool match_null_name) | ||
1260 | { | ||
1261 | struct ssif_addr_info *info, *found = NULL; | ||
1262 | |||
1263 | restart: | ||
1264 | list_for_each_entry(info, &ssif_infos, link) { | ||
1265 | if (info->binfo.addr == addr) { | ||
1266 | if (info->adapter_name || adapter_name) { | ||
1267 | if (!info->adapter_name != !adapter_name) { | ||
1268 | /* One is NULL and one is not */ | ||
1269 | continue; | ||
1270 | } | ||
1271 | if (strcmp(info->adapter_name, adapter_name)) | ||
1272 | /* Names to not match */ | ||
1273 | continue; | ||
1274 | } | ||
1275 | found = info; | ||
1276 | break; | ||
1277 | } | ||
1278 | } | ||
1279 | |||
1280 | if (!found && match_null_name) { | ||
1281 | /* Try to get an exact match first, then try with a NULL name */ | ||
1282 | adapter_name = NULL; | ||
1283 | match_null_name = false; | ||
1284 | goto restart; | ||
1285 | } | ||
1286 | |||
1287 | return found; | ||
1288 | } | ||
1289 | |||
1290 | static bool check_acpi(struct ssif_info *ssif_info, struct device *dev) | ||
1291 | { | ||
1292 | #ifdef CONFIG_ACPI | ||
1293 | acpi_handle acpi_handle; | ||
1294 | |||
1295 | acpi_handle = ACPI_HANDLE(dev); | ||
1296 | if (acpi_handle) { | ||
1297 | ssif_info->addr_source = SI_ACPI; | ||
1298 | ssif_info->addr_info.acpi_info.acpi_handle = acpi_handle; | ||
1299 | return true; | ||
1300 | } | ||
1301 | #endif | ||
1302 | return false; | ||
1303 | } | ||
1304 | |||
1305 | static int ssif_probe(struct i2c_client *client, const struct i2c_device_id *id) | ||
1306 | { | ||
1307 | unsigned char msg[3]; | ||
1308 | unsigned char *resp; | ||
1309 | struct ssif_info *ssif_info; | ||
1310 | int rv = 0; | ||
1311 | int len; | ||
1312 | int i; | ||
1313 | u8 slave_addr = 0; | ||
1314 | struct ssif_addr_info *addr_info = NULL; | ||
1315 | |||
1316 | |||
1317 | resp = kmalloc(IPMI_MAX_MSG_LENGTH, GFP_KERNEL); | ||
1318 | if (!resp) | ||
1319 | return -ENOMEM; | ||
1320 | |||
1321 | ssif_info = kzalloc(sizeof(*ssif_info), GFP_KERNEL); | ||
1322 | if (!ssif_info) { | ||
1323 | kfree(resp); | ||
1324 | return -ENOMEM; | ||
1325 | } | ||
1326 | |||
1327 | if (!check_acpi(ssif_info, &client->dev)) { | ||
1328 | addr_info = ssif_info_find(client->addr, client->adapter->name, | ||
1329 | true); | ||
1330 | if (!addr_info) { | ||
1331 | /* Must have come in through sysfs. */ | ||
1332 | ssif_info->addr_source = SI_HOTMOD; | ||
1333 | } else { | ||
1334 | ssif_info->addr_source = addr_info->addr_src; | ||
1335 | ssif_info->ssif_debug = addr_info->debug; | ||
1336 | ssif_info->addr_info = addr_info->addr_info; | ||
1337 | slave_addr = addr_info->slave_addr; | ||
1338 | } | ||
1339 | } | ||
1340 | |||
1341 | pr_info(PFX "Trying %s-specified SSIF interface at i2c address 0x%x, adapter %s, slave address 0x%x\n", | ||
1342 | ipmi_addr_src_to_str(ssif_info->addr_source), | ||
1343 | client->addr, client->adapter->name, slave_addr); | ||
1344 | |||
1345 | /* | ||
1346 | * Do a Get Device ID command, since it comes back with some | ||
1347 | * useful info. | ||
1348 | */ | ||
1349 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
1350 | msg[1] = IPMI_GET_DEVICE_ID_CMD; | ||
1351 | rv = do_cmd(client, 2, msg, &len, resp); | ||
1352 | if (rv) | ||
1353 | goto out; | ||
1354 | |||
1355 | rv = ipmi_demangle_device_id(resp, len, &ssif_info->device_id); | ||
1356 | if (rv) | ||
1357 | goto out; | ||
1358 | |||
1359 | ssif_info->client = client; | ||
1360 | i2c_set_clientdata(client, ssif_info); | ||
1361 | |||
1362 | /* Now check for system interface capabilities */ | ||
1363 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
1364 | msg[1] = IPMI_GET_SYSTEM_INTERFACE_CAPABILITIES_CMD; | ||
1365 | msg[2] = 0; /* SSIF */ | ||
1366 | rv = do_cmd(client, 3, msg, &len, resp); | ||
1367 | if (!rv && (len >= 3) && (resp[2] == 0)) { | ||
1368 | if (len < 7) { | ||
1369 | if (ssif_dbg_probe) | ||
1370 | pr_info(PFX "SSIF info too short: %d\n", len); | ||
1371 | goto no_support; | ||
1372 | } | ||
1373 | |||
1374 | /* Got a good SSIF response, handle it. */ | ||
1375 | ssif_info->max_xmit_msg_size = resp[5]; | ||
1376 | ssif_info->max_recv_msg_size = resp[6]; | ||
1377 | ssif_info->multi_support = (resp[4] >> 6) & 0x3; | ||
1378 | ssif_info->supports_pec = (resp[4] >> 3) & 0x1; | ||
1379 | |||
1380 | /* Sanitize the data */ | ||
1381 | switch (ssif_info->multi_support) { | ||
1382 | case SSIF_NO_MULTI: | ||
1383 | if (ssif_info->max_xmit_msg_size > 32) | ||
1384 | ssif_info->max_xmit_msg_size = 32; | ||
1385 | if (ssif_info->max_recv_msg_size > 32) | ||
1386 | ssif_info->max_recv_msg_size = 32; | ||
1387 | break; | ||
1388 | |||
1389 | case SSIF_MULTI_2_PART: | ||
1390 | if (ssif_info->max_xmit_msg_size > 64) | ||
1391 | ssif_info->max_xmit_msg_size = 64; | ||
1392 | if (ssif_info->max_recv_msg_size > 62) | ||
1393 | ssif_info->max_recv_msg_size = 62; | ||
1394 | break; | ||
1395 | |||
1396 | case SSIF_MULTI_n_PART: | ||
1397 | break; | ||
1398 | |||
1399 | default: | ||
1400 | /* Data is not sane, just give up. */ | ||
1401 | goto no_support; | ||
1402 | } | ||
1403 | } else { | ||
1404 | no_support: | ||
1405 | /* Assume no multi-part or PEC support */ | ||
1406 | pr_info(PFX "Error fetching SSIF: %d %d %2.2x, your system probably doesn't support this command so using defaults\n", | ||
1407 | rv, len, resp[2]); | ||
1408 | |||
1409 | ssif_info->max_xmit_msg_size = 32; | ||
1410 | ssif_info->max_recv_msg_size = 32; | ||
1411 | ssif_info->multi_support = SSIF_NO_MULTI; | ||
1412 | ssif_info->supports_pec = 0; | ||
1413 | } | ||
1414 | |||
1415 | /* Make sure the NMI timeout is cleared. */ | ||
1416 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
1417 | msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD; | ||
1418 | msg[2] = WDT_PRE_TIMEOUT_INT; | ||
1419 | rv = do_cmd(client, 3, msg, &len, resp); | ||
1420 | if (rv || (len < 3) || (resp[2] != 0)) | ||
1421 | pr_warn(PFX "Unable to clear message flags: %d %d %2.2x\n", | ||
1422 | rv, len, resp[2]); | ||
1423 | |||
1424 | /* Attempt to enable the event buffer. */ | ||
1425 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
1426 | msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD; | ||
1427 | rv = do_cmd(client, 2, msg, &len, resp); | ||
1428 | if (rv || (len < 4) || (resp[2] != 0)) { | ||
1429 | pr_warn(PFX "Error getting global enables: %d %d %2.2x\n", | ||
1430 | rv, len, resp[2]); | ||
1431 | rv = 0; /* Not fatal */ | ||
1432 | goto found; | ||
1433 | } | ||
1434 | |||
1435 | if (resp[3] & IPMI_BMC_EVT_MSG_BUFF) { | ||
1436 | ssif_info->has_event_buffer = true; | ||
1437 | /* buffer is already enabled, nothing to do. */ | ||
1438 | goto found; | ||
1439 | } | ||
1440 | |||
1441 | msg[0] = IPMI_NETFN_APP_REQUEST << 2; | ||
1442 | msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD; | ||
1443 | msg[2] = resp[3] | IPMI_BMC_EVT_MSG_BUFF; | ||
1444 | rv = do_cmd(client, 3, msg, &len, resp); | ||
1445 | if (rv || (len < 2)) { | ||
1446 | pr_warn(PFX "Error getting global enables: %d %d %2.2x\n", | ||
1447 | rv, len, resp[2]); | ||
1448 | rv = 0; /* Not fatal */ | ||
1449 | goto found; | ||
1450 | } | ||
1451 | |||
1452 | if (resp[2] == 0) | ||
1453 | /* A successful return means the event buffer is supported. */ | ||
1454 | ssif_info->has_event_buffer = true; | ||
1455 | |||
1456 | found: | ||
1457 | ssif_info->intf_num = atomic_inc_return(&next_intf); | ||
1458 | |||
1459 | if (ssif_dbg_probe) { | ||
1460 | pr_info("ssif_probe: i2c_probe found device at i2c address %x\n", | ||
1461 | client->addr); | ||
1462 | } | ||
1463 | |||
1464 | spin_lock_init(&ssif_info->lock); | ||
1465 | ssif_info->ssif_state = SSIF_NORMAL; | ||
1466 | init_timer(&ssif_info->retry_timer); | ||
1467 | ssif_info->retry_timer.data = (unsigned long) ssif_info; | ||
1468 | ssif_info->retry_timer.function = retry_timeout; | ||
1469 | |||
1470 | for (i = 0; i < SSIF_NUM_STATS; i++) | ||
1471 | atomic_set(&ssif_info->stats[i], 0); | ||
1472 | |||
1473 | if (ssif_info->supports_pec) | ||
1474 | ssif_info->client->flags |= I2C_CLIENT_PEC; | ||
1475 | |||
1476 | ssif_info->handlers.owner = THIS_MODULE; | ||
1477 | ssif_info->handlers.start_processing = ssif_start_processing; | ||
1478 | ssif_info->handlers.get_smi_info = get_smi_info; | ||
1479 | ssif_info->handlers.sender = sender; | ||
1480 | ssif_info->handlers.request_events = request_events; | ||
1481 | ssif_info->handlers.inc_usecount = inc_usecount; | ||
1482 | ssif_info->handlers.dec_usecount = dec_usecount; | ||
1483 | |||
1484 | { | ||
1485 | unsigned int thread_num; | ||
1486 | |||
1487 | thread_num = ((ssif_info->client->adapter->nr << 8) | | ||
1488 | ssif_info->client->addr); | ||
1489 | init_completion(&ssif_info->wake_thread); | ||
1490 | ssif_info->thread = kthread_run(ipmi_ssif_thread, ssif_info, | ||
1491 | "kssif%4.4x", thread_num); | ||
1492 | if (IS_ERR(ssif_info->thread)) { | ||
1493 | rv = PTR_ERR(ssif_info->thread); | ||
1494 | dev_notice(&ssif_info->client->dev, | ||
1495 | "Could not start kernel thread: error %d\n", | ||
1496 | rv); | ||
1497 | goto out; | ||
1498 | } | ||
1499 | } | ||
1500 | |||
1501 | rv = ipmi_register_smi(&ssif_info->handlers, | ||
1502 | ssif_info, | ||
1503 | &ssif_info->device_id, | ||
1504 | &ssif_info->client->dev, | ||
1505 | slave_addr); | ||
1506 | if (rv) { | ||
1507 | pr_err(PFX "Unable to register device: error %d\n", rv); | ||
1508 | goto out; | ||
1509 | } | ||
1510 | |||
1511 | rv = ipmi_smi_add_proc_entry(ssif_info->intf, "type", | ||
1512 | &smi_type_proc_ops, | ||
1513 | ssif_info); | ||
1514 | if (rv) { | ||
1515 | pr_err(PFX "Unable to create proc entry: %d\n", rv); | ||
1516 | goto out_err_unreg; | ||
1517 | } | ||
1518 | |||
1519 | rv = ipmi_smi_add_proc_entry(ssif_info->intf, "ssif_stats", | ||
1520 | &smi_stats_proc_ops, | ||
1521 | ssif_info); | ||
1522 | if (rv) { | ||
1523 | pr_err(PFX "Unable to create proc entry: %d\n", rv); | ||
1524 | goto out_err_unreg; | ||
1525 | } | ||
1526 | |||
1527 | out: | ||
1528 | if (rv) | ||
1529 | kfree(ssif_info); | ||
1530 | kfree(resp); | ||
1531 | return rv; | ||
1532 | |||
1533 | out_err_unreg: | ||
1534 | ipmi_unregister_smi(ssif_info->intf); | ||
1535 | goto out; | ||
1536 | } | ||
1537 | |||
1538 | static int ssif_adapter_handler(struct device *adev, void *opaque) | ||
1539 | { | ||
1540 | struct ssif_addr_info *addr_info = opaque; | ||
1541 | |||
1542 | if (adev->type != &i2c_adapter_type) | ||
1543 | return 0; | ||
1544 | |||
1545 | i2c_new_device(to_i2c_adapter(adev), &addr_info->binfo); | ||
1546 | |||
1547 | if (!addr_info->adapter_name) | ||
1548 | return 1; /* Only try the first I2C adapter by default. */ | ||
1549 | return 0; | ||
1550 | } | ||
1551 | |||
1552 | static int new_ssif_client(int addr, char *adapter_name, | ||
1553 | int debug, int slave_addr, | ||
1554 | enum ipmi_addr_src addr_src) | ||
1555 | { | ||
1556 | struct ssif_addr_info *addr_info; | ||
1557 | int rv = 0; | ||
1558 | |||
1559 | mutex_lock(&ssif_infos_mutex); | ||
1560 | if (ssif_info_find(addr, adapter_name, false)) { | ||
1561 | rv = -EEXIST; | ||
1562 | goto out_unlock; | ||
1563 | } | ||
1564 | |||
1565 | addr_info = kzalloc(sizeof(*addr_info), GFP_KERNEL); | ||
1566 | if (!addr_info) { | ||
1567 | rv = -ENOMEM; | ||
1568 | goto out_unlock; | ||
1569 | } | ||
1570 | |||
1571 | if (adapter_name) { | ||
1572 | addr_info->adapter_name = kstrdup(adapter_name, GFP_KERNEL); | ||
1573 | if (!addr_info->adapter_name) { | ||
1574 | kfree(addr_info); | ||
1575 | rv = -ENOMEM; | ||
1576 | goto out_unlock; | ||
1577 | } | ||
1578 | } | ||
1579 | |||
1580 | strncpy(addr_info->binfo.type, DEVICE_NAME, | ||
1581 | sizeof(addr_info->binfo.type)); | ||
1582 | addr_info->binfo.addr = addr; | ||
1583 | addr_info->binfo.platform_data = addr_info; | ||
1584 | addr_info->debug = debug; | ||
1585 | addr_info->slave_addr = slave_addr; | ||
1586 | addr_info->addr_src = addr_src; | ||
1587 | |||
1588 | list_add_tail(&addr_info->link, &ssif_infos); | ||
1589 | |||
1590 | if (initialized) | ||
1591 | i2c_for_each_dev(addr_info, ssif_adapter_handler); | ||
1592 | /* Otherwise address list will get it */ | ||
1593 | |||
1594 | out_unlock: | ||
1595 | mutex_unlock(&ssif_infos_mutex); | ||
1596 | return rv; | ||
1597 | } | ||
1598 | |||
1599 | static void free_ssif_clients(void) | ||
1600 | { | ||
1601 | struct ssif_addr_info *info, *tmp; | ||
1602 | |||
1603 | mutex_lock(&ssif_infos_mutex); | ||
1604 | list_for_each_entry_safe(info, tmp, &ssif_infos, link) { | ||
1605 | list_del(&info->link); | ||
1606 | kfree(info->adapter_name); | ||
1607 | kfree(info); | ||
1608 | } | ||
1609 | mutex_unlock(&ssif_infos_mutex); | ||
1610 | } | ||
1611 | |||
1612 | static unsigned short *ssif_address_list(void) | ||
1613 | { | ||
1614 | struct ssif_addr_info *info; | ||
1615 | unsigned int count = 0, i; | ||
1616 | unsigned short *address_list; | ||
1617 | |||
1618 | list_for_each_entry(info, &ssif_infos, link) | ||
1619 | count++; | ||
1620 | |||
1621 | address_list = kzalloc(sizeof(*address_list) * (count + 1), GFP_KERNEL); | ||
1622 | if (!address_list) | ||
1623 | return NULL; | ||
1624 | |||
1625 | i = 0; | ||
1626 | list_for_each_entry(info, &ssif_infos, link) { | ||
1627 | unsigned short addr = info->binfo.addr; | ||
1628 | int j; | ||
1629 | |||
1630 | for (j = 0; j < i; j++) { | ||
1631 | if (address_list[j] == addr) | ||
1632 | goto skip_addr; | ||
1633 | } | ||
1634 | address_list[i] = addr; | ||
1635 | skip_addr: | ||
1636 | i++; | ||
1637 | } | ||
1638 | address_list[i] = I2C_CLIENT_END; | ||
1639 | |||
1640 | return address_list; | ||
1641 | } | ||
1642 | |||
1643 | #ifdef CONFIG_ACPI | ||
1644 | static struct acpi_device_id ssif_acpi_match[] = { | ||
1645 | { "IPI0001", 0 }, | ||
1646 | { }, | ||
1647 | }; | ||
1648 | MODULE_DEVICE_TABLE(acpi, ssif_acpi_match); | ||
1649 | |||
1650 | /* | ||
1651 | * Once we get an ACPI failure, we don't try any more, because we go | ||
1652 | * through the tables sequentially. Once we don't find a table, there | ||
1653 | * are no more. | ||
1654 | */ | ||
1655 | static int acpi_failure; | ||
1656 | |||
1657 | /* | ||
1658 | * Defined in the IPMI 2.0 spec. | ||
1659 | */ | ||
1660 | struct SPMITable { | ||
1661 | s8 Signature[4]; | ||
1662 | u32 Length; | ||
1663 | u8 Revision; | ||
1664 | u8 Checksum; | ||
1665 | s8 OEMID[6]; | ||
1666 | s8 OEMTableID[8]; | ||
1667 | s8 OEMRevision[4]; | ||
1668 | s8 CreatorID[4]; | ||
1669 | s8 CreatorRevision[4]; | ||
1670 | u8 InterfaceType; | ||
1671 | u8 IPMIlegacy; | ||
1672 | s16 SpecificationRevision; | ||
1673 | |||
1674 | /* | ||
1675 | * Bit 0 - SCI interrupt supported | ||
1676 | * Bit 1 - I/O APIC/SAPIC | ||
1677 | */ | ||
1678 | u8 InterruptType; | ||
1679 | |||
1680 | /* | ||
1681 | * If bit 0 of InterruptType is set, then this is the SCI | ||
1682 | * interrupt in the GPEx_STS register. | ||
1683 | */ | ||
1684 | u8 GPE; | ||
1685 | |||
1686 | s16 Reserved; | ||
1687 | |||
1688 | /* | ||
1689 | * If bit 1 of InterruptType is set, then this is the I/O | ||
1690 | * APIC/SAPIC interrupt. | ||
1691 | */ | ||
1692 | u32 GlobalSystemInterrupt; | ||
1693 | |||
1694 | /* The actual register address. */ | ||
1695 | struct acpi_generic_address addr; | ||
1696 | |||
1697 | u8 UID[4]; | ||
1698 | |||
1699 | s8 spmi_id[1]; /* A '\0' terminated array starts here. */ | ||
1700 | }; | ||
1701 | |||
1702 | static int try_init_spmi(struct SPMITable *spmi) | ||
1703 | { | ||
1704 | unsigned short myaddr; | ||
1705 | |||
1706 | if (num_addrs >= MAX_SSIF_BMCS) | ||
1707 | return -1; | ||
1708 | |||
1709 | if (spmi->IPMIlegacy != 1) { | ||
1710 | pr_warn("IPMI: Bad SPMI legacy: %d\n", spmi->IPMIlegacy); | ||
1711 | return -ENODEV; | ||
1712 | } | ||
1713 | |||
1714 | if (spmi->InterfaceType != 4) | ||
1715 | return -ENODEV; | ||
1716 | |||
1717 | if (spmi->addr.space_id != ACPI_ADR_SPACE_SMBUS) { | ||
1718 | pr_warn(PFX "Invalid ACPI SSIF I/O Address type: %d\n", | ||
1719 | spmi->addr.space_id); | ||
1720 | return -EIO; | ||
1721 | } | ||
1722 | |||
1723 | myaddr = spmi->addr.address >> 1; | ||
1724 | |||
1725 | return new_ssif_client(myaddr, NULL, 0, 0, SI_SPMI); | ||
1726 | } | ||
1727 | |||
1728 | static void spmi_find_bmc(void) | ||
1729 | { | ||
1730 | acpi_status status; | ||
1731 | struct SPMITable *spmi; | ||
1732 | int i; | ||
1733 | |||
1734 | if (acpi_disabled) | ||
1735 | return; | ||
1736 | |||
1737 | if (acpi_failure) | ||
1738 | return; | ||
1739 | |||
1740 | for (i = 0; ; i++) { | ||
1741 | status = acpi_get_table(ACPI_SIG_SPMI, i+1, | ||
1742 | (struct acpi_table_header **)&spmi); | ||
1743 | if (status != AE_OK) | ||
1744 | return; | ||
1745 | |||
1746 | try_init_spmi(spmi); | ||
1747 | } | ||
1748 | } | ||
1749 | #else | ||
1750 | static void spmi_find_bmc(void) { } | ||
1751 | #endif | ||
1752 | |||
1753 | #ifdef CONFIG_DMI | ||
1754 | static int decode_dmi(const struct dmi_device *dmi_dev) | ||
1755 | { | ||
1756 | struct dmi_header *dm = dmi_dev->device_data; | ||
1757 | u8 *data = (u8 *) dm; | ||
1758 | u8 len = dm->length; | ||
1759 | unsigned short myaddr; | ||
1760 | int slave_addr; | ||
1761 | |||
1762 | if (num_addrs >= MAX_SSIF_BMCS) | ||
1763 | return -1; | ||
1764 | |||
1765 | if (len < 9) | ||
1766 | return -1; | ||
1767 | |||
1768 | if (data[0x04] != 4) /* Not SSIF */ | ||
1769 | return -1; | ||
1770 | |||
1771 | if ((data[8] >> 1) == 0) { | ||
1772 | /* | ||
1773 | * Some broken systems put the I2C address in | ||
1774 | * the slave address field. We try to | ||
1775 | * accommodate them here. | ||
1776 | */ | ||
1777 | myaddr = data[6] >> 1; | ||
1778 | slave_addr = 0; | ||
1779 | } else { | ||
1780 | myaddr = data[8] >> 1; | ||
1781 | slave_addr = data[6]; | ||
1782 | } | ||
1783 | |||
1784 | return new_ssif_client(myaddr, NULL, 0, 0, SI_SMBIOS); | ||
1785 | } | ||
1786 | |||
1787 | static void dmi_iterator(void) | ||
1788 | { | ||
1789 | const struct dmi_device *dev = NULL; | ||
1790 | |||
1791 | while ((dev = dmi_find_device(DMI_DEV_TYPE_IPMI, NULL, dev))) | ||
1792 | decode_dmi(dev); | ||
1793 | } | ||
1794 | #else | ||
1795 | static void dmi_iterator(void) { } | ||
1796 | #endif | ||
1797 | |||
1798 | static const struct i2c_device_id ssif_id[] = { | ||
1799 | { DEVICE_NAME, 0 }, | ||
1800 | { } | ||
1801 | }; | ||
1802 | MODULE_DEVICE_TABLE(i2c, ssif_id); | ||
1803 | |||
1804 | static struct i2c_driver ssif_i2c_driver = { | ||
1805 | .class = I2C_CLASS_HWMON, | ||
1806 | .driver = { | ||
1807 | .owner = THIS_MODULE, | ||
1808 | .name = DEVICE_NAME | ||
1809 | }, | ||
1810 | .probe = ssif_probe, | ||
1811 | .remove = ssif_remove, | ||
1812 | .id_table = ssif_id, | ||
1813 | .detect = ssif_detect | ||
1814 | }; | ||
1815 | |||
1816 | static int init_ipmi_ssif(void) | ||
1817 | { | ||
1818 | int i; | ||
1819 | int rv; | ||
1820 | |||
1821 | if (initialized) | ||
1822 | return 0; | ||
1823 | |||
1824 | pr_info("IPMI SSIF Interface driver\n"); | ||
1825 | |||
1826 | /* build list for i2c from addr list */ | ||
1827 | for (i = 0; i < num_addrs; i++) { | ||
1828 | rv = new_ssif_client(addr[i], adapter_name[i], | ||
1829 | dbg[i], slave_addrs[i], | ||
1830 | SI_HARDCODED); | ||
1831 | if (!rv) | ||
1832 | pr_err(PFX | ||
1833 | "Couldn't add hardcoded device at addr 0x%x\n", | ||
1834 | addr[i]); | ||
1835 | } | ||
1836 | |||
1837 | if (ssif_tryacpi) | ||
1838 | ssif_i2c_driver.driver.acpi_match_table = | ||
1839 | ACPI_PTR(ssif_acpi_match); | ||
1840 | if (ssif_trydmi) | ||
1841 | dmi_iterator(); | ||
1842 | if (ssif_tryacpi) | ||
1843 | spmi_find_bmc(); | ||
1844 | |||
1845 | ssif_i2c_driver.address_list = ssif_address_list(); | ||
1846 | |||
1847 | rv = i2c_add_driver(&ssif_i2c_driver); | ||
1848 | if (!rv) | ||
1849 | initialized = true; | ||
1850 | |||
1851 | return rv; | ||
1852 | } | ||
1853 | module_init(init_ipmi_ssif); | ||
1854 | |||
1855 | static void cleanup_ipmi_ssif(void) | ||
1856 | { | ||
1857 | if (!initialized) | ||
1858 | return; | ||
1859 | |||
1860 | initialized = false; | ||
1861 | |||
1862 | i2c_del_driver(&ssif_i2c_driver); | ||
1863 | |||
1864 | free_ssif_clients(); | ||
1865 | } | ||
1866 | module_exit(cleanup_ipmi_ssif); | ||
1867 | |||
1868 | MODULE_AUTHOR("Todd C Davis <todd.c.davis@intel.com>, Corey Minyard <minyard@acm.org>"); | ||
1869 | MODULE_DESCRIPTION("IPMI driver for management controllers on a SMBus"); | ||
1870 | MODULE_LICENSE("GPL"); | ||