<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > Linux USB gadget設(shè)備驅(qū)動(dòng)解析(4)--編寫一個(gè)gadget驅(qū)動(dòng)

          Linux USB gadget設(shè)備驅(qū)動(dòng)解析(4)--編寫一個(gè)gadget驅(qū)動(dòng)

          作者: 時(shí)間:2012-08-06 來源:網(wǎng)絡(luò) 收藏

          .bmAttributes = _ENDPOINT_XFER_BULK,

          };

          static struct usb_config_descriptor loopback_config = { //配置描述符

          .bLength = sizeof loopback_config,

          .bDescriptorType = _DT_CONFIG,

          /* compute wTotalLength on the fly */

          .bNumInterfaces = 1,

          .bConfigurationValue = CONFIG_LOOPBACK,

          .iConfiguration = STRING_LOOPBACK,

          .bmAttributes = _CONFIG_ATT_ONE | USB_CONFIG_ATT_SELFpower,

          .bMaxPower = 1, /* self-powered */

          };

          static const struct usb_interface_descriptor loopback_intf = { //接口描述符

          .bLength = sizeof loopback_intf,

          .bDescriptorType = USB_DT_INTERFACE,

          .bNumEndpoints = 1,

          .bInterfaceClass = USB_CLASS_VENDOR_SPEC,

          .iInterface = STRING_LOOPBACK,

          };

          /* static strings, in UTF-8 */

          #define STRING_MANUFACTURER 25

          #define STRING_PRODUCT 42

          #define STRING_SERIAL 101

          #define STRING_SOURCE_SINK 250

          #define STRING_LOOPBACK 251

          static char manufacturer[50];

          /* default serial number takes at least two packets */

          static char serial[] = 0123456789.0123456789.0123456789;

          static struct usb_string strings[] = { //字符串描述符

          { STRING_MANUFACTURER, manufacturer, },

          { STRING_PRODUCT, longname, },

          { STRING_SERIAL, serial, },

          { STRING_LOOPBACK, loopback, },

          { STRING_SOURCE_SINK, source_sink, },

          { } /* end of list */

          };

          static struct usb__strings stringtab = {

          .language = 0x0409, /* en-us */

          .strings = strings,

          };

          static const struct usb_descriptor_header *fs_loopback_function[] = {

          (struct usb_descriptor_header *) loopback_intf,

          (struct usb_descriptor_header *) fs_sink_desc,

          NULL,

          };

          static int

          usb_zero_open (struct inode *inode, struct file *file) //打開設(shè)備

          {

          struct zero_dev *dev =

          container_of (inode->i_cdev, struct zero_dev, cdev);

          file->private_data = dev;

          init_waitqueue_head (dev->bulkrq);

          return 0;

          }

          static int

          usb_zero_release (struct inode *inode, struct file *file) //關(guān)閉設(shè)備

          {

          return 0;

          }

          static void free_ep_req(struct usb_ep *ep, struct usb_request *req)

          {

          kfree(req->buf);

          usb_ep_free_request(ep, req);

          }

          static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)//分配請(qǐng)求

          {

          struct usb_request *req;

          req = usb_ep_alloc_request(ep, GFP_ATOMIC);

          if (req) {

          req->length = length;

          req->buf = kmalloc(length, GFP_ATOMIC);

          if (!req->buf) {

          usb_ep_free_request(ep, req);

          req = NULL;

          }

          }

          return req;

          }

          static void source_sink_complete(struct usb_ep *ep, struct usb_request *req)//請(qǐng)求完成函數(shù)

          {

          struct zero_dev *dev = ep->driver_data;

          int status = req->status;

          switch (status) {

          case 0: /* normal completion */

          if (ep == dev->out_ep) {

          memcpy(dev->data, req->buf, req-> actual);//返回?cái)?shù)據(jù)拷貝到req->buf中, //dev->data_size=req->length;

          dev->data_size=req->actual; //實(shí)際長度為req-> actual;需要確認(rèn)

          req –>short_not_ok為0。參考.h中關(guān)于usb_request結(jié)構(gòu)的注釋

          }

          break;

          /* this endpoint is normally active while we're configured */

          case -ECONNABORTED: /* hardware forced ep reset */

          case -ECONNRESET: /* request dequeued */

          case -ESHUTDOWN: /* disconnect from host */

          printk(%s gone (%d), %d/%dn, ep->name, status,

          req->actual, req->length);

          case -EOVERFLOW: /* buffer overrun on read means that

          * we didn't provide a big enough

          * buffer.

          */

          default:

          #if 1

          printk(%s complete --> %d, %d/%dn, ep->name,

          status, req->actual, req->length);

          #endif

          case -EREMOTEIO: /* short read */

          break;

          }

          free_ep_req(ep, req);

          wake_up_interruptible (dev->bulkrq); //喚醒讀函數(shù)

          }

          static struct usb_request *source_sink_start_ep(struct usb_ep *ep)//構(gòu)造并發(fā)送讀請(qǐng)求

          {

          struct usb_request *req;

          int status;

          //printk(in %sn,__FUNCTION__);

          req = alloc_ep_req(ep, 128);

          if (!req)

          return NULL;

          memset(req->buf, 0, req->length);

          req->complete = source_sink_complete; //請(qǐng)求完成函數(shù)

          status = usb_ep_queue(ep, req, GFP_ATOMIC); //遞交請(qǐng)求

          if (status) {

          struct zero_dev *dev = ep->driver_data;

          printk(start %s --> %dn, ep->name, status);

          free_ep_req(ep, req);

          req = NULL;

          }

          linux操作系統(tǒng)文章專題:linux操作系統(tǒng)詳解(linux不再難懂)

          linux相關(guān)文章:linux教程




          評(píng)論


          相關(guān)推薦

          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();