/* TTYVK base offset is 0x30000 into BAR1 */ #define BAR1_TTYVK_BASE_OFFSET 0x300000 /* Each TTYVK channel (TO or FROM) is 0x10000 */ #define BAR1_TTYVK_CHAN_OFFSET 0x100000 /* Each TTYVK channel has TO and FROM, hence the * 2 */ #define BAR1_TTYVK_BASE(index) (BAR1_TTYVK_BASE_OFFSET + \
((index) * BAR1_TTYVK_CHAN_OFFSET * 2)) /* TO TTYVK channel base comes before FROM for each index */ #define TO_TTYK_BASE(index) BAR1_TTYVK_BASE(index) #define FROM_TTYK_BASE(index) (BAR1_TTYVK_BASE(index) + \
BAR1_TTYVK_CHAN_OFFSET)
staticvoid bcm_vk_tty_wq_handler(struct work_struct *work)
{ struct bcm_vk *vk = container_of(work, struct bcm_vk, tty_wq_work); struct bcm_vk_tty *vktty; int card_status; int count; int i; int wr;
u8 c;
card_status = vkread32(vk, BAR_0, BAR_CARD_STATUS); if (BCM_VK_INTF_IS_DOWN(card_status)) return;
for (i = 0; i < BCM_VK_NUM_TTY; i++) {
count = 0; /* Check the card status that the tty channel is ready */ if ((card_status & BIT(i)) == 0) continue;
vktty = &vk->tty[i];
/* Don't increment read index if tty app is closed */ if (!vktty->is_opened) continue;
/* Fetch the wr offset in buffer from VK */
wr = vkread32(vk, BAR_1, VK_BAR_CHAN_WR(vktty, from));
/* safe to ignore until bar read gives proper size */ if (vktty->from_size == 0) continue;
if (wr >= vktty->from_size) {
dev_err(&vk->pdev->dev, "ERROR: wq handler ttyVK%d wr:0x%x > 0x%x\n",
i, wr, vktty->from_size); /* Need to signal and close device in this case */ continue;
}
/* * Simple read of circular buffer and * insert into tty flip buffer
*/ while (vk->tty[i].rd != wr) {
c = vkread8(vk, BAR_1,
VK_BAR_CHAN_DATA(vktty, from, vktty->rd));
vktty->rd++; if (vktty->rd >= vktty->from_size)
vktty->rd = 0;
tty_insert_flip_char(&vktty->port, c, TTY_NORMAL);
count++;
}
if (count) {
tty_flip_buffer_push(&vktty->port);
/* Update read offset from shadow register to card */
vkwrite32(vk, vktty->rd, BAR_1,
VK_BAR_CHAN_RD(vktty, from));
}
}
}
staticint bcm_vk_tty_open(struct tty_struct *tty, struct file *file)
{ int card_status; struct bcm_vk *vk; struct bcm_vk_tty *vktty; int index;
/* initialize the pointer in case something fails */
tty->driver_data = NULL;
vk = (struct bcm_vk *)dev_get_drvdata(tty->dev);
index = tty->index;
/* Do not allow tty device to be opened if tty on card not ready */
card_status = vkread32(vk, BAR_0, BAR_CARD_STATUS); if (BCM_VK_INTF_IS_DOWN(card_status) || ((card_status & BIT(index)) == 0)) return -EBUSY;
/* * Get shadow registers of the buffer sizes and the "to" write offset * and "from" read offset
*/
vktty->to_size = vkread32(vk, BAR_1, VK_BAR_CHAN_SIZE(vktty, to));
vktty->wr = vkread32(vk, BAR_1, VK_BAR_CHAN_WR(vktty, to));
vktty->from_size = vkread32(vk, BAR_1, VK_BAR_CHAN_SIZE(vktty, from));
vktty->rd = vkread32(vk, BAR_1, VK_BAR_CHAN_RD(vktty, from));
vktty->is_opened = true;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.