Lines Matching full:hp

87 static int (*hvsi_wait)(struct hvsi_struct *hp, int state);
99 static inline int is_console(struct hvsi_struct *hp) in is_console() argument
101 return hp->flags & HVSI_CONSOLE; in is_console()
104 static inline int is_open(struct hvsi_struct *hp) in is_open() argument
107 return (hp->state == HVSI_OPEN) in is_open()
108 || (hp->state == HVSI_WAIT_FOR_MCTRL_RESPONSE); in is_open()
111 static inline void print_state(struct hvsi_struct *hp) in print_state() argument
122 const char *name = (hp->state < ARRAY_SIZE(state_names)) in print_state()
123 ? state_names[hp->state] : "UNKNOWN"; in print_state()
125 pr_debug("hvsi%i: state = %s\n", hp->index, name); in print_state()
129 static inline void __set_state(struct hvsi_struct *hp, int state) in __set_state() argument
131 hp->state = state; in __set_state()
132 print_state(hp); in __set_state()
133 wake_up_all(&hp->stateq); in __set_state()
136 static inline void set_state(struct hvsi_struct *hp, int state) in set_state() argument
140 spin_lock_irqsave(&hp->lock, flags); in set_state()
141 __set_state(hp, state); in set_state()
142 spin_unlock_irqrestore(&hp->lock, flags); in set_state()
156 static inline int got_packet(const struct hvsi_struct *hp, uint8_t *packet) in got_packet() argument
158 if (hp->inbuf_end < packet + sizeof(struct hvsi_header)) in got_packet()
161 if (hp->inbuf_end < (packet + len_packet(packet))) in got_packet()
168 static void compact_inbuf(struct hvsi_struct *hp, uint8_t *read_to) in compact_inbuf() argument
170 int remaining = (int)(hp->inbuf_end - read_to); in compact_inbuf()
174 if (read_to != hp->inbuf) in compact_inbuf()
175 memmove(hp->inbuf, read_to, remaining); in compact_inbuf()
177 hp->inbuf_end = hp->inbuf + remaining; in compact_inbuf()
216 static int hvsi_read(struct hvsi_struct *hp, char *buf, int count) in hvsi_read() argument
220 got = hvc_get_chars(hp->vtermno, buf, count); in hvsi_read()
225 static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, in hvsi_recv_control() argument
234 pr_debug("hvsi%i: CD dropped\n", hp->index); in hvsi_recv_control()
235 hp->mctrl &= TIOCM_CD; in hvsi_recv_control()
241 pr_debug("hvsi%i: service processor came back\n", hp->index); in hvsi_recv_control()
242 if (hp->state != HVSI_CLOSED) { in hvsi_recv_control()
243 *to_handshake = hp; in hvsi_recv_control()
248 hp->index); in hvsi_recv_control()
254 static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet) in hvsi_recv_response() argument
259 switch (hp->state) { in hvsi_recv_response()
261 __set_state(hp, HVSI_WAIT_FOR_VER_QUERY); in hvsi_recv_response()
264 hp->mctrl = 0; in hvsi_recv_response()
267 hp->mctrl |= TIOCM_DTR; in hvsi_recv_response()
269 hp->mctrl |= TIOCM_CD; in hvsi_recv_response()
270 __set_state(hp, HVSI_OPEN); in hvsi_recv_response()
273 printk(KERN_ERR "hvsi%i: unexpected query response: ", hp->index); in hvsi_recv_response()
280 static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno) in hvsi_version_respond() argument
287 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_version_respond()
295 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_version_respond()
298 hp->index); in hvsi_version_respond()
305 static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet) in hvsi_recv_query() argument
309 switch (hp->state) { in hvsi_recv_query()
311 hvsi_version_respond(hp, be16_to_cpu(query->hdr.seqno)); in hvsi_recv_query()
312 __set_state(hp, HVSI_OPEN); in hvsi_recv_query()
315 printk(KERN_ERR "hvsi%i: unexpected query: ", hp->index); in hvsi_recv_query()
321 static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) in hvsi_insert_chars() argument
329 hp->sysrq = 1; in hvsi_insert_chars()
331 } else if (hp->sysrq) { in hvsi_insert_chars()
333 hp->sysrq = 0; in hvsi_insert_chars()
337 tty_insert_flip_char(&hp->port, c, 0); in hvsi_insert_chars()
350 static bool hvsi_recv_data(struct hvsi_struct *hp, const uint8_t *packet) in hvsi_recv_data() argument
367 hvsi_insert_chars(hp, data, datalen); in hvsi_recv_data()
375 memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow); in hvsi_recv_data()
376 hp->n_throttle = overflow; in hvsi_recv_data()
388 static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, in hvsi_load_chunk() argument
391 uint8_t *packet = hp->inbuf; in hvsi_load_chunk()
397 chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ); in hvsi_load_chunk()
404 dbg_dump_hex(hp->inbuf_end, chunklen); in hvsi_load_chunk()
406 hp->inbuf_end += chunklen; in hvsi_load_chunk()
409 while ((packet < hp->inbuf_end) && got_packet(hp, packet)) { in hvsi_load_chunk()
413 printk(KERN_ERR "hvsi%i: got malformed packet\n", hp->index); in hvsi_load_chunk()
415 while ((packet < hp->inbuf_end) && (!is_header(packet))) in hvsi_load_chunk()
426 if (!is_open(hp)) in hvsi_load_chunk()
428 flip = hvsi_recv_data(hp, packet); in hvsi_load_chunk()
431 hvsi_recv_control(hp, packet, tty, handshake); in hvsi_load_chunk()
434 hvsi_recv_response(hp, packet); in hvsi_load_chunk()
437 hvsi_recv_query(hp, packet); in hvsi_load_chunk()
441 hp->index, header->type); in hvsi_load_chunk()
454 compact_inbuf(hp, packet); in hvsi_load_chunk()
457 tty_flip_buffer_push(&hp->port); in hvsi_load_chunk()
462 static void hvsi_send_overflow(struct hvsi_struct *hp) in hvsi_send_overflow() argument
465 hp->n_throttle); in hvsi_send_overflow()
467 hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle); in hvsi_send_overflow()
468 hp->n_throttle = 0; in hvsi_send_overflow()
477 struct hvsi_struct *hp = (struct hvsi_struct *)arg; in hvsi_interrupt() local
485 tty = tty_port_tty_get(&hp->port); in hvsi_interrupt()
488 spin_lock_irqsave(&hp->lock, flags); in hvsi_interrupt()
489 again = hvsi_load_chunk(hp, tty, &handshake); in hvsi_interrupt()
490 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_interrupt()
498 spin_lock_irqsave(&hp->lock, flags); in hvsi_interrupt()
499 if (tty && hp->n_throttle && !tty_throttled(tty)) { in hvsi_interrupt()
502 hvsi_send_overflow(hp); in hvsi_interrupt()
503 tty_flip_buffer_push(&hp->port); in hvsi_interrupt()
505 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_interrupt()
513 static int __init poll_for_state(struct hvsi_struct *hp, int state) in poll_for_state() argument
518 hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */ in poll_for_state()
520 if (hp->state == state) in poll_for_state()
530 static int wait_for_state(struct hvsi_struct *hp, int state) in wait_for_state() argument
534 if (!wait_event_timeout(hp->stateq, (hp->state == state), HVSI_TIMEOUT)) in wait_for_state()
540 static int hvsi_query(struct hvsi_struct *hp, uint16_t verb) in hvsi_query() argument
547 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_query()
553 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_query()
555 printk(KERN_ERR "hvsi%i: couldn't send query (%i)!\n", hp->index, in hvsi_query()
563 static int hvsi_get_mctrl(struct hvsi_struct *hp) in hvsi_get_mctrl() argument
567 set_state(hp, HVSI_WAIT_FOR_MCTRL_RESPONSE); in hvsi_get_mctrl()
568 hvsi_query(hp, VSV_SEND_MODEM_CTL_STATUS); in hvsi_get_mctrl()
570 ret = hvsi_wait(hp, HVSI_OPEN); in hvsi_get_mctrl()
572 printk(KERN_ERR "hvsi%i: didn't get modem flags\n", hp->index); in hvsi_get_mctrl()
573 set_state(hp, HVSI_OPEN); in hvsi_get_mctrl()
577 pr_debug("%s: mctrl 0x%x\n", __func__, hp->mctrl); in hvsi_get_mctrl()
583 static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl) in hvsi_set_mctrl() argument
589 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_set_mctrl()
600 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_set_mctrl()
602 printk(KERN_ERR "hvsi%i: couldn't set DTR!\n", hp->index); in hvsi_set_mctrl()
609 static void hvsi_drain_input(struct hvsi_struct *hp) in hvsi_drain_input() argument
615 if (0 == hvsi_read(hp, buf, HVSI_MAX_READ)) in hvsi_drain_input()
619 static int hvsi_handshake(struct hvsi_struct *hp) in hvsi_handshake() argument
630 hvsi_drain_input(hp); in hvsi_handshake()
632 set_state(hp, HVSI_WAIT_FOR_VER_RESPONSE); in hvsi_handshake()
633 ret = hvsi_query(hp, VSV_SEND_VERSION_NUMBER); in hvsi_handshake()
635 printk(KERN_ERR "hvsi%i: couldn't send version query\n", hp->index); in hvsi_handshake()
639 ret = hvsi_wait(hp, HVSI_OPEN); in hvsi_handshake()
648 struct hvsi_struct *hp = in hvsi_handshaker() local
651 if (hvsi_handshake(hp) >= 0) in hvsi_handshaker()
654 printk(KERN_ERR "hvsi%i: re-handshaking failed\n", hp->index); in hvsi_handshaker()
655 if (is_console(hp)) { in hvsi_handshaker()
660 printk(KERN_ERR "hvsi%i: lost console!\n", hp->index); in hvsi_handshaker()
664 static int hvsi_put_chars(struct hvsi_struct *hp, const char *buf, int count) in hvsi_put_chars() argument
672 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_put_chars()
676 ret = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_put_chars()
684 static void hvsi_close_protocol(struct hvsi_struct *hp) in hvsi_close_protocol() argument
689 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_close_protocol()
696 hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_close_protocol()
701 struct hvsi_struct *hp; in hvsi_open() local
707 hp = &hvsi_ports[tty->index]; in hvsi_open()
709 tty->driver_data = hp; in hvsi_open()
712 if (hp->state == HVSI_FSP_DIED) in hvsi_open()
715 tty_port_tty_set(&hp->port, tty); in hvsi_open()
716 spin_lock_irqsave(&hp->lock, flags); in hvsi_open()
717 hp->port.count++; in hvsi_open()
718 atomic_set(&hp->seqno, 0); in hvsi_open()
719 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); in hvsi_open()
720 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_open()
722 if (is_console(hp)) in hvsi_open()
725 ret = hvsi_handshake(hp); in hvsi_open()
731 ret = hvsi_get_mctrl(hp); in hvsi_open()
737 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR); in hvsi_open()
746 /* wait for hvsi_write_worker to empty hp->outbuf */
747 static void hvsi_flush_output(struct hvsi_struct *hp) in hvsi_flush_output() argument
749 wait_event_timeout(hp->emptyq, (hp->n_outbuf <= 0), HVSI_TIMEOUT); in hvsi_flush_output()
752 cancel_delayed_work_sync(&hp->writer); in hvsi_flush_output()
753 flush_work(&hp->handshaker); in hvsi_flush_output()
759 hp->n_outbuf = 0; in hvsi_flush_output()
764 struct hvsi_struct *hp = tty->driver_data; in hvsi_close() local
772 spin_lock_irqsave(&hp->lock, flags); in hvsi_close()
774 if (--hp->port.count == 0) { in hvsi_close()
775 tty_port_tty_set(&hp->port, NULL); in hvsi_close()
776 hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */ in hvsi_close()
779 if (!is_console(hp)) { in hvsi_close()
780 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); /* no more irqs */ in hvsi_close()
781 __set_state(hp, HVSI_CLOSED); in hvsi_close()
788 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_close()
791 synchronize_irq(hp->virq); in hvsi_close()
794 hvsi_flush_output(hp); in hvsi_close()
797 hvsi_close_protocol(hp); in hvsi_close()
803 hvsi_drain_input(hp); in hvsi_close()
805 spin_lock_irqsave(&hp->lock, flags); in hvsi_close()
807 } else if (hp->port.count < 0) in hvsi_close()
809 hp - hvsi_ports, hp->port.count); in hvsi_close()
811 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_close()
816 struct hvsi_struct *hp = tty->driver_data; in hvsi_hangup() local
821 tty_port_tty_set(&hp->port, NULL); in hvsi_hangup()
823 spin_lock_irqsave(&hp->lock, flags); in hvsi_hangup()
824 hp->port.count = 0; in hvsi_hangup()
825 hp->n_outbuf = 0; in hvsi_hangup()
826 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_hangup()
829 /* called with hp->lock held */
830 static void hvsi_push(struct hvsi_struct *hp) in hvsi_push() argument
834 if (hp->n_outbuf <= 0) in hvsi_push()
837 n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf); in hvsi_push()
841 hp->n_outbuf = 0; in hvsi_push()
843 __set_state(hp, HVSI_FSP_DIED); in hvsi_push()
844 printk(KERN_ERR "hvsi%i: service processor died\n", hp->index); in hvsi_push()
851 struct hvsi_struct *hp = in hvsi_write_worker() local
861 spin_lock_irqsave(&hp->lock, flags); in hvsi_write_worker()
863 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); in hvsi_write_worker()
865 if (!is_open(hp)) { in hvsi_write_worker()
872 schedule_delayed_work(&hp->writer, HZ); in hvsi_write_worker()
876 hvsi_push(hp); in hvsi_write_worker()
877 if (hp->n_outbuf > 0) in hvsi_write_worker()
878 schedule_delayed_work(&hp->writer, 10); in hvsi_write_worker()
885 wake_up_all(&hp->emptyq); in hvsi_write_worker()
886 tty_port_tty_wakeup(&hp->port); in hvsi_write_worker()
890 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_write_worker()
895 struct hvsi_struct *hp = tty->driver_data; in hvsi_write_room() local
897 return N_OUTBUF - hp->n_outbuf; in hvsi_write_room()
902 struct hvsi_struct *hp = tty->driver_data; in hvsi_chars_in_buffer() local
904 return hp->n_outbuf; in hvsi_chars_in_buffer()
910 struct hvsi_struct *hp = tty->driver_data; in hvsi_write() local
915 spin_lock_irqsave(&hp->lock, flags); in hvsi_write()
917 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); in hvsi_write()
919 if (!is_open(hp)) { in hvsi_write()
926 * when the hypervisor buffer (16K) fills, data will stay in hp->outbuf in hvsi_write()
933 BUG_ON(hp->n_outbuf < 0); in hvsi_write()
934 memcpy(hp->outbuf + hp->n_outbuf, source, chunksize); in hvsi_write()
935 hp->n_outbuf += chunksize; in hvsi_write()
940 hvsi_push(hp); in hvsi_write()
943 if (hp->n_outbuf > 0) { in hvsi_write()
948 schedule_delayed_work(&hp->writer, 10); in hvsi_write()
952 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_write()
967 struct hvsi_struct *hp = tty->driver_data; in hvsi_throttle() local
971 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); in hvsi_throttle()
976 struct hvsi_struct *hp = tty->driver_data; in hvsi_unthrottle() local
981 spin_lock_irqsave(&hp->lock, flags); in hvsi_unthrottle()
982 if (hp->n_throttle) { in hvsi_unthrottle()
983 hvsi_send_overflow(hp); in hvsi_unthrottle()
984 tty_flip_buffer_push(&hp->port); in hvsi_unthrottle()
986 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_unthrottle()
989 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); in hvsi_unthrottle()
994 struct hvsi_struct *hp = tty->driver_data; in hvsi_tiocmget() local
996 hvsi_get_mctrl(hp); in hvsi_tiocmget()
997 return hp->mctrl; in hvsi_tiocmget()
1003 struct hvsi_struct *hp = tty->driver_data; in hvsi_tiocmset() local
1011 spin_lock_irqsave(&hp->lock, flags); in hvsi_tiocmset()
1013 new_mctrl = (hp->mctrl & ~clear) | set; in hvsi_tiocmset()
1015 if (hp->mctrl != new_mctrl) { in hvsi_tiocmset()
1016 hvsi_set_mctrl(hp, new_mctrl); in hvsi_tiocmset()
1017 hp->mctrl = new_mctrl; in hvsi_tiocmset()
1019 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_tiocmset()
1059 struct hvsi_struct *hp = &hvsi_ports[i]; in hvsi_init() local
1062 tty_port_link_device(&hp->port, driver, i); in hvsi_init()
1064 ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); in hvsi_init()
1067 hp->virq, ret); in hvsi_init()
1085 struct hvsi_struct *hp = &hvsi_ports[i]; in hvsi_init() local
1087 free_irq(hp->virq, hp); in hvsi_init()
1100 struct hvsi_struct *hp = &hvsi_ports[console->index]; in hvsi_console_print() local
1106 if (!is_open(hp)) in hvsi_console_print()
1124 ret = hvsi_put_chars(hp, c, i); in hvsi_console_print()
1141 struct hvsi_struct *hp; in hvsi_console_setup() local
1146 hp = &hvsi_ports[console->index]; in hvsi_console_setup()
1149 hvsi_close_protocol(hp); in hvsi_console_setup()
1151 ret = hvsi_handshake(hp); in hvsi_console_setup()
1155 ret = hvsi_get_mctrl(hp); in hvsi_console_setup()
1159 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR); in hvsi_console_setup()
1163 hp->flags |= HVSI_CONSOLE; in hvsi_console_setup()
1185 struct hvsi_struct *hp; in hvsi_console_init() local
1198 hp = &hvsi_ports[hvsi_count]; in hvsi_console_init()
1199 INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker); in hvsi_console_init()
1200 INIT_WORK(&hp->handshaker, hvsi_handshaker); in hvsi_console_init()
1201 init_waitqueue_head(&hp->emptyq); in hvsi_console_init()
1202 init_waitqueue_head(&hp->stateq); in hvsi_console_init()
1203 spin_lock_init(&hp->lock); in hvsi_console_init()
1204 tty_port_init(&hp->port); in hvsi_console_init()
1205 hp->index = hvsi_count; in hvsi_console_init()
1206 hp->inbuf_end = hp->inbuf; in hvsi_console_init()
1207 hp->state = HVSI_CLOSED; in hvsi_console_init()
1208 hp->vtermno = be32_to_cpup(vtermno); in hvsi_console_init()
1209 hp->virq = irq_create_mapping(NULL, be32_to_cpup(irq)); in hvsi_console_init()
1210 if (hp->virq == 0) { in hvsi_console_init()
1213 tty_port_destroy(&hp->port); in hvsi_console_init()