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

📄 darwin.c

📁 usb user mode lib
💻 C
📖 第 1 页 / 共 3 页
字号:
/* * Darwin/MacOS X Support * * (c) 2002-2004 Nathan Hjelm <hjelmn@users.sourceforge.net> * * 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. * * this driver is EXPERIMENTAL, use at your own risk and e-mail me bug reports. * * 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 "usbi.h"#include <unistd.h>/* standard includes for darwin/os10 (IOKit) */#include <IOKit/IOCFBundle.h>#include <IOKit/usb/IOUSBLib.h>#include <IOKit/IOCFPlugIn.h>/* some defines *//* IOUSBInterfaceInferface */#if defined (IOUSBINTERFACE_FUNCS_197)#warning "libusb being compiled for 10.3 or higher"#define usb_interface_t IOUSBInterfaceInterface197#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID197#define InterfaceVersion 197#elif defined (IOUSBINTERFACE_FUNCS_190)#warning "libusb being compiled for 10.2 or higher"#define usb_interface_t IOUSBInterfaceInterface190#define InterfaceInterfaceID kIOUSBInterfaceInterfaceID190#define InterfaceVersion 190#elif defined (IOUSBINTERFACE_FUNCS_182)#warning "libusb being compiled for 10.1 or higher"#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 timout 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 (IOUSBDEVICE_FUNCS_197)#define usb_device_t    IOUSBDeviceInterface197#define DeviceInterfaceID kIOUSBDeviceInterfaceID197#define DeviceVersion 197#elif defined (IOUSBDEVICE_FUNCS_187)#define usb_device_t    IOUSBDeviceInterface187#define DeviceInterfaceID kIOUSBDeviceInterfaceID187#define DeviceVersion 187#elif defined (IOUSBDEVICE_FUNCS_182)#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#endif#define io_return_t     IOReturn/* 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;};static CFRunLoopSourceRef runLoopSource;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 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;  }}int usb_os_open(usb_dev_handle *dev){  struct darwin_dev_handle *device;  io_return_t result;  io_iterator_t deviceIterator;  io_service_t usbDevice;  usb_device_t **darwin_device;  IOCFPlugInInterface **plugInInterface = NULL;  long score;  UInt16 address, vendor;  UInt32 location = *((UInt32 *)dev->device->dev);  UInt32 dlocation;  if (!dev)    USB_ERROR(-ENXIO);  if (!masterPort)    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);  /* 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(-ENOMEM);  }  result = IOServiceGetMatchingServices(masterPort,					matchingDict,					&deviceIterator);  matchingDict = NULL;  if (result != kIOReturnSuccess)    USB_ERROR_STR(-darwin_to_errno (result), "usb_os_open(IOServiceGetMatchingServices): %s", darwin_error_str(result));  while (IOIteratorIsValid (deviceIterator) && (usbDevice = IOIteratorNext(deviceIterator))) {    /* Create an intermediate plug-in */    result = IOCreatePlugInInterfaceForService(usbDevice, kIOUSBDeviceUserClientTypeID,                                               kIOCFPlugInInterfaceID, &plugInInterface,                                               &score);    result = IOObjectRelease(usbDevice);    if (result || !plugInInterface)      continue;    (*plugInInterface)->QueryInterface(plugInInterface, CFUUIDGetUUIDBytes(DeviceInterfaceID),                                       (LPVOID)&darwin_device);    (*plugInInterface)->Stop(plugInInterface);    IODestroyPlugInInterface (plugInInterface);    plugInInterface = NULL;    if (!darwin_device)      continue;    result = (*(darwin_device))->GetLocationID(darwin_device, (UInt32 *)&dlocation);    if (dlocation == location) {      device->device = darwin_device;      break;    }    (*darwin_device)->Release(darwin_device);  }  IOObjectRelease(deviceIterator);#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;  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 claim_interface ( struct darwin_dev_handle *device, int interface )static int claim_interface ( usb_dev_handle *dev, int interface ){  io_iterator_t interface_iterator;  io_service_t  usbInterface;  struct darwin_dev_handle *device;  io_return_t result;  IOUSBFindInterfaceRequest request;  IOCFPlugInInterface **plugInInterface = NULL;  long score;  int current_interface;  device = dev->impl_info;  request.bInterfaceClass = kIOUSBFindInterfaceDontCare;  request.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;  request.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;  request.bAlternateSetting = kIOUSBFindInterfaceDontCare;  result = (*(device->device))->CreateInterfaceIterator(device->device, &request, &interface_iterator);  if (result != kIOReturnSuccess)    USB_ERROR_STR (-darwin_to_errno(result), "claim_interface(CreateInterfaceIterator): %s",		   darwin_error_str(result));  for ( current_interface=0; current_interface<=interface; current_interface++ ) {    usbInterface = IOIteratorNext(interface_iterator);    if ( usb_debug > 3 )      fprintf ( stderr, "Interface %d of device is 0x%x\n",		current_interface, (void *)usbInterface );  }  current_interface--;  /* the interface iterator is no longer needed, release it */  IOObjectRelease(interface_iterator);  if (!usbInterface) {    UInt8 nConfig;			     /* Index of configuration to use */    IOUSBConfigurationDescriptorPtr configDesc; /* to describe which configuration to select */    /* Only a composite class device with no vendor-specific driver will       be configured. Otherwise, we need to do it ourselves, or there       will be no interfaces for the device. */    if ( usb_debug > 3 )      fprintf ( stderr,"claim_interface: No interface found; selecting configuration\n" );    result = (*(device->device))->GetNumberOfConfigurations ( device->device, &nConfig );    if (result != kIOReturnSuccess)      USB_ERROR_STR(-darwin_to_errno(result), "claim_interface(GetNumberOfConfigurations): %s",		    darwin_error_str(result));        if (nConfig < 1)      USB_ERROR_STR(-ENXIO ,"claim_interface(GetNumberOfConfigurations): no configurations");    else if ( nConfig > 1 && usb_debug > 0 )      fprintf ( stderr, "claim_interface: device has more than one"		" configuration, using the first (warning)\n" );    if ( usb_debug > 3 )

⌨️ 快捷键说明

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