]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/isa/pnp.c
This commit was generated by cvs2svn to compensate for changes in r142810,
[FreeBSD/FreeBSD.git] / sys / isa / pnp.c
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  *      from: pnp.c,v 1.11 1999/05/06 22:11:19 peter Exp
27  */
28
29 #include <sys/cdefs.h>
30 __FBSDID("$FreeBSD$");
31
32 #include <sys/param.h>
33 #include <sys/systm.h>
34 #include <sys/kernel.h>
35 #include <sys/module.h>
36 #include <sys/bus.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
43 typedef struct _pnp_id {
44         uint32_t vendor_id;
45         uint32_t serial;
46         u_char checksum;
47 } pnp_id;
48
49 struct pnp_set_config_arg {
50         int     csn;            /* Card number to configure */
51         int     ldn;            /* Logical device on card */
52 };
53
54 struct 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
64 struct 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 #ifdef PC98
97 /* Some NEC PnP cards have 9 bytes serial code. */
98 static pnp_id necids[] = {
99         {0x4180a3b8, 0xffffffff, 0x00}, /* PC-9801CB-B04 (NEC8041) */
100         {0x5181a3b8, 0xffffffff, 0x46}, /* PC-9821CB2-B04(NEC8151) */
101         {0x5182a3b8, 0xffffffff, 0xb8}, /* PC-9801-XX    (NEC8251) */
102         {0x9181a3b8, 0xffffffff, 0x00}, /* PC-9801-120   (NEC8191) */
103         {0, 0, 0}
104 };
105 #endif
106
107 /* The READ_DATA port that we are using currently */
108 static int pnp_rd_port;
109
110 static void   pnp_send_initiation_key(void);
111 static int    pnp_get_serial(pnp_id *p);
112 static int    pnp_isolation_protocol(device_t parent);
113
114 char *
115 pnp_eisaformat(uint32_t id)
116 {
117         uint8_t *data = (uint8_t *) &id;
118         static char idbuf[8];
119         const char  hextoascii[] = "0123456789abcdef";
120
121         idbuf[0] = '@' + ((data[0] & 0x7c) >> 2);
122         idbuf[1] = '@' + (((data[0] & 0x3) << 3) + ((data[1] & 0xe0) >> 5));
123         idbuf[2] = '@' + (data[1] & 0x1f);
124         idbuf[3] = hextoascii[(data[2] >> 4)];
125         idbuf[4] = hextoascii[(data[2] & 0xf)];
126         idbuf[5] = hextoascii[(data[3] >> 4)];
127         idbuf[6] = hextoascii[(data[3] & 0xf)];
128         idbuf[7] = 0;
129         return(idbuf);
130 }
131
132 static void
133 pnp_write(int d, u_char r)
134 {
135         outb (_PNP_ADDRESS, d);
136         outb (_PNP_WRITE_DATA, r);
137 }
138
139 /*
140  * Send Initiation LFSR as described in "Plug and Play ISA Specification",
141  * Intel May 94.
142  */
143 static void
144 pnp_send_initiation_key()
145 {
146         int cur, i;
147
148         /* Reset the LSFR */
149         outb(_PNP_ADDRESS, 0);
150         outb(_PNP_ADDRESS, 0); /* yes, we do need it twice! */
151
152         cur = 0x6a;
153         outb(_PNP_ADDRESS, cur);
154
155         for (i = 1; i < 32; i++) {
156                 cur = (cur >> 1) | (((cur ^ (cur >> 1)) << 7) & 0xff);
157                 outb(_PNP_ADDRESS, cur);
158         }
159 }
160
161
162 /*
163  * Get the device's serial number.  Returns 1 if the serial is valid.
164  */
165 static int
166 pnp_get_serial(pnp_id *p)
167 {
168         int i, bit, valid = 0, sum = 0x6a;
169         u_char *data = (u_char *)p;
170
171         bzero(data, sizeof(char) * 9);
172         outb(_PNP_ADDRESS, PNP_SERIAL_ISOLATION);
173         for (i = 0; i < 72; i++) {
174                 bit = inb((pnp_rd_port << 2) | 0x3) == 0x55;
175                 DELAY(250);     /* Delay 250 usec */
176
177                 /* Can't Short Circuit the next evaluation, so 'and' is last */
178                 bit = (inb((pnp_rd_port << 2) | 0x3) == 0xaa) && bit;
179                 DELAY(250);     /* Delay 250 usec */
180
181                 valid = valid || bit;
182                 if (i < 64)
183                         sum = (sum >> 1) |
184                           (((sum ^ (sum >> 1) ^ bit) << 7) & 0xff);
185                 data[i / 8] = (data[i / 8] >> 1) | (bit ? 0x80 : 0);
186         }
187
188         valid = valid && (data[8] == sum);
189
190         return (valid);
191 }
192
193 /*
194  * Fill's the buffer with resource info from the device.
195  * Returns the number of characters read.
196  */
197 static int
198 pnp_get_resource_info(u_char *buffer, int len)
199 {
200         int i, j, count;
201         u_char temp;
202
203         count = 0;
204         for (i = 0; i < len; i++) {
205                 outb(_PNP_ADDRESS, PNP_STATUS);
206                 for (j = 0; j < 100; j++) {
207                         if ((inb((pnp_rd_port << 2) | 0x3)) & 0x1)
208                                 break;
209                         DELAY(1);
210                 }
211                 if (j == 100) {
212                         printf("PnP device failed to report resource data\n");
213                         return (count);
214                 }
215                 outb(_PNP_ADDRESS, PNP_RESOURCE_DATA);
216                 temp = inb((pnp_rd_port << 2) | 0x3);
217                 if (buffer != NULL)
218                         buffer[i] = temp;
219                 count++;
220         }
221         return (count);
222 }
223
224 /*
225  * This function is called after the bus has assigned resource
226  * locations for a logical device.
227  */
228 static void
229 pnp_set_config(void *arg, struct isa_config *config, int enable)
230 {
231         int csn = ((struct pnp_set_config_arg *) arg)->csn;
232         int ldn = ((struct pnp_set_config_arg *) arg)->ldn;
233         int i;
234
235         /*
236          * First put all cards into Sleep state with the initiation
237          * key, then put our card into Config state.
238          */
239         pnp_send_initiation_key();
240         pnp_write(PNP_WAKE, csn);
241
242         /*
243          * Select our logical device so that we can program it.
244          */
245         pnp_write(PNP_SET_LDN, ldn);
246
247         /*
248          * Constrain the number of resources we will try to program
249          */
250         if (config->ic_nmem > ISA_PNP_NMEM) {
251                 printf("too many ISA memory ranges (%d > %d)\n",
252                     config->ic_nmem, ISA_PNP_NMEM);
253                 config->ic_nmem = ISA_PNP_NMEM;
254         }
255         if (config->ic_nport > ISA_PNP_NPORT) {
256                 printf("too many ISA I/O ranges (%d > %d)\n", config->ic_nport,
257                     ISA_PNP_NPORT);
258                 config->ic_nport = ISA_PNP_NPORT;
259         }
260         if (config->ic_nirq > ISA_PNP_NIRQ) {
261                 printf("too many ISA IRQs (%d > %d)\n", config->ic_nirq,
262                     ISA_PNP_NIRQ);
263                 config->ic_nirq = ISA_PNP_NIRQ;
264         }
265         if (config->ic_ndrq > ISA_PNP_NDRQ) {
266                 printf("too many ISA DRQs (%d > %d)\n", config->ic_ndrq,
267                     ISA_PNP_NDRQ);
268                 config->ic_ndrq = ISA_PNP_NDRQ;
269         }
270
271         /*
272          * Now program the resources.
273          */
274         for (i = 0; i < config->ic_nmem; i++) {
275                 uint32_t start;
276                 uint32_t size;
277
278                 /* XXX: should handle memory control register, 32 bit memory */
279                 if (config->ic_mem[i].ir_size == 0) {
280                         pnp_write(PNP_MEM_BASE_HIGH(i), 0);
281                         pnp_write(PNP_MEM_BASE_LOW(i), 0);
282                         pnp_write(PNP_MEM_RANGE_HIGH(i), 0);
283                         pnp_write(PNP_MEM_RANGE_LOW(i), 0);
284                 } else {
285                         start = config->ic_mem[i].ir_start;
286                         size =  config->ic_mem[i].ir_size;
287                         if (start & 0xff)
288                                 panic("pnp_set_config: bogus memory assignment");
289                         pnp_write(PNP_MEM_BASE_HIGH(i), (start >> 16) & 0xff);
290                         pnp_write(PNP_MEM_BASE_LOW(i), (start >> 8) & 0xff);
291                         pnp_write(PNP_MEM_RANGE_HIGH(i), (size >> 16) & 0xff);
292                         pnp_write(PNP_MEM_RANGE_LOW(i), (size >> 8) & 0xff);
293                 }
294         }
295         for (; i < ISA_PNP_NMEM; i++) {
296                 pnp_write(PNP_MEM_BASE_HIGH(i), 0);
297                 pnp_write(PNP_MEM_BASE_LOW(i), 0);
298                 pnp_write(PNP_MEM_RANGE_HIGH(i), 0);
299                 pnp_write(PNP_MEM_RANGE_LOW(i), 0);
300         }
301
302         for (i = 0; i < config->ic_nport; i++) {
303                 uint32_t start;
304
305                 if (config->ic_port[i].ir_size == 0) {
306                         pnp_write(PNP_IO_BASE_HIGH(i), 0);
307                         pnp_write(PNP_IO_BASE_LOW(i), 0);
308                 } else {
309                         start = config->ic_port[i].ir_start;
310                         pnp_write(PNP_IO_BASE_HIGH(i), (start >> 8) & 0xff);
311                         pnp_write(PNP_IO_BASE_LOW(i), (start >> 0) & 0xff);
312                 }
313         }
314         for (; i < ISA_PNP_NPORT; i++) {
315                 pnp_write(PNP_IO_BASE_HIGH(i), 0);
316                 pnp_write(PNP_IO_BASE_LOW(i), 0);
317         }
318
319         for (i = 0; i < config->ic_nirq; i++) {
320                 int irq;
321
322                 /* XXX: interrupt type */
323                 if (config->ic_irqmask[i] == 0) {
324                         pnp_write(PNP_IRQ_LEVEL(i), 0);
325                         pnp_write(PNP_IRQ_TYPE(i), 2);
326                 } else {
327                         irq = ffs(config->ic_irqmask[i]) - 1;
328                         pnp_write(PNP_IRQ_LEVEL(i), irq);
329                         pnp_write(PNP_IRQ_TYPE(i), 2); /* XXX */
330                 }
331         }
332         for (; i < ISA_PNP_NIRQ; i++) {
333                 /*
334                  * IRQ 0 is not a valid interrupt selection and
335                  * represents no interrupt selection.
336                  */
337                 pnp_write(PNP_IRQ_LEVEL(i), 0);
338                 pnp_write(PNP_IRQ_TYPE(i), 2);
339         }               
340
341         for (i = 0; i < config->ic_ndrq; i++) {
342                 int drq;
343
344                 if (config->ic_drqmask[i] == 0) {
345                         pnp_write(PNP_DMA_CHANNEL(i), 4);
346                 } else {
347                         drq = ffs(config->ic_drqmask[i]) - 1;
348                         pnp_write(PNP_DMA_CHANNEL(i), drq);
349                 }
350         }
351         for (; i < ISA_PNP_NDRQ; i++) {
352                 /*
353                  * DMA channel 4, the cascade channel is used to
354                  * indicate no DMA channel is active.
355                  */
356                 pnp_write(PNP_DMA_CHANNEL(i), 4);
357         }               
358
359         pnp_write(PNP_ACTIVATE, enable ? 1 : 0);
360
361         /*
362          * Wake everyone up again, we are finished.
363          */
364         pnp_write(PNP_CONFIG_CONTROL, PNP_CONFIG_CONTROL_WAIT_FOR_KEY);
365 }
366
367 /*
368  * Process quirks for a logical device.. The card must be in Config state.
369  */
370 void
371 pnp_check_quirks(uint32_t vendor_id, uint32_t logical_id, int ldn,
372     struct isa_config *config)
373 {
374         struct pnp_quirk *qp;
375
376         for (qp = &pnp_quirks[0]; qp->vendor_id; qp++) {
377                 if (qp->vendor_id == vendor_id
378                     && (qp->logical_id == 0 || qp->logical_id == logical_id)) {
379                         switch (qp->type) {
380                         case PNP_QUIRK_WRITE_REG:
381                                 pnp_write(PNP_SET_LDN, ldn);
382                                 pnp_write(qp->arg1, qp->arg2);
383                                 break;
384                         case PNP_QUIRK_EXTRA_IO:
385                                 if (config == NULL)
386                                         break;
387                                 if (qp->arg1 != 0) {
388                                         config->ic_nport++;
389                                         config->ic_port[config->ic_nport - 1] = config->ic_port[0];
390                                         config->ic_port[config->ic_nport - 1].ir_start += qp->arg1;
391                                         config->ic_port[config->ic_nport - 1].ir_end += qp->arg1;
392                                 }
393                                 if (qp->arg2 != 0) {
394                                         config->ic_nport++;
395                                         config->ic_port[config->ic_nport - 1] = config->ic_port[0];
396                                         config->ic_port[config->ic_nport - 1].ir_start += qp->arg2;
397                                         config->ic_port[config->ic_nport - 1].ir_end += qp->arg2;
398                                 }
399                                 break;
400                         }
401                 }
402         }
403 }
404
405 /*
406  * Scan Resource Data for Logical Devices.
407  *
408  * This function exits as soon as it gets an error reading *ANY*
409  * Resource Data or it reaches the end of Resource Data.  In the first
410  * case the return value will be TRUE, FALSE otherwise.
411  */
412 static int
413 pnp_create_devices(device_t parent, pnp_id *p, int csn,
414     u_char *resources, int len)
415 {
416         u_char tag, *resp, *resinfo, *startres = 0;
417         int large_len, scanning = len, retval = FALSE;
418         uint32_t logical_id;
419         device_t dev = 0;
420         int ldn = 0;
421         struct pnp_set_config_arg *csnldn;
422         char buf[100];
423         char *desc = 0;
424
425         resp = resources;
426         while (scanning > 0) {
427                 tag = *resp++;
428                 scanning--;
429                 if (PNP_RES_TYPE(tag) != 0) {
430                         /* Large resource */
431                         if (scanning < 2) {
432                                 scanning = 0;
433                                 continue;
434                         }
435                         large_len = resp[0] + (resp[1] << 8);
436                         resp += 2;
437
438                         if (scanning < large_len) {
439                                 scanning = 0;
440                                 continue;
441                         }
442                         resinfo = resp;
443                         resp += large_len;
444                         scanning -= large_len;
445
446                         if (PNP_LRES_NUM(tag) == PNP_TAG_ID_ANSI) {
447                                 if (dev) {
448                                         /*
449                                          * This is an optional device
450                                          * indentifier string. Skipt it
451                                          * for now.
452                                          */
453                                         continue;
454                                 }
455                                 /* else mandately card identifier string */
456                                 if (large_len > sizeof(buf) - 1)
457                                         large_len = sizeof(buf) - 1;
458                                 bcopy(resinfo, buf, large_len);
459
460                                 /*
461                                  * Trim trailing spaces.
462                                  */
463                                 while (buf[large_len-1] == ' ')
464                                         large_len--;
465                                 buf[large_len] = '\0';
466                                 desc = buf;
467                                 continue;
468                         }
469
470                         continue;
471                 }
472                 
473                 /* Small resource */
474                 if (scanning < PNP_SRES_LEN(tag)) {
475                         scanning = 0;
476                         continue;
477                 }
478                 resinfo = resp;
479                 resp += PNP_SRES_LEN(tag);
480                 scanning -= PNP_SRES_LEN(tag);;
481                         
482                 switch (PNP_SRES_NUM(tag)) {
483                 case PNP_TAG_LOGICAL_DEVICE:
484                         /*
485                          * Parse the resources for the previous
486                          * logical device (if any).
487                          */
488                         if (startres) {
489                                 pnp_parse_resources(dev, startres,
490                                     resinfo - startres - 1, ldn);
491                                 dev = 0;
492                                 startres = 0;
493                         }
494
495                         /* 
496                          * A new logical device. Scan for end of
497                          * resources.
498                          */
499                         bcopy(resinfo, &logical_id, 4);
500                         pnp_check_quirks(p->vendor_id, logical_id, ldn, NULL);
501                         dev = BUS_ADD_CHILD(parent, ISA_ORDER_PNP, NULL, -1);
502                         if (desc)
503                                 device_set_desc_copy(dev, desc);
504                         else
505                                 device_set_desc_copy(dev,
506                                     pnp_eisaformat(logical_id));
507                         isa_set_vendorid(dev, p->vendor_id);
508                         isa_set_serial(dev, p->serial);
509                         isa_set_logicalid(dev, logical_id);
510                         isa_set_configattr(dev,
511                             ISACFGATTR_CANDISABLE | ISACFGATTR_DYNAMIC);
512                         csnldn = malloc(sizeof *csnldn, M_DEVBUF, M_NOWAIT);
513                         if (!csnldn) {
514                                 device_printf(parent, "out of memory\n");
515                                 scanning = 0;
516                                 break;
517                         }
518                         csnldn->csn = csn;
519                         csnldn->ldn = ldn;
520                         ISA_SET_CONFIG_CALLBACK(parent, dev, pnp_set_config,
521                             csnldn);
522                         ldn++;
523                         startres = resp;
524                         break;
525                     
526                 case PNP_TAG_END:
527                         if (!startres) {
528                                 device_printf(parent, "malformed resources\n");
529                                 scanning = 0;
530                                 break;
531                         }
532                         pnp_parse_resources(dev, startres,
533                             resinfo - startres - 1, ldn);
534                         dev = 0;
535                         startres = 0;
536                         scanning = 0;
537                         break;
538
539                 default:
540                         /* Skip this resource */
541                         break;
542                 }
543         }
544
545         return (retval);
546 }
547
548 /*
549  * Read 'amount' bytes of resources from the card, allocating memory
550  * as needed. If a buffer is already available, it should be passed in
551  * '*resourcesp' and its length in '*spacep'. The number of resource
552  * bytes already in the buffer should be passed in '*lenp'. The memory
553  * allocated will be returned in '*resourcesp' with its size and the
554  * number of bytes of resources in '*spacep' and '*lenp' respectively.
555  *
556  * XXX: Multiple problems here, we forget to free() stuff in one
557  * XXX: error return, and in another case we free (*resourcesp) but
558  * XXX: don't tell the caller.
559  */
560 static int
561 pnp_read_bytes(int amount, u_char **resourcesp, int *spacep, int *lenp)
562 {
563         u_char *resources = *resourcesp;
564         u_char *newres;
565         int space = *spacep;
566         int len = *lenp;
567
568         if (space == 0) {
569                 space = 1024;
570                 resources = malloc(space, M_TEMP, M_NOWAIT);
571                 if (!resources)
572                         return (ENOMEM);
573         }
574         
575         if (len + amount > space) {
576                 int extra = 1024;
577                 while (len + amount > space + extra)
578                         extra += 1024;
579                 newres = malloc(space + extra, M_TEMP, M_NOWAIT);
580                 if (!newres) {
581                         /* XXX: free resources */
582                         return (ENOMEM);
583                 }
584                 bcopy(resources, newres, len);
585                 free(resources, M_TEMP);
586                 resources = newres;
587                 space += extra;
588         }
589
590         if (pnp_get_resource_info(resources + len, amount) != amount)
591                 return (EINVAL);
592         len += amount;
593
594         *resourcesp = resources;
595         *spacep = space;
596         *lenp = len;
597
598         return (0);
599 }
600
601 /*
602  * Read all resources from the card, allocating memory as needed. If a
603  * buffer is already available, it should be passed in '*resourcesp'
604  * and its length in '*spacep'. The memory allocated will be returned
605  * in '*resourcesp' with its size and the number of bytes of resources
606  * in '*spacep' and '*lenp' respectively.
607  */
608 static int
609 pnp_read_resources(u_char **resourcesp, int *spacep, int *lenp)
610 {
611         u_char *resources = *resourcesp;
612         int space = *spacep;
613         int len = 0;
614         int error, done;
615         u_char tag;
616
617         error = 0;
618         done = 0;
619         while (!done) {
620                 error = pnp_read_bytes(1, &resources, &space, &len);
621                 if (error)
622                         goto out;
623                 tag = resources[len-1];
624                 if (PNP_RES_TYPE(tag) == 0) {
625                         /*
626                          * Small resource, read contents.
627                          */
628                         error = pnp_read_bytes(PNP_SRES_LEN(tag),
629                             &resources, &space, &len);
630                         if (error)
631                                 goto out;
632                         if (PNP_SRES_NUM(tag) == PNP_TAG_END)
633                                 done = 1;
634                 } else {
635                         /*
636                          * Large resource, read length and contents.
637                          */
638                         error = pnp_read_bytes(2, &resources, &space, &len);
639                         if (error)
640                                 goto out;
641                         error = pnp_read_bytes(resources[len-2]
642                             + (resources[len-1] << 8), &resources, &space,
643                             &len);
644                         if (error)
645                                 goto out;
646                 }
647         }
648
649  out:
650         *resourcesp = resources;
651         *spacep = space;
652         *lenp = len;
653         return (error);
654 }
655
656 /*
657  * Run the isolation protocol. Use pnp_rd_port as the READ_DATA port
658  * value (caller should try multiple READ_DATA locations before giving
659  * up). Upon exiting, all cards are aware that they should use
660  * pnp_rd_port as the READ_DATA port.
661  *
662  * In the first pass, a csn is assigned to each board and pnp_id's
663  * are saved to an array, pnp_devices. In the second pass, each
664  * card is woken up and the device configuration is called.
665  */
666 static int
667 pnp_isolation_protocol(device_t parent)
668 {
669         int csn;
670         pnp_id id;
671         int found = 0, len;
672         u_char *resources = 0;
673         int space = 0;
674         int error;
675 #ifdef PC98
676         int n, necpnp;
677         u_char buffer[10];
678 #endif
679
680         /*
681          * Put all cards into the Sleep state so that we can clear
682          * their CSNs.
683          */
684         pnp_send_initiation_key();
685
686         /*
687          * Clear the CSN for all cards.
688          */
689         pnp_write(PNP_CONFIG_CONTROL, PNP_CONFIG_CONTROL_RESET_CSN);
690
691         /*
692          * Move all cards to the Isolation state.
693          */
694         pnp_write(PNP_WAKE, 0);
695
696         /*
697          * Tell them where the read point is going to be this time.
698          */
699         pnp_write(PNP_SET_RD_DATA, pnp_rd_port);
700
701         for (csn = 1; csn < PNP_MAX_CARDS; csn++) {
702                 /*
703                  * Start the serial isolation protocol.
704                  */
705                 outb(_PNP_ADDRESS, PNP_SERIAL_ISOLATION);
706                 DELAY(1000);    /* Delay 1 msec */
707
708                 if (pnp_get_serial(&id)) {
709                         /*
710                          * We have read the id from a card
711                          * successfully. The card which won the
712                          * isolation protocol will be in Isolation
713                          * mode and all others will be in Sleep.
714                          * Program the CSN of the isolated card
715                          * (taking it to Config state) and read its
716                          * resources, creating devices as we find
717                          * logical devices on the card.
718                          */
719                         pnp_write(PNP_SET_CSN, csn);
720 #ifdef PC98
721                         if (bootverbose)
722                                 printf("PnP Vendor ID = %x\n", id.vendor_id);
723                         /* Check for NEC PnP (9 bytes serial). */
724                         for (n = necpnp = 0; necids[n].vendor_id; n++) {
725                                 if (id.vendor_id == necids[n].vendor_id) {
726                                         necpnp = 1;
727                                         break;
728                                 }
729                         }
730                         if (necpnp) {
731                                 if (bootverbose)
732                                         printf("An NEC-PnP card (%s).\n",
733                                             pnp_eisaformat(id.vendor_id));
734                                 /*  Read dummy 9 bytes serial area. */
735                                 pnp_get_resource_info(buffer, 9);
736                         } else {
737                                 if (bootverbose)
738                                         printf("A Normal-ISA-PnP card (%s).\n",
739                                             pnp_eisaformat(id.vendor_id));
740                         }
741                         if (bootverbose)
742                                 printf("Reading PnP configuration for %s.\n",
743                                     pnp_eisaformat(id.vendor_id));
744 #endif
745                         error = pnp_read_resources(&resources, &space, &len);
746                         if (error)
747                                 break;
748                         pnp_create_devices(parent, &id, csn, resources, len);
749                         found++;
750                 } else
751                         break;
752
753                 /*
754                  * Put this card back to the Sleep state and
755                  * simultaneously move all cards which don't have a
756                  * CSN yet to Isolation state.
757                  */
758                 pnp_write(PNP_WAKE, 0);
759         }
760
761         /*
762          * Unless we have chosen the wrong read port, all cards will
763          * be in Sleep state. Put them back into WaitForKey for
764          * now. Their resources will be programmed later.
765          */
766         pnp_write(PNP_CONFIG_CONTROL, PNP_CONFIG_CONTROL_WAIT_FOR_KEY);
767
768         /*
769          * Cleanup.
770          */
771         if (resources)
772                 free(resources, M_TEMP);
773
774         return (found);
775 }
776
777
778 /*
779  * pnp_identify()
780  *
781  * autoconfiguration of pnp devices. This routine just runs the
782  * isolation protocol over several ports, until one is successful.
783  *
784  * may be called more than once ?
785  *
786  */
787
788 static void
789 pnp_identify(driver_t *driver, device_t parent)
790 {
791         int num_pnp_devs;
792
793         /* Try various READ_DATA ports from 0x203-0x3ff */
794         for (pnp_rd_port = 0x80; (pnp_rd_port < 0xff); pnp_rd_port += 0x10) {
795                 if (bootverbose)
796                         printf("pnp_identify: Trying Read_Port at %x\n",
797                             (pnp_rd_port << 2) | 0x3);
798
799                 num_pnp_devs = pnp_isolation_protocol(parent);
800                 if (num_pnp_devs)
801                         break;
802         }
803         if (bootverbose)
804                 printf("PNP Identify complete\n");
805 }
806
807 static device_method_t pnp_methods[] = {
808         /* Device interface */
809         DEVMETHOD(device_identify,      pnp_identify),
810
811         { 0, 0 }
812 };
813
814 static driver_t pnp_driver = {
815         "pnp",
816         pnp_methods,
817         1,                      /* no softc */
818 };
819
820 static devclass_t pnp_devclass;
821
822 DRIVER_MODULE(pnp, isa, pnp_driver, pnp_devclass, 0, 0);