ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / arch / ia64 / sn / io / sn2 / xbow.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/slab.h>
10 #include <linux/module.h>
11 #include <linux/interrupt.h>
12 #include <linux/mm.h>
13 #include <linux/delay.h>
14 #include <asm/sn/sgi.h>
15 #include <asm/sn/sn2/sn_private.h>
16 #include <asm/sn/iograph.h>
17 #include <asm/sn/simulator.h>
18 #include <asm/sn/hcl.h>
19 #include <asm/sn/hcl_util.h>
20 #include <asm/sn/pci/pcibr_private.h>
21
22 /* #define DEBUG                1 */
23 /* #define XBOW_DEBUG   1 */
24
25 #define kdebug 0
26
27
28 /*
29  * This file supports the Xbow chip.  Main functions: initializtion,
30  * error handling.
31  */
32
33 /*
34  * each vertex corresponding to an xbow chip
35  * has a "fastinfo" pointer pointing at one
36  * of these things.
37  */
38
39 struct xbow_soft_s {
40     vertex_hdl_t            conn;       /* our connection point */
41     vertex_hdl_t            vhdl;       /* xbow's private vertex */
42     vertex_hdl_t            busv;       /* the xswitch vertex */
43     xbow_t                 *base;       /* PIO pointer to crossbow chip */
44     char                   *name;       /* hwgraph name */
45
46     xbow_link_status_t      xbow_link_status[MAX_XBOW_PORTS];
47     widget_cfg_t           *wpio[MAX_XBOW_PORTS];       /* cached PIO pointer */
48
49     /* Bandwidth allocation state. Bandwidth values are for the
50      * destination port since contention happens there.
51      * Implicit mapping from xbow ports (8..f) -> (0..7) array indices.
52      */
53     unsigned long long      bw_hiwm[MAX_XBOW_PORTS];    /* hiwater mark values */
54     unsigned long long      bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */
55 };
56
57 #define xbow_soft_set(v,i)      hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))
58 #define xbow_soft_get(v)        ((struct xbow_soft_s *)hwgraph_fastinfo_get((v)))
59
60 /*
61  * Function Table of Contents
62  */
63
64 int                     xbow_attach(vertex_hdl_t);
65
66 int                     xbow_widget_present(xbow_t *, int);
67 static int              xbow_link_alive(xbow_t *, int);
68 vertex_hdl_t            xbow_widget_lookup(vertex_hdl_t, int);
69
70 void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
71 static void             xbow_setwidint(xtalk_intr_t);
72
73 xswitch_reset_link_f    xbow_reset_link;
74
75 xswitch_provider_t      xbow_provider =
76 {
77     xbow_reset_link,
78 };
79
80
81 static int
82 xbow_mmap(struct file * file, struct vm_area_struct * vma)
83 {
84         unsigned long           phys_addr;
85         int                     error;
86
87         phys_addr = (unsigned long)file->private_data & ~0xc000000000000000; /* Mask out the Uncache bits */
88         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
89         vma->vm_flags |= VM_RESERVED | VM_IO;
90         error = io_remap_page_range(vma, vma->vm_start, phys_addr,
91                                    vma->vm_end-vma->vm_start,
92                                    vma->vm_page_prot);
93         return(error);
94 }
95
96 /*
97  * This is the file operation table for the pcibr driver.
98  * As each of the functions are implemented, put the
99  * appropriate function name below.
100  */
101 struct file_operations xbow_fops = {
102         .owner          = THIS_MODULE,
103         .mmap           = xbow_mmap,
104 };
105
106 #ifdef XBRIDGE_REGS_SIM
107 /*    xbow_set_simulated_regs: sets xbow regs as needed
108  *      for powering through the boot
109  */
110 void
111 xbow_set_simulated_regs(xbow_t *xbow, int port)
112 {
113     /*
114      * turn on link
115      */
116     xbow->xb_link(port).link_status = (1<<31);
117     /*
118      * and give it a live widget too
119      */
120     xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT;
121     /*
122      * zero the link control reg
123      */
124     xbow->xb_link(port).link_control = 0x0;
125 }
126 #endif /* XBRIDGE_REGS_SIM */
127
128 /*
129  *    xbow_attach: the crosstalk provider has
130  *      determined that there is a crossbow widget
131  *      present, and has handed us the connection
132  *      point for that vertex.
133  *
134  *      We not only add our own vertex, but add
135  *      some "xtalk switch" data to the switch
136  *      vertex (at the connect point's parent) if
137  *      it does not have any.
138  */
139
140 /*ARGSUSED */
141 int
142 xbow_attach(vertex_hdl_t conn)
143 {
144     /*REFERENCED */
145     vertex_hdl_t            vhdl;
146     vertex_hdl_t            busv;
147     xbow_t                  *xbow;
148     struct xbow_soft_s      *soft;
149     int                     port;
150     xswitch_info_t          info;
151     xtalk_intr_t            intr_hdl;
152     char                    devnm[MAXDEVNAME], *s;
153     xbowreg_t               id;
154     int                     rev;
155     int                     i;
156     int                     xbow_num;
157 #if DEBUG && ATTACH_DEBUG
158     char                    name[MAXDEVNAME];
159 #endif
160     static irqreturn_t xbow_errintr_handler(int, void *, struct pt_regs *);
161
162         
163 #if DEBUG && ATTACH_DEBUG
164     printk("%s: xbow_attach\n", vertex_to_name(conn, name, MAXDEVNAME));
165 #endif
166
167     /*
168      * Get a PIO pointer to the base of the crossbow
169      * chip.
170      */
171 #ifdef XBRIDGE_REGS_SIM
172     printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t));
173     xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL);
174     if (!xbow)
175             return -ENOMEM;
176     /*
177      * turn on ports e and f like in a real live ibrick
178      */
179     xbow_set_simulated_regs(xbow, 0xe);
180     xbow_set_simulated_regs(xbow, 0xf);
181 #else
182     xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0);
183 #endif /* XBRIDGE_REGS_SIM */
184
185     /*
186      * Locate the "switch" vertex: it is the parent
187      * of our connection point.
188      */
189     busv = hwgraph_connectpt_get(conn);
190 #if DEBUG && ATTACH_DEBUG
191     printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow);
192 #endif
193
194     ASSERT(busv != GRAPH_VERTEX_NONE);
195
196     /*
197      * Create our private vertex, and connect our
198      * driver information to it. This makes it possible
199      * for diagnostic drivers to open the crossbow
200      * vertex for access to registers.
201      */
202
203     /*
204      * Register a xbow driver with hwgraph.
205      * file ops.
206      */
207     vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0,
208            0, 0, 0,
209            S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
210            (struct file_operations *)&xbow_fops, (void *)xbow);
211     if (!vhdl) {
212         printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
213                 (void *)conn);
214     }
215
216     /*
217      * Allocate the soft state structure and attach
218      * it to the xbow's vertex
219      */
220     soft = kmalloc(sizeof(*soft), GFP_KERNEL);
221     if (!soft)
222             return -ENOMEM;
223     soft->conn = conn;
224     soft->vhdl = vhdl;
225     soft->busv = busv;
226     soft->base = xbow;
227     /* does the universe really need another macro?  */
228     /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
229     /* hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft); */
230
231 #define XBOW_NUM_SUFFIX_FORMAT  "[xbow# %d]"
232
233     /* Add xbow number as a suffix to the hwgraph name of the xbow.
234      * This is helpful while looking at the error/warning messages.
235      */
236     xbow_num = 0;
237
238     /*
239      * get the name of this xbow vertex and keep the info.
240      * This is needed during errors and interupts, but as
241      * long as we have it, we can use it elsewhere.
242      */
243     s = dev_to_name(vhdl, devnm, MAXDEVNAME);
244     soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, 
245                             GFP_KERNEL);
246     if (!soft->name) {
247             kfree(soft);
248             return -ENOMEM;
249     }
250     sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num);
251
252 #ifdef XBRIDGE_REGS_SIM
253     /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined
254      * as 0xd000, so I'm using that for the partnum bitfield.
255      */
256     printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n");
257     id = 0x2d000049;
258 #else
259     id = xbow->xb_wid_id;
260 #endif /* XBRIDGE_REGS_SIM */
261     rev = XWIDGET_PART_REV_NUM(id);
262
263 #define XBOW_16_BIT_PORT_BW_MAX         (800 * 1000 * 1000)     /* 800 MB/s */
264
265     /* Set bandwidth hiwatermark and current values */
266     for (i = 0; i < MAX_XBOW_PORTS; i++) {
267         soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX;     /* for now */
268         soft->bw_cur_used[i] = 0;
269     }
270
271      /*
272       * attach the crossbow error interrupt.
273       */
274      intr_hdl = xtalk_intr_alloc(conn, (device_desc_t)0, vhdl);
275      ASSERT(intr_hdl != NULL);
276
277         {
278                 int irq = ((hub_intr_t)intr_hdl)->i_bit;
279                 int cpu = ((hub_intr_t)intr_hdl)->i_cpuid;
280
281                 intr_unreserve_level(cpu, irq);
282                 ((hub_intr_t)intr_hdl)->i_bit = SGI_XBOW_ERROR;
283         }
284  
285      xtalk_intr_connect(intr_hdl,
286                         (intr_func_t) xbow_errintr_handler,
287                         (intr_arg_t) soft,
288                         (xtalk_intr_setfunc_t) xbow_setwidint,
289                         (void *) xbow);
290
291      request_irq(SGI_XBOW_ERROR, (void *)xbow_errintr_handler, SA_SHIRQ, "XBOW error",
292                         (intr_arg_t) soft);
293
294  
295     /*
296      * Enable xbow error interrupts
297      */
298     xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE);
299
300     /*
301      * take a census of the widgets present,
302      * leaving notes at the switch vertex.
303      */
304     info = xswitch_info_new(busv);
305
306     for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
307          port < MAX_PORT_NUM; ++port) {
308         if (!xbow_link_alive(xbow, port)) {
309 #if DEBUG && XBOW_DEBUG
310             printk(KERN_INFO "0x%p link %d is not alive\n",
311                     (void *)busv, port);
312 #endif
313             continue;
314         }
315         if (!xbow_widget_present(xbow, port)) {
316 #if DEBUG && XBOW_DEBUG
317             printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", (void *)busv, port);
318 #endif
319             continue;
320         }
321 #if DEBUG && XBOW_DEBUG
322         printk(KERN_INFO "0x%p link %d has a widget\n",
323                 (void *)busv, port);
324 #endif
325
326         xswitch_info_link_is_ok(info, port);
327         /*
328          * Turn some error interrupts on
329          * and turn others off. The PROM has
330          * some things turned on we don't
331          * want to see (bandwidth allocation
332          * errors for instance); so if it
333          * is not listed here, it is not on.
334          */
335         xbow->xb_link(port).link_control =
336             ( (xbow->xb_link(port).link_control
337         /*
338          * Turn off these bits; they are non-fatal,
339          * but we might want to save some statistics
340          * on the frequency of these errors.
341          * XXX FIXME XXX
342          */
343             & ~XB_CTRL_RCV_CNT_OFLOW_IE
344             & ~XB_CTRL_XMT_CNT_OFLOW_IE
345             & ~XB_CTRL_BNDWDTH_ALLOC_IE
346             & ~XB_CTRL_RCV_IE)
347         /*
348          * These are the ones we want to turn on.
349          */
350             | (XB_CTRL_ILLEGAL_DST_IE
351             | XB_CTRL_OALLOC_IBUF_IE
352             | XB_CTRL_XMT_MAX_RTRY_IE
353             | XB_CTRL_MAXREQ_TOUT_IE
354             | XB_CTRL_XMT_RTRY_IE
355             | XB_CTRL_SRC_TOUT_IE) );
356     }
357
358     xswitch_provider_register(busv, &xbow_provider);
359
360     return 0;                           /* attach successful */
361 }
362
363 /*
364  * xbow_widget_present: See if a device is present
365  * on the specified port of this crossbow.
366  */
367 int
368 xbow_widget_present(xbow_t *xbow, int port)
369 {
370         if ( IS_RUNNING_ON_SIMULATOR() ) {
371                 if ( (port == 14) || (port == 15) ) {
372                         return 1;
373                 }
374                 else {
375                         return 0;
376                 }
377         }
378         else {
379                 /* WAR: port 0xf on PIC is missing present bit */
380                 if (XBOW_WAR_ENABLED(PV854827, xbow->xb_wid_id) &&
381                                         IS_PIC_XBOW(xbow->xb_wid_id) && port==0xf) {
382                         return 1;
383                 }
384                 else if ( IS_PIC_XBOW(xbow->xb_wid_id) && port==0xb ) {
385                         /* for opus the present bit doesn't work on port 0xb */
386                         return 1;
387                 }
388                 return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;
389         }
390 }
391
392 static int
393 xbow_link_alive(xbow_t * xbow, int port)
394 {
395     xbwX_stat_t             xbow_linkstat;
396
397     xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;
398     return (xbow_linkstat.link_alive);
399 }
400
401 /*
402  * xbow_widget_lookup
403  *      Lookup the edges connected to the xbow specified, and
404  *      retrieve the handle corresponding to the widgetnum
405  *      specified.
406  *      If not found, return 0.
407  */
408 vertex_hdl_t
409 xbow_widget_lookup(vertex_hdl_t vhdl,
410                    int widgetnum)
411 {
412     xswitch_info_t          xswitch_info;
413     vertex_hdl_t            conn;
414
415     xswitch_info = xswitch_info_get(vhdl);
416     conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
417     return conn;
418 }
419
420 /*
421  * xbow_setwidint: called when xtalk
422  * is establishing or migrating our
423  * interrupt service.
424  */
425 static void
426 xbow_setwidint(xtalk_intr_t intr)
427 {
428     xwidgetnum_t            targ = xtalk_intr_target_get(intr);
429     iopaddr_t               addr = xtalk_intr_addr_get(intr);
430     xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
431     xbow_t                 *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr);
432
433     xbow_intr_preset((void *) xbow, 0, targ, addr, vect);
434 }
435
436 /*
437  * xbow_intr_preset: called during mlreset time
438  * if the platform specific code needs to route
439  * an xbow interrupt before the xtalk infrastructure
440  * is available for use.
441  *
442  * Also called from xbow_setwidint, so we don't
443  * replicate the guts of the routine.
444  *
445  * XXX- probably should be renamed xbow_wid_intr_set or
446  * something to reduce confusion.
447  */
448 /*ARGSUSED3 */
449 void
450 xbow_intr_preset(void *which_widget,
451                  int which_widget_intr,
452                  xwidgetnum_t targ,
453                  iopaddr_t addr,
454                  xtalk_intr_vector_t vect)
455 {
456     xbow_t                 *xbow = (xbow_t *) which_widget;
457
458     xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |
459                               (0x000F0000 & (targ << 16)) |
460                               XTALK_ADDR_TO_UPPER(addr));
461     xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
462
463 }
464
465 #define XEM_ADD_STR(s)          printk("%s", (s))
466 #define XEM_ADD_NVAR(n,v)       printk("\t%20s: 0x%llx\n", (n), ((unsigned long long)v))
467 #define XEM_ADD_VAR(v)          XEM_ADD_NVAR(#v,(v))
468 #define XEM_ADD_IOEF(p,n)       if (IOERROR_FIELDVALID(ioe,n)) {        \
469                                     IOERROR_GETVALUE(p,ioe,n);          \
470                                     XEM_ADD_NVAR("ioe." #n, p);         \
471                                 }
472
473 int
474 xbow_xmit_retry_error(struct xbow_soft_s *soft,
475                       int port)
476 {
477     xswitch_info_t          info;
478     vertex_hdl_t            vhdl;
479     widget_cfg_t           *wid;
480     widgetreg_t             id;
481     int                     part;
482     int                     mfgr;
483
484     wid = soft->wpio[port - BASE_XBOW_PORT];
485     if (wid == NULL) {
486         /* If we can't track down a PIO
487          * pointer to our widget yet,
488          * leave our caller knowing that
489          * we are interested in this
490          * interrupt if it occurs in
491          * the future.
492          */
493         info = xswitch_info_get(soft->busv);
494         if (!info)
495             return 1;
496         vhdl = xswitch_info_vhdl_get(info, port);
497         if (vhdl == GRAPH_VERTEX_NONE)
498             return 1;
499         wid = (widget_cfg_t *) xtalk_piotrans_addr
500             (vhdl, 0, 0, sizeof *wid, 0);
501         if (!wid)
502             return 1;
503         soft->wpio[port - BASE_XBOW_PORT] = wid;
504     }
505     id = wid->w_id;
506     part = XWIDGET_PART_NUM(id);
507     mfgr = XWIDGET_MFG_NUM(id);
508
509     return 0;
510 }
511
512 /*
513  * xbow_errintr_handler will be called if the xbow
514  * sends an interrupt request to report an error.
515  */
516 static irqreturn_t
517 xbow_errintr_handler(int irq, void *arg, struct pt_regs *ep)
518 {
519     ioerror_t               ioe[1];
520     struct xbow_soft_s     *soft = (struct xbow_soft_s *)arg;
521     xbow_t                 *xbow = soft->base;
522     xbowreg_t               wid_control;
523     xbowreg_t               wid_stat;
524     xbowreg_t               wid_err_cmdword;
525     xbowreg_t               wid_err_upper;
526     xbowreg_t               wid_err_lower;
527     w_err_cmd_word_u        wid_err;
528     unsigned long long      wid_err_addr;
529
530     int                     fatal = 0;
531     int                     dump_ioe = 0;
532     static int xbow_error_handler(void *, int, ioerror_mode_t, ioerror_t *);
533
534     wid_control = xbow->xb_wid_control;
535     wid_stat = xbow->xb_wid_stat_clr;
536     wid_err_cmdword = xbow->xb_wid_err_cmdword;
537     wid_err_upper = xbow->xb_wid_err_upper;
538     wid_err_lower = xbow->xb_wid_err_lower;
539     xbow->xb_wid_err_cmdword = 0;
540
541     wid_err_addr = wid_err_lower | (((iopaddr_t) wid_err_upper & WIDGET_ERR_UPPER_ADDR_ONLY) << 32);
542
543     if (wid_stat & XB_WID_STAT_LINK_INTR_MASK) {
544         int                     port;
545
546         wid_err.r = wid_err_cmdword;
547
548         for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
549              port < MAX_PORT_NUM; port++) {
550             if (wid_stat & XB_WID_STAT_LINK_INTR(port)) {
551                 xb_linkregs_t          *link = &(xbow->xb_link(port));
552                 xbowreg_t               link_control = link->link_control;
553                 xbowreg_t               link_status = link->link_status_clr;
554                 xbowreg_t               link_aux_status = link->link_aux_status;
555                 xbowreg_t               link_pend;
556
557                 link_pend = link_status & link_control &
558                     (XB_STAT_ILLEGAL_DST_ERR
559                      | XB_STAT_OALLOC_IBUF_ERR
560                      | XB_STAT_RCV_CNT_OFLOW_ERR
561                      | XB_STAT_XMT_CNT_OFLOW_ERR
562                      | XB_STAT_XMT_MAX_RTRY_ERR
563                      | XB_STAT_RCV_ERR
564                      | XB_STAT_XMT_RTRY_ERR
565                      | XB_STAT_MAXREQ_TOUT_ERR
566                      | XB_STAT_SRC_TOUT_ERR
567                     );
568
569                 if (link_pend & XB_STAT_ILLEGAL_DST_ERR) {
570                     if (wid_err.f.sidn == port) {
571                         IOERROR_INIT(ioe);
572                         IOERROR_SETVALUE(ioe, widgetnum, port);
573                         IOERROR_SETVALUE(ioe, xtalkaddr, wid_err_addr);
574                         if (IOERROR_HANDLED ==
575                             xbow_error_handler(soft,
576                                                IOECODE_DMA,
577                                                MODE_DEVERROR,
578                                                ioe)) {
579                             link_pend &= ~XB_STAT_ILLEGAL_DST_ERR;
580                         } else {
581                             dump_ioe++;
582                         }
583                     }
584                 }
585                 /* Xbow/Bridge WAR:
586                  * if the bridge signals an LLP Transmitter Retry,
587                  * rewrite its control register.
588                  * If someone else triggers this interrupt,
589                  * ignore (and disable) the interrupt.
590                  */
591                 if (link_pend & XB_STAT_XMT_RTRY_ERR) {
592                     if (!xbow_xmit_retry_error(soft, port)) {
593                         link_control &= ~XB_CTRL_XMT_RTRY_IE;
594                         link->link_control = link_control;
595                         link->link_control;     /* stall until written */
596                     }
597                     link_pend &= ~XB_STAT_XMT_RTRY_ERR;
598                 }
599                 if (link_pend) {
600                     vertex_hdl_t        xwidget_vhdl;
601                     char                *xwidget_name;
602                     
603                     /* Get the widget name corresponding to the current
604                      * xbow link.
605                      */
606                     xwidget_vhdl = xbow_widget_lookup(soft->busv,port);
607                     xwidget_name = xwidget_name_get(xwidget_vhdl);
608
609                     printk("%s port %X[%s] XIO Bus Error",
610                             soft->name, port, xwidget_name);
611                     if (link_status & XB_STAT_MULTI_ERR)
612                         XEM_ADD_STR("\tMultiple Errors\n");
613                     if (link_status & XB_STAT_ILLEGAL_DST_ERR)
614                         XEM_ADD_STR("\tInvalid Packet Destination\n");
615                     if (link_status & XB_STAT_OALLOC_IBUF_ERR)
616                         XEM_ADD_STR("\tInput Overallocation Error\n");
617                     if (link_status & XB_STAT_RCV_CNT_OFLOW_ERR)
618                         XEM_ADD_STR("\tLLP receive error counter overflow\n");
619                     if (link_status & XB_STAT_XMT_CNT_OFLOW_ERR)
620                         XEM_ADD_STR("\tLLP transmit retry counter overflow\n");
621                     if (link_status & XB_STAT_XMT_MAX_RTRY_ERR)
622                         XEM_ADD_STR("\tLLP Max Transmitter Retry\n");
623                     if (link_status & XB_STAT_RCV_ERR)
624                         XEM_ADD_STR("\tLLP Receiver error\n");
625                     if (link_status & XB_STAT_XMT_RTRY_ERR)
626                         XEM_ADD_STR("\tLLP Transmitter Retry\n");
627                     if (link_status & XB_STAT_MAXREQ_TOUT_ERR)
628                         XEM_ADD_STR("\tMaximum Request Timeout\n");
629                     if (link_status & XB_STAT_SRC_TOUT_ERR)
630                         XEM_ADD_STR("\tSource Timeout Error\n");
631
632                     {
633                         int                     other_port;
634
635                         for (other_port = 8; other_port < 16; ++other_port) {
636                             if (link_aux_status & (1 << other_port)) {
637                                 /* XXX- need to go to "other_port"
638                                  * and clean up after the timeout?
639                                  */
640                                 XEM_ADD_VAR(other_port);
641                             }
642                         }
643                     }
644
645 #if !DEBUG
646                     if (kdebug) {
647 #endif
648                         XEM_ADD_VAR(link_control);
649                         XEM_ADD_VAR(link_status);
650                         XEM_ADD_VAR(link_aux_status);
651
652 #if !DEBUG
653                     }
654 #endif
655                     fatal++;
656                 }
657             }
658         }
659     }
660     if (wid_stat & wid_control & XB_WID_STAT_WIDGET0_INTR) {
661         /* we have a "widget zero" problem */
662
663         if (wid_stat & (XB_WID_STAT_MULTI_ERR
664                         | XB_WID_STAT_XTALK_ERR
665                         | XB_WID_STAT_REG_ACC_ERR)) {
666
667             printk("%s Port 0 XIO Bus Error",
668                     soft->name);
669             if (wid_stat & XB_WID_STAT_MULTI_ERR)
670                 XEM_ADD_STR("\tMultiple Error\n");
671             if (wid_stat & XB_WID_STAT_XTALK_ERR)
672                 XEM_ADD_STR("\tXIO Error\n");
673             if (wid_stat & XB_WID_STAT_REG_ACC_ERR)
674                 XEM_ADD_STR("\tRegister Access Error\n");
675
676             fatal++;
677         }
678     }
679     if (fatal) {
680         XEM_ADD_VAR(wid_stat);
681         XEM_ADD_VAR(wid_control);
682         XEM_ADD_VAR(wid_err_cmdword);
683         XEM_ADD_VAR(wid_err_upper);
684         XEM_ADD_VAR(wid_err_lower);
685         XEM_ADD_VAR(wid_err_addr);
686         panic("XIO Bus Error");
687     }
688     return IRQ_HANDLED;
689 }
690
691 /*
692  * XBOW ERROR Handling routines.
693  * These get invoked as part of walking down the error handling path
694  * from hub/heart towards the I/O device that caused the error.
695  */
696
697 /*
698  * xbow_error_handler
699  *      XBow error handling dispatch routine.
700  *      This is the primary interface used by external world to invoke
701  *      in case of an error related to a xbow.
702  *      Only functionality in this layer is to identify the widget handle
703  *      given the widgetnum. Otherwise, xbow does not gathers any error
704  *      data.
705  */
706 static int
707 xbow_error_handler(
708                       void *einfo,
709                       int error_code,
710                       ioerror_mode_t mode,
711                       ioerror_t *ioerror)
712 {
713     int                    retval = IOERROR_WIDGETLEVEL;
714
715     struct xbow_soft_s    *soft = (struct xbow_soft_s *) einfo;
716     int                   port;
717     vertex_hdl_t          conn;
718     vertex_hdl_t          busv;
719
720     xbow_t                 *xbow = soft->base;
721     xbowreg_t               wid_stat;
722     xbowreg_t               wid_err_cmdword;
723     xbowreg_t               wid_err_upper;
724     xbowreg_t               wid_err_lower;
725     unsigned long long      wid_err_addr;
726
727     xb_linkregs_t          *link;
728     xbowreg_t               link_control;
729     xbowreg_t               link_status;
730     xbowreg_t               link_aux_status;
731
732     ASSERT(soft != 0);
733     busv = soft->busv;
734
735 #if DEBUG && ERROR_DEBUG
736     printk("%s: xbow_error_handler\n", soft->name, busv);
737 #endif
738
739     IOERROR_GETVALUE(port, ioerror, widgetnum);
740
741     if (port == 0) {
742         /* error during access to xbow:
743          * do NOT attempt to access xbow regs.
744          */
745         if (mode == MODE_DEVPROBE)
746             return IOERROR_HANDLED;
747
748         if (error_code & IOECODE_DMA) {
749             printk(KERN_ALERT
750                     "DMA error blamed on Crossbow at %s\n"
751                     "\tbut Crosbow never initiates DMA!",
752                     soft->name);
753         }
754         if (error_code & IOECODE_PIO) {
755             iopaddr_t tmp;
756             IOERROR_GETVALUE(tmp, ioerror, xtalkaddr);
757             printk(KERN_ALERT "PIO Error on XIO Bus %s\n"
758                     "\tattempting to access XIO controller\n"
759                     "\twith offset 0x%lx",
760                     soft->name, tmp);
761         }
762         /* caller will dump contents of ioerror
763          * in DEBUG and kdebug kernels.
764          */
765
766         return retval;
767     }
768     /*
769      * error not on port zero:
770      * safe to read xbow registers.
771      */
772     wid_stat = xbow->xb_wid_stat;
773     wid_err_cmdword = xbow->xb_wid_err_cmdword;
774     wid_err_upper = xbow->xb_wid_err_upper;
775     wid_err_lower = xbow->xb_wid_err_lower;
776
777     wid_err_addr =
778         wid_err_lower
779         | (((iopaddr_t) wid_err_upper
780             & WIDGET_ERR_UPPER_ADDR_ONLY)
781            << 32);
782
783     if ((port < BASE_XBOW_PORT) ||
784         (port >= MAX_PORT_NUM)) {
785
786         if (mode == MODE_DEVPROBE)
787             return IOERROR_HANDLED;
788
789         if (error_code & IOECODE_DMA) {
790             printk(KERN_ALERT
791                     "DMA error blamed on XIO port at %s/%d\n"
792                     "\tbut Crossbow does not support that port",
793                     soft->name, port);
794         }
795         if (error_code & IOECODE_PIO) {
796             iopaddr_t tmp;
797             IOERROR_GETVALUE(tmp, ioerror, xtalkaddr);
798             printk(KERN_ALERT
799                     "PIO Error on XIO Bus %s\n"
800                     "\tattempting to access XIO port %d\n"
801                     "\t(which Crossbow does not support)"
802                     "\twith offset 0x%lx",
803                     soft->name, port, tmp);
804         }
805 #if !DEBUG
806         if (kdebug) {
807 #endif
808             XEM_ADD_STR("Raw status values for Crossbow:\n");
809             XEM_ADD_VAR(wid_stat);
810             XEM_ADD_VAR(wid_err_cmdword);
811             XEM_ADD_VAR(wid_err_upper);
812             XEM_ADD_VAR(wid_err_lower);
813             XEM_ADD_VAR(wid_err_addr);
814 #if !DEBUG
815         }
816 #endif
817
818         /* caller will dump contents of ioerror
819          * in DEBUG and kdebug kernels.
820          */
821
822         return retval;
823     }
824     /* access to valid port:
825      * ok to check port status.
826      */
827
828     link = &(xbow->xb_link(port));
829     link_control = link->link_control;
830     link_status = link->link_status;
831     link_aux_status = link->link_aux_status;
832
833     /* Check that there is something present
834      * in that XIO port.
835      */
836     /* WAR: PIC widget 0xf is missing prescense bit */
837     if (XBOW_WAR_ENABLED(PV854827, xbow->xb_wid_id) &&
838                 IS_PIC_XBOW(xbow->xb_wid_id) && (port==0xf))
839                 ;
840     else if (IS_PIC_XBOW(xbow->xb_wid_id) && (port==0xb))
841                 ;       /* WAR for opus this is missing on 0xb */
842     else if (!(link_aux_status & XB_AUX_STAT_PRESENT)) {
843         /* nobody connected. */
844         if (mode == MODE_DEVPROBE)
845             return IOERROR_HANDLED;
846
847         if (error_code & IOECODE_DMA) {
848             printk(KERN_ALERT
849                     "DMA error blamed on XIO port at %s/%d\n"
850                     "\tbut there is no device connected there.",
851                     soft->name, port);
852         }
853         if (error_code & IOECODE_PIO) {
854             iopaddr_t tmp;
855             IOERROR_GETVALUE(tmp, ioerror, xtalkaddr);
856             printk(KERN_ALERT
857                     "PIO Error on XIO Bus %s\n"
858                     "\tattempting to access XIO port %d\n"
859                     "\t(which has no device connected)"
860                     "\twith offset 0x%lx",
861                     soft->name, port, tmp);
862         }
863 #if !DEBUG
864         if (kdebug) {
865 #endif
866             XEM_ADD_STR("Raw status values for Crossbow:\n");
867             XEM_ADD_VAR(wid_stat);
868             XEM_ADD_VAR(wid_err_cmdword);
869             XEM_ADD_VAR(wid_err_upper);
870             XEM_ADD_VAR(wid_err_lower);
871             XEM_ADD_VAR(wid_err_addr);
872             XEM_ADD_VAR(port);
873             XEM_ADD_VAR(link_control);
874             XEM_ADD_VAR(link_status);
875             XEM_ADD_VAR(link_aux_status);
876 #if !DEBUG
877         }
878 #endif
879         return retval;
880
881     }
882     /* Check that the link is alive.
883      */
884     if (!(link_status & XB_STAT_LINKALIVE)) {
885         iopaddr_t tmp;
886         /* nobody connected. */
887         if (mode == MODE_DEVPROBE)
888             return IOERROR_HANDLED;
889
890         printk(KERN_ALERT
891                 "%s%sError on XIO Bus %s port %d",
892                 (error_code & IOECODE_DMA) ? "DMA " : "",
893                 (error_code & IOECODE_PIO) ? "PIO " : "",
894                 soft->name, port);
895
896         IOERROR_GETVALUE(tmp, ioerror, xtalkaddr);
897         if ((error_code & IOECODE_PIO) &&
898             (IOERROR_FIELDVALID(ioerror, xtalkaddr))) {
899                 printk("\tAccess attempted to offset 0x%lx\n", tmp);
900         }
901         if (link_aux_status & XB_AUX_LINKFAIL_RST_BAD)
902             XEM_ADD_STR("\tLink never came out of reset\n");
903         else
904             XEM_ADD_STR("\tLink failed while transferring data\n");
905
906     }
907     /* get the connection point for the widget
908      * involved in this error; if it exists and
909      * is not our connectpoint, cycle back through
910      * xtalk_error_handler to deliver control to
911      * the proper handler (or to report a generic
912      * crosstalk error).
913      *
914      * If the downstream handler won't handle
915      * the problem, we let our upstream caller
916      * deal with it, after (in DEBUG and kdebug
917      * kernels) dumping the xbow state for this
918      * port.
919      */
920     conn = xbow_widget_lookup(busv, port);
921     if ((conn != GRAPH_VERTEX_NONE) &&
922         (conn != soft->conn)) {
923         retval = xtalk_error_handler(conn, error_code, mode, ioerror);
924         if (retval == IOERROR_HANDLED)
925             return IOERROR_HANDLED;
926     }
927     if (mode == MODE_DEVPROBE)
928         return IOERROR_HANDLED;
929
930     if (retval == IOERROR_UNHANDLED) {
931         iopaddr_t tmp;
932         retval = IOERROR_PANIC;
933
934         printk(KERN_ALERT
935                 "%s%sError on XIO Bus %s port %d",
936                 (error_code & IOECODE_DMA) ? "DMA " : "",
937                 (error_code & IOECODE_PIO) ? "PIO " : "",
938                 soft->name, port);
939
940         IOERROR_GETVALUE(tmp, ioerror, xtalkaddr);
941         if ((error_code & IOECODE_PIO) &&
942             (IOERROR_FIELDVALID(ioerror, xtalkaddr))) {
943             printk("\tAccess attempted to offset 0x%lx\n", tmp);
944         }
945     }
946
947 #if !DEBUG
948     if (kdebug) {
949 #endif
950         XEM_ADD_STR("Raw status values for Crossbow:\n");
951         XEM_ADD_VAR(wid_stat);
952         XEM_ADD_VAR(wid_err_cmdword);
953         XEM_ADD_VAR(wid_err_upper);
954         XEM_ADD_VAR(wid_err_lower);
955         XEM_ADD_VAR(wid_err_addr);
956         XEM_ADD_VAR(port);
957         XEM_ADD_VAR(link_control);
958         XEM_ADD_VAR(link_status);
959         XEM_ADD_VAR(link_aux_status);
960 #if !DEBUG
961     }
962 #endif
963     /* caller will dump raw ioerror data
964      * in DEBUG and kdebug kernels.
965      */
966
967     return retval;
968 }
969
970 int
971 xbow_reset_link(vertex_hdl_t xconn_vhdl)
972 {
973     xwidget_info_t          widget_info;
974     xwidgetnum_t            port;
975     xbow_t                 *xbow;
976     xbowreg_t               ctrl;
977     xbwX_stat_t             stat;
978     unsigned                long itick;
979     unsigned int            dtick;
980     static long             ticks_to_wait = HZ / 1000;
981
982     widget_info = xwidget_info_get(xconn_vhdl);
983     port = xwidget_info_id_get(widget_info);
984
985 #ifdef XBOW_K1PTR                       /* defined if we only have one xbow ... */
986     xbow = XBOW_K1PTR;
987 #else
988     {
989         vertex_hdl_t            xbow_vhdl;
990         struct xbow_soft_s      *xbow_soft;
991
992         hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
993         xbow_soft = xbow_soft_get(xbow_vhdl);
994         xbow = xbow_soft->base;
995     }
996 #endif
997
998     /*
999      * This requires three PIOs (reset the link, check for the
1000      * reset, restore the control register for the link) plus
1001      * 10us to wait for the reset. We allow up to 1ms for the
1002      * widget to come out of reset before giving up and
1003      * returning a failure.
1004      */
1005     ctrl = xbow->xb_link(port).link_control;
1006     xbow->xb_link(port).link_reset = 0;
1007     itick = jiffies;
1008     while (1) {
1009         stat.linkstatus = xbow->xb_link(port).link_status;
1010         if (stat.link_alive)
1011             break;
1012         dtick = jiffies - itick;
1013         if (dtick > ticks_to_wait) {
1014             return -1;                  /* never came out of reset */
1015         }
1016         udelay(2);                      /* don't beat on link_status */
1017     }
1018     xbow->xb_link(port).link_control = ctrl;
1019     return 0;
1020 }