;*DDK*************************************************************************/
;
; COPYRIGHT (C) Award Software International Inc., 1994
; COPYRIGHT    Copyright (C) 1995 IBM Corporation
;
;    The following IBM OS/2 WARP source code is provided to you solely for
;    the purpose of assisting you in your development of OS/2 WARP device
;    drivers. You may use this code in accordance with the IBM License
;    Agreement provided in the IBM Device Driver Source Kit for OS/2. This
;    Copyright statement may not be removed.;
;*****************************************************************************/
                name    SSPCIC
                page    60, 132
                title   'SSPCIC'
;******************************************************************************
;*
;*                            File SSPCICDP.ASM
;*
;*                        Socket Services PCIC File
;*
;*                           Function Dispatcher
;*
;*
;*
;******************************************************************************

                include ssmac.inc           ; Macros
                include ssdefs.inc          ; Sockets Services definitions
                include ss_segm.inc         ; Segment definitions
                include ssPCIC.inc          ; PCIC module defs


;*****************************************************************************
;*                         --- Segment ResData ---
;*****************************************************************************
sBegin          ResData
bEntryCnt       db      0                   ; Checks for recursion into
                                            ; interface

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                          Array of adapter structures
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Adapters        ADP_DATA MAX_ADAPTERS DUP ({})

bTotAdapters    db      0                   ; Total adapters in system
bNumAdapters    db      0                   ; Number adapters handled by this
                                            ; SS module
bFirstAdapter   db      0                   ; First adapter handled by this SS
                                            ; module
bLastAdapter    db      0                   ; Last adapter handled by this SS
                                            ; module


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;                             Function Jump Tables
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;       The three arrays defined below must be ordered in the same sequence.
;       Failure to align the three arrays breaks the interface

; ----- This array contains the function codes supported by this implementation

bFunctions      db      GET_ADP_CNT
                db      GET_SS_INFO
                db      INQ_ADAPTER
                db      GET_ADAPTER
                db      SET_ADAPTER
                db      INQ_WINDOW
                db      GET_WINDOW
                db      SET_WINDOW
                db      GET_PAGE
                db      SET_PAGE
                db      INQ_SOCKET
                db      GET_SOCKET
                db      SET_SOCKET
                db      GET_STATUS
                db      RESET_SOCKET
                db      GET_VENDOR_INFO
                db      ACK_INTERRUPT
                db      SS_ADDR
NUM_FUNCTIONS   =       $ - OFFSET bFunctions

; ----- This array is the bit-mask identifying the arguments that need to be
;       validated before invoking a specific function.

; Note: ValidateArgs function assumes the only function that does NOT validate
;       the adapter is the first one, GetAdapterCnt.  Other functions expect
;       the [BX] register to point to the appropriate entry in the Adapters
;       array.  Failure to set BM_ADAPTER for all other functions may cause
;       random data access (read and/or write) with undefined results.

bmArgs          db      0                                  ; GET_ADP_CNT
                db      BM_ADAPTER                         ; GET_SS_INFO
                db      BM_ADAPTER                         ; INQ_ADAPTER
                db      BM_ADAPTER                         ; GET_ADAPTER
                db      BM_ADAPTER                         ; SET_ADAPTER
                db      BM_ADAPTER OR BM_WINDOW            ; INQ_WINDOW
                db      BM_ADAPTER OR BM_WINDOW            ; GET_WINDOW
                db      BM_ADAPTER OR BM_WINDOW            ; SET_WINDOW
                db      BM_ADAPTER OR BM_WINDOW OR BM_PAGE ; GET_PAGE
                db      BM_ADAPTER OR BM_WINDOW OR BM_PAGE ; SET_PAGE
                db      BM_ADAPTER OR BM_SOCKET            ; INQ_SOCKET
                db      BM_ADAPTER OR BM_SOCKET            ; GET_SOCKET
                db      BM_ADAPTER OR BM_SOCKET            ; SET_SOCKET
                db      BM_ADAPTER OR BM_SOCKET            ; GET_STATUS
                db      BM_ADAPTER OR BM_SOCKET OR BM_CARD ; RESET_SOCKET
                db      BM_ADAPTER                         ; GET_VENDOR_INFO
                db      BM_ADAPTER                         ; ACK_INTERRUPT
                db      BM_ADAPTER                         ; SS_ADDR

; This array is the pointers to the code implementing the various functions

pFunctions      dw      GetAdapterCnt                      ; GET_ADP_CNT
                dw      GetSSInfo                          ; GET_SS_INFO
                dw      InquireAdapter                     ; INQ_ADAPTER
                dw      GetAdapter                         ; GET_ADAPTER
                dw      SetAdapter                         ; SET_ADAPTER
                dw      InquireWindow                      ; INQ_WINDOW
                dw      GetWindow                          ; GET_WINDOW
                dw      SetWindow                          ; SET_WINDOW
                dw      GetPage                            ; GET_PAGE
                dw      SetPage                            ; SET_PAGE
                dw      InquireSocket                      ; INQ_SOCKET
                dw      GetSocket                          ; GET_SOCKET
                dw      SetSocket                          ; SET_SOCKET
                dw      GetStatus                          ; GET_STATUS
                dw      ResetSocket                        ; RESET_SOCKET
                dw      GetVendorInfo                      ; GET_VENDOR_INFO
                dw      AckInterrupt                       ; ACK_INTERRUPT
                dw      GetSetSSAddr                       ; SS_ADDR
sEnd            ResData

;*****************************************************************************
;*                         --- Segment ResCode ---
;*****************************************************************************
sBegin          ResCode

;*****************************************************************************
;*                             --- IsCardIn ---
;*
;*     Purpose: Check, if card is in socket
;*       Input: none
;*      Output: CY, if not
;* Scratch reg: none
;*     Written: by Alexis A.Piatetsky 23.07.94
;*****************************************************************************
IsCardIn        PROC    NEAR
                push    ax
                call    GetInstSktState
                and     al, SBM_CD
                pop     ax
                clc
                jnz     @f
                stc
@@:             ret
IsCardIn        ENDP

;*****************************************************************************
;*                           --- ValidateArgs ---
;*
;*     Purpose: Validate arguments according to function
;*       Input: [SI] = index into validation table
;*      Output: CY and Error code in Args.AH, if failed
;* Scratch reg: all
;*     Written: by Alexis A.Piatetsky 28.07.94
;*****************************************************************************
ValidateArgs    PROC    NEAR
                assume  ds:@data, es:Nothing

;--------------------- Initialize dynamic stack variables ---------------------

                mov     (ARGS PTR [BP]).bSocketIdx, 0
                mov     (ARGS PTR [BP]).bWindowIdx, 0
                mov     (ARGS PTR [BP]).bSocketNum, 0
                mov     (ARGS PTR [BP]).bWindowNum, 0

;------------ Validate adapter and create index into adapter array ------------
; Note: Adapter already confirmed in range by Dispatch code

                test    bmArgs[si], BM_ADAPTER  ; Need to check adapter?
                jnz     short @f                ; Yes, continue

                xor     ah, ah                  ; No, special case
                                                ; (GetAdapterCnt)
                jmp     short VAExit            ;  we're done, indicate success
@@:
                mov     al, (ARGS PTR [BP]).ALReg
                                                ; Index into array of adapters
                sub     al, bFirstAdapter
                mov     bl, sizeof ADP_DATA
                mul     bl
                add     ax, offset Adapters
                mov     bx, ax                  ; bx - Point adapter structure

;------------------------------- Validate Window ------------------------------

                test    bmArgs[si], BM_WINDOW   ; Need to check window?
                jz      short CkSocket

                mov     al, (ARGS PTR [bp]).BHReg ; Get window number

                cmp     al, (ADP_DATA PTR [bx]).bNumWindows ; Valid window ?
                mov     ah, BAD_WINDOW          ; Default to no
                jae     short VAExit            ; No, exit now

                call    CalcWndIndex
                mov     al, (ARGS PTR [bp]).bSocketNum
                jmp     short CreateSktIdx      ; If we are here, we already
                                                ; have socket number in
                                                ; bSocketNum

;------------------------------- Validate Socket ------------------------------


CkSocket:       test    bmArgs[si], BM_SOCKET
                jz      short CheckPage

                mov     ah, BAD_SOCKET          ; Default to     socket
                mov     al, (ARGS PTR [bp]).BLReg ; Get socket number

                cmp     al, (ADP_DATA PTR [bx]).bNumSockets ; Valid socket ?
                jae     short VAExit            ; No, exit now

                mov     (ARGS PTR [bp]).bSocketNum, al

CreateSktIdx:   mov     cl, PCIC_SKTINC
                mul     cl
                mov     (ARGS PTR [BP]).bSocketIdx, al

;-------------------------------- Validate page -------------------------------

CheckPage:      test    bmArgs[si], BM_PAGE
                jz      short CheckCard

                mov     ah, BAD_PAGE
                cmp     (ARGS PTR [bp]).BLReg, 0
                jne     short VAExit

                mov     ah, BAD_WINDOW
                cmp     (ARGS PTR [BP]).bWindowType, WIN_MEM
                je      CheckCard
                stc
                jmp     short VAExit

;-------------------------- Check, if card is inside --------------------------

CheckCard:      xor     ah, ah                  ; Default to success

                test    bmArgs[si], BM_CARD     ; Need to check for PC Card ?
                jz      short VAExit            ; No, we're done

                call    IsCardIn                ; Return CY, if not
                jnc     short VAExit            ; Yes, we're done

                mov     ah, NO_CARD             ; No, error out

VAExit:         mov     (ARGS PTR [BP]).AHReg, ah
                cmp     ah, 1
                cmc
                ret

ValidateArgs    ENDP

;*****************************************************************************
;*                           --- codCommon16 ---
;*
;*     Purpose: Common 16 bit entry point
;*       Input: As specified by PCMCIA
;*      Output: As specified by PCMCIA
;* Scratch reg: As specified by PCMCIA
;*     Written: by Alexis A.Piatetsky 28.07.94
;*****************************************************************************
codCommon16     PROC    FAR
                assume  ds:Nothing, es:Nothing

                push    ds                  ; Establish data addressability
                push    ax
                mov     ax, @data
                mov     ds, ax
        assume  ds:@data
                pop     ax

;---------------------------- Check adapter number ----------------------------

                cmp     ah, GET_ADP_CNT     ; Get adapter count ?
                je      adCheckOk           ; Yes, skip adapter check

                cmp     al, bFirstAdapter   ; valid adapter specified ?
                jb      ssBadAdapter

                cmp     al, bLastAdapter    ; maybe, adapter within range ?
                jbe     short adCheckOk     ; yes, continue

ssBadAdapter:   mov     ah, BAD_ADAPTER     ; no, indicate error
                jmp     short Common16Exit  ;  and exit

;---------------------- Check, if Interface is available ----------------------

adCheckOk:      cmp     ah, ACK_INTERRUPT   ; AckInterrupt request ?
                je      short @f            ; Yes, skip recursion check
                                            ; and interrupt enabling
                cmp     bEntryCnt, 0        ; Already in Socket Services ?
                je      short @f            ; No, attempt request


                mov     ah, BUSY            ; Yes, indicate error
                jmp     short Common16Exit  ;  and exit

;----------------------------- Enter in interface -----------------------------

@@:             inc     bEntryCnt           ; Indicate we're in interface call    Dispatch
                pop     ds                  ; Restore original ds value
                push    ds                  ; Keep it again
                pushx   <ax, bx, cx, dx, si, di, ds, es, bp> ; Create pars
                                                             ; structure in
                sub     sp, DYN_SIZE

                mov     bp, sp              ; Establish pointer to arguments

                push    es
                mov     ax, @data
                mov     ds, ax
                mov     es, ax
        assume  ds:@data, es:@data

                mov     al, (ARGS PTR [BP]).AHReg ; Get function to match
                mov     di, offset bFunctions     ; Point to list of valid
                                                  ; functions
                mov     cx, NUM_FUNCTIONS   ; Init loop counter

        repne   scasb                       ; Is function supported ?
                pop     es                  ; Restore segment register
        assume  es:Nothing

                MOV     (ARGS PTR [BP]).AHReg, BAD_FUNCTION ; Default to bad
                                                            ; function

                jnz     short @f                ; No, exit now

                sub     di, offset bFunctions   ; Yes, compute table index
                dec     di

                mov     si, di                  ; Setup [SI] as index
                mov     di, (ARGS PTR [BP]).DIReg ; and restore [DI]

                CALL    ValidateArgs            ; Are arguments valid ?
                jc      short @f                ; No, we're done

                shl     si, 1                   ; Create word index
                call    pFunctions[SI]          ; Yes, go do requested function

                mov     (ARGS PTR [BP]).AHReg, ah       ; Save return code

@@:             add     sp, DYN_SIZE

;----------------------------- Exit from interface ----------------------------

                dec     bEntryCnt
                popx    <bp, es, ds, di, si, dx, cx, bx, ax>
        assume  es:Nothing
Common16Exit:   pop     ds
        assume  ds:Nothing
Common16End:    ret

codCommon16     ENDP

;*****************************************************************************
;*                           --- codRM_Entry ---
;*
;*     Purpose: 16:16 mode entry point
;*       Input: As specified by PCMCIA
;*      Output: As specified by PCMCIA
;* Scratch reg: As specified by PCMCIA
;*     Written: by Alexis A.Piatetsky 28.07.94
;*****************************************************************************
codRM_Entry     PROC    FAR
                assumes ds, Nothing
                assumes es, Nothing
                assumes ss, Nothing

                cmp     ah, GET_ADP_CNT         ; Socket Services function
                                                ; request?
                jb      short SSDBadFunction    ; No, return BadFunction Error

                cmp     ah, CARD_SERVICES       ; Maybe, Function within range ?
                jb      short @f                ; Yes, go check adapter

SSDBadFunction: mov     ah, BAD_FUNCTION
                jmp     short RM_Exit           ; No, Indicate     Function,
                                                ; Exit
@@:             call    codCommon16

RM_Exit:        cmp     ah,1
                cmc
                retf
codRM_Entry     ENDP

sEnd            ResCode

                END
