ems_usb.c revision 8e95a2026f3b43f7c3d676adaccd2de9532e8dcc
1702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 2702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CAN driver for EMS Dr. Thomas Wuensche CPC-USB/ARM7 3702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 4702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Copyright (C) 2004-2009 EMS Dr. Thomas Wuensche 5702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 6702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * This program is free software; you can redistribute it and/or modify it 7702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * under the terms of the GNU General Public License as published 8702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * by the Free Software Foundation; version 2 of the License. 9702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 10702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * This program is distributed in the hope that it will be useful, but 11702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * WITHOUT ANY WARRANTY; without even the implied warranty of 12702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * General Public License for more details. 14702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 15702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * You should have received a copy of the GNU General Public License along 16702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * with this program; if not, write to the Free Software Foundation, Inc., 17702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 18702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 19702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/init.h> 20702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/signal.h> 21702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/slab.h> 22702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/module.h> 23702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/netdevice.h> 24702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/usb.h> 25702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 26702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/can.h> 27702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/can/dev.h> 28702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#include <linux/can/error.h> 29702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 30702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_AUTHOR("Sebastian Haas <haas@ems-wuensche.com>"); 31702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_DESCRIPTION("CAN driver for EMS Dr. Thomas Wuensche CAN/USB interfaces"); 32702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_LICENSE("GPL v2"); 33702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 34702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Control-Values for CPC_Control() Command Subject Selection */ 35702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CAN_MESSAGE 0x04 36702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CAN_STATE 0x0C 37702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_BUS_ERROR 0x1C 38702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 39702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Control Command Actions */ 40702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CONT_OFF 0 41702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_CONT_ON 1 42702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CONTR_ONCE 2 43702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 44702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Messages from CPC to PC */ 45702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_FRAME 1 /* CAN data frame */ 46702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_RTR_FRAME 8 /* CAN remote frame */ 47702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_PARAMS 12 /* Actual CAN parameters */ 48702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_STATE 14 /* CAN state message */ 49702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_EXT_CAN_FRAME 16 /* Extended CAN data frame */ 50702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_EXT_RTR_FRAME 17 /* Extended remote frame */ 51702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CONTROL 19 /* change interface behavior */ 52702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CONFIRM 20 /* command processed confirmation */ 53702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_OVERRUN 21 /* overrun events */ 54702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_CAN_FRAME_ERROR 23 /* detected bus errors */ 55702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_TYPE_ERR_COUNTER 25 /* RX/TX error counter */ 56702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 57702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Messages from the PC to the CPC interface */ 58702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_FRAME 1 /* CAN data frame */ 59702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CONTROL 3 /* control of interface behavior */ 60702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_PARAMS 6 /* set CAN parameters */ 61702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_RTR_FRAME 13 /* CAN remote frame */ 62702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_STATE 14 /* CAN state message */ 63702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_EXT_CAN_FRAME 15 /* Extended CAN data frame */ 64702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_EXT_RTR_FRAME 16 /* Extended CAN remote frame */ 65702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CAN_EXIT 200 /* exit the CAN */ 66702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 67702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_INQ_ERR_COUNTER 25 /* request the CAN error counters */ 68702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CLEAR_MSG_QUEUE 8 /* clear CPC_MSG queue */ 69702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CMD_TYPE_CLEAR_CMD_QUEUE 28 /* clear CPC_CMD queue */ 70702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 71702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CC_TYPE_SJA1000 2 /* Philips basic CAN controller */ 72702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 73702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CAN_ECODE_ERRFRAME 0x01 /* Ecode type */ 74702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 75702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Overrun types */ 76702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_EVENT_CAN 0x01 77702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_EVENT_CANSTATE 0x02 78702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_EVENT_BUSERROR 0x04 79702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 80702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 81702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * If the CAN controller lost a message we indicate it with the highest bit 82702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * set in the count field. 83702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 84702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_OVR_HW 0x80 85702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 86702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Size of the "struct ems_cpc_msg" without the union */ 87702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_MSG_HEADER_LEN 11 88702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_CAN_MSG_MIN_SIZE 5 89702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 90702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Define these values to match your devices */ 91702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define USB_CPCUSB_VENDOR_ID 0x12D6 92702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 93702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define USB_CPCUSB_ARM7_PRODUCT_ID 0x0444 94702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 95702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Mode register NXP LPC2119/SJA1000 CAN Controller */ 96702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_MOD_NORMAL 0x00 97702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_MOD_RM 0x01 98702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 99702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* ECC register NXP LPC2119/SJA1000 CAN Controller */ 100702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_SEG 0x1F 101702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_DIR 0x20 102702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_ERR 0x06 103702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_BIT 0x00 104702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_FORM 0x40 105702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_STUFF 0x80 106702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_ECC_MASK 0xc0 107702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 108702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Status register content */ 109702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_SR_BS 0x80 110702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_SR_ES 0x40 111702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 112702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define SJA1000_DEFAULT_OUTPUT_CONTROL 0xDA 113702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 114702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 115702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * The device actually uses a 16MHz clock to generate the CAN clock 116702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * but it expects SJA1000 bit settings based on 8MHz (is internally 117702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * converted). 118702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 119702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define EMS_USB_ARM7_CLOCK 8000000 120702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 121702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 122702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CAN-Message representation in a CPC_MSG. Message object type is 123702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CPC_MSG_TYPE_CAN_FRAME or CPC_MSG_TYPE_RTR_FRAME or 124702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * CPC_MSG_TYPE_EXT_CAN_FRAME or CPC_MSG_TYPE_EXT_RTR_FRAME. 125702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 126702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_msg { 127702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 id; 128702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 length; 129702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 msg[8]; 130702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 131702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 132702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Representation of the CAN parameters for the SJA1000 controller */ 133702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_sja1000_params { 134702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 mode; 135702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code0; 136702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code1; 137702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code2; 138702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_code3; 139702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask0; 140702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask1; 141702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask2; 142702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 acc_mask3; 143702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 btr0; 144702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 btr1; 145702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 outp_contr; 146702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 147702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 148702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* CAN params message representation */ 149702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_params { 150702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 cc_type; 151702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 152702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Will support M16C CAN controller in the future */ 153702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas union { 154702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_sja1000_params sja1000; 155702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } cc_params; 156702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 157702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 158702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Structure for confirmed message handling */ 159702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_confirm { 160702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 error; /* error code */ 161702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 162702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 163702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Structure for overrun conditions */ 164702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_overrun { 165702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 event; 166702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 count; 167702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 168702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 169702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* SJA1000 CAN errors (compatible to NXP LPC2119) */ 170702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_sja1000_can_error { 171702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 ecc; 172702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 rxerr; 173702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 txerr; 174702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 175702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 176702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* structure for CAN error conditions */ 177702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_error { 178702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 ecode; 179702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 180702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct { 181702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 cc_type; 182702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 183702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Other controllers may also provide error code capture regs */ 184702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas union { 185702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_sja1000_can_error sja1000; 186702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } regs; 187702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } cc; 188702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 189702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 190702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 191702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Structure containing RX/TX error counter. This structure is used to request 192702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * the values of the CAN controllers TX and RX error counter. 193702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 194702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct cpc_can_err_counter { 195702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 rx; 196702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 tx; 197702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 198702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 199702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* Main message type used between library and application */ 200702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct __attribute__ ((packed)) ems_cpc_msg { 201702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 type; /* type of message */ 202702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 length; /* length of data within union 'msg' */ 203702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 msgid; /* confirmation handle */ 204702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 ts_sec; /* timestamp in seconds */ 205702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 ts_nsec; /* timestamp in nano seconds */ 206702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 207702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas union { 208702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 generic[64]; 209702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_msg can_msg; 210702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_params can_params; 211702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_confirm confirmation; 212702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_overrun overrun; 213702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_error error; 214702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_can_err_counter err_counter; 215702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 can_state; 216702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } msg; 217702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 218702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 219702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 220702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Table of devices that work with this driver 221702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * NOTE: This driver supports only CPC-USB/ARM7 (LPC2119) yet. 222702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 223702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic struct usb_device_id ems_usb_table[] = { 224702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas {USB_DEVICE(USB_CPCUSB_VENDOR_ID, USB_CPCUSB_ARM7_PRODUCT_ID)}, 225702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas {} /* Terminating entry */ 226702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 227702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 228702171adeed3607ee9603ec30ce081411e36ae42Sebastian HaasMODULE_DEVICE_TABLE(usb, ems_usb_table); 229702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 230702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define RX_BUFFER_SIZE 64 231702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define CPC_HEADER_SIZE 4 232702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define INTR_IN_BUFFER_SIZE 4 233702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 234702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas#define MAX_RX_URBS 10 235a6e4bc5304033e434fabccabb230b8e9ff55d76fWolfgang Grandegger#define MAX_TX_URBS 10 236702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 237702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct ems_usb; 238702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 239702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct ems_tx_urb_context { 240702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev; 241702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 242702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u32 echo_index; 243702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 dlc; 244702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 245702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 246702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstruct ems_usb { 247702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_priv can; /* must be the first member */ 248702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int open_time; 249702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 250702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct sk_buff *echo_skb[MAX_TX_URBS]; 251702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 252702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct usb_device *udev; 253702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 254702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 255702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_t active_tx_urbs; 256702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct usb_anchor tx_submitted; 257702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_tx_urb_context tx_contexts[MAX_TX_URBS]; 258702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 259702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct usb_anchor rx_submitted; 260702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 261702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct urb *intr_urb; 262702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 263702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *tx_msg_buffer; 264702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 265702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *intr_in_buffer; 266702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unsigned int free_slots; /* remember number of available slots */ 267702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 268702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg active_params; /* active controller parameters */ 269702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 270702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 271702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_read_interrupt_callback(struct urb *urb) 272702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 273702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = urb->context; 274702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev = dev->netdev; 275702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int err; 276702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 277702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netif_device_present(netdev)) 278702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 279702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 280702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (urb->status) { 281702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case 0: 282702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->free_slots = dev->intr_in_buffer[1]; 283702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 284702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 285702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ECONNRESET: /* unlink */ 286702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ENOENT: 287702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ESHUTDOWN: 288702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 289702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 290702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 291702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "Rx interrupt aborted %d\n", 292702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->status); 293702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 294702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 295702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 296702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(urb, GFP_ATOMIC); 297702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 298702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) 299702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(netdev); 300702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas else if (err) 301702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 302702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "failed resubmitting intr urb: %d\n", err); 303702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 304702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 305702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 306702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 307702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_rx_can_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) 308702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 309702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_frame *cf; 310702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct sk_buff *skb; 311702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i; 312702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device_stats *stats = &dev->netdev->stats; 313702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3147b6856a0296a8f187bb88ba31fa83a08abba7966Wolfgang Grandegger skb = alloc_can_skb(dev->netdev, &cf); 315702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (skb == NULL) 316702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 317702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3182b2072e902848a63168570f500a5726744b3873aSebastian Haas cf->can_id = le32_to_cpu(msg->msg.can_msg.id); 319702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_dlc = min_t(u8, msg->msg.can_msg.length, 8); 320702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3218e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if (msg->type == CPC_MSG_TYPE_EXT_CAN_FRAME || 3228e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) 323702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_EFF_FLAG; 324702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3258e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches if (msg->type == CPC_MSG_TYPE_RTR_FRAME || 3268e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches msg->type == CPC_MSG_TYPE_EXT_RTR_FRAME) { 327702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_RTR_FLAG; 328702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 329702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < cf->can_dlc; i++) 330702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[i] = msg->msg.can_msg.msg[i]; 331702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 332702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 333702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_rx(skb); 334702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 335702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_packets++; 336702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_bytes += cf->can_dlc; 337702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 338702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 339702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_rx_err(struct ems_usb *dev, struct ems_cpc_msg *msg) 340702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 341702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_frame *cf; 342702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct sk_buff *skb; 343702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device_stats *stats = &dev->netdev->stats; 344702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 3457b6856a0296a8f187bb88ba31fa83a08abba7966Wolfgang Grandegger skb = alloc_can_err_skb(dev->netdev, &cf); 346702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (skb == NULL) 347702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 348702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 349702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (msg->type == CPC_MSG_TYPE_CAN_STATE) { 350702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 state = msg->msg.can_state; 351702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 352702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (state & SJA1000_SR_BS) { 353702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_BUS_OFF; 354702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_ERR_BUSOFF; 355702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 356702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_bus_off(dev->netdev); 357702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else if (state & SJA1000_SR_ES) { 358702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_ERROR_WARNING; 359702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.can_stats.error_warning++; 360702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 361702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_ERROR_ACTIVE; 362702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.can_stats.error_passive++; 363702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 364702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else if (msg->type == CPC_MSG_TYPE_CAN_FRAME_ERROR) { 365702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 ecc = msg->msg.error.cc.regs.sja1000.ecc; 366702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 txerr = msg->msg.error.cc.regs.sja1000.txerr; 367702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 rxerr = msg->msg.error.cc.regs.sja1000.rxerr; 368702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 369702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* bus error interrupt */ 370702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.can_stats.bus_error++; 371702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_errors++; 372702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 373702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; 374702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 375702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (ecc & SJA1000_ECC_MASK) { 376702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case SJA1000_ECC_BIT: 377702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_BIT; 378702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 379702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case SJA1000_ECC_FORM: 380702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_FORM; 381702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 382702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case SJA1000_ECC_STUFF: 383702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_STUFF; 384702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 385702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 386702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_UNSPEC; 387702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[3] = ecc & SJA1000_ECC_SEG; 388702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 389702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 390702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 391702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Error occured during transmission? */ 392702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if ((ecc & SJA1000_ECC_DIR) == 0) 393702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[2] |= CAN_ERR_PROT_TX; 394702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 395702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev->can.state == CAN_STATE_ERROR_WARNING || 396702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state == CAN_STATE_ERROR_PASSIVE) { 397702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[1] = (txerr > rxerr) ? 398702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas CAN_ERR_CRTL_TX_PASSIVE : CAN_ERR_CRTL_RX_PASSIVE; 399702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 400702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else if (msg->type == CPC_MSG_TYPE_OVERRUN) { 401702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->can_id |= CAN_ERR_CRTL; 402702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cf->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; 403702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 404702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_over_errors++; 405702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_errors++; 406702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 407702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 408702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_rx(skb); 409702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 410702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_packets++; 411702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->rx_bytes += cf->can_dlc; 412702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 413702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 414702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 415702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * callback for bulk IN urb 416702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 417702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_read_bulk_callback(struct urb *urb) 418702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 419702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = urb->context; 420702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 421702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int retval; 422702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 423702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev = dev->netdev; 424702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 425702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netif_device_present(netdev)) 426702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 427702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 428702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (urb->status) { 429702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case 0: /* success */ 430702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 431702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 432702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case -ENOENT: 433702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 434702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 435702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 436702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "Rx URB aborted (%d)\n", 437702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->status); 438702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto resubmit_urb; 439702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 440702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 441702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (urb->actual_length > CPC_HEADER_SIZE) { 442702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg *msg; 443702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *ibuf = urb->transfer_buffer; 444702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 msg_count, again, start; 445702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 446702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg_count = ibuf[0] & ~0x80; 447702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas again = ibuf[0] & 0x80; 448702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 449702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas start = CPC_HEADER_SIZE; 450702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 451702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas while (msg_count) { 452702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg = (struct ems_cpc_msg *)&ibuf[start]; 453702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 454702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (msg->type) { 455702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_CAN_STATE: 456702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Process CAN state changes */ 457702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_err(dev, msg); 458702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 459702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 460702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_CAN_FRAME: 461702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_EXT_CAN_FRAME: 462702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_RTR_FRAME: 463702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_EXT_RTR_FRAME: 464702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_can_msg(dev, msg); 465702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 466702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 467702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_CAN_FRAME_ERROR: 468702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Process errorframe */ 469702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_err(dev, msg); 470702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 471702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 472702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CPC_MSG_TYPE_OVERRUN: 473702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Message lost while receiving */ 474702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_rx_err(dev, msg); 475702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 476702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 477702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 478702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas start += CPC_MSG_HEADER_LEN + msg->length; 479702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg_count--; 480702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 481702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (start > urb->transfer_buffer_length) { 482702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "format error\n"); 483702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 484702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 485702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 486702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 487702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 488702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasresubmit_urb: 489702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), 490702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_buffer, RX_BUFFER_SIZE, 491702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_read_bulk_callback, dev); 492702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 493702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas retval = usb_submit_urb(urb, GFP_ATOMIC); 494702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 495702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (retval == -ENODEV) 496702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(netdev); 497702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas else if (retval) 498702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 499702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "failed resubmitting read bulk urb: %d\n", retval); 500702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 501702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 502702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 503702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 504702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 505702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * callback for bulk IN urb 506702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 507702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_write_bulk_callback(struct urb *urb) 508702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 509702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_tx_urb_context *context = urb->context; 510702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev; 511702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 512702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 513702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas BUG_ON(!context); 514702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 515702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev = context->dev; 516702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev = dev->netdev; 517702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 518702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* free up our allocated buffer */ 519702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_buffer_free(urb->dev, urb->transfer_buffer_length, 520702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_buffer, urb->transfer_dma); 521702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 522702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_dec(&dev->active_tx_urbs); 523702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 524702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netif_device_present(netdev)) 525702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return; 526702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 527702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (urb->status) 528702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "Tx URB aborted (%d)\n", 529702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->status); 530702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 531702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->trans_start = jiffies; 532702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 533702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* transmission complete interrupt */ 534702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->stats.tx_packets++; 535702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->stats.tx_bytes += context->dlc; 536702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 537702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_get_echo_skb(netdev, context->echo_index); 538702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 539702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Release context */ 540702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->echo_index = MAX_TX_URBS; 541702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 542702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (netif_queue_stopped(netdev)) 543702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_wake_queue(netdev); 544702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 545702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 546702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 547702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Send the given CPC command synchronously 548702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 549702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_command_msg(struct ems_usb *dev, struct ems_cpc_msg *msg) 550702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 551702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int actual_length; 552702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 553702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Copy payload */ 554702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas memcpy(&dev->tx_msg_buffer[CPC_HEADER_SIZE], msg, 555702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length + CPC_MSG_HEADER_LEN); 556702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 557702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Clear header */ 558702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas memset(&dev->tx_msg_buffer[0], 0, CPC_HEADER_SIZE); 559702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 560702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, 2), 561702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas &dev->tx_msg_buffer[0], 562702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length + CPC_MSG_HEADER_LEN + CPC_HEADER_SIZE, 563702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas &actual_length, 1000); 564702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 565702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 566702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 567702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Change CAN controllers' mode register 568702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 569702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_write_mode(struct ems_usb *dev, u8 mode) 570702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 571702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->active_params.msg.can_params.cc_params.sja1000.mode = mode; 572702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 573702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return ems_usb_command_msg(dev, &dev->active_params); 574702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 575702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 576702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 577702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Send a CPC_Control command to change behaviour when interface receives a CAN 578702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * message, bus error or CAN state changed notifications. 579702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 580702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_control_cmd(struct ems_usb *dev, u8 val) 581702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 582702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg cmd; 583702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 584702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.type = CPC_CMD_TYPE_CONTROL; 585702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.length = CPC_MSG_HEADER_LEN + 1; 586702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 587702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.msgid = 0; 588702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 589702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas cmd.msg.generic[0] = val; 590702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 591702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return ems_usb_command_msg(dev, &cmd); 592702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 593702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 594702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 595702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Start interface 596702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 597702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_start(struct ems_usb *dev) 598702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 599702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev = dev->netdev; 600702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int err, i; 601702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 602702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_in_buffer[0] = 0; 603702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->free_slots = 15; /* initial size */ 604702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 605702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_RX_URBS; i++) { 606702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct urb *urb = NULL; 607702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *buf = NULL; 608702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 609702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* create a URB, and a buffer for it */ 610702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb = usb_alloc_urb(0, GFP_KERNEL); 611702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!urb) { 612702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 613702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "No memory left for URBs\n"); 614702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -ENOMEM; 615702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 616702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 617702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas buf = usb_buffer_alloc(dev->udev, RX_BUFFER_SIZE, GFP_KERNEL, 618702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas &urb->transfer_dma); 619702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!buf) { 620702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 621702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "No memory left for USB buffer\n"); 622702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 623702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -ENOMEM; 624702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 625702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 626702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_bulk_urb(urb, dev->udev, usb_rcvbulkpipe(dev->udev, 2), 627702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas buf, RX_BUFFER_SIZE, 628702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_read_bulk_callback, dev); 629702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 630702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_anchor_urb(urb, &dev->rx_submitted); 631702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 632702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(urb, GFP_KERNEL); 633702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 634702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) 635702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(dev->netdev); 636702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 637702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unanchor_urb(urb); 638702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_buffer_free(dev->udev, RX_BUFFER_SIZE, buf, 639702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_dma); 640702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 641702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 642702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 643702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Drop reference, USB core will take care of freeing it */ 644702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 645702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 646702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 647702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Did we submit any URBs */ 648702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (i == 0) { 649702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't setup read URBs\n"); 650702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 651702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 652702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 653702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Warn if we've couldn't transmit all the URBs */ 654702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (i < MAX_RX_URBS) 655702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "rx performance may be slow\n"); 656702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 657702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Setup and start interrupt URB */ 658702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_int_urb(dev->intr_urb, dev->udev, 659702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_rcvintpipe(dev->udev, 1), 660702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_in_buffer, 661702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas INTR_IN_BUFFER_SIZE, 662702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas ems_usb_read_interrupt_callback, dev, 1); 663702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 664702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(dev->intr_urb, GFP_KERNEL); 665702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 666702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) 667702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(dev->netdev); 668702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 669702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "intr URB submit failed: %d\n", 670702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err); 671702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 672702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 673702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 674702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 675702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* CPC-USB will transfer received message to host */ 676702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_control_cmd(dev, CONTR_CAN_MESSAGE | CONTR_CONT_ON); 677702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 678702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 679702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 680702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* CPC-USB will transfer CAN state changes to host */ 681702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_control_cmd(dev, CONTR_CAN_STATE | CONTR_CONT_ON); 682702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 683702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 684702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 685702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* CPC-USB will transfer bus errors to host */ 686702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_control_cmd(dev, CONTR_BUS_ERROR | CONTR_CONT_ON); 687702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 688702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 689702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 690702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_write_mode(dev, SJA1000_MOD_NORMAL); 691702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 692702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto failed; 693702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 694702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_ERROR_ACTIVE; 695702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 696702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 697702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 698702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasfailed: 699702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) 700702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(dev->netdev); 701702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 702702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't submit control: %d\n", err); 703702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 704702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 705702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 706702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 707702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void unlink_all_urbs(struct ems_usb *dev) 708702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 709702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i; 710702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 711702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unlink_urb(dev->intr_urb); 712702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 713702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_kill_anchored_urbs(&dev->rx_submitted); 714702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 715702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_kill_anchored_urbs(&dev->tx_submitted); 716702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_set(&dev->active_tx_urbs, 0); 717702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 718702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_TX_URBS; i++) 719702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->tx_contexts[i].echo_index = MAX_TX_URBS; 720702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 721702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 722702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_open(struct net_device *netdev) 723702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 724702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 725702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int err; 726702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 727702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_write_mode(dev, SJA1000_MOD_RM); 728702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 729702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 730702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 731702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* common open */ 732702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = open_candev(netdev); 733702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) 734702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 735702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 736702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* finally start device */ 737702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_start(dev); 738702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 739702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) 740702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(dev->netdev); 741702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 742702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't start device: %d\n", 743702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err); 744702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 745702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas close_candev(netdev); 746702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 747702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 748702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 749702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 750702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->open_time = jiffies; 751702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 752702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_start_queue(netdev); 753702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 754702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 755702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 756702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 757702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic netdev_tx_t ems_usb_start_xmit(struct sk_buff *skb, struct net_device *netdev) 758702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 759702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 760702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_tx_urb_context *context = NULL; 761702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device_stats *stats = &netdev->stats; 762702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_frame *cf = (struct can_frame *)skb->data; 763702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_cpc_msg *msg; 764702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct urb *urb; 765702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 *buf; 766702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i, err; 767702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas size_t size = CPC_HEADER_SIZE + CPC_MSG_HEADER_LEN 768702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas + sizeof(struct cpc_can_msg); 769702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 770702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* create a URB, and a buffer for it, and copy the data to the URB */ 771702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb = usb_alloc_urb(0, GFP_ATOMIC); 772702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!urb) { 773702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "No memory left for URBs\n"); 774702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto nomem; 775702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 776702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 777702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas buf = usb_buffer_alloc(dev->udev, size, GFP_ATOMIC, &urb->transfer_dma); 778702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!buf) { 779702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "No memory left for USB buffer\n"); 780702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 781702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto nomem; 782702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 783702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 784702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg = (struct ems_cpc_msg *)&buf[CPC_HEADER_SIZE]; 785702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 786702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_msg.id = cf->can_id & CAN_ERR_MASK; 787702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_msg.length = cf->can_dlc; 788702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 789702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (cf->can_id & CAN_RTR_FLAG) { 790702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->type = cf->can_id & CAN_EFF_FLAG ? 791702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas CPC_CMD_TYPE_EXT_RTR_FRAME : CPC_CMD_TYPE_RTR_FRAME; 792702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 793702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length = CPC_CAN_MSG_MIN_SIZE; 794702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 795702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->type = cf->can_id & CAN_EFF_FLAG ? 796702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas CPC_CMD_TYPE_EXT_CAN_FRAME : CPC_CMD_TYPE_CAN_FRAME; 797702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 798702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < cf->can_dlc; i++) 799702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_msg.msg[i] = cf->data[i]; 800702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 801702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length = CPC_CAN_MSG_MIN_SIZE + cf->can_dlc; 802702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 803702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 8042b2072e902848a63168570f500a5726744b3873aSebastian Haas /* Respect byte order */ 8052b2072e902848a63168570f500a5726744b3873aSebastian Haas msg->msg.can_msg.id = cpu_to_le32(msg->msg.can_msg.id); 8062b2072e902848a63168570f500a5726744b3873aSebastian Haas 807702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_TX_URBS; i++) { 808702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev->tx_contexts[i].echo_index == MAX_TX_URBS) { 809702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context = &dev->tx_contexts[i]; 810702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 811702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 812702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 813702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 814702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* 815702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * May never happen! When this happens we'd more URBs in flight as 816702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * allowed (MAX_TX_URBS). 817702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 818702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!context) { 819702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unanchor_urb(urb); 820702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_buffer_free(dev->udev, size, buf, urb->transfer_dma); 821702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 822702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't find free context\n"); 823702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 824702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return NETDEV_TX_BUSY; 825702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 826702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 827702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->dev = dev; 828702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->echo_index = i; 829702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas context->dlc = cf->can_dlc; 830702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 831702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_fill_bulk_urb(urb, dev->udev, usb_sndbulkpipe(dev->udev, 2), buf, 832702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas size, ems_usb_write_bulk_callback, context); 833702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; 834702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_anchor_urb(urb, &dev->tx_submitted); 835702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 836702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_put_echo_skb(skb, netdev, context->echo_index); 837702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 838702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_inc(&dev->active_tx_urbs); 839702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 840702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_submit_urb(urb, GFP_ATOMIC); 841702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (unlikely(err)) { 842702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas can_free_echo_skb(netdev, context->echo_index); 843702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 844702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_unanchor_urb(urb); 845702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_buffer_free(dev->udev, size, buf, urb->transfer_dma); 846702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_kfree_skb(skb); 847702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 848702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_dec(&dev->active_tx_urbs); 849702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 850702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err == -ENODEV) { 851702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_device_detach(netdev); 852702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 853702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "failed tx_urb %d\n", err); 854702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 855702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->tx_dropped++; 856702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 857702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } else { 858702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->trans_start = jiffies; 859702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 860702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Slow down tx path */ 861702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (atomic_read(&dev->active_tx_urbs) >= MAX_TX_URBS || 862702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->free_slots < 5) { 863702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_stop_queue(netdev); 864702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 865702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 866702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 867702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* 868702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * Release our reference to this URB, the USB core will eventually free 869702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * it entirely. 870702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 871702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(urb); 872702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 873702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return NETDEV_TX_OK; 874702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 875702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasnomem: 876702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (skb) 877702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_kfree_skb(skb); 878702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 879702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas stats->tx_dropped++; 880702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 881702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return NETDEV_TX_OK; 882702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 883702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 884702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_close(struct net_device *netdev) 885702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 886702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 887702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 888702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Stop polling */ 889702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unlink_all_urbs(dev); 890702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 891702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_stop_queue(netdev); 892702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 893702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Set CAN controller to reset mode */ 894702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (ems_usb_write_mode(dev, SJA1000_MOD_RM)) 895702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't stop device"); 896702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 897702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas close_candev(netdev); 898702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 899702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->open_time = 0; 900702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 901702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 902702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 903702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 904702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic const struct net_device_ops ems_usb_netdev_ops = { 905702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .ndo_open = ems_usb_open, 906702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .ndo_stop = ems_usb_close, 907702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .ndo_start_xmit = ems_usb_start_xmit, 908702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 909702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 910702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic struct can_bittiming_const ems_usb_bittiming_const = { 911702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .name = "ems_usb", 912702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg1_min = 1, 913702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg1_max = 16, 914702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg2_min = 1, 915702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .tseg2_max = 8, 916702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .sjw_max = 4, 917702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .brp_min = 1, 918702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .brp_max = 64, 919702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .brp_inc = 1, 920702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 921702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 922702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_set_mode(struct net_device *netdev, enum can_mode mode) 923702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 924702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 925702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 926702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->open_time) 927702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -EINVAL; 928702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 929702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas switch (mode) { 930702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas case CAN_MODE_START: 931702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (ems_usb_write_mode(dev, SJA1000_MOD_NORMAL)) 932702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_warn(netdev->dev.parent, "couldn't start device"); 933702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 934702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (netif_queue_stopped(netdev)) 935702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netif_wake_queue(netdev); 936702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas break; 937702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 938702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas default: 939702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -EOPNOTSUPP; 940702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 941702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 942702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 943702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 944702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 945702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_set_bittiming(struct net_device *netdev) 946702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 947702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = netdev_priv(netdev); 948702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct can_bittiming *bt = &dev->can.bittiming; 949702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas u8 btr0, btr1; 950702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 951702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr0 = ((bt->brp - 1) & 0x3f) | (((bt->sjw - 1) & 0x3) << 6); 952702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr1 = ((bt->prop_seg + bt->phase_seg1 - 1) & 0xf) | 953702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas (((bt->phase_seg2 - 1) & 0x7) << 4); 954702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES) 955702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr1 |= 0x80; 956702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 957702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_info(netdev->dev.parent, "setting BTR0=0x%02x BTR1=0x%02x\n", 958702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas btr0, btr1); 959702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 960702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->active_params.msg.can_params.cc_params.sja1000.btr0 = btr0; 961702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->active_params.msg.can_params.cc_params.sja1000.btr1 = btr1; 962702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 963702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return ems_usb_command_msg(dev, &dev->active_params); 964702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 965702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 966702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void init_params_sja1000(struct ems_cpc_msg *msg) 967702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 968702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct cpc_sja1000_params *sja1000 = 969702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas &msg->msg.can_params.cc_params.sja1000; 970702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 971702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->type = CPC_CMD_TYPE_CAN_PARAMS; 972702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->length = sizeof(struct cpc_can_params); 973702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msgid = 0; 974702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 975702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas msg->msg.can_params.cc_type = CPC_CC_TYPE_SJA1000; 976702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 977702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Acceptance filter open */ 978702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code0 = 0x00; 979702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code1 = 0x00; 980702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code2 = 0x00; 981702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_code3 = 0x00; 982702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 983702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* Acceptance filter open */ 984702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask0 = 0xFF; 985702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask1 = 0xFF; 986702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask2 = 0xFF; 987702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->acc_mask3 = 0xFF; 988702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 989702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->btr0 = 0; 990702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->btr1 = 0; 991702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 992702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->outp_contr = SJA1000_DEFAULT_OUTPUT_CONTROL; 993702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sja1000->mode = SJA1000_MOD_RM; 994702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 995702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 996702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 997702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * probe function for new CPC-USB devices 998702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 999702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int ems_usb_probe(struct usb_interface *intf, 1000702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas const struct usb_device_id *id) 1001702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 1002702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct net_device *netdev; 1003702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev; 1004702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int i, err = -ENOMEM; 1005702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1006a6e4bc5304033e434fabccabb230b8e9ff55d76fWolfgang Grandegger netdev = alloc_candev(sizeof(struct ems_usb), MAX_TX_URBS); 1007702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!netdev) { 1008702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "Couldn't alloc candev\n"); 1009702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return -ENOMEM; 1010702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1011702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1012702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev = netdev_priv(netdev); 1013702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1014702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->udev = interface_to_usbdev(intf); 1015702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->netdev = netdev; 1016702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1017702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.state = CAN_STATE_STOPPED; 1018702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.clock.freq = EMS_USB_ARM7_CLOCK; 1019702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.bittiming_const = &ems_usb_bittiming_const; 1020702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.do_set_bittiming = ems_usb_set_bittiming; 1021702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->can.do_set_mode = ems_usb_set_mode; 1022702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1023702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->flags |= IFF_ECHO; /* we support local echo */ 1024702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1025702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->netdev_ops = &ems_usb_netdev_ops; 1026702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1027702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas netdev->flags |= IFF_ECHO; /* we support local echo */ 1028702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1029702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas init_usb_anchor(&dev->rx_submitted); 1030702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1031702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas init_usb_anchor(&dev->tx_submitted); 1032702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas atomic_set(&dev->active_tx_urbs, 0); 1033702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1034702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas for (i = 0; i < MAX_TX_URBS; i++) 1035702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->tx_contexts[i].echo_index = MAX_TX_URBS; 1036702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1037702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_urb = usb_alloc_urb(0, GFP_KERNEL); 1038702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->intr_urb) { 1039702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "Couldn't alloc intr URB\n"); 1040702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_candev; 1041702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1042702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1043702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->intr_in_buffer = kzalloc(INTR_IN_BUFFER_SIZE, GFP_KERNEL); 1044702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->intr_in_buffer) { 1045702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "Couldn't alloc Intr buffer\n"); 1046702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_intr_urb; 1047702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1048702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1049702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev->tx_msg_buffer = kzalloc(CPC_HEADER_SIZE + 1050702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas sizeof(struct ems_cpc_msg), GFP_KERNEL); 1051702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (!dev->tx_msg_buffer) { 1052702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, "Couldn't alloc Tx buffer\n"); 1053702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_intr_in_buffer; 1054702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1055702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1056702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_set_intfdata(intf, dev); 1057702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1058702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas SET_NETDEV_DEV(netdev, &intf->dev); 1059702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1060702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas init_params_sja1000(&dev->active_params); 1061702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1062702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = ems_usb_command_msg(dev, &dev->active_params); 1063702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 1064702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 1065702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "couldn't initialize controller: %d\n", err); 1066702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_tx_msg_buffer; 1067702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1068702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1069702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = register_candev(netdev); 1070702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 1071702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas dev_err(netdev->dev.parent, 1072702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas "couldn't register CAN device: %d\n", err); 1073702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas goto cleanup_tx_msg_buffer; 1074702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1075702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1076702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 1077702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1078702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_tx_msg_buffer: 1079702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas kfree(dev->tx_msg_buffer); 1080702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1081702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_intr_in_buffer: 1082702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas kfree(dev->intr_in_buffer); 1083702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1084702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_intr_urb: 1085702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(dev->intr_urb); 1086702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1087702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haascleanup_candev: 1088702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas free_candev(netdev); 1089702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1090702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 1091702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 1092702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1093702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* 1094702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas * called by the usb core when the device is removed from the system 1095702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas */ 1096702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void ems_usb_disconnect(struct usb_interface *intf) 1097702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 1098702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas struct ems_usb *dev = usb_get_intfdata(intf); 1099702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1100702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_set_intfdata(intf, NULL); 1101702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1102702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (dev) { 1103702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unregister_netdev(dev->netdev); 1104702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas free_candev(dev->netdev); 1105702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1106702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas unlink_all_urbs(dev); 1107702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1108702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_free_urb(dev->intr_urb); 1109702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1110702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas kfree(dev->intr_in_buffer); 1111702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1112702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 1113702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1114702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas/* usb specific object needed to register this driver with the usb subsystem */ 1115702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic struct usb_driver ems_usb_driver = { 1116702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .name = "ems_usb", 1117702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .probe = ems_usb_probe, 1118702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .disconnect = ems_usb_disconnect, 1119702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas .id_table = ems_usb_table, 1120702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas}; 1121702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1122702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic int __init ems_usb_init(void) 1123702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 1124702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas int err; 1125702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1126702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas printk(KERN_INFO "CPC-USB kernel driver loaded\n"); 1127702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1128702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* register this driver with the USB subsystem */ 1129702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err = usb_register(&ems_usb_driver); 1130702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1131702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas if (err) { 1132702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas err("usb_register failed. Error number %d\n", err); 1133702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return err; 1134702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas } 1135702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1136702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas return 0; 1137702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 1138702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1139702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasstatic void __exit ems_usb_exit(void) 1140702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas{ 1141702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas /* deregister this driver with the USB subsystem */ 1142702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas usb_deregister(&ems_usb_driver); 1143702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas} 1144702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haas 1145702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasmodule_init(ems_usb_init); 1146702171adeed3607ee9603ec30ce081411e36ae42Sebastian Haasmodule_exit(ems_usb_exit); 1147