Annotation of src/sys/dev/isa/if_cs_isa.c, Revision 1.20.4.1
1.20.4.1! yamt 1: /* $NetBSD: if_cs_isa.c,v 1.20 2008/04/08 20:08:49 cegger Exp $ */
1.1 thorpej 2:
3: /*
4: * Copyright 1997
5: * Digital Equipment Corporation. All rights reserved.
6: *
7: * This software is furnished under license and may be used and
8: * copied only in accordance with the following terms and conditions.
9: * Subject to these conditions, you may download, copy, install,
10: * use, modify and distribute this software in source and/or binary
11: * form. No title or ownership is transferred hereby.
12: *
13: * 1) Any source code used, modified or distributed must reproduce
14: * and retain this copyright notice and list of conditions as
15: * they appear in the source file.
16: *
17: * 2) No right is granted to use any trade name, trademark, or logo of
18: * Digital Equipment Corporation. Neither the "Digital Equipment
19: * Corporation" name nor any trademark or logo of Digital Equipment
20: * Corporation may be used to endorse or promote products derived
21: * from this software without the prior written permission of
22: * Digital Equipment Corporation.
23: *
24: * 3) This software is provided "AS-IS" and any express or implied
25: * warranties, including but not limited to, any implied warranties
26: * of merchantability, fitness for a particular purpose, or
27: * non-infringement are disclaimed. In no event shall DIGITAL be
28: * liable for any damages whatsoever, and in particular, DIGITAL
29: * shall not be liable for special, indirect, consequential, or
30: * incidental damages or damages for lost profits, loss of
31: * revenue or loss of use, whether such damages arise in contract,
32: * negligence, tort, under statute, in equity, at law or otherwise,
33: * even if advised of the possibility of such damage.
34: */
1.4 lukem 35:
36: #include <sys/cdefs.h>
1.20.4.1! yamt 37: __KERNEL_RCSID(0, "$NetBSD: if_cs_isa.c,v 1.20 2008/04/08 20:08:49 cegger Exp $");
1.1 thorpej 38:
39: #include <sys/param.h>
40: #include <sys/systm.h>
41: #include <sys/socket.h>
42: #include <sys/device.h>
1.3 mycroft 43:
44: #include "rnd.h"
45: #if NRND > 0
46: #include <sys/rnd.h>
47: #endif
1.1 thorpej 48:
49: #include <net/if.h>
50: #include <net/if_ether.h>
51: #include <net/if_media.h>
52:
1.19 ad 53: #include <sys/bus.h>
54: #include <sys/intr.h>
1.1 thorpej 55:
56: #include <dev/isa/isareg.h>
57: #include <dev/isa/isavar.h>
58: #include <dev/isa/isadmavar.h>
59:
1.5 yamt 60: #include <dev/ic/cs89x0reg.h>
61: #include <dev/ic/cs89x0var.h>
62: #include <dev/isa/cs89x0isavar.h>
1.1 thorpej 63:
1.20.4.1! yamt 64: int cs_isa_probe(device_t, cfdata_t, void *);
! 65: void cs_isa_attach(device_t, device_t, void *);
1.1 thorpej 66:
1.10 thorpej 67: CFATTACH_DECL(cs_isa, sizeof(struct cs_softc),
68: cs_isa_probe, cs_isa_attach, NULL, NULL);
1.1 thorpej 69:
1.15 perry 70: int
1.20.4.1! yamt 71: cs_isa_probe(device_t parent, cfdata_t cf, void *aux)
1.1 thorpej 72: {
73: struct isa_attach_args *ia = aux;
74: bus_space_tag_t iot = ia->ia_iot;
75: bus_space_tag_t memt = ia->ia_memt;
76: bus_space_handle_t ioh, memh;
1.7 augustss 77: struct cs_softc sc;
1.1 thorpej 78: int rv = 0, have_io = 0, have_mem = 0;
79: u_int16_t isa_cfg, isa_membase;
1.12 mycroft 80: int maddr, irq;
1.6 thorpej 81:
82: if (ia->ia_nio < 1)
83: return (0);
84: if (ia->ia_nirq < 1)
85: return (0);
86:
87: if (ISA_DIRECT_CONFIG(ia))
88: return (0);
1.1 thorpej 89:
90: /*
91: * Disallow wildcarded I/O base.
92: */
1.13 drochner 93: if (ia->ia_io[0].ir_addr == ISA_UNKNOWN_PORT)
1.1 thorpej 94: return (0);
95:
1.6 thorpej 96: if (ia->ia_niomem > 0)
97: maddr = ia->ia_iomem[0].ir_addr;
98: else
1.13 drochner 99: maddr = ISA_UNKNOWN_IOMEM;
1.6 thorpej 100:
1.1 thorpej 101: /*
102: * Map the I/O space.
103: */
1.6 thorpej 104: if (bus_space_map(ia->ia_iot, ia->ia_io[0].ir_addr, CS8900_IOSIZE,
105: 0, &ioh))
1.1 thorpej 106: goto out;
107: have_io = 1;
108:
1.7 augustss 109: memset(&sc, 0, sizeof sc);
110: sc.sc_iot = iot;
111: sc.sc_ioh = ioh;
1.1 thorpej 112: /* Verify that it's a Crystal product. */
1.7 augustss 113: if (CS_READ_PACKET_PAGE_IO(&sc, PKTPG_EISA_NUM) !=
1.1 thorpej 114: EISA_NUM_CRYSTAL)
115: goto out;
116:
117: /*
118: * Verify that it's a supported chip.
119: */
1.7 augustss 120: switch (CS_READ_PACKET_PAGE_IO(&sc, PKTPG_PRODUCT_ID) &
1.1 thorpej 121: PROD_ID_MASK) {
122: case PROD_ID_CS8900:
123: #ifdef notyet
124: case PROD_ID_CS8920:
125: case PROD_ID_CS8920M:
126: #endif
1.12 mycroft 127: break;
128: default:
129: /* invalid product ID */
130: goto out;
1.1 thorpej 131: }
132:
133: /*
134: * If the IRQ or memory address were not specified, read the
135: * ISA_CFG EEPROM location.
136: */
1.13 drochner 137: if (maddr == ISA_UNKNOWN_IOMEM ||
138: ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) {
1.7 augustss 139: if (cs_verify_eeprom(&sc) == CS_ERROR) {
1.1 thorpej 140: printf("cs_isa_probe: EEPROM bad or missing\n");
141: goto out;
142: }
1.7 augustss 143: if (cs_read_eeprom(&sc, EEPROM_ISA_CFG, &isa_cfg)
1.1 thorpej 144: == CS_ERROR) {
145: printf("cs_isa_probe: unable to read ISA_CFG\n");
146: goto out;
147: }
148: }
149:
150: /*
151: * If the IRQ wasn't specified, get it from the EEPROM.
152: */
1.13 drochner 153: if (ia->ia_irq[0].ir_irq == ISA_UNKNOWN_IRQ) {
1.1 thorpej 154: irq = isa_cfg & ISA_CFG_IRQ_MASK;
155: if (irq == 3)
156: irq = 5;
157: else
158: irq += 10;
1.6 thorpej 159: } else
160: irq = ia->ia_irq[0].ir_irq;
1.1 thorpej 161:
162: /*
163: * If the memory address wasn't specified, get it from the EEPROM.
164: */
1.13 drochner 165: if (maddr == ISA_UNKNOWN_IOMEM) {
1.1 thorpej 166: if ((isa_cfg & ISA_CFG_MEM_MODE) == 0) {
167: /* EEPROM says don't use memory mode. */
168: goto out;
169: }
1.7 augustss 170: if (cs_read_eeprom(&sc, EEPROM_MEM_BASE, &isa_membase)
1.1 thorpej 171: == CS_ERROR) {
172: printf("cs_isa_probe: unable to read MEM_BASE\n");
173: goto out;
174: }
175:
176: isa_membase &= MEM_BASE_MASK;
177: maddr = (int)isa_membase << 8;
178: }
179:
180: /*
181: * We now have a valid mem address; attempt to map it.
182: */
183: if (bus_space_map(ia->ia_memt, maddr, CS8900_MEMSIZE, 0, &memh)) {
184: /* Can't map it; fall back on i/o-only mode. */
185: printf("cs_isa_probe: unable to map memory space\n");
1.13 drochner 186: maddr = ISA_UNKNOWN_IOMEM;
1.1 thorpej 187: } else
188: have_mem = 1;
189:
1.12 mycroft 190: ia->ia_nio = 1;
191: ia->ia_io[0].ir_size = CS8900_IOSIZE;
192:
1.13 drochner 193: if (maddr == ISA_UNKNOWN_IOMEM)
1.12 mycroft 194: ia->ia_niomem = 0;
195: else {
196: ia->ia_niomem = 1;
197: ia->ia_iomem[0].ir_addr = maddr;
198: ia->ia_iomem[0].ir_size = CS8900_MEMSIZE;
199: }
200:
201: ia->ia_nirq = 1;
202: ia->ia_irq[0].ir_irq = irq;
203:
204: rv = 1;
205:
1.1 thorpej 206: out:
207: if (have_io)
208: bus_space_unmap(iot, ioh, CS8900_IOSIZE);
209: if (have_mem)
210: bus_space_unmap(memt, memh, CS8900_MEMSIZE);
211:
212: return (rv);
213: }
214:
1.15 perry 215: void
1.20.4.1! yamt 216: cs_isa_attach(device_t parent, device_t self, void *aux)
1.1 thorpej 217: {
218: struct cs_softc *sc = (struct cs_softc *) self;
1.5 yamt 219: struct cs_softc_isa *isc = (void *) self;
1.1 thorpej 220: struct isa_attach_args *ia = aux;
221:
1.5 yamt 222: isc->sc_ic = ia->ia_ic;
1.1 thorpej 223: sc->sc_iot = ia->ia_iot;
224: sc->sc_memt = ia->ia_memt;
225:
1.6 thorpej 226: if (ia->ia_ndrq > 0)
227: isc->sc_drq = ia->ia_drq[0].ir_drq;
228: else
229: isc->sc_drq = -1;
230:
231: sc->sc_irq = ia->ia_irq[0].ir_irq;
1.1 thorpej 232:
233: printf("\n");
234:
235: /*
236: * Map the device.
237: */
1.6 thorpej 238: if (bus_space_map(sc->sc_iot, ia->ia_io[0].ir_addr, CS8900_IOSIZE,
1.1 thorpej 239: 0, &sc->sc_ioh)) {
1.20 cegger 240: aprint_error_dev(&sc->sc_dev, "unable to map i/o space\n");
1.1 thorpej 241: return;
242: }
243:
244: /*
245: * Validate IRQ.
246: */
247: if (CS8900_IRQ_ISVALID(sc->sc_irq) == 0) {
1.20 cegger 248: aprint_error_dev(&sc->sc_dev, "invalid IRQ %d\n", sc->sc_irq);
1.1 thorpej 249: return;
250: }
251:
252: /*
253: * Map the memory space if it was specified. If we can do this,
254: * we set ourselves up to use memory mode forever. Otherwise,
255: * we fall back on I/O mode.
256: */
1.13 drochner 257: if (ia->ia_iomem[0].ir_addr != ISA_UNKNOWN_IOMEM &&
1.6 thorpej 258: ia->ia_iomem[0].ir_size == CS8900_MEMSIZE &&
259: CS8900_MEMBASE_ISVALID(ia->ia_iomem[0].ir_addr)) {
260: if (bus_space_map(sc->sc_memt, ia->ia_iomem[0].ir_addr,
261: CS8900_MEMSIZE, 0, &sc->sc_memh)) {
1.20 cegger 262: aprint_error_dev(&sc->sc_dev, "unable to map memory space\n");
1.1 thorpej 263: } else {
264: sc->sc_cfgflags |= CFGFLG_MEM_MODE;
1.6 thorpej 265: sc->sc_pktpgaddr = ia->ia_iomem[0].ir_addr;
1.1 thorpej 266: }
267: }
268:
269: sc->sc_ih = isa_intr_establish(ia->ia_ic, sc->sc_irq, IST_EDGE,
270: IPL_NET, cs_intr, sc);
271: if (sc->sc_ih == NULL) {
1.20 cegger 272: aprint_error_dev(&sc->sc_dev, "unable to establish interrupt\n");
1.1 thorpej 273: return;
274: }
1.5 yamt 275:
276: sc->sc_dma_chipinit = cs_isa_dma_chipinit;
277: sc->sc_dma_attach = cs_isa_dma_attach;
278: sc->sc_dma_process_rx = cs_process_rx_dma;
1.1 thorpej 279:
280: cs_attach(sc, NULL, NULL, 0, 0);
281: }
CVSweb <webmaster@jp.NetBSD.org>