2 Copyright (C) 1998, 2007, 2008, 2009, 2010, 2011
3 Free Software Foundation, Inc.
4 Contributed by Andrew Cagney and Cygnus Solutions.
6 This file is part of GDB, the GNU debugger.
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
44 struct hw_port_edge *next;
45 object_disposition disposition;
49 hw_port_event_method *to_port_event;
50 const struct hw_port_descriptor *ports;
51 struct hw_port_edge *edges;
54 const struct hw_port_descriptor empty_hw_ports[] = {
59 panic_hw_port_event (struct hw *me,
65 hw_abort (me, "no port method");
69 create_hw_port_data (struct hw *me)
71 me->ports_of_hw = HW_ZALLOC (me, struct hw_port_data);
72 set_hw_port_event (me, panic_hw_port_event);
73 set_hw_ports (me, empty_hw_ports);
77 delete_hw_port_data (struct hw *me)
79 hw_free (me, me->ports_of_hw);
80 me->ports_of_hw = NULL;
84 set_hw_ports (struct hw *me,
85 const struct hw_port_descriptor ports[])
87 me->ports_of_hw->ports = ports;
91 set_hw_port_event (struct hw *me,
92 hw_port_event_method *port_event)
94 me->ports_of_hw->to_port_event = port_event;
99 attach_hw_port_edge (struct hw *me,
100 struct hw_port_edge **list,
104 object_disposition disposition)
106 struct hw_port_edge *new_edge = HW_ZALLOC (me, struct hw_port_edge);
107 new_edge->my_port = my_port;
108 new_edge->dest = dest;
109 new_edge->dest_port = dest_port;
110 new_edge->next = *list;
111 new_edge->disposition = disposition;
117 detach_hw_port_edge (struct hw *me,
118 struct hw_port_edge **list,
123 while (*list != NULL)
125 struct hw_port_edge *old_edge = *list;
126 if (old_edge->dest == dest
127 && old_edge->dest_port == dest_port
128 && old_edge->my_port == my_port)
130 if (old_edge->disposition == permenant_object)
131 hw_abort (me, "attempt to delete permenant port edge");
132 *list = old_edge->next;
133 hw_free (me, old_edge);
137 hw_abort (me, "attempt to delete unattached port");
143 clean_hw_port_edges (struct hw_port_edge **list)
145 while (*list != NULL)
147 struct hw_port_edge *old_edge = *list;
148 switch (old_edge->disposition)
150 case permenant_object:
151 list = &old_edge->next;
153 case temporary_object:
154 *list = old_edge->next;
155 hw_free (me, old_edge);
166 hw_port_event (struct hw *me,
170 int found_an_edge = 0;
171 struct hw_port_edge *edge;
172 /* device's lines directly connected */
173 for (edge = me->ports_of_hw->edges;
177 if (edge->my_port == my_port)
179 edge->dest->ports_of_hw->to_port_event (edge->dest,
188 hw_abort (me, "No edge for port %d", my_port);
193 hw_port_attach (struct hw *me,
197 object_disposition disposition)
199 attach_hw_port_edge (me,
200 &me->ports_of_hw->edges,
209 hw_port_detach (struct hw *me,
214 detach_hw_port_edge (me,
215 &me->ports_of_hw->edges,
223 hw_port_traverse (struct hw *me,
224 hw_port_traverse_function *handler,
227 struct hw_port_edge *port_edge;
228 for (port_edge = me->ports_of_hw->edges;
230 port_edge = port_edge->next)
232 handler (me, port_edge->my_port,
233 port_edge->dest, port_edge->dest_port,
240 hw_port_decode (struct hw *me,
241 const char *port_name,
242 port_direction direction)
244 if (port_name == NULL || port_name[0] == '\0')
246 if (isdigit(port_name[0]))
248 return strtoul (port_name, NULL, 0);
252 const struct hw_port_descriptor *ports =
253 me->ports_of_hw->ports;
256 while (ports->name != NULL)
258 if (ports->direction == bidirect_port
259 || ports->direction == direction)
261 if (ports->nr_ports > 0)
263 int len = strlen (ports->name);
264 if (strncmp (port_name, ports->name, len) == 0)
266 if (port_name[len] == '\0')
267 return ports->number;
268 else if(isdigit (port_name[len]))
270 int port = (ports->number
271 + strtoul (&port_name[len], NULL, 0));
272 if (port >= ports->number + ports->nr_ports)
274 "Port %s out of range",
280 else if (strcmp (port_name, ports->name) == 0)
281 return ports->number;
287 hw_abort (me, "Unreconized port %s", port_name);
293 hw_port_encode (struct hw *me,
297 port_direction direction)
299 const struct hw_port_descriptor *ports = NULL;
300 ports = me->ports_of_hw->ports;
302 while (ports->name != NULL)
304 if (ports->direction == bidirect_port
305 || ports->direction == direction)
307 if (ports->nr_ports > 0)
309 if (port_number >= ports->number
310 && port_number < ports->number + ports->nr_ports)
312 strcpy (buf, ports->name);
313 sprintf (buf + strlen(buf), "%d", port_number - ports->number);
314 if (strlen (buf) >= sizeof_buf)
315 hw_abort (me, "hw_port_encode: buffer overflow");
321 if (ports->number == port_number)
323 if (strlen(ports->name) >= sizeof_buf)
324 hw_abort (me, "hw_port_encode: buffer overflow");
325 strcpy(buf, ports->name);
333 sprintf (buf, "%d", port_number);
334 if (strlen(buf) >= sizeof_buf)
335 hw_abort (me, "hw_port_encode: buffer overflow");