<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=us-ascii">
<TITLE></TITLE>

<META content="MSHTML 6.00.2800.1458" name=GENERATOR></HEAD>
<BODY>
<P><FONT size=2>In gen1 TS cm there was a function 
:<BR>ib_cm_service_assign()<BR>that return a free service_id .<BR>and then you 
could call ib_cm_listen with this service_id.<BR><BR>In Dapl implementation we 
use this when we want to listen on a not pre assign service_id<BR>(Dat verb: 
Dat_Psp_Create_any )<BR><BR>I think gen2 cm should include something similear 
:<BR><BR>There can be 2 ways to implement it :<BR>1) to add new function as it 
was in gen1<BR><BR>Index: 
include/ib_cm.h<BR>===================================================================<BR>+/**<BR>+ 
* ib_cm_service_assign() - return free service_id<BR>+ */<BR>+u64 
ib_cm_service_assign()(void);<BR>+<BR><BR>2) change the ib_cm_listen to 
understand that the reqeust comes without service_id<BR>   and then it 
will assign a service_id and only then will do the listen<BR>   this 
can be dane in many ways like :if the service_id == 0 (like sockets 
bind)<BR>  <BR><FONT face="Monotype Corsiva" 
size=5>  </FONT> <FONT face="Monotype Corsiva" color=#000080>Itamar 
Rabenstein</FONT> <BR><FONT face="CG Times" size=2>  Mellanox Technologies 
Ltd</FONT> <BR><FONT face="CG Times" size=2>mailto : 
itamar@mellanox.co.il</FONT> <BR><FONT face="CG Times" size=2>  
phone:       972-3-6259506</FONT> </P>
<P><BR></FONT><FONT size=2>-----Original Message-----<BR>From: Sean Hefty [<A 
href="mailto:mshefty@ichips.intel.com">mailto:mshefty@ichips.intel.com</A>]<BR>Sent: 
Thursday, December 16, 2004 9:56 PM<BR>To: openib-general@openib.org; 
halr@voltaire.com<BR>Subject: [openib-general] [PATCH] initial CM 
module<BR><BR><BR>This patch adds in the initial CM API and module code.  
The module loads,<BR>unloads, and allocates/deallocates connection structures, 
but that's about it.<BR>This patch does not include changes needed to Kconfig or 
the Makefile, since I'm<BR>not sure that it makes sense to change these 
yet.<BR><BR>I will commit this unless there are any objections.<BR><BR>- 
Sean<BR><BR>Index: 
include/ib_cm.h<BR>===================================================================<BR>--- 
include/ib_cm.h     (revision 0)<BR>+++ 
include/ib_cm.h     (revision 0)<BR>@@ -0,0 +1,387 
@@<BR>+/*<BR>+ * This software is available to you under a choice of one of 
two<BR>+ * licenses.  You may choose to be licensed under the terms of the 
GNU<BR>+ * General Public License (GPL) Version 2, available at<BR>+ * <<A 
href="http://www.fsf.org/copyleft/gpl.html" 
target=_blank>http://www.fsf.org/copyleft/gpl.html</A>>, or the OpenIB.org 
BSD<BR>+ * license, available in the LICENSE.TXT file accompanying this<BR>+ * 
software.  These details are also available at<BR>+ * <<A 
href="http://openib.org/license.html" 
target=_blank>http://openib.org/license.html</A>>.<BR>+ *<BR>+ * THE SOFTWARE 
IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,<BR>+ * EXPRESS OR IMPLIED, 
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<BR>+ * MERCHANTABILITY, FITNESS 
FOR A PARTICULAR PURPOSE AND<BR>+ * NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS<BR>+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN<BR>+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN<BR>+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE<BR>+ * SOFTWARE.<BR>+ *<BR>+ * Copyright (c) 2004 Intel 
Corporation.  All rights reserved.<BR>+ * Copyright (c) 2004 Topspin 
Corporation.  All rights reserved.<BR>+ * Copyright (c) 2004 Voltaire 
Corporation.  All rights reserved.<BR>+ *<BR>+ * $Id$<BR>+ */<BR>+#if 
!defined(IB_CM_H)<BR>+#define IB_CM_H<BR>+<BR>+#include 
<ib_mad.h><BR>+#include <ib_sa.h><BR>+<BR>+enum ib_cm_state 
{<BR>+       
IB_CM_IDLE,<BR>+       
IB_CM_LISTEN,<BR>+       
IB_CM_REQ_SENT,<BR>+       
IB_CM_REQ_RCVD,<BR>+       
IB_CM_MRA_REQ_SENT,<BR>+       
IB_CM_MRA_REQ_RCVD,<BR>+       
IB_CM_REP_SENT,<BR>+       
IB_CM_REP_RCVD,<BR>+       
IB_CM_MRA_REP_SENT,<BR>+       
IB_CM_MRA_REP_RCVD,<BR>+       
IB_CM_ESTABLISHED,<BR>+       
IB_CM_LAP_SENT,<BR>+       
IB_CM_LAP_RCVD,<BR>+       
IB_CM_MRA_LAP_SENT,<BR>+       
IB_CM_MRA_LAP_RCVD,<BR>+       
IB_CM_DREQ_SENT,<BR>+       
IB_CM_DREQ_RCVD,<BR>+       
IB_CM_TIMEWAIT,<BR>+       
IB_CM_SIDR_REQ_SENT,<BR>+       
IB_CM_SIDR_REQ_RCVD<BR>+};<BR>+<BR>+enum ib_cm_event_type 
{<BR>+       
IB_CM_REQ_TIMEOUT,<BR>+       
IB_CM_REQ_RECEIVED,<BR>+       
IB_CM_REP_TIMEOUT,<BR>+       
IB_CM_REP_RECEIVED,<BR>+       
IB_CM_RTU_RECEIVED,<BR>+       
IB_CM_DREQ_TIMEOUT,<BR>+       
IB_CM_DREQ_RECEIVED,<BR>+       
IB_CM_DREP_RECEIVED,<BR>+       
IB_CM_MRA_RECEIVED,<BR>+       
IB_CM_LAP_TIMEOUT,<BR>+       
IB_CM_LAP_RECEIVED,<BR>+       
IB_CM_APR_RECEIVED<BR>+};<BR>+<BR>+struct ib_cm_event 
{<BR>+       /* a whole lot more stuff goes here 
*/<BR>+       
void                    
*private_data;<BR>+       
u8                      
private_data_len;<BR>+       enum 
ib_cm_event_type   event;<BR>+};<BR>+<BR>+struct 
ib_cm_id;<BR>+<BR>+typedef void (*ib_cm_handler)(struct ib_cm_id 
*cm_id,<BR>+                             
struct ib_cm_event *event);<BR>+<BR>+struct ib_cm_id 
{<BR>+       
ib_cm_handler           
cm_handler;<BR>+       
void                    
*context;<BR>+       
u64                     
service_id;<BR>+       enum 
ib_cm_state        
state;<BR>+};<BR>+<BR>+/**<BR>+ * ib_create_cm_id - Allocate a connection 
identifier.<BR>+ * @cm_handler: Callback invoked to notify the user of CM 
events.<BR>+ * @context: User specified context associated with the 
connection<BR>+ *   identifier.<BR>+ *<BR>+ * Connection identifiers 
are used to track connection states and<BR>+ * listen requests.<BR>+ 
*/<BR>+struct ib_cm_id *ib_create_cm_id(ib_cm_handler 
cm_handler,<BR>+                                
void *context);<BR>+<BR>+/**<BR>+ * ib_destroy_cm_id - Destroy a connection 
identifier.<BR>+ * @cm_id: Connection identifier to destroy.<BR>+ *<BR>+ * This 
call blocks until the connection identifier is destroyed.<BR>+ */<BR>+int 
ib_destroy_cm_id(struct ib_cm_id *cm_id);<BR>+//*** TBD : add flags to allow 
calling routine from CM callback...<BR>+<BR>+/**<BR>+ * ib_cm_listen - Initiates 
listening on the specified service ID for<BR>+ *   connection and 
service ID resolution requests.<BR>+ * @cm_id: Connection identifier associated 
with the listen request.<BR>+ * @service_id: Service identifier matched against 
incoming connection<BR>+ *   and service ID resolution requests.<BR>+ 
* @service_mask: Mask applied to service ID used to listen across a<BR>+ 
*   range of service IDs.<BR>+ */<BR>+int ib_cm_listen(struct ib_cm_id 
*cm_id,<BR>+                
u64 
service_id,<BR>+                
u64 service_mask);<BR>+<BR>+struct ib_cm_req_param 
{<BR>+       struct 
ib_qp            
*qp;<BR>+       struct ib_path_record   
*primary_path;<BR>+       struct 
ib_path_record   
*alternate_path;<BR>+       
u64                     
service_id;<BR>+       
int                     
timeout_ms;<BR>+       
void                    
*private_data;<BR>+       
u8                      
private_data_len;<BR>+       
u8                      
responder_resources;<BR>+       
u8                      
initiator_depth;<BR>+       
u8                      
remote_cm_response_timeout;<BR>+       
u8                      
flow_control;<BR>+       
u8                      
local_cm_response_timeout;<BR>+       
u8                      
retry_count;<BR>+       
u8                      
rnr_retry_count;<BR>+       
u8                      
max_cm_retries;<BR>+};<BR>+<BR>+/**<BR>+ * ib_send_cm_req - Sends a connection 
request to the remote node.<BR>+ * @cm_id: Connection identifier that will be 
associated with the<BR>+ *   connection request.<BR>+ * @param: 
Connection request information needed to establish the<BR>+ *   
connection.<BR>+ */<BR>+int ib_send_cm_req(struct ib_cm_id 
*cm_id,<BR>+                  
struct ib_cm_req_param *param);<BR>+<BR>+struct ib_cm_rep_param 
{<BR>+       struct ib_qp    
*qp;<BR>+       
void            
*private_data;<BR>+       
u8              
reply_private_data_len;<BR>+       
u8              
responder_resources;<BR>+       
u8              
initiator_depth;<BR>+       
u8              
target_ack_delay;<BR>+       
u8              
failover_accepted;<BR>+       
u8              
flow_control;<BR>+       
u8              
rnr_retry_count;<BR>+};<BR>+<BR>+/**<BR>+ * ib_send_cm_rep - Sends a connection 
reply in response to a connection<BR>+ *   request.<BR>+ * @cm_id: 
Connection identifier that will be associated with the<BR>+ *   
connection request.<BR>+ * @param: Connection reply information needed to 
establish the<BR>+ *   connection.<BR>+ */<BR>+int 
ib_send_cm_rep(struct ib_cm_id 
*cm_id,<BR>+                  
struct ib_cm_req_param *param);<BR>+<BR>+/**<BR>+ * ib_send_cm_rtu - Sends a 
connection ready to use message in response<BR>+ *   to a connection 
reply message.<BR>+ * @cm_id: Connection identifier associated with the 
connection request.<BR>+ * @private_data: Optional user-defined private data 
sent with the<BR>+ *   ready to use message.<BR>+ * @private_data_len: 
Size of the private data buffer, in bytes.<BR>+ */<BR>+int ib_send_cm_rtu(struct 
ib_cm_id 
*cm_id,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len);<BR>+<BR>+/**<BR>+ * ib_send_cm_dreq - Sends a 
disconnection request for an existing<BR>+ *   connection.<BR>+ * 
@cm_id: Connection identifier associated with the connection being<BR>+ 
*   released.<BR>+ * @private_data: Optional user-defined private data 
sent with the<BR>+ *   disconnection request message.<BR>+ * 
@private_data_len: Size of the private data buffer, in bytes.<BR>+ */<BR>+int 
ib_send_cm_dreq(struct ib_cm_id 
*cm_id,<BR>+                   
void 
*private_data,<BR>+                   
u8 private_data_len);<BR>+<BR>+/**<BR>+ * ib_send_cm_drep - Sends a 
disconnection reply to a disconnection request.<BR>+ * @cm_id: Connection 
identifier associated with the connection being<BR>+ *   
released.<BR>+ * @private_data: Optional user-defined private data sent with 
the<BR>+ *   disconnection reply message.<BR>+ * @private_data_len: 
Size of the private data buffer, in bytes.<BR>+ */<BR>+int 
ib_send_cm_drep(struct ib_cm_id 
*cm_id,<BR>+                   
void 
*private_data,<BR>+                   
u8 private_data_len);<BR>+<BR>+/**<BR>+ * ib_cm_establish - Forces a connection 
state to established.<BR>+ * @cm_id: Connection identifier to transition to 
established.<BR>+ *<BR>+ * This routine should be invoked by users who receive 
messages on a<BR>+ * connected QP before an RTU has been received.<BR>+ 
*/<BR>+int ib_cm_establish(struct ib_cm_id *id);<BR>+<BR>+enum ib_cm_rej_reason 
{<BR>+       
IB_CM_REJ_NO_QP                         
= __constant_htons(1),<BR>+       
IB_CM_REJ_NO_EEC                        
= __constant_htons(2),<BR>+       
IB_CM_REJ_NO_RESOURCES                  
= __constant_htons(3),<BR>+       
IB_CM_REJ_TIMEOUT                       
= __constant_htons(4),<BR>+       
IB_CM_REJ_UNSUPPORTED                   
= __constant_htons(5),<BR>+       
IB_CM_REJ_INVALID_COMM_ID               
= __constant_htons(6),<BR>+       
IB_CM_REJ_INVALID_COMM_INSTANCE         
= __constant_htons(7),<BR>+       
IB_CM_REJ_INVALID_SERVICE_ID            
= __constant_htons(8),<BR>+       
IB_CM_REJ_INVALID_TRANSPORT_TYPE        = 
__constant_htons(9),<BR>+       
IB_CM_REJ_STALE_CONN                    
= __constant_htons(10),<BR>+       
IB_CM_REJ_RDC_NOT_EXIST                 
= __constant_htons(11),<BR>+       
IB_CM_REJ_INVALID_GID                   
= __constant_htons(12),<BR>+       
IB_CM_REJ_INVALID_LID                   
= __constant_htons(13),<BR>+       
IB_CM_REJ_INVALID_SL                    
= __constant_htons(14),<BR>+       
IB_CM_REJ_INVALID_TRAFFIC_CLASS         
= __constant_htons(15),<BR>+       
IB_CM_REJ_INVALID_HOP_LIMIT             
= __constant_htons(16),<BR>+       
IB_CM_REJ_INVALID_PACKET_RATE           
= __constant_htons(17),<BR>+       
IB_CM_REJ_INVALID_ALT_GID               
= __constant_htons(18),<BR>+       
IB_CM_REJ_INVALID_ALT_LID               
= __constant_htons(19),<BR>+       
IB_CM_REJ_INVALID_ALT_SL                
= __constant_htons(20),<BR>+       
IB_CM_REJ_INVALID_ALT_TRAFFIC_CLASS     = 
__constant_htons(21),<BR>+       
IB_CM_REJ_INVALID_ALT_HOP_LIMIT         
= __constant_htons(22),<BR>+       
IB_CM_REJ_INVALID_ALT_PACKET_RATE       = 
__constant_htons(23),<BR>+       
IB_CM_REJ_PORT_REDIRECT                 
= __constant_htons(24),<BR>+       
IB_CM_REJ_INVALID_MTU                   
= __constant_htons(26),<BR>+       
IB_CM_REJ_INSUFFICIENT_RESP_RESOURCES   = 
__constant_htons(27),<BR>+       
IB_CM_REJ_CONSUMER_DEFINED              
= __constant_htons(28),<BR>+       
IB_CM_REJ_INVALID_RNR_RETRY             
= __constant_htons(29),<BR>+       
IB_CM_REJ_DUPLICATE_LOCAL_COMM_ID       = 
__constant_htons(30),<BR>+       
IB_CM_REJ_INVALID_CLASS_VERSION         
= __constant_htons(31),<BR>+       
IB_CM_REJ_INVALID_FLOW_LABEL            
= __constant_htons(32),<BR>+       
IB_CM_REJ_INVALID_ALT_FLOW_LABEL        = 
__constant_htons(33)<BR>+};<BR>+<BR>+/**<BR>+ * ib_send_cm_rej - Sends a 
connection rejection message to the<BR>+ *   remote node.<BR>+ * 
@cm_id: Connection identifier associated with the connection being<BR>+ 
*   rejected.<BR>+ * @reason: Reason for the connection request 
rejection.<BR>+ * @ari: Optional additional rejection information.<BR>+ * 
@ari_length: Size of the additional rejection information, in bytes.<BR>+ * 
@private_data: Optional user-defined private data sent with the<BR>+ 
*   rejection message.<BR>+ * @private_data_len: Size of the private 
data buffer, in bytes.<BR>+ */<BR>+int ib_send_cm_rej(struct ib_cm_id 
*cm_id,<BR>+                  
enum ib_cm_rej_reason 
reason,<BR>+                  
void 
*ari,<BR>+                  
u8 
ari_length,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len);<BR>+<BR>+/**<BR>+ * ib_send_cm_mra - Sends a message 
receipt acknowledgement to a connection<BR>+ *   message.<BR>+ * 
@cm_id: Connection identifier associated with the connection message.<BR>+ * 
@service_timeout: The maximum time required for the sender to reply to<BR>+ 
*   to the connection message.<BR>+ * @private_data: Optional 
user-defined private data sent with the<BR>+ *   message receipt 
acknowledgement.<BR>+ * @private_data_len: Size of the private data buffer, in 
bytes.<BR>+ */<BR>+int ib_send_cm_mra(struct ib_cm_id 
*cm_id,<BR>+                  
u8 
service_timeout,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len);<BR>+<BR>+/**<BR>+ * ib_send_cm_lap - Sends a load 
alternate path request.<BR>+ * @cm_id: Connection identifier associated with the 
load alternate path<BR>+ *   message.<BR>+ * @alternate_path: A path 
record that identifies the alternate path to<BR>+ *   load.<BR>+ * 
@private_data: Optional user-defined private data sent with the<BR>+ 
*   load alternate path message.<BR>+ * @private_data_len: Size of the 
private data buffer, in bytes.<BR>+ */<BR>+int ib_send_cm_lap(struct ib_cm_id 
*cm_id,<BR>+                  
struct ib_path_record 
*alternate_path,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len);<BR>+<BR>+enum ib_cm_apr_status 
{<BR>+       
IB_CM_APR_SUCCESS,<BR>+       
IB_CM_APR_INVALID_COMM_ID,<BR>+       
IB_CM_APR_UNSUPPORTED,<BR>+       
IB_CM_APR_REJECT,<BR>+       
IB_CM_APR_REDIRECT,<BR>+       
IB_CM_APR_IS_CURRENT,<BR>+       
IB_CM_APR_INVALID_QPN_EECN,<BR>+       
IB_CM_APR_INVALID_LID,<BR>+       
IB_CM_APR_INVALID_GID,<BR>+       
IB_CM_APR_INVALID_FLOW_LABEL,<BR>+       
IB_CM_APR_INVALID_TCLASS,<BR>+       
IB_CM_APR_INVALID_HOP_LIMIT,<BR>+       
IB_CM_APR_INVALID_PACKET_RATE,<BR>+       
IB_CM_APR_INVALID_SL<BR>+};<BR>+<BR>+/**<BR>+ * ib_send_cm_apr - Sends an 
alternate path response message in response to<BR>+ *   a load 
alternate path request.<BR>+ * @cm_id: Connection identifier associated with the 
alternate path response.<BR>+ * @status: Reply status sent with the alternate 
path response.<BR>+ * @info: Optional additional information sent with the 
alternate path<BR>+ *   response.<BR>+ * @info_length: Size of the 
additional information, in bytes.<BR>+ * @private_data: Optional user-defined 
private data sent with the<BR>+ *   alternate path response 
message.<BR>+ * @private_data_len: Size of the private data buffer, in 
bytes.<BR>+ */<BR>+int ib_send_cm_apr(struct ib_cm_id 
*cm_id,<BR>+                  
enum ib_cm_apr_status 
status,<BR>+                  
void 
*info,<BR>+                  
u8 
info_length,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len);<BR>+<BR>+struct ib_cm_sidr_req_param 
{<BR>+       struct ib_path_record   
*path;<BR>+       
u64                     
service_id;<BR>+       
int                     
timeout_ms;<BR>+       
void                    
*private_data;<BR>+       
u8                      
private_data_len;<BR>+       
u16                     
pkey;<BR>+};<BR>+<BR>+/**<BR>+ * ib_send_cm_sidr_req - Sends a service ID 
resolution request to the<BR>+ *   remote node.<BR>+ * @cm_id: 
Communication identifier that will be associated with the<BR>+ *   
service ID resolution request.<BR>+ * @param: Service ID resolution request 
information.<BR>+ */<BR>+int ib_send_cm_sidr_req(struct ib_cm_id 
*cm_id,<BR>+                       
struct ib_cm_sidr_req_param *param);<BR>+<BR>+enum ib_cm_sidr_status 
{<BR>+       
IB_SIDR_SUCCESS,<BR>+       
IB_SIDR_UNSUPPORTED,<BR>+       
IB_SIDR_REJECT,<BR>+       
IB_SIDR_NO_QP,<BR>+       
IB_SIDR_REDIRECT,<BR>+       
IB_SIDR_UNSUPPORTED_VERSION<BR>+};<BR>+<BR>+struct ib_cm_sidr_rep_param 
{<BR>+       
u32                     
qp_num;<BR>+       
u32                     
qkey;<BR>+       enum ib_cm_sidr_status  
status;<BR>+       
void                    
*info;<BR>+       
u8                      
info_length;<BR>+       
void                    
*private_data;<BR>+       
u8                      
private_data_len;<BR>+};<BR>+<BR>+/**<BR>+ * ib_send_cm_sidr_rep - Sends a 
service ID resolution request to the<BR>+ *   remote node.<BR>+ * 
@cm_id: Communication identifier associated with the received service ID<BR>+ 
*   resolution request.<BR>+ * @param: Service ID resolution reply 
information.<BR>+ */<BR>+int ib_send_cm_sidr_rep(struct ib_cm_id 
*cm_id,<BR>+                       
struct ib_cm_sidr_rep_param *param);<BR>+<BR>+#endif /* IB_CM_H */<BR>Index: 
core/cm.c<BR>===================================================================<BR>--- 
core/cm.c   (revision 0)<BR>+++ core/cm.c   (revision 
0)<BR>@@ -0,0 +1,292 @@<BR>+/*<BR>+ * This software is available to you under a 
choice of one of two<BR>+ * licenses.  You may choose to be licensed under 
the terms of the GNU<BR>+ * General Public License (GPL) Version 2, available 
at<BR>+ * <<A href="http://www.fsf.org/copyleft/gpl.html" 
target=_blank>http://www.fsf.org/copyleft/gpl.html</A>>, or the OpenIB.org 
BSD<BR>+ * license, available in the LICENSE.TXT file accompanying this<BR>+ * 
software.  These details are also available at<BR>+ * <<A 
href="http://openib.org/license.html" 
target=_blank>http://openib.org/license.html</A>>.<BR>+ *<BR>+ * THE SOFTWARE 
IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,<BR>+ * EXPRESS OR IMPLIED, 
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF<BR>+ * MERCHANTABILITY, FITNESS 
FOR A PARTICULAR PURPOSE AND<BR>+ * NONINFRINGEMENT. IN NO EVENT SHALL THE 
AUTHORS OR COPYRIGHT HOLDERS<BR>+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
LIABILITY, WHETHER IN AN<BR>+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM, OUT OF OR IN<BR>+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
DEALINGS IN THE<BR>+ * SOFTWARE.<BR>+ *<BR>+ * Copyright (c) 2004 Intel 
Corporation.  All rights reserved.<BR>+ * Copyright (c) 2004 Topspin 
Corporation.  All rights reserved.<BR>+ * Copyright (c) 2004 Voltaire 
Corporation.  All rights reserved.<BR>+ *<BR>+ * $Id$<BR>+ */<BR>+#include 
<linux/err.h><BR>+#include <linux/spinlock.h><BR>+<BR>+#include 
<ib_cm.h><BR>+<BR>+MODULE_AUTHOR("Sean 
Hefty");<BR>+MODULE_DESCRIPTION("InfiniBand CM");<BR>+MODULE_LICENSE("Dual 
BSD/GPL");<BR>+<BR>+static void cm_add_one(struct ib_device *device);<BR>+static 
void cm_remove_one(struct ib_device *device);<BR>+<BR>+static struct ib_client 
cm_client = {<BR>+       .name   = 
"cm",<BR>+       .add    = 
cm_add_one,<BR>+       .remove = 
cm_remove_one<BR>+};<BR>+<BR>+struct cm_port 
{<BR>+       struct ib_mad_agent 
*mad_agent;<BR>+};<BR>+<BR>+struct ib_cm_id_private 
{<BR>+       struct ib_cm_id 
id;<BR>+<BR>+       spinlock_t 
lock;<BR>+       wait_queue_head_t 
wait;<BR>+       atomic_t 
refcount;<BR>+};<BR>+<BR>+struct ib_cm_id *ib_create_cm_id(ib_cm_handler 
cm_handler,<BR>+                                
void *context)<BR>+{<BR>+       struct 
ib_cm_id_private *cm_id_priv;<BR>+<BR>+       
cm_id_priv = kmalloc(sizeof *cm_id_priv, 
GFP_KERNEL);<BR>+       if 
(!cm_id_priv)<BR>+               
return ERR_PTR(-ENOMEM);<BR>+<BR>+       
cm_id_priv->id.service_id = 0;<BR>+       
cm_id_priv->id.state = IB_CM_IDLE;<BR>+       
cm_id_priv->id.cm_handler = 
cm_handler;<BR>+       cm_id_priv->id.context = 
context;<BR>+<BR>+       
spin_lock_init(&cm_id_priv->lock);<BR>+       
init_waitqueue_head(&cm_id_priv->wait);<BR>+       
atomic_set(&cm_id_priv->refcount, 
1);<BR>+<BR>+       return 
&cm_id_priv->id;<BR>+}<BR>+EXPORT_SYMBOL(ib_create_cm_id);<BR>+<BR>+static 
void reset_cm_state(struct ib_cm_id_private 
*cm_id_priv)<BR>+{<BR>+       /* reject 
connections if establishing */<BR>+       /* 
disconnect established connections */<BR>+       
/* update timewait info */<BR>+}<BR>+<BR>+int ib_destroy_cm_id(struct ib_cm_id 
*cm_id)<BR>+{<BR>+       struct ib_cm_id_private 
*cm_id_priv;<BR>+       unsigned long 
flags;<BR>+<BR>+       cm_id_priv = 
container_of(cm_id, struct ib_cm_id_private, 
id);<BR>+<BR>+       
spin_lock_irqsave(&cm_id_priv->lock, 
flags);<BR>+       switch(cm_id->state) 
{<BR>+       case 
IB_CM_IDLE:<BR>+       case 
IB_CM_LISTEN:<BR>+       case 
IB_CM_TIMEWAIT:<BR>+               
break;  /* Connection is ready to be destroyed. 
*/<BR>+       
default:<BR>+               
reset_cm_state(cm_id_priv);<BR>+               
break;<BR>+       
}<BR>+       cm_id->state = 
IB_CM_IDLE;<BR>+       
spin_unlock_irqrestore(&cm_id_priv->lock, 
flags);<BR>+<BR>+       
atomic_dec(&cm_id_priv->refcount);<BR>+       
wait_event(cm_id_priv->wait,<BR>+                  
!atomic_read(&cm_id_priv->refcount));<BR>+       
kfree(cm_id_priv);<BR>+       return 
0;<BR>+}<BR>+EXPORT_SYMBOL(ib_destroy_cm_id);<BR>+<BR>+int ib_cm_listen(struct 
ib_cm_id 
*cm_id,<BR>+                
u64 
service_id,<BR>+                
u64 service_mask)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_cm_listen);<BR>+<BR>+int 
ib_send_cm_req(struct ib_cm_id 
*cm_id,<BR>+                  
struct ib_cm_req_param *param)<BR>+{<BR>+       
return -EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_req);<BR>+<BR>+int 
ib_send_cm_rep(struct ib_cm_id 
*cm_id,<BR>+                  
struct ib_cm_req_param *param)<BR>+{<BR>+       
return -EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_rep);<BR>+<BR>+int 
ib_send_cm_rtu(struct ib_cm_id 
*cm_id,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_rtu);<BR>+<BR>+int 
ib_send_cm_dreq(struct ib_cm_id 
*cm_id,<BR>+                   
void 
*private_data,<BR>+                   
u8 private_data_len)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_dreq);<BR>+<BR>+int 
ib_send_cm_drep(struct ib_cm_id 
*cm_id,<BR>+                   
void 
*private_data,<BR>+                   
u8 private_data_len)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_drep);<BR>+<BR>+int 
ib_cm_establish(struct ib_cm_id 
*id)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_cm_establish);<BR>+<BR>+int 
ib_send_cm_rej(struct ib_cm_id 
*cm_id,<BR>+                  
enum ib_cm_rej_reason 
reason,<BR>+                  
void 
*ari,<BR>+                  
u8 
ari_length,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_rej);<BR>+<BR>+int 
ib_send_cm_mra(struct ib_cm_id 
*cm_id,<BR>+                  
u8 
service_timeout,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_mra);<BR>+<BR>+int 
ib_send_cm_lap(struct ib_cm_id 
*cm_id,<BR>+                  
struct ib_path_record 
*alternate_path,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_lap);<BR>+<BR>+int 
ib_send_cm_apr(struct ib_cm_id 
*cm_id,<BR>+                  
enum ib_cm_apr_status 
status,<BR>+                  
void 
*info,<BR>+                  
u8 
info_length,<BR>+                  
void 
*private_data,<BR>+                  
u8 private_data_len)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_apr);<BR>+<BR>+int 
ib_send_cm_sidr_req(struct ib_cm_id 
*cm_id,<BR>+                       
struct ib_cm_sidr_req_param 
*param)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_sidr_req);<BR>+<BR>+int 
ib_send_cm_sidr_rep(struct ib_cm_id 
*cm_id,<BR>+                       
struct ib_cm_sidr_rep_param 
*param)<BR>+{<BR>+       return 
-EINVAL;<BR>+}<BR>+EXPORT_SYMBOL(ib_send_cm_sidr_rep);<BR>+<BR>+static void 
send_handler(struct ib_mad_agent 
*mad_agent,<BR>+                        
struct ib_mad_send_wc 
*mad_send_wc)<BR>+{<BR>+       struct cm_port 
*port;<BR>+<BR>+       port = (struct cm_port 
*)mad_agent->context;<BR>+}<BR>+<BR>+static void recv_handler(struct 
ib_mad_agent 
*mad_agent,<BR>+                        
struct ib_mad_recv_wc 
*mad_recv_wc)<BR>+{<BR>+       struct cm_port 
*port;<BR>+<BR>+       port = (struct cm_port 
*)mad_agent->context;<BR>+}<BR>+<BR>+static void cm_add_one(struct ib_device 
*device)<BR>+{<BR>+       struct cm_port 
*port;<BR>+       struct ib_mad_reg_req 
reg_req;<BR>+       u8 
i;<BR>+<BR>+       port = kmalloc(sizeof *port * 
device->phys_port_cnt, GFP_KERNEL);<BR>+       
if 
(!port)<BR>+               
goto out;<BR>+<BR>+       memset(&reg_req, 0, 
sizeof reg_req);<BR>+       reg_req.mgmt_class = 
IB_MGMT_CLASS_CM;<BR>+       
reg_req.mgmt_class_version = 1;<BR>+       
set_bit(IB_MGMT_METHOD_GET, 
reg_req.method_mask);<BR>+       
set_bit(IB_MGMT_METHOD_SET, 
reg_req.method_mask);<BR>+       
set_bit(IB_MGMT_METHOD_GET_RESP, 
reg_req.method_mask);<BR>+       
set_bit(IB_MGMT_METHOD_SEND, 
reg_req.method_mask);<BR>+       for (i = 1; i 
<= device->phys_port_cnt; i++) 
{<BR>+               
port[i].mad_agent = ib_register_mad_agent(device, 
i,<BR>+                                                         
IB_QPT_GSI,<BR>+                                                         
&reg_req,<BR>+                                                         
0,<BR>+                                                         
send_handler,<BR>+                                                         
recv_handler,<BR>+                                                         
&port[i]);<BR>+       
}<BR>+<BR>+out:<BR>+       
ib_set_client_data(device, &cm_client, port);<BR>+}<BR>+<BR>+static void 
cm_remove_one(struct ib_device 
*device)<BR>+{<BR>+       struct cm_port 
*port;<BR>+       int 
i;<BR>+<BR>+       port = (struct cm_port 
*)ib_get_client_data(device, 
&cm_client);<BR>+       if 
(!port)<BR>+               
return;<BR>+<BR>+       for (i = 1; i <= 
device->phys_port_cnt; i++) 
{<BR>+               
if 
(!IS_ERR(port[i].mad_agent))<BR>+                       
ib_unregister_mad_agent(port[i].mad_agent);<BR>+       
}<BR>+       kfree(port);<BR>+}<BR>+<BR>+static 
int __init ib_cm_init(void)<BR>+{<BR>+       
return ib_register_client(&cm_client);<BR>+}<BR>+<BR>+static void __exit 
ib_cm_cleanup(void)<BR>+{<BR>+       
ib_unregister_client(&cm_client);<BR>+}<BR>+<BR>+module_init(ib_cm_init);<BR>+module_exit(ib_cm_cleanup);<BR>_______________________________________________<BR>openib-general 
mailing list<BR>openib-general@openib.org<BR><A 
href="http://openib.org/mailman/listinfo/openib-general" 
target=_blank>http://openib.org/mailman/listinfo/openib-general</A><BR><BR>To 
unsubscribe, please visit <A 
href="http://openib.org/mailman/listinfo/openib-general" 
target=_blank>http://openib.org/mailman/listinfo/openib-general</A> 
</FONT></P></BODY></HTML>