00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #include<system_data_cells.h>
00011 #include<linux/kernel.h>
00012 #include <asm/uaccess.h>
00013 #include <asm/hw_irq.h>
00014 #include <vms_drivers.h>
00015 #include <cpudef.h>
00016 #include <ipldef.h>
00017 #include <pridef.h>
00018 #include <irpdef.h>
00019 #include <acbdef.h>
00020 #include <tastdef.h>
00021 #include <ttyucbdef.h>
00022 #include <com_routines.h>
00023 #include <sch_routines.h>
00024 #include <smp_routines.h>
00025 #include <ipl.h>
00026 #include <queue.h>
00027
00028 #include <linux/mm.h>
00029 #include <linux/slab.h>
00030
00031 #include <internals.h>
00032
00033 void com_std_delattnastp (struct _acb **acb_lh, struct _ucb *ucb, int ipid);
00034
00035 void com_post(struct _irp * i, struct _ucb * u) {
00036 int savipl = getipl();
00037 if (savipl<IPL__IOPOST)
00038 setipl(IPL__IOPOST);
00039 vmslock(&SPIN_IOPOST, -1);
00040 insqti(i,&ioc_gq_postiq);
00041 vmsunlock(&SPIN_IOPOST, -1);
00042 if (ctl_gl_pcb->pcb$l_cpu_id != smp$gl_primid)
00043 smp_send_work(CPU_M_IOPOST, 0);
00044 else
00045 SOFTINT_IOPOST_VECTOR;
00046 setipl(savipl);
00047 }
00048
00049
00050
00051
00052
00053
00054
00055 void com_std_delattnast (struct _acb **acb_lh, struct _ucb *ucb) {
00056 com_std_delattnastp(acb_lh, ucb, 0);
00057 }
00058
00059 void fork_routine(fr3,fr4,fr5) {
00060 struct _acb * a = fr5;
00061 long * exp = &a->acb_l_kast;
00062
00063 a->acb_l_ast=a->acb$l_kast;
00064 a->acb_l_kast=0;
00065 a->acb_l_astprm=exp[1];
00066 a->acb_b_rmod=0;
00067 a->acb_l_pid=exp[3];
00068 return sch_qast(a->acb$l_pid,PRI$_IOCOM,a);
00069 }
00070
00071 void dealloc_tast(long arg) {
00072 struct _tast * tast = arg;
00073 tast->tast_v_busy=0;
00074 if (tast->tast_v_lost)
00075 return;
00076 kfree(arg);
00077
00078 }
00079
00080 void fork_routine2(fr3,fr4,fr5) {
00081 struct _acb * a = fr5;
00082 struct _tast * tast = fr5;
00083
00084 tast->tast_b_rmod|=ACB$M_PKAST|ACB$M_NODELETE;
00085 a->acb_l_ast=tast->tast$l_ast;
00086 a->acb_l_kast=dealloc_tast;
00087 a->acb_l_astprm=tast->tast$l_astprm;
00088 a->acb_b_rmod=tast->tast$b_rmod;
00089 a->acb_l_pid=tast->tast$l_pid;
00090 return sch_qast(a->acb$l_pid,PRI$_IOCOM,a);
00091 }
00092
00093
00094
00095
00096
00097
00098
00099
00100 void com_std_delattnastp (struct _acb **acb_lh, struct _ucb *ucb, int ipid) {
00101 struct _acb * next, * cur = acb_lh;
00102
00103 while (cur->acb_l_astqfl) {
00104 next=cur->acb_l_astqfl;
00105 long * exp=&next->acb_l_kast;
00106
00107 if ((ipid == 0) || (ipid == exp[3])) {
00108
00109 cur->acb_l_astqfl=next->acb$l_astqfl;
00110
00111 fork(fork_routine,0,0,next);
00112 } else {
00113 cur=next;
00114 }
00115 }
00116 }
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127 void com_std_delctrlastp (struct _acb **acb_lh, struct _ucb *ucb, int ipid, int matchchar, int *inclchar_p) {
00128
00129 struct _acb * next, * cur = acb_lh;
00130
00131 while (cur->acb_l_astqfl) {
00132 next=cur->acb_l_astqfl;
00133 struct _tast * tast = next;
00134
00135 if (tast->tast_l_mask) {
00136
00137
00138 }
00139
00140 if ((ipid == 0) || (ipid == tast->tast_l_pid)) {
00141
00142 if (tast->tast_v_busy)
00143 continue;
00144
00145 tast->tast_v_busy=1;
00146 cur->acb_l_astqfl=next->acb$l_astqfl;
00147 next->acb_b_rmod=SPL$C_QUEUEAST;
00148
00149 tast->tast_l_astprm=matchchar;
00150
00151 fork(fork_routine2,0,0,next);
00152 } else {
00153 cur=next;
00154 }
00155 }
00156 }
00157
00158 void com_std_delctrlast (struct _acb **acb_lh, struct _ucb *ucb, int matchchar, int *inclchar_p) {
00159 com_std_delctrlastp(acb_lh, ucb, 0, matchchar, inclchar_p);
00160 }
00161
00162 void com_std_drvdealmem (void *ptr) {
00163 kfree(ptr);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174 int com_std_flushattns (struct _pcb *pcb, struct _ucb *ucb, int chan, struct _acb **acb_lh) {
00175
00176 setipl(ucb->ucb_b_dipl);
00177 long ipid=pcb->pcb_l_pid;
00178 struct _acb * next, * cur = acb_lh;
00179
00180 while (cur->acb_l_astqfl) {
00181 next=cur->acb_l_astqfl;
00182 long * exp=&next->acb_l_kast;
00183
00184 if ((ipid == 0) || (ipid == exp[3])) {
00185
00186 cur->acb_l_astqfl=next->acb$l_astqfl;
00187 kfree(next);
00188
00189 } else {
00190 cur=next;
00191 }
00192 }
00193
00194 setipl(0);
00195 return SS__NORMAL;
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207 int com_std_flushctrls (struct _pcb *pcb, struct _ucb *ucb, int chan, struct _acb **acb_lh, int *mask_p) {
00208 struct _tast * tast = 0;
00209
00210
00211
00212 int tmp_mask=0;
00213 int did_modify=0;
00214 struct _acb * next, * cur = acb_lh;
00215 while (cur->acb_l_astqfl) {
00216 next=cur->acb_l_astqfl;
00217 struct _tast * t=((long)next)-((long)(&tast->tast_l_flink-(long)tast));
00218
00219 if (t->tast_l_pid == pcb->pcb$l_pid && t->tast$w_chan == chan) {
00220
00221 cur->acb_l_astqfl=next->acb$l_astqfl;
00222 if (t->tast_v_busy) {
00223
00224 t->tast_v_lost=1;
00225 } else {
00226
00227
00228 com_std_drvdealmem(t);
00229
00230 }
00231 } else {
00232
00233 tmp_mask|=t->tast_l_mask;
00234 }
00235 cur=next;
00236 }
00237
00238
00239
00240 struct _ltrm_ucb * tty = ucb;
00241
00242 tty->ucb_l_tl_outband=tmp_mask;
00243
00244 return SS__NORMAL;
00245 }
00246
00247 void com_std_post (struct _irp *irp, struct _ucb *ucb) {
00248 com_post(irp,ucb);
00249 }
00250
00251 void com_std_post_nocnt (struct _irp *irp);
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262 int com_std_setattnast (struct _irp *irp, struct _pcb *pcb, struct _ucb *ucb, struct _ccb *ccb, struct _acb **acb_lh) {
00263 short int chan=ccb-&ctl_gl_ccbbase[0];
00264 long * exp;
00265
00266 if (irp->irp_l_qio_p1==0)
00267 return com_std_flushattns(pcb,ucb,chan,acb_lh);
00268
00269 struct _acb * acb = kmalloc(sizeof(struct _acb)+100,GFP_KERNEL);
00270 memset(acb, 0, sizeof(struct _acb));
00271 exp=&acb->acb_l_kast;
00272
00273 exp[0]=irp->irp_l_qio_p1;
00274 exp[1]=irp->irp_l_qio_p2;
00275 exp[2]=chan;
00276 exp[3]=pcb->pcb_l_pid;
00277
00278 setipl(ucb->ucb_b_dipl);
00279 acb->acb_b_rmod=IPL$_QUEUEAST;
00280
00281 acb->acb_l_astqfl=*acb_lh;
00282 *acb_lh=acb;
00283
00284 setipl(0);
00285 return SS__NORMAL;
00286 }
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 int com_std_setctrlast (struct _irp *irp, struct _pcb *pcb, struct _ucb *ucb, struct _ccb *ccb, struct _acb **acb_lh,int mask, struct _tast **tast_p) {
00299 struct _acb * a;
00300 struct _tast * tast;
00301
00302 if (irp->irp_l_qio_p1==0 || irp->irp$l_qio_p2==0)
00303 return com_std_flushctrls (pcb, ucb, ccb->ccb$l_chan, acb_lh, mask);
00304
00305 a = kmalloc(sizeof(struct _tast), GFP_KERNEL);
00306 memset(a, 0, sizeof(struct _tast));
00307 tast = a;
00308
00309
00310
00311
00312 int tmp_mask=0;
00313 int did_modify=0;
00314 struct _acb * next, * cur = acb_lh;
00315 while (cur->acb_l_astqfl) {
00316 next=cur->acb_l_astqfl;
00317 struct _tast * t=((long)next)-((long)(&tast->tast_l_flink-(long)tast));
00318 if (t->tast_l_pid == pcb->pcb$l_pid && t->tast$w_chan == ccb->ccb$w_chan) {
00319 if (t->tast_v_busy) {
00320
00321 cur->acb_l_astqfl=next->acb$l_astqfl;
00322 t->tast_v_lost=1;
00323 goto use_allocated;
00324 } else {
00325
00326
00327 com_std_drvdealmem(a);
00328 tast=t;
00329 tast->tast_l_ast=irp->irp$l_qio_p1;
00330 tast->tast_l_astprm=irp->irp$l_qio_p2;
00331 tast->tast_l_mask=mask;
00332 did_modify=1;
00333
00334 }
00335 }
00336 tmp_mask|=t->tast_l_mask;
00337 cur=next;
00338 }
00339
00340 use_allocated:
00341 if (!did_modify) {
00342
00343 tast->tast_l_pid=pcb->pcb$l_pid;
00344 tast->tast_w_chan=ccb->ccb$w_chan;
00345 tast->tast_l_ast=irp->irp$l_qio_p1;
00346 tast->tast_l_astprm=irp->irp$l_qio_p2;
00347 tast->tast_l_mask=mask;
00348
00349
00350 struct _acb * acb=tast;
00351 acb->acb_l_astqfl=*acb_lh;
00352 *acb_lh=acb;
00353 }
00354
00355
00356
00357 struct _ltrm_ucb * tty = ucb;
00358
00359 tty->ucb_l_tl_outband=tmp_mask;
00360
00361 *tast_p=tast;
00362
00363 return SS__NORMAL;
00364 }
00365