linux/drivers/pci/hotplug/cpqphp.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0+ */
   2/*
   3 * Compaq Hot Plug Controller Driver
   4 *
   5 * Copyright (C) 1995,2001 Compaq Computer Corporation
   6 * Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
   7 * Copyright (C) 2001 IBM
   8 *
   9 * All rights reserved.
  10 *
  11 * Send feedback to <greg@kroah.com>
  12 *
  13 */
  14#ifndef _CPQPHP_H
  15#define _CPQPHP_H
  16
  17#include <linux/interrupt.h>
  18#include <asm/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 above
 181 * structure layout
 182 */
 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 above
 210 * structure layout
 211 */
 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                    0x0F0000
 327#define ROM_PHY_LEN                     0x00ffff
 328
 329#define PCI_HPC_ID                      0xA0F7
 330#define PCI_SUB_HPC_ID                  0xA2F7
 331#define PCI_SUB_HPC_ID2                 0xA2F8
 332#define PCI_SUB_HPC_ID3                 0xA2F9
 333#define PCI_SUB_HPC_ID_INTC             0xA2FA
 334#define PCI_SUB_HPC_ID4                 0xA2FD
 335
 336#define INT_BUTTON_IGNORE               0
 337#define INT_PRESENCE_ON                 1
 338#define INT_PRESENCE_OFF                2
 339#define INT_SWITCH_CLOSE                3
 340#define INT_SWITCH_OPEN                 4
 341#define INT_POWER_FAULT                 5
 342#define INT_POWER_FAULT_CLEAR           6
 343#define INT_BUTTON_PRESS                7
 344#define INT_BUTTON_RELEASE              8
 345#define INT_BUTTON_CANCEL               9
 346
 347#define STATIC_STATE                    0
 348#define BLINKINGON_STATE                1
 349#define BLINKINGOFF_STATE               2
 350#define POWERON_STATE                   3
 351#define POWEROFF_STATE                  4
 352
 353#define PCISLOT_INTERLOCK_CLOSED        0x00000001
 354#define PCISLOT_ADAPTER_PRESENT         0x00000002
 355#define PCISLOT_POWERED                 0x00000004
 356#define PCISLOT_66_MHZ_OPERATION        0x00000008
 357#define PCISLOT_64_BIT_OPERATION        0x00000010
 358#define PCISLOT_REPLACE_SUPPORTED       0x00000020
 359#define PCISLOT_ADD_SUPPORTED           0x00000040
 360#define PCISLOT_INTERLOCK_SUPPORTED     0x00000080
 361#define PCISLOT_66_MHZ_SUPPORTED        0x00000100
 362#define PCISLOT_64_BIT_SUPPORTED        0x00000200
 363
 364#define PCI_TO_PCI_BRIDGE_CLASS         0x00060400
 365
 366#define INTERLOCK_OPEN                  0x00000002
 367#define ADD_NOT_SUPPORTED               0x00000003
 368#define CARD_FUNCTIONING                0x00000005
 369#define ADAPTER_NOT_SAME                0x00000006
 370#define NO_ADAPTER_PRESENT              0x00000009
 371#define NOT_ENOUGH_RESOURCES            0x0000000B
 372#define DEVICE_TYPE_NOT_SUPPORTED       0x0000000C
 373#define POWER_FAILURE                   0x0000000E
 374
 375#define REMOVE_NOT_SUPPORTED            0x00000003
 376
 377
 378/*
 379 * error Messages
 380 */
 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_resource
 458 *
 459 * Puts node back in the resource list pointed to by head
 460 */
 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#endif
 730