void sda_slot_handle_detect(sda_slot_t *slot) { uint32_t inserted; sda_slot_enter(slot); slot->s_stamp = ddi_get_time(); slot->s_intransit = 1; slot->s_flags = 0; slot->s_rca = 0; slot->s_ready = B_FALSE; sda_getprop(slot, SDA_PROP_INSERTED, &inserted); slot->s_inserted = (inserted != 0); if (slot->s_inserted && !slot->s_failed) { /* * We need to initialize the card, so we only support * hipri commands for now. */ slot->s_init = B_TRUE; sda_slot_exit(slot); /* * Card insertion occurred. We have to run this on * another task, to avoid deadlock as the task may * need to dispatch commands. */ (void) ddi_taskq_dispatch(slot->s_hp_tq, sda_slot_insert, slot, DDI_SLEEP); } else { /* * Nuke in-flight commands. */ sda_slot_abort(slot, SDA_ENODEV); /* * Restart the slot (incl. power cycle). This gets the * slot to a known good state. */ sda_slot_reset(slot); slot->s_intransit = 0; sda_slot_exit(slot); bd_state_change(slot->s_bdh); } sda_slot_wakeup(slot); }
void sda_slot_handle_fault(sda_slot_t *slot, sda_fault_t fault) { const char *msg; int i; sda_slot_enter(slot); if ((fault == SDA_FAULT_TIMEOUT) && (slot->s_init)) { /* * Timeouts during initialization are quite normal. */ sda_slot_exit(slot); return; } slot->s_failed = B_TRUE; sda_slot_abort(slot, SDA_EFAULT); msg = "Unknown fault (%d)"; for (i = 0; sda_slot_faults[i].msg != NULL; i++) { if (sda_slot_faults[i].fault == fault) { msg = sda_slot_faults[i].msg; break; } } /* * FMA would be a better choice here. */ sda_slot_err(slot, msg, fault); /* * Shut down the slot. Interaction from userland via cfgadm * can revive it. * * FMA can help here. */ sda_slot_halt(slot); sda_slot_exit(slot); }
void sda_slot_insert(void *arg) { sda_slot_t *slot = arg; if (sda_init_card(slot) != SDA_EOK) { /* * Remove power from the slot. If a more severe fault * occurred, then a manual reset with cfgadm will be needed. */ sda_slot_err(slot, "Unable to initialize card!"); sda_slot_enter(slot); sda_slot_power_off(slot); sda_slot_abort(slot, SDA_ENODEV); sda_slot_exit(slot); } else if ((slot->s_flags & SLOTF_MEMORY) == 0) { /* * SDIO: For SDIO, we can write the card's * MANFID tuple in CIS to the UUID. Until we * support SDIO, we just suppress creating * devinfo nodes. */ sda_slot_err(slot, "Non-memory target not supported"); } else { sda_slot_enter(slot); if (sda_mem_parse_cid_csd(slot) != DDI_SUCCESS) { sda_slot_err(slot, "Unable to parse card identification"); } else { slot->s_warn = B_FALSE; slot->s_ready = B_TRUE; } sda_slot_exit(slot); } slot->s_stamp = ddi_get_time(); slot->s_intransit = 0; bd_state_change(slot->s_bdh); }
void sda_slot_insert(void *arg) { sda_slot_t *slot = arg; if (sda_init_card(slot) != SDA_EOK) { /* * Remove power from the slot. If a more severe fault * occurred, then a manual reset with cfgadm will be needed. */ sda_slot_err(slot, "Unable to initialize card!"); sda_slot_enter(slot); sda_slot_power_off(slot); sda_slot_abort(slot, SDA_ENODEV); sda_slot_exit(slot); sda_nexus_remove(slot); } else { sda_nexus_insert(slot); } slot->s_stamp = ddi_get_time(); slot->s_intransit = 0; }