static inline void set_state(struct hvsi_struct *hp, int state) { unsigned long flags; spin_lock_irqsave(&hp->lock, flags); __set_state(hp, state); spin_unlock_irqrestore(&hp->lock, flags); }
static void hvsi_recv_response(struct hvsi_struct *hp, uint8_t *packet) { struct hvsi_query_response *resp = (struct hvsi_query_response *)packet; switch (hp->state) { case HVSI_WAIT_FOR_VER_RESPONSE: __set_state(hp, HVSI_WAIT_FOR_VER_QUERY); break; case HVSI_WAIT_FOR_MCTRL_RESPONSE: hp->mctrl = 0; if (resp->u.mctrl_word & HVSI_TSDTR) hp->mctrl |= TIOCM_DTR; if (resp->u.mctrl_word & HVSI_TSCD) hp->mctrl |= TIOCM_CD; __set_state(hp, HVSI_OPEN); break; default: printk(KERN_ERR "hvsi%i: unexpected query response: ", hp->index); dump_packet(packet); break; } }
static void hvsi_close(struct tty_struct *tty, struct file *filp) { struct hvsi_struct *hp = tty->driver_data; unsigned long flags; pr_debug("%s\n", __FUNCTION__); if (tty_hung_up_p(filp)) return; spin_lock_irqsave(&hp->lock, flags); if (--hp->count == 0) { hp->tty = NULL; hp->inbuf_end = hp->inbuf; /* discard remaining partial packets */ /* only close down connection if it is not the console */ if (!is_console(hp)) { h_vio_signal(hp->vtermno, VIO_IRQ_DISABLE); /* no more irqs */ __set_state(hp, HVSI_CLOSED); /* * any data delivered to the tty layer after this will be * discarded (except for XON/XOFF) */ tty->closing = 1; spin_unlock_irqrestore(&hp->lock, flags); /* let any existing irq handlers finish. no more will start. */ synchronize_irq(hp->virq); /* hvsi_write_worker will re-schedule until outbuf is empty. */ hvsi_flush_output(hp); /* tell FSP to stop sending data */ hvsi_close_protocol(hp); /* * drain anything FSP is still in the middle of sending, and let * hvsi_handshake drain the rest on the next open. */ hvsi_drain_input(hp); spin_lock_irqsave(&hp->lock, flags); } } else if (hp->count < 0) printk(KERN_ERR "hvsi_close %lu: oops, count is %d\n", hp - hvsi_ports, hp->count); spin_unlock_irqrestore(&hp->lock, flags); }
static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet) { struct hvsi_query *query = (struct hvsi_query *)packet; switch (hp->state) { case HVSI_WAIT_FOR_VER_QUERY: hvsi_version_respond(hp, query->seqno); __set_state(hp, HVSI_OPEN); break; default: printk(KERN_ERR "hvsi%i: unexpected query: ", hp->index); dump_packet(packet); break; } }
static void hvsi_recv_query(struct hvsi_struct *hp, uint8_t *packet) { struct hvsi_query *query = (struct hvsi_query *)packet; switch (hp->state) { case HVSI_WAIT_FOR_VER_QUERY: hvsi_version_respond(hp, query->seqno); __set_state(hp, HVSI_OPEN); break; default: ; dump_packet(packet); break; } }
/* called with hp->lock held */ static void hvsi_push(struct hvsi_struct *hp) { int n; if (hp->n_outbuf <= 0) return; n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf); if (n > 0) { /* success */ pr_debug("%s: wrote %i chars\n", __FUNCTION__, n); hp->n_outbuf = 0; } else if (n == -EIO) { __set_state(hp, HVSI_FSP_DIED); printk(KERN_ERR "hvsi%i: service processor died\n", hp->index); } }
/* called with hp->lock held */ static void hvsi_push(struct hvsi_struct *hp) { int n; if (hp->n_outbuf <= 0) return; n = hvsi_put_chars(hp, hp->outbuf, hp->n_outbuf); if (n > 0) { /* success */ pr_debug("%s: wrote %i chars\n", __func__, n); hp->n_outbuf = 0; } else if (n == -EIO) { __set_state(hp, HVSI_FSP_DIED); ; } }
static int xmit_packet_precheck(struct ctx *ctx, unsigned int cpu) { unsigned int i; unsigned long plen_total, orig = ctx->num; size_t mtu, total_len = 0; bug_on(plen != dlen); for (i = 0; i < plen; ++i) total_len += packets[i].len; __set_state_cf(cpu, plen, total_len, CPU_STATS_STATE_CFG); plen_total = __wait_and_sum_others(ctx, cpu); if (orig > 0) { ctx->num = (unsigned long) round((1.0 * plen / plen_total) * orig); __set_state_cd(cpu, ctx->num, CPU_STATS_STATE_CHK | CPU_STATS_STATE_CFG); __correct_global_delta(ctx, cpu, orig); } if (plen == 0) { __set_state(cpu, CPU_STATS_STATE_RES); return 0; } for (mtu = device_mtu(ctx->device), i = 0; i < plen; ++i) { if (packets[i].len > mtu + PKT_MIN_LEN) panic("Device MTU < than packet%d's size!\n", i); if (packets[i].len <= PKT_MIN_LEN) panic("Packet%d's size must be > %d bytes!\n", i, PKT_MIN_LEN); } return 0; }