Commit de9b2fcc authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/pci-2.6: (22 commits)
  acpiphp: Link-time error for PCI Hotplug
  shpchp: cleanup shpchp.h
  shpchp: remove shpchprm_get_physical_slot_number
  shpchp: cleanup struct controller
  shpchp: remove unnecessary struct php_ctlr
  PCI: ATI sb600 sata quirk
  PCI legacy resource fix
  PCI: don't export device IDs to userspace
  PCI: Be a bit defensive in quirk_nvidia_ck804() so we don't risk dereferencing a NULL pdev.
  PCI: Fix multiple problems with VIA hardware
  PCI: Only check the HT capability bits in mpic.c
  PCI: Use pci_find_ht_capability() in drivers/pci/quirks.c
  PCI: Add #defines for Hypertransport MSI fields
  PCI: Use pci_find_ht_capability() in drivers/pci/htirq.c
  PCI: Add pci_find_ht_capability() for finding Hypertransport capabilities
  PCI: Create __pci_bus_find_cap_start() from __pci_bus_find_cap()
  pci: Introduce pci_find_present
  PCI: pcieport-driver: remove invalid warning message
  rpaphp: compiler warning cleanup
  PCI quirks: remove redundant check
  ...
parents fb34d203 031f30d2
......@@ -115,7 +115,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, pci
#define VIA_8363_KL133_REVISION_ID 0x81
#define VIA_8363_KM133_REVISION_ID 0x84
static void __devinit pci_fixup_via_northbridge_bug(struct pci_dev *d)
static void pci_fixup_via_northbridge_bug(struct pci_dev *d)
{
u8 v;
u8 revision;
......@@ -151,6 +151,10 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8622, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, pci_fixup_via_northbridge_bug);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8367_0, pci_fixup_via_northbridge_bug);
/*
* For some reasons Intel decided that certain parts of their
......@@ -181,7 +185,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_ANY_ID, pci_fixup_transparent_
* issue another HALT within 80 ns of the initial HALT, the failure condition
* is avoided.
*/
static void __init pci_fixup_nforce2(struct pci_dev *dev)
static void pci_fixup_nforce2(struct pci_dev *dev)
{
u32 val;
......@@ -204,6 +208,7 @@ static void __init pci_fixup_nforce2(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NFORCE2, pci_fixup_nforce2);
/* Max PCI Express root ports */
#define MAX_PCIEROOT 6
......@@ -419,7 +424,7 @@ DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_TI, 0x8032,
* Prevent the BIOS trapping accesses to the Cyrix CS5530A video device
* configuration space.
*/
static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
static void pci_early_fixup_cyrix_5530(struct pci_dev *dev)
{
u8 r;
/* clear 'F4 Video Configuration Trap' bit */
......@@ -429,3 +434,5 @@ static void __devinit pci_early_fixup_cyrix_5530(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
pci_early_fixup_cyrix_5530);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5530_LEGACY,
pci_early_fixup_cyrix_5530);
......@@ -390,7 +390,7 @@ static void __init mpic_scan_ht_pic(struct mpic *mpic, u8 __iomem *devbase,
u8 id = readb(devbase + pos + PCI_CAP_LIST_ID);
if (id == PCI_CAP_ID_HT) {
id = readb(devbase + pos + 3);
if (id == HT_CAPTYPE_IRQ)
if ((id & HT_5BIT_CAP_MASK) == HT_CAPTYPE_IRQ)
break;
}
}
......
......@@ -368,7 +368,6 @@ static struct pci_device_id atiixp_pci_tbl[] = {
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP300_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP400_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
{ PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, PCI_ANY_ID, PCI_ANY_ID, (PCI_CLASS_STORAGE_IDE<<8)|0x8a, 0xffff05, 1},
{ 0, },
};
MODULE_DEVICE_TABLE(pci, atiixp_pci_tbl);
......
......@@ -1682,7 +1682,7 @@ int __init acpiphp_glue_init(void)
*
* This function frees all data allocated in acpiphp_glue_init()
*/
void __exit acpiphp_glue_exit(void)
void acpiphp_glue_exit(void)
{
acpi_pci_unregister_driver(&acpi_pci_hp_driver);
}
......
......@@ -47,21 +47,11 @@ static ssize_t location_read_file (struct hotplug_slot *php_slot, char *buf)
return retval;
}
static struct hotplug_slot_attribute hotplug_slot_attr_location = {
static struct hotplug_slot_attribute php_attr_location = {
.attr = {.name = "phy_location", .mode = S_IFREG | S_IRUGO},
.show = location_read_file,
};
static void rpaphp_sysfs_add_attr_location (struct hotplug_slot *slot)
{
sysfs_create_file(&slot->kobj, &hotplug_slot_attr_location.attr);
}
static void rpaphp_sysfs_remove_attr_location (struct hotplug_slot *slot)
{
sysfs_remove_file(&slot->kobj, &hotplug_slot_attr_location.attr);
}
/* free up the memory used by a slot */
static void rpaphp_release_slot(struct hotplug_slot *hotplug_slot)
{
......@@ -145,7 +135,7 @@ int rpaphp_deregister_slot(struct slot *slot)
list_del(&slot->rpaphp_slot_list);
/* remove "phy_location" file */
rpaphp_sysfs_remove_attr_location(php_slot);
sysfs_remove_file(&php_slot->kobj, &php_attr_location.attr);
retval = pci_hp_deregister(php_slot);
if (retval)
......@@ -160,36 +150,45 @@ EXPORT_SYMBOL_GPL(rpaphp_deregister_slot);
int rpaphp_register_slot(struct slot *slot)
{
struct hotplug_slot *php_slot = slot->hotplug_slot;
int retval;
dbg("%s registering slot:path[%s] index[%x], name[%s] pdomain[%x] type[%d]\n",
__FUNCTION__, slot->dn->full_name, slot->index, slot->name,
slot->power_domain, slot->type);
/* should not try to register the same slot twice */
if (is_registered(slot)) { /* should't be here */
if (is_registered(slot)) {
err("rpaphp_register_slot: slot[%s] is already registered\n", slot->name);
rpaphp_release_slot(slot->hotplug_slot);
return -EAGAIN;
retval = -EAGAIN;
goto register_fail;
}
retval = pci_hp_register(slot->hotplug_slot);
retval = pci_hp_register(php_slot);
if (retval) {
err("pci_hp_register failed with error %d\n", retval);
rpaphp_release_slot(slot->hotplug_slot);
return retval;
goto register_fail;
}
/* create "phy_locatoin" file */
rpaphp_sysfs_add_attr_location(slot->hotplug_slot);
/* create "phy_location" file */
retval = sysfs_create_file(&php_slot->kobj, &php_attr_location.attr);
if (retval) {
err("sysfs_create_file failed with error %d\n", retval);
goto sysfs_fail;
}
/* add slot to our internal list */
dbg("%s adding slot[%s] to rpaphp_slot_list\n",
__FUNCTION__, slot->name);
list_add(&slot->rpaphp_slot_list, &rpaphp_slot_head);
info("Slot [%s](PCI location=%s) registered\n", slot->name,
slot->location);
num_slots++;
return 0;
sysfs_fail:
pci_hp_deregister(php_slot);
register_fail:
rpaphp_release_slot(php_slot);
return retval;
}
int rpaphp_get_power_status(struct slot *slot, u8 * value)
......
......@@ -47,11 +47,17 @@ extern int shpchp_poll_time;
extern int shpchp_debug;
extern struct workqueue_struct *shpchp_wq;
/*#define dbg(format, arg...) do { if (shpchp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/
#define dbg(format, arg...) do { if (shpchp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0)
#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
#define dbg(format, arg...) \
do { \
if (shpchp_debug) \
printk("%s: " format, MY_NAME , ## arg); \
} while (0)
#define err(format, arg...) \
printk(KERN_ERR "%s: " format, MY_NAME , ## arg)
#define info(format, arg...) \
printk(KERN_INFO "%s: " format, MY_NAME , ## arg)
#define warn(format, arg...) \
printk(KERN_WARNING "%s: " format, MY_NAME , ## arg)
#define SLOT_NAME_SIZE 10
struct slot {
......@@ -83,34 +89,27 @@ struct event_info {
struct controller {
struct mutex crit_sect; /* critical section mutex */
struct mutex cmd_lock; /* command lock */
struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */
int num_slots; /* Number of slots on ctlr */
int slot_num_inc; /* 1 or -1 */
struct pci_dev *pci_dev;
struct list_head slot_list;
struct hpc_ops *hpc_ops;
wait_queue_head_t queue; /* sleep & wake process */
u8 bus;
u8 device;
u8 function;
u8 slot_device_offset;
u8 add_support;
u32 pcix_misc2_reg; /* for amd pogo errata */
enum pci_bus_speed speed;
u32 first_slot; /* First physical slot number */
u8 slot_bus; /* Bus where the slots handled by this controller sit */
u32 cap_offset;
unsigned long mmio_base;
unsigned long mmio_size;
void __iomem *creg;
struct timer_list poll_timer;
};
/* Define AMD SHPC ID */
#define PCI_DEVICE_ID_AMD_GOLAM_7450 0x7450
#define PCI_DEVICE_ID_AMD_POGO_7458 0x7458
/* AMD PCIX bridge registers */
#define PCIX_MEM_BASE_LIMIT_OFFSET 0x1C
#define PCIX_MISCII_OFFSET 0x48
#define PCIX_MISC_BRIDGE_ERRORS_OFFSET 0x80
......@@ -145,8 +144,6 @@ struct controller {
#define POWERON_STATE 3
#define POWEROFF_STATE 4
#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400
/* Error messages */
#define INTERLOCK_OPEN 0x00000002
#define ADD_NOT_SUPPORTED 0x00000003
......@@ -158,37 +155,19 @@ struct controller {
#define WRONG_BUS_FREQUENCY 0x0000000D
#define POWER_FAILURE 0x0000000E
#define REMOVE_NOT_SUPPORTED 0x00000003
#define DISABLE_CARD 1
/*
* error Messages
*/
#define msg_initialization_err "Initialization failure, error=%d\n"
#define msg_button_on "PCI slot #%s - powering on due to button press.\n"
#define msg_button_off "PCI slot #%s - powering off due to button press.\n"
#define msg_button_cancel "PCI slot #%s - action canceled due to button press.\n"
/* sysfs functions for the hotplug controller info */
extern int __must_check shpchp_create_ctrl_files(struct controller *ctrl);
extern void shpchp_remove_ctrl_files(struct controller *ctrl);
extern int shpchp_sysfs_enable_slot(struct slot *slot);
extern int shpchp_sysfs_disable_slot(struct slot *slot);
extern u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id);
extern u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id);
extern u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id);
extern u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id);
/* pci functions */
extern int shpchp_save_config(struct controller *ctrl, int busnumber, int num_ctlr_slots, int first_device_num);
extern u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl);
extern u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl);
extern u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl);
extern u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl);
extern int shpchp_configure_device(struct slot *p_slot);
extern int shpchp_unconfigure_device(struct slot *p_slot);
extern void shpchp_remove_ctrl_files(struct controller *ctrl);
extern void cleanup_slots(struct controller *ctrl);
extern void queue_pushbutton_work(struct work_struct *work);
extern int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
#ifdef CONFIG_ACPI
static inline int get_hp_params_from_firmware(struct pci_dev *dev,
......@@ -201,7 +180,7 @@ static inline int get_hp_params_from_firmware(struct pci_dev *dev,
#define get_hp_hw_control_from_firmware(pdev) \
do { \
if (DEVICE_ACPI_HANDLE(&(pdev->dev))) \
acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev))); \
acpi_run_oshp(DEVICE_ACPI_HANDLE(&(pdev->dev)));\
} while (0)
#else
#define get_hp_params_from_firmware(dev, hpp) (-ENODEV)
......@@ -222,17 +201,6 @@ struct ctrl_reg {
volatile u32 serr_loc;
volatile u32 serr_intr_enable;
volatile u32 slot1;
volatile u32 slot2;
volatile u32 slot3;
volatile u32 slot4;
volatile u32 slot5;
volatile u32 slot6;
volatile u32 slot7;
volatile u32 slot8;
volatile u32 slot9;
volatile u32 slot10;
volatile u32 slot11;
volatile u32 slot12;
} __attribute__ ((packed));
/* offsets to the controller registers based on the above structure layout */
......@@ -250,80 +218,23 @@ enum ctrl_offsets {
SERR_LOC = offsetof(struct ctrl_reg, serr_loc),
SERR_INTR_ENABLE = offsetof(struct ctrl_reg, serr_intr_enable),
SLOT1 = offsetof(struct ctrl_reg, slot1),
SLOT2 = offsetof(struct ctrl_reg, slot2),
SLOT3 = offsetof(struct ctrl_reg, slot3),
SLOT4 = offsetof(struct ctrl_reg, slot4),
SLOT5 = offsetof(struct ctrl_reg, slot5),
SLOT6 = offsetof(struct ctrl_reg, slot6),
SLOT7 = offsetof(struct ctrl_reg, slot7),
SLOT8 = offsetof(struct ctrl_reg, slot8),
SLOT9 = offsetof(struct ctrl_reg, slot9),
SLOT10 = offsetof(struct ctrl_reg, slot10),
SLOT11 = offsetof(struct ctrl_reg, slot11),
SLOT12 = offsetof(struct ctrl_reg, slot12),
};
typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id);
struct php_ctlr_state_s {
struct php_ctlr_state_s *pnext;
struct pci_dev *pci_dev;
unsigned int irq;
unsigned long flags; /* spinlock's */
u32 slot_device_offset;
u32 num_slots;
struct timer_list int_poll_timer; /* Added for poll event */
php_intr_callback_t attention_button_callback;
php_intr_callback_t switch_change_callback;
php_intr_callback_t presence_change_callback;
php_intr_callback_t power_fault_callback;
void *callback_instance_id;
void __iomem *creg; /* Ptr to controller register space */
};
/* Inline functions */
/* Inline functions to check the sanity of a pointer that is passed to us */
static inline int slot_paranoia_check (struct slot *slot, const char *function)
static inline struct slot *get_slot(struct hotplug_slot *hotplug_slot)
{
if (!slot) {
dbg("%s - slot == NULL", function);
return -1;
}
if (!slot->hotplug_slot) {
dbg("%s - slot->hotplug_slot == NULL!", function);
return -1;
}
return 0;
}
static inline struct slot *get_slot (struct hotplug_slot *hotplug_slot, const char *function)
{
struct slot *slot;
if (!hotplug_slot) {
dbg("%s - hotplug_slot == NULL\n", function);
return NULL;
}
slot = (struct slot *)hotplug_slot->private;
if (slot_paranoia_check (slot, function))
return NULL;
return slot;
return hotplug_slot->private;
}
static inline struct slot *shpchp_find_slot (struct controller *ctrl, u8 device)
static inline struct slot *shpchp_find_slot(struct controller *ctrl, u8 device)
{
struct slot *slot;
if (!ctrl)
return NULL;
list_for_each_entry(slot, &ctrl->slot_list, slot_list) {
if (slot->device == device)
return slot;
}
err("%s: slot (device=0x%x) not found\n", __FUNCTION__, device);
return NULL;
}
......@@ -400,44 +311,27 @@ static inline void amd_pogo_errata_restore_misc_reg(struct slot *p_slot)
pci_write_config_dword(p_slot->ctrl->pci_dev, PCIX_MISCII_OFFSET, pcix_misc2_temp);
}
enum php_ctlr_type {
PCI,
ISA,
ACPI
};
int shpc_init( struct controller *ctrl, struct pci_dev *pdev);
int shpc_get_ctlr_slot_config( struct controller *ctrl,
int *num_ctlr_slots,
int *first_device_num,
int *physical_slot_num,
int *updown,
int *flags);
struct hpc_ops {
int (*power_on_slot ) (struct slot *slot);
int (*slot_enable ) (struct slot *slot);
int (*slot_disable ) (struct slot *slot);
int (*set_bus_speed_mode) (struct slot *slot, enum pci_bus_speed speed);
int (*get_power_status) (struct slot *slot, u8 *status);
int (*get_attention_status) (struct slot *slot, u8 *status);
int (*set_attention_status) (struct slot *slot, u8 status);
int (*get_latch_status) (struct slot *slot, u8 *status);
int (*get_adapter_status) (struct slot *slot, u8 *status);
int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed);
int (*get_adapter_speed) (struct slot *slot, enum pci_bus_speed *speed);
int (*get_mode1_ECC_cap) (struct slot *slot, u8 *mode);
int (*get_prog_int) (struct slot *slot, u8 *prog_int);
int (*query_power_fault) (struct slot *slot);
void (*green_led_on) (struct slot *slot);
void (*green_led_off) (struct slot *slot);
void (*green_led_blink) (struct slot *slot);
void (*release_ctlr) (struct controller *ctrl);
int (*check_cmd_status) (struct controller *ctrl);
int (*power_on_slot)(struct slot *slot);
int (*slot_enable)(struct slot *slot);
int (*slot_disable)(struct slot *slot);
int (*set_bus_speed_mode)(struct slot *slot, enum pci_bus_speed speed);
int (*get_power_status)(struct slot *slot, u8 *status);
int (*get_attention_status)(struct slot *slot, u8 *status);
int (*set_attention_status)(struct slot *slot, u8 status);
int (*get_latch_status)(struct slot *slot, u8 *status);
int (*get_adapter_status)(struct slot *slot, u8 *status);
int (*get_max_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
int (*get_cur_bus_speed)(struct slot *slot, enum pci_bus_speed *speed);
int (*get_adapter_speed)(struct slot *slot, enum pci_bus_speed *speed);
int (*get_mode1_ECC_cap)(struct slot *slot, u8 *mode);
int (*get_prog_int)(struct slot *slot, u8 *prog_int);
int (*query_power_fault)(struct slot *slot);
void (*green_led_on)(struct slot *slot);
void (*green_led_off)(struct slot *slot);
void (*green_led_blink)(struct slot *slot);
void (*release_ctlr)(struct controller *ctrl);
int (*check_cmd_status)(struct controller *ctrl);
};
#endif /* _SHPCHP_H */
......@@ -104,23 +104,6 @@ static void make_slot_name(struct slot *slot)
slot->bus, slot->number);
}
static int
shpchprm_get_physical_slot_number(struct controller *ctrl, u32 *sun,
u8 busnum, u8 devnum)
{
int offset = devnum - ctrl->slot_device_offset;
dbg("%s: ctrl->slot_num_inc %d, offset %d\n", __FUNCTION__,
ctrl->slot_num_inc, offset);
*sun = (u8) (ctrl->first_slot + ctrl->slot_num_inc *offset);
return 0;
}
static int init_slots(struct controller *ctrl)
{
struct slot *slot;
......@@ -128,7 +111,6 @@ static int init_slots(struct controller *ctrl)
struct hotplug_slot_info *info;
int retval = -ENOMEM;
int i;
u32 sun;
for (i = 0; i < ctrl->num_slots; i++) {
slot = kzalloc(sizeof(*slot), GFP_KERNEL);
......@@ -149,16 +131,11 @@ static int init_slots(struct controller *ctrl)
slot->hp_slot = i;
slot->ctrl = ctrl;
slot->bus = ctrl->slot_bus;
slot->bus = ctrl->pci_dev->subordinate->number;
slot->device = ctrl->slot_device_offset + i;
slot->hpc_ops = ctrl->hpc_ops;
slot->number = ctrl->first_slot + (ctrl->slot_num_inc * i);
mutex_init(&slot->lock);
if (shpchprm_get_physical_slot_number(ctrl, &sun,
slot->bus, slot->device))
goto error_info;
slot->number = sun;
INIT_DELAYED_WORK(&slot->work, queue_pushbutton_work);
/* register this slot with the hotplug pci core */
......@@ -211,42 +188,12 @@ void cleanup_slots(struct controller *ctrl)
}
}
static int get_ctlr_slot_config(struct controller *ctrl)
{
int num_ctlr_slots;
int first_device_num;
int physical_slot_num;
int updown;
int rc;
int flags;
rc = shpc_get_ctlr_slot_config(ctrl, &num_ctlr_slots,
&first_device_num, &physical_slot_num,
&updown, &flags);
if (rc) {
err("%s: get_ctlr_slot_config fail for b:d (%x:%x)\n",
__FUNCTION__, ctrl->bus, ctrl->device);
return -1;
}
ctrl->num_slots = num_ctlr_slots;
ctrl->slot_device_offset = first_device_num;
ctrl->first_slot = physical_slot_num;
ctrl->slot_num_inc = updown; /* either -1 or 1 */
dbg("%s: num_slot(0x%x) 1st_dev(0x%x) psn(0x%x) updown(%d) for b:d "
"(%x:%x)\n", __FUNCTION__, num_ctlr_slots, first_device_num,
physical_slot_num, updown, ctrl->bus, ctrl->device);
return 0;
}
/*
* set_attention_status - Turns the Amber LED for a slot on, off or blink
*/
static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -258,7 +205,7 @@ static int set_attention_status (struct hotplug_slot *hotplug_slot, u8 status)
static int enable_slot (struct hotplug_slot *hotplug_slot)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -267,7 +214,7 @@ static int enable_slot (struct hotplug_slot *hotplug_slot)
static int disable_slot (struct hotplug_slot *hotplug_slot)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -276,7 +223,7 @@ static int disable_slot (struct hotplug_slot *hotplug_slot)
static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -290,7 +237,7 @@ static int get_power_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -304,7 +251,7 @@ static int get_attention_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -318,7 +265,7 @@ static int get_latch_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -332,7 +279,7 @@ static int get_adapter_status (struct hotplug_slot *hotplug_slot, u8 *value)
static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
struct pci_bus *bus = slot->ctrl->pci_dev->subordinate;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -344,7 +291,7 @@ static int get_address (struct hotplug_slot *hotplug_slot, u32 *value)
static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -358,7 +305,7 @@ static int get_max_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_sp
static int get_cur_bus_speed (struct hotplug_slot *hotplug_slot, enum pci_bus_speed *value)
{
struct slot *slot = get_slot(hotplug_slot, __FUNCTION__);
struct slot *slot = get_slot(hotplug_slot);
int retval;
dbg("%s - physical_slot = %s\n", __FUNCTION__, hotplug_slot->name);
......@@ -385,9 +332,6 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
int rc;
struct controller *ctrl;
struct slot *t_slot;
int first_device_num; /* first PCI device number */
int num_ctlr_slots; /* number of slots implemented */
if (!is_shpc_capable(pdev))
return -ENODEV;
......@@ -408,47 +352,13 @@ static int shpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, ctrl);
ctrl->bus = pdev->bus->number;
ctrl->slot_bus = pdev->subordinate->number;
ctrl->device = PCI_SLOT(pdev->devfn);
ctrl->function = PCI_FUNC(pdev->devfn);
dbg("ctrl bus=0x%x, device=%x, function=%x, irq=%x\n",
ctrl->bus, ctrl->device, ctrl->function, pdev->irq);
/*
* Save configuration headers for this and subordinate PCI buses
*/
rc = get_ctlr_slot_config(ctrl);
if (rc) {
err(msg_initialization_err, rc);
goto err_out_release_ctlr;
}
first_device_num = ctrl->slot_device_offset;
num_ctlr_slots = ctrl->num_slots;
ctrl->add_support = 1;
/* Setup the slot information structures */
rc = init_slots(ctrl);
if (rc) {
err(msg_initialization_err, 6);
err("%s: slot initialization failed\n", SHPC_MODULE_NAME);
goto err_out_release_ctlr;
}
/* Now hpc_functions (slot->hpc_ops->functions) are ready */
t_slot = shpchp_find_slot(ctrl, first_device_num);
/* Check for operation bus speed */
rc = t_slot->hpc_ops->get_cur_bus_speed(t_slot, &ctrl->speed);
dbg("%s: t_slot->hp_slot %x\n", __FUNCTION__,t_slot->hp_slot);
if (rc || ctrl->speed == PCI_SPEED_UNKNOWN) {
err(SHPC_MODULE_NAME ": Can't get current bus speed. "
"Set to 33MHz PCI.\n");
ctrl->speed = PCI_SPEED_33MHz;
}
rc = shpchp_create_ctrl_files(ctrl);
if (rc)
goto err_cleanup_slots;
......
......@@ -57,9 +57,8 @@ static int queue_interrupt_event(struct slot *p_slot, u32 event_type)
return 0;
}
u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
u8 shpchp_handle_attention_button(u8 hp_slot, struct controller *ctrl)
{
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u32 event_type;
......@@ -81,9 +80,8 @@ u8 shpchp_handle_attention_button(u8 hp_slot, void *inst_id)
}
u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
u8 shpchp_handle_switch_change(u8 hp_slot, struct controller *ctrl)
{
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u8 getstatus;
u32 event_type;
......@@ -120,9 +118,8 @@ u8 shpchp_handle_switch_change(u8 hp_slot, void *inst_id)
return 1;
}
u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
u8 shpchp_handle_presence_change(u8 hp_slot, struct controller *ctrl)
{
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u32 event_type;
......@@ -154,9 +151,8 @@ u8 shpchp_handle_presence_change(u8 hp_slot, void *inst_id)
return 1;
}
u8 shpchp_handle_power_fault(u8 hp_slot, void *inst_id)
u8 shpchp_handle_power_fault(u8 hp_slot, struct controller *ctrl)
{
struct controller *ctrl = (struct controller *) inst_id;
struct slot *p_slot;
u32 event_type;
......@@ -497,10 +493,12 @@ static void handle_button_press_event(struct slot *p_slot)
p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (getstatus) {
p_slot->state = BLINKINGOFF_STATE;
info(msg_button_off, p_slot->name);
info("PCI slot #%s - powering off due to button "
"press.\n", p_slot->name);
} else {
p_slot->state = BLINKINGON_STATE;
info(msg_button_on, p_slot->name);
info("PCI slot #%s - powering on due to button "
"press.\n", p_slot->name);
}
/* blink green LED and turn off amber */
p_slot->hpc_ops->green_led_blink(p_slot);
......@@ -523,7 +521,8 @@ static void handle_button_press_event(struct slot *p_slot)
else
p_slot->hpc_ops->green_led_off(p_slot);
p_slot->hpc_ops->set_attention_status(p_slot, 0);
info(msg_button_cancel, p_slot->name);
info("PCI slot #%s - action canceled due to button press\n",
p_slot->name);
p_slot->state = STATIC_STATE;
break;
case POWEROFF_STATE:
......
......@@ -212,44 +212,40 @@
#define SLOT_SERR_INT_MASK 0x3
DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
static int ctlr_seq_num = 0; /* Controller sequenc # */
static spinlock_t list_lock;
static atomic_t shpchp_num_controllers = ATOMIC_INIT(0);
static irqreturn_t shpc_isr(int irq, void *dev_id);
static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec);
static void start_int_poll_timer(struct controller *ctrl, int sec);
static int hpc_check_cmd_status(struct controller *ctrl);
static inline u8 shpc_readb(struct controller *ctrl, int reg)
{
return readb(ctrl->hpc_ctlr_handle->creg + reg);
return readb(ctrl->creg + reg);
}
static inline void shpc_writeb(struct controller *ctrl, int reg, u8 val)
{
writeb(val, ctrl->hpc_ctlr_handle->creg + reg);
writeb(val, ctrl->creg + reg);
}
static inline u16 shpc_readw(struct controller *ctrl, int reg)
{
return readw(ctrl->hpc_ctlr_handle->creg + reg);
return readw(ctrl->creg + reg);
}
static inline void shpc_writew(struct controller *ctrl, int reg, u16 val)
{
writew(val, ctrl->hpc_ctlr_handle->creg + reg);
writew(val, ctrl->creg + reg);
}
static inline u32 shpc_readl(struct controller *ctrl, int reg)
{
return readl(ctrl->hpc_ctlr_handle->creg + reg);
return readl(ctrl->creg + reg);
}
static inline void shpc_writel(struct controller *ctrl, int reg, u32 val)
{
writel(val, ctrl->hpc_ctlr_handle->creg + reg);
writel(val, ctrl->creg + reg);
}
static inline int shpc_indirect_read(struct controller *ctrl, int index,
......@@ -268,21 +264,20 @@ static inline int shpc_indirect_read(struct controller *ctrl, int index,
/*
* This is the interrupt polling timeout function.
*/
static void int_poll_timeout(unsigned long lphp_ctlr)
static void int_poll_timeout(unsigned long data)
{
struct php_ctlr_state_s *php_ctlr =
(struct php_ctlr_state_s *)lphp_ctlr;
struct controller *ctrl = (struct controller *)data;
DBG_ENTER_ROUTINE
/* Poll for interrupt events. regs == NULL => polling */
shpc_isr(0, php_ctlr->callback_instance_id);
shpc_isr(0, ctrl);
init_timer(&php_ctlr->int_poll_timer);
init_timer(&ctrl->poll_timer);
if (!shpchp_poll_time)
shpchp_poll_time = 2; /* default polling interval is 2 sec */
start_int_poll_timer(php_ctlr, shpchp_poll_time);
start_int_poll_timer(ctrl, shpchp_poll_time);
DBG_LEAVE_ROUTINE
}
......@@ -290,16 +285,16 @@ static void int_poll_timeout(unsigned long lphp_ctlr)
/*
* This function starts the interrupt polling timer.
*/
static void start_int_poll_timer(struct php_ctlr_state_s *php_ctlr, int sec)
static void start_int_poll_timer(struct controller *ctrl, int sec)
{
/* Clamp to sane value */
if ((sec <= 0) || (sec > 60))
sec = 2;
php_ctlr->int_poll_timer.function = &int_poll_timeout;
php_ctlr->int_poll_timer.data = (unsigned long)php_ctlr;
php_ctlr->int_poll_timer.expires = jiffies + sec * HZ;
add_timer(&php_ctlr->int_poll_timer);
ctrl->poll_timer.function = &int_poll_timeout;
ctrl->poll_timer.data = (unsigned long)ctrl;
ctrl->poll_timer.expires = jiffies + sec * HZ;
add_timer(&ctrl->poll_timer);
}
static inline int is_ctrl_busy(struct controller *ctrl)
......@@ -666,33 +661,8 @@ static void hpc_set_green_led_blink(struct slot *slot)
shpc_write_cmd(slot, slot->hp_slot, SET_PWR_BLINK);
}
int shpc_get_ctlr_slot_config(struct controller *ctrl,
int *num_ctlr_slots, /* number of slots in this HPC */
int *first_device_num, /* PCI dev num of the first slot in this SHPC */
int *physical_slot_num, /* phy slot num of the first slot in this SHPC */
int *updown, /* physical_slot_num increament: 1 or -1 */
int *flags)
{
u32 slot_config;
DBG_ENTER_ROUTINE
slot_config = shpc_readl(ctrl, SLOT_CONFIG);
*first_device_num = (slot_config & FIRST_DEV_NUM) >> 8;
*num_ctlr_slots = slot_config & SLOT_NUM;
*physical_slot_num = (slot_config & PSN) >> 16;
*updown = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
dbg("%s: physical_slot_num = %x\n", __FUNCTION__, *physical_slot_num);
DBG_LEAVE_ROUTINE
return 0;
}
static void hpc_release_ctlr(struct controller *ctrl)
{
struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
struct php_ctlr_state_s *p, *p_prev;
int i;
u32 slot_reg, serr_int;
......@@ -722,40 +692,15 @@ static void hpc_release_ctlr(struct controller *ctrl)
serr_int &= ~SERR_INTR_RSVDZ_MASK;
shpc_writel(ctrl, SERR_INTR_ENABLE, serr_int);
if (shpchp_poll_mode) {
del_timer(&php_ctlr->int_poll_timer);
} else {
if (php_ctlr->irq) {
free_irq(php_ctlr->irq, ctrl);
php_ctlr->irq = 0;
pci_disable_msi(php_ctlr->pci_dev);
}
if (shpchp_poll_mode)
del_timer(&ctrl->poll_timer);
else {
free_irq(ctrl->pci_dev->irq, ctrl);
pci_disable_msi(ctrl->pci_dev);
}
if (php_ctlr->pci_dev) {
iounmap(php_ctlr->creg);
iounmap(ctrl->creg);
release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
php_ctlr->pci_dev = NULL;
}
spin_lock(&list_lock);
p = php_ctlr_list_head;
p_prev = NULL;
while (p) {
if (p == php_ctlr) {
if (p_prev)
p_prev->pnext = p->pnext;
else
php_ctlr_list_head = p->pnext;
break;
} else {
p_prev = p;
p = p->pnext;
}
}
spin_unlock(&list_lock);
kfree(php_ctlr);
/*
* If this is the last controller to be released, destroy the
......@@ -764,8 +709,7 @@ static void hpc_release_ctlr(struct controller *ctrl)
if (atomic_dec_and_test(&shpchp_num_controllers))
destroy_workqueue(shpchp_wq);
DBG_LEAVE_ROUTINE
DBG_LEAVE_ROUTINE
}
static int hpc_power_on_slot(struct slot * slot)
......@@ -891,7 +835,6 @@ static int hpc_set_bus_speed_mode(struct slot * slot, enum pci_bus_speed value)
static irqreturn_t shpc_isr(int irq, void *dev_id)
{
struct controller *ctrl = (struct controller *)dev_id;
struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
u32 serr_int, slot_reg, intr_loc, intr_loc2;
int hp_slot;
......@@ -942,20 +885,16 @@ static irqreturn_t shpc_isr(int irq, void *dev_id)
__FUNCTION__, hp_slot, slot_reg);
if (slot_reg & MRL_CHANGE_DETECTED)
php_ctlr->switch_change_callback(
hp_slot, php_ctlr->callback_instance_id);
shpchp_handle_switch_change(hp_slot, ctrl);
if (slot_reg & BUTTON_PRESS_DETECTED)
php_ctlr->attention_button_callback(
hp_slot, php_ctlr->callback_instance_id);
shpchp_handle_attention_button(hp_slot, ctrl);
if (slot_reg & PRSNT_CHANGE_DETECTED)
php_ctlr->presence_change_callback(
hp_slot , php_ctlr->callback_instance_id);
shpchp_handle_presence_change(hp_slot, ctrl);
if (slot_reg & (ISO_PFAULT_DETECTED | CON_PFAULT_DETECTED))
php_ctlr->power_fault_callback(
hp_slot, php_ctlr->callback_instance_id);
shpchp_handle_power_fault(hp_slot, ctrl);
/* Clear all slot events */
slot_reg &= ~SLOT_REG_RSVDZ_MASK;
......@@ -1114,10 +1053,8 @@ static struct hpc_ops shpchp_hpc_ops = {
.release_ctlr = hpc_release_ctlr,
};
int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
int shpc_init(struct controller *ctrl, struct pci_dev *pdev)
{
struct php_ctlr_state_s *php_ctlr, *p;
void *instance_id = ctrl;
int rc = -1, num_slots = 0;
u8 hp_slot;
u32 shpc_base_offset;
......@@ -1128,16 +1065,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
ctrl->pci_dev = pdev; /* pci_dev of the P2P bridge */
spin_lock_init(&list_lock);
php_ctlr = kzalloc(sizeof(*php_ctlr), GFP_KERNEL);
if (!php_ctlr) { /* allocate controller state data */
err("%s: HPC controller memory allocation error!\n", __FUNCTION__);
goto abort;
}
php_ctlr->pci_dev = pdev; /* save pci_dev in context */
if ((pdev->vendor == PCI_VENDOR_ID_AMD) || (pdev->device ==
PCI_DEVICE_ID_AMD_GOLAM_7450)) {
/* amd shpc driver doesn't use Base Offset; assume 0 */
......@@ -1147,20 +1074,20 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
ctrl->cap_offset = pci_find_capability(pdev, PCI_CAP_ID_SHPC);
if (!ctrl->cap_offset) {
err("%s : cap_offset == 0\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
dbg("%s: cap_offset = %x\n", __FUNCTION__, ctrl->cap_offset);
rc = shpc_indirect_read(ctrl, 0, &shpc_base_offset);
if (rc) {
err("%s: cannot read base_offset\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
rc = shpc_indirect_read(ctrl, 3, &tempdword);
if (rc) {
err("%s: cannot read slot config\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
num_slots = tempdword & SLOT_NUM;
dbg("%s: num_slots (indirect) %x\n", __FUNCTION__, num_slots);
......@@ -1170,7 +1097,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
if (rc) {
err("%s: cannot read creg (index = %d)\n",
__FUNCTION__, i);
goto abort_free_ctlr;
goto abort;
}
dbg("%s: offset %d: value %x\n", __FUNCTION__,i,
tempdword);
......@@ -1187,24 +1114,24 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
rc = pci_enable_device(pdev);
if (rc) {
err("%s: pci_enable_device failed\n", __FUNCTION__);
goto abort_free_ctlr;
goto abort;
}
if (!request_mem_region(ctrl->mmio_base, ctrl->mmio_size, MY_NAME)) {
err("%s: cannot reserve MMIO region\n", __FUNCTION__);
rc = -1;
goto abort_free_ctlr;
goto abort;
}
php_ctlr->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
if (!php_ctlr->creg) {
ctrl->creg = ioremap(ctrl->mmio_base, ctrl->mmio_size);
if (!ctrl->creg) {
err("%s: cannot remap MMIO region %lx @ %lx\n", __FUNCTION__,
ctrl->mmio_size, ctrl->mmio_base);
release_mem_region(ctrl->mmio_base, ctrl->mmio_size);
rc = -1;
goto abort_free_ctlr;
goto abort;
}
dbg("%s: php_ctlr->creg %p\n", __FUNCTION__, php_ctlr->creg);
dbg("%s: ctrl->creg %p\n", __FUNCTION__, ctrl->creg);
mutex_init(&ctrl->crit_sect);
mutex_init(&ctrl->cmd_lock);
......@@ -1212,23 +1139,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
/* Setup wait queue */
init_waitqueue_head(&ctrl->queue);
/* Find the IRQ */
php_ctlr->irq = pdev->irq;
php_ctlr->attention_button_callback = shpchp_handle_attention_button,
php_ctlr->switch_change_callback = shpchp_handle_switch_change;
php_ctlr->presence_change_callback = shpchp_handle_presence_change;
php_ctlr->power_fault_callback = shpchp_handle_power_fault;
php_ctlr->callback_instance_id = instance_id;
ctrl->hpc_ctlr_handle = php_ctlr;
ctrl->hpc_ops = &shpchp_hpc_ops;
/* Return PCI Controller Info */
slot_config = shpc_readl(ctrl, SLOT_CONFIG);
php_ctlr->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
php_ctlr->num_slots = slot_config & SLOT_NUM;
dbg("%s: slot_device_offset %x\n", __FUNCTION__, php_ctlr->slot_device_offset);
dbg("%s: num_slots %x\n", __FUNCTION__, php_ctlr->num_slots);
ctrl->slot_device_offset = (slot_config & FIRST_DEV_NUM) >> 8;
ctrl->num_slots = slot_config & SLOT_NUM;
ctrl->first_slot = (slot_config & PSN) >> 16;
ctrl->slot_num_inc = ((slot_config & UPDOWN) >> 29) ? 1 : -1;
/* Mask Global Interrupt Mask & Command Complete Interrupt Mask */
tempdword = shpc_readl(ctrl, SERR_INTR_ENABLE);
......@@ -1243,7 +1161,7 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
/* Mask the MRL sensor SERR Mask of individual slot in
* Slot SERR-INT Mask & clear all the existing event if any
*/
for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
hp_slot, slot_reg);
......@@ -1255,24 +1173,27 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
shpc_writel(ctrl, SLOT_REG(hp_slot), slot_reg);
}
if (shpchp_poll_mode) {/* Install interrupt polling code */
/* Install and start the interrupt polling timer */
init_timer(&php_ctlr->int_poll_timer);
start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
if (shpchp_poll_mode) {
/* Install interrupt polling timer. Start with 10 sec delay */
init_timer(&ctrl->poll_timer);
start_int_poll_timer(ctrl, 10);
} else {
/* Installs the interrupt handler */
rc = pci_enable_msi(pdev);
if (rc) {
info("Can't get msi for the hotplug controller\n");
info("Use INTx for the hotplug controller\n");
} else
php_ctlr->irq = pdev->irq;
}
rc = request_irq(php_ctlr->irq, shpc_isr, IRQF_SHARED, MY_NAME, (void *) ctrl);
dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
rc = request_irq(ctrl->pci_dev->irq, shpc_isr, IRQF_SHARED,
MY_NAME, (void *)ctrl);
dbg("%s: request_irq %d for hpc%d (returns %d)\n",
__FUNCTION__, ctrl->pci_dev->irq,
atomic_read(&shpchp_num_controllers), rc);
if (rc) {
err("Can't get irq %d for the hotplug controller\n", php_ctlr->irq);
goto abort_free_ctlr;
err("Can't get irq %d for the hotplug controller\n",
ctrl->pci_dev->irq);
goto abort_iounmap;
}
}
dbg("%s: HPC at b:d:f:irq=0x%x:%x:%x:%x\n", __FUNCTION__,
......@@ -1280,24 +1201,6 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
PCI_FUNC(pdev->devfn), pdev->irq);
get_hp_hw_control_from_firmware(pdev);
/* Add this HPC instance into the HPC list */
spin_lock(&list_lock);
if (php_ctlr_list_head == 0) {
php_ctlr_list_head = php_ctlr;
p = php_ctlr_list_head;
p->pnext = NULL;
} else {
p = php_ctlr_list_head;
while (p->pnext)
p = p->pnext;
p->pnext = php_ctlr;
}
spin_unlock(&list_lock);
ctlr_seq_num++;
/*
* If this is the first controller to be initialized,
* initialize the shpchpd work queue
......@@ -1306,14 +1209,14 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
shpchp_wq = create_singlethread_workqueue("shpchpd");
if (!shpchp_wq) {
rc = -ENOMEM;
goto abort_free_ctlr;
goto abort_iounmap;
}
}
/*
* Unmask all event interrupts of all slots
*/
for (hp_slot = 0; hp_slot < php_ctlr->num_slots; hp_slot++) {
for (hp_slot = 0; hp_slot < ctrl->num_slots; hp_slot++) {
slot_reg = shpc_readl(ctrl, SLOT_REG(hp_slot));
dbg("%s: Default Logical Slot Register %d value %x\n", __FUNCTION__,
hp_slot, slot_reg);
......@@ -1336,10 +1239,8 @@ int shpc_init(struct controller * ctrl, struct pci_dev * pdev)
return 0;
/* We end up here for the many possible ways to fail this API. */
abort_free_ctlr:
if (php_ctlr->creg)
iounmap(php_ctlr->creg);
kfree(php_ctlr);
abort_iounmap:
iounmap(ctrl->creg);
abort:
DBG_LEAVE_ROUTINE
return rc;
......
......@@ -99,14 +99,7 @@ int __ht_create_irq(struct pci_dev *dev, int idx, ht_irq_update_t *update)
int pos;
int irq;
pos = pci_find_capability(dev, PCI_CAP_ID_HT);
while (pos) {
u8 subtype;
pci_read_config_byte(dev, pos + 3, &subtype);
if (subtype == HT_CAPTYPE_IRQ)
break;
pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT);
}
pos = pci_find_ht_capability(dev, HT_CAPTYPE_IRQ);
if (!pos)
return -EINVAL;
......
......@@ -162,14 +162,9 @@ const struct pci_device_id *pci_match_id(const struct pci_device_id *ids,
const struct pci_device_id *pci_match_device(struct pci_driver *drv,
struct pci_dev *dev)
{
const struct pci_device_id *id;
struct pci_dynid *dynid;
id = pci_match_id(drv->id_table, dev);
if (id)
return id;
/* static ids didn't match, lets look at the dynamic ones */
/* Look at the dynamic ids first, before the static ones */
spin_lock(&drv->dynids.lock);
list_for_each_entry(dynid, &drv->dynids.list, node) {
if (pci_match_one_device(&dynid->id, dev)) {
......@@ -178,7 +173,8 @@ const struct pci_device_id *pci_match_device(struct pci_driver *drv,
}
}
spin_unlock(&drv->dynids.lock);
return NULL;
return pci_match_id(drv->id_table, dev);
}
static int pci_call_probe(struct pci_driver *drv, struct pci_dev *dev,
......@@ -357,6 +353,8 @@ static int pci_device_resume_early(struct device * dev)
struct pci_dev * pci_dev = to_pci_dev(dev);
struct pci_driver * drv = pci_dev->driver;
pci_fixup_device(pci_fixup_resume, pci_dev);
if (drv && drv->resume_early)
error = drv->resume_early(pci_dev);
return error;
......
......@@ -68,12 +68,14 @@ pci_max_busnr(void)
#endif /* 0 */
static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos, int cap)
#define PCI_FIND_CAP_TTL 48
static int __pci_find_next_cap_ttl(struct pci_bus *bus, unsigned int devfn,
u8 pos, int cap, int *ttl)
{
u8 id;
int ttl = 48;
while (ttl--) {
while ((*ttl)--) {
pci_bus_read_config_byte(bus, devfn, pos, &pos);
if (pos < 0x40)
break;
......@@ -89,6 +91,14 @@ static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn, u8 pos,
return 0;
}
static int __pci_find_next_cap(struct pci_bus *bus, unsigned int devfn,
u8 pos, int cap)
{
int ttl = PCI_FIND_CAP_TTL;
return __pci_find_next_cap_ttl(bus, devfn, pos, cap, &ttl);
}
int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
{
return __pci_find_next_cap(dev->bus, dev->devfn,
......@@ -96,10 +106,10 @@ int pci_find_next_capability(struct pci_dev *dev, u8 pos, int cap)
}
EXPORT_SYMBOL_GPL(pci_find_next_capability);
static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_type, int cap)
static int __pci_bus_find_cap_start(struct pci_bus *bus,
unsigned int devfn, u8 hdr_type)
{
u16 status;
u8 pos;
pci_bus_read_config_word(bus, devfn, PCI_STATUS, &status);
if (!(status & PCI_STATUS_CAP_LIST))
......@@ -108,15 +118,14 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
switch (hdr_type) {
case PCI_HEADER_TYPE_NORMAL:
case PCI_HEADER_TYPE_BRIDGE:
pos = PCI_CAPABILITY_LIST;
break;
return PCI_CAPABILITY_LIST;
case PCI_HEADER_TYPE_CARDBUS:
pos = PCI_CB_CAPABILITY_LIST;
break;
return PCI_CB_CAPABILITY_LIST;
default:
return 0;
}
return __pci_find_next_cap(bus, devfn, pos, cap);
return 0;
}
/**
......@@ -140,7 +149,13 @@ static int __pci_bus_find_cap(struct pci_bus *bus, unsigned int devfn, u8 hdr_ty
*/
int pci_find_capability(struct pci_dev *dev, int cap)
{
return __pci_bus_find_cap(dev->bus, dev->devfn, dev->hdr_type, cap);
int pos;
pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
if (pos)
pos = __pci_find_next_cap(dev->bus, dev->devfn, pos, cap);
return pos;
}
/**
......@@ -158,11 +173,16 @@ int pci_find_capability(struct pci_dev *dev, int cap)
*/
int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap)
{
int pos;
u8 hdr_type;
pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type);
return __pci_bus_find_cap(bus, devfn, hdr_type & 0x7f, cap);
pos = __pci_bus_find_cap_start(bus, devfn, hdr_type & 0x7f);
if (pos)
pos = __pci_find_next_cap(bus, devfn, pos, cap);
return pos;
}
/**
......@@ -214,6 +234,74 @@ int pci_find_ext_capability(struct pci_dev *dev, int cap)
}
EXPORT_SYMBOL_GPL(pci_find_ext_capability);
static int __pci_find_next_ht_cap(struct pci_dev *dev, int pos, int ht_cap)
{
int rc, ttl = PCI_FIND_CAP_TTL;
u8 cap, mask;
if (ht_cap == HT_CAPTYPE_SLAVE || ht_cap == HT_CAPTYPE_HOST)
mask = HT_3BIT_CAP_MASK;
else
mask = HT_5BIT_CAP_MASK;
pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
PCI_CAP_ID_HT, &ttl);
while (pos) {
rc = pci_read_config_byte(dev, pos + 3, &cap);
if (rc != PCIBIOS_SUCCESSFUL)
return 0;
if ((cap & mask) == ht_cap)
return pos;
pos = __pci_find_next_cap_ttl(dev->bus, dev->devfn, pos,
PCI_CAP_ID_HT, &ttl);
}
return 0;
}
/**
* pci_find_next_ht_capability - query a device's Hypertransport capabilities
* @dev: PCI device to query
* @pos: Position from which to continue searching
* @ht_cap: Hypertransport capability code
*
* To be used in conjunction with pci_find_ht_capability() to search for
* all capabilities matching @ht_cap. @pos should always be a value returned
* from pci_find_ht_capability().
*
* NB. To be 100% safe against broken PCI devices, the caller should take
* steps to avoid an infinite loop.
*/
int pci_find_next_ht_capability(struct pci_dev *dev, int pos, int ht_cap)
{
return __pci_find_next_ht_cap(dev, pos + PCI_CAP_LIST_NEXT, ht_cap);
}
EXPORT_SYMBOL_GPL(pci_find_next_ht_capability);
/**
* pci_find_ht_capability - query a device's Hypertransport capabilities
* @dev: PCI device to query
* @ht_cap: Hypertransport capability code
*
* Tell if a device supports a given Hypertransport capability.
* Returns an address within the device's PCI configuration space
* or 0 in case the device does not support the request capability.
* The address points to the PCI capability, of type PCI_CAP_ID_HT,
* which has a Hypertransport capability matching @ht_cap.
*/
int pci_find_ht_capability(struct pci_dev *dev, int ht_cap)
{
int pos;
pos = __pci_bus_find_cap_start(dev->bus, dev->devfn, dev->hdr_type);
if (pos)
pos = __pci_find_next_ht_cap(dev, pos, ht_cap);
return pos;
}
EXPORT_SYMBOL_GPL(pci_find_ht_capability);
/**
* pci_find_parent_resource - return resource region of parent bus of given region
* @dev: PCI device structure contains resources to be searched
......
......@@ -90,7 +90,7 @@ static int __devinit pcie_portdrv_probe (struct pci_dev *dev,
return -ENODEV;
pci_set_master(dev);
if (!dev->irq) {
if (!dev->irq && dev->pin) {
printk(KERN_WARNING
"%s->Dev[%04x:%04x] has invalid IRQ. Check vendor BIOS\n",
__FUNCTION__, dev->device, dev->vendor);
......
......@@ -649,6 +649,9 @@ static void pci_read_irq(struct pci_dev *dev)
* Returns 0 on success and -1 if unknown type of device (not normal, bridge
* or CardBus).
*/
#define LEGACY_IO_RESOURCE (IORESOURCE_IO | IORESOURCE_PCI_FIXED)
static int pci_setup_device(struct pci_dev * dev)
{
u32 class;
......@@ -692,18 +695,18 @@ static int pci_setup_device(struct pci_dev * dev)
if ((progif & 1) == 0) {
dev->resource[0].start = 0x1F0;
dev->resource[0].end = 0x1F7;
dev->resource[0].flags = IORESOURCE_IO;
dev->resource[0].flags = LEGACY_IO_RESOURCE;
dev->resource[1].start = 0x3F6;
dev->resource[1].end = 0x3F6;
dev->resource[1].flags = IORESOURCE_IO;
dev->resource[1].flags = LEGACY_IO_RESOURCE;
}
if ((progif & 4) == 0) {
dev->resource[2].start = 0x170;
dev->resource[2].end = 0x177;
dev->resource[2].flags = IORESOURCE_IO;
dev->resource[2].flags = LEGACY_IO_RESOURCE;
dev->resource[3].start = 0x376;
dev->resource[3].end = 0x376;
dev->resource[3].flags = IORESOURCE_IO;
dev->resource[3].flags = LEGACY_IO_RESOURCE;
}
}
break;
......
......@@ -36,7 +36,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_MELLANOX,PCI_DEVICE_ID_MELLANOX_TAVOR_BRID
/* Deal with broken BIOS'es that neglect to enable passive release,
which can cause problems in combination with the 82441FX/PPro MTRRs */
static void __devinit quirk_passive_release(struct pci_dev *dev)
static void quirk_passive_release(struct pci_dev *dev)
{
struct pci_dev *d = NULL;
unsigned char dlc;
......@@ -53,6 +53,7 @@ static void __devinit quirk_passive_release(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, quirk_passive_release );
/* The VIA VP2/VP3/MVP3 seem to have some 'features'. There may be a workaround
but VIA don't answer queries. If you happen to have good contacts at VIA
......@@ -134,7 +135,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82439TX, quir
* Updated based on further information from the site and also on
* information provided by VIA
*/
static void __devinit quirk_vialatency(struct pci_dev *dev)
static void quirk_vialatency(struct pci_dev *dev)
{
struct pci_dev *p;
u8 rev;
......@@ -185,6 +186,10 @@ static void __devinit quirk_vialatency(struct pci_dev *dev)
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency );
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency );
/* Must restore this on a resume from RAM */
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8363_0, quirk_vialatency );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8371_1, quirk_vialatency );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8361, quirk_vialatency );
/*
* VIA Apollo VP3 needs ETBF on BT848/878
......@@ -532,7 +537,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8235, quirk_vt8235
* TODO: When we have device-specific interrupt routers,
* this code will go away from quirks.
*/
static void __devinit quirk_via_ioapic(struct pci_dev *dev)
static void quirk_via_ioapic(struct pci_dev *dev)
{
u8 tmp;
......@@ -548,6 +553,7 @@ static void __devinit quirk_via_ioapic(struct pci_dev *dev)
pci_write_config_byte (dev, 0x58, tmp);
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_ioapic );
/*
* VIA 8237: Some BIOSs don't set the 'Bypass APIC De-Assert Message' Bit.
......@@ -555,7 +561,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, quirk_via_i
* Set this bit to get rid of cycle wastage.
* Otherwise uncritical.
*/
static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
static void quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
{
u8 misc_control2;
#define BYPASS_APIC_DEASSERT 8
......@@ -567,6 +573,7 @@ static void __devinit quirk_via_vt8237_bypass_apic_deassert(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, quirk_via_vt8237_bypass_apic_deassert);
/*
* The AMD io apic can hang the box when an apic irq is masked.
......@@ -600,7 +607,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_SI, PCI_ANY_ID, quirk_ioapic_rmw );
#define AMD8131_revB0 0x11
#define AMD8131_MISC 0x40
#define AMD8131_NIOAMODE_BIT 0
static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
static void quirk_amd_8131_ioapic(struct pci_dev *dev)
{
unsigned char revid, tmp;
......@@ -616,6 +623,7 @@ static void __init quirk_amd_8131_ioapic(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_amd_8131_ioapic);
#endif /* CONFIG_X86_IO_APIC */
......@@ -641,65 +649,84 @@ static void __devinit quirk_via_acpi(struct pci_dev *d)
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C586_3, quirk_via_acpi );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686_4, quirk_via_acpi );
/*
* Via 686A/B: The PCI_INTERRUPT_LINE register for the on-chip
* devices, USB0/1, AC97, MC97, and ACPI, has an unusual feature:
* when written, it makes an internal connection to the PIC.
* For these devices, this register is defined to be 4 bits wide.
* Normally this is fine. However for IO-APIC motherboards, or
* non-x86 architectures (yes Via exists on PPC among other places),
* we must mask the PCI_INTERRUPT_LINE value versus 0xf to get
* interrupts delivered properly.
*
* Some of the on-chip devices are actually '586 devices' so they are
* listed here.
*/
static int via_irq_fixup_needed = -1;
/*
* As some VIA hardware is available in PCI-card form, we need to restrict
* this quirk to VIA PCI hardware built onto VIA-based motherboards only.
* We try to locate a VIA southbridge before deciding whether the quirk
* should be applied.
* VIA bridges which have VLink
*/
static const struct pci_device_id via_irq_fixup_tbl[] = {
{
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
.class = PCI_CLASS_BRIDGE_ISA << 8,
.class_mask = 0xffff00,
},
static const struct pci_device_id via_vlink_fixup_tbl[] = {
/* Internal devices need IRQ line routing, pre VLink */
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C686), 0 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8231), 17 },
/* Devices with VLink */
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233_0), 17},
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233A), 17 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8233C_0), 17 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8235), 16 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237), 15 },
{ PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_8237A), 15 },
{ 0, },
};
static void quirk_via_irq(struct pci_dev *dev)
/**
* quirk_via_vlink - VIA VLink IRQ number update
* @dev: PCI device
*
* If the device we are dealing with is on a PIC IRQ we need to
* ensure that the IRQ line register which usually is not relevant
* for PCI cards, is actually written so that interrupts get sent
* to the right place
*/
static void quirk_via_vlink(struct pci_dev *dev)
{
const struct pci_device_id *via_vlink_fixup;
static int dev_lo = -1, dev_hi = 18;
u8 irq, new_irq;
if (via_irq_fixup_needed == -1)
via_irq_fixup_needed = pci_dev_present(via_irq_fixup_tbl);
/* Check if we have VLink and cache the result */
if (!via_irq_fixup_needed)
/* Checked already - no */
if (dev_lo == -2)
return;
/* Not checked - see what bridge we have and find the device
ranges */
if (dev_lo == -1) {
via_vlink_fixup = pci_find_present(via_vlink_fixup_tbl);
if (via_vlink_fixup == NULL) {
dev_lo = -2;
return;
}
dev_lo = via_vlink_fixup->driver_data;
/* 82C686 is special - 0/0 */
if (dev_lo == 0)
dev_hi = 0;
}
new_irq = dev->irq;
/* Don't quirk interrupts outside the legacy IRQ range */
if (!new_irq || new_irq > 15)
return;
/* Internal device ? */
if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) > dev_hi ||
PCI_SLOT(dev->devfn) < dev_lo)
return;
/* This is an internal VLink device on a PIC interrupt. The BIOS
ought to have set this but may not have, so we redo it */
pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &irq);
if (new_irq != irq) {
printk(KERN_INFO "PCI: VIA IRQ fixup for %s, from %d to %d\n",
printk(KERN_INFO "PCI: VIA VLink IRQ fixup for %s, from %d to %d\n",
pci_name(dev), irq, new_irq);
udelay(15); /* unknown if delay really needed */
pci_write_config_byte(dev, PCI_INTERRUPT_LINE, new_irq);
}
}
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_irq);
DECLARE_PCI_FIXUP_ENABLE(PCI_VENDOR_ID_VIA, PCI_ANY_ID, quirk_via_vlink);
/*
* VIA VT82C598 has its device ID settable and many BIOSes
......@@ -720,13 +747,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C597_0, quirk_vt
* do this even if the Linux CardBus driver is not loaded, because
* the Linux i82365 driver does not (and should not) handle CardBus.
*/
static void __devinit quirk_cardbus_legacy(struct pci_dev *dev)
static void quirk_cardbus_legacy(struct pci_dev *dev)
{
if ((PCI_CLASS_BRIDGE_CARDBUS << 8) ^ dev->class)
return;
pci_write_config_dword(dev, PCI_CB_LEGACY_MODE_BASE, 0);
}
DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
DECLARE_PCI_FIXUP_RESUME(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
/*
* Following the PCI ordering rules is optional on the AMD762. I'm not
......@@ -735,7 +763,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, quirk_cardbus_legacy);
* To be fair to AMD, it follows the spec by default, its BIOS people
* who turn it off!
*/
static void __devinit quirk_amd_ordering(struct pci_dev *dev)
static void quirk_amd_ordering(struct pci_dev *dev)
{
u32 pcic;
pci_read_config_dword(dev, 0x4C, &pcic);
......@@ -749,6 +777,7 @@ static void __devinit quirk_amd_ordering(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_FE_GATE_700C, quirk_amd_ordering );
/*
* DreamWorks provided workaround for Dunord I-3000 problem
......@@ -784,7 +813,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_TOSHIBA, 0x605, quirk_transparent_bridge
* datasheets found at http://www.national.com/ds/GX for info on what
* these bits do. <christer@weinigel.se>
*/
static void __init quirk_mediagx_master(struct pci_dev *dev)
static void quirk_mediagx_master(struct pci_dev *dev)
{
u8 reg;
pci_read_config_byte(dev, 0x41, &reg);
......@@ -795,13 +824,14 @@ static void __init quirk_mediagx_master(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_PCI_MASTER, quirk_mediagx_master );
/*
* Ensure C0 rev restreaming is off. This is normally done by
* the BIOS but in the odd case it is not the results are corruption
* hence the presence of a Linux check
*/
static void __init quirk_disable_pxb(struct pci_dev *pdev)
static void quirk_disable_pxb(struct pci_dev *pdev)
{
u16 config;
u8 rev;
......@@ -817,7 +847,25 @@ static void __init quirk_disable_pxb(struct pci_dev *pdev)
}
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82454NX, quirk_disable_pxb );
static void __devinit quirk_sb600_sata(struct pci_dev *pdev)
{
/* set sb600 sata to ahci mode */
if ((pdev->class >> 8) == PCI_CLASS_STORAGE_IDE) {
u8 tmp;
pci_read_config_byte(pdev, 0x40, &tmp);
pci_write_config_byte(pdev, 0x40, tmp|1);
pci_write_config_byte(pdev, 0x9, 1);
pci_write_config_byte(pdev, 0xa, 6);
pci_write_config_byte(pdev, 0x40, tmp);
pdev->class = 0x010601;
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_IXP600_SATA, quirk_sb600_sata);
/*
* Serverworks CSB5 IDE does not fully support native mode
......@@ -874,7 +922,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82375, quirk_e
* runs everywhere at present we suppress the printk output in most
* irrelevant cases.
*/
static void __init k8t_sound_hostbridge(struct pci_dev *dev)
static void k8t_sound_hostbridge(struct pci_dev *dev)
{
unsigned char val;
......@@ -893,8 +941,8 @@ static void __init k8t_sound_hostbridge(struct pci_dev *dev)
}
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_hostbridge);
#ifndef CONFIG_ACPI_SLEEP
/*
* On ASUS P4B boards, the SMBus PCI Device within the ICH2/4 southbridge
* is not activated. The myth is that Asus said that they do not want the
......@@ -906,10 +954,6 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, k8t_sound_ho
* bridge. Unfortunately, this device has no subvendor/subdevice ID. So it
* becomes necessary to do this tweak in two steps -- I've chosen the Host
* bridge as trigger.
*
* Actually, leaving it unhidden and not redoing the quirk over suspend2ram
* will cause thermal management to break down, and causing machine to
* overheat.
*/
static int __initdata asus_hides_smbus;
......@@ -1019,7 +1063,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855PM_HB, as
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82855GM_HB, asus_hides_smbus_hostbridge );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82915GM_HB, asus_hides_smbus_hostbridge );
static void __init asus_hides_smbus_lpc(struct pci_dev *dev)
static void asus_hides_smbus_lpc(struct pci_dev *dev)
{
u16 val;
......@@ -1042,8 +1086,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asu
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_0, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801BA_0, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_0, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801CA_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801DB_12, asus_hides_smbus_lpc );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82801EB_0, asus_hides_smbus_lpc );
static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
static void asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
{
u32 val, rcba;
void __iomem *base;
......@@ -1059,13 +1109,12 @@ static void __init asus_hides_smbus_lpc_ich6(struct pci_dev *dev)
printk(KERN_INFO "PCI: Enabled ICH6/i801 SMBus device\n");
}
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 );
#endif
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH6_1, asus_hides_smbus_lpc_ich6 );
/*
* SiS 96x south bridge: BIOS typically hides SMBus device...
*/
static void __init quirk_sis_96x_smbus(struct pci_dev *dev)
static void quirk_sis_96x_smbus(struct pci_dev *dev)
{
u8 val = 0;
printk(KERN_INFO "Enabling SiS 96x SMBus.\n");
......@@ -1086,7 +1135,7 @@ static int __devinitdata sis_96x_compatible = 0;
#define SIS_DETECT_REGISTER 0x40
static void __init quirk_sis_503(struct pci_dev *dev)
static void quirk_sis_503(struct pci_dev *dev)
{
u8 reg;
u16 devid;
......@@ -1122,13 +1171,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_651, quirk_sis_96x_
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_735, quirk_sis_96x_compatible );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_503, quirk_sis_503 );
/*
* On ASUS A8V and A8V Deluxe boards, the onboard AC97 audio controller
* and MC97 modem controller are disabled when a second PCI soundcard is
* present. This patch, tweaking the VT8237 ISA bridge, enables them.
* -- bjd
*/
static void __init asus_hides_ac97_lpc(struct pci_dev *dev)
static void asus_hides_ac97_lpc(struct pci_dev *dev)
{
u8 val;
int asus_hides_ac97 = 0;
......@@ -1159,6 +1209,14 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus );
DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_8237, asus_hides_ac97_lpc );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_961, quirk_sis_96x_smbus );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_962, quirk_sis_96x_smbus );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_963, quirk_sis_96x_smbus );
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_smbus );
#if defined(CONFIG_ATA) || defined(CONFIG_ATA_MODULE)
/*
......@@ -1167,7 +1225,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_SI, PCI_DEVICE_ID_SI_LPC, quirk_sis_96x_
* the PCI scanning.
*/
static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
static void quirk_jmicron_dualfn(struct pci_dev *pdev)
{
u32 conf;
u8 hdr;
......@@ -1205,6 +1263,7 @@ static void __devinit quirk_jmicron_dualfn(struct pci_dev *pdev)
}
DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, quirk_jmicron_dualfn);
#endif
......@@ -1532,6 +1591,8 @@ extern struct pci_fixup __start_pci_fixups_final[];
extern struct pci_fixup __end_pci_fixups_final[];
extern struct pci_fixup __start_pci_fixups_enable[];
extern struct pci_fixup __end_pci_fixups_enable[];
extern struct pci_fixup __start_pci_fixups_resume[];
extern struct pci_fixup __end_pci_fixups_resume[];
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
......@@ -1559,6 +1620,11 @@ void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev)
end = __end_pci_fixups_enable;
break;
case pci_fixup_resume:
start = __start_pci_fixups_resume;
end = __end_pci_fixups_resume;
break;
default:
/* stupid compiler warning, you would think with an enum... */
return;
......@@ -1596,7 +1662,7 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_INTEL, 0x1460, quirk_p64h2_1k_io);
* Force it to be linked by setting the corresponding control bit in the
* config space.
*/
static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
static void quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
{
uint8_t b;
if (pci_read_config_byte(dev, 0xf41, &b) == 0) {
......@@ -1610,6 +1676,8 @@ static void __devinit quirk_nvidia_ck804_pcie_aer_ext_cap(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap);
DECLARE_PCI_FIXUP_RESUME(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_CK804_PCIE,
quirk_nvidia_ck804_pcie_aer_ext_cap);
#ifdef CONFIG_PCI_MSI
/* To disable MSI globally */
......@@ -1644,19 +1712,23 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_8131_BRIDGE, quirk_
* return 1 if a HT MSI capability is found and enabled */
static int __devinit msi_ht_cap_enabled(struct pci_dev *dev)
{
u8 pos;
int ttl;
for (pos = pci_find_capability(dev, PCI_CAP_ID_HT), ttl = 48;
pos && ttl;
pos = pci_find_next_capability(dev, pos, PCI_CAP_ID_HT), ttl--) {
u32 cap_hdr;
/* MSI mapping section according to Hypertransport spec */
if (pci_read_config_dword(dev, pos, &cap_hdr) == 0
&& (cap_hdr & 0xf8000000) == 0xa8000000 /* MSI mapping */) {
printk(KERN_INFO "PCI: Found HT MSI mapping on %s with capability %s\n",
pci_name(dev), cap_hdr & 0x10000 ? "enabled" : "disabled");
return (cap_hdr & 0x10000) != 0; /* MSI mapping cap enabled */
int pos, ttl = 48;
pos = pci_find_ht_capability(dev, HT_CAPTYPE_MSI_MAPPING);
while (pos && ttl--) {
u8 flags;
if (pci_read_config_byte(dev, pos + HT_MSI_FLAGS,
&flags) == 0)
{
printk(KERN_INFO "PCI: Found %s HT MSI Mapping on %s\n",
flags & HT_MSI_FLAGS_ENABLE ?
"enabled" : "disabled", pci_name(dev));
return (flags & HT_MSI_FLAGS_ENABLE) != 0;
}
pos = pci_find_next_ht_capability(dev, pos,
HT_CAPTYPE_MSI_MAPPING);
}
return 0;
}
......@@ -1688,8 +1760,9 @@ static void __devinit quirk_nvidia_ck804_msi_ht_cap(struct pci_dev *dev)
* a single one having MSI is enough to be sure that MSI are supported.
*/
pdev = pci_get_slot(dev->bus, 0);
if (dev->subordinate && !msi_ht_cap_enabled(dev)
&& !msi_ht_cap_enabled(pdev)) {
if (!pdev)
return;
if (!msi_ht_cap_enabled(dev) && !msi_ht_cap_enabled(pdev)) {
printk(KERN_WARNING "PCI: MSI quirk detected. "
"MSI disabled on chipset %s.\n",
pci_name(dev));
......
......@@ -413,6 +413,24 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
return dev;
}
const struct pci_device_id *pci_find_present(const struct pci_device_id *ids)
{
struct pci_dev *dev;
const struct pci_device_id *found = NULL;
WARN_ON(in_interrupt());
down_read(&pci_bus_sem);
while (ids->vendor || ids->subvendor || ids->class_mask) {
list_for_each_entry(dev, &pci_devices, global_list) {
if ((found = pci_match_one_device(ids, dev)) != NULL)
break;
}
ids++;
}
up_read(&pci_bus_sem);
return found;
}
/**
* pci_dev_present - Returns 1 if device matching the device list is present, 0 if not.
* @ids: A pointer to a null terminated list of struct pci_device_id structures
......@@ -426,25 +444,11 @@ struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *from)
*/
int pci_dev_present(const struct pci_device_id *ids)
{
struct pci_dev *dev;
int found = 0;
WARN_ON(in_interrupt());
down_read(&pci_bus_sem);
while (ids->vendor || ids->subvendor || ids->class_mask) {
list_for_each_entry(dev, &pci_devices, global_list) {
if (pci_match_one_device(ids, dev)) {
found = 1;
goto exit;
}
}
ids++;
}
exit:
up_read(&pci_bus_sem);
return found;
return pci_find_present(ids) == NULL ? 0 : 1;
}
EXPORT_SYMBOL(pci_dev_present);
EXPORT_SYMBOL(pci_find_present);
EXPORT_SYMBOL(pci_find_device);
EXPORT_SYMBOL(pci_find_device_reverse);
......
......@@ -33,11 +33,22 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno)
u32 new, check, mask;
int reg;
/* Ignore resources for unimplemented BARs and unused resource slots
for 64 bit BARs. */
/*
* Ignore resources for unimplemented BARs and unused resource slots
* for 64 bit BARs.
*/
if (!res->flags)
return;
/*
* Ignore non-moveable resources. This might be legacy resources for
* which no functional BAR register exists or another important
* system resource we should better not move around in system address
* space.
*/
if (res->flags & IORESOURCE_PCI_FIXED)
return;
pcibios_resource_to_bus(dev, &region, res);
pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for "
......@@ -212,6 +223,10 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head)
resource_size_t r_align;
r = &dev->resource[i];
if (r->flags & IORESOURCE_PCI_FIXED)
continue;
r_align = r->end - r->start;
if (!(r->flags) || r->parent)
......
......@@ -35,6 +35,9 @@
VMLINUX_SYMBOL(__start_pci_fixups_enable) = .; \
*(.pci_fixup_enable) \
VMLINUX_SYMBOL(__end_pci_fixups_enable) = .; \
VMLINUX_SYMBOL(__start_pci_fixups_resume) = .; \
*(.pci_fixup_resume) \
VMLINUX_SYMBOL(__end_pci_fixups_resume) = .; \
} \
\
/* RapidIO route ops */ \
......
......@@ -119,7 +119,6 @@ header-y += nfs4_mount.h
header-y += nfs_mount.h
header-y += oom.h
header-y += param.h
header-y += pci_ids.h
header-y += pci_regs.h
header-y += personality.h
header-y += pfkeyv2.h
......@@ -162,7 +161,6 @@ header-y += vt.h
header-y += wireless.h
header-y += xattr.h
header-y += x25.h
header-y += zorro_ids.h
unifdef-y += acct.h
unifdef-y += adb.h
......
......@@ -91,6 +91,9 @@ struct resource_list {
#define IORESOURCE_ROM_COPY (1<<2) /* ROM is alloc'd copy, resource field overlaid */
#define IORESOURCE_ROM_BIOS_COPY (1<<3) /* ROM is BIOS copy, resource field overlaid */
/* PCI control bits. Shares IORESOURCE_BITS with above PCI ROM. */
#define IORESOURCE_PCI_FIXED (1<<4) /* Do not move resource */
/* PC/ISA/whatever - the normal PC address spaces: IO and memory */
extern struct resource ioport_resource;
extern struct resource iomem_resource;
......
......@@ -20,9 +20,6 @@
/* Include the pci register defines */
#include <linux/pci_regs.h>
/* Include the ID list */
#include <linux/pci_ids.h>
/*
* The PCI interface treats multi-function devices as independent
* devices. The slot/function address of each device is encoded
......@@ -54,6 +51,9 @@
#include <asm/atomic.h>
#include <linux/device.h>
/* Include the ID list */
#include <linux/pci_ids.h>
/* File state for mmap()s on /proc/bus/pci/X/Y */
enum pci_mmap_state {
pci_mmap_io,
......@@ -396,6 +396,21 @@ struct pci_driver {
*/
#define pci_module_init pci_register_driver
/**
* PCI_VDEVICE - macro used to describe a specific pci device in short form
* @vend: the vendor name
* @dev: the 16 bit PCI Device ID
*
* This macro is used to create a struct pci_device_id that matches a
* specific PCI device. The subvendor, and subdevice fields will be set
* to PCI_ANY_ID. The macro allows the next field to follow as the device
* private data.
*/
#define PCI_VDEVICE(vendor, device) \
PCI_VENDOR_ID_##vendor, (device), \
PCI_ANY_ID, PCI_ANY_ID, 0, 0
/* these external functions are only available when PCI support is enabled */
#ifdef CONFIG_PCI
......@@ -454,6 +469,8 @@ struct pci_dev *pci_find_slot (unsigned int bus, unsigned int devfn);
int pci_find_capability (struct pci_dev *dev, int cap);
int pci_find_next_capability (struct pci_dev *dev, u8 pos, int cap);
int pci_find_ext_capability (struct pci_dev *dev, int cap);
int pci_find_ht_capability (struct pci_dev *dev, int ht_cap);
int pci_find_next_ht_capability (struct pci_dev *dev, int pos, int ht_cap);
struct pci_bus *pci_find_next_bus(const struct pci_bus *from);
struct pci_dev *pci_get_device(unsigned int vendor, unsigned int device,
......@@ -468,6 +485,7 @@ struct pci_dev *pci_get_slot (struct pci_bus *bus, unsigned int devfn);
struct pci_dev *pci_get_bus_and_slot (unsigned int bus, unsigned int devfn);
struct pci_dev *pci_get_class (unsigned int class, struct pci_dev *from);
int pci_dev_present(const struct pci_device_id *ids);
const struct pci_device_id *pci_find_present(const struct pci_device_id *ids);
int pci_bus_read_config_byte (struct pci_bus *bus, unsigned int devfn, int where, u8 *val);
int pci_bus_read_config_word (struct pci_bus *bus, unsigned int devfn, int where, u16 *val);
......@@ -681,6 +699,7 @@ static inline struct pci_dev *pci_get_class(unsigned int class, struct pci_dev *
{ return NULL; }
#define pci_dev_present(ids) (0)
#define pci_find_present(ids) (NULL)
#define pci_dev_put(dev) do { } while (0)
static inline void pci_set_master(struct pci_dev *dev) { }
......@@ -783,6 +802,7 @@ enum pci_fixup_pass {
pci_fixup_header, /* After reading configuration header */
pci_fixup_final, /* Final phase of device fixups */
pci_fixup_enable, /* pci_enable_device() time */
pci_fixup_resume, /* pci_enable_device() time */
};
/* Anonymous variables would be nice... */
......@@ -801,6 +821,9 @@ enum pci_fixup_pass {
#define DECLARE_PCI_FIXUP_ENABLE(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_enable, \
vendor##device##hook, vendor, device, hook)
#define DECLARE_PCI_FIXUP_RESUME(vendor, device, hook) \
DECLARE_PCI_FIXUP_SECTION(.pci_fixup_resume, \
resume##vendor##device##hook, vendor, device, hook)
void pci_fixup_device(enum pci_fixup_pass pass, struct pci_dev *dev);
......
......@@ -104,6 +104,10 @@
#define PCI_CLASS_SERIAL_FIBER 0x0c04
#define PCI_CLASS_SERIAL_SMBUS 0x0c05
#define PCI_BASE_CLASS_WIRELESS 0x0d
#define PCI_CLASS_WIRELESS_RF_CONTROLLER 0x0d10
#define PCI_CLASS_WIRELESS_WHCI 0x0d1010
#define PCI_BASE_CLASS_INTELLIGENT 0x0e
#define PCI_CLASS_INTELLIGENT_I2O 0x0e00
......
......@@ -475,15 +475,32 @@
#define PCI_PWR_CAP 12 /* Capability */
#define PCI_PWR_CAP_BUDGET(x) ((x) & 1) /* Included in system budget */
/* Hypertransport sub capability types */
/*
* Hypertransport sub capability types
*
* Unfortunately there are both 3 bit and 5 bit capability types defined
* in the HT spec, catering for that is a little messy. You probably don't
* want to use these directly, just use pci_find_ht_capability() and it
* will do the right thing for you.
*/
#define HT_3BIT_CAP_MASK 0xE0
#define HT_CAPTYPE_SLAVE 0x00 /* Slave/Primary link configuration */
#define HT_CAPTYPE_HOST 0x20 /* Host/Secondary link configuration */
#define HT_5BIT_CAP_MASK 0xF8
#define HT_CAPTYPE_IRQ 0x80 /* IRQ Configuration */
#define HT_CAPTYPE_REMAPPING_40 0xA0 /* 40 bit address remapping */
#define HT_CAPTYPE_REMAPPING_64 0xA2 /* 64 bit address remapping */
#define HT_CAPTYPE_UNITID_CLUMP 0x90 /* Unit ID clumping */
#define HT_CAPTYPE_EXTCONF 0x98 /* Extended Configuration Space Access */
#define HT_CAPTYPE_MSI_MAPPING 0xA8 /* MSI Mapping Capability */
#define HT_MSI_FLAGS 0x02 /* Offset to flags */
#define HT_MSI_FLAGS_ENABLE 0x1 /* Mapping enable */
#define HT_MSI_FLAGS_FIXED 0x2 /* Fixed mapping only */
#define HT_MSI_FIXED_ADDR 0x00000000FEE00000ULL /* Fixed addr */
#define HT_MSI_ADDR_LO 0x04 /* Offset to low addr bits */
#define HT_MSI_ADDR_LO_MASK 0xFFF00000 /* Low address bit mask */
#define HT_MSI_ADDR_HI 0x08 /* Offset to high addr bits */
#define HT_CAPTYPE_DIRECT_ROUTE 0xB0 /* Direct routing configuration */
#define HT_CAPTYPE_VCSET 0xB8 /* Virtual Channel configuration */
#define HT_CAPTYPE_ERROR_RETRY 0xC0 /* Retry on error configuration */
......
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