From b73b76681ee4b1de68207b6a79f148f3a6f18e6e Mon Sep 17 00:00:00 2001 From: Jan Kriz Date: Sun, 27 Jul 2008 18:30:39 +0200 Subject: [PATCH] Usbcan thread split into smaller functions --- lincan/src/usbcan.c | 297 ++++++++++++++++++++++---------------------- 1 file changed, 147 insertions(+), 150 deletions(-) diff --git a/lincan/src/usbcan.c b/lincan/src/usbcan.c index c813715..42ece6f 100644 --- a/lincan/src/usbcan.c +++ b/lincan/src/usbcan.c @@ -678,53 +678,157 @@ int usbcan_config_irqs(struct canchip_t *chip, short irqs) } /** - * usbcan_irq_write_handler: - part of ISR code responsible for transmit events - * @chip: pointer to chip state structure - * @obj: pointer to attached queue description + * usbcan_kthread_read_handler: - part of kthread code responsible for receive completed events + * @dev: pointer to usb device related structure + * @obj: pointer to attached message object description * - * The main purpose of this function is to read message from attached queues - * and transfer message contents into CAN controller chip. + * The main purpose of this function is to read message from usb urb + * and transfer message contents to CAN queue ends. * This subroutine is called by - * usbcan_irq_write_handler() for transmit events. + * usbcan_kthread(). * File: src/usbcan.c */ -void usbcan_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) -{ - int cmd; +void usbcan_kthread_read_handler(struct usbcan_usb *dev, struct msgobj_t *obj){ + int i, j, len, retval; + CANMSG("USBCAN RX handler\n"); + for (i=0;irx[i].flags)){ + CANMSG("USBCAN Thread has received a message\n"); + if ((dev->chip)&&(dev->chip->flags & CHIP_CONFIGURED)){ + u8 *ptr; + struct usbcan_message *mess=&dev->rx[i]; - if(obj->tx_slot){ - // Do local transmitted message distribution if enabled - if (processlocal){ - // fill CAN message timestamp - can_filltimestamp(&obj->tx_slot->msg.timestamp); + len=*(u8 *)(mess->msg+1); + if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; + obj->rx_msg.length = len; + + obj->rx_msg.flags=le16_to_cpu(*(u16 *)(mess->msg+2)); + obj->rx_msg.id=le32_to_cpu((*(u32 *)(mess->msg+4))); + + for(ptr=mess->msg+8,j=0; j < len; ptr++,j++) { + obj->rx_msg.data[j]=*ptr; + } - obj->tx_slot->msg.flags |= MSG_LOCAL; - canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg); + // fill CAN message timestamp + can_filltimestamp(&obj->rx_msg.timestamp); + canque_filter_msg2edges(obj->qends, &obj->rx_msg); + } + else + CANMSG("Destination chip not found\n"); + } + if (!test_bit(USBCAN_MESSAGE_URB_PENDING,&dev->rx[i].flags)){ + CANMSG("Renewing RX urb\n"); + retval = usb_submit_urb (dev->rx[i].u, GFP_KERNEL); + if (retval<0){ + CANMSG("%d. URB error %d\n", i, retval); + set_bit(USBCAN_ERROR,&dev->flags); + } + else + set_bit(USBCAN_MESSAGE_URB_PENDING,&dev->rx[i].flags); } - // Free transmitted slot - canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); - obj->tx_slot=NULL; } +} - can_msgobj_clear_fl(obj,TX_PENDING); - cmd=canque_test_outslot(obj->qends, &obj->tx_qedge, &obj->tx_slot); - if(cmd<0) - return; - can_msgobj_set_fl(obj,TX_PENDING); +/** + * usbcan_kthread_write_handler: - part of kthread code responsible for transmit done events + * @dev: pointer to usb device related structure + * @obj: pointer to attached message object description + * + * The main purpose of this function is to free allocated resources on transmit done event + * This subroutine is called by + * usbcan_kthread(). + * File: src/usbcan.c + */ +void usbcan_kthread_write_handler(struct usbcan_usb *dev, struct msgobj_t *obj){ + int i; + CANMSG("USBCAN TX handler\n"); + for (i=0;itx[i].flags)){ + struct usbcan_message *mess=&dev->tx[i]; + CANMSG("USBCAN Message successfully sent\n"); + + if(mess->slot){ + // Do local transmitted message distribution if enabled + if (processlocal){ + // fill CAN message timestamp + can_filltimestamp(&mess->slot->msg.timestamp); + + mess->slot->msg.flags |= MSG_LOCAL; + canque_filter_msg2edges(obj->qends, &mess->slot->msg); + } + // Free transmitted slot + canque_free_outslot(obj->qends, mess->qedge, mess->slot); + mess->slot=NULL; + } + can_msgobj_clear_fl(obj,TX_PENDING); - if (chip->chipspecops->pre_write_config(chip, obj, &obj->tx_slot->msg)) { - obj->ret = -1; - canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_PREP); - canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); - obj->tx_slot=NULL; - return; + set_bit(USBCAN_FREE_TX_URB,&dev->flags); + set_bit(USBCAN_MESSAGE_FREE,&dev->tx[i].flags); + + // Test if some new messages arrived + set_bit(USBCAN_TX_PENDING,&dev->flags); + } } - if (chip->chipspecops->send_msg(chip, obj, &obj->tx_slot->msg)) { - obj->ret = -1; - canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_SEND); - canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); - obj->tx_slot=NULL; - return; +} + +/** + * usbcan_kthread_write_request_handler: - part of kthread code responsible for sending transmit urbs + * @dev: pointer to usb device related structure + * @obj: pointer to attached message object description + * + * The main purpose of this function is to create a usb transmit safe object + * and send it via free transmit usb urb + * This subroutine is called by + * usbcan_kthread(). + * File: src/usbcan.c + */ +void usbcan_kthread_write_request_handler(struct usbcan_usb *dev, struct msgobj_t *obj){ + int i, j, cmd, len, retval; + for (i=0;itx[i].flags)){ + struct usbcan_message *mess=&dev->tx[i]; + u8 *ptr; + cmd=canque_test_outslot(obj->qends, &mess->qedge, &mess->slot); + if(cmd>=0){ + CANMSG("USBCAN Sending a message\n"); + + can_msgobj_set_fl(obj,TX_PENDING); + clear_bit(USBCAN_FREE_TX_URB,&dev->flags); + clear_bit(USBCAN_MESSAGE_FREE,&dev->tx[i].flags); + + *(u8 *)(mess->msg)=0; + len = mess->slot->msg.length; + if(len > CAN_MSG_LENGTH) + len = CAN_MSG_LENGTH; + *(u8 *)(mess->msg+1)=len & 0xFF; + *(u16 *)(mess->msg+2)=cpu_to_le16(mess->slot->msg.flags); + *(u32 *)(mess->msg+4)=cpu_to_le32(mess->slot->msg.id); + + for(ptr=mess->msg+8,j=0; j < len; ptr++,j++) { + *ptr=mess->slot->msg.data[j] & 0xFF; + } + for(; j < 8; ptr++,j++) { + *ptr=0; + } + + set_bit(USBCAN_MESSAGE_URB_PENDING,&mess->flags); + retval = usb_submit_urb (dev->tx[i].u, GFP_KERNEL); + if (retval){ + CANMSG("%d. URB error %d\n",i,retval); + clear_bit(USBCAN_MESSAGE_URB_PENDING,&mess->flags); + set_bit(USBCAN_FREE_TX_URB,&dev->flags); + set_bit(USBCAN_MESSAGE_FREE,&dev->tx[i].flags); + obj->ret = -1; + canque_notify_inends(mess->qedge, CANQUEUE_NOTIFY_ERRTX_SEND); + canque_free_outslot(obj->qends, mess->qedge, mess->slot); + mess->slot=NULL; + } + } + else{ + set_bit(USBCAN_FREE_TX_URB,&dev->flags); + break; + } + } } } @@ -876,8 +980,10 @@ int usbcan_init_chip_data(struct candevice_t *candev, int chipnr) } +/** ********************************* + * USB related functions + * ********************************* */ -/* --------------------------------------------------------------------------------------------------- */ static int usbcan_sleep_thread(struct usbcan_usb *dev) { int rc = 0; @@ -1054,126 +1160,17 @@ int usbcan_kthread(void *data) { /* Normal work to do */ if (test_and_clear_bit(USBCAN_DATA_OK,&dev->flags)){ - int j, len; CANMSG("USBCAN Succesfull data transfer\n"); + if (test_and_clear_bit(USBCAN_DATA_RX,&dev->flags)){ - CANMSG("USBCAN RX handler\n"); - for (i=0;irx[i].flags)){ - CANMSG("USBCAN Thread has received a message\n"); - if ((dev->chip)&&(dev->chip->flags & CHIP_CONFIGURED)){ - u8 *ptr; - struct usbcan_message *mess=&dev->rx[i]; - - len=*(u8 *)(mess->msg+1); - if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; - obj->rx_msg.length = len; - - obj->rx_msg.flags=le16_to_cpu(*(u16 *)(mess->msg+2)); - obj->rx_msg.id=le32_to_cpu((*(u32 *)(mess->msg+4))); - - for(ptr=mess->msg+8,j=0; j < len; ptr++,j++) { - obj->rx_msg.data[j]=*ptr; - } - - // fill CAN message timestamp - can_filltimestamp(&obj->rx_msg.timestamp); - canque_filter_msg2edges(obj->qends, &obj->rx_msg); - } - else - CANMSG("Destination chip not found\n"); - } - if (!test_bit(USBCAN_MESSAGE_URB_PENDING,&dev->rx[i].flags)){ - CANMSG("Renewing RX urb\n"); - retval = usb_submit_urb (dev->rx[i].u, GFP_KERNEL); - if (retval<0){ - CANMSG("%d. URB error %d\n", i, retval); - set_bit(USBCAN_ERROR,&dev->flags); - } - else - set_bit(USBCAN_MESSAGE_URB_PENDING,&dev->rx[i].flags); - } - } + usbcan_kthread_read_handler(dev, obj); } if (test_and_clear_bit(USBCAN_DATA_TX,&dev->flags)){ - CANMSG("USBCAN TX handler\n"); - for (i=0;itx[i].flags)){ - struct usbcan_message *mess=&dev->tx[i]; - CANMSG("USBCAN Message successfully sent\n"); - - if(mess->slot){ - // Do local transmitted message distribution if enabled - if (processlocal){ - // fill CAN message timestamp - can_filltimestamp(&mess->slot->msg.timestamp); - - mess->slot->msg.flags |= MSG_LOCAL; - canque_filter_msg2edges(obj->qends, &mess->slot->msg); - } - // Free transmitted slot - canque_free_outslot(obj->qends, mess->qedge, mess->slot); - mess->slot=NULL; - } - can_msgobj_clear_fl(obj,TX_PENDING); - - set_bit(USBCAN_FREE_TX_URB,&dev->flags); - set_bit(USBCAN_MESSAGE_FREE,&dev->tx[i].flags); - - // Test if some new messages arrived - set_bit(USBCAN_TX_PENDING,&dev->flags); - } - } + usbcan_kthread_write_handler(dev, obj); } } if (test_and_clear_bit(USBCAN_TX_PENDING,&dev->flags)){ - int i, cmd,j,len; - for (i=0;itx[i].flags)){ - struct usbcan_message *mess=&dev->tx[i]; - u8 *ptr; - cmd=canque_test_outslot(obj->qends, &mess->qedge, &mess->slot); - if(cmd>=0){ - CANMSG("USBCAN Sending a message\n"); - - can_msgobj_set_fl(obj,TX_PENDING); - clear_bit(USBCAN_FREE_TX_URB,&dev->flags); - clear_bit(USBCAN_MESSAGE_FREE,&dev->tx[i].flags); - - *(u8 *)(mess->msg)=0; - len = mess->slot->msg.length; - if(len > CAN_MSG_LENGTH) - len = CAN_MSG_LENGTH; - *(u8 *)(mess->msg+1)=len & 0xFF; - *(u16 *)(mess->msg+2)=cpu_to_le16(mess->slot->msg.flags); - *(u32 *)(mess->msg+4)=cpu_to_le32(mess->slot->msg.id); - - for(ptr=mess->msg+8,j=0; j < len; ptr++,j++) { - *ptr=mess->slot->msg.data[j] & 0xFF; - } - for(; j < 8; ptr++,j++) { - *ptr=0; - } - - set_bit(USBCAN_MESSAGE_URB_PENDING,&mess->flags); - retval = usb_submit_urb (dev->tx[i].u, GFP_KERNEL); - if (retval){ - CANMSG("%d. URB error %d\n",i,retval); - clear_bit(USBCAN_MESSAGE_URB_PENDING,&mess->flags); - set_bit(USBCAN_FREE_TX_URB,&dev->flags); - set_bit(USBCAN_MESSAGE_FREE,&dev->tx[i].flags); - obj->ret = -1; - canque_notify_inends(mess->qedge, CANQUEUE_NOTIFY_ERRTX_SEND); - canque_free_outslot(obj->qends, mess->qedge, mess->slot); - mess->slot=NULL; - } - } - else{ - set_bit(USBCAN_FREE_TX_URB,&dev->flags); - break; - } - } - } + usbcan_kthread_write_request_handler(dev, obj); } } } -- 2.39.2