DOS2linux
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
Quoted 10 lines
1) set AX register to
0xd800
2) set slot number to DiSC_Id.slot, (eg. 1 in my case -> base is0x1000)
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
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->0x8000The ID port is atbase+0xc80
Configuration data follows atbase+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
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->0x8000The ID port is atbase+0xc80
Configuration data follows atbase+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 dmachd0xc0So 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
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 dmachd0xc0So 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.
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 dmachd0xc0So 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
0x10b2and at0x10c0. 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
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 255same for
0xc0I 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.
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
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
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
---------------------------------------------------------------------------
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