2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
6 * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <asm/sn/sgi.h>
12 #include <asm/sn/driver.h>
13 #include <asm/sn/io.h>
14 #include <asm/sn/iograph.h>
15 #include <asm/sn/hcl.h>
16 #include <asm/sn/labelcl.h>
17 #include <asm/sn/hcl_util.h>
18 #include <asm/sn/xtalk/xtalk.h>
19 #include <asm/sn/xtalk/xswitch.h>
20 #include <asm/sn/xtalk/xwidget.h>
21 #include <asm/sn/xtalk/xtalk_private.h>
24 * Implement io channel provider operations. The xtalk* layer provides a
25 * platform-independent interface for io channel devices. This layer
26 * switches among the possible implementations of a io channel adapter.
28 * On platforms with only one possible xtalk provider, macros can be
29 * set up at the top that cause the table lookups and indirections to
30 * completely disappear.
33 char widget_info_fingerprint
[] = "widget_info";
35 /* =====================================================================
36 * Function Table of Contents
38 xtalk_piomap_t
xtalk_piomap_alloc(vertex_hdl_t
, device_desc_t
, iopaddr_t
, size_t, size_t, unsigned);
39 void xtalk_piomap_free(xtalk_piomap_t
);
40 caddr_t
xtalk_piomap_addr(xtalk_piomap_t
, iopaddr_t
, size_t);
41 void xtalk_piomap_done(xtalk_piomap_t
);
42 caddr_t
xtalk_piotrans_addr(vertex_hdl_t
, device_desc_t
, iopaddr_t
, size_t, unsigned);
43 caddr_t
xtalk_pio_addr(vertex_hdl_t
, device_desc_t
, iopaddr_t
, size_t, xtalk_piomap_t
*, unsigned);
44 void xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f
*);
45 caddr_t
xtalk_early_piotrans_addr(xwidget_part_num_t
, xwidget_mfg_num_t
, int, iopaddr_t
, size_t, unsigned);
46 static caddr_t
null_xtalk_early_piotrans_addr(xwidget_part_num_t
, xwidget_mfg_num_t
, int, iopaddr_t
, size_t, unsigned);
47 xtalk_dmamap_t
xtalk_dmamap_alloc(vertex_hdl_t
, device_desc_t
, size_t, unsigned);
48 void xtalk_dmamap_free(xtalk_dmamap_t
);
49 iopaddr_t
xtalk_dmamap_addr(xtalk_dmamap_t
, paddr_t
, size_t);
50 void xtalk_dmamap_done(xtalk_dmamap_t
);
51 iopaddr_t
xtalk_dmatrans_addr(vertex_hdl_t
, device_desc_t
, paddr_t
, size_t, unsigned);
52 void xtalk_dmamap_drain(xtalk_dmamap_t
);
53 void xtalk_dmaaddr_drain(vertex_hdl_t
, iopaddr_t
, size_t);
54 xtalk_intr_t
xtalk_intr_alloc(vertex_hdl_t
, device_desc_t
, vertex_hdl_t
);
55 xtalk_intr_t
xtalk_intr_alloc_nothd(vertex_hdl_t
, device_desc_t
, vertex_hdl_t
);
56 void xtalk_intr_free(xtalk_intr_t
);
57 int xtalk_intr_connect(xtalk_intr_t
, intr_func_t
, intr_arg_t
, xtalk_intr_setfunc_t
, void *);
58 void xtalk_intr_disconnect(xtalk_intr_t
);
59 vertex_hdl_t
xtalk_intr_cpu_get(xtalk_intr_t
);
60 int xtalk_error_handler(vertex_hdl_t
, int, ioerror_mode_t
, ioerror_t
*);
61 void xtalk_provider_startup(vertex_hdl_t
);
62 void xtalk_provider_shutdown(vertex_hdl_t
);
63 vertex_hdl_t
xtalk_intr_dev_get(xtalk_intr_t
);
64 xwidgetnum_t
xtalk_intr_target_get(xtalk_intr_t
);
65 xtalk_intr_vector_t
xtalk_intr_vector_get(xtalk_intr_t
);
66 iopaddr_t
xtalk_intr_addr_get(struct xtalk_intr_s
*);
67 void *xtalk_intr_sfarg_get(xtalk_intr_t
);
68 vertex_hdl_t
xtalk_pio_dev_get(xtalk_piomap_t
);
69 xwidgetnum_t
xtalk_pio_target_get(xtalk_piomap_t
);
70 iopaddr_t
xtalk_pio_xtalk_addr_get(xtalk_piomap_t
);
71 ulong
xtalk_pio_mapsz_get(xtalk_piomap_t
);
72 caddr_t
xtalk_pio_kvaddr_get(xtalk_piomap_t
);
73 vertex_hdl_t
xtalk_dma_dev_get(xtalk_dmamap_t
);
74 xwidgetnum_t
xtalk_dma_target_get(xtalk_dmamap_t
);
75 xwidget_info_t
xwidget_info_chk(vertex_hdl_t
);
76 xwidget_info_t
xwidget_info_get(vertex_hdl_t
);
77 void xwidget_info_set(vertex_hdl_t
, xwidget_info_t
);
78 vertex_hdl_t
xwidget_info_dev_get(xwidget_info_t
);
79 xwidgetnum_t
xwidget_info_id_get(xwidget_info_t
);
80 vertex_hdl_t
xwidget_info_master_get(xwidget_info_t
);
81 xwidgetnum_t
xwidget_info_masterid_get(xwidget_info_t
);
82 xwidget_part_num_t
xwidget_info_part_num_get(xwidget_info_t
);
83 xwidget_mfg_num_t
xwidget_info_mfg_num_get(xwidget_info_t
);
84 char *xwidget_info_name_get(xwidget_info_t
);
85 void xtalk_provider_register(vertex_hdl_t
, xtalk_provider_t
*);
86 void xtalk_provider_unregister(vertex_hdl_t
);
87 xtalk_provider_t
*xtalk_provider_fns_get(vertex_hdl_t
);
88 int xwidget_driver_register(xwidget_part_num_t
,
91 void xwidget_driver_unregister(char *);
92 int xwidget_register(xwidget_hwid_t
, vertex_hdl_t
,
93 xwidgetnum_t
, vertex_hdl_t
,
95 int xwidget_unregister(vertex_hdl_t
);
96 void xwidget_reset(vertex_hdl_t
);
97 char *xwidget_name_get(vertex_hdl_t
);
98 #if !defined(DEV_FUNC)
100 * There is more than one possible provider
101 * for this platform. We need to examine the
102 * master vertex of the current vertex for
103 * a provider function structure, and indirect
104 * through the appropriately named member.
106 #define DEV_FUNC(dev,func) xwidget_to_provider_fns(dev)->func
107 #define CAST_PIOMAP(x) ((xtalk_piomap_t)(x))
108 #define CAST_DMAMAP(x) ((xtalk_dmamap_t)(x))
109 #define CAST_INTR(x) ((xtalk_intr_t)(x))
110 xtalk_provider_t
* xwidget_info_pops_get(xwidget_info_t info
);
112 static xtalk_provider_t
*
113 xwidget_to_provider_fns(vertex_hdl_t xconn
)
115 xwidget_info_t widget_info
;
116 xtalk_provider_t
*provider_fns
;
118 widget_info
= xwidget_info_get(xconn
);
119 ASSERT(widget_info
!= NULL
);
121 provider_fns
= xwidget_info_pops_get(widget_info
);
122 ASSERT(provider_fns
!= NULL
);
124 return (provider_fns
);
128 xwidget_info_pops_get(xwidget_info_t info
) {
129 vertex_hdl_t master
= info
->w_master
;
130 xtalk_provider_t
*provider_fns
;
132 provider_fns
= xtalk_provider_fns_get(master
);
134 ASSERT(provider_fns
!= NULL
);
140 * Many functions are not passed their vertex
141 * information directly; rather, they must
142 * dive through a resource map. These macros
143 * are available to coordinate this detail.
145 #define PIOMAP_FUNC(map,func) DEV_FUNC(map->xp_dev,func)
146 #define DMAMAP_FUNC(map,func) DEV_FUNC(map->xd_dev,func)
147 #define INTR_FUNC(intr,func) DEV_FUNC(intr_hdl->xi_dev,func)
149 /* =====================================================================
152 * For mapping system virtual address space to
153 * xtalk space on a specified widget
157 xtalk_piomap_alloc(vertex_hdl_t dev
, /* set up mapping for this device */
158 device_desc_t dev_desc
, /* device descriptor */
159 iopaddr_t xtalk_addr
, /* map for this xtalk_addr range */
161 size_t byte_count_max
, /* maximum size of a mapping */
163 { /* defined in sys/pio.h */
164 return (xtalk_piomap_t
) DEV_FUNC(dev
, piomap_alloc
)
165 (dev
, dev_desc
, xtalk_addr
, byte_count
, byte_count_max
, flags
);
170 xtalk_piomap_free(xtalk_piomap_t xtalk_piomap
)
172 PIOMAP_FUNC(xtalk_piomap
, piomap_free
)
173 (CAST_PIOMAP(xtalk_piomap
));
178 xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap
, /* mapping resources */
179 iopaddr_t xtalk_addr
, /* map for this xtalk address */
181 { /* map this many bytes */
182 return PIOMAP_FUNC(xtalk_piomap
, piomap_addr
)
183 (CAST_PIOMAP(xtalk_piomap
), xtalk_addr
, byte_count
);
188 xtalk_piomap_done(xtalk_piomap_t xtalk_piomap
)
190 PIOMAP_FUNC(xtalk_piomap
, piomap_done
)
191 (CAST_PIOMAP(xtalk_piomap
));
196 xtalk_piotrans_addr(vertex_hdl_t dev
, /* translate for this device */
197 device_desc_t dev_desc
, /* device descriptor */
198 iopaddr_t xtalk_addr
, /* Crosstalk address */
199 size_t byte_count
, /* map this many bytes */
201 { /* (currently unused) */
202 return DEV_FUNC(dev
, piotrans_addr
)
203 (dev
, dev_desc
, xtalk_addr
, byte_count
, flags
);
207 xtalk_pio_addr(vertex_hdl_t dev
, /* translate for this device */
208 device_desc_t dev_desc
, /* device descriptor */
209 iopaddr_t addr
, /* starting address (or offset in window) */
210 size_t byte_count
, /* map this many bytes */
211 xtalk_piomap_t
*mapp
, /* where to return the map pointer */
214 xtalk_piomap_t map
= 0;
218 *mapp
= 0; /* record "no map used" */
220 res
= xtalk_piotrans_addr
221 (dev
, dev_desc
, addr
, byte_count
, flags
);
223 return res
; /* xtalk_piotrans worked */
225 map
= xtalk_piomap_alloc
226 (dev
, dev_desc
, addr
, byte_count
, byte_count
, flags
);
228 return res
; /* xtalk_piomap_alloc failed */
230 res
= xtalk_piomap_addr
231 (map
, addr
, byte_count
);
233 xtalk_piomap_free(map
);
234 return res
; /* xtalk_piomap_addr failed */
237 *mapp
= map
; /* pass back map used */
239 return res
; /* xtalk_piomap_addr succeeded */
242 /* =====================================================================
243 * EARLY PIOTRANS SUPPORT
245 * There are places where drivers (mgras, for instance)
246 * need to get PIO translations before the infrastructure
247 * is extended to them (setting up textports, for
248 * instance). These drivers should call
249 * xtalk_early_piotrans_addr with their xtalk ID
250 * information, a sequence number (so we can use the second
251 * mgras for instance), and the usual piotrans parameters.
253 * Machine specific code should provide an implementation
254 * of early_piotrans_addr, and present a pointer to this
255 * function to xtalk_set_early_piotrans_addr so it can be
256 * used by clients without the clients having to know what
257 * platform or what xtalk provider is in use.
260 static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr
;
262 xtalk_early_piotrans_addr_f
*impl_early_piotrans_addr
= null_xtalk_early_piotrans_addr
;
264 /* xtalk_set_early_piotrans_addr:
265 * specify the early_piotrans_addr implementation function.
268 xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f
*impl
)
270 impl_early_piotrans_addr
= impl
;
273 /* xtalk_early_piotrans_addr:
274 * figure out a PIO address for the "nth" io channel widget that
275 * matches the specified part and mfgr number. Returns NULL if
276 * there is no such widget, or if the requested mapping can not
278 * Limitations on which io channel slots (and busses) are
279 * checked, and definitions of the ordering of the search across
280 * the io channel slots, are defined by the platform.
283 xtalk_early_piotrans_addr(xwidget_part_num_t part_num
,
284 xwidget_mfg_num_t mfg_num
,
286 iopaddr_t xtalk_addr
,
290 return impl_early_piotrans_addr
291 (part_num
, mfg_num
, which
, xtalk_addr
, byte_count
, flags
);
294 /* null_xtalk_early_piotrans_addr:
295 * used as the early_piotrans_addr implementation until and
296 * unless a real implementation is provided. In DEBUG kernels,
297 * we want to know who is calling before the implementation is
298 * registered; in non-DEBUG kernels, return NULL representing
299 * lack of mapping support.
303 null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num
,
304 xwidget_mfg_num_t mfg_num
,
306 iopaddr_t xtalk_addr
,
311 panic("null_xtalk_early_piotrans_addr");
316 /* =====================================================================
319 * For mapping from io channel space to system
324 xtalk_dmamap_alloc(vertex_hdl_t dev
, /* set up mappings for this device */
325 device_desc_t dev_desc
, /* device descriptor */
326 size_t byte_count_max
, /* max size of a mapping */
328 { /* defined in dma.h */
329 return (xtalk_dmamap_t
) DEV_FUNC(dev
, dmamap_alloc
)
330 (dev
, dev_desc
, byte_count_max
, flags
);
335 xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap
)
337 DMAMAP_FUNC(xtalk_dmamap
, dmamap_free
)
338 (CAST_DMAMAP(xtalk_dmamap
));
343 xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap
, /* use these mapping resources */
344 paddr_t paddr
, /* map for this address */
346 { /* map this many bytes */
347 return DMAMAP_FUNC(xtalk_dmamap
, dmamap_addr
)
348 (CAST_DMAMAP(xtalk_dmamap
), paddr
, byte_count
);
353 xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap
)
355 DMAMAP_FUNC(xtalk_dmamap
, dmamap_done
)
356 (CAST_DMAMAP(xtalk_dmamap
));
361 xtalk_dmatrans_addr(vertex_hdl_t dev
, /* translate for this device */
362 device_desc_t dev_desc
, /* device descriptor */
363 paddr_t paddr
, /* system physical address */
364 size_t byte_count
, /* length */
366 { /* defined in dma.h */
367 return DEV_FUNC(dev
, dmatrans_addr
)
368 (dev
, dev_desc
, paddr
, byte_count
, flags
);
373 xtalk_dmamap_drain(xtalk_dmamap_t map
)
375 DMAMAP_FUNC(map
, dmamap_drain
)
380 xtalk_dmaaddr_drain(vertex_hdl_t dev
, paddr_t addr
, size_t size
)
382 DEV_FUNC(dev
, dmaaddr_drain
)
386 /* =====================================================================
387 * INTERRUPT MANAGEMENT
389 * Allow io channel devices to establish interrupts
393 * Allocate resources required for an interrupt as specified in intr_desc.
394 * Return resource handle in intr_hdl.
397 xtalk_intr_alloc(vertex_hdl_t dev
, /* which Crosstalk device */
398 device_desc_t dev_desc
, /* device descriptor */
399 vertex_hdl_t owner_dev
)
400 { /* owner of this interrupt */
401 return (xtalk_intr_t
) DEV_FUNC(dev
, intr_alloc
)
402 (dev
, dev_desc
, owner_dev
);
406 * Allocate resources required for an interrupt as specified in dev_desc.
407 * Unconditionally setup resources to be non-threaded.
408 * Return resource handle in intr_hdl.
411 xtalk_intr_alloc_nothd(vertex_hdl_t dev
, /* which Crosstalk device */
412 device_desc_t dev_desc
, /* device descriptor */
413 vertex_hdl_t owner_dev
) /* owner of this interrupt */
415 return (xtalk_intr_t
) DEV_FUNC(dev
, intr_alloc_nothd
)
416 (dev
, dev_desc
, owner_dev
);
420 * Free resources consumed by intr_alloc.
423 xtalk_intr_free(xtalk_intr_t intr_hdl
)
425 INTR_FUNC(intr_hdl
, intr_free
)
426 (CAST_INTR(intr_hdl
));
431 * Associate resources allocated with a previous xtalk_intr_alloc call with the
432 * described handler, arg, name, etc.
434 * Returns 0 on success, returns <0 on failure.
437 xtalk_intr_connect(xtalk_intr_t intr_hdl
, /* xtalk intr resource handle */
438 intr_func_t intr_func
, /* xtalk intr handler */
439 intr_arg_t intr_arg
, /* arg to intr handler */
440 xtalk_intr_setfunc_t setfunc
, /* func to set intr hw */
441 void *setfunc_arg
) /* arg to setfunc */
443 return INTR_FUNC(intr_hdl
, intr_connect
)
444 (CAST_INTR(intr_hdl
), intr_func
, intr_arg
, setfunc
, setfunc_arg
);
449 * Disassociate handler with the specified interrupt.
452 xtalk_intr_disconnect(xtalk_intr_t intr_hdl
)
454 INTR_FUNC(intr_hdl
, intr_disconnect
)
455 (CAST_INTR(intr_hdl
));
460 * Return a hwgraph vertex that represents the CPU currently
461 * targeted by an interrupt.
464 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl
)
466 return (vertex_hdl_t
)0;
471 * =====================================================================
476 * xtalk_error_handler:
477 * pass this error on to the handler registered
478 * at the specified xtalk connecdtion point,
479 * or complain about it here if there is no handler.
481 * This routine plays two roles during error delivery
482 * to most widgets: first, the external agent (heart,
483 * hub, or whatever) calls in with the error and the
484 * connect point representing the io channel switch,
485 * or whatever io channel device is directly connected
488 * If there is a switch, it will generally look at the
489 * widget number stashed in the ioerror structure; and,
490 * if the error came from some widget other than the
491 * switch, it will call back into xtalk_error_handler
492 * with the connection point of the offending port.
501 xwidget_info_t xwidget_info
;
502 char name
[MAXDEVNAME
];
505 xwidget_info
= xwidget_info_get(xconn
);
506 /* Make sure that xwidget_info is a valid pointer before derefencing it.
507 * We could come in here during very early initialization.
509 if (xwidget_info
&& xwidget_info
->w_efunc
)
510 return xwidget_info
->w_efunc
511 (xwidget_info
->w_einfo
,
512 error_code
, mode
, ioerror
);
514 * no error handler registered for
515 * the offending port. it's not clear
516 * what needs to be done, but reporting
517 * it would be a good thing, unless it
518 * is a mode that requires nothing.
520 if ((mode
== MODE_DEVPROBE
) || (mode
== MODE_DEVUSERERROR
) ||
521 (mode
== MODE_DEVREENABLE
))
522 return IOERROR_HANDLED
;
524 printk(KERN_WARNING
"Xbow at %s encountered Fatal error", vertex_to_name(xconn
, name
, MAXDEVNAME
));
526 return IOERROR_UNHANDLED
;
530 /* =====================================================================
531 * CONFIGURATION MANAGEMENT
535 * Startup an io channel provider
538 xtalk_provider_startup(vertex_hdl_t xtalk_provider
)
540 ((xtalk_provider_t
*) hwgraph_fastinfo_get(xtalk_provider
))->provider_startup(xtalk_provider
);
545 * Shutdown an io channel provider
548 xtalk_provider_shutdown(vertex_hdl_t xtalk_provider
)
550 ((xtalk_provider_t
*) hwgraph_fastinfo_get(xtalk_provider
))->provider_shutdown(xtalk_provider
);
554 * Enable a device on a xtalk widget
557 xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl
, int devnum
)
563 * Shutdown a device on a xtalk widget
566 xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl
, int devnum
)
572 * Generic io channel functions, for use with all io channel providers
573 * and all io channel devices.
576 /* Generic io channel interrupt interfaces */
578 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr
)
580 return (xtalk_intr
->xi_dev
);
584 xtalk_intr_target_get(xtalk_intr_t xtalk_intr
)
586 return (xtalk_intr
->xi_target
);
590 xtalk_intr_vector_get(xtalk_intr_t xtalk_intr
)
592 return (xtalk_intr
->xi_vector
);
596 xtalk_intr_addr_get(struct xtalk_intr_s
*xtalk_intr
)
598 return (xtalk_intr
->xi_addr
);
602 xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr
)
604 return (xtalk_intr
->xi_sfarg
);
607 /* Generic io channel pio interfaces */
609 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap
)
611 return (xtalk_piomap
->xp_dev
);
615 xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap
)
617 return (xtalk_piomap
->xp_target
);
621 xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap
)
623 return (xtalk_piomap
->xp_xtalk_addr
);
627 xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap
)
629 return (xtalk_piomap
->xp_mapsz
);
633 xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap
)
635 return (xtalk_piomap
->xp_kvaddr
);
639 /* Generic io channel dma interfaces */
641 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap
)
643 return (xtalk_dmamap
->xd_dev
);
647 xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap
)
649 return (xtalk_dmamap
->xd_target
);
653 /* Generic io channel widget information interfaces */
656 * check to see if this vertex is a widget;
657 * if so, return its widget_info (if any).
658 * if not, return NULL.
661 xwidget_info_chk(vertex_hdl_t xwidget
)
663 arbitrary_info_t ainfo
= 0;
665 hwgraph_info_get_LBL(xwidget
, INFO_LBL_XWIDGET
, &ainfo
);
666 return (xwidget_info_t
) ainfo
;
671 xwidget_info_get(vertex_hdl_t xwidget
)
673 xwidget_info_t widget_info
;
675 widget_info
= (xwidget_info_t
)
676 hwgraph_fastinfo_get(xwidget
);
678 return (widget_info
);
682 xwidget_info_set(vertex_hdl_t xwidget
, xwidget_info_t widget_info
)
684 if (widget_info
!= NULL
)
685 widget_info
->w_fingerprint
= widget_info_fingerprint
;
687 hwgraph_fastinfo_set(xwidget
, (arbitrary_info_t
) widget_info
);
689 /* Also, mark this vertex as an xwidget,
690 * and use the widget_info, so xwidget_info_chk
691 * can work (and be fairly efficient).
693 hwgraph_info_add_LBL(xwidget
, INFO_LBL_XWIDGET
,
694 (arbitrary_info_t
) widget_info
);
698 xwidget_info_dev_get(xwidget_info_t xwidget_info
)
700 if (xwidget_info
== NULL
)
701 panic("xwidget_info_dev_get: null xwidget_info");
702 return (xwidget_info
->w_vertex
);
706 xwidget_info_id_get(xwidget_info_t xwidget_info
)
708 if (xwidget_info
== NULL
)
709 panic("xwidget_info_id_get: null xwidget_info");
710 return (xwidget_info
->w_id
);
715 xwidget_info_master_get(xwidget_info_t xwidget_info
)
717 if (xwidget_info
== NULL
)
718 panic("xwidget_info_master_get: null xwidget_info");
719 return (xwidget_info
->w_master
);
723 xwidget_info_masterid_get(xwidget_info_t xwidget_info
)
725 if (xwidget_info
== NULL
)
726 panic("xwidget_info_masterid_get: null xwidget_info");
727 return (xwidget_info
->w_masterid
);
731 xwidget_info_part_num_get(xwidget_info_t xwidget_info
)
733 if (xwidget_info
== NULL
)
734 panic("xwidget_info_part_num_get: null xwidget_info");
735 return (xwidget_info
->w_hwid
.part_num
);
739 xwidget_info_mfg_num_get(xwidget_info_t xwidget_info
)
741 if (xwidget_info
== NULL
)
742 panic("xwidget_info_mfg_num_get: null xwidget_info");
743 return (xwidget_info
->w_hwid
.mfg_num
);
745 /* Extract the widget name from the widget information
746 * for the xtalk widget.
749 xwidget_info_name_get(xwidget_info_t xwidget_info
)
751 if (xwidget_info
== NULL
)
752 panic("xwidget_info_name_get: null xwidget_info");
753 return(xwidget_info
->w_name
);
755 /* Generic io channel initialization interfaces */
758 * Associate a set of xtalk_provider functions with a vertex.
761 xtalk_provider_register(vertex_hdl_t provider
, xtalk_provider_t
*xtalk_fns
)
763 hwgraph_fastinfo_set(provider
, (arbitrary_info_t
) xtalk_fns
);
767 * Disassociate a set of xtalk_provider functions with a vertex.
770 xtalk_provider_unregister(vertex_hdl_t provider
)
772 hwgraph_fastinfo_set(provider
, (arbitrary_info_t
)NULL
);
776 * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
780 xtalk_provider_fns_get(vertex_hdl_t provider
)
782 return ((xtalk_provider_t
*) hwgraph_fastinfo_get(provider
));
786 * Inform xtalk infrastructure that a driver is no longer available for
787 * handling any widgets.
790 xwidget_driver_unregister(char *driver_prefix
)
796 * Call some function with each vertex that
797 * might be one of this driver's attach points.
800 xtalk_iterate(char *driver_prefix
,
807 * Register a xtalk device (xwidget) by doing the following.
808 * -allocate and initialize xwidget_info data
809 * -allocate a hwgraph vertex with name based on widget number (id)
810 * -look up the widget's initialization function and call it,
811 * or remember the vertex for later initialization.
815 xwidget_register(xwidget_hwid_t hwid
, /* widget's hardware ID */
816 vertex_hdl_t widget
, /* widget to initialize */
817 xwidgetnum_t id
, /* widget's target id (0..f) */
818 vertex_hdl_t master
, /* widget's master vertex */
819 xwidgetnum_t targetid
) /* master's target id (9/a) */
821 xwidget_info_t widget_info
;
822 char *s
,devnm
[MAXDEVNAME
];
824 /* Allocate widget_info and associate it with widget vertex */
825 widget_info
= kmalloc(sizeof(*widget_info
), GFP_KERNEL
);
829 /* Initialize widget_info */
830 widget_info
->w_vertex
= widget
;
831 widget_info
->w_id
= id
;
832 widget_info
->w_master
= master
;
833 widget_info
->w_masterid
= targetid
;
834 widget_info
->w_hwid
= *hwid
; /* structure copy */
835 widget_info
->w_efunc
= 0;
836 widget_info
->w_einfo
= 0;
838 * get the name of this xwidget vertex and keep the info.
839 * This is needed during errors and interupts, but as
840 * long as we have it, we can use it elsewhere.
842 s
= dev_to_name(widget
,devnm
,MAXDEVNAME
);
843 widget_info
->w_name
= kmalloc(strlen(s
) + 1, GFP_KERNEL
);
844 strcpy(widget_info
->w_name
,s
);
846 xwidget_info_set(widget
, widget_info
);
848 device_master_set(widget
, master
);
851 * Add pointer to async attach info -- tear down will be done when
852 * the particular descendant is done with the info.
854 return cdl_add_connpt(hwid
->part_num
, hwid
->mfg_num
,
859 * xwidget_unregister :
860 * Unregister the xtalk device and detach all its hwgraph namespace.
863 xwidget_unregister(vertex_hdl_t widget
)
865 xwidget_info_t widget_info
;
868 /* Make sure that we have valid widget information initialized */
869 if (!(widget_info
= xwidget_info_get(widget
)))
872 hwid
= &(widget_info
->w_hwid
);
874 kfree(widget_info
->w_name
);
880 xwidget_error_register(vertex_hdl_t xwidget
,
881 error_handler_f
*efunc
,
882 error_handler_arg_t einfo
)
884 xwidget_info_t xwidget_info
;
886 xwidget_info
= xwidget_info_get(xwidget
);
887 ASSERT(xwidget_info
!= NULL
);
888 xwidget_info
->w_efunc
= efunc
;
889 xwidget_info
->w_einfo
= einfo
;
893 * Issue a link reset to a widget.
896 xwidget_reset(vertex_hdl_t xwidget
)
898 xswitch_reset_link(xwidget
);
903 xwidget_gfx_reset(vertex_hdl_t xwidget
)
908 #define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */
910 /* Get the canonical hwgraph name of xtalk widget */
912 xwidget_name_get(vertex_hdl_t xwidget_vhdl
)
916 /* If we have a bogus widget handle then return
917 * a default anonymous widget name.
919 if (xwidget_vhdl
== GRAPH_VERTEX_NONE
)
920 return(ANON_XWIDGET_NAME
);
921 /* Read the widget name stored in the widget info
922 * for the widget setup during widget initialization.
924 info
= xwidget_info_get(xwidget_vhdl
);
925 ASSERT(info
!= NULL
);
926 return(xwidget_info_name_get(info
));