diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2010-08-23 16:55:08 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2010-08-23 16:55:08 +0000 |
commit | 025ada3dc16baad85340cb76893e771f9bc5bdc3 (patch) | |
tree | d3c7bbe05aa39e8dfd7810809ed16b0f2fa9a044 /sys | |
parent | 944ea1db1f2b0ee7394e86caf04bd553cdb34040 (diff) |
Rework the logic of xbridge pci_conf_{read,write} to avoid doing the disable
bridge interrupts dance when trying to access an uninplemented ioc3 register.
Makes PIC handling simpler as a bonus.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sgi/xbow/xbridge.c | 103 |
1 files changed, 54 insertions, 49 deletions
diff --git a/sys/arch/sgi/xbow/xbridge.c b/sys/arch/sgi/xbow/xbridge.c index 4f879563e0b..39e6222d2c8 100644 --- a/sys/arch/sgi/xbow/xbridge.c +++ b/sys/arch/sgi/xbow/xbridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: xbridge.c,v 1.72 2010/05/09 18:36:07 miod Exp $ */ +/* $OpenBSD: xbridge.c,v 1.73 2010/08/23 16:55:07 miod Exp $ */ /* * Copyright (c) 2008, 2009 Miodrag Vallat. @@ -696,27 +696,7 @@ xbridge_conf_read(void *cookie, pcitag_t tag, int offset) int skip; int s; - /* Disable interrupts on this bridge (especially error interrupts) */ - xbridge_write_reg(xb, BRIDGE_IER, 0); - (void)xbridge_read_reg(xb, WIDGET_TFLUSH); - s = splhigh(); - xbridge_decompose_tag(cookie, tag, &bus, &dev, &fn); - if (bus != 0) { - xbridge_write_reg(xb, BRIDGE_PCI_CFG, - (bus << 16) | (dev << 11)); - pa = xb->xb_regh + BRIDGE_PCI_CFG1_SPACE; - } else { - if (ISSET(xb->xb_flags, XF_PIC)) { - /* - * On PIC, device 0 in configuration space is the - * PIC itself, device slots are offset by one. - */ - pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + - ((dev + 1) << 12); - } else - pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12); - } /* * IOC3 devices only implement a subset of the PCI configuration @@ -758,14 +738,37 @@ xbridge_conf_read(void *cookie, pcitag_t tag, int offset) } if (skip == 0) { + /* + * Disable interrupts on this bridge (especially error + * interrupts). + */ + s = splhigh(); + xbridge_write_reg(xb, BRIDGE_IER, 0); + (void)xbridge_read_reg(xb, WIDGET_TFLUSH); + + if (bus != 0) { + xbridge_write_reg(xb, BRIDGE_PCI_CFG, + (bus << 16) | (dev << 11)); + pa = xb->xb_regh + BRIDGE_PCI_CFG1_SPACE; + } else { + /* + * On PIC, device 0 in configuration space is the + * PIC itself, device slots are offset by one. + */ + if (ISSET(xb->xb_flags, XF_PIC)) + dev++; + pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12); + } + pa += (fn << 8) + offset; if (guarded_read_4(pa, &data) != 0) data = 0xffffffff; + + xbridge_write_reg(xb, BRIDGE_IER, xb->xb_ier); + (void)xbridge_read_reg(xb, WIDGET_TFLUSH); + splx(s); } - splx(s); - xbridge_write_reg(xb, BRIDGE_IER, xb->xb_ier); - (void)xbridge_read_reg(xb, WIDGET_TFLUSH); return data; } @@ -778,27 +781,7 @@ xbridge_conf_write(void *cookie, pcitag_t tag, int offset, pcireg_t data) int skip; int s; - /* Disable interrupts on this bridge (especially error interrupts) */ - xbridge_write_reg(xb, BRIDGE_IER, 0); - (void)xbridge_read_reg(xb, WIDGET_TFLUSH); - s = splhigh(); - xbridge_decompose_tag(cookie, tag, &bus, &dev, &fn); - if (bus != 0) { - xbridge_write_reg(xb, BRIDGE_PCI_CFG, - (bus << 16) | (dev << 11)); - pa = xb->xb_regh + BRIDGE_PCI_CFG1_SPACE; - } else { - if (ISSET(xb->xb_flags, XF_PIC)) { - /* - * On PIC, device 0 in configuration space is the - * PIC itself, device slots are offset by one. - */ - pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + - ((dev + 1) << 12); - } else - pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12); - } /* * IOC3 devices only implement a subset of the PCI configuration @@ -837,13 +820,35 @@ xbridge_conf_write(void *cookie, pcitag_t tag, int offset, pcireg_t data) } if (skip == 0) { + /* + * Disable interrupts on this bridge (especially error + * interrupts). + */ + s = splhigh(); + xbridge_write_reg(xb, BRIDGE_IER, 0); + (void)xbridge_read_reg(xb, WIDGET_TFLUSH); + + if (bus != 0) { + xbridge_write_reg(xb, BRIDGE_PCI_CFG, + (bus << 16) | (dev << 11)); + pa = xb->xb_regh + BRIDGE_PCI_CFG1_SPACE; + } else { + /* + * On PIC, device 0 in configuration space is the + * PIC itself, device slots are offset by one. + */ + if (ISSET(xb->xb_flags, XF_PIC)) + dev++; + pa = xb->xb_regh + BRIDGE_PCI_CFG_SPACE + (dev << 12); + } + pa += (fn << 8) + offset; guarded_write_4(pa, data); - } - splx(s); - xbridge_write_reg(xb, BRIDGE_IER, xb->xb_ier); - (void)xbridge_read_reg(xb, WIDGET_TFLUSH); + xbridge_write_reg(xb, BRIDGE_IER, xb->xb_ier); + (void)xbridge_read_reg(xb, WIDGET_TFLUSH); + splx(s); + } } int @@ -3580,7 +3585,7 @@ xbridge_rbus_parent_mem(struct pci_attach_args *pa) * resources, return a valid body which will fail requests. */ if (rb == NULL) - rb = rbus_new_body(pa->pa_iot, NULL, NULL, 0, 0, 0, + rb = rbus_new_body(pa->pa_iot, NULL, 0, 0, 0, RBUS_SPACE_INVALID); return rb; |