mirror of https://gerrit.osmocom.org/libusrp
191 lines
5.7 KiB
C++
191 lines
5.7 KiB
C++
/* -*- c++ -*- */
|
|
/*
|
|
* Copyright 2006 Free Software Foundation, Inc.
|
|
*
|
|
* This file is part of GNU Radio.
|
|
*
|
|
* GNU Radio is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* GNU Radio is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with GNU Radio; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 51 Franklin Street,
|
|
* Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
/*
|
|
* The following code was taken from LIBUSB verion 0.1.10a,
|
|
* and makes the fusb_darwin codes do-able in the current GR
|
|
* programming framework. Parts and pieces were taken from
|
|
* usbi.h, darwin.c, and error.h .
|
|
*
|
|
* LIBUSB version 0.1.10a is covered by the LGPL, version 2;
|
|
* These codes are used with permission from:
|
|
* (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
|
|
* (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net>
|
|
* All rights reserved.
|
|
*/
|
|
|
|
#ifndef __DARWIN_LIBUSB_H__
|
|
#define __DARWIN_LIBUSB_H__
|
|
|
|
#include <IOKit/IOCFBundle.h>
|
|
#include <IOKit/IOCFPlugIn.h>
|
|
#include <IOKit/usb/IOUSBLib.h>
|
|
#include <IOKit/IOKitLib.h>
|
|
|
|
extern "C" {
|
|
static char *
|
|
darwin_error_str (int result)
|
|
{
|
|
switch (result) {
|
|
case kIOReturnSuccess:
|
|
return "no error";
|
|
case kIOReturnNotOpen:
|
|
return "device not opened for exclusive access";
|
|
case kIOReturnNoDevice:
|
|
return "no connection to an IOService";
|
|
case kIOUSBNoAsyncPortErr:
|
|
return "no asyc port has been opened for interface";
|
|
case kIOReturnExclusiveAccess:
|
|
return "another process has device opened for exclusive access";
|
|
case kIOUSBPipeStalled:
|
|
return "pipe is stalled";
|
|
case kIOReturnError:
|
|
return "could not establish a connection to Darin kernel";
|
|
case kIOReturnBadArgument:
|
|
return "invalid argument";
|
|
default:
|
|
return "unknown error";
|
|
}
|
|
}
|
|
|
|
/* not a valid errorno outside darwin.c */
|
|
#define LUSBDARWINSTALL (ELAST+1)
|
|
|
|
static int
|
|
darwin_to_errno (int result)
|
|
{
|
|
switch (result) {
|
|
case kIOReturnSuccess:
|
|
return 0;
|
|
case kIOReturnNotOpen:
|
|
return EBADF;
|
|
case kIOReturnNoDevice:
|
|
case kIOUSBNoAsyncPortErr:
|
|
return ENXIO;
|
|
case kIOReturnExclusiveAccess:
|
|
return EBUSY;
|
|
case kIOUSBPipeStalled:
|
|
return LUSBDARWINSTALL;
|
|
case kIOReturnBadArgument:
|
|
return EINVAL;
|
|
case kIOReturnError:
|
|
default:
|
|
return 1;
|
|
}
|
|
}
|
|
|
|
typedef enum {
|
|
USB_ERROR_TYPE_NONE = 0,
|
|
USB_ERROR_TYPE_STRING,
|
|
USB_ERROR_TYPE_ERRNO,
|
|
} usb_error_type_t;
|
|
|
|
extern char usb_error_str[1024];
|
|
extern int usb_error_errno;
|
|
extern usb_error_type_t usb_error_type;
|
|
|
|
#define USB_ERROR(r, x) \
|
|
do { \
|
|
usb_error_type = USB_ERROR_TYPE_ERRNO; \
|
|
usb_error_errno = x; \
|
|
return r; \
|
|
} while (0)
|
|
|
|
#define USB_ERROR_STR(r, x, format, args...) \
|
|
do { \
|
|
usb_error_type = USB_ERROR_TYPE_STRING; \
|
|
snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
|
|
if (usb_debug) \
|
|
fprintf(stderr, "USB error: %s\n", usb_error_str); \
|
|
return r; \
|
|
} while (0)
|
|
|
|
#define USB_ERROR_STR_ORIG(x, format, args...) \
|
|
do { \
|
|
usb_error_type = USB_ERROR_TYPE_STRING; \
|
|
snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
|
|
if (usb_debug) \
|
|
fprintf(stderr, "USB error: %s\n", usb_error_str); \
|
|
return x; \
|
|
} while (0)
|
|
|
|
#define USB_ERROR_STR_NO_RET(x, format, args...) \
|
|
do { \
|
|
usb_error_type = USB_ERROR_TYPE_STRING; \
|
|
snprintf(usb_error_str, sizeof(usb_error_str) - 1, format, ## args); \
|
|
if (usb_debug) \
|
|
fprintf(stderr, "USB error: %s\n", usb_error_str); \
|
|
} while (0)
|
|
|
|
/* simple function that figures out what pipeRef is associated with an endpoint */
|
|
static int ep_to_pipeRef (darwin_dev_handle *device, int ep)
|
|
{
|
|
io_return_t ret;
|
|
UInt8 numep, direction, number;
|
|
UInt8 dont_care1, dont_care3;
|
|
UInt16 dont_care2;
|
|
int i;
|
|
|
|
if (usb_debug > 3)
|
|
fprintf(stderr, "Converting ep address to pipeRef.\n");
|
|
|
|
/* retrieve the total number of endpoints on this interface */
|
|
ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);
|
|
if ( ret ) {
|
|
if ( usb_debug > 3 )
|
|
fprintf ( stderr, "ep_to_pipeRef: interface is %p\n", device->interface );
|
|
USB_ERROR_STR_ORIG ( -ret, "ep_to_pipeRef: can't get number of endpoints for interface" );
|
|
}
|
|
|
|
/* iterate through the pipeRefs until we find the correct one */
|
|
for (i = 1 ; i <= numep ; i++) {
|
|
ret = (*(device->interface))->GetPipeProperties(device->interface, i, &direction, &number,
|
|
&dont_care1, &dont_care2, &dont_care3);
|
|
|
|
if (ret != kIOReturnSuccess) {
|
|
fprintf (stderr, "ep_to_pipeRef: an error occurred getting pipe information on pipe %d\n",
|
|
i );
|
|
USB_ERROR_STR_ORIG (-darwin_to_errno(ret), "ep_to_pipeRef(GetPipeProperties): %s", darwin_error_str(ret));
|
|
}
|
|
|
|
if (usb_debug > 3)
|
|
fprintf (stderr, "ep_to_pipeRef: Pipe %i: DIR: %i number: %i\n", i, direction, number);
|
|
|
|
/* calculate the endpoint of the pipe and check it versus the requested endpoint */
|
|
if ( ((direction << 7 & USB_ENDPOINT_DIR_MASK) | (number & USB_ENDPOINT_ADDRESS_MASK)) == ep ) {
|
|
if (usb_debug > 3)
|
|
fprintf(stderr, "ep_to_pipeRef: pipeRef for ep address 0x%02x found: 0x%02x\n", ep, i);
|
|
|
|
return i;
|
|
}
|
|
}
|
|
|
|
if (usb_debug > 3)
|
|
fprintf(stderr, "ep_to_pipeRef: No pipeRef found with endpoint address 0x%02x.\n", ep);
|
|
|
|
/* none of the found pipes match the requested endpoint */
|
|
return -1;
|
|
}
|
|
|
|
}
|
|
#endif /* __DARWIN_LIBUSB_H__ */
|