First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / doc / devel / RAC.Notes
blob0aec9d795cf74fceaa1d82fb38ae6fcf5444b5d2
1 I. Abstract 
2 ===========
4 Graphics devices are accessed thru ranges in I/O or memory space. While
5 most modern graphics  devices allow relocation of such  ranges many of
6 them still require the use  of well established interfaces such as VGA
7 memory  and IO  ranges or  8514/A  IO ranges.   Up to  version 3.3  of
8 XFree86 only a single graphics  device could be driven. Therfore there
9 was no need  to address the issue of sharing such  memory or I/O ranges
10 among several devices. Starting with version 4.0 XFree86 is capable of
11 driving more  than one graphics interface in  a multi-head environment.
12 Therefore  a mechanism  needed to  be  designed which  was capable  of
13 controlling the sharing  the access to memory and  I/O ranges.  In this
14 document  we describe  to use  of  the RAC  (Resource Access  Control)
15 system in the XFree86 server which provides the service of controlling
16 access to interface resources.
18 II. Introduction
19 ================
21 Terms and definitions:
23 II.1. Bus
24 ---------
26 'Bus' is ambiguous as it is used for different things: It may refer to
27 physical incompatible  extension connectors in a  computer system. The
28 RAC system  knows two such systems: The  ISA bus and the  PCI bus. (On
29 the software  level EISA, MC and  VL buses are  currently treated like
30 ISA buses). 'Bus' may always  refer to logically different entities on
31 a single bus  system which are connected via bridges.  A PCI system may
32 have several  distinct PCI  buses connecting  each other  by PCI-PCI
33 bridges or to the host CPU by HOST-PCI bridges.
35 Systems that host  more than one bus system  link these together using
36 bridges. Bridges  are a  concern to  RAC as they  might block  or pass
37 specific  resources.  PCI-PCI  bridges  may  be set  up  to  pass  VGA
38 resources to the  secondary bus. PCI-ISA buses pass  any resources not
39 decoded on the primary PCI bus  to the ISA bus. This way VGA resources
40 (although  exclusive on  the ISA  bus) can  be shared  by ISA  and PCI
41 cards.  Currently HOST-PCI bridges are not yet handled by RACY as they
42 require specific drivers.
44 II.2. Entity 
45 ------------
47 The  smallest  independently  addressable  unit  on a  system  bus  is
48 referred to  as an entity. So far  we know ISA and  PCI entities.  PCI
49 entities can be  located on the PCI bus by an  unique ID consisting of
50 the bus, card and function number.
52 II.3. Resource
53 --------------
55  'Resource' refers to  a range of memory or  I/O addresses an entity
56 can decode.
58 If  a device is  capable of  disabling this  decoding the  resource is
59 called  sharable. For  PCI devices  a  generic method  is provided  to
60 control resource decoding. Other devices will have to provide a device
61 specific function to control decoding.
63 If  the  entity is  capable  of decoding  this  range  at a  different
64 location this resource is considered relocatable. Resource which start
65 at a specific address and  occupy a single continuous range are called
66 block resources.
68 Alternatively resource  addresses can  be decoded in  a way  that they
69 satisfy the condition: 
71                         address & mask == base
73 with  base &  mask ==  base.  Resources  addressed in  such a  way are
74 considered sparse resources.
77 II.4. Server States
78 ------------------
80 The resource access control system  knows two server states: the SETUP
81 and the  OPERATING state. The setup  state is entered  whenever a mode
82 change takes place  or the server exits or  does VT switching.  During
83 this  state any  entity  resource is  under  resource access  control.
84 During  OPERATING  state  only  those entities  are  controlled  which
85 actually  have  shared  resources  that  conflict  with  others.   The
86 determination which entity is to  be placed under RAC during OPERATING
87 state  takes   place  after  ScreenInit()  during   the  first  server
88 generation.  This doesn't apply if  only one screen is active: in this
89 case no RAC is needed and  the screen is simply left enabled while the
90 server is active.
93 III. Theory of operation
94 ========================
96 III.1. General
97 --------------
99 The common  level has knowledge  of generic access  control mechanisms
100 for devices on certain bus systems  (currently the PCI bus) as well as
101 of   methods   to   enable    or   disable   access   to   the   buses
102 itself. Furthermore it can  access information on resources decoded by
103 these devices and if necessary modify it.
105 When first  starting the Xserver collects all  this information, saves
106 it for restoration checks it for consistency and if necessary corrects
107 it.  Finally it disables  all resources  on a  generic level  prior to
108 calling any driver function.
110  The  user should  provide a  device  section in  XF86Config for  each
111 graphics device  installed in  his system. Each  such entity  which is
112 never to  be used as X display  device might be marked  as inactive by
113 adding the keyword "Inactive" to the device section.
115 When the Probe() function of each driver is called the device sections
116 are matched against  the devices found in the  system.  The driver may
117 probe devices at this stage  that cannot be identified by using device
118 independent methods. Access to all resources that can be controlled in
119 a  device independent way  is disabled.   The Probe()  function should
120 register all  non-relocatable resources at  this stage. If  a resource
121 conflict  is found between  exclusive resources  the driver  will fail
122 immediately.  Optionally  the driver  might  specify an  EntityInit(),
123 EntityLeave() and EntityEnter() function.
125 EntityInit() can be used to  disable any shared resources that are not
126 controlled by the generic access control functions. It is called prior
127 to the PreInit  phase regardless if an entity is  active or not.  When
128 calling  the EntityInit(),  EntityEnter() and  EntityLeave() functions
129 the  common level  will  disable access  to  all other  entities on  a
130 generic  level. Since  the common  level  has no  knowledge of  device
131 specific  methods  to  disable   access  to  resources  it  cannot  be
132 guaranteed that certain resources are  not decoded by any other entity
133 until  the EntityInit()  or EntityEnter()  phase is  finished.  Device
134 drivers should  therefore register all those resources  which they are
135 going to  disable.  If  these resources  are never to  be used  by any
136 driver  function they may  be flagged  'ResInit' so  that they  can be
137 removed  from  the resource  list  after  processing all  EntityInit()
138 functions.   EntityEnter() should  disable decoding  of  all resources
139 which are not registered as exclusive and which are not handled by the
140 generic  access  control  in  the  common level.   The  difference  to
141 EntityInit()  is  that the  latter  one  is  only called  once  during
142 lifetime of the server.  It can  therefore be used to set up variables
143 prior  to  disabling  resources.   EntityLeave()  should  restore  the
144 original state when exiting the server or switching to a different vt.
145 It also needs to disable device specific access functions if they need
146 to be  disabled on server exit or  VT switch. The default  state is to
147 enable them before giving up the VT.
149 In PreInit() phase each driver  should check if any sharable resources
150 it has registered during Probe()  has been denied and take appropriate
151 action which could simply be to  fail. If it needs to access resources
152 it  has disabled during  EntitySetup() it  can do  so provided  it has
153 registered  these   and  will  disable  them   before  returning  from
154 PreInit(). This  also applies to all other  driver functions.  Several
155 functions  are provided  to request  resource ranges,  register these,
156 correct PCI config  space and add replacements for  the generic access
157 functions.  Resources  may be  marked  'disabled'  or 'unused'  during
158 OPERATING  stage.  Although  these steps  could also  be  performed in
159 ScreenInit(), this is not desirable.
161 Following  PreInit() phase  the  common level  determines if  resource
162 access control is needed.  This is the case if more than one screen is
163 used. If necessary the RAC  wrapper module is loaded.  In ScreenInit()
164 the  drivers can  decide  which  operations need  to  be placed  under
165 RAC. Available are the frame buffer operations, the pointer operations
166 and  the colormap  operations. Any  operation that  requires resources
167 which might  be disabled during OPERATING  state should be  set to use
168 RAC.  This can be specified separately for memory and IO resources.
170 When ScreenInit() phase is done  the common level will determine which
171 shared resources  are requested  by more than  one driver and  set the
172 access functions accordingly.  This is done following these rules:
174 a. The sharable resources registered  by each entity are compared.  if
175    a resource is registered by more than one entity the entity will be
176    marked to need to share this resources type (IO or MEM).
178 b. A resource marked 'disabled' during OPERATING state will be ignored
179    entirely.
181 c. A resource marked 'unused'  will only conflicts with an overlapping
182    resource of an other entity if the second is actually in use during
183    OPERATING state.
185 d. If  an 'unused' resource was  found to conflict  however the entity
186    does not  use any other resource  of this type  the entire resource
187    type will be disabled for that entity.
189 The driver  has the choice among  different ways to  control access to
190 certain resources:
192 a. It can relay on the  generic access functions. This is probably the
193    most  common case.  Here  the  driver only  needs  to register  any
194    resource it is going to use.
196 b.  It  can replace  the generic access  functions by  driver specific
197    ones. This  will mostly  be used in  cases where no  generic access
198    functions are available.  In this  case the driver has to make sure
199    these  resources are  disabled when  entering the  PreInit() stage.
200    Since  the replacement  functions are  registered in  PreInit() the
201    driver will  have to enable these  resources itself if  it needs to
202    access  them during  this state.   The  driver can  specify if  the
203    replacement  functions  can  control  memory and/or  I/O  resources
204    separately.
206 c. The  driver can  enable resources itself  when it needs  them. Each
207    driver function enabling them needs  to disable them before it will
208    return. This should  be used if a resource  which can be controlled
209    in a device dependent way is only required during SETUP state. This
210    way it can be marked 'unused' during OPERATING state.
212 A  resource which  is  decoded during  OPERATING  state however  never
213 accessed by the driver should be marked unused.
214    
215 Since  access   switching  latencies  are  an   issue  during  Xserver
216 operation,  the  common  level  attempts  to minimize  the  number  of
217 entities that  need to  be placed under  RAC control.  When  a wrapped
218 operation  is called,  the  EnableAccess() function  is called  before
219 control  is passed  on.  EnableAccess()  checks if  a screen  is under
220 access control. If not it just establishes bus routing and returns. If
221 the screen needs to be under access control, EnableAccess() determines
222 which resource  types (MEM,IO)  are required.  Then  it tests  if this
223 access is  already established.   If so it  simply returns. If  not it
224 disables  the  currently established  access,  fixes  bus routing  and
225 enables access to all entities registered for this screen.
227 Whenever a  mode switch or a  vt-switch is performed  the common level
228 will return to SETUP state.
230 III.3. Resource Types
231 ---------------------
233 Resource  have  certain properties.  When  registering resources  each
234 range is  accompanied by a flag  consisting of the or'ed  flags of the
235 different  properties the  resource has.  Each resource  range  may be
236 classified according to 
238 - its  physical properties ie. if it addresses
239     memory (ResMem)  or 
240     I/O space (ResIo), 
241 - if it addresses a 
242     block (ResBlock) or 
243     sparse (ResSparse) 
244   range, 
245 - its access properties.  
247 There are two known access properties: 
249 - ResExclusive
250   for resources which may not be shared with any other device and 
251 - ResShared 
252   for resources which can be disabled and therefore can be shared.  
254 If  it is  desirable to  test a  resource against  any type  a generic
255 access type  'ResAny' is  provided. If this  is set the  resource will
256 conflict  with any  resource of  a different  entity  intersecting its
257 range.  Further it can be specified that a resource is decoded however
258 never  used during  any stage  (ResUnused) or  during  OPERATING state
259 (ResUnusedOpr). A resource only visible during the init functions (ie.
260 EntityInit(),  EntityEnter() and  EntityLeave()  should be  registered
261 with  the  flag  'ResInit'.   A  resource  that  might  conflict  with
262 background resource  ranges may be flagged with  'ResBios'. This might
263 be useful when registering resources  ranges that were assigned by the
264 system Bios.
266 Several  predefined resource lists  are available  for VGA  and 8514/A
267 resources in common/sf86Resources.h.
269 IV. Available Functions
270 =======================
272 The functions provided for resource management will be listed in order
273 of use in the driver.
275 IV.1. Probe phase
276 -----------------
278 In this stage each driver detects those resources it is able to drive,
279 creates an  entity record for each of  them, registers non-relocatable
280 resources and allocates screens and adds the resources to screens.
282 Two helper functions are provided  for matching device sections in the
283 XF86Config file to the devices:
285    int xf86MatchPciInstances(const char *driverName, int vendorID, 
286                              SymTabPtr chipsets, PciChipsets *PCIchipsets,
287                              GDevPtr *devList, int numDevs, DriverPtr drvp,
288                              int **foundEntities);
290    int xf86MatchIsaInstances(const char *driverName, SymTabPtr chipsets,
291                              IsaChipsets *ISAchipsets, DriverPtr drvp,
292                              FindIsaDevProc FindIsaDevice, GDevPtr *devList,
293                              int numDevs, int **foundEntities);
295 Both functions return the number of matched entities and their indices
296 in foundEntities list.
298 They make use of several  sub functions which are also available on the
299 driver level:
301    Bool xf86ComparePciBusString(const char *busID, int bus, 
302                                 int device, int func);
304 and 
306    Bool xf86ParseIsaBusString(const char *busID);
308 are called to interpret the busID in the device section. The functions:
310    int xf86ClaimPciSlot(int bus, int device, int func, DriverPtr drvp,
311                         int chipset, GDevPtr dev, Bool active);
313    int xf86ClaimIsaSlot(DriverPtr drvp, int chipset, GDevPtr dev, Bool
314                         active);
316 are  used  to  allocate   the  entities  and  initialize  their  data
317 structures.  Both functions  return the  index of  the  newly allocated
318 entity record or (-1) should  the function fail. Before probing an ISA
319 card
321    Bool xf86IsPrimaryIsa();
323 gets called to determine if the primary card was not detected on the
324 PCI bus.
326 Two helper functions are provided to aid configuring entities:
328    Bool xf86ConfigActivePciEntity(ScrnInfoPtr pScrn, int entityIndex,
329                                   PciChipsets *p_chip, resList res,
330                                   EntityProc init, EntityProc enter,
331                                   EntityProc leave, pointer private);
332    Bool xf86ConfigActiveIsaEntity(ScrnInfoPtr pScrn, int entityIndex,
333                                   IsaChipsets *i_chip, resList res,
334                                   EntityProc init, EntityProc enter,
335                                   EntityProc leave, pointer private); 
337 They  are used  to register  the init/enter/leave  functions described
338 above as well as the  non-relocatable resources. Generally the list of
339 fixed resources  is obtained from the  Isa/PciChipsets lists.  However
340 an additional list  of resources may be passed.  Generally this is not
341 required. The init/enter/leave functions have to be of type
343   typedef void (*EntityProc)(int entityIndex,pointer private);
345 They are  passed the entity index  and a pointer to  a private scratch
346 area. This  are can be  set up during  Probe() and its address  can be
347 passed  to xf86ConfigActiveIsaEntity()  xf86ConfigActivePciEntity() as
348 the last argument.
350 These helper functions use: 
352     void xf86ClaimFixedResources(resList list, int entityIndex);
354   To register  the non relocatable  resources which cannot  be disabled
355   and which  therefore would cause  the server to fail  immediately if
356   they  were found to  conflict. It  also records  non-relocatable but
357   sharable resources for processing after the Probe() phase.
359     Bool xf86SetEntityFuncs(int entityIndex, EntityProc init,
360                             EntityProc enter, EntityProc leave, pointer);
362   This function registers  the init/enter/leave() functions along with
363   the pointer to their private area to the entity.
365     void xf86AddEntityToScreen(ScrnInfoPtr pScrn, int entityIndex);
367   adds the entity to the screen.
369 These functions are  also available on the driver  level.  A detailed
370 Probe() function  is listed below. For  most drivers this  can be used
371 with little change.
373 Please  note  that  VGA  resources  have  to  be  claimed  in  Probe()
374 phase. Otherwise they are not routed to the bus.
376 IV.2. PreInit() phase
377 ---------------------
379 During  this  phase  the  remaining  resource  should  be  registered.
380 PreInit() should call
382   EntityInfoPtr xf86GetEntityInfo(int entityIndex);
384 To obtain a pointer to an  EntityInfoRec for each entity it is able to
385 drive and check if any  resource are listed in 'resources'. These have
386 been rejected in  the post-Probe() phase. The driver  should decide if
387 it can continue without using these or if it should fail.  The pointer
388 to the EntityInfoRec should be freed if not needed any more.
390 Several functions are provided to simplify resource registration:
392   Bool xf86IsEntityPrimary(int entityIndex);
394 is used to determine if the  entity is the display device that is used
395 during boot-up and text mode.
397   Bool xf86IsScreenPrimary(int scrnIndex);
399 finds  out if the  primary entity  is registered  for the  screen with
400 specified index.
402   pciVideoPtr xf86GetPciInfoForEntity(int entityIndex);
404 returns a pointer  to the pciVideoRec of the  specified entity. If the
405 entity is not a PCI device NULL is returned.
407 The primary function for registration of resources is
409   resPtr xf86RegisterResources(int entityIndex, resList list, int access);
411 it tries to register the resources in 'list'. If list is NULL it tries
412 to determine the resources automatically. This only works for entities
413 that  provide a  generic  way to  read  out the  resource ranges  they
414 decode. So far  this is only the case for PCI  devices. By default the
415 PCI resources are registered as shared (ResShared) if the driver wants
416 to set a  different access type it can do so  by specifying the access
417 flags in  the third argument.  A value of  0 means to use  the default
418 settings.  If  for any  reason  the resource  broker  is  not able  to
419 register some  of the requested  resources the function will  return a
420 pointer to a list of the failed ones. In this case the driver may move
421 the resource to different locations.  In case of PCI bus entities this
422 is done by passing the list of failed resources to
424   resPtr xf86ReallocatePciResources(int entityIndex, resPtr pRes);
426 this function returns a list  of reallocated resource. This list needs
427 to be  passed to xf86RegisterResources()  again to be  registered with
428 the broker.
430 Two functions are provided to obtain a resource range of a given type:
432   resRange xf86GetBlock(long type, memType size,
433                         memType window_start, memType window_end,
434                         memType align_mask, resPtr avoid);
435   resRange xf86GetSparse(long type,  unsigned long fixed_bits,
436                          unsigned long decode_mask, unsigned long address_mask,
437                          resPtr avoid);
439 The first  one tries  to find a  block range  of size 'size'  and type
440 'type'  in a  window bound  by  window_start and  window_end with  the
441 alignment specified  in alignment mask. Optionally a  list of resource
442 ranges which should  be avoided inside this window  can be passed.  On
443 failure it will return a zero range of type 'ResEnd'.
445 The latter function does the same for sparse resources. A spares range
446 is  determined by  to  parameters: the  mask  and the  base value.  An
447 address satisfying
449                         mask & address == base
451 belongs  to the specific  spares range.  'mask' and  'base' themselves
452 have to satisfy:
454                          mask & base == base.
456 Here three values  have to be specified: the  address mask which marks
457 all bits of the mask part  of the address, the decode_mask which masks
458 out the bits  which are hard coded and are  therefore not available for
459 relocation and  the values  of the fixed  bits. The function  tries to
460 find a base that satisfies  the given condition. If the function fails
461 it will return  a zero range of type 'ResEnd'.  Optionally it might be
462 passed a list of resource ranges to avoid.
464 Certain PCI devices  are broken in the sense  that they return invalid
465 size information for  a certain resource. In this  case the driver can
466 supply  the  correct  size  and  make sure  that  the  resource  range
467 allocated  for the  card is  large enough  to hold  the  address range
468 decoded by the card. The function:
470   Bool xf86FixPciResource(int entityIndex, unsigned int prt, CARD32 alignment,
471                           long type);
473 is used  for that. The  parameter prt contains  the number of  the PCI
474 base register that needs to be  modified. A value of 6 refers to the
475 BIOS  base   register.  The  size   is  specified  in   the  alignment
476 register. Since  PCI resources need to  span an integral  range of the
477 size 2^n  the alignment  also specifies the  number of  addresses that
478 will be decoded.  If the driver  specifies a type mask it can override
479 the default type for PCI  resources which is 'ResShared'. The resource
480 broker needs  to know  that to find  a matching resource  range.  This
481 function should be called before calling xf86RegisterResources().
483   Bool xf86CheckPciMemBase(pciVideoPtr pPci, unsigned long base);
485 checks that the memory base value specified in base matches one of the
486 PCI base address register values for the given PCI device.
488 The driver  may replace  the generic access  control functions  for an
489 entity by it's own ones.
491   void xf86SetAccessFuncs(EntityInfoPtr pEnt, xf86SetAccessFuncPtr funcs,
492                         xf86SetAccessFuncPtr oldFuncs);
494   with:
496   typedef struct {
497       xf86AccessPtr mem;
498       xf86AccessPtr io;
499       xf86AccessPtr io_mem;
500    } xf86SetAccessFuncRec, *xf86SetAccessFuncPtr;
502 is used  for that. The  driver can pass  three functions: one  for I/O
503 access,  one for memory  access and  one for  combined memory  and I/O
504 access.   If  the memory  access  and  combined  access functions  are
505 identical the  common level assumes  that the memory access  cannot be
506 controlled independently of I/O access, if the I/O access function and
507 the combined access functions are the  same it is assumed that I/O can
508 not  be  controlled independently.   If  memory  and  I/O have  to  be
509 controlled together  all three  values should be  the same.  If  a non
510 NULL value is passed as third argument it is interpreted as an address
511 where to store  the old access records. If the  third argument is NULL
512 it will  be assumed that the  generic access should  be enabled before
513 replacing the  access functions.  Otherwise  it will be  disabled. The
514 driver may enable them itself  using the returned values. It should do
515 this from his  replacement access functions as the  generic access may
516 be disabled by  the common level on certain  occasions. If replacement
517 functions  are  specified  they  must  control all  resources  of  the
518 specific type registered for the entity.
520 To find out if specific resource range is conflicting with another
521 resource
523   memType xf86ChkConflict(resRange *rgp, int entityIndex);
525 may be called. If a non-zero value is returned a conflict is found.
527   resPtr xf86SetOperatingState(resList list, int entityIndex, int mask);
529 is used to set the state of a resource during OPERATING state.  'list'
530 holds a list  to which 'mask' is to be  applied.  The parameter 'mask'
531 may have the value  'ResUnusedOpr' and 'ResDisableOpr'.  The first one
532 should be used if a  resource isn't used during OPERATING state however
533 decoded by the device while the latter one indicates that the resource
534 is not decoded  during OPERATING state. Note that  the resource ranges
535 have to match those specified during registration. If a range has been
536 specified  starting at A  and ending  at B  and suppose  C us  a value
537 satisfying A < C  < B one may not specify the  resource range (A,B) by
538 splitting it into two ranges (A,C) and (C,B).
540 Two functions are provided for special cases:
542   void xf86RemoveEntityFromScreen(ScrnInfoPtr pScrn, int entityIndex);
544 may be used  to remove an entity from a screen.  This only makes sense
545 if a screen has  more than one entity assigned or the  screen is to be
546 deleted. No test is made if the screen has any entities left.
548   void xf86DeallocateResourcesForEntity(int entityIndex, long type);
550 deallocates all  resources of  a given type  registered for  a certain
551 entity from the resource broker list.
553 IV.3. ScreenInit() phase
554 ------------------------
556 Setting up  the rac flags  is all that  remains to do  in ScreenInit()
557 phase (Note that these flags might also be set up in PreInit() phase).
558 The  ScrnInfoRec  has  separate  flags  for  memory  and  PIO  access:
559 racIoFlags and  racMemFlags. They specifies  which graphics operations
560 might require  the use of resources  which might be  disabled for some
561 reason.  Note that even exclusive  resources might be disabled if they
562 are disabled along with shared  resources. For example if a driver has
563 registered the  VGA PIO  resources and lets  the common  level disable
564 these by disabling PIO access  in PCI config space (the standard way),
565 exclusive PCI PIO ranges will  also be disabled.  Therefore the driver
566 has to flag any operations  requiring PCI PIO resources in racIoFlags.
567 The avaliable flags are defined in rac/xf86RAC.h.  Available are:
569  RAC_FB       for framebuffer operations (including hw acceleration)
570  RAC_CURSOR   for Cursor operations
571               (??? I'm not sure if we need this for SW cursor it depends
572               on which level the sw cursor is drawn)
573  RAC_COLORMAP for colormap operations
574  RAC_VIEWPORT for the call to RACAdjustFrame()
576 The flags are or'ed.
578 V. Appendix
579 ===========
581 A. Sample Probe() Function
582 --------------------------
584 static Bool
585 XXXProbe(DriverPtr drv, int flags)
587     Bool foundScreen = FALSE;
588     int numDevSections, numUsed;
589     GDevPtr *devSections;
590     int *usedChips;
591     int i;
592     
593     /*
594      * Find the config file Device sections that match this
595      * driver, and return if there are none.
596      */
597     if ((numDevSections = xf86MatchDevice(CHIPS_DRIVER_NAME,
598                                           &devSections)) <= 0) {
599         return FALSE;
600     }
601     /* PCI BUS */
602     /* test if PCI bus present */
603     if (xf86GetPciVideoInfo() ) {
604     /* match PCI instances with ones supported by the driver */
605         numUsed = xf86MatchPciInstances(XXX_NAME, PCI_VENDOR_XXX,
606                                         XXXChipsets, XXXPCIchipsets, 
607                                         devSections,numDevSections, drv,
608                                         &usedChips);
609         if (numUsed > 0) {
610             for (i = 0; i < numUsed; i++) {
611                             /* Allocate a ScrnInfoRec  */
612                 ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
613                 pScrn->driverVersion = VERSION;
614                 pScrn->driverName    = XXX_DRIVER_NAME;
615                 pScrn->name          = XXX_NAME;
616                 pScrn->Probe         = XXXProbe;
617                 pScrn->PreInit       = XXXPreInit;
618                 pScrn->ScreenInit    = XXXScreenInit;
619                 pScrn->SwitchMode    = XXXSwitchMode;
620                 pScrn->AdjustFrame   = XXXAdjustFrame;
621                 pScrn->EnterVT       = XXXEnterVT;
622                 pScrn->LeaveVT       = XXXLeaveVT;
623                 pScrn->FreeScreen    = XXXFreeScreen;
624                 pScrn->ValidMode     = XXXValidMode;
625                 foundScreen = TRUE;
626                  /* add screen to entity */
627                  xf86ConfigActivePciEntity(pScrn,usedChips[i],XXXPCIchipsets,
628                                            NULL,NULL,NULL,NULL,NULL);
629             }
630         }
631     }
633     /* Isa Bus */
634     numUsed = xf86MatchIsaInstances(XXX_NAME,XXXChipsets,XXXISAchipsets,
635                                      drv,chipsFindIsaDevice,devSections,
636                                      numDevSections,&usedChips);
637     if(numUsed >= 0)
638         for (i = 0; i < numUsed; i++) {
639             ScrnInfoPtr pScrn = xf86AllocateScreen(drv,0);
640           
641             pScrn->driverVersion = VERSION;
642             pScrn->driverName    = XXX_DRIVER_NAME;
643             pScrn->name          = XXX_NAME;
644             pScrn->Probe         = XXXProbe;
645             pScrn->PreInit       = XXXPreInit;
646             pScrn->ScreenInit    = XXXScreenInit;
647             pScrn->SwitchMode    = XXXSwitchMode;
648             pScrn->AdjustFrame   = XXXAdjustFrame;
649             pScrn->EnterVT       = XXXEnterVT;
650             pScrn->LeaveVT       = XXXLeaveVT;
651             pScrn->FreeScreen    = XXXFreeScreen;
652             pScrn->ValidMode     = XXXValidMode;
653             foundScreen = TRUE;
654             xf86ConfigActiveIsaEntity(pScrn,usedChips[i],XXXISAchipsets,
655                                       NULL,NULL,NULL,NULL,NULL);
656         }
657     xfree(devSections);
658     return foundScreen;
661 B. Porting Issues
662 -----------------
664 Here are some hints on porting code developed for RAC 1 to RAC 2.
666 1. a. Initialization of RAC is now entirely done on the common level.
667       Therefore the call to xf86RACInit() can be removed. 
669    b. Also there is no need for the racSymbols list. 
671    c. LoadSubModule(..,rac) should be removed.
673    d. racSymbols should be removed from LoaderRequestSymList(racSymbols,..)
675 2. a. if the driver uses the predefined resource lists xf86Resources.h
676       needs to be included.
678    b. RES_VGA should be changed to RES_EXCLUSIVE_VGA
680 3. The device list now belongs to the EntityInfoRec. 
681    Change pScrn->device to xxx->pEnt->device.
683 4. Rewrite the Probe() function. The example given above should work
684    as a guideline.
686 5. Register all necessary resources in PreInit() by calling 
687    xf86RegisterResources().
689 6. If applicable set the operating state of the registered resources 
690    by calling xf86SetOperatingState(). This should be done during
691    PreInit(). If necessary it might still be done in ScreenInit()
693 7. Set up the racIoFlags and racMemFlags.
696  LocalWords:  ISA