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

📄 btusb.c

📁 牛人写的一个蓝牙驱动教学程序
💻 C
📖 第 1 页 / 共 5 页
字号:
    {      /* For COMMAND type, also free the setup packet */      if ((type == COMMAND_TYPE) && (outurb->setup_packet!=NULL))      {        BTUSB_MEM_FREE(outurb->setup_packet);        outurb->setup_packet = NULL;      }      if (transferBuf != NULL)      {        BTUSB_MEM_FREE(transferBuf);        transferBuf=NULL;        /* Set the URB::transfer_buffer to NULL */        outurb->transfer_buffer = NULL;      }      /* Mark URB as unused */      outurb->context = NULL;    }#ifdef BTUSB_DEBUG    btusb_display_string("write - flow blocked", DBG_FILEOPS);#endif /* BTUSB_DEBUG */    return FLOW_BLOCKED;  }  else  {#ifdef URB_QUEUEING_SUPPORT    /* Submit a Zero length Bulk OUT URB, if required */    if (type == ACL_TYPE)    {      if (((count - 1) % devStruct->bulk_out_EPMaxPktSize) == 0)      {        int nStatus; /* To hold the status of the BTUSB_SUBMIT_URB() call */        nStatus = BTUSB_SUBMIT_URB(                    devStruct->write_urb_pool[urbPoolIndex_forZeroLength]);        /* Check whether the zero length URB was successfully submited */        if (nStatus != 0)        {          /* Unlink the URB for the previous transfer */          printk("%s (%d): Inside btusb_write(), failed to transmit "                 "zero length packet.\n",                 __FILE__,                 __LINE__);          /* Set the 'urbSubmitted' flag to FALSE */          urbSubmitted = FALSE;        }      }    }#endif /* URB_QUEUEING_SUPPORT */    /* Lock btusb_t struct */    BTUSB_RESOURCE_WAIT_FOR_UNLOCK(&devStruct->lock);    BTUSB_RESOURCE_LOCK(&devStruct->lock, flags);    if (type == SCO_TYPE)    {      /* For iso URB, make entry in ISO-out URB pool */      devStruct->iso_out_urb_pool[urbPoolIndex] = outurb;      /* Update pending-URB-count for iso URBs */      devStruct->pending_isoOutURBs ++;    }    else    {#ifdef URB_QUEUEING_SUPPORT      if (type == ACL_TYPE)      {        /* Check whether the URB was submitted */        if (urbSubmitted == TRUE)        {          /* Increment the number of pending OUT URBs */          devStruct->pending_outPoolURBs ++;          /* Check whether a Zero length Bulk OUT URB was submitted */          if (((count - 1) % devStruct->bulk_out_EPMaxPktSize) == 0)          {            /* Increment the number of pending OUT URBs */            devStruct->pending_outPoolURBs ++;          }        }      }      else /* 'type' is not ACL_TYPE */      {        /* Increment the number of pending OUT URBs */        devStruct->pending_outPoolURBs ++;      }#else      /* Increment the number of pending OUT URBs */      devStruct->pending_outPoolURBs ++;#endif /* URB_QUEUEING_SUPPORT */    }    /* Unlock btusb_t struct */    BTUSB_RESOURCE_UNLOCK(&devStruct->lock, flags);    /* return 'count' to indicate that write was successful */#ifdef BTUSB_DEBUG    btusb_display_string("write - Data sent successfully", DBG_FILEOPS);#endif /* BTUSB_DEBUG */#ifndef URB_QUEUEING_SUPPORT#ifdef TRANSMIT_ZERO_LENGTH_BULK_OUT  /*   * 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)    {      /* Set the flag specifying that a zero length packet should be sent */      devStruct->TransmitZeroLength_BulkOUT = TRUE;    }  }#endif /* TRANSMIT_ZERO_LENGTH_BULK_OUT */#endif /* URB_QUEUEING_SUPPORT */    return count;  }} /* End of btusb_write *//* * PURPOSE *  Function registered as completion call back for all the IN URBs. *  It adds the received data to device specific receive-data-queue and *  resubmits the URB for continued data reception. * * PARAMETERS TO THE FUNCTION *  TYPE    VARIABLE   DESCRIPTION *  urb_t*  bturb_p    Completed URB * * RETURN VALUE *  None. * * GLOBAL PARAMETERS MODIFIED BY THE FUNCTION *  None. */static voidbtusb_read_callback(urb_t *bturb_p){  int addNodeRetVal = STOP;  bool submitUrb = FALSE;  bool resetSubmitFlag  = TRUE;  node_t *nodeToAdd = NULL;  uint16  length = 0;  uint8   type = BULK_TYPE;  char *newBuf = NULL;  unsigned long flags;  btusb_t *devStruct = NULL;  int status;#ifdef MULTIPLE_BULK_IN_URBS  int i;#endif MULTIPLE_BULK_IN_URBS#ifdef BTUSB_DEBUG  btusb_display_string("Entering - Read_callback", DBG_CALLBACK);#endif /* BTUSB_DEBUG */  /* get the btusb_t struct associated with the URB */  devStruct = (btusb_t *) bturb_p->context;  if (devStruct == NULL)  {    return;  }    /* get actual length and type from URB */  length = bturb_p->actual_length;  type = TYPE_OF_URB_PIPE(bturb_p->pipe);  /*   *  If URB was successful and data was received,   *  if type was isochronous, try to reallocate buffer.   *  Add a node containing received data to receive-data-queue.   *  If needed, allocate new transfer buffer, fill URB and   *  re submit URB for continued data reception.   */  if ((devStruct->devOpened == TRUE) &&      (bturb_p->status == SUCCESS) &&      (length > 0))  {#ifdef BTUSB_DEBUG    btusb_display_string("Read - Got data from controller", DBG_CALLBACK);#endif /* BTUSB_DEBUG */    if (type == INTERRUPT_TYPE)    {      /* Check whether a short length packet is received */      if (length < devStruct->interrupt_in_EPMaxPktSize)      {        /* Copy the data to the buffer */        memcpy(&devStruct->InterruptInBuffer[devStruct->InterruptInDataLength],               bturb_p->transfer_buffer,               length);        /* Update Interrupt In Data Length */        devStruct->InterruptInDataLength += length;				/*         * Try to allocate new buffer of actual data size and add it to         * the queue         */#ifdef NONATOMIC_KMEM_CACHE_GROW				newBuf = kmalloc(sizeof(node_t) + devStruct->InterruptInDataLength,												 GFP_KERNEL | GFP_ATOMIC);#else													        newBuf = BTUSB_MEM_ALLOC((sizeof(node_t) +                                   devStruct->InterruptInDataLength));#endif /* NONATOMIC_KMEM_CACHE_GROW */					        if (newBuf != NULL)        {          nodeToAdd = (node_t *)newBuf;          nodeToAdd->length = devStruct->InterruptInDataLength;          nodeToAdd->type = type;          nodeToAdd->buf = (uint8 *)(newBuf+sizeof(node_t));          memcpy(nodeToAdd->buf,          devStruct->InterruptInBuffer,          devStruct->InterruptInDataLength);          /* Set InterruptInDataLength to zero */          devStruct->InterruptInDataLength = 0;          /* URB can be re-submitted with old transfer buffer */          submitUrb = TRUE;        }      }      else      {        /* Copy the data to the buffer */        memcpy(&devStruct->InterruptInBuffer[devStruct->InterruptInDataLength],               bturb_p->transfer_buffer,               length);        /* Update Interrupt In Data Length */        devStruct->InterruptInDataLength += length;        /* Set 'addNodeRetVal' to CONTINUE */        addNodeRetVal = CONTINUE;        /* Set 'submitUrb' to TRUE */        submitUrb = TRUE;      }    }    else 		{    	/* 			 * Try to allocate new buffer of actual data size and add it to 			 * the queue 			 */#ifdef NONATOMIC_KMEM_CACHE_GROW			newBuf = kmalloc(sizeof(node_t) + length, GFP_KERNEL | GFP_ATOMIC);#else													      newBuf = BTUSB_MEM_ALLOC((sizeof(node_t) + length));#endif /* NONATOMIC_KMEM_CACHE_GROW */											if (newBuf != NULL)    	{      	nodeToAdd = (node_t *)newBuf;      	nodeToAdd->length = length;      	nodeToAdd->type = type;      	nodeToAdd->buf = (uint8 *)(newBuf+sizeof(node_t));      	memcpy(nodeToAdd->buf, bturb_p->transfer_buffer,length);      	/* URB can be re-submitted with old transfer buffer */      	submitUrb = TRUE;			}    	else    	{#ifdef BTUSB_DEBUG      	printk("%s (%d): Failed to allocate memory to queue the data received.\n",            	 __FILE__,            	 __LINE__);#endif /* BTUSB_DEBUG */    	}    }    if (nodeToAdd != NULL)    {      /*        * Lock btusb_t struct,        * add the node to receive-data-queue and        * unlock it        */#if 0#ifdef BTUSB_DEBUG      printk("%s (%d): MN(%02d), ", 				     __FILE__, 				     __LINE__, 				     devStruct->minorNumber); 	      /* Display the type of data received and the number of bytes received */      switch (type)      {      case BULK_TYPE:		    printk("Received %d bytes of BULK data.\n", nodeToAdd->length);    		break;      		case INTERRUPT_TYPE:    		printk("Received %d bytes of INTR data.\n", nodeToAdd->length);    		break;  		case ISO_TYPE:    		printk("Received %d bytes of ISOC data.\n", nodeToAdd->length);    		break;  		};#endif /* BTUSB_DEBUG */#endif /* 0 */      BTUSB_RESOURCE_WAIT_FOR_UNLOCK(&devStruct->lock);      BTUSB_RESOURCE_LOCK(&devStruct->lock, flags);      addNodeRetVal = btusb_addToQueue(&devStruct->recvQueue, nodeToAdd);      BTUSB_RESOURCE_UNLOCK(&devStruct->lock, flags);    }#ifdef TEMPORARY_FIX_FOR_SLOW_DATA_RATE		if (addNodeRetVal != CONTINUE)		{			node_t *temp_node = NULL;						/* Remove the first node in the queue */  		temp_node = btusb_getNodeFromQueue(&devStruct->recvQueue);			/* Check whether the node is valid */			if (temp_node != NULL)			{				/* Free the node */    		BTUSB_MEM_FREE(temp_node);    		temp_node=NULL;			}			/* Set the 'addNodeRetVal' variable to CONTINUE */			addNodeRetVal = CONTINUE;      #if 0 			/* Put a error message */			printk("%s (%d): Inside btusb_read_callback(), QUEUE OVERFLOW)\n",             __FILE__,             __LINE__);#endif /* 0 */					}#endif /* TEMPORARY_FIX_FOR_SLOW_DATA_RATE */		/* if addNode returns CONTINUE, try to re-submit URB */    if ((addNodeRetVal == CONTINUE) && (submitUrb == TRUE))    {      if (type == INTERRUPT_TYPE)      {        resetSubmitFlag = FALSE;      }#if 0      else if ((BTUSB_SUBMIT_URB(bturb_p)) == SUCCESS)      {        resetSubmitFlag = FALSE; /* URB submission failed */      }#else      else       {#ifdef LINUX_2_4#warning Check whether the URB type is BULK or ISOCHRONOUS        BT_FILL_BULK_IN_URB(bturb_p,                            devStruct,                            bturb_p->transfer_buffer,                            MAX_BT_PKT_SIZE);#endif /* LINUX_2_4 */                      /* Resubmit the URB */        if ((status = BTUSB_SUBMIT_URB(bturb_p)) == SUCCESS)        {           resetSubmitFlag = FALSE; /* URB submission failed */        }#ifdef BTUSB_DEBUG         else        {          printk("%s (%d): Inside btusb_read_callback(), "                 "failed to resubmit URB, usb_submit_urb() returned 0x%X.\n",                 __FILE__,                 __LINE__,                 status);        }#endif /* BTUSB_DEBUG */        }#endif /* 0 */          }    else    {      if (type == INTERRUPT_TYPE)      {        /*         * When you don't have buffers in the queue, the IRP should not be         * resubmitted. Hence, unlink the Interrupt IN URB and don't let         * the USB Stack to resubmit it.         */        BTUSB_UNLINK_URB(bturb_p);      }    }  }  else /* no data received. re-submit URB*/  {#ifdef BTUSB_DEBUG    btusb_display_string("Read - No data received from controller",                         DBG_CALLBACK);#endif /* BTUSB_DEBUG */    if (devStruct->devOpened == TRUE)    {      if (type == INTERRUPT_TYPE)      {        /*         * Check whether this is a zero length after a series of max packet         * length data packets         */        if (devStruct->InterruptInDataLength > 0)        {          /*           * Try to allocate new buffer of actual data size and add it to           * the queue           */#ifdef NONATOMIC_KMEM_CACHE_GROW					newBuf = kmalloc(sizeof(node_t) + devStruct->InterruptInDataLength,													 GFP_KERNEL | GFP_ATOMIC);#else													          newBuf = BTUSB_MEM_ALLOC((sizeof(node_t) +                                    devStruct->InterruptInDataLength));#endif /* NONATOMIC_KMEM_CACHE_GROW */					          /* Check whether the memory was successfully allocated */          if (newBuf != NULL)          {            nodeToAdd = (node_t *)newBuf;            nodeToAdd->length = devStruct->InterruptInDataLength;            nodeToAdd->type = type;            nodeToAdd->buf = (uint8 *)(newBuf+sizeof(node_t));            memcpy(nodeToAdd->buf,                   devStruct->InterruptInBuffer,                   devStruct->InterruptInDataLength);            /* Set InterruptInDataLength to zero */            devStruct->InterruptInDataLength = 0;          }          else          {#ifdef BTUSB_DEBUG            printk("%s (%d): Failed to allocate memory to resubmit the URB.\n",                  __FILE__,                  __LINE__);#endif /* BTUSB_DEBUG */          }          /* Add the node to the queue */          if (nodeToAdd != NULL)          {            /*             * Lock btusb_t struct, add the node to receive-data-q

⌨️ 快捷键说明

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