Initial import from FreeBSD RELENG_4:
[dragonfly.git] / sys / dev / drm / drm_sysctl.h
1 /*
2  * $FreeBSD: src/sys/dev/drm/drm_sysctl.h,v 1.3.2.1 2003/04/26 07:05:29 anholt Exp $
3  */
4
5 #ifdef __FreeBSD__
6
7 #include <sys/sysctl.h>
8
9 static int         DRM(name_info)DRM_SYSCTL_HANDLER_ARGS;
10 static int         DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS;
11 static int         DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS;
12 static int         DRM(bufs_info)DRM_SYSCTL_HANDLER_ARGS;
13
14 struct DRM(sysctl_list) {
15         const char *name;
16         int        (*f) DRM_SYSCTL_HANDLER_ARGS;
17 } DRM(sysctl_list)[] = {
18         { "name",    DRM(name_info)    },
19         { "mem",     DRM(mem_info)     },
20         { "vm",      DRM(vm_info)      },
21         { "clients", DRM(clients_info) },
22         { "bufs",    DRM(bufs_info)    },
23 };
24 #define DRM_SYSCTL_ENTRIES (sizeof(DRM(sysctl_list))/sizeof(DRM(sysctl_list)[0]))
25
26 struct drm_sysctl_info {
27         struct sysctl_ctx_list ctx;
28         char                   name[2];
29 };
30
31 int DRM(sysctl_init)(drm_device_t *dev)
32 {
33         struct drm_sysctl_info *info;
34         struct sysctl_oid *oid;
35         struct sysctl_oid *top, *drioid;
36         int               i;
37
38         info = DRM(alloc)(sizeof *info, DRM_MEM_DRIVER);
39         if ( !info )
40                 return 1;
41         bzero(info, sizeof *info);
42         dev->sysctl = info;
43
44         /* Add the sysctl node for DRI if it doesn't already exist */
45         drioid = SYSCTL_ADD_NODE( &info->ctx, &sysctl__hw_children, OID_AUTO, "dri", CTLFLAG_RW, NULL, "DRI Graphics");
46         if (!drioid)
47                 return 1;
48
49         /* Find the next free slot under hw.dri */
50         i = 0;
51         SLIST_FOREACH(oid, SYSCTL_CHILDREN(drioid), oid_link) {
52                 if (i <= oid->oid_arg2)
53                         i = oid->oid_arg2 + 1;
54         }
55         if (i>9)
56                 return 1;
57         
58         /* Add the hw.dri.x for our device */
59         info->name[0] = '0' + i;
60         info->name[1] = 0;
61         top = SYSCTL_ADD_NODE( &info->ctx, SYSCTL_CHILDREN(drioid), OID_AUTO, info->name, CTLFLAG_RW, NULL, NULL);
62         if (!top)
63                 return 1;
64         
65         for (i = 0; i < DRM_SYSCTL_ENTRIES; i++) {
66                 oid = sysctl_add_oid( &info->ctx, 
67                         SYSCTL_CHILDREN(top), 
68                         OID_AUTO, 
69                         DRM(sysctl_list)[i].name, 
70                         CTLTYPE_INT | CTLFLAG_RD, 
71                         dev, 
72                         0, 
73                         DRM(sysctl_list)[i].f, 
74                         "A", 
75                         NULL);
76                 if (!oid)
77                         return 1;
78         }
79         return 0;
80 }
81
82 int DRM(sysctl_cleanup)(drm_device_t *dev)
83 {
84         int error;
85         error = sysctl_ctx_free( &dev->sysctl->ctx );
86
87         DRM(free)(dev->sysctl, sizeof *dev->sysctl, DRM_MEM_DRIVER);
88         dev->sysctl = NULL;
89
90         return error;
91 }
92
93 static int DRM(name_info)DRM_SYSCTL_HANDLER_ARGS
94 {
95         drm_device_t *dev = arg1;
96         char buf[128];
97         int error;
98
99         if (dev->unique) {
100                 DRM_SYSCTL_PRINT("%s 0x%x %s\n",
101                                dev->name, dev2udev(dev->devnode), dev->unique);
102         } else {
103                 DRM_SYSCTL_PRINT("%s 0x%x\n", dev->name, dev2udev(dev->devnode));
104         }
105
106         SYSCTL_OUT(req, "", 1);
107
108         return 0;
109 }
110
111 static int DRM(_vm_info)DRM_SYSCTL_HANDLER_ARGS
112 {
113         drm_device_t *dev = arg1;
114         drm_local_map_t    *map;
115         drm_map_list_entry_t    *listentry;
116         const char   *types[] = { "FB", "REG", "SHM" };
117         const char   *type;
118         int          i=0;
119         char         buf[128];
120         int          error;
121
122         DRM_SYSCTL_PRINT("slot   offset       size type flags    "
123                          "address mtrr\n\n");
124         error = SYSCTL_OUT(req, buf, strlen(buf));
125         if (error) return error;
126
127         if (dev->maplist != NULL) {
128                 TAILQ_FOREACH(listentry, dev->maplist, link) {
129                         map = listentry->map;
130                         if (map->type < 0 || map->type > 2) type = "??";
131                         else                                type = types[map->type];
132                         DRM_SYSCTL_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
133                                          i,
134                                          map->offset,
135                                          map->size,
136                                          type,
137                                          map->flags,
138                                          (unsigned long)map->handle);
139                         if (map->mtrr < 0) {
140                                 DRM_SYSCTL_PRINT("none\n");
141                         } else {
142                                 DRM_SYSCTL_PRINT("%4d\n", map->mtrr);
143                         }
144                         i++;
145                 }
146         }
147         SYSCTL_OUT(req, "", 1);
148
149         return 0;
150 }
151
152 static int DRM(vm_info)DRM_SYSCTL_HANDLER_ARGS
153 {
154         drm_device_t *dev = arg1;
155         int          ret;
156
157         DRM_LOCK;
158         ret = DRM(_vm_info)(oidp, arg1, arg2, req);
159         DRM_UNLOCK;
160
161         return ret;
162 }
163
164
165 /* drm_bufs_info is called whenever a process reads
166    hw.dri.0.bufs. */
167
168 static int DRM(_bufs_info) DRM_SYSCTL_HANDLER_ARGS
169 {
170         drm_device_t     *dev = arg1;
171         drm_device_dma_t *dma = dev->dma;
172         int              i;
173         char             buf[128];
174         int              error;
175
176         if (!dma)       return 0;
177         DRM_SYSCTL_PRINT(" o     size count  free        segs pages    kB\n\n");
178         for (i = 0; i <= DRM_MAX_ORDER; i++) {
179                 if (dma->bufs[i].buf_count)
180                         DRM_SYSCTL_PRINT("%2d %8d %5d %5d %5d %5d %5d\n",
181                                        i,
182                                        dma->bufs[i].buf_size,
183                                        dma->bufs[i].buf_count,
184                                        atomic_read(&dma->bufs[i]
185                                                    .freelist.count),
186                                        dma->bufs[i].seg_count,
187                                        dma->bufs[i].seg_count
188                                        *(1 << dma->bufs[i].page_order),
189                                        (dma->bufs[i].seg_count
190                                         * (1 << dma->bufs[i].page_order))
191                                        * PAGE_SIZE / 1024);
192         }
193         DRM_SYSCTL_PRINT("\n");
194         for (i = 0; i < dma->buf_count; i++) {
195                 if (i && !(i%32)) DRM_SYSCTL_PRINT("\n");
196                 DRM_SYSCTL_PRINT(" %d", dma->buflist[i]->list);
197         }
198         DRM_SYSCTL_PRINT("\n");
199
200         SYSCTL_OUT(req, "", 1);
201         return 0;
202 }
203
204 static int DRM(bufs_info) DRM_SYSCTL_HANDLER_ARGS
205 {
206         drm_device_t *dev = arg1;
207         int          ret;
208
209         DRM_LOCK;
210         ret = DRM(_bufs_info)(oidp, arg1, arg2, req);
211         DRM_UNLOCK;
212         return ret;
213 }
214
215
216 static int DRM(_clients_info) DRM_SYSCTL_HANDLER_ARGS
217 {
218         drm_device_t *dev = arg1;
219         drm_file_t   *priv;
220         char         buf[128];
221         int          error;
222
223         DRM_SYSCTL_PRINT("a dev pid    uid      magic     ioctls\n\n");
224         TAILQ_FOREACH(priv, &dev->files, link) {
225                 DRM_SYSCTL_PRINT("%c %3d %5d %5d %10u %10lu\n",
226                                priv->authenticated ? 'y' : 'n',
227                                priv->minor,
228                                priv->pid,
229                                priv->uid,
230                                priv->magic,
231                                priv->ioctl_count);
232         }
233
234         SYSCTL_OUT(req, "", 1);
235         return 0;
236 }
237
238 static int DRM(clients_info)DRM_SYSCTL_HANDLER_ARGS
239 {
240         drm_device_t *dev = arg1;
241         int          ret;
242
243         DRM_LOCK;
244         ret = DRM(_clients_info)(oidp, arg1, arg2, req);
245         DRM_UNLOCK;
246         return ret;
247 }
248
249
250 #elif defined(__NetBSD__)
251 /* stub it out for now, sysctl is only for debugging */
252 int DRM(sysctl_init)(drm_device_t *dev)
253 {
254         return 0;
255 }
256
257 int DRM(sysctl_cleanup)(drm_device_t *dev)
258 {
259         return 0;
260 }
261 #endif