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
pry
defined in line
99; used 1 times
Defined variables
Defined struct's