VME driver patch for PowerPC [Continued]

Oliver Korpilla okorpil at fh-landshut.de
Tue Jun 8 19:05:04 EST 2004


Hello!

I modified your vmemcpy() function and put it into driver master module like
below: (message continues after code)

/*===========================================================================
  * Copy data using the width specified
  * Returns: 0 or -1
  */
int vmemcpy_fromio(void *dest, const void *src, int nelem, int dw)
{
   int ii;

   /*
    * Depending on data width use byte, word or long word accesses.
    */
   switch (dw) {
   case VME_D8:
     {
       const uint8_t *s = src;
       uint8_t *d = dest;

       for (ii = 0; ii < nelem; ++ii, ++s, ++d)
	*d = readb(s);
     }
     break;
   case VME_D16:
     {
       const uint16_t *s = src;
       uint16_t *d = dest;

       for (ii = 0; ii < nelem; ++ii, ++s, ++d)
	*d = readw(s);
     }
     break;
   case VME_D32:
     {
       const uint32_t *s = src;
       uint32_t *d = dest;

       for (ii = 0; ii < nelem; ++ii, ++s, ++d)
	*d = readl(s);
     }
     break;
   default:
     return -EINVAL;
   }

   return 0;
}

/*===========================================================================
  * Copy data using the width specified
  * Returns: 0 or -1
  */
int vmemcpy_toio(void *dest, const void *src, int nelem, int dw)
{
   int ii;

   /*
    * Depending on data width use byte, word or long word accesses.
    */
   switch (dw) {
   case VME_D8:
     {
       const uint8_t *s = src;
       uint8_t *d = dest;

       for (ii = 0; ii < nelem; ++ii, ++s, ++d)
	writeb(*s, d);
     }
     break;
   case VME_D16:
     {
       const uint16_t *s = src;
       uint16_t *d = dest;

       for (ii = 0; ii < nelem; ++ii, ++s, ++d)
	writew(*s, d);
     }
     break;
   case VME_D32:
     {
       const uint32_t *s = src;
       uint32_t *d = dest;

       for (ii = 0; ii < nelem; ++ii, ++s, ++d)
	writel(*s, d);
     }
     break;
   default:
     return -EINVAL;
   }

   return 0;
}

I left out VME_D64 because it has no direct corresponding readll() and writell()
in include/asm-ppc/io.h.

I tested it with reading 4 bytes, VME data width VME_D8, writing 4 byte, and
reading 4 byte, giving me the following VME tracer results: (message continues
after trace)
          |   TIME     BUS  ADDRESS    DATA   R/W SIZE  STAT   IRQ*  IACK* AM EX
          |   rel.    LEVEL                                  7654321 OC IO
     -----+---------------------------------------------------------------------
=>   TRIG|   0.00 us  3   01000000  ....DE..  R  UBYTE  OK  -------  1 1  0D 1
         1|   1.04 us  3   01000001  ......AD  R  LBYTE  OK  -------  1 1  0D 1
         2|   1.08 us  3   01000002  ....FA..  R  UBYTE  OK  -------  1 1  0D 1
         3|   1.08 us  3   01000003  ......CE  R  LBYTE  OK  -------  1 1  0D 1
         4| 50.892 ms  3   01000000  ....AF..  W  UBYTE  OK  -------  1 1  0D 1
         5|   0.40 us  3   01000001  ......FE  W  LBYTE  OK  -------  1 1  0D 1
         6|   0.44 us  3   01000002  ....AF..  W  UBYTE  OK  -------  1 1  0D 1
         7|   0.44 us  3   01000003  ......FE  W  LBYTE  OK  -------  1 1  0D 1
         8| 38.440 ms  3   01000000  ....AF..  R  UBYTE  OK  -------  1 1  0D 1
         9|   1.24 us  3   01000001  ......FE  R  LBYTE  OK  -------  1 1  0D 1
        10|   1.08 us  3   01000002  ....AF..  R  UBYTE  OK  -------  1 1  0D 1
        11|   1.08 us  3   01000003  ......FE  R  LBYTE  OK  -------  1 1  0D 1

So, this corresponds to reading successfully 0xDEADFACE bytewise from the bus,
writing 0xAFFEAFFE back, and reading that value again successfully
(vmemcpy_fromio - vmemcpy_toio - vmemcpy_fromio), with a data width of VME_D8.

I guess it should be possible to implement read() and write() in terms of these
function, though I'm not entirely sure how to determine how to select the master
window from user space.

Any ideas on read() and write()?

With kind regards,
Oliver Korpilla

** Sent via the linuxppc-embedded mail list. See http://lists.linuxppc.org/





More information about the Linuxppc-embedded mailing list