Exemplo n.º 1
0
ulong mmc_bwrite(struct blk_desc *block_dev, lbaint_t start, lbaint_t blkcnt,
		 const void *src)
#endif
{
#ifdef CONFIG_BLK
	struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
#endif
	int dev_num = block_dev->devnum;
	lbaint_t cur, blocks_todo = blkcnt;
	int err;

	struct mmc *mmc = find_mmc_device(dev_num);
	if (!mmc)
		return 0;

	err = blk_select_hwpart_devnum(IF_TYPE_MMC, dev_num, block_dev->hwpart);
	if (err < 0)
		return 0;

	if (mmc_set_blocklen(mmc, mmc->write_bl_len))
		return 0;

	do {
		cur = (blocks_todo > mmc->cfg->b_max) ?
			mmc->cfg->b_max : blocks_todo;
		if (mmc_write_blocks(mmc, start, cur, src) != cur)
			return 0;
		blocks_todo -= cur;
		start += cur;
		src += cur * mmc->write_bl_len;
	} while (blocks_todo > 0);

	return blkcnt;
}
unsigned long
mmc_bread(int dev_num, unsigned long start, unsigned blkcnt, void *dst)
{
	unsigned cur, blocks_todo = blkcnt;
	struct mmc *mmc = find_mmc_device(dev_num);

	if (blkcnt == 0)
		return 0;
	if (!mmc)
		return 0;

	if ((start + blkcnt) > mmc->lba) {
		mmcdbg("MMC: block number 0x%x exceeds max(0x%x)\n",
			start + blkcnt, mmc->lba);
		return 0;
	}

	if (mmc_set_blocklen(mmc, mmc->read_bl_len))
		return 0;

	do {
		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
		if(mmc_read_blocks(mmc, dst, start, cur) != cur)
			return 0;
		blocks_todo -= cur;
		start += cur;
//		dst += cur * mmc->read_bl_len;
		dst = (char*)dst + cur * mmc->read_bl_len;
	} while (blocks_todo > 0);

	return blkcnt;
}
unsigned long
mmc_bwrite(int dev_num, unsigned long start, unsigned blkcnt, const void*src)
{
	unsigned cur, blocks_todo = blkcnt;

	struct mmc *mmc = find_mmc_device(dev_num);

	if (blkcnt == 0)
		return 0;
	if (!mmc)
		return 0;

	if (mmc_set_blocklen(mmc, mmc->write_bl_len))
		return 0;

	do {
		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
		if(mmc_write_blocks(mmc, start, cur, src) != cur)
			return 0;
		blocks_todo -= cur;
		start += cur;
//		src += cur * mmc->write_bl_len;
		src = (char*)src + cur * mmc->write_bl_len;
	} while (blocks_todo > 0);

	return blkcnt;
}
Exemplo n.º 4
0
ulong skymedi_write_file(struct mmc * mmc, lbaint_t start, char *name,
			 u32 timeout_ms)
{
	unsigned char *buffer = (unsigned char *)Bulk_out_buf;	//???
	file_header_t *header =
	    get_file_header(buffer, BULK_OUT_BUF_SIZE, name);
	if (header == NULL) {
		printf("can't find file %s\n", name);
		return 0;
	}

	u32 size = header->size;
	void *src = buffer + header->offset;

	lbaint_t blkcnt = (size - 1) / 512 + 1;
	lbaint_t cur, blocks_todo = blkcnt;

	if (mmc_set_blocklen(mmc, mmc->write_bl_len))
		return 0;

	do {
		cur = (blocks_todo > mmc->b_max) ? mmc->b_max : blocks_todo;
		if (skymedi_write_blocks(mmc, start, cur, src, timeout_ms) !=
		    cur)
			return 0;
		blocks_todo -= cur;
		start += cur;
		src += cur * mmc->write_bl_len;
	} while (blocks_todo > 0);

	return blkcnt;
}
Exemplo n.º 5
0
unsigned long
mmc_bread(int dev_num, unsigned long start, unsigned blkcnt, void *dst)
{
	unsigned cur, blocks_todo = blkcnt;
	struct mmc *mmc = find_mmc_device(dev_num);

	if (blkcnt == 0){
		mmcinfo("mmc %d blkcnt should not be 0\n",mmc->control_num);
		return 0;
	}
	if (!mmc){
		mmcinfo("Can not find mmc dev %d\n",dev_num);
		return 0;
	}

	if ((start + blkcnt) > mmc->lba) {
		mmcinfo("mmc %d: block number 0x%x exceeds max(0x%x)\n",mmc->control_num,
			start + blkcnt, mmc->lba);
		return 0;
	}

	if (mmc_set_blocklen(mmc, mmc->read_bl_len)){
		mmcinfo("mmc %d Set block len failed\n",mmc->control_num);
		return 0;
	}

	do {
		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
		if(mmc_read_blocks(mmc, dst, start, cur) != cur){
			mmcinfo("mmc %d block read failed\n",mmc->control_num);
			return 0;
		}
		blocks_todo -= cur;
		start += cur;
//		dst += cur * mmc->read_bl_len;
		dst = (char*)dst + cur * mmc->read_bl_len;
	} while (blocks_todo > 0);

	return blkcnt;
}
Exemplo n.º 6
0
unsigned long
mmc_bwrite(int dev_num, unsigned long start, unsigned blkcnt, const void*src)
{
	unsigned cur, blocks_todo = blkcnt;

	struct mmc *mmc = find_mmc_device(dev_num);

	if (blkcnt == 0){
		mmcinfo("mmc %d blkcnt should not be 0\n",dev_num);
		return 0;
	}
	if (!mmc){
		mmcinfo("Can not found device %d\n",dev_num);
		return 0;
	}

	if (mmc_set_blocklen(mmc, mmc->write_bl_len)){
		mmcinfo("mmc %d set block len failed\n",mmc->control_num);
//		sunxi_mmc_exit(dev_num);
//		if(sunxi_mmc_init(dev_num,4)<0){
//			mmcinfo("re init failed\n");
//			return 0;
//		}
		return 0;
	}

	do {
		cur = (blocks_todo > mmc->b_max) ?  mmc->b_max : blocks_todo;
		if(mmc_write_blocks(mmc, start, cur, src) != cur){
			mmcinfo("mmc %d write block failed\n",mmc->control_num);
			return 0;
		}
		blocks_todo -= cur;
		start += cur;
//		src += cur * mmc->write_bl_len;
		src = (char*)src + cur * mmc->write_bl_len;
	} while (blocks_todo > 0);

	return blkcnt;
}
int mmc_lock_unlock_by_buf(struct mmc_card *card, u8* key_buf,int key_len, int mode)
{

	int err, data_size;
	int max_buf_size ;
	u8 *data_buf;
	max_buf_size = 32;
	data_size = 1;
	//max password(16byte) max_key = max_password(old) + max_password(new) + 0xFF + 0xFF = 34
	if(key_len > 30)
	{
		return -EINVAL;
	}
	if (!(mode & MMC_LOCK_MODE_ERASE)) {
//		data_size =  key_len ;
		data_size = max_buf_size;
	}

	data_buf = kzalloc(max_buf_size, GFP_KERNEL);
	if (!data_buf)
	{
		printk("%s kzalloc failed\n",__func__);
		return -ENOMEM;
	}
	memset(data_buf, 0, max_buf_size);
	data_buf[0] |= mode;
	if (mode & MMC_LOCK_MODE_UNLOCK)
		data_buf[0] &= ~MMC_LOCK_MODE_UNLOCK;

	if (!(mode & MMC_LOCK_MODE_ERASE)) {
		data_buf[1] = key_len-2; //exclude end 2 chars (0xFF 0xFF)
		memcpy(data_buf + 2, key_buf, key_len);
	} else {
		data_buf[1] =0xff;
		data_buf[2] = 0xff;
	}

	/*-----------Set mmc Status Command-----------------------------*/
	err = sd_send_status(card);
	if(err)
	{
		goto out;
	}
	printk("[SDLOCK] %s STATUS data_size=%d\r\n",__func__,data_size);

	/*------------Set Block Length Command--------------------------*/
	err = sd_send_blocklen(card,data_size);
	if(err)
	{
		goto out;
	}
	printk("[SDLOCK] %s MMC_SET_BLOCKLEN \r\n",__func__);

	/*-----------Set Lock/Unlock Command---------------------------*/
	err = sd_send_lock_unlock_cmd(card,data_buf,data_size,max_buf_size);
	if(err)
	{
		goto out;
	}
	printk("[SDLOCK] %s MMC_LOCK_UNLOCK \r\n",__func__);

	/*-------------Set mmc Status Command--------------------*/
	err = sd_wait_lock_unlock_cmd(card,mode);
	if(err) {
		mmc_set_blocklen(card, 512);
		goto out;
	}

	err = mmc_set_blocklen(card, 512);

out:
	kfree(data_buf);

	return err;
}
Exemplo n.º 8
0
int mmc_gen_cmd(struct mmc_card *card, void *buf, u8 index, u8 arg1, u8 arg2, u8 mode)
{
	struct mmc_request mrq;
	struct mmc_command cmd;
	struct mmc_data data;
	struct mmc_command stop;
	struct scatterlist sg;
	void *data_buf;

	mmc_set_blocklen(card, 512);

	data_buf = kmalloc(512, GFP_KERNEL);
	if (data_buf == NULL)
		return -ENOMEM;

	memset(&mrq, 0, sizeof(struct mmc_request));
	memset(&cmd, 0, sizeof(struct mmc_command));
	memset(&data, 0, sizeof(struct mmc_data));
	memset(&stop, 0, sizeof(struct mmc_command));

	mrq.cmd = &cmd;
	mrq.data = &data;
	mrq.stop = &stop;

	cmd.opcode = MMC_GEN_CMD;
	cmd.arg = (arg2 << 16) |
		  (arg1 << 8) |
		  (index << 1) |
		  mode;

	cmd.flags = MMC_RSP_SPI_R1 | MMC_RSP_R1 | MMC_CMD_ADTC;

	data.blksz = 512;
	data.blocks = 1;
	data.flags = MMC_DATA_READ;
	data.sg = &sg;
	data.sg_len = 1;

	stop.opcode = MMC_STOP_TRANSMISSION;
	stop.arg = 0;
	stop.flags = MMC_RSP_SPI_R1B | MMC_RSP_R1B | MMC_CMD_AC;

	sg_init_one(&sg, data_buf, 512);

	mmc_set_data_timeout(&data, card);

	mmc_claim_host(card->host);
	mmc_wait_for_req(card->host, &mrq);
	mmc_release_host(card->host);

	memcpy(buf, data_buf, 512);
	kfree(data_buf);

	if (cmd.error)
		return cmd.error;
	if (data.error)
		return data.error;
	if (stop.error)
		return stop.error;

	return 0;
}
Exemplo n.º 9
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);
}