mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-02-06 03:41:52 +08:00
Named serial ports.
This commit is contained in:
@@ -60,8 +60,11 @@ typedef enum {
|
||||
SER_SET_DATA_FRAME,
|
||||
} el60xx_port_state;
|
||||
|
||||
#define EL6002_PORT_NAME_SIZE 16
|
||||
|
||||
typedef struct {
|
||||
ec_tty_t *tty;
|
||||
char name[EL6002_PORT_NAME_SIZE];
|
||||
|
||||
size_t max_tx_data_size;
|
||||
size_t max_rx_data_size;
|
||||
@@ -290,11 +293,12 @@ int el60xx_cflag_changed(void *data, tcflag_t cflag)
|
||||
el600x_data_frame_t *df_to_use = NULL;
|
||||
|
||||
#if DEBUG
|
||||
printk(KERN_INFO PFX "%s(data=%p, cflag=%x).\n", __func__, port, cflag);
|
||||
printk(KERN_INFO PFX "%s(%s, cflag=%x).\n", __func__, port->name, cflag);
|
||||
#endif
|
||||
|
||||
rtscts = cflag & CRTSCTS;
|
||||
printk(KERN_INFO PFX "Requested RTS/CTS: %s.\n", rtscts ? "yes" : "no");
|
||||
printk(KERN_INFO PFX "%s: Requested RTS/CTS: %s.\n",
|
||||
port->name, rtscts ? "yes" : "no");
|
||||
|
||||
cbaud = cflag & CBAUD;
|
||||
|
||||
@@ -308,10 +312,11 @@ int el60xx_cflag_changed(void *data, tcflag_t cflag)
|
||||
}
|
||||
|
||||
if (b_to_use) {
|
||||
printk(KERN_INFO PFX "Requested baud rate: %u.\n", b_to_use->baud);
|
||||
printk(KERN_INFO PFX "%s: Requested baud rate: %u.\n",
|
||||
port->name, b_to_use->baud);
|
||||
} else {
|
||||
printk(KERN_ERR PFX "Error: Baud rate index %x not supported.\n",
|
||||
cbaud);
|
||||
printk(KERN_ERR PFX "Error: %s does not support"
|
||||
" baud rate index %x.\n", port->name, cbaud);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -340,8 +345,8 @@ int el60xx_cflag_changed(void *data, tcflag_t cflag)
|
||||
|
||||
stop_bits = (cflag & CSTOPB) ? 2 : 1;
|
||||
|
||||
printk(KERN_INFO PFX "Requested Data frame: %u%c%u.\n",
|
||||
data_bits,
|
||||
printk(KERN_INFO PFX "%s: Requested Data frame: %u%c%u.\n",
|
||||
port->name, data_bits,
|
||||
(par == PAR_NONE ? 'N' : (par == PAR_ODD ? 'O' : 'E')),
|
||||
stop_bits);
|
||||
|
||||
@@ -357,7 +362,8 @@ int el60xx_cflag_changed(void *data, tcflag_t cflag)
|
||||
}
|
||||
|
||||
if (!df_to_use) {
|
||||
printk(KERN_ERR PFX "Error: Data frame type not supported.\n");
|
||||
printk(KERN_ERR PFX "Error: %s does not support data frame type.\n",
|
||||
port->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -371,13 +377,16 @@ int el60xx_cflag_changed(void *data, tcflag_t cflag)
|
||||
/****************************************************************************/
|
||||
|
||||
int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
|
||||
ec_domain_t *domain, unsigned int slot_offset)
|
||||
ec_domain_t *domain, unsigned int slot_offset, const char *name)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
strncpy(port->name, name, EL6002_PORT_NAME_SIZE);
|
||||
|
||||
port->tty = ectty_create(el60xx_cflag_changed, port);
|
||||
if (IS_ERR(port->tty)) {
|
||||
printk(KERN_ERR PFX "Failed to create tty.\n");
|
||||
printk(KERN_ERR PFX "Failed to create tty for %s.\n",
|
||||
port->name);
|
||||
ret = PTR_ERR(port->tty);
|
||||
goto out_return;
|
||||
}
|
||||
@@ -404,21 +413,24 @@ int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
|
||||
|
||||
if (!(port->rtscts_sdo = ecrt_slave_config_create_sdo_request(sc,
|
||||
0x8000 + slot_offset, 0x01, 1))) {
|
||||
printk(KERN_ERR PFX "Failed to create SDO request.\n");
|
||||
printk(KERN_ERR PFX "Failed to create SDO request for %s.\n",
|
||||
port->name);
|
||||
ret = -ENOMEM;
|
||||
goto out_free_tty;
|
||||
}
|
||||
|
||||
if (!(port->baud_sdo = ecrt_slave_config_create_sdo_request(sc,
|
||||
0x8000 + slot_offset, 0x11, 1))) {
|
||||
printk(KERN_ERR PFX "Failed to create SDO request.\n");
|
||||
printk(KERN_ERR PFX "Failed to create SDO request for %s.\n",
|
||||
port->name);
|
||||
ret = -ENOMEM;
|
||||
goto out_free_tty;
|
||||
}
|
||||
|
||||
if (!(port->frame_sdo = ecrt_slave_config_create_sdo_request(sc,
|
||||
0x8000 + slot_offset, 0x15, 1))) {
|
||||
printk(KERN_ERR PFX "Failed to create SDO request.\n");
|
||||
printk(KERN_ERR PFX "Failed to create SDO request for %s\n",
|
||||
port->name);
|
||||
ret = -ENOMEM;
|
||||
goto out_free_tty;
|
||||
}
|
||||
@@ -426,7 +438,8 @@ int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
|
||||
ret = ecrt_slave_config_reg_pdo_entry(
|
||||
sc, 0x7001 + slot_offset, 0x01, domain, NULL);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry.\n");
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry of %s\n",
|
||||
port->name);
|
||||
goto out_free_tty;
|
||||
}
|
||||
port->off_ctrl = ret;
|
||||
@@ -434,7 +447,8 @@ int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
|
||||
ret = ecrt_slave_config_reg_pdo_entry(
|
||||
sc, 0x7000 + slot_offset, 0x11, domain, NULL);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry.\n");
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry of %s.\n",
|
||||
port->name);
|
||||
goto out_free_tty;
|
||||
}
|
||||
port->off_tx = ret;
|
||||
@@ -442,7 +456,8 @@ int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
|
||||
ret = ecrt_slave_config_reg_pdo_entry(
|
||||
sc, 0x6001 + slot_offset, 0x01, domain, NULL);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry.\n");
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry of %s.\n",
|
||||
port->name);
|
||||
goto out_free_tty;
|
||||
}
|
||||
port->off_status = ret;
|
||||
@@ -450,7 +465,8 @@ int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
|
||||
ret = ecrt_slave_config_reg_pdo_entry(
|
||||
sc, 0x6000 + slot_offset, 0x11, domain, NULL);
|
||||
if (ret < 0) {
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry.\n");
|
||||
printk(KERN_ERR PFX "Failed to register PDO entry of %s.\n",
|
||||
port->name);
|
||||
goto out_free_tty;
|
||||
}
|
||||
port->off_rx = ret;
|
||||
@@ -458,6 +474,8 @@ int el60xx_port_init(el60xx_port_t *port, ec_slave_config_t *sc,
|
||||
if (port->max_tx_data_size > 0) {
|
||||
port->tx_data = kmalloc(port->max_tx_data_size, GFP_KERNEL);
|
||||
if (port->tx_data == NULL) {
|
||||
printk(KERN_ERR PFX "Failed to allocate %u bytes of TX"
|
||||
" memory for %s.\n", port->max_tx_data_size, port->name);
|
||||
ret = -ENOMEM;
|
||||
goto out_free_tty;
|
||||
}
|
||||
@@ -530,7 +548,8 @@ void el60xx_port_run(el60xx_port_t *port, u8 *pd)
|
||||
ectty_tx_data(port->tty, port->tx_data, port->max_tx_data_size);
|
||||
if (port->tx_data_size) {
|
||||
#if DEBUG
|
||||
printk(KERN_INFO PFX "Sending %u bytes.\n", port->tx_data_size);
|
||||
printk(KERN_INFO PFX "%s: Sending %u bytes.\n",
|
||||
port->name, port->tx_data_size);
|
||||
#endif
|
||||
port->tx_request_toggle = !port->tx_request_toggle;
|
||||
port->tx_accepted_toggle = tx_accepted_toggle;
|
||||
@@ -544,7 +563,8 @@ void el60xx_port_run(el60xx_port_t *port, u8 *pd)
|
||||
uint8_t rx_data_size = status >> 8;
|
||||
port->rx_request_toggle = rx_request_toggle;
|
||||
#if DEBUG
|
||||
printk(KERN_INFO PFX "Received %u bytes.\n", rx_data_size);
|
||||
printk(KERN_INFO PFX "%s: Received %u bytes.\n",
|
||||
port->name, rx_data_size);
|
||||
#endif
|
||||
ectty_rx_data(port->tty, rx_data, rx_data_size);
|
||||
port->rx_accepted_toggle = !port->rx_accepted_toggle;
|
||||
@@ -567,7 +587,7 @@ void el60xx_port_run(el60xx_port_t *port, u8 *pd)
|
||||
|
||||
case SER_WAIT_FOR_INIT_RESPONSE:
|
||||
if (!(status & (1 << 2))) {
|
||||
printk(KERN_INFO PFX "EL600x init successful.\n");
|
||||
printk(KERN_INFO PFX "%s: Init successful.\n", port->name);
|
||||
port->tx_accepted_toggle = 1;
|
||||
port->control = 0x0000;
|
||||
port->state = SER_READY;
|
||||
@@ -577,12 +597,14 @@ void el60xx_port_run(el60xx_port_t *port, u8 *pd)
|
||||
case SER_SET_RTSCTS:
|
||||
switch (ecrt_sdo_request_state(port->rtscts_sdo)) {
|
||||
case EC_REQUEST_SUCCESS:
|
||||
printk(KERN_INFO PFX "Slave accepted RTS/CTS.\n");
|
||||
printk(KERN_INFO PFX "%s: Accepted RTS/CTS.\n",
|
||||
port->name);
|
||||
port->current_rtscts = port->requested_rtscts;
|
||||
port->state = SER_REQUEST_INIT;
|
||||
break;
|
||||
case EC_REQUEST_ERROR:
|
||||
printk(KERN_INFO PFX "Failed to set RTS/CTS!\n");
|
||||
printk(KERN_ERR PFX "Failed to set RTS/CTS on %s!\n",
|
||||
port->name);
|
||||
port->state = SER_REQUEST_INIT;
|
||||
port->config_error = 1;
|
||||
break;
|
||||
@@ -594,12 +616,14 @@ void el60xx_port_run(el60xx_port_t *port, u8 *pd)
|
||||
case SER_SET_BAUD_RATE:
|
||||
switch (ecrt_sdo_request_state(port->baud_sdo)) {
|
||||
case EC_REQUEST_SUCCESS:
|
||||
printk(KERN_INFO PFX "Slave accepted baud rate.\n");
|
||||
printk(KERN_INFO PFX "%s: Accepted baud rate.\n",
|
||||
port->name);
|
||||
port->current_baud_rate = port->requested_baud_rate;
|
||||
port->state = SER_REQUEST_INIT;
|
||||
break;
|
||||
case EC_REQUEST_ERROR:
|
||||
printk(KERN_INFO PFX "Failed to set baud rate!\n");
|
||||
printk(KERN_ERR PFX "Failed to set baud rate on %s!\n",
|
||||
port->name);
|
||||
port->state = SER_REQUEST_INIT;
|
||||
port->config_error = 1;
|
||||
break;
|
||||
@@ -611,12 +635,14 @@ void el60xx_port_run(el60xx_port_t *port, u8 *pd)
|
||||
case SER_SET_DATA_FRAME:
|
||||
switch (ecrt_sdo_request_state(port->frame_sdo)) {
|
||||
case EC_REQUEST_SUCCESS:
|
||||
printk(KERN_INFO PFX "Slave accepted data frame.\n");
|
||||
printk(KERN_INFO PFX "%s: Accepted data frame.\n",
|
||||
port->name);
|
||||
port->current_data_frame = port->requested_data_frame;
|
||||
port->state = SER_REQUEST_INIT;
|
||||
break;
|
||||
case EC_REQUEST_ERROR:
|
||||
printk(KERN_INFO PFX "Failed to set data frame!\n");
|
||||
printk(KERN_ERR PFX "Failed to set data frame on %s!\n",
|
||||
port->name);
|
||||
port->state = SER_REQUEST_INIT;
|
||||
port->config_error = 1;
|
||||
break;
|
||||
@@ -639,20 +665,27 @@ int el6002_init(el6002_t *el6002, ec_master_t *master, u16 position,
|
||||
|
||||
if (!(el6002->sc = ecrt_master_slave_config(
|
||||
master, 0, position, vendor, product))) {
|
||||
printk(KERN_ERR PFX "Failed to create slave configuration.\n");
|
||||
printk(KERN_ERR PFX "EL6002(%u): Failed to create"
|
||||
" slave configuration.\n", position);
|
||||
ret = -EBUSY;
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
if (ecrt_slave_config_pdos(el6002->sc, EC_END, el6002_syncs)) {
|
||||
printk(KERN_ERR PFX "Failed to configure PDOs.\n");
|
||||
printk(KERN_ERR PFX "EL6002(%u): Failed to configure PDOs.\n",
|
||||
position);
|
||||
ret = -ENOMEM;
|
||||
goto out_return;
|
||||
}
|
||||
|
||||
for (i = 0; i < EL6002_PORTS; i++) {
|
||||
if (el60xx_port_init(el6002->port + i, el6002->sc, domain, i * 0x10)) {
|
||||
printk(KERN_ERR PFX "Failed to init port X%u.\n", i);
|
||||
char name[EL6002_PORT_NAME_SIZE];
|
||||
snprintf(name, EL6002_PORT_NAME_SIZE, "EL6002(%u) X%u",
|
||||
position, i + 1);
|
||||
if (el60xx_port_init(el6002->port + i, el6002->sc, domain, i * 0x10,
|
||||
name)) {
|
||||
printk(KERN_ERR PFX "EL6002(%u): Failed to init port X%u.\n",
|
||||
position, i);
|
||||
goto out_ports;
|
||||
}
|
||||
}
|
||||
@@ -719,7 +752,6 @@ int create_el6002_handler(ec_master_t *master, ec_domain_t *domain,
|
||||
|
||||
ret = el6002_init(el6002, master, position, domain, vendor, product);
|
||||
if (ret) {
|
||||
printk(KERN_ERR PFX "Failed to init serial device object.\n");
|
||||
kfree(el6002);
|
||||
return ret;
|
||||
}
|
||||
@@ -769,7 +801,7 @@ int create_serial_devices(ec_master_t *master, ec_domain_t *domain)
|
||||
}
|
||||
}
|
||||
|
||||
printk(KERN_INFO PFX "Finished.\n");
|
||||
printk(KERN_INFO PFX "Finished registering serial devices.\n");
|
||||
return 0;
|
||||
|
||||
out_free_handlers:
|
||||
|
||||
Reference in New Issue
Block a user