File: /usr/src/linux/arch/ia64/sn/io/pciio.c

1     /* $Id$
2      *
3      * This file is subject to the terms and conditions of the GNU General Public
4      * License.  See the file "COPYING" in the main directory of this archive
5      * for more details.
6      *
7      * Copyright (C) 1992 - 1997, 2000 Silicon Graphics, Inc.
8      * Copyright (C) 2000 by Colin Ngam
9      */
10     
11     #define	USRPCI	0
12     
13     #include <linux/types.h>
14     #include <linux/config.h>
15     #include <linux/slab.h>
16     #include <asm/sn/sgi.h>
17     #include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
18     #include <asm/sn/iograph.h>
19     #include <asm/sn/invent.h>
20     #include <asm/sn/hcl.h>
21     #include <asm/sn/hcl_util.h>
22     #include <asm/sn/labelcl.h>
23     #include <asm/sn/pci/bridge.h>
24     #include <asm/sn/ioerror_handling.h>
25     #include <asm/sn/pci/pciio.h>
26     #include <asm/sn/pci/pciio_private.h>
27     #include <asm/sn/sn_sal.h>
28     
29     #define DEBUG_PCIIO
30     #undef DEBUG_PCIIO	/* turn this on for yet more console output */
31     
32     
33     #define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
34     #define DEL(ptr)	(kfree(ptr))
35     
36     char                    pciio_info_fingerprint[] = "pciio_info";
37     
38     cdl_p                   pciio_registry = NULL;
39     
40     int
41     badaddr_val(volatile void *addr, int len, volatile void *ptr)
42     {
43     	int ret = 0;
44     	volatile void *new_addr;
45     
46     	switch (len) {
47     		case 4:
48     			new_addr = (void *)(((u64) addr)^4);
49     			ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr);
50     			break;
51     		default:
52     			printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len);
53     	}
54     
55     	if (ret < 0)
56     		panic("badaddr_val: unexpected status (%d) in probing", ret);
57     	return(ret);
58     
59     }
60     
61     
62     nasid_t
63     get_console_nasid(void)
64     {
65     	extern nasid_t console_nasid;
66     	return console_nasid;
67     }
68     
69     int
70     hub_dma_enabled(devfs_handle_t xconn_vhdl)
71     {
72     	return(0);
73     }
74     
75     int
76     hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
77     {
78     	return(0);
79     }
80     
81     void
82     ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror)
83     {
84     }
85     
86     /******
87      ****** end hack defines ......
88      ******/
89     
90     
91     
92     
93     /* =====================================================================
94      *    PCI Generic Bus Provider
95      * Implement PCI provider operations.  The pciio* layer provides a
96      * platform-independent interface for PCI devices.  This layer
97      * switches among the possible implementations of a PCI adapter.
98      */
99     
100     /* =====================================================================
101      *    Provider Function Location SHORTCUT
102      *
103      * On platforms with only one possible PCI provider, macros can be
104      * set up at the top that cause the table lookups and indirections to
105      * completely disappear.
106      */
107     
108     #if CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 || CONFIG_IA64_GENERIC
109     /*
110      *    For the moment, we will assume that IP27
111      *      only use Bridge ASICs to provide PCI support.
112      */
113     #include <asm/sn/pci/pcibr.h>
114     #define DEV_FUNC(dev,func)	pcibr_##func
115     #define CAST_PIOMAP(x)		((pcibr_piomap_t)(x))
116     #define CAST_DMAMAP(x)		((pcibr_dmamap_t)(x))
117     #define CAST_INTR(x)		((pcibr_intr_t)(x))
118     #endif /* CONFIG_SGI_IP35 || CONFIG_IA64_SGI_SN1 */
119     
120     /* =====================================================================
121      *    Function Table of Contents
122      */
123     
124     #if !defined(DEV_FUNC)
125     static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
126     #endif
127     
128     pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
129     void                    pciio_piomap_free(pciio_piomap_t);
130     caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
131     
132     void                    pciio_piomap_done(pciio_piomap_t);
133     caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
134     caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
135     
136     iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
137     void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
138     
139     pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
140     void                    pciio_dmamap_free(pciio_dmamap_t);
141     iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
142     alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
143     void                    pciio_dmamap_done(pciio_dmamap_t);
144     iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
145     alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
146     void			pciio_dmamap_drain(pciio_dmamap_t);
147     void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
148     void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
149     iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
150     
151     pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
152     void                    pciio_intr_free(pciio_intr_t);
153     int                     pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t, void *thread);
154     void                    pciio_intr_disconnect(pciio_intr_t);
155     devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
156     
157     void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
158     static pciio_info_t     pciio_cardinfo_get(devfs_handle_t, pciio_slot_t);
159     int                     pciio_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
160     int                     pciio_error_devenable(devfs_handle_t, int);
161     
162     void                    pciio_provider_startup(devfs_handle_t);
163     void                    pciio_provider_shutdown(devfs_handle_t);
164     
165     pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
166     pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
167     devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
168     
169     devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
170     pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
171     pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
172     iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
173     ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
174     caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
175     
176     devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
177     pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
178     
179     pciio_info_t            pciio_info_chk(devfs_handle_t);
180     pciio_info_t            pciio_info_get(devfs_handle_t);
181     void                    pciio_info_set(devfs_handle_t, pciio_info_t);
182     devfs_handle_t            pciio_info_dev_get(pciio_info_t);
183     pciio_slot_t            pciio_info_slot_get(pciio_info_t);
184     pciio_function_t        pciio_info_function_get(pciio_info_t);
185     pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
186     pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
187     devfs_handle_t            pciio_info_master_get(pciio_info_t);
188     arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
189     pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
190     error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
191     error_handler_arg_t    *pciio_info_einfo_get(pciio_info_t);
192     pciio_space_t		pciio_info_bar_space_get(pciio_info_t, int);
193     iopaddr_t		pciio_info_bar_base_get(pciio_info_t, int);
194     size_t			pciio_info_bar_size_get(pciio_info_t, int);
195     iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
196     size_t			pciio_info_rom_size_get(pciio_info_t);
197     
198     void                    pciio_init(void);
199     int                     pciio_attach(devfs_handle_t);
200     
201     void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
202     void                    pciio_provider_unregister(devfs_handle_t);
203     pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
204     
205     int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
206     void                    pciio_driver_unregister(char *driver_prefix);
207     
208     devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
209     
210     void			pciio_device_unregister(devfs_handle_t);
211     pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
212     void			pciio_device_info_free(pciio_info_t);
213     devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
214     void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
215     int                     pciio_device_attach(devfs_handle_t, int);
216     int			pciio_device_detach(devfs_handle_t, int);
217     void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
218     
219     int                     pciio_reset(devfs_handle_t);
220     int                     pciio_write_gather_flush(devfs_handle_t);
221     int                     pciio_slot_inuse(devfs_handle_t);
222     
223     /* =====================================================================
224      *    Provider Function Location
225      *
226      *      If there is more than one possible provider for
227      *      this platform, we need to examine the master
228      *      vertex of the current vertex for a provider
229      *      function structure, and indirect through the
230      *      appropriately named member.
231      */
232     
233     #if !defined(DEV_FUNC)
234     
235     static pciio_provider_t *
236     pciio_to_provider_fns(devfs_handle_t dev)
237     {
238         pciio_info_t            card_info;
239         pciio_provider_t       *provider_fns;
240     
241         /*
242          * We're called with two types of vertices, one is
243          * the bridge vertex (ends with "pci") and the other is the
244          * pci slot vertex (ends with "pci/[0-8]").  For the first type
245          * we need to get the provider from the PFUNCS label.  For
246          * the second we get it from fastinfo/c_pops.
247          */
248         provider_fns = pciio_provider_fns_get(dev);
249         if (provider_fns == NULL) {
250     	card_info = pciio_info_get(dev);
251     	if (card_info != NULL) {
252     		provider_fns = pciio_info_pops_get(card_info);
253     	}
254         }
255     
256         if (provider_fns == NULL)
257     #if defined(SUPPORT_PRINTING_V_FORMAT)
258     	PRINT_PANIC("%v: provider_fns == NULL", dev);
259     #else
260     	PRINT_PANIC("0x%x: provider_fns == NULL", dev);
261     #endif
262     
263         return provider_fns;
264     
265     }
266     
267     #define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
268     #define CAST_PIOMAP(x)		((pciio_piomap_t)(x))
269     #define CAST_DMAMAP(x)		((pciio_dmamap_t)(x))
270     #define CAST_INTR(x)		((pciio_intr_t)(x))
271     #endif
272     
273     /*
274      * Many functions are not passed their vertex
275      * information directly; rather, they must
276      * dive through a resource map. These macros
277      * are available to coordinate this detail.
278      */
279     #define PIOMAP_FUNC(map,func)		DEV_FUNC((map)->pp_dev,func)
280     #define DMAMAP_FUNC(map,func)		DEV_FUNC((map)->pd_dev,func)
281     #define INTR_FUNC(intr_hdl,func)	DEV_FUNC((intr_hdl)->pi_dev,func)
282     
283     /* =====================================================================
284      *          PIO MANAGEMENT
285      *
286      *      For mapping system virtual address space to
287      *      pciio space on a specified card
288      */
289     
290     pciio_piomap_t
291     pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
292     		   device_desc_t dev_desc,	/* device descriptor */
293     		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
294     		   iopaddr_t addr,	/* lowest address (or offset in window) */
295     		   size_t byte_count,	/* size of region containing our mappings */
296     		   size_t byte_count_max,	/* maximum size of a mapping */
297     		   unsigned flags)
298     {					/* defined in sys/pio.h */
299         return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc)
300     	(dev, dev_desc, space, addr, byte_count, byte_count_max, flags);
301     }
302     
303     void
304     pciio_piomap_free(pciio_piomap_t pciio_piomap)
305     {
306         PIOMAP_FUNC(pciio_piomap, piomap_free)
307     	(CAST_PIOMAP(pciio_piomap));
308     }
309     
310     caddr_t
311     pciio_piomap_addr(pciio_piomap_t pciio_piomap,	/* mapping resources */
312     		  iopaddr_t pciio_addr,	/* map for this pciio address */
313     		  size_t byte_count)
314     {					/* map this many bytes */
315         pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr)
316     	(CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count);
317     
318         return pciio_piomap->pp_kvaddr;
319     }
320     
321     void
322     pciio_piomap_done(pciio_piomap_t pciio_piomap)
323     {
324         PIOMAP_FUNC(pciio_piomap, piomap_done)
325     	(CAST_PIOMAP(pciio_piomap));
326     }
327     
328     caddr_t
329     pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
330     		    device_desc_t dev_desc,	/* device descriptor */
331     		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
332     		    iopaddr_t addr,	/* starting address (or offset in window) */
333     		    size_t byte_count,	/* map this many bytes */
334     		    unsigned flags)
335     {					/* (currently unused) */
336         return DEV_FUNC(dev, piotrans_addr)
337     	(dev, dev_desc, space, addr, byte_count, flags);
338     }
339     
340     caddr_t
341     pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
342     	       device_desc_t dev_desc,	/* device descriptor */
343     	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
344     	       iopaddr_t addr,		/* starting address (or offset in window) */
345     	       size_t byte_count,	/* map this many bytes */
346     	       pciio_piomap_t *mapp,	/* where to return the map pointer */
347     	       unsigned flags)
348     {					/* PIO flags */
349         pciio_piomap_t          map = 0;
350         int			    errfree = 0;
351         caddr_t                 res;
352     
353         if (mapp) {
354     	map = *mapp;			/* possible pre-allocated map */
355     	*mapp = 0;			/* record "no map used" */
356         }
357     
358         res = pciio_piotrans_addr
359     	(dev, dev_desc, space, addr, byte_count, flags);
360         if (res)
361     	return res;			/* pciio_piotrans worked */
362     
363         if (!map) {
364     	map = pciio_piomap_alloc
365     	    (dev, dev_desc, space, addr, byte_count, byte_count, flags);
366     	if (!map)
367     	    return res;			/* pciio_piomap_alloc failed */
368     	errfree = 1;
369         }
370     
371         res = pciio_piomap_addr
372     	(map, addr, byte_count);
373         if (!res) {
374     	if (errfree)
375     	    pciio_piomap_free(map);
376     	return res;			/* pciio_piomap_addr failed */
377         }
378         if (mapp)
379     	*mapp = map;			/* pass back map used */
380     
381         return res;				/* pciio_piomap_addr succeeded */
382     }
383     
384     iopaddr_t
385     pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
386     		     device_desc_t dev_desc,	/* Device descriptor */
387     		     pciio_space_t space,	/* MEM32/MEM64/IO */
388     		     size_t byte_count,	/* Size of mapping */
389     		     size_t align)
390     {					/* Alignment needed */
391         if (align < NBPP)
392     	align = NBPP;
393         return DEV_FUNC(dev, piospace_alloc)
394     	(dev, dev_desc, space, byte_count, align);
395     }
396     
397     void
398     pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
399     		    pciio_space_t space,	/* Type of space        */
400     		    iopaddr_t pciaddr,	/* starting address */
401     		    size_t byte_count)
402     {					/* Range of address   */
403         DEV_FUNC(dev, piospace_free)
404     	(dev, space, pciaddr, byte_count);
405     }
406     
407     /* =====================================================================
408      *          DMA MANAGEMENT
409      *
410      *      For mapping from pci space to system
411      *      physical space.
412      */
413     
414     pciio_dmamap_t
415     pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
416     		   device_desc_t dev_desc,	/* device descriptor */
417     		   size_t byte_count_max,	/* max size of a mapping */
418     		   unsigned flags)
419     {					/* defined in dma.h */
420         return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
421     	(dev, dev_desc, byte_count_max, flags);
422     }
423     
424     void
425     pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
426     {
427         DMAMAP_FUNC(pciio_dmamap, dmamap_free)
428     	(CAST_DMAMAP(pciio_dmamap));
429     }
430     
431     iopaddr_t
432     pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
433     		  paddr_t paddr,	/* map for this address */
434     		  size_t byte_count)
435     {					/* map this many bytes */
436         return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
437     	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
438     }
439     
440     alenlist_t
441     pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
442     		  alenlist_t alenlist,	/* map this Address/Length List */
443     		  unsigned flags)
444     {
445         return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
446     	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
447     }
448     
449     void
450     pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
451     {
452         DMAMAP_FUNC(pciio_dmamap, dmamap_done)
453     	(CAST_DMAMAP(pciio_dmamap));
454     }
455     
456     iopaddr_t
457     pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
458     		    device_desc_t dev_desc,	/* device descriptor */
459     		    paddr_t paddr,	/* system physical address */
460     		    size_t byte_count,	/* length */
461     		    unsigned flags)
462     {					/* defined in dma.h */
463         return DEV_FUNC(dev, dmatrans_addr)
464     	(dev, dev_desc, paddr, byte_count, flags);
465     }
466     
467     alenlist_t
468     pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
469     		    device_desc_t dev_desc,	/* device descriptor */
470     		    alenlist_t palenlist,	/* system address/length list */
471     		    unsigned flags)
472     {					/* defined in dma.h */
473         return DEV_FUNC(dev, dmatrans_list)
474     	(dev, dev_desc, palenlist, flags);
475     }
476     
477     iopaddr_t
478     pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
479     	       device_desc_t dev_desc,	/* device descriptor */
480     	       paddr_t paddr,		/* system physical address */
481     	       size_t byte_count,	/* length */
482     	       pciio_dmamap_t *mapp,	/* map to use, then map we used */
483     	       unsigned flags)
484     {					/* PIO flags */
485         pciio_dmamap_t          map = 0;
486         int			    errfree = 0;
487         iopaddr_t               res;
488     
489         if (mapp) {
490     	map = *mapp;			/* possible pre-allocated map */
491     	*mapp = 0;			/* record "no map used" */
492         }
493     
494         res = pciio_dmatrans_addr
495     	(dev, dev_desc, paddr, byte_count, flags);
496         if (res)
497     	return res;			/* pciio_dmatrans worked */
498     
499         if (!map) {
500     	map = pciio_dmamap_alloc
501     	    (dev, dev_desc, byte_count, flags);
502     	if (!map)
503     	    return res;			/* pciio_dmamap_alloc failed */
504     	errfree = 1;
505         }
506     
507         res = pciio_dmamap_addr
508     	(map, paddr, byte_count);
509         if (!res) {
510     	if (errfree)
511     	    pciio_dmamap_free(map);
512     	return res;			/* pciio_dmamap_addr failed */
513         }
514         if (mapp)
515     	*mapp = map;			/* pass back map used */
516     
517         return res;				/* pciio_dmamap_addr succeeded */
518     }
519     
520     void
521     pciio_dmamap_drain(pciio_dmamap_t map)
522     {
523         DMAMAP_FUNC(map, dmamap_drain)
524     	(CAST_DMAMAP(map));
525     }
526     
527     void
528     pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
529     {
530         DEV_FUNC(dev, dmaaddr_drain)
531     	(dev, addr, size);
532     }
533     
534     void
535     pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
536     {
537         DEV_FUNC(dev, dmalist_drain)
538     	(dev, list);
539     }
540     
541     /* =====================================================================
542      *          INTERRUPT MANAGEMENT
543      *
544      *      Allow crosstalk devices to establish interrupts
545      */
546     
547     /*
548      * Allocate resources required for an interrupt as specified in intr_desc.
549      * Return resource handle in intr_hdl.
550      */
551     pciio_intr_t
552     pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
553     		 device_desc_t dev_desc,	/* device descriptor */
554     		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
555     		 devfs_handle_t owner_dev)
556     {					/* owner of this interrupt */
557         return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
558     	(dev, dev_desc, lines, owner_dev);
559     }
560     
561     /*
562      * Free resources consumed by intr_alloc.
563      */
564     void
565     pciio_intr_free(pciio_intr_t intr_hdl)
566     {
567         INTR_FUNC(intr_hdl, intr_free)
568     	(CAST_INTR(intr_hdl));
569     }
570     
571     /*
572      * Associate resources allocated with a previous pciio_intr_alloc call with the
573      * described handler, arg, name, etc.
574      *
575      * Returns 0 on success, returns <0 on failure.
576      */
577     int
578     pciio_intr_connect(pciio_intr_t intr_hdl,	/* pciio intr resource handle */
579     		   intr_func_t intr_func,	/* pciio intr handler */
580     		   intr_arg_t intr_arg,	/* arg to intr handler */
581     		   void *thread)
582     {					/* intr thread to use */
583         return INTR_FUNC(intr_hdl, intr_connect)
584     	(CAST_INTR(intr_hdl), intr_func, intr_arg, thread);
585     }
586     
587     /*
588      * Disassociate handler with the specified interrupt.
589      */
590     void
591     pciio_intr_disconnect(pciio_intr_t intr_hdl)
592     {
593         INTR_FUNC(intr_hdl, intr_disconnect)
594     	(CAST_INTR(intr_hdl));
595     }
596     
597     /*
598      * Return a hwgraph vertex that represents the CPU currently
599      * targeted by an interrupt.
600      */
601     devfs_handle_t
602     pciio_intr_cpu_get(pciio_intr_t intr_hdl)
603     {
604         return INTR_FUNC(intr_hdl, intr_cpu_get)
605     	(CAST_INTR(intr_hdl));
606     }
607     
608     /* =====================================================================
609      *          ERROR MANAGEMENT
610      */
611     
612     void
613     pciio_slot_func_to_name(char		       *name,
614     			pciio_slot_t		slot,
615     			pciio_function_t	func)
616     {
617         /*
618          * standard connection points:
619          *
620          * PCIIO_SLOT_NONE:	.../pci/direct
621          * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3
622          * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c
623          */
624     
625         if (slot == PCIIO_SLOT_NONE)
626     	sprintf(name, "direct");
627         else if (func == PCIIO_FUNC_NONE)
628     	sprintf(name, "%d", slot);
629         else
630     	sprintf(name, "%d%c", slot, 'a'+func);
631     }
632     
633     /*
634      * pciio_cardinfo_get
635      *
636      * Get the pciio info structure corresponding to the
637      * specified PCI "slot" (we like it when the same index
638      * number is used for the PCI IDSEL, the REQ/GNT pair,
639      * and the interrupt line being used for INTA. We like
640      * it so much we call it the slot number).
641      */
642     static pciio_info_t
643     pciio_cardinfo_get(
644     		      devfs_handle_t pciio_vhdl,
645     		      pciio_slot_t pci_slot)
646     {
647         char                    namebuf[16];
648         pciio_info_t	    info = 0;
649         devfs_handle_t	    conn;
650     
651         pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);
652         if (GRAPH_SUCCESS ==
653     	hwgraph_traverse(pciio_vhdl, namebuf, &conn)) {
654     	info = pciio_info_chk(conn);
655     	hwgraph_vertex_unref(conn);
656         }
657     
658         return info;
659     }
660     
661     /*
662      * pciio_error_handler:
663      * dispatch an error to the appropriate
664      * pciio connection point, or process
665      * it as a generic pci error.
666      * Yes, the first parameter is the
667      * provider vertex at the middle of
668      * the bus; we get to the pciio connect
669      * point using the ioerror widgetdev field.
670      *
671      * This function is called by the
672      * specific PCI provider, after it has figured
673      * out where on the PCI bus (including which slot,
674      * if it can tell) the error came from.
675      */
676     /*ARGSUSED */
677     int
678     pciio_error_handler(
679     		       devfs_handle_t pciio_vhdl,
680     		       int error_code,
681     		       ioerror_mode_t mode,
682     		       ioerror_t *ioerror)
683     {
684         pciio_info_t            pciio_info;
685         devfs_handle_t            pconn_vhdl;
686     #if USRPCI
687         devfs_handle_t            usrpci_v;
688     #endif
689         pciio_slot_t            slot;
690     
691         int                     retval;
692     #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
693         error_state_t	    e_state;
694     #endif
695     
696     #if DEBUG && ERROR_DEBUG
697     #if defined(SUPPORT_PRINTING_V_FORMAT)
698         printk("%v: pciio_error_handler\n", pciio_vhdl);
699     #else
700         printk("0x%x: pciio_error_handler\n", pciio_vhdl);
701     #endif
702     #endif
703     
704     #if defined(SUPPORT_PRINTING_V_FORMAT)
705         IOERR_PRINTF(printk("%v: PCI Bus Error: Error code: %d Error mode: %d\n",
706     			 pciio_vhdl, error_code, mode));
707     #else
708         IOERR_PRINTF(printk("0x%x: PCI Bus Error: Error code: %d Error mode: %d\n",
709     			 pciio_vhdl, error_code, mode));
710     #endif
711     
712         /* If there is an error handler sitting on
713          * the "no-slot" connection point, give it
714          * first crack at the error. NOTE: it is
715          * quite possible that this function may
716          * do further refining of the ioerror.
717          */
718         pciio_info = pciio_cardinfo_get(pciio_vhdl, PCIIO_SLOT_NONE);
719         if (pciio_info && pciio_info->c_efunc) {
720     	pconn_vhdl = pciio_info_dev_get(pciio_info);
721     #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
722     	e_state = error_state_get(pciio_vhdl);
723     
724     	if (e_state == ERROR_STATE_ACTION)
725     	    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
726     
727     	if (error_state_set(pconn_vhdl,e_state) ==
728     	    ERROR_RETURN_CODE_CANNOT_SET_STATE)
729     	    return(IOERROR_UNHANDLED);
730     #endif
731     	retval = pciio_info->c_efunc
732     	    (pciio_info->c_einfo, error_code, mode, ioerror);
733     	if (retval != IOERROR_UNHANDLED)
734     	    return retval;
735         }
736     
737         /* Is the error associated with a particular slot?
738          */
739         if (IOERROR_FIELDVALID(ioerror, widgetdev)) {
740     	/*
741     	 * NOTE : 
742     	 * widgetdev is a 4byte value encoded as slot in the higher order
743     	 * 2 bytes and function in the lower order 2 bytes.
744     	 */
745     #ifdef LATER
746     	slot = pciio_widgetdev_slot_get(IOERROR_GETVALUE(ioerror, widgetdev));
747     #else
748     	slot = 0;
749     #endif
750     
751     	/* If this slot has an error handler,
752     	 * deliver the error to it.
753     	 */
754     	pciio_info = pciio_cardinfo_get(pciio_vhdl, slot);
755     	if (pciio_info != NULL) {
756     	    if (pciio_info->c_efunc != NULL) {
757     
758     		pconn_vhdl = pciio_info_dev_get(pciio_info);
759     #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
760     		e_state = error_state_get(pciio_vhdl);
761     
762     
763     		if (e_state == ERROR_STATE_ACTION)
764     		    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
765     
766     
767     
768     		if (error_state_set(pconn_vhdl,e_state) ==
769     		    ERROR_RETURN_CODE_CANNOT_SET_STATE)
770     		    return(IOERROR_UNHANDLED);
771     #endif
772     		retval = pciio_info->c_efunc
773     		    (pciio_info->c_einfo, error_code, mode, ioerror);
774     		if (retval != IOERROR_UNHANDLED)
775     		    return retval;
776     	    }
777     
778     #if USRPCI
779     	    /* If the USRPCI driver is available and
780     	     * knows about this connection point,
781     	     * deliver the error to it.
782     	     *
783     	     * OK to use pconn_vhdl here, even though we
784     	     * have already UNREF'd it, since we know that
785     	     * it is not going away.
786     	     */
787     	    pconn_vhdl = pciio_info_dev_get(pciio_info);
788     	    if (GRAPH_SUCCESS ==
789     		hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) {
790     		retval = usrpci_error_handler
791     		    (usrpci_v, error_code, IOERROR_GETVALUE(ioerror, busaddr));
792     		hwgraph_vertex_unref(usrpci_v);
793     		if (retval != IOERROR_UNHANDLED) {
794     		    /*
795     		     * This unref is not needed.  If this code is called often enough,
796     		     * the system will crash, due to vertex reference count reaching 0,
797     		     * causing vertex to be unallocated.  -jeremy
798     		     * hwgraph_vertex_unref(pconn_vhdl);
799     		     */
800     		    return retval;
801     		}
802     	    }
803     #endif
804     	}
805         }
806     
807         return (mode == MODE_DEVPROBE)
808     	? IOERROR_HANDLED	/* probes are OK */
809     	: IOERROR_UNHANDLED;	/* otherwise, foo! */
810     }
811     
812     int
813     pciio_error_devenable(devfs_handle_t pconn_vhdl, int error_code)
814     {
815         return DEV_FUNC(pconn_vhdl, error_devenable)
816     	(pconn_vhdl, error_code);
817         /* no cleanup specific to this layer. */
818     }
819     
820     /* =====================================================================
821      *          CONFIGURATION MANAGEMENT
822      */
823     
824     /*
825      * Startup a crosstalk provider
826      */
827     void
828     pciio_provider_startup(devfs_handle_t pciio_provider)
829     {
830         DEV_FUNC(pciio_provider, provider_startup)
831     	(pciio_provider);
832     }
833     
834     /*
835      * Shutdown a crosstalk provider
836      */
837     void
838     pciio_provider_shutdown(devfs_handle_t pciio_provider)
839     {
840         DEV_FUNC(pciio_provider, provider_shutdown)
841     	(pciio_provider);
842     }
843     
844     /*
845      * Specify endianness constraints.  The driver tells us what the device
846      * does and how it would like to see things in memory.  We reply with
847      * how things will actually appear in memory.
848      */
849     pciio_endian_t
850     pciio_endian_set(devfs_handle_t dev,
851     		 pciio_endian_t device_end,
852     		 pciio_endian_t desired_end)
853     {
854         ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE));
855         ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));
856     
857     #if DEBUG
858     #if defined(SUPPORT_PRINTING_V_FORMAT)
859         PRINT_ALERT("%v: pciio_endian_set is going away.\n"
860     	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
861     	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
862     	    dev);
863     #else
864         PRINT_ALERT("0x%x: pciio_endian_set is going away.\n"
865     	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
866     	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
867     	    dev);
868     #endif
869     #endif
870     
871         return DEV_FUNC(dev, endian_set)
872     	(dev, device_end, desired_end);
873     }
874     
875     /*
876      * Specify PCI arbitration priority.
877      */
878     pciio_priority_t
879     pciio_priority_set(devfs_handle_t dev,
880     		   pciio_priority_t device_prio)
881     {
882         ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
883     
884         return DEV_FUNC(dev, priority_set)
885     	(dev, device_prio);
886     }
887     
888     /*
889      * Read value of configuration register
890      */
891     uint64_t
892     pciio_config_get(devfs_handle_t	dev,
893     		 unsigned	reg,
894     		 unsigned	size)
895     {
896         uint64_t	value = 0;
897         unsigned	shift = 0;
898     
899         /* handle accesses that cross words here,
900          * since that's common code between all
901          * possible providers.
902          */
903         while (size > 0) {
904     	unsigned	biw = 4 - (reg&3);
905     	if (biw > size)
906     	    biw = size;
907     
908     	value |= DEV_FUNC(dev, config_get)
909     	    (dev, reg, biw) << shift;
910     
911     	shift += 8*biw;
912     	reg += biw;
913     	size -= biw;
914         }
915         return value;
916     }
917     
918     /*
919      * Change value of configuration register
920      */
921     void
922     pciio_config_set(devfs_handle_t	dev,
923     		 unsigned	reg,
924     		 unsigned	size,
925     		 uint64_t	value)
926     {
927         /* handle accesses that cross words here,
928          * since that's common code between all
929          * possible providers.
930          */
931         while (size > 0) {
932     	unsigned	biw = 4 - (reg&3);
933     	if (biw > size)
934     	    biw = size;
935     	    
936     	DEV_FUNC(dev, config_set)
937     	    (dev, reg, biw, value);
938     	reg += biw;
939     	size -= biw;
940     	value >>= biw * 8;
941         }
942     }
943     
944     /* =====================================================================
945      *          GENERIC PCI SUPPORT FUNCTIONS
946      */
947     pciio_slot_t
948     pciio_error_extract(devfs_handle_t 	dev,
949     		   pciio_space_t 	*space,
950     		   iopaddr_t		*offset)
951     {
952     	ASSERT(dev != NODEV);
953     	return DEV_FUNC(dev,error_extract)(dev,space,offset);
954     }
955     
956     /*
957      * Issue a hardware reset to a card.
958      */
959     int
960     pciio_reset(devfs_handle_t dev)
961     {
962         return DEV_FUNC(dev, reset) (dev);
963     }
964     
965     /*
966      * flush write gather buffers
967      */
968     int
969     pciio_write_gather_flush(devfs_handle_t dev)
970     {
971         return DEV_FUNC(dev, write_gather_flush) (dev);
972     }
973     
974     devfs_handle_t
975     pciio_intr_dev_get(pciio_intr_t pciio_intr)
976     {
977         return (pciio_intr->pi_dev);
978     }
979     
980     /****** Generic crosstalk pio interfaces ******/
981     devfs_handle_t
982     pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
983     {
984         return (pciio_piomap->pp_dev);
985     }
986     
987     pciio_slot_t
988     pciio_pio_slot_get(pciio_piomap_t pciio_piomap)
989     {
990         return (pciio_piomap->pp_slot);
991     }
992     
993     pciio_space_t
994     pciio_pio_space_get(pciio_piomap_t pciio_piomap)
995     {
996         return (pciio_piomap->pp_space);
997     }
998     
999     iopaddr_t
1000     pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap)
1001     {
1002         return (pciio_piomap->pp_pciaddr);
1003     }
1004     
1005     ulong
1006     pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap)
1007     {
1008         return (pciio_piomap->pp_mapsz);
1009     }
1010     
1011     caddr_t
1012     pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap)
1013     {
1014         return (pciio_piomap->pp_kvaddr);
1015     }
1016     
1017     /****** Generic crosstalk dma interfaces ******/
1018     devfs_handle_t
1019     pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
1020     {
1021         return (pciio_dmamap->pd_dev);
1022     }
1023     
1024     pciio_slot_t
1025     pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap)
1026     {
1027         return (pciio_dmamap->pd_slot);
1028     }
1029     
1030     /****** Generic pci slot information interfaces ******/
1031     
1032     pciio_info_t
1033     pciio_info_chk(devfs_handle_t pciio)
1034     {
1035         arbitrary_info_t        ainfo = 0;
1036     
1037         hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);
1038         return (pciio_info_t) ainfo;
1039     }
1040     
1041     pciio_info_t
1042     pciio_info_get(devfs_handle_t pciio)
1043     {
1044         pciio_info_t            pciio_info;
1045     
1046         pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);
1047     
1048     #ifdef DEBUG_PCIIO
1049         {
1050     	int pos;
1051     	char dname[256];
1052     	pos = devfs_generate_path(pciio, dname, 256);
1053     	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
1054         }
1055     #endif /* DEBUG_PCIIO */
1056     
1057     #ifdef BRINGUP
1058         if ((pciio_info != NULL) &&
1059     	(pciio_info->c_fingerprint != pciio_info_fingerprint)
1060     	&& (pciio_info->c_fingerprint != NULL)) {
1061     #else
1062         if ((pciio_info != NULL) &&
1063     	(pciio_info->c_fingerprint != pciio_info_fingerprint)) {
1064     #endif /* BRINGUP */
1065     
1066     	return((pciio_info_t)-1); /* Should panic .. */
1067         }
1068     	
1069     
1070         return pciio_info;
1071     }
1072     
1073     void
1074     pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
1075     {
1076         if (pciio_info != NULL)
1077     	pciio_info->c_fingerprint = pciio_info_fingerprint;
1078         hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);
1079     
1080         /* Also, mark this vertex as a PCI slot
1081          * and use the pciio_info, so pciio_info_chk
1082          * can work (and be fairly efficient).
1083          */
1084         hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
1085     			 (arbitrary_info_t) pciio_info);
1086     }
1087     
1088     devfs_handle_t
1089     pciio_info_dev_get(pciio_info_t pciio_info)
1090     {
1091         return (pciio_info->c_vertex);
1092     }
1093     
1094     /*ARGSUSED*/
1095     pciio_bus_t
1096     pciio_info_bus_get(pciio_info_t pciio_info)
1097     {
1098         /* XXX for now O2 always gets back bus 0 */
1099         return (pciio_bus_t)0;
1100     }
1101     
1102     pciio_slot_t
1103     pciio_info_slot_get(pciio_info_t pciio_info)
1104     {
1105         return (pciio_info->c_slot);
1106     }
1107     
1108     pciio_function_t
1109     pciio_info_function_get(pciio_info_t pciio_info)
1110     {
1111         return (pciio_info->c_func);
1112     }
1113     
1114     pciio_vendor_id_t
1115     pciio_info_vendor_id_get(pciio_info_t pciio_info)
1116     {
1117         return (pciio_info->c_vendor);
1118     }
1119     
1120     pciio_device_id_t
1121     pciio_info_device_id_get(pciio_info_t pciio_info)
1122     {
1123         return (pciio_info->c_device);
1124     }
1125     
1126     devfs_handle_t
1127     pciio_info_master_get(pciio_info_t pciio_info)
1128     {
1129         return (pciio_info->c_master);
1130     }
1131     
1132     arbitrary_info_t
1133     pciio_info_mfast_get(pciio_info_t pciio_info)
1134     {
1135         return (pciio_info->c_mfast);
1136     }
1137     
1138     pciio_provider_t       *
1139     pciio_info_pops_get(pciio_info_t pciio_info)
1140     {
1141         return (pciio_info->c_pops);
1142     }
1143     
1144     error_handler_f	       *
1145     pciio_info_efunc_get(pciio_info_t pciio_info)
1146     {
1147         return (pciio_info->c_efunc);
1148     }
1149     
1150     error_handler_arg_t    *
1151     pciio_info_einfo_get(pciio_info_t pciio_info)
1152     {
1153         return (pciio_info->c_einfo);
1154     }
1155     
1156     pciio_space_t
1157     pciio_info_bar_space_get(pciio_info_t info, int win)
1158     {
1159         return info->c_window[win].w_space;
1160     }
1161     
1162     iopaddr_t
1163     pciio_info_bar_base_get(pciio_info_t info, int win)
1164     {
1165         return info->c_window[win].w_base;
1166     }
1167     
1168     size_t
1169     pciio_info_bar_size_get(pciio_info_t info, int win)
1170     {
1171         return info->c_window[win].w_size;
1172     }
1173     
1174     iopaddr_t
1175     pciio_info_rom_base_get(pciio_info_t info)
1176     {
1177         return info->c_rbase;
1178     }
1179     
1180     size_t
1181     pciio_info_rom_size_get(pciio_info_t info)
1182     {
1183         return info->c_rsize;
1184     }
1185     
1186     
1187     /* =====================================================================
1188      *          GENERIC PCI INITIALIZATION FUNCTIONS
1189      */
1190     
1191     /*
1192      *    pciioinit: called once during device driver
1193      *      initializtion if this driver is configured into
1194      *      the system.
1195      */
1196     void
1197     pciio_init(void)
1198     {
1199         cdl_p                   cp;
1200     
1201     #if DEBUG && ATTACH_DEBUG
1202         printf("pciio_init\n");
1203     #endif
1204         /* Allocate the registry.
1205          * We might already have one.
1206          * If we don't, go get one.
1207          * MPness: someone might have
1208          * set one up for us while we
1209          * were not looking; use an atomic
1210          * compare-and-swap to commit to
1211          * using the new registry if and
1212          * only if nobody else did first.
1213          * If someone did get there first,
1214          * toss the one we allocated back
1215          * into the pool.
1216          */
1217         if (pciio_registry == NULL) {
1218     	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
1219     	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
1220     	    cdl_del(cp);
1221     	}
1222         }
1223         ASSERT(pciio_registry != NULL);
1224     }
1225     
1226     /*
1227      *    pciioattach: called for each vertex in the graph
1228      *      that is a PCI provider.
1229      */
1230     /*ARGSUSED */
1231     int
1232     pciio_attach(devfs_handle_t pciio)
1233     {
1234     #if DEBUG && ATTACH_DEBUG
1235     #if defined(SUPPORT_PRINTING_V_FORMAT)
1236         printk("%v: pciio_attach\n", pciio);
1237     #else
1238         printk("0x%x: pciio_attach\n", pciio);
1239     #endif
1240     #endif
1241         return 0;
1242     }
1243     
1244     /*
1245      * Associate a set of pciio_provider functions with a vertex.
1246      */
1247     void
1248     pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
1249     {
1250         hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
1251     }
1252     
1253     /*
1254      * Disassociate a set of pciio_provider functions with a vertex.
1255      */
1256     void
1257     pciio_provider_unregister(devfs_handle_t provider)
1258     {
1259         arbitrary_info_t        ainfo;
1260     
1261         hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
1262     }
1263     
1264     /*
1265      * Obtain a pointer to the pciio_provider functions for a specified Crosstalk
1266      * provider.
1267      */
1268     pciio_provider_t       *
1269     pciio_provider_fns_get(devfs_handle_t provider)
1270     {
1271         arbitrary_info_t        ainfo = 0;
1272     
1273         (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
1274         return (pciio_provider_t *) ainfo;
1275     }
1276     
1277     /*ARGSUSED4 */
1278     int
1279     pciio_driver_register(
1280     			 pciio_vendor_id_t vendor_id,
1281     			 pciio_device_id_t device_id,
1282     			 char *driver_prefix,
1283     			 unsigned flags)
1284     {
1285         /* a driver's init routine might call
1286          * pciio_driver_register before the
1287          * system calls pciio_init; so we
1288          * make the init call ourselves here.
1289          */
1290         if (pciio_registry == NULL)
1291     	pciio_init();
1292     
1293         return cdl_add_driver(pciio_registry,
1294     			  vendor_id, device_id,
1295     			  driver_prefix, flags, NULL);
1296     }
1297     
1298     /*
1299      * Remove an initialization function.
1300      */
1301     void
1302     pciio_driver_unregister(
1303     			   char *driver_prefix)
1304     {
1305         /* before a driver calls unregister,
1306          * it must have called register; so
1307          * we can assume we have a registry here.
1308          */
1309         ASSERT(pciio_registry != NULL);
1310     
1311         cdl_del_driver(pciio_registry, driver_prefix, NULL);
1312     }
1313     
1314     /* 
1315      * Set the slot status for a device supported by the 
1316      * driver being registered.
1317      */
1318     void
1319     pciio_driver_reg_callback(
1320                                devfs_handle_t pconn_vhdl,
1321     			   int key1,
1322     			   int key2,
1323                                int error)
1324     {
1325     }
1326     
1327     /* 
1328      * Set the slot status for a device supported by the 
1329      * driver being unregistered.
1330      */
1331     void
1332     pciio_driver_unreg_callback(
1333                                devfs_handle_t pconn_vhdl,
1334     			   int key1,
1335     			   int key2,
1336                                int error)
1337     {
1338     }
1339     
1340     /*
1341      * Call some function with each vertex that
1342      * might be one of this driver's attach points.
1343      */
1344     void
1345     pciio_iterate(char *driver_prefix,
1346     	      pciio_iter_f * func)
1347     {
1348         /* a driver's init routine might call
1349          * pciio_iterate before the
1350          * system calls pciio_init; so we
1351          * make the init call ourselves here.
1352          */
1353         if (pciio_registry == NULL)
1354     	pciio_init();
1355     
1356         ASSERT(pciio_registry != NULL);
1357     
1358         cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
1359     }
1360     
1361     devfs_handle_t
1362     pciio_device_register(
1363     		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
1364     		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
1365     		pciio_slot_t slot,	/* card's slot */
1366     		pciio_function_t func,	/* card's func */
1367     		pciio_vendor_id_t vendor_id,
1368     		pciio_device_id_t device_id)
1369     {
1370         return pciio_device_info_register
1371     	(connectpt, pciio_device_info_new (NULL, master, slot, func,
1372     					   vendor_id, device_id));
1373     }
1374     
1375     void
1376     pciio_device_unregister(devfs_handle_t pconn)
1377     {
1378         DEV_FUNC(pconn,device_unregister)(pconn);
1379     }
1380     
1381     pciio_info_t
1382     pciio_device_info_new(
1383     		pciio_info_t pciio_info,
1384     		devfs_handle_t master,
1385     		pciio_slot_t slot,
1386     		pciio_function_t func,
1387     		pciio_vendor_id_t vendor_id,
1388     		pciio_device_id_t device_id)
1389     {
1390         if (!pciio_info)
1391     	NEW(pciio_info);
1392         ASSERT(pciio_info != NULL);
1393     
1394         pciio_info->c_slot = slot;
1395         pciio_info->c_func = func;
1396         pciio_info->c_vendor = vendor_id;
1397         pciio_info->c_device = device_id;
1398         pciio_info->c_master = master;
1399         pciio_info->c_mfast = hwgraph_fastinfo_get(master);
1400         pciio_info->c_pops = pciio_provider_fns_get(master);
1401         pciio_info->c_efunc = 0;
1402         pciio_info->c_einfo = 0;
1403     
1404         return pciio_info;
1405     }
1406     
1407     void
1408     pciio_device_info_free(pciio_info_t pciio_info)
1409     {
1410         /* NOTE : pciio_info is a structure within the pcibr_info
1411          *	      and not a pointer to memory allocated on the heap !!
1412          */
1413         BZERO((char *)pciio_info,sizeof(pciio_info));
1414     }
1415     
1416     devfs_handle_t
1417     pciio_device_info_register(
1418     		devfs_handle_t connectpt,		/* vertex at center of bus */
1419     		pciio_info_t pciio_info)	/* details about the connectpt */
1420     {
1421         char		name[32];
1422         devfs_handle_t	pconn;
1423     
1424         pciio_slot_func_to_name(name,
1425     			    pciio_info->c_slot,
1426     			    pciio_info->c_func);
1427     
1428         if (GRAPH_SUCCESS !=
1429     	hwgraph_path_add(connectpt, name, &pconn))
1430     	return pconn;
1431     
1432         pciio_info->c_vertex = pconn;
1433         pciio_info_set(pconn, pciio_info);
1434     #ifdef BRINGUP
1435         {
1436     	int pos;
1437     	char dname[256];
1438     	pos = devfs_generate_path(pconn, dname, 256);
1439     #ifdef DEBUG_PCIIO
1440     	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
1441     #endif
1442         }
1443     #endif /* BRINGUP */
1444     
1445         /*
1446          * create link to our pci provider
1447          */
1448     
1449         device_master_set(pconn, pciio_info->c_master);
1450     
1451     #if USRPCI
1452         /*
1453          * Call into usrpci provider to let it initialize for
1454          * the given slot.
1455          */
1456         if (pciio_info->c_slot != PCIIO_SLOT_NONE)
1457     	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
1458     #endif
1459     
1460         return pconn;
1461     }
1462     
1463     void
1464     pciio_device_info_unregister(devfs_handle_t connectpt,
1465     			     pciio_info_t pciio_info)
1466     {
1467         char		name[32];
1468         devfs_handle_t	pconn;
1469     
1470         if (!pciio_info)
1471     	return;
1472     
1473         pciio_slot_func_to_name(name,
1474     			    pciio_info->c_slot,
1475     			    pciio_info->c_func);
1476     
1477         hwgraph_edge_remove(connectpt,name,&pconn);
1478         pciio_info_set(pconn,0);
1479     
1480         /* Remove the link to our pci provider */
1481         hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
1482     
1483     
1484         hwgraph_vertex_unref(pconn);
1485         hwgraph_vertex_destroy(pconn);
1486         
1487     }
1488     /* Add the pci card inventory information to the hwgraph
1489      */
1490     static void
1491     pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
1492     {
1493         pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
1494     
1495         ASSERT(pciio_info);
1496         ASSERT(pciio_info->c_vertex == pconn_vhdl);
1497     
1498         /* Donot add inventory  for non-existent devices */
1499         if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE)	||
1500     	(pciio_info->c_device == PCIIO_DEVICE_ID_NONE))
1501     	return;
1502         device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP,
1503     			 pciio_info->c_vendor,pciio_info->c_device,
1504     			 pciio_info->c_slot);
1505     }
1506     
1507     static void
1508     pciio_device_inventory_remove(devfs_handle_t pconn_vhdl)
1509     {
1510     #ifdef LATER
1511         hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1);
1512     #endif
1513     }
1514     
1515     /*ARGSUSED */
1516     int
1517     pciio_device_attach(devfs_handle_t pconn,
1518     		    int          drv_flags)
1519     {
1520         pciio_info_t            pciio_info;
1521         pciio_vendor_id_t       vendor_id;
1522         pciio_device_id_t       device_id;
1523         int pciba_attach(devfs_handle_t);
1524     
1525     
1526         pciio_device_inventory_add(pconn);
1527         pciio_info = pciio_info_get(pconn);
1528     
1529         vendor_id = pciio_info->c_vendor;
1530         device_id = pciio_info->c_device;
1531     
1532         /* we don't start attaching things until
1533          * all the driver init routines (including
1534          * pciio_init) have been called; so we
1535          * can assume here that we have a registry.
1536          */
1537         ASSERT(pciio_registry != NULL);
1538     
1539         /*
1540          * Since pciba is not called from cdl routines .. call it here.
1541          */
1542         pciba_attach(pconn);
1543     
1544         return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
1545     }
1546     
1547     int
1548     pciio_device_detach(devfs_handle_t pconn,
1549     		    int          drv_flags)
1550     {
1551         pciio_info_t            pciio_info;
1552         pciio_vendor_id_t       vendor_id;
1553         pciio_device_id_t       device_id;
1554     
1555         pciio_device_inventory_remove(pconn);
1556         pciio_info = pciio_info_get(pconn);
1557     
1558         vendor_id = pciio_info->c_vendor;
1559         device_id = pciio_info->c_device;
1560     
1561         /* we don't start attaching things until
1562          * all the driver init routines (including
1563          * pciio_init) have been called; so we
1564          * can assume here that we have a registry.
1565          */
1566         ASSERT(pciio_registry != NULL);
1567     
1568         return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
1569     		          pconn, drv_flags));
1570     
1571     }
1572     
1573     /*
1574      * pciio_error_register:
1575      * arrange for a function to be called with
1576      * a specified first parameter plus other
1577      * information when an error is encountered
1578      * and traced to the pci slot corresponding
1579      * to the connection point pconn.
1580      *
1581      * may also be called with a null function
1582      * pointer to "unregister" the error handler.
1583      *
1584      * NOTE: subsequent calls silently overwrite
1585      * previous data for this vertex. We assume that
1586      * cooperating drivers, well, cooperate ...
1587      */
1588     void
1589     pciio_error_register(devfs_handle_t pconn,
1590     		     error_handler_f *efunc,
1591     		     error_handler_arg_t einfo)
1592     {
1593         pciio_info_t            pciio_info;
1594     
1595         pciio_info = pciio_info_get(pconn);
1596         ASSERT(pciio_info != NULL);
1597         pciio_info->c_efunc = efunc;
1598         pciio_info->c_einfo = einfo;
1599     }
1600     
1601     /*
1602      * Check if any device has been found in this slot, and return
1603      * true or false
1604      * vhdl is the vertex for the slot
1605      */
1606     int
1607     pciio_slot_inuse(devfs_handle_t pconn_vhdl)
1608     {
1609         pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
1610     
1611         ASSERT(pciio_info);
1612         ASSERT(pciio_info->c_vertex == pconn_vhdl);
1613         if (pciio_info->c_vendor) {
1614     	/*
1615     	 * Non-zero value for vendor indicate
1616     	 * a board being found in this slot.
1617     	 */
1618     	return 1;
1619         }
1620         return 0;
1621     }
1622     
1623     int
1624     pciio_dma_enabled(devfs_handle_t pconn_vhdl)
1625     {
1626     	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
1627     }
1628