15b45337dSDoug Rabson /*- 25b45337dSDoug Rabson * Copyright (c) 1999 Doug Rabson 35b45337dSDoug Rabson * All rights reserved. 45b45337dSDoug Rabson * 55b45337dSDoug Rabson * Redistribution and use in source and binary forms, with or without 65b45337dSDoug Rabson * modification, are permitted provided that the following conditions 75b45337dSDoug Rabson * are met: 85b45337dSDoug Rabson * 1. Redistributions of source code must retain the above copyright 95b45337dSDoug Rabson * notice, this list of conditions and the following disclaimer. 105b45337dSDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright 115b45337dSDoug Rabson * notice, this list of conditions and the following disclaimer in the 125b45337dSDoug Rabson * documentation and/or other materials provided with the distribution. 135b45337dSDoug Rabson * 145b45337dSDoug Rabson * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 155b45337dSDoug Rabson * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 165b45337dSDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 175b45337dSDoug Rabson * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 185b45337dSDoug Rabson * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 195b45337dSDoug Rabson * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 205b45337dSDoug Rabson * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 215b45337dSDoug Rabson * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 225b45337dSDoug Rabson * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 235b45337dSDoug Rabson * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 245b45337dSDoug Rabson * SUCH DAMAGE. 255b45337dSDoug Rabson * 265b45337dSDoug Rabson * $FreeBSD$ 275b45337dSDoug Rabson */ 285b45337dSDoug Rabson 295b45337dSDoug Rabson #include <sys/param.h> 305b45337dSDoug Rabson #include <sys/systm.h> 315b45337dSDoug Rabson #include <sys/kernel.h> 32ca403ff8SDoug Rabson #include <sys/malloc.h> 335b45337dSDoug Rabson #include <sys/module.h> 345b45337dSDoug Rabson #include <sys/bus.h> 355b45337dSDoug Rabson #include <isa/isavar.h> 365b45337dSDoug Rabson #include <isa/pnpreg.h> 375b45337dSDoug Rabson #include <isa/pnpvar.h> 385b45337dSDoug Rabson 39acd3131bSDoug Rabson #define MAXDEP 8 40acd3131bSDoug Rabson 41bb2b9030SDoug Rabson #define I16(p) ((p)[0] + ((p)[1] << 8)) 42bb2b9030SDoug Rabson #define I32(p) (I16(p) + (I16(p+2) << 16)) 43bb2b9030SDoug Rabson 445b45337dSDoug Rabson /* 455b45337dSDoug Rabson * Parse resource data for Logical Devices. 465b45337dSDoug Rabson * 475b45337dSDoug Rabson * This function exits as soon as it gets an error reading *ANY* 48acd3131bSDoug Rabson * Resource Data or it reaches the end of Resource Data. 495b45337dSDoug Rabson */ 505b45337dSDoug Rabson void 515b45337dSDoug Rabson pnp_parse_resources(device_t dev, u_char *resources, int len) 525b45337dSDoug Rabson { 535b45337dSDoug Rabson device_t parent = device_get_parent(dev); 545b45337dSDoug Rabson u_char tag, *resp, *resinfo; 555b45337dSDoug Rabson int large_len, scanning = len; 56bb2b9030SDoug Rabson u_int32_t id, compat_id; 575b45337dSDoug Rabson struct isa_config *config; 58acd3131bSDoug Rabson int ncfgs = 1; 59acd3131bSDoug Rabson int priorities[1 + MAXDEP]; 60ca403ff8SDoug Rabson struct isa_config *configs; 615b45337dSDoug Rabson char buf[100]; 62acd3131bSDoug Rabson int i; 635b45337dSDoug Rabson 64bb2b9030SDoug Rabson id = isa_get_logicalid(dev); 65ca403ff8SDoug Rabson configs = (struct isa_config *)malloc(sizeof(*configs) * (1 + MAXDEP), 66ca403ff8SDoug Rabson M_DEVBUF, M_NOWAIT); 67ca403ff8SDoug Rabson if (configs == NULL) { 68ca403ff8SDoug Rabson device_printf(dev, "No memory to parse PNP data\n"); 69ca403ff8SDoug Rabson return; 70ca403ff8SDoug Rabson } 71ca403ff8SDoug Rabson bzero(configs, sizeof(*configs) * (1 + MAXDEP)); 72acd3131bSDoug Rabson config = &configs[0]; 73acd3131bSDoug Rabson priorities[0] = 0; 745b45337dSDoug Rabson resp = resources; 755b45337dSDoug Rabson while (scanning > 0) { 765b45337dSDoug Rabson tag = *resp++; 775b45337dSDoug Rabson scanning--; 785b45337dSDoug Rabson if (PNP_RES_TYPE(tag) == 0) { 795b45337dSDoug Rabson /* Small resource */ 805b45337dSDoug Rabson if (scanning < PNP_SRES_LEN(tag)) { 815b45337dSDoug Rabson scanning = 0; 825b45337dSDoug Rabson continue; 835b45337dSDoug Rabson } 845b45337dSDoug Rabson resinfo = resp; 855b45337dSDoug Rabson resp += PNP_SRES_LEN(tag); 865b45337dSDoug Rabson scanning -= PNP_SRES_LEN(tag);; 875b45337dSDoug Rabson 885b45337dSDoug Rabson switch (PNP_SRES_NUM(tag)) { 895b45337dSDoug Rabson case PNP_TAG_COMPAT_DEVICE: 905b45337dSDoug Rabson /* 915b45337dSDoug Rabson * Got a compatible device id 925b45337dSDoug Rabson * resource. Should keep a list of 935b45337dSDoug Rabson * compat ids in the device. 945b45337dSDoug Rabson */ 955b45337dSDoug Rabson bcopy(resinfo, &compat_id, 4); 965b45337dSDoug Rabson isa_set_compatid(dev, compat_id); 975b45337dSDoug Rabson break; 985b45337dSDoug Rabson 995b45337dSDoug Rabson case PNP_TAG_IRQ_FORMAT: 100bb2b9030SDoug Rabson if (bootverbose) { 101bb2b9030SDoug Rabson printf("%s: adding irq mask %#04x\n", 102bb2b9030SDoug Rabson pnp_eisaformat(id), 103bb2b9030SDoug Rabson I16(resinfo)); 104bb2b9030SDoug Rabson } 1055b45337dSDoug Rabson if (config->ic_nirq == ISA_NIRQ) { 106acd3131bSDoug Rabson device_printf(parent, "too many irqs\n"); 1075b45337dSDoug Rabson scanning = 0; 1085b45337dSDoug Rabson break; 1095b45337dSDoug Rabson } 1105b45337dSDoug Rabson config->ic_irqmask[config->ic_nirq] = 111bb2b9030SDoug Rabson I16(resinfo); 1125b45337dSDoug Rabson config->ic_nirq++; 1135b45337dSDoug Rabson break; 1145b45337dSDoug Rabson 1155b45337dSDoug Rabson case PNP_TAG_DMA_FORMAT: 116bb2b9030SDoug Rabson if (bootverbose) { 117bb2b9030SDoug Rabson printf("%s: adding dma mask %#02x\n", 118bb2b9030SDoug Rabson pnp_eisaformat(id), 119bb2b9030SDoug Rabson resinfo[0]); 120bb2b9030SDoug Rabson } 1215b45337dSDoug Rabson if (config->ic_ndrq == ISA_NDRQ) { 122acd3131bSDoug Rabson device_printf(parent, "too many drqs\n"); 1235b45337dSDoug Rabson scanning = 0; 1245b45337dSDoug Rabson break; 1255b45337dSDoug Rabson } 1265b45337dSDoug Rabson config->ic_drqmask[config->ic_ndrq] = 1275b45337dSDoug Rabson resinfo[0]; 1285b45337dSDoug Rabson config->ic_ndrq++; 1295b45337dSDoug Rabson break; 1305b45337dSDoug Rabson 1315b45337dSDoug Rabson case PNP_TAG_START_DEPENDANT: 132bb2b9030SDoug Rabson if (bootverbose) { 133bb2b9030SDoug Rabson printf("%s: start dependant\n", 134bb2b9030SDoug Rabson pnp_eisaformat(id)); 135bb2b9030SDoug Rabson } 136acd3131bSDoug Rabson if (ncfgs >= MAXDEP) { 137acd3131bSDoug Rabson device_printf(parent, "too many dependant configs (%d)\n", MAXDEP); 1385b45337dSDoug Rabson scanning = 0; 1395b45337dSDoug Rabson break; 1405b45337dSDoug Rabson } 141acd3131bSDoug Rabson config = &configs[ncfgs]; 1425b45337dSDoug Rabson /* 1435b45337dSDoug Rabson * If the priority is not specified, 1445b45337dSDoug Rabson * then use the default of 1455b45337dSDoug Rabson * 'acceptable' 1465b45337dSDoug Rabson */ 1475b45337dSDoug Rabson if (PNP_SRES_LEN(tag) > 0) 148acd3131bSDoug Rabson priorities[ncfgs] = resinfo[0]; 1495b45337dSDoug Rabson else 150acd3131bSDoug Rabson priorities[ncfgs] = 1; 151acd3131bSDoug Rabson ncfgs++; 1525b45337dSDoug Rabson break; 1535b45337dSDoug Rabson 1545b45337dSDoug Rabson case PNP_TAG_END_DEPENDANT: 155bb2b9030SDoug Rabson if (bootverbose) { 156bb2b9030SDoug Rabson printf("%s: end dependant\n", 157bb2b9030SDoug Rabson pnp_eisaformat(id)); 158bb2b9030SDoug Rabson } 159acd3131bSDoug Rabson config = &configs[0]; /* back to main config */ 1605b45337dSDoug Rabson break; 1615b45337dSDoug Rabson 1625b45337dSDoug Rabson case PNP_TAG_IO_RANGE: 163bb2b9030SDoug Rabson if (bootverbose) { 164bb2b9030SDoug Rabson printf("%s: adding io range " 165bb2b9030SDoug Rabson "%#x-%#x, size=%#x, " 166bb2b9030SDoug Rabson "align=%#x\n", 167bb2b9030SDoug Rabson pnp_eisaformat(id), 168bb2b9030SDoug Rabson I16(resinfo + 1), 169bb2b9030SDoug Rabson I16(resinfo + 3) + resinfo[6]-1, 170bb2b9030SDoug Rabson resinfo[6], 171bb2b9030SDoug Rabson resinfo[5]); 172bb2b9030SDoug Rabson } 1735b45337dSDoug Rabson if (config->ic_nport == ISA_NPORT) { 174acd3131bSDoug Rabson device_printf(parent, "too many ports\n"); 1755b45337dSDoug Rabson scanning = 0; 1765b45337dSDoug Rabson break; 1775b45337dSDoug Rabson } 1785b45337dSDoug Rabson config->ic_port[config->ic_nport].ir_start = 179bb2b9030SDoug Rabson I16(resinfo + 1); 1805b45337dSDoug Rabson config->ic_port[config->ic_nport].ir_end = 181bb2b9030SDoug Rabson I16(resinfo + 3) + resinfo[6] - 1; 182bb2b9030SDoug Rabson config->ic_port[config->ic_nport].ir_size = 1835b45337dSDoug Rabson resinfo[6]; 184bb2b9030SDoug Rabson if (resinfo[5] == 0) { 185bb2b9030SDoug Rabson /* Make sure align is at least one */ 186bb2b9030SDoug Rabson resinfo[5] = 1; 187bb2b9030SDoug Rabson } 1885b45337dSDoug Rabson config->ic_port[config->ic_nport].ir_align = 1895b45337dSDoug Rabson resinfo[5]; 1905b45337dSDoug Rabson config->ic_nport++; 1915b45337dSDoug Rabson break; 1925b45337dSDoug Rabson 1935b45337dSDoug Rabson case PNP_TAG_IO_FIXED: 194bb2b9030SDoug Rabson if (bootverbose) { 195acd3131bSDoug Rabson printf("%s: adding fixed io range " 196bb2b9030SDoug Rabson "%#x-%#x, size=%#x, " 197bb2b9030SDoug Rabson "align=%#x\n", 198bb2b9030SDoug Rabson pnp_eisaformat(id), 199bb2b9030SDoug Rabson I16(resinfo), 200bb2b9030SDoug Rabson I16(resinfo) + resinfo[2] - 1, 201bb2b9030SDoug Rabson resinfo[2], 202bb2b9030SDoug Rabson 1); 203bb2b9030SDoug Rabson } 2045b45337dSDoug Rabson if (config->ic_nport == ISA_NPORT) { 205acd3131bSDoug Rabson device_printf(parent, "too many ports\n"); 2065b45337dSDoug Rabson scanning = 0; 2075b45337dSDoug Rabson break; 2085b45337dSDoug Rabson } 2095b45337dSDoug Rabson config->ic_port[config->ic_nport].ir_start = 210bb2b9030SDoug Rabson I16(resinfo); 2115b45337dSDoug Rabson config->ic_port[config->ic_nport].ir_end = 212bb2b9030SDoug Rabson I16(resinfo) + resinfo[2] - 1; 2135b45337dSDoug Rabson config->ic_port[config->ic_nport].ir_size 2145b45337dSDoug Rabson = resinfo[2]; 2155b45337dSDoug Rabson config->ic_port[config->ic_nport].ir_align = 1; 2165b45337dSDoug Rabson config->ic_nport++; 2175b45337dSDoug Rabson break; 2185b45337dSDoug Rabson 219bb2b9030SDoug Rabson case PNP_TAG_END: 220bb2b9030SDoug Rabson if (bootverbose) { 221acd3131bSDoug Rabson printf("%s: end config\n", 222bb2b9030SDoug Rabson pnp_eisaformat(id)); 223bb2b9030SDoug Rabson } 224bb2b9030SDoug Rabson scanning = 0; 225bb2b9030SDoug Rabson break; 226bb2b9030SDoug Rabson 2275b45337dSDoug Rabson default: 2285b45337dSDoug Rabson /* Skip this resource */ 229acd3131bSDoug Rabson device_printf(parent, "unexpected small tag %d\n", 2305b45337dSDoug Rabson PNP_SRES_NUM(tag)); 2315b45337dSDoug Rabson break; 2325b45337dSDoug Rabson } 2335b45337dSDoug Rabson } else { 2345b45337dSDoug Rabson /* Large resource */ 2355b45337dSDoug Rabson if (scanning < 2) { 2365b45337dSDoug Rabson scanning = 0; 2375b45337dSDoug Rabson continue; 2385b45337dSDoug Rabson } 239bb2b9030SDoug Rabson large_len = I16(resp); 2405b45337dSDoug Rabson resp += 2; 2415b45337dSDoug Rabson scanning -= 2; 2425b45337dSDoug Rabson 2435b45337dSDoug Rabson if (scanning < large_len) { 2445b45337dSDoug Rabson scanning = 0; 2455b45337dSDoug Rabson continue; 2465b45337dSDoug Rabson } 2475b45337dSDoug Rabson resinfo = resp; 2485b45337dSDoug Rabson resp += large_len; 2495b45337dSDoug Rabson scanning -= large_len; 2505b45337dSDoug Rabson 251bb2b9030SDoug Rabson switch (PNP_LRES_NUM(tag)) { 252bb2b9030SDoug Rabson case PNP_TAG_ID_ANSI: 2535b45337dSDoug Rabson if (large_len > sizeof(buf) - 1) 2545b45337dSDoug Rabson large_len = sizeof(buf) - 1; 2555b45337dSDoug Rabson bcopy(resinfo, buf, large_len); 2565b45337dSDoug Rabson 2575b45337dSDoug Rabson /* 258acd3131bSDoug Rabson * Trim trailing spaces and garbage. 2595b45337dSDoug Rabson */ 260acd3131bSDoug Rabson while (large_len > 0 && buf[large_len - 1] <= ' ') 2615b45337dSDoug Rabson large_len--; 2625b45337dSDoug Rabson buf[large_len] = '\0'; 2635b45337dSDoug Rabson device_set_desc_copy(dev, buf); 264bb2b9030SDoug Rabson break; 2655b45337dSDoug Rabson 266bb2b9030SDoug Rabson case PNP_TAG_MEMORY_RANGE: 267bb2b9030SDoug Rabson if (bootverbose) { 2681f1624dcSDoug Rabson int temp = I16(resinfo + 7) << 8; 2691f1624dcSDoug Rabson 270bb2b9030SDoug Rabson printf("%s: adding memory range " 271bb2b9030SDoug Rabson "%#x-%#x, size=%#x, " 272bb2b9030SDoug Rabson "align=%#x\n", 273bb2b9030SDoug Rabson pnp_eisaformat(id), 274bb2b9030SDoug Rabson I16(resinfo + 1)<<8, 2751f1624dcSDoug Rabson (I16(resinfo + 3)<<8) + temp - 1, 2761f1624dcSDoug Rabson temp, 277bb2b9030SDoug Rabson I16(resinfo + 5)); 2785b45337dSDoug Rabson } 2795b45337dSDoug Rabson 2805b45337dSDoug Rabson if (config->ic_nmem == ISA_NMEM) { 281ca403ff8SDoug Rabson device_printf(parent, "too many memory ranges\n"); 2825b45337dSDoug Rabson scanning = 0; 2835b45337dSDoug Rabson break; 2845b45337dSDoug Rabson } 2855b45337dSDoug Rabson 2865b45337dSDoug Rabson config->ic_mem[config->ic_nmem].ir_start = 287bb2b9030SDoug Rabson I16(resinfo + 1)<<8; 2885b45337dSDoug Rabson config->ic_mem[config->ic_nmem].ir_end = 289bb2b9030SDoug Rabson (I16(resinfo + 3)<<8) 2901f1624dcSDoug Rabson + (I16(resinfo + 7) << 8) - 1; 2915b45337dSDoug Rabson config->ic_mem[config->ic_nmem].ir_size = 2921f1624dcSDoug Rabson I16(resinfo + 7) << 8; 2935b45337dSDoug Rabson config->ic_mem[config->ic_nmem].ir_align = 294bb2b9030SDoug Rabson I16(resinfo + 5); 2955b45337dSDoug Rabson if (!config->ic_mem[config->ic_nmem].ir_align) 296bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem] 297bb2b9030SDoug Rabson .ir_align = 0x10000; 2985b45337dSDoug Rabson config->ic_nmem++; 299bb2b9030SDoug Rabson break; 300bb2b9030SDoug Rabson 301bb2b9030SDoug Rabson case PNP_TAG_MEMORY32_RANGE: 302bb2b9030SDoug Rabson if (bootverbose) { 303acd3131bSDoug Rabson printf("%s: adding memory32 range " 304bb2b9030SDoug Rabson "%#x-%#x, size=%#x, " 305bb2b9030SDoug Rabson "align=%#x\n", 306bb2b9030SDoug Rabson pnp_eisaformat(id), 307bb2b9030SDoug Rabson I32(resinfo + 1), 308bb2b9030SDoug Rabson I32(resinfo + 5) 309bb2b9030SDoug Rabson + I32(resinfo + 13) - 1, 310bb2b9030SDoug Rabson I32(resinfo + 13), 311bb2b9030SDoug Rabson I32(resinfo + 9)); 312bb2b9030SDoug Rabson } 313bb2b9030SDoug Rabson 314bb2b9030SDoug Rabson if (config->ic_nmem == ISA_NMEM) { 315acd3131bSDoug Rabson device_printf(parent, "too many memory ranges\n"); 316bb2b9030SDoug Rabson scanning = 0; 317bb2b9030SDoug Rabson break; 318bb2b9030SDoug Rabson } 319bb2b9030SDoug Rabson 320bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_start = 321bb2b9030SDoug Rabson I32(resinfo + 1); 322bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_end = 323bb2b9030SDoug Rabson I32(resinfo + 5) 324bb2b9030SDoug Rabson + I32(resinfo + 13) - 1; 325bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_size = 326bb2b9030SDoug Rabson I32(resinfo + 13); 327bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_align = 328bb2b9030SDoug Rabson I32(resinfo + 9); 329bb2b9030SDoug Rabson config->ic_nmem++; 330bb2b9030SDoug Rabson break; 331bb2b9030SDoug Rabson 332bb2b9030SDoug Rabson case PNP_TAG_MEMORY32_FIXED: 333bb2b9030SDoug Rabson if (I32(resinfo + 5) == 0) { 334bb2b9030SDoug Rabson if (bootverbose) { 335bb2b9030SDoug Rabson printf("%s: skipping empty range\n", 336bb2b9030SDoug Rabson pnp_eisaformat(id)); 337bb2b9030SDoug Rabson } 338bb2b9030SDoug Rabson continue; 339bb2b9030SDoug Rabson } 340bb2b9030SDoug Rabson if (bootverbose) { 341acd3131bSDoug Rabson printf("%s: adding fixed memory32 range " 342bb2b9030SDoug Rabson "%#x-%#x, size=%#x\n", 343bb2b9030SDoug Rabson pnp_eisaformat(id), 344bb2b9030SDoug Rabson I32(resinfo + 1), 345bb2b9030SDoug Rabson I32(resinfo + 1) 346bb2b9030SDoug Rabson + I32(resinfo + 5) - 1, 347bb2b9030SDoug Rabson I32(resinfo + 5)); 348bb2b9030SDoug Rabson } 349bb2b9030SDoug Rabson 350bb2b9030SDoug Rabson if (config->ic_nmem == ISA_NMEM) { 351acd3131bSDoug Rabson device_printf(parent, "too many memory ranges\n"); 352bb2b9030SDoug Rabson scanning = 0; 353bb2b9030SDoug Rabson break; 354bb2b9030SDoug Rabson } 355bb2b9030SDoug Rabson 356bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_start = 357bb2b9030SDoug Rabson I32(resinfo + 1); 358bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_end = 359bb2b9030SDoug Rabson I32(resinfo + 1) 360bb2b9030SDoug Rabson + I32(resinfo + 5) - 1; 361bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_size = 362bb2b9030SDoug Rabson I32(resinfo + 5); 363bb2b9030SDoug Rabson config->ic_mem[config->ic_nmem].ir_align = 1; 364bb2b9030SDoug Rabson config->ic_nmem++; 365bb2b9030SDoug Rabson break; 366bb2b9030SDoug Rabson 367bb2b9030SDoug Rabson default: 368bb2b9030SDoug Rabson /* Skip this resource */ 369acd3131bSDoug Rabson device_printf(parent, "unexpected large tag %d\n", 370bb2b9030SDoug Rabson PNP_SRES_NUM(tag)); 371bb2b9030SDoug Rabson } 3725b45337dSDoug Rabson } 3735b45337dSDoug Rabson } 374acd3131bSDoug Rabson if(ncfgs == 1) { 375acd3131bSDoug Rabson /* Single config without dependants */ 376acd3131bSDoug Rabson (void)ISA_ADD_CONFIG(parent, dev, priorities[0], &configs[0]); 377ca403ff8SDoug Rabson free(configs, M_DEVBUF); 378acd3131bSDoug Rabson return; 3795b45337dSDoug Rabson } 380acd3131bSDoug Rabson /* Cycle through dependant configs merging primary details */ 381acd3131bSDoug Rabson for(i = 1; i < ncfgs; i++) { 382acd3131bSDoug Rabson int j; 383acd3131bSDoug Rabson config = &configs[i]; 384acd3131bSDoug Rabson for(j = 0; j < configs[0].ic_nmem; j++) { 385acd3131bSDoug Rabson if (config->ic_nmem == ISA_NMEM) { 386acd3131bSDoug Rabson device_printf(parent, "too many memory ranges\n"); 387ca403ff8SDoug Rabson free(configs, M_DEVBUF); 388acd3131bSDoug Rabson return; 389acd3131bSDoug Rabson } 390acd3131bSDoug Rabson config->ic_mem[config->ic_nmem] = configs[0].ic_mem[j]; 391acd3131bSDoug Rabson config->ic_nmem++; 392acd3131bSDoug Rabson } 393acd3131bSDoug Rabson for(j = 0; j < configs[0].ic_nport; j++) { 394acd3131bSDoug Rabson if (config->ic_nport == ISA_NPORT) { 395acd3131bSDoug Rabson device_printf(parent, "too many port ranges\n"); 396ca403ff8SDoug Rabson free(configs, M_DEVBUF); 397acd3131bSDoug Rabson return; 398acd3131bSDoug Rabson } 399acd3131bSDoug Rabson config->ic_port[config->ic_nport] = configs[0].ic_port[j]; 400acd3131bSDoug Rabson config->ic_nport++; 401acd3131bSDoug Rabson } 402acd3131bSDoug Rabson for(j = 0; j < configs[0].ic_nirq; j++) { 403acd3131bSDoug Rabson if (config->ic_nirq == ISA_NIRQ) { 404acd3131bSDoug Rabson device_printf(parent, "too many irq ranges\n"); 405ca403ff8SDoug Rabson free(configs, M_DEVBUF); 406acd3131bSDoug Rabson return; 407acd3131bSDoug Rabson } 408acd3131bSDoug Rabson config->ic_irqmask[config->ic_nirq] = configs[0].ic_irqmask[j]; 409acd3131bSDoug Rabson config->ic_nirq++; 410acd3131bSDoug Rabson } 411acd3131bSDoug Rabson for(j = 0; j < configs[0].ic_ndrq; j++) { 412acd3131bSDoug Rabson if (config->ic_ndrq == ISA_NDRQ) { 413acd3131bSDoug Rabson device_printf(parent, "too many drq ranges\n"); 414ca403ff8SDoug Rabson free(configs, M_DEVBUF); 415acd3131bSDoug Rabson return; 416acd3131bSDoug Rabson } 417acd3131bSDoug Rabson config->ic_drqmask[config->ic_ndrq] = configs[0].ic_drqmask[j]; 418acd3131bSDoug Rabson config->ic_ndrq++; 419acd3131bSDoug Rabson } 420acd3131bSDoug Rabson (void)ISA_ADD_CONFIG(parent, dev, priorities[i], &configs[i]); 421acd3131bSDoug Rabson } 422ca403ff8SDoug Rabson free(configs, M_DEVBUF); 423acd3131bSDoug Rabson } 424