]> git.pld-linux.org Git - packages/kernel.git/blame - linux-2.4.23-ipmi-v27.patch
- obsolete
[packages/kernel.git] / linux-2.4.23-ipmi-v27.patch
CommitLineData
10b3bcd5
AM
1diff -urN linux-2.4.23.org/Documentation/Configure.help linux-2.4.23/Documentation/Configure.help
2--- linux-2.4.23.org/Documentation/Configure.help 2003-12-06 17:45:52.831977967 +0100
3+++ linux-2.4.23/Documentation/Configure.help 2003-12-06 17:46:42.774500910 +0100
4@@ -4226,6 +4226,13 @@
5
6 If unsure, say N.
7
8+IPMI sockets
9+CONFIG_IPMI_SOCKET
10+ If you say Y here, you will include support for IPMI sockets;
11+ This is the better way for establishing and accessing IPMI devices.
12+
13+ If unsure, say N.
14+
15 # Choice: alphatype
16 Alpha system type
17 CONFIG_ALPHA_GENERIC
18@@ -29334,14 +29341,32 @@
19 generate an IPMI event describing the panic to each interface
20 registered with the message handler.
21
22+Generate OEM events containing the panic string
23+CONFIG_IPMI_PANIC_STRING
24+ When a panic occurs, this will cause the IPMI message handler to
25+ generate IPMI OEM type f0 events holding the IPMB address of the
26+ panic generator (byte 4 of the event), a sequence number for the
27+ string (byte 5 of the event) and part of the string (the rest of the
28+ event). Bytes 1, 2, and 3 are the normal usage for an OEM event.
29+ You can fetch these events and use the sequence numbers to piece the
30+ string together.
31+
32 Device interface for IPMI
33 CONFIG_IPMI_DEVICE_INTERFACE
34 This provides an IOCTL interface to the IPMI message handler so
35 userland processes may use IPMI. It supports poll() and select().
36
37+IPMI SI handler
38+CONFIG_IPMI_SI
39+ Provides a driver for System Interfaces (KCS, SMIC, BT).
40+ Currently, only KCS and SMIC are supported. If
41+ you are using IPMI, you should probably say "y" here.
42+
43 IPMI KCS handler
44 CONFIG_IPMI_KCS
45- Provides a driver for a KCS-style interface to a BMC.
46+ Provides a driver for a KCS-style interface to a BMC. This
47+ is deprecated, please use the IPMI System Interface handler
48+ instead.
49
50 IPMI Watchdog Timer
51 CONFIG_IPMI_WATCHDOG
52diff -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
55@@ -41,18 +41,29 @@
56 driver, each open file for this device ties in to the message handler
57 as an IPMI user.
58
59-ipmi_kcs_drv - A driver for the KCS SMI. Most system have a KCS
60-interface for IPMI.
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.
64+
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
67+SMIC interfaces.
68+
69+af_ipmi - A network socket interface to IPMI. This doesn't take up
70+a character device in your system.
71
72
73 Much documentation for the interface is in the include files. The
74 IPMI include files are:
75
76-ipmi.h - Contains the user interface and IOCTL interface for IPMI.
77+net/af_ipmi.h - Contains the socket interface.
78+
79+linux/ipmi.h - Contains the user interface and IOCTL interface for IPMI.
80
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.
84
85-ipmi_msgdefs.h - General definitions for base IPMI messaging.
86+linux/ipmi_msgdefs.h - General definitions for base IPMI messaging.
87
88
89 Addressing
90@@ -260,8 +271,66 @@
91 in the order they register, although if an SMI unregisters and then
92 another one registers, all bets are off.
93
94-The ipmi_smi.h defines the interface for SMIs, see that for more
95-details.
96+The ipmi_smi.h defines the interface for management interfaces, see
97+that for more details.
98+
99+
100+The SI Driver
101+-------------
102+
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:
108+
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]
112+
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.
115+
116+The si_type may be either "kcs" or "smic". If you leave it blank, it
117+defaults to "kcs".
118+
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
121+overrides si_ports.
122+
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.
125+
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.
128+
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.
132+
133+When compiled into the kernel, the addresses can be specified on the
134+kernel command line as:
135+
136+ ipmi_si=[<type>,]<bmc1>:<irq1>,[<type>,]<bmc2>:<irq2>....,[nodefault]
137+
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.
146+
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.
150+
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.
156
157
158 The KCS Driver
159@@ -323,7 +392,10 @@
160
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).
168
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
171diff -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
174@@ -213,7 +213,9 @@
175
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
183
184diff -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
187@@ -44,6 +44,8 @@
188 #include <asm/semaphore.h>
189 #include <linux/init.h>
190
191+#define IPMI_DEVINTF_VERSION "v27"
192+
193 struct ipmi_file_private
194 {
195 ipmi_user_t user;
196@@ -53,6 +55,8 @@
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;
202 };
203
204 static void file_receive_handler(struct ipmi_recv_msg *msg,
205@@ -105,7 +109,7 @@
206
207 static struct ipmi_user_hndl ipmi_hndlrs =
208 {
209- ipmi_recv_hndl : file_receive_handler
210+ .ipmi_recv_hndl = file_receive_handler,
211 };
212
213 static int ipmi_open(struct inode *inode, struct file *file)
214@@ -138,6 +142,10 @@
215 priv->fasync_queue = NULL;
216 sema_init(&(priv->recv_sem), 1);
217
218+ /* Use the low-level defaults. */
219+ priv->default_retries = -1;
220+ priv->default_retry_time_ms = 0;
221+
222 return 0;
223 }
224
225@@ -158,6 +166,47 @@
226 return 0;
227 }
228
229+static int handle_send_req(ipmi_user_t user,
230+ struct ipmi_req *req,
231+ int retries,
232+ unsigned int retry_time_ms)
233+{
234+ int rv;
235+ struct ipmi_addr addr;
236+ unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
237+
238+ if (req->addr_len > sizeof(struct ipmi_addr))
239+ return -EINVAL;
240+
241+ if (copy_from_user(&addr, req->addr, req->addr_len))
242+ return -EFAULT;
243+
244+ rv = ipmi_validate_addr(&addr, req->addr_len);
245+ if (rv)
246+ return rv;
247+
248+ if (req->msg.data != NULL) {
249+ if (req->msg.data_len > IPMI_MAX_MSG_LENGTH)
250+ return -EMSGSIZE;
251+
252+ if (copy_from_user(&msgdata,
253+ req->msg.data,
254+ req->msg.data_len))
255+ return -EFAULT;
256+ } else {
257+ req->msg.data_len = 0;
258+ }
259+ req->msg.data = msgdata;
260+
261+ return ipmi_request_settime(user,
262+ &addr,
263+ req->msgid,
264+ &(req->msg),
265+ 0,
266+ retries,
267+ retry_time_ms);
268+}
269+
270 static int ipmi_ioctl(struct inode *inode,
271 struct file *file,
272 unsigned int cmd,
273@@ -170,54 +219,33 @@
274 {
275 case IPMICTL_SEND_COMMAND:
276 {
277- struct ipmi_req req;
278- struct ipmi_addr addr;
279- unsigned char msgdata[IPMI_MAX_MSG_LENGTH];
280+ struct ipmi_req req;
281
282 if (copy_from_user(&req, (void *) data, sizeof(req))) {
283 rv = -EFAULT;
284 break;
285 }
286
287- if (req.addr_len > sizeof(struct ipmi_addr))
288- {
289- rv = -EINVAL;
290- break;
291- }
292+ rv = handle_send_req(priv->user,
293+ &req,
294+ priv->default_retries,
295+ priv->default_retry_time_ms);
296+ break;
297+ }
298
299- if (copy_from_user(&addr, req.addr, req.addr_len)) {
300+ case IPMICTL_SEND_COMMAND_SETTIME:
301+ {
302+ struct ipmi_req_settime req;
303+
304+ if (copy_from_user(&req, (void *) data, sizeof(req))) {
305 rv = -EFAULT;
306 break;
307 }
308
309- rv = ipmi_validate_addr(&addr, req.addr_len);
310- if (rv)
311- break;
312-
313- if (req.msg.data != NULL) {
314- if (req.msg.data_len > IPMI_MAX_MSG_LENGTH) {
315- rv = -EMSGSIZE;
316- break;
317- }
318-
319- if (copy_from_user(&msgdata,
320- req.msg.data,
321- req.msg.data_len))
322- {
323- rv = -EFAULT;
324- break;
325- }
326- } else {
327- req.msg.data_len = 0;
328- }
329-
330- req.msg.data = msgdata;
331-
332- rv = ipmi_request(priv->user,
333- &addr,
334- req.msgid,
335- &(req.msg),
336- 0);
337+ rv = handle_send_req(priv->user,
338+ &req.req,
339+ req.retries,
340+ req.retry_time_ms);
341 break;
342 }
343
344@@ -416,7 +444,36 @@
345 rv = 0;
346 break;
347 }
348+ case IPMICTL_SET_TIMING_PARMS_CMD:
349+ {
350+ struct ipmi_timing_parms parms;
351+
352+ if (copy_from_user(&parms, (void *) data, sizeof(parms))) {
353+ rv = -EFAULT;
354+ break;
355+ }
356+
357+ priv->default_retries = parms.retries;
358+ priv->default_retry_time_ms = parms.retry_time_ms;
359+ rv = 0;
360+ break;
361+ }
362+
363+ case IPMICTL_GET_TIMING_PARMS_CMD:
364+ {
365+ struct ipmi_timing_parms parms;
366+
367+ parms.retries = priv->default_retries;
368+ parms.retry_time_ms = priv->default_retry_time_ms;
369
370+ if (copy_to_user((void *) data, &parms, sizeof(parms))) {
371+ rv = -EFAULT;
372+ break;
373+ }
374+
375+ rv = 0;
376+ break;
377+ }
378 }
379
380 return rv;
381@@ -424,12 +481,12 @@
382
383
384 static struct file_operations ipmi_fops = {
385- owner: THIS_MODULE,
386- ioctl: ipmi_ioctl,
387- open: ipmi_open,
388- release: ipmi_release,
389- fasync: ipmi_fasync,
390- poll: ipmi_poll
391+ .owner = THIS_MODULE,
392+ .ioctl = ipmi_ioctl,
393+ .open = ipmi_open,
394+ .release = ipmi_release,
395+ .fasync = ipmi_fasync,
396+ .poll = ipmi_poll,
397 };
398
399 #define DEVICE_NAME "ipmidev"
400@@ -468,8 +525,9 @@
401
402 static struct ipmi_smi_watcher smi_watcher =
403 {
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,
409 };
410
411 static __init int init_ipmi_devintf(void)
412@@ -479,6 +537,9 @@
413 if (ipmi_major < 0)
414 return -EINVAL;
415
416+ printk(KERN_INFO "ipmi device interface version "
417+ IPMI_DEVINTF_VERSION "\n");
418+
419 rv = register_chrdev(ipmi_major, DEVICE_NAME, &ipmi_fops);
420 if (rv < 0) {
421 printk(KERN_ERR "ipmi: can't get major %d\n", ipmi_major);
422@@ -498,9 +559,6 @@
423 return rv;
424 }
425
426- printk(KERN_INFO "ipmi: device interface at char major %d\n",
427- ipmi_major);
428-
429 return 0;
430 }
431 module_init(init_ipmi_devintf);
432diff -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
435@@ -54,7 +54,7 @@
436 #include <linux/interrupt.h>
437 #include <linux/ipmi_smi.h>
438 #include <asm/io.h>
439-#include "ipmi_kcs_sm.h"
440+#include "ipmi_si_sm.h"
441 #include <linux/init.h>
442
443 /* Measure times between events in the driver. */
444@@ -72,6 +72,8 @@
445 /* This forces a dependency to the config file for this option. */
446 #endif
447
448+extern struct si_sm_handlers kcs_smi_handlers;
449+
450 enum kcs_intf_state {
451 KCS_NORMAL,
452 KCS_GETTING_FLAGS,
453@@ -87,7 +89,7 @@
454 struct kcs_info
455 {
456 ipmi_smi_t intf;
457- struct kcs_data *kcs_sm;
458+ struct si_sm_data *kcs_sm;
459 spinlock_t kcs_lock;
460 spinlock_t msg_lock;
461 struct list_head xmit_msgs;
462@@ -112,8 +114,10 @@
463 out. */
464 int run_to_completion;
465
466+ struct si_sm_io io;
467+
468 /* The I/O port of a KCS interface. */
469- int port;
470+ unsigned int port;
471
472 /* zero if no irq; */
473 int irq;
474@@ -164,7 +168,7 @@
475 deliver_recv_msg(kcs_info, msg);
476 }
477
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)
480 {
481 int rv;
482 struct list_head *entry = NULL;
483@@ -185,7 +189,7 @@
484
485 if (!entry) {
486 kcs_info->curr_msg = NULL;
487- rv = KCS_SM_IDLE;
488+ rv = SI_SM_IDLE;
489 } else {
490 int err;
491
492@@ -197,14 +201,15 @@
493 do_gettimeofday(&t);
494 printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
495 #endif
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(
500+ kcs_info->kcs_sm,
501+ kcs_info->curr_msg->data,
502+ kcs_info->curr_msg->data_size);
503 if (err) {
504 return_hosed_msg(kcs_info);
505 }
506
507- rv = KCS_CALL_WITHOUT_DELAY;
508+ rv = SI_SM_CALL_WITHOUT_DELAY;
509 }
510 spin_unlock(&(kcs_info->msg_lock));
511
512@@ -220,7 +225,7 @@
513 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
514 msg[1] = IPMI_GET_BMC_GLOBAL_ENABLES_CMD;
515
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;
519 }
520
521@@ -233,7 +238,7 @@
522 msg[1] = IPMI_CLEAR_MSG_FLAGS_CMD;
523 msg[2] = WDT_PRE_TIMEOUT_INT;
524
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;
528 }
529
530@@ -280,9 +285,10 @@
531 kcs_info->curr_msg->data[1] = IPMI_GET_MSG_CMD;
532 kcs_info->curr_msg->data_size = 2;
533
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(
538+ kcs_info->kcs_sm,
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. */
544@@ -298,9 +304,10 @@
545 kcs_info->curr_msg->data[1] = IPMI_READ_EVENT_MSG_BUFFER_CMD;
546 kcs_info->curr_msg->data_size = 2;
547
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(
552+ kcs_info->kcs_sm,
553+ kcs_info->curr_msg->data,
554+ kcs_info->curr_msg->data_size);
555 kcs_info->kcs_state = KCS_GETTING_EVENTS;
556 } else {
557 kcs_info->kcs_state = KCS_NORMAL;
558@@ -322,9 +329,10 @@
559 break;
560
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(
566+ kcs_info->kcs_sm,
567+ kcs_info->curr_msg->rsp,
568+ IPMI_MAX_MSG_LENGTH);
569
570 /* Do this here becase deliver_recv_msg() releases the
571 lock, and a new message can be put in during the
572@@ -340,7 +348,7 @@
573 unsigned int len;
574
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);
578 if (msg[2] != 0) {
579 /* Error fetching flags, just give up for
580 now. */
581@@ -362,7 +370,7 @@
582 unsigned char msg[3];
583
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);
587 if (msg[2] != 0) {
588 /* Error clearing flags */
589 printk(KERN_WARNING
590@@ -379,9 +387,9 @@
591 case KCS_GETTING_EVENTS:
592 {
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);
600
601 /* Do this here becase deliver_recv_msg() releases the
602 lock, and a new message can be put in during the
603@@ -404,9 +412,9 @@
604 case KCS_GETTING_MESSAGES:
605 {
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);
613
614 /* Do this here becase deliver_recv_msg() releases the
615 lock, and a new message can be put in during the
616@@ -431,7 +439,7 @@
617 unsigned char msg[4];
618
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);
622 if (msg[2] != 0) {
623 printk(KERN_WARNING
624 "ipmi_kcs: Could not enable interrupts"
625@@ -441,7 +449,8 @@
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;
633 }
634 break;
635@@ -452,7 +461,7 @@
636 unsigned char msg[4];
637
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);
641 if (msg[2] != 0) {
642 printk(KERN_WARNING
643 "ipmi_kcs: Could not enable interrupts"
644@@ -466,9 +475,10 @@
645
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,
650+ int time)
651 {
652- enum kcs_result kcs_result;
653+ enum si_sm_result kcs_result;
654
655 restart:
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);
663 time = 0;
664- while (kcs_result == KCS_CALL_WITHOUT_DELAY)
665+ while (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
666 {
667- kcs_result = kcs_event(kcs_info->kcs_sm, 0);
668+ kcs_result = kcs_smi_handlers.event(kcs_info->kcs_sm, 0);
669 }
670
671- if (kcs_result == KCS_TRANSACTION_COMPLETE)
672+ if (kcs_result == SI_SM_TRANSACTION_COMPLETE)
673 {
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);
677 }
678- else if (kcs_result == KCS_SM_HOSED)
679+ else if (kcs_result == SI_SM_HOSED)
680 {
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);
686 }
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;
690 }
691
692 /* We prefer handling attn over new messages. */
693- if (kcs_result == KCS_ATTN)
694+ if (kcs_result == SI_SM_ATTN)
695 {
696 unsigned char msg[2];
697
698@@ -514,19 +524,19 @@
699 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
700 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
701
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;
705 goto restart;
706 }
707
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)
714 goto restart;
715 }
716
717- if ((kcs_result == KCS_SM_IDLE)
718+ if ((kcs_result == SI_SM_IDLE)
719 && (atomic_read(&kcs_info->req_events)))
720 {
721 /* We are idle and the upper layer requested that I fetch
722@@ -537,7 +547,7 @@
723 msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
724 msg[1] = IPMI_GET_MSG_FLAGS_CMD;
725
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;
729 goto restart;
730 }
731@@ -549,11 +559,11 @@
732 struct ipmi_smi_msg *msg,
733 int priority)
734 {
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;
741 #ifdef DEBUG_TIMING
742- struct timeval t;
743+ struct timeval t;
744 #endif
745
746 spin_lock_irqsave(&(kcs_info->msg_lock), flags);
747@@ -574,7 +584,7 @@
748
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 @@
757
758 static void set_run_to_completion(void *send_info, int i_run_to_completion)
759 {
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;
766
767 spin_lock_irqsave(&(kcs_info->kcs_lock), flags);
768
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 @@
778
779 static void kcs_timeout(unsigned long data)
780 {
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;
791 #ifdef DEBUG_TIMING
792- struct timeval t;
793+ struct timeval t;
794 #endif
795
796 if (kcs_info->stop_operation) {
797@@ -712,7 +722,7 @@
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) {
806@@ -725,7 +735,7 @@
807 }
808 #else
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;
813 } else {
814 kcs_info->kcs_timer.expires = jiffies + KCS_TIMEOUT_JIFFIES;
815@@ -776,12 +786,12 @@
816 extern int kcs_dbg;
817 static int ipmi_kcs_detect_hardware(unsigned int port,
818 unsigned char *addr,
819- struct kcs_data *data)
820+ struct si_sm_data *data)
821 {
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;
830
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 @@
834 useful info. */
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);
839
840- kcs_result = kcs_event(data, 0);
841+ kcs_result = kcs_smi_handlers.event(data, 0);
842 for (;;)
843 {
844- if (kcs_result == KCS_CALL_WITH_DELAY) {
845- udelay(100);
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);
850 }
851- else if (kcs_result == KCS_CALL_WITHOUT_DELAY)
852+ else if (kcs_result == SI_SM_CALL_WITHOUT_DELAY)
853 {
854- kcs_result = kcs_event(data, 0);
855+ kcs_result = kcs_smi_handlers.event(data, 0);
856 }
857 else
858 break;
859 }
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. */
864 return -ENODEV;
865 }
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);
870 if (resp_len < 6)
871 /* That's odd, it should be longer. */
872 return -EINVAL;
873@@ -860,6 +871,36 @@
874 MODULE_PARM(kcs_irqs, "1-4i");
875 MODULE_PARM(kcs_ports, "1-4i");
876
877+static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
878+{
879+ struct kcs_info *info = io->info;
880+
881+ return inb(info->port+offset);
882+}
883+
884+static void port_outb(struct si_sm_io *io, unsigned int offset,
885+ unsigned char b)
886+{
887+ struct kcs_info *info = io->info;
888+
889+ outb(b, info->port+offset);
890+}
891+
892+static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
893+{
894+ struct kcs_info *info = io->info;
895+
896+ return readb(info->addr+offset);
897+}
898+
899+static void mem_outb(struct si_sm_io *io, unsigned int offset,
900+ unsigned char b)
901+{
902+ struct kcs_info *info = io->info;
903+
904+ writeb(b, info->addr+offset);
905+}
906+
907 /* Returns 0 if initialized, or negative on an error. */
908 static int init_one_kcs(int kcs_port,
909 int irq,
910@@ -902,6 +943,9 @@
911 kcs_port);
912 return -EIO;
913 }
914+ new_kcs->io.outputb = port_outb;
915+ new_kcs->io.inputb = port_inb;
916+ new_kcs->io.info = new_kcs;
917 } else {
918 if (request_mem_region(kcs_physaddr, 2, DEVICE_NAME) == NULL) {
919 kfree(new_kcs);
920@@ -917,15 +961,18 @@
921 kcs_physaddr);
922 return -EIO;
923 }
924+ new_kcs->io.outputb = mem_outb;
925+ new_kcs->io.inputb = mem_inb;
926+ new_kcs->io.info = new_kcs;
927 }
928
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");
933 rv = -ENOMEM;
934 goto out_err;
935 }
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));
940
941@@ -1027,11 +1074,7 @@
942
943 #ifdef CONFIG_ACPI_INTERPRETER
944
945-/* Retrieve the base physical address from ACPI tables. Originally
946- from Hewlett-Packard simple bmc.c, a GPL KCS driver. */
947-
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 @@
954 s8 OEMRevision[4];
955 s8 CreatorID[4];
956 s8 CreatorRevision[4];
957- s16 InterfaceType;
958+ u8 InterfaceType[2];
959 s16 SpecificationRevision;
960+
961+ /*
962+ * Bit 0 - SCI interrupt supported
963+ * Bit 1 - I/O APIC/SAPIC
964+ */
965 u8 InterruptType;
966+
967+ /* If bit 0 of InterruptType is set, then this is the SCI
968+ interrupt in the GPEx_STS register. */
969 u8 GPE;
970+
971 s16 Reserved;
972- u64 GlobalSystemInterrupt;
973- u8 BaseAddress[12];
974+
975+ /* If bit 1 of InterruptType is set, then this is the I/O
976+ APIC/SAPIC interrupt. */
977+ u32 GlobalSystemInterrupt;
978+
979+ /* The actual register address. */
980+ struct acpi_generic_address addr;
981+
982 u8 UID[4];
983-} __attribute__ ((packed));
984
985-static unsigned long acpi_find_bmc(void)
986+ s8 spmi_id[1]; /* A '\0' terminated array starts here. */
987+};
988+
989+static int acpi_find_bmc(unsigned long *physaddr, int *port)
990 {
991 acpi_status status;
992- struct acpi_table_header *spmi;
993- static unsigned long io_base = 0;
994-
995- if (io_base != 0)
996- return io_base;
997+ struct SPMITable *spmi;
998
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)
1004+ goto not_found;
1005+
1006+ if (spmi->InterfaceType[0] != 1)
1007+ /* Not IPMI. */
1008+ goto not_found;
1009+
1010+ if (spmi->InterfaceType[1] != 1)
1011+ /* Not KCS. */
1012+ goto not_found;
1013+
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);
1024+ } else
1025+ goto not_found; /* Not an address type we recognise. */
1026
1027- if (status != AE_OK) {
1028- printk(KERN_ERR "ipmi_kcs: SPMI table not found.\n");
1029- return 0;
1030- }
1031+ return 0;
1032
1033- memcpy(&io_base, ((struct SPMITable *)spmi)->BaseAddress,
1034- sizeof(io_base));
1035-
1036- return io_base;
1037+ not_found:
1038+ return -ENODEV;
1039 }
1040 #endif
1041
1042@@ -1087,6 +1162,7 @@
1043 int i = 0;
1044 #ifdef CONFIG_ACPI_INTERPRETER
1045 unsigned long physaddr = 0;
1046+ int port = 0;
1047 #endif
1048
1049 if (initialized)
1050@@ -1114,26 +1190,25 @@
1051 /* Only try the defaults if enabled and resources are available
1052 (because they weren't already specified above). */
1053
1054- if (kcs_trydefaults) {
1055+ if (kcs_trydefaults && (pos == 0)) {
1056+ rv = -EINVAL;
1057 #ifdef CONFIG_ACPI_INTERPRETER
1058- if ((physaddr = acpi_find_bmc())) {
1059- if (!check_mem_region(physaddr, 2)) {
1060- rv = init_one_kcs(0,
1061- 0,
1062- physaddr,
1063- &(kcs_infos[pos]));
1064- if (rv == 0)
1065- pos++;
1066- }
1067+ if (rv && (acpi_find_bmc(&physaddr, &port) == 0)) {
1068+ rv = init_one_kcs(port,
1069+ 0,
1070+ physaddr,
1071+ &(kcs_infos[pos]));
1072+ if (rv == 0)
1073+ pos++;
1074 }
1075 #endif
1076- if (!check_region(DEFAULT_IO_PORT, 2)) {
1077+ if (rv) {
1078 rv = init_one_kcs(DEFAULT_IO_PORT,
1079 0,
1080 0,
1081 &(kcs_infos[pos]));
1082 if (rv == 0)
1083- pos++;
1084+ pos++;
1085 }
1086 }
1087
1088diff -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
1091@@ -37,10 +37,11 @@
1092 * that document.
1093 */
1094
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"
1100
1101-#include "ipmi_kcs_sm.h"
1102+#define IPMI_KCS_VERSION "v27"
1103
1104 /* Set this if you want a printout of why the state machine was hosed
1105 when it gets hosed. */
1106@@ -95,29 +96,28 @@
1107 #define IPMI_ERR_MSG_TRUNCATED 0xc6
1108 #define IPMI_ERR_UNSPECIFIED 0xff
1109
1110-struct kcs_data
1111+struct si_sm_data
1112 {
1113- enum kcs_states state;
1114- unsigned int port;
1115- unsigned char *addr;
1116- unsigned char write_data[MAX_KCS_WRITE_SIZE];
1117- int write_pos;
1118- int write_count;
1119- int orig_write_count;
1120- unsigned char read_data[MAX_KCS_READ_SIZE];
1121- int read_pos;
1122- int truncated;
1123+ enum kcs_states state;
1124+ struct si_sm_io *io;
1125+ unsigned char write_data[MAX_KCS_WRITE_SIZE];
1126+ int write_pos;
1127+ int write_count;
1128+ int orig_write_count;
1129+ unsigned char read_data[MAX_KCS_READ_SIZE];
1130+ int read_pos;
1131+ int truncated;
1132
1133 unsigned int error_retries;
1134 long ibf_timeout;
1135 long obf_timeout;
1136 };
1137
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)
1141 {
1142 kcs->state = KCS_IDLE;
1143- kcs->port = port;
1144- kcs->addr = addr;
1145+ kcs->io = io;
1146 kcs->write_pos = 0;
1147 kcs->write_count = 0;
1148 kcs->orig_write_count = 0;
1149@@ -126,40 +126,29 @@
1150 kcs->truncated = 0;
1151 kcs->ibf_timeout = IBF_RETRY_TIMEOUT;
1152 kcs->obf_timeout = OBF_RETRY_TIMEOUT;
1153-}
1154
1155-/* Remember, init_one_kcs() insured port and addr can't both be set */
1156+ /* Reserve 2 I/O bytes. */
1157+ return 2;
1158+}
1159
1160-static inline unsigned char read_status(struct kcs_data *kcs)
1161+static inline unsigned char read_status(struct si_sm_data *kcs)
1162 {
1163- if (kcs->port)
1164- return inb(kcs->port + 1);
1165- else
1166- return readb(kcs->addr + 1);
1167+ return kcs->io->inputb(kcs->io, 1);
1168 }
1169
1170-static inline unsigned char read_data(struct kcs_data *kcs)
1171+static inline unsigned char read_data(struct si_sm_data *kcs)
1172 {
1173- if (kcs->port)
1174- return inb(kcs->port + 0);
1175- else
1176- return readb(kcs->addr + 0);
1177+ return kcs->io->inputb(kcs->io, 0);
1178 }
1179
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)
1182 {
1183- if (kcs->port)
1184- outb(data, kcs->port + 1);
1185- else
1186- writeb(data, kcs->addr + 1);
1187+ kcs->io->outputb(kcs->io, 1, data);
1188 }
1189
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)
1192 {
1193- if (kcs->port)
1194- outb(data, kcs->port + 0);
1195- else
1196- writeb(data, kcs->addr + 0);
1197+ kcs->io->outputb(kcs->io, 0, data);
1198 }
1199
1200 /* Control codes. */
1201@@ -179,14 +168,14 @@
1202 #define GET_STATUS_OBF(status) ((status) & 0x01)
1203
1204
1205-static inline void write_next_byte(struct kcs_data *kcs)
1206+static inline void write_next_byte(struct si_sm_data *kcs)
1207 {
1208 write_data(kcs, kcs->write_data[kcs->write_pos]);
1209 (kcs->write_pos)++;
1210 (kcs->write_count)--;
1211 }
1212
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)
1215 {
1216 (kcs->error_retries)++;
1217 if (kcs->error_retries > MAX_ERROR_RETRIES) {
1218@@ -199,7 +188,7 @@
1219 }
1220 }
1221
1222-static inline void read_next_byte(struct kcs_data *kcs)
1223+static inline void read_next_byte(struct si_sm_data *kcs)
1224 {
1225 if (kcs->read_pos >= MAX_KCS_READ_SIZE) {
1226 /* Throw the data away and mark it truncated. */
1227@@ -212,9 +201,8 @@
1228 write_data(kcs, KCS_READ_BYTE);
1229 }
1230
1231-static inline int check_ibf(struct kcs_data *kcs,
1232- unsigned char status,
1233- long time)
1234+static inline int check_ibf(struct si_sm_data *kcs, unsigned char status,
1235+ long time)
1236 {
1237 if (GET_STATUS_IBF(status)) {
1238 kcs->ibf_timeout -= time;
1239@@ -229,9 +217,8 @@
1240 return 1;
1241 }
1242
1243-static inline int check_obf(struct kcs_data *kcs,
1244- unsigned char status,
1245- long time)
1246+static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
1247+ long time)
1248 {
1249 if (! GET_STATUS_OBF(status)) {
1250 kcs->obf_timeout -= time;
1251@@ -245,13 +232,13 @@
1252 return 1;
1253 }
1254
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)
1257 {
1258 if (GET_STATUS_OBF(status))
1259 read_data(kcs);
1260 }
1261
1262-static void restart_kcs_transaction(struct kcs_data *kcs)
1263+static void restart_kcs_transaction(struct si_sm_data *kcs)
1264 {
1265 kcs->write_count = kcs->orig_write_count;
1266 kcs->write_pos = 0;
1267@@ -262,7 +249,8 @@
1268 write_cmd(kcs, KCS_WRITE_START);
1269 }
1270
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)
1274 {
1275 if ((size < 2) || (size > MAX_KCS_WRITE_SIZE)) {
1276 return -1;
1277@@ -284,7 +272,8 @@
1278 return 0;
1279 }
1280
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)
1284 {
1285 if (length < kcs->read_pos) {
1286 kcs->read_pos = length;
1287@@ -313,7 +302,7 @@
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)
1293 {
1294 unsigned char status;
1295 unsigned char state;
1296@@ -325,7 +314,7 @@
1297 #endif
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;
1302
1303 /* Just about everything looks at the KCS state, so grab that, too. */
1304 state = GET_STATUS_STATE(status);
1305@@ -336,9 +325,9 @@
1306 clear_obf(kcs, status);
1307
1308 if (GET_STATUS_ATN(status))
1309- return KCS_ATTN;
1310+ return SI_SM_ATTN;
1311 else
1312- return KCS_SM_IDLE;
1313+ return SI_SM_IDLE;
1314
1315 case KCS_START_OP:
1316 if (state != KCS_IDLE) {
1317@@ -405,7 +394,7 @@
1318
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);
1324 } else {
1325 /* We don't implement this exactly like the state
1326@@ -418,7 +407,7 @@
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;
1332 }
1333 break;
1334
1335@@ -441,7 +430,7 @@
1336 break;
1337 }
1338 if (! check_obf(kcs, status, time))
1339- return KCS_CALL_WITH_DELAY;
1340+ return SI_SM_CALL_WITH_DELAY;
1341
1342 clear_obf(kcs, status);
1343 write_data(kcs, KCS_READ_BYTE);
1344@@ -456,14 +445,14 @@
1345 }
1346
1347 if (! check_obf(kcs, status, time))
1348- return KCS_CALL_WITH_DELAY;
1349+ return SI_SM_CALL_WITH_DELAY;
1350
1351 clear_obf(kcs, status);
1352 if (kcs->orig_write_count) {
1353 restart_kcs_transaction(kcs);
1354 } else {
1355 kcs->state = KCS_IDLE;
1356- return KCS_TRANSACTION_COMPLETE;
1357+ return SI_SM_TRANSACTION_COMPLETE;
1358 }
1359 break;
1360
1361@@ -472,14 +461,42 @@
1362 }
1363
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;
1369 }
1370
1371- return KCS_CALL_WITHOUT_DELAY;
1372+ return SI_SM_CALL_WITHOUT_DELAY;
1373 }
1374
1375-int kcs_size(void)
1376+static int kcs_size(void)
1377 {
1378- return sizeof(struct kcs_data);
1379+ return sizeof(struct si_sm_data);
1380+}
1381+
1382+static int kcs_detect(struct si_sm_data *kcs)
1383+{
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)
1389+ return 1;
1390+
1391+ return 0;
1392 }
1393+
1394+static void kcs_cleanup(struct si_sm_data *kcs)
1395+{
1396+}
1397+
1398+struct si_sm_handlers kcs_smi_handlers =
1399+{
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,
1407+ .size = kcs_size,
1408+};
1409diff -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
1412@@ -44,16 +44,21 @@
1413 #include <linux/ipmi_smi.h>
1414 #include <linux/notifier.h>
1415 #include <linux/init.h>
1416+#include <linux/proc_fs.h>
1417+
1418+#define IPMI_MSGHANDLER_VERSION "v27"
1419
1420 struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
1421 static int ipmi_init_msghandler(void);
1422
1423 static int initialized = 0;
1424
1425+static struct proc_dir_entry *proc_ipmi_root = NULL;
1426+
1427 #define MAX_EVENTS_IN_QUEUE 25
1428
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
1433
1434 struct ipmi_user
1435@@ -82,7 +87,8 @@
1436
1437 struct seq_table
1438 {
1439- int inuse : 1;
1440+ unsigned int inuse : 1;
1441+ unsigned int broadcast : 1;
1442
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
1447 case... */
1448 unsigned char my_lun;
1449+
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;
1456+
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);
1462+
1463+ /* Proc FS stuff. */
1464+ struct proc_dir_entry *proc_dir;
1465+ char proc_dir_name[10];
1466+
1467+ spinlock_t counter_lock; /* For making counters atomic. */
1468+
1469+ /* Commands we got that were invalid. */
1470+ unsigned int sent_invalid_commands;
1471+
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;
1478+
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
1486+ incremented. */
1487+ unsigned int timed_out_ipmb_commands;
1488+
1489+ /* This is like above, but for broadcasts. Broadcasts are
1490+ *not* included in the above count (they are expected to
1491+ time out). */
1492+ unsigned int timed_out_ipmb_broadcasts;
1493+
1494+ /* Responses I have sent to the IPMB bus. */
1495+ unsigned int sent_ipmb_responses;
1496+
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;
1503+
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;
1510+
1511+ /* Invalid data in an event. */
1512+ unsigned int invalid_events;
1513+ /* Events that were received with the proper format. */
1514+ unsigned int events;
1515 };
1516
1517 int
1518@@ -328,7 +400,7 @@
1519
1520 static void deliver_response(struct ipmi_recv_msg *msg)
1521 {
1522- msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
1523+ msg->user->handler->ipmi_recv_hndl(msg, msg->user->handler_data);
1524 }
1525
1526 /* Find the next sequence number not being used and add the given
1527@@ -338,6 +410,7 @@
1528 struct ipmi_recv_msg *recv_msg,
1529 unsigned long timeout,
1530 int retries,
1531+ int broadcast,
1532 unsigned char *seq,
1533 long *seqid)
1534 {
1535@@ -360,6 +433,7 @@
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);
1542 *seq = i;
1543@@ -412,8 +486,8 @@
1544
1545
1546 /* Start the timer for a specific sequence table entry. */
1547-static int intf_start_seq_timer(ipmi_smi_t intf,
1548- long msgid)
1549+static int intf_start_seq_timer(ipmi_smi_t intf,
1550+ long msgid)
1551 {
1552 int rv = -ENODEV;
1553 unsigned long flags;
1554@@ -431,9 +505,50 @@
1555 {
1556 struct seq_table *ent = &(intf->seq_table[seq]);
1557 ent->timeout = ent->orig_timeout;
1558+ rv = 0;
1559+ }
1560+ spin_unlock_irqrestore(&(intf->seq_lock), flags);
1561+
1562+ return rv;
1563+}
1564+
1565+/* Got an error for the send message for a specific sequence number. */
1566+static int intf_err_seq(ipmi_smi_t intf,
1567+ long msgid,
1568+ unsigned int err)
1569+{
1570+ int rv = -ENODEV;
1571+ unsigned long flags;
1572+ unsigned char seq;
1573+ unsigned long seqid;
1574+ struct ipmi_recv_msg *msg = NULL;
1575+
1576+
1577+ GET_SEQ_FROM_MSGID(msgid, seq, seqid);
1578+
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))
1584+ {
1585+ struct seq_table *ent = &(intf->seq_table[seq]);
1586+
1587+ ent->inuse = 0;
1588+ msg = ent->recv_msg;
1589+ rv = 0;
1590 }
1591 spin_unlock_irqrestore(&(intf->seq_lock), flags);
1592
1593+ if (msg) {
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);
1600+ }
1601+
1602 return rv;
1603 }
1604
1605@@ -769,7 +884,9 @@
1606 struct ipmi_recv_msg *supplied_recv,
1607 int priority,
1608 unsigned char source_address,
1609- unsigned char source_lun)
1610+ unsigned char source_lun,
1611+ int retries,
1612+ unsigned int retry_time_ms)
1613 {
1614 int rv = 0;
1615 struct ipmi_smi_msg *smi_msg;
1616@@ -797,8 +914,11 @@
1617 }
1618
1619 if (addr->channel > IPMI_NUM_CHANNELS) {
1620- rv = -EINVAL;
1621- goto out_err;
1622+ spin_lock_irqsave(&intf->counter_lock, flags);
1623+ intf->sent_invalid_commands++;
1624+ spin_unlock_irqrestore(&intf->counter_lock, flags);
1625+ rv = -EINVAL;
1626+ goto out_err;
1627 }
1628
1629 recv_msg->user = user;
1630@@ -812,8 +932,12 @@
1631
1632
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);
1639 return -EINVAL;
1640+ }
1641
1642 memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr));
1643
1644@@ -824,11 +948,17 @@
1645 {
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);
1651 rv = -EINVAL;
1652 goto out_err;
1653 }
1654
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);
1659 rv = -EMSGSIZE;
1660 goto out_err;
1661 }
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))
1671 {
1672 struct ipmi_ipmb_addr *ipmb_addr;
1673 unsigned char ipmb_seq;
1674 long seqid;
1675- int broadcast;
1676- int retries;
1677+ int broadcast = 0;
1678
1679 if (addr == NULL) {
1680+ spin_lock_irqsave(&intf->counter_lock, flags);
1681+ intf->sent_invalid_commands++;
1682+ spin_unlock_irqrestore(&intf->counter_lock, flags);
1683 rv = -EINVAL;
1684 goto out_err;
1685 }
1686
1687+ if (retries < 0) {
1688+ if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE)
1689+ retries = 0; /* Don't retry broadcasts. */
1690+ else
1691+ retries = 4;
1692+ }
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
1696 address. */
1697 addr->addr_type = IPMI_IPMB_ADDR_TYPE;
1698 broadcast = 1;
1699- retries = 0; /* Don't retry broadcasts. */
1700- } else {
1701- broadcast = 0;
1702- retries = 4;
1703 }
1704
1705+
1706+ /* Default to 1 second retries. */
1707+ if (retry_time_ms == 0)
1708+ retry_time_ms = 1000;
1709+
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);
1716 rv = -EMSGSIZE;
1717 goto out_err;
1718 }
1719
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);
1725 rv = -EINVAL;
1726 goto out_err;
1727 }
1728@@ -884,6 +1032,9 @@
1729 if (recv_msg->msg.netfn & 0x1) {
1730 /* It's a response, so use the user's sequence
1731 from msgid. */
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,
1736 msgid, broadcast,
1737 source_address, source_lun);
1738@@ -892,13 +1043,17 @@
1739
1740 spin_lock_irqsave(&(intf->seq_lock), flags);
1741
1742+ spin_lock(&intf->counter_lock);
1743+ intf->sent_ipmb_commands++;
1744+ spin_unlock(&intf->counter_lock);
1745+
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,
1750 recv_msg,
1751- 1000,
1752+ retry_time_ms,
1753 retries,
1754+ broadcast,
1755 &ipmb_seq,
1756 &seqid);
1757 if (rv) {
1758@@ -934,16 +1089,19 @@
1759 }
1760 } else {
1761 /* Unknown address type. */
1762- rv = -EINVAL;
1763- goto out_err;
1764+ spin_lock_irqsave(&intf->counter_lock, flags);
1765+ intf->sent_invalid_commands++;
1766+ spin_unlock_irqrestore(&intf->counter_lock, flags);
1767+ rv = -EINVAL;
1768+ goto out_err;
1769 }
1770
1771 #if DEBUG_MSGING
1772 {
1773- int m;
1774- for (m=0; m<smi_msg->data_size; m++)
1775- printk(" %2.2x", smi_msg->data[m]);
1776- printk("\n");
1777+ int m;
1778+ for (m=0; m<smi_msg->data_size; m++)
1779+ printk(" %2.2x", smi_msg->data[m]);
1780+ printk("\n");
1781 }
1782 #endif
1783 intf->handlers->sender(intf->send_info, smi_msg, priority);
1784@@ -970,7 +1128,29 @@
1785 NULL, NULL,
1786 priority,
1787 user->intf->my_address,
1788- user->intf->my_lun);
1789+ user->intf->my_lun,
1790+ -1, 0);
1791+}
1792+
1793+int ipmi_request_settime(ipmi_user_t user,
1794+ struct ipmi_addr *addr,
1795+ long msgid,
1796+ struct ipmi_msg *msg,
1797+ int priority,
1798+ int retries,
1799+ unsigned int retry_time_ms)
1800+{
1801+ return i_ipmi_request(user,
1802+ user->intf,
1803+ addr,
1804+ msgid,
1805+ msg,
1806+ NULL, NULL,
1807+ priority,
1808+ user->intf->my_address,
1809+ user->intf->my_lun,
1810+ retries,
1811+ retry_time_ms);
1812 }
1813
1814 int ipmi_request_supply_msgs(ipmi_user_t user,
1815@@ -990,7 +1170,8 @@
1816 supplied_recv,
1817 priority,
1818 user->intf->my_address,
1819- user->intf->my_lun);
1820+ user->intf->my_lun,
1821+ -1, 0);
1822 }
1823
1824 int ipmi_request_with_source(ipmi_user_t user,
1825@@ -1009,7 +1190,124 @@
1826 NULL, NULL,
1827 priority,
1828 source_address,
1829- source_lun);
1830+ source_lun,
1831+ -1, 0);
1832+}
1833+
1834+static int ipmb_file_read_proc(char *page, char **start, off_t off,
1835+ int count, int *eof, void *data)
1836+{
1837+ char *out = (char *) page;
1838+ ipmi_smi_t intf = data;
1839+
1840+ return sprintf(out, "%x\n", intf->my_address);
1841+}
1842+
1843+static int version_file_read_proc(char *page, char **start, off_t off,
1844+ int count, int *eof, void *data)
1845+{
1846+ char *out = (char *) page;
1847+ ipmi_smi_t intf = data;
1848+
1849+ return sprintf(out, "%d.%d\n",
1850+ intf->version_major, intf->version_minor);
1851+}
1852+
1853+static int stat_file_read_proc(char *page, char **start, off_t off,
1854+ int count, int *eof, void *data)
1855+{
1856+ char *out = (char *) page;
1857+ ipmi_smi_t intf = data;
1858+
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",
1894+ intf->events);
1895+
1896+ return (out - ((char *) page));
1897+}
1898+
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)
1902+{
1903+ struct proc_dir_entry *file;
1904+ int rv = 0;
1905+
1906+ file = create_proc_entry(name, 0, smi->proc_dir);
1907+ if (!file)
1908+ rv = -ENOMEM;
1909+ else {
1910+ file->nlink = 1;
1911+ file->data = data;
1912+ file->read_proc = read_proc;
1913+ file->write_proc = write_proc;
1914+ file->owner = owner;
1915+ }
1916+
1917+ return rv;
1918+}
1919+
1920+static int add_proc_entries(ipmi_smi_t smi, int num)
1921+{
1922+ int rv = 0;
1923+
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)
1927+ rv = -ENOMEM;
1928+ else {
1929+ smi->proc_dir->owner = THIS_MODULE;
1930+ }
1931+
1932+ if (rv == 0)
1933+ rv = ipmi_smi_add_proc_entry(smi, "stats",
1934+ stat_file_read_proc, NULL,
1935+ smi, THIS_MODULE);
1936+
1937+ if (rv == 0)
1938+ rv = ipmi_smi_add_proc_entry(smi, "ipmb",
1939+ ipmb_file_read_proc, NULL,
1940+ smi, THIS_MODULE);
1941+
1942+ if (rv == 0)
1943+ rv = ipmi_smi_add_proc_entry(smi, "version",
1944+ version_file_read_proc, NULL,
1945+ smi, THIS_MODULE);
1946+
1947+ return rv;
1948 }
1949
1950 int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
1951@@ -1040,6 +1338,9 @@
1952 new_intf = kmalloc(sizeof(*new_intf), GFP_KERNEL);
1953 if (!new_intf)
1954 return -ENOMEM;
1955+ memset(new_intf, 0, sizeof(*new_intf));
1956+
1957+ new_intf->proc_dir = NULL;
1958
1959 rv = -ENOMEM;
1960
1961@@ -1069,6 +1370,8 @@
1962 INIT_LIST_HEAD(&(new_intf->cmd_rcvrs));
1963 new_intf->all_cmd_rcvr = NULL;
1964
1965+ spin_lock_init(&(new_intf->counter_lock));
1966+
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. */
1972 goto out;
1973
1974+ if (rv == 0)
1975+ rv = add_proc_entries(*intf, i);
1976+
1977 if (rv == 0) {
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);
1984- w->new_smi(i);
1985+ if (try_inc_mod_count(w->owner)) {
1986+ w->new_smi(i);
1987+ if (w->owner)
1988+ __MOD_DEC_USE_COUNT(w->owner);
1989+ }
1990 }
1991 up_read(&smi_watchers_sem);
1992 }
1993@@ -1104,8 +1414,12 @@
1994 out:
1995 up_read(&interfaces_sem);
1996
1997- if (rv)
1998+ if (rv) {
1999+ if (new_intf->proc_dir)
2000+ remove_proc_entry(new_intf->proc_dir_name,
2001+ proc_ipmi_root);
2002 kfree(new_intf);
2003+ }
2004
2005 return rv;
2006 }
2007@@ -1163,6 +1477,8 @@
2008 {
2009 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2010 if (ipmi_interfaces[i] == intf) {
2011+ remove_proc_entry(intf->proc_dir_name,
2012+ proc_ipmi_root);
2013 spin_lock_irqsave(&interfaces_lock, flags);
2014 ipmi_interfaces[i] = NULL;
2015 clean_up_interface_data(intf);
2016@@ -1204,15 +1520,21 @@
2017 {
2018 struct ipmi_ipmb_addr ipmb_addr;
2019 struct ipmi_recv_msg *recv_msg;
2020+ unsigned long flags;
2021
2022
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);
2029 return 0;
2030+ }
2031
2032- if (msg->rsp[2] != 0)
2033+ if (msg->rsp[2] != 0) {
2034 /* An error getting the response, just ignore it. */
2035 return 0;
2036+ }
2037
2038 ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
2039 ipmb_addr.slave_addr = msg->rsp[6];
2040@@ -1231,6 +1553,9 @@
2041 {
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);
2047 return 0;
2048 }
2049
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);
2058
2059 return 0;
2060@@ -1252,18 +1580,23 @@
2061 static int handle_get_msg_cmd(ipmi_smi_t intf,
2062 struct ipmi_smi_msg *msg)
2063 {
2064- struct list_head *entry;
2065+ struct list_head *entry;
2066 struct cmd_rcvr *rcvr;
2067- int rv = 0;
2068- unsigned char netfn;
2069- unsigned char cmd;
2070- ipmi_user_t user = NULL;
2071+ int rv = 0;
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;
2078
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);
2085 return 0;
2086+ }
2087
2088 if (msg->rsp[2] != 0) {
2089 /* An error getting the response, just ignore it. */
2090@@ -1291,6 +1624,10 @@
2091
2092 if (user == NULL) {
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);
2097+
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. */
2103 } else {
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);
2108+
2109 recv_msg = ipmi_alloc_recv_msg();
2110 if (! recv_msg) {
2111 /* We couldn't allocate memory for the
2112@@ -1374,6 +1715,9 @@
2113
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);
2119 return 0;
2120 }
2121
2122@@ -1386,6 +1730,10 @@
2123
2124 spin_lock_irqsave(&(intf->events_lock), flags);
2125
2126+ spin_lock(&intf->counter_lock);
2127+ intf->events++;
2128+ spin_unlock(&intf->counter_lock);
2129+
2130 /* Allocate and fill in one message for every user that is getting
2131 events. */
2132 list_for_each(entry, &(intf->users)) {
2133@@ -1459,6 +1807,7 @@
2134 struct ipmi_recv_msg *recv_msg;
2135 int found = 0;
2136 struct list_head *entry;
2137+ unsigned long flags;
2138
2139 recv_msg = (struct ipmi_recv_msg *) msg->user_data;
2140
2141@@ -1474,11 +1823,20 @@
2142 }
2143
2144 if (!found) {
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);
2153 } else {
2154 struct ipmi_system_interface_addr *smi_addr;
2155
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)
2165 {
2166- int requeue;
2167+ int requeue;
2168
2169 if (msg->rsp_size < 2) {
2170 /* Message is too small to be correct. */
2171@@ -1551,10 +1909,30 @@
2172 working on it. */
2173 read_lock(&(intf->users_lock));
2174
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
2180 timer for these. */
2181- intf_start_seq_timer(intf, msg->msgid);
2182+
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))
2190+ {
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]);
2196+ } else {
2197+ /* The message was sent, start the timer. */
2198+ intf_start_seq_timer(intf, msg->msgid);
2199+ }
2200+
2201 ipmi_free_smi_msg(msg);
2202 goto out_unlock;
2203 }
2204@@ -1699,6 +2077,12 @@
2205 ent->inuse = 0;
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++;
2211+ else
2212+ intf->timed_out_ipmb_commands++;
2213+ spin_unlock(&intf->counter_lock);
2214 } else {
2215 /* More retries, send again. */
2216
2217@@ -1708,6 +2092,9 @@
2218 ent->retries_left--;
2219 send_from_recv_msg(intf, ent->recv_msg, NULL,
2220 j, ent->seqid);
2221+ spin_lock(&intf->counter_lock);
2222+ intf->retransmitted_ipmb_commands++;
2223+ spin_unlock(&intf->counter_lock);
2224 }
2225 }
2226 spin_unlock_irqrestore(&(intf->seq_lock), flags);
2227@@ -1740,13 +2127,16 @@
2228
2229 static struct timer_list ipmi_timer;
2230
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))
2235
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
2238- in the queue. */
2239+/* How many jiffies does it take to get to the timeout time. */
2240+#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
2241+
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))
2247
2248 static volatile int stop_operation = 0;
2249@@ -1822,18 +2212,48 @@
2250 {
2251 }
2252
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)
2256+{
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))
2260+ {
2261+ /* A get event receiver command, save it. */
2262+ intf->event_receiver = msg->rsp[3];
2263+ intf->event_receiver_lun = msg->rsp[4] & 0x3;
2264+ }
2265+}
2266+
2267+static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_smi_msg *msg)
2268+{
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))
2272+ {
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;
2277+ }
2278+}
2279+#endif
2280+
2281+static void send_panic_events(char *str)
2282 {
2283 struct ipmi_msg msg;
2284 ipmi_smi_t intf;
2285- unsigned char data[8];
2286+ unsigned char data[16];
2287 int i;
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;
2293
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;
2299+ si->lun = 0;
2300
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. */
2306
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
2309- any more. */
2310- data[3] = 0;
2311- data[6] = 0;
2312- data[7] = 0;
2313+ /* Put a few breadcrums in. Hopefully later we can add more things
2314+ to make the panic events more useful. */
2315+ if (str) {
2316+ data[3] = str[0];
2317+ data[6] = str[1];
2318+ data[7] = str[2];
2319+ }
2320
2321 smi_msg.done = dummy_smi_done_handler;
2322 recv_msg.done = dummy_recv_done_handler;
2323@@ -1862,18 +2283,147 @@
2324 if (intf == NULL)
2325 continue;
2326
2327+ /* Send the event announcing the panic. */
2328 intf->handlers->set_run_to_completion(intf->send_info, 1);
2329 i_ipmi_request(NULL,
2330 intf,
2331- (struct ipmi_addr *) &addr,
2332+ &addr,
2333 0,
2334 &msg,
2335 &smi_msg,
2336 &recv_msg,
2337 0,
2338 intf->my_address,
2339- intf->my_lun);
2340+ intf->my_lun,
2341+ 0, 1); /* Don't retry, and don't wait. */
2342 }
2343+
2344+#ifdef CONFIG_IPMI_PANIC_STRING
2345+ /* On every interface, dump a bunch of OEM event holding the
2346+ string. */
2347+ if (!str)
2348+ return;
2349+
2350+ for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2351+ char *p = str;
2352+ struct ipmi_ipmb_addr *ipmb;
2353+ int j;
2354+
2355+ intf = ipmi_interfaces[i];
2356+ if (intf == NULL)
2357+ continue;
2358+
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
2363+ there. */
2364+
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;
2369+
2370+ /* Request the device info from the local MC. */
2371+ msg.netfn = IPMI_NETFN_APP_REQUEST;
2372+ msg.cmd = IPMI_GET_DEVICE_ID_CMD;
2373+ msg.data = NULL;
2374+ msg.data_len = 0;
2375+ intf->null_user_handler = device_id_fetcher;
2376+ i_ipmi_request(NULL,
2377+ intf,
2378+ &addr,
2379+ 0,
2380+ &msg,
2381+ &smi_msg,
2382+ &recv_msg,
2383+ 0,
2384+ intf->my_address,
2385+ intf->my_lun,
2386+ 0, 1); /* Don't retry, and don't wait. */
2387+
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;
2392+ msg.data = NULL;
2393+ msg.data_len = 0;
2394+ intf->null_user_handler = event_receiver_fetcher;
2395+ i_ipmi_request(NULL,
2396+ intf,
2397+ &addr,
2398+ 0,
2399+ &msg,
2400+ &smi_msg,
2401+ &recv_msg,
2402+ 0,
2403+ intf->my_address,
2404+ intf->my_lun,
2405+ 0, 1); /* no retry, and no wait. */
2406+ }
2407+ intf->null_user_handler = NULL;
2408+
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))
2415+ {
2416+ /* The event receiver is valid, send an IPMB
2417+ message. */
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
2426+ in my SEL. */
2427+ si = (struct ipmi_system_interface_addr *) &addr;
2428+ si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
2429+ si->channel = IPMI_BMC_CHANNEL;
2430+ si->lun = 0;
2431+ } else
2432+ continue; /* No where to send the event. */
2433+
2434+
2435+ msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */
2436+ msg.cmd = IPMI_ADD_SEL_ENTRY_CMD;
2437+ msg.data = data;
2438+ msg.data_len = 16;
2439+
2440+ j = 0;
2441+ while (*p) {
2442+ int size = strlen(p);
2443+
2444+ if (size > 11)
2445+ size = 11;
2446+ data[0] = 0;
2447+ data[1] = 0;
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);
2454+ p += size;
2455+
2456+ i_ipmi_request(NULL,
2457+ intf,
2458+ &addr,
2459+ 0,
2460+ &msg,
2461+ &smi_msg,
2462+ &recv_msg,
2463+ 0,
2464+ intf->my_address,
2465+ intf->my_lun,
2466+ 0, 1); /* no retry, and no wait. */
2467+ }
2468+ }
2469+#endif /* CONFIG_IPMI_PANIC_STRING */
2470 }
2471 #endif /* CONFIG_IPMI_PANIC_EVENT */
2472
2473@@ -1900,7 +2450,7 @@
2474 }
2475
2476 #ifdef CONFIG_IPMI_PANIC_EVENT
2477- send_panic_events();
2478+ send_panic_events(ptr);
2479 #endif
2480
2481 return NOTIFY_DONE;
2482@@ -1912,7 +2462,6 @@
2483 200 /* priority: INT_MAX >= x >= 0 */
2484 };
2485
2486-
2487 static __init int ipmi_init_msghandler(void)
2488 {
2489 int i;
2490@@ -1920,10 +2469,21 @@
2491 if (initialized)
2492 return 0;
2493
2494+ printk(KERN_INFO "ipmi message handler version "
2495+ IPMI_MSGHANDLER_VERSION "\n");
2496+
2497 for (i=0; i<MAX_IPMI_INTERFACES; i++) {
2498 ipmi_interfaces[i] = NULL;
2499 }
2500
2501+ proc_ipmi_root = proc_mkdir("ipmi", 0);
2502+ if (!proc_ipmi_root) {
2503+ printk("Unable to create IPMI proc dir\n");
2504+ return -ENOMEM;
2505+ }
2506+
2507+ proc_ipmi_root->owner = THIS_MODULE;
2508+
2509 init_timer(&ipmi_timer);
2510 ipmi_timer.data = 0;
2511 ipmi_timer.function = ipmi_timeout;
2512@@ -1934,8 +2494,6 @@
2513
2514 initialized = 1;
2515
2516- printk(KERN_INFO "ipmi: message handler initialized\n");
2517-
2518 return 0;
2519 }
2520
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);
2534diff -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
2537@@ -0,0 +1,1729 @@
2538+/*
2539+ * ipmi_si.c
2540+ *
2541+ * The interface to the IPMI driver for the system interfaces (KCS, SMIC,
2542+ * BT in the future).
2543+ *
2544+ * Author: MontaVista Software, Inc.
2545+ * Corey Minyard <minyard@mvista.com>
2546+ * source@mvista.com
2547+ *
2548+ * Copyright 2002 MontaVista Software Inc.
2549+ *
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.
2554+ *
2555+ *
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.
2566+ *
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.
2570+ */
2571+
2572+/*
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.
2576+ */
2577+
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
2595+# endif
2596+static inline void add_usec_to_timer(struct timer_list *t, long v)
2597+{
2598+ t->sub_expires += nsec_to_arch_cycle(v * 1000);
2599+ while (t->sub_expires >= arch_cycles_per_jiffy)
2600+ {
2601+ t->expires++;
2602+ t->sub_expires -= arch_cycles_per_jiffy;
2603+ }
2604+}
2605+#endif
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>
2611+
2612+#define IPMI_SI_VERSION "v27"
2613+
2614+/* Measure times between events in the driver. */
2615+#undef DEBUG_TIMING
2616+
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
2622+ short timeout */
2623+
2624+enum si_intf_state {
2625+ SI_NORMAL,
2626+ SI_GETTING_FLAGS,
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. */
2634+};
2635+
2636+enum si_type {
2637+ SI_KCS, SI_SMIC, SI_BT
2638+};
2639+
2640+struct smi_info
2641+{
2642+ ipmi_smi_t intf;
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;
2652+
2653+ /* Used to handle the various types of I/O that can occur with
2654+ IPMI */
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;
2661+
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;
2669+
2670+ /* If set to true, this will request events the next time the
2671+ state machine is idle. */
2672+ atomic_t req_events;
2673+
2674+ /* If true, run the state machine to completion on every send
2675+ call. Generally used after a panic to make sure stuff goes
2676+ out. */
2677+ int run_to_completion;
2678+
2679+ /* The I/O port of an SI interface. */
2680+ int port;
2681+
2682+ /* zero if no irq; */
2683+ int irq;
2684+
2685+ /* The physical and remapped memory addresses of a SI interface. */
2686+ unsigned long physaddr;
2687+ unsigned char *addr;
2688+
2689+ /* The timer for this si. */
2690+ struct timer_list si_timer;
2691+
2692+ /* The time (in jiffies) the last timeout occurred at. */
2693+ unsigned long last_timeout_jiffies;
2694+
2695+ /* Used to gracefully stop the timer without race conditions. */
2696+ volatile int stop_operation;
2697+ volatile int timer_stopped;
2698+
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
2702+ interrupts. */
2703+ int interrupt_disabled;
2704+
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;
2710+
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;
2725+};
2726+
2727+static void si_restart_short_timer(struct smi_info *smi_info);
2728+
2729+static void deliver_recv_msg(struct smi_info *smi_info,
2730+ struct ipmi_smi_msg *msg)
2731+{
2732+ /* Deliver the message to the upper layer with the lock
2733+ released. */
2734+ spin_unlock(&(smi_info->si_lock));
2735+ ipmi_smi_msg_received(smi_info->intf, msg);
2736+ spin_lock(&(smi_info->si_lock));
2737+}
2738+
2739+static void return_hosed_msg(struct smi_info *smi_info)
2740+{
2741+ struct ipmi_smi_msg *msg = smi_info->curr_msg;
2742+
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;
2748+
2749+ smi_info->curr_msg = NULL;
2750+ deliver_recv_msg(smi_info, msg);
2751+}
2752+
2753+static enum si_sm_result start_next_msg(struct smi_info *smi_info)
2754+{
2755+ int rv;
2756+ struct list_head *entry = NULL;
2757+#ifdef DEBUG_TIMING
2758+ struct timeval t;
2759+#endif
2760+
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));
2764+
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;
2770+ }
2771+
2772+ if (!entry) {
2773+ smi_info->curr_msg = NULL;
2774+ rv = SI_SM_IDLE;
2775+ } else {
2776+ int err;
2777+
2778+ list_del(entry);
2779+ smi_info->curr_msg = list_entry(entry,
2780+ struct ipmi_smi_msg,
2781+ link);
2782+#ifdef DEBUG_TIMING
2783+ do_gettimeofday(&t);
2784+ printk("**Start2: %d.%9.9d\n", t.tv_sec, t.tv_usec);
2785+#endif
2786+ err = smi_info->handlers->start_transaction(
2787+ smi_info->si_sm,
2788+ smi_info->curr_msg->data,
2789+ smi_info->curr_msg->data_size);
2790+ if (err) {
2791+ return_hosed_msg(smi_info);
2792+ }
2793+
2794+ rv = SI_SM_CALL_WITHOUT_DELAY;
2795+ }
2796+ spin_unlock(&(smi_info->msg_lock));
2797+
2798+ return rv;
2799+}
2800+
2801+static void start_enable_irq(struct smi_info *smi_info)
2802+{
2803+ unsigned char msg[2];
2804+
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;
2809+
2810+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 2);
2811+ smi_info->si_state = SI_ENABLE_INTERRUPTS1;
2812+}
2813+
2814+static void start_clear_flags(struct smi_info *smi_info)
2815+{
2816+ unsigned char msg[3];
2817+
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;
2822+
2823+ smi_info->handlers->start_transaction(smi_info->si_sm, msg, 3);
2824+ smi_info->si_state = SI_CLEARING_FLAGS;
2825+}
2826+
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)
2832+{
2833+ if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
2834+ disable_irq_nosync(smi_info->irq);
2835+ smi_info->interrupt_disabled = 1;
2836+ }
2837+}
2838+
2839+static inline void enable_si_irq(struct smi_info *smi_info)
2840+{
2841+ if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
2842+ enable_irq(smi_info->irq);
2843+ smi_info->interrupt_disabled = 0;
2844+ }
2845+}
2846+
2847+static void handle_flags(struct smi_info *smi_info)
2848+{
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);
2854+
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;
2866+ return;
2867+ }
2868+ enable_si_irq(smi_info);
2869+
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;
2873+
2874+ smi_info->handlers->start_transaction(
2875+ smi_info->si_sm,
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;
2885+ return;
2886+ }
2887+ enable_si_irq(smi_info);
2888+
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;
2892+
2893+ smi_info->handlers->start_transaction(
2894+ smi_info->si_sm,
2895+ smi_info->curr_msg->data,
2896+ smi_info->curr_msg->data_size);
2897+ smi_info->si_state = SI_GETTING_EVENTS;
2898+ } else {
2899+ smi_info->si_state = SI_NORMAL;
2900+ }
2901+}
2902+
2903+static void handle_transaction_done(struct smi_info *smi_info)
2904+{
2905+ struct ipmi_smi_msg *msg;
2906+#ifdef DEBUG_TIMING
2907+ struct timeval t;
2908+
2909+ do_gettimeofday(&t);
2910+ printk("**Done: %d.%9.9d\n", t.tv_sec, t.tv_usec);
2911+#endif
2912+ switch (smi_info->si_state) {
2913+ case SI_NORMAL:
2914+ if (!smi_info->curr_msg)
2915+ break;
2916+
2917+ smi_info->curr_msg->rsp_size
2918+ = smi_info->handlers->get_result(
2919+ smi_info->si_sm,
2920+ smi_info->curr_msg->rsp,
2921+ IPMI_MAX_MSG_LENGTH);
2922+
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);
2929+ break;
2930+
2931+ case SI_GETTING_FLAGS:
2932+ {
2933+ unsigned char msg[4];
2934+ unsigned int len;
2935+
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
2940+ now. */
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;
2946+ } else {
2947+ smi_info->msg_flags = msg[3];
2948+ handle_flags(smi_info);
2949+ }
2950+ break;
2951+ }
2952+
2953+ case SI_CLEARING_FLAGS:
2954+ case SI_CLEARING_FLAGS_THEN_SET_IRQ:
2955+ {
2956+ unsigned char msg[3];
2957+
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",
2964+ msg[2]);
2965+ }
2966+ if (smi_info->si_state == SI_CLEARING_FLAGS_THEN_SET_IRQ)
2967+ start_enable_irq(smi_info);
2968+ else
2969+ smi_info->si_state = SI_NORMAL;
2970+ break;
2971+ }
2972+
2973+ case SI_GETTING_EVENTS:
2974+ {
2975+ smi_info->curr_msg->rsp_size
2976+ = smi_info->handlers->get_result(
2977+ smi_info->si_sm,
2978+ smi_info->curr_msg->rsp,
2979+ IPMI_MAX_MSG_LENGTH);
2980+
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. */
2988+ msg->done(msg);
2989+
2990+ /* Take off the event flag. */
2991+ smi_info->msg_flags &= ~EVENT_MSG_BUFFER_FULL;
2992+ } else {
2993+ spin_lock(&smi_info->count_lock);
2994+ smi_info->events++;
2995+ spin_unlock(&smi_info->count_lock);
2996+
2997+ deliver_recv_msg(smi_info, msg);
2998+ }
2999+ handle_flags(smi_info);
3000+ break;
3001+ }
3002+
3003+ case SI_GETTING_MESSAGES:
3004+ {
3005+ smi_info->curr_msg->rsp_size
3006+ = smi_info->handlers->get_result(
3007+ smi_info->si_sm,
3008+ smi_info->curr_msg->rsp,
3009+ IPMI_MAX_MSG_LENGTH);
3010+
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. */
3018+ msg->done(msg);
3019+
3020+ /* Take off the msg flag. */
3021+ smi_info->msg_flags &= ~RECEIVE_MSG_AVAIL;
3022+ } else {
3023+ spin_lock(&smi_info->count_lock);
3024+ smi_info->incoming_messages++;
3025+ spin_unlock(&smi_info->count_lock);
3026+
3027+ deliver_recv_msg(smi_info, msg);
3028+ }
3029+ handle_flags(smi_info);
3030+ break;
3031+ }
3032+
3033+ case SI_ENABLE_INTERRUPTS1:
3034+ {
3035+ unsigned char msg[4];
3036+
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;
3044+ } else {
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;
3051+ }
3052+ break;
3053+ }
3054+
3055+ case SI_ENABLE_INTERRUPTS2:
3056+ {
3057+ unsigned char msg[4];
3058+
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");
3065+ }
3066+ smi_info->si_state = SI_NORMAL;
3067+ break;
3068+ }
3069+ }
3070+}
3071+
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,
3075+ int time)
3076+{
3077+ enum si_sm_result si_sm_result;
3078+
3079+ restart:
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);
3087+ time = 0;
3088+ while (si_sm_result == SI_SM_CALL_WITHOUT_DELAY)
3089+ {
3090+ si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3091+ }
3092+
3093+ if (si_sm_result == SI_SM_TRANSACTION_COMPLETE)
3094+ {
3095+ spin_lock(&smi_info->count_lock);
3096+ smi_info->complete_transactions++;
3097+ spin_unlock(&smi_info->count_lock);
3098+
3099+ handle_transaction_done(smi_info);
3100+ si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3101+ }
3102+ else if (si_sm_result == SI_SM_HOSED)
3103+ {
3104+ spin_lock(&smi_info->count_lock);
3105+ smi_info->hosed_count++;
3106+ spin_unlock(&smi_info->count_lock);
3107+
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);
3113+ }
3114+ si_sm_result = smi_info->handlers->event(smi_info->si_sm, 0);
3115+ smi_info->si_state = SI_NORMAL;
3116+ }
3117+
3118+ /* We prefer handling attn over new messages. */
3119+ if (si_sm_result == SI_SM_ATTN)
3120+ {
3121+ unsigned char msg[2];
3122+
3123+ spin_lock(&smi_info->count_lock);
3124+ smi_info->attentions++;
3125+ spin_unlock(&smi_info->count_lock);
3126+
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
3131+ possible. */
3132+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3133+ msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3134+
3135+ smi_info->handlers->start_transaction(
3136+ smi_info->si_sm, msg, 2);
3137+ smi_info->si_state = SI_GETTING_FLAGS;
3138+ goto restart;
3139+ }
3140+
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);
3146+
3147+ si_sm_result = start_next_msg(smi_info);
3148+ if (si_sm_result != SI_SM_IDLE)
3149+ goto restart;
3150+ }
3151+
3152+ if ((si_sm_result == SI_SM_IDLE)
3153+ && (atomic_read(&smi_info->req_events)))
3154+ {
3155+ /* We are idle and the upper layer requested that I fetch
3156+ events, so do so. */
3157+ unsigned char msg[2];
3158+
3159+ spin_lock(&smi_info->count_lock);
3160+ smi_info->flag_fetches++;
3161+ spin_unlock(&smi_info->count_lock);
3162+
3163+ atomic_set(&smi_info->req_events, 0);
3164+ msg[0] = (IPMI_NETFN_APP_REQUEST << 2);
3165+ msg[1] = IPMI_GET_MSG_FLAGS_CMD;
3166+
3167+ smi_info->handlers->start_transaction(
3168+ smi_info->si_sm, msg, 2);
3169+ smi_info->si_state = SI_GETTING_FLAGS;
3170+ goto restart;
3171+ }
3172+
3173+ return si_sm_result;
3174+}
3175+
3176+static void sender(void *send_info,
3177+ struct ipmi_smi_msg *msg,
3178+ int priority)
3179+{
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
3184+ struct timeval t;
3185+#endif
3186+
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);
3191+#endif
3192+
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));
3198+
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);
3202+
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);
3209+ }
3210+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3211+ return;
3212+ } else {
3213+ if (priority > 0) {
3214+ list_add_tail(&(msg->link), &(smi_info->hp_xmit_msgs));
3215+ } else {
3216+ list_add_tail(&(msg->link), &(smi_info->xmit_msgs));
3217+ }
3218+ }
3219+ spin_unlock_irqrestore(&(smi_info->msg_lock), flags);
3220+
3221+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3222+ if ((smi_info->si_state == SI_NORMAL)
3223+ && (smi_info->curr_msg == NULL))
3224+ {
3225+ start_next_msg(smi_info);
3226+ si_restart_short_timer(smi_info);
3227+ }
3228+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3229+}
3230+
3231+static void set_run_to_completion(void *send_info, int i_run_to_completion)
3232+{
3233+ struct smi_info *smi_info = (struct smi_info *) send_info;
3234+ enum si_sm_result result;
3235+ unsigned long flags;
3236+
3237+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3238+
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);
3246+ }
3247+ }
3248+
3249+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3250+}
3251+
3252+static void request_events(void *send_info)
3253+{
3254+ struct smi_info *smi_info = (struct smi_info *) send_info;
3255+
3256+ atomic_set(&smi_info->req_events, 1);
3257+}
3258+
3259+static int new_user(void *send_info)
3260+{
3261+ if (!try_inc_mod_count(THIS_MODULE))
3262+ return -EBUSY;
3263+ return 0;
3264+}
3265+
3266+static void user_left(void *send_info)
3267+{
3268+ MOD_DEC_USE_COUNT;
3269+}
3270+
3271+static int initialized = 0;
3272+
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)
3275+{
3276+#if defined(CONFIG_HIGH_RES_TIMERS)
3277+ unsigned long flags;
3278+ unsigned long jiffies_now;
3279+
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. */
3284+
3285+ /* We already have irqsave on, so no need for it
3286+ here. */
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);
3292+
3293+ add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC);
3294+
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);
3299+ }
3300+#endif
3301+}
3302+
3303+static void smi_timeout(unsigned long data)
3304+{
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
3311+ struct timeval t;
3312+#endif
3313+
3314+ if (smi_info->stop_operation) {
3315+ smi_info->timer_stopped = 1;
3316+ return;
3317+ }
3318+
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);
3323+#endif
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);
3328+
3329+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3330+
3331+ smi_info->last_timeout_jiffies = jiffies_now;
3332+
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;
3340+ }
3341+
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);
3350+#else
3351+ smi_info->si_timer.expires = jiffies + 1;
3352+#endif
3353+ } else {
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;
3360+#endif
3361+ }
3362+
3363+ do_add_timer:
3364+ add_timer(&(smi_info->si_timer));
3365+}
3366+
3367+static void si_irq_handler(int irq, void *data, struct pt_regs *regs)
3368+{
3369+ struct smi_info *smi_info = (struct smi_info *) data;
3370+ unsigned long flags;
3371+#ifdef DEBUG_TIMING
3372+ struct timeval t;
3373+#endif
3374+
3375+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3376+
3377+ spin_lock(&smi_info->count_lock);
3378+ smi_info->interrupts++;
3379+ spin_unlock(&smi_info->count_lock);
3380+
3381+ if (smi_info->stop_operation)
3382+ goto out;
3383+
3384+#ifdef DEBUG_TIMING
3385+ do_gettimeofday(&t);
3386+ printk("**Interrupt: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3387+#endif
3388+ smi_event_handler(smi_info, 0);
3389+ out:
3390+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3391+}
3392+
3393+static struct ipmi_smi_handlers handlers =
3394+{
3395+ sender: sender,
3396+ request_events: request_events,
3397+ new_user: new_user,
3398+ user_left: user_left,
3399+ set_run_to_completion: set_run_to_completion
3400+};
3401+
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 */
3404+
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 };
3409+
3410+#define DEVICE_NAME "ipmi_si"
3411+
3412+#define DEFAULT_KCS_IO_PORT 0xca2
3413+#define DEFAULT_SMIC_IO_PORT 0xca9
3414+
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 };
3420+
3421+
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");
3427+
3428+
3429+static int std_irq_setup(struct smi_info *info)
3430+{
3431+ int rv;
3432+
3433+ if (!info->irq)
3434+ return 0;
3435+
3436+ rv = request_irq(info->irq,
3437+ si_irq_handler,
3438+ SA_INTERRUPT,
3439+ DEVICE_NAME,
3440+ info);
3441+ if (rv) {
3442+ printk(KERN_WARNING
3443+ "ipmi_smi: %s unable to claim interrupt %d,"
3444+ " running polled\n",
3445+ DEVICE_NAME, info->irq);
3446+ info->irq = 0;
3447+ } else {
3448+ printk(" Using irq %d\n", info->irq);
3449+ }
3450+
3451+ return rv;
3452+}
3453+
3454+static void std_irq_cleanup(struct smi_info *info)
3455+{
3456+ if (!info->irq)
3457+ return;
3458+
3459+ free_irq(info->irq, info);
3460+}
3461+
3462+static unsigned char port_inb(struct si_sm_io *io, unsigned int offset)
3463+{
3464+ unsigned int *addr = io->info;
3465+
3466+ return inb((*addr)+offset);
3467+}
3468+
3469+static void port_outb(struct si_sm_io *io, unsigned int offset,
3470+ unsigned char b)
3471+{
3472+ unsigned int *addr = io->info;
3473+
3474+ outb(b, (*addr)+offset);
3475+}
3476+
3477+static int port_setup(struct smi_info *info)
3478+{
3479+ unsigned int *addr = info->io.info;
3480+
3481+ if (!addr || (!*addr))
3482+ return -ENODEV;
3483+
3484+ if (request_region(*addr, info->io_size, DEVICE_NAME) == NULL)
3485+ return -EIO;
3486+ return 0;
3487+}
3488+
3489+static void port_cleanup(struct smi_info *info)
3490+{
3491+ unsigned int *addr = info->io.info;
3492+
3493+ if (addr && (*addr))
3494+ release_region (*addr, info->io_size);
3495+ kfree(info);
3496+}
3497+
3498+static int try_init_port(int intf_num, struct smi_info **new_info)
3499+{
3500+ struct smi_info *info;
3501+
3502+ if (!si_ports[intf_num])
3503+ return -ENODEV;
3504+
3505+ info = kmalloc(sizeof(*info), GFP_KERNEL);
3506+ if (!info) {
3507+ printk("ipmi_smi: Could not allocate SMI data\n");
3508+ return -ENOMEM;
3509+ }
3510+ memset(info, 0, sizeof(*info));
3511+
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]);
3517+ info->irq = 0;
3518+ info->irq_setup = NULL;
3519+ *new_info = info;
3520+
3521+ printk("ipmi_smi: Trying state machine at I/O address 0x%x\n",
3522+ si_ports[intf_num]);
3523+ return 0;
3524+}
3525+
3526+static unsigned char mem_inb(struct si_sm_io *io, unsigned int offset)
3527+{
3528+ return readb((io->addr)+offset);
3529+}
3530+
3531+static void mem_outb(struct si_sm_io *io, unsigned int offset,
3532+ unsigned char b)
3533+{
3534+ writeb(b, (io->addr)+offset);
3535+}
3536+
3537+static int mem_setup(struct smi_info *info)
3538+{
3539+ unsigned long *addr = info->io.info;
3540+
3541+ if (!addr || (!*addr))
3542+ return -ENODEV;
3543+
3544+ if (request_mem_region(*addr, info->io_size, DEVICE_NAME) == NULL)
3545+ return -EIO;
3546+ info->io.addr = ioremap(*addr, info->io_size);
3547+ if (info->io.addr == NULL) {
3548+ release_mem_region(*addr, info->io_size);
3549+ return -EIO;
3550+ }
3551+ return 0;
3552+}
3553+
3554+static void mem_cleanup(struct smi_info *info)
3555+{
3556+ unsigned int *addr = info->io.info;
3557+
3558+ if (addr) {
3559+ iounmap(info->addr);
3560+ release_mem_region(*addr, info->io_size);
3561+ }
3562+ kfree(info);
3563+}
3564+
3565+static int try_init_mem(int intf_num, struct smi_info **new_info)
3566+{
3567+ struct smi_info *info;
3568+
3569+ if (!si_addrs[intf_num])
3570+ return -ENODEV;
3571+
3572+ info = kmalloc(sizeof(*info), GFP_KERNEL);
3573+ if (!info) {
3574+ printk("ipmi_smi: Could not allocate SMI data\n");
3575+ return -ENOMEM;
3576+ }
3577+ memset(info, 0, sizeof(*info));
3578+
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]);
3584+ info->irq = 0;
3585+ info->irq_setup = NULL;
3586+ *new_info = info;
3587+
3588+ printk("ipmi_smi: Trying state machine at memory address 0x%lx\n",
3589+ si_addrs[intf_num]);
3590+ return 0;
3591+}
3592+
3593+
3594+#ifdef CONFIG_ACPI_INTERPRETER
3595+
3596+#include <linux/acpi.h>
3597+#include <acpi/acpi.h>
3598+#include <acpi/actypes.h>
3599+#include <acpi/actbl.h>
3600+
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
3603+ are no more. */
3604+static int acpi_failure = 0;
3605+
3606+/* For GPE-type interrupts. */
3607+void ipmi_acpi_gpe(void *context)
3608+{
3609+ struct smi_info *smi_info = context;
3610+ unsigned long flags;
3611+#ifdef DEBUG_TIMING
3612+ struct timeval t;
3613+#endif
3614+
3615+ spin_lock_irqsave(&(smi_info->si_lock), flags);
3616+
3617+ spin_lock(&smi_info->count_lock);
3618+ smi_info->interrupts++;
3619+ spin_unlock(&smi_info->count_lock);
3620+
3621+ if (smi_info->stop_operation)
3622+ goto out;
3623+
3624+#ifdef DEBUG_TIMING
3625+ do_gettimeofday(&t);
3626+ printk("**ACPI_GPE: %d.%9.9d\n", t.tv_sec, t.tv_usec);
3627+#endif
3628+ smi_event_handler(smi_info, 0);
3629+ out:
3630+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
3631+}
3632+
3633+static int acpi_gpe_irq_setup(struct smi_info *info)
3634+{
3635+ acpi_status status;
3636+
3637+ if (!info->irq)
3638+ return 0;
3639+
3640+ /* FIXME - is level triggered right? */
3641+ status = acpi_install_gpe_handler(NULL,
3642+ info->irq,
3643+ ACPI_EVENT_LEVEL_TRIGGERED,
3644+ ipmi_acpi_gpe,
3645+ info);
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);
3651+ info->irq = 0;
3652+ return -EINVAL;
3653+ } else {
3654+ printk(" Using ACPI GPE %d\n", info->irq);
3655+ return 0;
3656+ }
3657+
3658+}
3659+
3660+static void acpi_gpe_irq_cleanup(struct smi_info *info)
3661+{
3662+ if (!info->irq)
3663+ return;
3664+
3665+ acpi_remove_gpe_handler(NULL, info->irq, ipmi_acpi_gpe);
3666+}
3667+
3668+/*
3669+ * Defined at
3670+ * http://h21007.www2.hp.com/dspp/files/unprotected/devresource/Docs/TechPapers/IA64/hpspmi.pdf
3671+ */
3672+struct SPMITable {
3673+ s8 Signature[4];
3674+ u32 Length;
3675+ u8 Revision;
3676+ u8 Checksum;
3677+ s8 OEMID[6];
3678+ s8 OEMTableID[8];
3679+ s8 OEMRevision[4];
3680+ s8 CreatorID[4];
3681+ s8 CreatorRevision[4];
3682+ u8 InterfaceType[2];
3683+ s16 SpecificationRevision;
3684+
3685+ /*
3686+ * Bit 0 - SCI interrupt supported
3687+ * Bit 1 - I/O APIC/SAPIC
3688+ */
3689+ u8 InterruptType;
3690+
3691+ /* If bit 0 of InterruptType is set, then this is the SCI
3692+ interrupt in the GPEx_STS register. */
3693+ u8 GPE;
3694+
3695+ s16 Reserved;
3696+
3697+ /* If bit 1 of InterruptType is set, then this is the I/O
3698+ APIC/SAPIC interrupt. */
3699+ u32 GlobalSystemInterrupt;
3700+
3701+ /* The actual register address. */
3702+ struct acpi_generic_address addr;
3703+
3704+ u8 UID[4];
3705+
3706+ s8 spmi_id[1]; /* A '\0' terminated array starts here. */
3707+};
3708+
3709+static int try_init_acpi(int intf_num, struct smi_info **new_info)
3710+{
3711+ struct smi_info *info;
3712+ acpi_status status;
3713+ struct SPMITable *spmi;
3714+ char *io_type;
3715+
3716+ if (acpi_failure)
3717+ return -ENODEV;
3718+
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) {
3723+ acpi_failure = 1;
3724+ return -ENODEV;
3725+ }
3726+
3727+ if (spmi->InterfaceType[0] != 1)
3728+ return -ENODEV;
3729+
3730+ /* Figure out the interface type. */
3731+ switch (spmi->InterfaceType[1])
3732+ {
3733+ case 1: /* KCS */
3734+ si_type[intf_num] = "kcs";
3735+ break;
3736+
3737+ case 2: /* SMIC */
3738+ si_type[intf_num] = "smic";
3739+ break;
3740+
3741+ case 3: /* BT */
3742+ si_type[intf_num] = "bt";
3743+ break;
3744+
3745+ default:
3746+ printk("ipmi_smi: Unknown ACPI SMI type.\n");
3747+ return -EIO;
3748+ }
3749+
3750+ info = kmalloc(sizeof(*info), GFP_KERNEL);
3751+ if (!info) {
3752+ printk("ipmi_smi: Could not allocate SMI data\n");
3753+ return -ENOMEM;
3754+ }
3755+ memset(info, 0, sizeof(*info));
3756+
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;
3767+ } else {
3768+ /* Use the default interrupt setting. */
3769+ info->irq = 0;
3770+ info->irq_setup = NULL;
3771+ }
3772+
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) {
3782+ io_type = "I/O";
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]);
3789+ } else {
3790+ kfree(info);
3791+ printk("ipmi_smi: Unknown ACPI I/O Address type.\n");
3792+ return -EIO;
3793+ }
3794+
3795+ *new_info = info;
3796+
3797+ printk("ipmi_smi: Found ACPI-specified state machine at %s"
3798+ " address 0x%lx\n",
3799+ io_type, (unsigned long) spmi->addr.address);
3800+ return 0;
3801+}
3802+#endif
3803+
3804+static int try_get_dev_id(struct smi_info *smi_info)
3805+{
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;
3810+
3811+ /* Do a Get Device ID command, since it comes back with some
3812+ useful info. */
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);
3816+
3817+ smi_result = smi_info->handlers->event(smi_info->si_sm, 0);
3818+ for (;;)
3819+ {
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);
3824+ }
3825+ else if (smi_result == SI_SM_CALL_WITHOUT_DELAY)
3826+ {
3827+ smi_result = smi_info->handlers->event(
3828+ smi_info->si_sm, 0);
3829+ }
3830+ else
3831+ break;
3832+ }
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. */
3836+ return -ENODEV;
3837+
3838+ /* Otherwise, we got some data. */
3839+ resp_len = smi_info->handlers->get_result(smi_info->si_sm,
3840+ resp, IPMI_MAX_MSG_LENGTH);
3841+ if (resp_len < 6)
3842+ /* That's odd, it should be longer. */
3843+ return -EINVAL;
3844+
3845+ if ((resp[1] != IPMI_GET_DEVICE_ID_CMD) || (resp[2] != 0))
3846+ /* That's odd, it shouldn't be able to fail. */
3847+ return -EINVAL;
3848+
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;
3855+
3856+ return 0;
3857+}
3858+
3859+extern struct si_sm_handlers kcs_smi_handlers;
3860+extern struct si_sm_handlers smic_smi_handlers;
3861+
3862+static int type_file_read_proc(char *page, char **start, off_t off,
3863+ int count, int *eof, void *data)
3864+{
3865+ char *out = (char *) page;
3866+ struct smi_info *smi = data;
3867+
3868+ switch (smi->si_type) {
3869+ case SI_KCS:
3870+ return sprintf(out, "kcs\n");
3871+ case SI_SMIC:
3872+ return sprintf(out, "smic\n");
3873+ case SI_BT:
3874+ return sprintf(out, "bt\n");
3875+ default:
3876+ return 0;
3877+ }
3878+}
3879+
3880+static int stat_file_read_proc(char *page, char **start, off_t off,
3881+ int count, int *eof, void *data)
3882+{
3883+ char *out = (char *) page;
3884+ struct smi_info *smi = data;
3885+
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",
3895+ smi->idles);
3896+ out += sprintf(out, "interrupts: %ld\n",
3897+ smi->interrupts);
3898+ out += sprintf(out, "attentions: %ld\n",
3899+ smi->attentions);
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",
3907+ smi->events);
3908+ out += sprintf(out, "watchdog_pretimeouts: %ld\n",
3909+ smi->watchdog_pretimeouts);
3910+ out += sprintf(out, "incoming_messages: %ld\n",
3911+ smi->incoming_messages);
3912+
3913+ return (out - ((char *) page));
3914+}
3915+
3916+/* Returns 0 if initialized, or negative on an error. */
3917+static int init_one_smi(int intf_num, struct smi_info **smi)
3918+{
3919+ int rv;
3920+ struct smi_info *new_smi;
3921+
3922+
3923+ rv = try_init_mem(intf_num, &new_smi);
3924+ if (rv)
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);
3929+ }
3930+#endif
3931+
3932+ if (rv)
3933+ return rv;
3934+
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;
3939+
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;
3944+ }
3945+
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";
3950+ else {
3951+ rv = -EINVAL;
3952+ goto out_err;
3953+ }
3954+ }
3955+
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;
3963+ } else {
3964+ /* No support for anything else yet. */
3965+ rv = -EIO;
3966+ goto out_err;
3967+ }
3968+
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");
3973+ rv = -ENOMEM;
3974+ goto out_err;
3975+ }
3976+ new_smi->io_size = new_smi->handlers->init_data(new_smi->si_sm,
3977+ &new_smi->io);
3978+
3979+ /* Now that we know the I/O size, we can set up the I/O. */
3980+ rv = new_smi->io_setup(new_smi);
3981+ if (rv) {
3982+ printk(" Could not set up I/O space\n");
3983+ goto out_err;
3984+ }
3985+
3986+ spin_lock_init(&(new_smi->si_lock));
3987+ spin_lock_init(&(new_smi->msg_lock));
3988+ spin_lock_init(&(new_smi->count_lock));
3989+
3990+ /* Do low-level detection first. */
3991+ if (new_smi->handlers->detect(new_smi->si_sm)) {
3992+ rv = -ENODEV;
3993+ goto out_err;
3994+ }
3995+
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);
3999+ if (rv)
4000+ goto out_err;
4001+
4002+ /* Try to claim any interrupts. */
4003+ new_smi->irq_setup(new_smi);
4004+
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;
4010+
4011+ rv = ipmi_register_smi(&handlers,
4012+ new_smi,
4013+ new_smi->ipmi_version_major,
4014+ new_smi->ipmi_version_minor,
4015+ &(new_smi->intf));
4016+ if (rv) {
4017+ printk(KERN_ERR
4018+ "ipmi_smi: Unable to register device: error %d\n",
4019+ rv);
4020+ goto out_err;
4021+ }
4022+
4023+ rv = ipmi_smi_add_proc_entry(new_smi->intf, "type",
4024+ type_file_read_proc, NULL,
4025+ new_smi, THIS_MODULE);
4026+ if (rv) {
4027+ printk(KERN_ERR
4028+ "ipmi_smi: Unable to create proc entry: %d\n",
4029+ rv);
4030+ goto out_err;
4031+ }
4032+
4033+ rv = ipmi_smi_add_proc_entry(new_smi->intf, "si_stats",
4034+ stat_file_read_proc, NULL,
4035+ new_smi, THIS_MODULE);
4036+ if (rv) {
4037+ printk(KERN_ERR
4038+ "ipmi_smi: Unable to create proc entry: %d\n",
4039+ rv);
4040+ goto out_err;
4041+ }
4042+
4043+ start_clear_flags(new_smi);
4044+
4045+ /* IRQ is defined to be set when non-zero. */
4046+ if (new_smi->irq)
4047+ new_smi->si_state = SI_CLEARING_FLAGS_THEN_SET_IRQ;
4048+
4049+ new_smi->interrupt_disabled = 0;
4050+ new_smi->timer_stopped = 0;
4051+ new_smi->stop_operation = 0;
4052+
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));
4059+
4060+ *smi = new_smi;
4061+
4062+ printk(" IPMI %s interface initialized\n", si_type[intf_num]);
4063+
4064+ return 0;
4065+
4066+ out_err:
4067+ if (new_smi->intf)
4068+ ipmi_unregister_smi(new_smi->intf);
4069+
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);
4075+ }
4076+ new_smi->io_cleanup(new_smi);
4077+ return rv;
4078+}
4079+
4080+static __init int init_ipmi_si(void)
4081+{
4082+ int rv = 0;
4083+ int pos = 0;
4084+ int i = 0;
4085+
4086+ if (initialized)
4087+ return 0;
4088+ initialized = 1;
4089+
4090+ printk(KERN_INFO "IPMI System Interface driver version "
4091+ IPMI_SI_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);
4096+ printk("\n");
4097+
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]));
4105+ if (rv) {
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]));
4110+ }
4111+ }
4112+ if (rv == 0)
4113+ pos++;
4114+
4115+ for (i=1; i < SI_MAX_PARMS; i++) {
4116+ rv = init_one_smi(i, &(smi_infos[pos]));
4117+ if (rv == 0)
4118+ pos++;
4119+ }
4120+
4121+ if (smi_infos[0] == NULL) {
4122+ printk("ipmi_smi: Unable to find any SMI interfaces\n");
4123+ return -ENODEV;
4124+ }
4125+
4126+ return 0;
4127+}
4128+module_init(init_ipmi_si);
4129+
4130+#ifdef MODULE
4131+void __exit cleanup_one_si(struct smi_info *to_clean)
4132+{
4133+ int rv;
4134+ unsigned long flags;
4135+
4136+ if (! to_clean)
4137+ return;
4138+
4139+ /* Tell the timer and interrupt handlers that we are shutting
4140+ down. */
4141+ spin_lock_irqsave(&(to_clean->si_lock), flags);
4142+ spin_lock(&(to_clean->msg_lock));
4143+
4144+ to_clean->stop_operation = 1;
4145+
4146+ to_clean->irq_cleanup(to_clean);
4147+
4148+ spin_unlock(&(to_clean->msg_lock));
4149+ spin_unlock_irqrestore(&(to_clean->si_lock), flags);
4150+
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
4154+ running. */
4155+ schedule_timeout(2);
4156+ while (!to_clean->timer_stopped) {
4157+ schedule_timeout(1);
4158+ }
4159+
4160+ rv = ipmi_unregister_smi(to_clean->intf);
4161+ if (rv) {
4162+ printk(KERN_ERR
4163+ "ipmi_smi: Unable to unregister device: errno=%d\n",
4164+ rv);
4165+ }
4166+
4167+ to_clean->handlers->cleanup(to_clean->si_sm);
4168+
4169+ kfree(to_clean->si_sm);
4170+
4171+ to_clean->io_cleanup(to_clean);
4172+}
4173+
4174+static __exit void cleanup_ipmi_si(void)
4175+{
4176+ int i;
4177+
4178+ if (!initialized)
4179+ return;
4180+
4181+ for (i=0; i<SI_MAX_DRIVERS; i++) {
4182+ cleanup_one_si(smi_infos[i]);
4183+ }
4184+}
4185+module_exit(cleanup_ipmi_si);
4186+#else
4187+
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
4196+
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
4200+
4201+ Remember, ipmi_si_setup() is passed the string after the equal sign. */
4202+
4203+static int __init ipmi_si_setup(char *str)
4204+{
4205+ unsigned long val;
4206+ char *cur, *colon;
4207+ int pos;
4208+
4209+ pos = 0;
4210+
4211+ cur = strsep(&str, ",");
4212+ while ((cur) && (*cur) && (pos < SI_MAX_PARMS)) {
4213+ switch (*cur) {
4214+ case 'n':
4215+ if (strcmp(cur, "nodefaults") == 0)
4216+ si_trydefaults = 0;
4217+ else
4218+ printk(KERN_INFO
4219+ "ipmi_si: bad parameter value %s\n",
4220+ cur);
4221+ break;
4222+
4223+ case 'k': /* KCS */
4224+ si_type[pos] = "kcs";
4225+ break;
4226+
4227+ case 's': /* SMIC */
4228+ si_type[pos] = "smic";
4229+ break;
4230+
4231+ case 'b': /* BT */
4232+ si_type[pos] = "bt";
4233+ break;
4234+
4235+ case 'm':
4236+ case 'p':
4237+ val = simple_strtoul(cur + 1,
4238+ &colon,
4239+ 0);
4240+ if (*cur == 'p')
4241+ si_ports[pos] = val;
4242+ else
4243+ si_addrs[pos] = val;
4244+ if (*colon == ':') {
4245+ val = simple_strtoul(colon + 1,
4246+ &colon,
4247+ 0);
4248+ si_irqs[pos] = val;
4249+ }
4250+ pos++;
4251+ break;
4252+
4253+ default:
4254+ printk(KERN_INFO
4255+ "ipmi_si: bad parameter value %s\n",
4256+ cur);
4257+ }
4258+ cur = strsep(&str, ",");
4259+ }
4260+
4261+ return 1;
4262+}
4263+__setup("ipmi_si=", ipmi_si_setup);
4264+#endif
4265+
4266+MODULE_LICENSE("GPL");
4267diff -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
4270@@ -0,0 +1,112 @@
4271+/*
4272+ * ipmi_si_sm.h
4273+ *
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.
4278+ *
4279+ * Author: MontaVista Software, Inc.
4280+ * Corey Minyard <minyard@mvista.com>
4281+ * source@mvista.com
4282+ *
4283+ * Copyright 2002 MontaVista Software Inc.
4284+ *
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.
4289+ *
4290+ *
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.
4301+ *
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.
4305+ */
4306+
4307+/* This is defined by the state machines themselves, it is an opaque
4308+ data type for them to use. */
4309+struct si_sm_data;
4310+
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. */
4314+struct si_sm_io
4315+{
4316+ unsigned char (*inputb)(struct si_sm_io *io, unsigned int offset);
4317+ void (*outputb)(struct si_sm_io *io,
4318+ unsigned int offset,
4319+ unsigned char b);
4320+
4321+ /* Generic info used by the actual handling routines, the
4322+ state machine shouldn't touch these. */
4323+ void *info;
4324+ void *addr;
4325+};
4326+
4327+/* Results of SMI events. */
4328+enum si_sm_result
4329+{
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. */
4337+};
4338+
4339+/* Handlers for the SMI state machine. */
4340+struct si_sm_handlers
4341+{
4342+ /* Put the version number of the state machine here so the
4343+ upper layer can print it. */
4344+ char *version;
4345+
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);
4350+
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);
4357+
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);
4363+
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);
4371+
4372+ /* Attempt to detect an SMI. Returns 0 on success or nonzero
4373+ on failure. */
4374+ int (*detect)(struct si_sm_data *smi);
4375+
4376+ /* The interface is shutting down, so clean it up. */
4377+ void (*cleanup)(struct si_sm_data *smi);
4378+
4379+ /* Return the size of the SMI structure in bytes. */
4380+ int (*size)(void);
4381+};
4382+
4383diff -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
4386@@ -0,0 +1,601 @@
4387+/*
4388+ * ipmi_smic_sm.c
4389+ *
4390+ * The state-machine driver for an IPMI SMIC driver
4391+ *
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
4394+ *
4395+ * modified by: Hannes Schulz <schulz@schwaar.com>
4396+ * ipmi@schwaar.com
4397+ *
4398+ *
4399+ * Corey Minyard's driver for the KSC interface has the following
4400+ * copyright notice:
4401+ * Copyright 2002 MontaVista Software Inc.
4402+ *
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
4407+ *
4408+ *
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.
4413+ *
4414+ *
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.
4425+ *
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. */
4429+
4430+#include <linux/kernel.h> /* For printk. */
4431+#include <linux/string.h>
4432+#include "ipmi_si_sm.h"
4433+
4434+#define IPMI_SMIC_VERSION "v27"
4435+
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
4440+*/
4441+#define SMIC_DEBUG_STATES 4
4442+#define SMIC_DEBUG_MSG 2
4443+#define SMIC_DEBUG_ENABLE 1
4444+
4445+static int smic_debug = 1;
4446+
4447+enum smic_states {
4448+ SMIC_IDLE,
4449+ SMIC_START_OP,
4450+ SMIC_OP_OK,
4451+ SMIC_WRITE_START,
4452+ SMIC_WRITE_NEXT,
4453+ SMIC_WRITE_END,
4454+ SMIC_WRITE2READ,
4455+ SMIC_READ_START,
4456+ SMIC_READ_NEXT,
4457+ SMIC_READ_END,
4458+ SMIC_HOSED
4459+};
4460+
4461+#define MAX_SMIC_READ_SIZE 80
4462+#define MAX_SMIC_WRITE_SIZE 80
4463+#define SMIC_MAX_ERROR_RETRIES 3
4464+
4465+/* Timeouts in microseconds. */
4466+#define SMIC_RETRY_TIMEOUT 100000
4467+#define IPMI_ERR_MSG_TRUNCATED 0xc6
4468+#define IPMI_ERR_UNSPECIFIED 0xff
4469+
4470+
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
4478+
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
4486+
4487+struct si_sm_data
4488+{
4489+ enum smic_states state;
4490+ struct si_sm_io *io;
4491+ unsigned char write_data[MAX_SMIC_WRITE_SIZE];
4492+ int write_pos;
4493+ int write_count;
4494+ int orig_write_count;
4495+ unsigned char read_data[MAX_SMIC_READ_SIZE];
4496+ int read_pos;
4497+ int truncated;
4498+ unsigned int error_retries;
4499+ long smic_timeout;
4500+};
4501+
4502+static unsigned int init_smic_data (struct si_sm_data *smic,
4503+ struct si_sm_io *io)
4504+{
4505+ smic->state = SMIC_IDLE;
4506+ smic->io = io;
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;
4514+
4515+ /* We use 3 bytes of I/O. */
4516+ return 3;
4517+}
4518+
4519+static int start_smic_transaction(struct si_sm_data *smic,
4520+ unsigned char *data, unsigned int size)
4521+{
4522+ unsigned int i;
4523+
4524+ if ((size < 2) || (size > MAX_SMIC_WRITE_SIZE)) {
4525+ return -1;
4526+ }
4527+ if ((smic->state != SMIC_IDLE) && (smic->state != SMIC_HOSED)) {
4528+ return -2;
4529+ }
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]));
4534+ }
4535+ printk ("\n");
4536+ }
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;
4545+ return 0;
4546+}
4547+
4548+static int smic_get_result(struct si_sm_data *smic,
4549+ unsigned char *data, unsigned int length)
4550+{
4551+ int i;
4552+
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]));
4557+ }
4558+ printk ("\n");
4559+ }
4560+ if (length < smic->read_pos) {
4561+ smic->read_pos = length;
4562+ smic->truncated = 1;
4563+ }
4564+ memcpy(data, smic->read_data, smic->read_pos);
4565+
4566+ if ((length >= 3) && (smic->read_pos < 3)) {
4567+ data[2] = IPMI_ERR_UNSPECIFIED;
4568+ smic->read_pos = 3;
4569+ }
4570+ if (smic->truncated) {
4571+ data[2] = IPMI_ERR_MSG_TRUNCATED;
4572+ smic->truncated = 0;
4573+ }
4574+ return smic->read_pos;
4575+}
4576+
4577+static inline unsigned char read_smic_flags(struct si_sm_data *smic)
4578+{
4579+ return smic->io->inputb(smic->io, 2);
4580+}
4581+
4582+static inline unsigned char read_smic_status(struct si_sm_data *smic)
4583+{
4584+ return smic->io->inputb(smic->io, 1);
4585+}
4586+
4587+static inline unsigned char read_smic_data(struct si_sm_data *smic)
4588+{
4589+ return smic->io->inputb(smic->io, 0);
4590+}
4591+
4592+static inline void write_smic_flags(struct si_sm_data *smic,
4593+ unsigned char flags)
4594+{
4595+ smic->io->outputb(smic->io, 2, flags);
4596+}
4597+
4598+static inline void write_smic_control(struct si_sm_data *smic,
4599+ unsigned char control)
4600+{
4601+ smic->io->outputb(smic->io, 1, control);
4602+}
4603+
4604+static inline void write_si_sm_data (struct si_sm_data *smic,
4605+ unsigned char data)
4606+{
4607+ smic->io->outputb(smic->io, 0, data);
4608+}
4609+
4610+static inline void start_error_recovery(struct si_sm_data *smic, char *reason)
4611+{
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);
4617+ }
4618+ smic->state = SMIC_HOSED;
4619+ } else {
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;
4625+ }
4626+}
4627+
4628+static inline void write_next_byte(struct si_sm_data *smic)
4629+{
4630+ write_si_sm_data(smic, smic->write_data[smic->write_pos]);
4631+ (smic->write_pos)++;
4632+ (smic->write_count)--;
4633+}
4634+
4635+static inline void read_next_byte (struct si_sm_data *smic)
4636+{
4637+ if (smic->read_pos >= MAX_SMIC_READ_SIZE) {
4638+ read_smic_data (smic);
4639+ smic->truncated = 1;
4640+ } else {
4641+ smic->read_data[smic->read_pos] = read_smic_data(smic);
4642+ (smic->read_pos)++;
4643+ }
4644+}
4645+
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
4656+
4657+#define SMIC_CONTROL 0x00
4658+#define SMIC_STATUS 0x80
4659+#define SMIC_CS_MASK 0x80
4660+
4661+#define SMIC_SMS 0x40
4662+#define SMIC_SMM 0x60
4663+#define SMIC_STREAM_MASK 0x60
4664+
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)
4673+
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)
4681+
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)
4690+
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)
4698+
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
4707+
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
4715+*/
4716+
4717+static enum si_sm_result smic_event (struct si_sm_data *smic, long time)
4718+{
4719+ unsigned char status;
4720+ unsigned char flags;
4721+ unsigned char data;
4722+
4723+ if (smic->state == SMIC_HOSED) {
4724+ init_smic_data(smic, smic->io);
4725+ return SI_SM_HOSED;
4726+ }
4727+ if (smic->state != SMIC_IDLE) {
4728+ if (smic_debug & SMIC_DEBUG_STATES) {
4729+ printk(KERN_INFO
4730+ "smic_event - smic->smic_timeout = %ld,"
4731+ " time = %ld\n",
4732+ smic->smic_timeout, time);
4733+ }
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;
4740+ }
4741+ }
4742+ }
4743+ flags = read_smic_flags(smic);
4744+ if (flags & SMIC_FLAG_BSY)
4745+ return SI_SM_CALL_WITH_DELAY;
4746+
4747+ status = read_smic_status (smic);
4748+ if (smic_debug & SMIC_DEBUG_STATES)
4749+ printk(KERN_INFO
4750+ "smic_event - state = %d, flags = 0x%02x,"
4751+ " status = 0x%02x\n",
4752+ smic->state, flags, status);
4753+
4754+ switch (smic->state) {
4755+ case SMIC_IDLE:
4756+ /* in IDLE we check for available messages */
4757+ if (flags & (SMIC_SMI |
4758+ SMIC_EVM_DATA_AVAIL | SMIC_SMS_DATA_AVAIL))
4759+ {
4760+ return SI_SM_ATTN;
4761+ }
4762+ return SI_SM_IDLE;
4763+
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;
4769+ break;
4770+
4771+ case 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;
4778+ }
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;
4784+ break;
4785+
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;
4792+ }
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) {
4797+ /* last byte */
4798+ write_smic_control(smic, SMIC_CC_SMS_WR_END);
4799+ smic->state = SMIC_WRITE_END;
4800+ } else {
4801+ write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
4802+ smic->state = SMIC_WRITE_NEXT;
4803+ }
4804+ write_next_byte(smic);
4805+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4806+ }
4807+ else {
4808+ return SI_SM_CALL_WITH_DELAY;
4809+ }
4810+ break;
4811+
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;
4818+ }
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;
4824+ }
4825+ else {
4826+ write_smic_control(smic, SMIC_CC_SMS_WR_NEXT);
4827+ smic->state = SMIC_WRITE_NEXT;
4828+ }
4829+ write_next_byte(smic);
4830+ write_smic_flags(smic, flags | SMIC_FLAG_BSY);
4831+ }
4832+ else {
4833+ return SI_SM_CALL_WITH_DELAY;
4834+ }
4835+ break;
4836+
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;
4843+ }
4844+ /* data register holds an error code */
4845+ data = read_smic_data(smic);
4846+ if (data != 0) {
4847+ if (smic_debug & SMIC_DEBUG_ENABLE) {
4848+ printk(KERN_INFO
4849+ "SMIC_WRITE_END: data = %02x\n", data);
4850+ }
4851+ start_error_recovery(smic,
4852+ "state = SMIC_WRITE_END, "
4853+ "data != SUCCESS");
4854+ return SI_SM_CALL_WITH_DELAY;
4855+ } else {
4856+ smic->state = SMIC_WRITE2READ;
4857+ }
4858+ break;
4859+
4860+ case SMIC_WRITE2READ:
4861+ /* we must wait for RX_DATA_READY to be set before we
4862+ can continue */
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;
4867+ } else {
4868+ return SI_SM_CALL_WITH_DELAY;
4869+ }
4870+ break;
4871+
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;
4878+ }
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;
4884+ } else {
4885+ return SI_SM_CALL_WITH_DELAY;
4886+ }
4887+ break;
4888+
4889+ case SMIC_READ_NEXT:
4890+ switch (status) {
4891+ /* smic tells us that this is the last byte to be read
4892+ --> clean up */
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;
4898+ break;
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;
4905+ } else {
4906+ return SI_SM_CALL_WITH_DELAY;
4907+ }
4908+ break;
4909+ default:
4910+ start_error_recovery(
4911+ smic,
4912+ "state = SMIC_READ_NEXT, "
4913+ "status != SMIC_SC_SMS_RD_(NEXT|END)");
4914+ return SI_SM_CALL_WITH_DELAY;
4915+ }
4916+ break;
4917+
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;
4924+ }
4925+ data = read_smic_data(smic);
4926+ /* data register holds an error code */
4927+ if (data != 0) {
4928+ if (smic_debug & SMIC_DEBUG_ENABLE) {
4929+ printk(KERN_INFO
4930+ "SMIC_READ_END: data = %02x\n", data);
4931+ }
4932+ start_error_recovery(smic,
4933+ "state = SMIC_READ_END, "
4934+ "data != SUCCESS");
4935+ return SI_SM_CALL_WITH_DELAY;
4936+ } else {
4937+ smic->state = SMIC_IDLE;
4938+ return SI_SM_TRANSACTION_COMPLETE;
4939+ }
4940+
4941+ case SMIC_HOSED:
4942+ init_smic_data(smic, smic->io);
4943+ return SI_SM_HOSED;
4944+
4945+ default:
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;
4950+ }
4951+ }
4952+ smic->smic_timeout = SMIC_RETRY_TIMEOUT;
4953+ return SI_SM_CALL_WITHOUT_DELAY;
4954+}
4955+
4956+static int smic_detect(struct si_sm_data *smic)
4957+{
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)
4963+ return 1;
4964+
4965+ return 0;
4966+}
4967+
4968+static void smic_cleanup(struct si_sm_data *kcs)
4969+{
4970+}
4971+
4972+static int smic_size(void)
4973+{
4974+ return sizeof(struct si_sm_data);
4975+}
4976+
4977+struct si_sm_handlers smic_smi_handlers =
4978+{
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,
4987+};
4988diff -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
4991@@ -50,6 +50,8 @@
4992 #include <asm/apic.h>
4993 #endif
4994
4995+#define IPMI_WATCHDOG_VERSION "v27"
4996+
4997 /*
4998 * The IPMI command/response information for the watchdog timer.
4999 */
5000@@ -153,10 +155,18 @@
5001 static char pretimeout_since_last_heartbeat = 0;
5002
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.");
5016
5017 /* Default state of the timer. */
5018 static unsigned char ipmi_watchdog_state = WDOG_TIMEOUT_NONE;
5019@@ -899,6 +909,7 @@
5020
5021 static struct ipmi_smi_watcher smi_watcher =
5022 {
5023+ .owner = THIS_MODULE,
5024 .new_smi = ipmi_new_smi,
5025 .smi_gone = ipmi_smi_gone
5026 };
5027@@ -907,6 +918,9 @@
5028 {
5029 int rv;
5030
5031+ printk(KERN_INFO "IPMI watchdog driver version "
5032+ IPMI_WATCHDOG_VERSION "\n");
5033+
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);
5040
5041- printk(KERN_INFO "IPMI watchdog by "
5042- "Corey Minyard (minyard@mvista.com)\n");
5043-
5044 return 0;
5045 }
5046
5047diff -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
5050@@ -6,11 +6,13 @@
5051
5052 export-objs := ipmi_msghandler.o ipmi_watchdog.o
5053
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
5058
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
5064
5065@@ -18,3 +20,6 @@
5066
5067 ipmi_kcs_drv.o: $(ipmi_kcs_drv-objs)
5068 $(LD) -r -o $@ $(ipmi_kcs_drv-objs)
5069+
5070+ipmi_si_drv.o: $(ipmi_si_drv-objs)
5071+ $(LD) -r -o $@ $(ipmi_si_drv-objs)
5072diff -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
5075@@ -160,6 +160,7 @@
5076 * The in-kernel interface.
5077 */
5078 #include <linux/list.h>
5079+#include <linux/module.h>
5080
5081 /* Opaque type for a IPMI message user. One of these is needed to
5082 send and receive messages. */
5083@@ -221,7 +222,12 @@
5084 void *handler_data,
5085 ipmi_user_t *user);
5086
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
5093+ safe, too. */
5094 int ipmi_destroy_user(ipmi_user_t user);
5095
5096 /* Get the IPMI version of the BMC we are talking to. */
5097@@ -261,6 +267,27 @@
5098 int priority);
5099
5100 /*
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
5106+ * used.
5107+ *
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.
5112+ */
5113+int ipmi_request_settime(ipmi_user_t user,
5114+ struct ipmi_addr *addr,
5115+ long msgid,
5116+ struct ipmi_msg *msg,
5117+ int priority,
5118+ int max_retries,
5119+ unsigned int retry_time_ms);
5120+
5121+/*
5122 * Like ipmi_request, but lets you specify the slave return address.
5123 */
5124 int ipmi_request_with_source(ipmi_user_t user,
5125@@ -331,6 +358,10 @@
5126 {
5127 struct list_head link;
5128
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;
5132+
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, \
5138 struct ipmi_req)
5139
5140+/* Messages sent to the interface with timing parameters are this
5141+ format. */
5142+struct ipmi_req_settime
5143+{
5144+ struct ipmi_req req;
5145+
5146+ /* See ipmi_request_settime() above for details on these
5147+ values. */
5148+ int retries;
5149+ unsigned int retry_time_ms;
5150+};
5151+/*
5152+ * Send a message to the interfaces with timing parameters. error values
5153+ * are:
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.
5159+ */
5160+#define IPMICTL_SEND_COMMAND_SETTIME _IOR(IPMI_IOC_MAGIC, 21, \
5161+ struct ipmi_req_settime)
5162+
5163 /* Messages received from the interface are this format. */
5164 struct ipmi_recv
5165 {
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)
5169
5170+/*
5171+ * Get/set the default timing values for an interface. You shouldn't
5172+ * generally mess with these.
5173+ */
5174+struct ipmi_timing_parms
5175+{
5176+ int retries;
5177+ unsigned int retry_time_ms;
5178+};
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)
5183+
5184 #endif /* __LINUX_IPMI_H */
5185diff -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
5188@@ -37,22 +37,34 @@
5189 /* Various definitions for IPMI messages used by almost everything in
5190 the IPMI stack. */
5191
5192-#define IPMI_NETFN_APP_REQUEST 0x06
5193-#define IPMI_NETFN_APP_RESPONSE 0x07
5194-
5195-#define IPMI_BMC_SLAVE_ADDR 0x20
5196+/* NetFNs and commands used inside the IPMI stack. */
5197+
5198+#define IPMI_NETFN_SENSOR_EVENT_REQUEST 0x04
5199+#define IPMI_NETFN_SENSOR_EVENT_RESPONSE 0x05
5200+#define IPMI_GET_EVENT_RECEIVER_CMD 0x01
5201
5202+#define IPMI_NETFN_APP_REQUEST 0x06
5203+#define IPMI_NETFN_APP_RESPONSE 0x07
5204 #define IPMI_GET_DEVICE_ID_CMD 0x01
5205-
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
5210-
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
5214
5215+#define IPMI_NETFN_STORAGE_REQUEST 0x0a
5216+#define IPMI_NETFN_STORAGE_RESPONSE 0x0b
5217+#define IPMI_ADD_SEL_ENTRY_CMD 0x44
5218+
5219+/* The default slave address */
5220+#define IPMI_BMC_SLAVE_ADDR 0x20
5221+
5222 #define IPMI_MAX_MSG_LENGTH 80
5223
5224+#define IPMI_CC_NO_ERROR 0
5225+#define IPMI_NODE_BUSY_ERR 0xc0
5226+#define IPMI_LOST_ARBITRATION_ERR 0x81
5227+
5228 #endif /* __LINUX_IPMI_MSGDEFS_H */
5229diff -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
5232@@ -35,6 +35,8 @@
5233 #define __LINUX_IPMI_SMI_H
5234
5235 #include <linux/ipmi_msgdefs.h>
5236+#include <linux/proc_fs.h>
5237+#include <linux/module.h>
5238
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 @@
5242 msg->done(msg);
5243 }
5244
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);
5251+
5252 #endif /* __LINUX_IPMI_SMI_H */
5253diff -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
5256@@ -24,7 +24,7 @@
5257
5258 struct poll_table_struct;
5259
5260-#define NPROTO 32 /* should be enough for now.. */
5261+#define NPROTO 64 /* should be enough for now.. */
5262
5263
5264 #define SYS_SOCKET 1 /* sys_socket(2) */
5265diff -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
5268@@ -175,7 +175,8 @@
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.. */
5275
5276 /* Protocol families, same as address families. */
5277 #define PF_UNSPEC AF_UNSPEC
5278@@ -207,6 +208,7 @@
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
5284
5285 /* Maximum queue length specifiable by listen. */
5286diff -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
5289@@ -0,0 +1,66 @@
5290+#ifndef _NET_IPMI_H
5291+#define _NET_IPMI_H
5292+
5293+#include <linux/ipmi.h>
5294+
5295+/*
5296+ * This is ipmi address for socket
5297+ */
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;
5302+};
5303+#define SOCKADDR_IPMI_OVERHEAD (sizeof(struct sockaddr_ipmi) \
5304+ - sizeof(struct ipmi_addr))
5305+
5306+/* A msg_control item, this takes a 'struct ipmi_timing_parms' */
5307+#define IPMI_CMSG_TIMING_PARMS 0x01
5308+
5309+/*
5310+ * This is ipmi message for socket
5311+ */
5312+struct ipmi_sock_msg {
5313+ int recv_type;
5314+ long msgid;
5315+
5316+ unsigned char netfn;
5317+ unsigned char cmd;
5318+ int data_len;
5319+ unsigned char data[0];
5320+};
5321+
5322+#define IPMI_MAX_SOCK_MSG_LENGTH (sizeof(struct ipmi_sock_msg)+IPMI_MAX_MSG_LENGTH)
5323+
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)
5328+
5329+/* Register to receive events. Takes an integer */
5330+#define SIOCIPMIGETEVENT (SIOCPROTOPRIVATE + 2)
5331+
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)
5336+
5337+/* Set/Get the IPMB address of the MC we are connected to, takes an
5338+ unsigned int. */
5339+#define SIOCIPMISETADDR (SIOCPROTOPRIVATE + 5)
5340+#define SIOCIPMIGETADDR (SIOCPROTOPRIVATE + 6)
5341+
5342+/* Socket information for IPMI for protinfo. */
5343+struct ipmi_sock {
5344+ ipmi_user_t user;
5345+ struct sockaddr_ipmi addr;
5346+ struct list_head msg_list;
5347+
5348+ wait_queue_head_t wait;
5349+ spinlock_t lock;
5350+
5351+ int default_retries;
5352+ unsigned int default_retry_time_ms;
5353+};
5354+
5355+#endif/*_NET_IPMI_H*/
5356diff -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
5359@@ -98,6 +98,10 @@
5360 #include <net/irda/irda.h>
5361 #endif
5362
5363+#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
5364+#include <net/af_ipmi.h>
5365+#endif
5366+
5367 #if defined(CONFIG_ATM) || defined(CONFIG_ATM_MODULE)
5368 struct atm_vcc;
5369 #endif
5370@@ -673,6 +677,9 @@
5371 #if defined(CONFIG_WAN_ROUTER) || defined(CONFIG_WAN_ROUTER_MODULE)
5372 struct wanpipe_opt *af_wanpipe;
5373 #endif
5374+#if defined(CONFIG_IPMI_SOCKET) || defined(CONFIG_IPMI_SOCKET_MODULE)
5375+ struct ipmi_sock af_ipmi;
5376+#endif
5377 } protinfo;
5378
5379
5380diff -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
5383@@ -0,0 +1,38 @@
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]
5412+Apply anyway? [n]
5413+Skipping patch.
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
5422diff -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
5425@@ -16,6 +16,7 @@
5426 fi
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
5433diff -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
5436@@ -0,0 +1,593 @@
5437+/*
5438+ * IPMI Socket Glue
5439+ *
5440+ * Author: Louis Zhuang <louis.zhuang@linux.intel.com>
5441+ * Copyright by Intel Corp., 2003
5442+ */
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>
5471+
5472+#define IPMI_SOCKINTF_VERSION "v25"
5473+
5474+#ifdef CONFIG_DEBUG_KERNEL
5475+static int debug = 0;
5476+#define dbg(format, arg...) \
5477+ do { \
5478+ if(debug) \
5479+ printk (KERN_DEBUG "%s: " format "\n", \
5480+ __FUNCTION__, ## arg); \
5481+ } while(0)
5482+#else
5483+#define dbg(format, arg...)
5484+#endif /* CONFIG_DEBUG_KERNEL */
5485+
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)
5498+
5499+static kmem_cache_t *ipmi_sk_cachep = NULL;
5500+
5501+static atomic_t ipmi_nr_socks = ATOMIC_INIT(0);
5502+
5503+
5504+
5505+/*
5506+ * utility functions
5507+ */
5508+static inline struct ipmi_sock *to_ipmi_sock(struct sock *sk)
5509+{
5510+ return &sk->protinfo.af_ipmi;
5511+}
5512+
5513+static inline void ipmi_release_sock(struct sock *sk, int embrion)
5514+{
5515+ struct ipmi_sock *i = to_ipmi_sock(sk);
5516+ struct sk_buff *skb;
5517+
5518+ if (i->user) {
5519+ ipmi_destroy_user(i->user);
5520+ i->user = NULL;
5521+ }
5522+
5523+ sock_orphan(sk);
5524+ sk->shutdown = SHUTDOWN_MASK;
5525+ sk->state = TCP_CLOSE;
5526+
5527+ while((skb=skb_dequeue(&sk->receive_queue))!=NULL)
5528+ kfree_skb(skb);
5529+
5530+ sock_put(sk);
5531+}
5532+
5533+static inline long ipmi_wait_for_queue(struct ipmi_sock *i, long timeo)
5534+{
5535+
5536+ DECLARE_WAITQUEUE(wait, current);
5537+
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);
5543+ return timeo;
5544+}
5545+
5546+/*
5547+ * IPMI operation functions
5548+ */
5549+static void sock_receive_handler(struct ipmi_recv_msg *msg,
5550+ void *handler_data)
5551+{
5552+ struct ipmi_sock *i = (struct ipmi_sock *)handler_data;
5553+ unsigned long flags;
5554+
5555+ spin_lock_irqsave(&i->lock, flags);
5556+ list_add_tail(&msg->link, &i->msg_list);
5557+ spin_unlock_irqrestore(&i->lock, flags);
5558+
5559+ wake_up_interruptible(&i->wait);
5560+}
5561+
5562+/*
5563+ * protocol operation functions
5564+ */
5565+static int ipmi_release(struct socket *sock)
5566+{
5567+ struct sock *sk = sock->sk;
5568+
5569+ if (!sk)
5570+ return 0;
5571+
5572+ sock->sk=NULL;
5573+ ipmi_release_sock(sk, 0);
5574+ return 0;
5575+}
5576+
5577+static struct ipmi_user_hndl ipmi_hnd = {
5578+ .ipmi_recv_hndl = sock_receive_handler
5579+};
5580+
5581+static int ipmi_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
5582+{
5583+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5584+ struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)uaddr;
5585+ int err = -EINVAL;
5586+
5587+ if (i->user != NULL) {
5588+ dbg("Cannot bind twice: %p", i->user);
5589+ return -EINVAL;
5590+ }
5591+
5592+ err = ipmi_create_user(addr->if_num, &ipmi_hnd, i, &i->user);
5593+ if (err) {
5594+ dbg("Cannot create user for the socket: %p", i->user);
5595+ return err;
5596+ }
5597+
5598+ memcpy(&i->addr, addr, sizeof(i->addr));
5599+ return 0;
5600+}
5601+
5602+static int ipmi_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
5603+{
5604+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5605+ memcpy(uaddr, &i->addr, sizeof(i->addr));
5606+ return 0;
5607+}
5608+
5609+static unsigned int ipmi_poll(struct file * file, struct socket *sock, poll_table *wait)
5610+{
5611+ unsigned int has_msg = 0;
5612+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5613+ unsigned long flags;
5614+
5615+ poll_wait(file, &i->wait, wait);
5616+ spin_lock_irqsave(&i->lock, flags);
5617+ if (!list_empty(&i->msg_list))
5618+ has_msg = 1;
5619+ spin_unlock_irqrestore(&i->lock, flags);
5620+
5621+ if (has_msg)
5622+ return POLLIN | POLLRDNORM;
5623+ return 0;
5624+}
5625+
5626+static int ipmi_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
5627+{
5628+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5629+ struct ipmi_cmdspec val;
5630+ int ival;
5631+ unsigned int uival;
5632+ int err;
5633+
5634+ dbg("cmd=%#x, arg=%#lx", cmd, arg);
5635+ switch(cmd) {
5636+ case SIOCIPMIREGCMD:
5637+ err = copy_from_user((void *)&val, (void *)arg,
5638+ sizeof(cmd));
5639+ if (err) {
5640+ err = -EFAULT;
5641+ break;
5642+ }
5643+
5644+ err = ipmi_register_for_cmd(i->user, val.netfn,
5645+ val.cmd);
5646+ break;
5647+
5648+ case SIOCIPMIUNREGCMD:
5649+ err = copy_from_user((void *)&val, (void *)arg,
5650+ sizeof(cmd));
5651+ if (err) {
5652+ err = -EFAULT;
5653+ break;
5654+ }
5655+
5656+ err = ipmi_unregister_for_cmd(i->user, val.netfn,
5657+ val.cmd);
5658+ break;
5659+
5660+ case SIOCIPMIGETEVENT:
5661+ err = copy_from_user((void *)&ival, (void *)arg,
5662+ sizeof(ival));
5663+ if (err) {
5664+ err = -EFAULT;
5665+ break;
5666+ }
5667+
5668+ err = ipmi_set_gets_events(i->user, ival);
5669+ break;
5670+
5671+ case SIOCIPMISETADDR:
5672+ err = copy_from_user((void *)&uival, (void *)arg,
5673+ sizeof(uival));
5674+ if (err) {
5675+ err = -EFAULT;
5676+ break;
5677+ }
5678+
5679+ ipmi_set_my_address(i->user, uival);
5680+ break;
5681+
5682+ case SIOCIPMIGETADDR:
5683+ uival = ipmi_get_my_address(i->user);
5684+
5685+ if (copy_to_user((void *) arg, &uival, sizeof(uival))) {
5686+ err = -EFAULT;
5687+ break;
5688+ }
5689+ err = 0;
5690+ break;
5691+
5692+ case SIOCIPMISETTIMING:
5693+ {
5694+ struct ipmi_timing_parms parms;
5695+
5696+ if (copy_from_user(&parms, (void *) arg, sizeof(parms))) {
5697+ err = -EFAULT;
5698+ break;
5699+ }
5700+
5701+ i->default_retries = parms.retries;
5702+ i->default_retry_time_ms = parms.retry_time_ms;
5703+ err = 0;
5704+ break;
5705+ }
5706+
5707+ case SIOCIPMIGETTIMING:
5708+ {
5709+ struct ipmi_timing_parms parms;
5710+
5711+ parms.retries = i->default_retries;
5712+ parms.retry_time_ms = i->default_retry_time_ms;
5713+
5714+ if (copy_to_user((void *) arg, &parms, sizeof(parms))) {
5715+ err = -EFAULT;
5716+ break;
5717+ }
5718+
5719+ err = 0;
5720+ break;
5721+ }
5722+
5723+ default:
5724+ err = dev_ioctl(cmd, (void *)arg);
5725+ break;
5726+ }
5727+
5728+ return err;
5729+}
5730+
5731+static int ipmi_recvmsg(struct socket *sock, struct msghdr *msg, int size,
5732+ int rflags, struct scm_cookie *scm)
5733+{
5734+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
5735+ long timeo;
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;
5740+ int err;
5741+ unsigned long flags;
5742+
5743+ timeo = sock_rcvtimeo(sock->sk, rflags & MSG_DONTWAIT);
5744+
5745+ while (1) {
5746+ spin_lock_irqsave(&i->lock, flags);
5747+ if (!list_empty(&i->msg_list))
5748+ break;
5749+ spin_unlock_irqrestore(&i->lock, flags);
5750+ if (!timeo) {
5751+ return -EAGAIN;
5752+ } else if (signal_pending (current)) {
5753+ dbg("Signal pending: %d", 1);
5754+ return -EINTR;
5755+ }
5756+
5757+ timeo = ipmi_wait_for_queue(i, timeo);
5758+ }
5759+
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);
5763+
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));
5770+
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);
5777+
5778+ ipmi_free_recv_msg(rcvmsg);
5779+
5780+ err = memcpy_toiovec(msg->msg_iov, (void *)smsg,
5781+ sizeof(struct ipmi_sock_msg) + smsg->data_len);
5782+ if (err) {
5783+ dbg("Cannot copy data to user: %p", i->user);
5784+ return err;
5785+ }
5786+
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);
5792+
5793+ return (sizeof(struct ipmi_sock_msg) + smsg->data_len);
5794+}
5795+
5796+static int ipmi_sendmsg(struct socket *sock, struct msghdr *msg, int len,
5797+ struct scm_cookie *scm)
5798+{
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;
5804+ int err;
5805+ struct ipmi_timing_parms tparms;
5806+ struct cmsghdr *cmsg;
5807+
5808+ err = ipmi_validate_addr(&addr->ipmi_addr,
5809+ msg->msg_namelen - SOCKADDR_IPMI_OVERHEAD);
5810+ if (err) {
5811+ dbg("Invalid IPMI address: %p", i->user);
5812+ goto err;
5813+ }
5814+
5815+ if (len > IPMI_MAX_SOCK_MSG_LENGTH) {
5816+ err = -EINVAL;
5817+ dbg("Message too long: %p", i->user);
5818+ goto err;
5819+ }
5820+
5821+ if (len < sizeof(struct ipmi_sock_msg)) {
5822+ err = -EINVAL;
5823+ dbg("Msg data too small for header: %p", i->user);
5824+ goto err;
5825+ }
5826+
5827+ err = memcpy_fromiovec((void *)smsg, msg->msg_iov, len);
5828+ if (err) {
5829+ dbg("Cannot copy data to kernel: %p", i->user);
5830+ goto err;
5831+ }
5832+
5833+ if (len < smsg->data_len+sizeof(struct ipmi_sock_msg)) {
5834+ err = -EINVAL;
5835+ dbg("Msg data is out of bound: %p", i->user);
5836+ goto err;
5837+ }
5838+
5839+ /* Set defaults. */
5840+ tparms.retries = i->default_retries;
5841+ tparms.retry_time_ms = i->default_retry_time_ms;
5842+
5843+ for (cmsg=CMSG_FIRSTHDR(msg);
5844+ cmsg;
5845+ cmsg = CMSG_NXTHDR(msg, cmsg))
5846+ {
5847+ if (cmsg->cmsg_len < sizeof(struct cmsghdr)) {
5848+ err = -EINVAL;
5849+ dbg("cmsg length too short: %p", i->user);
5850+ goto err;
5851+ }
5852+
5853+ if (cmsg->cmsg_level != SOL_SOCKET)
5854+ continue;
5855+
5856+ if (cmsg->cmsg_type == IPMI_CMSG_TIMING_PARMS) {
5857+ struct ipmi_timing_parms *pparms;
5858+
5859+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(*pparms))) {
5860+ err = -EINVAL;
5861+ dbg("timing parms cmsg not right size: %p",
5862+ i->user);
5863+ goto err;
5864+ }
5865+ pparms = (struct ipmi_timing_parms *) CMSG_DATA(cmsg);
5866+ tparms.retries = pparms->retries;
5867+ tparms.retry_time_ms = pparms->retry_time_ms;
5868+ }
5869+ }
5870+
5871+ imsg.netfn = smsg->netfn;
5872+ imsg.cmd = smsg->cmd;
5873+ imsg.data = smsg->data;
5874+ imsg.data_len = smsg->data_len;
5875+
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);
5884+ if (err) {
5885+ dbg("Cannot send message: %p", i->user);
5886+ goto err;
5887+ }
5888+
5889+err:
5890+ return err;
5891+}
5892+
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
5911+};
5912+
5913+
5914+static void ipmi_sock_destructor(struct sock *sk)
5915+{
5916+ skb_queue_purge(&sk->receive_queue);
5917+
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);
5922+ return;
5923+ }
5924+
5925+ atomic_dec(&ipmi_nr_socks);
5926+ MOD_DEC_USE_COUNT;
5927+}
5928+
5929+/*
5930+ * net protocol functions
5931+ */
5932+static struct sock *ipmi_socket_create1(struct socket *sock)
5933+{
5934+ struct sock *sk;
5935+
5936+ if (atomic_read(&ipmi_nr_socks) >= 2*files_stat.max_files)
5937+ return NULL;
5938+
5939+ MOD_INC_USE_COUNT;
5940+
5941+ sk = sk_alloc(PF_IPMI, GFP_KERNEL, 1);
5942+ if (!sk) {
5943+ MOD_DEC_USE_COUNT;
5944+ return NULL;
5945+ }
5946+
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);
5953+
5954+ /* Set to use default values. */
5955+ sk->protinfo.af_ipmi.default_retries = -1;
5956+ sk->protinfo.af_ipmi.default_retry_time_ms = 0;
5957+
5958+ atomic_inc(&ipmi_nr_socks);
5959+ return sk;
5960+}
5961+
5962+static int ipmi_socket_create(struct socket *sock, int protocol)
5963+{
5964+ if (!capable(CAP_NET_RAW))
5965+ return -EPERM;
5966+ if (protocol && protocol != PF_IPMI)
5967+ return -EPROTONOSUPPORT;
5968+
5969+ sock->state = SS_UNCONNECTED;
5970+
5971+ switch (sock->type) {
5972+ case SOCK_RAW:
5973+ sock->type=SOCK_DGRAM;
5974+ case SOCK_DGRAM:
5975+ sock->ops = &ipmi_ops;
5976+ break;
5977+ default:
5978+ return -EPROTONOSUPPORT;
5979+ }
5980+
5981+ return ipmi_socket_create1(sock)? 0 : -ENOMEM;
5982+}
5983+
5984+static struct net_proto_family ipmi_family_ops = {
5985+ .family = PF_IPMI,
5986+ .create = ipmi_socket_create,
5987+};
5988+
5989+
5990+/*
5991+ * init/exit functions
5992+ */
5993+static int __init ipmi_socket_init(void)
5994+{
5995+
5996+ int err=0;
5997+
5998+ printk(KERN_INFO "ipmi socket interface version "
5999+ IPMI_SOCKINTF_VERSION "\n");
6000+
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__);
6006+ err = -ENOMEM;
6007+ goto out;
6008+ }
6009+
6010+ err = sock_register(&ipmi_family_ops);
6011+ if (err)
6012+ kmem_cache_destroy(ipmi_sk_cachep);
6013+out:
6014+ return err;
6015+}
6016+
6017+static void __exit ipmi_socket_exit(void)
6018+{
6019+ sock_unregister(PF_IPMI);
6020+ kmem_cache_destroy(ipmi_sk_cachep);
6021+}
6022+
6023+#ifdef CONFIG_DEBUG_KERNEL
6024+MODULE_PARM(debug, "i");
6025+#endif
6026+module_init(ipmi_socket_init);
6027+module_exit(ipmi_socket_exit);
6028+
6029+MODULE_LICENSE("GPL");
6030diff -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
6033@@ -0,0 +1,7 @@
6034+
6035+O_TARGET = ipmi.o
6036+
6037+obj-$(CONFIG_IPMI_SOCKET) = af_ipmi.o
6038+
6039+include $(TOPDIR)/Rules.make
6040+
6041diff -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
6044@@ -8,7 +8,7 @@
6045 O_TARGET := network.o
6046
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
6051
6052 subdir-y := core ethernet
6053@@ -47,6 +47,7 @@
6054 subdir-$(CONFIG_DECNET) += decnet
6055 subdir-$(CONFIG_ECONET) += econet
6056 subdir-$(CONFIG_VLAN_8021Q) += 8021q
6057+subdir-$(CONFIG_IPMI_SOCKET) += ipmi
6058
6059 ifeq ($(CONFIG_NETFILTER),y)
6060 mod-subdirs += ipv4/ipvs
This page took 1.012778 seconds and 4 git commands to generate.