Lines Matching refs:hp
100 static int (*hvsi_wait)(struct hvsi_struct *hp, int state);
112 static inline int is_console(struct hvsi_struct *hp) in is_console() argument
114 return hp->flags & HVSI_CONSOLE; in is_console()
117 static inline int is_open(struct hvsi_struct *hp) in is_open() argument
120 return (hp->state == HVSI_OPEN) in is_open()
121 || (hp->state == HVSI_WAIT_FOR_MCTRL_RESPONSE); in is_open()
124 static inline void print_state(struct hvsi_struct *hp) in print_state() argument
135 const char *name = (hp->state < ARRAY_SIZE(state_names)) in print_state()
136 ? state_names[hp->state] : "UNKNOWN"; in print_state()
138 pr_debug("hvsi%i: state = %s\n", hp->index, name); in print_state()
142 static inline void __set_state(struct hvsi_struct *hp, int state) in __set_state() argument
144 hp->state = state; in __set_state()
145 print_state(hp); in __set_state()
146 wake_up_all(&hp->stateq); in __set_state()
149 static inline void set_state(struct hvsi_struct *hp, int state) in set_state() argument
153 spin_lock_irqsave(&hp->lock, flags); in set_state()
154 __set_state(hp, state); in set_state()
155 spin_unlock_irqrestore(&hp->lock, flags); in set_state()
169 static inline int got_packet(const struct hvsi_struct *hp, uint8_t *packet) in got_packet() argument
171 if (hp->inbuf_end < packet + sizeof(struct hvsi_header)) in got_packet()
174 if (hp->inbuf_end < (packet + len_packet(packet))) in got_packet()
181 static void compact_inbuf(struct hvsi_struct *hp, uint8_t *read_to) in compact_inbuf() argument
183 int remaining = (int)(hp->inbuf_end - read_to); in compact_inbuf()
187 if (read_to != hp->inbuf) in compact_inbuf()
188 memmove(hp->inbuf, read_to, remaining); in compact_inbuf()
190 hp->inbuf_end = hp->inbuf + remaining; in compact_inbuf()
229 static int hvsi_read(struct hvsi_struct *hp, char *buf, int count) in hvsi_read() argument
233 got = hvc_get_chars(hp->vtermno, buf, count); in hvsi_read()
238 static void hvsi_recv_control(struct hvsi_struct *hp, uint8_t *packet, in hvsi_recv_control() argument
247 pr_debug("hvsi%i: CD dropped\n", hp->index); in hvsi_recv_control()
248 hp->mctrl &= TIOCM_CD; in hvsi_recv_control()
254 pr_debug("hvsi%i: service processor came back\n", hp->index); in hvsi_recv_control()
255 if (hp->state != HVSI_CLOSED) { in hvsi_recv_control()
256 *to_handshake = hp; in hvsi_recv_control()
261 hp->index); in hvsi_recv_control()
267 static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet) in hvsi_recv_response() argument
272 switch (hp->state) { in hvsi_recv_response()
274 __set_state(hp, HVSI_WAIT_FOR_VER_QUERY); in hvsi_recv_response()
277 hp->mctrl = 0; in hvsi_recv_response()
280 hp->mctrl |= TIOCM_DTR; in hvsi_recv_response()
282 hp->mctrl |= TIOCM_CD; in hvsi_recv_response()
283 __set_state(hp, HVSI_OPEN); in hvsi_recv_response()
286 printk(KERN_ERR "hvsi%i: unexpected query response: ", hp->index); in hvsi_recv_response()
293 static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno) in hvsi_version_respond() argument
300 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_version_respond()
308 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_version_respond()
311 hp->index); in hvsi_version_respond()
318 static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet) in hvsi_recv_query() argument
322 switch (hp->state) { in hvsi_recv_query()
324 hvsi_version_respond(hp, be16_to_cpu(query->hdr.seqno)); in hvsi_recv_query()
325 __set_state(hp, HVSI_OPEN); in hvsi_recv_query()
328 printk(KERN_ERR "hvsi%i: unexpected query: ", hp->index); in hvsi_recv_query()
334 static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) in hvsi_insert_chars() argument
342 hp->sysrq = 1; in hvsi_insert_chars()
344 } else if (hp->sysrq) { in hvsi_insert_chars()
346 hp->sysrq = 0; in hvsi_insert_chars()
350 tty_insert_flip_char(&hp->port, c, 0); in hvsi_insert_chars()
363 static bool hvsi_recv_data(struct hvsi_struct *hp, const uint8_t *packet) in hvsi_recv_data() argument
380 hvsi_insert_chars(hp, data, datalen); in hvsi_recv_data()
388 memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow); in hvsi_recv_data()
389 hp->n_throttle = overflow; in hvsi_recv_data()
401 static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, in hvsi_load_chunk() argument
404 uint8_t *packet = hp->inbuf; in hvsi_load_chunk()
410 chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ); in hvsi_load_chunk()
417 dbg_dump_hex(hp->inbuf_end, chunklen); in hvsi_load_chunk()
419 hp->inbuf_end += chunklen; in hvsi_load_chunk()
422 while ((packet < hp->inbuf_end) && got_packet(hp, packet)) { in hvsi_load_chunk()
426 printk(KERN_ERR "hvsi%i: got malformed packet\n", hp->index); in hvsi_load_chunk()
428 while ((packet < hp->inbuf_end) && (!is_header(packet))) in hvsi_load_chunk()
439 if (!is_open(hp)) in hvsi_load_chunk()
441 flip = hvsi_recv_data(hp, packet); in hvsi_load_chunk()
444 hvsi_recv_control(hp, packet, tty, handshake); in hvsi_load_chunk()
447 hvsi_recv_response(hp, packet); in hvsi_load_chunk()
450 hvsi_recv_query(hp, packet); in hvsi_load_chunk()
454 hp->index, header->type); in hvsi_load_chunk()
467 compact_inbuf(hp, packet); in hvsi_load_chunk()
470 tty_flip_buffer_push(&hp->port); in hvsi_load_chunk()
475 static void hvsi_send_overflow(struct hvsi_struct *hp) in hvsi_send_overflow() argument
478 hp->n_throttle); in hvsi_send_overflow()
480 hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle); in hvsi_send_overflow()
481 hp->n_throttle = 0; in hvsi_send_overflow()
490 struct hvsi_struct *hp = (struct hvsi_struct *)arg; in hvsi_interrupt() local
498 tty = tty_port_tty_get(&hp->port); in hvsi_interrupt()
501 spin_lock_irqsave(&hp->lock, flags); in hvsi_interrupt()
502 again = hvsi_load_chunk(hp, tty, &handshake); in hvsi_interrupt()
503 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_interrupt()
511 spin_lock_irqsave(&hp->lock, flags); in hvsi_interrupt()
512 if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { in hvsi_interrupt()
515 hvsi_send_overflow(hp); in hvsi_interrupt()
516 tty_flip_buffer_push(&hp->port); in hvsi_interrupt()
518 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_interrupt()
526 static int __init poll_for_state(struct hvsi_struct *hp, int state) in poll_for_state() argument
531 hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */ in poll_for_state()
533 if (hp->state == state) in poll_for_state()
543 static int wait_for_state(struct hvsi_struct *hp, int state) in wait_for_state() argument
547 if (!wait_event_timeout(hp->stateq, (hp->state == state), HVSI_TIMEOUT)) in wait_for_state()
553 static int hvsi_query(struct hvsi_struct *hp, uint16_t verb) in hvsi_query() argument
560 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_query()
566 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_query()
568 printk(KERN_ERR "hvsi%i: couldn't send query (%i)!\n", hp->index, in hvsi_query()
576 static int hvsi_get_mctrl(struct hvsi_struct *hp) in hvsi_get_mctrl() argument
580 set_state(hp, HVSI_WAIT_FOR_MCTRL_RESPONSE); in hvsi_get_mctrl()
581 hvsi_query(hp, VSV_SEND_MODEM_CTL_STATUS); in hvsi_get_mctrl()
583 ret = hvsi_wait(hp, HVSI_OPEN); in hvsi_get_mctrl()
585 printk(KERN_ERR "hvsi%i: didn't get modem flags\n", hp->index); in hvsi_get_mctrl()
586 set_state(hp, HVSI_OPEN); in hvsi_get_mctrl()
590 pr_debug("%s: mctrl 0x%x\n", __func__, hp->mctrl); in hvsi_get_mctrl()
596 static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl) in hvsi_set_mctrl() argument
602 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_set_mctrl()
613 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_set_mctrl()
615 printk(KERN_ERR "hvsi%i: couldn't set DTR!\n", hp->index); in hvsi_set_mctrl()
622 static void hvsi_drain_input(struct hvsi_struct *hp) in hvsi_drain_input() argument
628 if (0 == hvsi_read(hp, buf, HVSI_MAX_READ)) in hvsi_drain_input()
632 static int hvsi_handshake(struct hvsi_struct *hp) in hvsi_handshake() argument
643 hvsi_drain_input(hp); in hvsi_handshake()
645 set_state(hp, HVSI_WAIT_FOR_VER_RESPONSE); in hvsi_handshake()
646 ret = hvsi_query(hp, VSV_SEND_VERSION_NUMBER); in hvsi_handshake()
648 printk(KERN_ERR "hvsi%i: couldn't send version query\n", hp->index); in hvsi_handshake()
652 ret = hvsi_wait(hp, HVSI_OPEN); in hvsi_handshake()
661 struct hvsi_struct *hp = in hvsi_handshaker() local
664 if (hvsi_handshake(hp) >= 0) in hvsi_handshaker()
667 printk(KERN_ERR "hvsi%i: re-handshaking failed\n", hp->index); in hvsi_handshaker()
668 if (is_console(hp)) { in hvsi_handshaker()
673 printk(KERN_ERR "hvsi%i: lost console!\n", hp->index); in hvsi_handshaker()
677 static int hvsi_put_chars(struct hvsi_struct *hp, const char *buf, int count) in hvsi_put_chars() argument
685 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_put_chars()
689 ret = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_put_chars()
697 static void hvsi_close_protocol(struct hvsi_struct *hp) in hvsi_close_protocol() argument
702 packet.hdr.seqno = cpu_to_be16(atomic_inc_return(&hp->seqno)); in hvsi_close_protocol()
709 hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_close_protocol()
714 struct hvsi_struct *hp; in hvsi_open() local
720 hp = &hvsi_ports[tty->index]; in hvsi_open()
722 tty->driver_data = hp; in hvsi_open()
725 if (hp->state == HVSI_FSP_DIED) in hvsi_open()
728 tty_port_tty_set(&hp->port, tty); in hvsi_open()
729 spin_lock_irqsave(&hp->lock, flags); in hvsi_open()
730 hp->port.count++; in hvsi_open()
731 atomic_set(&hp->seqno, 0); in hvsi_open()
732 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); in hvsi_open()
733 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_open()
735 if (is_console(hp)) in hvsi_open()
738 ret = hvsi_handshake(hp); in hvsi_open()
744 ret = hvsi_get_mctrl(hp); in hvsi_open()
750 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR); in hvsi_open()
760 static void hvsi_flush_output(struct hvsi_struct *hp) in hvsi_flush_output() argument
762 wait_event_timeout(hp->emptyq, (hp->n_outbuf <= 0), HVSI_TIMEOUT); in hvsi_flush_output()
765 cancel_delayed_work_sync(&hp->writer); in hvsi_flush_output()
766 flush_work(&hp->handshaker); in hvsi_flush_output()
772 hp->n_outbuf = 0; in hvsi_flush_output()
777 struct hvsi_struct *hp = tty->driver_data; in hvsi_close() local
785 spin_lock_irqsave(&hp->lock, flags); in hvsi_close()
787 if (--hp->port.count == 0) { in hvsi_close()
788 tty_port_tty_set(&hp->port, NULL); in hvsi_close()
789 hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */ in hvsi_close()
792 if (!is_console(hp)) { in hvsi_close()
793 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); /* no more irqs */ in hvsi_close()
794 __set_state(hp, HVSI_CLOSED); in hvsi_close()
801 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_close()
804 synchronize_irq(hp->virq); in hvsi_close()
807 hvsi_flush_output(hp); in hvsi_close()
810 hvsi_close_protocol(hp); in hvsi_close()
816 hvsi_drain_input(hp); in hvsi_close()
818 spin_lock_irqsave(&hp->lock, flags); in hvsi_close()
820 } else if (hp->port.count < 0) in hvsi_close()
822 hp - hvsi_ports, hp->port.count); in hvsi_close()
824 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_close()
829 struct hvsi_struct *hp = tty->driver_data; in hvsi_hangup() local
834 tty_port_tty_set(&hp->port, NULL); in hvsi_hangup()
836 spin_lock_irqsave(&hp->lock, flags); in hvsi_hangup()
837 hp->port.count = 0; in hvsi_hangup()
838 hp->n_outbuf = 0; in hvsi_hangup()
839 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_hangup()
843 static void hvsi_push(struct hvsi_struct *hp) in hvsi_push() argument
847 if (hp->n_outbuf <= 0) in hvsi_push()
850 n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf); in hvsi_push()
854 hp->n_outbuf = 0; in hvsi_push()
856 __set_state(hp, HVSI_FSP_DIED); in hvsi_push()
857 printk(KERN_ERR "hvsi%i: service processor died\n", hp->index); in hvsi_push()
864 struct hvsi_struct *hp = in hvsi_write_worker() local
874 spin_lock_irqsave(&hp->lock, flags); in hvsi_write_worker()
876 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); in hvsi_write_worker()
878 if (!is_open(hp)) { in hvsi_write_worker()
885 schedule_delayed_work(&hp->writer, HZ); in hvsi_write_worker()
889 hvsi_push(hp); in hvsi_write_worker()
890 if (hp->n_outbuf > 0) in hvsi_write_worker()
891 schedule_delayed_work(&hp->writer, 10); in hvsi_write_worker()
898 wake_up_all(&hp->emptyq); in hvsi_write_worker()
899 tty_port_tty_wakeup(&hp->port); in hvsi_write_worker()
903 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_write_worker()
908 struct hvsi_struct *hp = tty->driver_data; in hvsi_write_room() local
910 return N_OUTBUF - hp->n_outbuf; in hvsi_write_room()
915 struct hvsi_struct *hp = tty->driver_data; in hvsi_chars_in_buffer() local
917 return hp->n_outbuf; in hvsi_chars_in_buffer()
923 struct hvsi_struct *hp = tty->driver_data; in hvsi_write() local
929 spin_lock_irqsave(&hp->lock, flags); in hvsi_write()
931 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); in hvsi_write()
933 if (!is_open(hp)) { in hvsi_write()
947 BUG_ON(hp->n_outbuf < 0); in hvsi_write()
948 memcpy(hp->outbuf + hp->n_outbuf, source, chunksize); in hvsi_write()
949 hp->n_outbuf += chunksize; in hvsi_write()
954 hvsi_push(hp); in hvsi_write()
957 if (hp->n_outbuf > 0) { in hvsi_write()
962 schedule_delayed_work(&hp->writer, 10); in hvsi_write()
966 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_write()
981 struct hvsi_struct *hp = tty->driver_data; in hvsi_throttle() local
985 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); in hvsi_throttle()
990 struct hvsi_struct *hp = tty->driver_data; in hvsi_unthrottle() local
995 spin_lock_irqsave(&hp->lock, flags); in hvsi_unthrottle()
996 if (hp->n_throttle) { in hvsi_unthrottle()
997 hvsi_send_overflow(hp); in hvsi_unthrottle()
998 tty_flip_buffer_push(&hp->port); in hvsi_unthrottle()
1000 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_unthrottle()
1003 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); in hvsi_unthrottle()
1008 struct hvsi_struct *hp = tty->driver_data; in hvsi_tiocmget() local
1010 hvsi_get_mctrl(hp); in hvsi_tiocmget()
1011 return hp->mctrl; in hvsi_tiocmget()
1017 struct hvsi_struct *hp = tty->driver_data; in hvsi_tiocmset() local
1025 spin_lock_irqsave(&hp->lock, flags); in hvsi_tiocmset()
1027 new_mctrl = (hp->mctrl & ~clear) | set; in hvsi_tiocmset()
1029 if (hp->mctrl != new_mctrl) { in hvsi_tiocmset()
1030 hvsi_set_mctrl(hp, new_mctrl); in hvsi_tiocmset()
1031 hp->mctrl = new_mctrl; in hvsi_tiocmset()
1033 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_tiocmset()
1073 struct hvsi_struct *hp = &hvsi_ports[i]; in hvsi_init() local
1076 tty_port_link_device(&hp->port, hvsi_driver, i); in hvsi_init()
1078 ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); in hvsi_init()
1081 hp->virq, ret); in hvsi_init()
1099 struct hvsi_struct *hp = &hvsi_ports[console->index]; in hvsi_console_print() local
1105 if (!is_open(hp)) in hvsi_console_print()
1123 ret = hvsi_put_chars(hp, c, i); in hvsi_console_print()
1140 struct hvsi_struct *hp; in hvsi_console_setup() local
1145 hp = &hvsi_ports[console->index]; in hvsi_console_setup()
1148 hvsi_close_protocol(hp); in hvsi_console_setup()
1150 ret = hvsi_handshake(hp); in hvsi_console_setup()
1154 ret = hvsi_get_mctrl(hp); in hvsi_console_setup()
1158 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR); in hvsi_console_setup()
1162 hp->flags |= HVSI_CONSOLE; in hvsi_console_setup()
1184 struct hvsi_struct *hp; in hvsi_console_init() local
1197 hp = &hvsi_ports[hvsi_count]; in hvsi_console_init()
1198 INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker); in hvsi_console_init()
1199 INIT_WORK(&hp->handshaker, hvsi_handshaker); in hvsi_console_init()
1200 init_waitqueue_head(&hp->emptyq); in hvsi_console_init()
1201 init_waitqueue_head(&hp->stateq); in hvsi_console_init()
1202 spin_lock_init(&hp->lock); in hvsi_console_init()
1203 tty_port_init(&hp->port); in hvsi_console_init()
1204 hp->index = hvsi_count; in hvsi_console_init()
1205 hp->inbuf_end = hp->inbuf; in hvsi_console_init()
1206 hp->state = HVSI_CLOSED; in hvsi_console_init()
1207 hp->vtermno = be32_to_cpup(vtermno); in hvsi_console_init()
1208 hp->virq = irq_create_mapping(NULL, be32_to_cpup(irq)); in hvsi_console_init()
1209 if (hp->virq == 0) { in hvsi_console_init()
1212 tty_port_destroy(&hp->port); in hvsi_console_init()