xref: /freebsd/sys/isa/pnp.c (revision daf1cffce2e07931f27c6c6998652e90df6ba87e)
1 /*
2  * Copyright (c) 1996, Sujal M. Patel
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  *	$FreeBSD$
27  *      from: pnp.c,v 1.11 1999/05/06 22:11:19 peter Exp
28  */
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/bus.h>
35 #include <sys/malloc.h>
36 #include <isa/isavar.h>
37 #include <isa/pnpreg.h>
38 #include <isa/pnpvar.h>
39 #include <machine/clock.h>
40 
41 typedef struct _pnp_id {
42 	u_int32_t vendor_id;
43 	u_int32_t serial;
44 	u_char checksum;
45 } pnp_id;
46 
47 struct pnp_set_config_arg {
48 	int	csn;		/* Card number to configure */
49 	int	ldn;		/* Logical device on card */
50 };
51 
52 struct pnp_quirk {
53 	u_int32_t vendor_id;	/* Vendor of the card */
54 	u_int32_t logical_id;	/* ID of the device with quirk */
55 	int	type;
56 #define PNP_QUIRK_WRITE_REG	1 /* Need to write a pnp register  */
57 	int	arg1;
58 	int	arg2;
59 };
60 
61 struct pnp_quirk pnp_quirks[] = {
62 	/*
63 	 * The Gravis UltraSound needs register 0xf2 to be set to 0xff
64 	 * to enable power.
65 	 * XXX need to know the logical device id.
66 	 */
67 	{ 0x0100561e /* GRV0001 */,	0,
68 	  PNP_QUIRK_WRITE_REG,	0xf2,	 0xff },
69 
70 	{ 0 }
71 };
72 
73 #if 0
74 /*
75  * these entries are initialized using the autoconfig menu
76  * The struct is invalid (and must be initialized) if the first
77  * CSN is zero. The init code fills invalid entries with CSN 255
78  * which is not a supported value.
79  */
80 
81 struct pnp_cinfo pnp_ldn_overrides[MAX_PNP_LDN] = {
82     { 0 }
83 };
84 #endif
85 
86 /* The READ_DATA port that we are using currently */
87 static int pnp_rd_port;
88 
89 static void   pnp_send_initiation_key(void);
90 static int    pnp_get_serial(pnp_id *p);
91 static int    pnp_isolation_protocol(device_t parent);
92 
93 char *
94 pnp_eisaformat(u_int32_t id)
95 {
96 	u_int8_t *data = (u_int8_t *) &id;
97 	static char idbuf[8];
98 	const char  hextoascii[] = "0123456789abcdef";
99 
100 	idbuf[0] = '@' + ((data[0] & 0x7c) >> 2);
101 	idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5));
102 	idbuf[2] = '@' + (data[1] & 0x1f);
103 	idbuf[3] = hextoascii[(data[2] >> 4)];
104 	idbuf[4] = hextoascii[(data[2] & 0xf)];
105 	idbuf[5] = hextoascii[(data[3] >> 4)];
106 	idbuf[6] = hextoascii[(data[3] & 0xf)];
107 	idbuf[7] = 0;
108 	return(idbuf);
109 }
110 
111 static void
112 pnp_write(int d, u_char r)
113 {
114 	outb (_PNP_ADDRESS, d);
115 	outb (_PNP_WRITE_DATA, r);
116 }
117 
118 #if 0
119 
120 static u_char
121 pnp_read(int d)
122 {
123 	outb (_PNP_ADDRESS, d);
124 	return (inb(3 | (pnp_rd_port <<2)));
125 }
126 
127 #endif
128 
129 /*
130  * Send Initiation LFSR as described in "Plug and Play ISA Specification",
131  * Intel May 94.
132  */
133 static void
134 pnp_send_initiation_key()
135 {
136 	int cur, i;
137 
138 	/* Reset the LSFR */
139 	outb(_PNP_ADDRESS, 0);
140 	outb(_PNP_ADDRESS, 0); /* yes, we do need it twice! */
141 
142 	cur = 0x6a;
143 	outb(_PNP_ADDRESS, cur);
144 
145 	for (i = 1; i < 32; i++) {
146 		cur = (cur >> 1) | (((cur ^ (cur >> 1)) << 7) & 0xff);
147 		outb(_PNP_ADDRESS, cur);
148 	}
149 }
150 
151 
152 /*
153  * Get the device's serial number.  Returns 1 if the serial is valid.
154  */
155 static int
156 pnp_get_serial(pnp_id *p)
157 {
158 	int i, bit, valid = 0, sum = 0x6a;
159 	u_char *data = (u_char *)p;
160 
161 	bzero(data, sizeof(char) * 9);
162 	outb(_PNP_ADDRESS, PNP_SERIAL_ISOLATION);
163 	for (i = 0; i < 72; i++) {
164 		bit = inb((pnp_rd_port << 2) | 0x3) == 0x55;
165 		DELAY(250);	/* Delay 250 usec */
166 
167 		/* Can't Short Circuit the next evaluation, so 'and' is last */
168 		bit = (inb((pnp_rd_port << 2) | 0x3) == 0xaa) && bit;
169 		DELAY(250);	/* Delay 250 usec */
170 
171 		valid = valid || bit;
172 
173 		if (i < 64)
174 			sum = (sum >> 1) |
175 				(((sum ^ (sum >> 1) ^ bit) << 7) & 0xff);
176 
177 		data[i / 8] = (data[i / 8] >> 1) | (bit ? 0x80 : 0);
178 	}
179 
180 	valid = valid && (data[8] == sum);
181 
182 	return valid;
183 }
184 
185 /*
186  * Fill's the buffer with resource info from the device.
187  * Returns the number of characters read.
188  */
189 static int
190 pnp_get_resource_info(u_char *buffer, int len)
191 {
192 	int i, j, count;
193 	u_char temp;
194 
195 	count = 0;
196 	for (i = 0; i < len; i++) {
197 		outb(_PNP_ADDRESS, PNP_STATUS);
198 		for (j = 0; j < 100; j++) {
199 			if ((inb((pnp_rd_port << 2) | 0x3)) & 0x1)
200 				break;
201 			DELAY(1);
202 		}
203 		if (j == 100) {
204 			printf("PnP device failed to report resource data\n");
205 			return count;
206 		}
207 		outb(_PNP_ADDRESS, PNP_RESOURCE_DATA);
208 		temp = inb((pnp_rd_port << 2) | 0x3);
209 		if (buffer != NULL)
210 			buffer[i] = temp;
211 		count++;
212 	}
213 	return count;
214 }
215 
216 #if 0
217 /*
218  * write_pnp_parms initializes a logical device with the parms
219  * in d, and then activates the board if the last parameter is 1.
220  */
221 
222 static int
223 write_pnp_parms(struct pnp_cinfo *d, pnp_id *p, int ldn)
224 {
225     int i, empty = -1 ;
226 
227     pnp_write (SET_LDN, ldn );
228     i = pnp_read(SET_LDN) ;
229     if (i != ldn) {
230 	printf("Warning: LDN %d does not exist\n", ldn);
231     }
232     for (i = 0; i < 8; i++) {
233 	pnp_write(IO_CONFIG_BASE + i * 2, d->ic_port[i] >> 8 );
234 	pnp_write(IO_CONFIG_BASE + i * 2 + 1, d->ic_port[i] & 0xff );
235     }
236     for (i = 0; i < 4; i++) {
237 	pnp_write(MEM_CONFIG + i*8, (d->ic_mem[i].base >> 16) & 0xff );
238 	pnp_write(MEM_CONFIG + i*8+1, (d->ic_mem[i].base >> 8) & 0xff );
239 	pnp_write(MEM_CONFIG + i*8+2, d->ic_mem[i].control & 0xff );
240 	pnp_write(MEM_CONFIG + i*8+3, (d->ic_mem[i].range >> 16) & 0xff );
241 	pnp_write(MEM_CONFIG + i*8+4, (d->ic_mem[i].range >> 8) & 0xff );
242     }
243     for (i = 0; i < 2; i++) {
244 	pnp_write(IRQ_CONFIG + i*2    , d->irq[i] );
245 	pnp_write(IRQ_CONFIG + i*2 + 1, d->irq_type[i] );
246 	pnp_write(DRQ_CONFIG + i, d->drq[i] );
247     }
248     /*
249      * store parameters read into the current kernel
250      * so manual editing next time is easier
251      */
252     for (i = 0 ; i < MAX_PNP_LDN; i++) {
253 	if (pnp_ldn_overrides[i].csn == d->csn &&
254 		pnp_ldn_overrides[i].ldn == ldn) {
255 	    d->flags = pnp_ldn_overrides[i].flags ;
256 	    pnp_ldn_overrides[i] = *d ;
257 	    break ;
258 	} else if (pnp_ldn_overrides[i].csn < 1 ||
259 		pnp_ldn_overrides[i].csn == 255)
260 	    empty = i ;
261     }
262     if (i== MAX_PNP_LDN && empty != -1)
263 	pnp_ldn_overrides[empty] = *d;
264 
265     /*
266      * Here should really perform the range check, and
267      * return a failure if not successful.
268      */
269     pnp_write (IO_RANGE_CHECK, 0);
270     DELAY(1000); /* XXX is it really necessary ? */
271     pnp_write (ACTIVATE, d->enable ? 1 : 0);
272     DELAY(1000); /* XXX is it really necessary ? */
273     return 1 ;
274 }
275 #endif
276 
277 /*
278  * This function is called after the bus has assigned resource
279  * locations for a logical device.
280  */
281 static void
282 pnp_set_config(void *arg, struct isa_config *config, int enable)
283 {
284 	int csn = ((struct pnp_set_config_arg *) arg)->csn;
285 	int ldn = ((struct pnp_set_config_arg *) arg)->ldn;
286 	int i;
287 
288 	/*
289 	 * First put all cards into Sleep state with the initiation
290 	 * key, then put our card into Config state.
291 	 */
292 	pnp_send_initiation_key();
293 	pnp_write(PNP_WAKE, csn);
294 
295 	/*
296 	 * Select our logical device so that we can program it.
297 	 */
298 	pnp_write(PNP_SET_LDN, ldn);
299 
300 	/*
301 	 * Now program the resources.
302 	 */
303 	for (i = 0; i < config->ic_nmem; i++) {
304 		u_int32_t start = config->ic_mem[i].ir_start;
305 		u_int32_t size =  config->ic_mem[i].ir_size;
306 		if (start & 0xff)
307 			panic("pnp_set_config: bogus memory assignment");
308 		pnp_write(PNP_MEM_BASE_HIGH(i), (start >> 16) & 0xff);
309 		pnp_write(PNP_MEM_BASE_LOW(i), (start >> 8) & 0xff);
310 		pnp_write(PNP_MEM_RANGE_HIGH(i), (size >> 16) & 0xff);
311 		pnp_write(PNP_MEM_RANGE_LOW(i), (size >> 8) & 0xff);
312 	}
313 	for (; i < ISA_NMEM; i++) {
314 		pnp_write(PNP_MEM_BASE_HIGH(i), 0);
315 		pnp_write(PNP_MEM_BASE_LOW(i), 0);
316 		pnp_write(PNP_MEM_RANGE_HIGH(i), 0);
317 		pnp_write(PNP_MEM_RANGE_LOW(i), 0);
318 	}
319 
320 	for (i = 0; i < config->ic_nport; i++) {
321 		u_int32_t start = config->ic_port[i].ir_start;
322 		pnp_write(PNP_IO_BASE_HIGH(i), (start >> 8) & 0xff);
323 		pnp_write(PNP_IO_BASE_LOW(i), (start >> 0) & 0xff);
324 	}
325 	for (; i < ISA_NPORT; i++) {
326 		pnp_write(PNP_IO_BASE_HIGH(i), 0);
327 		pnp_write(PNP_IO_BASE_LOW(i), 0);
328 	}
329 
330 	for (i = 0; i < config->ic_nirq; i++) {
331 		int irq = ffs(config->ic_irqmask[i]) - 1;
332 		pnp_write(PNP_IRQ_LEVEL(i), irq);
333 		pnp_write(PNP_IRQ_TYPE(i), 2); /* XXX */
334 	}
335 	for (; i < ISA_NIRQ; i++) {
336 		/*
337 		 * IRQ 0 is not a valid interrupt selection and
338 		 * represents no interrupt selection.
339 		 */
340 		pnp_write(PNP_IRQ_LEVEL(i), 0);
341 	}
342 
343 	for (i = 0; i < config->ic_ndrq; i++) {
344 		int drq = ffs(config->ic_drqmask[i]) - 1;
345 		pnp_write(PNP_DMA_CHANNEL(i), drq);
346 	}
347 	for (; i < ISA_NDRQ; i++) {
348 		/*
349 		 * DMA channel 4, the cascade channel is used to
350 		 * indicate no DMA channel is active.
351 		 */
352 		pnp_write(PNP_DMA_CHANNEL(i), 4);
353 	}
354 
355 	pnp_write(PNP_ACTIVATE, enable ? 1 : 0);
356 
357 	/*
358 	 * Wake everyone up again, we are finished.
359 	 */
360 	pnp_write(PNP_CONFIG_CONTROL, PNP_CONFIG_CONTROL_WAIT_FOR_KEY);
361 }
362 
363 /*
364  * Process quirks for a logical device.. The card must be in Config state.
365  */
366 static void
367 pnp_check_quirks(u_int32_t vendor_id, u_int32_t logical_id, int ldn)
368 {
369 	struct pnp_quirk *qp;
370 
371 	for (qp = &pnp_quirks[0]; qp->vendor_id; qp++) {
372 		if (qp->vendor_id == vendor_id
373 		    && (qp->logical_id == 0
374 			|| qp->logical_id == logical_id)) {
375 			switch (qp->type) {
376 			case PNP_QUIRK_WRITE_REG:
377 				pnp_write(PNP_SET_LDN, ldn);
378 				pnp_write(qp->arg1, qp->arg2);
379 				break;
380 			}
381 		}
382 	}
383 }
384 
385 /*
386  * Scan Resource Data for Logical Devices.
387  *
388  * This function exits as soon as it gets an error reading *ANY*
389  * Resource Data or it reaches the end of Resource Data.  In the first
390  * case the return value will be TRUE, FALSE otherwise.
391  */
392 static int
393 pnp_create_devices(device_t parent, pnp_id *p, int csn,
394 		   u_char *resources, int len)
395 {
396 	u_char tag, *resp, *resinfo, *startres = 0;
397 	int large_len, scanning = len, retval = FALSE;
398 	u_int32_t logical_id;
399 	u_int32_t compat_id;
400 	device_t dev = 0;
401 	int ldn = 0;
402 	struct pnp_set_config_arg *csnldn;
403 	char buf[100];
404 	char *desc = 0;
405 
406 	resp = resources;
407 	while (scanning > 0) {
408 		tag = *resp++;
409 		scanning--;
410 		if (PNP_RES_TYPE(tag) != 0) {
411 			/* Large resource */
412 			if (scanning < 2) {
413 				scanning = 0;
414 				continue;
415 			}
416 			large_len = resp[0] + (resp[1] << 8);
417 			resp += 2;
418 
419 			if (scanning < large_len) {
420 				scanning = 0;
421 				continue;
422 			}
423 			resinfo = resp;
424 			resp += large_len;
425 			scanning -= large_len;
426 
427 			if (PNP_LRES_NUM(tag) == PNP_TAG_ID_ANSI) {
428 				if (large_len > sizeof(buf) - 1)
429 					large_len = sizeof(buf) - 1;
430 				bcopy(resinfo, buf, large_len);
431 
432 				/*
433 				 * Trim trailing spaces.
434 				 */
435 				while (buf[large_len-1] == ' ')
436 					large_len--;
437 				buf[large_len] = '\0';
438 				desc = buf;
439 				if (dev)
440 					device_set_desc_copy(dev, desc);
441 				continue;
442 			}
443 
444 			continue;
445 		}
446 
447 		/* Small resource */
448 		if (scanning < PNP_SRES_LEN(tag)) {
449 			scanning = 0;
450 			continue;
451 		}
452 		resinfo = resp;
453 		resp += PNP_SRES_LEN(tag);
454 		scanning -= PNP_SRES_LEN(tag);;
455 
456 		switch (PNP_SRES_NUM(tag)) {
457 		case PNP_TAG_LOGICAL_DEVICE:
458 			/*
459 			 * Parse the resources for the previous
460 			 * logical device (if any).
461 			 */
462 			if (startres) {
463 				pnp_parse_resources(dev, startres,
464 						    resinfo - startres - 1);
465 				dev = 0;
466 				startres = 0;
467 			}
468 
469 			/*
470 			 * A new logical device. Scan for end of
471 			 * resources.
472 			 */
473 			bcopy(resinfo, &logical_id, 4);
474 			pnp_check_quirks(p->vendor_id, logical_id, ldn);
475 			compat_id = 0;
476 			dev = BUS_ADD_CHILD(parent, ISA_ORDER_PNP, NULL, -1);
477 			if (desc)
478 				device_set_desc_copy(dev, desc);
479 			isa_set_vendorid(dev, p->vendor_id);
480 			isa_set_serial(dev, p->serial);
481 			isa_set_logicalid(dev, logical_id);
482 			csnldn = malloc(sizeof *csnldn, M_DEVBUF, M_NOWAIT);
483 			if (!csnldn) {
484 				device_printf(parent,
485 					      "out of memory\n");
486 				scanning = 0;
487 				break;
488 			}
489 			csnldn->csn = csn;
490 			csnldn->ldn = ldn;
491 			ISA_SET_CONFIG_CALLBACK(parent, dev,
492 						pnp_set_config, csnldn);
493 			ldn++;
494 			startres = resp;
495 			break;
496 
497 		case PNP_TAG_END:
498 			if (!startres) {
499 				device_printf(parent,
500 					      "malformed resources\n");
501 				scanning = 0;
502 				break;
503 			}
504 			pnp_parse_resources(dev, startres,
505 					    resinfo - startres - 1);
506 			dev = 0;
507 			startres = 0;
508 			scanning = 0;
509 			break;
510 
511 		default:
512 			/* Skip this resource */
513 			break;
514 		}
515 	}
516 
517 	return retval;
518 }
519 
520 /*
521  * Read 'amount' bytes of resources from the card, allocating memory
522  * as needed. If a buffer is already available, it should be passed in
523  * '*resourcesp' and its length in '*spacep'. The number of resource
524  * bytes already in the buffer should be passed in '*lenp'. The memory
525  * allocated will be returned in '*resourcesp' with its size and the
526  * number of bytes of resources in '*spacep' and '*lenp' respectively.
527  */
528 static int
529 pnp_read_bytes(int amount, u_char **resourcesp, int *spacep, int *lenp)
530 {
531 	u_char *resources = *resourcesp;
532 	u_char *newres;
533 	int space = *spacep;
534 	int len = *lenp;
535 
536 	if (space == 0) {
537 		space = 1024;
538 		resources = malloc(space, M_TEMP, M_NOWAIT);
539 		if (!resources)
540 			return ENOMEM;
541 	}
542 
543 	if (len + amount > space) {
544 		int extra = 1024;
545 		while (len + amount > space + extra)
546 			extra += 1024;
547 		newres = malloc(space + extra, M_TEMP, M_NOWAIT);
548 		if (!newres)
549 			return ENOMEM;
550 		bcopy(resources, newres, len);
551 		free(resources, M_TEMP);
552 		resources = newres;
553 		space += extra;
554 	}
555 
556 	if (pnp_get_resource_info(resources + len, amount) != amount)
557 		return EINVAL;
558 	len += amount;
559 
560 	*resourcesp = resources;
561 	*spacep = space;
562 	*lenp = len;
563 
564 	return 0;
565 }
566 
567 /*
568  * Read all resources from the card, allocating memory as needed. If a
569  * buffer is already available, it should be passed in '*resourcesp'
570  * and its length in '*spacep'. The memory allocated will be returned
571  * in '*resourcesp' with its size and the number of bytes of resources
572  * in '*spacep' and '*lenp' respectively.
573  */
574 static int
575 pnp_read_resources(u_char **resourcesp, int *spacep, int *lenp)
576 {
577 	u_char *resources = *resourcesp;
578 	int space = *spacep;
579 	int len = 0;
580 	int error, done;
581 	u_char tag;
582 
583 	error = 0;
584 	done = 0;
585 	while (!done) {
586 		error = pnp_read_bytes(1, &resources, &space, &len);
587 		if (error)
588 			goto out;
589 		tag = resources[len-1];
590 		if (PNP_RES_TYPE(tag) == 0) {
591 			/*
592 			 * Small resource, read contents.
593 			 */
594 			error = pnp_read_bytes(PNP_SRES_LEN(tag),
595 					       &resources, &space, &len);
596 			if (error)
597 				goto out;
598 			if (PNP_SRES_NUM(tag) == PNP_TAG_END)
599 				done = 1;
600 		} else {
601 			/*
602 			 * Large resource, read length and contents.
603 			 */
604 			error = pnp_read_bytes(2, &resources, &space, &len);
605 			if (error)
606 				goto out;
607 			error = pnp_read_bytes(resources[len-2]
608 					       + (resources[len-1] << 8),
609 					       &resources, &space, &len);
610 			if (error)
611 				goto out;
612 		}
613 	}
614 
615  out:
616 	*resourcesp = resources;
617 	*spacep = space;
618 	*lenp = len;
619 	return error;
620 }
621 
622 /*
623  * Run the isolation protocol. Use pnp_rd_port as the READ_DATA port
624  * value (caller should try multiple READ_DATA locations before giving
625  * up). Upon exiting, all cards are aware that they should use
626  * pnp_rd_port as the READ_DATA port.
627  *
628  * In the first pass, a csn is assigned to each board and pnp_id's
629  * are saved to an array, pnp_devices. In the second pass, each
630  * card is woken up and the device configuration is called.
631  */
632 static int
633 pnp_isolation_protocol(device_t parent)
634 {
635 	int csn;
636 	pnp_id id;
637 	int found = 0, len;
638 	u_char *resources = 0;
639 	int space = 0;
640 	int error;
641 
642 	/*
643 	 * Put all cards into the Sleep state so that we can clear
644 	 * their CSNs.
645 	 */
646 	pnp_send_initiation_key();
647 
648 	/*
649 	 * Clear the CSN for all cards.
650 	 */
651 	pnp_write(PNP_CONFIG_CONTROL, PNP_CONFIG_CONTROL_RESET_CSN);
652 
653 	/*
654 	 * Move all cards to the Isolation state.
655 	 */
656 	pnp_write(PNP_WAKE, 0);
657 
658 	/*
659 	 * Tell them where the read point is going to be this time.
660 	 */
661 	pnp_write(PNP_SET_RD_DATA, pnp_rd_port);
662 
663 	for (csn = 1; csn < PNP_MAX_CARDS; csn++) {
664 		/*
665 		 * Start the serial isolation protocol.
666 		 */
667 		outb(_PNP_ADDRESS, PNP_SERIAL_ISOLATION);
668 		DELAY(1000);	/* Delay 1 msec */
669 
670 		if (pnp_get_serial(&id)) {
671 			/*
672 			 * We have read the id from a card
673 			 * successfully. The card which won the
674 			 * isolation protocol will be in Isolation
675 			 * mode and all others will be in Sleep.
676 			 * Program the CSN of the isolated card
677 			 * (taking it to Config state) and read its
678 			 * resources, creating devices as we find
679 			 * logical devices on the card.
680 			 */
681 			pnp_write(PNP_SET_CSN, csn);
682 			error = pnp_read_resources(&resources,
683 						   &space,
684 						   &len);
685 			if (error)
686 				break;
687 			pnp_create_devices(parent, &id, csn,
688 					   resources, len);
689 			found++;
690 		} else
691 			break;
692 
693 		/*
694 		 * Put this card back to the Sleep state and
695 		 * simultaneously move all cards which don't have a
696 		 * CSN yet to Isolation state.
697 		 */
698 		pnp_write(PNP_WAKE, 0);
699 	}
700 
701 	/*
702 	 * Unless we have chosen the wrong read port, all cards will
703 	 * be in Sleep state. Put them back into WaitForKey for
704 	 * now. Their resources will be programmed later.
705 	 */
706 	pnp_write(PNP_CONFIG_CONTROL, PNP_CONFIG_CONTROL_WAIT_FOR_KEY);
707 
708 	/*
709 	 * Cleanup.
710 	 */
711 	if (resources)
712 		free(resources, M_TEMP);
713 
714 	return found;
715 }
716 
717 
718 /*
719  * pnp_identify()
720  *
721  * autoconfiguration of pnp devices. This routine just runs the
722  * isolation protocol over several ports, until one is successful.
723  *
724  * may be called more than once ?
725  *
726  */
727 
728 static void
729 pnp_identify(driver_t *driver, device_t parent)
730 {
731 	int num_pnp_devs;
732 
733 #if 0
734 	if (pnp_ldn_overrides[0].csn == 0) {
735 		if (bootverbose)
736 			printf("Initializing PnP override table\n");
737 		bzero (pnp_ldn_overrides, sizeof(pnp_ldn_overrides));
738 		pnp_ldn_overrides[0].csn = 255 ;
739 	}
740 #endif
741 
742 	/* Try various READ_DATA ports from 0x203-0x3ff */
743 	for (pnp_rd_port = 0x80; (pnp_rd_port < 0xff); pnp_rd_port += 0x10) {
744 		if (bootverbose)
745 			printf("Trying Read_Port at %x\n", (pnp_rd_port << 2) | 0x3);
746 
747 		num_pnp_devs = pnp_isolation_protocol(parent);
748 		if (num_pnp_devs)
749 			break;
750 	}
751 }
752 
753 static device_method_t pnp_methods[] = {
754 	/* Device interface */
755 	DEVMETHOD(device_identify,	pnp_identify),
756 
757 	{ 0, 0 }
758 };
759 
760 static driver_t pnp_driver = {
761 	"pnp",
762 	pnp_methods,
763 	1,			/* no softc */
764 };
765 
766 static devclass_t pnp_devclass;
767 
768 DRIVER_MODULE(pnp, isa, pnp_driver, pnp_devclass, 0, 0);
769