From: Corey Minyard <cminyard@mvista.com>
To: lkml <linux-kernel@vger.kernel.org>, Andrew Morton <akpm@osdl.org>
Subject: [PATCH} Network interface for IPMI
Date: Wed, 17 Nov 2004 14:36:22 -0600 [thread overview]
Message-ID: <419BB646.3070805@mvista.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 563 bytes --]
IPMI is a manage standard that allows intelligent management controllers
to monitor things about the system (temperature, fan speed, etc.). The
management controllers sit on a bus, and have addresses, and such.
After seeing the ugliness required for the 32-bit ioctl compatability
layers for 64-bit kernels, I have decided that the network interface for
IPMI is a good thing, as the IPMI device ioctls have pointers and
require ugly hacks. None should be needed for the network interface.
This patch adds that layer.
Relative to 2.6.10-rc2-mm1
-Corey
[-- Attachment #2: af_ipmi.diff --]
[-- Type: text/plain, Size: 19856 bytes --]
Index: linux-ipmi/include/linux/net.h
===================================================================
--- linux-ipmi.orig/include/linux/net.h 2004-11-17 13:12:11.000000000 -0600
+++ linux-ipmi/include/linux/net.h 2004-11-17 13:32:26.000000000 -0600
@@ -26,7 +26,7 @@
struct poll_table_struct;
struct inode;
-#define NPROTO 32 /* should be enough for now.. */
+#define NPROTO 64 /* should be enough for now.. */
#define SYS_SOCKET 1 /* sys_socket(2) */
#define SYS_BIND 2 /* sys_bind(2) */
Index: linux-ipmi/include/linux/socket.h
===================================================================
--- linux-ipmi.orig/include/linux/socket.h 2004-11-17 13:10:50.000000000 -0600
+++ linux-ipmi/include/linux/socket.h 2004-11-17 13:32:26.000000000 -0600
@@ -177,7 +177,8 @@
#define AF_WANPIPE 25 /* Wanpipe API Sockets */
#define AF_LLC 26 /* Linux LLC */
#define AF_BLUETOOTH 31 /* Bluetooth sockets */
-#define AF_MAX 32 /* For now.. */
+#define AF_IPMI 32 /* IPMI sockers */
+#define AF_MAX 33 /* For now.. */
/* Protocol families, same as address families. */
#define PF_UNSPEC AF_UNSPEC
@@ -209,6 +210,7 @@
#define PF_WANPIPE AF_WANPIPE
#define PF_LLC AF_LLC
#define PF_BLUETOOTH AF_BLUETOOTH
+#define PF_IPMI AF_IPMI
#define PF_MAX AF_MAX
/* Maximum queue length specifiable by listen. */
Index: linux-ipmi/include/net/af_ipmi.h
===================================================================
--- linux-ipmi.orig/include/net/af_ipmi.h 1969-12-31 18:00:00.000000000 -0600
+++ linux-ipmi/include/net/af_ipmi.h 2004-11-17 13:32:26.000000000 -0600
@@ -0,0 +1,59 @@
+/*
+ * IPMI Socket Glue
+ *
+ * Author: Louis Zhuang <louis.zhuang@linux.intel.com>
+ * Copyright by Intel Corp., 2003
+ */
+#ifndef _NET_IPMI_H
+#define _NET_IPMI_H
+
+#include <linux/ipmi.h>
+
+/*
+ * This is ipmi address for socket
+ */
+struct sockaddr_ipmi {
+ sa_family_t sipmi_family; /* AF_IPMI */
+ int if_num; /* IPMI interface number */
+ struct ipmi_addr ipmi_addr;
+};
+#define SOCKADDR_IPMI_OVERHEAD (sizeof(struct sockaddr_ipmi) \
+ - sizeof(struct ipmi_addr))
+
+/* A msg_control item, this takes a 'struct ipmi_timing_parms' */
+#define IPMI_CMSG_TIMING_PARMS 0x01
+
+/*
+ * This is ipmi message for socket
+ */
+struct ipmi_sock_msg {
+ int recv_type;
+ long msgid;
+
+ unsigned char netfn;
+ unsigned char cmd;
+ int data_len;
+ unsigned char data[0];
+};
+
+#define IPMI_MAX_SOCK_MSG_LENGTH (sizeof(struct ipmi_sock_msg)+IPMI_MAX_MSG_LENGTH)
+
+/* Register/unregister to receive specific commands. Uses struct
+ ipmi_cmdspec from linux/ipmi.h */
+#define SIOCIPMIREGCMD (SIOCPROTOPRIVATE + 0)
+#define SIOCIPMIUNREGCMD (SIOCPROTOPRIVATE + 1)
+
+/* Register to receive events. Takes an integer */
+#define SIOCIPMIGETEVENT (SIOCPROTOPRIVATE + 2)
+
+/* Set the default timing parameters for the socket. Takes a struct
+ ipmi_timing_parms from linux/ipmi.h */
+#define SIOCIPMISETTIMING (SIOCPROTOPRIVATE + 3)
+#define SIOCIPMIGETTIMING (SIOCPROTOPRIVATE + 4)
+
+/* Set/Get the IPMB address of the MC we are connected to, takes an
+ unsigned int. */
+#define SIOCIPMISETADDR (SIOCPROTOPRIVATE + 5)
+#define SIOCIPMIGETADDR (SIOCPROTOPRIVATE + 6)
+
+#endif/*_NET_IPMI_H*/
Index: linux-ipmi/net/ipmi/af_ipmi.c
===================================================================
--- linux-ipmi.orig/net/ipmi/af_ipmi.c 1969-12-31 18:00:00.000000000 -0600
+++ linux-ipmi/net/ipmi/af_ipmi.c 2004-11-17 13:32:26.000000000 -0600
@@ -0,0 +1,612 @@
+/*
+ * IPMI Socket Glue
+ *
+ * Author: Louis Zhuang <louis.zhuang@linux.intel.com>
+ * Copyright by Intel Corp., 2003
+ */
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/major.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/stat.h>
+#include <linux/socket.h>
+#include <linux/fcntl.h>
+#include <linux/sockios.h>
+#include <linux/net.h>
+#include <linux/in.h>
+#include <linux/fs.h>
+#include <linux/slab.h>
+#include <asm/uaccess.h>
+#include <linux/skbuff.h>
+#include <linux/tcp.h>
+#include <net/sock.h>
+#include <linux/proc_fs.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <linux/smp_lock.h>
+#include <linux/mount.h>
+#include <linux/security.h>
+#include <linux/ipmi.h>
+#include <net/af_ipmi.h>
+
+#define IPMI_SOCKINTF_VERSION "v33"
+
+#ifdef CONFIG_DEBUG_KERNEL
+static int debug = 0;
+#define dbg(format, arg...) \
+ do { \
+ if(debug) \
+ printk (KERN_DEBUG "%s: " format "\n", \
+ __FUNCTION__, ## arg); \
+ } while(0)
+#else
+#define dbg(format, arg...)
+#endif /* CONFIG_DEBUG_KERNEL */
+
+#define err(format, arg...) \
+ printk(KERN_ERR "%s: " format "\n", \
+ __FUNCTION__ , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO "%s: " format "\n", \
+ __FUNCTION__ , ## arg)
+#define warn(format, arg...) \
+ printk(KERN_WARNING "%s: " format "\n", \
+ __FUNCTION__ , ## arg)
+#define trace(format, arg...) \
+ printk(KERN_INFO "%s(" format ")\n", \
+ __FUNCTION__ , ## arg)
+
+struct ipmi_sock {
+ /* WARNING: sk has to be the first member */
+ struct sock sk;
+
+ ipmi_user_t user;
+ struct sockaddr_ipmi addr;
+ struct list_head msg_list;
+
+ wait_queue_head_t wait;
+ spinlock_t lock;
+
+ int default_retries;
+ unsigned int default_retry_time_ms;
+};
+
+static kmem_cache_t *ipmi_sk_cachep = NULL;
+
+static atomic_t ipmi_nr_socks = ATOMIC_INIT(0);
+
+
+
+/*
+ * utility functions
+ */
+static inline struct ipmi_sock *to_ipmi_sock(struct sock *sk)
+{
+ return container_of(sk, struct ipmi_sock, sk);
+}
+
+static inline void ipmi_release_sock(struct sock *sk, int embrion)
+{
+ struct ipmi_sock *i = to_ipmi_sock(sk);
+ struct sk_buff *skb;
+
+ if (i->user) {
+ ipmi_destroy_user(i->user);
+ i->user = NULL;
+ }
+
+ sock_orphan(&i->sk);
+ sk->sk_shutdown = SHUTDOWN_MASK;
+ sk->sk_state = TCP_CLOSE;
+
+ while((skb=skb_dequeue(&sk->sk_receive_queue))!=NULL)
+ kfree_skb(skb);
+
+ sock_put(sk);
+}
+
+static inline long ipmi_wait_for_queue(struct ipmi_sock *i, long timeo)
+{
+
+ DECLARE_WAITQUEUE(wait, current);
+
+ set_current_state(TASK_INTERRUPTIBLE);
+ add_wait_queue_exclusive(&i->wait, &wait);
+ timeo = schedule_timeout(timeo);
+ remove_wait_queue(&i->wait, &wait);
+ return timeo;
+}
+
+/*
+ * IPMI operation functions
+ */
+static void sock_receive_handler(struct ipmi_recv_msg *msg,
+ void *handler_data)
+{
+ struct ipmi_sock *i = (struct ipmi_sock *)handler_data;
+ unsigned long flags;
+
+ spin_lock_irqsave(&i->lock, flags);
+ list_add_tail(&msg->link, &i->msg_list);
+ spin_unlock_irqrestore(&i->lock, flags);
+
+ wake_up_interruptible(&i->wait);
+}
+
+/*
+ * protocol operation functions
+ */
+static int ipmi_release(struct socket *sock)
+{
+ struct sock *sk = sock->sk;
+
+ if (!sk)
+ return 0;
+
+ sock->sk=NULL;
+ ipmi_release_sock(sk, 0);
+ return 0;
+}
+
+static struct ipmi_user_hndl ipmi_hnd = {
+ .ipmi_recv_hndl = sock_receive_handler
+};
+
+static int ipmi_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
+{
+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
+ struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)uaddr;
+ int err = -EINVAL;
+
+ if (i->user != NULL) {
+ dbg("Cannot bind twice: %p", i->user);
+ return -EINVAL;
+ }
+
+ err = ipmi_create_user(addr->if_num, &ipmi_hnd, i, &i->user);
+ if (err) {
+ dbg("Cannot create user for the socket: %p", i->user);
+ return err;
+ }
+
+ memcpy(&i->addr, addr, sizeof(i->addr));
+ return 0;
+}
+
+static int ipmi_getname(struct socket *sock, struct sockaddr *uaddr, int *uaddr_len, int peer)
+{
+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
+ memcpy(uaddr, &i->addr, sizeof(i->addr));
+ return 0;
+}
+
+static unsigned int ipmi_poll(struct file * file, struct socket *sock, poll_table *wait)
+{
+ unsigned int has_msg = 0;
+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
+ unsigned long flags;
+
+ poll_wait(file, &i->wait, wait);
+ spin_lock_irqsave(&i->lock, flags);
+ if (!list_empty(&i->msg_list))
+ has_msg = 1;
+ spin_unlock_irqrestore(&i->lock, flags);
+
+ if (has_msg)
+ return POLLIN | POLLRDNORM;
+ return 0;
+}
+
+static int ipmi_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
+{
+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
+ struct ipmi_cmdspec val;
+ int ival;
+ unsigned int uival;
+ int err;
+
+ dbg("cmd=%#x, arg=%#lx", cmd, arg);
+ switch(cmd) {
+ case SIOCIPMIREGCMD:
+ err = copy_from_user((void *)&val, (void *)arg,
+ sizeof(cmd));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = ipmi_register_for_cmd(i->user, val.netfn,
+ val.cmd);
+ break;
+
+ case SIOCIPMIUNREGCMD:
+ err = copy_from_user((void *)&val, (void *)arg,
+ sizeof(cmd));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = ipmi_unregister_for_cmd(i->user, val.netfn,
+ val.cmd);
+ break;
+
+ case SIOCIPMIGETEVENT:
+ err = copy_from_user((void *)&ival, (void *)arg,
+ sizeof(ival));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = ipmi_set_gets_events(i->user, ival);
+ break;
+
+ case SIOCIPMISETADDR:
+ err = copy_from_user((void *)&uival, (void *)arg,
+ sizeof(uival));
+ if (err) {
+ err = -EFAULT;
+ break;
+ }
+
+ ipmi_set_my_address(i->user, uival);
+ break;
+
+ case SIOCIPMIGETADDR:
+ uival = ipmi_get_my_address(i->user);
+
+ if (copy_to_user((void *) arg, &uival, sizeof(uival))) {
+ err = -EFAULT;
+ break;
+ }
+ err = 0;
+ break;
+
+ case SIOCIPMISETTIMING:
+ {
+ struct ipmi_timing_parms parms;
+
+ if (copy_from_user(&parms, (void *) arg, sizeof(parms))) {
+ err = -EFAULT;
+ break;
+ }
+
+ i->default_retries = parms.retries;
+ i->default_retry_time_ms = parms.retry_time_ms;
+ err = 0;
+ break;
+ }
+
+ case SIOCIPMIGETTIMING:
+ {
+ struct ipmi_timing_parms parms;
+
+ parms.retries = i->default_retries;
+ parms.retry_time_ms = i->default_retry_time_ms;
+
+ if (copy_to_user((void *) arg, &parms, sizeof(parms))) {
+ err = -EFAULT;
+ break;
+ }
+
+ err = 0;
+ break;
+ }
+
+ default:
+ err = dev_ioctl(cmd, (void *)arg);
+ break;
+ }
+
+ return err;
+}
+
+static int ipmi_recvmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t size,
+ int rflags)
+{
+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
+ long timeo;
+ struct ipmi_recv_msg *rcvmsg;
+ struct sockaddr_ipmi addr;
+ char buf[IPMI_MAX_SOCK_MSG_LENGTH];
+ struct ipmi_sock_msg *smsg = (struct ipmi_sock_msg *)buf;
+ int err;
+ unsigned long flags;
+
+
+ timeo = sock_rcvtimeo(&i->sk, rflags & MSG_DONTWAIT);
+
+ while (1) {
+ spin_lock_irqsave(&i->lock, flags);
+ if (!list_empty(&i->msg_list))
+ break;
+ spin_unlock_irqrestore(&i->lock, flags);
+ if (!timeo) {
+ return -EAGAIN;
+ } else if (signal_pending (current)) {
+ dbg("Signal pending: %d", 1);
+ return -EINTR;
+ }
+
+ timeo = ipmi_wait_for_queue(i, timeo);
+ }
+
+ rcvmsg = list_entry(i->msg_list.next, struct ipmi_recv_msg, link);
+ list_del(&rcvmsg->link);
+ spin_unlock_irqrestore(&i->lock, flags);
+
+ memcpy(&addr.ipmi_addr, &rcvmsg->addr, sizeof(addr.ipmi_addr));
+ addr.if_num = i->addr.if_num;
+ addr.sipmi_family = i->addr.sipmi_family;
+ memcpy(msg->msg_name, &addr, sizeof(addr));
+ msg->msg_namelen = (SOCKADDR_IPMI_OVERHEAD
+ + ipmi_addr_length(rcvmsg->addr.addr_type));
+
+ smsg->recv_type = rcvmsg->recv_type;
+ smsg->msgid = rcvmsg->msgid;
+ smsg->netfn = rcvmsg->msg.netfn;
+ smsg->cmd = rcvmsg->msg.cmd;
+ smsg->data_len = rcvmsg->msg.data_len;
+ memcpy(smsg->data, rcvmsg->msg.data, smsg->data_len);
+
+ ipmi_free_recv_msg(rcvmsg);
+
+ err = memcpy_toiovec(msg->msg_iov, (void *)smsg,
+ sizeof(struct ipmi_sock_msg) + smsg->data_len);
+ if (err) {
+ dbg("Cannot copy data to user: %p", i->user);
+ return err;
+ }
+
+ dbg("user=%p", i->user);
+ dbg("addr_type=%x, channel=%x",
+ addr.ipmi_addr.addr_type, addr.ipmi_addr.channel);
+ dbg("netfn=%#02x, cmd=%#02x, data=%p, data_len=%x",
+ smsg->netfn, smsg->cmd, smsg->data, smsg->data_len);
+
+ return (sizeof(struct ipmi_sock_msg) + smsg->data_len);
+}
+
+static int ipmi_sendmsg(struct kiocb *iocb, struct socket *sock,
+ struct msghdr *msg, size_t len)
+{
+ struct ipmi_sock *i = to_ipmi_sock(sock->sk);
+ struct sockaddr_ipmi *addr = (struct sockaddr_ipmi *)msg->msg_name;
+ struct kernel_ipmi_msg imsg;
+ unsigned char buf[IPMI_MAX_SOCK_MSG_LENGTH];
+ struct ipmi_sock_msg *smsg = (struct ipmi_sock_msg *) buf;
+ int err;
+ struct ipmi_timing_parms tparms;
+ struct cmsghdr *cmsg;
+
+ err = ipmi_validate_addr(&addr->ipmi_addr,
+ msg->msg_namelen - SOCKADDR_IPMI_OVERHEAD);
+ if (err) {
+ dbg("Invalid IPMI address: %p", i->user);
+ goto err;
+ }
+
+ if (len > IPMI_MAX_SOCK_MSG_LENGTH) {
+ err = -EINVAL;
+ dbg("Message too long: %p", i->user);
+ goto err;
+ }
+
+ if (len < sizeof(struct ipmi_sock_msg)) {
+ err = -EINVAL;
+ dbg("Msg data too small for header: %p", i->user);
+ goto err;
+ }
+
+ err = memcpy_fromiovec((void *)smsg, msg->msg_iov, len);
+ if (err) {
+ dbg("Cannot copy data to kernel: %p", i->user);
+ goto err;
+ }
+
+ if (len < smsg->data_len+sizeof(struct ipmi_sock_msg)) {
+ err = -EINVAL;
+ dbg("Msg data is out of bound: %p", i->user);
+ goto err;
+ }
+
+ /* Set defaults. */
+ tparms.retries = i->default_retries;
+ tparms.retry_time_ms = i->default_retry_time_ms;
+
+ for (cmsg=CMSG_FIRSTHDR(msg);
+ cmsg;
+ cmsg = CMSG_NXTHDR(msg, cmsg))
+ {
+ if (cmsg->cmsg_len < sizeof(struct cmsghdr)) {
+ err = -EINVAL;
+ dbg("cmsg length too short: %p", i->user);
+ goto err;
+ }
+
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ continue;
+
+ if (cmsg->cmsg_type == IPMI_CMSG_TIMING_PARMS) {
+ struct ipmi_timing_parms *pparms;
+
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(*pparms))) {
+ err = -EINVAL;
+ dbg("timing parms cmsg not right size: %p",
+ i->user);
+ goto err;
+ }
+ pparms = (struct ipmi_timing_parms *) CMSG_DATA(cmsg);
+ tparms.retries = pparms->retries;
+ tparms.retry_time_ms = pparms->retry_time_ms;
+ }
+ }
+
+ imsg.netfn = smsg->netfn;
+ imsg.cmd = smsg->cmd;
+ imsg.data = smsg->data;
+ imsg.data_len = smsg->data_len;
+
+ dbg("user=%p", i->user);
+ dbg("addr_type=%x, channel=%x",
+ addr->ipmi_addr.addr_type, addr->ipmi_addr.channel);
+ dbg("netfn=%#02x, cmd=%#02x, data=%p, data_len=%x",
+ imsg.netfn, imsg.cmd, imsg.data, imsg.data_len);
+ err = ipmi_request_settime(i->user, &addr->ipmi_addr,
+ smsg->msgid, &imsg, NULL, 0,
+ tparms.retries, tparms.retry_time_ms);
+ if (err) {
+ dbg("Cannot send message: %p", i->user);
+ goto err;
+ }
+
+err:
+ return err;
+}
+
+static struct proto_ops ipmi_ops = {
+ .family = PF_IPMI,
+ .owner = THIS_MODULE,
+ .release = ipmi_release,
+ .bind = ipmi_bind,
+ .connect = sock_no_connect,
+ .socketpair = sock_no_socketpair,
+ .accept = sock_no_accept,
+ .getname = ipmi_getname,
+ .poll = ipmi_poll,
+ .ioctl = ipmi_ioctl,
+ .listen = sock_no_listen,
+ .shutdown = sock_no_shutdown,
+ .setsockopt = sock_no_setsockopt,
+ .getsockopt = sock_no_getsockopt,
+ .sendmsg = ipmi_sendmsg,
+ .recvmsg = ipmi_recvmsg,
+ .mmap = sock_no_mmap,
+ .sendpage = sock_no_sendpage
+};
+
+
+static void ipmi_sock_destructor(struct sock *sk)
+{
+ skb_queue_purge(&sk->sk_receive_queue);
+
+ BUG_TRAP(!atomic_read(&sk->sk_wmem_alloc));
+ BUG_TRAP(sk_unhashed(sk));
+ BUG_TRAP(!sk->sk_socket);
+ if (!sock_flag(sk, SOCK_DEAD)) {
+ printk("Attempt to release alive ipmi socket: %p\n", sk);
+ return;
+ }
+
+ atomic_dec(&ipmi_nr_socks);
+}
+
+/*
+ * net protocol functions
+ */
+static struct ipmi_sock *ipmi_socket_create1(struct socket *sock)
+{
+ struct ipmi_sock *i;
+
+ if (atomic_read(&ipmi_nr_socks) >= 2*files_stat.max_files)
+ return NULL;
+
+ i = (struct ipmi_sock *)sk_alloc(PF_IPMI, GFP_KERNEL,
+ sizeof(struct ipmi_sock), ipmi_sk_cachep);
+ if (!i) {
+ return NULL;
+ }
+
+
+ sock_init_data(sock, &i->sk);
+ sk_set_owner(&i->sk, THIS_MODULE);
+ i->sk.sk_destruct = ipmi_sock_destructor;
+ i->sk.sk_rcvtimeo = 5*HZ;
+ spin_lock_init(&i->lock);
+ INIT_LIST_HEAD(&i->msg_list);
+ init_waitqueue_head(&i->wait);
+
+ /* Set to use default values. */
+ i->default_retries = -1;
+ i->default_retry_time_ms = 0;
+
+ atomic_inc(&ipmi_nr_socks);
+ return i;
+}
+
+static int ipmi_socket_create(struct socket *sock, int protocol)
+{
+ if (!capable(CAP_NET_RAW))
+ return -EPERM;
+ if (protocol && protocol != PF_IPMI)
+ return -EPROTONOSUPPORT;
+
+ sock->state = SS_UNCONNECTED;
+
+ switch (sock->type) {
+ case SOCK_RAW:
+ sock->type=SOCK_DGRAM;
+ case SOCK_DGRAM:
+ sock->ops = &ipmi_ops;
+ break;
+ default:
+ return -EPROTONOSUPPORT;
+ }
+
+ return ipmi_socket_create1(sock)? 0 : -ENOMEM;
+}
+
+static struct net_proto_family ipmi_family_ops = {
+ .family = PF_IPMI,
+ .create = ipmi_socket_create,
+ .owner = THIS_MODULE,
+};
+
+
+/*
+ * init/exit functions
+ */
+static int __init ipmi_socket_init(void)
+{
+
+ int err=0;
+
+ printk(KERN_INFO "ipmi socket interface version "
+ IPMI_SOCKINTF_VERSION "\n");
+
+ ipmi_sk_cachep = kmem_cache_create("ipmi_sock",
+ sizeof(struct ipmi_sock), 0,
+ SLAB_HWCACHE_ALIGN, 0, 0);
+ if (!ipmi_sk_cachep) {
+ printk(KERN_CRIT "%s: Unable to create ipmi_sock SLAB cache!\n", __func__);
+ err = -ENOMEM;
+ goto out;
+ }
+
+ err = sock_register(&ipmi_family_ops);
+ if (err)
+ kmem_cache_destroy(ipmi_sk_cachep);
+out:
+ return err;
+}
+
+static void __exit ipmi_socket_exit(void)
+{
+ sock_unregister(PF_IPMI);
+ kmem_cache_destroy(ipmi_sk_cachep);
+}
+
+#ifdef CONFIG_DEBUG_KERNEL
+module_param(debug, int, 0);
+#endif
+module_init(ipmi_socket_init);
+module_exit(ipmi_socket_exit);
+
+MODULE_LICENSE("GPL");
Index: linux-ipmi/net/ipmi/Makefile
===================================================================
--- linux-ipmi.orig/net/ipmi/Makefile 1969-12-31 18:00:00.000000000 -0600
+++ linux-ipmi/net/ipmi/Makefile 2004-11-17 13:32:26.000000000 -0600
@@ -0,0 +1 @@
+obj-$(CONFIG_IPMI_SOCKET) = af_ipmi.o
Index: linux-ipmi/net/Kconfig
===================================================================
--- linux-ipmi.orig/net/Kconfig 2004-11-17 13:13:13.000000000 -0600
+++ linux-ipmi/net/Kconfig 2004-11-17 13:32:26.000000000 -0600
@@ -71,6 +71,17 @@
Say Y unless you know what you are doing.
+config IPMI_SOCKET
+ tristate "IPMI sockets"
+ depends on IPMI_HANDLER
+ ---help---
+ If you say Y here, you will include support for IPMI sockets;
+ This way you don't have to use devices to access IPMI. You
+ must also enable the IPMI message handler and a low-level
+ driver in the Character Drivers if you enable this.
+
+ If unsure, say N.
+
config NET_KEY
tristate "PF_KEY sockets"
select XFRM
Index: linux-ipmi/net/Makefile
===================================================================
--- linux-ipmi.orig/net/Makefile 2004-11-17 13:12:13.000000000 -0600
+++ linux-ipmi/net/Makefile 2004-11-17 13:32:26.000000000 -0600
@@ -42,6 +42,7 @@
obj-$(CONFIG_ECONET) += econet/
obj-$(CONFIG_VLAN_8021Q) += 8021q/
obj-$(CONFIG_IP_SCTP) += sctp/
+obj-$(CONFIG_IPMI_SOCKET) += ipmi/
ifeq ($(CONFIG_NET),y)
obj-$(CONFIG_SYSCTL) += sysctl_net.o
next reply other threads:[~2004-11-18 2:00 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-11-17 20:36 Corey Minyard [this message]
2004-11-17 20:51 ` [PATCH} Network interface for IPMI Andrew Morton
2004-11-17 21:19 ` Corey Minyard
2004-11-17 22:12 ` Corey Minyard
[not found] <31Fe2-5kB-11@gated-at.bofh.it>
2004-11-18 4:36 ` Andi Kleen
2004-11-18 14:09 ` Corey Minyard
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=419BB646.3070805@mvista.com \
--to=cminyard@mvista.com \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.