blob: 0e58e34ce48396671e6109da1fbf129f83f3e597 [file] [log] [blame]
/*
* Copyright (c) 2020, Mediatek Inc. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>
#include <errno.h>
#include "ufs.h"
#include "ufs_cmds.h"
#include "options.h"
#include "options.h"
#include "scsi_bsg_util.h"
#include "ufs_vendor.h"
static int write_data(struct tool_options *opt, int dev_fd, void *p_data);
static int read_data(struct tool_options *opt, int dev_fd, void *p_data);
int do_vendor(struct tool_options *opt)
{
int rc = INVALID;
int fd;
void *p_data;
WRITE_LOG("Start : %s", __func__);
p_data = malloc(opt->len);
if (!p_data) {
print_error("Cannot allocate %d Bytes", opt->len);
return ERROR;
}
fd = open(opt->path, O_RDWR | O_SYNC);
if (fd < 0) {
perror("Device open");
goto out;
}
if (opt->opr == WRITE)
rc = write_data(opt, fd, p_data);
else
rc = read_data(opt, fd, p_data);
out:
free(p_data);
if (fd != INVALID)
close(fd);
return rc;
}
static int write_data(struct tool_options *opt, int dev_fd, void *p_data)
{
int input_fd;
int rc = INVALID;
off_t file_size;
input_fd = open(opt->data, O_RDONLY | O_SYNC);
if (input_fd < 0) {
perror("Input file open");
return ERROR;
}
file_size = lseek(input_fd, 0, SEEK_END);
if ((file_size <= 0) || (file_size < opt->len)) {
print_error("Wrong input data file length = %d",
file_size);
goto out;
}
lseek(input_fd, 0, SEEK_SET);
if (read(input_fd, p_data, opt->len) != opt->len) {
print_error("Read %d data bytes from input file failed",
opt->len);
goto out;
}
rc = write_buffer(dev_fd, p_data, BUFFER_VENDOR_MODE, opt->index,
opt->offset, opt->len, opt->sg_type);
if (!rc)
printf("The vendor buffer was written\n");
out:
close(input_fd);
return rc;
}
static int read_data(struct tool_options *opt, int dev_fd, void *p_data)
{
int rc = INVALID;
rc = read_buffer(dev_fd, p_data, BUFFER_VENDOR_MODE, opt->index,
opt->offset, opt->len, opt->sg_type);
if (!rc) {
write_file("read_vendor_buffer.dat", p_data, opt->len);
printf("read_vendor_buffer.dat created\n");
}
return rc;
}
void vendor_help(char *tool_name)
{
printf("\n Vendor Write/Read Buffer command usage:\n");
printf("\n\t%s vendor [-r ][-w] <path to data file> [-L] <data_len>\n"
"\t\t[-O] <buf offset> [-p] <path to device>\n",
tool_name);
printf("\n\t-r\tRead vendor buffer command[default operation]\n");
printf("\n\t-w\tInput file path for write buffer vendor command\n");
printf("\n\t-L\tData buffer length, up to 512 Bytes[default value 512B]\n");
printf("\n\t-i\tBuffer ID\n");
printf("\n\t-g\t sg struct ver - 0: SG_IO_VER4 (default), 1: SG_IO_VER3\n");
printf("\n\t-O\tBuffer Offset\n");
printf("\n\t-p\tDevice path\n");
}