~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/ia64/sn/io/sn2/xtalk.c

Version: ~ [ linux-5.1-rc1 ] ~ [ linux-5.0.3 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.30 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.107 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.164 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.176 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.136 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.63 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp