xref: /netbsd-src/sys/dev/ic/i82365.c (revision aa73cae19608873cc4d1f712c4a0f8f8435f1ffa)
1 /*	$NetBSD: i82365.c,v 1.89 2005/02/27 00:27:01 perry Exp $	*/
2 
3 /*
4  * Copyright (c) 2004 Charles M. Hannum.  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 Charles M. Hannum.
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 
21 /*
22  * Copyright (c) 2000 Christian E. Hopps.  All rights reserved.
23  * Copyright (c) 1997 Marc Horowitz.  All rights reserved.
24  *
25  * Redistribution and use in source and binary forms, with or without
26  * modification, are permitted provided that the following conditions
27  * are met:
28  * 1. Redistributions of source code must retain the above copyright
29  *    notice, this list of conditions and the following disclaimer.
30  * 2. Redistributions in binary form must reproduce the above copyright
31  *    notice, this list of conditions and the following disclaimer in the
32  *    documentation and/or other materials provided with the distribution.
33  * 3. All advertising materials mentioning features or use of this software
34  *    must display the following acknowledgement:
35  *	This product includes software developed by Marc Horowitz.
36  * 4. The name of the author may not be used to endorse or promote products
37  *    derived from this software without specific prior written permission.
38  *
39  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
40  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
41  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
42  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
43  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
44  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
45  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
46  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
47  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
48  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
49  */
50 
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: i82365.c,v 1.89 2005/02/27 00:27:01 perry Exp $");
53 
54 #define	PCICDEBUG
55 
56 #include <sys/param.h>
57 #include <sys/systm.h>
58 #include <sys/device.h>
59 #include <sys/extent.h>
60 #include <sys/kernel.h>
61 #include <sys/malloc.h>
62 #include <sys/kthread.h>
63 
64 #include <machine/bus.h>
65 #include <machine/intr.h>
66 
67 #include <dev/pcmcia/pcmciareg.h>
68 #include <dev/pcmcia/pcmciavar.h>
69 
70 #include <dev/ic/i82365reg.h>
71 #include <dev/ic/i82365var.h>
72 
73 #include "locators.h"
74 
75 #ifdef PCICDEBUG
76 int	pcic_debug = 0;
77 #define	DPRINTF(arg) if (pcic_debug) printf arg;
78 #else
79 #define	DPRINTF(arg)
80 #endif
81 
82 /*
83  * Individual drivers will allocate their own memory and io regions. Memory
84  * regions must be a multiple of 4k, aligned on a 4k boundary.
85  */
86 
87 #define	PCIC_MEM_ALIGN	PCIC_MEM_PAGESIZE
88 
89 void	pcic_attach_socket(struct pcic_handle *);
90 void	pcic_attach_socket_finish(struct pcic_handle *);
91 
92 int	pcic_submatch(struct device *, struct cfdata *,
93 			   const locdesc_t *, void *);
94 int	pcic_print (void *arg, const char *pnp);
95 int	pcic_intr_socket(struct pcic_handle *);
96 void	pcic_poll_intr(void *);
97 
98 void	pcic_attach_card(struct pcic_handle *);
99 void	pcic_detach_card(struct pcic_handle *, int);
100 void	pcic_deactivate_card(struct pcic_handle *);
101 
102 void	pcic_chip_do_mem_map(struct pcic_handle *, int);
103 void	pcic_chip_do_io_map(struct pcic_handle *, int);
104 
105 void	pcic_create_event_thread(void *);
106 void	pcic_event_thread(void *);
107 
108 void	pcic_queue_event(struct pcic_handle *, int);
109 void	pcic_power(int, void *);
110 
111 static int	pcic_wait_ready(struct pcic_handle *);
112 static void	pcic_delay(struct pcic_handle *, int, const char *);
113 
114 static u_int8_t st_pcic_read(struct pcic_handle *, int);
115 static void st_pcic_write(struct pcic_handle *, int, u_int8_t);
116 
117 int
118 pcic_ident_ok(ident)
119 	int ident;
120 {
121 	/* this is very empirical and heuristic */
122 
123 	if ((ident == 0) || (ident == 0xff) || (ident & PCIC_IDENT_ZERO))
124 		return (0);
125 
126 	if ((ident & PCIC_IDENT_REV_MASK) == 0)
127 		return (0);
128 
129 	if ((ident & PCIC_IDENT_IFTYPE_MASK) != PCIC_IDENT_IFTYPE_MEM_AND_IO) {
130 #ifdef DIAGNOSTIC
131 		printf("pcic: does not support memory and I/O cards, "
132 		    "ignored (ident=%0x)\n", ident);
133 #endif
134 		return (0);
135 	}
136 
137 	return (1);
138 }
139 
140 int
141 pcic_vendor(h)
142 	struct pcic_handle *h;
143 {
144 	int reg;
145 	int vendor;
146 
147 	reg = pcic_read(h, PCIC_IDENT);
148 
149 	if ((reg & PCIC_IDENT_REV_MASK) == 0)
150 		return (PCIC_VENDOR_NONE);
151 
152 	switch (reg) {
153 	case 0x00:
154 	case 0xff:
155 		return (PCIC_VENDOR_NONE);
156 	case PCIC_IDENT_ID_INTEL0:
157 		vendor = PCIC_VENDOR_I82365SLR0;
158 		break;
159 	case PCIC_IDENT_ID_INTEL1:
160 		vendor = PCIC_VENDOR_I82365SLR1;
161 		break;
162 	case PCIC_IDENT_ID_INTEL2:
163 		vendor = PCIC_VENDOR_I82365SL_DF;
164 		break;
165 	case PCIC_IDENT_ID_IBM1:
166 	case PCIC_IDENT_ID_IBM2:
167 		vendor = PCIC_VENDOR_IBM;
168 		break;
169 	case PCIC_IDENT_ID_IBM3:
170 		vendor = PCIC_VENDOR_IBM_KING;
171 		break;
172 	default:
173 		vendor = PCIC_VENDOR_UNKNOWN;
174 		break;
175 	}
176 
177 	if (vendor == PCIC_VENDOR_I82365SLR0 ||
178 	    vendor == PCIC_VENDOR_I82365SLR1) {
179 		/*
180 		 * Check for Cirrus PD67xx.
181 		 * the chip_id of the cirrus toggles between 11 and 00 after a
182 		 * write.  weird.
183 		 */
184 		pcic_write(h, PCIC_CIRRUS_CHIP_INFO, 0);
185 		reg = pcic_read(h, -1);
186 		if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) ==
187 		    PCIC_CIRRUS_CHIP_INFO_CHIP_ID) {
188 			reg = pcic_read(h, -1);
189 			if ((reg & PCIC_CIRRUS_CHIP_INFO_CHIP_ID) == 0)
190 				return (PCIC_VENDOR_CIRRUS_PD67XX);
191 		}
192 
193 		/*
194 		 * check for Ricoh RF5C[23]96
195 		 */
196 		reg = pcic_read(h, PCIC_RICOH_REG_CHIP_ID);
197 		switch (reg) {
198 		case PCIC_RICOH_CHIP_ID_5C296:
199 			return (PCIC_VENDOR_RICOH_5C296);
200 		case PCIC_RICOH_CHIP_ID_5C396:
201 			return (PCIC_VENDOR_RICOH_5C396);
202 		}
203 	}
204 
205 	return (vendor);
206 }
207 
208 char *
209 pcic_vendor_to_string(vendor)
210 	int vendor;
211 {
212 	switch (vendor) {
213 	case PCIC_VENDOR_I82365SLR0:
214 		return ("Intel 82365SL Revision 0");
215 	case PCIC_VENDOR_I82365SLR1:
216 		return ("Intel 82365SL Revision 1");
217 	case PCIC_VENDOR_CIRRUS_PD67XX:
218 		return ("Cirrus PD6710/2X");
219 	case PCIC_VENDOR_I82365SL_DF:
220 		return ("Intel 82365SL-DF");
221 	case PCIC_VENDOR_RICOH_5C296:
222 		return ("Ricoh RF5C296");
223 	case PCIC_VENDOR_RICOH_5C396:
224 		return ("Ricoh RF5C396");
225 	case PCIC_VENDOR_IBM:
226 		return ("IBM PCIC");
227 	case PCIC_VENDOR_IBM_KING:
228 		return ("IBM KING");
229 	}
230 
231 	return ("Unknown controller");
232 }
233 
234 void
235 pcic_attach(sc)
236 	struct pcic_softc *sc;
237 {
238 	int i, reg, chip, socket;
239 	struct pcic_handle *h;
240 
241 	DPRINTF(("pcic ident regs:"));
242 
243 	lockinit(&sc->sc_pcic_lock, PWAIT, "pciclk", 0, 0);
244 
245 	/* find and configure for the available sockets */
246 	for (i = 0; i < PCIC_NSLOTS; i++) {
247 		h = &sc->handle[i];
248 		chip = i / 2;
249 		socket = i % 2;
250 
251 		h->ph_parent = (struct device *)sc;
252 		h->chip = chip;
253 		h->socket = socket;
254 		h->sock = chip * PCIC_CHIP_OFFSET + socket * PCIC_SOCKET_OFFSET;
255 		h->laststate = PCIC_LASTSTATE_EMPTY;
256 		/* initialize pcic_read and pcic_write functions */
257 		h->ph_read = st_pcic_read;
258 		h->ph_write = st_pcic_write;
259 		h->ph_bus_t = sc->iot;
260 		h->ph_bus_h = sc->ioh;
261 		h->flags = 0;
262 
263 		/* need to read vendor -- for cirrus to report no xtra chip */
264 		if (socket == 0)
265 			h->vendor = (h+1)->vendor = pcic_vendor(h);
266 
267 		switch (h->vendor) {
268 		case PCIC_VENDOR_NONE:
269 			/* no chip */
270 			continue;
271 		case PCIC_VENDOR_CIRRUS_PD67XX:
272 			reg = pcic_read(h, PCIC_CIRRUS_CHIP_INFO);
273 			if (socket == 0 ||
274 			    (reg & PCIC_CIRRUS_CHIP_INFO_SLOTS))
275 				h->flags = PCIC_FLAG_SOCKETP;
276 			break;
277 		default:
278 			/*
279 			 * During the socket probe, read the ident register
280 			 * twice.  I don't understand why, but sometimes the
281 			 * clone chips in hpcmips boxes read all-0s the first
282 			 * time. -- mycroft
283 			 */
284 			reg = pcic_read(h, PCIC_IDENT);
285 			DPRINTF(("socket %d ident reg 0x%02x\n", i, reg));
286 			reg = pcic_read(h, PCIC_IDENT);
287 			DPRINTF(("socket %d ident reg 0x%02x\n", i, reg));
288 			if (pcic_ident_ok(reg))
289 				h->flags = PCIC_FLAG_SOCKETP;
290 			break;
291 		}
292 	}
293 
294 	for (i = 0; i < PCIC_NSLOTS; i++) {
295 		h = &sc->handle[i];
296 
297 		if (h->flags & PCIC_FLAG_SOCKETP) {
298 			SIMPLEQ_INIT(&h->events);
299 
300 			/* disable interrupts and leave socket in reset */
301 			pcic_write(h, PCIC_INTR, 0);
302 
303 			/* zero out the address windows */
304 			pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
305 
306 			/* power down the socket */
307 			pcic_write(h, PCIC_PWRCTL, 0);
308 
309 			pcic_write(h, PCIC_CSC_INTR, 0);
310 			(void) pcic_read(h, PCIC_CSC);
311 		}
312 	}
313 
314 	/* print detected info */
315 	for (i = 0; i < PCIC_NSLOTS; i += 2) {
316 		h = &sc->handle[i];
317 		chip = i / 2;
318 
319 		if (h->vendor == PCIC_VENDOR_NONE)
320 			continue;
321 
322 		aprint_normal("%s: controller %d (%s) has ", sc->dev.dv_xname,
323 		    chip, pcic_vendor_to_string(sc->handle[i].vendor));
324 
325 		if ((h->flags & PCIC_FLAG_SOCKETP) &&
326 		    ((h+1)->flags & PCIC_FLAG_SOCKETP))
327 			aprint_normal("sockets A and B\n");
328 		else if (h->flags & PCIC_FLAG_SOCKETP)
329 			aprint_normal("socket A only\n");
330 		else if ((h+1)->flags & PCIC_FLAG_SOCKETP)
331 			aprint_normal("socket B only\n");
332 		else
333 			aprint_normal("no sockets\n");
334 	}
335 }
336 
337 /*
338  * attach the sockets before we know what interrupts we have
339  */
340 void
341 pcic_attach_sockets(sc)
342 	struct pcic_softc *sc;
343 {
344 	int i;
345 
346 	for (i = 0; i < PCIC_NSLOTS; i++)
347 		if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
348 			pcic_attach_socket(&sc->handle[i]);
349 }
350 
351 void
352 pcic_power(why, arg)
353 	int why;
354 	void *arg;
355 {
356 	struct pcic_handle *h = (struct pcic_handle *)arg;
357 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
358 	int reg;
359 
360 	DPRINTF(("%s: power: why %d\n", h->ph_parent->dv_xname, why));
361 
362 	if (h->flags & PCIC_FLAG_SOCKETP) {
363 		if ((why == PWR_RESUME) &&
364 		    (pcic_read(h, PCIC_CSC_INTR) == 0)) {
365 #ifdef PCICDEBUG
366 			char bitbuf[64];
367 #endif
368 			reg = PCIC_CSC_INTR_CD_ENABLE;
369 			if (sc->irq != -1)
370 			    reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT;
371 			pcic_write(h, PCIC_CSC_INTR, reg);
372 			DPRINTF(("%s: CSC_INTR was zero; reset to %s\n",
373 			    sc->dev.dv_xname,
374 			    bitmask_snprintf(pcic_read(h, PCIC_CSC_INTR),
375 				PCIC_CSC_INTR_FORMAT,
376 				bitbuf, sizeof(bitbuf))));
377 		}
378 
379 		/*
380 		 * check for card insertion or removal during suspend period.
381 		 * XXX: the code can't cope with card swap (remove then insert).
382 		 * how can we detect such situation?
383 		 */
384 		if (why == PWR_RESUME)
385 			(void)pcic_intr_socket(h);
386 	}
387 }
388 
389 
390 /*
391  * attach a socket -- we don't know about irqs yet
392  */
393 void
394 pcic_attach_socket(h)
395 	struct pcic_handle *h;
396 {
397 	struct pcmciabus_attach_args paa;
398 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
399 	int help[3];
400 	locdesc_t *ldesc = (void *)help; /* XXX */
401 
402 	/* initialize the rest of the handle */
403 
404 	h->shutdown = 0;
405 	h->memalloc = 0;
406 	h->ioalloc = 0;
407 	h->ih_irq = 0;
408 
409 	/* now, config one pcmcia device per socket */
410 
411 	paa.paa_busname = "pcmcia";
412 	paa.pct = (pcmcia_chipset_tag_t) sc->pct;
413 	paa.pch = (pcmcia_chipset_handle_t) h;
414 	paa.iobase = sc->iobase;
415 	paa.iosize = sc->iosize;
416 
417 	ldesc->len = 2;
418 	ldesc->locs[PCMCIABUSCF_CONTROLLER] = h->chip;
419 	ldesc->locs[PCMCIABUSCF_SOCKET] = h->socket;
420 
421 	h->pcmcia = config_found_sm_loc(&sc->dev, "pcmciabus", ldesc, &paa,
422 					pcic_print, pcic_submatch);
423 	if (h->pcmcia == NULL) {
424 		h->flags &= ~PCIC_FLAG_SOCKETP;
425 		return;
426 	}
427 
428 	/*
429 	 * queue creation of a kernel thread to handle insert/removal events.
430 	 */
431 #ifdef DIAGNOSTIC
432 	if (h->event_thread != NULL)
433 		panic("pcic_attach_socket: event thread");
434 #endif
435 	config_pending_incr();
436 	kthread_create(pcic_create_event_thread, h);
437 }
438 
439 /*
440  * now finish attaching the sockets, we are ready to allocate
441  * interrupts
442  */
443 void
444 pcic_attach_sockets_finish(sc)
445 	struct pcic_softc *sc;
446 {
447 	int i;
448 
449 	for (i = 0; i < PCIC_NSLOTS; i++)
450 		if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
451 			pcic_attach_socket_finish(&sc->handle[i]);
452 }
453 
454 /*
455  * finishing attaching the socket.  Interrupts may now be on
456  * if so expects the pcic interrupt to be blocked
457  */
458 void
459 pcic_attach_socket_finish(h)
460 	struct pcic_handle *h;
461 {
462 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
463 	int reg;
464 
465 	DPRINTF(("%s: attach finish socket %ld\n", h->ph_parent->dv_xname,
466 	    (long) (h - &sc->handle[0])));
467 
468 	/*
469 	 * Set up a powerhook to ensure it continues to interrupt on
470 	 * card detect even after suspend.
471 	 * (this works around a bug seen in suspend-to-disk on the
472 	 * Sony VAIO Z505; on resume, the CSC_INTR state is not preserved).
473 	 */
474 	powerhook_establish(pcic_power, h);
475 
476 	/* enable interrupts on card detect, poll for them if no irq avail */
477 	reg = PCIC_CSC_INTR_CD_ENABLE;
478 	if (sc->irq == -1) {
479 		if (sc->poll_established == 0) {
480 			callout_init(&sc->poll_ch);
481 			callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc);
482 			sc->poll_established = 1;
483 		}
484 	} else
485 		reg |= sc->irq << PCIC_CSC_INTR_IRQ_SHIFT;
486 	pcic_write(h, PCIC_CSC_INTR, reg);
487 
488 	/* steer above mgmt interrupt to configured place */
489 	if (sc->irq == 0)
490 		pcic_write(h, PCIC_INTR, PCIC_INTR_ENABLE);
491 
492 	/* clear possible card detect interrupt */
493 	(void) pcic_read(h, PCIC_CSC);
494 
495 	DPRINTF(("%s: attach finish vendor 0x%02x\n", h->ph_parent->dv_xname,
496 	    h->vendor));
497 
498 	/* unsleep the cirrus controller */
499 	if (h->vendor == PCIC_VENDOR_CIRRUS_PD67XX) {
500 		reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_2);
501 		if (reg & PCIC_CIRRUS_MISC_CTL_2_SUSPEND) {
502 			DPRINTF(("%s: socket %02x was suspended\n",
503 			    h->ph_parent->dv_xname, h->sock));
504 			reg &= ~PCIC_CIRRUS_MISC_CTL_2_SUSPEND;
505 			pcic_write(h, PCIC_CIRRUS_MISC_CTL_2, reg);
506 		}
507 	}
508 
509 	/* if there's a card there, then attach it. */
510 	reg = pcic_read(h, PCIC_IF_STATUS);
511 	if ((reg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
512 	    PCIC_IF_STATUS_CARDDETECT_PRESENT) {
513 		pcic_queue_event(h, PCIC_EVENT_INSERTION);
514 		h->laststate = PCIC_LASTSTATE_PRESENT;
515 	} else {
516 		h->laststate = PCIC_LASTSTATE_EMPTY;
517 	}
518 }
519 
520 void
521 pcic_create_event_thread(arg)
522 	void *arg;
523 {
524 	struct pcic_handle *h = arg;
525 	char cs[4];
526 
527 	snprintf(cs, sizeof(cs), "%d,%d", h->chip, h->socket);
528 
529 	if (kthread_create1(pcic_event_thread, h, &h->event_thread,
530 	    "%s,%s", h->ph_parent->dv_xname, cs)) {
531 		printf("%s: unable to create event thread for sock 0x%02x\n",
532 		    h->ph_parent->dv_xname, h->sock);
533 		panic("pcic_create_event_thread");
534 	}
535 }
536 
537 void
538 pcic_event_thread(arg)
539 	void *arg;
540 {
541 	struct pcic_handle *h = arg;
542 	struct pcic_event *pe;
543 	int s, first = 1;
544 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
545 
546 	while (h->shutdown == 0) {
547 		/*
548 		 * Serialize event processing on the PCIC.  We may
549 		 * sleep while we hold this lock.
550 		 */
551 		(void) lockmgr(&sc->sc_pcic_lock, LK_EXCLUSIVE, NULL);
552 
553 		s = splhigh();
554 		if ((pe = SIMPLEQ_FIRST(&h->events)) == NULL) {
555 			splx(s);
556 			if (first) {
557 				first = 0;
558 				config_pending_decr();
559 			}
560 			/*
561 			 * No events to process; release the PCIC lock.
562 			 */
563 			(void) lockmgr(&sc->sc_pcic_lock, LK_RELEASE, NULL);
564 			(void) tsleep(&h->events, PWAIT, "pcicev", 0);
565 			continue;
566 		} else {
567 			splx(s);
568 			/* sleep .25s to be enqueued chatterling interrupts */
569 			(void) tsleep((caddr_t)pcic_event_thread, PWAIT,
570 			    "pcicss", hz/4);
571 		}
572 		s = splhigh();
573 		SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
574 		splx(s);
575 
576 		switch (pe->pe_type) {
577 		case PCIC_EVENT_INSERTION:
578 			s = splhigh();
579 			while (1) {
580 				struct pcic_event *pe1, *pe2;
581 
582 				if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
583 					break;
584 				if (pe1->pe_type != PCIC_EVENT_REMOVAL)
585 					break;
586 				if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
587 					break;
588 				if (pe2->pe_type == PCIC_EVENT_INSERTION) {
589 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
590 					free(pe1, M_TEMP);
591 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
592 					free(pe2, M_TEMP);
593 				}
594 			}
595 			splx(s);
596 
597 			DPRINTF(("%s: insertion event\n",
598 			    h->ph_parent->dv_xname));
599 			pcic_attach_card(h);
600 			break;
601 
602 		case PCIC_EVENT_REMOVAL:
603 			s = splhigh();
604 			while (1) {
605 				struct pcic_event *pe1, *pe2;
606 
607 				if ((pe1 = SIMPLEQ_FIRST(&h->events)) == NULL)
608 					break;
609 				if (pe1->pe_type != PCIC_EVENT_INSERTION)
610 					break;
611 				if ((pe2 = SIMPLEQ_NEXT(pe1, pe_q)) == NULL)
612 					break;
613 				if (pe2->pe_type == PCIC_EVENT_REMOVAL) {
614 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
615 					free(pe1, M_TEMP);
616 					SIMPLEQ_REMOVE_HEAD(&h->events, pe_q);
617 					free(pe2, M_TEMP);
618 				}
619 			}
620 			splx(s);
621 
622 			DPRINTF(("%s: removal event\n",
623 			    h->ph_parent->dv_xname));
624 			pcic_detach_card(h, DETACH_FORCE);
625 			break;
626 
627 		default:
628 			panic("pcic_event_thread: unknown event %d",
629 			    pe->pe_type);
630 		}
631 		free(pe, M_TEMP);
632 
633 		(void) lockmgr(&sc->sc_pcic_lock, LK_RELEASE, NULL);
634 	}
635 
636 	h->event_thread = NULL;
637 
638 	/* In case parent is waiting for us to exit. */
639 	wakeup(sc);
640 
641 	kthread_exit(0);
642 }
643 
644 int
645 pcic_submatch(parent, cf, ldesc, aux)
646 	struct device *parent;
647 	struct cfdata *cf;
648 	const locdesc_t *ldesc;
649 	void *aux;
650 {
651 
652 	if (cf->cf_loc[PCMCIABUSCF_CONTROLLER] != PCMCIABUSCF_CONTROLLER_DEFAULT &&
653 	    cf->cf_loc[PCMCIABUSCF_CONTROLLER] != ldesc->locs[PCMCIABUSCF_CONTROLLER])
654 			return 0;
655 	if (cf->cf_loc[PCMCIABUSCF_SOCKET] != PCMCIABUSCF_SOCKET_DEFAULT &&
656 	    cf->cf_loc[PCMCIABUSCF_SOCKET] != ldesc->locs[PCMCIABUSCF_SOCKET])
657 			return 0;
658 
659 	return (config_match(parent, cf, aux));
660 }
661 
662 int
663 pcic_print(arg, pnp)
664 	void *arg;
665 	const char *pnp;
666 {
667 	struct pcmciabus_attach_args *paa = arg;
668 	struct pcic_handle *h = (struct pcic_handle *) paa->pch;
669 
670 	/* Only "pcmcia"s can attach to "pcic"s... easy. */
671 	if (pnp)
672 		aprint_normal("pcmcia at %s", pnp);
673 
674 	aprint_normal(" controller %d socket %d", h->chip, h->socket);
675 
676 	return (UNCONF);
677 }
678 
679 void
680 pcic_poll_intr(arg)
681 	void *arg;
682 {
683 	struct pcic_softc *sc;
684 	int i, s;
685 
686 	s = spltty();
687 	sc = arg;
688 	for (i = 0; i < PCIC_NSLOTS; i++)
689 		if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
690 			(void)pcic_intr_socket(&sc->handle[i]);
691 	callout_reset(&sc->poll_ch, hz / 2, pcic_poll_intr, sc);
692 	splx(s);
693 }
694 
695 int
696 pcic_intr(arg)
697 	void *arg;
698 {
699 	struct pcic_softc *sc = arg;
700 	int i, ret = 0;
701 
702 	DPRINTF(("%s: intr\n", sc->dev.dv_xname));
703 
704 	for (i = 0; i < PCIC_NSLOTS; i++)
705 		if (sc->handle[i].flags & PCIC_FLAG_SOCKETP)
706 			ret += pcic_intr_socket(&sc->handle[i]);
707 
708 	return (ret ? 1 : 0);
709 }
710 
711 int
712 pcic_intr_socket(h)
713 	struct pcic_handle *h;
714 {
715 	int cscreg;
716 
717 	cscreg = pcic_read(h, PCIC_CSC);
718 
719 	cscreg &= (PCIC_CSC_GPI |
720 		   PCIC_CSC_CD |
721 		   PCIC_CSC_READY |
722 		   PCIC_CSC_BATTWARN |
723 		   PCIC_CSC_BATTDEAD);
724 
725 	if (cscreg & PCIC_CSC_GPI) {
726 		DPRINTF(("%s: %02x GPI\n", h->ph_parent->dv_xname, h->sock));
727 	}
728 	if (cscreg & PCIC_CSC_CD) {
729 		int statreg;
730 
731 		statreg = pcic_read(h, PCIC_IF_STATUS);
732 
733 		DPRINTF(("%s: %02x CD %x\n", h->ph_parent->dv_xname, h->sock,
734 		    statreg));
735 
736 		if ((statreg & PCIC_IF_STATUS_CARDDETECT_MASK) ==
737 		    PCIC_IF_STATUS_CARDDETECT_PRESENT) {
738 			if (h->laststate != PCIC_LASTSTATE_PRESENT) {
739 				DPRINTF(("%s: enqueing INSERTION event\n",
740 					 h->ph_parent->dv_xname));
741 				pcic_queue_event(h, PCIC_EVENT_INSERTION);
742 			}
743 			h->laststate = PCIC_LASTSTATE_PRESENT;
744 		} else {
745 			if (h->laststate == PCIC_LASTSTATE_PRESENT) {
746 				/* Deactivate the card now. */
747 				DPRINTF(("%s: deactivating card\n",
748 					 h->ph_parent->dv_xname));
749 				pcic_deactivate_card(h);
750 
751 				DPRINTF(("%s: enqueing REMOVAL event\n",
752 					 h->ph_parent->dv_xname));
753 				pcic_queue_event(h, PCIC_EVENT_REMOVAL);
754 			}
755 			h->laststate = PCIC_LASTSTATE_EMPTY;
756 		}
757 	}
758 	if (cscreg & PCIC_CSC_READY) {
759 		DPRINTF(("%s: %02x READY\n", h->ph_parent->dv_xname, h->sock));
760 		/* shouldn't happen */
761 	}
762 	if (cscreg & PCIC_CSC_BATTWARN) {
763 		DPRINTF(("%s: %02x BATTWARN\n", h->ph_parent->dv_xname,
764 		    h->sock));
765 	}
766 	if (cscreg & PCIC_CSC_BATTDEAD) {
767 		DPRINTF(("%s: %02x BATTDEAD\n", h->ph_parent->dv_xname,
768 		    h->sock));
769 	}
770 	return (cscreg ? 1 : 0);
771 }
772 
773 void
774 pcic_queue_event(h, event)
775 	struct pcic_handle *h;
776 	int event;
777 {
778 	struct pcic_event *pe;
779 	int s;
780 
781 	pe = malloc(sizeof(*pe), M_TEMP, M_NOWAIT);
782 	if (pe == NULL)
783 		panic("pcic_queue_event: can't allocate event");
784 
785 	pe->pe_type = event;
786 	s = splhigh();
787 	SIMPLEQ_INSERT_TAIL(&h->events, pe, pe_q);
788 	splx(s);
789 	wakeup(&h->events);
790 }
791 
792 void
793 pcic_attach_card(h)
794 	struct pcic_handle *h;
795 {
796 
797 	if (!(h->flags & PCIC_FLAG_CARDP)) {
798 		/* call the MI attach function */
799 		pcmcia_card_attach(h->pcmcia);
800 
801 		h->flags |= PCIC_FLAG_CARDP;
802 	} else {
803 		DPRINTF(("pcic_attach_card: already attached"));
804 	}
805 }
806 
807 void
808 pcic_detach_card(h, flags)
809 	struct pcic_handle *h;
810 	int flags;		/* DETACH_* */
811 {
812 
813 	if (h->flags & PCIC_FLAG_CARDP) {
814 		h->flags &= ~PCIC_FLAG_CARDP;
815 
816 		/* call the MI detach function */
817 		pcmcia_card_detach(h->pcmcia, flags);
818 	} else {
819 		DPRINTF(("pcic_detach_card: already detached"));
820 	}
821 }
822 
823 void
824 pcic_deactivate_card(h)
825 	struct pcic_handle *h;
826 {
827 	int intr;
828 
829 	/* call the MI deactivate function */
830 	pcmcia_card_deactivate(h->pcmcia);
831 
832 	/* reset the socket */
833 	intr = pcic_read(h, PCIC_INTR);
834 	intr &= PCIC_INTR_ENABLE;
835 	pcic_write(h, PCIC_INTR, intr);
836 
837 	/* power down the socket */
838 	pcic_write(h, PCIC_PWRCTL, 0);
839 }
840 
841 int
842 pcic_chip_mem_alloc(pch, size, pcmhp)
843 	pcmcia_chipset_handle_t pch;
844 	bus_size_t size;
845 	struct pcmcia_mem_handle *pcmhp;
846 {
847 	struct pcic_handle *h = (struct pcic_handle *) pch;
848 	bus_space_handle_t memh;
849 	bus_addr_t addr;
850 	bus_size_t sizepg;
851 	int i, mask, mhandle;
852 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
853 
854 	/* out of sc->memh, allocate as many pages as necessary */
855 
856 	/* convert size to PCIC pages */
857 	sizepg = (size + (PCIC_MEM_ALIGN - 1)) / PCIC_MEM_ALIGN;
858 	if (sizepg > PCIC_MAX_MEM_PAGES)
859 		return (1);
860 
861 	mask = (1 << sizepg) - 1;
862 
863 	addr = 0;		/* XXX gcc -Wuninitialized */
864 	mhandle = 0;		/* XXX gcc -Wuninitialized */
865 
866 	for (i = 0; i <= PCIC_MAX_MEM_PAGES - sizepg; i++) {
867 		if ((sc->subregionmask & (mask << i)) == (mask << i)) {
868 			if (bus_space_subregion(sc->memt, sc->memh,
869 			    i * PCIC_MEM_PAGESIZE,
870 			    sizepg * PCIC_MEM_PAGESIZE, &memh))
871 				return (1);
872 			mhandle = mask << i;
873 			addr = sc->membase + (i * PCIC_MEM_PAGESIZE);
874 			sc->subregionmask &= ~(mhandle);
875 			pcmhp->memt = sc->memt;
876 			pcmhp->memh = memh;
877 			pcmhp->addr = addr;
878 			pcmhp->size = size;
879 			pcmhp->mhandle = mhandle;
880 			pcmhp->realsize = sizepg * PCIC_MEM_PAGESIZE;
881 			return (0);
882 		}
883 	}
884 
885 	return (1);
886 }
887 
888 void
889 pcic_chip_mem_free(pch, pcmhp)
890 	pcmcia_chipset_handle_t pch;
891 	struct pcmcia_mem_handle *pcmhp;
892 {
893 	struct pcic_handle *h = (struct pcic_handle *) pch;
894 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
895 
896 	sc->subregionmask |= pcmhp->mhandle;
897 }
898 
899 static const struct mem_map_index_st {
900 	int	sysmem_start_lsb;
901 	int	sysmem_start_msb;
902 	int	sysmem_stop_lsb;
903 	int	sysmem_stop_msb;
904 	int	cardmem_lsb;
905 	int	cardmem_msb;
906 	int	memenable;
907 } mem_map_index[] = {
908 	{
909 		PCIC_SYSMEM_ADDR0_START_LSB,
910 		PCIC_SYSMEM_ADDR0_START_MSB,
911 		PCIC_SYSMEM_ADDR0_STOP_LSB,
912 		PCIC_SYSMEM_ADDR0_STOP_MSB,
913 		PCIC_CARDMEM_ADDR0_LSB,
914 		PCIC_CARDMEM_ADDR0_MSB,
915 		PCIC_ADDRWIN_ENABLE_MEM0,
916 	},
917 	{
918 		PCIC_SYSMEM_ADDR1_START_LSB,
919 		PCIC_SYSMEM_ADDR1_START_MSB,
920 		PCIC_SYSMEM_ADDR1_STOP_LSB,
921 		PCIC_SYSMEM_ADDR1_STOP_MSB,
922 		PCIC_CARDMEM_ADDR1_LSB,
923 		PCIC_CARDMEM_ADDR1_MSB,
924 		PCIC_ADDRWIN_ENABLE_MEM1,
925 	},
926 	{
927 		PCIC_SYSMEM_ADDR2_START_LSB,
928 		PCIC_SYSMEM_ADDR2_START_MSB,
929 		PCIC_SYSMEM_ADDR2_STOP_LSB,
930 		PCIC_SYSMEM_ADDR2_STOP_MSB,
931 		PCIC_CARDMEM_ADDR2_LSB,
932 		PCIC_CARDMEM_ADDR2_MSB,
933 		PCIC_ADDRWIN_ENABLE_MEM2,
934 	},
935 	{
936 		PCIC_SYSMEM_ADDR3_START_LSB,
937 		PCIC_SYSMEM_ADDR3_START_MSB,
938 		PCIC_SYSMEM_ADDR3_STOP_LSB,
939 		PCIC_SYSMEM_ADDR3_STOP_MSB,
940 		PCIC_CARDMEM_ADDR3_LSB,
941 		PCIC_CARDMEM_ADDR3_MSB,
942 		PCIC_ADDRWIN_ENABLE_MEM3,
943 	},
944 	{
945 		PCIC_SYSMEM_ADDR4_START_LSB,
946 		PCIC_SYSMEM_ADDR4_START_MSB,
947 		PCIC_SYSMEM_ADDR4_STOP_LSB,
948 		PCIC_SYSMEM_ADDR4_STOP_MSB,
949 		PCIC_CARDMEM_ADDR4_LSB,
950 		PCIC_CARDMEM_ADDR4_MSB,
951 		PCIC_ADDRWIN_ENABLE_MEM4,
952 	},
953 };
954 
955 void
956 pcic_chip_do_mem_map(h, win)
957 	struct pcic_handle *h;
958 	int win;
959 {
960 	int reg;
961 	int kind = h->mem[win].kind & ~PCMCIA_WIDTH_MEM_MASK;
962 	int mem8 =
963 	    (h->mem[win].kind & PCMCIA_WIDTH_MEM_MASK) == PCMCIA_WIDTH_MEM8
964 	    || (kind == PCMCIA_MEM_ATTR);
965 
966 	DPRINTF(("mem8 %d\n", mem8));
967 	/* mem8 = 1; */
968 
969 	pcic_write(h, mem_map_index[win].sysmem_start_lsb,
970 	    (h->mem[win].addr >> PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
971 	pcic_write(h, mem_map_index[win].sysmem_start_msb,
972 	    ((h->mem[win].addr >> (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
973 	    PCIC_SYSMEM_ADDRX_START_MSB_ADDR_MASK) |
974 	    (mem8 ? 0 : PCIC_SYSMEM_ADDRX_START_MSB_DATASIZE_16BIT));
975 
976 	pcic_write(h, mem_map_index[win].sysmem_stop_lsb,
977 	    ((h->mem[win].addr + h->mem[win].size) >>
978 	    PCIC_SYSMEM_ADDRX_SHIFT) & 0xff);
979 	pcic_write(h, mem_map_index[win].sysmem_stop_msb,
980 	    (((h->mem[win].addr + h->mem[win].size) >>
981 	    (PCIC_SYSMEM_ADDRX_SHIFT + 8)) &
982 	    PCIC_SYSMEM_ADDRX_STOP_MSB_ADDR_MASK) |
983 	    PCIC_SYSMEM_ADDRX_STOP_MSB_WAIT2);
984 
985 	pcic_write(h, mem_map_index[win].cardmem_lsb,
986 	    (h->mem[win].offset >> PCIC_CARDMEM_ADDRX_SHIFT) & 0xff);
987 	pcic_write(h, mem_map_index[win].cardmem_msb,
988 	    ((h->mem[win].offset >> (PCIC_CARDMEM_ADDRX_SHIFT + 8)) &
989 	    PCIC_CARDMEM_ADDRX_MSB_ADDR_MASK) |
990 	    ((kind == PCMCIA_MEM_ATTR) ?
991 	    PCIC_CARDMEM_ADDRX_MSB_REGACTIVE_ATTR : 0));
992 
993 	reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
994 	reg |= (mem_map_index[win].memenable | PCIC_ADDRWIN_ENABLE_MEMCS16);
995 	pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
996 
997 	delay(100);
998 
999 #ifdef PCICDEBUG
1000 	{
1001 		int r1, r2, r3, r4, r5, r6;
1002 
1003 		r1 = pcic_read(h, mem_map_index[win].sysmem_start_msb);
1004 		r2 = pcic_read(h, mem_map_index[win].sysmem_start_lsb);
1005 		r3 = pcic_read(h, mem_map_index[win].sysmem_stop_msb);
1006 		r4 = pcic_read(h, mem_map_index[win].sysmem_stop_lsb);
1007 		r5 = pcic_read(h, mem_map_index[win].cardmem_msb);
1008 		r6 = pcic_read(h, mem_map_index[win].cardmem_lsb);
1009 
1010 		DPRINTF(("pcic_chip_do_mem_map window %d: %02x%02x %02x%02x "
1011 		    "%02x%02x\n", win, r1, r2, r3, r4, r5, r6));
1012 	}
1013 #endif
1014 }
1015 
1016 int
1017 pcic_chip_mem_map(pch, kind, card_addr, size, pcmhp, offsetp, windowp)
1018 	pcmcia_chipset_handle_t pch;
1019 	int kind;
1020 	bus_addr_t card_addr;
1021 	bus_size_t size;
1022 	struct pcmcia_mem_handle *pcmhp;
1023 	bus_size_t *offsetp;
1024 	int *windowp;
1025 {
1026 	struct pcic_handle *h = (struct pcic_handle *) pch;
1027 	bus_addr_t busaddr;
1028 	long card_offset;
1029 	int i, win;
1030 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
1031 
1032 	win = -1;
1033 	for (i = 0; i < (sizeof(mem_map_index) / sizeof(mem_map_index[0]));
1034 	    i++) {
1035 		if ((h->memalloc & (1 << i)) == 0) {
1036 			win = i;
1037 			h->memalloc |= (1 << i);
1038 			break;
1039 		}
1040 	}
1041 
1042 	if (win == -1)
1043 		return (1);
1044 
1045 	*windowp = win;
1046 
1047 	/* XXX this is pretty gross */
1048 
1049 	if (sc->memt != pcmhp->memt)
1050 		panic("pcic_chip_mem_map memt is bogus");
1051 
1052 	busaddr = pcmhp->addr;
1053 
1054 	/*
1055 	 * compute the address offset to the pcmcia address space for the
1056 	 * pcic.  this is intentionally signed.  The masks and shifts below
1057 	 * will cause TRT to happen in the pcic registers.  Deal with making
1058 	 * sure the address is aligned, and return the alignment offset.
1059 	 */
1060 
1061 	*offsetp = card_addr % PCIC_MEM_ALIGN;
1062 	card_addr -= *offsetp;
1063 
1064 	DPRINTF(("pcic_chip_mem_map window %d bus %lx+%lx+%lx at card addr "
1065 	    "%lx\n", win, (u_long) busaddr, (u_long) * offsetp, (u_long) size,
1066 	    (u_long) card_addr));
1067 
1068 	/*
1069 	 * include the offset in the size, and decrement size by one, since
1070 	 * the hw wants start/stop
1071 	 */
1072 	size += *offsetp - 1;
1073 
1074 	card_offset = (((long) card_addr) - ((long) busaddr));
1075 
1076 	h->mem[win].addr = busaddr;
1077 	h->mem[win].size = size;
1078 	h->mem[win].offset = card_offset;
1079 	h->mem[win].kind = kind;
1080 
1081 	pcic_chip_do_mem_map(h, win);
1082 
1083 	return (0);
1084 }
1085 
1086 void
1087 pcic_chip_mem_unmap(pch, window)
1088 	pcmcia_chipset_handle_t pch;
1089 	int window;
1090 {
1091 	struct pcic_handle *h = (struct pcic_handle *) pch;
1092 	int reg;
1093 
1094 	if (window >= (sizeof(mem_map_index) / sizeof(mem_map_index[0])))
1095 		panic("pcic_chip_mem_unmap: window out of range");
1096 
1097 	reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1098 	reg &= ~mem_map_index[window].memenable;
1099 	pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1100 
1101 	h->memalloc &= ~(1 << window);
1102 }
1103 
1104 int
1105 pcic_chip_io_alloc(pch, start, size, align, pcihp)
1106 	pcmcia_chipset_handle_t pch;
1107 	bus_addr_t start;
1108 	bus_size_t size;
1109 	bus_size_t align;
1110 	struct pcmcia_io_handle *pcihp;
1111 {
1112 	struct pcic_handle *h = (struct pcic_handle *) pch;
1113 	bus_space_tag_t iot;
1114 	bus_space_handle_t ioh;
1115 	bus_addr_t ioaddr;
1116 	int flags = 0;
1117 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
1118 
1119 	/*
1120 	 * Allocate some arbitrary I/O space.
1121 	 */
1122 
1123 	iot = sc->iot;
1124 
1125 	if (start) {
1126 		ioaddr = start;
1127 		if (bus_space_map(iot, start, size, 0, &ioh))
1128 			return (1);
1129 		DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
1130 		    (u_long) ioaddr, (u_long) size));
1131 	} else {
1132 		flags |= PCMCIA_IO_ALLOCATED;
1133 		if (bus_space_alloc(iot, sc->iobase,
1134 		    sc->iobase + sc->iosize, size, align, 0, 0,
1135 		    &ioaddr, &ioh))
1136 			return (1);
1137 		DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
1138 		    (u_long) ioaddr, (u_long) size));
1139 	}
1140 
1141 	pcihp->iot = iot;
1142 	pcihp->ioh = ioh;
1143 	pcihp->addr = ioaddr;
1144 	pcihp->size = size;
1145 	pcihp->flags = flags;
1146 
1147 	return (0);
1148 }
1149 
1150 void
1151 pcic_chip_io_free(pch, pcihp)
1152 	pcmcia_chipset_handle_t pch;
1153 	struct pcmcia_io_handle *pcihp;
1154 {
1155 	bus_space_tag_t iot = pcihp->iot;
1156 	bus_space_handle_t ioh = pcihp->ioh;
1157 	bus_size_t size = pcihp->size;
1158 
1159 	if (pcihp->flags & PCMCIA_IO_ALLOCATED)
1160 		bus_space_free(iot, ioh, size);
1161 	else
1162 		bus_space_unmap(iot, ioh, size);
1163 }
1164 
1165 
1166 static const struct io_map_index_st {
1167 	int	start_lsb;
1168 	int	start_msb;
1169 	int	stop_lsb;
1170 	int	stop_msb;
1171 	int	ioenable;
1172 	int	ioctlmask;
1173 	int	ioctlbits[3];		/* indexed by PCMCIA_WIDTH_* */
1174 }               io_map_index[] = {
1175 	{
1176 		PCIC_IOADDR0_START_LSB,
1177 		PCIC_IOADDR0_START_MSB,
1178 		PCIC_IOADDR0_STOP_LSB,
1179 		PCIC_IOADDR0_STOP_MSB,
1180 		PCIC_ADDRWIN_ENABLE_IO0,
1181 		PCIC_IOCTL_IO0_WAITSTATE | PCIC_IOCTL_IO0_ZEROWAIT |
1182 		PCIC_IOCTL_IO0_IOCS16SRC_MASK | PCIC_IOCTL_IO0_DATASIZE_MASK,
1183 		{
1184 			PCIC_IOCTL_IO0_IOCS16SRC_CARD,
1185 			PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
1186 			    PCIC_IOCTL_IO0_DATASIZE_8BIT,
1187 			PCIC_IOCTL_IO0_IOCS16SRC_DATASIZE |
1188 			    PCIC_IOCTL_IO0_DATASIZE_16BIT,
1189 		},
1190 	},
1191 	{
1192 		PCIC_IOADDR1_START_LSB,
1193 		PCIC_IOADDR1_START_MSB,
1194 		PCIC_IOADDR1_STOP_LSB,
1195 		PCIC_IOADDR1_STOP_MSB,
1196 		PCIC_ADDRWIN_ENABLE_IO1,
1197 		PCIC_IOCTL_IO1_WAITSTATE | PCIC_IOCTL_IO1_ZEROWAIT |
1198 		PCIC_IOCTL_IO1_IOCS16SRC_MASK | PCIC_IOCTL_IO1_DATASIZE_MASK,
1199 		{
1200 			PCIC_IOCTL_IO1_IOCS16SRC_CARD,
1201 			PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
1202 			    PCIC_IOCTL_IO1_DATASIZE_8BIT,
1203 			PCIC_IOCTL_IO1_IOCS16SRC_DATASIZE |
1204 			    PCIC_IOCTL_IO1_DATASIZE_16BIT,
1205 		},
1206 	},
1207 };
1208 
1209 void
1210 pcic_chip_do_io_map(h, win)
1211 	struct pcic_handle *h;
1212 	int win;
1213 {
1214 	int reg;
1215 
1216 	DPRINTF(("pcic_chip_do_io_map win %d addr %lx size %lx width %d\n",
1217 	    win, (long) h->io[win].addr, (long) h->io[win].size,
1218 	    h->io[win].width * 8));
1219 
1220 	pcic_write(h, io_map_index[win].start_lsb, h->io[win].addr & 0xff);
1221 	pcic_write(h, io_map_index[win].start_msb,
1222 	    (h->io[win].addr >> 8) & 0xff);
1223 
1224 	pcic_write(h, io_map_index[win].stop_lsb,
1225 	    (h->io[win].addr + h->io[win].size - 1) & 0xff);
1226 	pcic_write(h, io_map_index[win].stop_msb,
1227 	    ((h->io[win].addr + h->io[win].size - 1) >> 8) & 0xff);
1228 
1229 	reg = pcic_read(h, PCIC_IOCTL);
1230 	reg &= ~io_map_index[win].ioctlmask;
1231 	reg |= io_map_index[win].ioctlbits[h->io[win].width];
1232 	pcic_write(h, PCIC_IOCTL, reg);
1233 
1234 	reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1235 	reg |= io_map_index[win].ioenable;
1236 	pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1237 }
1238 
1239 int
1240 pcic_chip_io_map(pch, width, offset, size, pcihp, windowp)
1241 	pcmcia_chipset_handle_t pch;
1242 	int width;
1243 	bus_addr_t offset;
1244 	bus_size_t size;
1245 	struct pcmcia_io_handle *pcihp;
1246 	int *windowp;
1247 {
1248 	struct pcic_handle *h = (struct pcic_handle *) pch;
1249 	bus_addr_t ioaddr = pcihp->addr + offset;
1250 	int i, win;
1251 #ifdef PCICDEBUG
1252 	static char *width_names[] = { "auto", "io8", "io16" };
1253 #endif
1254 	struct pcic_softc *sc = (struct pcic_softc *)h->ph_parent;
1255 
1256 	/* XXX Sanity check offset/size. */
1257 
1258 	win = -1;
1259 	for (i = 0; i < (sizeof(io_map_index) / sizeof(io_map_index[0])); i++) {
1260 		if ((h->ioalloc & (1 << i)) == 0) {
1261 			win = i;
1262 			h->ioalloc |= (1 << i);
1263 			break;
1264 		}
1265 	}
1266 
1267 	if (win == -1)
1268 		return (1);
1269 
1270 	*windowp = win;
1271 
1272 	/* XXX this is pretty gross */
1273 
1274 	if (sc->iot != pcihp->iot)
1275 		panic("pcic_chip_io_map iot is bogus");
1276 
1277 	DPRINTF(("pcic_chip_io_map window %d %s port %lx+%lx\n",
1278 		 win, width_names[width], (u_long) ioaddr, (u_long) size));
1279 
1280 	/* XXX wtf is this doing here? */
1281 
1282 	printf("%s: port 0x%lx", sc->dev.dv_xname, (u_long) ioaddr);
1283 	if (size > 1)
1284 		printf("-0x%lx", (u_long) ioaddr + (u_long) size - 1);
1285 	printf("\n");
1286 
1287 	h->io[win].addr = ioaddr;
1288 	h->io[win].size = size;
1289 	h->io[win].width = width;
1290 
1291 	pcic_chip_do_io_map(h, win);
1292 
1293 	return (0);
1294 }
1295 
1296 void
1297 pcic_chip_io_unmap(pch, window)
1298 	pcmcia_chipset_handle_t pch;
1299 	int window;
1300 {
1301 	struct pcic_handle *h = (struct pcic_handle *) pch;
1302 	int reg;
1303 
1304 	if (window >= (sizeof(io_map_index) / sizeof(io_map_index[0])))
1305 		panic("pcic_chip_io_unmap: window out of range");
1306 
1307 	reg = pcic_read(h, PCIC_ADDRWIN_ENABLE);
1308 	reg &= ~io_map_index[window].ioenable;
1309 	pcic_write(h, PCIC_ADDRWIN_ENABLE, reg);
1310 
1311 	h->ioalloc &= ~(1 << window);
1312 }
1313 
1314 static int
1315 pcic_wait_ready(h)
1316 	struct pcic_handle *h;
1317 {
1318 	u_int8_t stat;
1319 	int i;
1320 
1321 	/* wait an initial 10ms for quick cards */
1322 	stat = pcic_read(h, PCIC_IF_STATUS);
1323 	if (stat & PCIC_IF_STATUS_READY)
1324 		return (0);
1325 	pcic_delay(h, 10, "pccwr0");
1326 	for (i = 0; i < 50; i++) {
1327 		stat = pcic_read(h, PCIC_IF_STATUS);
1328 		if (stat & PCIC_IF_STATUS_READY)
1329 			return (0);
1330 		if ((stat & PCIC_IF_STATUS_CARDDETECT_MASK) !=
1331 		    PCIC_IF_STATUS_CARDDETECT_PRESENT)
1332 			return (ENXIO);
1333 		/* wait .1s (100ms) each iteration now */
1334 		pcic_delay(h, 100, "pccwr1");
1335 	}
1336 
1337 	printf("pcic_wait_ready: ready never happened, status=%02x\n", stat);
1338 	return (EWOULDBLOCK);
1339 }
1340 
1341 /*
1342  * Perform long (msec order) delay.
1343  */
1344 static void
1345 pcic_delay(h, timo, wmesg)
1346 	struct pcic_handle *h;
1347 	int timo;			/* in ms.  must not be zero */
1348 	const char *wmesg;
1349 {
1350 
1351 #ifdef DIAGNOSTIC
1352 	if (timo <= 0)
1353 		panic("pcic_delay: called with timeout %d", timo);
1354 	if (!curlwp)
1355 		panic("pcic_delay: called in interrupt context");
1356 	if (!h->event_thread)
1357 		panic("pcic_delay: no event thread");
1358 #endif
1359 	DPRINTF(("pcic_delay: \"%s\" %p, sleep %d ms\n",
1360 	    wmesg, h->event_thread, timo));
1361 	tsleep(pcic_delay, PWAIT, wmesg, roundup(timo * hz, 1000) / 1000);
1362 }
1363 
1364 void
1365 pcic_chip_socket_enable(pch)
1366 	pcmcia_chipset_handle_t pch;
1367 {
1368 	struct pcic_handle *h = (struct pcic_handle *) pch;
1369 	int win;
1370 	u_int8_t power, intr;
1371 #ifdef DIAGNOSTIC
1372 	int reg;
1373 #endif
1374 
1375 #ifdef DIAGNOSTIC
1376 	if (h->flags & PCIC_FLAG_ENABLED)
1377 		printf("pcic_chip_socket_enable: enabling twice\n");
1378 #endif
1379 
1380 	/* disable interrupts; assert RESET */
1381 	intr = pcic_read(h, PCIC_INTR);
1382 	intr &= PCIC_INTR_ENABLE;
1383 	pcic_write(h, PCIC_INTR, intr);
1384 
1385 	/* zero out the address windows */
1386 	pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
1387 
1388 	/* power off; assert output enable bit */
1389 	power = PCIC_PWRCTL_OE;
1390 	pcic_write(h, PCIC_PWRCTL, power);
1391 
1392 	/*
1393 	 * power hack for RICOH RF5C[23]96
1394 	 */
1395 	switch( h->vendor ) {
1396 	case PCIC_VENDOR_RICOH_5C296:
1397 	case PCIC_VENDOR_RICOH_5C396:
1398 	{
1399 		int regtmp;
1400 		regtmp = pcic_read(h, PCIC_RICOH_REG_MCR2);
1401 #ifdef RICOH_POWER_HACK
1402 		regtmp |= PCIC_RICOH_MCR2_VCC_DIRECT;
1403 #else
1404 		regtmp &= ~(PCIC_RICOH_MCR2_VCC_DIRECT|PCIC_RICOH_MCR2_VCC_SEL_3V);
1405 #endif
1406 		pcic_write(h, PCIC_RICOH_REG_MCR2, regtmp);
1407 	}
1408 		break;
1409 	default:
1410 		break;
1411 	}
1412 
1413 #ifdef VADEM_POWER_HACK
1414 	bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x0e);
1415 	bus_space_write_1(sc->iot, sc->ioh, PCIC_REG_INDEX, 0x37);
1416 	printf("prcr = %02x\n", pcic_read(h, 0x02));
1417 	printf("cvsr = %02x\n", pcic_read(h, 0x2f));
1418 	printf("DANGER WILL ROBINSON!  Changing voltage select!\n");
1419 	pcic_write(h, 0x2f, pcic_read(h, 0x2f) & ~0x03);
1420 	printf("cvsr = %02x\n", pcic_read(h, 0x2f));
1421 #endif
1422 
1423 	/* power up the socket */
1424 	power |= PCIC_PWRCTL_PWR_ENABLE | PCIC_PWRCTL_VPP1_VCC;
1425 	pcic_write(h, PCIC_PWRCTL, power);
1426 
1427 	/*
1428 	 * Table 4-18 and figure 4-6 of the PC Card specifiction say:
1429 	 * Vcc Rising Time (Tpr) = 100ms
1430 	 * RESET Width (Th (Hi-z RESET)) = 1ms
1431 	 * RESET Width (Tw (RESET)) = 10us
1432 	 *
1433 	 * some machines require some more time to be settled
1434 	 * (100ms is added here).
1435 	 */
1436 	pcic_delay(h, 200 + 1, "pccen1");
1437 
1438 	/* negate RESET */
1439 	intr |= PCIC_INTR_RESET;
1440 	pcic_write(h, PCIC_INTR, intr);
1441 
1442 	/*
1443 	 * RESET Setup Time (Tsu (RESET)) = 20ms
1444 	 */
1445 	pcic_delay(h, 20, "pccen2");
1446 
1447 #ifdef DIAGNOSTIC
1448 	reg = pcic_read(h, PCIC_IF_STATUS);
1449 	if ((reg & PCIC_IF_STATUS_POWERACTIVE) == 0)
1450 		printf("pcic_chip_socket_enable: no power, status=%x\n", reg);
1451 #endif
1452 
1453 	/* wait for the chip to finish initializing */
1454 	if (pcic_wait_ready(h)) {
1455 		/* XXX return a failure status?? */
1456 		pcic_write(h, PCIC_PWRCTL, 0);
1457 		return;
1458 	}
1459 
1460 	/* reinstall all the memory and io mappings */
1461 	for (win = 0; win < PCIC_MEM_WINS; win++)
1462 		if (h->memalloc & (1 << win))
1463 			pcic_chip_do_mem_map(h, win);
1464 	for (win = 0; win < PCIC_IO_WINS; win++)
1465 		if (h->ioalloc & (1 << win))
1466 			pcic_chip_do_io_map(h, win);
1467 
1468 	h->flags |= PCIC_FLAG_ENABLED;
1469 }
1470 
1471 void
1472 pcic_chip_socket_disable(pch)
1473 	pcmcia_chipset_handle_t pch;
1474 {
1475 	struct pcic_handle *h = (struct pcic_handle *) pch;
1476 	u_int8_t intr;
1477 
1478 	DPRINTF(("pcic_chip_socket_disable\n"));
1479 
1480 	/* disable interrupts; assert RESET */
1481 	intr = pcic_read(h, PCIC_INTR);
1482 	intr &= PCIC_INTR_ENABLE;
1483 	pcic_write(h, PCIC_INTR, intr);
1484 
1485 	/* zero out the address windows */
1486 	pcic_write(h, PCIC_ADDRWIN_ENABLE, 0);
1487 
1488 	/* disable socket: negate output enable bit and power off */
1489 	pcic_write(h, PCIC_PWRCTL, 0);
1490 
1491 	/*
1492 	 * Vcc Falling Time (Tpf) = 300ms
1493 	 */
1494 	pcic_delay(h, 300, "pccwr1");
1495 
1496 	h->flags &= ~PCIC_FLAG_ENABLED;
1497 }
1498 
1499 void
1500 pcic_chip_socket_settype(pch, type)
1501 	pcmcia_chipset_handle_t pch;
1502 	int type;
1503 {
1504 	struct pcic_handle *h = (struct pcic_handle *) pch;
1505 	int intr;
1506 
1507 	intr = pcic_read(h, PCIC_INTR);
1508 	intr &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_CARDTYPE_MASK);
1509 	if (type == PCMCIA_IFTYPE_IO) {
1510 		intr |= PCIC_INTR_CARDTYPE_IO;
1511 		intr |= h->ih_irq << PCIC_INTR_IRQ_SHIFT;
1512 	} else
1513 		intr |= PCIC_INTR_CARDTYPE_MEM;
1514 	pcic_write(h, PCIC_INTR, intr);
1515 
1516 	DPRINTF(("%s: pcic_chip_socket_settype %02x type %s %02x\n",
1517 	    h->ph_parent->dv_xname, h->sock,
1518 	    ((type == PCMCIA_IFTYPE_IO) ? "io" : "mem"), intr));
1519 }
1520 
1521 static u_int8_t
1522 st_pcic_read(h, idx)
1523 	struct pcic_handle *h;
1524 	int idx;
1525 {
1526 
1527 	if (idx != -1)
1528 		bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX,
1529 		    h->sock + idx);
1530 	return (bus_space_read_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA));
1531 }
1532 
1533 static void
1534 st_pcic_write(h, idx, data)
1535 	struct pcic_handle *h;
1536 	int idx;
1537 	u_int8_t data;
1538 {
1539 
1540 	if (idx != -1)
1541 		bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_INDEX,
1542 		    h->sock + idx);
1543 	bus_space_write_1(h->ph_bus_t, h->ph_bus_h, PCIC_REG_DATA, data);
1544 }
1545