.TITLE bashdk .IDENT /1.1x/ ; experimental bashdk... ; does not try to avoid writel test. ; Seems to be needed to avoid bad blocks that don't clear on ; opticals... ;dgr$=0 vms$v5=1 ;++ ; ; Title: ; bashdk ; ; Action: ; patches dkdriver to allow opticals. Set for vms 5.5-2 ; (needs more tests to check dkdriver is ok, really. experimental.) ; ; Environment: ; CMKRNL privilege required, I/O data base is locked, program ; executed at elevated IPL. ; ; Author: ; Glenn Everhart. Uses some code from ZDEC.MAR by Mark Oakley. ;-- .SBTTL Symbols, Macros, Data .LIBRARY /SYS$LIBRARY:LIB.MLB/ $TPADEF ; Symbols for LIB$TPARSE. $SSDEF ; Symbols for return status. $UCBDEF ; Symbols for device ucb. $STSDEF ; Symbols for returned status. $DVIDEF ; Symbols for $GETDVI service. $DCDEF ; Symbols for device type. $dptdef $DEVDEF ; SYM. FOR SDI TYPE DEVICE. $brkdef $opcdef $pcbdef ; pcb symbols .PSECT CDEV_DATA,RD,WRT,NOEXE,LONG,SHR,PIC wrk: .long 0 ; scratch PIDDS: .ASCID /PID/ ; /PID switch PIDVL: .word 32 ; length of buffer .byte dsc$k_dtype_t ;text type .byte 1 ;fixed static .address pidtx pidtx: .blkl 8 ;text area for /pid:nnnnnnnn "nnnnnnnn" value pidwk: .long 0 ;work storage newpid: .long 0 ;pid to move device to P1DSC: .ascid /Device/ ; in .cld have a line ; parameter p1,prompt="Device:",value(required,type=$device),label=Device DEV_BUF: ; Buffer to hold device name. .BLKB 40 DEV_BUF_SIZ = . - DEV_BUF DEV_BUF_DESC: ; Descriptor pointing to device name. .LONG DEV_BUF_SIZ .ADDRESS DEV_BUF PID: ; Owner of device (if any). .BLKL 1 K_ARG: ; Argument list for kernel-mode routine. .LONG 2 ; 2 args .ADDRESS DEV_BUF_DESC ; Pass descriptor for device name. .address newpid ; PID to "give" device to. ; Note: pid field must be nonzero or this is a no-op. ; UCB$L_PID is set... .SBTTL Main program .PSECT CDEV_CODE,RD,NOWRT,EXE,LONG,SHR,PIC .ENTRY BSDK,^M ; Get the args. clrl newpid 30$: $CMKRNL_S - ; Enter k-mode to claim device for pid ROUTIN=Bshdk,- ARGLST=K_ARG BLBS R0,80$ BRW EXIT 80$: ; leave ret code in r0 EXIT: RET .SBTTL Bshdk Routine ;++ ; ; Functional Description: ; This routine Bshdks out the error count in the UCB for ; a specified device. ; ; Calling Sequence: ; $CMKRNL_S ROUTIN=Bshdk,ARGLST=K_ARG ; ; bash dkdriver in memory for opticals ; Formal Parameters: ; Descriptor for name of a device. ; ; Implicit Inputs: ; I/O database. ; ; Implicit Outputs: ; Device error count is set to Bshdk. ; ; Completion Status: ; Returned in R0. ; ; Side Effects: ; I/O database is locked (routine runs in kernel mode at elevated ; IPL). ; ;-- .ENTRY Bshdk,^M .if ndf,vms$v5 MOVL G^SCH$GL_CURPCB,R4 ;; Our PCB address is input to SCH .iff MOVL G^CTL$GL_PCB,R4 ;; Our PCB address is input to SCH .endc ;; routines. JSB G^SCH$IOLOCKW ;; Lock the I/O database. ;find dkdriver movl ioc$gl_dptlist,r5 ;dpt listhead movl r5,r6 1$: movl dpt$l_flink(r6),r6 ;get next elem. cmpl r6,r5 ;done? beql 77$ cmpl dpt$t_name+1(r6),#^a/DKDR/ bneq 1$ cmpl dpt$t_name+5(r6),#^a/IVER/ BNEQ 1$ ;GOT IT? ;if here r6 points at dkdriver ;bmsk=1a7a ;v5.5-2; =d0 hex ;icmpb=1a78 ;cmpb = 93 hex bmsk=6778 ;hex 1a7a icmpb=6776 ;hex 1a78 boadr=6226 ;hex 1852 boval=25 ;hex 19 (bneq -> blss) boclr1=^x1856 boclr2=^x185f slval=^x1A ;bit 26 = input device (instead of swl) sladr=^x1867 ;address in bbss inst slcmp=^xe2 ; ; don't let mode sense clear the 800 bit in ucb$l_dk_flags ; (ucb$v_noreassign) and set it in inspect routine cnorea=^x199e mdsense=^x800 ; ; avoid errs if no geom is there. geobsh=^x1b7a ; ; Also patch instruction that checks drivetype cdrom to do ; bneq to default to disk instead of default illegal. cmpb #^xD0,bmsk(r6) ;check value to bash bneq 177$ ;if neq leave cmpb #^x93,icmpb(r6) ;is it a cmpb inst? bneq 177$ cmpb #slcmp,sladr-1(r6) ;ensure bbss inst bneq 177$ ;patch dkdriver bmbc=^x1a78 ;addr of bitb instr we change to bicb2 (93 to 8a) bmts=^x1a7e ;addr of beql we change to brb (13 to 11) ; movb #00,bmsk(r6) ;bash it. movb #^x11,bmts(r6) ;accept bits as clr'd movb #^x8a,bmbc(r6) ;clr extra bits .if df,dgr$ 177$: .endc ; this patch will allow dkdriver to access other device types but will ; inhibit it from knowing that CDROM is automatically read/only. Note that ; CDRom can still be mounted /nowrite manually in this case however. ; Other SCSI types that are known will be treated OK, but if we get ; a SCSI type of 6 or 7 it will get treated like a disk. The CLRL ; instructions just prevent the read-only bits from being set. ; ; Note one uses disassembly of dkdriver, comparison of listings, and ; SDA poking to ensure one has the right addresses and values. movb #boval,boadr(r6) ;change the bneq to a blss ; so types less than 4 are treated as ;non disks ; fix so we don't need geom instantly movb #slval,geobsh(r6) ; clrl boclr1(r6) ; don't set any readonly bits ;bit 13 = hbs checked ;cdrom bit is 10000 bit ;noreass bit is 800 ; total = 2000 + 10000 = 12000 hex ;boo1=^x12800 boo1=^x10000 movl #boo1,boclr1(r6) ;set HBS check bit set and CDrom bit movl #0,boclr2(r6) ;leave nofe bit in, do not set hwl bit ; movl #dev$m_nofe,boclr2(r6) ;set nofe bit boof2=^x1864 ; movw #ucb$l_devchar2,boof2(r6) ;set nofe bit ; bicl #mdsense,cnorea(r6) ; don't clear noreassign bit from ; earlier set ; However leave cdrom bit set ; clrl boclr2(r6) ; fix not to set writelock for type 5,6, or 7 devs here movb #slval,sladr(r6) ;instead of setting swl bit, set idv bit ; which disks have anyway. ; we might be better ignoring "rc" bit errors...don't know so make it conditional ; to do so or not. ; increase retry count to 63 rci=^x100d rcu=^x100e movb #63,rcu(r6) ;change retry count from 3 to 63 ;(far as we can go in a 1 byte literal) movb #^x48,rci(r6) ;make it cvtfb, not movb ;so the count is 120, not 63 btmk=^x1cf3 ;clr out err_recov$m_rc from ignore mask bicb #^x10,btmk(r6) ig$rc=0 ;rec$eok=0 .if df,ig$rc rcmsk=^x1c42 movb #^x1b,rcmsk(r6) ;ignore err_recov$m_rc bits in mode sense too .endc .if df,rec$eok ; Also treat SCSI recovered errors as flags that we do nothing...if conditioned sensetbr=^x08ca movb #1,sensetbr(r6) ;set recovered errs as normal status returns .endc .if ndf,dgr$ 177$: .endc 77$: MOVL #SS$_NORMAL,R0 Bshdk_EXIT: PUSHL R0 ;;; Remember status. JSB G^SCH$IOUNLOCK ;;; Unlock I/O database (drop IPL). POPL R0 RET .END BSDK