|
|
1.1.1.2 ! root 1: /* $Id: sun-sc.c,v 1.6 2005/02/18 03:50:40 fredette Exp $ */ 1.1 root 2: 3: /* bus/multibus/sun-sc.c - implementation of Sun `sc' SCSI Multibus board emulation: */ 4: 5: /* 6: * Copyright (c) 2003 Matt Fredette 7: * All rights reserved. 8: * 9: * Redistribution and use in source and binary forms, with or without 10: * modification, are permitted provided that the following conditions 11: * are met: 12: * 1. Redistributions of source code must retain the above copyright 13: * notice, this list of conditions and the following disclaimer. 14: * 2. Redistributions in binary form must reproduce the above copyright 15: * notice, this list of conditions and the following disclaimer in the 16: * documentation and/or other materials provided with the distribution. 17: * 3. All advertising materials mentioning features or use of this software 18: * must display the following acknowledgement: 19: * This product includes software developed by Matt Fredette. 20: * 4. The name of the author may not be used to endorse or promote products 21: * derived from this software without specific prior written permission. 22: * 23: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 25: * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 26: * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 27: * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 28: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 29: * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 31: * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 32: * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 33: * POSSIBILITY OF SUCH DAMAGE. 34: */ 35: 36: #include <tme/common.h> 1.1.1.2 ! root 37: _TME_RCSID("$Id: sun-sc.c,v 1.6 2005/02/18 03:50:40 fredette Exp $"); 1.1 root 38: 39: /* includes: */ 40: #include <tme/generic/bus-device.h> 41: #include <tme/generic/scsi.h> 42: 43: /* macros: */ 44: 45: /* register offsets and sizes: */ 46: #define TME_SUN_SC_REG_DATA (0) 47: #define TME_SUN_SC_SIZ_DATA (sizeof(tme_uint8_t)) 48: #define TME_SUN_SC_REG_CMD_STAT (2) 49: #define TME_SUN_SC_SIZ_CMD_STAT (sizeof(tme_uint8_t)) 50: #define TME_SUN_SC_REG_ICR (4) 51: #define TME_SUN_SC_SIZ_ICR (sizeof(tme_uint16_t)) 52: #define TME_SUN_SC_REG_DMA_H (8) 53: #define TME_SUN_SC_SIZ_DMA_H (sizeof(tme_uint16_t)) 54: #define TME_SUN_SC_REG_DMA_L (10) 55: #define TME_SUN_SC_SIZ_DMA_L (sizeof(tme_uint16_t)) 56: #define TME_SUN_SC_REG_DMA_LEN (12) 57: #define TME_SUN_SC_SIZ_DMA_LEN (sizeof(tme_uint16_t)) 58: #define TME_SUN_SC_REG_INTVEC (15) 59: #define TME_SUN_SC_SIZ_INTVEC (sizeof(tme_uint8_t)) 60: #define TME_SUN_SC_SIZ_CARD (TME_SUN_SC_REG_INTVEC + TME_SUN_SC_SIZ_INTVEC) 61: 62: /* the bits in the Interface Control Register. bits greater than 63: or equal to SUNSCPAL_ICR_BUSY are read-only: */ 64: #define _TME_SUN_SC_ICR_RO_BITS (~(TME_SUN_SC_ICR_BUSY - 1)) 65: #define TME_SUN_SC_ICR_PARITY_ERROR (0x8000) /* parity error */ 66: #define TME_SUN_SC_ICR_BUS_ERROR (0x4000) /* bus error */ 67: #define TME_SUN_SC_ICR_ODD_LENGTH (0x2000) /* odd length */ 68: #define TME_SUN_SC_ICR_INT_REQUEST (0x1000) /* interrupt request */ 69: #define TME_SUN_SC_ICR_REQUEST (0x0800) /* request */ 70: #define TME_SUN_SC_ICR_MESSAGE (0x0400) /* message */ 71: #define TME_SUN_SC_ICR_COMMAND_DATA (0x0200) /* 1=command, 0=data */ 72: #define TME_SUN_SC_ICR_INPUT_OUTPUT (0x0100) /* 1=input (initiator should read), 0=output */ 73: #define TME_SUN_SC_ICR_PARITY (0x0080) /* parity */ 74: #define TME_SUN_SC_ICR_BUSY (0x0040) /* busy */ 75: #define TME_SUN_SC_ICR_SELECT (0x0020) /* select */ 76: #define TME_SUN_SC_ICR_RESET (0x0010) /* reset */ 77: #define TME_SUN_SC_ICR_PARITY_ENABLE (0x0008) /* enable parity */ 78: #define TME_SUN_SC_ICR_WORD_MODE (0x0004) /* word mode */ 79: #define TME_SUN_SC_ICR_DMA_ENABLE (0x0002) /* enable DMA */ 80: #define TME_SUN_SC_ICR_INT_ENABLE (0x0001) /* enable interrupts */ 81: 82: /* this gets the current SCSI information transfer bus phase, 83: including BSY, from an ICR value: */ 84: #define TME_SUN_SC_BUS_PHASE(icr) \ 85: ((icr) \ 86: & (TME_SUN_SC_ICR_BUSY \ 87: | TME_SUN_SC_ICR_MESSAGE \ 88: | TME_SUN_SC_ICR_COMMAND_DATA \ 89: | TME_SUN_SC_ICR_INPUT_OUTPUT)) 90: 91: /* these get and put a 16-bit register: */ 92: #define TME_SUN_SC_REG16_GET(sun_sc, reg) \ 93: tme_betoh_u16(*((tme_uint16_t *) &(sun_sc)->tme_sun_sc_card[reg])) 94: #define TME_SUN_SC_REG16_PUT(sun_sc, reg, val) \ 95: (*((tme_uint16_t *) &(sun_sc)->tme_sun_sc_card[reg]) = tme_htobe_u16(val)) 96: 97: /* these get and put the ICR: */ 98: #define TME_SUN_SC_ICR_GET(sun_sc) \ 99: TME_SUN_SC_REG16_GET(sun_sc, TME_SUN_SC_REG_ICR) 100: #define TME_SUN_SC_ICR_PUT(sun_sc, icr) \ 101: TME_SUN_SC_REG16_PUT(sun_sc, TME_SUN_SC_REG_ICR, icr) 102: 103: /* the size of the cycle callout ring buffer: */ 104: #define TME_SUN_SC_CYCLE_RING_SIZE (4) 105: 106: /* the callout flags: */ 107: #define TME_SUN_SC_CALLOUT_CHECK (0) 108: #define TME_SUN_SC_CALLOUT_RUNNING TME_BIT(0) 109: #define TME_SUN_SC_CALLOUTS_MASK (-2) 110: #define TME_SUN_SC_CALLOUT_CYCLE TME_BIT(1) 111: #define TME_SUN_SC_CALLOUT_TLB_FILL TME_BIT(2) 112: #define TME_SUN_SC_CALLOUT_INT TME_BIT(3) 113: 114: #if 1 115: #define TME_SUN_SC_DEBUG 116: #endif 117: 118: /* structures: */ 119: 120: /* an entry in the cycle callout ring buffer: */ 121: struct tme_sun_sc_cycle { 122: 123: /* the SCSI control and data signals to assert: */ 124: tme_scsi_control_t tme_sun_sc_cycle_control; 125: tme_scsi_data_t tme_sun_sc_cycle_data; 126: 1.1.1.2 ! root 127: /* the SCSI events to wait on, and the actions to take: */ ! 128: tme_uint32_t tme_sun_sc_cycle_events; ! 129: tme_uint32_t tme_sun_sc_cycle_actions; 1.1 root 130: 131: /* a DMA structure needed: */ 132: struct tme_scsi_dma tme_sun_sc_cycle_dma; 133: 134: /* for the cmd_stat DMA, the cmd_stat value: */ 135: tme_uint8_t tme_sun_sc_cycle_cmd_stat; 136: }; 137: 138: /* the card: */ 139: struct tme_sun_sc { 140: 141: /* our simple bus device header: */ 142: struct tme_bus_device tme_sun_sc_device; 143: #define tme_sun_sc_element tme_sun_sc_device.tme_bus_device_element 144: 145: /* the mutex protecting the card: */ 146: tme_mutex_t tme_sun_sc_mutex; 147: 148: /* the rwlock protecting the card: */ 149: tme_rwlock_t tme_sun_sc_rwlock; 150: 151: /* the SCSI bus connection: */ 152: struct tme_scsi_connection *tme_sun_sc_scsi_connection; 153: 154: /* the callout flags: */ 155: int tme_sun_sc_callout_flags; 156: 157: /* if our interrupt line is currently asserted: */ 158: int tme_sun_sc_int_asserted; 159: 160: /* it's easiest to just model the card as a chunk of memory: */ 161: tme_uint8_t tme_sun_sc_card[TME_SUN_SC_SIZ_CARD]; 162: 163: /* the cycle ring buffer: */ 164: struct tme_sun_sc_cycle tme_sun_sc_cycles[TME_SUN_SC_CYCLE_RING_SIZE]; 165: int tme_sun_sc_cycle_head; 166: int tme_sun_sc_cycle_tail; 167: 168: /* our DMA TLB set: */ 169: TME_ATOMIC(struct tme_bus_tlb *, tme_sun_sc_dma_tlb); 170: 171: /* the internal DMA buffer: */ 172: tme_uint8_t tme_sun_sc_int_dma[2]; 173: 174: #ifndef TME_NO_LOG 175: tme_uint16_t tme_sun_sc_last_log_icr; 176: #endif /* !TME_NO_LOG */ 177: }; 178: 179: /* globals: */ 180: 181: /* the Sun sc bus router: */ 182: static const tme_bus_lane_t tme_sun_sc_router[TME_BUS_ROUTER_SIZE(TME_BUS16_LOG2) * 2] = { 183: 184: /* [sc] initiator cycle size: 8 bits 185: [gen] responding port size: 8 bits 186: [gen] responding port least lane: 0: */ 187: /* D7-D0 */ TME_BUS_LANE_ROUTE(0), 188: /* D15-D8 */ TME_BUS_LANE_UNDEF, 189: 190: /* [sc] initiator cycle size: 8 bits 191: [gen] responding port size: 8 bits 192: [gen] responding port least lane: 1: */ 193: /* D7-D0 */ TME_BUS_LANE_ROUTE(0), 194: /* D15-D8 */ TME_BUS_LANE_UNDEF | TME_BUS_LANE_WARN, 195: 196: /* [sc] initiator cycle size: 8 bits 197: [gen] responding port size: 16 bits 198: [gen] responding port least lane: 0: */ 199: /* D7-D0 */ TME_BUS_LANE_ROUTE(0), 200: /* D15-D8 */ TME_BUS_LANE_UNDEF | TME_BUS_LANE_WARN, 201: 202: /* [sc] initiator cycle size: 8 bits 203: [gen] responding port size: 16 bits 204: [gen] responding port least lane: 1 - invalid, array placeholder: */ 205: /* D7-D0 */ TME_BUS_LANE_ABORT, 206: /* D15-D8 */ TME_BUS_LANE_ABORT, 207: 208: /* [sc] initiator cycle size: 16 bits 209: [gen] responding port size: 8 bits 210: [gen] responding port least lane: 0: */ 211: /* D7-D0 */ TME_BUS_LANE_ROUTE(0), 212: /* D15-D8 */ TME_BUS_LANE_ROUTE(1) | TME_BUS_LANE_WARN, 213: 214: /* [sc] initiator cycle size: 16 bits 215: [gen] responding port size: 8 bits 216: [gen] responding port least lane: 1: */ 217: /* D7-D0 */ TME_BUS_LANE_ROUTE(0) | TME_BUS_LANE_WARN, 218: /* D15-D8 */ TME_BUS_LANE_ROUTE(1) | TME_BUS_LANE_WARN, 219: 220: /* [sc] initiator cycle size: 16 bits 221: [gen] responding port size: 16 bits 222: [gen] responding port least lane: 0: */ 223: /* D7-D0 */ TME_BUS_LANE_ROUTE(0), 224: /* D15-D8 */ TME_BUS_LANE_ROUTE(1), 225: 226: /* [sc] initiator cycle size: 16 bits 227: [gen] responding port size: 16 bits 228: [gen] responding port least lane: 1 - invalid, array placeholder: */ 229: /* D7-D0 */ TME_BUS_LANE_ABORT, 230: /* D15-D8 */ TME_BUS_LANE_ABORT, 231: }; 232: 233: #ifdef TME_SUN_SC_DEBUG 234: void 235: _tme_sun_sc_reg16_put(struct tme_sun_sc *sun_sc, 236: int reg, 237: tme_uint16_t val_new) 238: { 239: const char *reg_name; 240: tme_uint16_t val_old; 241: 242: val_old = TME_SUN_SC_REG16_GET(sun_sc, reg); 243: if (val_old == val_new) { 244: return; 245: } 246: TME_SUN_SC_REG16_PUT(sun_sc, reg, val_new); 247: 248: switch (reg) { 249: case TME_SUN_SC_REG_ICR: 250: reg_name = "icr"; 251: break; 252: case TME_SUN_SC_REG_DMA_H: 253: case TME_SUN_SC_REG_DMA_L: 254: tme_log(&sun_sc->tme_sun_sc_element->tme_element_log_handle, 255: 100, TME_OK, 256: (&sun_sc->tme_sun_sc_element->tme_element_log_handle, 257: "dvma now 0x%04x%04x (len 0x%04x)", 258: TME_SUN_SC_REG16_GET(sun_sc, 259: TME_SUN_SC_REG_DMA_H), 260: TME_SUN_SC_REG16_GET(sun_sc, 261: TME_SUN_SC_REG_DMA_L), 262: (TME_SUN_SC_REG16_GET(sun_sc, 263: TME_SUN_SC_REG_DMA_LEN) 264: ^ 0xffff))); 265: return; 266: case TME_SUN_SC_REG_DMA_LEN: 267: reg_name = "len"; 268: val_new ^= 0xffff; 269: break; 270: default: 271: reg_name = "???"; 272: break; 273: } 274: tme_log(&sun_sc->tme_sun_sc_element->tme_element_log_handle, 275: 100, TME_OK, 276: (&sun_sc->tme_sun_sc_element->tme_element_log_handle, 277: "%s now 0x%04x", 278: reg_name, 279: val_new)); 280: } 281: #undef TME_SUN_SC_REG16_PUT 282: #define TME_SUN_SC_REG16_PUT _tme_sun_sc_reg16_put 283: #endif /* TME_SUN_SC_DEBUG */ 284: 285: /* this allocates the next cycle in the ring buffer: */ 286: struct tme_sun_sc_cycle * 287: _tme_sun_sc_cycle_new(struct tme_sun_sc *sun_sc, 1.1.1.2 ! root 288: tme_uint32_t events, ! 289: tme_uint32_t actions) 1.1 root 290: { 291: int old_head; 292: struct tme_sun_sc_cycle *sun_sc_cycle; 293: const struct tme_sun_sc_cycle *sun_sc_cycle_old; 294: 295: /* abort if the ring buffer overflows: */ 296: old_head = sun_sc->tme_sun_sc_cycle_head; 297: sun_sc->tme_sun_sc_cycle_head 298: = ((old_head 299: + 1) 300: & (TME_SUN_SC_CYCLE_RING_SIZE 301: - 1)); 302: if ((sun_sc->tme_sun_sc_cycle_head 303: == sun_sc->tme_sun_sc_cycle_tail) 304: && (sun_sc->tme_sun_sc_scsi_connection 305: != NULL)) { 306: abort(); 307: } 308: 309: /* initialize and return the cycle. we copy the previous cycle's 310: control signals, (and data signals too, unless the caller wants 311: the DMA sequence), so that callers only have to change the values 312: that they know are changing: */ 313: sun_sc_cycle 314: = &sun_sc->tme_sun_sc_cycles[old_head]; 315: memset(sun_sc_cycle, 0, sizeof(*sun_sc_cycle)); 316: sun_sc_cycle_old 317: = &sun_sc->tme_sun_sc_cycles[((old_head 318: - 1) 319: & (TME_SUN_SC_CYCLE_RING_SIZE 320: - 1))]; 321: sun_sc_cycle->tme_sun_sc_cycle_control 322: = sun_sc_cycle_old->tme_sun_sc_cycle_control; 323: sun_sc_cycle->tme_sun_sc_cycle_data 1.1.1.2 ! root 324: = ((actions ! 325: == TME_SCSI_ACTION_DMA_INITIATOR) 1.1 root 326: ? 0 327: : sun_sc_cycle_old->tme_sun_sc_cycle_data); 1.1.1.2 ! root 328: sun_sc_cycle->tme_sun_sc_cycle_events = events; ! 329: sun_sc_cycle->tme_sun_sc_cycle_actions = actions; 1.1 root 330: /* XXX parity? */ 331: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_flags 332: = TME_SCSI_DMA_8BIT; 333: return (sun_sc_cycle); 334: } 335: 336: /* this does a bus cycle to read or write into our internal DMA 337: buffer: */ 338: static int 339: _tme_sun_sc_bus_cycle_dma(struct tme_sun_sc *sun_sc, 340: struct tme_bus_tlb *tlb, 341: tme_uint8_t cycle_type, 342: tme_bus_addr_t address, 343: int word_mode) 344: { 345: struct tme_bus_cycle cycle_init; 346: int rc; 347: 348: /* use our internal DMA buffer: */ 349: cycle_init.tme_bus_cycle_buffer 350: = &sun_sc->tme_sun_sc_int_dma[0]; 351: 352: /* if we're in word mode, use the 16-bit bus router 353: and a 16-bit cycle size: */ 354: if (word_mode) { 355: cycle_init.tme_bus_cycle_lane_routing 356: = &tme_sun_sc_router[TME_BUS_ROUTER_SIZE(TME_BUS16_LOG2)]; 357: cycle_init.tme_bus_cycle_size 358: = sizeof(tme_uint16_t); 359: } 360: 361: /* otherwise, use the 8-bit bus router and an 8-bit 362: cycle size: */ 363: else { 364: cycle_init.tme_bus_cycle_lane_routing 365: = &tme_sun_sc_router[0]; 366: cycle_init.tme_bus_cycle_size 1.1.1.2 ! root 367: = sizeof(tme_uint8_t); 1.1 root 368: } 369: 370: assert (tlb->tme_bus_tlb_addr_shift == 0); 371: cycle_init.tme_bus_cycle_address 372: = (address 373: + tlb->tme_bus_tlb_addr_offset); 374: 375: cycle_init.tme_bus_cycle_buffer_increment 376: = 1; 377: 378: cycle_init.tme_bus_cycle_type 379: = cycle_type; 380: 381: cycle_init.tme_bus_cycle_port = 382: TME_BUS_CYCLE_PORT(0, TME_BUS16_LOG2); 383: 384: /* unlock the mutex: */ 385: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 386: 387: /* run the bus cycle: */ 388: rc = ((*tlb->tme_bus_tlb_cycle) 389: (tlb->tme_bus_tlb_cycle_private, 390: &cycle_init)); 391: 392: /* lock the mutex: */ 393: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 394: 395: return (rc); 396: } 397: 398: /* the Sun sc callout function. it must be called with the mutex locked: */ 399: static void 400: _tme_sun_sc_callout(struct tme_sun_sc *sun_sc, int new_callouts) 401: { 402: struct tme_scsi_connection *conn_scsi; 403: struct tme_bus_connection *conn_bus; 404: struct tme_bus_tlb *tlb; 1.1.1.2 ! root 405: struct tme_bus_tlb tlb_local; 1.1 root 406: int old_tail; 407: struct tme_sun_sc_cycle *sun_sc_cycle; 408: int callouts, later_callouts; 409: tme_bus_addr_t address; 410: tme_uint16_t resid; 411: tme_uint8_t cycle_type; 412: tme_bus_addr_t avail; 413: tme_uint8_t *emulator_off; 414: tme_uint16_t icr; 415: int rc; 416: int int_asserted; 417: 418: /* add in any new callouts: */ 419: sun_sc->tme_sun_sc_callout_flags |= new_callouts; 420: 421: /* if this function is already running in another thread, simply 422: return now. the other thread will do our work: */ 423: if (sun_sc->tme_sun_sc_callout_flags 424: & TME_SUN_SC_CALLOUT_RUNNING) { 425: return; 426: } 427: 428: /* callouts are now running: */ 429: sun_sc->tme_sun_sc_callout_flags 430: |= TME_SUN_SC_CALLOUT_RUNNING; 431: 432: /* assume that we won't need any later callouts: */ 433: later_callouts = 0; 434: 435: /* loop while callouts are needed: */ 436: for (; ((callouts 437: = sun_sc->tme_sun_sc_callout_flags) 438: & TME_SUN_SC_CALLOUTS_MASK); ) { 439: 440: /* clear the needed callouts: */ 441: sun_sc->tme_sun_sc_callout_flags 442: = (callouts 443: & ~TME_SUN_SC_CALLOUTS_MASK); 444: callouts 445: &= TME_SUN_SC_CALLOUTS_MASK; 446: 447: /* get this card's bus and SCSI connections: */ 448: conn_scsi = sun_sc->tme_sun_sc_scsi_connection; 449: conn_bus = TME_ATOMIC_READ(struct tme_bus_connection *, 450: sun_sc->tme_sun_sc_device.tme_bus_device_connection); 451: 452: /* if we need to call out a SCSI bus cycle: */ 453: if (callouts & TME_SUN_SC_CALLOUT_CYCLE) { 454: 455: /* there must be a cycle to call out: */ 456: old_tail = sun_sc->tme_sun_sc_cycle_tail; 457: assert (old_tail 458: != sun_sc->tme_sun_sc_cycle_head); 459: sun_sc_cycle 460: = &sun_sc->tme_sun_sc_cycles[old_tail]; 461: 462: /* unlock the mutex: */ 463: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 464: 465: /* do the callout: */ 1.1.1.2 ! root 466: /* XXX FIXME THREADS - this is not thread-safe, since we're ! 467: passing values from (and pointers to) the non-local ! 468: sun_sc_cycle: */ 1.1 root 469: rc = (conn_scsi != NULL 470: ? ((*conn_scsi->tme_scsi_connection_cycle) 471: (conn_scsi, 472: sun_sc_cycle->tme_sun_sc_cycle_control, 473: sun_sc_cycle->tme_sun_sc_cycle_data, 1.1.1.2 ! root 474: sun_sc_cycle->tme_sun_sc_cycle_events, ! 475: sun_sc_cycle->tme_sun_sc_cycle_actions, ! 476: ((sun_sc_cycle->tme_sun_sc_cycle_actions ! 477: == TME_SCSI_ACTION_DMA_INITIATOR) 1.1 root 478: ? &sun_sc_cycle->tme_sun_sc_cycle_dma 479: : NULL))) 480: : TME_OK); 481: 482: /* lock the mutex: */ 483: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 484: 485: /* if the callout was unsuccessful, remember that at some later 486: time this callout should be attempted again: */ 487: if (rc != TME_OK) { 488: later_callouts |= TME_SUN_SC_CALLOUT_CYCLE; 489: } 490: 491: /* otherwise, this callout was successful. if this cycle did 492: not use the DMA initiator sequence, it either used no 493: sequence or it used the wait_change sequence: */ 1.1.1.2 ! root 494: else if (sun_sc_cycle->tme_sun_sc_cycle_actions ! 495: != TME_SCSI_ACTION_DMA_INITIATOR) { 1.1 root 496: 497: /* advance the tail pointer if it hasn't been advanced 498: already: */ 499: if (sun_sc->tme_sun_sc_cycle_tail 500: == old_tail) { 501: sun_sc->tme_sun_sc_cycle_tail 502: = ((sun_sc->tme_sun_sc_cycle_tail 503: + 1) 504: & (TME_SUN_SC_CYCLE_RING_SIZE 505: - 1)); 506: } 507: 508: /* if there are more cycles to run, run them now: */ 509: if (sun_sc->tme_sun_sc_cycle_tail 510: != sun_sc->tme_sun_sc_cycle_head) { 511: sun_sc->tme_sun_sc_callout_flags 512: |= TME_SUN_SC_CALLOUT_CYCLE; 513: } 514: } 515: } 516: 517: /* if we need to call out a TLB fill: */ 518: if (callouts & TME_SUN_SC_CALLOUT_TLB_FILL) { 519: 520: /* get the current ICR value: */ 521: icr = TME_SUN_SC_ICR_GET(sun_sc); 522: 523: /* get the DMA address: */ 524: address 525: = TME_SUN_SC_REG16_GET(sun_sc, 526: TME_SUN_SC_REG_DMA_H); 527: address 528: = ((address 529: << 16) 530: | TME_SUN_SC_REG16_GET(sun_sc, 531: TME_SUN_SC_REG_DMA_L)); 532: 533: /* get the cycle type: */ 534: cycle_type 535: = ((icr 536: & TME_SUN_SC_ICR_INPUT_OUTPUT) 537: ? TME_BUS_CYCLE_WRITE 538: : TME_BUS_CYCLE_READ); 539: 540: /* get the resid: */ 541: resid 542: = (TME_SUN_SC_REG16_GET(sun_sc, 543: TME_SUN_SC_REG_DMA_LEN) 544: ^ 0xffff); 545: assert (resid 546: >= ((icr 547: & TME_SUN_SC_ICR_WORD_MODE) 548: ? sizeof(tme_uint16_t) 549: : sizeof(tme_uint8_t))); 550: 551: /* get the TLB entry: */ 552: tlb 553: = TME_ATOMIC_READ(struct tme_bus_tlb *, 554: sun_sc->tme_sun_sc_dma_tlb); 1.1.1.2 ! root 555: ! 556: /* reserve this TLB entry: */ ! 557: tme_bus_tlb_reserve(tlb, &tlb_local); ! 558: tlb = &tlb_local; 1.1 root 559: 560: /* unlock the mutex: */ 561: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 562: 563: /* do the callout: */ 564: rc = (conn_bus != NULL 565: ? ((*conn_bus->tme_bus_tlb_fill) 566: (conn_bus, 567: tlb, 568: address, 569: cycle_type)) 570: : TME_OK); 571: 572: /* lock the mutex: */ 573: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 574: 575: /* if the callout was unsuccessful, remember that at some later 576: time this callout should be attempted again: */ 577: if (rc != TME_OK) { 578: later_callouts |= TME_SUN_SC_CALLOUT_TLB_FILL; 579: } 580: 581: /* otherwise, use the filled TLB entry to start a SCSI 582: DMA sequence: */ 583: else { 584: 1.1.1.2 ! root 585: /* store the TLB entry: */ ! 586: tme_bus_tlb_back(tlb); ! 587: 1.1 root 588: /* get the number of bytes available in this TLB entry: */ 589: avail 590: = ((TME_ATOMIC_READ(tme_bus_addr_t, 591: tlb->tme_bus_tlb_addr_last) 592: - address) 593: + 1); 594: if (avail == 0 595: || avail > resid) { 596: avail = resid; 597: } 598: assert (avail 599: >= ((icr 600: & TME_SUN_SC_ICR_WORD_MODE) 601: ? sizeof(tme_uint16_t) 602: : sizeof(tme_uint8_t))); 603: 604: /* allocate the new SCSI bus cycle: */ 605: sun_sc_cycle 606: = _tme_sun_sc_cycle_new(sun_sc, 1.1.1.2 ! root 607: TME_SCSI_EVENT_NONE, ! 608: TME_SCSI_ACTION_DMA_INITIATOR); 1.1 root 609: 610: /* if this TLB entry allows fast transfers: */ 611: emulator_off 612: = ((cycle_type 613: == TME_BUS_CYCLE_READ) 1.1.1.2 ! root 614: ? (tme_uint8_t *) tlb->tme_bus_tlb_emulator_off_read 1.1 root 615: : tlb->tme_bus_tlb_emulator_off_write); 616: if (emulator_off 617: != TME_EMULATOR_OFF_UNDEF) { 618: 619: /* do the SCSI DMA sequence with the TLB fast transfer 620: buffer: */ 621: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in 622: = emulator_off + address; 623: } 624: 625: /* otherwise, this TLB entry does not allow fast transfers: */ 626: else { 627: 628: /* if this we need to read from this TLB, do a memory 629: read cycle into our internal DMA buffer: */ 630: if (cycle_type == TME_BUS_CYCLE_READ) { 631: rc = _tme_sun_sc_bus_cycle_dma(sun_sc, 1.1.1.2 ! root 632: /* XXX FIXME this is not thread-safe: */ 1.1 root 633: tlb, 634: TME_BUS_CYCLE_READ, 635: address, 636: (icr 637: & TME_SUN_SC_ICR_WORD_MODE)); 638: assert (rc == TME_OK); 639: } 640: 641: /* do the SCSI DMA sequence with our internal DMA buffer: */ 642: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in 643: = emulator_off + address; 644: avail 645: = ((icr 646: & TME_SUN_SC_ICR_WORD_MODE) 647: ? sizeof(tme_uint16_t) 648: : sizeof(tme_uint8_t)); 649: } 650: 651: /* finish the SCSI cycle: */ 652: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_out 653: = sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in; 654: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_resid 655: = avail; 656: 657: /* we now need to call out a SCSI cycle: */ 658: sun_sc->tme_sun_sc_callout_flags 659: |= TME_SUN_SC_CALLOUT_CYCLE; 660: } 661: } 662: 663: /* if we need to call out a possible change to our interrupt 664: signal: */ 665: if (callouts & TME_SUN_SC_CALLOUT_INT) { 666: 667: /* get the current ICR value: */ 668: icr = TME_SUN_SC_ICR_GET(sun_sc); 669: 670: /* see if the interrupt signal should be asserted or negated: */ 671: int_asserted = ((icr 672: & TME_SUN_SC_ICR_INT_REQUEST) 673: && (icr 674: & TME_SUN_SC_ICR_INT_ENABLE)); 675: 676: /* if the interrupt signal doesn't already have the right state: */ 677: if (!int_asserted 678: != !sun_sc->tme_sun_sc_int_asserted) { 679: 680: /* unlock our mutex: */ 681: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 682: 683: /* call out the bus interrupt signal edge: */ 684: rc = (*conn_bus->tme_bus_signal) 685: (conn_bus, 686: TME_BUS_SIGNAL_INT_UNSPEC 687: | (int_asserted 688: ? TME_BUS_SIGNAL_LEVEL_ASSERTED 1.1.1.2 ! root 689: : TME_BUS_SIGNAL_LEVEL_NEGATED)); 1.1 root 690: 691: /* lock our mutex: */ 692: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 693: 694: /* if this callout was successful, note the new state of the 695: interrupt signal: */ 696: if (rc == TME_OK) { 697: sun_sc->tme_sun_sc_int_asserted = int_asserted; 698: } 699: 700: /* otherwise, remember that at some later time this callout 701: should be attempted again: */ 702: else { 703: later_callouts |= TME_SUN_SC_CALLOUT_INT; 704: } 705: } 706: } 707: } 708: 709: /* put in any later callouts, and clear that callouts are running: */ 710: sun_sc->tme_sun_sc_callout_flags = later_callouts; 711: } 712: 1.1.1.2 ! root 713: /* the interrupt acknowledge function for the VME version: */ ! 714: static int ! 715: _tme_sun_sc_intack(void *_sun_sc, unsigned int signal, int *_vector) ! 716: { ! 717: struct tme_sun_sc *sun_sc; ! 718: ! 719: /* recover our data structure: */ ! 720: sun_sc = (struct tme_sun_sc *) _sun_sc; ! 721: ! 722: /* return the interrupt vector: */ ! 723: *_vector = sun_sc->tme_sun_sc_card[TME_SUN_SC_REG_INTVEC]; ! 724: ! 725: return (TME_OK); ! 726: } ! 727: 1.1 root 728: /* the Sun sc bus cycle handler for the data and cmd_stat registers. 729: these registers are connected directly to the SCSI data signals. 730: 731: a read of one of these registers samples the SCSI data bus, and a 732: write to one of these registers changes the SCSI data bus signals 733: asserted by the card. 734: 735: additionally, depending on context, a read or write of one of these 736: registers will cause the card to execute the initiator's side of a 737: REQ/ACK handshake to transfer a byte. 738: 739: a read or write of the cmd_stat register always causes the 740: handshake. a read or write of the data register when the SCSI bus 741: is in the DATA IN or DATA OUT phase with REQ asserted also causes 742: the handshake: */ 743: static int 744: _tme_sun_sc_bus_cycle_data_reg(struct tme_sun_sc *sun_sc, 745: struct tme_bus_cycle *cycle_init, 746: int is_cmd_stat) 747: { 748: tme_uint16_t icr; 749: tme_scsi_data_t data_old, data_new; 750: struct tme_sun_sc_cycle *sun_sc_cycle; 751: int new_callouts; 752: 753: /* assume we won't need any new callouts: */ 754: new_callouts = 0; 755: 756: /* lock the mutex: */ 757: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 758: 759: /* get the current ICR value: */ 760: icr = TME_SUN_SC_ICR_GET(sun_sc); 761: 762: /* save the old data register (really, the current 763: signals asserted on the data bus), and, in case 764: this is a read of the cmd_stat register, save 765: it in that register: */ 766: data_old = sun_sc->tme_sun_sc_card[TME_SUN_SC_REG_DATA]; 767: sun_sc->tme_sun_sc_card[TME_SUN_SC_REG_CMD_STAT] = data_old; 768: 769: /* run the cycle: */ 770: tme_bus_cycle_xfer_memory(cycle_init, 771: sun_sc->tme_sun_sc_card, 772: sun_sc->tme_sun_sc_device.tme_bus_device_address_last); 773: 774: /* put back the old data register, but get any value that 775: may have been written: */ 776: data_new 777: = (is_cmd_stat 778: ? sun_sc->tme_sun_sc_card[TME_SUN_SC_REG_CMD_STAT] 779: : sun_sc->tme_sun_sc_card[TME_SUN_SC_REG_DATA]); 780: sun_sc->tme_sun_sc_card[TME_SUN_SC_REG_DATA] = data_old; 781: 782: /* if this was a read or write of the cmd_stat register, or a read 783: or write of the data register while the bus is in the DATA IN or 784: DATA OUT phase with REQ asserted, do the initiator's side of the 785: REQ/ACK handshake: */ 786: if (is_cmd_stat 787: || ((icr 788: & (TME_SUN_SC_ICR_BUSY 789: | TME_SUN_SC_ICR_MESSAGE 790: | TME_SUN_SC_ICR_COMMAND_DATA 791: | TME_SUN_SC_ICR_REQUEST)) 792: == (TME_SUN_SC_ICR_BUSY 793: | TME_SUN_SC_ICR_REQUEST))) { 794: 795: /* make a new SCSI bus cycle: */ 796: /* XXX parity? */ 797: sun_sc_cycle 798: = _tme_sun_sc_cycle_new(sun_sc, 1.1.1.2 ! root 799: TME_SCSI_EVENT_NONE, ! 800: TME_SCSI_ACTION_DMA_INITIATOR); 1.1 root 801: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_resid 802: = sizeof(sun_sc_cycle->tme_sun_sc_cycle_cmd_stat); 803: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in 804: = &sun_sc_cycle->tme_sun_sc_cycle_cmd_stat; 805: sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_out 806: = &sun_sc_cycle->tme_sun_sc_cycle_cmd_stat; 807: sun_sc_cycle->tme_sun_sc_cycle_cmd_stat 808: = data_new; 809: 810: tme_log(&sun_sc->tme_sun_sc_element->tme_element_log_handle, 811: 100, TME_OK, 812: (&sun_sc->tme_sun_sc_element->tme_element_log_handle, 813: ((cycle_init->tme_bus_cycle_type 814: == TME_BUS_CYCLE_WRITE) 815: ? (is_cmd_stat 816: ? "0x%02x -> cmd_stat" 817: : "0x%02x -> data (handshake)") 818: : (is_cmd_stat 819: ? "cmd_stat-> 0x%02x" 820: : "data -> 0x%02x (handshake)")), 821: sun_sc_cycle->tme_sun_sc_cycle_cmd_stat)); 822: 823: new_callouts |= TME_SUN_SC_CALLOUT_CYCLE; 824: 825: /* since this SCSI DMA sequence won't be run right away, it's 826: important that we clear REQ now - otherwise if the sc device 827: driver happens to see REQ still set, it will think that the SCSI 828: handshake *did* happen, and that this REQ is now requesting the 829: next byte. when the DMA sequence ends we'll get a cycle call 830: that will bring us up-to-date: */ 831: TME_SUN_SC_ICR_PUT(sun_sc, 832: (icr 833: & ~TME_SUN_SC_ICR_REQUEST)); 834: } 835: 836: /* otherwise, if this was a write of the data register in a 837: non-handshake bus phase: */ 838: else if (cycle_init->tme_bus_cycle_type 839: == TME_BUS_CYCLE_WRITE) { 840: 841: /* if the data signals that we are asserting have changed, call 842: out a cycle, then wait: */ 843: sun_sc_cycle 844: = &sun_sc->tme_sun_sc_cycles[((sun_sc->tme_sun_sc_cycle_head 845: - 1) 846: & (TME_SUN_SC_CYCLE_RING_SIZE 847: - 1))]; 848: if (data_new != sun_sc_cycle->tme_sun_sc_cycle_data) { 849: tme_log(&sun_sc->tme_sun_sc_element->tme_element_log_handle, 850: 100, TME_OK, 851: (&sun_sc->tme_sun_sc_element->tme_element_log_handle, 852: "0x%02x -> data (no handshake)", 853: data_new)); 854: sun_sc_cycle 855: = _tme_sun_sc_cycle_new(sun_sc, 1.1.1.2 ! root 856: TME_SCSI_EVENT_BUS_CHANGE, ! 857: TME_SCSI_ACTION_NONE); 1.1 root 858: sun_sc_cycle->tme_sun_sc_cycle_data 859: = data_new; 860: new_callouts 861: |= TME_SUN_SC_CALLOUT_CYCLE; 862: } 863: } 864: 865: /* otherwise, this was a read of the data register in a 866: non-handshake bus phase: */ 867: else { 868: tme_log(&sun_sc->tme_sun_sc_element->tme_element_log_handle, 869: 100, TME_OK, 870: (&sun_sc->tme_sun_sc_element->tme_element_log_handle, 871: "data -> 0x%02x (no handshake)", 872: data_old)); 873: } 874: 875: /* make any new callouts: */ 876: _tme_sun_sc_callout(sun_sc, new_callouts); 877: 878: /* unlock the mutex: */ 879: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 880: 881: /* no faults: */ 882: return (TME_OK); 883: } 884: 885: /* the Sun sc bus cycle handler for the data register. this register 886: is connected directly to the SCSI data signals: */ 887: static int 888: _tme_sun_sc_bus_cycle_data(void *_sun_sc, 889: struct tme_bus_cycle *cycle_init) 890: { 891: return (_tme_sun_sc_bus_cycle_data_reg((struct tme_sun_sc *) _sun_sc, 892: cycle_init, 893: FALSE)); 894: } 895: 896: /* the Sun sc bus cycle handler for the command/status register. this 897: register is also connected directly to the SCSI data signals, but 898: reading or writing it additionally causes the card to execute the 899: initiator's side of a REQ/ACK handshake to transfer a byte: */ 900: static int 901: _tme_sun_sc_bus_cycle_cmd_stat(void *_sun_sc, 902: struct tme_bus_cycle *cycle_init) 903: { 904: return (_tme_sun_sc_bus_cycle_data_reg((struct tme_sun_sc *) _sun_sc, 905: cycle_init, 906: TRUE)); 907: } 908: 909: /* this tries to start or continue a DMA transfer: */ 910: static int 911: _tme_sun_sc_dma_start(struct tme_sun_sc *sun_sc, 912: tme_uint16_t *_icr) 913: { 914: tme_uint16_t icr; 915: tme_uint16_t resid; 916: 917: /* get the current ICR value: */ 918: icr = *_icr; 919: 920: /* get the resid: */ 921: resid 922: = (TME_SUN_SC_REG16_GET(sun_sc, 923: TME_SUN_SC_REG_DMA_LEN) 924: ^ 0xffff); 925: 926: tme_log(&sun_sc->tme_sun_sc_element->tme_element_log_handle, 927: 100, TME_OK, 928: (&sun_sc->tme_sun_sc_element->tme_element_log_handle, 929: "dma_start: icr=0x%04x dvma=0x%04x%04x len=0x%04x", 930: icr, 931: TME_SUN_SC_REG16_GET(sun_sc, 932: TME_SUN_SC_REG_DMA_H), 933: TME_SUN_SC_REG16_GET(sun_sc, 934: TME_SUN_SC_REG_DMA_L), 935: resid)); 936: 937: /* if we're not in the DATA IN or DATA OUT phases, do nothing. the 938: sun2 PROMs seem to set DMA_ENABLE when DMA is impossible: */ 939: if ((icr 940: & (TME_SUN_SC_ICR_DMA_ENABLE 941: | TME_SUN_SC_ICR_BUSY 942: | TME_SUN_SC_ICR_MESSAGE 943: | TME_SUN_SC_ICR_COMMAND_DATA 944: | TME_SUN_SC_ICR_REQUEST)) 945: != (TME_SUN_SC_ICR_DMA_ENABLE 946: | TME_SUN_SC_ICR_BUSY 947: | TME_SUN_SC_ICR_REQUEST)) { 948: return (TME_SUN_SC_CALLOUT_CHECK); 949: } 950: 951: /* if there are no more bytes left to transfer, we need 952: an interrupt: */ 953: if (resid == 0) { 954: *_icr 955: = ((icr 956: & ~TME_SUN_SC_ICR_ODD_LENGTH) 957: | TME_SUN_SC_ICR_INT_REQUEST); 958: return (TME_SUN_SC_CALLOUT_INT); 959: } 960: 961: /* if there is only one byte left to transfer, and we're in word 962: mode, note the odd byte, and we need an interrupt: */ 963: else if (resid == 1 964: && (icr 965: & TME_SUN_SC_ICR_WORD_MODE)) { 966: *_icr 967: = (icr 968: | TME_SUN_SC_ICR_ODD_LENGTH 969: | TME_SUN_SC_ICR_INT_REQUEST); 970: return (TME_SUN_SC_CALLOUT_INT); 971: } 972: 973: /* otherwise, start the DMA transfer with a TLB fill callout: */ 974: return (TME_SUN_SC_CALLOUT_TLB_FILL); 975: } 976: 977: /* the Sun sc bus cycle handler for the ICR. parts of this register 978: are connected directly to the SCSI control signals: */ 979: static int 980: _tme_sun_sc_bus_cycle_icr(void *_sun_sc, 981: struct tme_bus_cycle *cycle_init) 982: { 983: struct tme_sun_sc *sun_sc; 984: struct tme_sun_sc_cycle *sun_sc_cycle; 985: tme_uint16_t icr_old, icr_new, icr_diff; 986: int new_callouts; 987: 988: /* recover our data structure: */ 989: sun_sc = (struct tme_sun_sc *) _sun_sc; 990: 991: /* assume we won't need any new callouts: */ 992: new_callouts = 0; 993: 994: /* lock the mutex: */ 995: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 996: 997: /* save the old ICR value: */ 998: icr_old = TME_SUN_SC_ICR_GET(sun_sc); 999: icr_new = icr_old; 1000: 1001: /* if we were requesting an interrupt, clear it now and call out an 1002: interrupt change: */ 1003: if (icr_new & TME_SUN_SC_ICR_INT_REQUEST) { 1004: icr_new &= ~TME_SUN_SC_ICR_INT_REQUEST; 1005: new_callouts |= TME_SUN_SC_CALLOUT_INT; 1006: } 1007: 1008: /* run the bus cycle: */ 1009: tme_bus_cycle_xfer_memory(cycle_init, 1010: sun_sc->tme_sun_sc_card, 1011: sun_sc->tme_sun_sc_device.tme_bus_device_address_last); 1012: 1013: 1014: /* if this was a write: */ 1015: if (cycle_init->tme_bus_cycle_type 1016: == TME_BUS_CYCLE_WRITE) { 1017: 1018: /* put back the read-only bits: */ 1019: icr_new = TME_SUN_SC_ICR_GET(sun_sc); 1020: icr_new = ((icr_old 1021: & _TME_SUN_SC_ICR_RO_BITS) 1022: | (icr_new 1023: & ~_TME_SUN_SC_ICR_RO_BITS)); 1024: 1025: /* get the set of changed bits: */ 1026: icr_diff = icr_old ^ icr_new; 1027: 1028: /* a change in RESET: */ 1029: if (icr_diff & TME_SUN_SC_ICR_RESET) { 1030: 1031: /* make a new cycle that asserts no data or control signals, 1032: except possibly for RST: */ 1033: sun_sc_cycle 1034: = _tme_sun_sc_cycle_new(sun_sc, 1.1.1.2 ! root 1035: TME_SCSI_EVENT_BUS_CHANGE, ! 1036: TME_SCSI_ACTION_NONE); 1.1 root 1037: sun_sc_cycle->tme_sun_sc_cycle_control 1038: = ((icr_new 1039: & TME_SUN_SC_ICR_RESET) 1040: ? TME_SCSI_SIGNAL_RST 1041: : 0); 1042: sun_sc_cycle->tme_sun_sc_cycle_data 1043: = 0; 1044: new_callouts 1045: |= TME_SUN_SC_CALLOUT_CYCLE; 1046: } 1047: 1048: /* a change in SELECT: */ 1049: else if (icr_diff & TME_SUN_SC_ICR_SELECT) { 1050: 1051: /* make a new cycle that sets the new state of SEL: */ 1052: sun_sc_cycle 1053: = _tme_sun_sc_cycle_new(sun_sc, 1.1.1.2 ! root 1054: TME_SCSI_EVENT_BUS_CHANGE, ! 1055: TME_SCSI_ACTION_NONE); 1.1 root 1056: sun_sc_cycle->tme_sun_sc_cycle_control 1057: = ((sun_sc_cycle->tme_sun_sc_cycle_control 1058: & ~TME_SCSI_SIGNAL_SEL) 1059: | ((icr_new 1060: & TME_SUN_SC_ICR_SELECT) 1061: ? TME_SCSI_SIGNAL_SEL 1062: : 0)); 1063: new_callouts 1064: |= TME_SUN_SC_CALLOUT_CYCLE; 1065: } 1066: 1067: /* if DMA_ENABLE is now set: */ 1068: if (icr_diff 1069: & icr_new 1070: & TME_SUN_SC_ICR_DMA_ENABLE) { 1071: 1072: /* try to start DMA: */ 1073: new_callouts 1074: |= _tme_sun_sc_dma_start(sun_sc, 1075: &icr_new); 1076: } 1077: 1078: /* a change in INT_ENABLE: */ 1079: if (icr_diff 1080: & icr_new 1081: & TME_SUN_SC_ICR_INT_ENABLE) { 1082: 1083: /* our interrupt signal may be changing: */ 1084: new_callouts |= TME_SUN_SC_CALLOUT_INT; 1085: } 1086: } 1087: 1088: /* if the ICR changed, save and log the new value: */ 1089: if (icr_new != icr_old) { 1090: TME_SUN_SC_ICR_PUT(sun_sc, icr_new); 1091: } 1092: 1093: /* make any new callouts: */ 1094: _tme_sun_sc_callout(sun_sc, new_callouts); 1095: 1096: /* unlock the mutex: */ 1097: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 1098: 1099: /* no faults: */ 1100: return (TME_OK); 1101: } 1102: 1103: /* the Sun sc bus cycle handler for other card registers: */ 1104: static int 1105: _tme_sun_sc_bus_cycle_other(void *_sun_sc, 1106: struct tme_bus_cycle *cycle_init) 1107: { 1108: struct tme_sun_sc *sun_sc; 1109: 1110: /* recover our data structure: */ 1111: sun_sc = (struct tme_sun_sc *) _sun_sc; 1112: 1113: /* lock the mutex: */ 1114: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 1115: 1116: /* run the bus cycle: */ 1117: tme_bus_cycle_xfer_memory(cycle_init, 1118: sun_sc->tme_sun_sc_card, 1119: sun_sc->tme_sun_sc_device.tme_bus_device_address_last); 1120: 1121: /* if this was a write, dump out the other registers: */ 1122: if (cycle_init->tme_bus_cycle_type 1123: == TME_BUS_CYCLE_WRITE) { 1124: tme_log(&sun_sc->tme_sun_sc_element->tme_element_log_handle, 1125: 100, TME_OK, 1126: (&sun_sc->tme_sun_sc_element->tme_element_log_handle, 1127: "dvma=0x%04x%04x len=0x%04x", 1128: TME_SUN_SC_REG16_GET(sun_sc, 1129: TME_SUN_SC_REG_DMA_H), 1130: TME_SUN_SC_REG16_GET(sun_sc, 1131: TME_SUN_SC_REG_DMA_L), 1132: (TME_SUN_SC_REG16_GET(sun_sc, 1133: TME_SUN_SC_REG_DMA_LEN) 1134: ^ 0xffff))); 1135: } 1136: 1137: /* unlock the mutex: */ 1138: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 1139: 1140: /* no faults: */ 1141: return (TME_OK); 1142: } 1143: 1144: /* the Sun sc TLB filler: */ 1145: static int 1146: _tme_sun_sc_tlb_fill(void *_sun_sc, 1147: struct tme_bus_tlb *tlb, 1148: tme_bus_addr_t address, 1149: unsigned int cycles) 1150: { 1151: struct tme_sun_sc *sun_sc; 1152: 1153: /* recover our data structure: */ 1154: sun_sc = (struct tme_sun_sc *) _sun_sc; 1155: 1156: /* the address must be within range: */ 1157: assert(address < TME_SUN_SC_SIZ_CARD); 1158: 1159: /* initialize the TLB entry: */ 1160: tme_bus_tlb_initialize(tlb); 1161: 1162: #define TME_SUN_SC_TLB_REG(reg, siz, handler, rd)\ 1163: do { \ 1164: \ 1165: /* if this address falls in this register: */ \ 1166: if (((reg) \ 1167: <= address) \ 1168: && (address \ 1169: < ((reg) \ 1170: + (siz)))) { \ 1171: \ 1172: /* this TLB entry covers this register: */ \ 1173: TME_ATOMIC_WRITE(tme_bus_addr_t, \ 1174: tlb->tme_bus_tlb_addr_first,\ 1175: (reg)); \ 1176: TME_ATOMIC_WRITE(tme_bus_addr_t, \ 1177: tlb->tme_bus_tlb_addr_last,\ 1178: ((reg) \ 1179: + (siz) \ 1180: - 1)); \ 1181: \ 1182: /* our bus cycle handler: */ \ 1183: tlb->tme_bus_tlb_cycle = (handler); \ 1184: \ 1185: /* if this TLB entry allows fast reading: */\ 1186: if (rd) { \ 1187: tlb->tme_bus_tlb_emulator_off_read \ 1188: = &sun_sc->tme_sun_sc_card[0]; \ 1189: } \ 1190: } \ 1191: } while (/* CONSTCOND */ 0) 1192: 1193: TME_SUN_SC_TLB_REG(TME_SUN_SC_REG_DATA, 1194: TME_SUN_SC_SIZ_DATA, 1195: _tme_sun_sc_bus_cycle_data, 1196: FALSE); 1197: TME_SUN_SC_TLB_REG(TME_SUN_SC_REG_CMD_STAT, 1198: TME_SUN_SC_SIZ_CMD_STAT, 1199: _tme_sun_sc_bus_cycle_cmd_stat, 1200: FALSE); 1201: TME_SUN_SC_TLB_REG(TME_SUN_SC_REG_ICR, 1202: TME_SUN_SC_SIZ_ICR, 1203: _tme_sun_sc_bus_cycle_icr, 1204: TRUE); 1205: #undef TME_SUN_SC_TLB_REG 1206: 1207: /* anything else is some other register: */ 1208: if (tlb->tme_bus_tlb_cycle == NULL) { 1209: 1210: /* if this address is past the ICR, this TLB entry covers from 1211: past the ICR to the end of the card, else this TLB entry covers 1212: the byte at this address only: */ 1213: if (address 1214: >= (TME_SUN_SC_REG_ICR 1215: + TME_SUN_SC_SIZ_ICR)) { 1216: TME_ATOMIC_WRITE(tme_bus_addr_t, 1217: tlb->tme_bus_tlb_addr_first, 1218: (TME_SUN_SC_REG_ICR 1219: + TME_SUN_SC_SIZ_ICR)); 1220: TME_ATOMIC_WRITE(tme_bus_addr_t, 1221: tlb->tme_bus_tlb_addr_last, 1222: TME_SUN_SC_SIZ_CARD - 1); 1223: } 1224: else { 1225: TME_ATOMIC_WRITE(tme_bus_addr_t, 1226: tlb->tme_bus_tlb_addr_first, 1227: address); 1228: TME_ATOMIC_WRITE(tme_bus_addr_t, 1229: tlb->tme_bus_tlb_addr_last, 1230: address); 1231: } 1232: 1233: /* this TLB entry allows fast reading and writing: */ 1234: tlb->tme_bus_tlb_emulator_off_read 1235: = &sun_sc->tme_sun_sc_card[0]; 1236: tlb->tme_bus_tlb_emulator_off_write 1237: = &sun_sc->tme_sun_sc_card[0]; 1238: 1239: /* bus cycles are handled by the other handler: */ 1240: tlb->tme_bus_tlb_cycle = _tme_sun_sc_bus_cycle_other; 1241: } 1242: 1243: #ifdef TME_SUN_SC_DEBUG 1244: /* XXX when debugging, nothing is fast readable or writable: */ 1245: tlb->tme_bus_tlb_emulator_off_read 1246: = TME_EMULATOR_OFF_UNDEF; 1247: tlb->tme_bus_tlb_emulator_off_write 1248: = TME_EMULATOR_OFF_UNDEF; 1249: #endif /* TME_SUN_SC_DEBUG */ 1250: 1251: /* in case this TLB entry allows fast access: */ 1252: tlb->tme_bus_tlb_rwlock = &sun_sc->tme_sun_sc_rwlock; 1253: 1254: /* allow reading and writing: */ 1255: tlb->tme_bus_tlb_cycles_ok = TME_BUS_CYCLE_READ | TME_BUS_CYCLE_WRITE; 1256: 1257: /* our bus cycle handler private data: */ 1258: tlb->tme_bus_tlb_cycle_private = sun_sc; 1259: 1260: return (TME_OK); 1261: } 1262: 1263: /* this is called for an event on the SCSI bus: */ 1264: static int 1265: _tme_sun_sc_scsi_cycle(struct tme_scsi_connection *conn_scsi, 1266: tme_scsi_control_t control, 1267: tme_scsi_data_t data, 1.1.1.2 ! root 1268: tme_uint32_t events_triggered, ! 1269: tme_uint32_t actions_taken, ! 1270: const struct tme_scsi_dma *dma) 1.1 root 1271: { 1272: struct tme_sun_sc *sun_sc; 1273: struct tme_sun_sc_cycle *sun_sc_cycle; 1274: unsigned long count; 1275: struct tme_bus_tlb *tlb; 1276: tme_uint32_t address; 1277: tme_uint16_t resid; 1278: tme_uint16_t icr_old, icr_new; 1279: int new_callouts; 1280: int new_callouts_dma; 1281: int rc; 1282: 1283: /* recover our data structure: */ 1284: sun_sc = conn_scsi->tme_scsi_connection.tme_connection_element->tme_element_private; 1285: 1286: /* assume we won't need any new callouts: */ 1287: new_callouts = 0; 1288: 1289: /* lock the mutex: */ 1290: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 1291: 1292: /* get the old ICR value: */ 1293: icr_old = TME_SUN_SC_ICR_GET(sun_sc); 1294: 1295: /* update the ICR to reflect the current SCSI control signals: */ 1296: icr_new = icr_old; 1297: #define _TME_SUN_SC_ICR_CONTROL(_icr, _control) \ 1298: do { \ 1299: if (control & _control) { \ 1300: icr_new |= _icr; \ 1301: } \ 1302: else { \ 1303: icr_new &= ~_icr; \ 1304: } \ 1305: } while (/* CONSTCOND */ 0) 1306: _TME_SUN_SC_ICR_CONTROL(TME_SUN_SC_ICR_REQUEST, 1307: TME_SCSI_SIGNAL_REQ); 1308: _TME_SUN_SC_ICR_CONTROL(TME_SUN_SC_ICR_MESSAGE, 1309: TME_SCSI_SIGNAL_MSG); 1310: _TME_SUN_SC_ICR_CONTROL(TME_SUN_SC_ICR_COMMAND_DATA, 1311: TME_SCSI_SIGNAL_C_D); 1312: _TME_SUN_SC_ICR_CONTROL(TME_SUN_SC_ICR_INPUT_OUTPUT, 1313: TME_SCSI_SIGNAL_I_O); 1314: _TME_SUN_SC_ICR_CONTROL(TME_SUN_SC_ICR_PARITY, 1315: TME_SCSI_SIGNAL_DBP); 1316: _TME_SUN_SC_ICR_CONTROL(TME_SUN_SC_ICR_BUSY, 1317: TME_SCSI_SIGNAL_BSY); 1318: #undef _TME_SUN_SC_ICR_CONTROL 1319: 1320: /* if the bus phase has changed to the STATUS phase, call out an 1321: interrupt: */ 1322: /* XXX is this really how the board behaves? the sun2 PROM seems to 1323: rely on this behavior: */ 1324: if ((TME_SUN_SC_BUS_PHASE(icr_new) 1325: != TME_SUN_SC_BUS_PHASE(icr_old)) 1326: && (TME_SUN_SC_BUS_PHASE(icr_new) 1327: == (TME_SUN_SC_ICR_BUSY 1328: | TME_SUN_SC_ICR_COMMAND_DATA 1329: | TME_SUN_SC_ICR_INPUT_OUTPUT))) { 1330: icr_new 1331: |= TME_SUN_SC_ICR_INT_REQUEST; 1332: new_callouts 1333: |= TME_SUN_SC_CALLOUT_INT; 1334: } 1335: 1336: /* get the last SCSI cycle that we called out: */ 1337: sun_sc_cycle 1338: = &sun_sc->tme_sun_sc_cycles[sun_sc->tme_sun_sc_cycle_tail]; 1339: 1340: /* if the last SCSI cycle was for a DMA sequence: */ 1.1.1.2 ! root 1341: if (sun_sc_cycle->tme_sun_sc_cycle_actions ! 1342: == TME_SCSI_ACTION_DMA_INITIATOR) { ! 1343: ! 1344: /* copy in the finished DMA structure: */ ! 1345: sun_sc_cycle->tme_sun_sc_cycle_dma = *dma; 1.1 root 1346: 1347: /* if the last SCSI cycle was for a genuine DMA sequence (as opposed 1348: to a DMA sequence to transfer the cmd_stat register), update the 1349: card's DMA engine registers: */ 1350: if ((sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_out 1351: != &sun_sc_cycle->tme_sun_sc_cycle_cmd_stat) 1352: && (sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in 1353: != &sun_sc_cycle->tme_sun_sc_cycle_cmd_stat)) { 1354: 1355: /* get the number of bytes that were transferred: */ 1356: count 1357: = ((sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_out 1358: > sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in) 1359: ? (sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_out 1360: - sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in) 1361: : (sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_in 1362: - sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_out)); 1363: 1364: /* get the TLB entry: */ 1365: tlb 1366: = TME_ATOMIC_READ(struct tme_bus_tlb *, 1367: sun_sc->tme_sun_sc_dma_tlb); 1368: 1369: /* get the DMA address: */ 1370: address 1371: = TME_SUN_SC_REG16_GET(sun_sc, 1372: TME_SUN_SC_REG_DMA_H); 1373: address 1374: = ((address 1375: << 16) 1376: | TME_SUN_SC_REG16_GET(sun_sc, 1377: TME_SUN_SC_REG_DMA_L)); 1378: 1379: /* if we were doing a DMA write, but the TLB entry we filled 1380: doesn't allow fast writing, we need to do a memory write 1381: cycle to transfer the bytes from our internal DMA buffer into 1382: memory: */ 1383: if ((icr_old 1384: & TME_SUN_SC_ICR_INPUT_OUTPUT) 1385: && (tlb->tme_bus_tlb_emulator_off_write 1386: == TME_EMULATOR_OFF_UNDEF)) { 1387: rc = _tme_sun_sc_bus_cycle_dma(sun_sc, 1.1.1.2 ! root 1388: /* XXX FIXME this is not thread-safe: */ 1.1 root 1389: tlb, 1390: TME_BUS_CYCLE_WRITE, 1391: address, 1392: (icr_old 1393: & TME_SUN_SC_ICR_WORD_MODE)); 1394: assert (rc == TME_OK); 1395: } 1396: 1397: /* update the DMA address: */ 1398: address += count; 1399: TME_SUN_SC_REG16_PUT(sun_sc, 1400: TME_SUN_SC_REG_DMA_H, 1401: address >> 16); 1402: TME_SUN_SC_REG16_PUT(sun_sc, 1403: TME_SUN_SC_REG_DMA_L, 1404: address & 0xffff); 1405: 1406: /* update the DMA length: */ 1407: resid 1408: = (TME_SUN_SC_REG16_GET(sun_sc, 1409: TME_SUN_SC_REG_DMA_LEN) 1410: ^ 0xffff); 1411: assert (resid >= count); 1412: TME_SUN_SC_REG16_PUT(sun_sc, 1413: TME_SUN_SC_REG_DMA_LEN, 1414: ((resid 1415: - count) 1416: ^ 0xffff)); 1417: 1418: /* XXX this idea doesn't work because the initiator can't know 1419: the amount of data returned by some commands, like REQUEST 1420: SENSE. when does this card signal BUS_ERROR, then? */ 1421: #if 0 1422: /* if the DMA sequence didn't transfer all of the DMA bytes that 1423: we had made available, that usually means that the SCSI bus 1424: phase changed in the middle of the transfer, which is a bus 1425: error: */ 1426: if (sun_sc_cycle->tme_sun_sc_cycle_dma.tme_scsi_dma_resid 1427: > 0) { 1428: 1429: /* note the bus error and request an interrupt: */ 1430: icr_new 1431: |= (TME_SUN_SC_ICR_BUS_ERROR 1432: | TME_SUN_SC_ICR_INT_REQUEST); 1433: new_callouts |= TME_SUN_SC_CALLOUT_INT; 1434: } 1435: #endif 1436: } 1437: 1438: /* advance the tail pointer: */ 1439: sun_sc->tme_sun_sc_cycle_tail 1440: = ((sun_sc->tme_sun_sc_cycle_tail 1441: + 1) 1442: & (TME_SUN_SC_CYCLE_RING_SIZE 1443: - 1)); 1444: } 1445: 1446: /* always try to start or continue a DMA transfer. if one 1447: can't be started, just wait for another SCSI bus change: */ 1448: new_callouts_dma 1449: = _tme_sun_sc_dma_start(sun_sc, 1450: &icr_new); 1451: if (new_callouts_dma != 0) { 1452: new_callouts |= new_callouts_dma; 1453: } 1454: else { 1455: sun_sc_cycle 1456: = _tme_sun_sc_cycle_new(sun_sc, 1.1.1.2 ! root 1457: TME_SCSI_EVENT_BUS_CHANGE, ! 1458: TME_SCSI_ACTION_NONE); 1.1 root 1459: new_callouts 1460: |= TME_SUN_SC_CALLOUT_CYCLE; 1461: } 1462: 1463: /* update the ICR and data registers: */ 1464: TME_SUN_SC_ICR_PUT(sun_sc, icr_new); 1465: sun_sc->tme_sun_sc_card[TME_SUN_SC_REG_DATA] = data; 1466: 1467: /* make any new callouts: */ 1468: _tme_sun_sc_callout(sun_sc, new_callouts); 1469: 1470: /* unlock the mutex: */ 1471: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 1472: 1473: return (TME_OK); 1474: } 1475: 1476: /* this makes a new bus connection: */ 1477: static int 1478: _tme_sun_sc_connection_make_bus(struct tme_connection *conn, 1479: unsigned int state) 1480: { 1481: struct tme_sun_sc *sun_sc; 1482: struct tme_bus_connection *conn_bus; 1483: int rc; 1484: 1485: /* recover our data structure: */ 1486: sun_sc = conn->tme_connection_element->tme_element_private; 1487: 1488: /* call the bus device connection maker: */ 1489: rc = tme_bus_device_connection_make(conn, state); 1490: 1491: /* if the full connection was successful, and we don't have a TLB 1492: set yet, allocate it: */ 1493: if (rc == TME_OK 1494: && state == TME_CONNECTION_FULL 1495: && TME_ATOMIC_READ(struct tme_bus_tlb *, 1496: sun_sc->tme_sun_sc_dma_tlb) == NULL) { 1497: 1498: /* get our bus connection: */ 1499: conn_bus 1500: = TME_ATOMIC_READ(struct tme_bus_connection *, 1501: sun_sc->tme_sun_sc_device.tme_bus_device_connection); 1502: 1503: /* allocate the TLB set: */ 1504: rc = ((*conn_bus->tme_bus_tlb_set_allocate) 1505: (conn_bus, 1506: 1, 1507: sizeof(struct tme_bus_tlb), 1508: TME_ATOMIC_POINTER(&sun_sc->tme_sun_sc_dma_tlb))); 1509: assert (rc == TME_OK); 1510: } 1511: 1512: return (rc); 1513: } 1514: 1515: /* this makes a new SCSI connection: */ 1516: static int 1517: _tme_sun_sc_connection_make_scsi(struct tme_connection *conn, 1518: unsigned int state) 1519: { 1520: struct tme_sun_sc *sun_sc; 1521: struct tme_sun_sc_cycle *sun_sc_cycle; 1522: struct tme_scsi_connection *conn_scsi; 1523: struct tme_scsi_connection *conn_scsi_other; 1524: 1525: /* recover our data structures: */ 1526: sun_sc = conn->tme_connection_element->tme_element_private; 1527: conn_scsi = (struct tme_scsi_connection *) conn; 1528: conn_scsi_other = (struct tme_scsi_connection *) conn->tme_connection_other; 1529: 1530: /* both sides must be SCSI connections: */ 1531: assert(conn->tme_connection_type == TME_CONNECTION_SCSI); 1532: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_SCSI); 1533: 1534: /* we're always set up to answer calls across the connection, so we 1535: only have to do work when the connection has gone full, namely 1536: taking the other side of the connection: */ 1537: if (state == TME_CONNECTION_FULL) { 1538: 1539: /* lock our mutex: */ 1540: tme_mutex_lock(&sun_sc->tme_sun_sc_mutex); 1541: 1542: /* save our connection: */ 1543: sun_sc->tme_sun_sc_scsi_connection = conn_scsi_other; 1544: 1545: /* call out a cycle that asserts no signals and runs the 1546: wait-change sequence. this also fully-initializes 1547: this cycle - _tme_sun_sc_cycle_new copies the previous 1548: cycle into a newly allocated cycle, so this hopefully 1549: starts the chain of well-initialized cycles: */ 1550: sun_sc_cycle 1551: = _tme_sun_sc_cycle_new(sun_sc, 1.1.1.2 ! root 1552: TME_SCSI_EVENT_BUS_CHANGE, ! 1553: TME_SCSI_ACTION_NONE); 1.1 root 1554: sun_sc_cycle->tme_sun_sc_cycle_control 1555: = 0; 1556: sun_sc_cycle->tme_sun_sc_cycle_data 1557: = 0; 1558: _tme_sun_sc_callout(sun_sc, TME_SUN_SC_CALLOUT_CYCLE); 1559: 1560: /* unlock our mutex: */ 1561: tme_mutex_unlock(&sun_sc->tme_sun_sc_mutex); 1562: } 1563: 1564: return (TME_OK); 1565: } 1566: 1567: /* this breaks a connection: */ 1568: static int 1569: _tme_sun_sc_connection_break(struct tme_connection *conn, unsigned int state) 1570: { 1571: abort(); 1572: } 1573: 1574: /* this makes a new connection side for a Sun sc: */ 1575: static int 1576: _tme_sun_sc_connections_new(struct tme_element *element, 1577: const char * const *args, 1578: struct tme_connection **_conns, 1579: char **_output) 1580: { 1581: struct tme_sun_sc *sun_sc; 1582: struct tme_scsi_connection *conn_scsi; 1583: struct tme_connection *conn; 1584: int rc; 1585: 1586: /* recover our data structure: */ 1587: sun_sc = (struct tme_sun_sc *) element->tme_element_private; 1588: 1589: /* make the generic bus device connection side: */ 1590: rc = tme_bus_device_connections_new(element, args, _conns, _output); 1591: if (rc != TME_OK) { 1592: return (rc); 1593: } 1594: 1595: /* since we need to allocate a TLB set when we make our bus 1596: connection, make sure any generic bus device connection sides 1597: use our connection maker: */ 1598: for (conn = *_conns; 1599: conn != NULL; 1600: conn = conn->tme_connection_next) { 1601: if ((conn->tme_connection_type 1602: == TME_CONNECTION_BUS_GENERIC) 1603: && (conn->tme_connection_make 1604: == tme_bus_device_connection_make)) { 1605: conn->tme_connection_make 1606: = _tme_sun_sc_connection_make_bus; 1607: } 1608: } 1609: 1610: /* if we don't have a SCSI connection, make one: */ 1611: if (sun_sc->tme_sun_sc_scsi_connection == NULL) { 1612: 1613: /* allocate the new SCSI connection: */ 1614: conn_scsi = tme_new0(struct tme_scsi_connection, 1); 1615: conn = &conn_scsi->tme_scsi_connection; 1616: 1617: /* fill in the generic connection: */ 1618: conn->tme_connection_next = *_conns; 1619: conn->tme_connection_type = TME_CONNECTION_SCSI; 1620: conn->tme_connection_score = tme_scsi_connection_score; 1621: conn->tme_connection_make = _tme_sun_sc_connection_make_scsi; 1622: conn->tme_connection_break = _tme_sun_sc_connection_break; 1623: 1624: /* fill in the SCSI connection: */ 1625: conn_scsi->tme_scsi_connection_cycle = _tme_sun_sc_scsi_cycle; 1626: 1627: /* return the connection side possibility: */ 1628: *_conns = conn; 1629: } 1630: 1631: /* done: */ 1632: return (TME_OK); 1633: } 1634: 1635: /* the new Sun sc function: */ 1636: TME_ELEMENT_SUB_NEW_DECL(tme_bus_multibus,sun_sc) { 1637: struct tme_sun_sc *sun_sc; 1638: int arg_i; 1639: int usage; 1.1.1.2 ! root 1640: int vme; 1.1 root 1641: 1642: /* check our arguments: */ 1643: usage = 0; 1644: arg_i = 1; 1.1.1.2 ! root 1645: vme = FALSE; 1.1 root 1646: for (;;) { 1647: 1.1.1.2 ! root 1648: if (TME_ARG_IS(args[arg_i], "vme")) { ! 1649: vme = TRUE; ! 1650: arg_i++; 1.1 root 1651: } 1652: 1653: /* if we ran out of arguments: */ 1654: else if (args[arg_i] == NULL) { 1655: 1656: break; 1657: } 1658: 1659: /* otherwise this is a bad argument: */ 1660: else { 1661: tme_output_append_error(_output, 1662: "%s %s, ", 1663: args[arg_i], 1664: _("unexpected")); 1665: usage = TRUE; 1666: break; 1667: } 1668: } 1669: 1670: if (usage) { 1671: tme_output_append_error(_output, 1.1.1.2 ! root 1672: "%s %s [ vme ]", 1.1 root 1673: _("usage:"), 1674: args[0]); 1675: return (EINVAL); 1676: } 1677: 1678: /* start the Sun sc structure: */ 1679: sun_sc = tme_new0(struct tme_sun_sc, 1); 1680: sun_sc->tme_sun_sc_element = element; 1681: tme_mutex_init(&sun_sc->tme_sun_sc_mutex); 1682: tme_rwlock_init(&sun_sc->tme_sun_sc_rwlock); 1683: 1684: /* initialize our simple bus device descriptor: */ 1685: sun_sc->tme_sun_sc_device.tme_bus_device_element = element; 1686: sun_sc->tme_sun_sc_device.tme_bus_device_tlb_fill = _tme_sun_sc_tlb_fill; 1687: sun_sc->tme_sun_sc_device.tme_bus_device_address_last = TME_SUN_SC_SIZ_CARD - 1; 1.1.1.2 ! root 1688: if (vme) { ! 1689: sun_sc->tme_sun_sc_device.tme_bus_device_intack = _tme_sun_sc_intack; ! 1690: } 1.1 root 1691: 1692: /* fill the element: */ 1693: element->tme_element_private = sun_sc; 1694: element->tme_element_connections_new = _tme_sun_sc_connections_new; 1695: 1696: return (TME_OK); 1697: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.