Lines Matching refs:vio

18 int vio_ldc_send(struct vio_driver_state *vio, void *data, int len)  in vio_ldc_send()  argument
24 err = ldc_write(vio->lp, data, len); in vio_ldc_send()
34 static int send_ctrl(struct vio_driver_state *vio, in send_ctrl() argument
37 tag->sid = vio_send_sid(vio); in send_ctrl()
38 return vio_ldc_send(vio, tag, len); in send_ctrl()
48 static int send_version(struct vio_driver_state *vio, u16 major, u16 minor) in send_version() argument
52 vio->_local_sid = (u32) sched_clock(); in send_version()
58 pkt.dev_class = vio->dev_class; in send_version()
61 major, minor, vio->dev_class); in send_version()
63 return send_ctrl(vio, &pkt.tag, sizeof(pkt)); in send_version()
66 static int start_handshake(struct vio_driver_state *vio) in start_handshake() argument
72 vio->hs_state = VIO_HS_INVALID; in start_handshake()
74 err = send_version(vio, in start_handshake()
75 vio->ver_table[0].major, in start_handshake()
76 vio->ver_table[0].minor); in start_handshake()
83 static void flush_rx_dring(struct vio_driver_state *vio) in flush_rx_dring() argument
88 BUG_ON(!(vio->dr_state & VIO_DR_STATE_RXREG)); in flush_rx_dring()
90 dr = &vio->drings[VIO_DRIVER_RX_RING]; in flush_rx_dring()
93 BUG_ON(!vio->desc_buf); in flush_rx_dring()
94 kfree(vio->desc_buf); in flush_rx_dring()
95 vio->desc_buf = NULL; in flush_rx_dring()
101 void vio_link_state_change(struct vio_driver_state *vio, int event) in vio_link_state_change() argument
104 vio->hs_state = VIO_HS_INVALID; in vio_link_state_change()
106 switch (vio->dev_class) { in vio_link_state_change()
109 vio->dr_state = (VIO_DR_STATE_TXREQ | in vio_link_state_change()
114 vio->dr_state = VIO_DR_STATE_TXREQ; in vio_link_state_change()
117 vio->dr_state = VIO_DR_STATE_RXREQ; in vio_link_state_change()
120 start_handshake(vio); in vio_link_state_change()
122 vio->hs_state = VIO_HS_INVALID; in vio_link_state_change()
124 if (vio->dr_state & VIO_DR_STATE_RXREG) in vio_link_state_change()
125 flush_rx_dring(vio); in vio_link_state_change()
127 vio->dr_state = 0x00; in vio_link_state_change()
128 memset(&vio->ver, 0, sizeof(vio->ver)); in vio_link_state_change()
130 ldc_disconnect(vio->lp); in vio_link_state_change()
135 static int handshake_failure(struct vio_driver_state *vio) in handshake_failure() argument
146 vio->dr_state &= ~(VIO_DR_STATE_TXREG | in handshake_failure()
149 dr = &vio->drings[VIO_DRIVER_RX_RING]; in handshake_failure()
152 kfree(vio->desc_buf); in handshake_failure()
153 vio->desc_buf = NULL; in handshake_failure()
154 vio->desc_buf_len = 0; in handshake_failure()
156 vio->hs_state = VIO_HS_INVALID; in handshake_failure()
161 static int process_unknown(struct vio_driver_state *vio, void *arg) in process_unknown() argument
169 vio->vdev->channel_id); in process_unknown()
171 ldc_disconnect(vio->lp); in process_unknown()
176 static int send_dreg(struct vio_driver_state *vio) in send_dreg() argument
178 struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_TX_RING]; in send_dreg()
215 return send_ctrl(vio, &u.pkt.tag, bytes); in send_dreg()
218 static int send_rdx(struct vio_driver_state *vio) in send_rdx() argument
228 return send_ctrl(vio, &pkt.tag, sizeof(pkt)); in send_rdx()
231 static int send_attr(struct vio_driver_state *vio) in send_attr() argument
233 if (!vio->ops) in send_attr()
236 return vio->ops->send_attr(vio); in send_attr()
239 static struct vio_version *find_by_major(struct vio_driver_state *vio, in find_by_major() argument
245 for (i = 0; i < vio->ver_table_entries; i++) { in find_by_major()
246 struct vio_version *v = &vio->ver_table[i]; in find_by_major()
255 static int process_ver_info(struct vio_driver_state *vio, in process_ver_info() argument
264 if (vio->hs_state != VIO_HS_INVALID) { in process_ver_info()
266 memset(&vio->ver, 0, sizeof(vio->ver)); in process_ver_info()
267 vio->hs_state = VIO_HS_INVALID; in process_ver_info()
270 vap = find_by_major(vio, pkt->major); in process_ver_info()
272 vio->_peer_sid = pkt->tag.sid; in process_ver_info()
279 err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_info()
286 err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_info()
296 pkt->dev_class = vio->dev_class; in process_ver_info()
299 err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_info()
301 vio->ver = ver; in process_ver_info()
302 vio->hs_state = VIO_HS_GOTVERS; in process_ver_info()
306 return handshake_failure(vio); in process_ver_info()
311 static int process_ver_ack(struct vio_driver_state *vio, in process_ver_ack() argument
317 if (vio->hs_state & VIO_HS_GOTVERS) { in process_ver_ack()
318 if (vio->ver.major != pkt->major || in process_ver_ack()
319 vio->ver.minor != pkt->minor) { in process_ver_ack()
321 (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_ack()
322 return handshake_failure(vio); in process_ver_ack()
325 vio->ver.major = pkt->major; in process_ver_ack()
326 vio->ver.minor = pkt->minor; in process_ver_ack()
327 vio->hs_state = VIO_HS_GOTVERS; in process_ver_ack()
330 switch (vio->dev_class) { in process_ver_ack()
333 if (send_attr(vio) < 0) in process_ver_ack()
334 return handshake_failure(vio); in process_ver_ack()
344 static int process_ver_nack(struct vio_driver_state *vio, in process_ver_nack() argument
353 return handshake_failure(vio); in process_ver_nack()
354 nver = find_by_major(vio, pkt->major); in process_ver_nack()
356 return handshake_failure(vio); in process_ver_nack()
358 if (send_version(vio, nver->major, nver->minor) < 0) in process_ver_nack()
359 return handshake_failure(vio); in process_ver_nack()
364 static int process_ver(struct vio_driver_state *vio, struct vio_ver_info *pkt) in process_ver() argument
368 return process_ver_info(vio, pkt); in process_ver()
371 return process_ver_ack(vio, pkt); in process_ver()
374 return process_ver_nack(vio, pkt); in process_ver()
377 return handshake_failure(vio); in process_ver()
381 static int process_attr(struct vio_driver_state *vio, void *pkt) in process_attr() argument
385 if (!(vio->hs_state & VIO_HS_GOTVERS)) in process_attr()
386 return handshake_failure(vio); in process_attr()
388 if (!vio->ops) in process_attr()
391 err = vio->ops->handle_attr(vio, pkt); in process_attr()
393 return handshake_failure(vio); in process_attr()
395 vio->hs_state |= VIO_HS_GOT_ATTR; in process_attr()
397 if ((vio->dr_state & VIO_DR_STATE_TXREQ) && in process_attr()
398 !(vio->hs_state & VIO_HS_SENT_DREG)) { in process_attr()
399 if (send_dreg(vio) < 0) in process_attr()
400 return handshake_failure(vio); in process_attr()
402 vio->hs_state |= VIO_HS_SENT_DREG; in process_attr()
409 static int all_drings_registered(struct vio_driver_state *vio) in all_drings_registered() argument
413 need_rx = (vio->dr_state & VIO_DR_STATE_RXREQ); in all_drings_registered()
414 need_tx = (vio->dr_state & VIO_DR_STATE_TXREQ); in all_drings_registered()
417 !(vio->dr_state & VIO_DR_STATE_RXREG)) in all_drings_registered()
421 !(vio->dr_state & VIO_DR_STATE_TXREG)) in all_drings_registered()
427 static int process_dreg_info(struct vio_driver_state *vio, in process_dreg_info() argument
439 if (!(vio->dr_state & VIO_DR_STATE_RXREQ)) in process_dreg_info()
442 if (vio->dr_state & VIO_DR_STATE_RXREG) in process_dreg_info()
446 if (vio_version_after_eq(vio, 1, 6)) { in process_dreg_info()
452 BUG_ON(vio->desc_buf); in process_dreg_info()
454 vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); in process_dreg_info()
455 if (!vio->desc_buf) in process_dreg_info()
458 vio->desc_buf_len = pkt->descr_size; in process_dreg_info()
460 dr = &vio->drings[VIO_DRIVER_RX_RING]; in process_dreg_info()
485 if (send_ctrl(vio, &pkt->tag, struct_size(pkt, cookies, dr->ncookies)) < 0) in process_dreg_info()
488 vio->dr_state |= VIO_DR_STATE_RXREG; in process_dreg_info()
495 (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_dreg_info()
497 return handshake_failure(vio); in process_dreg_info()
500 static int process_dreg_ack(struct vio_driver_state *vio, in process_dreg_ack() argument
511 dr = &vio->drings[VIO_DRIVER_TX_RING]; in process_dreg_ack()
513 if (!(vio->dr_state & VIO_DR_STATE_TXREQ)) in process_dreg_ack()
514 return handshake_failure(vio); in process_dreg_ack()
517 vio->dr_state |= VIO_DR_STATE_TXREG; in process_dreg_ack()
519 if (all_drings_registered(vio)) { in process_dreg_ack()
520 if (send_rdx(vio) < 0) in process_dreg_ack()
521 return handshake_failure(vio); in process_dreg_ack()
522 vio->hs_state = VIO_HS_SENT_RDX; in process_dreg_ack()
527 static int process_dreg_nack(struct vio_driver_state *vio, in process_dreg_nack() argument
536 return handshake_failure(vio); in process_dreg_nack()
539 static int process_dreg(struct vio_driver_state *vio, in process_dreg() argument
542 if (!(vio->hs_state & VIO_HS_GOTVERS)) in process_dreg()
543 return handshake_failure(vio); in process_dreg()
547 return process_dreg_info(vio, pkt); in process_dreg()
550 return process_dreg_ack(vio, pkt); in process_dreg()
553 return process_dreg_nack(vio, pkt); in process_dreg()
556 return handshake_failure(vio); in process_dreg()
560 static int process_dunreg(struct vio_driver_state *vio, in process_dunreg() argument
563 struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_RX_RING]; in process_dunreg()
570 vio->dr_state &= ~VIO_DR_STATE_RXREG; in process_dunreg()
574 kfree(vio->desc_buf); in process_dunreg()
575 vio->desc_buf = NULL; in process_dunreg()
576 vio->desc_buf_len = 0; in process_dunreg()
581 static int process_rdx_info(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx_info() argument
587 if (send_ctrl(vio, &pkt->tag, sizeof(*pkt)) < 0) in process_rdx_info()
588 return handshake_failure(vio); in process_rdx_info()
590 vio->hs_state |= VIO_HS_SENT_RDX_ACK; in process_rdx_info()
594 static int process_rdx_ack(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx_ack() argument
598 if (!(vio->hs_state & VIO_HS_SENT_RDX)) in process_rdx_ack()
599 return handshake_failure(vio); in process_rdx_ack()
601 vio->hs_state |= VIO_HS_GOT_RDX_ACK; in process_rdx_ack()
605 static int process_rdx_nack(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx_nack() argument
609 return handshake_failure(vio); in process_rdx_nack()
612 static int process_rdx(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx() argument
614 if (!all_drings_registered(vio)) in process_rdx()
615 handshake_failure(vio); in process_rdx()
619 return process_rdx_info(vio, pkt); in process_rdx()
622 return process_rdx_ack(vio, pkt); in process_rdx()
625 return process_rdx_nack(vio, pkt); in process_rdx()
628 return handshake_failure(vio); in process_rdx()
632 int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt) in vio_control_pkt_engine() argument
635 u8 prev_state = vio->hs_state; in vio_control_pkt_engine()
640 err = process_ver(vio, pkt); in vio_control_pkt_engine()
644 err = process_attr(vio, pkt); in vio_control_pkt_engine()
648 err = process_dreg(vio, pkt); in vio_control_pkt_engine()
652 err = process_dunreg(vio, pkt); in vio_control_pkt_engine()
656 err = process_rdx(vio, pkt); in vio_control_pkt_engine()
660 err = process_unknown(vio, pkt); in vio_control_pkt_engine()
665 vio->hs_state != prev_state && in vio_control_pkt_engine()
666 (vio->hs_state & VIO_HS_COMPLETE)) { in vio_control_pkt_engine()
667 if (vio->ops) in vio_control_pkt_engine()
668 vio->ops->handshake_complete(vio); in vio_control_pkt_engine()
675 void vio_conn_reset(struct vio_driver_state *vio) in vio_conn_reset() argument
685 int vio_validate_sid(struct vio_driver_state *vio, struct vio_msg_tag *tp) in vio_validate_sid() argument
698 switch (vio->dev_class) { in vio_validate_sid()
703 sid = vio->_peer_sid; in vio_validate_sid()
707 sid = vio->_local_sid; in vio_validate_sid()
714 tp->sid, vio->_peer_sid, vio->_local_sid); in vio_validate_sid()
719 u32 vio_send_sid(struct vio_driver_state *vio) in vio_send_sid() argument
721 switch (vio->dev_class) { in vio_send_sid()
726 return vio->_local_sid; in vio_send_sid()
729 return vio->_peer_sid; in vio_send_sid()
734 int vio_ldc_alloc(struct vio_driver_state *vio, in vio_ldc_alloc() argument
741 cfg.tx_irq = vio->vdev->tx_irq; in vio_ldc_alloc()
742 cfg.rx_irq = vio->vdev->rx_irq; in vio_ldc_alloc()
744 lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg, vio->name); in vio_ldc_alloc()
748 vio->lp = lp; in vio_ldc_alloc()
754 void vio_ldc_free(struct vio_driver_state *vio) in vio_ldc_free() argument
756 ldc_free(vio->lp); in vio_ldc_free()
757 vio->lp = NULL; in vio_ldc_free()
759 kfree(vio->desc_buf); in vio_ldc_free()
760 vio->desc_buf = NULL; in vio_ldc_free()
761 vio->desc_buf_len = 0; in vio_ldc_free()
765 void vio_port_up(struct vio_driver_state *vio) in vio_port_up() argument
770 spin_lock_irqsave(&vio->lock, flags); in vio_port_up()
772 state = ldc_state(vio->lp); in vio_port_up()
776 err = ldc_bind(vio->lp); in vio_port_up()
780 vio->name, vio->vdev->channel_id, err); in vio_port_up()
784 if (ldc_mode(vio->lp) == LDC_MODE_RAW) in vio_port_up()
785 ldc_set_state(vio->lp, LDC_STATE_CONNECTED); in vio_port_up()
787 err = ldc_connect(vio->lp); in vio_port_up()
792 vio->name, vio->vdev->channel_id, err); in vio_port_up()
798 mod_timer(&vio->timer, expires); in vio_port_up()
801 spin_unlock_irqrestore(&vio->lock, flags); in vio_port_up()
807 struct vio_driver_state *vio = from_timer(vio, t, timer); in vio_port_timer() local
809 vio_port_up(vio); in vio_port_timer()
812 int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, in vio_driver_init() argument
844 spin_lock_init(&vio->lock); in vio_driver_init()
846 vio->name = name; in vio_driver_init()
848 vio->dev_class = dev_class; in vio_driver_init()
849 vio->vdev = vdev; in vio_driver_init()
851 vio->ver_table = ver_table; in vio_driver_init()
852 vio->ver_table_entries = ver_table_size; in vio_driver_init()
854 vio->ops = ops; in vio_driver_init()
856 timer_setup(&vio->timer, vio_port_timer, 0); in vio_driver_init()