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-2003 Silicon Graphics, Inc. All rights reserved.
8  */
9 
10 #include <linux/init.h>
11 #include <linux/types.h>
12 #include <linux/pci.h>
13 #include <linux/pci_ids.h>
14 #include <linux/sched.h>
15 #include <linux/ioport.h>
16 #include <linux/slab.h>
17 #include <asm/sn/sgi.h>
18 #include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
19 #include <asm/sn/iograph.h>
20 #include <asm/sn/invent.h>
21 #include <asm/sn/hcl.h>
22 #include <asm/sn/hcl_util.h>
23 #include <asm/sn/labelcl.h>
24 #include <asm/sn/pci/bridge.h>
25 #include <asm/sn/ioerror_handling.h>
26 #include <asm/sn/pci/pciio.h>
27 #include <asm/sn/pci/pciio_private.h>
28 #include <asm/sn/sn_sal.h>
29 #include <asm/sn/io.h>
30 #include <asm/sn/pci/pci_bus_cvlink.h>
31 #include <asm/sn/simulator.h>
32 
33 #define DEBUG_PCIIO
34 #undef DEBUG_PCIIO	/* turn this on for yet more console output */
35 
36 
37 char                    pciio_info_fingerprint[] = "pciio_info";
38 
39 /* =====================================================================
40  *    PCI Generic Bus Provider
41  * Implement PCI provider operations.  The pciio* layer provides a
42  * platform-independent interface for PCI devices.  This layer
43  * switches among the possible implementations of a PCI adapter.
44  */
45 
46 /* =====================================================================
47  *    Provider Function Location SHORTCUT
48  *
49  * On platforms with only one possible PCI provider, macros can be
50  * set up at the top that cause the table lookups and indirections to
51  * completely disappear.
52  */
53 
54 
55 /* =====================================================================
56  *    Function Table of Contents
57  */
58 
59 #if !defined(DEV_FUNC)
60 extern pciio_provider_t *pciio_to_provider_fns(vertex_hdl_t dev);
61 #endif
62 
63 /* =====================================================================
64  *    Provider Function Location
65  *
66  *      If there is more than one possible provider for
67  *      this platform, we need to examine the master
68  *      vertex of the current vertex for a provider
69  *      function structure, and indirect through the
70  *      appropriately named member.
71  */
72 
73 #if !defined(DEV_FUNC)
74 
75 pciio_provider_t *
pciio_to_provider_fns(vertex_hdl_t dev)76 pciio_to_provider_fns(vertex_hdl_t dev)
77 {
78     pciio_info_t            card_info;
79     pciio_provider_t       *provider_fns;
80 
81     /*
82      * We're called with two types of vertices, one is
83      * the bridge vertex (ends with "pci") and the other is the
84      * pci slot vertex (ends with "pci/[0-8]").  For the first type
85      * we need to get the provider from the PFUNCS label.  For
86      * the second we get it from fastinfo/c_pops.
87      */
88     provider_fns = pciio_provider_fns_get(dev);
89     if (provider_fns == NULL) {
90 	card_info = pciio_info_get(dev);
91 	if (card_info != NULL) {
92 		provider_fns = pciio_info_pops_get(card_info);
93 	}
94     }
95 
96     if (provider_fns == NULL) {
97 	char devname[MAXDEVNAME];
98 	panic("%s: provider_fns == NULL", vertex_to_name(dev, devname, MAXDEVNAME));
99     }
100     return provider_fns;
101 
102 }
103 
104 #define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
105 #define CAST_PIOMAP(x)		((pciio_piomap_t)(x))
106 #define CAST_DMAMAP(x)		((pciio_dmamap_t)(x))
107 #define CAST_INTR(x)		((pciio_intr_t)(x))
108 #endif
109 
110 /*
111  * Many functions are not passed their vertex
112  * information directly; rather, they must
113  * dive through a resource map. These macros
114  * are available to coordinate this detail.
115  */
116 #define PIOMAP_FUNC(map,func)		DEV_FUNC((map)->pp_dev,func)
117 #define DMAMAP_FUNC(map,func)		DEV_FUNC((map)->pd_dev,func)
118 #define INTR_FUNC(intr_hdl,func)	DEV_FUNC((intr_hdl)->pi_dev,func)
119 
120 /* =====================================================================
121  *          PIO MANAGEMENT
122  *
123  *      For mapping system virtual address space to
124  *      pciio space on a specified card
125  */
126 
127 pciio_piomap_t
pciio_piomap_alloc(vertex_hdl_t dev,device_desc_t dev_desc,pciio_space_t space,iopaddr_t addr,size_t byte_count,size_t byte_count_max,unsigned flags)128 pciio_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
129 		   device_desc_t dev_desc,	/* device descriptor */
130 		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
131 		   iopaddr_t addr,	/* lowest address (or offset in window) */
132 		   size_t byte_count,	/* size of region containing our mappings */
133 		   size_t byte_count_max,	/* maximum size of a mapping */
134 		   unsigned flags)
135 {					/* defined in sys/pio.h */
136     return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc)
137 	(dev, dev_desc, space, addr, byte_count, byte_count_max, flags);
138 }
139 
140 void
pciio_piomap_free(pciio_piomap_t pciio_piomap)141 pciio_piomap_free(pciio_piomap_t pciio_piomap)
142 {
143     PIOMAP_FUNC(pciio_piomap, piomap_free)
144 	(CAST_PIOMAP(pciio_piomap));
145 }
146 
147 caddr_t
pciio_piomap_addr(pciio_piomap_t pciio_piomap,iopaddr_t pciio_addr,size_t byte_count)148 pciio_piomap_addr(pciio_piomap_t pciio_piomap,	/* mapping resources */
149 		  iopaddr_t pciio_addr,	/* map for this pciio address */
150 		  size_t byte_count)
151 {					/* map this many bytes */
152     pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr)
153 	(CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count);
154 
155     return pciio_piomap->pp_kvaddr;
156 }
157 
158 void
pciio_piomap_done(pciio_piomap_t pciio_piomap)159 pciio_piomap_done(pciio_piomap_t pciio_piomap)
160 {
161     PIOMAP_FUNC(pciio_piomap, piomap_done)
162 	(CAST_PIOMAP(pciio_piomap));
163 }
164 
165 caddr_t
pciio_piotrans_addr(vertex_hdl_t dev,device_desc_t dev_desc,pciio_space_t space,iopaddr_t addr,size_t byte_count,unsigned flags)166 pciio_piotrans_addr(vertex_hdl_t dev,	/* translate for this device */
167 		    device_desc_t dev_desc,	/* device descriptor */
168 		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
169 		    iopaddr_t addr,	/* starting address (or offset in window) */
170 		    size_t byte_count,	/* map this many bytes */
171 		    unsigned flags)
172 {					/* (currently unused) */
173     return DEV_FUNC(dev, piotrans_addr)
174 	(dev, dev_desc, space, addr, byte_count, flags);
175 }
176 
177 caddr_t
pciio_pio_addr(vertex_hdl_t dev,device_desc_t dev_desc,pciio_space_t space,iopaddr_t addr,size_t byte_count,pciio_piomap_t * mapp,unsigned flags)178 pciio_pio_addr(vertex_hdl_t dev,	/* translate for this device */
179 	       device_desc_t dev_desc,	/* device descriptor */
180 	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
181 	       iopaddr_t addr,		/* starting address (or offset in window) */
182 	       size_t byte_count,	/* map this many bytes */
183 	       pciio_piomap_t *mapp,	/* where to return the map pointer */
184 	       unsigned flags)
185 {					/* PIO flags */
186     pciio_piomap_t          map = 0;
187     int			    errfree = 0;
188     caddr_t                 res;
189 
190     if (mapp) {
191 	map = *mapp;			/* possible pre-allocated map */
192 	*mapp = 0;			/* record "no map used" */
193     }
194 
195     res = pciio_piotrans_addr
196 	(dev, dev_desc, space, addr, byte_count, flags);
197     if (res)
198 	return res;			/* pciio_piotrans worked */
199 
200     if (!map) {
201 	map = pciio_piomap_alloc
202 	    (dev, dev_desc, space, addr, byte_count, byte_count, flags);
203 	if (!map)
204 	    return res;			/* pciio_piomap_alloc failed */
205 	errfree = 1;
206     }
207 
208     res = pciio_piomap_addr
209 	(map, addr, byte_count);
210     if (!res) {
211 	if (errfree)
212 	    pciio_piomap_free(map);
213 	return res;			/* pciio_piomap_addr failed */
214     }
215     if (mapp)
216 	*mapp = map;			/* pass back map used */
217 
218     return res;				/* pciio_piomap_addr succeeded */
219 }
220 
221 iopaddr_t
pciio_piospace_alloc(vertex_hdl_t dev,device_desc_t dev_desc,pciio_space_t space,size_t byte_count,size_t align)222 pciio_piospace_alloc(vertex_hdl_t dev,	/* Device requiring space */
223 		     device_desc_t dev_desc,	/* Device descriptor */
224 		     pciio_space_t space,	/* MEM32/MEM64/IO */
225 		     size_t byte_count,	/* Size of mapping */
226 		     size_t align)
227 {					/* Alignment needed */
228     if (align < PAGE_SIZE)
229 	align = PAGE_SIZE;
230     return DEV_FUNC(dev, piospace_alloc)
231 	(dev, dev_desc, space, byte_count, align);
232 }
233 
234 void
pciio_piospace_free(vertex_hdl_t dev,pciio_space_t space,iopaddr_t pciaddr,size_t byte_count)235 pciio_piospace_free(vertex_hdl_t dev,	/* Device freeing space */
236 		    pciio_space_t space,	/* Type of space        */
237 		    iopaddr_t pciaddr,	/* starting address */
238 		    size_t byte_count)
239 {					/* Range of address   */
240     DEV_FUNC(dev, piospace_free)
241 	(dev, space, pciaddr, byte_count);
242 }
243 
244 /* =====================================================================
245  *          DMA MANAGEMENT
246  *
247  *      For mapping from pci space to system
248  *      physical space.
249  */
250 
251 pciio_dmamap_t
pciio_dmamap_alloc(vertex_hdl_t dev,device_desc_t dev_desc,size_t byte_count_max,unsigned flags)252 pciio_dmamap_alloc(vertex_hdl_t dev,	/* set up mappings for this device */
253 		   device_desc_t dev_desc,	/* device descriptor */
254 		   size_t byte_count_max,	/* max size of a mapping */
255 		   unsigned flags)
256 {					/* defined in dma.h */
257     return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
258 	(dev, dev_desc, byte_count_max, flags);
259 }
260 
261 void
pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)262 pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
263 {
264     DMAMAP_FUNC(pciio_dmamap, dmamap_free)
265 	(CAST_DMAMAP(pciio_dmamap));
266 }
267 
268 iopaddr_t
pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,paddr_t paddr,size_t byte_count)269 pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
270 		  paddr_t paddr,	/* map for this address */
271 		  size_t byte_count)
272 {					/* map this many bytes */
273     return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
274 	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
275 }
276 
277 void
pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)278 pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
279 {
280     DMAMAP_FUNC(pciio_dmamap, dmamap_done)
281 	(CAST_DMAMAP(pciio_dmamap));
282 }
283 
284 iopaddr_t
pciio_dmatrans_addr(vertex_hdl_t dev,device_desc_t dev_desc,paddr_t paddr,size_t byte_count,unsigned flags)285 pciio_dmatrans_addr(vertex_hdl_t dev,	/* translate for this device */
286 		    device_desc_t dev_desc,	/* device descriptor */
287 		    paddr_t paddr,	/* system physical address */
288 		    size_t byte_count,	/* length */
289 		    unsigned flags)
290 {					/* defined in dma.h */
291     return DEV_FUNC(dev, dmatrans_addr)
292 	(dev, dev_desc, paddr, byte_count, flags);
293 }
294 
295 iopaddr_t
pciio_dma_addr(vertex_hdl_t dev,device_desc_t dev_desc,paddr_t paddr,size_t byte_count,pciio_dmamap_t * mapp,unsigned flags)296 pciio_dma_addr(vertex_hdl_t dev,	/* translate for this device */
297 	       device_desc_t dev_desc,	/* device descriptor */
298 	       paddr_t paddr,		/* system physical address */
299 	       size_t byte_count,	/* length */
300 	       pciio_dmamap_t *mapp,	/* map to use, then map we used */
301 	       unsigned flags)
302 {					/* PIO flags */
303     pciio_dmamap_t          map = 0;
304     int			    errfree = 0;
305     iopaddr_t               res;
306 
307     if (mapp) {
308 	map = *mapp;			/* possible pre-allocated map */
309 	*mapp = 0;			/* record "no map used" */
310     }
311 
312     res = pciio_dmatrans_addr
313 	(dev, dev_desc, paddr, byte_count, flags);
314     if (res)
315 	return res;			/* pciio_dmatrans worked */
316 
317     if (!map) {
318 	map = pciio_dmamap_alloc
319 	    (dev, dev_desc, byte_count, flags);
320 	if (!map)
321 	    return res;			/* pciio_dmamap_alloc failed */
322 	errfree = 1;
323     }
324 
325     res = pciio_dmamap_addr
326 	(map, paddr, byte_count);
327     if (!res) {
328 	if (errfree)
329 	    pciio_dmamap_free(map);
330 	return res;			/* pciio_dmamap_addr failed */
331     }
332     if (mapp)
333 	*mapp = map;			/* pass back map used */
334 
335     return res;				/* pciio_dmamap_addr succeeded */
336 }
337 
338 void
pciio_dmamap_drain(pciio_dmamap_t map)339 pciio_dmamap_drain(pciio_dmamap_t map)
340 {
341     DMAMAP_FUNC(map, dmamap_drain)
342 	(CAST_DMAMAP(map));
343 }
344 
345 void
pciio_dmaaddr_drain(vertex_hdl_t dev,paddr_t addr,size_t size)346 pciio_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
347 {
348     DEV_FUNC(dev, dmaaddr_drain)
349 	(dev, addr, size);
350 }
351 
352 void
pciio_dmalist_drain(vertex_hdl_t dev,alenlist_t list)353 pciio_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
354 {
355     DEV_FUNC(dev, dmalist_drain)
356 	(dev, list);
357 }
358 
359 /* =====================================================================
360  *          INTERRUPT MANAGEMENT
361  *
362  *      Allow crosstalk devices to establish interrupts
363  */
364 
365 /*
366  * Allocate resources required for an interrupt as specified in intr_desc.
367  * Return resource handle in intr_hdl.
368  */
369 pciio_intr_t
pciio_intr_alloc(vertex_hdl_t dev,device_desc_t dev_desc,pciio_intr_line_t lines,vertex_hdl_t owner_dev)370 pciio_intr_alloc(vertex_hdl_t dev,	/* which Crosstalk device */
371 		 device_desc_t dev_desc,	/* device descriptor */
372 		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
373 		 vertex_hdl_t owner_dev)
374 {					/* owner of this interrupt */
375     return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
376 	(dev, dev_desc, lines, owner_dev);
377 }
378 
379 /*
380  * Free resources consumed by intr_alloc.
381  */
382 void
pciio_intr_free(pciio_intr_t intr_hdl)383 pciio_intr_free(pciio_intr_t intr_hdl)
384 {
385     INTR_FUNC(intr_hdl, intr_free)
386 	(CAST_INTR(intr_hdl));
387 }
388 
389 /*
390  * Associate resources allocated with a previous pciio_intr_alloc call with the
391  * described handler, arg, name, etc.
392  *
393  * Returns 0 on success, returns <0 on failure.
394  */
395 int
pciio_intr_connect(pciio_intr_t intr_hdl,intr_func_t intr_func,intr_arg_t intr_arg)396 pciio_intr_connect(pciio_intr_t intr_hdl,
397 		intr_func_t intr_func, intr_arg_t intr_arg)	/* pciio intr resource handle */
398 {
399     return INTR_FUNC(intr_hdl, intr_connect)
400 	(CAST_INTR(intr_hdl), intr_func, intr_arg);
401 }
402 
403 /*
404  * Disassociate handler with the specified interrupt.
405  */
406 void
pciio_intr_disconnect(pciio_intr_t intr_hdl)407 pciio_intr_disconnect(pciio_intr_t intr_hdl)
408 {
409     INTR_FUNC(intr_hdl, intr_disconnect)
410 	(CAST_INTR(intr_hdl));
411 }
412 
413 /*
414  * Return a hwgraph vertex that represents the CPU currently
415  * targeted by an interrupt.
416  */
417 vertex_hdl_t
pciio_intr_cpu_get(pciio_intr_t intr_hdl)418 pciio_intr_cpu_get(pciio_intr_t intr_hdl)
419 {
420     return INTR_FUNC(intr_hdl, intr_cpu_get)
421 	(CAST_INTR(intr_hdl));
422 }
423 
424 void
pciio_slot_func_to_name(char * name,pciio_slot_t slot,pciio_function_t func)425 pciio_slot_func_to_name(char		       *name,
426 			pciio_slot_t		slot,
427 			pciio_function_t	func)
428 {
429     /*
430      * standard connection points:
431      *
432      * PCIIO_SLOT_NONE:	.../pci/direct
433      * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3
434      * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c
435      */
436 
437     if (slot == PCIIO_SLOT_NONE)
438 	sprintf(name, EDGE_LBL_DIRECT);
439     else if (func == PCIIO_FUNC_NONE)
440 	sprintf(name, "%d", slot);
441     else
442 	sprintf(name, "%d%c", slot, 'a'+func);
443 }
444 
445 /*
446  * pciio_cardinfo_get
447  *
448  * Get the pciio info structure corresponding to the
449  * specified PCI "slot" (we like it when the same index
450  * number is used for the PCI IDSEL, the REQ/GNT pair,
451  * and the interrupt line being used for INTA. We like
452  * it so much we call it the slot number).
453  */
454 static pciio_info_t
pciio_cardinfo_get(vertex_hdl_t pciio_vhdl,pciio_slot_t pci_slot)455 pciio_cardinfo_get(
456 		      vertex_hdl_t pciio_vhdl,
457 		      pciio_slot_t pci_slot)
458 {
459     char                    namebuf[16];
460     pciio_info_t	    info = 0;
461     vertex_hdl_t	    conn;
462 
463     pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);
464     if (GRAPH_SUCCESS ==
465 	hwgraph_traverse(pciio_vhdl, namebuf, &conn)) {
466 	info = pciio_info_chk(conn);
467 	hwgraph_vertex_unref(conn);
468     }
469 
470     return info;
471 }
472 
473 
474 /*
475  * pciio_error_handler:
476  * dispatch an error to the appropriate
477  * pciio connection point, or process
478  * it as a generic pci error.
479  * Yes, the first parameter is the
480  * provider vertex at the middle of
481  * the bus; we get to the pciio connect
482  * point using the ioerror widgetdev field.
483  *
484  * This function is called by the
485  * specific PCI provider, after it has figured
486  * out where on the PCI bus (including which slot,
487  * if it can tell) the error came from.
488  */
489 /*ARGSUSED */
490 int
pciio_error_handler(vertex_hdl_t pciio_vhdl,int error_code,ioerror_mode_t mode,ioerror_t * ioerror)491 pciio_error_handler(
492 		       vertex_hdl_t pciio_vhdl,
493 		       int error_code,
494 		       ioerror_mode_t mode,
495 		       ioerror_t *ioerror)
496 {
497     pciio_info_t            pciio_info;
498     vertex_hdl_t            pconn_vhdl;
499     pciio_slot_t            slot;
500 
501     int                     retval;
502 
503 #if DEBUG && ERROR_DEBUG
504     printk("%v: pciio_error_handler\n", pciio_vhdl);
505 #endif
506 
507     IOERR_PRINTF(printk(KERN_NOTICE "%v: PCI Bus Error: Error code: %d Error mode: %d\n",
508 			 pciio_vhdl, error_code, mode));
509 
510     /* If there is an error handler sitting on
511      * the "no-slot" connection point, give it
512      * first crack at the error. NOTE: it is
513      * quite possible that this function may
514      * do further refining of the ioerror.
515      */
516     pciio_info = pciio_cardinfo_get(pciio_vhdl, PCIIO_SLOT_NONE);
517     if (pciio_info && pciio_info->c_efunc) {
518 	pconn_vhdl = pciio_info_dev_get(pciio_info);
519 
520 	retval = pciio_info->c_efunc
521 	    (pciio_info->c_einfo, error_code, mode, ioerror);
522 	if (retval != IOERROR_UNHANDLED)
523 	    return retval;
524     }
525 
526     /* Is the error associated with a particular slot?
527      */
528     if (IOERROR_FIELDVALID(ioerror, widgetdev)) {
529 	short widgetdev;
530 	/*
531 	 * NOTE :
532 	 * widgetdev is a 4byte value encoded as slot in the higher order
533 	 * 2 bytes and function in the lower order 2 bytes.
534 	 */
535 	IOERROR_GETVALUE(widgetdev, ioerror, widgetdev);
536 	slot = pciio_widgetdev_slot_get(widgetdev);
537 
538 	/* If this slot has an error handler,
539 	 * deliver the error to it.
540 	 */
541 	pciio_info = pciio_cardinfo_get(pciio_vhdl, slot);
542 	if (pciio_info != NULL) {
543 	    if (pciio_info->c_efunc != NULL) {
544 
545 		pconn_vhdl = pciio_info_dev_get(pciio_info);
546 
547 		retval = pciio_info->c_efunc
548 		    (pciio_info->c_einfo, error_code, mode, ioerror);
549 		if (retval != IOERROR_UNHANDLED)
550 		    return retval;
551 	    }
552 	}
553     }
554 
555     return (mode == MODE_DEVPROBE)
556 	? IOERROR_HANDLED	/* probes are OK */
557 	: IOERROR_UNHANDLED;	/* otherwise, foo! */
558 }
559 
560 /* =====================================================================
561  *          CONFIGURATION MANAGEMENT
562  */
563 
564 /*
565  * Startup a crosstalk provider
566  */
567 void
pciio_provider_startup(vertex_hdl_t pciio_provider)568 pciio_provider_startup(vertex_hdl_t pciio_provider)
569 {
570     DEV_FUNC(pciio_provider, provider_startup)
571 	(pciio_provider);
572 }
573 
574 /*
575  * Shutdown a crosstalk provider
576  */
577 void
pciio_provider_shutdown(vertex_hdl_t pciio_provider)578 pciio_provider_shutdown(vertex_hdl_t pciio_provider)
579 {
580     DEV_FUNC(pciio_provider, provider_shutdown)
581 	(pciio_provider);
582 }
583 
584 /*
585  * Read value of configuration register
586  */
587 uint64_t
pciio_config_get(vertex_hdl_t dev,unsigned reg,unsigned size)588 pciio_config_get(vertex_hdl_t	dev,
589 		 unsigned	reg,
590 		 unsigned	size)
591 {
592     uint64_t	value = 0;
593     unsigned	shift = 0;
594 
595     /* handle accesses that cross words here,
596      * since that's common code between all
597      * possible providers.
598      */
599     while (size > 0) {
600 	unsigned	biw = 4 - (reg&3);
601 	if (biw > size)
602 	    biw = size;
603 
604 	value |= DEV_FUNC(dev, config_get)
605 	    (dev, reg, biw) << shift;
606 
607 	shift += 8*biw;
608 	reg += biw;
609 	size -= biw;
610     }
611     return value;
612 }
613 
614 /*
615  * Change value of configuration register
616  */
617 void
pciio_config_set(vertex_hdl_t dev,unsigned reg,unsigned size,uint64_t value)618 pciio_config_set(vertex_hdl_t	dev,
619 		 unsigned	reg,
620 		 unsigned	size,
621 		 uint64_t	value)
622 {
623     /* handle accesses that cross words here,
624      * since that's common code between all
625      * possible providers.
626      */
627     while (size > 0) {
628 	unsigned	biw = 4 - (reg&3);
629 	if (biw > size)
630 	    biw = size;
631 
632 	DEV_FUNC(dev, config_set)
633 	    (dev, reg, biw, value);
634 	reg += biw;
635 	size -= biw;
636 	value >>= biw * 8;
637     }
638 }
639 
640 /* =====================================================================
641  *          GENERIC PCI SUPPORT FUNCTIONS
642  */
643 
644 /*
645  * Issue a hardware reset to a card.
646  */
647 int
pciio_reset(vertex_hdl_t dev)648 pciio_reset(vertex_hdl_t dev)
649 {
650     return DEV_FUNC(dev, reset) (dev);
651 }
652 
653 /****** Generic pci slot information interfaces ******/
654 
655 pciio_info_t
pciio_info_chk(vertex_hdl_t pciio)656 pciio_info_chk(vertex_hdl_t pciio)
657 {
658     arbitrary_info_t        ainfo = 0;
659 
660     hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);
661     return (pciio_info_t) ainfo;
662 }
663 
664 pciio_info_t
pciio_info_get(vertex_hdl_t pciio)665 pciio_info_get(vertex_hdl_t pciio)
666 {
667     pciio_info_t            pciio_info;
668 
669     pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);
670 
671 #ifdef DEBUG_PCIIO
672     {
673 	int pos;
674 	char dname[256];
675 	pos = devfs_generate_path(pciio, dname, 256);
676 	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
677     }
678 #endif /* DEBUG_PCIIO */
679 
680     if ((pciio_info != NULL) &&
681         (pciio_info->c_fingerprint != pciio_info_fingerprint)
682         && (pciio_info->c_fingerprint != NULL)) {
683 
684         return((pciio_info_t)-1); /* Should panic .. */
685     }
686 
687     return pciio_info;
688 }
689 
690 void
pciio_info_set(vertex_hdl_t pciio,pciio_info_t pciio_info)691 pciio_info_set(vertex_hdl_t pciio, pciio_info_t pciio_info)
692 {
693     if (pciio_info != NULL)
694 	pciio_info->c_fingerprint = pciio_info_fingerprint;
695     hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);
696 
697     /* Also, mark this vertex as a PCI slot
698      * and use the pciio_info, so pciio_info_chk
699      * can work (and be fairly efficient).
700      */
701     hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
702 			 (arbitrary_info_t) pciio_info);
703 }
704 
705 vertex_hdl_t
pciio_info_dev_get(pciio_info_t pciio_info)706 pciio_info_dev_get(pciio_info_t pciio_info)
707 {
708     return (pciio_info->c_vertex);
709 }
710 
711 
712 pciio_slot_t
pciio_info_slot_get(pciio_info_t pciio_info)713 pciio_info_slot_get(pciio_info_t pciio_info)
714 {
715     return (pciio_info->c_slot);
716 }
717 
718 vertex_hdl_t
pciio_info_master_get(pciio_info_t pciio_info)719 pciio_info_master_get(pciio_info_t pciio_info)
720 {
721     return (pciio_info->c_master);
722 }
723 
724 arbitrary_info_t
pciio_info_mfast_get(pciio_info_t pciio_info)725 pciio_info_mfast_get(pciio_info_t pciio_info)
726 {
727     return (pciio_info->c_mfast);
728 }
729 
730 pciio_provider_t       *
pciio_info_pops_get(pciio_info_t pciio_info)731 pciio_info_pops_get(pciio_info_t pciio_info)
732 {
733     return (pciio_info->c_pops);
734 }
735 
736 
737 /* =====================================================================
738  *          GENERIC PCI INITIALIZATION FUNCTIONS
739  */
740 
741 /*
742  *    pciioattach: called for each vertex in the graph
743  *      that is a PCI provider.
744  */
745 /*ARGSUSED */
746 int
pciio_attach(vertex_hdl_t pciio)747 pciio_attach(vertex_hdl_t pciio)
748 {
749 #if DEBUG && ATTACH_DEBUG
750     char devname[MAXDEVNAME];
751     printk("%s: pciio_attach\n", vertex_to_name(pciio, devname, MAXDEVNAME));
752 #endif
753     return 0;
754 }
755 
756 /*
757  * Associate a set of pciio_provider functions with a vertex.
758  */
759 void
pciio_provider_register(vertex_hdl_t provider,pciio_provider_t * pciio_fns)760 pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns)
761 {
762     hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
763 }
764 
765 /*
766  * Disassociate a set of pciio_provider functions with a vertex.
767  */
768 void
pciio_provider_unregister(vertex_hdl_t provider)769 pciio_provider_unregister(vertex_hdl_t provider)
770 {
771     arbitrary_info_t        ainfo;
772 
773     hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
774 }
775 
776 /*
777  * Obtain a pointer to the pciio_provider functions for a specified Crosstalk
778  * provider.
779  */
780 pciio_provider_t       *
pciio_provider_fns_get(vertex_hdl_t provider)781 pciio_provider_fns_get(vertex_hdl_t provider)
782 {
783     arbitrary_info_t        ainfo = 0;
784 
785     (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
786     return (pciio_provider_t *) ainfo;
787 }
788 
789 pciio_info_t
pciio_device_info_new(pciio_info_t pciio_info,vertex_hdl_t master,pciio_slot_t slot,pciio_function_t func,pciio_vendor_id_t vendor_id,pciio_device_id_t device_id)790 pciio_device_info_new(
791 		pciio_info_t pciio_info,
792 		vertex_hdl_t master,
793 		pciio_slot_t slot,
794 		pciio_function_t func,
795 		pciio_vendor_id_t vendor_id,
796 		pciio_device_id_t device_id)
797 {
798     if (!pciio_info)
799 	NEW(pciio_info);
800     ASSERT(pciio_info != NULL);
801 
802     pciio_info->c_slot = slot;
803     pciio_info->c_func = func;
804     pciio_info->c_vendor = vendor_id;
805     pciio_info->c_device = device_id;
806     pciio_info->c_master = master;
807     pciio_info->c_mfast = hwgraph_fastinfo_get(master);
808     pciio_info->c_pops = pciio_provider_fns_get(master);
809     pciio_info->c_efunc = 0;
810     pciio_info->c_einfo = 0;
811 
812     return pciio_info;
813 }
814 
815 void
pciio_device_info_free(pciio_info_t pciio_info)816 pciio_device_info_free(pciio_info_t pciio_info)
817 {
818     /* NOTE : pciio_info is a structure within the pcibr_info
819      *	      and not a pointer to memory allocated on the heap !!
820      */
821     memset((char *)pciio_info, 0, sizeof(pciio_info));
822 }
823 
824 vertex_hdl_t
pciio_device_info_register(vertex_hdl_t connectpt,pciio_info_t pciio_info)825 pciio_device_info_register(
826 		vertex_hdl_t connectpt,		/* vertex at center of bus */
827 		pciio_info_t pciio_info)	/* details about the connectpt */
828 {
829     char		name[32];
830     vertex_hdl_t	pconn;
831     int device_master_set(vertex_hdl_t, vertex_hdl_t);
832 
833     pciio_slot_func_to_name(name,
834 			    pciio_info->c_slot,
835 			    pciio_info->c_func);
836 
837     if (GRAPH_SUCCESS !=
838 	hwgraph_path_add(connectpt, name, &pconn))
839 	return pconn;
840 
841     pciio_info->c_vertex = pconn;
842     pciio_info_set(pconn, pciio_info);
843 #ifdef DEBUG_PCIIO
844     {
845 	int pos;
846 	char dname[256];
847 	pos = devfs_generate_path(pconn, dname, 256);
848 	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
849     }
850 #endif /* DEBUG_PCIIO */
851 
852     /*
853      * create link to our pci provider
854      */
855 
856     device_master_set(pconn, pciio_info->c_master);
857     return pconn;
858 }
859 
860 void
pciio_device_info_unregister(vertex_hdl_t connectpt,pciio_info_t pciio_info)861 pciio_device_info_unregister(vertex_hdl_t connectpt,
862 			     pciio_info_t pciio_info)
863 {
864     char		name[32];
865     vertex_hdl_t	pconn;
866 
867     if (!pciio_info)
868 	return;
869 
870     pciio_slot_func_to_name(name,
871 			    pciio_info->c_slot,
872 			    pciio_info->c_func);
873 
874     hwgraph_edge_remove(connectpt,name,&pconn);
875     pciio_info_set(pconn,0);
876 
877     /* Remove the link to our pci provider */
878     hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
879 
880 
881     hwgraph_vertex_unref(pconn);
882     hwgraph_vertex_destroy(pconn);
883 
884 }
885 /* Add the pci card inventory information to the hwgraph
886  */
887 static void
pciio_device_inventory_add(vertex_hdl_t pconn_vhdl)888 pciio_device_inventory_add(vertex_hdl_t pconn_vhdl)
889 {
890     pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
891 
892     ASSERT(pciio_info);
893     ASSERT(pciio_info->c_vertex == pconn_vhdl);
894 
895     /* Donot add inventory  for non-existent devices */
896     if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE)	||
897 	(pciio_info->c_device == PCIIO_DEVICE_ID_NONE))
898 	return;
899     device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP,
900 			 pciio_info->c_vendor,pciio_info->c_device,
901 			 pciio_info->c_slot);
902 }
903 
904 /*ARGSUSED */
905 int
pciio_device_attach(vertex_hdl_t pconn,int drv_flags)906 pciio_device_attach(vertex_hdl_t pconn,
907 		    int          drv_flags)
908 {
909     pciio_info_t            pciio_info;
910     pciio_vendor_id_t       vendor_id;
911     pciio_device_id_t       device_id;
912 
913 
914     pciio_device_inventory_add(pconn);
915     pciio_info = pciio_info_get(pconn);
916 
917     vendor_id = pciio_info->c_vendor;
918     device_id = pciio_info->c_device;
919 
920     /* we don't start attaching things until
921      * all the driver init routines (including
922      * pciio_init) have been called; so we
923      * can assume here that we have a registry.
924      */
925 
926     return(cdl_add_connpt(vendor_id, device_id, pconn, drv_flags));
927 }
928 
929 int
pciio_device_detach(vertex_hdl_t pconn,int drv_flags)930 pciio_device_detach(vertex_hdl_t pconn,
931 		    int          drv_flags)
932 {
933     return(0);
934 }
935 
936 /*
937  * Allocate space from the specified PCI window mapping resource.  On
938  * success record information about the allocation in the supplied window
939  * allocation cookie (if non-NULL) and return the address of the allocated
940  * window.  On failure return NULL.
941  *
942  * The "size" parameter is usually from a PCI device's Base Address Register
943  * (BAR) decoder.  As such, the allocation must be aligned to be a multiple of
944  * that.  The "align" parameter acts as a ``minimum alignment'' allocation
945  * constraint.  The alignment contraint reflects system or device addressing
946  * restrictions such as the inability to share higher level ``windows''
947  * between devices, etc.  The returned PCI address allocation will be a
948  * multiple of the alignment constraint both in alignment and size.  Thus, the
949  * returned PCI address block is aligned to the maximum of the requested size
950  * and alignment.
951  */
952 iopaddr_t
pciio_device_win_alloc(struct resource * root_resource,pciio_win_alloc_t win_alloc,size_t start,size_t size,size_t align)953 pciio_device_win_alloc(struct resource *root_resource,
954 		       pciio_win_alloc_t win_alloc,
955 		       size_t start, size_t size, size_t align)
956 {
957 
958 	struct resource *new_res;
959 	int status = 0;
960 
961 	new_res = (struct resource *) kmalloc( sizeof(struct resource), GFP_KERNEL);
962 
963 	if (start > 0) {
964 		status = allocate_resource( root_resource, new_res,
965 			size, start /* Min start addr. */,
966 			(start + size) - 1, 1,
967 			NULL, NULL);
968 	} else {
969 		if (size > align)
970 			align = size;
971 		status = allocate_resource( root_resource, new_res,
972 				    size, align /* Min start addr. */,
973 				    root_resource->end, align,
974 				    NULL, NULL);
975 	}
976 
977 	if (status) {
978 		kfree(new_res);
979 		return((iopaddr_t) NULL);
980 	}
981 
982 	/*
983 	 * If a window allocation cookie has been supplied, use it to keep
984 	 * track of all the allocated space assigned to this window.
985 	 */
986 	if (win_alloc) {
987 		win_alloc->wa_resource = new_res;
988 		win_alloc->wa_base = new_res->start;
989 		win_alloc->wa_pages = size;
990 	}
991 
992 	return new_res->start;;
993 }
994 
995 /*
996  * Free the specified window allocation back into the PCI window mapping
997  * resource.  As noted above, we keep page addresses offset by 1 ...
998  */
999 void
pciio_device_win_free(pciio_win_alloc_t win_alloc)1000 pciio_device_win_free(pciio_win_alloc_t win_alloc)
1001 {
1002 
1003 	int status = 0;
1004 
1005 	if (win_alloc->wa_resource) {
1006 		status = release_resource(win_alloc->wa_resource);
1007 		if (!status)
1008 			kfree(win_alloc->wa_resource);
1009 		else
1010 			BUG();
1011 	}
1012 }
1013 
1014 /*
1015  * pciio_error_register:
1016  * arrange for a function to be called with
1017  * a specified first parameter plus other
1018  * information when an error is encountered
1019  * and traced to the pci slot corresponding
1020  * to the connection point pconn.
1021  *
1022  * may also be called with a null function
1023  * pointer to "unregister" the error handler.
1024  *
1025  * NOTE: subsequent calls silently overwrite
1026  * previous data for this vertex. We assume that
1027  * cooperating drivers, well, cooperate ...
1028  */
1029 void
pciio_error_register(vertex_hdl_t pconn,error_handler_f * efunc,error_handler_arg_t einfo)1030 pciio_error_register(vertex_hdl_t pconn,
1031 		     error_handler_f *efunc,
1032 		     error_handler_arg_t einfo)
1033 {
1034     pciio_info_t            pciio_info;
1035 
1036     pciio_info = pciio_info_get(pconn);
1037     ASSERT(pciio_info != NULL);
1038     pciio_info->c_efunc = efunc;
1039     pciio_info->c_einfo = einfo;
1040 }
1041 
1042 /*
1043  * Check if any device has been found in this slot, and return
1044  * true or false
1045  * vhdl is the vertex for the slot
1046  */
1047 int
pciio_slot_inuse(vertex_hdl_t pconn_vhdl)1048 pciio_slot_inuse(vertex_hdl_t pconn_vhdl)
1049 {
1050     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
1051 
1052     ASSERT(pciio_info);
1053     ASSERT(pciio_info->c_vertex == pconn_vhdl);
1054     if (pciio_info->c_vendor) {
1055 	/*
1056 	 * Non-zero value for vendor indicate
1057 	 * a board being found in this slot.
1058 	 */
1059 	return 1;
1060     }
1061     return 0;
1062 }
1063 
1064 int
pciio_dma_enabled(vertex_hdl_t pconn_vhdl)1065 pciio_dma_enabled(vertex_hdl_t pconn_vhdl)
1066 {
1067 	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
1068 }
1069 
1070 int
pciio_info_type1_get(pciio_info_t pci_info)1071 pciio_info_type1_get(pciio_info_t pci_info)
1072 {
1073 	return(0);
1074 }
1075