📄 btusb.c
字号:
{ /* 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 + -