1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)attach.c	2.1 (2.11BSD GTE) 1/10/94
   7:  */
   8: 
   9: /*
  10:  * Attach the passed device:
  11:  *	Patch the interrupt vector
  12:  *	Call the device attach routine
  13:  *
  14:  *	Call (if present) the vector setting routine, passing the
  15:  *	vector from /etc/dtab to the driver.  At present only the
  16:  *	MSCP and TMSCP drivers have routines to do this.  The detach()
  17:  *	routine was removed because it was superfluous.  The kernel no
  18:  *	longer calls every driver's XXroot() entry point at start up time,
  19:  *	thus there is nothing to detach any more.
  20:  */
  21: 
  22: #include <machine/psl.h>
  23: #include <machine/autoconfig.h>
  24: #include <sys/types.h>
  25: #include <a.out.h>
  26: #include <stdio.h>
  27: #include "dtab.h"
  28: #include "ivec.h"
  29: 
  30: extern  int debug;
  31: int vec_set[NVECTOR], num_vec;
  32: 
  33: attach(dp)
  34: DTAB    *dp;
  35: {
  36:     extern int  errno;
  37:     int unit,
  38:         addr,
  39:         ret;
  40:     register HAND   *sp;
  41: 
  42:     if ((unit = find_unit(dp)) == -1) {
  43:         prdev(dp);
  44:         printf(" unit already in use\n");
  45:         return;
  46:     }               /* first attach the device */
  47:     if (debug)
  48:         printf("attach: ucall %o(PSL_BR0, %o, %o)\n",dp->dt_attach->n_value,dp->dt_addr,unit);
  49:     else {
  50:         errno = 0;
  51:         if (!(ret = ucall(PSL_BR0, dp->dt_attach->n_value, dp->dt_addr, unit)) || ret == -1) {
  52:             prdev(dp);
  53:             if (ret == -1 && errno) {
  54:                 perror("ucall");
  55:                 exit(AC_SINGLE);
  56:             }
  57:             printf(" attach failed\n");
  58:             return;
  59:         }
  60:     }               /* then fill the interrupt vector */
  61:     addr = dp->dt_vector;
  62:     for (sp = (HAND *)dp->dt_handlers;sp;sp = sp->s_next) {
  63:         if (!sp->s_nl->n_value) {
  64:             prdev(dp);
  65:             printf(" no address found for %s\n", sp->s_str);
  66:             exit(AC_SINGLE);
  67:         }
  68:         write_vector(addr, sp->s_nl->n_value, pry(dp) + unit);
  69:         if (num_vec == NVECTOR - 1) {
  70:             printf("Too many vectors to configure\n");
  71:             exit(AC_SINGLE);
  72:         }
  73:         else
  74:             vec_set[num_vec++] = addr;
  75:         addr += IVSIZE;
  76:     }
  77:     prdev(dp);
  78:     if (dp->dt_setvec && dp->dt_setvec->n_value) {
  79:         ret = ucall(PSL_BR0,dp->dt_setvec->n_value,unit,dp->dt_vector);
  80:         if (ret == -1) {
  81:             printf(" vectorset failed\n");
  82:             exit(AC_SINGLE);
  83:         }
  84:     printf(" vectorset");
  85:     }
  86:     printf(" attached\n");
  87: }
  88: 
  89: have_set(vec)
  90: {
  91:     int cnt_vec;
  92: 
  93:     for (cnt_vec = 0;cnt_vec < num_vec;++cnt_vec)
  94:         if (vec_set[cnt_vec] == vec)
  95:             return(1);
  96:     return(0);
  97: }
  98: 
  99: pry(dp)
 100: DTAB    *dp;
 101: {
 102:     switch(dp->dt_br) {
 103:         case 4:
 104:             return(PSL_BR4);
 105:         case 5:
 106:             return(PSL_BR5);
 107:         case 6:
 108:             return(PSL_BR6);
 109:         default:
 110:             prdev(dp);
 111:             printf(": br%d is not supported.  Assuming 7\n", dp->dt_br);
 112:         case 7:
 113:             return(PSL_BR7);
 114:     }
 115: }
 116: 
 117: write_vector(addr,value,pri)
 118: int addr,
 119:     value,
 120:     pri;
 121: {
 122:     stuff(value,addr);
 123:     stuff(pri,addr + sizeof(int));
 124: }
 125: 
 126: /*
 127:  * find_unit -- Add this device to the list of devices if it isn't already
 128:  * in the list somewhere.  If it has an explicit unit number then use that,
 129:  * else fill in the wildcard with next biggest number.
 130:  */
 131: 
 132: find_unit(dp)
 133: DTAB    *dp;
 134: {
 135:     typedef struct done_s   {
 136:         char    *d_name;    /* device name */
 137:         int d_unit;     /* current unit for wildcarding */
 138:         struct  done_s *d_next;
 139:     } DONE;
 140:     static DONE *done,
 141:             *dn;
 142:     int want_unit;
 143:     char    *malloc();
 144: 
 145:     if (!done) {                /* initialize list */
 146:         done = dn = (DONE *)malloc((u_int)(sizeof(DONE)));
 147:         dn->d_name = dp->dt_name;
 148:         dn->d_next = NULL;
 149:         if ((dn->d_unit = dp->dt_unit - 1) < -1)
 150:             dn->d_unit = -1;
 151:     }
 152:     else for (dn = done;;dn = dn->d_next)   /* search list */
 153:         if (!strcmp(dn->d_name,dp->dt_name))
 154:             break;
 155:         else if (!dn->d_next) {
 156:             dn->d_next = (DONE *)malloc((u_int)sizeof(DONE));
 157:             dn = dn->d_next;
 158:             dn->d_next = NULL;
 159:             dn->d_name = dp->dt_name;
 160:             if ((dn->d_unit = dp->dt_unit - 1) < -1)
 161:                 dn->d_unit = -1;
 162:             break;
 163:         }               /* fill in wildcards */
 164:     if ((want_unit = dp->dt_unit) == -1)
 165:         want_unit = dn->d_unit + 1;
 166:     else if (want_unit <= dn->d_unit)
 167:         return(ERR);
 168:     return(dn->d_unit = dp->dt_unit = want_unit);
 169: }

Defined functions

attach defined in line 33; used 2 times
find_unit defined in line 132; used 1 times
  • in line 42
have_set defined in line 89; used 1 times
pry defined in line 99; used 1 times
  • in line 68
write_vector defined in line 117; used 5 times

Defined variables

num_vec defined in line 31; used 3 times
vec_set defined in line 31; used 2 times

Defined struct's

done_s defined in line 135; used 2 times
  • in line 138(2)
Last modified: 1994-01-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2978
Valid CSS Valid XHTML 1.0 Strict