| .. | .. | 
|---|
| 79 | 79 |  #define USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID	269 | 
|---|
| 80 | 80 |  #define USB_HYBRID_PRO_CANLIN_PRODUCT_ID	270 | 
|---|
| 81 | 81 |   | 
|---|
| 82 |  | -static inline bool kvaser_is_leaf(const struct usb_device_id *id)  | 
|---|
| 83 |  | -{  | 
|---|
| 84 |  | -	return (id->idProduct >= USB_LEAF_DEVEL_PRODUCT_ID &&  | 
|---|
| 85 |  | -		id->idProduct <= USB_CAN_R_PRODUCT_ID) ||  | 
|---|
| 86 |  | -		(id->idProduct >= USB_LEAF_LITE_V2_PRODUCT_ID &&  | 
|---|
| 87 |  | -		 id->idProduct <= USB_MINI_PCIE_2HS_PRODUCT_ID);  | 
|---|
| 88 |  | -}  | 
|---|
 | 82 | +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_hydra = {  | 
|---|
 | 83 | +	.quirks = 0,  | 
|---|
 | 84 | +	.ops = &kvaser_usb_hydra_dev_ops,  | 
|---|
 | 85 | +};  | 
|---|
| 89 | 86 |   | 
|---|
| 90 |  | -static inline bool kvaser_is_usbcan(const struct usb_device_id *id)  | 
|---|
| 91 |  | -{  | 
|---|
| 92 |  | -	return id->idProduct >= USB_USBCAN_REVB_PRODUCT_ID &&  | 
|---|
| 93 |  | -	       id->idProduct <= USB_MEMORATOR_PRODUCT_ID;  | 
|---|
| 94 |  | -}  | 
|---|
 | 87 | +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_usbcan = {  | 
|---|
 | 88 | +	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |  | 
|---|
 | 89 | +		  KVASER_USB_QUIRK_HAS_SILENT_MODE,  | 
|---|
 | 90 | +	.family = KVASER_USBCAN,  | 
|---|
 | 91 | +	.ops = &kvaser_usb_leaf_dev_ops,  | 
|---|
 | 92 | +};  | 
|---|
| 95 | 93 |   | 
|---|
| 96 |  | -static inline bool kvaser_is_hydra(const struct usb_device_id *id)  | 
|---|
| 97 |  | -{  | 
|---|
| 98 |  | -	return id->idProduct >= USB_BLACKBIRD_V2_PRODUCT_ID &&  | 
|---|
| 99 |  | -	       id->idProduct <= USB_HYBRID_PRO_CANLIN_PRODUCT_ID;  | 
|---|
| 100 |  | -}  | 
|---|
 | 94 | +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf = {  | 
|---|
 | 95 | +	.quirks = KVASER_USB_QUIRK_IGNORE_CLK_FREQ,  | 
|---|
 | 96 | +	.family = KVASER_LEAF,  | 
|---|
 | 97 | +	.ops = &kvaser_usb_leaf_dev_ops,  | 
|---|
 | 98 | +};  | 
|---|
 | 99 | +  | 
|---|
 | 100 | +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err = {  | 
|---|
 | 101 | +	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |  | 
|---|
 | 102 | +		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,  | 
|---|
 | 103 | +	.family = KVASER_LEAF,  | 
|---|
 | 104 | +	.ops = &kvaser_usb_leaf_dev_ops,  | 
|---|
 | 105 | +};  | 
|---|
 | 106 | +  | 
|---|
 | 107 | +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leaf_err_listen = {  | 
|---|
 | 108 | +	.quirks = KVASER_USB_QUIRK_HAS_TXRX_ERRORS |  | 
|---|
 | 109 | +		  KVASER_USB_QUIRK_HAS_SILENT_MODE |  | 
|---|
 | 110 | +		  KVASER_USB_QUIRK_IGNORE_CLK_FREQ,  | 
|---|
 | 111 | +	.family = KVASER_LEAF,  | 
|---|
 | 112 | +	.ops = &kvaser_usb_leaf_dev_ops,  | 
|---|
 | 113 | +};  | 
|---|
 | 114 | +  | 
|---|
 | 115 | +static const struct kvaser_usb_driver_info kvaser_usb_driver_info_leafimx = {  | 
|---|
 | 116 | +	.quirks = 0,  | 
|---|
 | 117 | +	.ops = &kvaser_usb_leaf_dev_ops,  | 
|---|
 | 118 | +};  | 
|---|
| 101 | 119 |   | 
|---|
| 102 | 120 |  static const struct usb_device_id kvaser_usb_table[] = { | 
|---|
| 103 |  | -	/* Leaf USB product IDs */  | 
|---|
| 104 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) },  | 
|---|
| 105 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) },  | 
|---|
 | 121 | +	/* Leaf M32C USB product IDs */  | 
|---|
 | 122 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID),  | 
|---|
 | 123 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },  | 
|---|
 | 124 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID),  | 
|---|
 | 125 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },  | 
|---|
| 106 | 126 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID), | 
|---|
| 107 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 108 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 127 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 109 | 128 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_PRODUCT_ID), | 
|---|
| 110 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 111 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 129 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 112 | 130 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LS_PRODUCT_ID), | 
|---|
| 113 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 114 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 131 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 115 | 132 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_SWC_PRODUCT_ID), | 
|---|
| 116 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 117 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 133 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 118 | 134 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_LIN_PRODUCT_ID), | 
|---|
| 119 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 120 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 135 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 121 | 136 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_LS_PRODUCT_ID), | 
|---|
| 122 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 123 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 137 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 124 | 138 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_SPRO_SWC_PRODUCT_ID), | 
|---|
| 125 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 126 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 139 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 127 | 140 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_DEVEL_PRODUCT_ID), | 
|---|
| 128 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 129 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 141 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 130 | 142 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSHS_PRODUCT_ID), | 
|---|
| 131 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 132 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 143 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 133 | 144 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_UPRO_HSHS_PRODUCT_ID), | 
|---|
| 134 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
| 135 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID) },  | 
|---|
 | 145 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },  | 
|---|
 | 146 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_GI_PRODUCT_ID),  | 
|---|
 | 147 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf },  | 
|---|
| 136 | 148 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_OBDII_PRODUCT_ID), | 
|---|
| 137 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS |  | 
|---|
| 138 |  | -			       KVASER_USB_HAS_SILENT_MODE },  | 
|---|
 | 149 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err_listen },  | 
|---|
| 139 | 150 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO2_HSLS_PRODUCT_ID), | 
|---|
| 140 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 151 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },  | 
|---|
| 141 | 152 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_CH_PRODUCT_ID), | 
|---|
| 142 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 153 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },  | 
|---|
| 143 | 154 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_SPRO_PRODUCT_ID), | 
|---|
| 144 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 155 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },  | 
|---|
| 145 | 156 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_MERCURY_PRODUCT_ID), | 
|---|
| 146 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 157 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },  | 
|---|
| 147 | 158 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_OEM_LEAF_PRODUCT_ID), | 
|---|
| 148 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 159 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },  | 
|---|
| 149 | 160 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID), | 
|---|
| 150 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
| 151 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) },  | 
|---|
| 152 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) },  | 
|---|
| 153 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID) },  | 
|---|
| 154 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID) },  | 
|---|
| 155 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID) },  | 
|---|
 | 161 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leaf_err },  | 
|---|
 | 162 | +  | 
|---|
 | 163 | +	/* Leaf i.MX28 USB product IDs */  | 
|---|
 | 164 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID),  | 
|---|
 | 165 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },  | 
|---|
 | 166 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID),  | 
|---|
 | 167 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },  | 
|---|
 | 168 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LIGHT_HS_V2_OEM_PRODUCT_ID),  | 
|---|
 | 169 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },  | 
|---|
 | 170 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_2HS_PRODUCT_ID),  | 
|---|
 | 171 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },  | 
|---|
 | 172 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_2HS_PRODUCT_ID),  | 
|---|
 | 173 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_leafimx },  | 
|---|
| 156 | 174 |   | 
|---|
| 157 | 175 |  	/* USBCANII USB product IDs */ | 
|---|
| 158 | 176 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID), | 
|---|
| 159 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 177 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },  | 
|---|
| 160 | 178 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID), | 
|---|
| 161 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 179 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },  | 
|---|
| 162 | 180 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID), | 
|---|
| 163 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 181 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },  | 
|---|
| 164 | 182 |  	{ USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID), | 
|---|
| 165 |  | -		.driver_info = KVASER_USB_HAS_TXRX_ERRORS },  | 
|---|
 | 183 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_usbcan },  | 
|---|
| 166 | 184 |   | 
|---|
| 167 | 185 |  	/* Minihydra USB product IDs */ | 
|---|
| 168 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID) },  | 
|---|
| 169 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID) },  | 
|---|
| 170 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID) },  | 
|---|
| 171 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID) },  | 
|---|
| 172 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID) },  | 
|---|
| 173 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID) },  | 
|---|
| 174 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID) },  | 
|---|
| 175 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID) },  | 
|---|
| 176 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID) },  | 
|---|
| 177 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID) },  | 
|---|
| 178 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID) },  | 
|---|
| 179 |  | -	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID) },  | 
|---|
 | 186 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_BLACKBIRD_V2_PRODUCT_ID),  | 
|---|
 | 187 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 188 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_5HS_PRODUCT_ID),  | 
|---|
 | 189 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 190 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_5HS_PRODUCT_ID),  | 
|---|
 | 191 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 192 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_LIGHT_4HS_PRODUCT_ID),  | 
|---|
 | 193 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 194 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_HS_V2_PRODUCT_ID),  | 
|---|
 | 195 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 196 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_PRO_2HS_V2_PRODUCT_ID),  | 
|---|
 | 197 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 198 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_2HS_PRODUCT_ID),  | 
|---|
 | 199 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 200 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_MEMO_PRO_2HS_V2_PRODUCT_ID),  | 
|---|
 | 201 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 202 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_CANLIN_PRODUCT_ID),  | 
|---|
 | 203 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 204 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_USBCAN_PRO_2HS_V2_PRODUCT_ID),  | 
|---|
 | 205 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 206 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_ATI_MEMO_PRO_2HS_V2_PRODUCT_ID),  | 
|---|
 | 207 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
 | 208 | +	{ USB_DEVICE(KVASER_VENDOR_ID, USB_HYBRID_PRO_CANLIN_PRODUCT_ID),  | 
|---|
 | 209 | +		.driver_info = (kernel_ulong_t)&kvaser_usb_driver_info_hydra },  | 
|---|
| 180 | 210 |  	{ } | 
|---|
| 181 | 211 |  }; | 
|---|
| 182 | 212 |  MODULE_DEVICE_TABLE(usb, kvaser_usb_table); | 
|---|
| .. | .. | 
|---|
| 267 | 297 |  static void kvaser_usb_read_bulk_callback(struct urb *urb) | 
|---|
| 268 | 298 |  { | 
|---|
| 269 | 299 |  	struct kvaser_usb *dev = urb->context; | 
|---|
 | 300 | +	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;  | 
|---|
| 270 | 301 |  	int err; | 
|---|
| 271 | 302 |  	unsigned int i; | 
|---|
| 272 | 303 |   | 
|---|
| .. | .. | 
|---|
| 283 | 314 |  		goto resubmit_urb; | 
|---|
| 284 | 315 |  	} | 
|---|
| 285 | 316 |   | 
|---|
| 286 |  | -	dev->ops->dev_read_bulk_callback(dev, urb->transfer_buffer,  | 
|---|
| 287 |  | -					 urb->actual_length);  | 
|---|
 | 317 | +	ops->dev_read_bulk_callback(dev, urb->transfer_buffer,  | 
|---|
 | 318 | +				    urb->actual_length);  | 
|---|
| 288 | 319 |   | 
|---|
| 289 | 320 |  resubmit_urb: | 
|---|
| 290 | 321 |  	usb_fill_bulk_urb(urb, dev->udev, | 
|---|
| .. | .. | 
|---|
| 378 | 409 |  { | 
|---|
| 379 | 410 |  	struct kvaser_usb_net_priv *priv = netdev_priv(netdev); | 
|---|
| 380 | 411 |  	struct kvaser_usb *dev = priv->dev; | 
|---|
 | 412 | +	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;  | 
|---|
| 381 | 413 |  	int err; | 
|---|
| 382 | 414 |   | 
|---|
| 383 | 415 |  	err = open_candev(netdev); | 
|---|
| .. | .. | 
|---|
| 388 | 420 |  	if (err) | 
|---|
| 389 | 421 |  		goto error; | 
|---|
| 390 | 422 |   | 
|---|
| 391 |  | -	err = dev->ops->dev_set_opt_mode(priv);  | 
|---|
 | 423 | +	err = ops->dev_set_opt_mode(priv);  | 
|---|
| 392 | 424 |  	if (err) | 
|---|
| 393 | 425 |  		goto error; | 
|---|
| 394 | 426 |   | 
|---|
| 395 |  | -	err = dev->ops->dev_start_chip(priv);  | 
|---|
 | 427 | +	err = ops->dev_start_chip(priv);  | 
|---|
| 396 | 428 |  	if (err) { | 
|---|
| 397 | 429 |  		netdev_warn(netdev, "Cannot start device, error %d\n", err); | 
|---|
| 398 | 430 |  		goto error; | 
|---|
| .. | .. | 
|---|
| 421 | 453 |  /* This method might sleep. Do not call it in the atomic context | 
|---|
| 422 | 454 |   * of URB completions. | 
|---|
| 423 | 455 |   */ | 
|---|
| 424 |  | -static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)  | 
|---|
 | 456 | +void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)  | 
|---|
| 425 | 457 |  { | 
|---|
| 426 | 458 |  	usb_kill_anchored_urbs(&priv->tx_submitted); | 
|---|
| 427 | 459 |  	kvaser_usb_reset_tx_urb_contexts(priv); | 
|---|
| .. | .. | 
|---|
| 449 | 481 |  { | 
|---|
| 450 | 482 |  	struct kvaser_usb_net_priv *priv = netdev_priv(netdev); | 
|---|
| 451 | 483 |  	struct kvaser_usb *dev = priv->dev; | 
|---|
 | 484 | +	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;  | 
|---|
| 452 | 485 |  	int err; | 
|---|
| 453 | 486 |   | 
|---|
| 454 | 487 |  	netif_stop_queue(netdev); | 
|---|
| 455 | 488 |   | 
|---|
| 456 |  | -	err = dev->ops->dev_flush_queue(priv);  | 
|---|
 | 489 | +	err = ops->dev_flush_queue(priv);  | 
|---|
| 457 | 490 |  	if (err) | 
|---|
| 458 | 491 |  		netdev_warn(netdev, "Cannot flush queue, error %d\n", err); | 
|---|
| 459 | 492 |   | 
|---|
| 460 |  | -	if (dev->ops->dev_reset_chip) {  | 
|---|
| 461 |  | -		err = dev->ops->dev_reset_chip(dev, priv->channel);  | 
|---|
 | 493 | +	if (ops->dev_reset_chip) {  | 
|---|
 | 494 | +		err = ops->dev_reset_chip(dev, priv->channel);  | 
|---|
| 462 | 495 |  		if (err) | 
|---|
| 463 | 496 |  			netdev_warn(netdev, "Cannot reset card, error %d\n", | 
|---|
| 464 | 497 |  				    err); | 
|---|
| 465 | 498 |  	} | 
|---|
| 466 | 499 |   | 
|---|
| 467 |  | -	err = dev->ops->dev_stop_chip(priv);  | 
|---|
 | 500 | +	err = ops->dev_stop_chip(priv);  | 
|---|
| 468 | 501 |  	if (err) | 
|---|
| 469 | 502 |  		netdev_warn(netdev, "Cannot stop device, error %d\n", err); | 
|---|
| 470 | 503 |   | 
|---|
| .. | .. | 
|---|
| 503 | 536 |  { | 
|---|
| 504 | 537 |  	struct kvaser_usb_net_priv *priv = netdev_priv(netdev); | 
|---|
| 505 | 538 |  	struct kvaser_usb *dev = priv->dev; | 
|---|
 | 539 | +	const struct kvaser_usb_dev_ops *ops = dev->driver_info->ops;  | 
|---|
| 506 | 540 |  	struct net_device_stats *stats = &netdev->stats; | 
|---|
| 507 | 541 |  	struct kvaser_usb_tx_urb_context *context = NULL; | 
|---|
| 508 | 542 |  	struct urb *urb; | 
|---|
| .. | .. | 
|---|
| 545 | 579 |  		goto freeurb; | 
|---|
| 546 | 580 |  	} | 
|---|
| 547 | 581 |   | 
|---|
| 548 |  | -	buf = dev->ops->dev_frame_to_cmd(priv, skb, &context->dlc, &cmd_len,  | 
|---|
| 549 |  | -					 context->echo_index);  | 
|---|
 | 582 | +	buf = ops->dev_frame_to_cmd(priv, skb, &context->dlc, &cmd_len,  | 
|---|
 | 583 | +				    context->echo_index);  | 
|---|
| 550 | 584 |  	if (!buf) { | 
|---|
| 551 | 585 |  		stats->tx_dropped++; | 
|---|
| 552 | 586 |  		dev_kfree_skb(skb); | 
|---|
| .. | .. | 
|---|
| 630 | 664 |  	} | 
|---|
| 631 | 665 |  } | 
|---|
| 632 | 666 |   | 
|---|
| 633 |  | -static int kvaser_usb_init_one(struct kvaser_usb *dev,  | 
|---|
| 634 |  | -			       const struct usb_device_id *id, int channel)  | 
|---|
 | 667 | +static int kvaser_usb_init_one(struct kvaser_usb *dev, int channel)  | 
|---|
| 635 | 668 |  { | 
|---|
| 636 | 669 |  	struct net_device *netdev; | 
|---|
| 637 | 670 |  	struct kvaser_usb_net_priv *priv; | 
|---|
 | 671 | +	const struct kvaser_usb_driver_info *driver_info = dev->driver_info;  | 
|---|
 | 672 | +	const struct kvaser_usb_dev_ops *ops = driver_info->ops;  | 
|---|
| 638 | 673 |  	int err; | 
|---|
| 639 | 674 |   | 
|---|
| 640 |  | -	if (dev->ops->dev_reset_chip) {  | 
|---|
| 641 |  | -		err = dev->ops->dev_reset_chip(dev, channel);  | 
|---|
 | 675 | +	if (ops->dev_reset_chip) {  | 
|---|
 | 676 | +		err = ops->dev_reset_chip(dev, channel);  | 
|---|
| 642 | 677 |  		if (err) | 
|---|
| 643 | 678 |  			return err; | 
|---|
| 644 | 679 |  	} | 
|---|
| 645 | 680 |   | 
|---|
| 646 |  | -	netdev = alloc_candev(sizeof(*priv) +  | 
|---|
| 647 |  | -			      dev->max_tx_urbs * sizeof(*priv->tx_contexts),  | 
|---|
 | 681 | +	netdev = alloc_candev(struct_size(priv, tx_contexts, dev->max_tx_urbs),  | 
|---|
| 648 | 682 |  			      dev->max_tx_urbs); | 
|---|
| 649 | 683 |  	if (!netdev) { | 
|---|
| 650 | 684 |  		dev_err(&dev->intf->dev, "Cannot alloc candev\n"); | 
|---|
| .. | .. | 
|---|
| 656 | 690 |  	init_usb_anchor(&priv->tx_submitted); | 
|---|
| 657 | 691 |  	init_completion(&priv->start_comp); | 
|---|
| 658 | 692 |  	init_completion(&priv->stop_comp); | 
|---|
 | 693 | +	init_completion(&priv->flush_comp);  | 
|---|
| 659 | 694 |  	priv->can.ctrlmode_supported = 0; | 
|---|
| 660 | 695 |   | 
|---|
| 661 | 696 |  	priv->dev = dev; | 
|---|
| .. | .. | 
|---|
| 668 | 703 |  	priv->can.state = CAN_STATE_STOPPED; | 
|---|
| 669 | 704 |  	priv->can.clock.freq = dev->cfg->clock.freq; | 
|---|
| 670 | 705 |  	priv->can.bittiming_const = dev->cfg->bittiming_const; | 
|---|
| 671 |  | -	priv->can.do_set_bittiming = dev->ops->dev_set_bittiming;  | 
|---|
| 672 |  | -	priv->can.do_set_mode = dev->ops->dev_set_mode;  | 
|---|
| 673 |  | -	if ((id->driver_info & KVASER_USB_HAS_TXRX_ERRORS) ||  | 
|---|
 | 706 | +	priv->can.do_set_bittiming = ops->dev_set_bittiming;  | 
|---|
 | 707 | +	priv->can.do_set_mode = ops->dev_set_mode;  | 
|---|
 | 708 | +	if ((driver_info->quirks & KVASER_USB_QUIRK_HAS_TXRX_ERRORS) ||  | 
|---|
| 674 | 709 |  	    (priv->dev->card_data.capabilities & KVASER_USB_CAP_BERR_CAP)) | 
|---|
| 675 |  | -		priv->can.do_get_berr_counter = dev->ops->dev_get_berr_counter;  | 
|---|
| 676 |  | -	if (id->driver_info & KVASER_USB_HAS_SILENT_MODE)  | 
|---|
 | 710 | +		priv->can.do_get_berr_counter = ops->dev_get_berr_counter;  | 
|---|
 | 711 | +	if (driver_info->quirks & KVASER_USB_QUIRK_HAS_SILENT_MODE)  | 
|---|
| 677 | 712 |  		priv->can.ctrlmode_supported |= CAN_CTRLMODE_LISTENONLY; | 
|---|
| 678 | 713 |   | 
|---|
| 679 | 714 |  	priv->can.ctrlmode_supported |= dev->card_data.ctrlmode_supported; | 
|---|
| 680 | 715 |   | 
|---|
| 681 | 716 |  	if (priv->can.ctrlmode_supported & CAN_CTRLMODE_FD) { | 
|---|
| 682 | 717 |  		priv->can.data_bittiming_const = dev->cfg->data_bittiming_const; | 
|---|
| 683 |  | -		priv->can.do_set_data_bittiming =  | 
|---|
| 684 |  | -					dev->ops->dev_set_data_bittiming;  | 
|---|
 | 718 | +		priv->can.do_set_data_bittiming = ops->dev_set_data_bittiming;  | 
|---|
| 685 | 719 |  	} | 
|---|
| 686 | 720 |   | 
|---|
| 687 | 721 |  	netdev->flags |= IFF_ECHO; | 
|---|
| .. | .. | 
|---|
| 712 | 746 |  	struct kvaser_usb *dev; | 
|---|
| 713 | 747 |  	int err; | 
|---|
| 714 | 748 |  	int i; | 
|---|
 | 749 | +	const struct kvaser_usb_driver_info *driver_info;  | 
|---|
 | 750 | +	const struct kvaser_usb_dev_ops *ops;  | 
|---|
 | 751 | +  | 
|---|
 | 752 | +	driver_info = (const struct kvaser_usb_driver_info *)id->driver_info;  | 
|---|
 | 753 | +	if (!driver_info)  | 
|---|
 | 754 | +		return -ENODEV;  | 
|---|
| 715 | 755 |   | 
|---|
| 716 | 756 |  	dev = devm_kzalloc(&intf->dev, sizeof(*dev), GFP_KERNEL); | 
|---|
| 717 | 757 |  	if (!dev) | 
|---|
| 718 | 758 |  		return -ENOMEM; | 
|---|
| 719 | 759 |   | 
|---|
| 720 |  | -	if (kvaser_is_leaf(id)) {  | 
|---|
| 721 |  | -		dev->card_data.leaf.family = KVASER_LEAF;  | 
|---|
| 722 |  | -		dev->ops = &kvaser_usb_leaf_dev_ops;  | 
|---|
| 723 |  | -	} else if (kvaser_is_usbcan(id)) {  | 
|---|
| 724 |  | -		dev->card_data.leaf.family = KVASER_USBCAN;  | 
|---|
| 725 |  | -		dev->ops = &kvaser_usb_leaf_dev_ops;  | 
|---|
| 726 |  | -	} else if (kvaser_is_hydra(id)) {  | 
|---|
| 727 |  | -		dev->ops = &kvaser_usb_hydra_dev_ops;  | 
|---|
| 728 |  | -	} else {  | 
|---|
| 729 |  | -		dev_err(&intf->dev,  | 
|---|
| 730 |  | -			"Product ID (%d) is not a supported Kvaser USB device\n",  | 
|---|
| 731 |  | -			id->idProduct);  | 
|---|
| 732 |  | -		return -ENODEV;  | 
|---|
| 733 |  | -	}  | 
|---|
| 734 |  | -  | 
|---|
| 735 | 760 |  	dev->intf = intf; | 
|---|
 | 761 | +	dev->driver_info = driver_info;  | 
|---|
 | 762 | +	ops = driver_info->ops;  | 
|---|
| 736 | 763 |   | 
|---|
| 737 |  | -	err = dev->ops->dev_setup_endpoints(dev);  | 
|---|
 | 764 | +	err = ops->dev_setup_endpoints(dev);  | 
|---|
| 738 | 765 |  	if (err) { | 
|---|
| 739 | 766 |  		dev_err(&intf->dev, "Cannot get usb endpoint(s)"); | 
|---|
| 740 | 767 |  		return err; | 
|---|
| .. | .. | 
|---|
| 748 | 775 |   | 
|---|
| 749 | 776 |  	dev->card_data.ctrlmode_supported = 0; | 
|---|
| 750 | 777 |  	dev->card_data.capabilities = 0; | 
|---|
| 751 |  | -	err = dev->ops->dev_init_card(dev);  | 
|---|
 | 778 | +	err = ops->dev_init_card(dev);  | 
|---|
| 752 | 779 |  	if (err) { | 
|---|
| 753 | 780 |  		dev_err(&intf->dev, | 
|---|
| 754 | 781 |  			"Failed to initialize card, error %d\n", err); | 
|---|
| 755 | 782 |  		return err; | 
|---|
| 756 | 783 |  	} | 
|---|
| 757 | 784 |   | 
|---|
| 758 |  | -	err = dev->ops->dev_get_software_info(dev);  | 
|---|
 | 785 | +	err = ops->dev_get_software_info(dev);  | 
|---|
| 759 | 786 |  	if (err) { | 
|---|
| 760 | 787 |  		dev_err(&intf->dev, | 
|---|
| 761 | 788 |  			"Cannot get software info, error %d\n", err); | 
|---|
| 762 | 789 |  		return err; | 
|---|
| 763 | 790 |  	} | 
|---|
| 764 | 791 |   | 
|---|
| 765 |  | -	if (dev->ops->dev_get_software_details) {  | 
|---|
| 766 |  | -		err = dev->ops->dev_get_software_details(dev);  | 
|---|
 | 792 | +	if (ops->dev_get_software_details) {  | 
|---|
 | 793 | +		err = ops->dev_get_software_details(dev);  | 
|---|
| 767 | 794 |  		if (err) { | 
|---|
| 768 | 795 |  			dev_err(&intf->dev, | 
|---|
| 769 | 796 |  				"Cannot get software details, error %d\n", err); | 
|---|
| .. | .. | 
|---|
| 781 | 808 |   | 
|---|
| 782 | 809 |  	dev_dbg(&intf->dev, "Max outstanding tx = %d URBs\n", dev->max_tx_urbs); | 
|---|
| 783 | 810 |   | 
|---|
| 784 |  | -	err = dev->ops->dev_get_card_info(dev);  | 
|---|
 | 811 | +	err = ops->dev_get_card_info(dev);  | 
|---|
| 785 | 812 |  	if (err) { | 
|---|
| 786 | 813 |  		dev_err(&intf->dev, "Cannot get card info, error %d\n", err); | 
|---|
| 787 | 814 |  		return err; | 
|---|
| 788 | 815 |  	} | 
|---|
| 789 | 816 |   | 
|---|
| 790 |  | -	if (dev->ops->dev_get_capabilities) {  | 
|---|
| 791 |  | -		err = dev->ops->dev_get_capabilities(dev);  | 
|---|
 | 817 | +	if (ops->dev_get_capabilities) {  | 
|---|
 | 818 | +		err = ops->dev_get_capabilities(dev);  | 
|---|
| 792 | 819 |  		if (err) { | 
|---|
| 793 | 820 |  			dev_err(&intf->dev, | 
|---|
| 794 | 821 |  				"Cannot get capabilities, error %d\n", err); | 
|---|
| .. | .. | 
|---|
| 798 | 825 |  	} | 
|---|
| 799 | 826 |   | 
|---|
| 800 | 827 |  	for (i = 0; i < dev->nchannels; i++) { | 
|---|
| 801 |  | -		err = kvaser_usb_init_one(dev, id, i);  | 
|---|
 | 828 | +		err = kvaser_usb_init_one(dev, i);  | 
|---|
| 802 | 829 |  		if (err) { | 
|---|
| 803 | 830 |  			kvaser_usb_remove_interfaces(dev); | 
|---|
| 804 | 831 |  			return err; | 
|---|