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; }
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 {
/* 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); }
/* 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; }