|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1992 NeXT Computer, Inc. ! 3: * ! 4: * AHARoutines.c - low-level I/O routines for Adaptec 1542 driver. ! 5: * ! 6: * HISTORY ! 7: * ! 8: * 13 Apr 1993 Doug Mitchell at NeXT ! 9: * Split off from AHAController.m. ! 10: */ ! 11: ! 12: #import "AHATypes.h" ! 13: #import "AHAInline.h" ! 14: #import "AHAThread.h" ! 15: #import "AHAControllerPrivate.h" ! 16: #import <driverkit/generalFuncs.h> ! 17: #import <driverkit/kernelDriver.h> ! 18: ! 19: ! 20: void aha_start_scsi( ! 21: unsigned short base ! 22: ) ! 23: { ! 24: aha_stat_reg_t stat; ! 25: ! 26: do { ! 27: stat = aha_get_stat(base); ! 28: } while (stat.dataout_full); ! 29: ! 30: aha_put_cmd(base, AHA_CMD_START_SCSI); ! 31: } ! 32: ! 33: ! 34: boolean_t aha_probe_cmd( ! 35: unsigned short base, ! 36: unsigned char cmd, ! 37: unsigned char *args, ! 38: int arglen, ! 39: unsigned char *reply, ! 40: int replylen, ! 41: boolean_t polled ! 42: ) ! 43: { ! 44: aha_stat_reg_t stat; ! 45: aha_intr_reg_t intr; ! 46: boolean_t success = FALSE; ! 47: int fail_count = 100000; ! 48: ! 49: do { ! 50: stat = aha_get_stat(base); ! 51: } while (stat.dataout_full && fail_count--); ! 52: if (fail_count <= 0) ! 53: return FALSE; ! 54: ! 55: aha_put_cmd(base, cmd); ! 56: ! 57: while (arglen-- > 0) { ! 58: fail_count = 100000; ! 59: do { ! 60: intr = aha_get_intr(base); ! 61: stat = aha_get_stat(base); ! 62: if (intr.cmd_done && stat.cmd_err) ! 63: goto out; ! 64: } while (stat.dataout_full && fail_count--); ! 65: if (fail_count <= 0) ! 66: return FALSE; ! 67: ! 68: aha_put_cmd(base, *args++); ! 69: } ! 70: ! 71: while (replylen-- > 0) { ! 72: fail_count = 100000; ! 73: do { ! 74: intr = aha_get_intr(base); ! 75: stat = aha_get_stat(base); ! 76: if (intr.cmd_done && stat.cmd_err) ! 77: goto out; ! 78: } while (!stat.datain_full && fail_count--); ! 79: if (fail_count <= 0) ! 80: return FALSE; ! 81: ! 82: *reply++ = aha_get_cmd(base); ! 83: } ! 84: success = TRUE; ! 85: ! 86: fail_count = 100000; ! 87: if (polled) do { ! 88: intr = aha_get_intr(base); ! 89: } while (!intr.cmd_done && fail_count--); ! 90: if (fail_count <= 0) ! 91: success = FALSE; ! 92: ! 93: out: ! 94: if (polled) ! 95: aha_clr_intr(base); ! 96: ! 97: return (success); ! 98: } ! 99: ! 100: boolean_t aha_cmd( ! 101: unsigned short base, ! 102: unsigned char cmd, ! 103: unsigned char *args, ! 104: int arglen, ! 105: unsigned char *reply, ! 106: int replylen, ! 107: boolean_t polled ! 108: ) ! 109: { ! 110: aha_stat_reg_t stat; ! 111: aha_intr_reg_t intr; ! 112: boolean_t success = FALSE; ! 113: ! 114: do { ! 115: stat = aha_get_stat(base); ! 116: } while (stat.dataout_full); ! 117: ! 118: aha_put_cmd(base, cmd); ! 119: ! 120: while (arglen-- > 0) { ! 121: do { ! 122: intr = aha_get_intr(base); ! 123: stat = aha_get_stat(base); ! 124: if (intr.cmd_done && stat.cmd_err) ! 125: goto out; ! 126: } while (stat.dataout_full); ! 127: ! 128: aha_put_cmd(base, *args++); ! 129: } ! 130: ! 131: while (replylen-- > 0) { ! 132: do { ! 133: intr = aha_get_intr(base); ! 134: stat = aha_get_stat(base); ! 135: if (intr.cmd_done && stat.cmd_err) ! 136: goto out; ! 137: } while (!stat.datain_full); ! 138: ! 139: *reply++ = aha_get_cmd(base); ! 140: } ! 141: success = TRUE; ! 142: ! 143: if (polled) do { ! 144: intr = aha_get_intr(base); ! 145: } while (!intr.cmd_done); ! 146: ! 147: out: ! 148: if (polled) ! 149: aha_clr_intr(base); ! 150: ! 151: return (success); ! 152: } ! 153: ! 154: ! 155: void aha_reset_board( ! 156: unsigned short base, ! 157: unsigned char aha_board_id ! 158: ) ! 159: { ! 160: ! 161: aha_ctrl_reg_t ctrl = { 0 }; ! 162: aha_stat_reg_t stat; ! 163: ! 164: ctrl.sw_rst = 1; ! 165: ! 166: aha_put_ctrl(base, ctrl); ! 167: ! 168: /* Avoid a 174x standard mode firmware bug */ ! 169: if (aha_board_id == AHA_174xA) { ! 170: do { ! 171: stat = aha_get_stat(base); ! 172: } while (!stat.idle); ! 173: IOSleep(500); ! 174: } ! 175: else { ! 176: do { ! 177: stat = aha_get_stat(base); ! 178: } while (!stat.idle || !stat.mb_init_needed); ! 179: } ! 180: ! 181: aha_clr_intr(base); ! 182: } ! 183: ! 184: boolean_t aha_setup_mb_area( ! 185: unsigned short base, ! 186: struct aha_mb_area *ahaMbArea, ! 187: struct ccb *ahaCcb ! 188: ) ! 189: { ! 190: aha_cmd_init_t init; ! 191: int i; ! 192: unsigned *mbPhysAddr; ! 193: IOReturn rtn; ! 194: aha_mb_t *mbOutVirt; ! 195: aha_mb_t *mbInVirt; ! 196: struct ccb *ccbPhys; ! 197: struct ccb *ccbVirt; ! 198: ! 199: ddm_init("AHAController aha_setup_mb_area\n", 1,2,3,4,5); ! 200: ! 201: rtn = IOPhysicalFromVirtual(IOVmTaskSelf(), ! 202: (vm_address_t)ahaMbArea, ! 203: (unsigned *)&mbPhysAddr); ! 204: if(rtn) { ! 205: IOLog("AHAController: Can't get physical address of " ! 206: "ahaMbArea (%s)\n", [IODevice stringFromReturn:rtn]); ! 207: return FALSE; ! 208: } ! 209: aha_unlock_mb(base); ! 210: ! 211: init.mb_cnt = AHA_MB_CNT; ! 212: aha_put_24((vm_offset_t)mbPhysAddr, init.mb_area_addr); ! 213: ! 214: if (!aha_cmd(base, ! 215: AHA_CMD_INIT, (unsigned char *)&init, sizeof (init), ! 216: 0, 0, TRUE)) { ! 217: IOLog("aha at %x: mb_init failed\n", base); ! 218: return (FALSE); ! 219: } ! 220: ! 221: /* ! 222: * Setup CCBs and mailboxes. The CCB pointers in the mb_out mailboxes ! 223: * have to be physical addresses; the mb_out pointer in the ccb is a ! 224: * virtual address. ! 225: */ ! 226: mbOutVirt = &ahaMbArea->mb_out[0]; ! 227: mbInVirt = &ahaMbArea->mb_in[0]; ! 228: ccbVirt = ahaCcb; ! 229: ! 230: for (i = 0; i < AHA_MB_CNT; i++) { ! 231: ! 232: mbOutVirt->mb_stat = AHA_MB_OUT_FREE; ! 233: mbInVirt->mb_stat = AHA_MB_IN_FREE; ! 234: ccbVirt->mb_out = mbOutVirt; ! 235: ! 236: rtn = IOPhysicalFromVirtual(IOVmTaskSelf(), ! 237: (vm_address_t)ccbVirt, ! 238: (unsigned *)&ccbPhys); ! 239: if(rtn) { ! 240: IOLog("AHAController: Can't get physical address of " ! 241: "ccb (%s)\n", [IODevice stringFromReturn:rtn]); ! 242: return FALSE; ! 243: } ! 244: ddm_init("ccbPhys[%d] = 0x%x\n", i, ccbPhys, 3,4,5); ! 245: ! 246: aha_put_24((vm_offset_t) ccbPhys, mbOutVirt->ccb_addr); ! 247: ! 248: mbOutVirt++; ! 249: mbInVirt++; ! 250: ccbVirt++; ! 251: } ! 252: ! 253: return (TRUE); ! 254: } ! 255: ! 256: void aha_unlock_mb( ! 257: unsigned short base ! 258: ) ! 259: { ! 260: aha_mb_lock_t lock; ! 261: ! 262: /* ! 263: * Unlock the mailbox interface in case extended ! 264: * BIOS translation was used. ! 265: */ ! 266: if(!aha_probe_cmd(base, AHA_CMD_GET_BIOS_INFO, ! 267: 0, 0, (unsigned char*)&lock, sizeof(lock), TRUE)) { ! 268: return; ! 269: } ! 270: ! 271: lock.mb_status = 0; ! 272: aha_probe_cmd(base, AHA_CMD_SET_MB_ENABLE, ! 273: (unsigned char *)&lock, sizeof(lock), 0, 0, TRUE); ! 274: } ! 275:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.