/* $Id: usb_surfwax.c,v 1.9 2004/03/25 00:06:14 jmuelmen Exp $ */ /* This file implements the USB-level functionality of libsurf on * systems that use Joe Virzi's surfwax library (i.e. windows). */ /* Note that at this level we're dealing with a device handle and * channel number. Turning module/board name into device handle and * channel number is done in module.c and board.c. */ #ifdef HAVE_SURFWAX #include "libsurf.h" #include "surfwax.h" #include "surf_int.h" #include "surf_drv.h" #define INIT if (!_init) surflib_init() static int _init = 0; int surf_find_boards (); struct surf_t *surf_search (const char *); #define BUFSIZE 1024 int surflib_init () { int ret = usb_init(); if (!ret) _init = 1; return ret; } int surf_write_ep (struct surf_t *b, int ep, char *buf, int count) { /* do the USB sending stuff; if it fails, call surf_find_boards() to see if the SuRF board is just hiding somewhere because of a re-enumeration. */ int n, i, length; int dev; INIT; i = 1; /* fix me --- try harder */ while (i--) { /* try to write to the board */ dev = surft_get_dev(b); if (ep) n = usb_bulk_write(dev, ep, buf, count); else /*fix me! */ ; /* now it's complicated! n = usb_control_msg(dev, buf, count, SURF_TO); */ if (n >= 0) /* we succeeded; we're happy. */ return n; /* if we didn't succeed, we have to see if the bus changed */ surft_make_stale(b); if (surf_find_boards()) /* something bad happened on the bus. errno is already set. */ return -1; /* if the board is still stale (i.e. we can't talk to the device), then it's time to give up. Probably some tourist took the board as a souvenir. */ if (surft_stale(b)) { surf_errno = ENOBOARD; return -1; } /* otherwise, we just try again. It should work on the second try unless someone changed the bus in the meantime. Then it'll work on the third try unless... */ } /* we failed. No board to be had. */ surf_errno = ENOBOARD; return -1; } int surf_read_ep (struct surf_t *b, int ep, char *buf, int count) { /* do the USB receiving stuff; if it fails, call surf_find_boards() to see if the SuRF board is just hiding somewhere because of a re-enumeration. */ int n, i; int dev; INIT; /* try to read from the board */ dev = surft_get_dev(b); i = 1; /* five tries to read from the damn thing should be enough */ while (i--) { if (ep) n = usb_bulk_read(dev, ep, buf, count); else /*fix me! */ ; /* now it's complicated! n = usb_control_msg(dev, buf, count, SURF_TO); */ if (n >= 0) /* we succeeded; we're happy. */ return n; /* if we didn't succeed, we have to see if the bus changed */ surft_make_stale(b); if (surf_find_boards()) /* something bad happened on the bus. errno is already set. */ return -1; /* if the board is still stale (i.e. we can't talk to the device), then it's time to give up. Probably some tourist took the board as a souvenir. */ if (surft_stale(b)) { surf_errno = ENOBOARD; return -1; } /* otherwise, we just try again. It should work on the second try unless someone changed the bus in the meantime. Then it'll work on the third try unless... */ /* fix me! There should be a provision for resetting the endpoint before giving up. */ } /* we failed. No board to be had. */ surf_errno = ENOBOARD; return -1; } static void convert_unicode (const char *unicode, char *ascii, int len) { int i; /* printf("Unicode string (length %x) is", len); */ /* for (i = 0; i < len; ++i) */ /* printf(" %x", unicode[i]); */ /* printf("\n"); */ for (i = 0; i < len / 2 - 1; ++i) ascii[i] = unicode[2 * i + 2]; ascii[i] = 0; } /* Go through the list of existing boards; check which ones are still connected and update the device handles as necessary */ int surf_find_boards () { /* go through the USB; get the SuRF device's serial number; check if it's in the list of boards already (binary search); if it is in the list, update the device handle if necessary; if it's not in the list, add it at the end; if there have been additions to the list, remember to qsort at the end! */ struct surf_t *surf; int dev; INIT; usb_reset(); while ((dev = usb_next_board()) != (char)-1) { int ret; char b_name[0x20], b_name_uc[0x20]; char rev[0x20], rev_uc[0x20]; if (usb_open(dev)) return -1; ret = usb_get_string(dev, 0x03, b_name_uc, 30); if (ret <= 0) { surf_errno = ESURFDEV; SURF_LOG(LOGSURF_ERROR, "Can't get board serial number\n"); return -1; } else convert_unicode(b_name_uc, b_name, ret); SURF_LOG(LOGSURF_LOUD, "Serial Number: %s\n", b_name); #if 0 ret = usb_get_string(udev, SURF_FIRM_REV, 0x03, rev_uc, sizeof(rev_uc)); if (ret <= 0) { surf_errno = ESURFDEV; SURF_LOG(LOGSURF_ERROR, "Can't get board firmware " "revision\n"); return -1; } else convert_unicode(rev_uc, rev, ret); SURF_LOG(LOGSURF_LOUD, "Revision: %02x.%02x.%02x\n", rev[0], rev[1], rev[2]); #endif /* see if the board is already in the list */ if (!(surf = surf_search(b_name))) { if (!(surf = surft_create(b_name))) /* something failed. Errno already got set. Just get out. */ return -1; } else { /* else just close the old device */ /* actually, dont. */ /* usb_close(surft_get_dev(surf)); */ } surft_set_dev(surf, dev); /* board is fresh again */ surft_make_fresh(surf); } return 0; } #endif /* HAVE_SURFWAX */