2003-05-01 19:10:49

by Lee, Shuyu

[permalink] [raw]
Subject: How to notify a user process from within a driver

Hello, All.

I am working on a device driver. One of the features of the hardware is
multi-channel I/O control. In order for a user process to communicate with
the hardware, my design is for the user process to call the driver's ioctl
to register a semaphore for each I/O channel, then wait on them. When the
hardware detects an input, the ISR then BH will wake up the user process.
This sounds straightforward in principle. Because there are two types of
semaphores in Linux (one for kernel, and one for user), I am not sure how
this can be accomplished. Any help would be greatly appreciated.

My development environment is:
1) OS: RedHat 7.2 (Linux 2.4.7),
2) gcc: 3.2.1,
3) PC: one P-III (HP kayak) with 128Mbyte of memory,
4) Bus: PCI.

Shuyu


2003-05-01 19:17:23

by Richard B. Johnson

[permalink] [raw]
Subject: Re: How to notify a user process from within a driver

On Thu, 1 May 2003, Lee, Shuyu wrote:

> Hello, All.
>
> I am working on a device driver. One of the features of the hardware is
> multi-channel I/O control. In order for a user process to communicate with
> the hardware, my design is for the user process to call the driver's ioctl
> to register a semaphore for each I/O channel, then wait on them. When the
> hardware detects an input, the ISR then BH will wake up the user process.
> This sounds straightforward in principle. Because there are two types of
> semaphores in Linux (one for kernel, and one for user), I am not sure how
> this can be accomplished. Any help would be greatly appreciated.
>
> My development environment is:
> 1) OS: RedHat 7.2 (Linux 2.4.7),
> 2) gcc: 3.2.1,
> 3) PC: one P-III (HP kayak) with 128Mbyte of memory,
> 4) Bus: PCI.
>
> Shuyu
>

You normally use poll() or select() for this. It's called poll()
inside the driver.

The user-mode code sleeps in poll() or select(). When your
driver ISR wants to wake up the process, it calls
wake_up_interruptible() from within the ISR.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.20 on an i686 machine (797.90 BogoMips).
Why is the government concerned about the lunatic fringe? Think about it.

2003-05-01 19:56:16

by Alan

[permalink] [raw]
Subject: Re: How to notify a user process from within a driver

On Iau, 2003-05-01 at 20:23, Lee, Shuyu wrote:
> Hello, All.
>
> I am working on a device driver. One of the features of the hardware is
> multi-channel I/O control. In order for a user process to communicate with
> the hardware, my design is for the user process to call the driver's ioctl
> to register a semaphore for each I/O channel,

For event waiting look at poll/select not at the SYS5 semaphore stuff
which is really an old compat hack for weird stuff AT&T did years ago.

2003-05-01 21:41:48

by Lee, Shuyu

[permalink] [raw]
Subject: RE: How to notify a user process from within a driver

Richard and Alan,

Thank you for the info. Given the prototype for poll() is
"int poll(struct pollfd *ufds, unsigned int nfds, int timeout);", and pollfd
is struct pollfd {int fd; short events; short revents};, how do I
communicate complex info to the driver?

For example, assuming there are 8 input lines on my hardware, and the user
wants to be notified in the following three cases:
1) input on Line 1 only,
2) input on either Line 2 or Line 3,
3) input on both Line 4 and Line 5,
how do I pass that info to the driver? Also, other than POLLERR and POLLHUP,
can I pass back to the user more descriptive error messages?

Thanks,
Shuyu


-----Original Message-----
From: Richard B. Johnson [mailto:[email protected]]
Sent: Thursday, May 01, 2003 3:32 PM
To: Lee, Shuyu
Cc: [email protected]
Subject: Re: How to notify a user process from within a driver

On Thu, 1 May 2003, Lee, Shuyu wrote:

> Hello, All.
>
> I am working on a device driver. One of the features of the hardware is
> multi-channel I/O control. In order for a user process to communicate with
> the hardware, my design is for the user process to call the driver's ioctl
> to register a semaphore for each I/O channel, then wait on them. When the
> hardware detects an input, the ISR then BH will wake up the user process.
> This sounds straightforward in principle. Because there are two types of
> semaphores in Linux (one for kernel, and one for user), I am not sure how
> this can be accomplished. Any help would be greatly appreciated.
>
> My development environment is:
> 1) OS: RedHat 7.2 (Linux 2.4.7),
> 2) gcc: 3.2.1,
> 3) PC: one P-III (HP kayak) with 128Mbyte of memory,
> 4) Bus: PCI.
>
> Shuyu
>

You normally use poll() or select() for this. It's called poll()
inside the driver.

The user-mode code sleeps in poll() or select(). When your
driver ISR wants to wake up the process, it calls
wake_up_interruptible() from within the ISR.

Cheers,
Dick Johnson
Penguin : Linux version 2.4.20 on an i686 machine (797.90 BogoMips).
Why is the government concerned about the lunatic fringe? Think about it.

2003-05-01 22:18:55

by Hua Zhong (hzhong)

[permalink] [raw]
Subject: RE: How to notify a user process from within a driver

You could have one fd for each line. Create multiple nodes in /dev with
different minor numbers. User space listens to the file(s) it is interested
in.

> Richard and Alan,
>
> Thank you for the info. Given the prototype for poll() is
> "int poll(struct pollfd *ufds, unsigned int nfds, int timeout);",
> and pollfd
> is struct pollfd {int fd; short events; short revents};, how do I
> communicate complex info to the driver?
>
> For example, assuming there are 8 input lines on my hardware, and the user
> wants to be notified in the following three cases:
> 1) input on Line 1 only,
> 2) input on either Line 2 or Line 3,
> 3) input on both Line 4 and Line 5,
> how do I pass that info to the driver? Also, other than POLLERR
> and POLLHUP,
> can I pass back to the user more descriptive error messages?
>
> Thanks,
> Shuyu
>
>
> -----Original Message-----
> From: Richard B. Johnson [mailto:[email protected]]
> Sent: Thursday, May 01, 2003 3:32 PM
> To: Lee, Shuyu
> Cc: [email protected]
> Subject: Re: How to notify a user process from within a driver
>
> On Thu, 1 May 2003, Lee, Shuyu wrote:
>
> > Hello, All.
> >
> > I am working on a device driver. One of the features of the hardware is
> > multi-channel I/O control. In order for a user process to
> communicate with
> > the hardware, my design is for the user process to call the
> driver's ioctl
> > to register a semaphore for each I/O channel, then wait on
> them. When the
> > hardware detects an input, the ISR then BH will wake up the
> user process.
> > This sounds straightforward in principle. Because there are two types of
> > semaphores in Linux (one for kernel, and one for user), I am
> not sure how
> > this can be accomplished. Any help would be greatly appreciated.
> >
> > My development environment is:
> > 1) OS: RedHat 7.2 (Linux 2.4.7),
> > 2) gcc: 3.2.1,
> > 3) PC: one P-III (HP kayak) with 128Mbyte of memory,
> > 4) Bus: PCI.
> >
> > Shuyu
> >
>
> You normally use poll() or select() for this. It's called poll()
> inside the driver.
>
> The user-mode code sleeps in poll() or select(). When your
> driver ISR wants to wake up the process, it calls
> wake_up_interruptible() from within the ISR.
>
> Cheers,
> Dick Johnson
> Penguin : Linux version 2.4.20 on an i686 machine (797.90 BogoMips).
> Why is the government concerned about the lunatic fringe? Think about it.
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/

2003-05-01 22:26:07

by Chris Friesen

[permalink] [raw]
Subject: Re: How to notify a user process from within a driver

Lee, Shuyu wrote:

> For example, assuming there are 8 input lines on my hardware, and the user
> wants to be notified in the following three cases:
> 1) input on Line 1 only,
> 2) input on either Line 2 or Line 3,
> 3) input on both Line 4 and Line 5,
> how do I pass that info to the driver? Also, other than POLLERR and POLLHUP,
> can I pass back to the user more descriptive error messages?

One to do something like this is to use signals. You could use ioctl for
userspace to register with the driver, and to query the status. When the
correct combination of inputs occurs, you thwap the process with a SIGUSR1,
which tells it to wake up and query the input line status.

Alternately, you could use ioctl for configuration and wait on a socket for
notification as to when to query the status.

Finally, you could use ioctl for configuration and write a byte to the socket
when the right event happens, the byte being a bitmap of the 8 input lines.

Chris


--
Chris Friesen | MailStop: 043/33/F10
Nortel Networks | work: (613) 765-0557
3500 Carling Avenue | fax: (613) 765-2986
Nepean, ON K2H 8E9 Canada | email: [email protected]

2003-05-02 11:40:36

by Richard B. Johnson

[permalink] [raw]
Subject: RE: How to notify a user process from within a driver

On Thu, 1 May 2003, Lee, Shuyu wrote:

> Richard and Alan,
>
> Thank you for the info. Given the prototype for poll() is
> "int poll(struct pollfd *ufds, unsigned int nfds, int timeout);", and pollfd
> is struct pollfd {int fd; short events; short revents};, how do I
> communicate complex info to the driver?
>
> For example, assuming there are 8 input lines on my hardware, and the user
> wants to be notified in the following three cases:
> 1) input on Line 1 only,
> 2) input on either Line 2 or Line 3,
> 3) input on both Line 4 and Line 5,
> how do I pass that info to the driver? Also, other than POLLERR and POLLHUP,
> can I pass back to the user more descriptive error messages?
>
> Thanks,
> Shuyu
>

poll() tells you something happened, ioctl() tells you what. Poll
has some bits (POLLIN, POLLOUT, etc.) that can be used to tell
the user-mode task what information to actually request in the
ioctl() call. Your ioctl() can receive and send anything if you
use the third variable as a pointer to your stuff.

struct info {
int a;
int b;
...
...
} info;
int fd;
struct pollfd pfd;
fd = open("/dev/device", O_RDWR);

pfd.fd = fd;
pfd.events = POLLIN;
pfd.revents = 0;
if(poll(&pfd, 1, 0) <= 0)
handle_problem();
else if (pfd.revents & POLLIN)
ret = ioctl(fd, GET_MY_INFORMATION, &foo);
else if (pfd.revents & POLLOUT)
ret = ioctl(fd, CHANGE_CONFIGURATION, &how);


Cheers,
Dick Johnson
Penguin : Linux version 2.4.20 on an i686 machine (797.90 BogoMips).
Why is the government concerned about the lunatic fringe? Think about it.