|
|
1.1 ! root 1: #include "vdfmt.h" ! 2: #include "cmd.h" ! 3: ! 4: ! 5: /* ! 6: ** ! 7: */ ! 8: ! 9: extern int wait_for_char; ! 10: ! 11: static cmd_text_element nul_table[] = { ! 12: { 0, "", "" } ! 13: }; ! 14: ! 15: char *clean_up = "Cleaning up... Please wait.\n"; ! 16: ! 17: ! 18: /* ! 19: ** ! 20: */ ! 21: ! 22: poll(wait) ! 23: int wait; ! 24: { ! 25: int tokens[10]; ! 26: ! 27: wait_for_char = 0; ! 28: vdtimeout = wait*1000*1000; ! 29: uncache(&(dcb.operrsta)); ! 30: while (!((dcb.operrsta) & (DCBCMP | DCBABT))) { ! 31: if(kill_processes == false) { ! 32: get_text_cmd(nul_table, tokens); ! 33: if(kill_processes == true) { ! 34: indent(); ! 35: print(clean_up); ! 36: exdent(1); ! 37: } ! 38: } ! 39: vdtimeout--; ! 40: uncache(&(dcb.operrsta)); ! 41: if (vdtimeout <= 0) { ! 42: if(C_INFO.type == SMDCTLR) ! 43: printf("\nVDDC"); ! 44: else ! 45: printf("\nSMD-E"); ! 46: printf(": Controller timeout"); ! 47: VDDC_ABORT(C_INFO.addr, C_INFO.type); ! 48: DELAY(30000); ! 49: break; ! 50: } ! 51: } ! 52: if((vdtimeout > 0)) { ! 53: if(C_INFO.type == SMD_ECTLR) { ! 54: uncache(&(C_INFO.addr->cdr_csr)); ! 55: while(C_INFO.addr->cdr_csr & CS_GO) { ! 56: DELAY(50); ! 57: uncache(&(C_INFO.addr->cdr_csr)); ! 58: } ! 59: } ! 60: DELAY(500); ! 61: } ! 62: if((dcb.opcode == RD) || (dcb.opcode == RD_RAW)) ! 63: mtpr(0, PADC); ! 64: uncache(&(dcb.operrsta)); ! 65: wait_for_char = 1; ! 66: } ! 67: ! 68: ! 69: /* ! 70: ** Access_with_no_trailer is used to perform controller functions which ! 71: ** require no data movement. ! 72: */ ! 73: ! 74: access_with_no_trailer(function, wait_time) ! 75: int function, wait_time; ! 76: { ! 77: dcb.opcode = function; /* command */ ! 78: dcb.intflg = NOINT; ! 79: dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ ! 80: dcb.operrsta = 0; ! 81: dcb.devselect = (function == VDSTART) ? 0 : (char)cur.drive; ! 82: dcb.trailcnt = (char)0; ! 83: mdcb.firstdcb = &dcb; ! 84: mdcb.vddcstat = 0; ! 85: VDDC_ATTENTION(C_INFO.addr, &mdcb, C_INFO.type); ! 86: poll(wait_time); ! 87: if(vdtimeout <= 0) { ! 88: printf(" during startup operation.\n"); ! 89: _longjmp(abort_environ, 1); ! 90: } ! 91: return dcb.operrsta; ! 92: } ! 93: ! 94: ! 95: /* ! 96: ** access_dsk is used by other routines to do reads and writes to the disk. ! 97: ** The status of the read / write is returned to the caller for processing. ! 98: */ ! 99: ! 100: access_dsk(buf, dskaddr, func, count, wait) ! 101: char *buf; ! 102: dskadr *dskaddr; ! 103: int func, count, wait; ! 104: { ! 105: cur.daddr.cylinder = dskaddr->cylinder; ! 106: cur.daddr.track = dskaddr->track; ! 107: wait_for_char = 0; ! 108: dcb.opcode = func; /* format sector command */ ! 109: dcb.intflg = NOINT; ! 110: dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ ! 111: dcb.operrsta = 0; ! 112: dcb.devselect = (char)cur.drive; ! 113: if(func == SEEK) { ! 114: dcb.trailcnt = (char)(sizeof(trseek) / sizeof(long)); ! 115: dcb.trail.sktrail.skaddr.cylinder = dskaddr->cylinder; ! 116: dcb.trail.sktrail.skaddr.track = dskaddr->track; ! 117: dcb.trail.sktrail.skaddr.sector = dskaddr->sector; ! 118: } ! 119: else { ! 120: dcb.trailcnt = (char)(sizeof(trrw) / sizeof(long)); ! 121: dcb.trail.rwtrail.memadr = buf; ! 122: dcb.trail.rwtrail.wcount=count*(CURRENT->secsize/sizeof(short)); ! 123: dcb.trail.rwtrail.disk.cylinder = dskaddr->cylinder; ! 124: dcb.trail.rwtrail.disk.track = dskaddr->track; ! 125: dcb.trail.rwtrail.disk.sector = dskaddr->sector; ! 126: } ! 127: mdcb.firstdcb = &dcb; ! 128: mdcb.vddcstat = 0; ! 129: VDDC_ATTENTION(C_INFO.addr, &mdcb, C_INFO.type); ! 130: if(wait) { ! 131: poll(2*60); ! 132: if(vdtimeout <= 0) { ! 133: printf(" in access_dsk.\n"); ! 134: _longjmp(abort_environ, 1); ! 135: } ! 136: } ! 137: wait_for_char = 1; ! 138: return dcb.operrsta; ! 139: } ! 140: ! 141: ! 142: /* ! 143: ** Spin_up_drive starts the drives on a controller and waits around for ! 144: ** the drive to spin up if it is not already spinning. ! 145: */ ! 146: ! 147: spin_up_drive() ! 148: { ! 149: VDDC_RESET(C_INFO.addr, C_INFO.type); ! 150: if(C_INFO.type == SMD_ECTLR) { ! 151: C_INFO.addr->cdr_csr = 0; ! 152: C_INFO.addr->mdcb_tcf = AM_ENPDA; ! 153: C_INFO.addr->dcb_tcf = AM_ENPDA; ! 154: C_INFO.addr->trail_tcf = AM_ENPDA; ! 155: C_INFO.addr->data_tcf = AM_ENPDA; ! 156: C_INFO.addr->cdr_ccf = CCF_SEN | 0x8 | CCF_STS | ! 157: XMD_32BIT | BSZ_16WRD | CCF_ERR | ! 158: CCF_ENP | CCF_EPE | CCF_EDE | CCF_ECE; ! 159: } ! 160: access_with_no_trailer(INIT, 10); ! 161: access_with_no_trailer(DIAG, 20); ! 162: configure_drive(0); ! 163: } ! 164: ! 165: /* ! 166: ** Configure_drive tells the controller what kind of drive is attached ! 167: ** on a particular line. ! 168: */ ! 169: ! 170: configure_drive(pass) ! 171: int pass; ! 172: { ! 173: dcb.opcode = RSTCFG; /* command */ ! 174: dcb.intflg = NOINT; ! 175: dcb.nxtdcb = (fmt_dcb *)0; /* end of chain */ ! 176: dcb.operrsta = 0; ! 177: dcb.devselect = (char)cur.drive; ! 178: dcb.trail.rstrail.ncyl = CURRENT->ncyl; ! 179: dcb.trail.rstrail.nsurfaces = CURRENT->ntrak; ! 180: if(C_INFO.type == SMDCTLR) ! 181: dcb.trailcnt = (char)2; ! 182: else { ! 183: dcb.trailcnt = (char)4; ! 184: dcb.trail.rstrail.nsectors = CURRENT->nsec; ! 185: dcb.trail.rstrail.slip_sec = CURRENT->nslip; ! 186: dcb.trail.rstrail.recovery = 0x00; ! 187: C_INFO.addr->cyl_skew = (*C_INFO.cylinder_skew)(); ! 188: C_INFO.addr->trk_skew = (*C_INFO.track_skew)(); ! 189: } ! 190: mdcb.firstdcb = &dcb; ! 191: mdcb.vddcstat = 0; ! 192: VDDC_ATTENTION(C_INFO.addr, &mdcb, C_INFO.type); ! 193: poll(5); ! 194: if(vdtimeout <= 0) { ! 195: printf(" during drive configuration.\n"); ! 196: _longjmp(abort_environ, 1); ! 197: } ! 198: if(dcb.operrsta & (NOTCYLERR | DRVNRDY)) { ! 199: if(pass) { ! 200: printf("\nDrive failed to start!\n\n"); ! 201: _longjmp(abort_environ, -1); ! 202: } ! 203: access_with_no_trailer(VDSTART, (cur.drive * 6) + 62); ! 204: DELAY((cur.drive * 5500000) + 62000000); ! 205: configure_drive(1); ! 206: } ! 207: } ! 208: ! 209: ! 210: /* ! 211: ** data_ok checks an error status word for bit patterns ! 212: ** associated with error conditions from the VDDC controller. If a hardware ! 213: ** error is present then the problem is reported on the console and the program ! 214: ** is halted. If a data error is present the a zero is returned. ! 215: ** If everything is OK then a 1 is returned. ! 216: */ ! 217: ! 218: data_ok() ! 219: { ! 220: register int status = dcb.operrsta; ! 221: ! 222: if(status & HARD_ERROR){ ! 223: if(status & DRVNRDY) ! 224: printf("\nDrive is not ready!"); ! 225: else if(status & INVDADR) ! 226: printf("\nInvalid disk address issued!"); ! 227: else if(status & DNEMEM) ! 228: printf("\nNon-existent memory error!"); ! 229: else if(status & PARERR) ! 230: printf("\nMain memory parity error!"); ! 231: else if(status & OPABRT) ! 232: printf("\nCPU aborted operation!"); ! 233: else if(status & WPTERR) ! 234: printf("\nDrive is write protected!"); ! 235: else if(status & DSEEKERR) ! 236: printf("\nDisk seek error!"); ! 237: else if(status & CTLRERR) ! 238: printf("\nController hardware error!"); ! 239: else ! 240: printf("\nNot on cylinder error!"); ! 241: printf(" Status = 0x%lx", status); ! 242: if(C_INFO.type == SMD_ECTLR) ! 243: printf(" Error code = 0x%x", dcb.err_code & 0xff); ! 244: printf("\n"); ! 245: printf("cylinder = %d, track = %d,", dcb.err_cyl, dcb.err_trk); ! 246: printf(" sector = %d, op = 0x%x\n", dcb.err_sec, dcb.opcode); ! 247: reset_controller(); ! 248: dcb.operrsta &= HEADER_ERROR; ! 249: } ! 250: return (int)(!(status & (DATA_ERROR | HEADER_ERROR))); ! 251: } ! 252: ! 253: ! 254: /* ! 255: ** ! 256: */ ! 257: ! 258: reset_controller() ! 259: { ! 260: printf("Resetting controller. Please wait...\n"); ! 261: spin_up_drive(); ! 262: printf("Controller was reset successfully.\n"); ! 263: } ! 264: ! 265: /* ! 266: ** ! 267: */ ! 268: ! 269: static int indent_count; ! 270: ! 271: ! 272: /* ! 273: ** ! 274: */ ! 275: ! 276: indent() ! 277: { ! 278: indent_count += 2; ! 279: } ! 280: ! 281: ! 282: /* ! 283: ** ! 284: */ ! 285: ! 286: exdent(count) ! 287: int count; ! 288: { ! 289: if(count == -1) ! 290: indent_count = 0; ! 291: else ! 292: indent_count -= count * 2; ! 293: if(indent_count < 0) ! 294: indent_count = 0; ! 295: } ! 296: ! 297: ! 298: /* ! 299: ** ! 300: */ ! 301: /*VARARGS1*/ ! 302: print(par0, par1, par2, par3, par4, par5, par6) ! 303: char *par0, *par1, *par2, *par3, *par4, *par5, *par6; ! 304: { ! 305: register int count = indent_count; ! 306: ! 307: while(count--) ! 308: printf(" "); ! 309: printf(par0, par1, par2, par3, par4, par5, par6); ! 310: DELAY((strlen(par0) + 20) * 9000); ! 311: } ! 312:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.