📄 btusb.c
字号:
{ break; } } } /* * If minor number is equal to 16, no more bluetooth device can be * connected, return error */ if (minor == MAX_BTDEV) {#ifdef BTUSB_DEBUG btusb_display_string("Error - Cannot support more than 16 devices", DBG_PROBE);#endif /* BTUSB_DEBUG */ MOD_DEC_USE_COUNT; return NULL; } /* btusb_devInfo_g as already found, just equate it to btusb struct */ if (btusb_devInfo_g[minor] != NULL) { devStruct = btusb_devInfo_g[minor];#ifdef BTUSB_DEBUG btusb_display_string("btusb_t struct has already been created !!", DBG_PROBE);#endif /* BTUSB_DEBUG */ } else /* allocate btusb structre, minor number and usb_device descriptor */ { if ((devStruct = BTUSB_MEM_ALLOC(sizeof(btusb_t))) == NULL) {#ifdef BTUSB_DEBUG btusb_display_string("Error - Out of memory", DBG_PROBE);#endif /* BTUSB_DEBUG */ MOD_DEC_USE_COUNT; return NULL; } btusb_devInfo_g[minor] = devStruct; devStruct->minorNumber = minor; devStruct->devDesc = dev; /* Intilize btusb struct members to default value */ btusb_set_devStruct_defaults(devStruct);#ifdef BTUSB_DEBUG btusb_display_string("created a new btusb_t struct !!", DBG_PROBE);#endif /* BTUSB_DEBUG */ } /* * If interface number == 0 store the endpoint info * (address. max packet size & interval) of bulk in, bulk out & * interrupt in endpoints in btusb structure */ if (ifnum == 0) { if((endpoint = interrupt_in_endpoint) != NULL) { devStruct->interrupt_in_EPAddress = endpoint->bEndpointAddress; devStruct->interrupt_in_EPMaxPktSize = endpoint->wMaxPacketSize; devStruct->interrupt_in_EPInterval = endpoint->bInterval; } devStruct->control_out_EPAddress = 0x00; devStruct->control_out_EPMaxPktSize = dev->descriptor.bMaxPacketSize0; if((endpoint = bulk_in_endpoint) != NULL) { devStruct->bulk_in_EPAddress = endpoint->bEndpointAddress; devStruct->bulk_in_EPMaxPktSize = endpoint->wMaxPacketSize; } if((endpoint = bulk_out_endpoint) != NULL) { devStruct->bulk_out_EPAddress = endpoint->bEndpointAddress; devStruct->bulk_out_EPMaxPktSize = endpoint->wMaxPacketSize; } } /* * If interface number == 1 store the endpoint info * (address & max packet size) of iso in & iso out endpoints in * btusb structure */ else /* ifnum = 1 */ { if((endpoint = iso_in_endpoint) != NULL) { devStruct->iso_in_EPAddress = endpoint->bEndpointAddress; devStruct->iso_in_EPMaxPktSize = endpoint->wMaxPacketSize; } if((endpoint = iso_out_endpoint) != NULL) { devStruct->iso_out_EPAddress = endpoint->bEndpointAddress; devStruct->iso_out_EPMaxPktSize = endpoint->wMaxPacketSize; } } /* * Allocate IN & OUT URBs . If error in allocation, cleanup * btusb_t struct and return NULL. On success, return btusb_t struct */#ifdef BTUSB_DEBUG btusb_display_string("Endpoint information has been stored !!", DBG_PROBE);#endif /* BTUSB_DEBUG */ status = btusb_allocate_urbs(devStruct, ifnum);#ifdef BTUSB_DEBUG btusb_display_string("URBs have been allocated !!", DBG_PROBE);#endif /* BTUSB_DEBUG */ if (status == ERROR) { btusb_devInfo_g[minor] = NULL; if(devStruct!=NULL) { BTUSB_MEM_FREE(devStruct); devStruct=NULL; } MOD_DEC_USE_COUNT;#ifdef BTUSB_DEBUG btusb_display_string("Error - Cannot allocate URBs", DBG_PROBE);#endif /* BTUSB_DEBUG */ return NULL; } else {#ifdef BTUSB_DEBUG btusb_display_string("btusb_probe was successful", DBG_PROBE);#endif /* BTUSB_DEBUG */ devStruct->moduleIncCount ++; return devStruct; }} /* end of btusb_probe() *//* * PURPOSE * This function is registered with the USB host driver to be called on * device disconnection. It unllinks all the pending URBs, cleans up all * the transfer buffers, releases all the URBs and frees the minor number. * * PARAMETERS TO THE FUNCTION * TYPE VARIABLE DESCRIPTION * usb_device* dev Descriptor of the device that was disconnected. * void* btusb_ptr btusb_t structure corresponding to the device. * * RETURN VALUE * None. * * GLOBAL PARAMETERS MODIFIED BY THE FUNCTION * btusb_devInfo_g */static voidbtusb_disconnect(struct usb_device *dev, void *btusb_ptr){ btusb_t *devStruct = NULL; uint32 i; uint8 devExistsFlag = FALSE; unsigned long flags = 0; if ((dev == NULL) || (btusb_ptr == NULL)) { /* Invalid input parameters. Return without doing anything */#ifdef BTUSB_DEBUG btusb_display_string("Bad inputs... Exiting btusb_disconnect", DBG_DISCONNECT);#endif /* BTUSB_DEBUG */ return; } /* Find device entry in btusb_devInfo_g array */ for(i=0; i<MAX_BTDEV; i++) { if (btusb_ptr == btusb_devInfo_g[i]) { devExistsFlag = TRUE; break; } } if (devExistsFlag == FALSE) { /* * Device not found. Might have already been disconnected. * return without doing anything */#ifdef BTUSB_DEBUG btusb_display_string("Device does not exists... Exiting btusb_disconnect", DBG_DISCONNECT);#endif /* BTUSB_DEBUG */ return; } devStruct = btusb_ptr; /* * The device structure needs to be cleaned up. * Mark the device to be closed, * unlink and free all the URBs and their transfer buffers, * clean up the receive data queue, * mark the device to have been cleaned up, * decrement moduleIncCount and return */ if (devStruct->devOpened == TRUE) {#ifdef BTUSB_DEBUG btusb_display_string("Device is open... Closing it", DBG_DISCONNECT);#endif /* BTUSB_DEBUG */ BTUSB_RESOURCE_WAIT_FOR_UNLOCK(&devStruct->lock); BTUSB_RESOURCE_LOCK(&devStruct->lock, flags); devStruct->devOpened = FALSE; devStruct->devFile->private_data = NULL; devStruct->devFile = NULL; devStruct->devDesc = NULL; BTUSB_RESOURCE_UNLOCK(&devStruct->lock, flags);#ifdef BTUSB_DEBUG btusb_display_string("Unlinking all URBs", DBG_DISCONNECT);#endif /* BTUSB_DEBUG */ btusb_unlink_urbs(devStruct);#ifdef BTUSB_DEBUG btusb_display_string("Cleaning up receive-data-queue", DBG_DISCONNECT);#endif /* BTUSB_DEBUG */ btusb_cleanup_queue(&devStruct->recvQueue); } MOD_DEC_USE_COUNT; devStruct->moduleIncCount --; if (devStruct->moduleIncCount == 0) {#ifdef BTUSB_DEBUG btusb_display_string("Freeing all URBs", DBG_DISCONNECT);#endif /* BTUSB_DEBUG */ btusb_free_urbs(devStruct); btusb_devInfo_g[devStruct->minorNumber] = NULL; if(devStruct!=NULL) { BTUSB_MEM_FREE(devStruct); devStruct=NULL; }#ifdef BTUSB_DEBUG btusb_display_string("Device is completely cleaned up", DBG_DISCONNECT);#endif /* BTUSB_DEBUG */ } return;} /* end of btusb_disconnect() *//* * PURPOSE * Function registered as OPEN file-operation function for btusb device. * It starts the communication with the device specified by minor number * in the inode. * * 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 while closing the device. * * GLOBAL PARAMETERS MODIFIED BY THE FUNCTION * None. */static intbtusb_open(struct inode *inode_p, struct file *file_p){ btusb_t *devStruct = NULL; uint8 *transferBuf = NULL; int transferBufSize = 0; urb_t *tempUrb = NULL; unsigned int numOfIsoPkts = 0; unsigned int i;#ifdef BTUSB_DEBUG btusb_display_string("open - Entering btusb_open!!", DBG_FILEOPS);#endif /* BTUSB_DEBUG */ /* if btusb_t struct for minor number is not found, return ERROR */ devStruct = btusb_devInfo_g[MINOR(inode_p->i_rdev)]; if (devStruct == NULL) {#ifdef BTUSB_DEBUG btusb_display_string("open - Device error", DBG_FILEOPS);#endif /* BTUSB_DEBUG */ return ERROR; }#ifdef EXCLUSIVE_DEVICE_OPEN /* Check whether the device is already open */ if (devStruct->devOpened == TRUE) { /* Return an Error Code saying that the device is already open */ return DEVICE_ALREADY_OPEN; }#endif /* EXCLUSIVE_DEVICE_OPEN */ /* Fill file structures private data */ file_p->private_data = devStruct; devStruct->devFile = file_p; /* transfer buffer size includes size of node_t */ transferBufSize = MAX_BT_PKT_SIZE + sizeof(node_t); /* Allocate transfer buffer, fill and submit interrupt IN URB */ tempUrb = devStruct->interrupt_in_urb; transferBuf = BTUSB_MEM_ALLOC(transferBufSize); /* If transfer buffer was allocated, submit URB */ BT_FILL_INT_IN_URB(tempUrb, devStruct, (transferBuf + sizeof(node_t)), MAX_BT_PKT_SIZE); if (transferBuf != NULL) { if (BTUSB_SUBMIT_URB(tempUrb) == SUCCESS) { devStruct->interrupt_in_urbSubmitted = TRUE; devStruct->pending_inURBs ++; } /* * NOTE: if URB submission failed, it will be re-submitted in * btusb_read */ } /* Allocate transfer buffer, fill and submit bulk IN URB */#ifdef MULTIPLE_BULK_IN_URBS for (i = 0; i < MAX_PENDING_BULK_IN_URBS; i++) { tempUrb = devStruct->bulk_in_urb[i]; transferBuf = BTUSB_MEM_ALLOC(transferBufSize); BT_FILL_BULK_IN_URB(tempUrb, devStruct, (transferBuf + sizeof(node_t)), MAX_BT_PKT_SIZE); /* If transfer buffer was allocated, submit URB */ if (transferBuf != NULL) { if (BTUSB_SUBMIT_URB(tempUrb) == SUCCESS) { devStruct->bulk_in_urbSubmitted = TRUE; devStruct->pending_inURBs ++; /* Increment the number of pending Bulk IN URBs */ devStruct->pending_bulk_in_urbs++; /* Mark the URB as submitted */ devStruct->bulk_in_urb_submitted[i] = TRUE; } /* * NOTE: * If URB submission failed, it will be re-submitted in btusb_read */ } } /* End of for (i = 0; i < MAX_PENDING_BULK_IN_URBS; i++) */#else /* MULTIPLE_BULK_IN_URBS */ tempUrb = devStruct->bulk_in_urb; transferBuf = BTUSB_MEM_ALLOC(transferBufSize); BT_FILL_BULK_IN_URB(tempUrb, devStruct, (transferBuf + sizeof(node_t)), MAX_BT_PKT_SIZE); /* If transfer buffer was allocated, submit URB */ if (transferBuf != NULL) { if (BTUSB_SUBMIT_URB(tempUrb) == SUCCESS) { devStruct->bulk_in_urbSubmitted = TRUE; devStruct->pending_inURBs ++; } /* * NOTE: if URB submission failed, it will be re-submitted in * btusb_read */ }#endif /* MULTIPLE_BULK_IN_URBS */ if (devStruct->iso_in_EPMaxPktSize > 0) { /* Allocate transfer buffer, fill and submit isochronous IN URB */ tempUrb = devStruct->iso_in_urb; transferBuf = BTUSB_MEM_ALLOC(transferBufSize); numOfIsoPkts = (MAX_BT_PKT_SIZE + devStruct->iso_in_EPMaxPktSize - 1) / devStruct->iso_in_EPMaxPktSize; BT_FILL_ISO_IN_URB(tempUrb, devStruct, (transferBuf + sizeof(node_t)), MAX_BT_PKT_SIZE, numOfIsoPkts); /* If transfer buffer was allocated, submit URB */ if (transferBuf != NULL) { /* 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 (BTUSB_SUBMIT_URB(tempUrb) == SUCCESS) { devStruct->iso_in_urbSubmitted = TRUE; devStruct->pending_inURBs ++; } /* * NOTE: if URB submission failed, it will be re-submitted in * btusb_read */ } } /* Mark device as opened for communication and return SUCCESS */ devStruct->devOpened = TRUE;#ifdef BTUSB_DEBUG btusb_display_string("open - Device opened successfully", DBG_FILEOPS);#endif /* BTUSB_DEBUG */ return SUCCESS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -