diff options
| author | David S. Miller <davem@sunset.davemloft.net> | 2007-07-18 03:06:22 -0400 |
|---|---|---|
| committer | David S. Miller <davem@sunset.davemloft.net> | 2007-07-18 04:20:13 -0400 |
| commit | a4cd184503f448dda346d2338aa61cb560cc1b14 (patch) | |
| tree | e9df02626899ca7ac0368ab06f6f1f13c9bf5226 | |
| parent | 8a2950cce6c8fa29bcbf6a3b33a63e0e68337f0e (diff) | |
[SPARC64]: Handle reset events in vio_link_state_change().
Signed-off-by: David S. Miller <davem@davemloft.net>
| -rw-r--r-- | arch/sparc64/kernel/viohs.c | 29 |
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 | ||
| 81 | static 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 | |||
| 81 | void vio_link_state_change(struct vio_driver_state *vio, int event) | 98 | void 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 | } |
| 103 | EXPORT_SYMBOL(vio_link_state_change); | 130 | EXPORT_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; |
