1 /*
2 * $Id$
3 *
4 * Copyright (C) 2003 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>, 2003.
22 *
23 */
24
25 #include <sysdep.h>
26
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30
31 #include <urjtag/cable.h>
32 #include <urjtag/chain.h>
33 #include "generic.h"
34 #include "generic_usbconn.h"
35
36 #include <urjtag/cmd.h>
37
38 static const urj_usbconn_cable_t * const urj_tap_cable_usbconn_cables[] = {
39 #define _URJ_USB(usb) &urj_tap_cable_usbconn_##usb,
40 #include "generic_usbconn_list.h"
41 NULL
42 };
43
44 int
urj_tap_cable_generic_usbconn_connect(urj_cable_t * cable,const urj_param_t * params[])45 urj_tap_cable_generic_usbconn_connect (urj_cable_t *cable,
46 const urj_param_t *params[])
47 {
48 urj_usbconn_cable_t user_specified = {
49 NULL, /* no name */
50 NULL, /* no string pattern */
51 NULL, /* no specific driver */
52 -1, /* no VID */
53 -1, /* no PID */
54 0, /* default interface */
55 };
56
57 urj_tap_cable_generic_params_t *cable_params;
58 urj_usbconn_t *conn = NULL;
59 int i;
60
61 if (strcasecmp (cable->driver->name, "usb") != 0)
62 {
63 user_specified.name = cable->driver->name;
64 }
65
66 if (params != NULL)
67 /* parse arguments beyond the cable name */
68 for (i = 0; params[i] != NULL; i++)
69 {
70 switch (params[i]->key)
71 {
72 case URJ_CABLE_PARAM_KEY_PID:
73 user_specified.pid = params[i]->value.lu;
74 break;
75 case URJ_CABLE_PARAM_KEY_VID:
76 user_specified.vid = params[i]->value.lu;
77 break;
78 case URJ_CABLE_PARAM_KEY_DESC:
79 user_specified.desc = params[i]->value.string;
80 break;
81 case URJ_CABLE_PARAM_KEY_DRIVER:
82 user_specified.driver = params[i]->value.string;
83 break;
84 case URJ_CABLE_PARAM_KEY_INTERFACE:
85 user_specified.interface = params[i]->value.lu;
86 break;
87 case URJ_CABLE_PARAM_KEY_INDEX:
88 user_specified.index = params[i]->value.lu;
89 break;
90 default:
91 // hand these to the driver connect()
92 break;
93 }
94 }
95
96 /* search usbconn driver list */
97 for (i = 0; urj_tap_usbconn_drivers[i] && !conn; i++)
98 {
99 if ((user_specified.driver == NULL)
100 || (strcasecmp (user_specified.driver,
101 urj_tap_usbconn_drivers[i]->type) == 0))
102 {
103 int j;
104
105 /* search cable list */
106 for (j = 0; urj_tap_cable_usbconn_cables[j] && !conn; j++)
107 {
108 if ((user_specified.name == NULL)
109 || (strcasecmp (user_specified.name,
110 urj_tap_cable_usbconn_cables[j]->name) == 0))
111 {
112 if (strcasecmp (urj_tap_cable_usbconn_cables[j]->driver,
113 urj_tap_usbconn_drivers[i]->type) == 0)
114 {
115 urj_usbconn_cable_t cable_try =
116 *(urj_tap_cable_usbconn_cables[j]);
117
118 if (user_specified.vid >= 0)
119 cable_try.vid = user_specified.vid;
120 if (user_specified.pid >= 0)
121 cable_try.pid = user_specified.pid;
122 if (user_specified.desc != 0)
123 cable_try.desc = user_specified.desc;
124 if (user_specified.interface != 0)
125 cable_try.interface = user_specified.interface;
126 if (user_specified.index != 0)
127 cable_try.index = user_specified.index;
128
129 conn = urj_tap_usbconn_drivers[i]->connect (&cable_try,
130 params);
131 }
132 }
133 }
134 }
135 }
136
137 if (!conn)
138 {
139 // @@@@ RFHH make this into either the error from drivers->connect,
140 // or urj_error_set (NOT_FOUND)
141 urj_log (URJ_LOG_LEVEL_ERROR,
142 _("Couldn't connect to suitable USB device.\n"));
143 return URJ_STATUS_FAIL;
144 }
145 else
146 {
147 /* If some cables have been tried before a suitable cable is found,
148 urj_error will still contain an error from the last fail trial.
149 Clear it to avoid confusing error reporting. */
150 urj_error_reset ();
151 }
152
153 cable_params = malloc (sizeof (urj_tap_cable_generic_params_t));
154 if (!cable_params)
155 {
156 urj_error_set (URJ_ERROR_OUT_OF_MEMORY, _("malloc(%zd) fails"),
157 sizeof (urj_tap_cable_generic_params_t));
158 urj_tap_usbconn_drivers[i]->free (conn);
159 return URJ_STATUS_FAIL;
160 }
161
162 cable->link.usb = conn;
163 cable->params = cable_params;
164 cable->chain = NULL;
165
166 return URJ_STATUS_OK;
167 }
168
169 void
urj_tap_cable_generic_usbconn_free(urj_cable_t * cable)170 urj_tap_cable_generic_usbconn_free (urj_cable_t *cable)
171 {
172 cable->link.usb->driver->free (cable->link.usb);
173 free (cable->params);
174 free (cable);
175 }
176
177 void
urj_tap_cable_generic_usbconn_done(urj_cable_t * cable)178 urj_tap_cable_generic_usbconn_done (urj_cable_t *cable)
179 {
180 urj_tap_usbconn_close (cable->link.usb);
181 }
182
183 void
urj_tap_cable_generic_usbconn_help_ex(urj_log_level_t ll,const char * cablename,const char * ex_short,const char * ex_desc)184 urj_tap_cable_generic_usbconn_help_ex (urj_log_level_t ll, const char *cablename,
185 const char *ex_short, const char *ex_desc)
186 {
187 int i;
188 const urj_usbconn_cable_t *conn;
189
190 for (i = 0; urj_tap_cable_usbconn_cables[i]; ++i)
191 {
192 conn = urj_tap_cable_usbconn_cables[i];
193 if (strcasecmp (conn->name, cablename) == 0)
194 break;
195 }
196 if (!urj_tap_cable_usbconn_cables[i])
197 {
198 urj_warning (_("Unable to locate cable %s"), cablename);
199 return;
200 }
201
202 urj_log (ll,
203 _("Usage: cable %s %s %s\n"
204 "\n" "%s%s"
205 "\n"
206 "Default: vid=0x%x pid=0x%x driver=%s\n"
207 "\n"),
208 cablename,
209 URJ_TAP_CABLE_GENERIC_USBCONN_HELP_SHORT, ex_short,
210 URJ_TAP_CABLE_GENERIC_USBCONN_HELP_DESC, ex_desc,
211 conn->vid, conn->pid, conn->driver);
212 }
213
214 void
urj_tap_cable_generic_usbconn_help(urj_log_level_t ll,const char * cablename)215 urj_tap_cable_generic_usbconn_help (urj_log_level_t ll, const char *cablename)
216 {
217 urj_tap_cable_generic_usbconn_help_ex (ll, cablename, "", "");
218 }
219
220 int
urj_tap_cable_usb_probe(char * params[])221 urj_tap_cable_usb_probe (char *params[])
222 {
223 int i,j;
224 urj_usbconn_t *conn;
225
226 urj_log_level_t old_level = urj_log_state.level;
227 urj_log_state.level = URJ_LOG_LEVEL_SILENT;
228
229 for (i = 0; urj_tap_usbconn_drivers[i]; ++i)
230 {
231 for (j = 0; urj_tap_cable_usbconn_cables[j]; ++j)
232 {
233 urj_usbconn_cable_t cable_try = *(urj_tap_cable_usbconn_cables[j]);
234 conn = urj_tap_usbconn_drivers[i]->connect (&cable_try, NULL);
235 if (conn)
236 {
237 urj_log_state.level = old_level;
238 params[1] = (char *)urj_tap_cable_usbconn_cables[j]->name;
239 urj_log (URJ_LOG_LEVEL_NORMAL,
240 _("Found USB cable: %s\n"), params[1]);
241 return URJ_STATUS_OK;
242 }
243 }
244 }
245
246 urj_log_state.level = old_level;
247 return URJ_STATUS_FAIL;
248 }
249