-/* ul_usb1.c
- * Linux CAN-bus device driver.
- * Written by Jan Kriz email:johen@post.cz
- * This software is released under the GPL-License.
- * Version lincan-0.3 17 Jun 2004
- *
- * Based on
- * USB Skeleton driver - 2.2
- *
- * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com)
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation, version 2.
- *
- * This driver is based on the 2.6.3 version of drivers/usb/usb-skeleton.c
- * but has been rewritten to be easier to read and use.
- *
- */
+/**************************************************************************/
+/* File: ul_usb1.c - UL_USB1 board specific part of USB<->CAN converter */
+/* */
+/* LinCAN - (Not only) Linux CAN bus driver */
+/* Copyright (C) 2002-2011 DCE FEE CTU Prague <http://dce.felk.cvut.cz> */
+/* Copyright (C) 2008 Jan Kriz email:johen@post.cz */
+/* */
+/* LinCAN is free software; you can redistribute it and/or modify it */
+/* under terms of the GNU General Public License as published by the */
+/* Free Software Foundation; either version 2, or (at your option) any */
+/* later version. LinCAN is distributed in the hope that it will be */
+/* useful, but WITHOUT ANY WARRANTY; without even the implied warranty */
+/* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */
+/* General Public License for more details. You should have received a */
+/* copy of the GNU General Public License along with LinCAN; see file */
+/* COPYING. If not, write to the Free Software Foundation, 675 Mass Ave, */
+/* Cambridge, MA 02139, USA. */
+/* */
+/* To allow use of LinCAN in the compact embedded systems firmware */
+/* and RT-executives (RTEMS for example), main authors agree with next */
+/* special exception: */
+/* */
+/* Including LinCAN header files in a file, instantiating LinCAN generics */
+/* or templates, or linking other files with LinCAN objects to produce */
+/* an application image/executable, does not by itself cause the */
+/* resulting application image/executable to be covered by */
+/* the GNU General Public License. */
+/* This exception does not however invalidate any other reasons */
+/* why the executable file might be covered by the GNU Public License. */
+/* Publication of enhanced or derived LinCAN files is required although. */
+/**************************************************************************/
-#include "./can/ul_usb1.h"
#include "./can/can.h"
#include "./can/can_sysdep.h"
#include "./can/main.h"
#include "./can/errno.h"
+#include "./can/ul_usb1.h"
+
/* Get a minor range for your devices from the usb maintainer */
#define USB_SKEL_MINOR_BASE 192
#define USB_SKEL_VENDOR_ID 0xDEAD
#define USB_SKEL_PRODUCT_ID 0x1001
-/* table of devices that work with this driver */
-// static struct usb_device_id ul_usb1_table [] = {
-// { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) },
-// { } /* Terminating entry */
-// };
-// MODULE_DEVICE_TABLE(usb, ul_usb1_table);
-
-// extern struct file_operations can_fops;
-
-// struct ul_usb1_combo {
-// struct usb_ul_usb1 * dev;
-// struct urb * urb;
-// };
/*
* IO_RANGE is the io-memory range that gets reserved, please adjust according
*/
#define IO_RANGE 0x100
-/* Structure to hold all of our device specific stuff */
-// struct usb_ul_usb1 {
-// struct usb_device *udev; /* the usb device for this device */
-// struct usb_interface *interface; /* the interface for this device */
-// struct semaphore limit_sem; /* limiting the number of writes in progress */
-// struct usb_anchor submitted; /* in case we need to retract our submissions */
-// unsigned char *bulk_in_buffer; /* the buffer to receive data */
-// size_t bulk_in_size; /* the size of the receive buffer */
-// unsigned char *int_in_buffer; /* the buffer to receive data */
-// size_t int_in_size; /* the size of the receive buffer */
-// __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
-// __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
-// __u8 int_in_endpointAddr; /* the address of the interrupt in endpoint */
-// int int_in_interval;
-// int errors; /* the last request tanked */
-// int open_count; /* count the number of openers */
-// spinlock_t err_lock; /* lock for errors */
-// struct mutex io_mutex; /* synchronize I/O with disconnect */
-// struct urb *irq;
-// struct candevice_t *candev;
-// };
-//
-// static struct usb_driver ul_usb1_driver;
-
/** ul_usb1_request_io
* ul_usb1_request_io: - reserve io or memory range for can board
* @candev: pointer to candevice/board which asks for io. Field @io_addr
*/
int ul_usb1_request_io(struct candevice_t *candev)
{
-// ((struct usb_ul_usb1*)candev->sysdevptr.anydev)->candev=candev;
return 0;
}
*/
int ul_usb1_release_io(struct candevice_t *candev)
{
-/* struct usb_ul_usb1 *dev;
- if (candev->sysdevptr.anydev){
- dev=(struct usb_ul_usb1*) candev->sysdevptr.anydev;
- usb_put_dev(dev->udev);
- usb_kill_urb(dev->irq);
- usb_free_urb(dev->irq);
- kfree(dev->bulk_in_buffer);
- kfree(dev->int_in_buffer);
- if (dev->candev){
- dev->candev->sysdevptr.anydev=NULL;
- //cleanup_usbdev(dev->candev);
- }
- kfree(dev);
- }*/
return 0;
}
*/
int ul_usb1_reset(struct candevice_t *candev)
{
- return 0;
+ return can_init();
}
#define RESET_ADDR 0x0
candev->nr_82527_chips=NR_82527;
candev->nr_sja1000_chips=NR_SJA1000;
candev->nr_all_chips=NR_82527+NR_SJA1000;
- //candev->flags |= CANDEV_PROGRAMMABLE_IRQ;
+ candev->flags |= CANDEV_PROGRAMMABLE_IRQ*0;
return 0;
}
candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL |
sjaOCR_TX0_LH;
+ candev->chip[chipnr]->chip_data=(void *)malloc(sizeof(struct ul_usb1_chip_data));
+ if (candev->chip[chipnr]->chip_data==NULL)
+ return -ENOMEM;
return 0;
}
* Return Value: The function does not return a value
* File: src/ul_usb1.c
*/
-void ul_usb1_write_register(struct candevice_t *candev,unsigned data, unsigned long address)
+void ul_usb1_write_register(unsigned data, unsigned long address)
{
- struct usb_ul_usb1 *dev;
- int retval;
- int bytes_transferred;
- unsigned char buffer[2];
- buffer[0]=((unsigned char)address & ~CAN_OP_MASK)+CAN_OP_WRITE;
- buffer[1]=(unsigned char)data;
-
- dev = (struct usb_ul_usb1 *)candev->sysdevptr.anydev;
-
-// mutex_lock(&dev->io_mutex);
-// if (!dev) { /* disconnect() was called */
-// CANMSG("Sending %lu:%X : ERR No device\n",address,(uint8_t)data);
-// retval = -ENODEV;
-// goto exit;
-// }
-// if (!dev->interface) { /* disconnect() was called */
-// CANMSG("Sending %lu:%X : ERR No interface\n",address,(uint8_t)data);
-// retval = -ENODEV;
-// goto exit;
-// }
-
- /* do a blocking bulk write to send data to the device */
-/* retval = usb_bulk_msg(dev->udev,
- usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
- buffer,
- 2,
- &bytes_transferred, 10000);
- CANMSG("Sending %lu:%X : retval %d, transferred %d bytes\n",address,(uint8_t)data,retval,bytes_transferred);
-
-exit:
- mutex_unlock(&dev->io_mutex);*/
+ can_write(data, address & 0xFF);
}
/** ul_usb1_read_register
* Return Value: The function returns the value stored in @address
* File: src/ul_usb1.c
*/
-unsigned ul_usb1_read_register(struct candevice_t *candev,unsigned long address)
+unsigned ul_usb1_read_register(unsigned long address)
{
- struct usb_ul_usb1 *dev;
- int retval;
- int bytes_transferred;
- unsigned char buffer[2];
- buffer[0]=((unsigned char)address & ~CAN_OP_MASK)+CAN_OP_READ;
- buffer[1]=0x00;
-
- dev = (struct usb_ul_usb1 *)candev->sysdevptr.anydev;
-
-// mutex_lock(&dev->io_mutex);
-// if (!dev) { /* disconnect() was called */
-// retval = -ENODEV;
-// goto exit;
-// }
-// if (!dev->interface) { /* disconnect() was called */
-// retval = -ENODEV;
-// goto exit;
-// }
-
- /* do a blocking bulk write to send data to the device */
-/* retval = usb_bulk_msg(dev->udev,
- usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
- buffer,
- 2,
- &bytes_transferred, 10000);
-
- CANMSG("Requested: %ld : retval %d, transferred %d bytes\n",address,retval,bytes_transferred);
- if ((retval)||(bytes_transferred!=2)){
- retval = -EFAULT;
- goto exit;
- }
-*/
- /* do a blocking bulk read to get data from the device */
-// retval = usb_bulk_msg(dev->udev,
-// usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
-// dev->bulk_in_buffer,
-// dev->bulk_in_size,
-// &bytes_transferred, 10000);
-
- /* if the read was successful, copy the data to userspace */
-/* CANMSG("Received %d bytes : %u:%X\n",bytes_transferred,(dev->bulk_in_buffer[0] & 0x7F),dev->bulk_in_buffer[1]);
- if (!retval) {
- if (bytes_transferred!=2)
- retval = -EFAULT;
- else
- retval = dev->bulk_in_buffer[1];
- }
-
-exit:
- mutex_unlock(&dev->io_mutex);
- return retval;*/
+ uint8_t data;
+ data = can_read(address & 0xFF);
+ return data;
}
/* !!! Don't change this function !!! */
return 0;
}
-
-
-
-/* --------------------------------------------------------------------------------------------------- */
-
-
-// static void ul_usb1_irq(struct urb *urb)
-// {
-// struct usb_ul_usb1 *dev = urb->context;
-// struct ul_usb1_combo devc;
-// int retval;
-//
-// CANMSG("Interrupt poll\n");
-//
-// switch (urb->status) {
-// case 0:
-// /* success */
-// break;
-// case -ECONNRESET:
-// case -ENOENT:
-// case -ESHUTDOWN:
-// /* this urb is terminated, clean up */
-// CANMSG("%s - urb shutting down with status: %d\n", __FUNCTION__, urb->status);
-// return;
-// default:
-// CANMSG("%s - nonzero urb status received: %d\n", __FUNCTION__, urb->status);
-// goto exit;
-// }
-//
-// devc.dev = dev;
-// devc.urb = urb;
-//
-// dev->candev->chip[0]->chipspecops->irq_handler(0,dev->candev->chip[0]);
-// CANMSG("Interrupt caught\n");
-//
-// exit:
-// retval = usb_submit_urb (urb, GFP_ATOMIC);
-// if (retval)
-// CANMSG("%s - usb_submit_urb failed with result %d\n",
-// __FUNCTION__, retval);
-// }
-
-// static void ul_usb1_delete(struct usb_ul_usb1 *dev)
-// {
-// usb_put_dev(dev->udev);
-// usb_kill_urb(dev->irq);
-// usb_free_urb(dev->irq);
-// kfree(dev->bulk_in_buffer);
-// kfree(dev->int_in_buffer);
-// if (dev->candev){
-// dev->candev->sysdevptr.anydev=NULL;
-// cleanup_usbdev(dev->candev);
-// }
-// kfree(dev);
-// }
-
-// static int ul_usb1_probe(struct usb_interface *interface, const struct usb_device_id *id)
-// {
-// struct usb_ul_usb1 *dev;
-// struct usb_host_interface *iface_desc;
-// struct usb_endpoint_descriptor *endpoint;
-// struct candevice_t *candev;
-// size_t buffer_size;
-// int i;
-// int retval = -ENOMEM;
-//
-// /* allocate memory for our device state and initialize it */
-// dev = kzalloc(sizeof(*dev), GFP_KERNEL);
-// if (!dev) {
-// err("Out of memory");
-// goto error;
-// }
-// sema_init(&dev->limit_sem, WRITES_IN_FLIGHT);
-// mutex_init(&dev->io_mutex);
-// spin_lock_init(&dev->err_lock);
-// init_usb_anchor(&dev->submitted);
-//
-// // dev->udev = usb_get_dev(interface_to_usbdev(interface));
-// dev->udev = interface_to_usbdev(interface);
-// dev->interface = interface;
-//
-// /* set up the endpoint information */
-// /* use only the first bulk-in and bulk-out endpoints */
-// iface_desc = interface->cur_altsetting;
-// for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
-// endpoint = &iface_desc->endpoint[i].desc;
-//
-// if (!dev->bulk_in_endpointAddr &&
-// usb_endpoint_is_bulk_in(endpoint)) {
-// /* we found a bulk in endpoint */
-// buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
-// dev->bulk_in_size = buffer_size;
-// dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
-// dev->bulk_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
-// if (!dev->bulk_in_buffer) {
-// err("Could not allocate bulk_in_buffer");
-// goto error;
-// }
-// }
-//
-// if (!dev->bulk_out_endpointAddr &&
-// usb_endpoint_is_bulk_out(endpoint)) {
-// /* we found a bulk out endpoint */
-// dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
-// }
-//
-// if (!dev->int_in_endpointAddr &&
-// usb_endpoint_is_int_in(endpoint)) {
-// /* we found an interrupt in endpoint */
-// buffer_size = le16_to_cpu(endpoint->wMaxPacketSize);
-// dev->int_in_size = buffer_size;
-// dev->int_in_endpointAddr = endpoint->bEndpointAddress;
-// dev->int_in_buffer = kmalloc(buffer_size, GFP_KERNEL);
-// dev->int_in_interval = endpoint->bInterval;
-// if (!dev->int_in_buffer) {
-// err("Could not allocate int_in_buffer");
-// goto error;
-// }
-// }
-// }
-// if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr && dev->int_in_endpointAddr)) {
-// err("Could not find all bulk-in, bulk-out and interrupt endpoints");
-// goto error;
-// }
-//
-// /* save our data pointer in this interface device */
-// usb_set_intfdata(interface, dev);
-//
-// if (main_init_done==1)
-// register_usbdev("ul_usb1",(void *) dev);
-// else {
-// mutex_lock(&usbdev_reg_mutex);
-// if (main_init_done==1)
-// register_usbdev("ul_usb1",(void *) dev);
-// else {
-// for (i=0;i<MAX_HW_CARDS;i++){
-// if (usbregq[i]==NULL){
-// usbregq[i]=(struct usbdev_reg_query *)can_checked_malloc(sizeof(struct usbdev_reg_query));
-// if (!usbregq[i]){
-// CANMSG("Error allocating usbdev_reg_query");
-// mutex_unlock(&usbdev_reg_mutex);
-// goto error;
-// }
-// sprintf (usbregq[i]->hwname,"ul_usb1");
-// usbregq[i]->anydev=(void *) dev;
-// break;
-// }
-// }
-// if (i==MAX_HW_CARDS){
-// CANMSG("No free space to register new card");
-// mutex_unlock(&usbdev_reg_mutex);
-// goto error;
-// }
-// }
-// mutex_unlock(&usbdev_reg_mutex);
-// }
-//
-// dev->irq = usb_alloc_urb(0, GFP_KERNEL);
-// if (!dev->irq){
-// CANMSG("Error allocating usb urb\n");
-// goto error;
-// }
-// dev->irq->dev = dev->udev;
-// usb_fill_int_urb(dev->irq, dev->udev,
-// usb_rcvintpipe(dev->udev, dev->int_in_endpointAddr),
-// dev->int_in_buffer, dev->int_in_size,
-// ul_usb1_irq, dev, dev->int_in_interval);
-// /* usb_fill_bulk_urb(dev->irq, dev->udev,
-// usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
-// dev->int_in_buffer, dev->int_in_size,
-// ul_usb1_irq, dev);*/
-//
-// /* dev->irq->transfer_dma = wacom->data_dma;
-// dev->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;*/
-// retval=usb_submit_urb(dev->irq, GFP_KERNEL);
-// if (retval){
-// CANMSG("INT URB %d\n",retval);
-// return -EIO;
-// }else
-// CANMSG("INT URB SUCCCESS\n");
-//
-// /* let the user know what node this device is now attached to */
-// info("USB Skeleton device now attached");
-// return 0;
-//
-// error:
-// ul_usb1_delete(dev);
-// return retval;
-// }
-
-// static void ul_usb1_disconnect(struct usb_interface *interface)
-// {
-// struct usb_ul_usb1 *dev;
-// int minor = interface->minor;
-//
-// dev = usb_get_intfdata(interface);
-// usb_set_intfdata(interface, NULL);
-//
-// /* prevent more I/O from starting */
-// mutex_lock(&dev->io_mutex);
-// dev->interface = NULL;
-// mutex_unlock(&dev->io_mutex);
-//
-// //usb_kill_anchored_urbs(&dev->submitted);
-//
-// ul_usb1_delete(dev);
-//
-// info("USB Skeleton now disconnected");
-// }
-
-// static struct usb_driver ul_usb1_driver = {
-// .name = "ul_usb1-can",
-// .id_table = ul_usb1_table,
-// .probe = ul_usb1_probe,
-// .disconnect = ul_usb1_disconnect,
-// .id_table = ul_usb1_table,
-// };
-
-// int ul_usb1_init(void){
-// return usb_register(&ul_usb1_driver);
-// }
-//
-// void ul_usb1_exit(void){
-// usb_deregister(&ul_usb1_driver);
-// }