1 /* JTAG low-level I/O to DLC9(10?) cables
2
3 As reversed engineered by kolja waschk
4 Adapted from urjtag/trunk/jtag/xpc.c
5 Copyright (C) 2008 Kolja Waschk
6
7 Copyright (C) 2009-2011 Uwe Bonnes bon@elektron.ikp.physik.tu-darmstadt.de
8
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
22
23 #include <errno.h>
24 #include <sys/time.h>
25 #include <stdint.h>
26
27 #include <xguff/usrp_interfaces.h>
28 #include <xguff/usrp_commands.h>
29 #include <string.h>
30 #include <cstdio>
31
32 #include "ioxpc.h"
33 #include "io_exception.h"
34
IOXPC()35 IOXPC::IOXPC()
36 : IOBase(), bptr(0), calls_rd(0) , calls_wr(0), call_ctrl(0)
37 {
38 }
Init(struct cable_t * cable,char const * serial,unsigned int freq)39 int IOXPC::Init(struct cable_t *cable, char const *serial, unsigned int freq)
40 {
41 int res;
42 unsigned char buf[2];
43 unsigned long long lserial=0;
44 char descstring[256];
45 char *description = 0;
46 char *p = cable->optstring;
47 int r;
48 unsigned int vendor = 0x03fd, product= 0x0008;
49 char *fname = getenv("XPC_DEBUG");
50 if (fname)
51 fp_dbg = fopen(fname,"wb");
52 else
53 fp_dbg = NULL;
54
55 /* split string by hand for more flexibility*/
56 if (p)
57 {
58 vendor = strtol(p, NULL, 0);
59 p = strchr(p,':');
60 if(p)
61 p ++;
62 }
63 if (p)
64 {
65 product = strtol(p, NULL, 0);
66 p = strchr(p,':');
67 if(p)
68 p ++;
69 }
70 if (p)
71 {
72 char *q = strchr(p,':');
73 int len;
74
75 if (q)
76 len = q-p-1;
77 else
78 len = strlen(p);
79 if (len >0)
80 strncpy(descstring, p, (len>256)?256:len);
81 p = q;
82 if(p)
83 p ++;
84 }
85
86 if(!(strcasecmp(cable->alias,"xpc_internal")))
87 subtype = XPC_INTERNAL;
88 // Open device
89 if(serial)
90 sscanf(serial,"%Lx", &lserial);
91 res = xpc_usb_open_desc(vendor, product, description, lserial);
92 if (res < 0)
93 {
94 fprintf(stderr,"No dongle found\n");
95 return res;
96 }
97 res = xpcu_request_28(xpcu, 0x11);
98 if (res < 0)
99 {
100 fprintf(stderr,"pcu_request_28 failed\n");
101 return res;
102 }
103 res = xpcu_write_gpio(xpcu, XPC_PROG);
104 if (res < 0)
105 {
106 fprintf(stderr,"xpcu_write_gpio failed\n");
107 return res;
108 }
109 res = xpcu_read_firmware_version(xpcu, buf);
110 if (res < 0)
111 {
112 fprintf(stderr,"xpcu_read_firmware_version: failed\n");
113 return res;
114 }
115 res = xpcu_read_cpld_version(xpcu, buf);
116 if (res < 0)
117 {
118 fprintf(stderr,"xpcu_read_cpld_version: failed\n");
119 return res;
120 }
121 if (verbose)
122 {
123 fprintf(stderr, "firmware version = 0x%02x%02x (%u)\n",
124 buf[1], buf[0], buf[1]<<8| buf[0]);
125 fprintf(stderr, "CPLD version = 0x%02x%02x (%u)\n",
126 buf[1], buf[0], buf[1]<<8| buf[0]);
127 if(hid)
128 #ifdef __WIN32__
129 fprintf(stderr, "DLC HID = 0x%I64x\n", hid);
130 #else
131 fprintf(stderr, "DLC HID = 0x%015Lx\n", hid);
132 #endif
133 }
134 if(!buf[1] && !buf[0])
135 {
136 fprintf(stderr,"Warning: version '0' can't be correct."
137 " Please try resetting the cable\n");
138 return 1;
139 }
140
141 if (subtype == XPC_INTERNAL)
142 {
143 res = xpcu_select_gpio(xpcu, 0);
144 if (res < 0)
145 {
146 usb_close(xpcu);
147 fprintf(stderr, "Error Setting internal mode: ");
148 return 2;
149 }
150 }
151 else
152 {
153 unsigned char zero[2] = {0,0};
154
155 r = xpcu_request_28(xpcu, 0x11);
156 if (r>=0) r = xpcu_output_enable(xpcu, 1);
157 if (r>=0) r = xpcu_shift(xpcu, 0xA6, 2, 2, zero, 0, NULL);
158 if (r>=0) r = xpcu_request_28(xpcu, 0x12);
159
160 if (r<0)
161 {
162 usb_close(xpcu);
163 fprintf(stderr, "Setting external mode: ");
164 return 3;
165 }
166 }
167 return 0;
168 }
169
~IOXPC()170 IOXPC::~IOXPC()
171 {
172 xpcu_output_enable(xpcu, 0);
173 xpc_close_interface (xpcu);
174 if(fp_dbg)
175 fclose(fp_dbg);
176 }
177
xpcu_output_enable(struct usb_dev_handle * xpcu,int enable)178 int IOXPC::xpcu_output_enable(struct usb_dev_handle *xpcu, int enable)
179 {
180 if(usb_control_msg(xpcu, 0x40, 0xB0, enable ? 0x18 : 0x10, 0, NULL, 0, 1000)
181 <0)
182 {
183 fprintf(stderr, "usb_control_msg(%x) %s\n", enable, usb_strerror());
184 return -1;
185 }
186 call_ctrl++;
187 return 0;
188 }
189
xpcu_request_28(struct usb_dev_handle * xpcu,int value)190 int IOXPC::xpcu_request_28(struct usb_dev_handle *xpcu, int value)
191 {
192 /* Typical values seen during autodetection of chain configuration:
193 0x11, 0x12 */
194
195 if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0028, value, NULL, 0, 1000)<0)
196 {
197 fprintf(stderr, "usb_control_msg(0x28 %x) %s\n", value, usb_strerror());
198 return -1;
199 }
200 call_ctrl++;
201 return 0;
202 }
203 /* ---------------------------------------------------------------------- */
204
xpcu_write_gpio(struct usb_dev_handle * xpcu,unsigned char bits)205 int IOXPC::xpcu_write_gpio(struct usb_dev_handle *xpcu, unsigned char bits)
206 {
207 if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0030, bits, NULL, 0, 1000)<0)
208 {
209 fprintf(stderr, "usb_control_msg(0x30.0x%02x) (write port E) %s\n",
210 bits, usb_strerror());
211 return -1;
212 }
213 call_ctrl++;
214 if (fp_dbg)
215 fprintf(fp_dbg, "w%02x ", bits);
216 return 0;
217 }
218
219 /* ---------------------------------------------------------------------- */
220
xpcu_read_gpio(struct usb_dev_handle * xpcu,unsigned char * bits)221 int IOXPC::xpcu_read_gpio(struct usb_dev_handle *xpcu, unsigned char *bits)
222 {
223 if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0038, 0, (char*)bits, 1, 1000)<0)
224 {
225 fprintf(stderr, "usb_control_msg(0x38) (read port E) %s\n",
226 usb_strerror());
227 return -1;
228 }
229 call_ctrl++;
230 if (fp_dbg)
231 fprintf(fp_dbg, "r%02x ", bits[0]);
232
233 return 0;
234 }
235
236 /* ---------------------------------------------------------------------- */
237
238
xpcu_read_cpld_version(struct usb_dev_handle * xpcu,unsigned char * buf)239 int IOXPC::xpcu_read_cpld_version(struct usb_dev_handle *xpcu,
240 unsigned char *buf)
241 {
242 if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0001, (char*)buf, 2, 1000)<0)
243 {
244 fprintf(stderr, "usb_control_msg(0x50.1) (read_cpld_version) %s\n",
245 usb_strerror());
246 return -1;
247 }
248 call_ctrl++;
249 return 0;
250 }
251
252 /* ---------------------------------------------------------------------- */
253
254
xpcu_read_hid(struct usb_dev_handle * xpcu)255 int IOXPC::xpcu_read_hid(struct usb_dev_handle *xpcu)
256 {
257 int i;
258 char buf[8];
259 hid = 0;
260 int rc = usb_control_msg(xpcu, 0xC0, 0xB0, 0x0042, 0x001, buf, 8, 1000);
261 if(rc<0)
262 {
263 return rc;
264 }
265 for (i=6; i>= 0; i--)
266 hid = (hid<<8) +buf[i];
267 call_ctrl++;
268 return 0;
269 }
270
271 /* ---------------------------------------------------------------------- */
272
xpcu_read_firmware_version(struct usb_dev_handle * xpcu,unsigned char * buf)273 int IOXPC::xpcu_read_firmware_version(struct usb_dev_handle *xpcu,
274 unsigned char *buf)
275 {
276 if(usb_control_msg(xpcu, 0xC0, 0xB0, 0x0050, 0x0000, (char*)buf, 2, 1000)<0)
277 {
278 fprintf(stderr, "usb_control_msg(0x50.0) (read_firmware_version) %s\n",
279 usb_strerror());
280 return -1;
281 }
282 call_ctrl++;
283 return 0;
284 }
hint_loadfirmware(struct usb_device * dev)285 void hint_loadfirmware(struct usb_device *dev)
286 {
287 fprintf(stderr,
288 "\nFirmware doesn't support unique number readout! If unique \n"
289 "number is needed for board destinction, try overloading(!)\n"
290 "with an firmware from ../Xilinx/nn.n/ISE/data\n"
291 "e.g. with fxload -t fx2lp -I <firmware> -D /dev/bus/usb/%s/%s\n"
292 "and e.g. firmware ../Xilinx/nn.n/ISE/data/xusb_emb.hex for SP601\n"
293 "or e.g. firmware ../Xilinx/nn.n/ISE/data/xusb_xp2.hex for DLC10\n"
294 "\n", dev->bus->dirname, dev->filename);
295 }
296
xpcu_select_gpio(struct usb_dev_handle * xpcu,int int_or_ext)297 int IOXPC::xpcu_select_gpio(struct usb_dev_handle *xpcu, int int_or_ext )
298 {
299 if(usb_control_msg(xpcu, 0x40, 0xB0, 0x0052, int_or_ext, NULL, 0, 1000)<0)
300 {
301 fprintf(stderr, "usb_control_msg(0x52.x) (select gpio) %s\n",
302 usb_strerror());
303 return -1;
304 }
305 call_ctrl++;
306 return 0;
307 }
308
309 /* === A6 transfer (TDI/TMS/TCK/RDO) ===
310 *
311 * Vendor request 0xA6 initiates a quite universal shift operation. The data
312 * is passed directly to the CPLD as 16-bit words.
313 *
314 * The argument N in the request specifies the number of state changes/bits.
315 *
316 * State changes are described by the following bulk write. It consists
317 * of ceil(N/4) little-endian 16-bit words, each describing up to 4 changes:
318 *
319 * Care has to be taken that N is NOT a multiple of 4.
320 * The CPLD doesn't seem to handle that well.
321 *
322 * Bit 0: Value for first TDI to shift out.
323 * Bit 1: Second TDI.
324 * Bit 2: Third TDI.
325 * Bit 3: Fourth TDI.
326 *
327 * Bit 4: Value for first TMS to shift out.
328 * Bit 5: Second TMS.
329 * Bit 6: Third TMS.
330 * Bit 7: Fourth TMS.
331 *
332 * Bit 8: Whether to raise/lower TCK for first bit.
333 * Bit 9: Same for second bit.
334 * Bit 10: Third bit.
335 * Bit 11: Fourth bit.
336 *
337 * Bit 12: Whether to read TDO for first bit
338 * Bit 13: Same for second bit.
339 * Bit 14: Third bit.
340 * Bit 15: Fourth bit.
341 *
342 * After the bulk write, if any of the bits 12..15 was set in any word, a
343 * bulk_read shall follow to collect the TDO data.
344 *
345 * TDO data is shifted in from MSB to LSB and transferred 32-bit little-endian.
346 * In a "full" word with 32 TDO bits, the earliest one reached bit 0.
347 * The earliest of 31 bits however would be bit 1. A 17 bit transfer has the LSB
348 * as the MSB of uint16_t[0], other bits are in uint16_t[1].
349 *
350 * However, if the last packet is smaller than 16, only 2 bytes are transferred.
351 * If there's only one TDO bit, it arrives as the MSB of the 16-bit word, uint16_t[0].
352 * uint16_t[1] is then skipped.
353 *
354 * For full 32 bits blocks, the data is aligned. The last non 32-bits block arrives
355 * non-aligned and has to be re-aligned. Half-words (16-bits) transfers have to be
356 * re-aligned too.
357 */
358 int
xpcu_shift(struct usb_dev_handle * xpcu,int reqno,int bits,int in_len,unsigned char * in,int out_len,unsigned char * out)359 IOXPC::xpcu_shift(struct usb_dev_handle *xpcu, int reqno, int bits,
360 int in_len, unsigned char *in, int out_len,
361 unsigned char *out )
362 {
363 if(usb_control_msg(xpcu, 0x40, 0xB0, reqno, bits, NULL, 0, 1000)<0)
364 {
365 fprintf(stderr, "usb_control_msg(0x40.0x%02x 0x%02x) (shift) %s\n",
366 reqno, bits, usb_strerror());
367 return -1;
368 }
369 call_ctrl++;
370 if(fp_dbg)
371 {
372 int i;
373 fprintf(fp_dbg, "###\n");
374 fprintf(fp_dbg, "reqno = %02X\n", reqno);
375 fprintf(fp_dbg, "bits = %d\n", bits);
376 fprintf(fp_dbg, "in_len = %d, in_len*2 = %d\n", in_len, in_len * 2);
377 fprintf(fp_dbg, "out_len = %d, out_len*8 = %d\n", out_len, out_len * 8);
378
379 fprintf(fp_dbg, "a6_display(\"%02X\", \"", bits);
380 for(i=0;i<in_len;i++) fprintf(fp_dbg, "%02X%s", in[i],
381 (i+1<in_len)?",":"");
382 fprintf(fp_dbg, "\", ");
383 }
384
385 if(usb_bulk_write(xpcu, 0x02, (char*)in, in_len, 1000)<0)
386 {
387 fprintf(fp_dbg, "\nusb_bulk_write error(shift): %s\n", usb_strerror());
388 return -1;
389 }
390 calls_wr++;
391 if(out_len > 0 && out != NULL)
392 {
393 if(usb_bulk_read(xpcu, 0x86, (char*)out, out_len, 1000)<0)
394 {
395 fprintf(stderr, "\nusb_bulk_read error(shift): %s\n",
396 usb_strerror());
397 return -1;
398 }
399 calls_rd++;
400 }
401
402 if(fp_dbg)
403 {
404 int i;
405 fprintf(fp_dbg, "\"");
406 for(i=0;i<out_len;i++)
407 fprintf(fp_dbg, "%02X%s", out[i], (i+1<out_len)?",":"");
408 fprintf(fp_dbg, "\")\n");
409 }
410
411 return 0;
412 }
413 /* ---------------------------------------------------------------------- */
414 int
xpcu_do_ext_transfer(xpc_ext_transfer_state_t * xts)415 IOXPC::xpcu_do_ext_transfer( xpc_ext_transfer_state_t *xts )
416 {
417 int r;
418 int in_len, out_len;
419
420 //cpld expects data (tdi) to be in 16 bit words
421 in_len = 2 * (xts->in_bits >> 2);
422 if ((xts->in_bits & 3) != 0) in_len += 2;
423
424 //cpld returns the read data (tdo) in 32 bit words
425 out_len = 2 * (xts->out_bits >> 4);
426 if ((xts->out_bits & 15) != 0) out_len += 2;
427
428 if(xts->out != NULL)
429 {
430 r = xpcu_shift (xpcu, 0xA6, xts->in_bits, in_len, xts->buf,
431 out_len, xts->buf);
432 }
433 else
434 {
435 r = xpcu_shift (xpcu, 0xA6, xts->in_bits, in_len, xts->buf, 0, NULL);
436 }
437 if(r >= 0 && xts->out_bits > 0)
438 {
439 int i;
440 unsigned int aligned_32bitwords, aligned_bytes;
441 unsigned int shift, bit_num, bit_val;
442
443 aligned_32bitwords = xts->out_bits/32;
444 aligned_bytes = aligned_32bitwords*4;
445 memcpy(xts->out, xts->buf, aligned_bytes);
446 xts->out_done = aligned_bytes*8;
447
448 //This data is not aligned
449 if (xts->out_bits % 32)
450 {
451 shift = xts->out_bits % 16; //we can also receive a 16-bit word in which case
452 if (shift) //the MSB starts in the least significant 16 bit word
453 shift = 16 - shift; //and it shifts the same way for 32 bit if
454 //out_bits > 16 and ( shift = 32 - out_bits % 32 )
455 if (fp_dbg)
456 fprintf(fp_dbg, "out_done %d shift %d\n", xts->out_done, shift);
457 for (i = aligned_bytes*8; i < xts->out_bits; i++)
458 {
459 bit_num = i + shift;
460 bit_val = xts->buf[bit_num/8] & (1<<(bit_num%8));
461 if(!(xts->out_done % 8))
462 xts->out[xts->out_done/8] = 0;
463 if (bit_val)
464 xts->out[xts->out_done/8] |= (1<<(xts->out_done%8));
465 xts->out_done++;
466 }
467 }
468
469 if (fp_dbg)
470 {
471 int i;
472 fprintf(fp_dbg, "Shifted data");
473 for( i = 0; i < out_len; i++)
474 {
475 fprintf(fp_dbg, " %02x", xts->out[i]);
476 }
477 fprintf(fp_dbg, "\n");
478 }
479
480 }
481
482 xts->in_bits = 0;
483 xts->out_bits = 0;
484
485 return r;
486 }
487
488 /* ---------------------------------------------------------------------- */
489 void
xpcu_add_bit_for_ext_transfer(xpc_ext_transfer_state_t * xts,bool in,bool tms,bool is_real)490 IOXPC::xpcu_add_bit_for_ext_transfer( xpc_ext_transfer_state_t *xts, bool in,
491 bool tms, bool is_real )
492 {
493 int bit_idx = (xts->in_bits & 3);
494 int buf_idx = (xts->in_bits - bit_idx) >> 1;
495
496 if(bit_idx == 0)
497 {
498 xts->buf[buf_idx] = 0;
499 xts->buf[buf_idx+1] = 0;
500 }
501
502 xts->in_bits++;
503
504 if(is_real)
505 {
506 if(in) xts->buf[buf_idx] |= (0x01<<bit_idx);
507 if(tms) xts->buf[buf_idx] |= (0x10<<bit_idx);
508
509 if(xts->out)
510 {
511 xts->buf[buf_idx+1] |= (0x11<<bit_idx);
512 xts->out_bits++;
513 }
514 else
515 {
516 xts->buf[buf_idx+1] |= (0x01<<bit_idx);
517 }
518 }
519 }
520
521 /* ---------------------------------------------------------------------- */
522
523
txrx_block(const unsigned char * in,unsigned char * out,int len,bool last)524 void IOXPC::txrx_block(const unsigned char *in, unsigned char *out, int len,
525 bool last)
526 {
527 int i;
528 if (fp_dbg)
529 {
530 fprintf(fp_dbg, "---\n");
531 fprintf(fp_dbg, "transfer size %d, %s output\n", len,
532 (out!=NULL) ? "with" : "without");
533 fprintf(fp_dbg, "tdi: ");
534 for(i=0;i<len;i++)
535 fprintf(fp_dbg, "%c", (in)?((in[i>>3] & (1<<i%8))?'1':'0'):'0');
536 fprintf(fp_dbg, "%s\n",(last)?"last":"");
537 }
538
539 if (subtype == XPC_INTERNAL)
540 {
541 unsigned char tdi, d;
542 for (i = 0; i < len; i++)
543 {
544 if ((i & 0x7) == 0)
545 {
546 if (in)
547 tdi = in[i>>3];
548 else
549 tdi = 0;
550 if(out)
551 out[i>>3] = 0;
552 }
553 xpcu_write_gpio(xpcu, XPC_PROG | XPC_TCK | ((last)? XPC_TMS : 0) |
554 ((tdi & 0x01)? XPC_TDI : 0));
555 if(out)
556 {
557 xpcu_read_gpio(xpcu, &d);
558 out[i>>3] |= ((d & XPC_TDO) == XPC_TDO)?(i%8):0;
559 }
560 xpcu_write_gpio(xpcu, XPC_PROG | 0 | ((last)? XPC_TMS : 0) |
561 ((tdi & 0x01)? XPC_TDI : 0));
562 tdi = tdi >> 1;
563 }
564 }
565 else
566 {
567 int j;
568 xpc_ext_transfer_state_t xts;
569
570 xts.out = (out)? out: NULL;
571 xts.in_bits = 0;
572 xts.out_bits = 0;
573 xts.out_done = 0;
574
575 for(i=0,j=0; i<len && j>=0; i++)
576 {
577 int tdi;
578 if (in)
579 {
580 if ((i & 0x7 ) == 0)
581 tdi = in[i>>3];
582 }
583 else
584 tdi = 0;
585
586 xpcu_add_bit_for_ext_transfer( &xts, (tdi & 1),
587 (i== len-1)?last:0, 1 );
588 tdi >>= 1;
589 if(xts.in_bits == (2*CPLD_MAX_BYTES - 1))
590 {
591 j = xpcu_do_ext_transfer( &xts );
592 }
593 }
594
595 if(xts.in_bits > 0 && j>=0)
596 {
597 /* CPLD doesn't like multiples of 4; add one dummy bit */
598 if((xts.in_bits & 3) == 0)
599 {
600 xpcu_add_bit_for_ext_transfer( &xts, 0, 0, 0 );
601 }
602 j = xpcu_do_ext_transfer( &xts );
603 }
604 }
605 }
606
tx_tms(unsigned char * in,int len,int force)607 void IOXPC::tx_tms(unsigned char *in, int len, int force)
608 {
609 int i;
610
611 if (fp_dbg)
612 {
613 fprintf(fp_dbg, "---\n");
614 fprintf(fp_dbg, "transfer size %d\n", len);
615 fprintf(fp_dbg, "TMS: ");
616 for(i=0;i<len;i++) fprintf(fp_dbg, "%c", (in[i>>3] & 1<<(i%8))?'1':'0');
617 fprintf(fp_dbg, "\n");
618 }
619
620 if (subtype == XPC_INTERNAL)
621 {
622 unsigned char tms;
623 for (i = 0; i < len; i++)
624 {
625 if ((i & 0x7) == 0)
626 tms = in[i>>3];
627 xpcu_write_gpio(xpcu, XPC_PROG | XPC_TCK |
628 ((tms & 0x01)? XPC_TMS : 0) | XPC_TDI);
629 xpcu_write_gpio(xpcu, XPC_PROG | 0 |
630 ((tms & 0x01)? XPC_TMS : 0) | XPC_TDI);
631 tms = tms >> 1;
632 }
633 }
634 else
635 {
636 int j;
637 xpc_ext_transfer_state_t xts;
638
639 xts.out = NULL;
640 xts.in_bits = 0;
641 xts.out_bits = 0;
642 xts.out_done = 0;
643
644 for(i=0,j=0; i<len && j>=0; i++)
645 {
646 xpcu_add_bit_for_ext_transfer( &xts, 1, (in[i>>3] & (1<<(i%8))), 1 );
647 if(xts.in_bits == (2*CPLD_MAX_BYTES - 1))
648 {
649 j = xpcu_do_ext_transfer( &xts );
650 }
651 }
652
653 if(xts.in_bits > 0 && j>=0)
654 {
655 /* CPLD doesn't like multiples of 4; add one dummy bit */
656 if((xts.in_bits & 3) == 0)
657 {
658 xpcu_add_bit_for_ext_transfer( &xts, 0, 0, 0 );
659 }
660 j = xpcu_do_ext_transfer( &xts );
661 }
662
663 }
664 }
665
666 #define xpc_error_return(code, str) do { \
667 error_str = str; \
668 return code; \
669 } while(0);
670
xpc_usb_open_desc(int vendor,int product,const char * description,unsigned long long int lserial)671 int IOXPC::xpc_usb_open_desc(int vendor, int product, const char* description,
672 unsigned long long int lserial)
673 {
674 /* Adapted from libftdi:ftdi_usb_open_desc()
675
676 Opens the first device with a given, vendor id, product id,
677 description and serial.
678 */
679
680 struct usb_bus *bus;
681 struct usb_device *dev;
682 char string[256];
683
684 usb_init();
685
686 if (usb_find_busses() < 0)
687 xpc_error_return(-1, "usb_find_busses() failed");
688 if (usb_find_devices() < 0)
689 xpc_error_return(-2, "usb_find_devices() failed");
690
691 for (bus = usb_get_busses(); bus; bus = bus->next)
692 {
693 for (dev = bus->devices; dev; dev = dev->next)
694 {
695 if (dev->descriptor.idVendor == vendor
696 && dev->descriptor.idProduct == product)
697 {
698 if (!(xpcu = usb_open(dev)))
699 xpc_error_return(-4, "usb_open() failed");
700 if (description != NULL)
701 {
702 if (usb_get_string_simple(xpcu, dev->descriptor.iProduct,
703 string, sizeof(string)) <= 0)
704 {
705 usb_close (xpcu);
706 xpc_error_return(-8,
707 "unable to fetch product description");
708 }
709 if (strncmp(string, description, sizeof(string)) != 0)
710 {
711 if (usb_close (xpcu) != 0)
712 xpc_error_return(-10, "unable to close device");
713 continue;
714 }
715 }
716
717 if (usb_set_configuration (xpcu, dev->config[0].bConfigurationValue) < 0)
718 {
719 fprintf (stderr, "%s: usb_set_configuration: failed conf %d\n",
720 __FUNCTION__, dev->config[0].bConfigurationValue);
721 fprintf (stderr, "%s\n", usb_strerror());
722 usb_close (xpcu);
723 xpc_error_return(-10,
724 "unable to set configuration");
725 }
726 if (usb_claim_interface (xpcu, 0) < 0){
727 fprintf (stderr, "%s:usb_claim_interface: failed interface 0\n",
728 __FUNCTION__);
729 fprintf (stderr, "%s\n", usb_strerror());
730 usb_close (xpcu);
731 xpc_error_return(-11,
732 "unable to claim interface");
733 }
734 #if 0
735 int rc = xpcu_read_hid(xpcu);
736 if (rc < 0)
737 {
738 if (rc == -EPIPE)
739 {
740 if (lserial != 0)
741 {
742 hint_loadfirmware(dev);
743 return 0;
744 }
745 }
746 else
747 fprintf(stderr, "usb_control_msg(0x42.1 %s\n",
748 usb_strerror());
749 }
750 else
751 if ((lserial != 0) && (lserial != hid))
752 {
753 usb_close (xpcu);
754 continue;
755 }
756 #else
757 hid = 0;
758 #endif
759 return 0;
760 }
761 }
762 }
763 // device not found
764 xpc_error_return(-3, "device not found");
765 }
766
xpc_close_interface(struct usb_dev_handle * udh)767 bool IOXPC::xpc_close_interface (struct usb_dev_handle *udh)
768 {
769 // we're assuming that closing an interface automatically releases it.
770 if(verbose)
771 fprintf(stderr, "USB Read Transactions: %d Write Transactions: %d"
772 " Control Transaction %d\n",
773 calls_rd, calls_wr, call_ctrl);
774 return usb_close (udh) == 0;
775 }
776
777
778