730 lines · c
1/* SPDX-License-Identifier: GPL-2.0+ */2/*3 * Compaq Hot Plug Controller Driver4 *5 * Copyright (C) 1995,2001 Compaq Computer Corporation6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)7 * Copyright (C) 2001 IBM8 *9 * All rights reserved.10 *11 * Send feedback to <greg@kroah.com>12 *13 */14#ifndef _CPQPHP_H15#define _CPQPHP_H16 17#include <linux/interrupt.h>18#include <linux/io.h> /* for read? and write? functions */19#include <linux/delay.h> /* for delays */20#include <linux/mutex.h>21#include <linux/sched/signal.h> /* for signal_pending() */22 23#define MY_NAME "cpqphp"24 25#define dbg(fmt, arg...) do { if (cpqhp_debug) printk(KERN_DEBUG "%s: " fmt, MY_NAME, ## arg); } while (0)26#define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME, ## arg)27#define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME, ## arg)28#define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME, ## arg)29 30 31 32struct smbios_system_slot {33 u8 type;34 u8 length;35 u16 handle;36 u8 name_string_num;37 u8 slot_type;38 u8 slot_width;39 u8 slot_current_usage;40 u8 slot_length;41 u16 slot_number;42 u8 properties1;43 u8 properties2;44} __attribute__ ((packed));45 46/* offsets to the smbios generic type based on the above structure layout */47enum smbios_system_slot_offsets {48 SMBIOS_SLOT_GENERIC_TYPE = offsetof(struct smbios_system_slot, type),49 SMBIOS_SLOT_GENERIC_LENGTH = offsetof(struct smbios_system_slot, length),50 SMBIOS_SLOT_GENERIC_HANDLE = offsetof(struct smbios_system_slot, handle),51 SMBIOS_SLOT_NAME_STRING_NUM = offsetof(struct smbios_system_slot, name_string_num),52 SMBIOS_SLOT_TYPE = offsetof(struct smbios_system_slot, slot_type),53 SMBIOS_SLOT_WIDTH = offsetof(struct smbios_system_slot, slot_width),54 SMBIOS_SLOT_CURRENT_USAGE = offsetof(struct smbios_system_slot, slot_current_usage),55 SMBIOS_SLOT_LENGTH = offsetof(struct smbios_system_slot, slot_length),56 SMBIOS_SLOT_NUMBER = offsetof(struct smbios_system_slot, slot_number),57 SMBIOS_SLOT_PROPERTIES1 = offsetof(struct smbios_system_slot, properties1),58 SMBIOS_SLOT_PROPERTIES2 = offsetof(struct smbios_system_slot, properties2),59};60 61struct smbios_generic {62 u8 type;63 u8 length;64 u16 handle;65} __attribute__ ((packed));66 67/* offsets to the smbios generic type based on the above structure layout */68enum smbios_generic_offsets {69 SMBIOS_GENERIC_TYPE = offsetof(struct smbios_generic, type),70 SMBIOS_GENERIC_LENGTH = offsetof(struct smbios_generic, length),71 SMBIOS_GENERIC_HANDLE = offsetof(struct smbios_generic, handle),72};73 74struct smbios_entry_point {75 char anchor[4];76 u8 ep_checksum;77 u8 ep_length;78 u8 major_version;79 u8 minor_version;80 u16 max_size_entry;81 u8 ep_rev;82 u8 reserved[5];83 char int_anchor[5];84 u8 int_checksum;85 u16 st_length;86 u32 st_address;87 u16 number_of_entrys;88 u8 bcd_rev;89} __attribute__ ((packed));90 91/* offsets to the smbios entry point based on the above structure layout */92enum smbios_entry_point_offsets {93 ANCHOR = offsetof(struct smbios_entry_point, anchor[0]),94 EP_CHECKSUM = offsetof(struct smbios_entry_point, ep_checksum),95 EP_LENGTH = offsetof(struct smbios_entry_point, ep_length),96 MAJOR_VERSION = offsetof(struct smbios_entry_point, major_version),97 MINOR_VERSION = offsetof(struct smbios_entry_point, minor_version),98 MAX_SIZE_ENTRY = offsetof(struct smbios_entry_point, max_size_entry),99 EP_REV = offsetof(struct smbios_entry_point, ep_rev),100 INT_ANCHOR = offsetof(struct smbios_entry_point, int_anchor[0]),101 INT_CHECKSUM = offsetof(struct smbios_entry_point, int_checksum),102 ST_LENGTH = offsetof(struct smbios_entry_point, st_length),103 ST_ADDRESS = offsetof(struct smbios_entry_point, st_address),104 NUMBER_OF_ENTRYS = offsetof(struct smbios_entry_point, number_of_entrys),105 BCD_REV = offsetof(struct smbios_entry_point, bcd_rev),106};107 108struct ctrl_reg { /* offset */109 u8 slot_RST; /* 0x00 */110 u8 slot_enable; /* 0x01 */111 u16 misc; /* 0x02 */112 u32 led_control; /* 0x04 */113 u32 int_input_clear; /* 0x08 */114 u32 int_mask; /* 0x0a */115 u8 reserved0; /* 0x10 */116 u8 reserved1; /* 0x11 */117 u8 reserved2; /* 0x12 */118 u8 gen_output_AB; /* 0x13 */119 u32 non_int_input; /* 0x14 */120 u32 reserved3; /* 0x18 */121 u32 reserved4; /* 0x1a */122 u32 reserved5; /* 0x20 */123 u8 reserved6; /* 0x24 */124 u8 reserved7; /* 0x25 */125 u16 reserved8; /* 0x26 */126 u8 slot_mask; /* 0x28 */127 u8 reserved9; /* 0x29 */128 u8 reserved10; /* 0x2a */129 u8 reserved11; /* 0x2b */130 u8 slot_SERR; /* 0x2c */131 u8 slot_power; /* 0x2d */132 u8 reserved12; /* 0x2e */133 u8 reserved13; /* 0x2f */134 u8 next_curr_freq; /* 0x30 */135 u8 reset_freq_mode; /* 0x31 */136} __attribute__ ((packed));137 138/* offsets to the controller registers based on the above structure layout */139enum ctrl_offsets {140 SLOT_RST = offsetof(struct ctrl_reg, slot_RST),141 SLOT_ENABLE = offsetof(struct ctrl_reg, slot_enable),142 MISC = offsetof(struct ctrl_reg, misc),143 LED_CONTROL = offsetof(struct ctrl_reg, led_control),144 INT_INPUT_CLEAR = offsetof(struct ctrl_reg, int_input_clear),145 INT_MASK = offsetof(struct ctrl_reg, int_mask),146 CTRL_RESERVED0 = offsetof(struct ctrl_reg, reserved0),147 CTRL_RESERVED1 = offsetof(struct ctrl_reg, reserved1),148 CTRL_RESERVED2 = offsetof(struct ctrl_reg, reserved1),149 GEN_OUTPUT_AB = offsetof(struct ctrl_reg, gen_output_AB),150 NON_INT_INPUT = offsetof(struct ctrl_reg, non_int_input),151 CTRL_RESERVED3 = offsetof(struct ctrl_reg, reserved3),152 CTRL_RESERVED4 = offsetof(struct ctrl_reg, reserved4),153 CTRL_RESERVED5 = offsetof(struct ctrl_reg, reserved5),154 CTRL_RESERVED6 = offsetof(struct ctrl_reg, reserved6),155 CTRL_RESERVED7 = offsetof(struct ctrl_reg, reserved7),156 CTRL_RESERVED8 = offsetof(struct ctrl_reg, reserved8),157 SLOT_MASK = offsetof(struct ctrl_reg, slot_mask),158 CTRL_RESERVED9 = offsetof(struct ctrl_reg, reserved9),159 CTRL_RESERVED10 = offsetof(struct ctrl_reg, reserved10),160 CTRL_RESERVED11 = offsetof(struct ctrl_reg, reserved11),161 SLOT_SERR = offsetof(struct ctrl_reg, slot_SERR),162 SLOT_POWER = offsetof(struct ctrl_reg, slot_power),163 NEXT_CURR_FREQ = offsetof(struct ctrl_reg, next_curr_freq),164 RESET_FREQ_MODE = offsetof(struct ctrl_reg, reset_freq_mode),165};166 167struct hrt {168 char sig0;169 char sig1;170 char sig2;171 char sig3;172 u16 unused_IRQ;173 u16 PCIIRQ;174 u8 number_of_entries;175 u8 revision;176 u16 reserved1;177 u32 reserved2;178} __attribute__ ((packed));179 180/* offsets to the hotplug resource table registers based on the above181 * structure layout182 */183enum hrt_offsets {184 SIG0 = offsetof(struct hrt, sig0),185 SIG1 = offsetof(struct hrt, sig1),186 SIG2 = offsetof(struct hrt, sig2),187 SIG3 = offsetof(struct hrt, sig3),188 UNUSED_IRQ = offsetof(struct hrt, unused_IRQ),189 PCIIRQ = offsetof(struct hrt, PCIIRQ),190 NUMBER_OF_ENTRIES = offsetof(struct hrt, number_of_entries),191 REVISION = offsetof(struct hrt, revision),192 HRT_RESERVED1 = offsetof(struct hrt, reserved1),193 HRT_RESERVED2 = offsetof(struct hrt, reserved2),194};195 196struct slot_rt {197 u8 dev_func;198 u8 primary_bus;199 u8 secondary_bus;200 u8 max_bus;201 u16 io_base;202 u16 io_length;203 u16 mem_base;204 u16 mem_length;205 u16 pre_mem_base;206 u16 pre_mem_length;207} __attribute__ ((packed));208 209/* offsets to the hotplug slot resource table registers based on the above210 * structure layout211 */212enum slot_rt_offsets {213 DEV_FUNC = offsetof(struct slot_rt, dev_func),214 PRIMARY_BUS = offsetof(struct slot_rt, primary_bus),215 SECONDARY_BUS = offsetof(struct slot_rt, secondary_bus),216 MAX_BUS = offsetof(struct slot_rt, max_bus),217 IO_BASE = offsetof(struct slot_rt, io_base),218 IO_LENGTH = offsetof(struct slot_rt, io_length),219 MEM_BASE = offsetof(struct slot_rt, mem_base),220 MEM_LENGTH = offsetof(struct slot_rt, mem_length),221 PRE_MEM_BASE = offsetof(struct slot_rt, pre_mem_base),222 PRE_MEM_LENGTH = offsetof(struct slot_rt, pre_mem_length),223};224 225struct pci_func {226 struct pci_func *next;227 u8 bus;228 u8 device;229 u8 function;230 u8 is_a_board;231 u16 status;232 u8 configured;233 u8 switch_save;234 u8 presence_save;235 u32 base_length[0x06];236 u8 base_type[0x06];237 u16 reserved2;238 u32 config_space[0x20];239 struct pci_resource *mem_head;240 struct pci_resource *p_mem_head;241 struct pci_resource *io_head;242 struct pci_resource *bus_head;243 struct timer_list *p_task_event;244 struct pci_dev *pci_dev;245};246 247struct slot {248 struct slot *next;249 u8 bus;250 u8 device;251 u8 number;252 u8 is_a_board;253 u8 configured;254 u8 state;255 u8 switch_save;256 u8 presence_save;257 u32 capabilities;258 u16 reserved2;259 struct timer_list task_event;260 u8 hp_slot;261 struct controller *ctrl;262 void __iomem *p_sm_slot;263 struct hotplug_slot hotplug_slot;264};265 266struct pci_resource {267 struct pci_resource *next;268 u32 base;269 u32 length;270};271 272struct event_info {273 u32 event_type;274 u8 hp_slot;275};276 277struct controller {278 struct controller *next;279 u32 ctrl_int_comp;280 struct mutex crit_sect; /* critical section mutex */281 void __iomem *hpc_reg; /* cookie for our pci controller location */282 struct pci_resource *mem_head;283 struct pci_resource *p_mem_head;284 struct pci_resource *io_head;285 struct pci_resource *bus_head;286 struct pci_dev *pci_dev;287 struct pci_bus *pci_bus;288 struct event_info event_queue[10];289 struct slot *slot;290 u8 next_event;291 u8 interrupt;292 u8 cfgspc_irq;293 u8 bus; /* bus number for the pci hotplug controller */294 u8 rev;295 u8 slot_device_offset;296 u8 first_slot;297 u8 add_support;298 u8 push_flag;299 u8 push_button; /* 0 = no pushbutton, 1 = pushbutton present */300 u8 slot_switch_type; /* 0 = no switch, 1 = switch present */301 u8 defeature_PHP; /* 0 = PHP not supported, 1 = PHP supported */302 u8 alternate_base_address; /* 0 = not supported, 1 = supported */303 u8 pci_config_space; /* Index/data access to working registers 0 = not supported, 1 = supported */304 u8 pcix_speed_capability; /* PCI-X */305 u8 pcix_support; /* PCI-X */306 u16 vendor_id;307 struct work_struct int_task_event;308 wait_queue_head_t queue; /* sleep & wake process */309 struct dentry *dentry; /* debugfs dentry */310};311 312struct irq_mapping {313 u8 barber_pole;314 u8 valid_INT;315 u8 interrupt[4];316};317 318struct resource_lists {319 struct pci_resource *mem_head;320 struct pci_resource *p_mem_head;321 struct pci_resource *io_head;322 struct pci_resource *bus_head;323 struct irq_mapping *irqs;324};325 326#define ROM_PHY_ADDR 0x0F0000327#define ROM_PHY_LEN 0x00ffff328 329#define PCI_HPC_ID 0xA0F7330#define PCI_SUB_HPC_ID 0xA2F7331#define PCI_SUB_HPC_ID2 0xA2F8332#define PCI_SUB_HPC_ID3 0xA2F9333#define PCI_SUB_HPC_ID_INTC 0xA2FA334#define PCI_SUB_HPC_ID4 0xA2FD335 336#define INT_BUTTON_IGNORE 0337#define INT_PRESENCE_ON 1338#define INT_PRESENCE_OFF 2339#define INT_SWITCH_CLOSE 3340#define INT_SWITCH_OPEN 4341#define INT_POWER_FAULT 5342#define INT_POWER_FAULT_CLEAR 6343#define INT_BUTTON_PRESS 7344#define INT_BUTTON_RELEASE 8345#define INT_BUTTON_CANCEL 9346 347#define STATIC_STATE 0348#define BLINKINGON_STATE 1349#define BLINKINGOFF_STATE 2350#define POWERON_STATE 3351#define POWEROFF_STATE 4352 353#define PCISLOT_INTERLOCK_CLOSED 0x00000001354#define PCISLOT_ADAPTER_PRESENT 0x00000002355#define PCISLOT_POWERED 0x00000004356#define PCISLOT_66_MHZ_OPERATION 0x00000008357#define PCISLOT_64_BIT_OPERATION 0x00000010358#define PCISLOT_REPLACE_SUPPORTED 0x00000020359#define PCISLOT_ADD_SUPPORTED 0x00000040360#define PCISLOT_INTERLOCK_SUPPORTED 0x00000080361#define PCISLOT_66_MHZ_SUPPORTED 0x00000100362#define PCISLOT_64_BIT_SUPPORTED 0x00000200363 364#define PCI_TO_PCI_BRIDGE_CLASS 0x00060400365 366#define INTERLOCK_OPEN 0x00000002367#define ADD_NOT_SUPPORTED 0x00000003368#define CARD_FUNCTIONING 0x00000005369#define ADAPTER_NOT_SAME 0x00000006370#define NO_ADAPTER_PRESENT 0x00000009371#define NOT_ENOUGH_RESOURCES 0x0000000B372#define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C373#define POWER_FAILURE 0x0000000E374 375#define REMOVE_NOT_SUPPORTED 0x00000003376 377 378/*379 * error Messages380 */381#define msg_initialization_err "Initialization failure, error=%d\n"382#define msg_HPC_rev_error "Unsupported revision of the PCI hot plug controller found.\n"383#define msg_HPC_non_compaq_or_intel "The PCI hot plug controller is not supported by this driver.\n"384#define msg_HPC_not_supported "this system is not supported by this version of cpqphpd. Upgrade to a newer version of cpqphpd\n"385#define msg_unable_to_save "unable to store PCI hot plug add resource information. This system must be rebooted before adding any PCI devices.\n"386#define msg_button_on "PCI slot #%d - powering on due to button press.\n"387#define msg_button_off "PCI slot #%d - powering off due to button press.\n"388#define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n"389#define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n"390 391 392/* debugfs functions for the hotplug controller info */393void cpqhp_initialize_debugfs(void);394void cpqhp_shutdown_debugfs(void);395void cpqhp_create_debugfs_files(struct controller *ctrl);396void cpqhp_remove_debugfs_files(struct controller *ctrl);397 398/* controller functions */399void cpqhp_pushbutton_thread(struct timer_list *t);400irqreturn_t cpqhp_ctrl_intr(int IRQ, void *data);401int cpqhp_find_available_resources(struct controller *ctrl,402 void __iomem *rom_start);403int cpqhp_event_start_thread(void);404void cpqhp_event_stop_thread(void);405struct pci_func *cpqhp_slot_create(unsigned char busnumber);406struct pci_func *cpqhp_slot_find(unsigned char bus, unsigned char device,407 unsigned char index);408int cpqhp_process_SI(struct controller *ctrl, struct pci_func *func);409int cpqhp_process_SS(struct controller *ctrl, struct pci_func *func);410int cpqhp_hardware_test(struct controller *ctrl, int test_num);411 412/* resource functions */413int cpqhp_resource_sort_and_combine(struct pci_resource **head);414 415/* pci functions */416int cpqhp_set_irq(u8 bus_num, u8 dev_num, u8 int_pin, u8 irq_num);417int cpqhp_get_bus_dev(struct controller *ctrl, u8 *bus_num, u8 *dev_num,418 u8 slot);419int cpqhp_save_config(struct controller *ctrl, int busnumber, int is_hot_plug);420int cpqhp_save_base_addr_length(struct controller *ctrl, struct pci_func *func);421int cpqhp_save_used_resources(struct controller *ctrl, struct pci_func *func);422int cpqhp_configure_board(struct controller *ctrl, struct pci_func *func);423int cpqhp_save_slot_config(struct controller *ctrl, struct pci_func *new_slot);424int cpqhp_valid_replace(struct controller *ctrl, struct pci_func *func);425void cpqhp_destroy_board_resources(struct pci_func *func);426int cpqhp_return_board_resources(struct pci_func *func,427 struct resource_lists *resources);428void cpqhp_destroy_resource_list(struct resource_lists *resources);429int cpqhp_configure_device(struct controller *ctrl, struct pci_func *func);430int cpqhp_unconfigure_device(struct pci_func *func);431 432/* Global variables */433extern int cpqhp_debug;434extern int cpqhp_legacy_mode;435extern struct controller *cpqhp_ctrl_list;436extern struct pci_func *cpqhp_slot_list[256];437extern struct irq_routing_table *cpqhp_routing_table;438 439/* these can be gotten rid of, but for debugging they are purty */440extern u8 cpqhp_nic_irq;441extern u8 cpqhp_disk_irq;442 443 444/* inline functions */445 446static inline const char *slot_name(struct slot *slot)447{448 return hotplug_slot_name(&slot->hotplug_slot);449}450 451static inline struct slot *to_slot(struct hotplug_slot *hotplug_slot)452{453 return container_of(hotplug_slot, struct slot, hotplug_slot);454}455 456/*457 * return_resource458 *459 * Puts node back in the resource list pointed to by head460 */461static inline void return_resource(struct pci_resource **head,462 struct pci_resource *node)463{464 if (!node || !head)465 return;466 node->next = *head;467 *head = node;468}469 470static inline void set_SOGO(struct controller *ctrl)471{472 u16 misc;473 474 misc = readw(ctrl->hpc_reg + MISC);475 misc = (misc | 0x0001) & 0xFFFB;476 writew(misc, ctrl->hpc_reg + MISC);477}478 479 480static inline void amber_LED_on(struct controller *ctrl, u8 slot)481{482 u32 led_control;483 484 led_control = readl(ctrl->hpc_reg + LED_CONTROL);485 led_control |= (0x01010000L << slot);486 writel(led_control, ctrl->hpc_reg + LED_CONTROL);487}488 489 490static inline void amber_LED_off(struct controller *ctrl, u8 slot)491{492 u32 led_control;493 494 led_control = readl(ctrl->hpc_reg + LED_CONTROL);495 led_control &= ~(0x01010000L << slot);496 writel(led_control, ctrl->hpc_reg + LED_CONTROL);497}498 499 500static inline int read_amber_LED(struct controller *ctrl, u8 slot)501{502 u32 led_control;503 504 led_control = readl(ctrl->hpc_reg + LED_CONTROL);505 led_control &= (0x01010000L << slot);506 507 return led_control ? 1 : 0;508}509 510 511static inline void green_LED_on(struct controller *ctrl, u8 slot)512{513 u32 led_control;514 515 led_control = readl(ctrl->hpc_reg + LED_CONTROL);516 led_control |= 0x0101L << slot;517 writel(led_control, ctrl->hpc_reg + LED_CONTROL);518}519 520static inline void green_LED_off(struct controller *ctrl, u8 slot)521{522 u32 led_control;523 524 led_control = readl(ctrl->hpc_reg + LED_CONTROL);525 led_control &= ~(0x0101L << slot);526 writel(led_control, ctrl->hpc_reg + LED_CONTROL);527}528 529 530static inline void green_LED_blink(struct controller *ctrl, u8 slot)531{532 u32 led_control;533 534 led_control = readl(ctrl->hpc_reg + LED_CONTROL);535 led_control &= ~(0x0101L << slot);536 led_control |= (0x0001L << slot);537 writel(led_control, ctrl->hpc_reg + LED_CONTROL);538}539 540 541static inline void slot_disable(struct controller *ctrl, u8 slot)542{543 u8 slot_enable;544 545 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);546 slot_enable &= ~(0x01 << slot);547 writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);548}549 550 551static inline void slot_enable(struct controller *ctrl, u8 slot)552{553 u8 slot_enable;554 555 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);556 slot_enable |= (0x01 << slot);557 writeb(slot_enable, ctrl->hpc_reg + SLOT_ENABLE);558}559 560 561static inline u8 is_slot_enabled(struct controller *ctrl, u8 slot)562{563 u8 slot_enable;564 565 slot_enable = readb(ctrl->hpc_reg + SLOT_ENABLE);566 slot_enable &= (0x01 << slot);567 return slot_enable ? 1 : 0;568}569 570 571static inline u8 read_slot_enable(struct controller *ctrl)572{573 return readb(ctrl->hpc_reg + SLOT_ENABLE);574}575 576 577/**578 * get_controller_speed - find the current frequency/mode of controller.579 *580 * @ctrl: controller to get frequency/mode for.581 *582 * Returns controller speed.583 */584static inline u8 get_controller_speed(struct controller *ctrl)585{586 u8 curr_freq;587 u16 misc;588 589 if (ctrl->pcix_support) {590 curr_freq = readb(ctrl->hpc_reg + NEXT_CURR_FREQ);591 if ((curr_freq & 0xB0) == 0xB0)592 return PCI_SPEED_133MHz_PCIX;593 if ((curr_freq & 0xA0) == 0xA0)594 return PCI_SPEED_100MHz_PCIX;595 if ((curr_freq & 0x90) == 0x90)596 return PCI_SPEED_66MHz_PCIX;597 if (curr_freq & 0x10)598 return PCI_SPEED_66MHz;599 600 return PCI_SPEED_33MHz;601 }602 603 misc = readw(ctrl->hpc_reg + MISC);604 return (misc & 0x0800) ? PCI_SPEED_66MHz : PCI_SPEED_33MHz;605}606 607 608/**609 * get_adapter_speed - find the max supported frequency/mode of adapter.610 *611 * @ctrl: hotplug controller.612 * @hp_slot: hotplug slot where adapter is installed.613 *614 * Returns adapter speed.615 */616static inline u8 get_adapter_speed(struct controller *ctrl, u8 hp_slot)617{618 u32 temp_dword = readl(ctrl->hpc_reg + NON_INT_INPUT);619 dbg("slot: %d, PCIXCAP: %8x\n", hp_slot, temp_dword);620 if (ctrl->pcix_support) {621 if (temp_dword & (0x10000 << hp_slot))622 return PCI_SPEED_133MHz_PCIX;623 if (temp_dword & (0x100 << hp_slot))624 return PCI_SPEED_66MHz_PCIX;625 }626 627 if (temp_dword & (0x01 << hp_slot))628 return PCI_SPEED_66MHz;629 630 return PCI_SPEED_33MHz;631}632 633static inline void enable_slot_power(struct controller *ctrl, u8 slot)634{635 u8 slot_power;636 637 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);638 slot_power |= (0x01 << slot);639 writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);640}641 642static inline void disable_slot_power(struct controller *ctrl, u8 slot)643{644 u8 slot_power;645 646 slot_power = readb(ctrl->hpc_reg + SLOT_POWER);647 slot_power &= ~(0x01 << slot);648 writeb(slot_power, ctrl->hpc_reg + SLOT_POWER);649}650 651 652static inline int cpq_get_attention_status(struct controller *ctrl, struct slot *slot)653{654 u8 hp_slot;655 656 hp_slot = slot->device - ctrl->slot_device_offset;657 658 return read_amber_LED(ctrl, hp_slot);659}660 661 662static inline int get_slot_enabled(struct controller *ctrl, struct slot *slot)663{664 u8 hp_slot;665 666 hp_slot = slot->device - ctrl->slot_device_offset;667 668 return is_slot_enabled(ctrl, hp_slot);669}670 671 672static inline int cpq_get_latch_status(struct controller *ctrl,673 struct slot *slot)674{675 u32 status;676 u8 hp_slot;677 678 hp_slot = slot->device - ctrl->slot_device_offset;679 dbg("%s: slot->device = %d, ctrl->slot_device_offset = %d\n",680 __func__, slot->device, ctrl->slot_device_offset);681 682 status = (readl(ctrl->hpc_reg + INT_INPUT_CLEAR) & (0x01L << hp_slot));683 684 return (status == 0) ? 1 : 0;685}686 687 688static inline int get_presence_status(struct controller *ctrl,689 struct slot *slot)690{691 int presence_save = 0;692 u8 hp_slot;693 u32 tempdword;694 695 hp_slot = slot->device - ctrl->slot_device_offset;696 697 tempdword = readl(ctrl->hpc_reg + INT_INPUT_CLEAR);698 presence_save = (int) ((((~tempdword) >> 23) | ((~tempdword) >> 15))699 >> hp_slot) & 0x02;700 701 return presence_save;702}703 704static inline int wait_for_ctrl_irq(struct controller *ctrl)705{706 DECLARE_WAITQUEUE(wait, current);707 int retval = 0;708 709 dbg("%s - start\n", __func__);710 add_wait_queue(&ctrl->queue, &wait);711 /* Sleep for up to 1 second to wait for the LED to change. */712 msleep_interruptible(1000);713 remove_wait_queue(&ctrl->queue, &wait);714 if (signal_pending(current))715 retval = -EINTR;716 717 dbg("%s - end\n", __func__);718 return retval;719}720 721#include <asm/pci_x86.h>722static inline int cpqhp_routing_table_length(void)723{724 BUG_ON(cpqhp_routing_table == NULL);725 return ((cpqhp_routing_table->size - sizeof(struct irq_routing_table)) /726 sizeof(struct irq_info));727}728 729#endif730