From: mckinneyj@cpva.saic.com Sent: Tuesday, July 06, 1999 1:34 PM To: Info-VAX@Mvb.Saic.Com Subject: Re: ZDEC for OpenVMS Alpha V7.x? In article <3780B904.193303D4@winternet.com>, Ed Wilts writes: > I've got an old ZDEC.MAR utility dating back many years that has served > me well over the years. Yesterday, I built it on a V7.1-2 system, and > although it compiled/linked without any problems, when zeroing a device > error count, it did it a little more aggressively than I would have > liked (can you say bugcheck boys & girls?)... > > Does anyone have a utility that zeros device error counts for V7.1? An > internals programmer I am not. > > Thanks, > .../Ed > mailto:ewilts@winternet.com -- Here's a hack that'll work on V7.1. I think that it was originally posted here many years ago (don't recall the author though it could possibly have been Ehud) as a combination of C and Macro. I've rewritten the assembler portion so that it's now all in C... - Jim ============================ ZERO.C ========================= /* * zero() - Clear device error count * * Usage: * $ zero == "$location:zero.exe" * $ zero [device] * * Build: * $ cc zero+sys$library:sys$lib_c.tlb/lib * $ link/sysexe/notrace zero * */ #define module_name Zero #define module_vers "V1.0.0" #ifdef __alpha #pragma module module_name module_vers #else /* __vax */ #module module_name module_vers #endif /* __alpha */ #include /* Descriptor structure definitions (for prompt) */ #include /* RTL routines */ #include /* Privilege definitions (to get BYPASS and *_IO) */ #include /* System service status values */ #include /* System service routines */ #include /* Channel control block */ #include /* Unit control block */ #include /* IO routines (ioc$verify_chan) */ #define check if(!(status & 1)) sys$exit(status); #ifdef __alpha main() #else /* __vax */ cmain() #endif /* __alpha */ { $DESCRIPTOR(prompt,"_Device: "); struct dsc$descriptor_s device; char _align(quadword) devbuf[32]; int32 _align(quadword) privmsk[2]; int32 status; int16 channel; CCB *ccb_p; /* pointer to device's CCB */ struct { int32 arg_count; /* number of args passed */ int32 ucb; /* 32bit address of ucb */ } cmkrnl_args; int32 reset_errcnt(int32 ucb); device.dsc$a_pointer = (char *) &devbuf; device.dsc$w_length = sizeof(devbuf); device.dsc$b_class = DSC$K_CLASS_S; device.dsc$b_dtype = DSC$K_DTYPE_T; /* Get the device name from the command line */ status = lib$get_foreign(&device,&prompt,&device.dsc$w_length,0); check; /* Enable privileges for access to device */ privmsk[0] = PRV$M_BYPASS | PRV$M_PHY_IO | PRV$M_LOG_IO; status = sys$setprv(1,&privmsk,0,0); check; /* Assign a channel to the device */ status = sys$assign(&device,&channel,0,0,0); check; /* Get UCB address from CCB */ status = ioc$verify_chan(channel, &ccb_p); /* get the device's CCB */ check; /* Call the kernel-mode routine to fixup UCB */ cmkrnl_args.arg_count = 1; /* a single argument */ cmkrnl_args.ucb = (int32) ccb_p->ccb$l_ucb; /* 32bit UCB address from CCB */ status = sys$cmkrnl(&reset_errcnt, &cmkrnl_args); check; /* Deassign the channel to device */ status = sys$dassgn(channel); check; return(SS$_NORMAL); } /* reset_errcnt - the kernel mode code */ /* we'll only be receiving the 32 significant bits of the UCB's address */ /* since sys$cmkrnl wants an arg list consisting of 32bit integers */ int32 reset_errcnt(int32 ucb) { UCB *ucb_p; /* allocate a pointer to UCB */ ucb_p = (UCB *) ucb; /* cast our argument there */ ucb_p->ucb$l_errcnt = 0; ucb_p->ucb$l_softerrcnt = 0; return(SS$_NORMAL); }