intro.c revision 1.2 1 1.2 pooka /* $NetBSD: intro.c,v 1.2 2007/11/21 18:11:17 pooka Exp $ */
2 1.1 pooka
3 1.1 pooka /*
4 1.1 pooka * El extra-simplo example of the userspace driver framework.
5 1.1 pooka *
6 1.1 pooka * Eventually there will be a library a la libpuffs (perhaps,
7 1.1 pooka * gasp, even the same lib), but for now it's all manual until
8 1.1 pooka * I get it figured out.
9 1.1 pooka *
10 1.1 pooka * So how to run this?
11 1.1 pooka * 0) sh MAKEDEV putter (if you don't have a freshly created /dev)
12 1.1 pooka * 1) run this program with the argument "/dev/pud"
13 1.1 pooka * 2) mknod a char device with the major 377 (see sources below)
14 1.1 pooka * 3) echo ascii art and jokes into device created in previous step
15 1.1 pooka * or read the device
16 1.1 pooka */
17 1.1 pooka
18 1.1 pooka #include <sys/types.h>
19 1.1 pooka
20 1.1 pooka #include <dev/pud/pud_msgif.h>
21 1.1 pooka
22 1.1 pooka #include <err.h>
23 1.1 pooka #include <errno.h>
24 1.1 pooka #include <fcntl.h>
25 1.1 pooka #include <stdio.h>
26 1.1 pooka #include <stdlib.h>
27 1.1 pooka #include <string.h>
28 1.1 pooka #include <unistd.h>
29 1.1 pooka
30 1.1 pooka #define DEFALLOC 1024*1024
31 1.1 pooka #define ECHOSTR "Would you like some sauce diable with that?\n"
32 1.1 pooka
33 1.1 pooka #ifndef MIN
34 1.1 pooka #define MIN(a,b) ((a)<(b)?(a):(b))
35 1.1 pooka #endif
36 1.1 pooka
37 1.1 pooka int
38 1.1 pooka main(int argc, char *argv[])
39 1.1 pooka {
40 1.1 pooka struct pud_req *pdr = malloc(DEFALLOC);
41 1.1 pooka struct pud_conf_reg pcr;
42 1.1 pooka int fd;
43 1.1 pooka ssize_t n;
44 1.1 pooka
45 1.1 pooka if (argc != 2)
46 1.1 pooka errx(1, "args");
47 1.1 pooka
48 1.1 pooka /*
49 1.1 pooka * open pud device
50 1.1 pooka */
51 1.1 pooka fd = open(argv[1], O_RDWR);
52 1.1 pooka if (fd == -1)
53 1.1 pooka err(1, "open");
54 1.1 pooka
55 1.1 pooka /*
56 1.1 pooka * register our major number
57 1.1 pooka */
58 1.1 pooka memset(&pcr, 0, sizeof(pcr));
59 1.1 pooka pcr.pm_pdr.pdr_pth.pth_framelen = sizeof(struct pud_conf_reg);
60 1.1 pooka pcr.pm_pdr.pdr_reqclass = PUD_REQ_CONF;
61 1.1 pooka pcr.pm_pdr.pdr_reqtype = PUD_CONF_REG;
62 1.1 pooka
63 1.1 pooka pcr.pm_regdev = makedev(377, 0);
64 1.2 pooka pcr.pm_flags = PUD_CONFFLAG_BDEV;
65 1.1 pooka strlcpy(pcr.pm_devname, "testdev", sizeof(pcr.pm_devname));
66 1.1 pooka
67 1.1 pooka n = write(fd, &pcr, pcr.pm_pdr.pdr_pth.pth_framelen);
68 1.1 pooka if (n == -1)
69 1.1 pooka err(1, "configure write");
70 1.1 pooka
71 1.1 pooka /*
72 1.1 pooka * process requests
73 1.1 pooka */
74 1.1 pooka for (;;) {
75 1.1 pooka n = read(fd, pdr, DEFALLOC);
76 1.2 pooka printf("read %d %d\n", n, errno);
77 1.1 pooka
78 1.1 pooka switch (pdr->pdr_reqtype) {
79 1.1 pooka case PUD_CDEV_OPEN:
80 1.1 pooka case PUD_CDEV_CLOSE:
81 1.1 pooka printf("got openclose %d\n", pdr->pdr_reqtype);
82 1.1 pooka pdr->pdr_rv = 0;
83 1.1 pooka break;
84 1.1 pooka
85 1.1 pooka case PUD_CDEV_READ:
86 1.2 pooka /* uh oh case PUD_BDEV_STRATREAD: */
87 1.1 pooka {
88 1.1 pooka struct pud_creq_read *pc_read;
89 1.1 pooka size_t clen;
90 1.1 pooka
91 1.1 pooka pc_read = (void *)pdr;
92 1.2 pooka printf("read from offset %llu, resid %zu\n",
93 1.2 pooka (unsigned long long)pc_read->pm_offset,
94 1.2 pooka pc_read->pm_resid);
95 1.2 pooka
96 1.1 pooka clen = MIN(strlen(ECHOSTR), pc_read->pm_resid);
97 1.1 pooka strncpy(pc_read->pm_data, ECHOSTR, clen);
98 1.2 pooka if (pdr->pdr_reqclass == PUD_REQ_BDEV) {
99 1.2 pooka clen = pc_read->pm_resid;
100 1.2 pooka pc_read->pm_resid = 0;
101 1.2 pooka } else {
102 1.2 pooka pc_read->pm_resid -= clen;
103 1.2 pooka }
104 1.1 pooka pdr->pdr_pth.pth_framelen =
105 1.1 pooka sizeof(struct pud_creq_read) + clen;
106 1.1 pooka }
107 1.1 pooka break;
108 1.1 pooka
109 1.1 pooka case PUD_CDEV_WRITE:
110 1.2 pooka /* uh uh oh case PUD_BDEV_STRATWRITE: */
111 1.1 pooka {
112 1.1 pooka struct pud_creq_write *pc_write;
113 1.1 pooka
114 1.1 pooka pc_write = (void *)pdr;
115 1.2 pooka printf("write to offset %llu, resid %zu\n",
116 1.2 pooka (unsigned long long)pc_write->pm_offset,
117 1.2 pooka pc_write->pm_resid);
118 1.2 pooka
119 1.1 pooka pc_write->pm_data[pc_write->pm_resid] = '\0';
120 1.1 pooka printf("got via write: %s", pc_write->pm_data);
121 1.1 pooka pdr->pdr_pth.pth_framelen =
122 1.1 pooka sizeof(struct pud_creq_write);
123 1.1 pooka pc_write->pm_resid = 0;
124 1.1 pooka }
125 1.1 pooka break;
126 1.1 pooka
127 1.1 pooka default:
128 1.1 pooka abort();
129 1.1 pooka }
130 1.1 pooka
131 1.1 pooka n = write(fd, pdr, pdr->pdr_pth.pth_framelen);
132 1.1 pooka printf("wrote %d %d\n", n, errno);
133 1.1 pooka }
134 1.1 pooka }
135