aboutsummaryrefslogtreecommitdiffstats
path: root/net/iucv
diff options
context:
space:
mode:
Diffstat (limited to 'net/iucv')
-rw-r--r--net/iucv/af_iucv.c19
1 files changed, 18 insertions, 1 deletions
diff --git a/net/iucv/af_iucv.c b/net/iucv/af_iucv.c
index 49e786535dc8..6cf02b41ef95 100644
--- a/net/iucv/af_iucv.c
+++ b/net/iucv/af_iucv.c
@@ -54,6 +54,7 @@ static void iucv_callback_connack(struct iucv_path *, u8 ipuser[16]);
54static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8], 54static int iucv_callback_connreq(struct iucv_path *, u8 ipvmid[8],
55 u8 ipuser[16]); 55 u8 ipuser[16]);
56static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]); 56static void iucv_callback_connrej(struct iucv_path *, u8 ipuser[16]);
57static void iucv_callback_shutdown(struct iucv_path *, u8 ipuser[16]);
57 58
58static struct iucv_sock_list iucv_sk_list = { 59static struct iucv_sock_list iucv_sk_list = {
59 .lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock), 60 .lock = __RW_LOCK_UNLOCKED(iucv_sk_list.lock),
@@ -65,7 +66,8 @@ static struct iucv_handler af_iucv_handler = {
65 .path_complete = iucv_callback_connack, 66 .path_complete = iucv_callback_connack,
66 .path_severed = iucv_callback_connrej, 67 .path_severed = iucv_callback_connrej,
67 .message_pending = iucv_callback_rx, 68 .message_pending = iucv_callback_rx,
68 .message_complete = iucv_callback_txdone 69 .message_complete = iucv_callback_txdone,
70 .path_quiesced = iucv_callback_shutdown,
69}; 71};
70 72
71static inline void high_nmcpy(unsigned char *dst, char *src) 73static inline void high_nmcpy(unsigned char *dst, char *src)
@@ -1196,6 +1198,21 @@ static void iucv_callback_connrej(struct iucv_path *path, u8 ipuser[16])
1196 sk->sk_state_change(sk); 1198 sk->sk_state_change(sk);
1197} 1199}
1198 1200
1201/* called if the other communication side shuts down its RECV direction;
1202 * in turn, the callback sets SEND_SHUTDOWN to disable sending of data.
1203 */
1204static void iucv_callback_shutdown(struct iucv_path *path, u8 ipuser[16])
1205{
1206 struct sock *sk = path->private;
1207
1208 bh_lock_sock(sk);
1209 if (sk->sk_state != IUCV_CLOSED) {
1210 sk->sk_shutdown |= SEND_SHUTDOWN;
1211 sk->sk_state_change(sk);
1212 }
1213 bh_unlock_sock(sk);
1214}
1215
1199static struct proto_ops iucv_sock_ops = { 1216static struct proto_ops iucv_sock_ops = {
1200 .family = PF_IUCV, 1217 .family = PF_IUCV,
1201 .owner = THIS_MODULE, 1218 .owner = THIS_MODULE,