Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 26 Aug 2012 21:38:49 GMT
From:      Aleksandr Rybalko <ray@ddteam.net>
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/171096: [arm][xscale][ixp]Allow 16bit access on PCI bus
Message-ID:  <201208262138.q7QLcnLx019261@red.freebsd.org>
Resent-Message-ID: <201208262140.q7QLe1pq071894@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201208262138.q7QLcnLx019261>