Lines Matching +full:lock +full:- +full:state
19 * - Redistributions of source code must retain the above
23 * - Redistributions in binary form must reproduce the above
38 #include <linux/dma-mapping.h>
73 index = -reason; in iwcm_reject_msg()
117 * The following services provide a mechanism for pre-allocating iwcm_work
118 * elements. The design pre-allocates them based on the cm_id type:
132 * be processed. cm_event_handler() returns -ENOMEM in this case. Its up
144 if (list_empty(&cm_id_priv->work_free_list)) in get_work()
146 work = list_first_entry(&cm_id_priv->work_free_list, struct iwcm_work, in get_work()
148 list_del_init(&work->free_list); in get_work()
154 list_add(&work->free_list, &work->cm_id->work_free_list); in put_work()
161 list_for_each_safe(e, tmp, &cm_id_priv->work_free_list) { in dealloc_work_entries()
171 BUG_ON(!list_empty(&cm_id_priv->work_free_list)); in alloc_work_entries()
172 while (count--) { in alloc_work_entries()
176 return -ENOMEM; in alloc_work_entries()
178 work->cm_id = cm_id_priv; in alloc_work_entries()
179 INIT_LIST_HEAD(&work->list); in alloc_work_entries()
194 p = kmemdup(event->private_data, event->private_data_len, GFP_ATOMIC); in copy_private_data()
196 return -ENOMEM; in copy_private_data()
197 event->private_data = p; in copy_private_data()
213 if (refcount_dec_and_test(&cm_id_priv->refcount)) { in iwcm_deref_id()
214 BUG_ON(!list_empty(&cm_id_priv->work_list)); in iwcm_deref_id()
226 refcount_inc(&cm_id_priv->refcount); in add_ref()
248 return ERR_PTR(-ENOMEM); in iw_create_cm_id()
250 cm_id_priv->state = IW_CM_STATE_IDLE; in iw_create_cm_id()
251 cm_id_priv->id.device = device; in iw_create_cm_id()
252 cm_id_priv->id.cm_handler = cm_handler; in iw_create_cm_id()
253 cm_id_priv->id.context = context; in iw_create_cm_id()
254 cm_id_priv->id.event_handler = cm_event_handler; in iw_create_cm_id()
255 cm_id_priv->id.add_ref = add_ref; in iw_create_cm_id()
256 cm_id_priv->id.rem_ref = rem_ref; in iw_create_cm_id()
257 spin_lock_init(&cm_id_priv->lock); in iw_create_cm_id()
258 refcount_set(&cm_id_priv->refcount, 1); in iw_create_cm_id()
259 init_waitqueue_head(&cm_id_priv->connect_wait); in iw_create_cm_id()
260 init_completion(&cm_id_priv->destroy_comp); in iw_create_cm_id()
261 INIT_LIST_HEAD(&cm_id_priv->work_list); in iw_create_cm_id()
262 INIT_LIST_HEAD(&cm_id_priv->work_free_list); in iw_create_cm_id()
264 return &cm_id_priv->id; in iw_create_cm_id()
274 return -EINVAL; in iwcm_modify_qp_err()
281 * This is really the RDMAC CLOSING state. It is most similar to the
282 * IB SQD QP state.
294 * CM_ID <-- CLOSING
298 * - If we are ESTABLISHED, move to CLOSING and modify the QP state
300 * - If the connection is already in the CLOSING or IDLE state, the peer is
302 * DISCONNECT event -- ignore the request and return 0
303 * - Disconnect on a listening endpoint returns -EINVAL
314 wait_event(cm_id_priv->connect_wait, in iw_cm_disconnect()
315 !test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags)); in iw_cm_disconnect()
317 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_disconnect()
318 switch (cm_id_priv->state) { in iw_cm_disconnect()
320 cm_id_priv->state = IW_CM_STATE_CLOSING; in iw_cm_disconnect()
322 /* QP could be <nul> for user-mode client */ in iw_cm_disconnect()
323 if (cm_id_priv->qp) in iw_cm_disconnect()
324 qp = cm_id_priv->qp; in iw_cm_disconnect()
326 ret = -EINVAL; in iw_cm_disconnect()
329 ret = -EINVAL; in iw_cm_disconnect()
347 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_disconnect()
367 * CM_ID <-- DESTROYING
385 wait_event(cm_id_priv->connect_wait, in destroy_cm_id()
386 !test_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags)); in destroy_cm_id()
392 set_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags); in destroy_cm_id()
394 spin_lock_irqsave(&cm_id_priv->lock, flags); in destroy_cm_id()
395 qp = cm_id_priv->qp; in destroy_cm_id()
396 cm_id_priv->qp = NULL; in destroy_cm_id()
398 switch (cm_id_priv->state) { in destroy_cm_id()
400 cm_id_priv->state = IW_CM_STATE_DESTROYING; in destroy_cm_id()
401 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in destroy_cm_id()
403 cm_id->device->ops.iw_destroy_listen(cm_id); in destroy_cm_id()
404 spin_lock_irqsave(&cm_id_priv->lock, flags); in destroy_cm_id()
407 cm_id_priv->state = IW_CM_STATE_DESTROYING; in destroy_cm_id()
408 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in destroy_cm_id()
411 spin_lock_irqsave(&cm_id_priv->lock, flags); in destroy_cm_id()
415 cm_id_priv->state = IW_CM_STATE_DESTROYING; in destroy_cm_id()
424 cm_id_priv->state = IW_CM_STATE_DESTROYING; in destroy_cm_id()
425 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in destroy_cm_id()
426 cm_id->device->ops.iw_reject(cm_id, NULL, 0); in destroy_cm_id()
427 spin_lock_irqsave(&cm_id_priv->lock, flags); in destroy_cm_id()
435 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in destroy_cm_id()
437 cm_id_priv->id.device->ops.iw_rem_ref(qp); in destroy_cm_id()
439 if (cm_id->mapped) { in destroy_cm_id()
440 iwpm_remove_mapinfo(&cm_id->local_addr, &cm_id->m_local_addr); in destroy_cm_id()
441 iwpm_remove_mapping(&cm_id->local_addr, RDMA_NL_IWCM); in destroy_cm_id()
461 * iw_cm_check_wildcard - If IP address is 0 then use original
473 if (pm_addr->ss_family == AF_INET) { in iw_cm_check_wildcard()
476 if (pm4_addr->sin_addr.s_addr == htonl(INADDR_ANY)) { in iw_cm_check_wildcard()
482 cm4_outaddr->sin_addr = cm4_addr->sin_addr; in iw_cm_check_wildcard()
487 if (ipv6_addr_type(&pm6_addr->sin6_addr) == IPV6_ADDR_ANY) { in iw_cm_check_wildcard()
493 cm6_outaddr->sin6_addr = cm6_addr->sin6_addr; in iw_cm_check_wildcard()
499 * iw_cm_map - Use portmapper to map the ports
511 const char *devname = dev_name(&cm_id->device->dev); in iw_cm_map()
512 const char *ifname = cm_id->device->iw_ifname; in iw_cm_map()
519 return -EINVAL; in iw_cm_map()
521 cm_id->m_local_addr = cm_id->local_addr; in iw_cm_map()
522 cm_id->m_remote_addr = cm_id->remote_addr; in iw_cm_map()
531 cm_id->mapped = true; in iw_cm_map()
532 pm_msg.loc_addr = cm_id->local_addr; in iw_cm_map()
533 pm_msg.rem_addr = cm_id->remote_addr; in iw_cm_map()
534 pm_msg.flags = (cm_id->device->iw_driver_flags & IW_F_NO_PORT_MAP) ? in iw_cm_map()
543 cm_id->m_local_addr = pm_msg.mapped_loc_addr; in iw_cm_map()
545 cm_id->m_remote_addr = pm_msg.mapped_rem_addr; in iw_cm_map()
547 &cm_id->remote_addr, in iw_cm_map()
548 &cm_id->m_remote_addr); in iw_cm_map()
552 return iwpm_create_mapinfo(&cm_id->local_addr, in iw_cm_map()
553 &cm_id->m_local_addr, in iw_cm_map()
558 * CM_ID <-- LISTEN
578 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_listen()
579 switch (cm_id_priv->state) { in iw_cm_listen()
581 cm_id_priv->state = IW_CM_STATE_LISTEN; in iw_cm_listen()
582 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_listen()
585 ret = cm_id->device->ops.iw_create_listen(cm_id, in iw_cm_listen()
588 cm_id_priv->state = IW_CM_STATE_IDLE; in iw_cm_listen()
589 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_listen()
592 ret = -EINVAL; in iw_cm_listen()
594 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_listen()
601 * CM_ID <-- IDLE
614 set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_reject()
616 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_reject()
617 if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) { in iw_cm_reject()
618 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_reject()
619 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_reject()
620 wake_up_all(&cm_id_priv->connect_wait); in iw_cm_reject()
621 return -EINVAL; in iw_cm_reject()
623 cm_id_priv->state = IW_CM_STATE_IDLE; in iw_cm_reject()
624 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_reject()
626 ret = cm_id->device->ops.iw_reject(cm_id, private_data, in iw_cm_reject()
629 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_reject()
630 wake_up_all(&cm_id_priv->connect_wait); in iw_cm_reject()
637 * CM_ID <-- ESTABLISHED
652 set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_accept()
654 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_accept()
655 if (cm_id_priv->state != IW_CM_STATE_CONN_RECV) { in iw_cm_accept()
656 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_accept()
657 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_accept()
658 wake_up_all(&cm_id_priv->connect_wait); in iw_cm_accept()
659 return -EINVAL; in iw_cm_accept()
662 qp = cm_id->device->ops.iw_get_qp(cm_id->device, iw_param->qpn); in iw_cm_accept()
664 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_accept()
665 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_accept()
666 wake_up_all(&cm_id_priv->connect_wait); in iw_cm_accept()
667 return -EINVAL; in iw_cm_accept()
669 cm_id->device->ops.iw_add_ref(qp); in iw_cm_accept()
670 cm_id_priv->qp = qp; in iw_cm_accept()
671 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_accept()
673 ret = cm_id->device->ops.iw_accept(cm_id, iw_param); in iw_cm_accept()
676 BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV); in iw_cm_accept()
677 cm_id_priv->state = IW_CM_STATE_IDLE; in iw_cm_accept()
678 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_accept()
679 qp = cm_id_priv->qp; in iw_cm_accept()
680 cm_id_priv->qp = NULL; in iw_cm_accept()
681 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_accept()
683 cm_id->device->ops.iw_rem_ref(qp); in iw_cm_accept()
684 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_accept()
685 wake_up_all(&cm_id_priv->connect_wait); in iw_cm_accept()
693 * Active Side: CM_ID <-- CONN_SENT
712 set_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_connect()
713 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_connect()
715 if (cm_id_priv->state != IW_CM_STATE_IDLE) { in iw_cm_connect()
716 ret = -EINVAL; in iw_cm_connect()
721 qp = cm_id->device->ops.iw_get_qp(cm_id->device, iw_param->qpn); in iw_cm_connect()
723 ret = -EINVAL; in iw_cm_connect()
726 cm_id->device->ops.iw_add_ref(qp); in iw_cm_connect()
727 cm_id_priv->qp = qp; in iw_cm_connect()
728 cm_id_priv->state = IW_CM_STATE_CONN_SENT; in iw_cm_connect()
729 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_connect()
733 ret = cm_id->device->ops.iw_connect(cm_id, iw_param); in iw_cm_connect()
737 spin_lock_irqsave(&cm_id_priv->lock, flags); in iw_cm_connect()
738 qp = cm_id_priv->qp; in iw_cm_connect()
739 cm_id_priv->qp = NULL; in iw_cm_connect()
740 cm_id_priv->state = IW_CM_STATE_IDLE; in iw_cm_connect()
742 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iw_cm_connect()
744 cm_id->device->ops.iw_rem_ref(qp); in iw_cm_connect()
745 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in iw_cm_connect()
746 wake_up_all(&cm_id_priv->connect_wait); in iw_cm_connect()
752 * Passive Side: new CM_ID <-- CONN_RECV
778 BUG_ON(iw_event->status); in cm_conn_req_handler()
780 cm_id = iw_create_cm_id(listen_id_priv->id.device, in cm_conn_req_handler()
781 listen_id_priv->id.cm_handler, in cm_conn_req_handler()
782 listen_id_priv->id.context); in cm_conn_req_handler()
787 cm_id->provider_data = iw_event->provider_data; in cm_conn_req_handler()
788 cm_id->m_local_addr = iw_event->local_addr; in cm_conn_req_handler()
789 cm_id->m_remote_addr = iw_event->remote_addr; in cm_conn_req_handler()
790 cm_id->local_addr = listen_id_priv->id.local_addr; in cm_conn_req_handler()
792 ret = iwpm_get_remote_info(&listen_id_priv->id.m_local_addr, in cm_conn_req_handler()
793 &iw_event->remote_addr, in cm_conn_req_handler()
794 &cm_id->remote_addr, in cm_conn_req_handler()
797 cm_id->remote_addr = iw_event->remote_addr; in cm_conn_req_handler()
799 iw_cm_check_wildcard(&listen_id_priv->id.m_local_addr, in cm_conn_req_handler()
800 &iw_event->local_addr, in cm_conn_req_handler()
801 &cm_id->local_addr); in cm_conn_req_handler()
802 iw_event->local_addr = cm_id->local_addr; in cm_conn_req_handler()
803 iw_event->remote_addr = cm_id->remote_addr; in cm_conn_req_handler()
807 cm_id_priv->state = IW_CM_STATE_CONN_RECV; in cm_conn_req_handler()
813 spin_lock_irqsave(&listen_id_priv->lock, flags); in cm_conn_req_handler()
814 if (listen_id_priv->state != IW_CM_STATE_LISTEN) { in cm_conn_req_handler()
815 spin_unlock_irqrestore(&listen_id_priv->lock, flags); in cm_conn_req_handler()
820 spin_unlock_irqrestore(&listen_id_priv->lock, flags); in cm_conn_req_handler()
830 ret = cm_id->cm_handler(cm_id, iw_event); in cm_conn_req_handler()
837 if (iw_event->private_data_len) in cm_conn_req_handler()
838 kfree(iw_event->private_data); in cm_conn_req_handler()
842 * Passive Side: CM_ID <-- ESTABLISHED
848 * This event can only be received in the CONN_RECV state. If the
859 spin_lock_irqsave(&cm_id_priv->lock, flags); in cm_conn_est_handler()
866 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in cm_conn_est_handler()
867 BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_RECV); in cm_conn_est_handler()
868 cm_id_priv->state = IW_CM_STATE_ESTABLISHED; in cm_conn_est_handler()
869 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in cm_conn_est_handler()
870 ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); in cm_conn_est_handler()
871 wake_up_all(&cm_id_priv->connect_wait); in cm_conn_est_handler()
877 * Active Side: CM_ID <-- ESTABLISHED
890 spin_lock_irqsave(&cm_id_priv->lock, flags); in cm_conn_rep_handler()
895 clear_bit(IWCM_F_CONNECT_WAIT, &cm_id_priv->flags); in cm_conn_rep_handler()
896 BUG_ON(cm_id_priv->state != IW_CM_STATE_CONN_SENT); in cm_conn_rep_handler()
897 if (iw_event->status == 0) { in cm_conn_rep_handler()
898 cm_id_priv->id.m_local_addr = iw_event->local_addr; in cm_conn_rep_handler()
899 cm_id_priv->id.m_remote_addr = iw_event->remote_addr; in cm_conn_rep_handler()
900 iw_event->local_addr = cm_id_priv->id.local_addr; in cm_conn_rep_handler()
901 iw_event->remote_addr = cm_id_priv->id.remote_addr; in cm_conn_rep_handler()
902 cm_id_priv->state = IW_CM_STATE_ESTABLISHED; in cm_conn_rep_handler()
905 qp = cm_id_priv->qp; in cm_conn_rep_handler()
906 cm_id_priv->qp = NULL; in cm_conn_rep_handler()
907 cm_id_priv->state = IW_CM_STATE_IDLE; in cm_conn_rep_handler()
909 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in cm_conn_rep_handler()
911 cm_id_priv->id.device->ops.iw_rem_ref(qp); in cm_conn_rep_handler()
912 ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); in cm_conn_rep_handler()
914 if (iw_event->private_data_len) in cm_conn_rep_handler()
915 kfree(iw_event->private_data); in cm_conn_rep_handler()
918 wake_up_all(&cm_id_priv->connect_wait); in cm_conn_rep_handler()
924 * CM_ID <-- CLOSING
926 * If in the ESTABLISHED state, move to CLOSING.
933 spin_lock_irqsave(&cm_id_priv->lock, flags); in cm_disconnect_handler()
934 if (cm_id_priv->state == IW_CM_STATE_ESTABLISHED) in cm_disconnect_handler()
935 cm_id_priv->state = IW_CM_STATE_CLOSING; in cm_disconnect_handler()
936 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in cm_disconnect_handler()
940 * CM_ID <-- IDLE
943 * moved by the provider to the ERR state. Disassociate the CM_ID from
946 * If in some other state, the cm_id was destroyed asynchronously.
956 spin_lock_irqsave(&cm_id_priv->lock, flags); in cm_close_handler()
957 qp = cm_id_priv->qp; in cm_close_handler()
958 cm_id_priv->qp = NULL; in cm_close_handler()
960 switch (cm_id_priv->state) { in cm_close_handler()
963 cm_id_priv->state = IW_CM_STATE_IDLE; in cm_close_handler()
971 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in cm_close_handler()
974 cm_id_priv->id.device->ops.iw_rem_ref(qp); in cm_close_handler()
976 ret = cm_id_priv->id.cm_handler(&cm_id_priv->id, iw_event); in cm_close_handler()
985 switch (iw_event->event) { in process_event()
1021 struct iwcm_id_private *cm_id_priv = work->cm_id; in cm_work_handler()
1025 spin_lock_irqsave(&cm_id_priv->lock, flags); in cm_work_handler()
1026 while (!list_empty(&cm_id_priv->work_list)) { in cm_work_handler()
1027 work = list_first_entry(&cm_id_priv->work_list, in cm_work_handler()
1029 list_del_init(&work->list); in cm_work_handler()
1030 levent = work->event; in cm_work_handler()
1032 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in cm_work_handler()
1034 if (!test_bit(IWCM_F_DROP_EVENTS, &cm_id_priv->flags)) { in cm_work_handler()
1037 WARN_ON_ONCE(destroy_cm_id(&cm_id_priv->id)); in cm_work_handler()
1042 spin_lock_irqsave(&cm_id_priv->lock, flags); in cm_work_handler()
1044 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in cm_work_handler()
1050 * the CM and/or block. Events are queued to a per-CM_ID
1059 * 0 - the event was handled.
1060 * -ENOMEM - the event was not handled due to lack of resources.
1072 spin_lock_irqsave(&cm_id_priv->lock, flags); in cm_event_handler()
1075 ret = -ENOMEM; in cm_event_handler()
1079 INIT_WORK(&work->work, cm_work_handler); in cm_event_handler()
1080 work->cm_id = cm_id_priv; in cm_event_handler()
1081 work->event = *iw_event; in cm_event_handler()
1083 if ((work->event.event == IW_CM_EVENT_CONNECT_REQUEST || in cm_event_handler()
1084 work->event.event == IW_CM_EVENT_CONNECT_REPLY) && in cm_event_handler()
1085 work->event.private_data_len) { in cm_event_handler()
1086 ret = copy_private_data(&work->event); in cm_event_handler()
1093 refcount_inc(&cm_id_priv->refcount); in cm_event_handler()
1094 list_add_tail(&work->list, &cm_id_priv->work_list); in cm_event_handler()
1095 queue_work(iwcm_wq, &work->work); in cm_event_handler()
1097 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in cm_event_handler()
1108 spin_lock_irqsave(&cm_id_priv->lock, flags); in iwcm_init_qp_init_attr()
1109 switch (cm_id_priv->state) { in iwcm_init_qp_init_attr()
1115 qp_attr->qp_access_flags = IB_ACCESS_REMOTE_WRITE| in iwcm_init_qp_init_attr()
1120 ret = -EINVAL; in iwcm_init_qp_init_attr()
1123 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iwcm_init_qp_init_attr()
1134 spin_lock_irqsave(&cm_id_priv->lock, flags); in iwcm_init_qp_rts_attr()
1135 switch (cm_id_priv->state) { in iwcm_init_qp_rts_attr()
1144 ret = -EINVAL; in iwcm_init_qp_rts_attr()
1147 spin_unlock_irqrestore(&cm_id_priv->lock, flags); in iwcm_init_qp_rts_attr()
1159 switch (qp_attr->qp_state) { in iw_cm_init_qp_attr()
1170 ret = -EINVAL; in iw_cm_init_qp_attr()
1203 return -ENOMEM; in iw_cm_init()