Lines Matching refs:port
46 /* Microseconds that thread will delay waiting for a vcc port ref */
108 * vcc_table_add() - Add VCC port to the VCC table
109 * @port: pointer to the VCC port
111 * Return: index of the port in the VCC table on success,
114 static int vcc_table_add(struct vcc_port *port)
122 vcc_table[i] = port;
135 * vcc_table_remove() - Removes a VCC port from the VCC table
151 * vcc_get() - Gets a reference to VCC port
155 * Return: reference to the VCC port, if found
156 * NULL, if port not found
160 struct vcc_port *port;
166 port = vcc_table[index];
167 if (!port) {
173 if (port->excl_locked) {
178 port->refcnt++;
180 return port;
183 if (port->refcnt) {
193 port->refcnt++;
194 port->excl_locked = true;
197 return port;
201 * vcc_put() - Returns a reference to VCC port
202 * @port: pointer to VCC port
208 static void vcc_put(struct vcc_port *port, bool excl)
212 if (!port)
218 if (WARN_ON((excl && !port->excl_locked) ||
219 (!excl && port->excl_locked)))
222 port->refcnt--;
225 port->excl_locked = false;
232 * vcc_get_ne() - Get a non-exclusive reference to VCC port
235 * Gets a non-exclusive reference to VCC port, if it's not removed
237 * Return: pointer to the VCC port, if found
238 * NULL, if port not found
242 struct vcc_port *port;
244 port = vcc_get(index, false);
246 if (port && port->removed) {
247 vcc_put(port, false);
251 return port;
254 static void vcc_kick_rx(struct vcc_port *port)
256 struct vio_driver_state *vio = &port->vio;
258 assert_spin_locked(&port->lock);
260 if (!timer_pending(&port->rx_timer) && !port->removed) {
262 port->rx_timer.expires = (jiffies + 1);
263 add_timer(&port->rx_timer);
267 static void vcc_kick_tx(struct vcc_port *port)
269 assert_spin_locked(&port->lock);
271 if (!timer_pending(&port->tx_timer) && !port->removed) {
272 port->tx_timer.expires = (jiffies + 1);
273 add_timer(&port->tx_timer);
279 if (WARN_ON(!tty || !tty->port))
286 (tty_buffer_request_room(tty->port, VCC_BUFF_LEN) < VCC_BUFF_LEN))
296 if (WARN_ON(!tty || !tty->port))
299 len = tty_insert_flip_string(tty->port, buf, size);
301 tty_flip_buffer_push(tty->port);
306 static int vcc_ldc_read(struct vcc_port *port)
308 struct vio_driver_state *vio = &port->vio;
313 tty = port->tty;
323 vcc_kick_rx(port);
359 struct vcc_port *port = from_timer(port, t, rx_timer);
364 spin_lock_irqsave(&port->lock, flags);
365 port->rx_timer.expires = 0;
367 vio = &port->vio;
371 if (!port->tty || port->removed)
374 rv = vcc_ldc_read(port);
379 spin_unlock_irqrestore(&port->lock, flags);
380 vcc_put(port, false);
385 struct vcc_port *port = from_timer(port, t, tx_timer);
391 spin_lock_irqsave(&port->lock, flags);
392 port->tx_timer.expires = 0;
394 if (!port->tty || port->removed)
397 tosend = min(VCC_BUFF_LEN, port->chars_in_buffer);
401 pkt = &port->buffer;
404 vccdbgl(port->vio.lp);
406 rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend));
411 vcc_kick_tx(port);
413 struct tty_struct *tty = port->tty;
415 port->chars_in_buffer = 0;
421 spin_unlock_irqrestore(&port->lock, flags);
422 vcc_put(port, false);
435 struct vcc_port *port;
439 port = arg;
440 vio = &port->vio;
442 spin_lock_irqsave(&port->lock, flags);
451 rv = vcc_ldc_read(port);
460 spin_unlock_irqrestore(&port->lock, flags);
481 struct vcc_port *port;
484 port = dev_get_drvdata(dev);
485 if (!port)
488 rv = scnprintf(buf, PAGE_SIZE, "%s\n", port->domain);
493 static int vcc_send_ctl(struct vcc_port *port, int ctl)
502 rv = ldc_write(port->vio.lp, &pkt, sizeof(pkt.tag));
513 struct vcc_port *port;
518 port = dev_get_drvdata(dev);
519 if (!port)
522 spin_lock_irqsave(&port->lock, flags);
526 else if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0)
527 vcc_kick_tx(port);
529 spin_unlock_irqrestore(&port->lock, flags);
549 * vcc_probe() - Initialize VCC port
550 * @vdev: Pointer to VIO device of the new VCC port
553 * Initializes a VCC port to receive serial console data from
563 struct vcc_port *port;
577 port = kzalloc(sizeof(struct vcc_port), GFP_KERNEL);
578 if (!port)
587 rv = vio_driver_init(&port->vio, vdev, VDEV_CONSOLE_CON, vcc_versions,
592 port->vio.debug = vcc_dbg_vio;
595 rv = vio_ldc_alloc(&port->vio, &vcc_ldc_cfg, port);
599 spin_lock_init(&port->lock);
601 port->index = vcc_table_add(port);
602 if (port->index == -1) {
609 dev = tty_register_device(vcc_tty_driver, port->index, &vdev->dev);
630 port->domain = kstrdup(domain, GFP_KERNEL);
631 if (!port->domain) {
643 timer_setup(&port->rx_timer, vcc_rx_timer, 0);
644 timer_setup(&port->tx_timer, vcc_tx_timer, 0);
646 dev_set_drvdata(&vdev->dev, port);
649 * IRQs until the port is up.
652 vio_port_up(&port->vio);
658 kfree(port->domain);
660 tty_unregister_device(vcc_tty_driver, port->index);
662 vcc_table_remove(port->index);
664 vio_ldc_free(&port->vio);
668 kfree(port);
674 * vcc_remove() - Terminate a VCC port
675 * @vdev: Pointer to VIO device of the VCC port
677 * Terminates a VCC port. Sets up the teardown of TTY and
684 struct vcc_port *port = dev_get_drvdata(&vdev->dev);
686 del_timer_sync(&port->rx_timer);
687 del_timer_sync(&port->tx_timer);
693 if (port->tty)
694 tty_vhangup(port->tty);
697 * clients to this port. This cannot fail.
699 vcc_get(port->index, true);
701 tty_unregister_device(vcc_tty_driver, port->index);
703 del_timer_sync(&port->vio.timer);
704 vio_ldc_free(&port->vio);
707 if (port->tty) {
708 port->removed = true;
709 vcc_put(port, true);
711 vcc_table_remove(port->index);
713 kfree(port->vio.name);
714 kfree(port->domain);
715 kfree(port);
721 .type = "vcc-port",
736 struct vcc_port *port;
741 port = vcc_get_ne(tty->index);
742 if (unlikely(!port)) {
743 pr_err("VCC: open: Failed to find VCC port\n");
747 if (unlikely(!port->vio.lp)) {
749 vcc_put(port, false);
752 vccdbgl(port->vio.lp);
754 vcc_put(port, false);
756 if (unlikely(!tty->port)) {
757 pr_err("VCC: open: TTY port not found\n");
761 if (unlikely(!tty->port->ops)) {
766 return tty_port_open(tty->port, tty, vcc_file);
774 if (unlikely(!tty->port)) {
775 pr_err("VCC: close: TTY port not found\n");
779 tty_port_close(tty->port, tty, vcc_file);
782 static void vcc_ldc_hup(struct vcc_port *port)
786 spin_lock_irqsave(&port->lock, flags);
788 if (vcc_send_ctl(port, VCC_CTL_HUP) < 0)
789 vcc_kick_tx(port);
791 spin_unlock_irqrestore(&port->lock, flags);
796 struct vcc_port *port;
798 port = vcc_get_ne(tty->index);
799 if (unlikely(!port)) {
800 pr_err("VCC: hangup: Failed to find VCC port\n");
804 if (unlikely(!tty->port)) {
805 pr_err("VCC: hangup: TTY port not found\n");
806 vcc_put(port, false);
810 vcc_ldc_hup(port);
812 vcc_put(port, false);
814 tty_port_hangup(tty->port);
819 struct vcc_port *port;
826 port = vcc_get_ne(tty->index);
827 if (unlikely(!port)) {
828 pr_err("VCC: write: Failed to find VCC port");
832 spin_lock_irqsave(&port->lock, flags);
834 pkt = &port->buffer;
840 (VCC_BUFF_LEN - port->chars_in_buffer));
845 memcpy(&pkt->data[port->chars_in_buffer], &buf[total_sent],
847 port->chars_in_buffer += tosend;
853 vccdbgl(port->vio.lp);
859 rv = ldc_write(port->vio.lp, pkt, (VIO_TAG_SIZE + tosend));
866 vcc_kick_tx(port);
870 port->chars_in_buffer = 0;
873 spin_unlock_irqrestore(&port->lock, flags);
875 vcc_put(port, false);
884 struct vcc_port *port;
887 port = vcc_get_ne(tty->index);
888 if (unlikely(!port)) {
889 pr_err("VCC: write_room: Failed to find VCC port\n");
893 num = VCC_BUFF_LEN - port->chars_in_buffer;
895 vcc_put(port, false);
902 struct vcc_port *port;
905 port = vcc_get_ne(tty->index);
906 if (unlikely(!port)) {
907 pr_err("VCC: chars_in_buffer: Failed to find VCC port\n");
911 num = port->chars_in_buffer;
913 vcc_put(port, false);
920 struct vcc_port *port;
923 port = vcc_get_ne(tty->index);
924 if (unlikely(!port)) {
925 pr_err("VCC: break_ctl: Failed to find VCC port\n");
931 vcc_put(port, false);
935 spin_lock_irqsave(&port->lock, flags);
937 if (vcc_send_ctl(port, VCC_CTL_BREAK) < 0)
938 vcc_kick_tx(port);
940 spin_unlock_irqrestore(&port->lock, flags);
942 vcc_put(port, false);
966 pr_err("VCC: install: Failed to find VCC port\n");
967 tty->port = NULL;
974 tty->port = port_tty;
985 struct vcc_port *port;
987 port = vcc_get(tty->index, true);
988 if (port) {
989 port->tty = NULL;
991 if (port->removed) {
993 kfree(port->vio.name);
994 kfree(port->domain);
995 kfree(port);
997 vcc_put(port, true);
1001 tty_port_destroy(tty->port);
1002 kfree(tty->port);
1003 tty->port = NULL;