~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to hw/xfree86/os-support/bus/Sbus.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * SBUS and OpenPROM access functions.
 
3
 *
 
4
 * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
 
5
 *
 
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 
7
 * of this software and associated documentation files (the "Software"), to deal
 
8
 * in the Software without restriction, including without limitation the rights
 
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 
10
 * copies of the Software, and to permit persons to whom the Software is
 
11
 * furnished to do so, subject to the following conditions:
 
12
 *
 
13
 * The above copyright notice and this permission notice shall be included in
 
14
 * all copies or substantial portions of the Software.
 
15
 *
 
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
19
 * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
 
20
 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 
21
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 
22
 */
 
23
/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Sbus.c,v 1.2tsi Exp $ */
 
24
 
 
25
#ifdef HAVE_XORG_CONFIG_H
 
26
#include <xorg-config.h>
 
27
#endif
 
28
 
 
29
#include <fcntl.h>
 
30
#include <stdio.h>
 
31
#include <unistd.h>
 
32
#include <stdlib.h>
 
33
#include <sys/ioctl.h>
 
34
#include <sys/mman.h>
 
35
#ifdef sun
 
36
#include <sys/utsname.h>
 
37
#endif
 
38
#include "xf86.h"
 
39
#include "xf86Priv.h"
 
40
#include "xf86_OSlib.h"
 
41
 
 
42
#include "xf86sbusBus.h"
 
43
#include "xf86Sbus.h"
 
44
 
 
45
int promRootNode;
 
46
 
 
47
static int promFd = -1;
 
48
static int promCurrentNode;
 
49
static int promOpenCount = 0;
 
50
static int promP1275 = -1;
 
51
#define MAX_PROP        128
 
52
#define MAX_VAL         (4096-128-4)
 
53
static struct openpromio *promOpio;
 
54
 
 
55
sbusDevicePtr *xf86SbusInfo = NULL;
 
56
 
 
57
struct sbus_devtable sbusDeviceTable[] = {
 
58
    { SBUS_DEVICE_BW2, FBTYPE_SUN2BW, "bwtwo", "Sun Monochrome (bwtwo)" },
 
59
    { SBUS_DEVICE_CG2, FBTYPE_SUN2COLOR, "cgtwo", "Sun Color2 (cgtwo)" },
 
60
    { SBUS_DEVICE_CG3, FBTYPE_SUN3COLOR, "cgthree", "Sun Color3 (cgthree)" },
 
61
    { SBUS_DEVICE_CG4, FBTYPE_SUN4COLOR, "cgfour", "Sun Color4 (cgfour)" },
 
62
    { SBUS_DEVICE_CG6, FBTYPE_SUNFAST_COLOR, "cgsix", "Sun GX" },
 
63
    { SBUS_DEVICE_CG8, FBTYPE_MEMCOLOR, "cgeight", "Sun CG8/RasterOps" },
 
64
    { SBUS_DEVICE_CG12, FBTYPE_SUNGP3, "cgtwelve", "Sun GS (cgtwelve)" },
 
65
    { SBUS_DEVICE_CG14, FBTYPE_MDICOLOR, "cgfourteen", "Sun SX" },
 
66
    { SBUS_DEVICE_GT, FBTYPE_SUNGT, "gt", "Sun Graphics Tower" },
 
67
    { SBUS_DEVICE_MGX, -1, "mgx", "Quantum 3D MGXplus" },
 
68
    { SBUS_DEVICE_LEO, FBTYPE_SUNLEO, "leo", "Sun ZX or Turbo ZX" },
 
69
    { SBUS_DEVICE_TCX, FBTYPE_TCXCOLOR, "tcx", "Sun TCX" },
 
70
    { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "ffb", "Sun FFB" },
 
71
    { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "afb", "Sun Elite3D" },
 
72
    { 0, 0, NULL }
 
73
};
 
74
 
 
75
int
 
76
promGetSibling(int node)
 
77
{
 
78
    promOpio->oprom_size = sizeof(int);
 
79
 
 
80
    if (node == -1) return 0;
 
81
    *(int *)promOpio->oprom_array = node;
 
82
    if (ioctl(promFd, OPROMNEXT, promOpio) < 0)
 
83
        return 0;
 
84
    promCurrentNode = *(int *)promOpio->oprom_array;
 
85
    return *(int *)promOpio->oprom_array;
 
86
}
 
87
 
 
88
int
 
89
promGetChild(int node)
 
90
{
 
91
    promOpio->oprom_size = sizeof(int);
 
92
 
 
93
    if (!node || node == -1) return 0;
 
94
    *(int *)promOpio->oprom_array = node;
 
95
    if (ioctl(promFd, OPROMCHILD, promOpio) < 0)
 
96
        return 0;
 
97
    promCurrentNode = *(int *)promOpio->oprom_array;
 
98
    return *(int *)promOpio->oprom_array;
 
99
}
 
100
 
 
101
char *
 
102
promGetProperty(const char *prop, int *lenp)
 
103
{
 
104
    promOpio->oprom_size = MAX_VAL;
 
105
 
 
106
    strcpy(promOpio->oprom_array, prop);
 
107
    if (ioctl(promFd, OPROMGETPROP, promOpio) < 0)
 
108
        return 0;
 
109
    if (lenp) *lenp = promOpio->oprom_size;
 
110
    return promOpio->oprom_array;
 
111
}
 
112
 
 
113
int
 
114
promGetBool(const char *prop)
 
115
{
 
116
    promOpio->oprom_size = 0;
 
117
 
 
118
    *(int *)promOpio->oprom_array = 0;
 
119
    for (;;) {
 
120
        promOpio->oprom_size = MAX_PROP;
 
121
        if (ioctl(promFd, OPROMNXTPROP, promOpio) < 0)
 
122
            return 0;
 
123
        if (!promOpio->oprom_size)
 
124
            return 0;
 
125
        if (!strcmp(promOpio->oprom_array, prop))
 
126
            return 1;
 
127
    }
 
128
}
 
129
 
 
130
#define PROM_NODE_SIBLING 0x01
 
131
#define PROM_NODE_PREF    0x02
 
132
#define PROM_NODE_SBUS    0x04
 
133
#define PROM_NODE_EBUS    0x08
 
134
#define PROM_NODE_PCI     0x10
 
135
 
 
136
static int
 
137
promSetNode(sbusPromNodePtr pnode)
 
138
{
 
139
    int node;
 
140
 
 
141
    if (!pnode->node || pnode->node == -1)
 
142
        return -1;
 
143
    if (pnode->cookie[0] & PROM_NODE_SIBLING)
 
144
        node = promGetSibling(pnode->cookie[1]);
 
145
    else
 
146
        node = promGetChild(pnode->cookie[1]);
 
147
    if (pnode->node != node)
 
148
        return -1;
 
149
    return 0;
 
150
}
 
151
 
 
152
static void
 
153
promIsP1275(void)
 
154
{
 
155
#ifdef linux
 
156
    FILE *f;
 
157
    char buffer[1024];
 
158
 
 
159
    if (promP1275 != -1)
 
160
        return;
 
161
    promP1275 = 0;
 
162
    f = fopen("/proc/cpuinfo","r");
 
163
    if (!f) return;
 
164
    while (fgets(buffer, 1024, f) != NULL)
 
165
        if (!strncmp (buffer, "type", 4) && strstr (buffer, "sun4u")) {
 
166
            promP1275 = 1;
 
167
            break;
 
168
        }
 
169
    fclose(f);
 
170
#elif defined(sun)
 
171
    struct utsname buffer;
 
172
 
 
173
    if ((uname(&buffer) >= 0) && !strcmp(buffer.machine, "sun4u"))
 
174
        promP1275 = TRUE;
 
175
    else
 
176
        promP1275 = FALSE;
 
177
#elif defined(__FreeBSD__)
 
178
    promP1275 = TRUE;
 
179
#else
 
180
#error Missing promIsP1275() function for this OS
 
181
#endif
 
182
}
 
183
 
 
184
void
 
185
sparcPromClose(void)
 
186
{
 
187
    if (promOpenCount > 1) {
 
188
        promOpenCount--;
 
189
        return;
 
190
    }
 
191
    if (promFd != -1) {
 
192
        close(promFd);
 
193
        promFd = -1;
 
194
    }
 
195
    if (promOpio) {
 
196
        xfree(promOpio);
 
197
        promOpio = NULL;
 
198
    }
 
199
    promOpenCount = 0;
 
200
}
 
201
 
 
202
int
 
203
sparcPromInit(void)
 
204
{
 
205
    if (promOpenCount) {
 
206
        promOpenCount++;
 
207
        return 0;
 
208
    }
 
209
    promFd = open("/dev/openprom", O_RDONLY, 0);
 
210
    if (promFd == -1)
 
211
        return -1;
 
212
    promOpio = (struct openpromio *)xalloc(4096);
 
213
    if (!promOpio) {
 
214
        sparcPromClose();
 
215
        return -1;
 
216
    }
 
217
    promRootNode = promGetSibling(0);
 
218
    if (!promRootNode) {
 
219
        sparcPromClose();
 
220
        return -1;
 
221
    }
 
222
    promIsP1275();
 
223
    promOpenCount++;
 
224
 
 
225
    return 0;
 
226
}
 
227
 
 
228
char *
 
229
sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp)
 
230
{
 
231
    if (promSetNode(pnode))
 
232
        return NULL;
 
233
    return promGetProperty(prop, lenp);
 
234
}
 
235
 
 
236
int
 
237
sparcPromGetBool(sbusPromNodePtr pnode, const char *prop)
 
238
{
 
239
    if (promSetNode(pnode))
 
240
        return 0;
 
241
    return promGetBool(prop);
 
242
}
 
243
 
 
244
static void
 
245
promWalkAssignNodes(int node, int oldnode, int flags, sbusDevicePtr *devicePtrs)
 
246
{
 
247
    int nextnode;
 
248
    int len, sbus = flags & PROM_NODE_SBUS;
 
249
    char *prop;
 
250
    int devId, i, j;
 
251
    sbusPromNode pNode, pNode2;
 
252
 
 
253
    prop = promGetProperty("device_type", &len);
 
254
    if (prop && (len > 0)) do {
 
255
        if (!strcmp(prop, "display")) {
 
256
            prop = promGetProperty("name", &len);
 
257
            if (!prop || len <= 0)
 
258
                break;
 
259
            while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',')
 
260
                prop++;
 
261
            for (i = 0; sbusDeviceTable[i].devId; i++)
 
262
                if (!strcmp(prop, sbusDeviceTable[i].promName))
 
263
                    break;
 
264
            devId = sbusDeviceTable[i].devId;
 
265
            if (!devId)
 
266
                break;
 
267
            if (!sbus) {
 
268
                if (devId == SBUS_DEVICE_FFB) {
 
269
                    /*
 
270
                     * All /SUNW,ffb outside of SBUS tree come before all
 
271
                     * /SUNW,afb outside of SBUS tree in Linux.
 
272
                     */
 
273
                    if (!strcmp(prop, "afb"))
 
274
                        flags |= PROM_NODE_PREF;
 
275
                } else if (devId != SBUS_DEVICE_CG14)
 
276
                    break;
 
277
            }
 
278
            for (i = 0; i < 32; i++) {
 
279
                if (!devicePtrs[i] || devicePtrs[i]->devId != devId)
 
280
                    continue;
 
281
                if (devicePtrs[i]->node.node) {
 
282
                    if ((devicePtrs[i]->node.cookie[0] & ~PROM_NODE_SIBLING) <=
 
283
                        (flags & ~PROM_NODE_SIBLING))
 
284
                        continue;
 
285
                    for (j = i + 1, pNode = devicePtrs[i]->node; j < 32; j++) {
 
286
                        if (!devicePtrs[j] || devicePtrs[j]->devId != devId)
 
287
                            continue;
 
288
                        pNode2 = devicePtrs[j]->node;
 
289
                        devicePtrs[j]->node = pNode;
 
290
                        pNode = pNode2;
 
291
                    }
 
292
                }
 
293
                devicePtrs[i]->node.node = node;
 
294
                devicePtrs[i]->node.cookie[0] = flags;
 
295
                devicePtrs[i]->node.cookie[1] = oldnode;
 
296
                break;
 
297
            }
 
298
            break;
 
299
        }
 
300
    } while (0);
 
301
 
 
302
    prop = promGetProperty("name", &len);
 
303
    if (prop && len > 0) {
 
304
        if (!strcmp(prop, "sbus") || !strcmp(prop, "sbi"))
 
305
            sbus = PROM_NODE_SBUS;
 
306
    }
 
307
 
 
308
    nextnode = promGetChild(node);
 
309
    if (nextnode)
 
310
        promWalkAssignNodes(nextnode, node, sbus, devicePtrs);
 
311
 
 
312
    nextnode = promGetSibling(node);
 
313
    if (nextnode)
 
314
        promWalkAssignNodes(nextnode, node, PROM_NODE_SIBLING | sbus, devicePtrs);
 
315
}
 
316
 
 
317
void
 
318
sparcPromAssignNodes(void)
 
319
{
 
320
    sbusDevicePtr psdp, *psdpp;
 
321
    int n, holes = 0, i, j;
 
322
    FILE *f;
 
323
    sbusDevicePtr devicePtrs[32];
 
324
 
 
325
    (void)memset(devicePtrs, 0, sizeof(devicePtrs));
 
326
    for (psdpp = xf86SbusInfo, n = 0; (psdp = *psdpp); psdpp++, n++) {
 
327
        if (psdp->fbNum != n)
 
328
            holes = 1;
 
329
        devicePtrs[psdp->fbNum] = psdp;
 
330
    }
 
331
    if (holes && (f = fopen("/proc/fb", "r")) != NULL) {
 
332
        /* We could not open one of fb devices, check /proc/fb to see what
 
333
         * were the types of the cards missed. */
 
334
        char buffer[64];
 
335
        int fbNum, devId;
 
336
        static struct {
 
337
            int devId;
 
338
            char *prefix;
 
339
        } procFbPrefixes[] = {
 
340
            { SBUS_DEVICE_BW2, "BWtwo" },
 
341
            { SBUS_DEVICE_CG14, "CGfourteen" },
 
342
            { SBUS_DEVICE_CG6, "CGsix" },
 
343
            { SBUS_DEVICE_CG3, "CGthree" },
 
344
            { SBUS_DEVICE_FFB, "Creator" },
 
345
            { SBUS_DEVICE_FFB, "Elite 3D" },
 
346
            { SBUS_DEVICE_LEO, "Leo" },
 
347
            { SBUS_DEVICE_TCX, "TCX" },
 
348
            { 0, NULL },
 
349
        };
 
350
 
 
351
        while (fscanf(f, "%d %63s\n", &fbNum, buffer) == 2) {
 
352
            for (i = 0; procFbPrefixes[i].devId; i++)
 
353
                if (! strncmp(procFbPrefixes[i].prefix, buffer,
 
354
                      strlen(procFbPrefixes[i].prefix)))
 
355
                    break;
 
356
            devId = procFbPrefixes[i].devId;
 
357
            if (! devId) continue;
 
358
            if (devicePtrs[fbNum]) {
 
359
                if (devicePtrs[fbNum]->devId != devId)
 
360
                    xf86ErrorF("Inconsistent /proc/fb with FBIOGATTR\n");
 
361
            } else if (!devicePtrs[fbNum]) {
 
362
                devicePtrs[fbNum] = psdp = xnfcalloc(sizeof (sbusDevice), 1);
 
363
                psdp->devId = devId;
 
364
                psdp->fbNum = fbNum;
 
365
                psdp->fd = -2;
 
366
            }
 
367
        }
 
368
        fclose(f);
 
369
    }
 
370
    promGetSibling(0);
 
371
    promWalkAssignNodes(promRootNode, 0, PROM_NODE_PREF, devicePtrs);
 
372
    for (i = 0, j = 0; i < 32; i++)
 
373
        if (devicePtrs[i] && devicePtrs[i]->fbNum == -1)
 
374
            j++;
 
375
    xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1));
 
376
    for (i = 0, psdpp = xf86SbusInfo; i < 32; i++)
 
377
        if (devicePtrs[i]) {
 
378
            if (devicePtrs[i]->fbNum == -1) {
 
379
                memmove(psdpp + 1, psdpp, sizeof(psdpp) * (n + 1));
 
380
                *psdpp = devicePtrs[i];
 
381
            } else
 
382
                n--;
 
383
        }
 
384
}
 
385
 
 
386
static char *
 
387
promGetReg(int type)
 
388
{
 
389
    char *prop;
 
390
    int len;
 
391
    static char regstr[40];
 
392
 
 
393
    regstr[0] = 0;
 
394
    prop = promGetProperty("reg", &len);
 
395
    if (prop && len >= 4) {
 
396
        unsigned int *reg = (unsigned int *)prop;
 
397
        if (!promP1275 || (type == PROM_NODE_SBUS) || (type == PROM_NODE_EBUS))
 
398
            sprintf (regstr, "@%x,%x", reg[0], reg[1]);
 
399
        else if (type == PROM_NODE_PCI) {
 
400
            if ((reg[0] >> 8) & 7)
 
401
                sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7);
 
402
            else
 
403
                sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f);
 
404
        } else if (len == 4)
 
405
            sprintf (regstr, "@%x", reg[0]);
 
406
        else {
 
407
            unsigned int regs[2];
 
408
 
 
409
            /* Things get more complicated on UPA. If upa-portid exists,
 
410
               then address is @upa-portid,second-int-in-reg, otherwise
 
411
               it is @first-int-in-reg/16,second-int-in-reg (well, probably
 
412
               upa-portid always exists, but just to be safe). */
 
413
            memcpy (regs, reg, sizeof(regs));
 
414
            prop = promGetProperty("upa-portid", &len);
 
415
            if (prop && len == 4) {
 
416
                reg = (unsigned int *)prop;
 
417
                sprintf (regstr, "@%x,%x", reg[0], regs[1]);
 
418
            } else
 
419
                sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]);
 
420
        }
 
421
    }
 
422
    return regstr;
 
423
}
 
424
 
 
425
static int
 
426
promWalkNode2Pathname(char *path, int parent, int node, int searchNode, int type)
 
427
{
 
428
    int nextnode;
 
429
    int len, ntype = type;
 
430
    char *prop, *p;
 
431
 
 
432
    prop = promGetProperty("name", &len);
 
433
    *path = '/';
 
434
    if (!prop || len <= 0)
 
435
        return 0;
 
436
    if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
 
437
        ntype = PROM_NODE_SBUS;
 
438
    else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
 
439
        ntype = PROM_NODE_EBUS;
 
440
    else if (!strcmp(prop, "pci") && !type)
 
441
        ntype = PROM_NODE_PCI;
 
442
    strcpy (path + 1, prop);
 
443
    p = promGetReg(type);
 
444
    if (*p)
 
445
        strcat (path, p);
 
446
    if (node == searchNode)
 
447
        return 1;
 
448
    nextnode = promGetChild(node);
 
449
    if (nextnode &&
 
450
        promWalkNode2Pathname(strchr(path, 0), node, nextnode, searchNode, ntype))
 
451
        return 1;
 
452
    nextnode = promGetSibling(node);
 
453
    if (nextnode &&
 
454
        promWalkNode2Pathname(path, parent, nextnode, searchNode, type))
 
455
        return 1;
 
456
    return 0;
 
457
}
 
458
 
 
459
char *
 
460
sparcPromNode2Pathname(sbusPromNodePtr pnode)
 
461
{
 
462
    char *ret;
 
463
 
 
464
    if (!pnode->node) return NULL;
 
465
    ret = xalloc(4096);
 
466
    if (!ret) return NULL;
 
467
    if (promWalkNode2Pathname(ret, promRootNode, promGetChild(promRootNode), pnode->node, 0))
 
468
        return ret;
 
469
    xfree(ret);
 
470
    return NULL;
 
471
}
 
472
 
 
473
static int
 
474
promWalkPathname2Node(char *name, char *regstr, int parent, int type)
 
475
{
 
476
    int len, node, ret;
 
477
    char *prop, *p;
 
478
 
 
479
    for (;;) {
 
480
        prop = promGetProperty("name", &len);
 
481
        if (!prop || len <= 0)
 
482
            return 0;
 
483
        if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type)
 
484
            type = PROM_NODE_SBUS;
 
485
        else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI)
 
486
            type = PROM_NODE_EBUS;
 
487
        else if (!strcmp(prop, "pci") && !type)
 
488
            type = PROM_NODE_PCI;
 
489
        for (node = promGetChild(parent); node; node = promGetSibling(node)) {
 
490
            prop = promGetProperty("name", &len);
 
491
            if (!prop || len <= 0)
 
492
                continue;
 
493
            if (*name && strcmp(name, prop))
 
494
                continue;
 
495
            if (*regstr) {
 
496
                p = promGetReg(type);
 
497
                if (! *p || strcmp(p + 1, regstr))
 
498
                    continue;
 
499
            }
 
500
            break;
 
501
        }
 
502
        if (!node) {
 
503
            for (node = promGetChild(parent); node; node = promGetSibling(node)) {
 
504
                ret = promWalkPathname2Node(name, regstr, node, type);
 
505
                if (ret) return ret;
 
506
            }
 
507
            return 0;
 
508
        }
 
509
        name = strchr(regstr, 0) + 1;
 
510
        if (! *name)
 
511
            return node;
 
512
        p = strchr(name, '/');
 
513
        if (p)
 
514
            *p = 0;
 
515
        else
 
516
            p = strchr(name, 0);
 
517
        regstr = strchr(name, '@');
 
518
        if (regstr)
 
519
            *regstr++ = 0;
 
520
        else
 
521
            regstr = p;
 
522
        if (name == regstr)
 
523
            return 0;
 
524
        parent = node;
 
525
    }
 
526
}
 
527
 
 
528
int
 
529
sparcPromPathname2Node(const char *pathName)
 
530
{
 
531
    int i;
 
532
    char *name, *regstr, *p;
 
533
 
 
534
    i = strlen(pathName);
 
535
    name = xalloc(i + 2);
 
536
    if (! name) return 0;
 
537
    strcpy (name, pathName);
 
538
    name [i + 1] = 0;
 
539
    if (name[0] != '/')
 
540
        return 0;
 
541
    p = strchr(name + 1, '/');
 
542
    if (p)
 
543
        *p = 0;
 
544
    else
 
545
        p = strchr(name, 0);
 
546
    regstr = strchr(name, '@');
 
547
    if (regstr)
 
548
        *regstr++ = 0;
 
549
    else
 
550
        regstr = p;
 
551
    if (name + 1 == regstr)
 
552
        return 0;
 
553
    promGetSibling(0);
 
554
    i = promWalkPathname2Node(name + 1, regstr, promRootNode, 0);
 
555
    xfree(name);
 
556
    return i;
 
557
}
 
558
 
 
559
pointer
 
560
xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size)
 
561
{
 
562
    pointer ret;
 
563
    unsigned long pagemask = xf86getpagesize() - 1;
 
564
    unsigned long off = offset & ~pagemask;
 
565
    unsigned long len = ((offset + size + pagemask) & ~pagemask) - off;
 
566
 
 
567
    if (psdp->fd == -1) {
 
568
        psdp->fd = open(psdp->device, O_RDWR);
 
569
        if (psdp->fd == -1)
 
570
            return NULL;
 
571
    } else if (psdp->fd < 0)
 
572
        return NULL;
 
573
 
 
574
    ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_PRIVATE,
 
575
                          psdp->fd, off);
 
576
    if (ret == (pointer) -1) {
 
577
        ret = (pointer) mmap (NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED,
 
578
                              psdp->fd, off);
 
579
    }
 
580
    if (ret == (pointer) -1)
 
581
        return NULL;
 
582
 
 
583
    return (char *)ret + (offset - off);
 
584
}
 
585
 
 
586
void
 
587
xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size)
 
588
{
 
589
    unsigned long mask = xf86getpagesize() - 1;
 
590
    unsigned long base = (unsigned long)addr & ~mask;
 
591
    unsigned long len = (((unsigned long)addr + size + mask) & ~mask) - base;
 
592
 
 
593
    munmap ((pointer)base, len);
 
594
}
 
595
 
 
596
/* Tell OS that we are driving the HW cursor ourselves. */
 
597
void
 
598
xf86SbusHideOsHwCursor(sbusDevicePtr psdp)
 
599
{
 
600
    struct fbcursor fbcursor;
 
601
    unsigned char zeros[8];
 
602
 
 
603
    memset(&fbcursor, 0, sizeof(fbcursor));
 
604
    memset(&zeros, 0, sizeof(zeros));
 
605
    fbcursor.cmap.count = 2;
 
606
    fbcursor.cmap.red = zeros;
 
607
    fbcursor.cmap.green = zeros;
 
608
    fbcursor.cmap.blue = zeros;
 
609
    fbcursor.image = (char *)zeros;
 
610
    fbcursor.mask = (char *)zeros;
 
611
    fbcursor.size.x = 32;
 
612
    fbcursor.size.y = 1;
 
613
    fbcursor.set = FB_CUR_SETALL;
 
614
    ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
 
615
}
 
616
 
 
617
/* Set HW cursor colormap. */
 
618
void
 
619
xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg)
 
620
{
 
621
    struct fbcursor fbcursor;
 
622
    unsigned char red[2], green[2], blue[2];
 
623
 
 
624
    memset(&fbcursor, 0, sizeof(fbcursor));
 
625
    red[0] = bg >> 16;
 
626
    green[0] = bg >> 8;
 
627
    blue[0] = bg;
 
628
    red[1] = fg >> 16;
 
629
    green[1] = fg >> 8;
 
630
    blue[1] = fg;
 
631
    fbcursor.cmap.count = 2;
 
632
    fbcursor.cmap.red = red;
 
633
    fbcursor.cmap.green = green;
 
634
    fbcursor.cmap.blue = blue;
 
635
    fbcursor.set = FB_CUR_SETCMAP;
 
636
    ioctl(psdp->fd, FBIOSCURSOR, &fbcursor);
 
637
}