xref: /OK3568_Linux_fs/external/xserver/hw/xfree86/common/xf86sbusBus.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * SBUS bus-specific code.
3*4882a593Smuzhiyun  *
4*4882a593Smuzhiyun  * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com)
5*4882a593Smuzhiyun  *
6*4882a593Smuzhiyun  * Permission is hereby granted, free of charge, to any person obtaining a copy
7*4882a593Smuzhiyun  * of this software and associated documentation files (the "Software"), to deal
8*4882a593Smuzhiyun  * in the Software without restriction, including without limitation the rights
9*4882a593Smuzhiyun  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10*4882a593Smuzhiyun  * copies of the Software, and to permit persons to whom the Software is
11*4882a593Smuzhiyun  * furnished to do so, subject to the following conditions:
12*4882a593Smuzhiyun  *
13*4882a593Smuzhiyun  * The above copyright notice and this permission notice shall be included in
14*4882a593Smuzhiyun  * all copies or substantial portions of the Software.
15*4882a593Smuzhiyun  *
16*4882a593Smuzhiyun  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17*4882a593Smuzhiyun  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18*4882a593Smuzhiyun  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19*4882a593Smuzhiyun  * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20*4882a593Smuzhiyun  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21*4882a593Smuzhiyun  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22*4882a593Smuzhiyun  */
23*4882a593Smuzhiyun 
24*4882a593Smuzhiyun #ifdef HAVE_XORG_CONFIG_H
25*4882a593Smuzhiyun #include <xorg-config.h>
26*4882a593Smuzhiyun #endif
27*4882a593Smuzhiyun 
28*4882a593Smuzhiyun #include <ctype.h>
29*4882a593Smuzhiyun #include <stdio.h>
30*4882a593Smuzhiyun #include <unistd.h>
31*4882a593Smuzhiyun #include <X11/X.h>
32*4882a593Smuzhiyun #include "os.h"
33*4882a593Smuzhiyun #include "xf86.h"
34*4882a593Smuzhiyun #include "xf86Priv.h"
35*4882a593Smuzhiyun #include "xf86_OSlib.h"
36*4882a593Smuzhiyun #include "xf86cmap.h"
37*4882a593Smuzhiyun 
38*4882a593Smuzhiyun #include "xf86Bus.h"
39*4882a593Smuzhiyun 
40*4882a593Smuzhiyun #include "xf86sbusBus.h"
41*4882a593Smuzhiyun #include "xf86Sbus.h"
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun Bool sbusSlotClaimed = FALSE;
44*4882a593Smuzhiyun 
45*4882a593Smuzhiyun static int xf86nSbusInfo;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun static void
CheckSbusDevice(const char * device,int fbNum)48*4882a593Smuzhiyun CheckSbusDevice(const char *device, int fbNum)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun     int fd, i;
51*4882a593Smuzhiyun     struct fbgattr fbattr;
52*4882a593Smuzhiyun     sbusDevicePtr psdp;
53*4882a593Smuzhiyun 
54*4882a593Smuzhiyun     fd = open(device, O_RDONLY, 0);
55*4882a593Smuzhiyun     if (fd < 0)
56*4882a593Smuzhiyun         return;
57*4882a593Smuzhiyun     memset(&fbattr, 0, sizeof(fbattr));
58*4882a593Smuzhiyun     if (ioctl(fd, FBIOGATTR, &fbattr) < 0) {
59*4882a593Smuzhiyun         if (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0) {
60*4882a593Smuzhiyun             close(fd);
61*4882a593Smuzhiyun             return;
62*4882a593Smuzhiyun         }
63*4882a593Smuzhiyun     }
64*4882a593Smuzhiyun     close(fd);
65*4882a593Smuzhiyun     for (i = 0; sbusDeviceTable[i].devId; i++)
66*4882a593Smuzhiyun         if (sbusDeviceTable[i].fbType == fbattr.fbtype.fb_type)
67*4882a593Smuzhiyun             break;
68*4882a593Smuzhiyun     if (!sbusDeviceTable[i].devId)
69*4882a593Smuzhiyun         return;
70*4882a593Smuzhiyun     xf86SbusInfo =
71*4882a593Smuzhiyun         xnfreallocarray(xf86SbusInfo, ++xf86nSbusInfo + 1, sizeof(psdp));
72*4882a593Smuzhiyun     xf86SbusInfo[xf86nSbusInfo] = NULL;
73*4882a593Smuzhiyun     xf86SbusInfo[xf86nSbusInfo - 1] = psdp = xnfcalloc(sizeof(sbusDevice), 1);
74*4882a593Smuzhiyun     psdp->devId = sbusDeviceTable[i].devId;
75*4882a593Smuzhiyun     psdp->fbNum = fbNum;
76*4882a593Smuzhiyun     psdp->device = xnfstrdup(device);
77*4882a593Smuzhiyun     psdp->width = fbattr.fbtype.fb_width;
78*4882a593Smuzhiyun     psdp->height = fbattr.fbtype.fb_height;
79*4882a593Smuzhiyun     psdp->fd = -1;
80*4882a593Smuzhiyun }
81*4882a593Smuzhiyun 
82*4882a593Smuzhiyun void
xf86SbusProbe(void)83*4882a593Smuzhiyun xf86SbusProbe(void)
84*4882a593Smuzhiyun {
85*4882a593Smuzhiyun     int i, useProm = 0;
86*4882a593Smuzhiyun     char fbDevName[32];
87*4882a593Smuzhiyun     sbusDevicePtr psdp, *psdpp;
88*4882a593Smuzhiyun 
89*4882a593Smuzhiyun     xf86SbusInfo = malloc(sizeof(psdp));
90*4882a593Smuzhiyun     *xf86SbusInfo = NULL;
91*4882a593Smuzhiyun     for (i = 0; i < 32; i++) {
92*4882a593Smuzhiyun         snprintf(fbDevName, sizeof(fbDevName), "/dev/fb%d", i);
93*4882a593Smuzhiyun         CheckSbusDevice(fbDevName, i);
94*4882a593Smuzhiyun     }
95*4882a593Smuzhiyun     if (sparcPromInit() >= 0) {
96*4882a593Smuzhiyun         useProm = 1;
97*4882a593Smuzhiyun         sparcPromAssignNodes();
98*4882a593Smuzhiyun     }
99*4882a593Smuzhiyun     for (psdpp = xf86SbusInfo; (psdp = *psdpp); psdpp++) {
100*4882a593Smuzhiyun         for (i = 0; sbusDeviceTable[i].devId; i++)
101*4882a593Smuzhiyun             if (sbusDeviceTable[i].devId == psdp->devId)
102*4882a593Smuzhiyun                 psdp->descr = sbusDeviceTable[i].descr;
103*4882a593Smuzhiyun         /*
104*4882a593Smuzhiyun          * If we can use PROM information and found the PROM node for this
105*4882a593Smuzhiyun          * device, we can tell more about the card.
106*4882a593Smuzhiyun          */
107*4882a593Smuzhiyun         if (useProm && psdp->node.node) {
108*4882a593Smuzhiyun             char *prop, *promPath;
109*4882a593Smuzhiyun             int len, chiprev, vmsize;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun             switch (psdp->devId) {
112*4882a593Smuzhiyun             case SBUS_DEVICE_MGX:
113*4882a593Smuzhiyun                 prop = sparcPromGetProperty(&psdp->node, "fb_size", &len);
114*4882a593Smuzhiyun                 if (prop && len == 4 && *(int *) prop == 0x400000)
115*4882a593Smuzhiyun                     psdp->descr = "Quantum 3D MGXplus with 4M VRAM";
116*4882a593Smuzhiyun                 break;
117*4882a593Smuzhiyun             case SBUS_DEVICE_CG6:
118*4882a593Smuzhiyun                 chiprev = 0;
119*4882a593Smuzhiyun                 vmsize = 0;
120*4882a593Smuzhiyun                 prop = sparcPromGetProperty(&psdp->node, "chiprev", &len);
121*4882a593Smuzhiyun                 if (prop && len == 4)
122*4882a593Smuzhiyun                     chiprev = *(int *) prop;
123*4882a593Smuzhiyun                 prop = sparcPromGetProperty(&psdp->node, "vmsize", &len);
124*4882a593Smuzhiyun                 if (prop && len == 4)
125*4882a593Smuzhiyun                     vmsize = *(int *) prop;
126*4882a593Smuzhiyun                 switch (chiprev) {
127*4882a593Smuzhiyun                 case 1:
128*4882a593Smuzhiyun                 case 2:
129*4882a593Smuzhiyun                 case 3:
130*4882a593Smuzhiyun                 case 4:
131*4882a593Smuzhiyun                     psdp->descr = "Sun Double width GX";
132*4882a593Smuzhiyun                     break;
133*4882a593Smuzhiyun                 case 5:
134*4882a593Smuzhiyun                 case 6:
135*4882a593Smuzhiyun                 case 7:
136*4882a593Smuzhiyun                 case 8:
137*4882a593Smuzhiyun                 case 9:
138*4882a593Smuzhiyun                     psdp->descr = "Sun Single width GX";
139*4882a593Smuzhiyun                     break;
140*4882a593Smuzhiyun                 case 11:
141*4882a593Smuzhiyun                     switch (vmsize) {
142*4882a593Smuzhiyun                     case 2:
143*4882a593Smuzhiyun                         psdp->descr = "Sun Turbo GX with 1M VSIMM";
144*4882a593Smuzhiyun                         break;
145*4882a593Smuzhiyun                     case 4:
146*4882a593Smuzhiyun                         psdp->descr = "Sun Turbo GX Plus";
147*4882a593Smuzhiyun                         break;
148*4882a593Smuzhiyun                     default:
149*4882a593Smuzhiyun                         psdp->descr = "Sun Turbo GX";
150*4882a593Smuzhiyun                         break;
151*4882a593Smuzhiyun                     }
152*4882a593Smuzhiyun                 }
153*4882a593Smuzhiyun                 break;
154*4882a593Smuzhiyun             case SBUS_DEVICE_CG14:
155*4882a593Smuzhiyun                 prop = sparcPromGetProperty(&psdp->node, "reg", &len);
156*4882a593Smuzhiyun                 vmsize = 0;
157*4882a593Smuzhiyun                 if (prop && !(len % 12) && len > 0)
158*4882a593Smuzhiyun                     vmsize = *(int *) (prop + len - 4);
159*4882a593Smuzhiyun                 switch (vmsize) {
160*4882a593Smuzhiyun                 case 0x400000:
161*4882a593Smuzhiyun                     psdp->descr = "Sun SX with 4M VSIMM";
162*4882a593Smuzhiyun                     break;
163*4882a593Smuzhiyun                 case 0x800000:
164*4882a593Smuzhiyun                     psdp->descr = "Sun SX with 8M VSIMM";
165*4882a593Smuzhiyun                     break;
166*4882a593Smuzhiyun                 }
167*4882a593Smuzhiyun                 break;
168*4882a593Smuzhiyun             case SBUS_DEVICE_LEO:
169*4882a593Smuzhiyun                 prop = sparcPromGetProperty(&psdp->node, "model", &len);
170*4882a593Smuzhiyun                 if (prop && len > 0 && !strstr(prop, "501-2503"))
171*4882a593Smuzhiyun                     psdp->descr = "Sun Turbo ZX";
172*4882a593Smuzhiyun                 break;
173*4882a593Smuzhiyun             case SBUS_DEVICE_TCX:
174*4882a593Smuzhiyun                 if (sparcPromGetBool(&psdp->node, "tcx-8-bit"))
175*4882a593Smuzhiyun                     psdp->descr = "Sun TCX (8bit)";
176*4882a593Smuzhiyun                 else
177*4882a593Smuzhiyun                     psdp->descr = "Sun TCX (S24)";
178*4882a593Smuzhiyun                 break;
179*4882a593Smuzhiyun             case SBUS_DEVICE_FFB:
180*4882a593Smuzhiyun                 prop = sparcPromGetProperty(&psdp->node, "name", &len);
181*4882a593Smuzhiyun                 chiprev = 0;
182*4882a593Smuzhiyun                 prop = sparcPromGetProperty(&psdp->node, "board_type", &len);
183*4882a593Smuzhiyun                 if (prop && len == 4)
184*4882a593Smuzhiyun                     chiprev = *(int *) prop;
185*4882a593Smuzhiyun                 if (strstr(prop, "afb")) {
186*4882a593Smuzhiyun                     if (chiprev == 3)
187*4882a593Smuzhiyun                         psdp->descr = "Sun|Elite3D-M6 Horizontal";
188*4882a593Smuzhiyun                 }
189*4882a593Smuzhiyun                 else {
190*4882a593Smuzhiyun                     switch (chiprev) {
191*4882a593Smuzhiyun                     case 0x08:
192*4882a593Smuzhiyun                         psdp->descr = "Sun FFB 67MHz Creator";
193*4882a593Smuzhiyun                         break;
194*4882a593Smuzhiyun                     case 0x0b:
195*4882a593Smuzhiyun                         psdp->descr = "Sun FFB 67MHz Creator 3D";
196*4882a593Smuzhiyun                         break;
197*4882a593Smuzhiyun                     case 0x1b:
198*4882a593Smuzhiyun                         psdp->descr = "Sun FFB 75MHz Creator 3D";
199*4882a593Smuzhiyun                         break;
200*4882a593Smuzhiyun                     case 0x20:
201*4882a593Smuzhiyun                     case 0x28:
202*4882a593Smuzhiyun                         psdp->descr = "Sun FFB2 Vertical Creator";
203*4882a593Smuzhiyun                         break;
204*4882a593Smuzhiyun                     case 0x23:
205*4882a593Smuzhiyun                     case 0x2b:
206*4882a593Smuzhiyun                         psdp->descr = "Sun FFB2 Vertical Creator 3D";
207*4882a593Smuzhiyun                         break;
208*4882a593Smuzhiyun                     case 0x30:
209*4882a593Smuzhiyun                         psdp->descr = "Sun FFB2+ Vertical Creator";
210*4882a593Smuzhiyun                         break;
211*4882a593Smuzhiyun                     case 0x33:
212*4882a593Smuzhiyun                         psdp->descr = "Sun FFB2+ Vertical Creator 3D";
213*4882a593Smuzhiyun                         break;
214*4882a593Smuzhiyun                     case 0x40:
215*4882a593Smuzhiyun                     case 0x48:
216*4882a593Smuzhiyun                         psdp->descr = "Sun FFB2 Horizontal Creator";
217*4882a593Smuzhiyun                         break;
218*4882a593Smuzhiyun                     case 0x43:
219*4882a593Smuzhiyun                     case 0x4b:
220*4882a593Smuzhiyun                         psdp->descr = "Sun FFB2 Horizontal Creator 3D";
221*4882a593Smuzhiyun                         break;
222*4882a593Smuzhiyun                     }
223*4882a593Smuzhiyun                 }
224*4882a593Smuzhiyun                 break;
225*4882a593Smuzhiyun             }
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun             xf86Msg(X_PROBED, "SBUS:(0x%08x) %s", psdp->node.node, psdp->descr);
228*4882a593Smuzhiyun             promPath = sparcPromNode2Pathname(&psdp->node);
229*4882a593Smuzhiyun             if (promPath) {
230*4882a593Smuzhiyun                 xf86ErrorF(" at %s", promPath);
231*4882a593Smuzhiyun                 free(promPath);
232*4882a593Smuzhiyun             }
233*4882a593Smuzhiyun         }
234*4882a593Smuzhiyun         else
235*4882a593Smuzhiyun             xf86Msg(X_PROBED, "SBUS: %s", psdp->descr);
236*4882a593Smuzhiyun         xf86ErrorF("\n");
237*4882a593Smuzhiyun     }
238*4882a593Smuzhiyun     if (useProm)
239*4882a593Smuzhiyun         sparcPromClose();
240*4882a593Smuzhiyun }
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun /*
243*4882a593Smuzhiyun  * Parse a BUS ID string, and return the SBUS bus parameters if it was
244*4882a593Smuzhiyun  * in the correct format for a SBUS bus id.
245*4882a593Smuzhiyun  */
246*4882a593Smuzhiyun 
247*4882a593Smuzhiyun Bool
xf86ParseSbusBusString(const char * busID,int * fbNum)248*4882a593Smuzhiyun xf86ParseSbusBusString(const char *busID, int *fbNum)
249*4882a593Smuzhiyun {
250*4882a593Smuzhiyun     /*
251*4882a593Smuzhiyun      * The format is assumed to be one of:
252*4882a593Smuzhiyun      * "fbN", e.g. "fb1", which means the device corresponding to /dev/fbN
253*4882a593Smuzhiyun      * "nameN", e.g. "cgsix0", which means Nth instance of card NAME
254*4882a593Smuzhiyun      * "/prompath", e.g. "/sbus@0,10001000/cgsix@3,0" which is PROM pathname
255*4882a593Smuzhiyun      * to the device.
256*4882a593Smuzhiyun      */
257*4882a593Smuzhiyun 
258*4882a593Smuzhiyun     const char *id;
259*4882a593Smuzhiyun     int i, len;
260*4882a593Smuzhiyun 
261*4882a593Smuzhiyun     if (StringToBusType(busID, &id) != BUS_SBUS)
262*4882a593Smuzhiyun         return FALSE;
263*4882a593Smuzhiyun 
264*4882a593Smuzhiyun     if (*id != '/') {
265*4882a593Smuzhiyun         if (!strncmp(id, "fb", 2)) {
266*4882a593Smuzhiyun             if (!isdigit(id[2]))
267*4882a593Smuzhiyun                 return FALSE;
268*4882a593Smuzhiyun             *fbNum = atoi(id + 2);
269*4882a593Smuzhiyun             return TRUE;
270*4882a593Smuzhiyun         }
271*4882a593Smuzhiyun         else {
272*4882a593Smuzhiyun             sbusDevicePtr *psdpp;
273*4882a593Smuzhiyun             int devId;
274*4882a593Smuzhiyun 
275*4882a593Smuzhiyun             for (i = 0, len = 0; sbusDeviceTable[i].devId; i++) {
276*4882a593Smuzhiyun                 len = strlen(sbusDeviceTable[i].promName);
277*4882a593Smuzhiyun                 if (!strncmp(sbusDeviceTable[i].promName, id, len)
278*4882a593Smuzhiyun                     && isdigit(id[len]))
279*4882a593Smuzhiyun                     break;
280*4882a593Smuzhiyun             }
281*4882a593Smuzhiyun             devId = sbusDeviceTable[i].devId;
282*4882a593Smuzhiyun             if (!devId)
283*4882a593Smuzhiyun                 return FALSE;
284*4882a593Smuzhiyun             i = atoi(id + len);
285*4882a593Smuzhiyun             for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
286*4882a593Smuzhiyun                 if ((*psdpp)->devId != devId)
287*4882a593Smuzhiyun                     continue;
288*4882a593Smuzhiyun                 if (!i) {
289*4882a593Smuzhiyun                     *fbNum = (*psdpp)->fbNum;
290*4882a593Smuzhiyun                     return TRUE;
291*4882a593Smuzhiyun                 }
292*4882a593Smuzhiyun                 i--;
293*4882a593Smuzhiyun             }
294*4882a593Smuzhiyun         }
295*4882a593Smuzhiyun         return FALSE;
296*4882a593Smuzhiyun     }
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun     if (sparcPromInit() >= 0) {
299*4882a593Smuzhiyun         i = sparcPromPathname2Node(id);
300*4882a593Smuzhiyun         sparcPromClose();
301*4882a593Smuzhiyun         if (i) {
302*4882a593Smuzhiyun             sbusDevicePtr *psdpp;
303*4882a593Smuzhiyun 
304*4882a593Smuzhiyun             for (psdpp = xf86SbusInfo; *psdpp; ++psdpp) {
305*4882a593Smuzhiyun                 if ((*psdpp)->node.node == i) {
306*4882a593Smuzhiyun                     *fbNum = (*psdpp)->fbNum;
307*4882a593Smuzhiyun                     return TRUE;
308*4882a593Smuzhiyun                 }
309*4882a593Smuzhiyun             }
310*4882a593Smuzhiyun         }
311*4882a593Smuzhiyun     }
312*4882a593Smuzhiyun     return FALSE;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun 
315*4882a593Smuzhiyun /*
316*4882a593Smuzhiyun  * Compare a BUS ID string with a SBUS bus id.  Return TRUE if they match.
317*4882a593Smuzhiyun  */
318*4882a593Smuzhiyun 
319*4882a593Smuzhiyun Bool
xf86CompareSbusBusString(const char * busID,int fbNum)320*4882a593Smuzhiyun xf86CompareSbusBusString(const char *busID, int fbNum)
321*4882a593Smuzhiyun {
322*4882a593Smuzhiyun     int iFbNum;
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun     if (xf86ParseSbusBusString(busID, &iFbNum)) {
325*4882a593Smuzhiyun         return fbNum == iFbNum;
326*4882a593Smuzhiyun     }
327*4882a593Smuzhiyun     else {
328*4882a593Smuzhiyun         return FALSE;
329*4882a593Smuzhiyun     }
330*4882a593Smuzhiyun }
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun /*
333*4882a593Smuzhiyun  * Check if the slot requested is free.  If it is already in use, return FALSE.
334*4882a593Smuzhiyun  */
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun Bool
xf86CheckSbusSlot(int fbNum)337*4882a593Smuzhiyun xf86CheckSbusSlot(int fbNum)
338*4882a593Smuzhiyun {
339*4882a593Smuzhiyun     int i;
340*4882a593Smuzhiyun     EntityPtr p;
341*4882a593Smuzhiyun 
342*4882a593Smuzhiyun     for (i = 0; i < xf86NumEntities; i++) {
343*4882a593Smuzhiyun         p = xf86Entities[i];
344*4882a593Smuzhiyun         /* Check if this SBUS slot is taken */
345*4882a593Smuzhiyun         if (p->bus.type == BUS_SBUS && p->bus.id.sbus.fbNum == fbNum)
346*4882a593Smuzhiyun             return FALSE;
347*4882a593Smuzhiyun     }
348*4882a593Smuzhiyun 
349*4882a593Smuzhiyun     return TRUE;
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun 
352*4882a593Smuzhiyun /*
353*4882a593Smuzhiyun  * If the slot requested is already in use, return -1.
354*4882a593Smuzhiyun  * Otherwise, claim the slot for the screen requesting it.
355*4882a593Smuzhiyun  */
356*4882a593Smuzhiyun 
357*4882a593Smuzhiyun int
xf86ClaimSbusSlot(sbusDevicePtr psdp,DriverPtr drvp,GDevPtr dev,Bool active)358*4882a593Smuzhiyun xf86ClaimSbusSlot(sbusDevicePtr psdp, DriverPtr drvp, GDevPtr dev, Bool active)
359*4882a593Smuzhiyun {
360*4882a593Smuzhiyun     EntityPtr p = NULL;
361*4882a593Smuzhiyun 
362*4882a593Smuzhiyun     int num;
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun     if (xf86CheckSbusSlot(psdp->fbNum)) {
365*4882a593Smuzhiyun         num = xf86AllocateEntity();
366*4882a593Smuzhiyun         p = xf86Entities[num];
367*4882a593Smuzhiyun         p->driver = drvp;
368*4882a593Smuzhiyun         p->chipset = -1;
369*4882a593Smuzhiyun         p->bus.type = BUS_SBUS;
370*4882a593Smuzhiyun         xf86AddDevToEntity(num, dev);
371*4882a593Smuzhiyun         p->bus.id.sbus.fbNum = psdp->fbNum;
372*4882a593Smuzhiyun         p->active = active;
373*4882a593Smuzhiyun         p->inUse = FALSE;
374*4882a593Smuzhiyun         sbusSlotClaimed = TRUE;
375*4882a593Smuzhiyun         return num;
376*4882a593Smuzhiyun     }
377*4882a593Smuzhiyun     else
378*4882a593Smuzhiyun         return -1;
379*4882a593Smuzhiyun }
380*4882a593Smuzhiyun 
381*4882a593Smuzhiyun int
xf86MatchSbusInstances(const char * driverName,int sbusDevId,GDevPtr * devList,int numDevs,DriverPtr drvp,int ** foundEntities)382*4882a593Smuzhiyun xf86MatchSbusInstances(const char *driverName, int sbusDevId,
383*4882a593Smuzhiyun                        GDevPtr * devList, int numDevs, DriverPtr drvp,
384*4882a593Smuzhiyun                        int **foundEntities)
385*4882a593Smuzhiyun {
386*4882a593Smuzhiyun     int i, j;
387*4882a593Smuzhiyun     sbusDevicePtr psdp, *psdpp;
388*4882a593Smuzhiyun     int numClaimedInstances = 0;
389*4882a593Smuzhiyun     int allocatedInstances = 0;
390*4882a593Smuzhiyun     int numFound = 0;
391*4882a593Smuzhiyun     GDevPtr devBus = NULL;
392*4882a593Smuzhiyun     GDevPtr dev = NULL;
393*4882a593Smuzhiyun     int *retEntities = NULL;
394*4882a593Smuzhiyun     int useProm = 0;
395*4882a593Smuzhiyun 
396*4882a593Smuzhiyun     struct Inst {
397*4882a593Smuzhiyun         sbusDevicePtr sbus;
398*4882a593Smuzhiyun         GDevPtr dev;
399*4882a593Smuzhiyun         Bool claimed;           /* BusID matches with a device section */
400*4882a593Smuzhiyun     } *instances = NULL;
401*4882a593Smuzhiyun 
402*4882a593Smuzhiyun     *foundEntities = NULL;
403*4882a593Smuzhiyun     for (psdpp = xf86SbusInfo, psdp = *psdpp; psdp; psdp = *++psdpp) {
404*4882a593Smuzhiyun         if (psdp->devId != sbusDevId)
405*4882a593Smuzhiyun             continue;
406*4882a593Smuzhiyun         if (psdp->fd == -2)
407*4882a593Smuzhiyun             continue;
408*4882a593Smuzhiyun         ++allocatedInstances;
409*4882a593Smuzhiyun         instances = xnfreallocarray(instances,
410*4882a593Smuzhiyun                                     allocatedInstances, sizeof(struct Inst));
411*4882a593Smuzhiyun         instances[allocatedInstances - 1].sbus = psdp;
412*4882a593Smuzhiyun         instances[allocatedInstances - 1].dev = NULL;
413*4882a593Smuzhiyun         instances[allocatedInstances - 1].claimed = FALSE;
414*4882a593Smuzhiyun         numFound++;
415*4882a593Smuzhiyun     }
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun     /*
418*4882a593Smuzhiyun      * This may be debatable, but if no SBUS devices with a matching vendor
419*4882a593Smuzhiyun      * type is found, return zero now.  It is probably not desirable to
420*4882a593Smuzhiyun      * allow the config file to override this.
421*4882a593Smuzhiyun      */
422*4882a593Smuzhiyun     if (allocatedInstances <= 0) {
423*4882a593Smuzhiyun         free(instances);
424*4882a593Smuzhiyun         return 0;
425*4882a593Smuzhiyun     }
426*4882a593Smuzhiyun 
427*4882a593Smuzhiyun     if (sparcPromInit() >= 0)
428*4882a593Smuzhiyun         useProm = 1;
429*4882a593Smuzhiyun 
430*4882a593Smuzhiyun     if (xf86DoConfigure && xf86DoConfigurePass1) {
431*4882a593Smuzhiyun         GDevPtr pGDev;
432*4882a593Smuzhiyun         int actualcards = 0;
433*4882a593Smuzhiyun 
434*4882a593Smuzhiyun         for (i = 0; i < allocatedInstances; i++) {
435*4882a593Smuzhiyun             actualcards++;
436*4882a593Smuzhiyun             pGDev = xf86AddBusDeviceToConfigure(drvp->driverName, BUS_SBUS,
437*4882a593Smuzhiyun                                                 instances[i].sbus, -1);
438*4882a593Smuzhiyun             if (pGDev) {
439*4882a593Smuzhiyun                 /*
440*4882a593Smuzhiyun                  * XF86Match???Instances() treat chipID and chipRev as
441*4882a593Smuzhiyun                  * overrides, so clobber them here.
442*4882a593Smuzhiyun                  */
443*4882a593Smuzhiyun                 pGDev->chipID = pGDev->chipRev = -1;
444*4882a593Smuzhiyun             }
445*4882a593Smuzhiyun         }
446*4882a593Smuzhiyun         free(instances);
447*4882a593Smuzhiyun         if (useProm)
448*4882a593Smuzhiyun             sparcPromClose();
449*4882a593Smuzhiyun         return actualcards;
450*4882a593Smuzhiyun     }
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun     DebugF("%s instances found: %d\n", driverName, allocatedInstances);
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun     for (i = 0; i < allocatedInstances; i++) {
455*4882a593Smuzhiyun         char *promPath = NULL;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun         psdp = instances[i].sbus;
458*4882a593Smuzhiyun         devBus = NULL;
459*4882a593Smuzhiyun         dev = NULL;
460*4882a593Smuzhiyun         if (useProm && psdp->node.node)
461*4882a593Smuzhiyun             promPath = sparcPromNode2Pathname(&psdp->node);
462*4882a593Smuzhiyun 
463*4882a593Smuzhiyun         for (j = 0; j < numDevs; j++) {
464*4882a593Smuzhiyun             if (devList[j]->busID && *devList[j]->busID) {
465*4882a593Smuzhiyun                 if (xf86CompareSbusBusString(devList[j]->busID, psdp->fbNum)) {
466*4882a593Smuzhiyun                     if (devBus)
467*4882a593Smuzhiyun                         xf86MsgVerb(X_WARNING, 0,
468*4882a593Smuzhiyun                                     "%s: More than one matching Device section for "
469*4882a593Smuzhiyun                                     "instance (BusID: %s) found: %s\n",
470*4882a593Smuzhiyun                                     driverName, devList[j]->identifier,
471*4882a593Smuzhiyun                                     devList[j]->busID);
472*4882a593Smuzhiyun                     else
473*4882a593Smuzhiyun                         devBus = devList[j];
474*4882a593Smuzhiyun                 }
475*4882a593Smuzhiyun             }
476*4882a593Smuzhiyun             else {
477*4882a593Smuzhiyun                 if (!dev && !devBus) {
478*4882a593Smuzhiyun                     if (promPath)
479*4882a593Smuzhiyun                         xf86Msg(X_PROBED,
480*4882a593Smuzhiyun                                 "Assigning device section with no busID to SBUS:%s\n",
481*4882a593Smuzhiyun                                 promPath);
482*4882a593Smuzhiyun                     else
483*4882a593Smuzhiyun                         xf86Msg(X_PROBED,
484*4882a593Smuzhiyun                                 "Assigning device section with no busID to SBUS:fb%d\n",
485*4882a593Smuzhiyun                                 psdp->fbNum);
486*4882a593Smuzhiyun                     dev = devList[j];
487*4882a593Smuzhiyun                 }
488*4882a593Smuzhiyun                 else
489*4882a593Smuzhiyun                     xf86MsgVerb(X_WARNING, 0,
490*4882a593Smuzhiyun                                 "%s: More than one matching Device section "
491*4882a593Smuzhiyun                                 "found: %s\n", driverName,
492*4882a593Smuzhiyun                                 devList[j]->identifier);
493*4882a593Smuzhiyun             }
494*4882a593Smuzhiyun         }
495*4882a593Smuzhiyun         if (devBus)
496*4882a593Smuzhiyun             dev = devBus;       /* busID preferred */
497*4882a593Smuzhiyun         if (!dev && psdp->fd != -2) {
498*4882a593Smuzhiyun             if (promPath) {
499*4882a593Smuzhiyun                 xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
500*4882a593Smuzhiyun                             "for instance (BusID SBUS:%s) found\n",
501*4882a593Smuzhiyun                             driverName, promPath);
502*4882a593Smuzhiyun             }
503*4882a593Smuzhiyun             else
504*4882a593Smuzhiyun                 xf86MsgVerb(X_WARNING, 0, "%s: No matching Device section "
505*4882a593Smuzhiyun                             "for instance (BusID SBUS:fb%d) found\n",
506*4882a593Smuzhiyun                             driverName, psdp->fbNum);
507*4882a593Smuzhiyun         }
508*4882a593Smuzhiyun         else if (dev) {
509*4882a593Smuzhiyun             numClaimedInstances++;
510*4882a593Smuzhiyun             instances[i].claimed = TRUE;
511*4882a593Smuzhiyun             instances[i].dev = dev;
512*4882a593Smuzhiyun         }
513*4882a593Smuzhiyun         free(promPath);
514*4882a593Smuzhiyun     }
515*4882a593Smuzhiyun 
516*4882a593Smuzhiyun     DebugF("%s instances found: %d\n", driverName, numClaimedInstances);
517*4882a593Smuzhiyun 
518*4882a593Smuzhiyun     /*
519*4882a593Smuzhiyun      * Of the claimed instances, check that another driver hasn't already
520*4882a593Smuzhiyun      * claimed its slot.
521*4882a593Smuzhiyun      */
522*4882a593Smuzhiyun     numFound = 0;
523*4882a593Smuzhiyun     for (i = 0; i < allocatedInstances && numClaimedInstances > 0; i++) {
524*4882a593Smuzhiyun         if (!instances[i].claimed)
525*4882a593Smuzhiyun             continue;
526*4882a593Smuzhiyun         psdp = instances[i].sbus;
527*4882a593Smuzhiyun         if (!xf86CheckSbusSlot(psdp->fbNum))
528*4882a593Smuzhiyun             continue;
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun         DebugF("%s: card at fb%d %08x is claimed by a Device section\n",
531*4882a593Smuzhiyun                driverName, psdp->fbNum, psdp->node.node);
532*4882a593Smuzhiyun 
533*4882a593Smuzhiyun         /* Allocate an entry in the lists to be returned */
534*4882a593Smuzhiyun         numFound++;
535*4882a593Smuzhiyun         retEntities = xnfreallocarray(retEntities, numFound, sizeof(int));
536*4882a593Smuzhiyun         retEntities[numFound - 1]
537*4882a593Smuzhiyun             = xf86ClaimSbusSlot(psdp, drvp, instances[i].dev,
538*4882a593Smuzhiyun                                 instances[i].dev->active ? TRUE : FALSE);
539*4882a593Smuzhiyun     }
540*4882a593Smuzhiyun     free(instances);
541*4882a593Smuzhiyun     if (numFound > 0) {
542*4882a593Smuzhiyun         *foundEntities = retEntities;
543*4882a593Smuzhiyun     }
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun     if (useProm)
546*4882a593Smuzhiyun         sparcPromClose();
547*4882a593Smuzhiyun 
548*4882a593Smuzhiyun     return numFound;
549*4882a593Smuzhiyun }
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun /*
552*4882a593Smuzhiyun  * xf86GetSbusInfoForEntity() -- Get the sbusDevicePtr of entity.
553*4882a593Smuzhiyun  */
554*4882a593Smuzhiyun sbusDevicePtr
xf86GetSbusInfoForEntity(int entityIndex)555*4882a593Smuzhiyun xf86GetSbusInfoForEntity(int entityIndex)
556*4882a593Smuzhiyun {
557*4882a593Smuzhiyun     sbusDevicePtr *psdpp;
558*4882a593Smuzhiyun     EntityPtr p = xf86Entities[entityIndex];
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun     if (entityIndex >= xf86NumEntities || p->bus.type != BUS_SBUS)
561*4882a593Smuzhiyun         return NULL;
562*4882a593Smuzhiyun 
563*4882a593Smuzhiyun     for (psdpp = xf86SbusInfo; *psdpp != NULL; psdpp++) {
564*4882a593Smuzhiyun         if (p->bus.id.sbus.fbNum == (*psdpp)->fbNum)
565*4882a593Smuzhiyun             return *psdpp;
566*4882a593Smuzhiyun     }
567*4882a593Smuzhiyun     return NULL;
568*4882a593Smuzhiyun }
569*4882a593Smuzhiyun 
570*4882a593Smuzhiyun int
xf86GetEntityForSbusInfo(sbusDevicePtr psdp)571*4882a593Smuzhiyun xf86GetEntityForSbusInfo(sbusDevicePtr psdp)
572*4882a593Smuzhiyun {
573*4882a593Smuzhiyun     int i;
574*4882a593Smuzhiyun 
575*4882a593Smuzhiyun     for (i = 0; i < xf86NumEntities; i++) {
576*4882a593Smuzhiyun         EntityPtr p = xf86Entities[i];
577*4882a593Smuzhiyun 
578*4882a593Smuzhiyun         if (p->bus.type != BUS_SBUS)
579*4882a593Smuzhiyun             continue;
580*4882a593Smuzhiyun 
581*4882a593Smuzhiyun         if (p->bus.id.sbus.fbNum == psdp->fbNum)
582*4882a593Smuzhiyun             return i;
583*4882a593Smuzhiyun     }
584*4882a593Smuzhiyun     return -1;
585*4882a593Smuzhiyun }
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun void
xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn,sbusDevicePtr psdp)588*4882a593Smuzhiyun xf86SbusUseBuiltinMode(ScrnInfoPtr pScrn, sbusDevicePtr psdp)
589*4882a593Smuzhiyun {
590*4882a593Smuzhiyun     DisplayModePtr mode;
591*4882a593Smuzhiyun 
592*4882a593Smuzhiyun     mode = xnfcalloc(sizeof(DisplayModeRec), 1);
593*4882a593Smuzhiyun     mode->name = "current";
594*4882a593Smuzhiyun     mode->next = mode;
595*4882a593Smuzhiyun     mode->prev = mode;
596*4882a593Smuzhiyun     mode->type = M_T_BUILTIN;
597*4882a593Smuzhiyun     mode->Clock = 100000000;
598*4882a593Smuzhiyun     mode->HDisplay = psdp->width;
599*4882a593Smuzhiyun     mode->HSyncStart = psdp->width;
600*4882a593Smuzhiyun     mode->HSyncEnd = psdp->width;
601*4882a593Smuzhiyun     mode->HTotal = psdp->width;
602*4882a593Smuzhiyun     mode->VDisplay = psdp->height;
603*4882a593Smuzhiyun     mode->VSyncStart = psdp->height;
604*4882a593Smuzhiyun     mode->VSyncEnd = psdp->height;
605*4882a593Smuzhiyun     mode->VTotal = psdp->height;
606*4882a593Smuzhiyun     mode->SynthClock = mode->Clock;
607*4882a593Smuzhiyun     mode->CrtcHDisplay = mode->HDisplay;
608*4882a593Smuzhiyun     mode->CrtcHSyncStart = mode->HSyncStart;
609*4882a593Smuzhiyun     mode->CrtcHSyncEnd = mode->HSyncEnd;
610*4882a593Smuzhiyun     mode->CrtcHTotal = mode->HTotal;
611*4882a593Smuzhiyun     mode->CrtcVDisplay = mode->VDisplay;
612*4882a593Smuzhiyun     mode->CrtcVSyncStart = mode->VSyncStart;
613*4882a593Smuzhiyun     mode->CrtcVSyncEnd = mode->VSyncEnd;
614*4882a593Smuzhiyun     mode->CrtcVTotal = mode->VTotal;
615*4882a593Smuzhiyun     mode->CrtcHAdjusted = FALSE;
616*4882a593Smuzhiyun     mode->CrtcVAdjusted = FALSE;
617*4882a593Smuzhiyun     pScrn->modes = mode;
618*4882a593Smuzhiyun     pScrn->virtualX = psdp->width;
619*4882a593Smuzhiyun     pScrn->virtualY = psdp->height;
620*4882a593Smuzhiyun }
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun static DevPrivateKeyRec sbusPaletteKeyRec;
623*4882a593Smuzhiyun #define sbusPaletteKey (&sbusPaletteKeyRec)
624*4882a593Smuzhiyun 
625*4882a593Smuzhiyun typedef struct _sbusCmap {
626*4882a593Smuzhiyun     sbusDevicePtr psdp;
627*4882a593Smuzhiyun     CloseScreenProcPtr CloseScreen;
628*4882a593Smuzhiyun     Bool origCmapValid;
629*4882a593Smuzhiyun     unsigned char origRed[16];
630*4882a593Smuzhiyun     unsigned char origGreen[16];
631*4882a593Smuzhiyun     unsigned char origBlue[16];
632*4882a593Smuzhiyun } sbusCmapRec, *sbusCmapPtr;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun #define SBUSCMAPPTR(pScreen) ((sbusCmapPtr) \
635*4882a593Smuzhiyun     dixLookupPrivate(&(pScreen)->devPrivates, sbusPaletteKey))
636*4882a593Smuzhiyun 
637*4882a593Smuzhiyun static void
xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn,int numColors,int * indices,LOCO * colors,VisualPtr pVisual)638*4882a593Smuzhiyun xf86SbusCmapLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
639*4882a593Smuzhiyun                         LOCO * colors, VisualPtr pVisual)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun     int i, index;
642*4882a593Smuzhiyun     sbusCmapPtr cmap;
643*4882a593Smuzhiyun     struct fbcmap fbcmap;
644*4882a593Smuzhiyun     unsigned char *data;
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun     cmap = SBUSCMAPPTR(pScrn->pScreen);
647*4882a593Smuzhiyun     if (!cmap)
648*4882a593Smuzhiyun         return;
649*4882a593Smuzhiyun     fbcmap.count = 0;
650*4882a593Smuzhiyun     fbcmap.index = indices[0];
651*4882a593Smuzhiyun     fbcmap.red = data = xallocarray(numColors, 3);
652*4882a593Smuzhiyun     if (!data)
653*4882a593Smuzhiyun         return;
654*4882a593Smuzhiyun     fbcmap.green = data + numColors;
655*4882a593Smuzhiyun     fbcmap.blue = fbcmap.green + numColors;
656*4882a593Smuzhiyun     for (i = 0; i < numColors; i++) {
657*4882a593Smuzhiyun         index = indices[i];
658*4882a593Smuzhiyun         if (fbcmap.count && index != fbcmap.index + fbcmap.count) {
659*4882a593Smuzhiyun             ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
660*4882a593Smuzhiyun             fbcmap.count = 0;
661*4882a593Smuzhiyun             fbcmap.index = index;
662*4882a593Smuzhiyun         }
663*4882a593Smuzhiyun         fbcmap.red[fbcmap.count] = colors[index].red;
664*4882a593Smuzhiyun         fbcmap.green[fbcmap.count] = colors[index].green;
665*4882a593Smuzhiyun         fbcmap.blue[fbcmap.count++] = colors[index].blue;
666*4882a593Smuzhiyun     }
667*4882a593Smuzhiyun     ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
668*4882a593Smuzhiyun     free(data);
669*4882a593Smuzhiyun }
670*4882a593Smuzhiyun 
671*4882a593Smuzhiyun static Bool
xf86SbusCmapCloseScreen(ScreenPtr pScreen)672*4882a593Smuzhiyun xf86SbusCmapCloseScreen(ScreenPtr pScreen)
673*4882a593Smuzhiyun {
674*4882a593Smuzhiyun     sbusCmapPtr cmap;
675*4882a593Smuzhiyun     struct fbcmap fbcmap;
676*4882a593Smuzhiyun 
677*4882a593Smuzhiyun     cmap = SBUSCMAPPTR(pScreen);
678*4882a593Smuzhiyun     if (cmap->origCmapValid) {
679*4882a593Smuzhiyun         fbcmap.index = 0;
680*4882a593Smuzhiyun         fbcmap.count = 16;
681*4882a593Smuzhiyun         fbcmap.red = cmap->origRed;
682*4882a593Smuzhiyun         fbcmap.green = cmap->origGreen;
683*4882a593Smuzhiyun         fbcmap.blue = cmap->origBlue;
684*4882a593Smuzhiyun         ioctl(cmap->psdp->fd, FBIOPUTCMAP, &fbcmap);
685*4882a593Smuzhiyun     }
686*4882a593Smuzhiyun     pScreen->CloseScreen = cmap->CloseScreen;
687*4882a593Smuzhiyun     free(cmap);
688*4882a593Smuzhiyun     return (*pScreen->CloseScreen) (pScreen);
689*4882a593Smuzhiyun }
690*4882a593Smuzhiyun 
691*4882a593Smuzhiyun Bool
xf86SbusHandleColormaps(ScreenPtr pScreen,sbusDevicePtr psdp)692*4882a593Smuzhiyun xf86SbusHandleColormaps(ScreenPtr pScreen, sbusDevicePtr psdp)
693*4882a593Smuzhiyun {
694*4882a593Smuzhiyun     sbusCmapPtr cmap;
695*4882a593Smuzhiyun     struct fbcmap fbcmap;
696*4882a593Smuzhiyun     unsigned char data[2];
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun     if (!dixRegisterPrivateKey(sbusPaletteKey, PRIVATE_SCREEN, 0))
699*4882a593Smuzhiyun         FatalError("Cannot register sbus private key");
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun     cmap = xnfcalloc(1, sizeof(sbusCmapRec));
702*4882a593Smuzhiyun     dixSetPrivate(&pScreen->devPrivates, sbusPaletteKey, cmap);
703*4882a593Smuzhiyun     cmap->psdp = psdp;
704*4882a593Smuzhiyun     fbcmap.index = 0;
705*4882a593Smuzhiyun     fbcmap.count = 16;
706*4882a593Smuzhiyun     fbcmap.red = cmap->origRed;
707*4882a593Smuzhiyun     fbcmap.green = cmap->origGreen;
708*4882a593Smuzhiyun     fbcmap.blue = cmap->origBlue;
709*4882a593Smuzhiyun     if (ioctl(psdp->fd, FBIOGETCMAP, &fbcmap) >= 0)
710*4882a593Smuzhiyun         cmap->origCmapValid = TRUE;
711*4882a593Smuzhiyun     fbcmap.index = 0;
712*4882a593Smuzhiyun     fbcmap.count = 2;
713*4882a593Smuzhiyun     fbcmap.red = data;
714*4882a593Smuzhiyun     fbcmap.green = data;
715*4882a593Smuzhiyun     fbcmap.blue = data;
716*4882a593Smuzhiyun     if (pScreen->whitePixel == 0) {
717*4882a593Smuzhiyun         data[0] = 255;
718*4882a593Smuzhiyun         data[1] = 0;
719*4882a593Smuzhiyun     }
720*4882a593Smuzhiyun     else {
721*4882a593Smuzhiyun         data[0] = 0;
722*4882a593Smuzhiyun         data[1] = 255;
723*4882a593Smuzhiyun     }
724*4882a593Smuzhiyun     ioctl(psdp->fd, FBIOPUTCMAP, &fbcmap);
725*4882a593Smuzhiyun     cmap->CloseScreen = pScreen->CloseScreen;
726*4882a593Smuzhiyun     pScreen->CloseScreen = xf86SbusCmapCloseScreen;
727*4882a593Smuzhiyun     return xf86HandleColormaps(pScreen, 256, 8,
728*4882a593Smuzhiyun                                xf86SbusCmapLoadPalette, NULL, 0);
729*4882a593Smuzhiyun }
730*4882a593Smuzhiyun 
731*4882a593Smuzhiyun Bool
xf86SbusConfigure(void * busData,sbusDevicePtr sBus)732*4882a593Smuzhiyun xf86SbusConfigure(void *busData, sbusDevicePtr sBus)
733*4882a593Smuzhiyun {
734*4882a593Smuzhiyun     if (sBus && sBus->fbNum == ((sbusDevicePtr) busData)->fbNum)
735*4882a593Smuzhiyun         return 0;
736*4882a593Smuzhiyun     return 1;
737*4882a593Smuzhiyun }
738*4882a593Smuzhiyun 
739*4882a593Smuzhiyun void
xf86SbusConfigureNewDev(void * busData,sbusDevicePtr sBus,GDevRec * GDev)740*4882a593Smuzhiyun xf86SbusConfigureNewDev(void *busData, sbusDevicePtr sBus, GDevRec * GDev)
741*4882a593Smuzhiyun {
742*4882a593Smuzhiyun     char *promPath = NULL;
743*4882a593Smuzhiyun 
744*4882a593Smuzhiyun     sBus = (sbusDevicePtr) busData;
745*4882a593Smuzhiyun     GDev->identifier = sBus->descr;
746*4882a593Smuzhiyun     if (sparcPromInit() >= 0) {
747*4882a593Smuzhiyun         promPath = sparcPromNode2Pathname(&sBus->node);
748*4882a593Smuzhiyun         sparcPromClose();
749*4882a593Smuzhiyun     }
750*4882a593Smuzhiyun     if (promPath) {
751*4882a593Smuzhiyun         XNFasprintf(&GDev->busID, "SBUS:%s", promPath);
752*4882a593Smuzhiyun         free(promPath);
753*4882a593Smuzhiyun     }
754*4882a593Smuzhiyun     else {
755*4882a593Smuzhiyun         XNFasprintf(&GDev->busID, "SBUS:fb%d", sBus->fbNum);
756*4882a593Smuzhiyun     }
757*4882a593Smuzhiyun }
758