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
toshoboe_stopchip(struct toshoboe_cb * self)95 toshoboe_stopchip (struct toshoboe_cb *self)
96 {
97 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
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
toshoboe_setbaud(struct toshoboe_cb * self,int baud)115 toshoboe_setbaud (struct toshoboe_cb *self, int baud)
116 {
117 unsigned long flags;
118 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
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
toshoboe_startchip(struct toshoboe_cb * self)184 toshoboe_startchip (struct toshoboe_cb *self)
185 {
186 __u32 physaddr;
187
188 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
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
toshoboe_enablebm(struct toshoboe_cb * self)215 toshoboe_enablebm (struct toshoboe_cb *self)
216 {
217 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
218 pci_set_master (self->pdev);
219 }
220
221 /*Don't let the chip look at memory */
222 static void
toshoboe_disablebm(struct toshoboe_cb * self)223 toshoboe_disablebm (struct toshoboe_cb *self)
224 {
225 __u8 command;
226 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
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
toshoboe_initbuffs(struct toshoboe_cb * self)236 toshoboe_initbuffs (struct toshoboe_cb *self)
237 {
238 int i;
239 unsigned long flags;
240
241 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
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
toshoboe_hard_xmit(struct sk_buff * skb,struct net_device * dev)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
toshoboe_interrupt(int irq,void * dev_id,struct pt_regs * regs)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, "%s()\n", __FUNCTION__);
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 "%s(), memory squeeze, dropping frame.\n", __FUNCTION__);
427 }
428
429 self->taskfile->recv[self->rxs].control = 0x83;
430 self->taskfile->recv[self->rxs].len = 0x0;
431
432 self->rxs++;
433 self->rxs %= RX_SLOTS;
434
435 if (skb)
436 netif_rx (skb);
437
438 }
439
440 }
441
442 if (irqstat & OBOE_ISR_20)
443 {
444 printk (KERN_WARNING "Oboe_irq: 20\n");
445 }
446 if (irqstat & OBOE_ISR_10)
447 {
448 printk (KERN_WARNING "Oboe_irq: 10\n");
449 }
450 if (irqstat & 0x8)
451 {
452 /*FIXME: I think this is a TX or RX error of some sort */
453
454 self->stats.tx_errors++;
455 self->stats.rx_errors++;
456
457 }
458
459
460 }
461
462 static int
toshoboe_net_init(struct net_device * dev)463 toshoboe_net_init (struct net_device *dev)
464 {
465 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
466
467 /* Setup to be a normal IrDA network device driver */
468 irda_device_setup (dev);
469
470 /* Insert overrides below this line! */
471 return 0;
472 }
473
474
475 static void
toshoboe_initptrs(struct toshoboe_cb * self)476 toshoboe_initptrs (struct toshoboe_cb *self)
477 {
478
479 unsigned long flags;
480 save_flags (flags);
481 cli ();
482
483 /*FIXME: need to test this carefully to check which one */
484 /*of the two possible startup logics the chip uses */
485 /*although it won't make any difference if no-one xmits durining init */
486 /*and none what soever if using ONETASK */
487
488 self->rxs = inb_p (OBOE_RCVT);
489 self->txs = inb_p (OBOE_XMTT) - OBOE_XMTT_OFFSET;
490
491 #if 0
492 self->rxs = 0;
493 self->txs = 0;
494 #endif
495 #if 0
496 self->rxs = RX_SLOTS - 1;
497 self->txs = 0;
498 #endif
499
500
501 self->txpending = 0;
502
503 restore_flags (flags);
504
505 }
506
507
508 static int
toshoboe_net_open(struct net_device * dev)509 toshoboe_net_open (struct net_device *dev)
510 {
511 struct toshoboe_cb *self;
512 char hwname[32];
513
514 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
515
516 ASSERT (dev != NULL, return -1;
517 );
518 self = (struct toshoboe_cb *) dev->priv;
519
520 ASSERT (self != NULL, return 0;
521 );
522
523 if (self->stopped)
524 return 0;
525
526 if (request_irq (self->io.irq, toshoboe_interrupt,
527 SA_SHIRQ | SA_INTERRUPT, dev->name, (void *) self))
528 {
529
530 return -EAGAIN;
531 }
532
533 toshoboe_initbuffs (self);
534 toshoboe_enablebm (self);
535 toshoboe_startchip (self);
536 toshoboe_initptrs (self);
537
538 /* Ready to play! */
539 netif_start_queue(dev);
540 /* Give self a hardware name */
541 sprintf(hwname, "Toshiba-FIR @ 0x%03x", self->base);
542 /*
543 * Open new IrLAP layer instance, now that everything should be
544 * initialized properly
545 */
546 self->irlap = irlap_open(dev, &self->qos, hwname);
547
548 self->open = 1;
549
550 MOD_INC_USE_COUNT;
551
552 return 0;
553
554 }
555
556 static int
toshoboe_net_close(struct net_device * dev)557 toshoboe_net_close (struct net_device *dev)
558 {
559 struct toshoboe_cb *self;
560
561 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
562
563 ASSERT (dev != NULL, return -1;
564 );
565 self = (struct toshoboe_cb *) dev->priv;
566
567 /* Stop device */
568 netif_stop_queue(dev);
569
570 /* Stop and remove instance of IrLAP */
571 if (self->irlap)
572 irlap_close(self->irlap);
573 self->irlap = NULL;
574
575 self->open = 0;
576
577 free_irq (self->io.irq, (void *) self);
578
579 if (!self->stopped)
580 {
581 toshoboe_stopchip (self);
582 toshoboe_disablebm (self);
583 }
584
585 MOD_DEC_USE_COUNT;
586
587 return 0;
588
589 }
590
591 /*
592 * Function toshoboe_net_ioctl (dev, rq, cmd)
593 *
594 * Process IOCTL commands for this device
595 *
596 */
toshoboe_net_ioctl(struct net_device * dev,struct ifreq * rq,int cmd)597 static int toshoboe_net_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
598 {
599 struct if_irda_req *irq = (struct if_irda_req *) rq;
600 struct toshoboe_cb *self;
601 unsigned long flags;
602 int ret = 0;
603
604 ASSERT(dev != NULL, return -1;);
605
606 self = dev->priv;
607
608 ASSERT(self != NULL, return -1;);
609
610 IRDA_DEBUG(2, "%s(), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
611
612 /* Disable interrupts & save flags */
613 save_flags(flags);
614 cli();
615 switch (cmd) {
616 case SIOCSBANDWIDTH: /* Set bandwidth */
617 if (!capable(CAP_NET_ADMIN)) {
618 ret = -EPERM;
619 goto out;
620 }
621 /* toshoboe_setbaud(self, irq->ifr_baudrate); */
622 /* Just change speed once - inserted by Paul Bristow */
623 self->new_speed = irq->ifr_baudrate;
624 break;
625 case SIOCSMEDIABUSY: /* Set media busy */
626 if (!capable(CAP_NET_ADMIN)) {
627 ret = -EPERM;
628 goto out;
629 }
630 irda_device_set_media_busy(self->netdev, TRUE);
631 break;
632 case SIOCGRECEIVING: /* Check if we are receiving right now */
633 irq->ifr_receiving = 0; /* Can't tell */
634 break;
635 default:
636 ret = -EOPNOTSUPP;
637 }
638 out:
639 restore_flags(flags);
640 return ret;
641 }
642
643 MODULE_DESCRIPTION("Toshiba OBOE IrDA Device Driver");
644 MODULE_AUTHOR("James McKenzie <james@fishsoup.dhs.org>");
645 MODULE_LICENSE("GPL");
646
647 MODULE_PARM (max_baud, "i");
648 MODULE_PARM_DESC(max_baus, "Maximum baud rate");
649
650 static void
toshoboe_remove(struct pci_dev * pci_dev)651 toshoboe_remove (struct pci_dev *pci_dev)
652 {
653 int i;
654 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
655
656 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
657
658 ASSERT (self != NULL, return;
659 );
660
661 if (!self->stopped)
662 {
663 toshoboe_stopchip (self);
664 toshoboe_disablebm (self);
665 }
666
667 release_region (self->io.sir_base, self->io.sir_ext);
668
669
670 for (i = 0; i < TX_SLOTS; ++i)
671 {
672 kfree (self->xmit_bufs[i]);
673 self->xmit_bufs[i] = NULL;
674 }
675
676 for (i = 0; i < RX_SLOTS; ++i)
677 {
678 kfree (self->recv_bufs[i]);
679 self->recv_bufs[i] = NULL;
680 }
681
682 if (self->netdev) {
683 /* Remove netdevice */
684 rtnl_lock();
685 unregister_netdevice(self->netdev);
686 rtnl_unlock();
687 }
688
689 kfree (self->taskfilebuf);
690 self->taskfilebuf = NULL;
691 self->taskfile = NULL;
692
693 return;
694
695 }
696
697 static int
toshoboe_probe(struct pci_dev * pci_dev,const struct pci_device_id * pdid)698 toshoboe_probe (struct pci_dev *pci_dev, const struct pci_device_id *pdid)
699 {
700 struct toshoboe_cb *self;
701 struct net_device *dev;
702 int i = 0;
703 int ok = 0;
704 int err;
705
706 IRDA_DEBUG (4, "%s()\n", __FUNCTION__);
707
708 if ((err=pci_enable_device(pci_dev)))
709 return err;
710
711 self = kmalloc (sizeof (struct toshoboe_cb), GFP_KERNEL);
712
713 if (self == NULL)
714 {
715 printk (KERN_ERR "IrDA: Can't allocate memory for "
716 "IrDA control block!\n");
717 return -ENOMEM;
718 }
719
720 memset (self, 0, sizeof (struct toshoboe_cb));
721
722 self->open = 0;
723 self->stopped = 0;
724 self->pdev = pci_dev;
725 self->base = pci_resource_start(pci_dev,0);
726
727 self->io.sir_base = self->base;
728 self->io.irq = pci_dev->irq;
729 self->io.sir_ext = CHIP_IO_EXTENT;
730 self->io.speed = 9600;
731
732 /* Lock the port that we need */
733 if (NULL==request_region (self->io.sir_base, self->io.sir_ext, driver_name))
734 {
735 IRDA_DEBUG (0, "%s(), can't get iobase of 0x%03x\n",
736 __FUNCTION__, self->io.sir_base);
737
738 err = -EBUSY;
739 goto freeself;
740 }
741
742 irda_init_max_qos_capabilies (&self->qos);
743 self->qos.baud_rate.bits = 0;
744
745 if (max_baud >= 2400)
746 self->qos.baud_rate.bits |= IR_2400;
747 /*if (max_baud>=4800) idev->qos.baud_rate.bits|=IR_4800; */
748 if (max_baud >= 9600)
749 self->qos.baud_rate.bits |= IR_9600;
750 if (max_baud >= 19200)
751 self->qos.baud_rate.bits |= IR_19200;
752 if (max_baud >= 115200)
753 self->qos.baud_rate.bits |= IR_115200;
754 #ifdef ENABLE_FAST
755 if (max_baud >= 576000)
756 self->qos.baud_rate.bits |= IR_576000;
757 if (max_baud >= 1152000)
758 self->qos.baud_rate.bits |= IR_1152000;
759 if (max_baud >= 4000000)
760 self->qos.baud_rate.bits |= (IR_4000000 << 8);
761 #endif
762
763
764 self->qos.min_turn_time.bits = 0xff; /*FIXME: what does this do? */
765
766 irda_qos_bits_to_value (&self->qos);
767
768 self->flags = IFF_SIR | IFF_DMA | IFF_PIO;
769
770 #ifdef ENABLE_FAST
771 if (max_baud >= 576000)
772 self->flags |= IFF_FIR;
773 #endif
774
775 /* Now setup the endless buffers we need */
776
777 self->txs = 0;
778 self->rxs = 0;
779
780 self->taskfilebuf = kmalloc (OBOE_TASK_BUF_LEN, GFP_KERNEL);
781 if (!self->taskfilebuf)
782 {
783 printk (KERN_ERR "toshoboe: kmalloc for DMA failed()\n");
784 err = -ENOMEM;
785 goto freeregion;
786 }
787
788
789 memset (self->taskfilebuf, 0, OBOE_TASK_BUF_LEN);
790
791 /*We need to align the taskfile on a taskfile size boundary */
792 {
793 __u32 addr;
794
795 addr = (__u32) self->taskfilebuf;
796 addr &= ~(sizeof (struct OboeTaskFile) - 1);
797 addr += sizeof (struct OboeTaskFile);
798
799 self->taskfile = (struct OboeTaskFile *) addr;
800 }
801
802 for (i = 0; i < TX_SLOTS; ++i)
803 {
804 self->xmit_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
805 if (self->xmit_bufs[i])
806 ok++;
807 }
808
809 for (i = 0; i < RX_SLOTS; ++i)
810 {
811 self->recv_bufs[i] = kmalloc (TX_BUF_SZ, GFP_KERNEL | GFP_DMA);
812 if (self->recv_bufs[i])
813 ok++;
814 }
815
816 if (ok != RX_SLOTS + TX_SLOTS)
817 {
818 printk (KERN_ERR "toshoboe: kmalloc for buffers failed()\n");
819 err = -ENOMEM;
820 goto freebufs;
821
822 }
823
824
825 if (!(dev = dev_alloc("irda%d", &err))) {
826 ERROR("%s(), dev_alloc() failed!\n", __FUNCTION__);
827 err = -ENOMEM;
828 goto freebufs;
829 }
830 dev->priv = (void *) self;
831 self->netdev = dev;
832
833 MESSAGE("IrDA: Registered device %s\n", dev->name);
834
835 dev->init = toshoboe_net_init;
836 dev->hard_start_xmit = toshoboe_hard_xmit;
837 dev->open = toshoboe_net_open;
838 dev->stop = toshoboe_net_close;
839 dev->do_ioctl = toshoboe_net_ioctl;
840
841 rtnl_lock();
842 err = register_netdevice(dev);
843 rtnl_unlock();
844 if (err) {
845 ERROR("%s(), register_netdev() failed!\n", __FUNCTION__);
846 /* XXX there is not freeing for dev? */
847 goto freebufs;
848 }
849 pci_set_drvdata(pci_dev,self);
850
851 printk (KERN_WARNING "ToshOboe: Using ");
852 #ifdef ONETASK
853 printk ("single");
854 #else
855 printk ("multiple");
856 #endif
857 printk (" tasks, version %s\n", rcsid);
858
859 return (0);
860 freebufs:
861 for (i = 0; i < TX_SLOTS; ++i)
862 if (self->xmit_bufs[i])
863 kfree (self->xmit_bufs[i]);
864 for (i = 0; i < RX_SLOTS; ++i)
865 if (self->recv_bufs[i])
866 kfree (self->recv_bufs[i]);
867 kfree(self->taskfilebuf);
868 freeregion:
869 release_region (self->io.sir_base, self->io.sir_ext);
870 freeself:
871 kfree (self);
872 return err;
873 }
874
875 static int
toshoboe_suspend(struct pci_dev * pci_dev,u32 crap)876 toshoboe_suspend (struct pci_dev *pci_dev, u32 crap)
877 {
878 int i = 10;
879 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
880
881 printk (KERN_WARNING "ToshOboe: suspending\n");
882
883 if (!self || self->stopped)
884 return 0;
885
886 self->stopped = 1;
887
888 if (!self->open)
889 return 0;
890
891 /*FIXME: can't sleep here wait one second */
892
893 while ((i--) && (self->txpending))
894 udelay (100);
895
896 toshoboe_stopchip (self);
897 toshoboe_disablebm (self);
898
899 self->txpending = 0;
900 return 0;
901 }
902
903
904 static int
toshoboe_resume(struct pci_dev * pci_dev)905 toshoboe_resume (struct pci_dev *pci_dev)
906 {
907 struct toshoboe_cb *self = (struct toshoboe_cb*)pci_get_drvdata(pci_dev);
908 unsigned long flags;
909
910 if (!self)
911 return 0;
912
913 if (!self->stopped)
914 return 0;
915
916 if (!self->open)
917 {
918 self->stopped = 0;
919 return 0;
920 }
921
922 save_flags (flags);
923 cli ();
924
925 toshoboe_initbuffs (self);
926 toshoboe_enablebm (self);
927 toshoboe_startchip (self);
928
929 toshoboe_setbaud (self, self->io.speed);
930
931 toshoboe_initptrs (self);
932
933 netif_wake_queue(self->netdev);
934 restore_flags (flags);
935 printk (KERN_WARNING "ToshOboe: waking up\n");
936 return 0;
937 }
938
939 static struct pci_driver toshoboe_pci_driver = {
940 name : "toshoboe",
941 id_table : toshoboe_pci_tbl,
942 probe : toshoboe_probe,
943 remove : toshoboe_remove,
944 suspend : toshoboe_suspend,
945 resume : toshoboe_resume
946 };
947
948 int __init
toshoboe_init(void)949 toshoboe_init (void)
950 {
951 return pci_module_init(&toshoboe_pci_driver);
952 }
953
954 void
toshoboe_cleanup(void)955 toshoboe_cleanup (void)
956 {
957 pci_unregister_driver(&toshoboe_pci_driver);
958 }
959
960 module_init(toshoboe_init);
961 module_exit(toshoboe_cleanup);
962