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 ---