Lines Matching full:ch

228 static int riocm_ch_close(struct rio_channel *ch);
250 static int riocm_cmp(struct rio_channel *ch, enum rio_cm_state cmp) in riocm_cmp() argument
254 spin_lock_bh(&ch->lock); in riocm_cmp()
255 ret = (ch->state == cmp); in riocm_cmp()
256 spin_unlock_bh(&ch->lock); in riocm_cmp()
260 static int riocm_cmp_exch(struct rio_channel *ch, in riocm_cmp_exch() argument
265 spin_lock_bh(&ch->lock); in riocm_cmp_exch()
266 ret = (ch->state == cmp); in riocm_cmp_exch()
268 ch->state = exch; in riocm_cmp_exch()
269 spin_unlock_bh(&ch->lock); in riocm_cmp_exch()
273 static enum rio_cm_state riocm_exch(struct rio_channel *ch, in riocm_exch() argument
278 spin_lock_bh(&ch->lock); in riocm_exch()
279 old = ch->state; in riocm_exch()
280 ch->state = exch; in riocm_exch()
281 spin_unlock_bh(&ch->lock); in riocm_exch()
287 struct rio_channel *ch; in riocm_get_channel() local
290 ch = idr_find(&ch_idr, nr); in riocm_get_channel()
291 if (ch) in riocm_get_channel()
292 kref_get(&ch->ref); in riocm_get_channel()
294 return ch; in riocm_get_channel()
297 static void riocm_put_channel(struct rio_channel *ch) in riocm_put_channel() argument
299 kref_put(&ch->ref, riocm_ch_free); in riocm_put_channel()
380 struct rio_channel *ch; in riocm_req_handler() local
387 ch = riocm_get_channel(chnum); in riocm_req_handler()
389 if (!ch) in riocm_req_handler()
392 if (ch->state != RIO_CM_LISTEN) { in riocm_req_handler()
394 riocm_put_channel(ch); in riocm_req_handler()
400 riocm_put_channel(ch); in riocm_req_handler()
408 spin_lock_bh(&ch->lock); in riocm_req_handler()
409 list_add_tail(&req->node, &ch->accept_queue); in riocm_req_handler()
410 spin_unlock_bh(&ch->lock); in riocm_req_handler()
411 complete(&ch->comp); in riocm_req_handler()
412 riocm_put_channel(ch); in riocm_req_handler()
427 struct rio_channel *ch; in riocm_resp_handler() local
432 ch = riocm_get_channel(chnum); in riocm_resp_handler()
433 if (!ch) in riocm_resp_handler()
436 if (ch->state != RIO_CM_CONNECT) { in riocm_resp_handler()
437 riocm_put_channel(ch); in riocm_resp_handler()
441 riocm_exch(ch, RIO_CM_CONNECTED); in riocm_resp_handler()
442 ch->rem_channel = ntohs(hh->src_ch); in riocm_resp_handler()
443 complete(&ch->comp); in riocm_resp_handler()
444 riocm_put_channel(ch); in riocm_resp_handler()
459 struct rio_channel *ch; in riocm_close_handler() local
463 riocm_debug(RX_CMD, "for ch=%d", ntohs(hh->dst_ch)); in riocm_close_handler()
466 ch = idr_find(&ch_idr, ntohs(hh->dst_ch)); in riocm_close_handler()
467 if (!ch) { in riocm_close_handler()
471 idr_remove(&ch_idr, ch->id); in riocm_close_handler()
474 riocm_exch(ch, RIO_CM_DISCONNECT); in riocm_close_handler()
476 ret = riocm_ch_close(ch); in riocm_close_handler()
497 riocm_debug(RX_CMD, "OP=%x for ch=%d from %d", in rio_cm_handler()
531 struct rio_channel *ch; in rio_rx_data_handler() local
535 riocm_debug(RX_DATA, "for ch=%d", ntohs(hdr->dst_ch)); in rio_rx_data_handler()
537 ch = riocm_get_channel(ntohs(hdr->dst_ch)); in rio_rx_data_handler()
538 if (!ch) { in rio_rx_data_handler()
545 spin_lock(&ch->lock); in rio_rx_data_handler()
547 if (ch->state != RIO_CM_CONNECTED) { in rio_rx_data_handler()
549 riocm_debug(RX_DATA, "ch=%d is in wrong state=%d", in rio_rx_data_handler()
550 ch->id, ch->state); in rio_rx_data_handler()
551 spin_unlock(&ch->lock); in rio_rx_data_handler()
553 riocm_put_channel(ch); in rio_rx_data_handler()
557 if (ch->rx_ring.count == RIOCM_RX_RING_SIZE) { in rio_rx_data_handler()
559 riocm_debug(RX_DATA, "ch=%d is full", ch->id); in rio_rx_data_handler()
560 spin_unlock(&ch->lock); in rio_rx_data_handler()
562 riocm_put_channel(ch); in rio_rx_data_handler()
566 ch->rx_ring.buf[ch->rx_ring.head] = buf; in rio_rx_data_handler()
567 ch->rx_ring.head++; in rio_rx_data_handler()
568 ch->rx_ring.count++; in rio_rx_data_handler()
569 ch->rx_ring.head %= RIOCM_RX_RING_SIZE; in rio_rx_data_handler()
571 complete(&ch->comp); in rio_rx_data_handler()
573 spin_unlock(&ch->lock); in rio_rx_data_handler()
574 riocm_put_channel(ch); in rio_rx_data_handler()
785 struct rio_channel *ch; in riocm_ch_send() local
792 ch = riocm_get_channel(ch_id); in riocm_ch_send()
793 if (!ch) { in riocm_ch_send()
799 if (!riocm_cmp(ch, RIO_CM_CONNECTED)) { in riocm_ch_send()
809 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_ch_send()
810 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_ch_send()
815 hdr->dst_ch = htons(ch->rem_channel); in riocm_ch_send()
816 hdr->src_ch = htons(ch->id); in riocm_ch_send()
825 ret = riocm_post_send(ch->cmdev, ch->rdev, buf, len); in riocm_ch_send()
827 riocm_debug(TX, "ch %d send_err=%d", ch->id, ret); in riocm_ch_send()
829 riocm_put_channel(ch); in riocm_ch_send()
833 static int riocm_ch_free_rxbuf(struct rio_channel *ch, void *buf) in riocm_ch_free_rxbuf() argument
837 spin_lock_bh(&ch->lock); in riocm_ch_free_rxbuf()
840 if (ch->rx_ring.inuse[i] == buf) { in riocm_ch_free_rxbuf()
841 ch->rx_ring.inuse[i] = NULL; in riocm_ch_free_rxbuf()
842 ch->rx_ring.inuse_cnt--; in riocm_ch_free_rxbuf()
848 spin_unlock_bh(&ch->lock); in riocm_ch_free_rxbuf()
858 * @ch: local channel ID
868 static int riocm_ch_receive(struct rio_channel *ch, void **buf, long timeout) in riocm_ch_receive() argument
874 if (!riocm_cmp(ch, RIO_CM_CONNECTED)) { in riocm_ch_receive()
879 if (ch->rx_ring.inuse_cnt == RIOCM_RX_RING_SIZE) { in riocm_ch_receive()
887 wret = wait_for_completion_interruptible_timeout(&ch->comp, timeout); in riocm_ch_receive()
889 riocm_debug(WAIT, "wait on %d returned %ld", ch->id, wret); in riocm_ch_receive()
896 ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -ECONNRESET; in riocm_ch_receive()
901 spin_lock_bh(&ch->lock); in riocm_ch_receive()
903 rxmsg = ch->rx_ring.buf[ch->rx_ring.tail]; in riocm_ch_receive()
904 ch->rx_ring.buf[ch->rx_ring.tail] = NULL; in riocm_ch_receive()
905 ch->rx_ring.count--; in riocm_ch_receive()
906 ch->rx_ring.tail++; in riocm_ch_receive()
907 ch->rx_ring.tail %= RIOCM_RX_RING_SIZE; in riocm_ch_receive()
911 if (ch->rx_ring.inuse[i] == NULL) { in riocm_ch_receive()
912 ch->rx_ring.inuse[i] = rxmsg; in riocm_ch_receive()
913 ch->rx_ring.inuse_cnt++; in riocm_ch_receive()
925 spin_unlock_bh(&ch->lock); in riocm_ch_receive()
947 struct rio_channel *ch = NULL; in riocm_ch_connect() local
952 ch = riocm_get_channel(loc_ch); in riocm_ch_connect()
953 if (!ch) in riocm_ch_connect()
956 if (!riocm_cmp_exch(ch, RIO_CM_IDLE, RIO_CM_CONNECT)) { in riocm_ch_connect()
961 ch->cmdev = cm; in riocm_ch_connect()
962 ch->rdev = peer->rdev; in riocm_ch_connect()
963 ch->context = NULL; in riocm_ch_connect()
964 ch->loc_destid = cm->mport->host_deviceid; in riocm_ch_connect()
965 ch->rem_channel = rem_ch; in riocm_ch_connect()
977 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_ch_connect()
1002 riocm_cmp_exch(ch, RIO_CM_CONNECT, RIO_CM_IDLE); in riocm_ch_connect()
1007 wret = wait_for_completion_interruptible_timeout(&ch->comp, in riocm_ch_connect()
1009 riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret); in riocm_ch_connect()
1016 ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -1; in riocm_ch_connect()
1019 riocm_put_channel(ch); in riocm_ch_connect()
1023 static int riocm_send_ack(struct rio_channel *ch) in riocm_send_ack() argument
1032 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_send_ack()
1033 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_send_ack()
1034 hdr->dst_ch = htons(ch->rem_channel); in riocm_send_ack()
1035 hdr->src_ch = htons(ch->id); in riocm_send_ack()
1045 ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr)); in riocm_send_ack()
1047 if (ret == -EBUSY && !riocm_queue_req(ch->cmdev, in riocm_send_ack()
1048 ch->rdev, hdr, sizeof(*hdr))) in riocm_send_ack()
1054 ch->id, rio_name(ch->rdev), ret); in riocm_send_ack()
1076 struct rio_channel *ch; in riocm_ch_accept() local
1084 ch = riocm_get_channel(ch_id); in riocm_ch_accept()
1085 if (!ch) in riocm_ch_accept()
1088 if (!riocm_cmp(ch, RIO_CM_LISTEN)) { in riocm_ch_accept()
1095 if (!try_wait_for_completion(&ch->comp)) { in riocm_ch_accept()
1100 riocm_debug(WAIT, "on %d", ch->id); in riocm_ch_accept()
1102 wret = wait_for_completion_interruptible_timeout(&ch->comp, in riocm_ch_accept()
1113 spin_lock_bh(&ch->lock); in riocm_ch_accept()
1115 if (ch->state != RIO_CM_LISTEN) { in riocm_ch_accept()
1117 } else if (list_empty(&ch->accept_queue)) { in riocm_ch_accept()
1119 ch->id); in riocm_ch_accept()
1123 spin_unlock_bh(&ch->lock); in riocm_ch_accept()
1126 riocm_debug(WAIT, "on %d returns %d", ch->id, err); in riocm_ch_accept()
1140 spin_lock_bh(&ch->lock); in riocm_ch_accept()
1142 req = list_first_entry(&ch->accept_queue, struct conn_req, node); in riocm_ch_accept()
1144 new_ch->cmdev = ch->cmdev; in riocm_ch_accept()
1145 new_ch->loc_destid = ch->loc_destid; in riocm_ch_accept()
1149 spin_unlock_bh(&ch->lock); in riocm_ch_accept()
1150 riocm_put_channel(ch); in riocm_ch_accept()
1151 ch = NULL; in riocm_ch_accept()
1189 if (ch) in riocm_ch_accept()
1190 riocm_put_channel(ch); in riocm_ch_accept()
1205 struct rio_channel *ch = NULL; in riocm_ch_listen() local
1210 ch = riocm_get_channel(ch_id); in riocm_ch_listen()
1211 if (!ch) in riocm_ch_listen()
1213 if (!riocm_cmp_exch(ch, RIO_CM_CHAN_BOUND, RIO_CM_LISTEN)) in riocm_ch_listen()
1215 riocm_put_channel(ch); in riocm_ch_listen()
1232 struct rio_channel *ch = NULL; in riocm_ch_bind() local
1251 ch = riocm_get_channel(ch_id); in riocm_ch_bind()
1252 if (!ch) { in riocm_ch_bind()
1257 spin_lock_bh(&ch->lock); in riocm_ch_bind()
1258 if (ch->state != RIO_CM_IDLE) { in riocm_ch_bind()
1259 spin_unlock_bh(&ch->lock); in riocm_ch_bind()
1264 ch->cmdev = cm; in riocm_ch_bind()
1265 ch->loc_destid = cm->mport->host_deviceid; in riocm_ch_bind()
1266 ch->context = context; in riocm_ch_bind()
1267 ch->state = RIO_CM_CHAN_BOUND; in riocm_ch_bind()
1268 spin_unlock_bh(&ch->lock); in riocm_ch_bind()
1270 riocm_put_channel(ch); in riocm_ch_bind()
1287 struct rio_channel *ch; in riocm_ch_alloc() local
1289 ch = kzalloc(sizeof(*ch), GFP_KERNEL); in riocm_ch_alloc()
1290 if (!ch) in riocm_ch_alloc()
1305 id = idr_alloc_cyclic(&ch_idr, ch, start, end, GFP_NOWAIT); in riocm_ch_alloc()
1310 kfree(ch); in riocm_ch_alloc()
1314 ch->id = (u16)id; in riocm_ch_alloc()
1315 ch->state = RIO_CM_IDLE; in riocm_ch_alloc()
1316 spin_lock_init(&ch->lock); in riocm_ch_alloc()
1317 INIT_LIST_HEAD(&ch->accept_queue); in riocm_ch_alloc()
1318 INIT_LIST_HEAD(&ch->ch_node); in riocm_ch_alloc()
1319 init_completion(&ch->comp); in riocm_ch_alloc()
1320 init_completion(&ch->comp_close); in riocm_ch_alloc()
1321 kref_init(&ch->ref); in riocm_ch_alloc()
1322 ch->rx_ring.head = 0; in riocm_ch_alloc()
1323 ch->rx_ring.tail = 0; in riocm_ch_alloc()
1324 ch->rx_ring.count = 0; in riocm_ch_alloc()
1325 ch->rx_ring.inuse_cnt = 0; in riocm_ch_alloc()
1327 return ch; in riocm_ch_alloc()
1348 struct rio_channel *ch = NULL; in riocm_ch_create() local
1350 ch = riocm_ch_alloc(*ch_num); in riocm_ch_create()
1352 if (IS_ERR(ch)) in riocm_ch_create()
1354 *ch_num, PTR_ERR(ch)); in riocm_ch_create()
1356 *ch_num = ch->id; in riocm_ch_create()
1358 return ch; in riocm_ch_create()
1367 struct rio_channel *ch = container_of(ref, struct rio_channel, ref); in riocm_ch_free() local
1370 riocm_debug(CHOP, "(ch_%d)", ch->id); in riocm_ch_free()
1372 if (ch->rx_ring.inuse_cnt) { in riocm_ch_free()
1374 i < RIOCM_RX_RING_SIZE && ch->rx_ring.inuse_cnt; i++) { in riocm_ch_free()
1375 if (ch->rx_ring.inuse[i] != NULL) { in riocm_ch_free()
1376 kfree(ch->rx_ring.inuse[i]); in riocm_ch_free()
1377 ch->rx_ring.inuse_cnt--; in riocm_ch_free()
1382 if (ch->rx_ring.count) in riocm_ch_free()
1383 for (i = 0; i < RIOCM_RX_RING_SIZE && ch->rx_ring.count; i++) { in riocm_ch_free()
1384 if (ch->rx_ring.buf[i] != NULL) { in riocm_ch_free()
1385 kfree(ch->rx_ring.buf[i]); in riocm_ch_free()
1386 ch->rx_ring.count--; in riocm_ch_free()
1390 complete(&ch->comp_close); in riocm_ch_free()
1393 static int riocm_send_close(struct rio_channel *ch) in riocm_send_close() argument
1406 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_send_close()
1407 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_send_close()
1412 hdr->dst_ch = htons(ch->rem_channel); in riocm_send_close()
1413 hdr->src_ch = htons(ch->id); in riocm_send_close()
1419 ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr)); in riocm_send_close()
1421 if (ret == -EBUSY && !riocm_queue_req(ch->cmdev, ch->rdev, in riocm_send_close()
1427 riocm_error("ch(%d) send CLOSE failed (ret=%d)", ch->id, ret); in riocm_send_close()
1434 * @ch: channel to be closed
1436 static int riocm_ch_close(struct rio_channel *ch) in riocm_ch_close() argument
1444 ch->id, current->comm, task_pid_nr(current)); in riocm_ch_close()
1446 state = riocm_exch(ch, RIO_CM_DESTROYING); in riocm_ch_close()
1448 riocm_send_close(ch); in riocm_ch_close()
1450 complete_all(&ch->comp); in riocm_ch_close()
1452 riocm_put_channel(ch); in riocm_ch_close()
1453 wret = wait_for_completion_interruptible_timeout(&ch->comp_close, tmo); in riocm_ch_close()
1455 riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret); in riocm_ch_close()
1459 riocm_debug(CHOP, "%s(%d) timed out waiting for ch %d", in riocm_ch_close()
1460 current->comm, task_pid_nr(current), ch->id); in riocm_ch_close()
1464 riocm_debug(CHOP, "%s(%d) wait for ch %d was interrupted", in riocm_ch_close()
1465 current->comm, task_pid_nr(current), ch->id); in riocm_ch_close()
1470 riocm_debug(CHOP, "ch_%d resources released", ch->id); in riocm_ch_close()
1471 kfree(ch); in riocm_ch_close()
1473 riocm_debug(CHOP, "failed to release ch_%d resources", ch->id); in riocm_ch_close()
1498 struct rio_channel *ch, *_c; in riocm_cdev_release() local
1507 idr_for_each_entry(&ch_idr, ch, i) { in riocm_cdev_release()
1508 if (ch && ch->filp == filp) { in riocm_cdev_release()
1510 ch->id, current->comm, in riocm_cdev_release()
1512 idr_remove(&ch_idr, ch->id); in riocm_cdev_release()
1513 list_add(&ch->ch_node, &list); in riocm_cdev_release()
1519 list_for_each_entry_safe(ch, _c, &list, ch_node) { in riocm_cdev_release()
1520 list_del(&ch->ch_node); in riocm_cdev_release()
1521 riocm_ch_close(ch); in riocm_cdev_release()
1662 struct rio_channel *ch; in cm_chan_create() local
1669 ch = riocm_ch_create(&ch_num); in cm_chan_create()
1670 if (IS_ERR(ch)) in cm_chan_create()
1671 return PTR_ERR(ch); in cm_chan_create()
1673 ch->filp = filp; in cm_chan_create()
1688 struct rio_channel *ch; in cm_chan_close() local
1697 ch = idr_find(&ch_idr, ch_num); in cm_chan_close()
1698 if (!ch) { in cm_chan_close()
1702 if (ch->filp != filp) { in cm_chan_close()
1706 idr_remove(&ch_idr, ch->id); in cm_chan_close()
1709 return riocm_ch_close(ch); in cm_chan_close()
1752 struct rio_channel *ch; in cm_chan_accept() local
1763 ch = riocm_ch_accept(param.ch_num, &param.ch_num, accept_to); in cm_chan_accept()
1764 if (IS_ERR(ch)) in cm_chan_accept()
1765 return PTR_ERR(ch); in cm_chan_accept()
1766 ch->filp = filp; in cm_chan_accept()
1769 ch->id, current->comm, task_pid_nr(current)); in cm_chan_accept()
1863 struct rio_channel *ch; in cm_chan_msg_rcv() local
1874 ch = riocm_get_channel(msg.ch_num); in cm_chan_msg_rcv()
1875 if (!ch) in cm_chan_msg_rcv()
1880 ret = riocm_ch_receive(ch, &buf, rxto); in cm_chan_msg_rcv()
1889 riocm_ch_free_rxbuf(ch, buf); in cm_chan_msg_rcv()
1891 riocm_put_channel(ch); in cm_chan_msg_rcv()
1995 struct rio_channel *ch, *_c; in riocm_remove_dev() local
2043 idr_for_each_entry(&ch_idr, ch, i) { in riocm_remove_dev()
2044 if (ch && ch->rdev == rdev) { in riocm_remove_dev()
2046 riocm_exch(ch, RIO_CM_DISCONNECT); in riocm_remove_dev()
2047 idr_remove(&ch_idr, ch->id); in riocm_remove_dev()
2048 list_add(&ch->ch_node, &list); in riocm_remove_dev()
2054 list_for_each_entry_safe(ch, _c, &list, ch_node) { in riocm_remove_dev()
2055 list_del(&ch->ch_node); in riocm_remove_dev()
2056 riocm_ch_close(ch); in riocm_remove_dev()
2179 struct rio_channel *ch, *_c; in riocm_remove_mport() local
2204 idr_for_each_entry(&ch_idr, ch, i) { in riocm_remove_mport()
2205 if (ch->cmdev == cm) { in riocm_remove_mport()
2207 mport->name, ch->id); in riocm_remove_mport()
2208 idr_remove(&ch_idr, ch->id); in riocm_remove_mport()
2209 list_add(&ch->ch_node, &list); in riocm_remove_mport()
2215 list_for_each_entry_safe(ch, _c, &list, ch_node) { in riocm_remove_mport()
2216 list_del(&ch->ch_node); in riocm_remove_mport()
2217 riocm_ch_close(ch); in riocm_remove_mport()
2241 struct rio_channel *ch; in rio_cm_shutdown() local
2255 idr_for_each_entry(&ch_idr, ch, i) { in rio_cm_shutdown()
2256 if (ch->state == RIO_CM_CONNECTED) { in rio_cm_shutdown()
2257 riocm_debug(EXIT, "close ch %d", ch->id); in rio_cm_shutdown()
2258 idr_remove(&ch_idr, ch->id); in rio_cm_shutdown()
2259 list_add(&ch->ch_node, &list); in rio_cm_shutdown()
2264 list_for_each_entry(ch, &list, ch_node) in rio_cm_shutdown()
2265 riocm_send_close(ch); in rio_cm_shutdown()