Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
E
etherlabmaster
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Jira
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
ICS Control System Infrastructure
etherlabmaster
Commits
ff953519
Commit
ff953519
authored
18 years ago
by
Florian Pose
Browse files
Options
Downloads
Patches
Plain Diff
EEPROM writing via SysFS.
parent
65733fe4
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
master/fsm.c
+162
-17
162 additions, 17 deletions
master/fsm.c
master/fsm.h
+1
-1
1 addition, 1 deletion
master/fsm.h
master/slave.c
+85
-1
85 additions, 1 deletion
master/slave.c
master/slave.h
+3
-0
3 additions, 0 deletions
master/slave.h
with
251 additions
and
19 deletions
master/fsm.c
+
162
−
17
View file @
ff953519
...
@@ -58,6 +58,7 @@ void ec_fsm_master_validate_product(ec_fsm_t *);
...
@@ -58,6 +58,7 @@ void ec_fsm_master_validate_product(ec_fsm_t *);
void
ec_fsm_master_reconfigure
(
ec_fsm_t
*
);
void
ec_fsm_master_reconfigure
(
ec_fsm_t
*
);
void
ec_fsm_master_address
(
ec_fsm_t
*
);
void
ec_fsm_master_address
(
ec_fsm_t
*
);
void
ec_fsm_master_conf
(
ec_fsm_t
*
);
void
ec_fsm_master_conf
(
ec_fsm_t
*
);
void
ec_fsm_master_eeprom
(
ec_fsm_t
*
);
void
ec_fsm_slave_start_reading
(
ec_fsm_t
*
);
void
ec_fsm_slave_start_reading
(
ec_fsm_t
*
);
void
ec_fsm_slave_read_status
(
ec_fsm_t
*
);
void
ec_fsm_slave_read_status
(
ec_fsm_t
*
);
...
@@ -77,8 +78,11 @@ void ec_fsm_slave_op(ec_fsm_t *);
...
@@ -77,8 +78,11 @@ void ec_fsm_slave_op(ec_fsm_t *);
void
ec_fsm_slave_op2
(
ec_fsm_t
*
);
void
ec_fsm_slave_op2
(
ec_fsm_t
*
);
void
ec_fsm_sii_start_reading
(
ec_fsm_t
*
);
void
ec_fsm_sii_start_reading
(
ec_fsm_t
*
);
void
ec_fsm_sii_check
(
ec_fsm_t
*
);
void
ec_fsm_sii_read_check
(
ec_fsm_t
*
);
void
ec_fsm_sii_fetch
(
ec_fsm_t
*
);
void
ec_fsm_sii_read_fetch
(
ec_fsm_t
*
);
void
ec_fsm_sii_start_writing
(
ec_fsm_t
*
);
void
ec_fsm_sii_write_check
(
ec_fsm_t
*
);
void
ec_fsm_sii_write_check2
(
ec_fsm_t
*
);
void
ec_fsm_sii_end
(
ec_fsm_t
*
);
void
ec_fsm_sii_end
(
ec_fsm_t
*
);
void
ec_fsm_sii_error
(
ec_fsm_t
*
);
void
ec_fsm_sii_error
(
ec_fsm_t
*
);
...
@@ -406,7 +410,25 @@ void ec_fsm_master_proc_states(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -406,7 +410,25 @@ void ec_fsm_master_proc_states(ec_fsm_t *fsm /**< finite state machine */)
return
;
return
;
}
}
// nothing to configure. restart master state machine.
if
(
master
->
mode
==
EC_MASTER_MODE_FREERUN
)
{
// nothing to configure. check for pending EEPROM write operations.
list_for_each_entry
(
slave
,
&
master
->
slaves
,
list
)
{
if
(
!
slave
->
new_eeprom_data
)
continue
;
// found pending EEPROM write operation. execute it!
EC_INFO
(
"Writing EEPROM of slave %i...
\n
"
,
slave
->
ring_position
);
fsm
->
sii_offset
=
0x0000
;
memcpy
(
fsm
->
sii_value
,
slave
->
new_eeprom_data
,
2
);
fsm
->
sii_mode
=
1
;
fsm
->
sii_state
=
ec_fsm_sii_start_writing
;
fsm
->
slave
=
slave
;
fsm
->
master_state
=
ec_fsm_master_eeprom
;
fsm
->
master_state
(
fsm
);
// execute immediately
return
;
}
}
// nothing to do. restart master state machine.
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
(
fsm
);
// execute immediately
fsm
->
master_state
(
fsm
);
// execute immediately
}
}
...
@@ -434,7 +456,7 @@ void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -434,7 +456,7 @@ void ec_fsm_master_validate_vendor(ec_fsm_t *fsm /**< finite state machine */)
if
(
fsm
->
sii_state
!=
ec_fsm_sii_end
)
return
;
if
(
fsm
->
sii_state
!=
ec_fsm_sii_end
)
return
;
if
(
EC_READ_U32
(
fsm
->
sii_
result
)
!=
slave
->
sii_vendor_id
)
{
if
(
EC_READ_U32
(
fsm
->
sii_
value
)
!=
slave
->
sii_vendor_id
)
{
EC_ERR
(
"Slave %i: invalid vendor ID!
\n
"
,
slave
->
ring_position
);
EC_ERR
(
"Slave %i: invalid vendor ID!
\n
"
,
slave
->
ring_position
);
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
(
fsm
);
// execute immediately
fsm
->
master_state
(
fsm
);
// execute immediately
...
@@ -472,10 +494,10 @@ void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -472,10 +494,10 @@ void ec_fsm_master_validate_product(ec_fsm_t *fsm /**< finite state machine */)
if
(
fsm
->
sii_state
!=
ec_fsm_sii_end
)
return
;
if
(
fsm
->
sii_state
!=
ec_fsm_sii_end
)
return
;
if
(
EC_READ_U32
(
fsm
->
sii_
result
)
!=
slave
->
sii_product_code
)
{
if
(
EC_READ_U32
(
fsm
->
sii_
value
)
!=
slave
->
sii_product_code
)
{
EC_ERR
(
"Slave %i: invalid product code!
\n
"
,
slave
->
ring_position
);
EC_ERR
(
"Slave %i: invalid product code!
\n
"
,
slave
->
ring_position
);
EC_ERR
(
"expected 0x%08X, got 0x%08X.
\n
"
,
slave
->
sii_product_code
,
EC_ERR
(
"expected 0x%08X, got 0x%08X.
\n
"
,
slave
->
sii_product_code
,
EC_READ_U32
(
fsm
->
sii_
result
));
EC_READ_U32
(
fsm
->
sii_
value
));
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
(
fsm
);
// execute immediately
fsm
->
master_state
(
fsm
);
// execute immediately
return
;
return
;
...
@@ -666,6 +688,49 @@ void ec_fsm_master_conf(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -666,6 +688,49 @@ void ec_fsm_master_conf(ec_fsm_t *fsm /**< finite state machine */)
fsm
->
master_state
(
fsm
);
// execute immediately
fsm
->
master_state
(
fsm
);
// execute immediately
}
}
/*****************************************************************************/
/**
Master state: EEPROM.
*/
void
ec_fsm_master_eeprom
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
{
ec_slave_t
*
slave
=
fsm
->
slave
;
fsm
->
sii_state
(
fsm
);
// execute SII state machine
if
(
fsm
->
sii_state
==
ec_fsm_sii_error
)
{
EC_ERR
(
"Failed to write EEPROM contents to slave %i.
\n
"
,
slave
->
ring_position
);
kfree
(
slave
->
new_eeprom_data
);
slave
->
new_eeprom_data
=
NULL
;
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
(
fsm
);
// execute immediately
return
;
}
if
(
fsm
->
sii_state
!=
ec_fsm_sii_end
)
return
;
fsm
->
sii_offset
++
;
if
(
fsm
->
sii_offset
<
slave
->
new_eeprom_size
)
{
memcpy
(
fsm
->
sii_value
,
slave
->
new_eeprom_data
+
fsm
->
sii_offset
,
2
);
fsm
->
sii_state
=
ec_fsm_sii_start_writing
;
fsm
->
sii_state
(
fsm
);
// execute immediately
return
;
}
// finished writing EEPROM
EC_INFO
(
"Finished writing EEPROM of slave %i.
\n
"
,
slave
->
ring_position
);
kfree
(
slave
->
new_eeprom_data
);
slave
->
new_eeprom_data
=
NULL
;
// restart master state machine.
fsm
->
master_state
=
ec_fsm_master_start
;
fsm
->
master_state
(
fsm
);
// execute immediately
return
;
}
/******************************************************************************
/******************************************************************************
* slave state machine
* slave state machine
*****************************************************************************/
*****************************************************************************/
...
@@ -834,8 +899,8 @@ void ec_fsm_slave_fetch_eeprom(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -834,8 +899,8 @@ void ec_fsm_slave_fetch_eeprom(ec_fsm_t *fsm /**< finite state machine */)
if
(
fsm
->
sii_state
!=
ec_fsm_sii_end
)
return
;
if
(
fsm
->
sii_state
!=
ec_fsm_sii_end
)
return
;
cat_type
=
EC_READ_U16
(
fsm
->
sii_
result
);
cat_type
=
EC_READ_U16
(
fsm
->
sii_
value
);
cat_size
=
EC_READ_U16
(
fsm
->
sii_
result
+
2
);
cat_size
=
EC_READ_U16
(
fsm
->
sii_
value
+
2
);
if
(
cat_type
!=
0xFFFF
)
{
// not the last category
if
(
cat_type
!=
0xFFFF
)
{
// not the last category
fsm
->
sii_offset
+=
cat_size
+
2
;
fsm
->
sii_offset
+=
cat_size
+
2
;
...
@@ -895,10 +960,10 @@ void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -895,10 +960,10 @@ void ec_fsm_slave_fetch_eeprom2(ec_fsm_t *fsm /**< finite state machine */)
// 2 words fetched
// 2 words fetched
if
(
fsm
->
sii_offset
+
2
<=
slave
->
eeprom_size
/
2
)
{
// 2 words fit
if
(
fsm
->
sii_offset
+
2
<=
slave
->
eeprom_size
/
2
)
{
// 2 words fit
memcpy
(
slave
->
eeprom_data
+
fsm
->
sii_offset
*
2
,
fsm
->
sii_
result
,
4
);
memcpy
(
slave
->
eeprom_data
+
fsm
->
sii_offset
*
2
,
fsm
->
sii_
value
,
4
);
}
}
else
{
// copy the last word
else
{
// copy the last word
memcpy
(
slave
->
eeprom_data
+
fsm
->
sii_offset
*
2
,
fsm
->
sii_
result
,
2
);
memcpy
(
slave
->
eeprom_data
+
fsm
->
sii_offset
*
2
,
fsm
->
sii_
value
,
2
);
}
}
if
(
fsm
->
sii_offset
+
2
<
slave
->
eeprom_size
/
2
)
{
if
(
fsm
->
sii_offset
+
2
<
slave
->
eeprom_size
/
2
)
{
...
@@ -1305,17 +1370,17 @@ void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -1305,17 +1370,17 @@ void ec_fsm_sii_start_reading(ec_fsm_t *fsm /**< finite state machine */)
EC_WRITE_U8
(
command
->
data
+
1
,
0x01
);
// request read operation
EC_WRITE_U8
(
command
->
data
+
1
,
0x01
);
// request read operation
EC_WRITE_U16
(
command
->
data
+
2
,
fsm
->
sii_offset
);
EC_WRITE_U16
(
command
->
data
+
2
,
fsm
->
sii_offset
);
ec_master_queue_command
(
fsm
->
master
,
command
);
ec_master_queue_command
(
fsm
->
master
,
command
);
fsm
->
sii_state
=
ec_fsm_sii_check
;
fsm
->
sii_state
=
ec_fsm_sii_
read_
check
;
}
}
/*****************************************************************************/
/*****************************************************************************/
/**
/**
SII state: CHECK.
SII state:
READ_
CHECK.
Checks, if the SII-read-command has been sent and issues a fetch command.
Checks, if the SII-read-command has been sent and issues a fetch command.
*/
*/
void
ec_fsm_sii_check
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
void
ec_fsm_sii_
read_
check
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
{
{
ec_command_t
*
command
=
&
fsm
->
command
;
ec_command_t
*
command
=
&
fsm
->
command
;
...
@@ -1336,17 +1401,17 @@ void ec_fsm_sii_check(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -1336,17 +1401,17 @@ void ec_fsm_sii_check(ec_fsm_t *fsm /**< finite state machine */)
}
}
ec_master_queue_command
(
fsm
->
master
,
command
);
ec_master_queue_command
(
fsm
->
master
,
command
);
fsm
->
sii_state
=
ec_fsm_sii_fetch
;
fsm
->
sii_state
=
ec_fsm_sii_
read_
fetch
;
}
}
/*****************************************************************************/
/*****************************************************************************/
/**
/**
SII state: FETCH.
SII state:
READ_
FETCH.
Fetches the result of an SII-read command.
Fetches the result of an SII-read command.
*/
*/
void
ec_fsm_sii_fetch
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
void
ec_fsm_sii_
read_
fetch
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
{
{
ec_command_t
*
command
=
&
fsm
->
command
;
ec_command_t
*
command
=
&
fsm
->
command
;
...
@@ -1391,12 +1456,92 @@ void ec_fsm_sii_fetch(ec_fsm_t *fsm /**< finite state machine */)
...
@@ -1391,12 +1456,92 @@ void ec_fsm_sii_fetch(ec_fsm_t *fsm /**< finite state machine */)
#endif
#endif
// SII value received.
// SII value received.
memcpy
(
fsm
->
sii_
result
,
command
->
data
+
6
,
4
);
memcpy
(
fsm
->
sii_
value
,
command
->
data
+
6
,
4
);
fsm
->
sii_state
=
ec_fsm_sii_end
;
fsm
->
sii_state
=
ec_fsm_sii_end
;
}
}
/*****************************************************************************/
/*****************************************************************************/
/**
SII state: START_WRITING.
Starts reading the slave information interface.
*/
void
ec_fsm_sii_start_writing
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
{
ec_command_t
*
command
=
&
fsm
->
command
;
// initiate write operation
ec_command_npwr
(
command
,
fsm
->
slave
->
station_address
,
0x502
,
8
);
EC_WRITE_U8
(
command
->
data
,
0x01
);
// enable write access
EC_WRITE_U8
(
command
->
data
+
1
,
0x02
);
// request write operation
EC_WRITE_U32
(
command
->
data
+
2
,
fsm
->
sii_offset
);
memcpy
(
command
->
data
+
6
,
fsm
->
sii_value
,
2
);
ec_master_queue_command
(
fsm
->
master
,
command
);
fsm
->
sii_state
=
ec_fsm_sii_write_check
;
}
/*****************************************************************************/
/**
SII state: WRITE_CHECK.
*/
void
ec_fsm_sii_write_check
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
{
ec_command_t
*
command
=
&
fsm
->
command
;
if
(
command
->
state
!=
EC_CMD_RECEIVED
||
command
->
working_counter
!=
1
)
{
EC_ERR
(
"SII: Reception of write command failed.
\n
"
);
fsm
->
sii_state
=
ec_fsm_sii_error
;
return
;
}
fsm
->
sii_start
=
get_cycles
();
// issue check/fetch command
ec_command_nprd
(
command
,
fsm
->
slave
->
station_address
,
0x502
,
2
);
ec_master_queue_command
(
fsm
->
master
,
command
);
fsm
->
sii_state
=
ec_fsm_sii_write_check2
;
}
/*****************************************************************************/
/**
SII state: WRITE_CHECK2.
*/
void
ec_fsm_sii_write_check2
(
ec_fsm_t
*
fsm
/**< finite state machine */
)
{
ec_command_t
*
command
=
&
fsm
->
command
;
if
(
command
->
state
!=
EC_CMD_RECEIVED
||
command
->
working_counter
!=
1
)
{
EC_ERR
(
"SII: Reception of write check command failed.
\n
"
);
fsm
->
sii_state
=
ec_fsm_sii_error
;
return
;
}
if
(
EC_READ_U8
(
command
->
data
+
1
)
&
0x82
)
{
// still busy... timeout?
if
(
get_cycles
()
-
fsm
->
sii_start
>=
(
cycles_t
)
10
*
cpu_khz
)
{
EC_ERR
(
"SII: Write timeout.
\n
"
);
fsm
->
sii_state
=
ec_fsm_sii_error
;
}
// issue check/fetch command again
ec_master_queue_command
(
fsm
->
master
,
command
);
}
else
if
(
EC_READ_U8
(
command
->
data
+
1
)
&
0x40
)
{
EC_ERR
(
"SII: Write operation failed!
\n
"
);
fsm
->
sii_state
=
ec_fsm_sii_error
;
}
else
{
// success
fsm
->
sii_state
=
ec_fsm_sii_end
;
}
}
/*****************************************************************************/
/**
/**
SII state: END.
SII state: END.
End state of the slave SII state machine.
End state of the slave SII state machine.
...
...
This diff is collapsed.
Click to expand it.
master/fsm.h
+
1
−
1
View file @
ff953519
...
@@ -71,7 +71,7 @@ struct ec_fsm
...
@@ -71,7 +71,7 @@ struct ec_fsm
void
(
*
sii_state
)(
ec_fsm_t
*
);
/**< SII state function */
void
(
*
sii_state
)(
ec_fsm_t
*
);
/**< SII state function */
uint16_t
sii_offset
;
/**< input: offset in SII */
uint16_t
sii_offset
;
/**< input: offset in SII */
unsigned
int
sii_mode
;
/**< SII reading done by APRD (0) or NPRD (1) */
unsigned
int
sii_mode
;
/**< SII reading done by APRD (0) or NPRD (1) */
uint8_t
sii_
result
[
4
];
/**<
output:
raw SII value (32bit) */
uint8_t
sii_
value
[
4
];
/**< raw SII value (32bit) */
cycles_t
sii_start
;
/**< sii start */
cycles_t
sii_start
;
/**< sii start */
void
(
*
change_state
)(
ec_fsm_t
*
);
/**< slave state change state function */
void
(
*
change_state
)(
ec_fsm_t
*
);
/**< slave state change state function */
...
...
This diff is collapsed.
Click to expand it.
master/slave.c
+
85
−
1
View file @
ff953519
...
@@ -69,7 +69,7 @@ EC_SYSFS_READ_ATTR(product_desc);
...
@@ -69,7 +69,7 @@ EC_SYSFS_READ_ATTR(product_desc);
EC_SYSFS_READ_ATTR
(
sii_name
);
EC_SYSFS_READ_ATTR
(
sii_name
);
EC_SYSFS_READ_ATTR
(
type
);
EC_SYSFS_READ_ATTR
(
type
);
EC_SYSFS_READ_WRITE_ATTR
(
state
);
EC_SYSFS_READ_WRITE_ATTR
(
state
);
EC_SYSFS_READ_ATTR
(
eeprom
);
EC_SYSFS_READ_
WRITE_
ATTR
(
eeprom
);
static
struct
attribute
*
def_attrs
[]
=
{
static
struct
attribute
*
def_attrs
[]
=
{
&
attr_ring_position
,
&
attr_ring_position
,
...
@@ -157,6 +157,8 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
...
@@ -157,6 +157,8 @@ int ec_slave_init(ec_slave_t *slave, /**< EtherCAT slave */
slave
->
current_state
=
EC_SLAVE_STATE_UNKNOWN
;
slave
->
current_state
=
EC_SLAVE_STATE_UNKNOWN
;
slave
->
state_error
=
0
;
slave
->
state_error
=
0
;
slave
->
online
=
1
;
slave
->
online
=
1
;
slave
->
new_eeprom_data
=
NULL
;
slave
->
new_eeprom_size
=
0
;
ec_command_init
(
&
slave
->
mbox_command
);
ec_command_init
(
&
slave
->
mbox_command
);
...
@@ -239,6 +241,7 @@ void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
...
@@ -239,6 +241,7 @@ void ec_slave_clear(struct kobject *kobj /**< kobject of the slave */)
}
}
if
(
slave
->
eeprom_data
)
kfree
(
slave
->
eeprom_data
);
if
(
slave
->
eeprom_data
)
kfree
(
slave
->
eeprom_data
);
if
(
slave
->
new_eeprom_data
)
kfree
(
slave
->
new_eeprom_data
);
ec_command_clear
(
&
slave
->
mbox_command
);
ec_command_clear
(
&
slave
->
mbox_command
);
}
}
...
@@ -1246,6 +1249,83 @@ int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */)
...
@@ -1246,6 +1249,83 @@ int ec_slave_check_crc(ec_slave_t *slave /**< EtherCAT slave */)
/*****************************************************************************/
/*****************************************************************************/
/**
Schedules an EEPROM write operation.
\return 0 in case of success, else < 0
*/
ssize_t
ec_slave_write_eeprom
(
ec_slave_t
*
slave
,
/**< EtherCAT slave */
const
uint8_t
*
data
,
/**< new EEPROM data */
size_t
size
/**< size of data in bytes */
)
{
uint16_t
word_size
,
cat_type
,
cat_size
;
const
uint16_t
*
data_words
,
*
next_header
;
uint16_t
*
new_data
;
if
(
!
slave
->
master
->
eeprom_write_enable
)
{
EC_ERR
(
"Writing EEPROMs not allowed! Enable via"
" eeprom_write_enable SysFS entry.
\n
"
);
return
-
1
;
}
if
(
slave
->
master
->
mode
!=
EC_MASTER_MODE_FREERUN
)
{
EC_ERR
(
"Writing EEPROMs only allowed in freerun mode!
\n
"
);
return
-
1
;
}
if
(
slave
->
new_eeprom_data
)
{
EC_ERR
(
"Slave %i already has a pending EEPROM write operation!
\n
"
,
slave
->
ring_position
);
return
-
1
;
}
// coarse check of the data
if
(
size
%
2
)
{
EC_ERR
(
"EEPROM size is odd! Dropping.
\n
"
);
return
-
1
;
}
data_words
=
(
const
uint16_t
*
)
data
;
word_size
=
size
/
2
;
if
(
word_size
<
0x0041
)
{
EC_ERR
(
"EEPROM data too short! Dropping.
\n
"
);
return
-
1
;
}
next_header
=
data_words
+
0x0040
;
cat_type
=
EC_READ_U16
(
next_header
);
while
(
cat_type
!=
0xFFFF
)
{
cat_type
=
EC_READ_U16
(
next_header
);
cat_size
=
EC_READ_U16
(
next_header
+
1
);
if
((
next_header
+
cat_size
+
2
)
-
data_words
>=
word_size
)
{
EC_ERR
(
"EEPROM data seems to be corrupted! Dropping.
\n
"
);
return
-
1
;
}
next_header
+=
cat_size
+
2
;
cat_type
=
EC_READ_U16
(
next_header
);
}
// data ok!
if
(
!
(
new_data
=
(
uint16_t
*
)
kmalloc
(
word_size
*
2
,
GFP_KERNEL
)))
{
EC_ERR
(
"Unable to allocate memory for new EEPROM data!
\n
"
);
return
-
1
;
}
memcpy
(
new_data
,
data
,
size
);
slave
->
new_eeprom_size
=
word_size
;
slave
->
new_eeprom_data
=
new_data
;
EC_INFO
(
"EEPROM writing scheduled for slave %i, %i words.
\n
"
,
slave
->
ring_position
,
word_size
);
return
0
;
}
/*****************************************************************************/
/**
/**
Formats attribute data for SysFS read access.
Formats attribute data for SysFS read access.
\return number of bytes to read
\return number of bytes to read
...
@@ -1359,6 +1439,10 @@ ssize_t ec_store_slave_attribute(struct kobject *kobj, /**< slave's kobject */
...
@@ -1359,6 +1439,10 @@ ssize_t ec_store_slave_attribute(struct kobject *kobj, /**< slave's kobject */
EC_ERR
(
"Failed to set slave state!
\n
"
);
EC_ERR
(
"Failed to set slave state!
\n
"
);
}
}
else
if
(
attr
==
&
attr_eeprom
)
{
if
(
!
ec_slave_write_eeprom
(
slave
,
buffer
,
size
))
return
size
;
}
return
-
EINVAL
;
return
-
EINVAL
;
}
}
...
...
This diff is collapsed.
Click to expand it.
master/slave.h
+
3
−
0
View file @
ff953519
...
@@ -271,6 +271,9 @@ struct ec_slave
...
@@ -271,6 +271,9 @@ struct ec_slave
char
*
eeprom_order
;
/**< slave order number acc. to EEPROM */
char
*
eeprom_order
;
/**< slave order number acc. to EEPROM */
char
*
eeprom_name
;
/**< slave name acc. to EEPROM */
char
*
eeprom_name
;
/**< slave name acc. to EEPROM */
uint16_t
*
new_eeprom_data
;
/**< new EEPROM data to write */
size_t
new_eeprom_size
;
/**< size of new EEPROM data in words */
struct
list_head
sdo_dictionary
;
/**< SDO directory list */
struct
list_head
sdo_dictionary
;
/**< SDO directory list */
ec_command_t
mbox_command
;
/**< mailbox command */
ec_command_t
mbox_command
;
/**< mailbox command */
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment