ipmi_msghandler.c 132.3 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0+
L
Linus Torvalds 已提交
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/*
 * ipmi_msghandler.c
 *
 * Incoming and outgoing message routing for an IPMI interface.
 *
 * Author: MontaVista Software, Inc.
 *         Corey Minyard <minyard@mvista.com>
 *         source@mvista.com
 *
 * Copyright 2002 MontaVista Software Inc.
 */

#include <linux/module.h>
#include <linux/errno.h>
#include <linux/poll.h>
17
#include <linux/sched.h>
18
#include <linux/seq_file.h>
L
Linus Torvalds 已提交
19
#include <linux/spinlock.h>
20
#include <linux/mutex.h>
L
Linus Torvalds 已提交
21 22 23 24 25 26
#include <linux/slab.h>
#include <linux/ipmi.h>
#include <linux/ipmi_smi.h>
#include <linux/notifier.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
27
#include <linux/rcupdate.h>
28
#include <linux/interrupt.h>
29
#include <linux/moduleparam.h>
30
#include <linux/workqueue.h>
31
#include <linux/uuid.h>
L
Linus Torvalds 已提交
32 33

#define PFX "IPMI message handler: "
34

C
Corey Minyard 已提交
35
#define IPMI_DRIVER_VERSION "39.2"
L
Linus Torvalds 已提交
36 37 38

static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
static int ipmi_init_msghandler(void);
39 40
static void smi_recv_tasklet(unsigned long);
static void handle_new_recv_msgs(ipmi_smi_t intf);
41
static void need_waiter(ipmi_smi_t intf);
42 43
static int handle_one_recv_msg(ipmi_smi_t          intf,
			       struct ipmi_smi_msg *msg);
L
Linus Torvalds 已提交
44

R
Randy Dunlap 已提交
45
static int initialized;
L
Linus Torvalds 已提交
46

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
enum ipmi_panic_event_op {
	IPMI_SEND_PANIC_EVENT_NONE,
	IPMI_SEND_PANIC_EVENT,
	IPMI_SEND_PANIC_EVENT_STRING
};
#ifdef CONFIG_IPMI_PANIC_STRING
#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT_STRING
#elif defined(CONFIG_IPMI_PANIC_EVENT)
#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT
#else
#define IPMI_PANIC_DEFAULT IPMI_SEND_PANIC_EVENT_NONE
#endif
static enum ipmi_panic_event_op ipmi_send_panic_event = IPMI_PANIC_DEFAULT;

static int panic_op_write_handler(const char *val,
				  const struct kernel_param *kp)
{
	char valcp[16];
	char *s;

X
Xiongfeng Wang 已提交
67
	strncpy(valcp, val, 15);
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
	valcp[15] = '\0';

	s = strstrip(valcp);

	if (strcmp(s, "none") == 0)
		ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT_NONE;
	else if (strcmp(s, "event") == 0)
		ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT;
	else if (strcmp(s, "string") == 0)
		ipmi_send_panic_event = IPMI_SEND_PANIC_EVENT_STRING;
	else
		return -EINVAL;

	return 0;
}

static int panic_op_read_handler(char *buffer, const struct kernel_param *kp)
{
	switch (ipmi_send_panic_event) {
	case IPMI_SEND_PANIC_EVENT_NONE:
		strcpy(buffer, "none");
		break;

	case IPMI_SEND_PANIC_EVENT:
		strcpy(buffer, "event");
		break;

	case IPMI_SEND_PANIC_EVENT_STRING:
		strcpy(buffer, "string");
		break;

	default:
		strcpy(buffer, "???");
		break;
	}

	return strlen(buffer);
}

static const struct kernel_param_ops panic_op_ops = {
	.set = panic_op_write_handler,
	.get = panic_op_read_handler
};
module_param_cb(panic_op, &panic_op_ops, NULL, 0600);
MODULE_PARM_DESC(panic_op, "Sets if the IPMI driver will attempt to store panic information in the event log in the event of a panic.  Set to 'none' for no, 'event' for a single event, or 'string' for a generic event and the panic string in IPMI OEM events.");


115
#ifdef CONFIG_IPMI_PROC_INTERFACE
R
Randy Dunlap 已提交
116
static struct proc_dir_entry *proc_ipmi_root;
117
#endif /* CONFIG_IPMI_PROC_INTERFACE */
L
Linus Torvalds 已提交
118 119 120

#define MAX_EVENTS_IN_QUEUE	25

121 122 123 124 125 126
/* Remain in auto-maintenance mode for this amount of time (in ms). */
static unsigned long maintenance_mode_timeout_ms = 30000;
module_param(maintenance_mode_timeout_ms, ulong, 0644);
MODULE_PARM_DESC(maintenance_mode_timeout_ms,
		 "The time (milliseconds) after the last maintenance message that the connection stays in maintenance mode.");

127 128 129 130
/*
 * Don't let a message sit in a queue forever, always time it with at lest
 * the max message timer.  This is in milliseconds.
 */
L
Linus Torvalds 已提交
131 132
#define MAX_MSG_TIMEOUT		60000

133 134 135 136 137 138 139 140 141 142 143 144 145
/*
 * Timeout times below are in milliseconds, and are done off a 1
 * second timer.  So setting the value to 1000 would mean anything
 * between 0 and 1000ms.  So really the only reasonable minimum
 * setting it 2000ms, which is between 1 and 2 seconds.
 */

/* The default timeout for message retries. */
static unsigned long default_retry_ms = 2000;
module_param(default_retry_ms, ulong, 0644);
MODULE_PARM_DESC(default_retry_ms,
		 "The time (milliseconds) between retry sends");

146 147 148 149 150 151
/* The default timeout for maintenance mode message retries. */
static unsigned long default_maintenance_retry_ms = 3000;
module_param(default_maintenance_retry_ms, ulong, 0644);
MODULE_PARM_DESC(default_maintenance_retry_ms,
		 "The time (milliseconds) between retry sends in maintenance mode");

152 153 154 155 156 157
/* The default maximum number of retries */
static unsigned int default_max_retries = 4;
module_param(default_max_retries, uint, 0644);
MODULE_PARM_DESC(default_max_retries,
		 "The time (milliseconds) between retry sends in maintenance mode");

158 159 160 161 162 163 164 165 166 167 168 169 170 171
/* Call every ~1000 ms. */
#define IPMI_TIMEOUT_TIME	1000

/* How many jiffies does it take to get to the timeout time. */
#define IPMI_TIMEOUT_JIFFIES	((IPMI_TIMEOUT_TIME * HZ) / 1000)

/*
 * Request events from the queue every second (this is the number of
 * IPMI_TIMEOUT_TIMES between event requests).  Hopefully, in the
 * future, IPMI will add a way to know immediately if an event is in
 * the queue and this silliness can go away.
 */
#define IPMI_REQUEST_EV_TIME	(1000 / (IPMI_TIMEOUT_TIME))

172 173 174
/* How long should we cache dynamic device IDs? */
#define IPMI_DYN_DEV_ID_EXPIRY	(10 * HZ)

175 176 177
/*
 * The main "user" data structure.
 */
178
struct ipmi_user {
L
Linus Torvalds 已提交
179 180
	struct list_head link;

C
Corey Minyard 已提交
181 182
	/* Set to false when the user is destroyed. */
	bool valid;
183 184 185

	struct kref refcount;

L
Linus Torvalds 已提交
186
	/* The upper layer that handles receive messages. */
C
Corey Minyard 已提交
187
	const struct ipmi_user_hndl *handler;
L
Linus Torvalds 已提交
188 189 190 191 192 193
	void             *handler_data;

	/* The interface this user is bound to. */
	ipmi_smi_t intf;

	/* Does this interface receive IPMI events? */
194
	bool gets_events;
L
Linus Torvalds 已提交
195 196
};

197
struct cmd_rcvr {
L
Linus Torvalds 已提交
198 199 200 201 202
	struct list_head link;

	ipmi_user_t   user;
	unsigned char netfn;
	unsigned char cmd;
203
	unsigned int  chans;
204 205 206 207 208 209 210

	/*
	 * This is used to form a linked lised during mass deletion.
	 * Since this is in an RCU list, we cannot use the link above
	 * or change any data until the RCU period completes.  So we
	 * use this next variable during mass deletion so we can have
	 * a list and don't have to wait and restart the search on
211 212
	 * every individual deletion of a command.
	 */
213
	struct cmd_rcvr *next;
L
Linus Torvalds 已提交
214 215
};

216
struct seq_table {
L
Linus Torvalds 已提交
217 218 219 220 221 222 223
	unsigned int         inuse : 1;
	unsigned int         broadcast : 1;

	unsigned long        timeout;
	unsigned long        orig_timeout;
	unsigned int         retries_left;

224 225 226 227 228
	/*
	 * To verify on an incoming send message response that this is
	 * the message that the response is for, we keep a sequence id
	 * and increment it every time we send a message.
	 */
L
Linus Torvalds 已提交
229 230
	long                 seqid;

231 232 233 234 235
	/*
	 * This is held so we can properly respond to the message on a
	 * timeout, and it is used to hold the temporary data for
	 * retransmission, too.
	 */
L
Linus Torvalds 已提交
236 237 238
	struct ipmi_recv_msg *recv_msg;
};

239 240 241 242
/*
 * Store the information in a msgid (long) to allow us to find a
 * sequence table entry from the msgid.
 */
C
Corey Minyard 已提交
243 244
#define STORE_SEQ_IN_MSGID(seq, seqid) \
	((((seq) & 0x3f) << 26) | ((seqid) & 0x3ffffff))
L
Linus Torvalds 已提交
245 246 247

#define GET_SEQ_FROM_MSGID(msgid, seq, seqid) \
	do {								\
C
Corey Minyard 已提交
248 249
		seq = (((msgid) >> 26) & 0x3f);				\
		seqid = ((msgid) & 0x3ffffff);				\
250
	} while (0)
L
Linus Torvalds 已提交
251

C
Corey Minyard 已提交
252
#define NEXT_SEQID(seqid) (((seqid) + 1) & 0x3ffffff)
L
Linus Torvalds 已提交
253

254
#define IPMI_MAX_CHANNELS       16
255
struct ipmi_channel {
L
Linus Torvalds 已提交
256 257
	unsigned char medium;
	unsigned char protocol;
258
};
259

260 261 262 263
struct ipmi_channel_set {
	struct ipmi_channel c[IPMI_MAX_CHANNELS];
};

264
struct ipmi_my_addrinfo {
265 266 267 268
	/*
	 * My slave address.  This is initialized to IPMI_BMC_SLAVE_ADDR,
	 * but may be changed by the user.
	 */
269 270
	unsigned char address;

271 272 273 274
	/*
	 * My LUN.  This should generally stay the SMS LUN, but just in
	 * case...
	 */
275
	unsigned char lun;
L
Linus Torvalds 已提交
276 277
};

278
#ifdef CONFIG_IPMI_PROC_INTERFACE
279
struct ipmi_proc_entry {
L
Linus Torvalds 已提交
280 281 282
	char                   *name;
	struct ipmi_proc_entry *next;
};
283
#endif
L
Linus Torvalds 已提交
284

285 286 287 288 289
/*
 * Note that the product id, manufacturer id, guid, and device id are
 * immutable in this structure, so dyn_mutex is not required for
 * accessing those.  If those change on a BMC, a new BMC is allocated.
 */
290
struct bmc_device {
291
	struct platform_device pdev;
292
	struct list_head       intfs; /* Interfaces on this BMC. */
293 294 295 296
	struct ipmi_device_id  id;
	struct ipmi_device_id  fetch_id;
	int                    dyn_id_set;
	unsigned long          dyn_id_expiry;
297
	struct mutex           dyn_mutex; /* Protects id, intfs, & dyn* */
298 299
	guid_t                 guid;
	guid_t                 fetch_guid;
300
	int                    dyn_guid_set;
301
	struct kref	       usecount;
302
	struct work_struct     remove_work;
303
};
304
#define to_bmc_device(x) container_of((x), struct bmc_device, pdev.dev)
305

306
static int bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
307
			     struct ipmi_device_id *id,
308
			     bool *guid_set, guid_t *guid);
309

310 311 312 313
/*
 * Various statistics for IPMI, these index stats[] in the ipmi_smi
 * structure.
 */
314 315 316
enum ipmi_stat_indexes {
	/* Commands we got from the user that were invalid. */
	IPMI_STAT_sent_invalid_commands = 0,
317

318 319
	/* Commands we sent to the MC. */
	IPMI_STAT_sent_local_commands,
320

321 322
	/* Responses from the MC that were delivered to a user. */
	IPMI_STAT_handled_local_responses,
323

324 325
	/* Responses from the MC that were not delivered to a user. */
	IPMI_STAT_unhandled_local_responses,
326

327 328
	/* Commands we sent out to the IPMB bus. */
	IPMI_STAT_sent_ipmb_commands,
329

330 331
	/* Commands sent on the IPMB that had errors on the SEND CMD */
	IPMI_STAT_sent_ipmb_command_errs,
332

333 334
	/* Each retransmit increments this count. */
	IPMI_STAT_retransmitted_ipmb_commands,
335

336 337 338 339 340
	/*
	 * When a message times out (runs out of retransmits) this is
	 * incremented.
	 */
	IPMI_STAT_timed_out_ipmb_commands,
341

342 343 344 345 346 347
	/*
	 * This is like above, but for broadcasts.  Broadcasts are
	 * *not* included in the above count (they are expected to
	 * time out).
	 */
	IPMI_STAT_timed_out_ipmb_broadcasts,
348

349 350
	/* Responses I have sent to the IPMB bus. */
	IPMI_STAT_sent_ipmb_responses,
351

352 353
	/* The response was delivered to the user. */
	IPMI_STAT_handled_ipmb_responses,
354

355 356
	/* The response had invalid data in it. */
	IPMI_STAT_invalid_ipmb_responses,
357

358 359
	/* The response didn't have anyone waiting for it. */
	IPMI_STAT_unhandled_ipmb_responses,
360

361 362
	/* Commands we sent out to the IPMB bus. */
	IPMI_STAT_sent_lan_commands,
363

364 365
	/* Commands sent on the IPMB that had errors on the SEND CMD */
	IPMI_STAT_sent_lan_command_errs,
366

367 368
	/* Each retransmit increments this count. */
	IPMI_STAT_retransmitted_lan_commands,
369

370 371 372 373 374 375 376 377
	/*
	 * When a message times out (runs out of retransmits) this is
	 * incremented.
	 */
	IPMI_STAT_timed_out_lan_commands,

	/* Responses I have sent to the IPMB bus. */
	IPMI_STAT_sent_lan_responses,
378

379 380
	/* The response was delivered to the user. */
	IPMI_STAT_handled_lan_responses,
381

382 383
	/* The response had invalid data in it. */
	IPMI_STAT_invalid_lan_responses,
384

385 386
	/* The response didn't have anyone waiting for it. */
	IPMI_STAT_unhandled_lan_responses,
387

388 389
	/* The command was delivered to the user. */
	IPMI_STAT_handled_commands,
390

391 392
	/* The command had invalid data in it. */
	IPMI_STAT_invalid_commands,
393

394 395
	/* The command didn't have anyone waiting for it. */
	IPMI_STAT_unhandled_commands,
396

397 398
	/* Invalid data in an event. */
	IPMI_STAT_invalid_events,
399

400 401
	/* Events that were received with the proper format. */
	IPMI_STAT_events,
402

403 404 405 406 407
	/* Retransmissions on IPMB that failed. */
	IPMI_STAT_dropped_rexmit_ipmb_commands,

	/* Retransmissions on LAN that failed. */
	IPMI_STAT_dropped_rexmit_lan_commands,
408

409 410 411
	/* This *must* remain last, add new values above this. */
	IPMI_NUM_STATS
};
412 413


L
Linus Torvalds 已提交
414
#define IPMI_IPMB_NUM_SEQ	64
415
struct ipmi_smi {
L
Linus Torvalds 已提交
416 417 418
	/* What interface number are we? */
	int intf_num;

419 420
	struct kref refcount;

421 422 423
	/* Set when the interface is being unregistered. */
	bool in_shutdown;

424 425 426
	/* Used for a list of interfaces. */
	struct list_head link;

427 428 429 430
	/*
	 * The list of upper layers that are using me.  seq_lock
	 * protects this.
	 */
431
	struct list_head users;
L
Linus Torvalds 已提交
432 433 434 435

	/* Used for wake ups at startup. */
	wait_queue_head_t waitq;

436 437 438 439 440 441 442
	/*
	 * Prevents the interface from being unregistered when the
	 * interface is used by being looked up through the BMC
	 * structure.
	 */
	struct mutex bmc_reg_mutex;

443
	struct bmc_device tmp_bmc;
444
	struct bmc_device *bmc;
C
Corey Minyard 已提交
445
	bool bmc_registered;
446
	struct list_head bmc_link;
447
	char *my_dev_name;
448
	bool in_bmc_register;  /* Handle recursive situations.  Yuck. */
449
	struct work_struct bmc_reg_work;
L
Linus Torvalds 已提交
450

451 452
	/*
	 * This is the lower-layer's sender routine.  Note that you
453 454
	 * must either be holding the ipmi_interfaces_mutex or be in
	 * an umpreemptible region to use this.  You must fetch the
455 456
	 * value into a local variable and make sure it is not NULL.
	 */
457
	const struct ipmi_smi_handlers *handlers;
L
Linus Torvalds 已提交
458 459
	void                     *send_info;

460
#ifdef CONFIG_IPMI_PROC_INTERFACE
C
Corey Minyard 已提交
461 462
	/* A list of proc entries for this interface. */
	struct mutex           proc_entry_lock;
L
Linus Torvalds 已提交
463
	struct ipmi_proc_entry *proc_entries;
464 465 466

	struct proc_dir_entry *proc_dir;
	char                  proc_dir_name[10];
467
#endif
L
Linus Torvalds 已提交
468

469 470 471
	/* Driver-model device for the system interface. */
	struct device          *si_dev;

472 473 474 475 476 477
	/*
	 * A table of sequence numbers for this interface.  We use the
	 * sequence numbers for IPMB messages that go out of the
	 * interface to match them up with their responses.  A routine
	 * is called periodically to time the items in this list.
	 */
L
Linus Torvalds 已提交
478 479 480 481
	spinlock_t       seq_lock;
	struct seq_table seq_table[IPMI_IPMB_NUM_SEQ];
	int curr_seq;

482
	/*
483 484 485 486
	 * Messages queued for delivery.  If delivery fails (out of memory
	 * for instance), They will stay in here to be processed later in a
	 * periodic timer interrupt.  The tasklet is for handling received
	 * messages directly from the handler.
487
	 */
488 489
	spinlock_t       waiting_rcv_msgs_lock;
	struct list_head waiting_rcv_msgs;
490 491
	atomic_t	 watchdog_pretimeouts_to_deliver;
	struct tasklet_struct recv_tasklet;
L
Linus Torvalds 已提交
492

493 494 495 496 497
	spinlock_t             xmit_msgs_lock;
	struct list_head       xmit_msgs;
	struct ipmi_smi_msg    *curr_msg;
	struct list_head       hp_xmit_msgs;

498 499 500 501
	/*
	 * The list of command receivers that are registered for commands
	 * on this interface.
	 */
502
	struct mutex     cmd_rcvrs_mutex;
L
Linus Torvalds 已提交
503 504
	struct list_head cmd_rcvrs;

505 506 507 508
	/*
	 * Events that were queues because no one was there to receive
	 * them.
	 */
L
Linus Torvalds 已提交
509 510 511
	spinlock_t       events_lock; /* For dealing with event stuff. */
	struct list_head waiting_events;
	unsigned int     waiting_events_count; /* How many events in queue? */
512 513
	char             delivering_events;
	char             event_msg_printed;
514 515 516
	atomic_t         event_waiters;
	unsigned int     ticks_to_req_ev;
	int              last_needs_timer;
L
Linus Torvalds 已提交
517

518 519 520 521
	/*
	 * The event receiver for my BMC, only really used at panic
	 * shutdown as a place to store this.
	 */
L
Linus Torvalds 已提交
522 523 524 525 526
	unsigned char event_receiver;
	unsigned char event_receiver_lun;
	unsigned char local_sel_device;
	unsigned char local_event_generator;

C
Corey Minyard 已提交
527 528
	/* For handling of maintenance mode. */
	int maintenance_mode;
C
Corey Minyard 已提交
529
	bool maintenance_mode_enable;
C
Corey Minyard 已提交
530 531 532
	int auto_maintenance_timeout;
	spinlock_t maintenance_mode_lock; /* Used in a timer... */

533 534 535 536 537 538 539
	/*
	 * If we are doing maintenance on something on IPMB, extend
	 * the timeout time to avoid timeouts writing firmware and
	 * such.
	 */
	int ipmb_maintenance_mode_timeout;

540 541 542 543 544
	/*
	 * A cheap hack, if this is non-null and a message to an
	 * interface comes in with a NULL user, call this routine with
	 * it.  Note that the message will still be freed by the
	 * caller.  This only works on the system interface.
545
	 *
546
	 * Protected by bmc_reg_mutex.
547
	 */
548
	void (*null_user_handler)(ipmi_smi_t intf, struct ipmi_recv_msg *msg);
L
Linus Torvalds 已提交
549

550 551 552 553
	/*
	 * When we are scanning the channels for an SMI, this will
	 * tell which channel we are scanning.
	 */
L
Linus Torvalds 已提交
554 555 556
	int curr_channel;

	/* Channel information */
557 558 559
	struct ipmi_channel_set *channel_list;
	unsigned int curr_working_cset; /* First index into the following. */
	struct ipmi_channel_set wchannels[2];
560
	struct ipmi_my_addrinfo addrinfo[IPMI_MAX_CHANNELS];
561
	bool channels_ready;
L
Linus Torvalds 已提交
562

563
	atomic_t stats[IPMI_NUM_STATS];
564 565 566 567 568 569 570

	/*
	 * run_to_completion duplicate of smb_info, smi_info
	 * and ipmi_serial_info structures. Used to decrease numbers of
	 * parameters passed by "low" level IPMI code.
	 */
	int run_to_completion;
L
Linus Torvalds 已提交
571
};
572
#define to_si_intf_from_dev(device) container_of(device, struct ipmi_smi, dev)
L
Linus Torvalds 已提交
573

574
static void __get_guid(ipmi_smi_t intf);
575 576 577
static void __ipmi_bmc_unregister(ipmi_smi_t intf);
static int __ipmi_bmc_register(ipmi_smi_t intf,
			       struct ipmi_device_id *id,
578
			       bool guid_set, guid_t *guid, int intf_num);
579
static int __scan_channels(ipmi_smi_t intf, struct ipmi_device_id *id);
580

581

582 583 584
/**
 * The driver model view of the IPMI messaging driver.
 */
585 586 587 588 589
static struct platform_driver ipmidriver = {
	.driver = {
		.name = "ipmi",
		.bus = &platform_bus_type
	}
590
};
591
/*
592
 * This mutex keeps us from adding the same BMC twice.
593
 */
594 595
static DEFINE_MUTEX(ipmidriver_mutex);

596
static LIST_HEAD(ipmi_interfaces);
597
static DEFINE_MUTEX(ipmi_interfaces_mutex);
L
Linus Torvalds 已提交
598

599 600 601
/*
 * List of watchers that want to know when smi's are added and deleted.
 */
602
static LIST_HEAD(smi_watchers);
603
static DEFINE_MUTEX(smi_watchers_mutex);
L
Linus Torvalds 已提交
604

605 606 607 608 609
#define ipmi_inc_stat(intf, stat) \
	atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
#define ipmi_get_stat(intf, stat) \
	((unsigned int) atomic_read(&(intf)->stats[IPMI_STAT_ ## stat]))

610 611
static const char * const addr_src_to_str[] = {
	"invalid", "hotmod", "hardcoded", "SPMI", "ACPI", "SMBIOS", "PCI",
612
	"device-tree", "platform"
613
};
614 615 616

const char *ipmi_addr_src_to_str(enum ipmi_addr_src src)
{
617
	if (src >= SI_LAST)
618 619 620 621 622
		src = 0; /* Invalid */
	return addr_src_to_str[src];
}
EXPORT_SYMBOL(ipmi_addr_src_to_str);

623 624 625 626 627 628 629 630 631 632 633 634 635 636
static int is_lan_addr(struct ipmi_addr *addr)
{
	return addr->addr_type == IPMI_LAN_ADDR_TYPE;
}

static int is_ipmb_addr(struct ipmi_addr *addr)
{
	return addr->addr_type == IPMI_IPMB_ADDR_TYPE;
}

static int is_ipmb_bcast_addr(struct ipmi_addr *addr)
{
	return addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE;
}
637

638 639 640 641 642 643 644 645 646 647
static void free_recv_msg_list(struct list_head *q)
{
	struct ipmi_recv_msg *msg, *msg2;

	list_for_each_entry_safe(msg, msg2, q, link) {
		list_del(&msg->link);
		ipmi_free_recv_msg(msg);
	}
}

648 649 650 651 652 653 654 655 656 657
static void free_smi_msg_list(struct list_head *q)
{
	struct ipmi_smi_msg *msg, *msg2;

	list_for_each_entry_safe(msg, msg2, q, link) {
		list_del(&msg->link);
		ipmi_free_smi_msg(msg);
	}
}

658 659 660 661 662 663
static void clean_up_interface_data(ipmi_smi_t intf)
{
	int              i;
	struct cmd_rcvr  *rcvr, *rcvr2;
	struct list_head list;

664 665
	tasklet_kill(&intf->recv_tasklet);

666
	free_smi_msg_list(&intf->waiting_rcv_msgs);
667 668
	free_recv_msg_list(&intf->waiting_events);

669 670 671 672
	/*
	 * Wholesale remove all the entries from the list in the
	 * interface and wait for RCU to know that none are in use.
	 */
673
	mutex_lock(&intf->cmd_rcvrs_mutex);
674 675
	INIT_LIST_HEAD(&list);
	list_splice_init_rcu(&intf->cmd_rcvrs, &list, synchronize_rcu);
676
	mutex_unlock(&intf->cmd_rcvrs_mutex);
677 678 679 680 681 682

	list_for_each_entry_safe(rcvr, rcvr2, &list, link)
		kfree(rcvr);

	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
		if ((intf->seq_table[i].inuse)
683
					&& (intf->seq_table[i].recv_msg))
684 685 686 687 688 689 690 691 692 693 694 695
			ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
	}
}

static void intf_free(struct kref *ref)
{
	ipmi_smi_t intf = container_of(ref, struct ipmi_smi, refcount);

	clean_up_interface_data(intf);
	kfree(intf);
}

696
struct watcher_entry {
697 698
	int              intf_num;
	ipmi_smi_t       intf;
699 700 701
	struct list_head link;
};

L
Linus Torvalds 已提交
702 703
int ipmi_smi_watcher_register(struct ipmi_smi_watcher *watcher)
{
704
	ipmi_smi_t intf;
705
	LIST_HEAD(to_deliver);
706 707
	struct watcher_entry *e, *e2;

708 709
	mutex_lock(&smi_watchers_mutex);

710 711
	mutex_lock(&ipmi_interfaces_mutex);

712
	/* Build a list of things to deliver. */
713
	list_for_each_entry(intf, &ipmi_interfaces, link) {
714 715 716 717 718
		if (intf->intf_num == -1)
			continue;
		e = kmalloc(sizeof(*e), GFP_KERNEL);
		if (!e)
			goto out_err;
719 720
		kref_get(&intf->refcount);
		e->intf = intf;
721 722 723
		e->intf_num = intf->intf_num;
		list_add_tail(&e->link, &to_deliver);
	}
L
Linus Torvalds 已提交
724

725 726
	/* We will succeed, so add it to the list. */
	list_add(&watcher->link, &smi_watchers);
727 728 729 730 731

	mutex_unlock(&ipmi_interfaces_mutex);

	list_for_each_entry_safe(e, e2, &to_deliver, link) {
		list_del(&e->link);
732 733
		watcher->new_smi(e->intf_num, e->intf->si_dev);
		kref_put(&e->intf->refcount, intf_free);
734
		kfree(e);
L
Linus Torvalds 已提交
735
	}
736

737
	mutex_unlock(&smi_watchers_mutex);
738

L
Linus Torvalds 已提交
739
	return 0;
740 741

 out_err:
742 743
	mutex_unlock(&ipmi_interfaces_mutex);
	mutex_unlock(&smi_watchers_mutex);
744 745
	list_for_each_entry_safe(e, e2, &to_deliver, link) {
		list_del(&e->link);
746
		kref_put(&e->intf->refcount, intf_free);
747 748 749
		kfree(e);
	}
	return -ENOMEM;
L
Linus Torvalds 已提交
750
}
751
EXPORT_SYMBOL(ipmi_smi_watcher_register);
L
Linus Torvalds 已提交
752 753 754

int ipmi_smi_watcher_unregister(struct ipmi_smi_watcher *watcher)
{
755
	mutex_lock(&smi_watchers_mutex);
L
Linus Torvalds 已提交
756
	list_del(&(watcher->link));
757
	mutex_unlock(&smi_watchers_mutex);
L
Linus Torvalds 已提交
758 759
	return 0;
}
760
EXPORT_SYMBOL(ipmi_smi_watcher_unregister);
L
Linus Torvalds 已提交
761

762 763 764
/*
 * Must be called with smi_watchers_mutex held.
 */
L
Linus Torvalds 已提交
765
static void
766
call_smi_watchers(int i, struct device *dev)
L
Linus Torvalds 已提交
767 768 769 770 771
{
	struct ipmi_smi_watcher *w;

	list_for_each_entry(w, &smi_watchers, link) {
		if (try_module_get(w->owner)) {
772
			w->new_smi(i, dev);
L
Linus Torvalds 已提交
773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794
			module_put(w->owner);
		}
	}
}

static int
ipmi_addr_equal(struct ipmi_addr *addr1, struct ipmi_addr *addr2)
{
	if (addr1->addr_type != addr2->addr_type)
		return 0;

	if (addr1->channel != addr2->channel)
		return 0;

	if (addr1->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
		struct ipmi_system_interface_addr *smi_addr1
		    = (struct ipmi_system_interface_addr *) addr1;
		struct ipmi_system_interface_addr *smi_addr2
		    = (struct ipmi_system_interface_addr *) addr2;
		return (smi_addr1->lun == smi_addr2->lun);
	}

795
	if (is_ipmb_addr(addr1) || is_ipmb_bcast_addr(addr1)) {
L
Linus Torvalds 已提交
796 797 798 799 800 801 802 803 804
		struct ipmi_ipmb_addr *ipmb_addr1
		    = (struct ipmi_ipmb_addr *) addr1;
		struct ipmi_ipmb_addr *ipmb_addr2
		    = (struct ipmi_ipmb_addr *) addr2;

		return ((ipmb_addr1->slave_addr == ipmb_addr2->slave_addr)
			&& (ipmb_addr1->lun == ipmb_addr2->lun));
	}

805
	if (is_lan_addr(addr1)) {
L
Linus Torvalds 已提交
806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822
		struct ipmi_lan_addr *lan_addr1
			= (struct ipmi_lan_addr *) addr1;
		struct ipmi_lan_addr *lan_addr2
		    = (struct ipmi_lan_addr *) addr2;

		return ((lan_addr1->remote_SWID == lan_addr2->remote_SWID)
			&& (lan_addr1->local_SWID == lan_addr2->local_SWID)
			&& (lan_addr1->session_handle
			    == lan_addr2->session_handle)
			&& (lan_addr1->lun == lan_addr2->lun));
	}

	return 1;
}

int ipmi_validate_addr(struct ipmi_addr *addr, int len)
{
823
	if (len < sizeof(struct ipmi_system_interface_addr))
L
Linus Torvalds 已提交
824 825 826 827 828 829 830 831 832
		return -EINVAL;

	if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
		if (addr->channel != IPMI_BMC_CHANNEL)
			return -EINVAL;
		return 0;
	}

	if ((addr->channel == IPMI_BMC_CHANNEL)
833
	    || (addr->channel >= IPMI_MAX_CHANNELS)
L
Linus Torvalds 已提交
834 835 836
	    || (addr->channel < 0))
		return -EINVAL;

837
	if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
838
		if (len < sizeof(struct ipmi_ipmb_addr))
L
Linus Torvalds 已提交
839 840 841 842
			return -EINVAL;
		return 0;
	}

843
	if (is_lan_addr(addr)) {
844
		if (len < sizeof(struct ipmi_lan_addr))
L
Linus Torvalds 已提交
845 846 847 848 849 850
			return -EINVAL;
		return 0;
	}

	return -EINVAL;
}
851
EXPORT_SYMBOL(ipmi_validate_addr);
L
Linus Torvalds 已提交
852 853 854 855 856 857 858

unsigned int ipmi_addr_length(int addr_type)
{
	if (addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
		return sizeof(struct ipmi_system_interface_addr);

	if ((addr_type == IPMI_IPMB_ADDR_TYPE)
859
			|| (addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE))
L
Linus Torvalds 已提交
860 861 862 863 864 865 866
		return sizeof(struct ipmi_ipmb_addr);

	if (addr_type == IPMI_LAN_ADDR_TYPE)
		return sizeof(struct ipmi_lan_addr);

	return 0;
}
867
EXPORT_SYMBOL(ipmi_addr_length);
L
Linus Torvalds 已提交
868 869 870

static void deliver_response(struct ipmi_recv_msg *msg)
{
871
	if (!msg->user) {
872 873 874 875 876
		ipmi_smi_t    intf = msg->user_msg_data;

		/* Special handling for NULL users. */
		if (intf->null_user_handler) {
			intf->null_user_handler(intf, msg);
877
			ipmi_inc_stat(intf, handled_local_responses);
878 879
		} else {
			/* No handler, so give up. */
880
			ipmi_inc_stat(intf, unhandled_local_responses);
881 882
		}
		ipmi_free_recv_msg(msg);
883 884 885 886 887 888 889
	} else if (!oops_in_progress) {
		/*
		 * If we are running in the panic context, calling the
		 * receive handler doesn't much meaning and has a deadlock
		 * risk.  At this moment, simply skip it in that case.
		 */

890 891
		ipmi_user_t user = msg->user;
		user->handler->ipmi_recv_hndl(msg, user->handler_data);
892
	}
L
Linus Torvalds 已提交
893 894
}

895 896 897 898 899 900 901 902 903 904 905
static void
deliver_err_response(struct ipmi_recv_msg *msg, int err)
{
	msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
	msg->msg_data[0] = err;
	msg->msg.netfn |= 1; /* Convert to a response. */
	msg->msg.data_len = 1;
	msg->msg.data = msg->msg_data;
	deliver_response(msg);
}

906 907 908 909 910
/*
 * Find the next sequence number not being used and add the given
 * message with the given timeout to the sequence table.  This must be
 * called with the interface's seq_lock held.
 */
L
Linus Torvalds 已提交
911 912 913 914 915 916 917 918 919 920 921
static int intf_next_seq(ipmi_smi_t           intf,
			 struct ipmi_recv_msg *recv_msg,
			 unsigned long        timeout,
			 int                  retries,
			 int                  broadcast,
			 unsigned char        *seq,
			 long                 *seqid)
{
	int          rv = 0;
	unsigned int i;

922 923 924 925 926
	if (timeout == 0)
		timeout = default_retry_ms;
	if (retries < 0)
		retries = default_max_retries;

927 928
	for (i = intf->curr_seq; (i+1)%IPMI_IPMB_NUM_SEQ != intf->curr_seq;
					i = (i+1)%IPMI_IPMB_NUM_SEQ) {
929
		if (!intf->seq_table[i].inuse)
L
Linus Torvalds 已提交
930 931 932
			break;
	}

933
	if (!intf->seq_table[i].inuse) {
L
Linus Torvalds 已提交
934 935
		intf->seq_table[i].recv_msg = recv_msg;

936 937 938 939
		/*
		 * Start with the maximum timeout, when the send response
		 * comes in we will start the real timer.
		 */
L
Linus Torvalds 已提交
940 941 942 943 944 945 946 947 948
		intf->seq_table[i].timeout = MAX_MSG_TIMEOUT;
		intf->seq_table[i].orig_timeout = timeout;
		intf->seq_table[i].retries_left = retries;
		intf->seq_table[i].broadcast = broadcast;
		intf->seq_table[i].inuse = 1;
		intf->seq_table[i].seqid = NEXT_SEQID(intf->seq_table[i].seqid);
		*seq = i;
		*seqid = intf->seq_table[i].seqid;
		intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
949
		need_waiter(intf);
L
Linus Torvalds 已提交
950 951 952
	} else {
		rv = -EAGAIN;
	}
953

L
Linus Torvalds 已提交
954 955 956
	return rv;
}

957 958 959 960 961 962 963
/*
 * Return the receive message for the given sequence number and
 * release the sequence number so it can be reused.  Some other data
 * is passed in to be sure the message matches up correctly (to help
 * guard against message coming in after their timeout and the
 * sequence number being reused).
 */
L
Linus Torvalds 已提交
964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981
static int intf_find_seq(ipmi_smi_t           intf,
			 unsigned char        seq,
			 short                channel,
			 unsigned char        cmd,
			 unsigned char        netfn,
			 struct ipmi_addr     *addr,
			 struct ipmi_recv_msg **recv_msg)
{
	int           rv = -ENODEV;
	unsigned long flags;

	if (seq >= IPMI_IPMB_NUM_SEQ)
		return -EINVAL;

	spin_lock_irqsave(&(intf->seq_lock), flags);
	if (intf->seq_table[seq].inuse) {
		struct ipmi_recv_msg *msg = intf->seq_table[seq].recv_msg;

982 983 984
		if ((msg->addr.channel == channel) && (msg->msg.cmd == cmd)
				&& (msg->msg.netfn == netfn)
				&& (ipmi_addr_equal(addr, &(msg->addr)))) {
L
Linus Torvalds 已提交
985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008
			*recv_msg = msg;
			intf->seq_table[seq].inuse = 0;
			rv = 0;
		}
	}
	spin_unlock_irqrestore(&(intf->seq_lock), flags);

	return rv;
}


/* Start the timer for a specific sequence table entry. */
static int intf_start_seq_timer(ipmi_smi_t intf,
				long       msgid)
{
	int           rv = -ENODEV;
	unsigned long flags;
	unsigned char seq;
	unsigned long seqid;


	GET_SEQ_FROM_MSGID(msgid, seq, seqid);

	spin_lock_irqsave(&(intf->seq_lock), flags);
1009 1010 1011 1012
	/*
	 * We do this verification because the user can be deleted
	 * while a message is outstanding.
	 */
L
Linus Torvalds 已提交
1013
	if ((intf->seq_table[seq].inuse)
1014
				&& (intf->seq_table[seq].seqid == seqid)) {
L
Linus Torvalds 已提交
1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038
		struct seq_table *ent = &(intf->seq_table[seq]);
		ent->timeout = ent->orig_timeout;
		rv = 0;
	}
	spin_unlock_irqrestore(&(intf->seq_lock), flags);

	return rv;
}

/* Got an error for the send message for a specific sequence number. */
static int intf_err_seq(ipmi_smi_t   intf,
			long         msgid,
			unsigned int err)
{
	int                  rv = -ENODEV;
	unsigned long        flags;
	unsigned char        seq;
	unsigned long        seqid;
	struct ipmi_recv_msg *msg = NULL;


	GET_SEQ_FROM_MSGID(msgid, seq, seqid);

	spin_lock_irqsave(&(intf->seq_lock), flags);
1039 1040 1041 1042
	/*
	 * We do this verification because the user can be deleted
	 * while a message is outstanding.
	 */
L
Linus Torvalds 已提交
1043
	if ((intf->seq_table[seq].inuse)
1044
				&& (intf->seq_table[seq].seqid == seqid)) {
L
Linus Torvalds 已提交
1045 1046 1047 1048 1049 1050 1051 1052
		struct seq_table *ent = &(intf->seq_table[seq]);

		ent->inuse = 0;
		msg = ent->recv_msg;
		rv = 0;
	}
	spin_unlock_irqrestore(&(intf->seq_lock), flags);

1053 1054
	if (msg)
		deliver_err_response(msg, err);
L
Linus Torvalds 已提交
1055 1056 1057 1058 1059 1060

	return rv;
}


int ipmi_create_user(unsigned int          if_num,
C
Corey Minyard 已提交
1061
		     const struct ipmi_user_hndl *handler,
L
Linus Torvalds 已提交
1062 1063 1064 1065 1066 1067 1068 1069
		     void                  *handler_data,
		     ipmi_user_t           *user)
{
	unsigned long flags;
	ipmi_user_t   new_user;
	int           rv = 0;
	ipmi_smi_t    intf;

1070 1071 1072 1073 1074 1075 1076
	/*
	 * There is no module usecount here, because it's not
	 * required.  Since this can only be used by and called from
	 * other modules, they will implicitly use this module, and
	 * thus this can't be removed unless the other modules are
	 * removed.
	 */
L
Linus Torvalds 已提交
1077 1078 1079 1080

	if (handler == NULL)
		return -EINVAL;

1081 1082 1083 1084
	/*
	 * Make sure the driver is actually initialized, this handles
	 * problems with initialization order.
	 */
L
Linus Torvalds 已提交
1085 1086 1087 1088 1089
	if (!initialized) {
		rv = ipmi_init_msghandler();
		if (rv)
			return rv;

1090 1091 1092 1093
		/*
		 * The init code doesn't return an error if it was turned
		 * off, but it won't initialize.  Check that.
		 */
L
Linus Torvalds 已提交
1094 1095 1096 1097 1098
		if (!initialized)
			return -ENODEV;
	}

	new_user = kmalloc(sizeof(*new_user), GFP_KERNEL);
1099
	if (!new_user)
L
Linus Torvalds 已提交
1100 1101
		return -ENOMEM;

1102
	mutex_lock(&ipmi_interfaces_mutex);
1103 1104 1105
	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
		if (intf->intf_num == if_num)
			goto found;
L
Linus Torvalds 已提交
1106
	}
1107
	/* Not found, return an error */
1108 1109
	rv = -EINVAL;
	goto out_kfree;
L
Linus Torvalds 已提交
1110

1111
 found:
1112 1113
	/* Note that each existing user holds a refcount to the interface. */
	kref_get(&intf->refcount);
L
Linus Torvalds 已提交
1114

1115
	kref_init(&new_user->refcount);
L
Linus Torvalds 已提交
1116 1117 1118
	new_user->handler = handler;
	new_user->handler_data = handler_data;
	new_user->intf = intf;
1119
	new_user->gets_events = false;
L
Linus Torvalds 已提交
1120 1121 1122

	if (!try_module_get(intf->handlers->owner)) {
		rv = -ENODEV;
1123
		goto out_kref;
L
Linus Torvalds 已提交
1124 1125 1126 1127 1128 1129
	}

	if (intf->handlers->inc_usecount) {
		rv = intf->handlers->inc_usecount(intf->send_info);
		if (rv) {
			module_put(intf->handlers->owner);
1130
			goto out_kref;
L
Linus Torvalds 已提交
1131 1132 1133
		}
	}

1134 1135 1136 1137
	/*
	 * Hold the lock so intf->handlers is guaranteed to be good
	 * until now
	 */
1138 1139
	mutex_unlock(&ipmi_interfaces_mutex);

C
Corey Minyard 已提交
1140
	new_user->valid = true;
1141 1142 1143
	spin_lock_irqsave(&intf->seq_lock, flags);
	list_add_rcu(&new_user->link, &intf->users);
	spin_unlock_irqrestore(&intf->seq_lock, flags);
1144 1145 1146 1147 1148
	if (handler->ipmi_watchdog_pretimeout) {
		/* User wants pretimeouts, so make sure to watch for them. */
		if (atomic_inc_return(&intf->event_waiters) == 1)
			need_waiter(intf);
	}
1149 1150
	*user = new_user;
	return 0;
L
Linus Torvalds 已提交
1151

1152
out_kref:
1153
	kref_put(&intf->refcount, intf_free);
1154
out_kfree:
1155
	mutex_unlock(&ipmi_interfaces_mutex);
1156
	kfree(new_user);
L
Linus Torvalds 已提交
1157 1158
	return rv;
}
1159
EXPORT_SYMBOL(ipmi_create_user);
L
Linus Torvalds 已提交
1160

1161 1162 1163 1164
int ipmi_get_smi_info(int if_num, struct ipmi_smi_info *data)
{
	int           rv = 0;
	ipmi_smi_t    intf;
1165
	const struct ipmi_smi_handlers *handlers;
1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187

	mutex_lock(&ipmi_interfaces_mutex);
	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
		if (intf->intf_num == if_num)
			goto found;
	}
	/* Not found, return an error */
	rv = -EINVAL;
	mutex_unlock(&ipmi_interfaces_mutex);
	return rv;

found:
	handlers = intf->handlers;
	rv = -ENOSYS;
	if (handlers->get_smi_info)
		rv = handlers->get_smi_info(intf->send_info, data);
	mutex_unlock(&ipmi_interfaces_mutex);

	return rv;
}
EXPORT_SYMBOL(ipmi_get_smi_info);

1188 1189 1190 1191 1192 1193 1194
static void free_user(struct kref *ref)
{
	ipmi_user_t user = container_of(ref, struct ipmi_user, refcount);
	kfree(user);
}

int ipmi_destroy_user(ipmi_user_t user)
L
Linus Torvalds 已提交
1195
{
1196
	ipmi_smi_t       intf = user->intf;
L
Linus Torvalds 已提交
1197 1198
	int              i;
	unsigned long    flags;
1199 1200
	struct cmd_rcvr  *rcvr;
	struct cmd_rcvr  *rcvrs = NULL;
L
Linus Torvalds 已提交
1201

C
Corey Minyard 已提交
1202
	user->valid = false;
L
Linus Torvalds 已提交
1203

1204 1205 1206 1207 1208 1209
	if (user->handler->ipmi_watchdog_pretimeout)
		atomic_dec(&intf->event_waiters);

	if (user->gets_events)
		atomic_dec(&intf->event_waiters);

1210 1211 1212
	/* Remove the user from the interface's sequence table. */
	spin_lock_irqsave(&intf->seq_lock, flags);
	list_del_rcu(&user->link);
L
Linus Torvalds 已提交
1213

C
Corey Minyard 已提交
1214
	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
1215
		if (intf->seq_table[i].inuse
1216
		    && (intf->seq_table[i].recv_msg->user == user)) {
1217
			intf->seq_table[i].inuse = 0;
1218
			ipmi_free_recv_msg(intf->seq_table[i].recv_msg);
L
Linus Torvalds 已提交
1219 1220
		}
	}
1221 1222 1223 1224 1225 1226 1227 1228
	spin_unlock_irqrestore(&intf->seq_lock, flags);

	/*
	 * Remove the user from the command receiver's table.  First
	 * we build a list of everything (not using the standard link,
	 * since other things may be using it till we do
	 * synchronize_rcu()) then free everything in that list.
	 */
1229
	mutex_lock(&intf->cmd_rcvrs_mutex);
1230
	list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
L
Linus Torvalds 已提交
1231
		if (rcvr->user == user) {
1232 1233 1234
			list_del_rcu(&rcvr->link);
			rcvr->next = rcvrs;
			rcvrs = rcvr;
L
Linus Torvalds 已提交
1235 1236
		}
	}
1237
	mutex_unlock(&intf->cmd_rcvrs_mutex);
1238 1239 1240 1241 1242 1243
	synchronize_rcu();
	while (rcvrs) {
		rcvr = rcvrs;
		rcvrs = rcvr->next;
		kfree(rcvr);
	}
L
Linus Torvalds 已提交
1244

1245 1246 1247 1248 1249 1250 1251
	mutex_lock(&ipmi_interfaces_mutex);
	if (intf->handlers) {
		module_put(intf->handlers->owner);
		if (intf->handlers->dec_usecount)
			intf->handlers->dec_usecount(intf->send_info);
	}
	mutex_unlock(&ipmi_interfaces_mutex);
L
Linus Torvalds 已提交
1252

1253
	kref_put(&intf->refcount, intf_free);
L
Linus Torvalds 已提交
1254

1255
	kref_put(&user->refcount, free_user);
L
Linus Torvalds 已提交
1256

1257
	return 0;
L
Linus Torvalds 已提交
1258
}
1259
EXPORT_SYMBOL(ipmi_destroy_user);
L
Linus Torvalds 已提交
1260

1261 1262 1263
int ipmi_get_version(ipmi_user_t   user,
		     unsigned char *major,
		     unsigned char *minor)
L
Linus Torvalds 已提交
1264
{
1265 1266 1267
	struct ipmi_device_id id;
	int rv;

1268
	rv = bmc_get_device_id(user->intf, NULL, &id, NULL, NULL);
1269 1270 1271 1272 1273 1274 1275
	if (rv)
		return rv;

	*major = ipmi_version_major(&id);
	*minor = ipmi_version_minor(&id);

	return 0;
L
Linus Torvalds 已提交
1276
}
1277
EXPORT_SYMBOL(ipmi_get_version);
L
Linus Torvalds 已提交
1278

1279 1280 1281
int ipmi_set_my_address(ipmi_user_t   user,
			unsigned int  channel,
			unsigned char address)
L
Linus Torvalds 已提交
1282
{
1283 1284
	if (channel >= IPMI_MAX_CHANNELS)
		return -EINVAL;
1285
	user->intf->addrinfo[channel].address = address;
1286
	return 0;
L
Linus Torvalds 已提交
1287
}
1288
EXPORT_SYMBOL(ipmi_set_my_address);
L
Linus Torvalds 已提交
1289

1290 1291 1292
int ipmi_get_my_address(ipmi_user_t   user,
			unsigned int  channel,
			unsigned char *address)
L
Linus Torvalds 已提交
1293
{
1294 1295
	if (channel >= IPMI_MAX_CHANNELS)
		return -EINVAL;
1296
	*address = user->intf->addrinfo[channel].address;
1297
	return 0;
L
Linus Torvalds 已提交
1298
}
1299
EXPORT_SYMBOL(ipmi_get_my_address);
L
Linus Torvalds 已提交
1300

1301 1302 1303
int ipmi_set_my_LUN(ipmi_user_t   user,
		    unsigned int  channel,
		    unsigned char LUN)
L
Linus Torvalds 已提交
1304
{
1305 1306
	if (channel >= IPMI_MAX_CHANNELS)
		return -EINVAL;
1307
	user->intf->addrinfo[channel].lun = LUN & 0x3;
1308
	return 0;
L
Linus Torvalds 已提交
1309
}
1310
EXPORT_SYMBOL(ipmi_set_my_LUN);
L
Linus Torvalds 已提交
1311

1312 1313 1314
int ipmi_get_my_LUN(ipmi_user_t   user,
		    unsigned int  channel,
		    unsigned char *address)
L
Linus Torvalds 已提交
1315
{
1316 1317
	if (channel >= IPMI_MAX_CHANNELS)
		return -EINVAL;
1318
	*address = user->intf->addrinfo[channel].lun;
1319
	return 0;
L
Linus Torvalds 已提交
1320
}
1321
EXPORT_SYMBOL(ipmi_get_my_LUN);
L
Linus Torvalds 已提交
1322

C
Corey Minyard 已提交
1323 1324 1325 1326 1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357
int ipmi_get_maintenance_mode(ipmi_user_t user)
{
	int           mode;
	unsigned long flags;

	spin_lock_irqsave(&user->intf->maintenance_mode_lock, flags);
	mode = user->intf->maintenance_mode;
	spin_unlock_irqrestore(&user->intf->maintenance_mode_lock, flags);

	return mode;
}
EXPORT_SYMBOL(ipmi_get_maintenance_mode);

static void maintenance_mode_update(ipmi_smi_t intf)
{
	if (intf->handlers->set_maintenance_mode)
		intf->handlers->set_maintenance_mode(
			intf->send_info, intf->maintenance_mode_enable);
}

int ipmi_set_maintenance_mode(ipmi_user_t user, int mode)
{
	int           rv = 0;
	unsigned long flags;
	ipmi_smi_t    intf = user->intf;

	spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
	if (intf->maintenance_mode != mode) {
		switch (mode) {
		case IPMI_MAINTENANCE_MODE_AUTO:
			intf->maintenance_mode_enable
				= (intf->auto_maintenance_timeout > 0);
			break;

		case IPMI_MAINTENANCE_MODE_OFF:
C
Corey Minyard 已提交
1358
			intf->maintenance_mode_enable = false;
C
Corey Minyard 已提交
1359 1360 1361
			break;

		case IPMI_MAINTENANCE_MODE_ON:
C
Corey Minyard 已提交
1362
			intf->maintenance_mode_enable = true;
C
Corey Minyard 已提交
1363 1364 1365 1366 1367 1368
			break;

		default:
			rv = -EINVAL;
			goto out_unlock;
		}
C
Corey Minyard 已提交
1369
		intf->maintenance_mode = mode;
C
Corey Minyard 已提交
1370 1371 1372 1373 1374 1375 1376 1377 1378 1379

		maintenance_mode_update(intf);
	}
 out_unlock:
	spin_unlock_irqrestore(&intf->maintenance_mode_lock, flags);

	return rv;
}
EXPORT_SYMBOL(ipmi_set_maintenance_mode);

1380
int ipmi_set_gets_events(ipmi_user_t user, bool val)
L
Linus Torvalds 已提交
1381
{
1382 1383 1384 1385
	unsigned long        flags;
	ipmi_smi_t           intf = user->intf;
	struct ipmi_recv_msg *msg, *msg2;
	struct list_head     msgs;
L
Linus Torvalds 已提交
1386

1387 1388 1389
	INIT_LIST_HEAD(&msgs);

	spin_lock_irqsave(&intf->events_lock, flags);
1390 1391 1392
	if (user->gets_events == val)
		goto out;

L
Linus Torvalds 已提交
1393 1394
	user->gets_events = val;

1395 1396 1397 1398 1399 1400 1401
	if (val) {
		if (atomic_inc_return(&intf->event_waiters) == 1)
			need_waiter(intf);
	} else {
		atomic_dec(&intf->event_waiters);
	}

1402 1403 1404 1405 1406 1407 1408 1409 1410
	if (intf->delivering_events)
		/*
		 * Another thread is delivering events for this, so
		 * let it handle any new events.
		 */
		goto out;

	/* Deliver any queued events. */
	while (user->gets_events && !list_empty(&intf->waiting_events)) {
A
Akinobu Mita 已提交
1411 1412
		list_for_each_entry_safe(msg, msg2, &intf->waiting_events, link)
			list_move_tail(&msg->link, &msgs);
1413
		intf->waiting_events_count = 0;
1414
		if (intf->event_msg_printed) {
1415 1416
			dev_warn(intf->si_dev,
				 PFX "Event queue no longer full\n");
1417 1418
			intf->event_msg_printed = 0;
		}
1419

1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430
		intf->delivering_events = 1;
		spin_unlock_irqrestore(&intf->events_lock, flags);

		list_for_each_entry_safe(msg, msg2, &msgs, link) {
			msg->user = user;
			kref_get(&user->refcount);
			deliver_response(msg);
		}

		spin_lock_irqsave(&intf->events_lock, flags);
		intf->delivering_events = 0;
1431 1432
	}

1433
 out:
1434
	spin_unlock_irqrestore(&intf->events_lock, flags);
L
Linus Torvalds 已提交
1435 1436 1437

	return 0;
}
1438
EXPORT_SYMBOL(ipmi_set_gets_events);
L
Linus Torvalds 已提交
1439

1440 1441
static struct cmd_rcvr *find_cmd_rcvr(ipmi_smi_t    intf,
				      unsigned char netfn,
1442 1443
				      unsigned char cmd,
				      unsigned char chan)
1444 1445 1446 1447
{
	struct cmd_rcvr *rcvr;

	list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
1448 1449
		if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)
					&& (rcvr->chans & (1 << chan)))
1450 1451 1452 1453 1454
			return rcvr;
	}
	return NULL;
}

1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469
static int is_cmd_rcvr_exclusive(ipmi_smi_t    intf,
				 unsigned char netfn,
				 unsigned char cmd,
				 unsigned int  chans)
{
	struct cmd_rcvr *rcvr;

	list_for_each_entry_rcu(rcvr, &intf->cmd_rcvrs, link) {
		if ((rcvr->netfn == netfn) && (rcvr->cmd == cmd)
					&& (rcvr->chans & chans))
			return 0;
	}
	return 1;
}

L
Linus Torvalds 已提交
1470 1471
int ipmi_register_for_cmd(ipmi_user_t   user,
			  unsigned char netfn,
1472 1473
			  unsigned char cmd,
			  unsigned int  chans)
L
Linus Torvalds 已提交
1474
{
1475 1476 1477
	ipmi_smi_t      intf = user->intf;
	struct cmd_rcvr *rcvr;
	int             rv = 0;
L
Linus Torvalds 已提交
1478 1479 1480


	rcvr = kmalloc(sizeof(*rcvr), GFP_KERNEL);
1481
	if (!rcvr)
L
Linus Torvalds 已提交
1482
		return -ENOMEM;
1483 1484
	rcvr->cmd = cmd;
	rcvr->netfn = netfn;
1485
	rcvr->chans = chans;
1486
	rcvr->user = user;
L
Linus Torvalds 已提交
1487

1488
	mutex_lock(&intf->cmd_rcvrs_mutex);
L
Linus Torvalds 已提交
1489
	/* Make sure the command/netfn is not already registered. */
1490
	if (!is_cmd_rcvr_exclusive(intf, netfn, cmd, chans)) {
1491 1492
		rv = -EBUSY;
		goto out_unlock;
L
Linus Torvalds 已提交
1493
	}
1494

1495 1496 1497
	if (atomic_inc_return(&intf->event_waiters) == 1)
		need_waiter(intf);

1498
	list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
L
Linus Torvalds 已提交
1499

1500
 out_unlock:
1501
	mutex_unlock(&intf->cmd_rcvrs_mutex);
L
Linus Torvalds 已提交
1502 1503 1504 1505 1506
	if (rv)
		kfree(rcvr);

	return rv;
}
1507
EXPORT_SYMBOL(ipmi_register_for_cmd);
L
Linus Torvalds 已提交
1508 1509 1510

int ipmi_unregister_for_cmd(ipmi_user_t   user,
			    unsigned char netfn,
1511 1512
			    unsigned char cmd,
			    unsigned int  chans)
L
Linus Torvalds 已提交
1513
{
1514 1515
	ipmi_smi_t      intf = user->intf;
	struct cmd_rcvr *rcvr;
1516 1517
	struct cmd_rcvr *rcvrs = NULL;
	int i, rv = -ENOENT;
L
Linus Torvalds 已提交
1518

1519
	mutex_lock(&intf->cmd_rcvrs_mutex);
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538
	for (i = 0; i < IPMI_NUM_CHANNELS; i++) {
		if (((1 << i) & chans) == 0)
			continue;
		rcvr = find_cmd_rcvr(intf, netfn, cmd, i);
		if (rcvr == NULL)
			continue;
		if (rcvr->user == user) {
			rv = 0;
			rcvr->chans &= ~chans;
			if (rcvr->chans == 0) {
				list_del_rcu(&rcvr->link);
				rcvr->next = rcvrs;
				rcvrs = rcvr;
			}
		}
	}
	mutex_unlock(&intf->cmd_rcvrs_mutex);
	synchronize_rcu();
	while (rcvrs) {
1539
		atomic_dec(&intf->event_waiters);
1540 1541
		rcvr = rcvrs;
		rcvrs = rcvr->next;
1542
		kfree(rcvr);
L
Linus Torvalds 已提交
1543
	}
1544
	return rv;
L
Linus Torvalds 已提交
1545
}
1546
EXPORT_SYMBOL(ipmi_unregister_for_cmd);
L
Linus Torvalds 已提交
1547 1548 1549 1550 1551

static unsigned char
ipmb_checksum(unsigned char *data, int size)
{
	unsigned char csum = 0;
1552

L
Linus Torvalds 已提交
1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593
	for (; size > 0; size--, data++)
		csum += *data;

	return -csum;
}

static inline void format_ipmb_msg(struct ipmi_smi_msg   *smi_msg,
				   struct kernel_ipmi_msg *msg,
				   struct ipmi_ipmb_addr *ipmb_addr,
				   long                  msgid,
				   unsigned char         ipmb_seq,
				   int                   broadcast,
				   unsigned char         source_address,
				   unsigned char         source_lun)
{
	int i = broadcast;

	/* Format the IPMB header data. */
	smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
	smi_msg->data[1] = IPMI_SEND_MSG_CMD;
	smi_msg->data[2] = ipmb_addr->channel;
	if (broadcast)
		smi_msg->data[3] = 0;
	smi_msg->data[i+3] = ipmb_addr->slave_addr;
	smi_msg->data[i+4] = (msg->netfn << 2) | (ipmb_addr->lun & 0x3);
	smi_msg->data[i+5] = ipmb_checksum(&(smi_msg->data[i+3]), 2);
	smi_msg->data[i+6] = source_address;
	smi_msg->data[i+7] = (ipmb_seq << 2) | source_lun;
	smi_msg->data[i+8] = msg->cmd;

	/* Now tack on the data to the message. */
	if (msg->data_len > 0)
		memcpy(&(smi_msg->data[i+9]), msg->data,
		       msg->data_len);
	smi_msg->data_size = msg->data_len + 9;

	/* Now calculate the checksum and tack it on. */
	smi_msg->data[i+smi_msg->data_size]
		= ipmb_checksum(&(smi_msg->data[i+6]),
				smi_msg->data_size-6);

1594 1595 1596 1597
	/*
	 * Add on the checksum size and the offset from the
	 * broadcast.
	 */
L
Linus Torvalds 已提交
1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632
	smi_msg->data_size += 1 + i;

	smi_msg->msgid = msgid;
}

static inline void format_lan_msg(struct ipmi_smi_msg   *smi_msg,
				  struct kernel_ipmi_msg *msg,
				  struct ipmi_lan_addr  *lan_addr,
				  long                  msgid,
				  unsigned char         ipmb_seq,
				  unsigned char         source_lun)
{
	/* Format the IPMB header data. */
	smi_msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
	smi_msg->data[1] = IPMI_SEND_MSG_CMD;
	smi_msg->data[2] = lan_addr->channel;
	smi_msg->data[3] = lan_addr->session_handle;
	smi_msg->data[4] = lan_addr->remote_SWID;
	smi_msg->data[5] = (msg->netfn << 2) | (lan_addr->lun & 0x3);
	smi_msg->data[6] = ipmb_checksum(&(smi_msg->data[4]), 2);
	smi_msg->data[7] = lan_addr->local_SWID;
	smi_msg->data[8] = (ipmb_seq << 2) | source_lun;
	smi_msg->data[9] = msg->cmd;

	/* Now tack on the data to the message. */
	if (msg->data_len > 0)
		memcpy(&(smi_msg->data[10]), msg->data,
		       msg->data_len);
	smi_msg->data_size = msg->data_len + 10;

	/* Now calculate the checksum and tack it on. */
	smi_msg->data[smi_msg->data_size]
		= ipmb_checksum(&(smi_msg->data[7]),
				smi_msg->data_size-7);

1633 1634 1635 1636
	/*
	 * Add on the checksum size and the offset from the
	 * broadcast.
	 */
L
Linus Torvalds 已提交
1637 1638 1639 1640 1641
	smi_msg->data_size += 1;

	smi_msg->msgid = msgid;
}

A
Arnd Bergmann 已提交
1642 1643 1644
static struct ipmi_smi_msg *smi_add_send_msg(ipmi_smi_t intf,
					     struct ipmi_smi_msg *smi_msg,
					     int priority)
1645
{
1646 1647 1648 1649 1650 1651 1652 1653 1654
	if (intf->curr_msg) {
		if (priority > 0)
			list_add_tail(&smi_msg->link, &intf->hp_xmit_msgs);
		else
			list_add_tail(&smi_msg->link, &intf->xmit_msgs);
		smi_msg = NULL;
	} else {
		intf->curr_msg = smi_msg;
	}
A
Arnd Bergmann 已提交
1655 1656 1657 1658 1659

	return smi_msg;
}


1660
static void smi_send(ipmi_smi_t intf, const struct ipmi_smi_handlers *handlers,
A
Arnd Bergmann 已提交
1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671
		     struct ipmi_smi_msg *smi_msg, int priority)
{
	int run_to_completion = intf->run_to_completion;

	if (run_to_completion) {
		smi_msg = smi_add_send_msg(intf, smi_msg, priority);
	} else {
		unsigned long flags;

		spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
		smi_msg = smi_add_send_msg(intf, smi_msg, priority);
1672
		spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
A
Arnd Bergmann 已提交
1673
	}
1674 1675

	if (smi_msg)
1676
		handlers->sender(intf->send_info, smi_msg);
1677 1678
}

1679 1680 1681 1682 1683 1684 1685 1686
static bool is_maintenance_mode_cmd(struct kernel_ipmi_msg *msg)
{
	return (((msg->netfn == IPMI_NETFN_APP_REQUEST)
		 && ((msg->cmd == IPMI_COLD_RESET_CMD)
		     || (msg->cmd == IPMI_WARM_RESET_CMD)))
		|| (msg->netfn == IPMI_NETFN_FIRMWARE_REQUEST));
}

1687 1688 1689 1690 1691 1692
/*
 * Separate from ipmi_request so that the user does not have to be
 * supplied in certain circumstances (mainly at panic time).  If
 * messages are supplied, they will be freed, even if an error
 * occurs.
 */
1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705
static int i_ipmi_request(ipmi_user_t          user,
			  ipmi_smi_t           intf,
			  struct ipmi_addr     *addr,
			  long                 msgid,
			  struct kernel_ipmi_msg *msg,
			  void                 *user_msg_data,
			  void                 *supplied_smi,
			  struct ipmi_recv_msg *supplied_recv,
			  int                  priority,
			  unsigned char        source_address,
			  unsigned char        source_lun,
			  int                  retries,
			  unsigned int         retry_time_ms)
L
Linus Torvalds 已提交
1706
{
1707 1708 1709 1710
	int                      rv = 0;
	struct ipmi_smi_msg      *smi_msg;
	struct ipmi_recv_msg     *recv_msg;
	unsigned long            flags;
L
Linus Torvalds 已提交
1711 1712


1713
	if (supplied_recv)
L
Linus Torvalds 已提交
1714
		recv_msg = supplied_recv;
1715
	else {
L
Linus Torvalds 已提交
1716
		recv_msg = ipmi_alloc_recv_msg();
1717
		if (recv_msg == NULL)
L
Linus Torvalds 已提交
1718 1719 1720 1721
			return -ENOMEM;
	}
	recv_msg->user_msg_data = user_msg_data;

1722
	if (supplied_smi)
L
Linus Torvalds 已提交
1723
		smi_msg = (struct ipmi_smi_msg *) supplied_smi;
1724
	else {
L
Linus Torvalds 已提交
1725 1726 1727 1728 1729 1730 1731
		smi_msg = ipmi_alloc_smi_msg();
		if (smi_msg == NULL) {
			ipmi_free_recv_msg(recv_msg);
			return -ENOMEM;
		}
	}

1732
	rcu_read_lock();
1733
	if (intf->in_shutdown) {
1734 1735 1736 1737
		rv = -ENODEV;
		goto out_err;
	}

L
Linus Torvalds 已提交
1738
	recv_msg->user = user;
1739 1740
	if (user)
		kref_get(&user->refcount);
L
Linus Torvalds 已提交
1741
	recv_msg->msgid = msgid;
1742 1743 1744 1745
	/*
	 * Store the message to send in the receive message so timeout
	 * responses can get the proper response data.
	 */
L
Linus Torvalds 已提交
1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758
	recv_msg->msg = *msg;

	if (addr->addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE) {
		struct ipmi_system_interface_addr *smi_addr;

		if (msg->netfn & 1) {
			/* Responses are not allowed to the SMI. */
			rv = -EINVAL;
			goto out_err;
		}

		smi_addr = (struct ipmi_system_interface_addr *) addr;
		if (smi_addr->lun > 3) {
1759
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1760 1761 1762 1763 1764 1765 1766 1767 1768
			rv = -EINVAL;
			goto out_err;
		}

		memcpy(&recv_msg->addr, smi_addr, sizeof(*smi_addr));

		if ((msg->netfn == IPMI_NETFN_APP_REQUEST)
		    && ((msg->cmd == IPMI_SEND_MSG_CMD)
			|| (msg->cmd == IPMI_GET_MSG_CMD)
1769 1770 1771 1772 1773
			|| (msg->cmd == IPMI_READ_EVENT_MSG_BUFFER_CMD))) {
			/*
			 * We don't let the user do these, since we manage
			 * the sequence numbers.
			 */
1774
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1775 1776 1777 1778
			rv = -EINVAL;
			goto out_err;
		}

1779
		if (is_maintenance_mode_cmd(msg)) {
C
Corey Minyard 已提交
1780 1781
			spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
			intf->auto_maintenance_timeout
1782
				= maintenance_mode_timeout_ms;
C
Corey Minyard 已提交
1783
			if (!intf->maintenance_mode
1784
			    && !intf->maintenance_mode_enable) {
C
Corey Minyard 已提交
1785
				intf->maintenance_mode_enable = true;
C
Corey Minyard 已提交
1786 1787 1788 1789 1790 1791
				maintenance_mode_update(intf);
			}
			spin_unlock_irqrestore(&intf->maintenance_mode_lock,
					       flags);
		}

L
Linus Torvalds 已提交
1792
		if ((msg->data_len + 2) > IPMI_MAX_MSG_LENGTH) {
1793
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804
			rv = -EMSGSIZE;
			goto out_err;
		}

		smi_msg->data[0] = (msg->netfn << 2) | (smi_addr->lun & 0x3);
		smi_msg->data[1] = msg->cmd;
		smi_msg->msgid = msgid;
		smi_msg->user_data = recv_msg;
		if (msg->data_len > 0)
			memcpy(&(smi_msg->data[2]), msg->data, msg->data_len);
		smi_msg->data_size = msg->data_len + 2;
1805
		ipmi_inc_stat(intf, sent_local_commands);
1806
	} else if (is_ipmb_addr(addr) || is_ipmb_bcast_addr(addr)) {
L
Linus Torvalds 已提交
1807 1808 1809 1810
		struct ipmi_ipmb_addr *ipmb_addr;
		unsigned char         ipmb_seq;
		long                  seqid;
		int                   broadcast = 0;
1811
		struct ipmi_channel   *chans;
L
Linus Torvalds 已提交
1812

1813
		if (addr->channel >= IPMI_MAX_CHANNELS) {
1814
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1815 1816 1817 1818
			rv = -EINVAL;
			goto out_err;
		}

1819 1820 1821
		chans = READ_ONCE(intf->channel_list)->c;

		if (chans[addr->channel].medium != IPMI_CHANNEL_MEDIUM_IPMB) {
1822
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1823 1824 1825 1826 1827
			rv = -EINVAL;
			goto out_err;
		}

		if (addr->addr_type == IPMI_IPMB_BROADCAST_ADDR_TYPE) {
1828 1829 1830 1831 1832 1833 1834 1835
			/*
			 * Broadcasts add a zero at the beginning of the
			 * message, but otherwise is the same as an IPMB
			 * address.
			 */
			addr->addr_type = IPMI_IPMB_ADDR_TYPE;
			broadcast = 1;
			retries = 0; /* Don't retry broadcasts. */
L
Linus Torvalds 已提交
1836 1837
		}

1838 1839 1840 1841
		/*
		 * 9 for the header and 1 for the checksum, plus
		 * possibly one for the broadcast.
		 */
L
Linus Torvalds 已提交
1842
		if ((msg->data_len + 10 + broadcast) > IPMI_MAX_MSG_LENGTH) {
1843
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1844 1845 1846 1847 1848 1849
			rv = -EMSGSIZE;
			goto out_err;
		}

		ipmb_addr = (struct ipmi_ipmb_addr *) addr;
		if (ipmb_addr->lun > 3) {
1850
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1851 1852 1853 1854 1855 1856 1857
			rv = -EINVAL;
			goto out_err;
		}

		memcpy(&recv_msg->addr, ipmb_addr, sizeof(*ipmb_addr));

		if (recv_msg->msg.netfn & 0x1) {
1858 1859 1860 1861
			/*
			 * It's a response, so use the user's sequence
			 * from msgid.
			 */
1862
			ipmi_inc_stat(intf, sent_ipmb_responses);
L
Linus Torvalds 已提交
1863 1864 1865 1866
			format_ipmb_msg(smi_msg, msg, ipmb_addr, msgid,
					msgid, broadcast,
					source_address, source_lun);

1867 1868 1869 1870
			/*
			 * Save the receive message so we can use it
			 * to deliver the response.
			 */
L
Linus Torvalds 已提交
1871 1872 1873 1874 1875 1876
			smi_msg->user_data = recv_msg;
		} else {
			/* It's a command, so get a sequence for it. */

			spin_lock_irqsave(&(intf->seq_lock), flags);

1877 1878 1879 1880 1881 1882 1883 1884 1885
			if (is_maintenance_mode_cmd(msg))
				intf->ipmb_maintenance_mode_timeout =
					maintenance_mode_timeout_ms;

			if (intf->ipmb_maintenance_mode_timeout &&
			    retry_time_ms == 0)
				/* Different default in maintenance mode */
				retry_time_ms = default_maintenance_retry_ms;

1886 1887 1888 1889
			/*
			 * Create a sequence number with a 1 second
			 * timeout and 4 retries.
			 */
L
Linus Torvalds 已提交
1890 1891 1892 1893 1894 1895 1896 1897
			rv = intf_next_seq(intf,
					   recv_msg,
					   retry_time_ms,
					   retries,
					   broadcast,
					   &ipmb_seq,
					   &seqid);
			if (rv) {
1898 1899 1900 1901
				/*
				 * We have used up all the sequence numbers,
				 * probably, so abort.
				 */
L
Linus Torvalds 已提交
1902 1903 1904 1905 1906
				spin_unlock_irqrestore(&(intf->seq_lock),
						       flags);
				goto out_err;
			}

1907 1908
			ipmi_inc_stat(intf, sent_ipmb_commands);

1909 1910 1911 1912 1913
			/*
			 * Store the sequence number in the message,
			 * so that when the send message response
			 * comes back we can start the timer.
			 */
L
Linus Torvalds 已提交
1914 1915 1916 1917 1918
			format_ipmb_msg(smi_msg, msg, ipmb_addr,
					STORE_SEQ_IN_MSGID(ipmb_seq, seqid),
					ipmb_seq, broadcast,
					source_address, source_lun);

1919 1920 1921 1922
			/*
			 * Copy the message into the recv message data, so we
			 * can retransmit it later if necessary.
			 */
L
Linus Torvalds 已提交
1923 1924 1925 1926 1927
			memcpy(recv_msg->msg_data, smi_msg->data,
			       smi_msg->data_size);
			recv_msg->msg.data = recv_msg->msg_data;
			recv_msg->msg.data_len = smi_msg->data_size;

1928 1929 1930 1931 1932 1933 1934 1935
			/*
			 * We don't unlock until here, because we need
			 * to copy the completed message into the
			 * recv_msg before we release the lock.
			 * Otherwise, race conditions may bite us.  I
			 * know that's pretty paranoid, but I prefer
			 * to be correct.
			 */
L
Linus Torvalds 已提交
1936 1937
			spin_unlock_irqrestore(&(intf->seq_lock), flags);
		}
1938
	} else if (is_lan_addr(addr)) {
L
Linus Torvalds 已提交
1939 1940 1941
		struct ipmi_lan_addr  *lan_addr;
		unsigned char         ipmb_seq;
		long                  seqid;
1942
		struct ipmi_channel   *chans;
L
Linus Torvalds 已提交
1943

1944
		if (addr->channel >= IPMI_MAX_CHANNELS) {
1945
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1946 1947 1948 1949
			rv = -EINVAL;
			goto out_err;
		}

1950 1951 1952
		chans = READ_ONCE(intf->channel_list)->c;

		if ((chans[addr->channel].medium
1953
				!= IPMI_CHANNEL_MEDIUM_8023LAN)
1954
		    && (chans[addr->channel].medium
1955
				!= IPMI_CHANNEL_MEDIUM_ASYNC)) {
1956
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1957 1958 1959 1960 1961 1962
			rv = -EINVAL;
			goto out_err;
		}

		/* 11 for the header and 1 for the checksum. */
		if ((msg->data_len + 12) > IPMI_MAX_MSG_LENGTH) {
1963
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1964 1965 1966 1967 1968 1969
			rv = -EMSGSIZE;
			goto out_err;
		}

		lan_addr = (struct ipmi_lan_addr *) addr;
		if (lan_addr->lun > 3) {
1970
			ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
1971 1972 1973 1974 1975 1976 1977
			rv = -EINVAL;
			goto out_err;
		}

		memcpy(&recv_msg->addr, lan_addr, sizeof(*lan_addr));

		if (recv_msg->msg.netfn & 0x1) {
1978 1979 1980 1981
			/*
			 * It's a response, so use the user's sequence
			 * from msgid.
			 */
1982
			ipmi_inc_stat(intf, sent_lan_responses);
L
Linus Torvalds 已提交
1983 1984 1985
			format_lan_msg(smi_msg, msg, lan_addr, msgid,
				       msgid, source_lun);

1986 1987 1988 1989
			/*
			 * Save the receive message so we can use it
			 * to deliver the response.
			 */
L
Linus Torvalds 已提交
1990 1991 1992 1993 1994 1995
			smi_msg->user_data = recv_msg;
		} else {
			/* It's a command, so get a sequence for it. */

			spin_lock_irqsave(&(intf->seq_lock), flags);

1996 1997 1998 1999
			/*
			 * Create a sequence number with a 1 second
			 * timeout and 4 retries.
			 */
L
Linus Torvalds 已提交
2000 2001 2002 2003 2004 2005 2006 2007
			rv = intf_next_seq(intf,
					   recv_msg,
					   retry_time_ms,
					   retries,
					   0,
					   &ipmb_seq,
					   &seqid);
			if (rv) {
2008 2009 2010 2011
				/*
				 * We have used up all the sequence numbers,
				 * probably, so abort.
				 */
L
Linus Torvalds 已提交
2012 2013 2014 2015 2016
				spin_unlock_irqrestore(&(intf->seq_lock),
						       flags);
				goto out_err;
			}

2017 2018
			ipmi_inc_stat(intf, sent_lan_commands);

2019 2020 2021 2022 2023
			/*
			 * Store the sequence number in the message,
			 * so that when the send message response
			 * comes back we can start the timer.
			 */
L
Linus Torvalds 已提交
2024 2025 2026 2027
			format_lan_msg(smi_msg, msg, lan_addr,
				       STORE_SEQ_IN_MSGID(ipmb_seq, seqid),
				       ipmb_seq, source_lun);

2028 2029 2030 2031
			/*
			 * Copy the message into the recv message data, so we
			 * can retransmit it later if necessary.
			 */
L
Linus Torvalds 已提交
2032 2033 2034 2035 2036
			memcpy(recv_msg->msg_data, smi_msg->data,
			       smi_msg->data_size);
			recv_msg->msg.data = recv_msg->msg_data;
			recv_msg->msg.data_len = smi_msg->data_size;

2037 2038 2039 2040 2041 2042 2043 2044
			/*
			 * We don't unlock until here, because we need
			 * to copy the completed message into the
			 * recv_msg before we release the lock.
			 * Otherwise, race conditions may bite us.  I
			 * know that's pretty paranoid, but I prefer
			 * to be correct.
			 */
L
Linus Torvalds 已提交
2045 2046 2047 2048
			spin_unlock_irqrestore(&(intf->seq_lock), flags);
		}
	} else {
	    /* Unknown address type. */
2049
		ipmi_inc_stat(intf, sent_invalid_commands);
L
Linus Torvalds 已提交
2050 2051 2052 2053 2054 2055 2056
		rv = -EINVAL;
		goto out_err;
	}

#ifdef DEBUG_MSGING
	{
		int m;
C
Corey Minyard 已提交
2057
		for (m = 0; m < smi_msg->data_size; m++)
L
Linus Torvalds 已提交
2058 2059 2060 2061
			printk(" %2.2x", smi_msg->data[m]);
		printk("\n");
	}
#endif
2062

2063
	smi_send(intf, intf->handlers, smi_msg, priority);
2064
	rcu_read_unlock();
L
Linus Torvalds 已提交
2065 2066 2067 2068

	return 0;

 out_err:
2069
	rcu_read_unlock();
L
Linus Torvalds 已提交
2070 2071 2072 2073 2074
	ipmi_free_smi_msg(smi_msg);
	ipmi_free_recv_msg(recv_msg);
	return rv;
}

2075 2076 2077 2078 2079 2080 2081
static int check_addr(ipmi_smi_t       intf,
		      struct ipmi_addr *addr,
		      unsigned char    *saddr,
		      unsigned char    *lun)
{
	if (addr->channel >= IPMI_MAX_CHANNELS)
		return -EINVAL;
2082 2083
	*lun = intf->addrinfo[addr->channel].lun;
	*saddr = intf->addrinfo[addr->channel].address;
2084 2085 2086
	return 0;
}

L
Linus Torvalds 已提交
2087 2088 2089 2090 2091 2092 2093 2094 2095
int ipmi_request_settime(ipmi_user_t      user,
			 struct ipmi_addr *addr,
			 long             msgid,
			 struct kernel_ipmi_msg  *msg,
			 void             *user_msg_data,
			 int              priority,
			 int              retries,
			 unsigned int     retry_time_ms)
{
2096
	unsigned char saddr = 0, lun = 0;
2097 2098
	int           rv;

2099
	if (!user)
2100
		return -EINVAL;
2101 2102 2103
	rv = check_addr(user->intf, addr, &saddr, &lun);
	if (rv)
		return rv;
L
Linus Torvalds 已提交
2104 2105 2106 2107 2108 2109 2110 2111
	return i_ipmi_request(user,
			      user->intf,
			      addr,
			      msgid,
			      msg,
			      user_msg_data,
			      NULL, NULL,
			      priority,
2112 2113
			      saddr,
			      lun,
L
Linus Torvalds 已提交
2114 2115 2116
			      retries,
			      retry_time_ms);
}
2117
EXPORT_SYMBOL(ipmi_request_settime);
L
Linus Torvalds 已提交
2118 2119 2120 2121 2122 2123 2124 2125 2126 2127

int ipmi_request_supply_msgs(ipmi_user_t          user,
			     struct ipmi_addr     *addr,
			     long                 msgid,
			     struct kernel_ipmi_msg *msg,
			     void                 *user_msg_data,
			     void                 *supplied_smi,
			     struct ipmi_recv_msg *supplied_recv,
			     int                  priority)
{
2128
	unsigned char saddr = 0, lun = 0;
2129 2130
	int           rv;

2131
	if (!user)
2132
		return -EINVAL;
2133 2134 2135
	rv = check_addr(user->intf, addr, &saddr, &lun);
	if (rv)
		return rv;
L
Linus Torvalds 已提交
2136 2137 2138 2139 2140 2141 2142 2143 2144
	return i_ipmi_request(user,
			      user->intf,
			      addr,
			      msgid,
			      msg,
			      user_msg_data,
			      supplied_smi,
			      supplied_recv,
			      priority,
2145 2146
			      saddr,
			      lun,
L
Linus Torvalds 已提交
2147 2148
			      -1, 0);
}
2149
EXPORT_SYMBOL(ipmi_request_supply_msgs);
L
Linus Torvalds 已提交
2150

2151 2152 2153 2154 2155 2156 2157
static void bmc_device_id_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
{
	int rv;

	if ((msg->addr.addr_type != IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
			|| (msg->msg.netfn != IPMI_NETFN_APP_RESPONSE)
			|| (msg->msg.cmd != IPMI_GET_DEVICE_ID_CMD)) {
2158 2159
		dev_warn(intf->si_dev,
			 PFX "invalid device_id msg: addr_type=%d netfn=%x cmd=%x\n",
2160 2161 2162 2163 2164 2165 2166
			msg->addr.addr_type, msg->msg.netfn, msg->msg.cmd);
		return;
	}

	rv = ipmi_demangle_device_id(msg->msg.netfn, msg->msg.cmd,
			msg->msg.data, msg->msg.data_len, &intf->bmc->fetch_id);
	if (rv) {
2167 2168
		dev_warn(intf->si_dev,
			 PFX "device id demangle failed: %d\n", rv);
2169 2170 2171 2172 2173 2174 2175 2176 2177 2178 2179 2180 2181 2182 2183 2184 2185 2186 2187 2188 2189 2190 2191 2192 2193 2194 2195 2196 2197 2198 2199 2200 2201 2202 2203 2204 2205
		intf->bmc->dyn_id_set = 0;
	} else {
		/*
		 * Make sure the id data is available before setting
		 * dyn_id_set.
		 */
		smp_wmb();
		intf->bmc->dyn_id_set = 1;
	}

	wake_up(&intf->waitq);
}

static int
send_get_device_id_cmd(ipmi_smi_t intf)
{
	struct ipmi_system_interface_addr si;
	struct kernel_ipmi_msg msg;

	si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	si.channel = IPMI_BMC_CHANNEL;
	si.lun = 0;

	msg.netfn = IPMI_NETFN_APP_REQUEST;
	msg.cmd = IPMI_GET_DEVICE_ID_CMD;
	msg.data = NULL;
	msg.data_len = 0;

	return i_ipmi_request(NULL,
			      intf,
			      (struct ipmi_addr *) &si,
			      0,
			      &msg,
			      intf,
			      NULL,
			      NULL,
			      0,
2206 2207
			      intf->addrinfo[0].address,
			      intf->addrinfo[0].lun,
2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 2231 2232 2233 2234 2235 2236 2237 2238 2239 2240 2241 2242 2243 2244
			      -1, 0);
}

static int __get_device_id(ipmi_smi_t intf, struct bmc_device *bmc)
{
	int rv;

	bmc->dyn_id_set = 2;

	intf->null_user_handler = bmc_device_id_handler;

	rv = send_get_device_id_cmd(intf);
	if (rv)
		return rv;

	wait_event(intf->waitq, bmc->dyn_id_set != 2);

	if (!bmc->dyn_id_set)
		rv = -EIO; /* Something went wrong in the fetch. */

	/* dyn_id_set makes the id data available. */
	smp_rmb();

	intf->null_user_handler = NULL;

	return rv;
}

/*
 * Fetch the device id for the bmc/interface.  You must pass in either
 * bmc or intf, this code will get the other one.  If the data has
 * been recently fetched, this will just use the cached data.  Otherwise
 * it will run a new fetch.
 *
 * Except for the first time this is called (in ipmi_register_smi()),
 * this will always return good data;
 */
2245 2246
static int __bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
			       struct ipmi_device_id *id,
2247
			       bool *guid_set, guid_t *guid, int intf_num)
2248
{
2249
	int rv = 0;
2250
	int prev_dyn_id_set, prev_guid_set;
2251
	bool intf_set = intf != NULL;
2252 2253 2254 2255 2256 2257 2258 2259 2260 2261 2262 2263 2264 2265 2266 2267 2268 2269 2270 2271 2272 2273

	if (!intf) {
		mutex_lock(&bmc->dyn_mutex);
retry_bmc_lock:
		if (list_empty(&bmc->intfs)) {
			mutex_unlock(&bmc->dyn_mutex);
			return -ENOENT;
		}
		intf = list_first_entry(&bmc->intfs, struct ipmi_smi,
					bmc_link);
		kref_get(&intf->refcount);
		mutex_unlock(&bmc->dyn_mutex);
		mutex_lock(&intf->bmc_reg_mutex);
		mutex_lock(&bmc->dyn_mutex);
		if (intf != list_first_entry(&bmc->intfs, struct ipmi_smi,
					     bmc_link)) {
			mutex_unlock(&intf->bmc_reg_mutex);
			kref_put(&intf->refcount, intf_free);
			goto retry_bmc_lock;
		}
	} else {
		mutex_lock(&intf->bmc_reg_mutex);
2274
		bmc = intf->bmc;
2275 2276 2277
		mutex_lock(&bmc->dyn_mutex);
		kref_get(&intf->refcount);
	}
2278

2279
	/* If we have a valid and current ID, just return that. */
2280 2281 2282
	if (intf->in_bmc_register ||
	    (bmc->dyn_id_set && time_is_after_jiffies(bmc->dyn_id_expiry)))
		goto out_noprocessing;
2283

2284 2285 2286 2287
	prev_guid_set = bmc->dyn_guid_set;
	__get_guid(intf);

	prev_dyn_id_set = bmc->dyn_id_set;
2288 2289 2290 2291
	rv = __get_device_id(intf, bmc);
	if (rv)
		goto out;

2292 2293 2294 2295 2296 2297 2298 2299
	/*
	 * The guid, device id, manufacturer id, and product id should
	 * not change on a BMC.  If it does we have to do some dancing.
	 */
	if (!intf->bmc_registered
	    || (!prev_guid_set && bmc->dyn_guid_set)
	    || (!prev_dyn_id_set && bmc->dyn_id_set)
	    || (prev_guid_set && bmc->dyn_guid_set
2300
		&& !guid_equal(&bmc->guid, &bmc->fetch_guid))
2301 2302 2303 2304 2305
	    || bmc->id.device_id != bmc->fetch_id.device_id
	    || bmc->id.manufacturer_id != bmc->fetch_id.manufacturer_id
	    || bmc->id.product_id != bmc->fetch_id.product_id) {
		struct ipmi_device_id id = bmc->fetch_id;
		int guid_set = bmc->dyn_guid_set;
2306
		guid_t guid;
2307

2308
		guid = bmc->fetch_guid;
2309 2310 2311 2312 2313 2314
		mutex_unlock(&bmc->dyn_mutex);

		__ipmi_bmc_unregister(intf);
		/* Fill in the temporary BMC for good measure. */
		intf->bmc->id = id;
		intf->bmc->dyn_guid_set = guid_set;
2315 2316
		intf->bmc->guid = guid;
		if (__ipmi_bmc_register(intf, &id, guid_set, &guid, intf_num))
2317
			need_waiter(intf); /* Retry later on an error. */
2318 2319 2320
		else
			__scan_channels(intf, &id);

2321 2322 2323 2324 2325 2326 2327 2328 2329 2330 2331 2332 2333 2334 2335 2336

		if (!intf_set) {
			/*
			 * We weren't given the interface on the
			 * command line, so restart the operation on
			 * the next interface for the BMC.
			 */
			mutex_unlock(&intf->bmc_reg_mutex);
			mutex_lock(&bmc->dyn_mutex);
			goto retry_bmc_lock;
		}

		/* We have a new BMC, set it up. */
		bmc = intf->bmc;
		mutex_lock(&bmc->dyn_mutex);
		goto out_noprocessing;
2337 2338 2339
	} else if (memcmp(&bmc->fetch_id, &bmc->id, sizeof(bmc->id)))
		/* Version info changes, scan the channels again. */
		__scan_channels(intf, &bmc->fetch_id);
2340 2341 2342 2343 2344 2345 2346 2347

	bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY;

out:
	if (rv && prev_dyn_id_set) {
		rv = 0; /* Ignore failures if we have previous data. */
		bmc->dyn_id_set = prev_dyn_id_set;
	}
2348 2349 2350
	if (!rv) {
		bmc->id = bmc->fetch_id;
		if (bmc->dyn_guid_set)
2351
			bmc->guid = bmc->fetch_guid;
2352 2353 2354 2355 2356 2357 2358 2359 2360 2361 2362
		else if (prev_guid_set)
			/*
			 * The guid used to be valid and it failed to fetch,
			 * just use the cached value.
			 */
			bmc->dyn_guid_set = prev_guid_set;
	}
out_noprocessing:
	if (!rv) {
		if (id)
			*id = bmc->id;
2363

2364 2365
		if (guid_set)
			*guid_set = bmc->dyn_guid_set;
2366

2367
		if (guid && bmc->dyn_guid_set)
2368
			*guid =  bmc->guid;
2369
	}
2370

2371 2372 2373 2374 2375
	mutex_unlock(&bmc->dyn_mutex);
	mutex_unlock(&intf->bmc_reg_mutex);

	kref_put(&intf->refcount, intf_free);
	return rv;
2376 2377
}

2378 2379
static int bmc_get_device_id(ipmi_smi_t intf, struct bmc_device *bmc,
			     struct ipmi_device_id *id,
2380
			     bool *guid_set, guid_t *guid)
2381 2382 2383 2384
{
	return __bmc_get_device_id(intf, bmc, id, guid_set, guid, -1);
}

2385
#ifdef CONFIG_IPMI_PROC_INTERFACE
2386
static int smi_ipmb_proc_show(struct seq_file *m, void *v)
L
Linus Torvalds 已提交
2387
{
2388
	ipmi_smi_t intf = m->private;
2389
	int        i;
L
Linus Torvalds 已提交
2390

2391
	seq_printf(m, "%x", intf->addrinfo[0].address);
2392
	for (i = 1; i < IPMI_MAX_CHANNELS; i++)
2393
		seq_printf(m, " %x", intf->addrinfo[i].address);
2394 2395
	seq_putc(m, '\n');

2396
	return 0;
L
Linus Torvalds 已提交
2397 2398
}

2399
static int smi_ipmb_proc_open(struct inode *inode, struct file *file)
L
Linus Torvalds 已提交
2400
{
A
Al Viro 已提交
2401
	return single_open(file, smi_ipmb_proc_show, PDE_DATA(inode));
2402
}
L
Linus Torvalds 已提交
2403

2404 2405 2406 2407 2408 2409 2410 2411 2412 2413
static const struct file_operations smi_ipmb_proc_ops = {
	.open		= smi_ipmb_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static int smi_version_proc_show(struct seq_file *m, void *v)
{
	ipmi_smi_t intf = m->private;
2414 2415 2416
	struct ipmi_device_id id;
	int rv;

2417
	rv = bmc_get_device_id(intf, NULL, &id, NULL, NULL);
2418 2419
	if (rv)
		return rv;
2420

2421
	seq_printf(m, "%u.%u\n",
2422 2423
		   ipmi_version_major(&id),
		   ipmi_version_minor(&id));
2424

2425
	return 0;
L
Linus Torvalds 已提交
2426 2427
}

2428
static int smi_version_proc_open(struct inode *inode, struct file *file)
L
Linus Torvalds 已提交
2429
{
A
Al Viro 已提交
2430
	return single_open(file, smi_version_proc_show, PDE_DATA(inode));
2431 2432 2433 2434 2435 2436 2437 2438
}

static const struct file_operations smi_version_proc_ops = {
	.open		= smi_version_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
L
Linus Torvalds 已提交
2439

2440 2441 2442 2443 2444
static int smi_stats_proc_show(struct seq_file *m, void *v)
{
	ipmi_smi_t intf = m->private;

	seq_printf(m, "sent_invalid_commands:       %u\n",
2445
		       ipmi_get_stat(intf, sent_invalid_commands));
2446
	seq_printf(m, "sent_local_commands:         %u\n",
2447
		       ipmi_get_stat(intf, sent_local_commands));
2448
	seq_printf(m, "handled_local_responses:     %u\n",
2449
		       ipmi_get_stat(intf, handled_local_responses));
2450
	seq_printf(m, "unhandled_local_responses:   %u\n",
2451
		       ipmi_get_stat(intf, unhandled_local_responses));
2452
	seq_printf(m, "sent_ipmb_commands:          %u\n",
2453
		       ipmi_get_stat(intf, sent_ipmb_commands));
2454
	seq_printf(m, "sent_ipmb_command_errs:      %u\n",
2455
		       ipmi_get_stat(intf, sent_ipmb_command_errs));
2456
	seq_printf(m, "retransmitted_ipmb_commands: %u\n",
2457
		       ipmi_get_stat(intf, retransmitted_ipmb_commands));
2458
	seq_printf(m, "timed_out_ipmb_commands:     %u\n",
2459
		       ipmi_get_stat(intf, timed_out_ipmb_commands));
2460
	seq_printf(m, "timed_out_ipmb_broadcasts:   %u\n",
2461
		       ipmi_get_stat(intf, timed_out_ipmb_broadcasts));
2462
	seq_printf(m, "sent_ipmb_responses:         %u\n",
2463
		       ipmi_get_stat(intf, sent_ipmb_responses));
2464
	seq_printf(m, "handled_ipmb_responses:      %u\n",
2465
		       ipmi_get_stat(intf, handled_ipmb_responses));
2466
	seq_printf(m, "invalid_ipmb_responses:      %u\n",
2467
		       ipmi_get_stat(intf, invalid_ipmb_responses));
2468
	seq_printf(m, "unhandled_ipmb_responses:    %u\n",
2469
		       ipmi_get_stat(intf, unhandled_ipmb_responses));
2470
	seq_printf(m, "sent_lan_commands:           %u\n",
2471
		       ipmi_get_stat(intf, sent_lan_commands));
2472
	seq_printf(m, "sent_lan_command_errs:       %u\n",
2473
		       ipmi_get_stat(intf, sent_lan_command_errs));
2474
	seq_printf(m, "retransmitted_lan_commands:  %u\n",
2475
		       ipmi_get_stat(intf, retransmitted_lan_commands));
2476
	seq_printf(m, "timed_out_lan_commands:      %u\n",
2477
		       ipmi_get_stat(intf, timed_out_lan_commands));
2478
	seq_printf(m, "sent_lan_responses:          %u\n",
2479
		       ipmi_get_stat(intf, sent_lan_responses));
2480
	seq_printf(m, "handled_lan_responses:       %u\n",
2481
		       ipmi_get_stat(intf, handled_lan_responses));
2482
	seq_printf(m, "invalid_lan_responses:       %u\n",
2483
		       ipmi_get_stat(intf, invalid_lan_responses));
2484
	seq_printf(m, "unhandled_lan_responses:     %u\n",
2485
		       ipmi_get_stat(intf, unhandled_lan_responses));
2486
	seq_printf(m, "handled_commands:            %u\n",
2487
		       ipmi_get_stat(intf, handled_commands));
2488
	seq_printf(m, "invalid_commands:            %u\n",
2489
		       ipmi_get_stat(intf, invalid_commands));
2490
	seq_printf(m, "unhandled_commands:          %u\n",
2491
		       ipmi_get_stat(intf, unhandled_commands));
2492
	seq_printf(m, "invalid_events:              %u\n",
2493
		       ipmi_get_stat(intf, invalid_events));
2494
	seq_printf(m, "events:                      %u\n",
2495
		       ipmi_get_stat(intf, events));
2496
	seq_printf(m, "failed rexmit LAN msgs:      %u\n",
2497
		       ipmi_get_stat(intf, dropped_rexmit_lan_commands));
2498
	seq_printf(m, "failed rexmit IPMB msgs:     %u\n",
2499
		       ipmi_get_stat(intf, dropped_rexmit_ipmb_commands));
2500 2501
	return 0;
}
L
Linus Torvalds 已提交
2502

2503 2504
static int smi_stats_proc_open(struct inode *inode, struct file *file)
{
A
Al Viro 已提交
2505
	return single_open(file, smi_stats_proc_show, PDE_DATA(inode));
L
Linus Torvalds 已提交
2506
}
2507 2508 2509 2510 2511 2512 2513

static const struct file_operations smi_stats_proc_ops = {
	.open		= smi_stats_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};
L
Linus Torvalds 已提交
2514 2515

int ipmi_smi_add_proc_entry(ipmi_smi_t smi, char *name,
2516
			    const struct file_operations *proc_ops,
2517
			    void *data)
L
Linus Torvalds 已提交
2518 2519
{
	int                    rv = 0;
2520
	struct proc_dir_entry  *file;
L
Linus Torvalds 已提交
2521 2522 2523 2524 2525 2526
	struct ipmi_proc_entry *entry;

	/* Create a list element. */
	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
	if (!entry)
		return -ENOMEM;
2527
	entry->name = kstrdup(name, GFP_KERNEL);
L
Linus Torvalds 已提交
2528 2529 2530 2531 2532
	if (!entry->name) {
		kfree(entry);
		return -ENOMEM;
	}

2533
	file = proc_create_data(name, 0, smi->proc_dir, proc_ops, data);
L
Linus Torvalds 已提交
2534 2535 2536 2537 2538
	if (!file) {
		kfree(entry->name);
		kfree(entry);
		rv = -ENOMEM;
	} else {
C
Corey Minyard 已提交
2539
		mutex_lock(&smi->proc_entry_lock);
L
Linus Torvalds 已提交
2540 2541 2542
		/* Stick it on the list. */
		entry->next = smi->proc_entries;
		smi->proc_entries = entry;
C
Corey Minyard 已提交
2543
		mutex_unlock(&smi->proc_entry_lock);
L
Linus Torvalds 已提交
2544 2545 2546 2547
	}

	return rv;
}
2548
EXPORT_SYMBOL(ipmi_smi_add_proc_entry);
L
Linus Torvalds 已提交
2549 2550 2551 2552 2553 2554 2555 2556 2557 2558 2559 2560

static int add_proc_entries(ipmi_smi_t smi, int num)
{
	int rv = 0;

	sprintf(smi->proc_dir_name, "%d", num);
	smi->proc_dir = proc_mkdir(smi->proc_dir_name, proc_ipmi_root);
	if (!smi->proc_dir)
		rv = -ENOMEM;

	if (rv == 0)
		rv = ipmi_smi_add_proc_entry(smi, "stats",
2561
					     &smi_stats_proc_ops,
2562
					     smi);
L
Linus Torvalds 已提交
2563 2564 2565

	if (rv == 0)
		rv = ipmi_smi_add_proc_entry(smi, "ipmb",
2566
					     &smi_ipmb_proc_ops,
2567
					     smi);
L
Linus Torvalds 已提交
2568 2569 2570

	if (rv == 0)
		rv = ipmi_smi_add_proc_entry(smi, "version",
2571
					     &smi_version_proc_ops,
2572
					     smi);
L
Linus Torvalds 已提交
2573 2574 2575 2576 2577 2578 2579 2580

	return rv;
}

static void remove_proc_entries(ipmi_smi_t smi)
{
	struct ipmi_proc_entry *entry;

C
Corey Minyard 已提交
2581
	mutex_lock(&smi->proc_entry_lock);
L
Linus Torvalds 已提交
2582 2583 2584 2585 2586 2587 2588 2589
	while (smi->proc_entries) {
		entry = smi->proc_entries;
		smi->proc_entries = entry->next;

		remove_proc_entry(entry->name, smi->proc_dir);
		kfree(entry->name);
		kfree(entry);
	}
C
Corey Minyard 已提交
2590
	mutex_unlock(&smi->proc_entry_lock);
L
Linus Torvalds 已提交
2591 2592
	remove_proc_entry(smi->proc_dir_name, proc_ipmi_root);
}
2593
#endif /* CONFIG_IPMI_PROC_INTERFACE */
L
Linus Torvalds 已提交
2594

2595 2596 2597 2598
static ssize_t device_id_show(struct device *dev,
			      struct device_attribute *attr,
			      char *buf)
{
2599
	struct bmc_device *bmc = to_bmc_device(dev);
2600 2601 2602
	struct ipmi_device_id id;
	int rv;

2603
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2604 2605
	if (rv)
		return rv;
2606

2607
	return snprintf(buf, 10, "%u\n", id.device_id);
2608
}
J
Joe Perches 已提交
2609
static DEVICE_ATTR_RO(device_id);
2610

2611 2612 2613
static ssize_t provides_device_sdrs_show(struct device *dev,
					 struct device_attribute *attr,
					 char *buf)
2614
{
2615
	struct bmc_device *bmc = to_bmc_device(dev);
2616 2617
	struct ipmi_device_id id;
	int rv;
2618

2619
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2620 2621 2622 2623
	if (rv)
		return rv;

	return snprintf(buf, 10, "%u\n", (id.device_revision & 0x80) >> 7);
2624
}
J
Joe Perches 已提交
2625
static DEVICE_ATTR_RO(provides_device_sdrs);
2626 2627 2628 2629

static ssize_t revision_show(struct device *dev, struct device_attribute *attr,
			     char *buf)
{
2630
	struct bmc_device *bmc = to_bmc_device(dev);
2631 2632
	struct ipmi_device_id id;
	int rv;
2633

2634
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2635 2636 2637 2638
	if (rv)
		return rv;

	return snprintf(buf, 20, "%u\n", id.device_revision & 0x0F);
2639
}
J
Joe Perches 已提交
2640
static DEVICE_ATTR_RO(revision);
2641

2642 2643 2644
static ssize_t firmware_revision_show(struct device *dev,
				      struct device_attribute *attr,
				      char *buf)
2645
{
2646
	struct bmc_device *bmc = to_bmc_device(dev);
2647 2648
	struct ipmi_device_id id;
	int rv;
2649

2650
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2651 2652 2653 2654 2655
	if (rv)
		return rv;

	return snprintf(buf, 20, "%u.%x\n", id.firmware_revision_1,
			id.firmware_revision_2);
2656
}
J
Joe Perches 已提交
2657
static DEVICE_ATTR_RO(firmware_revision);
2658 2659 2660 2661 2662

static ssize_t ipmi_version_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
2663
	struct bmc_device *bmc = to_bmc_device(dev);
2664 2665 2666
	struct ipmi_device_id id;
	int rv;

2667
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2668 2669
	if (rv)
		return rv;
2670 2671

	return snprintf(buf, 20, "%u.%u\n",
2672 2673
			ipmi_version_major(&id),
			ipmi_version_minor(&id));
2674
}
J
Joe Perches 已提交
2675
static DEVICE_ATTR_RO(ipmi_version);
2676 2677 2678 2679 2680

static ssize_t add_dev_support_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
2681
	struct bmc_device *bmc = to_bmc_device(dev);
2682 2683
	struct ipmi_device_id id;
	int rv;
2684

2685
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2686 2687 2688 2689
	if (rv)
		return rv;

	return snprintf(buf, 10, "0x%02x\n", id.additional_device_support);
2690
}
2691 2692
static DEVICE_ATTR(additional_device_support, S_IRUGO, add_dev_support_show,
		   NULL);
2693 2694 2695 2696 2697

static ssize_t manufacturer_id_show(struct device *dev,
				    struct device_attribute *attr,
				    char *buf)
{
2698
	struct bmc_device *bmc = to_bmc_device(dev);
2699 2700 2701
	struct ipmi_device_id id;
	int rv;

2702
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2703 2704
	if (rv)
		return rv;
2705

2706
	return snprintf(buf, 20, "0x%6.6x\n", id.manufacturer_id);
2707
}
J
Joe Perches 已提交
2708
static DEVICE_ATTR_RO(manufacturer_id);
2709 2710 2711 2712 2713

static ssize_t product_id_show(struct device *dev,
			       struct device_attribute *attr,
			       char *buf)
{
2714
	struct bmc_device *bmc = to_bmc_device(dev);
2715 2716 2717
	struct ipmi_device_id id;
	int rv;

2718
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2719 2720
	if (rv)
		return rv;
2721

2722
	return snprintf(buf, 10, "0x%4.4x\n", id.product_id);
2723
}
J
Joe Perches 已提交
2724
static DEVICE_ATTR_RO(product_id);
2725 2726 2727 2728 2729

static ssize_t aux_firmware_rev_show(struct device *dev,
				     struct device_attribute *attr,
				     char *buf)
{
2730
	struct bmc_device *bmc = to_bmc_device(dev);
2731 2732 2733
	struct ipmi_device_id id;
	int rv;

2734
	rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2735 2736
	if (rv)
		return rv;
2737 2738

	return snprintf(buf, 21, "0x%02x 0x%02x 0x%02x 0x%02x\n",
2739 2740 2741 2742
			id.aux_firmware_revision[3],
			id.aux_firmware_revision[2],
			id.aux_firmware_revision[1],
			id.aux_firmware_revision[0]);
2743
}
2744
static DEVICE_ATTR(aux_firmware_revision, S_IRUGO, aux_firmware_rev_show, NULL);
2745 2746 2747 2748

static ssize_t guid_show(struct device *dev, struct device_attribute *attr,
			 char *buf)
{
2749
	struct bmc_device *bmc = to_bmc_device(dev);
2750
	bool guid_set;
2751
	guid_t guid;
2752 2753
	int rv;

2754
	rv = bmc_get_device_id(NULL, bmc, NULL, &guid_set, &guid);
2755 2756 2757 2758
	if (rv)
		return rv;
	if (!guid_set)
		return -ENOENT;
2759

2760
	return snprintf(buf, 38, "%pUl\n", guid.b);
2761
}
J
Joe Perches 已提交
2762
static DEVICE_ATTR_RO(guid);
2763 2764 2765 2766 2767 2768 2769 2770 2771 2772

static struct attribute *bmc_dev_attrs[] = {
	&dev_attr_device_id.attr,
	&dev_attr_provides_device_sdrs.attr,
	&dev_attr_revision.attr,
	&dev_attr_firmware_revision.attr,
	&dev_attr_ipmi_version.attr,
	&dev_attr_additional_device_support.attr,
	&dev_attr_manufacturer_id.attr,
	&dev_attr_product_id.attr,
2773 2774
	&dev_attr_aux_firmware_revision.attr,
	&dev_attr_guid.attr,
2775 2776
	NULL
};
2777

2778 2779 2780 2781 2782 2783
static umode_t bmc_dev_attr_is_visible(struct kobject *kobj,
				       struct attribute *attr, int idx)
{
	struct device *dev = kobj_to_dev(kobj);
	struct bmc_device *bmc = to_bmc_device(dev);
	umode_t mode = attr->mode;
2784
	int rv;
2785

2786
	if (attr == &dev_attr_aux_firmware_revision.attr) {
2787 2788 2789
		struct ipmi_device_id id;

		rv = bmc_get_device_id(NULL, bmc, &id, NULL, NULL);
2790 2791
		return (!rv && id.aux_firmware_revision_set) ? mode : 0;
	}
2792 2793 2794 2795 2796 2797
	if (attr == &dev_attr_guid.attr) {
		bool guid_set;

		rv = bmc_get_device_id(NULL, bmc, NULL, &guid_set, NULL);
		return (!rv && guid_set) ? mode : 0;
	}
2798 2799 2800
	return mode;
}

2801
static const struct attribute_group bmc_dev_attr_group = {
2802
	.attrs		= bmc_dev_attrs,
2803
	.is_visible	= bmc_dev_attr_is_visible,
2804
};
J
Jeff Garzik 已提交
2805

2806 2807 2808 2809 2810
static const struct attribute_group *bmc_dev_attr_groups[] = {
	&bmc_dev_attr_group,
	NULL
};

2811
static const struct device_type bmc_device_type = {
2812 2813 2814
	.groups		= bmc_dev_attr_groups,
};

2815 2816
static int __find_bmc_guid(struct device *dev, void *data)
{
2817
	guid_t *guid = data;
2818 2819
	struct bmc_device *bmc;
	int rv;
2820

2821 2822 2823
	if (dev->type != &bmc_device_type)
		return 0;

2824
	bmc = to_bmc_device(dev);
2825
	rv = bmc->dyn_guid_set && guid_equal(&bmc->guid, guid);
2826 2827 2828
	if (rv)
		rv = kref_get_unless_zero(&bmc->usecount);
	return rv;
2829 2830
}

2831
/*
2832
 * Returns with the bmc's usecount incremented, if it is non-NULL.
2833
 */
2834
static struct bmc_device *ipmi_find_bmc_guid(struct device_driver *drv,
2835
					     guid_t *guid)
2836 2837
{
	struct device *dev;
2838
	struct bmc_device *bmc = NULL;
2839 2840

	dev = driver_find_device(drv, NULL, guid, __find_bmc_guid);
2841 2842 2843 2844 2845
	if (dev) {
		bmc = to_bmc_device(dev);
		put_device(dev);
	}
	return bmc;
2846 2847 2848 2849 2850 2851 2852 2853 2854
}

struct prod_dev_id {
	unsigned int  product_id;
	unsigned char device_id;
};

static int __find_bmc_prod_dev_id(struct device *dev, void *data)
{
2855
	struct prod_dev_id *cid = data;
2856
	struct bmc_device *bmc;
2857
	int rv;
2858 2859 2860

	if (dev->type != &bmc_device_type)
		return 0;
2861

2862
	bmc = to_bmc_device(dev);
2863 2864
	rv = (bmc->id.product_id == cid->product_id
	      && bmc->id.device_id == cid->device_id);
2865
	if (rv)
2866 2867
		rv = kref_get_unless_zero(&bmc->usecount);
	return rv;
2868 2869
}

2870
/*
2871
 * Returns with the bmc's usecount incremented, if it is non-NULL.
2872
 */
2873 2874 2875 2876 2877 2878 2879 2880 2881
static struct bmc_device *ipmi_find_bmc_prod_dev_id(
	struct device_driver *drv,
	unsigned int product_id, unsigned char device_id)
{
	struct prod_dev_id id = {
		.product_id = product_id,
		.device_id = device_id,
	};
	struct device *dev;
2882
	struct bmc_device *bmc = NULL;
2883 2884

	dev = driver_find_device(drv, NULL, &id, __find_bmc_prod_dev_id);
2885 2886 2887 2888 2889
	if (dev) {
		bmc = to_bmc_device(dev);
		put_device(dev);
	}
	return bmc;
2890 2891
}

2892 2893
static DEFINE_IDA(ipmi_bmc_ida);

2894 2895 2896 2897
static void
release_bmc_device(struct device *dev)
{
	kfree(to_bmc_device(dev));
J
Jeff Garzik 已提交
2898 2899
}

2900
static void cleanup_bmc_work(struct work_struct *work)
J
Jeff Garzik 已提交
2901
{
2902 2903
	struct bmc_device *bmc = container_of(work, struct bmc_device,
					      remove_work);
2904
	int id = bmc->pdev.id; /* Unregister overwrites id */
J
Jeff Garzik 已提交
2905

2906
	platform_device_unregister(&bmc->pdev);
2907
	ida_simple_remove(&ipmi_bmc_ida, id);
2908 2909
}

2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 2920 2921 2922 2923 2924 2925 2926
static void
cleanup_bmc_device(struct kref *ref)
{
	struct bmc_device *bmc = container_of(ref, struct bmc_device, usecount);

	/*
	 * Remove the platform device in a work queue to avoid issues
	 * with removing the device attributes while reading a device
	 * attribute.
	 */
	schedule_work(&bmc->remove_work);
}

/*
 * Must be called with intf->bmc_reg_mutex held.
 */
static void __ipmi_bmc_unregister(ipmi_smi_t intf)
2927 2928 2929
{
	struct bmc_device *bmc = intf->bmc;

C
Corey Minyard 已提交
2930 2931 2932
	if (!intf->bmc_registered)
		return;

2933
	sysfs_remove_link(&intf->si_dev->kobj, "bmc");
C
Corey Minyard 已提交
2934 2935 2936
	sysfs_remove_link(&bmc->pdev.dev.kobj, intf->my_dev_name);
	kfree(intf->my_dev_name);
	intf->my_dev_name = NULL;
2937

2938
	mutex_lock(&bmc->dyn_mutex);
2939
	list_del(&intf->bmc_link);
2940
	mutex_unlock(&bmc->dyn_mutex);
2941
	intf->bmc = &intf->tmp_bmc;
2942
	kref_put(&bmc->usecount, cleanup_bmc_device);
C
Corey Minyard 已提交
2943
	intf->bmc_registered = false;
2944
}
2945

2946 2947 2948 2949
static void ipmi_bmc_unregister(ipmi_smi_t intf)
{
	mutex_lock(&intf->bmc_reg_mutex);
	__ipmi_bmc_unregister(intf);
2950
	mutex_unlock(&intf->bmc_reg_mutex);
2951 2952
}

2953 2954 2955 2956 2957
/*
 * Must be called with intf->bmc_reg_mutex held.
 */
static int __ipmi_bmc_register(ipmi_smi_t intf,
			       struct ipmi_device_id *id,
2958
			       bool guid_set, guid_t *guid, int intf_num)
2959 2960
{
	int               rv;
2961
	struct bmc_device *bmc;
2962 2963
	struct bmc_device *old_bmc;

2964 2965 2966 2967 2968 2969 2970 2971 2972
	/*
	 * platform_device_register() can cause bmc_reg_mutex to
	 * be claimed because of the is_visible functions of
	 * the attributes.  Eliminate possible recursion and
	 * release the lock.
	 */
	intf->in_bmc_register = true;
	mutex_unlock(&intf->bmc_reg_mutex);

2973 2974 2975 2976
	/*
	 * Try to find if there is an bmc_device struct
	 * representing the interfaced BMC already
	 */
2977
	mutex_lock(&ipmidriver_mutex);
2978 2979
	if (guid_set)
		old_bmc = ipmi_find_bmc_guid(&ipmidriver.driver, guid);
2980
	else
2981
		old_bmc = ipmi_find_bmc_prod_dev_id(&ipmidriver.driver,
2982 2983
						    id->product_id,
						    id->device_id);
2984 2985 2986 2987 2988 2989

	/*
	 * If there is already an bmc_device, free the new one,
	 * otherwise register the new BMC device
	 */
	if (old_bmc) {
2990
		bmc = old_bmc;
2991 2992 2993 2994
		/*
		 * Note: old_bmc already has usecount incremented by
		 * the BMC find functions.
		 */
2995
		intf->bmc = old_bmc;
2996
		mutex_lock(&bmc->dyn_mutex);
2997
		list_add_tail(&intf->bmc_link, &bmc->intfs);
2998
		mutex_unlock(&bmc->dyn_mutex);
2999

3000 3001 3002 3003 3004 3005
		dev_info(intf->si_dev,
			 "ipmi: interfacing existing BMC (man_id: 0x%6.6x,"
			 " prod_id: 0x%4.4x, dev_id: 0x%2.2x)\n",
			 bmc->id.manufacturer_id,
			 bmc->id.product_id,
			 bmc->id.device_id);
3006
	} else {
3007 3008 3009 3010 3011 3012 3013
		bmc = kzalloc(sizeof(*bmc), GFP_KERNEL);
		if (!bmc) {
			rv = -ENOMEM;
			goto out;
		}
		INIT_LIST_HEAD(&bmc->intfs);
		mutex_init(&bmc->dyn_mutex);
3014 3015 3016 3017 3018
		INIT_WORK(&bmc->remove_work, cleanup_bmc_work);

		bmc->id = *id;
		bmc->dyn_id_set = 1;
		bmc->dyn_guid_set = guid_set;
3019
		bmc->guid = *guid;
3020
		bmc->dyn_id_expiry = jiffies + IPMI_DYN_DEV_ID_EXPIRY;
3021

3022
		bmc->pdev.name = "ipmi_bmc";
3023

3024 3025 3026
		rv = ida_simple_get(&ipmi_bmc_ida, 0, 0, GFP_KERNEL);
		if (rv < 0)
			goto out;
3027
		bmc->pdev.dev.driver = &ipmidriver.driver;
3028
		bmc->pdev.id = rv;
3029 3030
		bmc->pdev.dev.release = release_bmc_device;
		bmc->pdev.dev.type = &bmc_device_type;
3031
		kref_init(&bmc->usecount);
3032

3033 3034
		intf->bmc = bmc;
		mutex_lock(&bmc->dyn_mutex);
3035
		list_add_tail(&intf->bmc_link, &bmc->intfs);
3036 3037 3038
		mutex_unlock(&bmc->dyn_mutex);

		rv = platform_device_register(&bmc->pdev);
3039
		if (rv) {
3040 3041 3042
			dev_err(intf->si_dev,
				PFX " Unable to register bmc device: %d\n",
				rv);
C
Corey Minyard 已提交
3043
			goto out_list_del;
3044 3045
		}

3046 3047
		dev_info(intf->si_dev,
			 "Found new BMC (man_id: 0x%6.6x, prod_id: 0x%4.4x, dev_id: 0x%2.2x)\n",
3048 3049 3050
			 bmc->id.manufacturer_id,
			 bmc->id.product_id,
			 bmc->id.device_id);
3051 3052 3053 3054 3055 3056
	}

	/*
	 * create symlink from system interface device to bmc device
	 * and back.
	 */
3057
	rv = sysfs_create_link(&intf->si_dev->kobj, &bmc->pdev.dev.kobj, "bmc");
3058
	if (rv) {
3059 3060
		dev_err(intf->si_dev,
			PFX "Unable to create bmc symlink: %d\n", rv);
C
Corey Minyard 已提交
3061
		goto out_put_bmc;
3062 3063
	}

3064 3065 3066
	if (intf_num == -1)
		intf_num = intf->intf_num;
	intf->my_dev_name = kasprintf(GFP_KERNEL, "ipmi%d", intf_num);
3067 3068
	if (!intf->my_dev_name) {
		rv = -ENOMEM;
3069 3070
		dev_err(intf->si_dev,
			PFX "Unable to allocate link from BMC: %d\n", rv);
C
Corey Minyard 已提交
3071
		goto out_unlink1;
3072 3073
	}

3074
	rv = sysfs_create_link(&bmc->pdev.dev.kobj, &intf->si_dev->kobj,
3075 3076 3077 3078
			       intf->my_dev_name);
	if (rv) {
		kfree(intf->my_dev_name);
		intf->my_dev_name = NULL;
3079 3080
		dev_err(intf->si_dev,
			PFX "Unable to create symlink to bmc: %d\n", rv);
C
Corey Minyard 已提交
3081
		goto out_free_my_dev_name;
3082 3083
	}

C
Corey Minyard 已提交
3084
	intf->bmc_registered = true;
3085

C
Corey Minyard 已提交
3086
out:
3087 3088 3089
	mutex_unlock(&ipmidriver_mutex);
	mutex_lock(&intf->bmc_reg_mutex);
	intf->in_bmc_register = false;
3090
	return rv;
C
Corey Minyard 已提交
3091 3092 3093 3094 3095 3096 3097 3098 3099 3100


out_free_my_dev_name:
	kfree(intf->my_dev_name);
	intf->my_dev_name = NULL;

out_unlink1:
	sysfs_remove_link(&intf->si_dev->kobj, "bmc");

out_put_bmc:
3101
	mutex_lock(&bmc->dyn_mutex);
3102
	list_del(&intf->bmc_link);
3103
	mutex_unlock(&bmc->dyn_mutex);
3104
	intf->bmc = &intf->tmp_bmc;
C
Corey Minyard 已提交
3105 3106 3107 3108
	kref_put(&bmc->usecount, cleanup_bmc_device);
	goto out;

out_list_del:
3109
	mutex_lock(&bmc->dyn_mutex);
3110
	list_del(&intf->bmc_link);
3111
	mutex_unlock(&bmc->dyn_mutex);
3112
	intf->bmc = &intf->tmp_bmc;
C
Corey Minyard 已提交
3113 3114
	put_device(&bmc->pdev.dev);
	goto out;
3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139
}

static int
send_guid_cmd(ipmi_smi_t intf, int chan)
{
	struct kernel_ipmi_msg            msg;
	struct ipmi_system_interface_addr si;

	si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	si.channel = IPMI_BMC_CHANNEL;
	si.lun = 0;

	msg.netfn = IPMI_NETFN_APP_REQUEST;
	msg.cmd = IPMI_GET_DEVICE_GUID_CMD;
	msg.data = NULL;
	msg.data_len = 0;
	return i_ipmi_request(NULL,
			      intf,
			      (struct ipmi_addr *) &si,
			      0,
			      &msg,
			      intf,
			      NULL,
			      NULL,
			      0,
3140 3141
			      intf->addrinfo[0].address,
			      intf->addrinfo[0].lun,
3142 3143 3144
			      -1, 0);
}

3145
static void guid_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
3146
{
3147 3148
	struct bmc_device *bmc = intf->bmc;

3149 3150 3151 3152 3153 3154 3155 3156
	if ((msg->addr.addr_type != IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
	    || (msg->msg.netfn != IPMI_NETFN_APP_RESPONSE)
	    || (msg->msg.cmd != IPMI_GET_DEVICE_GUID_CMD))
		/* Not for me */
		return;

	if (msg->msg.data[0] != 0) {
		/* Error from getting the GUID, the BMC doesn't have one. */
3157
		bmc->dyn_guid_set = 0;
3158 3159 3160 3161
		goto out;
	}

	if (msg->msg.data_len < 17) {
3162
		bmc->dyn_guid_set = 0;
3163 3164 3165
		dev_warn(intf->si_dev,
			 PFX "The GUID response from the BMC was too short, it was %d but should have been 17.  Assuming GUID is not available.\n",
			 msg->msg.data_len);
3166 3167 3168
		goto out;
	}

3169
	memcpy(bmc->fetch_guid.b, msg->msg.data + 1, 16);
3170 3171 3172 3173 3174 3175
	/*
	 * Make sure the guid data is available before setting
	 * dyn_guid_set.
	 */
	smp_wmb();
	bmc->dyn_guid_set = 1;
3176 3177 3178 3179
 out:
	wake_up(&intf->waitq);
}

3180
static void __get_guid(ipmi_smi_t intf)
3181 3182
{
	int rv;
3183
	struct bmc_device *bmc = intf->bmc;
3184

3185
	bmc->dyn_guid_set = 2;
3186 3187 3188 3189
	intf->null_user_handler = guid_handler;
	rv = send_guid_cmd(intf, 0);
	if (rv)
		/* Send failed, no GUID available. */
3190 3191 3192 3193 3194 3195 3196
		bmc->dyn_guid_set = 0;

	wait_event(intf->waitq, bmc->dyn_guid_set != 2);

	/* dyn_guid_set makes the guid data available. */
	smp_rmb();

3197 3198 3199
	intf->null_user_handler = NULL;
}

L
Linus Torvalds 已提交
3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220
static int
send_channel_info_cmd(ipmi_smi_t intf, int chan)
{
	struct kernel_ipmi_msg            msg;
	unsigned char                     data[1];
	struct ipmi_system_interface_addr si;

	si.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	si.channel = IPMI_BMC_CHANNEL;
	si.lun = 0;

	msg.netfn = IPMI_NETFN_APP_REQUEST;
	msg.cmd = IPMI_GET_CHANNEL_INFO_CMD;
	msg.data = data;
	msg.data_len = 1;
	data[0] = chan;
	return i_ipmi_request(NULL,
			      intf,
			      (struct ipmi_addr *) &si,
			      0,
			      &msg,
3221
			      intf,
L
Linus Torvalds 已提交
3222 3223 3224
			      NULL,
			      NULL,
			      0,
3225 3226
			      intf->addrinfo[0].address,
			      intf->addrinfo[0].lun,
L
Linus Torvalds 已提交
3227 3228 3229 3230
			      -1, 0);
}

static void
3231
channel_handler(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
L
Linus Torvalds 已提交
3232 3233
{
	int rv = 0;
3234 3235 3236
	int ch;
	unsigned int set = intf->curr_working_cset;
	struct ipmi_channel *chans;
L
Linus Torvalds 已提交
3237

3238 3239
	if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
	    && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE)
3240
	    && (msg->msg.cmd == IPMI_GET_CHANNEL_INFO_CMD)) {
L
Linus Torvalds 已提交
3241
		/* It's the one we want */
3242
		if (msg->msg.data[0] != 0) {
L
Linus Torvalds 已提交
3243 3244
			/* Got an error from the channel, just go on. */

3245
			if (msg->msg.data[0] == IPMI_INVALID_COMMAND_ERR) {
3246 3247 3248 3249 3250 3251
				/*
				 * If the MC does not support this
				 * command, that is legal.  We just
				 * assume it has one IPMB at channel
				 * zero.
				 */
3252
				intf->wchannels[set].c[0].medium
L
Linus Torvalds 已提交
3253
					= IPMI_CHANNEL_MEDIUM_IPMB;
3254
				intf->wchannels[set].c[0].protocol
L
Linus Torvalds 已提交
3255 3256
					= IPMI_CHANNEL_PROTOCOL_IPMB;

3257 3258
				intf->channel_list = intf->wchannels + set;
				intf->channels_ready = true;
L
Linus Torvalds 已提交
3259 3260 3261 3262 3263
				wake_up(&intf->waitq);
				goto out;
			}
			goto next_channel;
		}
3264
		if (msg->msg.data_len < 4) {
L
Linus Torvalds 已提交
3265 3266 3267
			/* Message not big enough, just go on. */
			goto next_channel;
		}
3268 3269 3270 3271
		ch = intf->curr_channel;
		chans = intf->wchannels[set].c;
		chans[ch].medium = msg->msg.data[2] & 0x7f;
		chans[ch].protocol = msg->msg.data[3] & 0x1f;
L
Linus Torvalds 已提交
3272

3273
 next_channel:
L
Linus Torvalds 已提交
3274
		intf->curr_channel++;
3275 3276 3277
		if (intf->curr_channel >= IPMI_MAX_CHANNELS) {
			intf->channel_list = intf->wchannels + set;
			intf->channels_ready = true;
L
Linus Torvalds 已提交
3278
			wake_up(&intf->waitq);
3279 3280 3281
		} else {
			intf->channel_list = intf->wchannels + set;
			intf->channels_ready = true;
L
Linus Torvalds 已提交
3282
			rv = send_channel_info_cmd(intf, intf->curr_channel);
3283
		}
L
Linus Torvalds 已提交
3284 3285 3286

		if (rv) {
			/* Got an error somehow, just give up. */
3287 3288 3289
			dev_warn(intf->si_dev,
				 PFX "Error sending channel information for channel %d: %d\n",
				 intf->curr_channel, rv);
3290

3291 3292
			intf->channel_list = intf->wchannels + set;
			intf->channels_ready = true;
L
Linus Torvalds 已提交
3293 3294 3295 3296 3297 3298 3299
			wake_up(&intf->waitq);
		}
	}
 out:
	return;
}

3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346
/*
 * Must be holding intf->bmc_reg_mutex to call this.
 */
static int __scan_channels(ipmi_smi_t intf, struct ipmi_device_id *id)
{
	int rv;

	if (ipmi_version_major(id) > 1
			|| (ipmi_version_major(id) == 1
			    && ipmi_version_minor(id) >= 5)) {
		unsigned int set;

		/*
		 * Start scanning the channels to see what is
		 * available.
		 */
		set = !intf->curr_working_cset;
		intf->curr_working_cset = set;
		memset(&intf->wchannels[set], 0,
		       sizeof(struct ipmi_channel_set));

		intf->null_user_handler = channel_handler;
		intf->curr_channel = 0;
		rv = send_channel_info_cmd(intf, 0);
		if (rv) {
			dev_warn(intf->si_dev,
				 "Error sending channel information for channel 0, %d\n",
				 rv);
			return -EIO;
		}

		/* Wait for the channel info to be read. */
		wait_event(intf->waitq, intf->channels_ready);
		intf->null_user_handler = NULL;
	} else {
		unsigned int set = intf->curr_working_cset;

		/* Assume a single IPMB channel at zero. */
		intf->wchannels[set].c[0].medium = IPMI_CHANNEL_MEDIUM_IPMB;
		intf->wchannels[set].c[0].protocol = IPMI_CHANNEL_PROTOCOL_IPMB;
		intf->channel_list = intf->wchannels + set;
		intf->channels_ready = true;
	}

	return 0;
}

3347
static void ipmi_poll(ipmi_smi_t intf)
C
Corey Minyard 已提交
3348 3349 3350
{
	if (intf->handlers->poll)
		intf->handlers->poll(intf->send_info);
3351 3352
	/* In case something came in */
	handle_new_recv_msgs(intf);
C
Corey Minyard 已提交
3353
}
3354 3355 3356 3357

void ipmi_poll_interface(ipmi_user_t user)
{
	ipmi_poll(user->intf);
C
Corey Minyard 已提交
3358
}
3359
EXPORT_SYMBOL(ipmi_poll_interface);
C
Corey Minyard 已提交
3360

3361 3362 3363 3364 3365 3366 3367 3368 3369 3370
static void redo_bmc_reg(struct work_struct *work)
{
	ipmi_smi_t intf = container_of(work, struct ipmi_smi, bmc_reg_work);

	if (!intf->in_shutdown)
		bmc_get_device_id(intf, NULL, NULL, NULL, NULL);

	kref_put(&intf->refcount, intf_free);
}

3371
int ipmi_register_smi(const struct ipmi_smi_handlers *handlers,
L
Linus Torvalds 已提交
3372
		      void		       *send_info,
3373
		      struct device            *si_dev,
3374
		      unsigned char            slave_addr)
L
Linus Torvalds 已提交
3375 3376 3377
{
	int              i, j;
	int              rv;
3378
	ipmi_smi_t       intf;
3379 3380
	ipmi_smi_t       tintf;
	struct list_head *link;
3381
	struct ipmi_device_id id;
L
Linus Torvalds 已提交
3382

3383 3384 3385 3386
	/*
	 * Make sure the driver is actually initialized, this handles
	 * problems with initialization order.
	 */
L
Linus Torvalds 已提交
3387 3388 3389 3390
	if (!initialized) {
		rv = ipmi_init_msghandler();
		if (rv)
			return rv;
3391 3392 3393 3394
		/*
		 * The init code doesn't return an error if it was turned
		 * off, but it won't initialize.  Check that.
		 */
L
Linus Torvalds 已提交
3395 3396 3397 3398
		if (!initialized)
			return -ENODEV;
	}

3399
	intf = kzalloc(sizeof(*intf), GFP_KERNEL);
3400
	if (!intf)
L
Linus Torvalds 已提交
3401
		return -ENOMEM;
3402

3403
	intf->bmc = &intf->tmp_bmc;
3404
	INIT_LIST_HEAD(&intf->bmc->intfs);
3405 3406 3407
	mutex_init(&intf->bmc->dyn_mutex);
	INIT_LIST_HEAD(&intf->bmc_link);
	mutex_init(&intf->bmc_reg_mutex);
3408
	intf->intf_num = -1; /* Mark it invalid for now. */
3409
	kref_init(&intf->refcount);
3410
	INIT_WORK(&intf->bmc_reg_work, redo_bmc_reg);
3411
	intf->si_dev = si_dev;
3412
	for (j = 0; j < IPMI_MAX_CHANNELS; j++) {
3413 3414
		intf->addrinfo[j].address = IPMI_BMC_SLAVE_ADDR;
		intf->addrinfo[j].lun = 2;
3415 3416
	}
	if (slave_addr != 0)
3417
		intf->addrinfo[0].address = slave_addr;
3418 3419 3420 3421 3422 3423 3424 3425 3426
	INIT_LIST_HEAD(&intf->users);
	intf->handlers = handlers;
	intf->send_info = send_info;
	spin_lock_init(&intf->seq_lock);
	for (j = 0; j < IPMI_IPMB_NUM_SEQ; j++) {
		intf->seq_table[j].inuse = 0;
		intf->seq_table[j].seqid = 0;
	}
	intf->curr_seq = 0;
3427
#ifdef CONFIG_IPMI_PROC_INTERFACE
C
Corey Minyard 已提交
3428
	mutex_init(&intf->proc_entry_lock);
3429
#endif
3430 3431
	spin_lock_init(&intf->waiting_rcv_msgs_lock);
	INIT_LIST_HEAD(&intf->waiting_rcv_msgs);
3432 3433 3434 3435
	tasklet_init(&intf->recv_tasklet,
		     smi_recv_tasklet,
		     (unsigned long) intf);
	atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
3436 3437 3438
	spin_lock_init(&intf->xmit_msgs_lock);
	INIT_LIST_HEAD(&intf->xmit_msgs);
	INIT_LIST_HEAD(&intf->hp_xmit_msgs);
3439
	spin_lock_init(&intf->events_lock);
3440 3441
	atomic_set(&intf->event_waiters, 0);
	intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
3442 3443
	INIT_LIST_HEAD(&intf->waiting_events);
	intf->waiting_events_count = 0;
3444
	mutex_init(&intf->cmd_rcvrs_mutex);
C
Corey Minyard 已提交
3445
	spin_lock_init(&intf->maintenance_mode_lock);
3446 3447
	INIT_LIST_HEAD(&intf->cmd_rcvrs);
	init_waitqueue_head(&intf->waitq);
3448 3449
	for (i = 0; i < IPMI_NUM_STATS; i++)
		atomic_set(&intf->stats[i], 0);
3450

3451
#ifdef CONFIG_IPMI_PROC_INTERFACE
3452
	intf->proc_dir = NULL;
3453
#endif
L
Linus Torvalds 已提交
3454

3455
	mutex_lock(&smi_watchers_mutex);
3456 3457 3458 3459 3460 3461 3462
	mutex_lock(&ipmi_interfaces_mutex);
	/* Look for a hole in the numbers. */
	i = 0;
	link = &ipmi_interfaces;
	list_for_each_entry_rcu(tintf, &ipmi_interfaces, link) {
		if (tintf->intf_num != i) {
			link = &tintf->link;
L
Linus Torvalds 已提交
3463 3464
			break;
		}
3465
		i++;
L
Linus Torvalds 已提交
3466
	}
3467 3468 3469 3470 3471
	/* Add the new interface in numeric order. */
	if (i == 0)
		list_add_rcu(&intf->link, &ipmi_interfaces);
	else
		list_add_tail_rcu(&intf->link, link);
L
Linus Torvalds 已提交
3472

3473 3474 3475
	rv = handlers->start_processing(send_info, intf);
	if (rv)
		goto out;
L
Linus Torvalds 已提交
3476

3477
	rv = __bmc_get_device_id(intf, NULL, &id, NULL, NULL, i);
3478 3479 3480 3481 3482
	if (rv) {
		dev_err(si_dev, "Unable to get the device id: %d\n", rv);
		goto out;
	}

3483 3484 3485 3486 3487
	mutex_lock(&intf->bmc_reg_mutex);
	rv = __scan_channels(intf, &id);
	mutex_unlock(&intf->bmc_reg_mutex);
	if (rv)
		goto out;
L
Linus Torvalds 已提交
3488

3489
#ifdef CONFIG_IPMI_PROC_INTERFACE
C
Corey Minyard 已提交
3490
	rv = add_proc_entries(intf, i);
3491
#endif
L
Linus Torvalds 已提交
3492

3493
 out:
L
Linus Torvalds 已提交
3494
	if (rv) {
C
Corey Minyard 已提交
3495
		ipmi_bmc_unregister(intf);
3496
#ifdef CONFIG_IPMI_PROC_INTERFACE
3497 3498
		if (intf->proc_dir)
			remove_proc_entries(intf);
3499
#endif
3500
		intf->handlers = NULL;
3501 3502
		list_del_rcu(&intf->link);
		mutex_unlock(&ipmi_interfaces_mutex);
3503
		mutex_unlock(&smi_watchers_mutex);
3504
		synchronize_rcu();
3505 3506
		kref_put(&intf->refcount, intf_free);
	} else {
3507 3508 3509 3510 3511 3512
		/*
		 * Keep memory order straight for RCU readers.  Make
		 * sure everything else is committed to memory before
		 * setting intf_num to mark the interface valid.
		 */
		smp_wmb();
3513 3514
		intf->intf_num = i;
		mutex_unlock(&ipmi_interfaces_mutex);
3515
		/* After this point the interface is legal to use. */
3516
		call_smi_watchers(i, intf->si_dev);
3517
		mutex_unlock(&smi_watchers_mutex);
L
Linus Torvalds 已提交
3518 3519 3520 3521
	}

	return rv;
}
3522
EXPORT_SYMBOL(ipmi_register_smi);
L
Linus Torvalds 已提交
3523

3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535
static void deliver_smi_err_response(ipmi_smi_t intf,
				     struct ipmi_smi_msg *msg,
				     unsigned char err)
{
	msg->rsp[0] = msg->data[0] | 4;
	msg->rsp[1] = msg->data[1];
	msg->rsp[2] = err;
	msg->rsp_size = 3;
	/* It's an error, so it will never requeue, no need to check return. */
	handle_one_recv_msg(intf, msg);
}

3536 3537 3538 3539
static void cleanup_smi_msgs(ipmi_smi_t intf)
{
	int              i;
	struct seq_table *ent;
3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553
	struct ipmi_smi_msg *msg;
	struct list_head *entry;
	struct list_head tmplist;

	/* Clear out our transmit queues and hold the messages. */
	INIT_LIST_HEAD(&tmplist);
	list_splice_tail(&intf->hp_xmit_msgs, &tmplist);
	list_splice_tail(&intf->xmit_msgs, &tmplist);

	/* Current message first, to preserve order */
	while (intf->curr_msg && !list_empty(&intf->waiting_rcv_msgs)) {
		/* Wait for the message to clear out. */
		schedule_timeout(1);
	}
3554 3555

	/* No need for locks, the interface is down. */
3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567

	/*
	 * Return errors for all pending messages in queue and in the
	 * tables waiting for remote responses.
	 */
	while (!list_empty(&tmplist)) {
		entry = tmplist.next;
		list_del(entry);
		msg = list_entry(entry, struct ipmi_smi_msg, link);
		deliver_smi_err_response(intf, msg, IPMI_ERR_UNSPECIFIED);
	}

3568 3569 3570 3571 3572 3573 3574 3575
	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++) {
		ent = &(intf->seq_table[i]);
		if (!ent->inuse)
			continue;
		deliver_err_response(ent->recv_msg, IPMI_ERR_UNSPECIFIED);
	}
}

L
Linus Torvalds 已提交
3576 3577 3578
int ipmi_unregister_smi(ipmi_smi_t intf)
{
	struct ipmi_smi_watcher *w;
3579 3580
	int intf_num = intf->intf_num;
	ipmi_user_t user;
L
Linus Torvalds 已提交
3581

3582
	mutex_lock(&smi_watchers_mutex);
3583
	mutex_lock(&ipmi_interfaces_mutex);
3584
	intf->intf_num = -1;
3585
	intf->in_shutdown = true;
3586 3587 3588
	list_del_rcu(&intf->link);
	mutex_unlock(&ipmi_interfaces_mutex);
	synchronize_rcu();
L
Linus Torvalds 已提交
3589

3590 3591
	cleanup_smi_msgs(intf);

3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603
	/* Clean up the effects of users on the lower-level software. */
	mutex_lock(&ipmi_interfaces_mutex);
	rcu_read_lock();
	list_for_each_entry_rcu(user, &intf->users, link) {
		module_put(intf->handlers->owner);
		if (intf->handlers->dec_usecount)
			intf->handlers->dec_usecount(intf->send_info);
	}
	rcu_read_unlock();
	intf->handlers = NULL;
	mutex_unlock(&ipmi_interfaces_mutex);

3604
#ifdef CONFIG_IPMI_PROC_INTERFACE
3605
	remove_proc_entries(intf);
3606
#endif
3607
	ipmi_bmc_unregister(intf);
L
Linus Torvalds 已提交
3608

3609 3610 3611 3612
	/*
	 * Call all the watcher interfaces to tell them that
	 * an interface is gone.
	 */
3613
	list_for_each_entry(w, &smi_watchers, link)
3614 3615
		w->smi_gone(intf_num);
	mutex_unlock(&smi_watchers_mutex);
3616 3617

	kref_put(&intf->refcount, intf_free);
L
Linus Torvalds 已提交
3618 3619
	return 0;
}
3620
EXPORT_SYMBOL(ipmi_unregister_smi);
L
Linus Torvalds 已提交
3621 3622 3623 3624 3625 3626 3627

static int handle_ipmb_get_msg_rsp(ipmi_smi_t          intf,
				   struct ipmi_smi_msg *msg)
{
	struct ipmi_ipmb_addr ipmb_addr;
	struct ipmi_recv_msg  *recv_msg;

3628 3629 3630 3631
	/*
	 * This is 11, not 10, because the response must contain a
	 * completion code.
	 */
L
Linus Torvalds 已提交
3632 3633
	if (msg->rsp_size < 11) {
		/* Message not big enough, just ignore it. */
3634
		ipmi_inc_stat(intf, invalid_ipmb_responses);
L
Linus Torvalds 已提交
3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647
		return 0;
	}

	if (msg->rsp[2] != 0) {
		/* An error getting the response, just ignore it. */
		return 0;
	}

	ipmb_addr.addr_type = IPMI_IPMB_ADDR_TYPE;
	ipmb_addr.slave_addr = msg->rsp[6];
	ipmb_addr.channel = msg->rsp[3] & 0x0f;
	ipmb_addr.lun = msg->rsp[7] & 3;

3648 3649 3650 3651
	/*
	 * It's a response from a remote entity.  Look up the sequence
	 * number and handle the response.
	 */
L
Linus Torvalds 已提交
3652 3653 3654 3655 3656 3657
	if (intf_find_seq(intf,
			  msg->rsp[7] >> 2,
			  msg->rsp[3] & 0x0f,
			  msg->rsp[8],
			  (msg->rsp[4] >> 2) & (~1),
			  (struct ipmi_addr *) &(ipmb_addr),
3658 3659 3660 3661 3662
			  &recv_msg)) {
		/*
		 * We were unable to find the sequence number,
		 * so just nuke the message.
		 */
3663
		ipmi_inc_stat(intf, unhandled_ipmb_responses);
L
Linus Torvalds 已提交
3664 3665 3666 3667 3668 3669
		return 0;
	}

	memcpy(recv_msg->msg_data,
	       &(msg->rsp[9]),
	       msg->rsp_size - 9);
3670 3671 3672 3673 3674
	/*
	 * The other fields matched, so no need to set them, except
	 * for netfn, which needs to be the response that was
	 * returned, not the request value.
	 */
L
Linus Torvalds 已提交
3675 3676 3677 3678
	recv_msg->msg.netfn = msg->rsp[4] >> 2;
	recv_msg->msg.data = recv_msg->msg_data;
	recv_msg->msg.data_len = msg->rsp_size - 10;
	recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
3679
	ipmi_inc_stat(intf, handled_ipmb_responses);
L
Linus Torvalds 已提交
3680 3681 3682 3683 3684 3685 3686 3687
	deliver_response(recv_msg);

	return 0;
}

static int handle_ipmb_get_msg_cmd(ipmi_smi_t          intf,
				   struct ipmi_smi_msg *msg)
{
3688 3689 3690 3691
	struct cmd_rcvr          *rcvr;
	int                      rv = 0;
	unsigned char            netfn;
	unsigned char            cmd;
3692
	unsigned char            chan;
3693 3694 3695
	ipmi_user_t              user = NULL;
	struct ipmi_ipmb_addr    *ipmb_addr;
	struct ipmi_recv_msg     *recv_msg;
L
Linus Torvalds 已提交
3696 3697 3698

	if (msg->rsp_size < 10) {
		/* Message not big enough, just ignore it. */
3699
		ipmi_inc_stat(intf, invalid_commands);
L
Linus Torvalds 已提交
3700 3701 3702 3703 3704 3705 3706 3707 3708 3709
		return 0;
	}

	if (msg->rsp[2] != 0) {
		/* An error getting the response, just ignore it. */
		return 0;
	}

	netfn = msg->rsp[4] >> 2;
	cmd = msg->rsp[8];
3710
	chan = msg->rsp[3] & 0xf;
L
Linus Torvalds 已提交
3711

3712
	rcu_read_lock();
3713
	rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
3714 3715 3716 3717 3718
	if (rcvr) {
		user = rcvr->user;
		kref_get(&user->refcount);
	} else
		user = NULL;
3719
	rcu_read_unlock();
L
Linus Torvalds 已提交
3720 3721 3722

	if (user == NULL) {
		/* We didn't find a user, deliver an error response. */
3723
		ipmi_inc_stat(intf, unhandled_commands);
L
Linus Torvalds 已提交
3724 3725 3726 3727 3728

		msg->data[0] = (IPMI_NETFN_APP_REQUEST << 2);
		msg->data[1] = IPMI_SEND_MSG_CMD;
		msg->data[2] = msg->rsp[3];
		msg->data[3] = msg->rsp[6];
3729
		msg->data[4] = ((netfn + 1) << 2) | (msg->rsp[7] & 0x3);
L
Linus Torvalds 已提交
3730
		msg->data[5] = ipmb_checksum(&(msg->data[3]), 2);
3731
		msg->data[6] = intf->addrinfo[msg->rsp[3] & 0xf].address;
3732 3733
		/* rqseq/lun */
		msg->data[7] = (msg->rsp[7] & 0xfc) | (msg->rsp[4] & 0x3);
L
Linus Torvalds 已提交
3734 3735 3736 3737 3738 3739 3740 3741 3742
		msg->data[8] = msg->rsp[8]; /* cmd */
		msg->data[9] = IPMI_INVALID_CMD_COMPLETION_CODE;
		msg->data[10] = ipmb_checksum(&(msg->data[6]), 4);
		msg->data_size = 11;

#ifdef DEBUG_MSGING
	{
		int m;
		printk("Invalid command:");
C
Corey Minyard 已提交
3743
		for (m = 0; m < msg->data_size; m++)
L
Linus Torvalds 已提交
3744 3745 3746 3747
			printk(" %2.2x", msg->data[m]);
		printk("\n");
	}
#endif
3748
		rcu_read_lock();
3749 3750
		if (!intf->in_shutdown) {
			smi_send(intf, intf->handlers, msg, 0);
3751 3752 3753 3754 3755
			/*
			 * We used the message, so return the value
			 * that causes it to not be freed or
			 * queued.
			 */
3756 3757 3758
			rv = -1;
		}
		rcu_read_unlock();
L
Linus Torvalds 已提交
3759 3760
	} else {
		/* Deliver the message to the user. */
3761
		ipmi_inc_stat(intf, handled_commands);
L
Linus Torvalds 已提交
3762 3763

		recv_msg = ipmi_alloc_recv_msg();
3764
		if (!recv_msg) {
3765 3766 3767 3768 3769
			/*
			 * We couldn't allocate memory for the
			 * message, so requeue it for handling
			 * later.
			 */
L
Linus Torvalds 已提交
3770
			rv = 1;
3771
			kref_put(&user->refcount, free_user);
L
Linus Torvalds 已提交
3772 3773 3774 3775 3776 3777 3778 3779
		} else {
			/* Extract the source address from the data. */
			ipmb_addr = (struct ipmi_ipmb_addr *) &recv_msg->addr;
			ipmb_addr->addr_type = IPMI_IPMB_ADDR_TYPE;
			ipmb_addr->slave_addr = msg->rsp[6];
			ipmb_addr->lun = msg->rsp[7] & 3;
			ipmb_addr->channel = msg->rsp[3] & 0xf;

3780 3781 3782 3783
			/*
			 * Extract the rest of the message information
			 * from the IPMB header.
			 */
L
Linus Torvalds 已提交
3784 3785 3786 3787 3788 3789 3790
			recv_msg->user = user;
			recv_msg->recv_type = IPMI_CMD_RECV_TYPE;
			recv_msg->msgid = msg->rsp[7] >> 2;
			recv_msg->msg.netfn = msg->rsp[4] >> 2;
			recv_msg->msg.cmd = msg->rsp[8];
			recv_msg->msg.data = recv_msg->msg_data;

3791 3792 3793 3794
			/*
			 * We chop off 10, not 9 bytes because the checksum
			 * at the end also needs to be removed.
			 */
L
Linus Torvalds 已提交
3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812
			recv_msg->msg.data_len = msg->rsp_size - 10;
			memcpy(recv_msg->msg_data,
			       &(msg->rsp[9]),
			       msg->rsp_size - 10);
			deliver_response(recv_msg);
		}
	}

	return rv;
}

static int handle_lan_get_msg_rsp(ipmi_smi_t          intf,
				  struct ipmi_smi_msg *msg)
{
	struct ipmi_lan_addr  lan_addr;
	struct ipmi_recv_msg  *recv_msg;


3813 3814 3815 3816
	/*
	 * This is 13, not 12, because the response must contain a
	 * completion code.
	 */
L
Linus Torvalds 已提交
3817 3818
	if (msg->rsp_size < 13) {
		/* Message not big enough, just ignore it. */
3819
		ipmi_inc_stat(intf, invalid_lan_responses);
L
Linus Torvalds 已提交
3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835
		return 0;
	}

	if (msg->rsp[2] != 0) {
		/* An error getting the response, just ignore it. */
		return 0;
	}

	lan_addr.addr_type = IPMI_LAN_ADDR_TYPE;
	lan_addr.session_handle = msg->rsp[4];
	lan_addr.remote_SWID = msg->rsp[8];
	lan_addr.local_SWID = msg->rsp[5];
	lan_addr.channel = msg->rsp[3] & 0x0f;
	lan_addr.privilege = msg->rsp[3] >> 4;
	lan_addr.lun = msg->rsp[9] & 3;

3836 3837 3838 3839
	/*
	 * It's a response from a remote entity.  Look up the sequence
	 * number and handle the response.
	 */
L
Linus Torvalds 已提交
3840 3841 3842 3843 3844 3845
	if (intf_find_seq(intf,
			  msg->rsp[9] >> 2,
			  msg->rsp[3] & 0x0f,
			  msg->rsp[10],
			  (msg->rsp[6] >> 2) & (~1),
			  (struct ipmi_addr *) &(lan_addr),
3846 3847 3848 3849 3850
			  &recv_msg)) {
		/*
		 * We were unable to find the sequence number,
		 * so just nuke the message.
		 */
3851
		ipmi_inc_stat(intf, unhandled_lan_responses);
L
Linus Torvalds 已提交
3852 3853 3854 3855 3856 3857
		return 0;
	}

	memcpy(recv_msg->msg_data,
	       &(msg->rsp[11]),
	       msg->rsp_size - 11);
3858 3859 3860 3861 3862
	/*
	 * The other fields matched, so no need to set them, except
	 * for netfn, which needs to be the response that was
	 * returned, not the request value.
	 */
L
Linus Torvalds 已提交
3863 3864 3865 3866
	recv_msg->msg.netfn = msg->rsp[6] >> 2;
	recv_msg->msg.data = recv_msg->msg_data;
	recv_msg->msg.data_len = msg->rsp_size - 12;
	recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
3867
	ipmi_inc_stat(intf, handled_lan_responses);
L
Linus Torvalds 已提交
3868 3869 3870 3871 3872 3873 3874 3875
	deliver_response(recv_msg);

	return 0;
}

static int handle_lan_get_msg_cmd(ipmi_smi_t          intf,
				  struct ipmi_smi_msg *msg)
{
3876 3877 3878 3879
	struct cmd_rcvr          *rcvr;
	int                      rv = 0;
	unsigned char            netfn;
	unsigned char            cmd;
3880
	unsigned char            chan;
3881 3882 3883
	ipmi_user_t              user = NULL;
	struct ipmi_lan_addr     *lan_addr;
	struct ipmi_recv_msg     *recv_msg;
L
Linus Torvalds 已提交
3884 3885 3886

	if (msg->rsp_size < 12) {
		/* Message not big enough, just ignore it. */
3887
		ipmi_inc_stat(intf, invalid_commands);
L
Linus Torvalds 已提交
3888 3889 3890 3891 3892 3893 3894 3895 3896 3897
		return 0;
	}

	if (msg->rsp[2] != 0) {
		/* An error getting the response, just ignore it. */
		return 0;
	}

	netfn = msg->rsp[6] >> 2;
	cmd = msg->rsp[10];
3898
	chan = msg->rsp[3] & 0xf;
L
Linus Torvalds 已提交
3899

3900
	rcu_read_lock();
3901
	rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
3902 3903 3904 3905 3906
	if (rcvr) {
		user = rcvr->user;
		kref_get(&user->refcount);
	} else
		user = NULL;
3907
	rcu_read_unlock();
L
Linus Torvalds 已提交
3908 3909

	if (user == NULL) {
3910
		/* We didn't find a user, just give up. */
3911
		ipmi_inc_stat(intf, unhandled_commands);
L
Linus Torvalds 已提交
3912

3913 3914 3915 3916 3917
		/*
		 * Don't do anything with these messages, just allow
		 * them to be freed.
		 */
		rv = 0;
L
Linus Torvalds 已提交
3918 3919
	} else {
		/* Deliver the message to the user. */
3920
		ipmi_inc_stat(intf, handled_commands);
L
Linus Torvalds 已提交
3921 3922

		recv_msg = ipmi_alloc_recv_msg();
3923
		if (!recv_msg) {
3924 3925 3926 3927
			/*
			 * We couldn't allocate memory for the
			 * message, so requeue it for handling later.
			 */
L
Linus Torvalds 已提交
3928
			rv = 1;
3929
			kref_put(&user->refcount, free_user);
L
Linus Torvalds 已提交
3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940
		} else {
			/* Extract the source address from the data. */
			lan_addr = (struct ipmi_lan_addr *) &recv_msg->addr;
			lan_addr->addr_type = IPMI_LAN_ADDR_TYPE;
			lan_addr->session_handle = msg->rsp[4];
			lan_addr->remote_SWID = msg->rsp[8];
			lan_addr->local_SWID = msg->rsp[5];
			lan_addr->lun = msg->rsp[9] & 3;
			lan_addr->channel = msg->rsp[3] & 0xf;
			lan_addr->privilege = msg->rsp[3] >> 4;

3941 3942 3943 3944
			/*
			 * Extract the rest of the message information
			 * from the IPMB header.
			 */
L
Linus Torvalds 已提交
3945 3946 3947 3948 3949 3950 3951
			recv_msg->user = user;
			recv_msg->recv_type = IPMI_CMD_RECV_TYPE;
			recv_msg->msgid = msg->rsp[9] >> 2;
			recv_msg->msg.netfn = msg->rsp[6] >> 2;
			recv_msg->msg.cmd = msg->rsp[10];
			recv_msg->msg.data = recv_msg->msg_data;

3952 3953 3954 3955
			/*
			 * We chop off 12, not 11 bytes because the checksum
			 * at the end also needs to be removed.
			 */
L
Linus Torvalds 已提交
3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966
			recv_msg->msg.data_len = msg->rsp_size - 12;
			memcpy(recv_msg->msg_data,
			       &(msg->rsp[11]),
			       msg->rsp_size - 12);
			deliver_response(recv_msg);
		}
	}

	return rv;
}

D
dann frazier 已提交
3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074
/*
 * This routine will handle "Get Message" command responses with
 * channels that use an OEM Medium. The message format belongs to
 * the OEM.  See IPMI 2.0 specification, Chapter 6 and
 * Chapter 22, sections 22.6 and 22.24 for more details.
 */
static int handle_oem_get_msg_cmd(ipmi_smi_t          intf,
				  struct ipmi_smi_msg *msg)
{
	struct cmd_rcvr       *rcvr;
	int                   rv = 0;
	unsigned char         netfn;
	unsigned char         cmd;
	unsigned char         chan;
	ipmi_user_t           user = NULL;
	struct ipmi_system_interface_addr *smi_addr;
	struct ipmi_recv_msg  *recv_msg;

	/*
	 * We expect the OEM SW to perform error checking
	 * so we just do some basic sanity checks
	 */
	if (msg->rsp_size < 4) {
		/* Message not big enough, just ignore it. */
		ipmi_inc_stat(intf, invalid_commands);
		return 0;
	}

	if (msg->rsp[2] != 0) {
		/* An error getting the response, just ignore it. */
		return 0;
	}

	/*
	 * This is an OEM Message so the OEM needs to know how
	 * handle the message. We do no interpretation.
	 */
	netfn = msg->rsp[0] >> 2;
	cmd = msg->rsp[1];
	chan = msg->rsp[3] & 0xf;

	rcu_read_lock();
	rcvr = find_cmd_rcvr(intf, netfn, cmd, chan);
	if (rcvr) {
		user = rcvr->user;
		kref_get(&user->refcount);
	} else
		user = NULL;
	rcu_read_unlock();

	if (user == NULL) {
		/* We didn't find a user, just give up. */
		ipmi_inc_stat(intf, unhandled_commands);

		/*
		 * Don't do anything with these messages, just allow
		 * them to be freed.
		 */

		rv = 0;
	} else {
		/* Deliver the message to the user. */
		ipmi_inc_stat(intf, handled_commands);

		recv_msg = ipmi_alloc_recv_msg();
		if (!recv_msg) {
			/*
			 * We couldn't allocate memory for the
			 * message, so requeue it for handling
			 * later.
			 */
			rv = 1;
			kref_put(&user->refcount, free_user);
		} else {
			/*
			 * OEM Messages are expected to be delivered via
			 * the system interface to SMS software.  We might
			 * need to visit this again depending on OEM
			 * requirements
			 */
			smi_addr = ((struct ipmi_system_interface_addr *)
				    &(recv_msg->addr));
			smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
			smi_addr->channel = IPMI_BMC_CHANNEL;
			smi_addr->lun = msg->rsp[0] & 3;

			recv_msg->user = user;
			recv_msg->user_msg_data = NULL;
			recv_msg->recv_type = IPMI_OEM_RECV_TYPE;
			recv_msg->msg.netfn = msg->rsp[0] >> 2;
			recv_msg->msg.cmd = msg->rsp[1];
			recv_msg->msg.data = recv_msg->msg_data;

			/*
			 * The message starts at byte 4 which follows the
			 * the Channel Byte in the "GET MESSAGE" command
			 */
			recv_msg->msg.data_len = msg->rsp_size - 4;
			memcpy(recv_msg->msg_data,
			       &(msg->rsp[4]),
			       msg->rsp_size - 4);
			deliver_response(recv_msg);
		}
	}

	return rv;
}

L
Linus Torvalds 已提交
4075 4076 4077 4078
static void copy_event_into_recv_msg(struct ipmi_recv_msg *recv_msg,
				     struct ipmi_smi_msg  *msg)
{
	struct ipmi_system_interface_addr *smi_addr;
4079

L
Linus Torvalds 已提交
4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104
	recv_msg->msgid = 0;
	smi_addr = (struct ipmi_system_interface_addr *) &(recv_msg->addr);
	smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	smi_addr->channel = IPMI_BMC_CHANNEL;
	smi_addr->lun = msg->rsp[0] & 3;
	recv_msg->recv_type = IPMI_ASYNC_EVENT_RECV_TYPE;
	recv_msg->msg.netfn = msg->rsp[0] >> 2;
	recv_msg->msg.cmd = msg->rsp[1];
	memcpy(recv_msg->msg_data, &(msg->rsp[3]), msg->rsp_size - 3);
	recv_msg->msg.data = recv_msg->msg_data;
	recv_msg->msg.data_len = msg->rsp_size - 3;
}

static int handle_read_event_rsp(ipmi_smi_t          intf,
				 struct ipmi_smi_msg *msg)
{
	struct ipmi_recv_msg *recv_msg, *recv_msg2;
	struct list_head     msgs;
	ipmi_user_t          user;
	int                  rv = 0;
	int                  deliver_count = 0;
	unsigned long        flags;

	if (msg->rsp_size < 19) {
		/* Message is too small to be an IPMB event. */
4105
		ipmi_inc_stat(intf, invalid_events);
L
Linus Torvalds 已提交
4106 4107 4108 4109 4110 4111 4112 4113 4114 4115
		return 0;
	}

	if (msg->rsp[2] != 0) {
		/* An error getting the event, just ignore it. */
		return 0;
	}

	INIT_LIST_HEAD(&msgs);

4116
	spin_lock_irqsave(&intf->events_lock, flags);
L
Linus Torvalds 已提交
4117

4118
	ipmi_inc_stat(intf, events);
L
Linus Torvalds 已提交
4119

4120 4121 4122 4123
	/*
	 * Allocate and fill in one message for every user that is
	 * getting events.
	 */
4124 4125
	rcu_read_lock();
	list_for_each_entry_rcu(user, &intf->users, link) {
4126
		if (!user->gets_events)
L
Linus Torvalds 已提交
4127 4128 4129
			continue;

		recv_msg = ipmi_alloc_recv_msg();
4130
		if (!recv_msg) {
4131
			rcu_read_unlock();
4132 4133
			list_for_each_entry_safe(recv_msg, recv_msg2, &msgs,
						 link) {
L
Linus Torvalds 已提交
4134 4135 4136
				list_del(&recv_msg->link);
				ipmi_free_recv_msg(recv_msg);
			}
4137 4138 4139 4140 4141
			/*
			 * We couldn't allocate memory for the
			 * message, so requeue it for handling
			 * later.
			 */
L
Linus Torvalds 已提交
4142 4143 4144 4145 4146 4147 4148 4149
			rv = 1;
			goto out;
		}

		deliver_count++;

		copy_event_into_recv_msg(recv_msg, msg);
		recv_msg->user = user;
4150
		kref_get(&user->refcount);
L
Linus Torvalds 已提交
4151 4152
		list_add_tail(&(recv_msg->link), &msgs);
	}
4153
	rcu_read_unlock();
L
Linus Torvalds 已提交
4154 4155 4156 4157 4158 4159 4160 4161

	if (deliver_count) {
		/* Now deliver all the messages. */
		list_for_each_entry_safe(recv_msg, recv_msg2, &msgs, link) {
			list_del(&recv_msg->link);
			deliver_response(recv_msg);
		}
	} else if (intf->waiting_events_count < MAX_EVENTS_IN_QUEUE) {
4162 4163 4164 4165
		/*
		 * No one to receive the message, put it in queue if there's
		 * not already too many things in the queue.
		 */
L
Linus Torvalds 已提交
4166
		recv_msg = ipmi_alloc_recv_msg();
4167
		if (!recv_msg) {
4168 4169 4170 4171 4172
			/*
			 * We couldn't allocate memory for the
			 * message, so requeue it for handling
			 * later.
			 */
L
Linus Torvalds 已提交
4173 4174 4175 4176 4177 4178
			rv = 1;
			goto out;
		}

		copy_event_into_recv_msg(recv_msg, msg);
		list_add_tail(&(recv_msg->link), &(intf->waiting_events));
4179
		intf->waiting_events_count++;
4180
	} else if (!intf->event_msg_printed) {
4181 4182 4183 4184
		/*
		 * There's too many things in the queue, discard this
		 * message.
		 */
4185 4186
		dev_warn(intf->si_dev,
			 PFX "Event queue full, discarding incoming events\n");
4187
		intf->event_msg_printed = 1;
L
Linus Torvalds 已提交
4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199
	}

 out:
	spin_unlock_irqrestore(&(intf->events_lock), flags);

	return rv;
}

static int handle_bmc_rsp(ipmi_smi_t          intf,
			  struct ipmi_smi_msg *msg)
{
	struct ipmi_recv_msg *recv_msg;
4200
	struct ipmi_user     *user;
L
Linus Torvalds 已提交
4201 4202

	recv_msg = (struct ipmi_recv_msg *) msg->user_data;
4203
	if (recv_msg == NULL) {
4204 4205
		dev_warn(intf->si_dev,
			 "IPMI message received with no owner. This could be because of a malformed message, or because of a hardware error.  Contact your hardware vender for assistance\n");
4206 4207
		return 0;
	}
L
Linus Torvalds 已提交
4208

4209
	user = recv_msg->user;
L
Linus Torvalds 已提交
4210
	/* Make sure the user still exists. */
4211
	if (user && !user->valid) {
4212
		/* The user for the message went away, so give up. */
4213
		ipmi_inc_stat(intf, unhandled_local_responses);
L
Linus Torvalds 已提交
4214 4215 4216 4217
		ipmi_free_recv_msg(recv_msg);
	} else {
		struct ipmi_system_interface_addr *smi_addr;

4218
		ipmi_inc_stat(intf, handled_local_responses);
L
Linus Torvalds 已提交
4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238
		recv_msg->recv_type = IPMI_RESPONSE_RECV_TYPE;
		recv_msg->msgid = msg->msgid;
		smi_addr = ((struct ipmi_system_interface_addr *)
			    &(recv_msg->addr));
		smi_addr->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
		smi_addr->channel = IPMI_BMC_CHANNEL;
		smi_addr->lun = msg->rsp[0] & 3;
		recv_msg->msg.netfn = msg->rsp[0] >> 2;
		recv_msg->msg.cmd = msg->rsp[1];
		memcpy(recv_msg->msg_data,
		       &(msg->rsp[2]),
		       msg->rsp_size - 2);
		recv_msg->msg.data = recv_msg->msg_data;
		recv_msg->msg.data_len = msg->rsp_size - 2;
		deliver_response(recv_msg);
	}

	return 0;
}

4239
/*
4240
 * Handle a received message.  Return 1 if the message should be requeued,
4241 4242 4243
 * 0 if the message should be freed, or -1 if the message should not
 * be freed or requeued.
 */
4244
static int handle_one_recv_msg(ipmi_smi_t          intf,
L
Linus Torvalds 已提交
4245 4246 4247 4248 4249 4250 4251 4252
			       struct ipmi_smi_msg *msg)
{
	int requeue;
	int chan;

#ifdef DEBUG_MSGING
	int m;
	printk("Recv:");
C
Corey Minyard 已提交
4253
	for (m = 0; m < msg->rsp_size; m++)
L
Linus Torvalds 已提交
4254 4255 4256 4257 4258
		printk(" %2.2x", msg->rsp[m]);
	printk("\n");
#endif
	if (msg->rsp_size < 2) {
		/* Message is too small to be correct. */
4259 4260 4261
		dev_warn(intf->si_dev,
			 PFX "BMC returned to small a message for netfn %x cmd %x, got %d bytes\n",
			 (msg->data[0] >> 2) | 1, msg->data[1], msg->rsp_size);
L
Linus Torvalds 已提交
4262 4263 4264 4265 4266 4267

		/* Generate an error response for the message. */
		msg->rsp[0] = msg->data[0] | (1 << 2);
		msg->rsp[1] = msg->data[1];
		msg->rsp[2] = IPMI_ERR_UNSPECIFIED;
		msg->rsp_size = 3;
4268 4269 4270 4271 4272 4273
	} else if (((msg->rsp[0] >> 2) != ((msg->data[0] >> 2) | 1))
		   || (msg->rsp[1] != msg->data[1])) {
		/*
		 * The NetFN and Command in the response is not even
		 * marginally correct.
		 */
4274 4275 4276 4277
		dev_warn(intf->si_dev,
			 PFX "BMC returned incorrect response, expected netfn %x cmd %x, got netfn %x cmd %x\n",
			 (msg->data[0] >> 2) | 1, msg->data[1],
			 msg->rsp[0] >> 2, msg->rsp[1]);
L
Linus Torvalds 已提交
4278 4279 4280 4281 4282 4283 4284 4285 4286 4287

		/* Generate an error response for the message. */
		msg->rsp[0] = msg->data[0] | (1 << 2);
		msg->rsp[1] = msg->data[1];
		msg->rsp[2] = IPMI_ERR_UNSPECIFIED;
		msg->rsp_size = 3;
	}

	if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
	    && (msg->rsp[1] == IPMI_SEND_MSG_CMD)
4288 4289 4290 4291 4292
	    && (msg->user_data != NULL)) {
		/*
		 * It's a response to a response we sent.  For this we
		 * deliver a send message response to the user.
		 */
4293
		struct ipmi_recv_msg     *recv_msg = msg->user_data;
L
Linus Torvalds 已提交
4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304

		requeue = 0;
		if (msg->rsp_size < 2)
			/* Message is too small to be correct. */
			goto out;

		chan = msg->data[2] & 0x0f;
		if (chan >= IPMI_MAX_CHANNELS)
			/* Invalid channel number */
			goto out;

4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316
		if (!recv_msg)
			goto out;

		/* Make sure the user still exists. */
		if (!recv_msg->user || !recv_msg->user->valid)
			goto out;

		recv_msg->recv_type = IPMI_RESPONSE_RESPONSE_TYPE;
		recv_msg->msg.data = recv_msg->msg_data;
		recv_msg->msg.data_len = 1;
		recv_msg->msg_data[0] = msg->rsp[2];
		deliver_response(recv_msg);
L
Linus Torvalds 已提交
4317
	} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
4318
		   && (msg->rsp[1] == IPMI_GET_MSG_CMD)) {
4319 4320
		struct ipmi_channel   *chans;

L
Linus Torvalds 已提交
4321 4322 4323 4324 4325 4326 4327 4328
		/* It's from the receive queue. */
		chan = msg->rsp[3] & 0xf;
		if (chan >= IPMI_MAX_CHANNELS) {
			/* Invalid channel number */
			requeue = 0;
			goto out;
		}

D
dann frazier 已提交
4329
		/*
C
Corey Minyard 已提交
4330 4331 4332 4333 4334
		 * We need to make sure the channels have been initialized.
		 * The channel_handler routine will set the "curr_channel"
		 * equal to or greater than IPMI_MAX_CHANNELS when all the
		 * channels for this interface have been initialized.
		 */
4335
		if (!intf->channels_ready) {
C
Corey Minyard 已提交
4336
			requeue = 0; /* Throw the message away */
D
dann frazier 已提交
4337 4338 4339
			goto out;
		}

4340 4341 4342
		chans = READ_ONCE(intf->channel_list)->c;

		switch (chans[chan].medium) {
L
Linus Torvalds 已提交
4343 4344
		case IPMI_CHANNEL_MEDIUM_IPMB:
			if (msg->rsp[4] & 0x04) {
4345 4346 4347 4348
				/*
				 * It's a response, so find the
				 * requesting message and send it up.
				 */
L
Linus Torvalds 已提交
4349 4350
				requeue = handle_ipmb_get_msg_rsp(intf, msg);
			} else {
4351 4352 4353 4354
				/*
				 * It's a command to the SMS from some other
				 * entity.  Handle that.
				 */
L
Linus Torvalds 已提交
4355 4356 4357 4358 4359 4360 4361
				requeue = handle_ipmb_get_msg_cmd(intf, msg);
			}
			break;

		case IPMI_CHANNEL_MEDIUM_8023LAN:
		case IPMI_CHANNEL_MEDIUM_ASYNC:
			if (msg->rsp[6] & 0x04) {
4362 4363 4364 4365
				/*
				 * It's a response, so find the
				 * requesting message and send it up.
				 */
L
Linus Torvalds 已提交
4366 4367
				requeue = handle_lan_get_msg_rsp(intf, msg);
			} else {
4368 4369 4370 4371
				/*
				 * It's a command to the SMS from some other
				 * entity.  Handle that.
				 */
L
Linus Torvalds 已提交
4372 4373 4374 4375 4376
				requeue = handle_lan_get_msg_cmd(intf, msg);
			}
			break;

		default:
D
dann frazier 已提交
4377 4378
			/* Check for OEM Channels.  Clients had better
			   register for these commands. */
4379 4380
			if ((chans[chan].medium >= IPMI_CHANNEL_MEDIUM_OEM_MIN)
			    && (chans[chan].medium
D
dann frazier 已提交
4381 4382 4383 4384 4385 4386 4387 4388 4389
				<= IPMI_CHANNEL_MEDIUM_OEM_MAX)) {
				requeue = handle_oem_get_msg_cmd(intf, msg);
			} else {
				/*
				 * We don't handle the channel type, so just
				 * free the message.
				 */
				requeue = 0;
			}
L
Linus Torvalds 已提交
4390 4391 4392
		}

	} else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2))
4393
		   && (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD)) {
4394
		/* It's an asynchronous event. */
L
Linus Torvalds 已提交
4395 4396 4397 4398 4399 4400 4401 4402 4403 4404
		requeue = handle_read_event_rsp(intf, msg);
	} else {
		/* It's a response from the local BMC. */
		requeue = handle_bmc_rsp(intf, msg);
	}

 out:
	return requeue;
}

4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416
/*
 * If there are messages in the queue or pretimeouts, handle them.
 */
static void handle_new_recv_msgs(ipmi_smi_t intf)
{
	struct ipmi_smi_msg  *smi_msg;
	unsigned long        flags = 0;
	int                  rv;
	int                  run_to_completion = intf->run_to_completion;

	/* See if any waiting messages need to be processed. */
	if (!run_to_completion)
4417 4418 4419
		spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags);
	while (!list_empty(&intf->waiting_rcv_msgs)) {
		smi_msg = list_entry(intf->waiting_rcv_msgs.next,
4420
				     struct ipmi_smi_msg, link);
4421
		list_del(&smi_msg->link);
4422
		if (!run_to_completion)
4423 4424
			spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
					       flags);
4425 4426
		rv = handle_one_recv_msg(intf, smi_msg);
		if (!run_to_completion)
4427
			spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags);
4428
		if (rv > 0) {
4429 4430
			/*
			 * To preserve message order, quit if we
4431 4432 4433 4434
			 * can't handle a message.  Add the message
			 * back at the head, this is safe because this
			 * tasklet is the only thing that pulls the
			 * messages.
4435
			 */
4436
			list_add(&smi_msg->link, &intf->waiting_rcv_msgs);
4437
			break;
4438 4439 4440 4441 4442
		} else {
			if (rv == 0)
				/* Message handled */
				ipmi_free_smi_msg(smi_msg);
			/* If rv < 0, fatal error, del but don't free. */
4443 4444 4445
		}
	}
	if (!run_to_completion)
4446
		spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock, flags);
4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466

	/*
	 * If the pretimout count is non-zero, decrement one from it and
	 * deliver pretimeouts to all the users.
	 */
	if (atomic_add_unless(&intf->watchdog_pretimeouts_to_deliver, -1, 0)) {
		ipmi_user_t user;

		rcu_read_lock();
		list_for_each_entry_rcu(user, &intf->users, link) {
			if (user->handler->ipmi_watchdog_pretimeout)
				user->handler->ipmi_watchdog_pretimeout(
					user->handler_data);
		}
		rcu_read_unlock();
	}
}

static void smi_recv_tasklet(unsigned long val)
{
4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478
	unsigned long flags = 0; /* keep us warning-free. */
	ipmi_smi_t intf = (ipmi_smi_t) val;
	int run_to_completion = intf->run_to_completion;
	struct ipmi_smi_msg *newmsg = NULL;

	/*
	 * Start the next message if available.
	 *
	 * Do this here, not in the actual receiver, because we may deadlock
	 * because the lower layer is allowed to hold locks while calling
	 * message delivery.
	 */
4479 4480 4481

	rcu_read_lock();

4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501
	if (!run_to_completion)
		spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
	if (intf->curr_msg == NULL && !intf->in_shutdown) {
		struct list_head *entry = NULL;

		/* Pick the high priority queue first. */
		if (!list_empty(&intf->hp_xmit_msgs))
			entry = intf->hp_xmit_msgs.next;
		else if (!list_empty(&intf->xmit_msgs))
			entry = intf->xmit_msgs.next;

		if (entry) {
			list_del(entry);
			newmsg = list_entry(entry, struct ipmi_smi_msg, link);
			intf->curr_msg = newmsg;
		}
	}
	if (!run_to_completion)
		spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
	if (newmsg)
4502
		intf->handlers->sender(intf->send_info, newmsg);
4503

4504 4505
	rcu_read_unlock();

4506
	handle_new_recv_msgs(intf);
4507 4508
}

L
Linus Torvalds 已提交
4509 4510 4511 4512
/* Handle a new message from the lower layer. */
void ipmi_smi_msg_received(ipmi_smi_t          intf,
			   struct ipmi_smi_msg *msg)
{
4513
	unsigned long flags = 0; /* keep us warning-free. */
4514
	int run_to_completion = intf->run_to_completion;
L
Linus Torvalds 已提交
4515 4516 4517 4518

	if ((msg->data_size >= 2)
	    && (msg->data[0] == (IPMI_NETFN_APP_REQUEST << 2))
	    && (msg->data[1] == IPMI_SEND_MSG_CMD)
4519
	    && (msg->user_data == NULL)) {
4520 4521 4522 4523

		if (intf->in_shutdown)
			goto free_msg;

4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536
		/*
		 * This is the local response to a command send, start
		 * the timer for these.  The user_data will not be
		 * NULL if this is a response send, and we will let
		 * response sends just go through.
		 */

		/*
		 * Check for errors, if we get certain errors (ones
		 * that mean basically we can try again later), we
		 * ignore them and start the timer.  Otherwise we
		 * report the error immediately.
		 */
L
Linus Torvalds 已提交
4537 4538
		if ((msg->rsp_size >= 3) && (msg->rsp[2] != 0)
		    && (msg->rsp[2] != IPMI_NODE_BUSY_ERR)
4539 4540
		    && (msg->rsp[2] != IPMI_LOST_ARBITRATION_ERR)
		    && (msg->rsp[2] != IPMI_BUS_ERR)
4541
		    && (msg->rsp[2] != IPMI_NAK_ON_WRITE_ERR)) {
4542 4543
			int ch = msg->rsp[3] & 0xf;
			struct ipmi_channel *chans;
L
Linus Torvalds 已提交
4544 4545

			/* Got an error sending the message, handle it. */
4546 4547 4548 4549

			chans = READ_ONCE(intf->channel_list)->c;
			if ((chans[ch].medium == IPMI_CHANNEL_MEDIUM_8023LAN)
			    || (chans[ch].medium == IPMI_CHANNEL_MEDIUM_ASYNC))
4550
				ipmi_inc_stat(intf, sent_lan_command_errs);
L
Linus Torvalds 已提交
4551
			else
4552
				ipmi_inc_stat(intf, sent_ipmb_command_errs);
L
Linus Torvalds 已提交
4553
			intf_err_seq(intf, msg->msgid, msg->rsp[2]);
4554
		} else
L
Linus Torvalds 已提交
4555 4556 4557
			/* The message was sent, start the timer. */
			intf_start_seq_timer(intf, msg->msgid);

4558
free_msg:
L
Linus Torvalds 已提交
4559
		ipmi_free_smi_msg(msg);
4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570
	} else {
		/*
		 * To preserve message order, we keep a queue and deliver from
		 * a tasklet.
		 */
		if (!run_to_completion)
			spin_lock_irqsave(&intf->waiting_rcv_msgs_lock, flags);
		list_add_tail(&msg->link, &intf->waiting_rcv_msgs);
		if (!run_to_completion)
			spin_unlock_irqrestore(&intf->waiting_rcv_msgs_lock,
					       flags);
L
Linus Torvalds 已提交
4571 4572
	}

4573
	if (!run_to_completion)
4574
		spin_lock_irqsave(&intf->xmit_msgs_lock, flags);
4575 4576 4577 4578
	/*
	 * We can get an asynchronous event or receive message in addition
	 * to commands we send.
	 */
4579 4580
	if (msg == intf->curr_msg)
		intf->curr_msg = NULL;
4581
	if (!run_to_completion)
4582
		spin_unlock_irqrestore(&intf->xmit_msgs_lock, flags);
4583

4584 4585 4586 4587
	if (run_to_completion)
		smi_recv_tasklet((unsigned long) intf);
	else
		tasklet_schedule(&intf->recv_tasklet);
L
Linus Torvalds 已提交
4588
}
4589
EXPORT_SYMBOL(ipmi_smi_msg_received);
L
Linus Torvalds 已提交
4590 4591 4592

void ipmi_smi_watchdog_pretimeout(ipmi_smi_t intf)
{
4593 4594 4595
	if (intf->in_shutdown)
		return;

4596 4597
	atomic_set(&intf->watchdog_pretimeouts_to_deliver, 1);
	tasklet_schedule(&intf->recv_tasklet);
L
Linus Torvalds 已提交
4598
}
4599
EXPORT_SYMBOL(ipmi_smi_watchdog_pretimeout);
L
Linus Torvalds 已提交
4600

C
Corey Minyard 已提交
4601 4602 4603
static struct ipmi_smi_msg *
smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
		  unsigned char seq, long seqid)
L
Linus Torvalds 已提交
4604
{
C
Corey Minyard 已提交
4605
	struct ipmi_smi_msg *smi_msg = ipmi_alloc_smi_msg();
L
Linus Torvalds 已提交
4606
	if (!smi_msg)
4607 4608 4609 4610
		/*
		 * If we can't allocate the message, then just return, we
		 * get 4 retries, so this should be ok.
		 */
C
Corey Minyard 已提交
4611
		return NULL;
L
Linus Torvalds 已提交
4612 4613 4614 4615

	memcpy(smi_msg->data, recv_msg->msg.data, recv_msg->msg.data_len);
	smi_msg->data_size = recv_msg->msg.data_len;
	smi_msg->msgid = STORE_SEQ_IN_MSGID(seq, seqid);
4616

L
Linus Torvalds 已提交
4617 4618 4619 4620
#ifdef DEBUG_MSGING
	{
		int m;
		printk("Resend: ");
C
Corey Minyard 已提交
4621
		for (m = 0; m < smi_msg->data_size; m++)
L
Linus Torvalds 已提交
4622 4623 4624 4625
			printk(" %2.2x", smi_msg->data[m]);
		printk("\n");
	}
#endif
C
Corey Minyard 已提交
4626
	return smi_msg;
L
Linus Torvalds 已提交
4627 4628
}

4629
static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
4630 4631
			      struct list_head *timeouts,
			      unsigned long timeout_period,
4632 4633
			      int slot, unsigned long *flags,
			      unsigned int *waiting_msgs)
4634
{
4635
	struct ipmi_recv_msg     *msg;
4636
	const struct ipmi_smi_handlers *handlers;
4637

4638
	if (intf->in_shutdown)
4639
		return;
4640 4641 4642 4643

	if (!ent->inuse)
		return;

4644 4645
	if (timeout_period < ent->timeout) {
		ent->timeout -= timeout_period;
4646
		(*waiting_msgs)++;
4647
		return;
4648
	}
4649 4650 4651 4652 4653 4654 4655

	if (ent->retries_left == 0) {
		/* The message has used all its retries. */
		ent->inuse = 0;
		msg = ent->recv_msg;
		list_add_tail(&msg->link, timeouts);
		if (ent->broadcast)
4656
			ipmi_inc_stat(intf, timed_out_ipmb_broadcasts);
4657
		else if (is_lan_addr(&ent->recv_msg->addr))
4658
			ipmi_inc_stat(intf, timed_out_lan_commands);
4659
		else
4660
			ipmi_inc_stat(intf, timed_out_ipmb_commands);
4661 4662 4663 4664
	} else {
		struct ipmi_smi_msg *smi_msg;
		/* More retries, send again. */

4665 4666
		(*waiting_msgs)++;

4667 4668 4669 4670
		/*
		 * Start with the max timer, set to normal timer after
		 * the message is sent.
		 */
4671 4672 4673 4674
		ent->timeout = MAX_MSG_TIMEOUT;
		ent->retries_left--;
		smi_msg = smi_from_recv_msg(intf, ent->recv_msg, slot,
					    ent->seqid);
4675 4676 4677 4678 4679 4680 4681
		if (!smi_msg) {
			if (is_lan_addr(&ent->recv_msg->addr))
				ipmi_inc_stat(intf,
					      dropped_rexmit_lan_commands);
			else
				ipmi_inc_stat(intf,
					      dropped_rexmit_ipmb_commands);
4682
			return;
4683
		}
4684 4685

		spin_unlock_irqrestore(&intf->seq_lock, *flags);
4686

4687 4688 4689 4690 4691 4692 4693
		/*
		 * Send the new message.  We send with a zero
		 * priority.  It timed out, I doubt time is that
		 * critical now, and high priority messages are really
		 * only for messages to the local MC, which don't get
		 * resent.
		 */
4694
		handlers = intf->handlers;
4695 4696 4697 4698 4699 4700 4701 4702
		if (handlers) {
			if (is_lan_addr(&ent->recv_msg->addr))
				ipmi_inc_stat(intf,
					      retransmitted_lan_commands);
			else
				ipmi_inc_stat(intf,
					      retransmitted_ipmb_commands);

4703
			smi_send(intf, handlers, smi_msg, 0);
4704
		} else
4705 4706
			ipmi_free_smi_msg(smi_msg);

4707 4708 4709 4710
		spin_lock_irqsave(&intf->seq_lock, *flags);
	}
}

4711 4712
static unsigned int ipmi_timeout_handler(ipmi_smi_t intf,
					 unsigned long timeout_period)
L
Linus Torvalds 已提交
4713 4714 4715 4716
{
	struct list_head     timeouts;
	struct ipmi_recv_msg *msg, *msg2;
	unsigned long        flags;
4717
	int                  i;
4718
	unsigned int         waiting_msgs = 0;
L
Linus Torvalds 已提交
4719

4720 4721 4722 4723 4724 4725 4726 4727
	if (!intf->bmc_registered) {
		kref_get(&intf->refcount);
		if (!schedule_work(&intf->bmc_reg_work)) {
			kref_put(&intf->refcount, intf_free);
			waiting_msgs++;
		}
	}

4728 4729 4730 4731 4732 4733 4734
	/*
	 * Go through the seq table and find any messages that
	 * have timed out, putting them in the timeouts
	 * list.
	 */
	INIT_LIST_HEAD(&timeouts);
	spin_lock_irqsave(&intf->seq_lock, flags);
4735 4736 4737 4738 4739 4740
	if (intf->ipmb_maintenance_mode_timeout) {
		if (intf->ipmb_maintenance_mode_timeout <= timeout_period)
			intf->ipmb_maintenance_mode_timeout = 0;
		else
			intf->ipmb_maintenance_mode_timeout -= timeout_period;
	}
4741 4742 4743 4744 4745
	for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
		check_msg_timeout(intf, &(intf->seq_table[i]),
				  &timeouts, timeout_period, i,
				  &flags, &waiting_msgs);
	spin_unlock_irqrestore(&intf->seq_lock, flags);
4746

4747 4748
	list_for_each_entry_safe(msg, msg2, &timeouts, link)
		deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
C
Corey Minyard 已提交
4749

4750 4751 4752 4753 4754 4755 4756 4757 4758 4759
	/*
	 * Maintenance mode handling.  Check the timeout
	 * optimistically before we claim the lock.  It may
	 * mean a timeout gets missed occasionally, but that
	 * only means the timeout gets extended by one period
	 * in that case.  No big deal, and it avoids the lock
	 * most of the time.
	 */
	if (intf->auto_maintenance_timeout > 0) {
		spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
C
Corey Minyard 已提交
4760
		if (intf->auto_maintenance_timeout > 0) {
4761 4762 4763 4764
			intf->auto_maintenance_timeout
				-= timeout_period;
			if (!intf->maintenance_mode
			    && (intf->auto_maintenance_timeout <= 0)) {
C
Corey Minyard 已提交
4765
				intf->maintenance_mode_enable = false;
4766
				maintenance_mode_update(intf);
C
Corey Minyard 已提交
4767 4768
			}
		}
4769 4770
		spin_unlock_irqrestore(&intf->maintenance_mode_lock,
				       flags);
L
Linus Torvalds 已提交
4771
	}
4772 4773 4774 4775

	tasklet_schedule(&intf->recv_tasklet);

	return waiting_msgs;
L
Linus Torvalds 已提交
4776 4777
}

4778
static void ipmi_request_event(ipmi_smi_t intf)
L
Linus Torvalds 已提交
4779
{
4780 4781 4782
	/* No event requests when in maintenance mode. */
	if (intf->maintenance_mode_enable)
		return;
C
Corey Minyard 已提交
4783

4784 4785
	if (!intf->in_shutdown)
		intf->handlers->request_events(intf->send_info);
L
Linus Torvalds 已提交
4786 4787 4788 4789
}

static struct timer_list ipmi_timer;

4790
static atomic_t stop_operation;
L
Linus Torvalds 已提交
4791

4792
static void ipmi_timeout(struct timer_list *unused)
L
Linus Torvalds 已提交
4793
{
4794 4795 4796
	ipmi_smi_t intf;
	int nt = 0;

4797
	if (atomic_read(&stop_operation))
L
Linus Torvalds 已提交
4798 4799
		return;

4800 4801 4802 4803 4804 4805 4806 4807 4808 4809 4810 4811 4812 4813
	rcu_read_lock();
	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
		int lnt = 0;

		if (atomic_read(&intf->event_waiters)) {
			intf->ticks_to_req_ev--;
			if (intf->ticks_to_req_ev == 0) {
				ipmi_request_event(intf);
				intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
			}
			lnt++;
		}

		lnt += ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME);
L
Linus Torvalds 已提交
4814

4815 4816 4817 4818 4819
		lnt = !!lnt;
		if (lnt != intf->last_needs_timer &&
					intf->handlers->set_need_watch)
			intf->handlers->set_need_watch(intf->send_info, lnt);
		intf->last_needs_timer = lnt;
L
Linus Torvalds 已提交
4820

4821 4822 4823 4824 4825 4826
		nt += lnt;
	}
	rcu_read_unlock();

	if (nt)
		mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
L
Linus Torvalds 已提交
4827 4828
}

4829 4830 4831 4832 4833 4834
static void need_waiter(ipmi_smi_t intf)
{
	/* Racy, but worst case we start the timer twice. */
	if (!timer_pending(&ipmi_timer))
		mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
}
L
Linus Torvalds 已提交
4835 4836 4837 4838 4839 4840 4841 4842 4843 4844 4845 4846 4847 4848 4849 4850 4851 4852 4853 4854 4855

static atomic_t smi_msg_inuse_count = ATOMIC_INIT(0);
static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0);

static void free_smi_msg(struct ipmi_smi_msg *msg)
{
	atomic_dec(&smi_msg_inuse_count);
	kfree(msg);
}

struct ipmi_smi_msg *ipmi_alloc_smi_msg(void)
{
	struct ipmi_smi_msg *rv;
	rv = kmalloc(sizeof(struct ipmi_smi_msg), GFP_ATOMIC);
	if (rv) {
		rv->done = free_smi_msg;
		rv->user_data = NULL;
		atomic_inc(&smi_msg_inuse_count);
	}
	return rv;
}
4856
EXPORT_SYMBOL(ipmi_alloc_smi_msg);
L
Linus Torvalds 已提交
4857 4858 4859 4860 4861 4862 4863

static void free_recv_msg(struct ipmi_recv_msg *msg)
{
	atomic_dec(&recv_msg_inuse_count);
	kfree(msg);
}

A
Adrian Bunk 已提交
4864
static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void)
L
Linus Torvalds 已提交
4865 4866 4867 4868 4869
{
	struct ipmi_recv_msg *rv;

	rv = kmalloc(sizeof(struct ipmi_recv_msg), GFP_ATOMIC);
	if (rv) {
4870
		rv->user = NULL;
L
Linus Torvalds 已提交
4871 4872 4873 4874 4875 4876
		rv->done = free_recv_msg;
		atomic_inc(&recv_msg_inuse_count);
	}
	return rv;
}

4877 4878 4879 4880 4881 4882
void ipmi_free_recv_msg(struct ipmi_recv_msg *msg)
{
	if (msg->user)
		kref_put(&msg->user->refcount, free_user);
	msg->done(msg);
}
4883
EXPORT_SYMBOL(ipmi_free_recv_msg);
4884

4885 4886
static atomic_t panic_done_count = ATOMIC_INIT(0);

L
Linus Torvalds 已提交
4887 4888
static void dummy_smi_done_handler(struct ipmi_smi_msg *msg)
{
4889
	atomic_dec(&panic_done_count);
L
Linus Torvalds 已提交
4890 4891 4892 4893
}

static void dummy_recv_done_handler(struct ipmi_recv_msg *msg)
{
4894 4895 4896 4897 4898 4899 4900 4901 4902 4903 4904 4905 4906 4907 4908 4909 4910 4911 4912 4913 4914 4915 4916 4917 4918 4919
	atomic_dec(&panic_done_count);
}

/*
 * Inside a panic, send a message and wait for a response.
 */
static void ipmi_panic_request_and_wait(ipmi_smi_t           intf,
					struct ipmi_addr     *addr,
					struct kernel_ipmi_msg *msg)
{
	struct ipmi_smi_msg  smi_msg;
	struct ipmi_recv_msg recv_msg;
	int rv;

	smi_msg.done = dummy_smi_done_handler;
	recv_msg.done = dummy_recv_done_handler;
	atomic_add(2, &panic_done_count);
	rv = i_ipmi_request(NULL,
			    intf,
			    addr,
			    0,
			    msg,
			    intf,
			    &smi_msg,
			    &recv_msg,
			    0,
4920 4921
			    intf->addrinfo[0].address,
			    intf->addrinfo[0].lun,
4922 4923 4924
			    0, 1); /* Don't retry, and don't wait. */
	if (rv)
		atomic_sub(2, &panic_done_count);
4925 4926 4927
	else if (intf->handlers->flush_messages)
		intf->handlers->flush_messages(intf->send_info);

4928 4929
	while (atomic_read(&panic_done_count) != 0)
		ipmi_poll(intf);
L
Linus Torvalds 已提交
4930 4931
}

4932
static void event_receiver_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
L
Linus Torvalds 已提交
4933
{
4934 4935 4936
	if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
	    && (msg->msg.netfn == IPMI_NETFN_SENSOR_EVENT_RESPONSE)
	    && (msg->msg.cmd == IPMI_GET_EVENT_RECEIVER_CMD)
4937
	    && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) {
L
Linus Torvalds 已提交
4938
		/* A get event receiver command, save it. */
4939 4940
		intf->event_receiver = msg->msg.data[1];
		intf->event_receiver_lun = msg->msg.data[2] & 0x3;
L
Linus Torvalds 已提交
4941 4942 4943
	}
}

4944
static void device_id_fetcher(ipmi_smi_t intf, struct ipmi_recv_msg *msg)
L
Linus Torvalds 已提交
4945
{
4946 4947 4948
	if ((msg->addr.addr_type == IPMI_SYSTEM_INTERFACE_ADDR_TYPE)
	    && (msg->msg.netfn == IPMI_NETFN_APP_RESPONSE)
	    && (msg->msg.cmd == IPMI_GET_DEVICE_ID_CMD)
4949 4950 4951 4952 4953
	    && (msg->msg.data[0] == IPMI_CC_NO_ERROR)) {
		/*
		 * A get device id command, save if we are an event
		 * receiver or generator.
		 */
4954 4955
		intf->local_sel_device = (msg->msg.data[6] >> 2) & 1;
		intf->local_event_generator = (msg->msg.data[6] >> 5) & 1;
L
Linus Torvalds 已提交
4956 4957 4958
	}
}

4959
static void send_panic_events(ipmi_smi_t intf, char *str)
L
Linus Torvalds 已提交
4960
{
4961 4962
	struct kernel_ipmi_msg msg;
	unsigned char data[16];
L
Linus Torvalds 已提交
4963
	struct ipmi_system_interface_addr *si;
4964 4965 4966 4967
	struct ipmi_addr addr;
	char *p = str;
	struct ipmi_ipmb_addr *ipmb;
	int j;
L
Linus Torvalds 已提交
4968

4969 4970 4971
	if (ipmi_send_panic_event == IPMI_SEND_PANIC_EVENT_NONE)
		return;

L
Linus Torvalds 已提交
4972 4973 4974 4975 4976 4977 4978 4979 4980 4981
	si = (struct ipmi_system_interface_addr *) &addr;
	si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
	si->channel = IPMI_BMC_CHANNEL;
	si->lun = 0;

	/* Fill in an event telling that we have failed. */
	msg.netfn = 0x04; /* Sensor or Event. */
	msg.cmd = 2; /* Platform event command. */
	msg.data = data;
	msg.data_len = 8;
M
Matt Domsch 已提交
4982
	data[0] = 0x41; /* Kernel generator ID, IPMI table 5-4 */
L
Linus Torvalds 已提交
4983 4984 4985 4986 4987
	data[1] = 0x03; /* This is for IPMI 1.0. */
	data[2] = 0x20; /* OS Critical Stop, IPMI table 36-3 */
	data[4] = 0x6f; /* Sensor specific, IPMI table 36-1 */
	data[5] = 0xa1; /* Runtime stop OEM bytes 2 & 3. */

4988 4989 4990 4991
	/*
	 * Put a few breadcrumbs in.  Hopefully later we can add more things
	 * to make the panic events more useful.
	 */
L
Linus Torvalds 已提交
4992 4993 4994 4995 4996 4997
	if (str) {
		data[3] = str[0];
		data[6] = str[1];
		data[7] = str[2];
	}

4998 4999
	/* Send the event announcing the panic. */
	ipmi_panic_request_and_wait(intf, &addr, &msg);
L
Linus Torvalds 已提交
5000

5001 5002 5003 5004
	/*
	 * On every interface, dump a bunch of OEM event holding the
	 * string.
	 */
5005
	if (ipmi_send_panic_event != IPMI_SEND_PANIC_EVENT_STRING || !str)
L
Linus Torvalds 已提交
5006 5007
		return;

5008 5009 5010 5011 5012 5013 5014
	/*
	 * intf_num is used as an marker to tell if the
	 * interface is valid.  Thus we need a read barrier to
	 * make sure data fetched before checking intf_num
	 * won't be used.
	 */
	smp_rmb();
L
Linus Torvalds 已提交
5015

5016 5017 5018 5019 5020 5021 5022
	/*
	 * First job here is to figure out where to send the
	 * OEM events.  There's no way in IPMI to send OEM
	 * events using an event send command, so we have to
	 * find the SEL to put them in and stick them in
	 * there.
	 */
5023

5024 5025 5026 5027
	/* Get capabilities from the get device id. */
	intf->local_sel_device = 0;
	intf->local_event_generator = 0;
	intf->event_receiver = 0;
L
Linus Torvalds 已提交
5028

5029 5030 5031 5032 5033 5034 5035
	/* Request the device info from the local MC. */
	msg.netfn = IPMI_NETFN_APP_REQUEST;
	msg.cmd = IPMI_GET_DEVICE_ID_CMD;
	msg.data = NULL;
	msg.data_len = 0;
	intf->null_user_handler = device_id_fetcher;
	ipmi_panic_request_and_wait(intf, &addr, &msg);
L
Linus Torvalds 已提交
5036

5037 5038 5039 5040
	if (intf->local_event_generator) {
		/* Request the event receiver from the local MC. */
		msg.netfn = IPMI_NETFN_SENSOR_EVENT_REQUEST;
		msg.cmd = IPMI_GET_EVENT_RECEIVER_CMD;
L
Linus Torvalds 已提交
5041 5042
		msg.data = NULL;
		msg.data_len = 0;
5043
		intf->null_user_handler = event_receiver_fetcher;
5044
		ipmi_panic_request_and_wait(intf, &addr, &msg);
5045 5046
	}
	intf->null_user_handler = NULL;
L
Linus Torvalds 已提交
5047

5048 5049 5050 5051 5052 5053 5054 5055 5056 5057 5058 5059 5060 5061 5062 5063 5064 5065 5066 5067 5068 5069 5070 5071 5072 5073 5074 5075 5076
	/*
	 * Validate the event receiver.  The low bit must not
	 * be 1 (it must be a valid IPMB address), it cannot
	 * be zero, and it must not be my address.
	 */
	if (((intf->event_receiver & 1) == 0)
	    && (intf->event_receiver != 0)
	    && (intf->event_receiver != intf->addrinfo[0].address)) {
		/*
		 * The event receiver is valid, send an IPMB
		 * message.
		 */
		ipmb = (struct ipmi_ipmb_addr *) &addr;
		ipmb->addr_type = IPMI_IPMB_ADDR_TYPE;
		ipmb->channel = 0; /* FIXME - is this right? */
		ipmb->lun = intf->event_receiver_lun;
		ipmb->slave_addr = intf->event_receiver;
	} else if (intf->local_sel_device) {
		/*
		 * The event receiver was not valid (or was
		 * me), but I am an SEL device, just dump it
		 * in my SEL.
		 */
		si = (struct ipmi_system_interface_addr *) &addr;
		si->addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
		si->channel = IPMI_BMC_CHANNEL;
		si->lun = 0;
	} else
		return; /* No where to send the event. */
L
Linus Torvalds 已提交
5077

5078 5079 5080 5081 5082 5083 5084 5085 5086 5087 5088 5089 5090 5091 5092 5093
	msg.netfn = IPMI_NETFN_STORAGE_REQUEST; /* Storage. */
	msg.cmd = IPMI_ADD_SEL_ENTRY_CMD;
	msg.data = data;
	msg.data_len = 16;

	j = 0;
	while (*p) {
		int size = strlen(p);

		if (size > 11)
			size = 11;
		data[0] = 0;
		data[1] = 0;
		data[2] = 0xf0; /* OEM event without timestamp. */
		data[3] = intf->addrinfo[0].address;
		data[4] = j++; /* sequence # */
5094
		/*
5095 5096
		 * Always give 11 bytes, so strncpy will fill
		 * it with zeroes for me.
5097
		 */
5098 5099
		strncpy(data+5, p, 11);
		p += size;
L
Linus Torvalds 已提交
5100

5101
		ipmi_panic_request_and_wait(intf, &addr, &msg);
5102
	}
L
Linus Torvalds 已提交
5103 5104
}

R
Randy Dunlap 已提交
5105
static int has_panicked;
L
Linus Torvalds 已提交
5106 5107 5108

static int panic_event(struct notifier_block *this,
		       unsigned long         event,
5109
		       void                  *ptr)
L
Linus Torvalds 已提交
5110 5111
{
	ipmi_smi_t intf;
5112
	ipmi_user_t user;
L
Linus Torvalds 已提交
5113

L
Lee Revell 已提交
5114
	if (has_panicked)
L
Linus Torvalds 已提交
5115
		return NOTIFY_DONE;
L
Lee Revell 已提交
5116
	has_panicked = 1;
L
Linus Torvalds 已提交
5117 5118

	/* For every registered interface, set it to run to completion. */
5119
	list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
5120
		if (!intf->handlers || intf->intf_num == -1)
5121
			/* Interface is not ready. */
L
Linus Torvalds 已提交
5122 5123
			continue;

5124 5125 5126
		if (!intf->handlers->poll)
			continue;

5127 5128 5129 5130 5131 5132 5133 5134 5135 5136 5137 5138 5139 5140 5141 5142 5143
		/*
		 * If we were interrupted while locking xmit_msgs_lock or
		 * waiting_rcv_msgs_lock, the corresponding list may be
		 * corrupted.  In this case, drop items on the list for
		 * the safety.
		 */
		if (!spin_trylock(&intf->xmit_msgs_lock)) {
			INIT_LIST_HEAD(&intf->xmit_msgs);
			INIT_LIST_HEAD(&intf->hp_xmit_msgs);
		} else
			spin_unlock(&intf->xmit_msgs_lock);

		if (!spin_trylock(&intf->waiting_rcv_msgs_lock))
			INIT_LIST_HEAD(&intf->waiting_rcv_msgs);
		else
			spin_unlock(&intf->waiting_rcv_msgs_lock);

5144
		intf->run_to_completion = 1;
5145 5146 5147
		if (intf->handlers->set_run_to_completion)
			intf->handlers->set_run_to_completion(intf->send_info,
							      1);
L
Linus Torvalds 已提交
5148

5149 5150 5151 5152 5153 5154 5155 5156
		list_for_each_entry_rcu(user, &intf->users, link) {
			if (user->handler->ipmi_panic_handler)
				user->handler->ipmi_panic_handler(
					user->handler_data);
		}

		send_panic_events(intf, ptr);
	}
L
Linus Torvalds 已提交
5157 5158 5159 5160 5161 5162 5163 5164 5165 5166 5167 5168

	return NOTIFY_DONE;
}

static struct notifier_block panic_block = {
	.notifier_call	= panic_event,
	.next		= NULL,
	.priority	= 200	/* priority: INT_MAX >= x >= 0 */
};

static int ipmi_init_msghandler(void)
{
5169
	int rv;
L
Linus Torvalds 已提交
5170 5171 5172 5173

	if (initialized)
		return 0;

5174
	rv = driver_register(&ipmidriver.driver);
5175
	if (rv) {
5176
		pr_err(PFX "Could not register IPMI driver\n");
5177 5178 5179
		return rv;
	}

5180
	pr_info("ipmi message handler version " IPMI_DRIVER_VERSION "\n");
L
Linus Torvalds 已提交
5181

5182
#ifdef CONFIG_IPMI_PROC_INTERFACE
L
Linus Torvalds 已提交
5183 5184
	proc_ipmi_root = proc_mkdir("ipmi", NULL);
	if (!proc_ipmi_root) {
5185
	    pr_err(PFX "Unable to create IPMI proc dir");
5186
	    driver_unregister(&ipmidriver.driver);
L
Linus Torvalds 已提交
5187 5188 5189
	    return -ENOMEM;
	}

5190
#endif /* CONFIG_IPMI_PROC_INTERFACE */
L
Linus Torvalds 已提交
5191

5192
	timer_setup(&ipmi_timer, ipmi_timeout, 0);
5193
	mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
L
Linus Torvalds 已提交
5194

5195
	atomic_notifier_chain_register(&panic_notifier_list, &panic_block);
L
Linus Torvalds 已提交
5196 5197 5198 5199 5200 5201

	initialized = 1;

	return 0;
}

5202
static int __init ipmi_init_msghandler_mod(void)
L
Linus Torvalds 已提交
5203 5204 5205 5206 5207
{
	ipmi_init_msghandler();
	return 0;
}

5208
static void __exit cleanup_ipmi(void)
L
Linus Torvalds 已提交
5209 5210 5211 5212 5213 5214
{
	int count;

	if (!initialized)
		return;

5215
	atomic_notifier_chain_unregister(&panic_notifier_list, &panic_block);
L
Linus Torvalds 已提交
5216

5217 5218 5219 5220
	/*
	 * This can't be called if any interfaces exist, so no worry
	 * about shutting down the interfaces.
	 */
L
Linus Torvalds 已提交
5221

5222 5223 5224 5225 5226
	/*
	 * Tell the timer to stop, then wait for it to stop.  This
	 * avoids problems with race conditions removing the timer
	 * here.
	 */
5227 5228
	atomic_inc(&stop_operation);
	del_timer_sync(&ipmi_timer);
L
Linus Torvalds 已提交
5229

5230
#ifdef CONFIG_IPMI_PROC_INTERFACE
5231
	proc_remove(proc_ipmi_root);
5232
#endif /* CONFIG_IPMI_PROC_INTERFACE */
L
Linus Torvalds 已提交
5233

5234
	driver_unregister(&ipmidriver.driver);
5235

L
Linus Torvalds 已提交
5236 5237 5238 5239 5240
	initialized = 0;

	/* Check for buffer leaks. */
	count = atomic_read(&smi_msg_inuse_count);
	if (count != 0)
5241
		pr_warn(PFX "SMI message count %d at exit\n", count);
L
Linus Torvalds 已提交
5242 5243
	count = atomic_read(&recv_msg_inuse_count);
	if (count != 0)
5244
		pr_warn(PFX "recv message count %d at exit\n", count);
L
Linus Torvalds 已提交
5245 5246 5247 5248 5249
}
module_exit(cleanup_ipmi);

module_init(ipmi_init_msghandler_mod);
MODULE_LICENSE("GPL");
5250
MODULE_AUTHOR("Corey Minyard <minyard@mvista.com>");
5251 5252
MODULE_DESCRIPTION("Incoming and outgoing message routing for an IPMI"
		   " interface.");
5253
MODULE_VERSION(IPMI_DRIVER_VERSION);
5254
MODULE_SOFTDEP("post: ipmi_devintf");