⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 darwin.c

📁 This libusb version 0.1.12. libusb is a library which allows userspace application access to USB de
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Darwin/MacOS X Support * * (c) 2002-2005 Nathan Hjelm <hjelmn@users.sourceforge.net> * * (04/17/2005): *   - Lots of minor fixes. *   - Endpoint table now made by claim_interface to fix a bug. *   - Merged Read/Write to make modifications easier. * (03/25/2005): *   - Fixed a bug when using asynchronous callbacks within a multi-threaded application. * (03/14/2005): *   - Added an endpoint table to speed up bulk transfers. * 0.1.11 (02/22/2005): *   - Updated error checking in read/write routines to check completion codes. *   - Updated set_configuration so that the open interface is reclaimed before completion. *   - Fixed several typos. * 0.1.8 (01/12/2004): *   - Fixed several memory leaks. *   - Readded 10.0 support *   - Added support for USB fuctions defined in 10.3 and above * (01/02/2003): *   - Applied a patch by Philip Edelbrock <phil@edgedesign.us> that fixes a bug in usb_control_msg. * (12/16/2003): *   - Even better error printing. *   - Devices that cannot be opened can have their interfaces opened. * 0.1.6 (05/12/2002): *   - Fixed problem where libusb holds resources after program completion. *   - Mouse should no longer freeze up now. * 0.1.2 (02/13/2002): *   - Bulk functions should work properly now. * 0.1.1 (02/11/2002): *   - Fixed major bug (device and interface need to be released after use) * 0.1.0 (01/06/2002): *   - Tested driver with gphoto (works great as long as Image Capture isn't running) * 0.1d  (01/04/2002): *   - Implimented clear_halt and resetep *   - Uploaded to CVS. * 0.1b  (01/04/2002): *   - Added usb_debug line to bulk read and write function. * 0.1a  (01/03/2002): *   - Driver mostly completed using the macosx driver I wrote for my rioutil software. * * Derived from Linux version by Richard Tobin. * Also partly derived from BSD version. * * This library is covered by the LGPL, read LICENSE for details. */#ifdef HAVE_CONFIG_H#include "config.h"#endif#include <stdlib.h>#include <stdio.h>#include <unistd.h>/* standard includes for darwin/os10 (IOKit) */#include <mach/mach_port.h>#include <IOKit/IOCFBundle.h>#include <IOKit/usb/IOUSBLib.h>#include <IOKit/IOCFPlugIn.h>#include "usbi.h"/* some defines *//* IOUSBInterfaceInferface */#if defined (kIOUSBInterfaceInterfaceID220)// #warning "libusb being compiled for 10.4 or later"#define usb_interface_t IOUSBInterfaceInterface220#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID220#define InterfaceVersion 220#elif defined (kIOUSBInterfaceInterfaceID197)// #warning "libusb being compiled for 10.3 or later"#define usb_interface_t IOUSBInterfaceInterface197#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID197#define InterfaceVersion 197#elif defined (kIOUSBInterfaceInterfaceID190)// #warning "libusb being compiled for 10.2 or later"#define usb_interface_t IOUSBInterfaceInterface190#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID190#define InterfaceVersion 190#elif defined (kIOUSBInterfaceInterfaceID182)// #warning "libusb being compiled for 10.1 or later"#define usb_interface_t IOUSBInterfaceInterface182#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID182#define InterfaceVersion 182#else/* No timeout functions available! Time to upgrade your os. */#warning "libusb being compiled without support for timeout bulk functions! 10.0 and up"#define usb_interface_t IOUSBInterfaceInterface#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID#define LIBUSB_NO_TIMEOUT_INTERFACE#define InterfaceVersion 180#endif/* IOUSBDeviceInterface */#if defined (kIOUSBDeviceInterfaceID197)#define usb_device_t    IOUSBDeviceInterface197#define DeviceInterfaceID kIOUSBDeviceInterfaceID197#define DeviceVersion 197#elif defined (kIOUSBDeviceInterfaceID187)#define usb_device_t    IOUSBDeviceInterface187#define DeviceInterfaceID kIOUSBDeviceInterfaceID187#define DeviceVersion 187#elif defined (kIOUSBDeviceInterfaceID182)#define usb_device_t    IOUSBDeviceInterface182#define DeviceInterfaceID kIOUSBDeviceInterfaceID182#define DeviceVersion 182#else#define usb_device_t    IOUSBDeviceInterface#define DeviceInterfaceID kIOUSBDeviceInterfaceID#define LIBUSB_NO_TIMEOUT_DEVICE#define LIBUSB_NO_SEIZE_DEVICE#define DeviceVersion 180#endiftypedef IOReturn io_return_t;typedef IOCFPlugInInterface *io_cf_plugin_ref_t;typedef SInt32 s_int32_t;typedef IOReturn (*rw_async_func_t)(void *self, UInt8 pipeRef, void *buf, UInt32 size,				    IOAsyncCallback1 callback, void *refcon);typedef IOReturn (*rw_async_to_func_t)(void *self, UInt8 pipeRef, void *buf, UInt32 size,				       UInt32 noDataTimeout, UInt32 completionTimeout,				       IOAsyncCallback1 callback, void *refcon);#if !defined(IO_OBJECT_NULL)#define IO_OBJECT_NULL ((io_object_t)0)#endif/* Darwin/OS X impl does not use fd field, instead it uses this */struct darwin_dev_handle {  usb_device_t **device;  usb_interface_t **interface;  int open;  /* stored translation table for pipes to endpoints */  int num_endpoints;  unsigned char *endpoint_addrs;};static CFMutableDictionaryRef matchingDict;static IONotificationPortRef gNotifyPort;static mach_port_t masterPort = MACH_PORT_NULL;static void darwin_cleanup (void){  IONotificationPortDestroy(gNotifyPort);  mach_port_deallocate(mach_task_self(), masterPort);}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 async 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 the Darwin kernel";  case kIOUSBTransactionTimeout:    return "transaction timed out";  case kIOReturnBadArgument:    return "invalid argument";  case kIOReturnAborted:    return "transaction aborted";  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 kIOUSBTransactionTimeout:    return ETIMEDOUT;  case kIOReturnError:  default:    return 1;  }}static int usb_setup_iterator (io_iterator_t *deviceIterator){  int result;  /* set up the matching dictionary for class IOUSBDevice and its subclasses.     It will be consumed by the IOServiceGetMatchingServices call */  if ((matchingDict = IOServiceMatching(kIOUSBDeviceClassName)) == NULL) {    darwin_cleanup ();        USB_ERROR_STR(-1, "libusb/darwin.c usb_setup_iterator: Could not create a matching dictionary.\n");  }  result = IOServiceGetMatchingServices(masterPort, matchingDict, deviceIterator);  matchingDict = NULL;  if (result != kIOReturnSuccess)    USB_ERROR_STR (-darwin_to_errno (result), "libusb/darwin.c usb_setup_iterator: IOServiceGetMatchingServices: %s\n",		   darwin_error_str(result));  return 0;}static usb_device_t **usb_get_next_device (io_iterator_t deviceIterator, UInt32 *locationp){  io_cf_plugin_ref_t *plugInInterface = NULL;  usb_device_t **device;  io_service_t usbDevice;  long result, score;  if (!IOIteratorIsValid (deviceIterator) || !(usbDevice = IOIteratorNext(deviceIterator)))    return NULL;    result = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,					     kIOCFPlugInInterfaceID, &plugInInterface,					     &score);    result = IOObjectRelease(usbDevice);  if (result || !plugInInterface)    return NULL;    (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),				     (LPVOID)&device);    (*plugInInterface)->Stop(plugInInterface);  IODestroyPlugInInterface (plugInInterface);  plugInInterface = NULL;    (*(device))->GetLocationID(device, locationp);  return device;}int usb_os_open(usb_dev_handle *dev){  struct darwin_dev_handle *device;  io_return_t result;  io_iterator_t deviceIterator;  usb_device_t **darwin_device;  UInt32 location = *((UInt32 *)dev->device->dev);  UInt32 dlocation;  if (!dev)    USB_ERROR(-ENXIO);  if (masterPort == MACH_PORT_NULL)    USB_ERROR(-EINVAL);  device = calloc(1, sizeof(struct darwin_dev_handle));  if (!device)    USB_ERROR(-ENOMEM);  if (usb_debug > 3)    fprintf(stderr, "usb_os_open: %04x:%04x\n",	    dev->device->descriptor.idVendor,	    dev->device->descriptor.idProduct);  if ((result = usb_setup_iterator (&deviceIterator)) < 0)    return result;  /* This port of libusb uses locations to keep track of devices. */  while ((darwin_device = usb_get_next_device (deviceIterator, &dlocation)) != NULL) {    if (dlocation == location)      break;    (*darwin_device)->Release(darwin_device);  }  IOObjectRelease(deviceIterator);  device->device = darwin_device;  if (device->device == NULL)    USB_ERROR_STR (-ENOENT, "usb_os_open: %s\n", "Device not found!");#if !defined (LIBUSB_NO_SEIZE_DEVICE)  result = (*(device->device))->USBDeviceOpenSeize (device->device);#else  /* No Seize in OS X 10.0 (Darwin 1.4) */  result = (*(device->device))->USBDeviceOpen (device->device);#endif  if (result != kIOReturnSuccess) {    switch (result) {    case kIOReturnExclusiveAccess:      if (usb_debug > 0)	fprintf (stderr, "usb_os_open(USBDeviceOpenSeize): %s\n", darwin_error_str(result));      break;    default:      (*(device->device))->Release (device->device);      USB_ERROR_STR(-darwin_to_errno (result), "usb_os_open(USBDeviceOpenSeize): %s",		    darwin_error_str(result));    }        device->open = 0;  } else    device->open = 1;      dev->impl_info = device;  dev->interface = -1;  dev->altsetting = -1;  device->num_endpoints  = 0;  device->endpoint_addrs = NULL;  return 0;}int usb_os_close(usb_dev_handle *dev){  struct darwin_dev_handle *device;  io_return_t result;  if (!dev)    USB_ERROR(-ENXIO);  if ((device = dev->impl_info) == NULL)    USB_ERROR(-ENOENT);  usb_release_interface(dev, dev->interface);  if (usb_debug > 3)    fprintf(stderr, "usb_os_close: %04x:%04x\n",	    dev->device->descriptor.idVendor,	    dev->device->descriptor.idProduct);  if (device->open == 1)    result = (*(device->device))->USBDeviceClose(device->device);  else    result = kIOReturnSuccess;  /* device may not need to be released, but if it has to... */  (*(device->device))->Release(device->device);  if (result != kIOReturnSuccess)    USB_ERROR_STR(-darwin_to_errno(result), "usb_os_close(USBDeviceClose): %s", darwin_error_str(result));  free (device);  return 0;}static int get_endpoints (struct darwin_dev_handle *device){  io_return_t ret;  u_int8_t numep, direction, number;  u_int8_t dont_care1, dont_care3;  u_int16_t dont_care2;  int i;  if (device == NULL || device->interface == NULL)    return -EINVAL;  if (usb_debug > 1)    fprintf(stderr, "libusb/darwin.c get_endpoints: building table of endpoints.\n");  /* retrieve the total number of endpoints on this interface */  ret = (*(device->interface))->GetNumEndpoints(device->interface, &numep);  if ( ret ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -