1 diff -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
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.
18 @@ -29534,14 +29541,41 @@
19 generate an IPMI event describing the panic to each interface
20 registered with the message handler.
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
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().
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.
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
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.
61 diff -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
65 driver, each open file for this device ties in to the message handler
68 -ipmi_kcs_drv - A driver for the KCS SMI. Most system have a KCS
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.
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
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
82 +af_ipmi - A network socket interface to IPMI. This doesn't take up
83 +a character device in your system.
86 Much documentation for the interface is in the include files. The
87 IPMI include files are:
89 -ipmi.h - Contains the user interface and IOCTL interface for IPMI.
90 +net/af_ipmi.h - Contains the socket interface.
92 +linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
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.
98 -ipmi_msgdefs.h - General definitions for base IPMI messaging.
99 +linux/ipmi_msgdefs.h - General definitions for base IPMI messaging.
104 in the order they register, although if an SMI unregisters and then
105 another one registers, all bets are off.
107 -The ipmi_smi.h defines the interface for SMIs, see that for more
109 +The ipmi_smi.h defines the interface for management interfaces, see
110 +that for more details.
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:
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]
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.
129 +The si_type may be either "kcs", "smic", or "bt". If you leave it blank, it
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
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.
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.
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.
146 +When compiled into the kernel, the addresses can be specified on the
147 +kernel command line as:
149 + ipmi_si=[<type>,]<bmc1>:<irq1>,[<type>,]<bmc2>:<irq2>....,[nodefault]
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.
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.
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.
173 the KCS interface sucks.
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:
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]
189 +The addresses are specified in pairs, the first is the adapter ID and the
190 +second is the I2C address on that adapter.
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
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.
199 +Setting smb_dbg_probe to 1 will enable debugging of the probing and
200 +detection process for BMCs on the SMBusses.
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.
210 +When compiled into the kernel, the addresses can be specified on the
211 +kernel command line as:
213 + ipmi_smb=[<adapter1>.]<addr1>[:<debug1>],[<adapter2>.<addr2>[:<debug1>]....
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.
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,
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.
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).
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
244 diff -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
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
258 mainmenu_option next_comment
259 diff -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
266 + * The state-machine driver for an IPMI Block Transfer driver
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
271 + * modified by: Jordan Hargrave <jordan_hargrave@dell.com>
273 + * Corey Minyard's driver for the KSC interface has the following
274 + * copyright notice:
275 + * Copyright 2002 MontaVista Software Inc.
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
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.
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.
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.
305 +/* #define BT_DEBUG */
307 +#include <linux/kernel.h>
308 +#include <asm/string.h>
309 +#include "ipmi_si_sm.h"
311 +#define IPMI_BT_VERSION "v28"
314 +static void dump(const void *b, int len)
316 + const uint8_t *buf = (const uint8_t *)b;
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]);
325 + for(j=0; j<16; j++) {
326 + c = (i+j < len ? buf[i+j] : '.');
327 + printk("%c", (c >= ' ' && c <= 'z') ? c : '.');
332 +#define bt_printk printk
334 +#define bt_printk(x...) do { } while(0)
337 +/*===========================================================================
339 + * IPMI Block Transfer interface method
341 + *===========================================================================*/
343 +#define BIT(n) (1L << (n))
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)
355 +# define BT_RX_READY (BT_BMC2HOST_ATN)
356 +# define BT_TX_READY (BT_BMC_BUSY|BT_HOST2BMC_ATN)
358 +#define BT_BUFFER_REG 1
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)
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 */
371 +#define BT_WRITE_START 1
373 +#define BT_WRITE_END 3
375 +#define BT_READ_START 4
377 +#define BT_READ_END 6
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)
386 +/* --== Block Transfer XMIT/RECV structure ==-- */
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];
404 + /* --== read/write state ==-- */
408 + /* --== I/O handler */
409 + struct si_sm_io *io;
412 +static void bt_print_status(int v, char *pfx)
414 + if (v == 0) return;
417 + printk("%16s bt_ctrl ="
418 + " %.02x w:%d r:%d h2b:%d b2h:%d evt:%d hb:%d bb:%d\n",
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),
425 + bt(v,BT_HOST_BUSY),
426 + bt(v,BT_BMC_BUSY));
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))
440 +/*=================================================================
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)
447 +/*=================================================================
448 + * Reset BT controller to known state
449 + *=================================================================*/
450 +static inline void bt_reset(struct si_sm_data *bt)
454 + v = bt_read_ctrl(bt) & BT_HOST_BUSY;
456 + v | (BT_CLR_WR_PTR | BT_CLR_RD_PTR | BT_BMC2HOST_ATN |
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)
466 + bt->state = BT_IDLE;
470 + bt->wr.ptr = bt->wr.data;
473 + bt->rd.ptr = bt->rd.data;
474 + bt->error_retries = 0;
477 + /* reserve 3 i/o bytes */
481 +/*===================================================
482 + * bt_start_transaction - issue IPMI command
483 + *===================================================*/
484 +static int bt_start_transaction(struct si_sm_data *bt,
485 + unsigned char *data,
488 + bt_printk("bt_start: %d bytes\n", size);
490 + /* --== Validate size and state ==-- */
491 + if (size < 2 || size > BT_MAXREQSZ) {
494 + if (bt->state != BT_IDLE && bt->state != BT_HOSED) {
498 + /* --== assert: data = netfn|cmd|data... ==-- */
499 + bt->error_retries = 0;
500 + bt->state = BT_WRITE_START;
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);
508 + bt_printk("------ request ------\n");
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)
523 + int rdlen = bt->rd.len-1; /* skip sequence byte */
525 + if (length < rdlen) {
529 + memcpy(data, bt->rd.data, rdlen);
532 + bt_printk("------ result ------ : %d %d\n", length, rdlen);
536 + /* --== Minimum length is 3 bytes: nfLn, cCode, status, data[] ==-- */
537 + if ((length >= BT_MINPKTSZ) && (rdlen < BT_MINPKTSZ)) {
541 + if (bt->truncated) {
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)
553 + /* --== Read current status ==-- */
554 + bt->status = bt_read_ctrl(bt);
556 + switch(bt->state) {
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);
563 + if (bt_rx_ready(bt->status)) {
564 + bt_printk("*** READ READY\n");
565 + bt->state = BT_READ_START;
568 + if (bt->status & BT_HOST_BUSY) {
569 + bt_write_ctrl(bt, BT_HOST_BUSY);
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;
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);
587 + else if (bt->wr.pos == 2) {
588 + /* Write sequence number */
589 + bt_write_buffer(bt, bt->wr.seq);
592 + /* Write normal data */
593 + bt_write_buffer(bt, *(bt->wr.ptr++));
595 + if (bt->wr.pos++ == bt->wr.len) {
596 + bt->state = BT_WRITE_END;
598 + return SI_SM_CALL_WITH_DELAY;
601 + bt_print_status(bt->status,"write_end");
602 + bt_write_ctrl(bt, BT_HOST2BMC_ATN);
603 + bt->state = BT_READ_START;
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 */
614 + bt->rd.ptr = bt->rd.data;
615 + bt->state = BT_READ;
617 + return SI_SM_CALL_WITH_DELAY;
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;
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");
637 + *(bt->rd.ptr++) = bt_read_buffer(bt);
639 + if (bt->rd.pos++ == bt->rd.len) {
640 + bt->state = BT_READ_END;
642 + return SI_SM_CALL_WITH_DELAY;
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;
651 + return SI_SM_CALL_WITHOUT_DELAY;
654 +/*=======================================================
655 + * bt_detect - Detect if BT interface is supported
656 + *=======================================================*/
657 +static int bt_detect(struct si_sm_data *bt)
662 + bt->state = BT_IDLE;
664 + /* Check intmask and control register - neither should be 0xFF */
665 + v = bt_read_intmask(bt);
669 + v = bt_read_ctrl(bt);
673 + bt_print_status(v, "detect");
674 + return (v == 0xFF);
677 +/*=======================================================
678 + * bt_cleanup - Cleanup register state
679 + *=======================================================*/
680 +static void bt_cleanup(struct si_sm_data *bt)
682 + bt_printk("bt_cleanup\n");
685 +/*=======================================================
686 + * bt_size - Returns size of device extension
687 + *=======================================================*/
688 +static int bt_size(void)
690 + return sizeof(struct si_sm_data);
693 +struct si_sm_handlers bt_smi_handlers =
695 + .version = IPMI_BT_VERSION,
696 + .init_data = bt_init_data,
697 + .start_transaction = bt_start_transaction,
698 + .get_result = bt_get_result,
700 + .detect = bt_detect,
701 + .cleanup = bt_cleanup,
704 diff -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
708 #include <asm/semaphore.h>
709 #include <linux/init.h>
711 +#define IPMI_DEVINTF_VERSION "v28"
713 struct ipmi_file_private
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;
724 static void file_receive_handler(struct ipmi_recv_msg *msg,
727 static struct ipmi_user_hndl ipmi_hndlrs =
729 - ipmi_recv_hndl : file_receive_handler
730 + .ipmi_recv_hndl = file_receive_handler,
733 static int ipmi_open(struct inode *inode, struct file *file)
735 priv->fasync_queue = NULL;
736 sema_init(&(priv->recv_sem), 1);
738 + /* Use the low-level defaults. */
739 + priv->default_retries = -1;
740 + priv->default_retry_time_ms = 0;
749 +static int handle_send_req(ipmi_user_t user,
750 + struct ipmi_req *req,
752 + unsigned int retry_time_ms)
755 + struct ipmi_addr addr;
756 + unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
758 + if (req->addr_len > sizeof(struct ipmi_addr))
761 + if (copy_from_user(&addr, req->addr, req->addr_len))
764 + rv = ipmi_validate_addr(&addr, req->addr_len);
768 + if (req->msg.data != NULL) {
769 + if (req->msg.data_len > IPMI_MAX_MSG_LENGTH)
772 + if (copy_from_user(&msgdata,
774 + req->msg.data_len))
777 + req->msg.data_len = 0;
779 + req->msg.data = msgdata;
781 + return ipmi_request_settime(user,
790 static int ipmi_ioctl(struct inode *inode,
793 @@ -170,54 +219,33 @@
795 case IPMICTL_SEND_COMMAND:
797 - struct ipmi_req req;
798 - struct ipmi_addr addr;
799 - unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
800 + struct ipmi_req req;
802 if (copy_from_user(&req, (void *) data, sizeof(req))) {
807 - if (req.addr_len > sizeof(struct ipmi_addr))
812 + rv = handle_send_req(priv->user,
814 + priv->default_retries,
815 + priv->default_retry_time_ms);
819 - if (copy_from_user(&addr, req.addr, req.addr_len)) {
820 + case IPMICTL_SEND_COMMAND_SETTIME:
822 + struct ipmi_req_settime req;
824 + if (copy_from_user(&req, (void *) data, sizeof(req))) {
829 - rv = ipmi_validate_addr(&addr, req.addr_len);
833 - if (req.msg.data != NULL) {
834 - if (req.msg.data_len > IPMI_MAX_MSG_LENGTH) {
839 - if (copy_from_user(&msgdata,
847 - req.msg.data_len = 0;
850 - req.msg.data = msgdata;
852 - rv = ipmi_request(priv->user,
857 + rv = handle_send_req(priv->user,
860 + req.retry_time_ms);
868 + case IPMICTL_SET_TIMING_PARMS_CMD:
870 + struct ipmi_timing_parms parms;
872 + if (copy_from_user(&parms, (void *) data, sizeof(parms))) {
877 + priv->default_retries = parms.retries;
878 + priv->default_retry_time_ms = parms.retry_time_ms;
883 + case IPMICTL_GET_TIMING_PARMS_CMD:
885 + struct ipmi_timing_parms parms;
887 + parms.retries = priv->default_retries;
888 + parms.retry_time_ms = priv->default_retry_time_ms;
890 + if (copy_to_user((void *) data, &parms, sizeof(parms))) {
901 @@ -424,12 +481,12 @@
904 static struct file_operations ipmi_fops = {
905 - owner: THIS_MODULE,
908 - release: ipmi_release,
909 - fasync: ipmi_fasync,
911 + .owner = THIS_MODULE,
912 + .ioctl = ipmi_ioctl,
914 + .release = ipmi_release,
915 + .fasync = ipmi_fasync,
919 #define DEVICE_NAME "ipmidev"
922 static struct ipmi_smi_watcher smi_watcher =
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,
931 static __init int init_ipmi_devintf(void)
936 + printk(KERN_INFO "ipmi device interface version "
937 + IPMI_DEVINTF_VERSION "\n");
939 rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
941 printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
946 - printk(KERN_INFO "ipmi: device interface at char major %d\n",
951 module_init(init_ipmi_devintf);
952 diff -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
956 #include <linux/interrupt.h>
957 #include <linux/ipmi_smi.h>
959 -#include "ipmi_kcs_sm.h"
960 +#include "ipmi_si_sm.h"
961 #include <linux/init.h>
963 /* Measure times between events in the driver. */
965 /* This forces a dependency to the config file for this option. */
968 +extern struct si_sm_handlers kcs_smi_handlers;
970 enum kcs_intf_state {
977 - struct kcs_data *kcs_sm;
978 + struct si_sm_data *kcs_sm;
981 struct list_head xmit_msgs;
984 int run_to_completion;
986 + struct si_sm_io io;
988 /* The I/O port of a KCS interface. */
992 /* zero if no irq; */
995 deliver_recv_msg(kcs_info, msg);
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)
1002 struct list_head *entry = NULL;
1006 kcs_info->curr_msg = NULL;
1012 @@ -197,14 +201,15 @@
1013 do_gettimeofday(&t);
1014 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
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(
1021 + kcs_info->curr_msg->data,
1022 + kcs_info->curr_msg->data_size);
1024 return_hosed_msg(kcs_info);
1027 - rv = KCS_CALL_WITHOUT_DELAY;
1028 + rv = SI_SM_CALL_WITHOUT_DELAY;
1030 spin_unlock(&(kcs_info->msg_lock));
1033 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
1034 msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
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;
1042 msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
1043 msg[2] = WDT_PRE_TIMEOUT_INT;
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;
1050 @@ -280,9 +285,10 @@
1051 kcs_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
1052 kcs_info->curr_msg->data_size = 2;
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(
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;
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(
1073 + kcs_info->curr_msg->data,
1074 + kcs_info->curr_msg->data_size);
1075 kcs_info->kcs_state = KCS_GETTING_EVENTS;
1077 kcs_info->kcs_state = KCS_NORMAL;
1078 @@ -322,9 +329,10 @@
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(
1087 + kcs_info->curr_msg->rsp,
1088 + IPMI_MAX_MSG_LENGTH);
1090 /* Do this here becase deliver_recv_msg() releases the
1091 lock, and a new message can be put in during the
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);
1099 /* Error fetching flags, just give up for
1102 unsigned char msg[3];
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);
1108 /* Error clearing flags */
1111 case KCS_GETTING_EVENTS:
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);
1121 /* Do this here becase deliver_recv_msg() releases the
1122 lock, and a new message can be put in during the
1124 case KCS_GETTING_MESSAGES:
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);
1134 /* Do this here becase deliver_recv_msg() releases the
1135 lock, and a new message can be put in during the
1137 unsigned char msg[4];
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);
1144 "ipmi_kcs: Could not enable interrupts"
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;
1156 unsigned char msg[4];
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);
1163 "ipmi_kcs: Could not enable interrupts"
1164 @@ -466,9 +475,10 @@
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,
1172 - enum kcs_result kcs_result;
1173 + enum si_sm_result kcs_result;
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);
1184 - while (kcs_result == KCS_CALL_WITHOUT_DELAY)
1185 + while (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
1187 - kcs_result = kcs_event(kcs_info->kcs_sm, 0);
1188 + kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
1191 - if (kcs_result == KCS_TRANSACTION_COMPLETE)
1192 + if (kcs_result == SI_SM_TRANSACTION_COMPLETE)
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);
1198 - else if (kcs_result == KCS_SM_HOSED)
1199 + else if (kcs_result == SI_SM_HOSED)
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);
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;
1212 /* We prefer handling attn over new messages. */
1213 - if (kcs_result == KCS_ATTN)
1214 + if (kcs_result == SI_SM_ATTN)
1216 unsigned char msg[2];
1218 @@ -514,19 +524,19 @@
1219 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
1220 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
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;
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)
1237 - if ((kcs_result == KCS_SM_IDLE)
1238 + if ((kcs_result == SI_SM_IDLE)
1239 && (atomic_read(&kcs_info->req_events)))
1241 /* We are idle and the upper layer requested that I fetch
1243 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
1244 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
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;
1251 @@ -549,11 +559,11 @@
1252 struct ipmi_smi_msg *msg,
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;
1266 spin_lock_irqsave(&(kcs_info->msg_lock), flags);
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 @@
1278 static void set_run_to_completion(void *send_info, int i_run_to_completion)
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;
1287 spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
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 @@
1299 static void kcs_timeout(unsigned long data)
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;
1316 if (kcs_info->stop_operation) {
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) {
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;
1334 kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
1335 @@ -776,12 +786,12 @@
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)
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;
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 @@
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);
1360 - kcs_result = kcs_event(data, 0);
1361 + kcs_result = kcs_smi_handlers.event(data, 0);
1364 - if (kcs_result == KCS_CALL_WITH_DELAY) {
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);
1372 - else if (kcs_result == KCS_CALL_WITHOUT_DELAY)
1373 + else if (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
1375 - kcs_result = kcs_event(data, 0);
1376 + kcs_result = kcs_smi_handlers.event(data, 0);
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. */
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);
1392 /* That's odd, it should be longer. */
1394 @@ -860,6 +872,36 @@
1395 MODULE_PARM(kcs_irqs, "1-4i");
1396 MODULE_PARM(kcs_ports, "1-4i");
1398 +static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
1400 + struct kcs_info *info = io->info;
1402 + return inb(info->port+offset);
1405 +static void port_outb(struct si_sm_io *io, unsigned int offset,
1408 + struct kcs_info *info = io->info;
1410 + outb(b, info->port+offset);
1413 +static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
1415 + struct kcs_info *info = io->info;
1417 + return readb(info->addr+offset);
1420 +static void mem_outb(struct si_sm_io *io, unsigned int offset,
1423 + struct kcs_info *info = io->info;
1425 + writeb(b, info->addr+offset);
1428 /* Returns 0 if initialized, or negative on an error. */
1429 static int init_one_kcs(int kcs_port,
1435 + new_kcs->io.outputb = port_outb;
1436 + new_kcs->io.inputb = port_inb;
1437 + new_kcs->io.info = new_kcs;
1439 if (request_mem_region(kcs_physaddr, 2, DEVICE_NAME) == NULL) {
1441 @@ -917,15 +962,18 @@
1445 + new_kcs->io.outputb = mem_outb;
1446 + new_kcs->io.inputb = mem_inb;
1447 + new_kcs->io.info = new_kcs;
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");
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));
1462 @@ -1027,11 +1075,7 @@
1464 #ifdef CONFIG_ACPI_INTERPRETER
1466 -/* Retrieve the base physical address from ACPI tables. Originally
1467 - from Hewlett-Packard simple bmc.c, a GPL KCS driver. */
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 @@
1477 s8 CreatorRevision[4];
1478 - s16 InterfaceType;
1479 + u8 InterfaceType[2];
1480 s16 SpecificationRevision;
1483 + * Bit 0 - SCI interrupt supported
1484 + * Bit 1 - I/O APIC/SAPIC
1488 + /* If bit 0 of InterruptType is set, then this is the SCI
1489 + interrupt in the GPEx_STS register. */
1493 - u64 GlobalSystemInterrupt;
1494 - u8 BaseAddress[12];
1496 + /* If bit 1 of InterruptType is set, then this is the I/O
1497 + APIC/SAPIC interrupt. */
1498 + u32 GlobalSystemInterrupt;
1500 + /* The actual register address. */
1501 + struct acpi_generic_address addr;
1504 -} __attribute__ ((packed));
1506 -static unsigned long acpi_find_bmc(void)
1507 + s8 spmi_id[1]; /* A '\0' terminated array starts here. */
1510 +static int acpi_find_bmc(unsigned long *physaddr, int *port)
1513 - struct acpi_table_header *spmi;
1514 - static unsigned long io_base = 0;
1518 + struct SPMITable *spmi;
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)
1527 + if (spmi->InterfaceType[0] != 1)
1531 + if (spmi->InterfaceType[1] != 1)
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);
1546 + goto not_found; /* Not an address type we recognise. */
1548 - if (status != AE_OK) {
1549 - printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n");
1554 - memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress,
1563 @@ -1087,6 +1163,7 @@
1565 #ifdef CONFIG_ACPI_INTERPRETER
1566 unsigned long physaddr = 0;
1571 @@ -1114,26 +1191,25 @@
1572 /* Only try the defaults if enabled and resources are available
1573 (because they weren't already specified above). */
1575 - if (kcs_trydefaults) {
1576 + if (kcs_trydefaults && (pos == 0)) {
1578 #ifdef CONFIG_ACPI_INTERPRETER
1579 - if ((physaddr = acpi_find_bmc())) {
1580 - if (!check_mem_region(physaddr, 2)) {
1581 - rv = init_one_kcs(0,
1584 - &(kcs_infos[pos]));
1588 + if (rv && (acpi_find_bmc(&physaddr, &port) == 0)) {
1589 + rv = init_one_kcs(port,
1592 + &(kcs_infos[pos]));
1597 - if (!check_region(DEFAULT_IO_PORT, 2)) {
1599 rv = init_one_kcs(DEFAULT_IO_PORT,
1609 @@ -1185,8 +1261,10 @@
1610 conditions removing the timer here. Hopefully this will be
1611 long enough to avoid problems with interrupts still
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);
1620 diff -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
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"
1633 -#include "ipmi_kcs_sm.h"
1634 +#define IPMI_KCS_VERSION "v28"
1636 /* Set this if you want a printout of why the state machine was hosed
1637 when it gets hosed. */
1639 #define IPMI_ERR_MSG_TRUNCATED 0xc6
1640 #define IPMI_ERR_UNSPECIFIED 0xff
1645 - enum kcs_states state;
1646 - unsigned int port;
1647 - unsigned char *addr;
1648 - unsigned char write_data[MAX_KCS_WRITE_SIZE];
1651 - int orig_write_count;
1652 - unsigned char read_data[MAX_KCS_READ_SIZE];
1655 + enum kcs_states state;
1656 + struct si_sm_io *io;
1657 + unsigned char write_data[MAX_KCS_WRITE_SIZE];
1660 + int orig_write_count;
1661 + unsigned char read_data[MAX_KCS_READ_SIZE];
1665 unsigned int error_retries;
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)
1674 kcs->state = KCS_IDLE;
1679 kcs->write_count = 0;
1680 kcs->orig_write_count = 0;
1681 @@ -126,40 +126,29 @@
1683 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
1684 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
1687 -/* Remember, init_one_kcs() insured port and addr can't both be set */
1688 + /* Reserve 2 I/O bytes. */
1692 -static inline unsigned char read_status(struct kcs_data *kcs)
1693 +static inline unsigned char read_status(struct si_sm_data *kcs)
1696 - return inb(kcs->port + 1);
1698 - return readb(kcs->addr + 1);
1699 + return kcs->io->inputb(kcs->io, 1);
1702 -static inline unsigned char read_data(struct kcs_data *kcs)
1703 +static inline unsigned char read_data(struct si_sm_data *kcs)
1706 - return inb(kcs->port + 0);
1708 - return readb(kcs->addr + 0);
1709 + return kcs->io->inputb(kcs->io, 0);
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)
1716 - outb(data, kcs->port + 1);
1718 - writeb(data, kcs->addr + 1);
1719 + kcs->io->outputb(kcs->io, 1, data);
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)
1726 - outb(data, kcs->port + 0);
1728 - writeb(data, kcs->addr + 0);
1729 + kcs->io->outputb(kcs->io, 0, data);
1732 /* Control codes. */
1733 @@ -179,14 +168,14 @@
1734 #define GET_STATUS_OBF(status) ((status) & 0x01)
1737 -static inline void write_next_byte(struct kcs_data *kcs)
1738 +static inline void write_next_byte(struct si_sm_data *kcs)
1740 write_data(kcs, kcs->write_data[kcs->write_pos]);
1742 (kcs->write_count)--;
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)
1748 (kcs->error_retries)++;
1749 if (kcs->error_retries > MAX_ERROR_RETRIES) {
1754 -static inline void read_next_byte(struct kcs_data *kcs)
1755 +static inline void read_next_byte(struct si_sm_data *kcs)
1757 if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
1758 /* Throw the data away and mark it truncated. */
1760 write_data(kcs, KCS_READ_BYTE);
1763 -static inline int check_ibf(struct kcs_data *kcs,
1764 - unsigned char status,
1766 +static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
1769 if (GET_STATUS_IBF(status)) {
1770 kcs->ibf_timeout -= time;
1775 -static inline int check_obf(struct kcs_data *kcs,
1776 - unsigned char status,
1778 +static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
1781 if (! GET_STATUS_OBF(status)) {
1782 kcs->obf_timeout -= time;
1783 @@ -245,13 +232,13 @@
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)
1790 if (GET_STATUS_OBF(status))
1794 -static void restart_kcs_transaction(struct kcs_data *kcs)
1795 +static void restart_kcs_transaction(struct si_sm_data *kcs)
1797 kcs->write_count = kcs->orig_write_count;
1800 write_cmd(kcs, KCS_WRITE_START);
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)
1807 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
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)
1817 if (length < kcs->read_pos) {
1818 kcs->read_pos = length;
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)
1826 unsigned char status;
1827 unsigned char state;
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;
1835 /* Just about everything looks at the KCS state, so grab that, too. */
1836 state = GET_STATUS_STATE(status);
1838 clear_obf(kcs, status);
1840 if (GET_STATUS_ATN(status))
1842 + return SI_SM_ATTN;
1844 - return KCS_SM_IDLE;
1845 + return SI_SM_IDLE;
1848 if (state != KCS_IDLE) {
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);
1857 /* We don't implement this exactly like the state
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;
1870 if (! check_obf(kcs, status, time))
1871 - return KCS_CALL_WITH_DELAY;
1872 + return SI_SM_CALL_WITH_DELAY;
1874 clear_obf(kcs, status);
1875 write_data(kcs, KCS_READ_BYTE);
1876 @@ -456,14 +445,14 @@
1879 if (! check_obf(kcs, status, time))
1880 - return KCS_CALL_WITH_DELAY;
1881 + return SI_SM_CALL_WITH_DELAY;
1883 clear_obf(kcs, status);
1884 if (kcs->orig_write_count) {
1885 restart_kcs_transaction(kcs);
1887 kcs->state = KCS_IDLE;
1888 - return KCS_TRANSACTION_COMPLETE;
1889 + return SI_SM_TRANSACTION_COMPLETE;
1893 @@ -472,14 +461,42 @@
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;
1903 - return KCS_CALL_WITHOUT_DELAY;
1904 + return SI_SM_CALL_WITHOUT_DELAY;
1908 +static int kcs_size(void)
1910 - return sizeof(struct kcs_data);
1911 + return sizeof(struct si_sm_data);
1914 +static int kcs_detect(struct si_sm_data *kcs)
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)
1926 +static void kcs_cleanup(struct si_sm_data *kcs)
1930 +struct si_sm_handlers kcs_smi_handlers =
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,
1941 diff -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
1945 #include <linux/ipmi_smi.h>
1946 #include <linux/notifier.h>
1947 #include <linux/init.h>
1948 +#include <linux/proc_fs.h>
1950 +#define IPMI_MSGHANDLER_VERSION "v28"
1952 struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
1953 static int ipmi_init_msghandler(void);
1955 static int initialized = 0;
1957 +static struct proc_dir_entry *proc_ipmi_root = NULL;
1959 #define MAX_EVENTS_IN_QUEUE 25
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
1972 + unsigned int inuse : 1;
1973 + unsigned int broadcast : 1;
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
1980 unsigned char my_lun;
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;
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);
1995 + /* Proc FS stuff. */
1996 + struct proc_dir_entry *proc_dir;
1997 + char proc_dir_name[10];
1999 + spinlock_t counter_lock; /* For making counters atomic. */
2001 + /* Commands we got that were invalid. */
2002 + unsigned int sent_invalid_commands;
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;
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
2019 + unsigned int timed_out_ipmb_commands;
2021 + /* This is like above, but for broadcasts. Broadcasts are
2022 + *not* included in the above count (they are expected to
2024 + unsigned int timed_out_ipmb_broadcasts;
2026 + /* Responses I have sent to the IPMB bus. */
2027 + unsigned int sent_ipmb_responses;
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;
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;
2043 + /* Invalid data in an event. */
2044 + unsigned int invalid_events;
2045 + /* Events that were received with the proper format. */
2046 + unsigned int events;
2052 static void deliver_response(struct ipmi_recv_msg *msg)
2054 - msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
2055 + msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
2058 /* Find the next sequence number not being used and add the given
2060 struct ipmi_recv_msg *recv_msg,
2061 unsigned long timeout,
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);
2078 /* Start the timer for a specific sequence table entry. */
2079 -static int intf_start_seq_timer(ipmi_smi_t intf,
2081 +static int intf_start_seq_timer(ipmi_smi_t intf,
2085 unsigned long flags;
2086 @@ -431,9 +505,50 @@
2088 struct seq_table *ent = &(intf->seq_table[seq]);
2089 ent->timeout = ent->orig_timeout;
2092 + spin_unlock_irqrestore(&(intf->seq_lock), flags);
2097 +/* Got an error for the send message for a specific sequence number. */
2098 +static int intf_err_seq(ipmi_smi_t intf,
2103 + unsigned long flags;
2104 + unsigned char seq;
2105 + unsigned long seqid;
2106 + struct ipmi_recv_msg *msg = NULL;
2109 + GET_SEQ_FROM_MSGID(msgid, seq, seqid);
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))
2117 + struct seq_table *ent = &(intf->seq_table[seq]);
2120 + msg = ent->recv_msg;
2123 spin_unlock_irqrestore(&(intf->seq_lock), flags);
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);
2138 struct ipmi_recv_msg *supplied_recv,
2140 unsigned char source_address,
2141 - unsigned char source_lun)
2142 + unsigned char source_lun,
2144 + unsigned int retry_time_ms)
2147 struct ipmi_smi_msg *smi_msg;
2148 @@ -797,8 +914,11 @@
2151 if (addr->channel > IPMI_NUM_CHANNELS) {
2154 + spin_lock_irqsave(&intf->counter_lock, flags);
2155 + intf->sent_invalid_commands++;
2156 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2161 recv_msg->user = user;
2162 @@ -812,8 +932,12 @@
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);
2174 memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr));
2176 @@ -824,11 +948,17 @@
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);
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);
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))
2204 struct ipmi_ipmb_addr *ipmb_addr;
2205 unsigned char ipmb_seq;
2209 + int broadcast = 0;
2212 + spin_lock_irqsave(&intf->counter_lock, flags);
2213 + intf->sent_invalid_commands++;
2214 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2219 + if (retries < 0) {
2220 + if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
2221 + retries = 0; /* Don't retry broadcasts. */
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
2229 addr->addr_type = IPMI_IPMB_ADDR_TYPE;
2231 - retries = 0; /* Don't retry broadcasts. */
2238 + /* Default to 1 second retries. */
2239 + if (retry_time_ms == 0)
2240 + retry_time_ms = 1000;
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);
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);
2260 @@ -884,6 +1032,9 @@
2261 if (recv_msg->msg.netfn & 0x1) {
2262 /* It's a response, so use the user's sequence
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,
2269 source_address, source_lun);
2270 @@ -892,13 +1043,17 @@
2272 spin_lock_irqsave(&(intf->seq_lock), flags);
2274 + spin_lock(&intf->counter_lock);
2275 + intf->sent_ipmb_commands++;
2276 + spin_unlock(&intf->counter_lock);
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,
2290 @@ -934,16 +1089,19 @@
2293 /* Unknown address type. */
2296 + spin_lock_irqsave(&intf->counter_lock, flags);
2297 + intf->sent_invalid_commands++;
2298 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2306 - for (m=0; m<smi_msg->data_size; m++)
2307 - printk(" %2.2x", smi_msg->data[m]);
2310 + for (m=0; m<smi_msg->data_size; m++)
2311 + printk(" %2.2x", smi_msg->data[m]);
2315 intf->handlers->sender(intf->send_info, smi_msg, priority);
2316 @@ -970,7 +1128,29 @@
2319 user->intf->my_address,
2320 - user->intf->my_lun);
2321 + user->intf->my_lun,
2325 +int ipmi_request_settime(ipmi_user_t user,
2326 + struct ipmi_addr *addr,
2328 + struct ipmi_msg *msg,
2331 + unsigned int retry_time_ms)
2333 + return i_ipmi_request(user,
2340 + user->intf->my_address,
2341 + user->intf->my_lun,
2346 int ipmi_request_supply_msgs(ipmi_user_t user,
2347 @@ -990,7 +1170,8 @@
2350 user->intf->my_address,
2351 - user->intf->my_lun);
2352 + user->intf->my_lun,
2356 int ipmi_request_with_source(ipmi_user_t user,
2357 @@ -1009,7 +1190,124 @@
2366 +static int ipmb_file_read_proc(char *page, char **start, off_t off,
2367 + int count, int *eof, void *data)
2369 + char *out = (char *) page;
2370 + ipmi_smi_t intf = data;
2372 + return sprintf(out, "%x\n", intf->my_address);
2375 +static int version_file_read_proc(char *page, char **start, off_t off,
2376 + int count, int *eof, void *data)
2378 + char *out = (char *) page;
2379 + ipmi_smi_t intf = data;
2381 + return sprintf(out, "%d.%d\n",
2382 + intf->version_major, intf->version_minor);
2385 +static int stat_file_read_proc(char *page, char **start, off_t off,
2386 + int count, int *eof, void *data)
2388 + char *out = (char *) page;
2389 + ipmi_smi_t intf = data;
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",
2428 + return (out - ((char *) page));
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)
2435 + struct proc_dir_entry *file;
2438 + file = create_proc_entry(name, 0, smi->proc_dir);
2443 + file->data = data;
2444 + file->read_proc = read_proc;
2445 + file->write_proc = write_proc;
2446 + file->owner = owner;
2452 +static int add_proc_entries(ipmi_smi_t smi, int num)
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)
2461 + smi->proc_dir->owner = THIS_MODULE;
2465 + rv = ipmi_smi_add_proc_entry(smi, "stats",
2466 + stat_file_read_proc, NULL,
2467 + smi, THIS_MODULE);
2470 + rv = ipmi_smi_add_proc_entry(smi, "ipmb",
2471 + ipmb_file_read_proc, NULL,
2472 + smi, THIS_MODULE);
2475 + rv = ipmi_smi_add_proc_entry(smi, "version",
2476 + version_file_read_proc, NULL,
2477 + smi, THIS_MODULE);
2482 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
2483 @@ -1040,6 +1338,9 @@
2484 new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
2487 + memset(new_intf, 0, sizeof(*new_intf));
2489 + new_intf->proc_dir = NULL;
2493 @@ -1069,6 +1370,8 @@
2494 INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
2495 new_intf->all_cmd_rcvr = NULL;
2497 + spin_lock_init(&(new_intf->counter_lock));
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. */
2507 + rv = add_proc_entries(*intf, i);
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);
2517 + if (try_inc_mod_count(w->owner)) {
2520 + __MOD_DEC_USE_COUNT(w->owner);
2523 up_read(&smi_watchers_sem);
2525 @@ -1104,8 +1414,12 @@
2527 up_read(&interfaces_sem);
2531 + if (new_intf->proc_dir)
2532 + remove_proc_entry(new_intf->proc_dir_name,
2539 @@ -1163,6 +1477,8 @@
2541 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2542 if (ipmi_interfaces[i] == intf) {
2543 + remove_proc_entry(intf->proc_dir_name,
2545 spin_lock_irqsave(&interfaces_lock, flags);
2546 ipmi_interfaces[i] = NULL;
2547 clean_up_interface_data(intf);
2548 @@ -1204,15 +1520,21 @@
2550 struct ipmi_ipmb_addr ipmb_addr;
2551 struct ipmi_recv_msg *recv_msg;
2552 + unsigned long flags;
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);
2564 - if (msg->rsp[2] != 0)
2565 + if (msg->rsp[2] != 0) {
2566 /* An error getting the response, just ignore it. */
2570 ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
2571 ipmb_addr.slave_addr = msg->rsp[6];
2572 @@ -1231,6 +1553,9 @@
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);
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);
2592 @@ -1252,18 +1580,23 @@
2593 static int handle_get_msg_cmd(ipmi_smi_t intf,
2594 struct ipmi_smi_msg *msg)
2596 - struct list_head *entry;
2597 + struct list_head *entry;
2598 struct cmd_rcvr *rcvr;
2600 - unsigned char netfn;
2601 - unsigned char cmd;
2602 - ipmi_user_t user = NULL;
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;
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);
2620 if (msg->rsp[2] != 0) {
2621 /* An error getting the response, just ignore it. */
2622 @@ -1291,6 +1624,10 @@
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);
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. */
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);
2641 recv_msg = ipmi_alloc_recv_msg();
2643 /* We couldn't allocate memory for the
2644 @@ -1374,6 +1715,9 @@
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);
2654 @@ -1386,6 +1730,10 @@
2656 spin_lock_irqsave(&(intf->events_lock), flags);
2658 + spin_lock(&intf->counter_lock);
2660 + spin_unlock(&intf->counter_lock);
2662 /* Allocate and fill in one message for every user that is getting
2664 list_for_each(entry, &(intf->users)) {
2665 @@ -1459,6 +1807,7 @@
2666 struct ipmi_recv_msg *recv_msg;
2668 struct list_head *entry;
2669 + unsigned long flags;
2671 recv_msg = (struct ipmi_recv_msg *) msg->user_data;
2673 @@ -1474,11 +1823,20 @@
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);
2686 struct ipmi_system_interface_addr *smi_addr;
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)
2701 if (msg->rsp_size < 2) {
2702 /* Message is too small to be correct. */
2703 @@ -1551,10 +1909,30 @@
2705 read_lock(&(intf->users_lock));
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
2713 - intf_start_seq_timer(intf, msg->msgid);
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))
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]);
2729 + /* The message was sent, start the timer. */
2730 + intf_start_seq_timer(intf, msg->msgid);
2733 ipmi_free_smi_msg(msg);
2736 @@ -1699,6 +2077,12 @@
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++;
2744 + intf->timed_out_ipmb_commands++;
2745 + spin_unlock(&intf->counter_lock);
2747 /* More retries, send again. */
2749 @@ -1708,6 +2092,9 @@
2750 ent->retries_left--;
2751 send_from_recv_msg(intf, ent->recv_msg, NULL,
2753 + spin_lock(&intf->counter_lock);
2754 + intf->retransmitted_ipmb_commands++;
2755 + spin_unlock(&intf->counter_lock);
2758 spin_unlock_irqrestore(&(intf->seq_lock), flags);
2759 @@ -1740,13 +2127,16 @@
2761 static struct timer_list ipmi_timer;
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))
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
2771 +/* How many jiffies does it take to get to the timeout time. */
2772 +#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
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))
2780 static volatile int stop_operation = 0;
2781 @@ -1822,18 +2212,48 @@
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)
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))
2793 + /* A get event receiver command, save it. */
2794 + intf->event_receiver = msg->rsp[3];
2795 + intf->event_receiver_lun = msg->rsp[4] & 0x3;
2799 +static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
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))
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;
2813 +static void send_panic_events(char *str)
2815 struct ipmi_msg msg;
2817 - unsigned char data[8];
2818 + unsigned char data[16];
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;
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;
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. */
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
2845 + /* Put a few breadcrums in. Hopefully later we can add more things
2846 + to make the panic events more useful. */
2853 smi_msg.done = dummy_smi_done_handler;
2854 recv_msg.done = dummy_recv_done_handler;
2855 @@ -1862,18 +2283,147 @@
2859 + /* Send the event announcing the panic. */
2860 intf->handlers->set_run_to_completion(intf->send_info, 1);
2861 i_ipmi_request(NULL,
2863 - (struct ipmi_addr *) &addr,
2873 + 0, 1); /* Don't retry, and don't wait. */
2876 +#ifdef CONFIG_IPMI_PANIC_STRING
2877 + /* On every interface, dump a bunch of OEM event holding the
2882 + for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2884 + struct ipmi_ipmb_addr *ipmb;
2887 + intf = ipmi_interfaces[i];
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
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;
2902 + /* Request the device info from the local MC. */
2903 + msg.netfn = IPMI_NETFN_APP_REQUEST;
2904 + msg.cmd = IPMI_GET_DEVICE_ID_CMD;
2907 + intf->null_user_handler = device_id_fetcher;
2908 + i_ipmi_request(NULL,
2918 + 0, 1); /* Don't retry, and don't wait. */
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;
2926 + intf->null_user_handler = event_receiver_fetcher;
2927 + i_ipmi_request(NULL,
2937 + 0, 1); /* no retry, and no wait. */
2939 + intf->null_user_handler = NULL;
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))
2948 + /* The event receiver is valid, send an IPMB
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
2959 + si = (struct ipmi_system_interface_addr *) &addr;
2960 + si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2961 + si->channel = IPMI_BMC_CHANNEL;
2964 + continue; /* No where to send the event. */
2967 + msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */
2968 + msg.cmd = IPMI_ADD_SEL_ENTRY_CMD;
2970 + msg.data_len = 16;
2974 + int size = strlen(p);
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);
2988 + i_ipmi_request(NULL,
2998 + 0, 1); /* no retry, and no wait. */
3001 +#endif /* CONFIG_IPMI_PANIC_STRING */
3003 #endif /* CONFIG_IPMI_PANIC_EVENT */
3005 @@ -1900,7 +2450,7 @@
3008 #ifdef CONFIG_IPMI_PANIC_EVENT
3009 - send_panic_events();
3010 + send_panic_events(ptr);
3014 @@ -1912,7 +2462,6 @@
3015 200 /* priority: INT_MAX >= x >= 0 */
3019 static __init int ipmi_init_msghandler(void)
3022 @@ -1920,10 +2469,21 @@
3026 + printk(KERN_INFO "ipmi message handler version "
3027 + IPMI_MSGHANDLER_VERSION "\n");
3029 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
3030 ipmi_interfaces[i] = NULL;
3033 + proc_ipmi_root = proc_mkdir("ipmi", 0);
3034 + if (!proc_ipmi_root) {
3035 + printk("Unable to create IPMI proc dir\n");
3039 + proc_ipmi_root->owner = THIS_MODULE;
3041 init_timer(&ipmi_timer);
3042 ipmi_timer.data = 0;
3043 ipmi_timer.function = ipmi_timeout;
3044 @@ -1934,8 +2494,6 @@
3048 - printk(KERN_INFO "ipmi: message handler initialized\n");
3053 @@ -1955,6 +2513,7 @@
3054 problems with race conditions removing the timer here. */
3056 while (!timer_stopped) {
3057 + set_current_state(TASK_UNINTERRUPTIBLE);
3058 schedule_timeout(1);
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);
3074 diff -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
3081 + * The interface to the IPMI driver for the system interfaces (KCS, SMIC,
3082 + * BT in the future).
3084 + * Author: MontaVista Software, Inc.
3085 + * Corey Minyard <minyard@mvista.com>
3086 + * source@mvista.com
3088 + * Copyright 2002 MontaVista Software Inc.
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.
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.
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.
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.
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
3137 +static inline void add_usec_to_timer(struct timer_list *t, long v)
3139 + t->sub_expires += nsec_to_arch_cycle(v * 1000);
3140 + while (t->sub_expires >= arch_cycles_per_jiffy)
3143 + t->sub_expires -= arch_cycles_per_jiffy;
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>
3153 +#define IPMI_SI_VERSION "v28"
3155 +/* Measure times between events in the driver. */
3156 +#undef DEBUG_TIMING
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
3165 +enum si_intf_state {
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. */
3178 + SI_KCS, SI_SMIC, SI_BT
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;
3194 + /* Used to handle the various types of I/O that can occur with
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;
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;
3211 + /* If set to true, this will request events the next time the
3212 + state machine is idle. */
3213 + atomic_t req_events;
3215 + /* If true, run the state machine to completion on every send
3216 + call. Generally used after a panic to make sure stuff goes
3218 + int run_to_completion;
3220 + /* The I/O port of an SI interface. */
3223 + /* zero if no irq; */
3226 + /* The timer for this si. */
3227 + struct timer_list si_timer;
3229 + /* The time (in jiffies) the last timeout occurred at. */
3230 + unsigned long last_timeout_jiffies;
3232 + /* Used to gracefully stop the timer without race conditions. */
3233 + volatile int stop_operation;
3234 + volatile int timer_stopped;
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
3240 + int interrupt_disabled;
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;
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;
3264 +static void si_restart_short_timer(struct smi_info *smi_info);
3266 +static void deliver_recv_msg(struct smi_info *smi_info,
3267 + struct ipmi_smi_msg *msg)
3269 + /* Deliver the message to the upper layer with the lock
3271 + spin_unlock(&(smi_info->si_lock));
3272 + ipmi_smi_msg_received(smi_info->intf, msg);
3273 + spin_lock(&(smi_info->si_lock));
3276 +static void return_hosed_msg(struct smi_info *smi_info)
3278 + struct ipmi_smi_msg *msg = smi_info->curr_msg;
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;
3286 + smi_info->curr_msg = NULL;
3287 + deliver_recv_msg(smi_info, msg);
3290 +static enum si_sm_result start_next_msg(struct smi_info *smi_info)
3293 + struct list_head *entry = NULL;
3294 +#ifdef DEBUG_TIMING
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));
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;
3310 + smi_info->curr_msg = NULL;
3316 + smi_info->curr_msg = list_entry(entry,
3317 + struct ipmi_smi_msg,
3319 +#ifdef DEBUG_TIMING
3320 + do_gettimeofday(&t);
3321 + printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3323 + err = smi_info->handlers->start_transaction(
3325 + smi_info->curr_msg->data,
3326 + smi_info->curr_msg->data_size);
3328 + return_hosed_msg(smi_info);
3331 + rv = SI_SM_CALL_WITHOUT_DELAY;
3333 + spin_unlock(&(smi_info->msg_lock));
3338 +static void start_enable_irq(struct smi_info *smi_info)
3340 + unsigned char msg[2];
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;
3347 + smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
3348 + smi_info->si_state = SI_ENABLE_INTERRUPTS1;
3351 +static void start_clear_flags(struct smi_info *smi_info)
3353 + unsigned char msg[3];
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;
3360 + smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
3361 + smi_info->si_state = SI_CLEARING_FLAGS;
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)
3370 + if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
3371 + disable_irq_nosync(smi_info->irq);
3372 + smi_info->interrupt_disabled = 1;
3376 +static inline void enable_si_irq(struct smi_info *smi_info)
3378 + if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
3379 + enable_irq(smi_info->irq);
3380 + smi_info->interrupt_disabled = 0;
3384 +static void handle_flags(struct smi_info *smi_info)
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);
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;
3405 + enable_si_irq(smi_info);
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;
3411 + smi_info->handlers->start_transaction(
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;
3424 + enable_si_irq(smi_info);
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;
3430 + smi_info->handlers->start_transaction(
3432 + smi_info->curr_msg->data,
3433 + smi_info->curr_msg->data_size);
3434 + smi_info->si_state = SI_GETTING_EVENTS;
3436 + smi_info->si_state = SI_NORMAL;
3440 +static void handle_transaction_done(struct smi_info *smi_info)
3442 + struct ipmi_smi_msg *msg;
3443 +#ifdef DEBUG_TIMING
3446 + do_gettimeofday(&t);
3447 + printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3449 + switch (smi_info->si_state) {
3451 + if (!smi_info->curr_msg)
3454 + smi_info->curr_msg->rsp_size
3455 + = smi_info->handlers->get_result(
3457 + smi_info->curr_msg->rsp,
3458 + IPMI_MAX_MSG_LENGTH);
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);
3468 + case SI_GETTING_FLAGS:
3470 + unsigned char msg[4];
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
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;
3484 + smi_info->msg_flags = msg[3];
3485 + handle_flags(smi_info);
3490 + case SI_CLEARING_FLAGS:
3491 + case SI_CLEARING_FLAGS_THEN_SET_IRQ:
3493 + unsigned char msg[3];
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",
3503 + if (smi_info->si_state == SI_CLEARING_FLAGS_THEN_SET_IRQ)
3504 + start_enable_irq(smi_info);
3506 + smi_info->si_state = SI_NORMAL;
3510 + case SI_GETTING_EVENTS:
3512 + smi_info->curr_msg->rsp_size
3513 + = smi_info->handlers->get_result(
3515 + smi_info->curr_msg->rsp,
3516 + IPMI_MAX_MSG_LENGTH);
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. */
3527 + /* Take off the event flag. */
3528 + smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
3530 + spin_lock(&smi_info->count_lock);
3531 + smi_info->events++;
3532 + spin_unlock(&smi_info->count_lock);
3534 + deliver_recv_msg(smi_info, msg);
3536 + handle_flags(smi_info);
3540 + case SI_GETTING_MESSAGES:
3542 + smi_info->curr_msg->rsp_size
3543 + = smi_info->handlers->get_result(
3545 + smi_info->curr_msg->rsp,
3546 + IPMI_MAX_MSG_LENGTH);
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. */
3557 + /* Take off the msg flag. */
3558 + smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
3560 + spin_lock(&smi_info->count_lock);
3561 + smi_info->incoming_messages++;
3562 + spin_unlock(&smi_info->count_lock);
3564 + deliver_recv_msg(smi_info, msg);
3566 + handle_flags(smi_info);
3570 + case SI_ENABLE_INTERRUPTS1:
3572 + unsigned char msg[4];
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;
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;
3592 + case SI_ENABLE_INTERRUPTS2:
3594 + unsigned char msg[4];
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");
3603 + smi_info->si_state = SI_NORMAL;
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,
3614 + enum si_sm_result si_sm_result;
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);
3625 + while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY)
3627 + si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3630 + if (si_sm_result == SI_SM_TRANSACTION_COMPLETE)
3632 + spin_lock(&smi_info->count_lock);
3633 + smi_info->complete_transactions++;
3634 + spin_unlock(&smi_info->count_lock);
3636 + handle_transaction_done(smi_info);
3637 + si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3639 + else if (si_sm_result == SI_SM_HOSED)
3641 + spin_lock(&smi_info->count_lock);
3642 + smi_info->hosed_count++;
3643 + spin_unlock(&smi_info->count_lock);
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);
3651 + si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3652 + smi_info->si_state = SI_NORMAL;
3655 + /* We prefer handling attn over new messages. */
3656 + if (si_sm_result == SI_SM_ATTN)
3658 + unsigned char msg[2];
3660 + spin_lock(&smi_info->count_lock);
3661 + smi_info->attentions++;
3662 + spin_unlock(&smi_info->count_lock);
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
3669 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3670 + msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3672 + smi_info->handlers->start_transaction(
3673 + smi_info->si_sm, msg, 2);
3674 + smi_info->si_state = SI_GETTING_FLAGS;
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);
3684 + si_sm_result = start_next_msg(smi_info);
3685 + if (si_sm_result != SI_SM_IDLE)
3689 + if ((si_sm_result == SI_SM_IDLE)
3690 + && (atomic_read(&smi_info->req_events)))
3692 + /* We are idle and the upper layer requested that I fetch
3693 + events, so do so. */
3694 + unsigned char msg[2];
3696 + spin_lock(&smi_info->count_lock);
3697 + smi_info->flag_fetches++;
3698 + spin_unlock(&smi_info->count_lock);
3700 + atomic_set(&smi_info->req_events, 0);
3701 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3702 + msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3704 + smi_info->handlers->start_transaction(
3705 + smi_info->si_sm, msg, 2);
3706 + smi_info->si_state = SI_GETTING_FLAGS;
3710 + return si_sm_result;
3713 +static void sender(void *send_info,
3714 + struct ipmi_smi_msg *msg,
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
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);
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));
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);
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);
3747 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3750 + if (priority > 0) {
3751 + list_add_tail(&(msg->link), &(smi_info->hp_xmit_msgs));
3753 + list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
3756 + spin_unlock_irqrestore(&(smi_info->msg_lock), flags);
3758 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3759 + if ((smi_info->si_state == SI_NORMAL)
3760 + && (smi_info->curr_msg == NULL))
3762 + start_next_msg(smi_info);
3763 + si_restart_short_timer(smi_info);
3765 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3768 +static void set_run_to_completion(void *send_info, int i_run_to_completion)
3770 + struct smi_info *smi_info = (struct smi_info *) send_info;
3771 + enum si_sm_result result;
3772 + unsigned long flags;
3774 + spin_lock_irqsave(&(smi_info->si_lock), flags);
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);
3786 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3789 +static void request_events(void *send_info)
3791 + struct smi_info *smi_info = (struct smi_info *) send_info;
3793 + atomic_set(&smi_info->req_events, 1);
3796 +static int new_user(void *send_info)
3798 + if (!try_inc_mod_count(THIS_MODULE))
3803 +static void user_left(void *send_info)
3805 + MOD_DEC_USE_COUNT;
3808 +static int initialized = 0;
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)
3813 +#if defined(CONFIG_HIGH_RES_TIMERS)
3814 + unsigned long flags;
3815 + unsigned long jiffies_now;
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. */
3822 + /* We already have irqsave on, so no need for it
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);
3830 + add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
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);
3840 +static void smi_timeout(unsigned long data)
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
3851 + if (smi_info->stop_operation) {
3852 + smi_info->timer_stopped = 1;
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);
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);
3866 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3868 + smi_info->last_timeout_jiffies = jiffies_now;
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;
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);
3893 + smi_info->si_timer.expires = jiffies + 1;
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;
3906 + add_timer(&(smi_info->si_timer));
3909 +static void si_irq_handler(int irq, void *data, struct pt_regs *regs)
3911 + struct smi_info *smi_info = (struct smi_info *) data;
3912 + unsigned long flags;
3913 +#ifdef DEBUG_TIMING
3917 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3919 + spin_lock(&smi_info->count_lock);
3920 + smi_info->interrupts++;
3921 + spin_unlock(&smi_info->count_lock);
3923 + if (smi_info->stop_operation)
3926 +#ifdef DEBUG_TIMING
3927 + do_gettimeofday(&t);
3928 + printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3930 + smi_event_handler(smi_info, 0);
3932 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3935 +static struct ipmi_smi_handlers handlers =
3938 + request_events: request_events,
3939 + new_user: new_user,
3940 + user_left: user_left,
3941 + set_run_to_completion: set_run_to_completion
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 */
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 };
3952 +#define DEVICE_NAME "ipmi_si"
3954 +#define DEFAULT_KCS_IO_PORT 0xca2
3955 +#define DEFAULT_SMIC_IO_PORT 0xca9
3956 +#define DEFAULT_BT_IO_PORT 0xe4
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 };
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");
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)
3979 + for (i = 0; i < SI_MAX_PARMS; ++i) {
3980 + /* Don't check our address. */
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]))
3998 +static int std_irq_setup(struct smi_info *info)
4005 + rv = request_irq(info->irq,
4011 + printk(KERN_WARNING
4012 + "ipmi_smi: %s unable to claim interrupt %d,"
4013 + " running polled\n",
4014 + DEVICE_NAME, info->irq);
4017 + printk(" Using irq %d\n", info->irq);
4023 +static void std_irq_cleanup(struct smi_info *info)
4028 + free_irq(info->irq, info);
4031 +static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
4033 + unsigned int *addr = io->info;
4035 + return inb((*addr)+offset);
4038 +static void port_outb(struct si_sm_io *io, unsigned int offset,
4041 + unsigned int *addr = io->info;
4043 + outb(b, (*addr)+offset);
4046 +static int port_setup(struct smi_info *info)
4048 + unsigned int *addr = info->io.info;
4050 + if (!addr || (!*addr))
4053 + if (request_region(*addr, info->io_size, DEVICE_NAME) == NULL)
4058 +static void port_cleanup(struct smi_info *info)
4060 + unsigned int *addr = info->io.info;
4062 + if (addr && (*addr))
4063 + release_region (*addr, info->io_size);
4067 +static int try_init_port(int intf_num, struct smi_info **new_info)
4069 + struct smi_info *info;
4071 + if (!si_ports[intf_num])
4074 + if (!is_new_interface(intf_num, IPMI_IO_ADDR_SPACE,
4075 + si_ports[intf_num]))
4078 + info = kmalloc(sizeof(*info), GFP_KERNEL);
4080 + printk("ipmi_smi: Could not allocate SMI data\n");
4083 + memset(info, 0, sizeof(*info));
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]);
4091 + info->irq_setup = NULL;
4094 + printk("ipmi_smi: Trying state machine at I/O address 0x%x\n",
4095 + si_ports[intf_num]);
4099 +static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
4101 + return readb((io->addr)+offset);
4104 +static void mem_outb(struct si_sm_io *io, unsigned int offset,
4107 + writeb(b, (io->addr)+offset);
4110 +static int mem_setup(struct smi_info *info)
4112 + unsigned long addr = (unsigned long) info->io.info;
4117 + if (request_mem_region(addr, info->io_size, DEVICE_NAME) == NULL)
4119 + info->io.addr = ioremap(addr, info->io_size);
4120 + if (info->io.addr == NULL) {
4121 + release_mem_region(addr, info->io_size);
4127 +static void mem_cleanup(struct smi_info *info)
4129 + unsigned long addr = (unsigned long) info->io.info;
4131 + if (info->io.addr) {
4132 + iounmap(info->io.addr);
4133 + release_mem_region(addr, info->io_size);
4138 +static int try_init_mem(int intf_num, struct smi_info **new_info)
4140 + struct smi_info *info;
4142 + if (!si_addrs[intf_num])
4145 + if (!is_new_interface(intf_num, IPMI_MEM_ADDR_SPACE,
4146 + si_addrs[intf_num]))
4149 + info = kmalloc(sizeof(*info), GFP_KERNEL);
4151 + printk("ipmi_smi: Could not allocate SMI data\n");
4154 + memset(info, 0, sizeof(*info));
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];
4162 + info->irq_setup = NULL;
4165 + printk("ipmi_smi: Trying state machine at memory address 0x%lx\n",
4166 + si_addrs[intf_num]);
4170 +#ifdef CONFIG_ACPI_INTERPRETER
4172 +#include <linux/acpi.h>
4173 +#include <acpi/acpi.h>
4174 +#include <acpi/actypes.h>
4175 +#include <acpi/actbl.h>
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
4180 +static int acpi_failure = 0;
4182 +/* For GPE-type interrupts. */
4183 +void ipmi_acpi_gpe(void *context)
4185 + struct smi_info *smi_info = context;
4186 + unsigned long flags;
4187 +#ifdef DEBUG_TIMING
4191 + spin_lock_irqsave(&(smi_info->si_lock), flags);
4193 + spin_lock(&smi_info->count_lock);
4194 + smi_info->interrupts++;
4195 + spin_unlock(&smi_info->count_lock);
4197 + if (smi_info->stop_operation)
4200 +#ifdef DEBUG_TIMING
4201 + do_gettimeofday(&t);
4202 + printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
4204 + smi_event_handler(smi_info, 0);
4206 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
4209 +static int acpi_gpe_irq_setup(struct smi_info *info)
4211 + acpi_status status;
4216 + /* FIXME - is level triggered right? */
4217 + status = acpi_install_gpe_handler(NULL,
4219 + ACPI_GPE_LEVEL_TRIGGERED,
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);
4230 + printk(" Using ACPI GPE %d\n", info->irq);
4236 +static void acpi_gpe_irq_cleanup(struct smi_info *info)
4241 + acpi_remove_gpe_handler(NULL, info->irq, ipmi_acpi_gpe);
4246 + * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf
4255 + s8 OEMRevision[4];
4257 + s8 CreatorRevision[4];
4258 + u8 InterfaceType[2];
4259 + s16 SpecificationRevision;
4262 + * Bit 0 - SCI interrupt supported
4263 + * Bit 1 - I/O APIC/SAPIC
4267 + /* If bit 0 of InterruptType is set, then this is the SCI
4268 + interrupt in the GPEx_STS register. */
4273 + /* If bit 1 of InterruptType is set, then this is the I/O
4274 + APIC/SAPIC interrupt. */
4275 + u32 GlobalSystemInterrupt;
4277 + /* The actual register address. */
4278 + struct acpi_generic_address addr;
4282 + s8 spmi_id[1]; /* A '\0' terminated array starts here. */
4285 +static int try_init_acpi(int intf_num, struct smi_info **new_info)
4287 + struct smi_info *info;
4288 + acpi_status status;
4289 + struct SPMITable *spmi;
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) {
4304 + if (spmi->InterfaceType[0] != 1)
4307 + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
4308 + addr_space = IPMI_MEM_ADDR_SPACE;
4310 + addr_space = IPMI_IO_ADDR_SPACE;
4311 + if (!is_new_interface(-1, addr_space, spmi->addr.address))
4314 + /* Figure out the interface type. */
4315 + switch (spmi->InterfaceType[1])
4318 + si_type[intf_num] = "kcs";
4321 + case 2: /* SMIC */
4322 + si_type[intf_num] = "smic";
4326 + si_type[intf_num] = "bt";
4330 + printk("ipmi_smi: Unknown ACPI SMI type.\n");
4334 + info = kmalloc(sizeof(*info), GFP_KERNEL);
4336 + printk("ipmi_smi: Could not allocate SMI data\n");
4339 + memset(info, 0, sizeof(*info));
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;
4352 + /* Use the default interrupt setting. */
4354 + info->irq_setup = NULL;
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) {
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]);
4375 + printk("ipmi_smi: Unknown ACPI I/O Address type.\n");
4381 + printk("ipmi_smi: Found ACPI-specified state machine at %s"
4382 + " address 0x%lx\n",
4383 + io_type, (unsigned long) spmi->addr.address);
4390 +typedef struct dmi_ipmi_data
4394 + unsigned long base_addr;
4398 +typedef struct dmi_header
4405 +static int decode_dmi(dmi_header_t *dm, dmi_ipmi_data_t *ipmi_data)
4407 + u8 *data = (u8 *)dm;
4408 + unsigned long base_addr;
4410 + ipmi_data->type = data[0x04];
4412 + memcpy(&base_addr,&data[0x08],sizeof(unsigned long));
4413 + if (base_addr & 1) {
4415 + base_addr &= 0xFFFE;
4416 + ipmi_data->addr_space = IPMI_IO_ADDR_SPACE;
4420 + ipmi_data->addr_space = IPMI_MEM_ADDR_SPACE;
4423 + ipmi_data->base_addr = base_addr;
4424 + ipmi_data->irq = data[0x11];
4426 + if (is_new_interface(-1, ipmi_data->addr_space,ipmi_data->base_addr))
4429 + memset(ipmi_data,0,sizeof(dmi_ipmi_data_t));
4434 +static int dmi_table(u32 base, int len, int num,
4435 + dmi_ipmi_data_t *ipmi_data)
4438 + struct dmi_header *dm;
4443 + buf = ioremap(base, len);
4449 + while(i<num && (data - buf) < len)
4451 + dm=(dmi_header_t *)data;
4453 + if((data-buf+dm->length) >= len)
4456 + if (dm->type == 38) {
4457 + if (decode_dmi(dm, ipmi_data) == 0) {
4464 + while((data-buf) < len && (*data || data[1]))
4474 +inline static int dmi_checksum(u8 *buf)
4479 + for(a=0; a<15; a++)
4484 +static int dmi_iterator(dmi_ipmi_data_t *ipmi_data)
4489 +#ifdef CONFIG_SIMNOW
4493 + while(fp < 0xFFFFF)
4495 + isa_memcpy_fromio(buf, fp, 15);
4496 + if(memcmp(buf, "_DMI_", 5)==0 && dmi_checksum(buf))
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];
4502 + if(dmi_table(base, len, num, ipmi_data) == 0)
4511 +static int try_init_smbios(int intf_num, struct smi_info **new_info)
4513 + struct smi_info *info;
4514 + dmi_ipmi_data_t ipmi_data;
4518 + status = dmi_iterator(&ipmi_data);
4523 + switch(ipmi_data.type) {
4524 + case 0x01: /* KCS */
4525 + si_type[intf_num] = "kcs";
4527 + case 0x02: /* SMIC */
4528 + si_type[intf_num] = "smic";
4530 + case 0x03: /* BT */
4531 + si_type[intf_num] = "bt";
4534 + printk("ipmi_smi: Unknown SMBIOS SMI type.\n");
4538 + info = kmalloc(sizeof(*info), GFP_KERNEL);
4540 + printk("ipmi_smi: Could not allocate SMI data\n");
4543 + memset(info, 0, sizeof(*info));
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) {
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]);
4563 + printk("ipmi_smi: Unknown SMBIOS I/O Address type.\n");
4567 + si_irqs[intf_num] = ipmi_data.irq;
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);
4576 +#endif /* CONFIG_X86 */
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
4585 +/* Avoid more than one attempt to probe pci smic. */
4586 +static int pci_smic_checked = 0;
4588 +static int find_pci_smic(int intf_num, struct smi_info **new_info)
4590 + struct smi_info *info;
4592 + struct pci_dev *pci_dev = NULL;
4596 + if (!pci_present() || pci_smic_checked)
4599 + pci_smic_checked = 1;
4601 + if ((pci_dev = pci_find_device(PCI_HP_VENDOR_ID, PCI_MMC_DEVICE_ID,
4604 + else if ((pci_dev = pci_find_class(PCI_ERMC_CLASSCODE, NULL)) &&
4605 + pci_dev->subsystem_vendor == PCI_HP_VENDOR_ID)
4610 + error = pci_read_config_word(pci_dev, PCI_MMC_ADDR_CW, &base_addr);
4614 + "ipmi_smi: pci_read_config_word() failed (%d).\n",
4619 + /* Bit 0: 1 specifies programmed I/O, 0 specifies memory mapped I/O */
4620 + if (!(base_addr & 0x0001))
4623 + "ipmi_smi: memory mapped I/O not supported for PCI"
4628 + base_addr &= 0xFFFE;
4630 + /* Data register starts at base address + 1 in eRMC */
4633 + if (!is_new_interface(-1, IPMI_IO_ADDR_SPACE, base_addr))
4636 + info = kmalloc(sizeof(*info), GFP_KERNEL);
4638 + printk("ipmi_smi: Could not allocate SMI data\n");
4641 + memset(info, 0, sizeof(*info));
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]);
4652 + si_irqs[intf_num] = pci_dev->irq;
4653 + si_type[intf_num] = "smic";
4655 + printk("ipmi_smi: Found PCI SMIC at I/O address 0x%lx\n",
4656 + (long unsigned int) base_addr);
4660 +#endif /* CONFIG_PCI */
4662 +static int try_init_plug_and_play(int intf_num, struct smi_info **new_info)
4665 + if (find_pci_smic(intf_num, new_info)==0)
4668 + /* Include other methods here. */
4674 +static int try_get_dev_id(struct smi_info *smi_info)
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;
4681 + /* Do a Get Device ID command, since it comes back with some
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);
4687 + smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
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);
4696 + else if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
4698 + smi_result = smi_info->handlers->event(
4699 + smi_info->si_sm, 0);
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. */
4709 + /* Otherwise, we got some data. */
4710 + resp_len = smi_info->handlers->get_result(smi_info->si_sm,
4711 + resp, IPMI_MAX_MSG_LENGTH);
4713 + /* That's odd, it should be longer. */
4716 + if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0))
4717 + /* That's odd, it shouldn't be able to fail. */
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;
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;
4734 +static int type_file_read_proc(char *page, char **start, off_t off,
4735 + int count, int *eof, void *data)
4737 + char *out = (char *) page;
4738 + struct smi_info *smi = data;
4740 + switch (smi->si_type) {
4742 + return sprintf(out, "kcs\n");
4744 + return sprintf(out, "smic\n");
4746 + return sprintf(out, "bt\n");
4752 +static int stat_file_read_proc(char *page, char **start, off_t off,
4753 + int count, int *eof, void *data)
4755 + char *out = (char *) page;
4756 + struct smi_info *smi = data;
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",
4768 + out += sprintf(out, "interrupts: %ld\n",
4770 + out += sprintf(out, "attentions: %ld\n",
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",
4780 + out += sprintf(out, "watchdog_pretimeouts: %ld\n",
4781 + smi->watchdog_pretimeouts);
4782 + out += sprintf(out, "incoming_messages: %ld\n",
4783 + smi->incoming_messages);
4785 + return (out - ((char *) page));
4788 +/* Returns 0 if initialized, or negative on an error. */
4789 +static int init_one_smi(int intf_num, struct smi_info **smi)
4792 + struct smi_info *new_smi;
4795 + rv = try_init_mem(intf_num, &new_smi);
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);
4804 + if ((rv) && (si_trydefaults)) {
4805 + rv = try_init_smbios(intf_num, &new_smi);
4808 + if ((rv) && (si_trydefaults)) {
4809 + rv = try_init_plug_and_play(intf_num, &new_smi);
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;
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;
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";
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;
4848 + /* No support for anything else yet. */
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");
4860 + new_smi->io_size = new_smi->handlers->init_data(new_smi->si_sm,
4863 + /* Now that we know the I/O size, we can set up the I/O. */
4864 + rv = new_smi->io_setup(new_smi);
4866 + printk(" Could not set up I/O space\n");
4870 + spin_lock_init(&(new_smi->si_lock));
4871 + spin_lock_init(&(new_smi->msg_lock));
4872 + spin_lock_init(&(new_smi->count_lock));
4874 + /* Do low-level detection first. */
4875 + if (new_smi->handlers->detect(new_smi->si_sm)) {
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);
4886 + /* Try to claim any interrupts. */
4887 + new_smi->irq_setup(new_smi);
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;
4895 + rv = ipmi_register_smi(&handlers,
4897 + new_smi->ipmi_version_major,
4898 + new_smi->ipmi_version_minor,
4899 + &(new_smi->intf));
4902 + "ipmi_smi: Unable to register device: error %d\n",
4907 + rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
4908 + type_file_read_proc, NULL,
4909 + new_smi, THIS_MODULE);
4912 + "ipmi_smi: Unable to create proc entry: %d\n",
4917 + rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
4918 + stat_file_read_proc, NULL,
4919 + new_smi, THIS_MODULE);
4922 + "ipmi_smi: Unable to create proc entry: %d\n",
4927 + start_clear_flags(new_smi);
4929 + /* IRQ is defined to be set when non-zero. */
4931 + new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
4933 + new_smi->interrupt_disabled = 0;
4934 + new_smi->timer_stopped = 0;
4935 + new_smi->stop_operation = 0;
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));
4946 + printk(" IPMI %s interface initialized\n", si_type[intf_num]);
4951 + if (new_smi->intf)
4952 + ipmi_unregister_smi(new_smi->intf);
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);
4960 + new_smi->io_cleanup(new_smi);
4964 +static __init int init_ipmi_si(void)
4974 + printk(KERN_INFO "IPMI System Interface driver 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);
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]));
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]));
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]));
5007 + for (i=1; i < SI_MAX_PARMS; i++) {
5008 + rv = init_one_smi(i, &(smi_infos[pos]));
5013 + if (smi_infos[0] == NULL) {
5014 + printk("ipmi_smi: Unable to find any SMI interfaces\n");
5020 +module_init(init_ipmi_si);
5023 +void __exit cleanup_one_si(struct smi_info *to_clean)
5026 + unsigned long flags;
5031 + /* Tell the timer and interrupt handlers that we are shutting
5033 + spin_lock_irqsave(&(to_clean->si_lock), flags);
5034 + spin_lock(&(to_clean->msg_lock));
5036 + to_clean->stop_operation = 1;
5038 + to_clean->irq_cleanup(to_clean);
5040 + spin_unlock(&(to_clean->msg_lock));
5041 + spin_unlock_irqrestore(&(to_clean->si_lock), flags);
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
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);
5054 + rv = ipmi_unregister_smi(to_clean->intf);
5057 + "ipmi_smi: Unable to unregister device: errno=%d\n",
5061 + to_clean->handlers->cleanup(to_clean->si_sm);
5063 + kfree(to_clean->si_sm);
5065 + to_clean->io_cleanup(to_clean);
5068 +static __exit void cleanup_ipmi_si(void)
5075 + for (i=0; i<SI_MAX_DRIVERS; i++) {
5076 + cleanup_one_si(smi_infos[i]);
5079 +module_exit(cleanup_ipmi_si);
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
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
5095 + Remember, ipmi_si_setup() is passed the string after the equal sign. */
5097 +static int __init ipmi_si_setup(char *str)
5099 + unsigned long val;
5100 + char *cur, *colon;
5105 + cur = strsep(&str, ",");
5106 + while ((cur) && (*cur) && (pos < SI_MAX_PARMS)) {
5109 + if (strcmp(cur, "nodefaults") == 0)
5110 + si_trydefaults = 0;
5113 + "ipmi_si: bad parameter value %s\n",
5117 + case 'k': /* KCS */
5118 + si_type[pos] = "kcs";
5121 + case 's': /* SMIC */
5122 + si_type[pos] = "smic";
5125 + case 'b': /* BT */
5126 + si_type[pos] = "bt";
5131 + val = simple_strtoul(cur + 1,
5135 + si_ports[pos] = val;
5137 + si_addrs[pos] = val;
5138 + if (*colon == ':') {
5139 + val = simple_strtoul(colon + 1,
5142 + si_irqs[pos] = val;
5149 + "ipmi_si: bad parameter value %s\n",
5152 + cur = strsep(&str, ",");
5157 +__setup("ipmi_si=", ipmi_si_setup);
5160 +MODULE_LICENSE("GPL");
5161 diff -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
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.
5173 + * Author: MontaVista Software, Inc.
5174 + * Corey Minyard <minyard@mvista.com>
5175 + * source@mvista.com
5177 + * Copyright 2002 MontaVista Software Inc.
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.
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.
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.
5201 +/* This is defined by the state machines themselves, it is an opaque
5202 + data type for them to use. */
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. */
5210 + unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset);
5211 + void (*outputb)(struct si_sm_io *io,
5212 + unsigned int offset,
5215 + /* Generic info used by the actual handling routines, the
5216 + state machine shouldn't touch these. */
5221 +/* Results of SMI events. */
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. */
5233 +/* Handlers for the SMI state machine. */
5234 +struct si_sm_handlers
5236 + /* Put the version number of the state machine here so the
5237 + upper layer can print it. */
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);
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);
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);
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);
5266 + /* Attempt to detect an SMI. Returns 0 on success or nonzero
5268 + int (*detect)(struct si_sm_data *smi);
5270 + /* The interface is shutting down, so clean it up. */
5271 + void (*cleanup)(struct si_sm_data *smi);
5273 + /* Return the size of the SMI structure in bytes. */
5274 + int (*size)(void);
5277 diff -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
5284 + * The interface to the IPMI driver for SMBus access to a SMBus compliant device.
5286 + * Author: Intel Corporation
5287 + * Todd Davis <todd.c.davis@intel.com>
5289 + * Copyright 2003 Intel Corporation
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.
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.
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.
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.
5319 +#include <linux/config.h>
5320 +#include <linux/version.h>
5321 +#if defined(MODVERSIONS)
5322 +#include <linux/modversions.h>
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>
5339 +#define IPMI_SMB_VERSION "v28"
5341 +/* module feature switches */
5342 +#define REGISTER_SMI 1
5343 +#define SMB_KTHREAD 1
5346 +#include <linux/kernel.h>
5347 +#include <linux/smp_lock.h>
5349 +/* a structure to store all information we need
5351 +typedef struct kthread_struct
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;
5360 + /* queue thread is waiting on. Gets initialized by
5361 + init_kthread, can be used by thread itself.
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
5370 +} kthread_t; /* the variable that contains the thread data */
5373 +#define SMB_IPMI_REQUEST 2
5374 +#define SMB_IPMI_RESPONSE 3
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
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)
5387 +#ifdef CONFIG_IPMI_SMB
5388 +/* This forces a dependency to the config file for this option. */
5391 +enum smb_intf_state {
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. */
5403 +#define SMB_IDLE(smb) ((smb)->smb_state == SMB_NORMAL \
5404 + && (smb)->curr_msg == NULL \
5405 + && ! atomic_read(&(smb)->req_events))
5407 +#define SMB_MSG_RETRIES 10
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;
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;
5428 + /* If set to true, this will request events the next time the
5429 + state machine is idle. */
5430 + atomic_t req_events;
5432 + /* If true, run the state machine to completion on every send
5433 + call. Generally used after a panic to make sure stuff goes
5435 + int run_to_completion;
5438 + kthread_t smb_thread;
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;
5448 +static int initialized = 0;
5449 +static void return_hosed_msg(struct smb_info *smb_info);
5451 +static void deliver_recv_msg(struct smb_info *smb_info,
5452 + struct ipmi_smi_msg *msg)
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);
5460 + "malformed message in deliver_recv_msg:"
5461 + " rsp_size = %d\n", msg->rsp_size);
5462 + ipmi_free_smi_msg(msg);
5465 + ipmi_smi_msg_received(smb_info->intf, msg);
5469 +static void return_hosed_msg(struct smb_info *smb_info)
5471 + struct ipmi_smi_msg *msg = smb_info->curr_msg;
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;
5479 + smb_info->curr_msg = NULL;
5480 + deliver_recv_msg(smb_info, msg);
5483 +static s32 smbus_client_read_block_data(struct i2c_client *client, int debug,
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,
5495 + if ((retries += 1) >= SMB_MSG_RETRIES) {
5497 + "smb_smbus_read_block_data failed: %d\n",
5500 + } else if (debug & (SMB_DEBUG_MSG|SMB_DEBUG_TIMING)) {
5501 + printk(KERN_WARNING
5502 + "smb_smbus_read_block_data: retry %d\n",
5507 + if (debug & SMB_DEBUG_TIMING) {
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);
5514 + if (debug & SMB_DEBUG_MSG) {
5516 + printk(KERN_INFO "ipmi response:");
5517 + for (i = 0; i < resp_len; i ++) {
5518 + printk (" %02x", (unsigned char) (values[i]));
5526 +static s32 smb_smbus_read_block_data(struct smb_info *smb_info, u8 *values)
5528 + return smbus_client_read_block_data(&smb_info->client,
5529 + smb_info->smb_debug, values);
5532 +static s32 smbus_client_write_block_data(struct i2c_client *client, int debug,
5533 + u8 length, u8 *values)
5538 + if (debug & SMB_DEBUG_MSG) {
5541 + printk(KERN_INFO "ipmi request:");
5542 + for (i = 0; i < length; i ++) {
5543 + printk (" %02x", (unsigned char) (values [i]));
5548 + if (debug & SMB_DEBUG_TIMING) {
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);
5555 + while ((ret = i2c_smbus_write_block_data (client,
5557 + length, values)) < 0)
5559 + if ((retries += 1) >= SMB_MSG_RETRIES) {
5561 + "smb_smbus_write_block_data failed: %d\n", ret);
5563 + } else if (debug & (SMB_DEBUG_MSG|SMB_DEBUG_TIMING)) {
5564 + printk(KERN_WARNING
5565 + "smb_smbus_write_block_data: retry %d\n",
5572 +static s32 smb_smbus_write_block_data(struct smb_info *smb_info,
5573 + u8 length, u8 *values)
5575 + return smbus_client_write_block_data(&smb_info->client,
5576 + smb_info->smb_debug,
5581 +static void send_next_msg(struct smb_info *smb_info)
5584 + struct list_head *entry = NULL;
5586 + spin_lock(&(smb_info->msg_lock));
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;
5596 + spin_unlock(&(smb_info->msg_lock));
5597 + smb_info->curr_msg = NULL;
5601 + smb_info->curr_msg = list_entry(entry,
5602 + struct ipmi_smi_msg,
5604 + spin_unlock(&(smb_info->msg_lock));
5605 + rv = smb_smbus_write_block_data(
5607 + smb_info->curr_msg->data_size,
5608 + smb_info->curr_msg->data);
5610 + return_hosed_msg(smb_info);
5614 +static void start_enable_irq(struct smb_info *smb_info)
5616 + unsigned char msg[2];
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;
5623 + if (smb_smbus_write_block_data(smb_info, 2, msg) == 0) {
5624 + smb_info->smb_state = SMB_ENABLE_INTERRUPTS1;
5626 + smb_info->smb_state = SMB_NORMAL;
5630 +static void start_clear_flags(struct smb_info *smb_info)
5632 + unsigned char msg[3];
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;
5639 + if (smb_smbus_write_block_data(smb_info, 3, msg) == 0) {
5640 + smb_info->smb_state = SMB_CLEARING_FLAGS;
5642 + smb_info->smb_state = SMB_NORMAL;
5646 +static void handle_flags(struct smb_info *smb_info)
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;
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;
5665 + if (smb_smbus_write_block_data(
5667 + smb_info->curr_msg->data_size,
5668 + smb_info->curr_msg->data) == 0) {
5669 + smb_info->smb_state = SMB_GETTING_MESSAGES;
5671 + ipmi_free_smi_msg(smb_info->curr_msg);
5672 + smb_info->curr_msg = NULL;
5673 + smb_info->smb_state = SMB_NORMAL;
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;
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;
5688 + if (smb_smbus_write_block_data(
5690 + smb_info->curr_msg->data_size,
5691 + smb_info->curr_msg->data) == 0) {
5692 + smb_info->smb_state = SMB_GETTING_EVENTS;
5694 + ipmi_free_smi_msg(smb_info->curr_msg);
5695 + smb_info->curr_msg = NULL;
5696 + smb_info->smb_state = SMB_NORMAL;
5700 + smb_info->smb_state = SMB_NORMAL;
5704 +static void handle_transaction_done(struct smb_info *smb_info)
5706 + struct ipmi_smi_msg *msg;
5709 + if (smb_info->smb_debug & SMB_DEBUG_STATE) {
5710 + printk(KERN_INFO "DONE 1: state = %d.\n", smb_info->smb_state);
5712 + switch (smb_info->smb_state) {
5714 + if (!smb_info->curr_msg)
5717 + smb_info->curr_msg->rsp_size
5718 + = smb_smbus_read_block_data(
5720 + smb_info->curr_msg->rsp);
5722 + msg = smb_info->curr_msg;
5723 + smb_info->curr_msg = NULL;
5724 + deliver_recv_msg(smb_info, msg);
5727 + case SMB_GETTING_FLAGS:
5729 + unsigned char msg[4];
5731 + /* We got the flags from the SMB, now handle them. */
5732 + len = smb_smbus_read_block_data(smb_info, msg);
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;
5744 + smb_info->msg_flags = msg[3];
5745 + handle_flags(smb_info);
5750 + case SMB_CLEARING_FLAGS:
5751 + case SMB_CLEARING_FLAGS_THEN_SET_IRQ:
5753 + unsigned char msg[3];
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",
5763 + if (smb_info->smb_state == SMB_CLEARING_FLAGS_THEN_SET_IRQ)
5764 + start_enable_irq(smb_info);
5766 + smb_info->smb_state = SMB_NORMAL;
5770 + case SMB_GETTING_EVENTS:
5772 + smb_info->curr_msg->rsp_size
5773 + = smb_smbus_read_block_data(smb_info,
5774 + smb_info->curr_msg->rsp);
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. */
5782 + /* Take off the event flag. */
5783 + smb_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
5785 + deliver_recv_msg(smb_info, msg);
5787 + handle_flags(smb_info);
5791 + case SMB_GETTING_MESSAGES:
5793 + smb_info->curr_msg->rsp_size
5794 + = smb_smbus_read_block_data(smb_info,
5795 + smb_info->curr_msg->rsp);
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. */
5803 + /* Take off the msg flag. */
5804 + smb_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
5806 + deliver_recv_msg(smb_info, msg);
5808 + handle_flags(smb_info);
5812 + case SMB_ENABLE_INTERRUPTS1:
5814 + unsigned char msg[4];
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;
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;
5831 + smb_info->smb_state = SMB_NORMAL;
5836 + case SMB_ENABLE_INTERRUPTS2:
5838 + unsigned char msg[4];
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");
5847 + smb_info->smb_state = SMB_NORMAL;
5851 + if (smb_info->smb_debug & SMB_DEBUG_STATE) {
5852 + printk(KERN_INFO "DONE 2: state = %d.\n", smb_info->smb_state);
5857 + * smb_event_handler must have a user context for calls to lm_sensors'
5860 +static void smb_event_handler(struct smb_info *smb_info)
5863 + if (smb_info->smb_debug & SMB_DEBUG_STATE) {
5864 + printk(KERN_INFO "smb_event_handler: state = %d.\n",
5865 + smb_info->smb_state);
5867 + if (smb_info->smb_state == SMB_NORMAL) {
5868 + if (smb_info->curr_msg != NULL)
5870 + handle_transaction_done(smb_info);
5872 + /* If we are currently idle, try to start the
5873 + * next message. */
5874 + send_next_msg(smb_info);
5877 + handle_transaction_done(smb_info);
5880 + if (smb_info->smb_state == SMB_NORMAL &&
5881 + smb_info->curr_msg == NULL &&
5882 + atomic_read(&smb_info->req_events))
5884 + /* We are idle and the upper layer requested that I fetch
5885 + events, so do so. */
5886 + unsigned char msg[2];
5888 + atomic_set(&smb_info->req_events, 0);
5889 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
5890 + msg[1] = IPMI_GET_MSG_FLAGS_CMD;
5892 + rv = smb_smbus_write_block_data(smb_info, 2, msg);
5894 + smb_info->smb_state = SMB_GETTING_FLAGS;
5899 +#ifdef REGISTER_SMI
5900 +static void sender(void *send_info,
5901 + struct ipmi_smi_msg *msg,
5904 + struct smb_info *smb_info = (struct smb_info *) send_info;
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));
5913 + smb_event_handler(smb_info);
5914 + while (! SMB_IDLE(smb_info)) {
5915 + smb_event_handler(smb_info);
5920 + if (smb_info->smb_debug & SMB_DEBUG_TIMING) {
5922 + do_gettimeofday(&t);
5924 + "**Enqueue %02x %02x: %ld.%9.9ld\n",
5925 + msg->data[0], msg->data[1], t.tv_sec, t.tv_usec);
5928 + spin_lock(&(smb_info->msg_lock));
5929 + if (priority > 0) {
5930 + list_add_tail(&(msg->link), &(smb_info->hp_xmit_msgs));
5932 + list_add_tail(&(msg->link), &(smb_info->xmit_msgs));
5934 + spin_unlock(&(smb_info->msg_lock));
5937 + wake_up_interruptible(&smb_info->smb_thread.queue);
5941 +static void request_events(void *send_info)
5943 + struct smb_info *smb_info = (struct smb_info *) send_info;
5945 + atomic_set(&smb_info->req_events, 1);
5947 + wake_up_interruptible(&smb_info->smb_thread.queue);
5951 +static int new_user(void *send_info)
5953 + if (!try_inc_mod_count(THIS_MODULE))
5958 +static void user_left(void *send_info)
5960 + MOD_DEC_USE_COUNT;
5963 +static void set_run_to_completion(void *send_info, int i_run_to_completion)
5965 + struct smb_info *smb_info = (struct smb_info *) send_info;
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);
5981 +static struct ipmi_smi_handlers handlers =
5984 + request_events: request_events,
5985 + new_user: new_user,
5986 + user_left: user_left,
5987 + set_run_to_completion: set_run_to_completion
5989 +#endif /* REGISTER_SMI */
5992 +/* initialize new created thread. Called by the new thread. */
5993 +static void init_kthread(kthread_t *kthread, char *name)
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)
6001 + /* fill in thread structure */
6002 + kthread->thread = current;
6004 + /* set signal mask to what we want to respond */
6005 + siginitsetinv(¤t->blocked,
6006 + sigmask(SIGKILL)|sigmask(SIGINT)|sigmask(SIGTERM));
6008 + /* initialise wait queue */
6009 + init_waitqueue_head(&kthread->queue);
6011 + /* initialise termination flag */
6012 + kthread->terminate = 0;
6014 + /* set name of this process (max 15 chars + 0 !) */
6015 + sprintf(current->comm, name);
6017 + /* let others run */
6020 + /* tell the creator that we are ready and let him continue */
6021 + up(&kthread->startstop_sem);
6025 +/* cleanup of thread. Called by the exiting thread. */
6026 +static void exit_kthread(kthread_t *kthread)
6028 + /* we are terminating */
6030 + /* lock the kernel, the exit will unlock it */
6032 + kthread->thread = NULL;
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. */
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.
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)
6056 + kthread_t *kthread = &smb_info->smb_thread;
6057 + /* setup the thread environment */
6058 + init_kthread(kthread, "IPMI SMBus thread");
6060 + /* an endless loop in which we are doing our work */
6063 + smb_event_handler(smb_info);
6064 + while (! SMB_IDLE(smb_info)) {
6065 + smb_event_handler(smb_info);
6068 + interruptible_sleep_on(&kthread->queue);
6070 + /* We need to do a memory barrier here to be sure that
6071 + the flags are visible on all CPUs.
6075 + /* here we are back from sleep, either due to the timeout
6076 + (one second), or because we caught a signal.
6078 + if (kthread->terminate)
6080 + /* we received a request to terminate ourself */
6084 + /* cleanup the thread, leave */
6085 + exit_kthread(kthread);
6087 + /* returning from the thread here calls the exit functions */
6090 +static void kthread_launcher(void *data)
6092 + kernel_thread((int (*)(void *))smb_thread, data, 0);
6095 +/* create a new kernel thread. Called by the creator. */
6096 +static void start_kthread(struct smb_info *smb_info)
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.
6106 + init_MUTEX_LOCKED(&kthread->startstop_sem);
6108 + /* create the new thread my running a task through keventd */
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;
6116 + /* and schedule it for execution */
6117 + schedule_task(&kthread->tq);
6119 + /* wait till it has reached the setup_thread routine */
6120 + down(&kthread->startstop_sem);
6124 +/* stop a kernel thread. Called by the removing instance */
6125 +static void stop_kthread(kthread_t *kthread)
6127 + if (kthread->thread == NULL)
6129 + printk(KERN_WARNING
6130 + "stop_kthread: killing non existing thread!\n");
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. */
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.
6145 + init_MUTEX_LOCKED(&kthread->startstop_sem);
6147 + /* We need to do a memory barrier here to be sure that
6148 + the flags are visible on all CPUs.
6152 + /* set flag to request thread termination */
6153 + kthread->terminate = 1;
6154 + wake_up_interruptible(&kthread->queue);
6156 + /* We need to do a memory barrier here to be sure that
6157 + the flags are visible on all CPUs.
6160 + kill_proc(kthread->thread->pid, SIGKILL, 1);
6162 + /* block till thread terminated */
6163 + down(&kthread->startstop_sem);
6165 + /* release the big kernel lock */
6168 + /* now we are sure the thread is in zombie state. We
6169 + notify keventd to clean the process up.
6171 + kill_proc(2, SIGCHLD, 1);
6176 +static int ipmi_smb_detect_hardware(struct i2c_client *client, int debug,
6177 + struct smb_info **smb_info)
6179 + unsigned char msg[2];
6180 + unsigned char resp[IPMI_MAX_MSG_LENGTH];
6181 + unsigned long resp_len;
6183 + struct smb_info *info;
6185 + /* Do a Get Device ID command, since it comes back with some
6187 + msg[0] = IPMI_NETFN_APP_REQUEST << 2;
6188 + msg[1] = IPMI_GET_DEVICE_ID_CMD;
6190 + ret = smbus_client_write_block_data(client, debug, 2, msg);
6194 + /* Otherwise, we got some data. */
6195 + resp_len = smbus_client_read_block_data(client, debug, resp);
6197 + /* That's odd, it should be longer. */
6200 + if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0))
6201 + /* That's odd, it shouldn't be able to fail. */
6204 + info = kmalloc(sizeof(*info), GFP_KERNEL);
6207 + memset(info, 0, sizeof(*info));
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;
6222 +#define MAX_SMB_BMCS 4
6224 +/* An array of SMB interfaces. */
6225 +static struct smb_info *smb_infos[MAX_SMB_BMCS];
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.
6232 + * Always provide the i2c address if it is known.
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");
6238 + * If this is sent, don't probe for adapters anywhere but where the
6239 + * smb_addr array gives.
6241 +static int smb_defaultprobe = 1;
6242 +MODULE_PARM(smb_defaultprobe, "i");
6245 + * Turn debugging on for specific BMCs. This array is indexed by
6248 + * Debug bit flags: IPMI messages: 1, driver state: 2, timing: 4, I2C probe: 8
6250 +static int smb_dbg[MAX_SMB_BMCS];
6251 +MODULE_PARM(smb_dbg, "1-"__MODULE_STRING(MAX_SMB_BMCS)"i");
6254 + * Debug the probing of adapters.
6256 +static int smb_dbg_probe = 0;
6257 +MODULE_PARM(smb_dbg_probe, "i");
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,
6266 +static unsigned int normal_isa[] = { SENSORS_ISA_END };
6267 +static unsigned int normal_isa_range[] = { SENSORS_ISA_END };
6269 +static unsigned short reserved[] =
6271 +/* As defined by SMBus Spec. Appendix C */
6272 + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x28,
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 */
6286 +static unsigned short smb_empty_list[] = { I2C_CLIENT_END, I2C_CLIENT_END };
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,
6298 +static unsigned int pos_reserved_as(int pos)
6300 + if (smb_addr[pos*2+1] != 0)
6301 + return (smb_addr[pos*2] << 16) | smb_addr[pos*2+1];
6306 +static int smb_found_addr_proc(struct i2c_adapter *adapter, int addr,
6307 + unsigned short flags, int kind)
6309 + int id = i2c_adapter_id(adapter);
6310 + int debug = smb_dbg[id];
6314 + struct i2c_client client;
6315 + struct smb_info *smb_info;
6317 + memset(&client, 0, sizeof(&client));
6318 + strcpy(client.name, "IPMI");
6319 + client.addr = addr;
6320 + client.adapter = adapter;
6322 + rv = ipmi_smb_detect_hardware(&client, debug, &smb_info);
6324 + if (smb_dbg_probe) {
6326 + "smb_found_addr_proc:No IPMI client 0x%x: %d\n",
6332 + if (smb_dbg_probe) {
6334 + "smb_found_addr_proc: i2c_probe found device at"
6335 + " i2c address %x\n", addr);
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;
6347 + for (i=0; i < MAX_SMB_BMCS; i++) {
6348 + unsigned int res = pos_reserved_as(i);
6350 + if (res == ((id << 16) | addr)) {
6351 + /* We have a reserved position, use it. */
6356 + /* Claim the first unused position */
6357 + if (!res && (next_pos == -1) && (smb_infos[next_pos] == NULL))
6360 + if (next_pos == -1) {
6365 +#ifdef REGISTER_SMI
6366 + rv = ipmi_register_smi(&handlers,
6368 + smb_info->ipmi_version_major,
6369 + smb_info->ipmi_version_minor,
6370 + &(smb_info->intf));
6373 + "ipmi_smb: Unable to register device: error %d\n",
6379 + rv = i2c_attach_client(&smb_info->client);
6382 + "smb_found_one_addr_proc:"
6383 + " Unable to attach i2c client: error %d\n",
6385 +#ifdef REGISTER_SMI
6386 + ipmi_unregister_smi(smb_info->intf);
6391 + smb_info->pos = next_pos;
6392 + smb_infos[next_pos] = smb_info;
6395 + start_kthread(smb_info);
6398 + start_clear_flags(smb_info);
6399 + smb_event_handler(smb_info);
6408 +static int attach_adapter(struct i2c_adapter *adapter)
6410 + int id = i2c_adapter_id(adapter);
6412 + if (smb_dbg_probe) {
6413 + printk(KERN_INFO "init_one_smb: Checking SMBus adapter %d:"
6414 + " %s\n", id, adapter->name);
6416 + if ((i2c_get_functionality(adapter) & (I2C_FUNC_SMBUS_BLOCK_DATA))
6417 + == (I2C_FUNC_SMBUS_BLOCK_DATA))
6419 + if (smb_dbg_probe) {
6420 + printk(KERN_INFO "init_one_smb: found SMBus adapter:"
6421 + " %s\n", adapter->name);
6423 + i2c_probe(adapter, &smb_address_data, smb_found_addr_proc);
6429 +void cleanup_one_smb(struct smb_info *to_clean)
6437 + stop_kthread(&to_clean->smb_thread);
6440 +#ifdef REGISTER_SMI
6441 + rv = ipmi_unregister_smi(to_clean->intf);
6444 + "ipmi_smb: Unable to unregister device: errno=%d\n",
6449 + rv = i2c_detach_client(&to_clean->client);
6452 + "ipmi_smb: Unable to detach SMBUS client: errno=%d\n",
6456 + smb_infos[to_clean->pos] = NULL;
6460 +static int detach_client(struct i2c_client *client)
6462 + struct smb_info *smb_info = client->data;
6464 + cleanup_one_smb(smb_info);
6467 +static struct i2c_driver smb_i2c_driver =
6471 + .flags = I2C_DF_NOTIFY,
6472 + .attach_adapter = attach_adapter,
6473 + .detach_client = detach_client,
6478 +static __init int init_ipmi_smb(void)
6486 + printk(KERN_INFO "IPMI SMB Interface driver version "
6487 + IPMI_SMB_VERSION "\n");
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)
6494 + smb_addr[i] = I2C_CLIENT_END;
6495 + smb_addr[i+2] = I2C_CLIENT_END;
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;
6502 + rv = i2c_add_driver(&smb_i2c_driver);
6508 +module_init(init_ipmi_smb);
6511 +static __exit void cleanup_ipmi_smb(void)
6518 + for (i=0; i<MAX_SMB_BMCS; i++) {
6519 + cleanup_one_smb(smb_infos[i]);
6524 +module_exit(cleanup_ipmi_smb);
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
6532 + nodefaults Suppress trying the default address range
6533 + debug_probe Debug probing of adapters
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
6539 + Remember, ipmi_smb_setup() is passed the string after the equal sign. */
6541 +static int __init ipmi_smb_setup(char *str)
6543 + unsigned long val;
6549 + cur = strsep(&str, ",");
6550 + while ((cur) && (*cur) && (pos < MAX_SMB_BMCS)) {
6551 + if (strcmp(cur, "nodefaults") == 0) {
6552 + smb_defaultprobe = 0;
6555 + if (strcmp(cur, "debug_probe") == 0) {
6556 + smb_dbg_probe = 1;
6559 + val = simple_strtoul(cur,
6562 + if (*sep == '.') {
6563 + smb_addr[pos*2] = val;
6564 + val = simple_strtoul(sep + 1,
6568 + smb_addr[pos*2] = 0;
6570 + smb_addr[pos*2+1] = val;
6572 + if (*sep == ':') {
6573 + val = simple_strtoul(sep + 1,
6576 + smb_dbg[pos] = val;
6579 + cur = strsep(&str, ",");
6583 +__setup("ipmi_smb=", ipmi_smb_setup);
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");
6589 diff -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
6596 + * The state-machine driver for an IPMI SMIC driver
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
6601 + * modified by: Hannes Schulz <schulz@schwaar.com>
6602 + * ipmi@schwaar.com
6605 + * Corey Minyard's driver for the KSC interface has the following
6606 + * copyright notice:
6607 + * Copyright 2002 MontaVista Software Inc.
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
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.
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.
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. */
6636 +#include <linux/kernel.h> /* For printk. */
6637 +#include <linux/string.h>
6638 +#include "ipmi_si_sm.h"
6640 +#define IPMI_SMIC_VERSION "v28"
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
6647 +#define SMIC_DEBUG_STATES 4
6648 +#define SMIC_DEBUG_MSG 2
6649 +#define SMIC_DEBUG_ENABLE 1
6651 +static int smic_debug = 1;
6667 +#define MAX_SMIC_READ_SIZE 80
6668 +#define MAX_SMIC_WRITE_SIZE 80
6669 +#define SMIC_MAX_ERROR_RETRIES 3
6671 +/* Timeouts in microseconds. */
6672 +#define SMIC_RETRY_TIMEOUT 100000
6673 +#define IPMI_ERR_MSG_TRUNCATED 0xc6
6674 +#define IPMI_ERR_UNSPECIFIED 0xff
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
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
6695 + enum smic_states state;
6696 + struct si_sm_io *io;
6697 + unsigned char write_data[MAX_SMIC_WRITE_SIZE];
6700 + int orig_write_count;
6701 + unsigned char read_data[MAX_SMIC_READ_SIZE];
6704 + unsigned int error_retries;
6705 + long smic_timeout;
6708 +static unsigned int init_smic_data (struct si_sm_data *smic,
6709 + struct si_sm_io *io)
6711 + smic->state = SMIC_IDLE;
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;
6721 + /* We use 3 bytes of I/O. */
6725 +static int start_smic_transaction(struct si_sm_data *smic,
6726 + unsigned char *data, unsigned int size)
6730 + if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
6733 + if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
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]));
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;
6754 +static int smic_get_result(struct si_sm_data *smic,
6755 + unsigned char *data, unsigned int length)
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]));
6766 + if (length < smic->read_pos) {
6767 + smic->read_pos = length;
6768 + smic->truncated = 1;
6770 + memcpy(data, smic->read_data, smic->read_pos);
6772 + if ((length >= 3) && (smic->read_pos < 3)) {
6773 + data[2] = IPMI_ERR_UNSPECIFIED;
6774 + smic->read_pos = 3;
6776 + if (smic->truncated) {
6777 + data[2] = IPMI_ERR_MSG_TRUNCATED;
6778 + smic->truncated = 0;
6780 + return smic->read_pos;
6783 +static inline unsigned char read_smic_flags(struct si_sm_data *smic)
6785 + return smic->io->inputb(smic->io, 2);
6788 +static inline unsigned char read_smic_status(struct si_sm_data *smic)
6790 + return smic->io->inputb(smic->io, 1);
6793 +static inline unsigned char read_smic_data(struct si_sm_data *smic)
6795 + return smic->io->inputb(smic->io, 0);
6798 +static inline void write_smic_flags(struct si_sm_data *smic,
6799 + unsigned char flags)
6801 + smic->io->outputb(smic->io, 2, flags);
6804 +static inline void write_smic_control(struct si_sm_data *smic,
6805 + unsigned char control)
6807 + smic->io->outputb(smic->io, 1, control);
6810 +static inline void write_si_sm_data (struct si_sm_data *smic,
6811 + unsigned char data)
6813 + smic->io->outputb(smic->io, 0, data);
6816 +static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
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);
6824 + smic->state = SMIC_HOSED;
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;
6834 +static inline void write_next_byte(struct si_sm_data *smic)
6836 + write_si_sm_data(smic, smic->write_data[smic->write_pos]);
6837 + (smic->write_pos)++;
6838 + (smic->write_count)--;
6841 +static inline void read_next_byte (struct si_sm_data *smic)
6843 + if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
6844 + read_smic_data (smic);
6845 + smic->truncated = 1;
6847 + smic->read_data[smic->read_pos] = read_smic_data(smic);
6848 + (smic->read_pos)++;
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
6863 +#define SMIC_CONTROL 0x00
6864 +#define SMIC_STATUS 0x80
6865 +#define SMIC_CS_MASK 0x80
6867 +#define SMIC_SMS 0x40
6868 +#define SMIC_SMM 0x60
6869 +#define SMIC_STREAM_MASK 0x60
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)
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)
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)
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)
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
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
6923 +static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
6925 + unsigned char status;
6926 + unsigned char flags;
6927 + unsigned char data;
6929 + if (smic->state == SMIC_HOSED) {
6930 + init_smic_data(smic, smic->io);
6931 + return SI_SM_HOSED;
6933 + if (smic->state != SMIC_IDLE) {
6934 + if (smic_debug & SMIC_DEBUG_STATES) {
6936 + "smic_event - smic->smic_timeout = %ld,"
6938 + smic->smic_timeout, time);
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;
6949 + flags = read_smic_flags(smic);
6950 + if (flags & SMIC_FLAG_BSY)
6951 + return SI_SM_CALL_WITH_DELAY;
6953 + status = read_smic_status (smic);
6954 + if (smic_debug & SMIC_DEBUG_STATES)
6956 + "smic_event - state = %d, flags = 0x%02x,"
6957 + " status = 0x%02x\n",
6958 + smic->state, flags, status);
6960 + switch (smic->state) {
6962 + /* in IDLE we check for available messages */
6963 + if (flags & (SMIC_SMI |
6964 + SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
6966 + return SI_SM_ATTN;
6968 + return SI_SM_IDLE;
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;
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;
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;
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;
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) {
7004 + write_smic_control(smic, SMIC_CC_SMS_WR_END);
7005 + smic->state = SMIC_WRITE_END;
7007 + write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
7008 + smic->state = SMIC_WRITE_NEXT;
7010 + write_next_byte(smic);
7011 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7014 + return SI_SM_CALL_WITH_DELAY;
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;
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;
7032 + write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
7033 + smic->state = SMIC_WRITE_NEXT;
7035 + write_next_byte(smic);
7036 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
7039 + return SI_SM_CALL_WITH_DELAY;
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;
7050 + /* data register holds an error code */
7051 + data = read_smic_data(smic);
7053 + if (smic_debug & SMIC_DEBUG_ENABLE) {
7055 + "SMIC_WRITE_END: data = %02x\n", data);
7057 + start_error_recovery(smic,
7058 + "state = SMIC_WRITE_END, "
7059 + "data != SUCCESS");
7060 + return SI_SM_CALL_WITH_DELAY;
7062 + smic->state = SMIC_WRITE2READ;
7066 + case SMIC_WRITE2READ:
7067 + /* we must wait for RX_DATA_READY to be set before we
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;
7074 + return SI_SM_CALL_WITH_DELAY;
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;
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;
7091 + return SI_SM_CALL_WITH_DELAY;
7095 + case SMIC_READ_NEXT:
7097 + /* smic tells us that this is the last byte to be read
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;
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;
7112 + return SI_SM_CALL_WITH_DELAY;
7116 + start_error_recovery(
7118 + "state = SMIC_READ_NEXT, "
7119 + "status != SMIC_SC_SMS_RD_(NEXT|END)");
7120 + return SI_SM_CALL_WITH_DELAY;
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;
7131 + data = read_smic_data(smic);
7132 + /* data register holds an error code */
7134 + if (smic_debug & SMIC_DEBUG_ENABLE) {
7136 + "SMIC_READ_END: data = %02x\n", data);
7138 + start_error_recovery(smic,
7139 + "state = SMIC_READ_END, "
7140 + "data != SUCCESS");
7141 + return SI_SM_CALL_WITH_DELAY;
7143 + smic->state = SMIC_IDLE;
7144 + return SI_SM_TRANSACTION_COMPLETE;
7148 + init_smic_data(smic, smic->io);
7149 + return SI_SM_HOSED;
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;
7158 + smic->smic_timeout = SMIC_RETRY_TIMEOUT;
7159 + return SI_SM_CALL_WITHOUT_DELAY;
7162 +static int smic_detect(struct si_sm_data *smic)
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)
7174 +static void smic_cleanup(struct si_sm_data *kcs)
7178 +static int smic_size(void)
7180 + return sizeof(struct si_sm_data);
7183 +struct si_sm_handlers smic_smi_handlers =
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,
7194 diff -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
7198 #include <asm/apic.h>
7201 +#define IPMI_WATCHDOG_VERSION "v28"
7204 * The IPMI command/response information for the watchdog timer.
7206 @@ -153,10 +155,18 @@
7207 static char pretimeout_since_last_heartbeat = 0;
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.");
7223 /* Default state of the timer. */
7224 static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
7227 static struct ipmi_smi_watcher smi_watcher =
7229 + .owner = THIS_MODULE,
7230 .new_smi = ipmi_new_smi,
7231 .smi_gone = ipmi_smi_gone
7237 + printk(KERN_INFO "IPMI watchdog driver version "
7238 + IPMI_WATCHDOG_VERSION "\n");
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);
7247 - printk(KERN_INFO "IPMI watchdog by "
7248 - "Corey Minyard (minyard@mvista.com)\n");
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);
7261 diff -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
7266 export-objs := ipmi_msghandler.o ipmi_watchdog.o
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
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
7280 include $(TOPDIR)/Rules.make
7282 ipmi_kcs_drv.o: $(ipmi_kcs_drv-objs)
7283 $(LD) -r -o $@ $(ipmi_kcs_drv-objs)
7285 +ipmi_si_drv.o: $(ipmi_si_drv-objs)
7286 + $(LD) -r -o $@ $(ipmi_si_drv-objs)
7287 diff -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
7291 * The in-kernel interface.
7293 #include <linux/list.h>
7294 +#include <linux/module.h>
7296 /* Opaque type for a IPMI message user. One of these is needed to
7297 send and receive messages. */
7298 @@ -221,7 +222,12 @@
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
7309 int ipmi_destroy_user(ipmi_user_t user);
7311 /* Get the IPMI version of the BMC we are talking to. */
7312 @@ -261,6 +267,27 @@
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
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.
7328 +int ipmi_request_settime(ipmi_user_t user,
7329 + struct ipmi_addr *addr,
7331 + struct ipmi_msg *msg,
7334 + unsigned int retry_time_ms);
7337 * Like ipmi_request, but lets you specify the slave return address.
7339 int ipmi_request_with_source(ipmi_user_t user,
7340 @@ -331,6 +358,10 @@
7342 struct list_head link;
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;
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, \
7355 +/* Messages sent to the interface with timing parameters are this
7357 +struct ipmi_req_settime
7359 + struct ipmi_req req;
7361 + /* See ipmi_request_settime() above for details on these
7364 + unsigned int retry_time_ms;
7367 + * Send a message to the interfaces with timing parameters. error values
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.
7375 +#define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, \
7376 + struct ipmi_req_settime)
7378 /* Messages received from the interface are this format. */
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)
7386 + * Get/set the default timing values for an interface. You shouldn't
7387 + * generally mess with these.
7389 +struct ipmi_timing_parms
7392 + unsigned int retry_time_ms;
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)
7399 #endif /* __LINUX_IPMI_H */
7400 diff -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
7404 /* Various definitions for IPMI messages used by almost everything in
7407 -#define IPMI_NETFN_APP_REQUEST 0x06
7408 -#define IPMI_NETFN_APP_RESPONSE 0x07
7410 -#define IPMI_BMC_SLAVE_ADDR 0x20
7411 +/* NetFNs and commands used inside the IPMI stack. */
7413 +#define IPMI_NETFN_SENSOR_EVENT_REQUEST 0x04
7414 +#define IPMI_NETFN_SENSOR_EVENT_RESPONSE 0x05
7415 +#define IPMI_GET_EVENT_RECEIVER_CMD 0x01
7417 +#define IPMI_NETFN_APP_REQUEST 0x06
7418 +#define IPMI_NETFN_APP_RESPONSE 0x07
7419 #define IPMI_GET_DEVICE_ID_CMD 0x01
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
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
7430 +#define IPMI_NETFN_STORAGE_REQUEST 0x0a
7431 +#define IPMI_NETFN_STORAGE_RESPONSE 0x0b
7432 +#define IPMI_ADD_SEL_ENTRY_CMD 0x44
7434 +/* The default slave address */
7435 +#define IPMI_BMC_SLAVE_ADDR 0x20
7437 #define IPMI_MAX_MSG_LENGTH 80
7439 +#define IPMI_CC_NO_ERROR 0
7440 +#define IPMI_NODE_BUSY_ERR 0xc0
7441 +#define IPMI_LOST_ARBITRATION_ERR 0x81
7443 #endif /* __LINUX_IPMI_MSGDEFS_H */
7444 diff -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
7448 #define __LINUX_IPMI_SMI_H
7450 #include <linux/ipmi_msgdefs.h>
7451 +#include <linux/proc_fs.h>
7452 +#include <linux/module.h>
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 @@
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);
7467 #endif /* __LINUX_IPMI_SMI_H */
7468 diff -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
7473 struct poll_table_struct;
7475 -#define NPROTO 32 /* should be enough for now.. */
7476 +#define NPROTO 64 /* should be enough for now.. */
7479 #define SYS_SOCKET 1 /* sys_socket(2) */
7480 diff -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
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.. */
7491 /* Protocol families, same as address families. */
7492 #define PF_UNSPEC AF_UNSPEC
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
7500 /* Maximum queue length specifiable by listen. */
7501 diff -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
7505 +#ifndef _NET_IPMI_H
7506 +#define _NET_IPMI_H
7508 +#include <linux/ipmi.h>
7511 + * This is ipmi address for socket
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;
7518 +#define SOCKADDR_IPMI_OVERHEAD (sizeof(struct sockaddr_ipmi) \
7519 + - sizeof(struct ipmi_addr))
7521 +/* A msg_control item, this takes a 'struct ipmi_timing_parms' */
7522 +#define IPMI_CMSG_TIMING_PARMS 0x01
7525 + * This is ipmi message for socket
7527 +struct ipmi_sock_msg {
7531 + unsigned char netfn;
7532 + unsigned char cmd;
7534 + unsigned char data[0];
7537 +#define IPMI_MAX_SOCK_MSG_LENGTH (sizeof(struct ipmi_sock_msg)+IPMI_MAX_MSG_LENGTH)
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)
7544 +/* Register to receive events. Takes an integer */
7545 +#define SIOCIPMIGETEVENT (SIOCPROTOPRIVATE + 2)
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)
7552 +/* Set/Get the IPMB address of the MC we are connected to, takes an
7554 +#define SIOCIPMISETADDR (SIOCPROTOPRIVATE + 5)
7555 +#define SIOCIPMIGETADDR (SIOCPROTOPRIVATE + 6)
7557 +/* Socket information for IPMI for protinfo. */
7560 + struct sockaddr_ipmi addr;
7561 + struct list_head msg_list;
7563 + wait_queue_head_t wait;
7566 + int default_retries;
7567 + unsigned int default_retry_time_ms;
7570 +#endif/*_NET_IPMI_H*/
7571 diff -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
7575 #include <net/irda/irda.h>
7578 +#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
7579 +#include <net/af_ipmi.h>
7582 #if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE)
7586 #if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE)
7587 struct wanpipe_opt *af_wanpipe;
7589 +#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
7590 + struct ipmi_sock af_ipmi;
7595 diff -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
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
7606 diff -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
7611 + * IPMI Socket Glue
7613 + * Author: Louis Zhuang <louis.zhuang@linux.intel.com>
7614 + * Copyright by Intel Corp., 2003
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>
7645 +#define IPMI_SOCKINTF_VERSION "v25"
7647 +#ifdef CONFIG_DEBUG_KERNEL
7648 +static int debug = 0;
7649 +#define dbg(format, arg...) \
7652 + printk (KERN_DEBUG "%s: " format "\n", \
7653 + __FUNCTION__, ## arg); \
7656 +#define dbg(format, arg...)
7657 +#endif /* CONFIG_DEBUG_KERNEL */
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)
7672 +static kmem_cache_t *ipmi_sk_cachep = NULL;
7674 +static atomic_t ipmi_nr_socks = ATOMIC_INIT(0);
7679 + * utility functions
7681 +static inline struct ipmi_sock *to_ipmi_sock(struct sock *sk)
7683 + return &sk->protinfo.af_ipmi;
7686 +static inline void ipmi_release_sock(struct sock *sk, int embrion)
7688 + struct ipmi_sock *i = to_ipmi_sock(sk);
7689 + struct sk_buff *skb;
7692 + ipmi_destroy_user(i->user);
7697 + sk->shutdown = SHUTDOWN_MASK;
7698 + sk->state = TCP_CLOSE;
7700 + while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
7706 +static inline long ipmi_wait_for_queue(struct ipmi_sock *i, long timeo)
7709 + DECLARE_WAITQUEUE(wait, current);
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);
7720 + * IPMI operation functions
7722 +static void sock_receive_handler(struct ipmi_recv_msg *msg,
7723 + void *handler_data)
7725 + struct ipmi_sock *i = (struct ipmi_sock *)handler_data;
7726 + unsigned long flags;
7728 + spin_lock_irqsave(&i->lock, flags);
7729 + list_add_tail(&msg->link, &i->msg_list);
7730 + spin_unlock_irqrestore(&i->lock, flags);
7732 + wake_up_interruptible(&i->wait);
7736 + * protocol operation functions
7738 +static int ipmi_release(struct socket *sock)
7740 + struct sock *sk = sock->sk;
7746 + ipmi_release_sock(sk, 0);
7750 +static struct ipmi_user_hndl ipmi_hnd = {
7751 + .ipmi_recv_hndl = sock_receive_handler
7754 +static int ipmi_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
7756 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7757 + struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)uaddr;
7758 + int err = -EINVAL;
7760 + if (i->user != NULL) {
7761 + dbg("Cannot bind twice: %p", i->user);
7765 + err = ipmi_create_user(addr->if_num, &ipmi_hnd, i, &i->user);
7767 + dbg("Cannot create user for the socket: %p", i->user);
7771 + memcpy(&i->addr, addr, sizeof(i->addr));
7775 +static int ipmi_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
7777 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7778 + memcpy(uaddr, &i->addr, sizeof(i->addr));
7782 +static unsigned int ipmi_poll(struct file * file, struct socket *sock, poll_table *wait)
7784 + unsigned int has_msg = 0;
7785 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7786 + unsigned long flags;
7788 + poll_wait(file, &i->wait, wait);
7789 + spin_lock_irqsave(&i->lock, flags);
7790 + if (!list_empty(&i->msg_list))
7792 + spin_unlock_irqrestore(&i->lock, flags);
7795 + return POLLIN | POLLRDNORM;
7799 +static int ipmi_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
7801 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
7802 + struct ipmi_cmdspec val;
7804 + unsigned int uival;
7807 + dbg("cmd=%#x, arg=%#lx", cmd, arg);
7809 + case SIOCIPMIREGCMD:
7810 + err = copy_from_user((void *)&val, (void *)arg,
7817 + err = ipmi_register_for_cmd(i->user, val.netfn,
7821 + case SIOCIPMIUNREGCMD:
7822 + err = copy_from_user((void *)&val, (void *)arg,
7829 + err = ipmi_unregister_for_cmd(i->user, val.netfn,
7833 + case SIOCIPMIGETEVENT:
7834 + err = copy_from_user((void *)&ival, (void *)arg,
7841 + err = ipmi_set_gets_events(i->user, ival);
7844 + case SIOCIPMISETADDR:
7845 + err = copy_from_user((void *)&uival, (void *)arg,
7852 + ipmi_set_my_address(i->user, uival);
7855 + case SIOCIPMIGETADDR:
7856 + uival = ipmi_get_my_address(i->user);
7858 + if (copy_to_user((void *) arg, &uival, sizeof(uival))) {
7865 + case SIOCIPMISETTIMING:
7867 + struct ipmi_timing_parms parms;
7869 + if (copy_from_user(&parms, (void *) arg, sizeof(parms))) {
7874 + i->default_retries = parms.retries;
7875 + i->default_retry_time_ms = parms.retry_time_ms;
7880 + case SIOCIPMIGETTIMING:
7882 + struct ipmi_timing_parms parms;
7884 + parms.retries = i->default_retries;
7885 + parms.retry_time_ms = i->default_retry_time_ms;
7887 + if (copy_to_user((void *) arg, &parms, sizeof(parms))) {
7897 + err = dev_ioctl(cmd, (void *)arg);
7904 +static int ipmi_recvmsg(struct socket *sock, struct msghdr *msg, int size,
7905 + int rflags, struct scm_cookie *scm)
7907 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
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;
7914 + unsigned long flags;
7916 + timeo = sock_rcvtimeo(sock->sk, rflags & MSG_DONTWAIT);
7919 + spin_lock_irqsave(&i->lock, flags);
7920 + if (!list_empty(&i->msg_list))
7922 + spin_unlock_irqrestore(&i->lock, flags);
7925 + } else if (signal_pending (current)) {
7926 + dbg("Signal pending: %d", 1);
7930 + timeo = ipmi_wait_for_queue(i, timeo);
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);
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));
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);
7951 + ipmi_free_recv_msg(rcvmsg);
7953 + err = memcpy_toiovec(msg->msg_iov, (void *)smsg,
7954 + sizeof(struct ipmi_sock_msg) + smsg->data_len);
7956 + dbg("Cannot copy data to user: %p", i->user);
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);
7966 + return (sizeof(struct ipmi_sock_msg) + smsg->data_len);
7969 +static int ipmi_sendmsg(struct socket *sock, struct msghdr *msg, int len,
7970 + struct scm_cookie *scm)
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;
7978 + struct ipmi_timing_parms tparms;
7979 + struct cmsghdr *cmsg;
7981 + err = ipmi_validate_addr(&addr->ipmi_addr,
7982 + msg->msg_namelen - SOCKADDR_IPMI_OVERHEAD);
7984 + dbg("Invalid IPMI address: %p", i->user);
7988 + if (len > IPMI_MAX_SOCK_MSG_LENGTH) {
7990 + dbg("Message too long: %p", i->user);
7994 + if (len < sizeof(struct ipmi_sock_msg)) {
7996 + dbg("Msg data too small for header: %p", i->user);
8000 + err = memcpy_fromiovec((void *)smsg, msg->msg_iov, len);
8002 + dbg("Cannot copy data to kernel: %p", i->user);
8006 + if (len < smsg->data_len+sizeof(struct ipmi_sock_msg)) {
8008 + dbg("Msg data is out of bound: %p", i->user);
8012 + /* Set defaults. */
8013 + tparms.retries = i->default_retries;
8014 + tparms.retry_time_ms = i->default_retry_time_ms;
8016 + for (cmsg=CMSG_FIRSTHDR(msg);
8018 + cmsg = CMSG_NXTHDR(msg, cmsg))
8020 + if (cmsg->cmsg_len < sizeof(struct cmsghdr)) {
8022 + dbg("cmsg length too short: %p", i->user);
8026 + if (cmsg->cmsg_level != SOL_SOCKET)
8029 + if (cmsg->cmsg_type == IPMI_CMSG_TIMING_PARMS) {
8030 + struct ipmi_timing_parms *pparms;
8032 + if (cmsg->cmsg_len != CMSG_LEN(sizeof(*pparms))) {
8034 + dbg("timing parms cmsg not right size: %p",
8038 + pparms = (struct ipmi_timing_parms *) CMSG_DATA(cmsg);
8039 + tparms.retries = pparms->retries;
8040 + tparms.retry_time_ms = pparms->retry_time_ms;
8044 + imsg.netfn = smsg->netfn;
8045 + imsg.cmd = smsg->cmd;
8046 + imsg.data = smsg->data;
8047 + imsg.data_len = smsg->data_len;
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);
8058 + dbg("Cannot send message: %p", i->user);
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
8087 +static void ipmi_sock_destructor(struct sock *sk)
8089 + skb_queue_purge(&sk->receive_queue);
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);
8098 + atomic_dec(&ipmi_nr_socks);
8099 + MOD_DEC_USE_COUNT;
8103 + * net protocol functions
8105 +static struct sock *ipmi_socket_create1(struct socket *sock)
8109 + if (atomic_read(&ipmi_nr_socks) >= 2*files_stat.max_files)
8112 + MOD_INC_USE_COUNT;
8114 + sk = sk_alloc(PF_IPMI, GFP_KERNEL, 1);
8116 + MOD_DEC_USE_COUNT;
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);
8127 + /* Set to use default values. */
8128 + sk->protinfo.af_ipmi.default_retries = -1;
8129 + sk->protinfo.af_ipmi.default_retry_time_ms = 0;
8131 + atomic_inc(&ipmi_nr_socks);
8135 +static int ipmi_socket_create(struct socket *sock, int protocol)
8137 + if (!capable(CAP_NET_RAW))
8139 + if (protocol && protocol != PF_IPMI)
8140 + return -EPROTONOSUPPORT;
8142 + sock->state = SS_UNCONNECTED;
8144 + switch (sock->type) {
8146 + sock->type=SOCK_DGRAM;
8148 + sock->ops = &ipmi_ops;
8151 + return -EPROTONOSUPPORT;
8154 + return ipmi_socket_create1(sock)? 0 : -ENOMEM;
8157 +static struct net_proto_family ipmi_family_ops = {
8158 + .family = PF_IPMI,
8159 + .create = ipmi_socket_create,
8164 + * init/exit functions
8166 +static int __init ipmi_socket_init(void)
8171 + printk(KERN_INFO "ipmi socket interface version "
8172 + IPMI_SOCKINTF_VERSION "\n");
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__);
8183 + err = sock_register(&ipmi_family_ops);
8185 + kmem_cache_destroy(ipmi_sk_cachep);
8190 +static void __exit ipmi_socket_exit(void)
8192 + sock_unregister(PF_IPMI);
8193 + kmem_cache_destroy(ipmi_sk_cachep);
8196 +#ifdef CONFIG_DEBUG_KERNEL
8197 +MODULE_PARM(debug, "i");
8199 +module_init(ipmi_socket_init);
8200 +module_exit(ipmi_socket_exit);
8202 +MODULE_LICENSE("GPL");
8203 diff -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
8210 +obj-$(CONFIG_IPMI_SOCKET) = af_ipmi.o
8212 +include $(TOPDIR)/Rules.make
8214 diff -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
8218 O_TARGET := network.o
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
8225 subdir-y := core ethernet
8227 subdir-$(CONFIG_DECNET) += decnet
8228 subdir-$(CONFIG_ECONET) += econet
8229 subdir-$(CONFIG_VLAN_8021Q) += 8021q
8230 +subdir-$(CONFIG_IPMI_SOCKET) += ipmi
8232 ifeq ($(CONFIG_NETFILTER),y)
8233 mod-subdirs += ipv4/ipvs