bif: bif-core: add BIF NVM object writing support
Add a function to the bif-core driver which provides a means to write new BIF data objects into the non-volatile memory (NVM) of a BIF slave. Also add functions which can be used to overwrite or delete an existing BIF object. Change-Id: I6cd48409c696bd60a4d52b0fac8782c58d744df1 Signed-off-by: David Collins <collinsd@codeaurora.org>
This commit is contained in:
parent
387d5fb5be
commit
2cf302f2a7
|
@ -329,6 +329,25 @@ order to retrieve the set of BIF objects within a slave which match certain
|
||||||
criteria. bif_object_put() is used to free the memory allocated by
|
criteria. bif_object_put() is used to free the memory allocated by
|
||||||
bif_object_match_get().
|
bif_object_match_get().
|
||||||
|
|
||||||
|
BIF object manipulation in slave non-volatile memory:
|
||||||
|
-----------------------------------------------------
|
||||||
|
int bif_object_write(struct bif_slave *slave, u8 type, u8 version, u16
|
||||||
|
manufacturer_id, const u8 *data, int data_len);
|
||||||
|
|
||||||
|
int bif_object_overwrite(struct bif_slave *slave,
|
||||||
|
struct bif_object *object, u8 type, u8 version,
|
||||||
|
u16 manufacturer_id, const u8 *data, int data_len);
|
||||||
|
|
||||||
|
int bif_object_delete(struct bif_slave *slave, const struct bif_object *object);
|
||||||
|
|
||||||
|
bif_object_write() can be used to write a new BIF data object into the NVM of
|
||||||
|
a given slave. The new object is added to the end of the NVM object list.
|
||||||
|
bif_object_overwrite() can be used to overwrite an existing BIF data object
|
||||||
|
in the NVM of a slave. The new object data must be the same size as the
|
||||||
|
existing object data. bif_object_delete() can be used to delete a object from
|
||||||
|
the NVM object list and shift all of the objects after it in order to fill the
|
||||||
|
deleted object's space.
|
||||||
|
|
||||||
Get or set the BIF bus state or period:
|
Get or set the BIF bus state or period:
|
||||||
---------------------------------------
|
---------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -833,6 +833,45 @@ static void bif_slave_ctrl_unlock(struct bif_slave *slave)
|
||||||
bif_ctrl_unlock(&slave->ctrl);
|
bif_ctrl_unlock(&slave->ctrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bif_crc_ccitt() - calculate the CRC-CCITT CRC value of the data specified
|
||||||
|
* @buffer: Data to calculate the CRC of
|
||||||
|
* @len: Length of the data buffer in bytes
|
||||||
|
*
|
||||||
|
* MIPI-BIF specifies the usage of CRC-CCITT for BIF data objects. This
|
||||||
|
* function performs the CRC calculation while taking into account the bit
|
||||||
|
* ordering used by BIF.
|
||||||
|
*/
|
||||||
|
u16 bif_crc_ccitt(const u8 *buffer, unsigned int len)
|
||||||
|
{
|
||||||
|
u16 crc = 0xFFFF;
|
||||||
|
|
||||||
|
while (len--) {
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(*buffer));
|
||||||
|
buffer++;
|
||||||
|
}
|
||||||
|
return bitrev16(crc);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(bif_crc_ccitt);
|
||||||
|
|
||||||
|
static u16 bif_object_crc_ccitt(const struct bif_object *object)
|
||||||
|
{
|
||||||
|
u16 crc = 0xFFFF;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(object->type));
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(object->version));
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(object->manufacturer_id >> 8));
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(object->manufacturer_id));
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(object->length >> 8));
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(object->length));
|
||||||
|
|
||||||
|
for (i = 0; i < object->length - 8; i++)
|
||||||
|
crc = crc_ccitt_byte(crc, bitrev8(object->data[i]));
|
||||||
|
|
||||||
|
return bitrev16(crc);
|
||||||
|
}
|
||||||
|
|
||||||
static int bif_check_task(struct bif_slave *slave, unsigned int task)
|
static int bif_check_task(struct bif_slave *slave, unsigned int task)
|
||||||
{
|
{
|
||||||
if (IS_ERR_OR_NULL(slave)) {
|
if (IS_ERR_OR_NULL(slave)) {
|
||||||
|
@ -1860,6 +1899,382 @@ void bif_object_put(struct bif_object *object)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(bif_object_put);
|
EXPORT_SYMBOL(bif_object_put);
|
||||||
|
|
||||||
|
/* Copies the contents of object into buf following MIPI-BIF formatting. */
|
||||||
|
static void bif_object_flatten(u8 *buf, const struct bif_object *object)
|
||||||
|
{
|
||||||
|
buf[0] = object->type;
|
||||||
|
buf[1] = object->version;
|
||||||
|
buf[2] = object->manufacturer_id >> 8;
|
||||||
|
buf[3] = object->manufacturer_id;
|
||||||
|
buf[4] = object->length >> 8;
|
||||||
|
buf[5] = object->length;
|
||||||
|
memcpy(&buf[6], object->data, object->length - 8);
|
||||||
|
buf[object->length - 2] = object->crc >> 8;
|
||||||
|
buf[object->length - 1] = object->crc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bif_object_write() - writes a new BIF object at the end of the object list in
|
||||||
|
* the non-volatile memory of a slave
|
||||||
|
* @slave: BIF slave handle
|
||||||
|
* @type: Type of the object
|
||||||
|
* @version: Version of the object
|
||||||
|
* @manufacturer_id: Manufacturer ID number allocated by MIPI
|
||||||
|
* @data: Data contained in the object
|
||||||
|
* @data_len: Length of the data
|
||||||
|
*
|
||||||
|
* Returns 0 on success or errno on failure. This function will fail if the NVM
|
||||||
|
* lock points to an offset after the BIF object list terminator (0x00).
|
||||||
|
*/
|
||||||
|
int bif_object_write(struct bif_slave *slave, u8 type, u8 version,
|
||||||
|
u16 manufacturer_id, const u8 *data, int data_len)
|
||||||
|
{
|
||||||
|
struct bif_object *object;
|
||||||
|
struct bif_object *tail_object;
|
||||||
|
struct bif_nvm_function *nvm;
|
||||||
|
int rc;
|
||||||
|
int add_null = 0;
|
||||||
|
u16 offset = 0;
|
||||||
|
u8 *buf;
|
||||||
|
|
||||||
|
if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(data)) {
|
||||||
|
pr_err("Invalid input pointer\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvm = slave->sdev->nvm_function;
|
||||||
|
if (!nvm) {
|
||||||
|
pr_err("BIF slave has no NVM function\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
bif_slave_ctrl_lock(slave);
|
||||||
|
if (nvm->object_count > 0) {
|
||||||
|
tail_object = list_entry(nvm->object_list.prev,
|
||||||
|
struct bif_object, list);
|
||||||
|
offset = tail_object->addr - nvm->nvm_base_address
|
||||||
|
+ tail_object->length;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset < nvm->nvm_lock_offset) {
|
||||||
|
pr_err("Cannot write BIF object to NVM because the end of the object list is locked (end=%d < lock=%d)\n",
|
||||||
|
offset, nvm->nvm_lock_offset);
|
||||||
|
rc = -EPERM;
|
||||||
|
goto error_unlock;
|
||||||
|
} else if (offset + data_len + 8 > nvm->nvm_size) {
|
||||||
|
pr_err("Cannot write BIF object to NVM because there is not enough remaining space (size=%d > remaining=%d)\n",
|
||||||
|
data_len + 8, nvm->nvm_size - offset);
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset + data_len + 8 < nvm->nvm_size)
|
||||||
|
add_null = 1;
|
||||||
|
object = kzalloc(sizeof(*object), GFP_KERNEL);
|
||||||
|
if (!object) {
|
||||||
|
pr_err("kzalloc failed\n");
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
object->data = kzalloc(data_len, GFP_KERNEL);
|
||||||
|
if (!object->data) {
|
||||||
|
pr_err("kzalloc failed\n");
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto free_object;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = kzalloc(data_len + 8 + add_null, GFP_KERNEL);
|
||||||
|
if (!buf) {
|
||||||
|
pr_err("kzalloc failed\n");
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto free_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
object->type = type;
|
||||||
|
object->version = version;
|
||||||
|
object->manufacturer_id = manufacturer_id;
|
||||||
|
object->length = data_len + 8;
|
||||||
|
memcpy(object->data, data, data_len);
|
||||||
|
object->crc = bif_object_crc_ccitt(object);
|
||||||
|
object->addr = offset + nvm->nvm_base_address;
|
||||||
|
|
||||||
|
bif_object_flatten(buf, object);
|
||||||
|
if (add_null)
|
||||||
|
buf[object->length] = BIF_OBJ_END_OF_LIST;
|
||||||
|
|
||||||
|
rc = _bif_slave_nvm_raw_write(slave->sdev, offset, buf,
|
||||||
|
object->length + add_null);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("NVM write failed, rc=%d\n", rc);
|
||||||
|
kfree(buf);
|
||||||
|
goto free_data;
|
||||||
|
}
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
|
list_add_tail(&object->list, &nvm->object_list);
|
||||||
|
nvm->object_count++;
|
||||||
|
|
||||||
|
bif_slave_ctrl_unlock(slave);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
free_data:
|
||||||
|
kfree(object->data);
|
||||||
|
free_object:
|
||||||
|
kfree(object);
|
||||||
|
error_unlock:
|
||||||
|
bif_slave_ctrl_unlock(slave);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(bif_object_write);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns a pointer to the internal object referenced by a consumer object
|
||||||
|
* if it exists. Returns NULL if the internal object cannot be found.
|
||||||
|
*/
|
||||||
|
static struct bif_object *bif_object_consumer_search(
|
||||||
|
struct bif_nvm_function *nvm, const struct bif_object *consumer_object)
|
||||||
|
{
|
||||||
|
struct bif_object *object = NULL;
|
||||||
|
struct bif_object *search_object;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Internal struct in object linked list is pointed to by consumer
|
||||||
|
* object list.prev.
|
||||||
|
*/
|
||||||
|
search_object = list_entry(consumer_object->list.prev,
|
||||||
|
struct bif_object, list);
|
||||||
|
|
||||||
|
list_for_each_entry(object, &nvm->object_list, list) {
|
||||||
|
if (object == search_object)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object != search_object)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bif_object_overwrite() - overwrites an existing BIF object found in the
|
||||||
|
* non-volatile memory of a slave
|
||||||
|
* @slave: BIF slave handle
|
||||||
|
* @object: Existing object in the slave to overwrite
|
||||||
|
* @type: Type of the object
|
||||||
|
* @version: Version of the object
|
||||||
|
* @manufacturer_id: Manufacturer ID number allocated by MIPI
|
||||||
|
* @data: Data contained in the object
|
||||||
|
* @data_len: Length of the data
|
||||||
|
*
|
||||||
|
* Returns 0 on success or errno on failure. The data stored within 'object'
|
||||||
|
* is updated to the new values upon success. The new data written to the
|
||||||
|
* object must have exactly the same length as the old data (i.e.
|
||||||
|
* data_len == object->length - 8).
|
||||||
|
*
|
||||||
|
* This function will fail if the NVM lock points to an offset after the
|
||||||
|
* beginning of the existing BIF object.
|
||||||
|
*/
|
||||||
|
int bif_object_overwrite(struct bif_slave *slave,
|
||||||
|
struct bif_object *object, u8 type, u8 version,
|
||||||
|
u16 manufacturer_id, const u8 *data, int data_len)
|
||||||
|
{
|
||||||
|
struct bif_object *edit_object = NULL;
|
||||||
|
struct bif_nvm_function *nvm;
|
||||||
|
int rc;
|
||||||
|
u16 crc;
|
||||||
|
u8 *buf;
|
||||||
|
|
||||||
|
if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(object)
|
||||||
|
|| IS_ERR_OR_NULL(data)) {
|
||||||
|
pr_err("Invalid input pointer\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvm = slave->sdev->nvm_function;
|
||||||
|
if (!nvm) {
|
||||||
|
pr_err("BIF slave has no NVM function\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_len + 8 != object->length) {
|
||||||
|
pr_err("New data length=%d is different from existing length=%d\n",
|
||||||
|
data_len, object->length - 8);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
bif_slave_ctrl_lock(slave);
|
||||||
|
|
||||||
|
edit_object = bif_object_consumer_search(nvm, object);
|
||||||
|
if (!edit_object) {
|
||||||
|
pr_err("BIF object not found within slave\n");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (edit_object->addr - nvm->nvm_base_address < nvm->nvm_lock_offset) {
|
||||||
|
pr_err("Cannot overwrite BIF object in NVM because some portion of it is locked\n");
|
||||||
|
rc = -EPERM;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = kzalloc(data_len + 8, GFP_KERNEL);
|
||||||
|
if (!buf) {
|
||||||
|
pr_err("kzalloc failed\n");
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf[0] = type;
|
||||||
|
buf[1] = version;
|
||||||
|
buf[2] = manufacturer_id >> 8;
|
||||||
|
buf[3] = manufacturer_id;
|
||||||
|
buf[4] = (data_len + 8) >> 8;
|
||||||
|
buf[5] = data_len + 8;
|
||||||
|
memcpy(&buf[6], data, data_len);
|
||||||
|
crc = bif_crc_ccitt(buf, data_len + 6);
|
||||||
|
buf[data_len + 6] = crc >> 8;
|
||||||
|
buf[data_len + 7] = crc;
|
||||||
|
|
||||||
|
rc = _bif_slave_nvm_raw_write(slave->sdev,
|
||||||
|
object->addr - nvm->nvm_base_address, buf, data_len + 8);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("NVM write failed, rc=%d\n", rc);
|
||||||
|
kfree(buf);
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
|
/* Update internal object struct. */
|
||||||
|
edit_object->type = type;
|
||||||
|
edit_object->version = version;
|
||||||
|
edit_object->manufacturer_id = manufacturer_id;
|
||||||
|
edit_object->length = data_len + 8;
|
||||||
|
memcpy(edit_object->data, data, data_len);
|
||||||
|
edit_object->crc = crc;
|
||||||
|
|
||||||
|
/* Update consumer object struct. */
|
||||||
|
object->type = type;
|
||||||
|
object->version = version;
|
||||||
|
object->manufacturer_id = manufacturer_id;
|
||||||
|
object->length = data_len + 8;
|
||||||
|
memcpy(object->data, data, data_len);
|
||||||
|
object->crc = crc;
|
||||||
|
|
||||||
|
error_unlock:
|
||||||
|
bif_slave_ctrl_unlock(slave);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(bif_object_overwrite);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* bif_object_delete() - deletes an existing BIF object found in the
|
||||||
|
* non-volatile memory of a slave. Objects found in the
|
||||||
|
* object list in the NVM of the slave are shifted forward
|
||||||
|
* in order to fill the hole left by the deleted object
|
||||||
|
* @slave: BIF slave handle
|
||||||
|
* @object: Existing object in the slave to delete
|
||||||
|
*
|
||||||
|
* Returns 0 on success or errno on failure. bif_object_put() must still be
|
||||||
|
* called after this function in order to free the memory in the consumer
|
||||||
|
* 'object' struct pointer.
|
||||||
|
*
|
||||||
|
* This function will fail if the NVM lock points to an offset after the
|
||||||
|
* beginning of the existing BIF object.
|
||||||
|
*/
|
||||||
|
int bif_object_delete(struct bif_slave *slave, const struct bif_object *object)
|
||||||
|
{
|
||||||
|
struct bif_object *del_object = NULL;
|
||||||
|
struct bif_object *tail_object;
|
||||||
|
struct bif_nvm_function *nvm;
|
||||||
|
bool found = false;
|
||||||
|
int pos = 0;
|
||||||
|
int rc;
|
||||||
|
u8 *buf;
|
||||||
|
|
||||||
|
if (IS_ERR_OR_NULL(slave) || IS_ERR_OR_NULL(object)) {
|
||||||
|
pr_err("Invalid input pointer\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
nvm = slave->sdev->nvm_function;
|
||||||
|
if (!nvm) {
|
||||||
|
pr_err("BIF slave has no NVM function\n");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
bif_slave_ctrl_lock(slave);
|
||||||
|
|
||||||
|
del_object = bif_object_consumer_search(nvm, object);
|
||||||
|
if (!del_object) {
|
||||||
|
pr_err("BIF object not found within slave\n");
|
||||||
|
rc = -EINVAL;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (del_object->addr - nvm->nvm_base_address < nvm->nvm_lock_offset) {
|
||||||
|
pr_err("Cannot delete BIF object in NVM because some portion of it is locked\n");
|
||||||
|
rc = -EPERM;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
buf = kmalloc(nvm->nvm_size, GFP_KERNEL);
|
||||||
|
if (!buf) {
|
||||||
|
pr_err("kzalloc failed\n");
|
||||||
|
rc = -ENOMEM;
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Copy the contents of objects after the one to be deleted into a flat
|
||||||
|
* array.
|
||||||
|
*/
|
||||||
|
list_for_each_entry(tail_object, &nvm->object_list, list) {
|
||||||
|
if (found) {
|
||||||
|
bif_object_flatten(&buf[pos], tail_object);
|
||||||
|
pos += tail_object->length;
|
||||||
|
} else if (tail_object == del_object) {
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add the list terminator. */
|
||||||
|
buf[pos++] = BIF_OBJ_END_OF_LIST;
|
||||||
|
|
||||||
|
rc = _bif_slave_nvm_raw_write(slave->sdev,
|
||||||
|
del_object->addr - nvm->nvm_base_address, buf, pos);
|
||||||
|
if (rc < 0) {
|
||||||
|
pr_err("NVM write failed, rc=%d\n", rc);
|
||||||
|
kfree(buf);
|
||||||
|
goto error_unlock;
|
||||||
|
}
|
||||||
|
kfree(buf);
|
||||||
|
|
||||||
|
/* Update the addresses of the objects after the one to be deleted. */
|
||||||
|
found = false;
|
||||||
|
list_for_each_entry(tail_object, &nvm->object_list, list) {
|
||||||
|
if (found)
|
||||||
|
tail_object->addr -= del_object->length;
|
||||||
|
else if (tail_object == del_object)
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_del(&del_object->list);
|
||||||
|
kfree(del_object->data);
|
||||||
|
kfree(del_object);
|
||||||
|
nvm->object_count--;
|
||||||
|
|
||||||
|
error_unlock:
|
||||||
|
bif_slave_ctrl_unlock(slave);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(bif_object_delete);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* bif_slave_read() - read contiguous memory values from a BIF slave
|
* bif_slave_read() - read contiguous memory values from a BIF slave
|
||||||
* @slave: BIF slave handle
|
* @slave: BIF slave handle
|
||||||
|
@ -2529,45 +2944,6 @@ static int bif_initialize_slave_control_function(struct bif_slave_dev *sdev,
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* bif_crc_ccitt() - calculate the CRC-CCITT CRC value of the data specified
|
|
||||||
* @buffer: Data to calculate the CRC of
|
|
||||||
* @len: Length of the data buffer in bytes
|
|
||||||
*
|
|
||||||
* MIPI-BIF specifies the usage of CRC-CCITT for BIF data objects. This
|
|
||||||
* function performs the CRC calculation while taking into account the bit
|
|
||||||
* ordering used by BIF.
|
|
||||||
*/
|
|
||||||
u16 bif_crc_ccitt(const u8 *buffer, unsigned int len)
|
|
||||||
{
|
|
||||||
u16 crc = 0xFFFF;
|
|
||||||
|
|
||||||
while (len--) {
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(*buffer));
|
|
||||||
buffer++;
|
|
||||||
}
|
|
||||||
return bitrev16(crc);
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(bif_crc_ccitt);
|
|
||||||
|
|
||||||
static u16 bif_object_crc_ccitt(const struct bif_object *object)
|
|
||||||
{
|
|
||||||
u16 crc = 0xFFFF;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(object->type));
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(object->version));
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(object->manufacturer_id >> 8));
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(object->manufacturer_id));
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(object->length >> 8));
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(object->length));
|
|
||||||
|
|
||||||
for (i = 0; i < object->length - 8; i++)
|
|
||||||
crc = crc_ccitt_byte(crc, bitrev8(object->data[i]));
|
|
||||||
|
|
||||||
return bitrev16(crc);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the specified function is an NVM function and if it is, then
|
* Check if the specified function is an NVM function and if it is, then
|
||||||
* instantiate NVM function data for the slave and read all objects.
|
* instantiate NVM function data for the slave and read all objects.
|
||||||
|
|
|
@ -564,6 +564,15 @@ int bif_slave_nvm_raw_read(struct bif_slave *slave, u16 offset, u8 *buf,
|
||||||
int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset, u8 *buf,
|
int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset, u8 *buf,
|
||||||
int len);
|
int len);
|
||||||
|
|
||||||
|
int bif_object_write(struct bif_slave *slave, u8 type, u8 version, u16
|
||||||
|
manufacturer_id, const u8 *data, int data_len);
|
||||||
|
|
||||||
|
int bif_object_overwrite(struct bif_slave *slave,
|
||||||
|
struct bif_object *object, u8 type, u8 version,
|
||||||
|
u16 manufacturer_id, const u8 *data, int data_len);
|
||||||
|
|
||||||
|
int bif_object_delete(struct bif_slave *slave, const struct bif_object *object);
|
||||||
|
|
||||||
int bif_slave_is_present(struct bif_slave *slave);
|
int bif_slave_is_present(struct bif_slave *slave);
|
||||||
|
|
||||||
int bif_slave_is_selected(struct bif_slave *slave);
|
int bif_slave_is_selected(struct bif_slave *slave);
|
||||||
|
@ -664,6 +673,19 @@ static inline int bif_slave_nvm_raw_write(struct bif_slave *slave, u16 offset,
|
||||||
u8 *buf, int len)
|
u8 *buf, int len)
|
||||||
{ return -EPERM; }
|
{ return -EPERM; }
|
||||||
|
|
||||||
|
static inline int bif_object_write(struct bif_slave *slave, u8 type, u8 version,
|
||||||
|
u16 manufacturer_id, const u8 *data, int data_len)
|
||||||
|
{ return -EPERM; }
|
||||||
|
|
||||||
|
static inline int bif_object_overwrite(struct bif_slave *slave,
|
||||||
|
struct bif_object *object, u8 type, u8 version,
|
||||||
|
u16 manufacturer_id, const u8 *data, int data_len)
|
||||||
|
{ return -EPERM; }
|
||||||
|
|
||||||
|
static inline int bif_object_delete(struct bif_slave *slave,
|
||||||
|
const struct bif_object *object)
|
||||||
|
{ return -EPERM; }
|
||||||
|
|
||||||
static inline int bif_slave_is_present(struct bif_slave *slave)
|
static inline int bif_slave_is_present(struct bif_slave *slave)
|
||||||
{ return -EPERM; }
|
{ return -EPERM; }
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue