.TITLE GET_ETHERNET_ID .IDENT /E01/ ;++ ; ; GET_ETHERNET_ID - return hardware address of Ethernet adapter ; ; Calling format: ; ; status = GET_ETHERNET_ID (id) ; ; Arguments: ; ; id 6-byte location where Ethernet hardware id is to be ; stored. Passed by reference ; ; Returned statuses: ; ; SS$_NORMAL - Normal successful completion ; LIB$_INSEF - Insufficient event flags ; Other errors from $ASSIGN, $QIOW ; ; Notes: ; ; Device name is coded as XQA0 for DEQNA - change below to ; XEA0 for DEUNA or DELUA. ; ;-- .LIBRARY "SYS$LIBRARY:LIB.MLB" $IODEF $NMADEF $SSDEF .DSABL GLOBAL .EXTRN LIB$GET_EF .EXTRN LIB$FREE_EF .PSECT $CODE,RD,EXE,NOWRT,SHR,PIC DEVNAM: .ASCII 'XEA0' ; Change to XEA0 for DEUNA/DELUA ;+ ; Define offsets into stack frame for various structures ;- DEVDSC = -8 ; Quadword string descriptor for device name CHARBUF = DEVDSC - 8 ; Sense mode P1 Charcteristics Buffer EXCBUF_SIZE = 120 ; Size of Extended Characteristics Buffer EXCBUF = CHARBUF - EXCBUF_SIZE ; P2 Extended Characteristics Buffer EXCDSC = EXCBUF - 8 ; Descriptor for EXCBUF IOSB = EXCDSC - 8 ; I/O status block EFN = IOSB - 4 ; Event flag number CHANNEL = EFN - 4 ; Channel DATA_SIZE = CHANNEL ; Size of data area .ENTRY GET_ETHERNET_ID, ^M ADDL2 #DATA_SIZE, SP ; Allocate stack frame MOVL #4, B^DEVDSC(FP) ; Set up string descriptor MOVAB B^DEVNAM, B^DEVDSC+4(FP) ;+ ; Assign a channel to the device. ;- $ASSIGN_S DEVNAM = DEVDSC(FP), CHAN = CHANNEL(FP) BLBC R0, 5$ ; If error ;+ ; Allocate a local event flag number. ;- PUSHAB W^EFN(FP) CALLS #1, G^LIB$GET_EF BLBC R0, 5$ ; If error ;+ ; Set up the extended characteristics buffer descriptor ;- MOVAB EXCDSC(FP), R0 MOVL #EXCBUF_SIZE, (R0) ; Buffer size MOVAB EXCBUF(FP), 4(R0) ; Buffer address ;+ ; Sense the characteristics ;- $QIOW_S FUNC = #, - CHAN = CHANNEL(FP),- EFN = EFN(FP),- IOSB = IOSB(FP),- P1 = CHARBUF(FP),- P2 = R0 ; Address of EXCDSC BLBC R0, FINISH MOVW IOSB(FP), R0 5$: BLBC R0, FINISH ;+ ; Scan through the extended characteristics buffer looking for the ; hardware ID. ;- MOVAB EXCBUF(FP), R0 ; Get buffer address MOVZWL IOSB+2(FP), R2 ; Get buffer size ADDL2 R0, R2 ; Determine end of buffer 10$: CMPL R0, R2 ; End of buffer? BGEQU NOTFOUND ; If so, error MOVW (R0)+, R1 ; Get next parameter ID CMPZV #0, #12, R1, #NMA$C_PCLI_HWA BEQL 30$ ; Got the hardware ID BBS #12, R1, 20$ ; Skip if counted string ADDL2 #4, R0 ; Skip next longword BRB 10$ 20$: MOVZWL (R0)+, R1 ; Get string length ADDL2 R1, R0 ; Skip string BRB 10$ 30$: ADDL2 #2, R0 ; Skip length (we assume it is 6) MOVL 4(AP), R1 ; Get destination address MOVW (R0)+, (R1)+ ; Move first two bytes MOVL (R0), (R1) ; Move last four bytes MOVL #1, R0 ; Success FINISH: MOVL R0, R2 ; Save completion status TSTL CHANNEL(FP) ; Do we have a channel assigned? BEQL 10$ ; If so, deassign it $DASSGN_S CHAN = CHANNEL(FP) 10$: TSTL EFN(FP) ; Do we have an EFN allocated? BEQL 20$ ; If so, deallocate it PUSHAB EFN(FP) CALLS #1, G^LIB$FREE_EF 20$: MOVL R2, R0 ; Return completion status RET ;+ ; Come here in unlikely event that hardware address is not located ;- NOTFOUND: MOVL #SS$_BADPARAM, R0 BRB FINISH .END ============================================================================= C Test of GET_ETHERNET_ID INTEGER*4 GET_ETHERNET_ID BYTE HARDWARE_ID(6) ISTAT = GET_ETHERNET_ID (HARDWARE_ID) IF (.NOT. ISTAT) CALL LIB$STOP(%VAL(ISTAT)) WRITE (6,101) HARDWARE_ID 101 FORMAT(' Ethernet hardware address is: ',6(Z2.2,:,'-')) END