initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / ia64 / sn / io / sn2 / xtalk.c
blob4e9769cfb1630297d4c1d5867095b3c08349d07f
1 /*
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
4 * for more details.
6 * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
7 */
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,
89 xwidget_mfg_num_t,
90 char *, unsigned);
91 void xwidget_driver_unregister(char *);
92 int xwidget_register(xwidget_hwid_t, vertex_hdl_t,
93 xwidgetnum_t, vertex_hdl_t,
94 xwidgetnum_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);
127 xtalk_provider_t *
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);
135 return provider_fns;
137 #endif
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 /* =====================================================================
150 * PIO MANAGEMENT
152 * For mapping system virtual address space to
153 * xtalk space on a specified widget
156 xtalk_piomap_t
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 */
160 size_t byte_count,
161 size_t byte_count_max, /* maximum size of a mapping */
162 unsigned flags)
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);
169 void
170 xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
172 PIOMAP_FUNC(xtalk_piomap, piomap_free)
173 (CAST_PIOMAP(xtalk_piomap));
177 caddr_t
178 xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap, /* mapping resources */
179 iopaddr_t xtalk_addr, /* map for this xtalk address */
180 size_t byte_count)
181 { /* map this many bytes */
182 return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
183 (CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
187 void
188 xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
190 PIOMAP_FUNC(xtalk_piomap, piomap_done)
191 (CAST_PIOMAP(xtalk_piomap));
195 caddr_t
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 */
200 unsigned flags)
201 { /* (currently unused) */
202 return DEV_FUNC(dev, piotrans_addr)
203 (dev, dev_desc, xtalk_addr, byte_count, flags);
206 caddr_t
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 */
212 unsigned flags)
213 { /* PIO flags */
214 xtalk_piomap_t map = 0;
215 caddr_t res;
217 if (mapp)
218 *mapp = 0; /* record "no map used" */
220 res = xtalk_piotrans_addr
221 (dev, dev_desc, addr, byte_count, flags);
222 if (res)
223 return res; /* xtalk_piotrans worked */
225 map = xtalk_piomap_alloc
226 (dev, dev_desc, addr, byte_count, byte_count, flags);
227 if (!map)
228 return res; /* xtalk_piomap_alloc failed */
230 res = xtalk_piomap_addr
231 (map, addr, byte_count);
232 if (!res) {
233 xtalk_piomap_free(map);
234 return res; /* xtalk_piomap_addr failed */
236 if (mapp)
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.
267 void
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
277 * be constructed.
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.
282 caddr_t
283 xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
284 xwidget_mfg_num_t mfg_num,
285 int which,
286 iopaddr_t xtalk_addr,
287 size_t byte_count,
288 unsigned flags)
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.
301 /*ARGSUSED */
302 static caddr_t
303 null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
304 xwidget_mfg_num_t mfg_num,
305 int which,
306 iopaddr_t xtalk_addr,
307 size_t byte_count,
308 unsigned flags)
310 #if DEBUG
311 panic("null_xtalk_early_piotrans_addr");
312 #endif
313 return NULL;
316 /* =====================================================================
317 * DMA MANAGEMENT
319 * For mapping from io channel space to system
320 * physical space.
323 xtalk_dmamap_t
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 */
327 unsigned flags)
328 { /* defined in dma.h */
329 return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
330 (dev, dev_desc, byte_count_max, flags);
334 void
335 xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
337 DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
338 (CAST_DMAMAP(xtalk_dmamap));
342 iopaddr_t
343 xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap, /* use these mapping resources */
344 paddr_t paddr, /* map for this address */
345 size_t byte_count)
346 { /* map this many bytes */
347 return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
348 (CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
352 void
353 xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
355 DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
356 (CAST_DMAMAP(xtalk_dmamap));
360 iopaddr_t
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 */
365 unsigned flags)
366 { /* defined in dma.h */
367 return DEV_FUNC(dev, dmatrans_addr)
368 (dev, dev_desc, paddr, byte_count, flags);
372 void
373 xtalk_dmamap_drain(xtalk_dmamap_t map)
375 DMAMAP_FUNC(map, dmamap_drain)
376 (CAST_DMAMAP(map));
379 void
380 xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
382 DEV_FUNC(dev, dmaaddr_drain)
383 (dev, addr, size);
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.
396 xtalk_intr_t
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.
410 xtalk_intr_t
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.
422 void
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.
451 void
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.
463 vertex_hdl_t
464 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
466 return (vertex_hdl_t)0;
471 * =====================================================================
472 * ERROR MANAGEMENT
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
486 * to the agent.
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.
495 xtalk_error_handler(
496 vertex_hdl_t xconn,
497 int error_code,
498 ioerror_mode_t mode,
499 ioerror_t *ioerror)
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
537 void
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
547 void
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
556 void
557 xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum)
559 return;
563 * Shutdown a device on a xtalk widget
565 void
566 xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum)
568 return;
572 * Generic io channel functions, for use with all io channel providers
573 * and all io channel devices.
576 /* Generic io channel interrupt interfaces */
577 vertex_hdl_t
578 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
580 return (xtalk_intr->xi_dev);
583 xwidgetnum_t
584 xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
586 return (xtalk_intr->xi_target);
589 xtalk_intr_vector_t
590 xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
592 return (xtalk_intr->xi_vector);
595 iopaddr_t
596 xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
598 return (xtalk_intr->xi_addr);
601 void *
602 xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
604 return (xtalk_intr->xi_sfarg);
607 /* Generic io channel pio interfaces */
608 vertex_hdl_t
609 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
611 return (xtalk_piomap->xp_dev);
614 xwidgetnum_t
615 xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
617 return (xtalk_piomap->xp_target);
620 iopaddr_t
621 xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
623 return (xtalk_piomap->xp_xtalk_addr);
626 ulong
627 xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
629 return (xtalk_piomap->xp_mapsz);
632 caddr_t
633 xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
635 return (xtalk_piomap->xp_kvaddr);
639 /* Generic io channel dma interfaces */
640 vertex_hdl_t
641 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
643 return (xtalk_dmamap->xd_dev);
646 xwidgetnum_t
647 xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
649 return (xtalk_dmamap->xd_target);
653 /* Generic io channel widget information interfaces */
655 /* xwidget_info_chk:
656 * check to see if this vertex is a widget;
657 * if so, return its widget_info (if any).
658 * if not, return NULL.
660 xwidget_info_t
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;
670 xwidget_info_t
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);
681 void
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);
697 vertex_hdl_t
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);
705 xwidgetnum_t
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);
714 vertex_hdl_t
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);
722 xwidgetnum_t
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);
730 xwidget_part_num_t
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);
738 xwidget_mfg_num_t
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.
748 char *
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.
760 void
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.
769 void
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
777 * provider.
779 xtalk_provider_t *
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.
789 void
790 xwidget_driver_unregister(char *driver_prefix)
792 return;
796 * Call some function with each vertex that
797 * might be one of this driver's attach points.
799 void
800 xtalk_iterate(char *driver_prefix,
801 xtalk_iter_f *func)
806 * xwidget_register:
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);
826 if (!widget_info)
827 return - ENOMEM;
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,
855 widget, 0);
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;
866 xwidget_hwid_t hwid;
868 /* Make sure that we have valid widget information initialized */
869 if (!(widget_info = xwidget_info_get(widget)))
870 return 1;
872 hwid = &(widget_info->w_hwid);
874 kfree(widget_info->w_name);
875 kfree(widget_info);
876 return 0;
879 void
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.
895 void
896 xwidget_reset(vertex_hdl_t xwidget)
898 xswitch_reset_link(xwidget);
902 void
903 xwidget_gfx_reset(vertex_hdl_t xwidget)
905 return;
908 #define ANON_XWIDGET_NAME "No Name" /* Default Widget Name */
910 /* Get the canonical hwgraph name of xtalk widget */
911 char *
912 xwidget_name_get(vertex_hdl_t xwidget_vhdl)
914 xwidget_info_t info;
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));