From owner-freebsd-drivers@FreeBSD.ORG Thu Nov 3 11:05:47 2005 Return-Path: X-Original-To: freebsd-drivers@freebsd.org Delivered-To: freebsd-drivers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id D711716A41F for ; Thu, 3 Nov 2005 11:05:47 +0000 (GMT) (envelope-from mayong@mail.com) Received: from webmail-outgoing.us4.outblaze.com (webmail-outgoing.us4.outblaze.com [205.158.62.67]) by mx1.FreeBSD.org (Postfix) with ESMTP id 7F73F43D45 for ; Thu, 3 Nov 2005 11:05:47 +0000 (GMT) (envelope-from mayong@mail.com) Received: from unknown (unknown [192.168.9.180]) by webmail-outgoing.us4.outblaze.com (Postfix) with QMQP id C9FCC18001DA for ; Thu, 3 Nov 2005 11:05:46 +0000 (GMT) X-OB-Received: from unknown (205.158.62.81) by wfilter.us4.outblaze.com; 3 Nov 2005 11:05:46 -0000 Received: by ws1-2.us4.outblaze.com (Postfix, from userid 1001) id BC3701F50B2; Thu, 3 Nov 2005 11:05:46 +0000 (GMT) Content-Disposition: inline Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 From: "Yong Ma" To: "M. Warner Losh" Date: Thu, 03 Nov 2005 06:05:46 -0500 Received: from [159.226.5.225] by ws1-2.us4.outblaze.com with http for mayong@mail.com; Thu, 03 Nov 2005 06:05:46 -0500 X-Originating-Ip: 159.226.5.225 X-Originating-Server: ws1-2.us4.outblaze.com Message-Id: <20051103110546.BC3701F50B2@ws1-2.us4.outblaze.com> Cc: freebsd-drivers@freebsd.org Subject: Re: Interface of the driver X-BeenThere: freebsd-drivers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Writing device drivers for FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 03 Nov 2005 11:05:48 -0000 ----- Original Message ----- From: "M. Warner Losh" To: mayong@mail.com Subject: Re: Interface of the driver Date: Wed, 02 Nov 2005 21:36:24 -0700 (MST) >=20 > In message: <20051103025038.CAF618401E@ws1-5.us4.outblaze.com> > "Yong Ma" writes: >=20 > : 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)? >=20 > 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). >=20 > : If so, > : how can I pass some arguments(such as my private key or the file > : name that will be encrypted)? >=20 > 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. >=20 > : Can I call some function(with > : arguments) defined in the driver in my user implications, and how? >=20 > Most drivers that define an ioctl interface have a fooio.h header. > fooio.h will include and then device their command > numbers. For example, mtio.h defines mag tape ioctls: >=20 > /* 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 */ >=20 > 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: >=20 > static int > saioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct=20 > thread *td) > { > int err; > ... > err =3D 0; > switch (cmd) { > ... > case MTIOCTOP: > { > struct mtop *mt =3D (struct mtop *) arg; > err =3D sa_process_mt(mt); > break; > } > default: > err =3D ENOTTY; > break; > } > ... > return (err); > } >=20 >=20 > The sa_process_mt routine would be something the driver wrote to > interpret the struct mtop from this call. Similarly for other ioctls. >=20 > _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. >=20 > In userland, the user would just include the fooio.h file and use it > like they would for any other ioctl: >=20 > struct foo_state > { > ... > }; >=20 > #define FOOIOCGETSTATE _IOR('f', 1, struct foo_state); > ... > struct foo_state state; > int foo; >=20 > fd =3D open("/dev/foo0", O_RDWR); > if (fd =3D=3D -1) > err(1, "open"); > if (ioctl(fd, FOOIOCGETSTATE, &state) =3D=3D -1) > err(1, "IOOIOCFETSTATE"); > /* Do something with the state */ > close(fd); > ... >=20 > hope this helps.. >=20 > Warner Thank you very much,it is just what I need! I did as you said but came across some problems: My test application is as follows(ioctltest.c): 1 #include 2 #include 3 #include 4 #include 5 #include 6 7 #define ENCRYPTFILE _IOW("s", 3, struct ioctlinfo) 8 9 struct ioctlinfo{ 10 unsigned long addr; 11 char *buffer; 12 }; 13 14 int main(void){ 15 int fd; 16 struct ioctlinfo info; 17 info.addr=3D0; 18 char *ibuffer=3D"Ioctl test!\n"; 19 printf("Ioctltest:%s\n",ibuffer); 20 info.buffer=3Dibuffer; 21 fd=3Dopen("/dev/sjy22b0",O_RDWR); 22 if(fd=3D=3D-1) 23 err(1,"open"); 24 if(ioctl(fd,ENCRYPTFILE,&info)=3D=3D-1) 25 err(1,"CRYPTFILE!"); 26 close(fd); 27 return (0); 28 } A really simple one:),and the ioctl() in driver adjust as this: ... 313 case ENCRYPTFILE: 314 ioinfo=3D(struct ioctlinfo *)addr; 315 printf("Ioctlinfo :\n addr=3D%ld\nbuffer:%s= \n",ioinfo->addr,ioinfo->buffer); 316 317 break; ... but when I complie the test application(ioctltest.c),it told me: ioctltest.c: In function `main': ioctltest.c:24: error: invalid operands to binary << *** Error code 1 ~~~~~~~~~~~~~~~~~~~~~~~~~~ what's wrong?did I lose any headers or anything else? Thanks Yong --=20 ___________________________________________________ Play 100s of games for FREE! http://games.mail.com/