Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1511281
  • 博文数量: 129
  • 博客积分: 1449
  • 博客等级: 上尉
  • 技术积分: 3048
  • 用 户 组: 普通用户
  • 注册时间: 2012-07-24 18:36
文章分类

全部博文(129)

文章存档

2015年(3)

2014年(20)

2013年(65)

2012年(41)

分类: LINUX

2012-08-02 16:14:03

/install/lib/pkgconfig/libusb.pc, 内容如下:

prefix=/home/xxg/libusb-0.1.12/install
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: libusb
Description: USB access library
Version: 0.1.12
Libs: -L${libdir} -lusb

Cflags: -I${includedir}


一 libusb 介绍 

   libusb 设计了一系列的外部API 为应用程序所调用,通过这些API应用程序可以操作硬件,从libusb的源代码可以看出,这些API 调用了内核的底层接口,和kernel driver中所用到的函数所实现的功能差不多,只是libusb更加接近USB 规范。使得libusb的使用也比开发内核驱动相对容易的多。 

一些重要的数据结构:

点击(此处)折叠或打开

  1. struct usb_dev_handle {
  2.     int fd;
  3.     struct usb_bus *bus;
  4.     struct usb_device *device;
  5.     int config;
  6.     int interface;
  7.     int altsetting;
  8.     void *impl_info;
  9. };

  10. struct usb_device {
  11.     struct usb_device *next, *prev;
  12.     char filename[PATH_MAX + 1];
  13.     struct usb_bus *bus;
  14.     struct usb_device_descriptor descriptor;
  15.     struct usb_config_descriptor *config;
  16.     void *dev; /* Darwin support */
  17. };

  18. struct usb_bus {
  19.     struct usb_bus *next, *prev;
  20.     char dirname[PATH_MAX + 1];
  21.     struct usb_device *devices;
  22. };


二  libusb 的外部接口 


2.1 初始化设备接口 

这些接口也可以称为核心函数,它们主要用来初始化并寻找相关设备。 

usb_init

函数定义: void usb_init(void);

从函数名称可以看出这个函数是用来初始化相关数据的,这个函数大家只要记住必须调用就行了,而且是一开始就要调用的.

 

usb_find_busses

函数定义: int usb_find_busses(void);

寻找系统上的usb总线,任何usb设备都通过usb总线和计算机总线通信。进而和其他设备通信。此函数返回总线数。

 

usb_find_devices

函数定义: int usb_find_devices(void);

寻找总线上的usb设备,这个函数必要在调用usb_find_busses()后使用。以上的三个函数都是一开始就要用到的,此函数返回设备数量。

 

usb_get_busses

函数定义: struct usb_bus *usb_get_busses(void);

这个函数返回总线的列表,在高一些的版本中已经用不到了,这在下面的实例中会有讲解

  

2.2 操作设备接口

     usb_open

函数定义: usb_dev_handle *usb_open(struct *usb_device dev);

  打开要使用的设备,在对硬件进行操作前必须要调用usb_open 来打开设备,这里大家看到有两个结构体 usb_dev_handle 和 usb_device 是我们在开发中经常碰到的,有必要把它们的结构看一看。在libusb 中的usb.h和usbi.h中有定义。

  这里我们不妨理解为返回的 usb_dev_handle 指针是指向设备的句柄,而行参里输入就是需要打开的设备。

 

   usb_close

   函数定义: int usb_close(usb_dev_handle *dev);

   与usb_open相对应,关闭设备,是必须调用的, 返回0成功,<0 失败。

 

   usb_set_configuration

   函数定义: int usb_set_configuration(usb_dev_handle *dev, int configuration);

   设置当前设备使用的configuration,参数configuration 是你要使用的configurtation descriptoes中的bConfigurationValue, 返回0成功,<0失败( 一个设备可能包含多个configuration,比如同时支持高速和低速的设备就有对应的两个configuration,详细可查看usb标准)

 

   usb_set_altinterface

   函数定义: int usb_set_altinterface(usb_dev_handle *dev, int alternate);

   和名字的意思一样,此函数设置当前设备配置的interface descriptor,参数alternate是指interface descriptor中的bAlternateSetting。返回0成功,<0失败

 

   usb_resetep

   函数定义: int usb_resetep(usb_dev_handle *dev, unsigned int ep);

   复位指定的endpoint,参数ep 是指bEndpointAddress,。这个函数不经常用,被下面介绍的usb_clear_halt函数所替代。

 

   usb_clear_halt

   函数定义: int usb_clear_halt (usb_dev_handle *dev, unsigned int ep);

   复位指定的endpoint,参数ep 是指bEndpointAddress。这个函数用来替代usb_resetep

 

   usb_reset

   函数定义: int usb_reset(usb_dev_handle *dev);

   这个函数现在基本不怎么用,不过这里我也讲一下,和名字所起的意思一样,这个函数reset设备,因为重启设备后还是要重新打开设备,所以用usb_close就已经可以满足要求了。

 

   usb_claim_interface

   函数定义: int usb_claim_interface(usb_dev_handle *dev, int interface);

   注册与操作系统通信的接口,这个函数必须被调用,因为只有注册接口,才能做相应的操作。

Interface 指 bInterfaceNumber. (下面介绍的usb_release_interface 与之相对应,也是必须调用的函数)

 

   usb_release_interface

   函数定义: int usb_release_interface(usb_dev_handle *dev, int interface);

   注销被usb_claim_interface函数调用后的接口,释放资源,和usb_claim_interface对应使用。

 

   2.3 控制传输接口 

   usb_control_msg

   函数定义:int usb_control_msg(usb_dev_handle *dev, int requesttype, int request, int value, int index, char *bytes, int size, int timeout);

   从默认的管道发送和接受控制数据

 

   usb_get_string

   函数定义: int usb_get_string(usb_dev_handle *dev, int index, int langid, char *buf, size_t buflen);

 

   usb_get_string_simple

函数定义:  int usb_get_string_simple(usb_dev_handle *dev, int index, char *buf, size_t buflen);

  

   usb_get_descriptor

   函数定义: int usb_get_descriptor(usb_dev_handle *dev, unsigned char type, unsigned char index, void *buf, int size);

 

   usb_get_descriptor_by_endpoint

   函数定义: int usb_get_descriptor_by_endpoint(usb_dev_handle *dev, int ep, unsigned char type, unsigned char index, void *buf, int size);

  

   2.4 批传输接口 

   usb_bulk_write

   函数定义: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

 

    usb_interrupt_read

函数定义: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

  

2.5 中断传输接口

usb_bulk_write

函数定义: int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);

 

usb_interrupt_read

函数定义: int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size, int timeout);



C代码:


#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include "usb.h"

#define IDVENDOR  0x0483
#define IDPRODUCT 0xD0D0	//ST公司的CR95HF

#define DEBUGP printf

//------------------------------------------------------------------
// handles to USB ports
#define MAX_PORTNUM 16
struct usb_dev_handle* usbhnd[MAX_PORTNUM];
struct usb_device *usb_dev_list[MAX_PORTNUM];
int usb_num_devices = -1;
int g_portnum = 0;

// Initialize the USB system
static char USBInit(void)
{
	struct usb_bus *bus;
	struct usb_device *dev;

  static int USBInitDone = 0;
  int i, iret = 0;

  if (USBInitDone != 0) return 0;

	// initialize USB subsystem
	usb_init();
	usb_set_debug(0);
	usb_find_busses();
	usb_find_devices();

	for (i=0; inext) {
		for (dev = bus->devices; dev; dev = dev->next) {
			DEBUGP("%s/%s     %04X/%04X\n", bus->dirname, dev->filename,
						dev->descriptor.idVendor, dev->descriptor.idProduct);
			if (dev->descriptor.idVendor == IDVENDOR && dev->descriptor.idProduct == IDPRODUCT) {
				DEBUGP("Find device \n");

				usbhnd[g_portnum] = usb_open(dev);
				iret = 1;
				if (usbhnd[g_portnum] == NULL) {
					iret = 0;
				}
				break;
			}
		}
	}

	DEBUGP("USBInit ret = %d\n", iret);
	USBInitDone = 1 ;
	return iret;
}

void USBClose(int portnum)
{
	usb_release_interface(usbhnd[portnum], 0);
	usb_close(usbhnd[portnum]);
	usbhnd[portnum] = NULL;
}

int main(void)
{
	int iret;

	iret = USBInit();
	if (iret) {
		USBClose(g_portnum);
	}

	return 1;
}



WR703N上运行结果:

root@OpenWrt:/xutest# ./libusbtest
001/005     04FA/2490
001/002     1A40/0101
001/001     1D6B/0002
root@OpenWrt:/xutest# ./libusbtest
libusb demo begin, qiushui_007 test ok
001/005     04FA/2490
001/002     1A40/0101
001/001     1D6B/0002
USBInit ret = 0
root@OpenWrt:/xutest# ./libusbtest
libusb demo begin, qiushui_007 test ok
001/006     0483/D0D0
Find device 
USBInit ret = 1
root@OpenWrt:/xutest# ./libusbtest
Segmentation fault
root@OpenWrt:/xutest# ./libusbtest
libusb demo begin, qiushui_007 test ok
001/006     0483/D0D0
Find device 
USBInit ret = 1


另: 封装了lua的运行结果

root@OpenWrt:/xutest# lua testow.lua

 a bc d , len = 9       a bc d, len = 6
1B 4C 75 61 51 00 01 02 03 04 07 08     12
1B 4C 75 61 51 00 00 04 04 04 08 04     false   12
13      27      Lua     81      0       0       4       4       4       8       4
A1 B0 B9 12 12 B9 B0 A1 12 B9 B0 A1 
13      314159265       314159265       314159265
313233343536, crc8_hex = 0xEC
array = F1 F2 F3 F4 F5 F6 
crc8 = 0x45
owAcquireEx_DS9490: USB
001/013     04FA/2490
Find DS2490, usb_num_devices = 0
owAcquireEx_DS9490: begin --- 
owAcquireEx_DS9490: portnum = 0
read_rom = 0001804400000002
direct read rom: 0001804400000002
read_1991 = E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF 
read_1991_hex = E1E2E3E4E5E6E7E8E9EAEBECEDEEEF

root@OpenWrt:/xutest# ./luatest
--> Hello LUA, this is my first lua program for yingying!
--> 2
lua: crc8 = EC, 07
owAcquireEx_DS9490: USB
001/013     04FA/2490
Find DS2490, usb_num_devices = 0
owAcquireEx_DS9490: begin --- 
owAcquireEx_DS9490: portnum = 0
ROM 1 = 02178145000000C3
ROM 2 = 01C1C64E1400000A



1. 源码参考: libusb-0.1.12的源码中参考 linux.c, 

点击(此处)折叠或打开

  1. /*
  2.  * Linux USB support
  3.  *
  4.  * Copyright (c) 2000-2003 Johannes Erdfelt <johannes@erdfelt.com>
  5.  *
  6.  * This library is covered by the LGPL, read LICENSE for details.
  7.  */

  8. #include <stdlib.h>    /* getenv, etc */
  9. #include <unistd.h>
  10. #include <string.h>
  11. #include <stdio.h>
  12. #include <fcntl.h>
  13. #include <errno.h>
  14. #include <sys/time.h>
  15. #include <dirent.h>

  16. #include "linux.h"
  17. #include "usbi.h"

  18. static char usb_path[PATH_MAX + 1] = "";

  19. static int device_open(struct usb_device *dev)
  20. {
  21.   char filename[PATH_MAX + 1];
  22.   int fd;

  23.   snprintf(filename, sizeof(filename) - 1, "%s/%s/%s",
  24.     usb_path, dev->bus->dirname, dev->filename);

  25.   fd = open(filename, O_RDWR);
  26.   if (fd < 0) {
  27.     fd = open(filename, O_RDONLY);
  28.     if (fd < 0)
  29.       USB_ERROR_STR(-errno, "failed to open %s: %s",
  30.     filename, strerror(errno));
  31.   }

  32.   return fd;
  33. }

  34. int usb_os_open(usb_dev_handle *dev)
  35. {
  36.   dev->fd = device_open(dev->device);

  37.   return 0;
  38. }

  39. int usb_os_close(usb_dev_handle *dev)
  40. {
  41.   if (dev->fd < 0)
  42.     return 0;

  43.   if (close(dev->fd) == -1)
  44.     /* Failing trying to close a file really isn't an error, so return 0 */
  45.     USB_ERROR_STR(0, "tried to close device fd %d: %s", dev->fd,
  46.     strerror(errno));

  47.   return 0;
  48. }

  49. int usb_set_configuration(usb_dev_handle *dev, int configuration)
  50. {
  51.   int ret;

  52.   ret = ioctl(dev->fd, IOCTL_USB_SETCONFIG, &configuration);
  53.   if (ret < 0)
  54.     USB_ERROR_STR(-errno, "could not set config %d: %s", configuration,
  55.     strerror(errno));

  56.   dev->config = configuration;

  57.   return 0;
  58. }

  59. int usb_claim_interface(usb_dev_handle *dev, int interface)
  60. {
  61.   int ret;

  62.   ret = ioctl(dev->fd, IOCTL_USB_CLAIMINTF, &interface);
  63.   if (ret < 0) {
  64.     if (errno == EBUSY && usb_debug > 0)
  65.       fprintf(stderr, "Check that you have permissions to write to %s/%s and, if you don't, that you set up hotplug () correctly.\n", dev->bus->dirname, dev->device->filename);

  66.     USB_ERROR_STR(-errno, "could not claim interface %d: %s", interface,
  67.     strerror(errno));
  68.   }

  69.   dev->interface = interface;

  70.   return 0;
  71. }

  72. int usb_release_interface(usb_dev_handle *dev, int interface)
  73. {
  74.   int ret;

  75.   ret = ioctl(dev->fd, IOCTL_USB_RELEASEINTF, &interface);
  76.   if (ret < 0)
  77.     USB_ERROR_STR(-errno, "could not release intf %d: %s", interface,
  78.         strerror(errno));

  79.   dev->interface = -1;

  80.   return 0;
  81. }

  82. int usb_set_altinterface(usb_dev_handle *dev, int alternate)
  83. {
  84.   int ret;
  85.   struct usb_setinterface setintf;

  86.   if (dev->interface < 0)
  87.     USB_ERROR(-EINVAL);

  88.   setintf.interface = dev->interface;
  89.   setintf.altsetting = alternate;

  90.   ret = ioctl(dev->fd, IOCTL_USB_SETINTF, &setintf);
  91.   if (ret < 0)
  92.     USB_ERROR_STR(-errno, "could not set alt intf %d/%d: %s",
  93.     dev->interface, alternate, strerror(errno));

  94.   dev->altsetting = alternate;

  95.   return 0;
  96. }

  97. /*
  98.  * Linux usbfs has a limit of one page size for synchronous bulk read/write.
  99.  * 4096 is the most portable maximum we can do for now.
  100.  * Linux usbfs has a limit of 16KB for the URB interface. We use this now
  101.  * to get better performance for USB 2.0 devices.
  102.  */
  103. #define MAX_READ_WRITE    (16 * 1024)

  104. int usb_control_msg(usb_dev_handle *dev, int requesttype, int request,
  105.     int value, int index, char *bytes, int size, int timeout)
  106. {
  107.   struct usb_ctrltransfer ctrl;
  108.   int ret;

  109.   ctrl.bRequestType = requesttype;
  110.   ctrl.bRequest = request;
  111.   ctrl.wValue = value;
  112.   ctrl.wIndex = index;
  113.   ctrl.wLength = size;

  114.   ctrl.data = bytes;
  115.   ctrl.timeout = timeout;

  116.   ret = ioctl(dev->fd, IOCTL_USB_CONTROL, &ctrl);
  117.   if (ret < 0)
  118.     USB_ERROR_STR(-errno, "error sending control message: %s", strerror(errno));

  119.   return ret;
  120. }

  121. #define URB_USERCONTEXT_COOKIE        ((void *)0x1)

  122. /* Reading and writing are the same except for the endpoint */
  123. static int usb_urb_transfer(usb_dev_handle *dev, int ep, int urbtype,
  124.     char *bytes, int size, int timeout)
  125. {
  126.   struct usb_urb urb;
  127.   int bytesdone = 0, requested;
  128.   struct timeval tv, tv_ref, tv_now;
  129.   struct usb_urb *context;
  130.   int ret, waiting;

  131.   /*
  132.    * HACK: The use of urb.usercontext is a hack to get threaded applications
  133.    * sort of working again. Threaded support is still not recommended, but
  134.    * this should allow applications to work in the common cases. Basically,
  135.    * if we get the completion for an URB we're not waiting for, then we update
  136.    * the usercontext pointer to 1 for the other threads URB and it will see
  137.    * the change after it wakes up from the the timeout. Ugly, but it works.
  138.    */

  139.   /*
  140.    * Get actual time, and add the timeout value. The result is the absolute
  141.    * time where we have to quit waiting for an message.
  142.    */
  143.   gettimeofday(&tv_ref, NULL);
  144.   tv_ref.tv_sec = tv_ref.tv_sec + timeout / 1000;
  145.   tv_ref.tv_usec = tv_ref.tv_usec + (timeout % 1000) * 1000;

  146.   if (tv_ref.tv_usec > 1000000) {
  147.     tv_ref.tv_usec -= 1000000;
  148.     tv_ref.tv_sec++;
  149.   }

  150.   do {
  151.     fd_set writefds;

  152.     requested = size - bytesdone;
  153.     if (requested > MAX_READ_WRITE)
  154.       requested = MAX_READ_WRITE;

  155.     urb.type = urbtype;
  156.     urb.endpoint = ep;
  157.     urb.flags = 0;
  158.     urb.buffer = bytes + bytesdone;
  159.     urb.buffer_length = requested;
  160.     urb.signr = 0;
  161.     urb.actual_length = 0;
  162.     urb.number_of_packets = 0;    /* don't do isochronous yet */
  163.     urb.usercontext = NULL;

  164.     ret = ioctl(dev->fd, IOCTL_USB_SUBMITURB, &urb);
  165.     if (ret < 0) {
  166.       USB_ERROR_STR(-errno, "error submitting URB: %s", strerror(errno));
  167.       return ret;
  168.     }

  169.     FD_ZERO(&writefds);
  170.     FD_SET(dev->fd, &writefds);

  171. restart:
  172.     waiting = 1;
  173.     context = NULL;
  174.     while (!urb.usercontext && ((ret = ioctl(dev->fd, IOCTL_USB_REAPURBNDELAY, &context)) == -1) && waiting) {
  175.       tv.tv_sec = 0;
  176.       tv.tv_usec = 1000; // 1 msec
  177.       select(dev->fd + 1, NULL, &writefds, NULL, &tv); //sub second wait

  178.       if (timeout) {
  179.         /* compare with actual time, as the select timeout is not that precise */
  180.         gettimeofday(&tv_now, NULL);

  181.         if ((tv_now.tv_sec > tv_ref.tv_sec) ||
  182.             ((tv_now.tv_sec == tv_ref.tv_sec) && (tv_now.tv_usec >= tv_ref.tv_usec)))
  183.           waiting = 0;
  184.       }
  185.     }

  186.     if (context && context != &urb) {
  187.       context->usercontext = URB_USERCONTEXT_COOKIE;
  188.       /* We need to restart since we got a successful URB, but not ours */
  189.       goto restart;
  190.     }

  191.     /*
  192.      * If there was an error, that wasn't EAGAIN (no completion), then
  193.      * something happened during the reaping and we should return that
  194.      * error now
  195.      */
  196.     if (ret < 0 && !urb.usercontext && errno != EAGAIN)
  197.       USB_ERROR_STR(-errno, "error reaping URB: %s", strerror(errno));

  198.     bytesdone += urb.actual_length;
  199.   } while ((ret == 0 || urb.usercontext) && bytesdone < size && urb.actual_length == requested);

  200.   /* If the URB didn't complete in success or error, then let's unlink it */
  201.   if (ret < 0 && !urb.usercontext) {
  202.     int rc;

  203.     if (!waiting)
  204.       rc = -ETIMEDOUT;
  205.     else
  206.       rc = urb.status;

  207.     ret = ioctl(dev->fd, IOCTL_USB_DISCARDURB, &urb);
  208.     if (ret < 0 && errno != EINVAL && usb_debug >= 1)
  209.       fprintf(stderr, "error discarding URB: %s", strerror(errno));

  210.     /*
  211.      * When the URB is unlinked, it gets moved to the completed list and
  212.      * then we need to reap it or else the next time we call this function,
  213.      * we'll get the previous completion and exit early
  214.      */
  215.     ioctl(dev->fd, IOCTL_USB_REAPURB, &context);

  216.     return rc;
  217.   }

  218.   return bytesdone;
  219. }

  220. int usb_bulk_write(usb_dev_handle *dev, int ep, char *bytes, int size,
  221.     int timeout)
  222. {
  223.   /* Ensure the endpoint address is correct */
  224.   return usb_urb_transfer(dev, ep, USB_URB_TYPE_BULK, bytes, size,
  225.         timeout);
  226. }

  227. int usb_bulk_read(usb_dev_handle *dev, int ep, char *bytes, int size,
  228.     int timeout)
  229. {
  230.   /* Ensure the endpoint address is correct */
  231.   ep |= USB_ENDPOINT_IN;
  232.   return usb_urb_transfer(dev, ep, USB_URB_TYPE_BULK, bytes, size,
  233.         timeout);
  234. }

  235. /*
  236.  * FIXME: Packetize large buffers here. 2.4 HCDs (atleast, haven't checked
  237.  * 2.5 HCDs yet) don't handle multi-packet Interrupt transfers. So we need
  238.  * to lookup the endpoint packet size and packetize appropriately here.
  239.  */
  240. int usb_interrupt_write(usb_dev_handle *dev, int ep, char *bytes, int size,
  241.     int timeout)
  242. {
  243.   /* Ensure the endpoint address is correct */
  244.   return usb_urb_transfer(dev, ep, USB_URB_TYPE_INTERRUPT, bytes, size,
  245.         timeout);
  246. }

  247. int usb_interrupt_read(usb_dev_handle *dev, int ep, char *bytes, int size,
  248.     int timeout)
  249. {
  250.   /* Ensure the endpoint address is correct */
  251.   ep |= USB_ENDPOINT_IN;
  252.   return usb_urb_transfer(dev, ep, USB_URB_TYPE_INTERRUPT, bytes, size,
  253.         timeout);
  254. }

  255. int usb_os_find_busses(struct usb_bus **busses)
  256. {
  257.   struct usb_bus *fbus = NULL;
  258.   DIR *dir;
  259.   struct dirent *entry;

  260.   dir = opendir(usb_path);
  261.   if (!dir)
  262.     USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", usb_path,
  263.     strerror(errno));

  264.   while ((entry = readdir(dir)) != NULL) {
  265.     struct usb_bus *bus;

  266.     /* Skip anything starting with a . */
  267.     if (entry->d_name[0] == '.')
  268.       continue;

  269.     if (!strchr("0123456789", entry->d_name[strlen(entry->d_name) - 1])) {
  270.       if (usb_debug >= 2)
  271.         fprintf(stderr, "usb_os_find_busses: Skipping non bus directory %s\n",
  272.         entry->d_name);
  273.       continue;
  274.     }

  275.     bus = malloc(sizeof(*bus));
  276.     if (!bus)
  277.       USB_ERROR(-ENOMEM);

  278.     memset((void *)bus, 0, sizeof(*bus));

  279.     strncpy(bus->dirname, entry->d_name, sizeof(bus->dirname) - 1);
  280.     bus->dirname[sizeof(bus->dirname) - 1] = 0;

  281.     LIST_ADD(fbus, bus);

  282.     if (usb_debug >= 2)
  283.        fprintf(stderr, "usb_os_find_busses: Found %s\n", bus->dirname);
  284.   }

  285.   closedir(dir);

  286.   *busses = fbus;

  287.   return 0;
  288. }

  289. int usb_os_find_devices(struct usb_bus *bus, struct usb_device **devices)
  290. {
  291.   struct usb_device *fdev = NULL;
  292.   DIR *dir;
  293.   struct dirent *entry;
  294.   char dirpath[PATH_MAX + 1];

  295.   snprintf(dirpath, PATH_MAX, "%s/%s", usb_path, bus->dirname);

  296.   dir = opendir(dirpath);
  297.   if (!dir)
  298.     USB_ERROR_STR(-errno, "couldn't opendir(%s): %s", dirpath,
  299.     strerror(errno));

  300.   while ((entry = readdir(dir)) != NULL) {
  301.     unsigned char device_desc[DEVICE_DESC_LENGTH];
  302.     char filename[PATH_MAX + 1];
  303.     struct usb_device *dev;
  304.     struct usb_connectinfo connectinfo;
  305.     int i, fd, ret;

  306.     /* Skip anything starting with a . */
  307.     if (entry->d_name[0] == '.')
  308.       continue;

  309.     dev = malloc(sizeof(*dev));
  310.     if (!dev)
  311.       USB_ERROR(-ENOMEM);

  312.     memset((void *)dev, 0, sizeof(*dev));

  313.     dev->bus = bus;

  314.     strncpy(dev->filename, entry->d_name, sizeof(dev->filename) - 1);
  315.     dev->filename[sizeof(dev->filename) - 1] = 0;

  316.     snprintf(filename, sizeof(filename) - 1, "%s/%s", dirpath, entry->d_name);
  317.     fd = open(filename, O_RDWR);
  318.     if (fd < 0) {
  319.       fd = open(filename, O_RDONLY);
  320.       if (fd < 0) {
  321.         if (usb_debug >= 2)
  322.           fprintf(stderr, "usb_os_find_devices: Couldn't open %s\n",
  323.                   filename);

  324.         free(dev);
  325.         continue;
  326.       }
  327.     }

  328.     /* Get the device number */
  329.     ret = ioctl(fd, IOCTL_USB_CONNECTINFO, &connectinfo);
  330.     if (ret < 0) {
  331.       if (usb_debug)
  332.         fprintf(stderr, "usb_os_find_devices: couldn't get connect info\n");
  333.     } else
  334.       dev->devnum = connectinfo.devnum;

  335.     ret = read(fd, (void *)device_desc, DEVICE_DESC_LENGTH);
  336.     if (ret < 0) {
  337.       if (usb_debug)
  338.         fprintf(stderr, "usb_os_find_devices: Couldn't read descriptor\n");

  339.       free(dev);

  340.       goto err;
  341.     }

  342.     /*
  343.      * Linux kernel converts the words in this descriptor to CPU endian, so
  344.      * we use the undocumented W character for usb_parse_descriptor() that
  345.      * doesn't convert endianess when parsing the descriptor
  346.      */
  347.     usb_parse_descriptor(device_desc, "bbWbbbbWWWbbbb", &dev->descriptor);

  348.     LIST_ADD(fdev, dev);

  349.     if (usb_debug >= 2)
  350.       fprintf(stderr, "usb_os_find_devices: Found %s on %s\n",
  351.         dev->filename, bus->dirname);

  352.     /* Now try to fetch the rest of the descriptors */
  353.     if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG)
  354.       /* Silent since we'll try again later */
  355.       goto err;

  356.     if (dev->descriptor.bNumConfigurations < 1)
  357.       /* Silent since we'll try again later */
  358.       goto err;

  359.     dev->config = (struct usb_config_descriptor *)malloc(dev->descriptor.bNumConfigurations * sizeof(struct usb_config_descriptor));
  360.     if (!dev->config)
  361.       /* Silent since we'll try again later */
  362.       goto err;

  363.     memset(dev->config, 0, dev->descriptor.bNumConfigurations *
  364.           sizeof(struct usb_config_descriptor));

  365.     for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
  366.       unsigned char buffer[8], *bigbuffer;
  367.       struct usb_config_descriptor config;

  368.       /* Get the first 8 bytes so we can figure out what the total length is */
  369.       ret = read(fd, (void *)buffer, 8);
  370.       if (ret < 8) {
  371.         if (usb_debug >= 1) {
  372.           if (ret < 0)
  373.             fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
  374.           else
  375.             fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", 8, ret);
  376.         }

  377.         goto err;
  378.       }

  379.       usb_parse_descriptor(buffer, "bbw", &config);

  380.       bigbuffer = malloc(config.wTotalLength);
  381.       if (!bigbuffer) {
  382.         if (usb_debug >= 1)
  383.           fprintf(stderr, "Unable to allocate memory for descriptors\n");
  384.         goto err;
  385.       }

  386.       /* Read the rest of the config descriptor */
  387.       memcpy(bigbuffer, buffer, 8);

  388.       ret = read(fd, (void *)(bigbuffer + 8), config.wTotalLength - 8);
  389.       if (ret < config.wTotalLength - 8) {
  390.         if (usb_debug >= 1) {
  391.           if (ret < 0)
  392.             fprintf(stderr, "Unable to get descriptor (%d)\n", ret);
  393.           else
  394.             fprintf(stderr, "Config descriptor too short (expected %d, got %d)\n", config.wTotalLength, ret);
  395.         }

  396.         free(bigbuffer);
  397.         goto err;
  398.       }

  399.       ret = usb_parse_configuration(&dev->config[i], bigbuffer);
  400.       if (usb_debug >= 2) {
  401.         if (ret > 0)
  402.           fprintf(stderr, "Descriptor data still left\n");
  403.         else if (ret < 0)
  404.           fprintf(stderr, "Unable to parse descriptors\n");
  405.       }

  406.       free(bigbuffer);
  407.     }

  408. err:
  409.     close(fd);
  410.   }

  411.   closedir(dir);

  412.   *devices = fdev;

  413.   return 0;
  414. }

  415. int usb_os_determine_children(struct usb_bus *bus)
  416. {
  417.   struct usb_device *dev, *devices[256];
  418.   struct usb_ioctl command;
  419.   int ret, i, i1;

  420.   /* Create a list of devices first */
  421.   memset(devices, 0, sizeof(devices));
  422.   for (dev = bus->devices; dev; dev = dev->next)
  423.     if (dev->devnum)
  424.       devices[dev->devnum] = dev;

  425.   /* Now fetch the children for each device */
  426.   for (dev = bus->devices; dev; dev = dev->next) {
  427.     struct usb_hub_portinfo portinfo;
  428.     int fd;

  429.     fd = device_open(dev);
  430.     if (fd < 0)
  431.       continue;

  432.     /* Query the hub driver for the children of this device */
  433.     if (dev->config && dev->config->interface && dev->config->interface->altsetting)
  434.       command.ifno = dev->config->interface->altsetting->bInterfaceNumber;
  435.     else
  436.       command.ifno = 0;
  437.     command.ioctl_code = IOCTL_USB_HUB_PORTINFO;
  438.     command.data = &portinfo;
  439.     ret = ioctl(fd, IOCTL_USB_IOCTL, &command);
  440.     if (ret < 0) {
  441.       /* errno == ENOSYS means the device probably wasn't a hub */
  442.       if (errno != ENOSYS && usb_debug > 1)
  443.         fprintf(stderr, "error obtaining child information: %s\n",
  444.         strerror(errno));

  445.       close(fd);
  446.       continue;
  447.     }

  448.     dev->num_children = 0;
  449.     for (i = 0; i < portinfo.numports; i++)
  450.       if (portinfo.port[i])
  451.         dev->num_children++;

  452.     /* Free any old children first */
  453.     free(dev->children);

  454.     dev->children = malloc(sizeof(struct usb_device *) * dev->num_children);
  455.     if (!dev->children) {
  456.       if (usb_debug > 1)
  457.         fprintf(stderr, "error allocating %zu bytes memory for dev->children\n",
  458.                 sizeof(struct usb_device *) * dev->num_children);

  459.       dev->num_children = 0;
  460.       close(fd);
  461.       continue;
  462.     }

  463.     for (i = 0, i1 = 0; i < portinfo.numports; i++) {
  464.       if (!portinfo.port[i])
  465.         continue;

  466.       dev->children[i1++] = devices[portinfo.port[i]];

  467.       devices[portinfo.port[i]] = NULL;
  468.     }

  469.     close(fd);
  470.   }

  471.   /*
  472.    * There should be one device left in the devices list and that should be
  473.    * the root device
  474.    */
  475.   for (i = 0; i < sizeof(devices) / sizeof(devices[0]); i++) {
  476.     if (devices[i])
  477.       bus->root_dev = devices[i];
  478.   }

  479.   return 0;
  480. }

  481. static int check_usb_vfs(const char *dirname)
  482. {
  483.   DIR *dir;
  484.   struct dirent *entry;
  485.   int found = 0;

  486.   dir = opendir(dirname);
  487.   if (!dir)
  488.     return 0;

  489.   while ((entry = readdir(dir)) != NULL) {
  490.     /* Skip anything starting with a . */
  491.     if (entry->d_name[0] == '.')
  492.       continue;

  493.     /* We assume if we find any files that it must be the right place */
  494.     found = 1;
  495.     break;
  496.   }

  497.   closedir(dir);

  498.   return found;
  499. }

  500. void usb_os_init(void)
  501. {
  502.   /* Find the path to the virtual filesystem */
  503.   if (getenv("USB_DEVFS_PATH")) {
  504.     if (check_usb_vfs(getenv("USB_DEVFS_PATH"))) {
  505.       strncpy(usb_path, getenv("USB_DEVFS_PATH"), sizeof(usb_path) - 1);
  506.       usb_path[sizeof(usb_path) - 1] = 0;
  507.     } else if (usb_debug)
  508.       fprintf(stderr, "usb_os_init: couldn't find USB VFS in USB_DEVFS_PATH\n");
  509.   }

  510.   if (!usb_path[0]) {
  511.     if (check_usb_vfs("/dev/bus/usb")) {
  512.       strncpy(usb_path, "/dev/bus/usb", sizeof(usb_path) - 1);
  513.       usb_path[sizeof(usb_path) - 1] = 0;
  514.     } else if (check_usb_vfs("/proc/bus/usb")) {
  515.       strncpy(usb_path, "/proc/bus/usb", sizeof(usb_path) - 1);
  516.       usb_path[sizeof(usb_path) - 1] = 0;
  517.     } else
  518.       usb_path[0] = 0;    /* No path, no USB support */
  519.   }

  520.   if (usb_debug) {
  521.     if (usb_path[0])
  522.       fprintf(stderr, "usb_os_init: Found USB VFS at %s\n", usb_path);
  523.     else
  524.       fprintf(stderr, "usb_os_init: No USB VFS found, is it mounted?\n");
  525.   }
  526. }

  527. int usb_resetep(usb_dev_handle *dev, unsigned int ep)
  528. {
  529.   int ret;

  530.   ret = ioctl(dev->fd, IOCTL_USB_RESETEP, &ep);
  531.   if (ret)
  532.     USB_ERROR_STR(-errno, "could not reset ep %d: %s", ep,
  533.         strerror(errno));

  534.   return 0;
  535. }

  536. int usb_clear_halt(usb_dev_handle *dev, unsigned int ep)
  537. {
  538.   int ret;

  539.   ret = ioctl(dev->fd, IOCTL_USB_CLEAR_HALT, &ep);
  540.   if (ret)
  541.     USB_ERROR_STR(-errno, "could not clear/halt ep %d: %s", ep,
  542.         strerror(errno));

  543.   return 0;
  544. }

  545. int usb_reset(usb_dev_handle *dev)
  546. {
  547.   int ret;

  548.   ret = ioctl(dev->fd, IOCTL_USB_RESET, NULL);
  549.   if (ret)
  550.      USB_ERROR_STR(-errno, "could not reset: %s", strerror(errno));

  551.   return 0;
  552. }

  553. int usb_get_driver_np(usb_dev_handle *dev, int interface, char *name,
  554.     unsigned int namelen)
  555. {
  556.   struct usb_getdriver getdrv;
  557.   int ret;

  558.   getdrv.interface = interface;
  559.   ret = ioctl(dev->fd, IOCTL_USB_GETDRIVER, &getdrv);
  560.   if (ret)
  561.     USB_ERROR_STR(-errno, "could not get bound driver: %s", strerror(errno));

  562.   strncpy(name, getdrv.driver, namelen - 1);
  563.   name[namelen - 1] = 0;

  564.   return 0;
  565. }

  566. int usb_detach_kernel_driver_np(usb_dev_handle *dev, int interface)
  567. {
  568.   struct usb_ioctl command;
  569.   int ret;

  570.   command.ifno = interface;
  571.   command.ioctl_code = IOCTL_USB_DISCONNECT;
  572.   command.data = NULL;

  573.   ret = ioctl(dev->fd, IOCTL_USB_IOCTL, &command);
  574.   if (ret)
  575.     USB_ERROR_STR(-errno, "could not detach kernel driver from interface %d: %s",
  576.         interface, strerror(errno));

  577.   return 0;
  578. }

2. 
阅读(6121) | 评论(2) | 转发(0) |
0

上一篇:大小端(自己整理备用)

下一篇:curl 集锦

给主人留下些什么吧!~~

qiushui_0072012-08-06 08:52:35

txgc_wm: 写得简单了点哦!.....
刚开始的呀

txgc_wm2012-08-03 08:54:24

写得简单了点哦!