Commit 1d4123ec authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://linuxusb.bkbits.net/pci_hp-2.5

into penguin.transmeta.com:/home/penguin/torvalds/repositories/kernel/linux
parents 4a554b57 7694db54
...@@ -40,3 +40,14 @@ CONFIG_HOTPLUG_PCI_IBM ...@@ -40,3 +40,14 @@ CONFIG_HOTPLUG_PCI_IBM
When in doubt, say N. When in doubt, say N.
CONFIG_HOTPLUG_PCI_ACPI
Say Y here if you have a system that supports PCI Hotplug using
ACPI.
This code is also available as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
The module will be called acpiphp.o. If you want to compile it
as a module, say M here and read <file:Documentation/modules.txt>.
When in doubt, say N.
...@@ -11,5 +11,6 @@ dep_mbool ' Save configuration into NVRAM on Compaq servers' CONFIG_HOTPLUG_P ...@@ -11,5 +11,6 @@ dep_mbool ' Save configuration into NVRAM on Compaq servers' CONFIG_HOTPLUG_P
if [ "$CONFIG_X86_IO_APIC" = "y" ]; then if [ "$CONFIG_X86_IO_APIC" = "y" ]; then
dep_tristate ' IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86 dep_tristate ' IBM PCI Hotplug driver' CONFIG_HOTPLUG_PCI_IBM $CONFIG_HOTPLUG_PCI $CONFIG_X86_IO_APIC $CONFIG_X86
fi fi
dep_tristate ' ACPI PCI Hotplug driver' CONFIG_HOTPLUG_PCI_ACPI $CONFIG_APCI $CONFIG_HOTPLUG_PCI
endmenu endmenu
...@@ -7,6 +7,7 @@ export-objs := pci_hotplug_core.o pci_hotplug_util.o ...@@ -7,6 +7,7 @@ export-objs := pci_hotplug_core.o pci_hotplug_util.o
obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o obj-$(CONFIG_HOTPLUG_PCI) += pci_hotplug.o
obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o obj-$(CONFIG_HOTPLUG_PCI_COMPAQ) += cpqphp.o
obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o obj-$(CONFIG_HOTPLUG_PCI_IBM) += ibmphp.o
obj-$(CONFIG_HOTPLUG_PCI_ACPI) += acpiphp.o
pci_hotplug-objs := pci_hotplug_core.o \ pci_hotplug-objs := pci_hotplug_core.o \
pci_hotplug_util.o pci_hotplug_util.o
...@@ -22,6 +23,18 @@ ibmphp-objs := ibmphp_core.o \ ...@@ -22,6 +23,18 @@ ibmphp-objs := ibmphp_core.o \
ibmphp_res.o \ ibmphp_res.o \
ibmphp_hpc.o ibmphp_hpc.o
acpiphp-objs := acpiphp_core.o \
acpiphp_glue.o \
acpiphp_pci.o \
acpiphp_res.o
ifdef CONFIG_HOTPLUG_PCI_ACPI
EXTRA_CFLAGS += -D_LINUX -I$(TOPDIR)/drivers/acpi
ifdef CONFIG_ACPI_DEBUG
EXTRA_CFLAGS += -DACPI_DEBUG_OUTPUT
endif
endif
ifeq ($(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM),y) ifeq ($(CONFIG_HOTPLUG_PCI_COMPAQ_NVRAM),y)
cpqphp-objs += cpqphp_nvram.o cpqphp-objs += cpqphp_nvram.o
endif endif
......
/*
* ACPI PCI Hot Plug Controller Driver
*
* Copyright (c) 1995,2001 Compaq Computer Corporation
* Copyright (c) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (c) 2001 IBM Corp.
* Copyright (c) 2002 Hiroshi Aono (h-aono@ap.jp.nec.com)
* Copyright (c) 2002 Takayoshi Kochi (t-kouchi@cq.jp.nec.com)
* Copyright (c) 2002 NEC Corporation
*
* All rights reserved.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. 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.
*
* Send feedback to <gregkh@us.ibm.com>,
* <h-aono@ap.jp.nec.com>,
* <t-kouchi@cq.jp.nec.com>
*
*/
#ifndef _ACPIPHP_H
#define _ACPIPHP_H
#include "include/acpi.h"
#include "pci_hotplug.h"
#include "acpi_bus.h"
#define dbg(format, arg...) \
do { \
if (acpiphp_debug) \
printk (KERN_DEBUG "%s: " format "\n", \
MY_NAME , ## arg); \
} while (0)
#define err(format, arg...) printk (KERN_ERR "%s: " format "\n", MY_NAME , ## arg)
#define info(format, arg...) printk (KERN_INFO "%s: " format "\n", MY_NAME , ## arg)
#define warn(format, arg...) printk (KERN_WARNING "%s: " format "\n", MY_NAME , ## arg)
#define SLOT_MAGIC 0x67267322
/* name size which is used for entries in pcihpfs */
#define SLOT_NAME_SIZE 32 /* ACPI{_SUN}-{BUS}:{DEV} */
struct acpiphp_bridge;
struct acpiphp_slot;
struct pci_resource;
/*
* struct slot - slot information for each *physical* slot
*/
struct slot {
u32 magic;
u8 number;
struct hotplug_slot *hotplug_slot;
struct list_head slot_list;
struct acpiphp_slot *acpi_slot;
};
/*
* struct pci_resource - describes pci resource (mem, pfmem, io, bus)
*/
struct pci_resource {
struct pci_resource * next;
u64 base;
u32 length;
};
/**
* struct hpp_param - ACPI 2.0 _HPP Hot Plug Parameters
* @cache_line_size in DWORD
* @latency_timer in PCI clock
* @enable_SERR 0 or 1
* @enable_PERR 0 or 1
*/
struct hpp_param {
u8 cache_line_size;
u8 latency_timer;
u8 enable_SERR;
u8 enable_PERR;
};
/**
* struct acpiphp_bridge - PCI bridge information
*
* for each bridge device in ACPI namespace
*/
struct acpiphp_bridge {
struct list_head list;
acpi_handle handle;
struct acpiphp_slot *slots;
int type;
int nr_slots;
u8 seg;
u8 bus;
u8 sub;
u32 flags;
/* This bus (host bridge) or Secondary bus (PCI-to-PCI bridge) */
struct pci_bus *pci_bus;
/* PCI-to-PCI bridge device */
struct pci_dev *pci_dev;
/* ACPI 2.0 _HPP parameters */
struct hpp_param hpp;
spinlock_t res_lock;
/* available resources on this bus */
struct pci_resource *mem_head;
struct pci_resource *p_mem_head;
struct pci_resource *io_head;
struct pci_resource *bus_head;
};
/**
* struct acpiphp_slot - PCI slot information
*
* PCI slot information for each *physical* PCI slot
*/
struct acpiphp_slot {
struct acpiphp_slot *next;
struct acpiphp_bridge *bridge; /* parent */
struct list_head funcs; /* one slot may have different
objects (i.e. for each function) */
struct semaphore crit_sect;
u32 id; /* slot id (serial #) for hotplug core */
u8 device; /* pci device# */
u32 sun; /* ACPI _SUN (slot unique number) */
u32 slotno; /* slot number relative to bridge */
u32 flags; /* see below */
};
/**
* struct acpiphp_func - PCI function information
*
* PCI function information for each object in ACPI namespace
* typically 8 objects per slot (i.e. for each PCI function)
*/
struct acpiphp_func {
struct acpiphp_slot *slot; /* parent */
struct list_head sibling;
struct pci_dev *pci_dev;
acpi_handle handle;
u8 function; /* pci function# */
u32 flags; /* see below */
/* resources used for this function */
struct pci_resource *mem_head;
struct pci_resource *p_mem_head;
struct pci_resource *io_head;
struct pci_resource *bus_head;
};
/* PCI bus bridge HID */
#define ACPI_PCI_HOST_HID "PNP0A03"
/* PCI BRIDGE type */
#define BRIDGE_TYPE_HOST 0
#define BRIDGE_TYPE_P2P 1
/* ACPI _STA method value (ignore bit 4; battery present) */
#define ACPI_STA_PRESENT (0x00000001)
#define ACPI_STA_ENABLED (0x00000002)
#define ACPI_STA_SHOW_IN_UI (0x00000004)
#define ACPI_STA_FUNCTIONING (0x00000008)
#define ACPI_STA_ALL (0x0000000f)
/* bridge flags */
#define BRIDGE_HAS_STA (0x00000001)
#define BRIDGE_HAS_EJ0 (0x00000002)
#define BRIDGE_HAS_HPP (0x00000004)
#define BRIDGE_HAS_PS0 (0x00000010)
#define BRIDGE_HAS_PS1 (0x00000020)
#define BRIDGE_HAS_PS2 (0x00000040)
#define BRIDGE_HAS_PS3 (0x00000080)
/* slot flags */
#define SLOT_POWEREDON (0x00000001)
#define SLOT_ENABLED (0x00000002)
#define SLOT_MULTIFUNCTION (x000000004)
/* function flags */
#define FUNC_HAS_STA (0x00000001)
#define FUNC_HAS_EJ0 (0x00000002)
#define FUNC_HAS_PS0 (0x00000010)
#define FUNC_HAS_PS1 (0x00000020)
#define FUNC_HAS_PS2 (0x00000040)
#define FUNC_HAS_PS3 (0x00000080)
/* not yet */
#define SLOT_SUPPORT_66MHZ (0x00010000)
#define SLOT_SUPPORT_100MHZ (0x00020000)
#define SLOT_SUPPORT_133MHZ (0x00040000)
#define SLOT_SUPPORT_PCIX (0x00080000)
/* function prototypes */
/* acpiphp_glue.c */
extern int acpiphp_glue_init (void);
extern void acpiphp_glue_exit (void);
extern int acpiphp_get_num_slots (void);
extern struct acpiphp_slot *get_slot_from_id (int id);
typedef int (*acpiphp_callback)(struct acpiphp_slot *slot, void *data);
extern int acpiphp_for_each_slot (acpiphp_callback fn, void *data);
extern int acpiphp_check_bridge (struct acpiphp_bridge *bridge);
extern int acpiphp_enable_slot (struct acpiphp_slot *slot);
extern int acpiphp_disable_slot (struct acpiphp_slot *slot);
extern u8 acpiphp_get_power_status (struct acpiphp_slot *slot);
extern u8 acpiphp_get_attention_status (struct acpiphp_slot *slot);
extern u8 acpiphp_get_latch_status (struct acpiphp_slot *slot);
extern u8 acpiphp_get_adapter_status (struct acpiphp_slot *slot);
/* acpiphp_pci.c */
extern struct pci_dev *acpiphp_allocate_pcidev (struct pci_bus *pbus, int dev, int fn);
extern int acpiphp_configure_slot (struct acpiphp_slot *slot);
extern int acpiphp_configure_function (struct acpiphp_func *func);
extern int acpiphp_unconfigure_function (struct acpiphp_func *func);
extern int acpiphp_detect_pci_resource (struct acpiphp_bridge *bridge);
extern int acpiphp_init_func_resource (struct acpiphp_func *func);
/* acpiphp_res.c */
extern struct pci_resource *acpiphp_get_io_resource (struct pci_resource **head, u32 size);
extern struct pci_resource *acpiphp_get_max_resource (struct pci_resource **head, u32 size);
extern struct pci_resource *acpiphp_get_resource (struct pci_resource **head, u32 size);
extern struct pci_resource *acpiphp_get_resource_with_base (struct pci_resource **head, u64 base, u32 size);
extern int acpiphp_resource_sort_and_combine (struct pci_resource **head);
extern struct pci_resource *acpiphp_make_resource (u64 base, u32 length);
extern void acpiphp_move_resource (struct pci_resource **from, struct pci_resource **to);
extern void acpiphp_free_resource (struct pci_resource **res);
extern void acpiphp_dump_resource (struct acpiphp_bridge *bridge); /* debug */
extern void acpiphp_dump_func_resource (struct acpiphp_func *func); /* debug */
/* variables */
extern int acpiphp_debug;
#endif /* _ACPIPHP_H */
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -1110,6 +1110,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1110,6 +1110,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* /*
* Get IO, memory, and IRQ resources for new devices * Get IO, memory, and IRQ resources for new devices
*/ */
// The next line is required for cpqhp_find_available_resources
ctrl->interrupt = pdev->irq;
rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start); rc = cpqhp_find_available_resources(ctrl, cpqhp_rom_start);
ctrl->add_support = !rc; ctrl->add_support = !rc;
if (rc) { if (rc) {
...@@ -1138,7 +1141,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -1138,7 +1141,6 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK); writel(0xFFFFFFFFL, ctrl->hpc_reg + INT_MASK);
/* set up the interrupt */ /* set up the interrupt */
ctrl->interrupt = pdev->irq;
dbg("HPC interrupt = %d \n", ctrl->interrupt); dbg("HPC interrupt = %d \n", ctrl->interrupt);
if (request_irq(ctrl->interrupt, if (request_irq(ctrl->interrupt,
(void (*)(int, void *, struct pt_regs *)) &cpqhp_ctrl_intr, (void (*)(int, void *, struct pt_regs *)) &cpqhp_ctrl_intr,
......
...@@ -360,8 +360,8 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num) ...@@ -360,8 +360,8 @@ int cpqhp_set_irq (u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num)
__FUNCTION__, dev_num, bus_num, int_pin, irq_num); __FUNCTION__, dev_num, bus_num, int_pin, irq_num);
rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num); rc = pcibios_set_irq_routing(&fakedev, int_pin - 0x0a, irq_num);
dbg("%s: rc %d\n", __FUNCTION__, rc); dbg("%s: rc %d\n", __FUNCTION__, rc);
if (rc) if (!rc)
return rc; return !rc;
// set the Edge Level Control Register (ELCR) // set the Edge Level Control Register (ELCR)
temp_word = inb(0x4d0); temp_word = inb(0x4d0);
......
...@@ -686,9 +686,10 @@ static int validate (struct slot *slot_cur, int opn) ...@@ -686,9 +686,10 @@ static int validate (struct slot *slot_cur, int opn)
int ibmphp_update_slot_info (struct slot *slot_cur) int ibmphp_update_slot_info (struct slot *slot_cur)
{ {
struct hotplug_slot_info *info; struct hotplug_slot_info *info;
char buffer[10]; char buffer[30];
int rc; int rc;
// u8 bus_speed; u8 bus_speed;
u8 mode;
info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL); info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
if (!info) { if (!info) {
...@@ -696,7 +697,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -696,7 +697,7 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
return -ENOMEM; return -ENOMEM;
} }
snprintf (buffer, 10, "%d", slot_cur->number); strncpy (buffer, slot_cur->hotplug_slot->name, 30);
info->power_status = SLOT_PWRGD (slot_cur->status); info->power_status = SLOT_PWRGD (slot_cur->status);
info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status); info->attention_status = SLOT_ATTN (slot_cur->status, slot_cur->ext_status);
info->latch_status = SLOT_LATCH (slot_cur->status); info->latch_status = SLOT_LATCH (slot_cur->status);
...@@ -707,21 +708,33 @@ int ibmphp_update_slot_info (struct slot *slot_cur) ...@@ -707,21 +708,33 @@ int ibmphp_update_slot_info (struct slot *slot_cur)
info->adapter_status = 1; info->adapter_status = 1;
// get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0); // get_max_adapter_speed_1 (slot_cur->hotplug_slot, &info->max_adapter_speed_status, 0);
} }
/* !!!!!!!!!TO DO: THIS NEEDS TO CHANGE!!!!!!!!!!!!! */
/* bus_speed = slot_cur->bus_on->current_speed;
bus_speed &= 0x0f;
if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCIX)
bus_speed |= 0x80;
else if (slot_cur->bus_on->current_bus_mode == BUS_MODE_PCI)
bus_speed |= 0x40;
else
bus_speed |= 0x20;
info->cur_bus_speed_status = bus_speed; bus_speed = slot_cur->bus_on->current_speed;
info->max_bus_speed_status = slot_cur->hotplug_slot->info->max_bus_speed_status; mode = slot_cur->bus_on->current_bus_mode;
switch (bus_speed) {
case BUS_SPEED_33:
break;
case BUS_SPEED_66:
if (mode == BUS_MODE_PCIX)
bus_speed += 0x01;
else if (mode == BUS_MODE_PCI)
;
else
bus_speed = PCI_SPEED_UNKNOWN;
break;
case BUS_SPEED_100:
case BUS_SPEED_133:
bus_speed += 0x01;
break;
default:
bus_speed = PCI_SPEED_UNKNOWN;
}
info->cur_bus_speed = bus_speed;
info->max_bus_speed = slot_cur->hotplug_slot->info->max_bus_speed;
// To do: bus_names // To do: bus_names
*/
rc = pci_hp_change_slot_info (buffer, info); rc = pci_hp_change_slot_info (buffer, info);
kfree (info); kfree (info);
return rc; return rc;
...@@ -989,7 +1002,7 @@ static u8 bus_structure_fixup (u8 busno) ...@@ -989,7 +1002,7 @@ static u8 bus_structure_fixup (u8 busno)
struct pci_dev *dev; struct pci_dev *dev;
u16 l; u16 l;
if (!find_bus (busno) || !(ibmphp_find_same_bus_num (busno))) if (find_bus (busno) || !(ibmphp_find_same_bus_num (busno)))
return 1; return 1;
bus = kmalloc (sizeof (*bus), GFP_KERNEL); bus = kmalloc (sizeof (*bus), GFP_KERNEL);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment