eisaconf.c revision 20450
1243791Sdim/* 2243791Sdim * EISA bus probe and attach routines 3243791Sdim * 4243791Sdim * Copyright (c) 1995, 1996 Justin T. Gibbs. 5243791Sdim * All rights reserved. 6243791Sdim * 7243791Sdim * Redistribution and use in source and binary forms, with or without 8243791Sdim * modification, are permitted provided that the following conditions 9243791Sdim * are met: 10243791Sdim * 1. Redistributions of source code must retain the above copyright 11243791Sdim * notice immediately at the beginning of the file, without modification, 12243791Sdim * this list of conditions, and the following disclaimer. 13243791Sdim * 2. Redistributions in binary form must reproduce the above copyright 14243791Sdim * notice, this list of conditions and the following disclaimer in the 15249423Sdim * documentation and/or other materials provided with the distribution. 16249423Sdim * 3. The name of the author may not be used to endorse or promote products 17243791Sdim * derived from this software without specific prior written permission. 18249423Sdim * 19243791Sdim * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 20249423Sdim * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21243791Sdim * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22243791Sdim * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR 23243791Sdim * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24243791Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25243791Sdim * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26243791Sdim * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27243791Sdim * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28243791Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29243791Sdim * SUCH DAMAGE. 30243791Sdim * 31243791Sdim * $Id: eisaconf.c,v 1.23 1996/09/08 10:43:42 phk Exp $ 32243791Sdim */ 33243791Sdim#include <sys/param.h> 34243791Sdim#include <sys/systm.h> 35243791Sdim#include <sys/kernel.h> 36243791Sdim#include <sys/sysctl.h> 37243791Sdim#include <sys/conf.h> 38243791Sdim#include <sys/malloc.h> 39243791Sdim 40243791Sdim#include <i386/eisa/eisaconf.h> 41243791Sdim 42243791Sdim#include <i386/isa/icu.h> /* Hmmm. Interrupt stuff? */ 43243791Sdim 44243791Sdimstruct eisa_device_node{ 45243791Sdim struct eisa_device dev; 46243791Sdim struct eisa_device_node *next; 47243791Sdim}; 48243791Sdim 49243791Sdim/* 50243791Sdim * This should probably be a list of "struct device" once it exists. 51243791Sdim * A struct device will incorperate ioconf and driver entry point data 52243791Sdim * regardless of how its attached to the system (via unions) as well 53243791Sdim * as more generic information that all device types should support (unit 54243791Sdim * number, if its installed, etc). 55243791Sdim */ 56243791Sdimstatic struct eisa_device_node *eisa_dev_list; 57243791Sdimstatic struct eisa_device_node **eisa_dev_list_tail = &eisa_dev_list; 58243791Sdimstatic u_long eisa_unit; 59243791Sdim 60243791Sdimstatic struct eisa_driver mainboard_drv = { 61243791Sdim "eisa", 62243791Sdim NULL, 63243791Sdim NULL, 64243791Sdim NULL, 65243791Sdim &eisa_unit 66243791Sdim }; 67243791Sdim 68243791Sdim/* 69243791Sdim * Add the mainboard_drv to the eisa driver linkerset so that it is 70243791Sdim * defined even if no EISA drivers are linked into the kernel. 71243791Sdim */ 72243791SdimDATA_SET (eisadriver_set, mainboard_drv); 73243791Sdim 74243791Sdim/* 75243791Sdim * Local function declarations and static variables 76243791Sdim */ 77243791Sdimvoid eisa_reg_print __P((struct eisa_device *e_dev, char *string, 78243791Sdim char *separator)); 79243791Sdimstatic int eisa_add_resvaddr __P((struct eisa_device *e_dev, 80243791Sdim struct resvlist *head, u_long base, 81243791Sdim u_long size, int flags)); 82243791Sdimstatic int eisa_reg_resvaddr __P((struct eisa_device *e_dev, 83243791Sdim struct resvlist *head, resvaddr_t *resvaddr, 84243791Sdim int *reg_count)); 85243791Sdim 86243791Sdim/* 87243791Sdim * Keep some state about what we've printed so far 88243791Sdim * to make probe output pretty. 89243791Sdim */ 90243791Sdimstatic struct { 91243791Sdim int in_registration;/* reg_start has been called */ 92243791Sdim int num_interrupts; 93243791Sdim int num_ioaddrs; 94243791Sdim int num_maddrs; 95243791Sdim int column; /* How much we have output so far. */ 96243791Sdim#define MAX_COL 80 97243791Sdim} reg_state; 98243791Sdim 99243791Sdim/* XXX Global variable, so UserConfig can change it. */ 100243791Sdimint num_eisa_slots = EISA_SLOTS; 101243791Sdim 102243791Sdim/* 103243791Sdim** probe for EISA devices 104243791Sdim*/ 105243791Sdimvoid 106243791Sdimeisa_configure() 107243791Sdim{ 108243791Sdim int i,slot; 109243791Sdim char *id_string; 110243791Sdim struct eisa_device_node *dev_node; 111243791Sdim struct eisa_driver **e_drvp; 112243791Sdim struct eisa_driver *e_drv; 113243791Sdim struct eisa_device *e_dev; 114243791Sdim int eisaBase = 0xc80; 115243791Sdim eisa_id_t eisa_id; 116243791Sdim 117243791Sdim e_drvp = (struct eisa_driver**)eisadriver_set.ls_items; 118243791Sdim 119243791Sdim for (slot = 0; slot < num_eisa_slots; eisaBase+=0x1000, slot++) { 120243791Sdim int id_size = sizeof(eisa_id); 121243791Sdim eisa_id = 0; 122243791Sdim for( i = 0; i < id_size; i++ ) { 123243791Sdim outb(eisaBase,0x80 + i); /*Some cards require priming*/ 124243791Sdim eisa_id |= inb(eisaBase+i) << ((id_size-i-1)*CHAR_BIT); 125243791Sdim } 126243791Sdim if (eisa_id & 0x80000000) 127243791Sdim continue; /* no EISA card in slot */ 128243791Sdim 129243791Sdim /* Prepare an eisa_device_node for this slot */ 130243791Sdim dev_node = (struct eisa_device_node *)malloc(sizeof(*dev_node), 131243791Sdim M_DEVBUF, M_NOWAIT); 132243791Sdim if (!dev_node) { 133243791Sdim printf("eisa0: cannot malloc eisa_device_node"); 134243791Sdim break; /* Try to attach what we have already */ 135243791Sdim } 136243791Sdim bzero(dev_node, sizeof(*dev_node)); 137243791Sdim e_dev = &(dev_node->dev); 138243791Sdim 139243791Sdim e_dev->id = eisa_id; 140243791Sdim /* 141243791Sdim * Add an EISA ID based descriptive name incase we don't 142243791Sdim * have a driver for it. We do this now instead of after all 143243791Sdim * probes because in the future, the eisa module will only 144243791Sdim * be responsible for creating the list of devices in the system 145243791Sdim * for the configuration manager to use. 146243791Sdim */ 147243791Sdim e_dev->full_name = (char *)malloc(8*sizeof(char), 148243791Sdim M_DEVBUF, M_NOWAIT); 149243791Sdim if (!e_dev->full_name) { 150243791Sdim panic("Eisa probe unable to malloc"); 151243791Sdim } 152243791Sdim sprintf(e_dev->full_name, "%c%c%c%x%x", 153243791Sdim EISA_MFCTR_CHAR0(e_dev->id), 154243791Sdim EISA_MFCTR_CHAR1(e_dev->id), 155243791Sdim EISA_MFCTR_CHAR2(e_dev->id), 156243791Sdim EISA_PRODUCT_ID(e_dev->id), 157243791Sdim EISA_REVISION_ID(e_dev->id)); 158243791Sdim 159243791Sdim e_dev->ioconf.slot = slot; 160243791Sdim 161243791Sdim /* Initialize our lists of reserved addresses */ 162243791Sdim LIST_INIT(&(e_dev->ioconf.ioaddrs)); 163243791Sdim LIST_INIT(&(e_dev->ioconf.maddrs)); 164243791Sdim 165243791Sdim *eisa_dev_list_tail = dev_node; 166243791Sdim eisa_dev_list_tail = &dev_node->next; 167263508Sdim } 168243791Sdim 169243791Sdim dev_node = eisa_dev_list; 170243791Sdim 171243791Sdim /* 172243791Sdim * "Attach" the system board 173243791Sdim */ 174243791Sdim 175243791Sdim /* The first will be the motherboard in a true EISA system */ 176243791Sdim if (dev_node && (dev_node->dev.ioconf.slot == 0)) { 177243791Sdim e_dev = &dev_node->dev; 178243791Sdim e_dev->driver = &mainboard_drv; 179243791Sdim e_dev->unit = (*e_dev->driver->unit)++; 180243791Sdim id_string = e_dev->full_name; 181243791Sdim e_dev->full_name = (char *)malloc(strlen(e_dev->full_name) 182243791Sdim + sizeof(" (System Board)") 183243791Sdim + 1, M_DEVBUF, M_NOWAIT); 184243791Sdim if (!e_dev->full_name) { 185243791Sdim panic("Eisa probe unable to malloc"); 186243791Sdim } 187243791Sdim sprintf(e_dev->full_name, "%s (System Board)", id_string); 188243791Sdim free(id_string, M_DEVBUF); 189243791Sdim 190243791Sdim printf("%s%ld: <%s>\n", 191243791Sdim e_dev->driver->name, 192243791Sdim e_dev->unit, 193243791Sdim e_dev->full_name); 194243791Sdim 195243791Sdim /* Should set the iosize, but I don't have a spec handy */ 196243791Sdim printf("Probing for devices on the EISA bus\n"); 197243791Sdim dev_node = dev_node->next; 198243791Sdim } 199243791Sdim 200243791Sdim if (!eisa_dev_list) { 201243791Sdim /* 202243791Sdim * No devices. 203243791Sdim */ 204243791Sdim return; 205243791Sdim } 206243791Sdim /* 207243791Sdim * See what devices we recognize. 208243791Sdim */ 209243791Sdim while((e_drv = *e_drvp++)) { 210243791Sdim if (e_drv->probe) 211243791Sdim (*e_drv->probe)(); 212243791Sdim } 213243791Sdim 214243791Sdim /* 215243791Sdim * Attach the devices we found in slot order 216243791Sdim */ 217243791Sdim for (; dev_node; dev_node=dev_node->next) { 218243791Sdim e_dev = &dev_node->dev; 219243791Sdim e_drv = e_dev->driver; 220243791Sdim 221243791Sdim if (e_drv) { 222243791Sdim /* 223243791Sdim * Determine the proper unit number for this device. 224243791Sdim * Here we should look in the device table generated 225243791Sdim * by config to see if this type of device is enabled 226243791Sdim * either generically or for this particular address 227243791Sdim * as well as determine if a reserved unit number 228243791Sdim * should be used. We should also ensure that the 229243791Sdim * "next availible unit number" skips over "wired" unit 230243791Sdim * numbers. This will be done after config is fixed or 231243791Sdim * some other configuration method is chosen. 232243791Sdim */ 233243791Sdim e_dev->unit = (*e_drv->unit)++; 234243791Sdim if ((*e_drv->attach)(e_dev) < 0) { 235243791Sdim /* Ensure registration has ended */ 236243791Sdim reg_state.in_registration = 0; 237243791Sdim printf("\n%s0:%d <%s> attach failed\n", 238243791Sdim mainboard_drv.name, 239243791Sdim e_dev->ioconf.slot, 240243791Sdim e_dev->full_name); 241243791Sdim continue; 242243791Sdim } 243243791Sdim /* Ensure registration has ended */ 244243791Sdim reg_state.in_registration = 0; 245243791Sdim } 246243791Sdim else { 247243791Sdim /* Announce unattached device */ 248243791Sdim printf("%s0:%d <%s=0x%x> unknown device\n", 249243791Sdim mainboard_drv.name, 250243791Sdim e_dev->ioconf.slot, 251243791Sdim e_dev->full_name, 252243791Sdim e_dev->id); 253243791Sdim } 254243791Sdim } 255243791Sdim} 256243791Sdim 257243791Sdimstruct eisa_device * 258243791Sdimeisa_match_dev(e_dev, match_func) 259243791Sdim struct eisa_device *e_dev; 260243791Sdim char* (*match_func)(eisa_id_t); 261243791Sdim{ 262243791Sdim struct eisa_device_node *e_node = eisa_dev_list; 263243791Sdim 264243791Sdim if (e_dev) { 265243791Sdim /* Start our search from the last successful match */ 266243791Sdim e_node = ((struct eisa_device_node *)e_dev)->next; 267243791Sdim } 268243791Sdim 269243791Sdim for(; e_node; e_node = e_node->next) { 270243791Sdim char *result; 271243791Sdim if (e_node->dev.driver) { 272243791Sdim /* Already claimed */ 273243791Sdim continue; 274243791Sdim } 275243791Sdim result = (*match_func)(e_node->dev.id); 276243791Sdim if (result) { 277243791Sdim free(e_node->dev.full_name, M_DEVBUF); 278243791Sdim e_node->dev.full_name = result; 279243791Sdim return (&(e_node->dev)); 280243791Sdim } 281243791Sdim } 282243791Sdim return NULL; 283243791Sdim} 284243791Sdim 285243791Sdim/* Interrupt and I/O space registration facitlities */ 286243791Sdimvoid 287243791Sdimeisa_reg_start(e_dev) 288243791Sdim struct eisa_device *e_dev; 289243791Sdim{ 290243791Sdim /* 291243791Sdim * Announce the device. 292243791Sdim */ 293243791Sdim char *string; 294243791Sdim 295243791Sdim reg_state.in_registration = 1; 296243791Sdim reg_state.num_interrupts = 0; 297243791Sdim reg_state.num_ioaddrs = 0; 298243791Sdim reg_state.num_maddrs = 0; 299243791Sdim reg_state.column = 0; 300243791Sdim 301243791Sdim string = malloc(strlen(e_dev->full_name) + sizeof(" <>") + /*NULL*/1, 302243791Sdim M_TEMP, M_NOWAIT); 303243791Sdim if(!string) { 304243791Sdim printf("eisa0: cannot malloc device description string\n"); 305243791Sdim return; 306243791Sdim } 307243791Sdim sprintf(string, " <%s>", e_dev->full_name); 308243791Sdim eisa_reg_print(e_dev, string, /*separator=*/NULL); 309243791Sdim free(string, M_TEMP); 310243791Sdim} 311243791Sdim 312243791Sdim/* 313243791Sdim * Output registration information mindfull of screen wrap. 314243791Sdim * Output an optional character separator before the string 315243791Sdim * if the line does not wrap. 316243791Sdim */ 317243791Sdimvoid 318243791Sdimeisa_reg_print(e_dev, string, separator) 319243791Sdim struct eisa_device *e_dev; 320243791Sdim char *string; 321243791Sdim char *separator; 322243791Sdim{ 323243791Sdim int len = strlen(string); 324243791Sdim 325243791Sdim if(separator) 326243791Sdim len++; 327243791Sdim 328243791Sdim if(reg_state.column + len > MAX_COL) { 329243791Sdim printf("\n"); 330243791Sdim reg_state.column = 0; 331243791Sdim } 332243791Sdim else if(separator) { 333243791Sdim printf("%c", *separator); 334243791Sdim reg_state.column++; 335243791Sdim } 336243791Sdim 337243791Sdim if(reg_state.column == 0) 338243791Sdim reg_state.column += printf("%s%ld:%s", 339243791Sdim e_dev->driver->name, 340243791Sdim e_dev->unit, 341243791Sdim string); 342243791Sdim else 343243791Sdim reg_state.column += printf("%s", string); 344243791Sdim} 345243791Sdim 346243791Sdim/* Interrupt and I/O space registration facitlities */ 347243791Sdimvoid 348243791Sdimeisa_reg_end(e_dev) 349243791Sdim struct eisa_device *e_dev; 350243791Sdim{ 351243791Sdim if( reg_state.in_registration ) 352243791Sdim { 353243791Sdim char string[25]; 354243791Sdim 355243791Sdim sprintf(string, " on %s0 slot %d", 356243791Sdim mainboard_drv.name, 357243791Sdim e_dev->ioconf.slot); 358243791Sdim eisa_reg_print(e_dev, string, NULL); 359243791Sdim printf("\n"); 360243791Sdim reg_state.in_registration = 0; 361243791Sdim } 362243791Sdim else 363263508Sdim printf("eisa_reg_end called outside of a " 364243791Sdim "registration session\n"); 365243791Sdim} 366243791Sdim 367243791Sdimint 368243791Sdimeisa_add_intr(e_dev, irq) 369243791Sdim struct eisa_device *e_dev; 370243791Sdim int irq; 371243791Sdim{ 372243791Sdim e_dev->ioconf.irq |= 1ul << irq; 373243791Sdim return 0; 374243791Sdim} 375243791Sdim 376243791Sdimint 377243791Sdimeisa_reg_intr(e_dev, irq, func, arg, maskptr, shared) 378243791Sdim struct eisa_device *e_dev; 379243791Sdim int irq; 380243791Sdim void (*func)(void *); 381243791Sdim void *arg; 382243791Sdim u_int *maskptr; 383243791Sdim int shared; 384243791Sdim{ 385243791Sdim int result; 386243791Sdim int s; 387243791Sdim char string[25]; 388243791Sdim char separator = ','; 389243791Sdim 390243791Sdim#if NOT_YET 391243791Sdim /* 392243791Sdim * Punt on conflict detection for the moment. 393243791Sdim * I want to develop a generic routine to do 394243791Sdim * this for all device types. 395243791Sdim */ 396243791Sdim int checkthese = CC_IRQ; 397243791Sdim if (haveseen_dev(dev, checkthese)) 398243791Sdim return 1; 399243791Sdim#endif 400243791Sdim if (reg_state.in_registration) { 401243791Sdim s = splhigh(); 402243791Sdim /* 403243791Sdim * This should really go to a routine that can optionally 404243791Sdim * handle shared interrupts. 405243791Sdim */ 406243791Sdim result = register_intr(irq, /* isa irq */ 407243791Sdim 0, /* deviced?? */ 408243791Sdim 0, /* flags? */ 409243791Sdim (inthand2_t*) func, /* handler */ 410243791Sdim maskptr, /* mask pointer */ 411243791Sdim (int)arg); /* handler arg */ 412243791Sdim 413243791Sdim if (result) { 414243791Sdim printf ("\neisa_reg_int: result=%d\n", result); 415243791Sdim splx(s); 416243791Sdim return (result); 417243791Sdim }; 418243791Sdim update_intr_masks(); 419243791Sdim splx(s); 420243791Sdim } 421243791Sdim else 422243791Sdim return EPERM; 423243791Sdim 424243791Sdim e_dev->ioconf.irq |= 1ul << irq; 425243791Sdim sprintf(string, " irq %d", irq); 426243791Sdim eisa_reg_print(e_dev, string, reg_state.num_interrupts ? 427243791Sdim &separator : NULL); 428243791Sdim reg_state.num_interrupts++; 429243791Sdim return (0); 430243791Sdim} 431243791Sdim 432243791Sdimint 433243791Sdimeisa_release_intr(e_dev, irq, func) 434243791Sdim struct eisa_device *e_dev; 435243791Sdim int irq; 436243791Sdim void (*func)(void *); 437243791Sdim{ 438243791Sdim int result; 439243791Sdim int s; 440243791Sdim 441243791Sdim if (!(e_dev->ioconf.irq & (1ul << irq))) { 442243791Sdim printf("%s%ld: Attempted to release an interrupt (%d) " 443243791Sdim "it doesn't own\n", e_dev->driver->name, 444243791Sdim e_dev->unit, irq); 445243791Sdim return (-1); 446243791Sdim } 447243791Sdim 448243791Sdim s = splhigh(); 449243791Sdim INTRDIS ((1ul<<irq)); 450243791Sdim 451243791Sdim result = unregister_intr (irq, (inthand2_t*)func); 452243791Sdim 453243791Sdim if (result) 454243791Sdim printf ("eisa_release_intr: result=%d\n", result); 455243791Sdim 456243791Sdim update_intr_masks(); 457243791Sdim 458243791Sdim splx(s); 459243791Sdim return (result); 460243791Sdim} 461243791Sdim 462243791Sdimint 463243791Sdimeisa_enable_intr(e_dev, irq) 464243791Sdim struct eisa_device *e_dev; 465243791Sdim int irq; 466243791Sdim{ 467243791Sdim int s; 468243791Sdim 469243791Sdim if (!(e_dev->ioconf.irq & (1ul << irq))) { 470243791Sdim printf("%s%ld: Attempted to enable an interrupt (%d) " 471243791Sdim "it doesn't own\n", e_dev->driver->name, 472243791Sdim e_dev->unit, irq); 473243791Sdim return (-1); 474243791Sdim } 475243791Sdim s = splhigh(); 476243791Sdim INTREN((1ul << irq)); 477243791Sdim splx(s); 478243791Sdim return 0; 479243791Sdim} 480243791Sdim 481243791Sdimstatic int 482243791Sdimeisa_add_resvaddr(e_dev, head, base, size, flags) 483243791Sdim struct eisa_device *e_dev; 484243791Sdim struct resvlist *head; 485243791Sdim u_long base; 486243791Sdim u_long size; 487243791Sdim int flags; 488243791Sdim{ 489243791Sdim resvaddr_t *reservation; 490243791Sdim 491243791Sdim reservation = (resvaddr_t *)malloc(sizeof(resvaddr_t), 492243791Sdim M_DEVBUF, M_NOWAIT); 493243791Sdim if(!reservation) 494243791Sdim return (ENOMEM); 495243791Sdim 496243791Sdim reservation->addr = base; 497243791Sdim reservation->size = size; 498243791Sdim reservation->flags = flags; 499243791Sdim 500243791Sdim if (!head->lh_first) { 501243791Sdim LIST_INSERT_HEAD(head, reservation, links); 502243791Sdim } 503243791Sdim else { 504243791Sdim resvaddr_t *node; 505243791Sdim for(node = head->lh_first; node; node = node->links.le_next) { 506243791Sdim if (node->addr > reservation->addr) { 507243791Sdim /* 508243791Sdim * List is sorted in increasing 509243791Sdim * address order. 510243791Sdim */ 511243791Sdim LIST_INSERT_BEFORE(node, reservation, links); 512243791Sdim break; 513243791Sdim } 514243791Sdim 515243791Sdim if (node->addr == reservation->addr) { 516243791Sdim /* 517243791Sdim * If the entry we want to add 518243791Sdim * matches any already in here, 519243791Sdim * fail. 520243791Sdim */ 521243791Sdim free(reservation, M_DEVBUF); 522243791Sdim return (EEXIST); 523243791Sdim } 524243791Sdim 525243791Sdim if (!node->links.le_next) { 526243791Sdim LIST_INSERT_AFTER(node, reservation, links); 527243791Sdim break; 528243791Sdim } 529243791Sdim } 530243791Sdim } 531243791Sdim return (0); 532243791Sdim} 533243791Sdim 534243791Sdimint 535243791Sdimeisa_add_mspace(e_dev, mbase, msize, flags) 536243791Sdim struct eisa_device *e_dev; 537243791Sdim u_long mbase; 538243791Sdim u_long msize; 539243791Sdim int flags; 540243791Sdim{ 541243791Sdim return eisa_add_resvaddr(e_dev, &(e_dev->ioconf.maddrs), mbase, msize, 542243791Sdim flags); 543243791Sdim} 544243791Sdim 545243791Sdimint 546243791Sdimeisa_add_iospace(e_dev, iobase, iosize, flags) 547243791Sdim struct eisa_device *e_dev; 548243791Sdim u_long iobase; 549243791Sdim u_long iosize; 550243791Sdim int flags; 551243791Sdim{ 552243791Sdim return eisa_add_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), iobase, 553243791Sdim iosize, flags); 554243791Sdim} 555243791Sdim 556243791Sdimstatic int 557243791Sdimeisa_reg_resvaddr(e_dev, head, resvaddr, reg_count) 558243791Sdim struct eisa_device *e_dev; 559243791Sdim struct resvlist *head; 560243791Sdim resvaddr_t *resvaddr; 561243791Sdim int *reg_count; 562243791Sdim{ 563243791Sdim if (reg_state.in_registration) { 564243791Sdim resvaddr_t *node; 565243791Sdim /* 566243791Sdim * Ensure that this resvaddr is actually in the devices' 567243791Sdim * reservation list. 568243791Sdim */ 569243791Sdim for(node = head->lh_first; node; 570243791Sdim node = node->links.le_next) { 571243791Sdim if (node == resvaddr) { 572243791Sdim char buf[35]; 573243791Sdim char separator = ','; 574243791Sdim char *string = buf; 575243791Sdim 576243791Sdim if (*reg_count == 0) { 577243791Sdim /* First time */ 578243791Sdim string += sprintf(string, " at"); 579243791Sdim } 580243791Sdim 581243791Sdim if (node->size == 1 582243791Sdim || (node->flags & RESVADDR_BITMASK)) 583 sprintf(string, " 0x%lx", node->addr); 584 else 585 sprintf(string, " 0x%lx-0x%lx", 586 node->addr, 587 node->addr + node->size - 1); 588 eisa_reg_print(e_dev, buf, 589 *reg_count ? &separator : NULL); 590 (*reg_count)++; 591 return (0); 592 } 593 } 594 return (ENOENT); 595 } 596 return EPERM; 597} 598 599int 600eisa_reg_mspace(e_dev, resvaddr) 601 struct eisa_device *e_dev; 602 resvaddr_t *resvaddr; 603{ 604#ifdef NOT_YET 605 /* 606 * Punt on conflict detection for the moment. 607 * I want to develop a generic routine to do 608 * this for all device types. 609 */ 610 int checkthese = CC_MADDR; 611 if (haveseen_dev(dev, checkthese)) 612 return -1; 613#endif 614 return (eisa_reg_resvaddr(e_dev, &(e_dev->ioconf.maddrs), resvaddr, 615 &(reg_state.num_maddrs))); 616} 617 618int 619eisa_reg_iospace(e_dev, resvaddr) 620 struct eisa_device *e_dev; 621 resvaddr_t *resvaddr; 622{ 623#ifdef NOT_YET 624 /* 625 * Punt on conflict detection for the moment. 626 * I want to develop a generic routine to do 627 * this for all device types. 628 */ 629 int checkthese = CC_IOADDR; 630 if (haveseen_dev(dev, checkthese)) 631 return -1; 632#endif 633 return (eisa_reg_resvaddr(e_dev, &(e_dev->ioconf.ioaddrs), resvaddr, 634 &(reg_state.num_ioaddrs))); 635} 636 637int 638eisa_registerdev(e_dev, driver) 639 struct eisa_device *e_dev; 640 struct eisa_driver *driver; 641{ 642 e_dev->driver = driver; /* Driver now owns this device */ 643 return (0); 644} 645 646