Lines Matching refs:vio
16 int vio_ldc_send(struct vio_driver_state *vio, void *data, int len) in vio_ldc_send() argument
22 err = ldc_write(vio->lp, data, len); in vio_ldc_send()
32 static int send_ctrl(struct vio_driver_state *vio, in send_ctrl() argument
35 tag->sid = vio_send_sid(vio); in send_ctrl()
36 return vio_ldc_send(vio, tag, len); in send_ctrl()
46 static int send_version(struct vio_driver_state *vio, u16 major, u16 minor) in send_version() argument
50 vio->_local_sid = (u32) sched_clock(); in send_version()
56 pkt.dev_class = vio->dev_class; in send_version()
59 major, minor, vio->dev_class); in send_version()
61 return send_ctrl(vio, &pkt.tag, sizeof(pkt)); in send_version()
64 static int start_handshake(struct vio_driver_state *vio) in start_handshake() argument
70 vio->hs_state = VIO_HS_INVALID; in start_handshake()
72 err = send_version(vio, in start_handshake()
73 vio->ver_table[0].major, in start_handshake()
74 vio->ver_table[0].minor); in start_handshake()
81 static void flush_rx_dring(struct vio_driver_state *vio) in flush_rx_dring() argument
86 BUG_ON(!(vio->dr_state & VIO_DR_STATE_RXREG)); in flush_rx_dring()
88 dr = &vio->drings[VIO_DRIVER_RX_RING]; in flush_rx_dring()
91 BUG_ON(!vio->desc_buf); in flush_rx_dring()
92 kfree(vio->desc_buf); in flush_rx_dring()
93 vio->desc_buf = NULL; in flush_rx_dring()
99 void vio_link_state_change(struct vio_driver_state *vio, int event) in vio_link_state_change() argument
102 vio->hs_state = VIO_HS_INVALID; in vio_link_state_change()
104 switch (vio->dev_class) { in vio_link_state_change()
107 vio->dr_state = (VIO_DR_STATE_TXREQ | in vio_link_state_change()
112 vio->dr_state = VIO_DR_STATE_TXREQ; in vio_link_state_change()
115 vio->dr_state = VIO_DR_STATE_RXREQ; in vio_link_state_change()
118 start_handshake(vio); in vio_link_state_change()
120 vio->hs_state = VIO_HS_INVALID; in vio_link_state_change()
122 if (vio->dr_state & VIO_DR_STATE_RXREG) in vio_link_state_change()
123 flush_rx_dring(vio); in vio_link_state_change()
125 vio->dr_state = 0x00; in vio_link_state_change()
126 memset(&vio->ver, 0, sizeof(vio->ver)); in vio_link_state_change()
128 ldc_disconnect(vio->lp); in vio_link_state_change()
133 static int handshake_failure(struct vio_driver_state *vio) in handshake_failure() argument
144 vio->dr_state &= ~(VIO_DR_STATE_TXREG | in handshake_failure()
147 dr = &vio->drings[VIO_DRIVER_RX_RING]; in handshake_failure()
150 kfree(vio->desc_buf); in handshake_failure()
151 vio->desc_buf = NULL; in handshake_failure()
152 vio->desc_buf_len = 0; in handshake_failure()
154 vio->hs_state = VIO_HS_INVALID; in handshake_failure()
159 static int process_unknown(struct vio_driver_state *vio, void *arg) in process_unknown() argument
167 vio->vdev->channel_id); in process_unknown()
169 ldc_disconnect(vio->lp); in process_unknown()
174 static int send_dreg(struct vio_driver_state *vio) in send_dreg() argument
176 struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_TX_RING]; in send_dreg()
207 return send_ctrl(vio, &u.pkt.tag, sizeof(u)); in send_dreg()
210 static int send_rdx(struct vio_driver_state *vio) in send_rdx() argument
220 return send_ctrl(vio, &pkt.tag, sizeof(pkt)); in send_rdx()
223 static int send_attr(struct vio_driver_state *vio) in send_attr() argument
225 return vio->ops->send_attr(vio); in send_attr()
228 static struct vio_version *find_by_major(struct vio_driver_state *vio, in find_by_major() argument
234 for (i = 0; i < vio->ver_table_entries; i++) { in find_by_major()
235 struct vio_version *v = &vio->ver_table[i]; in find_by_major()
244 static int process_ver_info(struct vio_driver_state *vio, in process_ver_info() argument
253 if (vio->hs_state != VIO_HS_INVALID) { in process_ver_info()
255 memset(&vio->ver, 0, sizeof(vio->ver)); in process_ver_info()
256 vio->hs_state = VIO_HS_INVALID; in process_ver_info()
259 vap = find_by_major(vio, pkt->major); in process_ver_info()
261 vio->_peer_sid = pkt->tag.sid; in process_ver_info()
268 err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_info()
275 err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_info()
287 err = send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_info()
289 vio->ver = ver; in process_ver_info()
290 vio->hs_state = VIO_HS_GOTVERS; in process_ver_info()
294 return handshake_failure(vio); in process_ver_info()
299 static int process_ver_ack(struct vio_driver_state *vio, in process_ver_ack() argument
305 if (vio->hs_state & VIO_HS_GOTVERS) { in process_ver_ack()
306 if (vio->ver.major != pkt->major || in process_ver_ack()
307 vio->ver.minor != pkt->minor) { in process_ver_ack()
309 (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_ver_ack()
310 return handshake_failure(vio); in process_ver_ack()
313 vio->ver.major = pkt->major; in process_ver_ack()
314 vio->ver.minor = pkt->minor; in process_ver_ack()
315 vio->hs_state = VIO_HS_GOTVERS; in process_ver_ack()
318 switch (vio->dev_class) { in process_ver_ack()
321 if (send_attr(vio) < 0) in process_ver_ack()
322 return handshake_failure(vio); in process_ver_ack()
332 static int process_ver_nack(struct vio_driver_state *vio, in process_ver_nack() argument
341 return handshake_failure(vio); in process_ver_nack()
342 nver = find_by_major(vio, pkt->major); in process_ver_nack()
344 return handshake_failure(vio); in process_ver_nack()
346 if (send_version(vio, nver->major, nver->minor) < 0) in process_ver_nack()
347 return handshake_failure(vio); in process_ver_nack()
352 static int process_ver(struct vio_driver_state *vio, struct vio_ver_info *pkt) in process_ver() argument
356 return process_ver_info(vio, pkt); in process_ver()
359 return process_ver_ack(vio, pkt); in process_ver()
362 return process_ver_nack(vio, pkt); in process_ver()
365 return handshake_failure(vio); in process_ver()
369 static int process_attr(struct vio_driver_state *vio, void *pkt) in process_attr() argument
373 if (!(vio->hs_state & VIO_HS_GOTVERS)) in process_attr()
374 return handshake_failure(vio); in process_attr()
376 err = vio->ops->handle_attr(vio, pkt); in process_attr()
378 return handshake_failure(vio); in process_attr()
380 vio->hs_state |= VIO_HS_GOT_ATTR; in process_attr()
382 if ((vio->dr_state & VIO_DR_STATE_TXREQ) && in process_attr()
383 !(vio->hs_state & VIO_HS_SENT_DREG)) { in process_attr()
384 if (send_dreg(vio) < 0) in process_attr()
385 return handshake_failure(vio); in process_attr()
387 vio->hs_state |= VIO_HS_SENT_DREG; in process_attr()
393 static int all_drings_registered(struct vio_driver_state *vio) in all_drings_registered() argument
397 need_rx = (vio->dr_state & VIO_DR_STATE_RXREQ); in all_drings_registered()
398 need_tx = (vio->dr_state & VIO_DR_STATE_TXREQ); in all_drings_registered()
401 !(vio->dr_state & VIO_DR_STATE_RXREG)) in all_drings_registered()
405 !(vio->dr_state & VIO_DR_STATE_TXREG)) in all_drings_registered()
411 static int process_dreg_info(struct vio_driver_state *vio, in process_dreg_info() argument
423 if (!(vio->dr_state & VIO_DR_STATE_RXREQ)) in process_dreg_info()
426 if (vio->dr_state & VIO_DR_STATE_RXREG) in process_dreg_info()
430 if (vio_version_after_eq(vio, 1, 6)) { in process_dreg_info()
436 BUG_ON(vio->desc_buf); in process_dreg_info()
438 vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); in process_dreg_info()
439 if (!vio->desc_buf) in process_dreg_info()
442 vio->desc_buf_len = pkt->descr_size; in process_dreg_info()
444 dr = &vio->drings[VIO_DRIVER_RX_RING]; in process_dreg_info()
471 if (send_ctrl(vio, &pkt->tag, len) < 0) in process_dreg_info()
474 vio->dr_state |= VIO_DR_STATE_RXREG; in process_dreg_info()
481 (void) send_ctrl(vio, &pkt->tag, sizeof(*pkt)); in process_dreg_info()
483 return handshake_failure(vio); in process_dreg_info()
486 static int process_dreg_ack(struct vio_driver_state *vio, in process_dreg_ack() argument
497 dr = &vio->drings[VIO_DRIVER_TX_RING]; in process_dreg_ack()
499 if (!(vio->dr_state & VIO_DR_STATE_TXREQ)) in process_dreg_ack()
500 return handshake_failure(vio); in process_dreg_ack()
503 vio->dr_state |= VIO_DR_STATE_TXREG; in process_dreg_ack()
505 if (all_drings_registered(vio)) { in process_dreg_ack()
506 if (send_rdx(vio) < 0) in process_dreg_ack()
507 return handshake_failure(vio); in process_dreg_ack()
508 vio->hs_state = VIO_HS_SENT_RDX; in process_dreg_ack()
513 static int process_dreg_nack(struct vio_driver_state *vio, in process_dreg_nack() argument
522 return handshake_failure(vio); in process_dreg_nack()
525 static int process_dreg(struct vio_driver_state *vio, in process_dreg() argument
528 if (!(vio->hs_state & VIO_HS_GOTVERS)) in process_dreg()
529 return handshake_failure(vio); in process_dreg()
533 return process_dreg_info(vio, pkt); in process_dreg()
536 return process_dreg_ack(vio, pkt); in process_dreg()
539 return process_dreg_nack(vio, pkt); in process_dreg()
542 return handshake_failure(vio); in process_dreg()
546 static int process_dunreg(struct vio_driver_state *vio, in process_dunreg() argument
549 struct vio_dring_state *dr = &vio->drings[VIO_DRIVER_RX_RING]; in process_dunreg()
556 vio->dr_state &= ~VIO_DR_STATE_RXREG; in process_dunreg()
560 kfree(vio->desc_buf); in process_dunreg()
561 vio->desc_buf = NULL; in process_dunreg()
562 vio->desc_buf_len = 0; in process_dunreg()
567 static int process_rdx_info(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx_info() argument
573 if (send_ctrl(vio, &pkt->tag, sizeof(*pkt)) < 0) in process_rdx_info()
574 return handshake_failure(vio); in process_rdx_info()
576 vio->hs_state |= VIO_HS_SENT_RDX_ACK; in process_rdx_info()
580 static int process_rdx_ack(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx_ack() argument
584 if (!(vio->hs_state & VIO_HS_SENT_RDX)) in process_rdx_ack()
585 return handshake_failure(vio); in process_rdx_ack()
587 vio->hs_state |= VIO_HS_GOT_RDX_ACK; in process_rdx_ack()
591 static int process_rdx_nack(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx_nack() argument
595 return handshake_failure(vio); in process_rdx_nack()
598 static int process_rdx(struct vio_driver_state *vio, struct vio_rdx *pkt) in process_rdx() argument
600 if (!all_drings_registered(vio)) in process_rdx()
601 handshake_failure(vio); in process_rdx()
605 return process_rdx_info(vio, pkt); in process_rdx()
608 return process_rdx_ack(vio, pkt); in process_rdx()
611 return process_rdx_nack(vio, pkt); in process_rdx()
614 return handshake_failure(vio); in process_rdx()
618 int vio_control_pkt_engine(struct vio_driver_state *vio, void *pkt) in vio_control_pkt_engine() argument
621 u8 prev_state = vio->hs_state; in vio_control_pkt_engine()
626 err = process_ver(vio, pkt); in vio_control_pkt_engine()
630 err = process_attr(vio, pkt); in vio_control_pkt_engine()
634 err = process_dreg(vio, pkt); in vio_control_pkt_engine()
638 err = process_dunreg(vio, pkt); in vio_control_pkt_engine()
642 err = process_rdx(vio, pkt); in vio_control_pkt_engine()
646 err = process_unknown(vio, pkt); in vio_control_pkt_engine()
650 vio->hs_state != prev_state && in vio_control_pkt_engine()
651 (vio->hs_state & VIO_HS_COMPLETE)) in vio_control_pkt_engine()
652 vio->ops->handshake_complete(vio); in vio_control_pkt_engine()
658 void vio_conn_reset(struct vio_driver_state *vio) in vio_conn_reset() argument
668 int vio_validate_sid(struct vio_driver_state *vio, struct vio_msg_tag *tp) in vio_validate_sid() argument
681 switch (vio->dev_class) { in vio_validate_sid()
686 sid = vio->_peer_sid; in vio_validate_sid()
690 sid = vio->_local_sid; in vio_validate_sid()
697 tp->sid, vio->_peer_sid, vio->_local_sid); in vio_validate_sid()
702 u32 vio_send_sid(struct vio_driver_state *vio) in vio_send_sid() argument
704 switch (vio->dev_class) { in vio_send_sid()
709 return vio->_local_sid; in vio_send_sid()
712 return vio->_peer_sid; in vio_send_sid()
717 int vio_ldc_alloc(struct vio_driver_state *vio, in vio_ldc_alloc() argument
724 cfg.tx_irq = vio->vdev->tx_irq; in vio_ldc_alloc()
725 cfg.rx_irq = vio->vdev->rx_irq; in vio_ldc_alloc()
727 lp = ldc_alloc(vio->vdev->channel_id, &cfg, event_arg, vio->name); in vio_ldc_alloc()
731 vio->lp = lp; in vio_ldc_alloc()
737 void vio_ldc_free(struct vio_driver_state *vio) in vio_ldc_free() argument
739 ldc_free(vio->lp); in vio_ldc_free()
740 vio->lp = NULL; in vio_ldc_free()
742 kfree(vio->desc_buf); in vio_ldc_free()
743 vio->desc_buf = NULL; in vio_ldc_free()
744 vio->desc_buf_len = 0; in vio_ldc_free()
748 void vio_port_up(struct vio_driver_state *vio) in vio_port_up() argument
753 spin_lock_irqsave(&vio->lock, flags); in vio_port_up()
755 state = ldc_state(vio->lp); in vio_port_up()
759 err = ldc_bind(vio->lp); in vio_port_up()
763 vio->name, vio->vdev->channel_id, err); in vio_port_up()
767 err = ldc_connect(vio->lp); in vio_port_up()
771 vio->name, vio->vdev->channel_id, err); in vio_port_up()
777 mod_timer(&vio->timer, expires); in vio_port_up()
780 spin_unlock_irqrestore(&vio->lock, flags); in vio_port_up()
786 struct vio_driver_state *vio = (struct vio_driver_state *) _arg; in vio_port_timer() local
788 vio_port_up(vio); in vio_port_timer()
791 int vio_driver_init(struct vio_driver_state *vio, struct vio_dev *vdev, in vio_driver_init() argument
818 spin_lock_init(&vio->lock); in vio_driver_init()
820 vio->name = name; in vio_driver_init()
822 vio->dev_class = dev_class; in vio_driver_init()
823 vio->vdev = vdev; in vio_driver_init()
825 vio->ver_table = ver_table; in vio_driver_init()
826 vio->ver_table_entries = ver_table_size; in vio_driver_init()
828 vio->ops = ops; in vio_driver_init()
830 setup_timer(&vio->timer, vio_port_timer, (unsigned long) vio); in vio_driver_init()