1 /* $NetBSD: intro.c,v 1.3 2007/11/22 11:28:49 pooka Exp $ */
4 * El extra-simplo example of the userspace driver framework.
6 * Eventually there will be a library a la libpuffs (perhaps,
7 * gasp, even the same lib), but for now it's all manual until
8 * I get it figured out.
11 * 0) sh MAKEDEV putter (if you don't have a freshly created /dev)
12 * 1) run this program with the argument "/dev/pud"
13 * 2) mknod a char device with the major 377 (see sources below)
14 * 3) echo ascii art and jokes into device created in previous step
18 #include <sys/types.h>
20 #include <dev/pud/pud_msgif.h>
32 #define DEFALLOC 1024*1024
33 #define ECHOSTR1 "Would you like some sauce diable with that?\n"
34 #define ECHOSTR2 "Nej tack, you fool, I'm happy with my tournedos Rossini\n"
37 const char *curstr
= ECHOSTR1
;
40 #define MIN(a,b) ((a)<(b)?(a):(b))
44 main(int argc
, char *argv
[])
46 struct pud_req
*pdr
= malloc(DEFALLOC
);
47 struct pud_conf_reg pcr
;
57 fd
= open(argv
[1], O_RDWR
);
62 * register our major number
64 memset(&pcr
, 0, sizeof(pcr
));
65 pcr
.pm_pdr
.pdr_pth
.pth_framelen
= sizeof(struct pud_conf_reg
);
66 pcr
.pm_version
= PUD_DEVELVERSION
| PUD_VERSION
;
67 pcr
.pm_pdr
.pdr_reqclass
= PUD_REQ_CONF
;
68 pcr
.pm_pdr
.pdr_reqtype
= PUD_CONF_REG
;
70 pcr
.pm_regdev
= makedev(377, 0);
71 pcr
.pm_flags
= PUD_CONFFLAG_BDEV
;
72 strlcpy(pcr
.pm_devname
, "testdev", sizeof(pcr
.pm_devname
));
74 n
= write(fd
, &pcr
, pcr
.pm_pdr
.pdr_pth
.pth_framelen
);
76 err(1, "configure write");
82 n
= read(fd
, pdr
, DEFALLOC
);
83 printf("read %d %d\n", n
, errno
);
85 switch (pdr
->pdr_reqtype
) {
88 printf("got openclose %d\n", pdr
->pdr_reqtype
);
93 /* uh oh case PUD_BDEV_STRATREAD: */
95 struct pud_creq_read
*pc_read
;
98 pc_read
= (void *)pdr
;
99 printf("read from offset %llu, resid %zu\n",
100 (unsigned long long)pc_read
->pm_offset
,
103 clen
= MIN(strlen(curstr
), pc_read
->pm_resid
);
104 strncpy(pc_read
->pm_data
, curstr
, clen
);
105 if (pdr
->pdr_reqclass
== PUD_REQ_BDEV
) {
106 clen
= pc_read
->pm_resid
;
107 pc_read
->pm_resid
= 0;
109 pc_read
->pm_resid
-= clen
;
111 pdr
->pdr_pth
.pth_framelen
=
112 sizeof(struct pud_creq_read
) + clen
;
117 /* uh uh oh case PUD_BDEV_STRATWRITE: */
119 struct pud_creq_write
*pc_write
;
121 pc_write
= (void *)pdr
;
122 printf("write to offset %llu, resid %zu\n",
123 (unsigned long long)pc_write
->pm_offset
,
126 pc_write
->pm_data
[pc_write
->pm_resid
] = '\0';
127 printf("got via write: %s", pc_write
->pm_data
);
128 pdr
->pdr_pth
.pth_framelen
=
129 sizeof(struct pud_creq_write
);
130 pc_write
->pm_resid
= 0;
136 struct pud_req_ioctl
*pc_ioctl
;
139 pc_ioctl
= (void *)pdr
;
140 switch (pc_ioctl
->pm_iocmd
) {
143 iocval
= (int *)pc_ioctl
->pm_data
;
144 if (*iocval
< 0 || *iocval
> 2) {
145 pdr
->pdr_rv
= ERANGE
;
166 n
= write(fd
, pdr
, pdr
->pdr_pth
.pth_framelen
);
167 printf("wrote %d %d\n", n
, errno
);