Lines Matching refs:ch
237 static int riocm_ch_close(struct rio_channel *ch);
257 static int riocm_cmp(struct rio_channel *ch, enum rio_cm_state cmp) in riocm_cmp() argument
261 spin_lock_bh(&ch->lock); in riocm_cmp()
262 ret = (ch->state == cmp); in riocm_cmp()
263 spin_unlock_bh(&ch->lock); in riocm_cmp()
267 static int riocm_cmp_exch(struct rio_channel *ch, in riocm_cmp_exch() argument
272 spin_lock_bh(&ch->lock); in riocm_cmp_exch()
273 ret = (ch->state == cmp); in riocm_cmp_exch()
275 ch->state = exch; in riocm_cmp_exch()
276 spin_unlock_bh(&ch->lock); in riocm_cmp_exch()
280 static enum rio_cm_state riocm_exch(struct rio_channel *ch, in riocm_exch() argument
285 spin_lock_bh(&ch->lock); in riocm_exch()
286 old = ch->state; in riocm_exch()
287 ch->state = exch; in riocm_exch()
288 spin_unlock_bh(&ch->lock); in riocm_exch()
294 struct rio_channel *ch; in riocm_get_channel() local
297 ch = idr_find(&ch_idr, nr); in riocm_get_channel()
298 if (ch) in riocm_get_channel()
299 kref_get(&ch->ref); in riocm_get_channel()
301 return ch; in riocm_get_channel()
304 static void riocm_put_channel(struct rio_channel *ch) in riocm_put_channel() argument
306 kref_put(&ch->ref, riocm_ch_free); in riocm_put_channel()
387 struct rio_channel *ch; in riocm_req_handler() local
394 ch = riocm_get_channel(chnum); in riocm_req_handler()
396 if (!ch) in riocm_req_handler()
399 if (ch->state != RIO_CM_LISTEN) { in riocm_req_handler()
401 riocm_put_channel(ch); in riocm_req_handler()
407 riocm_put_channel(ch); in riocm_req_handler()
415 spin_lock_bh(&ch->lock); in riocm_req_handler()
416 list_add_tail(&req->node, &ch->accept_queue); in riocm_req_handler()
417 spin_unlock_bh(&ch->lock); in riocm_req_handler()
418 complete(&ch->comp); in riocm_req_handler()
419 riocm_put_channel(ch); in riocm_req_handler()
434 struct rio_channel *ch; in riocm_resp_handler() local
439 ch = riocm_get_channel(chnum); in riocm_resp_handler()
440 if (!ch) in riocm_resp_handler()
443 if (ch->state != RIO_CM_CONNECT) { in riocm_resp_handler()
444 riocm_put_channel(ch); in riocm_resp_handler()
448 riocm_exch(ch, RIO_CM_CONNECTED); in riocm_resp_handler()
449 ch->rem_channel = ntohs(hh->src_ch); in riocm_resp_handler()
450 complete(&ch->comp); in riocm_resp_handler()
451 riocm_put_channel(ch); in riocm_resp_handler()
466 struct rio_channel *ch; in riocm_close_handler() local
473 ch = idr_find(&ch_idr, ntohs(hh->dst_ch)); in riocm_close_handler()
474 if (!ch) { in riocm_close_handler()
478 idr_remove(&ch_idr, ch->id); in riocm_close_handler()
481 riocm_exch(ch, RIO_CM_DISCONNECT); in riocm_close_handler()
483 ret = riocm_ch_close(ch); in riocm_close_handler()
538 struct rio_channel *ch; in rio_rx_data_handler() local
544 ch = riocm_get_channel(ntohs(hdr->dst_ch)); in rio_rx_data_handler()
545 if (!ch) { in rio_rx_data_handler()
552 spin_lock(&ch->lock); in rio_rx_data_handler()
554 if (ch->state != RIO_CM_CONNECTED) { in rio_rx_data_handler()
557 ch->id, ch->state); in rio_rx_data_handler()
558 spin_unlock(&ch->lock); in rio_rx_data_handler()
560 riocm_put_channel(ch); in rio_rx_data_handler()
564 if (ch->rx_ring.count == RIOCM_RX_RING_SIZE) { in rio_rx_data_handler()
566 riocm_debug(RX_DATA, "ch=%d is full", ch->id); in rio_rx_data_handler()
567 spin_unlock(&ch->lock); in rio_rx_data_handler()
569 riocm_put_channel(ch); in rio_rx_data_handler()
573 ch->rx_ring.buf[ch->rx_ring.head] = buf; in rio_rx_data_handler()
574 ch->rx_ring.head++; in rio_rx_data_handler()
575 ch->rx_ring.count++; in rio_rx_data_handler()
576 ch->rx_ring.head %= RIOCM_RX_RING_SIZE; in rio_rx_data_handler()
578 complete(&ch->comp); in rio_rx_data_handler()
580 spin_unlock(&ch->lock); in rio_rx_data_handler()
581 riocm_put_channel(ch); in rio_rx_data_handler()
792 struct rio_channel *ch; in riocm_ch_send() local
799 ch = riocm_get_channel(ch_id); in riocm_ch_send()
800 if (!ch) { in riocm_ch_send()
806 if (!riocm_cmp(ch, RIO_CM_CONNECTED)) { in riocm_ch_send()
816 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_ch_send()
817 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_ch_send()
822 hdr->dst_ch = htons(ch->rem_channel); in riocm_ch_send()
823 hdr->src_ch = htons(ch->id); in riocm_ch_send()
832 ret = riocm_post_send(ch->cmdev, ch->rdev, buf, len); in riocm_ch_send()
834 riocm_debug(TX, "ch %d send_err=%d", ch->id, ret); in riocm_ch_send()
836 riocm_put_channel(ch); in riocm_ch_send()
840 static int riocm_ch_free_rxbuf(struct rio_channel *ch, void *buf) in riocm_ch_free_rxbuf() argument
844 spin_lock_bh(&ch->lock); in riocm_ch_free_rxbuf()
847 if (ch->rx_ring.inuse[i] == buf) { in riocm_ch_free_rxbuf()
848 ch->rx_ring.inuse[i] = NULL; in riocm_ch_free_rxbuf()
849 ch->rx_ring.inuse_cnt--; in riocm_ch_free_rxbuf()
855 spin_unlock_bh(&ch->lock); in riocm_ch_free_rxbuf()
875 static int riocm_ch_receive(struct rio_channel *ch, void **buf, long timeout) in riocm_ch_receive() argument
881 if (!riocm_cmp(ch, RIO_CM_CONNECTED)) { in riocm_ch_receive()
886 if (ch->rx_ring.inuse_cnt == RIOCM_RX_RING_SIZE) { in riocm_ch_receive()
894 wret = wait_for_completion_interruptible_timeout(&ch->comp, timeout); in riocm_ch_receive()
896 riocm_debug(WAIT, "wait on %d returned %ld", ch->id, wret); in riocm_ch_receive()
903 ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -ECONNRESET; in riocm_ch_receive()
908 spin_lock_bh(&ch->lock); in riocm_ch_receive()
910 rxmsg = ch->rx_ring.buf[ch->rx_ring.tail]; in riocm_ch_receive()
911 ch->rx_ring.buf[ch->rx_ring.tail] = NULL; in riocm_ch_receive()
912 ch->rx_ring.count--; in riocm_ch_receive()
913 ch->rx_ring.tail++; in riocm_ch_receive()
914 ch->rx_ring.tail %= RIOCM_RX_RING_SIZE; in riocm_ch_receive()
918 if (ch->rx_ring.inuse[i] == NULL) { in riocm_ch_receive()
919 ch->rx_ring.inuse[i] = rxmsg; in riocm_ch_receive()
920 ch->rx_ring.inuse_cnt++; in riocm_ch_receive()
932 spin_unlock_bh(&ch->lock); in riocm_ch_receive()
954 struct rio_channel *ch = NULL; in riocm_ch_connect() local
959 ch = riocm_get_channel(loc_ch); in riocm_ch_connect()
960 if (!ch) in riocm_ch_connect()
963 if (!riocm_cmp_exch(ch, RIO_CM_IDLE, RIO_CM_CONNECT)) { in riocm_ch_connect()
968 ch->cmdev = cm; in riocm_ch_connect()
969 ch->rdev = peer->rdev; in riocm_ch_connect()
970 ch->context = NULL; in riocm_ch_connect()
971 ch->loc_destid = cm->mport->host_deviceid; in riocm_ch_connect()
972 ch->rem_channel = rem_ch; in riocm_ch_connect()
984 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_ch_connect()
1009 riocm_cmp_exch(ch, RIO_CM_CONNECT, RIO_CM_IDLE); in riocm_ch_connect()
1014 wret = wait_for_completion_interruptible_timeout(&ch->comp, in riocm_ch_connect()
1016 riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret); in riocm_ch_connect()
1023 ret = riocm_cmp(ch, RIO_CM_CONNECTED) ? 0 : -1; in riocm_ch_connect()
1026 riocm_put_channel(ch); in riocm_ch_connect()
1030 static int riocm_send_ack(struct rio_channel *ch) in riocm_send_ack() argument
1039 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_send_ack()
1040 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_send_ack()
1041 hdr->dst_ch = htons(ch->rem_channel); in riocm_send_ack()
1042 hdr->src_ch = htons(ch->id); in riocm_send_ack()
1052 ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr)); in riocm_send_ack()
1054 if (ret == -EBUSY && !riocm_queue_req(ch->cmdev, in riocm_send_ack()
1055 ch->rdev, hdr, sizeof(*hdr))) in riocm_send_ack()
1061 ch->id, rio_name(ch->rdev), ret); in riocm_send_ack()
1083 struct rio_channel *ch; in riocm_ch_accept() local
1091 ch = riocm_get_channel(ch_id); in riocm_ch_accept()
1092 if (!ch) in riocm_ch_accept()
1095 if (!riocm_cmp(ch, RIO_CM_LISTEN)) { in riocm_ch_accept()
1102 if (!try_wait_for_completion(&ch->comp)) { in riocm_ch_accept()
1107 riocm_debug(WAIT, "on %d", ch->id); in riocm_ch_accept()
1109 wret = wait_for_completion_interruptible_timeout(&ch->comp, in riocm_ch_accept()
1120 spin_lock_bh(&ch->lock); in riocm_ch_accept()
1122 if (ch->state != RIO_CM_LISTEN) { in riocm_ch_accept()
1124 } else if (list_empty(&ch->accept_queue)) { in riocm_ch_accept()
1126 ch->id); in riocm_ch_accept()
1130 spin_unlock_bh(&ch->lock); in riocm_ch_accept()
1133 riocm_debug(WAIT, "on %d returns %d", ch->id, err); in riocm_ch_accept()
1147 spin_lock_bh(&ch->lock); in riocm_ch_accept()
1149 req = list_first_entry(&ch->accept_queue, struct conn_req, node); in riocm_ch_accept()
1151 new_ch->cmdev = ch->cmdev; in riocm_ch_accept()
1152 new_ch->loc_destid = ch->loc_destid; in riocm_ch_accept()
1156 spin_unlock_bh(&ch->lock); in riocm_ch_accept()
1157 riocm_put_channel(ch); in riocm_ch_accept()
1158 ch = NULL; in riocm_ch_accept()
1196 if (ch) in riocm_ch_accept()
1197 riocm_put_channel(ch); in riocm_ch_accept()
1212 struct rio_channel *ch = NULL; in riocm_ch_listen() local
1217 ch = riocm_get_channel(ch_id); in riocm_ch_listen()
1218 if (!ch || !riocm_cmp_exch(ch, RIO_CM_CHAN_BOUND, RIO_CM_LISTEN)) in riocm_ch_listen()
1220 riocm_put_channel(ch); in riocm_ch_listen()
1237 struct rio_channel *ch = NULL; in riocm_ch_bind() local
1256 ch = riocm_get_channel(ch_id); in riocm_ch_bind()
1257 if (!ch) { in riocm_ch_bind()
1262 spin_lock_bh(&ch->lock); in riocm_ch_bind()
1263 if (ch->state != RIO_CM_IDLE) { in riocm_ch_bind()
1264 spin_unlock_bh(&ch->lock); in riocm_ch_bind()
1269 ch->cmdev = cm; in riocm_ch_bind()
1270 ch->loc_destid = cm->mport->host_deviceid; in riocm_ch_bind()
1271 ch->context = context; in riocm_ch_bind()
1272 ch->state = RIO_CM_CHAN_BOUND; in riocm_ch_bind()
1273 spin_unlock_bh(&ch->lock); in riocm_ch_bind()
1275 riocm_put_channel(ch); in riocm_ch_bind()
1292 struct rio_channel *ch; in riocm_ch_alloc() local
1294 ch = kzalloc(sizeof(*ch), GFP_KERNEL); in riocm_ch_alloc()
1295 if (!ch) in riocm_ch_alloc()
1310 id = idr_alloc_cyclic(&ch_idr, ch, start, end, GFP_NOWAIT); in riocm_ch_alloc()
1315 kfree(ch); in riocm_ch_alloc()
1319 ch->id = (u16)id; in riocm_ch_alloc()
1320 ch->state = RIO_CM_IDLE; in riocm_ch_alloc()
1321 spin_lock_init(&ch->lock); in riocm_ch_alloc()
1322 INIT_LIST_HEAD(&ch->accept_queue); in riocm_ch_alloc()
1323 INIT_LIST_HEAD(&ch->ch_node); in riocm_ch_alloc()
1324 init_completion(&ch->comp); in riocm_ch_alloc()
1325 init_completion(&ch->comp_close); in riocm_ch_alloc()
1326 kref_init(&ch->ref); in riocm_ch_alloc()
1327 ch->rx_ring.head = 0; in riocm_ch_alloc()
1328 ch->rx_ring.tail = 0; in riocm_ch_alloc()
1329 ch->rx_ring.count = 0; in riocm_ch_alloc()
1330 ch->rx_ring.inuse_cnt = 0; in riocm_ch_alloc()
1332 return ch; in riocm_ch_alloc()
1353 struct rio_channel *ch = NULL; in riocm_ch_create() local
1355 ch = riocm_ch_alloc(*ch_num); in riocm_ch_create()
1357 if (IS_ERR(ch)) in riocm_ch_create()
1359 *ch_num, PTR_ERR(ch)); in riocm_ch_create()
1361 *ch_num = ch->id; in riocm_ch_create()
1363 return ch; in riocm_ch_create()
1372 struct rio_channel *ch = container_of(ref, struct rio_channel, ref); in riocm_ch_free() local
1375 riocm_debug(CHOP, "(ch_%d)", ch->id); in riocm_ch_free()
1377 if (ch->rx_ring.inuse_cnt) { in riocm_ch_free()
1379 i < RIOCM_RX_RING_SIZE && ch->rx_ring.inuse_cnt; i++) { in riocm_ch_free()
1380 if (ch->rx_ring.inuse[i] != NULL) { in riocm_ch_free()
1381 kfree(ch->rx_ring.inuse[i]); in riocm_ch_free()
1382 ch->rx_ring.inuse_cnt--; in riocm_ch_free()
1387 if (ch->rx_ring.count) in riocm_ch_free()
1388 for (i = 0; i < RIOCM_RX_RING_SIZE && ch->rx_ring.count; i++) { in riocm_ch_free()
1389 if (ch->rx_ring.buf[i] != NULL) { in riocm_ch_free()
1390 kfree(ch->rx_ring.buf[i]); in riocm_ch_free()
1391 ch->rx_ring.count--; in riocm_ch_free()
1395 complete(&ch->comp_close); in riocm_ch_free()
1398 static int riocm_send_close(struct rio_channel *ch) in riocm_send_close() argument
1411 hdr->bhdr.src_id = htonl(ch->loc_destid); in riocm_send_close()
1412 hdr->bhdr.dst_id = htonl(ch->rem_destid); in riocm_send_close()
1417 hdr->dst_ch = htons(ch->rem_channel); in riocm_send_close()
1418 hdr->src_ch = htons(ch->id); in riocm_send_close()
1424 ret = riocm_post_send(ch->cmdev, ch->rdev, hdr, sizeof(*hdr)); in riocm_send_close()
1426 if (ret == -EBUSY && !riocm_queue_req(ch->cmdev, ch->rdev, in riocm_send_close()
1432 riocm_error("ch(%d) send CLOSE failed (ret=%d)", ch->id, ret); in riocm_send_close()
1441 static int riocm_ch_close(struct rio_channel *ch) in riocm_ch_close() argument
1449 ch->id, current->comm, task_pid_nr(current)); in riocm_ch_close()
1451 state = riocm_exch(ch, RIO_CM_DESTROYING); in riocm_ch_close()
1453 riocm_send_close(ch); in riocm_ch_close()
1455 complete_all(&ch->comp); in riocm_ch_close()
1457 riocm_put_channel(ch); in riocm_ch_close()
1458 wret = wait_for_completion_interruptible_timeout(&ch->comp_close, tmo); in riocm_ch_close()
1460 riocm_debug(WAIT, "wait on %d returns %ld", ch->id, wret); in riocm_ch_close()
1465 current->comm, task_pid_nr(current), ch->id); in riocm_ch_close()
1470 current->comm, task_pid_nr(current), ch->id); in riocm_ch_close()
1475 riocm_debug(CHOP, "ch_%d resources released", ch->id); in riocm_ch_close()
1476 kfree(ch); in riocm_ch_close()
1478 riocm_debug(CHOP, "failed to release ch_%d resources", ch->id); in riocm_ch_close()
1503 struct rio_channel *ch, *_c; in riocm_cdev_release() local
1512 idr_for_each_entry(&ch_idr, ch, i) { in riocm_cdev_release()
1513 if (ch && ch->filp == filp) { in riocm_cdev_release()
1515 ch->id, current->comm, in riocm_cdev_release()
1517 idr_remove(&ch_idr, ch->id); in riocm_cdev_release()
1518 list_add(&ch->ch_node, &list); in riocm_cdev_release()
1524 list_for_each_entry_safe(ch, _c, &list, ch_node) { in riocm_cdev_release()
1525 list_del(&ch->ch_node); in riocm_cdev_release()
1526 riocm_ch_close(ch); in riocm_cdev_release()
1667 struct rio_channel *ch; in cm_chan_create() local
1674 ch = riocm_ch_create(&ch_num); in cm_chan_create()
1675 if (IS_ERR(ch)) in cm_chan_create()
1676 return PTR_ERR(ch); in cm_chan_create()
1678 ch->filp = filp; in cm_chan_create()
1693 struct rio_channel *ch; in cm_chan_close() local
1702 ch = idr_find(&ch_idr, ch_num); in cm_chan_close()
1703 if (!ch) { in cm_chan_close()
1707 if (ch->filp != filp) { in cm_chan_close()
1711 idr_remove(&ch_idr, ch->id); in cm_chan_close()
1714 return riocm_ch_close(ch); in cm_chan_close()
1757 struct rio_channel *ch; in cm_chan_accept() local
1768 ch = riocm_ch_accept(param.ch_num, ¶m.ch_num, accept_to); in cm_chan_accept()
1769 if (IS_ERR(ch)) in cm_chan_accept()
1770 return PTR_ERR(ch); in cm_chan_accept()
1771 ch->filp = filp; in cm_chan_accept()
1774 ch->id, current->comm, task_pid_nr(current)); in cm_chan_accept()
1868 struct rio_channel *ch; in cm_chan_msg_rcv() local
1879 ch = riocm_get_channel(msg.ch_num); in cm_chan_msg_rcv()
1880 if (!ch) in cm_chan_msg_rcv()
1885 ret = riocm_ch_receive(ch, &buf, rxto); in cm_chan_msg_rcv()
1894 riocm_ch_free_rxbuf(ch, buf); in cm_chan_msg_rcv()
1896 riocm_put_channel(ch); in cm_chan_msg_rcv()
2000 struct rio_channel *ch, *_c; in riocm_remove_dev() local
2048 idr_for_each_entry(&ch_idr, ch, i) { in riocm_remove_dev()
2049 if (ch && ch->rdev == rdev) { in riocm_remove_dev()
2051 riocm_exch(ch, RIO_CM_DISCONNECT); in riocm_remove_dev()
2052 idr_remove(&ch_idr, ch->id); in riocm_remove_dev()
2053 list_add(&ch->ch_node, &list); in riocm_remove_dev()
2059 list_for_each_entry_safe(ch, _c, &list, ch_node) { in riocm_remove_dev()
2060 list_del(&ch->ch_node); in riocm_remove_dev()
2061 riocm_ch_close(ch); in riocm_remove_dev()
2181 struct rio_channel *ch, *_c; in riocm_remove_mport() local
2206 idr_for_each_entry(&ch_idr, ch, i) { in riocm_remove_mport()
2207 if (ch->cmdev == cm) { in riocm_remove_mport()
2209 mport->name, ch->id); in riocm_remove_mport()
2210 idr_remove(&ch_idr, ch->id); in riocm_remove_mport()
2211 list_add(&ch->ch_node, &list); in riocm_remove_mport()
2217 list_for_each_entry_safe(ch, _c, &list, ch_node) { in riocm_remove_mport()
2218 list_del(&ch->ch_node); in riocm_remove_mport()
2219 riocm_ch_close(ch); in riocm_remove_mport()
2243 struct rio_channel *ch; in rio_cm_shutdown() local
2257 idr_for_each_entry(&ch_idr, ch, i) { in rio_cm_shutdown()
2258 if (ch->state == RIO_CM_CONNECTED) { in rio_cm_shutdown()
2259 riocm_debug(EXIT, "close ch %d", ch->id); in rio_cm_shutdown()
2260 idr_remove(&ch_idr, ch->id); in rio_cm_shutdown()
2261 list_add(&ch->ch_node, &list); in rio_cm_shutdown()
2266 list_for_each_entry(ch, &list, ch_node) in rio_cm_shutdown()
2267 riocm_send_close(ch); in rio_cm_shutdown()