xref: /openbsd-src/sys/dev/pci/gdt_pci.c (revision 47911bd667ac77dc523b8a13ef40b012dbffa741)
1 /*	$OpenBSD: gdt_pci.c,v 1.17 2002/06/11 14:41:35 niklas Exp $	*/
2 
3 /*
4  * Copyright (c) 1999, 2000 Niklas Hallqvist.  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. All advertising materials mentioning features or use of this software
15  *    must display the following acknowledgement:
16  *	This product includes software developed by Niklas Hallqvist.
17  * 4. The name of the author may not be used to endorse or promote products
18  *    derived from this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
21  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
22  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
23  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
24  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
29  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  */
31 
32 /*
33  * This driver would not have written if it was not for the hardware donations
34  * from both ICP-Vortex and �ko.neT.  I want to thank them for their support.
35  */
36 
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/device.h>
40 #include <sys/kernel.h>
41 #include <sys/malloc.h>
42 #include <sys/queue.h>
43 
44 #include <machine/bus.h>
45 #include <machine/endian.h>
46 #include <machine/intr.h>
47 
48 #include <scsi/scsi_all.h>
49 #include <scsi/scsiconf.h>
50 
51 #include <dev/pci/pcidevs.h>
52 #include <dev/pci/pcireg.h>
53 #include <dev/pci/pcivar.h>
54 
55 #include <dev/ic/gdtreg.h>
56 #include <dev/ic/gdtvar.h>
57 
58 /* Product numbers for Fibre-Channel are greater than or equal to 0x200 */
59 #define GDT_PCI_PRODUCT_FC	0x200
60 
61 /* Mapping registers for various areas */
62 #define GDT_PCI_DPMEM		0x10
63 #define GDT_PCINEW_IOMEM	0x10
64 #define GDT_PCINEW_IO		0x14
65 #define GDT_PCINEW_DPMEM	0x18
66 
67 /* PCI SRAM structure */
68 #define GDT_MAGIC	0x00	/* u_int32_t, controller ID from BIOS */
69 #define GDT_NEED_DEINIT	0x04	/* u_int16_t, switch between BIOS/driver */
70 #define GDT_SWITCH_SUPPORT 0x06	/* u_int8_t, see GDT_NEED_DEINIT */
71 #define GDT_OS_USED	0x10	/* u_int8_t [16], OS code per service */
72 #define GDT_FW_MAGIC	0x3c	/* u_int8_t, controller ID from firmware */
73 #define GDT_SRAM_SZ	0x40
74 
75 /* DPRAM PCI controllers */
76 #define GDT_DPR_IF	0x00	/* interface area */
77 #define GDT_6SR		(0xff0 - GDT_SRAM_SZ)
78 #define GDT_SEMA1	0xff1	/* volatile u_int8_t, command semaphore */
79 #define GDT_IRQEN	0xff5	/* u_int8_t, board interrupts enable */
80 #define GDT_EVENT	0xff8	/* u_int8_t, release event */
81 #define GDT_IRQDEL	0xffc	/* u_int8_t, acknowledge board interrupt */
82 #define GDT_DPRAM_SZ	0x1000
83 
84 /* PLX register structure (new PCI controllers) */
85 #define GDT_CFG_REG	0x00	/* u_int8_t, DPRAM cfg. (2: < 1MB, 0: any) */
86 #define GDT_SEMA0_REG	0x40	/* volatile u_int8_t, command semaphore */
87 #define GDT_SEMA1_REG	0x41	/* volatile u_int8_t, status semaphore */
88 #define GDT_PLX_STATUS	0x44	/* volatile u_int16_t, command status */
89 #define GDT_PLX_SERVICE	0x46	/* u_int16_t, service */
90 #define GDT_PLX_INFO	0x48	/* u_int32_t [2], additional info */
91 #define GDT_LDOOR_REG	0x60	/* u_int8_t, PCI to local doorbell */
92 #define GDT_EDOOR_REG	0x64	/* volatile u_int8_t, local to PCI doorbell */
93 #define GDT_CONTROL0	0x68	/* u_int8_t, control0 register (unused) */
94 #define GDT_CONTROL1	0x69	/* u_int8_t, board interrupts enable */
95 #define GDT_PLX_SZ	0x80
96 
97 /* DPRAM new PCI controllers */
98 #define GDT_IC		0x00	/* interface */
99 #define GDT_PCINEW_6SR	(0x4000 - GDT_SRAM_SZ)
100 				/* SRAM structure */
101 #define GDT_PCINEW_SZ	0x4000
102 
103 /* i960 register structure (PCI MPR controllers) */
104 #define GDT_MPR_SEMA0	0x10	/* volatile u_int8_t, command semaphore */
105 #define GDT_MPR_SEMA1	0x12	/* volatile u_int8_t, status semaphore */
106 #define GDT_MPR_STATUS	0x14	/* volatile u_int16_t, command status */
107 #define GDT_MPR_SERVICE	0x16	/* u_int16_t, service */
108 #define GDT_MPR_INFO	0x18	/* u_int32_t [2], additional info */
109 #define GDT_MPR_LDOOR	0x20	/* u_int8_t, PCI to local doorbell */
110 #define GDT_MPR_EDOOR	0x2c	/* volatile u_int8_t, locl to PCI doorbell */
111 #define GDT_EDOOR_EN	0x34	/* u_int8_t, board interrupts enable */
112 #define GDT_I960_SZ	0x1000
113 
114 /* DPRAM PCI MPR controllers */
115 #define GDT_I960R	0x00	/* 4KB i960 registers */
116 #define GDT_MPR_IC	GDT_I960_SZ
117 				/* interface area */
118 #define GDT_MPR_6SR	(GDT_I960_SZ + 0x3000 - GDT_SRAM_SZ)
119 				/* SRAM structure */
120 #define GDT_MPR_SZ	0x4000
121 
122 int	gdt_pci_probe(struct device *, void *, void *);
123 void	gdt_pci_attach(struct device *, struct device *, void *);
124 void	gdt_pci_enable_intr(struct gdt_softc *);
125 
126 void	gdt_pci_copy_cmd(struct gdt_softc *, struct gdt_ccb *);
127 u_int8_t gdt_pci_get_status(struct gdt_softc *);
128 void	gdt_pci_intr(struct gdt_softc *, struct gdt_intr_ctx *);
129 void	gdt_pci_release_event(struct gdt_softc *, struct gdt_ccb *);
130 void	gdt_pci_set_sema0(struct gdt_softc *);
131 int	gdt_pci_test_busy(struct gdt_softc *);
132 
133 void	gdt_pcinew_copy_cmd(struct gdt_softc *, struct gdt_ccb *);
134 u_int8_t gdt_pcinew_get_status(struct gdt_softc *);
135 void	gdt_pcinew_intr(struct gdt_softc *, struct gdt_intr_ctx *);
136 void	gdt_pcinew_release_event(struct gdt_softc *, struct gdt_ccb *);
137 void	gdt_pcinew_set_sema0(struct gdt_softc *);
138 int	gdt_pcinew_test_busy(struct gdt_softc *);
139 
140 void	gdt_mpr_copy_cmd(struct gdt_softc *, struct gdt_ccb *);
141 u_int8_t gdt_mpr_get_status(struct gdt_softc *);
142 void	gdt_mpr_intr(struct gdt_softc *, struct gdt_intr_ctx *);
143 void	gdt_mpr_release_event(struct gdt_softc *, struct gdt_ccb *);
144 void	gdt_mpr_set_sema0(struct gdt_softc *);
145 int	gdt_mpr_test_busy(struct gdt_softc *);
146 
147 struct cfattach gdt_pci_ca = {
148 	sizeof (struct gdt_softc), gdt_pci_probe, gdt_pci_attach
149 };
150 
151 int
152 gdt_pci_probe(parent, match, aux)
153         struct device *parent;
154         void *match, *aux;
155 {
156         struct pci_attach_args *pa = aux;
157 
158 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VORTEX &&
159 	    PCI_PRODUCT(pa->pa_id) >= 0x100 && PCI_PRODUCT(pa->pa_id) <= 0x300)
160 		return (1);
161 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL &&
162 	    (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_GDT_RAID1 ||
163 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_GDT_RAID2))
164 		return (1);
165 	return (0);
166 }
167 
168 void
169 gdt_pci_attach(parent, self, aux)
170         struct device *parent, *self;
171         void *aux;
172 {
173 	struct pci_attach_args *pa = aux;
174 	struct gdt_softc *gdt = (void *)self;
175 	bus_space_tag_t dpmemt, iomemt, iot;
176 	bus_space_handle_t dpmemh, iomemh, ioh;
177 	bus_addr_t dpmembase, iomembase, iobase;
178 	bus_size_t dpmemsize, iomemsize, iosize;
179 	u_int16_t prod;
180 	u_int32_t status = 0;
181 #define DPMEM_MAPPED		1
182 #define IOMEM_MAPPED		2
183 #define IO_MAPPED		4
184 #define INTR_ESTABLISHED	8
185 	int retries;
186 	u_int8_t protocol;
187 	pci_intr_handle_t ih;
188 	const char *intrstr;
189 
190 	printf(": ");
191 
192 	gdt->sc_class = 0;
193 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_VORTEX) {
194 		prod = PCI_PRODUCT(pa->pa_id);
195 		switch (prod) {
196 		case PCI_PRODUCT_VORTEX_GDT_60x0:
197 		case PCI_PRODUCT_VORTEX_GDT_6000B:
198 			gdt->sc_class = GDT_PCI;
199 			break;
200 
201 		case PCI_PRODUCT_VORTEX_GDT_6x10:
202 		case PCI_PRODUCT_VORTEX_GDT_6x20:
203 		case PCI_PRODUCT_VORTEX_GDT_6530:
204 		case PCI_PRODUCT_VORTEX_GDT_6550:
205 		case PCI_PRODUCT_VORTEX_GDT_6x17:
206 		case PCI_PRODUCT_VORTEX_GDT_6x27:
207 		case PCI_PRODUCT_VORTEX_GDT_6537:
208 		case PCI_PRODUCT_VORTEX_GDT_6557:
209 		case PCI_PRODUCT_VORTEX_GDT_6x15:
210 		case PCI_PRODUCT_VORTEX_GDT_6x25:
211 		case PCI_PRODUCT_VORTEX_GDT_6535:
212 		case PCI_PRODUCT_VORTEX_GDT_6555:
213 			gdt->sc_class = GDT_PCINEW;
214 			break;
215 
216 		case PCI_PRODUCT_VORTEX_GDT_6x17RP:
217 		case PCI_PRODUCT_VORTEX_GDT_6x27RP:
218 		case PCI_PRODUCT_VORTEX_GDT_6537RP:
219 		case PCI_PRODUCT_VORTEX_GDT_6557RP:
220 		case PCI_PRODUCT_VORTEX_GDT_6x11RP:
221 		case PCI_PRODUCT_VORTEX_GDT_6x21RP:
222 		case PCI_PRODUCT_VORTEX_GDT_6x17RD:
223 		case PCI_PRODUCT_VORTEX_GDT_6x27RD:
224 		case PCI_PRODUCT_VORTEX_GDT_6537RD:
225 		case PCI_PRODUCT_VORTEX_GDT_6557RD:
226 		case PCI_PRODUCT_VORTEX_GDT_6x11RD:
227 		case PCI_PRODUCT_VORTEX_GDT_6x21RD:
228 		case PCI_PRODUCT_VORTEX_GDT_6x18RD:
229 		case PCI_PRODUCT_VORTEX_GDT_6x28RD:
230 		case PCI_PRODUCT_VORTEX_GDT_6x38RD:
231 		case PCI_PRODUCT_VORTEX_GDT_6x58RD:
232 		case PCI_PRODUCT_VORTEX_GDT_6518RS:
233 		case PCI_PRODUCT_VORTEX_GDT_7x18RN:
234 		case PCI_PRODUCT_VORTEX_GDT_7x28RN:
235 		case PCI_PRODUCT_VORTEX_GDT_7x38RN:
236 		case PCI_PRODUCT_VORTEX_GDT_7x58RN:
237 		case PCI_PRODUCT_VORTEX_GDT_6x19RD:
238 		case PCI_PRODUCT_VORTEX_GDT_6x29RD:
239 		case PCI_PRODUCT_VORTEX_GDT_7x19RN:
240 		case PCI_PRODUCT_VORTEX_GDT_7x29RN:
241 		case PCI_PRODUCT_VORTEX_GDT_7x43RN:
242 			gdt->sc_class = GDT_MPR;
243 		}
244 
245 		/* If we don't recognize it, determine class heuristically.  */
246 		if (gdt->sc_class == 0)
247 			gdt->sc_class = prod < 0x100 ? GDT_PCINEW : GDT_MPR;
248 
249 		if (prod >= GDT_PCI_PRODUCT_FC)
250 			gdt->sc_class |= GDT_FC;
251 
252 	} else if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_INTEL) {
253 		gdt->sc_class = GDT_MPR;
254 	}
255 
256 	if (pci_mapreg_map(pa,
257 	    GDT_CLASS(gdt) == GDT_PCINEW ? GDT_PCINEW_DPMEM : GDT_PCI_DPMEM,
258 	    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT, 0, &dpmemt,
259 	    &dpmemh, &dpmembase, &dpmemsize, 0)) {
260 		if (pci_mapreg_map(pa,
261 		    GDT_CLASS(gdt) == GDT_PCINEW ? GDT_PCINEW_DPMEM :
262 		    GDT_PCI_DPMEM,
263 		    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT_1M, 0,
264 		    &dpmemt,&dpmemh, &dpmembase, &dpmemsize, 0)) {
265 			printf("cannot map DPMEM\n");
266 			goto bail_out;
267 		}
268 	}
269 	status |= DPMEM_MAPPED;
270 	gdt->sc_dpmemt = dpmemt;
271 	gdt->sc_dpmemh = dpmemh;
272 	gdt->sc_dpmembase = dpmembase;
273 	gdt->sc_dmat = pa->pa_dmat;
274 
275 	/*
276 	 * The GDT_PCINEW series also has two other regions to map.
277 	 */
278 	if (GDT_CLASS(gdt) == GDT_PCINEW) {
279 		if (pci_mapreg_map(pa, GDT_PCINEW_IOMEM, PCI_MAPREG_TYPE_MEM,
280 		    0, &iomemt, &iomemh, &iomembase, &iomemsize, 0)) {
281 			printf("cannot map memory mapped I/O ports\n");
282 			goto bail_out;
283 		}
284 		status |= IOMEM_MAPPED;
285 
286 		if (pci_mapreg_map(pa, GDT_PCINEW_IO, PCI_MAPREG_TYPE_IO, 0,
287 		    &iot, &ioh, &iobase, &iosize, 0)) {
288 			printf("cannot map I/O ports\n");
289 			goto bail_out;
290 		}
291 		status |= IO_MAPPED;
292 		gdt->sc_iot = iot;
293 		gdt->sc_ioh = ioh;
294 		gdt->sc_iobase = iobase;
295 	}
296 
297 	switch (GDT_CLASS(gdt)) {
298 	case GDT_PCI:
299 		bus_space_set_region_4(dpmemt, dpmemh, 0, 0,
300 		    GDT_DPR_IF_SZ >> 2);
301 		if (bus_space_read_1(dpmemt, dpmemh, 0) != 0) {
302 			printf("cannot write to DPMEM\n");
303 			goto bail_out;
304 		}
305 
306 #if 0
307 		/* disable board interrupts, deinit services */
308 		gdth_writeb(0xff, &dp6_ptr->io.irqdel);
309 		gdth_writeb(0x00, &dp6_ptr->io.irqen);;
310 		gdth_writeb(0x00, &dp6_ptr->u.ic.S_Status);
311 		gdth_writeb(0x00, &dp6_ptr->u.ic.Cmd_Index);
312 
313 		gdth_writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]);
314 		gdth_writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx);
315 		gdth_writeb(0, &dp6_ptr->io.event);
316 		retries = INIT_RETRIES;
317 		gdth_delay(20);
318 		while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xff) {
319 		  if (--retries == 0) {
320 		    printk("initialization error (DEINIT failed)\n");
321 		    gdth_munmap(ha->brd);
322 		    return 0;
323 		  }
324 		  gdth_delay(1);
325 		}
326 		prot_ver = (unchar)gdth_readl(&dp6_ptr->u.ic.S_Info[0]);
327 		gdth_writeb(0, &dp6_ptr->u.ic.S_Status);
328 		gdth_writeb(0xff, &dp6_ptr->io.irqdel);
329 		if (prot_ver != PROTOCOL_VERSION) {
330 		  printk("illegal protocol version\n");
331 		  gdth_munmap(ha->brd);
332 		  return 0;
333 		}
334 
335 		ha->type = GDT_PCI;
336 		ha->ic_all_size = sizeof(dp6_ptr->u);
337 
338 		/* special command to controller BIOS */
339 		gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[0]);
340 		gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[1]);
341 		gdth_writel(0x01, &dp6_ptr->u.ic.S_Info[2]);
342 		gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[3]);
343 		gdth_writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx);
344 		gdth_writeb(0, &dp6_ptr->io.event);
345 		retries = INIT_RETRIES;
346 		gdth_delay(20);
347 		while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xfe) {
348 		  if (--retries == 0) {
349 		    printk("initialization error\n");
350 		    gdth_munmap(ha->brd);
351 		    return 0;
352 		  }
353 		  gdth_delay(1);
354 		}
355 		gdth_writeb(0, &dp6_ptr->u.ic.S_Status);
356 		gdth_writeb(0xff, &dp6_ptr->io.irqdel);
357 #endif
358 
359 		gdt->sc_ic_all_size = GDT_DPRAM_SZ;
360 
361 		gdt->sc_copy_cmd = gdt_pci_copy_cmd;
362 		gdt->sc_get_status = gdt_pci_get_status;
363 		gdt->sc_intr = gdt_pci_intr;
364 		gdt->sc_release_event = gdt_pci_release_event;
365 		gdt->sc_set_sema0 = gdt_pci_set_sema0;
366 		gdt->sc_test_busy = gdt_pci_test_busy;
367 
368 		break;
369 
370 	case GDT_PCINEW:
371 		bus_space_set_region_4(dpmemt, dpmemh, 0, 0,
372 		    GDT_DPR_IF_SZ >> 2);
373 		if (bus_space_read_1(dpmemt, dpmemh, 0) != 0) {
374 			printf("cannot write to DPMEM\n");
375 			goto bail_out;
376 		}
377 
378 #if 0
379 		/* disable board interrupts, deinit services */
380 		outb(0x00,PTR2USHORT(&ha->plx->control1));
381 		outb(0xff,PTR2USHORT(&ha->plx->edoor_reg));
382 
383 		gdth_writeb(0x00, &dp6c_ptr->u.ic.S_Status);
384 		gdth_writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index);
385 
386 		gdth_writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]);
387 		gdth_writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx);
388 
389 		outb(1,PTR2USHORT(&ha->plx->ldoor_reg));
390 
391 		retries = INIT_RETRIES;
392 		gdth_delay(20);
393 		while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xff) {
394 		  if (--retries == 0) {
395 		    printk("initialization error (DEINIT failed)\n");
396 		    gdth_munmap(ha->brd);
397 		    return 0;
398 		  }
399 		  gdth_delay(1);
400 		}
401 		prot_ver = (unchar)gdth_readl(&dp6c_ptr->u.ic.S_Info[0]);
402 		gdth_writeb(0, &dp6c_ptr->u.ic.Status);
403 		if (prot_ver != PROTOCOL_VERSION) {
404 		  printk("illegal protocol version\n");
405 		  gdth_munmap(ha->brd);
406 		  return 0;
407 		}
408 
409 		ha->type = GDT_PCINEW;
410 		ha->ic_all_size = sizeof(dp6c_ptr->u);
411 
412 		/* special command to controller BIOS */
413 		gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[0]);
414 		gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[1]);
415 		gdth_writel(0x01, &dp6c_ptr->u.ic.S_Info[2]);
416 		gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[3]);
417 		gdth_writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx);
418 
419 		outb(1,PTR2USHORT(&ha->plx->ldoor_reg));
420 
421 		retries = INIT_RETRIES;
422 		gdth_delay(20);
423 		while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) {
424 		  if (--retries == 0) {
425 		    printk("initialization error\n");
426 		    gdth_munmap(ha->brd);
427 		    return 0;
428 		  }
429 		  gdth_delay(1);
430 		}
431 		gdth_writeb(0, &dp6c_ptr->u.ic.S_Status);
432 #endif
433 
434 		gdt->sc_ic_all_size = GDT_PCINEW_SZ;
435 
436 		gdt->sc_copy_cmd = gdt_pcinew_copy_cmd;
437 		gdt->sc_get_status = gdt_pcinew_get_status;
438 		gdt->sc_intr = gdt_pcinew_intr;
439 		gdt->sc_release_event = gdt_pcinew_release_event;
440 		gdt->sc_set_sema0 = gdt_pcinew_set_sema0;
441 		gdt->sc_test_busy = gdt_pcinew_test_busy;
442 
443 		break;
444 
445 	case GDT_MPR:
446 		bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC, GDT_MPR_MAGIC);
447 		if (bus_space_read_4(dpmemt, dpmemh, GDT_MPR_IC) !=
448 		    GDT_MPR_MAGIC) {
449 			printf("cannot access DPMEM at 0x%x (shadowed?)\n",
450 			    dpmembase);
451 			goto bail_out;
452 		}
453 
454 		/*
455 		 * XXX Here the Linux driver has a weird remapping logic I
456 		 * don't understand.  My controller does not need it, and I
457 		 * cannot see what purpose it serves, therefore I did not
458 		 * do anything similar.
459 		 */
460 
461 		bus_space_set_region_4(dpmemt, dpmemh, GDT_I960_SZ, 0,
462 		    GDT_DPR_IF_SZ >> 2);
463 
464 		/* Disable everything */
465 		bus_space_write_1(dpmemt, dpmemh, GDT_EDOOR_EN,
466 		    bus_space_read_1(dpmemt, dpmemh, GDT_EDOOR_EN) | 4);
467 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_EDOOR, 0xff);
468 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS,
469 		    0);
470 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_CMD_INDEX,
471 		    0);
472 
473 		bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO,
474 		    dpmembase);
475 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
476 		    0xff);
477 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_LDOOR, 1);
478 
479 		DELAY(20);
480 		retries = GDT_RETRIES;
481 		while (bus_space_read_1(dpmemt, dpmemh,
482 		    GDT_MPR_IC + GDT_S_STATUS) != 0xff) {
483 			if (--retries == 0) {
484 				printf("DEINIT failed (status 0x%x)\n",
485 				    bus_space_read_1(dpmemt, dpmemh,
486 				    GDT_MPR_IC + GDT_S_STATUS));
487 				goto bail_out;
488 			}
489 			DELAY(1);
490 		}
491 
492 		protocol = (u_int8_t)bus_space_read_4(dpmemt, dpmemh,
493 		    GDT_MPR_IC + GDT_S_INFO);
494 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS,
495 		    0);
496 		if (protocol != GDT_PROTOCOL_VERSION) {
497 		 	printf("unsupported protocol %d\n", protocol);
498 			goto bail_out;
499 		}
500 
501 		/* special commnd to controller BIOS */
502 		bus_space_write_4(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_INFO, 0);
503 		bus_space_write_4(dpmemt, dpmemh,
504 		    GDT_MPR_IC + GDT_S_INFO + sizeof (u_int32_t), 0);
505 		bus_space_write_4(dpmemt, dpmemh,
506 		    GDT_MPR_IC + GDT_S_INFO + 2 * sizeof (u_int32_t), 1);
507 		bus_space_write_4(dpmemt, dpmemh,
508 		    GDT_MPR_IC + GDT_S_INFO + 3 * sizeof (u_int32_t), 0);
509 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_CMD_INDX,
510 		    0xfe);
511 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_LDOOR, 1);
512 
513 		DELAY(20);
514 		retries = GDT_RETRIES;
515 		while (bus_space_read_1(dpmemt, dpmemh,
516 		    GDT_MPR_IC + GDT_S_STATUS) != 0xfe) {
517 			if (--retries == 0) {
518 				printf("initialization error\n");
519 				goto bail_out;
520 			}
521 			DELAY(1);
522 		}
523 
524 		bus_space_write_1(dpmemt, dpmemh, GDT_MPR_IC + GDT_S_STATUS,
525 		    0);
526 
527 		gdt->sc_ic_all_size = GDT_MPR_SZ;
528 
529 		gdt->sc_copy_cmd = gdt_mpr_copy_cmd;
530 		gdt->sc_get_status = gdt_mpr_get_status;
531 		gdt->sc_intr = gdt_mpr_intr;
532 		gdt->sc_release_event = gdt_mpr_release_event;
533 		gdt->sc_set_sema0 = gdt_mpr_set_sema0;
534 		gdt->sc_test_busy = gdt_mpr_test_busy;
535 	}
536 
537 	if (pci_intr_map(pa, &ih)) {
538 		printf("couldn't map interrupt\n");
539 		goto bail_out;
540 	}
541 	intrstr = pci_intr_string(pa->pa_pc, ih);
542 	gdt->sc_ih = pci_intr_establish(pa->pa_pc, ih, IPL_BIO, gdt_intr, gdt,
543 	    gdt->sc_dev.dv_xname);
544 	if (gdt->sc_ih == NULL) {
545 		printf("couldn't establish interrupt");
546 		if (intrstr != NULL)
547 			printf(" at %s", intrstr);
548 		printf("\n");
549 		goto bail_out;
550 	}
551 	status |= INTR_ESTABLISHED;
552 	if (intrstr != NULL)
553 		printf("%s ", intrstr);
554 
555 	if (gdt_attach(gdt))
556 		goto bail_out;
557 
558 	gdt_pci_enable_intr(gdt);
559 
560 	return;
561 
562  bail_out:
563 	if (status & DPMEM_MAPPED)
564 		bus_space_unmap(dpmemt, dpmemh, dpmemsize);
565 	if (status & IOMEM_MAPPED)
566 		bus_space_unmap(iomemt, iomemh, iomembase);
567 	if (status & IO_MAPPED)
568 		bus_space_unmap(iot, ioh, iosize);
569 	if (status & INTR_ESTABLISHED)
570 		pci_intr_disestablish(pa->pa_pc, gdt->sc_ih);
571 	return;
572 }
573 
574 /* Enable interrupts */
575 void
576 gdt_pci_enable_intr(gdt)
577 	struct gdt_softc *gdt;
578 {
579 	GDT_DPRINTF(GDT_D_INTR, ("gdt_pci_enable_intr(%p) ", gdt));
580 
581 	switch(GDT_CLASS(gdt)) {
582 	case GDT_PCI:
583 		bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_IRQDEL,
584 		    1);
585 		bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
586 		    GDT_CMD_INDEX, 0);
587 		bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_IRQEN,
588 		    1);
589 		break;
590 
591 	case GDT_PCINEW:
592 		bus_space_write_1(gdt->sc_iot, gdt->sc_ioh, GDT_EDOOR_REG,
593 		    0xff);
594 		bus_space_write_1(gdt->sc_iot, gdt->sc_ioh, GDT_CONTROL1, 3);
595 		break;
596 
597 	case GDT_MPR:
598 		bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
599 		    GDT_MPR_EDOOR, 0xff);
600 		bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_EDOOR_EN,
601 		    bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
602 		    GDT_EDOOR_EN) & ~4);
603 		break;
604 	}
605 }
606 
607 /*
608  * "old" PCI controller-specific functions
609  */
610 
611 void
612 gdt_pci_copy_cmd(gdt, ccb)
613 	struct gdt_softc *gdt;
614 	struct gdt_ccb *ccb;
615 {
616 	/* XXX Not yet implemented */
617 }
618 
619 u_int8_t
620 gdt_pci_get_status(gdt)
621 	struct gdt_softc *gdt;
622 {
623 	/* XXX Not yet implemented */
624 	return (0);
625 }
626 
627 void
628 gdt_pci_intr(gdt, ctx)
629 	struct gdt_softc *gdt;
630 	struct gdt_intr_ctx *ctx;
631 {
632 	/* XXX Not yet implemented */
633 }
634 
635 void
636 gdt_pci_release_event(gdt, ccb)
637 	struct gdt_softc *gdt;
638 	struct gdt_ccb *ccb;
639 {
640 	/* XXX Not yet implemented */
641 }
642 
643 void
644 gdt_pci_set_sema0(gdt)
645 	struct gdt_softc *gdt;
646 {
647 	bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_SEMA0, 1);
648 }
649 
650 int
651 gdt_pci_test_busy(gdt)
652 	struct gdt_softc *gdt;
653 {
654 	/* XXX Not yet implemented */
655 	return (0);
656 }
657 
658 /*
659  * "new" PCI controller-specific functions
660  */
661 
662 void
663 gdt_pcinew_copy_cmd(gdt, ccb)
664 	struct gdt_softc *gdt;
665 	struct gdt_ccb *ccb;
666 {
667 	/* XXX Not yet implemented */
668 }
669 
670 u_int8_t
671 gdt_pcinew_get_status(gdt)
672 	struct gdt_softc *gdt;
673 {
674 	/* XXX Not yet implemented */
675 	return (0);
676 }
677 
678 void
679 gdt_pcinew_intr(gdt, ctx)
680 	struct gdt_softc *gdt;
681 	struct gdt_intr_ctx *ctx;
682 {
683 	/* XXX Not yet implemented */
684 }
685 
686 void
687 gdt_pcinew_release_event(gdt, ccb)
688 	struct gdt_softc *gdt;
689 	struct gdt_ccb *ccb;
690 {
691 	/* XXX Not yet implemented */
692 }
693 
694 void
695 gdt_pcinew_set_sema0(gdt)
696 	struct gdt_softc *gdt;
697 {
698 	bus_space_write_1(gdt->sc_iot, gdt->sc_ioh, GDT_SEMA0_REG, 1);
699 }
700 
701 int
702 gdt_pcinew_test_busy(gdt)
703 	struct gdt_softc *gdt;
704 {
705 	/* XXX Not yet implemented */
706 	return (0);
707 }
708 
709 /*
710  * MPR PCI controller-specific functions
711  */
712 
713 void
714 gdt_mpr_copy_cmd(gdt, ccb)
715 	struct gdt_softc *gdt;
716 	struct gdt_ccb *ccb;
717 {
718 	u_int16_t cp_count = roundup(gdt->sc_cmd_len, sizeof (u_int32_t));
719 	u_int16_t dp_offset = gdt->sc_cmd_off;
720 	u_int16_t cmd_no = gdt->sc_cmd_cnt++;
721 
722 	GDT_DPRINTF(GDT_D_CMD, ("gdt_mpr_copy_cmd(%p) ", gdt));
723 
724 	gdt->sc_cmd_off += cp_count;
725 
726 	bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh,
727 	    GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_OFFSET,
728 	    GDT_DPMEM_COMMAND_OFFSET + dp_offset);
729 	bus_space_write_2(gdt->sc_dpmemt, gdt->sc_dpmemh,
730 	    GDT_MPR_IC + GDT_COMM_QUEUE + cmd_no * GDT_COMM_Q_SZ + GDT_SERV_ID,
731 	    ccb->gc_service);
732 	bus_space_write_raw_region_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
733 	    GDT_MPR_IC + GDT_DPR_CMD + dp_offset, gdt->sc_cmd, cp_count);
734 }
735 
736 u_int8_t
737 gdt_mpr_get_status(gdt)
738 	struct gdt_softc *gdt;
739 {
740 	GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_get_status(%p) ", gdt));
741 
742 	return bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR);
743 }
744 
745 void
746 gdt_mpr_intr(gdt, ctx)
747 	struct gdt_softc *gdt;
748 	struct gdt_intr_ctx *ctx;
749 {
750 	GDT_DPRINTF(GDT_D_INTR, ("gdt_mpr_intr(%p) ", gdt));
751 
752 	if (ctx->istatus & 0x80) {		/* error flag */
753 		ctx->istatus &= ~0x80;
754 		ctx->cmd_status = bus_space_read_2(gdt->sc_dpmemt,
755 		    gdt->sc_dpmemh, GDT_MPR_STATUS);
756 		if (ctx->istatus == GDT_ASYNCINDEX) {
757 			ctx->service = bus_space_read_2(gdt->sc_dpmemt,
758 			    gdt->sc_dpmemh, GDT_MPR_SERVICE);
759 			ctx->info2 = bus_space_read_4(gdt->sc_dpmemt,
760 			    gdt->sc_dpmemh, GDT_MPR_INFO + sizeof (u_int32_t));
761 		}
762 	} else					/* no error */
763 		ctx->cmd_status = GDT_S_OK;
764 
765 	ctx->info =
766 	    bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_INFO);
767 
768 	if (gdt_polling)			/* init. -> more info */
769 		ctx->info2 = bus_space_read_4(gdt->sc_dpmemt, gdt->sc_dpmemh,
770 		    GDT_MPR_INFO + sizeof (u_int32_t));
771 	bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_EDOOR, 0xff);
772 	bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA1, 0);
773 }
774 
775 void
776 gdt_mpr_release_event(gdt, ccb)
777 	struct gdt_softc *gdt;
778 	struct gdt_ccb *ccb;
779 {
780 	GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_release_event(%p) ", gdt));
781 
782 	if (gdt_dec16(gdt->sc_cmd + GDT_CMD_OPCODE) == GDT_INIT)
783 		ccb->gc_service |= 0x80;
784 	bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_LDOOR, 1);
785 }
786 
787 void
788 gdt_mpr_set_sema0(gdt)
789 	struct gdt_softc *gdt;
790 {
791 	GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_set_sema0(%p) ", gdt));
792 
793 	bus_space_write_1(gdt->sc_dpmemt, gdt->sc_dpmemh, GDT_MPR_SEMA0, 1);
794 }
795 
796 int
797 gdt_mpr_test_busy(gdt)
798 	struct gdt_softc *gdt;
799 {
800 	GDT_DPRINTF(GDT_D_MISC, ("gdt_mpr_test_busy(%p) ", gdt));
801 
802 	return (bus_space_read_1(gdt->sc_dpmemt, gdt->sc_dpmemh,
803 	    GDT_MPR_SEMA0) & 1);
804 }
805