diff options
author | Stephane Grosjean <s.grosjean@peak-system.com> | 2012-03-02 10:13:04 -0500 |
---|---|---|
committer | Marc Kleine-Budde <mkl@pengutronix.de> | 2012-03-03 11:40:51 -0500 |
commit | bb4785551f64e18b2c8bb15a3bd2b22f5ebf624d (patch) | |
tree | 4a515acc5afb744a15f202cfb62889767ec06ad4 /drivers/net/can | |
parent | 2b61972b74219d21ef1e91178349bdb840357688 (diff) |
can: usb: PEAK-System Technik USB adapters driver core
This patch adds the core of the peak_usb driver which handles PEAK-System
Technik PCAN USB adapters. It defines the parts which are common to the
PCAN-USB adapters: can network interfaces management, network-to/from-usb
data path interface, timestamps management...
Tested-by: Oliver Hartkopp <socketcan@hartkopp.net>
Acked-by: Wolfgang Grandegger <wg@grandegger.com>
Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'drivers/net/can')
-rw-r--r-- | drivers/net/can/usb/Kconfig | 6 | ||||
-rw-r--r-- | drivers/net/can/usb/Makefile | 1 | ||||
-rw-r--r-- | drivers/net/can/usb/peak_usb/Makefile | 2 | ||||
-rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_usb_core.c | 951 | ||||
-rw-r--r-- | drivers/net/can/usb/peak_usb/pcan_usb_core.h | 146 |
5 files changed, 1106 insertions, 0 deletions
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig index 04525495b15b..0a6876841c20 100644 --- a/drivers/net/can/usb/Kconfig +++ b/drivers/net/can/usb/Kconfig | |||
@@ -13,4 +13,10 @@ config CAN_ESD_USB2 | |||
13 | This driver supports the CAN-USB/2 interface | 13 | This driver supports the CAN-USB/2 interface |
14 | from esd electronic system design gmbh (http://www.esd.eu). | 14 | from esd electronic system design gmbh (http://www.esd.eu). |
15 | 15 | ||
16 | config CAN_PEAK_USB | ||
17 | tristate "PEAK PCAN-USB/USB Pro interfaces" | ||
18 | ---help--- | ||
19 | This driver supports the PCAN-USB and PCAN-USB Pro adapters | ||
20 | from PEAK-System Technik (http://www.peak-system.com). | ||
21 | |||
16 | endmenu | 22 | endmenu |
diff --git a/drivers/net/can/usb/Makefile b/drivers/net/can/usb/Makefile index fce3cf11719f..da6d1d3b2969 100644 --- a/drivers/net/can/usb/Makefile +++ b/drivers/net/can/usb/Makefile | |||
@@ -4,5 +4,6 @@ | |||
4 | 4 | ||
5 | obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o | 5 | obj-$(CONFIG_CAN_EMS_USB) += ems_usb.o |
6 | obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o | 6 | obj-$(CONFIG_CAN_ESD_USB2) += esd_usb2.o |
7 | obj-$(CONFIG_CAN_PEAK_USB) += peak_usb/ | ||
7 | 8 | ||
8 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG | 9 | ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG |
diff --git a/drivers/net/can/usb/peak_usb/Makefile b/drivers/net/can/usb/peak_usb/Makefile new file mode 100644 index 000000000000..bbb23ceb65f6 --- /dev/null +++ b/drivers/net/can/usb/peak_usb/Makefile | |||
@@ -0,0 +1,2 @@ | |||
1 | obj-$(CONFIG_CAN_PEAK_USB) += peak_usb.o | ||
2 | peak_usb-y = pcan_usb_core.o | ||
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c new file mode 100644 index 000000000000..d2f91f737871 --- /dev/null +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c | |||
@@ -0,0 +1,951 @@ | |||
1 | /* | ||
2 | * CAN driver for PEAK System USB adapters | ||
3 | * Derived from the PCAN project file driver/src/pcan_usb_core.c | ||
4 | * | ||
5 | * Copyright (C) 2003-2010 PEAK System-Technik GmbH | ||
6 | * Copyright (C) 2010-2012 Stephane Grosjean <s.grosjean@peak-system.com> | ||
7 | * | ||
8 | * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published | ||
12 | * by the Free Software Foundation; version 2 of the License. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | */ | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/signal.h> | ||
21 | #include <linux/slab.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/netdevice.h> | ||
24 | #include <linux/usb.h> | ||
25 | |||
26 | #include <linux/can.h> | ||
27 | #include <linux/can/dev.h> | ||
28 | #include <linux/can/error.h> | ||
29 | |||
30 | #include "pcan_usb_core.h" | ||
31 | |||
32 | MODULE_AUTHOR("Stephane Grosjean <s.grosjean@peak-system.com>"); | ||
33 | MODULE_DESCRIPTION("CAN driver for PEAK-System USB adapters"); | ||
34 | MODULE_LICENSE("GPL v2"); | ||
35 | |||
36 | /* Table of devices that work with this driver */ | ||
37 | static struct usb_device_id peak_usb_table[] = { | ||
38 | {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USB_PRODUCT_ID)}, | ||
39 | {USB_DEVICE(PCAN_USB_VENDOR_ID, PCAN_USBPRO_PRODUCT_ID)}, | ||
40 | {} /* Terminating entry */ | ||
41 | }; | ||
42 | |||
43 | MODULE_DEVICE_TABLE(usb, peak_usb_table); | ||
44 | |||
45 | /* List of supported PCAN-USB adapters (NULL terminated list) */ | ||
46 | static struct peak_usb_adapter *peak_usb_adapters_list[] = { | ||
47 | &pcan_usb, | ||
48 | &pcan_usb_pro, | ||
49 | NULL, | ||
50 | }; | ||
51 | |||
52 | /* | ||
53 | * dump memory | ||
54 | */ | ||
55 | #define DUMP_WIDTH 16 | ||
56 | void dump_mem(char *prompt, void *p, int l) | ||
57 | { | ||
58 | pr_info("%s dumping %s (%d bytes):\n", | ||
59 | PCAN_USB_DRIVER_NAME, prompt ? prompt : "memory", l); | ||
60 | print_hex_dump(KERN_INFO, PCAN_USB_DRIVER_NAME " ", DUMP_PREFIX_NONE, | ||
61 | DUMP_WIDTH, 1, p, l, false); | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * initialize a time_ref object with usb adapter own settings | ||
66 | */ | ||
67 | void peak_usb_init_time_ref(struct peak_time_ref *time_ref, | ||
68 | struct peak_usb_adapter *adapter) | ||
69 | { | ||
70 | if (time_ref) { | ||
71 | memset(time_ref, 0, sizeof(struct peak_time_ref)); | ||
72 | time_ref->adapter = adapter; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | static void peak_usb_add_us(struct timeval *tv, u32 delta_us) | ||
77 | { | ||
78 | /* number of s. to add to final time */ | ||
79 | u32 delta_s = delta_us / 1000000; | ||
80 | |||
81 | delta_us -= delta_s * 1000000; | ||
82 | |||
83 | tv->tv_usec += delta_us; | ||
84 | if (tv->tv_usec >= 1000000) { | ||
85 | tv->tv_usec -= 1000000; | ||
86 | delta_s++; | ||
87 | } | ||
88 | tv->tv_sec += delta_s; | ||
89 | } | ||
90 | |||
91 | /* | ||
92 | * sometimes, another now may be more recent than current one... | ||
93 | */ | ||
94 | void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now) | ||
95 | { | ||
96 | time_ref->ts_dev_2 = ts_now; | ||
97 | |||
98 | /* should wait at least two passes before computing */ | ||
99 | if (time_ref->tv_host.tv_sec > 0) { | ||
100 | u32 delta_ts = time_ref->ts_dev_2 - time_ref->ts_dev_1; | ||
101 | |||
102 | if (time_ref->ts_dev_2 < time_ref->ts_dev_1) | ||
103 | delta_ts &= (1 << time_ref->adapter->ts_used_bits) - 1; | ||
104 | |||
105 | time_ref->ts_total += delta_ts; | ||
106 | } | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * register device timestamp as now | ||
111 | */ | ||
112 | void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now) | ||
113 | { | ||
114 | if (time_ref->tv_host_0.tv_sec == 0) { | ||
115 | /* use monotonic clock to correctly compute further deltas */ | ||
116 | time_ref->tv_host_0 = ktime_to_timeval(ktime_get()); | ||
117 | time_ref->tv_host.tv_sec = 0; | ||
118 | } else { | ||
119 | /* | ||
120 | * delta_us should not be >= 2^32 => delta_s should be < 4294 | ||
121 | * handle 32-bits wrapping here: if count of s. reaches 4200, | ||
122 | * reset counters and change time base | ||
123 | */ | ||
124 | if (time_ref->tv_host.tv_sec != 0) { | ||
125 | u32 delta_s = time_ref->tv_host.tv_sec | ||
126 | - time_ref->tv_host_0.tv_sec; | ||
127 | if (delta_s > 4200) { | ||
128 | time_ref->tv_host_0 = time_ref->tv_host; | ||
129 | time_ref->ts_total = 0; | ||
130 | } | ||
131 | } | ||
132 | |||
133 | time_ref->tv_host = ktime_to_timeval(ktime_get()); | ||
134 | time_ref->tick_count++; | ||
135 | } | ||
136 | |||
137 | time_ref->ts_dev_1 = time_ref->ts_dev_2; | ||
138 | peak_usb_update_ts_now(time_ref, ts_now); | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * compute timeval according to current ts and time_ref data | ||
143 | */ | ||
144 | void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts, | ||
145 | struct timeval *tv) | ||
146 | { | ||
147 | /* protect from getting timeval before setting now */ | ||
148 | if (time_ref->tv_host.tv_sec > 0) { | ||
149 | u64 delta_us; | ||
150 | |||
151 | delta_us = ts - time_ref->ts_dev_2; | ||
152 | if (ts < time_ref->ts_dev_2) | ||
153 | delta_us &= (1 << time_ref->adapter->ts_used_bits) - 1; | ||
154 | |||
155 | delta_us += time_ref->ts_total; | ||
156 | |||
157 | delta_us *= time_ref->adapter->us_per_ts_scale; | ||
158 | delta_us >>= time_ref->adapter->us_per_ts_shift; | ||
159 | |||
160 | *tv = time_ref->tv_host_0; | ||
161 | peak_usb_add_us(tv, (u32)delta_us); | ||
162 | } else { | ||
163 | *tv = ktime_to_timeval(ktime_get()); | ||
164 | } | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * callback for bulk Rx urb | ||
169 | */ | ||
170 | static void peak_usb_read_bulk_callback(struct urb *urb) | ||
171 | { | ||
172 | struct peak_usb_device *dev = urb->context; | ||
173 | struct net_device *netdev; | ||
174 | int err; | ||
175 | |||
176 | netdev = dev->netdev; | ||
177 | |||
178 | if (!netif_device_present(netdev)) | ||
179 | return; | ||
180 | |||
181 | /* check reception status */ | ||
182 | switch (urb->status) { | ||
183 | case 0: | ||
184 | /* success */ | ||
185 | break; | ||
186 | |||
187 | case -EILSEQ: | ||
188 | case -ENOENT: | ||
189 | case -ECONNRESET: | ||
190 | case -ESHUTDOWN: | ||
191 | return; | ||
192 | |||
193 | default: | ||
194 | if (net_ratelimit()) | ||
195 | netdev_err(netdev, | ||
196 | "Rx urb aborted (%d)\n", urb->status); | ||
197 | goto resubmit_urb; | ||
198 | } | ||
199 | |||
200 | /* protect from any incoming empty msgs */ | ||
201 | if ((urb->actual_length > 0) && (dev->adapter->dev_decode_buf)) { | ||
202 | /* handle these kinds of msgs only if _start callback called */ | ||
203 | if (dev->state & PCAN_USB_STATE_STARTED) { | ||
204 | err = dev->adapter->dev_decode_buf(dev, urb); | ||
205 | if (err) | ||
206 | dump_mem("received usb message", | ||
207 | urb->transfer_buffer, | ||
208 | urb->transfer_buffer_length); | ||
209 | } | ||
210 | } | ||
211 | |||
212 | resubmit_urb: | ||
213 | usb_fill_bulk_urb(urb, dev->udev, | ||
214 | usb_rcvbulkpipe(dev->udev, dev->ep_msg_in), | ||
215 | urb->transfer_buffer, dev->adapter->rx_buffer_size, | ||
216 | peak_usb_read_bulk_callback, dev); | ||
217 | |||
218 | usb_anchor_urb(urb, &dev->rx_submitted); | ||
219 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
220 | if (!err) | ||
221 | return; | ||
222 | |||
223 | usb_unanchor_urb(urb); | ||
224 | |||
225 | if (err == -ENODEV) | ||
226 | netif_device_detach(netdev); | ||
227 | else | ||
228 | netdev_err(netdev, "failed resubmitting read bulk urb: %d\n", | ||
229 | err); | ||
230 | } | ||
231 | |||
232 | /* | ||
233 | * callback for bulk Tx urb | ||
234 | */ | ||
235 | static void peak_usb_write_bulk_callback(struct urb *urb) | ||
236 | { | ||
237 | struct peak_tx_urb_context *context = urb->context; | ||
238 | struct peak_usb_device *dev; | ||
239 | struct net_device *netdev; | ||
240 | |||
241 | BUG_ON(!context); | ||
242 | |||
243 | dev = context->dev; | ||
244 | netdev = dev->netdev; | ||
245 | |||
246 | atomic_dec(&dev->active_tx_urbs); | ||
247 | |||
248 | if (!netif_device_present(netdev)) | ||
249 | return; | ||
250 | |||
251 | /* check tx status */ | ||
252 | switch (urb->status) { | ||
253 | case 0: | ||
254 | /* transmission complete */ | ||
255 | netdev->stats.tx_packets++; | ||
256 | netdev->stats.tx_bytes += context->dlc; | ||
257 | |||
258 | /* prevent tx timeout */ | ||
259 | netdev->trans_start = jiffies; | ||
260 | break; | ||
261 | |||
262 | default: | ||
263 | if (net_ratelimit()) | ||
264 | netdev_err(netdev, "Tx urb aborted (%d)\n", | ||
265 | urb->status); | ||
266 | case -EPROTO: | ||
267 | case -ENOENT: | ||
268 | case -ECONNRESET: | ||
269 | case -ESHUTDOWN: | ||
270 | |||
271 | break; | ||
272 | } | ||
273 | |||
274 | /* should always release echo skb and corresponding context */ | ||
275 | can_get_echo_skb(netdev, context->echo_index); | ||
276 | context->echo_index = PCAN_USB_MAX_TX_URBS; | ||
277 | |||
278 | /* do wakeup tx queue in case of success only */ | ||
279 | if (!urb->status) | ||
280 | netif_wake_queue(netdev); | ||
281 | } | ||
282 | |||
283 | /* | ||
284 | * called by netdev to send one skb on the CAN interface. | ||
285 | */ | ||
286 | static netdev_tx_t peak_usb_ndo_start_xmit(struct sk_buff *skb, | ||
287 | struct net_device *netdev) | ||
288 | { | ||
289 | struct peak_usb_device *dev = netdev_priv(netdev); | ||
290 | struct peak_tx_urb_context *context = NULL; | ||
291 | struct net_device_stats *stats = &netdev->stats; | ||
292 | struct can_frame *cf = (struct can_frame *)skb->data; | ||
293 | struct urb *urb; | ||
294 | u8 *obuf; | ||
295 | int i, err; | ||
296 | size_t size = dev->adapter->tx_buffer_size; | ||
297 | |||
298 | if (can_dropped_invalid_skb(netdev, skb)) | ||
299 | return NETDEV_TX_OK; | ||
300 | |||
301 | for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) | ||
302 | if (dev->tx_contexts[i].echo_index == PCAN_USB_MAX_TX_URBS) { | ||
303 | context = dev->tx_contexts + i; | ||
304 | break; | ||
305 | } | ||
306 | |||
307 | if (!context) { | ||
308 | /* should not occur except during restart */ | ||
309 | return NETDEV_TX_BUSY; | ||
310 | } | ||
311 | |||
312 | urb = context->urb; | ||
313 | obuf = urb->transfer_buffer; | ||
314 | |||
315 | err = dev->adapter->dev_encode_msg(dev, skb, obuf, &size); | ||
316 | if (err) { | ||
317 | if (net_ratelimit()) | ||
318 | netdev_err(netdev, "packet dropped\n"); | ||
319 | dev_kfree_skb(skb); | ||
320 | stats->tx_dropped++; | ||
321 | return NETDEV_TX_OK; | ||
322 | } | ||
323 | |||
324 | context->echo_index = i; | ||
325 | context->dlc = cf->can_dlc; | ||
326 | |||
327 | usb_anchor_urb(urb, &dev->tx_submitted); | ||
328 | |||
329 | can_put_echo_skb(skb, netdev, context->echo_index); | ||
330 | |||
331 | atomic_inc(&dev->active_tx_urbs); | ||
332 | |||
333 | err = usb_submit_urb(urb, GFP_ATOMIC); | ||
334 | if (err) { | ||
335 | can_free_echo_skb(netdev, context->echo_index); | ||
336 | |||
337 | usb_unanchor_urb(urb); | ||
338 | |||
339 | /* this context is not used in fact */ | ||
340 | context->echo_index = PCAN_USB_MAX_TX_URBS; | ||
341 | |||
342 | atomic_dec(&dev->active_tx_urbs); | ||
343 | |||
344 | switch (err) { | ||
345 | case -ENODEV: | ||
346 | netif_device_detach(netdev); | ||
347 | break; | ||
348 | default: | ||
349 | netdev_warn(netdev, "tx urb submitting failed err=%d\n", | ||
350 | err); | ||
351 | case -ENOENT: | ||
352 | /* cable unplugged */ | ||
353 | stats->tx_dropped++; | ||
354 | } | ||
355 | } else { | ||
356 | netdev->trans_start = jiffies; | ||
357 | |||
358 | /* slow down tx path */ | ||
359 | if (atomic_read(&dev->active_tx_urbs) >= PCAN_USB_MAX_TX_URBS) | ||
360 | netif_stop_queue(netdev); | ||
361 | } | ||
362 | |||
363 | return NETDEV_TX_OK; | ||
364 | } | ||
365 | |||
366 | /* | ||
367 | * start the CAN interface. | ||
368 | * Rx and Tx urbs are allocated here. Rx urbs are submitted here. | ||
369 | */ | ||
370 | static int peak_usb_start(struct peak_usb_device *dev) | ||
371 | { | ||
372 | struct net_device *netdev = dev->netdev; | ||
373 | int err, i; | ||
374 | |||
375 | for (i = 0; i < PCAN_USB_MAX_RX_URBS; i++) { | ||
376 | struct urb *urb; | ||
377 | u8 *buf; | ||
378 | |||
379 | /* create a URB, and a buffer for it, to receive usb messages */ | ||
380 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
381 | if (!urb) { | ||
382 | netdev_err(netdev, "No memory left for URBs\n"); | ||
383 | err = -ENOMEM; | ||
384 | break; | ||
385 | } | ||
386 | |||
387 | buf = kmalloc(dev->adapter->rx_buffer_size, GFP_KERNEL); | ||
388 | if (!buf) { | ||
389 | netdev_err(netdev, "No memory left for USB buffer\n"); | ||
390 | usb_free_urb(urb); | ||
391 | err = -ENOMEM; | ||
392 | break; | ||
393 | } | ||
394 | |||
395 | usb_fill_bulk_urb(urb, dev->udev, | ||
396 | usb_rcvbulkpipe(dev->udev, dev->ep_msg_in), | ||
397 | buf, dev->adapter->rx_buffer_size, | ||
398 | peak_usb_read_bulk_callback, dev); | ||
399 | |||
400 | /* ask last usb_free_urb() to also kfree() transfer_buffer */ | ||
401 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
402 | usb_anchor_urb(urb, &dev->rx_submitted); | ||
403 | |||
404 | err = usb_submit_urb(urb, GFP_KERNEL); | ||
405 | if (err) { | ||
406 | if (err == -ENODEV) | ||
407 | netif_device_detach(dev->netdev); | ||
408 | |||
409 | usb_unanchor_urb(urb); | ||
410 | kfree(buf); | ||
411 | usb_free_urb(urb); | ||
412 | break; | ||
413 | } | ||
414 | |||
415 | /* drop reference, USB core will take care of freeing it */ | ||
416 | usb_free_urb(urb); | ||
417 | } | ||
418 | |||
419 | /* did we submit any URBs? Warn if we was not able to submit all urbs */ | ||
420 | if (i < PCAN_USB_MAX_RX_URBS) { | ||
421 | if (i == 0) { | ||
422 | netdev_err(netdev, "couldn't setup any rx URB\n"); | ||
423 | return err; | ||
424 | } | ||
425 | |||
426 | netdev_warn(netdev, "rx performance may be slow\n"); | ||
427 | } | ||
428 | |||
429 | /* pre-alloc tx buffers and corresponding urbs */ | ||
430 | for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) { | ||
431 | struct peak_tx_urb_context *context; | ||
432 | struct urb *urb; | ||
433 | u8 *buf; | ||
434 | |||
435 | /* create a URB and a buffer for it, to transmit usb messages */ | ||
436 | urb = usb_alloc_urb(0, GFP_KERNEL); | ||
437 | if (!urb) { | ||
438 | netdev_err(netdev, "No memory left for URBs\n"); | ||
439 | err = -ENOMEM; | ||
440 | break; | ||
441 | } | ||
442 | |||
443 | buf = kmalloc(dev->adapter->tx_buffer_size, GFP_KERNEL); | ||
444 | if (!buf) { | ||
445 | netdev_err(netdev, "No memory left for USB buffer\n"); | ||
446 | usb_free_urb(urb); | ||
447 | err = -ENOMEM; | ||
448 | break; | ||
449 | } | ||
450 | |||
451 | context = dev->tx_contexts + i; | ||
452 | context->dev = dev; | ||
453 | context->urb = urb; | ||
454 | |||
455 | usb_fill_bulk_urb(urb, dev->udev, | ||
456 | usb_sndbulkpipe(dev->udev, dev->ep_msg_out), | ||
457 | buf, dev->adapter->tx_buffer_size, | ||
458 | peak_usb_write_bulk_callback, context); | ||
459 | |||
460 | /* ask last usb_free_urb() to also kfree() transfer_buffer */ | ||
461 | urb->transfer_flags |= URB_FREE_BUFFER; | ||
462 | } | ||
463 | |||
464 | /* warn if we were not able to allocate enough tx contexts */ | ||
465 | if (i < PCAN_USB_MAX_TX_URBS) { | ||
466 | if (i == 0) { | ||
467 | netdev_err(netdev, "couldn't setup any tx URB\n"); | ||
468 | return err; | ||
469 | } | ||
470 | |||
471 | netdev_warn(netdev, "tx performance may be slow\n"); | ||
472 | } | ||
473 | |||
474 | if (dev->adapter->dev_start) { | ||
475 | err = dev->adapter->dev_start(dev); | ||
476 | if (err) | ||
477 | goto failed; | ||
478 | } | ||
479 | |||
480 | dev->state |= PCAN_USB_STATE_STARTED; | ||
481 | |||
482 | /* can set bus on now */ | ||
483 | if (dev->adapter->dev_set_bus) { | ||
484 | err = dev->adapter->dev_set_bus(dev, 1); | ||
485 | if (err) | ||
486 | goto failed; | ||
487 | } | ||
488 | |||
489 | dev->can.state = CAN_STATE_ERROR_ACTIVE; | ||
490 | |||
491 | return 0; | ||
492 | |||
493 | failed: | ||
494 | if (err == -ENODEV) | ||
495 | netif_device_detach(dev->netdev); | ||
496 | |||
497 | netdev_warn(netdev, "couldn't submit control: %d\n", err); | ||
498 | |||
499 | return err; | ||
500 | } | ||
501 | |||
502 | /* | ||
503 | * called by netdev to open the corresponding CAN interface. | ||
504 | */ | ||
505 | static int peak_usb_ndo_open(struct net_device *netdev) | ||
506 | { | ||
507 | struct peak_usb_device *dev = netdev_priv(netdev); | ||
508 | int err; | ||
509 | |||
510 | /* common open */ | ||
511 | err = open_candev(netdev); | ||
512 | if (err) | ||
513 | return err; | ||
514 | |||
515 | /* finally start device */ | ||
516 | err = peak_usb_start(dev); | ||
517 | if (err) { | ||
518 | netdev_err(netdev, "couldn't start device: %d\n", err); | ||
519 | close_candev(netdev); | ||
520 | return err; | ||
521 | } | ||
522 | |||
523 | dev->open_time = jiffies; | ||
524 | netif_start_queue(netdev); | ||
525 | |||
526 | return 0; | ||
527 | } | ||
528 | |||
529 | /* | ||
530 | * unlink in-flight Rx and Tx urbs and free their memory. | ||
531 | */ | ||
532 | static void peak_usb_unlink_all_urbs(struct peak_usb_device *dev) | ||
533 | { | ||
534 | int i; | ||
535 | |||
536 | /* free all Rx (submitted) urbs */ | ||
537 | usb_kill_anchored_urbs(&dev->rx_submitted); | ||
538 | |||
539 | /* free unsubmitted Tx urbs first */ | ||
540 | for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) { | ||
541 | struct urb *urb = dev->tx_contexts[i].urb; | ||
542 | |||
543 | if (!urb || | ||
544 | dev->tx_contexts[i].echo_index != PCAN_USB_MAX_TX_URBS) { | ||
545 | /* | ||
546 | * this urb is already released or always submitted, | ||
547 | * let usb core free by itself | ||
548 | */ | ||
549 | continue; | ||
550 | } | ||
551 | |||
552 | usb_free_urb(urb); | ||
553 | dev->tx_contexts[i].urb = NULL; | ||
554 | } | ||
555 | |||
556 | /* then free all submitted Tx urbs */ | ||
557 | usb_kill_anchored_urbs(&dev->tx_submitted); | ||
558 | atomic_set(&dev->active_tx_urbs, 0); | ||
559 | } | ||
560 | |||
561 | /* | ||
562 | * called by netdev to close the corresponding CAN interface. | ||
563 | */ | ||
564 | static int peak_usb_ndo_stop(struct net_device *netdev) | ||
565 | { | ||
566 | struct peak_usb_device *dev = netdev_priv(netdev); | ||
567 | |||
568 | dev->state &= ~PCAN_USB_STATE_STARTED; | ||
569 | netif_stop_queue(netdev); | ||
570 | |||
571 | /* unlink all pending urbs and free used memory */ | ||
572 | peak_usb_unlink_all_urbs(dev); | ||
573 | |||
574 | if (dev->adapter->dev_stop) | ||
575 | dev->adapter->dev_stop(dev); | ||
576 | |||
577 | close_candev(netdev); | ||
578 | |||
579 | dev->open_time = 0; | ||
580 | dev->can.state = CAN_STATE_STOPPED; | ||
581 | |||
582 | /* can set bus off now */ | ||
583 | if (dev->adapter->dev_set_bus) { | ||
584 | int err = dev->adapter->dev_set_bus(dev, 0); | ||
585 | if (err) | ||
586 | return err; | ||
587 | } | ||
588 | |||
589 | return 0; | ||
590 | } | ||
591 | |||
592 | /* | ||
593 | * handle end of waiting for the device to reset | ||
594 | */ | ||
595 | void peak_usb_restart_complete(struct peak_usb_device *dev) | ||
596 | { | ||
597 | /* finally MUST update can state */ | ||
598 | dev->can.state = CAN_STATE_ERROR_ACTIVE; | ||
599 | |||
600 | /* netdev queue can be awaken now */ | ||
601 | netif_wake_queue(dev->netdev); | ||
602 | } | ||
603 | |||
604 | void peak_usb_async_complete(struct urb *urb) | ||
605 | { | ||
606 | kfree(urb->transfer_buffer); | ||
607 | usb_free_urb(urb); | ||
608 | } | ||
609 | |||
610 | /* | ||
611 | * device (auto-)restart mechanism runs in a timer context => | ||
612 | * MUST handle restart with asynchronous usb transfers | ||
613 | */ | ||
614 | static int peak_usb_restart(struct peak_usb_device *dev) | ||
615 | { | ||
616 | struct urb *urb; | ||
617 | int err; | ||
618 | u8 *buf; | ||
619 | |||
620 | /* | ||
621 | * if device doesn't define any asynchronous restart handler, simply | ||
622 | * wake the netdev queue up | ||
623 | */ | ||
624 | if (!dev->adapter->dev_restart_async) { | ||
625 | peak_usb_restart_complete(dev); | ||
626 | return 0; | ||
627 | } | ||
628 | |||
629 | /* first allocate a urb to handle the asynchronous steps */ | ||
630 | urb = usb_alloc_urb(0, GFP_ATOMIC); | ||
631 | if (!urb) { | ||
632 | netdev_err(dev->netdev, "no memory left for urb\n"); | ||
633 | return -ENOMEM; | ||
634 | } | ||
635 | |||
636 | /* also allocate enough space for the commands to send */ | ||
637 | buf = kmalloc(PCAN_USB_MAX_CMD_LEN, GFP_ATOMIC); | ||
638 | if (!buf) { | ||
639 | netdev_err(dev->netdev, "no memory left for async cmd\n"); | ||
640 | usb_free_urb(urb); | ||
641 | return -ENOMEM; | ||
642 | } | ||
643 | |||
644 | /* call the device specific handler for the restart */ | ||
645 | err = dev->adapter->dev_restart_async(dev, urb, buf); | ||
646 | if (!err) | ||
647 | return 0; | ||
648 | |||
649 | kfree(buf); | ||
650 | usb_free_urb(urb); | ||
651 | |||
652 | return err; | ||
653 | } | ||
654 | |||
655 | /* | ||
656 | * candev callback used to change CAN mode. | ||
657 | * Warning: this is called from a timer context! | ||
658 | */ | ||
659 | static int peak_usb_set_mode(struct net_device *netdev, enum can_mode mode) | ||
660 | { | ||
661 | struct peak_usb_device *dev = netdev_priv(netdev); | ||
662 | int err = 0; | ||
663 | |||
664 | if (!dev->open_time) | ||
665 | return -EINVAL; | ||
666 | |||
667 | switch (mode) { | ||
668 | case CAN_MODE_START: | ||
669 | err = peak_usb_restart(dev); | ||
670 | if (err) | ||
671 | netdev_err(netdev, "couldn't start device (err %d)\n", | ||
672 | err); | ||
673 | break; | ||
674 | |||
675 | default: | ||
676 | return -EOPNOTSUPP; | ||
677 | } | ||
678 | |||
679 | return err; | ||
680 | } | ||
681 | |||
682 | /* | ||
683 | * candev callback used to set device bitrate. | ||
684 | */ | ||
685 | static int peak_usb_set_bittiming(struct net_device *netdev) | ||
686 | { | ||
687 | struct peak_usb_device *dev = netdev_priv(netdev); | ||
688 | struct can_bittiming *bt = &dev->can.bittiming; | ||
689 | |||
690 | if (dev->adapter->dev_set_bittiming) { | ||
691 | int err = dev->adapter->dev_set_bittiming(dev, bt); | ||
692 | |||
693 | if (err) | ||
694 | netdev_info(netdev, "couldn't set bitrate (err %d)\n", | ||
695 | err); | ||
696 | return err; | ||
697 | } | ||
698 | |||
699 | return 0; | ||
700 | } | ||
701 | |||
702 | static const struct net_device_ops peak_usb_netdev_ops = { | ||
703 | .ndo_open = peak_usb_ndo_open, | ||
704 | .ndo_stop = peak_usb_ndo_stop, | ||
705 | .ndo_start_xmit = peak_usb_ndo_start_xmit, | ||
706 | }; | ||
707 | |||
708 | /* | ||
709 | * create one device which is attached to CAN controller #ctrl_idx of the | ||
710 | * usb adapter. | ||
711 | */ | ||
712 | static int peak_usb_create_dev(struct peak_usb_adapter *peak_usb_adapter, | ||
713 | struct usb_interface *intf, int ctrl_idx) | ||
714 | { | ||
715 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
716 | int sizeof_candev = peak_usb_adapter->sizeof_dev_private; | ||
717 | struct peak_usb_device *dev; | ||
718 | struct net_device *netdev; | ||
719 | int i, err; | ||
720 | u16 tmp16; | ||
721 | |||
722 | if (sizeof_candev < sizeof(struct peak_usb_device)) | ||
723 | sizeof_candev = sizeof(struct peak_usb_device); | ||
724 | |||
725 | netdev = alloc_candev(sizeof_candev, PCAN_USB_MAX_TX_URBS); | ||
726 | if (!netdev) { | ||
727 | dev_err(&intf->dev, "%s: couldn't alloc candev\n", | ||
728 | PCAN_USB_DRIVER_NAME); | ||
729 | return -ENOMEM; | ||
730 | } | ||
731 | |||
732 | dev = netdev_priv(netdev); | ||
733 | |||
734 | /* allocate a buffer large enough to send commands */ | ||
735 | dev->cmd_buf = kmalloc(PCAN_USB_MAX_CMD_LEN, GFP_KERNEL); | ||
736 | if (!dev->cmd_buf) { | ||
737 | dev_err(&intf->dev, "%s: couldn't alloc cmd buffer\n", | ||
738 | PCAN_USB_DRIVER_NAME); | ||
739 | err = -ENOMEM; | ||
740 | goto lbl_set_intf_data; | ||
741 | } | ||
742 | |||
743 | dev->udev = usb_dev; | ||
744 | dev->netdev = netdev; | ||
745 | dev->adapter = peak_usb_adapter; | ||
746 | dev->ctrl_idx = ctrl_idx; | ||
747 | dev->state = PCAN_USB_STATE_CONNECTED; | ||
748 | |||
749 | dev->ep_msg_in = peak_usb_adapter->ep_msg_in; | ||
750 | dev->ep_msg_out = peak_usb_adapter->ep_msg_out[ctrl_idx]; | ||
751 | |||
752 | dev->can.clock = peak_usb_adapter->clock; | ||
753 | dev->can.bittiming_const = &peak_usb_adapter->bittiming_const; | ||
754 | dev->can.do_set_bittiming = peak_usb_set_bittiming; | ||
755 | dev->can.do_set_mode = peak_usb_set_mode; | ||
756 | dev->can.ctrlmode_supported = CAN_CTRLMODE_3_SAMPLES | | ||
757 | CAN_CTRLMODE_LISTENONLY; | ||
758 | |||
759 | netdev->netdev_ops = &peak_usb_netdev_ops; | ||
760 | |||
761 | netdev->flags |= IFF_ECHO; /* we support local echo */ | ||
762 | |||
763 | init_usb_anchor(&dev->rx_submitted); | ||
764 | |||
765 | init_usb_anchor(&dev->tx_submitted); | ||
766 | atomic_set(&dev->active_tx_urbs, 0); | ||
767 | |||
768 | for (i = 0; i < PCAN_USB_MAX_TX_URBS; i++) | ||
769 | dev->tx_contexts[i].echo_index = PCAN_USB_MAX_TX_URBS; | ||
770 | |||
771 | dev->prev_siblings = usb_get_intfdata(intf); | ||
772 | usb_set_intfdata(intf, dev); | ||
773 | |||
774 | SET_NETDEV_DEV(netdev, &intf->dev); | ||
775 | |||
776 | err = register_candev(netdev); | ||
777 | if (err) { | ||
778 | dev_err(&intf->dev, "couldn't register CAN device: %d\n", err); | ||
779 | goto lbl_free_cmd_buf; | ||
780 | } | ||
781 | |||
782 | if (dev->prev_siblings) | ||
783 | (dev->prev_siblings)->next_siblings = dev; | ||
784 | |||
785 | /* keep hw revision into the netdevice */ | ||
786 | tmp16 = le16_to_cpu(usb_dev->descriptor.bcdDevice); | ||
787 | dev->device_rev = tmp16 >> 8; | ||
788 | |||
789 | if (dev->adapter->dev_init) { | ||
790 | err = dev->adapter->dev_init(dev); | ||
791 | if (err) | ||
792 | goto lbl_free_cmd_buf; | ||
793 | } | ||
794 | |||
795 | /* set bus off */ | ||
796 | if (dev->adapter->dev_set_bus) { | ||
797 | err = dev->adapter->dev_set_bus(dev, 0); | ||
798 | if (err) | ||
799 | goto lbl_free_cmd_buf; | ||
800 | } | ||
801 | |||
802 | /* get device number early */ | ||
803 | if (dev->adapter->dev_get_device_id) | ||
804 | dev->adapter->dev_get_device_id(dev, &dev->device_number); | ||
805 | |||
806 | netdev_info(netdev, "attached to %s channel %u (device %u)\n", | ||
807 | peak_usb_adapter->name, ctrl_idx, dev->device_number); | ||
808 | |||
809 | return 0; | ||
810 | |||
811 | lbl_free_cmd_buf: | ||
812 | kfree(dev->cmd_buf); | ||
813 | |||
814 | lbl_set_intf_data: | ||
815 | usb_set_intfdata(intf, dev->prev_siblings); | ||
816 | free_candev(netdev); | ||
817 | |||
818 | return err; | ||
819 | } | ||
820 | |||
821 | /* | ||
822 | * called by the usb core when the device is unplugged from the system | ||
823 | */ | ||
824 | static void peak_usb_disconnect(struct usb_interface *intf) | ||
825 | { | ||
826 | struct peak_usb_device *dev; | ||
827 | |||
828 | /* unregister as many netdev devices as siblings */ | ||
829 | for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) { | ||
830 | struct net_device *netdev = dev->netdev; | ||
831 | char name[IFNAMSIZ]; | ||
832 | |||
833 | dev->state &= ~PCAN_USB_STATE_CONNECTED; | ||
834 | strncpy(name, netdev->name, IFNAMSIZ); | ||
835 | |||
836 | unregister_netdev(netdev); | ||
837 | free_candev(netdev); | ||
838 | |||
839 | kfree(dev->cmd_buf); | ||
840 | dev->next_siblings = NULL; | ||
841 | if (dev->adapter->dev_free) | ||
842 | dev->adapter->dev_free(dev); | ||
843 | |||
844 | dev_info(&intf->dev, "%s removed\n", name); | ||
845 | } | ||
846 | |||
847 | usb_set_intfdata(intf, NULL); | ||
848 | } | ||
849 | |||
850 | /* | ||
851 | * probe function for new PEAK-System devices | ||
852 | */ | ||
853 | static int peak_usb_probe(struct usb_interface *intf, | ||
854 | const struct usb_device_id *id) | ||
855 | { | ||
856 | struct usb_device *usb_dev = interface_to_usbdev(intf); | ||
857 | struct peak_usb_adapter *peak_usb_adapter, **pp; | ||
858 | int i, err = -ENOMEM; | ||
859 | |||
860 | usb_dev = interface_to_usbdev(intf); | ||
861 | |||
862 | /* get corresponding PCAN-USB adapter */ | ||
863 | for (pp = peak_usb_adapters_list; *pp; pp++) | ||
864 | if ((*pp)->device_id == usb_dev->descriptor.idProduct) | ||
865 | break; | ||
866 | |||
867 | peak_usb_adapter = *pp; | ||
868 | if (!peak_usb_adapter) { | ||
869 | /* should never come except device_id bad usage in this file */ | ||
870 | pr_err("%s: didn't find device id. 0x%x in devices list\n", | ||
871 | PCAN_USB_DRIVER_NAME, usb_dev->descriptor.idProduct); | ||
872 | return -ENODEV; | ||
873 | } | ||
874 | |||
875 | /* got corresponding adapter: check if it handles current interface */ | ||
876 | if (peak_usb_adapter->intf_probe) { | ||
877 | err = peak_usb_adapter->intf_probe(intf); | ||
878 | if (err) | ||
879 | return err; | ||
880 | } | ||
881 | |||
882 | for (i = 0; i < peak_usb_adapter->ctrl_count; i++) { | ||
883 | err = peak_usb_create_dev(peak_usb_adapter, intf, i); | ||
884 | if (err) { | ||
885 | /* deregister already created devices */ | ||
886 | peak_usb_disconnect(intf); | ||
887 | break; | ||
888 | } | ||
889 | } | ||
890 | |||
891 | return err; | ||
892 | } | ||
893 | |||
894 | /* usb specific object needed to register this driver with the usb subsystem */ | ||
895 | static struct usb_driver peak_usb_driver = { | ||
896 | .name = PCAN_USB_DRIVER_NAME, | ||
897 | .disconnect = peak_usb_disconnect, | ||
898 | .probe = peak_usb_probe, | ||
899 | .id_table = peak_usb_table, | ||
900 | }; | ||
901 | |||
902 | static int __init peak_usb_init(void) | ||
903 | { | ||
904 | int err; | ||
905 | |||
906 | /* register this driver with the USB subsystem */ | ||
907 | err = usb_register(&peak_usb_driver); | ||
908 | if (err) | ||
909 | pr_err("%s: usb_register failed (err %d)\n", | ||
910 | PCAN_USB_DRIVER_NAME, err); | ||
911 | |||
912 | return err; | ||
913 | } | ||
914 | |||
915 | static int peak_usb_do_device_exit(struct device *d, void *arg) | ||
916 | { | ||
917 | struct usb_interface *intf = to_usb_interface(d); | ||
918 | struct peak_usb_device *dev; | ||
919 | |||
920 | /* stop as many netdev devices as siblings */ | ||
921 | for (dev = usb_get_intfdata(intf); dev; dev = dev->prev_siblings) { | ||
922 | struct net_device *netdev = dev->netdev; | ||
923 | |||
924 | if (netif_device_present(netdev)) | ||
925 | if (dev->adapter->dev_exit) | ||
926 | dev->adapter->dev_exit(dev); | ||
927 | } | ||
928 | |||
929 | return 0; | ||
930 | } | ||
931 | |||
932 | static void __exit peak_usb_exit(void) | ||
933 | { | ||
934 | int err; | ||
935 | |||
936 | /* last chance do send any synchronous commands here */ | ||
937 | err = driver_for_each_device(&peak_usb_driver.drvwrap.driver, NULL, | ||
938 | NULL, peak_usb_do_device_exit); | ||
939 | if (err) | ||
940 | pr_err("%s: failed to stop all can devices (err %d)\n", | ||
941 | PCAN_USB_DRIVER_NAME, err); | ||
942 | |||
943 | /* deregister this driver with the USB subsystem */ | ||
944 | usb_deregister(&peak_usb_driver); | ||
945 | |||
946 | pr_info("%s: PCAN-USB interfaces driver unloaded\n", | ||
947 | PCAN_USB_DRIVER_NAME); | ||
948 | } | ||
949 | |||
950 | module_init(peak_usb_init); | ||
951 | module_exit(peak_usb_exit); | ||
diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.h b/drivers/net/can/usb/peak_usb/pcan_usb_core.h new file mode 100644 index 000000000000..a948c5a89401 --- /dev/null +++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.h | |||
@@ -0,0 +1,146 @@ | |||
1 | /* | ||
2 | * CAN driver for PEAK System USB adapters | ||
3 | * Derived from the PCAN project file driver/src/pcan_usb_core.c | ||
4 | * | ||
5 | * Copyright (C) 2003-2010 PEAK System-Technik GmbH | ||
6 | * Copyright (C) 2010-2012 Stephane Grosjean <s.grosjean@peak-system.com> | ||
7 | * | ||
8 | * Many thanks to Klaus Hitschler <klaus.hitschler@gmx.de> | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published | ||
12 | * by the Free Software Foundation; version 2 of the License. | ||
13 | * | ||
14 | * This program is distributed in the hope that it will be useful, but | ||
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
17 | * General Public License for more details. | ||
18 | */ | ||
19 | #ifndef PCAN_USB_CORE_H | ||
20 | #define PCAN_USB_CORE_H | ||
21 | |||
22 | /* PEAK-System vendor id. */ | ||
23 | #define PCAN_USB_VENDOR_ID 0x0c72 | ||
24 | |||
25 | /* supported device ids. */ | ||
26 | #define PCAN_USB_PRODUCT_ID 0x000c | ||
27 | #define PCAN_USBPRO_PRODUCT_ID 0x000d | ||
28 | |||
29 | #define PCAN_USB_DRIVER_NAME "peak_usb" | ||
30 | |||
31 | /* number of urbs that are submitted for rx/tx per channel */ | ||
32 | #define PCAN_USB_MAX_RX_URBS 4 | ||
33 | #define PCAN_USB_MAX_TX_URBS 10 | ||
34 | |||
35 | /* usb adapters maximum channels per usb interface */ | ||
36 | #define PCAN_USB_MAX_CHANNEL 2 | ||
37 | |||
38 | /* maximum length of the usb commands sent to/received from the devices */ | ||
39 | #define PCAN_USB_MAX_CMD_LEN 32 | ||
40 | |||
41 | struct peak_usb_device; | ||
42 | |||
43 | /* PEAK-System USB adapter descriptor */ | ||
44 | struct peak_usb_adapter { | ||
45 | char *name; | ||
46 | u32 device_id; | ||
47 | struct can_clock clock; | ||
48 | struct can_bittiming_const bittiming_const; | ||
49 | unsigned int ctrl_count; | ||
50 | |||
51 | int (*intf_probe)(struct usb_interface *intf); | ||
52 | |||
53 | int (*dev_init)(struct peak_usb_device *dev); | ||
54 | void (*dev_exit)(struct peak_usb_device *dev); | ||
55 | void (*dev_free)(struct peak_usb_device *dev); | ||
56 | int (*dev_open)(struct peak_usb_device *dev); | ||
57 | int (*dev_close)(struct peak_usb_device *dev); | ||
58 | int (*dev_set_bittiming)(struct peak_usb_device *dev, | ||
59 | struct can_bittiming *bt); | ||
60 | int (*dev_set_bus)(struct peak_usb_device *dev, u8 onoff); | ||
61 | int (*dev_get_device_id)(struct peak_usb_device *dev, u32 *device_id); | ||
62 | int (*dev_decode_buf)(struct peak_usb_device *dev, struct urb *urb); | ||
63 | int (*dev_encode_msg)(struct peak_usb_device *dev, struct sk_buff *skb, | ||
64 | u8 *obuf, size_t *size); | ||
65 | int (*dev_start)(struct peak_usb_device *dev); | ||
66 | int (*dev_stop)(struct peak_usb_device *dev); | ||
67 | int (*dev_restart_async)(struct peak_usb_device *dev, struct urb *urb, | ||
68 | u8 *buf); | ||
69 | u8 ep_msg_in; | ||
70 | u8 ep_msg_out[PCAN_USB_MAX_CHANNEL]; | ||
71 | u8 ts_used_bits; | ||
72 | u32 ts_period; | ||
73 | u8 us_per_ts_shift; | ||
74 | u32 us_per_ts_scale; | ||
75 | |||
76 | int rx_buffer_size; | ||
77 | int tx_buffer_size; | ||
78 | int sizeof_dev_private; | ||
79 | }; | ||
80 | |||
81 | extern struct peak_usb_adapter pcan_usb; | ||
82 | extern struct peak_usb_adapter pcan_usb_pro; | ||
83 | |||
84 | struct peak_time_ref { | ||
85 | struct timeval tv_host_0, tv_host; | ||
86 | u32 ts_dev_1, ts_dev_2; | ||
87 | u64 ts_total; | ||
88 | u32 tick_count; | ||
89 | struct peak_usb_adapter *adapter; | ||
90 | }; | ||
91 | |||
92 | struct peak_tx_urb_context { | ||
93 | struct peak_usb_device *dev; | ||
94 | u32 echo_index; | ||
95 | u8 dlc; | ||
96 | struct urb *urb; | ||
97 | }; | ||
98 | |||
99 | #define PCAN_USB_STATE_CONNECTED 0x00000001 | ||
100 | #define PCAN_USB_STATE_STARTED 0x00000002 | ||
101 | |||
102 | /* PEAK-System USB device */ | ||
103 | struct peak_usb_device { | ||
104 | struct can_priv can; | ||
105 | struct peak_usb_adapter *adapter; | ||
106 | unsigned int ctrl_idx; | ||
107 | int open_time; | ||
108 | u32 state; | ||
109 | |||
110 | struct sk_buff *echo_skb[PCAN_USB_MAX_TX_URBS]; | ||
111 | |||
112 | struct usb_device *udev; | ||
113 | struct net_device *netdev; | ||
114 | |||
115 | atomic_t active_tx_urbs; | ||
116 | struct usb_anchor tx_submitted; | ||
117 | struct peak_tx_urb_context tx_contexts[PCAN_USB_MAX_TX_URBS]; | ||
118 | |||
119 | u8 *cmd_buf; | ||
120 | struct usb_anchor rx_submitted; | ||
121 | |||
122 | u32 device_number; | ||
123 | u8 device_rev; | ||
124 | |||
125 | u8 ep_msg_in; | ||
126 | u8 ep_msg_out; | ||
127 | |||
128 | u16 bus_load; | ||
129 | |||
130 | struct peak_usb_device *prev_siblings; | ||
131 | struct peak_usb_device *next_siblings; | ||
132 | }; | ||
133 | |||
134 | void dump_mem(char *prompt, void *p, int l); | ||
135 | |||
136 | /* common timestamp management */ | ||
137 | void peak_usb_init_time_ref(struct peak_time_ref *time_ref, | ||
138 | struct peak_usb_adapter *adapter); | ||
139 | void peak_usb_update_ts_now(struct peak_time_ref *time_ref, u32 ts_now); | ||
140 | void peak_usb_set_ts_now(struct peak_time_ref *time_ref, u32 ts_now); | ||
141 | void peak_usb_get_ts_tv(struct peak_time_ref *time_ref, u32 ts, | ||
142 | struct timeval *tv); | ||
143 | |||
144 | void peak_usb_async_complete(struct urb *urb); | ||
145 | void peak_usb_restart_complete(struct peak_usb_device *dev); | ||
146 | #endif | ||