Legacy hotplug modules and documentation: Delete. These modules no

longer work with 2.6 kernels.


git-svn-id: http://lm-sensors.org/svn/lm-sensors/branches/lm-sensors-3.0.0@4402 7894878c-1315-0410-8ee3-d5d059ff63e0
This commit is contained in:
Jean Delvare committed 2007-05-13 08:22:47 +00:00
1 parent 9232f4eb43
commit 314c674660
7 files changed
+14 -1014

No files matched your search

+1
View File
@@ -4,6 +4,7 @@ lm_sensors CHANGES file
SVN HEAD
All bus modules and documentation: Delete
All chip modules and documentation: Delete
Legacy hotplug modules and documentation: Delete
File doc/version-2: Delete, obsolete
File sensors.conf.eg: Add a dme1737 section
File lm_sensors.sysconfig: Delete, now generated by sensors-detect
-24
View File
@@ -1,24 +0,0 @@
INCLUDEDIR = /usr/include
# Compile with Debugging turned on - watch out, lots of pci device infos.
CFLAGS = -D__KERNEL__ -DMODULE -DLINUX -DM7101_DEBUG -O2 -Wall -I$(INCLUDEDIR)
# CFLAGS := -D__KERNEL__ -DMODULE -DLINUX -O2 -Wall -I$(INCLUDEDIR)
CC := gcc
LD := ld
# extract versionnumber from version.h
VER = $(shell awk -F\" '/REL/ {print $$2}' $(INCLUDEDIR)/linux/version.h)
OBJS = m7101.o
all: $(OBJS)
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
install: all
install -m 644 $(OBJS) /lib/modules/$(VER)/kernel/drivers/i2c/busses
clean:
rm -f $(OBJS)
-64
View File
@@ -1,64 +0,0 @@
# pcwd Kernel Module Makefile
#
VERSION=1.40
# The currently running kernel version. This is used right below to
# determine where the kernel sources can be found.
KERNELVERSION := $(shell uname -r)
# The location of linux itself. This is used to find the kernel headers
# and other things.
#LINUX := /usr/src/linux
LINUX := /lib/modules/$(KERNELVERSION)/build
LINUX_HEADERS := $(LINUX)/include
# Uncomment the third line on SMP systems if the magic invocation fails. It
# is a bit complicated because SMP configuration changed around kernel 2.1.130
SMP := $(shell if grep -q '^SMP[[:space:]]*=' $(LINUX)/Makefile || \
grep -q '^[[:space:]]*\#define[[:space:]]*CONFIG_SMP[[:space:]]*1' $(LINUX_HEADERS)/linux/autoconf.h ; \
then echo 1; else echo 0; fi)
#SMP := 0
#SMP := 1
# Uncomment the second or third line if the magic invocation fails.
# We need to know whether CONFIG_MODVERSIONS is defined.
MODVER := $(shell if cat $(LINUX_HEADERS)/linux/config.h $(LINUX_HEADERS)/linux/autoconf.h 2>/dev/null | grep -q '^[[:space:]]*\#define[[:space:]]*CONFIG_MODVERSIONS[[:space:]]*1'; then echo 1; else echo 0; fi)
#MODVER := 0
#MODVER := 1
MODCPPFLAGS :=
ifeq ($(SMP),1)
MODCPPFLAGS += -D__SMP__
endif
ifeq ($(MODVER),1)
MODCPPFLAGS += -DMODVERSIONS -include $(LINUX_HEADERS)/linux/modversions.h
endif
CFLAGS := $(MODCPPFLAGS) -D__KERNEL__ -DMODULE -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strict-aliasing -I$(LINUX_HEADERS)
OBJS = p4b_smbus.o
all: $(OBJS)
install: all
install -d /lib/modules/$(KERNELVERSION)/kernel/drivers/i2c/busses
install -c p4b_smbus.o /lib/modules/$(KERNELVERSION)/kernel/drivers/i2c/busses
# test ! -x /dev/watchdog || mknod -m 600 /dev/watchdog c 10 130
# test ! -x /dev/temperature || mknod -m 600 /dev/temperature c 10 131
inst: all
rmmod p4b_smbus
install -d /lib/modules/$(KERNELVERSION)/kernel/drivers/i2c/busses
install -c p4b_smbus.o /lib/modules/$(KERNEL)/kernel/drivers/i2c/busses
depmod -a
# modprobe p4b_smbus
clean:
rm -f *.o *~ core
cleandist:
rm -f *.o *~ core
-112
View File
@@ -1,112 +0,0 @@
Files in this directory:
* m7101.c
M7101 - SMBus Support for ALi M15x3 based motherboards.
* README.p4b
More detailed information for files below.
* p4b_smbus.c
2.4 Kernel module which unhides the bus for ASUS boards.
* unhide_ICH_SMBus
Script which unhides the bus for 2.6 kernel.
--------------------------------------------------------
Quick Start (2.4 kernels only):
Verify that hotplug is enabled in your kernel (general setup)
and reconfigure/rebuild/reinstall kernel if not
"lspci" to verify that 7101 device is not present
"make"
(as root) "make install"
(as root) "insmod m7101"
"lspci" to verify that 7101 device is present
--------------------------------------------------------
--------------------------------------------------------
Version 0.2 for 2.4.0-testx kernels.
Mark D. Studebaker <mdsxyz123@yahoo.com>
*** You must have 'Support for hot-pluggable devices' enabled
*** in your kernel (under 'general setup') for this module to work!!
For 2.2 and early 2.3 kernels you must use version 0.1;
version 0.2 will not work.
Version 0.1 does not use the kernel hotplug facility.
--------------------------------------------------------
Notes below for the 0.2 version, MDS.
--------------------------------------------------------
Default I/O addresses are 0xe800 for SMBus and 0xec00 for ACPI.
These can be changed at module insertion.
For example:
insmod m7101 smb_io=0x5000 acpi_io=0x4000
--------------------------------------------------------
Notes below from the 0.1 version, B. Kohl.
--------------------------------------------------------
This module was written to enable SMBus support on ALi M15x3 chipset based
motherboards. Although it was written for and tested on Gigabytes GA-5AX
it should work on any M15x3 chipset based board.
Probably most people trying this software on a GA-5AX will be utterly
disappointed. We have seen no sensor chips on this board - only DIMMs
were connected to the SMBus. If you are trying to make lm_sensors read
temperature and voltage values you will be pretty lost.
CAVEAT: To perform it's task this module needs to manipulate PCI-config
data and device structures on a very low level. This bears the risk of
causing havoc to your system in case anything goes wrong. Use this soft-
ware absolutely at your own risk.
Installation:
Untar the m7101.tgz file into an appropriate location and cd into the
m7101 subdirectory. Then type "make" to build the module file 'm7101.o'.
To insert it type
$ insmod m7101.o
as root.
If everything goes well (no error messages) you will see a description like
the following when doing 'lspci -v':
00:03.0 Non-VGA unclassified device: Acer Laboratories Inc. [ALi] M7101 PMU
Flags: medium devsel
I/O ports at 4000
I/O ports at 5000
and find an entry in the proc filesystem under /proc/bus/pci/00/03.0.
Removing the module removes the M7101 device from the proc file system
and switches the SMBus support off.
The lm_sensors software now should be able to access devices on the
motherboard's SMBus through the M7101.
Values for the ACPI-IO port (normally 0x4000) and the SMBus-IO port
(normally 0x5000) can be specified using the parameters acpi_io and
smbus_io respectively on the insmod command line.
The module defaults to ports 0xec00 and 0xe800.
In case the module does not load you might want to switch on debugging
by uncommenting the second CFLAGS-line (with the -DM7101_DEBUG switch)
in the Makefile.
This module was written to activate SMBus support. I don't know neither
have I tested wether it works with the software from the ACPI project.
Note: Egcs compilers with versions below 2.95.2 do not compile properly.
Use either 2.95.2 or gcc 2.7.2.x.
I have tested this module with 2.2 kernels up to version 2.2.14.
I wish to thank Frank Bauer for his help with this module.
Burkhard Kohl (burkhard.kohl@gmx.de)
+13 -83
View File
@@ -1,13 +1,15 @@
What is it?
-----------
It unhides the SMBus of Intel ICH southbridges hidden
on ASUS P4B series. It is implemented as a module (p4b_smbus.o),
or a shell script for the 2.6 kernel (unhide_ICH_SMBus).
It unhides the SMBus of Intel ICH southbridges hidden on Asus P4B series
and some other Asus and non-Asus systems. It is implemented as a shell
script for the 2.6 kernel: unhide_ICH_SMBus.
It works with the following chips:
* ICH2 (82801BA)
* ICH2-M (82801BAM)
* ICH3 (82801CA)
* ICH3-M (82801CAM)
* ICH4 (82801DB)
* ICH4-M (82801DBM)
* ICH5 (82801EB)
@@ -17,13 +19,15 @@ with the German support and learned that: "We do not want the users to be
irritated by just another PCI Device in the Win98 device manager."
Really funny :-).
This module is for 2.4 kernels only. For 2.6 kernels, activation is
handled by the code in drivers/pci/quirks.c in the kernel source. If you
have the 2.6 kernel and the quirks code does not activate your SMBus,
you may:
For 2.6 kernels, activation is normally handled by the code in
drivers/pci/quirks.c in the kernel source. If you have the 2.6 kernel and
the quirks code does not activate your SMBus, you may:
* check if you have kernel version from 2.6.17 to 2.6.19
If so you, need to disable ACPI sleep support and recompile kernel.
* first of all, read the paragraph "Hidden ICH SMBus" in
Documentation/i2c/busses/i2c-i801 in the kernel source.
* check if you have kernel version from 2.6.16 to 2.6.19
If so, you need to disable ACPI sleep support and recompile kernel.
If you don't use suspend try below instead of recompilation.
* run as root the ./unhide_ICH_SMBus script. It will unhide the bus
@@ -33,77 +37,3 @@ you may:
* if above script works and you have latest kernel, you may
try to fix the quirks.c, recompile and test your new kernel,
and then submit a patch to us. Contact us if you need assistance.
Information for 2.4 users continues below.
NOTE: As of kernel 2.4.23, the kernel activates the SMBus PCI device
on the following boards:
* Asus P4B
* Asus P4B533
* Asus P4PE
* Asus P4T533
* Asus P4G8X Deluxe
So this module is no longer required for these boards. For the other
affected boards, it still is.
What does the module do?
------------------------
(Note: the following instructions assume the ICH2. For the ICH4,
the PCI IDs are 24C0 and 24C3)
It turnes off (!) the bits number 8 and 3 in the LPC register of the ICH2.
This you can also try as root with setpci and pcitweak.
First do a:
setpci -d 8086:2440 f2.w
You will get an hex number VAL - in my case 148 (Hex)-, where you have to
erase the two bits - in my case you get 40 (Hex).
Then do a:
setpci -d 8086:2440 f2.w=VAL
Running "lspci -n" you will not see any new device, but with "pcitweak -l" you
should get a line similar to this in the output:
PCI: 00:1f:3: chip 8086,2443 card 1043,8028 rev 12 class 0c,05,00 hdr 00
The important thing is the "8086,2443" here.
The device is activated, but not included in /proc/pci and
/proc/bus/pci/devices. This is the reason for running the module.
What are the system requirements?
---------------------------------
- Obviously a board with Intel i801BA/DB/EB ICH2/4/5 with broken BIOS.
- A linux working with a 2.4 kernel AND hotplug support in it!
- A installed kernel tree and gcc.
- i2c and sensor modules installed.
How to install?
---------------
Simply do a:
make -f Makefile.p4b
insmod p4b_smbus.o
modprobe i2c-core
modprobe i2c-i801
modprobe i2c-dev
modprobe i2c-proc
Then run your sensor:
modprobe w83781d
What should i never do?
-----------------------
Do not try to do a "rmmod p4b_smbus" before a "rmmod i2c-i801".
The other way around should be okay. Otherwise you remove the PCI device
without notifying the i2c driver.
-------------------------------
Ilja Rauhut <IljaRauhut@web.de>
-391
View File
@@ -1,391 +0,0 @@
/*
* m7101.c
*
* Initialize the M7101 device on ALi M15x3 Chipsets
*/
/*
Copyright (c) 2000 Burkhard Kohl <buk@buks.ipn.de>,
Frank Bauer <frank.bauer@nikocity.de>, and
Mark D. Studebaker <mdsxyz123@yahoo.com>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* CHANGES:
* 030799 FB: created this file
* frank.bauer@nikocity.de
*
* 110799 BK: messed it up to insert the M7101 dev after boot
* buk@buks.ipn.de
*
* 160799 BK: grouped portions of the code into functions
*
* June 21, 2000 MDS: Add Copyright and GPL comments,
* distribute as release 0.1.
*
* Sept 21, 2000 MDS: Rewrite to use kernel hotplug facility,
* (similar to drivers/pcmcia/cardbus.c),
* fix makefile so it will compile,
* distribute as release 0.2.
*
* This code is absolutely experimental - use it at your own
* risk.
*
* Warning, this module will work only with 2.4.x kernels.
* If it works with earlier kernels then it is by luck.
*
* Warning, this module does not work with egcs < 2.95.2, use
* gcc > 2.7.2 or egcs >= 2.95.2.
*
*/
#ifdef M7101_DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE !TRUE
#endif
#include <linux/config.h>
#ifndef CONFIG_HOTPLUG
#error ERROR - You must have 'Support for hot-pluggable devices' enabled in your kernel (under 'general setup')!!
#endif
/* Deal with CONFIG_MODVERSIONS */
#ifdef CONFIG_MODVERSIONS
#define MODVERSIONS
#include <linux/modversions.h>
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/stddef.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <asm/types.h>
/*
from lm_sensors-2.3.3:
*/
#define SMBHSTCFG 0x0E0
/* PCI Address Constants */
#define SMBATPC 0x05B /* used to unlock xxxBA registers */
/* ALI15X3 address lock bits */
#define ALI15X3_LOCK 0x06
/*
addresses the i/o space gets mapped to,
for M1543C, Bits 16-31 are supposed to be zero
*/
#define ACPI_IO_SIZE 0x40
#define SMB_IO_SIZE 0x20
#define ACPI_BASE 0x0
#define SMB_BASE 0x1
static u32 acpi_io = 0xEC00; /* Set I/O Base defaults here */
static u32 smb_io = 0xE800;
MODULE_PARM(acpi_io, "l");
MODULE_PARM(smb_io, "l");
#ifdef M7101_DEBUG
static int debug = 0;
MODULE_PARM(debug, "i");
#endif
/* status, used to indicate that io space needs to be freed */
static struct pci_dev *m7101 = NULL;
static int m7101_inserted = FALSE;
extern void cleanup_module();
static rwlock_t m7101_lock = RW_LOCK_UNLOCKED;
static unsigned long m7101_lock_flags = 0;
#ifdef M7101_DEBUG
static void
dump_dev_data(struct pci_dev *dev, int address_data)
{
if (dev != NULL) {
printk("m7101: devfn: 0x%4x class: 0x%4x\n",
dev->devfn, dev->class);
printk("m7101: vendor: 0x%4x device: 0x%4x\n",
dev->vendor, dev->device);
if (address_data) {
printk("m7101: resource[0]: 0x%08lx resource[1]: 0x%08lx\n",
dev->resource[0].start, dev->resource[1].start);
printk("m7101: resource[2]: 0x%08lx resource[3]: 0x%08lx\n",
dev->resource[2].start, dev->resource[3].start);
printk("m7101: resource[4]: 0x%08lx resource[5]: 0x%08lx\n",
dev->resource[4].start, dev->resource[5].start);
printk("m7101: rom_address: 0x%08lx\n",
dev->resource[PCI_ROM_RESOURCE].start);
}
}
}
#endif
/*
* Checks whether PMU and SMB are enabled and turns them on in case they are not.
* It's done by clearing Bit 2 in M1533 config space 5Fh.
* I/O
*/
static int
m7101_enable(struct pci_dev *dev){
u8 val = 0;
pci_read_config_byte(dev, 0x5F, &val);
DBG("m7101: M7101 config byte reading 0x%X.\n", val);
if (val & 0x4) {
pci_write_config_byte(dev, 0x5F, val & 0xFB);
pci_read_config_byte(dev, 0x5F, &val);
if(val & 0x4) {
DBG("m7101: Can't enable PMU/SMB, config byte locked:-(\n");
return -EIO;
}
}
return 0;
}
/*
* Builds the basic pci_dev for the M7101
*/
static int
m7101_build(struct pci_dev **m7101, struct pci_bus *bus)
{
u32 devfn;
u16 id = 0;
u16 vid = 0;
int ret;
DBG("m7101: requesting kernel space for the m7101 entry.\n");
*m7101 = kmalloc(sizeof(**m7101), GFP_ATOMIC);
if(NULL == *m7101) {
printk("m7101: out of memory.\n");
return -ENOMEM;
}
/* minimally fill in structure for search */
/* The device should be on the same bus as the M1533. */
memset(*m7101, 0, sizeof(**m7101));
(*m7101)->bus = bus;
(*m7101)->sysdata = bus->sysdata;
(*m7101)->hdr_type = PCI_HEADER_TYPE_NORMAL;
DBG("m7101: now looking for M7101.\n");
for (id = 0, devfn = 0; devfn < 0xFF; devfn++) {
(*m7101)->devfn = devfn;
ret = pci_read_config_word(*m7101, PCI_DEVICE_ID, &id);
if (ret == 0 && PCI_DEVICE_ID_AL_M7101 == id) {
pci_read_config_word(*m7101, PCI_VENDOR_ID, &vid);
if(vid == PCI_VENDOR_ID_AL)
break;
}
}
if (PCI_DEVICE_ID_AL_M7101 != id) {
DBG("m7101: M7101 not found although M1533 present - strange.\n");
return -EACCES;
} else {
DBG("m7101: M7101 found and enabled. Devfn: 0x%X.\n", devfn);
}
/* We now have the devfn and bus of the M7101 device.
* let's put the rest of the device data together.
*/
(*m7101)->vendor = PCI_VENDOR_ID_AL;
(*m7101)->hdr_type = PCI_HEADER_TYPE_NORMAL;
(*m7101)->device = PCI_DEVICE_ID_AL_M7101;
return(pci_setup_device(*m7101));
}
/*
* unlock the address registers if necessary
*/
static int
m7101_unlock_registers(struct pci_dev *m7101)
{
u8 val = 0;
if (pci_read_config_byte(m7101, SMBATPC, &val)) {
DBG("m7101: failed to read SMBATPC\n");
return -EIO;
} else {
if(val & ALI15X3_LOCK) {
DBG("m7101: need to unlock the address registers\n");
val &= ~ALI15X3_LOCK;
if (pci_write_config_byte(m7101, SMBATPC, val)) {
DBG("m7101: failed to write SMBATPC\n");
return -EIO;
}
}
}
return 0;
}
static int
m7101_set_io_address(struct pci_dev *m7101, u32 addr, int base_idx, int size)
{
if (!addr) {
printk("m7101: Sorry - cannot assign address 0 to region.\n");
return -EINVAL;
}
if (check_region(addr, size)) {
printk("m7101: Requested IO-region 0x%x already in use.\n", addr);
return -EBUSY;
} else {
m7101->resource[base_idx].start = addr;
}
return 0;
}
/* Initialize the module */
int init_module(void)
{
struct pci_bus *bus = NULL;
struct pci_dev *dev = NULL;
u32 acpi_addr = 0, smb_addr = 0;
int ret = 0;
DBG("m7101: init_module().\n");
/* Are we on a PCI-Board? */
if (!pci_present()) {
printk("m7101: No PCI bus found - sorry.\n");
return -ENODEV;
}
/* We want to be sure that the M7101 is not present yet. */
dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M7101, NULL);
if (dev) {
printk("m7101: M7101 already present, no need to run this module.\n");
#ifdef M7101_DEBUG
if(debug)
{
printk("m7101: removing device for testing\n");
pci_remove_device(dev);
m7101_inserted = 0;
return 0;
}
else
#endif
return -EPERM;
}
/* Are we operating a M15x3 chipset */
dev = pci_find_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
if (NULL == dev) {
printk("m7101: ALi M15xx chipset not found.\n");
return -ENODEV ;
}
/* we need the bus pointer later */
bus = dev->bus;
if ( (ret = m7101_enable(dev)) ) {
printk("m7101: Unable to turn on M7101 device - sorry!\n");
return ret;
}
if ( (ret = m7101_build(&m7101, bus)) ){
return ret;
}
/* thus, now we have a rudimentary dev for M7101 ... */
/* check wether register need to be unlocked. */
if ( (ret = m7101_unlock_registers(m7101)) ){
return ret;
}
/*
* Handle address assignment for ACPI_IO
* If address is already assigned do nothing.
*/
acpi_addr = m7101->resource[ACPI_BASE].start;
if (!acpi_addr) {
acpi_io |= PCI_BASE_ADDRESS_SPACE_IO;
ret = m7101_set_io_address(m7101, acpi_io,ACPI_BASE, ACPI_IO_SIZE);
if (ret)
return ret;
acpi_addr = acpi_io;
}
/*
* Handle address assignment for SMB_IO
* If address is already assigned then do nothing.
*/
smb_addr = m7101->resource[SMB_BASE].start;
if (!smb_addr) {
smb_io |= PCI_BASE_ADDRESS_SPACE_IO;
ret = m7101_set_io_address(m7101, smb_io, SMB_BASE, SMB_IO_SIZE);
if (ret)
return ret;
smb_addr = smb_io;
}
#ifdef M7101_DEBUG
dump_dev_data(m7101, 1);
#endif
if ( (ret = pci_enable_device(m7101)) ) {
printk("m7101: Unable to pci_enable M7101 device!\n");
return ret;
}
DBG("m7101: now inserting.\n");
pci_insert_device(m7101, m7101->bus);
printk("m7101: Enabled with ACPI I/O address 0x%04X and SMB I/O address 0x%04X\n",
acpi_addr, smb_addr);
m7101_inserted = TRUE;
return 0;
}
void cleanup_module()
{
write_lock_irqsave(m7101_lock, m7101_lock_flags);
if (m7101_inserted) {
pci_remove_device(m7101);
m7101_inserted = FALSE;
}
write_unlock_irqrestore(m7101_lock, m7101_lock_flags);
if (NULL != m7101)
kfree(m7101);
printk("m7101: bye bye\n");
}
EXPORT_NO_SYMBOLS;
#ifdef MODULE
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif
MODULE_AUTHOR("Burkhard Kohl <bku@buks.ipn.de>, "
"Frank Bauer <frank.bauer@nikocity.de>, "
"and Mark Studebaker <mdsxyz123@yahoo.com>");
MODULE_DESCRIPTION("M7101 PCI Inserter");
#endif /* MODULE */
-340
View File
@@ -1,340 +0,0 @@
/*
* p4b_smbus.c
*
* Initialize the SMBus device on ICH2/2-M/4/4-M/5 (82801BA/BAM/DB/DBM/EB)
*/
/*
Copyright (c) 2002 Ilja Rauhut <IljaRauhut@web.de> and
Klaus Woltereck <kw42@gmx.net>,
Based on the m7101.c hotplug example by:
Copyright (c) 2000 Burkhard Kohl <buk@buks.ipn.de>,
Frank Bauer <frank.bauer@nikocity.de>, and
Mark D. Studebaker <mdsxyz123@yahoo.com>
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., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
/* CHANGES:
* February 13,2002 IR First Version
*
* This code is absolutely experimental - use it at your own
* risk.
*
* Warning, this module will work only with 2.4.x kernels.
* If it works with earlier kernels then it is by luck.
*
* Warning, this module does not work with egcs < 2.95.2, use
* gcc > 2.7.2 or egcs >= 2.95.2.
*
*
* June 21, 2002, added support for the ICH4, code clean up -- Klaus
*
* Apr 13, 2004, modified for ICH4-M (82801DBM) -- Axel Thimm <Axel.Thimm@ATrpms.net>
* bugfix: register F2/bit 8 on ICH2* is bit 0 on ICH4*
*
* Jan 6, 2007, added support for the ICH5 -- Jean Delvare
*/
#ifdef P4Bsmbus_DEBUG
#define DBG(x...) printk(x)
#else
#define DBG(x...)
#endif
#ifndef TRUE
#define TRUE 1
#define FALSE !TRUE
#endif
#include <linux/config.h>
#ifndef CONFIG_HOTPLUG
#error ERROR - You must have 'Support for hot-pluggable devices' enabled in your kernel (under 'general setup')!!
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/stddef.h>
#include <linux/ioport.h>
#include <linux/errno.h>
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <asm/types.h>
#include <linux/sched.h>
#include <linux/signal.h>
#include <asm/irq.h>
/*
rmm from lm_sensors-2.3.3:
*/
#define SMB_IO_SIZE 0xF
#define SMB_BASE 0x20
/*
* some shorter definitions for the ICHx PCI device IDs
*/
#define ICH2 0x2440
#define ICH2_M 0x244c
#define ICH2_SMBUS 0x2443
#define ICH4 0x24c0
#define ICH4_M 0x24cc
#define ICH4_SMBUS 0x24c3
#define ICH5 0x24d0
#define ICH5_SMBUS 0x24d3
#define is_supported_smbus(id) \
((id) == ICH2_SMBUS || \
(id) == ICH4_SMBUS || \
(id) == ICH5_SMBUS)
/* status, used to indicate that io space needs to be freed */
static struct pci_dev *i801smbus = NULL;
static int i801smbus_inserted = FALSE;
extern void cleanup_module(void);
static rwlock_t i801smbus_lock = RW_LOCK_UNLOCKED;
static unsigned long i801smbus_lock_flags = 0;
/*
* Checks whether SMBus is enabled and turns it on in case they are not.
* It's done by modifying the i801 function disable register, F2h.
* ICH2(-M): PCI-Device 0x8086:0x2440(0x244c)
* Bit 3: Disables SMBus Host Controller function.
* Bit 8: allows SMBus I/O space to be accessible when Bit 3 is set.
* ICH4(-M): PCI-Device 0x8086:0x24c0(0x24cc)
* Bit 3: Disables SMBus Host Controller function.
* Bit 0: allows SMBus I/O space to be accessible when Bit 3 is set.
* ICH5: PCI-Device 0x8086:0x24d0
* Same as ICH4.
*/
static int
i801smbus_enable(struct pci_dev *dev, u16 testmask, u16 mask){
u16 val = 0;
pci_read_config_word(dev, 0xF2, &val);
DBG("i801smbus: i801smbus config byte reading 0x%X.\n", val);
if (val & testmask) {
pci_write_config_word(dev, 0xF2, val & mask);
pci_read_config_word(dev, 0xF2, &val);
if(val & testmask)
{
DBG("i801smbus: i801smbus config byte locked:-(\n");
return -EIO;
}
else
printk("i801smbus: SMBus activated in LPC!\n");
}
return 0;
}
/*
* Builds the basic pci_dev for the i801smbus
*/
static int i801smbus_build(struct pci_dev **i801smbus, struct pci_bus *bus)
{
u32 devfn;
u16 id = 0;
u16 vid = 0;
int ret;
DBG("i801smbus: requesting kernel space for the i801smbus entry.\n");
*i801smbus = kmalloc(sizeof(**i801smbus), GFP_ATOMIC);
if(NULL == *i801smbus) {
printk("i801smbus: out of memory.\n");
return -ENOMEM;
}
/* minimally fill in structure for search */
/* The device should be on the same bus as the i801. */
memset(*i801smbus, 0, sizeof(**i801smbus));
(*i801smbus)->bus = bus;
(*i801smbus)->sysdata = bus->sysdata;
(*i801smbus)->hdr_type = PCI_HEADER_TYPE_NORMAL;
DBG("i801smbus: now looking for i801smbus.\n");
for (id = 0, devfn = 0; devfn < 0xFF; devfn++) {
(*i801smbus)->devfn = devfn;
ret = pci_read_config_word(*i801smbus, PCI_DEVICE_ID, &id);
if (ret == 0 && is_supported_smbus(id)) {
pci_read_config_word(*i801smbus, PCI_VENDOR_ID, &vid);
if(vid == 0x8086)
break;
}
}
if (!is_supported_smbus(id)) {
DBG("i801smbus: i801smbus not found although i801 present - strange.\n");
return -EACCES;
} else {
DBG("i801smbus: i801smbus found and enabled. Devfn: 0x%X.\n", devfn);
}
/* We now have the devfn and bus of the i801smbus device.
* let's put the rest of the device data together.
*/
(*i801smbus)->vendor = 0x8086;
(*i801smbus)->hdr_type = PCI_HEADER_TYPE_NORMAL;
(*i801smbus)->device = id;
return(pci_setup_device(*i801smbus));
}
/* Initialize the module */
int init_module(void)
{
struct pci_bus *bus = NULL;
struct pci_dev *dev = NULL;
int ret = 0;
u16 testmask = 0, mask = 0;
DBG("i801smbus: init_module().\n");
/* Are we on a PCI-Board? */
if (!pci_present()) {
printk("i801smbus: No PCI bus found - sorry.\n");
return -ENODEV;
}
/* We want to be sure that the i801smbus is not present yet. */
dev = pci_find_device(0x8086, ICH2_SMBUS, NULL);
if (dev)
{
printk("i801smbus: SMBus already active\n");
return -EPERM;
}
dev = pci_find_device(0x8086, ICH4_SMBUS, NULL);
if (dev)
{
printk("i801smbus: SMBus already active\n");
return -EPERM;
}
dev = pci_find_device(0x8086, ICH5_SMBUS, NULL);
if (dev)
{
printk("i801smbus: SMBus already active\n");
return -EPERM;
}
/* Are we operating a i801 chipset */
if ((dev = pci_find_device(0x8086, ICH2, NULL)) != 0)
{
printk("i801smbus: found Intel ICH2 (82801BA).\n");
testmask = 0x008;
mask = 0xfef7;
}
else if ((dev = pci_find_device(0x8086, ICH2_M, NULL)) != 0)
{
printk("i801smbus: found Intel ICH2-M (82801BAM).\n");
testmask = 0x008;
mask = 0xfef7;
}
else if ((dev = pci_find_device(0x8086, ICH4, NULL)) != 0)
{
printk("i801smbus: found Intel ICH4 (82801DB).\n");
testmask = 0x008;
mask = 0xfff6;
}
else if ((dev = pci_find_device(0x8086, ICH4_M, NULL)) != 0)
{
printk("i801smbus: found Intel ICH4-M (82801DBM).\n");
testmask = 0x008;
mask = 0xfff6;
}
else if ((dev = pci_find_device(0x8086, ICH5, NULL)) != 0)
{
printk(KERN_INFO "i801smbus: Found Intel ICH5 (82801EB)\n");
testmask = 0x008;
mask = 0xfff6;
}
else
{
printk(KERN_NOTICE "i801smbus: No supported Intel ICH (82801) "
"chip found\n");
return -ENODEV ;
}
/* we need the bus pointer later */
bus = dev->bus;
if ( (ret = i801smbus_enable(dev, testmask, mask)) )
{
printk("i801smbus: Unable to turn on i801smbus device - sorry!\n");
return ret;
}
if ( (ret = i801smbus_build(&i801smbus, bus)) )
return ret;
if ( (ret = pci_enable_device(i801smbus)) ) {
printk("i801smbus: Unable to pci_enable i801smbus device!\n");
return ret;
}
DBG("i801smbus: now inserting.\n");
pci_insert_device(i801smbus, i801smbus->bus);
printk("i801smbus: Enabled\n");
i801smbus_inserted = TRUE;
return 0;
}
void cleanup_module(void)
{
write_lock_irqsave(&i801smbus_lock, i801smbus_lock_flags);
if (i801smbus_inserted) {
pci_remove_device(i801smbus);
i801smbus_inserted = FALSE;
}
write_unlock_irqrestore(&i801smbus_lock, i801smbus_lock_flags);
if (NULL != i801smbus)
{
kfree(i801smbus);
}
printk("i801smbus: SMBus device removed\n");
}
EXPORT_NO_SYMBOLS;
#ifdef MODULE
#ifdef MODULE_LICENSE
MODULE_LICENSE("GPL");
#endif
MODULE_AUTHOR("Ilja Rauhut <IljaRauhut@web.de>, "
"Burkhard Kohl <bku@buks.ipn.de>, "
"Frank Bauer <frank.bauer@nikocity.de>, "
"Mark Studebaker <mdsxyz123@yahoo.com>,"
"and Klaus Woltereck <kw42@gmx.net>");
MODULE_DESCRIPTION("i801smbus PCI Inserter");
#endif /* MODULE */