Skip to contentSkip to conversation

DOS2linux

DISCUSSION Bart Vandewoestyne 6 participants 11 messages Aug 27, 2001 – Aug 28, 2001

lore
Share & tools
lore
#0 lore raw

I have a routine from a DOS driver that looks like this:

static int getslotinfo( void )
{
static char buff[320], *s=&buff[0]; int valid;

inregs.h.ah=0xd8; inregs.h.al=0x1; inregs.h.cl=DiSC_Id.slot>>12;
inregs.h.ch=0;
sregs.ds=FP_SEG(s); inregs.x.si=FP_OFF(s); int86x(0x15, &inregs, &outregs, &sregs); valid=outregs.h.ah;
if(!valid) { DiSC_Id.it=buff[itconf]; DiSC_Id.dma=buff[dmachd]; } return(valid);
}

(full DOS-code is at http://mc303.ulyssis.org/heim/downloads/DISCDRV.C
)

Doing some research learned me that this piece of code does the following things (according to http://www.ctyme.com/intr/rb-1641.htm
):

1) set AX register to 0xd800
2) set slot number to DiSC_Id.slot, (eg. 1 in my case -> base is 0x1000)
3) set function number to read
4) assign a 320-byte buffer for standard configuration data block
5) execute a software interrupt via the DOS specific int86x function, this puts configuration data into the 320-byte buffer.
6) check if we get a valid return
7) if we have a valid situation, assign values from the configuration block to DiSC_Id.it (it level) and DiSC_Id.dma (dma level)

So here's my question:

On http://www.ctyme.com/intr/rb-1641.htm I can see that this is all about reading data from an EISA SYSTEM ROM. I can't imagine there doesn't exist some linux-API that allows me to do just the same.

What function calls and header files should I use in order to read this 'EISA SYSTEM ROM' and assign the correct values to DiSC_Id.it and DiSC_Id.dma ?

If there doesn't exist an API for this, what memory ranges should i probe in order to get these values?

Thanks for answers,
mc303

Signature · 5 lines
Ing. Bart Vandewoestyne			 [email protected]
Hugo Verrieststraat 48			       GSM: +32 (0)478 397 697
B-8550 Zwevegem			 http://users.pandora.be/vandewoestyne
----------------------------------------------------------------------
"Any fool can know, the point is to understand." - Albert Einstein
#1 lore raw
Quoted 10 lines

1) set AX register to 0xd800
2) set slot number to DiSC_Id.slot, (eg. 1 in my case -> base is 0x1000)
3) set function number to read
4) assign a 320-byte buffer for standard configuration data block
5) execute a software interrupt via the DOS specific int86x function, this puts configuration data into the 320-byte buffer.
6) check if we get a valid return
7) if we have a valid situation, assign values from the configuration block to DiSC_Id.it (it level) and DiSC_Id.dma (dma level)

Oh god, thats the deep magic EISA weirdness department

Quoted 3 lines

On http://www.ctyme.com/intr/rb-1641.htm I can see that this is all about reading data from an EISA SYSTEM ROM. I can't imagine there doesn't exist some linux-API that allows me to do just the same.

Well actually its one of those things that needs writing cleanly but currently appears in its own form in some EISA drivers

EISA slots are I/O mapped at 0x1000, 0x2000, 0x3000, 0x4000 -> 0x8000 The ID port is at base+0xc80
Configuration data follows at base+0xc84, 0xc88 ...

I would assume the 320 byte buffer is providing this same data block, and maybe more but I don't know the details. I thought EISA boards had gone away

Alan

#2 lore raw
Quoted 2 lines · Alan Cox

Oh god, thats the deep magic EISA weirdness department

*gnarf* ;-) Not good for a beginner like me I assume? :-(

Quoted 2 lines

Well actually its one of those things that needs writing cleanly but currently appears in its own form in some EISA drivers

Hmm... with 'writing cleanly' you mean that there should become things available like eisa_register_device() etc...?

Quoted 3 lines

EISA slots are I/O mapped at 0x1000, 0x2000, 0x3000, 0x4000 -> 0x8000 The ID port is at base+0xc80
Configuration data follows at base+0xc84, 0xc88 ...

Yep, that was also what I figured out.

Quoted 2 lines

I would assume the 320 byte buffer is providing this same data block, and maybe more but I don't know the details.

That is also what I think, but the problem is that I don't know at which offset to look for that data...
If you look at the code:

static int getslotinfo( void )
{
static char buff[320], *s=&buff[0]; int valid;

inregs.h.ah=0xd8; inregs.h.al=0x1; inregs.h.cl=DiSC_Id.slot>>12;
inregs.h.ch=0;
sregs.ds=FP_SEG(s); inregs.x.si=FP_OFF(s); int86x(0x15, &inregs, &outregs, &sregs); valid=outregs.h.ah;
if(!valid) { DiSC_Id.it=buff[itconf]; DiSC_Id.dma=buff[dmachd]; } return(valid);
}

Would it help if i told you that itconf and dmachd are defined as (see
http://mc303.ulyssis.org/heim/downloads/DISCINC.H )

#define itconf 0xb2
#define dmachd 0xc0

So if my EISA board is at 0x1000, i should be able to read these values from 0x1000+0xb2 and 0x1000+0xc0 ??? And if 'yes', any idea about how to read them? (byte, word, long...? My guess would be as a byte, but I'm not sure...)

Quoted 1 line

I thought EISA boards had gone away

Unfortunately... the device I am trying to write a driver for is especially designed for our university. Not many of those boards exist in the world I guess :-(
(I hope that last sentence didn't take away your interest in my project ;-)

Greetzzz,
mc303

Signature · 5 lines
Ing. Bart Vandewoestyne			 [email protected]
Hugo Verrieststraat 48			       GSM: +32 (0)478 397 697
B-8550 Zwevegem			 http://users.pandora.be/vandewoestyne
----------------------------------------------------------------------
"Any fool can know, the point is to understand." - Albert Einstein
#3 lore raw
Quoted 2 lines

Hmm... with 'writing cleanly' you mean that there should become things available like eisa_register_device() etc...?

Yeah

Quoted 16 lines
Quoted 3 lines

EISA slots are I/O mapped at 0x1000, 0x2000, 0x3000, 0x4000 -> 0x8000 The ID port is at base+0xc80
Configuration data follows at base+0xc84, 0xc88 ...

Yep, that was also what I figured out.

Quoted 2 lines

I would assume the 320 byte buffer is providing this same data block, and maybe more but I don't know the details.

That is also what I think, but the problem is that I don't know at which offset to look for that data...
If you look at the code:

Would it help if i told you that itconf and dmachd are defined as (see
http://mc303.ulyssis.org/heim/downloads/DISCINC.H )

Quoted 8 lines

#define itconf 0xb2
#define dmachd 0xc0

So if my EISA board is at 0x1000, i should be able to read these values from 0x1000+0xb2 and 0x1000+0xc0 ??? And if 'yes', any idea about how to read them? (byte, word, long...? My guess would be as a byte, but I'm not sure...)

Wild guess. Try iobase + 0xC80 to check if the card is in that slot, then check inb(iobase+0xC80+0xb2) and see if that gives sane answers

#4 lore raw
In reply to Bart Vandewoestyne
Quoted 20 lines · Bart Vandewoesteyne

That is also what I think, but the problem is that I don't know at which offset to look for that data...
If you look at the code:

static int getslotinfo( void )
{
static char buff[320], *s=&buff[0]; int valid;

inregs.h.ah=0xd8; inregs.h.al=0x1; inregs.h.cl=DiSC_Id.slot>>12;
inregs.h.ch=0;
sregs.ds=FP_SEG(s); inregs.x.si=FP_OFF(s); int86x(0x15, &inregs, &outregs, &sregs); valid=outregs.h.ah;
if(!valid) { DiSC_Id.it=buff[itconf]; DiSC_Id.dma=buff[dmachd]; } return(valid);
}

Would it help if i told you that itconf and dmachd are defined as (see
http://mc303.ulyssis.org/heim/downloads/DISCINC.H )

Quoted 7 lines

#define itconf 0xb2
#define dmachd 0xc0

So if my EISA board is at 0x1000, i should be able to read these values from 0x1000+0xb2 and 0x1000+0xc0 ??? And if 'yes', any idea about how to read them? (byte, word, long...? My guess would be as a byte, but I'm not sure...)

Looking at the above piece of sourcecode, I would say your guess is correct. "buff" is declared as an array of chars (bytes), so I would try to read a byte at 0x10b2 and at 0x10c0. Just try it out & see what you get back...

Camiel.

#5 lore raw
Quoted 25 lines · Camiel Vanderhoeven
Quoted 17 lines

static int getslotinfo( void )
{
static char buff[320], *s=&buff[0]; int valid;

inregs.h.ah=0xd8; inregs.h.al=0x1; inregs.h.cl=DiSC_Id.slot>>12;
inregs.h.ch=0;
sregs.ds=FP_SEG(s); inregs.x.si=FP_OFF(s); int86x(0x15, &inregs, &outregs, &sregs); valid=outregs.h.ah;
if(!valid) { DiSC_Id.it=buff[itconf]; DiSC_Id.dma=buff[dmachd]; } return(valid);
}

Would it help if i told you that itconf and dmachd are defined as (see
http://mc303.ulyssis.org/heim/downloads/DISCINC.H )

Quoted 7 lines

#define itconf 0xb2
#define dmachd 0xc0

So if my EISA board is at 0x1000, i should be able to read these values from 0x1000+0xb2 and 0x1000+0xc0 ??? And if 'yes', any idea about how to read them? (byte, word, long...? My guess would be as a byte, but I'm not sure...)

Quoted 4 lines

Looking at the above piece of sourcecode, I would say your guess is correct. "buff" is declared as an array of chars (bytes), so I would try to read a byte at 0x10b2 and at 0x10c0. Just try it out & see what you get back...

I tried reading bytes from the following locations:

0x1000+0xb2 -> gives me 255
0x1000+0xc80+0xb2 -> gives me 255
0x1000+0xc84+0xb2 -> gives me 255

same for 0xc0

I guess these aren't the values I should be expecting... :-(

Greetzzz,
mc303

Signature · 5 lines
Ing. Bart Vandewoestyne			 [email protected]
Hugo Verrieststraat 48			       GSM: +32 (0)478 397 697
B-8550 Zwevegem			 http://users.pandora.be/vandewoestyne
----------------------------------------------------------------------
"Any fool can know, the point is to understand." - Albert Einstein
#6 lore raw
Quoted 10 lines · Bart Vandewoestyne

I tried reading bytes from the following locations:

0x1000+0xb2 -> gives me 255
0x1000+0xc80+0xb2 -> gives me 255
0x1000+0xc84+0xb2 -> gives me 255

same for 0xc0

I guess these aren't the values I should be expecting... :-(

Did you do a normal read from memory, or did you use port-i/o? I think you should use the latter. Of course, your card could be at 2000h in stead of 1000h, or at X000h for that matter. I'm not very familiar with the EISA architecture, but I do know that each card can use the following I/O ranges:
X000h-X0FFh; X400h-X4FFh; X800h-X8FFh; XC00-XCFF, where X is the slot number. There is a book on the EISA architecture available free of charge as a PDF file from www.mindshare.com/pdf/eisabook.pdf. Perhaps you'll find what you need to know from studying that. I hope this helps.

Veel success ermee,

Camiel.

#7 lore raw
Quoted 2 lines · Camiel Vanderhoeven

Did you do a normal read from memory, or did you use port-i/o?

I used the inb() function.

Quoted 2 lines

you should use the latter. Of course, your card could be at 2000h in stead of 1000h, or at X000h for that matter.

My card is at 1000h, that's something i know for sure, because I can probe the EISA ID at 0x1000+0xc80.

Quoted 5 lines

I'm not very familiar with
the EISA architecture, but I do know that each card can use the following I/O ranges:
X000h-X0FFh; X400h-X4FFh; X800h-X8FFh; XC00-XCFF, where X is the slot number.

I guess you mean X0000h-X0FFF; X1000-X1FFF; ...

Quoted 3 lines

There is a book on the EISA architecture available free of charge as a PDF file from www.mindshare.com/pdf/eisabook.pdf. Perhaps you'll find what you need to know from studying that. I hope this helps.

Tnx for the tip! I will check it out!

I also found this URL: http://uw7doc.sco.com/cgi-bin/man/man?eisa+D4

It comes from UnixWare 7 documentation and there they have the kind of translation that I want to do (that is: translate INT 15h call "Read Function" (AH=D8h, AL=01h)) to linux. As i understood there isn't such thing available for linux? Meaning I'll have to try and implement that stuff myself? But then the problem remains: how do i get to the data that is in the 320 byte buffer returned from an INT 15h call "Read Function" (AH=D8h, AL=01h)

Greetzzz,
mc303

Signature · 5 lines
Ing. Bart Vandewoestyne			 [email protected]
Hugo Verrieststraat 48			       GSM: +32 (0)478 397 697
B-8550 Zwevegem			 http://users.pandora.be/vandewoestyne
----------------------------------------------------------------------
"Any fool can know, the point is to understand." - Albert Einstein
#8 lore raw
In reply to Camiel Vanderhoeven
Quoted 9 lines · Bart Vandewoestyne

I also found this URL: http://uw7doc.sco.com/cgi-bin/man/man?eisa+D4

It comes from UnixWare 7 documentation and there they have the kind of translation that I want to do (that is: translate INT 15h call "Read Function" (AH=D8h, AL=01h)) to linux. As i understood there isn't such thing available for linux? Meaning I'll have to try and implement that stuff myself? But then the problem remains: how do i get to the data that is in the 320 byte buffer returned from an INT 15h call "Read Function" (AH=D8h, AL=01h)

Basically, nobody ever implemented an EISA bus layer because it is rare to see EISA hardware anymore. The few EISA aware drivers in Linux handle configuration themselves. I had thought about doing it at one time for the sake of completeness, but I don't have access to any EISA hardware to test.

--

Brian Gerst

#9 lore raw
In reply to Alan Cox
Quoted 3 lines · Alan Cox

I would assume the 320 byte buffer is providing this same data block, and maybe more but I don't know the details. I thought EISA boards had gone away

oh come on alan, you know full well nothing ever goes away :) eisa should, by all means (as should mca) but as long as the boards and machines still exist you can expect them to rear their ugly heads and bite, especially when you least expect it.

eisa is evil!

Kelsey Hudson [email protected]
Software Engineer
Compendium Technologies, Inc (619) 725-0771
---------------------------------------------------------------------------

#10 lore raw
In reply to Bart Vandewoestyne
Quoted 16 lines · Bart Vandewoestyne

I have a routine from a DOS driver that looks like this:

static int getslotinfo( void )
{
static char buff[320], *s=&buff[0]; int valid;

inregs.h.ah=0xd8; inregs.h.al=0x1; inregs.h.cl=DiSC_Id.slot>>12;
inregs.h.ch=0;
sregs.ds=FP_SEG(s); inregs.x.si=FP_OFF(s); int86x(0x15, &inregs, &outregs, &sregs); valid=outregs.h.ah;
if(!valid) { DiSC_Id.it=buff[itconf]; DiSC_Id.dma=buff[dmachd]; } return(valid);
}

Quoted 8 lines

(full DOS-code is at http://mc303.ulyssis.org/heim/downloads/DISCDRV.C
)

Doing some research learned me that this piece of code does the following things (according to http://www.ctyme.com/intr/rb-1641.htm
):

1) set AX register to 0xd800

                        ^^^^^^ actually to 0xd801
Quoted 10 lines

2) set slot number to DiSC_Id.slot, (eg. 1 in my case -> base is 0x1000)
3) set function number to read
4) assign a 320-byte buffer for standard configuration data block
5) execute a software interrupt via the DOS specific int86x function, this puts configuration data into the 320-byte buffer.
6) check if we get a valid return
7) if we have a valid situation, assign values from the configuration block to DiSC_Id.it (it level) and DiSC_Id.dma (dma level)

Quoted 5 lines

So here's my question:

On http://www.ctyme.com/intr/rb-1641.htm I can see that this is all about reading data from an EISA SYSTEM ROM. I can't imagine there doesn't exist some linux-API that allows me to do just the same.

I don't have any direct EISA experience on Linux, but the Linux Device Drivers book (remember that one?) says:

"EISA devices are configured by software, but they don't need any particular operating system
support. EISA drivers already exist in the Linux kernel for Ethernet devices and SCSI controllers."

and

"As far as the driver is concerned, there is no special support for EISA in the kernel, and the
programmer must deal with ISA extensions by himself. The driver uses standard EISA I/O
operations to access the EISA registers. The drivers that are already in the kernel can be used as
sample code."

See (and read) http://www.xml.com/ldd/chapter/book/ch15.html
and some drivers that already do this.

Quoted 6 lines

What function calls and header files should I use in order to read this 'EISA SYSTEM ROM' and assign the correct values to DiSC_Id.it and DiSC_Id.dma ?

If there doesn't exist an API for this, what memory ranges should i probe in order to get these values?

~Randy