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
271 switch (hp->state) { in hvsi_recv_response()
273 __set_state(hp, HVSI_WAIT_FOR_VER_QUERY); in hvsi_recv_response()
276 hp->mctrl = 0; in hvsi_recv_response()
278 hp->mctrl |= TIOCM_DTR; in hvsi_recv_response()
280 hp->mctrl |= TIOCM_CD; in hvsi_recv_response()
281 __set_state(hp, HVSI_OPEN); in hvsi_recv_response()
284 printk(KERN_ERR "hvsi%i: unexpected query response: ", hp->index); in hvsi_recv_response()
291 static int hvsi_version_respond(struct hvsi_struct *hp, uint16_t query_seqno) in hvsi_version_respond() argument
298 packet.hdr.seqno = atomic_inc_return(&hp->seqno); in hvsi_version_respond()
306 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_version_respond()
309 hp->index); in hvsi_version_respond()
316 static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet) in hvsi_recv_query() argument
320 switch (hp->state) { in hvsi_recv_query()
322 hvsi_version_respond(hp, query->hdr.seqno); in hvsi_recv_query()
323 __set_state(hp, HVSI_OPEN); in hvsi_recv_query()
326 printk(KERN_ERR "hvsi%i: unexpected query: ", hp->index); in hvsi_recv_query()
332 static void hvsi_insert_chars(struct hvsi_struct *hp, const char *buf, int len) in hvsi_insert_chars() argument
340 hp->sysrq = 1; in hvsi_insert_chars()
342 } else if (hp->sysrq) { in hvsi_insert_chars()
344 hp->sysrq = 0; in hvsi_insert_chars()
348 tty_insert_flip_char(&hp->port, c, 0); in hvsi_insert_chars()
361 static bool hvsi_recv_data(struct hvsi_struct *hp, const uint8_t *packet) in hvsi_recv_data() argument
378 hvsi_insert_chars(hp, data, datalen); in hvsi_recv_data()
386 memcpy(hp->throttle_buf, data + TTY_THRESHOLD_THROTTLE, overflow); in hvsi_recv_data()
387 hp->n_throttle = overflow; in hvsi_recv_data()
399 static int hvsi_load_chunk(struct hvsi_struct *hp, struct tty_struct *tty, in hvsi_load_chunk() argument
402 uint8_t *packet = hp->inbuf; in hvsi_load_chunk()
408 chunklen = hvsi_read(hp, hp->inbuf_end, HVSI_MAX_READ); in hvsi_load_chunk()
415 dbg_dump_hex(hp->inbuf_end, chunklen); in hvsi_load_chunk()
417 hp->inbuf_end += chunklen; in hvsi_load_chunk()
420 while ((packet < hp->inbuf_end) && got_packet(hp, packet)) { in hvsi_load_chunk()
424 printk(KERN_ERR "hvsi%i: got malformed packet\n", hp->index); in hvsi_load_chunk()
426 while ((packet < hp->inbuf_end) && (!is_header(packet))) in hvsi_load_chunk()
437 if (!is_open(hp)) in hvsi_load_chunk()
439 flip = hvsi_recv_data(hp, packet); in hvsi_load_chunk()
442 hvsi_recv_control(hp, packet, tty, handshake); in hvsi_load_chunk()
445 hvsi_recv_response(hp, packet); in hvsi_load_chunk()
448 hvsi_recv_query(hp, packet); in hvsi_load_chunk()
452 hp->index, header->type); in hvsi_load_chunk()
465 compact_inbuf(hp, packet); in hvsi_load_chunk()
468 tty_flip_buffer_push(&hp->port); in hvsi_load_chunk()
473 static void hvsi_send_overflow(struct hvsi_struct *hp) in hvsi_send_overflow() argument
476 hp->n_throttle); in hvsi_send_overflow()
478 hvsi_insert_chars(hp, hp->throttle_buf, hp->n_throttle); in hvsi_send_overflow()
479 hp->n_throttle = 0; in hvsi_send_overflow()
488 struct hvsi_struct *hp = (struct hvsi_struct *)arg; in hvsi_interrupt() local
496 tty = tty_port_tty_get(&hp->port); in hvsi_interrupt()
499 spin_lock_irqsave(&hp->lock, flags); in hvsi_interrupt()
500 again = hvsi_load_chunk(hp, tty, &handshake); in hvsi_interrupt()
501 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_interrupt()
509 spin_lock_irqsave(&hp->lock, flags); in hvsi_interrupt()
510 if (tty && hp->n_throttle && !test_bit(TTY_THROTTLED, &tty->flags)) { in hvsi_interrupt()
513 hvsi_send_overflow(hp); in hvsi_interrupt()
514 tty_flip_buffer_push(&hp->port); in hvsi_interrupt()
516 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_interrupt()
524 static int __init poll_for_state(struct hvsi_struct *hp, int state) in poll_for_state() argument
529 hvsi_interrupt(hp->virq, (void *)hp); /* get pending data */ in poll_for_state()
531 if (hp->state == state) in poll_for_state()
541 static int wait_for_state(struct hvsi_struct *hp, int state) in wait_for_state() argument
545 if (!wait_event_timeout(hp->stateq, (hp->state == state), HVSI_TIMEOUT)) in wait_for_state()
551 static int hvsi_query(struct hvsi_struct *hp, uint16_t verb) in hvsi_query() argument
558 packet.hdr.seqno = atomic_inc_return(&hp->seqno); in hvsi_query()
564 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_query()
566 printk(KERN_ERR "hvsi%i: couldn't send query (%i)!\n", hp->index, in hvsi_query()
574 static int hvsi_get_mctrl(struct hvsi_struct *hp) in hvsi_get_mctrl() argument
578 set_state(hp, HVSI_WAIT_FOR_MCTRL_RESPONSE); in hvsi_get_mctrl()
579 hvsi_query(hp, VSV_SEND_MODEM_CTL_STATUS); in hvsi_get_mctrl()
581 ret = hvsi_wait(hp, HVSI_OPEN); in hvsi_get_mctrl()
583 printk(KERN_ERR "hvsi%i: didn't get modem flags\n", hp->index); in hvsi_get_mctrl()
584 set_state(hp, HVSI_OPEN); in hvsi_get_mctrl()
588 pr_debug("%s: mctrl 0x%x\n", __func__, hp->mctrl); in hvsi_get_mctrl()
594 static int hvsi_set_mctrl(struct hvsi_struct *hp, uint16_t mctrl) in hvsi_set_mctrl() argument
600 packet.hdr.seqno = atomic_inc_return(&hp->seqno); in hvsi_set_mctrl()
611 wrote = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_set_mctrl()
613 printk(KERN_ERR "hvsi%i: couldn't set DTR!\n", hp->index); in hvsi_set_mctrl()
620 static void hvsi_drain_input(struct hvsi_struct *hp) in hvsi_drain_input() argument
626 if (0 == hvsi_read(hp, buf, HVSI_MAX_READ)) in hvsi_drain_input()
630 static int hvsi_handshake(struct hvsi_struct *hp) in hvsi_handshake() argument
641 hvsi_drain_input(hp); in hvsi_handshake()
643 set_state(hp, HVSI_WAIT_FOR_VER_RESPONSE); in hvsi_handshake()
644 ret = hvsi_query(hp, VSV_SEND_VERSION_NUMBER); in hvsi_handshake()
646 printk(KERN_ERR "hvsi%i: couldn't send version query\n", hp->index); in hvsi_handshake()
650 ret = hvsi_wait(hp, HVSI_OPEN); in hvsi_handshake()
659 struct hvsi_struct *hp = in hvsi_handshaker() local
662 if (hvsi_handshake(hp) >= 0) in hvsi_handshaker()
665 printk(KERN_ERR "hvsi%i: re-handshaking failed\n", hp->index); in hvsi_handshaker()
666 if (is_console(hp)) { in hvsi_handshaker()
671 printk(KERN_ERR "hvsi%i: lost console!\n", hp->index); in hvsi_handshaker()
675 static int hvsi_put_chars(struct hvsi_struct *hp, const char *buf, int count) in hvsi_put_chars() argument
683 packet.hdr.seqno = atomic_inc_return(&hp->seqno); in hvsi_put_chars()
687 ret = hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_put_chars()
695 static void hvsi_close_protocol(struct hvsi_struct *hp) in hvsi_close_protocol() argument
700 packet.hdr.seqno = atomic_inc_return(&hp->seqno); in hvsi_close_protocol()
707 hvc_put_chars(hp->vtermno, (char *)&packet, packet.hdr.len); in hvsi_close_protocol()
712 struct hvsi_struct *hp; in hvsi_open() local
718 hp = &hvsi_ports[tty->index]; in hvsi_open()
720 tty->driver_data = hp; in hvsi_open()
723 if (hp->state == HVSI_FSP_DIED) in hvsi_open()
726 tty_port_tty_set(&hp->port, tty); in hvsi_open()
727 spin_lock_irqsave(&hp->lock, flags); in hvsi_open()
728 hp->port.count++; in hvsi_open()
729 atomic_set(&hp->seqno, 0); in hvsi_open()
730 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); in hvsi_open()
731 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_open()
733 if (is_console(hp)) in hvsi_open()
736 ret = hvsi_handshake(hp); in hvsi_open()
742 ret = hvsi_get_mctrl(hp); in hvsi_open()
748 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR); in hvsi_open()
758 static void hvsi_flush_output(struct hvsi_struct *hp) in hvsi_flush_output() argument
760 wait_event_timeout(hp->emptyq, (hp->n_outbuf <= 0), HVSI_TIMEOUT); in hvsi_flush_output()
763 cancel_delayed_work_sync(&hp->writer); in hvsi_flush_output()
764 flush_work(&hp->handshaker); in hvsi_flush_output()
770 hp->n_outbuf = 0; in hvsi_flush_output()
775 struct hvsi_struct *hp = tty->driver_data; in hvsi_close() local
783 spin_lock_irqsave(&hp->lock, flags); in hvsi_close()
785 if (--hp->port.count == 0) { in hvsi_close()
786 tty_port_tty_set(&hp->port, NULL); in hvsi_close()
787 hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */ in hvsi_close()
790 if (!is_console(hp)) { in hvsi_close()
791 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); /* no more irqs */ in hvsi_close()
792 __set_state(hp, HVSI_CLOSED); in hvsi_close()
799 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_close()
802 synchronize_irq(hp->virq); in hvsi_close()
805 hvsi_flush_output(hp); in hvsi_close()
808 hvsi_close_protocol(hp); in hvsi_close()
814 hvsi_drain_input(hp); in hvsi_close()
816 spin_lock_irqsave(&hp->lock, flags); in hvsi_close()
818 } else if (hp->port.count < 0) in hvsi_close()
820 hp - hvsi_ports, hp->port.count); in hvsi_close()
822 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_close()
827 struct hvsi_struct *hp = tty->driver_data; in hvsi_hangup() local
832 tty_port_tty_set(&hp->port, NULL); in hvsi_hangup()
834 spin_lock_irqsave(&hp->lock, flags); in hvsi_hangup()
835 hp->port.count = 0; in hvsi_hangup()
836 hp->n_outbuf = 0; in hvsi_hangup()
837 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_hangup()
841 static void hvsi_push(struct hvsi_struct *hp) in hvsi_push() argument
845 if (hp->n_outbuf <= 0) in hvsi_push()
848 n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf); in hvsi_push()
852 hp->n_outbuf = 0; in hvsi_push()
854 __set_state(hp, HVSI_FSP_DIED); in hvsi_push()
855 printk(KERN_ERR "hvsi%i: service processor died\n", hp->index); in hvsi_push()
862 struct hvsi_struct *hp = in hvsi_write_worker() local
872 spin_lock_irqsave(&hp->lock, flags); in hvsi_write_worker()
874 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); in hvsi_write_worker()
876 if (!is_open(hp)) { in hvsi_write_worker()
883 schedule_delayed_work(&hp->writer, HZ); in hvsi_write_worker()
887 hvsi_push(hp); in hvsi_write_worker()
888 if (hp->n_outbuf > 0) in hvsi_write_worker()
889 schedule_delayed_work(&hp->writer, 10); in hvsi_write_worker()
896 wake_up_all(&hp->emptyq); in hvsi_write_worker()
897 tty_port_tty_wakeup(&hp->port); in hvsi_write_worker()
901 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_write_worker()
906 struct hvsi_struct *hp = tty->driver_data; in hvsi_write_room() local
908 return N_OUTBUF - hp->n_outbuf; in hvsi_write_room()
913 struct hvsi_struct *hp = tty->driver_data; in hvsi_chars_in_buffer() local
915 return hp->n_outbuf; in hvsi_chars_in_buffer()
921 struct hvsi_struct *hp = tty->driver_data; in hvsi_write() local
927 spin_lock_irqsave(&hp->lock, flags); in hvsi_write()
929 pr_debug("%s: %i chars in buffer\n", __func__, hp->n_outbuf); in hvsi_write()
931 if (!is_open(hp)) { in hvsi_write()
945 BUG_ON(hp->n_outbuf < 0); in hvsi_write()
946 memcpy(hp->outbuf + hp->n_outbuf, source, chunksize); in hvsi_write()
947 hp->n_outbuf += chunksize; in hvsi_write()
952 hvsi_push(hp); in hvsi_write()
955 if (hp->n_outbuf > 0) { in hvsi_write()
960 schedule_delayed_work(&hp->writer, 10); in hvsi_write()
964 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_write()
979 struct hvsi_struct *hp = tty->driver_data; in hvsi_throttle() local
983 h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); in hvsi_throttle()
988 struct hvsi_struct *hp = tty->driver_data; in hvsi_unthrottle() local
993 spin_lock_irqsave(&hp->lock, flags); in hvsi_unthrottle()
994 if (hp->n_throttle) { in hvsi_unthrottle()
995 hvsi_send_overflow(hp); in hvsi_unthrottle()
996 tty_flip_buffer_push(&hp->port); in hvsi_unthrottle()
998 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_unthrottle()
1001 h_vio_signal(hp->vtermno, VIO_IRQ_ENABLE); in hvsi_unthrottle()
1006 struct hvsi_struct *hp = tty->driver_data; in hvsi_tiocmget() local
1008 hvsi_get_mctrl(hp); in hvsi_tiocmget()
1009 return hp->mctrl; in hvsi_tiocmget()
1015 struct hvsi_struct *hp = tty->driver_data; in hvsi_tiocmset() local
1023 spin_lock_irqsave(&hp->lock, flags); in hvsi_tiocmset()
1025 new_mctrl = (hp->mctrl & ~clear) | set; in hvsi_tiocmset()
1027 if (hp->mctrl != new_mctrl) { in hvsi_tiocmset()
1028 hvsi_set_mctrl(hp, new_mctrl); in hvsi_tiocmset()
1029 hp->mctrl = new_mctrl; in hvsi_tiocmset()
1031 spin_unlock_irqrestore(&hp->lock, flags); in hvsi_tiocmset()
1071 struct hvsi_struct *hp = &hvsi_ports[i]; in hvsi_init() local
1074 tty_port_link_device(&hp->port, hvsi_driver, i); in hvsi_init()
1076 ret = request_irq(hp->virq, hvsi_interrupt, 0, "hvsi", hp); in hvsi_init()
1079 hp->virq, ret); in hvsi_init()
1097 struct hvsi_struct *hp = &hvsi_ports[console->index]; in hvsi_console_print() local
1103 if (!is_open(hp)) in hvsi_console_print()
1121 ret = hvsi_put_chars(hp, c, i); in hvsi_console_print()
1138 struct hvsi_struct *hp; in hvsi_console_setup() local
1143 hp = &hvsi_ports[console->index]; in hvsi_console_setup()
1146 hvsi_close_protocol(hp); in hvsi_console_setup()
1148 ret = hvsi_handshake(hp); in hvsi_console_setup()
1152 ret = hvsi_get_mctrl(hp); in hvsi_console_setup()
1156 ret = hvsi_set_mctrl(hp, hp->mctrl | TIOCM_DTR); in hvsi_console_setup()
1160 hp->flags |= HVSI_CONSOLE; in hvsi_console_setup()
1182 struct hvsi_struct *hp; in hvsi_console_init() local
1195 hp = &hvsi_ports[hvsi_count]; in hvsi_console_init()
1196 INIT_DELAYED_WORK(&hp->writer, hvsi_write_worker); in hvsi_console_init()
1197 INIT_WORK(&hp->handshaker, hvsi_handshaker); in hvsi_console_init()
1198 init_waitqueue_head(&hp->emptyq); in hvsi_console_init()
1199 init_waitqueue_head(&hp->stateq); in hvsi_console_init()
1200 spin_lock_init(&hp->lock); in hvsi_console_init()
1201 tty_port_init(&hp->port); in hvsi_console_init()
1202 hp->index = hvsi_count; in hvsi_console_init()
1203 hp->inbuf_end = hp->inbuf; in hvsi_console_init()
1204 hp->state = HVSI_CLOSED; in hvsi_console_init()
1205 hp->vtermno = *vtermno; in hvsi_console_init()
1206 hp->virq = irq_create_mapping(NULL, irq[0]); in hvsi_console_init()
1207 if (hp->virq == 0) { in hvsi_console_init()
1210 tty_port_destroy(&hp->port); in hvsi_console_init()