1 /*****************************************************************************/
4 * plusb.c -- prolific pl-2301/pl-2302 driver.
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)
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.
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.
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.
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.
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)
33 * $Id: plusb.c,v 1.18 2000/02/14 10:38:58 fliegl Exp $
38 * Original Version of driver.
39 * v0.2 15 Sep 2000 pavel
40 * Patches to decrease latency by rescheduling the bottom half of
42 * v0.3 10 Oct 2000 eric
43 * Patches to work in v2.2 backport (v2.4 changes the way net_dev.name
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
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)
76 * Fix to not re-submit the urb on error to help when cables
77 * are yanked (not tested)
80 * KNOWN PROBLEMS: (Any suggestions greatfully accepted!)
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
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
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.
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.
121 /*****************************************************************************/
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>
137 #include <linux/usb.h>
139 #if (LINUX_VERSION_CODE < 0x020300)
140 #define dev_kfree_skb_any dev_kfree_skb
143 /* Definitions formerly in plusb.h relocated. No need to export them -EZA */
145 #define _PLUSB_INTPIPE 0x1
146 #define _PLUSB_BULKOUTPIPE 0x2
147 #define _PLUSB_BULKINPIPE 0x3
151 /* increase size of BULK_DATA_LEN so we can use bigger MTU's*/
152 #define _BULK_DATA_LEN 32768
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 */
164 spinlock_t lock; /* Lock for the buffer list. re-used for
165 locking around submitting the readurb member.
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 */
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 */
190 * skb_list - queue of packets from the network driver to be delivered to USB
194 struct list_head skb_list;
198 } skb_list_t,*pskb_list_t;
201 /* --------------------------------------------------------------------- */
206 * Interrupt endpoint status byte, from Prolific PL-2301 docs
207 * Check the 'download' link at www.prolifictech.com
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 */
219 /*-------------------------------------------------------------------*/
221 static plusb_t plusb[NRPLUSB];
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);
227 /* --------------------------------------------------------------------- */
230 * plusb_add_buf_tail - Take the head of the src list and append it to
231 * the tail of the dest list
233 static int plusb_add_buf_tail (plusb_t *s, struct list_head *dst, struct list_head *src)
235 unsigned long flags = 0;
236 struct list_head *tmp;
239 spin_lock_irqsave (&s->lock, flags);
241 if (list_empty (src)) {
242 // no elements in source buffer
248 list_add_tail (tmp, dst);
250 err: spin_unlock_irqrestore (&s->lock, flags);
253 /*-------------------------------------------------------------------*/
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
261 static void dequeue_next_skb(char * func, plusb_t * s)
263 skb_list_t * skb_list;
264 unsigned long flags = 0;
269 spin_lock_irqsave (&s->lock, flags);
271 if (!list_empty (&s->tx_skb_list) && !s->writeurb_submitted) {
273 skb_list = list_entry (s->tx_skb_list.next, skb_list_t, skb_list);
276 s->writeurb_submitted = 1;
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);
284 dbg ("%s: %s: submitting urb. skb_list %p", s->net_dev.name, func, skb_list);
286 submit_ret = usb_submit_urb(s->writeurb);
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);
292 } /* end if the skb value has been filled in */
295 spin_unlock_irqrestore (&s->lock, flags);
299 * submit_read_urb - re-submit the read URB to the stack
301 void submit_read_urb(char * func, plusb_t * s)
303 unsigned long flags=0;
308 spin_lock_irqsave (&s->lock, flags);
310 if (!s->readurb_submitted) {
312 s->readurb_submitted=1;
313 s->readurb->dev=s->usbdev;
314 ret = usb_submit_urb(s->readurb);
316 printk (KERN_CRIT "%s: %s: error %d submitting read URB\n",
317 s->net_dev.name, func, ret);
318 s->readurb_submitted=0;
322 spin_unlock_irqrestore (&s->lock, flags);
325 /* --------------------------------------------------------------------- */
328 * plusb_net_xmit - callback from the network device driver for outgoing data
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.
335 static int plusb_net_xmit(struct sk_buff *skb, struct net_device *dev)
337 plusb_t *s=dev->priv;
338 skb_list_t *skb_list;
341 dbg("plusb_net_xmit: len:%d i:%d",skb->len,in_interrupt());
343 if(!s->connected || !s->opened) {
345 NOTE: If we get to this point, you'll return the error
346 kernel: virtual device plusb0 asks to queue packet
348 Other things we could do:
349 1) just drop this packet
350 2) drop other packets in the queue
355 spin_lock_irqsave (&s->lock, flags);
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
363 dbg ("plusb: Free list is empty.");
365 s->net_stats.tx_dropped++;
366 spin_unlock_irqrestore (&s->lock, flags);
370 skb_list = list_entry (s->tx_skb_list.prev, skb_list_t, skb_list);
375 if (list_empty(&s->free_skb_list)) {
376 /* apply "backpressure". Tell the net layer to stop sending
379 netif_stop_queue(dev);
382 spin_unlock_irqrestore (&s->lock, flags);
384 /* If there is no write urb outstanding, pull the first thing
385 off of the list and submit it to the USB stack
387 dequeue_next_skb("plusb_net_xmit", s);
392 /* --------------------------------------------------------------------- */
395 * plusb_write_bulk_complete () - callback after the data has been
396 * sent to the USB device, or a timeout occured.
398 static void plusb_write_bulk_complete(urb_t *purb)
400 skb_list_t * skb_list=purb->context;
401 plusb_t *s=skb_list->s;
403 dbg ("%s: plusb_write_bulk_complete: status:%d skb_list:%p\n",
404 s->net_dev.name, purb->status, skb_list);
408 if( purb->status == -EPIPE )
409 printk(KERN_CRIT "%s: plusb_write_bulk_complete: got -EPIPE and don't know what to do!\n",
413 s->net_stats.tx_packets++;
414 s->net_stats.tx_bytes+=skb_list->skb->len;
417 err ("%s: plusb_write_bulk_complete: returned ERROR status:%d\n",
418 s->net_dev.name, purb->status);
420 s->net_stats.tx_errors++;
421 s->net_stats.tx_aborted_errors++;
424 dbg("plusb_bh: dev_kfree_skb");
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
429 dev_kfree_skb_any(skb_list->skb);
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.");
437 s->writeurb_submitted = 0;
439 netif_wake_queue((&s->net_dev));
441 dequeue_next_skb("plusb_write_bulk_complete", s);
447 * plusb_read_bulk_complete - Callback for data arriving from the USB device
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
453 static void plusb_read_bulk_complete(urb_t *purb)
456 plusb_t *s=purb->context;
458 dbg("plusb_read_bulk_complete: status:%d length:%d", purb->status,purb->actual_length);
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",
466 else if (!purb->status) {
469 int len=purb->transfer_buffer_length;
470 struct net_device_stats *stats=&s->net_stats;
472 skb=dev_alloc_skb(len);
475 printk (KERN_CRIT "%s: plusb_read_bulk_complete: dev_alloc_skb(%d)=NULL, dropping frame\n", s->net_dev.name, len);
478 dst=(char *)skb_put(skb, len);
479 memcpy( dst, purb->transfer_buffer, len);
481 skb->dev=&s->net_dev;
482 skb->protocol=eth_type_trans(skb, skb->dev);
484 stats->rx_bytes+=len;
490 s->readurb_submitted = 0;
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.
499 err ("%s: plusb_read_bulk_complete: returned status %d\n",
500 s->net_dev.name, purb->status);
507 /* Keep it coming! resubmit the URB for reading.. Make sure
508 we aren't in contention with the interrupt callback.
510 submit_read_urb("plusb_read_bulk_complete", s);
513 /* --------------------------------------------------------------------- */
515 * plusb_int_complete - USB driver callback for interrupt msg from the device
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.)
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.
529 static void plusb_int_complete(urb_t *purb)
531 plusb_t *s=purb->context;
532 s->status=((unsigned char*)purb->transfer_buffer)[0]&255;
535 /* This isn't right because 0x20 is TX_RDY and
536 sometimes will not be set
538 if((s->status&0x3f)!=0x20) {
539 warn("invalid device status %02X", s->status);
546 /* Don't turn this on unless you want to see the log flooded. */
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);
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
565 /* Try to submit the read URB again. Make sure
566 we aren't in contention with the bulk read callback
568 submit_read_urb ("plusb_int_complete", s);
570 /* While we are at it, why not check to see if the
571 write urb should be re-submitted?
573 dequeue_next_skb("plusb_int_complete", s);
579 /* --------------------------------------------------------------------- */
581 * plusb_free_all - deallocate all memory kept for an instance of the device.
583 static void plusb_free_all(plusb_t *s)
585 struct list_head *skb;
586 skb_list_t *skb_list;
588 dbg("plusb_free_all");
590 /* set a flag to tell all callbacks to cease and desist */
593 /* If the interrupt handler is about to fire, let it finish up */
594 run_task_queue(&tq_immediate);
597 dbg("unlink inturb");
598 usb_unlink_urb(s->inturb);
599 dbg("free_urb inturb");
600 usb_free_urb(s->inturb);
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;
611 dbg("unlink readurb");
612 usb_unlink_urb(s->readurb);
613 dbg("free_urb readurb:");
614 usb_free_urb(s->readurb);
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;
624 s->readurb_submitted = 0;
627 dbg("unlink writeurb");
628 usb_unlink_urb(s->writeurb);
629 dbg("free_urb writeurb:");
630 usb_free_urb(s->writeurb);
634 s->writeurb_submitted = 0;
636 while(!list_empty(&s->free_skb_list)) {
637 skb=s->free_skb_list.next;
639 skb_list = list_entry (skb, skb_list_t, skb_list);
643 while(!list_empty(&s->tx_skb_list)) {
644 skb=s->tx_skb_list.next;
646 skb_list = list_entry (skb, skb_list_t, skb_list);
648 dbg ("Freeing SKB in queue");
649 dev_kfree_skb_any(skb_list->skb);
650 skb_list->skb = NULL;
657 dbg("plusb_free_all: finished");
660 /*-------------------------------------------------------------------*/
662 * plusb_alloc - allocate memory associated with one instance of the device
664 static int plusb_alloc(plusb_t *s)
671 for(i=0 ; i < _SKB_NUM ; i++) {
672 skb=kmalloc(sizeof(skb_list_t), GFP_KERNEL);
674 err("kmalloc for skb_list failed");
677 memset(skb, 0, sizeof(skb_list_t));
678 list_add(&skb->skb_list, &s->free_skb_list);
681 dbg("inturb allocation:");
682 s->inturb=usb_alloc_urb(0);
684 err("alloc_urb failed");
688 dbg("bulk read urb allocation:");
689 s->readurb=usb_alloc_urb(0);
691 err("alloc_urb failed");
695 dbg("bulk write urb allocation:");
696 s->writeurb=usb_alloc_urb(0);
698 err("alloc_urb for writeurb failed");
702 dbg("readurb/inturb init:");
703 s->interrupt_in_buffer=kmalloc(64, GFP_KERNEL);
704 if(!s->interrupt_in_buffer) {
705 err("kmalloc failed");
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
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);
719 dbg("inturb submission:");
720 if(usb_submit_urb(s->inturb)<0) {
721 err("usb_submit_urb failed");
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);
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);
736 /* The write urb will be initialized inside the network
740 /* get the bulk read going */
741 submit_read_urb("plusb_alloc", s);
743 dbg ("plusb_alloc: finished. readurb=%p writeurb=%p inturb=%p",
744 s->readurb, s->writeurb, s->inturb);
749 dbg("plusb_alloc: failed");
755 /*-------------------------------------------------------------------*/
757 static int plusb_net_open(struct net_device *dev)
759 plusb_t *s=dev->priv;
761 dbg("plusb_net_open");
770 netif_start_queue(dev);
772 dbg("plusb_net_open: success");
778 /* --------------------------------------------------------------------- */
780 static int plusb_net_stop(struct net_device *dev)
782 plusb_t *s=dev->priv;
784 netif_stop_queue(dev);
786 dbg("plusb_net_stop");
792 dbg("plusb_net_stop:finished");
796 /* --------------------------------------------------------------------- */
798 static struct net_device_stats *plusb_net_get_stats(struct net_device *dev)
800 plusb_t *s=dev->priv;
802 dbg("net_device_stats");
804 return &s->net_stats;
807 /* --------------------------------------------------------------------- */
809 static plusb_t *plusb_find_struct (void)
813 for (u = 0; u < NRPLUSB; u++) {
814 plusb_t *s = &plusb[u];
821 /* --------------------------------------------------------------------- */
823 static void plusb_disconnect (struct usb_device *usbdev, void *ptr)
827 dbg("plusb_disconnect");
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;
842 dbg("plusb_disconnect: finished");
846 /* --------------------------------------------------------------------- */
848 static int plusb_change_mtu(struct net_device *dev, int new_mtu)
850 if ((new_mtu < 68) || (new_mtu > _BULK_DATA_LEN))
853 printk("plusb: changing mtu to %d\n", new_mtu);
856 /* NOTE: Could we change the size of the READ URB here dynamically
857 to save kernel memory?
862 /* --------------------------------------------------------------------- */
864 int plusb_net_init(struct net_device *dev)
866 dbg("plusb_net_init");
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;
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...
880 dev->tx_queue_len = 0;
881 dev->flags = IFF_POINTOPOINT|IFF_NOARP;
884 dbg("plusb_net_init: finished");
888 /* --------------------------------------------------------------------- */
890 static void *plusb_probe (struct usb_device *usbdev, unsigned int ifnum)
894 dbg("plusb: probe: vendor id 0x%x, device id 0x%x ifnum:%d",
895 usbdev->descriptor.idVendor, usbdev->descriptor.idProduct, ifnum);
897 if (usbdev->descriptor.idVendor != 0x067b || usbdev->descriptor.idProduct > 0x1)
900 /* We don't handle multiple configurations */
901 if (usbdev->descriptor.bNumConfigurations != 1)
904 s = plusb_find_struct ();
910 if (usb_set_configuration (s->usbdev, usbdev->config[0].bConfigurationValue) < 0) {
911 err("set_configuration failed");
915 if (usb_set_interface (s->usbdev, 0, 0) < 0) {
916 err("set_interface failed");
920 #if (LINUX_VERSION_CODE < 0x020300)
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)
932 /* Find the device number... we seem to have lost it... -EZA */
933 for (i=0; i<NRPLUSB; i++) {
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;
944 printk ("plusb_probe: Registering Device\n");
945 if(!register_netdev(&s->net_dev))
946 info("registered: %s", s->net_dev.name);
948 err("register_netdev failed");
949 s->net_dev.name[0] = '\0';
951 dbg ("plusb_probe: Connected!");
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;
960 if(!register_netdev(&s->net_dev))
961 info("registered: %s", s->net_dev.name);
963 err("register_netdev failed");
964 s->net_dev.name[0] = '\0';
972 dbg("net device already allocated, restarting USB transfers");
976 info("bound to interface: %d dev: %p", ifnum, usbdev);
980 /* --------------------------------------------------------------------- */
982 static struct usb_driver plusb_driver =
986 disconnect: plusb_disconnect,
989 /* --------------------------------------------------------------------- */
991 static int __init plusb_init (void)
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);
1005 /* register misc device */
1006 usb_register (&plusb_driver);
1008 dbg("plusb_init: driver registered");
1013 /* --------------------------------------------------------------------- */
1015 static void __exit plusb_cleanup (void)
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;
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';
1038 usb_deregister (&plusb_driver);
1039 dbg("plusb_cleanup: finished");
1042 /* --------------------------------------------------------------------- */
1044 MODULE_AUTHOR ("Deti Fliegl, deti@fliegl.de");
1045 MODULE_DESCRIPTION ("PL-2302 USB Interface Driver for Linux (c)2000");
1048 module_init (plusb_init);
1049 module_exit (plusb_cleanup);
1051 /* --------------------------------------------------------------------- */