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

📄 btusb.c

📁 牛人写的一个蓝牙驱动教学程序
💻 C
📖 第 1 页 / 共 5 页
字号:
       * 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;        }        else        {          printk("%s (%d): Inside btusb_read(), "                 "failed to resubmit URB, usb_submit_urb() returned 0x%X.\n",                 __FILE__,                 __LINE__,                 status);        }#endif /* 0 */      }    }#endif /* MULTIPLE_BULK_IN_URBS */    if ((devStruct->iso_in_urbSubmitted == FALSE) &&        (devStruct->iso_in_EPMaxPktSize))    {      tempUrb = devStruct->iso_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);          numOfIsoPkts = (MAX_BT_PKT_SIZE + devStruct->iso_in_EPMaxPktSize - 1) /                         devStruct->iso_in_EPMaxPktSize;          /* Set attributes of ISO frame descriptors */          for(i=0; i < numOfIsoPkts; i++)          {            tempUrb->iso_frame_desc[i].offset = i * devStruct->iso_in_EPMaxPktSize;            tempUrb->iso_frame_desc[i].length = devStruct->iso_in_EPMaxPktSize;            tempUrb->iso_frame_desc[i].status = 0;            tempUrb->iso_frame_desc[i].actual_length = 0;          }        }      }      /*       * If transfer buffer exists, submit URB. Set URB submitted flag on       * success       */      if (tempUrb->transfer_buffer != NULL)      {#ifdef BTUSB_DEBUG        btusb_display_string("submit sio URB", DBG_FILEOPS);#endif /* BTUSB_DEBUG */        if (BTUSB_SUBMIT_URB(tempUrb) == SUCCESS)        {          isoInUrbSubmitted = TRUE;        }      }    }  }  /* if any URBs were submitted, update the btusb_t struct */  if ((intInUrbSubmitted == TRUE) ||      (bulkInUrbSubmitted == TRUE) ||      (isoInUrbSubmitted == TRUE))  {    /*     * Lock the device info struct before updating pending URB count and     * URB submitted flags     */    BTUSB_RESOURCE_WAIT_FOR_UNLOCK(&devStruct->lock);    BTUSB_RESOURCE_LOCK(&devStruct->lock, flags);    if (intInUrbSubmitted == TRUE)    {#ifdef BTUSB_DEBUG      btusb_display_string("submitted interrupt URB", DBG_FILEOPS);#endif /* BTUSB_DEBUG */      devStruct->interrupt_in_urbSubmitted = TRUE;      devStruct->pending_inURBs ++;    }    if (bulkInUrbSubmitted == TRUE)    {#ifdef BTUSB_DEBUG      btusb_display_string("submitted bulk URB", DBG_FILEOPS);#endif /* BTUSB_DEBUG */      devStruct->bulk_in_urbSubmitted = TRUE;      devStruct->pending_inURBs ++;    }    if (isoInUrbSubmitted == TRUE)    {#ifdef BTUSB_DEBUG      btusb_display_string("submitted iso URB", DBG_FILEOPS);#endif /* BTUSB_DEBUG */      devStruct->iso_in_urbSubmitted = TRUE;      devStruct->pending_inURBs ++;    }    /* Unlock the device info structure */    BTUSB_RESOURCE_UNLOCK(&devStruct->lock, flags);  }  return retVal;} /* End of btusb_read *//* * PURPOSE *  This function is registered as WRITE file operation function for btusb *  device. If device is opened for communication, it sends a packet to the *  BT host controller through appropriate USB pipe. * * PARAMETERS TO THE FUNCTION *  TYPE     VARIABLE  DESCRIPTION *  file*    file_p    Valid file structure *  char*    buf_p     user buffer containing data to be sent *  size_t   count     Length of data in buffer *  loff_t*  pos_p     Offset. Always ignored. * * RETURN VALUE *  VALUE         DESCRIPTION *  count         If packet was sent successfully. *  FLOW_BLOCKED  If not able to get or submit URB. *  NO_MEM        If error in memory allocation. *  ERROR         If device does not exist. * * GLOBAL PARAMETERS MODIFIED BY THE FUNCTION *  None. */static ssize_tbtusb_write(struct file  *file_p,            const char   *buf_p,            size_t       count,            loff_t       *pos_p){  btusb_t *devStruct = NULL;  uint8   type;  uint8   *transferBuf = NULL;  int urbPoolIndex = MAX_ISO_OUT_URBS;  urb_t   *outurb = NULL;  unsigned int  numOfIsoPkts = 0;  unsigned int  i;  devrequest  *btCmdRequest = NULL;  unsigned long   flags;#ifdef URB_QUEUEING_SUPPORT  int   urbPoolIndex_forZeroLength = MAX_ISO_OUT_URBS;  bool  urbSubmitted = TRUE;#endif /* URB_QUEUEING_SUPPORT */  /* 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("write - 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("write - Device error", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* Determine type of data. If invalid type, return ERROR */  type = *buf_p;  if ((type != ACL_TYPE) && (type != SCO_TYPE) && (type != COMMAND_TYPE))  {#ifdef BTUSB_DEBUG    btusb_display_string("write - Device error", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* If type of data is SCO and SCO type is not supported, return ERROR */  if ((type == SCO_TYPE) && (devStruct->iso_out_EPMaxPktSize == 0))  {#ifdef BTUSB_DEBUG    btusb_display_string("write - Device error, Isochronous not supported",                         DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return ERROR;  }  /* Allocate transfer buffer. If allocation failed, return NO_MEM */  if ((transferBuf = BTUSB_MEM_ALLOC((count-1))) == NULL)  {#ifdef BTUSB_DEBUG    btusb_display_string("write - Out of memory", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return NO_MEM;  }  /*   *  Find a free URB corresponding to the type, fill it and submit it.   *  If error in finding free URB or in submission, return FLOW_BLOCKED.   */  if (type == SCO_TYPE)  {    /* Request type is SCO */    /* Check if ISO URB pool can hold one more URB */    urbPoolIndex = MAX_ISO_OUT_URBS;    for(i=0;i<MAX_ISO_OUT_URBS;i++)    {      if (devStruct->iso_out_urb_pool[i] != NULL)      {        urbPoolIndex = i;        break;      }    }    if (urbPoolIndex == MAX_ISO_OUT_URBS)    {      /* URB pool is full. Release transfer buffer and return FLOW_BLOCKED */      if(transferBuf!=NULL)      {          BTUSB_MEM_FREE(transferBuf);          transferBuf=NULL;      }#ifdef BTUSB_DEBUG      btusb_display_string("write - No free URBs", DBG_FILEOPS);#endif /* BTUSB_DEBUG */      return FLOW_BLOCKED;    }    /* URB pool can hold one more URB. Allocate URB as per request size */    numOfIsoPkts = (count + devStruct->iso_out_EPMaxPktSize - 1) /                   devStruct->iso_out_EPMaxPktSize;    outurb = BTUSB_ALLOC_URB(numOfIsoPkts);    if (outurb == NULL)    {      /*       * URB allocation failed. Release transfer buffer and       * return FLOW_BLOCKED       */      if(transferBuf!=NULL)      {        BTUSB_MEM_FREE(transferBuf);        transferBuf=NULL;      }#ifdef BTUSB_DEBUG      btusb_display_string("write - No free URBs", DBG_FILEOPS);#endif /* BTUSB_DEBUG */      return FLOW_BLOCKED;    }    /* Copy data from user memory to the transfer buffer in kernel memory */    copy_from_user(transferBuf, (buf_p+1), (count - 1));    /* Fill URB */    BT_FILL_ISO_OUT_URB(outurb,                        devStruct,                        transferBuf,                        (count - 1),                        numOfIsoPkts);    /* Set attributes of ISO frame descriptors */    for (i = 0; i < numOfIsoPkts; i++)    {      outurb->iso_frame_desc[i].offset = i * devStruct->iso_in_EPMaxPktSize;      outurb->iso_frame_desc[i].length = devStruct->iso_in_EPMaxPktSize;      outurb->iso_frame_desc[i].status = 0;      outurb->iso_frame_desc[i].actual_length = 0;    }  }  else  {    /* Request type is not SCO */    /* Check if WRITE URB pool can hold one more URB */    urbPoolIndex = MAX_WRITE_URBS;    for (i=0; i < MAX_WRITE_URBS; i++)    {      if (devStruct->write_urb_pool[i]->context == NULL)      {        urbPoolIndex = i;        break;      }    }#ifdef URB_QUEUEING_SUPPORT    /*     * Check whether a zero length packet should be send for a     * Bulk OUT Transfer.     *     * NOTE: The 'count' parameter also includes the packet qualifier which     * is not sent on the bus.     */    if (type == ACL_TYPE)    {      if (((count - 1) % devStruct->bulk_out_EPMaxPktSize) == 0)      {        /*         * Check whether an additional URB is available in the pool of         * write URBs         */        for (i = 0; i < MAX_WRITE_URBS; i++)        {          if (devStruct->write_urb_pool[i]->context == NULL)          {            if (i != urbPoolIndex)            {              urbPoolIndex_forZeroLength = i;              break;            }          }        }        /* Check whether an additional URB is available */        if (urbPoolIndex_forZeroLength == MAX_WRITE_URBS)        {          /* Check whether memory was allocated for the transfer buffer */          if (transferBuf != NULL)          {            /* Free the memory allocated for the transfer buffer */            BTUSB_MEM_FREE(transferBuf);            transferBuf = NULL;          }          /* Return FLOW_BLOCKED, as the URB's cannot be submitted */          return FLOW_BLOCKED;        }      }    }#endif /* URB_QUEUEING_SUPPORT */    /* URB pool is full. Release transfer buffer and return FLOW_BLOCKED */    if ((urbPoolIndex == MAX_WRITE_URBS) && (transferBuf!=NULL))    {      BTUSB_MEM_FREE(transferBuf);      transferBuf=NULL;#ifdef BTUSB_DEBUG      btusb_display_string("write - No free URBs", DBG_FILEOPS);#endif /* BTUSB_DEBUG */      return FLOW_BLOCKED;    }    /* For COMMAND out request, allocate and fill setup packet */    if (type == COMMAND_TYPE)    {      if ((btCmdRequest = BTUSB_MEM_ALLOC(sizeof(devrequest)))==NULL)      {        /*         * Cannot allocate memory for setup packet. Free transfer buffer         * and return NO_MEM         */        if(transferBuf!=NULL)        {          BTUSB_MEM_FREE(transferBuf);          transferBuf=NULL;        }#ifdef BTUSB_DEBUG        btusb_display_string("write - No free URBs", DBG_FILEOPS);#endif /* BTUSB_DEBUG */        return NO_MEM;      }      /*       * Control URB needs setup packet.       * Fill setup packet with Bluetooth request       */      btCmdRequest->requesttype = BLUETOOTH_CONTROL_REQUEST_TYPE;      btCmdRequest->request = 0x00;      btCmdRequest->value = 0x00;      btCmdRequest->index = (uint16)0x0000;      btCmdRequest->length = (uint16)(count - 1);    }    /* Get urb from WRITE URB pool */    outurb = devStruct->write_urb_pool[urbPoolIndex];    /* Copy data from user memory to the transfer buffer in kernel memory */    copy_from_user(transferBuf, (buf_p+1), (count - 1));    /* Fill URB */    if (type == ACL_TYPE)    {      BT_FILL_BULK_OUT_URB(outurb, devStruct, transferBuf, (count-1));#ifdef URB_QUEUEING_SUPPORT      /* Populate the Zero length Bulk OUT URB, if required */      if (type == ACL_TYPE)      {        if (((count - 1) % devStruct->bulk_out_EPMaxPktSize) == 0)        {          BT_FILL_BULK_OUT_URB(            devStruct->write_urb_pool[urbPoolIndex_forZeroLength],            devStruct,            NULL, /* Transfer buffer */            0 /* Transfer Length */);        }      }#endif /* URB_QUEUEING_SUPPORT */    }    else    {      BT_FILL_CONTROL_OUT_URB(outurb,                              (unsigned char *)btCmdRequest,                              devStruct,                              transferBuf,                              (count-1));    }  }  /*   * Submit URB. If URB submission failed, clean up memory and return   * FLOW_BLOCKED. If URB submission succeeded, return 'count' to indicate   * that data was sent.   */  if (BTUSB_SUBMIT_URB(outurb) != 0)  {    /* URB submission failed. Clean up memory and return FLOW_BLOCKED */    if (type == SCO_TYPE)    {      BTUSB_MEM_FREE(transferBuf);      BTUSB_FREE_URB(outurb);    }    else

⌨️ 快捷键说明

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