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