00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include<linux/spinlock.h>
00012 #include<asm/unistd.h>
00013
00014 #include<acbdef.h>
00015 #include<aqbdef.h>
00016 #include<cdrpdef.h>
00017 #include<ddtdef.h>
00018 #include<dyndef.h>
00019 #include<fdtdef.h>
00020 #include<ipl.h>
00021 #include<internals.h>
00022 #include<iodef.h>
00023 #include<ipldef.h>
00024 #include<irpdef.h>
00025 #include<pridef.h>
00026 #include<ssdef.h>
00027 #include<starlet.h>
00028 #include<system_data_cells.h>
00029 #include<ucbdef.h>
00030 #include<vcbdef.h>
00031
00032 #include<linux/vmalloc.h>
00033 #include<linux/linkage.h>
00034 #include<linux/kernel.h>
00035 #include<asm/hw_irq.h>
00036 #include "../../starlet/src/sysdep.h"
00037 #include <exe_routines.h>
00038 #include <misc_routines.h>
00039 #include <sch_routines.h>
00040 #include <ioc_routines.h>
00041 #include <queue.h>
00042 #include <linux/slab.h>
00043
00044 #define MYDEB_IRP
00045 #undef MYDEB_IRP
00046
00047 void exe_qioqe2ppkt (struct _pcb * p, struct _irp * i);
00048 void exe_qioqxqppkt (struct _pcb * p, struct _irp * i);
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060 void exe_insertirp(struct _ucb * u, struct _irp * i) {
00061
00062 struct _irp *head=&u->ucb_l_ioqfl;
00063 struct _irp *tmp=u->ucb_l_ioqfl;
00064
00065 while (tmp!=head && i->irp_b_pri>tmp->irp$b_pri)
00066 tmp=tmp->irp_l_ioqfl;
00067
00068 insque(i,tmp);
00069 }
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 int exe_std_abortio(struct _irp * i, struct _pcb * p, struct _ucb * u, int qio_sts) {
00080
00081 int savipl = forklock(u->ucb_b_flck, u->ucb$b_flck);
00082 #if 0
00083 if (i->irp_l_iosb)
00084 bzero(i->irp_l_iosb,8);
00085 #endif
00086
00087 i->irp_l_iosb=0;
00088
00089 i->irp_b_rmod&=~ACB$M_QUOTA;
00090
00091
00092 insque(i,smp_gl_cpu_data[smp$gl_primid ]->cpu$l_psbl);
00093
00094 SOFTINT_IOPOST_VECTOR;
00095
00096
00097 forkunlock(u->ucb_b_flck, savipl);
00098
00099 return qio_sts;
00100 }
00101
00102 void exe_altqueuepkt (void) {}
00103
00104
00105
00106
00107
00108
00109
00110
00111 int exe_altquepkt (struct _irp * i, struct _pcb * p, struct _ucb * u) {
00112 struct _ddt *d;
00113 void (*f)(void *,void *);
00114
00115 int savipl=forklock(u->ucb_b_flck,u->ucb$b_flck);
00116
00117
00118
00119 d=u->ucb_l_ddt;
00120 f=d->ddt_l_altstart;
00121
00122 f(i,u);
00123
00124
00125 forkunlock(u->ucb_b_flck,savipl);
00126 return SS__NORMAL;
00127 }
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138 int exe_finishio (long status1, long status2, struct _irp * i, struct _pcb * p, struct _ucb * u) {
00139
00140
00141 i->irp_l_iost1=status1;
00142 i->irp_l_iost2=status2;
00143
00144 int savipl = forklock(u->ucb_b_flck, u->ucb$b_flck);
00145
00146 insque(i,smp_gl_cpu_data[smp$gl_primid ]->cpu$l_psbl);
00147 SOFTINT_IOPOST_VECTOR;
00148
00149 forkunlock(u->ucb_b_flck, savipl);
00150
00151 setipl(0);
00152
00153 return SS__NORMAL;
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164 int exe_finishioc (long status, struct _irp * i, struct _pcb * p, struct _ucb * u) {
00165
00166 return exe_finishio(status,0,i,p,u);
00167 }
00168
00169
00170
00171
00172
00173
00174
00175 int exe_insioq (struct _irp * i, struct _ucb * u) {
00176
00177 int savipl=forklock(u->ucb_b_flck, u->ucb$b_flck);
00178
00179
00180 if (u->ucb_l_sts & UCB$M_BSY)
00181 exe_insertirp(u,i);
00182 else {
00183
00184 u->ucb_l_sts|=UCB$M_BSY;
00185 ioc_initiate(i,u);
00186 }
00187
00188
00189 forkunlock(u->ucb_b_flck,savipl);
00190 return SS__NORMAL;
00191 }
00192
00193 #if 0
00194 asmlinkage int exe_qiow_not(unsigned int efn, unsigned short int chan,unsigned int func, struct _iosb *iosb, void(*astadr)(__unknown_params), long astprm, void*p1, long p2, long p3, long p4, long p5, long p6) {
00195 struct struct_qio s;
00196
00197 s.efn=efn;
00198 s.chan=chan;
00199 s.func=func;
00200 s.iosb=iosb;
00201 s.astadr=astadr;
00202 s.astprm=astprm;
00203 s.p1=p1;
00204 s.p2=p2;
00205 s.p3=p3;
00206 s.p4=p4;
00207 s.p5=p5;
00208 s.p6=p6;
00209 return exe_qiow(&s);
00210 }
00211 #endif
00212
00213 extern int sys_qio(unsigned int efn, unsigned short int chan,unsigned int func, struct _iosb *iosb, void(*astadr)(__unknown_params), long astprm, void*p1, long p2, long p3, long p4, long p5, long p6);
00214
00215 asmlinkage int exe_qiow (unsigned int efn, unsigned short int chan,unsigned int func, struct _iosb *iosb, void(*astadr)(__unknown_params), long astprm, void*p1, long p2, long p3, long p4, long p5, long p6) {
00216
00217
00218
00219 int status=sys_qio(efn,chan,func,iosb,astadr,astprm,p1,p2,p3,p4,p5,p6);
00220 if ((status&1)==0) return status;
00221 return exe_synch(efn,iosb);
00222
00223 }
00224
00225 #ifdef MYDEB_IRP
00226 long lastirp[32];
00227 long lastirp1[32*20];
00228 long lastirp2[32*6];
00229 #if 1
00230 long myirp[1024*6];
00231 long myirpc=0;
00232 #endif
00233
00234 static int qcnt = 0;
00235 #endif
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 asmlinkage int exe_qio (unsigned int efn, unsigned short int chan,unsigned int func, struct _iosb *iosb, void(*astadr)(__unknown_params), long astprm, void*p1, long p2, long p3, long p4, long p5, long p6) {
00251 int retval = 0;
00252 #if 0
00253 if (chan>1000)
00254 panic("chan 1000 %x\n",chan);
00255 #endif
00256 unsigned int c, d;
00257 struct _pcb * p=current;
00258 struct _irp * i;
00259
00260 exe_clref(efn);
00261
00262
00263 if (chan<0 || chan>ctl_gl_chindx) return SS$_IVCHAN;
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 if (iosb) *((unsigned long long *)iosb)=0;
00281
00282
00283 int oldipl=getipl();
00284 setipl(IPL__ASTDEL);
00285
00286
00287
00288
00289 i=kmalloc(sizeof(struct _irp),GFP_KERNEL);
00290 memset(i,0,sizeof(struct _irp));
00291
00292
00293 i->irp_b_type=DYN$C_IRP;
00294 i->irp_b_efn=efn;
00295 i->irp_b_rmod=p->psl_prv_mod;
00296 i->irp_l_ast=astadr;
00297 i->irp_l_astprm=astprm;
00298 i->irp_l_iosb=iosb;
00299 i->irp_w_chan=chan;
00300 i->irp_l_func=func;
00301 i->irp_b_pri=p->pcb$b_pri;
00302 i->irp_l_qio_p1=p1;
00303 i->irp_l_qio_p2=p2;
00304 i->irp_l_qio_p3=p3;
00305 i->irp_l_qio_p4=p4;
00306 i->irp_l_qio_p5=p5;
00307 i->irp_l_qio_p6=p6;
00308 i->irp_l_ucb=ctl$gl_ccbbase[chan].ccb$l_ucb;
00309 i->irp_l_pid=current->pcb$l_pid;
00310 i->irp_l_sts|=IRP$M_BUFIO;
00311
00312 #ifdef MYDEB_IRP
00313 i->irp_w_empty=qcnt++;
00314 lastirp[i->irp_l_pid&31]=i;
00315 #if 1
00316 memcpy(&lastirp1[20*(i->irp_l_pid&31)],i,20*4);
00317 memcpy(&lastirp2[6*(i->irp_l_pid&31)],&i->irp$l_qio_p1,6*4);
00318 memcpy(&lastirp2[6*(i->irp_l_pid&31)+5],&exe$gl_abstim_tics,4);
00319 #endif
00320 #if 1
00321 memcpy(&myirp[myirpc],i,20*4);
00322 myirpc+=20;
00323 memcpy(&myirp[myirpc],&i->irp_l_qio_p1,6*4);
00324 memcpy(&myirp[myirpc+5],&exe_gl_abstim_tics,4);
00325 myirpc+=8;
00326 if (myirpc>1024) myirpc=0;
00327 #endif
00328 #endif
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339 c=i->irp_v_fcode;
00340 d=i->irp_v_fmod;
00341 if (0==ctl_ga_ccb_table[chan].ccb$l_ucb->ucb$l_ddt->ddt$l_fdt->fdt$ps_func_rtn[i->irp$v_fcode]) {
00342 retval = SS__ILLIOFUNC;
00343 goto earlyerror;
00344 }
00345
00346 retval = ctl_ga_ccb_table[chan].ccb$l_ucb->ucb$l_ddt->ddt$l_fdt->fdt$ps_func_rtn[i->irp$v_fcode](i,p,i->irp$l_ucb,&ctl$gl_ccbbase[chan]);
00347 setipl(oldipl);
00348 return retval;
00349
00350 earlyerror:
00351 setipl(oldipl);
00352
00353 sch_postef(current->pcb$l_pid,PRI$_NULL,efn);
00354 return retval;
00355
00356 }
00357
00358
00359
00360
00361
00362
00363
00364
00365 int exe_qioacppkt (struct _irp * i, struct _pcb * p, struct _ucb * u) {
00366 int wasempty;
00367
00368 struct _vcb * v=u->ucb_l_vcb;
00369
00370 struct _aqb * a=v->vcb_l_aqb;
00371
00372 if (a->aqb_l_acppid==0) {
00373 exe_qioqxqppkt(p,i);
00374 return SS__NORMAL;
00375 }
00376
00377 #ifdef CONFIG_VMS
00378 if (a->aqb_l_acppid==1) {
00379 exe_qioqe2ppkt(p,i);
00380 return SS__NORMAL;
00381 }
00382 #endif
00383 wasempty=aqempty(&a->aqb_l_acpqfl);
00384
00385 insque(i,&a->aqb_l_acpqfl);
00386
00387 if (!wasempty) return SS__NORMAL;
00388
00389 vmslock(&SPIN_SCHED,IPL__SCHED);
00390
00391 sch_wake(a->aqb$l_acppid);
00392 vmsunlock(&SPIN_SCHED,-1);
00393
00394 setipl(0);
00395
00396 return SS__NORMAL;
00397 }
00398
00399
00400
00401
00402
00403
00404
00405
00406 int exe_qiodrvpkt (struct _irp * i, struct _pcb * p, struct _ucb * u) {
00407
00408 exe_insioq(i,u);
00409
00410 setipl(0);
00411 return SS__NORMAL;
00412 }
00413
00414 int exe_std_qiodrvpkt (struct _irp * i, struct _ucb * u) {
00415 return exe_qiodrvpkt(i,0,u);
00416 }
00417
00418 extern f11b_dispatch();
00419
00420 extern exttwo_dispatch();
00421
00422
00423
00424
00425
00426
00427
00428 void exe_qioqxqppkt (struct _pcb * p, struct _irp * i) {
00429 struct _acb *a=&i->irp_l_fqfl;
00430
00431
00432
00433
00434 a->acb_l_pid=p->pcb$l_pid;
00435 a->acb_l_ast=f11b$dispatch;
00436 a->acb_l_astprm=i;
00437 a->acb_b_rmod|=ACB$M_NODELETE;
00438 #if 0
00439 remque(i,0);
00440 #endif
00441
00442 sch_qast(p->pcb$l_pid,PRI$_RESAVL,a);
00443
00444 setipl(0);
00445 }
00446
00447
00448
00449
00450
00451
00452
00453 #ifdef CONFIG_VMS
00454 void exe_qioqe2ppkt (struct _pcb * p, struct _irp * i) {
00455 struct _acb *a=&i->irp_l_fqfl;
00456
00457
00458
00459
00460 a->acb_l_pid=p->pcb$l_pid;
00461 a->acb_l_ast=exttwo$dispatch;
00462 a->acb_l_astprm=i;
00463 a->acb_b_rmod|=ACB$M_NODELETE;
00464 #if 0
00465 remque(i,0);
00466 #endif
00467
00468 sch_qast(p->pcb$l_pid,PRI$_RESAVL,a);
00469
00470 }
00471 #endif
00472
00473 asmlinkage int exe_qiow_wrap(struct struct_qio * s) {
00474 return exe_qiow(s->efn,s->chan,s->func,s->iosb,s->astadr,s->astprm,s->p1,s->p2,s->p3,s->p4,s->p5,s->p6);
00475 }
00476
00477 asmlinkage int exe_qio_wrap(struct struct_qio * s) {
00478 return exe_qio(s->efn,s->chan,s->func,s->iosb,s->astadr,s->astprm,s->p1,s->p2,s->p3,s->p4,s->p5,s->p6);
00479 }
00480
00481