PCI driver

I have had to convert an existing QNX 4.25 system from an ISA board to a PCI
motherboard board. I am trying to development a driver for a Keithley A/D
board. VendorID and DeviceID are known and using the QNX function
_CA_PCI_Read_Config_DWord I have determined the base address from the
configuration space to be 0xe700 from the General Control Register 0.
Knowing this what procedure do I use (QNX functions) to read and write to
the PCI memory space? How does one set the offset from the base address?
Does one have to create a new device to read and write?

I would really appreciate some guidance if possible

John E. Kaye

“John Kaye” <jekaye@total.net> wrote in message
news:bij932$tr$1@inn.qnx.com

I have had to convert an existing QNX 4.25 system from an ISA board to a
PCI
motherboard board. I am trying to development a driver for a Keithley A/D
board. VendorID and DeviceID are known and using the QNX function
_CA_PCI_Read_Config_DWord I have determined the base address from the
configuration space to be 0xe700 from the General Control Register 0.

Knowing this what procedure do I use (QNX functions) to read and write to
the PCI memory space?

Read the documentation on _CA set of function. In one of the function
(don’t remember which one) there is an example how to do this. It involves
using mmap.

0xe700 is a very odd address for PCI memory (as 0xe700 is more of an ISA
address). Are you sure this is not IO based instead of memory based.

How does one set the offset from the base address?
Does one have to create a new device to read and write?

No the mecanism is the same whether the card is ISA or PCI it’s just how you
obtain the address/memory type/ interupt that changes.

I would really appreciate some guidance if possible

John E. Kaye

Mario

Thanks for your response. I have read the documentation on the _CA_PCI
group. Using mmap maps the base address to 0xf000 ( from the 0xe700). I am
therefore confused about memory based and I/O based. The QNX example uses
the macro PCI_IS_MEM(address) to determine whether it is MEM or I/O. Can
you explain the difference?

Thanks

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bijtb9$dii$1@inn.qnx.com

“John Kaye” <> jekaye@total.net> > wrote in message
news:bij932$tr$> 1@inn.qnx.com> …
I have had to convert an existing QNX 4.25 system from an ISA board to a
PCI
motherboard board. I am trying to development a driver for a Keithley
A/D
board. VendorID and DeviceID are known and using the QNX function
_CA_PCI_Read_Config_DWord I have determined the base address from the
configuration space to be 0xe700 from the General Control Register 0.

Knowing this what procedure do I use (QNX functions) to read and write
to
the PCI memory space?

Read the documentation on _CA set of function. In one of the function
(don’t remember which one) there is an example how to do this. It
involves
using mmap.

0xe700 is a very odd address for PCI memory (as 0xe700 is more of an ISA
address). Are you sure this is not IO based instead of memory based.

How does one set the offset from the base address?
Does one have to create a new device to read and write?

No the mecanism is the same whether the card is ISA or PCI it’s just how
you
obtain the address/memory type/ interupt that changes.


I would really appreciate some guidance if possible

John E. Kaye
\

“John Kaye” <jekaye@total.net> wrote in message
news:bijvbt$f4j$1@inn.qnx.com

Mario

Thanks for your response. I have read the documentation on the _CA_PCI
group. Using mmap maps the base address to 0xf000 ( from the 0xe700). I
am
therefore confused about memory based and I/O based. The QNX example uses
the macro PCI_IS_MEM(address) to determine whether it is MEM or I/O. Can
you explain the difference?

Memory based is basicly what it says, it’s access just like RAM, with C
pointer.

IO based is accessed via inp() and outp() functions.

The reason for having two different type of access dates from prehistoric
ages :wink:

Thanks

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bijtb9$dii$> 1@inn.qnx.com> …

“John Kaye” <> jekaye@total.net> > wrote in message
news:bij932$tr$> 1@inn.qnx.com> …
I have had to convert an existing QNX 4.25 system from an ISA board to
a
PCI
motherboard board. I am trying to development a driver for a Keithley
A/D
board. VendorID and DeviceID are known and using the QNX function
_CA_PCI_Read_Config_DWord I have determined the base address from the
configuration space to be 0xe700 from the General Control Register 0.

Knowing this what procedure do I use (QNX functions) to read and write
to
the PCI memory space?

Read the documentation on _CA set of function. In one of the function
(don’t remember which one) there is an example how to do this. It
involves
using mmap.

0xe700 is a very odd address for PCI memory (as 0xe700 is more of an ISA
address). Are you sure this is not IO based instead of memory based.

How does one set the offset from the base address?
Does one have to create a new device to read and write?

No the mecanism is the same whether the card is ISA or PCI it’s just how
you
obtain the address/memory type/ interupt that changes.


I would really appreciate some guidance if possible

John E. Kaye


\

John Kaye wrote:

Mario

Thanks for explanation on mmap. On this whole issue of writing this driver
to replace an existing ISA board with PCI, the only book I found was one by
O’Reilly “Linux Device Drivers”. Reading several chapters it used kernel
calls, kernel space, etc and the major and minor numbers of the device.
Reviewing some demonstration code I found on the net for a Keithley card
using Linux it made it look very complicated!!
It appears much easier to write this device driver code using QNX…
especially using C pointers, etc. Why would one need kernel calls or need
to register the device? Any comments?

Writing drivers for QNX bears no resemblence to writing drivers for Linux. The
QNX O/S is what we like to refer to in “the business” as a coherent design :wink:

You are correct, writing drivers for QNX is much easier than it is for Linux.

Mario

Many thanks for your “pointing” me in the right direction. I got the
Keithley board to function correctly with C pointers to the mapped memory.
A/D, D/A and DIO all work. A last comment. You felt that the address of
0xe700 was not a PCI address. What range would you expect? The board
works but I don’t understand why it has to be mapped using the mmap
function. Can you briefly explain if you know.

Thanks again

JEK

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bik2iu$h4j$1@inn.qnx.com

“John Kaye” <> jekaye@total.net> > wrote in message
news:bijvbt$f4j$> 1@inn.qnx.com> …
Mario

Thanks for your response. I have read the documentation on the _CA_PCI
group. Using mmap maps the base address to 0xf000 ( from the 0xe700).
I
am
therefore confused about memory based and I/O based. The QNX example
uses
the macro PCI_IS_MEM(address) to determine whether it is MEM or I/O.
Can
you explain the difference?

Memory based is basicly what it says, it’s access just like RAM, with C
pointer.

IO based is accessed via inp() and outp() functions.

The reason for having two different type of access dates from prehistoric
ages > :wink:


Thanks

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bijtb9$dii$> 1@inn.qnx.com> …

“John Kaye” <> jekaye@total.net> > wrote in message
news:bij932$tr$> 1@inn.qnx.com> …
I have had to convert an existing QNX 4.25 system from an ISA board
to
a
PCI
motherboard board. I am trying to development a driver for a
Keithley
A/D
board. VendorID and DeviceID are known and using the QNX function
_CA_PCI_Read_Config_DWord I have determined the base address from
the
configuration space to be 0xe700 from the General Control Register
0.

Knowing this what procedure do I use (QNX functions) to read and
write
to
the PCI memory space?

Read the documentation on _CA set of function. In one of the function
(don’t remember which one) there is an example how to do this. It
involves
using mmap.

0xe700 is a very odd address for PCI memory (as 0xe700 is more of an
ISA
address). Are you sure this is not IO based instead of memory based.

How does one set the offset from the base address?
Does one have to create a new device to read and write?

No the mecanism is the same whether the card is ISA or PCI it’s just
how
you
obtain the address/memory type/ interupt that changes.


I would really appreciate some guidance if possible

John E. Kaye




\

“John Kaye” <jekaye@total.net> wrote in message
news:bilvig$23v$1@inn.qnx.com

Mario

Many thanks for your “pointing” me in the right direction. I got the
Keithley board to function correctly with C pointers to the mapped memory.
A/D, D/A and DIO all work. A last comment. You felt that the address of
0xe700 was not a PCI address.

Because 0xe700 is an range of address that is often use by ISA card. ISA
card are limited to what address they can use because address bus on ISA is
reduce compare to PCI. So to prevent conflict BIOS will usually attribute
PCI card that are in a range that does not conflict with ISA.
What range would you expect?

The board works but I don’t understand why it has to be mapped using the
mmap function.

Because QNX4 is an OS that uses virtual adresses. That means if a pointer is
set 0xbeef for example it’s not the physical address but rather a virtual
address, in reality you don’t care where is the real physical location.
That is one way the OS can protect program from accessing each other memory.
It also allows better memory utilisation because your code and data can be
scatter all over the physical memory but because of virtual memory it all
looks linear to your application. Since the _CA_PCI set of function gives
you a physical address you need to tell the OS that you want to map a
physical portion of memory into your virtual memory space. That’s what mmap
does. If you notice the adresse returned by mmap is different then the one
you specified :wink:

Can you briefly explain if you know.


Thanks again

JEK

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bik2iu$h4j$> 1@inn.qnx.com> …

“John Kaye” <> jekaye@total.net> > wrote in message
news:bijvbt$f4j$> 1@inn.qnx.com> …
Mario

Thanks for your response. I have read the documentation on the
_CA_PCI
group. Using mmap maps the base address to 0xf000 ( from the 0xe700).
I
am
therefore confused about memory based and I/O based. The QNX example
uses
the macro PCI_IS_MEM(address) to determine whether it is MEM or I/O.
Can
you explain the difference?

Memory based is basicly what it says, it’s access just like RAM, with C
pointer.

IO based is accessed via inp() and outp() functions.

The reason for having two different type of access dates from
prehistoric
ages > :wink:


Thanks

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bijtb9$dii$> 1@inn.qnx.com> …

“John Kaye” <> jekaye@total.net> > wrote in message
news:bij932$tr$> 1@inn.qnx.com> …
I have had to convert an existing QNX 4.25 system from an ISA
board
to
a
PCI
motherboard board. I am trying to development a driver for a
Keithley
A/D
board. VendorID and DeviceID are known and using the QNX function
_CA_PCI_Read_Config_DWord I have determined the base address from
the
configuration space to be 0xe700 from the General Control Register
0.

Knowing this what procedure do I use (QNX functions) to read and
write
to
the PCI memory space?

Read the documentation on _CA set of function. In one of the
function
(don’t remember which one) there is an example how to do this. It
involves
using mmap.

0xe700 is a very odd address for PCI memory (as 0xe700 is more of an
ISA
address). Are you sure this is not IO based instead of memory
based.

How does one set the offset from the base address?
Does one have to create a new device to read and write?

No the mecanism is the same whether the card is ISA or PCI it’s just
how
you
obtain the address/memory type/ interupt that changes.


I would really appreciate some guidance if possible

John E. Kaye






\

Mario

Thanks for explanation on mmap. On this whole issue of writing this driver
to replace an existing ISA board with PCI, the only book I found was one by
O’Reilly “Linux Device Drivers”. Reading several chapters it used kernel
calls, kernel space, etc and the major and minor numbers of the device.
Reviewing some demonstration code I found on the net for a Keithley card
using Linux it made it look very complicated!!
It appears much easier to write this device driver code using QNX…
especially using C pointers, etc. Why would one need kernel calls or need
to register the device? Any comments?

JEK


“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bim2u2$4ct$1@inn.qnx.com

“John Kaye” <> jekaye@total.net> > wrote in message
news:bilvig$23v$> 1@inn.qnx.com> …
Mario

Many thanks for your “pointing” me in the right direction. I got the
Keithley board to function correctly with C pointers to the mapped
memory.
A/D, D/A and DIO all work. A last comment. You felt that the address
of
0xe700 was not a PCI address.

Because 0xe700 is an range of address that is often use by ISA card. ISA
card are limited to what address they can use because address bus on ISA
is
reduce compare to PCI. So to prevent conflict BIOS will usually attribute
PCI card that are in a range that does not conflict with ISA.
What range would you expect?

The board works but I don’t understand why it has to be mapped using the
mmap function.

Because QNX4 is an OS that uses virtual adresses. That means if a pointer
is
set 0xbeef for example it’s not the physical address but rather a virtual
address, in reality you don’t care where is the real physical location.
That is one way the OS can protect program from accessing each other
memory.
It also allows better memory utilisation because your code and data can be
scatter all over the physical memory but because of virtual memory it all
looks linear to your application. Since the _CA_PCI set of function gives
you a physical address you need to tell the OS that you want to map a
physical portion of memory into your virtual memory space. That’s what
mmap
does. If you notice the adresse returned by mmap is different then the
one
you specified > :wink:

Can you briefly explain if you know.


Thanks again

JEK

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bik2iu$h4j$> 1@inn.qnx.com> …

“John Kaye” <> jekaye@total.net> > wrote in message
news:bijvbt$f4j$> 1@inn.qnx.com> …
Mario

Thanks for your response. I have read the documentation on the
_CA_PCI
group. Using mmap maps the base address to 0xf000 ( from the
0xe700).
I
am
therefore confused about memory based and I/O based. The QNX
example
uses
the macro PCI_IS_MEM(address) to determine whether it is MEM or I/O.
Can
you explain the difference?

Memory based is basicly what it says, it’s access just like RAM, with
C
pointer.

IO based is accessed via inp() and outp() functions.

The reason for having two different type of access dates from
prehistoric
ages > :wink:


Thanks

“Mario Charest” postmaster@127.0.0.1 wrote in message
news:bijtb9$dii$> 1@inn.qnx.com> …

“John Kaye” <> jekaye@total.net> > wrote in message
news:bij932$tr$> 1@inn.qnx.com> …
I have had to convert an existing QNX 4.25 system from an ISA
board
to
a
PCI
motherboard board. I am trying to development a driver for a
Keithley
A/D
board. VendorID and DeviceID are known and using the QNX
function
_CA_PCI_Read_Config_DWord I have determined the base address
from
the
configuration space to be 0xe700 from the General Control
Register
0.

Knowing this what procedure do I use (QNX functions) to read and
write
to
the PCI memory space?

Read the documentation on _CA set of function. In one of the
function
(don’t remember which one) there is an example how to do this. It
involves
using mmap.

0xe700 is a very odd address for PCI memory (as 0xe700 is more of
an
ISA
address). Are you sure this is not IO based instead of memory
based.

How does one set the offset from the base address?
Does one have to create a new device to read and write?

No the mecanism is the same whether the card is ISA or PCI it’s
just
how
you
obtain the address/memory type/ interupt that changes.


I would really appreciate some guidance if possible

John E. Kaye








\

“Rennie Allen” <rgallen@attbi.com> wrote in message
news:bimgek$d2h$1@inn.qnx.com

John Kaye wrote:
Mario

Thanks for explanation on mmap. On this whole issue of writing this
driver
to replace an existing ISA board with PCI, the only book I found was one
by
O’Reilly “Linux Device Drivers”. Reading several chapters it used
kernel
calls, kernel space, etc and the major and minor numbers of the device.
Reviewing some demonstration code I found on the net for a Keithley card
using Linux it made it look very complicated!!
It appears much easier to write this device driver code using QNX…
especially using C pointers, etc. Why would one need kernel calls or
need
to register the device? Any comments?

I’m not an expert on Linux, but any program that want to access hardware as
to run in kernel mode and in kernel mode you are in a differerent
environment then user mode, which is why you have to comply with a different
sets of rules.

Writing drivers for QNX bears no resemblence to writing drivers for Linux.
The
QNX O/S is what we like to refer to in “the business” as a coherent design
:wink:



You are correct, writing drivers for QNX is much easier than it is for
Linux.

For beginner resmgr is complicated, but then you don’t have to use it !