source: drsdaq/VME/struck/sis1100/V2.02/dev/pci/sis1100_autoconf_netbsd.c@ 23

Last change on this file since 23 was 22, checked in by ogrimm, 16 years ago
First commit of drsdaq program
File size: 9.4 KB
Line 
1/* $ZEL: sis1100_autoconf_netbsd.c,v 1.6 2004/05/27 23:10:18 wuestner Exp $ */
2
3/*
4 * Copyright (c) 2001-2004
5 * Matthias Drochner, Peter Wuestner. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <dev/pci/sis1100_sc.h>
30
31struct sis1100_softc *sis1100_devdata[sis1100_MAXCARDS];
32
33struct cdevsw sis1100cdevsw = {
34 sis1100_open,
35 sis1100_close,
36 sis1100_read,
37 sis1100_write,
38 sis1100_ioctl,
39 (dev_type_stop((*))) enodev,
40 0,
41 sis1100_poll,
42 sis1100_mmap,
43 0
44};
45
46#if __NetBSD_Version__ < 106000000
47struct cfdriver sis1100cfdriver = {
48 NULL,
49 "sis1100_",
50 DV_DULL,
51 0
52};
53#else
54struct cfdriver {
55 LIST_ENTRY(cfdriver) cd_list; /* link on allcfdrivers */
56 struct cfattachlist cd_attach; /* list of all attachments */
57 void **cd_devs; /* devices found */
58 const char *cd_name; /* device name */
59 enum devclass cd_class; /* device classification */
60 int cd_ndevs; /* size of cd_devs array */
61 const char * const *cd_attrs; /* attributes for this device */
62};
63#endif
64
65int sis1100match(struct device *, struct cfdata *, void *);
66void sis1100attach(struct device *, struct device *, void *);
67int sis1100detach(struct device *, int);
68
69int sis1100intr(void *);
70
71struct cfattach sis1100cfattach = {
72 sizeof(struct sis1100_softc),
73 sis1100match,
74 sis1100attach,
75 sis1100detach,
76 0
77};
78
79int sis1100locs[] = {-1, -1};
80extern const char *pcicf_locnames[];
81
82struct cfdata sis1100cfdata = {
83 &sis1100cfattach,
84 &sis1100cfdriver,
85 0,
86 FSTATE_STAR,
87 sis1100locs,
88 0,
89 NULL,
90 pcicf_locnames
91};
92
93int
94sis1100match(parent, match, aux)
95 struct device *parent;
96 struct cfdata *match;
97 void *aux;
98{
99#define MIN_FV 5
100#define MAX_FV 7
101
102 struct pci_attach_args *pa = aux;
103 int revision;
104 bus_space_tag_t reg_t;
105 bus_space_handle_t reg_h;
106 bus_size_t reg_size;
107 u_int32_t ident;
108 int hw_type, hw_ver, fw_code, fw_ver;
109
110 if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_FZJZEL ||
111 PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_FZJZEL_GIGALINK)
112 return (0);
113
114 revision=PCI_REVISION(pci_conf_read(pa->pa_pc, pa->pa_tag,
115 PCI_CLASS_REG));
116 if (revision!=1) {
117 printf("sis1100: pci_revision=%d\n", revision);
118 return (0);
119 }
120
121 if (pci_mapreg_map(pa, 0x18, PCI_MAPREG_TYPE_MEM, 0,
122 &reg_t, &reg_h, NULL, &reg_size)) {
123 printf("sis1100: can't map register space\n");
124 return 0;
125 }
126 ident=bus_space_read_4(reg_t, reg_h, ofs(struct sis1100_reg, ident));
127 printf("sis1100: ident=0x%08x\n", ident);
128 bus_space_unmap(reg_t, reg_h, reg_size);
129 hw_type= ident &0xff;
130 hw_ver =(ident>> 8)&0xff;
131 fw_code=(ident>>16)&0xff;
132 fw_ver =(ident>>24)&0xff;
133 if (hw_type!=1) {
134 printf("sis1100: wrong hw_type %d\n", hw_type);
135 return 0;
136 }
137 if (hw_ver!=1) {
138 printf("sis1100: wrong hw_version %d\n", hw_ver);
139 return 0;
140 }
141 if (fw_code!=1) {
142 printf("sis1100: wrong fw_code %d\n", fw_code);
143 return 0;
144 }
145 if (fw_ver<MIN_FV) {
146 printf("sis1100: Firmware version (%d) too old;"
147 " at least version %d is required.\n", fw_ver, MIN_FV);
148 return 0;
149 }
150 if (fw_ver>MAX_FV) {
151 printf("sis1100: Firmware version (%d) too new;"
152 "Driver not tested with"
153 " versions greater than %d.\n", fw_ver, MAX_FV);
154 }
155 return (1);
156#undef MIN_FV
157#undef MAX_FV
158}
159
160void
161sis1100attach(parent, self, aux)
162 struct device *parent, *self;
163 void *aux;
164{
165 struct sis1100_softc *sc = (void *)self;
166 struct pci_attach_args *pa = aux;
167 pci_chipset_tag_t pc = pa->pa_pc;
168 int i;
169 pci_intr_handle_t ih;
170 const char *intrstr = NULL;
171
172 printf("\n");
173#if 0
174 printf("MINORBITS =%d\n", sis1100_MINORBITS);
175 printf("MINORCARDBITS=%d\n", sis1100_MINORCARDBITS);
176 printf("MAXCARDS =%d\n", sis1100_MAXCARDS);
177 printf("MINORUSERBITS=%d\n", sis1100_MINORUSERBITS);
178 printf("MINORCARDMASK=0x%08x\n",sis1100_MINORCARDMASK );
179 printf("MINORTYPEMASK=0x%08x\n", sis1100_MINORTYPEMASK);
180 printf("MINORUSERMASK=0x%08x\n", sis1100_MINORUSERMASK);
181 printf("MINORUTMASK =0x%08x\n", sis1100_MINORUTMASK);
182 printf("sc=%p\n", sc);
183 printf("clearing fdatalist[0..%d]\n", sis1100_MINORUTMASK+1);
184#endif
185 for (i=0; i<=sis1100_MINORUTMASK; i++) sc->fdatalist[i]=0;
186
187 if (pci_mapreg_map(pa, 0x10, PCI_MAPREG_TYPE_MEM, 0,
188 &sc->plx_t, &sc->plx_h, NULL, &sc->plx_size)) {
189 printf("%s: can't map plx space\n", sc->sc_dev.dv_xname);
190 sc->plx_size=0;
191 return;
192 }
193
194 if (pci_mapreg_map(pa, 0x18, PCI_MAPREG_TYPE_MEM, 0,
195 &sc->reg_t, &sc->reg_h, &sc->reg_addr, &sc->reg_size)) {
196 printf("%s: can't map register space\n", sc->sc_dev.dv_xname);
197 sc->reg_size=0;
198 return;
199 }
200
201 if (pci_mapreg_map(pa, 0x1c, PCI_MAPREG_TYPE_MEM, 0,
202 &sc->rem_t, &sc->rem_h, &sc->rem_addr, &sc->rem_size)) {
203 printf("%s: can't map remote space\n", sc->sc_dev.dv_xname);
204 printf("%s: mmap not available\n", sc->sc_dev.dv_xname);
205 sc->rem_size=0;
206 }
207
208 pINFO(sc, "reg_addr=0x%08x, reg_size=%ld",
209 (unsigned int)sc->reg_addr, sc->reg_size);
210 pINFO(sc, "rem_addr=0x%08x, rem_size=%ld",
211 (unsigned int)sc->rem_addr, sc->rem_size);
212
213/*
214 {
215 int rev;
216 rev = PCI_REVISION(pci_conf_read(pc, pa->pa_tag, PCI_CLASS_REG));
217 printf("%s: PCI revision %d\n", sc->sc_dev.dv_xname, rev);
218 }
219*/
220#ifdef NEVER
221 {
222 pcitag_t bridgetag;
223 int i;
224
225 bridgetag=pci_make_tag(pc, 0, 18, 0);
226 for (i=0; i<0x40; i+=4) {
227 pcireg_t x=pci_conf_read(pc, bridgetag, i);
228 printf("bridge[%02x]: 0x%08x\n", i, x);
229 }
230 }
231#endif
232 sc->sc_pc = pc;
233 sc->sc_pcitag = pa->pa_tag;
234 sc->sc_dmat=pa->pa_dmat;
235
236 simple_lock_init(&sc->lock_intcsr);
237 simple_lock_init(&sc->lock_sc_inuse);
238 lockinit(&sc->sem_hw, 0, "sem_hw", 0, 0);
239 lockinit(&sc->sem_fdata_list, 0, "sem_fdata_list", 0, 0);
240
241 callout_init(&sc->link_up_timer);
242
243 simple_lock_init(&sc->handlercommand.lock);
244 sc->handlercommand.command=0;
245 INIT_LIST_HEAD(&sc->fdata_list_head);
246 kthread_create1(sis1100_irq_thread, sc, &sc->vmeirq_pp, "%s", "sis1100_irq");
247 simple_lock_init(&sc->remoteirq_wait);
248 simple_lock_init(&sc->local_wait);
249
250 sc->sc_dma.devname=sc->sc_dev.dv_xname;
251 sc->sc_dma.iot=sc->plx_t;
252 sc->sc_dma.ioh=sc->plx_h;
253 sc->sc_dma.dmat=pa->pa_dmat;
254
255 if (plx9054_dmaalloc(&sc->sc_dma, MAX_DMA_LEN))
256 return;
257
258 if (sis1100_init(sc)) {
259 printf("%s: cannot initialize device\n", sc->sc_dev.dv_xname);
260 return;
261 }
262
263 /* Map and establish the interrupt. */
264 if (pci_intr_map(pc, pa->pa_intrtag, pa->pa_intrpin,
265 pa->pa_intrline, &ih)) {
266 printf("%s: couldn't map interrupt\n", sc->sc_dev.dv_xname);
267 return;
268 }
269 intrstr = pci_intr_string(pc, ih);
270
271 sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, sis1100_intr, sc);
272 if (sc->sc_ih == NULL) {
273 printf("%s: couldn't establish interrupt",
274 sc->sc_dev.dv_xname);
275 if (intrstr != NULL)
276 printf(" at %s", intrstr);
277 printf("\n");
278 return;
279 }
280 printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
281}
282
283int
284sis1100detach(self, flags)
285 struct device *self;
286 int flags;
287{
288 struct sis1100_softc *sc = (void *)self;
289 int i;
290
291 if (sc->sc_inuse)
292 return (EBUSY);
293
294 sis1100_done(sc);
295 callout_stop(&sc->link_up_timer);
296
297 simple_lock(&sc->handlercommand.lock);
298 sc->handlercommand.command=handlercomm_die;
299 wakeup(&sc->handler_wait);
300 /* XXX PNORELOCK??? */
301 ltsleep(sc, PCATCH|PNORELOCK, "terminate_sync", 0,
302 &sc->handlercommand.lock);
303
304 for (i=0; i<=sis1100_MINORUTMASK; i++) {
305 if (sc->fdatalist[i]) free(sc->fdatalist[i], M_DEVBUF);
306 }
307
308 if (sc->sc_ih)
309 pci_intr_disestablish(sc->sc_pc, sc->sc_ih);
310
311 plx9054_dmafree(&sc->sc_dma);
312
313 if (sc->plx_size)
314 bus_space_unmap(sc->plx_t, sc->plx_h, sc->plx_size);
315 if (sc->reg_size)
316 bus_space_unmap(sc->reg_t, sc->reg_h, sc->reg_size);
317 if (sc->rem_size)
318 bus_space_unmap(sc->rem_t, sc->rem_h, sc->rem_size);
319 return (0);
320}
Note: See TracBrowser for help on using the repository browser.