www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1995/02/02/10:59:49

Via: uk.ac.ulcc.vmsfe; Thu, 2 Feb 1995 11:18:32 +0000
Date: Thu, 2 Feb 95 11:18 GMT
From: "Kevin Ashley, Systems Development, ULCC" <CZIWKGA AT VMSFE DOT ULCC DOT AC DOT UK>
To: DJGPP <DJGPP AT SUN DOT SOE DOT CLARKSON DOT EDU>
Subject: Request for advice with djgpp, ASPI manager and them _go32_dpmi*
functions

Greetings, djgpp-ers. I'm try to port a program written in Microsoft
C which communicates with the Adaptec SCSI Aspi Manager driver. (Well,
it's more complex than that ; it was actually a Unix program ported to
Microsoft C, but that's not relevant right now...)

I'm basically a Unix/VMS systems hacker and am not at all familiar with
using traditional DOS system calls via compilers such as Microsoft C,
which I don't have access to, and I haven't yet found a good reference
to explain it all. I've found the docs on using the intxxx and
_go32_dpmi_* functions difficult to grapple with, since they reasonable
assume that one already knows how to program in the traditional DOS
fashion and mainly just explain the differences introduced by the
djgpp 32-bit environment. I've been happily using djgpp for 18 months
for other programs which don't need to interact so closely with DOS.

I'm hoping someone can shed some advice which might get me started and then
hopefully I can make more progress on my own.

I have a code fragment from the original program like this:
*******************

/*
 * This will be the function for all aspi requests, it gets
 * initialized at aspiinit() and called from aspirequest()
 */

void (far *aspi)(void far *) = (void far *) 0;


void aspiinit()
{
  int h,i;
  long l;
  union REGS inregs;
  union REGS outregs;
  char *getenv(), *tapeid;

  if ( (h=open("SCSIMGR$",0)) == -1 )  {
    perror("Opening ASPI Manager");
    exit(1);
  }

/*
 * This is an ioctl(READ) to the "SCSIMGR$".
 * It returns the entrypoint of the aspi-module (far pointer)
 * in the 4 bytes, pointed to by the dx register.
 */

  inregs.x.ax = 0x4402;
  inregs.x.dx = ( int ) &aspi;
  inregs.x.cx = 4;
  inregs.x.bx = h;
  intdos(&inregs, &outregs);
************
The intent of this as far as I can see is to get an address, which I guess
is real-mode, and which is later used to despatch all requests to the manager.
I tried simply using the djgpp intdos(), which I didn't expect to work
as I realise it only does for interrupts which go32 knows about. I then
tried the following:
*************
void ( *aspi)(void  *) = (void  *) 0;

void aspiinit()
{
  int h,i;
  long l;
#ifdef __GO32__
#include <dpmi.h>
_go32_dpmi_registers inregs;
_go32_dpmi_seginfo dosmem1,dosmem2;
#else
  union REGS inregs;
  union REGS outregs;
#endif
 char *getenv(), *tapeid;

  if ( (h=open("SCSIMGR$",0)) == -1 )  {
    perror("Opening ASPI Manager");
    exit(1);
  }

/*
 * This is an ioctl(READ) to the "SCSIMGR$".
 * It returns the entrypoint of the aspi-module (far pointer)
 * in the 4 bytes, pointed to by the dx register.
 */

  inregs.x.ax = 0x4402;
  inregs.x.cx = 4;
  inregs.x.bx = h;
#ifdef __GO32__
  dosmem1.size = 1;
  inregs.x.ss = inregs.x.sp = inregs.x.flags = 0;
  if(_go32_dpmi_allocate_dos_memory(&dosmem1)) {  
	printf("Unable to allocate DOS memory\n");
	exit(1);
  }
  printf("Alloc DOS mem returns RS: %x RO: %x size: %d\n",
	dosmem1.rm_segment,dosmem1.rm_offset,dosmem1.size);
  inregs.x.dx = dosmem1.rm_segment*16;
  i = dosmem1.rm_segment*16;
  
  dosmemget(dosmem1.rm_segment*16,sizeof(int),&aspi);
  printf("Aspi entry before int is %x\n",(int) aspi);
  i = _go32_dpmi_simulate_int(0x21,&inregs);
  printf("File was %d, int returns %d\n",h,i);
  dosmemget(dosmem1.rm_segment*16,sizeof(int),&aspi);
  _go32_dpmi_free_dos_memory(&dosmem1);
  printf("Aspi entry is %x\n",(int) aspi);
  exit(1);
**********

I'm unsure in this case what I should be putting in inregs.x.dx. It should
be the address of a location in which to place the ASPI entry point. As
you can see, I have allocated one 16-byte block with dosmemget to receive
this, but I can't understand from the docs what the real-mode address
of this is. Is it dosmem.rm_segment or dosmem.rm_segment*16+dosmem.rm_offset
or what ? In any event, the code above doesn't return an error, but the
dosmemget shows that the address I've pointed to doesn't change after the
call. I simply don't know enough about 80x86 real-mode addressing to
fathom how an address is constructed from segment/offset pairs. I presume
the segment is the number of a 64 Kbyte block, and the offset a
16-bit address within that block, since the real-mode addressing seems
to be all done with 16-bit values.

Assuming someone can get me past this, I then need to work out
how to dispatch things via the pointer returned. I presume that
_go32_dpmi_simulate_fcall is what I want. The rest of the program
builds up command request blocks using code similar to that below:

*****************
/*
 * GetDeviceTyp: The returned typ corresponds to the typ of an
 *               SCSI-Inquiry command.
 */

int GetDeviceTyp(adapter, target_id, lun)
int adapter;
int target_id;
int lun;
{
  struct _srbgettyp *srb;
  int i;

  /* allocate a SCSI Request Block (SRB) */

  if ( (srb=calloc(sizeof( struct _srbgettyp), 1)) == 0 ) return(E$NoMem);

  srb->h.cmd = 1;
  srb->h.adapter = adapter;
  srb->target_id = target_id;
  srb->lun = lun;

  /* Issue the request */
  if ( (i=aspireq(srb)) ) {
*************

***********
and the function aspireq() does the following:

int aspireq(srb)
void *srb;
{
  int cnt;

  struct _srbinquiry *s;
  s = ( struct _srbinquiry *) srb;
  aspi(s);
  cnt = 10;
  while ( cnt-- ) while ( ! s->h.status )  ;   /* POLL ! */
  if ( s->h.status == 1 ) return E$NoErr;
  return E$AspiErr;
}
**********

I presume that I need to allocate these structures in low memory
with dosmemget, fill them in with copies of the structures I have,
and use _go32_dpmi_simulate_fcall to dispatch the aspi() function. Am
I right ? And, when these structures themselves contain the addresses
of buffers to read and/or write from, what sort of address do I put there?

Thanks to anyone who has taken the time to read through this and can
offer any advice.

Kevin Ashley
------------------------------------------------------------------------------
Kevin Ashley                              K DOT Ashley AT Ulcc DOT ac DOT uk
Systems Development Group Manager      http://www.ulcc.ac.uk/staff/Kevin+Ashley
University of London Computer Centre.      ...ukc!ncdlab!K.Ashley
                      This is not a signature

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019