X-Git-Url: http://rtime.felk.cvut.cz/gitweb/lincan.git/blobdiff_plain/24dde2b186e49d6d597d5a02e2b5f51e2147ca6e..f9522530e37184c3dcfb818a35f55ec3f177406f:/lincan/src/usbcan.c diff --git a/lincan/src/usbcan.c b/lincan/src/usbcan.c index cb1c9b0..a18f862 100644 --- a/lincan/src/usbcan.c +++ b/lincan/src/usbcan.c @@ -5,7 +5,6 @@ * Version lincan-0.3 17 Jul 2008 */ -#include "../include/kthread.h" #include "../include/can.h" #include "../include/can_sysdep.h" #include "../include/main.h" @@ -13,6 +12,23 @@ #include "../include/setup.h" #include "../include/usbcan.h" +static int usbcan_probe(struct usb_interface *interface, const struct usb_device_id *id); +static void usbcan_disconnect(struct usb_interface *interface); + +/* table of devices that work with this driver */ +static struct usb_device_id usbcan_table [] = { + { USB_DEVICE(USBCAN_VENDOR_ID, USBCAN_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, usbcan_table); + +static struct usb_driver usbcan_driver = { + .name = "usbcan", + .id_table = usbcan_table, + .probe = usbcan_probe, + .disconnect = usbcan_disconnect, +}; + /** * usbcan_request_io: - reserve io or memory range for can board * @candev: pointer to candevice/board which asks for io. Field @io_addr @@ -253,17 +269,17 @@ int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned l int retval; struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev; - struct usbcan_mask_t mask={ - .code=code; - .mask=mask; - }; + __u8 usbbuf[16]; + + *(uint32_t *)(usbbuf)=cpu_to_le32(mask); + *(uint32_t *)(usbbuf+4)=cpu_to_le32(code); retval=usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ctl_out_endpointAddr), USBCAN_VENDOR_EXT_MASK_SET, USB_TYPE_VENDOR, 0, chip->chip_idx, - &mask, sizeof(usbcan_mask_t), + &usbbuf, 16, 10000); if (retval<0) return -ENODEV; @@ -273,11 +289,11 @@ int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned l USBCAN_VENDOR_EXT_MASK_STATUS, USB_TYPE_VENDOR, 0, chip->chip_idx, - dev->ctl_in_buffer, dev->ctl_in_size, + &usbbuf, 16, 10000); - if (retval==1){ - if(dev->ctl_in_buffer[0]==1){ + if (retval==16){ + if(usbbuf[0]==1){ DEBUGMSG("Setting acceptance code to 0x%lx\n",(unsigned long)code); DEBUGMSG("Setting acceptance mask to 0x%lx\n",(unsigned long)mask); return 0; @@ -306,21 +322,19 @@ int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int retval; struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev; - // Data too big to use single receive control message - struct can_baudparams_t baud={ - .flags=flags, - .baudrate=rate, - .sjw=sjw, - .sample_pt=sampl_pt, - }; + __u8 usbbuf[16]; + *(int32_t *)(usbbuf)=cpu_to_le32(rate); + *(int32_t *)(usbbuf+4)=cpu_to_le32(sjw); + *(int32_t *)(usbbuf+8)=cpu_to_le32(sampl_pt); + *(int32_t *)(usbbuf+12)=cpu_to_le32(flags); retval=usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ctl_out_endpointAddr), USBCAN_VENDOR_BAUD_RATE_SET, USB_TYPE_VENDOR, 0, chip->chip_idx, - &baud, sizeof(can_baudparams_t), + &usbbuf, 16, 10000); if (retval<0) return -ENODEV; @@ -330,11 +344,11 @@ int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, USBCAN_VENDOR_BAUD_RATE_STATUS, USB_TYPE_VENDOR, 0, chip->chip_idx, - dev->ctl_in_buffer, dev->ctl_in_size, + usbbuf, 16, 10000); - if (retval==1){ - if(dev->ctl_in_buffer[0]==1) + if (retval==16){ + if(usbbuf[0]==1) return 0; } @@ -377,6 +391,7 @@ int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev; int i=0; int len; + __u8 *ptr; /* Wait until Transmit Buffer Status is released */ while ( usbcan_chip_queue_status(chip) && @@ -388,29 +403,20 @@ int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, return -EIO; } - dev->tx_msg.chip_id=(__u8)chip->chip_idx; + *(uint8_t *)(dev->tx_msg)=chip->chip_idx & 0xFF; len = msg->length; if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; - dev->tx_msg.length=(__u8)len; - dev->tx_msg.flags=(__u16)msg->flags; - - if(msg->flags&MSG_EXT) { - dev->tx_msg.id[0]=(msg->id) & 0xff; - dev->tx_msg.id[1]=(msg->id>>8) & 0xff; - dev->tx_msg.id[2]=(msg->id>>16) & 0xff; - dev->tx_msg.id[3]=(msg->id>>24) & 0xff; - } else { - dev->tx_msg.id[0]=(msg->id) & 0xff; - dev->tx_msg.id[1]=(msg->id>>8) & 0xff; - dev->tx_msg.id[2]=0; - dev->tx_msg.id[3]=0; - } - for(i=0; i < len; i++) { - dev->tx_msg.data[i]=(__u8) msg->data[i]; + + *(uint8_t *)(dev->tx_msg+1)=len & 0xFF; + *(uint16_t *)(dev->tx_msg+2)=cpu_to_le16(msg->flags); + *(uint32_t *)(dev->tx_msg+4)=cpu_to_le32(msg->id); + + for(ptr=dev->tx_msg+8,i=0; i < len; ptr++,i++) { + *ptr=msg->data[i] & 0xFF; } - for(i; i < 8; i++) { - dev->tx_msg.data[i]=0; + for(; i < 8; ptr++,i++) { + *ptr=0; } return 0; } @@ -430,12 +436,12 @@ int usbcan_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg) { struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev; - int len; + int len,retval; set_bit(USBCAN_TX_PENDING,&dev->flags); retval=usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr), - &dev->tx_msg, sizeof(usbcan_canmsg_t), + &dev->tx_msg, 16, &len,10000); clear_bit(USBCAN_TX_PENDING,&dev->flags); if (retval){ @@ -480,12 +486,13 @@ int usbcan_set_btregs(struct canchip_t *chip, unsigned short btr0, { int retval; struct usbcan_usb *dev=(struct usbcan_usb*)chip->hostdevice->sysdevptr.anydev; + uint16_t value=(btr1&0xFF)<<8 | (btr0&0xFF); retval = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev, dev->ctl_in_endpointAddr), USBCAN_VENDOR_SET_BTREGS, USB_TYPE_VENDOR, - btr1<<8 | btr0, chip->chip_idx, + cpu_to_le16(value), chip->chip_idx, dev->ctl_in_buffer, dev->ctl_in_size, 10000); @@ -547,9 +554,9 @@ int usbcan_chip_queue_status(struct canchip_t *chip) if (retval==1){ if(dev->ctl_in_buffer[0]==1) - return 1; - if(dev->ctl_in_buffer[0]==0) return 0; + if(dev->ctl_in_buffer[0]==0) + return 1; } return -ENODEV; } @@ -1003,7 +1010,7 @@ void usbcan_read_kthread(kthread_t *kthread) dev->rcv->dev = dev->udev; usb_fill_bulk_urb(dev->rcv, dev->udev, usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr), - &dev->rcv_msg, sizeof(usbcan_canmsg_t), + &dev->rcv_msg, 16, usbcan_rcv, dev); /* an endless loop in which we are doing our work */ @@ -1016,9 +1023,9 @@ void usbcan_read_kthread(kthread_t *kthread) } /* fall asleep */ wait_event_interruptible(kthread->queue, - test_bit(USBCAN_CHIP_DATA_READ,&chip_data->flags) - || test_bit(USBCAN_CHIP_TERMINATE,&chip_data->flags) - || test_bit(USBCAN_CHIP_ERROR,&chip_data->flags) + test_bit(USBCAN_DATA_READ,&dev->flags) + || test_bit(USBCAN_TERMINATE,&dev->flags) + || test_bit(USBCAN_ERROR,&dev->flags) ); /* We need to do a memory barrier here to be sure that @@ -1032,37 +1039,32 @@ void usbcan_read_kthread(kthread_t *kthread) break; } - if (test_bit(USBCAN_CHIP_ERROR,&chip_data->flags)){ + if (test_bit(USBCAN_ERROR,&dev->flags)){ CANMSG("URB error %d\n",retval); break; } { /* Normal work to do */ - if (test_bit(USBCAN_CHIP_DATA_READ,&chip_data->flags)){ + if (test_bit(USBCAN_DATA_READ,&dev->flags)){ int i, len; - clear_bit(USBCAN_CHIP_DATA_READ,&chip_data->flags); - - if ((dev->candev->chip[dev->rcv_msg.chip_id])&& - (dev->candev->chip[dev->rcv_msg.chip_id].flags & CHIP_CONFIGURED)){ - - obj=dev->candev->chip[dev->rcv_msg.chip_id]->msgobj[0]; - if (dev->rcv_msg.flags & MSG_EXT) { - obj->rx_msg.id = - (dev->rcv_msg.id[0]) + - (dev->rcv_msg.id[1]<<8) + - (dev->rcv_msg.id[2]<<16) + - (dev->rcv_msg.id[3]<<24); - } else { - obj->rx_msg.id = - (dev->rcv_msg.id[0]) + - (dev->rcv_msg.id[1]<<8); - } - obj->rx_msg.flags = dev->rcv_msg.flags; - len=dev->rcv_msg.length; + clear_bit(USBCAN_DATA_READ,&dev->flags); + + if ((dev->candev->chip[dev->rcv_msg[0]])&& + (dev->candev->chip[dev->rcv_msg[0]]->flags & CHIP_CONFIGURED) + ){ + __u8 *ptr; + + obj=dev->candev->chip[dev->rcv_msg[0]]->msgobj[0]; + + len=*(uint8_t *)(dev->rcv_msg+1); if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; obj->rx_msg.length = len; - for(i=0; i< len; i++) { - obj->rx_msg.data[i]=obj->rx_msg.data[i]; + + obj->rx_msg.flags=le16_to_cpu(*(uint16_t *)(dev->rcv_msg+2)); + obj->rx_msg.id=le32_to_cpu((*(uint32_t *)(dev->rcv_msg+4))); + + for(ptr=dev->rcv_msg+8,i=0; i < len; ptr++,i++) { + obj->rx_msg.data[i]=*ptr; } // fill CAN message timestamp