/*
* Standard PCI Hot Plug Driver
*
* Copyright (C) 1995,2001 Compaq Computer Corporation
* Copyright (C) 2001 Greg Kroah-Hartman (greg@kroah.com)
* Copyright (C) 2001 IBM Corp.
* Copyright (C) 2003-2004 Intel Corporation
*
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for more
* details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Send feedback to <greg@kroah.com>,<kristen.c.accardi@intel.com>
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/interrupt.h>
#include "shpchp.h"
#ifdef DEBUG
#define DBG_K_TRACE_ENTRY ((unsigned int)0x00000001) /* On function entry */
#define DBG_K_TRACE_EXIT ((unsigned int)0x00000002) /* On function exit */
#define DBG_K_INFO ((unsigned int)0x00000004) /* Info messages */
#define DBG_K_ERROR ((unsigned int)0x00000008) /* Error messages */
#define DBG_K_TRACE (DBG_K_TRACE_ENTRY|DBG_K_TRACE_EXIT)
#define DBG_K_STANDARD (DBG_K_INFO|DBG_K_ERROR|DBG_K_TRACE)
/* Redefine this flagword to set debug level */
#define DEBUG_LEVEL DBG_K_STANDARD
#define DEFINE_DBG_BUFFER char __dbg_str_buf[256];
#define DBG_PRINT( dbg_flags, args... ) \
do { \
if ( DEBUG_LEVEL & ( dbg_flags ) ) \
{ \
int len; \
len = sprintf( __dbg_str_buf, "%s:%d: %s: ", \
__FILE__, __LINE__, __FUNCTION__ ); \
sprintf( __dbg_str_buf + len, args ); \
printk( KERN_NOTICE "%s\n", __dbg_str_buf ); \
} \
} while (0)
#define DBG_ENTER_ROUTINE DBG_PRINT (DBG_K_TRACE_ENTRY, "%s", "[Entry]");
#define DBG_LEAVE_ROUTINE DBG_PRINT (DBG_K_TRACE_EXIT, "%s", "[Exit]");
#else
#define DEFINE_DBG_BUFFER
#define DBG_ENTER_ROUTINE
#define DBG_LEAVE_ROUTINE
#endif /* DEBUG */
/* Slot Available Register I field definition */
#define SLOT_33MHZ 0x0000001f
#define SLOT_66MHZ_PCIX 0x00001f00
#define SLOT_100MHZ_PCIX 0x001f0000
#define SLOT_133MHZ_PCIX 0x1f000000
/* Slot Available Register II field definition */
#define SLOT_66MHZ 0x0000001f
#define SLOT_66MHZ_PCIX_266 0x00000f00
#define SLOT_100MHZ_PCIX_266 0x0000f000
#define SLOT_133MHZ_PCIX_266 0x000f0000
#define SLOT_66MHZ_PCIX_533 0x00f00000
#define SLOT_100MHZ_PCIX_533 0x0f000000
#define SLOT_133MHZ_PCIX_533 0xf0000000
/* Slot Configuration */
#define SLOT_NUM 0x0000001F
#define FIRST_DEV_NUM 0x00001F00
#define PSN 0x07FF0000
#define UPDOWN 0x20000000
#define MRLSENSOR 0x40000000
#define ATTN_BUTTON 0x80000000
/*
* Interrupt Locator Register definitions
*/
#define CMD_INTR_PENDING (1 << 0)
#define SLOT_INTR_PENDING(i) (1 << (i + 1))
/*
* Controller SERR-INT Register
*/
#define GLOBAL_INTR_MASK (1 << 0)
#define GLOBAL_SERR_MASK (1 << 1)
#define COMMAND_INTR_MASK (1 << 2)
#define ARBITER_SERR_MASK (1 << 3)
#define COMMAND_DETECTED (1 << 16)
#define ARBITER_DETECTED (1 << 17)
#define SERR_INTR_RSVDZ_MASK 0xfffc0000
/*
* Logical Slot Register definitions
*/
#define SLOT_REG(i) (SLOT1 + (4 * i))
#define SLOT_STATE_SHIFT (0)
#define SLOT_STATE_MASK (3 << 0)
#define SLOT_STATE_PWRONLY (1)
#define SLOT_STATE_ENABLED (2)
#define SLOT_STATE_DISABLED (3)
#define PWR_LED_STATE_SHIFT (2)
#define PWR_LED_STATE_MASK (3 << 2)
#define ATN_LED_STATE_SHIFT (4)
#define ATN_LED_STATE_MASK (3 << 4)
#define ATN_LED_STATE_ON (1)
#define ATN_LED_STATE_BLINK (2)
#define ATN_LED_STATE_OFF (3)
#define POWER_FAULT (1 << 6)
#define ATN_BUTTON (1 << 7)
#define MRL_SENSOR (1 << 8)
#define MHZ66_CAP (1 << 9)
#define PRSNT_SHIFT (10)
#define PRSNT_MASK (3 << 10)
#define PCIX_CAP_SHIFT (12)
#define PCIX_CAP_MASK_PI1 (3 << 12)
#define PCIX_CAP_MASK_PI2 (7 << 12)
#define PRSNT_CHANGE_DETECTED (1 << 16)
#define ISO_PFAULT_DETECTED (1 << 17)
#define BUTTON_PRESS_DETECTED (1 << 18)
#define MRL_CHANGE_DETECTED (1 << 19)
#define CON_PFAULT_DETECTED (1 << 20)
#define PRSNT_CHANGE_INTR_MASK (1 << 24)
#define ISO_PFAULT_INTR_MASK (1 << 25)
#define BUTTON_PRESS_INTR_MASK (1 << 26)
#define MRL_CHANGE_INTR_MASK (1 << 27)
#define CON_PFAULT_INTR_MASK (1 << 28)
#define MRL_CHANGE_SERR_MASK (1 << 29)
#define CON_PFAULT_SERR_MASK (1 << 30)
#define SLOT_REG_RSVDZ_MASK (1 << 15) | (7 << 21)
/*
* SHPC Command Code definitnions
*
* Slot Operation 00h - 3Fh
* Set Bus Segment Speed/Mode A 40h - 47h
* Power-Only All Slots 48h
* Enable All Slots 49h
* Set Bus Segment Speed/Mode B (PI=2) 50h - 5Fh
* Reserved Command Codes 60h - BFh
* Vendor Specific Commands C0h - FFh
*/
#define SET_SLOT_PWR 0x01 /* Slot Operation */
#define SET_SLOT_ENABLE 0x02
#define SET_SLOT_DISABLE 0x03
#define SET_PWR_ON 0x04
#define SET_PWR_BLINK 0x08
#define SET_PWR_OFF 0x0c
#define SET_ATTN_ON 0x10
#define SET_ATTN_BLINK 0x20
#define SET_ATTN_OFF 0x30
#define SETA_PCI_33MHZ 0x40 /* Set Bus Segment Speed/Mode A */
#define SETA_PCI_66MHZ 0x41
#define SETA_PCIX_66MHZ 0x42
#define SETA_PCIX_100MHZ 0x43
#define SETA_PCIX_133MHZ 0x44
#define SETA_RESERVED1 0x45
#define SETA_RESERVED2 0x46
#define SETA_RESERVED3 0x47
#define SET_PWR_ONLY_ALL 0x48 /* Power-Only All Slots */
#define SET_ENABLE_ALL 0x49 /* Enable All Slots */
#define SETB_PCI_33MHZ 0x50 /* Set Bus Segment Speed/Mode B */
#define SETB_PCI_66MHZ 0x51
#define SETB_PCIX_66MHZ_PM 0x52
#define SETB_PCIX_100MHZ_PM