Rename printf -> kprintf in sys/ and add some defines where necessary
[dragonfly.git] / sys / dev / netif / sr / if_sr_isa.c
1 /*
2  * Copyright (c) 1996 - 2001 John Hay.
3  * Copyright (c) 1996 SDL Communications, Inc.
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the author nor the names of any co-contributors
15  *    may be used to endorse or promote products derived from this software
16  *    without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  *
30  * $FreeBSD: src/sys/dev/sr/if_sr_isa.c,v 1.46.2.1 2002/06/17 15:10:58 jhay Exp $
31  * $DragonFly: src/sys/dev/netif/sr/if_sr_isa.c,v 1.6 2006/12/22 23:26:22 swildner Exp $
32  */
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/conf.h>           /* cdevsw stuff */
37 #include <sys/kernel.h>         /* SYSINIT stuff */
38 #include <sys/uio.h>            /* SYSINIT stuff */
39 #include <sys/malloc.h>         /* malloc region definitions */
40 #include <sys/module.h>
41 #include <sys/bus.h>
42 #include <sys/rman.h>
43 #include <sys/time.h>
44
45 #include <bus/isa/isavar.h>
46 #include "isa_if.h"
47
48 #include "../ic_layer/hd64570.h"
49 #include "if_srregs.h"
50
51 /*
52  * List of valid interrupt numbers for the N2 ISA card.
53  */
54 static int sr_irqtable[16] = {
55         0,      /*  0 */
56         0,      /*  1 */
57         0,      /*  2 */
58         1,      /*  3 */
59         1,      /*  4 */
60         1,      /*  5 */
61         0,      /*  6 */
62         1,      /*  7 */
63         0,      /*  8 */
64         0,      /*  9 */
65         1,      /* 10 */
66         1,      /* 11 */
67         1,      /* 12 */
68         0,      /* 13 */
69         0,      /* 14 */
70         1       /* 15 */
71 };
72
73 static int sr_isa_probe (device_t);
74 static int sr_isa_attach (device_t);
75
76 static struct isa_pnp_id sr_ids[] = {
77         {0,             NULL}
78 };
79
80 static device_method_t sr_methods[] = {
81         DEVMETHOD(device_probe,         sr_isa_probe),
82         DEVMETHOD(device_attach,        sr_isa_attach),
83         DEVMETHOD(device_detach,        sr_detach),
84         { 0, 0 }
85 };
86
87 static driver_t sr_isa_driver = {
88         "sr",
89         sr_methods,
90         sizeof (struct sr_hardc)
91 };
92
93 DRIVER_MODULE(if_sr, isa, sr_isa_driver, sr_devclass, 0, 0);
94
95 static u_int    src_get8_io(u_int base, u_int off);
96 static u_int    src_get16_io(u_int base, u_int off);
97 static void     src_put8_io(u_int base, u_int off, u_int val);
98 static void     src_put16_io(u_int base, u_int off, u_int val);
99 static u_int    src_dpram_size(device_t device);
100
101 /*
102  * Probe for an ISA card. If it is there, size its memory. Then get the
103  * rest of its information and fill it in.
104  */
105 static int
106 sr_isa_probe (device_t device)
107 {
108         struct sr_hardc *hc;
109         int error;
110         u_int32_t flags;
111         u_int i, tmp;
112         u_short port;
113         u_long irq, junk, membase, memsize, port_start, port_count;
114         sca_regs *sca = 0;
115
116         error = ISA_PNP_PROBE(device_get_parent(device), device, sr_ids);
117         if (error == ENXIO || error == 0)
118                 return (error);
119
120         hc = device_get_softc(device);
121
122         if (sr_allocate_ioport(device, 0, SRC_IO_SIZ)) {
123                 return (ENXIO);
124         }
125
126         /*
127          * Now see if the card is realy there.
128          */
129         error = bus_get_resource(device, SYS_RES_IOPORT, 0, &port_start,
130             &port_count);
131         port = port_start;
132
133         hc->cardtype = SR_CRD_N2;
134         hc->cunit = device_get_unit(device);
135         hc->iobase = port_start;
136         /*
137          * We have to fill these in early because the SRC_PUT* and SRC_GET*
138          * macros use them.
139          */
140         hc->src_get8 = src_get8_io;
141         hc->src_get16 = src_get16_io;
142         hc->src_put8 = src_put8_io;
143         hc->src_put16 = src_put16_io;
144
145         hc->sca = 0;
146         hc->numports = NCHAN;   /* assumed # of channels on the card */
147
148         flags = device_get_flags(device);
149         if (flags & SR_FLAGS_NCHAN_MSK)
150                 hc->numports = flags & SR_FLAGS_NCHAN_MSK;
151
152         outb(port + SR_PCR, 0); /* turn off the card */
153
154         /*
155          * Next, we'll test the Base Address Register to retension of
156          * data... ... seeing if we're *really* talking to an N2.
157          */
158         for (i = 0; i < 0x100; i++) {
159                 outb(port + SR_BAR, i);
160                 inb(port + SR_PCR);
161                 tmp = inb(port + SR_BAR);
162                 if (tmp != i) {
163                         kprintf("sr%d: probe failed BAR %x, %x.\n",
164                                hc->cunit, i, tmp);
165                         goto errexit;
166                 }
167         }
168
169         /*
170          * Now see if we can see the SCA.
171          */
172         outb(port + SR_PCR, SR_PCR_SCARUN | inb(port + SR_PCR));
173         SRC_PUT8(port, sca->wcrl, 0);
174         SRC_PUT8(port, sca->wcrm, 0);
175         SRC_PUT8(port, sca->wcrh, 0);
176         SRC_PUT8(port, sca->pcr, 0);
177         SRC_PUT8(port, sca->msci[0].tmc, 0);
178         inb(port);
179
180         tmp = SRC_GET8(port, sca->msci[0].tmc);
181         if (tmp != 0) {
182                 kprintf("sr%d: Error reading SCA 0, %x\n", hc->cunit, tmp);
183                 goto errexit;
184         }
185         SRC_PUT8(port, sca->msci[0].tmc, 0x5A);
186         inb(port);
187
188         tmp = SRC_GET8(port, sca->msci[0].tmc);
189         if (tmp != 0x5A) {
190                 kprintf("sr%d: Error reading SCA 0x5A, %x\n", hc->cunit, tmp);
191                 goto errexit;
192         }
193         SRC_PUT16(port, sca->dmac[0].cda, 0);
194         inb(port);
195
196         tmp = SRC_GET16(port, sca->dmac[0].cda);
197         if (tmp != 0) {
198                 kprintf("sr%d: Error reading SCA 0, %x\n", hc->cunit, tmp);
199                 goto errexit;
200         }
201         SRC_PUT16(port, sca->dmac[0].cda, 0x55AA);
202         inb(port);
203
204         tmp = SRC_GET16(port, sca->dmac[0].cda);
205         if (tmp != 0x55AA) {
206                 kprintf("sr%d: Error reading SCA 0x55AA, %x\n",
207                        hc->cunit, tmp);
208                 goto errexit;
209         }
210
211         membase = bus_get_resource_start(device, SYS_RES_MEMORY, 0);
212         memsize = SRC_WIN_SIZ;
213         if (bus_set_resource(device, SYS_RES_MEMORY, 0, membase, memsize))
214                 goto errexit;
215
216         if (sr_allocate_memory(device, 0, SRC_WIN_SIZ))
217                 goto errexit;
218
219         if (src_dpram_size(device) < 4)
220                 goto errexit;
221
222         if (sr_allocate_irq(device, 0, 1))
223                 goto errexit;
224
225         if (bus_get_resource(device, SYS_RES_IRQ, 0, &irq, &junk)) {
226                 goto errexit;
227         }
228         /*
229          * Do a little sanity check.
230          */
231         if (sr_irqtable[irq] == 0)
232                 kprintf("sr%d: Warning: illegal interrupt %ld chosen.\n",
233                        hc->cunit, irq);
234
235         /*
236          * Bogus card configuration
237          */
238         if ((hc->numports > NCHAN)      /* only 2 ports/card */
239             ||(hc->memsize > (512 * 1024)))     /* no more than 256K */
240                 goto errexit;
241
242         sr_deallocate_resources(device);
243         return (0);
244
245 errexit:
246         sr_deallocate_resources(device);
247         return (ENXIO);
248 }
249
250 /*
251  * srattach_isa and srattach_pci allocate memory for hardc, softc and
252  * data buffers. It also does any initialization that is bus specific.
253  * At the end they call the common srattach() function.
254  */
255 static int
256 sr_isa_attach (device_t device)
257 {
258         u_char mar;
259         u_int32_t flags;
260         struct sr_hardc *hc;
261
262         hc = device_get_softc(device);
263         bzero(hc, sizeof(struct sr_hardc));
264
265         if (sr_allocate_ioport(device, 0, SRC_IO_SIZ))
266                 goto errexit;
267         if (sr_allocate_memory(device, 0, SRC_WIN_SIZ))
268                 goto errexit;
269         if (sr_allocate_irq(device, 0, 1))
270                 goto errexit;
271
272         /*
273          * We have to fill these in early because the SRC_PUT* and SRC_GET*
274          * macros use them.
275          */
276         hc->src_get8 = src_get8_io;
277         hc->src_get16 = src_get16_io;
278         hc->src_put8 = src_put8_io;
279         hc->src_put16 = src_put16_io;
280
281         hc->cardtype = SR_CRD_N2;
282         hc->cunit = device_get_unit(device);
283         hc->sca = 0;
284         hc->numports = NCHAN;   /* assumed # of channels on the card */
285         flags = device_get_flags(device);
286         if (flags & SR_FLAGS_NCHAN_MSK)
287                 hc->numports = flags & SR_FLAGS_NCHAN_MSK;
288
289         hc->iobase = rman_get_start(hc->res_ioport);
290         hc->sca_base = hc->iobase;
291         hc->mem_start = (caddr_t)rman_get_virtual(hc->res_memory);
292         hc->mem_end = hc->mem_start + SRC_WIN_SIZ;
293         hc->mem_pstart = 0;
294         hc->winmsk = SRC_WIN_MSK;
295
296         hc->mempages = src_dpram_size(device);
297         hc->memsize = hc->mempages * SRC_WIN_SIZ;
298
299         outb(hc->iobase + SR_PCR, inb(hc->iobase + SR_PCR) | SR_PCR_SCARUN);
300         outb(hc->iobase + SR_PSR, inb(hc->iobase + SR_PSR) | SR_PSR_EN_SCA_DMA);
301         outb(hc->iobase + SR_MCR,
302              SR_MCR_DTR0 | SR_MCR_DTR1 | SR_MCR_TE0 | SR_MCR_TE1);
303
304         SRC_SET_ON(hc->iobase);
305
306         /*
307          * Configure the card. Mem address, irq,
308          */
309         mar = (rman_get_start(hc->res_memory) >> 16) & SR_PCR_16M_SEL;
310         outb(hc->iobase + SR_PCR,
311              mar | (inb(hc->iobase + SR_PCR) & ~SR_PCR_16M_SEL));
312         mar = rman_get_start(hc->res_memory) >> 12;
313         outb(hc->iobase + SR_BAR, mar);
314
315         return sr_attach(device);
316
317 errexit:
318         sr_deallocate_resources(device);
319         return (ENXIO);
320 }
321
322 /*
323  * I/O for ISA N2 card(s)
324  */
325 #define SRC_REG(iobase,y)       ((((y) & 0xf) + (((y) & 0xf0) << 6) +       \
326                                 (iobase)) | 0x8000)
327
328 static u_int
329 src_get8_io(u_int base, u_int off)
330 {
331         return inb(SRC_REG(base, off));
332 }
333
334 static u_int
335 src_get16_io(u_int base, u_int off)
336 {
337         return inw(SRC_REG(base, off));
338 }
339
340 static void
341 src_put8_io(u_int base, u_int off, u_int val)
342 {
343         outb(SRC_REG(base, off), val);
344 }
345
346 static void
347 src_put16_io(u_int base, u_int off, u_int val)
348 {
349         outw(SRC_REG(base, off), val);
350 }
351
352 static u_int
353 src_dpram_size(device_t device)
354 {
355         u_int pgs, i;
356         u_short port;
357         u_short *smem;
358         u_char mar;
359         u_long membase;
360         struct sr_hardc *hc;
361
362         hc = device_get_softc(device);
363         port = hc->iobase;
364
365         /*
366          * OK, the board's interface registers seem to work. Now we'll see
367          * if the Dual-Ported RAM is fully accessible...
368          */
369         outb(port + SR_PCR, SR_PCR_EN_VPM | SR_PCR_ISA16);
370         outb(port + SR_PSR, SR_PSR_WIN_16K);
371
372         /*
373          * Take the kernel "virtual" address supplied to us and convert
374          * it to a "real" address. Then program the card to use that.
375          */
376         membase = rman_get_start(hc->res_memory);
377         mar = (membase >> 16) & SR_PCR_16M_SEL;
378         outb(port + SR_PCR, mar | inb(port + SR_PCR));
379         mar = membase >> 12;
380         outb(port + SR_BAR, mar);
381         outb(port + SR_PCR, inb(port + SR_PCR) | SR_PCR_MEM_WIN);
382         smem = (u_short *)rman_get_virtual(hc->res_memory);/* DP RAM Address */
383         /*
384          * Here we will perform the memory scan to size the device.
385          *
386          * This is done by marking each potential page with a magic number.
387          * We then loop through the pages looking for that magic number. As
388          * soon as we no longer see that magic number, we'll quit the scan,
389          * knowing that no more memory is present. This provides the number
390          * of pages present on the card.
391          *
392          * Note: We're sizing 16K memory granules.
393          */
394         for (i = 0; i <= SR_PSR_PG_SEL; i++) {
395                 outb(port + SR_PSR,
396                      (inb(port + SR_PSR) & ~SR_PSR_PG_SEL) | i);
397
398                 *smem = 0xAA55;
399         }
400
401         for (i = 0; i <= SR_PSR_PG_SEL; i++) {
402                 outb(port + SR_PSR,
403                      (inb(port + SR_PSR) & ~SR_PSR_PG_SEL) | i);
404
405                 if (*smem != 0xAA55) {
406                         /*
407                          * If we have less than 64k of memory, give up. That
408                          * is 4 x 16k pages.
409                          */
410                         if (i < 4) {
411                                 kprintf("sr%d: Bad mem page %d, mem %x, %x.\n",
412                                        hc->cunit, i, 0xAA55, *smem);
413                                 return 0;
414                         }
415                         break;
416                 }
417                 *smem = i;
418         }
419
420         hc->mempages = i;
421         hc->memsize = i * SRC_WIN_SIZ;
422         hc->winmsk = SRC_WIN_MSK;
423         pgs = i;                /* final count of 16K pages */
424
425         /*
426          * This next loop erases the contents of that page in DPRAM
427          */
428         for (i = 0; i <= pgs; i++) {
429                 outb(port + SR_PSR,
430                      (inb(port + SR_PSR) & ~SR_PSR_PG_SEL) | i);
431                 bzero(smem, SRC_WIN_SIZ);
432         }
433
434         SRC_SET_OFF(port);
435         return (pgs);
436 }