Major and Minor Device Numbers for Resource Manager Devices

I am porting an I/O Manager from QnX 4 to a resource manager on 6.2. I want
to be able to assign a major (the same number) and minor (different for each
device) to the devices (maximum :sunglasses: serviced by the RM. These devices are
character special devices (c).

QnX 4 provided qnx_device_attach to allow assignment of a major device
number to the manager. Minor numbers could be selectively assigned to each
device using qnx_prefix_attach ()

I want to be able to configure my devices in the same manner using 6.2.

After resmgr_attach is run for each device, the major and minor numbers for
each device assinged to the RM are all 0 (ls -l /dev/xxx)

I have used rsrcdbmgr_devno_attach (). This function will not allow the ‘/’
character in the path, so I can’t present /dev/xxx to this function.

I have used resmgr_devino with similar results.

The Rob Krten book (ppgs 289 and 291) describes the rdev member of the
iofunc_attr_t structure as containing a major and minor device number.
After my RM runs, this member is 0. I have also assigned (the optional)
iofunc_mount_t structure to each device. The dev member of this structure
for each device also contains 0. For now, I am stuffing the correct minor
number in the ‘dev’ member of the iofunc_mount_t structure. Not an
acceptable solution.

When I list other ‘c’ type devices (such as /dev/ser*) I see a proper major,
minor number set displayed.

  1. What is the proper method to assign a major number to my RM. The
    porting document says that qnx_device_attach () is replaced in 6.2 by
    rsrcdbmgr_devno_attach ().

  2. What function can be used to assign the minor number I want assigned
    to each device serviced by the RM.

Any Ideas ???

Gordon Baxter <gbaxter@gandacar.ca> wrote:

After resmgr_attach is run for each device, the major and minor numbers for
each device assinged to the RM are all 0 (ls -l /dev/xxx)

iofunc_attr_init() will zero out the rdev field.

I have used rsrcdbmgr_devno_attach (). This function will not allow the ‘/’
character in the path, so I can’t present /dev/xxx to this function.

I am not sure what you mean by this? The ‘name’ field to this function
is not a pathname but a major device category (strings are used for
major device classes). Refer to <sys/ftype.h> for some definition of
common major classes and manifests. You will either want to just use
_MAJOR_DEV or perhaps construct your own using _MAJOR_CHAR_PREFIX.
Then to get the device numbers call:

attr->rdev = rsrcdbmgr_devno_attach(_MAJOR_DEV, -1 , 0);

I have used resmgr_devino with similar results.

This routine is used to populate the dev and ino fields of a stat entry
for each pathname registered with proc. You need to pass it the id
returned from resmgr_attach(). So something like:

resmgr_devino(ID, &attr->dev, &attr->inode);

  1. What is the proper method to assign a major number to my RM. The
    porting document says that qnx_device_attach () is replaced in 6.2 by
    rsrcdbmgr_devno_attach ().

That is correct.

  1. What function can be used to assign the minor number I want assigned
    to each device serviced by the RM.

rsrcdbmgr_devno_attach(); you can force a particular minor number but
typically you would pass ‘-1’ as the request/hint to take any available
value. Major device classes are a reasonably scarce resource, so instead
of defining your own string call reuse one of the standard ones from the
<sys/ftype.h> that most closely fits your device type if possible.

John Garvey <jgarvey@qnx.com> wrote:

resmgr_devino(ID, &attr->dev, &attr->inode);

Small typo, of course I meant “attr->mount->dev” here. The default
iofunc_stat() callout will arrange for this value to be retrieved
from the mount structure and placed into st_dev.

Implemented your suggestions and works very well. Thank you. (I used
_MAJOR_CHAR_PREFIX to implement my devices.)

I have one other question.

When a utility such as ls is invoked (ls -l /dev/sdc*) for instance, the
io_open and io_close functions are accessed.

I don’t really want to open and close the physical hardware port in this
case.

How can I detect the difference between this type of open/close vs an
open/close issued by a user program ??

Gordon Baxter <gbaxter@gandacar.ca> wrote:

Implemented your suggestions and works very well. Thank you. (I used
_MAJOR_CHAR_PREFIX to implement my devices.)

Great!

When a utility such as ls is invoked (ls -l /dev/sdc*) for instance, the
io_open and io_close functions are accessed.
I don’t really want to open and close the physical hardware port in this
case.
How can I detect the difference between this type of open/close vs an
open/close issued by a user program ??

Everything (under the covers, at the resmgr-level) is done on open fds
(in your example, the stat() performed by “ls”, which turns into a
open/fstat/close combined sequence). You can examine the open mode of
the request (“msg->connect.ioflag & (_IO_FLAG_RD | IO_FLAG_WR)") to
distinguish between a client trying to open the entry to really use it
for read/write and one just getting metadata access to it. For your
hardware manager, if neither of those bits are set on the open then you
probably do not want to access/initialise the hardware. (The standard
helper routines "iofunc
{read,write}_verify()” will later check that the
OCB open mode included the appropriate IO_FLAG{RD,WR} bit, so you
won’t get a bogus attempt to do real access on an fd you didn’t set up
first :slight_smile:

Thanks for the info.

I assumed that ocb->ioflag from the io_close_ocb call contains the same
info as msg->connect.ioflag from the io_open call, and implemented the same
logic described in your note for the close_ocb handler.

Appreciate your help.