* [BK PATCH] Driver Core update for 2.6.4-rc1
@ 2004-03-03 4:14 Greg KH
2004-03-03 4:16 ` [PATCH] " Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:14 UTC (permalink / raw)
To: torvalds, akpm; +Cc: linux-kernel
Hi,
Here are a few driver core changes for 2.6.4-rc1. There are a few
patches from Randy Dunlap that finish up his big sys_* cleanups, and the
ibm service processor driver has been added as well as some other minor
bugfixes. All of these patches have been in the -mm tree for a while
now.
Please pull from:
bk://kernel.bkbits.net/gregkh/linux/driver-2.6
thanks,
greg k-h
p.s. I'll send these as patches in response to this email to lkml for
those who want to see them.
arch/arm/kernel/time.c | 2
arch/arm/mach-integrator/integrator_ap.c | 2
arch/arm/mach-sa1100/irq.c | 2
arch/i386/kernel/apic.c | 4
arch/i386/kernel/i8259.c | 4
arch/i386/kernel/nmi.c | 2
arch/i386/kernel/time.c | 2
arch/i386/oprofile/nmi_int.c | 8
arch/mips/kernel/i8259.c | 4
arch/ppc/platforms/pmac_pic.c | 2
arch/ppc/syslib/open_pic.c | 2
arch/ppc/syslib/open_pic2.c | 2
arch/x86_64/kernel/apic.c | 4
arch/x86_64/kernel/i8259.c | 4
arch/x86_64/kernel/mce.c | 4
arch/x86_64/kernel/nmi.c | 4
arch/x86_64/kernel/time.c | 4
drivers/Kconfig | 2
drivers/base/Kconfig | 11
drivers/base/bus.c | 5
drivers/base/class.c | 5
drivers/base/class_simple.c | 5
drivers/base/core.c | 5
drivers/base/cpu.c | 2
drivers/base/driver.c | 5
drivers/base/init.c | 4
drivers/base/node.c | 2
drivers/base/power/main.c | 5
drivers/base/power/shutdown.c | 7
drivers/base/sys.c | 19
drivers/char/misc.c | 24 -
drivers/input/serio/i8042.c | 4
drivers/misc/Kconfig | 17
drivers/misc/Makefile | 2
drivers/misc/ibmasm/Makefile | 13
drivers/misc/ibmasm/command.c | 175 +++++++
drivers/misc/ibmasm/dot_command.c | 146 ++++++
drivers/misc/ibmasm/dot_command.h | 78 +++
drivers/misc/ibmasm/event.c | 169 +++++++
drivers/misc/ibmasm/heartbeat.c | 91 +++
drivers/misc/ibmasm/i2o.h | 77 +++
drivers/misc/ibmasm/ibmasm.h | 224 +++++++++
drivers/misc/ibmasm/ibmasmfs.c | 717 +++++++++++++++++++++++++++++++
drivers/misc/ibmasm/lowlevel.c | 81 +++
drivers/misc/ibmasm/lowlevel.h | 137 +++++
drivers/misc/ibmasm/module.c | 210 +++++++++
drivers/misc/ibmasm/r_heartbeat.c | 98 ++++
drivers/misc/ibmasm/remote.c | 152 ++++++
drivers/misc/ibmasm/remote.h | 119 +++++
drivers/misc/ibmasm/uart.c | 72 +++
drivers/s390/block/xpram.c | 12
include/linux/sysdev.h | 4
lib/kobject.c | 11
53 files changed, 2695 insertions(+), 71 deletions(-)
-----
<masbock:us.ibm.com>:
o Driver for IBM service processor - updated (2/2)
o Driver for IBM service processor - updated (1/2)
Andrew Morton:
o fix x86_64 build for sys_device_register rename
Greg Kroah-Hartman:
o Driver core: add CONFIG_DEBUG_DRIVER to help track down driver core bugs easier
o Make IBMASM driver depend on X86 as that is the only valid platform for it
o kobject: clean up kobject_get() convoluted logic
o kobject: fix kobject hotplug debug message to show more needed info
Randy Dunlap:
o rename sys_bus_init()
o sys_device_[un]register() are not syscalls
Stephen Hemminger:
o propogate errors from misc_register to caller
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.17.3, 2004/02/27 11:12:02-08:00, greg@kroah.com
kobject: fix kobject hotplug debug message to show more needed info.
lib/kobject.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c Tue Mar 2 19:50:53 2004
+++ b/lib/kobject.c Tue Mar 2 19:50:53 2004
@@ -185,8 +185,8 @@
}
}
- pr_debug ("%s: %s %s %s %s %s %s\n", __FUNCTION__, argv[0], argv[1],
- envp[0], envp[1], envp[2], envp[3]);
+ pr_debug ("%s: %s %s %s %s %s %s %s\n", __FUNCTION__, argv[0], argv[1],
+ envp[0], envp[1], envp[2], envp[3], envp[4]);
retval = call_usermodehelper (argv[0], argv, envp, 0);
if (retval)
pr_debug ("%s - call_usermodehelper returned %d\n",
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 8:00 ` Christoph Hellwig
0 siblings, 2 replies; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.17.5, 2004/02/27 11:40:29-08:00, masbock@us.ibm.com
[PATCH] Driver for IBM service processor - updated (1/2)
Here is a device driver for the IBM xSeries RSA service processor.
The ibmasm driver is mainly intended to be used in conjunction with a user space
API and systems management applications that need to get in-band access to
the service processor, such as sending commands or waiting for events.
For the remote video feature the driver relays remote mouse and keyboard
events to user space.
By itself the driver also allows the OS to make use the UART on the service
processor board as a regular serial line.
The user interface to the driver is a custom file system. It does not use sysfs since
the operations on the files are somewhat beyond the one file / one value rule for sysfs.
Since it is not strictly a char driver I put it into the drivers/misc directory.
The patch is fairly big, therefore I split it up into the file system part and the
everything-else part.
Here is the non-filesystem part:
drivers/Kconfig | 2
drivers/misc/Kconfig | 16 ++
drivers/misc/Makefile | 2
drivers/misc/ibmasm/Makefile | 13 ++
drivers/misc/ibmasm/command.c | 175 +++++++++++++++++++++++++++++
drivers/misc/ibmasm/dot_command.c | 146 ++++++++++++++++++++++++
drivers/misc/ibmasm/dot_command.h | 78 +++++++++++++
drivers/misc/ibmasm/event.c | 169 ++++++++++++++++++++++++++++
drivers/misc/ibmasm/heartbeat.c | 91 +++++++++++++++
drivers/misc/ibmasm/i2o.h | 77 +++++++++++++
drivers/misc/ibmasm/ibmasm.h | 224 ++++++++++++++++++++++++++++++++++++++
drivers/misc/ibmasm/lowlevel.c | 81 +++++++++++++
drivers/misc/ibmasm/lowlevel.h | 137 +++++++++++++++++++++++
drivers/misc/ibmasm/module.c | 210 +++++++++++++++++++++++++++++++++++
drivers/misc/ibmasm/r_heartbeat.c | 98 ++++++++++++++++
drivers/misc/ibmasm/remote.c | 152 +++++++++++++++++++++++++
drivers/misc/ibmasm/remote.h | 119 ++++++++++++++++++++
drivers/misc/ibmasm/uart.c | 72 ++++++++++++
18 files changed, 1861 insertions(+), 1 deletion(-)
diff -Nru a/drivers/Kconfig b/drivers/Kconfig
--- a/drivers/Kconfig Tue Mar 2 19:49:59 2004
+++ b/drivers/Kconfig Tue Mar 2 19:49:59 2004
@@ -42,7 +42,7 @@
source "drivers/i2c/Kconfig"
-# source "drivers/misc/Kconfig"
+source "drivers/misc/Kconfig"
source "drivers/media/Kconfig"
diff -Nru a/drivers/misc/Kconfig b/drivers/misc/Kconfig
--- a/drivers/misc/Kconfig Tue Mar 2 19:49:59 2004
+++ b/drivers/misc/Kconfig Tue Mar 2 19:49:59 2004
@@ -4,5 +4,21 @@
menu "Misc devices"
+config IBM_ASM
+ tristate "Device driver for IBM RSA service processor"
+ default n
+ ---help---
+ This option enables device driver support for in-band access to the
+ IBM RSA (Condor) service processor in eServer xSeries systems.
+ The ibmasm device driver allows user space application to access
+ ASM (Advanced Systems Management) functions on the service
+ processor. The driver is meant to be used in conjunction with
+ a user space API.
+ The ibmasm driver also enables the OS to use the UART on the
+ service processor board as a regular serial port.
+
+
+ If unsure, say N.
+
endmenu
diff -Nru a/drivers/misc/Makefile b/drivers/misc/Makefile
--- a/drivers/misc/Makefile Tue Mar 2 19:49:59 2004
+++ b/drivers/misc/Makefile Tue Mar 2 19:49:59 2004
@@ -2,3 +2,5 @@
# Makefile for misc devices that really don't fit anywhere else.
#
obj- := misc.o # Dummy rule to force built-in.o to be made
+
+obj-$(CONFIG_IBM_ASM) += ibmasm/
diff -Nru a/drivers/misc/ibmasm/Makefile b/drivers/misc/ibmasm/Makefile
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/Makefile Tue Mar 2 19:49:59 2004
@@ -0,0 +1,13 @@
+
+obj-$(CONFIG_IBM_ASM) := ibmasm.o
+
+ibmasm-objs := module.o \
+ ibmasmfs.o \
+ event.o \
+ command.o \
+ remote.o \
+ heartbeat.o \
+ r_heartbeat.o \
+ dot_command.o \
+ lowlevel.o \
+ uart.o
diff -Nru a/drivers/misc/ibmasm/command.c b/drivers/misc/ibmasm/command.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/command.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,175 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include "ibmasm.h"
+
+static void exec_next_command(struct service_processor *sp);
+static void free_command(struct kobject *kobj);
+
+static struct kobj_type ibmasm_cmd_kobj_type = {
+ .release = free_command,
+};
+
+
+struct command *ibmasm_new_command(size_t buffer_size)
+{
+ struct command *cmd;
+
+ if (buffer_size > IBMASM_CMD_MAX_BUFFER_SIZE)
+ return NULL;
+
+ cmd = kmalloc(sizeof(struct command), GFP_KERNEL);
+ if (cmd == NULL)
+ return NULL;
+
+ memset(cmd, 0, sizeof(*cmd));
+
+ cmd->buffer = kmalloc(buffer_size, GFP_KERNEL);
+ if (cmd->buffer == NULL) {
+ kfree(cmd);
+ return NULL;
+ }
+ memset(cmd->buffer, 0, buffer_size);
+ cmd->buffer_size = buffer_size;
+
+ kobject_init(&cmd->kobj);
+ cmd->kobj.ktype = &ibmasm_cmd_kobj_type;
+
+ cmd->status = IBMASM_CMD_PENDING;
+ init_waitqueue_head(&cmd->wait);
+ INIT_LIST_HEAD(&cmd->queue_node);
+
+ return cmd;
+}
+
+static void free_command(struct kobject *kobj)
+{
+ struct command *cmd = to_command(kobj);
+
+ list_del(&cmd->queue_node);
+ kfree(cmd->buffer);
+ kfree(cmd);
+}
+
+static void enqueue_command(struct service_processor *sp, struct command *cmd)
+{
+ list_add_tail(&cmd->queue_node, &sp->command_queue);
+}
+
+static struct command *dequeue_command(struct service_processor *sp)
+{
+ struct command *cmd;
+ struct list_head *next;
+
+ if (list_empty(&sp->command_queue))
+ return NULL;
+
+ next = sp->command_queue.next;
+ list_del_init(next);
+ cmd = list_entry(next, struct command, queue_node);
+
+ return cmd;
+}
+
+static inline void do_exec_command(struct service_processor *sp)
+{
+ if (ibmasm_send_i2o_message(sp)) {
+ sp->current_command->status = IBMASM_CMD_FAILED;
+ exec_next_command(sp);
+ }
+}
+
+/**
+ * exec_command
+ * send a command to a service processor
+ * Commands are executed sequentially. One command (sp->current_command)
+ * is sent to the service processor. Once the interrupt handler gets a
+ * message of type command_response, the message is copied into
+ * the current commands buffer,
+ */
+void ibmasm_exec_command(struct service_processor *sp, struct command *cmd)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&sp->lock, flags);
+
+ if (!sp->current_command) {
+ command_get(cmd);
+ sp->current_command = cmd;
+ spin_unlock_irqrestore(&sp->lock, flags);
+
+ do_exec_command(sp);
+ } else {
+ enqueue_command(sp, cmd);
+ spin_unlock_irqrestore(&sp->lock, flags);
+ }
+}
+
+static void exec_next_command(struct service_processor *sp)
+{
+ unsigned long flags;
+
+ wake_up(&sp->current_command->wait);
+ command_put(sp->current_command);
+
+ spin_lock_irqsave(&sp->lock, flags);
+ sp->current_command = dequeue_command(sp);
+ if (sp->current_command) {
+ command_get(sp->current_command);
+ spin_unlock_irqrestore(&sp->lock, flags);
+ do_exec_command(sp);
+ } else {
+ spin_unlock_irqrestore(&sp->lock, flags);
+ }
+}
+
+/**
+ * Sleep until a command has failed or a response has been received
+ * and the command status been updated by the interrupt handler.
+ * (see receive_response).
+ */
+void ibmasm_wait_for_response(struct command *cmd, int timeout)
+{
+ wait_event_interruptible_timeout(cmd->wait,
+ cmd->status == IBMASM_CMD_COMPLETE ||
+ cmd->status == IBMASM_CMD_FAILED,
+ timeout * HZ);
+}
+
+/**
+ * receive_command_response
+ * called by the interrupt handler when a dot command of type command_response
+ * was received.
+ */
+void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size)
+{
+ struct command *cmd = sp->current_command;
+
+ if (!sp->current_command)
+ return;
+
+ memcpy(cmd->buffer, response, min(size, cmd->buffer_size));
+ cmd->status = IBMASM_CMD_COMPLETE;
+ exec_next_command(sp);
+}
diff -Nru a/drivers/misc/ibmasm/dot_command.c b/drivers/misc/ibmasm/dot_command.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/dot_command.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,146 @@
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include "ibmasm.h"
+#include "dot_command.h"
+
+/**
+ * Dispatch an incoming message to the specific handler for the message.
+ * Called from interrupt context.
+ */
+void ibmasm_receive_message(struct service_processor *sp, void *message, int message_size)
+{
+ u32 size;
+ struct dot_command_header *header = (struct dot_command_header *)message;
+
+ size = get_dot_command_size(message);
+ if (size > message_size)
+ size = message_size;
+
+ switch (header->type) {
+ case sp_event:
+ ibmasm_receive_event(sp, message, size);
+ break;
+ case sp_command_response:
+ ibmasm_receive_command_response(sp, message, size);
+ break;
+ case sp_heartbeat:
+ ibmasm_receive_heartbeat(sp, message, size);
+ break;
+ default:
+ dev_err(sp->dev, "Received unknown message from service processor\n");
+ }
+}
+
+
+#define INIT_BUFFER_SIZE 32
+
+
+/**
+ * send the 4.3.5.10 dot command (driver VPD) to the service processor
+ */
+int ibmasm_send_driver_vpd(struct service_processor *sp)
+{
+ struct command *command;
+ struct dot_command_header *header;
+ u8 *vpd_command;
+ u8 *vpd_data;
+ int result = 0;
+
+ command = ibmasm_new_command(INIT_BUFFER_SIZE);
+ if (command == NULL)
+ return -ENOMEM;
+
+ header = (struct dot_command_header *)command->buffer;
+ header->type = sp_write;
+ header->command_size = 4;
+ header->data_size = 16;
+ header->status = 0;
+ header->reserved = 0;
+
+ vpd_command = command->buffer + sizeof(struct dot_command_header);
+ vpd_command[0] = 0x4;
+ vpd_command[1] = 0x3;
+ vpd_command[2] = 0x5;
+ vpd_command[3] = 0xa;
+
+ vpd_data = vpd_command + header->command_size;
+ vpd_data[0] = 0;
+ strcat(vpd_data, IBMASM_DRIVER_VPD);
+ vpd_data[10] = 0;
+ vpd_data[15] = 0;
+
+ ibmasm_exec_command(sp, command);
+ ibmasm_wait_for_response(command, IBMASM_CMD_TIMEOUT_NORMAL);
+
+ if (command->status != IBMASM_CMD_COMPLETE)
+ result = -ENODEV;
+
+ command_put(command);
+
+ return result;
+}
+
+struct os_state_command {
+ struct dot_command_header header;
+ unsigned char command[3];
+ unsigned char data;
+};
+
+/**
+ * send the 4.3.6 dot command (os state) to the service processor
+ * During driver init this function is called with os state "up".
+ * This causes the service processor to start sending heartbeats the
+ * driver.
+ * During driver exit the function is called with os state "down",
+ * causing the service processor to stop the heartbeats.
+ */
+int ibmasm_send_os_state(struct service_processor *sp, int os_state)
+{
+ struct command *cmd;
+ struct os_state_command *os_state_cmd;
+ int result = 0;
+
+ cmd = ibmasm_new_command(sizeof(struct os_state_command));
+ if (cmd == NULL)
+ return -ENOMEM;
+
+ os_state_cmd = (struct os_state_command *)cmd->buffer;
+ os_state_cmd->header.type = sp_write;
+ os_state_cmd->header.command_size = 3;
+ os_state_cmd->header.data_size = 1;
+ os_state_cmd->header.status = 0;
+ os_state_cmd->command[0] = 4;
+ os_state_cmd->command[1] = 3;
+ os_state_cmd->command[2] = 6;
+ os_state_cmd->data = os_state;
+
+ ibmasm_exec_command(sp, cmd);
+ ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
+
+ if (cmd->status != IBMASM_CMD_COMPLETE)
+ result = -ENODEV;
+
+ command_put(cmd);
+ return result;
+}
diff -Nru a/drivers/misc/ibmasm/dot_command.h b/drivers/misc/ibmasm/dot_command.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/dot_command.h Tue Mar 2 19:49:59 2004
@@ -0,0 +1,78 @@
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#ifndef __DOT_COMMAND_H__
+#define __DOT_COMMAND_H__
+
+/*
+ * dot commands are the protocol used to communicate with the service
+ * processor.
+ * They consist of header, a command of variable length and data of
+ * variable length.
+ */
+
+/* dot command types */
+#define sp_write 0
+#define sp_write_next 1
+#define sp_read 2
+#define sp_read_next 3
+#define sp_command_response 4
+#define sp_event 5
+#define sp_heartbeat 6
+
+#pragma pack(1)
+struct dot_command_header {
+ u8 type;
+ u8 command_size;
+ u16 data_size;
+ u8 status;
+ u8 reserved;
+};
+#pragma pack()
+
+static inline size_t get_dot_command_size(void *buffer)
+{
+ struct dot_command_header *cmd = (struct dot_command_header *)buffer;
+ return sizeof(struct dot_command_header) + cmd->command_size + cmd->data_size;
+}
+
+static inline unsigned int get_dot_command_timeout(void *buffer)
+{
+ struct dot_command_header *header = (struct dot_command_header *)buffer;
+ unsigned char *cmd = buffer + sizeof(struct dot_command_header);
+
+ /* dot commands 6.3.1, 7.1 and 8.x need a longer timeout */
+
+ if (header->command_size == 3) {
+ if ((cmd[0] == 6) && (cmd[1] == 3) && (cmd[2] == 1))
+ return IBMASM_CMD_TIMEOUT_EXTRA;
+ } else if (header->command_size == 2) {
+ if ((cmd[0] == 7) && (cmd[1] == 1))
+ return IBMASM_CMD_TIMEOUT_EXTRA;
+ if (cmd[0] == 8)
+ return IBMASM_CMD_TIMEOUT_EXTRA;
+ }
+ return IBMASM_CMD_TIMEOUT_NORMAL;
+}
+
+#endif /* __DOT_COMMAND_H__ */
diff -Nru a/drivers/misc/ibmasm/event.c b/drivers/misc/ibmasm/event.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/event.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,169 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include "ibmasm.h"
+
+/*
+ * ASM service processor event handling routines.
+ *
+ * Events are signalled to the device drivers through interrupts.
+ * They have the format of dot commands, with the type field set to
+ * sp_event.
+ * The driver does not interpret the events, it simply stores them in a
+ * circular buffer.
+ */
+
+
+static void wake_up_event_readers(struct service_processor *sp)
+{
+ struct event_reader *reader;
+
+ list_for_each_entry(reader, &sp->event_buffer->readers, node)
+ wake_up_interruptible(&reader->wait);
+}
+
+/**
+ * receive_event
+ * Called by the interrupt handler when a dot command of type sp_event is
+ * received.
+ * Store the event in the circular event buffer, wake up any sleeping
+ * event readers.
+ * There is no reader marker in the buffer, therefore readers are
+ * responsible for keeping up with the writer, or they will loose events.
+ */
+void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int data_size)
+{
+ struct event_buffer *buffer = sp->event_buffer;
+ struct ibmasm_event *event;
+ unsigned long flags;
+
+ data_size = min(data_size, IBMASM_EVENT_MAX_SIZE);
+
+ spin_lock_irqsave(&sp->lock, flags);
+ /* copy the event into the next slot in the circular buffer */
+ event = &buffer->events[buffer->next_index];
+ memcpy(event->data, data, data_size);
+ event->data_size = data_size;
+ event->serial_number = buffer->next_serial_number;
+
+ /* advance indices in the buffer */
+ buffer->next_index = (buffer->next_index + 1) % IBMASM_NUM_EVENTS;
+ buffer->next_serial_number++;
+ spin_unlock_irqrestore(&sp->lock, flags);
+
+ wake_up_event_readers(sp);
+}
+
+static inline int event_available(struct event_buffer *b, struct event_reader *r)
+{
+ return (r->next_serial_number < b->next_serial_number);
+}
+
+/**
+ * get_next_event
+ * Called by event readers (initiated from user space through the file
+ * system).
+ * Sleeps until a new event is available.
+ */
+int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader)
+{
+ struct event_buffer *buffer = sp->event_buffer;
+ struct ibmasm_event *event;
+ unsigned int index;
+ unsigned long flags;
+
+ if (wait_event_interruptible(reader->wait, event_available(buffer, reader)))
+ return -ERESTARTSYS;
+
+ if (!event_available(buffer, reader))
+ return 0;
+
+ spin_lock_irqsave(&sp->lock, flags);
+
+ index = buffer->next_index;
+ event = &buffer->events[index];
+ while (event->serial_number < reader->next_serial_number) {
+ index = (index + 1) % IBMASM_NUM_EVENTS;
+ event = &buffer->events[index];
+ }
+ memcpy(reader->data, event->data, event->data_size);
+ reader->data_size = event->data_size;
+ reader->next_serial_number = event->serial_number + 1;
+
+ spin_unlock_irqrestore(&sp->lock, flags);
+
+ return event->data_size;
+}
+
+void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader)
+{
+ unsigned long flags;
+
+ reader->next_serial_number = sp->event_buffer->next_serial_number;
+ init_waitqueue_head(&reader->wait);
+ spin_lock_irqsave(&sp->lock, flags);
+ list_add(&reader->node, &sp->event_buffer->readers);
+ spin_unlock_irqrestore(&sp->lock, flags);
+}
+
+void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader)
+{
+ unsigned long flags;
+
+ wake_up_interruptible(&reader->wait);
+
+ spin_lock_irqsave(&sp->lock, flags);
+ list_del(&reader->node);
+ spin_unlock_irqrestore(&sp->lock, flags);
+}
+
+int ibmasm_event_buffer_init(struct service_processor *sp)
+{
+ struct event_buffer *buffer;
+ struct ibmasm_event *event;
+ int i;
+
+ buffer = kmalloc(sizeof(struct event_buffer), GFP_KERNEL);
+ if (!buffer)
+ return 1;
+
+ buffer->next_index = 0;
+ buffer->next_serial_number = 1;
+
+ event = buffer->events;
+ for (i=0; i<IBMASM_NUM_EVENTS; i++, event++)
+ event->serial_number = 0;
+
+ INIT_LIST_HEAD(&buffer->readers);
+
+ sp->event_buffer = buffer;
+
+ return 0;
+}
+
+void ibmasm_event_buffer_exit(struct service_processor *sp)
+{
+ wake_up_event_readers(sp);
+ kfree(sp->event_buffer);
+}
diff -Nru a/drivers/misc/ibmasm/heartbeat.c b/drivers/misc/ibmasm/heartbeat.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/heartbeat.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,91 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include <linux/notifier.h>
+#include "ibmasm.h"
+#include "dot_command.h"
+
+static int suspend_heartbeats = 0;
+
+/*
+ * Once the driver indicates to the service processor that it is running
+ * - see send_os_state() - the service processor sends periodic heartbeats
+ * to the driver. The driver must respond to the heartbeats or else the OS
+ * will be rebooted.
+ * In the case of a panic the interrupt handler continues to work and thus
+ * continues to respond to heartbeats, making the service processor believe
+ * the OS is still running and thus preventing a reboot.
+ * To prevent this from happening a callback is added the panic_notifier_list.
+ * Before responding to a heartbeat the driver checks if a panic has happened,
+ * if yes it suspends heartbeat, causing the service processor to reboot as
+ * expected.
+ */
+static int panic_happened(struct notifier_block *n, unsigned long val, void *v)
+{
+ suspend_heartbeats = 1;
+ return 0;
+}
+
+static struct notifier_block panic_notifier = { panic_happened, NULL, 1 };
+
+void ibmasm_register_panic_notifier(void)
+{
+ notifier_chain_register(&panic_notifier_list, &panic_notifier);
+}
+
+void ibmasm_unregister_panic_notifier(void)
+{
+ notifier_chain_unregister(&panic_notifier_list, &panic_notifier);
+}
+
+
+int ibmasm_heartbeat_init(struct service_processor *sp)
+{
+ sp->heartbeat = ibmasm_new_command(HEARTBEAT_BUFFER_SIZE);
+ if (sp->heartbeat == NULL)
+ return -ENOMEM;
+
+ return 0;
+}
+
+void ibmasm_heartbeat_exit(struct service_processor *sp)
+{
+ command_put(sp->heartbeat);
+}
+
+void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size_t size)
+{
+ struct command *cmd = sp->heartbeat;
+ struct dot_command_header *header = (struct dot_command_header *)cmd->buffer;
+
+ if (suspend_heartbeats)
+ return;
+
+ /* return the received dot command to sender */
+ cmd->status = IBMASM_CMD_PENDING;
+ size = min(size, cmd->buffer_size);
+ memcpy(cmd->buffer, message, size);
+ header->type = sp_write;
+ ibmasm_exec_command(sp, cmd);
+}
diff -Nru a/drivers/misc/ibmasm/i2o.h b/drivers/misc/ibmasm/i2o.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/i2o.h Tue Mar 2 19:49:59 2004
@@ -0,0 +1,77 @@
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#pragma pack(1)
+struct i2o_header {
+ u8 version;
+ u8 message_flags;
+ u16 message_size;
+ u8 target;
+ u8 initiator_and_target;
+ u8 initiator;
+ u8 function;
+ u32 initiator_context;
+};
+#pragma pack()
+
+#define I2O_HEADER_TEMPLATE \
+ { .version = 0x01, \
+ .message_flags = 0x00, \
+ .function = 0xFF, \
+ .initiator = 0x00, \
+ .initiator_and_target = 0x40, \
+ .target = 0x00, \
+ .initiator_context = 0x0 }
+
+#define I2O_MESSAGE_SIZE 0x1000
+#define I2O_COMMAND_SIZE (I2O_MESSAGE_SIZE - sizeof(struct i2o_header))
+
+#pragma pack(1)
+struct i2o_message {
+ struct i2o_header header;
+ void *data;
+};
+#pragma pack()
+
+static inline unsigned short outgoing_message_size(unsigned int data_size)
+{
+ unsigned int size;
+ unsigned short i2o_size;
+
+ if (data_size > I2O_COMMAND_SIZE)
+ data_size = I2O_COMMAND_SIZE;
+
+ size = sizeof(struct i2o_header) + data_size;
+
+ i2o_size = size / sizeof(u32);
+
+ if (size % sizeof(u32))
+ i2o_size++;
+
+ return i2o_size;
+}
+
+static inline u32 incoming_data_size(struct i2o_message *i2o_message)
+{
+ return (sizeof(u32) * i2o_message->header.message_size);
+}
diff -Nru a/drivers/misc/ibmasm/ibmasm.h b/drivers/misc/ibmasm/ibmasm.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/ibmasm.h Tue Mar 2 19:49:59 2004
@@ -0,0 +1,224 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/list.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+#include <linux/slab.h>
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/interrupt.h>
+#include <linux/device.h>
+
+/* Driver identification */
+#define DRIVER_NAME "ibmasm"
+#define DRIVER_VERSION "0.4"
+#define DRIVER_AUTHOR "Max Asbock"
+#define DRIVER_DESC "IBM ASM Service Processor Driver"
+
+#define err(msg) printk(KERN_ERR "%s: " msg "\n", DRIVER_NAME)
+#define info(msg) printk(KERN_INFO "%s: " msg "\n", DRIVER_NAME)
+
+
+#define IBMASM_CMD_PENDING 0
+#define IBMASM_CMD_COMPLETE 1
+#define IBMASM_CMD_FAILED 2
+
+#define IBMASM_CMD_TIMEOUT_NORMAL 45
+#define IBMASM_CMD_TIMEOUT_EXTRA 240
+
+#define IBMASM_CMD_MAX_BUFFER_SIZE 0x4000
+
+#define REVERSE_HEARTBEAT_TIMEOUT 120
+
+#define HEARTBEAT_BUFFER_SIZE 0x400
+
+#ifdef IA64
+#define IBMASM_DRIVER_VPD "Lin64 6.08 "
+#else
+#define IBMASM_DRIVER_VPD "Lin32 6.08 "
+#endif
+
+#define SYSTEM_STATE_OS_UP 5
+#define SYSTEM_STATE_OS_DOWN 4
+
+#define IBMASM_NAME_SIZE 16
+
+#define IBMASM_NUM_EVENTS 10
+#define IBMASM_EVENT_MAX_SIZE 2048u
+
+
+struct command {
+ struct list_head queue_node;
+ wait_queue_head_t wait;
+ unsigned char *buffer;
+ size_t buffer_size;
+ int status;
+ struct kobject kobj;
+};
+#define to_command(c) container_of(c, struct command, kobj)
+
+static inline void command_put(struct command *cmd)
+{
+ kobject_put(&cmd->kobj);
+}
+
+static inline void command_get(struct command *cmd)
+{
+ kobject_get(&cmd->kobj);
+}
+
+
+struct ibmasm_event {
+ unsigned int serial_number;
+ unsigned int data_size;
+ unsigned char data[IBMASM_EVENT_MAX_SIZE];
+};
+
+struct event_buffer {
+ struct ibmasm_event events[IBMASM_NUM_EVENTS];
+ unsigned int next_serial_number;
+ unsigned int next_index;
+ struct list_head readers;
+};
+
+struct event_reader {
+ unsigned int next_serial_number;
+ wait_queue_head_t wait;
+ struct list_head node;
+ unsigned int data_size;
+ unsigned char data[IBMASM_EVENT_MAX_SIZE];
+};
+
+struct reverse_heartbeat {
+ wait_queue_head_t wait;
+ unsigned int stopped;
+};
+
+
+/* remote console events */
+struct mouse_event {
+ long x;
+ long y;
+ unsigned char buttons;
+ unsigned char transitions;
+};
+
+struct keyboard_event {
+ unsigned long key_code;
+ unsigned char key_down;
+};
+
+struct remote_event {
+ unsigned long type;
+ union {
+ struct mouse_event mouse;
+ struct keyboard_event keyboard;
+ } data;
+};
+
+#define DRIVER_REMOTE_QUEUE_SIZE 240
+
+struct remote_queue {
+ struct remote_event *start;
+ struct remote_event *end;
+ struct remote_event *reader;
+ struct remote_event *writer;
+ unsigned int size;
+ int open;
+ wait_queue_head_t wait;
+};
+
+
+struct service_processor {
+ struct list_head node;
+ spinlock_t lock;
+ void *base_address;
+ unsigned int irq;
+ struct command *current_command;
+ struct command *heartbeat;
+ struct list_head command_queue;
+ struct event_buffer *event_buffer;
+ char dirname[IBMASM_NAME_SIZE];
+ char devname[IBMASM_NAME_SIZE];
+ unsigned int number;
+ struct remote_queue remote_queue;
+ int serial_line;
+ struct device *dev;
+};
+
+/* command processing */
+extern struct command *ibmasm_new_command(size_t buffer_size);
+extern void ibmasm_exec_command(struct service_processor *sp, struct command *cmd);
+extern void ibmasm_wait_for_response(struct command *cmd, int timeout);
+extern void ibmasm_receive_command_response(struct service_processor *sp, void *response, size_t size);
+
+/* event processing */
+extern int ibmasm_event_buffer_init(struct service_processor *sp);
+extern void ibmasm_event_buffer_exit(struct service_processor *sp);
+extern void ibmasm_receive_event(struct service_processor *sp, void *data, unsigned int data_size);
+extern void ibmasm_event_reader_register(struct service_processor *sp, struct event_reader *reader);
+extern void ibmasm_event_reader_unregister(struct service_processor *sp, struct event_reader *reader);
+extern int ibmasm_get_next_event(struct service_processor *sp, struct event_reader *reader);
+
+/* heartbeat - from SP to OS */
+extern void ibmasm_register_panic_notifier(void);
+extern void ibmasm_unregister_panic_notifier(void);
+extern int ibmasm_heartbeat_init(struct service_processor *sp);
+extern void ibmasm_heartbeat_exit(struct service_processor *sp);
+extern void ibmasm_receive_heartbeat(struct service_processor *sp, void *message, size_t size);
+
+/* reverse heartbeat - from OS to SP */
+extern void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb);
+extern int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb);
+extern void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb);
+
+/* dot commands */
+extern void ibmasm_receive_message(struct service_processor *sp, void *data, int data_size);
+extern int ibmasm_send_driver_vpd(struct service_processor *sp);
+extern int ibmasm_send_os_state(struct service_processor *sp, int os_state);
+
+/* low level message processing */
+extern int ibmasm_send_i2o_message(struct service_processor *sp);
+extern irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs);
+
+/* remote console */
+extern void ibmasm_handle_mouse_interrupt(struct service_processor *sp);
+extern int ibmasm_init_remote_queue(struct service_processor *sp);
+extern void ibmasm_free_remote_queue(struct service_processor *sp);
+extern void ibmasm_advance_reader(struct remote_queue *q, unsigned int n);
+extern size_t ibmasm_events_available(struct remote_queue *q);
+
+/* file system */
+extern int ibmasmfs_register(void);
+extern void ibmasmfs_unregister(void);
+extern void ibmasmfs_add_sp(struct service_processor *sp);
+
+/* uart */
+extern void ibmasm_register_uart(struct service_processor *sp);
+extern void ibmasm_unregister_uart(struct service_processor *sp);
diff -Nru a/drivers/misc/ibmasm/lowlevel.c b/drivers/misc/ibmasm/lowlevel.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/lowlevel.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,81 @@
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include "ibmasm.h"
+#include "lowlevel.h"
+#include "i2o.h"
+#include "dot_command.h"
+#include "remote.h"
+
+static struct i2o_header header = I2O_HEADER_TEMPLATE;
+
+
+int ibmasm_send_i2o_message(struct service_processor *sp)
+{
+ u32 mfa;
+ unsigned int command_size;
+ struct i2o_message *message;
+ struct command *command = sp->current_command;
+
+ mfa = get_mfa_inbound(sp->base_address);
+ if (!mfa)
+ return 1;
+
+ command_size = get_dot_command_size(command->buffer);
+ header.message_size = outgoing_message_size(command_size);
+
+ message = get_i2o_message(sp->base_address, mfa);
+
+ memcpy(&message->header, &header, sizeof(struct i2o_header));
+ memcpy(&message->data, command->buffer, command_size);
+
+ set_mfa_inbound(sp->base_address, mfa);
+
+ return 0;
+}
+
+irqreturn_t ibmasm_interrupt_handler(int irq, void * dev_id, struct pt_regs *regs)
+{
+ u32 mfa;
+ struct service_processor *sp = (struct service_processor *)dev_id;
+ void *base_address = sp->base_address;
+
+ if (!sp_interrupt_pending(base_address))
+ return IRQ_NONE;
+
+ if (mouse_interrupt_pending(sp)) {
+ ibmasm_handle_mouse_interrupt(sp);
+ mfa = get_mfa_outbound(base_address);
+ clear_mouse_interrupt(sp);
+ set_mfa_outbound(base_address, mfa);
+ return IRQ_HANDLED;
+ }
+
+ mfa = get_mfa_outbound(base_address);
+ if (valid_mfa(mfa)) {
+ struct i2o_message *msg = get_i2o_message(base_address, mfa);
+ ibmasm_receive_message(sp, &msg->data, incoming_data_size(msg));
+ }
+ set_mfa_outbound(base_address, mfa);
+ return IRQ_HANDLED;
+}
diff -Nru a/drivers/misc/ibmasm/lowlevel.h b/drivers/misc/ibmasm/lowlevel.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/lowlevel.h Tue Mar 2 19:49:59 2004
@@ -0,0 +1,137 @@
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+/* Condor service processor specific hardware definitions */
+
+#ifndef __IBMASM_CONDOR_H__
+#define __IBMASM_CONDOR_H__
+
+#include <asm/io.h>
+
+#define VENDORID_IBM 0x1014
+#define DEVICEID_RSA 0x010F
+
+#define GET_MFA_ADDR(x) (x & 0xFFFFFF00)
+
+#define MAILBOX_FULL(x) (x & 0x00000001)
+
+#define NO_MFAS_AVAILABLE 0xFFFFFFFF
+
+
+#define INBOUND_QUEUE_PORT 0x40 /* contains address of next free MFA */
+#define OUTBOUND_QUEUE_PORT 0x44 /* contains address of posted MFA */
+
+#define SP_INTR_MASK 0x00000008
+#define UART_INTR_MASK 0x00000010
+
+#define INTR_STATUS_REGISTER 0x13A0
+#define INTR_CONTROL_REGISTER 0x13A4
+
+#define SCOUT_COM_A_BASE 0x0000
+#define SCOUT_COM_B_BASE 0x0100
+#define SCOUT_COM_C_BASE 0x0200
+#define SCOUT_COM_D_BASE 0x0300
+
+static inline int sp_interrupt_pending(void *base_address)
+{
+ return SP_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
+}
+
+static inline int uart_interrupt_pending(void *base_address)
+{
+ return UART_INTR_MASK & readl(base_address + INTR_STATUS_REGISTER);
+}
+
+static inline void ibmasm_enable_interrupts(void *base_address, int mask)
+{
+ void *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
+ writel( readl(ctrl_reg) & ~mask, ctrl_reg);
+}
+
+static inline void ibmasm_disable_interrupts(void *base_address, int mask)
+{
+ void *ctrl_reg = base_address + INTR_CONTROL_REGISTER;
+ writel( readl(ctrl_reg) | mask, ctrl_reg);
+}
+
+static inline void enable_sp_interrupts(void *base_address)
+{
+ ibmasm_enable_interrupts(base_address, SP_INTR_MASK);
+}
+
+static inline void disable_sp_interrupts(void *base_address)
+{
+ ibmasm_disable_interrupts(base_address, SP_INTR_MASK);
+}
+
+static inline void enable_uart_interrupts(void *base_address)
+{
+ ibmasm_enable_interrupts(base_address, UART_INTR_MASK);
+}
+
+static inline void disable_uart_interrupts(void *base_address)
+{
+ ibmasm_disable_interrupts(base_address, UART_INTR_MASK);
+}
+
+#define valid_mfa(mfa) ( (mfa) != NO_MFAS_AVAILABLE )
+
+static inline u32 get_mfa_outbound(void *base_address)
+{
+ int retry;
+ u32 mfa;
+
+ for (retry=0; retry<=10; retry++) {
+ mfa = readl(base_address + OUTBOUND_QUEUE_PORT);
+ if (valid_mfa(mfa))
+ break;
+ }
+ return mfa;
+}
+
+static inline void set_mfa_outbound(void *base_address, u32 mfa)
+{
+ writel(mfa, base_address + OUTBOUND_QUEUE_PORT);
+}
+
+static inline u32 get_mfa_inbound(void *base_address)
+{
+ u32 mfa = readl(base_address + INBOUND_QUEUE_PORT);
+
+ if (MAILBOX_FULL(mfa))
+ return 0;
+
+ return mfa;
+}
+
+static inline void set_mfa_inbound(void *base_address, u32 mfa)
+{
+ writel(mfa, base_address + INBOUND_QUEUE_PORT);
+}
+
+static inline struct i2o_message *get_i2o_message(void *base_address, u32 mfa)
+{
+ return (struct i2o_message *)(GET_MFA_ADDR(mfa) + base_address);
+}
+
+#endif /* __IBMASM_CONDOR_H__ */
diff -Nru a/drivers/misc/ibmasm/module.c b/drivers/misc/ibmasm/module.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/module.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,210 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ * This driver is based on code originally written by Pete Reynolds
+ * and others.
+ *
+ */
+
+/*
+ * The ASM device driver does the following things:
+ *
+ * 1) When loaded it sends a message to the service processor,
+ * indicating that an OS is * running. This causes the service processor
+ * to send periodic heartbeats to the OS.
+ *
+ * 2) Answers the periodic heartbeats sent by the service processor.
+ * Failure to do so would result in system reboot.
+ *
+ * 3) Acts as a pass through for dot commands sent from user applications.
+ * The interface for this is the ibmasmfs file system.
+ *
+ * 4) Allows user applications to register for event notification. Events
+ * are sent to the driver through interrupts. They can be read from user
+ * space through the ibmasmfs file system.
+ *
+ * 5) Allows user space applications to send heartbeats to the service
+ * processor (aka reverse heartbeats). Again this happens through ibmasmfs.
+ *
+ * 6) Handles remote mouse and keyboard event interrupts and makes them
+ * available to user applications through ibmasmfs.
+ *
+ */
+
+#include <linux/pci.h>
+#include <linux/init.h>
+#include "ibmasm.h"
+#include "lowlevel.h"
+#include "remote.h"
+
+
+static int __init ibmasm_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+ int result = -ENOMEM;
+ struct service_processor *sp;
+
+ sp = kmalloc(sizeof(struct service_processor), GFP_KERNEL);
+ if (sp == NULL) {
+ dev_err(&pdev->dev, "Failed to allocate memory\n");
+ return result;
+ }
+ memset(sp, 0, sizeof(struct service_processor));
+
+ pci_set_drvdata(pdev, (void *)sp);
+ sp->dev = &pdev->dev;
+ sp->number = pdev->bus->number;
+ snprintf(sp->dirname, IBMASM_NAME_SIZE, "%d", sp->number);
+ snprintf(sp->devname, IBMASM_NAME_SIZE, "%s%d", DRIVER_NAME, sp->number);
+
+ if (ibmasm_event_buffer_init(sp)) {
+ dev_err(sp->dev, "Failed to allocate event buffer\n");
+ goto error_eventbuffer;
+ }
+
+ if (ibmasm_heartbeat_init(sp)) {
+ dev_err(sp->dev, "Failed to allocate heartbeat command\n");
+ goto error_heartbeat;
+ }
+
+ sp->irq = pdev->irq;
+ sp->base_address = ioremap(pci_resource_start(pdev, 0),
+ pci_resource_len(pdev, 0));
+ if (sp->base_address == 0) {
+ dev_err(sp->dev, "Failed to ioremap pci memory\n");
+ result = -ENODEV;
+ goto error_ioremap;
+ }
+
+ result = ibmasm_init_remote_queue(sp);
+ if (result) {
+ dev_err(sp->dev, "Failed to initialize remote queue\n");
+ goto error_remote_queue;
+ }
+
+ sp->lock = SPIN_LOCK_UNLOCKED;
+ INIT_LIST_HEAD(&sp->command_queue);
+
+ result = request_irq(sp->irq, ibmasm_interrupt_handler, SA_SHIRQ, sp->devname, (void*)sp);
+ if (result) {
+ dev_err(sp->dev, "Failed to register interrupt handler\n");
+ goto error_request_irq;
+ }
+
+ enable_sp_interrupts(sp->base_address);
+ disable_mouse_interrupts(sp);
+
+ result = ibmasm_send_driver_vpd(sp);
+ if (result) {
+ dev_err(sp->dev, "Failed to send driver VPD to service processor\n");
+ goto error_send_message;
+ }
+ result = ibmasm_send_os_state(sp, SYSTEM_STATE_OS_UP);
+ if (result) {
+ dev_err(sp->dev, "Failed to send OS state to service processor\n");
+ goto error_send_message;
+ }
+ ibmasmfs_add_sp(sp);
+
+ ibmasm_register_uart(sp);
+
+ return 0;
+
+error_send_message:
+ disable_sp_interrupts(sp->base_address);
+ free_irq(sp->irq, (void *)sp);
+error_request_irq:
+ ibmasm_free_remote_queue(sp);
+error_remote_queue:
+ iounmap(sp->base_address);
+error_ioremap:
+ ibmasm_heartbeat_exit(sp);
+error_heartbeat:
+ ibmasm_event_buffer_exit(sp);
+error_eventbuffer:
+ kfree(sp);
+
+ return result;
+}
+
+static void __exit ibmasm_remove_one(struct pci_dev *pdev)
+{
+ struct service_processor *sp = (struct service_processor *)pci_get_drvdata(pdev);
+
+ ibmasm_unregister_uart(sp);
+ ibmasm_send_os_state(sp, SYSTEM_STATE_OS_DOWN);
+ disable_sp_interrupts(sp->base_address);
+ disable_mouse_interrupts(sp);
+ free_irq(sp->irq, (void *)sp);
+ ibmasm_heartbeat_exit(sp);
+ ibmasm_free_remote_queue(sp);
+ iounmap(sp->base_address);
+ ibmasm_event_buffer_exit(sp);
+ kfree(sp);
+}
+
+static struct pci_device_id ibmasm_pci_table[] =
+{
+ { PCI_DEVICE(VENDORID_IBM, DEVICEID_RSA) },
+ {},
+};
+
+static struct pci_driver ibmasm_driver = {
+ .name = DRIVER_NAME,
+ .id_table = ibmasm_pci_table,
+ .probe = ibmasm_init_one,
+ .remove = __devexit_p(ibmasm_remove_one),
+};
+
+static void __exit ibmasm_exit (void)
+{
+ ibmasm_unregister_panic_notifier();
+ ibmasmfs_unregister();
+ pci_unregister_driver(&ibmasm_driver);
+ info(DRIVER_DESC " version " DRIVER_VERSION " unloaded");
+}
+
+static int __init ibmasm_init(void)
+{
+ int result;
+
+ result = ibmasmfs_register();
+ if (result) {
+ err("Failed to register ibmasmfs file system");
+ return result;
+ }
+ result = pci_register_driver(&ibmasm_driver);
+ if (result <= 0) {
+ pci_unregister_driver(&ibmasm_driver);
+ ibmasmfs_unregister();
+ return -ENODEV;
+ }
+ ibmasm_register_panic_notifier();
+ info(DRIVER_DESC " version " DRIVER_VERSION " loaded");
+ return 0;
+}
+
+module_init(ibmasm_init);
+module_exit(ibmasm_exit);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/misc/ibmasm/r_heartbeat.c b/drivers/misc/ibmasm/r_heartbeat.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/r_heartbeat.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,98 @@
+
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include "ibmasm.h"
+#include "dot_command.h"
+
+/*
+ * Reverse Heartbeat, i.e. heartbeats sent from the driver to the
+ * service processor.
+ * These heartbeats are initiated by user level programs.
+ */
+
+/* the reverse heartbeat dot command */
+#pragma pack(1)
+static struct {
+ struct dot_command_header header;
+ unsigned char command[3];
+} rhb_dot_cmd = {
+ .header = {
+ .type = sp_read,
+ .command_size = 3,
+ .data_size = 0,
+ .status = 0
+ },
+ .command = { 4, 3, 6 }
+};
+#pragma pack()
+
+void ibmasm_init_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
+{
+ init_waitqueue_head(&rhb->wait);
+ rhb->stopped = 0;
+}
+
+/**
+ * start_reverse_heartbeat
+ * Loop forever, sending a reverse heartbeat dot command to the service
+ * processor, then sleeping. The loop comes to an end if the service
+ * processor fails to respond 3 times or we were interrupted.
+ */
+int ibmasm_start_reverse_heartbeat(struct service_processor *sp, struct reverse_heartbeat *rhb)
+{
+ struct command *cmd;
+ int times_failed = 0;
+ int result = 1;
+
+ cmd = ibmasm_new_command(sizeof rhb_dot_cmd);
+ if (!cmd)
+ return -ENOMEM;
+
+ while (times_failed < 3) {
+ memcpy(cmd->buffer, (void *)&rhb_dot_cmd, sizeof rhb_dot_cmd);
+ cmd->status = IBMASM_CMD_PENDING;
+ ibmasm_exec_command(sp, cmd);
+ ibmasm_wait_for_response(cmd, IBMASM_CMD_TIMEOUT_NORMAL);
+
+ if (cmd->status != IBMASM_CMD_COMPLETE)
+ times_failed++;
+
+ wait_event_interruptible_timeout(rhb->wait,
+ rhb->stopped,
+ REVERSE_HEARTBEAT_TIMEOUT * HZ);
+
+ if (signal_pending(current) || rhb->stopped) {
+ result = -EINTR;
+ break;
+ }
+ }
+ command_put(cmd);
+ rhb->stopped = 0;
+
+ return result;
+}
+
+void ibmasm_stop_reverse_heartbeat(struct reverse_heartbeat *rhb)
+{
+ rhb->stopped = 1;
+ wake_up_interruptible(&rhb->wait);
+}
diff -Nru a/drivers/misc/ibmasm/remote.c b/drivers/misc/ibmasm/remote.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/remote.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,152 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+/* Remote mouse and keyboard event handling functions */
+
+#include "ibmasm.h"
+#include "remote.h"
+
+int ibmasm_init_remote_queue(struct service_processor *sp)
+{
+ struct remote_queue *q = &sp->remote_queue;
+
+ disable_mouse_interrupts(sp);
+
+ q->open = 0;
+ q->size = 0;
+
+ q->start = kmalloc(DRIVER_REMOTE_QUEUE_SIZE * sizeof(struct remote_event), GFP_KERNEL);
+ if (q->start == 0)
+ return -ENOMEM;
+
+ q->end = q->start + DRIVER_REMOTE_QUEUE_SIZE;
+ q->reader = q->start;
+ q->writer = q->start;
+ q->size = DRIVER_REMOTE_QUEUE_SIZE;
+ init_waitqueue_head(&q->wait);
+
+ return 0;
+}
+
+void ibmasm_free_remote_queue(struct service_processor *sp)
+{
+ kfree(sp->remote_queue.start);
+}
+
+void ibmasm_advance_reader(struct remote_queue *q, unsigned int n)
+{
+ q->reader += n;
+ if (q->reader >= q->end)
+ q->reader -= q->size;
+}
+
+size_t ibmasm_events_available(struct remote_queue *q)
+{
+ ssize_t diff = q->writer - q->reader;
+
+ return (diff >= 0) ? diff : q->end - q->reader;
+}
+
+
+static int space_free(struct remote_queue *q)
+{
+ if (q->reader == q->writer)
+ return q->size - 1;
+
+ return ( (q->reader + q->size - q->writer) % q->size ) - 1;
+}
+
+static void set_mouse_event(struct remote_input *input, struct mouse_event *mouse)
+{
+ static char last_buttons = 0;
+
+ mouse->x = input->data.mouse.x;
+ mouse->y = input->data.mouse.y;
+
+ if (input->mouse_buttons == REMOTE_MOUSE_DOUBLE_CLICK) {
+ mouse->buttons = REMOTE_MOUSE_DOUBLE_CLICK;
+ last_buttons = 0;
+ return;
+ }
+ mouse->transitions = last_buttons ^ input->mouse_buttons;
+ mouse->buttons = input->mouse_buttons;
+
+ last_buttons = input->mouse_buttons;
+}
+
+static void set_keyboard_event(struct remote_input *input, struct keyboard_event *keyboard)
+{
+ keyboard->key_code = input->data.keyboard.key_code;
+ keyboard->key_down = input->data.keyboard.key_down;
+}
+
+static int add_to_driver_queue(struct remote_queue *q, struct remote_input *input)
+{
+ struct remote_event *event = q->writer;
+
+ if (space_free(q) < 1) {
+ return 1;
+ }
+
+ switch(input->type) {
+ case (INPUT_TYPE_MOUSE):
+ event->type = INPUT_TYPE_MOUSE;
+ set_mouse_event(input, &event->data.mouse);
+ break;
+ case (INPUT_TYPE_KEYBOARD):
+ event->type = INPUT_TYPE_KEYBOARD;
+ set_keyboard_event(input, &event->data.keyboard);
+ break;
+ default:
+ return 0;
+ }
+ event->type = input->type;
+
+ q->writer++;
+ if (q->writer == q->end)
+ q->writer = q->start;
+
+ return 0;
+}
+
+
+void ibmasm_handle_mouse_interrupt(struct service_processor *sp)
+{
+ unsigned long reader;
+ unsigned long writer;
+ struct remote_input input;
+
+ reader = get_queue_reader(sp);
+ writer = get_queue_writer(sp);
+
+ while (reader != writer) {
+ memcpy(&input, (void *)get_queue_entry(sp, reader), sizeof(struct remote_input));
+
+ if (add_to_driver_queue(&sp->remote_queue, &input))
+ break;
+
+ reader = advance_queue_reader(sp, reader);
+ }
+ wake_up_interruptible(&sp->remote_queue.wait);
+}
diff -Nru a/drivers/misc/ibmasm/remote.h b/drivers/misc/ibmasm/remote.h
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/remote.h Tue Mar 2 19:49:59 2004
@@ -0,0 +1,119 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ * Orignally written by Pete Reynolds
+ */
+
+#ifndef _IBMASM_REMOTE_H_
+#define _IBMASM_REMOTE_H_
+
+#include <asm/io.h>
+
+/* pci offsets */
+#define CONDOR_MOUSE_DATA 0x000AC000
+#define CONDOR_MOUSE_ISR_CONTROL 0x00
+#define CONDOR_MOUSE_ISR_STATUS 0x04
+#define CONDOR_MOUSE_Q_READER 0x08
+#define CONDOR_MOUSE_Q_WRITER 0x0C
+#define CONDOR_MOUSE_Q_BEGIN 0x10
+#define CONDOR_MOUSE_MAX_X 0x14
+#define CONDOR_MOUSE_MAX_Y 0x18
+
+#define CONDOR_INPUT_DESKTOP_INFO 0x1F0
+#define CONDOR_INPUT_DISPLAY_RESX 0x1F4
+#define CONDOR_INPUT_DISPLAY_RESY 0x1F8
+#define CONDOR_INPUT_DISPLAY_BITS 0x1FC
+#define CONDOR_OUTPUT_VNC_STATUS 0x200
+
+#define CONDOR_MOUSE_INTR_STATUS_MASK 0x00000001
+
+#define INPUT_TYPE_MOUSE 0x1
+#define INPUT_TYPE_KEYBOARD 0x2
+
+
+/* mouse button states received from SP */
+#define REMOTE_MOUSE_DOUBLE_CLICK 0xF0
+#define REMOTE_MOUSE_BUTTON_LEFT 0x01
+#define REMOTE_MOUSE_BUTTON_MIDDLE 0x02
+#define REMOTE_MOUSE_BUTTON_RIGHT 0x04
+
+
+struct mouse_input {
+ unsigned short y;
+ unsigned short x;
+};
+
+
+struct keyboard_input {
+ unsigned short key_code;
+ unsigned char key_flag;
+ unsigned char key_down;
+};
+
+
+
+struct remote_input {
+ union {
+ struct mouse_input mouse;
+ struct keyboard_input keyboard;
+ } data;
+
+ unsigned char type;
+ unsigned char pad1;
+ unsigned char mouse_buttons;
+ unsigned char pad3;
+};
+
+#define mouse_addr(sp) sp->base_address + CONDOR_MOUSE_DATA
+#define display_width(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESX
+#define display_height(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_RESY
+#define display_depth(sp) mouse_addr(sp) + CONDOR_INPUT_DISPLAY_BITS
+#define vnc_status(sp) mouse_addr(sp) + CONDOR_OUTPUT_VNC_STATUS
+
+#define mouse_interrupt_pending(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
+#define clear_mouse_interrupt(sp) writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_STATUS)
+#define enable_mouse_interrupts(sp) writel(1, mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL)
+#define disable_mouse_interrupts(sp) writel(0, mouse_addr(sp) + CONDOR_MOUSE_ISR_CONTROL)
+
+/* remote input queue operations */
+#define REMOTE_QUEUE_SIZE 60
+
+#define get_queue_writer(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_Q_WRITER)
+#define get_queue_reader(sp) readl(mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
+#define set_queue_reader(sp, reader) writel(reader, mouse_addr(sp) + CONDOR_MOUSE_Q_READER)
+
+#define queue_begin mouse_addr(sp) + CONDOR_MOUSE_Q_BEGIN
+
+#define get_queue_entry(sp, read_index) \
+ queue_begin + read_index * sizeof(struct remote_input)
+
+static inline int advance_queue_reader(struct service_processor *sp, unsigned long reader)
+{
+ reader++;
+ if (reader == REMOTE_QUEUE_SIZE)
+ reader = 0;
+
+ set_queue_reader(sp, reader);
+ return reader;
+}
+
+#endif /* _IBMASM_REMOTE_H_ */
diff -Nru a/drivers/misc/ibmasm/uart.c b/drivers/misc/ibmasm/uart.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/uart.c Tue Mar 2 19:49:59 2004
@@ -0,0 +1,72 @@
+
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+#include <linux/termios.h>
+#include <linux/tty.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/serial_reg.h>
+#include "ibmasm.h"
+#include "lowlevel.h"
+
+
+void ibmasm_register_uart(struct service_processor *sp)
+{
+ struct serial_struct serial;
+ unsigned char *iomem_base;
+
+ iomem_base = sp->base_address + SCOUT_COM_B_BASE;
+
+ /* read the uart scratch register to determine if the UART
+ * is dedicated to the service processor or if the OS can use it
+ */
+ if (0 == readl(iomem_base + UART_SCR)) {
+ dev_info(sp->dev, "IBM SP UART not registered, owned by service processor\n");
+ sp->serial_line = -1;
+ return;
+ }
+
+ memset(&serial, 0, sizeof(serial));
+ serial.irq = sp->irq;
+ serial.baud_base = 3686400 / 16;
+ serial.flags = UPF_AUTOPROBE | UPF_SHARE_IRQ;
+ serial.io_type = UPIO_MEM;
+ serial.iomem_base = iomem_base;
+
+ sp->serial_line = register_serial(&serial);
+ if (sp->serial_line < 0) {
+ dev_err(sp->dev, "Failed to register serial port\n");
+ return;
+ }
+ enable_uart_interrupts(sp->base_address);
+}
+
+void ibmasm_unregister_uart(struct service_processor *sp)
+{
+ if (sp->serial_line < 0)
+ return;
+
+ disable_uart_interrupts(sp->base_address);
+ unregister_serial(sp->serial_line);
+}
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.17.2, 2004/02/26 16:31:27-08:00, akpm@osdl.org
[PATCH] fix x86_64 build for sys_device_register rename
fix x86_64 build for sys_device_register rename
arch/x86_64/kernel/mce.c | 2 +-
arch/x86_64/kernel/time.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff -Nru a/arch/x86_64/kernel/mce.c b/arch/x86_64/kernel/mce.c
--- a/arch/x86_64/kernel/mce.c Tue Mar 2 19:51:20 2004
+++ b/arch/x86_64/kernel/mce.c Tue Mar 2 19:51:20 2004
@@ -448,7 +448,7 @@
return -EIO;
err = sysdev_class_register(&mce_sysclass);
if (!err)
- err = sys_device_register(&device_mce);
+ err = sysdev_register(&device_mce);
if (!err) {
/* could create per CPU objects, but is not worth it. */
sysdev_create_file(&device_mce, &attr_disabled_banks);
diff -Nru a/arch/x86_64/kernel/time.c b/arch/x86_64/kernel/time.c
--- a/arch/x86_64/kernel/time.c Tue Mar 2 19:51:20 2004
+++ b/arch/x86_64/kernel/time.c Tue Mar 2 19:51:20 2004
@@ -788,7 +788,7 @@
{
int error = sysdev_class_register(&pit_sysclass);
if (!error)
- error = sys_device_register(&device_i8253);
+ error = sysdev_register(&device_i8253);
return error;
}
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 8:00 ` Christoph Hellwig
1 sibling, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.17.6, 2004/02/27 11:40:48-08:00, masbock@us.ibm.com
[PATCH] Driver for IBM service processor - updated (2/2)
Here is the filesystem part for the IBM RSA service processor device driver
drivers/misc/ibmasm/ibmasmfs.c | 717 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 717 insertions(+)
diff -Nru a/drivers/misc/ibmasm/ibmasmfs.c b/drivers/misc/ibmasm/ibmasmfs.c
--- /dev/null Wed Dec 31 16:00:00 1969
+++ b/drivers/misc/ibmasm/ibmasmfs.c Tue Mar 2 19:49:32 2004
@@ -0,0 +1,717 @@
+/*
+ * IBM ASM Service Processor Device Driver
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Copyright (C) IBM Corporation, 2004
+ *
+ * Author: Max Asböck <amax@us.ibm.com>
+ *
+ */
+
+/*
+ * Parts of this code are based on an article by Jonathan Corbet
+ * that appeared in Linux Weekly News.
+ */
+
+
+/*
+ * The IBMASM file virtual filesystem. It creates the following hierarchy
+ * dymamically when mounted from user space:
+ *
+ * /ibmasm
+ * |-- 0
+ * | |-- command
+ * | |-- event
+ * | |-- reverse_heartbeat
+ * | `-- remote_video
+ * | |-- connected
+ * | |-- depth
+ * | |-- events
+ * | |-- height
+ * | `-- width
+ * .
+ * .
+ * .
+ * `-- n
+ * |-- command
+ * |-- event
+ * |-- reverse_heartbeat
+ * `-- remote_video
+ * |-- connected
+ * |-- depth
+ * |-- events
+ * |-- height
+ * `-- width
+ *
+ * For each service processor the following files are created:
+ *
+ * command: execute dot commands
+ * write: execute a dot command on the service processor
+ * read: return the result of a previously executed dot command
+ *
+ * events: listen for service processor events
+ * read: sleep (interruptible) until an event occurs
+ * write: wakeup sleeping event listener
+ *
+ * reverse_heartbeat: send a heartbeat to the service processor
+ * read: sleep (interruptible) until the reverse heartbeat fails
+ * write: wakeup sleeping heartbeat listener
+ *
+ * remote_video/width
+ * remote_video/height
+ * remote_video/width: control remote display settings
+ * write: set value
+ * read: read value
+ *
+ * remote_video/connected
+ * read: return "1" if web browser VNC java applet is connected,
+ * "0" otherwise
+ *
+ * remote_video/events
+ * read: sleep until a remote mouse or keyboard event occurs, then return
+ * then event.
+ */
+
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <asm/uaccess.h>
+#include <asm/io.h>
+#include "ibmasm.h"
+#include "remote.h"
+#include "dot_command.h"
+
+#define IBMASMFS_MAGIC 0x66726f67
+
+static LIST_HEAD(service_processors);
+
+static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode);
+static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root);
+static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent);
+
+
+static struct super_block *ibmasmfs_get_super(struct file_system_type *fst,
+ int flags, const char *name, void *data)
+{
+ return get_sb_single(fst, flags, data, ibmasmfs_fill_super);
+}
+
+static struct super_operations ibmasmfs_s_ops = {
+ .statfs = simple_statfs,
+ .drop_inode = generic_delete_inode,
+};
+
+static struct file_operations *ibmasmfs_dir_ops = &simple_dir_operations;
+
+static struct file_system_type ibmasmfs_type = {
+ .owner = THIS_MODULE,
+ .name = "ibmasmfs",
+ .get_sb = ibmasmfs_get_super,
+ .kill_sb = kill_litter_super,
+};
+
+static int ibmasmfs_fill_super (struct super_block *sb, void *data, int silent)
+{
+ struct inode *root;
+ struct dentry *root_dentry;
+
+ sb->s_blocksize = PAGE_CACHE_SIZE;
+ sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+ sb->s_magic = IBMASMFS_MAGIC;
+ sb->s_op = &ibmasmfs_s_ops;
+
+ root = ibmasmfs_make_inode (sb, S_IFDIR | 0500);
+ if (!root)
+ return -ENOMEM;
+
+ root->i_op = &simple_dir_inode_operations;
+ root->i_fop = ibmasmfs_dir_ops;
+
+ root_dentry = d_alloc_root(root);
+ if (!root_dentry) {
+ iput(root);
+ return -ENOMEM;
+ }
+ sb->s_root = root_dentry;
+
+ ibmasmfs_create_files(sb, root_dentry);
+ return 0;
+}
+
+static struct inode *ibmasmfs_make_inode(struct super_block *sb, int mode)
+{
+ struct inode *ret = new_inode(sb);
+
+ if (ret) {
+ ret->i_mode = mode;
+ ret->i_uid = ret->i_gid = 0;
+ ret->i_blksize = PAGE_CACHE_SIZE;
+ ret->i_blocks = 0;
+ ret->i_atime = ret->i_mtime = ret->i_ctime = CURRENT_TIME;
+ }
+ return ret;
+}
+
+static struct dentry *ibmasmfs_create_file (struct super_block *sb,
+ struct dentry *parent,
+ const char *name,
+ struct file_operations *fops,
+ void *data,
+ int mode)
+{
+ struct dentry *dentry;
+ struct inode *inode;
+ struct qstr qname;
+
+ qname.name = name;
+ qname.len = strlen (name);
+ qname.hash = full_name_hash(name, qname.len);
+
+ dentry = d_alloc(parent, &qname);
+ if (!dentry)
+ return NULL;
+
+ inode = ibmasmfs_make_inode(sb, S_IFREG | mode);
+ if (!inode) {
+ dput(dentry);
+ return NULL;
+ }
+
+ inode->i_fop = fops;
+ inode->u.generic_ip = data;
+
+ d_add(dentry, inode);
+ return dentry;
+}
+
+static struct dentry *ibmasmfs_create_dir (struct super_block *sb,
+ struct dentry *parent,
+ const char *name)
+{
+ struct dentry *dentry;
+ struct inode *inode;
+ struct qstr qname;
+
+ qname.name = name;
+ qname.len = strlen (name);
+ qname.hash = full_name_hash(name, qname.len);
+ dentry = d_alloc(parent, &qname);
+ if (!dentry)
+ return NULL;
+
+ inode = ibmasmfs_make_inode(sb, S_IFDIR | 0500);
+ if (!inode) {
+ dput(dentry);
+ return NULL;
+ }
+
+ inode->i_op = &simple_dir_inode_operations;
+ inode->i_fop = ibmasmfs_dir_ops;
+
+ d_add(dentry, inode);
+ return dentry;
+}
+
+int ibmasmfs_register()
+{
+ return register_filesystem(&ibmasmfs_type);
+}
+
+void ibmasmfs_unregister()
+{
+ unregister_filesystem(&ibmasmfs_type);
+}
+
+void ibmasmfs_add_sp(struct service_processor *sp)
+{
+ list_add(&sp->node, &service_processors);
+}
+
+/* struct to save state between command file operations */
+struct ibmasmfs_command_data {
+ struct service_processor *sp;
+ struct command *command;
+};
+
+/* struct to save state between event file operations */
+struct ibmasmfs_event_data {
+ struct service_processor *sp;
+ struct event_reader reader;
+ int active;
+};
+
+/* struct to save state between reverse heartbeat file operations */
+struct ibmasmfs_heartbeat_data {
+ struct service_processor *sp;
+ struct reverse_heartbeat heartbeat;
+ int active;
+};
+
+static int command_file_open(struct inode *inode, struct file *file)
+{
+ struct ibmasmfs_command_data *command_data;
+
+ if (!inode->u.generic_ip)
+ return -ENODEV;
+
+ command_data = kmalloc(sizeof(struct ibmasmfs_command_data), GFP_KERNEL);
+ if (!command_data)
+ return -ENOMEM;
+
+ command_data->command = NULL;
+ command_data->sp = inode->u.generic_ip;
+ file->private_data = command_data;
+ return 0;
+}
+
+static int command_file_close(struct inode *inode, struct file *file)
+{
+ struct ibmasmfs_command_data *command_data = file->private_data;
+
+ if (command_data->command)
+ command_put(command_data->command);
+
+ kfree(command_data);
+ return 0;
+}
+
+static ssize_t command_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+{
+ struct ibmasmfs_command_data *command_data = file->private_data;
+ struct command *cmd;
+ int len;
+ unsigned long flags;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ spin_lock_irqsave(&command_data->sp->lock, flags);
+ cmd = command_data->command;
+ if (cmd == NULL) {
+ spin_unlock_irqrestore(&command_data->sp->lock, flags);
+ return 0;
+ }
+ command_data->command = NULL;
+ spin_unlock_irqrestore(&command_data->sp->lock, flags);
+
+ if (cmd->status != IBMASM_CMD_COMPLETE) {
+ command_put(cmd);
+ return -EIO;
+ }
+ len = min(count, cmd->buffer_size);
+ if (copy_to_user(buf, cmd->buffer, len)) {
+ command_put(cmd);
+ return -EFAULT;
+ }
+ command_put(cmd);
+
+ return len;
+}
+
+static ssize_t command_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
+{
+ struct ibmasmfs_command_data *command_data = file->private_data;
+ struct command *cmd;
+ unsigned long flags;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count == 0 || count > IBMASM_CMD_MAX_BUFFER_SIZE)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ /* commands are executed sequentially, only one command at a time */
+ if (command_data->command)
+ return -EAGAIN;
+
+ cmd = ibmasm_new_command(count);
+ if (!cmd)
+ return -ENOMEM;
+
+ if (copy_from_user((void *)cmd->buffer, (void *)ubuff, count)) {
+ command_put(cmd);
+ return -EFAULT;
+ }
+
+ spin_lock_irqsave(&command_data->sp->lock, flags);
+ if (command_data->command) {
+ spin_unlock_irqrestore(&command_data->sp->lock, flags);
+ command_put(cmd);
+ return -EAGAIN;
+ }
+ command_data->command = cmd;
+ spin_unlock_irqrestore(&command_data->sp->lock, flags);
+
+ ibmasm_exec_command(command_data->sp, cmd);
+ ibmasm_wait_for_response(cmd, get_dot_command_timeout(cmd->buffer));
+
+ return count;
+}
+
+static int event_file_open(struct inode *inode, struct file *file)
+{
+ struct ibmasmfs_event_data *event_data;
+ struct service_processor *sp;
+
+ if (!inode->u.generic_ip)
+ return -ENODEV;
+
+ sp = inode->u.generic_ip;
+
+ event_data = kmalloc(sizeof(struct ibmasmfs_event_data), GFP_KERNEL);
+ if (!event_data)
+ return -ENOMEM;
+
+ ibmasm_event_reader_register(sp, &event_data->reader);
+
+ event_data->sp = sp;
+ file->private_data = event_data;
+ return 0;
+}
+
+static int event_file_close(struct inode *inode, struct file *file)
+{
+ struct ibmasmfs_event_data *event_data = file->private_data;
+
+ ibmasm_event_reader_unregister(event_data->sp, &event_data->reader);
+ kfree(event_data);
+ return 0;
+}
+
+static ssize_t event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+{
+ struct ibmasmfs_event_data *event_data = file->private_data;
+ struct event_reader *reader = &event_data->reader;
+ int ret;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count == 0 || count > IBMASM_EVENT_MAX_SIZE)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ ret = ibmasm_get_next_event(event_data->sp, reader);
+ if (ret <= 0)
+ return ret;
+
+ if (count < reader->data_size)
+ return -EINVAL;
+
+ if (copy_to_user(buf, reader->data, reader->data_size))
+ return -EFAULT;
+
+ return reader->data_size;
+}
+
+static ssize_t event_file_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+{
+ struct ibmasmfs_event_data *event_data = file->private_data;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count != 1)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ wake_up_interruptible(&event_data->reader.wait);
+ return 0;
+}
+
+static int r_heartbeat_file_open(struct inode *inode, struct file *file)
+{
+ struct ibmasmfs_heartbeat_data *rhbeat;
+
+ if (!inode->u.generic_ip)
+ return -ENODEV;
+
+ rhbeat = kmalloc(sizeof(struct ibmasmfs_heartbeat_data), GFP_KERNEL);
+ if (!rhbeat)
+ return -ENOMEM;
+
+ rhbeat->sp = (struct service_processor *)inode->u.generic_ip;
+ rhbeat->active = 0;
+ ibmasm_init_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);
+ file->private_data = rhbeat;
+ return 0;
+}
+
+static int r_heartbeat_file_close(struct inode *inode, struct file *file)
+{
+ struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
+
+ kfree(rhbeat);
+ return 0;
+}
+
+static ssize_t r_heartbeat_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+{
+ struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
+ unsigned long flags;
+ int result;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count == 0 || count > 1024)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ /* allow only one reverse heartbeat per process */
+ spin_lock_irqsave(&rhbeat->sp->lock, flags);
+ if (rhbeat->active) {
+ spin_unlock_irqrestore(&rhbeat->sp->lock, flags);
+ return -EBUSY;
+ }
+ rhbeat->active = 1;
+ spin_unlock_irqrestore(&rhbeat->sp->lock, flags);
+
+ result = ibmasm_start_reverse_heartbeat(rhbeat->sp, &rhbeat->heartbeat);
+ rhbeat->active = 0;
+
+ return result;
+}
+
+static ssize_t r_heartbeat_file_write(struct file *file, const char *buf, size_t count, loff_t *offset)
+{
+ struct ibmasmfs_heartbeat_data *rhbeat = file->private_data;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count != 1)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ if (rhbeat->active)
+ ibmasm_stop_reverse_heartbeat(&rhbeat->heartbeat);
+
+ return 1;
+}
+
+static int remote_settings_file_open(struct inode *inode, struct file *file)
+{
+ file->private_data = inode->u.generic_ip;
+ return 0;
+}
+
+static int remote_settings_file_close(struct inode *inode, struct file *file)
+{
+ return 0;
+}
+
+static ssize_t remote_settings_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+{
+ unsigned long address = (unsigned long)file->private_data;
+ unsigned char *page;
+ int retval;
+ int len = 0;
+ unsigned int value;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count == 0 || count > 1024)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ page = (unsigned char *)__get_free_page(GFP_KERNEL);
+ if (!page)
+ return -ENOMEM;
+
+ value = readl(address);
+ len = sprintf(page, "%d\n", value);
+
+ if (copy_to_user(buf, page, len)) {
+ retval = -EFAULT;
+ goto exit;
+ }
+ *offset += len;
+ retval = len;
+
+exit:
+ free_page((unsigned long)page);
+ return retval;
+}
+
+static ssize_t remote_settings_file_write(struct file *file, const char *ubuff, size_t count, loff_t *offset)
+{
+ unsigned long address = (unsigned long)file->private_data;
+ char *buff;
+ unsigned int value;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count == 0 || count > 1024)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ buff = kmalloc (count + 1, GFP_KERNEL);
+ if (!buff)
+ return -ENOMEM;
+
+ memset(buff, 0x0, count + 1);
+
+ if (copy_from_user((void *)buff, (void *)ubuff, count)) {
+ kfree(buff);
+ return -EFAULT;
+ }
+
+ value = simple_strtoul(buff, NULL, 10);
+ writel(value, address);
+ kfree(buff);
+
+ return count;
+}
+
+static int remote_event_file_open(struct inode *inode, struct file *file)
+{
+ struct service_processor *sp;
+ unsigned long flags;
+ struct remote_queue *q;
+
+ file->private_data = inode->u.generic_ip;
+ sp = file->private_data;
+ q = &sp->remote_queue;
+
+ /* allow only one event reader */
+ spin_lock_irqsave(&sp->lock, flags);
+ if (q->open) {
+ spin_unlock_irqrestore(&sp->lock, flags);
+ return -EBUSY;
+ }
+ q->open = 1;
+ spin_unlock_irqrestore(&sp->lock, flags);
+
+ enable_mouse_interrupts(sp);
+
+ return 0;
+}
+
+static int remote_event_file_close(struct inode *inode, struct file *file)
+{
+ struct service_processor *sp = file->private_data;
+
+ disable_mouse_interrupts(sp);
+ wake_up_interruptible(&sp->remote_queue.wait);
+ sp->remote_queue.open = 0;
+
+ return 0;
+}
+
+static ssize_t remote_event_file_read(struct file *file, char *buf, size_t count, loff_t *offset)
+{
+ struct service_processor *sp = file->private_data;
+ struct remote_queue *q = &sp->remote_queue;
+ size_t data_size;
+ struct remote_event *reader = q->reader;
+ size_t num_events;
+
+ if (*offset < 0)
+ return -EINVAL;
+ if (count == 0 || count > 1024)
+ return 0;
+ if (*offset != 0)
+ return 0;
+
+ if (wait_event_interruptible(q->wait, q->reader != q->writer))
+ return -ERESTARTSYS;
+
+ /* only get multiples of struct remote_event */
+ num_events = min((count/sizeof(struct remote_event)), ibmasm_events_available(q));
+ if (!num_events)
+ return 0;
+
+ data_size = num_events * sizeof(struct remote_event);
+
+ if (copy_to_user(buf, reader, data_size))
+ return -EFAULT;
+
+ ibmasm_advance_reader(q, num_events);
+
+ return data_size;
+}
+
+
+static struct file_operations command_fops = {
+ .open = command_file_open,
+ .release = command_file_close,
+ .read = command_file_read,
+ .write = command_file_write,
+};
+
+static struct file_operations event_fops = {
+ .open = event_file_open,
+ .release = event_file_close,
+ .read = event_file_read,
+ .write event_file_write,
+};
+
+static struct file_operations r_heartbeat_fops = {
+ .open = r_heartbeat_file_open,
+ .release = r_heartbeat_file_close,
+ .read = r_heartbeat_file_read,
+ .write = r_heartbeat_file_write,
+};
+
+static struct file_operations remote_settings_fops = {
+ .open = remote_settings_file_open,
+ .release = remote_settings_file_close,
+ .read = remote_settings_file_read,
+ .write = remote_settings_file_write,
+};
+
+static struct file_operations remote_event_fops = {
+ .open = remote_event_file_open,
+ .release = remote_event_file_close,
+ .read = remote_event_file_read,
+};
+
+
+static void ibmasmfs_create_files (struct super_block *sb, struct dentry *root)
+{
+ struct list_head *entry;
+ struct service_processor *sp;
+
+ list_for_each(entry, &service_processors) {
+ struct dentry *dir;
+ struct dentry *remote_dir;
+ sp = list_entry(entry, struct service_processor, node);
+ dir = ibmasmfs_create_dir(sb, root, sp->dirname);
+ if (!dir)
+ continue;
+
+ ibmasmfs_create_file(sb, dir, "command", &command_fops, sp, S_IRUSR|S_IWUSR);
+ ibmasmfs_create_file(sb, dir, "event", &event_fops, sp, S_IRUSR|S_IWUSR);
+ ibmasmfs_create_file(sb, dir, "reverse_heartbeat", &r_heartbeat_fops, sp, S_IRUSR|S_IWUSR);
+
+ remote_dir = ibmasmfs_create_dir(sb, dir, "remote_video");
+ if (!remote_dir)
+ continue;
+
+ ibmasmfs_create_file(sb, remote_dir, "width", &remote_settings_fops, (void *)display_width(sp), S_IRUSR|S_IWUSR);
+ ibmasmfs_create_file(sb, remote_dir, "height", &remote_settings_fops, (void *)display_height(sp), S_IRUSR|S_IWUSR);
+ ibmasmfs_create_file(sb, remote_dir, "depth", &remote_settings_fops, (void *)display_depth(sp), S_IRUSR|S_IWUSR);
+ ibmasmfs_create_file(sb, remote_dir, "connected", &remote_settings_fops, (void *)vnc_status(sp), S_IRUSR);
+ ibmasmfs_create_file(sb, remote_dir, "events", &remote_event_fops, (void *)sp, S_IRUSR);
+ }
+}
^ permalink raw reply [flat|nested] 17+ messages in thread
* [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:14 [BK PATCH] Driver Core update for 2.6.4-rc1 Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1557.72.1, 2004/02/19 13:09:14-08:00, rddunlap@osdl.org
[PATCH] sys_device_[un]register() are not syscalls
sys_xyz() names in Linux are all syscalls... except for
sys_device_register() and sys_device_unregister().
This patch renames them so that the sys_ namespace is once
again used only by syscalls.
arch/arm/kernel/time.c | 2 +-
arch/arm/mach-integrator/integrator_ap.c | 2 +-
arch/arm/mach-sa1100/irq.c | 2 +-
arch/i386/kernel/apic.c | 2 +-
arch/i386/kernel/i8259.c | 4 ++--
arch/i386/kernel/nmi.c | 2 +-
arch/i386/kernel/time.c | 2 +-
arch/i386/oprofile/nmi_int.c | 4 ++--
arch/mips/kernel/i8259.c | 2 +-
arch/ppc/platforms/pmac_pic.c | 2 +-
arch/ppc/syslib/open_pic.c | 2 +-
arch/ppc/syslib/open_pic2.c | 2 +-
arch/x86_64/kernel/apic.c | 2 +-
arch/x86_64/kernel/i8259.c | 2 +-
arch/x86_64/kernel/nmi.c | 2 +-
drivers/base/cpu.c | 2 +-
drivers/base/node.c | 2 +-
drivers/base/sys.c | 12 ++++++------
drivers/input/serio/i8042.c | 4 ++--
drivers/s390/block/xpram.c | 6 +++---
include/linux/sysdev.h | 4 ++--
21 files changed, 32 insertions(+), 32 deletions(-)
diff -Nru a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
--- a/arch/arm/kernel/time.c Tue Mar 2 19:52:41 2004
+++ b/arch/arm/kernel/time.c Tue Mar 2 19:52:41 2004
@@ -178,7 +178,7 @@
int ret;
ret = sysdev_class_register(&leds_sysclass);
if (ret == 0)
- ret = sys_device_register(&leds_device);
+ ret = sysdev_register(&leds_device);
return ret;
}
diff -Nru a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c
--- a/arch/arm/mach-integrator/integrator_ap.c Tue Mar 2 19:52:41 2004
+++ b/arch/arm/mach-integrator/integrator_ap.c Tue Mar 2 19:52:41 2004
@@ -173,7 +173,7 @@
{
int ret = sysdev_class_register(&irq_class);
if (ret == 0)
- ret = sys_device_register(&irq_device);
+ ret = sysdev_register(&irq_device);
return ret;
}
diff -Nru a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
--- a/arch/arm/mach-sa1100/irq.c Tue Mar 2 19:52:41 2004
+++ b/arch/arm/mach-sa1100/irq.c Tue Mar 2 19:52:41 2004
@@ -278,7 +278,7 @@
static int __init sa1100irq_init_devicefs(void)
{
sysdev_class_register(&sa1100irq_sysclass);
- return sys_device_register(&sa1100irq_device);
+ return sysdev_register(&sa1100irq_device);
}
device_initcall(sa1100irq_init_devicefs);
diff -Nru a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
--- a/arch/i386/kernel/apic.c Tue Mar 2 19:52:41 2004
+++ b/arch/i386/kernel/apic.c Tue Mar 2 19:52:41 2004
@@ -595,7 +595,7 @@
error = sysdev_class_register(&lapic_sysclass);
if (!error)
- error = sys_device_register(&device_lapic);
+ error = sysdev_register(&device_lapic);
return error;
}
device_initcall(init_lapic_sysfs);
diff -Nru a/arch/i386/kernel/i8259.c b/arch/i386/kernel/i8259.c
--- a/arch/i386/kernel/i8259.c Tue Mar 2 19:52:41 2004
+++ b/arch/i386/kernel/i8259.c Tue Mar 2 19:52:41 2004
@@ -258,7 +258,7 @@
{
int error = sysdev_class_register(&i8259_sysdev_class);
if (!error)
- error = sys_device_register(&device_i8259A);
+ error = sysdev_register(&device_i8259A);
return error;
}
@@ -401,7 +401,7 @@
{
int error = sysdev_class_register(&timer_sysclass);
if (!error)
- error = sys_device_register(&device_timer);
+ error = sysdev_register(&device_timer);
return error;
}
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c Tue Mar 2 19:52:41 2004
+++ b/arch/i386/kernel/nmi.c Tue Mar 2 19:52:41 2004
@@ -248,7 +248,7 @@
error = sysdev_class_register(&nmi_sysclass);
if (!error)
- error = sys_device_register(&device_lapic_nmi);
+ error = sysdev_register(&device_lapic_nmi);
return error;
}
/* must come after the local APIC's device_initcall() */
diff -Nru a/arch/i386/kernel/time.c b/arch/i386/kernel/time.c
--- a/arch/i386/kernel/time.c Tue Mar 2 19:52:41 2004
+++ b/arch/i386/kernel/time.c Tue Mar 2 19:52:41 2004
@@ -346,7 +346,7 @@
{
int error = sysdev_class_register(&pit_sysclass);
if (!error)
- error = sys_device_register(&device_i8253);
+ error = sysdev_register(&device_i8253);
return error;
}
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c Tue Mar 2 19:52:41 2004
+++ b/arch/i386/oprofile/nmi_int.c Tue Mar 2 19:52:41 2004
@@ -65,14 +65,14 @@
{
int error;
if (!(error = sysdev_class_register(&oprofile_sysclass)))
- error = sys_device_register(&device_oprofile);
+ error = sysdev_register(&device_oprofile);
return error;
}
static void __exit exit_driverfs(void)
{
- sys_device_unregister(&device_oprofile);
+ sysdev_unregister(&device_oprofile);
sysdev_class_unregister(&oprofile_sysclass);
}
diff -Nru a/arch/mips/kernel/i8259.c b/arch/mips/kernel/i8259.c
--- a/arch/mips/kernel/i8259.c Tue Mar 2 19:52:41 2004
+++ b/arch/mips/kernel/i8259.c Tue Mar 2 19:52:41 2004
@@ -242,7 +242,7 @@
{
int error = sysdev_class_register(&i8259_sysdev_class);
if (!error)
- error = sys_device_register(&device_i8259A);
+ error = sysdev_register(&device_i8259A);
return error;
}
diff -Nru a/arch/ppc/platforms/pmac_pic.c b/arch/ppc/platforms/pmac_pic.c
--- a/arch/ppc/platforms/pmac_pic.c Tue Mar 2 19:52:41 2004
+++ b/arch/ppc/platforms/pmac_pic.c Tue Mar 2 19:52:41 2004
@@ -646,7 +646,7 @@
printk(KERN_DEBUG "Registering pmac pic with sysfs...\n");
sysdev_class_register(&pmacpic_sysclass);
- sys_device_register(&device_pmacpic);
+ sysdev_register(&device_pmacpic);
sysdev_driver_register(&pmacpic_sysclass, &driver_pmacpic);
return 0;
}
diff -Nru a/arch/ppc/syslib/open_pic.c b/arch/ppc/syslib/open_pic.c
--- a/arch/ppc/syslib/open_pic.c Tue Mar 2 19:52:41 2004
+++ b/arch/ppc/syslib/open_pic.c Tue Mar 2 19:52:41 2004
@@ -1032,7 +1032,7 @@
printk(KERN_ERR "Failed registering openpic sys class\n");
return -ENODEV;
}
- rc = sys_device_register(&device_openpic);
+ rc = sysdev_register(&device_openpic);
if (rc) {
printk(KERN_ERR "Failed registering openpic sys device\n");
return -ENODEV;
diff -Nru a/arch/ppc/syslib/open_pic2.c b/arch/ppc/syslib/open_pic2.c
--- a/arch/ppc/syslib/open_pic2.c Tue Mar 2 19:52:41 2004
+++ b/arch/ppc/syslib/open_pic2.c Tue Mar 2 19:52:41 2004
@@ -699,7 +699,7 @@
printk(KERN_ERR "Failed registering openpic sys class\n");
return -ENODEV;
}
- rc = sys_device_register(&device_openpic2);
+ rc = sysdev_register(&device_openpic2);
if (rc) {
printk(KERN_ERR "Failed registering openpic sys device\n");
return -ENODEV;
diff -Nru a/arch/x86_64/kernel/apic.c b/arch/x86_64/kernel/apic.c
--- a/arch/x86_64/kernel/apic.c Tue Mar 2 19:52:41 2004
+++ b/arch/x86_64/kernel/apic.c Tue Mar 2 19:52:41 2004
@@ -552,7 +552,7 @@
/* XXX: remove suspend/resume procs if !apic_pm_state.active? */
error = sysdev_class_register(&lapic_sysclass);
if (!error)
- error = sys_device_register(&device_lapic);
+ error = sysdev_register(&device_lapic);
return error;
}
device_initcall(init_lapic_sysfs);
diff -Nru a/arch/x86_64/kernel/i8259.c b/arch/x86_64/kernel/i8259.c
--- a/arch/x86_64/kernel/i8259.c Tue Mar 2 19:52:41 2004
+++ b/arch/x86_64/kernel/i8259.c Tue Mar 2 19:52:41 2004
@@ -430,7 +430,7 @@
{
int error = sysdev_class_register(&timer_sysclass);
if (!error)
- error = sys_device_register(&device_timer);
+ error = sysdev_register(&device_timer);
return error;
}
diff -Nru a/arch/x86_64/kernel/nmi.c b/arch/x86_64/kernel/nmi.c
--- a/arch/x86_64/kernel/nmi.c Tue Mar 2 19:52:41 2004
+++ b/arch/x86_64/kernel/nmi.c Tue Mar 2 19:52:41 2004
@@ -218,7 +218,7 @@
error = sysdev_class_register(&nmi_sysclass);
if (!error)
- error = sys_device_register(&device_lapic_nmi);
+ error = sysdev_register(&device_lapic_nmi);
return error;
}
/* must come after the local APIC's device_initcall() */
diff -Nru a/drivers/base/cpu.c b/drivers/base/cpu.c
--- a/drivers/base/cpu.c Tue Mar 2 19:52:41 2004
+++ b/drivers/base/cpu.c Tue Mar 2 19:52:41 2004
@@ -29,7 +29,7 @@
cpu->sysdev.id = num;
cpu->sysdev.cls = &cpu_sysdev_class;
- error = sys_device_register(&cpu->sysdev);
+ error = sysdev_register(&cpu->sysdev);
if (!error && root)
error = sysfs_create_link(&root->sysdev.kobj,
&cpu->sysdev.kobj,
diff -Nru a/drivers/base/node.c b/drivers/base/node.c
--- a/drivers/base/node.c Tue Mar 2 19:52:41 2004
+++ b/drivers/base/node.c Tue Mar 2 19:52:41 2004
@@ -69,7 +69,7 @@
node->cpumap = node_to_cpumask(num);
node->sysdev.id = num;
node->sysdev.cls = &node_class;
- error = sys_device_register(&node->sysdev);
+ error = sysdev_register(&node->sysdev);
if (!error){
sysdev_create_file(&node->sysdev, &attr_cpumap);
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c Tue Mar 2 19:52:41 2004
+++ b/drivers/base/sys.c Tue Mar 2 19:52:41 2004
@@ -8,7 +8,7 @@
*
* This exports a 'system' bus type.
* By default, a 'sys' bus gets added to the root of the system. There will
- * always be core system devices. Devices can use sys_device_register() to
+ * always be core system devices. Devices can use sysdev_register() to
* add themselves as children of the system bus.
*/
@@ -164,11 +164,11 @@
/**
- * sys_device_register - add a system device to the tree
+ * sysdev_register - add a system device to the tree
* @sysdev: device in question
*
*/
-int sys_device_register(struct sys_device * sysdev)
+int sysdev_register(struct sys_device * sysdev)
{
int error;
struct sysdev_class * cls = sysdev->cls;
@@ -212,7 +212,7 @@
return error;
}
-void sys_device_unregister(struct sys_device * sysdev)
+void sysdev_unregister(struct sys_device * sysdev)
{
struct sysdev_driver * drv;
@@ -390,5 +390,5 @@
return subsystem_register(&system_subsys);
}
-EXPORT_SYMBOL(sys_device_register);
-EXPORT_SYMBOL(sys_device_unregister);
+EXPORT_SYMBOL(sysdev_register);
+EXPORT_SYMBOL(sysdev_unregister);
diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c Tue Mar 2 19:52:41 2004
+++ b/drivers/input/serio/i8042.c Tue Mar 2 19:52:41 2004
@@ -957,7 +957,7 @@
mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
if (sysdev_class_register(&kbc_sysclass) == 0) {
- if (sys_device_register(&device_i8042) == 0)
+ if (sysdev_register(&device_i8042) == 0)
i8042_sysdev_initialized = 1;
else
sysdev_class_unregister(&kbc_sysclass);
@@ -980,7 +980,7 @@
pm_unregister(i8042_pm_dev);
if (i8042_sysdev_initialized) {
- sys_device_unregister(&device_i8042);
+ sysdev_unregister(&device_i8042);
sysdev_class_unregister(&kbc_sysclass);
}
diff -Nru a/drivers/s390/block/xpram.c b/drivers/s390/block/xpram.c
--- a/drivers/s390/block/xpram.c Tue Mar 2 19:52:41 2004
+++ b/drivers/s390/block/xpram.c Tue Mar 2 19:52:41 2004
@@ -492,7 +492,7 @@
}
unregister_blkdev(XPRAM_MAJOR, XPRAM_NAME);
devfs_remove("slram");
- sys_device_unregister(&xpram_sys_device);
+ sysdev_unregister(&xpram_sys_device);
sysdev_class_unregister(&xpram_sysclass);
}
@@ -515,14 +515,14 @@
if (rc)
return rc;
- rc = sys_device_register(&xpram_sys_device);
+ rc = sysdev_register(&xpram_sys_device);
if (rc) {
sysdev_class_unregister(&xpram_sysclass);
return rc;
}
rc = xpram_setup_blkdev();
if (rc)
- sys_device_unregister(&xpram_sys_device);
+ sysdev_unregister(&xpram_sys_device);
return rc;
}
diff -Nru a/include/linux/sysdev.h b/include/linux/sysdev.h
--- a/include/linux/sysdev.h Tue Mar 2 19:52:41 2004
+++ b/include/linux/sysdev.h Tue Mar 2 19:52:41 2004
@@ -70,8 +70,8 @@
struct kobject kobj;
};
-extern int sys_device_register(struct sys_device *);
-extern void sys_device_unregister(struct sys_device *);
+extern int sysdev_register(struct sys_device *);
+extern void sysdev_unregister(struct sys_device *);
struct sysdev_attribute {
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.17.4, 2004/02/27 11:18:21-08:00, greg@kroah.com
kobject: clean up kobject_get() convoluted logic.
lib/kobject.c | 7 ++-----
1 files changed, 2 insertions(+), 5 deletions(-)
diff -Nru a/lib/kobject.c b/lib/kobject.c
--- a/lib/kobject.c Tue Mar 2 19:50:26 2004
+++ b/lib/kobject.c Tue Mar 2 19:50:26 2004
@@ -425,14 +425,11 @@
struct kobject * kobject_get(struct kobject * kobj)
{
- struct kobject * ret = kobj;
-
if (kobj) {
WARN_ON(!atomic_read(&kobj->refcount));
atomic_inc(&kobj->refcount);
- } else
- ret = NULL;
- return ret;
+ }
+ return kobj;
}
/**
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` [PATCH] " Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1557.72.2, 2004/02/19 15:38:41-08:00, shemminger@osdl.org
[PATCH] propogate errors from misc_register to caller
The patch to check for / in class_device is not enough.
The misc_register function needs to check return value of the things it calls!
drivers/char/misc.c | 24 +++++++++++++++++++-----
1 files changed, 19 insertions(+), 5 deletions(-)
diff -Nru a/drivers/char/misc.c b/drivers/char/misc.c
--- a/drivers/char/misc.c Tue Mar 2 19:52:14 2004
+++ b/drivers/char/misc.c Tue Mar 2 19:52:14 2004
@@ -212,6 +212,9 @@
int misc_register(struct miscdevice * misc)
{
struct miscdevice *c;
+ struct class_device *class;
+ dev_t dev;
+ int err;
down(&misc_sem);
list_for_each_entry(c, &misc_list, list) {
@@ -240,19 +243,30 @@
snprintf(misc->devfs_name, sizeof(misc->devfs_name),
"misc/%s", misc->name);
}
+ dev = MKDEV(MISC_MAJOR, misc->minor);
- class_simple_device_add(misc_class, MKDEV(MISC_MAJOR, misc->minor),
- misc->dev, misc->name);
- devfs_mk_cdev(MKDEV(MISC_MAJOR, misc->minor),
- S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP, misc->devfs_name);
+ class = class_simple_device_add(misc_class, dev,
+ misc->dev, misc->name);
+ if (IS_ERR(class)) {
+ err = PTR_ERR(class);
+ goto out;
+ }
+
+ err = devfs_mk_cdev(dev, S_IFCHR|S_IRUSR|S_IWUSR|S_IRGRP,
+ misc->devfs_name);
+ if (err) {
+ class_simple_device_remove(dev);
+ goto out;
+ }
/*
* Add it to the front, so that later devices can "override"
* earlier defaults
*/
list_add(&misc->list, &misc_list);
+ out:
up(&misc_sem);
- return 0;
+ return err;
}
/**
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 22:24 ` Russell King
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.24.4, 2004/03/02 16:39:36-08:00, greg@kroah.com
Driver core: add CONFIG_DEBUG_DRIVER to help track down driver core bugs easier.
drivers/base/Kconfig | 11 +++++++++++
drivers/base/bus.c | 5 ++++-
drivers/base/class.c | 5 ++++-
drivers/base/class_simple.c | 5 ++++-
drivers/base/core.c | 5 ++++-
drivers/base/driver.c | 5 ++++-
drivers/base/power/main.c | 5 ++++-
drivers/base/power/shutdown.c | 7 +++++--
drivers/base/sys.c | 5 ++++-
9 files changed, 44 insertions(+), 9 deletions(-)
diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig
--- a/drivers/base/Kconfig Tue Mar 2 19:48:11 2004
+++ b/drivers/base/Kconfig Tue Mar 2 19:48:11 2004
@@ -8,4 +8,15 @@
require hotplug firmware loading support, but a module built outside
the kernel tree does.
+config DEBUG_DRIVER
+ bool "Driver Core verbose debug messages"
+ depends on DEBUG_KERNEL
+ help
+ Say Y here if you want the Driver core to produce a bunch of
+ debug messages to the system log. Select this if you are having a
+ problem with the driver core and want to see more of what is
+ going on.
+
+ If you are unsure about this, say N here.
+
endmenu
diff -Nru a/drivers/base/bus.c b/drivers/base/bus.c
--- a/drivers/base/bus.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/bus.c Tue Mar 2 19:48:11 2004
@@ -8,7 +8,10 @@
*
*/
-#undef DEBUG
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/device.h>
#include <linux/module.h>
diff -Nru a/drivers/base/class.c b/drivers/base/class.c
--- a/drivers/base/class.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/class.c Tue Mar 2 19:48:11 2004
@@ -10,7 +10,10 @@
*
*/
-#undef DEBUG
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/device.h>
#include <linux/module.h>
diff -Nru a/drivers/base/class_simple.c b/drivers/base/class_simple.c
--- a/drivers/base/class_simple.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/class_simple.c Tue Mar 2 19:48:11 2004
@@ -8,7 +8,10 @@
*
*/
-#define DEBUG 1
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/device.h>
#include <linux/kdev_t.h>
diff -Nru a/drivers/base/core.c b/drivers/base/core.c
--- a/drivers/base/core.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/core.c Tue Mar 2 19:48:11 2004
@@ -8,7 +8,10 @@
*
*/
-#undef DEBUG
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/device.h>
#include <linux/err.h>
diff -Nru a/drivers/base/driver.c b/drivers/base/driver.c
--- a/drivers/base/driver.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/driver.c Tue Mar 2 19:48:11 2004
@@ -8,7 +8,10 @@
*
*/
-#undef DEBUG
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/device.h>
#include <linux/module.h>
diff -Nru a/drivers/base/power/main.c b/drivers/base/power/main.c
--- a/drivers/base/power/main.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/power/main.c Tue Mar 2 19:48:11 2004
@@ -19,7 +19,10 @@
* ancestral dependencies that the subsystem list maintains.
*/
-#undef DEBUG
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/device.h>
#include "power.h"
diff -Nru a/drivers/base/power/shutdown.c b/drivers/base/power/shutdown.c
--- a/drivers/base/power/shutdown.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/power/shutdown.c Tue Mar 2 19:48:11 2004
@@ -8,7 +8,10 @@
*
*/
-#undef DEBUG
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/device.h>
#include <asm/semaphore.h>
@@ -54,7 +57,7 @@
down_write(&devices_subsys.rwsem);
list_for_each_entry_reverse(dev,&devices_subsys.kset.list,kobj.entry) {
- pr_debug("shutting down %s: ",dev->name);
+ pr_debug("shutting down %s: ",dev->bus_id);
if (dev->driver && dev->driver->shutdown) {
pr_debug("Ok\n");
dev->driver->shutdown(dev);
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c Tue Mar 2 19:48:11 2004
+++ b/drivers/base/sys.c Tue Mar 2 19:48:11 2004
@@ -12,7 +12,10 @@
* add themselves as children of the system bus.
*/
-#undef DEBUG
+#include <linux/config.h>
+#ifdef CONFIG_DEBUG_DRIVER
+#define DEBUG 1
+#endif
#include <linux/sysdev.h>
#include <linux/err.h>
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.24.2, 2004/03/01 15:54:54-08:00, rddunlap@osdl.org
[PATCH] rename sys_bus_init()
rename sys_bus_init() to system_bus_init() so that
it doesn't appear to be a syscall;
drivers/base/init.c | 4 ++--
drivers/base/sys.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff -Nru a/drivers/base/init.c b/drivers/base/init.c
--- a/drivers/base/init.c Tue Mar 2 19:49:05 2004
+++ b/drivers/base/init.c Tue Mar 2 19:49:05 2004
@@ -15,7 +15,7 @@
extern int classes_init(void);
extern int firmware_init(void);
extern int platform_bus_init(void);
-extern int sys_bus_init(void);
+extern int system_bus_init(void);
extern int cpu_dev_init(void);
/**
@@ -37,6 +37,6 @@
* core core pieces.
*/
platform_bus_init();
- sys_bus_init();
+ system_bus_init();
cpu_dev_init();
}
diff -Nru a/drivers/base/sys.c b/drivers/base/sys.c
--- a/drivers/base/sys.c Tue Mar 2 19:49:05 2004
+++ b/drivers/base/sys.c Tue Mar 2 19:49:05 2004
@@ -384,7 +384,7 @@
}
-int __init sys_bus_init(void)
+int __init system_bus_init(void)
{
system_subsys.kset.kobj.parent = &devices_subsys.kset.kobj;
return subsystem_register(&system_subsys);
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 4:16 UTC (permalink / raw)
To: linux-kernel
ChangeSet 1.1612.24.3, 2004/03/02 12:13:47-08:00, greg@kroah.com
Make IBMASM driver depend on X86 as that is the only valid platform for it.
drivers/misc/Kconfig | 1 +
1 files changed, 1 insertion(+)
diff -Nru a/drivers/misc/Kconfig b/drivers/misc/Kconfig
--- a/drivers/misc/Kconfig Tue Mar 2 19:48:38 2004
+++ b/drivers/misc/Kconfig Tue Mar 2 19:48:38 2004
@@ -6,6 +6,7 @@
config IBM_ASM
tristate "Device driver for IBM RSA service processor"
+ depends on X86
default n
---help---
This option enables device driver support for in-band access to the
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 8:00 ` Christoph Hellwig
2004-03-03 15:07 ` Greg KH
1 sibling, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2004-03-03 8:00 UTC (permalink / raw)
To: Greg KH; +Cc: linux-kernel
On Tue, Mar 02, 2004 at 08:16:38PM -0800, Greg KH wrote:
> ChangeSet 1.1612.17.5, 2004/02/27 11:40:29-08:00, masbock@us.ibm.com
>
> [PATCH] Driver for IBM service processor - updated (1/2)
please don't put anything into drivers/misc for now. We might over to it,
but then we should do it for all drivers we think it makes sense instead
of random ones.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 8:00 ` Christoph Hellwig
@ 2004-03-03 15:07 ` Greg KH
2004-03-03 15:13 ` Christoph Hellwig
0 siblings, 1 reply; 17+ messages in thread
From: Greg KH @ 2004-03-03 15:07 UTC (permalink / raw)
To: Christoph Hellwig, linux-kernel
On Wed, Mar 03, 2004 at 08:00:37AM +0000, Christoph Hellwig wrote:
> On Tue, Mar 02, 2004 at 08:16:38PM -0800, Greg KH wrote:
> > ChangeSet 1.1612.17.5, 2004/02/27 11:40:29-08:00, masbock@us.ibm.com
> >
> > [PATCH] Driver for IBM service processor - updated (1/2)
>
> please don't put anything into drivers/misc for now. We might over to it,
> but then we should do it for all drivers we think it makes sense instead
> of random ones.
Hm, well where do you feel I should move this driver to in the tree
then?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 15:07 ` Greg KH
@ 2004-03-03 15:13 ` Christoph Hellwig
2004-03-03 15:19 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Christoph Hellwig @ 2004-03-03 15:13 UTC (permalink / raw)
To: Greg KH; +Cc: Christoph Hellwig, linux-kernel
On Wed, Mar 03, 2004 at 07:07:44AM -0800, Greg KH wrote:
> On Wed, Mar 03, 2004 at 08:00:37AM +0000, Christoph Hellwig wrote:
> > On Tue, Mar 02, 2004 at 08:16:38PM -0800, Greg KH wrote:
> > > ChangeSet 1.1612.17.5, 2004/02/27 11:40:29-08:00, masbock@us.ibm.com
> > >
> > > [PATCH] Driver for IBM service processor - updated (1/2)
> >
> > please don't put anything into drivers/misc for now. We might over to it,
> > but then we should do it for all drivers we think it makes sense instead
> > of random ones.
>
> Hm, well where do you feel I should move this driver to in the tree
> then?
Currently drivers/char/ is the catchall for random gunk. But given that
there seem to be more and more such service processors around it might be
a good idea to just give them a directory udner drivers/ for themselves.
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 15:13 ` Christoph Hellwig
@ 2004-03-03 15:19 ` Greg KH
0 siblings, 0 replies; 17+ messages in thread
From: Greg KH @ 2004-03-03 15:19 UTC (permalink / raw)
To: Christoph Hellwig, linux-kernel
On Wed, Mar 03, 2004 at 03:13:10PM +0000, Christoph Hellwig wrote:
> On Wed, Mar 03, 2004 at 07:07:44AM -0800, Greg KH wrote:
> > On Wed, Mar 03, 2004 at 08:00:37AM +0000, Christoph Hellwig wrote:
> > > On Tue, Mar 02, 2004 at 08:16:38PM -0800, Greg KH wrote:
> > > > ChangeSet 1.1612.17.5, 2004/02/27 11:40:29-08:00, masbock@us.ibm.com
> > > >
> > > > [PATCH] Driver for IBM service processor - updated (1/2)
> > >
> > > please don't put anything into drivers/misc for now. We might over to it,
> > > but then we should do it for all drivers we think it makes sense instead
> > > of random ones.
> >
> > Hm, well where do you feel I should move this driver to in the tree
> > then?
>
> Currently drivers/char/ is the catchall for random gunk.
Yeah, but this driver does not even have a char interface, otherwise I
would have no problem adding this there.
> But given that
> there seem to be more and more such service processors around it might be
> a good idea to just give them a directory udner drivers/ for themselves.
How about drivers/sp or drivers/service_processor? I'd be glad to
rename the misc directory to that and clear up two issues at once :)
thanks,
greg k-h
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 4:16 ` Greg KH
@ 2004-03-03 22:24 ` Russell King
2004-03-03 23:06 ` Greg KH
0 siblings, 1 reply; 17+ messages in thread
From: Russell King @ 2004-03-03 22:24 UTC (permalink / raw)
To: Greg KH; +Cc: linux-kernel
On Tue, Mar 02, 2004 at 08:16:39PM -0800, Greg KH wrote:
> ChangeSet 1.1612.24.4, 2004/03/02 16:39:36-08:00, greg@kroah.com
>
> Driver core: add CONFIG_DEBUG_DRIVER to help track down driver core bugs easier.
Wouldn't a cleaner way to do this be to add -DDEBUG to EXTRA_CFLAGS
in the makefile if CONFIG_DEBUG_DRIVER is set, and remove the #undef
DEBUG statements in each .c file?
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of: 2.6 PCMCIA - http://pcmcia.arm.linux.org.uk/
2.6 Serial core
^ permalink raw reply [flat|nested] 17+ messages in thread
* Re: [PATCH] Driver Core update for 2.6.4-rc1
2004-03-03 22:24 ` Russell King
@ 2004-03-03 23:06 ` Greg KH
0 siblings, 0 replies; 17+ messages in thread
From: Greg KH @ 2004-03-03 23:06 UTC (permalink / raw)
To: linux-kernel
On Wed, Mar 03, 2004 at 10:24:54PM +0000, Russell King wrote:
> On Tue, Mar 02, 2004 at 08:16:39PM -0800, Greg KH wrote:
> > ChangeSet 1.1612.24.4, 2004/03/02 16:39:36-08:00, greg@kroah.com
> >
> > Driver core: add CONFIG_DEBUG_DRIVER to help track down driver core bugs easier.
>
> Wouldn't a cleaner way to do this be to add -DDEBUG to EXTRA_CFLAGS
> in the makefile if CONFIG_DEBUG_DRIVER is set, and remove the #undef
> DEBUG statements in each .c file?
Yes it would, I didn't realize we could do that :)
Do any other subsystems do that?
thanks,
greg k-h
^ permalink raw reply [flat|nested] 17+ messages in thread
end of thread, other threads:[~2004-03-03 23:28 UTC | newest]
Thread overview: 17+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-03 4:14 [BK PATCH] Driver Core update for 2.6.4-rc1 Greg KH
2004-03-03 4:16 ` [PATCH] " Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 4:16 ` Greg KH
2004-03-03 22:24 ` Russell King
2004-03-03 23:06 ` Greg KH
2004-03-03 8:00 ` Christoph Hellwig
2004-03-03 15:07 ` Greg KH
2004-03-03 15:13 ` Christoph Hellwig
2004-03-03 15:19 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox