Ejemplo n.º 1
0
/**
 * Erase a block range on the MMC
 * @param: dbc	Pointer to doorbell command area.
 * @param: fd	file descriptor of backing file.
 * @param: start	start block number
 * @param: end	end block number
 */
static void mmc_erase_group(struct doorbell_command_t *dbc, int fd,
			    unsigned start, unsigned end)
{
	unsigned char  *buf;
	const off_t s = mmc_bounded_seek(dbc, fd, start, end + 1 - start);

	if (s <= (off_t)-1) {
		command_failure(dbc, dbc->device_id);
		return;
	}

	buf = malloc(mmc_blocklen);
	if (buf == NULL) {
		command_failure(dbc, dbc->device_id);
		return;
	}

	memset(buf, '\0', sizeof(buf));

	while (dbc->result == 0 && start <= end) {
		mmc_write_block(dbc, fd, start, 1, buf);
		++start;
	}
	free(buf);
}
Ejemplo n.º 2
0
DRESULT diskWrite (BYTE disk __attribute__ ((unused)), const BYTE *buff, DWORD sector, BYTE count)
{
  DWORD res = 0;
  int i;

  if (gDiskStatus & DSTATUS_NOINIT) 
    return DRESULT_NOTRDY;
  if (gDiskStatus & DSTATUS_PROTECT) 
    return DRESULT_WRPRT;
  if (!count) 
    return DRESULT_PARERR;

//printf("diskWrite ( %d , %d )\n", sector, count);
  for (i = 0; i < count; i++)
  {
		if (res == 0)
			memcpy(MMCWRData, buff + i*512, 512);
		else
			break;

		res = mmc_write_block(i+sector);
		print("write block ");
		printNum(i);
		print("\n");
  }

  if (res == 0)
    return DRESULT_OK;
  else
    return DRESULT_ERROR; 
}
Ejemplo n.º 3
0
void mmc_command(struct doorbell_command_t *dbc)
{
	/* See sandbox_mmc.c for the command_data[] layout. */
	int fd;
	unsigned command = dbc->command_data[0];

	fd = open_mmc_file(get_mmc_device(dbc));

	if (fd == -1) {
		fprintf(stderr, "Unable to open/create '%s'\n",
			mmc_file[get_mmc_device(dbc)]);
		command_failure(dbc, dbc->device_id);
		return;
	}

	mmc_clear_results(dbc);

	switch (command) {
	case MMC_CMD_GO_IDLE_STATE:
		/* NOP */
		break;
	case MMC_CMD_SEND_OP_COND:
		mmc_send_op_cond(dbc);
		break;
	case MMC_CMD_ALL_SEND_CID:
		mmc_send_cid_register(dbc);
		break;
	case MMC_CMD_SET_RELATIVE_ADDR: /* SD_CMD_SEND_RELATIVE_ADDR */
		dbc->command_data[8]  = 0x500;
		break;
	case MMC_CMD_SWITCH:
		/* NOP */
		break;
	case MMC_CMD_SELECT_CARD:
		dbc->command_data[8] = MMC_STATUS_RDY_FOR_DATA | MMC_STATUS;
		break;
	case MMC_CMD_SEND_EXT_CSD:
		if (dbc->command_data[4] == 0)	/* SD_CMD_SEND_IF_COND */
			command_timeout(dbc, dbc->device_id);
		else				/* MMC_CMD_SEND_EXT_CSD */
			mmc_send_ext_csd_register(dbc);
		break;
	case MMC_CMD_SEND_CSD:
		mmc_send_csd_register(dbc);
		break;
	case MMC_CMD_STOP_TRANSMISSION:
		verbose("%s: ignored '%d' command\n", __func__, command);
		break;
	case MMC_CMD_SEND_STATUS:
		dbc->command_data[8] = MMC_STATUS_RDY_FOR_DATA | MMC_STATUS;
		break;
	case MMC_CMD_SET_BLOCKLEN:
		mmc_set_blocklen(dbc, dbc->command_data[2]);
		break;
	case MMC_CMD_READ_SINGLE_BLOCK: {
		const unsigned start = dbc->command_data[2];
		void *buf = (void *)(uintptr_t)dbc->command_data[4];
		mmc_read_block(dbc, fd, start, 1, buf);
		break;
	}
	case MMC_CMD_READ_MULTIPLE_BLOCK: {
		const unsigned start = dbc->command_data[2];
		void *buf = (void *)(uintptr_t)dbc->command_data[4];
		const unsigned len = dbc->command_data[6];

		mmc_read_block(dbc, fd, start, len, buf);
		break;
	}
	case MMC_CMD_WRITE_SINGLE_BLOCK: {
		const unsigned start = dbc->command_data[2];
		void *buf = (void *)(uintptr_t)dbc->command_data[4];

		mmc_write_block(dbc, fd, start, 1, buf);
		break;
	}
	case MMC_CMD_WRITE_MULTIPLE_BLOCK: {
		const unsigned start = dbc->command_data[2];
		void *buf = (void *)(uintptr_t)dbc->command_data[4];
		const unsigned len = dbc->command_data[6];

		mmc_write_block(dbc, fd, start, len, buf);
		break;
	}
	case MMC_CMD_ERASE_GROUP_START:
		mmc_erase_group_start(dbc, dbc->command_data[2]);
		break;
	case MMC_CMD_ERASE_GROUP_END:
		mmc_erase_group_end(dbc, dbc->command_data[2]);
		break;
	case MMC_CMD_ERASE:
		mmc_erase_group(dbc, fd,
				mmc_erase_group_start_block,
				mmc_erase_group_end_block);
		break;
	case SD_CMD_APP_SEND_OP_COND:
		dbc->command_data[8] = 0;
		command_timeout(dbc, dbc->device_id);
		break;
	case SD_CMD_APP_SEND_SCR:
		/* Do not support higher clock speeds */
		command_failure(dbc, dbc->device_id);
		break;
	case MMC_CMD_APP_CMD:
		dbc->command_data[8] = OCR_BUSY | OCR_HCS;
		break;
	default:
		mmc_unknown_command(dbc, command);
		break;
	}
	close(fd);
}