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