1 /* $NetBSD: if_ntwoc_isa.c,v 1.21 2009/05/12 09:10:15 cegger Exp $ */
3 * Copyright (c) 1999 Christian E. Hopps
4 * Copyright (c) 1996 John Hay.
5 * Copyright (c) 1996 SDL Communications, Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $Id: if_ntwoc_isa.c,v 1.22 2009/11/27 20:56:28 dsl Exp $
35 #include <sys/cdefs.h>
36 __KERNEL_RCSID(0, "$NetBSD: if_ntwoc_isa.c,v 1.21 2009/05/12 09:10:15 cegger Exp $");
38 #include <sys/param.h>
39 #include <sys/systm.h>
40 #include <sys/device.h>
42 #include <sys/socket.h>
50 #include <dev/isa/isavar.h>
52 #include <dev/ic/hd64570reg.h>
53 #include <dev/ic/hd64570var.h>
55 #include <dev/isa/if_ntwoc_isareg.h>
62 #define NTWO_DPRINTF(x) printf x
64 #define NTWO_DPRINTF(x)
67 #if __NetBSD_Version__ >= 104160000
68 static void ntwoc_isa_config_interrupts(device_t
);
70 #define SCA_BASECLOCK 9830400
73 /* hard core 16k for now */
74 #define NTWOC_WIN_SIZE 0x4000
76 struct ntwoc_isa_softc
{
77 /* Generic device stuff */
78 struct device sc_dev
; /* Common to all devices */
80 /* PCI chipset glue */
81 void *sc_ih
; /* Interrupt handler */
82 isa_chipset_tag_t sc_ic
; /* ISA chipset handle */
84 struct sca_softc sc_sca
; /* the SCA itself */
87 static int ntwoc_isa_probe(device_t
, cfdata_t
, void *);
88 static void ntwoc_isa_attach(device_t
, device_t
, void *);
90 static void ntwoc_isa_clock_callback(void *, int, int);
91 static void ntwoc_isa_dtr_callback(void *, int, int);
92 static int ntwoc_isa_intr(void *);
93 static void ntwoc_isa_get_clock(struct sca_port
*, u_int8_t
, u_int8_t
,
95 static void ntwoc_isa_setup_memory(struct sca_softc
*sc
);
96 static void ntwoc_isa_shutdown(void *sc
);
98 CFATTACH_DECL(ntwoc_isa
, sizeof(struct ntwoc_isa_softc
),
99 ntwoc_isa_probe
, ntwoc_isa_attach
, NULL
, NULL
);
102 * Names for daughter card types. These match the NTWOC_DB_* defines.
104 const char *ntwoc_db_names
[] = {
105 "V.35", "Unknown 0x01", "Test", "Unknown 0x03",
106 "RS232", "Unknown 0x05", "RS422", "None"
109 /* some weird offset XXX */
110 #define SCA_REG(r) (((r) & 0xf) + (((r) & 0xf0) << 6))
113 * functions that read and write to the sca registers
116 ntwoc_isa_sca_write_1(struct sca_softc
*sc
, u_int reg
, u_int8_t val
)
118 bus_space_write_1(sc
->sc_iot
, sc
->scu_sca_ioh
[(reg
& 0xf0) >> 4],
123 ntwoc_isa_sca_write_2(struct sca_softc
*sc
, u_int reg
, u_int16_t val
)
125 bus_space_write_2(sc
->sc_iot
, sc
->scu_sca_ioh
[(reg
& 0xf0) >> 4],
130 ntwoc_isa_sca_read_1(struct sca_softc
*sc
, u_int reg
)
133 bus_space_read_1(sc
->sc_iot
, sc
->scu_sca_ioh
[(reg
& 0xf0) >> 4],
138 ntwoc_isa_sca_read_2(struct sca_softc
*sc
, u_int reg
)
141 bus_space_read_2(sc
->sc_iot
, sc
->scu_sca_ioh
[(reg
& 0xf0) >> 4],
146 * set the correct window/page
149 ntwoc_isa_set_page(struct sca_softc
*sca
, bus_addr_t addr
)
153 /* get old psr value replace old window with new */
154 psr
= bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PSR
);
155 psr
&= ~NTWOC_PG_MSK
;
156 psr
|= ((addr
>> sca
->scu_pageshift
) & NTWOC_PG_MSK
);
157 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PSR
, psr
);
161 * enable the memory window
164 ntwoc_isa_set_on(struct sca_softc
*sca
)
168 /* get old value and add window enable */
169 pcr
= bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
);
170 pcr
|= NTWOC_PCR_MEM_WIN
;
171 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
, pcr
);
175 * turn off memory window
178 ntwoc_isa_set_off(struct sca_softc
*sca
)
182 /* get old value and remove window enable */
183 pcr
= bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
);
184 pcr
&= ~NTWOC_PCR_MEM_WIN
;
185 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
, pcr
);
189 ntwoc_isa_probe(device_t parent
, cfdata_t match
, void *aux
)
191 struct isa_attach_args
*ia
;
192 bus_space_tag_t iot
, memt
;
193 bus_space_handle_t ioh
, memh
, sca_ioh
[16];
195 int gotmem
, gotsca
[16];
198 ia
= (struct isa_attach_args
*)aux
;
204 if (ia
->ia_niomem
< 1)
209 if (ISA_DIRECT_CONFIG(ia
))
212 memset(gotsca
, 0, sizeof(gotsca
));
216 /* disallow wildcarded I/O base */
217 if (ia
->ia_io
[0].ir_addr
== ISA_UNKNOWN_PORT
) {
218 printf("ntwoc_isa_probe: must specify port address\n");
222 if (ia
->ia_irq
[0].ir_irq
== ISA_UNKNOWN_IRQ
) {
223 printf("ntwoc_isa_probe: must specify irq\n");
227 if (ia
->ia_iomem
[0].ir_addr
== ISA_UNKNOWN_IOMEM
) {
228 printf("ntwoc_isa_probe: must specify iomem\n");
232 tmp
= (match
->cf_flags
& NTWOC_FLAGS_NPORT_MASK
) + 1;
233 if (tmp
< 1 || tmp
> 2) {
234 printf("ntwoc_isa_probe: only 1 or 2 ports allowed\n");
238 /* map the isa io addresses */
239 if ((tmp
= bus_space_map(iot
, ia
->ia_io
[0].ir_addr
,
240 NTWOC_SRC_IOPORT_SIZE
, 0, &ioh
))) {
241 printf("ntwoc_isa_probe: mapping port 0x%x sz %d failed: %d\n",
242 ia
->ia_io
[0].ir_addr
, NTWOC_SRC_IOPORT_SIZE
, tmp
);
246 ioport
= ia
->ia_io
[0].ir_addr
+ 0x8000;
247 for (i
= 0; i
< 16; ioport
+= (0x10 << 6), i
++) {
248 /* map the isa io addresses */
249 if ((tmp
= bus_space_map(iot
, ioport
, 16, 0, &sca_ioh
[i
]))) {
251 "ntwoc_isa_probe: mapping sca 0x%x sz %d failed: %d\n",
258 /* map the isa memory addresses */
259 /* XXX we really want the user to select this */
260 if ((tmp
= bus_space_map(ia
->ia_memt
, ia
->ia_iomem
[0].ir_addr
,
261 NTWOC_WIN_SIZE
, 0, &memh
))) {
262 printf("ntwoc_isa_probe: mapping mem 0x%x sz %d failed: %d\n",
263 ia
->ia_iomem
[0].ir_addr
, NTWOC_WIN_SIZE
, tmp
);
268 /* turn off the card */
269 bus_space_write_1(iot
, ioh
, NTWOC_PCR
, 0);
272 * Next, we'll test the Base Address Register to retension of
273 * data... ... seeing if we're *really* talking to an N2.
275 for (i
= 0; i
< 0x100; i
++) {
276 bus_space_write_1(iot
, ioh
, NTWOC_BAR
, i
);
277 (void)bus_space_read_1(iot
, ioh
, NTWOC_PCR
);
278 if (bus_space_read_1(iot
, ioh
, NTWOC_BAR
) != i
) {
279 printf("ntwoc_isa_probe failed (BAR %x, %x)\n", i
, tmp
);
284 /* XXX XXX update the calls to SCA_REG to use our mapping */
287 * Now see if we can see the SCA.
289 bus_space_write_1(iot
, ioh
, NTWOC_PCR
,
290 NTWOC_PCR_SCARUN
| bus_space_read_1(iot
, ioh
, NTWOC_PCR
));
291 bus_space_write_1(iot
, sca_ioh
[0], SCA_REG(SCA_WCRL
), 0);
292 bus_space_write_1(iot
, sca_ioh
[0], SCA_REG(SCA_WCRM
), 0);
293 bus_space_write_1(iot
, sca_ioh
[0], SCA_REG(SCA_WCRH
), 0);
294 bus_space_write_1(iot
, sca_ioh
[0], SCA_REG(SCA_PCR
), 0);
296 bus_space_write_1(iot
, sca_ioh
[0], SCA_REG(SCA_TMC0
), 0);
297 (void)bus_space_read_1(iot
, ioh
, 0);
298 if ((tmp
= bus_space_read_1(iot
, sca_ioh
[0], SCA_REG(SCA_TMC0
))) != 0) {
299 printf("ntwoc_isa_probe: Error reading SCA (TMC0 0, %x)\n",
304 bus_space_write_1(iot
, sca_ioh
[0], SCA_REG(SCA_TMC0
), 0x5A);
305 (void)bus_space_read_1(iot
, ioh
, 0);
307 tmp
= bus_space_read_1(iot
, sca_ioh
[0], SCA_REG(SCA_TMC0
));
309 printf("ntwoc_isa_probe: Error reading SCA (TMC0 5A, %x)\n",
314 bus_space_write_2(iot
, sca_ioh
[0], SCA_REG(SCA_CDAL0
), 0);
315 (void)bus_space_read_1(iot
, ioh
, 0);
316 tmp
= bus_space_read_2(iot
, sca_ioh
[0], SCA_REG(SCA_CDAL0
));
318 printf("ntwoc_isa_probe: Error reading SCA (CDAL0 0, %x)\n",
323 bus_space_write_2(iot
, sca_ioh
[0], SCA_REG(SCA_CDAL0
), 0x55AA);
324 (void)bus_space_read_1(iot
, ioh
, 0);
325 tmp
= bus_space_read_2(iot
, sca_ioh
[0], SCA_REG(SCA_CDAL0
));
327 printf("ntwoc_isa_probe: Error reading SCA (CDAL0 55AA, %x)\n",
333 * I had a weird card that didn't function correctly on a certain
334 * newer MB. I suspect it was the whacky port addresses.
335 * The following correctly failed it.
337 bus_space_write_2(iot
, sca_ioh
[0], SCA_REG(SCA_TCNTL0
), 0x0);
338 (void)bus_space_read_1(iot
, ioh
, 0);
339 tmp
= bus_space_read_2(iot
, sca_ioh
[0], SCA_REG(SCA_TCNTL0
));
341 printf("ntwoc_isa_probe: Error reading SCA (TCNTL0 0, %x)\n",
346 bus_space_write_2(iot
, sca_ioh
[0], SCA_REG(SCA_TCNTL0
), 0x55AA);
347 (void)bus_space_read_1(iot
, ioh
, 0);
348 tmp
= bus_space_read_2(iot
, sca_ioh
[0], SCA_REG(SCA_TCNTL0
));
350 printf("ntwoc_isa_probe: Error reading SCA (TCNTL0 55AA, %x)\n",
356 ia
->ia_io
[0].ir_size
= NTWOC_SRC_IOPORT_SIZE
;
359 ia
->ia_iomem
[0].ir_size
= NTWOC_WIN_SIZE
;
367 /* turn off the card */
368 bus_space_write_1(iot
, ioh
, NTWOC_PCR
, 0);
371 bus_space_unmap(memt
, memh
, NTWOC_WIN_SIZE
);
372 for (i
= 0; i
< 16; i
++) {
374 bus_space_unmap(iot
, sca_ioh
[i
], 16);
376 bus_space_unmap(iot
, ioh
, NTWOC_SRC_IOPORT_SIZE
);
381 * we win! attach the card
384 ntwoc_isa_attach(device_t parent
, device_t self
, void *aux
)
386 struct ntwoc_isa_softc
*sc
;
387 struct isa_attach_args
*ia
;
388 struct sca_softc
*sca
;
390 u_int8_t rdiv
, tdiv
, tmc
;
391 u_int32_t flags
, ioport
;
395 ia
= (struct isa_attach_args
*)aux
;
396 sc
= (struct ntwoc_isa_softc
*)self
;
400 printf(": N2 Serial Interface\n");
401 flags
= device_cfdata(&sc
->sc_dev
)->cf_flags
;
403 sc
->sc_ic
= ia
->ia_ic
;
404 sca
->sc_parent
= &sc
->sc_dev
;
405 sca
->sc_numports
= (flags
& NTWOC_FLAGS_NPORT_MASK
) + 1;
408 sca
->sc_dtr_callback
= ntwoc_isa_dtr_callback
;
409 sca
->sc_clock_callback
= ntwoc_isa_clock_callback
;
410 sca
->sc_read_1
= ntwoc_isa_sca_read_1
;
411 sca
->sc_read_2
= ntwoc_isa_sca_read_2
;
412 sca
->sc_write_1
= ntwoc_isa_sca_write_1
;
413 sca
->sc_write_2
= ntwoc_isa_sca_write_2
;
414 sca
->scu_set_page
= ntwoc_isa_set_page
;
415 sca
->scu_page_on
= ntwoc_isa_set_on
;
416 sca
->scu_page_off
= ntwoc_isa_set_off
;
419 sca
->sc_iot
= ia
->ia_iot
;
420 if ((rv
= bus_space_map(ia
->ia_iot
, ia
->ia_io
[0].ir_addr
,
421 NTWOC_SRC_IOPORT_SIZE
, 0, &sca
->sc_ioh
))) {
422 aprint_error_dev(&sc
->sc_dev
, "can't map io 0x%x sz %d, %d\n",
423 ia
->ia_io
[0].ir_addr
,
424 NTWOC_SRC_IOPORT_SIZE
, rv
);
428 /* support weird mapping (they used this to avoid 10-bit aliasing) */
429 ioport
= ia
->ia_io
[0].ir_addr
+ 0x8000;
430 for (i
= 0; i
< 16; ioport
+= (0x10 << 6), i
++) {
431 /* map the isa io addresses */
432 if ((tmp
= bus_space_map(ia
->ia_iot
, ioport
, 16, 0,
433 &sca
->scu_sca_ioh
[i
]))) {
434 aprint_error_dev(&sc
->sc_dev
, "mapping sca 0x%x sz %d failed: %d\n",
440 /* map the isa memory */
441 sca
->scu_memt
= ia
->ia_memt
;
442 sca
->scu_pagesize
= 0x4000; /* force 16k for now */
443 if (sca
->scu_pagesize
< 0x8000) {
444 /* round down to 16k */
445 sca
->scu_pagesize
= 0x4000;
446 sca
->scu_pageshift
= 14;
447 tmp
= NTWOC_PSR_WIN_16K
;
448 } else if (sca
->scu_pagesize
< 0x10000) {
449 /* round down to 32k */
450 sca
->scu_pagesize
= 0x8000;
451 sca
->scu_pageshift
= 15;
452 tmp
= NTWOC_PSR_WIN_32K
;
453 } else if (sca
->scu_pagesize
< 0x20000) {
454 /* round down to 64k */
455 sca
->scu_pagesize
= 0x10000;
456 sca
->scu_pageshift
= 16;
457 tmp
= NTWOC_PSR_WIN_64K
;
459 sca
->scu_pagesize
= 0x20000;
460 sca
->scu_pageshift
= 17;
461 tmp
= NTWOC_PSR_WIN_128K
;
463 sca
->scu_pagemask
= sca
->scu_pagesize
- 1;
464 if ((rv
= bus_space_map(ia
->ia_memt
, ia
->ia_iomem
[0].ir_addr
,
465 sca
->scu_pagesize
, 0, &sca
->scu_memh
))) {
466 aprint_error_dev(&sc
->sc_dev
, "can't map mem 0x%x sz %ld, %d\n",
467 ia
->ia_iomem
[0].ir_addr
,
468 (u_long
)sca
->scu_pagesize
, rv
);
472 /* turn the card on!! */
473 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
,
474 bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
)
477 /* set the window size to 16k */
478 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PSR
, tmp
);
481 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_MCR
,
482 NTWOC_MCR_DTR0
| NTWOC_MCR_DTR1
| NTWOC_MCR_TE0
| NTWOC_MCR_TE1
);
485 /* allow for address above 1M and 16 bit i/o */
487 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
,
488 bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
)
489 | NTWOC_PCR_EN_VPM
| NTWOC_PCR_ISA16
);
491 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
,
492 bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
)
495 /* program the card with the io address */
496 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
,
497 ((ia
->ia_iomem
[0].ir_addr
>> 16) & NTWOC_PCR_16M_SEL
)
499 (bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PCR
)
500 & ~NTWOC_PCR_16M_SEL
));
501 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_BAR
,
502 (ia
->ia_iomem
[0].ir_addr
>> 12));
504 /* enable the memory window */
505 ntwoc_isa_set_on(sca
);
508 * write a magic value into each possible page of memory
509 * incrementing by our window size
512 for (i
= 0; i
<= NTWOC_PSR_PG_SEL
; addr
+= sca
->scu_pagesize
, i
++) {
513 /* select the page */
514 ntwoc_isa_set_page(sca
, addr
);
515 bus_space_write_2(sca
->scu_memt
, sca
->scu_memh
, 0, 0xAA55);
519 * go back through pages and verify that value is different
520 * after writing to previous page
523 for (i
= 0; i
<= NTWOC_PSR_PG_SEL
; addr
+= sca
->scu_pagesize
, i
++) {
524 ntwoc_isa_set_page(sca
, addr
);
526 tmp
= bus_space_read_2(sca
->scu_memt
, sca
->scu_memh
, 0);
530 /* write a different value into this page now */
531 bus_space_write_2(sca
->scu_memt
, sca
->scu_memh
, 0, i
);
533 sca
->scu_npages
= pgs
= i
; /* final count of 16K pages */
535 /* erase the pages */
537 for (i
= 0; i
<= pgs
; addr
+= sca
->scu_pagesize
, i
++) {
538 ntwoc_isa_set_page(sca
, addr
);
539 bus_space_set_region_1(sca
->scu_memt
, sca
->scu_memh
, 0, 0,
544 printf("%s: sca port 0x%x-0x%x dpram %ldk %d serial port%s\n",
545 device_xname(&sc
->sc_dev
), ia
->ia_io
[0].ir_addr
| 0x8000,
546 (ia
->ia_io
[0].ir_addr
| 0x8000) + NTWOC_SRC_ASIC_SIZE
- 1,
547 pgs
* (sca
->scu_pagesize
/ 1024), sca
->sc_numports
,
548 (sca
->sc_numports
> 1 ? "s" : ""));
550 printf("%s: dpram %ldk %d serial port%s\n",
551 device_xname(&sc
->sc_dev
), (u_long
)pgs
* (sca
->scu_pagesize
/ 1024),
552 sca
->sc_numports
, (sca
->sc_numports
> 1 ? "s" : ""));
555 /* disable the memory window */
556 ntwoc_isa_set_off(sca
);
558 /* enabled sca DMA */
559 bus_space_write_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PSR
,
560 bus_space_read_1(sca
->sc_iot
, sca
->sc_ioh
, NTWOC_PSR
)
561 | NTWOC_PSR_EN_SCA_DMA
);
563 /* now establish our irq -- perhaps sanity check the value */
564 sc
->sc_ih
= isa_intr_establish(ia
->ia_ic
, ia
->ia_irq
[0].ir_irq
,
565 IST_EDGE
, IPL_NET
, ntwoc_isa_intr
, sc
);
566 if (sc
->sc_ih
== NULL
) {
567 aprint_error_dev(&sc
->sc_dev
, "can't establish interrupt\n");
571 /* make sure we have 2 pages for each port */
572 if (pgs
< 2 * sca
->sc_numports
) {
573 printf("%s: %d less than required pages of memory of %d\n",
574 device_xname(&sc
->sc_dev
), pgs
, 2 * sca
->sc_numports
);
578 /* sca_get_base_clock(sca); */
581 * get clock information from user
583 rdiv
= (flags
& NTWOC_FLAGS_RXDIV_MASK
) >> NTWOC_FLAGS_RXDIV_SHIFT
;
585 panic("bad rx divisor in flags");
587 tdiv
= (flags
& NTWOC_FLAGS_TXDIV_MASK
) >> NTWOC_FLAGS_TXDIV_SHIFT
;
589 panic("bad tx divisor in flags");
590 tmc
= (flags
& NTWOC_FLAGS_TMC_MASK
) >> NTWOC_FLAGS_TMC_SHIFT
;
592 ntwoc_isa_get_clock(&sca
->sc_ports
[0],
593 flags
& NTWOC_FLAGS_CLK0_MASK
, tmc
, rdiv
, tdiv
);
594 if (sca
->sc_numports
> 1)
595 ntwoc_isa_get_clock(&sca
->sc_ports
[1],
596 (flags
& NTWOC_FLAGS_CLK1_MASK
) >> NTWOC_FLAGS_CLK1_SHIFT
,
599 ntwoc_isa_setup_memory(sca
);
603 /* attach configured ports */
604 sca_port_attach(sca
, 0);
605 if (sca
->sc_numports
== 2)
606 sca_port_attach(sca
, 1);
609 * Add shutdown hook so that DMA is disabled prior to reboot. Not
610 * doing do could allow DMA to corrupt kernel memory during the
611 * reboot before the driver initializes.
613 shutdownhook_establish(ntwoc_isa_shutdown
, sc
);
615 #if __NetBSD_Version__ >= 104160000
617 * defer getting the base clock until interrupts are enabled
618 * (and thus we have microtime())
620 config_interrupts(self
, ntwoc_isa_config_interrupts
);
622 /* no callback pre 1.4-mumble */
623 sca
->sc_baseclock
= SCA_BASECLOCK
;
624 sca_print_clock_info(&sc
->sc_sca
);
629 * extract the clock information for a port from the flags field
632 ntwoc_isa_get_clock(struct sca_port
*scp
, u_int8_t flags
, u_int8_t tmc
,
633 u_int8_t rdiv
, u_int8_t tdiv
)
636 (flags
& NTWOC_FLAGS_ECLOCK_MASK
) >> NTWOC_FLAGS_ECLOCK_SHIFT
;
642 switch ((flags
& NTWOC_FLAGS_RXS_MASK
) >> NTWOC_FLAGS_RXS_SHIFT
) {
643 case NTWOC_FLAGS_RXS_LINE
:
646 case NTWOC_FLAGS_RXS_LINE_SN
:
647 scp
->sp_rxs
|= SCA_RXS_CLK_LINE_SN
;
649 case NTWOC_FLAGS_RXS_INTERNAL
:
650 scp
->sp_rxs
|= SCA_RXS_CLK_INTERNAL
;
652 case NTWOC_FLAGS_RXS_ADPLL_OUT
:
653 scp
->sp_rxs
|= SCA_RXS_CLK_ADPLL_OUT
;
655 case NTWOC_FLAGS_RXS_ADPLL_IN
:
656 scp
->sp_rxs
|= SCA_RXS_CLK_ADPLL_IN
;
659 panic("bad rx source in flags");
663 switch ((flags
& NTWOC_FLAGS_TXS_MASK
) >> NTWOC_FLAGS_TXS_SHIFT
) {
664 case NTWOC_FLAGS_TXS_LINE
:
667 case NTWOC_FLAGS_TXS_INTERNAL
:
668 scp
->sp_txs
|= SCA_TXS_CLK_INTERNAL
;
670 case NTWOC_FLAGS_TXS_RXCLOCK
:
671 scp
->sp_txs
|= SCA_TXS_CLK_RXCLK
;
674 panic("bad rx source in flags");
680 ntwoc_isa_intr(void *arg
)
682 struct ntwoc_isa_softc
*sc
= (struct ntwoc_isa_softc
*)arg
;
684 return sca_hardintr(&sc
->sc_sca
);
688 * shut down interrupts and DMA, so we don't trash the kernel on warm
689 * boot. Also, lower DTR on each port and disable card interrupts.
692 ntwoc_isa_shutdown(void *aux
)
694 struct ntwoc_isa_softc
*sc
= aux
;
698 * shut down the SCA ports
700 sca_shutdown(&sc
->sc_sca
);
703 * lower DTR on both ports
705 mcr
= bus_space_read_1(sc
->sc_sca
.sc_iot
, sc
->sc_sca
.sc_ioh
, NTWOC_MCR
);
706 mcr
|= (NTWOC_MCR_DTR0
| NTWOC_MCR_DTR1
);
707 bus_space_write_1(sc
->sc_sca
.sc_iot
, sc
->sc_sca
.sc_ioh
, NTWOC_MCR
, mcr
);
709 /* turn off the card */
710 bus_space_write_1(sc
->sc_sca
.sc_iot
, sc
->sc_sca
.sc_ioh
, NTWOC_PCR
, 0);
714 ntwoc_isa_dtr_callback(void *aux
, int port
, int state
)
716 struct ntwoc_isa_softc
*sc
= aux
;
719 mcr
= bus_space_read_1(sc
->sc_sca
.sc_iot
, sc
->sc_sca
.sc_ioh
, NTWOC_MCR
);
721 NTWO_DPRINTF(("port == %d, state == %d, old mcr: 0x%02x\n",
726 mcr
|= NTWOC_MCR_DTR0
;
728 mcr
&= ~NTWOC_MCR_DTR0
;
731 mcr
|= NTWOC_MCR_DTR1
;
733 mcr
&= ~NTWOC_MCR_DTR1
;
736 NTWO_DPRINTF(("new mcr: 0x%02x\n", mcr
));
738 bus_space_write_1(sc
->sc_sca
.sc_iot
, sc
->sc_sca
.sc_ioh
, NTWOC_MCR
, mcr
);
742 ntwoc_isa_clock_callback(void *aux
, int port
, int enable
)
744 struct ntwoc_isa_softc
*sc
= aux
;
747 mcr
= bus_space_read_1(sc
->sc_sca
.sc_iot
, sc
->sc_sca
.sc_ioh
, NTWOC_MCR
);
749 NTWO_DPRINTF(("clock: port == %d, enable == %d, old mcr: 0x%02x\n",
754 mcr
&= ~NTWOC_MCR_ETC0
;
756 mcr
|= NTWOC_MCR_ETC0
;
759 mcr
&= ~NTWOC_MCR_ETC1
;
761 mcr
|= NTWOC_MCR_ETC1
;
764 NTWO_DPRINTF(("clock: new mcr: 0x%02x\n", mcr
));
766 bus_space_write_1(sc
->sc_sca
.sc_iot
, sc
->sc_sca
.sc_ioh
, NTWOC_MCR
, mcr
);
770 ntwoc_isa_setup_memory(struct sca_softc
*sc
)
772 struct sca_port
*scp
;
775 /* allocate enough descriptors for a full page */
777 sc
->sc_ports
[0].sp_ntxdesc
= (sc
->scu_pagesize
/ SCA_BSIZE
) - 1;
778 sc
->sc_ports
[0].sp_nrxdesc
= (sc
->scu_pagesize
/ SCA_BSIZE
) - 1;
779 if (sc
->sc_numports
== 2) {
780 sc
->sc_ports
[1].sp_ntxdesc
= sc
->sc_ports
[0].sp_ntxdesc
;
781 sc
->sc_ports
[1].sp_nrxdesc
= sc
->sc_ports
[0].sp_nrxdesc
;
785 for (i
= 0; i
< sc
->sc_numports
; i
++) {
786 scp
= &sc
->sc_ports
[i
];
787 scp
->sp_txdesc_p
= (bus_addr_t
)(j
* sc
->scu_pagesize
);
788 scp
->sp_txdesc
= (void *)scp
->sp_txdesc_p
;
789 scp
->sp_txbuf_p
= scp
->sp_txdesc_p
;
790 scp
->sp_txbuf_p
+= SCA_BSIZE
;
791 scp
->sp_txbuf
= (void *)scp
->sp_txbuf_p
;
794 scp
->sp_rxdesc_p
= (bus_addr_t
)(j
* sc
->scu_pagesize
);
795 scp
->sp_rxdesc
= (void *)scp
->sp_txdesc_p
;
796 scp
->sp_rxbuf_p
= scp
->sp_rxdesc_p
;
797 scp
->sp_rxbuf_p
+= SCA_BSIZE
;
798 scp
->sp_rxbuf
= (void *)scp
->sp_rxbuf_p
;
803 #if __NetBSD_Version__ >= 104160000
805 * get the base clock frequency
808 ntwoc_isa_config_interrupts(device_t self
)
810 struct ntwoc_isa_softc
*sc
;
813 sca_get_base_clock(&sc
->sc_sca
);
814 sca_print_clock_info(&sc
->sc_sca
);