00001
00002
00003
00004
00005
00006 #include <linux/init.h>
00007 #include <linux/sched.h>
00008 #include <linux/vmalloc.h>
00009
00010 #include <ccbdef.h>
00011 #include <crbdef.h>
00012 #include <dcdef.h>
00013 #include <ddbdef.h>
00014 #include <ddtdef.h>
00015 #include <devdef.h>
00016 #include <dptdef.h>
00017 #include <dyndef.h>
00018 #include <fdtdef.h>
00019 #include <internals.h>
00020 #include <iodef.h>
00021 #include <ipldef.h>
00022 #include <irpdef.h>
00023 #include <rsndef.h>
00024 #include <ssdef.h>
00025 #include <system_data_cells.h>
00026 #include <ucbdef.h>
00027 #include <descrip.h>
00028 #include <vms_drivers.h>
00029 #include <iosbdef.h>
00030 #include <com_routines.h>
00031 #include <queue.h>
00032 #include <exe_routines.h>
00033 #include <ioc_routines.h>
00034 #include <misc_routines.h>
00035 #include <sch_routines.h>
00036 #include <linux/slab.h>
00037
00038 #define irp_l_nopartnerqfl irp$l_fqfl
00039 #define irp_l_nopartnerqbl irp$l_fqbl
00040
00041 void mb_finishread(struct _ucb * u);
00042
00043 struct _dpt mb_dpt = { };
00044
00045 struct __mmb {
00046 struct __mmb * mmb_l_msgqfl;
00047 struct __mmb * mmb_l_msgqbl;
00048 unsigned short int mmb_w_size;
00049 unsigned char mmb_b_type;
00050 unsigned char mmb_b_func;
00051 struct _irp * mmb_l_irp;
00052 unsigned long mmb_l_pid;
00053 void * mmb_l_noreaderwaitqfl;
00054 void * mmb_l_noreaderwaitqbl;
00055 void * mmb_l_datastart;
00056 unsigned short mmb_w_datasize;
00057 short mmb_w_bufquochrg;
00058 char mmb_t_data[0];
00059 };
00060
00061 struct __srb {
00062 void * srb_l_addr;
00063 void * srb_l_virtaddr;
00064 unsigned short int srb_w_size;
00065 unsigned char srb_b_type;
00066 unsigned char srb_b_func;
00067 void * srb_l_datastart;
00068 unsigned short int srb_w_datasize;
00069 unsigned short srb_w_reqsiz;
00070 short srb_w_bufquochrg;
00071 char srb_t_data[0];
00072 };
00073
00074 int mb_fdt_setmode(struct _irp * i, struct _pcb * p, struct _ucb * u, struct _ccb * c) {
00075 int func=i->irp_l_func;
00076 struct _mb_ucb * mu=u;
00077 if (i->irp_l_func&IO$M_READERWAIT) {
00078 if (mu->ucb_l_mb_readerrefc==0)
00079 return exe_finishioc(SS$_NORMAL,i,p,u);
00080 insque(i,mu->ucb_l_mb_readerwaitqfl);
00081 return SS__NORMAL;
00082 }
00083 if (i->irp_l_func&IO$M_WRITERWAIT) {
00084 if (mu->ucb_l_mb_writerrefc==0)
00085 return exe_finishioc(SS$_NORMAL,i,p,u);
00086 insque(i,mu->ucb_l_mb_writerwaitqfl);
00087 return SS__NORMAL;
00088 }
00089 if (i->irp_l_func&IO$M_MB_ROOM_NOTIFY) {
00090 com_std_setattnast(i,p,u,c,mu->ucb$l_mb_room_notify);
00091 return exe_finishioc(SS$_NORMAL,i,p,u);
00092 }
00093 if (i->irp_l_func&IO$M_READATTN) {
00094 com_std_setattnast(i,p,u,c,&u->ucb$l_mb_r_ast);
00095 if (!aqempty(mu->ucb_l_mb_readqfl))
00096 com_std_delattnast(&u->ucb$l_mb_r_ast,u);
00097 } else {
00098 com_std_setattnast(i,p,u,c,&u->ucb$l_mb_w_ast);
00099 if (u->ucb_w_msgcnt)
00100 com_std_delattnast(&u->ucb$l_mb_w_ast,u);
00101 }
00102
00103 return exe_finishioc(SS$_NORMAL,i,p,u);
00104 }
00105
00106 int mb_fdt_sensemode(struct _irp * i, struct _pcb * p, struct _ucb * u, struct _ccb * c) {
00107 int retsts=SS__NORMAL;
00108 int func=i->irp_l_func;
00109 struct _mb_ucb * mu=u;
00110 struct __mmb * head=&u->ucb_l_mb_msgqfl;
00111 struct __mmb * tmp=head->mmb_l_msgqfl;
00112 int sum=0;
00113 if (i->irp_l_func&IO$M_WRITERWAIT && mu->ucb$l_mb_writerrefc==0)
00114 retsts=SS__NOWRITER;
00115 if (i->irp_l_func&IO$M_READERWAIT && mu->ucb$l_mb_readerrefc==0)
00116 retsts=SS__NOREADER;
00117 while (tmp!=head) {
00118 sum+=tmp->mmb_w_datasize;
00119 tmp=tmp->mmb_l_msgqfl;
00120 }
00121 retsts=(retsts)+(u->ucb_w_msgcnt<<16);
00122 return exe_finishio(retsts,sum,i,p,u);
00123 }
00124
00125 int mb_fdt_write (struct _irp * i, struct _pcb * p, struct _ucb * u, struct _ccb * c) {
00126 int savipl;
00127 struct __mmb * m;
00128 struct _mb_ucb * mu=u
00129 ;
00130
00131 if (c->ccb_l_sts&CCB$M_NOWRITEACC)
00132 return exe_std_abortio(i,p,u,SS$_ILLIOFUNC);
00133
00134 if (!test_and_set_bit(CCB_V_WRTCHKDON,&c->ccb$l_sts)) {
00135 int sts=exe_std_chkwrtacces(0,0,p,u);
00136 if ((sts&1)==0)
00137 return exe_std_abortio(sts,i,p,u);
00138 }
00139
00140 if (i->irp_l_qio_p2>u->ucb$w_devbufsiz)
00141 return exe_std_abortio(i,p,u,SS$_MBTOOSML);
00142
00143 int func=i->irp_l_func;
00144
00145 if ((func&IO_M_READERCHECK) && (mu->ucb$l_mb_readerrefc==0))
00146 return exe_finishioc(SS$_NOREADER,i,p,u);
00147
00148 if ((func&IO_M_FCODE)==IO$_WRITEOF) {
00149 i->irp_l_boff=0;
00150 i->irp_l_bcnt=0;
00151 i->irp_l_media=&i->irp$l_media;
00152 } else {
00153 i->irp_l_bcnt=i->irp$l_qio_p2;
00154 i->irp_l_media=i->irp$l_qio_p1;
00155 }
00156
00157 exe_std_writechk(i,p,u,i->irp$l_qio_p1, i->irp$l_qio_p2);
00158
00159 m=kmalloc(sizeof(struct __mmb)+i->irp_l_qio_p2,GFP_KERNEL);
00160 if (m) {
00161 memset(m,0,sizeof(struct __mmb)+i->irp_l_qio_p2);
00162 m->mmb_w_size=sizeof(struct __mmb)+i->irp$l_qio_p2;
00163 m->mmb_b_type=DYN$C_BUFIO;
00164 m->mmb_b_func=func;
00165 m->mmb_w_datasize=i->irp$l_qio_p2;
00166 qhead_init(&m->mmb_l_noreaderwaitqfl);
00167 if ((func&IO_M_NOW)==0) m->mmb$l_irp=i;
00168 m->mmb_l_pid=ctl$gl_pcb->pcb$l_pid;
00169 m->mmb_w_datasize=i->irp$l_bcnt;
00170 m->mmb_l_datastart=&m->mmb$t_data;
00171 if (m->mmb_w_datasize)
00172 memcpy(m->mmb_t_data,i->irp$l_qio_p1,i->irp$l_qio_p2);
00173 } else {
00174 if (i->irp_l_func & IO$M_NORSWAIT)
00175 return exe_std_iorsnwait(i,p,u,c,SS$_INSFMEM, RSN$_NPDYNMEM);
00176 else
00177 return exe_std_abortio(i,p,u,SS$_INSFMEM);
00178 }
00179
00180 savipl=vmslock(&SPIN_MAILBOX,IPL__MAILBOX);
00181
00182 if (i->irp_l_qio_p2>u->ucb$w_bufquo && aqempty(mu->ucb$l_mb_readqfl)) {
00183
00184 kfree(m);
00185
00186 if (i->irp_l_bcnt > u->ucb$w_iniquo) {
00187 return exe_std_abortio(i,p,u,SS$_MBTOOSML);
00188 }
00189
00190 if (i->irp_l_func & IO$M_NORSWAIT)
00191 return exe_std_iorsnwait(i,p,u,c,SS$_MBFULL, RSN$_MAILBOX);
00192 else
00193 return exe_std_abortio(i,p,u,SS$_MBFULL);
00194
00195 }
00196
00197 u->ucb_w_msgcnt++;
00198 u->ucb_l_devdepend=u->ucb$w_msgcnt;
00199
00200 u->ucb_w_bufquo-=m->mmb$w_datasize;
00201 if (m->mmb_w_datasize==0 || ((func&IO$M_FCODE)==IO$_WRITEOF))
00202 u->ucb_w_bufquo--;
00203
00204 insque(m,u->ucb_l_mb_msgqbl);
00205
00206
00207 if (!aqempty(mu->ucb_l_mb_readqfl))
00208 mb_finishread(u);
00209 else
00210 {
00211 if ((func&IO_M_NOW)==0 || (func&IO$M_READERCHECK && mu->ucb$l_mb_readerrefc==0))
00212 insque(&m->mmb_l_noreaderwaitqfl,mu->ucb$l_mb_noreaderwaitqfl);
00213 com_std_delattnast(&u->ucb$l_mb_w_ast, u);
00214 }
00215
00216 vmsunlock(&SPIN_MAILBOX,savipl);
00217
00218 if (func&IO_M_NOW)
00219 return exe_finishioc(SS$_NORMAL|(i->irp$l_bcnt<<16),i,p,u);
00220 else
00221 return SS__NORMAL;
00222 }
00223
00224 int mb_fdt_read (struct _irp * i, struct _pcb * p, struct _ucb * u, struct _ccb * c) {
00225 if (c->ccb_l_sts&CCB$M_NOREADACC)
00226 return exe_std_abortio(i,p,u,SS$_ILLIOFUNC);
00227
00228 if (i->irp_l_qio_p2>u->ucb$w_devbufsiz)
00229 return exe_std_abortio(i,p,u,SS$_MBTOOSML);
00230
00231 if (i->irp_l_qio_p2)
00232 exe_std_readchk(i,p,u,i->irp$l_qio_p1,i->irp$l_qio_p2);
00233
00234 int func=i->irp_l_func;
00235 struct _mb_ucb * mu=u;
00236 struct __srb * s = 0;
00237 int savipl;
00238 int skip=0;
00239
00240 if (i->irp_l_qio_p2) {
00241 i->irp_l_bcnt=i->irp$l_qio_p2;
00242 i->irp_l_media=i->irp$l_qio_p1;
00243 } else {
00244 i->irp_l_bcnt=0;
00245 i->irp_l_media=&i->irp$l_media;
00246 }
00247
00248 if ((i->irp_l_bcnt == 0) && (i->irp$l_func & IO$M_STREAM))
00249 return exe_finishioc(SS$_NORMAL,i,p,u);
00250
00251 if ((func&IO_M_WRITERCHECK) && (u->ucb$w_msgcnt==0) && (mu->ucb$l_mb_writerrefc==0))
00252 return exe_finishioc(SS$_NOWRITER,i,p,u);
00253
00254 i->irp_l_sts|=IRP$M_BUFIO;
00255 i->irp_l_sts|=IRP$M_MBXIO;
00256
00257 if (i->irp_l_qio_p2>u->ucb$w_bufquo || i->irp$l_qio_p2>u->ucb$w_iniquo)
00258 return exe_std_abortio(i,p,u,SS$_EXQUOTA);
00259
00260 savipl=vmslock(&SPIN_MAILBOX,IPL__MAILBOX);
00261
00262 if ((func&IO_M_STREAM) && !aqempty(u->ucb$l_mb_msgqfl)) {
00263 struct __mmb * tmp = u->ucb_l_mb_msgqfl;
00264 if (tmp->mmb_w_datasize == i->irp$l_bcnt)
00265 skip = 1;
00266 }
00267
00268 if ((func & IO_M_STREAM) && ! skip) {
00269 s=kmalloc(sizeof(struct __srb)+i->irp_l_qio_p2,GFP_KERNEL);
00270 if (s) {
00271 memset(s,0,sizeof(struct __srb)+i->irp_l_qio_p2);
00272 s->srb_w_size=sizeof(struct __srb)+i->irp$l_qio_p2;
00273 s->srb_b_type=DYN$C_BUFIO;
00274 s->srb_b_func=func;
00275 s->srb_w_datasize=0;
00276 s->srb_w_reqsiz=i->irp$l_qio_p2;
00277 s->srb_w_bufquochrg=1;
00278 s->srb_l_datastart=&s->srb$t_data;
00279 s->srb_l_virtaddr=i->irp$l_media;
00280 s->srb_l_addr=&s->srb$t_data;
00281 i->irp_l_svapte=s;
00282 } else {
00283 return exe_std_iorsnwait(i,p,u,c,SS$_INSFMEM, RSN$_NPDYNMEM);
00284 }
00285
00286 u->ucb_w_bufquo-=i->irp$l_qio_p2;
00287 }
00288
00289 if ((func & IO_M_STREAM) && ! skip) {
00290 if (u->ucb_w_bufquo<s->srb$w_reqsiz) {
00291 if (u->ucb_w_iniquo<s->srb$w_reqsiz && aqempty(u->ucb$l_mb_msgqfl))
00292 return exe_std_abortio(i,p,u,SS$_MBFULL);
00293 }
00294 }
00295
00296 if ((func & IO_M_NOW) && (u->ucb$w_msgcnt==0)) {
00297 vmsunlock(&SPIN_MAILBOX,savipl);
00298 if (i->irp_l_svapte) {
00299 kfree(s);
00300 if (s->srb_w_bufquochrg)
00301 u->ucb_w_bufquo+=i->irp$l_qio_p2;
00302 }
00303 i->irp_l_svapte=0;
00304 return exe_finishioc(SS$_ENDOFFILE,i,p,u);
00305 }
00306
00307 if ((func&IO_M_WRITERCHECK) && mu->ucb$l_mb_writerrefc && u->ucb$w_msgcnt==0)
00308 insque(&i->irp_l_nopartnerqfl,mu->ucb$l_mb_nowriterwaitqfl);
00309 else
00310 i->irp_l_nopartnerqfl=0;
00311
00312
00313
00314
00315 insque(i,mu->ucb_l_mb_readqbl);
00316
00317 if (!aqempty(u->ucb_l_mb_msgqfl))
00318 mb_finishread(u);
00319 else
00320 com_std_delattnast(&u->ucb$l_mb_r_ast ,u);
00321 vmsunlock(&SPIN_MAILBOX,savipl);
00322 return SS__NORMAL;
00323 }
00324
00325 create_fork_thread() {
00326 sch_std_ravail(RSN$_MAILBOX);
00327 }
00328
00329 enum { read_equal, read_less, read_more };
00330
00331 void mb_finishread(struct _ucb * u) {
00332 struct _mb_ucb * mu = u;
00333 struct __srb * s = 0;
00334 int room_ast=0;
00335 int not_done;
00336
00337 do {
00338
00339 not_done=0;
00340 struct _irp * i = mu->ucb_l_mb_readqfl;
00341 struct __mmb * msg = u->ucb_l_mb_msgqfl;
00342 long read_status=read_equal;
00343 short func = i->irp_l_func;
00344 int retstatus=SS__NORMAL;
00345
00346 if (func & IO_M_STREAM) {
00347 if (msg->mmb_w_datasize < i->irp$l_bcnt)
00348 read_status=read_more;
00349 if (msg->mmb_w_datasize > i->irp$l_bcnt)
00350 read_status=read_less;
00351 }
00352 if ((func&IO_M_FCODE)==IO$_WRITEOF)
00353 read_status=read_equal;
00354
00355 switch (read_status) {
00356 case read_equal:
00357 remque(i,0);
00358 msg=remque(msg,0);
00359 if (i->irp_l_svapte==0)
00360 i->irp_l_svapte=msg;
00361 else {
00362 s = i->irp_l_svapte;
00363 if (s->srb_w_datasize==0) {
00364 i->irp_l_svapte=msg;
00365 if (s->srb_w_bufquochrg) {
00366 room_ast=1;
00367 u->ucb_w_bufquo+=s->srb$w_reqsiz;
00368 }
00369 com_std_drvdealmem(s);
00370 }
00371 }
00372
00373 if (i->irp_l_nopartnerqfl)
00374 remque(i->irp_l_nopartnerqfl,0);
00375 if (!aqempty(msg->mmb_l_noreaderwaitqfl))
00376 remque(msg->mmb_l_noreaderwaitqfl,0);
00377 #if 0
00378 if (msg->mmb_l_nowriterwaitqfl)
00379 remque(msg->mmb_l_nowriterwaitqfl,0);
00380 #endif
00381
00382 if (i->irp_l_svapte!=msg) {
00383 memcpy(s->srb_l_datastart,msg->mmb$l_datastart,msg->mmb$w_datasize);
00384 s->srb_w_datasize+=s->srb$w_datasize;
00385 } else {
00386 msg->mmb_l_msgqfl=msg->mmb$l_datastart;
00387 msg->mmb_l_msgqbl=i->irp$l_media;
00388 }
00389
00390 if (msg->mmb_w_bufquochrg) {
00391 room_ast=1;
00392 if (msg->mmb_w_datasize==0)
00393 u->ucb_w_bufquo++;
00394 else
00395 u->ucb_w_bufquo+=msg->mmb$w_datasize;
00396 }
00397
00398 if (sch_gl_resmask & (1<<RSN$_MAILBOX))
00399 fork(create_fork_thread,0,0,u);
00400
00401 if (i->irp_l_svapte!=msg) {
00402 if (s->srb_w_bufquochrg) {
00403 room_ast=1;
00404 u->ucb_w_bufquo+=s->srb$w_reqsiz;
00405 }
00406 }
00407
00408 if (i->irp_l_bcnt<msg->mmb$w_datasize)
00409 retstatus=SS__BUFFEROVF;
00410
00411 if (i->irp_l_svapte!=msg)
00412 i->irp_l_bcnt=s->srb$w_datasize;
00413
00414 if ((func&IO_M_FCODE)==IO$_WRITEOF)
00415 retstatus=SS__ENDOFFILE;
00416
00417 u->ucb_w_msgcnt--;
00418 u->ucb_l_devdepend=u->ucb$w_msgcnt;
00419
00420 if (msg->mmb_l_irp) {
00421 struct _irp * wirp=msg->mmb_l_irp;
00422 wirp->irp_l_iost1= (wirp->irp$l_bcnt<<16) + SS$_NORMAL;
00423 wirp->irp_l_iost2 = exe$ipid_to_epid(msg->mmb$l_pid);
00424 com_post(wirp,u);
00425 }
00426
00427 if (i->irp_l_svapte!=msg)
00428 com_std_drvdealmem(msg);
00429
00430 i->irp_l_iost1= (i->irp$l_bcnt<<16) + retstatus;
00431 i->irp_l_iost2 = exe$ipid_to_epid(msg->mmb$l_pid);
00432
00433 com_post(i,u);
00434
00435 break;
00436 case read_less:
00437 remque(i,0);
00438
00439 if (i->irp_l_nopartnerqfl)
00440 remque(i->irp_l_nopartnerqfl,0);
00441 #if 0
00442 if (msg->mmb_l_nowriterwaitqfl)
00443 remque(msg->mmb_l_nowriterwaitqfl,0);
00444 #endif
00445
00446 if (s->srb_w_bufquochrg) {
00447 room_ast=1;
00448 u->ucb_w_bufquo+=s->srb$w_reqsiz;
00449 }
00450
00451 if (msg->mmb_w_bufquochrg) {
00452 room_ast=1;
00453 if (i->irp_l_bcnt==0)
00454 u->ucb_w_bufquo++;
00455 else
00456 u->ucb_w_bufquo+=i->irp$l_bcnt;
00457 }
00458
00459 if (sch_gl_resmask & (1<<RSN$_MAILBOX))
00460 fork(create_fork_thread,0,0,u);
00461
00462 s=i->irp_l_svapte;
00463
00464 memcpy(s->srb_l_datastart,msg->mmb$l_datastart,i->irp$l_bcnt);
00465 s->srb_w_datasize+=i->irp$l_bcnt;
00466 msg->mmb_w_datasize-=i->irp$l_bcnt;
00467 msg->mmb_l_datastart+=i->irp$l_bcnt;
00468
00469 i->irp_l_bcnt=s->srb$w_datasize;
00470 i->irp_l_iost1= (i->irp$l_bcnt<<16) + SS$_NORMAL;
00471 i->irp_l_iost2 = exe$ipid_to_epid(msg->mmb$l_pid);
00472
00473 com_post(i,u);
00474
00475 not_done=aqempty(mu->ucb_l_mb_readqfl)==0;
00476
00477 break;
00478 case read_more:
00479 msg=remque(msg,0);
00480 if (!aqempty(msg->mmb_l_noreaderwaitqfl))
00481 remque(msg->mmb_l_noreaderwaitqfl,0);
00482
00483 msg->mmb_l_msgqfl=msg->mmb$l_datastart;
00484 msg->mmb_l_msgqbl=i->irp$l_media;
00485
00486 if(msg->mmb_w_bufquochrg) {
00487 room_ast=1;
00488 if (msg->mmb_w_datasize==0)
00489 u->ucb_w_bufquo++;
00490 else
00491 u->ucb_w_bufquo+=msg->mmb$w_datasize;
00492 }
00493
00494 if (sch_gl_resmask & (1<<RSN$_MAILBOX))
00495 fork(create_fork_thread,0,0,u);
00496
00497 s=i->irp_l_svapte;
00498 memcpy(s->srb_l_datastart,msg->mmb$l_datastart,msg->mmb$w_datasize);
00499
00500 i->irp_l_bcnt-=msg->mmb$w_datasize;
00501 s->srb_w_datasize+=msg->mmb$w_datasize;
00502 s->srb_l_datastart+=msg->mmb$w_datasize;
00503
00504 u->ucb_w_msgcnt--;
00505 u->ucb_l_devdepend=u->ucb$w_msgcnt;
00506
00507 if (msg->mmb_l_irp) {
00508 struct _irp * wirp=msg->mmb_l_irp;
00509 wirp->irp_l_iost1= (wirp->irp$l_bcnt<<16) + SS$_NORMAL;
00510 wirp->irp_l_iost2 = exe$ipid_to_epid(msg->mmb$l_pid);
00511 com_post(wirp,u);
00512 }
00513 com_std_drvdealmem(msg);
00514
00515 struct __mmb * next = u->ucb_l_mb_msgqfl;
00516
00517 if (!aqempty(&u->ucb_l_mb_msgqfl) && (next->mmb$b_func&IO$M_FCODE)!=IO$_WRITEOF) {
00518 not_done=1;
00519 } else {
00520
00521 if (s->srb_w_bufquochrg) {
00522 room_ast=1;
00523 u->ucb_w_bufquo+=s->srb$w_reqsiz;
00524 }
00525
00526 i->irp_l_bcnt=s->srb$w_datasize;
00527 remque(i,0);
00528
00529 i->irp_l_iost1= (s->srb$w_datasize<<16) + SS$_NORMAL;
00530 i->irp_l_iost2 = exe$ipid_to_epid(msg->mmb$l_pid);
00531
00532 com_post(i,u);
00533 }
00534 break;
00535 }
00536 } while (not_done);
00537
00538 if (room_ast)
00539 com_std_delattnast(&mu->ucb$l_mb_room_notify, u);
00540
00541 }
00542
00543 void mb_cancel (struct _irp * i, struct _pcb * p, struct _ucb * u, struct _ccb * c) {
00544 int func=i->irp_l_func;
00545
00546 }
00547
00548 void mb_aux_routine (struct _irp * i, struct _pcb * p, struct _ucb * u, struct _ccb * c) {
00549 int func=i->irp_l_func;
00550
00551 }
00552
00553 static struct _fdt mb_fdt = {
00554 fdt_q_valid:IO$_NOP|IO$_UNLOAD|IO$_AVAILABLE|IO$_PACKACK|IO$_SENSECHAR|IO$_SETCHAR|IO$_SENSEMODE|IO$_SETMODE|IO$_WRITECHECK|IO$_READPBLK|IO$_WRITELBLK|IO$_DSE|IO$_ACCESS|IO$_ACPCONTROL|IO$_CREATE|IO$_DEACCESS|IO$_DELETE|IO$_MODIFY|IO$_MOUNT|IO$_READRCT|IO$_CRESHAD|IO$_ADDSHAD|IO$_COPYSHAD|IO$_REMSHAD|IO$_SHADMV|IO$_DISPLAY|IO$_SETPRFPATH|IO$_FORMAT,
00555 fdt_q_buffered:IO$_NOP|IO$_UNLOAD|IO$_AVAILABLE|IO$_PACKACK|IO$_DSE|IO$_SENSECHAR|IO$_SETCHAR|IO$_SENSEMODE|IO$_SETMODE|IO$_ACCESS|IO$_ACPCONTROL|IO$_CREATE|IO$_DEACCESS|IO$_DELETE|IO$_MODIFY|IO$_MOUNT|IO$_CRESHAD|IO$_ADDSHAD|IO$_COPYSHAD|IO$_REMSHAD|IO$_SHADMV|IO$_DISPLAY|IO$_FORMAT
00556 };
00557
00558
00559 static void startio () { };
00560 static void unsolint (void) { };
00561 static void cancel (void) { };
00562 static void regdump (void) { };
00563 static void diagbuf (void) { };
00564 static void errorbuf (void) { };
00565 static void unitinit (void) { };
00566 static void altstart (void) { };
00567 static void mntver (void) { };
00568 static void cloneducb (void) { };
00569 static void mntv_sssc (void) { };
00570 static void mntv_for (void) { };
00571 static void mntv_sqd (void) { };
00572 static void aux_storage (void) { };
00573 static void aux_routine (void) { };
00574
00575 static struct _ddt mb_ddt = {
00576 ddt_l_start: startio,
00577 ddt_l_unsolint: unsolint,
00578 ddt_l_fdt: &mb$fdt,
00579 ddt_l_cancel: cancel,
00580 ddt_l_regdump: regdump,
00581 ddt_l_diagbuf: diagbuf,
00582 ddt_l_errorbuf: errorbuf,
00583 ddt_l_unitinit: unitinit,
00584 ddt_l_altstart: altstart,
00585 ddt_l_mntver: mntver,
00586 ddt_l_cloneducb: cloneducb,
00587 ddt_w_fdtsize: 0,
00588 ddt_ps_mntv_sssc: mntv_sssc,
00589 ddt_ps_mntv_for: mntv_for,
00590 ddt_ps_mntv_sqd: mntv_sqd,
00591 ddt_ps_aux_storage: aux_storage,
00592 ddt_ps_aux_routine: aux_routine
00593 };
00594
00595 #undef ini_fdt_act
00596 extern void ini_fdt_act(struct _fdt * f, unsigned long long mask, void * fn, unsigned long type);
00597
00598 void mb_struc_init (struct _crb * crb, struct _ddb * ddb, struct _idb * idb, struct _orb * orb, struct _ucb * ucb) {
00599 ucb->ucb_b_flck=IPL$_IOLOCK8;
00600 ucb->ucb_b_dipl=IPL$_IOLOCK8;
00601
00602 ucb->ucb_l_devchar = DEV$M_REC | DEV$M_AVL | DEV$M_CCL | DEV$M_FOD;
00603
00604 ucb->ucb_l_devchar2 = DEV$M_NNM;
00605 ucb->ucb_b_devclass = DC$_MAILBOX;
00606 #if 0
00607 ucb->ucb_b_devtype = DT$_TTYUNKN;
00608 ucb->ucb_w_devbufsiz = 132;
00609 #endif
00610
00611 ucb->ucb_l_devdepend = 99;
00612
00613
00614
00615 return;
00616 }
00617
00618 void mb_struc_reinit (struct _crb * crb, struct _ddb * ddb, struct _idb * idb, struct _orb * orb, struct _ucb * ucb) {
00619 ddb->ddb_ps_ddt=&mb$ddt;
00620
00621 return;
00622 }
00623
00624 struct _ucb * mbucb0;
00625
00626 int mb_unit_init (struct _idb * idb, struct _ucb * ucb) {
00627 ucb->ucb_v_online = 0;
00628
00629
00630
00631
00632
00633
00634
00635 ucb->ucb_v_online = 1;
00636
00637 #if 0
00638 ucb -> ucb_w_size = sizeof(struct _mb_ucb);
00639 #endif
00640
00641 mbucb0=ucb;
00642
00643 return SS__NORMAL;
00644 }
00645
00646 struct _dpt mb_dpt;
00647 struct _ddb mb_ddb;
00648 struct _mb_ucb mb_ucb;
00649 struct _crb mb_crb;
00650
00651 int mb_init_tables() {
00652 ini_dpt_name(&mb_dpt, "MBDRIVER");
00653 ini_dpt_adapt(&mb_dpt, 0);
00654 ini_dpt_defunits(&mb_dpt, 1);
00655 ini_dpt_ucbsize(&mb_dpt,sizeof(struct _mb_ucb));
00656 ini_dpt_struc_init(&mb_dpt, mb$struc_init);
00657 ini_dpt_struc_reinit(&mb_dpt, mb$struc_reinit);
00658 ini_dpt_ucb_crams(&mb_dpt, 1);
00659 ini_dpt_end(&mb_dpt);
00660
00661 ini_ddt_unitinit(&mb_ddt, mb$unit_init);
00662 ini_ddt_start(&mb_ddt, startio);
00663 ini_ddt_cancel(&mb_ddt, ioc_std$cancelio);
00664 ini_ddt_end(&mb_ddt);
00665
00666
00667
00668 ini_fdt_act(&mb_fdt,IO$_READLBLK,mb$fdt_read,1);
00669 ini_fdt_act(&mb_fdt,IO$_READPBLK,mb$fdt_read,1);
00670 ini_fdt_act(&mb_fdt,IO$_READVBLK,mb$fdt_read,1);
00671 ini_fdt_act(&mb_fdt,IO$_WRITELBLK,mb$fdt_write,1);
00672 ini_fdt_act(&mb_fdt,IO$_WRITEPBLK,mb$fdt_write,1);
00673 ini_fdt_act(&mb_fdt,IO$_WRITEVBLK,mb$fdt_write,1);
00674 ini_fdt_act(&mb_fdt,IO$_WRITEOF, mb$fdt_write, 1);
00675 ini_fdt_act(&mb_fdt,IO$_SETMODE, mb$fdt_setmode, 1);
00676 ini_fdt_act(&mb_fdt,IO$_SENSEMODE, mb$fdt_sensemode, 1);
00677 ini_fdt_end(&mb_fdt);
00678
00679 return SS__NORMAL;
00680 }
00681
00682 long mb_iodb_vmsinit(void) {
00683 #if 0
00684 struct _ucb * ucb=&mb_ucb;
00685 struct _ddb * ddb=&mb_ddb;
00686 struct _crb * crb=&mb_crb;
00687 #endif
00688 #if 0
00689 struct _ucb * ucb=kmalloc(sizeof(struct _ucb),GFP_KERNEL);
00690 struct _ddb * ddb=kmalloc(sizeof(struct _ddb),GFP_KERNEL);
00691 struct _crb * crb=kmalloc(sizeof(struct _crb),GFP_KERNEL);
00692 unsigned long idb=0,orb=0;
00693
00694 mbucb0=ucb;
00695
00696 memset(ucb,0,sizeof(struct _ucb));
00697 memset(ddb,0,sizeof(struct _ddb));
00698 memset(crb,0,sizeof(struct _crb));
00699
00700 ucb -> ucb_w_size = sizeof(struct _mb_ucb);
00701
00702 init_ddb(ddb,&mb_ddt,ucb,"mba");
00703 init_ucb(ucb, ddb, &mb_ddt, crb);
00704 init_crb(crb);
00705
00706
00707 mb_init_tables();
00708 mb_struc_init (crb, ddb, idb, orb, ucb);
00709 mb_struc_reinit (crb, ddb, idb, orb, ucb);
00710 mb_unit_init (idb, ucb);
00711
00712 insertdevlist(ddb);
00713
00714 return ddb;
00715 #endif
00716
00717 int load_driver_inner(long, long, long, long);
00718 load_driver_inner(mb_init_tables, &mb$ddt, &mb$dpt, &mb$fdt);
00719 }
00720
00721 #if 0
00722 long mb_iodbunit_vmsinit(struct _ddb * ddb,int unitno,void * dsc) {
00723 unsigned short int chan;
00724 struct _ucb * newucb;
00725 ioc_std_clone_ucb(ddb->ddb$ps_ucb,&newucb);
00726 #if 0
00727 exe_assign(dsc,&chan,0,0,0);
00728 registerdevchan(MKDEV(MB0_MAJOR,unitno),chan);
00729 #endif
00730
00731 }
00732 #endif
00733
00734 int mb_vmsinit(void) {
00735
00736
00737 unsigned short chan0, chan1, chan2;
00738 _DESCRIPTOR(u0,"mba0");
00739 unsigned long idb=0,orb=0;
00740 struct _ccb * ccb;
00741 struct _ucb * newucb0,*newucb1,*newucb2;
00742 struct _ddb * ddb;
00743
00744 printk(KERN_INFO "dev here pre\n");
00745
00746 ddb=mb_iodb_vmsinit();
00747
00748
00749
00750
00751 #if 0
00752 mb_iodbunit_vmsinit(ddb,0,&u0);
00753 #endif
00754
00755 printk(KERN_INFO "dev here\n");
00756
00757
00758
00759 }
00760
00761 int exe_std_wrtmailbox (struct _mb_ucb *mb_ucb, int msgsiz, void *msg,...) {
00762 struct __mmb * m;
00763 struct _ucb * u = mb_ucb;
00764
00765 if (msgsiz>u->ucb_w_bufquo) {
00766
00767 return SS__MBFULL;
00768
00769 }
00770 if (msgsiz>u->ucb_w_devbufsiz)
00771 return SS__MBTOOSML;
00772
00773
00774 m=kmalloc(sizeof(struct __mmb)+msgsiz,GFP_KERNEL);
00775 memset(m,0,sizeof(struct __mmb)+msgsiz);
00776 m->mmb_w_size=sizeof(struct __mmb)+msgsiz;
00777 m->mmb_b_type=DYN$C_BUFIO;
00778 m->mmb_b_func=0;
00779 m->mmb_w_datasize=msgsiz;
00780 qhead_init(&m->mmb_l_noreaderwaitqfl);
00781 m->mmb_l_irp=0;
00782 m->mmb_l_pid=ctl$gl_pcb->pcb$l_pid;
00783 m->mmb_l_datastart=&m->mmb$t_data;
00784 if (m->mmb_w_datasize)
00785 memcpy(m->mmb_t_data,msg,msgsiz);
00786
00787 u->ucb_w_msgcnt++;
00788 u->ucb_l_devdepend=u->ucb$w_msgcnt;
00789
00790 if (m->mmb_w_bufquochrg) {
00791
00792 if (m->mmb_w_datasize==0)
00793 u->ucb_w_bufquo++;
00794 else
00795 u->ucb_w_bufquo-=m->mmb$w_datasize;
00796 }
00797
00798 insque(m,u->ucb_l_mb_msgqbl);
00799
00800 if (!aqempty(mb_ucb->ucb_l_mb_readqfl))
00801 mb_finishread(u);
00802 else
00803 {
00804 com_std_delattnast(&u->ucb$l_mb_w_ast, u);
00805 }
00806
00807
00808
00809 return SS__NORMAL;
00810 }
00811
00812 int exe_std_sndevmsg(struct _mb_ucb *mb_ucb, int msgtyp, struct _ucb *ucb) {
00813 struct _ucb * u=mb_ucb;
00814 long message[8];
00815
00816 if (u->ucb_b_devclass != DC$_MAILBOX)
00817 return SS__DEVNOTMBX;
00818 message[0]=msgtyp + (ucb->ucb_w_unit << 16);
00819 message[1]=0;
00820
00821
00822 sprintf(&message[1],"%s%d",&ucb->ucb_l_ddb->ddb$t_name[1],ucb->ucb$w_unit);
00823
00824 return exe_std_wrtmailbox(mb_ucb,8*sizeof(long),message);
00825 }
00826
00827 int mb_chanunwait(struct _ucb * u, struct _ccb * c) {
00828
00829
00830 struct _mb_ucb * mu = u;
00831 if ((c->ccb_l_sts&CCB$M_NOREADACC)==0)
00832 mu->ucb_l_mb_readerrefc++;
00833 if ((c->ccb_l_sts&CCB$M_NOWRITEACC)==0)
00834 mu->ucb_l_mb_writerrefc++;
00835 if ((c->ccb_l_sts&CCB$M_NOREADACC)==0) {
00836 struct _irp * i=mu->ucb_l_mb_readerwaitqfl;
00837 while (!aqempty(mu->ucb_l_mb_readerwaitqfl)) {
00838 i->irp_l_iost1=SS$_NORMAL;
00839 i->irp_l_iost2=0;
00840 com_post(i,u);
00841 remque(i,0);
00842 i=mu->ucb_l_mb_readerwaitqfl;
00843 }
00844 }
00845 if ((c->ccb_l_sts&CCB$M_NOWRITEACC)==0) {
00846 struct _irp * i=mu->ucb_l_mb_writerwaitqfl;
00847 while (!aqempty(mu->ucb_l_mb_writerwaitqfl)) {
00848 i->irp_l_iost1=SS$_NORMAL;
00849 i->irp_l_iost2=0;
00850 com_post(i,u);
00851 remque(i,0);
00852 i=mu->ucb_l_mb_writerwaitqfl;
00853 }
00854 }
00855 return SS__NORMAL;
00856 }
00857