|
|
1.1 ! root 1: /* $Id: bus-device.c,v 1.5 2003/05/16 21:48:08 fredette Exp $ */ ! 2: ! 3: /* bus/bus-device.c - implementation of a generic bus device support: */ ! 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> ! 37: _TME_RCSID("$Id: bus-device.c,v 1.5 2003/05/16 21:48:08 fredette Exp $"); ! 38: ! 39: /* includes: */ ! 40: #include <tme/generic/bus-device.h> ! 41: ! 42: /* this scores a connection: */ ! 43: int ! 44: tme_bus_device_connection_score(struct tme_connection *conn, unsigned int *_score) ! 45: { ! 46: struct tme_bus_device *device; ! 47: struct tme_bus_connection *conn_bus_other_old; ! 48: struct tme_bus_connection *conn_bus_other_new; ! 49: ! 50: /* recover our device: */ ! 51: device = conn->tme_connection_element->tme_element_private; ! 52: ! 53: /* both sides must be generic bus connections: */ ! 54: assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC); ! 55: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC); ! 56: ! 57: /* a simple bus device can have multiple connections, but they all ! 58: must be from the same bus. the only way we check that is by ! 59: comparing elements: */ ! 60: conn_bus_other_old = TME_ATOMIC_READ(struct tme_bus_connection *, ! 61: device->tme_bus_device_connection); ! 62: conn_bus_other_new = (struct tme_bus_connection *) conn->tme_connection_other; ! 63: if (conn_bus_other_old != NULL ! 64: && (conn_bus_other_old->tme_bus_connection.tme_connection_element ! 65: != conn_bus_other_new->tme_bus_connection.tme_connection_element)) { ! 66: *_score = 0; ! 67: return (TME_OK); ! 68: } ! 69: ! 70: /* otherwise, this is our first connection or another connection to ! 71: the same element. note that there's no good way to differentiate ! 72: a connection to a bus from a connection to just another chip, so ! 73: we always return a nonzero score here: */ ! 74: *_score = 1; ! 75: return (TME_OK); ! 76: } ! 77: ! 78: /* this makes a new connection: */ ! 79: int ! 80: tme_bus_device_connection_make(struct tme_connection *conn, unsigned int state) ! 81: { ! 82: struct tme_bus_device *device; ! 83: ! 84: /* recover our device: */ ! 85: device = conn->tme_connection_element->tme_element_private; ! 86: ! 87: /* both sides must be generic bus connections: */ ! 88: assert(conn->tme_connection_type == TME_CONNECTION_BUS_GENERIC); ! 89: assert(conn->tme_connection_other->tme_connection_type == TME_CONNECTION_BUS_GENERIC); ! 90: ! 91: /* simple bus devices are always set up to answer calls across the ! 92: connection, so we only have to do work when the connection ! 93: has gone full, namely taking the other side of the ! 94: connection: */ ! 95: if (state == TME_CONNECTION_FULL) { ! 96: ! 97: /* save our connection: */ ! 98: TME_ATOMIC_WRITE(struct tme_bus_connection *, ! 99: device->tme_bus_device_connection, ! 100: (struct tme_bus_connection *) conn->tme_connection_other); ! 101: } ! 102: ! 103: return (TME_OK); ! 104: } ! 105: ! 106: /* this breaks a connection: */ ! 107: int ! 108: tme_bus_device_connection_break(struct tme_connection *conn, unsigned int state) ! 109: { ! 110: abort(); ! 111: } ! 112: ! 113: static int ! 114: _tme_bus_device_signal(struct tme_bus_connection *conn_bus, unsigned int signal) ! 115: { ! 116: struct tme_bus_device *device; ! 117: device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private; ! 118: return ((*device->tme_bus_device_signal)(device, signal)); ! 119: } ! 120: ! 121: static int ! 122: _tme_bus_device_intack(struct tme_bus_connection *conn_bus, unsigned int signal, int *vector) ! 123: { ! 124: struct tme_bus_device *device; ! 125: device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private; ! 126: return ((*device->tme_bus_device_intack)(device, signal, vector)); ! 127: } ! 128: ! 129: static int ! 130: _tme_bus_device_tlb_fill(struct tme_bus_connection *conn_bus, struct tme_bus_tlb *tlb, ! 131: tme_bus_addr_t address, unsigned int cycles) ! 132: { ! 133: struct tme_bus_device *device; ! 134: device = conn_bus->tme_bus_connection.tme_connection_element->tme_element_private; ! 135: return ((*device->tme_bus_device_tlb_fill)(device, tlb, address, cycles)); ! 136: } ! 137: ! 138: /* this makes a new connection side for a simple bus device: */ ! 139: int ! 140: tme_bus_device_connections_new(struct tme_element *element, ! 141: const char * const *args, ! 142: struct tme_connection **_conns, ! 143: char **_output) ! 144: { ! 145: struct tme_bus_device *device; ! 146: struct tme_bus_connection *conn_bus; ! 147: struct tme_connection *conn; ! 148: ! 149: /* recover our device: */ ! 150: device = (struct tme_bus_device *) element->tme_element_private; ! 151: ! 152: /* create our side of a generic bus connection: */ ! 153: conn_bus = tme_new0(struct tme_bus_connection, 1); ! 154: conn = &conn_bus->tme_bus_connection; ! 155: ! 156: /* fill in the generic connection: */ ! 157: conn->tme_connection_next = *_conns; ! 158: conn->tme_connection_type = TME_CONNECTION_BUS_GENERIC; ! 159: conn->tme_connection_score = tme_bus_device_connection_score; ! 160: conn->tme_connection_make = tme_bus_device_connection_make; ! 161: conn->tme_connection_break = tme_bus_device_connection_break; ! 162: ! 163: /* fill in the generic bus connection: */ ! 164: conn_bus->tme_bus_address_last = device->tme_bus_device_address_last; ! 165: if (device->tme_bus_device_signal != NULL) { ! 166: conn_bus->tme_bus_signal = _tme_bus_device_signal; ! 167: } ! 168: if (device->tme_bus_device_intack != NULL) { ! 169: conn_bus->tme_bus_intack = _tme_bus_device_intack; ! 170: } ! 171: conn_bus->tme_bus_tlb_fill = _tme_bus_device_tlb_fill; ! 172: ! 173: /* return the connection side possibility: */ ! 174: *_conns = conn; ! 175: return (TME_OK); ! 176: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.