1 /*****************************************************************************/
2
3 /*
4 * plusb.c -- prolific pl-2301/pl-2302 driver.
5 *
6 * Copyright (C) 2000 Deti Fliegl (deti@fliegl.de)
7 * Copyright (C) 2000 Pavel Machek (pavel@suse.cz)
8 * Copyright (C) 2000 Eric Z. Ayers (eric@compgen.com)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
24 *
25 * This driver creates a network interface (plusb0, plusb1, ...) that will
26 * send messages over a USB host-host cable based on the Prolific ASIC.
27 * It works a lot like plip or PP over an RS-232C null modem cable.
28 *
29 * Expect speeds of around 330Kbytes/second over a UHCI host controller.
30 * OHCI should be faster. Increase the MTU for faster transfers of large
31 * files (up-to 800Kbytes/second). (16384 is a good size)
32 *
33 * $Id: plusb.c,v 1.18 2000/02/14 10:38:58 fliegl Exp $
34 *
35 * Changelog:
36 *
37 * v0.1 deti
38 * Original Version of driver.
39 * v0.2 15 Sep 2000 pavel
40 * Patches to decrease latency by rescheduling the bottom half of
41 * interrupt code.
42 * v0.3 10 Oct 2000 eric
43 * Patches to work in v2.2 backport (v2.4 changes the way net_dev.name
44 * is allocated)
45 * v0.4 19 Oct 2000 eric
46 * Some more performance fixes. Lock re-submitting urbs.
47 * Lower the number of sk_buff's to queue.
48 * v0.5 25 Oct 2000 eric
49 * Removed use of usb_bulk_msg() all together. This caused
50 * the driver to block in an interrupt context.
51 * Consolidate read urb submission into read_urb_submit().
52 * Performance is the same as v0.4.
53 * v0.5.1 27 Oct 2000 eric
54 * Extra debugging messages to help diagnose problem with uchi.o stack.
55 * v0.5.2 27 Oct 2000 eric
56 * Set the 'start' flag for the network device in plusb_net_start()
57 * and plusb_net_stop() (doesn't help)
58 * v0.5.3 27 Oct 2000 pavel
59 * Commented out handlers when -EPIPE is received,
60 * (remove calls to usb_clear_halt()) Since the callback is in
61 * an interrupt context, it doesn't help, it just panics
62 * the kernel. (what do we do?)
63 * Under high load, dev_alloc_skb() fails, the read URB must
64 * be re-submitted.
65 * Added plusb_change_mtu() and increased the size of _BULK_DATA_LEN
66 * v0.5.4 31 Oct 2000 eric
67 * Fix race between plusb_net_xmit() and plusb_bulk_write_complete()
68 * v0.5.5 1 Nov 2000 eric
69 * Remove dev->start field, otherwise, it won't compile in 2.4
70 * Use dev_kfree_skb_any(). (important in 2.4 kernel)
71 * v0.5.6 2 Nov 2000 pavel,eric
72 * Add calls to netif_stop_queue() and netif_start_queue()
73 * Drop packets that come in while the free list is empty.
74 * (This version is being submitted after the release of 2.4-test10)
75 * v0.5.7 6 Nov 2000
76 * Fix to not re-submit the urb on error to help when cables
77 * are yanked (not tested)
78 *
79 *
80 * KNOWN PROBLEMS: (Any suggestions greatfully accepted!)
81 *
82 * 2 Nov 2000
83 * - The shutdown for this may not be entirely clean. Sometimes, the
84 * kernel will Oops when the cable is unplugged, or
85 * if the plusb module is removed.
86 * - If you ifdown a device and then ifup it again, the link will not
87 * always work. You have to 'rmmod plusb ; modprobe plusb' on
88 * both machines to get it to work again. Something must be wrong with
89 * plusb_net_open() and plusb_net_start() ? Maybe
90 * the 'suspend' and 'resume' entry points need to be
91 * implemented?
92 * - Needs to handle -EPIPE correctly in bulk complete handlers.
93 * (replace usb_clear_halt() function with async urbs?)
94 * - I think this code relies too much on one spinlock and does
95 * too much in the interrupt handler. The net1080 code is
96 * much more elegant, and should work for this chip. Its
97 * only drawback is that it is going to be tough to backport
98 * it to v2.2.
99 * - Occasionally the device will hang under the 'uhci.o'
100 * driver. The workaround is to ifdown the device and
101 * remove the modules, then re-insert them. You may have
102 * better luck with the 'usb-uhci.o' driver.
103 * - After using ifconfig down ; ifconfig up, sometimes packets
104 * continue to be received, but there is a framing problem.
105 *
106 * FUTURE DIRECTIONS:
107 *
108 * - Fix the known problems.
109 * - There isn't much functional difference between the net1080
110 * driver and this one. It would be neat if the same driver
111 * could handle both types of chips. Or if both drivers
112 * could handle both types of chips - this one is easier to
113 * backport to the 2.2 kernel.
114 * - Get rid of plusb_add_buf_tail and the single spinlock.
115 * Use a separate spinlock for the 2 lists, and use atomic
116 * operators for writeurb_submitted and readurb_submitted members.
117 *
118 *
119 */
120
121 /*****************************************************************************/
122
123 #include <linux/module.h>
124 #include <linux/socket.h>
125 #include <linux/miscdevice.h>
126 #include <linux/list.h>
127 #include <linux/vmalloc.h>
128 #include <linux/slab.h>
129 #include <linux/init.h>
130 #include <asm/uaccess.h>
131 #include <asm/atomic.h>
132 #include <linux/delay.h>
133 #include <linux/netdevice.h>
134 #include <linux/etherdevice.h>
135 #include <linux/skbuff.h>
136 //#define DEBUG 1
137 #include <linux/usb.h>
138
139 #if (LINUX_VERSION_CODE < 0x020300)
140 #define dev_kfree_skb_any dev_kfree_skb
141 #endif
142
143 /* Definitions formerly in plusb.h relocated. No need to export them -EZA */
144
145 #define _PLUSB_INTPIPE 0x1
146 #define _PLUSB_BULKOUTPIPE 0x2
147 #define _PLUSB_BULKINPIPE 0x3
148
149 #define _SKB_NUM 32
150
151 /* increase size of BULK_DATA_LEN so we can use bigger MTU's*/
152 #define _BULK_DATA_LEN 32768
153
154
155 typedef struct
156 {
157 int connected; /* indicates if this structure is active */
158 struct usb_device *usbdev;
159 /* keep track of USB structure */
160 int status; /* Prolific status byte returned from interrupt */
161 int in_bh; /* flag to indicate that we are in the bulk handler */
162 int opened; /* flag to indicate that network dev is open */
163
164 spinlock_t lock; /* Lock for the buffer list. re-used for
165 locking around submitting the readurb member.
166 */
167 urb_t *inturb; /* Read buffer for the interrupt callback */
168 unsigned char * interrupt_in_buffer;
169 /* holds data for the inturb*/
170 urb_t *readurb; /* Read buffer for the bulk data callback */
171 unsigned char * bulk_in_buffer;
172 /* kmalloc'ed data for the readurb */
173 int readurb_submitted;
174 /* Flag to indicate that readurb already sent */
175 urb_t *writeurb; /* Write buffer for the bulk data callback */
176 int writeurb_submitted;
177 /* Flag to indicate that writeurb already sent */
178
179 struct list_head tx_skb_list;
180 /* sk_buff's read from net device */
181 struct list_head free_skb_list;
182 /* free sk_buff list */
183 struct net_device net_dev;
184 /* handle to linux network device */
185 struct net_device_stats net_stats;
186 /* stats to return for ifconfig output */
187 } plusb_t,*pplusb_t;
188
189 /*
190 * skb_list - queue of packets from the network driver to be delivered to USB
191 */
192 typedef struct
193 {
194 struct list_head skb_list;
195 struct sk_buff *skb;
196 int state;
197 plusb_t *s;
198 } skb_list_t,*pskb_list_t;
199
200
201 /* --------------------------------------------------------------------- */
202
203 #define NRPLUSB 4
204
205 /*
206 * Interrupt endpoint status byte, from Prolific PL-2301 docs
207 * Check the 'download' link at www.prolifictech.com
208 */
209 #define _PL_INT_RES1 0x80 /* reserved */
210 #define _PL_INT_RES2 0x40 /* reserved */
211 #define _PL_INT_RXD _PL_INT_RES2 /* Read data ready - Not documented by Prolific, but seems to work! */
212 #define _PL_INT_TX_RDY 0x20 /* OK to transmit data */
213 #define _PL_INT_RESET_O 0x10 /* reset output pipe */
214 #define _PL_INT_RESET_I 0x08 /* reset input pipe */
215 #define _PL_INT_TX_C 0x04 /* transmission complete */
216 #define _PL_INT_TX_REQ 0x02 /* transmission received */
217 #define _PL_INT_PEER_E 0x01 /* peer exists */
218
219 /*-------------------------------------------------------------------*/
220
221 static plusb_t plusb[NRPLUSB];
222
223 static void plusb_write_bulk_complete(urb_t *purb);
224 static void plusb_read_bulk_complete(urb_t *purb);
225 static void plusb_int_complete(urb_t *purb);
226
227 /* --------------------------------------------------------------------- */
228
229 /*
230 * plusb_add_buf_tail - Take the head of the src list and append it to
231 * the tail of the dest list
232 */
233 static int plusb_add_buf_tail (plusb_t *s, struct list_head *dst, struct list_head *src)
234 {
235 unsigned long flags = 0;
236 struct list_head *tmp;
237 int ret = 0;
238
239 spin_lock_irqsave (&s->lock, flags);
240
241 if (list_empty (src)) {
242 // no elements in source buffer
243 ret = -1;
244 goto err;
245 }
246 tmp = src->next;
247 list_del (tmp);
248 list_add_tail (tmp, dst);
249
250 err: spin_unlock_irqrestore (&s->lock, flags);
251 return ret;
252 }
253 /*-------------------------------------------------------------------*/
254
255 /*
256 * dequeue_next_skb - submit the first thing on the tx_skb_list to the
257 * USB stack. This function should be called each time we get a new
258 * message to send to the other host, or each time a message is sucessfully
259 * sent.
260 */
261 static void dequeue_next_skb(char * func, plusb_t * s)
262 {
263 skb_list_t * skb_list;
264 unsigned long flags = 0;
265
266 if (!s->connected)
267 return;
268
269 spin_lock_irqsave (&s->lock, flags);
270
271 if (!list_empty (&s->tx_skb_list) && !s->writeurb_submitted) {
272 int submit_ret;
273 skb_list = list_entry (s->tx_skb_list.next, skb_list_t, skb_list);
274
275 if (skb_list->skb) {
276 s->writeurb_submitted = 1;
277
278 /* Use the buffer inside the sk_buff directly. why copy? */
279 FILL_BULK_URB_TO(s->writeurb, s->usbdev,
280 usb_sndbulkpipe(s->usbdev, _PLUSB_BULKOUTPIPE),
281 skb_list->skb->data, skb_list->skb->len,
282 plusb_write_bulk_complete, skb_list, 500);
283
284 dbg ("%s: %s: submitting urb. skb_list %p", s->net_dev.name, func, skb_list);
285
286 submit_ret = usb_submit_urb(s->writeurb);
287 if (submit_ret) {
288 s->writeurb_submitted = 0;
289 printk (KERN_CRIT "%s: %s: can't submit writeurb: %d\n",
290 s->net_dev.name, func, submit_ret);
291 }
292 } /* end if the skb value has been filled in */
293 }
294
295 spin_unlock_irqrestore (&s->lock, flags);
296 }
297
298 /*
299 * submit_read_urb - re-submit the read URB to the stack
300 */
301 void submit_read_urb(char * func, plusb_t * s)
302 {
303 unsigned long flags=0;
304
305 if (!s->connected)
306 return;
307
308 spin_lock_irqsave (&s->lock, flags);
309
310 if (!s->readurb_submitted) {
311 int ret;
312 s->readurb_submitted=1;
313 s->readurb->dev=s->usbdev;
314 ret = usb_submit_urb(s->readurb);
315 if (ret) {
316 printk (KERN_CRIT "%s: %s: error %d submitting read URB\n",
317 s->net_dev.name, func, ret);
318 s->readurb_submitted=0;
319 }
320 }
321
322 spin_unlock_irqrestore (&s->lock, flags);
323
324 }
325 /* --------------------------------------------------------------------- */
326
327 /*
328 * plusb_net_xmit - callback from the network device driver for outgoing data
329 *
330 * Data has arrived to the network device from the local machine and needs
331 * to be sent over the USB cable. This is in an interrupt, so we don't
332 * want to spend too much time in this function.
333 *
334 */
335 static int plusb_net_xmit(struct sk_buff *skb, struct net_device *dev)
336 {
337 plusb_t *s=dev->priv;
338 skb_list_t *skb_list;
339 unsigned int flags;
340
341 dbg("plusb_net_xmit: len:%d i:%d",skb->len,in_interrupt());
342
343 if(!s->connected || !s->opened) {
344 /*
345 NOTE: If we get to this point, you'll return the error
346 kernel: virtual device plusb0 asks to queue packet
347
348 Other things we could do:
349 1) just drop this packet
350 2) drop other packets in the queue
351 */
352 return 1;
353 }
354
355 spin_lock_irqsave (&s->lock, flags);
356
357 if (list_empty(&s->free_skb_list)
358 || plusb_add_buf_tail (s, &s->tx_skb_list, &s->free_skb_list)) {
359 /* The buffers on this side are full. DROP the packet
360 I think that this shouldn't happen with the correct
361 use of the netif_XXX functions -EZA
362 */
363 dbg ("plusb: Free list is empty.");
364 kfree_skb(skb);
365 s->net_stats.tx_dropped++;
366 spin_unlock_irqrestore (&s->lock, flags);
367 return 0;
368 }
369
370 skb_list = list_entry (s->tx_skb_list.prev, skb_list_t, skb_list);
371 skb_list->skb=skb;
372 skb_list->state=1;
373 skb_list->s=s;
374
375 if (list_empty(&s->free_skb_list)) {
376 /* apply "backpressure". Tell the net layer to stop sending
377 the driver packets.
378 */
379 netif_stop_queue(dev);
380 }
381
382 spin_unlock_irqrestore (&s->lock, flags);
383
384 /* If there is no write urb outstanding, pull the first thing
385 off of the list and submit it to the USB stack
386 */
387 dequeue_next_skb("plusb_net_xmit", s);
388
389 return 0;
390 }
391
392 /* --------------------------------------------------------------------- */
393
394 /*
395 * plusb_write_bulk_complete () - callback after the data has been
396 * sent to the USB device, or a timeout occured.
397 */
398 static void plusb_write_bulk_complete(urb_t *purb)
399 {
400 skb_list_t * skb_list=purb->context;
401 plusb_t *s=skb_list->s;
402
403 dbg ("%s: plusb_write_bulk_complete: status:%d skb_list:%p\n",
404 s->net_dev.name, purb->status, skb_list);
405
406 skb_list->state=0;
407
408 if( purb->status == -EPIPE )
409 printk(KERN_CRIT "%s: plusb_write_bulk_complete: got -EPIPE and don't know what to do!\n",
410 s->net_dev.name);
411
412 if(!purb->status) {
413 s->net_stats.tx_packets++;
414 s->net_stats.tx_bytes+=skb_list->skb->len;
415 }
416 else {
417 err ("%s: plusb_write_bulk_complete: returned ERROR status:%d\n",
418 s->net_dev.name, purb->status);
419
420 s->net_stats.tx_errors++;
421 s->net_stats.tx_aborted_errors++;
422 }
423
424 dbg("plusb_bh: dev_kfree_skb");
425
426 /* NOTE: In 2.4 it's a problem to call dev_kfree_skb() in a hard IRQ:
427 Oct 28 23:42:14 bug kernel: Warning: kfree_skb on hard IRQ c023329a
428 */
429 dev_kfree_skb_any(skb_list->skb);
430
431 skb_list->skb = NULL;
432 if (plusb_add_buf_tail (s, &s->free_skb_list, &s->tx_skb_list)) {
433 err ("plusb: tx list empty. This shouldn't happen.");
434 }
435
436 purb->status = 0;
437 s->writeurb_submitted = 0;
438
439 netif_wake_queue((&s->net_dev));
440
441 dequeue_next_skb("plusb_write_bulk_complete", s);
442
443
444 }
445
446 /*
447 * plusb_read_bulk_complete - Callback for data arriving from the USB device
448 *
449 * This gets called back when a full 'urb' is received from the remote system.
450 * This urb was allocated by this driver and is kept in the member: s->readurb
451 *
452 */
453 static void plusb_read_bulk_complete(urb_t *purb)
454 {
455
456 plusb_t *s=purb->context;
457
458 dbg("plusb_read_bulk_complete: status:%d length:%d", purb->status,purb->actual_length);
459
460 if(!s->connected)
461 return;
462
463 if( purb->status == -EPIPE )
464 printk(KERN_CRIT "%s: plusb_read_bulk_complete: got -EPIPE and I don't know what to do!\n",
465 s->net_dev.name);
466 else if (!purb->status) {
467 struct sk_buff *skb;
468 unsigned char *dst;
469 int len=purb->transfer_buffer_length;
470 struct net_device_stats *stats=&s->net_stats;
471
472 skb=dev_alloc_skb(len);
473
474 if(!skb) {
475 printk (KERN_CRIT "%s: plusb_read_bulk_complete: dev_alloc_skb(%d)=NULL, dropping frame\n", s->net_dev.name, len);
476 stats->rx_dropped++;
477 } else {
478 dst=(char *)skb_put(skb, len);
479 memcpy( dst, purb->transfer_buffer, len);
480
481 skb->dev=&s->net_dev;
482 skb->protocol=eth_type_trans(skb, skb->dev);
483 stats->rx_packets++;
484 stats->rx_bytes+=len;
485 netif_rx(skb);
486 }
487
488 }
489
490 s->readurb_submitted = 0;
491
492 if (purb->status) {
493 /* Give the system a chance to "catch its breath". Shortcut
494 re-submitting the read URB> It will be re-submitted if
495 another interrupt comes back. The problem scenario is that
496 the plub is pulled and the read returns an error.
497 You don't want to resumbit in this case.
498 */
499 err ("%s: plusb_read_bulk_complete: returned status %d\n",
500 s->net_dev.name, purb->status);
501 return;
502 }
503
504
505 purb->status=0;
506
507 /* Keep it coming! resubmit the URB for reading.. Make sure
508 we aren't in contention with the interrupt callback.
509 */
510 submit_read_urb("plusb_read_bulk_complete", s);
511 }
512
513 /* --------------------------------------------------------------------- */
514 /*
515 * plusb_int_complete - USB driver callback for interrupt msg from the device
516 *
517 * Interrupts are scheduled to go off on a periodic basis (see FILL_INT_URB)
518 * For the prolific device, this is basically just returning a register
519 * filled with bits. See the macro definitions for _PL_INT_XXX above.
520 * Most of these bits are for implementing a machine-machine protocol
521 * and can be set with a special message (described as the "Quicklink"
522 * feature in the prolific documentation.)
523 *
524 * I don't think we need any of that to work as a network device. If a
525 * message is lost, big deal - that's what UNIX networking expects from
526 * the physical layer.
527 *
528 */
529 static void plusb_int_complete(urb_t *purb)
530 {
531 plusb_t *s=purb->context;
532 s->status=((unsigned char*)purb->transfer_buffer)[0]&255;
533
534 #if 0
535 /* This isn't right because 0x20 is TX_RDY and
536 sometimes will not be set
537 */
538 if((s->status&0x3f)!=0x20) {
539 warn("invalid device status %02X", s->status);
540 return;
541 }
542 #endif
543 if(!s->connected)
544 return;
545
546 /* Don't turn this on unless you want to see the log flooded. */
547 #if 0
548 printk("plusb_int_complete: PEER_E:%d TX_REQ:%d TX_C:%d RESET_IN:%d RESET_O: %d TX_RDY:%d RES1:%d RES2:%d\n",
549 s->status & _PL_INT_PEER_E ? 1 : 0,
550 s->status & _PL_INT_TX_REQ ? 1 : 0,
551 s->status & _PL_INT_TX_C ? 1 : 0,
552 s->status & _PL_INT_RESET_I ? 1 : 0,
553 s->status & _PL_INT_RESET_O ? 1 : 0,
554 s->status & _PL_INT_TX_RDY ? 1 : 0,
555 s->status & _PL_INT_RES1 ? 1 : 0,
556 s->status & _PL_INT_RES2 ? 1 : 0);
557 #endif
558
559 #if 1
560 /* At first glance, this logic appears to not really be needed, but
561 it can help recover from intermittent problems where the
562 usb_submit_urb() fails in the read callback. -EZA
563 */
564
565 /* Try to submit the read URB again. Make sure
566 we aren't in contention with the bulk read callback
567 */
568 submit_read_urb ("plusb_int_complete", s);
569
570 /* While we are at it, why not check to see if the
571 write urb should be re-submitted?
572 */
573 dequeue_next_skb("plusb_int_complete", s);
574
575 #endif
576
577 }
578
579 /* --------------------------------------------------------------------- */
580 /*
581 * plusb_free_all - deallocate all memory kept for an instance of the device.
582 */
583 static void plusb_free_all(plusb_t *s)
584 {
585 struct list_head *skb;
586 skb_list_t *skb_list;
587
588 dbg("plusb_free_all");
589
590 /* set a flag to tell all callbacks to cease and desist */
591 s->connected = 0;
592
593 /* If the interrupt handler is about to fire, let it finish up */
594 run_task_queue(&tq_immediate);
595
596 if(s->inturb) {
597 dbg("unlink inturb");
598 usb_unlink_urb(s->inturb);
599 dbg("free_urb inturb");
600 usb_free_urb(s->inturb);
601 s->inturb=NULL;
602 }
603
604 if(s->interrupt_in_buffer) {
605 dbg("kfree s->interrupt_in_buffer");
606 kfree(s->interrupt_in_buffer);
607 s->interrupt_in_buffer=NULL;
608 }
609
610 if(s->readurb) {
611 dbg("unlink readurb");
612 usb_unlink_urb(s->readurb);
613 dbg("free_urb readurb:");
614 usb_free_urb(s->readurb);
615 s->readurb=NULL;
616 }
617
618 if(s->bulk_in_buffer) {
619 dbg("kfree s->bulk_in_buffer");
620 kfree(s->bulk_in_buffer);
621 s->bulk_in_buffer=NULL;
622 }
623
624 s->readurb_submitted = 0;
625
626 if(s->writeurb) {
627 dbg("unlink writeurb");
628 usb_unlink_urb(s->writeurb);
629 dbg("free_urb writeurb:");
630 usb_free_urb(s->writeurb);
631 s->writeurb=NULL;
632 }
633
634 s->writeurb_submitted = 0;
635
636 while(!list_empty(&s->free_skb_list)) {
637 skb=s->free_skb_list.next;
638 list_del(skb);
639 skb_list = list_entry (skb, skb_list_t, skb_list);
640 kfree(skb_list);
641 }
642
643 while(!list_empty(&s->tx_skb_list)) {
644 skb=s->tx_skb_list.next;
645 list_del(skb);
646 skb_list = list_entry (skb, skb_list_t, skb_list);
647 if (skb_list->skb) {
648 dbg ("Freeing SKB in queue");
649 dev_kfree_skb_any(skb_list->skb);
650 skb_list->skb = NULL;
651 }
652 kfree(skb_list);
653 }
654
655 s->in_bh=0;
656
657 dbg("plusb_free_all: finished");
658 }
659
660 /*-------------------------------------------------------------------*/
661 /*
662 * plusb_alloc - allocate memory associated with one instance of the device
663 */
664 static int plusb_alloc(plusb_t *s)
665 {
666 int i;
667 skb_list_t *skb;
668
669 dbg("plusb_alloc");
670
671 for(i=0 ; i < _SKB_NUM ; i++) {
672 skb=kmalloc(sizeof(skb_list_t), GFP_KERNEL);
673 if(!skb) {
674 err("kmalloc for skb_list failed");
675 goto reject;
676 }
677 memset(skb, 0, sizeof(skb_list_t));
678 list_add(&skb->skb_list, &s->free_skb_list);
679 }
680
681 dbg("inturb allocation:");
682 s->inturb=usb_alloc_urb(0);
683 if(!s->inturb) {
684 err("alloc_urb failed");
685 goto reject;
686 }
687
688 dbg("bulk read urb allocation:");
689 s->readurb=usb_alloc_urb(0);
690 if(!s->readurb) {
691 err("alloc_urb failed");
692 goto reject;
693 }
694
695 dbg("bulk write urb allocation:");
696 s->writeurb=usb_alloc_urb(0);
697 if(!s->writeurb) {
698 err("alloc_urb for writeurb failed");
699 goto reject;
700 }
701
702 dbg("readurb/inturb init:");
703 s->interrupt_in_buffer=kmalloc(64, GFP_KERNEL);
704 if(!s->interrupt_in_buffer) {
705 err("kmalloc failed");
706 goto reject;
707 }
708
709 /* The original value of '10' makes this interrupt fire off a LOT.
710 It was set so low because the callback determined when to
711 sumbit the buld read URB. I've lowered it to 100 - the driver
712 doesn't depend on that logic anymore. -EZA
713 */
714 FILL_INT_URB(s->inturb, s->usbdev,
715 usb_rcvintpipe (s->usbdev, _PLUSB_INTPIPE),
716 s->interrupt_in_buffer, 1,
717 plusb_int_complete, s, HZ);
718
719 dbg("inturb submission:");
720 if(usb_submit_urb(s->inturb)<0) {
721 err("usb_submit_urb failed");
722 goto reject;
723 }
724
725 dbg("readurb init:");
726 s->bulk_in_buffer = kmalloc(_BULK_DATA_LEN, GFP_KERNEL);
727 if (!s->bulk_in_buffer) {
728 err("kmalloc %d bytes for bulk in buffer failed", _BULK_DATA_LEN);
729 }
730
731 FILL_BULK_URB(s->readurb, s->usbdev,
732 usb_rcvbulkpipe(s->usbdev, _PLUSB_BULKINPIPE),
733 s->bulk_in_buffer, _BULK_DATA_LEN,
734 plusb_read_bulk_complete, s);
735
736 /* The write urb will be initialized inside the network
737 interrupt.
738 */
739
740 /* get the bulk read going */
741 submit_read_urb("plusb_alloc", s);
742
743 dbg ("plusb_alloc: finished. readurb=%p writeurb=%p inturb=%p",
744 s->readurb, s->writeurb, s->inturb);
745
746 return 0;
747
748 reject:
749 dbg("plusb_alloc: failed");
750
751 plusb_free_all(s);
752 return -ENOMEM;
753 }
754
755 /*-------------------------------------------------------------------*/
756
757 static int plusb_net_open(struct net_device *dev)
758 {
759 plusb_t *s=dev->priv;
760
761 dbg("plusb_net_open");
762
763 if(plusb_alloc(s))
764 return -ENOMEM;
765
766 s->opened=1;
767
768 MOD_INC_USE_COUNT;
769
770 netif_start_queue(dev);
771
772 dbg("plusb_net_open: success");
773
774 return 0;
775
776 }
777
778 /* --------------------------------------------------------------------- */
779
780 static int plusb_net_stop(struct net_device *dev)
781 {
782 plusb_t *s=dev->priv;
783
784 netif_stop_queue(dev);
785
786 dbg("plusb_net_stop");
787
788 s->opened=0;
789 plusb_free_all(s);
790
791 MOD_DEC_USE_COUNT;
792 dbg("plusb_net_stop:finished");
793 return 0;
794 }
795
796 /* --------------------------------------------------------------------- */
797
798 static struct net_device_stats *plusb_net_get_stats(struct net_device *dev)
799 {
800 plusb_t *s=dev->priv;
801
802 dbg("net_device_stats");
803
804 return &s->net_stats;
805 }
806
807 /* --------------------------------------------------------------------- */
808
809 static plusb_t *plusb_find_struct (void)
810 {
811 int u;
812
813 for (u = 0; u < NRPLUSB; u++) {
814 plusb_t *s = &plusb[u];
815 if (!s->connected)
816 return s;
817 }
818 return NULL;
819 }
820
821 /* --------------------------------------------------------------------- */
822
823 static void plusb_disconnect (struct usb_device *usbdev, void *ptr)
824 {
825 plusb_t *s = ptr;
826
827 dbg("plusb_disconnect");
828
829 plusb_free_all(s);
830
831 if(!s->opened && s->net_dev.name) {
832 dbg("unregistering netdev: %s",s->net_dev.name);
833 unregister_netdev(&s->net_dev);
834 s->net_dev.name[0] = '\0';
835 #if (LINUX_VERSION_CODE < 0x020300)
836 dbg("plusb_disconnect: About to free name");
837 kfree (s->net_dev.name);
838 s->net_dev.name = NULL;
839 #endif
840 }
841
842 dbg("plusb_disconnect: finished");
843 MOD_DEC_USE_COUNT;
844 }
845
846 /* --------------------------------------------------------------------- */
847
848 static int plusb_change_mtu(struct net_device *dev, int new_mtu)
849 {
850 if ((new_mtu < 68) || (new_mtu > _BULK_DATA_LEN))
851 return -EINVAL;
852
853 printk("plusb: changing mtu to %d\n", new_mtu);
854 dev->mtu = new_mtu;
855
856 /* NOTE: Could we change the size of the READ URB here dynamically
857 to save kernel memory?
858 */
859 return 0;
860 }
861
862 /* --------------------------------------------------------------------- */
863
864 int plusb_net_init(struct net_device *dev)
865 {
866 dbg("plusb_net_init");
867
868 dev->open=plusb_net_open;
869 dev->stop=plusb_net_stop;
870 dev->hard_start_xmit=plusb_net_xmit;
871 dev->get_stats = plusb_net_get_stats;
872 ether_setup(dev);
873 dev->change_mtu = plusb_change_mtu;
874 /* Setting the default MTU to 16K gives good performance for
875 me, and keeps the ping latency low too. Setting it up
876 to 32K made performance go down. -EZA
877 Pavel says it would be best not to do this...
878 */
879 /*dev->mtu=16384; */
880 dev->tx_queue_len = 0;
881 dev->flags = IFF_POINTOPOINT|IFF_NOARP;
882
883
884 dbg("plusb_net_init: finished");
885 return 0;
886 }
887
888 /* --------------------------------------------------------------------- */
889
890 static void *plusb_probe (struct usb_device *usbdev, unsigned int ifnum)
891 {
892 plusb_t *s;
893
894 dbg("plusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
895 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
896
897 if (usbdev->descriptor.idVendor != 0x067b || usbdev->descriptor.idProduct > 0x1)
898 return NULL;
899
900 /* We don't handle multiple configurations */
901 if (usbdev->descriptor.bNumConfigurations != 1)
902 return NULL;
903
904 s = plusb_find_struct ();
905 if (!s)
906 return NULL;
907
908 s->usbdev = usbdev;
909
910 if (usb_set_configuration (s->usbdev, usbdev->config[0].bConfigurationValue) < 0) {
911 err("set_configuration failed");
912 return NULL;
913 }
914
915 if (usb_set_interface (s->usbdev, 0, 0) < 0) {
916 err("set_interface failed");
917 return NULL;
918 }
919
920 #if (LINUX_VERSION_CODE < 0x020300)
921 {
922 int i;
923
924 /* For Kernel version 2.2, the driver is responsible for
925 allocating this memory. For version 2.4, the rules
926 have apparently changed, but there is a nifty function
927 'init_netdev' that might make this easier... It's in
928 ../net/net_init.c - but can we get there from here? (no)
929 -EZA
930 */
931
932 /* Find the device number... we seem to have lost it... -EZA */
933 for (i=0; i<NRPLUSB; i++) {
934 if (&plusb[i] == s)
935 break;
936 }
937
938 if(!s->net_dev.name) {
939 s->net_dev.name = kmalloc(strlen("plusbXXXX"), GFP_KERNEL);
940 sprintf (s->net_dev.name, "plusb%d", i);
941 s->net_dev.init=plusb_net_init;
942 s->net_dev.priv=s;
943
944 printk ("plusb_probe: Registering Device\n");
945 if(!register_netdev(&s->net_dev))
946 info("registered: %s", s->net_dev.name);
947 else {
948 err("register_netdev failed");
949 s->net_dev.name[0] = '\0';
950 }
951 dbg ("plusb_probe: Connected!");
952 }
953 }
954 #else
955 /* Kernel version 2.3+ works a little bit differently than 2.2 */
956 if(!s->net_dev.name[0]) {
957 strcpy(s->net_dev.name, "plusb%d");
958 s->net_dev.init=plusb_net_init;
959 s->net_dev.priv=s;
960 if(!register_netdev(&s->net_dev))
961 info("registered: %s", s->net_dev.name);
962 else {
963 err("register_netdev failed");
964 s->net_dev.name[0] = '\0';
965 }
966 }
967 #endif
968
969 s->connected = 1;
970
971 if(s->opened) {
972 dbg("net device already allocated, restarting USB transfers");
973 plusb_alloc(s);
974 }
975
976 info("bound to interface: %d dev: %p", ifnum, usbdev);
977 MOD_INC_USE_COUNT;
978 return s;
979 }
980 /* --------------------------------------------------------------------- */
981
982 static struct usb_driver plusb_driver =
983 {
984 name: "plusb",
985 probe: plusb_probe,
986 disconnect: plusb_disconnect,
987 };
988
989 /* --------------------------------------------------------------------- */
990
991 static int __init plusb_init (void)
992 {
993 unsigned u;
994 dbg("plusb_init");
995
996 /* initialize struct */
997 for (u = 0; u < NRPLUSB; u++) {
998 plusb_t *s = &plusb[u];
999 memset (s, 0, sizeof (plusb_t));
1000 INIT_LIST_HEAD (&s->tx_skb_list);
1001 INIT_LIST_HEAD (&s->free_skb_list);
1002 spin_lock_init (&s->lock);
1003 }
1004
1005 /* register misc device */
1006 usb_register (&plusb_driver);
1007
1008 dbg("plusb_init: driver registered");
1009
1010 return 0;
1011 }
1012
1013 /* --------------------------------------------------------------------- */
1014
1015 static void __exit plusb_cleanup (void)
1016 {
1017 unsigned u;
1018
1019 dbg("plusb_cleanup");
1020 for (u = 0; u < NRPLUSB; u++) {
1021 plusb_t *s = &plusb[u];
1022 #if (LINUX_VERSION_CODE < 0x020300)
1023 if(s->net_dev.name) {
1024 dbg("unregistering netdev: %s",s->net_dev.name);
1025 unregister_netdev(&s->net_dev);
1026 s->net_dev.name[0] = '\0';
1027 kfree (s->net_dev.name);
1028 s->net_dev.name = NULL;
1029 }
1030 #else
1031 if(s->net_dev.name[0]) {
1032 dbg("unregistering netdev: %s",s->net_dev.name);
1033 unregister_netdev(&s->net_dev);
1034 s->net_dev.name[0] = '\0';
1035 }
1036 #endif
1037 }
1038 usb_deregister (&plusb_driver);
1039 dbg("plusb_cleanup: finished");
1040 }
1041
1042 /* --------------------------------------------------------------------- */
1043
1044 MODULE_AUTHOR ("Deti Fliegl, deti@fliegl.de");
1045 MODULE_DESCRIPTION ("PL-2302 USB Interface Driver for Linux (c)2000");
1046
1047
1048 module_init (plusb_init);
1049 module_exit (plusb_cleanup);
1050
1051 /* --------------------------------------------------------------------- */
1052
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.