int get_mscp_chan(char * s) { int sts; unsigned short int chan; struct _ucb * ucb; struct dsc$descriptor dsc; struct return_values r; struct _vcb * vcb; struct _aqb * aqb; dsc.dsc$a_pointer=do_file_translate(s); dsc.dsc$w_length=strlen(dsc.dsc$a_pointer); if (ioc$search(&r,&dsc)==SS$_NORMAL) return ((struct _ucb *)r.val1)->ucb$ps_adp; ucb = fl_init(s); vcb = (struct _vcb *) kmalloc(sizeof(struct _vcb),GFP_KERNEL); memset(vcb,0,sizeof(struct _vcb)); vcb->vcb$b_type=DYN$C_VCB; aqb = (struct _aqb *) kmalloc(sizeof(struct _aqb),GFP_KERNEL); memset(aqb,0,sizeof(struct _aqb)); aqb->aqb$b_type=DYN$C_AQB; qhead_init(&aqb->aqb$l_acpqfl); ucb->ucb$l_vcb=vcb; vcb->vcb$l_aqb=aqb; qhead_init(&vcb->vcb$l_fcbfl); vcb->vcb$l_cache = NULL; // ? sts = phyio_init(strlen(s),s,&ucb->ucb$l_vcb->vcb$l_aqb->aqb$l_mount_count,0,0); // check dsc.dsc$a_pointer=do_file_translate(s); dsc.dsc$w_length=strlen(dsc.dsc$a_pointer); sts=exe$assign(&dsc,&chan,0,0,0); ucb->ucb$ps_adp=chan; //wrong field and use, but.... return chan; }
void __init xqp_init(void) { #if 0 int i; for(i=0; i<1; i++) { qhead_init(&xqps[i].xqp_head); } #endif }
asmlinkage int exe$creprc(unsigned int *pidadr, void *image, void *input, void *output, void *error, struct _generic_64 *prvadr, unsigned int *quota, void*prcnam, unsigned int baspri, unsigned int uic, unsigned short int mbxunt, unsigned int stsflg,...) { unsigned long stack_here; struct _pcb * p, * cur; int retval; struct dsc$descriptor * imd = image, * ind = input, * oud = output, * erd = error; unsigned long clone_flags=CLONE_VFORK; //check pidadr ctl$gl_creprc_flags = stsflg; // check for PRC$M_NOUAF sometime if (stsflg&PRC$M_DETACH) { } if (uic) { } //setipl(IPL$_ASTDEL);//postpone this? cur=ctl$gl_pcb; vmslock(&SPIN_SCHED, IPL$_SCHED); vmslock(&SPIN_MMG, IPL$_MMG); p = alloc_task_struct(); //bzero(p,sizeof(struct _pcb));//not wise? memset(p,0,sizeof(struct _pcb)); // check more // compensate for no struct clone/copy p->sigmask_lock = SPIN_LOCK_UNLOCKED; p->alloc_lock = SPIN_LOCK_UNLOCKED; qhead_init(&p->pcb$l_astqfl); // and enable ast del to all modes p->pcb$b_type = DYN$C_PCB; p->pcb$b_asten=15; p->phd$b_astlvl=4; p->pr_astlvl=4; p->psl=0; p->pslindex=0; qhead_init(&p->pcb$l_lockqfl); // set capabilities p->pcb$l_permanent_capability = sch$gl_default_process_cap; p->pcb$l_capability = p->pcb$l_permanent_capability; // set affinity // set default fileprot // set arb // set mbx stuff // from setprn: if (prcnam) { struct dsc$descriptor *s=prcnam; strncpy(p->pcb$t_lname,s->dsc$a_pointer,s->dsc$w_length); } // set priv p->pcb$l_priv=ctl$gl_pcb->pcb$l_priv; // set pris p->pcb$b_prib=31-baspri; p->pcb$b_pri=31-baspri-6; // if (p->pcb$b_pri<16) p->pcb$b_pri=16; p->pcb$w_quant=-QUANTUM; // set uic p->pcb$l_uic=ctl$gl_pcb->pcb$l_uic; // set vms pid // check process name // do something with pqb p->pcb$l_pqb=kmalloc(sizeof(struct _pqb),GFP_KERNEL); memset(p->pcb$l_pqb,0,sizeof(struct _pqb)); struct _pqb * pqb = p->pcb$l_pqb; pqb->pqb$q_prvmsk = ctl$gq_procpriv; if (imd) memcpy(pqb->pqb$t_image,imd->dsc$a_pointer,imd->dsc$w_length); if (ind) memcpy(pqb->pqb$t_input,ind->dsc$a_pointer,ind->dsc$w_length); if (oud) memcpy(pqb->pqb$t_output,oud->dsc$a_pointer,oud->dsc$w_length); if (erd) memcpy(pqb->pqb$t_error,erd->dsc$a_pointer,erd->dsc$w_length); if (oud) // temp measure memcpy(p->pcb$t_terminal,oud->dsc$a_pointer,oud->dsc$w_length); // translate some logicals // copy security clearance // copy msg // copy flags // set jib // do quotas // process itmlst // set pcb$l_pqb #if 0 setipl(IPL$_MMG); vmslock(&SPIN_SCHED,-1); // find vacant slot in pcb vector // and store it #endif // make ipid and epid p->pcb$l_pid=alloc_ipid(); { unsigned long *vec=sch$gl_pcbvec; vec[p->pcb$l_pid&0xffff]=p; } p->pcb$l_epid=exe$ipid_to_epid(p->pcb$l_pid); // should invoke sch$chse, put this at bottom? // setipl(0) and return // now lots of things from fork retval = -EAGAIN; /* * Check if we are over our maximum process limit, but be sure to * exclude root. This is needed to make it possible for login and * friends to set the per-user process limit to something lower * than the amount of processes root is running. -- Rik */ #if 0 if (atomic_read(&p->user->processes) >= p->rlim[RLIMIT_NPROC].rlim_cur && !capable(CAP_SYS_ADMIN) && !capable(CAP_SYS_RESOURCE)) goto bad_fork_free; atomic_inc(&p->user->__count); atomic_inc(&p->user->processes); #endif /* * Counter increases are protected by * the kernel lock so nr_threads can't * increase under us (but it may decrease). */ get_exec_domain(p->exec_domain); if (p->binfmt && p->binfmt->module) __MOD_INC_USE_COUNT(p->binfmt->module); p->did_exec = 0; p->swappable = 0; p->state = TASK_UNINTERRUPTIBLE; //copy_flags(clone_flags, p); // not here? p->pcb$l_pid = alloc_ipid(); p->run_list.next = NULL; p->run_list.prev = NULL; p->p_cptr = NULL; init_waitqueue_head(&p->wait_chldexit); p->vfork_done = NULL; spin_lock_init(&p->alloc_lock); p->sigpending = 0; init_sigpending(&p->pending); p->it_real_value = p->it_virt_value = p->it_prof_value = 0; p->it_real_incr = p->it_virt_incr = p->it_prof_incr = 0; init_timer(&p->real_timer); p->real_timer.data = (unsigned long) p; p->leader = 0; /* session leadership doesn't inherit */ p->tty_old_pgrp = 0; p->times.tms_utime = p->times.tms_stime = 0; p->times.tms_cutime = p->times.tms_cstime = 0; p->lock_depth = -1; /* -1 = no lock */ p->start_time = jiffies; INIT_LIST_HEAD(&p->local_pages); p->files = current->files; p->fs = current->fs; p->sig = current->sig; /* copy all the process information */ if (copy_files(clone_flags, p)) goto bad_fork_cleanup; if (copy_fs(clone_flags, p)) goto bad_fork_cleanup_files; if (copy_sighand(clone_flags, p)) goto bad_fork_cleanup_fs; bad_fork_cleanup: bad_fork_cleanup_files: bad_fork_cleanup_fs: // now a hole // now more from fork /* ok, now we should be set up.. */ p->swappable = 1; p->exit_signal = 0; p->pdeath_signal = 0; /* * "share" dynamic priority between parent and child, thus the * total amount of dynamic priorities in the system doesnt change, * more scheduling fairness. This is only important in the first * timeslice, on the long run the scheduling behaviour is unchanged. */ /* * Ok, add it to the run-queues and make it * visible to the rest of the system. * * Let it rip! */ retval = p->pcb$l_epid; INIT_LIST_HEAD(&p->thread_group); /* Need tasklist lock for parent etc handling! */ write_lock_irq(&tasklist_lock); /* CLONE_PARENT and CLONE_THREAD re-use the old parent */ p->p_opptr = current->p_opptr; p->p_pptr = current->p_pptr; p->p_opptr = current /*->p_opptr*/; p->p_pptr = current /*->p_pptr*/; SET_LINKS(p); nr_threads++; write_unlock_irq(&tasklist_lock); // printk("fork befwak\n"); //wake_up_process(p); /* do this last */ // wake_up_process2(p,PRI$_TICOM); /* do this last */ //goto fork_out;//?? // now something from exec // wait, better do execve itself memcpy(p->rlim, current->rlim, sizeof(p->rlim)); qhead_init(&p->pcb$l_sqfl); struct mm_struct * mm = mm_alloc(); p->mm = mm; p->active_mm = mm; p->user = INIT_USER; spin_lock(&mmlist_lock); #if 0 list_add(&mm->mmlist, &p->p_pptr->mm->mmlist); #endif mmlist_nr++; spin_unlock(&mmlist_lock); // Now we are getting into the area that is really the swappers // To be moved to shell.c and swp$shelinit later p->pcb$l_phd=kmalloc(sizeof(struct _phd),GFP_KERNEL); init_phd(p->pcb$l_phd); init_fork_p1pp(p,p->pcb$l_phd,ctl$gl_pcb,ctl$gl_pcb->pcb$l_phd); #ifdef __x86_64__ shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x2000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x2000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ffa0000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ffa0000-0x2000,0x7fffe000); #else shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff80000-0x2000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x1000,0x7fffe000); shell_init_other(p,ctl$gl_pcb,0x7ff90000-0x2000,0x7fffe000); #endif int exe$procstrt(struct _pcb * p); struct pt_regs * regs = &pidadr; //printk("newthread %x\n",p), retval = new_thread(0, clone_flags, 0, 0, p, 0); int eip=0,esp=0; // start_thread(regs,eip,esp); sch$chse(p, PRI$_TICOM); vmsunlock(&SPIN_MMG,-1); vmsunlock(&SPIN_SCHED,0); return SS$_NORMAL; #if 0 return sys_execve(((struct dsc$descriptor *)image)->dsc$a_pointer,0,0); return SS$_NORMAL; #endif #if 0 { char * filename=((struct dsc$descriptor *)image)->dsc$a_pointer; char ** argv=0; char ** envp=0; struct pt_regs * regs=0; struct linux_binprm bprm; struct file *file; int retval; int i; file = open_exec(filename); retval = PTR_ERR(file); if (IS_ERR(file)) return retval; bprm.p = PAGE_SIZE*MAX_ARG_PAGES-sizeof(void *); memset(bprm.page, 0, MAX_ARG_PAGES*sizeof(bprm.page[0])); bprm.file = file; bprm.filename = filename; bprm.sh_bang = 0; bprm.loader = 0; bprm.exec = 0; if ((bprm.argc = count(argv, bprm.p / sizeof(void *))) < 0) { allow_write_access(file); fput(file); //printk("here 7 %x\n",bprm.argc); return bprm.argc; } if ((bprm.envc = count(envp, bprm.p / sizeof(void *))) < 0) { allow_write_access(file); fput(file); //printk("here 6\n"); return bprm.envc; } retval = prepare_binprm(&bprm); //printk("here 4\n"); if (retval < 0) goto out; retval = copy_strings_kernel(1, &bprm.filename, &bprm); //printk("here 3\n"); if (retval < 0) goto out; bprm.exec = bprm.p; retval = copy_strings(bprm.envc, envp, &bprm); //printk("here 2\n"); if (retval < 0) goto out; retval = copy_strings(bprm.argc, argv, &bprm); //printk("here 1\n"); if (retval < 0) goto out; retval = search_binary_handler(&bprm,regs); if (retval >= 0) /* execve success */ return retval; out: /* Something went wrong, return the inode and free the argument pages*/ allow_write_access(bprm.file); if (bprm.file) fput(bprm.file); for (i = 0 ; i < MAX_ARG_PAGES ; i++) { struct page * page = bprm.page[i]; if (page) __free_page(page); } return retval; } #endif fork_out: return retval; bad_fork_free: free_task_struct(p); goto fork_out; }
asmlinkage int exe$enq(unsigned int efn, unsigned int lkmode, struct _lksb *lksb, unsigned int flags, void *resnam, unsigned int parid, void (*astadr)(), unsigned long astprm, void (*blkastadr)(), unsigned int acmode, unsigned int rsdm_id) { int convert; int retval=SS$_NORMAL; int sts; // some tests. one only for now, should be more. if (lkmode>LCK$K_EXMODE) return SS$_BADPARAM; vmslock(&SPIN_SCS,IPL$_SCS); // check. probably too early convert=flags&LCK$M_CONVERT; if (!convert) { /* new lock */ struct _rsb * res = 0; struct _rsb * old; struct _lkb * lck = 0, *par = 0; struct dsc$descriptor * resnamdsc; int sserror=0; resnamdsc=resnam; if (resnamdsc->dsc$w_length==0 || resnamdsc->dsc$w_length>RSB$K_MAXLEN) { sserror=SS$_IVBUFLEN; goto error; } if (flags&LCK$M_EXPEDITE) if (lkmode!=LCK$K_NLMODE) { sserror=SS$_UNSUPPORTED; goto error; } if (lkmode!=LCK$K_NLMODE) { sserror=SS$_UNSUPPORTED; goto error; } res=kmalloc(sizeof(struct _rsb),GFP_KERNEL); memset(res,0,sizeof(struct _rsb)); lck=kmalloc(sizeof(struct _lkb),GFP_KERNEL); memset(lck,0,sizeof(struct _lkb)); lck->lkb$b_efn=efn; lck->lkb$l_flags=flags; lck->lkb$b_rqmode=lkmode; lck->lkb$l_cplastadr=astadr; lck->lkb$l_blkastadr=blkastadr; lck->lkb$l_astprm=astprm; lck->lkb$l_pid=current->pcb$l_pid; lck->lkb$l_lksb=lksb; qhead_init(&lck->lkb$l_sqfl); qhead_init(&lck->lkb$l_ownqfl); strncpy(res->rsb$t_resnam,resnamdsc->dsc$a_pointer,resnamdsc->dsc$w_length); res->rsb$b_rsnlen=resnamdsc->dsc$w_length; setipl(IPL$_SCS); // do scs spinlock //setipl(IPL$_ASTDEL); if (flags&LCK$M_SYSTEM) { /* priv checks */ } else { } if (parid==0) { //list_add(&res->lr_childof, &ns->ns_root_list); //this is added to lck$gl_rrsfl down below, I think } else { //check valid lock // check lock access mode par=lockidtbl[parid]; if (current->pcb$l_pid != par->lkb$l_pid) { vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return SS$_IVLOCKID; } //check if parent granted, if not return SS$_PARNOTGRANT; if (par->lkb$b_state!=LKB$K_CONVERT || par->lkb$b_state!=LKB$K_GRANTED) if ((par->lkb$l_flags & LCK$M_CONVERT) == 0) { vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return SS$_PARNOTGRANT; } par->lkb$w_refcnt++; res->rsb$l_parent = par->lkb$l_rsb; // should not be here? //check if uic-specific resource //check if system-wide //charge lock against quota //list_add(&res->lr_childof, &parent->lr_children); //res->rsb$l_rtrsb=enq_find_oldest_parent(r,p->lkb$l_rsb); lck->lkb$l_parent=par; } old=find_reshashtbl(resnamdsc); if (!old) { lck$gl_rsbcnt++; lck$gl_lckcnt++; if (flags & LCK$M_SYNCSTS) retval=SS$_SYNCH; qhead_init(&res->rsb$l_grqfl); qhead_init(&res->rsb$l_cvtqfl); qhead_init(&res->rsb$l_wtqfl); //insque(&lck->lkb$l_sqfl,res->rsb$l_grqfl); lck->lkb$l_rsb=res; insert_reshashtbl(res); if (parid==0) { insque(&res->rsb$l_rrsfl,lck$gl_rrsfl); qhead_init(&res->rsb$l_srsfl); res->rsb$b_depth=0; res->rsb$l_rtrsb=res; exe$clref(lck->lkb$b_efn); insque(&lck->lkb$l_ownqfl,¤t->pcb$l_lockqfl); //?if (q->flags & LKB$M_DCPLAST) lksb->lksb$l_lkid=insert_lck(lck); lksb->lksb$w_status=SS$_NORMAL; sts = lck$grant_lock(lck ,res ,-1,lkmode,flags,efn,res->rsb$b_ggmode); goto end; } else { // it has a parid non-zero res->rsb$l_csid=par->lkb$l_rsb->rsb$l_csid; par->lkb$l_rsb->rsb$w_refcnt++; res->rsb$b_depth=par->lkb$l_rsb->rsb$b_depth+1; //check maxdepth if (res->rsb$b_depth>10) { // pick a number ? retval=SS$_EXDEPTH; goto error; } res->rsb$l_rtrsb=par->lkb$l_rsb->rsb$l_rtrsb; insque(&res->rsb$l_srsfl,&par->lkb$l_rsb->rsb$l_srsfl); if (par->lkb$l_csid) { //remote lck$snd_granted(lck); } else { sts = lck$grant_lock(lck,res,-1,lkmode,flags,efn,res->rsb$b_ggmode); } } } else { /* old, found in resource hash table */ /* something else? */ int granted = 0; if (flags & LCK$M_SYNCSTS) retval=SS$_SYNCH; kfree(res); res=old; lck->lkb$l_rsb=res; //after, also check whether something in cvtqfl or wtqfl -> insque wtqfl if (0!=test_bit(res->rsb$b_ggmode,&lck$ar_compat_tbl[lck->lkb$b_rqmode])) { if (aqempty(res->rsb$l_wtqfl)) { granted=1; //sts = lck$grant_lock(lck ,res ,-1,lkmode,flags,efn); } else { if (flags&LCK$M_NOQUEUE) { res->rsb$w_lckcnt--; kfree(lck); vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return SS$_NOTQUEUED; } else { lck->lkb$b_state=LKB$K_WAITING; insque(&lck->lkb$l_sqfl,res->rsb$l_wtqfl); lksb->lksb$w_status=0; lck->lkb$l_status|=LKB$M_ASYNC; maybe_blkast(res,lck); } } } else { // if not compatible if (flags&LCK$M_NOQUEUE) { res->rsb$w_lckcnt--; kfree(lck); vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return SS$_NOTQUEUED; } else { lck->lkb$b_state=LKB$K_WAITING; insque(&lck->lkb$l_sqfl,res->rsb$l_wtqfl); lksb->lksb$w_status=0; lck->lkb$l_status|=LKB$M_ASYNC; maybe_blkast(res,lck); // insque(&lck->lkb$l_ownqfl,¤t->pcb$l_lockqfl); } } lksb->lksb$l_lkid=insert_lck(lck); lksb->lksb$w_status=SS$_NORMAL; if ((granted & 1)==1) { if (0/*par->lkb$l_csid*/) { //remote lck$snd_granted(lck); } else { sts = lck$grant_lock(lck, res, -1,lkmode,flags,efn,res->rsb$b_ggmode); } } } end: /* raise ipl */ vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return retval; error: /* ipl back */ kfree(res); kfree(lck); vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return sserror; } else { // convert /* convert */ int granted = 0, newmodes = 0; struct _lkb * lck; struct _rsb * res; void * dummy; int newmode; lck=lockidtbl[lksb->lksb$l_lkid]; res=lck->lkb$l_rsb; if (lck->lkb$b_state!=LKB$K_GRANTED) { vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return SS$_CVTUNGRANT; } lck->lkb$b_efn=efn; lck->lkb$l_flags=flags; lck->lkb$b_rqmode=lkmode; lck->lkb$l_cplastadr=astadr; lck->lkb$l_blkastadr=blkastadr; lck->lkb$l_astprm=astprm; lck->lkb$l_lksb=lksb; remque(&lck->lkb$l_sqfl,&lck->lkb$l_sqfl);// ? //remque(&res->rsb$l_grqfl,dummy); // superfluous if (aqempty(res->rsb$l_cvtqfl) && aqempty(res->rsb$l_grqfl)) { sts = lck$grant_lock(lck ,res,lck->lkb$b_grmode,lkmode,flags,efn,-1); vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return SS$_NORMAL; } else { // convert, something in cvtqfl or grqfl if (res->rsb$b_cgmode!=lck->lkb$b_grmode) { newmode=res->rsb$b_ggmode; } else { newmode=find_highest(lck,res); newmodes= 0; } if (test_bit(lkmode,&lck$ar_compat_tbl[newmode])) { //sts = lck$grant_lock(lck,res,lck->lkb$b_grmode,lkmode,flags,efn); granted = 1; } } if (granted) { if (newmodes) { res->rsb$b_fgmode=newmode; res->rsb$b_ggmode=newmode; res->rsb$b_cgmode=newmode; } sts = lck$grant_lock(lck,res,lck->lkb$b_grmode,lkmode /*newmode*/,flags,efn,res->rsb$b_ggmode); grant_queued(res,newmode,1,1); } else { int wasempty=aqempty(&res->rsb$l_cvtqfl); lck->lkb$b_rqmode=lkmode; insque(&lck->lkb$l_sqfl,res->rsb$l_cvtqfl); lck->lkb$b_state=LKB$K_CONVERT; lksb->lksb$w_status=0; lck->lkb$l_status|=LKB$M_ASYNC; maybe_blkast(res,lck); if (wasempty) res->rsb$b_cgmode=newmode; sts=SS$_NORMAL; } vmsunlock(&SPIN_SCS,IPL$_ASTDEL); return sts; } vmsunlock(&SPIN_SCS,IPL$_ASTDEL); }
int create_fcb_acl(struct _fcb * fcb, struct _fh2 * fh2) { struct _iosb iosb; unsigned int retsts; unsigned curvbn=1; unsigned extents = 0; struct _fh2 *head = 0; unsigned short *mp; long acep; struct _acedef * ace; #if 0 struct _vcb * vcb = xqp->current_vcb; struct _ucb * ucb; if (vcb->vcb$l_rvn) { struct _rvt * rvt = vcb->vcb$l_rvt; struct _ucb ** ucblst = rvt->rvt$l_ucblst; ucb = ucblst[fcb->fcb$b_fid_rvn - 1]; } else ucb = vcb->vcb$l_rvt; #endif void qhead_init(); qhead_init(&fcb->fcb$l_aclfl); if (fh2) head=fh2; mp = (unsigned short *) head + head->fh2$b_acoffset; acep = mp; ace = acep; while (ace->ace$b_size) { switch (ace->ace$b_type) { case ACE$C_AUDIT: break; case ACE$C_ALARM: break; case ACE$C_DIRDEF: break; case ACE$C_INFO: break; case ACE$C_KEYID: break; case ACE$C_RMSJNL_AI: case ACE$C_RMSJNL_AT: case ACE$C_RMSJNL_BI: case ACE$C_RMSJNL_RU: case ACE$C_RMSJNL_RU_DEFAULT: break; default: panic("ace does not exist\n"); break; } struct _acldef * acl = kmalloc(sizeof(struct _acldef), GFP_KERNEL); struct _acedef * newace = kmalloc(ace->ace$b_size, GFP_KERNEL); // check. needed? memcpy(newace, ace, ace->ace$b_size); acl->acl$w_size = sizeof(struct _acldef); acl->acl$b_type = DYN$C_ACL; acl->acl$l_list = newace; void insque(); insque(acl, &fcb->fcb$l_aclfl); acep += ace->ace$b_size; ace = acep; } retsts = SS$_NORMAL; return retsts; }
int mscplisten(void * packet, struct _cdt * c, struct _pdt * p) { int sts; struct _iosb * iosb=kmalloc(sizeof(struct _iosb),GFP_KERNEL); struct _cdrp * cdrp; struct _scs * scs = packet; struct _scs1 * scs1 = scs; struct _ppd * ppd = scs; struct _cdt * cdt = &cdtl[scs->scs$l_dst_conid]; struct _mscp_basic_pkt * basic = ((unsigned long)packet) + sizeof(*scs); void * next = basic; struct _transfer_commands * trans = basic; unsigned short int chan;//wasint chan =get_mscp_chan(cdt->cdt$l_condat); char * nam; $DESCRIPTOR(devnam,"d0a0"); nam=devnam.dsc$a_pointer; nam[1]=basic->mscp$b_caa; nam[3]=48+basic->mscp$w_unit; exe$assign(&devnam,&chan,0,0,0); if (hrbq==0) qhead_init(&hrbq); //printk("packet %x %x %x %x\n",packet,ppd,ppd->ppd$b_opc,chan); switch (ppd->ppd$b_opc) { case PPD$C_REQDAT: goto read; break; case PPD$C_SNDDAT: goto write; break; case PPD$C_SNDDG: goto mscp; break; default: panic("ppdopc\n"); } mscp: { unsigned long lbn=trans->mscp$l_lbn; struct _hrb * hrb=kmalloc(sizeof(struct _hrb),GFP_KERNEL); cdrp = vmalloc(sizeof(struct _cdrp)); memset(cdrp,0,sizeof(struct _cdrp)); memset(hrb,0,sizeof(struct _hrb)); hrb->hrb$l_lbn=lbn; hrb->hrb$l_cmd_time=scs1->scs$l_rspid; // wrong, but have to have some id... insque(hrb,&hrbq); if (basic->mscp$b_opcode == MSCP$K_OP_WRITE) { basic->mscp$b_opcode = MSCP$K_OP_END; cdrp->cdrp$w_cdrpsize=600; cdrp->cdrp$l_cdt=c; cdrp->cdrp$l_msg_buf=basic; cdrp->cdrp$l_xct_len=512; //scs_std$senddg(0,600,cdrp); } if (basic->mscp$b_opcode == MSCP$K_OP_READ) { } if (basic->mscp$b_opcode == MSCP$K_OP_GTUNT) { $DESCRIPTOR(disk,"dqa0"); char * str = disk.dsc$a_pointer; str[3]='0'+basic->mscp$w_unit; long long dummy; int sts=ioc$search(&dummy, &disk); struct _gtunt * gtunt = kmalloc(sizeof(struct _gtunt),GFP_KERNEL); memset(gtunt, 0, sizeof(struct _gtunt)); struct _mscp_basic_pkt * gtbas = gtunt; gtbas->mscp$b_opcode=MSCP$K_OP_GTUNT|MSCP$M_OP_END; gtbas->mscp$w_unit=basic->mscp$w_unit; if (sts==SS$_NORMAL) gtbas->mscp$w_status=MSCP$K_ST_SUCC; else gtbas->mscp$w_status=MSCP$K_ST_OFFLN; struct _cdrp * cdrp = vmalloc(sizeof(struct _cdrp)); memset(cdrp,0,sizeof(struct _cdrp)); cdrp->cdrp$w_cdrpsize=400; cdrp->cdrp$l_rspid=scs_std$alloc_rspid(0,0,cdrp,0); cdrp->cdrp$l_cdt=find_mscp_cdt(); cdrp->cdrp$l_msg_buf=gtunt; cdrp->cdrp$l_xct_len=sizeof(struct _gtunt); if (cdrp->cdrp$l_cdt==0) { printk("gtunt srv no cdt\n"); return; } scs_std$senddg(0,400,cdrp); } if (basic->mscp$b_opcode == (MSCP$K_OP_GTUNT|MSCP$M_OP_END) ) { if (basic->mscp$w_status==MSCP$K_ST_SUCC) { struct _ddb * ddb; struct _ucb * ucb; char dev[16]; extern struct _sb othersb; char len=othersb.sb$t_nodename[0]; memcpy(dev,&othersb.sb$t_nodename[1],len); dev[len]='$'; dev[len+1]='d'; dev[len+2]='q'; dev[len+3]='a'; dev[len+4]='0';//+basic->mscp$w_unit; struct dsc$descriptor disk; disk.dsc$a_pointer=dev; disk.dsc$w_length=len+5; long long dummy; int sts=ioc$search(&dummy, &disk); if (sts!=SS$_NORMAL) { ddb=ide_iodb_vmsinit(1); du_iodb_clu_vmsinit(ddb->ddb$ps_ucb); struct _ucb * ucb = ddb->ddb$ps_ucb; ucb->ucb$l_ddt=&du$ddt; if (ddb) ddb->ddb$ps_sb=&othersb; } else { long *l=&dummy; struct _ucb * u = *l; ddb = u->ucb$l_ddb; } int i=basic->mscp$w_unit; $DESCRIPTOR(d, "dqa0"); char * c= d.dsc$a_pointer; c[3]='0'+i; ucb = ide_iodbunit_vmsinit(ddb,i,&d); ucb->ucb$l_ddt=&du$ddt; ((struct _mscp_ucb *)ucb)->ucb$w_mscpunit=ucb->ucb$w_unit; printk("UCB MSCPUNIT %x\n",((struct _mscp_ucb *)ucb)->ucb$w_mscpunit); } } } return; read: { char * buf = vmalloc(1024); struct _irp * i=kmalloc(sizeof(struct _irp),GFP_KERNEL); struct _ucb * u; struct _hrb * hrb = find_hrb(scs1->scs$l_rspid); //printk("mscpread\n"); remque(hrb,hrb); memset(i,0,sizeof(struct _irp)); iosb->iosb$w_status=0; i->irp$b_type=DYN$C_IRP; i->irp$w_chan=chan; i->irp$l_func=IO$_READLBLK; i->irp$l_iosb=iosb; i->irp$l_qio_p1=buf; i->irp$l_qio_p2=512; i->irp$l_qio_p3=hrb->hrb$l_lbn; ((struct _acb *)i)->acb$b_rmod|=ACB$M_NODELETE; // bad idea to free this //printk("chan %x\n",chan); u=ctl$gl_ccbbase[chan].ccb$l_ucb; i->irp$l_ucb=u; i->irp$l_pid=current->pcb$l_pid; i->irp$l_sts|=IRP$M_BUFIO; i->irp$l_astprm=i; i->irp$l_ast=returnsome; i->irp$l_cdt=c; i->irp$l_rspid=scs1->scs$l_rspid; exe$insioq(i,u); } exe$dassgn(chan); return; write: { struct _irp * i=kmalloc(sizeof(struct _irp),GFP_KERNEL); struct _ucb * u; struct _hrb * hrb = find_hrb(scs1->scs$l_rspid); //printk("mscpwrite\n"); remque(hrb,hrb); memset(i,0,sizeof(struct _irp)); iosb->iosb$w_status=0; i->irp$b_type=DYN$C_IRP; i->irp$w_chan=chan; i->irp$l_func=IO$_WRITELBLK; i->irp$l_iosb=iosb; i->irp$l_qio_p1=next; i->irp$l_qio_p2=512; i->irp$l_qio_p3=hrb->hrb$l_lbn; //printk("chan %x\n",chan); u=ctl$gl_ccbbase[chan].ccb$l_ucb; i->irp$l_ucb=u; i->irp$l_pid=current->pcb$l_pid; i->irp$l_sts|=IRP$M_BUFIO; i->irp$l_astprm=i; i->irp$l_ast=returnsome; i->irp$l_cdt=c; i->irp$l_rspid=scs1->scs$l_rspid; exe$insioq(i,u); } exe$dassgn(chan); return; }
void xqp_init2(void) { qhead_init(&xqp->xqp_head); }