Lines Matching +full:cm +full:- +full:poll +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * rio_cm - RapidIO Channelized Messaging Driver
5 * Copyright 2013-2016 Integrated Device Technology, Inc.
12 #include <linux/dma-mapping.h>
22 #include <linux/poll.h>
180 struct cm_dev *cmdev; /* associated CM device object */
203 struct cm_dev *cm; member
226 static int riocm_post_send(struct cm_dev *cm, struct rio_dev *rdev,
246 is_msg_capable(dev->src_ops, dev->dst_ops)
252 spin_lock_bh(&ch->lock); in riocm_cmp()
253 ret = (ch->state == cmp); in riocm_cmp()
254 spin_unlock_bh(&ch->lock); in riocm_cmp()
263 spin_lock_bh(&ch->lock); in riocm_cmp_exch()
264 ret = (ch->state == cmp); in riocm_cmp_exch()
266 ch->state = exch; in riocm_cmp_exch()
267 spin_unlock_bh(&ch->lock); in riocm_cmp_exch()
276 spin_lock_bh(&ch->lock); in riocm_exch()
277 old = ch->state; in riocm_exch()
278 ch->state = exch; in riocm_exch()
279 spin_unlock_bh(&ch->lock); in riocm_exch()
290 kref_get(&ch->ref); in riocm_get_channel()
297 kref_put(&ch->ref, riocm_ch_free); in riocm_put_channel()
300 static void *riocm_rx_get_msg(struct cm_dev *cm) in riocm_rx_get_msg() argument
305 msg = rio_get_inb_message(cm->mport, cmbox); in riocm_rx_get_msg()
308 if (cm->rx_buf[i] == msg) { in riocm_rx_get_msg()
309 cm->rx_buf[i] = NULL; in riocm_rx_get_msg()
310 cm->rx_slots++; in riocm_rx_get_msg()
323 * riocm_rx_fill - fills a ring of receive buffers for given cm device
324 * @cm: cm_dev object
329 static void riocm_rx_fill(struct cm_dev *cm, int nent) in riocm_rx_fill() argument
333 if (cm->rx_slots == 0) in riocm_rx_fill()
336 for (i = 0; i < RIOCM_RX_RING_SIZE && cm->rx_slots && nent; i++) { in riocm_rx_fill()
337 if (cm->rx_buf[i] == NULL) { in riocm_rx_fill()
338 cm->rx_buf[i] = kmalloc(RIO_MAX_MSG_SIZE, GFP_KERNEL); in riocm_rx_fill()
339 if (cm->rx_buf[i] == NULL) in riocm_rx_fill()
341 rio_add_inb_buffer(cm->mport, cmbox, cm->rx_buf[i]); in riocm_rx_fill()
342 cm->rx_slots--; in riocm_rx_fill()
343 nent--; in riocm_rx_fill()
349 * riocm_rx_free - frees all receive buffers associated with given cm device
350 * @cm: cm_dev object
354 static void riocm_rx_free(struct cm_dev *cm) in riocm_rx_free() argument
359 if (cm->rx_buf[i] != NULL) { in riocm_rx_free()
360 kfree(cm->rx_buf[i]); in riocm_rx_free()
361 cm->rx_buf[i] = NULL; in riocm_rx_free()
367 * riocm_req_handler - connection request handler
368 * @cm: cm_dev object
372 * -EINVAL if channel is not in correct state,
373 * -ENODEV if cannot find a channel with specified ID,
374 * -ENOMEM if unable to allocate memory to store the request
376 static int riocm_req_handler(struct cm_dev *cm, void *req_data) in riocm_req_handler() argument
383 chnum = ntohs(hh->dst_ch); in riocm_req_handler()
388 return -ENODEV; in riocm_req_handler()
390 if (ch->state != RIO_CM_LISTEN) { in riocm_req_handler()
393 return -EINVAL; in riocm_req_handler()
399 return -ENOMEM; in riocm_req_handler()
402 req->destid = ntohl(hh->bhdr.src_id); in riocm_req_handler()
403 req->chan = ntohs(hh->src_ch); in riocm_req_handler()
404 req->cmdev = cm; in riocm_req_handler()
406 spin_lock_bh(&ch->lock); in riocm_req_handler()
407 list_add_tail(&req->node, &ch->accept_queue); in riocm_req_handler()
408 spin_unlock_bh(&ch->lock); in riocm_req_handler()
409 complete(&ch->comp); in riocm_req_handler()
416 * riocm_resp_handler - response to connection request handler
420 * -EINVAL if channel is not in correct state,
421 * -ENODEV if cannot find a channel with specified ID,
429 chnum = ntohs(hh->dst_ch); in riocm_resp_handler()
432 return -ENODEV; in riocm_resp_handler()
434 if (ch->state != RIO_CM_CONNECT) { in riocm_resp_handler()
436 return -EINVAL; in riocm_resp_handler()
440 ch->rem_channel = ntohs(hh->src_ch); in riocm_resp_handler()
441 complete(&ch->comp); in riocm_resp_handler()
448 * riocm_close_handler - channel close request handler
452 * -ENODEV if cannot find a channel with specified ID,
461 riocm_debug(RX_CMD, "for ch=%d", ntohs(hh->dst_ch)); in riocm_close_handler()
464 ch = idr_find(&ch_idr, ntohs(hh->dst_ch)); in riocm_close_handler()
467 return -ENODEV; in riocm_close_handler()
469 idr_remove(&ch_idr, ch->id); in riocm_close_handler()
482 * rio_cm_handler - function that services request (non-data) packets
483 * @cm: cm_dev object
486 static void rio_cm_handler(struct cm_dev *cm, void *data) in rio_cm_handler() argument
490 if (!rio_mport_is_running(cm->mport)) in rio_cm_handler()
496 hdr->ch_op, ntohs(hdr->dst_ch), ntohs(hdr->src_ch)); in rio_cm_handler()
498 switch (hdr->ch_op) { in rio_cm_handler()
500 riocm_req_handler(cm, data); in rio_cm_handler()
517 * rio_rx_data_handler - received data packet handler
518 * @cm: cm_dev object
522 * -ENODEV if cannot find a channel with specified ID,
523 * -EIO if channel is not in CONNECTED state,
524 * -ENOMEM if channel RX queue is full (packet discarded)
526 static int rio_rx_data_handler(struct cm_dev *cm, void *buf) in rio_rx_data_handler() argument
533 riocm_debug(RX_DATA, "for ch=%d", ntohs(hdr->dst_ch)); in rio_rx_data_handler()
535 ch = riocm_get_channel(ntohs(hdr->dst_ch)); in rio_rx_data_handler()
537 /* Discard data message for non-existing channel */ in rio_rx_data_handler()
539 return -ENODEV; in rio_rx_data_handler()
543 spin_lock(&ch->lock); in rio_rx_data_handler()
545 if (ch->state != RIO_CM_CONNECTED) { in rio_rx_data_handler()
548 ch->id, ch->state); in rio_rx_data_handler()
549 spin_unlock(&ch->lock); in rio_rx_data_handler()
552 return -EIO; in rio_rx_data_handler()
555 if (ch->rx_ring.count == RIOCM_RX_RING_SIZE) { in rio_rx_data_handler()
557 riocm_debug(RX_DATA, "ch=%d is full", ch->id); in rio_rx_data_handler()
558 spin_unlock(&ch->lock); in rio_rx_data_handler()
561 return -ENOMEM; in rio_rx_data_handler()
564 ch->rx_ring.buf[ch->rx_ring.head] = buf; in rio_rx_data_handler()
565 ch->rx_ring.head++; in rio_rx_data_handler()
566 ch->rx_ring.count++; in rio_rx_data_handler()
567 ch->rx_ring.head %= RIOCM_RX_RING_SIZE; in rio_rx_data_handler()
569 complete(&ch->comp); in rio_rx_data_handler()
571 spin_unlock(&ch->lock); in rio_rx_data_handler()
578 * rio_ibmsg_handler - inbound message packet handler
582 struct cm_dev *cm = container_of(work, struct cm_dev, rx_work); in rio_ibmsg_handler() local
586 if (!rio_mport_is_running(cm->mport)) in rio_ibmsg_handler()
590 mutex_lock(&cm->rx_lock); in rio_ibmsg_handler()
591 data = riocm_rx_get_msg(cm); in rio_ibmsg_handler()
593 riocm_rx_fill(cm, 1); in rio_ibmsg_handler()
594 mutex_unlock(&cm->rx_lock); in rio_ibmsg_handler()
601 if (hdr->bhdr.type != RIO_CM_CHAN) { in rio_ibmsg_handler()
604 hdr->bhdr.type); in rio_ibmsg_handler()
610 if (hdr->ch_op == CM_DATA_MSG) in rio_ibmsg_handler()
611 rio_rx_data_handler(cm, data); in rio_ibmsg_handler()
613 rio_cm_handler(cm, data); in rio_ibmsg_handler()
620 struct cm_dev *cm = dev_id; in riocm_inb_msg_event() local
622 if (rio_mport_is_running(cm->mport) && !work_pending(&cm->rx_work)) in riocm_inb_msg_event()
623 queue_work(cm->rx_wq, &cm->rx_work); in riocm_inb_msg_event()
627 * rio_txcq_handler - TX completion handler
628 * @cm: cm_dev object
635 static void rio_txcq_handler(struct cm_dev *cm, int slot) in rio_txcq_handler() argument
644 cm->mport->id, slot, cm->tx_cnt); in rio_txcq_handler()
646 spin_lock(&cm->tx_lock); in rio_txcq_handler()
647 ack_slot = cm->tx_ack_slot; in rio_txcq_handler()
652 while (cm->tx_cnt && ((ack_slot != slot) || in rio_txcq_handler()
653 (cm->tx_cnt == RIOCM_TX_RING_SIZE))) { in rio_txcq_handler()
655 cm->tx_buf[ack_slot] = NULL; in rio_txcq_handler()
657 ack_slot &= (RIOCM_TX_RING_SIZE - 1); in rio_txcq_handler()
658 cm->tx_cnt--; in rio_txcq_handler()
661 if (cm->tx_cnt < 0 || cm->tx_cnt > RIOCM_TX_RING_SIZE) in rio_txcq_handler()
662 riocm_error("tx_cnt %d out of sync", cm->tx_cnt); in rio_txcq_handler()
664 WARN_ON((cm->tx_cnt < 0) || (cm->tx_cnt > RIOCM_TX_RING_SIZE)); in rio_txcq_handler()
666 cm->tx_ack_slot = ack_slot; in rio_txcq_handler()
671 if (!list_empty(&cm->tx_reqs) && (cm->tx_cnt < RIOCM_TX_RING_SIZE)) { in rio_txcq_handler()
675 list_for_each_entry_safe(req, _req, &cm->tx_reqs, node) { in rio_txcq_handler()
676 list_del(&req->node); in rio_txcq_handler()
677 cm->tx_buf[cm->tx_slot] = req->buffer; in rio_txcq_handler()
678 rc = rio_add_outb_message(cm->mport, req->rdev, cmbox, in rio_txcq_handler()
679 req->buffer, req->len); in rio_txcq_handler()
680 kfree(req->buffer); in rio_txcq_handler()
683 ++cm->tx_cnt; in rio_txcq_handler()
684 ++cm->tx_slot; in rio_txcq_handler()
685 cm->tx_slot &= (RIOCM_TX_RING_SIZE - 1); in rio_txcq_handler()
686 if (cm->tx_cnt == RIOCM_TX_RING_SIZE) in rio_txcq_handler()
691 spin_unlock(&cm->tx_lock); in rio_txcq_handler()
697 struct cm_dev *cm = dev_id; in riocm_outb_msg_event() local
699 if (cm && rio_mport_is_running(cm->mport)) in riocm_outb_msg_event()
700 rio_txcq_handler(cm, slot); in riocm_outb_msg_event()
703 static int riocm_queue_req(struct cm_dev *cm, struct rio_dev *rdev, in riocm_queue_req() argument
711 return -ENOMEM; in riocm_queue_req()
713 treq->rdev = rdev; in riocm_queue_req()
714 treq->buffer = buffer; in riocm_queue_req()
715 treq->len = len; in riocm_queue_req()
717 spin_lock_irqsave(&cm->tx_lock, flags); in riocm_queue_req()
718 list_add_tail(&treq->node, &cm->tx_reqs); in riocm_queue_req()
719 spin_unlock_irqrestore(&cm->tx_lock, flags); in riocm_queue_req()
724 * riocm_post_send - helper function that places packet into msg TX queue
725 * @cm: cm_dev object
733 static int riocm_post_send(struct cm_dev *cm, struct rio_dev *rdev, in riocm_post_send() argument
739 spin_lock_irqsave(&cm->tx_lock, flags); in riocm_post_send()
741 if (cm->mport == NULL) { in riocm_post_send()
742 rc = -ENODEV; in riocm_post_send()
746 if (cm->tx_cnt == RIOCM_TX_RING_SIZE) { in riocm_post_send()
748 rc = -EBUSY; in riocm_post_send()
752 cm->tx_buf[cm->tx_slot] = buffer; in riocm_post_send()
753 rc = rio_add_outb_message(cm->mport, rdev, cmbox, buffer, len); in riocm_post_send()
756 buffer, rdev->destid, cm->tx_slot, cm->tx_cnt); in riocm_post_send()
758 ++cm->tx_cnt; in riocm_post_send()
759 ++cm->tx_slot; in riocm_post_send()
760 cm->tx_slot &= (RIOCM_TX_RING_SIZE - 1); in riocm_post_send()
763 spin_unlock_irqrestore(&cm->tx_lock, flags); in riocm_post_send()
768 * riocm_ch_send - sends a data packet to a remote device
770 * @buf: pointer to a data buffer to send (including CM header)
771 * @len: length of data to transfer (including CM header)
776 * -EINVAL if one or more input parameters is/are not valid,
777 * -ENODEV if cannot find a channel with specified ID,
778 * -EAGAIN if a channel is not in CONNECTED state,
788 return -EINVAL; in riocm_ch_send()
791 return -EINVAL; /* insufficient data from user */ in riocm_ch_send()
795 riocm_error("%s(%d) ch_%d not found", current->comm, in riocm_ch_send()
797 return -ENODEV; in riocm_ch_send()
801 ret = -EAGAIN; in riocm_ch_send()
810 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_ch_send()
811 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_ch_send()
812 hdr->bhdr.src_mbox = cmbox; in riocm_ch_send()
813 hdr->bhdr.dst_mbox = cmbox; in riocm_ch_send()
814 hdr->bhdr.type = RIO_CM_CHAN; in riocm_ch_send()
815 hdr->ch_op = CM_DATA_MSG; in riocm_ch_send()
816 hdr->dst_ch = htons(ch->rem_channel); in riocm_ch_send()
817 hdr->src_ch = htons(ch->id); in riocm_ch_send()
818 hdr->msg_len = htons((u16)len); in riocm_ch_send()
821 * HW-specific add_outb_message() routine copies TX data into its own in riocm_ch_send()
826 ret = riocm_post_send(ch->cmdev, ch->rdev, buf, len); in riocm_ch_send()
828 riocm_debug(TX, "ch %d send_err=%d", ch->id, ret); in riocm_ch_send()
836 int i, ret = -EINVAL; in riocm_ch_free_rxbuf()
838 spin_lock_bh(&ch->lock); in riocm_ch_free_rxbuf()
841 if (ch->rx_ring.inuse[i] == buf) { in riocm_ch_free_rxbuf()
842 ch->rx_ring.inuse[i] = NULL; in riocm_ch_free_rxbuf()
843 ch->rx_ring.inuse_cnt--; in riocm_ch_free_rxbuf()
849 spin_unlock_bh(&ch->lock); in riocm_ch_free_rxbuf()
858 * riocm_ch_receive - fetch a data packet received for the specified channel
864 * -EAGAIN if a channel is not in CONNECTED state,
865 * -ENOMEM if in-use tracking queue is full,
866 * -ETIME if wait timeout expired,
867 * -EINTR if wait was interrupted.
876 ret = -EAGAIN; in riocm_ch_receive()
880 if (ch->rx_ring.inuse_cnt == RIOCM_RX_RING_SIZE) { in riocm_ch_receive()
884 ret = -ENOMEM; in riocm_ch_receive()
888 wret = wait_for_completion_interruptible_timeout(&ch->comp, timeout); in riocm_ch_receive()
890 riocm_debug(WAIT, "wait on %d returned %ld", ch->id, wret); in riocm_ch_receive()
893 ret = -ETIME; in riocm_ch_receive()
894 else if (wret == -ERESTARTSYS) in riocm_ch_receive()
895 ret = -EINTR; in riocm_ch_receive()
897 ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -ECONNRESET; in riocm_ch_receive()
902 spin_lock_bh(&ch->lock); in riocm_ch_receive()
904 rxmsg = ch->rx_ring.buf[ch->rx_ring.tail]; in riocm_ch_receive()
905 ch->rx_ring.buf[ch->rx_ring.tail] = NULL; in riocm_ch_receive()
906 ch->rx_ring.count--; in riocm_ch_receive()
907 ch->rx_ring.tail++; in riocm_ch_receive()
908 ch->rx_ring.tail %= RIOCM_RX_RING_SIZE; in riocm_ch_receive()
909 ret = -ENOMEM; in riocm_ch_receive()
912 if (ch->rx_ring.inuse[i] == NULL) { in riocm_ch_receive()
913 ch->rx_ring.inuse[i] = rxmsg; in riocm_ch_receive()
914 ch->rx_ring.inuse_cnt++; in riocm_ch_receive()
926 spin_unlock_bh(&ch->lock); in riocm_ch_receive()
933 * riocm_ch_connect - sends a connect request to a remote device
935 * @cm: CM device to send connect request
940 * -EINVAL if the channel is not in IDLE state,
941 * -EAGAIN if no connection request available immediately,
942 * -ETIME if ACK response timeout expired,
943 * -EINTR if wait for response was interrupted.
945 static int riocm_ch_connect(u16 loc_ch, struct cm_dev *cm, in riocm_ch_connect() argument
955 return -ENODEV; in riocm_ch_connect()
958 ret = -EINVAL; in riocm_ch_connect()
962 ch->cmdev = cm; in riocm_ch_connect()
963 ch->rdev = peer->rdev; in riocm_ch_connect()
964 ch->context = NULL; in riocm_ch_connect()
965 ch->loc_destid = cm->mport->host_deviceid; in riocm_ch_connect()
966 ch->rem_channel = rem_ch; in riocm_ch_connect()
974 ret = -ENOMEM; in riocm_ch_connect()
978 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_ch_connect()
979 hdr->bhdr.dst_id = htonl(peer->rdev->destid); in riocm_ch_connect()
980 hdr->bhdr.src_mbox = cmbox; in riocm_ch_connect()
981 hdr->bhdr.dst_mbox = cmbox; in riocm_ch_connect()
982 hdr->bhdr.type = RIO_CM_CHAN; in riocm_ch_connect()
983 hdr->ch_op = CM_CONN_REQ; in riocm_ch_connect()
984 hdr->dst_ch = htons(rem_ch); in riocm_ch_connect()
985 hdr->src_ch = htons(loc_ch); in riocm_ch_connect()
988 * HW-specific add_outb_message() routine copies TX data into its in riocm_ch_connect()
992 ret = riocm_post_send(cm, peer->rdev, hdr, sizeof(*hdr)); in riocm_ch_connect()
994 if (ret != -EBUSY) { in riocm_ch_connect()
997 ret = riocm_queue_req(cm, peer->rdev, hdr, sizeof(*hdr)); in riocm_ch_connect()
1008 wret = wait_for_completion_interruptible_timeout(&ch->comp, in riocm_ch_connect()
1010 riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret); in riocm_ch_connect()
1013 ret = -ETIME; in riocm_ch_connect()
1014 else if (wret == -ERESTARTSYS) in riocm_ch_connect()
1015 ret = -EINTR; in riocm_ch_connect()
1017 ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -1; in riocm_ch_connect()
1031 return -ENOMEM; in riocm_send_ack()
1033 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_send_ack()
1034 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_send_ack()
1035 hdr->dst_ch = htons(ch->rem_channel); in riocm_send_ack()
1036 hdr->src_ch = htons(ch->id); in riocm_send_ack()
1037 hdr->bhdr.src_mbox = cmbox; in riocm_send_ack()
1038 hdr->bhdr.dst_mbox = cmbox; in riocm_send_ack()
1039 hdr->bhdr.type = RIO_CM_CHAN; in riocm_send_ack()
1040 hdr->ch_op = CM_CONN_ACK; in riocm_send_ack()
1046 ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr)); in riocm_send_ack()
1048 if (ret == -EBUSY && !riocm_queue_req(ch->cmdev, in riocm_send_ack()
1049 ch->rdev, hdr, sizeof(*hdr))) in riocm_send_ack()
1055 ch->id, rio_name(ch->rdev), ret); in riocm_send_ack()
1060 * riocm_ch_accept - accept incoming connection request
1063 * @timeout: wait timeout (if 0 non-blocking call, do not wait if connection
1066 * Returns: pointer to new channel struct if success, or error-valued pointer:
1067 * -ENODEV - cannot find specified channel or mport,
1068 * -EINVAL - the channel is not in IDLE state,
1069 * -EAGAIN - no connection request available immediately (timeout=0),
1070 * -ENOMEM - unable to allocate new channel,
1071 * -ETIME - wait timeout expired,
1072 * -EINTR - wait was interrupted.
1087 return ERR_PTR(-EINVAL); in riocm_ch_accept()
1090 err = -EINVAL; in riocm_ch_accept()
1096 if (!try_wait_for_completion(&ch->comp)) { in riocm_ch_accept()
1097 err = -EAGAIN; in riocm_ch_accept()
1101 riocm_debug(WAIT, "on %d", ch->id); in riocm_ch_accept()
1103 wret = wait_for_completion_interruptible_timeout(&ch->comp, in riocm_ch_accept()
1106 err = -ETIME; in riocm_ch_accept()
1108 } else if (wret == -ERESTARTSYS) { in riocm_ch_accept()
1109 err = -EINTR; in riocm_ch_accept()
1114 spin_lock_bh(&ch->lock); in riocm_ch_accept()
1116 if (ch->state != RIO_CM_LISTEN) { in riocm_ch_accept()
1117 err = -ECANCELED; in riocm_ch_accept()
1118 } else if (list_empty(&ch->accept_queue)) { in riocm_ch_accept()
1120 ch->id); in riocm_ch_accept()
1121 err = -EIO; in riocm_ch_accept()
1124 spin_unlock_bh(&ch->lock); in riocm_ch_accept()
1127 riocm_debug(WAIT, "on %d returns %d", ch->id, err); in riocm_ch_accept()
1137 err = -ENOMEM; in riocm_ch_accept()
1141 spin_lock_bh(&ch->lock); in riocm_ch_accept()
1143 req = list_first_entry(&ch->accept_queue, struct conn_req, node); in riocm_ch_accept()
1144 list_del(&req->node); in riocm_ch_accept()
1145 new_ch->cmdev = ch->cmdev; in riocm_ch_accept()
1146 new_ch->loc_destid = ch->loc_destid; in riocm_ch_accept()
1147 new_ch->rem_destid = req->destid; in riocm_ch_accept()
1148 new_ch->rem_channel = req->chan; in riocm_ch_accept()
1150 spin_unlock_bh(&ch->lock); in riocm_ch_accept()
1157 list_for_each_entry(peer, &new_ch->cmdev->peers, node) { in riocm_ch_accept()
1158 if (peer->rdev->destid == new_ch->rem_destid) { in riocm_ch_accept()
1160 rio_name(peer->rdev)); in riocm_ch_accept()
1169 err = -ENODEV; in riocm_ch_accept()
1173 new_ch->rdev = peer->rdev; in riocm_ch_accept()
1174 new_ch->state = RIO_CM_CONNECTED; in riocm_ch_accept()
1175 spin_lock_init(&new_ch->lock); in riocm_ch_accept()
1180 *new_ch_id = new_ch->id; in riocm_ch_accept()
1185 idr_remove(&ch_idr, new_ch->id); in riocm_ch_accept()
1197 * riocm_ch_listen - puts a channel into LISTEN state
1201 * -EINVAL if the specified channel does not exists or
1213 return -EINVAL; in riocm_ch_listen()
1215 ret = -EINVAL; in riocm_ch_listen()
1221 * riocm_ch_bind - associate a channel object and an mport device
1227 * -ENODEV if cannot find specified mport,
1228 * -EINVAL if the specified channel does not exist or
1234 struct cm_dev *cm; in riocm_ch_bind() local
1235 int rc = -ENODEV; in riocm_ch_bind()
1241 list_for_each_entry(cm, &cm_dev_list, list) { in riocm_ch_bind()
1242 if ((cm->mport->id == mport_id) && in riocm_ch_bind()
1243 rio_mport_is_running(cm->mport)) { in riocm_ch_bind()
1254 rc = -EINVAL; in riocm_ch_bind()
1258 spin_lock_bh(&ch->lock); in riocm_ch_bind()
1259 if (ch->state != RIO_CM_IDLE) { in riocm_ch_bind()
1260 spin_unlock_bh(&ch->lock); in riocm_ch_bind()
1261 rc = -EINVAL; in riocm_ch_bind()
1265 ch->cmdev = cm; in riocm_ch_bind()
1266 ch->loc_destid = cm->mport->host_deviceid; in riocm_ch_bind()
1267 ch->context = context; in riocm_ch_bind()
1268 ch->state = RIO_CM_CHAN_BOUND; in riocm_ch_bind()
1269 spin_unlock_bh(&ch->lock); in riocm_ch_bind()
1278 * riocm_ch_alloc - channel object allocation helper routine
1282 * or error-valued pointer
1292 return ERR_PTR(-ENOMEM); in riocm_ch_alloc()
1312 return ERR_PTR(id == -ENOSPC ? -EBUSY : id); in riocm_ch_alloc()
1315 ch->id = (u16)id; in riocm_ch_alloc()
1316 ch->state = RIO_CM_IDLE; in riocm_ch_alloc()
1317 spin_lock_init(&ch->lock); in riocm_ch_alloc()
1318 INIT_LIST_HEAD(&ch->accept_queue); in riocm_ch_alloc()
1319 INIT_LIST_HEAD(&ch->ch_node); in riocm_ch_alloc()
1320 init_completion(&ch->comp); in riocm_ch_alloc()
1321 init_completion(&ch->comp_close); in riocm_ch_alloc()
1322 kref_init(&ch->ref); in riocm_ch_alloc()
1323 ch->rx_ring.head = 0; in riocm_ch_alloc()
1324 ch->rx_ring.tail = 0; in riocm_ch_alloc()
1325 ch->rx_ring.count = 0; in riocm_ch_alloc()
1326 ch->rx_ring.inuse_cnt = 0; in riocm_ch_alloc()
1332 * riocm_ch_create - creates a new channel object and allocates ID for it
1340 * allocation. Range below 'chstart' is reserved for pre-defined ID numbers.
1341 * Available channel numbers are limited by 16-bit size of channel numbers used
1345 * updated via pointer) or error-valued pointer if error.
1357 *ch_num = ch->id; in riocm_ch_create()
1363 * riocm_ch_free - channel object release routine
1371 riocm_debug(CHOP, "(ch_%d)", ch->id); in riocm_ch_free()
1373 if (ch->rx_ring.inuse_cnt) { in riocm_ch_free()
1375 i < RIOCM_RX_RING_SIZE && ch->rx_ring.inuse_cnt; i++) { in riocm_ch_free()
1376 if (ch->rx_ring.inuse[i] != NULL) { in riocm_ch_free()
1377 kfree(ch->rx_ring.inuse[i]); in riocm_ch_free()
1378 ch->rx_ring.inuse_cnt--; in riocm_ch_free()
1383 if (ch->rx_ring.count) in riocm_ch_free()
1384 for (i = 0; i < RIOCM_RX_RING_SIZE && ch->rx_ring.count; i++) { in riocm_ch_free()
1385 if (ch->rx_ring.buf[i] != NULL) { in riocm_ch_free()
1386 kfree(ch->rx_ring.buf[i]); in riocm_ch_free()
1387 ch->rx_ring.count--; in riocm_ch_free()
1391 complete(&ch->comp_close); in riocm_ch_free()
1405 return -ENOMEM; in riocm_send_close()
1407 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_send_close()
1408 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_send_close()
1409 hdr->bhdr.src_mbox = cmbox; in riocm_send_close()
1410 hdr->bhdr.dst_mbox = cmbox; in riocm_send_close()
1411 hdr->bhdr.type = RIO_CM_CHAN; in riocm_send_close()
1412 hdr->ch_op = CM_CONN_CLOSE; in riocm_send_close()
1413 hdr->dst_ch = htons(ch->rem_channel); in riocm_send_close()
1414 hdr->src_ch = htons(ch->id); in riocm_send_close()
1418 * buffer. Needs to be reviewed if switched to direct buffer mode. in riocm_send_close()
1420 ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr)); in riocm_send_close()
1422 if (ret == -EBUSY && !riocm_queue_req(ch->cmdev, ch->rdev, in riocm_send_close()
1428 riocm_error("ch(%d) send CLOSE failed (ret=%d)", ch->id, ret); in riocm_send_close()
1434 * riocm_ch_close - closes a channel object with specified ID (by local request)
1445 ch->id, current->comm, task_pid_nr(current)); in riocm_ch_close()
1451 complete_all(&ch->comp); in riocm_ch_close()
1454 wret = wait_for_completion_interruptible_timeout(&ch->comp_close, tmo); in riocm_ch_close()
1456 riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret); in riocm_ch_close()
1461 current->comm, task_pid_nr(current), ch->id); in riocm_ch_close()
1462 ret = -ETIMEDOUT; in riocm_ch_close()
1463 } else if (wret == -ERESTARTSYS) { in riocm_ch_close()
1466 current->comm, task_pid_nr(current), ch->id); in riocm_ch_close()
1467 ret = -EINTR; in riocm_ch_close()
1471 riocm_debug(CHOP, "ch_%d resources released", ch->id); in riocm_ch_close()
1474 riocm_debug(CHOP, "failed to release ch_%d resources", ch->id); in riocm_ch_close()
1481 * riocm_cdev_open() - Open character device
1486 current->comm, task_pid_nr(current), filp); in riocm_cdev_open()
1489 return -ENODEV; in riocm_cdev_open()
1495 * riocm_cdev_release() - Release character device
1504 current->comm, task_pid_nr(current), filp); in riocm_cdev_release()
1509 if (ch && ch->filp == filp) { in riocm_cdev_release()
1511 ch->id, current->comm, in riocm_cdev_release()
1513 idr_remove(&ch_idr, ch->id); in riocm_cdev_release()
1514 list_add(&ch->ch_node, &list); in riocm_cdev_release()
1521 list_del(&ch->ch_node); in riocm_cdev_release()
1530 * cm_ep_get_list_size() - Reports number of endpoints in the network
1537 struct cm_dev *cm; in cm_ep_get_list_size() local
1540 return -EFAULT; in cm_ep_get_list_size()
1542 return -EINVAL; in cm_ep_get_list_size()
1546 list_for_each_entry(cm, &cm_dev_list, list) { in cm_ep_get_list_size()
1547 if (cm->mport->id == mport_id) { in cm_ep_get_list_size()
1548 count = cm->npeers; in cm_ep_get_list_size()
1551 return -EFAULT; in cm_ep_get_list_size()
1557 return -ENODEV; in cm_ep_get_list_size()
1561 * cm_ep_get_list() - Returns list of attached endpoints
1565 struct cm_dev *cm; in cm_ep_get_list() local
1575 return -EFAULT; in cm_ep_get_list()
1578 return -EINVAL; in cm_ep_get_list()
1582 list_for_each_entry(cm, &cm_dev_list, list) in cm_ep_get_list()
1583 if (cm->mport->id == (u8)info[1]) in cm_ep_get_list()
1587 return -ENODEV; in cm_ep_get_list()
1590 nent = min(info[0], cm->npeers); in cm_ep_get_list()
1594 return -ENOMEM; in cm_ep_get_list()
1599 list_for_each_entry(peer, &cm->peers, node) { in cm_ep_get_list()
1600 *entry_ptr = (u32)peer->rdev->destid; in cm_ep_get_list()
1610 ret = -EFAULT; in cm_ep_get_list()
1617 * cm_mport_get_list() - Returns list of available local mport devices
1624 struct cm_dev *cm; in cm_mport_get_list() local
1629 return -EFAULT; in cm_mport_get_list()
1631 return -EINVAL; in cm_mport_get_list()
1634 return -ENOMEM; in cm_mport_get_list()
1639 list_for_each_entry(cm, &cm_dev_list, list) { in cm_mport_get_list()
1641 *entry_ptr = (cm->mport->id << 16) | in cm_mport_get_list()
1642 cm->mport->host_deviceid; in cm_mport_get_list()
1650 ret = -EFAULT; in cm_mport_get_list()
1657 * cm_chan_create() - Create a message exchange channel
1666 return -EFAULT; in cm_chan_create()
1669 ch_num, current->comm, task_pid_nr(current)); in cm_chan_create()
1674 ch->filp = filp; in cm_chan_create()
1676 ch_num, current->comm, task_pid_nr(current)); in cm_chan_create()
1681 * cm_chan_close() - Close channel
1692 return -EFAULT; in cm_chan_close()
1695 ch_num, current->comm, task_pid_nr(current)); in cm_chan_close()
1703 if (ch->filp != filp) { in cm_chan_close()
1705 return -EINVAL; in cm_chan_close()
1707 idr_remove(&ch_idr, ch->id); in cm_chan_close()
1714 * cm_chan_bind() - Bind channel
1722 return -EFAULT; in cm_chan_bind()
1724 return -EINVAL; in cm_chan_bind()
1730 * cm_chan_listen() - Listen on channel
1739 return -EFAULT; in cm_chan_listen()
1745 * cm_chan_accept() - Accept incoming connection
1756 return -EFAULT; in cm_chan_accept()
1759 param.ch_num, current->comm, task_pid_nr(current)); in cm_chan_accept()
1767 ch->filp = filp; in cm_chan_accept()
1770 ch->id, current->comm, task_pid_nr(current)); in cm_chan_accept()
1773 return -EFAULT; in cm_chan_accept()
1778 * cm_chan_connect() - Connect on channel
1784 struct cm_dev *cm; in cm_chan_connect() local
1786 int ret = -ENODEV; in cm_chan_connect()
1789 return -EFAULT; in cm_chan_connect()
1791 return -EINVAL; in cm_chan_connect()
1796 list_for_each_entry(cm, &cm_dev_list, list) { in cm_chan_connect()
1797 if (cm->mport->id == chan.mport_id) { in cm_chan_connect()
1806 if (chan.remote_destid >= RIO_ANY_DESTID(cm->mport->sys_size)) { in cm_chan_connect()
1807 ret = -EINVAL; in cm_chan_connect()
1812 ret = -ENODEV; in cm_chan_connect()
1814 list_for_each_entry(peer, &cm->peers, node) { in cm_chan_connect()
1815 if (peer->rdev->destid == chan.remote_destid) { in cm_chan_connect()
1826 return riocm_ch_connect(chan.id, cm, peer, chan.remote_channel); in cm_chan_connect()
1833 * cm_chan_msg_send() - Send a message through channel
1843 return -EFAULT; in cm_chan_msg_send()
1845 return -EINVAL; in cm_chan_msg_send()
1858 * cm_chan_msg_rcv() - Receive a message through channel
1870 return -EFAULT; in cm_chan_msg_rcv()
1873 return -EINVAL; in cm_chan_msg_rcv()
1877 return -ENODEV; in cm_chan_msg_rcv()
1888 ret = -EFAULT; in cm_chan_msg_rcv()
1897 * riocm_cdev_ioctl() - IOCTL requests handler
1929 return -EINVAL; in riocm_cdev_ioctl()
1940 * riocm_add_dev - add new remote RapidIO device into channel management core
1951 struct cm_dev *cm; in riocm_add_dev() local
1953 /* Check if the remote device has capabilities required to support CM */ in riocm_add_dev()
1961 return -ENOMEM; in riocm_add_dev()
1965 list_for_each_entry(cm, &cm_dev_list, list) { in riocm_add_dev()
1966 if (cm->mport == rdev->net->hport) in riocm_add_dev()
1972 return -ENODEV; in riocm_add_dev()
1975 peer->rdev = rdev; in riocm_add_dev()
1976 list_add_tail(&peer->node, &cm->peers); in riocm_add_dev()
1977 cm->npeers++; in riocm_add_dev()
1984 * riocm_remove_dev - remove remote RapidIO device from channel management core
1994 struct cm_dev *cm; in riocm_remove_dev() local
2001 /* Check if the remote device has capabilities required to support CM */ in riocm_remove_dev()
2009 list_for_each_entry(cm, &cm_dev_list, list) { in riocm_remove_dev()
2010 if (cm->mport == rdev->net->hport) { in riocm_remove_dev()
2023 list_for_each_entry(peer, &cm->peers, node) { in riocm_remove_dev()
2024 if (peer->rdev == rdev) { in riocm_remove_dev()
2027 list_del(&peer->node); in riocm_remove_dev()
2028 cm->npeers--; in riocm_remove_dev()
2045 if (ch && ch->rdev == rdev) { in riocm_remove_dev()
2046 if (atomic_read(&rdev->state) != RIO_DEVICE_SHUTDOWN) in riocm_remove_dev()
2048 idr_remove(&ch_idr, ch->id); in riocm_remove_dev()
2049 list_add(&ch->ch_node, &list); in riocm_remove_dev()
2056 list_del(&ch->ch_node); in riocm_remove_dev()
2063 * riocm_cdev_add() - Create rio_cm char device
2091 * riocm_add_mport - add new local mport device into channel management core
2094 * When a new mport device is added, CM immediately reserves inbound and
2101 struct cm_dev *cm; in riocm_add_mport() local
2104 riocm_debug(MPORT, "add mport %s", mport->name); in riocm_add_mport()
2106 cm = kzalloc(sizeof(*cm), GFP_KERNEL); in riocm_add_mport()
2107 if (!cm) in riocm_add_mport()
2108 return -ENOMEM; in riocm_add_mport()
2110 cm->mport = mport; in riocm_add_mport()
2112 rc = rio_request_outb_mbox(mport, cm, cmbox, in riocm_add_mport()
2116 cmbox, mport->name); in riocm_add_mport()
2117 kfree(cm); in riocm_add_mport()
2118 return -ENODEV; in riocm_add_mport()
2121 rc = rio_request_inb_mbox(mport, cm, cmbox, in riocm_add_mport()
2125 cmbox, mport->name); in riocm_add_mport()
2127 kfree(cm); in riocm_add_mport()
2128 return -ENODEV; in riocm_add_mport()
2131 cm->rx_wq = create_workqueue(DRV_NAME "/rxq"); in riocm_add_mport()
2132 if (!cm->rx_wq) { in riocm_add_mport()
2135 kfree(cm); in riocm_add_mport()
2136 return -ENOMEM; in riocm_add_mport()
2144 cm->rx_buf[i] = NULL; in riocm_add_mport()
2146 cm->rx_slots = RIOCM_RX_RING_SIZE; in riocm_add_mport()
2147 mutex_init(&cm->rx_lock); in riocm_add_mport()
2148 riocm_rx_fill(cm, RIOCM_RX_RING_SIZE); in riocm_add_mport()
2149 INIT_WORK(&cm->rx_work, rio_ibmsg_handler); in riocm_add_mport()
2151 cm->tx_slot = 0; in riocm_add_mport()
2152 cm->tx_cnt = 0; in riocm_add_mport()
2153 cm->tx_ack_slot = 0; in riocm_add_mport()
2154 spin_lock_init(&cm->tx_lock); in riocm_add_mport()
2156 INIT_LIST_HEAD(&cm->peers); in riocm_add_mport()
2157 cm->npeers = 0; in riocm_add_mport()
2158 INIT_LIST_HEAD(&cm->tx_reqs); in riocm_add_mport()
2161 list_add_tail(&cm->list, &cm_dev_list); in riocm_add_mport()
2168 * riocm_remove_mport - remove local mport device from channel management core
2173 * registered with the CM core.
2178 struct cm_dev *cm; in riocm_remove_mport() local
2185 riocm_debug(MPORT, "%s", mport->name); in riocm_remove_mport()
2189 list_for_each_entry(cm, &cm_dev_list, list) { in riocm_remove_mport()
2190 if (cm->mport == mport) { in riocm_remove_mport()
2191 list_del(&cm->list); in riocm_remove_mport()
2200 flush_workqueue(cm->rx_wq); in riocm_remove_mport()
2201 destroy_workqueue(cm->rx_wq); in riocm_remove_mport()
2206 if (ch->cmdev == cm) { in riocm_remove_mport()
2208 mport->name, ch->id); in riocm_remove_mport()
2209 idr_remove(&ch_idr, ch->id); in riocm_remove_mport()
2210 list_add(&ch->ch_node, &list); in riocm_remove_mport()
2217 list_del(&ch->ch_node); in riocm_remove_mport()
2226 if (!list_empty(&cm->peers)) in riocm_remove_mport()
2228 list_for_each_entry_safe(peer, temp, &cm->peers, node) { in riocm_remove_mport()
2229 riocm_debug(RDEV, "removing peer %s", rio_name(peer->rdev)); in riocm_remove_mport()
2230 list_del(&peer->node); in riocm_remove_mport()
2234 riocm_rx_free(cm); in riocm_remove_mport()
2235 kfree(cm); in riocm_remove_mport()
2236 riocm_debug(MPORT, "%s done", mport->name); in riocm_remove_mport()
2257 if (ch->state == RIO_CM_CONNECTED) { in rio_cm_shutdown()
2258 riocm_debug(EXIT, "close ch %d", ch->id); in rio_cm_shutdown()
2259 idr_remove(&ch_idr, ch->id); in rio_cm_shutdown()
2260 list_add(&ch->ch_node, &list); in rio_cm_shutdown()
2344 ret = -ENODEV; in riocm_init()