2 Copyright (C) 1998, 2007 Free Software Foundation, Inc.
3 Contributed by Andrew Cagney and Cygnus Solutions.
5 This file is part of GDB, the GNU debugger.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
45 struct hw_port_edge *next;
46 object_disposition disposition;
50 hw_port_event_method *to_port_event;
51 const struct hw_port_descriptor *ports;
52 struct hw_port_edge *edges;
55 const struct hw_port_descriptor empty_hw_ports[] = {
60 panic_hw_port_event (struct hw *me,
66 hw_abort (me, "no port method");
70 create_hw_port_data (struct hw *me)
72 me->ports_of_hw = HW_ZALLOC (me, struct hw_port_data);
73 set_hw_port_event (me, panic_hw_port_event);
74 set_hw_ports (me, empty_hw_ports);
78 delete_hw_port_data (struct hw *me)
80 hw_free (me, me->ports_of_hw);
81 me->ports_of_hw = NULL;
85 set_hw_ports (struct hw *me,
86 const struct hw_port_descriptor ports[])
88 me->ports_of_hw->ports = ports;
92 set_hw_port_event (struct hw *me,
93 hw_port_event_method *port_event)
95 me->ports_of_hw->to_port_event = port_event;
100 attach_hw_port_edge (struct hw *me,
101 struct hw_port_edge **list,
105 object_disposition disposition)
107 struct hw_port_edge *new_edge = HW_ZALLOC (me, struct hw_port_edge);
108 new_edge->my_port = my_port;
109 new_edge->dest = dest;
110 new_edge->dest_port = dest_port;
111 new_edge->next = *list;
112 new_edge->disposition = disposition;
118 detach_hw_port_edge (struct hw *me,
119 struct hw_port_edge **list,
124 while (*list != NULL)
126 struct hw_port_edge *old_edge = *list;
127 if (old_edge->dest == dest
128 && old_edge->dest_port == dest_port
129 && old_edge->my_port == my_port)
131 if (old_edge->disposition == permenant_object)
132 hw_abort (me, "attempt to delete permenant port edge");
133 *list = old_edge->next;
134 hw_free (me, old_edge);
138 hw_abort (me, "attempt to delete unattached port");
144 clean_hw_port_edges (struct hw_port_edge **list)
146 while (*list != NULL)
148 struct hw_port_edge *old_edge = *list;
149 switch (old_edge->disposition)
151 case permenant_object:
152 list = &old_edge->next;
154 case temporary_object:
155 *list = old_edge->next;
156 hw_free (me, old_edge);
167 hw_port_event (struct hw *me,
171 int found_an_edge = 0;
172 struct hw_port_edge *edge;
173 /* device's lines directly connected */
174 for (edge = me->ports_of_hw->edges;
178 if (edge->my_port == my_port)
180 edge->dest->ports_of_hw->to_port_event (edge->dest,
189 hw_abort (me, "No edge for port %d", my_port);
194 hw_port_attach (struct hw *me,
198 object_disposition disposition)
200 attach_hw_port_edge (me,
201 &me->ports_of_hw->edges,
210 hw_port_detach (struct hw *me,
215 detach_hw_port_edge (me,
216 &me->ports_of_hw->edges,
224 hw_port_traverse (struct hw *me,
225 hw_port_traverse_function *handler,
228 struct hw_port_edge *port_edge;
229 for (port_edge = me->ports_of_hw->edges;
231 port_edge = port_edge->next)
233 handler (me, port_edge->my_port,
234 port_edge->dest, port_edge->dest_port,
241 hw_port_decode (struct hw *me,
242 const char *port_name,
243 port_direction direction)
245 if (port_name == NULL || port_name[0] == '\0')
247 if (isdigit(port_name[0]))
249 return strtoul (port_name, NULL, 0);
253 const struct hw_port_descriptor *ports =
254 me->ports_of_hw->ports;
257 while (ports->name != NULL)
259 if (ports->direction == bidirect_port
260 || ports->direction == direction)
262 if (ports->nr_ports > 0)
264 int len = strlen (ports->name);
265 if (strncmp (port_name, ports->name, len) == 0)
267 if (port_name[len] == '\0')
268 return ports->number;
269 else if(isdigit (port_name[len]))
271 int port = (ports->number
272 + strtoul (&port_name[len], NULL, 0));
273 if (port >= ports->number + ports->nr_ports)
275 "Port %s out of range",
281 else if (strcmp (port_name, ports->name) == 0)
282 return ports->number;
288 hw_abort (me, "Unreconized port %s", port_name);
294 hw_port_encode (struct hw *me,
298 port_direction direction)
300 const struct hw_port_descriptor *ports = NULL;
301 ports = me->ports_of_hw->ports;
303 while (ports->name != NULL)
305 if (ports->direction == bidirect_port
306 || ports->direction == direction)
308 if (ports->nr_ports > 0)
310 if (port_number >= ports->number
311 && port_number < ports->number + ports->nr_ports)
313 strcpy (buf, ports->name);
314 sprintf (buf + strlen(buf), "%d", port_number - ports->number);
315 if (strlen (buf) >= sizeof_buf)
316 hw_abort (me, "hw_port_encode: buffer overflow");
322 if (ports->number == port_number)
324 if (strlen(ports->name) >= sizeof_buf)
325 hw_abort (me, "hw_port_encode: buffer overflow");
326 strcpy(buf, ports->name);
334 sprintf (buf, "%d", port_number);
335 if (strlen(buf) >= sizeof_buf)
336 hw_abort (me, "hw_port_encode: buffer overflow");