All of lore.kernel.org
 help / color / mirror / Atom feed
* vme_tsi148 question
@ 2013-12-27 20:15 Michael Kenney
  2013-12-28  0:23 ` Martyn Welch
  0 siblings, 1 reply; 22+ messages in thread
From: Michael Kenney @ 2013-12-27 20:15 UTC (permalink / raw)
  To: driverdev-devel

Hello,

I'm in the process of trying to debug an issue with a VME A/D board
and have noticed some curious behavior in the VME bus protocol.

We are using the vme_tsi148 bridge driver along with the vme_user
driver to access the VME boards. The A/D board requires D32 bus cycles
and the VME master window is configured accordingly, however, when
monitoring the bus cycles with a logic analyzer, we noticed that the
CPU is transferring one byte at a time (i.e. four D8 transfers rather
than one D32).

Is this the expected behavior of the tsi148 driver?

If there is a more appropriate mailing-list for this question, please
let me know.

Thanks.

--Mike
-----------------------------------------------------------------------------
Michael Kenney
Ocean Engineering Dept
Applied Physics Lab
University of Washington
-----------------------------------------------------------------------------
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2013-12-27 20:15 vme_tsi148 question Michael Kenney
@ 2013-12-28  0:23 ` Martyn Welch
  2013-12-28  0:34   ` Michael Kenney
  0 siblings, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2013-12-28  0:23 UTC (permalink / raw)
  To: Michael Kenney, driverdev-devel

On 27/12/13 20:15, Michael Kenney wrote:
> We are using the vme_tsi148 bridge driver along with the vme_user
> driver to access the VME boards. The A/D board requires D32 bus cycles
> and the VME master window is configured accordingly, however, when
> monitoring the bus cycles with a logic analyzer, we noticed that the
> CPU is transferring one byte at a time (i.e. four D8 transfers rather
> than one D32).
>
> Is this the expected behavior of the tsi148 driver?
>

Hi Mike,

This is certainly not the expected behaviour - if the window is 
configured for D32 then it should do 32 bit transfers where possible.

I've heard of this happening recently, but haven't yet been able to 
replicate it. Which VME board are you running Linux on and which flavour 
of Linux?

> If there is a more appropriate mailing-list for this question, please
> let me know.
>

This is the correct list.

Martyn

_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2013-12-28  0:23 ` Martyn Welch
@ 2013-12-28  0:34   ` Michael Kenney
  2014-01-07 16:14     ` Michael Kenney
  2014-02-04 15:28     ` Martyn Welch
  0 siblings, 2 replies; 22+ messages in thread
From: Michael Kenney @ 2013-12-28  0:34 UTC (permalink / raw)
  To: Martyn Welch; +Cc: driverdev-devel

Hi Martyn,

On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
> On 27/12/13 20:15, Michael Kenney wrote:
>>
>> We are using the vme_tsi148 bridge driver along with the vme_user
>> driver to access the VME boards. The A/D board requires D32 bus cycles
>> and the VME master window is configured accordingly, however, when
>> monitoring the bus cycles with a logic analyzer, we noticed that the
>> CPU is transferring one byte at a time (i.e. four D8 transfers rather
>> than one D32).
>>
>> Is this the expected behavior of the tsi148 driver?
>>
>
> Hi Mike,
>
> This is certainly not the expected behaviour - if the window is configured
> for D32 then it should do 32 bit transfers where possible.
>
> I've heard of this happening recently, but haven't yet been able to
> replicate it. Which VME board are you running Linux on and which flavour of
> Linux?

I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600 (Pentium M
based CPU board).

--Mike
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2013-12-28  0:34   ` Michael Kenney
@ 2014-01-07 16:14     ` Michael Kenney
  2014-01-13 12:00       ` Martyn Welch
  2014-02-04 15:28     ` Martyn Welch
  1 sibling, 1 reply; 22+ messages in thread
From: Michael Kenney @ 2014-01-07 16:14 UTC (permalink / raw)
  To: Martyn Welch; +Cc: driverdev-devel

Hi Martyn,

On Fri, Dec 27, 2013 at 4:34 PM, Michael Kenney <mfkenney@gmail.com> wrote:
>
> Hi Martyn,
>
> On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
> > On 27/12/13 20:15, Michael Kenney wrote:
> >>
> >> We are using the vme_tsi148 bridge driver along with the vme_user
> >> driver to access the VME boards. The A/D board requires D32 bus cycles
> >> and the VME master window is configured accordingly, however, when
> >> monitoring the bus cycles with a logic analyzer, we noticed that the
> >> CPU is transferring one byte at a time (i.e. four D8 transfers rather
> >> than one D32).
> >>
> >> Is this the expected behavior of the tsi148 driver?
> >>
> >
> > Hi Mike,
> >
> > This is certainly not the expected behaviour - if the window is configured
> > for D32 then it should do 32 bit transfers where possible.
> >
> > I've heard of this happening recently, but haven't yet been able to
> > replicate it. Which VME board are you running Linux on and which flavour of
> > Linux?
>
> I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600 (Pentium M
> based CPU board).
>

Just wanted to touch-base and see if you had any insight as to this
VME protocol issue with the tsi148. Let me know if there are any
further tests you would like me to run.

Thanks.

--Mike
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-01-07 16:14     ` Michael Kenney
@ 2014-01-13 12:00       ` Martyn Welch
  2014-01-13 14:49         ` Michael Kenney
  0 siblings, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-01-13 12:00 UTC (permalink / raw)
  To: Michael Kenney; +Cc: driverdev-devel

On 07/01/14 16:14, Michael Kenney wrote:
> Hi Martyn,
> 
> On Fri, Dec 27, 2013 at 4:34 PM, Michael Kenney <mfkenney@gmail.com> wrote:
>>
>> Hi Martyn,
>>
>> On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
>>> On 27/12/13 20:15, Michael Kenney wrote:
>>>>
>>>> We are using the vme_tsi148 bridge driver along with the vme_user
>>>> driver to access the VME boards. The A/D board requires D32 bus cycles
>>>> and the VME master window is configured accordingly, however, when
>>>> monitoring the bus cycles with a logic analyzer, we noticed that the
>>>> CPU is transferring one byte at a time (i.e. four D8 transfers rather
>>>> than one D32).
>>>>
>>>> Is this the expected behavior of the tsi148 driver?
>>>>
>>>
>>> Hi Mike,
>>>
>>> This is certainly not the expected behaviour - if the window is configured
>>> for D32 then it should do 32 bit transfers where possible.
>>>
>>> I've heard of this happening recently, but haven't yet been able to
>>> replicate it. Which VME board are you running Linux on and which flavour of
>>> Linux?
>>
>> I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600 (Pentium M
>> based CPU board).
>>
> 
> Just wanted to touch-base and see if you had any insight as to this
> VME protocol issue with the tsi148. Let me know if there are any
> further tests you would like me to run.
> 

Hi Mike,

I'm a little bemused by this one - I haven't managed to replicate it yet. I
have a feeling that the VME driver in version 3.2 won't use 16-bit transfers
at the beginning of blocks that aren't naturally aligned (it does D8, D8, D8,
D32... rather than D8, D16, D32... but I'm fairly sure it was doing the bulk
of a large transfer correctly).

I've got some test code here you could try (VME address may need modifying to
something more appropriate to you - I have an old PPC board acting as a slave
at 0x8BB00000 in my system). I'm running this on a 3.12 kernel, but this
should work (could you try a newer version of the kernel?):

=== START:test_extended.c ===
#define _XOPEN_SOURCE 500
#define u32 unsigned int
#include <linux/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include "vme_user.h"

int main(int argc, char *argv[])
{
        int fd;
        int i;
        int retval;
        unsigned char data[128];
	int loop;

        struct vme_master master;

        fd = open("/dev/bus/vme/m0", O_RDWR);
        if (fd == -1) {
                perror("ERROR: Opening window device file");
                return 1;
        }

        master.enable   = 1;
        master.vme_addr = 0x8BB00000;
        master.size     = 0x10000;
        master.aspace   = 4;			// VME_A32
        master.cycle    = 0x2000 | 0x8000;	// user/data access
        master.dwidth   = 4;			// VME_D32

        retval = ioctl(fd, VME_SET_MASTER, &master);
        if (retval != 0) {
                printf("retval=%d\n", retval);
                perror("ERROR: Failed to configure window");
                return 1;
        }
        for (i=0; i<sizeof(data); i++) {
                data[i] = i;
        }

	retval = pwrite(fd, data, sizeof(data), 0x0);
	if (retval < sizeof(data)) {
		printf("WARNING: Only read %d bytes", retval);
	}

	retval = pread(fd, data, sizeof(data), 0x0);
	if (retval < sizeof(data)) {
		printf("WARNING: Only read %d bytes", retval);
	}

	for(i = 0; i < sizeof(data); i++) {
		if (i % 8 == 0) {
			printf("\n""%4.4x: ", i);
		}
		printf("%2.2x ", data[i]);
	}
	printf("\n");

        close(fd);

        return 0;
}

=== END:test_extended.c ===

=== START: vme_user.h ===
#ifndef _VME_USER_H_
#define _VME_USER_H_

#define VME_USER_BUS_MAX	1

/*
 * VMEbus Master Window Configuration Structure
 */
struct vme_master {
	int enable;			/* State of Window */
	unsigned long long vme_addr;	/* Starting Address on the VMEbus */
	unsigned long long size;	/* Window Size */
	int32_t aspace;			/* Address Space */
	int32_t cycle;			/* Cycle properties */
	int32_t dwidth;			/* Maximum Data Width */
#if 0
	char prefetchEnable;		/* Prefetch Read Enable State */
	int prefetchSize;		/* Prefetch Read Size (Cache Lines) */
	char wrPostEnable;		/* Write Post State */
#endif
};


/*
 * IOCTL Commands and structures
 */

/* Magic number for use in ioctls */
#define VME_IOC_MAGIC 0xAE


/* VMEbus Slave Window Configuration Structure */
struct vme_slave {
	int enable;			/* State of Window */
	unsigned long long vme_addr;	/* Starting Address on the VMEbus */
	unsigned long long size;	/* Window Size */
	int32_t aspace;			/* Address Space */
	int32_t cycle;			/* Cycle properties */
#if 0
	char wrPostEnable;		/* Write Post State */
	char rmwLock;			/* Lock PCI during RMW Cycles */
	char data64BitCapable;		/* non-VMEbus capable of 64-bit Data */
#endif
};

struct vme_irq_id {
	int8_t level;
	int8_t statid;
};

#define VME_GET_SLAVE _IOR(VME_IOC_MAGIC, 1, struct vme_slave)
#define VME_SET_SLAVE _IOW(VME_IOC_MAGIC, 2, struct vme_slave)
#define VME_GET_MASTER _IOR(VME_IOC_MAGIC, 3, struct vme_master)
#define VME_SET_MASTER _IOW(VME_IOC_MAGIC, 4, struct vme_master)
#define VME_IRQ_GEN _IOW(VME_IOC_MAGIC, 5, struct vme_irq_id)

#endif /* _VME_USER_H_ */

=== END: vme_user.h ===

Compiled with "gcc -o test_extended test_extended.c".

When run:

root@ge-xvb601:~/vme_test# ./test_extended

0000: 00 01 02 03 04 05 06 07
0008: 08 09 0a 0b 0c 0d 0e 0f
0010: 10 11 12 13 14 15 16 17
0018: 18 19 1a 1b 1c 1d 1e 1f
0020: 20 21 22 23 24 25 26 27
0028: 28 29 2a 2b 2c 2d 2e 2f
0030: 30 31 32 33 34 35 36 37
0038: 38 39 3a 3b 3c 3d 3e 3f
0040: 40 41 42 43 44 45 46 47
0048: 48 49 4a 4b 4c 4d 4e 4f
0050: 50 51 52 53 54 55 56 57
0058: 58 59 5a 5b 5c 5d 5e 5f
0060: 60 61 62 63 64 65 66 67
0068: 68 69 6a 6b 6c 6d 6e 6f
0070: 70 71 72 73 74 75 76 77
0078: 78 79 7a 7b 7c 7d 7e 7f
root@ge-xvb601:~/vme_test#

I've plugged in an analyser, everything looks good here, 32-bit reads and
writes. I've confirmed that I see 16-bit cycles when I set dwidth to 2.

Martyn

-- 
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-01-13 12:00       ` Martyn Welch
@ 2014-01-13 14:49         ` Michael Kenney
  2014-01-14  4:07           ` Michael Kenney
  0 siblings, 1 reply; 22+ messages in thread
From: Michael Kenney @ 2014-01-13 14:49 UTC (permalink / raw)
  To: Martyn Welch; +Cc: driverdev-devel

Hi Martyn,

On Mon, Jan 13, 2014 at 4:00 AM, Martyn Welch <martyn.welch@ge.com> wrote:
[snip]
>
> Hi Mike,
>
> I'm a little bemused by this one - I haven't managed to replicate it yet. I
> have a feeling that the VME driver in version 3.2 won't use 16-bit transfers
> at the beginning of blocks that aren't naturally aligned (it does D8, D8, D8,
> D32... rather than D8, D16, D32... but I'm fairly sure it was doing the bulk
> of a large transfer correctly).
>
> I've got some test code here you could try (VME address may need modifying to
> something more appropriate to you - I have an old PPC board acting as a slave
> at 0x8BB00000 in my system). I'm running this on a 3.12 kernel, but this
> should work (could you try a newer version of the kernel?):
>
[code removed]
>
> I've plugged in an analyser, everything looks good here, 32-bit reads and
> writes. I've confirmed that I see 16-bit cycles when I set dwidth to 2.

Thanks, I will trying running the test code later this week. As for
upgrading the kernel, I will certainly look into it.

--Mike
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-01-13 14:49         ` Michael Kenney
@ 2014-01-14  4:07           ` Michael Kenney
  2014-01-14  9:39             ` Martyn Welch
  0 siblings, 1 reply; 22+ messages in thread
From: Michael Kenney @ 2014-01-14  4:07 UTC (permalink / raw)
  To: Martyn Welch; +Cc: driverdev-devel

Hi Martyn,


On Mon, Jan 13, 2014 at 6:49 AM, Michael Kenney <mfkenney@gmail.com> wrote:
> Hi Martyn,
>
> On Mon, Jan 13, 2014 at 4:00 AM, Martyn Welch <martyn.welch@ge.com> wrote:
> [snip]
>>
>> Hi Mike,
>>
>> I'm a little bemused by this one - I haven't managed to replicate it yet. I
>> have a feeling that the VME driver in version 3.2 won't use 16-bit transfers
>> at the beginning of blocks that aren't naturally aligned (it does D8, D8, D8,
>> D32... rather than D8, D16, D32... but I'm fairly sure it was doing the bulk
>> of a large transfer correctly).
>>
>> I've got some test code here you could try (VME address may need modifying to
>> something more appropriate to you - I have an old PPC board acting as a slave
>> at 0x8BB00000 in my system). I'm running this on a 3.12 kernel, but this
>> should work (could you try a newer version of the kernel?):
>>
> [code removed]
>>
>> I've plugged in an analyser, everything looks good here, 32-bit reads and
>> writes. I've confirmed that I see 16-bit cycles when I set dwidth to 2.
>
> Thanks, I will trying running the test code later this week. As for
> upgrading the kernel, I will certainly look into it.
>

Since my existing code basically does the same thing as your test
program, I decided to go ahead and update the kernel to 3.12 and rerun
my own code.

Unfortunately, the results are the same. I'm running this from home so
I'll have to confirm with the logic-analyzer tomorrow but the bridge
driver error messages suggest the same D8 writes (which for some
reason our A/D board does not like). Here's a dmesg excerpt:

[ 5631.810902] vme_tsi148 0000:02:02.0: VME Bus Error at address:
0x508000, attributes: 8008b900
[ 5631.810972] vme_tsi148 0000:02:02.0: VME Bus Exception Overflow Occurred
[ 5631.810977] vme_tsi148 0000:02:02.0: VME Bus Error at address:
0x508001, attributes: c0087900
[ 5631.810991] vme_tsi148 0000:02:02.0: VME Bus Error at address:
0x508003, attributes: 80087900
[ 5631.811061] vme_tsi148 0000:02:02.0: VME Bus Exception Overflow Occurred

The register that I am trying to write occupies 4 bytes starting at
0x508000. I have verified that the value I am trying to write to the
register is 4-byte aligned. I'm essentially doing the following:

uint32_t value;
pwrite(window_fd, &value, sizeof(value), 0x508000);

Window is configured for A24 and D32.

Does the "attributes" value from the tsi148 provide any further clues?

--Mike
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-01-14  4:07           ` Michael Kenney
@ 2014-01-14  9:39             ` Martyn Welch
  2014-01-14 16:25               ` Michael Kenney
  0 siblings, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-01-14  9:39 UTC (permalink / raw)
  To: Michael Kenney; +Cc: driverdev-devel

On 14/01/14 04:07, Michael Kenney wrote:
> Unfortunately, the results are the same. I'm running this from home so
> I'll have to confirm with the logic-analyzer tomorrow but the bridge
> driver error messages suggest the same D8 writes (which for some
> reason our A/D board does not like). 

The hardware probably doesn't support 8-bit reads/writes, from memory, it
doesn't have to according to the spec.

> Here's a dmesg excerpt:
> 
> [ 5631.810902] vme_tsi148 0000:02:02.0: VME Bus Error at address:
> 0x508000, attributes: 8008b900
> [ 5631.810972] vme_tsi148 0000:02:02.0: VME Bus Exception Overflow Occurred
> [ 5631.810977] vme_tsi148 0000:02:02.0: VME Bus Error at address:
> 0x508001, attributes: c0087900
> [ 5631.810991] vme_tsi148 0000:02:02.0: VME Bus Error at address:
> 0x508003, attributes: 80087900
> [ 5631.811061] vme_tsi148 0000:02:02.0: VME Bus Exception Overflow Occurred
> 
> The register that I am trying to write occupies 4 bytes starting at
> 0x508000. I have verified that the value I am trying to write to the
> register is 4-byte aligned. I'm essentially doing the following:
> 
> uint32_t value;
> pwrite(window_fd, &value, sizeof(value), 0x508000);
> 

How have you setup the window? The offset is relative to the window you have
configured, so if that doesn't start at 0x0, then you aren't writing where you
think you are.

> Window is configured for A24 and D32.
> 
> Does the "attributes" value from the tsi148 provide any further clues?
> 

Not really - it gives the status of some of the VME lines when the error
occurred (Address lines, data strobes), it says that there was an error, in
one case it shows an exception overflow and that it happened on the VME bus.

Martyn

-- 
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-01-14  9:39             ` Martyn Welch
@ 2014-01-14 16:25               ` Michael Kenney
  0 siblings, 0 replies; 22+ messages in thread
From: Michael Kenney @ 2014-01-14 16:25 UTC (permalink / raw)
  To: Martyn Welch; +Cc: driverdev-devel

On Tue, Jan 14, 2014 at 1:39 AM, Martyn Welch <martyn.welch@ge.com> wrote:
> On 14/01/14 04:07, Michael Kenney wrote:
>> Unfortunately, the results are the same. I'm running this from home so
>> I'll have to confirm with the logic-analyzer tomorrow but the bridge
>> driver error messages suggest the same D8 writes (which for some
>> reason our A/D board does not like).
>
> The hardware probably doesn't support 8-bit reads/writes, from memory, it
> doesn't have to according to the spec.

Looks like I was wrong about where the Bus Errors are occurring. They
are actually being generated on the reads from the board. Both reads
and writes are being done as D8 but only the reads result in an error
from the slave...

>
>> Here's a dmesg excerpt:
>>
>> [ 5631.810902] vme_tsi148 0000:02:02.0: VME Bus Error at address:
>> 0x508000, attributes: 8008b900
>> [ 5631.810972] vme_tsi148 0000:02:02.0: VME Bus Exception Overflow Occurred
>> [ 5631.810977] vme_tsi148 0000:02:02.0: VME Bus Error at address:
>> 0x508001, attributes: c0087900
>> [ 5631.810991] vme_tsi148 0000:02:02.0: VME Bus Error at address:
>> 0x508003, attributes: 80087900
>> [ 5631.811061] vme_tsi148 0000:02:02.0: VME Bus Exception Overflow Occurred
>>
>> The register that I am trying to write occupies 4 bytes starting at
>> 0x508000. I have verified that the value I am trying to write to the
>> register is 4-byte aligned. I'm essentially doing the following:
>>
>> uint32_t value;
>> pwrite(window_fd, &value, sizeof(value), 0x508000);
>>
>
> How have you setup the window? The offset is relative to the window you have
> configured, so if that doesn't start at 0x0, then you aren't writing where you
> think you are.

In this case, I have setup the window starting at 0 and spanning the
entire A24 address space. We have more boards than windows so we
share, each board's offset is its VME bus address.

>
>> Window is configured for A24 and D32.
>>
>> Does the "attributes" value from the tsi148 provide any further clues?
>>
>
> Not really - it gives the status of some of the VME lines when the error
> occurred (Address lines, data strobes), it says that there was an error, in
> one case it shows an exception overflow and that it happened on the VME bus.

That's too bad.

What's interesting is the same D8 reads/writes are occurring with the
other boards in the system but not causing any problems. This whole
issue might be a red-herring, I just wish I knew why the reads/write
were being broken up like this...

It's time to find someone familiar with the A/D board hardware. The
board is 10 years old (long since discontinued) and the original
manufacturer (ICS) was actually purchased by GE (small world :-) some
years back.

--Mike
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2013-12-28  0:34   ` Michael Kenney
  2014-01-07 16:14     ` Michael Kenney
@ 2014-02-04 15:28     ` Martyn Welch
       [not found]       ` <CAAq=YFCq0J31mBdh_0j8-39vjskkAMn47Ac8RYdigqPQVgRt5Q@mail.gmail.com>
  1 sibling, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-02-04 15:28 UTC (permalink / raw)
  To: Michael Kenney, Martyn Welch; +Cc: driverdev-devel

On 28/12/13 00:34, Michael Kenney wrote:
> Hi Martyn,
>
> On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
>> On 27/12/13 20:15, Michael Kenney wrote:
>>>
>>> We are using the vme_tsi148 bridge driver along with the vme_user
>>> driver to access the VME boards. The A/D board requires D32 bus cycles
>>> and the VME master window is configured accordingly, however, when
>>> monitoring the bus cycles with a logic analyzer, we noticed that the
>>> CPU is transferring one byte at a time (i.e. four D8 transfers rather
>>> than one D32).
>>>
>>> Is this the expected behavior of the tsi148 driver?
>>>
>>
>> Hi Mike,
>>
>> This is certainly not the expected behaviour - if the window is configured
>> for D32 then it should do 32 bit transfers where possible.
>>
>> I've heard of this happening recently, but haven't yet been able to
>> replicate it. Which VME board are you running Linux on and which flavour of
>> Linux?
>
> I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600 (Pentium M
> based CPU board).
>

I haven't forgotten about this, still not sure exactly what is happening.

Is your install/kernel 32 or 64 bit?

Are you doing single 32-bit transfers, or are you seeing this on longer 
transfers (i.e. copying a buffer full of data)?

Martyn

-- 
--
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
       [not found]       ` <CAAq=YFCq0J31mBdh_0j8-39vjskkAMn47Ac8RYdigqPQVgRt5Q@mail.gmail.com>
@ 2014-02-04 18:34         ` Martyn Welch
  2014-02-05 17:41           ` Greg KH
  0 siblings, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-02-04 18:34 UTC (permalink / raw)
  To: Michael Kenney; +Cc: Martyn Welch, driverdev-devel, Greg KH

On 04/02/14 16:34, Michael Kenney wrote:
> Hi Martyn,
>
> On Tue, Feb 4, 2014 at 7:28 AM, Martyn Welch <martyn.welch@ge.com
> <mailto:martyn.welch@ge.com>> wrote:
>
>     On 28/12/13 00:34, Michael Kenney wrote:
>
>         Hi Martyn,
>
>         On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch
>         <martyn@welchs.me.uk <mailto:martyn@welchs.me.uk>> wrote:
>
>             On 27/12/13 20:15, Michael Kenney wrote:
>
>
>                 We are using the vme_tsi148 bridge driver along with the
>                 vme_user
>                 driver to access the VME boards. The A/D board requires
>                 D32 bus cycles
>                 and the VME master window is configured accordingly,
>                 however, when
>                 monitoring the bus cycles with a logic analyzer, we
>                 noticed that the
>                 CPU is transferring one byte at a time (i.e. four D8
>                 transfers rather
>                 than one D32).
>
>                 Is this the expected behavior of the tsi148 driver?
>
>
>             Hi Mike,
>
>             This is certainly not the expected behaviour - if the window
>             is configured
>             for D32 then it should do 32 bit transfers where possible.
>
>             I've heard of this happening recently, but haven't yet been
>             able to
>             replicate it. Which VME board are you running Linux on and
>             which flavour of
>             Linux?
>
>
>         I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600
>         (Pentium M
>         based CPU board).
>
>
>     I haven't forgotten about this, still not sure exactly what is
>     happening.
>
>     Is your install/kernel 32 or 64 bit?
>
>     Are you doing single 32-bit transfers, or are you seeing this on
>     longer transfers (i.e. copying a buffer full of data)?
>
>
> Thanks for getting back to me.
>
> I'm running a 32-bit kernel and I see this behavior on all transfers
> regardless of buffer size.
>

Gah! Thought I could see what may be causing it in 64-bit kernels, but 
not 32-bit (my x86 asm is not particularly hot).

I think we /may/ be hitting issues with how the memcpy function gets 
implemented on specific architectures. The tsi148 is a PCI/X to VME 
bridge, if it receives a series of 8-bit reads or writes, it translates 
these to 8-bit reads or writes on the VME bus, which is not necessarily 
what we want.

According to the data sheet, the card you are using has an Intel 6300ESB 
ICH, which seems to be PCI/X (so we can rule out PCIe to PCI/X bridges 
or something like that doing nasty things).

I think (if I follow everything correctly) then the memcpy for 32-bit is 
handled by __memcpy in arch/x86/include/asm/string_32.h:

static __always_inline void *__memcpy(void *to, const void *from, size_t n)
{
         int d0, d1, d2;
         asm volatile("rep ; movsl\n\t"
                      "movl %4,%%ecx\n\t"
                      "andl $3,%%ecx\n\t"
                      "jz 1f\n\t"
                      "rep ; movsb\n\t"
                      "1:"
                      : "=&c" (d0), "=&D" (d1), "=&S" (d2)
                      : "0" (n / 4), "g" (n), "1" ((long)to), "2" 
((long)from)
                      : "memory");
         return to;
}

I'd expected this function to use movl (32-bit moves) where possible, 
but movsb to get to naturally aligned moves (which is something that we 
deal with in the VME code already to use 16-bit reads where we can).

Greg (as co-maintainer of the VME subsystem :-) ), Am I reading this right?

On x86_64 I think we end up using memcpy_c_e() in 
arch/x86/lib/memcpy_64.S at least some of the time:

/*
  * memcpy_c_e() - enhanced fast string memcpy. This is faster and 
simpler than
  * memcpy_c. Use memcpy_c_e when possible.
  *
  * This gets patched over the unrolled variant (below) via the
  * alternative instructions framework:
  */
         .section .altinstr_replacement, "ax", @progbits
.Lmemcpy_c_e:
         movq %rdi, %rax
         movq %rdx, %rcx
         rep movsb
         ret
.Lmemcpy_e_e:
         .previous

Which I think uses movq (64-bit moves) where possible, falling back to 
movb. So for 32-bit / some small transfers, we'll see 8-bit transfers.

So it seems that your issue may unfortunately be different from what 
we've seen internally.

Greg, Any ideas? I'm not sure the best person/mailing list to ask.

Martyn

-- 
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-02-04 18:34         ` Martyn Welch
@ 2014-02-05 17:41           ` Greg KH
  2014-02-05 21:22             ` Martyn Welch
  0 siblings, 1 reply; 22+ messages in thread
From: Greg KH @ 2014-02-05 17:41 UTC (permalink / raw)
  To: Martyn Welch; +Cc: Michael Kenney, driverdev-devel, Martyn Welch

On Tue, Feb 04, 2014 at 06:34:13PM +0000, Martyn Welch wrote:
> On 04/02/14 16:34, Michael Kenney wrote:
> >Hi Martyn,
> >
> >On Tue, Feb 4, 2014 at 7:28 AM, Martyn Welch <martyn.welch@ge.com
> ><mailto:martyn.welch@ge.com>> wrote:
> >
> >    On 28/12/13 00:34, Michael Kenney wrote:
> >
> >        Hi Martyn,
> >
> >        On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch
> >        <martyn@welchs.me.uk <mailto:martyn@welchs.me.uk>> wrote:
> >
> >            On 27/12/13 20:15, Michael Kenney wrote:
> >
> >
> >                We are using the vme_tsi148 bridge driver along with the
> >                vme_user
> >                driver to access the VME boards. The A/D board requires
> >                D32 bus cycles
> >                and the VME master window is configured accordingly,
> >                however, when
> >                monitoring the bus cycles with a logic analyzer, we
> >                noticed that the
> >                CPU is transferring one byte at a time (i.e. four D8
> >                transfers rather
> >                than one D32).
> >
> >                Is this the expected behavior of the tsi148 driver?
> >
> >
> >            Hi Mike,
> >
> >            This is certainly not the expected behaviour - if the window
> >            is configured
> >            for D32 then it should do 32 bit transfers where possible.
> >
> >            I've heard of this happening recently, but haven't yet been
> >            able to
> >            replicate it. Which VME board are you running Linux on and
> >            which flavour of
> >            Linux?
> >
> >
> >        I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600
> >        (Pentium M
> >        based CPU board).
> >
> >
> >    I haven't forgotten about this, still not sure exactly what is
> >    happening.
> >
> >    Is your install/kernel 32 or 64 bit?
> >
> >    Are you doing single 32-bit transfers, or are you seeing this on
> >    longer transfers (i.e. copying a buffer full of data)?
> >
> >
> >Thanks for getting back to me.
> >
> >I'm running a 32-bit kernel and I see this behavior on all transfers
> >regardless of buffer size.
> >
> 
> Gah! Thought I could see what may be causing it in 64-bit kernels, but not
> 32-bit (my x86 asm is not particularly hot).
> 
> I think we /may/ be hitting issues with how the memcpy function gets
> implemented on specific architectures. The tsi148 is a PCI/X to VME bridge,
> if it receives a series of 8-bit reads or writes, it translates these to
> 8-bit reads or writes on the VME bus, which is not necessarily what we want.
> 
> According to the data sheet, the card you are using has an Intel 6300ESB
> ICH, which seems to be PCI/X (so we can rule out PCIe to PCI/X bridges or
> something like that doing nasty things).
> 
> I think (if I follow everything correctly) then the memcpy for 32-bit is
> handled by __memcpy in arch/x86/include/asm/string_32.h:
> 
> static __always_inline void *__memcpy(void *to, const void *from, size_t n)
> {
>         int d0, d1, d2;
>         asm volatile("rep ; movsl\n\t"
>                      "movl %4,%%ecx\n\t"
>                      "andl $3,%%ecx\n\t"
>                      "jz 1f\n\t"
>                      "rep ; movsb\n\t"
>                      "1:"
>                      : "=&c" (d0), "=&D" (d1), "=&S" (d2)
>                      : "0" (n / 4), "g" (n), "1" ((long)to), "2"
> ((long)from)
>                      : "memory");
>         return to;
> }
> 
> I'd expected this function to use movl (32-bit moves) where possible, but
> movsb to get to naturally aligned moves (which is something that we deal
> with in the VME code already to use 16-bit reads where we can).
> 
> Greg (as co-maintainer of the VME subsystem :-) ), Am I reading this right?

Yes, but why would it matter if we copy by bytes, bits, or dwords to a
memory-backed bus?  By definition, that shouldn't matter.  If it does
matter, then we shouldn't be using memcpy, or relying on the compiler to
do the copying, but rather we need to use a write() function instead as
this would be IO memory that does care about this type of thing.

Does that help?

thanks,

greg k-h
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-02-05 17:41           ` Greg KH
@ 2014-02-05 21:22             ` Martyn Welch
  2014-02-05 21:38               ` Michael Kenney
  0 siblings, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-02-05 21:22 UTC (permalink / raw)
  To: Greg KH; +Cc: Martyn Welch, Michael Kenney, driverdev-devel

[-- Attachment #1: Type: text/plain, Size: 7001 bytes --]

On 5 February 2014 17:41, Greg KH <gregkh@linuxfoundation.org> wrote:

> On Tue, Feb 04, 2014 at 06:34:13PM +0000, Martyn Welch wrote:
> > On 04/02/14 16:34, Michael Kenney wrote:
> > >Hi Martyn,
> > >
> > >On Tue, Feb 4, 2014 at 7:28 AM, Martyn Welch <martyn.welch@ge.com
> > ><mailto:martyn.welch@ge.com>> wrote:
> > >
> > >    On 28/12/13 00:34, Michael Kenney wrote:
> > >
> > >        Hi Martyn,
> > >
> > >        On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch
> > >        <martyn@welchs.me.uk <mailto:martyn@welchs.me.uk>> wrote:
> > >
> > >            On 27/12/13 20:15, Michael Kenney wrote:
> > >
> > >
> > >                We are using the vme_tsi148 bridge driver along with the
> > >                vme_user
> > >                driver to access the VME boards. The A/D board requires
> > >                D32 bus cycles
> > >                and the VME master window is configured accordingly,
> > >                however, when
> > >                monitoring the bus cycles with a logic analyzer, we
> > >                noticed that the
> > >                CPU is transferring one byte at a time (i.e. four D8
> > >                transfers rather
> > >                than one D32).
> > >
> > >                Is this the expected behavior of the tsi148 driver?
> > >
> > >
> > >            Hi Mike,
> > >
> > >            This is certainly not the expected behaviour - if the window
> > >            is configured
> > >            for D32 then it should do 32 bit transfers where possible.
> > >
> > >            I've heard of this happening recently, but haven't yet been
> > >            able to
> > >            replicate it. Which VME board are you running Linux on and
> > >            which flavour of
> > >            Linux?
> > >
> > >
> > >        I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600
> > >        (Pentium M
> > >        based CPU board).
> > >
> > >
> > >    I haven't forgotten about this, still not sure exactly what is
> > >    happening.
> > >
> > >    Is your install/kernel 32 or 64 bit?
> > >
> > >    Are you doing single 32-bit transfers, or are you seeing this on
> > >    longer transfers (i.e. copying a buffer full of data)?
> > >
> > >
> > >Thanks for getting back to me.
> > >
> > >I'm running a 32-bit kernel and I see this behavior on all transfers
> > >regardless of buffer size.
> > >
> >
> > Gah! Thought I could see what may be causing it in 64-bit kernels, but
> not
> > 32-bit (my x86 asm is not particularly hot).
> >
> > I think we /may/ be hitting issues with how the memcpy function gets
> > implemented on specific architectures. The tsi148 is a PCI/X to VME
> bridge,
> > if it receives a series of 8-bit reads or writes, it translates these to
> > 8-bit reads or writes on the VME bus, which is not necessarily what we
> want.
> >
> > According to the data sheet, the card you are using has an Intel 6300ESB
> > ICH, which seems to be PCI/X (so we can rule out PCIe to PCI/X bridges or
> > something like that doing nasty things).
> >
> > I think (if I follow everything correctly) then the memcpy for 32-bit is
> > handled by __memcpy in arch/x86/include/asm/string_32.h:
> >
> > static __always_inline void *__memcpy(void *to, const void *from, size_t
> n)
> > {
> >         int d0, d1, d2;
> >         asm volatile("rep ; movsl\n\t"
> >                      "movl %4,%%ecx\n\t"
> >                      "andl $3,%%ecx\n\t"
> >                      "jz 1f\n\t"
> >                      "rep ; movsb\n\t"
> >                      "1:"
> >                      : "=&c" (d0), "=&D" (d1), "=&S" (d2)
> >                      : "0" (n / 4), "g" (n), "1" ((long)to), "2"
> > ((long)from)
> >                      : "memory");
> >         return to;
> > }
> >
> > I'd expected this function to use movl (32-bit moves) where possible, but
> > movsb to get to naturally aligned moves (which is something that we deal
> > with in the VME code already to use 16-bit reads where we can).
> >
> > Greg (as co-maintainer of the VME subsystem :-) ), Am I reading this
> right?
>
> Yes, but why would it matter if we copy by bytes, bits, or dwords to a
> memory-backed bus?  By definition, that shouldn't matter.  If it does
> matter, then we shouldn't be using memcpy, or relying on the compiler to
> do the copying, but rather we need to use a write() function instead as
> this would be IO memory that does care about this type of thing.
>
>
The drivers are using the functions memcpy_toio and memcpy_fromio for the
bulk of the transfer, these seem to equate to memcpy on x86.

In this instance it does matter - some devices can only accept certain
width accesses and the VME bridge will translate a 8-bit PCI transfer to a
8-bit transfer on the VME bus.

So (and I haven't even compile tested this yet), this?:

diff --git a/drivers/vme/bridges/vme_ca91cx42.c
b/drivers/vme/bridges/vme_ca91cx42.c
index 1425d22c..0d87ebd 100644
--- a/drivers/vme/bridges/vme_ca91cx42.c
+++ b/drivers/vme/bridges/vme_ca91cx42.c
@@ -894,9 +894,9 @@ static ssize_t ca91cx42_master_read(struct
vme_master_resource *image,
        }

        count32 = (count - done) & ~0x3;
-       if (count32 > 0) {
-               memcpy_fromio(buf + done, addr + done, (unsigned int)count);
-               done += count32;
+       while (done < count32) {
+               *(u32 *)(buf + done) = ioread32(addr + done);
+               done += 4;
        }

        if ((count - done) & 0x2) {
@@ -948,9 +948,9 @@ static ssize_t ca91cx42_master_write(struct
vme_master_resource *image,
        }

        count32 = (count - done) & ~0x3;
-       if (count32 > 0) {
-               memcpy_toio(addr + done, buf + done, count32);
-               done += count32;
+       while (done < count32) {
+               iowrite32(*(u32 *)(buf + done), addr + done);
+               done += 4;
        }

        if ((count - done) & 0x2) {
diff --git a/drivers/vme/bridges/vme_tsi148.c
b/drivers/vme/bridges/vme_tsi148.c
index 5fbd08f..bc82991 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -1297,9 +1297,9 @@ static ssize_t tsi148_master_read(struct
vme_master_resource *image, void *buf,
        }

        count32 = (count - done) & ~0x3;
-       if (count32 > 0) {
-               memcpy_fromio(buf + done, addr + done, count32);
-               done += count32;
+       if (done < count32) {
+               *(u32 *)(buf + done) = ioread32(addr + done);
+               done += 4;
        }

        if ((count - done) & 0x2) {
@@ -1379,9 +1379,9 @@ static ssize_t tsi148_master_write(struct
vme_master_resource *image, void *buf,
        }

        count32 = (count - done) & ~0x3;
-       if (count32 > 0) {
-               memcpy_toio(addr + done, buf + done, count32);
-               done += count32;
+       if (done < count32) {
+               iowrite32(*(u32 *)(buf + done), addr + done);
+               done += 4;
        }

        if ((count - done) & 0x2) {



> Does that help?
>
>
Yep :-)

Thanks Greg.

Martyn

[-- Attachment #2: Type: text/html, Size: 10278 bytes --]

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-02-05 21:22             ` Martyn Welch
@ 2014-02-05 21:38               ` Michael Kenney
  2014-02-05 23:21                 ` Michael Kenney
  0 siblings, 1 reply; 22+ messages in thread
From: Michael Kenney @ 2014-02-05 21:38 UTC (permalink / raw)
  To: Martyn Welch; +Cc: Greg KH, Martyn Welch, driverdev-devel

On Wed, Feb 5, 2014 at 1:22 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
>
>
>
> On 5 February 2014 17:41, Greg KH <gregkh@linuxfoundation.org> wrote:
>>
>> On Tue, Feb 04, 2014 at 06:34:13PM +0000, Martyn Welch wrote:
>> > On 04/02/14 16:34, Michael Kenney wrote:
>> > >Hi Martyn,
>> > >
>> > >On Tue, Feb 4, 2014 at 7:28 AM, Martyn Welch <martyn.welch@ge.com
>> > ><mailto:martyn.welch@ge.com>> wrote:
>> > >
>> > >    On 28/12/13 00:34, Michael Kenney wrote:
>> > >
>> > >        Hi Martyn,
>> > >
>> > >        On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch
>> > >        <martyn@welchs.me.uk <mailto:martyn@welchs.me.uk>> wrote:
>> > >
>> > >            On 27/12/13 20:15, Michael Kenney wrote:
>> > >
>> > >
>> > >                We are using the vme_tsi148 bridge driver along with
>> > > the
>> > >                vme_user
>> > >                driver to access the VME boards. The A/D board requires
>> > >                D32 bus cycles
>> > >                and the VME master window is configured accordingly,
>> > >                however, when
>> > >                monitoring the bus cycles with a logic analyzer, we
>> > >                noticed that the
>> > >                CPU is transferring one byte at a time (i.e. four D8
>> > >                transfers rather
>> > >                than one D32).
>> > >
>> > >                Is this the expected behavior of the tsi148 driver?
>> > >
>> > >
>> > >            Hi Mike,
>> > >
>> > >            This is certainly not the expected behaviour - if the
>> > > window
>> > >            is configured
>> > >            for D32 then it should do 32 bit transfers where possible.
>> > >
>> > >            I've heard of this happening recently, but haven't yet been
>> > >            able to
>> > >            replicate it. Which VME board are you running Linux on and
>> > >            which flavour of
>> > >            Linux?
>> > >
>> > >
>> > >        I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600
>> > >        (Pentium M
>> > >        based CPU board).
>> > >
>> > >
>> > >    I haven't forgotten about this, still not sure exactly what is
>> > >    happening.
>> > >
>> > >    Is your install/kernel 32 or 64 bit?
>> > >
>> > >    Are you doing single 32-bit transfers, or are you seeing this on
>> > >    longer transfers (i.e. copying a buffer full of data)?
>> > >
>> > >
>> > >Thanks for getting back to me.
>> > >
>> > >I'm running a 32-bit kernel and I see this behavior on all transfers
>> > >regardless of buffer size.
>> > >
>> >
>> > Gah! Thought I could see what may be causing it in 64-bit kernels, but
>> > not
>> > 32-bit (my x86 asm is not particularly hot).
>> >
>> > I think we /may/ be hitting issues with how the memcpy function gets
>> > implemented on specific architectures. The tsi148 is a PCI/X to VME
>> > bridge,
>> > if it receives a series of 8-bit reads or writes, it translates these to
>> > 8-bit reads or writes on the VME bus, which is not necessarily what we
>> > want.
>> >
>> > According to the data sheet, the card you are using has an Intel 6300ESB
>> > ICH, which seems to be PCI/X (so we can rule out PCIe to PCI/X bridges
>> > or
>> > something like that doing nasty things).
>> >
>> > I think (if I follow everything correctly) then the memcpy for 32-bit is
>> > handled by __memcpy in arch/x86/include/asm/string_32.h:
>> >
>> > static __always_inline void *__memcpy(void *to, const void *from, size_t
>> > n)
>> > {
>> >         int d0, d1, d2;
>> >         asm volatile("rep ; movsl\n\t"
>> >                      "movl %4,%%ecx\n\t"
>> >                      "andl $3,%%ecx\n\t"
>> >                      "jz 1f\n\t"
>> >                      "rep ; movsb\n\t"
>> >                      "1:"
>> >                      : "=&c" (d0), "=&D" (d1), "=&S" (d2)
>> >                      : "0" (n / 4), "g" (n), "1" ((long)to), "2"
>> > ((long)from)
>> >                      : "memory");
>> >         return to;
>> > }
>> >
>> > I'd expected this function to use movl (32-bit moves) where possible,
>> > but
>> > movsb to get to naturally aligned moves (which is something that we deal
>> > with in the VME code already to use 16-bit reads where we can).
>> >
>> > Greg (as co-maintainer of the VME subsystem :-) ), Am I reading this
>> > right?
>>
>> Yes, but why would it matter if we copy by bytes, bits, or dwords to a
>> memory-backed bus?  By definition, that shouldn't matter.  If it does
>> matter, then we shouldn't be using memcpy, or relying on the compiler to
>> do the copying, but rather we need to use a write() function instead as
>> this would be IO memory that does care about this type of thing.
>>
>
> The drivers are using the functions memcpy_toio and memcpy_fromio for the
> bulk of the transfer, these seem to equate to memcpy on x86.
>
> In this instance it does matter - some devices can only accept certain width
> accesses and the VME bridge will translate a 8-bit PCI transfer to a 8-bit
> transfer on the VME bus.
>
> So (and I haven't even compile tested this yet), this?:
>
> diff --git a/drivers/vme/bridges/vme_ca91cx42.c
> b/drivers/vme/bridges/vme_ca91cx42.c
> index 1425d22c..0d87ebd 100644
> --- a/drivers/vme/bridges/vme_ca91cx42.c
> +++ b/drivers/vme/bridges/vme_ca91cx42.c
> @@ -894,9 +894,9 @@ static ssize_t ca91cx42_master_read(struct
> vme_master_resource *image,
>         }
>
>         count32 = (count - done) & ~0x3;
> -       if (count32 > 0) {
> -               memcpy_fromio(buf + done, addr + done, (unsigned int)count);
> -               done += count32;
> +       while (done < count32) {
> +               *(u32 *)(buf + done) = ioread32(addr + done);
> +               done += 4;
>         }
>
>         if ((count - done) & 0x2) {
> @@ -948,9 +948,9 @@ static ssize_t ca91cx42_master_write(struct
> vme_master_resource *image,
>         }
>
>         count32 = (count - done) & ~0x3;
> -       if (count32 > 0) {
> -               memcpy_toio(addr + done, buf + done, count32);
> -               done += count32;
> +       while (done < count32) {
> +               iowrite32(*(u32 *)(buf + done), addr + done);
> +               done += 4;
>         }
>
>         if ((count - done) & 0x2) {
> diff --git a/drivers/vme/bridges/vme_tsi148.c
> b/drivers/vme/bridges/vme_tsi148.c
> index 5fbd08f..bc82991 100644
> --- a/drivers/vme/bridges/vme_tsi148.c
> +++ b/drivers/vme/bridges/vme_tsi148.c
> @@ -1297,9 +1297,9 @@ static ssize_t tsi148_master_read(struct
> vme_master_resource *image, void *buf,
>         }
>
>         count32 = (count - done) & ~0x3;
> -       if (count32 > 0) {
> -               memcpy_fromio(buf + done, addr + done, count32);
> -               done += count32;
> +       if (done < count32) {
> +               *(u32 *)(buf + done) = ioread32(addr + done);
> +               done += 4;
>         }
>
>         if ((count - done) & 0x2) {
> @@ -1379,9 +1379,9 @@ static ssize_t tsi148_master_write(struct
> vme_master_resource *image, void *buf,
>         }
>
>         count32 = (count - done) & ~0x3;
> -       if (count32 > 0) {
> -               memcpy_toio(addr + done, buf + done, count32);
> -               done += count32;
> +       if (done < count32) {
> +               iowrite32(*(u32 *)(buf + done), addr + done);
> +               done += 4;
>         }
>
>         if ((count - done) & 0x2) {
>
>
>>
>> Does that help?
>>
>
> Yep :-)
>
> Thanks Greg.

That certainly looks promising. I can give that patch a try later this week.

Thanks.

--Mike

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-02-05 21:38               ` Michael Kenney
@ 2014-02-05 23:21                 ` Michael Kenney
  2014-02-06  8:40                   ` Martyn Welch
  0 siblings, 1 reply; 22+ messages in thread
From: Michael Kenney @ 2014-02-05 23:21 UTC (permalink / raw)
  To: Martyn Welch; +Cc: Martyn Welch, Greg KH, driverdev-devel

On Wed, Feb 5, 2014 at 1:38 PM, Michael Kenney <mfkenney@gmail.com> wrote:
> On Wed, Feb 5, 2014 at 1:22 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
>>
>>
>>
>> On 5 February 2014 17:41, Greg KH <gregkh@linuxfoundation.org> wrote:
>>>
>>> On Tue, Feb 04, 2014 at 06:34:13PM +0000, Martyn Welch wrote:
>>> > On 04/02/14 16:34, Michael Kenney wrote:
>>> > >Hi Martyn,
>>> > >
>>> > >On Tue, Feb 4, 2014 at 7:28 AM, Martyn Welch <martyn.welch@ge.com
>>> > ><mailto:martyn.welch@ge.com>> wrote:
>>> > >
>>> > >    On 28/12/13 00:34, Michael Kenney wrote:
>>> > >
>>> > >        Hi Martyn,
>>> > >
>>> > >        On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch
>>> > >        <martyn@welchs.me.uk <mailto:martyn@welchs.me.uk>> wrote:
>>> > >
>>> > >            On 27/12/13 20:15, Michael Kenney wrote:
>>> > >
>>> > >
>>> > >                We are using the vme_tsi148 bridge driver along with
>>> > > the
>>> > >                vme_user
>>> > >                driver to access the VME boards. The A/D board requires
>>> > >                D32 bus cycles
>>> > >                and the VME master window is configured accordingly,
>>> > >                however, when
>>> > >                monitoring the bus cycles with a logic analyzer, we
>>> > >                noticed that the
>>> > >                CPU is transferring one byte at a time (i.e. four D8
>>> > >                transfers rather
>>> > >                than one D32).
>>> > >
>>> > >                Is this the expected behavior of the tsi148 driver?
>>> > >
>>> > >
>>> > >            Hi Mike,
>>> > >
>>> > >            This is certainly not the expected behaviour - if the
>>> > > window
>>> > >            is configured
>>> > >            for D32 then it should do 32 bit transfers where possible.
>>> > >
>>> > >            I've heard of this happening recently, but haven't yet been
>>> > >            able to
>>> > >            replicate it. Which VME board are you running Linux on and
>>> > >            which flavour of
>>> > >            Linux?
>>> > >
>>> > >
>>> > >        I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600
>>> > >        (Pentium M
>>> > >        based CPU board).
>>> > >
>>> > >
>>> > >    I haven't forgotten about this, still not sure exactly what is
>>> > >    happening.
>>> > >
>>> > >    Is your install/kernel 32 or 64 bit?
>>> > >
>>> > >    Are you doing single 32-bit transfers, or are you seeing this on
>>> > >    longer transfers (i.e. copying a buffer full of data)?
>>> > >
>>> > >
>>> > >Thanks for getting back to me.
>>> > >
>>> > >I'm running a 32-bit kernel and I see this behavior on all transfers
>>> > >regardless of buffer size.
>>> > >
>>> >
>>> > Gah! Thought I could see what may be causing it in 64-bit kernels, but
>>> > not
>>> > 32-bit (my x86 asm is not particularly hot).
>>> >
>>> > I think we /may/ be hitting issues with how the memcpy function gets
>>> > implemented on specific architectures. The tsi148 is a PCI/X to VME
>>> > bridge,
>>> > if it receives a series of 8-bit reads or writes, it translates these to
>>> > 8-bit reads or writes on the VME bus, which is not necessarily what we
>>> > want.
>>> >
>>> > According to the data sheet, the card you are using has an Intel 6300ESB
>>> > ICH, which seems to be PCI/X (so we can rule out PCIe to PCI/X bridges
>>> > or
>>> > something like that doing nasty things).
>>> >
>>> > I think (if I follow everything correctly) then the memcpy for 32-bit is
>>> > handled by __memcpy in arch/x86/include/asm/string_32.h:
>>> >
>>> > static __always_inline void *__memcpy(void *to, const void *from, size_t
>>> > n)
>>> > {
>>> >         int d0, d1, d2;
>>> >         asm volatile("rep ; movsl\n\t"
>>> >                      "movl %4,%%ecx\n\t"
>>> >                      "andl $3,%%ecx\n\t"
>>> >                      "jz 1f\n\t"
>>> >                      "rep ; movsb\n\t"
>>> >                      "1:"
>>> >                      : "=&c" (d0), "=&D" (d1), "=&S" (d2)
>>> >                      : "0" (n / 4), "g" (n), "1" ((long)to), "2"
>>> > ((long)from)
>>> >                      : "memory");
>>> >         return to;
>>> > }
>>> >
>>> > I'd expected this function to use movl (32-bit moves) where possible,
>>> > but
>>> > movsb to get to naturally aligned moves (which is something that we deal
>>> > with in the VME code already to use 16-bit reads where we can).
>>> >
>>> > Greg (as co-maintainer of the VME subsystem :-) ), Am I reading this
>>> > right?
>>>
>>> Yes, but why would it matter if we copy by bytes, bits, or dwords to a
>>> memory-backed bus?  By definition, that shouldn't matter.  If it does
>>> matter, then we shouldn't be using memcpy, or relying on the compiler to
>>> do the copying, but rather we need to use a write() function instead as
>>> this would be IO memory that does care about this type of thing.
>>>
>>
>> The drivers are using the functions memcpy_toio and memcpy_fromio for the
>> bulk of the transfer, these seem to equate to memcpy on x86.
>>
>> In this instance it does matter - some devices can only accept certain width
>> accesses and the VME bridge will translate a 8-bit PCI transfer to a 8-bit
>> transfer on the VME bus.
>>
>> So (and I haven't even compile tested this yet), this?:
>>
>> diff --git a/drivers/vme/bridges/vme_ca91cx42.c
>> b/drivers/vme/bridges/vme_ca91cx42.c
>> index 1425d22c..0d87ebd 100644
>> --- a/drivers/vme/bridges/vme_ca91cx42.c
>> +++ b/drivers/vme/bridges/vme_ca91cx42.c
>> @@ -894,9 +894,9 @@ static ssize_t ca91cx42_master_read(struct
>> vme_master_resource *image,
>>         }
>>
>>         count32 = (count - done) & ~0x3;
>> -       if (count32 > 0) {
>> -               memcpy_fromio(buf + done, addr + done, (unsigned int)count);
>> -               done += count32;
>> +       while (done < count32) {
>> +               *(u32 *)(buf + done) = ioread32(addr + done);
>> +               done += 4;
>>         }
>>
>>         if ((count - done) & 0x2) {
>> @@ -948,9 +948,9 @@ static ssize_t ca91cx42_master_write(struct
>> vme_master_resource *image,
>>         }
>>
>>         count32 = (count - done) & ~0x3;
>> -       if (count32 > 0) {
>> -               memcpy_toio(addr + done, buf + done, count32);
>> -               done += count32;
>> +       while (done < count32) {
>> +               iowrite32(*(u32 *)(buf + done), addr + done);
>> +               done += 4;
>>         }
>>
>>         if ((count - done) & 0x2) {
>> diff --git a/drivers/vme/bridges/vme_tsi148.c
>> b/drivers/vme/bridges/vme_tsi148.c
>> index 5fbd08f..bc82991 100644
>> --- a/drivers/vme/bridges/vme_tsi148.c
>> +++ b/drivers/vme/bridges/vme_tsi148.c
>> @@ -1297,9 +1297,9 @@ static ssize_t tsi148_master_read(struct
>> vme_master_resource *image, void *buf,
>>         }
>>
>>         count32 = (count - done) & ~0x3;
>> -       if (count32 > 0) {
>> -               memcpy_fromio(buf + done, addr + done, count32);
>> -               done += count32;
>> +       if (done < count32) {
>> +               *(u32 *)(buf + done) = ioread32(addr + done);
>> +               done += 4;
>>         }
>>
>>         if ((count - done) & 0x2) {
>> @@ -1379,9 +1379,9 @@ static ssize_t tsi148_master_write(struct
>> vme_master_resource *image, void *buf,
>>         }
>>
>>         count32 = (count - done) & ~0x3;
>> -       if (count32 > 0) {
>> -               memcpy_toio(addr + done, buf + done, count32);
>> -               done += count32;
>> +       if (done < count32) {
>> +               iowrite32(*(u32 *)(buf + done), addr + done);
>> +               done += 4;
>>         }
>>
>>         if ((count - done) & 0x2) {
>>
>>
>>>
>>> Does that help?
>>>
>>
>> Yep :-)
>>
>> Thanks Greg.
>
> That certainly looks promising. I can give that patch a try later this week.
>
> Thanks.

Good news Martyn.

I had a bit of time today to test your patch and am happy to say it
worked! No more bus errors.

Now I can work on getting the actual data acquisition working :-)

Thanks again for all your help.

--Mike
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-02-05 23:21                 ` Michael Kenney
@ 2014-02-06  8:40                   ` Martyn Welch
  2014-02-06 13:35                     ` [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour Martyn Welch
  2014-02-06 14:07                     ` vme_tsi148 question Michael Kenney
  0 siblings, 2 replies; 22+ messages in thread
From: Martyn Welch @ 2014-02-06  8:40 UTC (permalink / raw)
  To: Michael Kenney, Martyn Welch; +Cc: Greg KH, driverdev-devel



On 05/02/14 23:21, Michael Kenney wrote:
> On Wed, Feb 5, 2014 at 1:38 PM, Michael Kenney <mfkenney@gmail.com> wrote:
>> On Wed, Feb 5, 2014 at 1:22 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
>>>
>>>
>>>
>>> On 5 February 2014 17:41, Greg KH <gregkh@linuxfoundation.org> wrote:
>>>>
>>>> On Tue, Feb 04, 2014 at 06:34:13PM +0000, Martyn Welch wrote:
>>>>> On 04/02/14 16:34, Michael Kenney wrote:
>>>>>> Hi Martyn,
>>>>>>
>>>>>> On Tue, Feb 4, 2014 at 7:28 AM, Martyn Welch <martyn.welch@ge.com
>>>>>> <mailto:martyn.welch@ge.com>> wrote:
>>>>>>
>>>>>>     On 28/12/13 00:34, Michael Kenney wrote:
>>>>>>
>>>>>>         Hi Martyn,
>>>>>>
>>>>>>         On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch
>>>>>>         <martyn@welchs.me.uk <mailto:martyn@welchs.me.uk>> wrote:
>>>>>>
>>>>>>             On 27/12/13 20:15, Michael Kenney wrote:
>>>>>>
>>>>>>
>>>>>>                 We are using the vme_tsi148 bridge driver along with
>>>>>> the
>>>>>>                 vme_user
>>>>>>                 driver to access the VME boards. The A/D board requires
>>>>>>                 D32 bus cycles
>>>>>>                 and the VME master window is configured accordingly,
>>>>>>                 however, when
>>>>>>                 monitoring the bus cycles with a logic analyzer, we
>>>>>>                 noticed that the
>>>>>>                 CPU is transferring one byte at a time (i.e. four D8
>>>>>>                 transfers rather
>>>>>>                 than one D32).
>>>>>>
>>>>>>                 Is this the expected behavior of the tsi148 driver?
>>>>>>
>>>>>>
>>>>>>             Hi Mike,
>>>>>>
>>>>>>             This is certainly not the expected behaviour - if the
>>>>>> window
>>>>>>             is configured
>>>>>>             for D32 then it should do 32 bit transfers where possible.
>>>>>>
>>>>>>             I've heard of this happening recently, but haven't yet been
>>>>>>             able to
>>>>>>             replicate it. Which VME board are you running Linux on and
>>>>>>             which flavour of
>>>>>>             Linux?
>>>>>>
>>>>>>
>>>>>>         I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600
>>>>>>         (Pentium M
>>>>>>         based CPU board).
>>>>>>
>>>>>>
>>>>>>     I haven't forgotten about this, still not sure exactly what is
>>>>>>     happening.
>>>>>>
>>>>>>     Is your install/kernel 32 or 64 bit?
>>>>>>
>>>>>>     Are you doing single 32-bit transfers, or are you seeing this on
>>>>>>     longer transfers (i.e. copying a buffer full of data)?
>>>>>>
>>>>>>
>>>>>> Thanks for getting back to me.
>>>>>>
>>>>>> I'm running a 32-bit kernel and I see this behavior on all transfers
>>>>>> regardless of buffer size.
>>>>>>
>>>>>
>>>>> Gah! Thought I could see what may be causing it in 64-bit kernels, but
>>>>> not
>>>>> 32-bit (my x86 asm is not particularly hot).
>>>>>
>>>>> I think we /may/ be hitting issues with how the memcpy function gets
>>>>> implemented on specific architectures. The tsi148 is a PCI/X to VME
>>>>> bridge,
>>>>> if it receives a series of 8-bit reads or writes, it translates these to
>>>>> 8-bit reads or writes on the VME bus, which is not necessarily what we
>>>>> want.
>>>>>
>>>>> According to the data sheet, the card you are using has an Intel 6300ESB
>>>>> ICH, which seems to be PCI/X (so we can rule out PCIe to PCI/X bridges
>>>>> or
>>>>> something like that doing nasty things).
>>>>>
>>>>> I think (if I follow everything correctly) then the memcpy for 32-bit is
>>>>> handled by __memcpy in arch/x86/include/asm/string_32.h:
>>>>>
>>>>> static __always_inline void *__memcpy(void *to, const void *from, size_t
>>>>> n)
>>>>> {
>>>>>          int d0, d1, d2;
>>>>>          asm volatile("rep ; movsl\n\t"
>>>>>                       "movl %4,%%ecx\n\t"
>>>>>                       "andl $3,%%ecx\n\t"
>>>>>                       "jz 1f\n\t"
>>>>>                       "rep ; movsb\n\t"
>>>>>                       "1:"
>>>>>                       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
>>>>>                       : "0" (n / 4), "g" (n), "1" ((long)to), "2"
>>>>> ((long)from)
>>>>>                       : "memory");
>>>>>          return to;
>>>>> }
>>>>>
>>>>> I'd expected this function to use movl (32-bit moves) where possible,
>>>>> but
>>>>> movsb to get to naturally aligned moves (which is something that we deal
>>>>> with in the VME code already to use 16-bit reads where we can).
>>>>>
>>>>> Greg (as co-maintainer of the VME subsystem :-) ), Am I reading this
>>>>> right?
>>>>
>>>> Yes, but why would it matter if we copy by bytes, bits, or dwords to a
>>>> memory-backed bus?  By definition, that shouldn't matter.  If it does
>>>> matter, then we shouldn't be using memcpy, or relying on the compiler to
>>>> do the copying, but rather we need to use a write() function instead as
>>>> this would be IO memory that does care about this type of thing.
>>>>
>>>
>>> The drivers are using the functions memcpy_toio and memcpy_fromio for the
>>> bulk of the transfer, these seem to equate to memcpy on x86.
>>>
>>> In this instance it does matter - some devices can only accept certain width
>>> accesses and the VME bridge will translate a 8-bit PCI transfer to a 8-bit
>>> transfer on the VME bus.
>>>
>>> So (and I haven't even compile tested this yet), this?:
>>>
>>> diff --git a/drivers/vme/bridges/vme_ca91cx42.c
>>> b/drivers/vme/bridges/vme_ca91cx42.c
>>> index 1425d22c..0d87ebd 100644
>>> --- a/drivers/vme/bridges/vme_ca91cx42.c
>>> +++ b/drivers/vme/bridges/vme_ca91cx42.c
>>> @@ -894,9 +894,9 @@ static ssize_t ca91cx42_master_read(struct
>>> vme_master_resource *image,
>>>          }
>>>
>>>          count32 = (count - done) & ~0x3;
>>> -       if (count32 > 0) {
>>> -               memcpy_fromio(buf + done, addr + done, (unsigned int)count);
>>> -               done += count32;
>>> +       while (done < count32) {
>>> +               *(u32 *)(buf + done) = ioread32(addr + done);
>>> +               done += 4;
>>>          }
>>>
>>>          if ((count - done) & 0x2) {
>>> @@ -948,9 +948,9 @@ static ssize_t ca91cx42_master_write(struct
>>> vme_master_resource *image,
>>>          }
>>>
>>>          count32 = (count - done) & ~0x3;
>>> -       if (count32 > 0) {
>>> -               memcpy_toio(addr + done, buf + done, count32);
>>> -               done += count32;
>>> +       while (done < count32) {
>>> +               iowrite32(*(u32 *)(buf + done), addr + done);
>>> +               done += 4;
>>>          }
>>>
>>>          if ((count - done) & 0x2) {
>>> diff --git a/drivers/vme/bridges/vme_tsi148.c
>>> b/drivers/vme/bridges/vme_tsi148.c
>>> index 5fbd08f..bc82991 100644
>>> --- a/drivers/vme/bridges/vme_tsi148.c
>>> +++ b/drivers/vme/bridges/vme_tsi148.c
>>> @@ -1297,9 +1297,9 @@ static ssize_t tsi148_master_read(struct
>>> vme_master_resource *image, void *buf,
>>>          }
>>>
>>>          count32 = (count - done) & ~0x3;
>>> -       if (count32 > 0) {
>>> -               memcpy_fromio(buf + done, addr + done, count32);
>>> -               done += count32;
>>> +       if (done < count32) {
>>> +               *(u32 *)(buf + done) = ioread32(addr + done);
>>> +               done += 4;
>>>          }
>>>
>>>          if ((count - done) & 0x2) {
>>> @@ -1379,9 +1379,9 @@ static ssize_t tsi148_master_write(struct
>>> vme_master_resource *image, void *buf,
>>>          }
>>>
>>>          count32 = (count - done) & ~0x3;
>>> -       if (count32 > 0) {
>>> -               memcpy_toio(addr + done, buf + done, count32);
>>> -               done += count32;
>>> +       if (done < count32) {
>>> +               iowrite32(*(u32 *)(buf + done), addr + done);
>>> +               done += 4;
>>>          }
>>>
>>>          if ((count - done) & 0x2) {
>>>
>>>
>>>>
>>>> Does that help?
>>>>
>>>
>>> Yep :-)
>>>
>>> Thanks Greg.
>>
>> That certainly looks promising. I can give that patch a try later this week.
>>
>> Thanks.
>
> Good news Martyn.
>
> I had a bit of time today to test your patch and am happy to say it
> worked! No more bus errors.
>
> Now I can work on getting the actual data acquisition working :-)
>

Thanks Mike.

Guess you didn't spot the little bug then :-)

For the tsi148 I forgot to change the conditional from "if" to "while".

I'll submit a proper patch in a minute,

Martyn

> Thanks again for all your help.
>
> --Mike
>

-- 
--
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour
  2014-02-06  8:40                   ` Martyn Welch
@ 2014-02-06 13:35                     ` Martyn Welch
  2014-02-12 13:20                       ` Martyn Welch
  2014-02-06 14:07                     ` vme_tsi148 question Michael Kenney
  1 sibling, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-02-06 13:35 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: driverdev-devel, Manohar Vanga, Michael Kenney, Martyn Welch

The ca91cx42 and tsi148 VME bridges use the width of reads and writes on the
PCI bus in part to control the width of the cycles on the VME bus. It is
important that we can control the width of cycles on the VME bus as some VME
hardware requires cycles of a specific width. The memcpy_toio() and
memcpy_fromio() functions do not provide sufficient control, so instead loop
using ioread functions.

Reported-by: Michael Kenney <mfkenney@gmail.com>
Signed-off-by: Martyn Welch <martyn.welch@ge.com>
---
 drivers/vme/bridges/vme_ca91cx42.c |   29 ++++++++++++++---------------
 drivers/vme/bridges/vme_tsi148.c   |   18 +++++++++---------
 2 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c
index a06edbf..92b5719 100644
--- a/drivers/vme/bridges/vme_ca91cx42.c
+++ b/drivers/vme/bridges/vme_ca91cx42.c
@@ -869,14 +869,13 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
 
 	spin_lock(&image->lock);
 
-	/* The following code handles VME address alignment problem
-	 * in order to assure the maximal data width cycle.
-	 * We cannot use memcpy_xxx directly here because it
-	 * may cut data transfer in 8-bits cycles, thus making
-	 * D16 cycle impossible.
-	 * From the other hand, the bridge itself assures that
-	 * maximal configured data cycle is used and splits it
-	 * automatically for non-aligned addresses.
+	/* The following code handles VME address alignment. We cannot use
+	 * memcpy_xxx here because it may cut data transfers in to 8-bit
+	 * cycles when D16 or D32 cycles are required on the VME bus.
+	 * On the other hand, the bridge itself assures that the maximum data
+	 * cycle configured for the transfer is used and splits it
+	 * automatically for non-aligned addresses, so we don't want the
+	 * overhead of needlessly forcing small transfers for the entire cycle.
 	 */
 	if ((uintptr_t)addr & 0x1) {
 		*(u8 *)buf = ioread8(addr);
@@ -896,9 +895,9 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_fromio(buf + done, addr + done, (unsigned int)count);
-		done += count32;
+	while (done < count32) {
+		*(u32 *)(buf + done) = ioread32(addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
@@ -930,7 +929,7 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
 	spin_lock(&image->lock);
 
 	/* Here we apply for the same strategy we do in master_read
-	 * function in order to assure D16 cycle when required.
+	 * function in order to assure the correct cycles.
 	 */
 	if ((uintptr_t)addr & 0x1) {
 		iowrite8(*(u8 *)buf, addr);
@@ -950,9 +949,9 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_toio(addr + done, buf + done, count32);
-		done += count32;
+	while (done < count32) {
+		iowrite32(*(u32 *)(buf + done), addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index 16830d8..21ac513 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -1276,8 +1276,8 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
 	spin_lock(&image->lock);
 
 	/* The following code handles VME address alignment. We cannot use
-	 * memcpy_xxx directly here because it may cut small data transfers in
-	 * to 8-bit cycles, thus making D16 cycle impossible.
+	 * memcpy_xxx here because it may cut data transfers in to 8-bit
+	 * cycles when D16 or D32 cycles are required on the VME bus.
 	 * On the other hand, the bridge itself assures that the maximum data
 	 * cycle configured for the transfer is used and splits it
 	 * automatically for non-aligned addresses, so we don't want the
@@ -1301,9 +1301,9 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_fromio(buf + done, addr + done, count32);
-		done += count32;
+	while (done < count32) {
+		*(u32 *)(buf + done) = ioread32(addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
@@ -1363,7 +1363,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
 	spin_lock(&image->lock);
 
 	/* Here we apply for the same strategy we do in master_read
-	 * function in order to assure D16 cycle when required.
+	 * function in order to assure the correct cycles.
 	 */
 	if ((uintptr_t)addr & 0x1) {
 		iowrite8(*(u8 *)buf, addr);
@@ -1383,9 +1383,9 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
 	}
 
 	count32 = (count - done) & ~0x3;
-	if (count32 > 0) {
-		memcpy_toio(addr + done, buf + done, count32);
-		done += count32;
+	while (done < count32) {
+		iowrite32(*(u32 *)(buf + done), addr + done);
+		done += 4;
 	}
 
 	if ((count - done) & 0x2) {
-- 
1.7.9.5

^ permalink raw reply related	[flat|nested] 22+ messages in thread

* Re: vme_tsi148 question
  2014-02-06  8:40                   ` Martyn Welch
  2014-02-06 13:35                     ` [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour Martyn Welch
@ 2014-02-06 14:07                     ` Michael Kenney
  1 sibling, 0 replies; 22+ messages in thread
From: Michael Kenney @ 2014-02-06 14:07 UTC (permalink / raw)
  To: Martyn Welch; +Cc: Greg KH, driverdev-devel

On Thu, Feb 6, 2014 at 12:40 AM, Martyn Welch <martyn.welch@ge.com> wrote:
>
>
> On 05/02/14 23:21, Michael Kenney wrote:
>>
>> On Wed, Feb 5, 2014 at 1:38 PM, Michael Kenney <mfkenney@gmail.com> wrote:
>>>
>>> On Wed, Feb 5, 2014 at 1:22 PM, Martyn Welch <martyn@welchs.me.uk> wrote:
>>>>
>>>>
>>>>
>>>>
>>>> On 5 February 2014 17:41, Greg KH <gregkh@linuxfoundation.org> wrote:
>>>>>
>>>>>
>>>>> On Tue, Feb 04, 2014 at 06:34:13PM +0000, Martyn Welch wrote:
>>>>>>
>>>>>> On 04/02/14 16:34, Michael Kenney wrote:
>>>>>>>
>>>>>>> Hi Martyn,
>>>>>>>
>>>>>>> On Tue, Feb 4, 2014 at 7:28 AM, Martyn Welch <martyn.welch@ge.com
>>>>>>> <mailto:martyn.welch@ge.com>> wrote:
>>>>>>>
>>>>>>>     On 28/12/13 00:34, Michael Kenney wrote:
>>>>>>>
>>>>>>>         Hi Martyn,
>>>>>>>
>>>>>>>         On Fri, Dec 27, 2013 at 4:23 PM, Martyn Welch
>>>>>>>         <martyn@welchs.me.uk <mailto:martyn@welchs.me.uk>> wrote:
>>>>>>>
>>>>>>>             On 27/12/13 20:15, Michael Kenney wrote:
>>>>>>>
>>>>>>>
>>>>>>>                 We are using the vme_tsi148 bridge driver along with
>>>>>>> the
>>>>>>>                 vme_user
>>>>>>>                 driver to access the VME boards. The A/D board
>>>>>>> requires
>>>>>>>                 D32 bus cycles
>>>>>>>                 and the VME master window is configured accordingly,
>>>>>>>                 however, when
>>>>>>>                 monitoring the bus cycles with a logic analyzer, we
>>>>>>>                 noticed that the
>>>>>>>                 CPU is transferring one byte at a time (i.e. four D8
>>>>>>>                 transfers rather
>>>>>>>                 than one D32).
>>>>>>>
>>>>>>>                 Is this the expected behavior of the tsi148 driver?
>>>>>>>
>>>>>>>
>>>>>>>             Hi Mike,
>>>>>>>
>>>>>>>             This is certainly not the expected behaviour - if the
>>>>>>> window
>>>>>>>             is configured
>>>>>>>             for D32 then it should do 32 bit transfers where
>>>>>>> possible.
>>>>>>>
>>>>>>>             I've heard of this happening recently, but haven't yet
>>>>>>> been
>>>>>>>             able to
>>>>>>>             replicate it. Which VME board are you running Linux on
>>>>>>> and
>>>>>>>             which flavour of
>>>>>>>             Linux?
>>>>>>>
>>>>>>>
>>>>>>>         I'm running Debian 7.2 with kernel 3.2 on a Fastwel CPC600
>>>>>>>         (Pentium M
>>>>>>>         based CPU board).
>>>>>>>
>>>>>>>
>>>>>>>     I haven't forgotten about this, still not sure exactly what is
>>>>>>>     happening.
>>>>>>>
>>>>>>>     Is your install/kernel 32 or 64 bit?
>>>>>>>
>>>>>>>     Are you doing single 32-bit transfers, or are you seeing this on
>>>>>>>     longer transfers (i.e. copying a buffer full of data)?
>>>>>>>
>>>>>>>
>>>>>>> Thanks for getting back to me.
>>>>>>>
>>>>>>> I'm running a 32-bit kernel and I see this behavior on all transfers
>>>>>>> regardless of buffer size.
>>>>>>>
>>>>>>
>>>>>> Gah! Thought I could see what may be causing it in 64-bit kernels, but
>>>>>> not
>>>>>> 32-bit (my x86 asm is not particularly hot).
>>>>>>
>>>>>> I think we /may/ be hitting issues with how the memcpy function gets
>>>>>> implemented on specific architectures. The tsi148 is a PCI/X to VME
>>>>>> bridge,
>>>>>> if it receives a series of 8-bit reads or writes, it translates these
>>>>>> to
>>>>>> 8-bit reads or writes on the VME bus, which is not necessarily what we
>>>>>> want.
>>>>>>
>>>>>> According to the data sheet, the card you are using has an Intel
>>>>>> 6300ESB
>>>>>> ICH, which seems to be PCI/X (so we can rule out PCIe to PCI/X bridges
>>>>>> or
>>>>>> something like that doing nasty things).
>>>>>>
>>>>>> I think (if I follow everything correctly) then the memcpy for 32-bit
>>>>>> is
>>>>>> handled by __memcpy in arch/x86/include/asm/string_32.h:
>>>>>>
>>>>>> static __always_inline void *__memcpy(void *to, const void *from,
>>>>>> size_t
>>>>>> n)
>>>>>> {
>>>>>>          int d0, d1, d2;
>>>>>>          asm volatile("rep ; movsl\n\t"
>>>>>>                       "movl %4,%%ecx\n\t"
>>>>>>                       "andl $3,%%ecx\n\t"
>>>>>>                       "jz 1f\n\t"
>>>>>>                       "rep ; movsb\n\t"
>>>>>>                       "1:"
>>>>>>                       : "=&c" (d0), "=&D" (d1), "=&S" (d2)
>>>>>>                       : "0" (n / 4), "g" (n), "1" ((long)to), "2"
>>>>>> ((long)from)
>>>>>>                       : "memory");
>>>>>>          return to;
>>>>>> }
>>>>>>
>>>>>> I'd expected this function to use movl (32-bit moves) where possible,
>>>>>> but
>>>>>> movsb to get to naturally aligned moves (which is something that we
>>>>>> deal
>>>>>> with in the VME code already to use 16-bit reads where we can).
>>>>>>
>>>>>> Greg (as co-maintainer of the VME subsystem :-) ), Am I reading this
>>>>>> right?
>>>>>
>>>>>
>>>>> Yes, but why would it matter if we copy by bytes, bits, or dwords to a
>>>>> memory-backed bus?  By definition, that shouldn't matter.  If it does
>>>>> matter, then we shouldn't be using memcpy, or relying on the compiler
>>>>> to
>>>>> do the copying, but rather we need to use a write() function instead as
>>>>> this would be IO memory that does care about this type of thing.
>>>>>
>>>>
>>>> The drivers are using the functions memcpy_toio and memcpy_fromio for
>>>> the
>>>> bulk of the transfer, these seem to equate to memcpy on x86.
>>>>
>>>> In this instance it does matter - some devices can only accept certain
>>>> width
>>>> accesses and the VME bridge will translate a 8-bit PCI transfer to a
>>>> 8-bit
>>>> transfer on the VME bus.
>>>>
>>>> So (and I haven't even compile tested this yet), this?:
>>>>
>>>> diff --git a/drivers/vme/bridges/vme_ca91cx42.c
>>>> b/drivers/vme/bridges/vme_ca91cx42.c
>>>> index 1425d22c..0d87ebd 100644
>>>> --- a/drivers/vme/bridges/vme_ca91cx42.c
>>>> +++ b/drivers/vme/bridges/vme_ca91cx42.c
>>>> @@ -894,9 +894,9 @@ static ssize_t ca91cx42_master_read(struct
>>>> vme_master_resource *image,
>>>>          }
>>>>
>>>>          count32 = (count - done) & ~0x3;
>>>> -       if (count32 > 0) {
>>>> -               memcpy_fromio(buf + done, addr + done, (unsigned
>>>> int)count);
>>>> -               done += count32;
>>>> +       while (done < count32) {
>>>> +               *(u32 *)(buf + done) = ioread32(addr + done);
>>>> +               done += 4;
>>>>          }
>>>>
>>>>          if ((count - done) & 0x2) {
>>>> @@ -948,9 +948,9 @@ static ssize_t ca91cx42_master_write(struct
>>>> vme_master_resource *image,
>>>>          }
>>>>
>>>>          count32 = (count - done) & ~0x3;
>>>> -       if (count32 > 0) {
>>>> -               memcpy_toio(addr + done, buf + done, count32);
>>>> -               done += count32;
>>>> +       while (done < count32) {
>>>> +               iowrite32(*(u32 *)(buf + done), addr + done);
>>>> +               done += 4;
>>>>          }
>>>>
>>>>          if ((count - done) & 0x2) {
>>>> diff --git a/drivers/vme/bridges/vme_tsi148.c
>>>> b/drivers/vme/bridges/vme_tsi148.c
>>>> index 5fbd08f..bc82991 100644
>>>> --- a/drivers/vme/bridges/vme_tsi148.c
>>>> +++ b/drivers/vme/bridges/vme_tsi148.c
>>>> @@ -1297,9 +1297,9 @@ static ssize_t tsi148_master_read(struct
>>>> vme_master_resource *image, void *buf,
>>>>          }
>>>>
>>>>          count32 = (count - done) & ~0x3;
>>>> -       if (count32 > 0) {
>>>> -               memcpy_fromio(buf + done, addr + done, count32);
>>>> -               done += count32;
>>>> +       if (done < count32) {
>>>> +               *(u32 *)(buf + done) = ioread32(addr + done);
>>>> +               done += 4;
>>>>          }
>>>>
>>>>          if ((count - done) & 0x2) {
>>>> @@ -1379,9 +1379,9 @@ static ssize_t tsi148_master_write(struct
>>>> vme_master_resource *image, void *buf,
>>>>          }
>>>>
>>>>          count32 = (count - done) & ~0x3;
>>>> -       if (count32 > 0) {
>>>> -               memcpy_toio(addr + done, buf + done, count32);
>>>> -               done += count32;
>>>> +       if (done < count32) {
>>>> +               iowrite32(*(u32 *)(buf + done), addr + done);
>>>> +               done += 4;
>>>>          }
>>>>
>>>>          if ((count - done) & 0x2) {
>>>>
>>>>
>>>>>
>>>>> Does that help?
>>>>>
>>>>
>>>> Yep :-)
>>>>
>>>> Thanks Greg.
>>>
>>>
>>> That certainly looks promising. I can give that patch a try later this
>>> week.
>>>
>>> Thanks.
>>
>>
>> Good news Martyn.
>>
>> I had a bit of time today to test your patch and am happy to say it
>> worked! No more bus errors.
>>
>> Now I can work on getting the actual data acquisition working :-)
>>
>
> Thanks Mike.
>
> Guess you didn't spot the little bug then :-)

Oops, I sure didn't.  I was so happy to not see a bus error on my
simple one-word read/write test that I hadn't gone any further yet
:-).

>
> For the tsi148 I forgot to change the conditional from "if" to "while".
>
> I'll submit a proper patch in a minute,

I'll give that a try today. Thanks.

--Mike
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour
  2014-02-06 13:35                     ` [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour Martyn Welch
@ 2014-02-12 13:20                       ` Martyn Welch
  2014-02-12 16:43                         ` Greg Kroah-Hartman
  0 siblings, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-02-12 13:20 UTC (permalink / raw)
  To: Greg Kroah-Hartman
  Cc: Martyn Welch, Michael Kenney, driverdev-devel, Manohar Vanga

Hmm, can't see this patch on the mailing list, though get send-mail 
cc'ed me and I got it that way. As you've added a later patch that I 
wrote and not this one, can I assume that you didn't get it either Greg?

(This one is needed as well)

Martyn

On 06/02/14 13:35, Martyn Welch wrote:
> The ca91cx42 and tsi148 VME bridges use the width of reads and writes on the
> PCI bus in part to control the width of the cycles on the VME bus. It is
> important that we can control the width of cycles on the VME bus as some VME
> hardware requires cycles of a specific width. The memcpy_toio() and
> memcpy_fromio() functions do not provide sufficient control, so instead loop
> using ioread functions.
>
> Reported-by: Michael Kenney <mfkenney@gmail.com>
> Signed-off-by: Martyn Welch <martyn.welch@ge.com>
> ---
>   drivers/vme/bridges/vme_ca91cx42.c |   29 ++++++++++++++---------------
>   drivers/vme/bridges/vme_tsi148.c   |   18 +++++++++---------
>   2 files changed, 23 insertions(+), 24 deletions(-)
>
> diff --git a/drivers/vme/bridges/vme_ca91cx42.c b/drivers/vme/bridges/vme_ca91cx42.c
> index a06edbf..92b5719 100644
> --- a/drivers/vme/bridges/vme_ca91cx42.c
> +++ b/drivers/vme/bridges/vme_ca91cx42.c
> @@ -869,14 +869,13 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
>
>   	spin_lock(&image->lock);
>
> -	/* The following code handles VME address alignment problem
> -	 * in order to assure the maximal data width cycle.
> -	 * We cannot use memcpy_xxx directly here because it
> -	 * may cut data transfer in 8-bits cycles, thus making
> -	 * D16 cycle impossible.
> -	 * From the other hand, the bridge itself assures that
> -	 * maximal configured data cycle is used and splits it
> -	 * automatically for non-aligned addresses.
> +	/* The following code handles VME address alignment. We cannot use
> +	 * memcpy_xxx here because it may cut data transfers in to 8-bit
> +	 * cycles when D16 or D32 cycles are required on the VME bus.
> +	 * On the other hand, the bridge itself assures that the maximum data
> +	 * cycle configured for the transfer is used and splits it
> +	 * automatically for non-aligned addresses, so we don't want the
> +	 * overhead of needlessly forcing small transfers for the entire cycle.
>   	 */
>   	if ((uintptr_t)addr & 0x1) {
>   		*(u8 *)buf = ioread8(addr);
> @@ -896,9 +895,9 @@ static ssize_t ca91cx42_master_read(struct vme_master_resource *image,
>   	}
>
>   	count32 = (count - done) & ~0x3;
> -	if (count32 > 0) {
> -		memcpy_fromio(buf + done, addr + done, (unsigned int)count);
> -		done += count32;
> +	while (done < count32) {
> +		*(u32 *)(buf + done) = ioread32(addr + done);
> +		done += 4;
>   	}
>
>   	if ((count - done) & 0x2) {
> @@ -930,7 +929,7 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
>   	spin_lock(&image->lock);
>
>   	/* Here we apply for the same strategy we do in master_read
> -	 * function in order to assure D16 cycle when required.
> +	 * function in order to assure the correct cycles.
>   	 */
>   	if ((uintptr_t)addr & 0x1) {
>   		iowrite8(*(u8 *)buf, addr);
> @@ -950,9 +949,9 @@ static ssize_t ca91cx42_master_write(struct vme_master_resource *image,
>   	}
>
>   	count32 = (count - done) & ~0x3;
> -	if (count32 > 0) {
> -		memcpy_toio(addr + done, buf + done, count32);
> -		done += count32;
> +	while (done < count32) {
> +		iowrite32(*(u32 *)(buf + done), addr + done);
> +		done += 4;
>   	}
>
>   	if ((count - done) & 0x2) {
> diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
> index 16830d8..21ac513 100644
> --- a/drivers/vme/bridges/vme_tsi148.c
> +++ b/drivers/vme/bridges/vme_tsi148.c
> @@ -1276,8 +1276,8 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
>   	spin_lock(&image->lock);
>
>   	/* The following code handles VME address alignment. We cannot use
> -	 * memcpy_xxx directly here because it may cut small data transfers in
> -	 * to 8-bit cycles, thus making D16 cycle impossible.
> +	 * memcpy_xxx here because it may cut data transfers in to 8-bit
> +	 * cycles when D16 or D32 cycles are required on the VME bus.
>   	 * On the other hand, the bridge itself assures that the maximum data
>   	 * cycle configured for the transfer is used and splits it
>   	 * automatically for non-aligned addresses, so we don't want the
> @@ -1301,9 +1301,9 @@ static ssize_t tsi148_master_read(struct vme_master_resource *image, void *buf,
>   	}
>
>   	count32 = (count - done) & ~0x3;
> -	if (count32 > 0) {
> -		memcpy_fromio(buf + done, addr + done, count32);
> -		done += count32;
> +	while (done < count32) {
> +		*(u32 *)(buf + done) = ioread32(addr + done);
> +		done += 4;
>   	}
>
>   	if ((count - done) & 0x2) {
> @@ -1363,7 +1363,7 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
>   	spin_lock(&image->lock);
>
>   	/* Here we apply for the same strategy we do in master_read
> -	 * function in order to assure D16 cycle when required.
> +	 * function in order to assure the correct cycles.
>   	 */
>   	if ((uintptr_t)addr & 0x1) {
>   		iowrite8(*(u8 *)buf, addr);
> @@ -1383,9 +1383,9 @@ static ssize_t tsi148_master_write(struct vme_master_resource *image, void *buf,
>   	}
>
>   	count32 = (count - done) & ~0x3;
> -	if (count32 > 0) {
> -		memcpy_toio(addr + done, buf + done, count32);
> -		done += count32;
> +	while (done < count32) {
> +		iowrite32(*(u32 *)(buf + done), addr + done);
> +		done += 4;
>   	}
>
>   	if ((count - done) & 0x2) {
>

-- 
--
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour
  2014-02-12 13:20                       ` Martyn Welch
@ 2014-02-12 16:43                         ` Greg Kroah-Hartman
  2014-02-12 17:50                           ` Martyn Welch
  0 siblings, 1 reply; 22+ messages in thread
From: Greg Kroah-Hartman @ 2014-02-12 16:43 UTC (permalink / raw)
  To: Martyn Welch; +Cc: Michael Kenney, driverdev-devel, Manohar Vanga

On Wed, Feb 12, 2014 at 01:20:33PM +0000, Martyn Welch wrote:
> Hmm, can't see this patch on the mailing list, though get send-mail cc'ed me
> and I got it that way. As you've added a later patch that I wrote and not
> this one, can I assume that you didn't get it either Greg?

No, I didn't get this patch at all, care to resend it?  I only got the
"VME: Correct read/write alignment algorithm" patch from what I can
tell.

thanks,

greg k-h
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour
  2014-02-12 16:43                         ` Greg Kroah-Hartman
@ 2014-02-12 17:50                           ` Martyn Welch
  2014-02-12 18:50                             ` Greg Kroah-Hartman
  0 siblings, 1 reply; 22+ messages in thread
From: Martyn Welch @ 2014-02-12 17:50 UTC (permalink / raw)
  To: Greg Kroah-Hartman; +Cc: Michael Kenney, driverdev-devel, Manohar Vanga

On 12/02/14 16:43, Greg Kroah-Hartman wrote:
> On Wed, Feb 12, 2014 at 01:20:33PM +0000, Martyn Welch wrote:
>> Hmm, can't see this patch on the mailing list, though get send-mail cc'ed me
>> and I got it that way. As you've added a later patch that I wrote and not
>> this one, can I assume that you didn't get it either Greg?
>
> No, I didn't get this patch at all, care to resend it?  I only got the
> "VME: Correct read/write alignment algorithm" patch from what I can
> tell.
>

Resent. Oddly neither patch seems to have reached the mailing list, 
though you have received one of them. Both were sent exactly the same 
way (with git send-email, from the same machine). Confused.

Did you get the patch this time?

Martyn

-- 
Martyn Welch (Lead Software Engineer)  | Registered in England and Wales
GE Intelligent Platforms               | (3828642) at 100 Barbirolli Square
T +44(0)1327322748                     | Manchester, M2 3AB
E martyn.welch@ge.com                  | VAT:GB 927559189
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

* Re: [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour
  2014-02-12 17:50                           ` Martyn Welch
@ 2014-02-12 18:50                             ` Greg Kroah-Hartman
  0 siblings, 0 replies; 22+ messages in thread
From: Greg Kroah-Hartman @ 2014-02-12 18:50 UTC (permalink / raw)
  To: Martyn Welch; +Cc: Michael Kenney, driverdev-devel, Manohar Vanga

On Wed, Feb 12, 2014 at 05:50:25PM +0000, Martyn Welch wrote:
> On 12/02/14 16:43, Greg Kroah-Hartman wrote:
> >On Wed, Feb 12, 2014 at 01:20:33PM +0000, Martyn Welch wrote:
> >>Hmm, can't see this patch on the mailing list, though get send-mail cc'ed me
> >>and I got it that way. As you've added a later patch that I wrote and not
> >>this one, can I assume that you didn't get it either Greg?
> >
> >No, I didn't get this patch at all, care to resend it?  I only got the
> >"VME: Correct read/write alignment algorithm" patch from what I can
> >tell.
> >
> 
> Resent. Oddly neither patch seems to have reached the mailing list, though
> you have received one of them. Both were sent exactly the same way (with git
> send-email, from the same machine). Confused.
> 
> Did you get the patch this time?

Yes, I got 2 copies of it (looks like you sent it twice...)

I also just found my original copy of it as well, it was still in my
TODO patch queue, so sorry for the resend request.  I'll queue it up
later today...

thanks,

greg k-h
_______________________________________________
devel mailing list
devel@linuxdriverproject.org
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel

^ permalink raw reply	[flat|nested] 22+ messages in thread

end of thread, other threads:[~2014-02-12 18:49 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-12-27 20:15 vme_tsi148 question Michael Kenney
2013-12-28  0:23 ` Martyn Welch
2013-12-28  0:34   ` Michael Kenney
2014-01-07 16:14     ` Michael Kenney
2014-01-13 12:00       ` Martyn Welch
2014-01-13 14:49         ` Michael Kenney
2014-01-14  4:07           ` Michael Kenney
2014-01-14  9:39             ` Martyn Welch
2014-01-14 16:25               ` Michael Kenney
2014-02-04 15:28     ` Martyn Welch
     [not found]       ` <CAAq=YFCq0J31mBdh_0j8-39vjskkAMn47Ac8RYdigqPQVgRt5Q@mail.gmail.com>
2014-02-04 18:34         ` Martyn Welch
2014-02-05 17:41           ` Greg KH
2014-02-05 21:22             ` Martyn Welch
2014-02-05 21:38               ` Michael Kenney
2014-02-05 23:21                 ` Michael Kenney
2014-02-06  8:40                   ` Martyn Welch
2014-02-06 13:35                     ` [PATCH] VME: Stop using memcpy_[to|from]io() due to unwanted behaviour Martyn Welch
2014-02-12 13:20                       ` Martyn Welch
2014-02-12 16:43                         ` Greg Kroah-Hartman
2014-02-12 17:50                           ` Martyn Welch
2014-02-12 18:50                             ` Greg Kroah-Hartman
2014-02-06 14:07                     ` vme_tsi148 question Michael Kenney

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.