driver

B

Bill Cunningham

This is part of a driver skull. Now I want to make sure I understand
some of the lines.

int (*ioctrl) (struct usb_device dev,unsigned in code,void buff);

Ok what I belive I have above is a function that points to an int. This
being especially what I am asking about,

int (*ioctl) this function is called ioctl or is a pointer to a function
called ioctl. I'm not sure which. And an int is returned.

Am I close?

Bill
 
K

Keith Thompson

Bill Cunningham said:
This is part of a driver skull. Now I want to make sure I understand
some of the lines.

What is a "driver skull"? I assume that's a typo, but I have no idea
for what.
int (*ioctrl) (struct usb_device dev,unsigned in code,void buff);

Ok what I belive I have above is a function that points to an int. This
being especially what I am asking about,

int (*ioctl) this function is called ioctl or is a pointer to a function
called ioctl. I'm not sure which. And an int is returned.

Am I close?

No, you're not even close to being close.

The declaration contains syntax errors, presumably caused by your
attempt to re-type it rather than copy-and-paste it. How many
times have we told you not to do that?

I won't waste my time correcting the typos, so there's nothing more
to say.
 
B

Bill Cunningham

Keith Thompson said:
What is a "driver skull"? I assume that's a typo, but I have no idea
for what.


No, you're not even close to being close.

The declaration contains syntax errors, presumably caused by your
attempt to re-type it rather than copy-and-paste it. How many
times have we told you not to do that?

I tried to cut and paste and the site wouldn't let me do it. Here's a
url which I should cut to begin with.

http://www.lrr.in.tum.de/Par/arch/usb/usbdoc/node16.html#127
 
E

Edward A. Falk

int (*ioctrl) (struct usb_device dev,unsigned in code,void buff);

Ok what I belive I have above is a function that points to an int. This
being especially what I am asking about,

No, you have a pointer to a function that returns int. Without the parens
around "ioctl", you would have a function that returned pointer to int.
int (*ioctl) this function is called ioctl or is a pointer to a function
called ioctl. I'm not sure which. And an int is returned.

Closer, but still wrong. It's a variable named "ioctl" which is a
pointer to a function that returns int.

In other words, the parens serve to set precedence in a declaration, just
as in an expression.

int foo(args)
foo is function that returns int

int *foo(args)
foo is a function that returns int *

int (*foo)(args)
(*foo) is a function that returns int. I.e. foo is a pointer to
a function that returns int.

int *(*foo)(args)
And for good measure, a pointer to a function that returns a
pointer to int.

What you're looking at is a crude form of object-oriented programming, used
because kernel writers don't like to use C++ or any other language that
requires a lot (or any) runtime support libraries.

You didn't say, but I recognized the snippet you used as part of a
device driver structure. A class definition of sorts.

Crudely reconstructed from memory:

struct file_operations {
char *devicename;
int (*open)(args);
int (*release)(args);
int (*ioctl)(args);
int (*read)(args);
int (*write)(args);
};

In an object-oriented language, this would have been a class called
file_operations with open(), release(), ioctl(), etc. methods. In a
pure C environment, it's a data structure that holds pointers to
functions to perform specific to a certain kind of device.

I hope you don't my saying so (and I hope I'm not being trolled), but if
you don't already know this stuff, then I think perhaps you're not ready
for kernel programming, which is about as deep end of the pool as you
can get.
 
B

Bill Cunningham

Edward A. Falk said:
I hope you don't my saying so (and I hope I'm not being trolled), but if
you don't already know this stuff, then I think perhaps you're not ready
for kernel programming, which is about as deep end of the pool as you
can get.
http://www.lrr.in.tum.de/Par/arch/usb/usbdoc/node16.html#127

Yes it is part of a struct for a usb device driver. As I looked at the
raw code as found at the above url I recognize ioctl as being part of kernel
code or system calls. So the function is a pointer to ioctl. Then does the
function prototype I descibed not have a function name of its own?

Bill
 
K

Keith Thompson

Bill Cunningham said:
Edward A. Falk said:
http://www.lrr.in.tum.de/Par/arch/usb/usbdoc/node16.html#127

Yes it is part of a struct for a usb device driver. As I looked at the
raw code as found at the above url I recognize ioctl as being part of kernel
code or system calls. So the function is a pointer to ioctl. Then does the
function prototype I descibed not have a function name of its own?

What do you mean by "the function"? There is no function in the code
you showed us.

Here's the code on the web page (which is inexplicably presented
as an image rather than as text), with the indentation tweaked for
better legibility:

struct usb_driver {
const char *name;

void * (*probe) (struct usb_device *,
unsigned int,
const struct usb_device *id_table);
void (*disconnect)(struct usb_device *, void *);

struct list_head driver_list;

struct file_operations *fops;
int minor;
struct semaphore serialize;
int (*ioctl) (struct usb_device *dev,
unsigned int code,
void *buf);
const struct usb_device_id *id_table;
};

A struct usb_driver has a member named "ioctl". This member is a
pointer to a function. There is no indication here of what function
it might actually point to.

Bill, this is fairly advanced stuff. I think you're in *way* over
your head. But given your past behavior, you'll probably just drop
this just as you're beginning to understand some small part of it
and start over again with something else.

What exactly are you trying to accomplish?
 
B

Bill Cunningham

[snip]
Bill, this is fairly advanced stuff. I think you're in *way* over
your head. But given your past behavior, you'll probably just drop
this just as you're beginning to understand some small part of it
and start over again with something else.

What exactly are you trying to accomplish?

An understanding of this C code for starters. There is something called
ioctl in kernel code. But I guess it has nothing to do with this code and
there are no functions in it. I have never used a int (*ioctl) or anything
related. So with the code on this page how would I pass something from
(*ioctl) or from void (*disconnect) ? I also see what looks like struct
being declared from struct prototypes like for example.

struct file_operations *fops;

Somewhere there is a struct called file_operations that fops points to. Am I
making sense?

Bill
 
B

Bill Cunningham

[snip]
Here's the code on the web page (which is inexplicably presented
as an image rather than as text), with the indentation tweaked for
better legibility:

struct usb_driver {
const char *name;

void * (*probe) (struct usb_device *,
unsigned int,
const struct usb_device *id_table);
void (*disconnect)(struct usb_device *, void *);

struct list_head driver_list;

struct file_operations *fops;
int minor;
struct semaphore serialize;
int (*ioctl) (struct usb_device *dev,
unsigned int code,
void *buf);
const struct usb_device_id *id_table;
};

Maybe there is not enough to this struct and code snippet to be able to
tell much. This code is very much dependant on other code it looks like to
me.

Bill
 
S

Seebs

Bill, this is fairly advanced stuff. I think you're in *way* over
your head. But given your past behavior, you'll probably just drop
this just as you're beginning to understand some small part of it
and start over again with something else.

What exactly are you trying to accomplish?

I would guess that he's got no more idea what he's trying to do than
he does what any of the code or text means.

You're asking that question of someone who can, fairly often, get
stumped on questions like "I altered lines of this program at random
because I got an error message, now it doesn't work" -- I don't think
that "trying to accomplish" is really the right concept here, that
would imply some kind of goal-directed behavior.

-s
 
B

Bill Cunningham

What exactly are you trying to accomplish?

More than anything to understand this new code that I've never seen. I'm
looking at linux device driver books but this is the type of code that I
need to discypher. It's interesting reading and I learn more about OSs but I
want to understand more C too so where better to ask than clc? I understand
what you are saying when you say it's too advanced for me but there's two
ways to learn to swim learn basics and wade out little by little, or learn
basics and jump in the deep part with some helpers.

I also see there are no functions defined/declared here. I see what you
mean. This is just a small piece of code from something more complex
obviously.

From a guy that has no idea how to attempt macro expansion. I don't even
know what its purpose would be good for.

BTW I looked at scheme that everyone says is so simple. I think C would
be easier and more effective for me.

Bill
 
C

Curtis Dyer

More than anything to understand this new code that I've
never seen. I'm
looking at linux device driver books but this is the type of
code that I need to discypher. It's interesting reading and I
learn more about OSs but I want to understand more C too so
where better to ask than clc? I understand what you are saying
when you say it's too advanced for me but there's two ways to
learn to swim learn basics and wade out little by little, or
learn basics and jump in the deep part with some helpers.

The problem here is that you seem to be assuming you have a handle
on the basics. Judging by your recent posting history, this is
still not the case. In addition to having some issues with C
syntax, there are other fundamental, more general, programming
concepts you have yet to grasp.

Attempting to deal with advanced systems programming most likely
won't help you at all. FWIW, I remember trying to learn to use the
Win32 API before I knew C. Needless to say, that was a bad idea.

<snip>
 
D

Donkey Hottie

struct file_operations *fops;

Somewhere there is a struct called file_operations that fops points to. Am I
making sense?

No. The file_operations is the *type* of the struct that fops points to.
fops does not point anything currently, it has to be assigned a value to
do so. That snippet has it uninitialized.
 
B

Bill Cunningham

Attempting to deal with advanced systems programming most likely
won't help you at all. FWIW, I remember trying to learn to use the
Win32 API before I knew C. Needless to say, that was a bad idea.

It never panned out for me either. There's so much code lurking here
that I see that's out of my grasp. But keith mentioned previously that I
would walk away and do something else before learning something from this.
This is indeed deep C code.

Bill
 
B

Bill Cunningham

No. The file_operations is the *type* of the struct that fops points to.
fops does not point anything currently, it has to be assigned a value to
do so. That snippet has it uninitialized.

Being uninitialized you say. Is that something a declaration similar to

int a;

In this code?

Bill
 
E

Edward A. Falk

[snip]


An understanding of this C code for starters. There is something called
ioctl in kernel code. But I guess it has nothing to do with this code and
there are no functions in it.

Here's how it works: The ioctl() C library function generates a system
call in a completely architecture-dependent manner. The system call is
decoded by the kernel which will call some internal function which may
or may not be named "ioctl". Let's assume that it is, although it could
just as easily be called "do_ioctl" or "sys_ioctl", or anything else.

The internal ioctl() function will receive as one of its arguments a
file descriptor. It will use the file descriptor to look up some sort
of device control structure.

(I'm being deliberately vauge here, because I've worked on more than
one operating system in my life, and they all do things in their own way.)

The device control structure will either have an "int (*ioctl)(...);" entry
in it, or it will point to some other structure that does. One way or another,
the kernel will drill down through the data structures until it finds that
entry.

The kernel has no idea what that entry points to or what it's called. It may
in fact not point to anything (null pointer), in which case the kernel will
return an ENOTTY error (or something else, depends on the os version).

If the ioctl pointer is non-null, the kernel will assume that it points to a legitimate
ioctl function provided by a device driver, and call it. What happens next depends
on the driver in question.

By convention, a device driver named "foo" will usually name its ioctl function
"foo_ioctl()", but that's not a requirement. You could just as easily name it
"ioctl()" as long as you made it private to your driver module. (This is bad practice,
however, since it makes debugging harder.)

Under Linux especially, it gets more complicated because Linux loves to group
similar devices together and share as much code as possible, via sub-devices
and other techniques. For instance, caling ioctl() on a block device will
result in a call to the block driver ioctl() function which may handle the
call itself, or pass it on to device-type-specific (CD, Disk, etc.) ioctl
function, which in turn may pass the request onto a driver-specific ioctl
function and so forth. All of these calls will be made through further
"int (*ioctl)()" pointers.

I have never used a int (*ioctl) or anything
related. So with the code on this page how would I pass something from
(*ioctl) or from void (*disconnect) ?

One of the white-light epiphanies I experienced when I was first exposed
to C was the insanely radical notion that you could have a *pointer*
to a *function* and change that pointer any time you wanted. After that
moment, I never looked back at the legacy languages I had been programming
in previously.

The way you use such a function goes back to my previous post, where I wrote

int (*foo)()
(*foo) is a function that returns int.

So what you do is refer to (*foo) as a function call.

For example:

int (*ioctl)(args); /* "ioctl" is a pointer to a function. It
* does not point to anything yet.
/

ioctl = &foo_ioctl; /* "ioctl" now points to the
* foo_ioctl() function.
*/

(*ioctl)(args); /* call foo_ioctl() /

(A couple of notes:

1) The compiler knows that if you refer to a function name alone, you
mean the address of that function, so "&foo_ioctl" can be written as
simply "foo_ioctl".

2) The compiler also knows what to do if you treat a pointer to a function
as if it were the name of a function, so "(*ioctl)(args)" can be written
as simply "ioctl(args)"

So I could have written:

int (*ioctl)(args);
ioctl = foo_ioctl;
ioctl(args);

I find that the shorter form is more common and looks better, but it does
require you to know in your head what are simple function names and what
are function pointers.

A more useful example:

int do_ioctl(fd, args)
{
struct dev_info *dev = get_dev_from_fd(fd);
struct file_operations *fops;
if (dev == NULL || dev->fops == NULL)
return ENOTTY;
fops = dev->fops;
if (fops->ioctl == NULL)
return ENOTTY;
else
return fops->ioctl(args);
}

Or even (assuming I'm confident I won't hit any NULL pointers):

int do_ioctl(fd, args)
{
return get_dev_from_fd(fd)->fops->ioctl(args);
}

struct file_operations *fops;

Somewhere there is a struct called file_operations that fops points to. Am I
making sense?

Yes. "file_operations" is the *type* of struct that fops points to.
We neither know nor care what its actual name is.
 
H

Herbert Rosenau

More than anything to understand this new code that I've never seen. I'm
looking at linux device driver books but this is the type of code that I
need to discypher.

Bill, that is far, far away from the knowledge you own currently.
Stick that back to the far future you may come in some years. You have
to learn much more of the basics of C before you gets to that
complicated level of very, very experienced experts needed to
understund a bit of programming drivers or kernel.


--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!
 
B

Bill Cunningham

Bill, that is far, far away from the knowledge you own currently.
Stick that back to the far future you may come in some years. You have
to learn much more of the basics of C before you gets to that
complicated level of very, very experienced experts needed to
understund a bit of programming drivers or kernel.

I know but I am curious as to the code I see in places (like the linux
kernel). Atleast I understand now that this is an attempt at OOP. You learn
everyday.

Bill
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top