p_slot = shpchp_find_slot(ctrl, hp_slot + ctrl->slot_device_offset);
p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
+ dbg("%s: Card present %x Power status %x\n", __FUNCTION__,
+ func->presence_save, func->pwr_save);
if (getstatus) {
/*
info("Latch open on Slot(%d)\n", ctrl->first_slot + hp_slot);
func->switch_save = 0;
taskInfo->event_type = INT_SWITCH_OPEN;
+ if (func->pwr_save && func->presence_save) {
+ taskInfo->event_type = INT_POWER_FAULT;
+ err("Surprise Removal of card\n");
+ }
} else {
/*
* Switch closed
/* This one isn't an aligned length, so we'll make a new entry
* and split it up.
*/
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
return(NULL);
if ((node->length - (temp_dword - node->base)) < size)
continue;
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
return(NULL);
if (node->length > size) {
/* This one is longer than we need
so we'll make a new entry and split it up */
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
return(NULL);
if ((max->length - (temp_dword - max->base)) < size)
continue;
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
return(NULL);
if ((max->base + max->length) & (size - 1)) {
/* This one isn't end aligned properly at the top
so we'll make a new entry and split it up */
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
return(NULL);
for ( i = 0; max_size[i] > size; i++) {
if (max->length > max_size[i]) {
- split_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node),
+ GFP_KERNEL);
if (!split_node)
break; /* return (NULL); */
split_node->base = max->base + max_size[i];
if ((node->length - (temp_dword - node->base)) < size)
continue;
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
return(NULL);
dbg("%s: too big\n", __FUNCTION__);
/* this one is longer than we need
so we'll make a new entry and split it up */
- split_node = (struct pci_resource*) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ split_node = kmalloc(sizeof(*split_node), GFP_KERNEL);
if (!split_node)
return(NULL);
struct pci_func *new_slot;
struct pci_func *next;
- new_slot = (struct pci_func *) kmalloc(sizeof(struct pci_func), GFP_KERNEL);
+ new_slot = kmalloc(sizeof(*new_slot), GFP_KERNEL);
if (new_slot == NULL) {
return(new_slot);
/* The following routines constitute the bulk of the
hotplug controller logic
*/
+static u32 change_bus_speed(struct controller *ctrl, struct slot *p_slot, enum pci_bus_speed speed)
+{
+ u32 rc = 0;
+ dbg("%s: change to speed %d\n", __FUNCTION__, speed);
+ down(&ctrl->crit_sect);
+ if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, speed))) {
+ err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+ wait_for_ctrl_irq (ctrl);
+
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+ err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
+ __FUNCTION__);
+ err("%s: Error code (%d)\n", __FUNCTION__, rc);
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+ up(&ctrl->crit_sect);
+ return rc;
+}
+
+static u32 fix_bus_speed(struct controller *ctrl, struct slot *pslot, u8 flag,
+enum pci_bus_speed asp, enum pci_bus_speed bsp, enum pci_bus_speed msp)
+{
+ u32 rc = 0;
+
+ if (flag != 0) { /* Other slots on the same bus are occupied */
+ if ( asp < bsp ) {
+ err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bsp, asp);
+ return WRONG_BUS_FREQUENCY;
+ }
+ } else {
+ /* Other slots on the same bus are empty */
+ if (msp == bsp) {
+ /* if adapter_speed >= bus_speed, do nothing */
+ if (asp < bsp) {
+ /*
+ * Try to lower bus speed to accommodate the adapter if other slots
+ * on the same controller are empty
+ */
+ if ((rc = change_bus_speed(ctrl, pslot, asp)))
+ return rc;
+ }
+ } else {
+ if (asp < msp) {
+ if ((rc = change_bus_speed(ctrl, pslot, asp)))
+ return rc;
+ } else {
+ if ((rc = change_bus_speed(ctrl, pslot, msp)))
+ return rc;
+ }
+ }
+ }
+ return rc;
+}
/**
* board_added - Called after a board has been added to the system.
*/
static u32 board_added(struct pci_func * func, struct controller * ctrl)
{
- u8 hp_slot, slot;
+ u8 hp_slot;
u8 slots_not_empty = 0;
int index;
u32 temp_register = 0xFFFFFFFF;
u32 retval, rc = 0;
struct pci_func *new_func = NULL;
- struct pci_func *t_func = NULL;
- struct slot *p_slot, *pslot;
+ struct slot *p_slot;
struct resource_lists res_lists;
enum pci_bus_speed adapter_speed, bus_speed, max_bus_speed;
u8 pi, mode;
return -1;
}
+
+ if ((ctrl->pci_dev->vendor == 0x8086) && (ctrl->pci_dev->device == 0x0332)) {
+ if (slots_not_empty)
+ return WRONG_BUS_FREQUENCY;
+
+ if ((rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, PCI_SPEED_33MHz))) {
+ err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+ wait_for_ctrl_irq (ctrl);
+
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+ err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
+ __FUNCTION__);
+ err("%s: Error code (%d)\n", __FUNCTION__, rc);
+ up(&ctrl->crit_sect);
+ return WRONG_BUS_FREQUENCY;
+ }
+ /* turn on board, blink green LED, turn off Amber LED */
+ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
+ err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+ wait_for_ctrl_irq (ctrl);
+
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
+ err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
+ up(&ctrl->crit_sect);
+ return rc;
+ }
+ }
+
rc = p_slot->hpc_ops->get_adapter_speed(p_slot, &adapter_speed);
/* 0 = PCI 33Mhz, 1 = PCI 66 Mhz, 2 = PCI-X 66 PA, 4 = PCI-X 66 ECC, */
/* 5 = PCI-X 133 PA, 7 = PCI-X 133 ECC, 0xa = PCI-X 133 Mhz 266, */
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
- rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi);
- if (rc) {
+ if ((rc = p_slot->hpc_ops->get_prog_int(p_slot, &pi))) {
err("%s: Can't get controller programming interface, set it to 1\n", __FUNCTION__);
pi = 1;
}
+
+ /* Check if there are other slots or devices on the same bus */
+ if (!list_empty(&ctrl->pci_dev->subordinate->devices))
+ slots_not_empty = 1;
+
+ dbg("%s: slots_not_empty %d, pi %d\n", __FUNCTION__,
+ slots_not_empty, pi);
+ dbg("adapter_speed %d, bus_speed %d, max_bus_speed %d\n",
+ adapter_speed, bus_speed, max_bus_speed);
+
if (pi == 2) {
- for ( slot = 0; slot < ctrl->num_slots; slot++) {
- if (slot != hp_slot) {
- pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset);
- t_func = shpchp_slot_find(pslot->bus, pslot->device, 0);
- slots_not_empty |= t_func->is_a_board;
- }
+ dbg("%s: In PI = %d\n", __FUNCTION__, pi);
+ if ((rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode))) {
+ err("%s: Can't get Mode1_ECC, set mode to 0\n", __FUNCTION__);
+ mode = 0;
}
switch (adapter_speed) {
- case PCI_SPEED_133MHz_PCIX_533:
+ case PCI_SPEED_133MHz_PCIX_533:
case PCI_SPEED_133MHz_PCIX_266:
- if ((( bus_speed < 0xa ) || (bus_speed < 0xd)) && (max_bus_speed > bus_speed) &&
- ((max_bus_speed <= 0xa) || (max_bus_speed <= 0xd)) && (!slots_not_empty)) {
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
- break;
+ if ((bus_speed != adapter_speed) &&
+ ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+ return rc;
+ break;
case PCI_SPEED_133MHz_PCIX_ECC:
case PCI_SPEED_133MHz_PCIX:
-
- rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode);
-
- if (rc) {
- err("%s: PI is 1 \n", __FUNCTION__);
- return WRONG_BUS_FREQUENCY;
- }
-
if (mode) { /* Bus - Mode 1 ECC */
-
- if (bus_speed > 0x7) {
- err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
- return WRONG_BUS_FREQUENCY;
- }
-
- if ((bus_speed < 0x7) && (max_bus_speed <= 0x7) &&
- (bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
+ if ((bus_speed != 0x7) &&
+ ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+ return rc;
} else {
- if (bus_speed > 0x4) {
- err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
- return WRONG_BUS_FREQUENCY;
- }
-
- if ((bus_speed < 0x4) && (max_bus_speed <= 0x4) &&
- (bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
+ if ((bus_speed != 0x4) &&
+ ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+ return rc;
}
break;
case PCI_SPEED_66MHz_PCIX_ECC:
case PCI_SPEED_66MHz_PCIX:
-
- rc = p_slot->hpc_ops->get_mode1_ECC_cap(p_slot, &mode);
-
- if (rc) {
- err("%s: PI is 1 \n", __FUNCTION__);
- return WRONG_BUS_FREQUENCY;
- }
-
if (mode) { /* Bus - Mode 1 ECC */
-
- if (bus_speed > 0x5) {
- err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
- return WRONG_BUS_FREQUENCY;
- }
-
- if ((bus_speed < 0x5) && (max_bus_speed <= 0x5) &&
- (bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
+ if ((bus_speed != 0x5) &&
+ ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+ return rc;
} else {
- if (bus_speed > 0x2) {
- err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
- return WRONG_BUS_FREQUENCY;
- }
-
- if ((bus_speed < 0x2) && (max_bus_speed <= 0x2) &&
- (bus_speed < max_bus_speed) && (!slots_not_empty)) {
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
+ if ((bus_speed != 0x2) &&
+ ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+ return rc;
}
break;
case PCI_SPEED_66MHz:
- if (bus_speed > 0x1) {
- err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
- return WRONG_BUS_FREQUENCY;
- }
- if (bus_speed == 0x1)
- ;
- if ((bus_speed == 0x0) && ( max_bus_speed == 0x1)) {
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- }
+ if ((bus_speed != 0x1) &&
+ ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+ return rc;
break;
case PCI_SPEED_33MHz:
if (bus_speed > 0x0) {
- err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
- return WRONG_BUS_FREQUENCY;
+ if (slots_not_empty == 0) {
+ if ((rc = change_bus_speed(ctrl, p_slot, adapter_speed)))
+ return rc;
+ } else {
+ err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
+ return WRONG_BUS_FREQUENCY;
+ }
}
break;
default:
return WRONG_BUS_FREQUENCY;
}
} else {
- /* if adpater_speed == bus_speed, nothing to do here */
- if (adapter_speed != bus_speed) {
- for ( slot = 0; slot < ctrl->num_slots; slot++) {
- if (slot != hp_slot) {
- pslot = shpchp_find_slot(ctrl, slot + ctrl->slot_device_offset);
- t_func = shpchp_slot_find(pslot->bus, pslot->device, 0);
- slots_not_empty |= t_func->is_a_board;
- }
- }
-
- if (slots_not_empty != 0) { /* Other slots on the same bus are occupied */
- if ( adapter_speed < bus_speed ) {
- err("%s: speed of bus %x and adapter %x mismatch\n", __FUNCTION__, bus_speed, adapter_speed);
- return WRONG_BUS_FREQUENCY;
- }
- /* Do nothing if adapter_speed >= bus_speed */
- }
- }
-
- if ((adapter_speed != bus_speed) && (slots_not_empty == 0)) {
- /* Other slots on the same bus are empty */
-
- rc = p_slot->hpc_ops->get_max_bus_speed(p_slot, &max_bus_speed);
- if (rc || max_bus_speed == PCI_SPEED_UNKNOWN) {
- err("%s: Can't get max bus operation speed\n", __FUNCTION__);
- max_bus_speed = bus_speed;
- }
-
- if (max_bus_speed == bus_speed) {
- /* if adapter_speed >= bus_speed, do nothing */
- if (adapter_speed < bus_speed) {
- /*
- * Try to lower bus speed to accommodate the adapter if other slots
- * on the same controller are empty
- */
-
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed);
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
-
- }
- } else {
- /* Wait for exclusive access to hardware */
- down(&ctrl->crit_sect);
-
- /* max_bus_speed != bus_speed. Note: max_bus_speed should be > than bus_speed */
- if (adapter_speed < max_bus_speed)
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, adapter_speed);
- else
- rc = p_slot->hpc_ops->set_bus_speed_mode(p_slot, max_bus_speed);
-
- if (rc) {
- err("%s: Issue of set bus speed mode command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (ctrl);
-
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
- err("%s: Can't set bus speed/mode in the case of adapter & bus mismatch\n",
- __FUNCTION__);
- err("%s: Error code (%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
- return WRONG_BUS_FREQUENCY;
- }
- /* Done with exclusive hardware access */
- up(&ctrl->crit_sect);
-
- }
- }
+ /* If adpater_speed == bus_speed, nothing to do here */
+ dbg("%s: In PI = %d\n", __FUNCTION__, pi);
+ if ((adapter_speed != bus_speed) &&
+ ((rc = fix_bus_speed(ctrl, p_slot, slots_not_empty, adapter_speed, bus_speed, max_bus_speed))))
+ return rc;
}
- /* Wait for exclusive access to hardware */
down(&ctrl->crit_sect);
-
/* turn on board, blink green LED, turn off Amber LED */
- rc = p_slot->hpc_ops->slot_enable(p_slot);
-
- if (rc) {
+ if ((rc = p_slot->hpc_ops->slot_enable(p_slot))) {
err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
- /* Done with exclusive hardware access */
up(&ctrl->crit_sect);
return rc;
}
- /* Wait for the command to complete */
wait_for_ctrl_irq (ctrl);
- rc = p_slot->hpc_ops->check_cmd_status(ctrl);
- if (rc) {
+ if ((rc = p_slot->hpc_ops->check_cmd_status(ctrl))) {
err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
- /* Done with exclusive hardware access */
up(&ctrl->crit_sect);
return rc;
}
- /* Done with exclusive hardware access */
up(&ctrl->crit_sect);
/* Wait for ~1 second */
dbg("%s: before long_delay\n", __FUNCTION__);
wait_for_ctrl_irq (ctrl);
- dbg("%s: afterlong_delay\n", __FUNCTION__);
+ dbg("%s: after long_delay\n", __FUNCTION__);
dbg("%s: func status = %x\n", __FUNCTION__, func->status);
/* Check for a power fault */
retval = p_slot->hpc_ops->check_cmd_status(ctrl);
if (retval) {
- err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
+ err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, retval);
/* Done with exclusive hardware access */
up(&ctrl->crit_sect);
return retval;
func->status = 0;
func->switch_save = 0x10;
func->is_a_board = 0x01;
+ func->pwr_save = 1;
- /* next, we will instantiate the linux pci_dev structures
+ /* Next, we will instantiate the linux pci_dev structures
* (with appropriate driver notification, if already present)
*/
index = 0;
func->function = 0;
func->configured = 0;
func->switch_save = 0x10;
+ func->pwr_save = 0;
func->is_a_board = 0;
}
}
+/**
+ * shpchp_pushbutton_thread
+ *
+ * Scheduled procedure to handle blocking stuff for the pushbuttons
+ * Handles all pending events and exits.
+ *
+ */
+static void shpchp_pushbutton_thread (unsigned long slot)
+{
+ struct slot *p_slot = (struct slot *) slot;
+ u8 getstatus;
+
+ pushbutton_pending = 0;
+
+ if (!p_slot) {
+ dbg("%s: Error! slot NULL\n", __FUNCTION__);
+ return;
+ }
+
+ p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
+ if (getstatus) {
+ p_slot->state = POWEROFF_STATE;
+ dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+
+ shpchp_disable_slot(p_slot);
+ p_slot->state = STATIC_STATE;
+ } else {
+ p_slot->state = POWERON_STATE;
+ dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
+
+ if (shpchp_enable_slot(p_slot)) {
+ /* Wait for exclusive access to hardware */
+ down(&p_slot->ctrl->crit_sect);
+
+ p_slot->hpc_ops->green_led_off(p_slot);
+
+ /* Wait for the command to complete */
+ wait_for_ctrl_irq (p_slot->ctrl);
+
+ /* Done with exclusive hardware access */
+ up(&p_slot->ctrl->crit_sect);
+ }
+ p_slot->state = STATIC_STATE;
+ }
+
+ return;
+}
+
+
/* this is the main worker thread */
static int event_thread(void* data)
{
event_finished=0;
init_MUTEX_LOCKED(&event_semaphore);
- pid = kernel_thread(event_thread, 0, 0);
+ pid = kernel_thread(event_thread, NULL, 0);
if (pid < 0) {
err ("Can't start up our event thread\n");
struct hotplug_slot_info *info;
int result;
- info = kmalloc (sizeof (struct hotplug_slot_info), GFP_KERNEL);
+ info = kmalloc(sizeof(*info), GFP_KERNEL);
if (!info)
return -ENOMEM;
}
-/**
- * shpchp_pushbutton_thread
- *
- * Scheduled procedure to handle blocking stuff for the pushbuttons
- * Handles all pending events and exits.
- *
- */
-void shpchp_pushbutton_thread (unsigned long slot)
-{
- struct slot *p_slot = (struct slot *) slot;
- u8 getstatus;
- int rc;
-
- pushbutton_pending = 0;
-
- if (!p_slot) {
- dbg("%s: Error! slot NULL\n", __FUNCTION__);
- return;
- }
-
- p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
- if (getstatus) {
- p_slot->state = POWEROFF_STATE;
- dbg("In power_down_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
-
- if (shpchp_disable_slot(p_slot)) {
- /* Wait for exclusive access to hardware */
- down(&p_slot->ctrl->crit_sect);
-
- /* Turn on the Attention LED */
- rc = p_slot->hpc_ops->set_attention_status(p_slot, 1);
- if (rc) {
- err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__);
- return;
- }
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (p_slot->ctrl);
-
- /* Done with exclusive hardware access */
- up(&p_slot->ctrl->crit_sect);
- }
- p_slot->state = STATIC_STATE;
- } else {
- p_slot->state = POWERON_STATE;
- dbg("In add_board, b:d(%x:%x)\n", p_slot->bus, p_slot->device);
-
- if (shpchp_enable_slot(p_slot)) {
- /* Wait for exclusive access to hardware */
- down(&p_slot->ctrl->crit_sect);
-
- /* Turn off the green LED */
- rc = p_slot->hpc_ops->set_attention_status(p_slot, 1);
- if (rc) {
- err("%s: Issue of Set Atten Indicator On command failed\n", __FUNCTION__);
- return;
- }
- /* Wait for the command to complete */
- wait_for_ctrl_irq (p_slot->ctrl);
-
- p_slot->hpc_ops->green_led_off(p_slot);
-
- /* Wait for the command to complete */
- wait_for_ctrl_irq (p_slot->ctrl);
-
- /* Done with exclusive hardware access */
- up(&p_slot->ctrl->crit_sect);
- }
- p_slot->state = STATIC_STATE;
- }
-
- return;
-}
-
-
int shpchp_enable_slot (struct slot *p_slot)
{
u8 getstatus = 0;
func = shpchp_slot_find(p_slot->bus, p_slot->device, 0);
if (!func) {
dbg("%s: Error! slot NULL\n", __FUNCTION__);
- return (1);
+ return 1;
}
/* Check to see if (latch closed, card present, power off) */
if (rc || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
- return (0);
+ return 1;
}
rc = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (rc || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
- return (0);
+ return 1;
}
rc = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (rc || getstatus) {
info("%s: already enabled on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
- return (0);
+ return 1;
}
up(&p_slot->ctrl->crit_sect);
func = shpchp_slot_create(p_slot->bus);
if (func == NULL)
- return (1);
+ return 1;
func->bus = p_slot->bus;
func->device = p_slot->device;
/* We have to save the presence info for these slots */
p_slot->hpc_ops->get_adapter_status(p_slot, &(func->presence_save));
+ p_slot->hpc_ops->get_power_status(p_slot, &(func->pwr_save));
+ dbg("%s: func->pwr_save %x\n", __FUNCTION__, func->pwr_save);
p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
func->switch_save = !getstatus? 0x10:0;
u32 rc = 0;
int ret = 0;
unsigned int devfn;
- struct pci_bus *pci_bus = p_slot->ctrl->pci_dev->subordinate;
+ struct pci_bus *pci_bus;
struct pci_func *func;
if (!p_slot->ctrl)
- return (1);
+ return 1;
+
+ pci_bus = p_slot->ctrl->pci_dev->subordinate;
/* Check to see if (latch closed, card present, power on) */
down(&p_slot->ctrl->crit_sect);
if (ret || !getstatus) {
info("%s: no adapter on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
- return (0);
+ return 1;
}
ret = p_slot->hpc_ops->get_latch_status(p_slot, &getstatus);
if (ret || getstatus) {
info("%s: latch open on slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
- return (0);
+ return 1;
}
ret = p_slot->hpc_ops->get_power_status(p_slot, &getstatus);
if (ret || !getstatus) {
info("%s: already disabled slot(%x)\n", __FUNCTION__, p_slot->number);
up(&p_slot->ctrl->crit_sect);
- return (0);
+ return 1;
}
up(&p_slot->ctrl->crit_sect);
/* Make copies of the nodes we are going to pass down so that
* if there is a problem,we can just use these to free resources
*/
- hold_bus_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_IO_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
- hold_p_mem_node = (struct pci_resource *) kmalloc(sizeof(struct pci_resource), GFP_KERNEL);
+ hold_bus_node = kmalloc(sizeof(*hold_bus_node), GFP_KERNEL);
+ hold_IO_node = kmalloc(sizeof(*hold_IO_node), GFP_KERNEL);
+ hold_mem_node = kmalloc(sizeof(*hold_mem_node), GFP_KERNEL);
+ hold_p_mem_node = kmalloc(sizeof(*hold_p_mem_node), GFP_KERNEL);
if (!hold_bus_node || !hold_IO_node || !hold_mem_node || !hold_p_mem_node) {
- if (hold_bus_node)
- kfree(hold_bus_node);
- if (hold_IO_node)
- kfree(hold_IO_node);
- if (hold_mem_node)
- kfree(hold_mem_node);
- if (hold_p_mem_node)
- kfree(hold_p_mem_node);
+ kfree(hold_bus_node);
+ kfree(hold_IO_node);
+ kfree(hold_mem_node);
+ kfree(hold_p_mem_node);
- return(1);
+ return 1;
}
memcpy(hold_bus_node, bus_node, sizeof(struct pci_resource));
/* set IO base and Limit registers */
RES_CHECK(io_node->base, 8);
temp_byte = (u8)(io_node->base >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_BASE, temp_byte);
+ rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_BASE, temp_byte);
RES_CHECK(io_node->base + io_node->length - 1, 8);
temp_byte = (u8)((io_node->base + io_node->length - 1) >> 8);
- rc = pci_bus_write_config_byte (pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
+ rc = pci_bus_write_config_byte(pci_bus, devfn, PCI_IO_LIMIT, temp_byte);
} else {
kfree(hold_IO_node);
hold_IO_node = NULL;
/* set Mem base and Limit registers */
RES_CHECK(mem_node->base, 16);
temp_word = (u32)(mem_node->base >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
RES_CHECK(mem_node->base + mem_node->length - 1, 16);
temp_word = (u32)((mem_node->base + mem_node->length - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
} else {
temp_word = 0xFFFF;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_BASE, temp_word);
temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_MEMORY_LIMIT, temp_word);
kfree(hold_mem_node);
hold_mem_node = NULL;
/* set Pre Mem base and Limit registers */
RES_CHECK(p_mem_node->base, 16);
temp_word = (u32)(p_mem_node->base >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
RES_CHECK(p_mem_node->base + p_mem_node->length - 1, 16);
temp_word = (u32)((p_mem_node->base + p_mem_node->length - 1) >> 16);
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
} else {
temp_word = 0xFFFF;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_BASE, temp_word);
temp_word = 0x0000;
- rc = pci_bus_write_config_word (pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
+ rc = pci_bus_write_config_word(pci_bus, devfn, PCI_PREF_MEMORY_LIMIT, temp_word);
kfree(hold_p_mem_node);
hold_p_mem_node = NULL;
ID = 0xFFFFFFFF;
pci_bus->number = hold_bus_node->base;
- pci_bus_read_config_dword (pci_bus, PCI_DEVFN(device, 0), PCI_VENDOR_ID, &ID);
+ pci_bus_read_config_dword(pci_bus, PCI_DEVFN(device, 0),
+ PCI_VENDOR_ID, &ID);
pci_bus->number = func->bus;
if (ID != 0xFFFFFFFF) { /* device Present */