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