lkml.org 
[lkml]   [2001]   [Aug]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectEISA irq probing problem (ESIC chip)
I am trying to write a linux driver for an EISA data aquisition card. 
More info on my little special project is at
http://mc303.ulyssis.org/heim/

I am able to probe for the EISA ID, but i can't get the irq level from
the card... this is how I *think* it is done, please correct me if
possible...

I have been grepping all over the kernel source to find EISA drivers,
and i came along /usr/src/linux/drivers/net/defxx.c... When I looked
at the header file, I saw that under the section "/* Define EISA
controller register offsets */" all the registers (the ones with ESIC
in the define string) seemed to match with the registers I have on my
EISA controller (HD64981F EISA Slave Interface Controller, ESIC ->
found nothing on the web), and also the defxx.c driver supports FDDI,
and my card also has a connector for an optical cable, so i guess we
are talking about the same controller here....

Then I looked at how the defxx.c driver gets the interrupt level from
the ESIC chip (see source) and I decided to try and do it the same
way, like this:

...
#define DISC_ESIC_K_FUNCTION_CNTRL 0xCAE
#define DISC_ESIC_K_CSR_IO_LEN
DISC_ESIC_K_FUNCTION_CNTRL+1 /* alwa
ys last reg + 1 */
...
#define DISC_CONFIG_STAT_0_M_IRQ 0x03
#define DISC_CONFIG_STAT_0_V_IRQ 0
...
#define DISC_CONFIG_STAT_0_IRQ_K_4 0
#define DISC_CONFIG_STAT_0_IRQ_K_5 1
#define DISC_CONFIG_STAT_0_IRQ_K_6 2
#define DISC_CONFIG_STAT_0_IRQ_K_7 3

...

static int getslotinfo(void)
{
u8 val;

if (!request_region(0x1000, DISC_ESIC_K_CSR_IO_LEN, "disc")) {
printk(KERN_ERR "disc.c: Cannot reserve I/O
resource!\n");
return -EBUSY;
}

val = inb(0x1000+0xCA9);
printk
switch ((val & DISC_CONFIG_STAT_0_M_IRQ) >>
DISC_CONFIG_STAT_0_V_IRQ)
{
case DISC_CONFIG_STAT_0_IRQ_K_4:
DiSC_Id.it = 4;
break;

case DISC_CONFIG_STAT_0_IRQ_K_5:
DiSC_Id.it = 5;
break;

case DISC_CONFIG_STAT_0_IRQ_K_6:
DiSC_Id.it = 6;
break;

case DISC_CONFIG_STAT_0_IRQ_K_7:
DiSC_Id.it = 7;
break;

default:
printk(KERN_WARNING "disc: found no matching
IRQ!\n");
return 1;
}
printk(KERN_WARNING "disc: DiSC_Id.it=%d\n", DiSC_Id.it);
release_region(0x1000, DISC_ESIC_K_CSR_IO_LEN);

return 0;
}

I know my EISA card is at the first slot (0x1000). The register that
is defined at offset 0xCA9 has the following bits:

Bit 7:
0: No interrupt pending from LIREQ0
1: Interrupt pending from LIREQ0
( Bit 7 is automatically cleared after the register is read if LIREQ0
is set to edge-triggered input (bit 4 is set to 1).

Bit 6: reserved

Bit 5:
0: Corresponding IRQx is level-sensitive input
1: Corresponding IRQx is edge-triggered output

Bit 4:
0: LIREQ0 is level-sensitive input
1: LIREQ0 is edge-triggered input

Bit 3:
0: Disable interrupt request LIREQ0
1: Enable interrupt request LIREQ0

Bit 2: reserved

Bit 1 and Bit 0:
00: LIREQ0 is assigned to IRQ0
01: LIREQ0 is assigned to IRQ1
10: LIREQ0 is assigned to IRQ2
11: LIREQ0 is assigned to IRQ3


So if i understand my code, what is it doing is that is first masks
with the mask for interrupts to get only the last two bits, then it
shifts 0 bits to the right so we can read the interrupt as a number
and then depending on the number we read, it checks which IRQ level is
stored on the card.

And here is where the problem comes up!!!!!!!!!!!!!!!!!!!

With the DOS utility, called "ECU" (EISA Configuration Utility), I can
assign the card to IRQ 4, 5, 6 or 7. So i guess 4 maps to 00, 5 to
01, 6 to 10 and 7 to 11.
Then I set the card up for -let say for example- IRQ 4 with the ECU.
Then I boot a dos program (see URL in the beginning of this mail) that
uses the card and where I put some printf's just to be able to see
what interrupt level it is reading (the DiSC_ID.it value in the
getslotinfo() function), i can see that it indeed is using irq 4. (The
dos program finds the it level by generating an INT15/D801H, see DOS
code on page)

The problem is... when i try the same thing with my above linux code
(not on the site yet, site contains older version!) i do not get the
correct irq... seems like the values at 0x1CA9 never have changed, no
matter what IRQ i set up with the ECU utility (although i *KNOW* it
has changed because the DOS program tells me so...)

Am I forgetting something here? I already tried with or without the
request_region function call, I inspected the io range with hexdump
and it seems like the values at 0x1caeh remain the same???? How is
this possible??? They should've been changed because I used the ECU
to change them???

There is also a second Interrupt Channel Configuration and Status
Register at offset xCAAH, the bits are exactly the same but instead of
LIREQ0 it is for LIREQ1. I also tried all the above with this offset,
without result...

I went through the defxx.c code but I can't see what it is doing more
than my code :-(

What could i possibly doing wrong here???


Regards,
Bart Vandewoestyne

--
Ing. Bart Vandewoestyne Bart.Vandewoestyne@pandora.be
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
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

\
 
 \ /
  Last update: 2005-03-22 13:01    [W:0.047 / U:0.328 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site