ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / ia64 / sn / io / sn2 / xtalk.c
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.
5  *
6  * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
7  */
8
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>
22
23 /*
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.
27  *
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.
31  */
32
33 char                    widget_info_fingerprint[] = "widget_info";
34
35 /* =====================================================================
36  *            Function Table of Contents
37  */
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)
99 /*
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.
105  */
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);
111
112 static xtalk_provider_t *
113 xwidget_to_provider_fns(vertex_hdl_t xconn)
114 {
115     xwidget_info_t          widget_info;
116     xtalk_provider_t       *provider_fns;
117
118     widget_info = xwidget_info_get(xconn);
119     ASSERT(widget_info != NULL);
120
121     provider_fns = xwidget_info_pops_get(widget_info);
122     ASSERT(provider_fns != NULL);
123
124     return (provider_fns);
125 }
126
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;
131
132         provider_fns = xtalk_provider_fns_get(master);
133
134         ASSERT(provider_fns != NULL);
135         return provider_fns;
136 }
137 #endif
138
139 /*
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.
144  */
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)
148
149 /* =====================================================================
150  *                    PIO MANAGEMENT
151  *
152  *      For mapping system virtual address space to
153  *      xtalk space on a specified widget
154  */
155
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);
166 }
167
168
169 void
170 xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
171 {
172     PIOMAP_FUNC(xtalk_piomap, piomap_free)
173         (CAST_PIOMAP(xtalk_piomap));
174 }
175
176
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);
184 }
185
186
187 void
188 xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
189 {
190     PIOMAP_FUNC(xtalk_piomap, piomap_done)
191         (CAST_PIOMAP(xtalk_piomap));
192 }
193
194
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);
204 }
205
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;
216
217     if (mapp)
218         *mapp = 0;                      /* record "no map used" */
219
220     res = xtalk_piotrans_addr
221         (dev, dev_desc, addr, byte_count, flags);
222     if (res)
223         return res;                     /* xtalk_piotrans worked */
224
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 */
229
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 */
235     }
236     if (mapp)
237         *mapp = map;                    /* pass back map used */
238
239     return res;                         /* xtalk_piomap_addr succeeded */
240 }
241
242 /* =====================================================================
243  *            EARLY PIOTRANS SUPPORT
244  *
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.
252  *
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.
258  */
259
260 static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
261
262 xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
263
264 /* xtalk_set_early_piotrans_addr:
265  * specify the early_piotrans_addr implementation function.
266  */
267 void
268 xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
269 {
270     impl_early_piotrans_addr = impl;
271 }
272
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.
281  */
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)
289 {
290     return impl_early_piotrans_addr
291         (part_num, mfg_num, which, xtalk_addr, byte_count, flags);
292 }
293
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.
300  */
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)
309 {
310 #if DEBUG
311     panic("null_xtalk_early_piotrans_addr");
312 #endif
313     return NULL;
314 }
315
316 /* =====================================================================
317  *                    DMA MANAGEMENT
318  *
319  *      For mapping from io channel space to system
320  *      physical space.
321  */
322
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);
331 }
332
333
334 void
335 xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
336 {
337     DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
338         (CAST_DMAMAP(xtalk_dmamap));
339 }
340
341
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);
349 }
350
351
352 void
353 xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
354 {
355     DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
356         (CAST_DMAMAP(xtalk_dmamap));
357 }
358
359
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);
369 }
370
371
372 void
373 xtalk_dmamap_drain(xtalk_dmamap_t map)
374 {
375     DMAMAP_FUNC(map, dmamap_drain)
376         (CAST_DMAMAP(map));
377 }
378
379 void
380 xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
381 {
382     DEV_FUNC(dev, dmaaddr_drain)
383         (dev, addr, size);
384 }
385
386 /* =====================================================================
387  *                    INTERRUPT MANAGEMENT
388  *
389  *      Allow io channel devices to establish interrupts
390  */
391
392 /*
393  * Allocate resources required for an interrupt as specified in intr_desc.
394  * Return resource handle in intr_hdl.
395  */
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);
403 }
404
405 /*
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.
409  */
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 */
414 {
415     return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
416         (dev, dev_desc, owner_dev);
417 }
418
419 /*
420  * Free resources consumed by intr_alloc.
421  */
422 void
423 xtalk_intr_free(xtalk_intr_t intr_hdl)
424 {
425     INTR_FUNC(intr_hdl, intr_free)
426         (CAST_INTR(intr_hdl));
427 }
428
429
430 /*
431  * Associate resources allocated with a previous xtalk_intr_alloc call with the
432  * described handler, arg, name, etc.
433  *
434  * Returns 0 on success, returns <0 on failure.
435  */
436 int
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 */
442 {
443     return INTR_FUNC(intr_hdl, intr_connect)
444         (CAST_INTR(intr_hdl), intr_func, intr_arg, setfunc, setfunc_arg);
445 }
446
447
448 /*
449  * Disassociate handler with the specified interrupt.
450  */
451 void
452 xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
453 {
454     INTR_FUNC(intr_hdl, intr_disconnect)
455         (CAST_INTR(intr_hdl));
456 }
457
458
459 /*
460  * Return a hwgraph vertex that represents the CPU currently
461  * targeted by an interrupt.
462  */
463 vertex_hdl_t
464 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
465 {
466       return (vertex_hdl_t)0;
467 }
468
469
470 /*
471  * =====================================================================
472  *                      ERROR MANAGEMENT
473  */
474
475 /*
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.
480  *
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.
487  *
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.
493  */
494 int
495 xtalk_error_handler(
496                        vertex_hdl_t xconn,
497                        int error_code,
498                        ioerror_mode_t mode,
499                        ioerror_t *ioerror)
500 {
501     xwidget_info_t          xwidget_info;
502     char                    name[MAXDEVNAME];
503
504
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. 
508      */
509     if (xwidget_info && xwidget_info->w_efunc)
510         return xwidget_info->w_efunc
511             (xwidget_info->w_einfo,
512              error_code, mode, ioerror);
513     /*
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.
519      */
520     if ((mode == MODE_DEVPROBE) || (mode == MODE_DEVUSERERROR) ||
521         (mode == MODE_DEVREENABLE))
522         return IOERROR_HANDLED;
523
524     printk(KERN_WARNING "Xbow at %s encountered Fatal error", vertex_to_name(xconn, name, MAXDEVNAME));
525
526     return IOERROR_UNHANDLED;
527 }
528
529
530 /* =====================================================================
531  *                    CONFIGURATION MANAGEMENT
532  */
533
534 /*
535  * Startup an io channel provider
536  */
537 void
538 xtalk_provider_startup(vertex_hdl_t xtalk_provider)
539 {
540     ((xtalk_provider_t *) hwgraph_fastinfo_get(xtalk_provider))->provider_startup(xtalk_provider);
541 }
542
543
544 /*
545  * Shutdown an io channel provider
546  */
547 void
548 xtalk_provider_shutdown(vertex_hdl_t xtalk_provider)
549 {
550     ((xtalk_provider_t *) hwgraph_fastinfo_get(xtalk_provider))->provider_shutdown(xtalk_provider);
551 }
552
553 /* 
554  * Enable a device on a xtalk widget 
555  */
556 void
557 xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum)
558 {
559         return;
560 }
561
562 /* 
563  * Shutdown a device on a xtalk widget 
564  */
565 void
566 xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum)
567 {
568         return;
569 }
570
571 /*
572  * Generic io channel functions, for use with all io channel providers
573  * and all io channel devices.
574  */
575
576 /* Generic io channel interrupt interfaces */
577 vertex_hdl_t
578 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
579 {
580     return (xtalk_intr->xi_dev);
581 }
582
583 xwidgetnum_t
584 xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
585 {
586     return (xtalk_intr->xi_target);
587 }
588
589 xtalk_intr_vector_t
590 xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
591 {
592     return (xtalk_intr->xi_vector);
593 }
594
595 iopaddr_t
596 xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
597 {
598     return (xtalk_intr->xi_addr);
599 }
600
601 void                   *
602 xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
603 {
604     return (xtalk_intr->xi_sfarg);
605 }
606
607 /* Generic io channel pio interfaces */
608 vertex_hdl_t
609 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
610 {
611     return (xtalk_piomap->xp_dev);
612 }
613
614 xwidgetnum_t
615 xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
616 {
617     return (xtalk_piomap->xp_target);
618 }
619
620 iopaddr_t
621 xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
622 {
623     return (xtalk_piomap->xp_xtalk_addr);
624 }
625
626 ulong
627 xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
628 {
629     return (xtalk_piomap->xp_mapsz);
630 }
631
632 caddr_t
633 xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
634 {
635     return (xtalk_piomap->xp_kvaddr);
636 }
637
638
639 /* Generic io channel dma interfaces */
640 vertex_hdl_t
641 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
642 {
643     return (xtalk_dmamap->xd_dev);
644 }
645
646 xwidgetnum_t
647 xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
648 {
649     return (xtalk_dmamap->xd_target);
650 }
651
652
653 /* Generic io channel widget information interfaces */
654
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.
659  */
660 xwidget_info_t
661 xwidget_info_chk(vertex_hdl_t xwidget)
662 {
663     arbitrary_info_t        ainfo = 0;
664
665     hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
666     return (xwidget_info_t) ainfo;
667 }
668
669
670 xwidget_info_t
671 xwidget_info_get(vertex_hdl_t xwidget)
672 {
673     xwidget_info_t          widget_info;
674
675     widget_info = (xwidget_info_t)
676         hwgraph_fastinfo_get(xwidget);
677
678     return (widget_info);
679 }
680
681 void
682 xwidget_info_set(vertex_hdl_t xwidget, xwidget_info_t widget_info)
683 {
684     if (widget_info != NULL)
685         widget_info->w_fingerprint = widget_info_fingerprint;
686
687     hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
688
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).
692      */
693     hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
694                          (arbitrary_info_t) widget_info);
695 }
696
697 vertex_hdl_t
698 xwidget_info_dev_get(xwidget_info_t xwidget_info)
699 {
700     if (xwidget_info == NULL)
701         panic("xwidget_info_dev_get: null xwidget_info");
702     return (xwidget_info->w_vertex);
703 }
704
705 xwidgetnum_t
706 xwidget_info_id_get(xwidget_info_t xwidget_info)
707 {
708     if (xwidget_info == NULL)
709         panic("xwidget_info_id_get: null xwidget_info");
710     return (xwidget_info->w_id);
711 }
712
713
714 vertex_hdl_t
715 xwidget_info_master_get(xwidget_info_t xwidget_info)
716 {
717     if (xwidget_info == NULL)
718         panic("xwidget_info_master_get: null xwidget_info");
719     return (xwidget_info->w_master);
720 }
721
722 xwidgetnum_t
723 xwidget_info_masterid_get(xwidget_info_t xwidget_info)
724 {
725     if (xwidget_info == NULL)
726         panic("xwidget_info_masterid_get: null xwidget_info");
727     return (xwidget_info->w_masterid);
728 }
729
730 xwidget_part_num_t
731 xwidget_info_part_num_get(xwidget_info_t xwidget_info)
732 {
733     if (xwidget_info == NULL)
734         panic("xwidget_info_part_num_get: null xwidget_info");
735     return (xwidget_info->w_hwid.part_num);
736 }
737
738 xwidget_mfg_num_t
739 xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
740 {
741     if (xwidget_info == NULL)
742         panic("xwidget_info_mfg_num_get: null xwidget_info");
743     return (xwidget_info->w_hwid.mfg_num);
744 }
745 /* Extract the widget name from the widget information
746  * for the xtalk widget.
747  */
748 char *
749 xwidget_info_name_get(xwidget_info_t xwidget_info)
750 {
751     if (xwidget_info == NULL)
752         panic("xwidget_info_name_get: null xwidget_info");
753     return(xwidget_info->w_name);
754 }
755 /* Generic io channel initialization interfaces */
756
757 /*
758  * Associate a set of xtalk_provider functions with a vertex.
759  */
760 void
761 xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns)
762 {
763     hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
764 }
765
766 /*
767  * Disassociate a set of xtalk_provider functions with a vertex.
768  */
769 void
770 xtalk_provider_unregister(vertex_hdl_t provider)
771 {
772     hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
773 }
774
775 /*
776  * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
777  * provider.
778  */
779 xtalk_provider_t       *
780 xtalk_provider_fns_get(vertex_hdl_t provider)
781 {
782     return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
783 }
784
785 /*
786  * Inform xtalk infrastructure that a driver is no longer available for
787  * handling any widgets.
788  */
789 void
790 xwidget_driver_unregister(char *driver_prefix)
791 {
792         return;
793 }
794
795 /*
796  * Call some function with each vertex that
797  * might be one of this driver's attach points.
798  */
799 void
800 xtalk_iterate(char *driver_prefix,
801               xtalk_iter_f *func)
802 {
803 }
804
805 /*
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.
812  *
813  */
814 int
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) */
820 {                       
821     xwidget_info_t          widget_info;
822     char                    *s,devnm[MAXDEVNAME];
823
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;
828
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;
837     /*
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.
841      */
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);
845     
846     xwidget_info_set(widget, widget_info);
847
848     device_master_set(widget, master);
849
850     /* 
851      * Add pointer to async attach info -- tear down will be done when
852      * the particular descendant is done with the info.
853      */
854     return cdl_add_connpt(hwid->part_num, hwid->mfg_num,
855                           widget, 0);
856 }
857
858 /*
859  * xwidget_unregister :
860  *      Unregister the xtalk device and detach all its hwgraph namespace.
861  */
862 int
863 xwidget_unregister(vertex_hdl_t widget)
864 {
865     xwidget_info_t      widget_info;
866     xwidget_hwid_t      hwid;
867
868     /* Make sure that we have valid widget information initialized */
869     if (!(widget_info = xwidget_info_get(widget)))
870         return 1;
871
872     hwid = &(widget_info->w_hwid);
873
874     kfree(widget_info->w_name);
875     kfree(widget_info);
876     return 0;
877 }
878
879 void
880 xwidget_error_register(vertex_hdl_t xwidget,
881                        error_handler_f *efunc,
882                        error_handler_arg_t einfo)
883 {
884     xwidget_info_t          xwidget_info;
885
886     xwidget_info = xwidget_info_get(xwidget);
887     ASSERT(xwidget_info != NULL);
888     xwidget_info->w_efunc = efunc;
889     xwidget_info->w_einfo = einfo;
890 }
891
892 /*
893  * Issue a link reset to a widget.
894  */
895 void
896 xwidget_reset(vertex_hdl_t xwidget)
897 {
898     xswitch_reset_link(xwidget);
899 }
900
901
902 void
903 xwidget_gfx_reset(vertex_hdl_t xwidget)
904 {
905         return;
906 }
907
908 #define ANON_XWIDGET_NAME       "No Name"       /* Default Widget Name */
909
910 /* Get the canonical hwgraph  name of xtalk widget */
911 char *
912 xwidget_name_get(vertex_hdl_t xwidget_vhdl)
913 {
914         xwidget_info_t  info;
915
916         /* If we have a bogus widget handle then return
917          * a default anonymous widget name.
918          */
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.
923          */
924         info = xwidget_info_get(xwidget_vhdl);
925         ASSERT(info != NULL);
926         return(xwidget_info_name_get(info));
927 }