#define MRL_SENS_PRSN 0x00000004
#define ATTN_LED_PRSN 0x00000008
#define PWR_LED_PRSN 0x00000010
-#define HP_SUPR_RM 0x00000020
+#define HP_SUPR_RM_SUP 0x00000020
#define HP_CAP 0x00000040
#define SLOT_PWR_VALUE 0x000003F8
#define SLOT_PWR_LIMIT 0x00000C00
static spinlock_t hpc_event_lock;
DEFINE_DBG_BUFFER /* Debug string buffer for entire HPC defined here */
-static struct php_ctlr_state_s *php_ctlr_list_head = 0; /* HPC state linked list */
+static struct php_ctlr_state_s *php_ctlr_list_head; /* HPC state linked list */
static int ctlr_seq_num = 0; /* Controller sequence # */
static spinlock_t list_lock;
static int pcie_write_cmd(struct slot *slot, u16 cmd)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
int retval = 0;
u16 slot_status;
DBG_ENTER_ROUTINE
dbg("%s : Enter\n", __FUNCTION__);
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_check_lnk_status(struct controller *ctrl)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
u16 lnk_status;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
return retval;
}
- if ( (lnk_status & (LNK_TRN | LNK_TRN_ERR)) == 0x0C00) {
+ dbg("%s: lnk_status = %x\n", __FUNCTION__, lnk_status);
+ if ( (lnk_status & LNK_TRN) || (lnk_status & LNK_TRN_ERR) ||
+ !(lnk_status & NEG_LINK_WD)) {
err("%s : Link Training Error occurs \n", __FUNCTION__);
retval = -1;
return retval;
static int hpc_get_attention_status(struct slot *slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_ctrl;
u8 atten_led_state;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_get_power_status(struct slot * slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_ctrl;
u8 pwr_state;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_get_latch_status(struct slot *slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_status;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_get_adapter_status(struct slot *slot, u8 *status)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_status;
u8 card_state;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_query_power_fault(struct slot * slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_status;
u8 pwr_fault;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_set_attention_status(struct slot *slot, u8 value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd = 0;
u16 slot_ctrl;
int rc = 0;
dbg("%s: \n", __FUNCTION__);
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static void hpc_set_green_led_on(struct slot *slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd;
u16 slot_ctrl;
int rc = 0;
dbg("%s: \n", __FUNCTION__);
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
}
static void hpc_set_green_led_off(struct slot *slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd;
u16 slot_ctrl;
int rc = 0;
dbg("%s: \n", __FUNCTION__);
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
}
static void hpc_set_green_led_blink(struct slot *slot)
{
- struct php_ctlr_state_s *php_ctlr =(struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd;
u16 slot_ctrl;
int rc = 0;
dbg("%s: \n", __FUNCTION__);
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
}
int *num_ctlr_slots, /* number of slots in this HPC; only 1 in PCIE */
int *first_device_num, /* PCI dev num of the first slot in this PCIE */
int *physical_slot_num, /* phy slot num of the first slot in this PCIE */
- int *updown, /* physical_slot_num increament: 1 or -1 */
- int *flags)
+ u8 *ctrlcap)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
u32 slot_cap;
int rc = 0;
DBG_ENTER_ROUTINE
- if (!ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
}
*physical_slot_num = slot_cap >> 19;
-
- *updown = -1;
+ dbg("%s: PSN %d \n", __FUNCTION__, *physical_slot_num);
+
+ *ctrlcap = slot_cap & 0x0000007f;
DBG_LEAVE_ROUTINE
return 0;
static void hpc_release_ctlr(struct controller *ctrl)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = ctrl->hpc_ctlr_handle;
struct php_ctlr_state_s *p, *p_prev;
DBG_ENTER_ROUTINE
- if (!ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return ;
}
if (php_ctlr->irq) {
free_irq(php_ctlr->irq, ctrl);
php_ctlr->irq = 0;
+ if (!pcie_mch_quirk)
+ pci_disable_msi(php_ctlr->pci_dev);
}
}
if (php_ctlr->pci_dev)
- php_ctlr->pci_dev = 0;
+ php_ctlr->pci_dev = NULL;
spin_lock(&list_lock);
p = php_ctlr_list_head;
static int hpc_power_on_slot(struct slot * slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd;
u16 slot_ctrl;
DBG_ENTER_ROUTINE
dbg("%s: \n", __FUNCTION__);
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_power_off_slot(struct slot * slot)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
u16 slot_cmd;
u16 slot_ctrl;
DBG_ENTER_ROUTINE
dbg("%s: \n", __FUNCTION__);
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
return IRQ_NONE;
if (!pciehp_poll_mode) {
- ctrl = (struct controller *)dev_id;
+ ctrl = dev_id;
php_ctlr = ctrl->hpc_ctlr_handle;
} else {
- php_ctlr = (struct php_ctlr_state_s *) dev_id;
+ php_ctlr = dev_id;
ctrl = (struct controller *)php_ctlr->callback_instance_id;
}
return IRQ_HANDLED;
}
-static int hpc_get_max_lnk_speed (struct slot *slot, enum pcie_link_speed *value)
+static int hpc_get_max_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
enum pcie_link_speed lnk_speed;
u32 lnk_cap;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_get_max_lnk_width (struct slot *slot, enum pcie_link_width *value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
enum pcie_link_width lnk_wdth;
u32 lnk_cap;
int retval = 0;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
return retval;
}
-static int hpc_get_cur_lnk_speed (struct slot *slot, enum pcie_link_speed *value)
+static int hpc_get_cur_lnk_speed (struct slot *slot, enum pci_bus_speed *value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
enum pcie_link_speed lnk_speed = PCI_SPEED_UNKNOWN;
int retval = 0;
u16 lnk_status;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
static int hpc_get_cur_lnk_width (struct slot *slot, enum pcie_link_width *value)
{
- struct php_ctlr_state_s *php_ctlr = (struct php_ctlr_state_s *) slot->ctrl->hpc_ctlr_handle;
+ struct php_ctlr_state_s *php_ctlr = slot->ctrl->hpc_ctlr_handle;
enum pcie_link_width lnk_wdth = PCIE_LNK_WIDTH_UNKNOWN;
int retval = 0;
u16 lnk_status;
DBG_ENTER_ROUTINE
- if (!slot->ctrl->hpc_ctlr_handle) {
+ if (!php_ctlr) {
err("%s: Invalid HPC controller handle!\n", __FUNCTION__);
return -1;
}
};
int pcie_init(struct controller * ctrl,
- struct pci_dev * pdev,
+ struct pcie_device *dev,
php_intr_callback_t attention_button_callback,
php_intr_callback_t switch_change_callback,
php_intr_callback_t presence_change_callback,
static int first = 1;
u16 temp_word;
u16 cap_reg;
- u16 intr_enable;
+ u16 intr_enable = 0;
u32 slot_cap;
int cap_base, saved_cap_base;
u16 slot_status, slot_ctrl;
+ struct pci_dev *pdev;
DBG_ENTER_ROUTINE
}
memset(php_ctlr, 0, sizeof(struct php_ctlr_state_s));
-
+
+ pdev = dev->port;
php_ctlr->pci_dev = pdev; /* save pci_dev in context */
dbg("%s: pdev->vendor %x pdev->device %x\n", __FUNCTION__,
}
dbg("pdev = %p: b:d:f:irq=0x%x:%x:%x:%x\n", pdev, pdev->bus->number,
- PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), pdev->irq);
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn), dev->irq);
for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++)
if (pci_resource_len(pdev, rc) > 0)
dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc,
info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device,
pdev->subsystem_vendor, pdev->subsystem_device);
+ if (pci_enable_device(pdev))
+ goto abort_free_ctlr;
+
init_MUTEX(&ctrl->crit_sect);
/* setup wait queue */
init_waitqueue_head(&ctrl->queue);
/* find the IRQ */
- php_ctlr->irq = pdev->irq;
+ php_ctlr->irq = dev->irq;
dbg("HPC interrupt = %d\n", php_ctlr->irq);
/* Save interrupt callback info */
start_int_poll_timer( php_ctlr, 10 ); /* start with 10 second delay */
} else {
/* Installs the interrupt handler */
- dbg("%s: pciehp_msi_quirk = %x\n", __FUNCTION__, pciehp_msi_quirk);
- if (!pciehp_msi_quirk) {
- 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");
- dbg("%s: rc = %x\n", __FUNCTION__, rc);
- } else
- php_ctlr->irq = pdev->irq;
- }
rc = request_irq(php_ctlr->irq, pcie_isr, SA_SHIRQ, MY_NAME, (void *) ctrl);
dbg("%s: request_irq %d for hpc%d (returns %d)\n", __FUNCTION__, php_ctlr->irq, ctlr_seq_num, rc);
if (rc) {
goto abort_free_ctlr;
}
dbg("%s: SLOT_CTRL %x value read %x\n", __FUNCTION__, SLOT_CTRL, temp_word);
+ dbg("%s: slot_cap %x\n", __FUNCTION__, slot_cap);
- intr_enable = ATTN_BUTTN_ENABLE | PWR_FAULT_DETECT_ENABLE | MRL_DETECT_ENABLE |
- PRSN_DETECT_ENABLE;
+ intr_enable = intr_enable | PRSN_DETECT_ENABLE;
+
+ if (ATTN_BUTTN(slot_cap))
+ intr_enable = intr_enable | ATTN_BUTTN_ENABLE;
+
+ if (POWER_CTRL(slot_cap))
+ intr_enable = intr_enable | PWR_FAULT_DETECT_ENABLE;
+
+ if (MRL_SENS(slot_cap))
+ intr_enable = intr_enable | MRL_DETECT_ENABLE;
temp_word = (temp_word & ~intr_enable) | intr_enable;
if (php_ctlr_list_head == 0) {
php_ctlr_list_head = php_ctlr;
p = php_ctlr_list_head;
- p->pnext = 0;
+ p->pnext = NULL;
} else {
p = php_ctlr_list_head;