00001
00002
00003
00004
00005
00006 #include<linux/linkage.h>
00007 #include<system_data_cells.h>
00008 #include<ucbdef.h>
00009 #include<irpdef.h>
00010 #include<fkbdef.h>
00011 #include<ipldef.h>
00012 #include<ipl.h>
00013 #include<internals.h>
00014 #include <linux/smp.h>
00015 #include <asm/current.h>
00016 #include <linux/kernel.h>
00017 #include <linux/sched.h>
00018 #include <asm/hw_irq.h>
00019 #include <queue.h>
00020
00021 asmlinkage void exe_forkdspth(int i);
00022 void exe_fork(struct _irp * i, struct _ucb * u);
00023 void exe_queue_fork(struct _irp * i, struct _ucb * u);
00024
00025 struct fork_lock_struct {
00026 struct _spl * spin;
00027 int ipl;
00028 };
00029
00030
00031 static struct fork_lock_struct forklock_table[7]={
00032 { &SPIN_IOLOCK8, IPL__IOLOCK8 },
00033 { 0, 0 },
00034 { &SPIN_IOLOCK8, IPL__IOLOCK8 },
00035 { &SPIN_IOLOCK9, IPL__IOLOCK9 },
00036 { &SPIN_IOLOCK10, IPL__IOLOCK10 },
00037 { &SPIN_IOLOCK11, IPL__IOLOCK11 },
00038 { &SPIN_MAILBOX, IPL__MAILBOX }
00039 };
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 int inline forklock(int i, signed int j) {
00050 if (i<6 || i == 7 || i > 12)
00051 panic("forklock\n");
00052 if (j==-2) j=forklock_table[i-6].ipl;
00053 return vmslock(forklock_table[i-6].spin, j);
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void inline forkunlock(int i, signed int j) {
00065 if (i<6 || i == 7 || i > 12)
00066 panic("forkunlock\n");
00067 if (j==-2) j=forklock_table[i-6].ipl;
00068 vmsunlock(forklock_table[i-6].spin, j);
00069 }
00070
00071
00072
00073
00074
00075 asmlinkage void exe_frkipl6dsp(void) {
00076 exe_forkdspth(6);
00077 }
00078
00079
00080
00081
00082
00083 asmlinkage void exe_frkipl8dsp(void) {
00084 exe_forkdspth(8);
00085 }
00086
00087
00088
00089
00090
00091 asmlinkage void exe_frkipl9dsp(void) {
00092 exe_forkdspth(9);
00093 }
00094
00095
00096
00097
00098
00099 asmlinkage void exe_frkipl10dsp(void) {
00100 exe_forkdspth(10);
00101 }
00102
00103
00104
00105
00106
00107 asmlinkage void exe_frkipl11dsp(void) {
00108 exe_forkdspth(11);
00109 }
00110
00111
00112
00113
00114
00115
00116 asmlinkage void exe_forkdspth(int i) {
00117 void (*func)(void *,void *, void *);
00118 struct _fkb * f, * dummy = 0, * fq;
00119 #ifdef __x86_64__
00120 if (intr_blocked(i))
00121 return;
00122 regtrap(REG_INTR, i);
00123 #endif
00124 setipl(i);
00125
00126
00127 fq=smp_gl_cpu_data[smp_processor_id()]->cpu$q_swiqfl[i-6];
00128 while (!aqempty(fq)) {
00129 f=remque(fq,dummy);
00130
00131 func=f->fkb_l_fpc;
00132
00133 int savipl = vmslock(forklock_table[i-6].spin, forklock_table[i-6].spin);
00134
00135 func(f->fkb_l_fr3,f->fkb$l_fr4,f);
00136
00137 vmsunlock(forklock_table[i-6].spin, savipl);
00138
00139 fq=smp_gl_cpu_data[smp_processor_id()]->cpu$q_swiqfl[0];
00140 }
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 void exe_iofork(struct _irp * i, struct _ucb * u) {
00150
00151 u->ucb_l_sts&=~UCB$M_TIM;
00152
00153 exe_fork(i,u);
00154 }
00155
00156
00157
00158
00159
00160
00161
00162 void exe_fork(struct _irp * i, struct _ucb * u) {
00163 u->ucb_l_fr3=i;
00164
00165
00166 exe_queue_fork(i,u);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 void exe_queue_fork(struct _irp * i, struct _ucb * u) {
00176 int curipl;
00177 int newipl;
00178 int isempty;
00179 struct _fkb * f=u;
00180
00181
00182
00183
00184 newipl=f->fkb_b_flck;
00185
00186 f=smp_gl_cpu_data[smp_processor_id()]->cpu$q_swiqfl[newipl-6];
00187 isempty=aqempty(f);
00188 insque(u,f->fkb_l_fqbl);
00189
00190 if (isempty) {
00191
00192 switch (newipl) {
00193 case IPL__IOLOCK11:
00194 SOFTINT_IOLOCK11_VECTOR;
00195 break;
00196 case IPL__IOLOCK10:
00197 SOFTINT_IOLOCK10_VECTOR;
00198 break;
00199 case IPL__IOLOCK9:
00200 SOFTINT_IOLOCK9_VECTOR;
00201 break;
00202 case IPL__IOLOCK8:
00203 SOFTINT_IOLOCK8_VECTOR;
00204 break;
00205 case IPL__QUEUEAST:
00206 SOFTINT_QUEUEAST_VECTOR;
00207 break;
00208 default:
00209 panic("in forkdspth\n");
00210 }
00211 }
00212 }
00213
00214 void exe_std_queue_fork(struct _fkb * fkb) {
00215 exe_queue_fork(0,fkb);
00216 }
00217
00218
00219 void exe_std_primitive_fork(long fr3, long fr4, struct _fkb * fkb) {
00220 fkb->fkb_l_fr3=fr3;
00221 fkb->fkb_l_fr4=fr4;
00222 exe_std_queue_fork(fkb);
00223 }
00224