1111 status = pciehpc_reg_get16(ctrl_p,
1112 bus_p->bus_pcie_off + PCIE_LINKSTS);
1113
1114 if (!(status & PCIE_LINKSTS_DLL_LINK_ACTIVE)) {
1115 /* wait 1 sec for the DLL State Changed event */
1116 (void) cv_timedwait(&slot_p->hs_dll_active_cv,
1117 &ctrl_p->hc_mutex,
1118 ddi_get_lbolt() +
1119 SEC_TO_TICK(PCIE_HP_DLL_STATE_CHANGE_TIMEOUT));
1120
1121 /* check Link status */
1122 status = pciehpc_reg_get16(ctrl_p,
1123 bus_p->bus_pcie_off +
1124 PCIE_LINKSTS);
1125 if (!(status & PCIE_LINKSTS_DLL_LINK_ACTIVE))
1126 goto cleanup2;
1127 }
1128 }
1129
1130 /* wait 1 sec for link to come up */
1131 delay(drv_usectohz(1000000));
1132
1133 /* check power is really turned ON */
1134 control = pciehpc_reg_get16(ctrl_p,
1135 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1136
1137 if (control & PCIE_SLOTCTL_PWR_CONTROL) {
1138 PCIE_DBG("slot %d fails to turn on power on connect\n",
1139 slot_p->hs_phy_slot_num);
1140
1141 goto cleanup1;
1142 }
1143
1144 /* clear power fault status */
1145 status = pciehpc_reg_get16(ctrl_p,
1146 bus_p->bus_pcie_off + PCIE_SLOTSTS);
1147 status |= PCIE_SLOTSTS_PWR_FAULT_DETECTED;
1148 pciehpc_reg_put16(ctrl_p, bus_p->bus_pcie_off + PCIE_SLOTSTS,
1149 status);
1150
1151 /* enable power fault detection interrupt */
1152 control |= PCIE_SLOTCTL_PWR_FAULT_EN;
1153 pciehpc_issue_hpc_command(ctrl_p, control);
1154
1155 /* 4. Set power LED to be ON */
1156 pciehpc_set_led_state(ctrl_p, PCIE_HP_POWER_LED, PCIE_HP_LED_ON);
1157
1158 /* if EMI is present, turn it ON */
1159 if (ctrl_p->hc_has_emi_lock) {
1160 status = pciehpc_reg_get16(ctrl_p,
1161 bus_p->bus_pcie_off + PCIE_SLOTSTS);
1162
1163 if (!(status & PCIE_SLOTSTS_EMI_LOCK_SET)) {
1164 control = pciehpc_reg_get16(ctrl_p,
1165 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1166 control |= PCIE_SLOTCTL_EMI_LOCK_CONTROL;
1167 pciehpc_issue_hpc_command(ctrl_p, control);
1168
1169 /* wait 1 sec after toggling the state of EMI lock */
1170 delay(drv_usectohz(1000000));
1171 }
1172 }
1173
1174 *result = slot_p->hs_info.cn_state =
1175 DDI_HP_CN_STATE_POWERED;
1176
1177 return (DDI_SUCCESS);
1178
1179 cleanup2:
1180 control = pciehpc_reg_get16(ctrl_p,
1181 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1182
1183 /* if power is ON, set power control to OFF */
1184 if (!(control & PCIE_SLOTCTL_PWR_CONTROL)) {
1185 control |= PCIE_SLOTCTL_PWR_CONTROL;
1186 pciehpc_issue_hpc_command(ctrl_p, control);
1187 }
1188
1189 cleanup1:
1190 /* set power led to OFF */
1259 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1260 ASSERT(control & PCIE_SLOTCTL_PWR_CONTROL);
1261 #endif
1262
1263 /* 3. Set power LED to be OFF */
1264 pciehpc_set_led_state(ctrl_p, PCIE_HP_POWER_LED, PCIE_HP_LED_OFF);
1265 pciehpc_set_led_state(ctrl_p, PCIE_HP_ATTN_LED, PCIE_HP_LED_OFF);
1266
1267 /* if EMI is present, turn it OFF */
1268 if (ctrl_p->hc_has_emi_lock) {
1269 status = pciehpc_reg_get16(ctrl_p,
1270 bus_p->bus_pcie_off + PCIE_SLOTSTS);
1271
1272 if (status & PCIE_SLOTSTS_EMI_LOCK_SET) {
1273 control = pciehpc_reg_get16(ctrl_p,
1274 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1275 control |= PCIE_SLOTCTL_EMI_LOCK_CONTROL;
1276 pciehpc_issue_hpc_command(ctrl_p, control);
1277
1278 /* wait 1 sec after toggling the state of EMI lock */
1279 delay(drv_usectohz(1000000));
1280 }
1281 }
1282
1283 /* get the current state of the slot */
1284 pciehpc_get_slot_state(slot_p);
1285
1286 *result = slot_p->hs_info.cn_state;
1287
1288 return (DDI_SUCCESS);
1289
1290 cleanup:
1291 return (DDI_FAILURE);
1292 }
1293
1294 /*
1295 * pciehpc_slot_probe()
1296 *
1297 * Probe the slot.
1298 *
1299 * Note: This function is called by DDI HP framework at kernel context only
|
1111 status = pciehpc_reg_get16(ctrl_p,
1112 bus_p->bus_pcie_off + PCIE_LINKSTS);
1113
1114 if (!(status & PCIE_LINKSTS_DLL_LINK_ACTIVE)) {
1115 /* wait 1 sec for the DLL State Changed event */
1116 (void) cv_timedwait(&slot_p->hs_dll_active_cv,
1117 &ctrl_p->hc_mutex,
1118 ddi_get_lbolt() +
1119 SEC_TO_TICK(PCIE_HP_DLL_STATE_CHANGE_TIMEOUT));
1120
1121 /* check Link status */
1122 status = pciehpc_reg_get16(ctrl_p,
1123 bus_p->bus_pcie_off +
1124 PCIE_LINKSTS);
1125 if (!(status & PCIE_LINKSTS_DLL_LINK_ACTIVE))
1126 goto cleanup2;
1127 }
1128 }
1129
1130 /* wait 1 sec for link to come up */
1131 delay(drv_sectohz(1));
1132
1133 /* check power is really turned ON */
1134 control = pciehpc_reg_get16(ctrl_p,
1135 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1136
1137 if (control & PCIE_SLOTCTL_PWR_CONTROL) {
1138 PCIE_DBG("slot %d fails to turn on power on connect\n",
1139 slot_p->hs_phy_slot_num);
1140
1141 goto cleanup1;
1142 }
1143
1144 /* clear power fault status */
1145 status = pciehpc_reg_get16(ctrl_p,
1146 bus_p->bus_pcie_off + PCIE_SLOTSTS);
1147 status |= PCIE_SLOTSTS_PWR_FAULT_DETECTED;
1148 pciehpc_reg_put16(ctrl_p, bus_p->bus_pcie_off + PCIE_SLOTSTS,
1149 status);
1150
1151 /* enable power fault detection interrupt */
1152 control |= PCIE_SLOTCTL_PWR_FAULT_EN;
1153 pciehpc_issue_hpc_command(ctrl_p, control);
1154
1155 /* 4. Set power LED to be ON */
1156 pciehpc_set_led_state(ctrl_p, PCIE_HP_POWER_LED, PCIE_HP_LED_ON);
1157
1158 /* if EMI is present, turn it ON */
1159 if (ctrl_p->hc_has_emi_lock) {
1160 status = pciehpc_reg_get16(ctrl_p,
1161 bus_p->bus_pcie_off + PCIE_SLOTSTS);
1162
1163 if (!(status & PCIE_SLOTSTS_EMI_LOCK_SET)) {
1164 control = pciehpc_reg_get16(ctrl_p,
1165 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1166 control |= PCIE_SLOTCTL_EMI_LOCK_CONTROL;
1167 pciehpc_issue_hpc_command(ctrl_p, control);
1168
1169 /* wait 1 sec after toggling the state of EMI lock */
1170 delay(drv_sectohz(1));
1171 }
1172 }
1173
1174 *result = slot_p->hs_info.cn_state =
1175 DDI_HP_CN_STATE_POWERED;
1176
1177 return (DDI_SUCCESS);
1178
1179 cleanup2:
1180 control = pciehpc_reg_get16(ctrl_p,
1181 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1182
1183 /* if power is ON, set power control to OFF */
1184 if (!(control & PCIE_SLOTCTL_PWR_CONTROL)) {
1185 control |= PCIE_SLOTCTL_PWR_CONTROL;
1186 pciehpc_issue_hpc_command(ctrl_p, control);
1187 }
1188
1189 cleanup1:
1190 /* set power led to OFF */
1259 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1260 ASSERT(control & PCIE_SLOTCTL_PWR_CONTROL);
1261 #endif
1262
1263 /* 3. Set power LED to be OFF */
1264 pciehpc_set_led_state(ctrl_p, PCIE_HP_POWER_LED, PCIE_HP_LED_OFF);
1265 pciehpc_set_led_state(ctrl_p, PCIE_HP_ATTN_LED, PCIE_HP_LED_OFF);
1266
1267 /* if EMI is present, turn it OFF */
1268 if (ctrl_p->hc_has_emi_lock) {
1269 status = pciehpc_reg_get16(ctrl_p,
1270 bus_p->bus_pcie_off + PCIE_SLOTSTS);
1271
1272 if (status & PCIE_SLOTSTS_EMI_LOCK_SET) {
1273 control = pciehpc_reg_get16(ctrl_p,
1274 bus_p->bus_pcie_off + PCIE_SLOTCTL);
1275 control |= PCIE_SLOTCTL_EMI_LOCK_CONTROL;
1276 pciehpc_issue_hpc_command(ctrl_p, control);
1277
1278 /* wait 1 sec after toggling the state of EMI lock */
1279 delay(drv_sectohz(1));
1280 }
1281 }
1282
1283 /* get the current state of the slot */
1284 pciehpc_get_slot_state(slot_p);
1285
1286 *result = slot_p->hs_info.cn_state;
1287
1288 return (DDI_SUCCESS);
1289
1290 cleanup:
1291 return (DDI_FAILURE);
1292 }
1293
1294 /*
1295 * pciehpc_slot_probe()
1296 *
1297 * Probe the slot.
1298 *
1299 * Note: This function is called by DDI HP framework at kernel context only
|