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

📄 btusb.c

📁 牛人写的一个蓝牙驱动教学程序
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* * PURPOSE *  Function registered as CLOSE file operation function for btusb device. *  It stops all communication witht he device and cleans up *  btusb_t structure associated with the device. * * PARAMETERS TO THE FUNCTION *  TYPE    VARIABLE  DESCRIPTION *  inode*  inode_p   Inode struct corresponding to btusb device. *  file*   file_p    Valid file structure of btusb device. * * RETURN VALUE *  VALUE    DESCRIPTION *  SUCCESS  If closing the device was successful. *  ERROR    If error in closing the device. * * GLOBAL PARAMETERS MODIFIED BY THE FUNCTION *  None. */static intbtusb_close(struct inode  *inode_p,            struct file   *file_p){  btusb_t *devStruct = NULL;  unsigned long flags;#ifdef BTUSB_DEBUG  btusb_display_string("close - Closing device file", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  /* if btusb_t struct for minor number is not found, return ERROR */  devStruct = (btusb_t *)file_p->private_data;  if (devStruct == NULL)  {#ifdef BTUSB_DEBUG    btusb_display_string("close - Error! Invalid file descriptor",                         DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  if (btusb_devInfo_g[devStruct->minorNumber] != devStruct)  {#ifdef BTUSB_DEBUG    btusb_display_string("close - Error! devStruct mismatch", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* if device is not opened, return ERROR */  if (devStruct->devOpened == FALSE)  {#ifdef BTUSB_DEBUG    btusb_display_string("close - Device already closed", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return SUCCESS;  }#ifdef BTUSB_DEBUG  btusb_display_string("close - DEvice is open. Need to close", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  /* Lock the btusb_t struct, reset devOpened flag and unlock it */  BTUSB_RESOURCE_WAIT_FOR_UNLOCK(&devStruct->lock);  BTUSB_RESOURCE_LOCK(&devStruct->lock, flags);  devStruct->devOpened = FALSE;  devStruct->devFile->private_data = NULL;  devStruct->devFile = NULL;  BTUSB_RESOURCE_UNLOCK(&devStruct->lock, flags);#ifdef BTUSB_DEBUG  btusb_display_string("close - Unlinking submitted URBs", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  /* Unlink all the submitted URBs of this device */  btusb_unlink_urbs(devStruct);#ifdef BTUSB_DEBUG  btusb_display_string("close - Cleaning up receive data queue", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  /* Clean up the receive-data_queue and reset its parameters to defaults */  btusb_cleanup_queue(&devStruct->recvQueue);#ifdef BTUSB_DEBUG  btusb_display_string("close - Device closed", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  return SUCCESS;}/* * PURPOSE *  Function registered as IOCTL file operation function for btusb device. *  Currently it supports a single command to set max-queue-length of a *  receive-data-queue. Command is 0x01. * * PARAMETERS TO THE FUNCTION *  TYPE           VARIABLE  DESCRIPTION *  inode*         inode_p   Inode struct corresponding to btusb device. *  file*          file_p    Valid file structure of btusb device. *  unsigned int   cmd       ioctl command. 0x01 for set max queue length. *  unsigned long  arg       Argument of command. * * RETURN VALUE *  VALUE    DESCRIPTION *  SUCCESS  If command was successful. *  ERROR    If command failed. * * GLOBAL PARAMETERS MODIFIED BY THE FUNCTION *  None. */static intbtusb_ioctl(struct inode   *inode_p,            struct file    *file_p,            unsigned int   cmd,            unsigned long  arg){  btusb_t *devStruct = NULL;  unsigned long flags;  int retVal = ERROR;  /* Get devStruct from file_p. If NULL, return ERROR */  devStruct = (btusb_t *)file_p->private_data;  if (devStruct == NULL)  {#ifdef BTUSB_DEBUG    btusb_display_string("ioctl - Command failed", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* If device is not opened, return ERROR */  if (devStruct->devOpened == FALSE)  {#ifdef BTUSB_DEBUG    btusb_display_string("ioctl - Command failed", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  switch(cmd)  {  case 0x01: /* set max queue length command */    /*     * Update max-queue-length only if value is within     * MAX_PENDING_IN_URBS to 255     */    if ((arg >= MAX_PENDING_IN_URBS) && (arg < 256))    {      BTUSB_RESOURCE_WAIT_FOR_UNLOCK(&devStruct->lock);      BTUSB_RESOURCE_LOCK(&devStruct->lock, flags);      devStruct->recvQueue.maxLength = arg;      BTUSB_RESOURCE_UNLOCK(&devStruct->lock, flags);      retVal = SUCCESS;    }    break;  default:    /* Return error if command is not supported */    retVal = ERROR;    break;  }  if (retVal == ERROR)  {#ifdef BTUSB_DEBUG    btusb_display_string("ioctl - Command failed", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  }  else  {#ifdef BTUSB_DEBUG    btusb_display_string("ioctl - Command success", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  }  return retVal;} /* End of btusb_ioctl *//* * PURPOSE *  Function registered as READ file operation function for btusb device. *  If device is opened for communication, it returns a data chunk got *  from device specific receive-data-queue. *  This function also takes care of re-submitting IN URBs where were *  not submitted. * * PARAMETERS TO THE FUNCTION *  TYPE     VARIABLE  DESCRIPTION *  file*    file_p    Valid file structure. *  char*    buf_p     user buffer to hold received data. *  size_t   count     Length of data to be read. Always MAX_BT_PKT_SIZE. *  loff_t*  pos_p     Offset. Always ignored. * * RETURN VALUE *  VALUE           DESCRIPTION *  Actual length   Length of data chunk including type if data is being *                  returned. *  NO_DATA         If device receive-data-queue was empty. *  ERROR           If device does not exist. * * GLOBAL PARAMETERS MODIFIED BY THE FUNCTION *  None. */static ssize_tbtusb_read(struct file  *file_p,           char         *buf_p,           size_t       count,           loff_t       *pos_p){  btusb_t *devStruct = NULL;  unsigned long flags;  node_t  *nodeFromQueue = NULL;  int16 spaceInQueue = 0;  urb_t   *tempUrb = NULL;  uint8   *transferBuf = NULL;  unsigned int numOfIsoPkts = 0;  unsigned int i;  ssize_t retVal = ERROR;  bool  bulkInUrbSubmitted = FALSE;  bool  isoInUrbSubmitted = FALSE;  bool  intInUrbSubmitted = FALSE;  int status;  /* Get devStruct from file_p.If NULL, return ERROR*/  devStruct = (btusb_t *)file_p->private_data;  if (devStruct == NULL)  {#ifdef BTUSB_DEBUG    btusb_display_string("read - Device error", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* If device is not opened, return ERROR */  if (devStruct->devOpened == FALSE)  {#ifdef BTUSB_DEBUG    btusb_display_string("read - Device error", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* If requested data length is not MAX_BT_PKT_SIZE, return ERROR */  if (count != MAX_BT_PKT_SIZE)  {#ifdef BTUSB_DEBUG    btusb_display_string("read - Request data length is not MAX_BT_PKT_SIZE",                         DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* Lock the btusb_t struct, get a node from its receive-data-queue     and unlock it */  BTUSB_RESOURCE_WAIT_FOR_UNLOCK(&devStruct->lock);  BTUSB_RESOURCE_LOCK(&devStruct->lock, flags);  nodeFromQueue = btusb_getNodeFromQueue(&devStruct->recvQueue);  spaceInQueue =    devStruct->recvQueue.maxLength - devStruct->recvQueue.currentLength;  BTUSB_RESOURCE_UNLOCK(&devStruct->lock, flags);  /* If node from queue was not NULL, copy type and data to user buffer */  if (nodeFromQueue != NULL)  {    switch (nodeFromQueue->type)    {    case INTERRUPT_TYPE:      *buf_p = EVENT_TYPE;      break;    case BULK_TYPE:      *buf_p = ACL_TYPE;      break;    case ISO_TYPE:      *buf_p = SCO_TYPE;      break;    default:      *buf_p = EVENT_TYPE;      break;    }    copy_to_user((buf_p+1),nodeFromQueue->buf,nodeFromQueue->length);    /* set return value to length of data along with type being returned */    retVal = nodeFromQueue->length + 1;    BTUSB_MEM_FREE(nodeFromQueue);    nodeFromQueue=NULL;#ifdef BTUSB_DEBUG    btusb_display_string("read - Got data", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  }  else  {    /* set retrun value to NO_DATA */    retVal = NO_DATA;#ifdef BTUSB_DEBUG    btusb_display_string("Read - No data", DBG_FILEOPS);#endif /* BTUSB_DEBUG */  }  /*   * if space in queue >= MAX_PENDING_IN_URBS, submit IN URBs which were   * not submitted   */  if (spaceInQueue >= MAX_PENDING_IN_URBS)  {    /* Submit interrupt-in URB if it was not submitted */    if (devStruct->interrupt_in_urbSubmitted == FALSE)    {      tempUrb = devStruct->interrupt_in_urb;      /* Allocate transfer buffer if it was not allocated */      if (tempUrb->transfer_buffer == NULL)      {        transferBuf = BTUSB_MEM_ALLOC((sizeof(node_t) + MAX_BT_PKT_SIZE));        if (transferBuf != NULL)        {          tempUrb->transfer_buffer = transferBuf + sizeof(node_t);        }      }      /*       * If transfer buffer exists, submit URB. Set URB submitted flag on       * success       */      if (tempUrb->transfer_buffer != NULL)      {        if (BTUSB_SUBMIT_URB(tempUrb) == SUCCESS)        {          intInUrbSubmitted = TRUE;        }#ifdef BTUSB_DEBUG    btusb_display_string("submit interrupt URB", DBG_FILEOPS);#endif /* BTUSB_DEBUG */      }    }      /* Submit bulk-in URB if it was not submitted */#ifdef MULTIPLE_BULK_IN_URBS    if ((devStruct->bulk_in_urbSubmitted == FALSE) ||        (devStruct->pending_bulk_in_urbs < MAX_PENDING_BULK_IN_URBS))    {      /* To hold the URB available */      int nURBAvailable = MAX_PENDING_BULK_IN_URBS;            /* Locate the URB which is available */      for (i = 0; i < MAX_PENDING_BULK_IN_URBS; i++)      {        if (devStruct->bulk_in_urb_submitted[i] == FALSE)        {          nURBAvailable = i;                }      }      /* Check whether an URB is avaiable */#ifdef BTUSB_DEBUG      if (nURBAvailable == MAX_PENDING_BULK_IN_URBS)      {        printk("%s (%d): Inside btusb_read(), no BULK IN URB available.\n",               __FILE__,               __LINE__);        return ERROR;      }#endif /* BTUSB_DEBUG */            tempUrb = devStruct->bulk_in_urb[nURBAvailable];            /* Allocate transfer buffer if it was not allocated */      if (tempUrb->transfer_buffer == NULL)      {        transferBuf = BTUSB_MEM_ALLOC((sizeof(node_t) + MAX_BT_PKT_SIZE));        if (transferBuf != NULL)        {          tempUrb->transfer_buffer = transferBuf + sizeof(node_t);        }      }      /*       * If transfer buffer exists, submit URB. Set URB submitted flag on       * success       */      if (tempUrb->transfer_buffer != NULL)      {#ifdef BTUSB_DEBUG        btusb_display_string("submit bulk URB", DBG_FILEOPS);#endif /* BTUSB_DEBUG */#if 0        if (BTUSB_SUBMIT_URB(tempUrb) == SUCCESS)        {          bulkInUrbSubmitted = TRUE;        }#else#ifdef LINUX_2_4        BT_FILL_BULK_IN_URB(tempUrb,                            devStruct,                            tempUrb->transfer_buffer,                            MAX_BT_PKT_SIZE);#endif /* LINUX_2_4 */                      if ((status = BTUSB_SUBMIT_URB(tempUrb)) == SUCCESS)        {          bulkInUrbSubmitted = TRUE;          /* Increment the number of bulk in urbs pending */          devStruct->pending_bulk_in_urbs++;          /* Set the urb flag as submitted */          devStruct->bulk_in_urb_submitted[nURBAvailable] = TRUE;        }        else        {          printk("%s (%d): Inside btusb_read(), "                 "failed to resubmit URB, usb_submit_urb() returned 0x%X.\n",                 __FILE__,                 __LINE__,                 status);        }#endif /* 0 */              }    }#else /* MULTIPLE_BULK_IN_URBS */    if (devStruct->bulk_in_urbSubmitted == FALSE)    {      tempUrb = devStruct->bulk_in_urb;            /* Allocate transfer buffer if it was not allocated */      if (tempUrb->transfer_buffer == NULL)      {        transferBuf = BTUSB_MEM_ALLOC((sizeof(node_t) + MAX_BT_PKT_SIZE));        if (transferBuf != NULL)        {          tempUrb->transfer_buffer = transferBuf + sizeof(node_t);        }      }      /*

⌨️ 快捷键说明

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