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 2003-12-06 17:45:52.831977967 +0100
3 +++ linux-2.4.23/Documentation/Configure.help 2003-12-06 17:46:42.774500910 +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 @@ -29334,14 +29341,32 @@
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 diff -urN linux-2.4.23.org/Documentation/IPMI.txt linux-2.4.23/Documentation/IPMI.txt
53 --- linux-2.4.23.org/Documentation/IPMI.txt 2003-12-06 12:55:11.829841204 +0100
54 +++ linux-2.4.23/Documentation/IPMI.txt 2003-12-06 17:46:42.792497135 +0100
56 driver, each open file for this device ties in to the message handler
59 -ipmi_kcs_drv - A driver for the KCS SMI. Most system have a KCS
61 +ipmi_si_drv - A driver for various system interfaces. This supports
62 +KCS, SMIC, and may support BT in the future. Unless you have your own
63 +custom interface, you probably need to use this.
65 +ipmi_kcs_drv - A driver for the KCS SI. Most systems have a KCS
66 +interface for IPMI. This is deprecated, ipmi_si_drv supports KCS and
69 +af_ipmi - A network socket interface to IPMI. This doesn't take up
70 +a character device in your system.
73 Much documentation for the interface is in the include files. The
74 IPMI include files are:
76 -ipmi.h - Contains the user interface and IOCTL interface for IPMI.
77 +net/af_ipmi.h - Contains the socket interface.
79 +linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
81 -ipmi_smi.h - Contains the interface for SMI drivers to use.
82 +linux/ipmi_smi.h - Contains the interface for system management interfaces
83 +(things that interface to IPMI controllers) to use.
85 -ipmi_msgdefs.h - General definitions for base IPMI messaging.
86 +linux/ipmi_msgdefs.h - General definitions for base IPMI messaging.
91 in the order they register, although if an SMI unregisters and then
92 another one registers, all bets are off.
94 -The ipmi_smi.h defines the interface for SMIs, see that for more
96 +The ipmi_smi.h defines the interface for management interfaces, see
97 +that for more details.
103 +The SI driver allows up to 4 KCS or SMIC interfaces to be configured
104 +in the system. By default, scan the ACPI tables for interfaces, and
105 +if it doesn't find any the driver will attempt to register one KCS
106 +interface at the spec-specified I/O port 0xca2 without interrupts.
107 +You can change this at module load time (for a module) with:
109 + insmod ipmi_si_drv.o si_type=<type1>,<type2>....
110 + si_ports=<port1>,<port2>... si_addrs=<addr1>,<addr2>
111 + si_irqs=<irq1>,<irq2>... si_trydefaults=[0|1]
113 +Each of these except si_trydefaults is a list, the first item for the
114 +first interface, second item for the second interface, etc.
116 +The si_type may be either "kcs" or "smic". If you leave it blank, it
119 +If you specify si_addrs as non-zero for an interface, the driver will
120 +use the memory address given as the address of the device. This
123 +If you specify si_ports as non-zero for an interface, the driver will
124 +use the I/O port given as the device address.
126 +If you specify si_irqs as non-zero for an interface, the driver will
127 +attempt to use the given interrupt for the device.
129 +si_trydefaults sets whether the standard IPMI interface at 0xca2 and
130 +any interfaces specified by ACPE are tried. By default, the driver
131 +tries it, set this value to zero to turn this off.
133 +When compiled into the kernel, the addresses can be specified on the
134 +kernel command line as:
136 + ipmi_si=[<type>,]<bmc1>:<irq1>,[<type>,]<bmc2>:<irq2>....,[nodefault]
138 +The type is optional and may be either "kcs" for KCS or "smic" for
139 +SMIC. If not specified, it defaults to KCS. The <bmcx> values is
140 +either "p<port>" or "m<addr>" for port or memory addresses. So for
141 +instance, a KCS interface at port 0xca2 using interrupt 9 and a SMIC
142 +memory interface at address 0xf9827341 with no interrupt would be
143 +specified "ipmi_si=k,p0xca2:9,s,m0xf9827341". If you specify zero
144 +for in irq or don't specify it, the driver will run polled unless the
145 +software can detect the interrupt to use in the ACPI tables.
147 +By default, the driver will attempt to detect a KCS device at the
148 +spec-specified 0xca2 address and any address specified by ACPI. If
149 +you want to turn this off, use the "nodefault" option.
151 +If you have high-res timers compiled into the kernel, the driver will
152 +use them to provide much better performance. Note that if you do not
153 +have high-res timers enabled in the kernel and you don't have
154 +interrupts enabled, the driver will run VERY slowly. Don't blame me,
155 +these interfaces suck.
161 The timeout is the number of seconds to the action, and the pretimeout
162 is the amount of seconds before the reset that the pre-timeout panic will
163 -occur (if pretimeout is zero, then pretimeout will not be enabled).
164 +occur (if pretimeout is zero, then pretimeout will not be enabled). Note
165 +that the pretimeout is the time before the final timeout. So if the
166 +timeout is 50 seconds and the pretimeout is 10 seconds, then the pretimeout
167 +will occur in 40 second (10 seconds before the timeout).
169 The action may be "reset", "power_cycle", or "power_off", and
170 specifies what to do when the timer times out, and defaults to
171 diff -urN linux-2.4.23.org/drivers/char/Config.in linux-2.4.23/drivers/char/Config.in
172 --- linux-2.4.23.org/drivers/char/Config.in 2003-12-06 12:53:22.102691137 +0100
173 +++ linux-2.4.23/drivers/char/Config.in 2003-12-06 17:46:42.890476581 +0100
176 tristate 'IPMI top-level message handler' CONFIG_IPMI_HANDLER
177 dep_mbool ' Generate a panic event to all BMCs on a panic' CONFIG_IPMI_PANIC_EVENT $CONFIG_IPMI_HANDLER
178 +dep_mbool ' Generate a OEM events holding the panic string' CONFIG_IPMI_PANIC_STRING $CONFIG_IPMI_PANIC_EVENT
179 dep_tristate ' Device interface for IPMI' CONFIG_IPMI_DEVICE_INTERFACE $CONFIG_IPMI_HANDLER
180 +dep_tristate ' IPMI SI handler' CONFIG_IPMI_SI $CONFIG_IPMI_HANDLER
181 dep_tristate ' IPMI KCS handler' CONFIG_IPMI_KCS $CONFIG_IPMI_HANDLER
182 dep_tristate ' IPMI Watchdog Timer' CONFIG_IPMI_WATCHDOG $CONFIG_IPMI_HANDLER
184 diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_devintf.c linux-2.4.23/drivers/char/ipmi/ipmi_devintf.c
185 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_devintf.c 2003-12-06 12:53:23.036496678 +0100
186 +++ linux-2.4.23/drivers/char/ipmi/ipmi_devintf.c 2003-12-06 17:46:42.918470709 +0100
188 #include <asm/semaphore.h>
189 #include <linux/init.h>
191 +#define IPMI_DEVINTF_VERSION "v27"
193 struct ipmi_file_private
197 struct fasync_struct *fasync_queue;
198 wait_queue_head_t wait;
199 struct semaphore recv_sem;
200 + int default_retries;
201 + unsigned int default_retry_time_ms;
204 static void file_receive_handler(struct ipmi_recv_msg *msg,
207 static struct ipmi_user_hndl ipmi_hndlrs =
209 - ipmi_recv_hndl : file_receive_handler
210 + .ipmi_recv_hndl = file_receive_handler,
213 static int ipmi_open(struct inode *inode, struct file *file)
215 priv->fasync_queue = NULL;
216 sema_init(&(priv->recv_sem), 1);
218 + /* Use the low-level defaults. */
219 + priv->default_retries = -1;
220 + priv->default_retry_time_ms = 0;
229 +static int handle_send_req(ipmi_user_t user,
230 + struct ipmi_req *req,
232 + unsigned int retry_time_ms)
235 + struct ipmi_addr addr;
236 + unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
238 + if (req->addr_len > sizeof(struct ipmi_addr))
241 + if (copy_from_user(&addr, req->addr, req->addr_len))
244 + rv = ipmi_validate_addr(&addr, req->addr_len);
248 + if (req->msg.data != NULL) {
249 + if (req->msg.data_len > IPMI_MAX_MSG_LENGTH)
252 + if (copy_from_user(&msgdata,
254 + req->msg.data_len))
257 + req->msg.data_len = 0;
259 + req->msg.data = msgdata;
261 + return ipmi_request_settime(user,
270 static int ipmi_ioctl(struct inode *inode,
273 @@ -170,54 +219,33 @@
275 case IPMICTL_SEND_COMMAND:
277 - struct ipmi_req req;
278 - struct ipmi_addr addr;
279 - unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
280 + struct ipmi_req req;
282 if (copy_from_user(&req, (void *) data, sizeof(req))) {
287 - if (req.addr_len > sizeof(struct ipmi_addr))
292 + rv = handle_send_req(priv->user,
294 + priv->default_retries,
295 + priv->default_retry_time_ms);
299 - if (copy_from_user(&addr, req.addr, req.addr_len)) {
300 + case IPMICTL_SEND_COMMAND_SETTIME:
302 + struct ipmi_req_settime req;
304 + if (copy_from_user(&req, (void *) data, sizeof(req))) {
309 - rv = ipmi_validate_addr(&addr, req.addr_len);
313 - if (req.msg.data != NULL) {
314 - if (req.msg.data_len > IPMI_MAX_MSG_LENGTH) {
319 - if (copy_from_user(&msgdata,
327 - req.msg.data_len = 0;
330 - req.msg.data = msgdata;
332 - rv = ipmi_request(priv->user,
337 + rv = handle_send_req(priv->user,
340 + req.retry_time_ms);
348 + case IPMICTL_SET_TIMING_PARMS_CMD:
350 + struct ipmi_timing_parms parms;
352 + if (copy_from_user(&parms, (void *) data, sizeof(parms))) {
357 + priv->default_retries = parms.retries;
358 + priv->default_retry_time_ms = parms.retry_time_ms;
363 + case IPMICTL_GET_TIMING_PARMS_CMD:
365 + struct ipmi_timing_parms parms;
367 + parms.retries = priv->default_retries;
368 + parms.retry_time_ms = priv->default_retry_time_ms;
370 + if (copy_to_user((void *) data, &parms, sizeof(parms))) {
381 @@ -424,12 +481,12 @@
384 static struct file_operations ipmi_fops = {
385 - owner: THIS_MODULE,
388 - release: ipmi_release,
389 - fasync: ipmi_fasync,
391 + .owner = THIS_MODULE,
392 + .ioctl = ipmi_ioctl,
394 + .release = ipmi_release,
395 + .fasync = ipmi_fasync,
399 #define DEVICE_NAME "ipmidev"
402 static struct ipmi_smi_watcher smi_watcher =
404 - new_smi : ipmi_new_smi,
405 - smi_gone : ipmi_smi_gone
406 + .owner = THIS_MODULE,
407 + .new_smi = ipmi_new_smi,
408 + .smi_gone = ipmi_smi_gone,
411 static __init int init_ipmi_devintf(void)
416 + printk(KERN_INFO "ipmi device interface version "
417 + IPMI_DEVINTF_VERSION "\n");
419 rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
421 printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
426 - printk(KERN_INFO "ipmi: device interface at char major %d\n",
431 module_init(init_ipmi_devintf);
432 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
433 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_kcs_intf.c 2003-12-06 12:53:22.989506463 +0100
434 +++ linux-2.4.23/drivers/char/ipmi/ipmi_kcs_intf.c 2003-12-06 17:46:42.974458964 +0100
436 #include <linux/interrupt.h>
437 #include <linux/ipmi_smi.h>
439 -#include "ipmi_kcs_sm.h"
440 +#include "ipmi_si_sm.h"
441 #include <linux/init.h>
443 /* Measure times between events in the driver. */
445 /* This forces a dependency to the config file for this option. */
448 +extern struct si_sm_handlers kcs_smi_handlers;
450 enum kcs_intf_state {
457 - struct kcs_data *kcs_sm;
458 + struct si_sm_data *kcs_sm;
461 struct list_head xmit_msgs;
464 int run_to_completion;
466 + struct si_sm_io io;
468 /* The I/O port of a KCS interface. */
472 /* zero if no irq; */
475 deliver_recv_msg(kcs_info, msg);
478 -static enum kcs_result start_next_msg(struct kcs_info *kcs_info)
479 +static enum si_sm_result start_next_msg(struct kcs_info *kcs_info)
482 struct list_head *entry = NULL;
486 kcs_info->curr_msg = NULL;
492 @@ -197,14 +201,15 @@
494 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
496 - err = start_kcs_transaction(kcs_info->kcs_sm,
497 - kcs_info->curr_msg->data,
498 - kcs_info->curr_msg->data_size);
499 + err = kcs_smi_handlers.start_transaction(
501 + kcs_info->curr_msg->data,
502 + kcs_info->curr_msg->data_size);
504 return_hosed_msg(kcs_info);
507 - rv = KCS_CALL_WITHOUT_DELAY;
508 + rv = SI_SM_CALL_WITHOUT_DELAY;
510 spin_unlock(&(kcs_info->msg_lock));
513 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
514 msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
516 - start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
517 + kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 2);
518 kcs_info->kcs_state = KCS_ENABLE_INTERRUPTS1;
522 msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
523 msg[2] = WDT_PRE_TIMEOUT_INT;
525 - start_kcs_transaction(kcs_info->kcs_sm, msg, 3);
526 + kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 3);
527 kcs_info->kcs_state = KCS_CLEARING_FLAGS;
531 kcs_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
532 kcs_info->curr_msg->data_size = 2;
534 - start_kcs_transaction(kcs_info->kcs_sm,
535 - kcs_info->curr_msg->data,
536 - kcs_info->curr_msg->data_size);
537 + kcs_smi_handlers.start_transaction(
539 + kcs_info->curr_msg->data,
540 + kcs_info->curr_msg->data_size);
541 kcs_info->kcs_state = KCS_GETTING_MESSAGES;
542 } else if (kcs_info->msg_flags & EVENT_MSG_BUFFER_FULL) {
543 /* Events available. */
545 kcs_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
546 kcs_info->curr_msg->data_size = 2;
548 - start_kcs_transaction(kcs_info->kcs_sm,
549 - kcs_info->curr_msg->data,
550 - kcs_info->curr_msg->data_size);
551 + kcs_smi_handlers.start_transaction(
553 + kcs_info->curr_msg->data,
554 + kcs_info->curr_msg->data_size);
555 kcs_info->kcs_state = KCS_GETTING_EVENTS;
557 kcs_info->kcs_state = KCS_NORMAL;
561 kcs_info->curr_msg->rsp_size
562 - = kcs_get_result(kcs_info->kcs_sm,
563 - kcs_info->curr_msg->rsp,
564 - IPMI_MAX_MSG_LENGTH);
565 + = kcs_smi_handlers.get_result(
567 + kcs_info->curr_msg->rsp,
568 + IPMI_MAX_MSG_LENGTH);
570 /* Do this here becase deliver_recv_msg() releases the
571 lock, and a new message can be put in during the
575 /* We got the flags from the KCS, now handle them. */
576 - len = kcs_get_result(kcs_info->kcs_sm, msg, 4);
577 + len = kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 4);
579 /* Error fetching flags, just give up for
582 unsigned char msg[3];
584 /* We cleared the flags. */
585 - kcs_get_result(kcs_info->kcs_sm, msg, 3);
586 + kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 3);
588 /* Error clearing flags */
591 case KCS_GETTING_EVENTS:
593 kcs_info->curr_msg->rsp_size
594 - = kcs_get_result(kcs_info->kcs_sm,
595 - kcs_info->curr_msg->rsp,
596 - IPMI_MAX_MSG_LENGTH);
597 + = kcs_smi_handlers.get_result(kcs_info->kcs_sm,
598 + kcs_info->curr_msg->rsp,
599 + IPMI_MAX_MSG_LENGTH);
601 /* Do this here becase deliver_recv_msg() releases the
602 lock, and a new message can be put in during the
604 case KCS_GETTING_MESSAGES:
606 kcs_info->curr_msg->rsp_size
607 - = kcs_get_result(kcs_info->kcs_sm,
608 - kcs_info->curr_msg->rsp,
609 - IPMI_MAX_MSG_LENGTH);
610 + = kcs_smi_handlers.get_result(kcs_info->kcs_sm,
611 + kcs_info->curr_msg->rsp,
612 + IPMI_MAX_MSG_LENGTH);
614 /* Do this here becase deliver_recv_msg() releases the
615 lock, and a new message can be put in during the
617 unsigned char msg[4];
619 /* We got the flags from the KCS, now handle them. */
620 - kcs_get_result(kcs_info->kcs_sm, msg, 4);
621 + kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 4);
624 "ipmi_kcs: Could not enable interrupts"
626 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
627 msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
628 msg[2] = msg[3] | 1; /* enable msg queue int */
629 - start_kcs_transaction(kcs_info->kcs_sm, msg,3);
630 + kcs_smi_handlers.start_transaction(
631 + kcs_info->kcs_sm, msg,3);
632 kcs_info->kcs_state = KCS_ENABLE_INTERRUPTS2;
636 unsigned char msg[4];
638 /* We got the flags from the KCS, now handle them. */
639 - kcs_get_result(kcs_info->kcs_sm, msg, 4);
640 + kcs_smi_handlers.get_result(kcs_info->kcs_sm, msg, 4);
643 "ipmi_kcs: Could not enable interrupts"
646 /* Called on timeouts and events. Timeouts should pass the elapsed
647 time, interrupts should pass in zero. */
648 -static enum kcs_result kcs_event_handler(struct kcs_info *kcs_info, int time)
649 +static enum si_sm_result kcs_event_handler(struct kcs_info *kcs_info,
652 - enum kcs_result kcs_result;
653 + enum si_sm_result kcs_result;
656 /* There used to be a loop here that waited a little while
657 @@ -477,19 +487,19 @@
658 range, which is far too long to wait in an interrupt. So
659 we just run until the state machine tells us something
660 happened or it needs a delay. */
661 - kcs_result = kcs_event(kcs_info->kcs_sm, time);
662 + kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, time);
664 - while (kcs_result == KCS_CALL_WITHOUT_DELAY)
665 + while (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
667 - kcs_result = kcs_event(kcs_info->kcs_sm, 0);
668 + kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
671 - if (kcs_result == KCS_TRANSACTION_COMPLETE)
672 + if (kcs_result == SI_SM_TRANSACTION_COMPLETE)
674 handle_transaction_done(kcs_info);
675 - kcs_result = kcs_event(kcs_info->kcs_sm, 0);
676 + kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
678 - else if (kcs_result == KCS_SM_HOSED)
679 + else if (kcs_result == SI_SM_HOSED)
681 if (kcs_info->curr_msg != NULL) {
682 /* If we were handling a user message, format
683 @@ -497,12 +507,12 @@
684 tell it about the error. */
685 return_hosed_msg(kcs_info);
687 - kcs_result = kcs_event(kcs_info->kcs_sm, 0);
688 + kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
689 kcs_info->kcs_state = KCS_NORMAL;
692 /* We prefer handling attn over new messages. */
693 - if (kcs_result == KCS_ATTN)
694 + if (kcs_result == SI_SM_ATTN)
696 unsigned char msg[2];
698 @@ -514,19 +524,19 @@
699 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
700 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
702 - start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
703 + kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 2);
704 kcs_info->kcs_state = KCS_GETTING_FLAGS;
708 /* If we are currently idle, try to start the next message. */
709 - if (kcs_result == KCS_SM_IDLE) {
710 + if (kcs_result == SI_SM_IDLE) {
711 kcs_result = start_next_msg(kcs_info);
712 - if (kcs_result != KCS_SM_IDLE)
713 + if (kcs_result != SI_SM_IDLE)
717 - if ((kcs_result == KCS_SM_IDLE)
718 + if ((kcs_result == SI_SM_IDLE)
719 && (atomic_read(&kcs_info->req_events)))
721 /* We are idle and the upper layer requested that I fetch
723 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
724 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
726 - start_kcs_transaction(kcs_info->kcs_sm, msg, 2);
727 + kcs_smi_handlers.start_transaction(kcs_info->kcs_sm, msg, 2);
728 kcs_info->kcs_state = KCS_GETTING_FLAGS;
731 @@ -549,11 +559,11 @@
732 struct ipmi_smi_msg *msg,
735 - struct kcs_info *kcs_info = (struct kcs_info *) send_info;
736 - enum kcs_result result;
737 - unsigned long flags;
738 + struct kcs_info *kcs_info = (struct kcs_info *) send_info;
739 + enum si_sm_result result;
740 + unsigned long flags;
746 spin_lock_irqsave(&(kcs_info->msg_lock), flags);
749 spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
750 result = kcs_event_handler(kcs_info, 0);
751 - while (result != KCS_SM_IDLE) {
752 + while (result != SI_SM_IDLE) {
753 udelay(KCS_SHORT_TIMEOUT_USEC);
754 result = kcs_event_handler(kcs_info,
755 KCS_SHORT_TIMEOUT_USEC);
756 @@ -602,16 +612,16 @@
758 static void set_run_to_completion(void *send_info, int i_run_to_completion)
760 - struct kcs_info *kcs_info = (struct kcs_info *) send_info;
761 - enum kcs_result result;
762 - unsigned long flags;
763 + struct kcs_info *kcs_info = (struct kcs_info *) send_info;
764 + enum si_sm_result result;
765 + unsigned long flags;
767 spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
769 kcs_info->run_to_completion = i_run_to_completion;
770 if (i_run_to_completion) {
771 result = kcs_event_handler(kcs_info, 0);
772 - while (result != KCS_SM_IDLE) {
773 + while (result != SI_SM_IDLE) {
774 udelay(KCS_SHORT_TIMEOUT_USEC);
775 result = kcs_event_handler(kcs_info,
776 KCS_SHORT_TIMEOUT_USEC);
777 @@ -676,13 +686,13 @@
779 static void kcs_timeout(unsigned long data)
781 - struct kcs_info *kcs_info = (struct kcs_info *) data;
782 - enum kcs_result kcs_result;
783 - unsigned long flags;
784 - unsigned long jiffies_now;
785 - unsigned long time_diff;
786 + struct kcs_info *kcs_info = (struct kcs_info *) data;
787 + enum si_sm_result kcs_result;
788 + unsigned long flags;
789 + unsigned long jiffies_now;
790 + unsigned long time_diff;
796 if (kcs_info->stop_operation) {
798 /* If the state machine asks for a short delay, then shorten
799 the timer timeout. */
800 #ifdef CONFIG_HIGH_RES_TIMERS
801 - if (kcs_result == KCS_CALL_WITH_DELAY) {
802 + if (kcs_result == SI_SM_CALL_WITH_DELAY) {
803 kcs_info->kcs_timer.sub_expires
804 += usec_to_arch_cycles(KCS_SHORT_TIMEOUT_USEC);
805 while (kcs_info->kcs_timer.sub_expires >= cycles_per_jiffies) {
809 /* If requested, take the shortest delay possible */
810 - if (kcs_result == KCS_CALL_WITH_DELAY) {
811 + if (kcs_result == SI_SM_CALL_WITH_DELAY) {
812 kcs_info->kcs_timer.expires = jiffies + 1;
814 kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
815 @@ -776,12 +786,12 @@
817 static int ipmi_kcs_detect_hardware(unsigned int port,
819 - struct kcs_data *data)
820 + struct si_sm_data *data)
822 - unsigned char msg[2];
823 - unsigned char resp[IPMI_MAX_MSG_LENGTH];
824 - unsigned long resp_len;
825 - enum kcs_result kcs_result;
826 + unsigned char msg[2];
827 + unsigned char resp[IPMI_MAX_MSG_LENGTH];
828 + unsigned long resp_len;
829 + enum si_sm_result kcs_result;
831 /* It's impossible for the KCS status register to be all 1's,
832 (assuming a properly functioning, self-initialized BMC)
833 @@ -798,29 +808,30 @@
835 msg[0] = IPMI_NETFN_APP_REQUEST << 2;
836 msg[1] = IPMI_GET_DEVICE_ID_CMD;
837 - start_kcs_transaction(data, msg, 2);
838 + kcs_smi_handlers.start_transaction(data, msg, 2);
840 - kcs_result = kcs_event(data, 0);
841 + kcs_result = kcs_smi_handlers.event(data, 0);
844 - if (kcs_result == KCS_CALL_WITH_DELAY) {
846 - kcs_result = kcs_event(data, 100);
847 + if (kcs_result == SI_SM_CALL_WITH_DELAY) {
848 + schedule_timeout(1);
849 + kcs_result = kcs_smi_handlers.event(data, 100);
851 - else if (kcs_result == KCS_CALL_WITHOUT_DELAY)
852 + else if (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
854 - kcs_result = kcs_event(data, 0);
855 + kcs_result = kcs_smi_handlers.event(data, 0);
860 - if (kcs_result == KCS_SM_HOSED) {
861 + if (kcs_result == SI_SM_HOSED) {
862 /* We couldn't get the state machine to run, so whatever's at
863 the port is probably not an IPMI KCS interface. */
866 /* Otherwise, we got some data. */
867 - resp_len = kcs_get_result(data, resp, IPMI_MAX_MSG_LENGTH);
868 + resp_len = kcs_smi_handlers.get_result(data, resp,
869 + IPMI_MAX_MSG_LENGTH);
871 /* That's odd, it should be longer. */
874 MODULE_PARM(kcs_irqs, "1-4i");
875 MODULE_PARM(kcs_ports, "1-4i");
877 +static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
879 + struct kcs_info *info = io->info;
881 + return inb(info->port+offset);
884 +static void port_outb(struct si_sm_io *io, unsigned int offset,
887 + struct kcs_info *info = io->info;
889 + outb(b, info->port+offset);
892 +static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
894 + struct kcs_info *info = io->info;
896 + return readb(info->addr+offset);
899 +static void mem_outb(struct si_sm_io *io, unsigned int offset,
902 + struct kcs_info *info = io->info;
904 + writeb(b, info->addr+offset);
907 /* Returns 0 if initialized, or negative on an error. */
908 static int init_one_kcs(int kcs_port,
914 + new_kcs->io.outputb = port_outb;
915 + new_kcs->io.inputb = port_inb;
916 + new_kcs->io.info = new_kcs;
918 if (request_mem_region(kcs_physaddr, 2, DEVICE_NAME) == NULL) {
920 @@ -917,15 +961,18 @@
924 + new_kcs->io.outputb = mem_outb;
925 + new_kcs->io.inputb = mem_inb;
926 + new_kcs->io.info = new_kcs;
929 - new_kcs->kcs_sm = kmalloc(kcs_size(), GFP_KERNEL);
930 + new_kcs->kcs_sm = kmalloc(kcs_smi_handlers.size(), GFP_KERNEL);
931 if (!new_kcs->kcs_sm) {
932 printk(KERN_ERR "ipmi_kcs: out of memory\n");
936 - init_kcs_data(new_kcs->kcs_sm, kcs_port, new_kcs->addr);
937 + kcs_smi_handlers.init_data(new_kcs->kcs_sm, &(new_kcs->io));
938 spin_lock_init(&(new_kcs->kcs_lock));
939 spin_lock_init(&(new_kcs->msg_lock));
941 @@ -1027,11 +1074,7 @@
943 #ifdef CONFIG_ACPI_INTERPRETER
945 -/* Retrieve the base physical address from ACPI tables. Originally
946 - from Hewlett-Packard simple bmc.c, a GPL KCS driver. */
948 #include <linux/acpi.h>
949 -/* A real hack, but everything's not there yet in 2.4. */
950 #include <acpi/acpi.h>
951 #include <acpi/actypes.h>
952 #include <acpi/actbl.h>
953 @@ -1046,37 +1089,69 @@
956 s8 CreatorRevision[4];
958 + u8 InterfaceType[2];
959 s16 SpecificationRevision;
962 + * Bit 0 - SCI interrupt supported
963 + * Bit 1 - I/O APIC/SAPIC
967 + /* If bit 0 of InterruptType is set, then this is the SCI
968 + interrupt in the GPEx_STS register. */
972 - u64 GlobalSystemInterrupt;
973 - u8 BaseAddress[12];
975 + /* If bit 1 of InterruptType is set, then this is the I/O
976 + APIC/SAPIC interrupt. */
977 + u32 GlobalSystemInterrupt;
979 + /* The actual register address. */
980 + struct acpi_generic_address addr;
983 -} __attribute__ ((packed));
985 -static unsigned long acpi_find_bmc(void)
986 + s8 spmi_id[1]; /* A '\0' terminated array starts here. */
989 +static int acpi_find_bmc(unsigned long *physaddr, int *port)
992 - struct acpi_table_header *spmi;
993 - static unsigned long io_base = 0;
997 + struct SPMITable *spmi;
999 status = acpi_get_firmware_table("SPMI", 1,
1000 - ACPI_LOGICAL_ADDRESSING, &spmi);
1001 + ACPI_LOGICAL_ADDRESSING,
1002 + (struct acpi_table_header **) &spmi);
1003 + if (status != AE_OK)
1006 + if (spmi->InterfaceType[0] != 1)
1010 + if (spmi->InterfaceType[1] != 1)
1014 + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
1015 + *physaddr = spmi->addr.address;
1016 + printk("ipmi_kcs_intf: Found ACPI-specified state machine"
1017 + " at memory address 0x%lx\n",
1018 + (unsigned long) spmi->addr.address);
1019 + } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
1020 + *port = spmi->addr.address;
1021 + printk("ipmi_kcs_intf: Found ACPI-specified state machine"
1022 + " at I/O address 0x%x\n",
1023 + (int) spmi->addr.address);
1025 + goto not_found; /* Not an address type we recognise. */
1027 - if (status != AE_OK) {
1028 - printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n");
1033 - memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress,
1042 @@ -1087,6 +1162,7 @@
1044 #ifdef CONFIG_ACPI_INTERPRETER
1045 unsigned long physaddr = 0;
1050 @@ -1114,26 +1190,25 @@
1051 /* Only try the defaults if enabled and resources are available
1052 (because they weren't already specified above). */
1054 - if (kcs_trydefaults) {
1055 + if (kcs_trydefaults && (pos == 0)) {
1057 #ifdef CONFIG_ACPI_INTERPRETER
1058 - if ((physaddr = acpi_find_bmc())) {
1059 - if (!check_mem_region(physaddr, 2)) {
1060 - rv = init_one_kcs(0,
1063 - &(kcs_infos[pos]));
1067 + if (rv && (acpi_find_bmc(&physaddr, &port) == 0)) {
1068 + rv = init_one_kcs(port,
1071 + &(kcs_infos[pos]));
1076 - if (!check_region(DEFAULT_IO_PORT, 2)) {
1078 rv = init_one_kcs(DEFAULT_IO_PORT,
1088 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
1089 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_kcs_sm.c 2003-12-06 12:53:23.035496886 +0100
1090 +++ linux-2.4.23/drivers/char/ipmi/ipmi_kcs_sm.c 2003-12-06 17:46:42.982457286 +0100
1095 -#include <asm/io.h>
1096 -#include <asm/string.h> /* Gets rid of memcpy warning */
1097 +#include <linux/kernel.h> /* For printk. */
1098 +#include <linux/string.h>
1099 +#include "ipmi_si_sm.h"
1101 -#include "ipmi_kcs_sm.h"
1102 +#define IPMI_KCS_VERSION "v27"
1104 /* Set this if you want a printout of why the state machine was hosed
1105 when it gets hosed. */
1107 #define IPMI_ERR_MSG_TRUNCATED 0xc6
1108 #define IPMI_ERR_UNSPECIFIED 0xff
1113 - enum kcs_states state;
1114 - unsigned int port;
1115 - unsigned char *addr;
1116 - unsigned char write_data[MAX_KCS_WRITE_SIZE];
1119 - int orig_write_count;
1120 - unsigned char read_data[MAX_KCS_READ_SIZE];
1123 + enum kcs_states state;
1124 + struct si_sm_io *io;
1125 + unsigned char write_data[MAX_KCS_WRITE_SIZE];
1128 + int orig_write_count;
1129 + unsigned char read_data[MAX_KCS_READ_SIZE];
1133 unsigned int error_retries;
1138 -void init_kcs_data(struct kcs_data *kcs, unsigned int port, unsigned char *addr)
1139 +static unsigned int init_kcs_data(struct si_sm_data *kcs,
1140 + struct si_sm_io *io)
1142 kcs->state = KCS_IDLE;
1147 kcs->write_count = 0;
1148 kcs->orig_write_count = 0;
1149 @@ -126,40 +126,29 @@
1151 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
1152 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
1155 -/* Remember, init_one_kcs() insured port and addr can't both be set */
1156 + /* Reserve 2 I/O bytes. */
1160 -static inline unsigned char read_status(struct kcs_data *kcs)
1161 +static inline unsigned char read_status(struct si_sm_data *kcs)
1164 - return inb(kcs->port + 1);
1166 - return readb(kcs->addr + 1);
1167 + return kcs->io->inputb(kcs->io, 1);
1170 -static inline unsigned char read_data(struct kcs_data *kcs)
1171 +static inline unsigned char read_data(struct si_sm_data *kcs)
1174 - return inb(kcs->port + 0);
1176 - return readb(kcs->addr + 0);
1177 + return kcs->io->inputb(kcs->io, 0);
1180 -static inline void write_cmd(struct kcs_data *kcs, unsigned char data)
1181 +static inline void write_cmd(struct si_sm_data *kcs, unsigned char data)
1184 - outb(data, kcs->port + 1);
1186 - writeb(data, kcs->addr + 1);
1187 + kcs->io->outputb(kcs->io, 1, data);
1190 -static inline void write_data(struct kcs_data *kcs, unsigned char data)
1191 +static inline void write_data(struct si_sm_data *kcs, unsigned char data)
1194 - outb(data, kcs->port + 0);
1196 - writeb(data, kcs->addr + 0);
1197 + kcs->io->outputb(kcs->io, 0, data);
1200 /* Control codes. */
1201 @@ -179,14 +168,14 @@
1202 #define GET_STATUS_OBF(status) ((status) & 0x01)
1205 -static inline void write_next_byte(struct kcs_data *kcs)
1206 +static inline void write_next_byte(struct si_sm_data *kcs)
1208 write_data(kcs, kcs->write_data[kcs->write_pos]);
1210 (kcs->write_count)--;
1213 -static inline void start_error_recovery(struct kcs_data *kcs, char *reason)
1214 +static inline void start_error_recovery(struct si_sm_data *kcs, char *reason)
1216 (kcs->error_retries)++;
1217 if (kcs->error_retries > MAX_ERROR_RETRIES) {
1222 -static inline void read_next_byte(struct kcs_data *kcs)
1223 +static inline void read_next_byte(struct si_sm_data *kcs)
1225 if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
1226 /* Throw the data away and mark it truncated. */
1228 write_data(kcs, KCS_READ_BYTE);
1231 -static inline int check_ibf(struct kcs_data *kcs,
1232 - unsigned char status,
1234 +static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
1237 if (GET_STATUS_IBF(status)) {
1238 kcs->ibf_timeout -= time;
1243 -static inline int check_obf(struct kcs_data *kcs,
1244 - unsigned char status,
1246 +static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
1249 if (! GET_STATUS_OBF(status)) {
1250 kcs->obf_timeout -= time;
1251 @@ -245,13 +232,13 @@
1255 -static void clear_obf(struct kcs_data *kcs, unsigned char status)
1256 +static void clear_obf(struct si_sm_data *kcs, unsigned char status)
1258 if (GET_STATUS_OBF(status))
1262 -static void restart_kcs_transaction(struct kcs_data *kcs)
1263 +static void restart_kcs_transaction(struct si_sm_data *kcs)
1265 kcs->write_count = kcs->orig_write_count;
1268 write_cmd(kcs, KCS_WRITE_START);
1271 -int start_kcs_transaction(struct kcs_data *kcs, char *data, unsigned int size)
1272 +static int start_kcs_transaction(struct si_sm_data *kcs, unsigned char *data,
1273 + unsigned int size)
1275 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
1281 -int kcs_get_result(struct kcs_data *kcs, unsigned char *data, int length)
1282 +static int get_kcs_result(struct si_sm_data *kcs, unsigned char *data,
1283 + unsigned int length)
1285 if (length < kcs->read_pos) {
1286 kcs->read_pos = length;
1288 /* This implements the state machine defined in the IPMI manual, see
1289 that for details on how this works. Divide that flowchart into
1290 sections delimited by "Wait for IBF" and this will become clear. */
1291 -enum kcs_result kcs_event(struct kcs_data *kcs, long time)
1292 +static enum si_sm_result kcs_event(struct si_sm_data *kcs, long time)
1294 unsigned char status;
1295 unsigned char state;
1298 /* All states wait for ibf, so just do it here. */
1299 if (!check_ibf(kcs, status, time))
1300 - return KCS_CALL_WITH_DELAY;
1301 + return SI_SM_CALL_WITH_DELAY;
1303 /* Just about everything looks at the KCS state, so grab that, too. */
1304 state = GET_STATUS_STATE(status);
1306 clear_obf(kcs, status);
1308 if (GET_STATUS_ATN(status))
1310 + return SI_SM_ATTN;
1312 - return KCS_SM_IDLE;
1313 + return SI_SM_IDLE;
1316 if (state != KCS_IDLE) {
1319 if (state == KCS_READ_STATE) {
1320 if (! check_obf(kcs, status, time))
1321 - return KCS_CALL_WITH_DELAY;
1322 + return SI_SM_CALL_WITH_DELAY;
1323 read_next_byte(kcs);
1325 /* We don't implement this exactly like the state
1327 clear_obf(kcs, status);
1328 kcs->orig_write_count = 0;
1329 kcs->state = KCS_IDLE;
1330 - return KCS_TRANSACTION_COMPLETE;
1331 + return SI_SM_TRANSACTION_COMPLETE;
1338 if (! check_obf(kcs, status, time))
1339 - return KCS_CALL_WITH_DELAY;
1340 + return SI_SM_CALL_WITH_DELAY;
1342 clear_obf(kcs, status);
1343 write_data(kcs, KCS_READ_BYTE);
1344 @@ -456,14 +445,14 @@
1347 if (! check_obf(kcs, status, time))
1348 - return KCS_CALL_WITH_DELAY;
1349 + return SI_SM_CALL_WITH_DELAY;
1351 clear_obf(kcs, status);
1352 if (kcs->orig_write_count) {
1353 restart_kcs_transaction(kcs);
1355 kcs->state = KCS_IDLE;
1356 - return KCS_TRANSACTION_COMPLETE;
1357 + return SI_SM_TRANSACTION_COMPLETE;
1361 @@ -472,14 +461,42 @@
1364 if (kcs->state == KCS_HOSED) {
1365 - init_kcs_data(kcs, kcs->port, kcs->addr);
1366 - return KCS_SM_HOSED;
1367 + init_kcs_data(kcs, kcs->io);
1368 + return SI_SM_HOSED;
1371 - return KCS_CALL_WITHOUT_DELAY;
1372 + return SI_SM_CALL_WITHOUT_DELAY;
1376 +static int kcs_size(void)
1378 - return sizeof(struct kcs_data);
1379 + return sizeof(struct si_sm_data);
1382 +static int kcs_detect(struct si_sm_data *kcs)
1384 + /* It's impossible for the KCS status register to be all 1's,
1385 + (assuming a properly functioning, self-initialized BMC)
1386 + but that's what you get from reading a bogus address, so we
1387 + test that first. */
1388 + if (read_status(kcs) == 0xff)
1394 +static void kcs_cleanup(struct si_sm_data *kcs)
1398 +struct si_sm_handlers kcs_smi_handlers =
1400 + .version = IPMI_KCS_VERSION,
1401 + .init_data = init_kcs_data,
1402 + .start_transaction = start_kcs_transaction,
1403 + .get_result = get_kcs_result,
1404 + .event = kcs_event,
1405 + .detect = kcs_detect,
1406 + .cleanup = kcs_cleanup,
1409 diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_msghandler.c linux-2.4.23/drivers/char/ipmi/ipmi_msghandler.c
1410 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_msghandler.c 2003-12-06 12:53:23.012501675 +0100
1411 +++ linux-2.4.23/drivers/char/ipmi/ipmi_msghandler.c 2003-12-06 17:46:42.995454560 +0100
1413 #include <linux/ipmi_smi.h>
1414 #include <linux/notifier.h>
1415 #include <linux/init.h>
1416 +#include <linux/proc_fs.h>
1418 +#define IPMI_MSGHANDLER_VERSION "v27"
1420 struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
1421 static int ipmi_init_msghandler(void);
1423 static int initialized = 0;
1425 +static struct proc_dir_entry *proc_ipmi_root = NULL;
1427 #define MAX_EVENTS_IN_QUEUE 25
1429 /* Don't let a message sit in a queue forever, always time it with at lest
1430 - the max message timer. */
1431 + the max message timer. This is in milliseconds. */
1432 #define MAX_MSG_TIMEOUT 60000
1440 + unsigned int inuse : 1;
1441 + unsigned int broadcast : 1;
1443 unsigned long timeout;
1444 unsigned long orig_timeout;
1445 @@ -169,6 +175,72 @@
1446 /* My LUN. This should generally stay the SMS LUN, but just in
1448 unsigned char my_lun;
1450 + /* The event receiver for my BMC, only really used at panic
1451 + shutdown as a place to store this. */
1452 + unsigned char event_receiver;
1453 + unsigned char event_receiver_lun;
1454 + unsigned char local_sel_device;
1455 + unsigned char local_event_generator;
1457 + /* A cheap hack, if this is non-null and a message to an
1458 + interface comes in with a NULL user, call this routine with
1459 + it. Note that the message will still be freed by the
1460 + caller. This only works on the system interface. */
1461 + void (*null_user_handler)(ipmi_smi_t intf, struct ipmi_smi_msg *msg);
1463 + /* Proc FS stuff. */
1464 + struct proc_dir_entry *proc_dir;
1465 + char proc_dir_name[10];
1467 + spinlock_t counter_lock; /* For making counters atomic. */
1469 + /* Commands we got that were invalid. */
1470 + unsigned int sent_invalid_commands;
1472 + /* Commands we sent to the MC. */
1473 + unsigned int sent_local_commands;
1474 + /* Responses from the MC that were delivered to a user. */
1475 + unsigned int handled_local_responses;
1476 + /* Responses from the MC that were not delivered to a user. */
1477 + unsigned int unhandled_local_responses;
1479 + /* Commands we sent out to the IPMB bus. */
1480 + unsigned int sent_ipmb_commands;
1481 + /* Commands sent on the IPMB that had errors on the SEND CMD */
1482 + unsigned int sent_ipmb_command_errs;
1483 + /* Each retransmit increments this count. */
1484 + unsigned int retransmitted_ipmb_commands;
1485 + /* When a message times out (runs out of retransmits) this is
1487 + unsigned int timed_out_ipmb_commands;
1489 + /* This is like above, but for broadcasts. Broadcasts are
1490 + *not* included in the above count (they are expected to
1492 + unsigned int timed_out_ipmb_broadcasts;
1494 + /* Responses I have sent to the IPMB bus. */
1495 + unsigned int sent_ipmb_responses;
1497 + /* The response was delivered to the user. */
1498 + unsigned int handled_ipmb_responses;
1499 + /* The response had invalid data in it. */
1500 + unsigned int invalid_ipmb_responses;
1501 + /* The response didn't have anyone waiting for it. */
1502 + unsigned int unhandled_ipmb_responses;
1504 + /* The command was delivered to the user. */
1505 + unsigned int handled_commands;
1506 + /* The command had invalid data in it. */
1507 + unsigned int invalid_commands;
1508 + /* The command didn't have anyone waiting for it. */
1509 + unsigned int unhandled_commands;
1511 + /* Invalid data in an event. */
1512 + unsigned int invalid_events;
1513 + /* Events that were received with the proper format. */
1514 + unsigned int events;
1520 static void deliver_response(struct ipmi_recv_msg *msg)
1522 - msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
1523 + msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
1526 /* Find the next sequence number not being used and add the given
1528 struct ipmi_recv_msg *recv_msg,
1529 unsigned long timeout,
1536 intf->seq_table[i].timeout = MAX_MSG_TIMEOUT;
1537 intf->seq_table[i].orig_timeout = timeout;
1538 intf->seq_table[i].retries_left = retries;
1539 + intf->seq_table[i].broadcast = broadcast;
1540 intf->seq_table[i].inuse = 1;
1541 intf->seq_table[i].seqid = NEXT_SEQID(intf->seq_table[i].seqid);
1546 /* Start the timer for a specific sequence table entry. */
1547 -static int intf_start_seq_timer(ipmi_smi_t intf,
1549 +static int intf_start_seq_timer(ipmi_smi_t intf,
1553 unsigned long flags;
1554 @@ -431,9 +505,50 @@
1556 struct seq_table *ent = &(intf->seq_table[seq]);
1557 ent->timeout = ent->orig_timeout;
1560 + spin_unlock_irqrestore(&(intf->seq_lock), flags);
1565 +/* Got an error for the send message for a specific sequence number. */
1566 +static int intf_err_seq(ipmi_smi_t intf,
1571 + unsigned long flags;
1572 + unsigned char seq;
1573 + unsigned long seqid;
1574 + struct ipmi_recv_msg *msg = NULL;
1577 + GET_SEQ_FROM_MSGID(msgid, seq, seqid);
1579 + spin_lock_irqsave(&(intf->seq_lock), flags);
1580 + /* We do this verification because the user can be deleted
1581 + while a message is outstanding. */
1582 + if ((intf->seq_table[seq].inuse)
1583 + && (intf->seq_table[seq].seqid == seqid))
1585 + struct seq_table *ent = &(intf->seq_table[seq]);
1588 + msg = ent->recv_msg;
1591 spin_unlock_irqrestore(&(intf->seq_lock), flags);
1594 + msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
1595 + msg->msg_data[0] = err;
1596 + msg->msg.netfn |= 1; /* Convert to a response. */
1597 + msg->msg.data_len = 1;
1598 + msg->msg.data = msg->msg_data;
1599 + deliver_response(msg);
1606 struct ipmi_recv_msg *supplied_recv,
1608 unsigned char source_address,
1609 - unsigned char source_lun)
1610 + unsigned char source_lun,
1612 + unsigned int retry_time_ms)
1615 struct ipmi_smi_msg *smi_msg;
1616 @@ -797,8 +914,11 @@
1619 if (addr->channel > IPMI_NUM_CHANNELS) {
1622 + spin_lock_irqsave(&intf->counter_lock, flags);
1623 + intf->sent_invalid_commands++;
1624 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1629 recv_msg->user = user;
1630 @@ -812,8 +932,12 @@
1633 smi_addr = (struct ipmi_system_interface_addr *) addr;
1634 - if (smi_addr->lun > 3)
1635 + if (smi_addr->lun > 3) {
1636 + spin_lock_irqsave(&intf->counter_lock, flags);
1637 + intf->sent_invalid_commands++;
1638 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1642 memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr));
1644 @@ -824,11 +948,17 @@
1646 /* We don't let the user do these, since we manage
1647 the sequence numbers. */
1648 + spin_lock_irqsave(&intf->counter_lock, flags);
1649 + intf->sent_invalid_commands++;
1650 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1655 if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) {
1656 + spin_lock_irqsave(&intf->counter_lock, flags);
1657 + intf->sent_invalid_commands++;
1658 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1662 @@ -840,41 +970,59 @@
1663 if (msg->data_len > 0)
1664 memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
1665 smi_msg->data_size = msg->data_len + 2;
1666 + spin_lock_irqsave(&intf->counter_lock, flags);
1667 + intf->sent_local_commands++;
1668 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1669 } else if ((addr->addr_type == IPMI_IPMB_ADDR_TYPE)
1670 || (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
1672 struct ipmi_ipmb_addr *ipmb_addr;
1673 unsigned char ipmb_seq;
1677 + int broadcast = 0;
1680 + spin_lock_irqsave(&intf->counter_lock, flags);
1681 + intf->sent_invalid_commands++;
1682 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1687 + if (retries < 0) {
1688 + if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
1689 + retries = 0; /* Don't retry broadcasts. */
1693 if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) {
1694 /* Broadcasts add a zero at the beginning of the
1695 message, but otherwise is the same as an IPMB
1697 addr->addr_type = IPMI_IPMB_ADDR_TYPE;
1699 - retries = 0; /* Don't retry broadcasts. */
1706 + /* Default to 1 second retries. */
1707 + if (retry_time_ms == 0)
1708 + retry_time_ms = 1000;
1710 /* 9 for the header and 1 for the checksum, plus
1711 possibly one for the broadcast. */
1712 if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) {
1713 + spin_lock_irqsave(&intf->counter_lock, flags);
1714 + intf->sent_invalid_commands++;
1715 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1720 ipmb_addr = (struct ipmi_ipmb_addr *) addr;
1721 if (ipmb_addr->lun > 3) {
1722 + spin_lock_irqsave(&intf->counter_lock, flags);
1723 + intf->sent_invalid_commands++;
1724 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1728 @@ -884,6 +1032,9 @@
1729 if (recv_msg->msg.netfn & 0x1) {
1730 /* It's a response, so use the user's sequence
1732 + spin_lock_irqsave(&intf->counter_lock, flags);
1733 + intf->sent_ipmb_responses++;
1734 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1735 format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid,
1737 source_address, source_lun);
1738 @@ -892,13 +1043,17 @@
1740 spin_lock_irqsave(&(intf->seq_lock), flags);
1742 + spin_lock(&intf->counter_lock);
1743 + intf->sent_ipmb_commands++;
1744 + spin_unlock(&intf->counter_lock);
1746 /* Create a sequence number with a 1 second
1747 timeout and 4 retries. */
1748 - /* FIXME - magic number for the timeout. */
1749 rv = intf_next_seq(intf,
1758 @@ -934,16 +1089,19 @@
1761 /* Unknown address type. */
1764 + spin_lock_irqsave(&intf->counter_lock, flags);
1765 + intf->sent_invalid_commands++;
1766 + spin_unlock_irqrestore(&intf->counter_lock, flags);
1774 - for (m=0; m<smi_msg->data_size; m++)
1775 - printk(" %2.2x", smi_msg->data[m]);
1778 + for (m=0; m<smi_msg->data_size; m++)
1779 + printk(" %2.2x", smi_msg->data[m]);
1783 intf->handlers->sender(intf->send_info, smi_msg, priority);
1784 @@ -970,7 +1128,29 @@
1787 user->intf->my_address,
1788 - user->intf->my_lun);
1789 + user->intf->my_lun,
1793 +int ipmi_request_settime(ipmi_user_t user,
1794 + struct ipmi_addr *addr,
1796 + struct ipmi_msg *msg,
1799 + unsigned int retry_time_ms)
1801 + return i_ipmi_request(user,
1808 + user->intf->my_address,
1809 + user->intf->my_lun,
1814 int ipmi_request_supply_msgs(ipmi_user_t user,
1815 @@ -990,7 +1170,8 @@
1818 user->intf->my_address,
1819 - user->intf->my_lun);
1820 + user->intf->my_lun,
1824 int ipmi_request_with_source(ipmi_user_t user,
1825 @@ -1009,7 +1190,124 @@
1834 +static int ipmb_file_read_proc(char *page, char **start, off_t off,
1835 + int count, int *eof, void *data)
1837 + char *out = (char *) page;
1838 + ipmi_smi_t intf = data;
1840 + return sprintf(out, "%x\n", intf->my_address);
1843 +static int version_file_read_proc(char *page, char **start, off_t off,
1844 + int count, int *eof, void *data)
1846 + char *out = (char *) page;
1847 + ipmi_smi_t intf = data;
1849 + return sprintf(out, "%d.%d\n",
1850 + intf->version_major, intf->version_minor);
1853 +static int stat_file_read_proc(char *page, char **start, off_t off,
1854 + int count, int *eof, void *data)
1856 + char *out = (char *) page;
1857 + ipmi_smi_t intf = data;
1859 + out += sprintf(out, "sent_invalid_commands: %d\n",
1860 + intf->sent_invalid_commands);
1861 + out += sprintf(out, "sent_local_commands: %d\n",
1862 + intf->sent_local_commands);
1863 + out += sprintf(out, "handled_local_responses: %d\n",
1864 + intf->handled_local_responses);
1865 + out += sprintf(out, "unhandled_local_responses: %d\n",
1866 + intf->unhandled_local_responses);
1867 + out += sprintf(out, "sent_ipmb_commands: %d\n",
1868 + intf->sent_ipmb_commands);
1869 + out += sprintf(out, "sent_ipmb_command_errs: %d\n",
1870 + intf->sent_ipmb_command_errs);
1871 + out += sprintf(out, "retransmitted_ipmb_commands: %d\n",
1872 + intf->retransmitted_ipmb_commands);
1873 + out += sprintf(out, "timed_out_ipmb_commands: %d\n",
1874 + intf->timed_out_ipmb_commands);
1875 + out += sprintf(out, "timed_out_ipmb_broadcasts: %d\n",
1876 + intf->timed_out_ipmb_broadcasts);
1877 + out += sprintf(out, "sent_ipmb_responses: %d\n",
1878 + intf->sent_ipmb_responses);
1879 + out += sprintf(out, "handled_ipmb_responses: %d\n",
1880 + intf->handled_ipmb_responses);
1881 + out += sprintf(out, "invalid_ipmb_responses: %d\n",
1882 + intf->invalid_ipmb_responses);
1883 + out += sprintf(out, "unhandled_ipmb_responses: %d\n",
1884 + intf->unhandled_ipmb_responses);
1885 + out += sprintf(out, "handled_commands: %d\n",
1886 + intf->handled_commands);
1887 + out += sprintf(out, "invalid_commands: %d\n",
1888 + intf->invalid_commands);
1889 + out += sprintf(out, "unhandled_commands: %d\n",
1890 + intf->unhandled_commands);
1891 + out += sprintf(out, "invalid_events: %d\n",
1892 + intf->invalid_events);
1893 + out += sprintf(out, "events: %d\n",
1896 + return (out - ((char *) page));
1899 +int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
1900 + read_proc_t *read_proc, write_proc_t *write_proc,
1901 + void *data, struct module *owner)
1903 + struct proc_dir_entry *file;
1906 + file = create_proc_entry(name, 0, smi->proc_dir);
1911 + file->data = data;
1912 + file->read_proc = read_proc;
1913 + file->write_proc = write_proc;
1914 + file->owner = owner;
1920 +static int add_proc_entries(ipmi_smi_t smi, int num)
1924 + sprintf(smi->proc_dir_name, "%d", num);
1925 + smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
1926 + if (!smi->proc_dir)
1929 + smi->proc_dir->owner = THIS_MODULE;
1933 + rv = ipmi_smi_add_proc_entry(smi, "stats",
1934 + stat_file_read_proc, NULL,
1935 + smi, THIS_MODULE);
1938 + rv = ipmi_smi_add_proc_entry(smi, "ipmb",
1939 + ipmb_file_read_proc, NULL,
1940 + smi, THIS_MODULE);
1943 + rv = ipmi_smi_add_proc_entry(smi, "version",
1944 + version_file_read_proc, NULL,
1945 + smi, THIS_MODULE);
1950 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
1951 @@ -1040,6 +1338,9 @@
1952 new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
1955 + memset(new_intf, 0, sizeof(*new_intf));
1957 + new_intf->proc_dir = NULL;
1961 @@ -1069,6 +1370,8 @@
1962 INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
1963 new_intf->all_cmd_rcvr = NULL;
1965 + spin_lock_init(&(new_intf->counter_lock));
1967 spin_lock_irqsave(&interfaces_lock, flags);
1968 ipmi_interfaces[i] = new_intf;
1969 spin_unlock_irqrestore(&interfaces_lock, flags);
1970 @@ -1089,6 +1392,9 @@
1971 /* Well, it went away. Just return. */
1975 + rv = add_proc_entries(*intf, i);
1978 /* Call all the watcher interfaces to tell them that a
1979 new interface is available. */
1980 @@ -1096,7 +1402,11 @@
1981 list_for_each(entry, &smi_watchers) {
1982 struct ipmi_smi_watcher *w;
1983 w = list_entry(entry, struct ipmi_smi_watcher, link);
1985 + if (try_inc_mod_count(w->owner)) {
1988 + __MOD_DEC_USE_COUNT(w->owner);
1991 up_read(&smi_watchers_sem);
1993 @@ -1104,8 +1414,12 @@
1995 up_read(&interfaces_sem);
1999 + if (new_intf->proc_dir)
2000 + remove_proc_entry(new_intf->proc_dir_name,
2007 @@ -1163,6 +1477,8 @@
2009 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2010 if (ipmi_interfaces[i] == intf) {
2011 + remove_proc_entry(intf->proc_dir_name,
2013 spin_lock_irqsave(&interfaces_lock, flags);
2014 ipmi_interfaces[i] = NULL;
2015 clean_up_interface_data(intf);
2016 @@ -1204,15 +1520,21 @@
2018 struct ipmi_ipmb_addr ipmb_addr;
2019 struct ipmi_recv_msg *recv_msg;
2020 + unsigned long flags;
2023 - if (msg->rsp_size < 11)
2024 + if (msg->rsp_size < 11) {
2025 /* Message not big enough, just ignore it. */
2026 + spin_lock_irqsave(&intf->counter_lock, flags);
2027 + intf->invalid_ipmb_responses++;
2028 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2032 - if (msg->rsp[2] != 0)
2033 + if (msg->rsp[2] != 0) {
2034 /* An error getting the response, just ignore it. */
2038 ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
2039 ipmb_addr.slave_addr = msg->rsp[6];
2040 @@ -1231,6 +1553,9 @@
2042 /* We were unable to find the sequence number,
2043 so just nuke the message. */
2044 + spin_lock_irqsave(&intf->counter_lock, flags);
2045 + intf->unhandled_ipmb_responses++;
2046 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2050 @@ -1244,6 +1569,9 @@
2051 recv_msg->msg.data = recv_msg->msg_data;
2052 recv_msg->msg.data_len = msg->rsp_size - 10;
2053 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
2054 + spin_lock_irqsave(&intf->counter_lock, flags);
2055 + intf->handled_ipmb_responses++;
2056 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2057 deliver_response(recv_msg);
2060 @@ -1252,18 +1580,23 @@
2061 static int handle_get_msg_cmd(ipmi_smi_t intf,
2062 struct ipmi_smi_msg *msg)
2064 - struct list_head *entry;
2065 + struct list_head *entry;
2066 struct cmd_rcvr *rcvr;
2068 - unsigned char netfn;
2069 - unsigned char cmd;
2070 - ipmi_user_t user = NULL;
2072 + unsigned char netfn;
2073 + unsigned char cmd;
2074 + ipmi_user_t user = NULL;
2075 struct ipmi_ipmb_addr *ipmb_addr;
2076 struct ipmi_recv_msg *recv_msg;
2077 + unsigned long flags;
2079 - if (msg->rsp_size < 10)
2080 + if (msg->rsp_size < 10) {
2081 /* Message not big enough, just ignore it. */
2082 + spin_lock_irqsave(&intf->counter_lock, flags);
2083 + intf->invalid_commands++;
2084 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2088 if (msg->rsp[2] != 0) {
2089 /* An error getting the response, just ignore it. */
2090 @@ -1291,6 +1624,10 @@
2093 /* We didn't find a user, deliver an error response. */
2094 + spin_lock_irqsave(&intf->counter_lock, flags);
2095 + intf->unhandled_commands++;
2096 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2098 msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
2099 msg->data[1] = IPMI_SEND_MSG_CMD;
2100 msg->data[2] = msg->rsp[3];
2101 @@ -1311,6 +1648,10 @@
2102 causes it to not be freed or queued. */
2104 /* Deliver the message to the user. */
2105 + spin_lock_irqsave(&intf->counter_lock, flags);
2106 + intf->handled_commands++;
2107 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2109 recv_msg = ipmi_alloc_recv_msg();
2111 /* We couldn't allocate memory for the
2112 @@ -1374,6 +1715,9 @@
2114 if (msg->rsp_size < 19) {
2115 /* Message is too small to be an IPMB event. */
2116 + spin_lock_irqsave(&intf->counter_lock, flags);
2117 + intf->invalid_events++;
2118 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2122 @@ -1386,6 +1730,10 @@
2124 spin_lock_irqsave(&(intf->events_lock), flags);
2126 + spin_lock(&intf->counter_lock);
2128 + spin_unlock(&intf->counter_lock);
2130 /* Allocate and fill in one message for every user that is getting
2132 list_for_each(entry, &(intf->users)) {
2133 @@ -1459,6 +1807,7 @@
2134 struct ipmi_recv_msg *recv_msg;
2136 struct list_head *entry;
2137 + unsigned long flags;
2139 recv_msg = (struct ipmi_recv_msg *) msg->user_data;
2141 @@ -1474,11 +1823,20 @@
2145 + /* Special handling for NULL users. */
2146 + if (!recv_msg->user && intf->null_user_handler)
2147 + intf->null_user_handler(intf, msg);
2148 /* The user for the message went away, so give up. */
2149 + spin_lock_irqsave(&intf->counter_lock, flags);
2150 + intf->unhandled_local_responses++;
2151 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2152 ipmi_free_recv_msg(recv_msg);
2154 struct ipmi_system_interface_addr *smi_addr;
2156 + spin_lock_irqsave(&intf->counter_lock, flags);
2157 + intf->handled_local_responses++;
2158 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2159 recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
2160 recv_msg->msgid = msg->msgid;
2161 smi_addr = ((struct ipmi_system_interface_addr *)
2162 @@ -1505,7 +1863,7 @@
2163 static int handle_new_recv_msg(ipmi_smi_t intf,
2164 struct ipmi_smi_msg *msg)
2169 if (msg->rsp_size < 2) {
2170 /* Message is too small to be correct. */
2171 @@ -1551,10 +1909,30 @@
2173 read_lock(&(intf->users_lock));
2175 - if ((msg->data_size >= 2) && (msg->data[1] == IPMI_SEND_MSG_CMD)) {
2176 + if ((msg->data_size >= 2)
2177 + && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
2178 + && (msg->data[1] == IPMI_SEND_MSG_CMD)) {
2179 /* This is the local response to a send, start the
2181 - intf_start_seq_timer(intf, msg->msgid);
2183 + /* Check for errors, if we get certain errors (ones
2184 + that mean basically we can try again later), we
2185 + ignore them and start the timer. Otherwise we
2186 + report the error immediately. */
2187 + if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0)
2188 + && (msg->rsp[2] != IPMI_NODE_BUSY_ERR)
2189 + && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR))
2191 + /* Got an error sending the message, handle it. */
2192 + spin_lock_irqsave(&intf->counter_lock, flags);
2193 + intf->sent_ipmb_command_errs++;
2194 + spin_unlock_irqrestore(&intf->counter_lock, flags);
2195 + intf_err_seq(intf, msg->msgid, msg->rsp[2]);
2197 + /* The message was sent, start the timer. */
2198 + intf_start_seq_timer(intf, msg->msgid);
2201 ipmi_free_smi_msg(msg);
2204 @@ -1699,6 +2077,12 @@
2206 msg = ent->recv_msg;
2207 list_add_tail(&(msg->link), &timeouts);
2208 + spin_lock(&intf->counter_lock);
2209 + if (ent->broadcast)
2210 + intf->timed_out_ipmb_broadcasts++;
2212 + intf->timed_out_ipmb_commands++;
2213 + spin_unlock(&intf->counter_lock);
2215 /* More retries, send again. */
2217 @@ -1708,6 +2092,9 @@
2218 ent->retries_left--;
2219 send_from_recv_msg(intf, ent->recv_msg, NULL,
2221 + spin_lock(&intf->counter_lock);
2222 + intf->retransmitted_ipmb_commands++;
2223 + spin_unlock(&intf->counter_lock);
2226 spin_unlock_irqrestore(&(intf->seq_lock), flags);
2227 @@ -1740,13 +2127,16 @@
2229 static struct timer_list ipmi_timer;
2231 -/* Call every 100 ms. */
2232 +/* Call every ~100 ms. */
2233 #define IPMI_TIMEOUT_TIME 100
2234 -#define IPMI_TIMEOUT_JIFFIES (IPMI_TIMEOUT_TIME/(1000/HZ))
2236 -/* Request events from the queue every second. Hopefully, in the
2237 - future, IPMI will add a way to know immediately if an event is
2239 +/* How many jiffies does it take to get to the timeout time. */
2240 +#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
2242 +/* Request events from the queue every second (this is the number of
2243 + IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
2244 + future, IPMI will add a way to know immediately if an event is in
2245 + the queue and this silliness can go away. */
2246 #define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
2248 static volatile int stop_operation = 0;
2249 @@ -1822,18 +2212,48 @@
2253 -static void send_panic_events(void)
2254 +#ifdef CONFIG_IPMI_PANIC_STRING
2255 +static void event_receiver_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
2257 + if ((msg->rsp[0] == (IPMI_NETFN_SENSOR_EVENT_RESPONSE << 2))
2258 + && (msg->rsp[1] == IPMI_GET_EVENT_RECEIVER_CMD)
2259 + && (msg->rsp[2] == IPMI_CC_NO_ERROR))
2261 + /* A get event receiver command, save it. */
2262 + intf->event_receiver = msg->rsp[3];
2263 + intf->event_receiver_lun = msg->rsp[4] & 0x3;
2267 +static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
2269 + if ((msg->rsp[0] == (IPMI_NETFN_APP_RESPONSE << 2))
2270 + && (msg->rsp[1] == IPMI_GET_DEVICE_ID_CMD)
2271 + && (msg->rsp[2] == IPMI_CC_NO_ERROR))
2273 + /* A get device id command, save if we are an event
2274 + receiver or generator. */
2275 + intf->local_sel_device = (msg->rsp[8] >> 2) & 1;
2276 + intf->local_event_generator = (msg->rsp[8] >> 5) & 1;
2281 +static void send_panic_events(char *str)
2283 struct ipmi_msg msg;
2285 - unsigned char data[8];
2286 + unsigned char data[16];
2288 - struct ipmi_system_interface_addr addr;
2289 + struct ipmi_system_interface_addr *si;
2290 + struct ipmi_addr addr;
2291 struct ipmi_smi_msg smi_msg;
2292 struct ipmi_recv_msg recv_msg;
2294 - addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2295 - addr.channel = IPMI_BMC_CHANNEL;
2296 + si = (struct ipmi_system_interface_addr *) &addr;
2297 + si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2298 + si->channel = IPMI_BMC_CHANNEL;
2301 /* Fill in an event telling that we have failed. */
2302 msg.netfn = 0x04; /* Sensor or Event. */
2303 @@ -1846,12 +2266,13 @@
2304 data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */
2305 data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */
2307 - /* These used to have the first three bytes of the panic string,
2308 - but not only is that not terribly useful, it's not available
2313 + /* Put a few breadcrums in. Hopefully later we can add more things
2314 + to make the panic events more useful. */
2321 smi_msg.done = dummy_smi_done_handler;
2322 recv_msg.done = dummy_recv_done_handler;
2323 @@ -1862,18 +2283,147 @@
2327 + /* Send the event announcing the panic. */
2328 intf->handlers->set_run_to_completion(intf->send_info, 1);
2329 i_ipmi_request(NULL,
2331 - (struct ipmi_addr *) &addr,
2341 + 0, 1); /* Don't retry, and don't wait. */
2344 +#ifdef CONFIG_IPMI_PANIC_STRING
2345 + /* On every interface, dump a bunch of OEM event holding the
2350 + for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2352 + struct ipmi_ipmb_addr *ipmb;
2355 + intf = ipmi_interfaces[i];
2359 + /* First job here is to figure out where to send the
2360 + OEM events. There's no way in IPMI to send OEM
2361 + events using an event send command, so we have to
2362 + find the SEL to put them in and stick them in
2365 + /* Get capabilities from the get device id. */
2366 + intf->local_sel_device = 0;
2367 + intf->local_event_generator = 0;
2368 + intf->event_receiver = 0;
2370 + /* Request the device info from the local MC. */
2371 + msg.netfn = IPMI_NETFN_APP_REQUEST;
2372 + msg.cmd = IPMI_GET_DEVICE_ID_CMD;
2375 + intf->null_user_handler = device_id_fetcher;
2376 + i_ipmi_request(NULL,
2386 + 0, 1); /* Don't retry, and don't wait. */
2388 + if (intf->local_event_generator) {
2389 + /* Request the event receiver from the local MC. */
2390 + msg.netfn = IPMI_NETFN_SENSOR_EVENT_REQUEST;
2391 + msg.cmd = IPMI_GET_EVENT_RECEIVER_CMD;
2394 + intf->null_user_handler = event_receiver_fetcher;
2395 + i_ipmi_request(NULL,
2405 + 0, 1); /* no retry, and no wait. */
2407 + intf->null_user_handler = NULL;
2409 + /* Validate the event receiver. The low bit must not
2410 + be 1 (it must be a valid IPMB address), it cannot
2411 + be zero, and it must not be my address. */
2412 + if (((intf->event_receiver & 1) == 0)
2413 + && (intf->event_receiver != 0)
2414 + && (intf->event_receiver != intf->my_address))
2416 + /* The event receiver is valid, send an IPMB
2418 + ipmb = (struct ipmi_ipmb_addr *) &addr;
2419 + ipmb->addr_type = IPMI_IPMB_ADDR_TYPE;
2420 + ipmb->channel = 0; /* FIXME - is this right? */
2421 + ipmb->lun = intf->event_receiver_lun;
2422 + ipmb->slave_addr = intf->event_receiver;
2423 + } else if (intf->local_sel_device) {
2424 + /* The event receiver was not valid (or was
2425 + me), but I am an SEL device, just dump it
2427 + si = (struct ipmi_system_interface_addr *) &addr;
2428 + si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2429 + si->channel = IPMI_BMC_CHANNEL;
2432 + continue; /* No where to send the event. */
2435 + msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */
2436 + msg.cmd = IPMI_ADD_SEL_ENTRY_CMD;
2438 + msg.data_len = 16;
2442 + int size = strlen(p);
2448 + data[2] = 0xf0; /* OEM event without timestamp. */
2449 + data[3] = intf->my_address;
2450 + data[4] = j++; /* sequence # */
2451 + /* Always give 11 bytes, so strncpy will fill
2452 + it with zeroes for me. */
2453 + strncpy(data+5, p, 11);
2456 + i_ipmi_request(NULL,
2466 + 0, 1); /* no retry, and no wait. */
2469 +#endif /* CONFIG_IPMI_PANIC_STRING */
2471 #endif /* CONFIG_IPMI_PANIC_EVENT */
2473 @@ -1900,7 +2450,7 @@
2476 #ifdef CONFIG_IPMI_PANIC_EVENT
2477 - send_panic_events();
2478 + send_panic_events(ptr);
2482 @@ -1912,7 +2462,6 @@
2483 200 /* priority: INT_MAX >= x >= 0 */
2487 static __init int ipmi_init_msghandler(void)
2490 @@ -1920,10 +2469,21 @@
2494 + printk(KERN_INFO "ipmi message handler version "
2495 + IPMI_MSGHANDLER_VERSION "\n");
2497 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2498 ipmi_interfaces[i] = NULL;
2501 + proc_ipmi_root = proc_mkdir("ipmi", 0);
2502 + if (!proc_ipmi_root) {
2503 + printk("Unable to create IPMI proc dir\n");
2507 + proc_ipmi_root->owner = THIS_MODULE;
2509 init_timer(&ipmi_timer);
2510 ipmi_timer.data = 0;
2511 ipmi_timer.function = ipmi_timeout;
2512 @@ -1934,8 +2494,6 @@
2516 - printk(KERN_INFO "ipmi: message handler initialized\n");
2521 @@ -1980,6 +2538,7 @@
2522 EXPORT_SYMBOL(ipmi_destroy_user);
2523 EXPORT_SYMBOL(ipmi_get_version);
2524 EXPORT_SYMBOL(ipmi_request);
2525 +EXPORT_SYMBOL(ipmi_request_settime);
2526 EXPORT_SYMBOL(ipmi_request_supply_msgs);
2527 EXPORT_SYMBOL(ipmi_request_with_source);
2528 EXPORT_SYMBOL(ipmi_register_smi);
2529 @@ -2001,3 +2560,4 @@
2530 EXPORT_SYMBOL(ipmi_get_my_address);
2531 EXPORT_SYMBOL(ipmi_set_my_LUN);
2532 EXPORT_SYMBOL(ipmi_get_my_LUN);
2533 +EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
2534 diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_si.c linux-2.4.23/drivers/char/ipmi/ipmi_si.c
2535 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_si.c 1970-01-01 01:00:00.000000000 +0100
2536 +++ linux-2.4.23/drivers/char/ipmi/ipmi_si.c 2003-12-06 17:46:43.002453092 +0100
2541 + * The interface to the IPMI driver for the system interfaces (KCS, SMIC,
2542 + * BT in the future).
2544 + * Author: MontaVista Software, Inc.
2545 + * Corey Minyard <minyard@mvista.com>
2546 + * source@mvista.com
2548 + * Copyright 2002 MontaVista Software Inc.
2550 + * This program is free software; you can redistribute it and/or modify it
2551 + * under the terms of the GNU General Public License as published by the
2552 + * Free Software Foundation; either version 2 of the License, or (at your
2553 + * option) any later version.
2556 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
2557 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
2558 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2559 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2560 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
2561 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
2562 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
2563 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
2564 + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
2565 + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2567 + * You should have received a copy of the GNU General Public License along
2568 + * with this program; if not, write to the Free Software Foundation, Inc.,
2569 + * 675 Mass Ave, Cambridge, MA 02139, USA.
2573 + * This file holds the "policy" for the interface to the SMI state
2574 + * machine. It does the configuration, handles timers and interrupts,
2575 + * and drives the real SMI state machine.
2578 +#include <linux/config.h>
2579 +#include <linux/module.h>
2580 +#include <asm/system.h>
2581 +#include <linux/sched.h>
2582 +#include <linux/timer.h>
2583 +#include <linux/errno.h>
2584 +#include <linux/spinlock.h>
2585 +#include <linux/slab.h>
2586 +#include <linux/delay.h>
2587 +#include <linux/list.h>
2588 +#include <linux/ioport.h>
2589 +#ifdef CONFIG_HIGH_RES_TIMERS
2590 +#include <linux/hrtime.h>
2591 +# if defined(schedule_next_int)
2592 +/* Old high-res timer code, do translations. */
2593 +# define get_arch_cycles(a) quick_update_jiffies_sub(a)
2594 +# define arch_cycles_per_jiffy cycles_per_jiffies
2596 +static inline void add_usec_to_timer(struct timer_list *t, long v)
2598 + t->sub_expires += nsec_to_arch_cycle(v * 1000);
2599 + while (t->sub_expires >= arch_cycles_per_jiffy)
2602 + t->sub_expires -= arch_cycles_per_jiffy;
2606 +#include <linux/interrupt.h>
2607 +#include <linux/ipmi_smi.h>
2608 +#include <asm/io.h>
2609 +#include "ipmi_si_sm.h"
2610 +#include <linux/init.h>
2612 +#define IPMI_SI_VERSION "v27"
2614 +/* Measure times between events in the driver. */
2615 +#undef DEBUG_TIMING
2617 +/* Call every 10 ms when nothing is going on. */
2618 +#define SI_TIMEOUT_TIME_USEC 10000
2619 +#define SI_USEC_PER_JIFFY (1000000/HZ)
2620 +#define SI_TIMEOUT_JIFFIES (SI_TIMEOUT_TIME_USEC/SI_USEC_PER_JIFFY)
2621 +#define SI_SHORT_TIMEOUT_USEC 250 /* .25ms when the SM request a
2624 +enum si_intf_state {
2627 + SI_GETTING_EVENTS,
2628 + SI_CLEARING_FLAGS,
2629 + SI_CLEARING_FLAGS_THEN_SET_IRQ,
2630 + SI_GETTING_MESSAGES,
2631 + SI_ENABLE_INTERRUPTS1,
2632 + SI_ENABLE_INTERRUPTS2
2633 + /* FIXME - add watchdog stuff. */
2637 + SI_KCS, SI_SMIC, SI_BT
2643 + struct si_sm_data *si_sm;
2644 + struct si_sm_handlers *handlers;
2645 + enum si_type si_type;
2646 + spinlock_t si_lock;
2647 + spinlock_t msg_lock;
2648 + struct list_head xmit_msgs;
2649 + struct list_head hp_xmit_msgs;
2650 + struct ipmi_smi_msg *curr_msg;
2651 + enum si_intf_state si_state;
2653 + /* Used to handle the various types of I/O that can occur with
2655 + struct si_sm_io io;
2656 + int (*io_setup)(struct smi_info *info);
2657 + void (*io_cleanup)(struct smi_info *info);
2658 + int (*irq_setup)(struct smi_info *info);
2659 + void (*irq_cleanup)(struct smi_info *info);
2660 + unsigned int io_size;
2662 + /* Flags from the last GET_MSG_FLAGS command, used when an ATTN
2663 + is set to hold the flags until we are done handling everything
2664 + from the flags. */
2665 +#define RECEIVE_MSG_AVAIL 0x01
2666 +#define EVENT_MSG_BUFFER_FULL 0x02
2667 +#define WDT_PRE_TIMEOUT_INT 0x08
2668 + unsigned char msg_flags;
2670 + /* If set to true, this will request events the next time the
2671 + state machine is idle. */
2672 + atomic_t req_events;
2674 + /* If true, run the state machine to completion on every send
2675 + call. Generally used after a panic to make sure stuff goes
2677 + int run_to_completion;
2679 + /* The I/O port of an SI interface. */
2682 + /* zero if no irq; */
2685 + /* The physical and remapped memory addresses of a SI interface. */
2686 + unsigned long physaddr;
2687 + unsigned char *addr;
2689 + /* The timer for this si. */
2690 + struct timer_list si_timer;
2692 + /* The time (in jiffies) the last timeout occurred at. */
2693 + unsigned long last_timeout_jiffies;
2695 + /* Used to gracefully stop the timer without race conditions. */
2696 + volatile int stop_operation;
2697 + volatile int timer_stopped;
2699 + /* The driver will disable interrupts when it gets into a
2700 + situation where it cannot handle messages due to lack of
2701 + memory. Once that situation clears up, it will re-enable
2703 + int interrupt_disabled;
2705 + unsigned char ipmi_si_dev_rev;
2706 + unsigned char ipmi_si_fw_rev_major;
2707 + unsigned char ipmi_si_fw_rev_minor;
2708 + unsigned char ipmi_version_major;
2709 + unsigned char ipmi_version_minor;
2711 + /* Counters and things for the proc filesystem. */
2712 + spinlock_t count_lock;
2713 + unsigned long short_timeouts;
2714 + unsigned long long_timeouts;
2715 + unsigned long timeout_restarts;
2716 + unsigned long idles;
2717 + unsigned long interrupts;
2718 + unsigned long attentions;
2719 + unsigned long flag_fetches;
2720 + unsigned long hosed_count;
2721 + unsigned long complete_transactions;
2722 + unsigned long events;
2723 + unsigned long watchdog_pretimeouts;
2724 + unsigned long incoming_messages;
2727 +static void si_restart_short_timer(struct smi_info *smi_info);
2729 +static void deliver_recv_msg(struct smi_info *smi_info,
2730 + struct ipmi_smi_msg *msg)
2732 + /* Deliver the message to the upper layer with the lock
2734 + spin_unlock(&(smi_info->si_lock));
2735 + ipmi_smi_msg_received(smi_info->intf, msg);
2736 + spin_lock(&(smi_info->si_lock));
2739 +static void return_hosed_msg(struct smi_info *smi_info)
2741 + struct ipmi_smi_msg *msg = smi_info->curr_msg;
2743 + /* Make it a reponse */
2744 + msg->rsp[0] = msg->data[0] | 4;
2745 + msg->rsp[1] = msg->data[1];
2746 + msg->rsp[2] = 0xFF; /* Unknown error. */
2747 + msg->rsp_size = 3;
2749 + smi_info->curr_msg = NULL;
2750 + deliver_recv_msg(smi_info, msg);
2753 +static enum si_sm_result start_next_msg(struct smi_info *smi_info)
2756 + struct list_head *entry = NULL;
2757 +#ifdef DEBUG_TIMING
2761 + /* No need to save flags, we aleady have interrupts off and we
2762 + already hold the SMI lock. */
2763 + spin_lock(&(smi_info->msg_lock));
2765 + /* Pick the high priority queue first. */
2766 + if (! list_empty(&(smi_info->hp_xmit_msgs))) {
2767 + entry = smi_info->hp_xmit_msgs.next;
2768 + } else if (! list_empty(&(smi_info->xmit_msgs))) {
2769 + entry = smi_info->xmit_msgs.next;
2773 + smi_info->curr_msg = NULL;
2779 + smi_info->curr_msg = list_entry(entry,
2780 + struct ipmi_smi_msg,
2782 +#ifdef DEBUG_TIMING
2783 + do_gettimeofday(&t);
2784 + printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
2786 + err = smi_info->handlers->start_transaction(
2788 + smi_info->curr_msg->data,
2789 + smi_info->curr_msg->data_size);
2791 + return_hosed_msg(smi_info);
2794 + rv = SI_SM_CALL_WITHOUT_DELAY;
2796 + spin_unlock(&(smi_info->msg_lock));
2801 +static void start_enable_irq(struct smi_info *smi_info)
2803 + unsigned char msg[2];
2805 + /* If we are enabling interrupts, we have to tell the
2806 + BMC to use them. */
2807 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
2808 + msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
2810 + smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
2811 + smi_info->si_state = SI_ENABLE_INTERRUPTS1;
2814 +static void start_clear_flags(struct smi_info *smi_info)
2816 + unsigned char msg[3];
2818 + /* Make sure the watchdog pre-timeout flag is not set at startup. */
2819 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
2820 + msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
2821 + msg[2] = WDT_PRE_TIMEOUT_INT;
2823 + smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
2824 + smi_info->si_state = SI_CLEARING_FLAGS;
2827 +/* When we have a situtaion where we run out of memory and cannot
2828 + allocate messages, we just leave them in the BMC and run the system
2829 + polled until we can allocate some memory. Once we have some
2830 + memory, we will re-enable the interrupt. */
2831 +static inline void disable_si_irq(struct smi_info *smi_info)
2833 + if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
2834 + disable_irq_nosync(smi_info->irq);
2835 + smi_info->interrupt_disabled = 1;
2839 +static inline void enable_si_irq(struct smi_info *smi_info)
2841 + if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
2842 + enable_irq(smi_info->irq);
2843 + smi_info->interrupt_disabled = 0;
2847 +static void handle_flags(struct smi_info *smi_info)
2849 + if (smi_info->msg_flags & WDT_PRE_TIMEOUT_INT) {
2850 + /* Watchdog pre-timeout */
2851 + spin_lock(&smi_info->count_lock);
2852 + smi_info->watchdog_pretimeouts++;
2853 + spin_unlock(&smi_info->count_lock);
2855 + start_clear_flags(smi_info);
2856 + smi_info->msg_flags &= ~WDT_PRE_TIMEOUT_INT;
2857 + spin_unlock(&(smi_info->si_lock));
2858 + ipmi_smi_watchdog_pretimeout(smi_info->intf);
2859 + spin_lock(&(smi_info->si_lock));
2860 + } else if (smi_info->msg_flags & RECEIVE_MSG_AVAIL) {
2861 + /* Messages available. */
2862 + smi_info->curr_msg = ipmi_alloc_smi_msg();
2863 + if (!smi_info->curr_msg) {
2864 + disable_si_irq(smi_info);
2865 + smi_info->si_state = SI_NORMAL;
2868 + enable_si_irq(smi_info);
2870 + smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
2871 + smi_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
2872 + smi_info->curr_msg->data_size = 2;
2874 + smi_info->handlers->start_transaction(
2876 + smi_info->curr_msg->data,
2877 + smi_info->curr_msg->data_size);
2878 + smi_info->si_state = SI_GETTING_MESSAGES;
2879 + } else if (smi_info->msg_flags & EVENT_MSG_BUFFER_FULL) {
2880 + /* Events available. */
2881 + smi_info->curr_msg = ipmi_alloc_smi_msg();
2882 + if (!smi_info->curr_msg) {
2883 + disable_si_irq(smi_info);
2884 + smi_info->si_state = SI_NORMAL;
2887 + enable_si_irq(smi_info);
2889 + smi_info->curr_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
2890 + smi_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
2891 + smi_info->curr_msg->data_size = 2;
2893 + smi_info->handlers->start_transaction(
2895 + smi_info->curr_msg->data,
2896 + smi_info->curr_msg->data_size);
2897 + smi_info->si_state = SI_GETTING_EVENTS;
2899 + smi_info->si_state = SI_NORMAL;
2903 +static void handle_transaction_done(struct smi_info *smi_info)
2905 + struct ipmi_smi_msg *msg;
2906 +#ifdef DEBUG_TIMING
2909 + do_gettimeofday(&t);
2910 + printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec);
2912 + switch (smi_info->si_state) {
2914 + if (!smi_info->curr_msg)
2917 + smi_info->curr_msg->rsp_size
2918 + = smi_info->handlers->get_result(
2920 + smi_info->curr_msg->rsp,
2921 + IPMI_MAX_MSG_LENGTH);
2923 + /* Do this here becase deliver_recv_msg() releases the
2924 + lock, and a new message can be put in during the
2925 + time the lock is released. */
2926 + msg = smi_info->curr_msg;
2927 + smi_info->curr_msg = NULL;
2928 + deliver_recv_msg(smi_info, msg);
2931 + case SI_GETTING_FLAGS:
2933 + unsigned char msg[4];
2936 + /* We got the flags from the SMI, now handle them. */
2937 + len = smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
2938 + if (msg[2] != 0) {
2939 + /* Error fetching flags, just give up for
2941 + smi_info->si_state = SI_NORMAL;
2942 + } else if (len < 3) {
2943 + /* Hmm, no flags. That's technically illegal, but
2944 + don't use uninitialized data. */
2945 + smi_info->si_state = SI_NORMAL;
2947 + smi_info->msg_flags = msg[3];
2948 + handle_flags(smi_info);
2953 + case SI_CLEARING_FLAGS:
2954 + case SI_CLEARING_FLAGS_THEN_SET_IRQ:
2956 + unsigned char msg[3];
2958 + /* We cleared the flags. */
2959 + smi_info->handlers->get_result(smi_info->si_sm, msg, 3);
2960 + if (msg[2] != 0) {
2961 + /* Error clearing flags */
2962 + printk(KERN_WARNING
2963 + "ipmi_smi: Error clearing flags: %2.2x\n",
2966 + if (smi_info->si_state == SI_CLEARING_FLAGS_THEN_SET_IRQ)
2967 + start_enable_irq(smi_info);
2969 + smi_info->si_state = SI_NORMAL;
2973 + case SI_GETTING_EVENTS:
2975 + smi_info->curr_msg->rsp_size
2976 + = smi_info->handlers->get_result(
2978 + smi_info->curr_msg->rsp,
2979 + IPMI_MAX_MSG_LENGTH);
2981 + /* Do this here becase deliver_recv_msg() releases the
2982 + lock, and a new message can be put in during the
2983 + time the lock is released. */
2984 + msg = smi_info->curr_msg;
2985 + smi_info->curr_msg = NULL;
2986 + if (msg->rsp[2] != 0) {
2987 + /* Error getting event, probably done. */
2990 + /* Take off the event flag. */
2991 + smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
2993 + spin_lock(&smi_info->count_lock);
2994 + smi_info->events++;
2995 + spin_unlock(&smi_info->count_lock);
2997 + deliver_recv_msg(smi_info, msg);
2999 + handle_flags(smi_info);
3003 + case SI_GETTING_MESSAGES:
3005 + smi_info->curr_msg->rsp_size
3006 + = smi_info->handlers->get_result(
3008 + smi_info->curr_msg->rsp,
3009 + IPMI_MAX_MSG_LENGTH);
3011 + /* Do this here becase deliver_recv_msg() releases the
3012 + lock, and a new message can be put in during the
3013 + time the lock is released. */
3014 + msg = smi_info->curr_msg;
3015 + smi_info->curr_msg = NULL;
3016 + if (msg->rsp[2] != 0) {
3017 + /* Error getting event, probably done. */
3020 + /* Take off the msg flag. */
3021 + smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
3023 + spin_lock(&smi_info->count_lock);
3024 + smi_info->incoming_messages++;
3025 + spin_unlock(&smi_info->count_lock);
3027 + deliver_recv_msg(smi_info, msg);
3029 + handle_flags(smi_info);
3033 + case SI_ENABLE_INTERRUPTS1:
3035 + unsigned char msg[4];
3037 + /* We got the flags from the SMI, now handle them. */
3038 + smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
3039 + if (msg[2] != 0) {
3040 + printk(KERN_WARNING
3041 + "ipmi_smi: Could not enable interrupts"
3042 + ", failed get, using polled mode.\n");
3043 + smi_info->si_state = SI_NORMAL;
3045 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3046 + msg[1] = IPMI_SET_BMC_GLOBAL_ENABLES_CMD;
3047 + msg[2] = msg[3] | 1; /* enable msg queue int */
3048 + smi_info->handlers->start_transaction(
3049 + smi_info->si_sm, msg, 3);
3050 + smi_info->si_state = SI_ENABLE_INTERRUPTS2;
3055 + case SI_ENABLE_INTERRUPTS2:
3057 + unsigned char msg[4];
3059 + /* We got the flags from the SMI, now handle them. */
3060 + smi_info->handlers->get_result(smi_info->si_sm, msg, 4);
3061 + if (msg[2] != 0) {
3062 + printk(KERN_WARNING
3063 + "ipmi_smi: Could not enable interrupts"
3064 + ", failed set, using polled mode.\n");
3066 + smi_info->si_state = SI_NORMAL;
3072 +/* Called on timeouts and events. Timeouts should pass the elapsed
3073 + time, interrupts should pass in zero. */
3074 +static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
3077 + enum si_sm_result si_sm_result;
3080 + /* There used to be a loop here that waited a little while
3081 + (around 25us) before giving up. That turned out to be
3082 + pointless, the minimum delays I was seeing were in the 300us
3083 + range, which is far too long to wait in an interrupt. So
3084 + we just run until the state machine tells us something
3085 + happened or it needs a delay. */
3086 + si_sm_result = smi_info->handlers->event(smi_info->si_sm, time);
3088 + while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY)
3090 + si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3093 + if (si_sm_result == SI_SM_TRANSACTION_COMPLETE)
3095 + spin_lock(&smi_info->count_lock);
3096 + smi_info->complete_transactions++;
3097 + spin_unlock(&smi_info->count_lock);
3099 + handle_transaction_done(smi_info);
3100 + si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3102 + else if (si_sm_result == SI_SM_HOSED)
3104 + spin_lock(&smi_info->count_lock);
3105 + smi_info->hosed_count++;
3106 + spin_unlock(&smi_info->count_lock);
3108 + if (smi_info->curr_msg != NULL) {
3109 + /* If we were handling a user message, format
3110 + a response to send to the upper layer to
3111 + tell it about the error. */
3112 + return_hosed_msg(smi_info);
3114 + si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3115 + smi_info->si_state = SI_NORMAL;
3118 + /* We prefer handling attn over new messages. */
3119 + if (si_sm_result == SI_SM_ATTN)
3121 + unsigned char msg[2];
3123 + spin_lock(&smi_info->count_lock);
3124 + smi_info->attentions++;
3125 + spin_unlock(&smi_info->count_lock);
3127 + /* Got a attn, send down a get message flags to see
3128 + what's causing it. It would be better to handle
3129 + this in the upper layer, but due to the way
3130 + interrupts work with the SMI, that's not really
3132 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3133 + msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3135 + smi_info->handlers->start_transaction(
3136 + smi_info->si_sm, msg, 2);
3137 + smi_info->si_state = SI_GETTING_FLAGS;
3141 + /* If we are currently idle, try to start the next message. */
3142 + if (si_sm_result == SI_SM_IDLE) {
3143 + spin_lock(&smi_info->count_lock);
3144 + smi_info->idles++;
3145 + spin_unlock(&smi_info->count_lock);
3147 + si_sm_result = start_next_msg(smi_info);
3148 + if (si_sm_result != SI_SM_IDLE)
3152 + if ((si_sm_result == SI_SM_IDLE)
3153 + && (atomic_read(&smi_info->req_events)))
3155 + /* We are idle and the upper layer requested that I fetch
3156 + events, so do so. */
3157 + unsigned char msg[2];
3159 + spin_lock(&smi_info->count_lock);
3160 + smi_info->flag_fetches++;
3161 + spin_unlock(&smi_info->count_lock);
3163 + atomic_set(&smi_info->req_events, 0);
3164 + msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3165 + msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3167 + smi_info->handlers->start_transaction(
3168 + smi_info->si_sm, msg, 2);
3169 + smi_info->si_state = SI_GETTING_FLAGS;
3173 + return si_sm_result;
3176 +static void sender(void *send_info,
3177 + struct ipmi_smi_msg *msg,
3180 + struct smi_info *smi_info = (struct smi_info *) send_info;
3181 + enum si_sm_result result;
3182 + unsigned long flags;
3183 +#ifdef DEBUG_TIMING
3187 + spin_lock_irqsave(&(smi_info->msg_lock), flags);
3188 +#ifdef DEBUG_TIMING
3189 + do_gettimeofday(&t);
3190 + printk("**Enqueue: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3193 + if (smi_info->run_to_completion) {
3194 + /* If we are running to completion, then throw it in
3195 + the list and run transactions until everything is
3196 + clear. Priority doesn't matter here. */
3197 + list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
3199 + /* We have to release the msg lock and claim the smi
3200 + lock in this case, because of race conditions. */
3201 + spin_unlock_irqrestore(&(smi_info->msg_lock), flags);
3203 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3204 + result = smi_event_handler(smi_info, 0);
3205 + while (result != SI_SM_IDLE) {
3206 + udelay(SI_SHORT_TIMEOUT_USEC);
3207 + result = smi_event_handler(smi_info,
3208 + SI_SHORT_TIMEOUT_USEC);
3210 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3213 + if (priority > 0) {
3214 + list_add_tail(&(msg->link), &(smi_info->hp_xmit_msgs));
3216 + list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
3219 + spin_unlock_irqrestore(&(smi_info->msg_lock), flags);
3221 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3222 + if ((smi_info->si_state == SI_NORMAL)
3223 + && (smi_info->curr_msg == NULL))
3225 + start_next_msg(smi_info);
3226 + si_restart_short_timer(smi_info);
3228 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3231 +static void set_run_to_completion(void *send_info, int i_run_to_completion)
3233 + struct smi_info *smi_info = (struct smi_info *) send_info;
3234 + enum si_sm_result result;
3235 + unsigned long flags;
3237 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3239 + smi_info->run_to_completion = i_run_to_completion;
3240 + if (i_run_to_completion) {
3241 + result = smi_event_handler(smi_info, 0);
3242 + while (result != SI_SM_IDLE) {
3243 + udelay(SI_SHORT_TIMEOUT_USEC);
3244 + result = smi_event_handler(smi_info,
3245 + SI_SHORT_TIMEOUT_USEC);
3249 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3252 +static void request_events(void *send_info)
3254 + struct smi_info *smi_info = (struct smi_info *) send_info;
3256 + atomic_set(&smi_info->req_events, 1);
3259 +static int new_user(void *send_info)
3261 + if (!try_inc_mod_count(THIS_MODULE))
3266 +static void user_left(void *send_info)
3268 + MOD_DEC_USE_COUNT;
3271 +static int initialized = 0;
3273 +/* Must be called with interrupts off and with the si_lock held. */
3274 +static void si_restart_short_timer(struct smi_info *smi_info)
3276 +#if defined(CONFIG_HIGH_RES_TIMERS)
3277 + unsigned long flags;
3278 + unsigned long jiffies_now;
3280 + if (del_timer(&(smi_info->si_timer))) {
3281 + /* If we don't delete the timer, then it will go off
3282 + immediately, anyway. So we only process if we
3283 + actually delete the timer. */
3285 + /* We already have irqsave on, so no need for it
3287 + read_lock(&xtime_lock);
3288 + jiffies_now = jiffies;
3289 + smi_info->si_timer.expires = jiffies_now;
3290 + smi_info->si_timer.sub_expires = get_arch_cycles(jiffies_now);
3291 + read_unlock(&xtime_lock);
3293 + add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
3295 + add_timer(&(smi_info->si_timer));
3296 + spin_lock_irqsave(&smi_info->count_lock, flags);
3297 + smi_info->timeout_restarts++;
3298 + spin_unlock_irqrestore(&smi_info->count_lock, flags);
3303 +static void smi_timeout(unsigned long data)
3305 + struct smi_info *smi_info = (struct smi_info *) data;
3306 + enum si_sm_result smi_result;
3307 + unsigned long flags;
3308 + unsigned long jiffies_now;
3309 + unsigned long time_diff;
3310 +#ifdef DEBUG_TIMING
3314 + if (smi_info->stop_operation) {
3315 + smi_info->timer_stopped = 1;
3319 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3320 +#ifdef DEBUG_TIMING
3321 + do_gettimeofday(&t);
3322 + printk("**Timer: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3324 + jiffies_now = jiffies;
3325 + time_diff = ((jiffies_now - smi_info->last_timeout_jiffies)
3326 + * SI_USEC_PER_JIFFY);
3327 + smi_result = smi_event_handler(smi_info, time_diff);
3329 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3331 + smi_info->last_timeout_jiffies = jiffies_now;
3333 + if ((smi_info->irq) && (! smi_info->interrupt_disabled)) {
3334 + /* Running with interrupts, only do long timeouts. */
3335 + smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
3336 + spin_lock_irqsave(&smi_info->count_lock, flags);
3337 + smi_info->long_timeouts++;
3338 + spin_unlock_irqrestore(&smi_info->count_lock, flags);
3339 + goto do_add_timer;
3342 + /* If the state machine asks for a short delay, then shorten
3343 + the timer timeout. */
3344 + if (smi_result == SI_SM_CALL_WITH_DELAY) {
3345 + spin_lock_irqsave(&smi_info->count_lock, flags);
3346 + smi_info->short_timeouts++;
3347 + spin_unlock_irqrestore(&smi_info->count_lock, flags);
3348 +#if defined(CONFIG_HIGH_RES_TIMERS)
3349 + add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
3351 + smi_info->si_timer.expires = jiffies + 1;
3354 + spin_lock_irqsave(&smi_info->count_lock, flags);
3355 + smi_info->long_timeouts++;
3356 + spin_unlock_irqrestore(&smi_info->count_lock, flags);
3357 + smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
3358 +#if defined(CONFIG_HIGH_RES_TIMERS)
3359 + smi_info->si_timer.sub_expires = 0;
3364 + add_timer(&(smi_info->si_timer));
3367 +static void si_irq_handler(int irq, void *data, struct pt_regs *regs)
3369 + struct smi_info *smi_info = (struct smi_info *) data;
3370 + unsigned long flags;
3371 +#ifdef DEBUG_TIMING
3375 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3377 + spin_lock(&smi_info->count_lock);
3378 + smi_info->interrupts++;
3379 + spin_unlock(&smi_info->count_lock);
3381 + if (smi_info->stop_operation)
3384 +#ifdef DEBUG_TIMING
3385 + do_gettimeofday(&t);
3386 + printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3388 + smi_event_handler(smi_info, 0);
3390 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3393 +static struct ipmi_smi_handlers handlers =
3396 + request_events: request_events,
3397 + new_user: new_user,
3398 + user_left: user_left,
3399 + set_run_to_completion: set_run_to_completion
3402 +/* There can be 4 IO ports passed in (with or without IRQs), 4 addresses,
3403 + a default IO port, and 1 ACPI/SPMI address. That sets SI_MAX_DRIVERS */
3405 +#define SI_MAX_PARMS 4
3406 +#define SI_MAX_DRIVERS ((SI_MAX_PARMS * 2) + 2)
3407 +static struct smi_info *smi_infos[SI_MAX_DRIVERS] =
3408 +{ NULL, NULL, NULL, NULL };
3410 +#define DEVICE_NAME "ipmi_si"
3412 +#define DEFAULT_KCS_IO_PORT 0xca2
3413 +#define DEFAULT_SMIC_IO_PORT 0xca9
3415 +static int si_trydefaults = 1;
3416 +static char *si_type[SI_MAX_PARMS] = { NULL, NULL, NULL, NULL };
3417 +static unsigned long si_addrs[SI_MAX_PARMS] = { 0, 0, 0, 0 };
3418 +static unsigned int si_ports[SI_MAX_PARMS] = { 0, 0, 0, 0 };
3419 +static int si_irqs[SI_MAX_PARMS] = { 0, 0, 0, 0 };
3422 +MODULE_PARM(si_trydefaults, "i");
3423 +MODULE_PARM(si_type, "1-4s");
3424 +MODULE_PARM(si_addrs, "1-4l");
3425 +MODULE_PARM(si_irqs, "1-4i");
3426 +MODULE_PARM(si_ports, "1-4i");
3429 +static int std_irq_setup(struct smi_info *info)
3436 + rv = request_irq(info->irq,
3442 + printk(KERN_WARNING
3443 + "ipmi_smi: %s unable to claim interrupt %d,"
3444 + " running polled\n",
3445 + DEVICE_NAME, info->irq);
3448 + printk(" Using irq %d\n", info->irq);
3454 +static void std_irq_cleanup(struct smi_info *info)
3459 + free_irq(info->irq, info);
3462 +static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
3464 + unsigned int *addr = io->info;
3466 + return inb((*addr)+offset);
3469 +static void port_outb(struct si_sm_io *io, unsigned int offset,
3472 + unsigned int *addr = io->info;
3474 + outb(b, (*addr)+offset);
3477 +static int port_setup(struct smi_info *info)
3479 + unsigned int *addr = info->io.info;
3481 + if (!addr || (!*addr))
3484 + if (request_region(*addr, info->io_size, DEVICE_NAME) == NULL)
3489 +static void port_cleanup(struct smi_info *info)
3491 + unsigned int *addr = info->io.info;
3493 + if (addr && (*addr))
3494 + release_region (*addr, info->io_size);
3498 +static int try_init_port(int intf_num, struct smi_info **new_info)
3500 + struct smi_info *info;
3502 + if (!si_ports[intf_num])
3505 + info = kmalloc(sizeof(*info), GFP_KERNEL);
3507 + printk("ipmi_smi: Could not allocate SMI data\n");
3510 + memset(info, 0, sizeof(*info));
3512 + info->io_setup = port_setup;
3513 + info->io_cleanup = port_cleanup;
3514 + info->io.inputb = port_inb;
3515 + info->io.outputb = port_outb;
3516 + info->io.info = &(si_ports[intf_num]);
3518 + info->irq_setup = NULL;
3521 + printk("ipmi_smi: Trying state machine at I/O address 0x%x\n",
3522 + si_ports[intf_num]);
3526 +static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
3528 + return readb((io->addr)+offset);
3531 +static void mem_outb(struct si_sm_io *io, unsigned int offset,
3534 + writeb(b, (io->addr)+offset);
3537 +static int mem_setup(struct smi_info *info)
3539 + unsigned long *addr = info->io.info;
3541 + if (!addr || (!*addr))
3544 + if (request_mem_region(*addr, info->io_size, DEVICE_NAME) == NULL)
3546 + info->io.addr = ioremap(*addr, info->io_size);
3547 + if (info->io.addr == NULL) {
3548 + release_mem_region(*addr, info->io_size);
3554 +static void mem_cleanup(struct smi_info *info)
3556 + unsigned int *addr = info->io.info;
3559 + iounmap(info->addr);
3560 + release_mem_region(*addr, info->io_size);
3565 +static int try_init_mem(int intf_num, struct smi_info **new_info)
3567 + struct smi_info *info;
3569 + if (!si_addrs[intf_num])
3572 + info = kmalloc(sizeof(*info), GFP_KERNEL);
3574 + printk("ipmi_smi: Could not allocate SMI data\n");
3577 + memset(info, 0, sizeof(*info));
3579 + info->io_setup = mem_setup;
3580 + info->io_cleanup = mem_cleanup;
3581 + info->io.inputb = mem_inb;
3582 + info->io.outputb = mem_outb;
3583 + info->io.info = &(si_addrs[intf_num]);
3585 + info->irq_setup = NULL;
3588 + printk("ipmi_smi: Trying state machine at memory address 0x%lx\n",
3589 + si_addrs[intf_num]);
3594 +#ifdef CONFIG_ACPI_INTERPRETER
3596 +#include <linux/acpi.h>
3597 +#include <acpi/acpi.h>
3598 +#include <acpi/actypes.h>
3599 +#include <acpi/actbl.h>
3601 +/* Once we get an ACPI failure, we don't try any more, because we go
3602 + through the tables sequentially. Once we don't find a table, there
3604 +static int acpi_failure = 0;
3606 +/* For GPE-type interrupts. */
3607 +void ipmi_acpi_gpe(void *context)
3609 + struct smi_info *smi_info = context;
3610 + unsigned long flags;
3611 +#ifdef DEBUG_TIMING
3615 + spin_lock_irqsave(&(smi_info->si_lock), flags);
3617 + spin_lock(&smi_info->count_lock);
3618 + smi_info->interrupts++;
3619 + spin_unlock(&smi_info->count_lock);
3621 + if (smi_info->stop_operation)
3624 +#ifdef DEBUG_TIMING
3625 + do_gettimeofday(&t);
3626 + printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3628 + smi_event_handler(smi_info, 0);
3630 + spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3633 +static int acpi_gpe_irq_setup(struct smi_info *info)
3635 + acpi_status status;
3640 + /* FIXME - is level triggered right? */
3641 + status = acpi_install_gpe_handler(NULL,
3643 + ACPI_EVENT_LEVEL_TRIGGERED,
3646 + if (status != AE_OK) {
3647 + printk(KERN_WARNING
3648 + "ipmi_smi: %s unable to claim ACPI GPE %d,"
3649 + " running polled\n",
3650 + DEVICE_NAME, info->irq);
3654 + printk(" Using ACPI GPE %d\n", info->irq);
3660 +static void acpi_gpe_irq_cleanup(struct smi_info *info)
3665 + acpi_remove_gpe_handler(NULL, info->irq, ipmi_acpi_gpe);
3670 + * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf
3679 + s8 OEMRevision[4];
3681 + s8 CreatorRevision[4];
3682 + u8 InterfaceType[2];
3683 + s16 SpecificationRevision;
3686 + * Bit 0 - SCI interrupt supported
3687 + * Bit 1 - I/O APIC/SAPIC
3691 + /* If bit 0 of InterruptType is set, then this is the SCI
3692 + interrupt in the GPEx_STS register. */
3697 + /* If bit 1 of InterruptType is set, then this is the I/O
3698 + APIC/SAPIC interrupt. */
3699 + u32 GlobalSystemInterrupt;
3701 + /* The actual register address. */
3702 + struct acpi_generic_address addr;
3706 + s8 spmi_id[1]; /* A '\0' terminated array starts here. */
3709 +static int try_init_acpi(int intf_num, struct smi_info **new_info)
3711 + struct smi_info *info;
3712 + acpi_status status;
3713 + struct SPMITable *spmi;
3719 + status = acpi_get_firmware_table("SPMI", intf_num+1,
3720 + ACPI_LOGICAL_ADDRESSING,
3721 + (struct acpi_table_header **) &spmi);
3722 + if (status != AE_OK) {
3727 + if (spmi->InterfaceType[0] != 1)
3730 + /* Figure out the interface type. */
3731 + switch (spmi->InterfaceType[1])
3734 + si_type[intf_num] = "kcs";
3737 + case 2: /* SMIC */
3738 + si_type[intf_num] = "smic";
3742 + si_type[intf_num] = "bt";
3746 + printk("ipmi_smi: Unknown ACPI SMI type.\n");
3750 + info = kmalloc(sizeof(*info), GFP_KERNEL);
3752 + printk("ipmi_smi: Could not allocate SMI data\n");
3755 + memset(info, 0, sizeof(*info));
3757 + if (spmi->InterruptType & 1) {
3758 + /* We've got a GPE interrupt. */
3759 + info->irq = spmi->GPE;
3760 + info->irq_setup = acpi_gpe_irq_setup;
3761 + info->irq_cleanup = acpi_gpe_irq_cleanup;
3762 + } else if (spmi->InterruptType & 2) {
3763 + /* We've got an APIC/SAPIC interrupt. */
3764 + info->irq = spmi->GlobalSystemInterrupt;
3765 + info->irq_setup = std_irq_setup;
3766 + info->irq_cleanup = std_irq_cleanup;
3768 + /* Use the default interrupt setting. */
3770 + info->irq_setup = NULL;
3773 + if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
3774 + io_type = "memory";
3775 + info->io_setup = mem_setup;
3776 + info->io_cleanup = mem_cleanup;
3777 + si_addrs[intf_num] = spmi->addr.address;
3778 + info->io.inputb = mem_inb;
3779 + info->io.outputb = mem_outb;
3780 + info->io.info = &(si_addrs[intf_num]);
3781 + } else if (spmi->addr.address_space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
3783 + info->io_setup = port_setup;
3784 + info->io_cleanup = port_cleanup;
3785 + si_ports[intf_num] = spmi->addr.address;
3786 + info->io.inputb = port_inb;
3787 + info->io.outputb = port_outb;
3788 + info->io.info = &(si_ports[intf_num]);
3791 + printk("ipmi_smi: Unknown ACPI I/O Address type.\n");
3797 + printk("ipmi_smi: Found ACPI-specified state machine at %s"
3798 + " address 0x%lx\n",
3799 + io_type, (unsigned long) spmi->addr.address);
3804 +static int try_get_dev_id(struct smi_info *smi_info)
3806 + unsigned char msg[2];
3807 + unsigned char resp[IPMI_MAX_MSG_LENGTH];
3808 + unsigned long resp_len;
3809 + enum si_sm_result smi_result;
3811 + /* Do a Get Device ID command, since it comes back with some
3813 + msg[0] = IPMI_NETFN_APP_REQUEST << 2;
3814 + msg[1] = IPMI_GET_DEVICE_ID_CMD;
3815 + smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
3817 + smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
3820 + if (smi_result == SI_SM_CALL_WITH_DELAY) {
3821 + schedule_timeout(1);
3822 + smi_result = smi_info->handlers->event(
3823 + smi_info->si_sm, 100);
3825 + else if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
3827 + smi_result = smi_info->handlers->event(
3828 + smi_info->si_sm, 0);
3833 + if (smi_result == SI_SM_HOSED)
3834 + /* We couldn't get the state machine to run, so whatever's at
3835 + the port is probably not an IPMI SMI interface. */
3838 + /* Otherwise, we got some data. */
3839 + resp_len = smi_info->handlers->get_result(smi_info->si_sm,
3840 + resp, IPMI_MAX_MSG_LENGTH);
3842 + /* That's odd, it should be longer. */
3845 + if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0))
3846 + /* That's odd, it shouldn't be able to fail. */
3849 + /* Record info from the get device id, in case we need it. */
3850 + smi_info->ipmi_si_dev_rev = resp[4] & 0xf;
3851 + smi_info->ipmi_si_fw_rev_major = resp[5] & 0x7f;
3852 + smi_info->ipmi_si_fw_rev_minor = resp[6];
3853 + smi_info->ipmi_version_major = resp[7] & 0xf;
3854 + smi_info->ipmi_version_minor = resp[7] >> 4;
3859 +extern struct si_sm_handlers kcs_smi_handlers;
3860 +extern struct si_sm_handlers smic_smi_handlers;
3862 +static int type_file_read_proc(char *page, char **start, off_t off,
3863 + int count, int *eof, void *data)
3865 + char *out = (char *) page;
3866 + struct smi_info *smi = data;
3868 + switch (smi->si_type) {
3870 + return sprintf(out, "kcs\n");
3872 + return sprintf(out, "smic\n");
3874 + return sprintf(out, "bt\n");
3880 +static int stat_file_read_proc(char *page, char **start, off_t off,
3881 + int count, int *eof, void *data)
3883 + char *out = (char *) page;
3884 + struct smi_info *smi = data;
3886 + out += sprintf(out, "interrupts_enabled: %d\n",
3887 + smi->irq && !smi->interrupt_disabled);
3888 + out += sprintf(out, "short_timeouts: %ld\n",
3889 + smi->short_timeouts);
3890 + out += sprintf(out, "long_timeouts: %ld\n",
3891 + smi->long_timeouts);
3892 + out += sprintf(out, "timeout_restarts: %ld\n",
3893 + smi->timeout_restarts);
3894 + out += sprintf(out, "idles: %ld\n",
3896 + out += sprintf(out, "interrupts: %ld\n",
3898 + out += sprintf(out, "attentions: %ld\n",
3900 + out += sprintf(out, "flag_fetches: %ld\n",
3901 + smi->flag_fetches);
3902 + out += sprintf(out, "hosed_count: %ld\n",
3903 + smi->hosed_count);
3904 + out += sprintf(out, "complete_transactions: %ld\n",
3905 + smi->complete_transactions);
3906 + out += sprintf(out, "events: %ld\n",
3908 + out += sprintf(out, "watchdog_pretimeouts: %ld\n",
3909 + smi->watchdog_pretimeouts);
3910 + out += sprintf(out, "incoming_messages: %ld\n",
3911 + smi->incoming_messages);
3913 + return (out - ((char *) page));
3916 +/* Returns 0 if initialized, or negative on an error. */
3917 +static int init_one_smi(int intf_num, struct smi_info **smi)
3920 + struct smi_info *new_smi;
3923 + rv = try_init_mem(intf_num, &new_smi);
3925 + rv = try_init_port(intf_num, &new_smi);
3926 +#ifdef CONFIG_ACPI_INTERPRETER
3927 + if ((rv) && (si_trydefaults)) {
3928 + rv = try_init_acpi(intf_num, &new_smi);
3935 + /* So we know not to free it unless we have allocated one. */
3936 + new_smi->intf = NULL;
3937 + new_smi->si_sm = NULL;
3938 + new_smi->handlers = 0;
3940 + if (!new_smi->irq_setup) {
3941 + new_smi->irq = si_irqs[intf_num];
3942 + new_smi->irq_setup = std_irq_setup;
3943 + new_smi->irq_cleanup = std_irq_cleanup;
3946 + /* Default to KCS if no type is specified. */
3947 + if (si_type[intf_num] == NULL) {
3948 + if (si_trydefaults)
3949 + si_type[intf_num] = "kcs";
3956 + /* Set up the state machine to use. */
3957 + if (strcmp(si_type[intf_num], "kcs") == 0) {
3958 + new_smi->handlers = &kcs_smi_handlers;
3959 + new_smi->si_type = SI_KCS;
3960 + } else if (strcmp(si_type[intf_num], "smic") == 0) {
3961 + new_smi->handlers = &smic_smi_handlers;
3962 + new_smi->si_type = SI_SMIC;
3964 + /* No support for anything else yet. */
3969 + /* Allocate the state machine's data and initialize it. */
3970 + new_smi->si_sm = kmalloc(new_smi->handlers->size(), GFP_KERNEL);
3971 + if (!new_smi->si_sm) {
3972 + printk(" Could not allocate state machine memory\n");
3976 + new_smi->io_size = new_smi->handlers->init_data(new_smi->si_sm,
3979 + /* Now that we know the I/O size, we can set up the I/O. */
3980 + rv = new_smi->io_setup(new_smi);
3982 + printk(" Could not set up I/O space\n");
3986 + spin_lock_init(&(new_smi->si_lock));
3987 + spin_lock_init(&(new_smi->msg_lock));
3988 + spin_lock_init(&(new_smi->count_lock));
3990 + /* Do low-level detection first. */
3991 + if (new_smi->handlers->detect(new_smi->si_sm)) {
3996 + /* Attempt a get device id command. If it fails, we probably
3997 + don't have a SMI here. */
3998 + rv = try_get_dev_id(new_smi);
4002 + /* Try to claim any interrupts. */
4003 + new_smi->irq_setup(new_smi);
4005 + INIT_LIST_HEAD(&(new_smi->xmit_msgs));
4006 + INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
4007 + new_smi->curr_msg = NULL;
4008 + atomic_set(&new_smi->req_events, 0);
4009 + new_smi->run_to_completion = 0;
4011 + rv = ipmi_register_smi(&handlers,
4013 + new_smi->ipmi_version_major,
4014 + new_smi->ipmi_version_minor,
4015 + &(new_smi->intf));
4018 + "ipmi_smi: Unable to register device: error %d\n",
4023 + rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
4024 + type_file_read_proc, NULL,
4025 + new_smi, THIS_MODULE);
4028 + "ipmi_smi: Unable to create proc entry: %d\n",
4033 + rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
4034 + stat_file_read_proc, NULL,
4035 + new_smi, THIS_MODULE);
4038 + "ipmi_smi: Unable to create proc entry: %d\n",
4043 + start_clear_flags(new_smi);
4045 + /* IRQ is defined to be set when non-zero. */
4047 + new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
4049 + new_smi->interrupt_disabled = 0;
4050 + new_smi->timer_stopped = 0;
4051 + new_smi->stop_operation = 0;
4053 + init_timer(&(new_smi->si_timer));
4054 + new_smi->si_timer.data = (long) new_smi;
4055 + new_smi->si_timer.function = smi_timeout;
4056 + new_smi->last_timeout_jiffies = jiffies;
4057 + new_smi->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES;
4058 + add_timer(&(new_smi->si_timer));
4062 + printk(" IPMI %s interface initialized\n", si_type[intf_num]);
4067 + if (new_smi->intf)
4068 + ipmi_unregister_smi(new_smi->intf);
4070 + new_smi->irq_cleanup(new_smi);
4071 + if (new_smi->si_sm) {
4072 + if (new_smi->handlers)
4073 + new_smi->handlers->cleanup(new_smi->si_sm);
4074 + kfree(new_smi->si_sm);
4076 + new_smi->io_cleanup(new_smi);
4080 +static __init int init_ipmi_si(void)
4090 + printk(KERN_INFO "IPMI System Interface driver version "
4092 + if (kcs_smi_handlers.version)
4093 + printk(", KCS version %s", kcs_smi_handlers.version);
4094 + if (smic_smi_handlers.version)
4095 + printk(", SMIC version %s", smic_smi_handlers.version);
4098 + rv = init_one_smi(0, &(smi_infos[pos]));
4099 + if (rv && !si_ports[0] && si_trydefaults) {
4100 + /* If we are trying defaults and the initial port is
4101 + not set, then set it. */
4102 + si_type[0] = "kcs";
4103 + si_ports[0] = DEFAULT_KCS_IO_PORT;
4104 + rv = init_one_smi(0, &(smi_infos[pos]));
4106 + /* No KCS - try SMIC */
4107 + si_type[0] = "smic";
4108 + si_ports[0] = DEFAULT_SMIC_IO_PORT;
4109 + rv = init_one_smi(0, &(smi_infos[pos]));
4115 + for (i=1; i < SI_MAX_PARMS; i++) {
4116 + rv = init_one_smi(i, &(smi_infos[pos]));
4121 + if (smi_infos[0] == NULL) {
4122 + printk("ipmi_smi: Unable to find any SMI interfaces\n");
4128 +module_init(init_ipmi_si);
4131 +void __exit cleanup_one_si(struct smi_info *to_clean)
4134 + unsigned long flags;
4139 + /* Tell the timer and interrupt handlers that we are shutting
4141 + spin_lock_irqsave(&(to_clean->si_lock), flags);
4142 + spin_lock(&(to_clean->msg_lock));
4144 + to_clean->stop_operation = 1;
4146 + to_clean->irq_cleanup(to_clean);
4148 + spin_unlock(&(to_clean->msg_lock));
4149 + spin_unlock_irqrestore(&(to_clean->si_lock), flags);
4151 + /* Wait for the timer to stop. This avoids problems with race
4152 + conditions removing the timer here. Hopefully this will be
4153 + long enough to avoid problems with interrupts still
4155 + schedule_timeout(2);
4156 + while (!to_clean->timer_stopped) {
4157 + schedule_timeout(1);
4160 + rv = ipmi_unregister_smi(to_clean->intf);
4163 + "ipmi_smi: Unable to unregister device: errno=%d\n",
4167 + to_clean->handlers->cleanup(to_clean->si_sm);
4169 + kfree(to_clean->si_sm);
4171 + to_clean->io_cleanup(to_clean);
4174 +static __exit void cleanup_ipmi_si(void)
4181 + for (i=0; i<SI_MAX_DRIVERS; i++) {
4182 + cleanup_one_si(smi_infos[i]);
4185 +module_exit(cleanup_ipmi_si);
4188 +/* Unfortunately, cmdline::get_options() only returns integers, not
4189 + longs. Since we need ulongs (64-bit physical addresses) parse the
4190 + comma-separated list manually. Arguments can be one of these forms:
4191 + m0xaabbccddeeff A physical memory address without an IRQ
4192 + m0xaabbccddeeff:cc A physical memory address with an IRQ
4193 + p0xaabb An IO port without an IRQ
4194 + p0xaabb:cc An IO port with an IRQ
4195 + nodefaults Suppress trying the default IO port or ACPI address
4197 + For example, to pass one IO port with an IRQ, one address, and
4198 + suppress the use of the default IO port and ACPI address,
4199 + use this option string: ipmi_smi=p0xCA2:5,m0xFF5B0022,nodefaults
4201 + Remember, ipmi_si_setup() is passed the string after the equal sign. */
4203 +static int __init ipmi_si_setup(char *str)
4205 + unsigned long val;
4206 + char *cur, *colon;
4211 + cur = strsep(&str, ",");
4212 + while ((cur) && (*cur) && (pos < SI_MAX_PARMS)) {
4215 + if (strcmp(cur, "nodefaults") == 0)
4216 + si_trydefaults = 0;
4219 + "ipmi_si: bad parameter value %s\n",
4223 + case 'k': /* KCS */
4224 + si_type[pos] = "kcs";
4227 + case 's': /* SMIC */
4228 + si_type[pos] = "smic";
4231 + case 'b': /* BT */
4232 + si_type[pos] = "bt";
4237 + val = simple_strtoul(cur + 1,
4241 + si_ports[pos] = val;
4243 + si_addrs[pos] = val;
4244 + if (*colon == ':') {
4245 + val = simple_strtoul(colon + 1,
4248 + si_irqs[pos] = val;
4255 + "ipmi_si: bad parameter value %s\n",
4258 + cur = strsep(&str, ",");
4263 +__setup("ipmi_si=", ipmi_si_setup);
4266 +MODULE_LICENSE("GPL");
4267 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
4268 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_si_sm.h 1970-01-01 01:00:00.000000000 +0100
4269 +++ linux-2.4.23/drivers/char/ipmi/ipmi_si_sm.h 2003-12-06 17:46:43.004452672 +0100
4274 + * State machine interface for low-level IPMI system management
4275 + * interface state machines. This code is the interface between
4276 + * the ipmi_smi code (that handles the policy of a KCS, SMIC, or
4277 + * BT interface) and the actual low-level state machine.
4279 + * Author: MontaVista Software, Inc.
4280 + * Corey Minyard <minyard@mvista.com>
4281 + * source@mvista.com
4283 + * Copyright 2002 MontaVista Software Inc.
4285 + * This program is free software; you can redistribute it and/or modify it
4286 + * under the terms of the GNU General Public License as published by the
4287 + * Free Software Foundation; either version 2 of the License, or (at your
4288 + * option) any later version.
4291 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
4292 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4293 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
4294 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
4295 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
4296 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
4297 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4298 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
4299 + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
4300 + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4302 + * You should have received a copy of the GNU General Public License along
4303 + * with this program; if not, write to the Free Software Foundation, Inc.,
4304 + * 675 Mass Ave, Cambridge, MA 02139, USA.
4307 +/* This is defined by the state machines themselves, it is an opaque
4308 + data type for them to use. */
4311 +/* The structure for doing I/O in the state machine. The state
4312 + machine doesn't have the actual I/O routines, they are done through
4313 + this interface. */
4316 + unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset);
4317 + void (*outputb)(struct si_sm_io *io,
4318 + unsigned int offset,
4321 + /* Generic info used by the actual handling routines, the
4322 + state machine shouldn't touch these. */
4327 +/* Results of SMI events. */
4330 + SI_SM_CALL_WITHOUT_DELAY, /* Call the driver again immediately */
4331 + SI_SM_CALL_WITH_DELAY, /* Delay some before calling again. */
4332 + SI_SM_TRANSACTION_COMPLETE, /* A transaction is finished. */
4333 + SI_SM_IDLE, /* The SM is in idle state. */
4334 + SI_SM_HOSED, /* The hardware violated the state machine. */
4335 + SI_SM_ATTN /* The hardware is asserting attn and the
4336 + state machine is idle. */
4339 +/* Handlers for the SMI state machine. */
4340 +struct si_sm_handlers
4342 + /* Put the version number of the state machine here so the
4343 + upper layer can print it. */
4346 + /* Initialize the data and return the amount of I/O space to
4347 + reserve for the space. */
4348 + unsigned int (*init_data)(struct si_sm_data *smi,
4349 + struct si_sm_io *io);
4351 + /* Start a new transaction in the state machine. This will
4352 + return -2 if the state machine is not idle, -1 if the size
4353 + is invalid (to large or too small), or 0 if the transaction
4354 + is successfully completed. */
4355 + int (*start_transaction)(struct si_sm_data *smi,
4356 + unsigned char *data, unsigned int size);
4358 + /* Return the results after the transaction. This will return
4359 + -1 if the buffer is too small, zero if no transaction is
4360 + present, or the actual length of the result data. */
4361 + int (*get_result)(struct si_sm_data *smi,
4362 + unsigned char *data, unsigned int length);
4364 + /* Call this periodically (for a polled interface) or upon
4365 + receiving an interrupt (for a interrupt-driven interface).
4366 + If interrupt driven, you should probably poll this
4367 + periodically when not in idle state. This should be called
4368 + with the time that passed since the last call, if it is
4369 + significant. Time is in microseconds. */
4370 + enum si_sm_result (*event)(struct si_sm_data *smi, long time);
4372 + /* Attempt to detect an SMI. Returns 0 on success or nonzero
4374 + int (*detect)(struct si_sm_data *smi);
4376 + /* The interface is shutting down, so clean it up. */
4377 + void (*cleanup)(struct si_sm_data *smi);
4379 + /* Return the size of the SMI structure in bytes. */
4380 + int (*size)(void);
4383 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
4384 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_smic_sm.c 1970-01-01 01:00:00.000000000 +0100
4385 +++ linux-2.4.23/drivers/char/ipmi/ipmi_smic_sm.c 2003-12-06 17:46:43.024448478 +0100
4390 + * The state-machine driver for an IPMI SMIC driver
4392 + * It started as a copy of Corey Minyard's driver for the KSC interface
4393 + * and the kernel patch "mmcdev-patch-245" by HP
4395 + * modified by: Hannes Schulz <schulz@schwaar.com>
4396 + * ipmi@schwaar.com
4399 + * Corey Minyard's driver for the KSC interface has the following
4400 + * copyright notice:
4401 + * Copyright 2002 MontaVista Software Inc.
4403 + * the kernel patch "mmcdev-patch-245" by HP has the following
4404 + * copyright notice:
4405 + * (c) Copyright 2001 Grant Grundler (c) Copyright
4406 + * 2001 Hewlett-Packard Company
4409 + * This program is free software; you can redistribute it and/or modify it
4410 + * under the terms of the GNU General Public License as published by the
4411 + * Free Software Foundation; either version 2 of the License, or (at your
4412 + * option) any later version.
4415 + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
4416 + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
4417 + * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
4418 + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
4419 + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
4420 + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
4421 + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
4422 + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
4423 + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
4424 + * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4426 + * You should have received a copy of the GNU General Public License along
4427 + * with this program; if not, write to the Free Software Foundation, Inc.,
4428 + * 675 Mass Ave, Cambridge, MA 02139, USA. */
4430 +#include <linux/kernel.h> /* For printk. */
4431 +#include <linux/string.h>
4432 +#include "ipmi_si_sm.h"
4434 +#define IPMI_SMIC_VERSION "v27"
4436 +/* smic_debug is a bit-field
4437 + * SMIC_DEBUG_ENABLE - turned on for now
4438 + * SMIC_DEBUG_MSG - commands and their responses
4439 + * SMIC_DEBUG_STATES - state machine
4441 +#define SMIC_DEBUG_STATES 4
4442 +#define SMIC_DEBUG_MSG 2
4443 +#define SMIC_DEBUG_ENABLE 1
4445 +static int smic_debug = 1;
4461 +#define MAX_SMIC_READ_SIZE 80
4462 +#define MAX_SMIC_WRITE_SIZE 80
4463 +#define SMIC_MAX_ERROR_RETRIES 3
4465 +/* Timeouts in microseconds. */
4466 +#define SMIC_RETRY_TIMEOUT 100000
4467 +#define IPMI_ERR_MSG_TRUNCATED 0xc6
4468 +#define IPMI_ERR_UNSPECIFIED 0xff
4471 +/* SMIC Flags Register Bits */
4472 +#define SMIC_RX_DATA_READY 0x80
4473 +#define SMIC_TX_DATA_READY 0x40
4474 +#define SMIC_SMI 0x10
4475 +#define SMIC_EVM_DATA_AVAIL 0x08
4476 +#define SMIC_SMS_DATA_AVAIL 0x04
4477 +#define SMIC_FLAG_BSY 0x01
4479 +/* SMIC Error Codes */
4480 +#define EC_NO_ERROR 0x00
4481 +#define EC_ABORTED 0x01
4482 +#define EC_ILLEGAL_CONTROL 0x02
4483 +#define EC_NO_RESPONSE 0x03
4484 +#define EC_ILLEGAL_COMMAND 0x04
4485 +#define EC_BUFFER_FULL 0x05
4489 + enum smic_states state;
4490 + struct si_sm_io *io;
4491 + unsigned char write_data[MAX_SMIC_WRITE_SIZE];
4494 + int orig_write_count;
4495 + unsigned char read_data[MAX_SMIC_READ_SIZE];
4498 + unsigned int error_retries;
4499 + long smic_timeout;
4502 +static unsigned int init_smic_data (struct si_sm_data *smic,
4503 + struct si_sm_io *io)
4505 + smic->state = SMIC_IDLE;
4507 + smic->write_pos = 0;
4508 + smic->write_count = 0;
4509 + smic->orig_write_count = 0;
4510 + smic->read_pos = 0;
4511 + smic->error_retries = 0;
4512 + smic->truncated = 0;
4513 + smic->smic_timeout = SMIC_RETRY_TIMEOUT;
4515 + /* We use 3 bytes of I/O. */
4519 +static int start_smic_transaction(struct si_sm_data *smic,
4520 + unsigned char *data, unsigned int size)
4524 + if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
4527 + if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
4530 + if (smic_debug & SMIC_DEBUG_MSG) {
4531 + printk(KERN_INFO "start_smic_transaction -");
4532 + for (i = 0; i < size; i ++) {
4533 + printk (" %02x", (unsigned char) (data [i]));
4537 + smic->error_retries = 0;
4538 + memcpy(smic->write_data, data, size);
4539 + smic->write_count = size;
4540 + smic->orig_write_count = size;
4541 + smic->write_pos = 0;
4542 + smic->read_pos = 0;
4543 + smic->state = SMIC_START_OP;
4544 + smic->smic_timeout = SMIC_RETRY_TIMEOUT;
4548 +static int smic_get_result(struct si_sm_data *smic,
4549 + unsigned char *data, unsigned int length)
4553 + if (smic_debug & SMIC_DEBUG_MSG) {
4554 + printk (KERN_INFO "smic_get result -");
4555 + for (i = 0; i < smic->read_pos; i ++) {
4556 + printk (" %02x", (smic->read_data [i]));
4560 + if (length < smic->read_pos) {
4561 + smic->read_pos = length;
4562 + smic->truncated = 1;
4564 + memcpy(data, smic->read_data, smic->read_pos);
4566 + if ((length >= 3) && (smic->read_pos < 3)) {
4567 + data[2] = IPMI_ERR_UNSPECIFIED;
4568 + smic->read_pos = 3;
4570 + if (smic->truncated) {
4571 + data[2] = IPMI_ERR_MSG_TRUNCATED;
4572 + smic->truncated = 0;
4574 + return smic->read_pos;
4577 +static inline unsigned char read_smic_flags(struct si_sm_data *smic)
4579 + return smic->io->inputb(smic->io, 2);
4582 +static inline unsigned char read_smic_status(struct si_sm_data *smic)
4584 + return smic->io->inputb(smic->io, 1);
4587 +static inline unsigned char read_smic_data(struct si_sm_data *smic)
4589 + return smic->io->inputb(smic->io, 0);
4592 +static inline void write_smic_flags(struct si_sm_data *smic,
4593 + unsigned char flags)
4595 + smic->io->outputb(smic->io, 2, flags);
4598 +static inline void write_smic_control(struct si_sm_data *smic,
4599 + unsigned char control)
4601 + smic->io->outputb(smic->io, 1, control);
4604 +static inline void write_si_sm_data (struct si_sm_data *smic,
4605 + unsigned char data)
4607 + smic->io->outputb(smic->io, 0, data);
4610 +static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
4612 + (smic->error_retries)++;
4613 + if (smic->error_retries > SMIC_MAX_ERROR_RETRIES) {
4614 + if (smic_debug & SMIC_DEBUG_ENABLE) {
4615 + printk(KERN_WARNING
4616 + "ipmi_smic_drv: smic hosed: %s\n", reason);
4618 + smic->state = SMIC_HOSED;
4620 + smic->write_count = smic->orig_write_count;
4621 + smic->write_pos = 0;
4622 + smic->read_pos = 0;
4623 + smic->state = SMIC_START_OP;
4624 + smic->smic_timeout = SMIC_RETRY_TIMEOUT;
4628 +static inline void write_next_byte(struct si_sm_data *smic)
4630 + write_si_sm_data(smic, smic->write_data[smic->write_pos]);
4631 + (smic->write_pos)++;
4632 + (smic->write_count)--;
4635 +static inline void read_next_byte (struct si_sm_data *smic)
4637 + if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
4638 + read_smic_data (smic);
4639 + smic->truncated = 1;
4641 + smic->read_data[smic->read_pos] = read_smic_data(smic);
4642 + (smic->read_pos)++;
4646 +/* SMIC Control/Status Code Components */
4647 +#define SMIC_GET_STATUS 0x00 /* Control form's name */
4648 +#define SMIC_READY 0x00 /* Status form's name */
4649 +#define SMIC_WR_START 0x01 /* Unified Control/Status names... */
4650 +#define SMIC_WR_NEXT 0x02
4651 +#define SMIC_WR_END 0x03
4652 +#define SMIC_RD_START 0x04
4653 +#define SMIC_RD_NEXT 0x05
4654 +#define SMIC_RD_END 0x06
4655 +#define SMIC_CODE_MASK 0x0f
4657 +#define SMIC_CONTROL 0x00
4658 +#define SMIC_STATUS 0x80
4659 +#define SMIC_CS_MASK 0x80
4661 +#define SMIC_SMS 0x40
4662 +#define SMIC_SMM 0x60
4663 +#define SMIC_STREAM_MASK 0x60
4665 +/* SMIC Control Codes */
4666 +#define SMIC_CC_SMS_GET_STATUS (SMIC_CONTROL|SMIC_SMS|SMIC_GET_STATUS)
4667 +#define SMIC_CC_SMS_WR_START (SMIC_CONTROL|SMIC_SMS|SMIC_WR_START)
4668 +#define SMIC_CC_SMS_WR_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_WR_NEXT)
4669 +#define SMIC_CC_SMS_WR_END (SMIC_CONTROL|SMIC_SMS|SMIC_WR_END)
4670 +#define SMIC_CC_SMS_RD_START (SMIC_CONTROL|SMIC_SMS|SMIC_RD_START)
4671 +#define SMIC_CC_SMS_RD_NEXT (SMIC_CONTROL|SMIC_SMS|SMIC_RD_NEXT)
4672 +#define SMIC_CC_SMS_RD_END (SMIC_CONTROL|SMIC_SMS|SMIC_RD_END)
4674 +#define SMIC_CC_SMM_GET_STATUS (SMIC_CONTROL|SMIC_SMM|SMIC_GET_STATUS)
4675 +#define SMIC_CC_SMM_WR_START (SMIC_CONTROL|SMIC_SMM|SMIC_WR_START)
4676 +#define SMIC_CC_SMM_WR_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_WR_NEXT)
4677 +#define SMIC_CC_SMM_WR_END (SMIC_CONTROL|SMIC_SMM|SMIC_WR_END)
4678 +#define SMIC_CC_SMM_RD_START (SMIC_CONTROL|SMIC_SMM|SMIC_RD_START)
4679 +#define SMIC_CC_SMM_RD_NEXT (SMIC_CONTROL|SMIC_SMM|SMIC_RD_NEXT)
4680 +#define SMIC_CC_SMM_RD_END (SMIC_CONTROL|SMIC_SMM|SMIC_RD_END)
4682 +/* SMIC Status Codes */
4683 +#define SMIC_SC_SMS_READY (SMIC_STATUS|SMIC_SMS|SMIC_READY)
4684 +#define SMIC_SC_SMS_WR_START (SMIC_STATUS|SMIC_SMS|SMIC_WR_START)
4685 +#define SMIC_SC_SMS_WR_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_WR_NEXT)
4686 +#define SMIC_SC_SMS_WR_END (SMIC_STATUS|SMIC_SMS|SMIC_WR_END)
4687 +#define SMIC_SC_SMS_RD_START (SMIC_STATUS|SMIC_SMS|SMIC_RD_START)
4688 +#define SMIC_SC_SMS_RD_NEXT (SMIC_STATUS|SMIC_SMS|SMIC_RD_NEXT)
4689 +#define SMIC_SC_SMS_RD_END (SMIC_STATUS|SMIC_SMS|SMIC_RD_END)
4691 +#define SMIC_SC_SMM_READY (SMIC_STATUS|SMIC_SMM|SMIC_READY)
4692 +#define SMIC_SC_SMM_WR_START (SMIC_STATUS|SMIC_SMM|SMIC_WR_START)
4693 +#define SMIC_SC_SMM_WR_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_WR_NEXT)
4694 +#define SMIC_SC_SMM_WR_END (SMIC_STATUS|SMIC_SMM|SMIC_WR_END)
4695 +#define SMIC_SC_SMM_RD_START (SMIC_STATUS|SMIC_SMM|SMIC_RD_START)
4696 +#define SMIC_SC_SMM_RD_NEXT (SMIC_STATUS|SMIC_SMM|SMIC_RD_NEXT)
4697 +#define SMIC_SC_SMM_RD_END (SMIC_STATUS|SMIC_SMM|SMIC_RD_END)
4699 +/* these are the control/status codes we actually use
4700 + SMIC_CC_SMS_GET_STATUS 0x40
4701 + SMIC_CC_SMS_WR_START 0x41
4702 + SMIC_CC_SMS_WR_NEXT 0x42
4703 + SMIC_CC_SMS_WR_END 0x43
4704 + SMIC_CC_SMS_RD_START 0x44
4705 + SMIC_CC_SMS_RD_NEXT 0x45
4706 + SMIC_CC_SMS_RD_END 0x46
4708 + SMIC_SC_SMS_READY 0xC0
4709 + SMIC_SC_SMS_WR_START 0xC1
4710 + SMIC_SC_SMS_WR_NEXT 0xC2
4711 + SMIC_SC_SMS_WR_END 0xC3
4712 + SMIC_SC_SMS_RD_START 0xC4
4713 + SMIC_SC_SMS_RD_NEXT 0xC5
4714 + SMIC_SC_SMS_RD_END 0xC6
4717 +static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
4719 + unsigned char status;
4720 + unsigned char flags;
4721 + unsigned char data;
4723 + if (smic->state == SMIC_HOSED) {
4724 + init_smic_data(smic, smic->io);
4725 + return SI_SM_HOSED;
4727 + if (smic->state != SMIC_IDLE) {
4728 + if (smic_debug & SMIC_DEBUG_STATES) {
4730 + "smic_event - smic->smic_timeout = %ld,"
4732 + smic->smic_timeout, time);
4734 +/* FIXME: smic_event is sometimes called with time > SMIC_RETRY_TIMEOUT */
4735 + if (time < SMIC_RETRY_TIMEOUT) {
4736 + smic->smic_timeout -= time;
4737 + if (smic->smic_timeout < 0) {
4738 + start_error_recovery(smic, "smic timed out.");
4739 + return SI_SM_CALL_WITH_DELAY;
4743 + flags = read_smic_flags(smic);
4744 + if (flags & SMIC_FLAG_BSY)
4745 + return SI_SM_CALL_WITH_DELAY;
4747 + status = read_smic_status (smic);
4748 + if (smic_debug & SMIC_DEBUG_STATES)
4750 + "smic_event - state = %d, flags = 0x%02x,"
4751 + " status = 0x%02x\n",
4752 + smic->state, flags, status);
4754 + switch (smic->state) {
4756 + /* in IDLE we check for available messages */
4757 + if (flags & (SMIC_SMI |
4758 + SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
4760 + return SI_SM_ATTN;
4762 + return SI_SM_IDLE;
4764 + case SMIC_START_OP:
4765 + /* sanity check whether smic is really idle */
4766 + write_smic_control(smic, SMIC_CC_SMS_GET_STATUS);
4767 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4768 + smic->state = SMIC_OP_OK;
4772 + if (status != SMIC_SC_SMS_READY) {
4773 + /* this should not happen */
4774 + start_error_recovery(smic,
4775 + "state = SMIC_OP_OK,"
4776 + " status != SMIC_SC_SMS_READY");
4777 + return SI_SM_CALL_WITH_DELAY;
4779 + /* OK so far; smic is idle let us start ... */
4780 + write_smic_control(smic, SMIC_CC_SMS_WR_START);
4781 + write_next_byte(smic);
4782 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4783 + smic->state = SMIC_WRITE_START;
4786 + case SMIC_WRITE_START:
4787 + if (status != SMIC_SC_SMS_WR_START) {
4788 + start_error_recovery(smic,
4789 + "state = SMIC_WRITE_START, "
4790 + "status != SMIC_SC_SMS_WR_START");
4791 + return SI_SM_CALL_WITH_DELAY;
4793 + /* we must not issue WR_(NEXT|END) unless
4794 + TX_DATA_READY is set */
4795 + if (flags & SMIC_TX_DATA_READY) {
4796 + if (smic->write_count == 1) {
4798 + write_smic_control(smic, SMIC_CC_SMS_WR_END);
4799 + smic->state = SMIC_WRITE_END;
4801 + write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
4802 + smic->state = SMIC_WRITE_NEXT;
4804 + write_next_byte(smic);
4805 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4808 + return SI_SM_CALL_WITH_DELAY;
4812 + case SMIC_WRITE_NEXT:
4813 + if (status != SMIC_SC_SMS_WR_NEXT) {
4814 + start_error_recovery(smic,
4815 + "state = SMIC_WRITE_NEXT, "
4816 + "status != SMIC_SC_SMS_WR_NEXT");
4817 + return SI_SM_CALL_WITH_DELAY;
4819 + /* this is the same code as in SMIC_WRITE_START */
4820 + if (flags & SMIC_TX_DATA_READY) {
4821 + if (smic->write_count == 1) {
4822 + write_smic_control(smic, SMIC_CC_SMS_WR_END);
4823 + smic->state = SMIC_WRITE_END;
4826 + write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
4827 + smic->state = SMIC_WRITE_NEXT;
4829 + write_next_byte(smic);
4830 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4833 + return SI_SM_CALL_WITH_DELAY;
4837 + case SMIC_WRITE_END:
4838 + if (status != SMIC_SC_SMS_WR_END) {
4839 + start_error_recovery (smic,
4840 + "state = SMIC_WRITE_END, "
4841 + "status != SMIC_SC_SMS_WR_END");
4842 + return SI_SM_CALL_WITH_DELAY;
4844 + /* data register holds an error code */
4845 + data = read_smic_data(smic);
4847 + if (smic_debug & SMIC_DEBUG_ENABLE) {
4849 + "SMIC_WRITE_END: data = %02x\n", data);
4851 + start_error_recovery(smic,
4852 + "state = SMIC_WRITE_END, "
4853 + "data != SUCCESS");
4854 + return SI_SM_CALL_WITH_DELAY;
4856 + smic->state = SMIC_WRITE2READ;
4860 + case SMIC_WRITE2READ:
4861 + /* we must wait for RX_DATA_READY to be set before we
4863 + if (flags & SMIC_RX_DATA_READY) {
4864 + write_smic_control(smic, SMIC_CC_SMS_RD_START);
4865 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4866 + smic->state = SMIC_READ_START;
4868 + return SI_SM_CALL_WITH_DELAY;
4872 + case SMIC_READ_START:
4873 + if (status != SMIC_SC_SMS_RD_START) {
4874 + start_error_recovery(smic,
4875 + "state = SMIC_READ_START, "
4876 + "status != SMIC_SC_SMS_RD_START");
4877 + return SI_SM_CALL_WITH_DELAY;
4879 + if (flags & SMIC_RX_DATA_READY) {
4880 + read_next_byte(smic);
4881 + write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
4882 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4883 + smic->state = SMIC_READ_NEXT;
4885 + return SI_SM_CALL_WITH_DELAY;
4889 + case SMIC_READ_NEXT:
4891 + /* smic tells us that this is the last byte to be read
4893 + case SMIC_SC_SMS_RD_END:
4894 + read_next_byte(smic);
4895 + write_smic_control(smic, SMIC_CC_SMS_RD_END);
4896 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4897 + smic->state = SMIC_READ_END;
4899 + case SMIC_SC_SMS_RD_NEXT:
4900 + if (flags & SMIC_RX_DATA_READY) {
4901 + read_next_byte(smic);
4902 + write_smic_control(smic, SMIC_CC_SMS_RD_NEXT);
4903 + write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4904 + smic->state = SMIC_READ_NEXT;
4906 + return SI_SM_CALL_WITH_DELAY;
4910 + start_error_recovery(
4912 + "state = SMIC_READ_NEXT, "
4913 + "status != SMIC_SC_SMS_RD_(NEXT|END)");
4914 + return SI_SM_CALL_WITH_DELAY;
4918 + case SMIC_READ_END:
4919 + if (status != SMIC_SC_SMS_READY) {
4920 + start_error_recovery(smic,
4921 + "state = SMIC_READ_END, "
4922 + "status != SMIC_SC_SMS_READY");
4923 + return SI_SM_CALL_WITH_DELAY;
4925 + data = read_smic_data(smic);
4926 + /* data register holds an error code */
4928 + if (smic_debug & SMIC_DEBUG_ENABLE) {
4930 + "SMIC_READ_END: data = %02x\n", data);
4932 + start_error_recovery(smic,
4933 + "state = SMIC_READ_END, "
4934 + "data != SUCCESS");
4935 + return SI_SM_CALL_WITH_DELAY;
4937 + smic->state = SMIC_IDLE;
4938 + return SI_SM_TRANSACTION_COMPLETE;
4942 + init_smic_data(smic, smic->io);
4943 + return SI_SM_HOSED;
4946 + if (smic_debug & SMIC_DEBUG_ENABLE) {
4947 + printk(KERN_WARNING "smic->state = %d\n", smic->state);
4948 + start_error_recovery(smic, "state = UNKNOWN");
4949 + return SI_SM_CALL_WITH_DELAY;
4952 + smic->smic_timeout = SMIC_RETRY_TIMEOUT;
4953 + return SI_SM_CALL_WITHOUT_DELAY;
4956 +static int smic_detect(struct si_sm_data *smic)
4958 + /* It's impossible for the SMIC fnags register to be all 1's,
4959 + (assuming a properly functioning, self-initialized BMC)
4960 + but that's what you get from reading a bogus address, so we
4961 + test that first. */
4962 + if (read_smic_flags(smic) == 0xff)
4968 +static void smic_cleanup(struct si_sm_data *kcs)
4972 +static int smic_size(void)
4974 + return sizeof(struct si_sm_data);
4977 +struct si_sm_handlers smic_smi_handlers =
4979 + .version = IPMI_SMIC_VERSION,
4980 + .init_data = init_smic_data,
4981 + .start_transaction = start_smic_transaction,
4982 + .get_result = smic_get_result,
4983 + .event = smic_event,
4984 + .detect = smic_detect,
4985 + .cleanup = smic_cleanup,
4986 + .size = smic_size,
4988 diff -urN linux-2.4.23.org/drivers/char/ipmi/ipmi_watchdog.c linux-2.4.23/drivers/char/ipmi/ipmi_watchdog.c
4989 --- linux-2.4.23.org/drivers/char/ipmi/ipmi_watchdog.c 2003-12-06 12:53:23.003503549 +0100
4990 +++ linux-2.4.23/drivers/char/ipmi/ipmi_watchdog.c 2003-12-06 17:46:43.041444912 +0100
4992 #include <asm/apic.h>
4995 +#define IPMI_WATCHDOG_VERSION "v27"
4998 * The IPMI command/response information for the watchdog timer.
5000 @@ -153,10 +155,18 @@
5001 static char pretimeout_since_last_heartbeat = 0;
5003 MODULE_PARM(timeout, "i");
5004 +MODULE_PARM_DESC(timeout, "Timeout value in seconds.");
5005 MODULE_PARM(pretimeout, "i");
5006 +MODULE_PARM_DESC(pretimeout, "Pretimeout value in seconds.");
5007 MODULE_PARM(action, "s");
5008 +MODULE_PARM_DESC(action, "Timeout action. One of: "
5009 + "reset, none, power_cycle, power_off.");
5010 MODULE_PARM(preaction, "s");
5011 +MODULE_PARM_DESC(preaction, "Pretimeout action. One of: "
5012 + "pre_none, pre_smi, pre_nmi, pre_int.");
5013 MODULE_PARM(preop, "s");
5014 +MODULE_PARM_DESC(preop, "Pretimeout driver operation. One of: "
5015 + "preop_none, preop_panic, preop_give_data.");
5017 /* Default state of the timer. */
5018 static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
5021 static struct ipmi_smi_watcher smi_watcher =
5023 + .owner = THIS_MODULE,
5024 .new_smi = ipmi_new_smi,
5025 .smi_gone = ipmi_smi_gone
5031 + printk(KERN_INFO "IPMI watchdog driver version "
5032 + IPMI_WATCHDOG_VERSION "\n");
5034 if (strcmp(action, "reset") == 0) {
5035 action_val = WDOG_TIMEOUT_RESET;
5036 } else if (strcmp(action, "none") == 0) {
5037 @@ -995,9 +1009,6 @@
5038 register_reboot_notifier(&wdog_reboot_notifier);
5039 notifier_chain_register(&panic_notifier_list, &wdog_panic_notifier);
5041 - printk(KERN_INFO "IPMI watchdog by "
5042 - "Corey Minyard (minyard@mvista.com)\n");
5047 diff -urN linux-2.4.23.org/drivers/char/ipmi/Makefile linux-2.4.23/drivers/char/ipmi/Makefile
5048 --- linux-2.4.23.org/drivers/char/ipmi/Makefile 2003-12-06 12:53:23.043495221 +0100
5049 +++ linux-2.4.23/drivers/char/ipmi/Makefile 2003-12-06 17:46:43.064440089 +0100
5052 export-objs := ipmi_msghandler.o ipmi_watchdog.o
5054 -list-multi := ipmi_kcs_drv.o
5055 +list-multi := ipmi_kcs_drv.o ipmi_si_drv.o
5056 ipmi_kcs_drv-objs := ipmi_kcs_sm.o ipmi_kcs_intf.o
5057 +ipmi_si_drv-objs := ipmi_si.o ipmi_kcs_sm.o ipmi_smic_sm.o
5059 obj-$(CONFIG_IPMI_HANDLER) += ipmi_msghandler.o
5060 obj-$(CONFIG_IPMI_DEVICE_INTERFACE) += ipmi_devintf.o
5061 +obj-$(CONFIG_IPMI_SI) += ipmi_si_drv.o
5062 obj-$(CONFIG_IPMI_KCS) += ipmi_kcs_drv.o
5063 obj-$(CONFIG_IPMI_WATCHDOG) += ipmi_watchdog.o
5067 ipmi_kcs_drv.o: $(ipmi_kcs_drv-objs)
5068 $(LD) -r -o $@ $(ipmi_kcs_drv-objs)
5070 +ipmi_si_drv.o: $(ipmi_si_drv-objs)
5071 + $(LD) -r -o $@ $(ipmi_si_drv-objs)
5072 diff -urN linux-2.4.23.org/include/linux/ipmi.h linux-2.4.23/include/linux/ipmi.h
5073 --- linux-2.4.23.org/include/linux/ipmi.h 2003-12-06 12:52:27.330097221 +0100
5074 +++ linux-2.4.23/include/linux/ipmi.h 2003-12-06 17:46:43.115429392 +0100
5076 * The in-kernel interface.
5078 #include <linux/list.h>
5079 +#include <linux/module.h>
5081 /* Opaque type for a IPMI message user. One of these is needed to
5082 send and receive messages. */
5083 @@ -221,7 +222,12 @@
5087 -/* Destroy the given user of the IPMI layer. */
5088 +/* Destroy the given user of the IPMI layer. Note that after this
5089 + function returns, the system is guaranteed to not call any
5090 + callbacks for the user. Thus as long as you destroy all the users
5091 + before you unload a module, you will be safe. And if you destroy
5092 + the users before you destroy the callback structures, it should be
5094 int ipmi_destroy_user(ipmi_user_t user);
5096 /* Get the IPMI version of the BMC we are talking to. */
5097 @@ -261,6 +267,27 @@
5101 + * Like ipmi_request, but lets you specify the number of retries and
5102 + * the retry time. The retries is the number of times the message
5103 + * will be resent if no reply is received. If set to -1, the default
5104 + * value will be used. The retry time is the time in milliseconds
5105 + * between retries. If set to zero, the default value will be
5108 + * Don't use this unless you *really* have to. It's primarily for the
5109 + * IPMI over LAN converter; since the LAN stuff does its own retries,
5110 + * it makes no sense to do it here. However, this can be used if you
5111 + * have unusual requirements.
5113 +int ipmi_request_settime(ipmi_user_t user,
5114 + struct ipmi_addr *addr,
5116 + struct ipmi_msg *msg,
5119 + unsigned int retry_time_ms);
5122 * Like ipmi_request, but lets you specify the slave return address.
5124 int ipmi_request_with_source(ipmi_user_t user,
5125 @@ -331,6 +358,10 @@
5127 struct list_head link;
5129 + /* You must set the owner to the current module, if you are in
5130 + a module (generally just set it to "THIS_MODULE"). */
5131 + struct module *owner;
5133 /* These two are called with read locks held for the interface
5134 the watcher list. So you can add and remove users from the
5135 IPMI interface, send messages, etc., but you cannot add
5136 @@ -422,6 +453,29 @@
5137 #define IPMICTL_SEND_COMMAND _IOR(IPMI_IOC_MAGIC, 13, \
5140 +/* Messages sent to the interface with timing parameters are this
5142 +struct ipmi_req_settime
5144 + struct ipmi_req req;
5146 + /* See ipmi_request_settime() above for details on these
5149 + unsigned int retry_time_ms;
5152 + * Send a message to the interfaces with timing parameters. error values
5154 + * - EFAULT - an address supplied was invalid.
5155 + * - EINVAL - The address supplied was not valid, or the command
5156 + * was not allowed.
5157 + * - EMSGSIZE - The message to was too large.
5158 + * - ENOMEM - Buffers could not be allocated for the command.
5160 +#define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, \
5161 + struct ipmi_req_settime)
5163 /* Messages received from the interface are this format. */
5166 @@ -513,4 +567,18 @@
5167 #define IPMICTL_SET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 19, unsigned int)
5168 #define IPMICTL_GET_MY_LUN_CMD _IOR(IPMI_IOC_MAGIC, 20, unsigned int)
5171 + * Get/set the default timing values for an interface. You shouldn't
5172 + * generally mess with these.
5174 +struct ipmi_timing_parms
5177 + unsigned int retry_time_ms;
5179 +#define IPMICTL_SET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 22, \
5180 + struct ipmi_timing_parms)
5181 +#define IPMICTL_GET_TIMING_PARMS_CMD _IOR(IPMI_IOC_MAGIC, 23, \
5182 + struct ipmi_timing_parms)
5184 #endif /* __LINUX_IPMI_H */
5185 diff -urN linux-2.4.23.org/include/linux/ipmi_msgdefs.h linux-2.4.23/include/linux/ipmi_msgdefs.h
5186 --- linux-2.4.23.org/include/linux/ipmi_msgdefs.h 2003-12-06 12:52:27.323098678 +0100
5187 +++ linux-2.4.23/include/linux/ipmi_msgdefs.h 2003-12-06 17:46:43.148422471 +0100
5189 /* Various definitions for IPMI messages used by almost everything in
5192 -#define IPMI_NETFN_APP_REQUEST 0x06
5193 -#define IPMI_NETFN_APP_RESPONSE 0x07
5195 -#define IPMI_BMC_SLAVE_ADDR 0x20
5196 +/* NetFNs and commands used inside the IPMI stack. */
5198 +#define IPMI_NETFN_SENSOR_EVENT_REQUEST 0x04
5199 +#define IPMI_NETFN_SENSOR_EVENT_RESPONSE 0x05
5200 +#define IPMI_GET_EVENT_RECEIVER_CMD 0x01
5202 +#define IPMI_NETFN_APP_REQUEST 0x06
5203 +#define IPMI_NETFN_APP_RESPONSE 0x07
5204 #define IPMI_GET_DEVICE_ID_CMD 0x01
5206 #define IPMI_CLEAR_MSG_FLAGS_CMD 0x30
5207 #define IPMI_GET_MSG_FLAGS_CMD 0x31
5208 #define IPMI_SEND_MSG_CMD 0x34
5209 #define IPMI_GET_MSG_CMD 0x33
5211 #define IPMI_SET_BMC_GLOBAL_ENABLES_CMD 0x2e
5212 #define IPMI_GET_BMC_GLOBAL_ENABLES_CMD 0x2f
5213 #define IPMI_READ_EVENT_MSG_BUFFER_CMD 0x35
5215 +#define IPMI_NETFN_STORAGE_REQUEST 0x0a
5216 +#define IPMI_NETFN_STORAGE_RESPONSE 0x0b
5217 +#define IPMI_ADD_SEL_ENTRY_CMD 0x44
5219 +/* The default slave address */
5220 +#define IPMI_BMC_SLAVE_ADDR 0x20
5222 #define IPMI_MAX_MSG_LENGTH 80
5224 +#define IPMI_CC_NO_ERROR 0
5225 +#define IPMI_NODE_BUSY_ERR 0xc0
5226 +#define IPMI_LOST_ARBITRATION_ERR 0x81
5228 #endif /* __LINUX_IPMI_MSGDEFS_H */
5229 diff -urN linux-2.4.23.org/include/linux/ipmi_smi.h linux-2.4.23/include/linux/ipmi_smi.h
5230 --- linux-2.4.23.org/include/linux/ipmi_smi.h 2003-12-06 12:52:27.322098886 +0100
5231 +++ linux-2.4.23/include/linux/ipmi_smi.h 2003-12-06 17:46:43.162419535 +0100
5233 #define __LINUX_IPMI_SMI_H
5235 #include <linux/ipmi_msgdefs.h>
5236 +#include <linux/proc_fs.h>
5237 +#include <linux/module.h>
5239 /* This files describes the interface for IPMI system management interface
5240 drivers to bind into the IPMI message handler. */
5241 @@ -141,4 +143,11 @@
5245 +/* Allow the lower layer to add things to the proc filesystem
5246 + directory for this interface. Note that the entry will
5247 + automatically be dstroyed when the interface is destroyed. */
5248 +int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
5249 + read_proc_t *read_proc, write_proc_t *write_proc,
5250 + void *data, struct module *owner);
5252 #endif /* __LINUX_IPMI_SMI_H */
5253 diff -urN linux-2.4.23.org/include/linux/net.h linux-2.4.23/include/linux/net.h
5254 --- linux-2.4.23.org/include/linux/net.h 2003-12-06 12:52:26.841199031 +0100
5255 +++ linux-2.4.23/include/linux/net.h 2003-12-06 17:46:43.181415550 +0100
5258 struct poll_table_struct;
5260 -#define NPROTO 32 /* should be enough for now.. */
5261 +#define NPROTO 64 /* should be enough for now.. */
5264 #define SYS_SOCKET 1 /* sys_socket(2) */
5265 diff -urN linux-2.4.23.org/include/linux/socket.h linux-2.4.23/include/linux/socket.h
5266 --- linux-2.4.23.org/include/linux/socket.h 2003-12-06 12:52:26.722223807 +0100
5267 +++ linux-2.4.23/include/linux/socket.h 2003-12-06 17:46:43.201411356 +0100
5269 #define AF_WANPIPE 25 /* Wanpipe API Sockets */
5270 #define AF_LLC 26 /* Linux LLC */
5271 #define AF_BLUETOOTH 31 /* Bluetooth sockets */
5272 -#define AF_MAX 32 /* For now.. */
5273 +#define AF_IPMI 32 /* IPMI sockers */
5274 +#define AF_MAX 33 /* For now.. */
5276 /* Protocol families, same as address families. */
5277 #define PF_UNSPEC AF_UNSPEC
5279 #define PF_WANPIPE AF_WANPIPE
5280 #define PF_LLC AF_LLC
5281 #define PF_BLUETOOTH AF_BLUETOOTH
5282 +#define PF_IPMI AF_IPMI
5283 #define PF_MAX AF_MAX
5285 /* Maximum queue length specifiable by listen. */
5286 diff -urN linux-2.4.23.org/include/net/af_ipmi.h linux-2.4.23/include/net/af_ipmi.h
5287 --- linux-2.4.23.org/include/net/af_ipmi.h 1970-01-01 01:00:00.000000000 +0100
5288 +++ linux-2.4.23/include/net/af_ipmi.h 2003-12-06 17:46:43.228405693 +0100
5290 +#ifndef _NET_IPMI_H
5291 +#define _NET_IPMI_H
5293 +#include <linux/ipmi.h>
5296 + * This is ipmi address for socket
5298 +struct sockaddr_ipmi {
5299 + sa_family_t sipmi_family; /* AF_IPMI */
5300 + int if_num; /* IPMI interface number */
5301 + struct ipmi_addr ipmi_addr;
5303 +#define SOCKADDR_IPMI_OVERHEAD (sizeof(struct sockaddr_ipmi) \
5304 + - sizeof(struct ipmi_addr))
5306 +/* A msg_control item, this takes a 'struct ipmi_timing_parms' */
5307 +#define IPMI_CMSG_TIMING_PARMS 0x01
5310 + * This is ipmi message for socket
5312 +struct ipmi_sock_msg {
5316 + unsigned char netfn;
5317 + unsigned char cmd;
5319 + unsigned char data[0];
5322 +#define IPMI_MAX_SOCK_MSG_LENGTH (sizeof(struct ipmi_sock_msg)+IPMI_MAX_MSG_LENGTH)
5324 +/* Register/unregister to receive specific commands. Uses struct
5325 + ipmi_cmdspec from linux/ipmi.h */
5326 +#define SIOCIPMIREGCMD (SIOCPROTOPRIVATE + 0)
5327 +#define SIOCIPMIUNREGCMD (SIOCPROTOPRIVATE + 1)
5329 +/* Register to receive events. Takes an integer */
5330 +#define SIOCIPMIGETEVENT (SIOCPROTOPRIVATE + 2)
5332 +/* Set the default timing parameters for the socket. Takes a struct
5333 + ipmi_timing_parms from linux/ipmi.h */
5334 +#define SIOCIPMISETTIMING (SIOCPROTOPRIVATE + 3)
5335 +#define SIOCIPMIGETTIMING (SIOCPROTOPRIVATE + 4)
5337 +/* Set/Get the IPMB address of the MC we are connected to, takes an
5339 +#define SIOCIPMISETADDR (SIOCPROTOPRIVATE + 5)
5340 +#define SIOCIPMIGETADDR (SIOCPROTOPRIVATE + 6)
5342 +/* Socket information for IPMI for protinfo. */
5345 + struct sockaddr_ipmi addr;
5346 + struct list_head msg_list;
5348 + wait_queue_head_t wait;
5351 + int default_retries;
5352 + unsigned int default_retry_time_ms;
5355 +#endif/*_NET_IPMI_H*/
5356 diff -urN linux-2.4.23.org/include/net/sock.h linux-2.4.23/include/net/sock.h
5357 --- linux-2.4.23.org/include/net/sock.h 2003-12-06 12:52:36.719142002 +0100
5358 +++ linux-2.4.23/include/net/sock.h 2003-12-06 17:46:43.247401708 +0100
5360 #include <net/irda/irda.h>
5363 +#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
5364 +#include <net/af_ipmi.h>
5367 #if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE)
5371 #if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE)
5372 struct wanpipe_opt *af_wanpipe;
5374 +#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
5375 + struct ipmi_sock af_ipmi;
5380 diff -urN linux-2.4.23.org/LOG linux-2.4.23/LOG
5381 --- linux-2.4.23.org/LOG 1970-01-01 01:00:00.000000000 +0100
5382 +++ linux-2.4.23/LOG 2003-12-06 17:46:43.371375702 +0100
5384 +patching file Documentation/Configure.help
5385 +Hunk #1 succeeded at 4226 (offset 974 lines).
5386 +Hunk #2 succeeded at 29341 (offset 1959 lines).
5387 +patching file Documentation/IPMI.txt
5388 +patching file drivers/char/Config.in
5389 +Hunk #1 succeeded at 213 (offset 9 lines).
5390 +patching file drivers/char/ipmi/ipmi_devintf.c
5391 +patching file drivers/char/ipmi/ipmi_kcs_intf.c
5392 +patching file drivers/char/ipmi/ipmi_kcs_sm.c
5393 +patching file drivers/char/ipmi/ipmi_msghandler.c
5394 +patching file drivers/char/ipmi/ipmi_si.c
5395 +patching file drivers/char/ipmi/ipmi_si_sm.h
5396 +patching file drivers/char/ipmi/ipmi_smic_sm.c
5397 +patching file drivers/char/ipmi/ipmi_watchdog.c
5398 +patching file drivers/char/ipmi/Makefile
5399 +patching file include/linux/ipmi.h
5400 +patching file include/linux/ipmi_msgdefs.h
5401 +patching file include/linux/ipmi_smi.h
5402 +patching file include/linux/net.h
5403 +patching file include/linux/socket.h
5404 +Hunk #1 succeeded at 175 (offset 2 lines).
5405 +Hunk #2 succeeded at 208 (offset 2 lines).
5406 +patching file include/net/af_ipmi.h
5407 +patching file include/net/sock.h
5408 +Hunk #1 succeeded at 98 (offset 3 lines).
5409 +Hunk #2 succeeded at 677 (offset 6 lines).
5410 +patching file kernel/panic.c
5411 +Reversed (or previously applied) patch detected! Assume -R? [n]
5414 +1 out of 1 hunk ignored -- saving rejects to file kernel/panic.c.rej
5415 +patching file net/Config.in
5416 +patching file net/ipmi/af_ipmi.c
5417 +patching file net/ipmi/Makefile
5418 +patching file net/Makefile
5419 +Hunk #1 FAILED at 7.
5420 +Hunk #2 succeeded at 47 with fuzz 2 (offset 2 lines).
5421 +1 out of 2 hunks FAILED -- saving rejects to file net/Makefile.rej
5422 diff -urN linux-2.4.23.org/net/Config.in linux-2.4.23/net/Config.in
5423 --- linux-2.4.23.org/net/Config.in 2003-12-06 12:52:51.579047508 +0100
5424 +++ linux-2.4.23/net/Config.in 2003-12-06 17:46:43.327384930 +0100
5427 bool 'Socket Filtering' CONFIG_FILTER
5428 tristate 'Unix domain sockets' CONFIG_UNIX
5429 +tristate 'IPMI sockets' CONFIG_IPMI_SOCKET
5430 bool 'TCP/IP networking' CONFIG_INET
5431 if [ "$CONFIG_INET" = "y" ]; then
5432 source net/ipv4/Config.in
5433 diff -urN linux-2.4.23.org/net/ipmi/af_ipmi.c linux-2.4.23/net/ipmi/af_ipmi.c
5434 --- linux-2.4.23.org/net/ipmi/af_ipmi.c 1970-01-01 01:00:00.000000000 +0100
5435 +++ linux-2.4.23/net/ipmi/af_ipmi.c 2003-12-06 17:46:43.330384301 +0100
5438 + * IPMI Socket Glue
5440 + * Author: Louis Zhuang <louis.zhuang@linux.intel.com>
5441 + * Copyright by Intel Corp., 2003
5443 +#include <linux/module.h>
5444 +#include <linux/config.h>
5445 +#include <linux/kernel.h>
5446 +#include <linux/major.h>
5447 +#include <linux/signal.h>
5448 +#include <linux/sched.h>
5449 +#include <linux/errno.h>
5450 +#include <linux/string.h>
5451 +#include <linux/stat.h>
5452 +#include <linux/socket.h>
5453 +#include <linux/fcntl.h>
5454 +#include <linux/sockios.h>
5455 +#include <linux/net.h>
5456 +#include <linux/in.h>
5457 +#include <linux/fs.h>
5458 +#include <linux/slab.h>
5459 +#include <asm/uaccess.h>
5460 +#include <linux/skbuff.h>
5461 +#include <linux/tcp.h>
5462 +#include <net/sock.h>
5463 +#include <linux/proc_fs.h>
5464 +#include <linux/init.h>
5465 +#include <linux/poll.h>
5466 +#include <linux/smp_lock.h>
5467 +#include <linux/mount.h>
5468 +#include <linux/ipmi.h>
5469 +#include <net/af_ipmi.h>
5470 +#include <linux/rtnetlink.h>
5472 +#define IPMI_SOCKINTF_VERSION "v25"
5474 +#ifdef CONFIG_DEBUG_KERNEL
5475 +static int debug = 0;
5476 +#define dbg(format, arg...) \
5479 + printk (KERN_DEBUG "%s: " format "\n", \
5480 + __FUNCTION__, ## arg); \
5483 +#define dbg(format, arg...)
5484 +#endif /* CONFIG_DEBUG_KERNEL */
5486 +#define err(format, arg...) \
5487 + printk(KERN_ERR "%s: " format "\n", \
5488 + __FUNCTION__ , ## arg)
5489 +#define info(format, arg...) \
5490 + printk(KERN_INFO "%s: " format "\n", \
5491 + __FUNCTION__ , ## arg)
5492 +#define warn(format, arg...) \
5493 + printk(KERN_WARNING "%s: " format "\n", \
5494 + __FUNCTION__ , ## arg)
5495 +#define trace(format, arg...) \
5496 + printk(KERN_INFO "%s(" format ")\n", \
5497 + __FUNCTION__ , ## arg)
5499 +static kmem_cache_t *ipmi_sk_cachep = NULL;
5501 +static atomic_t ipmi_nr_socks = ATOMIC_INIT(0);
5506 + * utility functions
5508 +static inline struct ipmi_sock *to_ipmi_sock(struct sock *sk)
5510 + return &sk->protinfo.af_ipmi;
5513 +static inline void ipmi_release_sock(struct sock *sk, int embrion)
5515 + struct ipmi_sock *i = to_ipmi_sock(sk);
5516 + struct sk_buff *skb;
5519 + ipmi_destroy_user(i->user);
5524 + sk->shutdown = SHUTDOWN_MASK;
5525 + sk->state = TCP_CLOSE;
5527 + while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
5533 +static inline long ipmi_wait_for_queue(struct ipmi_sock *i, long timeo)
5536 + DECLARE_WAITQUEUE(wait, current);
5538 + set_current_state(TASK_INTERRUPTIBLE);
5539 + add_wait_queue_exclusive(&i->wait, &wait);
5540 + timeo = schedule_timeout(timeo);
5541 + set_current_state(TASK_RUNNING);
5542 + remove_wait_queue(&i->wait, &wait);
5547 + * IPMI operation functions
5549 +static void sock_receive_handler(struct ipmi_recv_msg *msg,
5550 + void *handler_data)
5552 + struct ipmi_sock *i = (struct ipmi_sock *)handler_data;
5553 + unsigned long flags;
5555 + spin_lock_irqsave(&i->lock, flags);
5556 + list_add_tail(&msg->link, &i->msg_list);
5557 + spin_unlock_irqrestore(&i->lock, flags);
5559 + wake_up_interruptible(&i->wait);
5563 + * protocol operation functions
5565 +static int ipmi_release(struct socket *sock)
5567 + struct sock *sk = sock->sk;
5573 + ipmi_release_sock(sk, 0);
5577 +static struct ipmi_user_hndl ipmi_hnd = {
5578 + .ipmi_recv_hndl = sock_receive_handler
5581 +static int ipmi_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
5583 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5584 + struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)uaddr;
5585 + int err = -EINVAL;
5587 + if (i->user != NULL) {
5588 + dbg("Cannot bind twice: %p", i->user);
5592 + err = ipmi_create_user(addr->if_num, &ipmi_hnd, i, &i->user);
5594 + dbg("Cannot create user for the socket: %p", i->user);
5598 + memcpy(&i->addr, addr, sizeof(i->addr));
5602 +static int ipmi_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
5604 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5605 + memcpy(uaddr, &i->addr, sizeof(i->addr));
5609 +static unsigned int ipmi_poll(struct file * file, struct socket *sock, poll_table *wait)
5611 + unsigned int has_msg = 0;
5612 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5613 + unsigned long flags;
5615 + poll_wait(file, &i->wait, wait);
5616 + spin_lock_irqsave(&i->lock, flags);
5617 + if (!list_empty(&i->msg_list))
5619 + spin_unlock_irqrestore(&i->lock, flags);
5622 + return POLLIN | POLLRDNORM;
5626 +static int ipmi_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
5628 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5629 + struct ipmi_cmdspec val;
5631 + unsigned int uival;
5634 + dbg("cmd=%#x, arg=%#lx", cmd, arg);
5636 + case SIOCIPMIREGCMD:
5637 + err = copy_from_user((void *)&val, (void *)arg,
5644 + err = ipmi_register_for_cmd(i->user, val.netfn,
5648 + case SIOCIPMIUNREGCMD:
5649 + err = copy_from_user((void *)&val, (void *)arg,
5656 + err = ipmi_unregister_for_cmd(i->user, val.netfn,
5660 + case SIOCIPMIGETEVENT:
5661 + err = copy_from_user((void *)&ival, (void *)arg,
5668 + err = ipmi_set_gets_events(i->user, ival);
5671 + case SIOCIPMISETADDR:
5672 + err = copy_from_user((void *)&uival, (void *)arg,
5679 + ipmi_set_my_address(i->user, uival);
5682 + case SIOCIPMIGETADDR:
5683 + uival = ipmi_get_my_address(i->user);
5685 + if (copy_to_user((void *) arg, &uival, sizeof(uival))) {
5692 + case SIOCIPMISETTIMING:
5694 + struct ipmi_timing_parms parms;
5696 + if (copy_from_user(&parms, (void *) arg, sizeof(parms))) {
5701 + i->default_retries = parms.retries;
5702 + i->default_retry_time_ms = parms.retry_time_ms;
5707 + case SIOCIPMIGETTIMING:
5709 + struct ipmi_timing_parms parms;
5711 + parms.retries = i->default_retries;
5712 + parms.retry_time_ms = i->default_retry_time_ms;
5714 + if (copy_to_user((void *) arg, &parms, sizeof(parms))) {
5724 + err = dev_ioctl(cmd, (void *)arg);
5731 +static int ipmi_recvmsg(struct socket *sock, struct msghdr *msg, int size,
5732 + int rflags, struct scm_cookie *scm)
5734 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5736 + struct ipmi_recv_msg *rcvmsg;
5737 + struct sockaddr_ipmi addr;
5738 + char buf[IPMI_MAX_SOCK_MSG_LENGTH];
5739 + struct ipmi_sock_msg *smsg = (struct ipmi_sock_msg *)buf;
5741 + unsigned long flags;
5743 + timeo = sock_rcvtimeo(sock->sk, rflags & MSG_DONTWAIT);
5746 + spin_lock_irqsave(&i->lock, flags);
5747 + if (!list_empty(&i->msg_list))
5749 + spin_unlock_irqrestore(&i->lock, flags);
5752 + } else if (signal_pending (current)) {
5753 + dbg("Signal pending: %d", 1);
5757 + timeo = ipmi_wait_for_queue(i, timeo);
5760 + rcvmsg = list_entry(i->msg_list.next, struct ipmi_recv_msg, link);
5761 + list_del(&rcvmsg->link);
5762 + spin_unlock_irqrestore(&i->lock, flags);
5764 + memcpy(&addr.ipmi_addr, &rcvmsg->addr, sizeof(addr.ipmi_addr));
5765 + addr.if_num = i->addr.if_num;
5766 + addr.sipmi_family = i->addr.sipmi_family;
5767 + memcpy(msg->msg_name, &addr, sizeof(addr));
5768 + msg->msg_namelen = (SOCKADDR_IPMI_OVERHEAD
5769 + + ipmi_addr_length(rcvmsg->addr.addr_type));
5771 + smsg->recv_type = rcvmsg->recv_type;
5772 + smsg->msgid = rcvmsg->msgid;
5773 + smsg->netfn = rcvmsg->msg.netfn;
5774 + smsg->cmd = rcvmsg->msg.cmd;
5775 + smsg->data_len = rcvmsg->msg.data_len;
5776 + memcpy(smsg->data, rcvmsg->msg.data, smsg->data_len);
5778 + ipmi_free_recv_msg(rcvmsg);
5780 + err = memcpy_toiovec(msg->msg_iov, (void *)smsg,
5781 + sizeof(struct ipmi_sock_msg) + smsg->data_len);
5783 + dbg("Cannot copy data to user: %p", i->user);
5787 + dbg("user=%p", i->user);
5788 + dbg("addr_type=%x, channel=%x",
5789 + addr.ipmi_addr.addr_type, addr.ipmi_addr.channel);
5790 + dbg("netfn=%#02x, cmd=%#02x, data=%p, data_len=%x",
5791 + smsg->netfn, smsg->cmd, smsg->data, smsg->data_len);
5793 + return (sizeof(struct ipmi_sock_msg) + smsg->data_len);
5796 +static int ipmi_sendmsg(struct socket *sock, struct msghdr *msg, int len,
5797 + struct scm_cookie *scm)
5799 + struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5800 + struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)msg->msg_name;
5801 + struct ipmi_msg imsg;
5802 + unsigned char buf[IPMI_MAX_SOCK_MSG_LENGTH];
5803 + struct ipmi_sock_msg *smsg = (struct ipmi_sock_msg *)buf;
5805 + struct ipmi_timing_parms tparms;
5806 + struct cmsghdr *cmsg;
5808 + err = ipmi_validate_addr(&addr->ipmi_addr,
5809 + msg->msg_namelen - SOCKADDR_IPMI_OVERHEAD);
5811 + dbg("Invalid IPMI address: %p", i->user);
5815 + if (len > IPMI_MAX_SOCK_MSG_LENGTH) {
5817 + dbg("Message too long: %p", i->user);
5821 + if (len < sizeof(struct ipmi_sock_msg)) {
5823 + dbg("Msg data too small for header: %p", i->user);
5827 + err = memcpy_fromiovec((void *)smsg, msg->msg_iov, len);
5829 + dbg("Cannot copy data to kernel: %p", i->user);
5833 + if (len < smsg->data_len+sizeof(struct ipmi_sock_msg)) {
5835 + dbg("Msg data is out of bound: %p", i->user);
5839 + /* Set defaults. */
5840 + tparms.retries = i->default_retries;
5841 + tparms.retry_time_ms = i->default_retry_time_ms;
5843 + for (cmsg=CMSG_FIRSTHDR(msg);
5845 + cmsg = CMSG_NXTHDR(msg, cmsg))
5847 + if (cmsg->cmsg_len < sizeof(struct cmsghdr)) {
5849 + dbg("cmsg length too short: %p", i->user);
5853 + if (cmsg->cmsg_level != SOL_SOCKET)
5856 + if (cmsg->cmsg_type == IPMI_CMSG_TIMING_PARMS) {
5857 + struct ipmi_timing_parms *pparms;
5859 + if (cmsg->cmsg_len != CMSG_LEN(sizeof(*pparms))) {
5861 + dbg("timing parms cmsg not right size: %p",
5865 + pparms = (struct ipmi_timing_parms *) CMSG_DATA(cmsg);
5866 + tparms.retries = pparms->retries;
5867 + tparms.retry_time_ms = pparms->retry_time_ms;
5871 + imsg.netfn = smsg->netfn;
5872 + imsg.cmd = smsg->cmd;
5873 + imsg.data = smsg->data;
5874 + imsg.data_len = smsg->data_len;
5876 + dbg("user=%p", i->user);
5877 + dbg("addr_type=%x, channel=%x",
5878 + addr->ipmi_addr.addr_type, addr->ipmi_addr.channel);
5879 + dbg("netfn=%#02x, cmd=%#02x, data=%p, data_len=%x",
5880 + imsg.netfn, imsg.cmd, imsg.data, imsg.data_len);
5881 + err = ipmi_request_settime(i->user, &addr->ipmi_addr,
5882 + smsg->msgid, &imsg, 0,
5883 + tparms.retries, tparms.retry_time_ms);
5885 + dbg("Cannot send message: %p", i->user);
5893 +static struct proto_ops ipmi_ops = {
5894 + .family = PF_IPMI,
5895 + .release = ipmi_release,
5896 + .bind = ipmi_bind,
5897 + .connect = sock_no_connect,
5898 + .socketpair = sock_no_socketpair,
5899 + .accept = sock_no_accept,
5900 + .getname = ipmi_getname,
5901 + .poll = ipmi_poll,
5902 + .ioctl = ipmi_ioctl,
5903 + .listen = sock_no_listen,
5904 + .shutdown = sock_no_shutdown,
5905 + .setsockopt = sock_no_setsockopt,
5906 + .getsockopt = sock_no_getsockopt,
5907 + .sendmsg = ipmi_sendmsg,
5908 + .recvmsg = ipmi_recvmsg,
5909 + .mmap = sock_no_mmap,
5910 + .sendpage = sock_no_sendpage
5914 +static void ipmi_sock_destructor(struct sock *sk)
5916 + skb_queue_purge(&sk->receive_queue);
5918 + BUG_TRAP(atomic_read(&sk->wmem_alloc) == 0);
5919 + BUG_TRAP(sk->socket==NULL);
5920 + if (sk->dead==0) {
5921 + printk("Attempt to release alive ipmi socket: %p\n", sk);
5925 + atomic_dec(&ipmi_nr_socks);
5926 + MOD_DEC_USE_COUNT;
5930 + * net protocol functions
5932 +static struct sock *ipmi_socket_create1(struct socket *sock)
5936 + if (atomic_read(&ipmi_nr_socks) >= 2*files_stat.max_files)
5939 + MOD_INC_USE_COUNT;
5941 + sk = sk_alloc(PF_IPMI, GFP_KERNEL, 1);
5943 + MOD_DEC_USE_COUNT;
5947 + sock_init_data(sock, sk);
5948 + sock->sk->rcvtimeo = 5*HZ;
5949 + sock->sk->destruct = ipmi_sock_destructor;
5950 + spin_lock_init(&sk->protinfo.af_ipmi.lock);
5951 + INIT_LIST_HEAD(&sk->protinfo.af_ipmi.msg_list);
5952 + init_waitqueue_head(&sk->protinfo.af_ipmi.wait);
5954 + /* Set to use default values. */
5955 + sk->protinfo.af_ipmi.default_retries = -1;
5956 + sk->protinfo.af_ipmi.default_retry_time_ms = 0;
5958 + atomic_inc(&ipmi_nr_socks);
5962 +static int ipmi_socket_create(struct socket *sock, int protocol)
5964 + if (!capable(CAP_NET_RAW))
5966 + if (protocol && protocol != PF_IPMI)
5967 + return -EPROTONOSUPPORT;
5969 + sock->state = SS_UNCONNECTED;
5971 + switch (sock->type) {
5973 + sock->type=SOCK_DGRAM;
5975 + sock->ops = &ipmi_ops;
5978 + return -EPROTONOSUPPORT;
5981 + return ipmi_socket_create1(sock)? 0 : -ENOMEM;
5984 +static struct net_proto_family ipmi_family_ops = {
5985 + .family = PF_IPMI,
5986 + .create = ipmi_socket_create,
5991 + * init/exit functions
5993 +static int __init ipmi_socket_init(void)
5998 + printk(KERN_INFO "ipmi socket interface version "
5999 + IPMI_SOCKINTF_VERSION "\n");
6001 + ipmi_sk_cachep = kmem_cache_create("ipmi_sock",
6002 + sizeof(struct ipmi_sock), 0,
6003 + SLAB_HWCACHE_ALIGN, 0, 0);
6004 + if (!ipmi_sk_cachep) {
6005 + printk(KERN_CRIT "%s: Unable to create ipmi_sock SLAB cache\n", __func__);
6010 + err = sock_register(&ipmi_family_ops);
6012 + kmem_cache_destroy(ipmi_sk_cachep);
6017 +static void __exit ipmi_socket_exit(void)
6019 + sock_unregister(PF_IPMI);
6020 + kmem_cache_destroy(ipmi_sk_cachep);
6023 +#ifdef CONFIG_DEBUG_KERNEL
6024 +MODULE_PARM(debug, "i");
6026 +module_init(ipmi_socket_init);
6027 +module_exit(ipmi_socket_exit);
6029 +MODULE_LICENSE("GPL");
6030 diff -urN linux-2.4.23.org/net/ipmi/Makefile linux-2.4.23/net/ipmi/Makefile
6031 --- linux-2.4.23.org/net/ipmi/Makefile 1970-01-01 01:00:00.000000000 +0100
6032 +++ linux-2.4.23/net/ipmi/Makefile 2003-12-06 17:46:43.353379477 +0100
6037 +obj-$(CONFIG_IPMI_SOCKET) = af_ipmi.o
6039 +include $(TOPDIR)/Rules.make
6041 diff -urN linux-2.4.23.org/net/Makefile linux-2.4.23/net/Makefile
6042 --- linux-2.4.23.org/net/Makefile 2003-12-06 12:52:51.596043969 +0100
6043 +++ linux-2.4.23/net/Makefile 2003-12-06 17:48:04.493359735 +0100
6045 O_TARGET := network.o
6047 mod-subdirs := ipv4/netfilter ipv6/netfilter bridge/netfilter ipx irda \
6048 - bluetooth atm netlink sched core sctp
6049 + bluetooth atm netlink sched core sctp ipmi
6050 export-objs := netsyms.o
6052 subdir-y := core ethernet
6054 subdir-$(CONFIG_DECNET) += decnet
6055 subdir-$(CONFIG_ECONET) += econet
6056 subdir-$(CONFIG_VLAN_8021Q) += 8021q
6057 +subdir-$(CONFIG_IPMI_SOCKET) += ipmi
6059 ifeq ($(CONFIG_NETFILTER),y)
6060 mod-subdirs += ipv4/ipvs