1 /*
2  * $Id$
3  *
4  * Copyright (C) 2002 ETC s.r.o.
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19  * 02111-1307, USA.
20  *
21  * Written by Marcel Telka <marcel@telka.sk>, 2002.
22  *
23  */
24 
25 #include <sysdep.h>
26 
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 
31 #include <urjtag/part.h>
32 #include <urjtag/tap_register.h>
33 #include <urjtag/data_register.h>
34 #include <urjtag/error.h>
35 
36 urj_data_register_t *
urj_part_data_register_alloc(const char * name,int len)37 urj_part_data_register_alloc (const char *name, int len)
38 {
39     urj_data_register_t *dr;
40 
41     if (!name)
42         return NULL;
43 
44     dr = malloc (sizeof *dr);
45     if (!dr)
46     {
47         urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails",
48                        sizeof *dr);
49         return NULL;
50     }
51 
52     if (strlen (name) > URJ_DATA_REGISTER_MAXLEN)
53         urj_warning (_("Data register name too long\n"));
54     strncpy (dr->name, name, URJ_DATA_REGISTER_MAXLEN);
55     dr->name[URJ_DATA_REGISTER_MAXLEN] = '\0';
56 
57     if (len > 0)
58     {
59         dr->in = urj_tap_register_alloc (len);
60         dr->out = urj_tap_register_alloc (len);
61     }
62     else
63     {
64         dr->in = urj_tap_register_alloc (1);
65         dr->out = urj_tap_register_alloc (1);
66     }
67     if (!dr->in || !dr->out)
68     {
69         // retain error state
70         free (dr->in);
71         free (dr->out);
72         free (dr->name);
73         free (dr);
74         return NULL;
75     }
76 
77     dr->next = NULL;
78 
79     return dr;
80 }
81 
82 void
urj_part_data_register_free(urj_data_register_t * dr)83 urj_part_data_register_free (urj_data_register_t *dr)
84 {
85     if (!dr)
86         return;
87 
88     urj_tap_register_free (dr->in);
89     urj_tap_register_free (dr->out);
90     free (dr);
91 }
92 
93 int
urj_part_data_register_define(urj_part_t * part,const char * name,int len)94 urj_part_data_register_define (urj_part_t *part, const char *name, int len)
95 {
96     urj_data_register_t *dr;
97 
98     if (urj_part_find_data_register (part, name) != NULL)
99     {
100         urj_error_set (URJ_ERROR_ALREADY,
101                        _("Data register '%s' already defined"), name);
102         return URJ_STATUS_FAIL;
103     }
104 
105     dr = urj_part_data_register_alloc (name, len);
106     if (!dr)
107         // retain error state
108         return URJ_STATUS_FAIL;
109 
110     dr->next = part->data_registers;
111     part->data_registers = dr;
112 
113     /* Boundary Scan Register */
114     if (strcasecmp (dr->name, "BSR") == 0)
115     {
116         int i;
117 
118         part->boundary_length = len;
119         part->bsbits = malloc (part->boundary_length * sizeof *part->bsbits);
120         if (!part->bsbits)
121         {
122             urj_error_set (URJ_ERROR_OUT_OF_MEMORY, "malloc(%zd) fails",
123                            part->boundary_length * sizeof *part->bsbits);
124             return URJ_STATUS_FAIL;
125         }
126         for (i = 0; i < part->boundary_length; i++)
127             part->bsbits[i] = NULL;
128     }
129 
130     /* Device Identification Register */
131     else if (strcasecmp (dr->name, "DIR") == 0)
132         urj_tap_register_init (dr->out, urj_tap_register_get_string (part->id));
133 
134     return URJ_STATUS_OK;
135 }
136 
137 int
urj_part_data_register_realloc(urj_data_register_t * dr,int new_len)138 urj_part_data_register_realloc (urj_data_register_t *dr, int new_len)
139 {
140     if (urj_tap_register_realloc (dr->in, new_len) == NULL)
141         return URJ_STATUS_FAIL;
142     if (urj_tap_register_realloc (dr->out, new_len) == NULL)
143         return URJ_STATUS_FAIL;
144 
145     return URJ_STATUS_OK;
146 }
147