nick@motto.UUCP (Nick Woodbridge) (01/06/89)
*** Dual Ported Memory Device Drivers **** I want to run a synchronous I/O board under OS/2,and the board uses a dual-ported memory window configurable from 0 to 960K to communicate with the main processor. Does anyone have any experience of writing OS/2 device drivers to handle this type of peripheral board? If so can you provide any software? The board in question is the Emulex DCP-88/VM board with four synchronous ports. I would also like to hear from anyone who knows of other multi-port RS-232C synchronous AT compatible boards that are available. Our application is to run the HDLC protocol on the link.So in addition to all the above,does anyone know of OS/2 software packages to handle HDLC? Nicholas Woodbridge Motorola Canada, Ltd. 416-499-1441 ext. 3161 uunet!mnetor!motto!nick
wei@hpctdls.HP.COM (Bill Ives) (01/10/89)
I have had experience writting such a driver for OS/2 to communicate with another processor accross a dual-port memory area. Unfortunately I cannot give the code due to its propriatary nature, but I can give you some hints to make it easier for you to develop your own code. First, this type of DD is the easiest since its not interrupt driven -- thus I was able to ignor all device help routines associated with request packets. Some initial requirements: To make OS/2 ignor your segment of shared memory at boot time it must be non-contiguous with the rest of memory -- it can still use partial address decoding though. Your device driver must be included in a device statement in config.os2 file. Within you device driver, you should define it as a character device not a block device -- this make everything else easier. The device strategy routine should only have to route the open, close , and devIOCTL calls. The open and close correspond to DosOpen and DosClose calls respectively. The devIOCTL cooresponds to DosDevIOCTL call, which takes at most two 32bit parameters which your routines can define. Normally, these can be pointers to parameter buffers. With the DD, only keep physical addresses - as these must be converted to valid descriptors each time your called and freed afterward -- see documentation on devHelp routines PhysToVirt and VirtToPhys to do this. Since your writing a shared memory driver the device initialization routine can use your physical address to obtain a virtual address -- and then it can initialize it appropriately. Remember, if there is any chance for contention in the shared memory you should set up a ram semaphore located within the shared memory (so that the other side can access it.). This last point is a matter of how you set up the protocol. Whenever your strategy routine encounters the devIOCTL call ( presumably to do reads/writes to the memory ) you should validate the virtual addresses passed to you from the caller with VerifyAccess devHlp routine -- this will help with those general protection faults. The last area of concern is that of the return code passed back in AX when exiting the DD. You should return device failure 0CH for any errors and an Okay return code otherwise. Some sample code is shown below: ; To assemble and create SYS file do: ; MASM SHAREMEM ; LINK SHAREMEM,SHAREMEM.SYS,,DOSCALLS,SHAREMEM; maxcmd equ 25 ; max allowed command code. DGROUP group _DATA _DATA segment word public 'DATA' header dd -1 ; DD link to next DD dd 88C0h ; device attr word dd Strat ; strategy routine entry point dw 0 ; reserved db 'SMEM0000' ; logical device name db 8 dub (0) ; reserved devhlp dd ? ; DevHlp entry point ; Strategy routine dispatch table for ; request packet command code. dispch dw Init ; 0 = init driver dw Ignor; 1 media check ... etc .... dw DevOpen ; 13 = device open dw DevClose; 14 = device close ... etc ... dw GenIOCTL ; 16 = generic ICTL ... etc ... dw Error ; 26 = not used .. other global data goes here.. _DATA ends ; macros and stuff goes here.... _TEXT segment word public 'CODE' assume cs:_TEXT,ds:DGROUP,es:NOTHING Strat proc far ; dd strategy routin called by os/2 kernel ; es:bx = addr of request packet. mov di,es:[bx+2] ; get cmd code and di,0ffh cmp di,maxcmd ; supported by this driver jle strat1 ; jump if okay call Error jmp strat2 strat1: add di,di ; cmd code * 2 call word ptr [di+dispch] ; branch to routine strat2: mov es:[bx+3],ax ; ax into request packet retcode field ret Strat endp ; retcodes 0100h if done with no error ; 0000h if thread should be blocked pending interrupt ; 81xxh if done and error detected ( xx=error code ) DevOpen proc near ; function 13 = device open .. do open of shared memory.. i.e. initialization etc. DevOpen endp DevClose proc near DevClose endp GenIOCTL proc near push es push bx ... get user specified params and read/write shared memory appropriately. on error mov ax,810ch on okay mov ax,0100h pop bx pop es ret GenIOCTL endp Error proc near ; bad cmd code mov ax,8103h ; unknown command error. ret Error endp Init proc near .... do initialization of device and shrink the SYS image down by writing the end of the code and data segs into the request packet like: mov word ptr es:[bx+14],offset _TEXT:Init mov word ptr es:[bx+16] offset DGROUP:thelastdiscardablevarindataseg .... ret Init endp _TEXT ends end