int mmc_wait_command(SIM_HBA *hba) { SIM_MMC_EXT *ext; struct _pulse pulse; iov_t iov; int rcvid, intr=0, retry=0; ext = (SIM_MMC_EXT *)hba->ext; SETIOV(&iov, &pulse, sizeof(pulse)); while (1) { if ((rcvid = MsgReceivev(hba->chid, &iov, 1, NULL)) == -1) continue; intr = 0; switch (pulse.code) { case SIM_INTERRUPT: intr=ext->interrupt(hba, hba->cfg.IRQRegisters[0], ext->resp_type, ext->mmc_resp); InterruptUnmask(hba->cfg.IRQRegisters[0], hba->iid); break; case SIM_DMA_INTERRUPT: intr=ext->interrupt(hba, hba->cfg.IRQRegisters[0], ext->resp_type, ext->mmc_resp); if(hba->cfg.NumIRQs > 1) { InterruptUnmask(hba->cfg.IRQRegisters[1], ext->iid); } break; case SIM_TIMER: // Only check media if card detection interrupt is not supported if (!(ext->hccap & MMC_HCCAP_CD_INTR)) mmc_media_check(hba); if(!(ext->eflags & MMC_EFLAG_INSERTED)) return MMC_FAILURE; break; default: break; } if(intr & MMC_INTR_CARD){ mmc_media_check(hba); return MMC_FAILURE; } if((intr & MMC_INTR_COMMAND) && !(intr & MMC_INTR_ERROR)) return MMC_SUCCESS; if(retry++ >5) return MMC_FAILURE; } return MMC_FAILURE; }
static void mmc_unit_ready(SIM_HBA *hba) { SIM_MMC_EXT *ext = (SIM_MMC_EXT *)hba->ext; CCB_SCSIIO *ccb = ext->nexus; if (ext->eflags & MMC_EFLAG_MEDIA_CHANGED) { mmc_sense(hba, SK_UNIT_ATN, ASC_MEDIUM_CHANGED, ASCQ_UNKNOWN_CHANGED); atomic_clr(&ext->eflags, MMC_EFLAG_MEDIA_CHANGED); } else if (ext->eflags & MMC_EFLAG_READY) { if (ext->detect(hba) != MMC_SUCCESS) { mmc_media_check(hba); mmc_sense(hba, SK_NOT_RDY, ASC_MEDIA_NOT_PRESENT, 0); } else ccb->cam_ch.cam_status = CAM_REQ_CMP; } else mmc_sense(hba, SK_NOT_RDY, ASC_MEDIA_NOT_PRESENT, 0); }