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