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