# HG changeset patch # User Florian Pose # Date 1204561359 0 # Node ID f4f53be425aceca8e67278789579ea24665c5f60 # Parent 726326d0aef4f0a581757638e71dde405dd5c573 Removed ec_sdodata_t; CoE state machines work on ec_sdo_request_t. diff -r 726326d0aef4 -r f4f53be425ac TODO --- a/TODO Mon Mar 03 16:17:23 2008 +0000 +++ b/TODO Mon Mar 03 16:22:39 2008 +0000 @@ -25,7 +25,6 @@ * Adapt remaining examples. * Separate Pdo and Pdo entry classes. * Attach Pdo names. -* Replace ec_sdo_data_t with ec_sdo_request_t. * Make all define underscores the same. Future issues: diff -r 726326d0aef4 -r f4f53be425ac master/fsm_coe.c --- a/master/fsm_coe.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_coe.c Mon Mar 03 16:22:39 2008 +0000 @@ -183,13 +183,14 @@ Starts to download an Sdo to a slave. */ -void ec_fsm_coe_download(ec_fsm_coe_t *fsm, /**< finite state machine */ - ec_slave_t *slave, /**< EtherCAT slave */ - ec_sdo_data_t *sdodata /**< Sdo data object */ - ) +void ec_fsm_coe_download( + ec_fsm_coe_t *fsm, /**< State machine. */ + ec_slave_t *slave, /**< EtherCAT slave. */ + ec_sdo_request_t *request /**< Sdo request. */ + ) { fsm->slave = slave; - fsm->sdodata = sdodata; + fsm->request = request; fsm->state = ec_fsm_coe_down_start; } @@ -954,12 +955,12 @@ { ec_datagram_t *datagram = fsm->datagram; ec_slave_t *slave = fsm->slave; - ec_sdo_data_t *sdodata = fsm->sdodata; + ec_sdo_request_t *request = fsm->request; uint8_t *data; if (fsm->slave->master->debug_level) EC_DBG("Downloading Sdo 0x%04X:%i to slave %i.\n", - sdodata->index, sdodata->subindex, slave->ring_position); + request->index, request->subindex, slave->ring_position); if (!(slave->sii.mailbox_protocols & EC_MBOX_COE)) { EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); @@ -967,14 +968,14 @@ return; } - if (slave->sii.rx_mailbox_size < 6 + 10 + sdodata->size) { + if (slave->sii.rx_mailbox_size < 6 + 10 + request->data_size) { EC_ERR("Sdo fragmenting not supported yet!\n"); fsm->state = ec_fsm_coe_error; return; } if (!(data = ec_slave_mbox_prepare_send(slave, datagram, 0x03, - sdodata->size + 10))) { + request->data_size + 10))) { fsm->state = ec_fsm_coe_error; return; } @@ -982,10 +983,10 @@ EC_WRITE_U16(data, 0x2 << 12); // Sdo request EC_WRITE_U8 (data + 2, (0x1 // size specified | 0x1 << 5)); // Download request - EC_WRITE_U16(data + 3, sdodata->index); - EC_WRITE_U8 (data + 5, sdodata->subindex); - EC_WRITE_U32(data + 6, sdodata->size); - memcpy(data + 10, sdodata->data, sdodata->size); + EC_WRITE_U16(data + 3, request->index); + EC_WRITE_U8 (data + 5, request->subindex); + EC_WRITE_U32(data + 6, request->data_size); + memcpy(data + 10, request->data, request->data_size); fsm->retries = EC_FSM_RETRIES; fsm->state = ec_fsm_coe_down_request; @@ -1092,7 +1093,7 @@ ec_slave_t *slave = fsm->slave; uint8_t *data, mbox_prot; size_t rec_size; - ec_sdo_data_t *sdodata = fsm->sdodata; + ec_sdo_request_t *request = fsm->request; if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--) return; // FIXME: request again? @@ -1136,7 +1137,7 @@ EC_READ_U8 (data + 2) >> 5 == 0x4) { // abort Sdo transfer request fsm->state = ec_fsm_coe_error; EC_ERR("Sdo download 0x%04X:%X (%i bytes) aborted on slave %i.\n", - sdodata->index, sdodata->subindex, sdodata->size, + request->index, request->subindex, request->data_size, slave->ring_position); if (rec_size < 10) { EC_ERR("Incomplete Abort command:\n"); @@ -1149,11 +1150,11 @@ if (EC_READ_U16(data) >> 12 != 0x3 || // Sdo response EC_READ_U8 (data + 2) >> 5 != 0x3 || // Download response - EC_READ_U16(data + 3) != sdodata->index || // index - EC_READ_U8 (data + 5) != sdodata->subindex) { // subindex + EC_READ_U16(data + 3) != request->index || // index + EC_READ_U8 (data + 5) != request->subindex) { // subindex fsm->state = ec_fsm_coe_error; EC_ERR("Sdo download 0x%04X:%X (%i bytes) failed:\n", - sdodata->index, sdodata->subindex, sdodata->size); + request->index, request->subindex, request->data_size); EC_ERR("Invalid Sdo download response at slave %i!\n", slave->ring_position); ec_print_data(data, rec_size); @@ -1368,12 +1369,6 @@ return; } - if (request->data) { - kfree(request->data); - request->data = NULL; - } - request->size = 0; - // normal or expedited? expedited = EC_READ_U8(data + 2) & 0x02; @@ -1414,18 +1409,10 @@ return; } - if (!(request->data = (uint8_t *) - kmalloc(complete_size + 1, GFP_ATOMIC))) { - EC_ERR("Failed to allocate %i bytes of Sdo data!\n", - complete_size); - fsm->state = ec_fsm_coe_error; - return; - } - request->data[complete_size] = 0x00; // just to be sure... - - memcpy(request->data, data + 6, complete_size); - request->size = complete_size; - + if (ec_sdo_request_copy_data(request, data + 6, complete_size)) { + fsm->state = ec_fsm_coe_error; + return; + } } else { // normal if (rec_size < 10) { EC_ERR("Received currupted Sdo normal upload" @@ -1458,17 +1445,16 @@ return; } - if (!(request->data = (uint8_t *) - kmalloc(complete_size + 1, GFP_ATOMIC))) { - EC_ERR("Failed to allocate %i bytes of Sdo data!\n", - complete_size); - fsm->state = ec_fsm_coe_error; - return; - } - request->data[complete_size] = 0x00; // just to be sure... - - memcpy(request->data, data + 10, data_size); - request->size = complete_size; + if (ec_sdo_request_alloc(request, complete_size)) { + fsm->state = ec_fsm_coe_error; + return; + } + + if (ec_sdo_request_copy_data(request, data + 10, data_size)) { + fsm->state = ec_fsm_coe_error; + return; + } + fsm->toggle = 0; if (data_size < complete_size) { @@ -1592,6 +1578,7 @@ /** CoE state: UP RESPONSE. \todo Timeout behavior + \todo Check for \a data_size exceeding \a complete_size. */ void ec_fsm_coe_up_seg_response(ec_fsm_coe_t *fsm /**< finite state machine */) @@ -1677,8 +1664,8 @@ data_size, seg_size); } - memcpy(request->data + request->size, data + 10, data_size); - request->size += data_size; + memcpy(request->data + request->data_size, data + 10, data_size); + request->data_size += data_size; if (!last_segment) { fsm->toggle = !fsm->toggle; diff -r 726326d0aef4 -r f4f53be425ac master/fsm_coe.h --- a/master/fsm_coe.h Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_coe.h Mon Mar 03 16:22:39 2008 +0000 @@ -60,7 +60,6 @@ unsigned int retries; /**< retries upon datagram timeout */ void (*state)(ec_fsm_coe_t *); /**< CoE state function */ - ec_sdo_data_t *sdodata; /**< input/output: Sdo data object */ cycles_t cycles_start; /**< CoE timestamp */ ec_sdo_t *sdo; /**< current Sdo */ uint8_t subindex; /**< current subindex */ @@ -74,7 +73,7 @@ void ec_fsm_coe_clear(ec_fsm_coe_t *); void ec_fsm_coe_dictionary(ec_fsm_coe_t *, ec_slave_t *); -void ec_fsm_coe_download(ec_fsm_coe_t *, ec_slave_t *, ec_sdo_data_t *); +void ec_fsm_coe_download(ec_fsm_coe_t *, ec_slave_t *, ec_sdo_request_t *); void ec_fsm_coe_upload(ec_fsm_coe_t *, ec_slave_t *, ec_sdo_request_t *); int ec_fsm_coe_exec(ec_fsm_coe_t *); diff -r 726326d0aef4 -r f4f53be425ac master/fsm_coe_map.c --- a/master/fsm_coe_map.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_coe_map.c Mon Mar 03 16:22:39 2008 +0000 @@ -181,7 +181,8 @@ ec_pdo_mapping_clear_pdos(&fsm->mapping); - ec_sdo_request_read(&fsm->request, fsm->sync_sdo_index, 0); + ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, 0); + ec_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_count; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -235,8 +236,9 @@ ) { if (fsm->sync_subindex <= fsm->sync_subindices) { - ec_sdo_request_read(&fsm->request, fsm->sync_sdo_index, + ec_sdo_request_address(&fsm->request, fsm->sync_sdo_index, fsm->sync_subindex); + ec_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -292,7 +294,8 @@ list_add_tail(&fsm->pdo->list, &fsm->mapping.pdos); - ec_sdo_request_read(&fsm->request, fsm->pdo->index, 0); + ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); + ec_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_entry_count; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately @@ -338,7 +341,8 @@ ) { if (fsm->pdo_subindex <= fsm->pdo_subindices) { - ec_sdo_request_read(&fsm->request, fsm->pdo->index, fsm->pdo_subindex); + ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->pdo_subindex); + ec_sdo_request_read(&fsm->request); fsm->state = ec_fsm_coe_map_state_pdo_entry; ec_fsm_coe_upload(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately diff -r 726326d0aef4 -r f4f53be425ac master/fsm_pdo_config.c --- a/master/fsm_pdo_config.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_pdo_config.c Mon Mar 03 16:22:39 2008 +0000 @@ -65,7 +65,7 @@ ) { fsm->fsm_coe = fsm_coe; - fsm->sdodata.data = (uint8_t *) &fsm->sdo_value; + ec_sdo_request_init(&fsm->request); } /*****************************************************************************/ @@ -76,6 +76,7 @@ ec_fsm_pdo_config_t *fsm /**< pdo_config state machine */ ) { + ec_sdo_request_clear(&fsm->request); } /*****************************************************************************/ @@ -204,17 +205,22 @@ fsm->pdo->index, fsm->slave->ring_position); } + if (ec_sdo_request_alloc(&fsm->request, 4)) { + fsm->state = ec_fsm_pdo_config_state_error; + return; + } + // set mapped Pdo count to zero - fsm->sdodata.index = fsm->pdo->index; - fsm->sdodata.subindex = 0; // number of configured entries - EC_WRITE_U8(&fsm->sdo_value, 0); - fsm->sdodata.size = 1; + EC_WRITE_U8(&fsm->request.data, 0); + fsm->request.data_size = 1; + ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); + ec_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting entry count to zero for Pdo 0x%04X.\n", fsm->pdo->index); fsm->state = ec_fsm_pdo_config_state_zero_count; - ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->sdodata); + ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately } @@ -243,18 +249,18 @@ { uint32_t value; - fsm->sdodata.subindex = fsm->entry_count; value = fsm->entry->index << 16 | fsm->entry->subindex << 8 | fsm->entry->bit_length; - EC_WRITE_U32(&fsm->sdo_value, value); - fsm->sdodata.size = 4; - + EC_WRITE_U32(&fsm->request.data, value); + fsm->request.data_size = 4; + ec_sdo_request_address(&fsm->request, fsm->pdo->index, fsm->entry_count); + ec_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Configuring Pdo entry %08X at position %u.\n", value, fsm->entry_count); fsm->state = ec_fsm_pdo_config_state_add_entry; - ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->sdodata); + ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately } @@ -311,16 +317,16 @@ // find next entry if (!(fsm->entry = ec_fsm_pdo_config_next_entry(fsm, &fsm->entry->list))) { // No more entries to add. Write entry count. - fsm->sdodata.subindex = 0; - EC_WRITE_U8(&fsm->sdo_value, fsm->entry_count); - fsm->sdodata.size = 1; - + EC_WRITE_U8(&fsm->request.data, fsm->entry_count); + fsm->request.data_size = 1; + ec_sdo_request_address(&fsm->request, fsm->pdo->index, 0); + ec_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting number of Pdo entries to %u.\n", fsm->entry_count); fsm->state = ec_fsm_pdo_config_state_entry_count; - ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->sdodata); + ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately return; } diff -r 726326d0aef4 -r f4f53be425ac master/fsm_pdo_config.h --- a/master/fsm_pdo_config.h Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_pdo_config.h Mon Mar 03 16:22:39 2008 +0000 @@ -63,8 +63,7 @@ const ec_pdo_t *pdo; /**< Current Pdo to configure. */ const ec_pdo_entry_t *entry; /**< Current entry. */ - ec_sdo_data_t sdodata; /**< Sdo configuration data. */ - uint16_t sdo_value; /**< Sdo value. */ + ec_sdo_request_t request; /**< Sdo request. */ unsigned int entry_count; /**< Number of configured entries. */ }; diff -r 726326d0aef4 -r f4f53be425ac master/fsm_pdo_mapping.c --- a/master/fsm_pdo_mapping.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_pdo_mapping.c Mon Mar 03 16:22:39 2008 +0000 @@ -65,7 +65,7 @@ ) { fsm->fsm_coe = fsm_coe; - fsm->sdodata.data = (uint8_t *) &fsm->sdo_value; + ec_sdo_request_init(&fsm->request); } /*****************************************************************************/ @@ -76,6 +76,7 @@ ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ ) { + ec_sdo_request_clear(&fsm->request); } /*****************************************************************************/ @@ -195,16 +196,21 @@ fsm->sync->index, fsm->slave->ring_position); } + if (ec_sdo_request_alloc(&fsm->request, 2)) { + fsm->state = ec_fsm_pdo_mapping_state_error; + return; + } + // set mapped Pdo count to zero - fsm->sdodata.index = 0x1C10 + fsm->sync->index; - fsm->sdodata.subindex = 0; // mapped Pdo count - EC_WRITE_U8(&fsm->sdo_value, 0); // zero Pdos mapped - fsm->sdodata.size = 1; + EC_WRITE_U8(&fsm->request.data, 0); // zero Pdos mapped + fsm->request.data_size = 1; + ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); + ec_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting Pdo count to zero for SM%u.\n", fsm->sync->index); fsm->state = ec_fsm_pdo_mapping_state_zero_count; - ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->sdodata); + ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately return; } @@ -238,16 +244,17 @@ ec_fsm_pdo_mapping_t *fsm /**< mapping state machine */ ) { - fsm->sdodata.subindex = fsm->pdo_count; - EC_WRITE_U16(&fsm->sdo_value, fsm->pdo->index); - fsm->sdodata.size = 2; - + EC_WRITE_U16(&fsm->request.data, fsm->pdo->index); + fsm->request.data_size = 2; + ec_sdo_request_address(&fsm->request, + 0x1C10 + fsm->sync->index, fsm->pdo_count); + ec_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Mapping Pdo 0x%04X at position %u.\n", - fsm->pdo->index, fsm->sdodata.subindex); + fsm->pdo->index, fsm->pdo_count); fsm->state = ec_fsm_pdo_mapping_state_add_pdo; - ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->sdodata); + ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately } @@ -304,16 +311,16 @@ // find next Pdo if (!(fsm->pdo = ec_fsm_pdo_mapping_next_pdo(fsm, &fsm->pdo->list))) { // no more Pdos to map. write Pdo count - fsm->sdodata.subindex = 0; - EC_WRITE_U8(&fsm->sdo_value, fsm->pdo_count); - fsm->sdodata.size = 1; - + EC_WRITE_U8(&fsm->request.data, fsm->pdo_count); + fsm->request.data_size = 1; + ec_sdo_request_address(&fsm->request, 0x1C10 + fsm->sync->index, 0); + ec_sdo_request_write(&fsm->request); if (fsm->slave->master->debug_level) EC_DBG("Setting number of mapped Pdos to %u.\n", fsm->pdo_count); fsm->state = ec_fsm_pdo_mapping_state_pdo_count; - ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->sdodata); + ec_fsm_coe_download(fsm->fsm_coe, fsm->slave, &fsm->request); ec_fsm_coe_exec(fsm->fsm_coe); // execute immediately return; } diff -r 726326d0aef4 -r f4f53be425ac master/fsm_pdo_mapping.h --- a/master/fsm_pdo_mapping.h Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_pdo_mapping.h Mon Mar 03 16:22:39 2008 +0000 @@ -67,8 +67,7 @@ const ec_pdo_mapping_t *mapping; /**< Target Pdo mapping. */ const ec_pdo_t *pdo; /**< Current Pdo. */ - ec_sdo_data_t sdodata; /**< Sdo configuration data. */ - uint16_t sdo_value; /**< Sdo value. */ + ec_sdo_request_t request; /**< Sdo request. */ unsigned int pdo_count; /**< Number of mapped Pdos. */ }; diff -r 726326d0aef4 -r f4f53be425ac master/fsm_slave_config.c --- a/master/fsm_slave_config.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_slave_config.c Mon Mar 03 16:22:39 2008 +0000 @@ -448,9 +448,10 @@ // start Sdo configuration fsm->state = ec_fsm_slave_config_state_sdo_conf; - fsm->sdodata = - list_entry(fsm->slave->config->sdo_configs.next, ec_sdo_data_t, list); - ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->sdodata); + fsm->request = list_entry(fsm->slave->config->sdo_configs.next, + ec_sdo_request_t, list); + ec_sdo_request_write(fsm->request); + ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->request); ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately } @@ -475,10 +476,11 @@ } // Another Sdo to configure? - if (fsm->sdodata->list.next != &fsm->slave->config->sdo_configs) { - fsm->sdodata = - list_entry(fsm->sdodata->list.next, ec_sdo_data_t, list); - ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->sdodata); + if (fsm->request->list.next != &fsm->slave->config->sdo_configs) { + fsm->request = list_entry(fsm->request->list.next, ec_sdo_request_t, + list); + ec_sdo_request_write(fsm->request); + ec_fsm_coe_download(&fsm->fsm_coe, fsm->slave, fsm->request); ec_fsm_coe_exec(&fsm->fsm_coe); // execute immediately return; } diff -r 726326d0aef4 -r f4f53be425ac master/fsm_slave_config.h --- a/master/fsm_slave_config.h Mon Mar 03 16:17:23 2008 +0000 +++ b/master/fsm_slave_config.h Mon Mar 03 16:22:39 2008 +0000 @@ -65,7 +65,7 @@ unsigned int retries; /**< Retries on datagram timeout. */ void (*state)(ec_fsm_slave_config_t *); /**< State function. */ - ec_sdo_data_t *sdodata; /**< Sdo configuration data. */ + ec_sdo_request_t *request; /**< Sdo request for Sdo configuration. */ ec_fsm_change_t fsm_change; /**< State change state machine. */ ec_fsm_coe_t fsm_coe; /**< CoE state machine. */ ec_fsm_pdo_mapping_t fsm_pdo_map; /**< Pdo mapping state machine. */ diff -r 726326d0aef4 -r f4f53be425ac master/sdo.h --- a/master/sdo.h Mon Mar 03 16:17:23 2008 +0000 +++ b/master/sdo.h Mon Mar 03 16:22:39 2008 +0000 @@ -64,20 +64,6 @@ /*****************************************************************************/ -/** CANopen Sdo configuration data. - * \todo remove - */ -typedef struct { - struct list_head list; /**< list item */ - uint16_t index; /**< Sdo index */ - uint8_t subindex; /**< Sdo subindex */ - uint8_t *data; /**< pointer to Sdo data */ - size_t size; /**< size of Sdo data */ -} -ec_sdo_data_t; - -/*****************************************************************************/ - int ec_sdo_init(ec_sdo_t *, uint16_t, ec_slave_t *); void ec_sdo_destroy(ec_sdo_t *); diff -r 726326d0aef4 -r f4f53be425ac master/sdo_entry.c --- a/master/sdo_entry.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/sdo_entry.c Mon Mar 03 16:22:39 2008 +0000 @@ -242,7 +242,7 @@ "Invalid bit length %u for data type 0x%04X. Data:\n", entry->bit_length, entry->data_type); raw_data: - for (i = 0; i < request->size; i++) + for (i = 0; i < request->data_size; i++) off += sprintf(buffer + off, "%02X (%c)\n", request->data[i], request->data[i]); return off; @@ -268,7 +268,8 @@ request.slave = entry->sdo->slave; ec_sdo_request_init(&request.req); - ec_sdo_request_read(&request.req, entry->sdo->index, entry->subindex); + ec_sdo_request_address(&request.req, entry->sdo->index, entry->subindex); + ec_sdo_request_read(&request.req); // schedule request. down(&master->sdo_sem); diff -r 726326d0aef4 -r f4f53be425ac master/sdo_request.c --- a/master/sdo_request.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/sdo_request.c Mon Mar 03 16:22:39 2008 +0000 @@ -55,7 +55,8 @@ ) { req->data = NULL; - req->size = 0; + req->mem_size = 0; + req->data_size = 0; req->state = EC_REQUEST_COMPLETE; } @@ -83,14 +84,15 @@ req->data = NULL; } - req->size = 0; + req->mem_size = 0; + req->data_size = 0; } /*****************************************************************************/ -/** Start an Sdo read operation (download). +/** Set the Sdo address. */ -void ec_sdo_request_read( +void ec_sdo_request_address( ec_sdo_request_t *req, /**< Sdo request. */ uint16_t index, /**< Sdo index. */ uint8_t subindex /**< Sdo subindex. */ @@ -98,9 +100,74 @@ { req->index = index; req->subindex = subindex; - req->state = EC_REQUEST_QUEUED; - - ec_sdo_request_clear_data(req); } /*****************************************************************************/ + +/** Pre-allocates the data memory. + * + * If the \a mem_size is already bigger than \a size, nothing is done. + */ +int ec_sdo_request_alloc( + ec_sdo_request_t *req, /**< Sdo request. */ + size_t size /**< Data size to allocate. */ + ) +{ + if (size <= req->mem_size) + return 0; + + ec_sdo_request_clear_data(req); + + if (!(req->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { + EC_ERR("Failed to allocate %u bytes of Sdo memory.\n", size); + return -1; + } + + req->mem_size = size; + req->data_size = 0; + return 0; +} + +/*****************************************************************************/ + +/** Copies Sdo data from an external source. + * + * If the \a mem_size is to small, new memory is allocated. + */ +int ec_sdo_request_copy_data( + ec_sdo_request_t *req, /**< Sdo request. */ + const uint8_t *source, /**< Source data. */ + size_t size /**< Number of bytes in \a source. */ + ) +{ + if (ec_sdo_request_alloc(req, size)) + return -1; + + memcpy(req->data, source, size); + req->data_size = size; + return 0; +} + +/*****************************************************************************/ + +/** Start an Sdo read operation (Sdo upload). + */ +void ec_sdo_request_read( + ec_sdo_request_t *req /**< Sdo request. */ + ) +{ + req->state = EC_REQUEST_QUEUED; +} + +/*****************************************************************************/ + +/** Start an Sdo write operation (Sdo download). + */ +void ec_sdo_request_write( + ec_sdo_request_t *req /**< Sdo request. */ + ) +{ + req->state = EC_REQUEST_QUEUED; +} + +/*****************************************************************************/ diff -r 726326d0aef4 -r f4f53be425ac master/sdo_request.h --- a/master/sdo_request.h Mon Mar 03 16:17:23 2008 +0000 +++ b/master/sdo_request.h Mon Mar 03 16:22:39 2008 +0000 @@ -54,7 +54,8 @@ uint16_t index; /**< Sdo index. */ uint8_t subindex; /**< Sdo subindex. */ uint8_t *data; /**< Pointer to Sdo data. */ - size_t size; /**< Size of Sdo data. */ + size_t mem_size; /**< Size of Sdo data memory. */ + size_t data_size; /**< Size of Sdo data. */ ec_request_state_t state; /**< Sdo request state. */ } ec_sdo_request_t; @@ -63,7 +64,12 @@ void ec_sdo_request_init(ec_sdo_request_t *); void ec_sdo_request_clear(ec_sdo_request_t *); -void ec_sdo_request_read(ec_sdo_request_t *, uint16_t, uint8_t); +void ec_sdo_request_address(ec_sdo_request_t *, uint16_t, uint8_t); +int ec_sdo_request_alloc(ec_sdo_request_t *, size_t); +int ec_sdo_request_copy_data(ec_sdo_request_t *, const uint8_t *, size_t); + +void ec_sdo_request_read(ec_sdo_request_t *); +void ec_sdo_request_write(ec_sdo_request_t *); /*****************************************************************************/ diff -r 726326d0aef4 -r f4f53be425ac master/slave_config.c --- a/master/slave_config.c Mon Mar 03 16:17:23 2008 +0000 +++ b/master/slave_config.c Mon Mar 03 16:22:39 2008 +0000 @@ -159,7 +159,7 @@ { ec_slave_config_t *sc; ec_direction_t dir; - ec_sdo_data_t *sdodata, *next_sdodata; + ec_sdo_request_t *req, *next_req; sc = container_of(kobj, ec_slave_config_t, kobj); @@ -168,13 +168,11 @@ ec_pdo_mapping_clear(&sc->mapping[dir]); // free all Sdo configurations - list_for_each_entry_safe(sdodata, next_sdodata, &sc->sdo_configs, list) { - list_del(&sdodata->list); - kfree(sdodata->data); - kfree(sdodata); - } - - /** \todo */ + list_for_each_entry_safe(req, next_req, &sc->sdo_configs, list) { + list_del(&req->list); + ec_sdo_request_clear(req); + kfree(req); + } kfree(sc); } @@ -234,7 +232,7 @@ const ec_pdo_t *pdo; const ec_pdo_entry_t *entry; char str[20]; - ec_sdo_data_t *sdodata; + const ec_sdo_request_t *req; buf += sprintf(buf, "Alias: 0x%04X (%u)\n", sc->alias, sc->alias); buf += sprintf(buf, "Position: %u\n", sc->position); @@ -265,15 +263,15 @@ if (!list_empty((struct list_head *) &sc->sdo_configs)) { buf += sprintf(buf, "\nSdo configurations:\n"); - list_for_each_entry(sdodata, &sc->sdo_configs, list) { - switch (sdodata->size) { - case 1: sprintf(str, "%u", EC_READ_U8(sdodata->data)); break; - case 2: sprintf(str, "%u", EC_READ_U16(sdodata->data)); break; - case 4: sprintf(str, "%u", EC_READ_U32(sdodata->data)); break; + list_for_each_entry(req, &sc->sdo_configs, list) { + switch (req->data_size) { + case 1: sprintf(str, "%u", EC_READ_U8(req->data)); break; + case 2: sprintf(str, "%u", EC_READ_U16(req->data)); break; + case 4: sprintf(str, "%u", EC_READ_U32(req->data)); break; default: sprintf(str, "(invalid size)"); break; } buf += sprintf(buf, " 0x%04X:%-3i -> %s\n", - sdodata->index, sdodata->subindex, str); + req->index, req->subindex, str); } buf += sprintf(buf, "\n"); } @@ -310,31 +308,29 @@ uint8_t subindex, const uint8_t *data, size_t size) { ec_slave_t *slave = sc->slave; - ec_sdo_data_t *sdodata; + ec_sdo_request_t *req; if (slave && !(slave->sii.mailbox_protocols & EC_MBOX_COE)) { EC_ERR("Slave %u does not support CoE!\n", slave->ring_position); return -1; } - if (!(sdodata = (ec_sdo_data_t *) - kmalloc(sizeof(ec_sdo_data_t), GFP_KERNEL))) { - EC_ERR("Failed to allocate memory for Sdo configuration object!\n"); + if (!(req = (ec_sdo_request_t *) + kmalloc(sizeof(ec_sdo_request_t), GFP_KERNEL))) { + EC_ERR("Failed to allocate memory for Sdo configuration!\n"); return -1; } - if (!(sdodata->data = (uint8_t *) kmalloc(size, GFP_KERNEL))) { - EC_ERR("Failed to allocate memory for Sdo configuration data!\n"); - kfree(sdodata); + ec_sdo_request_init(req); + ec_sdo_request_address(req, index, subindex); + + if (ec_sdo_request_copy_data(req, data, size)) { + ec_sdo_request_clear(req); + kfree(req); return -1; } - - sdodata->index = index; - sdodata->subindex = subindex; - memcpy(sdodata->data, data, size); - sdodata->size = size; - - list_add_tail(&sdodata->list, &sc->sdo_configs); + + list_add_tail(&req->list, &sc->sdo_configs); return 0; }