From 3da9fdf0c2e23ade29ba869e4a752b99bdfe844e Mon Sep 17 00:00:00 2001 From: Jan Kriz Date: Tue, 15 Jul 2008 22:33:29 +0200 Subject: [PATCH] minor changes in the code in order to be compilable --- lincan/include/main.h | 3 + lincan/include/usbcan.h | 3 +- lincan/src/usbcan.c | 534 +++++++++++++++++++++------------------- 3 files changed, 285 insertions(+), 255 deletions(-) diff --git a/lincan/include/main.h b/lincan/include/main.h index 651d0c2..296ee2d 100644 --- a/lincan/include/main.h +++ b/lincan/include/main.h @@ -512,3 +512,6 @@ void can_filltimestamp(canmsg_tstamp_t *ptimestamp) #ifdef CAN_WITH_RTL extern int can_rtl_priority; #endif /*CAN_WITH_RTL*/ + +extern struct candevice_t* register_usbdev(const char *hwname,void *anydev); +extern void cleanup_usbdev(struct candevice_t *dev); diff --git a/lincan/include/usbcan.h b/lincan/include/usbcan.h index 94fa0fc..d2be18f 100644 --- a/lincan/include/usbcan.h +++ b/lincan/include/usbcan.h @@ -14,6 +14,7 @@ #include #include #include +#include int usbcan_request_io(struct candevice_t *candev); int usbcan_release_io(struct candevice_t *candev); @@ -40,4 +41,4 @@ int usbcan_irq_handler(int irq, struct canchip_t *chip); int usbcan_init(void); void usbcan_exit(void); -#endif /*USBCAN_H*/ \ No newline at end of file +#endif /*USBCAN_H*/ diff --git a/lincan/src/usbcan.c b/lincan/src/usbcan.c index a66e287..7017123 100644 --- a/lincan/src/usbcan.c +++ b/lincan/src/usbcan.c @@ -8,8 +8,33 @@ #include "../include/can.h" #include "../include/can_sysdep.h" #include "../include/main.h" +#include "../include/devcommon.h" +#include "../include/setup.h" #include "../include/usbcan.h" +/* our private defines. if this grows any larger, use your own .h file */ +#define MAX_TRANSFER (PAGE_SIZE - 512) +/* MAX_TRANSFER is chosen so that the VM is not stressed by + allocations > PAGE_SIZE and the number of packets in a page + is an integer 512 is the largest possible packet on EHCI */ +#define WRITES_IN_FLIGHT 8 +/* arbitrarily chosen */ + +/* Define these values to match your devices */ +#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 usbcan_table [] = { + { USB_DEVICE(USB_SKEL_VENDOR_ID, USB_SKEL_PRODUCT_ID) }, + { } /* Terminating entry */ +}; +MODULE_DEVICE_TABLE(usb, usbcan_table); + +extern struct file_operations can_fops; + +int usbcan_register(struct hwspecops_t *hwspecops); + /* * IO_RANGE is the io-memory range that gets reserved, please adjust according * your hardware. Example: #define IO_RANGE 0x100 for i82527 chips or @@ -17,6 +42,30 @@ */ #define IO_RANGE 0x100 +/* Structure to hold all of our device specific stuff */ +struct usb_usbcan { + 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 usbcan_driver; + /** * usbcan_request_io: - reserve io or memory range for can board * @candev: pointer to candevice/board which asks for io. Field @io_addr @@ -33,12 +82,7 @@ */ int usbcan_request_io(struct candevice_t *candev) { - if (!can_request_io_region(candev->io_addr,IO_RANGE,DEVICE_NAME)) { - CANMSG("Unable to open port: 0x%lx\n",candev->io_addr); - return -ENODEV; - }else { - DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + IO_RANGE - 1); - } + ((struct usb_ul_usb1*)candev->sysdevptr.anydev)->candev=candev; return 0; } @@ -56,7 +100,20 @@ int usbcan_request_io(struct candevice_t *candev) */ int usbcan_release_io(struct candevice_t *candev) { - can_release_io_region(candev->io_addr,IO_RANGE); + 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; } @@ -103,82 +160,6 @@ int usbcan_init_hw_data(struct candevice_t *candev) return 0; } -/** - * usbcan_init_chip_data - Initialize chips - * @candev: Pointer to candevice/board structure - * @chipnr: Number of the CAN chip on the hardware card - * - * The function usbcan_init_chip_data() is used to initialize the hardware - * structure containing information about the CAN chips. - * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or - * "sja1000". - * The @chip_base_addr entry represents the start of the 'official' memory map - * of the installed chip. It's likely that this is the same as the @io_addr - * argument supplied at module loading time. - * The @clock entry holds the chip clock value in Hz. - * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider - * register. Options defined in the %sja1000.h file: - * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN - * The entry @sja_ocr_reg holds hardware specific options for the Output Control - * register. Options defined in the %sja1000.h file: - * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK, - * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ. - * The entry @int_clk_reg holds hardware specific options for the Clock Out - * register. Options defined in the %i82527.h file: - * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1. - * The entry @int_bus_reg holds hardware specific options for the Bus - * Configuration register. Options defined in the %i82527.h file: - * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY. - * The entry @int_cpu_reg holds hardware specific options for the cpu interface - * register. Options defined in the %i82527.h file: - * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST. - * Return Value: The function always returns zero - * File: src/usbcan.c - */ -int usbcan_init_chip_data(struct candevice_t *candev, int chipnr) -{ - canchip_t chip=candev->chip[chipnr]; - - chip->chip_type="usbcan"; - chip->max_objects=1; - usbcan_register(chip->chipspecops); - - CANMSG("initializing usbcan chip operations\n"); - chipspecops->chip_config=usbcan_chip_config; - chipspecops->baud_rate=usbcan_baud_rate; - chipspecops->standard_mask=usbcan_standard_mask; - chipspecops->extended_mask=usbcan_extended_mask; - chipspecops->message15_mask=usbcan_extended_mask; - chipspecops->clear_objects=usbcan_clear_objects; - chipspecops->config_irqs=usbcan_config_irqs; - chipspecops->pre_read_config=usbcan_pre_read_config; - chipspecops->pre_write_config=usbcan_pre_write_config; - chipspecops->send_msg=usbcan_send_msg; - chipspecops->check_tx_stat=usbcan_check_tx_stat; - chipspecops->wakeup_tx=usbcan_wakeup_tx; - chipspecops->remote_request=usbcan_remote_request; - chipspecops->enable_configuration=usbcan_enable_configuration; - chipspecops->disable_configuration=usbcan_disable_configuration; - chipspecops->attach_to_chip=usbcan_attach_to_chip; - chipspecops->release_chip=usbcan_release_chip; - chipspecops->set_btregs=usbcan_set_btregs; - chipspecops->start_chip=usbcan_start_chip; - chipspecops->stop_chip=usbcan_stop_chip; - chipspecops->irq_handler=usbcan_irq_handler; - chipspecops->irq_accept=NULL; - - candev->chip[chipnr]->chip_base_addr=candev->io_addr; - candev->chip[chipnr]->clock = 16000000; - candev->chip[chipnr]->int_cpu_reg = iCPU_DSC; - candev->chip[chipnr]->int_clk_reg = iCLK_SL1; - candev->chip[chipnr]->int_bus_reg = iBUS_CBY; - candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF; - candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | - sjaOCR_TX0_LH; - - return 0; -} - /** * usbcan_init_obj_data - Initialize message buffers * @chip: Pointer to chip specific structure @@ -266,6 +247,8 @@ int usbcan_register(struct hwspecops_t *hwspecops) return 0; } +#ifdef CONFIG_OC_LINCAN_DETAILED_ERRORS + static const char *sja1000_ecc_errc_str[]={ "bit error", "form error", @@ -315,7 +298,7 @@ static int sja1000_report_error_limit_counter; static void sja1000_report_error(struct canchip_t *chip, unsigned sr, unsigned ir, unsigned ecc) { - if(sja1000_report_error_limit_counter>=100) +/* if(sja1000_report_error_limit_counter>=100) return; CANMSG("Error: status register: 0x%x irq_register: 0x%02x error: 0x%02x\n", @@ -357,7 +340,7 @@ static void sja1000_report_error(struct canchip_t *chip, */ int usbcan_enable_configuration(struct canchip_t *chip) { - int i=0; +/* int i=0; enum sja1000_PeliCAN_MOD flags; can_disable_irq(chip->chip_irq); @@ -377,7 +360,7 @@ int usbcan_enable_configuration(struct canchip_t *chip) can_enable_irq(chip->chip_irq); return -ENODEV; } - +*/ return 0; } @@ -387,7 +370,7 @@ int usbcan_enable_configuration(struct canchip_t *chip) */ int usbcan_disable_configuration(struct canchip_t *chip) { - int i=0; +/* int i=0; enum sja1000_PeliCAN_MOD flags; flags=can_read_reg(chip,SJAMOD); @@ -407,7 +390,7 @@ int usbcan_disable_configuration(struct canchip_t *chip) } can_enable_irq(chip->chip_irq); - +*/ return 0; } @@ -425,22 +408,22 @@ int usbcan_disable_configuration(struct canchip_t *chip) */ int usbcan_chip_config(struct canchip_t *chip) { - int i; +/* int i; unsigned char n, r; if (usbcan_enable_configuration(chip)) return -ENODEV; - /* Set mode, clock out, comparator */ + // Set mode, clock out, comparator can_write_reg(chip,sjaCDR_PELICAN|chip->sja_cdr_reg,SJACDR); - /* Ensure, that interrupts are disabled even on the chip level now */ + // Ensure, that interrupts are disabled even on the chip level now can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER); - /* Set driver output configuration */ + // Set driver output configuration can_write_reg(chip,chip->sja_ocr_reg,SJAOCR); - /* Simple check for chip presence */ + // Simple check for chip presence for (i=0, n=0x5a; i<8; i++, n+=0xf) { can_write_reg(chip,n,SJAACR0+i); } @@ -462,11 +445,11 @@ int usbcan_chip_config(struct canchip_t *chip) if (usbcan_baud_rate(chip,chip->baudrate,chip->clock,0,75,0)) return -ENODEV; - /* Enable hardware interrupts */ + // Enable hardware interrupts can_write_reg(chip, sjaENABLE_INTERRUPTS, SJAIER); usbcan_disable_configuration(chip); - +*/ return 0; } @@ -481,7 +464,7 @@ int usbcan_chip_config(struct canchip_t *chip) */ int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned long mask) { - int i; +/* int i; if (usbcan_enable_configuration(chip)) return -ENODEV; @@ -498,7 +481,7 @@ int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned l DEBUGMSG("Setting acceptance mask to 0x%lx\n",(unsigned long)mask); usbcan_disable_configuration(chip); - +*/ return 0; } @@ -517,59 +500,59 @@ int usbcan_extended_mask(struct canchip_t *chip, unsigned long code, unsigned l int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, int sampl_pt, int flags) { - int best_error = 1000000000, error; - int best_tseg=0, best_brp=0, best_rate=0, brp=0; - int tseg=0, tseg1=0, tseg2=0; - - if (usbcan_enable_configuration(chip)) - return -ENODEV; - - clock /=2; - - /* tseg even = round down, odd = round up */ - for (tseg=(0+0+2)*2; tseg<=(sjaMAX_TSEG2+sjaMAX_TSEG1+2)*2+1; tseg++) { - brp = clock/((1+tseg/2)*rate)+tseg%2; - if (brp == 0 || brp > 64) - continue; - error = rate - clock/(brp*(1+tseg/2)); - if (error < 0) - error = -error; - if (error <= best_error) { - best_error = error; - best_tseg = tseg/2; - best_brp = brp-1; - best_rate = clock/(brp*(1+tseg/2)); - } - } - if (best_error && (rate/best_error < 10)) { - CANMSG("baud rate %d is not possible with %d Hz clock\n", - rate, 2*clock); - CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n", - best_rate, best_brp, best_tseg, tseg1, tseg2); - return -EINVAL; - } - tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100; - if (tseg2 < 0) - tseg2 = 0; - if (tseg2 > sjaMAX_TSEG2) - tseg2 = sjaMAX_TSEG2; - tseg1 = best_tseg-tseg2-2; - if (tseg1>sjaMAX_TSEG1) { - tseg1 = sjaMAX_TSEG1; - tseg2 = best_tseg-tseg1-2; - } - - DEBUGMSG("Setting %d bps.\n", best_rate); - DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n", - best_brp, best_tseg, tseg1, tseg2, - (100*(best_tseg-tseg2)/(best_tseg+1))); - - - can_write_reg(chip, sjw<<6 | best_brp, SJABTR0); - can_write_reg(chip, ((flags & BTR1_SAM) != 0)<<7 | (tseg2<<4) - | tseg1, SJABTR1); - - usbcan_disable_configuration(chip); +// int best_error = 1000000000, error; +// int best_tseg=0, best_brp=0, best_rate=0, brp=0; +// int tseg=0, tseg1=0, tseg2=0; +// +// if (usbcan_enable_configuration(chip)) +// return -ENODEV; +// +// clock /=2; +// +// // tseg even = round down, odd = round up +// for (tseg=(0+0+2)*2; tseg<=(sjaMAX_TSEG2+sjaMAX_TSEG1+2)*2+1; tseg++) { +// brp = clock/((1+tseg/2)*rate)+tseg%2; +// if (brp == 0 || brp > 64) +// continue; +// error = rate - clock/(brp*(1+tseg/2)); +// if (error < 0) +// error = -error; +// if (error <= best_error) { +// best_error = error; +// best_tseg = tseg/2; +// best_brp = brp-1; +// best_rate = clock/(brp*(1+tseg/2)); +// } +// } +// if (best_error && (rate/best_error < 10)) { +// CANMSG("baud rate %d is not possible with %d Hz clock\n", +// rate, 2*clock); +// CANMSG("%d bps. brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d\n", +// best_rate, best_brp, best_tseg, tseg1, tseg2); +// return -EINVAL; +// } +// tseg2 = best_tseg-(sampl_pt*(best_tseg+1))/100; +// if (tseg2 < 0) +// tseg2 = 0; +// if (tseg2 > sjaMAX_TSEG2) +// tseg2 = sjaMAX_TSEG2; +// tseg1 = best_tseg-tseg2-2; +// if (tseg1>sjaMAX_TSEG1) { +// tseg1 = sjaMAX_TSEG1; +// tseg2 = best_tseg-tseg1-2; +// } +// +// DEBUGMSG("Setting %d bps.\n", best_rate); +// DEBUGMSG("brp=%d, best_tseg=%d, tseg1=%d, tseg2=%d, sampl_pt=%d\n", +// best_brp, best_tseg, tseg1, tseg2, +// (100*(best_tseg-tseg2)/(best_tseg+1))); +// +// +// can_write_reg(chip, sjw<<6 | best_brp, SJABTR0); +// can_write_reg(chip, ((flags & BTR1_SAM) != 0)<<7 | (tseg2<<4) +// | tseg1, SJABTR1); +// +// usbcan_disable_configuration(chip); return 0; } @@ -582,7 +565,7 @@ int usbcan_baud_rate(struct canchip_t *chip, int rate, int clock, int sjw, * File: src/usbcan.c */ void usbcan_read(struct canchip_t *chip, struct msgobj_t *obj) { - int i, flags, len, datastart; +/* int i, flags, len, datastart; do { flags = can_read_reg(chip,SJAFRM); if(flags&sjaFRM_FF) { @@ -608,14 +591,14 @@ void usbcan_read(struct canchip_t *chip, struct msgobj_t *obj) { obj->rx_msg.data[i]=can_read_reg(chip,datastart+i); } - /* fill CAN message timestamp */ + // fill CAN message timestamp can_filltimestamp(&obj->rx_msg.timestamp); canque_filter_msg2edges(obj->qends, &obj->rx_msg); can_write_reg(chip, sjaCMR_RRB, SJACMR); - } while (can_read_reg(chip, SJASR) & sjaSR_RBS); + } while (can_read_reg(chip, SJASR) & sjaSR_RBS);*/ } /** @@ -629,11 +612,11 @@ void usbcan_read(struct canchip_t *chip, struct msgobj_t *obj) { */ int usbcan_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj) { - int status; +/* int status; status=can_read_reg(chip,SJASR); if(status & sjaSR_BS) { - /* Try to recover from error condition */ + // Try to recover from error condition DEBUGMSG("usbcan_pre_read_config bus-off recover 0x%x\n",status); usbcan_enable_configuration(chip); can_write_reg(chip, 0, SJARXERR); @@ -648,7 +631,7 @@ int usbcan_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj) can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER); //disable interrupts for a moment usbcan_read(chip, obj); - can_write_reg(chip, sjaENABLE_INTERRUPTS, SJAIER); //enable interrupts + can_write_reg(chip, sjaENABLE_INTERRUPTS, SJAIER); //enable interrupts*/ return 1; } @@ -669,19 +652,19 @@ int usbcan_pre_read_config(struct canchip_t *chip, struct msgobj_t *obj) int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg) { - int i=0; +/* int i=0; unsigned int id; int status; int len; - /* Wait until Transmit Buffer Status is released */ + // Wait until Transmit Buffer Status is released while ( !((status=can_read_reg(chip, SJASR)) & sjaSR_TBS) && i++length; if(len > CAN_MSG_LENGTH) len = CAN_MSG_LENGTH; - /* len &= sjaFRM_DLC_M; ensured by above condition already */ + // len &= sjaFRM_DLC_M; ensured by above condition already can_write_reg(chip, ((msg->flags&MSG_EXT)?sjaFRM_FF:0) | ((msg->flags & MSG_RTR) ? sjaFRM_RTR : 0) | len, SJAFRM); if(msg->flags&MSG_EXT) { @@ -730,7 +713,7 @@ int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, for(i=0; i < len; i++) { can_write_reg(chip, msg->data[i], SJADATS+i); } - } + }*/ return 0; } @@ -748,8 +731,8 @@ int usbcan_pre_write_config(struct canchip_t *chip, struct msgobj_t *obj, int usbcan_send_msg(struct canchip_t *chip, struct msgobj_t *obj, struct canmsg_t *msg) { - can_write_reg(chip, sjaCMR_TR, SJACMR); - +/* can_write_reg(chip, sjaCMR_TR, SJACMR); +*/ return 0; } @@ -764,10 +747,10 @@ int usbcan_send_msg(struct canchip_t *chip, struct msgobj_t *obj, */ int usbcan_check_tx_stat(struct canchip_t *chip) { - if (can_read_reg(chip,SJASR) & sjaSR_TCS) +// if (can_read_reg(chip,SJASR) & sjaSR_TCS) return 0; - else - return 1; +// else +// return 1; } /** @@ -782,14 +765,14 @@ int usbcan_check_tx_stat(struct canchip_t *chip) int usbcan_set_btregs(struct canchip_t *chip, unsigned short btr0, unsigned short btr1) { - if (usbcan_enable_configuration(chip)) +/* if (usbcan_enable_configuration(chip)) return -ENODEV; can_write_reg(chip, btr0, SJABTR0); can_write_reg(chip, btr1, SJABTR1); usbcan_disable_configuration(chip); - +*/ return 0; } @@ -802,13 +785,13 @@ int usbcan_set_btregs(struct canchip_t *chip, unsigned short btr0, */ int usbcan_start_chip(struct canchip_t *chip) { - enum sja1000_PeliCAN_MOD flags; +/* enum sja1000_PeliCAN_MOD flags; flags = can_read_reg(chip, SJAMOD) & (sjaMOD_LOM|sjaMOD_STM|sjaMOD_AFM|sjaMOD_SM); can_write_reg(chip, flags, SJAMOD); sja1000_report_error_limit_counter=0; - +*/ return 0; } @@ -821,11 +804,11 @@ int usbcan_start_chip(struct canchip_t *chip) */ int usbcan_stop_chip(struct canchip_t *chip) { - enum sja1000_PeliCAN_MOD flags; +/* enum sja1000_PeliCAN_MOD flags; flags = can_read_reg(chip, SJAMOD) & (sjaMOD_LOM|sjaMOD_STM|sjaMOD_AFM|sjaMOD_SM); can_write_reg(chip, flags|sjaMOD_RM, SJAMOD); - +*/ return 0; } @@ -850,9 +833,9 @@ int usbcan_attach_to_chip(struct canchip_t *chip) */ int usbcan_release_chip(struct canchip_t *chip) { - usbcan_stop_chip(chip); +/* usbcan_stop_chip(chip); can_write_reg(chip, sjaDISABLE_INTERRUPTS, SJAIER); - +*/ return 0; } @@ -926,18 +909,18 @@ int usbcan_config_irqs(struct canchip_t *chip, short irqs) */ void usbcan_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) { - int cmd; +/* int cmd; if(obj->tx_slot){ - /* Do local transmitted message distribution if enabled */ + // Do local transmitted message distribution if enabled if (processlocal){ - /* fill CAN message timestamp */ + // fill CAN message timestamp can_filltimestamp(&obj->tx_slot->msg.timestamp); obj->tx_slot->msg.flags |= MSG_LOCAL; canque_filter_msg2edges(obj->qends, &obj->tx_slot->msg); } - /* Free transmitted slot */ + // Free transmitted slot canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); obj->tx_slot=NULL; } @@ -962,7 +945,7 @@ void usbcan_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) obj->tx_slot=NULL; return; } - +*/ } #define MAX_RETR 10 @@ -981,7 +964,7 @@ void usbcan_irq_write_handler(struct canchip_t *chip, struct msgobj_t *obj) */ int usbcan_irq_handler(int irq, struct canchip_t *chip) { - int irq_register, status, error_code; +/* int irq_register, status, error_code; struct msgobj_t *obj=chip->msgobj[0]; int loop_cnt=CHIP_MAX_IRQLOOP; @@ -1007,16 +990,16 @@ int usbcan_irq_handler(int irq, struct canchip_t *chip) return CANCHIP_IRQ_STUCK; } - /* (irq_register & sjaIR_RI) */ - /* old variant using SJAIR, collides with intended use with irq_accept */ + // (irq_register & sjaIR_RI) + // old variant using SJAIR, collides with intended use with irq_accept if (status & sjaSR_RBS) { DEBUGMSG("sja1000_irq_handler: RI or RBS\n"); usbcan_read(chip,obj); obj->ret = 0; } - /* (irq_register & sjaIR_TI) */ - /* old variant using SJAIR, collides with intended use with irq_accept */ + // (irq_register & sjaIR_TI) + // old variant using SJAIR, collides with intended use with irq_accept if (((status & sjaSR_TBS) && can_msgobj_test_fl(obj,TX_PENDING))|| (can_msgobj_test_fl(obj,TX_REQUEST))) { DEBUGMSG("sja1000_irq_handler: TI or TX_PENDING and TBS\n"); @@ -1043,7 +1026,7 @@ int usbcan_irq_handler(int irq, struct canchip_t *chip) if(error_code == 0xd9) { obj->ret= -ENXIO; - /* no such device or address - no ACK received */ + // no such device or address - no ACK received } if(obj->tx_retry_cnt++>MAX_RETR) { can_write_reg(chip, sjaCMR_AT, SJACMR); // cancel any transmition @@ -1056,8 +1039,8 @@ int usbcan_irq_handler(int irq, struct canchip_t *chip) if(obj->tx_slot){ canque_notify_inends(obj->tx_qedge, CANQUEUE_NOTIFY_ERRTX_BUS); - /*canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); - obj->tx_slot=NULL;*/ + //canque_free_outslot(obj->qends, obj->tx_qedge, obj->tx_slot); + //obj->tx_slot=NULL; } } else { @@ -1077,7 +1060,7 @@ int usbcan_irq_handler(int irq, struct canchip_t *chip) } while((irq_register & (sjaIR_BEI|sjaIR_EPI|sjaIR_DOI|sjaIR_EI|sjaIR_RI)) || (can_msgobj_test_fl(obj,TX_REQUEST) && !can_msgobj_test_fl(obj,TX_LOCK)) || (status & sjaSR_RBS)); - +*/ return CANCHIP_IRQ_HANDLED; } @@ -1095,7 +1078,7 @@ int usbcan_irq_handler(int irq, struct canchip_t *chip) int usbcan_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) { - can_preempt_disable(); +/* can_preempt_disable(); can_msgobj_set_fl(obj,TX_PENDING); can_msgobj_set_fl(obj,TX_REQUEST); @@ -1112,11 +1095,11 @@ int usbcan_wakeup_tx(struct canchip_t *chip, struct msgobj_t *obj) DEBUGMSG("TX looping in usbcan_wakeup_tx\n"); } - can_preempt_enable(); + can_preempt_enable();*/ return 0; } -int usbcan_register(struct chipspecops_t *chipspecops) +int usbcan_chipregister(struct chipspecops_t *chipspecops) { return 0; } @@ -1134,15 +1117,90 @@ int usbcan_fill_chipspecops(struct canchip_t *chip) return 0; } +/** + * usbcan_init_chip_data - Initialize chips + * @candev: Pointer to candevice/board structure + * @chipnr: Number of the CAN chip on the hardware card + * + * The function usbcan_init_chip_data() is used to initialize the hardware + * structure containing information about the CAN chips. + * %CHIP_TYPE represents the type of CAN chip. %CHIP_TYPE can be "i82527" or + * "sja1000". + * The @chip_base_addr entry represents the start of the 'official' memory map + * of the installed chip. It's likely that this is the same as the @io_addr + * argument supplied at module loading time. + * The @clock entry holds the chip clock value in Hz. + * The entry @sja_cdr_reg holds hardware specific options for the Clock Divider + * register. Options defined in the %sja1000.h file: + * %sjaCDR_CLKOUT_MASK, %sjaCDR_CLK_OFF, %sjaCDR_RXINPEN, %sjaCDR_CBP, %sjaCDR_PELICAN + * The entry @sja_ocr_reg holds hardware specific options for the Output Control + * register. Options defined in the %sja1000.h file: + * %sjaOCR_MODE_BIPHASE, %sjaOCR_MODE_TEST, %sjaOCR_MODE_NORMAL, %sjaOCR_MODE_CLOCK, + * %sjaOCR_TX0_LH, %sjaOCR_TX1_ZZ. + * The entry @int_clk_reg holds hardware specific options for the Clock Out + * register. Options defined in the %i82527.h file: + * %iCLK_CD0, %iCLK_CD1, %iCLK_CD2, %iCLK_CD3, %iCLK_SL0, %iCLK_SL1. + * The entry @int_bus_reg holds hardware specific options for the Bus + * Configuration register. Options defined in the %i82527.h file: + * %iBUS_DR0, %iBUS_DR1, %iBUS_DT1, %iBUS_POL, %iBUS_CBY. + * The entry @int_cpu_reg holds hardware specific options for the cpu interface + * register. Options defined in the %i82527.h file: + * %iCPU_CEN, %iCPU_MUX, %iCPU_SLP, %iCPU_PWD, %iCPU_DMC, %iCPU_DSC, %iCPU_RST. + * Return Value: The function always returns zero + * File: src/usbcan.c + */ +int usbcan_init_chip_data(struct candevice_t *candev, int chipnr) +{ + struct canchip_t *chip=candev->chip[chipnr]; + + chip->chip_type="usbcan"; + chip->max_objects=1; + usbcan_chipregister(chip->chipspecops); + + CANMSG("initializing usbcan chip operations\n"); + chip->chipspecops->chip_config=usbcan_chip_config; + chip->chipspecops->baud_rate=usbcan_baud_rate; + chip->chipspecops->standard_mask=usbcan_standard_mask; + chip->chipspecops->extended_mask=usbcan_extended_mask; + chip->chipspecops->message15_mask=usbcan_extended_mask; + chip->chipspecops->clear_objects=usbcan_clear_objects; + chip->chipspecops->config_irqs=usbcan_config_irqs; + chip->chipspecops->pre_read_config=usbcan_pre_read_config; + chip->chipspecops->pre_write_config=usbcan_pre_write_config; + chip->chipspecops->send_msg=usbcan_send_msg; + chip->chipspecops->check_tx_stat=usbcan_check_tx_stat; + chip->chipspecops->wakeup_tx=usbcan_wakeup_tx; + chip->chipspecops->remote_request=usbcan_remote_request; + chip->chipspecops->enable_configuration=usbcan_enable_configuration; + chip->chipspecops->disable_configuration=usbcan_disable_configuration; + chip->chipspecops->attach_to_chip=usbcan_attach_to_chip; + chip->chipspecops->release_chip=usbcan_release_chip; + chip->chipspecops->set_btregs=usbcan_set_btregs; + chip->chipspecops->start_chip=usbcan_start_chip; + chip->chipspecops->stop_chip=usbcan_stop_chip; + chip->chipspecops->irq_handler=usbcan_irq_handler; + chip->chipspecops->irq_accept=NULL; + + candev->chip[chipnr]->chip_base_addr=candev->io_addr; + candev->chip[chipnr]->clock = 16000000; +/* candev->chip[chipnr]->int_cpu_reg = iCPU_DSC; + candev->chip[chipnr]->int_clk_reg = iCLK_SL1; + candev->chip[chipnr]->int_bus_reg = iBUS_CBY; + candev->chip[chipnr]->sja_cdr_reg = sjaCDR_CBP | sjaCDR_CLK_OFF; + candev->chip[chipnr]->sja_ocr_reg = sjaOCR_MODE_NORMAL | + sjaOCR_TX0_LH;*/ + + return 0; +} + /* --------------------------------------------------------------------------------------------------- */ -static void ul_usb1_irq(struct urb *urb) +static void usbcan_irq(struct urb *urb) { - struct usb_ul_usb1 *dev = urb->context; - struct ul_usb1_combo devc; + struct usb_usbcan *dev = urb->context; int retval; CANMSG("Interrupt poll\n"); @@ -1162,9 +1220,6 @@ static void ul_usb1_irq(struct urb *urb) goto exit; } - devc.dev = dev; - devc.urb = urb; - dev->candev->chip[0]->chipspecops->irq_handler(0,dev->candev->chip[0]); CANMSG("Interrupt caught\n"); @@ -1175,7 +1230,7 @@ static void ul_usb1_irq(struct urb *urb) __FUNCTION__, retval); } -static void ul_usb1_delete(struct usb_ul_usb1 *dev) +static void usbcan_delete(struct usb_usbcan *dev) { usb_put_dev(dev->udev); usb_kill_urb(dev->irq); @@ -1189,9 +1244,9 @@ static void ul_usb1_delete(struct usb_ul_usb1 *dev) kfree(dev); } -static int ul_usb1_probe(struct usb_interface *interface, const struct usb_device_id *id) +static int usbcan_probe(struct usb_interface *interface, const struct usb_device_id *id) { - struct usb_ul_usb1 *dev; + struct usb_usbcan *dev; struct usb_host_interface *iface_desc; struct usb_endpoint_descriptor *endpoint; struct candevice_t *candev; @@ -1206,7 +1261,6 @@ static int ul_usb1_probe(struct usb_interface *interface, const struct usb_devic 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); @@ -1239,9 +1293,9 @@ static int ul_usb1_probe(struct usb_interface *interface, const struct usb_devic dev->bulk_out_endpointAddr = endpoint->bEndpointAddress; } - if (!dev->int_in_endpointAddr && +/* if (!dev->int_in_endpointAddr && usb_endpoint_is_int_in(endpoint)) { - /* we found an interrupt 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; @@ -1251,9 +1305,9 @@ static int ul_usb1_probe(struct usb_interface *interface, const struct usb_devic err("Could not allocate int_in_buffer"); goto error; } - } + }*/ } - if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr && dev->int_in_endpointAddr)) { + if (!(dev->bulk_in_endpointAddr && dev->bulk_out_endpointAddr)) { err("Could not find all bulk-in, bulk-out and interrupt endpoints"); goto error; } @@ -1261,36 +1315,9 @@ static int ul_usb1_probe(struct usb_interface *interface, const struct usb_devic /* 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;ihwname,"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); - } + register_usbdev("usbcan",(void *) dev); - dev->irq = usb_alloc_urb(0, GFP_KERNEL); +/* dev->irq = usb_alloc_urb(0, GFP_KERNEL); if (!dev->irq){ CANMSG("Error allocating usb urb\n"); goto error; @@ -1299,33 +1326,33 @@ static int ul_usb1_probe(struct usb_interface *interface, const struct usb_devic 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); + usbcan_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);*/ + usbcan_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"); +// 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); + usbcan_delete(dev); return retval; } -static void ul_usb1_disconnect(struct usb_interface *interface) +static void usbcan_disconnect(struct usb_interface *interface) { - struct usb_ul_usb1 *dev; + struct usb_usbcan *dev; int minor = interface->minor; dev = usb_get_intfdata(interface); @@ -1338,23 +1365,22 @@ static void ul_usb1_disconnect(struct usb_interface *interface) //usb_kill_anchored_urbs(&dev->submitted); - ul_usb1_delete(dev); + usbcan_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, +static struct usb_driver usbcan_driver = { + .name = "usbcan", + .id_table = usbcan_table, + .probe = usbcan_probe, + .disconnect = usbcan_disconnect, }; int usbcan_init(void){ - return usb_register(&ul_usb1_driver); + return usb_register(&usbcan_driver); } void usbcan_exit(void){ - usb_deregister(&ul_usb1_driver); + usb_deregister(&usbcan_driver); } -- 2.39.2