* License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2007 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/module.h>
                     BTE_LNSTAT_LOAD(bte), *bte->most_rcnt_na));
 
        if (transfer_stat & IBLS_ERROR) {
-               bte_status = transfer_stat & ~IBLS_ERROR;
+               bte_status = BTE_GET_ERROR_STATUS(transfer_stat);
        } else {
                bte_status = BTE_SUCCESS;
        }
 
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2007 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/types.h>
        for (i = 0; i < BTES_PER_NODE; i++) {
                bte = &err_nodepda->bte_if[i];
                status = BTE_LNSTAT_LOAD(bte);
-               if ((status & IBLS_ERROR) || !(status & IBLS_BUSY))
+               if (status & IBLS_ERROR) {
+                       bte->bh_error = BTE_SHUB2_ERROR(status);
+                       continue;
+               }
+               if (!(status & IBLS_BUSY))
                        continue;
                mod_timer(recovery_timer, jiffies + (HZ * 5));
                BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
 
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2007 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
        BTEFAIL_NOTAVAIL,       /* BTE not available */
 } bte_result_t;
 
+#define BTEFAIL_SH2_RESP_SHORT 0x1     /* bit 000001 */
+#define BTEFAIL_SH2_RESP_LONG  0x2     /* bit 000010 */
+#define BTEFAIL_SH2_RESP_DSP   0x4     /* bit 000100 */
+#define BTEFAIL_SH2_RESP_ACCESS        0x8     /* bit 001000 */
+#define BTEFAIL_SH2_CRB_TO     0x10    /* bit 010000 */
+#define BTEFAIL_SH2_NACK_LIMIT 0x20    /* bit 100000 */
+#define BTEFAIL_SH2_ALL                0x3F    /* bit 111111 */
+
+#define        BTE_ERR_BITS    0x3FUL
+#define        BTE_ERR_SHIFT   36
+#define BTE_ERR_MASK   (BTE_ERR_BITS << BTE_ERR_SHIFT)
+
+#define BTE_ERROR_RETRY(value)                                         \
+       (is_shub2() ? (value != BTEFAIL_SH2_CRB_TO)                     \
+               : (value != BTEFAIL_TOUT))
+
+/*
+ * On shub1 BTE_ERR_MASK will always be false, so no need for is_shub2()
+ */
+#define BTE_SHUB2_ERROR(_status)                                       \
+       ((_status & BTE_ERR_MASK)                                       \
+          ? (((_status >> BTE_ERR_SHIFT) & BTE_ERR_BITS) | IBLS_ERROR) \
+          : _status)
+
+#define BTE_GET_ERROR_STATUS(_status)                                  \
+       (BTE_SHUB2_ERROR(_status) & ~IBLS_ERROR)
+
+#define BTE_VALID_SH2_ERROR(value)                                     \
+       ((value >= BTEFAIL_SH2_RESP_SHORT) && (value <= BTEFAIL_SH2_ALL))
 
 /*
  * Structure defining a bte.  An instance of this
 
        BUG_ON(REGION_NUMBER(vdst) != RGN_KERNEL);
 
        ret = bte_copy(src, pdst, len, mode, notification);
-       if (ret != BTE_SUCCESS) {
+       if ((ret != BTE_SUCCESS) && BTE_ERROR_RETRY(ret)) {
                if (!in_interrupt()) {
                        cond_resched();
                }
 
        xpcDisconnected,        /* 51: channel disconnected (closed) */
 
-       xpcUnknownReason        /* 52: unknown reason -- must be last in list */
+       xpcBteSh2Start,         /* 52: BTE CRB timeout */
+
+                               /* 53: 0x1 BTE Error Response Short */
+       xpcBteSh2RspShort = xpcBteSh2Start + BTEFAIL_SH2_RESP_SHORT,
+
+                               /* 54: 0x2 BTE Error Response Long */
+       xpcBteSh2RspLong = xpcBteSh2Start + BTEFAIL_SH2_RESP_LONG,
+
+                               /* 56: 0x4 BTE Error Response DSB */
+       xpcBteSh2RspDSB = xpcBteSh2Start + BTEFAIL_SH2_RESP_DSP,
+
+                               /* 60: 0x8 BTE Error Response Access */
+       xpcBteSh2RspAccess = xpcBteSh2Start + BTEFAIL_SH2_RESP_ACCESS,
+
+                               /* 68: 0x10 BTE Error CRB timeout */
+       xpcBteSh2CRBTO = xpcBteSh2Start + BTEFAIL_SH2_CRB_TO,
+
+                               /* 84: 0x20 BTE Error NACK limit */
+       xpcBteSh2NACKLimit = xpcBteSh2Start + BTEFAIL_SH2_NACK_LIMIT,
+
+                               /* 115: BTE end */
+       xpcBteSh2End = xpcBteSh2Start + BTEFAIL_SH2_ALL,
+
+       xpcUnknownReason        /* 116: unknown reason -- must be last in list */
 };
 
 
 
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2004-2006 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2004-2007 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
 static inline enum xpc_retval
 xpc_map_bte_errors(bte_result_t error)
 {
+       if (is_shub2()) {
+               if (BTE_VALID_SH2_ERROR(error))
+                       return xpcBteSh2Start + error;
+               else
+                       return xpcBteUnmappedError;
+       }
        switch (error) {
        case BTE_SUCCESS:       return xpcSuccess;
        case BTEFAIL_DIR:       return xpcBteDirectoryError;