static uint mmc_spi_readdata(struct mmc *mmc, void *xbuf,
				u32 bcnt, u32 bsize)
{
	struct spi_slave *spi = mmc->priv;
	u8 *buf = xbuf;
	u8 r1;
	u16 crc;
	int i;
	while (bcnt--) {
		for (i = 0; i < RTOUT; i++) {
			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
			if (r1 != 0xff) /* data token */
				break;
		}
		debug("%s:tok%d %x\n", __func__, i, r1);
		if (r1 == SPI_TOKEN_SINGLE) {
			spi_xfer(spi, bsize * 8, NULL, buf, 0);
			spi_xfer(spi, 2 * 8, NULL, &crc, 0);
#ifdef CONFIG_MMC_SPI_CRC_ON
			if (be_to_cpu16(cyg_crc16(buf, bsize)) != crc) {
				debug("%s: CRC error\n", mmc->cfg->name);
				r1 = R1_SPI_COM_CRC;
				break;
			}
#endif
			r1 = 0;
		} else {
			r1 = R1_SPI_ERROR;
			break;
		}
		buf += bsize;
	}
	return r1;
}
Esempio n. 2
0
static uint mmc_spi_readdata(struct mmc_spi_host *host, void *xbuf,
				uint32_t bcnt, uint32_t bsize)
{
	uint8_t *buf = xbuf;
	uint8_t r1;
	uint16_t crc;
	int i;

	while (bcnt--) {
		for (i = 0; i < RTOUT; i++) {
			mmc_spi_readbytes(host, 1, &r1);
			if (r1 != 0xff) /* data token */
				break;
		}
		if (r1 == SPI_TOKEN_SINGLE) {
			mmc_spi_readbytes(host, bsize, buf);
			mmc_spi_readbytes(host, 2, &crc);
#ifdef CONFIG_MMC_SPI_CRC_ON
			if (be16_to_cpu(cyg_crc16(buf, bsize)) != crc) {
				dev_dbg(host->dev, "%s: CRC error\n", __func__);
				r1 = R1_SPI_COM_CRC;
				break;
			}
#endif
			r1 = 0;
		} else {
			r1 = R1_SPI_ERROR;
			break;
		}
		buf += bsize;
	}

	return r1;
}
Esempio n. 3
0
externC void
cyg_start( void )
{
    CYG_TEST_INIT();

    CYG_TEST_INFO("Calculating CRCs");

    if (1500790746l != cyg_posix_crc32(license_txt,sizeof(license_txt)-1)) {
        CYG_TEST_FAIL("Wrong POSIX CRC32 calculation");
    } else {
        CYG_TEST_PASS("POSIX CRC32 calculation");
    }

    if (1247800780 != cyg_crc32(license_txt,sizeof(license_txt)-1)) {
        CYG_TEST_FAIL("Wrong Gary S. Browns' crc32 calculation");
    } else {
        CYG_TEST_PASS("Gary S. Browns' crc32 calculation");
    }

    if (32256 != cyg_crc16(license_txt,sizeof(license_txt)-1)) {
        CYG_TEST_FAIL_FINISH("Wrong 16bit CRC calculation");
    } else {
        CYG_TEST_PASS_FINISH("16bit CRC calculation");
    }
}
Esempio n. 4
0
static uint mmc_spi_writedata(struct mmc_spi_host *host, const void *xbuf,
			      uint32_t bcnt, uint32_t bsize, int multi)
{
	const uint8_t *buf = xbuf;
	uint8_t r1;
	uint16_t crc = 0;
	uint8_t tok[2];
	int i;

	tok[0] = 0xff;
	tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;

	while (bcnt--) {
#ifdef CONFIG_MMC_SPI_CRC_ON
		crc = be16_to_cpu(cyg_crc16((u8 *)buf, bsize));
#endif
		mmc_spi_writebytes(host, 2, tok);
		mmc_spi_writebytes(host, bsize, (void *)buf);
		mmc_spi_writebytes(host, 2, &crc);

		for (i = 0; i < CTOUT; i++) {
			mmc_spi_readbytes(host, 1, &r1);
			if ((r1 & 0x11) == 0x01) /* response token */
				break;
		}

		dev_dbg(host->dev,"%s   : TOKEN%d RESP 0x%X\n", __func__, i, r1);
		if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
			for (i = 0; i < WTOUT; i++) { /* wait busy */
				mmc_spi_readbytes(host, 1, &r1);
				if (i && r1 == 0xff) {
					r1 = 0;
					break;
				}
			}
			if (i == WTOUT) {
				dev_dbg(host->dev, "%s: wtout %x\n", __func__, r1);
				r1 = R1_SPI_ERROR;
				break;
			}
		} else {
			dev_dbg(host->dev, "%s: err %x\n", __func__, r1);
			r1 = R1_SPI_COM_CRC;
			break;
		}
		buf += bsize;
	}

	if (multi && bcnt == -1) { /* stop multi write */
		tok[1] = SPI_TOKEN_STOP_TRAN;
		mmc_spi_writebytes(host, 2, tok);
		for (i = 0; i < WTOUT; i++) { /* wait busy */
			mmc_spi_readbytes(host, 1, &r1);
			if (i && r1 == 0xff) {
				r1 = 0;
				break;
			}
		}
		if (i == WTOUT) {
			dev_dbg(host->dev, "%s: wstop %x\n", __func__, r1);
			r1 = R1_SPI_ERROR;
		}
	}

	return r1;
}
static uint mmc_spi_writedata(struct mmc *mmc, const void *xbuf,
			      u32 bcnt, u32 bsize, int multi)
{
	struct spi_slave *spi = mmc->priv;
	const u8 *buf = xbuf;
	u8 r1;
	u16 crc;
	u8 tok[2];
	int i;
	tok[0] = 0xff;
	tok[1] = multi ? SPI_TOKEN_MULTI_WRITE : SPI_TOKEN_SINGLE;
	while (bcnt--) {
#ifdef CONFIG_MMC_SPI_CRC_ON
		crc = cpu_to_be16(cyg_crc16((u8 *)buf, bsize));
#endif
		spi_xfer(spi, 2 * 8, tok, NULL, 0);
		spi_xfer(spi, bsize * 8, buf, NULL, 0);
		spi_xfer(spi, 2 * 8, &crc, NULL, 0);
		for (i = 0; i < CTOUT; i++) {
			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
			if ((r1 & 0x10) == 0) /* response token */
				break;
		}
		debug("%s:tok%d %x\n", __func__, i, r1);
		if (SPI_MMC_RESPONSE_CODE(r1) == SPI_RESPONSE_ACCEPTED) {
			for (i = 0; i < WTOUT; i++) { /* wait busy */
				spi_xfer(spi, 1 * 8, NULL, &r1, 0);
				if (i && r1 == 0xff) {
					r1 = 0;
					break;
				}
			}
			if (i == WTOUT) {
				debug("%s:wtout %x\n", __func__, r1);
				r1 = R1_SPI_ERROR;
				break;
			}
		} else {
			debug("%s: err %x\n", __func__, r1);
			r1 = R1_SPI_COM_CRC;
			break;
		}
		buf += bsize;
	}
	if (multi && bcnt == -1) { /* stop multi write */
		tok[1] = SPI_TOKEN_STOP_TRAN;
		spi_xfer(spi, 2 * 8, tok, NULL, 0);
		for (i = 0; i < WTOUT; i++) { /* wait busy */
			spi_xfer(spi, 1 * 8, NULL, &r1, 0);
			if (i && r1 == 0xff) {
				r1 = 0;
				break;
			}
		}
		if (i == WTOUT) {
			debug("%s:wstop %x\n", __func__, r1);
			r1 = R1_SPI_ERROR;
		}
	}
	return r1;
}
Esempio n. 6
0
static int
xyzModem_get_hdr (void)
{
  char c;
  int res;
  bool hdr_found = false;
  int i, can_total, hdr_chars;
  unsigned short cksum;

  ZM_DEBUG (zm_new ());
  /* Find the start of a header */
  can_total = 0;
  hdr_chars = 0;

  if (xyz.tx_ack)
    {
      CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
      xyz.tx_ack = false;
    }
  while (!hdr_found)
    {
      res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
      ZM_DEBUG (zm_save (c));
      if (res)
	{
	  hdr_chars++;
	  switch (c)
	    {
	    case SOH:
	      xyz.total_SOH++;
	    case STX:
	      if (c == STX)
		xyz.total_STX++;
	      hdr_found = true;
	      break;
	    case CAN:
	      xyz.total_CAN++;
	      ZM_DEBUG (zm_dump (__LINE__));
	      if (++can_total == xyzModem_CAN_COUNT)
		{
		  return xyzModem_cancel;
		}
	      else
		{
		  /* Wait for multiple CAN to avoid early quits */
		  break;
		}
	    case EOT:
	      /* EOT only supported if no noise */
	      if (hdr_chars == 1)
		{
		  CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
		  ZM_DEBUG (zm_dprintf ("ACK on EOT #%d\n", __LINE__));
		  ZM_DEBUG (zm_dump (__LINE__));
		  return xyzModem_eof;
		}
	    default:
	      /* Ignore, waiting for start of header */
	      ;
	    }
	}
      else
	{
	  /* Data stream timed out */
	  xyzModem_flush ();	/* Toss any current input */
	  ZM_DEBUG (zm_dump (__LINE__));
	  CYGACC_CALL_IF_DELAY_US ((cyg_int32) 250000);
	  return xyzModem_timeout;
	}
    }

  /* Header found, now read the data */
  res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.blk);
  ZM_DEBUG (zm_save (xyz.blk));
  if (!res)
    {
      ZM_DEBUG (zm_dump (__LINE__));
      return xyzModem_timeout;
    }
  res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.cblk);
  ZM_DEBUG (zm_save (xyz.cblk));
  if (!res)
    {
      ZM_DEBUG (zm_dump (__LINE__));
      return xyzModem_timeout;
    }
  xyz.len = (c == SOH) ? 128 : 1024;
  xyz.bufp = xyz.pkt;
  for (i = 0; i < xyz.len; i++)
    {
      res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
      ZM_DEBUG (zm_save (c));
      if (res)
	{
	  xyz.pkt[i] = c;
	}
      else
	{
	  ZM_DEBUG (zm_dump (__LINE__));
	  return xyzModem_timeout;
	}
    }
  res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc1);
  ZM_DEBUG (zm_save (xyz.crc1));
  if (!res)
    {
      ZM_DEBUG (zm_dump (__LINE__));
      return xyzModem_timeout;
    }
  if (xyz.crc_mode)
    {
      res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, (char *) &xyz.crc2);
      ZM_DEBUG (zm_save (xyz.crc2));
      if (!res)
	{
	  ZM_DEBUG (zm_dump (__LINE__));
	  return xyzModem_timeout;
	}
    }
  ZM_DEBUG (zm_dump (__LINE__));
  /* Validate the message */
  if ((xyz.blk ^ xyz.cblk) != (unsigned char) 0xFF)
    {
      ZM_DEBUG (zm_dprintf
		("Framing error - blk: %x/%x/%x\n", xyz.blk, xyz.cblk,
		 (xyz.blk ^ xyz.cblk)));
      ZM_DEBUG (zm_dump_buf (xyz.pkt, xyz.len));
      xyzModem_flush ();
      return xyzModem_frame;
    }
  /* Verify checksum/CRC */
  if (xyz.crc_mode)
    {
      cksum = cyg_crc16 (xyz.pkt, xyz.len);
      if (cksum != ((xyz.crc1 << 8) | xyz.crc2))
	{
	  ZM_DEBUG (zm_dprintf ("CRC error - recvd: %02x%02x, computed: %x\n",
				xyz.crc1, xyz.crc2, cksum & 0xFFFF));
	  return xyzModem_cksum;
	}
    }
  else
    {
      cksum = 0;
      for (i = 0; i < xyz.len; i++)
	{
	  cksum += xyz.pkt[i];
	}
      if (xyz.crc1 != (cksum & 0xFF))
	{
	  ZM_DEBUG (zm_dprintf
		    ("Checksum error - recvd: %x, computed: %x\n", xyz.crc1,
		     cksum & 0xFF));
	  return xyzModem_cksum;
	}
    }
  /* If we get here, the message passes [structural] muster */
  return 0;
}
Esempio n. 7
0
int
xyzModem_stream_read (char *buf, int size, int *err)
{
    int stat, total, len;
    int retries;

    total = 0;
    stat = xyzModem_cancel;
    /* Try and get 'size' bytes into the buffer */
    while (!xyz.at_eof && (size > 0))
    {
        if (xyz.len == 0)
        {
            retries = xyzModem_MAX_RETRIES;
            while (retries-- > 0)
            {
                stat = xyzModem_get_hdr ();
                if (stat == 0)
                {
                    if (xyz.blk == xyz.next_blk)
                    {
                        xyz.tx_ack = true;
                        ZM_DEBUG (zm_dprintf
                                  ("ACK block %d (%d)\n", xyz.blk, __LINE__));
                        xyz.next_blk = (xyz.next_blk + 1) & 0xFF;

#if defined(xyzModem_zmodem) || defined(USE_YMODEM_LENGTH)
                        if (xyz.mode == xyzModem_xmodem || xyz.file_length == 0)
                        {
#else
                        if (1)
                        {
#endif
                            /* Data blocks can be padded with ^Z (EOF) characters */
                            /* This code tries to detect and remove them */
                            if ((xyz.bufp[xyz.len - 1] == EOF) &&
                                    (xyz.bufp[xyz.len - 2] == EOF) &&
                                    (xyz.bufp[xyz.len - 3] == EOF))
                            {
                                while (xyz.len
                                        && (xyz.bufp[xyz.len - 1] == EOF))
                                {
                                    xyz.len--;
                                }
                            }
                        }

#ifdef USE_YMODEM_LENGTH
                        /*
                         * See if accumulated length exceeds that of the file.
                         * If so, reduce size (i.e., cut out pad bytes)
                         * Only do this for Y-modem (and Z-modem should it ever
                         * be supported since it can fall back to Y-modem mode).
                         */
                        if (xyz.mode != xyzModem_xmodem && 0 != xyz.file_length)
                        {
                            xyz.read_length += xyz.len;
                            if (xyz.read_length > xyz.file_length)
                            {
                                xyz.len -= (xyz.read_length - xyz.file_length);
                            }
                        }
#endif
                        break;
                    }
                    else if (xyz.blk == ((xyz.next_blk - 1) & 0xFF))
                    {
                        /* Just re-ACK this so sender will get on with it */
                        CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                        continue;	/* Need new header */
                    }
                    else
                    {
                        stat = xyzModem_sequence;
                    }
                }
                if (stat == xyzModem_cancel)
                {
                    break;
                }
                if (stat == xyzModem_eof)
                {
                    CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                    ZM_DEBUG (zm_dprintf ("ACK (%d)\n", __LINE__));
                    if (xyz.mode == xyzModem_ymodem)
                    {
                        CYGACC_COMM_IF_PUTC (*xyz.__chan,
                                             (xyz.crc_mode ? 'C' : NAK));
                        xyz.total_retries++;
                        ZM_DEBUG (zm_dprintf ("Reading Final Header\n"));
                        stat = xyzModem_get_hdr ();
                        CYGACC_COMM_IF_PUTC (*xyz.__chan, ACK);
                        ZM_DEBUG (zm_dprintf ("FINAL ACK (%d)\n", __LINE__));
                    }
                    xyz.at_eof = true;
                    break;
                }
                CYGACC_COMM_IF_PUTC (*xyz.__chan, (xyz.crc_mode ? 'C' : NAK));
                xyz.total_retries++;
                ZM_DEBUG (zm_dprintf ("NAK (%d)\n", __LINE__));
            }
            if (stat < 0)
            {
                *err = stat;
                xyz.len = -1;
                return total;
            }
        }
        /* Don't "read" data from the EOF protocol package */
        if (!xyz.at_eof)
        {
            len = xyz.len;
            if (size < len)
                len = size;
            memcpy (buf, xyz.bufp, len);
            size -= len;
            buf += len;
            total += len;
            xyz.len -= len;
            xyz.bufp += len;
        }
    }
    return total;
}

int
xyzModem_stream_write(ulong src,long size)
{
    char c;
    unsigned char  *psrc;
    unsigned short cksum;
    int ultlen = 0;
    int total = 0;
    int retry, i, res;
    int flag_ok = 0;
    int flag_frame = 0;
    psrc =(unsigned char *)src;
    xyz.blk  = 1;
    xyz.cblk = ~xyz.blk;
    xyz.len  = xyzModem_1k;

    for (retry = 0; retry < 300; ++retry) {
        res = CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
        if (res) {
            switch (c) {
            case 'C':
                xyz.crc_mode = true;
                flag_ok = 1;
                ZM_DEBUG (zm_dprintf ("Receive char CRC***\n"));
                break;
            case NAK:
                xyz.crc_mode = false;
                flag_ok = 1;
                ZM_DEBUG (zm_dprintf ("Receive char NAK***\n"));
                break;
            case CAN:
                ZM_DEBUG (zm_dprintf ("Receive char cancel***\n"));
                CYGACC_COMM_IF_GETC_TIMEOUT (*xyz.__chan, &c);
                if (c == CAN) {
                    serial_putc_raw(ACK);
                    xyzModem_flush ();
                    return -1;
                }
                break;
            default:
                ZM_DEBUG (zm_dprintf ("Receive  char %x***\n",c));
                break;
            }
        }
        if (flag_ok == 1)
            break;
    }

    if (flag_ok == 0) {
        serial_putc_raw(CAN);
        serial_putc_raw(CAN);
        serial_putc_raw(CAN);
        xyzModem_flush ();
        return -2;
    }

    while(1) {
        flag_frame = 0;
        ultlen = size - total;

        if (ultlen > xyz.len)
            ultlen = xyz.len;

        if (ultlen > 0) {
            memcpy (xyz.pkt, &psrc[total], ultlen);
            if (ultlen < xyz.len) {
                memset (&xyz.pkt[ultlen], EOF, xyz.len-ultlen);
            }

            if (xyz.crc_mode) {
                cksum = cyg_crc16(xyz.pkt, xyz.len);
                xyz.crc1 = (cksum >> 8) & 0xFF;
                xyz.crc2 = cksum & 0xFF;
                ZM_DEBUG (zm_dprintf ("add crc check***\n"));
            } else {
Esempio n. 8
0
static int xyzModem_get_hdr(void)
{
	char c;
	int res;
	unsigned int hdr_found = 0;
	int i, can_total, hdr_chars;
	unsigned short cksum;

	/* Find the start of a header */
	can_total = 0;
	hdr_chars = 0;

	if(xyz.tx_ack){
		putc(ACK);
		xyz.tx_ack = 0;
	}

	while(!hdr_found){
		res = comm_if_getc_tout(&c);

		if(res){
			hdr_chars++;

			switch(c){
			case SOH:
				xyz.total_SOH++;
			case STX:
				if(c == STX)
					xyz.total_STX++;

				hdr_found = 1;
				break;
			case CAN:
				xyz.total_CAN++;

				if(++can_total == xyzModem_CAN_COUNT){
					return xyzModem_cancel;
				} else {
					/* Wait for multiple CAN to avoid early quits */
					break;
				}
			case EOT:
				/* EOT only supported if no noise */
				if(hdr_chars == 1){
					putc(ACK);
					return xyzModem_eof;
				}
			default:
				/* Ignore, waiting for start of header */
				;
			}
		} else {
			/* Data stream timed out */
			xyzModem_flush(); /* Toss any current input */
			udelay(250000);
			return xyzModem_timeout;
		}
	}

	/* Header found, now read the data */
	res = comm_if_getc_tout((char *)&xyz.blk);
	if(!res){
		return xyzModem_timeout;
	}

	res = comm_if_getc_tout((char *)&xyz.cblk);
	if(!res){
		return xyzModem_timeout;
	}

	xyz.len = (c == SOH) ? 128 : 1024;
	xyz.bufp = xyz.pkt;
	for(i = 0;  i < xyz.len;  i++){
		res = comm_if_getc_tout(&c);
		if(res){
			xyz.pkt[i] = c;
		} else {
			return xyzModem_timeout;
		}
	}

	res = comm_if_getc_tout((char *)&xyz.crc1);
	if(!res){
		return xyzModem_timeout;
	}

	if(xyz.crc_mode){
		res = comm_if_getc_tout((char *)&xyz.crc2);
		if(!res){
			return xyzModem_timeout;
		}
	}

	/* Validate the message */
	if((xyz.blk ^ xyz.cblk) != (unsigned char)0xFF){
		xyzModem_flush();
		return xyzModem_frame;
	}

	/* Verify checksum/CRC */
	if(xyz.crc_mode){
		cksum = cyg_crc16(xyz.pkt, xyz.len);
		if(cksum != ((xyz.crc1 << 8) | xyz.crc2)){
			return xyzModem_cksum;
		}
	} else {
		cksum = 0;
		for(i = 0;  i < xyz.len;  i++){
			cksum += xyz.pkt[i];
		}

		if(xyz.crc1 != (cksum & 0xFF)){
			return xyzModem_cksum;
		}
	}

	/* If we get here, the message passes [structural] muster */
	return 0;
}