This source file includes following definitions.
- ei_open
- ei_close
- ei_start_xmit
- ei_interrupt
- ei_tx_err
- ei_tx_intr
- ei_receive
- ei_rx_overrun
- get_stats
- set_multicast_list
- ethdev_init
- NS8390_init
- NS8390_trigger_send
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 static const char *version =
40 "8390.c:v1.10 9/23/94 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
41
42 #include <linux/module.h>
43 #include <linux/kernel.h>
44 #include <linux/sched.h>
45 #include <linux/fs.h>
46 #include <linux/types.h>
47 #include <linux/ptrace.h>
48 #include <linux/string.h>
49 #include <asm/system.h>
50 #include <asm/segment.h>
51 #include <asm/bitops.h>
52 #include <asm/io.h>
53 #include <linux/errno.h>
54 #include <linux/fcntl.h>
55 #include <linux/in.h>
56 #include <linux/interrupt.h>
57
58 #include <linux/netdevice.h>
59 #include <linux/etherdevice.h>
60
61 #include "8390.h"
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81 #define ei_reset_8390 (ei_local->reset_8390)
82 #define ei_block_output (ei_local->block_output)
83 #define ei_block_input (ei_local->block_input)
84 #define ei_get_8390_hdr (ei_local->get_8390_hdr)
85
86
87 #ifdef EI_DEBUG
88 int ei_debug = EI_DEBUG;
89 #else
90 int ei_debug = 1;
91 #endif
92
93
94 static void ei_tx_intr(struct device *dev);
95 static void ei_tx_err(struct device *dev);
96 static void ei_receive(struct device *dev);
97 static void ei_rx_overrun(struct device *dev);
98
99
100 static void NS8390_trigger_send(struct device *dev, unsigned int length,
101 int start_page);
102 static void set_multicast_list(struct device *dev);
103
104
105
106
107
108
109 int ei_open(struct device *dev)
110 {
111 struct ei_device *ei_local = (struct ei_device *) dev->priv;
112
113
114 if (ei_local == NULL) {
115 printk(KERN_EMERG "%s: ei_open passed a non-existent device!\n", dev->name);
116 return -ENXIO;
117 }
118
119 irq2dev_map[dev->irq] = dev;
120 NS8390_init(dev, 1);
121 dev->start = 1;
122 ei_local->irqlock = 0;
123 return 0;
124 }
125
126
127 int ei_close(struct device *dev)
128 {
129 NS8390_init(dev, 0);
130 dev->start = 0;
131 return 0;
132 }
133
134 static int ei_start_xmit(struct sk_buff *skb, struct device *dev)
135 {
136 int e8390_base = dev->base_addr;
137 struct ei_device *ei_local = (struct ei_device *) dev->priv;
138 int length, send_length, output_page;
139
140
141
142
143
144
145
146 if (dev->tbusy) {
147 int txsr = inb(e8390_base+EN0_TSR), isr;
148 int tickssofar = jiffies - dev->trans_start;
149 if (tickssofar < TX_TIMEOUT || (tickssofar < (TX_TIMEOUT+5) && ! (txsr & ENTSR_PTX))) {
150 return 1;
151 }
152 isr = inb(e8390_base+EN0_ISR);
153 if (dev->start == 0) {
154 printk("%s: xmit on stopped card\n", dev->name);
155 return 1;
156 }
157
158
159
160
161
162
163
164 printk(KERN_DEBUG "%s: Tx timed out, %s TSR=%#2x, ISR=%#2x, t=%d.\n",
165 dev->name, (txsr & ENTSR_ABT) ? "excess collisions." :
166 (isr) ? "lost interrupt?" : "cable problem?", txsr, isr, tickssofar);
167
168 if (!isr && !ei_local->stat.tx_packets) {
169
170 ei_local->interface_num ^= 1;
171 }
172
173
174 ei_reset_8390(dev);
175 NS8390_init(dev, 1);
176 dev->trans_start = jiffies;
177 }
178
179
180
181
182 if (skb == NULL) {
183 dev_tint(dev);
184 return 0;
185 }
186
187 length = skb->len;
188 if (skb->len <= 0)
189 return 0;
190
191
192 outb_p(0x00, e8390_base + EN0_IMR);
193 if (dev->interrupt) {
194 printk("%s: Tx request while isr active.\n",dev->name);
195 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
196 return 1;
197 }
198 ei_local->irqlock = 1;
199
200 send_length = ETH_ZLEN < length ? length : ETH_ZLEN;
201
202 #ifdef EI_PINGPONG
203
204
205
206
207
208
209
210
211
212 if (ei_local->tx1 == 0) {
213 output_page = ei_local->tx_start_page;
214 ei_local->tx1 = send_length;
215 if (ei_debug && ei_local->tx2 > 0)
216 printk("%s: idle transmitter tx2=%d, lasttx=%d, txing=%d.\n",
217 dev->name, ei_local->tx2, ei_local->lasttx, ei_local->txing);
218 } else if (ei_local->tx2 == 0) {
219 output_page = ei_local->tx_start_page + TX_1X_PAGES;
220 ei_local->tx2 = send_length;
221 if (ei_debug && ei_local->tx1 > 0)
222 printk("%s: idle transmitter, tx1=%d, lasttx=%d, txing=%d.\n",
223 dev->name, ei_local->tx1, ei_local->lasttx, ei_local->txing);
224 } else {
225 if (ei_debug)
226 printk("%s: No Tx buffers free! irq=%d tx1=%d tx2=%d last=%d\n",
227 dev->name, dev->interrupt, ei_local->tx1, ei_local->tx2, ei_local->lasttx);
228 ei_local->irqlock = 0;
229 dev->tbusy = 1;
230 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
231 return 1;
232 }
233
234
235
236
237
238
239
240 ei_block_output(dev, length, skb->data, output_page);
241 if (! ei_local->txing) {
242 ei_local->txing = 1;
243 NS8390_trigger_send(dev, send_length, output_page);
244 dev->trans_start = jiffies;
245 if (output_page == ei_local->tx_start_page) {
246 ei_local->tx1 = -1;
247 ei_local->lasttx = -1;
248 } else {
249 ei_local->tx2 = -1;
250 ei_local->lasttx = -2;
251 }
252 } else
253 ei_local->txqueue++;
254
255 dev->tbusy = (ei_local->tx1 && ei_local->tx2);
256
257 #else
258
259
260
261
262
263
264
265 ei_block_output(dev, length, skb->data, ei_local->tx_start_page);
266 ei_local->txing = 1;
267 NS8390_trigger_send(dev, send_length, ei_local->tx_start_page);
268 dev->trans_start = jiffies;
269 dev->tbusy = 1;
270
271 #endif
272
273
274 ei_local->irqlock = 0;
275 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
276
277 dev_kfree_skb (skb, FREE_WRITE);
278
279 return 0;
280 }
281
282
283
284 void ei_interrupt(int irq, void *dev_id, struct pt_regs * regs)
285 {
286 struct device *dev = (struct device *)(irq2dev_map[irq]);
287 int e8390_base;
288 int interrupts, nr_serviced = 0;
289 struct ei_device *ei_local;
290
291 if (dev == NULL) {
292 printk ("net_interrupt(): irq %d for unknown device.\n", irq);
293 return;
294 }
295 e8390_base = dev->base_addr;
296 ei_local = (struct ei_device *) dev->priv;
297 if (dev->interrupt || ei_local->irqlock) {
298
299 printk(ei_local->irqlock
300 ? "%s: Interrupted while interrupts are masked! isr=%#2x imr=%#2x.\n"
301 : "%s: Reentering the interrupt handler! isr=%#2x imr=%#2x.\n",
302 dev->name, inb_p(e8390_base + EN0_ISR),
303 inb_p(e8390_base + EN0_IMR));
304 return;
305 }
306
307 dev->interrupt = 1;
308
309
310 outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);
311 if (ei_debug > 3)
312 printk("%s: interrupt(isr=%#2.2x).\n", dev->name,
313 inb_p(e8390_base + EN0_ISR));
314
315
316 while ((interrupts = inb_p(e8390_base + EN0_ISR)) != 0
317 && ++nr_serviced < MAX_SERVICE) {
318 if (dev->start == 0) {
319 printk("%s: interrupt from stopped card\n", dev->name);
320 interrupts = 0;
321 break;
322 }
323 if (interrupts & ENISR_OVER) {
324 ei_rx_overrun(dev);
325 } else if (interrupts & (ENISR_RX+ENISR_RX_ERR)) {
326
327 ei_receive(dev);
328 }
329
330 if (interrupts & ENISR_TX) {
331 ei_tx_intr(dev);
332 } else if (interrupts & ENISR_TX_ERR) {
333 ei_tx_err(dev);
334 }
335
336 if (interrupts & ENISR_COUNTERS) {
337 ei_local->stat.rx_frame_errors += inb_p(e8390_base + EN0_COUNTER0);
338 ei_local->stat.rx_crc_errors += inb_p(e8390_base + EN0_COUNTER1);
339 ei_local->stat.rx_missed_errors+= inb_p(e8390_base + EN0_COUNTER2);
340 outb_p(ENISR_COUNTERS, e8390_base + EN0_ISR);
341 }
342
343
344 if (interrupts & ENISR_RDC) {
345 outb_p(ENISR_RDC, e8390_base + EN0_ISR);
346 }
347
348 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
349 }
350
351 if (interrupts && ei_debug) {
352 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base + E8390_CMD);
353 if (nr_serviced >= MAX_SERVICE) {
354 printk("%s: Too much work at interrupt, status %#2.2x\n",
355 dev->name, interrupts);
356 outb_p(ENISR_ALL, e8390_base + EN0_ISR);
357 } else {
358 printk("%s: unknown interrupt %#2x\n", dev->name, interrupts);
359 outb_p(0xff, e8390_base + EN0_ISR);
360 }
361 }
362 dev->interrupt = 0;
363 return;
364 }
365
366
367
368
369
370
371
372
373
374
375 static void ei_tx_err(struct device *dev)
376 {
377 int e8390_base = dev->base_addr;
378 unsigned char txsr = inb_p(e8390_base+EN0_TSR);
379 unsigned char tx_was_aborted = txsr & (ENTSR_ABT+ENTSR_FU);
380
381 #ifdef VERBOSE_ERROR_DUMP
382 printk(KERN_DEBUG "%s: transmitter error (%#2x): ", dev->name, txsr);
383 if (txsr & ENTSR_ABT)
384 printk("excess-collisions ");
385 if (txsr & ENTSR_ND)
386 printk("non-deferral ");
387 if (txsr & ENTSR_CRS)
388 printk("lost-carrier ");
389 if (txsr & ENTSR_FU)
390 printk("FIFO-underrun ");
391 if (txsr & ENTSR_CDH)
392 printk("lost-heartbeat ");
393 printk("\n");
394 #endif
395
396 outb_p(ENISR_TX_ERR, e8390_base + EN0_ISR);
397
398 if (tx_was_aborted)
399 ei_tx_intr(dev);
400
401 }
402
403
404
405 static void ei_tx_intr(struct device *dev)
406 {
407 int e8390_base = dev->base_addr;
408 int status = inb(e8390_base + EN0_TSR);
409 struct ei_device *ei_local = (struct ei_device *) dev->priv;
410
411 outb_p(ENISR_TX, e8390_base + EN0_ISR);
412
413 #ifdef EI_PINGPONG
414
415
416
417
418
419 ei_local->txqueue--;
420 if (ei_local->tx1 < 0) {
421 if (ei_local->lasttx != 1 && ei_local->lasttx != -1)
422 printk("%s: bogus last_tx_buffer %d, tx1=%d.\n",
423 ei_local->name, ei_local->lasttx, ei_local->tx1);
424 ei_local->tx1 = 0;
425 dev->tbusy = 0;
426 if (ei_local->tx2 > 0) {
427 ei_local->txing = 1;
428 NS8390_trigger_send(dev, ei_local->tx2, ei_local->tx_start_page + 6);
429 dev->trans_start = jiffies;
430 ei_local->tx2 = -1,
431 ei_local->lasttx = 2;
432 } else
433 ei_local->lasttx = 20, ei_local->txing = 0;
434 } else if (ei_local->tx2 < 0) {
435 if (ei_local->lasttx != 2 && ei_local->lasttx != -2)
436 printk("%s: bogus last_tx_buffer %d, tx2=%d.\n",
437 ei_local->name, ei_local->lasttx, ei_local->tx2);
438 ei_local->tx2 = 0;
439 dev->tbusy = 0;
440 if (ei_local->tx1 > 0) {
441 ei_local->txing = 1;
442 NS8390_trigger_send(dev, ei_local->tx1, ei_local->tx_start_page);
443 dev->trans_start = jiffies;
444 ei_local->tx1 = -1;
445 ei_local->lasttx = 1;
446 } else
447 ei_local->lasttx = 10, ei_local->txing = 0;
448 } else
449 printk("%s: unexpected TX-done interrupt, lasttx=%d.\n",
450 dev->name, ei_local->lasttx);
451
452 #else
453
454
455
456 ei_local->txing = 0;
457 dev->tbusy = 0;
458 #endif
459
460
461 if (status & ENTSR_COL)
462 ei_local->stat.collisions++;
463 if (status & ENTSR_PTX)
464 ei_local->stat.tx_packets++;
465 else {
466 ei_local->stat.tx_errors++;
467 if (status & ENTSR_ABT) ei_local->stat.tx_aborted_errors++;
468 if (status & ENTSR_CRS) ei_local->stat.tx_carrier_errors++;
469 if (status & ENTSR_FU) ei_local->stat.tx_fifo_errors++;
470 if (status & ENTSR_CDH) ei_local->stat.tx_heartbeat_errors++;
471 if (status & ENTSR_OWC) ei_local->stat.tx_window_errors++;
472 }
473
474 mark_bh (NET_BH);
475 }
476
477
478
479 static void ei_receive(struct device *dev)
480 {
481 int e8390_base = dev->base_addr;
482 struct ei_device *ei_local = (struct ei_device *) dev->priv;
483 unsigned char rxing_page, this_frame, next_frame;
484 unsigned short current_offset;
485 int rx_pkt_count = 0;
486 struct e8390_pkt_hdr rx_frame;
487 int num_rx_pages = ei_local->stop_page-ei_local->rx_start_page;
488
489 while (++rx_pkt_count < 10) {
490 int pkt_len;
491
492
493 outb_p(E8390_NODMA+E8390_PAGE1, e8390_base + E8390_CMD);
494 rxing_page = inb_p(e8390_base + EN1_CURPAG);
495 outb_p(E8390_NODMA+E8390_PAGE0, e8390_base + E8390_CMD);
496
497
498 this_frame = inb_p(e8390_base + EN0_BOUNDARY) + 1;
499 if (this_frame >= ei_local->stop_page)
500 this_frame = ei_local->rx_start_page;
501
502
503
504 if (ei_debug > 0 && this_frame != ei_local->current_page)
505 printk("%s: mismatched read page pointers %2x vs %2x.\n",
506 dev->name, this_frame, ei_local->current_page);
507
508 if (this_frame == rxing_page)
509 break;
510
511 current_offset = this_frame << 8;
512 ei_get_8390_hdr(dev, &rx_frame, this_frame);
513
514 pkt_len = rx_frame.count - sizeof(struct e8390_pkt_hdr);
515
516 next_frame = this_frame + 1 + ((pkt_len+4)>>8);
517
518
519
520
521 if (rx_frame.next != next_frame
522 && rx_frame.next != next_frame + 1
523 && rx_frame.next != next_frame - num_rx_pages
524 && rx_frame.next != next_frame + 1 - num_rx_pages) {
525 ei_local->current_page = rxing_page;
526 outb(ei_local->current_page-1, e8390_base+EN0_BOUNDARY);
527 ei_local->stat.rx_errors++;
528 continue;
529 }
530
531 if (pkt_len < 60 || pkt_len > 1518) {
532 if (ei_debug)
533 printk("%s: bogus packet size: %d, status=%#2x nxpg=%#2x.\n",
534 dev->name, rx_frame.count, rx_frame.status,
535 rx_frame.next);
536 ei_local->stat.rx_errors++;
537 } else if ((rx_frame.status & 0x0F) == ENRSR_RXOK) {
538 struct sk_buff *skb;
539
540 skb = dev_alloc_skb(pkt_len+2);
541 if (skb == NULL) {
542 if (ei_debug > 1)
543 printk("%s: Couldn't allocate a sk_buff of size %d.\n",
544 dev->name, pkt_len);
545 ei_local->stat.rx_dropped++;
546 break;
547 } else {
548 skb_reserve(skb,2);
549 skb->dev = dev;
550 skb_put(skb, pkt_len);
551 ei_block_input(dev, pkt_len, skb, current_offset + sizeof(rx_frame));
552 skb->protocol=eth_type_trans(skb,dev);
553 netif_rx(skb);
554 ei_local->stat.rx_packets++;
555 }
556 } else {
557 int errs = rx_frame.status;
558 if (ei_debug)
559 printk("%s: bogus packet: status=%#2x nxpg=%#2x size=%d\n",
560 dev->name, rx_frame.status, rx_frame.next,
561 rx_frame.count);
562 if (errs & ENRSR_FO)
563 ei_local->stat.rx_fifo_errors++;
564 }
565 next_frame = rx_frame.next;
566
567
568 if (next_frame >= ei_local->stop_page) {
569 printk("%s: next frame inconsistency, %#2x\n", dev->name,
570 next_frame);
571 next_frame = ei_local->rx_start_page;
572 }
573 ei_local->current_page = next_frame;
574 outb_p(next_frame-1, e8390_base+EN0_BOUNDARY);
575 }
576
577
578
579 outb_p(ENISR_RX+ENISR_RX_ERR, e8390_base+EN0_ISR);
580 return;
581 }
582
583
584
585 static void ei_rx_overrun(struct device *dev)
586 {
587 int e8390_base = dev->base_addr;
588 int reset_start_time = jiffies;
589 struct ei_device *ei_local = (struct ei_device *) dev->priv;
590
591
592 outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base+E8390_CMD);
593
594 if (ei_debug > 1)
595 printk("%s: Receiver overrun.\n", dev->name);
596 ei_local->stat.rx_over_errors++;
597
598
599
600
601
602
603
604
605 while ((inb_p(e8390_base+EN0_ISR) & ENISR_RESET) == 0)
606 if (jiffies - reset_start_time > 2*HZ/100) {
607 printk("%s: reset did not complete at ei_rx_overrun.\n",
608 dev->name);
609 NS8390_init(dev, 1);
610 return;
611 }
612
613
614 ei_receive(dev);
615
616 outb_p(ENISR_OVER, e8390_base+EN0_ISR);
617
618 outb_p(E8390_NODMA + E8390_PAGE0 + E8390_START, e8390_base + E8390_CMD);
619 outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR);
620 }
621
622 static struct enet_statistics *get_stats(struct device *dev)
623 {
624 short ioaddr = dev->base_addr;
625 struct ei_device *ei_local = (struct ei_device *) dev->priv;
626
627
628 if (dev->start == 0) return &ei_local->stat;
629
630
631 ei_local->stat.rx_frame_errors += inb_p(ioaddr + EN0_COUNTER0);
632 ei_local->stat.rx_crc_errors += inb_p(ioaddr + EN0_COUNTER1);
633 ei_local->stat.rx_missed_errors+= inb_p(ioaddr + EN0_COUNTER2);
634
635 return &ei_local->stat;
636 }
637
638
639
640
641
642 static void set_multicast_list(struct device *dev)
643 {
644 short ioaddr = dev->base_addr;
645
646 if(dev->flags&IFF_PROMISC)
647 {
648 outb_p(E8390_RXCONFIG | 0x18, ioaddr + EN0_RXCR);
649 }
650 else if((dev->flags&IFF_ALLMULTI)||dev->mc_list)
651 {
652
653
654 outb_p(E8390_RXCONFIG | 0x08, ioaddr + EN0_RXCR);
655 }
656 else
657 outb_p(E8390_RXCONFIG, ioaddr + EN0_RXCR);
658 }
659
660
661 int ethdev_init(struct device *dev)
662 {
663 if (ei_debug > 1)
664 printk(version);
665
666 if (dev->priv == NULL) {
667 struct ei_device *ei_local;
668
669 dev->priv = kmalloc(sizeof(struct ei_device), GFP_KERNEL);
670 if (dev->priv == NULL)
671 return -ENOMEM;
672 memset(dev->priv, 0, sizeof(struct ei_device));
673 ei_local = (struct ei_device *)dev->priv;
674 }
675
676 dev->hard_start_xmit = &ei_start_xmit;
677 dev->get_stats = get_stats;
678 dev->set_multicast_list = &set_multicast_list;
679
680 ether_setup(dev);
681
682 return 0;
683 }
684
685
686
687
688 void NS8390_init(struct device *dev, int startp)
689 {
690 int e8390_base = dev->base_addr;
691 struct ei_device *ei_local = (struct ei_device *) dev->priv;
692 int i;
693 int endcfg = ei_local->word16 ? (0x48 | ENDCFG_WTS) : 0x48;
694 unsigned long flags;
695
696
697 outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base);
698 outb_p(endcfg, e8390_base + EN0_DCFG);
699
700 outb_p(0x00, e8390_base + EN0_RCNTLO);
701 outb_p(0x00, e8390_base + EN0_RCNTHI);
702
703 outb_p(E8390_RXOFF, e8390_base + EN0_RXCR);
704 outb_p(E8390_TXOFF, e8390_base + EN0_TXCR);
705
706 outb_p(ei_local->tx_start_page, e8390_base + EN0_TPSR);
707 ei_local->tx1 = ei_local->tx2 = 0;
708 outb_p(ei_local->rx_start_page, e8390_base + EN0_STARTPG);
709 outb_p(ei_local->stop_page-1, e8390_base + EN0_BOUNDARY);
710 ei_local->current_page = ei_local->rx_start_page;
711 outb_p(ei_local->stop_page, e8390_base + EN0_STOPPG);
712
713 outb_p(0xFF, e8390_base + EN0_ISR);
714 outb_p(0x00, e8390_base + EN0_IMR);
715
716
717
718 save_flags(flags);
719 cli();
720 outb_p(E8390_NODMA + E8390_PAGE1 + E8390_STOP, e8390_base);
721 for(i = 0; i < 6; i++) {
722 outb_p(dev->dev_addr[i], e8390_base + EN1_PHYS + i);
723 }
724
725
726 for(i = 0; i < 8; i++)
727 outb_p(0xff, e8390_base + EN1_MULT + i);
728
729 outb_p(ei_local->rx_start_page, e8390_base + EN1_CURPAG);
730 outb_p(E8390_NODMA+E8390_PAGE0+E8390_STOP, e8390_base);
731 restore_flags(flags);
732 dev->tbusy = 0;
733 dev->interrupt = 0;
734 ei_local->tx1 = ei_local->tx2 = 0;
735 ei_local->txing = 0;
736 if (startp) {
737 outb_p(0xff, e8390_base + EN0_ISR);
738 outb_p(ENISR_ALL, e8390_base + EN0_IMR);
739 outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, e8390_base);
740 outb_p(E8390_TXCONFIG, e8390_base + EN0_TXCR);
741
742 outb_p(E8390_RXCONFIG, e8390_base + EN0_RXCR);
743 dev->set_multicast_list(dev);
744
745 }
746 return;
747 }
748
749
750 static void NS8390_trigger_send(struct device *dev, unsigned int length,
751 int start_page)
752 {
753 int e8390_base = dev->base_addr;
754
755 outb_p(E8390_NODMA+E8390_PAGE0, e8390_base);
756
757 if (inb_p(e8390_base) & E8390_TRANS) {
758 printk("%s: trigger_send() called with the transmitter busy.\n",
759 dev->name);
760 return;
761 }
762 outb_p(length & 0xff, e8390_base + EN0_TCNTLO);
763 outb_p(length >> 8, e8390_base + EN0_TCNTHI);
764 outb_p(start_page, e8390_base + EN0_TPSR);
765 outb_p(E8390_NODMA+E8390_TRANS+E8390_START, e8390_base);
766 return;
767 }
768
769 #ifdef MODULE
770
771 int init_module(void)
772 {
773 return 0;
774 }
775
776 void
777 cleanup_module(void)
778 {
779 }
780 #endif
781
782
783
784
785
786
787
788
789
790