- /* 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__);
- 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);
- up(&ctrl->crit_sect);
- 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);
-
- }
- }