File: /usr/src/linux/arch/ia64/sn/io/xtalk.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 #include <linux/types.h>
12 #include <linux/slab.h>
13 #include <asm/sn/sgi.h>
14 #include <asm/sn/iobus.h>
15 #include <asm/sn/iograph.h>
16 #include <asm/sn/invent.h>
17 #include <asm/sn/hcl.h>
18 #include <asm/sn/labelcl.h>
19 #include <asm/sn/hcl_util.h>
20
21 #include <asm/sn/xtalk/xtalk.h>
22 #include <asm/sn/xtalk/xswitch.h>
23 #include <asm/sn/xtalk/xwidget.h>
24
25 #include <asm/sn/xtalk/xtalk_private.h>
26
27 /*
28 * Implement crosstalk provider operations. The xtalk* layer provides a
29 * platform-independent interface for crosstalk devices. This layer
30 * switches among the possible implementations of a crosstalk adapter.
31 *
32 * On platforms with only one possible xtalk provider, macros can be
33 * set up at the top that cause the table lookups and indirections to
34 * completely disappear.
35 */
36
37 #define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
38 #define DEL(ptr) (kfree(ptr))
39
40 char widget_info_fingerprint[] = "widget_info";
41
42 cdl_p xtalk_registry = NULL;
43
44 #include <asm/sn/agent.h>
45 #define DEV_FUNC(dev,func) hub_##func
46 #define CAST_PIOMAP(x) ((hub_piomap_t)(x))
47 #define CAST_DMAMAP(x) ((hub_dmamap_t)(x))
48 #define CAST_INTR(x) ((hub_intr_t)(x))
49
50 /* =====================================================================
51 * Function Table of Contents
52 */
53 xtalk_piomap_t xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
54 void xtalk_piomap_free(xtalk_piomap_t);
55 caddr_t xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
56 void xtalk_piomap_done(xtalk_piomap_t);
57 caddr_t xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
58 caddr_t xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
59 void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
60 caddr_t xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
61 static caddr_t null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
62 xtalk_dmamap_t xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
63 void xtalk_dmamap_free(xtalk_dmamap_t);
64 iopaddr_t xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
65 alenlist_t xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
66 void xtalk_dmamap_done(xtalk_dmamap_t);
67 iopaddr_t xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
68 alenlist_t xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
69 void xtalk_dmamap_drain(xtalk_dmamap_t);
70 void xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
71 void xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
72 xtalk_intr_t xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
73 xtalk_intr_t xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
74 void xtalk_intr_free(xtalk_intr_t);
75 int xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *, void *);
76 void xtalk_intr_disconnect(xtalk_intr_t);
77 devfs_handle_t xtalk_intr_cpu_get(xtalk_intr_t);
78 int xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
79 int xtalk_error_devenable(devfs_handle_t, int, int);
80 void xtalk_provider_startup(devfs_handle_t);
81 void xtalk_provider_shutdown(devfs_handle_t);
82 devfs_handle_t xtalk_intr_dev_get(xtalk_intr_t);
83 xwidgetnum_t xtalk_intr_target_get(xtalk_intr_t);
84 xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t);
85 iopaddr_t xtalk_intr_addr_get(struct xtalk_intr_s *);
86 void *xtalk_intr_sfarg_get(xtalk_intr_t);
87 devfs_handle_t xtalk_pio_dev_get(xtalk_piomap_t);
88 xwidgetnum_t xtalk_pio_target_get(xtalk_piomap_t);
89 iopaddr_t xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
90 ulong xtalk_pio_mapsz_get(xtalk_piomap_t);
91 caddr_t xtalk_pio_kvaddr_get(xtalk_piomap_t);
92 devfs_handle_t xtalk_dma_dev_get(xtalk_dmamap_t);
93 xwidgetnum_t xtalk_dma_target_get(xtalk_dmamap_t);
94 xwidget_info_t xwidget_info_chk(devfs_handle_t);
95 xwidget_info_t xwidget_info_get(devfs_handle_t);
96 void xwidget_info_set(devfs_handle_t, xwidget_info_t);
97 devfs_handle_t xwidget_info_dev_get(xwidget_info_t);
98 xwidgetnum_t xwidget_info_id_get(xwidget_info_t);
99 devfs_handle_t xwidget_info_master_get(xwidget_info_t);
100 xwidgetnum_t xwidget_info_masterid_get(xwidget_info_t);
101 xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t);
102 xwidget_mfg_num_t xwidget_info_mfg_num_get(xwidget_info_t);
103 char *xwidget_info_name_get(xwidget_info_t);
104 void xtalk_init(void);
105 void xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
106 void xtalk_provider_unregister(devfs_handle_t);
107 xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t);
108 int xwidget_driver_register(xwidget_part_num_t,
109 xwidget_mfg_num_t,
110 char *, unsigned);
111 void xwidget_driver_unregister(char *);
112 int xwidget_register(xwidget_hwid_t, devfs_handle_t,
113 xwidgetnum_t, devfs_handle_t,
114 xwidgetnum_t, async_attach_t);
115 int xwidget_unregister(devfs_handle_t);
116 void xwidget_error_register(devfs_handle_t, error_handler_f *,
117 error_handler_arg_t);
118 void xwidget_reset(devfs_handle_t);
119 char *xwidget_name_get(devfs_handle_t);
120 #if !defined(DEV_FUNC)
121 /*
122 * There is more than one possible provider
123 * for this platform. We need to examine the
124 * master vertex of the current vertex for
125 * a provider function structure, and indirect
126 * through the appropriately named member.
127 */
128 #define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func
129 #define CAST_PIOMAP(x) ((xtalk_piomap_t)(x))
130 #define CAST_DMAMAP(x) ((xtalk_dmamap_t)(x))
131 #define CAST_INTR(x) ((xtalk_intr_t)(x))
132
133 static xtalk_provider_t *
134 xwidget_to_provider_fns(devfs_handle_t xconn)
135 {
136 xwidget_info_t widget_info;
137 xtalk_provider_t *provider_fns;
138
139 widget_info = xwidget_info_get(xconn);
140 ASSERT(widget_info != NULL);
141
142 provider_fns = xwidget_info_pops_get(widget_info);
143 ASSERT(provider_fns != NULL);
144
145 return (provider_fns);
146 }
147 #endif
148
149 /*
150 * Many functions are not passed their vertex
151 * information directly; rather, they must
152 * dive through a resource map. These macros
153 * are available to coordinate this detail.
154 */
155 #define PIOMAP_FUNC(map,func) DEV_FUNC(map->xp_dev,func)
156 #define DMAMAP_FUNC(map,func) DEV_FUNC(map->xd_dev,func)
157 #define INTR_FUNC(intr,func) DEV_FUNC(intr_hdl->xi_dev,func)
158
159 /* =====================================================================
160 * PIO MANAGEMENT
161 *
162 * For mapping system virtual address space to
163 * xtalk space on a specified widget
164 */
165
166 xtalk_piomap_t
167 xtalk_piomap_alloc(devfs_handle_t dev, /* set up mapping for this device */
168 device_desc_t dev_desc, /* device descriptor */
169 iopaddr_t xtalk_addr, /* map for this xtalk_addr range */
170 size_t byte_count,
171 size_t byte_count_max, /* maximum size of a mapping */
172 unsigned flags)
173 { /* defined in sys/pio.h */
174 return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)
175 (dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);
176 }
177
178
179 void
180 xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
181 {
182 PIOMAP_FUNC(xtalk_piomap, piomap_free)
183 (CAST_PIOMAP(xtalk_piomap));
184 }
185
186
187 caddr_t
188 xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap, /* mapping resources */
189 iopaddr_t xtalk_addr, /* map for this xtalk address */
190 size_t byte_count)
191 { /* map this many bytes */
192 return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
193 (CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
194 }
195
196
197 void
198 xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
199 {
200 PIOMAP_FUNC(xtalk_piomap, piomap_done)
201 (CAST_PIOMAP(xtalk_piomap));
202 }
203
204
205 caddr_t
206 xtalk_piotrans_addr(devfs_handle_t dev, /* translate for this device */
207 device_desc_t dev_desc, /* device descriptor */
208 iopaddr_t xtalk_addr, /* Crosstalk address */
209 size_t byte_count, /* map this many bytes */
210 unsigned flags)
211 { /* (currently unused) */
212 return DEV_FUNC(dev, piotrans_addr)
213 (dev, dev_desc, xtalk_addr, byte_count, flags);
214 }
215
216 caddr_t
217 xtalk_pio_addr(devfs_handle_t dev, /* translate for this device */
218 device_desc_t dev_desc, /* device descriptor */
219 iopaddr_t addr, /* starting address (or offset in window) */
220 size_t byte_count, /* map this many bytes */
221 xtalk_piomap_t *mapp, /* where to return the map pointer */
222 unsigned flags)
223 { /* PIO flags */
224 xtalk_piomap_t map = 0;
225 caddr_t res;
226
227 if (mapp)
228 *mapp = 0; /* record "no map used" */
229
230 res = xtalk_piotrans_addr
231 (dev, dev_desc, addr, byte_count, flags);
232 if (res)
233 return res; /* xtalk_piotrans worked */
234
235 map = xtalk_piomap_alloc
236 (dev, dev_desc, addr, byte_count, byte_count, flags);
237 if (!map)
238 return res; /* xtalk_piomap_alloc failed */
239
240 res = xtalk_piomap_addr
241 (map, addr, byte_count);
242 if (!res) {
243 xtalk_piomap_free(map);
244 return res; /* xtalk_piomap_addr failed */
245 }
246 if (mapp)
247 *mapp = map; /* pass back map used */
248
249 return res; /* xtalk_piomap_addr succeeded */
250 }
251
252 /* =====================================================================
253 * EARLY PIOTRANS SUPPORT
254 *
255 * There are places where drivers (mgras, for instance)
256 * need to get PIO translations before the infrastructure
257 * is extended to them (setting up textports, for
258 * instance). These drivers should call
259 * xtalk_early_piotrans_addr with their xtalk ID
260 * information, a sequence number (so we can use the second
261 * mgras for instance), and the usual piotrans parameters.
262 *
263 * Machine specific code should provide an implementation
264 * of early_piotrans_addr, and present a pointer to this
265 * function to xtalk_set_early_piotrans_addr so it can be
266 * used by clients without the clients having to know what
267 * platform or what xtalk provider is in use.
268 */
269
270 static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
271
272 xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
273
274 /* xtalk_set_early_piotrans_addr:
275 * specify the early_piotrans_addr implementation function.
276 */
277 void
278 xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
279 {
280 impl_early_piotrans_addr = impl;
281 }
282
283 /* xtalk_early_piotrans_addr:
284 * figure out a PIO address for the "nth" crosstalk widget that
285 * matches the specified part and mfgr number. Returns NULL if
286 * there is no such widget, or if the requested mapping can not
287 * be constructed.
288 * Limitations on which crosstalk slots (and busses) are
289 * checked, and definitions of the ordering of the search across
290 * the crosstalk slots, are defined by the platform.
291 */
292 caddr_t
293 xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
294 xwidget_mfg_num_t mfg_num,
295 int which,
296 iopaddr_t xtalk_addr,
297 size_t byte_count,
298 unsigned flags)
299 {
300 return impl_early_piotrans_addr
301 (part_num, mfg_num, which, xtalk_addr, byte_count, flags);
302 }
303
304 /* null_xtalk_early_piotrans_addr:
305 * used as the early_piotrans_addr implementation until and
306 * unless a real implementation is provided. In DEBUG kernels,
307 * we want to know who is calling before the implementation is
308 * registered; in non-DEBUG kernels, return NULL representing
309 * lack of mapping support.
310 */
311 /*ARGSUSED */
312 static caddr_t
313 null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
314 xwidget_mfg_num_t mfg_num,
315 int which,
316 iopaddr_t xtalk_addr,
317 size_t byte_count,
318 unsigned flags)
319 {
320 #if DEBUG
321 PRINT_PANIC("null_xtalk_early_piotrans_addr");
322 #endif
323 return NULL;
324 }
325
326 /* =====================================================================
327 * DMA MANAGEMENT
328 *
329 * For mapping from crosstalk space to system
330 * physical space.
331 */
332
333 xtalk_dmamap_t
334 xtalk_dmamap_alloc(devfs_handle_t dev, /* set up mappings for this device */
335 device_desc_t dev_desc, /* device descriptor */
336 size_t byte_count_max, /* max size of a mapping */
337 unsigned flags)
338 { /* defined in dma.h */
339 return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
340 (dev, dev_desc, byte_count_max, flags);
341 }
342
343
344 void
345 xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
346 {
347 DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
348 (CAST_DMAMAP(xtalk_dmamap));
349 }
350
351
352 iopaddr_t
353 xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */
354 paddr_t paddr, /* map for this address */
355 size_t byte_count)
356 { /* map this many bytes */
357 return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
358 (CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
359 }
360
361
362 alenlist_t
363 xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */
364 alenlist_t alenlist, /* map this Address/Length List */
365 unsigned flags)
366 {
367 return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
368 (CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
369 }
370
371
372 void
373 xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
374 {
375 DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
376 (CAST_DMAMAP(xtalk_dmamap));
377 }
378
379
380 iopaddr_t
381 xtalk_dmatrans_addr(devfs_handle_t dev, /* translate for this device */
382 device_desc_t dev_desc, /* device descriptor */
383 paddr_t paddr, /* system physical address */
384 size_t byte_count, /* length */
385 unsigned flags)
386 { /* defined in dma.h */
387 return DEV_FUNC(dev, dmatrans_addr)
388 (dev, dev_desc, paddr, byte_count, flags);
389 }
390
391
392 alenlist_t
393 xtalk_dmatrans_list(devfs_handle_t dev, /* translate for this device */
394 device_desc_t dev_desc, /* device descriptor */
395 alenlist_t palenlist, /* system address/length list */
396 unsigned flags)
397 { /* defined in dma.h */
398 return DEV_FUNC(dev, dmatrans_list)
399 (dev, dev_desc, palenlist, flags);
400 }
401
402 void
403 xtalk_dmamap_drain(xtalk_dmamap_t map)
404 {
405 DMAMAP_FUNC(map, dmamap_drain)
406 (CAST_DMAMAP(map));
407 }
408
409 void
410 xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
411 {
412 DEV_FUNC(dev, dmaaddr_drain)
413 (dev, addr, size);
414 }
415
416 void
417 xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
418 {
419 DEV_FUNC(dev, dmalist_drain)
420 (dev, list);
421 }
422
423 /* =====================================================================
424 * INTERRUPT MANAGEMENT
425 *
426 * Allow crosstalk devices to establish interrupts
427 */
428
429 /*
430 * Allocate resources required for an interrupt as specified in intr_desc.
431 * Return resource handle in intr_hdl.
432 */
433 xtalk_intr_t
434 xtalk_intr_alloc(devfs_handle_t dev, /* which Crosstalk device */
435 device_desc_t dev_desc, /* device descriptor */
436 devfs_handle_t owner_dev)
437 { /* owner of this interrupt */
438 return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
439 (dev, dev_desc, owner_dev);
440 }
441
442 /*
443 * Allocate resources required for an interrupt as specified in dev_desc.
444 * Unconditionally setup resources to be non-threaded.
445 * Return resource handle in intr_hdl.
446 */
447 xtalk_intr_t
448 xtalk_intr_alloc_nothd(devfs_handle_t dev, /* which Crosstalk device */
449 device_desc_t dev_desc, /* device descriptor */
450 devfs_handle_t owner_dev) /* owner of this interrupt */
451 {
452 return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
453 (dev, dev_desc, owner_dev);
454 }
455
456 /*
457 * Free resources consumed by intr_alloc.
458 */
459 void
460 xtalk_intr_free(xtalk_intr_t intr_hdl)
461 {
462 INTR_FUNC(intr_hdl, intr_free)
463 (CAST_INTR(intr_hdl));
464 }
465
466
467 /*
468 * Associate resources allocated with a previous xtalk_intr_alloc call with the
469 * described handler, arg, name, etc.
470 *
471 * Returns 0 on success, returns <0 on failure.
472 */
473 int
474 xtalk_intr_connect(xtalk_intr_t intr_hdl, /* xtalk intr resource handle */
475 intr_func_t intr_func, /* xtalk intr handler */
476 intr_arg_t intr_arg, /* arg to intr handler */
477 xtalk_intr_setfunc_t setfunc, /* func to set intr hw */
478 void *setfunc_arg, /* arg to setfunc */
479 void *thread)
480 { /* intr thread to use */
481 return INTR_FUNC(intr_hdl, intr_connect)
482 (CAST_INTR(intr_hdl), intr_func, intr_arg, setfunc, setfunc_arg, thread);
483 }
484
485
486 /*
487 * Disassociate handler with the specified interrupt.
488 */
489 void
490 xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
491 {
492 INTR_FUNC(intr_hdl, intr_disconnect)
493 (CAST_INTR(intr_hdl));
494 }
495
496
497 /*
498 * Return a hwgraph vertex that represents the CPU currently
499 * targeted by an interrupt.
500 */
501 devfs_handle_t
502 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
503 {
504 return INTR_FUNC(intr_hdl, intr_cpu_get)
505 (CAST_INTR(intr_hdl));
506 }
507
508
509 /*
510 * =====================================================================
511 * ERROR MANAGEMENT
512 */
513
514 /*
515 * xtalk_error_handler:
516 * pass this error on to the handler registered
517 * at the specified xtalk connecdtion point,
518 * or complain about it here if there is no handler.
519 *
520 * This routine plays two roles during error delivery
521 * to most widgets: first, the external agent (heart,
522 * hub, or whatever) calls in with the error and the
523 * connect point representing the crosstalk switch,
524 * or whatever crosstalk device is directly connected
525 * to the agent.
526 *
527 * If there is a switch, it will generally look at the
528 * widget number stashed in the ioerror structure; and,
529 * if the error came from some widget other than the
530 * switch, it will call back into xtalk_error_handler
531 * with the connection point of the offending port.
532 */
533 int
534 xtalk_error_handler(
535 devfs_handle_t xconn,
536 int error_code,
537 ioerror_mode_t mode,
538 ioerror_t *ioerror)
539 {
540 xwidget_info_t xwidget_info;
541
542 #if DEBUG && ERROR_DEBUG
543 #ifdef SUPPORT_PRINTING_V_FORMAT
544 printk("%v: xtalk_error_handler\n", xconn);
545 #else
546 printk("%x: xtalk_error_handler\n", xconn);
547 #endif
548 #endif
549
550 xwidget_info = xwidget_info_get(xconn);
551 /* Make sure that xwidget_info is a valid pointer before derefencing it.
552 * We could come in here during very early initialization.
553 */
554 if (xwidget_info && xwidget_info->w_efunc)
555 return xwidget_info->w_efunc
556 (xwidget_info->w_einfo,
557 error_code, mode, ioerror);
558 /*
559 * no error handler registered for
560 * the offending port. it's not clear
561 * what needs to be done, but reporting
562 * it would be a good thing, unless it
563 * is a mode that requires nothing.
564 */
565 if ((mode == MODE_DEVPROBE) || (mode == MODE_DEVUSERERROR) ||
566 (mode == MODE_DEVREENABLE))
567 return IOERROR_HANDLED;
568
569 #ifdef LATER
570 #ifdef SUPPORT_PRINTING_V_FORMAT
571 PRINT_WARNING("Xbow at %v encountered Fatal error", xconn);
572 #else
573 PRINT_WARNING("Xbow at %x encountered Fatal error", xconn);
574 #endif
575 #endif /* LATER */
576 ioerror_dump("xtalk", error_code, mode, ioerror);
577
578 return IOERROR_UNHANDLED;
579 }
580
581 int
582 xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
583 {
584 return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code);
585 }
586
587
588 /* =====================================================================
589 * CONFIGURATION MANAGEMENT
590 */
591
592 /*
593 * Startup a crosstalk provider
594 */
595 void
596 xtalk_provider_startup(devfs_handle_t xtalk_provider)
597 {
598 DEV_FUNC(xtalk_provider, provider_startup)
599 (xtalk_provider);
600 }
601
602
603 /*
604 * Shutdown a crosstalk provider
605 */
606 void
607 xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
608 {
609 DEV_FUNC(xtalk_provider, provider_shutdown)
610 (xtalk_provider);
611 }
612
613 /*
614 * Enable a device on a xtalk widget
615 */
616 void
617 xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
618 {
619 DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
620 }
621
622 /*
623 * Shutdown a device on a xtalk widget
624 */
625 void
626 xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
627 {
628 DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
629 }
630
631 int
632 xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
633 {
634 return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
635 }
636 /*
637 * Generic crosstalk functions, for use with all crosstalk providers
638 * and all crosstalk devices.
639 */
640
641 /****** Generic crosstalk interrupt interfaces ******/
642 devfs_handle_t
643 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
644 {
645 return (xtalk_intr->xi_dev);
646 }
647
648 xwidgetnum_t
649 xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
650 {
651 return (xtalk_intr->xi_target);
652 }
653
654 xtalk_intr_vector_t
655 xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
656 {
657 return (xtalk_intr->xi_vector);
658 }
659
660 iopaddr_t
661 xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
662 {
663 return (xtalk_intr->xi_addr);
664 }
665
666 void *
667 xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
668 {
669 return (xtalk_intr->xi_sfarg);
670 }
671
672 /****** Generic crosstalk pio interfaces ******/
673 devfs_handle_t
674 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
675 {
676 return (xtalk_piomap->xp_dev);
677 }
678
679 xwidgetnum_t
680 xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
681 {
682 return (xtalk_piomap->xp_target);
683 }
684
685 iopaddr_t
686 xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
687 {
688 return (xtalk_piomap->xp_xtalk_addr);
689 }
690
691 ulong
692 xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
693 {
694 return (xtalk_piomap->xp_mapsz);
695 }
696
697 caddr_t
698 xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
699 {
700 return (xtalk_piomap->xp_kvaddr);
701 }
702
703
704 /****** Generic crosstalk dma interfaces ******/
705 devfs_handle_t
706 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
707 {
708 return (xtalk_dmamap->xd_dev);
709 }
710
711 xwidgetnum_t
712 xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
713 {
714 return (xtalk_dmamap->xd_target);
715 }
716
717
718 /****** Generic crosstalk widget information interfaces ******/
719
720 /* xwidget_info_chk:
721 * check to see if this vertex is a widget;
722 * if so, return its widget_info (if any).
723 * if not, return NULL.
724 */
725 xwidget_info_t
726 xwidget_info_chk(devfs_handle_t xwidget)
727 {
728 arbitrary_info_t ainfo = 0;
729
730 hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
731 return (xwidget_info_t) ainfo;
732 }
733
734
735 xwidget_info_t
736 xwidget_info_get(devfs_handle_t xwidget)
737 {
738 xwidget_info_t widget_info;
739
740 widget_info = (xwidget_info_t)
741 hwgraph_fastinfo_get(xwidget);
742
743 #ifdef LATER
744 if ((widget_info != NULL) &&
745 (widget_info->w_fingerprint != widget_info_fingerprint))
746 #ifdef SUPPORT_PRINTING_V_FORMAT
747 PRINT_PANIC("%v bad xwidget_info", xwidget);
748 #else
749 PRINT_PANIC("%x bad xwidget_info", xwidget);
750 #endif
751 #endif /* LATER */
752
753 return (widget_info);
754 }
755
756 void
757 xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
758 {
759 if (widget_info != NULL)
760 widget_info->w_fingerprint = widget_info_fingerprint;
761
762 hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
763
764 /* Also, mark this vertex as an xwidget,
765 * and use the widget_info, so xwidget_info_chk
766 * can work (and be fairly efficient).
767 */
768 hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
769 (arbitrary_info_t) widget_info);
770 }
771
772 devfs_handle_t
773 xwidget_info_dev_get(xwidget_info_t xwidget_info)
774 {
775 if (xwidget_info == NULL)
776 panic("null xwidget_info");
777 return (xwidget_info->w_vertex);
778 }
779
780 xwidgetnum_t
781 xwidget_info_id_get(xwidget_info_t xwidget_info)
782 {
783 if (xwidget_info == NULL)
784 panic("null xwidget_info");
785 return (xwidget_info->w_id);
786 }
787
788
789 devfs_handle_t
790 xwidget_info_master_get(xwidget_info_t xwidget_info)
791 {
792 if (xwidget_info == NULL)
793 panic("null xwidget_info");
794 return (xwidget_info->w_master);
795 }
796
797 xwidgetnum_t
798 xwidget_info_masterid_get(xwidget_info_t xwidget_info)
799 {
800 if (xwidget_info == NULL)
801 panic("null xwidget_info");
802 return (xwidget_info->w_masterid);
803 }
804
805 xwidget_part_num_t
806 xwidget_info_part_num_get(xwidget_info_t xwidget_info)
807 {
808 if (xwidget_info == NULL)
809 panic("null xwidget_info");
810 return (xwidget_info->w_hwid.part_num);
811 }
812
813 xwidget_mfg_num_t
814 xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
815 {
816 if (xwidget_info == NULL)
817 panic("null xwidget_info");
818 return (xwidget_info->w_hwid.mfg_num);
819 }
820 /* Extract the widget name from the widget information
821 * for the xtalk widget.
822 */
823 char *
824 xwidget_info_name_get(xwidget_info_t xwidget_info)
825 {
826 if (xwidget_info == NULL)
827 panic("null xwidget info");
828 return(xwidget_info->w_name);
829 }
830 /****** Generic crosstalk initialization interfaces ******/
831
832 /*
833 * One-time initialization needed for systems that support crosstalk.
834 */
835 void
836 xtalk_init(void)
837 {
838 cdl_p cp;
839
840 #if DEBUG && ATTACH_DEBUG
841 printf("xtalk_init\n");
842 #endif
843 /* Allocate the registry.
844 * We might already have one.
845 * If we don't, go get one.
846 * MPness: someone might have
847 * set one up for us while we
848 * were not looking; use an atomic
849 * compare-and-swap to commit to
850 * using the new registry if and
851 * only if nobody else did first.
852 * If someone did get there first,
853 * toss the one we allocated back
854 * into the pool.
855 */
856 if (xtalk_registry == NULL) {
857 cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
858 if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
859 cdl_del(cp);
860 }
861 }
862 ASSERT(xtalk_registry != NULL);
863 }
864
865 /*
866 * Associate a set of xtalk_provider functions with a vertex.
867 */
868 void
869 xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
870 {
871 hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
872 }
873
874 /*
875 * Disassociate a set of xtalk_provider functions with a vertex.
876 */
877 void
878 xtalk_provider_unregister(devfs_handle_t provider)
879 {
880 hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
881 }
882
883 /*
884 * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
885 * provider.
886 */
887 xtalk_provider_t *
888 xtalk_provider_fns_get(devfs_handle_t provider)
889 {
890 return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
891 }
892
893 /*
894 * Announce a driver for a particular crosstalk part.
895 * Returns 0 on success or -1 on failure. Failure occurs if the
896 * specified hardware already has a driver.
897 */
898 /*ARGSUSED4 */
899 int
900 xwidget_driver_register(xwidget_part_num_t part_num,
901 xwidget_mfg_num_t mfg_num,
902 char *driver_prefix,
903 unsigned flags)
904 {
905 /* a driver's init routine could call
906 * xwidget_driver_register before the
907 * system calls xtalk_init; so, we
908 * make the call here.
909 */
910 if (xtalk_registry == NULL)
911 xtalk_init();
912
913 return cdl_add_driver(xtalk_registry,
914 part_num, mfg_num,
915 driver_prefix, flags, NULL);
916 }
917
918 /*
919 * Inform xtalk infrastructure that a driver is no longer available for
920 * handling any widgets.
921 */
922 void
923 xwidget_driver_unregister(char *driver_prefix)
924 {
925 /* before a driver calls unregister,
926 * it must have called registger; so we
927 * can assume we have a registry here.
928 */
929 ASSERT(xtalk_registry != NULL);
930
931 cdl_del_driver(xtalk_registry, driver_prefix, NULL);
932 }
933
934 /*
935 * Call some function with each vertex that
936 * might be one of this driver's attach points.
937 */
938 void
939 xtalk_iterate(char *driver_prefix,
940 xtalk_iter_f *func)
941 {
942 ASSERT(xtalk_registry != NULL);
943
944 cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
945 }
946
947 /*
948 * xwidget_register:
949 * Register a xtalk device (xwidget) by doing the following.
950 * -allocate and initialize xwidget_info data
951 * -allocate a hwgraph vertex with name based on widget number (id)
952 * -look up the widget's initialization function and call it,
953 * or remember the vertex for later initialization.
954 *
955 */
956 int
957 xwidget_register(xwidget_hwid_t hwid, /* widget's hardware ID */
958 devfs_handle_t widget, /* widget to initialize */
959 xwidgetnum_t id, /* widget's target id (0..f) */
960 devfs_handle_t master, /* widget's master vertex */
961 xwidgetnum_t targetid, /* master's target id (9/a) */
962 async_attach_t aa)
963 {
964 xwidget_info_t widget_info;
965 char *s,devnm[MAXDEVNAME];
966
967 /* Allocate widget_info and associate it with widget vertex */
968 NEW(widget_info);
969
970 /* Initialize widget_info */
971 widget_info->w_vertex = widget;
972 widget_info->w_id = id;
973 widget_info->w_master = master;
974 widget_info->w_masterid = targetid;
975 widget_info->w_hwid = *hwid; /* structure copy */
976 widget_info->w_efunc = 0;
977 widget_info->w_einfo = 0;
978 /*
979 * get the name of this xwidget vertex and keep the info.
980 * This is needed during errors and interrupts, but as
981 * long as we have it, we can use it elsewhere.
982 */
983 s = dev_to_name(widget,devnm,MAXDEVNAME);
984 widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
985 strcpy(widget_info->w_name,s);
986
987 xwidget_info_set(widget, widget_info);
988
989 device_master_set(widget, master);
990
991 /* All the driver init routines (including
992 * xtalk_init) are called before we get into
993 * attaching devices, so we can assume we
994 * have a registry here.
995 */
996 ASSERT(xtalk_registry != NULL);
997
998 /*
999 * Add pointer to async attach info -- tear down will be done when
1000 * the particular descendant is done with the info.
1001 */
1002 if (aa)
1003 async_attach_add_info(widget, aa);
1004
1005 return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
1006 widget, 0);
1007 }
1008
1009 /*
1010 * xwidget_unregister :
1011 * Unregister the xtalk device and detach all its hwgraph namespace.
1012 */
1013 int
1014 xwidget_unregister(devfs_handle_t widget)
1015 {
1016 xwidget_info_t widget_info;
1017 xwidget_hwid_t hwid;
1018
1019 /* Make sure that we have valid widget information initialized */
1020 if (!(widget_info = xwidget_info_get(widget)))
1021 return(1);
1022
1023 /* Remove the inventory information associated
1024 * with the widget.
1025 */
1026 hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1);
1027
1028 hwid = &(widget_info->w_hwid);
1029
1030 cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
1031 widget, 0);
1032
1033 /* Clean out the xwidget information */
1034 (void)kfree(widget_info->w_name);
1035 BZERO((void *)widget_info, sizeof(widget_info));
1036 DEL(widget_info);
1037
1038 return(0);
1039 }
1040
1041 void
1042 xwidget_error_register(devfs_handle_t xwidget,
1043 error_handler_f *efunc,
1044 error_handler_arg_t einfo)
1045 {
1046 xwidget_info_t xwidget_info;
1047
1048 xwidget_info = xwidget_info_get(xwidget);
1049 ASSERT(xwidget_info != NULL);
1050 xwidget_info->w_efunc = efunc;
1051 xwidget_info->w_einfo = einfo;
1052 }
1053
1054 /*
1055 * Issue a link reset to a widget.
1056 */
1057 void
1058 xwidget_reset(devfs_handle_t xwidget)
1059 {
1060 xswitch_reset_link(xwidget);
1061
1062 }
1063
1064
1065 void
1066 xwidget_gfx_reset(devfs_handle_t xwidget)
1067 {
1068 xwidget_info_t info;
1069
1070 xswitch_reset_link(xwidget);
1071 info = xwidget_info_get(xwidget);
1072 #ifdef LATER
1073 ASSERT_ALWAYS(info != NULL);
1074 #endif
1075
1076 /*
1077 * Enable this for other architectures once we add widget_reset to the
1078 * xtalk provider interface.
1079 */
1080 DEV_FUNC(xtalk_provider, widget_reset)
1081 (xwidget_info_master_get(info), xwidget_info_id_get(info));
1082 }
1083
1084 #define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */
1085
1086 /* Get the canonical hwgraph name of xtalk widget */
1087 char *
1088 xwidget_name_get(devfs_handle_t xwidget_vhdl)
1089 {
1090 xwidget_info_t info;
1091
1092 /* If we have a bogus widget handle then return
1093 * a default anonymous widget name.
1094 */
1095 if (xwidget_vhdl == GRAPH_VERTEX_NONE)
1096 return(ANON_XWIDGET_NAME);
1097 /* Read the widget name stored in the widget info
1098 * for the widget setup during widget initialization.
1099 */
1100 info = xwidget_info_get(xwidget_vhdl);
1101 ASSERT(info != NULL);
1102 return(xwidget_info_name_get(info));
1103 }
1104
1105 /*
1106 * xtalk_device_shutdown
1107 * Disable the specified xtalk widget and clean out all the software
1108 * state associated with it.
1109 */
1110 int
1111 xtalk_device_shutdown(devfs_handle_t xbus_vhdl, xwidgetnum_t widget)
1112 {
1113 devfs_handle_t widget_vhdl;
1114 char edge_name[8];
1115
1116 sprintf(edge_name, "%d", widget);
1117 if (hwgraph_traverse(xbus_vhdl, edge_name, &widget_vhdl)
1118 != GRAPH_SUCCESS)
1119 return(1);
1120
1121 xwidget_unregister(widget_vhdl);
1122
1123 return(0);
1124 }
1125 /*
1126 * xtalk_device_inquiry
1127 * Find out hardware information about the xtalk widget.
1128 */
1129 int
1130 xtalk_device_inquiry(devfs_handle_t xbus_vhdl, xwidgetnum_t widget)
1131 {
1132
1133 extern void hub_device_inquiry(devfs_handle_t, xwidgetnum_t);
1134 hub_device_inquiry(xbus_vhdl, widget);
1135 return(0);
1136 }
1137