Esempio n. 1
0
bool TopologicalGraph::FindPlanarMap()
  {if(planarMap() < 0){if(debug())DebugPrintf("  EXIST planarMap < 0");return false;}
  bool Connect= CheckConnected();

  if(planarMap() == 1) 
      {if(debug())DebugPrintf("  EXIST planarMap = 1");
      return true;
      }
  if(Connect && ComputeGenus() == 0)
      {if(debug())DebugPrintf("Good Genus");
      planarMap() = 1;return true;
      }
  if(Connect && Set(tvertex()).exist(PROP_COORD)) // Geometric Graph
      {GeometricGraph GG(*this);
      if(debug())DebugPrintf("Executing geometric cir");
      Prop1<int> maptype(Set(),PROP_MAPTYPE,0);
      int _maptype = maptype();
      svector<tbrin> cir0,acir0;
      cir0 = cir; acir0 = acir;
      if(GG.ComputeGeometricCir() == 0)
          {if(debug())DebugPrintf("Using geometric map");
          planarMap() = 1;return true;
          }
      maptype() =  _maptype;
      cir.vector() = cir0; acir.vector() = acir0; 
      }
  if(debug())DebugPrintf("FindPlanarMap:LRALGO");
  int ret = Planarity();
  if(ret  == 1){planarMap() = 1; return true;}
  else planarMap() = -1;
  return false;
  }
Esempio n. 2
0
static int mmc_spi_request(struct mci_host *mci, struct mci_cmd *cmd, struct mci_data *data)
{
	struct mmc_spi_host	*host = to_spi_host(mci);
	uint8_t r1;
	int i;
	int ret = 0;

	dev_dbg(host->dev, "%s     : CMD%02d, RESP %s, ARG 0x%X\n", __func__,
	      cmd->cmdidx, maptype(cmd), cmd->cmdarg);

	r1 = mmc_spi_command_send(host, cmd);

	cmd->response[0] = r1;

	if (r1 == 0xff) { /* no response */
		ret = -ETIME;
		goto done;
	} else if (r1 & R1_SPI_COM_CRC) {
		ret = -ECOMM;
		goto done;
	} else if (r1 & ~R1_SPI_IDLE) { /* other errors */
		ret = -ETIME;
		goto done;
	} else if (cmd->resp_type == MMC_RSP_R2) {
		r1 = mmc_spi_readdata(host, cmd->response, 1, 16);
		for (i = 0; i < 4; i++)
			cmd->response[i] = be32_to_cpu(cmd->response[i]);
		dev_dbg(host->dev, "MMC_RSP_R2 -> %x %x %x %x\n", cmd->response[0], cmd->response[1],
		      cmd->response[2], cmd->response[3]);
	} else if (!data) {
		switch (cmd->cmdidx) {
		case SD_CMD_SEND_IF_COND:
		case MMC_CMD_SPI_READ_OCR:
			mmc_spi_readbytes(host, 4, cmd->response);
			cmd->response[0] = be32_to_cpu(cmd->response[0]);
			break;
		}
	} else {
		if (data->flags == MMC_DATA_READ) {
			dev_dbg(host->dev, "%s     : DATA READ, %x blocks, bsize = 0x%X\n", __func__,
			      data->blocks, data->blocksize);
			r1 = mmc_spi_readdata(host, data->dest,
				data->blocks, data->blocksize);
		} else if  (data->flags == MMC_DATA_WRITE) {
			dev_dbg(host->dev, "%s     : DATA WRITE, %x blocks, bsize = 0x%X\n", __func__,
			      data->blocks, data->blocksize);
			r1 = mmc_spi_writedata(host, data->src,
				data->blocks, data->blocksize,
				(cmd->cmdidx == MMC_CMD_WRITE_MULTIPLE_BLOCK));
		}
		if (r1 & R1_SPI_COM_CRC)
			ret = -ECOMM;
		else if (r1)
			ret = -ETIME;
	}

done:
	mmc_cs_off(host);
	return ret;

return  0;

}
/* return zero, else negative errno after setting cmd->error */
static int mmc_spi_response_get(struct mmc_spi_host *host,
		struct mmc_command *cmd, int cs_on)
{
	u8	*cp = host->data->status;
	u8	*end = cp + host->t.len;
	int	value = 0;
	int	bitshift;
	u8 	leftover = 0;
	unsigned short rotator;
	int 	i;
	char	tag[32];

	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
		cmd->opcode, maptype(cmd));

	/* Except for data block reads, the whole response will already
	 * be stored in the scratch buffer.  It's somewhere after the
	 * command and the first byte we read after it.  We ignore that
	 * first byte.  After STOP_TRANSMISSION command it may include
	 * two data bits, but otherwise it's all ones.
	 */
	cp += 8;
	while (cp < end && *cp == 0xff)
		cp++;

	/* Data block reads (R1 response types) may need more data... */
	if (cp == end) {
		cp = host->data->status;
		end = cp+1;

		/* Card sends N(CR) (== 1..8) bytes of all-ones then one
		 * status byte ... and we already scanned 2 bytes.
		 *
		 * REVISIT block read paths use nasty byte-at-a-time I/O
		 * so it can always DMA directly into the target buffer.
		 * It'd probably be better to memcpy() the first chunk and
		 * avoid extra i/o calls...
		 *
		 * Note we check for more than 8 bytes, because in practice,
		 * some SD cards are slow...
		 */
		for (i = 2; i < 16; i++) {
			value = mmc_spi_readbytes(host, 1);
			if (value < 0)
				goto done;
			if (*cp != 0xff)
				goto checkstatus;
		}
		value = -ETIMEDOUT;
		goto done;
	}

checkstatus:
	bitshift = 0;
	if (*cp & 0x80)	{
		/* Houston, we have an ugly card with a bit-shifted response */
		rotator = *cp++ << 8;
		/* read the next byte */
		if (cp == end) {
			value = mmc_spi_readbytes(host, 1);
			if (value < 0)
				goto done;
			cp = host->data->status;
			end = cp+1;
		}
		rotator |= *cp++;
		while (rotator & 0x8000) {
			bitshift++;
			rotator <<= 1;
		}
		cmd->resp[0] = rotator >> 8;
		leftover = rotator;
	} else {
Esempio n. 4
0
/* Issue command and read its response.
 * Returns zero on success, negative for error.
 *
 * On error, caller must cope with mmc core retry mechanism.  That
 * means immediate low-level resubmit, which affects the bus lock...
 */
static int
mmc_spi_command_send(struct mmc_spi_host *host,
		struct mmc_request *mrq,
		struct mmc_command *cmd, int cs_on)
{
	struct scratch		*data = host->data;
	u8			*cp = data->status;
	u32			arg = cmd->arg;
	int			status;
	struct spi_transfer	*t;

	/* We can handle most commands (except block reads) in one full
	 * duplex I/O operation before either starting the next transfer
	 * (data block or command) or else deselecting the card.
	 *
	 * First, write 7 bytes:
	 *  - an all-ones byte to ensure the card is ready
	 *  - opcode byte (plus start and transmission bits)
	 *  - four bytes of big-endian argument
	 *  - crc7 (plus end bit) ... always computed, it's cheap
	 *
	 * We init the whole buffer to all-ones, which is what we need
	 * to write while we're reading (later) response data.
	 */
	memset(cp++, 0xff, sizeof(data->status));

	*cp++ = 0x40 | cmd->opcode;
	*cp++ = (u8)(arg >> 24);
	*cp++ = (u8)(arg >> 16);
	*cp++ = (u8)(arg >> 8);
	*cp++ = (u8)arg;
	*cp++ = (crc7(0, &data->status[1], 5) << 1) | 0x01;

	/* Then, read up to 13 bytes (while writing all-ones):
	 *  - N(CR) (== 1..8) bytes of all-ones
	 *  - status byte (for all response types)
	 *  - the rest of the response, either:
	 *      + nothing, for R1 or R1B responses
	 *	+ second status byte, for R2 responses
	 *	+ four data bytes, for R3 and R7 responses
	 *
	 * Finally, read some more bytes ... in the nice cases we know in
	 * advance how many, and reading 1 more is always OK:
	 *  - N(EC) (== 0..N) bytes of all-ones, before deselect/finish
	 *  - N(RC) (== 1..N) bytes of all-ones, before next command
	 *  - N(WR) (== 1..N) bytes of all-ones, before data write
	 *
	 * So in those cases one full duplex I/O of at most 21 bytes will
	 * handle the whole command, leaving the card ready to receive a
	 * data block or new command.  We do that whenever we can, shaving
	 * CPU and IRQ costs (especially when using DMA or FIFOs).
	 *
	 * There are two other cases, where it's not generally practical
	 * to rely on a single I/O:
	 *
	 *  - R1B responses need at least N(EC) bytes of all-zeroes.
	 *
	 *    In this case we can *try* to fit it into one I/O, then
	 *    maybe read more data later.
	 *
	 *  - Data block reads are more troublesome, since a variable
	 *    number of padding bytes precede the token and data.
	 *      + N(CX) (== 0..8) bytes of all-ones, before CSD or CID
	 *      + N(AC) (== 1..many) bytes of all-ones
	 *
	 *    In this case we currently only have minimal speedups here:
	 *    when N(CR) == 1 we can avoid I/O in response_get().
	 */
	if (cs_on && (mrq->data->flags & MMC_DATA_READ)) {
		cp += 2;	/* min(N(CR)) + status */
		/* R1 */
	} else {
		cp += 10;	/* max(N(CR)) + status + min(N(RC),N(WR)) */
		if (cmd->flags & MMC_RSP_SPI_S2)	/* R2/R5 */
			cp++;
		else if (cmd->flags & MMC_RSP_SPI_B4)	/* R3/R4/R7 */
			cp += 4;
		else if (cmd->flags & MMC_RSP_BUSY)	/* R1B */
			cp = data->status + sizeof(data->status);
		/* else:  R1 (most commands) */
	}

	dev_dbg(&host->spi->dev, "  mmc_spi: CMD%d, resp %s\n",
		cmd->opcode, maptype(cmd));

	/* send command, leaving chipselect active */
	spi_message_init(&host->m);

	t = &host->t;
	memset(t, 0, sizeof(*t));
	t->tx_buf = t->rx_buf = data->status;
	t->tx_dma = t->rx_dma = host->data_dma;
	t->len = cp - data->status;
	t->cs_change = 1;
	spi_message_add_tail(t, &host->m);

	if (host->dma_dev) {
		host->m.is_dma_mapped = 1;
		dma_sync_single_for_device(host->dma_dev,
				host->data_dma, sizeof(*host->data),
				DMA_BIDIRECTIONAL);
	}
	status = spi_sync(host->spi, &host->m);

	if (host->dma_dev)
		dma_sync_single_for_cpu(host->dma_dev,
				host->data_dma, sizeof(*host->data),
				DMA_BIDIRECTIONAL);
	if (status < 0) {
		dev_dbg(&host->spi->dev, "  ... write returned %d\n", status);
		cmd->error = status;
		return status;
	}

	/* after no-data commands and STOP_TRANSMISSION, chipselect off */
	return mmc_spi_response_get(host, cmd, cs_on);
}
Esempio n. 5
0
/* return zero, else negative errno after setting cmd->error */
static int mmc_spi_response_get(struct mmc_spi_host *host,
		struct mmc_command *cmd, int cs_on)
{
	u8	*cp = host->data->status;
	u8	*end = cp + host->t.len;
	int	value = 0;
	char	tag[32];

	snprintf(tag, sizeof(tag), "  ... CMD%d response SPI_%s",
		cmd->opcode, maptype(cmd));

	/* Except for data block reads, the whole response will already
	 * be stored in the scratch buffer.  It's somewhere after the
	 * command and the first byte we read after it.  We ignore that
	 * first byte.  After STOP_TRANSMISSION command it may include
	 * two data bits, but otherwise it's all ones.
	 */
	cp += 8;
	while (cp < end && *cp == 0xff)
		cp++;

	/* Data block reads (R1 response types) may need more data... */
	if (cp == end) {
		unsigned	i;

		cp = host->data->status;

		/* Card sends N(CR) (== 1..8) bytes of all-ones then one
		 * status byte ... and we already scanned 2 bytes.
		 *
		 * REVISIT block read paths use nasty byte-at-a-time I/O
		 * so it can always DMA directly into the target buffer.
		 * It'd probably be better to memcpy() the first chunk and
		 * avoid extra i/o calls...
		 */
		for (i = 2; i < 9; i++) {
			value = mmc_spi_readbytes(host, 1);
			if (value < 0)
				goto done;
			if (*cp != 0xff)
				goto checkstatus;
		}
		value = -ETIMEDOUT;
		goto done;
	}

checkstatus:
	if (*cp & 0x80) {
		dev_dbg(&host->spi->dev, "%s: INVALID RESPONSE, %02x\n",
					tag, *cp);
		value = -EBADR;
		goto done;
	}

	cmd->resp[0] = *cp++;
	cmd->error = 0;

	/* Status byte: the entire seven-bit R1 response.  */
	if (cmd->resp[0] != 0) {
		if ((R1_SPI_PARAMETER | R1_SPI_ADDRESS
					| R1_SPI_ILLEGAL_COMMAND)
				& cmd->resp[0])
			value = -EINVAL;
		else if (R1_SPI_COM_CRC & cmd->resp[0])
			value = -EILSEQ;
		else if ((R1_SPI_ERASE_SEQ | R1_SPI_ERASE_RESET)
				& cmd->resp[0])
			value = -EIO;
		/* else R1_SPI_IDLE, "it's resetting" */
	}

	switch (mmc_spi_resp_type(cmd)) {

	/* SPI R1B == R1 + busy; STOP_TRANSMISSION (for multiblock reads)
	 * and less-common stuff like various erase operations.
	 */
	case MMC_RSP_SPI_R1B:
		/* maybe we read all the busy tokens already */
		while (cp < end && *cp == 0)
			cp++;
		if (cp == end)
			mmc_spi_wait_unbusy(host, r1b_timeout);
		break;

	/* SPI R2 == R1 + second status byte; SEND_STATUS
	 * SPI R5 == R1 + data byte; IO_RW_DIRECT
	 */
	case MMC_RSP_SPI_R2:
		cmd->resp[0] |= *cp << 8;
		break;

	/* SPI R3, R4, or R7 == R1 + 4 bytes */
	case MMC_RSP_SPI_R3:
		cmd->resp[1] = be32_to_cpu(get_unaligned((u32 *)cp));
		break;

	/* SPI R1 == just one status byte */
	case MMC_RSP_SPI_R1:
		break;

	default:
		dev_dbg(&host->spi->dev, "bad response type %04x\n",
				mmc_spi_resp_type(cmd));
		if (value >= 0)
			value = -EINVAL;
		goto done;
	}

	if (value < 0)
		dev_dbg(&host->spi->dev, "%s: resp %04x %08x\n",
			tag, cmd->resp[0], cmd->resp[1]);

	/* disable chipselect on errors and some success cases */
	if (value >= 0 && cs_on)
		return value;
done:
	if (value < 0)
		cmd->error = value;
	mmc_cs_off(host);
	return value;
}