af_iucv.c (ef6af7bdb9e6c14eae8dc5fe852aefe1e089c85c) | af_iucv.c (80bc97aa0aaab974bbbfb99a78d7515414004616) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * IUCV protocol stack for Linux on zSeries 4 * 5 * Copyright IBM Corp. 2006, 2009 6 * 7 * Author(s): Jennifer Hunt <jenhunt@us.ibm.com> 8 * Hendrik Brueckner <brueckner@linux.vnet.ibm.com> --- 75 unchanged lines hidden (view full) --- 84 __ret; \ 85}) 86 87static struct sock *iucv_accept_dequeue(struct sock *parent, 88 struct socket *newsock); 89static void iucv_sock_kill(struct sock *sk); 90static void iucv_sock_close(struct sock *sk); 91 | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * IUCV protocol stack for Linux on zSeries 4 * 5 * Copyright IBM Corp. 2006, 2009 6 * 7 * Author(s): Jennifer Hunt <jenhunt@us.ibm.com> 8 * Hendrik Brueckner <brueckner@linux.vnet.ibm.com> --- 75 unchanged lines hidden (view full) --- 84 __ret; \ 85}) 86 87static struct sock *iucv_accept_dequeue(struct sock *parent, 88 struct socket *newsock); 89static void iucv_sock_kill(struct sock *sk); 90static void iucv_sock_close(struct sock *sk); 91 |
92static void afiucv_hs_callback_txnotify(struct sk_buff *, enum iucv_tx_notify); | 92static void afiucv_hs_callback_txnotify(struct sock *sk, enum iucv_tx_notify); |
93 94/* Call Back functions */ 95static void iucv_callback_rx(struct iucv_path *, struct iucv_message *); 96static void iucv_callback_txdone(struct iucv_path *, struct iucv_message *); 97static void iucv_callback_connack(struct iucv_path *, u8 *); 98static int iucv_callback_connreq(struct iucv_path *, u8 *, u8 *); 99static void iucv_callback_connrej(struct iucv_path *, u8 *); 100static void iucv_callback_shutdown(struct iucv_path *, u8 *); --- 105 unchanged lines hidden (view full) --- 206/** 207 * afiucv_hs_send() - send a message through HiperSockets transport 208 */ 209static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock, 210 struct sk_buff *skb, u8 flags) 211{ 212 struct iucv_sock *iucv = iucv_sk(sock); 213 struct af_iucv_trans_hdr *phs_hdr; | 93 94/* Call Back functions */ 95static void iucv_callback_rx(struct iucv_path *, struct iucv_message *); 96static void iucv_callback_txdone(struct iucv_path *, struct iucv_message *); 97static void iucv_callback_connack(struct iucv_path *, u8 *); 98static int iucv_callback_connreq(struct iucv_path *, u8 *, u8 *); 99static void iucv_callback_connrej(struct iucv_path *, u8 *); 100static void iucv_callback_shutdown(struct iucv_path *, u8 *); --- 105 unchanged lines hidden (view full) --- 206/** 207 * afiucv_hs_send() - send a message through HiperSockets transport 208 */ 209static int afiucv_hs_send(struct iucv_message *imsg, struct sock *sock, 210 struct sk_buff *skb, u8 flags) 211{ 212 struct iucv_sock *iucv = iucv_sk(sock); 213 struct af_iucv_trans_hdr *phs_hdr; |
214 struct sk_buff *nskb; | |
215 int err, confirm_recv = 0; 216 217 phs_hdr = skb_push(skb, sizeof(*phs_hdr)); 218 memset(phs_hdr, 0, sizeof(*phs_hdr)); 219 skb_reset_network_header(skb); 220 221 phs_hdr->magic = ETH_P_AF_IUCV; 222 phs_hdr->version = 1; --- 33 unchanged lines hidden (view full) --- 256 if (sock->sk_type == SOCK_SEQPACKET) { 257 err = -EMSGSIZE; 258 goto err_free; 259 } 260 skb_trim(skb, skb->dev->mtu); 261 } 262 skb->protocol = cpu_to_be16(ETH_P_AF_IUCV); 263 | 214 int err, confirm_recv = 0; 215 216 phs_hdr = skb_push(skb, sizeof(*phs_hdr)); 217 memset(phs_hdr, 0, sizeof(*phs_hdr)); 218 skb_reset_network_header(skb); 219 220 phs_hdr->magic = ETH_P_AF_IUCV; 221 phs_hdr->version = 1; --- 33 unchanged lines hidden (view full) --- 255 if (sock->sk_type == SOCK_SEQPACKET) { 256 err = -EMSGSIZE; 257 goto err_free; 258 } 259 skb_trim(skb, skb->dev->mtu); 260 } 261 skb->protocol = cpu_to_be16(ETH_P_AF_IUCV); 262 |
264 __skb_header_release(skb); 265 nskb = skb_clone(skb, GFP_ATOMIC); 266 if (!nskb) { 267 err = -ENOMEM; 268 goto err_free; 269 } 270 271 skb_queue_tail(&iucv->send_skb_q, nskb); | |
272 atomic_inc(&iucv->skbs_in_xmit); 273 err = dev_queue_xmit(skb); 274 if (net_xmit_eval(err)) { 275 atomic_dec(&iucv->skbs_in_xmit); | 263 atomic_inc(&iucv->skbs_in_xmit); 264 err = dev_queue_xmit(skb); 265 if (net_xmit_eval(err)) { 266 atomic_dec(&iucv->skbs_in_xmit); |
276 skb_unlink(nskb, &iucv->send_skb_q); 277 kfree_skb(nskb); | |
278 } else { 279 atomic_sub(confirm_recv, &iucv->msg_recv); 280 WARN_ON(atomic_read(&iucv->msg_recv) < 0); 281 } 282 return net_xmit_eval(err); 283 284err_free: 285 kfree_skb(skb); --- 1855 unchanged lines hidden (view full) --- 2141 2142 return err; 2143} 2144 2145/** 2146 * afiucv_hs_callback_txnotify() - handle send notifcations from HiperSockets 2147 * transport 2148 **/ | 267 } else { 268 atomic_sub(confirm_recv, &iucv->msg_recv); 269 WARN_ON(atomic_read(&iucv->msg_recv) < 0); 270 } 271 return net_xmit_eval(err); 272 273err_free: 274 kfree_skb(skb); --- 1855 unchanged lines hidden (view full) --- 2130 2131 return err; 2132} 2133 2134/** 2135 * afiucv_hs_callback_txnotify() - handle send notifcations from HiperSockets 2136 * transport 2137 **/ |
2149static void afiucv_hs_callback_txnotify(struct sk_buff *skb, 2150 enum iucv_tx_notify n) | 2138static void afiucv_hs_callback_txnotify(struct sock *sk, enum iucv_tx_notify n) |
2151{ | 2139{ |
2152 struct iucv_sock *iucv = iucv_sk(skb->sk); 2153 struct sock *sk = skb->sk; 2154 struct sk_buff_head *list; 2155 struct sk_buff *list_skb; 2156 struct sk_buff *nskb; 2157 unsigned long flags; | 2140 struct iucv_sock *iucv = iucv_sk(sk); |
2158 2159 if (sock_flag(sk, SOCK_ZAPPED)) 2160 return; 2161 | 2141 2142 if (sock_flag(sk, SOCK_ZAPPED)) 2143 return; 2144 |
2162 list = &iucv->send_skb_q; 2163 spin_lock_irqsave(&list->lock, flags); 2164 skb_queue_walk_safe(list, list_skb, nskb) { 2165 if (skb_shinfo(list_skb) == skb_shinfo(skb)) { 2166 switch (n) { 2167 case TX_NOTIFY_OK: 2168 atomic_dec(&iucv->skbs_in_xmit); 2169 __skb_unlink(list_skb, list); 2170 kfree_skb(list_skb); 2171 iucv_sock_wake_msglim(sk); 2172 break; 2173 case TX_NOTIFY_PENDING: 2174 atomic_inc(&iucv->pendings); 2175 break; 2176 case TX_NOTIFY_DELAYED_OK: 2177 atomic_dec(&iucv->skbs_in_xmit); 2178 __skb_unlink(list_skb, list); 2179 atomic_dec(&iucv->pendings); 2180 if (atomic_read(&iucv->pendings) <= 0) 2181 iucv_sock_wake_msglim(sk); 2182 kfree_skb(list_skb); 2183 break; 2184 case TX_NOTIFY_UNREACHABLE: 2185 case TX_NOTIFY_DELAYED_UNREACHABLE: 2186 case TX_NOTIFY_TPQFULL: /* not yet used */ 2187 case TX_NOTIFY_GENERALERROR: 2188 case TX_NOTIFY_DELAYED_GENERALERROR: 2189 atomic_dec(&iucv->skbs_in_xmit); 2190 __skb_unlink(list_skb, list); 2191 kfree_skb(list_skb); 2192 if (sk->sk_state == IUCV_CONNECTED) { 2193 sk->sk_state = IUCV_DISCONN; 2194 sk->sk_state_change(sk); 2195 } 2196 break; 2197 } 2198 break; | 2145 switch (n) { 2146 case TX_NOTIFY_OK: 2147 atomic_dec(&iucv->skbs_in_xmit); 2148 iucv_sock_wake_msglim(sk); 2149 break; 2150 case TX_NOTIFY_PENDING: 2151 atomic_inc(&iucv->pendings); 2152 break; 2153 case TX_NOTIFY_DELAYED_OK: 2154 atomic_dec(&iucv->skbs_in_xmit); 2155 if (atomic_dec_return(&iucv->pendings) <= 0) 2156 iucv_sock_wake_msglim(sk); 2157 break; 2158 default: 2159 atomic_dec(&iucv->skbs_in_xmit); 2160 if (sk->sk_state == IUCV_CONNECTED) { 2161 sk->sk_state = IUCV_DISCONN; 2162 sk->sk_state_change(sk); |
2199 } 2200 } | 2163 } 2164 } |
2201 spin_unlock_irqrestore(&list->lock, flags); | |
2202 2203 if (sk->sk_state == IUCV_CLOSING) { 2204 if (atomic_read(&iucv->skbs_in_xmit) == 0) { 2205 sk->sk_state = IUCV_CLOSED; 2206 sk->sk_state_change(sk); 2207 } 2208 } | 2165 2166 if (sk->sk_state == IUCV_CLOSING) { 2167 if (atomic_read(&iucv->skbs_in_xmit) == 0) { 2168 sk->sk_state = IUCV_CLOSED; 2169 sk->sk_state_change(sk); 2170 } 2171 } |
2209 | |
2210} 2211 2212/* 2213 * afiucv_netdev_event: handle netdev notifier chain events 2214 */ 2215static int afiucv_netdev_event(struct notifier_block *this, 2216 unsigned long event, void *ptr) 2217{ --- 176 unchanged lines hidden --- | 2172} 2173 2174/* 2175 * afiucv_netdev_event: handle netdev notifier chain events 2176 */ 2177static int afiucv_netdev_event(struct notifier_block *this, 2178 unsigned long event, void *ptr) 2179{ --- 176 unchanged lines hidden --- |