static int ipoctal_write(struct ipoctal *ipoctal, unsigned int channel, const unsigned char *buf, int count) { ipoctal->nb_bytes[channel] = 0; ipoctal->count_wr[channel] = 0; /* Copy the data to the write buffer */ ipoctal_copy_write_buffer(ipoctal, channel, buf, count); ipoctal->error_flag[channel] = UART_NOERROR; ipoctal->read_write[channel].error_flag = UART_NOERROR; /* Using half-duplex on transmission */ ipoctal->chan_status[channel] = CHAN_WRITE; ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, CR_DISABLE_RX); if (ipoctal->board_id == IP_OCTAL_485_ID) { ipoctal_write_cr_cmd(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, CR_CMD_ASSERT_RTSN); } ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, CR_ENABLE_TX); wait_event_interruptible(ipoctal->queue[channel], ipoctal->write); /* End Write operation */ ipoctal->write = 0; ipoctal->chan_status[channel] = CHAN_READ; if(ipoctal->board_id != IP_OCTAL_485_ID) { ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, CR_DISABLE_TX); ipoctal_write_io_reg(ipoctal, &ipoctal->chan_regs[channel].u.w.cr, CR_ENABLE_RX); } return ipoctal->count_wr[channel]; }
static int ipoctal_write_tty(struct tty_struct *tty, const unsigned char *buf, int count) { struct ipoctal_channel *channel = tty->driver_data; unsigned int char_copied; char_copied = ipoctal_copy_write_buffer(channel, buf, count); /* As the IP-OCTAL 485 only supports half duplex, do it manually */ if (channel->board_id == IPACK1_DEVICE_ID_SBS_OCTAL_485) { iowrite8(CR_DISABLE_RX, &channel->regs->w.cr); channel->rx_enable = 0; iowrite8(CR_CMD_ASSERT_RTSN, &channel->regs->w.cr); } /* * Send a packet and then disable TX to avoid failure after several send * operations */ iowrite8(CR_ENABLE_TX, &channel->regs->w.cr); return char_copied; }