1 /* 2 * PCI Express Hot Plug Controller Driver 3 * 4 * Copyright (C) 1995,2001 Compaq Computer Corporation 5 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com) 6 * Copyright (C) 2001 IBM Corp. 7 * Copyright (C) 2003-2004 Intel Corporation 8 * 9 * All rights reserved. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or (at 14 * your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, but 17 * WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 19 * NON INFRINGEMENT. See the GNU General Public License for more 20 * details. 21 * 22 * You should have received a copy of the GNU General Public License 23 * along with this program; if not, write to the Free Software 24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 25 * 26 * Send feedback to <greg@kroah.com>, <kristen.c.accardi@intel.com> 27 * 28 */ 29 #ifndef _PCIEHP_H 30 #define _PCIEHP_H 31 32 #include <linux/types.h> 33 #include <linux/pci.h> 34 #include <linux/delay.h> 35 #include <linux/sched.h> /* signal_pending() */ 36 #include <linux/pcieport_if.h> 37 #include "pci_hotplug.h" 38 39 #define MY_NAME "pciehp" 40 41 extern int pciehp_poll_mode; 42 extern int pciehp_poll_time; 43 extern int pciehp_debug; 44 extern int pciehp_force; 45 46 /*#define dbg(format, arg...) do { if (pciehp_debug) printk(KERN_DEBUG "%s: " format, MY_NAME , ## arg); } while (0)*/ 47 #define dbg(format, arg...) do { if (pciehp_debug) printk("%s: " format, MY_NAME , ## arg); } while (0) 48 #define err(format, arg...) printk(KERN_ERR "%s: " format, MY_NAME , ## arg) 49 #define info(format, arg...) printk(KERN_INFO "%s: " format, MY_NAME , ## arg) 50 #define warn(format, arg...) printk(KERN_WARNING "%s: " format, MY_NAME , ## arg) 51 52 struct hotplug_params { 53 u8 cache_line_size; 54 u8 latency_timer; 55 u8 enable_serr; 56 u8 enable_perr; 57 }; 58 59 struct slot { 60 struct slot *next; 61 u8 bus; 62 u8 device; 63 u32 number; 64 u8 state; 65 struct timer_list task_event; 66 u8 hp_slot; 67 struct controller *ctrl; 68 struct hpc_ops *hpc_ops; 69 struct hotplug_slot *hotplug_slot; 70 struct list_head slot_list; 71 }; 72 73 struct event_info { 74 u32 event_type; 75 u8 hp_slot; 76 }; 77 78 typedef u8(*php_intr_callback_t) (u8 hp_slot, void *instance_id); 79 80 struct php_ctlr_state_s { 81 struct php_ctlr_state_s *pnext; 82 struct pci_dev *pci_dev; 83 unsigned int irq; 84 unsigned long flags; /* spinlock's */ 85 u32 slot_device_offset; 86 u32 num_slots; 87 struct timer_list int_poll_timer; /* Added for poll event */ 88 php_intr_callback_t attention_button_callback; 89 php_intr_callback_t switch_change_callback; 90 php_intr_callback_t presence_change_callback; 91 php_intr_callback_t power_fault_callback; 92 void *callback_instance_id; 93 struct ctrl_reg *creg; /* Ptr to controller register space */ 94 }; 95 96 #define MAX_EVENTS 10 97 struct controller { 98 struct controller *next; 99 struct semaphore crit_sect; /* critical section semaphore */ 100 struct php_ctlr_state_s *hpc_ctlr_handle; /* HPC controller handle */ 101 int num_slots; /* Number of slots on ctlr */ 102 int slot_num_inc; /* 1 or -1 */ 103 struct pci_dev *pci_dev; 104 struct pci_bus *pci_bus; 105 struct event_info event_queue[MAX_EVENTS]; 106 struct slot *slot; 107 struct hpc_ops *hpc_ops; 108 wait_queue_head_t queue; /* sleep & wake process */ 109 u8 next_event; 110 u8 bus; 111 u8 device; 112 u8 function; 113 u8 slot_device_offset; 114 u32 first_slot; /* First physical slot number */ /* PCIE only has 1 slot */ 115 u8 slot_bus; /* Bus where the slots handled by this controller sit */ 116 u8 ctrlcap; 117 u16 vendor_id; 118 u8 cap_base; 119 }; 120 121 #define INT_BUTTON_IGNORE 0 122 #define INT_PRESENCE_ON 1 123 #define INT_PRESENCE_OFF 2 124 #define INT_SWITCH_CLOSE 3 125 #define INT_SWITCH_OPEN 4 126 #define INT_POWER_FAULT 5 127 #define INT_POWER_FAULT_CLEAR 6 128 #define INT_BUTTON_PRESS 7 129 #define INT_BUTTON_RELEASE 8 130 #define INT_BUTTON_CANCEL 9 131 132 #define STATIC_STATE 0 133 #define BLINKINGON_STATE 1 134 #define BLINKINGOFF_STATE 2 135 #define POWERON_STATE 3 136 #define POWEROFF_STATE 4 137 138 #define PCI_TO_PCI_BRIDGE_CLASS 0x00060400 139 140 /* Error messages */ 141 #define INTERLOCK_OPEN 0x00000002 142 #define ADD_NOT_SUPPORTED 0x00000003 143 #define CARD_FUNCTIONING 0x00000005 144 #define ADAPTER_NOT_SAME 0x00000006 145 #define NO_ADAPTER_PRESENT 0x00000009 146 #define NOT_ENOUGH_RESOURCES 0x0000000B 147 #define DEVICE_TYPE_NOT_SUPPORTED 0x0000000C 148 #define WRONG_BUS_FREQUENCY 0x0000000D 149 #define POWER_FAILURE 0x0000000E 150 151 #define REMOVE_NOT_SUPPORTED 0x00000003 152 153 #define DISABLE_CARD 1 154 155 /* Field definitions in Slot Capabilities Register */ 156 #define ATTN_BUTTN_PRSN 0x00000001 157 #define PWR_CTRL_PRSN 0x00000002 158 #define MRL_SENS_PRSN 0x00000004 159 #define ATTN_LED_PRSN 0x00000008 160 #define PWR_LED_PRSN 0x00000010 161 #define HP_SUPR_RM_SUP 0x00000020 162 163 #define ATTN_BUTTN(cap) (cap & ATTN_BUTTN_PRSN) 164 #define POWER_CTRL(cap) (cap & PWR_CTRL_PRSN) 165 #define MRL_SENS(cap) (cap & MRL_SENS_PRSN) 166 #define ATTN_LED(cap) (cap & ATTN_LED_PRSN) 167 #define PWR_LED(cap) (cap & PWR_LED_PRSN) 168 #define HP_SUPR_RM(cap) (cap & HP_SUPR_RM_SUP) 169 170 /* 171 * error Messages 172 */ 173 #define msg_initialization_err "Initialization failure, error=%d\n" 174 #define msg_button_on "PCI slot #%d - powering on due to button press.\n" 175 #define msg_button_off "PCI slot #%d - powering off due to button press.\n" 176 #define msg_button_cancel "PCI slot #%d - action canceled due to button press.\n" 177 #define msg_button_ignore "PCI slot #%d - button press ignored. (action in progress...)\n" 178 179 /* controller functions */ 180 extern int pciehp_event_start_thread (void); 181 extern void pciehp_event_stop_thread (void); 182 extern int pciehp_enable_slot (struct slot *slot); 183 extern int pciehp_disable_slot (struct slot *slot); 184 185 extern u8 pciehp_handle_attention_button (u8 hp_slot, void *inst_id); 186 extern u8 pciehp_handle_switch_change (u8 hp_slot, void *inst_id); 187 extern u8 pciehp_handle_presence_change (u8 hp_slot, void *inst_id); 188 extern u8 pciehp_handle_power_fault (u8 hp_slot, void *inst_id); 189 /* extern void long_delay (int delay); */ 190 191 /* pci functions */ 192 extern int pciehp_configure_device (struct slot *p_slot); 193 extern int pciehp_unconfigure_device (struct slot *p_slot); 194 extern int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev); 195 extern void pciehp_get_hp_params_from_firmware(struct pci_dev *dev, 196 struct hotplug_params *hpp); 197 198 199 200 /* Global variables */ 201 extern struct controller *pciehp_ctrl_list; 202 203 /* Inline functions */ 204 205 static inline struct slot *pciehp_find_slot(struct controller *ctrl, u8 device) 206 { 207 struct slot *p_slot, *tmp_slot = NULL; 208 209 p_slot = ctrl->slot; 210 211 while (p_slot && (p_slot->device != device)) { 212 tmp_slot = p_slot; 213 p_slot = p_slot->next; 214 } 215 if (p_slot == NULL) { 216 err("ERROR: pciehp_find_slot device=0x%x\n", device); 217 p_slot = tmp_slot; 218 } 219 220 return p_slot; 221 } 222 223 static inline int wait_for_ctrl_irq(struct controller *ctrl) 224 { 225 int retval = 0; 226 227 DECLARE_WAITQUEUE(wait, current); 228 229 add_wait_queue(&ctrl->queue, &wait); 230 if (!pciehp_poll_mode) 231 /* Sleep for up to 1 second */ 232 msleep_interruptible(1000); 233 else 234 msleep_interruptible(2500); 235 236 remove_wait_queue(&ctrl->queue, &wait); 237 if (signal_pending(current)) 238 retval = -EINTR; 239 240 return retval; 241 } 242 243 #define SLOT_NAME_SIZE 10 244 245 static inline void make_slot_name(char *buffer, int buffer_size, struct slot *slot) 246 { 247 snprintf(buffer, buffer_size, "%04d_%04d", slot->bus, slot->number); 248 } 249 250 enum php_ctlr_type { 251 PCI, 252 ISA, 253 ACPI 254 }; 255 256 int pcie_init(struct controller *ctrl, struct pcie_device *dev); 257 258 /* This has no meaning for PCI Express, as there is only 1 slot per port */ 259 int pcie_get_ctlr_slot_config(struct controller *ctrl, 260 int *num_ctlr_slots, 261 int *first_device_num, 262 int *physical_slot_num, 263 u8 *ctrlcap); 264 265 struct hpc_ops { 266 int (*power_on_slot) (struct slot *slot); 267 int (*power_off_slot) (struct slot *slot); 268 int (*get_power_status) (struct slot *slot, u8 *status); 269 int (*get_attention_status) (struct slot *slot, u8 *status); 270 int (*set_attention_status) (struct slot *slot, u8 status); 271 int (*get_latch_status) (struct slot *slot, u8 *status); 272 int (*get_adapter_status) (struct slot *slot, u8 *status); 273 274 int (*get_max_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); 275 int (*get_cur_bus_speed) (struct slot *slot, enum pci_bus_speed *speed); 276 277 int (*get_max_lnk_width) (struct slot *slot, enum pcie_link_width *value); 278 int (*get_cur_lnk_width) (struct slot *slot, enum pcie_link_width *value); 279 280 int (*query_power_fault) (struct slot *slot); 281 void (*green_led_on) (struct slot *slot); 282 void (*green_led_off) (struct slot *slot); 283 void (*green_led_blink) (struct slot *slot); 284 void (*release_ctlr) (struct controller *ctrl); 285 int (*check_lnk_status) (struct controller *ctrl); 286 }; 287 288 #endif /* _PCIEHP_H */ 289