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