/* * ATA (soft) reset */ EXPORT void ataReset(DrvTab *drv) { UW iob = drv->IOB; UW reg, tm; BOOL master; /* Set it to drive 0 */ ataSetDrive(drv, 0); /* Check the existence of drive 0 (Master) */ master = (InB(REG_DRVHEAD) == 0xff && InB(REG_STS) == 0xff) ? FALSE : TRUE; /* Reset pulse output */ reg = (drv->d.pcc.IOConf[0] & IOC_IO2_NONE)? REG_DEVCTL : REG_DEVCTL2; OutB(reg, dcSRST); WaitUsec(20); /* Wait for "20 usec" */ OutB(reg, dcNORM); /* Wait until it becomes ready status: Firstly set it to drive 1 when there is no "Master" */ for (tm = 0;;) { if (master == TRUE || ataSetDrive(drv, 0x100) == E_OK) { if ((ataStatusIn(drv) & stBSY) == 0) break; } if (drv->Spec.pccard && ataStatusIn(drv) == 0xff) break; /* There is no card */ if (sdChkTmout(&tm, RESET_TMO, 10)) break; } /* Set Drive (Master & Slave) to the reset status */ if (drv->Top != NULL) drv = drv->Top; for (; drv != NULL; drv = drv->Next) drv->Reset = TRUE; }
/* * Status check */ LOCAL W ataChkSts(DrvTab *drv, UB chk, UB ok) { UW iob = drv->IOB; W i; for (i = 0; i < STATUS_TMO; i += 10, WaitUsec(10)) { if ((InB(REG_STS) & chk) == ok) return E_OK; } return ERR_DATABUSY; }
/* * Drive setting */ EXPORT ER ataSetDrive(DrvTab *drv, W drvno) { UW iob = drv->IOB; UB dno; if (drvno < 0) drvno = drv->DrvNo; OutB(REG_DRVHEAD, dno = drDRV(drvno)); WaitUsec(4); /* Waiting is necessary depending on drive */ if (InB(REG_DRVHEAD) == dno) return E_OK; return ERR_NOPORT; }
VOID CalculateGenericAdapterTiming (NPA npA) { NPU npU; for (npU = npA->UnitCB; npU < (npA->UnitCB + MAX_UNITS); npU++) { /* For each attached unit */ if (npU->Flags & UCBF_NOTPRESENT) continue; npU->CurPIOMode = npU->FoundPIOMode; if ((npA->Cap & CHIPCAP_SATA) || (BMSTATUSREG && (InB (BMSTATUSREG) & (npU == npA->UnitCB ? 0x20 : 0x40)))) { if (npU->CurDMAMode > 0) npU->CurPIOMode = npU->CurDMAMode + 2; if (npU->UltraDMAMode > 0) npU->CurDMAMode = 3 + (npU->UltraDMAMode - 1); } else { npU->CurDMAMode = npU->UltraDMAMode = 0; npU->Flags &= ~UCBF_BM_DMA; } } }
VOID NEAR GenericInitComplete (NPA npA) { if (InB (npA->BMISTA) & 0x80) { /* busmaster supports simplex mode only */ /* serialize access to IDE chip */ if (npA->IDEChannel) { NPA mate; NPHWRESOURCE npHWR; mate = npA->npC->npA[1 - npA->IDEChannel]; if (!mate) return; npHWR = mate->npHWR; DISABLE npA->npHWR->npFirstACBX = 0; npHWR->npFirstACBX->npNextACBX = npA; npA->npNextACBX = 0; npA->npHWR = npHWR; ENABLE } }
/* * Cylinder register input */ EXPORT W ataCylIn(DrvTab *drv) { UW iob = drv->IOB; return (InB(REG_CYL_H) << 8) | InB(REG_CYL_L); }
/* * Error information input */ EXPORT W ataErrorIn(DrvTab *drv) { UW iob = drv->IOB; return InB(REG_ERR); }