public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [RFC][PATCH 2.6.13-rc6] add Dell Systems Management Base Driver (dcdbas) with sysfs support
@ 2005-08-15 20:05 Doug Warzecha
  2005-08-15 20:23 ` Kyle Moffett
  2005-08-16  5:52 ` Greg KH
  0 siblings, 2 replies; 36+ messages in thread
From: Doug Warzecha @ 2005-08-15 20:05 UTC (permalink / raw)
  To: linux-kernel; +Cc: Douglas_Warzecha

This patch adds the Dell Systems Management Base Driver with sysfs support.

This driver has been tested with Dell OpenManage.

Signed-off-by: Doug Warzecha <Douglas_Warzecha@dell.com>
---
diff -uprN linux-2.6.13-rc6.orig/Documentation/dcdbas.txt linux-2.6.13-rc6/Documentation/dcdbas.txt
--- linux-2.6.13-rc6.orig/Documentation/dcdbas.txt	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.13-rc6/Documentation/dcdbas.txt	2005-08-15 14:07:21.000000000 -0500
@@ -0,0 +1,71 @@
+Overview
+
+The Dell Systems Management Base Driver provides a sysfs interface for
+systems management software such as Dell OpenManage to perform system
+management interrupts and host control actions (system power cycle or
+power off after OS shutdown) on certain Dell systems.
+
+Dell OpenManage requires this driver on the following Dell PowerEdge systems:
+300, 1300, 1400, 400SC, 500SC, 1500SC, 1550, 600SC, 1600SC, 650, 1655MC,
+700, and 750.  Other Dell software such as the open source Libsmbios library
+is expected to make use of this driver, and it may include use on other Dell
+systems.
+
+
+System Management Interrupt
+
+On some Dell systems, systems management software must access certain
+management information via a system management interrupt (SMI).  The SMI data
+buffer must reside in 32-bit address space, and the physical address of the
+buffer is required for the SMI.  The driver maintains the memory required for
+the SMI and provides a way for the application to generate the SMI.
+The driver creates the following sysfs entries for systems management
+software to perform these system management interrupts:
+
+/sys/devices/platform/dcdbas/smi_data
+/sys/devices/platform/dcdbas/smi_data_buf_phys_addr
+/sys/devices/platform/dcdbas/smi_data_buf_size
+/sys/devices/platform/dcdbas/callintf_smi
+
+Systems management software must perform the following steps to execute
+a SMI using this driver:
+
+1) Lock smi_data.
+2) Determine buffer size needed for system management command.
+3) Write buffer size needed to smi_data_buf_size.
+   (Driver will ensure that its SMI data buffer is at least that size.)
+4) If physical address of SMI data buffer is needed to set up system
+   management command, read physical address from smi_data_buf_phys_addr
+   and add to command data.
+5) Write system management command to smi_data.
+6) Write "1" to callintf_smi to generate a calling interface SMI.
+7) Read system management command response from smi_data.
+8) Unlock smi_data.
+
+
+Host Control Action
+
+Dell OpenManage supports a host control feature that allows the administrator
+to perform a power cycle or power off of the system after the OS has finished
+shutting down.  On some Dell systems, this host control feature requires that
+a driver perform a SMI after the OS has finished shutting down.
+
+The driver creates the following sysfs entries for systems management software
+to schedule the driver to perform a power cycle or power off host control
+action after the system has finished shutting down:
+
+/sys/devices/platform/dcdbas/host_control_action
+/sys/devices/platform/dcdbas/host_control_smi_type
+/sys/devices/platform/dcdbas/host_control_on_shutdown
+
+Dell OpenManage performs the following steps to execute a power cycle or
+power off host control action using this driver:
+
+1) Write host control action to be performed to host_control_action.
+2) Write type of SMI that driver needs to perform to host_control_smi_type.
+3) Write "1" to host_control_on_shutdown to enable host control action.
+4) Initiate OS shutdown.
+   (Driver will perform host control SMI when it is notified that the OS
+   has finished shutting down.)
+
+
diff -uprN linux-2.6.13-rc6.orig/drivers/firmware/dcdbas.c linux-2.6.13-rc6/drivers/firmware/dcdbas.c
--- linux-2.6.13-rc6.orig/drivers/firmware/dcdbas.c	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.13-rc6/drivers/firmware/dcdbas.c	2005-08-15 14:07:32.000000000 -0500
@@ -0,0 +1,601 @@
+/*
+ *  dcdbas.c: Dell Systems Management Base Driver
+ *
+ *  The Dell Systems Management Base Driver provides a sysfs interface for
+ *  systems management software to perform System Management Interrupts (SMIs)
+ *  and Host Control Actions (power cycle or power off after OS shutdown) on
+ *  Dell systems.
+ *
+ *  See Documentation/dcdbas.txt for more information.
+ *
+ *  Copyright (C) 1995-2005 Dell Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License v2.0 as published by
+ *  the Free Software Foundation.
+ *
+ *  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.
+ */
+
+#include <linux/device.h>
+#include <linux/dma-mapping.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/mc146818rtc.h>
+#include <linux/module.h>
+#include <linux/reboot.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/spinlock.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/semaphore.h>
+
+#include "dcdbas.h"
+
+#define DRIVER_NAME		"dcdbas"
+#define DRIVER_VERSION		"5.6.0-1"
+#define DRIVER_DESCRIPTION	"Dell Systems Management Base Driver"
+
+static struct platform_device *dcdbas_pdev;
+
+static u8 *smi_data_buf;
+static dma_addr_t smi_data_buf_handle;
+static unsigned long smi_data_buf_size;
+static u32 smi_data_buf_phys_addr;
+static DECLARE_MUTEX(smi_data_lock);
+
+static unsigned int host_control_action;
+static unsigned int host_control_smi_type;
+static unsigned int host_control_on_shutdown;
+
+/**
+ * smi_data_buf_free: free SMI data buffer
+ */
+static void smi_data_buf_free(void)
+{
+	if (!smi_data_buf)
+		return;
+
+	dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
+		__FUNCTION__, smi_data_buf_phys_addr, smi_data_buf_size);
+
+	dma_free_coherent(&dcdbas_pdev->dev, smi_data_buf_size, smi_data_buf,
+			  smi_data_buf_handle);
+	smi_data_buf = NULL;
+	smi_data_buf_handle = 0;
+	smi_data_buf_phys_addr = 0;
+	smi_data_buf_size = 0;
+}
+
+/**
+ * smi_data_buf_realloc: grow SMI data buffer if needed
+ */
+static int smi_data_buf_realloc(unsigned long size)
+{
+	void *buf;
+	dma_addr_t handle;
+	int ret = 0;
+
+	if (size > MAX_SMI_DATA_BUF_SIZE)
+		return -EINVAL;
+
+	down(&smi_data_lock);
+
+	/* check if current buffer is big enough */
+	if (smi_data_buf_size >= size) {
+		if (size && !smi_data_buf) {
+			dev_dbg(&dcdbas_pdev->dev,
+				"%s: corruption detected\n", __FUNCTION__);
+			ret = -EFAULT;
+			goto out;
+		}
+
+		/* current buffer is big enough */
+		goto out;
+	}
+
+	/* new buffer is needed */
+	buf = dma_alloc_coherent(&dcdbas_pdev->dev, size, &handle, GFP_KERNEL);
+	if (!buf) {
+		dev_dbg(&dcdbas_pdev->dev,
+			"%s: failed to allocate memory size %lu\n",
+			__FUNCTION__, size);
+		ret = -ENOMEM;
+		goto out;
+	}
+	/* memory zeroed by dma_alloc_coherent */
+
+	/* free any existing buffer */
+	smi_data_buf_free();
+
+	/* set up new buffer for use */
+	smi_data_buf = buf;
+	smi_data_buf_handle = handle;
+	smi_data_buf_phys_addr = (u32) virt_to_phys(buf);
+	smi_data_buf_size = size;
+
+	dev_dbg(&dcdbas_pdev->dev, "%s: phys: %x size: %lu\n",
+		__FUNCTION__, smi_data_buf_phys_addr, smi_data_buf_size);
+out:
+	up(&smi_data_lock);
+	return ret;
+}
+
+static ssize_t smi_data_buf_phys_addr_show(struct device *dev,
+					   struct device_attribute *attr,
+					   char *buf)
+{
+	return sprintf(buf, "%x\n", smi_data_buf_phys_addr);
+}
+
+static ssize_t smi_data_buf_size_show(struct device *dev,
+				      struct device_attribute *attr,
+				      char *buf)
+{
+	return sprintf(buf, "%lu\n", smi_data_buf_size);
+}
+
+static ssize_t smi_data_buf_size_store(struct device *dev,
+				       struct device_attribute *attr,
+				       const char *buf, size_t count)
+{
+	unsigned long buf_size;
+	ssize_t ret;
+
+	buf_size = simple_strtoul(buf, NULL, 10);
+
+	/* make sure SMI data buffer is at least buf_size */
+	ret = smi_data_buf_realloc(buf_size);
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+static ssize_t smi_data_read(struct kobject *kobj, char *buf, loff_t pos,
+			     size_t count)
+{
+	size_t max_read;
+	ssize_t ret;
+
+	down(&smi_data_lock);
+
+	if (pos >= smi_data_buf_size) {
+		ret = 0;
+		goto out;
+	}
+
+	max_read = smi_data_buf_size - pos;
+	ret = min(max_read, count);
+	memcpy(buf, smi_data_buf + pos, ret);
+out:
+	up(&smi_data_lock);
+	return ret;
+}
+
+static ssize_t smi_data_write(struct kobject *kobj, char *buf, loff_t pos,
+			      size_t count)
+{
+	size_t max_write;
+	ssize_t ret;
+
+	down(&smi_data_lock);
+
+	if (pos >= smi_data_buf_size) {
+		ret = 0;
+		goto out;
+	}
+
+	max_write = smi_data_buf_size - pos;
+	ret = min(max_write, count);
+	memcpy(smi_data_buf + pos, buf, ret);
+out:
+	up(&smi_data_lock);
+	return ret;
+}
+
+static ssize_t host_control_action_show(struct device *dev,
+					struct device_attribute *attr,
+					char *buf)
+{
+	return sprintf(buf, "%u\n", host_control_action);
+}
+
+static ssize_t host_control_action_store(struct device *dev,
+					 struct device_attribute *attr,
+					 const char *buf, size_t count)
+{
+	ssize_t ret;
+
+	/* make sure buffer is available for host control command */
+	ret = smi_data_buf_realloc(sizeof(struct apm_cmd));
+	if (ret)
+		return ret;
+
+	host_control_action = simple_strtoul(buf, NULL, 10);
+	return count;
+}
+
+static ssize_t host_control_smi_type_show(struct device *dev,
+					  struct device_attribute *attr,
+					  char *buf)
+{
+	return sprintf(buf, "%u\n", host_control_smi_type);
+}
+
+static ssize_t host_control_smi_type_store(struct device *dev,
+					   struct device_attribute *attr,
+					   const char *buf, size_t count)
+{
+	host_control_smi_type = simple_strtoul(buf, NULL, 10);
+	return count;
+}
+
+static ssize_t host_control_on_shutdown_show(struct device *dev,
+					     struct device_attribute *attr,
+					     char *buf)
+{
+	return sprintf(buf, "%u\n", host_control_on_shutdown);
+}
+
+static ssize_t host_control_on_shutdown_store(struct device *dev,
+					      struct device_attribute *attr,
+					      const char *buf, size_t count)
+{
+	host_control_on_shutdown = simple_strtoul(buf, NULL, 10);
+	return count;
+}
+
+/**
+ * callintf_smi: generate calling interface SMI
+ */
+static int callintf_smi(void)
+{
+	struct callintf_cmd *ci_cmd;
+	cpumask_t old_mask;
+	u32 command_buffer_phys_addr;
+	int ret = 0;
+
+	/* SMI requires CPU 0 */
+	old_mask = current->cpus_allowed;
+	set_cpus_allowed(current, cpumask_of_cpu(0));
+	if (smp_processor_id() != 0) {
+		dev_dbg(&dcdbas_pdev->dev, "%s: failed to get CPU 0\n",
+			__FUNCTION__);
+		ret = -EBUSY;
+		goto out1;
+	}
+
+	down(&smi_data_lock);
+
+	if (smi_data_buf_size < sizeof(struct callintf_cmd)) {
+		ret = -ENODEV;
+		goto out2;
+	}
+
+	ci_cmd = (struct callintf_cmd *)smi_data_buf;
+	if (ci_cmd->magic != CALLINTF_CMD_MAGIC) {
+		ret = -EBADR;
+		goto out2;
+	}
+
+	/*
+	 * SMI requires command buffer physical address in ebx and
+	 * command signature in ecx.
+	 */
+	command_buffer_phys_addr = (u32) virt_to_phys(ci_cmd->command_buffer);
+
+	/* generate SMI */
+	__asm__ __volatile__(
+		"outb %b0,%w1"
+		: /* no output args */
+		: "a" (ci_cmd->command_code), 
+		  "d" (ci_cmd->command_address), 
+		  "b" (command_buffer_phys_addr), 
+		  "c" (ci_cmd->command_signature)  
+		: "memory"
+	);
+
+out2:
+	up(&smi_data_lock);
+out1:
+	set_cpus_allowed(current, old_mask);
+	return ret;
+}
+
+/**
+ * callintf_smi_store:
+ * 
+ * The valid values are:
+ * 1: generate calling interface SMI
+ * 
+ * User application writes calling interface command to smi_data
+ * before telling driver to generate SMI.
+ */
+static ssize_t callintf_smi_store(struct device *dev,
+				  struct device_attribute *attr,
+				  const char *buf, size_t count)
+{
+	int ret;
+
+	if (simple_strtoul(buf, NULL, 10) != 1)
+		return -EINVAL;
+
+	ret = callintf_smi();
+	if (ret)
+		return ret;
+
+	return count;
+}
+
+/**
+ * host_control_smi: generate host control SMI
+ *
+ * Caller must set up the host control command in smi_data_buf.
+ */
+static int host_control_smi(void)
+{
+	struct apm_cmd *apm_cmd;
+	u8 *data;
+	unsigned long flags;
+	u32 num_ticks;
+	s8 cmd_status;
+	u8 index;
+
+	apm_cmd = (struct apm_cmd *)smi_data_buf;
+	apm_cmd->status = ESM_STATUS_CMD_UNSUCCESSFUL;
+
+	switch (host_control_smi_type) {
+	case HC_SMITYPE_TYPE1:
+		/* write SMI data buffer physical address */
+		data = (u8 *)&smi_data_buf_phys_addr;
+		spin_lock_irqsave(&rtc_lock, flags);
+		for (index = PE1300_CMOS_CMD_STRUCT_PTR;
+		     index < (PE1300_CMOS_CMD_STRUCT_PTR + 4);
+		     index++) {
+			outb(index,
+			     (CMOS_BASE_PORT + CMOS_PAGE2_INDEX_PORT_PIIX4));
+			outb(*data++,
+			     (CMOS_BASE_PORT + CMOS_PAGE2_DATA_PORT_PIIX4));
+		}
+		spin_unlock_irqrestore(&rtc_lock, flags);
+
+		/* first set status to -1 as called by spec */
+		cmd_status = ESM_STATUS_CMD_UNSUCCESSFUL;
+		outb((u8) cmd_status, PCAT_APM_STATUS_PORT);
+
+		/* generate SMM call */
+		outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
+
+		/* restore RTC index pointer */
+		spin_lock_irqsave(&rtc_lock, flags);
+		outb(0x0C, 0x70);
+		inb(0x70);
+		spin_unlock_irqrestore(&rtc_lock, flags);
+
+		/* wait a few to see if it executed */
+		num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
+		while ((cmd_status = inb(PCAT_APM_STATUS_PORT))
+		       == ESM_STATUS_CMD_UNSUCCESSFUL) {
+			num_ticks--;
+			if (num_ticks == EXPIRED_TIMER)
+				return -ETIME;
+		}
+		break;
+
+	case HC_SMITYPE_TYPE2:
+	case HC_SMITYPE_TYPE3:
+		/* write SMI data buffer physical address */
+		data = (u8 *)&smi_data_buf_phys_addr;
+		spin_lock_irqsave(&rtc_lock, flags);
+		for (index = PE1400_CMOS_CMD_STRUCT_PTR;
+		     index < (PE1400_CMOS_CMD_STRUCT_PTR + 4);
+		     index++) {
+			outb(index, (CMOS_BASE_PORT + CMOS_PAGE1_INDEX_PORT));
+			outb(*data++, (CMOS_BASE_PORT + CMOS_PAGE1_DATA_PORT));
+		}
+		spin_unlock_irqrestore(&rtc_lock, flags);
+
+		/* generate SMM call */
+		if (host_control_smi_type == HC_SMITYPE_TYPE3)
+			outb(ESM_APM_CMD, PCAT_APM_CONTROL_PORT);
+		else
+			outb(ESM_APM_CMD, PE1400_APM_CONTROL_PORT);
+
+		/* restore RTC index pointer */
+		spin_lock_irqsave(&rtc_lock, flags);
+		outb(0x0C, 0x70);
+		inb(0x70);
+		spin_unlock_irqrestore(&rtc_lock, flags);
+
+		/* read control port back to serialize write */
+		cmd_status = inb(PE1400_APM_CONTROL_PORT);
+
+		/* wait a few to see if it executed */
+		num_ticks = TIMEOUT_USEC_SHORT_SEMA_BLOCKING;
+		while (apm_cmd->status == ESM_STATUS_CMD_UNSUCCESSFUL) {
+			num_ticks--;
+			if (num_ticks == EXPIRED_TIMER)
+				return -ETIME;
+		}
+		break;
+
+	default:
+		dev_dbg(&dcdbas_pdev->dev, "%s: invalid SMI type %u\n",
+			__FUNCTION__, host_control_smi_type);
+		return -ENOSYS;
+	}
+
+	return 0;
+}
+
+/**
+ * dcdbas_host_control: initiate host control
+ * 
+ * This function is called by the driver after the system has
+ * finished shutting down if the user application specified a
+ * host control action to perform on shutdown.  It is safe to
+ * use smi_data_buf at this point because the system has finished
+ * shutting down and no userspace apps are running.
+ */
+static void dcdbas_host_control(void)
+{
+	struct apm_cmd *apm_cmd;
+	u8 action;
+
+	if (host_control_action == HC_ACTION_NONE)
+		return;
+
+	action = host_control_action;
+	host_control_action = HC_ACTION_NONE;
+
+	if (!smi_data_buf) {
+		dev_dbg(&dcdbas_pdev->dev, "%s: no SMI buffer\n", __FUNCTION__);
+		return;
+	}
+
+	if (smi_data_buf_size < sizeof(struct apm_cmd)) {
+		dev_dbg(&dcdbas_pdev->dev, "%s: SMI buffer too small\n",
+			__FUNCTION__);
+		return;
+	}
+
+	apm_cmd = (struct apm_cmd *)smi_data_buf;
+
+	/* power off takes precedence */
+	if (action & HC_ACTION_HOST_CONTROL_POWEROFF) {
+		apm_cmd->command = ESM_APM_POWER_CYCLE;
+		apm_cmd->reserved = 0;
+		*((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 0;
+		host_control_smi();
+	} else if (action & HC_ACTION_HOST_CONTROL_POWERCYCLE) {
+		apm_cmd->command = ESM_APM_POWER_CYCLE;
+		apm_cmd->reserved = 0;
+		*((s16 *)&apm_cmd->parameters.shortreq.parm[0]) = (s16) 20;
+		host_control_smi();
+	}
+}
+
+/**
+ * dcdbas_reboot_notify: handle reboot notification for host control
+ */
+static int dcdbas_reboot_notify(struct notifier_block *nb, unsigned long code,
+				void *unused)
+{
+	static unsigned int notify_cnt = 0;
+
+	switch (code) {
+	case SYS_DOWN:
+	case SYS_HALT:
+	case SYS_POWER_OFF:
+		if (host_control_on_shutdown) {
+			/* firmware is going to perform host control action */
+			if (++notify_cnt == 2) {
+				printk(KERN_WARNING
+				       "Please wait for shutdown "
+				       "action to complete...\n");
+				dcdbas_host_control();
+			}
+			/*
+			 * register again and initiate the host control
+			 * action on the second notification to allow
+			 * everyone that registered to be notified
+			 */
+			register_reboot_notifier(nb);
+		}
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+static struct notifier_block dcdbas_reboot_nb = {
+	.notifier_call = dcdbas_reboot_notify,
+	.next = NULL,
+	.priority = 0
+};
+
+static DCDBAS_BIN_ATTR_RW(smi_data);
+
+static struct bin_attribute *dcdbas_bin_attrs[] = {
+	&bin_attr_smi_data,
+	NULL
+};
+
+static DCDBAS_DEV_ATTR_RW(smi_data_buf_size);
+static DCDBAS_DEV_ATTR_RO(smi_data_buf_phys_addr);
+static DCDBAS_DEV_ATTR_WO(callintf_smi);
+static DCDBAS_DEV_ATTR_RW(host_control_action);
+static DCDBAS_DEV_ATTR_RW(host_control_smi_type);
+static DCDBAS_DEV_ATTR_RW(host_control_on_shutdown);
+
+static struct device_attribute *dcdbas_dev_attrs[] = {
+	&dev_attr_smi_data_buf_size,
+	&dev_attr_smi_data_buf_phys_addr,
+	&dev_attr_callintf_smi,
+	&dev_attr_host_control_action,
+	&dev_attr_host_control_smi_type,
+	&dev_attr_host_control_on_shutdown,
+	NULL
+};
+
+/**
+ * dcdbas_init: initialize driver
+ */
+static int __init dcdbas_init(void)
+{
+	int i;
+
+	host_control_action = HC_ACTION_NONE;
+	host_control_smi_type = HC_SMITYPE_NONE;
+
+	dcdbas_pdev = platform_device_register_simple(DRIVER_NAME, -1, NULL, 0);
+	if (IS_ERR(dcdbas_pdev))
+		return PTR_ERR(dcdbas_pdev);
+
+	/*
+	 * BIOS SMI calls require buffer addresses be in 32-bit address space.
+	 * This is done by setting the DMA mask below.
+	 */
+	dcdbas_pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
+	dcdbas_pdev->dev.dma_mask = &dcdbas_pdev->dev.coherent_dma_mask;
+
+	register_reboot_notifier(&dcdbas_reboot_nb);
+
+	for (i = 0; dcdbas_bin_attrs[i]; i++)
+		sysfs_create_bin_file(&dcdbas_pdev->dev.kobj,
+				      dcdbas_bin_attrs[i]);
+
+	for (i = 0; dcdbas_dev_attrs[i]; i++)
+		device_create_file(&dcdbas_pdev->dev, dcdbas_dev_attrs[i]);
+
+	dev_info(&dcdbas_pdev->dev, "%s (version %s)\n",
+		 DRIVER_DESCRIPTION, DRIVER_VERSION);
+
+	return 0;
+}
+
+/**
+ * dcdbas_exit: perform driver cleanup
+ */
+static void __exit dcdbas_exit(void)
+{
+	platform_device_unregister(dcdbas_pdev);
+	unregister_reboot_notifier(&dcdbas_reboot_nb);
+	smi_data_buf_free();
+}
+
+module_init(dcdbas_init);
+module_exit(dcdbas_exit);
+
+MODULE_DESCRIPTION(DRIVER_DESCRIPTION " (version " DRIVER_VERSION ")");
+MODULE_VERSION(DRIVER_VERSION);
+MODULE_AUTHOR("Dell Inc.");
+MODULE_LICENSE("GPL");
+
diff -uprN linux-2.6.13-rc6.orig/drivers/firmware/dcdbas.h linux-2.6.13-rc6/drivers/firmware/dcdbas.h
--- linux-2.6.13-rc6.orig/drivers/firmware/dcdbas.h	1969-12-31 18:00:00.000000000 -0600
+++ linux-2.6.13-rc6/drivers/firmware/dcdbas.h	2005-08-15 14:07:35.000000000 -0500
@@ -0,0 +1,106 @@
+/*
+ *  dcdbas.h: Definitions for Dell Systems Management Base driver
+ *
+ *  Copyright (C) 1995-2005 Dell Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License v2.0 as published by
+ *  the Free Software Foundation.
+ *
+ *  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.
+ */
+
+#ifndef _DCDBAS_H_
+#define _DCDBAS_H_
+
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/sysfs.h>
+#include <linux/types.h>
+
+#define MAX_SMI_DATA_BUF_SIZE			(256 * 1024)
+
+#define HC_ACTION_NONE				(0)
+#define HC_ACTION_HOST_CONTROL_POWEROFF		BIT(1)
+#define HC_ACTION_HOST_CONTROL_POWERCYCLE	BIT(2)
+
+#define HC_SMITYPE_NONE				(0)
+#define HC_SMITYPE_TYPE1			(1)
+#define HC_SMITYPE_TYPE2			(2)
+#define HC_SMITYPE_TYPE3			(3)
+
+#define ESM_APM_CMD				(0x0A0)
+#define ESM_APM_POWER_CYCLE			(0x10)
+#define ESM_STATUS_CMD_UNSUCCESSFUL		(-1)
+
+#define CMOS_BASE_PORT				(0x070)
+#define CMOS_PAGE1_INDEX_PORT			(0)
+#define CMOS_PAGE1_DATA_PORT			(1)
+#define CMOS_PAGE2_INDEX_PORT_PIIX4		(2)
+#define CMOS_PAGE2_DATA_PORT_PIIX4		(3)
+#define PE1400_APM_CONTROL_PORT			(0x0B0)
+#define PCAT_APM_CONTROL_PORT			(0x0B2)
+#define PCAT_APM_STATUS_PORT			(0x0B3)
+#define PE1300_CMOS_CMD_STRUCT_PTR		(0x38)
+#define PE1400_CMOS_CMD_STRUCT_PTR		(0x70)
+
+#define MAX_SYSMGMT_SHORTCMD_PARMBUF_LEN	(14)
+#define MAX_SYSMGMT_LONGCMD_SGENTRY_NUM		(16)
+
+#define TIMEOUT_USEC_SHORT_SEMA_BLOCKING	(10000)
+#define EXPIRED_TIMER				(0)
+
+#define CALLINTF_CMD_MAGIC			(0x43414C4C)
+
+#define DCDBAS_DEV_ATTR_RW(_name) \
+	DEVICE_ATTR(_name,0644,_name##_show,_name##_store);
+
+#define DCDBAS_DEV_ATTR_RO(_name) \
+	DEVICE_ATTR(_name,0444,_name##_show,NULL);
+
+#define DCDBAS_DEV_ATTR_WO(_name) \
+	DEVICE_ATTR(_name,0200,NULL,_name##_store);
+
+#define DCDBAS_BIN_ATTR_RW(_name) \
+struct bin_attribute bin_attr_##_name = { \
+	.attr =  { .name = __stringify(_name), \
+		   .mode = 0644, \
+		   .owner = THIS_MODULE }, \
+	.read =  _name##_read, \
+	.write = _name##_write, \
+}
+
+struct callintf_cmd {
+	u32 magic;
+	u16 command_address;
+	u8 command_code;
+	u8 reserved;
+	u32 command_signature;
+	u8 command_buffer[1];
+} __attribute__ ((packed));
+
+struct apm_cmd {
+	u8 command;
+	s8 status;
+	u16 reserved;
+	union {
+		struct {
+			u8 parm[MAX_SYSMGMT_SHORTCMD_PARMBUF_LEN];
+		} __attribute__ ((packed)) shortreq;
+
+		struct {
+			u16 num_sg_entries;
+			struct {
+				u32 size;
+				u64 addr;
+			} __attribute__ ((packed))
+			    sglist[MAX_SYSMGMT_LONGCMD_SGENTRY_NUM];
+		} __attribute__ ((packed)) longreq;
+	} __attribute__ ((packed)) parameters;
+} __attribute__ ((packed));
+
+#endif /* _DCDBAS_H_ */
+
diff -uprN linux-2.6.13-rc6.orig/drivers/firmware/Kconfig linux-2.6.13-rc6/drivers/firmware/Kconfig
--- linux-2.6.13-rc6.orig/drivers/firmware/Kconfig	2005-06-17 14:48:29.000000000 -0500
+++ linux-2.6.13-rc6/drivers/firmware/Kconfig	2005-08-15 14:07:39.000000000 -0500
@@ -58,4 +58,21 @@ config EFI_PCDP
 
 	  See <http://www.dig64.org/specifications/DIG64_HCDPv20_042804.pdf>
 
+config DCDBAS
+	tristate "Dell Systems Management Base Driver"
+	depends on X86 || X86_64
+	default m
+	help
+	  The Dell Systems Management Base Driver provides a sysfs interface
+	  for systems management software to perform System Management
+	  Interrupts (SMIs) and Host Control Actions (system power cycle or
+	  power off after OS shutdown) on certain Dell systems.
+
+	  See <file:Documentation/dcdbas.txt> for more details on the driver
+	  and the Dell systems on which Dell systems management software makes
+	  use of this driver.
+
+	  Say Y or M here to enable the driver for use by Dell systems
+	  management software such as Dell OpenManage.
+
 endmenu
diff -uprN linux-2.6.13-rc6.orig/drivers/firmware/Makefile linux-2.6.13-rc6/drivers/firmware/Makefile
--- linux-2.6.13-rc6.orig/drivers/firmware/Makefile	2005-06-17 14:48:29.000000000 -0500
+++ linux-2.6.13-rc6/drivers/firmware/Makefile	2005-08-15 14:07:43.000000000 -0500
@@ -4,3 +4,4 @@
 obj-$(CONFIG_EDD)             	+= edd.o
 obj-$(CONFIG_EFI_VARS)		+= efivars.o
 obj-$(CONFIG_EFI_PCDP)		+= pcdp.o
+obj-$(CONFIG_DCDBAS)		+= dcdbas.o
diff -uprN linux-2.6.13-rc6.orig/MAINTAINERS linux-2.6.13-rc6/MAINTAINERS
--- linux-2.6.13-rc6.orig/MAINTAINERS	2005-08-15 11:19:05.000000000 -0500
+++ linux-2.6.13-rc6/MAINTAINERS	2005-08-15 14:07:12.000000000 -0500
@@ -696,6 +696,11 @@ M:	dz@debian.org
 W:	http://www.debian.org/~dz/i8k/
 S:	Maintained
 
+DELL SYSTEMS MANAGEMENT BASE DRIVER (dcdbas)
+P:	Doug Warzecha
+M:	Douglas_Warzecha@dell.com
+S:	Maintained
+
 DEVICE-MAPPER
 P:	Alasdair Kergon
 L:	dm-devel@redhat.com

^ permalink raw reply	[flat|nested] 36+ messages in thread
* Re: [RFC][PATCH 2.6.13-rc6] add Dell Systems Management Base Driver (dcdbas) with sysfs support
@ 2005-08-15 22:58 Michael_E_Brown
  2005-08-16  1:29 ` Kyle Moffett
  0 siblings, 1 reply; 36+ messages in thread
From: Michael_E_Brown @ 2005-08-15 22:58 UTC (permalink / raw)
  To: mrmacman_g4; +Cc: linux-kernel, Douglas_Warzecha, Matt_Domsch

>> +On some Dell systems, systems management software must access
certain
>> +management information via a system management interrupt (SMI).   
>> The SMI data
>> +buffer must reside in 32-bit address space, and the physical  
>> address of the
>> +buffer is required for the SMI.  The driver maintains the memory  
>> required for
>> +the SMI and provides a way for the application to generate the SMI.
>> +The driver creates the following sysfs entries for systems
management
>> +software to perform these system management interrupts:
>
> Why can't you just implement the system management actions in the
kernel
> driver?  This is tantamount to a binary SMI hook to userspace.  What
> functionality does this provide on a dell system from an
administrator's
> point of view?

Kyle,
	I'm sure that not everybody agrees with the whole concept of SMI

calls. Nevertheless, these calls exist, and in order to have a complete 
systems-management solution, we have to provide a way to do SMI calls. 
Now, we have developed a way to do these SMI calls from userspace
without 
kernel support, but we are trying to be community-friendly and show our 
hooks in the open, rather than trying to sneak them in under the covers.

	You might not like the concept of a generic hook for SMI calls
in 
the kernel, but the alternatives are hardly better. One alternative is 
the already-mentioned method that we do things under the covers in 
userspace. Another alternative is that we write separate kernel code for

each and every SMI call that exists in the Dell BIOS. The second 
alternative is not entirely feasible. We have over 60 SMI functions, and

we would have to write a kernel-mode wrapper for each and every one. I 
hope you agree that code that doesn't exist is less buggy than code that

is, and that code that is in userspace is a whole lot less likely to
cause 
a kernel crash than code that is in the kernel. We are trying to keep
our 
kernel bloat down. We don't really think that customers of IBM or HP
really 
want their Red Hat kernels loaded down with a bunch of Dell-only code.
	
	Additionally, we are releasing an open source library (GPL/OSL
dual 
license) that can use these hooks to perform many systems management 
functions in userspace. See http://linux.dell.com/libsmbios/main/. We 
should have code in libsmbios to do SMI using this driver within about
two 
weeks.  We currently writing the SMI hooks in libsmbios using this
posted 
version of the driver. I am the maintainer of this project, and it is my
goal 
to have code in libsmbios for every Dell SMI call.

	Dell is not trying to use this driver as a method of inserting
binary 
blobs into the kernel, nor are we trying to subvert kernel security by 
implementing this driver. We are simply trying to get all of our systems

management software into the kernel as open source drivers. This
represents 
a fundamental shift in philosophy from the Dell systems-management team
from 
our previous binary-only driver approach. 

	We would welcome feedback on a better way to implement this
driver in 
the kernel, but the fact remains that we have to have a way to do this,
and 
we are open-sourcing all of the code necessary to get this done. 
--
Michael Brown

^ permalink raw reply	[flat|nested] 36+ messages in thread
* Re: [RFC][PATCH 2.6.13-rc6] add Dell Systems Management Base Driver (dcdbas) with sysfs support
@ 2005-08-16  4:09 Michael E Brown
  2005-08-16  5:17 ` Valdis.Kletnieks
  0 siblings, 1 reply; 36+ messages in thread
From: Michael E Brown @ 2005-08-16  4:09 UTC (permalink / raw)
  To: Valdis.Kletnieks, linux-kernel

>On Mon, 15 Aug 2005 18:38:49 CDT, Doug Warzecha said:
>
>> > If this is supposed to be used with the RBU code to trigger a BIOS  
>> > update, ...
>> 
>> This driver is not needed by the RBU code.
>
> Documentation/dell_rbu.txt says:
>
>> The rbu driver needs to have an application which will inform the BIOS to
>> enable the update in the next system reboot.
>
> Can the dcdbas code be used to implement that application?

No, dcdbas has nothing to do with this. I'll have to submit a patch
against the docs. The program you need to use already exists and is
open source. You can use libsmbios to do this.
http://linux.dell.com/libsmbios/main.

The binary you want to use is "activateCmosToken", under bins/output/
(after compilation). The command line syntax is like this:
	activateCmosToken 0x005C

If you want to cancel a BIOS update that has already been activated
(per above), use: 	
	activateCmosToken 0x005D

Basically, follow the docs in the RBU docs as far as cat-ing the bios
update image to the rbu sysfs files, then use the activateCmosToken
program to tell BIOS to do the update on reboot. 

-- 
Michael





^ permalink raw reply	[flat|nested] 36+ messages in thread
* Re: [RFC][PATCH 2.6.13-rc6] add Dell Systems Management Base Driver (dcdbas) with sysfs support
@ 2005-08-16  4:58 Michael E Brown
  2005-08-16  5:36 ` Valdis.Kletnieks
  0 siblings, 1 reply; 36+ messages in thread
From: Michael E Brown @ 2005-08-16  4:58 UTC (permalink / raw)
  To: Kyle Moffett, Doug Warzecha, linux-kernel

I am not subscribed to linux-kernel. Please cc me (and Doug) on all
replies. Sorry if I'm breaking peoples threading, but I am cut-and-
pasting this from web archives, since this wasn't cc-d to me
originally. 

>On Aug 15, 2005, at 19:38:49, Doug Warzecha wrote:
>> On Mon, Aug 15, 2005 at 04:23:37PM -0400, Kyle Moffett wrote:
>>> Why can't you just implement the system management actions in the  
>>> kernel
>>> driver?
>>
>> We want to minimize the amount of code in the kernel and avoid  
>> having to
>> update the driver each time a new system management command is added.
>
> One of the recent trends in kernel driver development is to make as much
> as possible accessible through standard tools (like with echo and cat  
> via sysfs).

Where it makes sense. Everything can be taken too far, and I believe
that you are taking this past the point of sanity. Are you also to
advocate that X stop mmap()-ing /dev/mem to manipulate PCI memory-space
of the video cards, but rather we should have a kernel driver that
makes every register of each PCI card available as a file in sysfs so
that we can re-write X as a big bash script? Let me know how that works
out.

>
>> The libsmbios project is being updated to use this code.  http:// 
>> linux.dell.com/libsmbios/main/.  Using the libsmbios code, you
>> will be able to set all of the options in BIOS F2 screen from Linux
>> userspace.  Also, libsmbios is looking at implementing a few other  
>> things
>> like fan status.  Libsmbios is 100% open-source (OSL/GPL dual  
>> license).
>
>  From my point of view, this driver could use sysfs almost entirely  
> and put
> all of the hardware-manipulation code completely in kernel space, along
> with the hardware detection code.  You could have plain-text files in
> /sys/bus/platform/dellbios/ that have all of the BIOS F2 options  
> accessible
> to the admin from the command line, without special tools.  (You could
> always add an extra program that presents a BIOS-like interface)

Conservatively counting, I see just about 350 different BIOS options in
my current list, plus about 60 different (unrelated) SMI calls. We are
talking about several tens of thousands of lines of code in the kernel
to surface each of these in the kernel along with all of the necessary
BIOS-bug-workaround and platform detection code. This is not pretty,
nor easy code. I, personally, do not want to be responsible for the
parsing bug that causes a root hole here. 

In userspace, I can easily stick all of the cross-references into an
XML file, along with the workarounds and bug-fixes, which makes the
code a bit tighter. We have one project here at Dell that implemented
an all C (userspace) equivalent of what you are talking about, and they
ended up writing a code generation script that took XML definitions of
each option and generated the resulting C code. They still ended up
with a huge bucketload of code. We don't have the same conveniences in
kernel-land. All the nice toys are userspace.

>> The method of generating a host control SMI is not exactly the same  
>> for
>> each PowerEdge system listed in dcdbas.txt.  host_control_smi_type  
>> tells
>> the driver how to generate the host control SMI for the system in use.
>> I'll update dcdbas.txt with the SMI type value associated with the  
>> systems
>> listed in that file.
>
> This is an _excellent_ reason why more of this should be in the kernel.
> What happens if the wrong SMI is used?  Shouldn't it be relatively easy
> for the kernel to determine the correct SMI itself?

No, this is an _EXCELLENT_ reason why _LESS_ of this should be in the
kernel. Why should we have to duplicate a _TON_ of code inside the
kernel to figure out which platform we are on, and then look up in a
table which method to use for that platform? We have a _MUCH_ nicer
programming environment available to us in userspace where we can use
things like libsmbios to look up the platform type, then look in an
easily-updateable text file which smi type to use. In general, plugging
the wrong value here is a no-op.

What you are advocating is that we bloat the kernel beyond belief just
so you can use echo and cat. I thought that we were trying to remove
extra stuff from the kernel. I thought this was the reasoning behind
initramfs and things like irqbalanced.

-- 
Michael



^ permalink raw reply	[flat|nested] 36+ messages in thread
* Re: [RFC][PATCH 2.6.13-rc6] add Dell Systems Management Base Driver (dcdbas) with sysfs support
@ 2005-08-16  5:19 Michael E Brown
  2005-08-16  5:35 ` Chris Wedgwood
  0 siblings, 1 reply; 36+ messages in thread
From: Michael E Brown @ 2005-08-16  5:19 UTC (permalink / raw)
  To: Kyle Moffett, Chris Wedgwood, linux-kernel, Doug Warzecha

Again, please cc Doug and I on replies...

Kyle Moffett wrote:
>On Aug 16, 2005, at 00:34:51, Chris Wedgwood wrote:
>> On Mon, Aug 15, 2005 at 04:23:37PM -0400, Kyle Moffett wrote:
>>> Why can't you just implement the system management actions in the
>>> kernel driver?
>>
>> Why put things in the kernel unless it's really needed?

Thank you. Our sentiments exactly.

>>
>> I'm not thrillied about the lack of userspace support for this driver
>> but that still doesn't mean we need to shovel wads of crap into the
>> kernel.

Hmm... did I mention libsmbios? :-)
http://linux.dell.com/libsmbios/main.

SMI support is not yet implemented inside libsmbios, but I am working
feverishly on it (in-between emails to linux-kernel, of course.) :-) We
have a development mailing list, and I will make the announcement there
when it has been complete. I will also be submitting patches to the RBU
documentation and dcdbas documentation pointing to libsmbios for folks
that want a 100% open-source method of using these drivers.

I cannot (at this point, I'm working on it, though), provide our
internal documentation of our SMI implementation directly. But, I am
authorized to add all of this to libsmbios, and I intend to very
clearly document all of the SMI calls in libsmbios. 

>
> I'm worried that it might be more of a mess in userspace than it  
> could be
> if done properly in the kernel.  Hardware drivers, especially for  
> something
> as critical as the BIOS, should probably be done in-kernel.  Look at the
> mess that X has become, it mmaps /dev/mem and pokes at the PCI busses
> directly.  I just don't want an MSI-driver to become another /dev/mem.

Again, this is a whole different thing from a video card driver. The
SMI driver consists of one instruction: "outb magic_port#,
magic_value;", with the simple addition that EBX contain the
physical address of buffer that holds the requested command code and the
return values.

There isn't really a whole lot more than that. For the Dell SMI, you
have to look up the magic port # and magic value in smbios,
specifically, there is a vendor structure 0xDA with a specific layout
(which will be documented in libsmbios) that specifies the magic port
and value.

Aside from that, for the most part, the only thing SMI ever does is
pass buffers back and forth. 

-- 
Michael




^ permalink raw reply	[flat|nested] 36+ messages in thread
* RE: [RFC][PATCH 2.6.13-rc6] add Dell Systems Management Base Driver (dcdbas) with sysfs support
@ 2005-08-16 23:47 Michael_E_Brown
  2005-08-17  5:33 ` Matt Domsch
  0 siblings, 1 reply; 36+ messages in thread
From: Michael_E_Brown @ 2005-08-16 23:47 UTC (permalink / raw)
  To: greg; +Cc: mrmacman_g4, linux-kernel, Douglas_Warzecha, Matt_Domsch

> -----Original Message-----
> From: Greg KH [mailto:greg@kroah.com] 
> Sent: Tuesday, August 16, 2005 6:24 PM
> To: Brown, Michael E
> Cc: mrmacman_g4@mac.com; linux-kernel@vger.kernel.org; 
> Warzecha, Douglas; Domsch, Matt
> Subject: Re: [RFC][PATCH 2.6.13-rc6] add Dell Systems 
> Management Base Driver (dcdbas) with sysfs support
> 
> 
> On Tue, Aug 16, 2005 at 06:11:13PM -0500, 
> Michael_E_Brown@Dell.com wrote:
> > 
> >     The main use of this driver by libsmbios will be to set BIOS F2
> > options. Based on your feedback, I will _NOT_ be implementing any 
> > fan/sensor functionality in libsmbios, but will work with 
> the lmsensors 
> > guys to do this instead. I only originally mentioned it because I 
> > thought it would be useful. My eyes have now been opened as 
> to the best 
> > way to do this, and we will do it that way.
> 
> Ok, sounds good.
> 
> Hm, what about my code comments, they seem to have been lost 
> in the noise...

No, they are not lost. Doug is working on them and will send you
something shortly (EOD today).

> 
> > And just to re-iterate one more time, we can already directly hook 
> > into
> > hardware from userspace without any kernel auditing. We are 
> just trying 
> > to set this out on the table for everybody to see.
> 
> So, this whole driver is not needed at all?  It can all be 
> done from userspace?  If so, then this shouldn't be added to 
> the kernel tree.

Several reasons:

A) Auditability: we don't do "secret" SMI calls behind people's backs.
This is an issue for some of our larger customers. This also provides a
legitimate reason that I can use to justify to management publicly
documenting the rest of the SMI calls that are not in use by our
software. Things like: "Hey, SomeBigDellCustomer wants to know what Dell
is doing with the open source dcdbas driver and all of the other SMI
function docs" pull a lot of weight.

B) Safety: It is easier to provide a single API with well defined
semantics so there are no race conditions when multiple programs try to
do SMI at the same time. SMI from userspace can be tricky, and I want to
make it easy to get right. Things like finding an usused BIOS reserved
area and coordinating access between multiple programs can be difficult.
Additionally, finding an area large enough to hold everything for the
larger SMI calls is tricky (ie. depends on which system, BIOS memory
layout, etc. Very difficult to safely code for and mostly not worth the
effort if we can get this driver in).

C) host control actions need to happen in kernel at shutdown, so that
part of the driver needs to be in the kernel. (this part isn't the part
that provides generic SMI stuff to userspace)

--
Michael

^ permalink raw reply	[flat|nested] 36+ messages in thread
[parent not found: <4277B1B44843BA48B0173B5B0A0DED4352817E@ausx3mps301.aus.amer.dell.com.suse.lists.linux.kernel>]

end of thread, other threads:[~2005-08-17  7:32 UTC | newest]

Thread overview: 36+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-08-15 20:05 [RFC][PATCH 2.6.13-rc6] add Dell Systems Management Base Driver (dcdbas) with sysfs support Doug Warzecha
2005-08-15 20:23 ` Kyle Moffett
2005-08-15 23:38   ` Doug Warzecha
2005-08-16  1:44     ` Kyle Moffett
2005-08-16  2:43     ` Valdis.Kletnieks
2005-08-16  4:34   ` Chris Wedgwood
2005-08-16  4:55     ` Kyle Moffett
2005-08-16  5:14       ` Chris Wedgwood
2005-08-16  5:52 ` Greg KH
2005-08-17  0:02   ` Doug Warzecha
  -- strict thread matches above, loose matches on Subject: below --
2005-08-15 22:58 Michael_E_Brown
2005-08-16  1:29 ` Kyle Moffett
2005-08-16  3:10   ` Michael E Brown
2005-08-16  5:59     ` Nathan Lutchansky
2005-08-16  8:16     ` Greg KH
2005-08-16 13:34       ` Michael E Brown
2005-08-16 20:31         ` Pavel Machek
2005-08-16 20:37         ` Greg KH
2005-08-16 23:11           ` Michael_E_Brown
2005-08-16 23:23             ` Greg KH
2005-08-16  4:09 Michael E Brown
2005-08-16  5:17 ` Valdis.Kletnieks
2005-08-16  5:30   ` Michael E Brown
2005-08-16  4:58 Michael E Brown
2005-08-16  5:36 ` Valdis.Kletnieks
2005-08-16  6:10   ` Michael E Brown
2005-08-16  6:45     ` Valdis.Kletnieks
2005-08-16 12:15   ` Andrey Panin
2005-08-16  5:19 Michael E Brown
2005-08-16  5:35 ` Chris Wedgwood
2005-08-16  5:50   ` Michael E Brown
2005-08-16 23:47 Michael_E_Brown
2005-08-17  5:33 ` Matt Domsch
2005-08-17  7:32   ` Kyle Moffett
     [not found] <4277B1B44843BA48B0173B5B0A0DED4352817E@ausx3mps301.aus.amer.dell.com.suse.lists.linux.kernel>
     [not found] ` <DEFA2736-585A-4F84-9262-C3EB53E8E2A0@mac.com.suse.lists.linux.kernel>
     [not found]   ` <1124161828.10755.87.camel@soltek.michaels-house.net.suse.lists.linux.kernel>
     [not found]     ` <20050816081622.GA22625@kroah.com.suse.lists.linux.kernel>
     [not found]       ` <1124199265.10755.310.camel@soltek.michaels-house.net.suse.lists.linux.kernel>
     [not found]         ` <20050816203706.GA27198@kroah.com.suse.lists.linux.kernel>
     [not found]           ` <4277B1B44843BA48B0173B5B0A0DED43528192@ausx3mps301.aus.amer.dell.com.suse.lists.linux.kernel>
2005-08-17  0:23             ` Andi Kleen
2005-08-17  0:41               ` Michael E Brown

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox