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