+ RETURN(1);
+}
+
+static int bulk_get_sink_callback(ptl_event_t *ev)
+{
+ struct ptlrpc_bulk_desc *desc = ev->mem_desc.user_ptr;
+ unsigned long flags;
+ ENTRY;
+
+ CDEBUG(D_NET, "got %s event %d\n",
+ (ev->type == PTL_EVENT_SENT) ? "SENT" :
+ (ev->type == PTL_EVENT_REPLY) ? "REPLY" : "UNEXPECTED",
+ ev->type);
+
+ LASSERT(ev->type == PTL_EVENT_SENT || ev->type == PTL_EVENT_REPLY);
+
+ /* 1 fragment for each page always */
+ LASSERT(ev->mem_desc.niov == desc->bd_page_count);
+
+ spin_lock_irqsave (&desc->bd_lock, flags);
+ LASSERT(desc->bd_callback_count > 0 &&
+ desc->bd_callback_count <= 2);
+
+ if (--desc->bd_callback_count == 0) {
+ desc->bd_network_rw = 0;
+ desc->bd_complete = 1;
+ wake_up(&desc->bd_waitq);
+ }
+ spin_unlock_irqrestore (&desc->bd_lock, flags);
+
+ RETURN(0);
+}
+
+int ptlrpc_uuid_to_peer (struct obd_uuid *uuid, struct ptlrpc_peer *peer)
+{
+ struct ptlrpc_ni *pni;
+ struct lustre_peer lpeer;
+ int i;
+ int rc = lustre_uuid_to_peer (uuid->uuid, &lpeer);
+
+ if (rc != 0)
+ RETURN (rc);
+
+ for (i = 0; i < ptlrpc_ninterfaces; i++) {
+ pni = &ptlrpc_interfaces[i];
+
+ if (!memcmp(&lpeer.peer_ni, &pni->pni_ni_h,
+ sizeof (lpeer.peer_ni))) {
+ peer->peer_nid = lpeer.peer_nid;
+ peer->peer_ni = pni;
+ return (0);
+ }
+ }
+
+ CERROR("Can't find ptlrpc interface for "LPX64" ni handle %08lx."LPX64"\n",
+ lpeer.peer_nid, lpeer.peer_ni.nal_idx, lpeer.peer_ni.cookie);
+ return (-ENOENT);
+}
+
+void ptlrpc_ni_fini(struct ptlrpc_ni *pni)
+{
+ PtlEQFree(pni->pni_request_out_eq_h);
+ PtlEQFree(pni->pni_reply_out_eq_h);
+ PtlEQFree(pni->pni_reply_in_eq_h);
+ PtlEQFree(pni->pni_bulk_put_source_eq_h);
+ PtlEQFree(pni->pni_bulk_put_sink_eq_h);
+ PtlEQFree(pni->pni_bulk_get_source_eq_h);
+ PtlEQFree(pni->pni_bulk_get_sink_eq_h);
+
+ kportal_put_ni (pni->pni_number);
+}
+
+int ptlrpc_ni_init(int number, char *name, struct ptlrpc_ni *pni)
+{
+ int rc;
+ ptl_handle_ni_t *nip = kportal_get_ni (number);
+
+ if (nip == NULL) {
+ CDEBUG (D_NET, "Network interface %s not loaded\n", name);
+ return (-ENOENT);
+ }
+
+ CDEBUG (D_NET, "init %d %s: nal_idx %ld\n", number, name, nip->nal_idx);
+
+ pni->pni_name = name;
+ pni->pni_number = number;
+ pni->pni_ni_h = *nip;
+
+ pni->pni_request_out_eq_h = PTL_HANDLE_NONE;
+ pni->pni_reply_out_eq_h = PTL_HANDLE_NONE;
+ pni->pni_reply_in_eq_h = PTL_HANDLE_NONE;
+ pni->pni_bulk_put_source_eq_h = PTL_HANDLE_NONE;
+ pni->pni_bulk_put_sink_eq_h = PTL_HANDLE_NONE;
+ pni->pni_bulk_get_source_eq_h = PTL_HANDLE_NONE;
+ pni->pni_bulk_get_sink_eq_h = PTL_HANDLE_NONE;
+
+ /* NB We never actually PtlEQGet() out of these events queues since
+ * we're only interested in the event callback, so we can just let
+ * them wrap. Their sizes aren't a big deal, apart from providing
+ * a little history for debugging... */
+
+ rc = PtlEQAlloc(pni->pni_ni_h, 1024, request_out_callback,
+ &pni->pni_request_out_eq_h);
+ if (rc != PTL_OK)
+ GOTO (fail, rc = -ENOMEM);
+
+ rc = PtlEQAlloc(pni->pni_ni_h, 1024, reply_out_callback,
+ &pni->pni_reply_out_eq_h);
+ if (rc != PTL_OK)
+ GOTO (fail, rc = -ENOMEM);
+
+ rc = PtlEQAlloc(pni->pni_ni_h, 1024, reply_in_callback,
+ &pni->pni_reply_in_eq_h);