File: /usr/src/linux/drivers/net/irda/toshoboe.c
1 /*********************************************************************
2 *
3 * Filename: toshoboe.c
4 * Version: 0.1
5 * Description: Driver for the Toshiba OBOE (or type-O or 700 or 701)
6 * FIR Chipset.
7 * Status: Experimental.
8 * Author: James McKenzie <james@fishsoup.dhs.org>
9 * Created at: Sat May 8 12:35:27 1999
10 * Modified: Paul Bristow <paul.bristow@technologist.com>
11 * Modified: Mon Nov 11 19:10:05 1999
12 *
13 * Copyright (c) 1999-2000 James McKenzie, All Rights Reserved.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License as
17 * published by the Free Software Foundation; either version 2 of
18 * the License, or (at your option) any later version.
19 *
20 * Neither James McKenzie nor Cambridge University admit liability nor
21 * provide warranty for any of this software. This material is
22 * provided "AS-IS" and at no charge.
23 *
24 * Applicable Models : Libretto 100CT. and many more
25 * Toshiba refers to this chip as the type-O IR port.
26 *
27 ********************************************************************/
28
29 /* This driver is experimental, I have only three ir devices */
30 /* an olivetti notebook which doesn't have FIR, a toshiba libretto, and */
31 /* an hp printer, this works fine at 4MBPS with my HP printer */
32
33 static char *rcsid = "$Id: toshoboe.c,v 1.91 1999/06/29 14:21:06 root Exp $";
34
35 /* Define this to have only one frame in the XMIT or RECV queue */
36 /* Toshiba's drivers do this, but it disables back to back tansfers */
37 /* I think that the chip may have some problems certainly, I have */
38 /* seen it jump over tasks in the taskfile->xmit with this turned on */
39 #define ONETASK
40
41 /* To adjust the number of tasks in use edit toshoboe.h */
42
43 /* Define this to enable FIR and MIR support */
44 #define ENABLE_FAST
45
46 /* Size of IO window */
47 #define CHIP_IO_EXTENT 0x1f
48
49 /* Transmit and receive buffer sizes, adjust at your peril */
50 #define RX_BUF_SZ 4196
51 #define TX_BUF_SZ 4196
52
53 /* No user servicable parts below here */
54
55 #include <linux/module.h>
56 #include <linux/kernel.h>
57 #include <linux/types.h>
58 #include <linux/skbuff.h>
59 #include <linux/netdevice.h>
60 #include <linux/ioport.h>
61 #include <linux/delay.h>
62 #include <linux/slab.h>
63 #include <linux/init.h>
64 #include <linux/pci.h>
65 #include <linux/rtnetlink.h>
66
67 #include <asm/system.h>
68 #include <asm/io.h>
69
70 #include <net/irda/wrapper.h>
71 #include <net/irda/irda.h>
72 #include <net/irda/irmod.h>
73 #include <net/irda/irlap_frame.h>
74 #include <net/irda/irda_device.h>
75
76 #include <linux/pm.h>
77
78 #include <net/irda/toshoboe.h>
79
80 #define PCI_DEVICE_ID_FIR701b 0x0d01
81
82 static struct pci_device_id toshoboe_pci_tbl[] __initdata = {
83 { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701, PCI_ANY_ID, PCI_ANY_ID, },
84 { PCI_VENDOR_ID_TOSHIBA, PCI_DEVICE_ID_FIR701b, PCI_ANY_ID, PCI_ANY_ID, },
85 { } /* Terminating entry */
86 };
87 MODULE_DEVICE_TABLE(pci, toshoboe_pci_tbl);
88
89 static const char *driver_name = "toshoboe";
90
91 static int max_baud = 4000000;
92
93 /* Shutdown the chip and point the taskfile reg somewhere else */
94 static void
95 toshoboe_stopchip (struct toshoboe_cb *self)
96 {
97 IRDA_DEBUG (4, __FUNCTION__ "()\n");
98
99 outb_p (0x0e, OBOE_REG_11);
100
101 outb_p (0x00, OBOE_RST);
102 outb_p (0x3f, OBOE_TFP2); /*Write the taskfile address */
103 outb_p (0xff, OBOE_TFP1);
104 outb_p (0xff, OBOE_TFP0);
105 outb_p (0x0f, OBOE_REG_1B);
106 outb_p (0xff, OBOE_REG_1A);
107 outb_p (0x00, OBOE_ISR); /*FIXME: should i do this to disbale ints */
108 outb_p (0x80, OBOE_RST);
109 outb_p (0xe, OBOE_LOCK);
110
111 }
112
113 /*Set the baud rate */
114 static void
115 toshoboe_setbaud (struct toshoboe_cb *self, int baud)
116 {
117 unsigned long flags;
118 IRDA_DEBUG (4, __FUNCTION__ "()\n");
119
120 printk (KERN_WARNING "ToshOboe: setting baud to %d\n", baud);
121
122 save_flags (flags);
123 cli ();
124 switch (baud)
125 {
126 case 2400:
127 outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
128 outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
129 outb_p (0xbf, OBOE_UDIV);
130 break;
131 case 4800:
132 outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
133 outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
134 outb_p (0x5f, OBOE_UDIV);
135 break;
136 case 9600:
137 outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
138 outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
139 outb_p (0x2f, OBOE_UDIV);
140 break;
141 case 19200:
142 outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
143 outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
144 outb_p (0x17, OBOE_UDIV);
145 break;
146 case 38400:
147 outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
148 outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
149 outb_p (0xb, OBOE_UDIV);
150 break;
151 case 57600:
152 outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
153 outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
154 outb_p (0x7, OBOE_UDIV);
155 break;
156 case 115200:
157 outb_p (OBOE_PMDL_SIR, OBOE_PMDL);
158 outb_p (OBOE_SMDL_SIR, OBOE_SMDL);
159 outb_p (0x3, OBOE_UDIV);
160 break;
161 case 1152000:
162 outb_p (OBOE_PMDL_MIR, OBOE_PMDL);
163 outb_p (OBOE_SMDL_MIR, OBOE_SMDL);
164 outb_p (0x1, OBOE_UDIV);
165 break;
166 case 4000000:
167 outb_p (OBOE_PMDL_FIR, OBOE_PMDL);
168 outb_p (OBOE_SMDL_FIR, OBOE_SMDL);
169 outb_p (0x0, OBOE_UDIV);
170 break;
171 }
172
173 restore_flags (flags);
174
175 outb_p (0x00, OBOE_RST);
176 outb_p (0x80, OBOE_RST);
177 outb_p (0x01, OBOE_REG_9);
178
179 self->io.speed = baud;
180 }
181
182 /* Wake the chip up and get it looking at the taskfile */
183 static void
184 toshoboe_startchip (struct toshoboe_cb *self)
185 {
186 __u32 physaddr;
187
188 IRDA_DEBUG (4, __FUNCTION__ "()\n");
189
190
191 outb_p (0, OBOE_LOCK);
192 outb_p (0, OBOE_RST);
193 outb_p (OBOE_NTR_VAL, OBOE_NTR);
194 outb_p (0xf0, OBOE_REG_D);
195 outb_p (0xff, OBOE_ISR);
196 outb_p (0x0f, OBOE_REG_1B);
197 outb_p (0xff, OBOE_REG_1A);
198
199
200 physaddr = virt_to_bus (self->taskfile);
201
202 outb_p ((physaddr >> 0x0a) & 0xff, OBOE_TFP0);
203 outb_p ((physaddr >> 0x12) & 0xff, OBOE_TFP1);
204 outb_p ((physaddr >> 0x1a) & 0x3f, OBOE_TFP2);
205
206 outb_p (0x0e, OBOE_REG_11);
207 outb_p (0x80, OBOE_RST);
208
209 toshoboe_setbaud (self, 9600);
210
211 }
212
213 /*Let the chip look at memory */
214 static void
215 toshoboe_enablebm (struct toshoboe_cb *self)
216 {
217 IRDA_DEBUG (4, __FUNCTION__ "()\n");
218 pci_set_master (self->pdev);
219 }
220
221 /*Don't let the chip look at memory */
222 static void
223 toshoboe_disablebm (struct toshoboe_cb *self)
224 {
225 __u8 command;
226 IRDA_DEBUG (4, __FUNCTION__ "()\n");
227
228 pci_read_config_byte (self->pdev, PCI_COMMAND, &command);
229 command &= ~PCI_COMMAND_MASTER;
230 pci_write_config_byte (self->pdev, PCI_COMMAND, command);
231
232 }
233
234 /*setup the taskfile */
235 static void
236 toshoboe_initbuffs (struct toshoboe_cb *self)
237 {
238 int i;
239 unsigned long flags;
240
241 IRDA_DEBUG (4, __FUNCTION__ "()\n");
242
243 save_flags (flags);
244 cli ();
245
246 for (i = 0; i < TX_SLOTS; ++i)
247 {
248 self->taskfile->xmit[i].len = 0;
249 self->taskfile->xmit[i].control = 0x00;
250 self->taskfile->xmit[i].buffer = virt_to_bus (self->xmit_bufs[i]);
251 }
252
253 for (i = 0; i < RX_SLOTS; ++i)
254 {
255 self->taskfile->recv[i].len = 0;
256 self->taskfile->recv[i].control = 0x83;
257 self->taskfile->recv[i].buffer = virt_to_bus (self->recv_bufs[i]);
258 }
259
260 restore_flags (flags);
261 }
262
263 /*Transmit something */
264 static int
265 toshoboe_hard_xmit (struct sk_buff *skb, struct net_device *dev)
266 {
267 struct toshoboe_cb *self;
268 __s32 speed;
269 int mtt, len;
270
271 self = (struct toshoboe_cb *) dev->priv;
272
273 ASSERT (self != NULL, return 0;
274 );
275
276 /* Check if we need to change the speed */
277 speed = irda_get_next_speed(skb);
278 if ((speed != self->io.speed) && (speed != -1)) {
279 /* Check for empty frame */
280 if (!skb->len) {
281 toshoboe_setbaud(self, speed);
282 dev_kfree_skb(skb);
283 return 0;
284 } else
285 self->new_speed = speed;
286 }
287
288 netif_stop_queue(dev);
289
290 if (self->stopped) {
291 dev_kfree_skb(skb);
292 return 0;
293 }
294
295 #ifdef ONETASK
296 if (self->txpending)
297 return -EBUSY;
298
299 self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
300
301 self->txs &= 0x3f;
302
303 #endif
304
305 if (self->taskfile->xmit[self->txs].control)
306 return -EBUSY;
307
308
309 if (inb_p (OBOE_RST) & OBOE_RST_WRAP)
310 {
311 len = async_wrap_skb (skb, self->xmit_bufs[self->txs], TX_BUF_SZ);
312 }
313 else
314 {
315 len = skb->len;
316 memcpy (self->xmit_bufs[self->txs], skb->data, len);
317 }
318 self->taskfile->xmit[self->txs].len = len & 0x0fff;
319
320
321
322 outb_p (0, OBOE_RST);
323 outb_p (0x1e, OBOE_REG_11);
324
325 self->taskfile->xmit[self->txs].control = 0x84;
326
327 mtt = irda_get_mtt (skb);
328 if (mtt)
329 udelay (mtt);
330
331 self->txpending++;
332
333 /*FIXME: ask about busy,media_busy stuff, for the moment */
334 /*busy means can't queue any more */
335 #ifndef ONETASK
336 if (self->txpending != TX_SLOTS)
337 {
338 netif_wake_queue(dev);
339 }
340 #endif
341
342 outb_p (0x80, OBOE_RST);
343 outb_p (1, OBOE_REG_9);
344
345 self->txs++;
346 self->txs %= TX_SLOTS;
347
348 dev_kfree_skb (skb);
349
350 return 0;
351 }
352
353 /*interrupt handler */
354 static void
355 toshoboe_interrupt (int irq, void *dev_id, struct pt_regs *regs)
356 {
357 struct toshoboe_cb *self = (struct toshoboe_cb *) dev_id;
358 __u8 irqstat;
359 struct sk_buff *skb;
360
361 if (self == NULL)
362 {
363 printk (KERN_WARNING "%s: irq %d for unknown device.\n",
364 driver_name, irq);
365 return;
366 }
367
368 IRDA_DEBUG (4, __FUNCTION__ "()\n");
369
370 irqstat = inb_p (OBOE_ISR);
371
372 /* woz it us */
373 if (!(irqstat & 0xf8))
374 return;
375
376 outb_p (irqstat, OBOE_ISR); /*Acknologede it */
377
378
379 /* Txdone */
380 if (irqstat & OBOE_ISR_TXDONE)
381 {
382 self->txpending--;
383
384 self->stats.tx_packets++;
385
386 if (self->new_speed) {
387 toshoboe_setbaud(self, self->new_speed);
388
389 self->new_speed = 0;
390 }
391 /* Tell network layer that we want more frames */
392 netif_wake_queue(self->netdev);
393 }
394
395 if (irqstat & OBOE_ISR_RXDONE)
396 {
397
398 #ifdef ONETASK
399 self->rxs = inb_p (OBOE_RCVT);
400 self->rxs += (RX_SLOTS - 1);
401 self->rxs %= RX_SLOTS;
402 #else
403 while (self->taskfile->recv[self->rxs].control == 0)
404 #endif
405 {
406 int len = self->taskfile->recv[self->rxs].len;
407
408 if (len > 2)
409 len -= 2;
410
411 skb = dev_alloc_skb (len + 1);
412 if (skb)
413 {
414 skb_reserve (skb, 1);
415
416 skb_put (skb, len);
417 memcpy (skb->data, self->recv_bufs[self->rxs], len);
418
419 self->stats.rx_packets++;
420 skb->dev = self->netdev;
421 skb->mac.raw = skb->data;
422 skb->protocol = htons (ETH_P_IRDA);
423 }
424 else
425 {
426 printk (KERN_INFO __FUNCTION__
427 "(), memory squeeze, dropping frame.\n");
428 }
429
430 self->taskfile->recv[self->rxs].control = 0x83;
431 self->taskfile->recv[self->rxs].len = 0x0;
432
433 self->rxs++;
434 self->rxs %= RX_SLOTS;
435
436 if (skb)
437 netif_rx (skb);
438
439 }
440
441 }
442
443 if (irqstat & OBOE_ISR_20)
444 {
445 printk (KERN_WARNING "Oboe_irq: 20\n");
446 }
447 if (irqstat & OBOE_ISR_10)
448 {
449 printk (KERN_WARNING "Oboe_irq: 10\n");
450 }
451 if (irqstat & 0x8)
452 {
453 /*FIXME: I think this is a TX or RX error of some sort */
454
455 self->stats.tx_errors++;
456 self->stats.rx_errors++;
457
458 }
459
460
461 }
462
463 static int
464 toshoboe_net_init (struct net_device *dev)
465 {
466 IRDA_DEBUG (4, __FUNCTION__ "()\n");
467
468 /* Setup to be a normal IrDA network device driver */
469 irda_device_setup (dev);
470
471 /* Insert overrides below this line! */
472 return 0;
473 }
474
475
476 static void
477 toshoboe_initptrs (struct toshoboe_cb *self)
478 {
479
480 unsigned long flags;
481 save_flags (flags);
482 cli ();
483
484 /*FIXME: need to test this carefully to check which one */
485 /*of the two possible startup logics the chip uses */
486 /*although it won't make any difference if no-one xmits durining init */
487 /*and none what soever if using ONETASK */
488
489 self->rxs = inb_p (OBOE_RCVT);
490 self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
491
492 #if 0
493 self->rxs = 0;
494 self->txs = 0;
495 #endif
496 #if 0
497 self->rxs = RX_SLOTS - 1;
498 self->txs = 0;
499 #endif
500
501
502 self->txpending = 0;
503
504 restore_flags (flags);
505
506 }
507
508
509 static int
510 toshoboe_net_open (struct net_device *dev)
511 {
512 struct toshoboe_cb *self;
513 char hwname[32];
514
515 IRDA_DEBUG (4, __FUNCTION__ "()\n");
516
517 ASSERT (dev != NULL, return -1;
518 );
519 self = (struct toshoboe_cb *) dev->priv;
520
521 ASSERT (self != NULL, return 0;
522 );
523
524 if (self->stopped)
525 return 0;
526
527 if (request_irq (self->io.irq, toshoboe_interrupt,
528 SA_SHIRQ | SA_INTERRUPT, dev->name, (void *) self))
529 {
530
531 return -EAGAIN;
532 }
533
534 toshoboe_initbuffs (self);
535 toshoboe_enablebm (self);
536 toshoboe_startchip (self);
537 toshoboe_initptrs (self);
538
539 /* Ready to play! */
540 netif_start_queue(dev);
541 /* Give self a hardware name */
542 sprintf(hwname, "Toshiba-FIR @ 0x%03x", self->base);
543 /*
544 * Open new IrLAP layer instance, now that everything should be
545 * initialized properly
546 */
547 self->irlap = irlap_open(dev, &self->qos, hwname);
548
549 self->open = 1;
550
551 MOD_INC_USE_COUNT;
552
553 return 0;
554
555 }
556
557 static int
558 toshoboe_net_close (struct net_device *dev)
559 {
560 struct toshoboe_cb *self;
561
562 IRDA_DEBUG (4, __FUNCTION__ "()\n");
563
564 ASSERT (dev != NULL, return -1;
565 );
566 self = (struct toshoboe_cb *) dev->priv;
567
568 /* Stop device */
569 netif_stop_queue(dev);
570
571 /* Stop and remove instance of IrLAP */
572 if (self->irlap)
573 irlap_close(self->irlap);
574 self->irlap = NULL;
575
576 self->open = 0;
577
578 free_irq (self->io.irq, (void *) self);
579
580 if (!self->stopped)
581 {
582 toshoboe_stopchip (self);
583 toshoboe_disablebm (self);
584 }
585
586 MOD_DEC_USE_COUNT;
587
588 return 0;
589
590 }
591
592 /*
593 * Function toshoboe_net_ioctl (dev, rq, cmd)
594 *
595 * Process IOCTL commands for this device
596 *
597 */
598 static int toshoboe_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
599 {
600 struct if_irda_req *irq = (struct if_irda_req *) rq;
601 struct toshoboe_cb *self;
602 unsigned long flags;
603 int ret = 0;
604
605 ASSERT(dev != NULL, return -1;);
606
607 self = dev->priv;
608
609 ASSERT(self != NULL, return -1;);
610
611 IRDA_DEBUG(2, __FUNCTION__ "(), %s, (cmd=0x%X)\n", dev->name, cmd);
612
613 /* Disable interrupts & save flags */
614 save_flags(flags);
615 cli();
616 switch (cmd) {
617 case SIOCSBANDWIDTH: /* Set bandwidth */
618 if (!capable(CAP_NET_ADMIN)) {
619 ret = -EPERM;
620 goto out;
621 }
622 /* toshoboe_setbaud(self, irq->ifr_baudrate); */
623 /* Just change speed once - inserted by Paul Bristow */
624 self->new_speed = irq->ifr_baudrate;
625 break;
626 case SIOCSMEDIABUSY: /* Set media busy */
627 if (!capable(CAP_NET_ADMIN)) {
628 ret = -EPERM;
629 goto out;
630 }
631 irda_device_set_media_busy(self->netdev, TRUE);
632 break;
633 case SIOCGRECEIVING: /* Check if we are receiving right now */
634 irq->ifr_receiving = 0; /* Can't tell */
635 break;
636 default:
637 ret = -EOPNOTSUPP;
638 }
639 out:
640 restore_flags(flags);
641 return ret;
642 }
643
644 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
645 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
646 MODULE_PARM (max_baud, "i");
647 MODULE_PARM_DESC(max_baus, "Maximum baud rate");
648
649 static void
650 toshoboe_remove (struct pci_dev *pci_dev)
651 {
652 int i;
653 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
654
655 IRDA_DEBUG (4, __FUNCTION__ "()\n");
656
657 ASSERT (self != NULL, return;
658 );
659
660 if (!self->stopped)
661 {
662 toshoboe_stopchip (self);
663 toshoboe_disablebm (self);
664 }
665
666 release_region (self->io.sir_base, self->io.sir_ext);
667
668
669 for (i = 0; i < TX_SLOTS; ++i)
670 {
671 kfree (self->xmit_bufs[i]);
672 self->xmit_bufs[i] = NULL;
673 }
674
675 for (i = 0; i < RX_SLOTS; ++i)
676 {
677 kfree (self->recv_bufs[i]);
678 self->recv_bufs[i] = NULL;
679 }
680
681 if (self->netdev) {
682 /* Remove netdevice */
683 rtnl_lock();
684 unregister_netdevice(self->netdev);
685 rtnl_unlock();
686 }
687
688 kfree (self->taskfilebuf);
689 self->taskfilebuf = NULL;
690 self->taskfile = NULL;
691
692 return;
693
694 }
695
696 static int
697 toshoboe_probe (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
698 {
699 struct toshoboe_cb *self;
700 struct net_device *dev;
701 int i = 0;
702 int ok = 0;
703 int err;
704
705 IRDA_DEBUG (4, __FUNCTION__ "()\n");
706
707 if ((err=pci_enable_device(pci_dev)))
708 return err;
709
710 self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL);
711
712 if (self == NULL)
713 {
714 printk (KERN_ERR "IrDA: Can't allocate memory for "
715 "IrDA control block!\n");
716 return -ENOMEM;
717 }
718
719 memset (self, 0, sizeof (struct toshoboe_cb));
720
721 self->open = 0;
722 self->stopped = 0;
723 self->pdev = pci_dev;
724 self->base = pci_resource_start(pci_dev,0);
725
726 self->io.sir_base = self->base;
727 self->io.irq = pci_dev->irq;
728 self->io.sir_ext = CHIP_IO_EXTENT;
729 self->io.speed = 9600;
730
731 /* Lock the port that we need */
732 if (NULL==request_region (self->io.sir_base, self->io.sir_ext, driver_name))
733 {
734 IRDA_DEBUG (0, __FUNCTION__ "(), can't get iobase of 0x%03x\n",
735 self->io.sir_base);
736
737 err = -EBUSY;
738 goto freeself;
739 }
740
741 irda_init_max_qos_capabilies (&self->qos);
742 self->qos.baud_rate.bits = 0;
743
744 if (max_baud >= 2400)
745 self->qos.baud_rate.bits |= IR_2400;
746 /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
747 if (max_baud >= 9600)
748 self->qos.baud_rate.bits |= IR_9600;
749 if (max_baud >= 19200)
750 self->qos.baud_rate.bits |= IR_19200;
751 if (max_baud >= 115200)
752 self->qos.baud_rate.bits |= IR_115200;
753 #ifdef ENABLE_FAST
754 if (max_baud >= 576000)
755 self->qos.baud_rate.bits |= IR_576000;
756 if (max_baud >= 1152000)
757 self->qos.baud_rate.bits |= IR_1152000;
758 if (max_baud >= 4000000)
759 self->qos.baud_rate.bits |= (IR_4000000 << 8);
760 #endif
761
762
763 self->qos.min_turn_time.bits = 0xff; /*FIXME: what does this do? */
764
765 irda_qos_bits_to_value (&self->qos);
766
767 self->flags = IFF_SIR | IFF_DMA | IFF_PIO;
768
769 #ifdef ENABLE_FAST
770 if (max_baud >= 576000)
771 self->flags |= IFF_FIR;
772 #endif
773
774 /* Now setup the endless buffers we need */
775
776 self->txs = 0;
777 self->rxs = 0;
778
779 self->taskfilebuf = kmalloc (OBOE_TASK_BUF_LEN, GFP_KERNEL);
780 if (!self->taskfilebuf)
781 {
782 printk (KERN_ERR "toshoboe: kmalloc for DMA failed()\n");
783 err = -ENOMEM;
784 goto freeregion;
785 }
786
787
788 memset (self->taskfilebuf, 0, OBOE_TASK_BUF_LEN);
789
790 /*We need to align the taskfile on a taskfile size boundary */
791 {
792 __u32 addr;
793
794 addr = (__u32) self->taskfilebuf;
795 addr &= ~(sizeof (struct OboeTaskFile) - 1);
796 addr += sizeof (struct OboeTaskFile);
797
798 self->taskfile = (struct OboeTaskFile *) addr;
799 }
800
801 for (i = 0; i < TX_SLOTS; ++i)
802 {
803 self->xmit_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
804 if (self->xmit_bufs[i])
805 ok++;
806 }
807
808 for (i = 0; i < RX_SLOTS; ++i)
809 {
810 self->recv_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
811 if (self->recv_bufs[i])
812 ok++;
813 }
814
815 if (ok != RX_SLOTS + TX_SLOTS)
816 {
817 printk (KERN_ERR "toshoboe: kmalloc for buffers failed()\n");
818 err = -ENOMEM;
819 goto freebufs;
820
821 }
822
823
824 if (!(dev = dev_alloc("irda%d", &err))) {
825 ERROR(__FUNCTION__ "(), dev_alloc() failed!\n");
826 err = -ENOMEM;
827 goto freebufs;
828 }
829 dev->priv = (void *) self;
830 self->netdev = dev;
831
832 MESSAGE("IrDA: Registered device %s\n", dev->name);
833
834 dev->init = toshoboe_net_init;
835 dev->hard_start_xmit = toshoboe_hard_xmit;
836 dev->open = toshoboe_net_open;
837 dev->stop = toshoboe_net_close;
838 dev->do_ioctl = toshoboe_net_ioctl;
839
840 rtnl_lock();
841 err = register_netdevice(dev);
842 rtnl_unlock();
843 if (err) {
844 ERROR(__FUNCTION__ "(), register_netdev() failed!\n");
845 /* XXX there is not freeing for dev? */
846 goto freebufs;
847 }
848 pci_set_drvdata(pci_dev,self);
849
850 printk (KERN_WARNING "ToshOboe: Using ");
851 #ifdef ONETASK
852 printk ("single");
853 #else
854 printk ("multiple");
855 #endif
856 printk (" tasks, version %s\n", rcsid);
857
858 return (0);
859 freebufs:
860 for (i = 0; i < TX_SLOTS; ++i)
861 if (self->xmit_bufs[i])
862 kfree (self->xmit_bufs[i]);
863 for (i = 0; i < RX_SLOTS; ++i)
864 if (self->recv_bufs[i])
865 kfree (self->recv_bufs[i]);
866 kfree(self->taskfilebuf);
867 freeregion:
868 release_region (self->io.sir_base, self->io.sir_ext);
869 freeself:
870 kfree (self);
871 return err;
872 }
873
874 static int
875 toshoboe_suspend (struct pci_dev *pci_dev, u32 crap)
876 {
877 int i = 10;
878 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
879
880 printk (KERN_WARNING "ToshOboe: suspending\n");
881
882 if (!self || self->stopped)
883 return 0;
884
885 self->stopped = 1;
886
887 if (!self->open)
888 return 0;
889
890 /*FIXME: can't sleep here wait one second */
891
892 while ((i--) && (self->txpending))
893 udelay (100);
894
895 toshoboe_stopchip (self);
896 toshoboe_disablebm (self);
897
898 self->txpending = 0;
899 return 0;
900 }
901
902
903 static int
904 toshoboe_resume (struct pci_dev *pci_dev)
905 {
906 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
907 unsigned long flags;
908
909 if (!self)
910 return 0;
911
912 if (!self->stopped)
913 return 0;
914
915 if (!self->open)
916 {
917 self->stopped = 0;
918 return 0;
919 }
920
921 save_flags (flags);
922 cli ();
923
924 toshoboe_initbuffs (self);
925 toshoboe_enablebm (self);
926 toshoboe_startchip (self);
927
928 toshoboe_setbaud (self, self->io.speed);
929
930 toshoboe_initptrs (self);
931
932 netif_wake_queue(self->netdev);
933 restore_flags (flags);
934 printk (KERN_WARNING "ToshOboe: waking up\n");
935 return 0;
936 }
937
938 static struct pci_driver toshoboe_pci_driver = {
939 name : "toshoboe",
940 id_table : toshoboe_pci_tbl,
941 probe : toshoboe_probe,
942 remove : toshoboe_remove,
943 suspend : toshoboe_suspend,
944 resume : toshoboe_resume
945 };
946
947 int __init
948 toshoboe_init (void)
949 {
950 return pci_module_init(&toshoboe_pci_driver);
951 }
952
953 void
954 toshoboe_cleanup (void)
955 {
956 pci_unregister_driver(&toshoboe_pci_driver);
957 }
958
959 module_init(toshoboe_init);
960 module_exit(toshoboe_cleanup);
961