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;
}
Beispiel #2
0
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);
}