aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sparc64')
-rw-r--r--arch/sparc64/kernel/viohs.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/arch/sparc64/kernel/viohs.c b/arch/sparc64/kernel/viohs.c
index 15613add45d1..8eb381fa0f28 100644
--- a/arch/sparc64/kernel/viohs.c
+++ b/arch/sparc64/kernel/viohs.c
@@ -78,6 +78,23 @@ static int start_handshake(struct vio_driver_state *vio)
78 return 0; 78 return 0;
79} 79}
80 80
81static void flush_rx_dring(struct vio_driver_state *vio)
82{
83 struct vio_dring_state *dr;
84 u64 ident;
85
86 BUG_ON(!(vio->dr_state & VIO_DR_STATE_RXREG));
87
88 dr = &vio->drings[VIO_DRIVER_RX_RING];
89 ident = dr->ident;
90
91 BUG_ON(!vio->desc_buf);
92 kfree(vio->desc_buf);
93
94 memset(dr, 0, sizeof(*dr));
95 dr->ident = ident;
96}
97
81void vio_link_state_change(struct vio_driver_state *vio, int event) 98void vio_link_state_change(struct vio_driver_state *vio, int event)
82{ 99{
83 if (event == LDC_EVENT_UP) { 100 if (event == LDC_EVENT_UP) {
@@ -98,6 +115,16 @@ void vio_link_state_change(struct vio_driver_state *vio, int event)
98 break; 115 break;
99 } 116 }
100 start_handshake(vio); 117 start_handshake(vio);
118 } else if (event == LDC_EVENT_RESET) {
119 vio->hs_state = VIO_HS_INVALID;
120
121 if (vio->dr_state & VIO_DR_STATE_RXREG)
122 flush_rx_dring(vio);
123
124 vio->dr_state = 0x00;
125 memset(&vio->ver, 0, sizeof(vio->ver));
126
127 ldc_disconnect(vio->lp);
101 } 128 }
102} 129}
103EXPORT_SYMBOL(vio_link_state_change); 130EXPORT_SYMBOL(vio_link_state_change);
@@ -396,6 +423,8 @@ static int process_dreg_info(struct vio_driver_state *vio,
396 if (vio->dr_state & VIO_DR_STATE_RXREG) 423 if (vio->dr_state & VIO_DR_STATE_RXREG)
397 goto send_nack; 424 goto send_nack;
398 425
426 BUG_ON(vio->desc_buf);
427
399 vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC); 428 vio->desc_buf = kzalloc(pkt->descr_size, GFP_ATOMIC);
400 if (!vio->desc_buf) 429 if (!vio->desc_buf)
401 goto send_nack; 430 goto send_nack;