kern/171096: [arm][xscale][ixp]Allow 16bit access on PCI bus
Aleksandr Rybalko
ray at ddteam.net
Sun Aug 26 21:40:01 UTC 2012
>Number: 171096
>Category: kern
>Synopsis: [arm][xscale][ixp]Allow 16bit access on PCI bus
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: update
>Submitter-Id: current-users
>Arrival-Date: Sun Aug 26 21:40:01 UTC 2012
>Closed-Date:
>Last-Modified:
>Originator: Aleksandr Rybalko
>Release: HEAD
>Organization:
>Environment:
>Description:
Patch enable ability to use 16bit access on xScale IXP family SoCs PCI bus. Required for PATA controllers.
>How-To-Repeat:
>Fix:
Patch attached with submission follows:
Index: ixp425_pci_space.c
===================================================================
--- ixp425_pci_space.c (revision 239333)
+++ ixp425_pci_space.c (working copy)
@@ -98,6 +98,15 @@
static void _pci_mem_bs_w_4(void *, bus_space_handle_t, bus_size_t, u_int32_t);
#endif
+void _pci_io_rm_2(void *, bus_space_handle_t, bus_size_t, u_int16_t *,
+ bus_size_t);
+void _pci_io_wm_2(void *, bus_space_handle_t, bus_size_t, const u_int16_t *,
+ bus_size_t);
+void _pci_io_rm_2_s(void *, bus_space_handle_t, bus_size_t, u_int16_t *,
+ bus_size_t);
+void _pci_io_wm_2_s(void *, bus_space_handle_t, bus_size_t, const u_int16_t *,
+ bus_size_t);
+
struct bus_space ixp425_pci_io_bs_tag_template = {
/* mapping/unmapping */
.bs_map = ixp425_pci_io_bs_map,
@@ -140,6 +149,10 @@
.bs_w_2_s = _pci_io_bs_w_2,
.bs_w_4_s = _pci_io_bs_w_4,
#endif
+ .bs_rm_2 = _pci_io_rm_2,
+ .bs_wm_2 = _pci_io_wm_2,
+ .bs_rm_2_s = _pci_io_rm_2_s,
+ .bs_wm_2_s = _pci_io_wm_2_s,
};
void
@@ -219,7 +232,7 @@
bus_size_t len, int flags)
{
/* NULL */
-}
+}
/* io bs */
int
@@ -238,8 +251,8 @@
int
ixp425_pci_io_bs_alloc(void *t, bus_addr_t rstart, bus_addr_t rend,
- bus_size_t size, bus_size_t alignment, bus_size_t boundary, int cacheable,
- bus_addr_t *bpap, bus_space_handle_t *bshp)
+ bus_size_t size, bus_size_t alignment, bus_size_t boundary,
+ int cacheable, bus_addr_t *bpap, bus_space_handle_t *bshp)
{
panic("ixp425_pci_io_bs_alloc(): not implemented\n");
}
@@ -256,7 +269,10 @@
{
u_int32_t data;
- CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3);
+ /*
+ * PCI bus allow byte access, so address truncation is not required.
+ */
+ CSR_WRITE_4(PCI_NP_AD, (ioh + off));
CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_READ);
data = CSR_READ_4(PCI_NP_RDATA);
if (CSR_READ_4(PCI_ISR) & ISR_PFE)
@@ -274,7 +290,7 @@
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
- return data >> (8 * n);
+ return ((data >> (8 * n)) & 0xff);
}
static u_int16_t
@@ -286,7 +302,7 @@
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
- return data >> (8 * n);
+ return ((data >> (8 * n)) & 0xffff);
}
static u_int32_t
@@ -295,6 +311,7 @@
u_int32_t data;
data = _bs_r(v, ioh, off, 0);
+
return data;
}
@@ -308,7 +325,7 @@
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
- return data >> (8 * n);
+ return ((data >> (8 * n)) & 0xff);
}
static u_int16_t
@@ -320,7 +337,7 @@
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
data = _bs_r(v, ioh, off, be);
- return data >> (8 * n);
+ return ((data >> (8 * n)) & 0xffff);
}
static u_int32_t
@@ -329,6 +346,7 @@
u_int32_t data;
data = _bs_r(v, ioh, off, 0);
+
return le32toh(data);
}
#endif /* __ARMEB__ */
@@ -337,7 +355,10 @@
_bs_w(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int32_t be, u_int32_t data)
{
- CSR_WRITE_4(PCI_NP_AD, (ioh + off) & ~3);
+ /*
+ * PCI bus allow byte access, so address truncation is not required.
+ */
+ CSR_WRITE_4(PCI_NP_AD, (ioh + off));
CSR_WRITE_4(PCI_NP_CBE, be | COMMAND_NP_IO_WRITE);
CSR_WRITE_4(PCI_NP_WDATA, data);
if (CSR_READ_4(PCI_ISR) & ISR_PFE)
@@ -352,7 +373,7 @@
n = (ioh + off) % 4;
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
- data = val << (8 * n);
+ data = (val & 0xff) << (8 * n);
_bs_w(v, ioh, off, be, data);
}
@@ -364,7 +385,7 @@
n = (ioh + off) % 4;
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
- data = val << (8 * n);
+ data = (val & 0xffff) << (8 * n);
_bs_w(v, ioh, off, be, data);
}
@@ -372,6 +393,7 @@
_pci_io_bs_w_4(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int32_t val)
{
+
_bs_w(v, ioh, off, 0, val);
}
@@ -384,7 +406,7 @@
n = (ioh + off) % 4;
be = (0xf & ~(1U << n)) << NP_CBE_SHIFT;
- data = val << (8 * n);
+ data = (val & 0xff) << (8 * n);
_bs_w(v, ioh, off, be, data);
}
@@ -396,7 +418,7 @@
n = (ioh + off) % 4;
be = (0xf & ~((1U << n) | (1U << (n + 1)))) << NP_CBE_SHIFT;
- data = val << (8 * n);
+ data = (val & 0xffff) << (8 * n);
_bs_w(v, ioh, off, be, data);
}
@@ -404,10 +426,48 @@
_pci_io_bs_w_4_s(void *v, bus_space_handle_t ioh, bus_size_t off,
u_int32_t val)
{
+
_bs_w(v, ioh, off, 0, htole32(val));
}
#endif /* __ARMEB__ */
+void
+_pci_io_rm_2(void *t, bus_space_handle_t h, bus_size_t o,
+ u_int16_t *d, bus_size_t c)
+{
+ _pci_io_rm_2_s(t, h, o, d, c);
+}
+
+void
+_pci_io_wm_2(void *t, bus_space_handle_t h, bus_size_t o,
+ const u_int16_t *d, bus_size_t c)
+{
+ _pci_io_wm_2_s(t, h, o, d, c);
+}
+
+void
+_pci_io_rm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
+ u_int16_t *d, bus_size_t c)
+{
+ uint16_t v;
+ bus_size_t i;
+
+ for (i = 0; i < c; i++) {
+ v = _pci_io_bs_r_2(t, h, o);
+ d[i] = bswap16(v);
+ }
+}
+
+void
+_pci_io_wm_2_s(void *t, bus_space_handle_t h, bus_size_t o,
+ const u_int16_t *d, bus_size_t c)
+{
+ bus_size_t i;
+
+ for (i = 0; i < c; i++)
+ _pci_io_bs_w_2(t, h, o, bswap16(d[i]));
+}
+
/* mem bs */
int
ixp425_pci_mem_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list