Date: Wed, 02 Nov 2005 21:36:24 -0700 (MST) From: "M. Warner Losh" <imp@bsdimp.com> To: mayong@mail.com Cc: freebsd-drivers@freebsd.org Subject: Re: Interface of the driver Message-ID: <20051102.213624.50069863.imp@bsdimp.com> In-Reply-To: <20051103025038.CAF618401E@ws1-5.us4.outblaze.com> References: <20051103025038.CAF618401E@ws1-5.us4.outblaze.com>
next in thread | previous in thread | raw e-mail | index | archive | help
In message: <20051103025038.CAF618401E@ws1-5.us4.outblaze.com> "Yong Ma" <mayong@mail.com> writes: : My driver for the cryptographic accelerator is almost finished, the : next job will be the development of user interfaces. I've got some : problems now: Is the ioctl() function the only way in which the user : implications interact with the driver(mine is a KLD module)? Yes and no. It is the typical way that most drivers choose to interact with userland. In this model, you have to add a device entry (see make_dev(9)) wher you give it a 'cdevsw' structure. This is the stylized way of doing function potiners for entry points (virtual functions in C++ use a similar mechanism) to the driver. You create a device, the user opens it and then issues requests. In your case ioctl (although I suspect read and write too). : If so, : how can I pass some arguments(such as my private key or the file : name that will be encrypted)? There are a number of macros which help you to pass arguments. The ioctl function itself takes a 'function' and a 'arguement'. Since the 'function' also encodes the size and direction of the ioctl, it can copy the arguments into the kenrel for you and copy them out when you are done. : Can I call some function(with : arguments) defined in the driver in my user implications, and how? Most drivers that define an ioctl interface have a fooio.h header. fooio.h will include <sys/ioccom.h> and then device their command numbers. For example, mtio.h defines mag tape ioctls: /* mag tape io control commands */ #define MTIOCTOP _IOW('m', 1, struct mtop) /* do a mag tape op */ #define MTIOCGET _IOR('m', 2, struct mtget) /* get tape status */ /* these two do not appear to be used anywhere */ #define MTIOCIEOT _IO('m', 3) /* ignore EOT error */ The first one 'writes' a magtape operation to the kernel. This is contained in a struct mtop. The struct mtop is defined in mtio.h, but I've omitted it here. The driver gets the MTIOCTOP operations, does some casting and then extracts data from the passed in structure. The kernel code looks something like: static int saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td) { int err; ... err = 0; switch (cmd) { ... case MTIOCTOP: { struct mtop *mt = (struct mtop *) arg; err = sa_process_mt(mt); break; } default: err = ENOTTY; break; } ... return (err); } The sa_process_mt routine would be something the driver wrote to interpret the struct mtop from this call. Similarly for other ioctls. _IOW() is for defining ioctls that write data into the kernel only. Most 'set' ioctls are IOW. _IOR are used to extract data from the kernel. Most 'get' ioctls are IOR. _IO ioctls are ioctls that pass no data to the kernel and do some predefined thing (like set the ignore eof flag above). _IOWR are used to pass data both ways, into and out of the kernel. These are used for more complicated 'get' routines or to communicate data back out of the kernel. In userland, the user would just include the fooio.h file and use it like they would for any other ioctl: struct foo_state { ... }; #define FOOIOCGETSTATE _IOR('f', 1, struct foo_state); ... struct foo_state state; int foo; fd = open("/dev/foo0", O_RDWR); if (fd == -1) err(1, "open"); if (ioctl(fd, FOOIOCGETSTATE, &state) == -1) err(1, "IOOIOCFETSTATE"); /* Do something with the state */ close(fd); ... hope this helps.. Warner
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20051102.213624.50069863.imp>