]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.23-ipmi-v28.patch
- added description of djurban's branch
[packages/kernel.git] / linux-2.4.23-ipmi-v28.patch
CommitLineData
409d0572
AM
1diff -urN linux-2.4.23.org/Documentation/Configure.help linux-2.4.23/Documentation/Configure.help
2--- linux-2.4.23.org/Documentation/Configure.help 2004-01-02 23:33:09.001923647 +0100
3+++ linux-2.4.23/Documentation/Configure.help 2004-01-02 23:33:47.987823068 +0100
4@@ -4185,6 +4185,13 @@
5
6 If unsure, say N.
7
8+IPMI sockets
9+CONFIG_IPMI_SOCKET
10+ If you say Y here, you will include support for IPMI sockets;
11+ This is the better way for establishing and accessing IPMI devices.
12+
13+ If unsure, say N.
14+
15 # Choice: alphatype
16 Alpha system type
17 CONFIG_ALPHA_GENERIC
18@@ -29534,14 +29541,41 @@
19 generate an IPMI event describing the panic to each interface
20 registered with the message handler.
21
22+Generate OEM events containing the panic string
23+CONFIG_IPMI_PANIC_STRING
24+ When a panic occurs, this will cause the IPMI message handler to
25+ generate IPMI OEM type f0 events holding the IPMB address of the
26+ panic generator (byte 4 of the event), a sequence number for the
27+ string (byte 5 of the event) and part of the string (the rest of the
28+ event). Bytes 1, 2, and 3 are the normal usage for an OEM event.
29+ You can fetch these events and use the sequence numbers to piece the
30+ string together.
31+
32 Device interface for IPMI
33 CONFIG_IPMI_DEVICE_INTERFACE
34 This provides an IOCTL interface to the IPMI message handler so
35 userland processes may use IPMI. It supports poll() and select().
36
37+IPMI SI handler
38+CONFIG_IPMI_SI
39+ Provides a driver for System Interfaces (KCS, SMIC, BT).
40+ Currently, only KCS and SMIC are supported. If
41+ you are using IPMI, you should probably say "y" here.
42+
43 IPMI KCS handler
44 CONFIG_IPMI_KCS
45- Provides a driver for a KCS-style interface to a BMC.
46+ Provides a driver for a KCS-style interface to a BMC. This
47+ is deprecated, please use the IPMI System Interface handler
48+ instead.
49+
50+IPMI SMBus handler
51+CONFIG_IPMI_SMB
52+ Provides a driver for a SMBus interface to a BMC, meaning that you
53+ have a driver that must be accessed over an I2C bus instead of a
54+ standard interface. This module requires I2C support. Note that
55+ you might need some I2C changes if CONFIG_IPMI_PANIC_EVENT is
56+ enabled along with this, so the I2C driver knows to run to
57+ completion during sending a panic event.
58
59 IPMI Watchdog Timer
60 CONFIG_IPMI_WATCHDOG
61diff -urN linux-2.4.23.org/Documentation/IPMI.txt linux-2.4.23/Documentation/IPMI.txt
62--- linux-2.4.23.org/Documentation/IPMI.txt 2004-01-02 23:33:01.180548761 +0100
63+++ linux-2.4.23/Documentation/IPMI.txt 2004-01-02 23:33:47.993821821 +0100
64@@ -41,18 +41,33 @@
65 driver, each open file for this device ties in to the message handler
66 as an IPMI user.
67
68-ipmi_kcs_drv - A driver for the KCS SMI. Most system have a KCS
69-interface for IPMI.
70+ipmi_si_drv - A driver for various system interfaces. This supports
71+KCS, SMIC, and may support BT in the future. Unless you have your own
72+custom interface, you probably need to use this.
73+
74+ipmi_kcs_drv - A driver for the KCS SI. Most systems have a KCS
75+interface for IPMI. This is deprecated, ipmi_si_drv supports KCS and
76+SMIC interfaces.
77+
78+ipmi_smb_intf - A driver for accessing BMCs on the SMBus. It uses the
79+I2C kernel driver's SMBus interfaces to send and receive IPMI messages
80+over the SMBus.
81+
82+af_ipmi - A network socket interface to IPMI. This doesn't take up
83+a character device in your system.
84
85
86 Much documentation for the interface is in the include files. The
87 IPMI include files are:
88
89-ipmi.h - Contains the user interface and IOCTL interface for IPMI.
90+net/af_ipmi.h - Contains the socket interface.
91+
92+linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
93
94-ipmi_smi.h - Contains the interface for SMI drivers to use.
95+linux/ipmi_smi.h - Contains the interface for system management interfaces
96+(things that interface to IPMI controllers) to use.
97
98-ipmi_msgdefs.h - General definitions for base IPMI messaging.
99+linux/ipmi_msgdefs.h - General definitions for base IPMI messaging.
100
101
102 Addressing
103@@ -260,8 +275,66 @@
104 in the order they register, although if an SMI unregisters and then
105 another one registers, all bets are off.
106
107-The ipmi_smi.h defines the interface for SMIs, see that for more
108-details.
109+The ipmi_smi.h defines the interface for management interfaces, see
110+that for more details.
111+
112+
113+The SI Driver
114+-------------
115+
116+The SI driver allows up to 4 KCS or SMIC interfaces to be configured
117+in the system. By default, scan the ACPI tables for interfaces, and
118+if it doesn't find any the driver will attempt to register one KCS
119+interface at the spec-specified I/O port 0xca2 without interrupts.
120+You can change this at module load time (for a module) with:
121+
122+ insmod ipmi_si_drv.o si_type=<type1>,<type2>....
123+ si_ports=<port1>,<port2>... si_addrs=<addr1>,<addr2>
124+ si_irqs=<irq1>,<irq2>... si_trydefaults=[0|1]
125+
126+Each of these except si_trydefaults is a list, the first item for the
127+first interface, second item for the second interface, etc.
128+
129+The si_type may be either "kcs", "smic", or "bt". If you leave it blank, it
130+defaults to "kcs".
131+
132+If you specify si_addrs as non-zero for an interface, the driver will
133+use the memory address given as the address of the device. This
134+overrides si_ports.
135+
136+If you specify si_ports as non-zero for an interface, the driver will
137+use the I/O port given as the device address.
138+
139+If you specify si_irqs as non-zero for an interface, the driver will
140+attempt to use the given interrupt for the device.
141+
142+si_trydefaults sets whether the standard IPMI interface at 0xca2 and
143+any interfaces specified by ACPE are tried. By default, the driver
144+tries it, set this value to zero to turn this off.
145+
146+When compiled into the kernel, the addresses can be specified on the
147+kernel command line as:
148+
149+ ipmi_si=[<type>,]<bmc1>:<irq1>,[<type>,]<bmc2>:<irq2>....,[nodefault]
150+
151+The type is optional and may be either "kcs" for KCS, "smic" for
152+SMIC, or "bt" for BT. If not specified, it defaults to KCS.
153+The <bmcx> values is either "p<port>" or "m<addr>" for port or memory
154+addresses. So for instance, a KCS interface at port 0xca2 using
155+interrupt 9 and a SMIC memory interface at address 0xf9827341 with no
156+interrupt would be specified "ipmi_si=k,p0xca2:9,s,m0xf9827341". If you
157+specify zero for in irq or don't specify it, the driver will run polled
158+unless the software can detect the interrupt to use in the ACPI tables.
159+
160+By default, the driver will attempt to detect a KCS device at the
161+spec-specified 0xca2 address and any address specified by ACPI. If
162+you want to turn this off, use the "nodefault" option.
163+
164+If you have high-res timers compiled into the kernel, the driver will
165+use them to provide much better performance. Note that if you do not
166+have high-res timers enabled in the kernel and you don't have
167+interrupts enabled, the driver will run VERY slowly. Don't blame me,
168+these interfaces suck.
169
170
171 The KCS Driver
172@@ -309,6 +382,59 @@
173 the KCS interface sucks.
174
175
176+The SMBus Driver
177+----------------
178+
179+The SMBus driver allows up to 4 SMBus devices to be configured in the
180+system. By default, the driver will register any SMBus interfaces it finds
181+in the I2C address range of 0x20 to 0x4f on any adapter. You can change this
182+at module load time (for a module) with:
183+
184+ insmod ipmi_smb_intf.o
185+ smb_addr=<adapter1>,<i2caddr1>[,<adapter2>,<i2caddr2>[,...]]
186+ smb_dbg=<flags1>,<flags2>...
187+ [smb_defaultprobe=0] [smb_dbg_probe=1]
188+
189+The addresses are specified in pairs, the first is the adapter ID and the
190+second is the I2C address on that adapter.
191+
192+The debug flags are bit flags for each BMC found, they are:
193+IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
194+
195+Setting smb_defaultprobe to zero disabled the default probing of SMBus
196+interfaces at address range 0x20 to 0x4f. This means that only the
197+BMCs specified on the smb_addr line will be detected.
198+
199+Setting smb_dbg_probe to 1 will enable debugging of the probing and
200+detection process for BMCs on the SMBusses.
201+
202+Discovering the IPMI compilant BMC on the SMBus can cause devices
203+on the I2C bus to fail. The SMBus driver writes a "Get Device ID" IPMI
204+message as a block write to the I2C bus and waits for a response.
205+This action can be detrimental to some I2C devices. It is highly recommended
206+that the known I2c address be given to the SMBus driver in the smb_addr
207+parameter. The default adrress range will not be used when a smb_addr
208+parameter is provided.
209+
210+When compiled into the kernel, the addresses can be specified on the
211+kernel command line as:
212+
213+ ipmi_smb=[<adapter1>.]<addr1>[:<debug1>],[<adapter2>.<addr2>[:<debug1>]....
214+
215+The [<adapterx>.]<addrx>[:<debugx>] I2C address-debug flag are value
216+set for each BMC. If the adapter is not given, then it defaults to
217+zero. The debug flag is the same as the smb_dbg flag given above.
218+
219+You may also specify "nodefaults" and "debug_probe", separated by
220+commas, on the ipmi_smb line. These will disable the default SMB
221+probe and enable debugging of the BMC probing and detection process,
222+respectively.
223+
224+Note that you might need some I2C changes if CONFIG_IPMI_PANIC_EVENT
225+is enabled along with this, so the I2C driver knows to run to
226+completion during sending a panic event.
227+
228+
229 Other Pieces
230 ------------
231
232@@ -323,7 +449,10 @@
233
234 The timeout is the number of seconds to the action, and the pretimeout
235 is the amount of seconds before the reset that the pre-timeout panic will
236-occur (if pretimeout is zero, then pretimeout will not be enabled).
237+occur (if pretimeout is zero, then pretimeout will not be enabled). Note
238+that the pretimeout is the time before the final timeout. So if the
239+timeout is 50 seconds and the pretimeout is 10 seconds, then the pretimeout
240+will occur in 40 second (10 seconds before the timeout).
241
242 The action may be "reset", "power_cycle", or "power_off", and
243 specifies what to do when the timer times out, and defaults to
244diff -urN linux-2.4.23.org/drivers/char/Config.in linux-2.4.23/drivers/char/Config.in
245--- linux-2.4.23.org/drivers/char/Config.in 2004-01-02 23:31:35.216409593 +0100
246+++ linux-2.4.23/drivers/char/Config.in 2004-01-02 23:33:48.006819121 +0100
247@@ -214,8 +214,11 @@
248
249 tristate 'IPMI top-level message handler' CONFIG_IPMI_HANDLER
250 dep_mbool ' Generate a panic event to all BMCs on a panic' CONFIG_IPMI_PANIC_EVENT $CONFIG_IPMI_HANDLER
251+dep_mbool ' Generate a OEM events holding the panic string' CONFIG_IPMI_PANIC_STRING $CONFIG_IPMI_PANIC_EVENT
252 dep_tristate ' Device interface for IPMI' CONFIG_IPMI_DEVICE_INTERFACE $CONFIG_IPMI_HANDLER
253+dep_tristate ' IPMI SI handler' CONFIG_IPMI_SI $CONFIG_IPMI_HANDLER
254 dep_tristate ' IPMI KCS handler' CONFIG_IPMI_KCS $CONFIG_IPMI_HANDLER
255+dep_tristate ' IPMI SMBus handler' CONFIG_IPMI_SMB $CONFIG_IPMI_HANDLER $CONFIG_I2C
256 dep_tristate ' IPMI Watchdog Timer' CONFIG_IPMI_WATCHDOG $CONFIG_IPMI_HANDLER
257
258 mainmenu_option next_comment
259diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_bt_sm.c linux-2.4.23/drivers/char/ipmi/ipmi_bt_sm.c
260--- linux-2.4.23.org/drivers/char/ipmi/ipmi_bt_sm.c 1970-01-01 01:00:00.000000000 +0100
261+++ linux-2.4.23/drivers/char/ipmi/ipmi_bt_sm.c 2004-01-02 23:33:48.010818290 +0100
262@@ -0,0 +1,441 @@
263+/*
264+ * ipmi_bt_sm.c
265+ *
266+ * The state-machine driver for an IPMI Block Transfer driver
267+ *
268+ * It started as a copy of Corey Minyard's driver for the KSC interface
269+ * and the kernel patch "mmcdev-patch-245" by HP
270+ *
271+ * modified by: Jordan Hargrave <jordan_hargrave@dell.com>
272+ *
273+ * Corey Minyard's driver for the KSC interface has the following
274+ * copyright notice:
275+ * Copyright 2002 MontaVista Software Inc.
276+ *
277+ * the kernel patch "mmcdev-patch-245" by HP has the following
278+ * copyright notice:
279+ * (c) Copyright 2001 Grant Grundler (c) Copyright
280+ * 2001 Hewlett-Packard Company
281+ *
282+ *
283+ * This program is free software; you can redistribute it and/or modify it
284+ * under the terms of the GNU General Public License as published by the
285+ * Free Software Foundation; either version 2 of the License, or (at your
286+ * option) any later version.
287+ *
288+ *
289+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
290+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
291+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
292+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
293+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
294+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
295+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
296+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
297+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
298+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
299+ *
300+ * You should have received a copy of the GNU General Public License along
301+ * with this program; if not, write to the Free Software Foundation, Inc.,
302+ * 675 Mass Ave, Cambridge, MA 02139, USA.
303+ */
304+
305+/* #define BT_DEBUG */
306+
307+#include <linux/kernel.h>
308+#include <asm/string.h>
309+#include "ipmi_si_sm.h"
310+
311+#define IPMI_BT_VERSION "v28"
312+
313+#ifdef BT_DEBUG
314+static void dump(const void *b, int len)
315+{
316+ const uint8_t *buf = (const uint8_t *)b;
317+ int i, j, c;
318+
319+ for(i=0; i<len; i+=16) {
320+ for(j=0; j<16; j++) {
321+ if (i+j >= len) printk("XX ");
322+ else printk("%.02x ", buf[i+j]);
323+ }
324+ printk(" ");
325+ for(j=0; j<16; j++) {
326+ c = (i+j < len ? buf[i+j] : '.');
327+ printk("%c", (c >= ' ' && c <= 'z') ? c : '.');
328+ }
329+ printk("\n");
330+ }
331+}
332+#define bt_printk printk
333+#else
334+#define bt_printk(x...) do { } while(0)
335+#endif
336+
337+/*===========================================================================
338+ *
339+ * IPMI Block Transfer interface method
340+ *
341+ *===========================================================================*/
342+#ifndef BIT
343+#define BIT(n) (1L << (n))
344+#endif
345+
346+#define BT_CTRL_REG 0
347+# define BT_CLR_WR_PTR BIT(0)
348+# define BT_CLR_RD_PTR BIT(1)
349+# define BT_HOST2BMC_ATN BIT(2)
350+# define BT_BMC2HOST_ATN BIT(3)
351+# define BT_EVT_ATN BIT(4)
352+# define BT_HOST_BUSY BIT(6)
353+# define BT_BMC_BUSY BIT(7)
354+
355+# define BT_RX_READY (BT_BMC2HOST_ATN)
356+# define BT_TX_READY (BT_BMC_BUSY|BT_HOST2BMC_ATN)
357+
358+#define BT_BUFFER_REG 1
359+
360+#define BT_INTMASK_REG 2
361+# define BT_BMC2HOST_IRQ_EN BIT(0)
362+# define BT_BMC2HOST_IRQ BIT(1)
363+# define BT_HOST2BMC_RESET BIT(7)
364+
365+#define BT_SEQMASK 0x3F
366+#define BT_MAXREQSZ 128
367+#define BT_MINRESPSZ 4 /* len+nfln+seq+ccode */
368+#define BT_MINPKTSZ 3 /* nfln+ccode+status */
369+
370+#define BT_IDLE 0
371+#define BT_WRITE_START 1
372+#define BT_WRITE 2
373+#define BT_WRITE_END 3
374+
375+#define BT_READ_START 4
376+#define BT_READ 5
377+#define BT_READ_END 6
378+
379+#define BT_HOSED 7
380+#define BT_ERROR 8
381+
382+#define bt(a,b) ((a)&(b) ? 1 : 0)
383+#define port_outb(bt,port,val) bt->io->outputb(bt->io, port, val)
384+#define port_inb(bt,port) bt->io->inputb(bt->io, port)
385+
386+/* --== Block Transfer XMIT/RECV structure ==-- */
387+struct bt_xmit
388+{
389+ int seq; // sequence number
390+ int len; // length of data packet
391+ int pos; // current write pos
392+ uint8_t *ptr; // current write ptr
393+ uint8_t data[BT_MAXREQSZ];
394+};
395+
396+struct si_sm_data
397+{
398+ int state;
399+ int status;
400+ int btSeq;
401+ int error_retries;
402+ int truncated;
403+
404+ /* --== read/write state ==-- */
405+ struct bt_xmit wr;
406+ struct bt_xmit rd;
407+
408+ /* --== I/O handler */
409+ struct si_sm_io *io;
410+};
411+
412+static void bt_print_status(int v, char *pfx)
413+{
414+ if (v == 0) return;
415+
416+#ifdef BT_DEBUG
417+ printk("%16s bt_ctrl ="
418+ " %.02x w:%d r:%d h2b:%d b2h:%d evt:%d hb:%d bb:%d\n",
419+ pfx, v,
420+ bt(v,BT_CLR_WR_PTR),
421+ bt(v,BT_CLR_RD_PTR),
422+ bt(v,BT_HOST2BMC_ATN),
423+ bt(v,BT_BMC2HOST_ATN),
424+ bt(v,BT_EVT_ATN),
425+ bt(v,BT_HOST_BUSY),
426+ bt(v,BT_BMC_BUSY));
427+#endif
428+}
429+
430+/*=================================================================
431+ * Read/Write BT registers
432+ *=================================================================*/
433+#define bt_read_ctrl(bt) port_inb((bt), BT_CTRL_REG)
434+#define bt_write_ctrl(bt,val) port_outb((bt), BT_CTRL_REG, (val))
435+#define bt_read_buffer(bt) port_inb((bt), BT_BUFFER_REG)
436+#define bt_write_buffer(bt,val) port_outb((bt), BT_BUFFER_REG, (val))
437+#define bt_read_intmask(bt) port_inb((bt), BT_INTMASK_REG)
438+#define bt_write_intmask(bt,val) port_outb((bt), BT_INTMASK_REG, (val))
439+
440+/*=================================================================
441+ * Test BT state
442+ *=================================================================*/
443+#define bt_rx_ready(sts) ((sts) & BT_RX_READY)
444+#define bt_evt_ready(sts) ((sts) & BT_EVT_ATN)
445+#define bt_tx_ready(sts) (~(sts) & BT_TX_READY)
446+
447+/*=================================================================
448+ * Reset BT controller to known state
449+ *=================================================================*/
450+static inline void bt_reset(struct si_sm_data *bt)
451+{
452+ unsigned char v;
453+
454+ v = bt_read_ctrl(bt) & BT_HOST_BUSY;
455+ bt_write_ctrl(bt,
456+ v | (BT_CLR_WR_PTR | BT_CLR_RD_PTR | BT_BMC2HOST_ATN |
457+ BT_EVT_ATN));
458+}
459+
460+/*===================================================
461+ * bt_init_data - initialize si_sm_data structure
462+ *===================================================*/
463+static unsigned int bt_init_data(struct si_sm_data *bt,
464+ struct si_sm_io *io)
465+{
466+ bt->state = BT_IDLE;
467+ bt->io = io;
468+ bt->wr.pos = 0;
469+ bt->wr.len = 0;
470+ bt->wr.ptr = bt->wr.data;
471+ bt->rd.pos = 0;
472+ bt->rd.len = 0;
473+ bt->rd.ptr = bt->rd.data;
474+ bt->error_retries = 0;
475+ bt->truncated = 0;
476+
477+ /* reserve 3 i/o bytes */
478+ return 3;
479+}
480+
481+/*===================================================
482+ * bt_start_transaction - issue IPMI command
483+ *===================================================*/
484+static int bt_start_transaction(struct si_sm_data *bt,
485+ unsigned char *data,
486+ unsigned int size)
487+{
488+ bt_printk("bt_start: %d bytes\n", size);
489+
490+ /* --== Validate size and state ==-- */
491+ if (size < 2 || size > BT_MAXREQSZ) {
492+ return -1;
493+ }
494+ if (bt->state != BT_IDLE && bt->state != BT_HOSED) {
495+ return -2;
496+ }
497+
498+ /* --== assert: data = netfn|cmd|data... ==-- */
499+ bt->error_retries = 0;
500+ bt->state = BT_WRITE_START;
501+ bt->wr.pos = 0;
502+ bt->wr.len = size+1;
503+ bt->wr.ptr = bt->wr.data;
504+ bt->wr.seq = ++bt->btSeq & BT_SEQMASK;
505+ memcpy(bt->wr.data, data, size);
506+
507+#ifdef BT_DEBUG
508+ bt_printk("------ request ------\n");
509+ dump(data, size);
510+#endif
511+
512+ return 0;
513+}
514+
515+
516+/*=======================================================
517+ * bt_get_result - get event or result of IPMI command
518+ *=======================================================*/
519+static int bt_get_result(struct si_sm_data *bt,
520+ unsigned char *data,
521+ unsigned int length)
522+{
523+ int rdlen = bt->rd.len-1; /* skip sequence byte */
524+
525+ if (length < rdlen) {
526+ rdlen = length;
527+ bt->truncated = 1;
528+ }
529+ memcpy(data, bt->rd.data, rdlen);
530+
531+#ifdef BT_DEBUG
532+ bt_printk("------ result ------ : %d %d\n", length, rdlen);
533+ dump(data, rdlen);
534+#endif
535+
536+ /* --== Minimum length is 3 bytes: nfLn, cCode, status, data[] ==-- */
537+ if ((length >= BT_MINPKTSZ) && (rdlen < BT_MINPKTSZ)) {
538+ data[2] = 0xFF;
539+ rdlen = 3;
540+ }
541+ if (bt->truncated) {
542+ data[2] = 0xFE;
543+ bt->truncated = 0;
544+ }
545+ return rdlen;
546+}
547+
548+/*=======================================================
549+ * bt_event - state machine to retreive/send events
550+ *=======================================================*/
551+static enum si_sm_result bt_event(struct si_sm_data *bt, long time)
552+{
553+ /* --== Read current status ==-- */
554+ bt->status = bt_read_ctrl(bt);
555+
556+ switch(bt->state) {
557+ case BT_IDLE:
558+ bt_print_status(bt->status, "idle");
559+ if (bt_evt_ready(bt->status)) {
560+ bt_printk("*** EVENT READY\n");
561+ bt_write_ctrl(bt, BT_EVT_ATN);
562+ }
563+ if (bt_rx_ready(bt->status)) {
564+ bt_printk("*** READ READY\n");
565+ bt->state = BT_READ_START;
566+ return SI_SM_ATTN;
567+ }
568+ if (bt->status & BT_HOST_BUSY) {
569+ bt_write_ctrl(bt, BT_HOST_BUSY);
570+ }
571+ return SI_SM_IDLE;
572+
573+ case BT_WRITE_START:
574+ bt_print_status(bt->status,"write_start");
575+ if (bt_tx_ready(bt->status)) {
576+ bt_write_ctrl(bt, BT_CLR_WR_PTR); /* signal write */
577+ bt->state = BT_WRITE;
578+ }
579+ break;
580+
581+ case BT_WRITE:
582+ bt_print_status(bt->status,"write");
583+ if (bt->wr.pos == 0) {
584+ /* Write length of data */
585+ bt_write_buffer(bt, bt->wr.len);
586+ }
587+ else if (bt->wr.pos == 2) {
588+ /* Write sequence number */
589+ bt_write_buffer(bt, bt->wr.seq);
590+ }
591+ else {
592+ /* Write normal data */
593+ bt_write_buffer(bt, *(bt->wr.ptr++));
594+ }
595+ if (bt->wr.pos++ == bt->wr.len) {
596+ bt->state = BT_WRITE_END;
597+ }
598+ return SI_SM_CALL_WITH_DELAY;
599+
600+ case BT_WRITE_END:
601+ bt_print_status(bt->status,"write_end");
602+ bt_write_ctrl(bt, BT_HOST2BMC_ATN);
603+ bt->state = BT_READ_START;
604+ break;
605+
606+ case BT_READ_START:
607+ bt_print_status(bt->status, "read_start");
608+ if (bt_rx_ready(bt->status)) {
609+ bt_write_ctrl(bt, BT_HOST_BUSY); /* mark host busy */
610+ bt_write_ctrl(bt, BT_BMC2HOST_ATN); /* clear bmc2host attn */
611+ bt_write_ctrl(bt, BT_CLR_RD_PTR); /* signal read */
612+
613+ bt->rd.pos = 0;
614+ bt->rd.ptr = bt->rd.data;
615+ bt->state = BT_READ;
616+ }
617+ return SI_SM_CALL_WITH_DELAY;
618+
619+ case BT_READ:
620+ bt_print_status(bt->status, "read");
621+ if (bt->rd.pos == 0) {
622+ /* Read total buffer length - check here */
623+ bt->rd.len = bt_read_buffer(bt);
624+ bt_printk("read length: %x\n", bt->rd.len);
625+ if (bt->rd.len < BT_MINRESPSZ) {
626+ bt->state = BT_READ_END;
627+ }
628+ }
629+ else if (bt->rd.pos == 2) {
630+ /* Read sequence */
631+ bt->rd.seq = bt_read_buffer(bt);
632+ if (bt->rd.seq != bt->wr.seq) {
633+ printk("Out of order sequence!\n");
634+ }
635+ }
636+ else {
637+ *(bt->rd.ptr++) = bt_read_buffer(bt);
638+ }
639+ if (bt->rd.pos++ == bt->rd.len) {
640+ bt->state = BT_READ_END;
641+ }
642+ return SI_SM_CALL_WITH_DELAY;
643+
644+ case BT_READ_END:
645+ bt_print_status(bt->status, "read_end");
646+ bt_write_ctrl(bt, BT_HOST_BUSY); /* clear host busy */
647+ bt->state = BT_IDLE;
648+ return SI_SM_TRANSACTION_COMPLETE;
649+ }
650+
651+ return SI_SM_CALL_WITHOUT_DELAY;
652+}
653+
654+/*=======================================================
655+ * bt_detect - Detect if BT interface is supported
656+ *=======================================================*/
657+static int bt_detect(struct si_sm_data *bt)
658+{
659+ int v;
660+
661+ bt->btSeq = 0x0;
662+ bt->state = BT_IDLE;
663+
664+ /* Check intmask and control register - neither should be 0xFF */
665+ v = bt_read_intmask(bt);
666+ if (v == 0xFF) {
667+ return 1;
668+ }
669+ v = bt_read_ctrl(bt);
670+ if (v != 0xFF) {
671+ bt_reset(bt);
672+ }
673+ bt_print_status(v, "detect");
674+ return (v == 0xFF);
675+}
676+
677+/*=======================================================
678+ * bt_cleanup - Cleanup register state
679+ *=======================================================*/
680+static void bt_cleanup(struct si_sm_data *bt)
681+{
682+ bt_printk("bt_cleanup\n");
683+}
684+
685+/*=======================================================
686+ * bt_size - Returns size of device extension
687+ *=======================================================*/
688+static int bt_size(void)
689+{
690+ return sizeof(struct si_sm_data);
691+}
692+
693+struct si_sm_handlers bt_smi_handlers =
694+{
695+ .version = IPMI_BT_VERSION,
696+ .init_data = bt_init_data,
697+ .start_transaction = bt_start_transaction,
698+ .get_result = bt_get_result,
699+ .event = bt_event,
700+ .detect = bt_detect,
701+ .cleanup = bt_cleanup,
702+ .size = bt_size,
703+};
704diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_devintf.c linux-2.4.23/drivers/char/ipmi/ipmi_devintf.c
705--- linux-2.4.23.org/drivers/char/ipmi/ipmi_devintf.c 2004-01-02 23:31:35.452360571 +0100
706+++ linux-2.4.23/drivers/char/ipmi/ipmi_devintf.c 2004-01-02 23:33:48.026814966 +0100
707@@ -44,6 +44,8 @@
708 #include <asm/semaphore.h>
709 #include <linux/init.h>
710
711+#define IPMI_DEVINTF_VERSION "v28"
712+
713 struct ipmi_file_private
714 {
715 ipmi_user_t user;
716@@ -53,6 +55,8 @@
717 struct fasync_struct *fasync_queue;
718 wait_queue_head_t wait;
719 struct semaphore recv_sem;
720+ int default_retries;
721+ unsigned int default_retry_time_ms;
722 };
723
724 static void file_receive_handler(struct ipmi_recv_msg *msg,
725@@ -105,7 +109,7 @@
726
727 static struct ipmi_user_hndl ipmi_hndlrs =
728 {
729- ipmi_recv_hndl : file_receive_handler
730+ .ipmi_recv_hndl = file_receive_handler,
731 };
732
733 static int ipmi_open(struct inode *inode, struct file *file)
734@@ -138,6 +142,10 @@
735 priv->fasync_queue = NULL;
736 sema_init(&(priv->recv_sem), 1);
737
738+ /* Use the low-level defaults. */
739+ priv->default_retries = -1;
740+ priv->default_retry_time_ms = 0;
741+
742 return 0;
743 }
744
745@@ -158,6 +166,47 @@
746 return 0;
747 }
748
749+static int handle_send_req(ipmi_user_t user,
750+ struct ipmi_req *req,
751+ int retries,
752+ unsigned int retry_time_ms)
753+{
754+ int rv;
755+ struct ipmi_addr addr;
756+ unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
757+
758+ if (req->addr_len > sizeof(struct ipmi_addr))
759+ return -EINVAL;
760+
761+ if (copy_from_user(&addr, req->addr, req->addr_len))
762+ return -EFAULT;
763+
764+ rv = ipmi_validate_addr(&addr, req->addr_len);
765+ if (rv)
766+ return rv;
767+
768+ if (req->msg.data != NULL) {
769+ if (req->msg.data_len > IPMI_MAX_MSG_LENGTH)
770+ return -EMSGSIZE;
771+
772+ if (copy_from_user(&msgdata,
773+ req->msg.data,
774+ req->msg.data_len))
775+ return -EFAULT;
776+ } else {
777+ req->msg.data_len = 0;
778+ }
779+ req->msg.data = msgdata;
780+
781+ return ipmi_request_settime(user,
782+ &addr,
783+ req->msgid,
784+ &(req->msg),
785+ 0,
786+ retries,
787+ retry_time_ms);
788+}
789+
790 static int ipmi_ioctl(struct inode *inode,
791 struct file *file,
792 unsigned int cmd,
793@@ -170,54 +219,33 @@
794 {
795 case IPMICTL_SEND_COMMAND:
796 {
797- struct ipmi_req req;
798- struct ipmi_addr addr;
799- unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
800+ struct ipmi_req req;
801
802 if (copy_from_user(&req, (void *) data, sizeof(req))) {
803 rv = -EFAULT;
804 break;
805 }
806
807- if (req.addr_len > sizeof(struct ipmi_addr))
808- {
809- rv = -EINVAL;
810- break;
811- }
812+ rv = handle_send_req(priv->user,
813+ &req,
814+ priv->default_retries,
815+ priv->default_retry_time_ms);
816+ break;
817+ }
818
819- if (copy_from_user(&addr, req.addr, req.addr_len)) {
820+ case IPMICTL_SEND_COMMAND_SETTIME:
821+ {
822+ struct ipmi_req_settime req;
823+
824+ if (copy_from_user(&req, (void *) data, sizeof(req))) {
825 rv = -EFAULT;
826 break;
827 }
828
829- rv = ipmi_validate_addr(&addr, req.addr_len);
830- if (rv)
831- break;
832-
833- if (req.msg.data != NULL) {
834- if (req.msg.data_len > IPMI_MAX_MSG_LENGTH) {
835- rv = -EMSGSIZE;
836- break;
837- }
838-
839- if (copy_from_user(&msgdata,
840- req.msg.data,
841- req.msg.data_len))
842- {
843- rv = -EFAULT;
844- break;
845- }
846- } else {
847- req.msg.data_len = 0;
848- }
849-
850- req.msg.data = msgdata;
851-
852- rv = ipmi_request(priv->user,
853- &addr,
854- req.msgid,
855- &(req.msg),
856- 0);
857+ rv = handle_send_req(priv->user,
858+ &req.req,
859+ req.retries,
860+ req.retry_time_ms);
861 break;
862 }
863
864@@ -416,7 +444,36 @@
865 rv = 0;
866 break;
867 }
868+ case IPMICTL_SET_TIMING_PARMS_CMD:
869+ {
870+ struct ipmi_timing_parms parms;
871+
872+ if (copy_from_user(&parms, (void *) data, sizeof(parms))) {
873+ rv = -EFAULT;
874+ break;
875+ }
876+
877+ priv->default_retries = parms.retries;
878+ priv->default_retry_time_ms = parms.retry_time_ms;
879+ rv = 0;
880+ break;
881+ }
882+
883+ case IPMICTL_GET_TIMING_PARMS_CMD:
884+ {
885+ struct ipmi_timing_parms parms;
886+
887+ parms.retries = priv->default_retries;
888+ parms.retry_time_ms = priv->default_retry_time_ms;
889
890+ if (copy_to_user((void *) data, &parms, sizeof(parms))) {
891+ rv = -EFAULT;
892+ break;
893+ }
894+
895+ rv = 0;
896+ break;
897+ }
898 }
899
900 return rv;
901@@ -424,12 +481,12 @@
902
903
904 static struct file_operations ipmi_fops = {
905- owner: THIS_MODULE,
906- ioctl: ipmi_ioctl,
907- open: ipmi_open,
908- release: ipmi_release,
909- fasync: ipmi_fasync,
910- poll: ipmi_poll
911+ .owner = THIS_MODULE,
912+ .ioctl = ipmi_ioctl,
913+ .open = ipmi_open,
914+ .release = ipmi_release,
915+ .fasync = ipmi_fasync,
916+ .poll = ipmi_poll,
917 };
918
919 #define DEVICE_NAME "ipmidev"
920@@ -468,8 +525,9 @@
921
922 static struct ipmi_smi_watcher smi_watcher =
923 {
924- new_smi : ipmi_new_smi,
925- smi_gone : ipmi_smi_gone
926+ .owner = THIS_MODULE,
927+ .new_smi = ipmi_new_smi,
928+ .smi_gone = ipmi_smi_gone,
929 };
930
931 static __init int init_ipmi_devintf(void)
932@@ -479,6 +537,9 @@
933 if (ipmi_major < 0)
934 return -EINVAL;
935
936+ printk(KERN_INFO "ipmi device interface version "
937+ IPMI_DEVINTF_VERSION "\n");
938+
939 rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
940 if (rv < 0) {
941 printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
942@@ -498,9 +559,6 @@
943 return rv;
944 }
945
946- printk(KERN_INFO "ipmi: device interface at char major %d\n",
947- ipmi_major);
948-
949 return 0;
950 }
951 module_init(init_ipmi_devintf);
952diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_kcs_intf.c linux-2.4.23/drivers/char/ipmi/ipmi_kcs_intf.c
953--- linux-2.4.23.org/drivers/char/ipmi/ipmi_kcs_intf.c 2004-01-02 23:31:35.446361818 +0100
954+++ linux-2.4.23/drivers/char/ipmi/ipmi_kcs_intf.c 2004-01-02 23:33:48.034813304 +0100
955@@ -54,7 +54,7 @@
956 #include <linux/interrupt.h>
957 #include <linux/ipmi_smi.h>
958 #include <asm/io.h>
959-#include "ipmi_kcs_sm.h"
960+#include "ipmi_si_sm.h"
961 #include <linux/init.h>
962
963 /* Measure times between events in the driver. */
964@@ -72,6 +72,8 @@
965 /* This forces a dependency to the config file for this option. */
966 #endif
967
968+extern struct si_sm_handlers kcs_smi_handlers;
969+
970 enum kcs_intf_state {
971 KCS_NORMAL,
972 KCS_GETTING_FLAGS,
973@@ -87,7 +89,7 @@
974 struct kcs_info
975 {
976 ipmi_smi_t intf;
977- struct kcs_data *kcs_sm;
978+ struct si_sm_data *kcs_sm;
979 spinlock_t kcs_lock;
980 spinlock_t msg_lock;
981 struct list_head xmit_msgs;
982@@ -112,8 +114,10 @@
983 out. */
984 int run_to_completion;
985
986+ struct si_sm_io io;
987+
988 /* The I/O port of a KCS interface. */
989- int port;
990+ unsigned int port;
991
992 /* zero if no irq; */
993 int irq;
994@@ -164,7 +168,7 @@
995 deliver_recv_msg(kcs_info, msg);
996 }
997
998-static enum kcs_result start_next_msg(struct kcs_info *kcs_info)
999+static enum si_sm_result start_next_msg(struct kcs_info *kcs_info)
1000 {
1001 int rv;
1002 struct list_head *entry = NULL;
1003@@ -185,7 +189,7 @@
1004
1005 if (!entry) {
1006 kcs_info->curr_msg = NULL;
1007- rv = KCS_SM_IDLE;
1008+ rv = SI_SM_IDLE;
1009 } else {
1010 int err;
1011
1012@@ -197,14 +201,15 @@
1013 do_gettimeofday(&t);
1014 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
1015 #endif
1016- err = start_kcs_transaction(kcs_info->kcs_sm,
1017- kcs_info->curr_msg->data,
1018- kcs_info->curr_msg->data_size);
1019+ err = kcs_smi_handlers.start_transaction(
1020+ kcs_info->kcs_sm,
1021+ kcs_info->curr_msg->data,
1022+ kcs_info->curr_msg->data_size);
1023 if (err) {
1024 return_hosed_msg(kcs_info);
1025 }
1026
1027- rv = KCS_CALL_WITHOUT_DELAY;
1028+ rv = SI_SM_CALL_WITHOUT_DELAY;
1029 }
1030 spin_unlock(&(kcs_info->msg_lock));
1031
1032@@ -220,7 +225,7 @@
1033 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
1034 msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
1035
1036- start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
1037+ kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 2);
1038 kcs_info->kcs_state = KCS_ENABLE_INTERRUPTS1;
1039 }
1040
1041@@ -233,7 +238,7 @@
1042 msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
1043 msg[2] = WDT_PRE_TIMEOUT_INT;
1044
1045- start_kcs_transaction(kcs_info->kcs_sm, msg, 3);
1046+ kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 3);
1047 kcs_info->kcs_state = KCS_CLEARING_FLAGS;
1048 }
1049
1050@@ -280,9 +285,10 @@
1051 kcs_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
1052 kcs_info->curr_msg->data_size = 2;
1053
1054- start_kcs_transaction(kcs_info->kcs_sm,
1055- kcs_info->curr_msg->data,
1056- kcs_info->curr_msg->data_size);
1057+ kcs_smi_handlers.start_transaction(
1058+ kcs_info->kcs_sm,
1059+ kcs_info->curr_msg->data,
1060+ kcs_info->curr_msg->data_size);
1061 kcs_info->kcs_state = KCS_GETTING_MESSAGES;
1062 } else if (kcs_info->msg_flags & EVENT_MSG_BUFFER_FULL) {
1063 /* Events available. */
1064@@ -298,9 +304,10 @@
1065 kcs_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
1066 kcs_info->curr_msg->data_size = 2;
1067
1068- start_kcs_transaction(kcs_info->kcs_sm,
1069- kcs_info->curr_msg->data,
1070- kcs_info->curr_msg->data_size);
1071+ kcs_smi_handlers.start_transaction(
1072+ kcs_info->kcs_sm,
1073+ kcs_info->curr_msg->data,
1074+ kcs_info->curr_msg->data_size);
1075 kcs_info->kcs_state = KCS_GETTING_EVENTS;
1076 } else {
1077 kcs_info->kcs_state = KCS_NORMAL;
1078@@ -322,9 +329,10 @@
1079 break;
1080
1081 kcs_info->curr_msg->rsp_size
1082- = kcs_get_result(kcs_info->kcs_sm,
1083- kcs_info->curr_msg->rsp,
1084- IPMI_MAX_MSG_LENGTH);
1085+ = kcs_smi_handlers.get_result(
1086+ kcs_info->kcs_sm,
1087+ kcs_info->curr_msg->rsp,
1088+ IPMI_MAX_MSG_LENGTH);
1089
1090 /* Do this here becase deliver_recv_msg() releases the
1091 lock, and a new message can be put in during the
1092@@ -340,7 +348,7 @@
1093 unsigned int len;
1094
1095 /* We got the flags from the KCS, now handle them. */
1096- len = kcs_get_result(kcs_info->kcs_sm, msg, 4);
1097+ len = kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 4);
1098 if (msg[2] != 0) {
1099 /* Error fetching flags, just give up for
1100 now. */
1101@@ -362,7 +370,7 @@
1102 unsigned char msg[3];
1103
1104 /* We cleared the flags. */
1105- kcs_get_result(kcs_info->kcs_sm, msg, 3);
1106+ kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 3);
1107 if (msg[2] != 0) {
1108 /* Error clearing flags */
1109 printk(KERN_WARNING
1110@@ -379,9 +387,9 @@
1111 case KCS_GETTING_EVENTS:
1112 {
1113 kcs_info->curr_msg->rsp_size
1114- = kcs_get_result(kcs_info->kcs_sm,
1115- kcs_info->curr_msg->rsp,
1116- IPMI_MAX_MSG_LENGTH);
1117+ = kcs_smi_handlers.get_result(kcs_info->kcs_sm,
1118+ kcs_info->curr_msg->rsp,
1119+ IPMI_MAX_MSG_LENGTH);
1120
1121 /* Do this here becase deliver_recv_msg() releases the
1122 lock, and a new message can be put in during the
1123@@ -404,9 +412,9 @@
1124 case KCS_GETTING_MESSAGES:
1125 {
1126 kcs_info->curr_msg->rsp_size
1127- = kcs_get_result(kcs_info->kcs_sm,
1128- kcs_info->curr_msg->rsp,
1129- IPMI_MAX_MSG_LENGTH);
1130+ = kcs_smi_handlers.get_result(kcs_info->kcs_sm,
1131+ kcs_info->curr_msg->rsp,
1132+ IPMI_MAX_MSG_LENGTH);
1133
1134 /* Do this here becase deliver_recv_msg() releases the
1135 lock, and a new message can be put in during the
1136@@ -431,7 +439,7 @@
1137 unsigned char msg[4];
1138
1139 /* We got the flags from the KCS, now handle them. */
1140- kcs_get_result(kcs_info->kcs_sm, msg, 4);
1141+ kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 4);
1142 if (msg[2] != 0) {
1143 printk(KERN_WARNING
1144 "ipmi_kcs: Could not enable interrupts"
1145@@ -441,7 +449,8 @@
1146 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
1147 msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
1148 msg[2] = msg[3] | 1; /* enable msg queue int */
1149- start_kcs_transaction(kcs_info->kcs_sm, msg,3);
1150+ kcs_smi_handlers.start_transaction(
1151+ kcs_info->kcs_sm, msg,3);
1152 kcs_info->kcs_state = KCS_ENABLE_INTERRUPTS2;
1153 }
1154 break;
1155@@ -452,7 +461,7 @@
1156 unsigned char msg[4];
1157
1158 /* We got the flags from the KCS, now handle them. */
1159- kcs_get_result(kcs_info->kcs_sm, msg, 4);
1160+ kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 4);
1161 if (msg[2] != 0) {
1162 printk(KERN_WARNING
1163 "ipmi_kcs: Could not enable interrupts"
1164@@ -466,9 +475,10 @@
1165
1166 /* Called on timeouts and events. Timeouts should pass the elapsed
1167 time, interrupts should pass in zero. */
1168-static enum kcs_result kcs_event_handler(struct kcs_info *kcs_info, int time)
1169+static enum si_sm_result kcs_event_handler(struct kcs_info *kcs_info,
1170+ int time)
1171 {
1172- enum kcs_result kcs_result;
1173+ enum si_sm_result kcs_result;
1174
1175 restart:
1176 /* There used to be a loop here that waited a little while
1177@@ -477,19 +487,19 @@
1178 range, which is far too long to wait in an interrupt. So
1179 we just run until the state machine tells us something
1180 happened or it needs a delay. */
1181- kcs_result = kcs_event(kcs_info->kcs_sm, time);
1182+ kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, time);
1183 time = 0;
1184- while (kcs_result == KCS_CALL_WITHOUT_DELAY)
1185+ while (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
1186 {
1187- kcs_result = kcs_event(kcs_info->kcs_sm, 0);
1188+ kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
1189 }
1190
1191- if (kcs_result == KCS_TRANSACTION_COMPLETE)
1192+ if (kcs_result == SI_SM_TRANSACTION_COMPLETE)
1193 {
1194 handle_transaction_done(kcs_info);
1195- kcs_result = kcs_event(kcs_info->kcs_sm, 0);
1196+ kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
1197 }
1198- else if (kcs_result == KCS_SM_HOSED)
1199+ else if (kcs_result == SI_SM_HOSED)
1200 {
1201 if (kcs_info->curr_msg != NULL) {
1202 /* If we were handling a user message, format
1203@@ -497,12 +507,12 @@
1204 tell it about the error. */
1205 return_hosed_msg(kcs_info);
1206 }
1207- kcs_result = kcs_event(kcs_info->kcs_sm, 0);
1208+ kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
1209 kcs_info->kcs_state = KCS_NORMAL;
1210 }
1211
1212 /* We prefer handling attn over new messages. */
1213- if (kcs_result == KCS_ATTN)
1214+ if (kcs_result == SI_SM_ATTN)
1215 {
1216 unsigned char msg[2];
1217
1218@@ -514,19 +524,19 @@
1219 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
1220 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
1221
1222- start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
1223+ kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 2);
1224 kcs_info->kcs_state = KCS_GETTING_FLAGS;
1225 goto restart;
1226 }
1227
1228 /* If we are currently idle, try to start the next message. */
1229- if (kcs_result == KCS_SM_IDLE) {
1230+ if (kcs_result == SI_SM_IDLE) {
1231 kcs_result = start_next_msg(kcs_info);
1232- if (kcs_result != KCS_SM_IDLE)
1233+ if (kcs_result != SI_SM_IDLE)
1234 goto restart;
1235 }
1236
1237- if ((kcs_result == KCS_SM_IDLE)
1238+ if ((kcs_result == SI_SM_IDLE)
1239 && (atomic_read(&kcs_info->req_events)))
1240 {
1241 /* We are idle and the upper layer requested that I fetch
1242@@ -537,7 +547,7 @@
1243 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
1244 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
1245
1246- start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
1247+ kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 2);
1248 kcs_info->kcs_state = KCS_GETTING_FLAGS;
1249 goto restart;
1250 }
1251@@ -549,11 +559,11 @@
1252 struct ipmi_smi_msg *msg,
1253 int priority)
1254 {
1255- struct kcs_info *kcs_info = (struct kcs_info *) send_info;
1256- enum kcs_result result;
1257- unsigned long flags;
1258+ struct kcs_info *kcs_info = (struct kcs_info *) send_info;
1259+ enum si_sm_result result;
1260+ unsigned long flags;
1261 #ifdef DEBUG_TIMING
1262- struct timeval t;
1263+ struct timeval t;
1264 #endif
1265
1266 spin_lock_irqsave(&(kcs_info->msg_lock), flags);
1267@@ -574,7 +584,7 @@
1268
1269 spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
1270 result = kcs_event_handler(kcs_info, 0);
1271- while (result != KCS_SM_IDLE) {
1272+ while (result != SI_SM_IDLE) {
1273 udelay(KCS_SHORT_TIMEOUT_USEC);
1274 result = kcs_event_handler(kcs_info,
1275 KCS_SHORT_TIMEOUT_USEC);
1276@@ -602,16 +612,16 @@
1277
1278 static void set_run_to_completion(void *send_info, int i_run_to_completion)
1279 {
1280- struct kcs_info *kcs_info = (struct kcs_info *) send_info;
1281- enum kcs_result result;
1282- unsigned long flags;
1283+ struct kcs_info *kcs_info = (struct kcs_info *) send_info;
1284+ enum si_sm_result result;
1285+ unsigned long flags;
1286
1287 spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
1288
1289 kcs_info->run_to_completion = i_run_to_completion;
1290 if (i_run_to_completion) {
1291 result = kcs_event_handler(kcs_info, 0);
1292- while (result != KCS_SM_IDLE) {
1293+ while (result != SI_SM_IDLE) {
1294 udelay(KCS_SHORT_TIMEOUT_USEC);
1295 result = kcs_event_handler(kcs_info,
1296 KCS_SHORT_TIMEOUT_USEC);
1297@@ -676,13 +686,13 @@
1298
1299 static void kcs_timeout(unsigned long data)
1300 {
1301- struct kcs_info *kcs_info = (struct kcs_info *) data;
1302- enum kcs_result kcs_result;
1303- unsigned long flags;
1304- unsigned long jiffies_now;
1305- unsigned long time_diff;
1306+ struct kcs_info *kcs_info = (struct kcs_info *) data;
1307+ enum si_sm_result kcs_result;
1308+ unsigned long flags;
1309+ unsigned long jiffies_now;
1310+ unsigned long time_diff;
1311 #ifdef DEBUG_TIMING
1312- struct timeval t;
1313+ struct timeval t;
1314 #endif
1315
1316 if (kcs_info->stop_operation) {
1317@@ -712,7 +722,7 @@
1318 /* If the state machine asks for a short delay, then shorten
1319 the timer timeout. */
1320 #ifdef CONFIG_HIGH_RES_TIMERS
1321- if (kcs_result == KCS_CALL_WITH_DELAY) {
1322+ if (kcs_result == SI_SM_CALL_WITH_DELAY) {
1323 kcs_info->kcs_timer.sub_expires
1324 += usec_to_arch_cycles(KCS_SHORT_TIMEOUT_USEC);
1325 while (kcs_info->kcs_timer.sub_expires >= cycles_per_jiffies) {
1326@@ -725,7 +735,7 @@
1327 }
1328 #else
1329 /* If requested, take the shortest delay possible */
1330- if (kcs_result == KCS_CALL_WITH_DELAY) {
1331+ if (kcs_result == SI_SM_CALL_WITH_DELAY) {
1332 kcs_info->kcs_timer.expires = jiffies + 1;
1333 } else {
1334 kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
1335@@ -776,12 +786,12 @@
1336 extern int kcs_dbg;
1337 static int ipmi_kcs_detect_hardware(unsigned int port,
1338 unsigned char *addr,
1339- struct kcs_data *data)
1340+ struct si_sm_data *data)
1341 {
1342- unsigned char msg[2];
1343- unsigned char resp[IPMI_MAX_MSG_LENGTH];
1344- unsigned long resp_len;
1345- enum kcs_result kcs_result;
1346+ unsigned char msg[2];
1347+ unsigned char resp[IPMI_MAX_MSG_LENGTH];
1348+ unsigned long resp_len;
1349+ enum si_sm_result kcs_result;
1350
1351 /* It's impossible for the KCS status register to be all 1's,
1352 (assuming a properly functioning, self-initialized BMC)
1353@@ -798,29 +808,31 @@
1354 useful info. */
1355 msg[0] = IPMI_NETFN_APP_REQUEST << 2;
1356 msg[1] = IPMI_GET_DEVICE_ID_CMD;
1357- start_kcs_transaction(data, msg, 2);
1358+ kcs_smi_handlers.start_transaction(data, msg, 2);
1359
1360- kcs_result = kcs_event(data, 0);
1361+ kcs_result = kcs_smi_handlers.event(data, 0);
1362 for (;;)
1363 {
1364- if (kcs_result == KCS_CALL_WITH_DELAY) {
1365- udelay(100);
1366- kcs_result = kcs_event(data, 100);
1367+ if (kcs_result == SI_SM_CALL_WITH_DELAY) {
1368+ set_current_state(TASK_UNINTERRUPTIBLE);
1369+ schedule_timeout(1);
1370+ kcs_result = kcs_smi_handlers.event(data, 100);
1371 }
1372- else if (kcs_result == KCS_CALL_WITHOUT_DELAY)
1373+ else if (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
1374 {
1375- kcs_result = kcs_event(data, 0);
1376+ kcs_result = kcs_smi_handlers.event(data, 0);
1377 }
1378 else
1379 break;
1380 }
1381- if (kcs_result == KCS_SM_HOSED) {
1382+ if (kcs_result == SI_SM_HOSED) {
1383 /* We couldn't get the state machine to run, so whatever's at
1384 the port is probably not an IPMI KCS interface. */
1385 return -ENODEV;
1386 }
1387 /* Otherwise, we got some data. */
1388- resp_len = kcs_get_result(data, resp, IPMI_MAX_MSG_LENGTH);
1389+ resp_len = kcs_smi_handlers.get_result(data, resp,
1390+ IPMI_MAX_MSG_LENGTH);
1391 if (resp_len < 6)
1392 /* That's odd, it should be longer. */
1393 return -EINVAL;
1394@@ -860,6 +872,36 @@
1395 MODULE_PARM(kcs_irqs, "1-4i");
1396 MODULE_PARM(kcs_ports, "1-4i");
1397
1398+static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
1399+{
1400+ struct kcs_info *info = io->info;
1401+
1402+ return inb(info->port+offset);
1403+}
1404+
1405+static void port_outb(struct si_sm_io *io, unsigned int offset,
1406+ unsigned char b)
1407+{
1408+ struct kcs_info *info = io->info;
1409+
1410+ outb(b, info->port+offset);
1411+}
1412+
1413+static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
1414+{
1415+ struct kcs_info *info = io->info;
1416+
1417+ return readb(info->addr+offset);
1418+}
1419+
1420+static void mem_outb(struct si_sm_io *io, unsigned int offset,
1421+ unsigned char b)
1422+{
1423+ struct kcs_info *info = io->info;
1424+
1425+ writeb(b, info->addr+offset);
1426+}
1427+
1428 /* Returns 0 if initialized, or negative on an error. */
1429 static int init_one_kcs(int kcs_port,
1430 int irq,
1431@@ -902,6 +944,9 @@
1432 kcs_port);
1433 return -EIO;
1434 }
1435+ new_kcs->io.outputb = port_outb;
1436+ new_kcs->io.inputb = port_inb;
1437+ new_kcs->io.info = new_kcs;
1438 } else {
1439 if (request_mem_region(kcs_physaddr, 2, DEVICE_NAME) == NULL) {
1440 kfree(new_kcs);
1441@@ -917,15 +962,18 @@
1442 kcs_physaddr);
1443 return -EIO;
1444 }
1445+ new_kcs->io.outputb = mem_outb;
1446+ new_kcs->io.inputb = mem_inb;
1447+ new_kcs->io.info = new_kcs;
1448 }
1449
1450- new_kcs->kcs_sm = kmalloc(kcs_size(), GFP_KERNEL);
1451+ new_kcs->kcs_sm = kmalloc(kcs_smi_handlers.size(), GFP_KERNEL);
1452 if (!new_kcs->kcs_sm) {
1453 printk(KERN_ERR "ipmi_kcs: out of memory\n");
1454 rv = -ENOMEM;
1455 goto out_err;
1456 }
1457- init_kcs_data(new_kcs->kcs_sm, kcs_port, new_kcs->addr);
1458+ kcs_smi_handlers.init_data(new_kcs->kcs_sm, &(new_kcs->io));
1459 spin_lock_init(&(new_kcs->kcs_lock));
1460 spin_lock_init(&(new_kcs->msg_lock));
1461
1462@@ -1027,11 +1075,7 @@
1463
1464 #ifdef CONFIG_ACPI_INTERPRETER
1465
1466-/* Retrieve the base physical address from ACPI tables. Originally
1467- from Hewlett-Packard simple bmc.c, a GPL KCS driver. */
1468-
1469 #include <linux/acpi.h>
1470-/* A real hack, but everything's not there yet in 2.4. */
1471 #include <acpi/acpi.h>
1472 #include <acpi/actypes.h>
1473 #include <acpi/actbl.h>
1474@@ -1046,37 +1090,69 @@
1475 s8 OEMRevision[4];
1476 s8 CreatorID[4];
1477 s8 CreatorRevision[4];
1478- s16 InterfaceType;
1479+ u8 InterfaceType[2];
1480 s16 SpecificationRevision;
1481+
1482+ /*
1483+ * Bit 0 - SCI interrupt supported
1484+ * Bit 1 - I/O APIC/SAPIC
1485+ */
1486 u8 InterruptType;
1487+
1488+ /* If bit 0 of InterruptType is set, then this is the SCI
1489+ interrupt in the GPEx_STS register. */
1490 u8 GPE;
1491+
1492 s16 Reserved;
1493- u64 GlobalSystemInterrupt;
1494- u8 BaseAddress[12];
1495+
1496+ /* If bit 1 of InterruptType is set, then this is the I/O
1497+ APIC/SAPIC interrupt. */
1498+ u32 GlobalSystemInterrupt;
1499+
1500+ /* The actual register address. */
1501+ struct acpi_generic_address addr;
1502+
1503 u8 UID[4];
1504-} __attribute__ ((packed));
1505
1506-static unsigned long acpi_find_bmc(void)
1507+ s8 spmi_id[1]; /* A '\0' terminated array starts here. */
1508+};
1509+
1510+static int acpi_find_bmc(unsigned long *physaddr, int *port)
1511 {
1512 acpi_status status;
1513- struct acpi_table_header *spmi;
1514- static unsigned long io_base = 0;
1515-
1516- if (io_base != 0)
1517- return io_base;
1518+ struct SPMITable *spmi;
1519
1520 status = acpi_get_firmware_table("SPMI", 1,
1521- ACPI_LOGICAL_ADDRESSING, &spmi);
1522+ ACPI_LOGICAL_ADDRESSING,
1523+ (struct acpi_table_header **) &spmi);
1524+ if (status != AE_OK)
1525+ goto not_found;
1526+
1527+ if (spmi->InterfaceType[0] != 1)
1528+ /* Not IPMI. */
1529+ goto not_found;
1530+
1531+ if (spmi->InterfaceType[1] != 1)
1532+ /* Not KCS. */
1533+ goto not_found;
1534+
1535+ if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
1536+ *physaddr = spmi->addr.address;
1537+ printk("ipmi_kcs_intf: Found ACPI-specified state machine"
1538+ " at memory address 0x%lx\n",
1539+ (unsigned long) spmi->addr.address);
1540+ } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
1541+ *port = spmi->addr.address;
1542+ printk("ipmi_kcs_intf: Found ACPI-specified state machine"
1543+ " at I/O address 0x%x\n",
1544+ (int) spmi->addr.address);
1545+ } else
1546+ goto not_found; /* Not an address type we recognise. */
1547
1548- if (status != AE_OK) {
1549- printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n");
1550- return 0;
1551- }
1552+ return 0;
1553
1554- memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress,
1555- sizeof(io_base));
1556-
1557- return io_base;
1558+ not_found:
1559+ return -ENODEV;
1560 }
1561 #endif
1562
1563@@ -1087,6 +1163,7 @@
1564 int i = 0;
1565 #ifdef CONFIG_ACPI_INTERPRETER
1566 unsigned long physaddr = 0;
1567+ int port = 0;
1568 #endif
1569
1570 if (initialized)
1571@@ -1114,26 +1191,25 @@
1572 /* Only try the defaults if enabled and resources are available
1573 (because they weren't already specified above). */
1574
1575- if (kcs_trydefaults) {
1576+ if (kcs_trydefaults && (pos == 0)) {
1577+ rv = -EINVAL;
1578 #ifdef CONFIG_ACPI_INTERPRETER
1579- if ((physaddr = acpi_find_bmc())) {
1580- if (!check_mem_region(physaddr, 2)) {
1581- rv = init_one_kcs(0,
1582- 0,
1583- physaddr,
1584- &(kcs_infos[pos]));
1585- if (rv == 0)
1586- pos++;
1587- }
1588+ if (rv && (acpi_find_bmc(&physaddr, &port) == 0)) {
1589+ rv = init_one_kcs(port,
1590+ 0,
1591+ physaddr,
1592+ &(kcs_infos[pos]));
1593+ if (rv == 0)
1594+ pos++;
1595 }
1596 #endif
1597- if (!check_region(DEFAULT_IO_PORT, 2)) {
1598+ if (rv) {
1599 rv = init_one_kcs(DEFAULT_IO_PORT,
1600 0,
1601 0,
1602 &(kcs_infos[pos]));
1603 if (rv == 0)
1604- pos++;
1605+ pos++;
1606 }
1607 }
1608
1609@@ -1185,8 +1261,10 @@
1610 conditions removing the timer here. Hopefully this will be
1611 long enough to avoid problems with interrupts still
1612 running. */
1613+ set_current_state(TASK_UNINTERRUPTIBLE);
1614 schedule_timeout(2);
1615 while (!to_clean->timer_stopped) {
1616+ set_current_state(TASK_UNINTERRUPTIBLE);
1617 schedule_timeout(1);
1618 }
1619
1620diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_kcs_sm.c linux-2.4.23/drivers/char/ipmi/ipmi_kcs_sm.c
1621--- linux-2.4.23.org/drivers/char/ipmi/ipmi_kcs_sm.c 2004-01-02 23:31:35.451360779 +0100
1622+++ linux-2.4.23/drivers/char/ipmi/ipmi_kcs_sm.c 2004-01-02 23:33:48.038812473 +0100
1623@@ -37,10 +37,11 @@
1624 * that document.
1625 */
1626
1627-#include <asm/io.h>
1628-#include <asm/string.h> /* Gets rid of memcpy warning */
1629+#include <linux/kernel.h> /* For printk. */
1630+#include <linux/string.h>
1631+#include "ipmi_si_sm.h"
1632
1633-#include "ipmi_kcs_sm.h"
1634+#define IPMI_KCS_VERSION "v28"
1635
1636 /* Set this if you want a printout of why the state machine was hosed
1637 when it gets hosed. */
1638@@ -95,29 +96,28 @@
1639 #define IPMI_ERR_MSG_TRUNCATED 0xc6
1640 #define IPMI_ERR_UNSPECIFIED 0xff
1641
1642-struct kcs_data
1643+struct si_sm_data
1644 {
1645- enum kcs_states state;
1646- unsigned int port;
1647- unsigned char *addr;
1648- unsigned char write_data[MAX_KCS_WRITE_SIZE];
1649- int write_pos;
1650- int write_count;
1651- int orig_write_count;
1652- unsigned char read_data[MAX_KCS_READ_SIZE];
1653- int read_pos;
1654- int truncated;
1655+ enum kcs_states state;
1656+ struct si_sm_io *io;
1657+ unsigned char write_data[MAX_KCS_WRITE_SIZE];
1658+ int write_pos;
1659+ int write_count;
1660+ int orig_write_count;
1661+ unsigned char read_data[MAX_KCS_READ_SIZE];
1662+ int read_pos;
1663+ int truncated;
1664
1665 unsigned int error_retries;
1666 long ibf_timeout;
1667 long obf_timeout;
1668 };
1669
1670-void init_kcs_data(struct kcs_data *kcs, unsigned int port, unsigned char *addr)
1671+static unsigned int init_kcs_data(struct si_sm_data *kcs,
1672+ struct si_sm_io *io)
1673 {
1674 kcs->state = KCS_IDLE;
1675- kcs->port = port;
1676- kcs->addr = addr;
1677+ kcs->io = io;
1678 kcs->write_pos = 0;
1679 kcs->write_count = 0;
1680 kcs->orig_write_count = 0;
1681@@ -126,40 +126,29 @@
1682 kcs->truncated = 0;
1683 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
1684 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
1685-}
1686
1687-/* Remember, init_one_kcs() insured port and addr can't both be set */
1688+ /* Reserve 2 I/O bytes. */
1689+ return 2;
1690+}
1691
1692-static inline unsigned char read_status(struct kcs_data *kcs)
1693+static inline unsigned char read_status(struct si_sm_data *kcs)
1694 {
1695- if (kcs->port)
1696- return inb(kcs->port + 1);
1697- else
1698- return readb(kcs->addr + 1);
1699+ return kcs->io->inputb(kcs->io, 1);
1700 }
1701
1702-static inline unsigned char read_data(struct kcs_data *kcs)
1703+static inline unsigned char read_data(struct si_sm_data *kcs)
1704 {
1705- if (kcs->port)
1706- return inb(kcs->port + 0);
1707- else
1708- return readb(kcs->addr + 0);
1709+ return kcs->io->inputb(kcs->io, 0);
1710 }
1711
1712-static inline void write_cmd(struct kcs_data *kcs, unsigned char data)
1713+static inline void write_cmd(struct si_sm_data *kcs, unsigned char data)
1714 {
1715- if (kcs->port)
1716- outb(data, kcs->port + 1);
1717- else
1718- writeb(data, kcs->addr + 1);
1719+ kcs->io->outputb(kcs->io, 1, data);
1720 }
1721
1722-static inline void write_data(struct kcs_data *kcs, unsigned char data)
1723+static inline void write_data(struct si_sm_data *kcs, unsigned char data)
1724 {
1725- if (kcs->port)
1726- outb(data, kcs->port + 0);
1727- else
1728- writeb(data, kcs->addr + 0);
1729+ kcs->io->outputb(kcs->io, 0, data);
1730 }
1731
1732 /* Control codes. */
1733@@ -179,14 +168,14 @@
1734 #define GET_STATUS_OBF(status) ((status) & 0x01)
1735
1736
1737-static inline void write_next_byte(struct kcs_data *kcs)
1738+static inline void write_next_byte(struct si_sm_data *kcs)
1739 {
1740 write_data(kcs, kcs->write_data[kcs->write_pos]);
1741 (kcs->write_pos)++;
1742 (kcs->write_count)--;
1743 }
1744
1745-static inline void start_error_recovery(struct kcs_data *kcs, char *reason)
1746+static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
1747 {
1748 (kcs->error_retries)++;
1749 if (kcs->error_retries > MAX_ERROR_RETRIES) {
1750@@ -199,7 +188,7 @@
1751 }
1752 }
1753
1754-static inline void read_next_byte(struct kcs_data *kcs)
1755+static inline void read_next_byte(struct si_sm_data *kcs)
1756 {
1757 if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
1758 /* Throw the data away and mark it truncated. */
1759@@ -212,9 +201,8 @@
1760 write_data(kcs, KCS_READ_BYTE);
1761 }
1762
1763-static inline int check_ibf(struct kcs_data *kcs,
1764- unsigned char status,
1765- long time)
1766+static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
1767+ long time)
1768 {
1769 if (GET_STATUS_IBF(status)) {
1770 kcs->ibf_timeout -= time;
1771@@ -229,9 +217,8 @@
1772 return 1;
1773 }
1774
1775-static inline int check_obf(struct kcs_data *kcs,
1776- unsigned char status,
1777- long time)
1778+static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
1779+ long time)
1780 {
1781 if (! GET_STATUS_OBF(status)) {
1782 kcs->obf_timeout -= time;
1783@@ -245,13 +232,13 @@
1784 return 1;
1785 }
1786
1787-static void clear_obf(struct kcs_data *kcs, unsigned char status)
1788+static void clear_obf(struct si_sm_data *kcs, unsigned char status)
1789 {
1790 if (GET_STATUS_OBF(status))
1791 read_data(kcs);
1792 }
1793
1794-static void restart_kcs_transaction(struct kcs_data *kcs)
1795+static void restart_kcs_transaction(struct si_sm_data *kcs)
1796 {
1797 kcs->write_count = kcs->orig_write_count;
1798 kcs->write_pos = 0;
1799@@ -262,7 +249,8 @@
1800 write_cmd(kcs, KCS_WRITE_START);
1801 }
1802
1803-int start_kcs_transaction(struct kcs_data *kcs, char *data, unsigned int size)
1804+static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
1805+ unsigned int size)
1806 {
1807 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
1808 return -1;
1809@@ -284,7 +272,8 @@
1810 return 0;
1811 }
1812
1813-int kcs_get_result(struct kcs_data *kcs, unsigned char *data, int length)
1814+static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data,
1815+ unsigned int length)
1816 {
1817 if (length < kcs->read_pos) {
1818 kcs->read_pos = length;
1819@@ -313,7 +302,7 @@
1820 /* This implements the state machine defined in the IPMI manual, see
1821 that for details on how this works. Divide that flowchart into
1822 sections delimited by "Wait for IBF" and this will become clear. */
1823-enum kcs_result kcs_event(struct kcs_data *kcs, long time)
1824+static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
1825 {
1826 unsigned char status;
1827 unsigned char state;
1828@@ -325,7 +314,7 @@
1829 #endif
1830 /* All states wait for ibf, so just do it here. */
1831 if (!check_ibf(kcs, status, time))
1832- return KCS_CALL_WITH_DELAY;
1833+ return SI_SM_CALL_WITH_DELAY;
1834
1835 /* Just about everything looks at the KCS state, so grab that, too. */
1836 state = GET_STATUS_STATE(status);
1837@@ -336,9 +325,9 @@
1838 clear_obf(kcs, status);
1839
1840 if (GET_STATUS_ATN(status))
1841- return KCS_ATTN;
1842+ return SI_SM_ATTN;
1843 else
1844- return KCS_SM_IDLE;
1845+ return SI_SM_IDLE;
1846
1847 case KCS_START_OP:
1848 if (state != KCS_IDLE) {
1849@@ -405,7 +394,7 @@
1850
1851 if (state == KCS_READ_STATE) {
1852 if (! check_obf(kcs, status, time))
1853- return KCS_CALL_WITH_DELAY;
1854+ return SI_SM_CALL_WITH_DELAY;
1855 read_next_byte(kcs);
1856 } else {
1857 /* We don't implement this exactly like the state
1858@@ -418,7 +407,7 @@
1859 clear_obf(kcs, status);
1860 kcs->orig_write_count = 0;
1861 kcs->state = KCS_IDLE;
1862- return KCS_TRANSACTION_COMPLETE;
1863+ return SI_SM_TRANSACTION_COMPLETE;
1864 }
1865 break;
1866
1867@@ -441,7 +430,7 @@
1868 break;
1869 }
1870 if (! check_obf(kcs, status, time))
1871- return KCS_CALL_WITH_DELAY;
1872+ return SI_SM_CALL_WITH_DELAY;
1873
1874 clear_obf(kcs, status);
1875 write_data(kcs, KCS_READ_BYTE);
1876@@ -456,14 +445,14 @@
1877 }
1878
1879 if (! check_obf(kcs, status, time))
1880- return KCS_CALL_WITH_DELAY;
1881+ return SI_SM_CALL_WITH_DELAY;
1882
1883 clear_obf(kcs, status);
1884 if (kcs->orig_write_count) {
1885 restart_kcs_transaction(kcs);
1886 } else {
1887 kcs->state = KCS_IDLE;
1888- return KCS_TRANSACTION_COMPLETE;
1889+ return SI_SM_TRANSACTION_COMPLETE;
1890 }
1891 break;
1892
1893@@ -472,14 +461,42 @@
1894 }
1895
1896 if (kcs->state == KCS_HOSED) {
1897- init_kcs_data(kcs, kcs->port, kcs->addr);
1898- return KCS_SM_HOSED;
1899+ init_kcs_data(kcs, kcs->io);
1900+ return SI_SM_HOSED;
1901 }
1902
1903- return KCS_CALL_WITHOUT_DELAY;
1904+ return SI_SM_CALL_WITHOUT_DELAY;
1905 }
1906
1907-int kcs_size(void)
1908+static int kcs_size(void)
1909 {
1910- return sizeof(struct kcs_data);
1911+ return sizeof(struct si_sm_data);
1912+}
1913+
1914+static int kcs_detect(struct si_sm_data *kcs)
1915+{
1916+ /* It's impossible for the KCS status register to be all 1's,
1917+ (assuming a properly functioning, self-initialized BMC)
1918+ but that's what you get from reading a bogus address, so we
1919+ test that first. */
1920+ if (read_status(kcs) == 0xff)
1921+ return 1;
1922+
1923+ return 0;
1924 }
1925+
1926+static void kcs_cleanup(struct si_sm_data *kcs)
1927+{
1928+}
1929+
1930+struct si_sm_handlers kcs_smi_handlers =
1931+{
1932+ .version = IPMI_KCS_VERSION,
1933+ .init_data = init_kcs_data,
1934+ .start_transaction = start_kcs_transaction,
1935+ .get_result = get_kcs_result,
1936+ .event = kcs_event,
1937+ .detect = kcs_detect,
1938+ .cleanup = kcs_cleanup,
1939+ .size = kcs_size,
1940+};
1941diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_msghandler.c linux-2.4.23/drivers/char/ipmi/ipmi_msghandler.c
1942--- linux-2.4.23.org/drivers/char/ipmi/ipmi_msghandler.c 2004-01-02 23:31:35.450360987 +0100
1943+++ linux-2.4.23/drivers/char/ipmi/ipmi_msghandler.c 2004-01-02 23:33:48.046810811 +0100
1944@@ -44,16 +44,21 @@
1945 #include <linux/ipmi_smi.h>
1946 #include <linux/notifier.h>
1947 #include <linux/init.h>
1948+#include <linux/proc_fs.h>
1949+
1950+#define IPMI_MSGHANDLER_VERSION "v28"
1951
1952 struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
1953 static int ipmi_init_msghandler(void);
1954
1955 static int initialized = 0;
1956
1957+static struct proc_dir_entry *proc_ipmi_root = NULL;
1958+
1959 #define MAX_EVENTS_IN_QUEUE 25
1960
1961 /* Don't let a message sit in a queue forever, always time it with at lest
1962- the max message timer. */
1963+ the max message timer. This is in milliseconds. */
1964 #define MAX_MSG_TIMEOUT 60000
1965
1966 struct ipmi_user
1967@@ -82,7 +87,8 @@
1968
1969 struct seq_table
1970 {
1971- int inuse : 1;
1972+ unsigned int inuse : 1;
1973+ unsigned int broadcast : 1;
1974
1975 unsigned long timeout;
1976 unsigned long orig_timeout;
1977@@ -169,6 +175,72 @@
1978 /* My LUN. This should generally stay the SMS LUN, but just in
1979 case... */
1980 unsigned char my_lun;
1981+
1982+ /* The event receiver for my BMC, only really used at panic
1983+ shutdown as a place to store this. */
1984+ unsigned char event_receiver;
1985+ unsigned char event_receiver_lun;
1986+ unsigned char local_sel_device;
1987+ unsigned char local_event_generator;
1988+
1989+ /* A cheap hack, if this is non-null and a message to an
1990+ interface comes in with a NULL user, call this routine with
1991+ it. Note that the message will still be freed by the
1992+ caller. This only works on the system interface. */
1993+ void (*null_user_handler)(ipmi_smi_t intf, struct ipmi_smi_msg *msg);
1994+
1995+ /* Proc FS stuff. */
1996+ struct proc_dir_entry *proc_dir;
1997+ char proc_dir_name[10];
1998+
1999+ spinlock_t counter_lock; /* For making counters atomic. */
2000+
2001+ /* Commands we got that were invalid. */
2002+ unsigned int sent_invalid_commands;
2003+
2004+ /* Commands we sent to the MC. */
2005+ unsigned int sent_local_commands;
2006+ /* Responses from the MC that were delivered to a user. */
2007+ unsigned int handled_local_responses;
2008+ /* Responses from the MC that were not delivered to a user. */
2009+ unsigned int unhandled_local_responses;
2010+
2011+ /* Commands we sent out to the IPMB bus. */
2012+ unsigned int sent_ipmb_commands;
2013+ /* Commands sent on the IPMB that had errors on the SEND CMD */
2014+ unsigned int sent_ipmb_command_errs;
2015+ /* Each retransmit increments this count. */
2016+ unsigned int retransmitted_ipmb_commands;
2017+ /* When a message times out (runs out of retransmits) this is
2018+ incremented. */
2019+ unsigned int timed_out_ipmb_commands;
2020+
2021+ /* This is like above, but for broadcasts. Broadcasts are
2022+ *not* included in the above count (they are expected to
2023+ time out). */
2024+ unsigned int timed_out_ipmb_broadcasts;
2025+
2026+ /* Responses I have sent to the IPMB bus. */
2027+ unsigned int sent_ipmb_responses;
2028+
2029+ /* The response was delivered to the user. */
2030+ unsigned int handled_ipmb_responses;
2031+ /* The response had invalid data in it. */
2032+ unsigned int invalid_ipmb_responses;
2033+ /* The response didn't have anyone waiting for it. */
2034+ unsigned int unhandled_ipmb_responses;
2035+
2036+ /* The command was delivered to the user. */
2037+ unsigned int handled_commands;
2038+ /* The command had invalid data in it. */
2039+ unsigned int invalid_commands;
2040+ /* The command didn't have anyone waiting for it. */
2041+ unsigned int unhandled_commands;
2042+
2043+ /* Invalid data in an event. */
2044+ unsigned int invalid_events;
2045+ /* Events that were received with the proper format. */
2046+ unsigned int events;
2047 };
2048
2049 int
2050@@ -328,7 +400,7 @@
2051
2052 static void deliver_response(struct ipmi_recv_msg *msg)
2053 {
2054- msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
2055+ msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
2056 }
2057
2058 /* Find the next sequence number not being used and add the given
2059@@ -338,6 +410,7 @@
2060 struct ipmi_recv_msg *recv_msg,
2061 unsigned long timeout,
2062 int retries,
2063+ int broadcast,
2064 unsigned char *seq,
2065 long *seqid)
2066 {
2067@@ -360,6 +433,7 @@
2068 intf->seq_table[i].timeout = MAX_MSG_TIMEOUT;
2069 intf->seq_table[i].orig_timeout = timeout;
2070 intf->seq_table[i].retries_left = retries;
2071+ intf->seq_table[i].broadcast = broadcast;
2072 intf->seq_table[i].inuse = 1;
2073 intf->seq_table[i].seqid = NEXT_SEQID(intf->seq_table[i].seqid);
2074 *seq = i;
2075@@ -412,8 +486,8 @@
2076
2077
2078 /* Start the timer for a specific sequence table entry. */
2079-static int intf_start_seq_timer(ipmi_smi_t intf,
2080- long msgid)
2081+static int intf_start_seq_timer(ipmi_smi_t intf,
2082+ long msgid)
2083 {
2084 int rv = -ENODEV;
2085 unsigned long flags;
2086@@ -431,9 +505,50 @@
2087 {
2088 struct seq_table *ent = &(intf->seq_table[seq]);
2089 ent->timeout = ent->orig_timeout;
2090+ rv = 0;
2091+ }
2092+ spin_unlock_irqrestore(&(intf->seq_lock), flags);
2093+
2094+ return rv;
2095+}
2096+
2097+/* Got an error for the send message for a specific sequence number. */
2098+static int intf_err_seq(ipmi_smi_t intf,
2099+ long msgid,
2100+ unsigned int err)
2101+{
2102+ int rv = -ENODEV;
2103+ unsigned long flags;
2104+ unsigned char seq;
2105+ unsigned long seqid;
2106+ struct ipmi_recv_msg *msg = NULL;
2107+
2108+
2109+ GET_SEQ_FROM_MSGID(msgid, seq, seqid);
2110+
2111+ spin_lock_irqsave(&(intf->seq_lock), flags);
2112+ /* We do this verification because the user can be deleted
2113+ while a message is outstanding. */
2114+ if ((intf->seq_table[seq].inuse)
2115+ && (intf->seq_table[seq].seqid == seqid))
2116+ {
2117+ struct seq_table *ent = &(intf->seq_table[seq]);
2118+
2119+ ent->inuse = 0;
2120+ msg = ent->recv_msg;
2121+ rv = 0;
2122 }
2123 spin_unlock_irqrestore(&(intf->seq_lock), flags);
2124
2125+ if (msg) {
2126+ msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
2127+ msg->msg_data[0] = err;
2128+ msg->msg.netfn |= 1; /* Convert to a response. */
2129+ msg->msg.data_len = 1;
2130+ msg->msg.data = msg->msg_data;
2131+ deliver_response(msg);
2132+ }
2133+
2134 return rv;
2135 }
2136
2137@@ -769,7 +884,9 @@
2138 struct ipmi_recv_msg *supplied_recv,
2139 int priority,
2140 unsigned char source_address,
2141- unsigned char source_lun)
2142+ unsigned char source_lun,
2143+ int retries,
2144+ unsigned int retry_time_ms)
2145 {
2146 int rv = 0;
2147 struct ipmi_smi_msg *smi_msg;
2148@@ -797,8 +914,11 @@
2149 }
2150
2151 if (addr->channel > IPMI_NUM_CHANNELS) {
2152- rv = -EINVAL;
2153- goto out_err;
2154+ spin_lock_irqsave(&intf->counter_lock, flags);
2155+ intf->sent_invalid_commands++;
2156+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2157+ rv = -EINVAL;
2158+ goto out_err;
2159 }
2160
2161 recv_msg->user = user;
2162@@ -812,8 +932,12 @@
2163
2164
2165 smi_addr = (struct ipmi_system_interface_addr *) addr;
2166- if (smi_addr->lun > 3)
2167+ if (smi_addr->lun > 3) {
2168+ spin_lock_irqsave(&intf->counter_lock, flags);
2169+ intf->sent_invalid_commands++;
2170+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2171 return -EINVAL;
2172+ }
2173
2174 memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr));
2175
2176@@ -824,11 +948,17 @@
2177 {
2178 /* We don't let the user do these, since we manage
2179 the sequence numbers. */
2180+ spin_lock_irqsave(&intf->counter_lock, flags);
2181+ intf->sent_invalid_commands++;
2182+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2183 rv = -EINVAL;
2184 goto out_err;
2185 }
2186
2187 if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) {
2188+ spin_lock_irqsave(&intf->counter_lock, flags);
2189+ intf->sent_invalid_commands++;
2190+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2191 rv = -EMSGSIZE;
2192 goto out_err;
2193 }
2194@@ -840,41 +970,59 @@
2195 if (msg->data_len > 0)
2196 memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
2197 smi_msg->data_size = msg->data_len + 2;
2198+ spin_lock_irqsave(&intf->counter_lock, flags);
2199+ intf->sent_local_commands++;
2200+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2201 } else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
2202 || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
2203 {
2204 struct ipmi_ipmb_addr *ipmb_addr;
2205 unsigned char ipmb_seq;
2206 long seqid;
2207- int broadcast;
2208- int retries;
2209+ int broadcast = 0;
2210
2211 if (addr == NULL) {
2212+ spin_lock_irqsave(&intf->counter_lock, flags);
2213+ intf->sent_invalid_commands++;
2214+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2215 rv = -EINVAL;
2216 goto out_err;
2217 }
2218
2219+ if (retries < 0) {
2220+ if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
2221+ retries = 0; /* Don't retry broadcasts. */
2222+ else
2223+ retries = 4;
2224+ }
2225 if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) {
2226 /* Broadcasts add a zero at the beginning of the
2227 message, but otherwise is the same as an IPMB
2228 address. */
2229 addr->addr_type = IPMI_IPMB_ADDR_TYPE;
2230 broadcast = 1;
2231- retries = 0; /* Don't retry broadcasts. */
2232- } else {
2233- broadcast = 0;
2234- retries = 4;
2235 }
2236
2237+
2238+ /* Default to 1 second retries. */
2239+ if (retry_time_ms == 0)
2240+ retry_time_ms = 1000;
2241+
2242 /* 9 for the header and 1 for the checksum, plus
2243 possibly one for the broadcast. */
2244 if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) {
2245+ spin_lock_irqsave(&intf->counter_lock, flags);
2246+ intf->sent_invalid_commands++;
2247+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2248 rv = -EMSGSIZE;
2249 goto out_err;
2250 }
2251
2252 ipmb_addr = (struct ipmi_ipmb_addr *) addr;
2253 if (ipmb_addr->lun > 3) {
2254+ spin_lock_irqsave(&intf->counter_lock, flags);
2255+ intf->sent_invalid_commands++;
2256+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2257 rv = -EINVAL;
2258 goto out_err;
2259 }
2260@@ -884,6 +1032,9 @@
2261 if (recv_msg->msg.netfn & 0x1) {
2262 /* It's a response, so use the user's sequence
2263 from msgid. */
2264+ spin_lock_irqsave(&intf->counter_lock, flags);
2265+ intf->sent_ipmb_responses++;
2266+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2267 format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid,
2268 msgid, broadcast,
2269 source_address, source_lun);
2270@@ -892,13 +1043,17 @@
2271
2272 spin_lock_irqsave(&(intf->seq_lock), flags);
2273
2274+ spin_lock(&intf->counter_lock);
2275+ intf->sent_ipmb_commands++;
2276+ spin_unlock(&intf->counter_lock);
2277+
2278 /* Create a sequence number with a 1 second
2279 timeout and 4 retries. */
2280- /* FIXME - magic number for the timeout. */
2281 rv = intf_next_seq(intf,
2282 recv_msg,
2283- 1000,
2284+ retry_time_ms,
2285 retries,
2286+ broadcast,
2287 &ipmb_seq,
2288 &seqid);
2289 if (rv) {
2290@@ -934,16 +1089,19 @@
2291 }
2292 } else {
2293 /* Unknown address type. */
2294- rv = -EINVAL;
2295- goto out_err;
2296+ spin_lock_irqsave(&intf->counter_lock, flags);
2297+ intf->sent_invalid_commands++;
2298+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2299+ rv = -EINVAL;
2300+ goto out_err;
2301 }
2302
2303 #if DEBUG_MSGING
2304 {
2305- int m;
2306- for (m=0; m<smi_msg->data_size; m++)
2307- printk(" %2.2x", smi_msg->data[m]);
2308- printk("\n");
2309+ int m;
2310+ for (m=0; m<smi_msg->data_size; m++)
2311+ printk(" %2.2x", smi_msg->data[m]);
2312+ printk("\n");
2313 }
2314 #endif
2315 intf->handlers->sender(intf->send_info, smi_msg, priority);
2316@@ -970,7 +1128,29 @@
2317 NULL, NULL,
2318 priority,
2319 user->intf->my_address,
2320- user->intf->my_lun);
2321+ user->intf->my_lun,
2322+ -1, 0);
2323+}
2324+
2325+int ipmi_request_settime(ipmi_user_t user,
2326+ struct ipmi_addr *addr,
2327+ long msgid,
2328+ struct ipmi_msg *msg,
2329+ int priority,
2330+ int retries,
2331+ unsigned int retry_time_ms)
2332+{
2333+ return i_ipmi_request(user,
2334+ user->intf,
2335+ addr,
2336+ msgid,
2337+ msg,
2338+ NULL, NULL,
2339+ priority,
2340+ user->intf->my_address,
2341+ user->intf->my_lun,
2342+ retries,
2343+ retry_time_ms);
2344 }
2345
2346 int ipmi_request_supply_msgs(ipmi_user_t user,
2347@@ -990,7 +1170,8 @@
2348 supplied_recv,
2349 priority,
2350 user->intf->my_address,
2351- user->intf->my_lun);
2352+ user->intf->my_lun,
2353+ -1, 0);
2354 }
2355
2356 int ipmi_request_with_source(ipmi_user_t user,
2357@@ -1009,7 +1190,124 @@
2358 NULL, NULL,
2359 priority,
2360 source_address,
2361- source_lun);
2362+ source_lun,
2363+ -1, 0);
2364+}
2365+
2366+static int ipmb_file_read_proc(char *page, char **start, off_t off,
2367+ int count, int *eof, void *data)
2368+{
2369+ char *out = (char *) page;
2370+ ipmi_smi_t intf = data;
2371+
2372+ return sprintf(out, "%x\n", intf->my_address);
2373+}
2374+
2375+static int version_file_read_proc(char *page, char **start, off_t off,
2376+ int count, int *eof, void *data)
2377+{
2378+ char *out = (char *) page;
2379+ ipmi_smi_t intf = data;
2380+
2381+ return sprintf(out, "%d.%d\n",
2382+ intf->version_major, intf->version_minor);
2383+}
2384+
2385+static int stat_file_read_proc(char *page, char **start, off_t off,
2386+ int count, int *eof, void *data)
2387+{
2388+ char *out = (char *) page;
2389+ ipmi_smi_t intf = data;
2390+
2391+ out += sprintf(out, "sent_invalid_commands: %d\n",
2392+ intf->sent_invalid_commands);
2393+ out += sprintf(out, "sent_local_commands: %d\n",
2394+ intf->sent_local_commands);
2395+ out += sprintf(out, "handled_local_responses: %d\n",
2396+ intf->handled_local_responses);
2397+ out += sprintf(out, "unhandled_local_responses: %d\n",
2398+ intf->unhandled_local_responses);
2399+ out += sprintf(out, "sent_ipmb_commands: %d\n",
2400+ intf->sent_ipmb_commands);
2401+ out += sprintf(out, "sent_ipmb_command_errs: %d\n",
2402+ intf->sent_ipmb_command_errs);
2403+ out += sprintf(out, "retransmitted_ipmb_commands: %d\n",
2404+ intf->retransmitted_ipmb_commands);
2405+ out += sprintf(out, "timed_out_ipmb_commands: %d\n",
2406+ intf->timed_out_ipmb_commands);
2407+ out += sprintf(out, "timed_out_ipmb_broadcasts: %d\n",
2408+ intf->timed_out_ipmb_broadcasts);
2409+ out += sprintf(out, "sent_ipmb_responses: %d\n",
2410+ intf->sent_ipmb_responses);
2411+ out += sprintf(out, "handled_ipmb_responses: %d\n",
2412+ intf->handled_ipmb_responses);
2413+ out += sprintf(out, "invalid_ipmb_responses: %d\n",
2414+ intf->invalid_ipmb_responses);
2415+ out += sprintf(out, "unhandled_ipmb_responses: %d\n",
2416+ intf->unhandled_ipmb_responses);
2417+ out += sprintf(out, "handled_commands: %d\n",
2418+ intf->handled_commands);
2419+ out += sprintf(out, "invalid_commands: %d\n",
2420+ intf->invalid_commands);
2421+ out += sprintf(out, "unhandled_commands: %d\n",
2422+ intf->unhandled_commands);
2423+ out += sprintf(out, "invalid_events: %d\n",
2424+ intf->invalid_events);
2425+ out += sprintf(out, "events: %d\n",
2426+ intf->events);
2427+
2428+ return (out - ((char *) page));
2429+}
2430+
2431+int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
2432+ read_proc_t *read_proc, write_proc_t *write_proc,
2433+ void *data, struct module *owner)
2434+{
2435+ struct proc_dir_entry *file;
2436+ int rv = 0;
2437+
2438+ file = create_proc_entry(name, 0, smi->proc_dir);
2439+ if (!file)
2440+ rv = -ENOMEM;
2441+ else {
2442+ file->nlink = 1;
2443+ file->data = data;
2444+ file->read_proc = read_proc;
2445+ file->write_proc = write_proc;
2446+ file->owner = owner;
2447+ }
2448+
2449+ return rv;
2450+}
2451+
2452+static int add_proc_entries(ipmi_smi_t smi, int num)
2453+{
2454+ int rv = 0;
2455+
2456+ sprintf(smi->proc_dir_name, "%d", num);
2457+ smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
2458+ if (!smi->proc_dir)
2459+ rv = -ENOMEM;
2460+ else {
2461+ smi->proc_dir->owner = THIS_MODULE;
2462+ }
2463+
2464+ if (rv == 0)
2465+ rv = ipmi_smi_add_proc_entry(smi, "stats",
2466+ stat_file_read_proc, NULL,
2467+ smi, THIS_MODULE);
2468+
2469+ if (rv == 0)
2470+ rv = ipmi_smi_add_proc_entry(smi, "ipmb",
2471+ ipmb_file_read_proc, NULL,
2472+ smi, THIS_MODULE);
2473+
2474+ if (rv == 0)
2475+ rv = ipmi_smi_add_proc_entry(smi, "version",
2476+ version_file_read_proc, NULL,
2477+ smi, THIS_MODULE);
2478+
2479+ return rv;
2480 }
2481
2482 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2483@@ -1040,6 +1338,9 @@
2484 new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
2485 if (!new_intf)
2486 return -ENOMEM;
2487+ memset(new_intf, 0, sizeof(*new_intf));
2488+
2489+ new_intf->proc_dir = NULL;
2490
2491 rv = -ENOMEM;
2492
2493@@ -1069,6 +1370,8 @@
2494 INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
2495 new_intf->all_cmd_rcvr = NULL;
2496
2497+ spin_lock_init(&(new_intf->counter_lock));
2498+
2499 spin_lock_irqsave(&interfaces_lock, flags);
2500 ipmi_interfaces[i] = new_intf;
2501 spin_unlock_irqrestore(&interfaces_lock, flags);
2502@@ -1089,6 +1392,9 @@
2503 /* Well, it went away. Just return. */
2504 goto out;
2505
2506+ if (rv == 0)
2507+ rv = add_proc_entries(*intf, i);
2508+
2509 if (rv == 0) {
2510 /* Call all the watcher interfaces to tell them that a
2511 new interface is available. */
2512@@ -1096,7 +1402,11 @@
2513 list_for_each(entry, &smi_watchers) {
2514 struct ipmi_smi_watcher *w;
2515 w = list_entry(entry, struct ipmi_smi_watcher, link);
2516- w->new_smi(i);
2517+ if (try_inc_mod_count(w->owner)) {
2518+ w->new_smi(i);
2519+ if (w->owner)
2520+ __MOD_DEC_USE_COUNT(w->owner);
2521+ }
2522 }
2523 up_read(&smi_watchers_sem);
2524 }
2525@@ -1104,8 +1414,12 @@
2526 out:
2527 up_read(&interfaces_sem);
2528
2529- if (rv)
2530+ if (rv) {
2531+ if (new_intf->proc_dir)
2532+ remove_proc_entry(new_intf->proc_dir_name,
2533+ proc_ipmi_root);
2534 kfree(new_intf);
2535+ }
2536
2537 return rv;
2538 }
2539@@ -1163,6 +1477,8 @@
2540 {
2541 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2542 if (ipmi_interfaces[i] == intf) {
2543+ remove_proc_entry(intf->proc_dir_name,
2544+ proc_ipmi_root);
2545 spin_lock_irqsave(&interfaces_lock, flags);
2546 ipmi_interfaces[i] = NULL;
2547 clean_up_interface_data(intf);
2548@@ -1204,15 +1520,21 @@
2549 {
2550 struct ipmi_ipmb_addr ipmb_addr;
2551 struct ipmi_recv_msg *recv_msg;
2552+ unsigned long flags;
2553
2554
2555- if (msg->rsp_size < 11)
2556+ if (msg->rsp_size < 11) {
2557 /* Message not big enough, just ignore it. */
2558+ spin_lock_irqsave(&intf->counter_lock, flags);
2559+ intf->invalid_ipmb_responses++;
2560+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2561 return 0;
2562+ }
2563
2564- if (msg->rsp[2] != 0)
2565+ if (msg->rsp[2] != 0) {
2566 /* An error getting the response, just ignore it. */
2567 return 0;
2568+ }
2569
2570 ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
2571 ipmb_addr.slave_addr = msg->rsp[6];
2572@@ -1231,6 +1553,9 @@
2573 {
2574 /* We were unable to find the sequence number,
2575 so just nuke the message. */
2576+ spin_lock_irqsave(&intf->counter_lock, flags);
2577+ intf->unhandled_ipmb_responses++;
2578+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2579 return 0;
2580 }
2581
2582@@ -1244,6 +1569,9 @@
2583 recv_msg->msg.data = recv_msg->msg_data;
2584 recv_msg->msg.data_len = msg->rsp_size - 10;
2585 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
2586+ spin_lock_irqsave(&intf->counter_lock, flags);
2587+ intf->handled_ipmb_responses++;
2588+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2589 deliver_response(recv_msg);
2590
2591 return 0;
2592@@ -1252,18 +1580,23 @@
2593 static int handle_get_msg_cmd(ipmi_smi_t intf,
2594 struct ipmi_smi_msg *msg)
2595 {
2596- struct list_head *entry;
2597+ struct list_head *entry;
2598 struct cmd_rcvr *rcvr;
2599- int rv = 0;
2600- unsigned char netfn;
2601- unsigned char cmd;
2602- ipmi_user_t user = NULL;
2603+ int rv = 0;
2604+ unsigned char netfn;
2605+ unsigned char cmd;
2606+ ipmi_user_t user = NULL;
2607 struct ipmi_ipmb_addr *ipmb_addr;
2608 struct ipmi_recv_msg *recv_msg;
2609+ unsigned long flags;
2610
2611- if (msg->rsp_size < 10)
2612+ if (msg->rsp_size < 10) {
2613 /* Message not big enough, just ignore it. */
2614+ spin_lock_irqsave(&intf->counter_lock, flags);
2615+ intf->invalid_commands++;
2616+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2617 return 0;
2618+ }
2619
2620 if (msg->rsp[2] != 0) {
2621 /* An error getting the response, just ignore it. */
2622@@ -1291,6 +1624,10 @@
2623
2624 if (user == NULL) {
2625 /* We didn't find a user, deliver an error response. */
2626+ spin_lock_irqsave(&intf->counter_lock, flags);
2627+ intf->unhandled_commands++;
2628+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2629+
2630 msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
2631 msg->data[1] = IPMI_SEND_MSG_CMD;
2632 msg->data[2] = msg->rsp[3];
2633@@ -1311,6 +1648,10 @@
2634 causes it to not be freed or queued. */
2635 } else {
2636 /* Deliver the message to the user. */
2637+ spin_lock_irqsave(&intf->counter_lock, flags);
2638+ intf->handled_commands++;
2639+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2640+
2641 recv_msg = ipmi_alloc_recv_msg();
2642 if (! recv_msg) {
2643 /* We couldn't allocate memory for the
2644@@ -1374,6 +1715,9 @@
2645
2646 if (msg->rsp_size < 19) {
2647 /* Message is too small to be an IPMB event. */
2648+ spin_lock_irqsave(&intf->counter_lock, flags);
2649+ intf->invalid_events++;
2650+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2651 return 0;
2652 }
2653
2654@@ -1386,6 +1730,10 @@
2655
2656 spin_lock_irqsave(&(intf->events_lock), flags);
2657
2658+ spin_lock(&intf->counter_lock);
2659+ intf->events++;
2660+ spin_unlock(&intf->counter_lock);
2661+
2662 /* Allocate and fill in one message for every user that is getting
2663 events. */
2664 list_for_each(entry, &(intf->users)) {
2665@@ -1459,6 +1807,7 @@
2666 struct ipmi_recv_msg *recv_msg;
2667 int found = 0;
2668 struct list_head *entry;
2669+ unsigned long flags;
2670
2671 recv_msg = (struct ipmi_recv_msg *) msg->user_data;
2672
2673@@ -1474,11 +1823,20 @@
2674 }
2675
2676 if (!found) {
2677+ /* Special handling for NULL users. */
2678+ if (!recv_msg->user && intf->null_user_handler)
2679+ intf->null_user_handler(intf, msg);
2680 /* The user for the message went away, so give up. */
2681+ spin_lock_irqsave(&intf->counter_lock, flags);
2682+ intf->unhandled_local_responses++;
2683+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2684 ipmi_free_recv_msg(recv_msg);
2685 } else {
2686 struct ipmi_system_interface_addr *smi_addr;
2687
2688+ spin_lock_irqsave(&intf->counter_lock, flags);
2689+ intf->handled_local_responses++;
2690+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2691 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
2692 recv_msg->msgid = msg->msgid;
2693 smi_addr = ((struct ipmi_system_interface_addr *)
2694@@ -1505,7 +1863,7 @@
2695 static int handle_new_recv_msg(ipmi_smi_t intf,
2696 struct ipmi_smi_msg *msg)
2697 {
2698- int requeue;
2699+ int requeue;
2700
2701 if (msg->rsp_size < 2) {
2702 /* Message is too small to be correct. */
2703@@ -1551,10 +1909,30 @@
2704 working on it. */
2705 read_lock(&(intf->users_lock));
2706
2707- if ((msg->data_size >= 2) && (msg->data[1] == IPMI_SEND_MSG_CMD)) {
2708+ if ((msg->data_size >= 2)
2709+ && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
2710+ && (msg->data[1] == IPMI_SEND_MSG_CMD)) {
2711 /* This is the local response to a send, start the
2712 timer for these. */
2713- intf_start_seq_timer(intf, msg->msgid);
2714+
2715+ /* Check for errors, if we get certain errors (ones
2716+ that mean basically we can try again later), we
2717+ ignore them and start the timer. Otherwise we
2718+ report the error immediately. */
2719+ if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0)
2720+ && (msg->rsp[2] != IPMI_NODE_BUSY_ERR)
2721+ && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR))
2722+ {
2723+ /* Got an error sending the message, handle it. */
2724+ spin_lock_irqsave(&intf->counter_lock, flags);
2725+ intf->sent_ipmb_command_errs++;
2726+ spin_unlock_irqrestore(&intf->counter_lock, flags);
2727+ intf_err_seq(intf, msg->msgid, msg->rsp[2]);
2728+ } else {
2729+ /* The message was sent, start the timer. */
2730+ intf_start_seq_timer(intf, msg->msgid);
2731+ }
2732+
2733 ipmi_free_smi_msg(msg);
2734 goto out_unlock;
2735 }
2736@@ -1699,6 +2077,12 @@
2737 ent->inuse = 0;
2738 msg = ent->recv_msg;
2739 list_add_tail(&(msg->link), &timeouts);
2740+ spin_lock(&intf->counter_lock);
2741+ if (ent->broadcast)
2742+ intf->timed_out_ipmb_broadcasts++;
2743+ else
2744+ intf->timed_out_ipmb_commands++;
2745+ spin_unlock(&intf->counter_lock);
2746 } else {
2747 /* More retries, send again. */
2748
2749@@ -1708,6 +2092,9 @@
2750 ent->retries_left--;
2751 send_from_recv_msg(intf, ent->recv_msg, NULL,
2752 j, ent->seqid);
2753+ spin_lock(&intf->counter_lock);
2754+ intf->retransmitted_ipmb_commands++;
2755+ spin_unlock(&intf->counter_lock);
2756 }
2757 }
2758 spin_unlock_irqrestore(&(intf->seq_lock), flags);
2759@@ -1740,13 +2127,16 @@
2760
2761 static struct timer_list ipmi_timer;
2762
2763-/* Call every 100 ms. */
2764+/* Call every ~100 ms. */
2765 #define IPMI_TIMEOUT_TIME 100
2766-#define IPMI_TIMEOUT_JIFFIES (IPMI_TIMEOUT_TIME/(1000/HZ))
2767
2768-/* Request events from the queue every second. Hopefully, in the
2769- future, IPMI will add a way to know immediately if an event is
2770- in the queue. */
2771+/* How many jiffies does it take to get to the timeout time. */
2772+#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
2773+
2774+/* Request events from the queue every second (this is the number of
2775+ IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
2776+ future, IPMI will add a way to know immediately if an event is in
2777+ the queue and this silliness can go away. */
2778 #define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
2779
2780 static volatile int stop_operation = 0;
2781@@ -1822,18 +2212,48 @@
2782 {
2783 }
2784
2785-static void send_panic_events(void)
2786+#ifdef CONFIG_IPMI_PANIC_STRING
2787+static void event_receiver_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
2788+{
2789+ if ((msg->rsp[0] == (IPMI_NETFN_SENSOR_EVENT_RESPONSE << 2))
2790+ && (msg->rsp[1] == IPMI_GET_EVENT_RECEIVER_CMD)
2791+ && (msg->rsp[2] == IPMI_CC_NO_ERROR))
2792+ {
2793+ /* A get event receiver command, save it. */
2794+ intf->event_receiver = msg->rsp[3];
2795+ intf->event_receiver_lun = msg->rsp[4] & 0x3;
2796+ }
2797+}
2798+
2799+static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
2800+{
2801+ if ((msg->rsp[0] == (IPMI_NETFN_APP_RESPONSE << 2))
2802+ && (msg->rsp[1] == IPMI_GET_DEVICE_ID_CMD)
2803+ && (msg->rsp[2] == IPMI_CC_NO_ERROR))
2804+ {
2805+ /* A get device id command, save if we are an event
2806+ receiver or generator. */
2807+ intf->local_sel_device = (msg->rsp[8] >> 2) & 1;
2808+ intf->local_event_generator = (msg->rsp[8] >> 5) & 1;
2809+ }
2810+}
2811+#endif
2812+
2813+static void send_panic_events(char *str)
2814 {
2815 struct ipmi_msg msg;
2816 ipmi_smi_t intf;
2817- unsigned char data[8];
2818+ unsigned char data[16];
2819 int i;
2820- struct ipmi_system_interface_addr addr;
2821+ struct ipmi_system_interface_addr *si;
2822+ struct ipmi_addr addr;
2823 struct ipmi_smi_msg smi_msg;
2824 struct ipmi_recv_msg recv_msg;
2825
2826- addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2827- addr.channel = IPMI_BMC_CHANNEL;
2828+ si = (struct ipmi_system_interface_addr *) &addr;
2829+ si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2830+ si->channel = IPMI_BMC_CHANNEL;
2831+ si->lun = 0;
2832
2833 /* Fill in an event telling that we have failed. */
2834 msg.netfn = 0x04; /* Sensor or Event. */
2835@@ -1846,12 +2266,13 @@
2836 data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */
2837 data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */
2838
2839- /* These used to have the first three bytes of the panic string,
2840- but not only is that not terribly useful, it's not available
2841- any more. */
2842- data[3] = 0;
2843- data[6] = 0;
2844- data[7] = 0;
2845+ /* Put a few breadcrums in. Hopefully later we can add more things
2846+ to make the panic events more useful. */
2847+ if (str) {
2848+ data[3] = str[0];
2849+ data[6] = str[1];
2850+ data[7] = str[2];
2851+ }
2852
2853 smi_msg.done = dummy_smi_done_handler;
2854 recv_msg.done = dummy_recv_done_handler;
2855@@ -1862,18 +2283,147 @@
2856 if (intf == NULL)
2857 continue;
2858
2859+ /* Send the event announcing the panic. */
2860 intf->handlers->set_run_to_completion(intf->send_info, 1);
2861 i_ipmi_request(NULL,
2862 intf,
2863- (struct ipmi_addr *) &addr,
2864+ &addr,
2865 0,
2866 &msg,
2867 &smi_msg,
2868 &recv_msg,
2869 0,
2870 intf->my_address,
2871- intf->my_lun);
2872+ intf->my_lun,
2873+ 0, 1); /* Don't retry, and don't wait. */
2874 }
2875+
2876+#ifdef CONFIG_IPMI_PANIC_STRING
2877+ /* On every interface, dump a bunch of OEM event holding the
2878+ string. */
2879+ if (!str)
2880+ return;
2881+
2882+ for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2883+ char *p = str;
2884+ struct ipmi_ipmb_addr *ipmb;
2885+ int j;
2886+
2887+ intf = ipmi_interfaces[i];
2888+ if (intf == NULL)
2889+ continue;
2890+
2891+ /* First job here is to figure out where to send the
2892+ OEM events. There's no way in IPMI to send OEM
2893+ events using an event send command, so we have to
2894+ find the SEL to put them in and stick them in
2895+ there. */
2896+
2897+ /* Get capabilities from the get device id. */
2898+ intf->local_sel_device = 0;
2899+ intf->local_event_generator = 0;
2900+ intf->event_receiver = 0;
2901+
2902+ /* Request the device info from the local MC. */
2903+ msg.netfn = IPMI_NETFN_APP_REQUEST;
2904+ msg.cmd = IPMI_GET_DEVICE_ID_CMD;
2905+ msg.data = NULL;
2906+ msg.data_len = 0;
2907+ intf->null_user_handler = device_id_fetcher;
2908+ i_ipmi_request(NULL,
2909+ intf,
2910+ &addr,
2911+ 0,
2912+ &msg,
2913+ &smi_msg,
2914+ &recv_msg,
2915+ 0,
2916+ intf->my_address,
2917+ intf->my_lun,
2918+ 0, 1); /* Don't retry, and don't wait. */
2919+
2920+ if (intf->local_event_generator) {
2921+ /* Request the event receiver from the local MC. */
2922+ msg.netfn = IPMI_NETFN_SENSOR_EVENT_REQUEST;
2923+ msg.cmd = IPMI_GET_EVENT_RECEIVER_CMD;
2924+ msg.data = NULL;
2925+ msg.data_len = 0;
2926+ intf->null_user_handler = event_receiver_fetcher;
2927+ i_ipmi_request(NULL,
2928+ intf,
2929+ &addr,
2930+ 0,
2931+ &msg,
2932+ &smi_msg,
2933+ &recv_msg,
2934+ 0,
2935+ intf->my_address,
2936+ intf->my_lun,
2937+ 0, 1); /* no retry, and no wait. */
2938+ }
2939+ intf->null_user_handler = NULL;
2940+
2941+ /* Validate the event receiver. The low bit must not
2942+ be 1 (it must be a valid IPMB address), it cannot
2943+ be zero, and it must not be my address. */
2944+ if (((intf->event_receiver & 1) == 0)
2945+ && (intf->event_receiver != 0)
2946+ && (intf->event_receiver != intf->my_address))
2947+ {
2948+ /* The event receiver is valid, send an IPMB
2949+ message. */
2950+ ipmb = (struct ipmi_ipmb_addr *) &addr;
2951+ ipmb->addr_type = IPMI_IPMB_ADDR_TYPE;
2952+ ipmb->channel = 0; /* FIXME - is this right? */
2953+ ipmb->lun = intf->event_receiver_lun;
2954+ ipmb->slave_addr = intf->event_receiver;
2955+ } else if (intf->local_sel_device) {
2956+ /* The event receiver was not valid (or was
2957+ me), but I am an SEL device, just dump it
2958+ in my SEL. */
2959+ si = (struct ipmi_system_interface_addr *) &addr;
2960+ si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2961+ si->channel = IPMI_BMC_CHANNEL;
2962+ si->lun = 0;
2963+ } else
2964+ continue; /* No where to send the event. */
2965+
2966+
2967+ msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */
2968+ msg.cmd = IPMI_ADD_SEL_ENTRY_CMD;
2969+ msg.data = data;
2970+ msg.data_len = 16;
2971+
2972+ j = 0;
2973+ while (*p) {
2974+ int size = strlen(p);
2975+
2976+ if (size > 11)
2977+ size = 11;
2978+ data[0] = 0;
2979+ data[1] = 0;
2980+ data[2] = 0xf0; /* OEM event without timestamp. */
2981+ data[3] = intf->my_address;
2982+ data[4] = j++; /* sequence # */
2983+ /* Always give 11 bytes, so strncpy will fill
2984+ it with zeroes for me. */
2985+ strncpy(data+5, p, 11);
2986+ p += size;
2987+
2988+ i_ipmi_request(NULL,
2989+ intf,
2990+ &addr,
2991+ 0,
2992+ &msg,
2993+ &smi_msg,
2994+ &recv_msg,
2995+ 0,
2996+ intf->my_address,
2997+ intf->my_lun,
2998+ 0, 1); /* no retry, and no wait. */
2999+ }
3000+ }
3001+#endif /* CONFIG_IPMI_PANIC_STRING */
3002 }
3003 #endif /* CONFIG_IPMI_PANIC_EVENT */
3004
3005@@ -1900,7 +2450,7 @@
3006 }
3007
3008 #ifdef CONFIG_IPMI_PANIC_EVENT
3009- send_panic_events();
3010+ send_panic_events(ptr);
3011 #endif
3012
3013 return NOTIFY_DONE;
3014@@ -1912,7 +2462,6 @@
3015 200 /* priority: INT_MAX >= x >= 0 */
3016 };
3017
3018-
3019 static __init int ipmi_init_msghandler(void)
3020 {
3021 int i;
3022@@ -1920,10 +2469,21 @@
3023 if (initialized)
3024 return 0;
3025
3026+ printk(KERN_INFO "ipmi message handler version "
3027+ IPMI_MSGHANDLER_VERSION "\n");
3028+
3029 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
3030 ipmi_interfaces[i] = NULL;
3031 }
3032
3033+ proc_ipmi_root = proc_mkdir("ipmi", 0);
3034+ if (!proc_ipmi_root) {
3035+ printk("Unable to create IPMI proc dir\n");
3036+ return -ENOMEM;
3037+ }
3038+
3039+ proc_ipmi_root->owner = THIS_MODULE;
3040+
3041 init_timer(&ipmi_timer);
3042 ipmi_timer.data = 0;
3043 ipmi_timer.function = ipmi_timeout;
3044@@ -1934,8 +2494,6 @@
3045
3046 initialized = 1;
3047
3048- printk(KERN_INFO "ipmi: message handler initialized\n");
3049-
3050 return 0;
3051 }
3052
3053@@ -1955,6 +2513,7 @@
3054 problems with race conditions removing the timer here. */
3055 stop_operation = 1;
3056 while (!timer_stopped) {
3057+ set_current_state(TASK_UNINTERRUPTIBLE);
3058 schedule_timeout(1);
3059 }
3060
3061@@ -1980,6 +2539,7 @@
3062 EXPORT_SYMBOL(ipmi_destroy_user);
3063 EXPORT_SYMBOL(ipmi_get_version);
3064 EXPORT_SYMBOL(ipmi_request);
3065+EXPORT_SYMBOL(ipmi_request_settime);
3066 EXPORT_SYMBOL(ipmi_request_supply_msgs);
3067 EXPORT_SYMBOL(ipmi_request_with_source);
3068 EXPORT_SYMBOL(ipmi_register_smi);
3069@@ -2001,3 +2561,4 @@
3070 EXPORT_SYMBOL(ipmi_get_my_address);
3071 EXPORT_SYMBOL(ipmi_set_my_LUN);
3072 EXPORT_SYMBOL(ipmi_get_my_LUN);
3073+EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
3074diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_si.c linux-2.4.23/drivers/char/ipmi/ipmi_si.c
3075--- linux-2.4.23.org/drivers/char/ipmi/ipmi_si.c 1970-01-01 01:00:00.000000000 +0100
3076+++ linux-2.4.23/drivers/char/ipmi/ipmi_si.c 2004-01-02 23:33:48.054809149 +0100
3077@@ -0,0 +1,2083 @@
3078+/*
3079+ * ipmi_si.c
3080+ *
3081+ * The interface to the IPMI driver for the system interfaces (KCS, SMIC,
3082+ * BT in the future).
3083+ *
3084+ * Author: MontaVista Software, Inc.
3085+ * Corey Minyard <minyard@mvista.com>
3086+ * source@mvista.com
3087+ *
3088+ * Copyright 2002 MontaVista Software Inc.
3089+ *
3090+ * This program is free software; you can redistribute it and/or modify it
3091+ * under the terms of the GNU General Public License as published by the
3092+ * Free Software Foundation; either version 2 of the License, or (at your
3093+ * option) any later version.
3094+ *
3095+ *
3096+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
3097+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
3098+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
3099+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
3100+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
3101+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
3102+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
3103+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
3104+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
3105+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3106+ *
3107+ * You should have received a copy of the GNU General Public License along
3108+ * with this program; if not, write to the Free Software Foundation, Inc.,
3109+ * 675 Mass Ave, Cambridge, MA 02139, USA.
3110+ */
3111+
3112+/*
3113+ * This file holds the "policy" for the interface to the SMI state
3114+ * machine. It does the configuration, handles timers and interrupts,
3115+ * and drives the real SMI state machine.
3116+ */
3117+
3118+#include <linux/config.h>
3119+#include <linux/module.h>
3120+#include <asm/system.h>
3121+#include <linux/sched.h>
3122+#include <linux/timer.h>
3123+#include <linux/errno.h>
3124+#include <linux/spinlock.h>
3125+#include <linux/slab.h>
3126+#include <linux/delay.h>
3127+#include <linux/list.h>
3128+#include <linux/pci.h>
3129+#include <linux/ioport.h>
3130+#ifdef CONFIG_HIGH_RES_TIMERS
3131+#include <linux/hrtime.h>
3132+# if defined(schedule_next_int)
3133+/* Old high-res timer code, do translations. */
3134+# define get_arch_cycles(a) quick_update_jiffies_sub(a)
3135+# define arch_cycles_per_jiffy cycles_per_jiffies
3136+# endif
3137+static inline void add_usec_to_timer(struct timer_list *t, long v)
3138+{
3139+ t->sub_expires += nsec_to_arch_cycle(v * 1000);
3140+ while (t->sub_expires >= arch_cycles_per_jiffy)
3141+ {
3142+ t->expires++;
3143+ t->sub_expires -= arch_cycles_per_jiffy;
3144+ }
3145+}
3146+#endif
3147+#include <linux/interrupt.h>
3148+#include <linux/ipmi_smi.h>
3149+#include <asm/io.h>
3150+#include "ipmi_si_sm.h"
3151+#include <linux/init.h>
3152+
3153+#define IPMI_SI_VERSION "v28"
3154+
3155+/* Measure times between events in the driver. */
3156+#undef DEBUG_TIMING
3157+
3158+/* Call every 10 ms when nothing is going on. */
3159+#define SI_TIMEOUT_TIME_USEC 10000
3160+#define SI_USEC_PER_JIFFY (1000000/HZ)
3161+#define SI_TIMEOUT_JIFFIES (SI_TIMEOUT_TIME_USEC/SI_USEC_PER_JIFFY)
3162+#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a
3163+ short timeout */
3164+
3165+enum si_intf_state {
3166+ SI_NORMAL,
3167+ SI_GETTING_FLAGS,
3168+ SI_GETTING_EVENTS,
3169+ SI_CLEARING_FLAGS,
3170+ SI_CLEARING_FLAGS_THEN_SET_IRQ,
3171+ SI_GETTING_MESSAGES,
3172+ SI_ENABLE_INTERRUPTS1,
3173+ SI_ENABLE_INTERRUPTS2
3174+ /* FIXME - add watchdog stuff. */
3175+};
3176+
3177+enum si_type {
3178+ SI_KCS, SI_SMIC, SI_BT
3179+};
3180+
3181+struct smi_info
3182+{
3183+ ipmi_smi_t intf;
3184+ struct si_sm_data *si_sm;
3185+ struct si_sm_handlers *handlers;
3186+ enum si_type si_type;
3187+ spinlock_t si_lock;
3188+ spinlock_t msg_lock;
3189+ struct list_head xmit_msgs;
3190+ struct list_head hp_xmit_msgs;
3191+ struct ipmi_smi_msg *curr_msg;
3192+ enum si_intf_state si_state;
3193+
3194+ /* Used to handle the various types of I/O that can occur with
3195+ IPMI */
3196+ struct si_sm_io io;
3197+ int (*io_setup)(struct smi_info *info);
3198+ void (*io_cleanup)(struct smi_info *info);
3199+ int (*irq_setup)(struct smi_info *info);
3200+ void (*irq_cleanup)(struct smi_info *info);
3201+ unsigned int io_size;
3202+
3203+ /* Flags from the last GET_MSG_FLAGS command, used when an ATTN
3204+ is set to hold the flags until we are done handling everything
3205+ from the flags. */
3206+#define RECEIVE_MSG_AVAIL 0x01
3207+#define EVENT_MSG_BUFFER_FULL 0x02
3208+#define WDT_PRE_TIMEOUT_INT 0x08
3209+ unsigned char msg_flags;
3210+
3211+ /* If set to true, this will request events the next time the
3212+ state machine is idle. */
3213+ atomic_t req_events;
3214+
3215+ /* If true, run the state machine to completion on every send
3216+ call. Generally used after a panic to make sure stuff goes
3217+ out. */
3218+ int run_to_completion;
3219+
3220+ /* The I/O port of an SI interface. */
3221+ int port;
3222+
3223+ /* zero if no irq; */
3224+ int irq;
3225+
3226+ /* The timer for this si. */
3227+ struct timer_list si_timer;
3228+
3229+ /* The time (in jiffies) the last timeout occurred at. */
3230+ unsigned long last_timeout_jiffies;
3231+
3232+ /* Used to gracefully stop the timer without race conditions. */
3233+ volatile int stop_operation;
3234+ volatile int timer_stopped;
3235+
3236+ /* The driver will disable interrupts when it gets into a
3237+ situation where it cannot handle messages due to lack of
3238+ memory. Once that situation clears up, it will re-enable
3239+ interrupts. */
3240+ int interrupt_disabled;
3241+
3242+ unsigned char ipmi_si_dev_rev;
3243+ unsigned char ipmi_si_fw_rev_major;
3244+ unsigned char ipmi_si_fw_rev_minor;
3245+ unsigned char ipmi_version_major;
3246+ unsigned char ipmi_version_minor;
3247+
3248+ /* Counters and things for the proc filesystem. */
3249+ spinlock_t count_lock;
3250+ unsigned long short_timeouts;
3251+ unsigned long long_timeouts;
3252+ unsigned long timeout_restarts;
3253+ unsigned long idles;
3254+ unsigned long interrupts;
3255+ unsigned long attentions;
3256+ unsigned long flag_fetches;
3257+ unsigned long hosed_count;
3258+ unsigned long complete_transactions;
3259+ unsigned long events;
3260+ unsigned long watchdog_pretimeouts;
3261+ unsigned long incoming_messages;
3262+};
3263+
3264+static void si_restart_short_timer(struct smi_info *smi_info);
3265+
3266+static void deliver_recv_msg(struct smi_info *smi_info,
3267+ struct ipmi_smi_msg *msg)
3268+{
3269+ /* Deliver the message to the upper layer with the lock
3270+ released. */
3271+ spin_unlock(&(smi_info->si_lock));
3272+ ipmi_smi_msg_received(smi_info->intf, msg);
3273+ spin_lock(&(smi_info->si_lock));
3274+}
3275+
3276+static void return_hosed_msg(struct smi_info *smi_info)
3277+{
3278+ struct ipmi_smi_msg *msg = smi_info->curr_msg;
3279+
3280+ /* Make it a reponse */
3281+ msg->rsp[0] = msg->data[0] | 4;
3282+ msg->rsp[1] = msg->data[1];
3283+ msg->rsp[2] = 0xFF; /* Unknown error. */
3284+ msg->rsp_size = 3;
3285+
3286+ smi_info->curr_msg = NULL;
3287+ deliver_recv_msg(smi_info, msg);
3288+}
3289+
3290+static enum si_sm_result start_next_msg(struct smi_info *smi_info)
3291+{
3292+ int rv;
3293+ struct list_head *entry = NULL;
3294+#ifdef DEBUG_TIMING
3295+ struct timeval t;
3296+#endif
3297+
3298+ /* No need to save flags, we aleady have interrupts off and we
3299+ already hold the SMI lock. */
3300+ spin_lock(&(smi_info->msg_lock));
3301+
3302+ /* Pick the high priority queue first. */
3303+ if (! list_empty(&(smi_info->hp_xmit_msgs))) {
3304+ entry = smi_info->hp_xmit_msgs.next;
3305+ } else if (! list_empty(&(smi_info->xmit_msgs))) {
3306+ entry = smi_info->xmit_msgs.next;
3307+ }
3308+
3309+ if (!entry) {
3310+ smi_info->curr_msg = NULL;
3311+ rv = SI_SM_IDLE;
3312+ } else {
3313+ int err;
3314+
3315+ list_del(entry);
3316+ smi_info->curr_msg = list_entry(entry,
3317+ struct ipmi_smi_msg,
3318+ link);
3319+#ifdef DEBUG_TIMING
3320+ do_gettimeofday(&t);
3321+ printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3322+#endif
3323+ err = smi_info->handlers->start_transaction(
3324+ smi_info->si_sm,
3325+ smi_info->curr_msg->data,
3326+ smi_info->curr_msg->data_size);
3327+ if (err) {
3328+ return_hosed_msg(smi_info);
3329+ }
3330+
3331+ rv = SI_SM_CALL_WITHOUT_DELAY;
3332+ }
3333+ spin_unlock(&(smi_info->msg_lock));
3334+
3335+ return rv;
3336+}
3337+
3338+static void start_enable_irq(struct smi_info *smi_info)
3339+{
3340+ unsigned char msg[2];
3341+
3342+ /* If we are enabling interrupts, we have to tell the
3343+ BMC to use them. */
3344+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3345+ msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
3346+
3347+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
3348+ smi_info->si_state = SI_ENABLE_INTERRUPTS1;
3349+}
3350+
3351+static void start_clear_flags(struct smi_info *smi_info)
3352+{
3353+ unsigned char msg[3];
3354+
3355+ /* Make sure the watchdog pre-timeout flag is not set at startup. */
3356+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3357+ msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
3358+ msg[2] = WDT_PRE_TIMEOUT_INT;
3359+
3360+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
3361+ smi_info->si_state = SI_CLEARING_FLAGS;
3362+}
3363+
3364+/* When we have a situtaion where we run out of memory and cannot
3365+ allocate messages, we just leave them in the BMC and run the system
3366+ polled until we can allocate some memory. Once we have some
3367+ memory, we will re-enable the interrupt. */
3368+static inline void disable_si_irq(struct smi_info *smi_info)
3369+{
3370+ if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
3371+ disable_irq_nosync(smi_info->irq);
3372+ smi_info->interrupt_disabled = 1;
3373+ }
3374+}
3375+
3376+static inline void enable_si_irq(struct smi_info *smi_info)
3377+{
3378+ if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
3379+ enable_irq(smi_info->irq);
3380+ smi_info->interrupt_disabled = 0;
3381+ }
3382+}
3383+
3384+static void handle_flags(struct smi_info *smi_info)
3385+{
3386+ if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) {
3387+ /* Watchdog pre-timeout */
3388+ spin_lock(&smi_info->count_lock);
3389+ smi_info->watchdog_pretimeouts++;
3390+ spin_unlock(&smi_info->count_lock);
3391+
3392+ start_clear_flags(smi_info);
3393+ smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
3394+ spin_unlock(&(smi_info->si_lock));
3395+ ipmi_smi_watchdog_pretimeout(smi_info->intf);
3396+ spin_lock(&(smi_info->si_lock));
3397+ } else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) {
3398+ /* Messages available. */
3399+ smi_info->curr_msg = ipmi_alloc_smi_msg();
3400+ if (!smi_info->curr_msg) {
3401+ disable_si_irq(smi_info);
3402+ smi_info->si_state = SI_NORMAL;
3403+ return;
3404+ }
3405+ enable_si_irq(smi_info);
3406+
3407+ smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
3408+ smi_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
3409+ smi_info->curr_msg->data_size = 2;
3410+
3411+ smi_info->handlers->start_transaction(
3412+ smi_info->si_sm,
3413+ smi_info->curr_msg->data,
3414+ smi_info->curr_msg->data_size);
3415+ smi_info->si_state = SI_GETTING_MESSAGES;
3416+ } else if (smi_info->msg_flags & EVENT_MSG_BUFFER_FULL) {
3417+ /* Events available. */
3418+ smi_info->curr_msg = ipmi_alloc_smi_msg();
3419+ if (!smi_info->curr_msg) {
3420+ disable_si_irq(smi_info);
3421+ smi_info->si_state = SI_NORMAL;
3422+ return;
3423+ }
3424+ enable_si_irq(smi_info);
3425+
3426+ smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
3427+ smi_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
3428+ smi_info->curr_msg->data_size = 2;
3429+
3430+ smi_info->handlers->start_transaction(
3431+ smi_info->si_sm,
3432+ smi_info->curr_msg->data,
3433+ smi_info->curr_msg->data_size);
3434+ smi_info->si_state = SI_GETTING_EVENTS;
3435+ } else {
3436+ smi_info->si_state = SI_NORMAL;
3437+ }
3438+}
3439+
3440+static void handle_transaction_done(struct smi_info *smi_info)
3441+{
3442+ struct ipmi_smi_msg *msg;
3443+#ifdef DEBUG_TIMING
3444+ struct timeval t;
3445+
3446+ do_gettimeofday(&t);
3447+ printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3448+#endif
3449+ switch (smi_info->si_state) {
3450+ case SI_NORMAL:
3451+ if (!smi_info->curr_msg)
3452+ break;
3453+
3454+ smi_info->curr_msg->rsp_size
3455+ = smi_info->handlers->get_result(
3456+ smi_info->si_sm,
3457+ smi_info->curr_msg->rsp,
3458+ IPMI_MAX_MSG_LENGTH);
3459+
3460+ /* Do this here becase deliver_recv_msg() releases the
3461+ lock, and a new message can be put in during the
3462+ time the lock is released. */
3463+ msg = smi_info->curr_msg;
3464+ smi_info->curr_msg = NULL;
3465+ deliver_recv_msg(smi_info, msg);
3466+ break;
3467+
3468+ case SI_GETTING_FLAGS:
3469+ {
3470+ unsigned char msg[4];
3471+ unsigned int len;
3472+
3473+ /* We got the flags from the SMI, now handle them. */
3474+ len = smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
3475+ if (msg[2] != 0) {
3476+ /* Error fetching flags, just give up for
3477+ now. */
3478+ smi_info->si_state = SI_NORMAL;
3479+ } else if (len < 3) {
3480+ /* Hmm, no flags. That's technically illegal, but
3481+ don't use uninitialized data. */
3482+ smi_info->si_state = SI_NORMAL;
3483+ } else {
3484+ smi_info->msg_flags = msg[3];
3485+ handle_flags(smi_info);
3486+ }
3487+ break;
3488+ }
3489+
3490+ case SI_CLEARING_FLAGS:
3491+ case SI_CLEARING_FLAGS_THEN_SET_IRQ:
3492+ {
3493+ unsigned char msg[3];
3494+
3495+ /* We cleared the flags. */
3496+ smi_info->handlers->get_result(smi_info->si_sm, msg, 3);
3497+ if (msg[2] != 0) {
3498+ /* Error clearing flags */
3499+ printk(KERN_WARNING
3500+ "ipmi_smi: Error clearing flags: %2.2x\n",
3501+ msg[2]);
3502+ }
3503+ if (smi_info->si_state == SI_CLEARING_FLAGS_THEN_SET_IRQ)
3504+ start_enable_irq(smi_info);
3505+ else
3506+ smi_info->si_state = SI_NORMAL;
3507+ break;
3508+ }
3509+
3510+ case SI_GETTING_EVENTS:
3511+ {
3512+ smi_info->curr_msg->rsp_size
3513+ = smi_info->handlers->get_result(
3514+ smi_info->si_sm,
3515+ smi_info->curr_msg->rsp,
3516+ IPMI_MAX_MSG_LENGTH);
3517+
3518+ /* Do this here becase deliver_recv_msg() releases the
3519+ lock, and a new message can be put in during the
3520+ time the lock is released. */
3521+ msg = smi_info->curr_msg;
3522+ smi_info->curr_msg = NULL;
3523+ if (msg->rsp[2] != 0) {
3524+ /* Error getting event, probably done. */
3525+ msg->done(msg);
3526+
3527+ /* Take off the event flag. */
3528+ smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
3529+ } else {
3530+ spin_lock(&smi_info->count_lock);
3531+ smi_info->events++;
3532+ spin_unlock(&smi_info->count_lock);
3533+
3534+ deliver_recv_msg(smi_info, msg);
3535+ }
3536+ handle_flags(smi_info);
3537+ break;
3538+ }
3539+
3540+ case SI_GETTING_MESSAGES:
3541+ {
3542+ smi_info->curr_msg->rsp_size
3543+ = smi_info->handlers->get_result(
3544+ smi_info->si_sm,
3545+ smi_info->curr_msg->rsp,
3546+ IPMI_MAX_MSG_LENGTH);
3547+
3548+ /* Do this here becase deliver_recv_msg() releases the
3549+ lock, and a new message can be put in during the
3550+ time the lock is released. */
3551+ msg = smi_info->curr_msg;
3552+ smi_info->curr_msg = NULL;
3553+ if (msg->rsp[2] != 0) {
3554+ /* Error getting event, probably done. */
3555+ msg->done(msg);
3556+
3557+ /* Take off the msg flag. */
3558+ smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
3559+ } else {
3560+ spin_lock(&smi_info->count_lock);
3561+ smi_info->incoming_messages++;
3562+ spin_unlock(&smi_info->count_lock);
3563+
3564+ deliver_recv_msg(smi_info, msg);
3565+ }
3566+ handle_flags(smi_info);
3567+ break;
3568+ }
3569+
3570+ case SI_ENABLE_INTERRUPTS1:
3571+ {
3572+ unsigned char msg[4];
3573+
3574+ /* We got the flags from the SMI, now handle them. */
3575+ smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
3576+ if (msg[2] != 0) {
3577+ printk(KERN_WARNING
3578+ "ipmi_smi: Could not enable interrupts"
3579+ ", failed get, using polled mode.\n");
3580+ smi_info->si_state = SI_NORMAL;
3581+ } else {
3582+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3583+ msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
3584+ msg[2] = msg[3] | 1; /* enable msg queue int */
3585+ smi_info->handlers->start_transaction(
3586+ smi_info->si_sm, msg, 3);
3587+ smi_info->si_state = SI_ENABLE_INTERRUPTS2;
3588+ }
3589+ break;
3590+ }
3591+
3592+ case SI_ENABLE_INTERRUPTS2:
3593+ {
3594+ unsigned char msg[4];
3595+
3596+ /* We got the flags from the SMI, now handle them. */
3597+ smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
3598+ if (msg[2] != 0) {
3599+ printk(KERN_WARNING
3600+ "ipmi_smi: Could not enable interrupts"
3601+ ", failed set, using polled mode.\n");
3602+ }
3603+ smi_info->si_state = SI_NORMAL;
3604+ break;
3605+ }
3606+ }
3607+}
3608+
3609+/* Called on timeouts and events. Timeouts should pass the elapsed
3610+ time, interrupts should pass in zero. */
3611+static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
3612+ int time)
3613+{
3614+ enum si_sm_result si_sm_result;
3615+
3616+ restart:
3617+ /* There used to be a loop here that waited a little while
3618+ (around 25us) before giving up. That turned out to be
3619+ pointless, the minimum delays I was seeing were in the 300us
3620+ range, which is far too long to wait in an interrupt. So
3621+ we just run until the state machine tells us something
3622+ happened or it needs a delay. */
3623+ si_sm_result = smi_info->handlers->event(smi_info->si_sm, time);
3624+ time = 0;
3625+ while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY)
3626+ {
3627+ si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3628+ }
3629+
3630+ if (si_sm_result == SI_SM_TRANSACTION_COMPLETE)
3631+ {
3632+ spin_lock(&smi_info->count_lock);
3633+ smi_info->complete_transactions++;
3634+ spin_unlock(&smi_info->count_lock);
3635+
3636+ handle_transaction_done(smi_info);
3637+ si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3638+ }
3639+ else if (si_sm_result == SI_SM_HOSED)
3640+ {
3641+ spin_lock(&smi_info->count_lock);
3642+ smi_info->hosed_count++;
3643+ spin_unlock(&smi_info->count_lock);
3644+
3645+ if (smi_info->curr_msg != NULL) {
3646+ /* If we were handling a user message, format
3647+ a response to send to the upper layer to
3648+ tell it about the error. */
3649+ return_hosed_msg(smi_info);
3650+ }
3651+ si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3652+ smi_info->si_state = SI_NORMAL;
3653+ }
3654+
3655+ /* We prefer handling attn over new messages. */
3656+ if (si_sm_result == SI_SM_ATTN)
3657+ {
3658+ unsigned char msg[2];
3659+
3660+ spin_lock(&smi_info->count_lock);
3661+ smi_info->attentions++;
3662+ spin_unlock(&smi_info->count_lock);
3663+
3664+ /* Got a attn, send down a get message flags to see
3665+ what's causing it. It would be better to handle
3666+ this in the upper layer, but due to the way
3667+ interrupts work with the SMI, that's not really
3668+ possible. */
3669+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3670+ msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3671+
3672+ smi_info->handlers->start_transaction(
3673+ smi_info->si_sm, msg, 2);
3674+ smi_info->si_state = SI_GETTING_FLAGS;
3675+ goto restart;
3676+ }
3677+
3678+ /* If we are currently idle, try to start the next message. */
3679+ if (si_sm_result == SI_SM_IDLE) {
3680+ spin_lock(&smi_info->count_lock);
3681+ smi_info->idles++;
3682+ spin_unlock(&smi_info->count_lock);
3683+
3684+ si_sm_result = start_next_msg(smi_info);
3685+ if (si_sm_result != SI_SM_IDLE)
3686+ goto restart;
3687+ }
3688+
3689+ if ((si_sm_result == SI_SM_IDLE)
3690+ && (atomic_read(&smi_info->req_events)))
3691+ {
3692+ /* We are idle and the upper layer requested that I fetch
3693+ events, so do so. */
3694+ unsigned char msg[2];
3695+
3696+ spin_lock(&smi_info->count_lock);
3697+ smi_info->flag_fetches++;
3698+ spin_unlock(&smi_info->count_lock);
3699+
3700+ atomic_set(&smi_info->req_events, 0);
3701+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3702+ msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3703+
3704+ smi_info->handlers->start_transaction(
3705+ smi_info->si_sm, msg, 2);
3706+ smi_info->si_state = SI_GETTING_FLAGS;
3707+ goto restart;
3708+ }
3709+
3710+ return si_sm_result;
3711+}
3712+
3713+static void sender(void *send_info,
3714+ struct ipmi_smi_msg *msg,
3715+ int priority)
3716+{
3717+ struct smi_info *smi_info = (struct smi_info *) send_info;
3718+ enum si_sm_result result;
3719+ unsigned long flags;
3720+#ifdef DEBUG_TIMING
3721+ struct timeval t;
3722+#endif
3723+
3724+ spin_lock_irqsave(&(smi_info->msg_lock), flags);
3725+#ifdef DEBUG_TIMING
3726+ do_gettimeofday(&t);
3727+ printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3728+#endif
3729+
3730+ if (smi_info->run_to_completion) {
3731+ /* If we are running to completion, then throw it in
3732+ the list and run transactions until everything is
3733+ clear. Priority doesn't matter here. */
3734+ list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
3735+
3736+ /* We have to release the msg lock and claim the smi
3737+ lock in this case, because of race conditions. */
3738+ spin_unlock_irqrestore(&(smi_info->msg_lock), flags);
3739+
3740+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3741+ result = smi_event_handler(smi_info, 0);
3742+ while (result != SI_SM_IDLE) {
3743+ udelay(SI_SHORT_TIMEOUT_USEC);
3744+ result = smi_event_handler(smi_info,
3745+ SI_SHORT_TIMEOUT_USEC);
3746+ }
3747+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3748+ return;
3749+ } else {
3750+ if (priority > 0) {
3751+ list_add_tail(&(msg->link), &(smi_info->hp_xmit_msgs));
3752+ } else {
3753+ list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
3754+ }
3755+ }
3756+ spin_unlock_irqrestore(&(smi_info->msg_lock), flags);
3757+
3758+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3759+ if ((smi_info->si_state == SI_NORMAL)
3760+ && (smi_info->curr_msg == NULL))
3761+ {
3762+ start_next_msg(smi_info);
3763+ si_restart_short_timer(smi_info);
3764+ }
3765+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3766+}
3767+
3768+static void set_run_to_completion(void *send_info, int i_run_to_completion)
3769+{
3770+ struct smi_info *smi_info = (struct smi_info *) send_info;
3771+ enum si_sm_result result;
3772+ unsigned long flags;
3773+
3774+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3775+
3776+ smi_info->run_to_completion = i_run_to_completion;
3777+ if (i_run_to_completion) {
3778+ result = smi_event_handler(smi_info, 0);
3779+ while (result != SI_SM_IDLE) {
3780+ udelay(SI_SHORT_TIMEOUT_USEC);
3781+ result = smi_event_handler(smi_info,
3782+ SI_SHORT_TIMEOUT_USEC);
3783+ }
3784+ }
3785+
3786+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3787+}
3788+
3789+static void request_events(void *send_info)
3790+{
3791+ struct smi_info *smi_info = (struct smi_info *) send_info;
3792+
3793+ atomic_set(&smi_info->req_events, 1);
3794+}
3795+
3796+static int new_user(void *send_info)
3797+{
3798+ if (!try_inc_mod_count(THIS_MODULE))
3799+ return -EBUSY;
3800+ return 0;
3801+}
3802+
3803+static void user_left(void *send_info)
3804+{
3805+ MOD_DEC_USE_COUNT;
3806+}
3807+
3808+static int initialized = 0;
3809+
3810+/* Must be called with interrupts off and with the si_lock held. */
3811+static void si_restart_short_timer(struct smi_info *smi_info)
3812+{
3813+#if defined(CONFIG_HIGH_RES_TIMERS)
3814+ unsigned long flags;
3815+ unsigned long jiffies_now;
3816+
3817+ if (del_timer(&(smi_info->si_timer))) {
3818+ /* If we don't delete the timer, then it will go off
3819+ immediately, anyway. So we only process if we
3820+ actually delete the timer. */
3821+
3822+ /* We already have irqsave on, so no need for it
3823+ here. */
3824+ read_lock(&xtime_lock);
3825+ jiffies_now = jiffies;
3826+ smi_info->si_timer.expires = jiffies_now;
3827+ smi_info->si_timer.sub_expires = get_arch_cycles(jiffies_now);
3828+ read_unlock(&xtime_lock);
3829+
3830+ add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
3831+
3832+ add_timer(&(smi_info->si_timer));
3833+ spin_lock_irqsave(&smi_info->count_lock, flags);
3834+ smi_info->timeout_restarts++;
3835+ spin_unlock_irqrestore(&smi_info->count_lock, flags);
3836+ }
3837+#endif
3838+}
3839+
3840+static void smi_timeout(unsigned long data)
3841+{
3842+ struct smi_info *smi_info = (struct smi_info *) data;
3843+ enum si_sm_result smi_result;
3844+ unsigned long flags;
3845+ unsigned long jiffies_now;
3846+ unsigned long time_diff;
3847+#ifdef DEBUG_TIMING
3848+ struct timeval t;
3849+#endif
3850+
3851+ if (smi_info->stop_operation) {
3852+ smi_info->timer_stopped = 1;
3853+ return;
3854+ }
3855+
3856+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3857+#ifdef DEBUG_TIMING
3858+ do_gettimeofday(&t);
3859+ printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3860+#endif
3861+ jiffies_now = jiffies;
3862+ time_diff = ((jiffies_now - smi_info->last_timeout_jiffies)
3863+ * SI_USEC_PER_JIFFY);
3864+ smi_result = smi_event_handler(smi_info, time_diff);
3865+
3866+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3867+
3868+ smi_info->last_timeout_jiffies = jiffies_now;
3869+
3870+ if ((smi_info->irq) && (! smi_info->interrupt_disabled)) {
3871+ /* Running with interrupts, only do long timeouts. */
3872+ smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
3873+ spin_lock_irqsave(&smi_info->count_lock, flags);
3874+ smi_info->long_timeouts++;
3875+ spin_unlock_irqrestore(&smi_info->count_lock, flags);
3876+ goto do_add_timer;
3877+ }
3878+
3879+ /* If the state machine asks for a short delay, then shorten
3880+ the timer timeout. */
3881+ if (smi_result == SI_SM_CALL_WITH_DELAY) {
3882+ spin_lock_irqsave(&smi_info->count_lock, flags);
3883+ smi_info->short_timeouts++;
3884+ spin_unlock_irqrestore(&smi_info->count_lock, flags);
3885+#if defined(CONFIG_HIGH_RES_TIMERS)
3886+ read_lock(&xtime_lock);
3887+ smi_info->si_timer.expires = jiffies;
3888+ smi_info->si_timer.sub_expires
3889+ = get_arch_cycles(smi_info->si_timer.expires);
3890+ read_unlock(&xtime_lock);
3891+ add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
3892+#else
3893+ smi_info->si_timer.expires = jiffies + 1;
3894+#endif
3895+ } else {
3896+ spin_lock_irqsave(&smi_info->count_lock, flags);
3897+ smi_info->long_timeouts++;
3898+ spin_unlock_irqrestore(&smi_info->count_lock, flags);
3899+ smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
3900+#if defined(CONFIG_HIGH_RES_TIMERS)
3901+ smi_info->si_timer.sub_expires = 0;
3902+#endif
3903+ }
3904+
3905+ do_add_timer:
3906+ add_timer(&(smi_info->si_timer));
3907+}
3908+
3909+static void si_irq_handler(int irq, void *data, struct pt_regs *regs)
3910+{
3911+ struct smi_info *smi_info = (struct smi_info *) data;
3912+ unsigned long flags;
3913+#ifdef DEBUG_TIMING
3914+ struct timeval t;
3915+#endif
3916+
3917+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3918+
3919+ spin_lock(&smi_info->count_lock);
3920+ smi_info->interrupts++;
3921+ spin_unlock(&smi_info->count_lock);
3922+
3923+ if (smi_info->stop_operation)
3924+ goto out;
3925+
3926+#ifdef DEBUG_TIMING
3927+ do_gettimeofday(&t);
3928+ printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3929+#endif
3930+ smi_event_handler(smi_info, 0);
3931+ out:
3932+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3933+}
3934+
3935+static struct ipmi_smi_handlers handlers =
3936+{
3937+ sender: sender,
3938+ request_events: request_events,
3939+ new_user: new_user,
3940+ user_left: user_left,
3941+ set_run_to_completion: set_run_to_completion
3942+};
3943+
3944+/* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
3945+ a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */
3946+
3947+#define SI_MAX_PARMS 4
3948+#define SI_MAX_DRIVERS ((SI_MAX_PARMS * 2) + 2)
3949+static struct smi_info *smi_infos[SI_MAX_DRIVERS] =
3950+{ NULL, NULL, NULL, NULL };
3951+
3952+#define DEVICE_NAME "ipmi_si"
3953+
3954+#define DEFAULT_KCS_IO_PORT 0xca2
3955+#define DEFAULT_SMIC_IO_PORT 0xca9
3956+#define DEFAULT_BT_IO_PORT 0xe4
3957+
3958+static int si_trydefaults = 1;
3959+static char *si_type[SI_MAX_PARMS] = { NULL, NULL, NULL, NULL };
3960+static unsigned long si_addrs[SI_MAX_PARMS] = { 0, 0, 0, 0 };
3961+static unsigned int si_ports[SI_MAX_PARMS] = { 0, 0, 0, 0 };
3962+static int si_irqs[SI_MAX_PARMS] = { 0, 0, 0, 0 };
3963+
3964+
3965+MODULE_PARM(si_trydefaults, "i");
3966+MODULE_PARM(si_type, "1-4s");
3967+MODULE_PARM(si_addrs, "1-4l");
3968+MODULE_PARM(si_irqs, "1-4i");
3969+MODULE_PARM(si_ports, "1-4i");
3970+
3971+
3972+#if defined(CONFIG_ACPI_INTERPRETER) || defined(CONFIG_X86) || defined(CONFIG_PCI)
3973+#define IPMI_MEM_ADDR_SPACE 1
3974+#define IPMI_IO_ADDR_SPACE 2
3975+static int is_new_interface(int intf, u8 addr_space, unsigned long base_addr)
3976+{
3977+ int i;
3978+
3979+ for (i = 0; i < SI_MAX_PARMS; ++i) {
3980+ /* Don't check our address. */
3981+ if (i == intf)
3982+ continue;
3983+ if (si_type[i] != NULL) {
3984+ if ((addr_space == IPMI_MEM_ADDR_SPACE &&
3985+ base_addr == si_addrs[i]) ||
3986+ (addr_space == IPMI_IO_ADDR_SPACE &&
3987+ base_addr == si_ports[i]))
3988+ return 0;
3989+ }
3990+ else
3991+ break;
3992+ }
3993+
3994+ return 1;
3995+}
3996+#endif
3997+
3998+static int std_irq_setup(struct smi_info *info)
3999+{
4000+ int rv;
4001+
4002+ if (!info->irq)
4003+ return 0;
4004+
4005+ rv = request_irq(info->irq,
4006+ si_irq_handler,
4007+ SA_INTERRUPT,
4008+ DEVICE_NAME,
4009+ info);
4010+ if (rv) {
4011+ printk(KERN_WARNING
4012+ "ipmi_smi: %s unable to claim interrupt %d,"
4013+ " running polled\n",
4014+ DEVICE_NAME, info->irq);
4015+ info->irq = 0;
4016+ } else {
4017+ printk(" Using irq %d\n", info->irq);
4018+ }
4019+
4020+ return rv;
4021+}
4022+
4023+static void std_irq_cleanup(struct smi_info *info)
4024+{
4025+ if (!info->irq)
4026+ return;
4027+
4028+ free_irq(info->irq, info);
4029+}
4030+
4031+static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
4032+{
4033+ unsigned int *addr = io->info;
4034+
4035+ return inb((*addr)+offset);
4036+}
4037+
4038+static void port_outb(struct si_sm_io *io, unsigned int offset,
4039+ unsigned char b)
4040+{
4041+ unsigned int *addr = io->info;
4042+
4043+ outb(b, (*addr)+offset);
4044+}
4045+
4046+static int port_setup(struct smi_info *info)
4047+{
4048+ unsigned int *addr = info->io.info;
4049+
4050+ if (!addr || (!*addr))
4051+ return -ENODEV;
4052+
4053+ if (request_region(*addr, info->io_size, DEVICE_NAME) == NULL)
4054+ return -EIO;
4055+ return 0;
4056+}
4057+
4058+static void port_cleanup(struct smi_info *info)
4059+{
4060+ unsigned int *addr = info->io.info;
4061+
4062+ if (addr && (*addr))
4063+ release_region (*addr, info->io_size);
4064+ kfree(info);
4065+}
4066+
4067+static int try_init_port(int intf_num, struct smi_info **new_info)
4068+{
4069+ struct smi_info *info;
4070+
4071+ if (!si_ports[intf_num])
4072+ return -ENODEV;
4073+
4074+ if (!is_new_interface(intf_num, IPMI_IO_ADDR_SPACE,
4075+ si_ports[intf_num]))
4076+ return -ENODEV;
4077+
4078+ info = kmalloc(sizeof(*info), GFP_KERNEL);
4079+ if (!info) {
4080+ printk("ipmi_smi: Could not allocate SMI data\n");
4081+ return -ENOMEM;
4082+ }
4083+ memset(info, 0, sizeof(*info));
4084+
4085+ info->io_setup = port_setup;
4086+ info->io_cleanup = port_cleanup;
4087+ info->io.inputb = port_inb;
4088+ info->io.outputb = port_outb;
4089+ info->io.info = &(si_ports[intf_num]);
4090+ info->irq = 0;
4091+ info->irq_setup = NULL;
4092+ *new_info = info;
4093+
4094+ printk("ipmi_smi: Trying state machine at I/O address 0x%x\n",
4095+ si_ports[intf_num]);
4096+ return 0;
4097+}
4098+
4099+static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
4100+{
4101+ return readb((io->addr)+offset);
4102+}
4103+
4104+static void mem_outb(struct si_sm_io *io, unsigned int offset,
4105+ unsigned char b)
4106+{
4107+ writeb(b, (io->addr)+offset);
4108+}
4109+
4110+static int mem_setup(struct smi_info *info)
4111+{
4112+ unsigned long addr = (unsigned long) info->io.info;
4113+
4114+ if (!addr)
4115+ return -ENODEV;
4116+
4117+ if (request_mem_region(addr, info->io_size, DEVICE_NAME) == NULL)
4118+ return -EIO;
4119+ info->io.addr = ioremap(addr, info->io_size);
4120+ if (info->io.addr == NULL) {
4121+ release_mem_region(addr, info->io_size);
4122+ return -EIO;
4123+ }
4124+ return 0;
4125+}
4126+
4127+static void mem_cleanup(struct smi_info *info)
4128+{
4129+ unsigned long addr = (unsigned long) info->io.info;
4130+
4131+ if (info->io.addr) {
4132+ iounmap(info->io.addr);
4133+ release_mem_region(addr, info->io_size);
4134+ }
4135+ kfree(info);
4136+}
4137+
4138+static int try_init_mem(int intf_num, struct smi_info **new_info)
4139+{
4140+ struct smi_info *info;
4141+
4142+ if (!si_addrs[intf_num])
4143+ return -ENODEV;
4144+
4145+ if (!is_new_interface(intf_num, IPMI_MEM_ADDR_SPACE,
4146+ si_addrs[intf_num]))
4147+ return -ENODEV;
4148+
4149+ info = kmalloc(sizeof(*info), GFP_KERNEL);
4150+ if (!info) {
4151+ printk("ipmi_smi: Could not allocate SMI data\n");
4152+ return -ENOMEM;
4153+ }
4154+ memset(info, 0, sizeof(*info));
4155+
4156+ info->io_setup = mem_setup;
4157+ info->io_cleanup = mem_cleanup;
4158+ info->io.inputb = mem_inb;
4159+ info->io.outputb = mem_outb;
4160+ info->io.info = (void *) si_addrs[intf_num];
4161+ info->irq = 0;
4162+ info->irq_setup = NULL;
4163+ *new_info = info;
4164+
4165+ printk("ipmi_smi: Trying state machine at memory address 0x%lx\n",
4166+ si_addrs[intf_num]);
4167+ return 0;
4168+}
4169+
4170+#ifdef CONFIG_ACPI_INTERPRETER
4171+
4172+#include <linux/acpi.h>
4173+#include <acpi/acpi.h>
4174+#include <acpi/actypes.h>
4175+#include <acpi/actbl.h>
4176+
4177+/* Once we get an ACPI failure, we don't try any more, because we go
4178+ through the tables sequentially. Once we don't find a table, there
4179+ are no more. */
4180+static int acpi_failure = 0;
4181+
4182+/* For GPE-type interrupts. */
4183+void ipmi_acpi_gpe(void *context)
4184+{
4185+ struct smi_info *smi_info = context;
4186+ unsigned long flags;
4187+#ifdef DEBUG_TIMING
4188+ struct timeval t;
4189+#endif
4190+
4191+ spin_lock_irqsave(&(smi_info->si_lock), flags);
4192+
4193+ spin_lock(&smi_info->count_lock);
4194+ smi_info->interrupts++;
4195+ spin_unlock(&smi_info->count_lock);
4196+
4197+ if (smi_info->stop_operation)
4198+ goto out;
4199+
4200+#ifdef DEBUG_TIMING
4201+ do_gettimeofday(&t);
4202+ printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
4203+#endif
4204+ smi_event_handler(smi_info, 0);
4205+ out:
4206+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
4207+}
4208+
4209+static int acpi_gpe_irq_setup(struct smi_info *info)
4210+{
4211+ acpi_status status;
4212+
4213+ if (!info->irq)
4214+ return 0;
4215+
4216+ /* FIXME - is level triggered right? */
4217+ status = acpi_install_gpe_handler(NULL,
4218+ info->irq,
1473c4cd 4219+ ACPI_GPE_LEVEL_TRIGGERED,
409d0572
AM
4220+ ipmi_acpi_gpe,
4221+ info);
4222+ if (status != AE_OK) {
4223+ printk(KERN_WARNING
4224+ "ipmi_smi: %s unable to claim ACPI GPE %d,"
4225+ " running polled\n",
4226+ DEVICE_NAME, info->irq);
4227+ info->irq = 0;
4228+ return -EINVAL;
4229+ } else {
4230+ printk(" Using ACPI GPE %d\n", info->irq);
4231+ return 0;
4232+ }
4233+
4234+}
4235+
4236+static void acpi_gpe_irq_cleanup(struct smi_info *info)
4237+{
4238+ if (!info->irq)
4239+ return;
4240+
4241+ acpi_remove_gpe_handler(NULL, info->irq, ipmi_acpi_gpe);
4242+}
4243+
4244+/*
4245+ * Defined at
4246+ * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf
4247+ */
4248+struct SPMITable {
4249+ s8 Signature[4];
4250+ u32 Length;
4251+ u8 Revision;
4252+ u8 Checksum;
4253+ s8 OEMID[6];
4254+ s8 OEMTableID[8];
4255+ s8 OEMRevision[4];
4256+ s8 CreatorID[4];
4257+ s8 CreatorRevision[4];
4258+ u8 InterfaceType[2];
4259+ s16 SpecificationRevision;
4260+
4261+ /*
4262+ * Bit 0 - SCI interrupt supported
4263+ * Bit 1 - I/O APIC/SAPIC
4264+ */
4265+ u8 InterruptType;
4266+
4267+ /* If bit 0 of InterruptType is set, then this is the SCI
4268+ interrupt in the GPEx_STS register. */
4269+ u8 GPE;
4270+
4271+ s16 Reserved;
4272+
4273+ /* If bit 1 of InterruptType is set, then this is the I/O
4274+ APIC/SAPIC interrupt. */
4275+ u32 GlobalSystemInterrupt;
4276+
4277+ /* The actual register address. */
4278+ struct acpi_generic_address addr;
4279+
4280+ u8 UID[4];
4281+
4282+ s8 spmi_id[1]; /* A '\0' terminated array starts here. */
4283+};
4284+
4285+static int try_init_acpi(int intf_num, struct smi_info **new_info)
4286+{
4287+ struct smi_info *info;
4288+ acpi_status status;
4289+ struct SPMITable *spmi;
4290+ char *io_type;
4291+ u8 addr_space;
4292+
4293+ if (acpi_failure)
4294+ return -ENODEV;
4295+
4296+ status = acpi_get_firmware_table("SPMI", intf_num+1,
4297+ ACPI_LOGICAL_ADDRESSING,
4298+ (struct acpi_table_header **) &spmi);
4299+ if (status != AE_OK) {
4300+ acpi_failure = 1;
4301+ return -ENODEV;
4302+ }
4303+
4304+ if (spmi->InterfaceType[0] != 1)
4305+ return -ENODEV;
4306+
4307+ if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
4308+ addr_space = IPMI_MEM_ADDR_SPACE;
4309+ else
4310+ addr_space = IPMI_IO_ADDR_SPACE;
4311+ if (!is_new_interface(-1, addr_space, spmi->addr.address))
4312+ return -ENODEV;
4313+
4314+ /* Figure out the interface type. */
4315+ switch (spmi->InterfaceType[1])
4316+ {
4317+ case 1: /* KCS */
4318+ si_type[intf_num] = "kcs";
4319+ break;
4320+
4321+ case 2: /* SMIC */
4322+ si_type[intf_num] = "smic";
4323+ break;
4324+
4325+ case 3: /* BT */
4326+ si_type[intf_num] = "bt";
4327+ break;
4328+
4329+ default:
4330+ printk("ipmi_smi: Unknown ACPI SMI type.\n");
4331+ return -EIO;
4332+ }
4333+
4334+ info = kmalloc(sizeof(*info), GFP_KERNEL);
4335+ if (!info) {
4336+ printk("ipmi_smi: Could not allocate SMI data\n");
4337+ return -ENOMEM;
4338+ }
4339+ memset(info, 0, sizeof(*info));
4340+
4341+ if (spmi->InterruptType & 1) {
4342+ /* We've got a GPE interrupt. */
4343+ info->irq = spmi->GPE;
4344+ info->irq_setup = acpi_gpe_irq_setup;
4345+ info->irq_cleanup = acpi_gpe_irq_cleanup;
4346+ } else if (spmi->InterruptType & 2) {
4347+ /* We've got an APIC/SAPIC interrupt. */
4348+ info->irq = spmi->GlobalSystemInterrupt;
4349+ info->irq_setup = std_irq_setup;
4350+ info->irq_cleanup = std_irq_cleanup;
4351+ } else {
4352+ /* Use the default interrupt setting. */
4353+ info->irq = 0;
4354+ info->irq_setup = NULL;
4355+ }
4356+
4357+ if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
4358+ io_type = "memory";
4359+ info->io_setup = mem_setup;
4360+ info->io_cleanup = mem_cleanup;
4361+ si_addrs[intf_num] = spmi->addr.address;
4362+ info->io.inputb = mem_inb;
4363+ info->io.outputb = mem_outb;
4364+ info->io.info = &(si_addrs[intf_num]);
4365+ } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
4366+ io_type = "I/O";
4367+ info->io_setup = port_setup;
4368+ info->io_cleanup = port_cleanup;
4369+ si_ports[intf_num] = spmi->addr.address;
4370+ info->io.inputb = port_inb;
4371+ info->io.outputb = port_outb;
4372+ info->io.info = &(si_ports[intf_num]);
4373+ } else {
4374+ kfree(info);
4375+ printk("ipmi_smi: Unknown ACPI I/O Address type.\n");
4376+ return -EIO;
4377+ }
4378+
4379+ *new_info = info;
4380+
4381+ printk("ipmi_smi: Found ACPI-specified state machine at %s"
4382+ " address 0x%lx\n",
4383+ io_type, (unsigned long) spmi->addr.address);
4384+ return 0;
4385+}
4386+#endif
4387+
4388+#ifdef CONFIG_X86
4389+
4390+typedef struct dmi_ipmi_data
4391+{
4392+ u8 type;
4393+ u8 addr_space;
4394+ unsigned long base_addr;
4395+ u8 irq;
4396+}dmi_ipmi_data_t;
4397+
4398+typedef struct dmi_header
4399+{
4400+ u8 type;
4401+ u8 length;
4402+ u16 handle;
4403+}dmi_header_t;
4404+
4405+static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data)
4406+{
4407+ u8 *data = (u8 *)dm;
4408+ unsigned long base_addr;
4409+
4410+ ipmi_data->type = data[0x04];
4411+
4412+ memcpy(&base_addr,&data[0x08],sizeof(unsigned long));
4413+ if (base_addr & 1) {
4414+ /* I/O */
4415+ base_addr &= 0xFFFE;
4416+ ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
4417+ }
4418+ else {
4419+ /* Memory */
4420+ ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE;
4421+ }
4422+
4423+ ipmi_data->base_addr = base_addr;
4424+ ipmi_data->irq = data[0x11];
4425+
4426+ if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr))
4427+ return 0;
4428+
4429+ memset(ipmi_data,0,sizeof(dmi_ipmi_data_t));
4430+
4431+ return -1;
4432+}
4433+
4434+static int dmi_table(u32 base, int len, int num,
4435+ dmi_ipmi_data_t *ipmi_data)
4436+{
4437+ u8 *buf;
4438+ struct dmi_header *dm;
4439+ u8 *data;
4440+ int i=1;
4441+ int status=-1;
4442+
4443+ buf = ioremap(base, len);
4444+ if(buf==NULL)
4445+ return -1;
4446+
4447+ data = buf;
4448+
4449+ while(i<num && (data - buf) < len)
4450+ {
4451+ dm=(dmi_header_t *)data;
4452+
4453+ if((data-buf+dm->length) >= len)
4454+ break;
4455+
4456+ if (dm->type == 38) {
4457+ if (decode_dmi(dm, ipmi_data) == 0) {
4458+ status = 0;
4459+ break;
4460+ }
4461+ }
4462+
4463+ data+=dm->length;
4464+ while((data-buf) < len && (*data || data[1]))
4465+ data++;
4466+ data+=2;
4467+ i++;
4468+ }
4469+ iounmap(buf);
4470+
4471+ return status;
4472+}
4473+
4474+inline static int dmi_checksum(u8 *buf)
4475+{
4476+ u8 sum=0;
4477+ int a;
4478+
4479+ for(a=0; a<15; a++)
4480+ sum+=buf[a];
4481+ return (sum==0);
4482+}
4483+
4484+static int dmi_iterator(dmi_ipmi_data_t *ipmi_data)
4485+{
4486+ u8 buf[15];
4487+ u32 fp=0xF0000;
4488+
4489+#ifdef CONFIG_SIMNOW
4490+ return -1;
4491+#endif
4492+
4493+ while(fp < 0xFFFFF)
4494+ {
4495+ isa_memcpy_fromio(buf, fp, 15);
4496+ if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
4497+ {
4498+ u16 num=buf[13]<<8|buf[12];
4499+ u16 len=buf[7]<<8|buf[6];
4500+ u32 base=buf[11]<<24|buf[10]<<16|buf[9]<<8|buf[8];
4501+
4502+ if(dmi_table(base, len, num, ipmi_data) == 0)
4503+ return 0;
4504+ }
4505+ fp+=16;
4506+ }
4507+
4508+ return -1;
4509+}
4510+
4511+static int try_init_smbios(int intf_num, struct smi_info **new_info)
4512+{
4513+ struct smi_info *info;
4514+ dmi_ipmi_data_t ipmi_data;
4515+ char *io_type;
4516+ int status;
4517+
4518+ status = dmi_iterator(&ipmi_data);
4519+
4520+ if (status < 0)
4521+ return -ENODEV;
4522+
4523+ switch(ipmi_data.type) {
4524+ case 0x01: /* KCS */
4525+ si_type[intf_num] = "kcs";
4526+ break;
4527+ case 0x02: /* SMIC */
4528+ si_type[intf_num] = "smic";
4529+ break;
4530+ case 0x03: /* BT */
4531+ si_type[intf_num] = "bt";
4532+ break;
4533+ default:
4534+ printk("ipmi_smi: Unknown SMBIOS SMI type.\n");
4535+ return -EIO;
4536+ }
4537+
4538+ info = kmalloc(sizeof(*info), GFP_KERNEL);
4539+ if (!info) {
4540+ printk("ipmi_smi: Could not allocate SMI data\n");
4541+ return -ENOMEM;
4542+ }
4543+ memset(info, 0, sizeof(*info));
4544+
4545+ if (ipmi_data.addr_space == 1) {
4546+ io_type = "memory";
4547+ info->io_setup = mem_setup;
4548+ info->io_cleanup = mem_cleanup;
4549+ si_addrs[intf_num] = ipmi_data.base_addr;
4550+ info->io.inputb = mem_inb;
4551+ info->io.outputb = mem_outb;
4552+ info->io.info = &(si_addrs[intf_num]);
4553+ } else if (ipmi_data.addr_space == 2) {
4554+ io_type = "I/O";
4555+ info->io_setup = port_setup;
4556+ info->io_cleanup = port_cleanup;
4557+ si_ports[intf_num] = ipmi_data.base_addr;
4558+ info->io.inputb = port_inb;
4559+ info->io.outputb = port_outb;
4560+ info->io.info = &(si_ports[intf_num]);
4561+ } else {
4562+ kfree(info);
4563+ printk("ipmi_smi: Unknown SMBIOS I/O Address type.\n");
4564+ return -EIO;
4565+ }
4566+
4567+ si_irqs[intf_num] = ipmi_data.irq;
4568+
4569+ *new_info = info;
4570+
4571+ printk("ipmi_smi: Found SMBIOS-specified state machine at %s"
4572+ " address 0x%lx\n",
4573+ io_type, (unsigned long)ipmi_data.base_addr);
4574+ return 0;
4575+}
4576+#endif /* CONFIG_X86 */
4577+
4578+#ifdef CONFIG_PCI
4579+
4580+#define PCI_ERMC_CLASSCODE 0x0C0700
4581+#define PCI_HP_VENDOR_ID 0x103C
4582+#define PCI_MMC_DEVICE_ID 0x121A
4583+#define PCI_MMC_ADDR_CW 0x10
4584+
4585+/* Avoid more than one attempt to probe pci smic. */
4586+static int pci_smic_checked = 0;
4587+
4588+static int find_pci_smic(int intf_num, struct smi_info **new_info)
4589+{
4590+ struct smi_info *info;
4591+ int error;
4592+ struct pci_dev *pci_dev = NULL;
4593+ u16 base_addr;
4594+ int fe_rmc = 0;
4595+
4596+ if (!pci_present() || pci_smic_checked)
4597+ return -ENODEV;
4598+
4599+ pci_smic_checked = 1;
4600+
4601+ if ((pci_dev = pci_find_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
4602+ NULL)))
4603+ ;
4604+ else if ((pci_dev = pci_find_class(PCI_ERMC_CLASSCODE, NULL)) &&
4605+ pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)
4606+ fe_rmc = 1;
4607+ else
4608+ return -ENODEV;
4609+
4610+ error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr);
4611+ if (error)
4612+ {
4613+ printk(KERN_ERR
4614+ "ipmi_smi: pci_read_config_word() failed (%d).\n",
4615+ error);
4616+ return -ENODEV;
4617+ }
4618+
4619+ /* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */
4620+ if (!(base_addr & 0x0001))
4621+ {
4622+ printk(KERN_ERR
4623+ "ipmi_smi: memory mapped I/O not supported for PCI"
4624+ " smic.\n");
4625+ return -ENODEV;
4626+ }
4627+
4628+ base_addr &= 0xFFFE;
4629+ if (!fe_rmc)
4630+ /* Data register starts at base address + 1 in eRMC */
4631+ ++base_addr;
4632+
4633+ if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr))
4634+ return -ENODEV;
4635+
4636+ info = kmalloc(sizeof(*info), GFP_KERNEL);
4637+ if (!info) {
4638+ printk("ipmi_smi: Could not allocate SMI data\n");
4639+ return -ENOMEM;
4640+ }
4641+ memset(info, 0, sizeof(*info));
4642+
4643+ info->io_setup = port_setup;
4644+ info->io_cleanup = port_cleanup;
4645+ si_ports[intf_num] = base_addr;
4646+ info->io.inputb = port_inb;
4647+ info->io.outputb = port_outb;
4648+ info->io.info = &(si_ports[intf_num]);
4649+
4650+ *new_info = info;
4651+
4652+ si_irqs[intf_num] = pci_dev->irq;
4653+ si_type[intf_num] = "smic";
4654+
4655+ printk("ipmi_smi: Found PCI SMIC at I/O address 0x%lx\n",
4656+ (long unsigned int) base_addr);
4657+
4658+ return 0;
4659+}
4660+#endif /* CONFIG_PCI */
4661+
4662+static int try_init_plug_and_play(int intf_num, struct smi_info **new_info)
4663+{
4664+#ifdef CONFIG_PCI
4665+ if (find_pci_smic(intf_num, new_info)==0)
4666+ return 0;
4667+#endif
4668+ /* Include other methods here. */
4669+
4670+ return -ENODEV;
4671+}
4672+
4673+
4674+static int try_get_dev_id(struct smi_info *smi_info)
4675+{
4676+ unsigned char msg[2];
4677+ unsigned char resp[IPMI_MAX_MSG_LENGTH];
4678+ unsigned long resp_len;
4679+ enum si_sm_result smi_result;
4680+
4681+ /* Do a Get Device ID command, since it comes back with some
4682+ useful info. */
4683+ msg[0] = IPMI_NETFN_APP_REQUEST << 2;
4684+ msg[1] = IPMI_GET_DEVICE_ID_CMD;
4685+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
4686+
4687+ smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
4688+ for (;;)
4689+ {
4690+ if (smi_result == SI_SM_CALL_WITH_DELAY) {
4691+ set_current_state(TASK_UNINTERRUPTIBLE);
4692+ schedule_timeout(1);
4693+ smi_result = smi_info->handlers->event(
4694+ smi_info->si_sm, 100);
4695+ }
4696+ else if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
4697+ {
4698+ smi_result = smi_info->handlers->event(
4699+ smi_info->si_sm, 0);
4700+ }
4701+ else
4702+ break;
4703+ }
4704+ if (smi_result == SI_SM_HOSED)
4705+ /* We couldn't get the state machine to run, so whatever's at
4706+ the port is probably not an IPMI SMI interface. */
4707+ return -ENODEV;
4708+
4709+ /* Otherwise, we got some data. */
4710+ resp_len = smi_info->handlers->get_result(smi_info->si_sm,
4711+ resp, IPMI_MAX_MSG_LENGTH);
4712+ if (resp_len < 6)
4713+ /* That's odd, it should be longer. */
4714+ return -EINVAL;
4715+
4716+ if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0))
4717+ /* That's odd, it shouldn't be able to fail. */
4718+ return -EINVAL;
4719+
4720+ /* Record info from the get device id, in case we need it. */
4721+ smi_info->ipmi_si_dev_rev = resp[4] & 0xf;
4722+ smi_info->ipmi_si_fw_rev_major = resp[5] & 0x7f;
4723+ smi_info->ipmi_si_fw_rev_minor = resp[6];
4724+ smi_info->ipmi_version_major = resp[7] & 0xf;
4725+ smi_info->ipmi_version_minor = resp[7] >> 4;
4726+
4727+ return 0;
4728+}
4729+
4730+extern struct si_sm_handlers kcs_smi_handlers;
4731+extern struct si_sm_handlers smic_smi_handlers;
4732+extern struct si_sm_handlers bt_smi_handlers;
4733+
4734+static int type_file_read_proc(char *page, char **start, off_t off,
4735+ int count, int *eof, void *data)
4736+{
4737+ char *out = (char *) page;
4738+ struct smi_info *smi = data;
4739+
4740+ switch (smi->si_type) {
4741+ case SI_KCS:
4742+ return sprintf(out, "kcs\n");
4743+ case SI_SMIC:
4744+ return sprintf(out, "smic\n");
4745+ case SI_BT:
4746+ return sprintf(out, "bt\n");
4747+ default:
4748+ return 0;
4749+ }
4750+}
4751+
4752+static int stat_file_read_proc(char *page, char **start, off_t off,
4753+ int count, int *eof, void *data)
4754+{
4755+ char *out = (char *) page;
4756+ struct smi_info *smi = data;
4757+
4758+ out += sprintf(out, "interrupts_enabled: %d\n",
4759+ smi->irq && !smi->interrupt_disabled);
4760+ out += sprintf(out, "short_timeouts: %ld\n",
4761+ smi->short_timeouts);
4762+ out += sprintf(out, "long_timeouts: %ld\n",
4763+ smi->long_timeouts);
4764+ out += sprintf(out, "timeout_restarts: %ld\n",
4765+ smi->timeout_restarts);
4766+ out += sprintf(out, "idles: %ld\n",
4767+ smi->idles);
4768+ out += sprintf(out, "interrupts: %ld\n",
4769+ smi->interrupts);
4770+ out += sprintf(out, "attentions: %ld\n",
4771+ smi->attentions);
4772+ out += sprintf(out, "flag_fetches: %ld\n",
4773+ smi->flag_fetches);
4774+ out += sprintf(out, "hosed_count: %ld\n",
4775+ smi->hosed_count);
4776+ out += sprintf(out, "complete_transactions: %ld\n",
4777+ smi->complete_transactions);
4778+ out += sprintf(out, "events: %ld\n",
4779+ smi->events);
4780+ out += sprintf(out, "watchdog_pretimeouts: %ld\n",
4781+ smi->watchdog_pretimeouts);
4782+ out += sprintf(out, "incoming_messages: %ld\n",
4783+ smi->incoming_messages);
4784+
4785+ return (out - ((char *) page));
4786+}
4787+
4788+/* Returns 0 if initialized, or negative on an error. */
4789+static int init_one_smi(int intf_num, struct smi_info **smi)
4790+{
4791+ int rv;
4792+ struct smi_info *new_smi;
4793+
4794+
4795+ rv = try_init_mem(intf_num, &new_smi);
4796+ if (rv)
4797+ rv = try_init_port(intf_num, &new_smi);
4798+#ifdef CONFIG_ACPI_INTERPRETER
4799+ if ((rv) && (si_trydefaults)) {
4800+ rv = try_init_acpi(intf_num, &new_smi);
4801+ }
4802+#endif
4803+#ifdef CONFIG_X86
4804+ if ((rv) && (si_trydefaults)) {
4805+ rv = try_init_smbios(intf_num, &new_smi);
4806+ }
4807+#endif
4808+ if ((rv) && (si_trydefaults)) {
4809+ rv = try_init_plug_and_play(intf_num, &new_smi);
4810+ }
4811+
4812+
4813+ if (rv)
4814+ return rv;
4815+
4816+ /* So we know not to free it unless we have allocated one. */
4817+ new_smi->intf = NULL;
4818+ new_smi->si_sm = NULL;
4819+ new_smi->handlers = 0;
4820+
4821+ if (!new_smi->irq_setup) {
4822+ new_smi->irq = si_irqs[intf_num];
4823+ new_smi->irq_setup = std_irq_setup;
4824+ new_smi->irq_cleanup = std_irq_cleanup;
4825+ }
4826+
4827+ /* Default to KCS if no type is specified. */
4828+ if (si_type[intf_num] == NULL) {
4829+ if (si_trydefaults)
4830+ si_type[intf_num] = "kcs";
4831+ else {
4832+ rv = -EINVAL;
4833+ goto out_err;
4834+ }
4835+ }
4836+
4837+ /* Set up the state machine to use. */
4838+ if (strcmp(si_type[intf_num], "kcs") == 0) {
4839+ new_smi->handlers = &kcs_smi_handlers;
4840+ new_smi->si_type = SI_KCS;
4841+ } else if (strcmp(si_type[intf_num], "smic") == 0) {
4842+ new_smi->handlers = &smic_smi_handlers;
4843+ new_smi->si_type = SI_SMIC;
4844+ } else if (strcmp(si_type[intf_num], "bt") == 0) {
4845+ new_smi->handlers = &bt_smi_handlers;
4846+ new_smi->si_type = SI_BT;
4847+ } else {
4848+ /* No support for anything else yet. */
4849+ rv = -EIO;
4850+ goto out_err;
4851+ }
4852+
4853+ /* Allocate the state machine's data and initialize it. */
4854+ new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL);
4855+ if (!new_smi->si_sm) {
4856+ printk(" Could not allocate state machine memory\n");
4857+ rv = -ENOMEM;
4858+ goto out_err;
4859+ }
4860+ new_smi->io_size = new_smi->handlers->init_data(new_smi->si_sm,
4861+ &new_smi->io);
4862+
4863+ /* Now that we know the I/O size, we can set up the I/O. */
4864+ rv = new_smi->io_setup(new_smi);
4865+ if (rv) {
4866+ printk(" Could not set up I/O space\n");
4867+ goto out_err;
4868+ }
4869+
4870+ spin_lock_init(&(new_smi->si_lock));
4871+ spin_lock_init(&(new_smi->msg_lock));
4872+ spin_lock_init(&(new_smi->count_lock));
4873+
4874+ /* Do low-level detection first. */
4875+ if (new_smi->handlers->detect(new_smi->si_sm)) {
4876+ rv = -ENODEV;
4877+ goto out_err;
4878+ }
4879+
4880+ /* Attempt a get device id command. If it fails, we probably
4881+ don't have a SMI here. */
4882+ rv = try_get_dev_id(new_smi);
4883+ if (rv)
4884+ goto out_err;
4885+
4886+ /* Try to claim any interrupts. */
4887+ new_smi->irq_setup(new_smi);
4888+
4889+ INIT_LIST_HEAD(&(new_smi->xmit_msgs));
4890+ INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
4891+ new_smi->curr_msg = NULL;
4892+ atomic_set(&new_smi->req_events, 0);
4893+ new_smi->run_to_completion = 0;
4894+
4895+ rv = ipmi_register_smi(&handlers,
4896+ new_smi,
4897+ new_smi->ipmi_version_major,
4898+ new_smi->ipmi_version_minor,
4899+ &(new_smi->intf));
4900+ if (rv) {
4901+ printk(KERN_ERR
4902+ "ipmi_smi: Unable to register device: error %d\n",
4903+ rv);
4904+ goto out_err;
4905+ }
4906+
4907+ rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
4908+ type_file_read_proc, NULL,
4909+ new_smi, THIS_MODULE);
4910+ if (rv) {
4911+ printk(KERN_ERR
4912+ "ipmi_smi: Unable to create proc entry: %d\n",
4913+ rv);
4914+ goto out_err;
4915+ }
4916+
4917+ rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
4918+ stat_file_read_proc, NULL,
4919+ new_smi, THIS_MODULE);
4920+ if (rv) {
4921+ printk(KERN_ERR
4922+ "ipmi_smi: Unable to create proc entry: %d\n",
4923+ rv);
4924+ goto out_err;
4925+ }
4926+
4927+ start_clear_flags(new_smi);
4928+
4929+ /* IRQ is defined to be set when non-zero. */
4930+ if (new_smi->irq)
4931+ new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
4932+
4933+ new_smi->interrupt_disabled = 0;
4934+ new_smi->timer_stopped = 0;
4935+ new_smi->stop_operation = 0;
4936+
4937+ init_timer(&(new_smi->si_timer));
4938+ new_smi->si_timer.data = (long) new_smi;
4939+ new_smi->si_timer.function = smi_timeout;
4940+ new_smi->last_timeout_jiffies = jiffies;
4941+ new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
4942+ add_timer(&(new_smi->si_timer));
4943+
4944+ *smi = new_smi;
4945+
4946+ printk(" IPMI %s interface initialized\n", si_type[intf_num]);
4947+
4948+ return 0;
4949+
4950+ out_err:
4951+ if (new_smi->intf)
4952+ ipmi_unregister_smi(new_smi->intf);
4953+
4954+ new_smi->irq_cleanup(new_smi);
4955+ if (new_smi->si_sm) {
4956+ if (new_smi->handlers)
4957+ new_smi->handlers->cleanup(new_smi->si_sm);
4958+ kfree(new_smi->si_sm);
4959+ }
4960+ new_smi->io_cleanup(new_smi);
4961+ return rv;
4962+}
4963+
4964+static __init int init_ipmi_si(void)
4965+{
4966+ int rv = 0;
4967+ int pos = 0;
4968+ int i = 0;
4969+
4970+ if (initialized)
4971+ return 0;
4972+ initialized = 1;
4973+
4974+ printk(KERN_INFO "IPMI System Interface driver version "
4975+ IPMI_SI_VERSION);
4976+ if (kcs_smi_handlers.version)
4977+ printk(", KCS version %s", kcs_smi_handlers.version);
4978+ if (smic_smi_handlers.version)
4979+ printk(", SMIC version %s", smic_smi_handlers.version);
4980+ if (bt_smi_handlers.version)
4981+ printk(", BT version %s", bt_smi_handlers.version);
4982+ printk("\n");
4983+
4984+ rv = init_one_smi(0, &(smi_infos[pos]));
4985+ if (rv && !si_ports[0] && si_trydefaults) {
4986+ /* If we are trying defaults and the initial port is
4987+ not set, then set it. */
4988+ si_type[0] = "kcs";
4989+ si_ports[0] = DEFAULT_KCS_IO_PORT;
4990+ rv = init_one_smi(0, &(smi_infos[pos]));
4991+ if (rv) {
4992+ /* No KCS - try SMIC */
4993+ si_type[0] = "smic";
4994+ si_ports[0] = DEFAULT_SMIC_IO_PORT;
4995+ rv = init_one_smi(0, &(smi_infos[pos]));
4996+ }
4997+ if (rv) {
4998+ /* No SMIC - try BT */
4999+ si_type[0] = "bt";
5000+ si_ports[0] = DEFAULT_BT_IO_PORT;
5001+ rv = init_one_smi(0, &(smi_infos[pos]));
5002+ }
5003+ }
5004+ if (rv == 0)
5005+ pos++;
5006+
5007+ for (i=1; i < SI_MAX_PARMS; i++) {
5008+ rv = init_one_smi(i, &(smi_infos[pos]));
5009+ if (rv == 0)
5010+ pos++;
5011+ }
5012+
5013+ if (smi_infos[0] == NULL) {
5014+ printk("ipmi_smi: Unable to find any SMI interfaces\n");
5015+ return -ENODEV;
5016+ }
5017+
5018+ return 0;
5019+}
5020+module_init(init_ipmi_si);
5021+
5022+#ifdef MODULE
5023+void __exit cleanup_one_si(struct smi_info *to_clean)
5024+{
5025+ int rv;
5026+ unsigned long flags;
5027+
5028+ if (! to_clean)
5029+ return;
5030+
5031+ /* Tell the timer and interrupt handlers that we are shutting
5032+ down. */
5033+ spin_lock_irqsave(&(to_clean->si_lock), flags);
5034+ spin_lock(&(to_clean->msg_lock));
5035+
5036+ to_clean->stop_operation = 1;
5037+
5038+ to_clean->irq_cleanup(to_clean);
5039+
5040+ spin_unlock(&(to_clean->msg_lock));
5041+ spin_unlock_irqrestore(&(to_clean->si_lock), flags);
5042+
5043+ /* Wait for the timer to stop. This avoids problems with race
5044+ conditions removing the timer here. Hopefully this will be
5045+ long enough to avoid problems with interrupts still
5046+ running. */
5047+ set_current_state(TASK_UNINTERRUPTIBLE);
5048+ schedule_timeout(2);
5049+ while (!to_clean->timer_stopped) {
5050+ set_current_state(TASK_UNINTERRUPTIBLE);
5051+ schedule_timeout(1);
5052+ }
5053+
5054+ rv = ipmi_unregister_smi(to_clean->intf);
5055+ if (rv) {
5056+ printk(KERN_ERR
5057+ "ipmi_smi: Unable to unregister device: errno=%d\n",
5058+ rv);
5059+ }
5060+
5061+ to_clean->handlers->cleanup(to_clean->si_sm);
5062+
5063+ kfree(to_clean->si_sm);
5064+
5065+ to_clean->io_cleanup(to_clean);
5066+}
5067+
5068+static __exit void cleanup_ipmi_si(void)
5069+{
5070+ int i;
5071+
5072+ if (!initialized)
5073+ return;
5074+
5075+ for (i=0; i<SI_MAX_DRIVERS; i++) {
5076+ cleanup_one_si(smi_infos[i]);
5077+ }
5078+}
5079+module_exit(cleanup_ipmi_si);
5080+#else
5081+
5082+/* Unfortunately, cmdline::get_options() only returns integers, not
5083+ longs. Since we need ulongs (64-bit physical addresses) parse the
5084+ comma-separated list manually. Arguments can be one of these forms:
5085+ m0xaabbccddeeff A physical memory address without an IRQ
5086+ m0xaabbccddeeff:cc A physical memory address with an IRQ
5087+ p0xaabb An IO port without an IRQ
5088+ p0xaabb:cc An IO port with an IRQ
5089+ nodefaults Suppress trying the default IO port or ACPI address
5090+
5091+ For example, to pass one IO port with an IRQ, one address, and
5092+ suppress the use of the default IO port and ACPI address,
5093+ use this option string: ipmi_smi=p0xCA2:5,m0xFF5B0022,nodefaults
5094+
5095+ Remember, ipmi_si_setup() is passed the string after the equal sign. */
5096+
5097+static int __init ipmi_si_setup(char *str)
5098+{
5099+ unsigned long val;
5100+ char *cur, *colon;
5101+ int pos;
5102+
5103+ pos = 0;
5104+
5105+ cur = strsep(&str, ",");
5106+ while ((cur) && (*cur) && (pos < SI_MAX_PARMS)) {
5107+ switch (*cur) {
5108+ case 'n':
5109+ if (strcmp(cur, "nodefaults") == 0)
5110+ si_trydefaults = 0;
5111+ else
5112+ printk(KERN_INFO
5113+ "ipmi_si: bad parameter value %s\n",
5114+ cur);
5115+ break;
5116+
5117+ case 'k': /* KCS */
5118+ si_type[pos] = "kcs";
5119+ break;
5120+
5121+ case 's': /* SMIC */
5122+ si_type[pos] = "smic";
5123+ break;
5124+
5125+ case 'b': /* BT */
5126+ si_type[pos] = "bt";
5127+ break;
5128+
5129+ case 'm':
5130+ case 'p':
5131+ val = simple_strtoul(cur + 1,
5132+ &colon,
5133+ 0);
5134+ if (*cur == 'p')
5135+ si_ports[pos] = val;
5136+ else
5137+ si_addrs[pos] = val;
5138+ if (*colon == ':') {
5139+ val = simple_strtoul(colon + 1,
5140+ &colon,
5141+ 0);
5142+ si_irqs[pos] = val;
5143+ }
5144+ pos++;
5145+ break;
5146+
5147+ default:
5148+ printk(KERN_INFO
5149+ "ipmi_si: bad parameter value %s\n",
5150+ cur);
5151+ }
5152+ cur = strsep(&str, ",");
5153+ }
5154+
5155+ return 1;
5156+}
5157+__setup("ipmi_si=", ipmi_si_setup);
5158+#endif
5159+
5160+MODULE_LICENSE("GPL");
5161diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_si_sm.h linux-2.4.23/drivers/char/ipmi/ipmi_si_sm.h
5162--- linux-2.4.23.org/drivers/char/ipmi/ipmi_si_sm.h 1970-01-01 01:00:00.000000000 +0100
5163+++ linux-2.4.23/drivers/char/ipmi/ipmi_si_sm.h 2004-01-02 23:33:48.056808733 +0100
5164@@ -0,0 +1,112 @@
5165+/*
5166+ * ipmi_si_sm.h
5167+ *
5168+ * State machine interface for low-level IPMI system management
5169+ * interface state machines. This code is the interface between
5170+ * the ipmi_smi code (that handles the policy of a KCS, SMIC, or
5171+ * BT interface) and the actual low-level state machine.
5172+ *
5173+ * Author: MontaVista Software, Inc.
5174+ * Corey Minyard <minyard@mvista.com>
5175+ * source@mvista.com
5176+ *
5177+ * Copyright 2002 MontaVista Software Inc.
5178+ *
5179+ * This program is free software; you can redistribute it and/or modify it
5180+ * under the terms of the GNU General Public License as published by the
5181+ * Free Software Foundation; either version 2 of the License, or (at your
5182+ * option) any later version.
5183+ *
5184+ *
5185+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
5186+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
5187+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5188+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5189+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
5190+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
5191+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5192+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
5193+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
5194+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5195+ *
5196+ * You should have received a copy of the GNU General Public License along
5197+ * with this program; if not, write to the Free Software Foundation, Inc.,
5198+ * 675 Mass Ave, Cambridge, MA 02139, USA.
5199+ */
5200+
5201+/* This is defined by the state machines themselves, it is an opaque
5202+ data type for them to use. */
5203+struct si_sm_data;
5204+
5205+/* The structure for doing I/O in the state machine. The state
5206+ machine doesn't have the actual I/O routines, they are done through
5207+ this interface. */
5208+struct si_sm_io
5209+{
5210+ unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset);
5211+ void (*outputb)(struct si_sm_io *io,
5212+ unsigned int offset,
5213+ unsigned char b);
5214+
5215+ /* Generic info used by the actual handling routines, the
5216+ state machine shouldn't touch these. */
5217+ void *info;
5218+ void *addr;
5219+};
5220+
5221+/* Results of SMI events. */
5222+enum si_sm_result
5223+{
5224+ SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */
5225+ SI_SM_CALL_WITH_DELAY, /* Delay some before calling again. */
5226+ SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */
5227+ SI_SM_IDLE, /* The SM is in idle state. */
5228+ SI_SM_HOSED, /* The hardware violated the state machine. */
5229+ SI_SM_ATTN /* The hardware is asserting attn and the
5230+ state machine is idle. */
5231+};
5232+
5233+/* Handlers for the SMI state machine. */
5234+struct si_sm_handlers
5235+{
5236+ /* Put the version number of the state machine here so the
5237+ upper layer can print it. */
5238+ char *version;
5239+
5240+ /* Initialize the data and return the amount of I/O space to
5241+ reserve for the space. */
5242+ unsigned int (*init_data)(struct si_sm_data *smi,
5243+ struct si_sm_io *io);
5244+
5245+ /* Start a new transaction in the state machine. This will
5246+ return -2 if the state machine is not idle, -1 if the size
5247+ is invalid (to large or too small), or 0 if the transaction
5248+ is successfully completed. */
5249+ int (*start_transaction)(struct si_sm_data *smi,
5250+ unsigned char *data, unsigned int size);
5251+
5252+ /* Return the results after the transaction. This will return
5253+ -1 if the buffer is too small, zero if no transaction is
5254+ present, or the actual length of the result data. */
5255+ int (*get_result)(struct si_sm_data *smi,
5256+ unsigned char *data, unsigned int length);
5257+
5258+ /* Call this periodically (for a polled interface) or upon
5259+ receiving an interrupt (for a interrupt-driven interface).
5260+ If interrupt driven, you should probably poll this
5261+ periodically when not in idle state. This should be called
5262+ with the time that passed since the last call, if it is
5263+ significant. Time is in microseconds. */
5264+ enum si_sm_result (*event)(struct si_sm_data *smi, long time);
5265+
5266+ /* Attempt to detect an SMI. Returns 0 on success or nonzero
5267+ on failure. */
5268+ int (*detect)(struct si_sm_data *smi);
5269+
5270+ /* The interface is shutting down, so clean it up. */
5271+ void (*cleanup)(struct si_sm_data *smi);
5272+
5273+ /* Return the size of the SMI structure in bytes. */
5274+ int (*size)(void);
5275+};
5276+
5277diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_smb_intf.c linux-2.4.23/drivers/char/ipmi/ipmi_smb_intf.c
5278--- linux-2.4.23.org/drivers/char/ipmi/ipmi_smb_intf.c 1970-01-01 01:00:00.000000000 +0100
5279+++ linux-2.4.23/drivers/char/ipmi/ipmi_smb_intf.c 2004-01-02 23:33:48.062807487 +0100
5280@@ -0,0 +1,1308 @@
5281+/*
5282+ * ipmi_smb_intf.c
5283+ *
5284+ * The interface to the IPMI driver for SMBus access to a SMBus compliant device.
5285+ *
5286+ * Author: Intel Corporation
5287+ * Todd Davis <todd.c.davis@intel.com>
5288+ *
5289+ * Copyright 2003 Intel Corporation
5290+ *
5291+ * This program is free software; you can redistribute it and/or modify it
5292+ * under the terms of the GNU General Public License as published by the
5293+ * Free Software Foundation; either version 2 of the License, or (at your
5294+ * option) any later version.
5295+ *
5296+ *
5297+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
5298+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
5299+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
5300+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
5301+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
5302+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
5303+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
5304+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
5305+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
5306+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5307+ *
5308+ * You should have received a copy of the GNU General Public License along
5309+ * with this program; if not, write to the Free Software Foundation, Inc.,
5310+ * 675 Mass Ave, Cambridge, MA 02139, USA.
5311+ */
5312+
5313+/*
5314+ * This file holds the "policy" for the interface to the SMB state
5315+ * machine. It does the configuration, handles timers and interrupts,
5316+ * and drives the real SMB state machine.
5317+ */
5318+
5319+#include <linux/config.h>
5320+#include <linux/version.h>
5321+#if defined(MODVERSIONS)
5322+#include <linux/modversions.h>
5323+#endif
5324+
5325+#include <linux/module.h>
5326+#include <asm/system.h>
5327+#include <linux/sched.h>
5328+#include <linux/timer.h>
5329+#include <linux/errno.h>
5330+#include <linux/spinlock.h>
5331+#include <linux/slab.h>
5332+#include <linux/delay.h>
5333+#include <linux/list.h>
5334+#include <linux/i2c.h>
5335+#include <linux/ipmi_smi.h>
5336+#include <linux/init.h>
5337+
5338+
5339+#define IPMI_SMB_VERSION "v28"
5340+
5341+/* module feature switches */
5342+#define REGISTER_SMI 1
5343+#define SMB_KTHREAD 1
5344+
5345+#ifdef SMB_KTHREAD
5346+#include <linux/kernel.h>
5347+#include <linux/smp_lock.h>
5348+
5349+/* a structure to store all information we need
5350+ for our thread */
5351+typedef struct kthread_struct
5352+{
5353+ /* Linux task structure of thread */
5354+ struct task_struct *thread;
5355+ /* Task queue need to launch thread */
5356+ struct tq_struct tq;
5357+ /* semaphore needed on start and creation of thread. */
5358+ struct semaphore startstop_sem;
5359+
5360+ /* queue thread is waiting on. Gets initialized by
5361+ init_kthread, can be used by thread itself.
5362+ */
5363+ wait_queue_head_t queue;
5364+ /* flag to tell thread whether to die or not.
5365+ When the thread receives a signal, it must check
5366+ the value of terminate and call exit_kthread and terminate
5367+ if set.
5368+ */
5369+ int terminate;
5370+} kthread_t; /* the variable that contains the thread data */
5371+#endif
5372+
5373+#define SMB_IPMI_REQUEST 2
5374+#define SMB_IPMI_RESPONSE 3
5375+
5376+/* smb_debug is a bit-field
5377+ * SMB_DEBUG_MSG - commands and their responses
5378+ * SMB_DEBUG_STATES - message states
5379+ * SMB_DEBUG_TIMING - Measure times between events in the driver
5380+ */
5381+#define SMB_DEBUG_TIMING 4
5382+#define SMB_DEBUG_STATE 2
5383+#define SMB_DEBUG_MSG 1
5384+#define SMB_NODEBUG 0
5385+#define SMB_DEFAULT_DEBUG (SMB_NODEBUG)
5386+
5387+#ifdef CONFIG_IPMI_SMB
5388+/* This forces a dependency to the config file for this option. */
5389+#endif
5390+
5391+enum smb_intf_state {
5392+ SMB_NORMAL,
5393+ SMB_GETTING_FLAGS,
5394+ SMB_GETTING_EVENTS,
5395+ SMB_CLEARING_FLAGS,
5396+ SMB_CLEARING_FLAGS_THEN_SET_IRQ,
5397+ SMB_GETTING_MESSAGES,
5398+ SMB_ENABLE_INTERRUPTS1,
5399+ SMB_ENABLE_INTERRUPTS2
5400+ /* FIXME - add watchdog stuff. */
5401+};
5402+
5403+#define SMB_IDLE(smb) ((smb)->smb_state == SMB_NORMAL \
5404+ && (smb)->curr_msg == NULL \
5405+ && ! atomic_read(&(smb)->req_events))
5406+
5407+#define SMB_MSG_RETRIES 10
5408+
5409+struct smb_info
5410+{
5411+ int pos;
5412+ ipmi_smi_t intf;
5413+ spinlock_t msg_lock;
5414+ struct list_head xmit_msgs;
5415+ struct list_head hp_xmit_msgs;
5416+ struct ipmi_smi_msg *curr_msg;
5417+ enum smb_intf_state smb_state;
5418+ unsigned long smb_debug;
5419+
5420+ /* Flags from the last GET_MSG_FLAGS command, used when an ATTN
5421+ is set to hold the flags until we are done handling everything
5422+ from the flags. */
5423+#define RECEIVE_MSG_AVAIL 0x01
5424+#define EVENT_MSG_BUFFER_FULL 0x02
5425+#define WDT_PRE_TIMEOUT_INT 0x08
5426+ unsigned char msg_flags;
5427+
5428+ /* If set to true, this will request events the next time the
5429+ state machine is idle. */
5430+ atomic_t req_events;
5431+
5432+ /* If true, run the state machine to completion on every send
5433+ call. Generally used after a panic to make sure stuff goes
5434+ out. */
5435+ int run_to_completion;
5436+
5437+#ifdef SMB_KTHREAD
5438+ kthread_t smb_thread;
5439+#endif
5440+ struct i2c_client client;
5441+ unsigned char ipmi_smb_dev_rev;
5442+ unsigned char ipmi_smb_fw_rev_major;
5443+ unsigned char ipmi_smb_fw_rev_minor;
5444+ unsigned char ipmi_version_major;
5445+ unsigned char ipmi_version_minor;
5446+};
5447+
5448+static int initialized = 0;
5449+static void return_hosed_msg(struct smb_info *smb_info);
5450+
5451+static void deliver_recv_msg(struct smb_info *smb_info,
5452+ struct ipmi_smi_msg *msg)
5453+{
5454+ if (msg->rsp_size < 0) {
5455+ if (smb_info->curr_msg == NULL) {
5456+ smb_info->curr_msg = msg;
5457+ return_hosed_msg(smb_info);
5458+ } else {
5459+ printk(KERN_ERR
5460+ "malformed message in deliver_recv_msg:"
5461+ " rsp_size = %d\n", msg->rsp_size);
5462+ ipmi_free_smi_msg(msg);
5463+ }
5464+ } else {
5465+ ipmi_smi_msg_received(smb_info->intf, msg);
5466+ }
5467+}
5468+
5469+static void return_hosed_msg(struct smb_info *smb_info)
5470+{
5471+ struct ipmi_smi_msg *msg = smb_info->curr_msg;
5472+
5473+ /* Make it a reponse */
5474+ msg->rsp[0] = msg->data[0] | 4;
5475+ msg->rsp[1] = msg->data[1];
5476+ msg->rsp[2] = 0xFF; /* Unknown error. */
5477+ msg->rsp_size = 3;
5478+
5479+ smb_info->curr_msg = NULL;
5480+ deliver_recv_msg(smb_info, msg);
5481+}
5482+
5483+static s32 smbus_client_read_block_data(struct i2c_client *client, int debug,
5484+ u8 *values)
5485+{
5486+ s32 resp_len;
5487+ int retries = 0;
5488+
5489+ /* FIXME - is there a way to limit the read size? This culd
5490+ * be an overrun situation otherwise. */
5491+ while ((resp_len = i2c_smbus_read_block_data (client,
5492+ SMB_IPMI_RESPONSE,
5493+ values)) < 0)
5494+ {
5495+ if ((retries += 1) >= SMB_MSG_RETRIES) {
5496+ printk(KERN_ERR
5497+ "smb_smbus_read_block_data failed: %d\n",
5498+ resp_len);
5499+ break;
5500+ } else if (debug & (SMB_DEBUG_MSG|SMB_DEBUG_TIMING)) {
5501+ printk(KERN_WARNING
5502+ "smb_smbus_read_block_data: retry %d\n",
5503+ retries);
5504+ }
5505+ }
5506+
5507+ if (debug & SMB_DEBUG_TIMING) {
5508+ struct timeval t;
5509+ do_gettimeofday(&t);
5510+ printk(KERN_INFO "**Response %02x %02x %02x: %ld.%9.9ld\n",
5511+ values[0], values[1], values[2], t.tv_sec, t.tv_usec);
5512+ }
5513+
5514+ if (debug & SMB_DEBUG_MSG) {
5515+ int i;
5516+ printk(KERN_INFO "ipmi response:");
5517+ for (i = 0; i < resp_len; i ++) {
5518+ printk (" %02x", (unsigned char) (values[i]));
5519+ }
5520+ printk ("\n");
5521+ }
5522+
5523+ return resp_len;
5524+}
5525+
5526+static s32 smb_smbus_read_block_data(struct smb_info *smb_info, u8 *values)
5527+{
5528+ return smbus_client_read_block_data(&smb_info->client,
5529+ smb_info->smb_debug, values);
5530+}
5531+
5532+static s32 smbus_client_write_block_data(struct i2c_client *client, int debug,
5533+ u8 length, u8 *values)
5534+{
5535+ s32 ret;
5536+ int retries = 0;
5537+
5538+ if (debug & SMB_DEBUG_MSG) {
5539+ int i ;
5540+
5541+ printk(KERN_INFO "ipmi request:");
5542+ for (i = 0; i < length; i ++) {
5543+ printk (" %02x", (unsigned char) (values [i]));
5544+ }
5545+ printk ("\n");
5546+ }
5547+
5548+ if (debug & SMB_DEBUG_TIMING) {
5549+ struct timeval t;
5550+ do_gettimeofday(&t);
5551+ printk(KERN_INFO "**Request %02x %02x: %ld.%9.9ld\n",
5552+ values [0],values [1], t.tv_sec, t.tv_usec);
5553+ }
5554+
5555+ while ((ret = i2c_smbus_write_block_data (client,
5556+ SMB_IPMI_REQUEST,
5557+ length, values)) < 0)
5558+ {
5559+ if ((retries += 1) >= SMB_MSG_RETRIES) {
5560+ printk(KERN_ERR
5561+ "smb_smbus_write_block_data failed: %d\n", ret);
5562+ break;
5563+ } else if (debug & (SMB_DEBUG_MSG|SMB_DEBUG_TIMING)) {
5564+ printk(KERN_WARNING
5565+ "smb_smbus_write_block_data: retry %d\n",
5566+ retries);
5567+ }
5568+ }
5569+ return ret;
5570+}
5571+
5572+static s32 smb_smbus_write_block_data(struct smb_info *smb_info,
5573+ u8 length, u8 *values)
5574+{
5575+ return smbus_client_write_block_data(&smb_info->client,
5576+ smb_info->smb_debug,
5577+ length,
5578+ values);
5579+}
5580+
5581+static void send_next_msg(struct smb_info *smb_info)
5582+{
5583+ s32 rv;
5584+ struct list_head *entry = NULL;
5585+
5586+ spin_lock(&(smb_info->msg_lock));
5587+
5588+ /* Pick the high priority queue first. */
5589+ if (! list_empty(&(smb_info->hp_xmit_msgs))) {
5590+ entry = smb_info->hp_xmit_msgs.next;
5591+ } else if (! list_empty(&(smb_info->xmit_msgs))) {
5592+ entry = smb_info->xmit_msgs.next;
5593+ }
5594+
5595+ if (!entry) {
5596+ spin_unlock(&(smb_info->msg_lock));
5597+ smb_info->curr_msg = NULL;
5598+ return;
5599+ }
5600+ list_del(entry);
5601+ smb_info->curr_msg = list_entry(entry,
5602+ struct ipmi_smi_msg,
5603+ link);
5604+ spin_unlock(&(smb_info->msg_lock));
5605+ rv = smb_smbus_write_block_data(
5606+ smb_info,
5607+ smb_info->curr_msg->data_size,
5608+ smb_info->curr_msg->data);
5609+ if (rv) {
5610+ return_hosed_msg(smb_info);
5611+ }
5612+}
5613+
5614+static void start_enable_irq(struct smb_info *smb_info)
5615+{
5616+ unsigned char msg[2];
5617+
5618+ /* If we are enabling interrupts, we have to tell the
5619+ IPMI device to use them. */
5620+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
5621+ msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
5622+
5623+ if (smb_smbus_write_block_data(smb_info, 2, msg) == 0) {
5624+ smb_info->smb_state = SMB_ENABLE_INTERRUPTS1;
5625+ } else {
5626+ smb_info->smb_state = SMB_NORMAL;
5627+ }
5628+}
5629+
5630+static void start_clear_flags(struct smb_info *smb_info)
5631+{
5632+ unsigned char msg[3];
5633+
5634+ /* Make sure the watchdog pre-timeout flag is not set at startup. */
5635+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
5636+ msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
5637+ msg[2] = WDT_PRE_TIMEOUT_INT;
5638+
5639+ if (smb_smbus_write_block_data(smb_info, 3, msg) == 0) {
5640+ smb_info->smb_state = SMB_CLEARING_FLAGS;
5641+ } else {
5642+ smb_info->smb_state = SMB_NORMAL;
5643+ }
5644+}
5645+
5646+static void handle_flags(struct smb_info *smb_info)
5647+{
5648+ if (smb_info->msg_flags & WDT_PRE_TIMEOUT_INT) {
5649+ /* Watchdog pre-timeout */
5650+ start_clear_flags(smb_info);
5651+ smb_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
5652+ ipmi_smi_watchdog_pretimeout(smb_info->intf);
5653+ } else if (smb_info->msg_flags & RECEIVE_MSG_AVAIL) {
5654+ /* Messages available. */
5655+ smb_info->curr_msg = ipmi_alloc_smi_msg();
5656+ if (!smb_info->curr_msg) {
5657+ smb_info->smb_state = SMB_NORMAL;
5658+ return;
5659+ }
5660+
5661+ smb_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
5662+ smb_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
5663+ smb_info->curr_msg->data_size = 2;
5664+
5665+ if (smb_smbus_write_block_data(
5666+ smb_info,
5667+ smb_info->curr_msg->data_size,
5668+ smb_info->curr_msg->data) == 0) {
5669+ smb_info->smb_state = SMB_GETTING_MESSAGES;
5670+ } else {
5671+ ipmi_free_smi_msg(smb_info->curr_msg);
5672+ smb_info->curr_msg = NULL;
5673+ smb_info->smb_state = SMB_NORMAL;
5674+ return;
5675+ }
5676+ } else if (smb_info->msg_flags & EVENT_MSG_BUFFER_FULL) {
5677+ /* Events available. */
5678+ smb_info->curr_msg = ipmi_alloc_smi_msg();
5679+ if (!smb_info->curr_msg) {
5680+ smb_info->smb_state = SMB_NORMAL;
5681+ return;
5682+ }
5683+
5684+ smb_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
5685+ smb_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
5686+ smb_info->curr_msg->data_size = 2;
5687+
5688+ if (smb_smbus_write_block_data(
5689+ smb_info,
5690+ smb_info->curr_msg->data_size,
5691+ smb_info->curr_msg->data) == 0) {
5692+ smb_info->smb_state = SMB_GETTING_EVENTS;
5693+ } else {
5694+ ipmi_free_smi_msg(smb_info->curr_msg);
5695+ smb_info->curr_msg = NULL;
5696+ smb_info->smb_state = SMB_NORMAL;
5697+ return;
5698+ }
5699+ } else {
5700+ smb_info->smb_state = SMB_NORMAL;
5701+ }
5702+}
5703+
5704+static void handle_transaction_done(struct smb_info *smb_info)
5705+{
5706+ struct ipmi_smi_msg *msg;
5707+ unsigned int len;
5708+
5709+ if (smb_info->smb_debug & SMB_DEBUG_STATE) {
5710+ printk(KERN_INFO "DONE 1: state = %d.\n", smb_info->smb_state);
5711+ }
5712+ switch (smb_info->smb_state) {
5713+ case SMB_NORMAL:
5714+ if (!smb_info->curr_msg)
5715+ break;
5716+
5717+ smb_info->curr_msg->rsp_size
5718+ = smb_smbus_read_block_data(
5719+ smb_info,
5720+ smb_info->curr_msg->rsp);
5721+
5722+ msg = smb_info->curr_msg;
5723+ smb_info->curr_msg = NULL;
5724+ deliver_recv_msg(smb_info, msg);
5725+ break;
5726+
5727+ case SMB_GETTING_FLAGS:
5728+ {
5729+ unsigned char msg[4];
5730+
5731+ /* We got the flags from the SMB, now handle them. */
5732+ len = smb_smbus_read_block_data(smb_info, msg);
5733+ if (len < 0) {
5734+ /* Error fetching flags, just give up for now. */
5735+ smb_info->smb_state = SMB_NORMAL;
5736+ } else if (msg[2] != 0) {
5737+ /* Error fetching flags, just give up for now. */
5738+ smb_info->smb_state = SMB_NORMAL;
5739+ } else if (len < 3) {
5740+ /* Hmm, no flags. That's technically illegal, but
5741+ don't use uninitialized data. */
5742+ smb_info->smb_state = SMB_NORMAL;
5743+ } else {
5744+ smb_info->msg_flags = msg[3];
5745+ handle_flags(smb_info);
5746+ }
5747+ break;
5748+ }
5749+
5750+ case SMB_CLEARING_FLAGS:
5751+ case SMB_CLEARING_FLAGS_THEN_SET_IRQ:
5752+ {
5753+ unsigned char msg[3];
5754+
5755+ /* We cleared the flags. */
5756+ len = smb_smbus_read_block_data(smb_info, msg);
5757+ if (len < 0 || msg[2] != 0) {
5758+ /* Error clearing flags */
5759+ printk(KERN_WARNING
5760+ "ipmi_smb: Error clearing flags: %2.2x\n",
5761+ msg[2]);
5762+ }
5763+ if (smb_info->smb_state == SMB_CLEARING_FLAGS_THEN_SET_IRQ)
5764+ start_enable_irq(smb_info);
5765+ else
5766+ smb_info->smb_state = SMB_NORMAL;
5767+ break;
5768+ }
5769+
5770+ case SMB_GETTING_EVENTS:
5771+ {
5772+ smb_info->curr_msg->rsp_size
5773+ = smb_smbus_read_block_data(smb_info,
5774+ smb_info->curr_msg->rsp);
5775+
5776+ msg = smb_info->curr_msg;
5777+ smb_info->curr_msg = NULL;
5778+ if (msg->rsp_size < 0 || msg->rsp[2] != 0) {
5779+ /* Error getting event, probably done. */
5780+ msg->done(msg);
5781+
5782+ /* Take off the event flag. */
5783+ smb_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
5784+ } else {
5785+ deliver_recv_msg(smb_info, msg);
5786+ }
5787+ handle_flags(smb_info);
5788+ break;
5789+ }
5790+
5791+ case SMB_GETTING_MESSAGES:
5792+ {
5793+ smb_info->curr_msg->rsp_size
5794+ = smb_smbus_read_block_data(smb_info,
5795+ smb_info->curr_msg->rsp);
5796+
5797+ msg = smb_info->curr_msg;
5798+ smb_info->curr_msg = NULL;
5799+ if (msg->rsp_size < 0 || msg->rsp[2] != 0) {
5800+ /* Error getting event, probably done. */
5801+ msg->done(msg);
5802+
5803+ /* Take off the msg flag. */
5804+ smb_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
5805+ } else {
5806+ deliver_recv_msg(smb_info, msg);
5807+ }
5808+ handle_flags(smb_info);
5809+ break;
5810+ }
5811+
5812+ case SMB_ENABLE_INTERRUPTS1:
5813+ {
5814+ unsigned char msg[4];
5815+
5816+ /* We got the flags from the SMB, now handle them. */
5817+ len = smb_smbus_read_block_data(smb_info, msg);
5818+ if (len < 0 || msg[2] != 0) {
5819+ printk(KERN_WARNING
5820+ "ipmi_smb: Could not enable interrupts"
5821+ ", failed get, using polled mode.\n");
5822+ smb_info->smb_state = SMB_NORMAL;
5823+ } else {
5824+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
5825+ msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
5826+ msg[2] = msg[3] | 1; /* enable msg queue int */
5827+ if (smb_smbus_write_block_data(
5828+ smb_info,3, msg) == 0) {
5829+ smb_info->smb_state = SMB_ENABLE_INTERRUPTS2;
5830+ } else
5831+ smb_info->smb_state = SMB_NORMAL;
5832+ }
5833+ break;
5834+ }
5835+
5836+ case SMB_ENABLE_INTERRUPTS2:
5837+ {
5838+ unsigned char msg[4];
5839+
5840+ /* We got the flags from the SMB, now handle them. */
5841+ len = smb_smbus_read_block_data(smb_info, msg);
5842+ if (len < 0 || msg[2] != 0) {
5843+ printk(KERN_WARNING
5844+ "ipmi_smb: Could not enable interrupts"
5845+ ", failed set, using polled mode.\n");
5846+ }
5847+ smb_info->smb_state = SMB_NORMAL;
5848+ break;
5849+ }
5850+ }
5851+ if (smb_info->smb_debug & SMB_DEBUG_STATE) {
5852+ printk(KERN_INFO "DONE 2: state = %d.\n", smb_info->smb_state);
5853+ }
5854+}
5855+
5856+/*
5857+ * smb_event_handler must have a user context for calls to lm_sensors'
5858+ * SMBus interface
5859+ */
5860+static void smb_event_handler(struct smb_info *smb_info)
5861+{
5862+ s32 rv;
5863+ if (smb_info->smb_debug & SMB_DEBUG_STATE) {
5864+ printk(KERN_INFO "smb_event_handler: state = %d.\n",
5865+ smb_info->smb_state);
5866+ }
5867+ if (smb_info->smb_state == SMB_NORMAL) {
5868+ if (smb_info->curr_msg != NULL)
5869+ {
5870+ handle_transaction_done(smb_info);
5871+ } else {
5872+ /* If we are currently idle, try to start the
5873+ * next message. */
5874+ send_next_msg(smb_info);
5875+ }
5876+ } else {
5877+ handle_transaction_done(smb_info);
5878+ }
5879+
5880+ if (smb_info->smb_state == SMB_NORMAL &&
5881+ smb_info->curr_msg == NULL &&
5882+ atomic_read(&smb_info->req_events))
5883+ {
5884+ /* We are idle and the upper layer requested that I fetch
5885+ events, so do so. */
5886+ unsigned char msg[2];
5887+
5888+ atomic_set(&smb_info->req_events, 0);
5889+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
5890+ msg[1] = IPMI_GET_MSG_FLAGS_CMD;
5891+
5892+ rv = smb_smbus_write_block_data(smb_info, 2, msg);
5893+ if(rv == 0) {
5894+ smb_info->smb_state = SMB_GETTING_FLAGS;
5895+ }
5896+ }
5897+}
5898+
5899+#ifdef REGISTER_SMI
5900+static void sender(void *send_info,
5901+ struct ipmi_smi_msg *msg,
5902+ int priority)
5903+{
5904+ struct smb_info *smb_info = (struct smb_info *) send_info;
5905+
5906+#ifdef CONFIG_IPMI_PANIC_EVENT
5907+ if (smb_info->run_to_completion) {
5908+ /* If we are running to completion, then throw it in
5909+ the list and run transactions until everything is
5910+ clear. Priority doesn't matter here. */
5911+ list_add_tail(&(msg->link), &(smb_info->xmit_msgs));
5912+
5913+ smb_event_handler(smb_info);
5914+ while (! SMB_IDLE(smb_info)) {
5915+ smb_event_handler(smb_info);
5916+ }
5917+ return;
5918+ }
5919+#endif
5920+ if (smb_info->smb_debug & SMB_DEBUG_TIMING) {
5921+ struct timeval t;
5922+ do_gettimeofday(&t);
5923+ printk(KERN_INFO
5924+ "**Enqueue %02x %02x: %ld.%9.9ld\n",
5925+ msg->data[0], msg->data[1], t.tv_sec, t.tv_usec);
5926+ }
5927+
5928+ spin_lock(&(smb_info->msg_lock));
5929+ if (priority > 0) {
5930+ list_add_tail(&(msg->link), &(smb_info->hp_xmit_msgs));
5931+ } else {
5932+ list_add_tail(&(msg->link), &(smb_info->xmit_msgs));
5933+ }
5934+ spin_unlock(&(smb_info->msg_lock));
5935+
5936+#ifdef SMB_KTHREAD
5937+ wake_up_interruptible(&smb_info->smb_thread.queue);
5938+#endif
5939+}
5940+
5941+static void request_events(void *send_info)
5942+{
5943+ struct smb_info *smb_info = (struct smb_info *) send_info;
5944+
5945+ atomic_set(&smb_info->req_events, 1);
5946+#ifdef SMB_KTHREAD
5947+ wake_up_interruptible(&smb_info->smb_thread.queue);
5948+#endif
5949+}
5950+
5951+static int new_user(void *send_info)
5952+{
5953+ if (!try_inc_mod_count(THIS_MODULE))
5954+ return -EBUSY;
5955+ return 0;
5956+}
5957+
5958+static void user_left(void *send_info)
5959+{
5960+ MOD_DEC_USE_COUNT;
5961+}
5962+
5963+static void set_run_to_completion(void *send_info, int i_run_to_completion)
5964+{
5965+ struct smb_info *smb_info = (struct smb_info *) send_info;
5966+
5967+ smb_info->run_to_completion = i_run_to_completion;
5968+#ifdef CONFIG_IPMI_PANIC_EVENT
5969+ /* Note that if this does not compile, there are some I2C
5970+ changes that you need to handle this properly. */
5971+ i2c_set_panic_thread(i_run_to_completion);
5972+ if (i_run_to_completion) {
5973+ smb_event_handler(smb_info);
5974+ while (! SMB_IDLE(smb_info)) {
5975+ smb_event_handler(smb_info);
5976+ }
5977+ }
5978+#endif
5979+}
5980+
5981+static struct ipmi_smi_handlers handlers =
5982+{
5983+ sender: sender,
5984+ request_events: request_events,
5985+ new_user: new_user,
5986+ user_left: user_left,
5987+ set_run_to_completion: set_run_to_completion
5988+};
5989+#endif /* REGISTER_SMI */
5990+
5991+#ifdef SMB_KTHREAD
5992+/* initialize new created thread. Called by the new thread. */
5993+static void init_kthread(kthread_t *kthread, char *name)
5994+{
5995+ /* lock the kernel. A new kernel thread starts without
5996+ the big kernel lock, regardless of the lock state
5997+ of the creator (the lock level is *not* inheritated)
5998+ */
5999+ lock_kernel();
6000+
6001+ /* fill in thread structure */
6002+ kthread->thread = current;
6003+
6004+ /* set signal mask to what we want to respond */
6005+ siginitsetinv(&current->blocked,
6006+ sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
6007+
6008+ /* initialise wait queue */
6009+ init_waitqueue_head(&kthread->queue);
6010+
6011+ /* initialise termination flag */
6012+ kthread->terminate = 0;
6013+
6014+ /* set name of this process (max 15 chars + 0 !) */
6015+ sprintf(current->comm, name);
6016+
6017+ /* let others run */
6018+ unlock_kernel();
6019+
6020+ /* tell the creator that we are ready and let him continue */
6021+ up(&kthread->startstop_sem);
6022+
6023+}
6024+
6025+/* cleanup of thread. Called by the exiting thread. */
6026+static void exit_kthread(kthread_t *kthread)
6027+{
6028+ /* we are terminating */
6029+
6030+ /* lock the kernel, the exit will unlock it */
6031+ lock_kernel();
6032+ kthread->thread = NULL;
6033+ mb();
6034+
6035+ /* notify the stop_kthread() routine that we are terminating. */
6036+ up(&kthread->startstop_sem);
6037+ /* the kernel_thread that called clone() does a do_exit here. */
6038+
6039+ /* there is no race here between execution of the "killer" and
6040+ real termination of the thread (race window between up and
6041+ do_exit), since both the thread and the "killer" function
6042+ are running with the kernel lock held. The kernel lock
6043+ will be freed after the thread exited, so the code is
6044+ really not executed anymore as soon as the unload functions
6045+ gets the kernel lock back. The init process may not have
6046+ made the cleanup of the process here, but the cleanup can
6047+ be done safely with the module unloaded.
6048+ */
6049+
6050+}
6051+
6052+/* this is the thread function for making SMBus function calls into
6053+ * the lm_sensors' i2c-core module */
6054+static void smb_thread(struct smb_info *smb_info)
6055+{
6056+ kthread_t *kthread = &smb_info->smb_thread;
6057+ /* setup the thread environment */
6058+ init_kthread(kthread, "IPMI SMBus thread");
6059+
6060+ /* an endless loop in which we are doing our work */
6061+ for(;;)
6062+ {
6063+ smb_event_handler(smb_info);
6064+ while (! SMB_IDLE(smb_info)) {
6065+ smb_event_handler(smb_info);
6066+ }
6067+
6068+ interruptible_sleep_on(&kthread->queue);
6069+
6070+ /* We need to do a memory barrier here to be sure that
6071+ the flags are visible on all CPUs.
6072+ */
6073+ mb();
6074+
6075+ /* here we are back from sleep, either due to the timeout
6076+ (one second), or because we caught a signal.
6077+ */
6078+ if (kthread->terminate)
6079+ {
6080+ /* we received a request to terminate ourself */
6081+ break;
6082+ }
6083+ }
6084+ /* cleanup the thread, leave */
6085+ exit_kthread(kthread);
6086+
6087+ /* returning from the thread here calls the exit functions */
6088+}
6089+
6090+static void kthread_launcher(void *data)
6091+{
6092+ kernel_thread((int (*)(void *))smb_thread, data, 0);
6093+}
6094+
6095+/* create a new kernel thread. Called by the creator. */
6096+static void start_kthread(struct smb_info *smb_info)
6097+{
6098+ kthread_t *kthread = &smb_info->smb_thread;
6099+ /* initialize the semaphore:
6100+ we start with the semaphore locked. The new kernel
6101+ thread will setup its stuff and unlock it. This
6102+ control flow (the one that creates the thread) blocks
6103+ in the down operation below until the thread has reached
6104+ the up() operation.
6105+ */
6106+ init_MUTEX_LOCKED(&kthread->startstop_sem);
6107+
6108+ /* create the new thread my running a task through keventd */
6109+
6110+ /* initialize the task queue structure */
6111+ kthread->tq.sync = 0;
6112+ INIT_LIST_HEAD(&kthread->tq.list);
6113+ kthread->tq.routine = kthread_launcher;
6114+ kthread->tq.data = smb_info;
6115+
6116+ /* and schedule it for execution */
6117+ schedule_task(&kthread->tq);
6118+
6119+ /* wait till it has reached the setup_thread routine */
6120+ down(&kthread->startstop_sem);
6121+
6122+}
6123+
6124+/* stop a kernel thread. Called by the removing instance */
6125+static void stop_kthread(kthread_t *kthread)
6126+{
6127+ if (kthread->thread == NULL)
6128+ {
6129+ printk(KERN_WARNING
6130+ "stop_kthread: killing non existing thread!\n");
6131+ return;
6132+ }
6133+
6134+ /* this function needs to be protected with the big
6135+ kernel lock (lock_kernel()). The lock must be
6136+ grabbed before changing the terminate
6137+ flag and released after the down() call. */
6138+ lock_kernel();
6139+
6140+ /* initialize the semaphore. We lock it here, the
6141+ leave_thread call of the thread to be terminated
6142+ will unlock it. As soon as we see the semaphore
6143+ unlocked, we know that the thread has exited.
6144+ */
6145+ init_MUTEX_LOCKED(&kthread->startstop_sem);
6146+
6147+ /* We need to do a memory barrier here to be sure that
6148+ the flags are visible on all CPUs.
6149+ */
6150+ mb();
6151+
6152+ /* set flag to request thread termination */
6153+ kthread->terminate = 1;
6154+ wake_up_interruptible(&kthread->queue);
6155+
6156+ /* We need to do a memory barrier here to be sure that
6157+ the flags are visible on all CPUs.
6158+ */
6159+ mb();
6160+ kill_proc(kthread->thread->pid, SIGKILL, 1);
6161+
6162+ /* block till thread terminated */
6163+ down(&kthread->startstop_sem);
6164+
6165+ /* release the big kernel lock */
6166+ unlock_kernel();
6167+
6168+ /* now we are sure the thread is in zombie state. We
6169+ notify keventd to clean the process up.
6170+ */
6171+ kill_proc(2, SIGCHLD, 1);
6172+
6173+}
6174+#endif
6175+
6176+static int ipmi_smb_detect_hardware(struct i2c_client *client, int debug,
6177+ struct smb_info **smb_info)
6178+{
6179+ unsigned char msg[2];
6180+ unsigned char resp[IPMI_MAX_MSG_LENGTH];
6181+ unsigned long resp_len;
6182+ s32 ret;
6183+ struct smb_info *info;
6184+
6185+ /* Do a Get Device ID command, since it comes back with some
6186+ useful info. */
6187+ msg[0] = IPMI_NETFN_APP_REQUEST << 2;
6188+ msg[1] = IPMI_GET_DEVICE_ID_CMD;
6189+
6190+ ret = smbus_client_write_block_data(client, debug, 2, msg);
6191+ if (ret)
6192+ return -ENODEV;
6193+
6194+ /* Otherwise, we got some data. */
6195+ resp_len = smbus_client_read_block_data(client, debug, resp);
6196+ if (resp_len < 6)
6197+ /* That's odd, it should be longer. */
6198+ return -EINVAL;
6199+
6200+ if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0))
6201+ /* That's odd, it shouldn't be able to fail. */
6202+ return -EINVAL;
6203+
6204+ info = kmalloc(sizeof(*info), GFP_KERNEL);
6205+ if (!info)
6206+ return -ENOMEM;
6207+ memset(info, 0, sizeof(*info));
6208+
6209+ info->ipmi_smb_dev_rev = resp[4] & 0xf;
6210+ info->ipmi_smb_fw_rev_major = resp[5] & 0x7f;
6211+ info->ipmi_smb_fw_rev_minor = resp[6];
6212+ info->ipmi_version_major = resp[7] & 0xf;
6213+ info->ipmi_version_minor = resp[7] >> 4;
6214+ info->client = *client;
6215+ info->client.data = info;
6216+
6217+ *smb_info = info;
6218+
6219+ return 0;
6220+}
6221+
6222+#define MAX_SMB_BMCS 4
6223+
6224+/* An array of SMB interfaces. */
6225+static struct smb_info *smb_infos[MAX_SMB_BMCS];
6226+
6227+/*
6228+ * An array of pairs of numbers to specify where specific BMCs exist.
6229+ * Each pair specifies the adapter number and address on the adapter.
6230+ * A BMC will be forced at that position.
6231+ *
6232+ * Always provide the i2c address if it is known.
6233+ */
6234+static unsigned short __initdata smb_addr[MAX_SMB_BMCS*2 + 2];
6235+MODULE_PARM(smb_addr, "1-"__MODULE_STRING(MAX_SMB_BMCS*2)"h");
6236+
6237+/*
6238+ * If this is sent, don't probe for adapters anywhere but where the
6239+ * smb_addr array gives.
6240+ */
6241+static int smb_defaultprobe = 1;
6242+MODULE_PARM(smb_defaultprobe, "i");
6243+
6244+/*
6245+ * Turn debugging on for specific BMCs. This array is indexed by
6246+ * BMC number.
6247+ *
6248+ * Debug bit flags: IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
6249+ */
6250+static int smb_dbg[MAX_SMB_BMCS];
6251+MODULE_PARM(smb_dbg, "1-"__MODULE_STRING(MAX_SMB_BMCS)"i");
6252+
6253+/*
6254+ * Debug the probing of adapters.
6255+ */
6256+static int smb_dbg_probe = 0;
6257+MODULE_PARM(smb_dbg_probe, "i");
6258+
6259+#define SMB_I2C_START_ADDR 0x20
6260+#define SMB_I2C_END_ADDR 0x4f
6261+static unsigned short normal_i2c[] = { I2C_CLIENT_END, I2C_CLIENT_END };
6262+static unsigned short normal_i2c_range[] = { SMB_I2C_START_ADDR,
6263+ SMB_I2C_END_ADDR,
6264+ I2C_CLIENT_END };
6265+/*
6266+static unsigned int normal_isa[] = { SENSORS_ISA_END };
6267+static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
6268+*/
6269+static unsigned short reserved[] =
6270+{
6271+/* As defined by SMBus Spec. Appendix C */
6272+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x28,
6273+ 0x37,
6274+/* As defined by SMBus Spec. Sect. 5.2 */
6275+ 0x01, 0x02, 0x03, 0x04, 0x05,
6276+ 0x06, 0x07, 0x78, 0x79, 0x7a, 0x7b,
6277+ 0x7c, 0x7d, 0x7e, 0x7f,
6278+/* Common PC addresses (bad idea) */
6279+ 0x2d, 0x48, 0x49, /* sensors */
6280+ 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, /* eeproms */
6281+ 0x69, /* clock chips */
6282+
6283+ I2C_CLIENT_END
6284+};
6285+
6286+static unsigned short smb_empty_list[] = { I2C_CLIENT_END, I2C_CLIENT_END };
6287+
6288+static struct i2c_client_address_data smb_address_data = {
6289+ .normal_i2c = normal_i2c,
6290+ .normal_i2c_range = normal_i2c_range,
6291+ .probe = smb_empty_list,
6292+ .probe_range = smb_empty_list,
6293+ .ignore = reserved,
6294+ .ignore_range = smb_empty_list,
6295+ .force = smb_addr,
6296+};
6297+
6298+static unsigned int pos_reserved_as(int pos)
6299+{
6300+ if (smb_addr[pos*2+1] != 0)
6301+ return (smb_addr[pos*2] << 16) | smb_addr[pos*2+1];
6302+
6303+ return 0;
6304+}
6305+
6306+static int smb_found_addr_proc(struct i2c_adapter *adapter, int addr,
6307+ unsigned short flags, int kind)
6308+{
6309+ int id = i2c_adapter_id(adapter);
6310+ int debug = smb_dbg[id];
6311+ int rv;
6312+ int i;
6313+ int next_pos;
6314+ struct i2c_client client;
6315+ struct smb_info *smb_info;
6316+
6317+ memset(&client, 0, sizeof(&client));
6318+ strcpy(client.name, "IPMI");
6319+ client.addr = addr;
6320+ client.adapter = adapter;
6321+
6322+ rv = ipmi_smb_detect_hardware(&client, debug, &smb_info);
6323+ if (rv) {
6324+ if (smb_dbg_probe) {
6325+ printk(KERN_INFO
6326+ "smb_found_addr_proc:No IPMI client 0x%x: %d\n",
6327+ addr, rv);
6328+ }
6329+ return 0;
6330+ }
6331+
6332+ if (smb_dbg_probe) {
6333+ printk(KERN_INFO
6334+ "smb_found_addr_proc: i2c_probe found device at"
6335+ " i2c address %x\n", addr);
6336+ }
6337+
6338+ spin_lock_init(&(smb_info->msg_lock));
6339+ INIT_LIST_HEAD(&(smb_info->xmit_msgs));
6340+ INIT_LIST_HEAD(&(smb_info->hp_xmit_msgs));
6341+ smb_info->curr_msg = NULL;
6342+ atomic_set(&smb_info->req_events, 0);
6343+ smb_info->run_to_completion = 0;
6344+ smb_info->smb_state = SMB_NORMAL;
6345+
6346+ next_pos = -1;
6347+ for (i=0; i < MAX_SMB_BMCS; i++) {
6348+ unsigned int res = pos_reserved_as(i);
6349+
6350+ if (res == ((id << 16) | addr)) {
6351+ /* We have a reserved position, use it. */
6352+ next_pos = i;
6353+ break;
6354+ }
6355+
6356+ /* Claim the first unused position */
6357+ if (!res && (next_pos == -1) && (smb_infos[next_pos] == NULL))
6358+ next_pos = i;
6359+ }
6360+ if (next_pos == -1) {
6361+ rv = -EBUSY;
6362+ goto out_err;
6363+ }
6364+
6365+#ifdef REGISTER_SMI
6366+ rv = ipmi_register_smi(&handlers,
6367+ smb_info,
6368+ smb_info->ipmi_version_major,
6369+ smb_info->ipmi_version_minor,
6370+ &(smb_info->intf));
6371+ if (rv) {
6372+ printk(KERN_ERR
6373+ "ipmi_smb: Unable to register device: error %d\n",
6374+ rv);
6375+ goto out_err;
6376+ }
6377+#endif
6378+
6379+ rv = i2c_attach_client(&smb_info->client);
6380+ if (rv) {
6381+ printk(KERN_ERR
6382+ "smb_found_one_addr_proc:"
6383+ " Unable to attach i2c client: error %d\n",
6384+ rv);
6385+#ifdef REGISTER_SMI
6386+ ipmi_unregister_smi(smb_info->intf);
6387+#endif
6388+ goto out_err;
6389+ }
6390+
6391+ smb_info->pos = next_pos;
6392+ smb_infos[next_pos] = smb_info;
6393+
6394+#ifdef SMB_KTHREAD
6395+ start_kthread(smb_info);
6396+#endif
6397+
6398+ start_clear_flags(smb_info);
6399+ smb_event_handler(smb_info);
6400+
6401+ return addr;
6402+
6403+ out_err:
6404+ kfree(smb_info);
6405+ return 0;
6406+}
6407+
6408+static int attach_adapter(struct i2c_adapter *adapter)
6409+{
6410+ int id = i2c_adapter_id(adapter);
6411+
6412+ if (smb_dbg_probe) {
6413+ printk(KERN_INFO "init_one_smb: Checking SMBus adapter %d:"
6414+ " %s\n", id, adapter->name);
6415+ }
6416+ if ((i2c_get_functionality(adapter) & (I2C_FUNC_SMBUS_BLOCK_DATA))
6417+ == (I2C_FUNC_SMBUS_BLOCK_DATA))
6418+ {
6419+ if (smb_dbg_probe) {
6420+ printk(KERN_INFO "init_one_smb: found SMBus adapter:"
6421+ " %s\n", adapter->name);
6422+ }
6423+ i2c_probe(adapter, &smb_address_data, smb_found_addr_proc);
6424+ }
6425+
6426+ return 0;
6427+}
6428+
6429+void cleanup_one_smb(struct smb_info *to_clean)
6430+{
6431+ int rv;
6432+
6433+ if (! to_clean)
6434+ return;
6435+
6436+#ifdef SMB_KTHREAD
6437+ stop_kthread(&to_clean->smb_thread);
6438+#endif
6439+
6440+#ifdef REGISTER_SMI
6441+ rv = ipmi_unregister_smi(to_clean->intf);
6442+ if (rv) {
6443+ printk(KERN_ERR
6444+ "ipmi_smb: Unable to unregister device: errno=%d\n",
6445+ rv);
6446+ }
6447+#endif
6448+
6449+ rv = i2c_detach_client(&to_clean->client);
6450+ if (rv) {
6451+ printk(KERN_ERR
6452+ "ipmi_smb: Unable to detach SMBUS client: errno=%d\n",
6453+ rv);
6454+ }
6455+
6456+ smb_infos[to_clean->pos] = NULL;
6457+ kfree(to_clean);
6458+}
6459+
6460+static int detach_client(struct i2c_client *client)
6461+{
6462+ struct smb_info *smb_info = client->data;
6463+
6464+ cleanup_one_smb(smb_info);
6465+}
6466+
6467+static struct i2c_driver smb_i2c_driver =
6468+{
8bef1308 6469+
409d0572
AM
6470+ .name = "IPMI",
6471+ .flags = I2C_DF_NOTIFY,
6472+ .attach_adapter = attach_adapter,
6473+ .detach_client = detach_client,
6474+ .command = NULL,
4fe8ef33 6475+
409d0572
AM
6476+};
6477+
6478+static __init int init_ipmi_smb(void)
6479+{
6480+ int i;
6481+ int rv;
6482+
6483+ if (initialized)
6484+ return 0;
6485+
6486+ printk(KERN_INFO "IPMI SMB Interface driver version "
6487+ IPMI_SMB_VERSION "\n");
6488+
6489+ /* Make sure the smb_addr array is terminated. */
6490+ for (i=0; i<MAX_SMB_BMCS*2; i+=2) {
6491+ if (smb_addr[i+1] == 0)
6492+ break;
6493+ }
6494+ smb_addr[i] = I2C_CLIENT_END;
6495+ smb_addr[i+2] = I2C_CLIENT_END;
6496+
6497+ /* If the default probing is turned off, then disable the
6498+ * range scanning. */
6499+ if (!smb_defaultprobe)
6500+ normal_i2c_range[0] = I2C_CLIENT_END;
6501+
6502+ rv = i2c_add_driver(&smb_i2c_driver);
6503+ if (!rv)
6504+ initialized = 1;
6505+
6506+ return rv;
6507+}
6508+module_init(init_ipmi_smb);
6509+
6510+#ifdef MODULE
6511+static __exit void cleanup_ipmi_smb(void)
6512+{
6513+ int i;
6514+
6515+ if (!initialized)
6516+ return;
6517+
6518+ for (i=0; i<MAX_SMB_BMCS; i++) {
6519+ cleanup_one_smb(smb_infos[i]);
6520+ }
6521+
6522+ initialized = 0;
6523+}
6524+module_exit(cleanup_ipmi_smb);
6525+#else
6526+
6527+/* [<adapter>.]addr[:debug] Force a BMC at the given address on the
6528+ given adapter (or adapter 0 if not given). If
6529+ the debug portion is given, this this is the
6530+ debug bits as explained in the definition of
6531+ smb_dbg above.
6532+ nodefaults Suppress trying the default address range
6533+ debug_probe Debug probing of adapters
6534+
6535+ For example, to pass one IO port with an IRQ, one address, and
6536+ suppress the use of the default IO port and ACPI address,
6537+ use this option string: ipmi_kcs=p0xCA2:5,m0xFF5B0022,nodefaults
6538+
6539+ Remember, ipmi_smb_setup() is passed the string after the equal sign. */
6540+
6541+static int __init ipmi_smb_setup(char *str)
6542+{
6543+ unsigned long val;
6544+ char *cur, *sep;
6545+ int pos;
6546+
6547+ pos = 0;
6548+
6549+ cur = strsep(&str, ",");
6550+ while ((cur) && (*cur) && (pos < MAX_SMB_BMCS)) {
6551+ if (strcmp(cur, "nodefaults") == 0) {
6552+ smb_defaultprobe = 0;
6553+ continue;
6554+ }
6555+ if (strcmp(cur, "debug_probe") == 0) {
6556+ smb_dbg_probe = 1;
6557+ continue;
6558+ }
6559+ val = simple_strtoul(cur,
6560+ &sep,
6561+ 0);
6562+ if (*sep == '.') {
6563+ smb_addr[pos*2] = val;
6564+ val = simple_strtoul(sep + 1,
6565+ &sep,
6566+ 0);
6567+ } else
6568+ smb_addr[pos*2] = 0;
6569+
6570+ smb_addr[pos*2+1] = val;
6571+
6572+ if (*sep == ':') {
6573+ val = simple_strtoul(sep + 1,
6574+ &sep,
6575+ 0);
6576+ smb_dbg[pos] = val;
6577+ }
6578+ pos++;
6579+ cur = strsep(&str, ",");
6580+ }
6581+ return 1;
6582+}
6583+__setup("ipmi_smb=", ipmi_smb_setup);
6584+#endif
6585+
6586+MODULE_AUTHOR("Todd C Davis <todd.c.davis@intel.com>");
6587+MODULE_DESCRIPTION("IPMI system interface driver for management controllers on a SMBus");
6588+MODULE_LICENSE("GPL");
6589diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_smic_sm.c linux-2.4.23/drivers/char/ipmi/ipmi_smic_sm.c
6590--- linux-2.4.23.org/drivers/char/ipmi/ipmi_smic_sm.c 1970-01-01 01:00:00.000000000 +0100
6591+++ linux-2.4.23/drivers/char/ipmi/ipmi_smic_sm.c 2004-01-02 23:33:48.066806656 +0100
6592@@ -0,0 +1,601 @@
6593+/*
6594+ * ipmi_smic_sm.c
6595+ *
6596+ * The state-machine driver for an IPMI SMIC driver
6597+ *
6598+ * It started as a copy of Corey Minyard's driver for the KSC interface
6599+ * and the kernel patch "mmcdev-patch-245" by HP
6600+ *
6601+ * modified by: Hannes Schulz <schulz@schwaar.com>
6602+ * ipmi@schwaar.com
6603+ *
6604+ *
6605+ * Corey Minyard's driver for the KSC interface has the following
6606+ * copyright notice:
6607+ * Copyright 2002 MontaVista Software Inc.
6608+ *
6609+ * the kernel patch "mmcdev-patch-245" by HP has the following
6610+ * copyright notice:
6611+ * (c) Copyright 2001 Grant Grundler (c) Copyright
6612+ * 2001 Hewlett-Packard Company
6613+ *
6614+ *
6615+ * This program is free software; you can redistribute it and/or modify it
6616+ * under the terms of the GNU General Public License as published by the
6617+ * Free Software Foundation; either version 2 of the License, or (at your
6618+ * option) any later version.
6619+ *
6620+ *
6621+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
6622+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
6623+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
6624+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
6625+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
6626+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
6627+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
6628+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
6629+ * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
6630+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6631+ *
6632+ * You should have received a copy of the GNU General Public License along
6633+ * with this program; if not, write to the Free Software Foundation, Inc.,
6634+ * 675 Mass Ave, Cambridge, MA 02139, USA. */
6635+
6636+#include <linux/kernel.h> /* For printk. */
6637+#include <linux/string.h>
6638+#include "ipmi_si_sm.h"
6639+
6640+#define IPMI_SMIC_VERSION "v28"
6641+
6642+/* smic_debug is a bit-field
6643+ * SMIC_DEBUG_ENABLE - turned on for now
6644+ * SMIC_DEBUG_MSG - commands and their responses
6645+ * SMIC_DEBUG_STATES - state machine
6646+*/
6647+#define SMIC_DEBUG_STATES 4
6648+#define SMIC_DEBUG_MSG 2
6649+#define SMIC_DEBUG_ENABLE 1
6650+
6651+static int smic_debug = 1;
6652+
6653+enum smic_states {
6654+ SMIC_IDLE,
6655+ SMIC_START_OP,
6656+ SMIC_OP_OK,
6657+ SMIC_WRITE_START,
6658+ SMIC_WRITE_NEXT,
6659+ SMIC_WRITE_END,
6660+ SMIC_WRITE2READ,
6661+ SMIC_READ_START,
6662+ SMIC_READ_NEXT,
6663+ SMIC_READ_END,
6664+ SMIC_HOSED
6665+};
6666+
6667+#define MAX_SMIC_READ_SIZE 80
6668+#define MAX_SMIC_WRITE_SIZE 80
6669+#define SMIC_MAX_ERROR_RETRIES 3
6670+
6671+/* Timeouts in microseconds. */
6672+#define SMIC_RETRY_TIMEOUT 100000
6673+#define IPMI_ERR_MSG_TRUNCATED 0xc6
6674+#define IPMI_ERR_UNSPECIFIED 0xff
6675+
6676+
6677+/* SMIC Flags Register Bits */
6678+#define SMIC_RX_DATA_READY 0x80
6679+#define SMIC_TX_DATA_READY 0x40
6680+#define SMIC_SMI 0x10
6681+#define SMIC_EVM_DATA_AVAIL 0x08
6682+#define SMIC_SMS_DATA_AVAIL 0x04
6683+#define SMIC_FLAG_BSY 0x01
6684+
6685+/* SMIC Error Codes */
6686+#define EC_NO_ERROR 0x00
6687+#define EC_ABORTED 0x01
6688+#define EC_ILLEGAL_CONTROL 0x02
6689+#define EC_NO_RESPONSE 0x03
6690+#define EC_ILLEGAL_COMMAND 0x04
6691+#define EC_BUFFER_FULL 0x05
6692+
6693+struct si_sm_data
6694+{
6695+ enum smic_states state;
6696+ struct si_sm_io *io;
6697+ unsigned char write_data[MAX_SMIC_WRITE_SIZE];
6698+ int write_pos;
6699+ int write_count;
6700+ int orig_write_count;
6701+ unsigned char read_data[MAX_SMIC_READ_SIZE];
6702+ int read_pos;
6703+ int truncated;
6704+ unsigned int error_retries;
6705+ long smic_timeout;
6706+};
6707+
6708+static unsigned int init_smic_data (struct si_sm_data *smic,
6709+ struct si_sm_io *io)
6710+{
6711+ smic->state = SMIC_IDLE;
6712+ smic->io = io;
6713+ smic->write_pos = 0;
6714+ smic->write_count = 0;
6715+ smic->orig_write_count = 0;
6716+ smic->read_pos = 0;
6717+ smic->error_retries = 0;
6718+ smic->truncated = 0;
6719+ smic->smic_timeout = SMIC_RETRY_TIMEOUT;
6720+
6721+ /* We use 3 bytes of I/O. */
6722+ return 3;
6723+}
6724+
6725+static int start_smic_transaction(struct si_sm_data *smic,
6726+ unsigned char *data, unsigned int size)
6727+{
6728+ unsigned int i;
6729+
6730+ if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
6731+ return -1;
6732+ }
6733+ if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
6734+ return -2;
6735+ }
6736+ if (smic_debug & SMIC_DEBUG_MSG) {
6737+ printk(KERN_INFO "start_smic_transaction -");
6738+ for (i = 0; i < size; i ++) {
6739+ printk (" %02x", (unsigned char) (data [i]));
6740+ }
6741+ printk ("\n");
6742+ }
6743+ smic->error_retries = 0;
6744+ memcpy(smic->write_data, data, size);
6745+ smic->write_count = size;
6746+ smic->orig_write_count = size;
6747+ smic->write_pos = 0;
6748+ smic->read_pos = 0;
6749+ smic->state = SMIC_START_OP;
6750+ smic->smic_timeout = SMIC_RETRY_TIMEOUT;
6751+ return 0;
6752+}
6753+
6754+static int smic_get_result(struct si_sm_data *smic,
6755+ unsigned char *data, unsigned int length)
6756+{
6757+ int i;
6758+
6759+ if (smic_debug & SMIC_DEBUG_MSG) {
6760+ printk (KERN_INFO "smic_get result -");
6761+ for (i = 0; i < smic->read_pos; i ++) {
6762+ printk (" %02x", (smic->read_data [i]));
6763+ }
6764+ printk ("\n");
6765+ }
6766+ if (length < smic->read_pos) {
6767+ smic->read_pos = length;
6768+ smic->truncated = 1;
6769+ }
6770+ memcpy(data, smic->read_data, smic->read_pos);
6771+
6772+ if ((length >= 3) && (smic->read_pos < 3)) {
6773+ data[2] = IPMI_ERR_UNSPECIFIED;
6774+ smic->read_pos = 3;
6775+ }
6776+ if (smic->truncated) {
6777+ data[2] = IPMI_ERR_MSG_TRUNCATED;
6778+ smic->truncated = 0;
6779+ }
6780+ return smic->read_pos;
6781+}
6782+
6783+static inline unsigned char read_smic_flags(struct si_sm_data *smic)
6784+{
6785+ return smic->io->inputb(smic->io, 2);
6786+}
6787+
6788+static inline unsigned char read_smic_status(struct si_sm_data *smic)
6789+{
6790+ return smic->io->inputb(smic->io, 1);
6791+}
6792+
6793+static inline unsigned char read_smic_data(struct si_sm_data *smic)
6794+{
6795+ return smic->io->inputb(smic->io, 0);
6796+}
6797+
6798+static inline void write_smic_flags(struct si_sm_data *smic,
6799+ unsigned char flags)
6800+{
6801+ smic->io->outputb(smic->io, 2, flags);
6802+}
6803+
6804+static inline void write_smic_control(struct si_sm_data *smic,
6805+ unsigned char control)
6806+{
6807+ smic->io->outputb(smic->io, 1, control);
6808+}
6809+
6810+static inline void write_si_sm_data (struct si_sm_data *smic,
6811+ unsigned char data)
6812+{
6813+ smic->io->outputb(smic->io, 0, data);
6814+}
6815+
6816+static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
6817+{
6818+ (smic->error_retries)++;
6819+ if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
6820+ if (smic_debug & SMIC_DEBUG_ENABLE) {
6821+ printk(KERN_WARNING
6822+ "ipmi_smic_drv: smic hosed: %s\n", reason);
6823+ }
6824+ smic->state = SMIC_HOSED;
6825+ } else {
6826+ smic->write_count = smic->orig_write_count;
6827+ smic->write_pos = 0;
6828+ smic->read_pos = 0;
6829+ smic->state = SMIC_START_OP;
6830+ smic->smic_timeout = SMIC_RETRY_TIMEOUT;
6831+ }
6832+}
6833+
6834+static inline void write_next_byte(struct si_sm_data *smic)
6835+{
6836+ write_si_sm_data(smic, smic->write_data[smic->write_pos]);
6837+ (smic->write_pos)++;
6838+ (smic->write_count)--;
6839+}
6840+
6841+static inline void read_next_byte (struct si_sm_data *smic)
6842+{
6843+ if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
6844+ read_smic_data (smic);
6845+ smic->truncated = 1;
6846+ } else {
6847+ smic->read_data[smic->read_pos] = read_smic_data(smic);
6848+ (smic->read_pos)++;
6849+ }
6850+}
6851+
6852+/* SMIC Control/Status Code Components */
6853+#define SMIC_GET_STATUS 0x00 /* Control form's name */
6854+#define SMIC_READY 0x00 /* Status form's name */
6855+#define SMIC_WR_START 0x01 /* Unified Control/Status names... */
6856+#define SMIC_WR_NEXT 0x02
6857+#define SMIC_WR_END 0x03
6858+#define SMIC_RD_START 0x04
6859+#define SMIC_RD_NEXT 0x05
6860+#define SMIC_RD_END 0x06
6861+#define SMIC_CODE_MASK 0x0f
6862+
6863+#define SMIC_CONTROL 0x00
6864+#define SMIC_STATUS 0x80
6865+#define SMIC_CS_MASK 0x80
6866+
6867+#define SMIC_SMS 0x40
6868+#define SMIC_SMM 0x60
6869+#define SMIC_STREAM_MASK 0x60
6870+
6871+/* SMIC Control Codes */
6872+#define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
6873+#define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
6874+#define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
6875+#define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
6876+#define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
6877+#define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
6878+#define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
6879+
6880+#define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
6881+#define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
6882+#define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
6883+#define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
6884+#define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
6885+#define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
6886+#define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
6887+
6888+/* SMIC Status Codes */
6889+#define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY)
6890+#define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
6891+#define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
6892+#define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
6893+#define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
6894+#define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
6895+#define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
6896+
6897+#define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY)
6898+#define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
6899+#define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
6900+#define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
6901+#define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
6902+#define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
6903+#define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
6904+
6905+/* these are the control/status codes we actually use
6906+ SMIC_CC_SMS_GET_STATUS 0x40
6907+ SMIC_CC_SMS_WR_START 0x41
6908+ SMIC_CC_SMS_WR_NEXT 0x42
6909+ SMIC_CC_SMS_WR_END 0x43
6910+ SMIC_CC_SMS_RD_START 0x44
6911+ SMIC_CC_SMS_RD_NEXT 0x45
6912+ SMIC_CC_SMS_RD_END 0x46
6913+
6914+ SMIC_SC_SMS_READY 0xC0
6915+ SMIC_SC_SMS_WR_START 0xC1
6916+ SMIC_SC_SMS_WR_NEXT 0xC2
6917+ SMIC_SC_SMS_WR_END 0xC3
6918+ SMIC_SC_SMS_RD_START 0xC4
6919+ SMIC_SC_SMS_RD_NEXT 0xC5
6920+ SMIC_SC_SMS_RD_END 0xC6
6921+*/
6922+
6923+static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
6924+{
6925+ unsigned char status;
6926+ unsigned char flags;
6927+ unsigned char data;
6928+
6929+ if (smic->state == SMIC_HOSED) {
6930+ init_smic_data(smic, smic->io);
6931+ return SI_SM_HOSED;
6932+ }
6933+ if (smic->state != SMIC_IDLE) {
6934+ if (smic_debug & SMIC_DEBUG_STATES) {
6935+ printk(KERN_INFO
6936+ "smic_event - smic->smic_timeout = %ld,"
6937+ " time = %ld\n",
6938+ smic->smic_timeout, time);
6939+ }
6940+/* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */
6941+ if (time < SMIC_RETRY_TIMEOUT) {
6942+ smic->smic_timeout -= time;
6943+ if (smic->smic_timeout < 0) {
6944+ start_error_recovery(smic, "smic timed out.");
6945+ return SI_SM_CALL_WITH_DELAY;
6946+ }
6947+ }
6948+ }
6949+ flags = read_smic_flags(smic);
6950+ if (flags & SMIC_FLAG_BSY)
6951+ return SI_SM_CALL_WITH_DELAY;
6952+
6953+ status = read_smic_status (smic);
6954+ if (smic_debug & SMIC_DEBUG_STATES)
6955+ printk(KERN_INFO
6956+ "smic_event - state = %d, flags = 0x%02x,"
6957+ " status = 0x%02x\n",
6958+ smic->state, flags, status);
6959+
6960+ switch (smic->state) {
6961+ case SMIC_IDLE:
6962+ /* in IDLE we check for available messages */
6963+ if (flags & (SMIC_SMI |
6964+ SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
6965+ {
6966+ return SI_SM_ATTN;
6967+ }
6968+ return SI_SM_IDLE;
6969+
6970+ case SMIC_START_OP:
6971+ /* sanity check whether smic is really idle */
6972+ write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
6973+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
6974+ smic->state = SMIC_OP_OK;
6975+ break;
6976+
6977+ case SMIC_OP_OK:
6978+ if (status != SMIC_SC_SMS_READY) {
6979+ /* this should not happen */
6980+ start_error_recovery(smic,
6981+ "state = SMIC_OP_OK,"
6982+ " status != SMIC_SC_SMS_READY");
6983+ return SI_SM_CALL_WITH_DELAY;
6984+ }
6985+ /* OK so far; smic is idle let us start ... */
6986+ write_smic_control(smic, SMIC_CC_SMS_WR_START);
6987+ write_next_byte(smic);
6988+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
6989+ smic->state = SMIC_WRITE_START;
6990+ break;
6991+
6992+ case SMIC_WRITE_START:
6993+ if (status != SMIC_SC_SMS_WR_START) {
6994+ start_error_recovery(smic,
6995+ "state = SMIC_WRITE_START, "
6996+ "status != SMIC_SC_SMS_WR_START");
6997+ return SI_SM_CALL_WITH_DELAY;
6998+ }
6999+ /* we must not issue WR_(NEXT|END) unless
7000+ TX_DATA_READY is set */
7001+ if (flags & SMIC_TX_DATA_READY) {
7002+ if (smic->write_count == 1) {
7003+ /* last byte */
7004+ write_smic_control(smic, SMIC_CC_SMS_WR_END);
7005+ smic->state = SMIC_WRITE_END;
7006+ } else {
7007+ write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
7008+ smic->state = SMIC_WRITE_NEXT;
7009+ }
7010+ write_next_byte(smic);
7011+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7012+ }
7013+ else {
7014+ return SI_SM_CALL_WITH_DELAY;
7015+ }
7016+ break;
7017+
7018+ case SMIC_WRITE_NEXT:
7019+ if (status != SMIC_SC_SMS_WR_NEXT) {
7020+ start_error_recovery(smic,
7021+ "state = SMIC_WRITE_NEXT, "
7022+ "status != SMIC_SC_SMS_WR_NEXT");
7023+ return SI_SM_CALL_WITH_DELAY;
7024+ }
7025+ /* this is the same code as in SMIC_WRITE_START */
7026+ if (flags & SMIC_TX_DATA_READY) {
7027+ if (smic->write_count == 1) {
7028+ write_smic_control(smic, SMIC_CC_SMS_WR_END);
7029+ smic->state = SMIC_WRITE_END;
7030+ }
7031+ else {
7032+ write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
7033+ smic->state = SMIC_WRITE_NEXT;
7034+ }
7035+ write_next_byte(smic);
7036+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7037+ }
7038+ else {
7039+ return SI_SM_CALL_WITH_DELAY;
7040+ }
7041+ break;
7042+
7043+ case SMIC_WRITE_END:
7044+ if (status != SMIC_SC_SMS_WR_END) {
7045+ start_error_recovery (smic,
7046+ "state = SMIC_WRITE_END, "
7047+ "status != SMIC_SC_SMS_WR_END");
7048+ return SI_SM_CALL_WITH_DELAY;
7049+ }
7050+ /* data register holds an error code */
7051+ data = read_smic_data(smic);
7052+ if (data != 0) {
7053+ if (smic_debug & SMIC_DEBUG_ENABLE) {
7054+ printk(KERN_INFO
7055+ "SMIC_WRITE_END: data = %02x\n", data);
7056+ }
7057+ start_error_recovery(smic,
7058+ "state = SMIC_WRITE_END, "
7059+ "data != SUCCESS");
7060+ return SI_SM_CALL_WITH_DELAY;
7061+ } else {
7062+ smic->state = SMIC_WRITE2READ;
7063+ }
7064+ break;
7065+
7066+ case SMIC_WRITE2READ:
7067+ /* we must wait for RX_DATA_READY to be set before we
7068+ can continue */
7069+ if (flags & SMIC_RX_DATA_READY) {
7070+ write_smic_control(smic, SMIC_CC_SMS_RD_START);
7071+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7072+ smic->state = SMIC_READ_START;
7073+ } else {
7074+ return SI_SM_CALL_WITH_DELAY;
7075+ }
7076+ break;
7077+
7078+ case SMIC_READ_START:
7079+ if (status != SMIC_SC_SMS_RD_START) {
7080+ start_error_recovery(smic,
7081+ "state = SMIC_READ_START, "
7082+ "status != SMIC_SC_SMS_RD_START");
7083+ return SI_SM_CALL_WITH_DELAY;
7084+ }
7085+ if (flags & SMIC_RX_DATA_READY) {
7086+ read_next_byte(smic);
7087+ write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
7088+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7089+ smic->state = SMIC_READ_NEXT;
7090+ } else {
7091+ return SI_SM_CALL_WITH_DELAY;
7092+ }
7093+ break;
7094+
7095+ case SMIC_READ_NEXT:
7096+ switch (status) {
7097+ /* smic tells us that this is the last byte to be read
7098+ --> clean up */
7099+ case SMIC_SC_SMS_RD_END:
7100+ read_next_byte(smic);
7101+ write_smic_control(smic, SMIC_CC_SMS_RD_END);
7102+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7103+ smic->state = SMIC_READ_END;
7104+ break;
7105+ case SMIC_SC_SMS_RD_NEXT:
7106+ if (flags & SMIC_RX_DATA_READY) {
7107+ read_next_byte(smic);
7108+ write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
7109+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7110+ smic->state = SMIC_READ_NEXT;
7111+ } else {
7112+ return SI_SM_CALL_WITH_DELAY;
7113+ }
7114+ break;
7115+ default:
7116+ start_error_recovery(
7117+ smic,
7118+ "state = SMIC_READ_NEXT, "
7119+ "status != SMIC_SC_SMS_RD_(NEXT|END)");
7120+ return SI_SM_CALL_WITH_DELAY;
7121+ }
7122+ break;
7123+
7124+ case SMIC_READ_END:
7125+ if (status != SMIC_SC_SMS_READY) {
7126+ start_error_recovery(smic,
7127+ "state = SMIC_READ_END, "
7128+ "status != SMIC_SC_SMS_READY");
7129+ return SI_SM_CALL_WITH_DELAY;
7130+ }
7131+ data = read_smic_data(smic);
7132+ /* data register holds an error code */
7133+ if (data != 0) {
7134+ if (smic_debug & SMIC_DEBUG_ENABLE) {
7135+ printk(KERN_INFO
7136+ "SMIC_READ_END: data = %02x\n", data);
7137+ }
7138+ start_error_recovery(smic,
7139+ "state = SMIC_READ_END, "
7140+ "data != SUCCESS");
7141+ return SI_SM_CALL_WITH_DELAY;
7142+ } else {
7143+ smic->state = SMIC_IDLE;
7144+ return SI_SM_TRANSACTION_COMPLETE;
7145+ }
7146+
7147+ case SMIC_HOSED:
7148+ init_smic_data(smic, smic->io);
7149+ return SI_SM_HOSED;
7150+
7151+ default:
7152+ if (smic_debug & SMIC_DEBUG_ENABLE) {
7153+ printk(KERN_WARNING "smic->state = %d\n", smic->state);
7154+ start_error_recovery(smic, "state = UNKNOWN");
7155+ return SI_SM_CALL_WITH_DELAY;
7156+ }
7157+ }
7158+ smic->smic_timeout = SMIC_RETRY_TIMEOUT;
7159+ return SI_SM_CALL_WITHOUT_DELAY;
7160+}
7161+
7162+static int smic_detect(struct si_sm_data *smic)
7163+{
7164+ /* It's impossible for the SMIC fnags register to be all 1's,
7165+ (assuming a properly functioning, self-initialized BMC)
7166+ but that's what you get from reading a bogus address, so we
7167+ test that first. */
7168+ if (read_smic_flags(smic) == 0xff)
7169+ return 1;
7170+
7171+ return 0;
7172+}
7173+
7174+static void smic_cleanup(struct si_sm_data *kcs)
7175+{
7176+}
7177+
7178+static int smic_size(void)
7179+{
7180+ return sizeof(struct si_sm_data);
7181+}
7182+
7183+struct si_sm_handlers smic_smi_handlers =
7184+{
7185+ .version = IPMI_SMIC_VERSION,
7186+ .init_data = init_smic_data,
7187+ .start_transaction = start_smic_transaction,
7188+ .get_result = smic_get_result,
7189+ .event = smic_event,
7190+ .detect = smic_detect,
7191+ .cleanup = smic_cleanup,
7192+ .size = smic_size,
7193+};
7194diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_watchdog.c linux-2.4.23/drivers/char/ipmi/ipmi_watchdog.c
7195--- linux-2.4.23.org/drivers/char/ipmi/ipmi_watchdog.c 2004-01-02 23:31:35.448361402 +0100
7196+++ linux-2.4.23/drivers/char/ipmi/ipmi_watchdog.c 2004-01-02 23:33:48.069806033 +0100
7197@@ -50,6 +50,8 @@
7198 #include <asm/apic.h>
7199 #endif
7200
7201+#define IPMI_WATCHDOG_VERSION "v28"
7202+
7203 /*
7204 * The IPMI command/response information for the watchdog timer.
7205 */
7206@@ -153,10 +155,18 @@
7207 static char pretimeout_since_last_heartbeat = 0;
7208
7209 MODULE_PARM(timeout, "i");
7210+MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
7211 MODULE_PARM(pretimeout, "i");
7212+MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds.");
7213 MODULE_PARM(action, "s");
7214+MODULE_PARM_DESC(action, "Timeout action. One of: "
7215+ "reset, none, power_cycle, power_off.");
7216 MODULE_PARM(preaction, "s");
7217+MODULE_PARM_DESC(preaction, "Pretimeout action. One of: "
7218+ "pre_none, pre_smi, pre_nmi, pre_int.");
7219 MODULE_PARM(preop, "s");
7220+MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: "
7221+ "preop_none, preop_panic, preop_give_data.");
7222
7223 /* Default state of the timer. */
7224 static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
7225@@ -899,6 +909,7 @@
7226
7227 static struct ipmi_smi_watcher smi_watcher =
7228 {
7229+ .owner = THIS_MODULE,
7230 .new_smi = ipmi_new_smi,
7231 .smi_gone = ipmi_smi_gone
7232 };
7233@@ -907,6 +918,9 @@
7234 {
7235 int rv;
7236
7237+ printk(KERN_INFO "IPMI watchdog driver version "
7238+ IPMI_WATCHDOG_VERSION "\n");
7239+
7240 if (strcmp(action, "reset") == 0) {
7241 action_val = WDOG_TIMEOUT_RESET;
7242 } else if (strcmp(action, "none") == 0) {
7243@@ -995,9 +1009,6 @@
7244 register_reboot_notifier(&wdog_reboot_notifier);
7245 notifier_chain_register(&panic_notifier_list, &wdog_panic_notifier);
7246
7247- printk(KERN_INFO "IPMI watchdog by "
7248- "Corey Minyard (minyard@mvista.com)\n");
7249-
7250 return 0;
7251 }
7252
7253@@ -1030,6 +1041,7 @@
7254 pointers to our buffers, we want to make sure they are done before
7255 we release our memory. */
7256 while (atomic_read(&set_timeout_tofree)) {
7257+ set_current_state(TASK_UNINTERRUPTIBLE);
7258 schedule_timeout(1);
7259 }
7260
7261diff -urN linux-2.4.23.org/drivers/char/ipmi/Makefile linux-2.4.23/drivers/char/ipmi/Makefile
7262--- linux-2.4.23.org/drivers/char/ipmi/Makefile 2004-01-02 23:31:35.453360363 +0100
7263+++ linux-2.4.23/drivers/char/ipmi/Makefile 2004-01-02 23:33:48.071805617 +0100
7264@@ -6,15 +6,21 @@
7265
7266 export-objs := ipmi_msghandler.o ipmi_watchdog.o
7267
7268-list-multi := ipmi_kcs_drv.o
7269+list-multi := ipmi_kcs_drv.o ipmi_si_drv.o
7270 ipmi_kcs_drv-objs := ipmi_kcs_sm.o ipmi_kcs_intf.o
7271+ipmi_si_drv-objs := ipmi_si.o ipmi_kcs_sm.o ipmi_smic_sm.o ipmi_bt_sm.o
7272
7273 obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
7274 obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
7275+obj-$(CONFIG_IPMI_SI) += ipmi_si_drv.o
7276 obj-$(CONFIG_IPMI_KCS) += ipmi_kcs_drv.o
7277+obj-$(CONFIG_IPMI_SMB) += ipmi_smb_intf.o
7278 obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
7279
7280 include $(TOPDIR)/Rules.make
7281
7282 ipmi_kcs_drv.o: $(ipmi_kcs_drv-objs)
7283 $(LD) -r -o $@ $(ipmi_kcs_drv-objs)
7284+
7285+ipmi_si_drv.o: $(ipmi_si_drv-objs)
7286+ $(LD) -r -o $@ $(ipmi_si_drv-objs)
7287diff -urN linux-2.4.23.org/include/linux/ipmi.h linux-2.4.23/include/linux/ipmi.h
7288--- linux-2.4.23.org/include/linux/ipmi.h 2004-01-02 23:30:59.366857718 +0100
7289+++ linux-2.4.23/include/linux/ipmi.h 2004-01-02 23:33:48.094800839 +0100
7290@@ -160,6 +160,7 @@
7291 * The in-kernel interface.
7292 */
7293 #include <linux/list.h>
7294+#include <linux/module.h>
7295
7296 /* Opaque type for a IPMI message user. One of these is needed to
7297 send and receive messages. */
7298@@ -221,7 +222,12 @@
7299 void *handler_data,
7300 ipmi_user_t *user);
7301
7302-/* Destroy the given user of the IPMI layer. */
7303+/* Destroy the given user of the IPMI layer. Note that after this
7304+ function returns, the system is guaranteed to not call any
7305+ callbacks for the user. Thus as long as you destroy all the users
7306+ before you unload a module, you will be safe. And if you destroy
7307+ the users before you destroy the callback structures, it should be
7308+ safe, too. */
7309 int ipmi_destroy_user(ipmi_user_t user);
7310
7311 /* Get the IPMI version of the BMC we are talking to. */
7312@@ -261,6 +267,27 @@
7313 int priority);
7314
7315 /*
7316+ * Like ipmi_request, but lets you specify the number of retries and
7317+ * the retry time. The retries is the number of times the message
7318+ * will be resent if no reply is received. If set to -1, the default
7319+ * value will be used. The retry time is the time in milliseconds
7320+ * between retries. If set to zero, the default value will be
7321+ * used.
7322+ *
7323+ * Don't use this unless you *really* have to. It's primarily for the
7324+ * IPMI over LAN converter; since the LAN stuff does its own retries,
7325+ * it makes no sense to do it here. However, this can be used if you
7326+ * have unusual requirements.
7327+ */
7328+int ipmi_request_settime(ipmi_user_t user,
7329+ struct ipmi_addr *addr,
7330+ long msgid,
7331+ struct ipmi_msg *msg,
7332+ int priority,
7333+ int max_retries,
7334+ unsigned int retry_time_ms);
7335+
7336+/*
7337 * Like ipmi_request, but lets you specify the slave return address.
7338 */
7339 int ipmi_request_with_source(ipmi_user_t user,
7340@@ -331,6 +358,10 @@
7341 {
7342 struct list_head link;
7343
7344+ /* You must set the owner to the current module, if you are in
7345+ a module (generally just set it to "THIS_MODULE"). */
7346+ struct module *owner;
7347+
7348 /* These two are called with read locks held for the interface
7349 the watcher list. So you can add and remove users from the
7350 IPMI interface, send messages, etc., but you cannot add
7351@@ -422,6 +453,29 @@
7352 #define IPMICTL_SEND_COMMAND _IOR(IPMI_IOC_MAGIC, 13, \
7353 struct ipmi_req)
7354
7355+/* Messages sent to the interface with timing parameters are this
7356+ format. */
7357+struct ipmi_req_settime
7358+{
7359+ struct ipmi_req req;
7360+
7361+ /* See ipmi_request_settime() above for details on these
7362+ values. */
7363+ int retries;
7364+ unsigned int retry_time_ms;
7365+};
7366+/*
7367+ * Send a message to the interfaces with timing parameters. error values
7368+ * are:
7369+ * - EFAULT - an address supplied was invalid.
7370+ * - EINVAL - The address supplied was not valid, or the command
7371+ * was not allowed.
7372+ * - EMSGSIZE - The message to was too large.
7373+ * - ENOMEM - Buffers could not be allocated for the command.
7374+ */
7375+#define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, \
7376+ struct ipmi_req_settime)
7377+
7378 /* Messages received from the interface are this format. */
7379 struct ipmi_recv
7380 {
7381@@ -513,4 +567,18 @@
7382 #define IPMICTL_SET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 19, unsigned int)
7383 #define IPMICTL_GET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 20, unsigned int)
7384
7385+/*
7386+ * Get/set the default timing values for an interface. You shouldn't
7387+ * generally mess with these.
7388+ */
7389+struct ipmi_timing_parms
7390+{
7391+ int retries;
7392+ unsigned int retry_time_ms;
7393+};
7394+#define IPMICTL_SET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 22, \
7395+ struct ipmi_timing_parms)
7396+#define IPMICTL_GET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 23, \
7397+ struct ipmi_timing_parms)
7398+
7399 #endif /* __LINUX_IPMI_H */
7400diff -urN linux-2.4.23.org/include/linux/ipmi_msgdefs.h linux-2.4.23/include/linux/ipmi_msgdefs.h
7401--- linux-2.4.23.org/include/linux/ipmi_msgdefs.h 2004-01-02 23:30:59.337863741 +0100
7402+++ linux-2.4.23/include/linux/ipmi_msgdefs.h 2004-01-02 23:33:48.096800424 +0100
7403@@ -37,22 +37,34 @@
7404 /* Various definitions for IPMI messages used by almost everything in
7405 the IPMI stack. */
7406
7407-#define IPMI_NETFN_APP_REQUEST 0x06
7408-#define IPMI_NETFN_APP_RESPONSE 0x07
7409-
7410-#define IPMI_BMC_SLAVE_ADDR 0x20
7411+/* NetFNs and commands used inside the IPMI stack. */
7412+
7413+#define IPMI_NETFN_SENSOR_EVENT_REQUEST 0x04
7414+#define IPMI_NETFN_SENSOR_EVENT_RESPONSE 0x05
7415+#define IPMI_GET_EVENT_RECEIVER_CMD 0x01
7416
7417+#define IPMI_NETFN_APP_REQUEST 0x06
7418+#define IPMI_NETFN_APP_RESPONSE 0x07
7419 #define IPMI_GET_DEVICE_ID_CMD 0x01
7420-
7421 #define IPMI_CLEAR_MSG_FLAGS_CMD 0x30
7422 #define IPMI_GET_MSG_FLAGS_CMD 0x31
7423 #define IPMI_SEND_MSG_CMD 0x34
7424 #define IPMI_GET_MSG_CMD 0x33
7425-
7426 #define IPMI_SET_BMC_GLOBAL_ENABLES_CMD 0x2e
7427 #define IPMI_GET_BMC_GLOBAL_ENABLES_CMD 0x2f
7428 #define IPMI_READ_EVENT_MSG_BUFFER_CMD 0x35
7429
7430+#define IPMI_NETFN_STORAGE_REQUEST 0x0a
7431+#define IPMI_NETFN_STORAGE_RESPONSE 0x0b
7432+#define IPMI_ADD_SEL_ENTRY_CMD 0x44
7433+
7434+/* The default slave address */
7435+#define IPMI_BMC_SLAVE_ADDR 0x20
7436+
7437 #define IPMI_MAX_MSG_LENGTH 80
7438
7439+#define IPMI_CC_NO_ERROR 0
7440+#define IPMI_NODE_BUSY_ERR 0xc0
7441+#define IPMI_LOST_ARBITRATION_ERR 0x81
7442+
7443 #endif /* __LINUX_IPMI_MSGDEFS_H */
7444diff -urN linux-2.4.23.org/include/linux/ipmi_smi.h linux-2.4.23/include/linux/ipmi_smi.h
7445--- linux-2.4.23.org/include/linux/ipmi_smi.h 2004-01-02 23:30:59.336863949 +0100
7446+++ linux-2.4.23/include/linux/ipmi_smi.h 2004-01-02 23:33:48.098800008 +0100
7447@@ -35,6 +35,8 @@
7448 #define __LINUX_IPMI_SMI_H
7449
7450 #include <linux/ipmi_msgdefs.h>
7451+#include <linux/proc_fs.h>
7452+#include <linux/module.h>
7453
7454 /* This files describes the interface for IPMI system management interface
7455 drivers to bind into the IPMI message handler. */
7456@@ -141,4 +143,11 @@
7457 msg->done(msg);
7458 }
7459
7460+/* Allow the lower layer to add things to the proc filesystem
7461+ directory for this interface. Note that the entry will
7462+ automatically be dstroyed when the interface is destroyed. */
7463+int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
7464+ read_proc_t *read_proc, write_proc_t *write_proc,
7465+ void *data, struct module *owner);
7466+
7467 #endif /* __LINUX_IPMI_SMI_H */
7468diff -urN linux-2.4.23.org/include/linux/net.h linux-2.4.23/include/linux/net.h
7469--- linux-2.4.23.org/include/linux/net.h 2004-01-02 23:30:59.030927510 +0100
7470+++ linux-2.4.23/include/linux/net.h 2004-01-02 23:33:48.123794815 +0100
7471@@ -24,7 +24,7 @@
7472
7473 struct poll_table_struct;
7474
7475-#define NPROTO 32 /* should be enough for now.. */
7476+#define NPROTO 64 /* should be enough for now.. */
7477
7478
7479 #define SYS_SOCKET 1 /* sys_socket(2) */
7480diff -urN linux-2.4.23.org/include/linux/socket.h linux-2.4.23/include/linux/socket.h
7481--- linux-2.4.23.org/include/linux/socket.h 2004-01-02 23:30:58.991935611 +0100
7482+++ linux-2.4.23/include/linux/socket.h 2004-01-02 23:33:48.151788998 +0100
7483@@ -175,7 +175,8 @@
7484 #define AF_WANPIPE 25 /* Wanpipe API Sockets */
7485 #define AF_LLC 26 /* Linux LLC */
7486 #define AF_BLUETOOTH 31 /* Bluetooth sockets */
7487-#define AF_MAX 32 /* For now.. */
7488+#define AF_IPMI 32 /* IPMI sockers */
7489+#define AF_MAX 33 /* For now.. */
7490
7491 /* Protocol families, same as address families. */
7492 #define PF_UNSPEC AF_UNSPEC
7493@@ -207,6 +208,7 @@
7494 #define PF_WANPIPE AF_WANPIPE
7495 #define PF_LLC AF_LLC
7496 #define PF_BLUETOOTH AF_BLUETOOTH
7497+#define PF_IPMI AF_IPMI
7498 #define PF_MAX AF_MAX
7499
7500 /* Maximum queue length specifiable by listen. */
7501diff -urN linux-2.4.23.org/include/net/af_ipmi.h linux-2.4.23/include/net/af_ipmi.h
7502--- linux-2.4.23.org/include/net/af_ipmi.h 1970-01-01 01:00:00.000000000 +0100
7503+++ linux-2.4.23/include/net/af_ipmi.h 2004-01-02 23:33:48.155788167 +0100
7504@@ -0,0 +1,66 @@
7505+#ifndef _NET_IPMI_H
7506+#define _NET_IPMI_H
7507+
7508+#include <linux/ipmi.h>
7509+
7510+/*
7511+ * This is ipmi address for socket
7512+ */
7513+struct sockaddr_ipmi {
7514+ sa_family_t sipmi_family; /* AF_IPMI */
7515+ int if_num; /* IPMI interface number */
7516+ struct ipmi_addr ipmi_addr;
7517+};
7518+#define SOCKADDR_IPMI_OVERHEAD (sizeof(struct sockaddr_ipmi) \
7519+ - sizeof(struct ipmi_addr))
7520+
7521+/* A msg_control item, this takes a 'struct ipmi_timing_parms' */
7522+#define IPMI_CMSG_TIMING_PARMS 0x01
7523+
7524+/*
7525+ * This is ipmi message for socket
7526+ */
7527+struct ipmi_sock_msg {
7528+ int recv_type;
7529+ long msgid;
7530+
7531+ unsigned char netfn;
7532+ unsigned char cmd;
7533+ int data_len;
7534+ unsigned char data[0];
7535+};
7536+
7537+#define IPMI_MAX_SOCK_MSG_LENGTH (sizeof(struct ipmi_sock_msg)+IPMI_MAX_MSG_LENGTH)
7538+
7539+/* Register/unregister to receive specific commands. Uses struct
7540+ ipmi_cmdspec from linux/ipmi.h */
7541+#define SIOCIPMIREGCMD (SIOCPROTOPRIVATE + 0)
7542+#define SIOCIPMIUNREGCMD (SIOCPROTOPRIVATE + 1)
7543+
7544+/* Register to receive events. Takes an integer */
7545+#define SIOCIPMIGETEVENT (SIOCPROTOPRIVATE + 2)
7546+
7547+/* Set the default timing parameters for the socket. Takes a struct
7548+ ipmi_timing_parms from linux/ipmi.h */
7549+#define SIOCIPMISETTIMING (SIOCPROTOPRIVATE + 3)
7550+#define SIOCIPMIGETTIMING (SIOCPROTOPRIVATE + 4)
7551+
7552+/* Set/Get the IPMB address of the MC we are connected to, takes an
7553+ unsigned int. */
7554+#define SIOCIPMISETADDR (SIOCPROTOPRIVATE + 5)
7555+#define SIOCIPMIGETADDR (SIOCPROTOPRIVATE + 6)
7556+
7557+/* Socket information for IPMI for protinfo. */
7558+struct ipmi_sock {
7559+ ipmi_user_t user;
7560+ struct sockaddr_ipmi addr;
7561+ struct list_head msg_list;
7562+
7563+ wait_queue_head_t wait;
7564+ spinlock_t lock;
7565+
7566+ int default_retries;
7567+ unsigned int default_retry_time_ms;
7568+};
7569+
7570+#endif/*_NET_IPMI_H*/
7571diff -urN linux-2.4.23.org/include/net/sock.h linux-2.4.23/include/net/sock.h
7572--- linux-2.4.23.org/include/net/sock.h 2004-01-02 23:31:07.058259765 +0100
7573+++ linux-2.4.23/include/net/sock.h 2004-01-02 23:33:48.166785882 +0100
7574@@ -98,6 +98,10 @@
7575 #include <net/irda/irda.h>
7576 #endif
7577
7578+#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
7579+#include <net/af_ipmi.h>
7580+#endif
7581+
7582 #if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE)
7583 struct atm_vcc;
7584 #endif
7585@@ -673,6 +677,9 @@
7586 #if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE)
7587 struct wanpipe_opt *af_wanpipe;
7588 #endif
7589+#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
7590+ struct ipmi_sock af_ipmi;
7591+#endif
7592 } protinfo;
7593
7594
7595diff -urN linux-2.4.23.org/net/Config.in linux-2.4.23/net/Config.in
7596--- linux-2.4.23.org/net/Config.in 2004-01-02 23:31:20.022566302 +0100
7597+++ linux-2.4.23/net/Config.in 2004-01-02 23:33:48.180782973 +0100
7598@@ -16,6 +16,7 @@
7599 fi
7600 bool 'Socket Filtering' CONFIG_FILTER
7601 tristate 'Unix domain sockets' CONFIG_UNIX
7602+tristate 'IPMI sockets' CONFIG_IPMI_SOCKET
7603 bool 'TCP/IP networking' CONFIG_INET
7604 if [ "$CONFIG_INET" = "y" ]; then
7605 source net/ipv4/Config.in
7606diff -urN linux-2.4.23.org/net/ipmi/af_ipmi.c linux-2.4.23/net/ipmi/af_ipmi.c
7607--- linux-2.4.23.org/net/ipmi/af_ipmi.c 1970-01-01 01:00:00.000000000 +0100
7608+++ linux-2.4.23/net/ipmi/af_ipmi.c 2004-01-02 23:33:48.187781519 +0100
7609@@ -0,0 +1,593 @@
7610+/*
7611+ * IPMI Socket Glue
7612+ *
7613+ * Author: Louis Zhuang <louis.zhuang@linux.intel.com>
7614+ * Copyright by Intel Corp., 2003
7615+ */
7616+#include <linux/module.h>
7617+#include <linux/config.h>
7618+#include <linux/kernel.h>
7619+#include <linux/major.h>
7620+#include <linux/signal.h>
7621+#include <linux/sched.h>
7622+#include <linux/errno.h>
7623+#include <linux/string.h>
7624+#include <linux/stat.h>
7625+#include <linux/socket.h>
7626+#include <linux/fcntl.h>
7627+#include <linux/sockios.h>
7628+#include <linux/net.h>
7629+#include <linux/in.h>
7630+#include <linux/fs.h>
7631+#include <linux/slab.h>
7632+#include <asm/uaccess.h>
7633+#include <linux/skbuff.h>
7634+#include <linux/tcp.h>
7635+#include <net/sock.h>
7636+#include <linux/proc_fs.h>
7637+#include <linux/init.h>
7638+#include <linux/poll.h>
7639+#include <linux/smp_lock.h>
7640+#include <linux/mount.h>
7641+#include <linux/ipmi.h>
7642+#include <net/af_ipmi.h>
7643+#include <linux/rtnetlink.h>
7644+
7645+#define IPMI_SOCKINTF_VERSION "v25"
7646+
7647+#ifdef CONFIG_DEBUG_KERNEL
7648+static int debug = 0;
7649+#define dbg(format, arg...) \
7650+ do { \
7651+ if(debug) \
7652+ printk (KERN_DEBUG "%s: " format "\n", \
7653+ __FUNCTION__, ## arg); \
7654+ } while(0)
7655+#else
7656+#define dbg(format, arg...)
7657+#endif /* CONFIG_DEBUG_KERNEL */
7658+
7659+#define err(format, arg...) \
7660+ printk(KERN_ERR "%s: " format "\n", \
7661+ __FUNCTION__ , ## arg)
7662+#define info(format, arg...) \
7663+ printk(KERN_INFO "%s: " format "\n", \
7664+ __FUNCTION__ , ## arg)
7665+#define warn(format, arg...) \
7666+ printk(KERN_WARNING "%s: " format "\n", \
7667+ __FUNCTION__ , ## arg)
7668+#define trace(format, arg...) \
7669+ printk(KERN_INFO "%s(" format ")\n", \
7670+ __FUNCTION__ , ## arg)
7671+
7672+static kmem_cache_t *ipmi_sk_cachep = NULL;
7673+
7674+static atomic_t ipmi_nr_socks = ATOMIC_INIT(0);
7675+
7676+
7677+
7678+/*
7679+ * utility functions
7680+ */
7681+static inline struct ipmi_sock *to_ipmi_sock(struct sock *sk)
7682+{
7683+ return &sk->protinfo.af_ipmi;
7684+}
7685+
7686+static inline void ipmi_release_sock(struct sock *sk, int embrion)
7687+{
7688+ struct ipmi_sock *i = to_ipmi_sock(sk);
7689+ struct sk_buff *skb;
7690+
7691+ if (i->user) {
7692+ ipmi_destroy_user(i->user);
7693+ i->user = NULL;
7694+ }
7695+
7696+ sock_orphan(sk);
7697+ sk->shutdown = SHUTDOWN_MASK;
7698+ sk->state = TCP_CLOSE;
7699+
7700+ while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
7701+ kfree_skb(skb);
7702+
7703+ sock_put(sk);
7704+}
7705+
7706+static inline long ipmi_wait_for_queue(struct ipmi_sock *i, long timeo)
7707+{
7708+
7709+ DECLARE_WAITQUEUE(wait, current);
7710+
7711+ set_current_state(TASK_INTERRUPTIBLE);
7712+ add_wait_queue_exclusive(&i->wait, &wait);
7713+ timeo = schedule_timeout(timeo);
7714+ set_current_state(TASK_RUNNING);
7715+ remove_wait_queue(&i->wait, &wait);
7716+ return timeo;
7717+}
7718+
7719+/*
7720+ * IPMI operation functions
7721+ */
7722+static void sock_receive_handler(struct ipmi_recv_msg *msg,
7723+ void *handler_data)
7724+{
7725+ struct ipmi_sock *i = (struct ipmi_sock *)handler_data;
7726+ unsigned long flags;
7727+
7728+ spin_lock_irqsave(&i->lock, flags);
7729+ list_add_tail(&msg->link, &i->msg_list);
7730+ spin_unlock_irqrestore(&i->lock, flags);
7731+
7732+ wake_up_interruptible(&i->wait);
7733+}
7734+
7735+/*
7736+ * protocol operation functions
7737+ */
7738+static int ipmi_release(struct socket *sock)
7739+{
7740+ struct sock *sk = sock->sk;
7741+
7742+ if (!sk)
7743+ return 0;
7744+
7745+ sock->sk=NULL;
7746+ ipmi_release_sock(sk, 0);
7747+ return 0;
7748+}
7749+
7750+static struct ipmi_user_hndl ipmi_hnd = {
7751+ .ipmi_recv_hndl = sock_receive_handler
7752+};
7753+
7754+static int ipmi_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
7755+{
7756+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7757+ struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)uaddr;
7758+ int err = -EINVAL;
7759+
7760+ if (i->user != NULL) {
7761+ dbg("Cannot bind twice: %p", i->user);
7762+ return -EINVAL;
7763+ }
7764+
7765+ err = ipmi_create_user(addr->if_num, &ipmi_hnd, i, &i->user);
7766+ if (err) {
7767+ dbg("Cannot create user for the socket: %p", i->user);
7768+ return err;
7769+ }
7770+
7771+ memcpy(&i->addr, addr, sizeof(i->addr));
7772+ return 0;
7773+}
7774+
7775+static int ipmi_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
7776+{
7777+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7778+ memcpy(uaddr, &i->addr, sizeof(i->addr));
7779+ return 0;
7780+}
7781+
7782+static unsigned int ipmi_poll(struct file * file, struct socket *sock, poll_table *wait)
7783+{
7784+ unsigned int has_msg = 0;
7785+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7786+ unsigned long flags;
7787+
7788+ poll_wait(file, &i->wait, wait);
7789+ spin_lock_irqsave(&i->lock, flags);
7790+ if (!list_empty(&i->msg_list))
7791+ has_msg = 1;
7792+ spin_unlock_irqrestore(&i->lock, flags);
7793+
7794+ if (has_msg)
7795+ return POLLIN | POLLRDNORM;
7796+ return 0;
7797+}
7798+
7799+static int ipmi_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
7800+{
7801+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7802+ struct ipmi_cmdspec val;
7803+ int ival;
7804+ unsigned int uival;
7805+ int err;
7806+
7807+ dbg("cmd=%#x, arg=%#lx", cmd, arg);
7808+ switch(cmd) {
7809+ case SIOCIPMIREGCMD:
7810+ err = copy_from_user((void *)&val, (void *)arg,
7811+ sizeof(cmd));
7812+ if (err) {
7813+ err = -EFAULT;
7814+ break;
7815+ }
7816+
7817+ err = ipmi_register_for_cmd(i->user, val.netfn,
7818+ val.cmd);
7819+ break;
7820+
7821+ case SIOCIPMIUNREGCMD:
7822+ err = copy_from_user((void *)&val, (void *)arg,
7823+ sizeof(cmd));
7824+ if (err) {
7825+ err = -EFAULT;
7826+ break;
7827+ }
7828+
7829+ err = ipmi_unregister_for_cmd(i->user, val.netfn,
7830+ val.cmd);
7831+ break;
7832+
7833+ case SIOCIPMIGETEVENT:
7834+ err = copy_from_user((void *)&ival, (void *)arg,
7835+ sizeof(ival));
7836+ if (err) {
7837+ err = -EFAULT;
7838+ break;
7839+ }
7840+
7841+ err = ipmi_set_gets_events(i->user, ival);
7842+ break;
7843+
7844+ case SIOCIPMISETADDR:
7845+ err = copy_from_user((void *)&uival, (void *)arg,
7846+ sizeof(uival));
7847+ if (err) {
7848+ err = -EFAULT;
7849+ break;
7850+ }
7851+
7852+ ipmi_set_my_address(i->user, uival);
7853+ break;
7854+
7855+ case SIOCIPMIGETADDR:
7856+ uival = ipmi_get_my_address(i->user);
7857+
7858+ if (copy_to_user((void *) arg, &uival, sizeof(uival))) {
7859+ err = -EFAULT;
7860+ break;
7861+ }
7862+ err = 0;
7863+ break;
7864+
7865+ case SIOCIPMISETTIMING:
7866+ {
7867+ struct ipmi_timing_parms parms;
7868+
7869+ if (copy_from_user(&parms, (void *) arg, sizeof(parms))) {
7870+ err = -EFAULT;
7871+ break;
7872+ }
7873+
7874+ i->default_retries = parms.retries;
7875+ i->default_retry_time_ms = parms.retry_time_ms;
7876+ err = 0;
7877+ break;
7878+ }
7879+
7880+ case SIOCIPMIGETTIMING:
7881+ {
7882+ struct ipmi_timing_parms parms;
7883+
7884+ parms.retries = i->default_retries;
7885+ parms.retry_time_ms = i->default_retry_time_ms;
7886+
7887+ if (copy_to_user((void *) arg, &parms, sizeof(parms))) {
7888+ err = -EFAULT;
7889+ break;
7890+ }
7891+
7892+ err = 0;
7893+ break;
7894+ }
7895+
7896+ default:
7897+ err = dev_ioctl(cmd, (void *)arg);
7898+ break;
7899+ }
7900+
7901+ return err;
7902+}
7903+
7904+static int ipmi_recvmsg(struct socket *sock, struct msghdr *msg, int size,
7905+ int rflags, struct scm_cookie *scm)
7906+{
7907+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7908+ long timeo;
7909+ struct ipmi_recv_msg *rcvmsg;
7910+ struct sockaddr_ipmi addr;
7911+ char buf[IPMI_MAX_SOCK_MSG_LENGTH];
7912+ struct ipmi_sock_msg *smsg = (struct ipmi_sock_msg *)buf;
7913+ int err;
7914+ unsigned long flags;
7915+
7916+ timeo = sock_rcvtimeo(sock->sk, rflags & MSG_DONTWAIT);
7917+
7918+ while (1) {
7919+ spin_lock_irqsave(&i->lock, flags);
7920+ if (!list_empty(&i->msg_list))
7921+ break;
7922+ spin_unlock_irqrestore(&i->lock, flags);
7923+ if (!timeo) {
7924+ return -EAGAIN;
7925+ } else if (signal_pending (current)) {
7926+ dbg("Signal pending: %d", 1);
7927+ return -EINTR;
7928+ }
7929+
7930+ timeo = ipmi_wait_for_queue(i, timeo);
7931+ }
7932+
7933+ rcvmsg = list_entry(i->msg_list.next, struct ipmi_recv_msg, link);
7934+ list_del(&rcvmsg->link);
7935+ spin_unlock_irqrestore(&i->lock, flags);
7936+
7937+ memcpy(&addr.ipmi_addr, &rcvmsg->addr, sizeof(addr.ipmi_addr));
7938+ addr.if_num = i->addr.if_num;
7939+ addr.sipmi_family = i->addr.sipmi_family;
7940+ memcpy(msg->msg_name, &addr, sizeof(addr));
7941+ msg->msg_namelen = (SOCKADDR_IPMI_OVERHEAD
7942+ + ipmi_addr_length(rcvmsg->addr.addr_type));
7943+
7944+ smsg->recv_type = rcvmsg->recv_type;
7945+ smsg->msgid = rcvmsg->msgid;
7946+ smsg->netfn = rcvmsg->msg.netfn;
7947+ smsg->cmd = rcvmsg->msg.cmd;
7948+ smsg->data_len = rcvmsg->msg.data_len;
7949+ memcpy(smsg->data, rcvmsg->msg.data, smsg->data_len);
7950+
7951+ ipmi_free_recv_msg(rcvmsg);
7952+
7953+ err = memcpy_toiovec(msg->msg_iov, (void *)smsg,
7954+ sizeof(struct ipmi_sock_msg) + smsg->data_len);
7955+ if (err) {
7956+ dbg("Cannot copy data to user: %p", i->user);
7957+ return err;
7958+ }
7959+
7960+ dbg("user=%p", i->user);
7961+ dbg("addr_type=%x, channel=%x",
7962+ addr.ipmi_addr.addr_type, addr.ipmi_addr.channel);
7963+ dbg("netfn=%#02x, cmd=%#02x, data=%p, data_len=%x",
7964+ smsg->netfn, smsg->cmd, smsg->data, smsg->data_len);
7965+
7966+ return (sizeof(struct ipmi_sock_msg) + smsg->data_len);
7967+}
7968+
7969+static int ipmi_sendmsg(struct socket *sock, struct msghdr *msg, int len,
7970+ struct scm_cookie *scm)
7971+{
7972+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7973+ struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)msg->msg_name;
7974+ struct ipmi_msg imsg;
7975+ unsigned char buf[IPMI_MAX_SOCK_MSG_LENGTH];
7976+ struct ipmi_sock_msg *smsg = (struct ipmi_sock_msg *)buf;
7977+ int err;
7978+ struct ipmi_timing_parms tparms;
7979+ struct cmsghdr *cmsg;
7980+
7981+ err = ipmi_validate_addr(&addr->ipmi_addr,
7982+ msg->msg_namelen - SOCKADDR_IPMI_OVERHEAD);
7983+ if (err) {
7984+ dbg("Invalid IPMI address: %p", i->user);
7985+ goto err;
7986+ }
7987+
7988+ if (len > IPMI_MAX_SOCK_MSG_LENGTH) {
7989+ err = -EINVAL;
7990+ dbg("Message too long: %p", i->user);
7991+ goto err;
7992+ }
7993+
7994+ if (len < sizeof(struct ipmi_sock_msg)) {
7995+ err = -EINVAL;
7996+ dbg("Msg data too small for header: %p", i->user);
7997+ goto err;
7998+ }
7999+
8000+ err = memcpy_fromiovec((void *)smsg, msg->msg_iov, len);
8001+ if (err) {
8002+ dbg("Cannot copy data to kernel: %p", i->user);
8003+ goto err;
8004+ }
8005+
8006+ if (len < smsg->data_len+sizeof(struct ipmi_sock_msg)) {
8007+ err = -EINVAL;
8008+ dbg("Msg data is out of bound: %p", i->user);
8009+ goto err;
8010+ }
8011+
8012+ /* Set defaults. */
8013+ tparms.retries = i->default_retries;
8014+ tparms.retry_time_ms = i->default_retry_time_ms;
8015+
8016+ for (cmsg=CMSG_FIRSTHDR(msg);
8017+ cmsg;
8018+ cmsg = CMSG_NXTHDR(msg, cmsg))
8019+ {
8020+ if (cmsg->cmsg_len < sizeof(struct cmsghdr)) {
8021+ err = -EINVAL;
8022+ dbg("cmsg length too short: %p", i->user);
8023+ goto err;
8024+ }
8025+
8026+ if (cmsg->cmsg_level != SOL_SOCKET)
8027+ continue;
8028+
8029+ if (cmsg->cmsg_type == IPMI_CMSG_TIMING_PARMS) {
8030+ struct ipmi_timing_parms *pparms;
8031+
8032+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(*pparms))) {
8033+ err = -EINVAL;
8034+ dbg("timing parms cmsg not right size: %p",
8035+ i->user);
8036+ goto err;
8037+ }
8038+ pparms = (struct ipmi_timing_parms *) CMSG_DATA(cmsg);
8039+ tparms.retries = pparms->retries;
8040+ tparms.retry_time_ms = pparms->retry_time_ms;
8041+ }
8042+ }
8043+
8044+ imsg.netfn = smsg->netfn;
8045+ imsg.cmd = smsg->cmd;
8046+ imsg.data = smsg->data;
8047+ imsg.data_len = smsg->data_len;
8048+
8049+ dbg("user=%p", i->user);
8050+ dbg("addr_type=%x, channel=%x",
8051+ addr->ipmi_addr.addr_type, addr->ipmi_addr.channel);
8052+ dbg("netfn=%#02x, cmd=%#02x, data=%p, data_len=%x",
8053+ imsg.netfn, imsg.cmd, imsg.data, imsg.data_len);
8054+ err = ipmi_request_settime(i->user, &addr->ipmi_addr,
8055+ smsg->msgid, &imsg, 0,
8056+ tparms.retries, tparms.retry_time_ms);
8057+ if (err) {
8058+ dbg("Cannot send message: %p", i->user);
8059+ goto err;
8060+ }
8061+
8062+err:
8063+ return err;
8064+}
8065+
8066+static struct proto_ops ipmi_ops = {
8067+ .family = PF_IPMI,
8068+ .release = ipmi_release,
8069+ .bind = ipmi_bind,
8070+ .connect = sock_no_connect,
8071+ .socketpair = sock_no_socketpair,
8072+ .accept = sock_no_accept,
8073+ .getname = ipmi_getname,
8074+ .poll = ipmi_poll,
8075+ .ioctl = ipmi_ioctl,
8076+ .listen = sock_no_listen,
8077+ .shutdown = sock_no_shutdown,
8078+ .setsockopt = sock_no_setsockopt,
8079+ .getsockopt = sock_no_getsockopt,
8080+ .sendmsg = ipmi_sendmsg,
8081+ .recvmsg = ipmi_recvmsg,
8082+ .mmap = sock_no_mmap,
8083+ .sendpage = sock_no_sendpage
8084+};
8085+
8086+
8087+static void ipmi_sock_destructor(struct sock *sk)
8088+{
8089+ skb_queue_purge(&sk->receive_queue);
8090+
8091+ BUG_TRAP(atomic_read(&sk->wmem_alloc) == 0);
8092+ BUG_TRAP(sk->socket==NULL);
8093+ if (sk->dead==0) {
8094+ printk("Attempt to release alive ipmi socket: %p\n", sk);
8095+ return;
8096+ }
8097+
8098+ atomic_dec(&ipmi_nr_socks);
8099+ MOD_DEC_USE_COUNT;
8100+}
8101+
8102+/*
8103+ * net protocol functions
8104+ */
8105+static struct sock *ipmi_socket_create1(struct socket *sock)
8106+{
8107+ struct sock *sk;
8108+
8109+ if (atomic_read(&ipmi_nr_socks) >= 2*files_stat.max_files)
8110+ return NULL;
8111+
8112+ MOD_INC_USE_COUNT;
8113+
8114+ sk = sk_alloc(PF_IPMI, GFP_KERNEL, 1);
8115+ if (!sk) {
8116+ MOD_DEC_USE_COUNT;
8117+ return NULL;
8118+ }
8119+
8120+ sock_init_data(sock, sk);
8121+ sock->sk->rcvtimeo = 5*HZ;
8122+ sock->sk->destruct = ipmi_sock_destructor;
8123+ spin_lock_init(&sk->protinfo.af_ipmi.lock);
8124+ INIT_LIST_HEAD(&sk->protinfo.af_ipmi.msg_list);
8125+ init_waitqueue_head(&sk->protinfo.af_ipmi.wait);
8126+
8127+ /* Set to use default values. */
8128+ sk->protinfo.af_ipmi.default_retries = -1;
8129+ sk->protinfo.af_ipmi.default_retry_time_ms = 0;
8130+
8131+ atomic_inc(&ipmi_nr_socks);
8132+ return sk;
8133+}
8134+
8135+static int ipmi_socket_create(struct socket *sock, int protocol)
8136+{
8137+ if (!capable(CAP_NET_RAW))
8138+ return -EPERM;
8139+ if (protocol && protocol != PF_IPMI)
8140+ return -EPROTONOSUPPORT;
8141+
8142+ sock->state = SS_UNCONNECTED;
8143+
8144+ switch (sock->type) {
8145+ case SOCK_RAW:
8146+ sock->type=SOCK_DGRAM;
8147+ case SOCK_DGRAM:
8148+ sock->ops = &ipmi_ops;
8149+ break;
8150+ default:
8151+ return -EPROTONOSUPPORT;
8152+ }
8153+
8154+ return ipmi_socket_create1(sock)? 0 : -ENOMEM;
8155+}
8156+
8157+static struct net_proto_family ipmi_family_ops = {
8158+ .family = PF_IPMI,
8159+ .create = ipmi_socket_create,
8160+};
8161+
8162+
8163+/*
8164+ * init/exit functions
8165+ */
8166+static int __init ipmi_socket_init(void)
8167+{
8168+
8169+ int err=0;
8170+
8171+ printk(KERN_INFO "ipmi socket interface version "
8172+ IPMI_SOCKINTF_VERSION "\n");
8173+
8174+ ipmi_sk_cachep = kmem_cache_create("ipmi_sock",
8175+ sizeof(struct ipmi_sock), 0,
8176+ SLAB_HWCACHE_ALIGN, 0, 0);
8177+ if (!ipmi_sk_cachep) {
8178+ printk(KERN_CRIT "%s: Unable to create ipmi_sock SLAB cache\n", __func__);
8179+ err = -ENOMEM;
8180+ goto out;
8181+ }
8182+
8183+ err = sock_register(&ipmi_family_ops);
8184+ if (err)
8185+ kmem_cache_destroy(ipmi_sk_cachep);
8186+out:
8187+ return err;
8188+}
8189+
8190+static void __exit ipmi_socket_exit(void)
8191+{
8192+ sock_unregister(PF_IPMI);
8193+ kmem_cache_destroy(ipmi_sk_cachep);
8194+}
8195+
8196+#ifdef CONFIG_DEBUG_KERNEL
8197+MODULE_PARM(debug, "i");
8198+#endif
8199+module_init(ipmi_socket_init);
8200+module_exit(ipmi_socket_exit);
8201+
8202+MODULE_LICENSE("GPL");
8203diff -urN linux-2.4.23.org/net/ipmi/Makefile linux-2.4.23/net/ipmi/Makefile
8204--- linux-2.4.23.org/net/ipmi/Makefile 1970-01-01 01:00:00.000000000 +0100
8205+++ linux-2.4.23/net/ipmi/Makefile 2004-01-02 23:33:48.189781104 +0100
8206@@ -0,0 +1,7 @@
8207+
8208+O_TARGET = ipmi.o
8209+
8210+obj-$(CONFIG_IPMI_SOCKET) = af_ipmi.o
8211+
8212+include $(TOPDIR)/Rules.make
8213+
8214diff -urN linux-2.4.23.org/net/Makefile linux-2.4.23/net/Makefile
8215--- linux-2.4.23.org/net/Makefile 2004-01-02 23:31:20.022566302 +0100
8216+++ linux-2.4.23/net/Makefile 2004-01-02 23:34:55.468801116 +0100
8217@@ -8,7 +8,7 @@
8218 O_TARGET := network.o
8219
8220 mod-subdirs := ipv4/netfilter ipv6/netfilter bridge/netfilter ipx irda \
8221- bluetooth atm netlink sched core sctp
8222+ bluetooth atm netlink sched core sctp ipmi
8223 export-objs := netsyms.o
8224
8225 subdir-y := core ethernet
8226@@ -54,6 +54,7 @@
8227 subdir-$(CONFIG_DECNET) += decnet
8228 subdir-$(CONFIG_ECONET) += econet
8229 subdir-$(CONFIG_VLAN_8021Q) += 8021q
8230+subdir-$(CONFIG_IPMI_SOCKET) += ipmi
8231
8232 ifeq ($(CONFIG_NETFILTER),y)
8233 mod-subdirs += ipv4/ipvs
This page took 5.943076 seconds and 4 git commands to generate.