icast *multicast;
	int ret;

	dev = ib_get_client_data(device, &mcast_client);
	if (!dev)
		return ERR_PTR(-ENODEV);

	member = kmalloc(sizeof *member, gfp_mask);
	if (!member)
		return ERR_PTR(-ENOMEM);

	ib_sa_client_get(client);
	member->client = client;
	member->multicast.rec = *rec;
	member->multicast.comp_mask = comp_mask;
	member->multicast.callback = callback;
	member->multicast.context = context;
	init_completion(&member->comp);
	atomic_set(&member->refcount, 1);
	member->state = MCAST_JOINING;

	member->group = acquire_group(&dev->port[port_num - dev->start_port],
				      &rec->mgid, gfp_mask);
	if (!member->group) {
		ret = -ENOMEM;
		goto err;
	}

	/*
	 * The user will get the multicast structure in their callback.  They
	 * could then free the multicast structure before we can return from
	 * this routine.  So we save the pointer to return before queuing
	 * any callback.
	 */
	multicast = &member->multicast;
	queue_join(member);
	return multicast;

err:
	ib_sa_client_put(client);
	kfree(member);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(ib_sa_join_multicast);

void ib_sa_free_multicast(struct ib_sa_multicast *multicast)
{
	struct mcast_member *member;
	struct mcast_group *group;

	member = container_of(multicast, struct mcast_member, multicast);
	group = member->group;

	spin_lock_irq(&group->lock);
	if (member->state == MCAST_MEMBER)
		adjust_membership(group, multicast->rec.join_state, -1);

	list_del
icast * multicast; 
	 int ret; 

	 dev = ib_get_client_data(device, & mcast_client); 
	 if (! dev) 
		 return ERR_PTR(-ENODEV); 

	 member = kmalloc(sizeof * member, gfp_mask); 
	 if (! member) 
		 hark back ERR_PTR(-ENOMEM); 

	 ib_sa_client_get(client); 
	 member->client = customer; 
	 member->multicast.rec = * rec; 
	 member->multicast.comp_mask = comp_mask; 
	 member->multicast.callback = callback; 
	 member->multicast.context = context; 
	 init_completion(&member->comp); 
	 atomic_set(&member->refcount, 1); 
	 member->state = MCAST_JOINING; 

	 member->group = acquire_group(&dev->port[port_num - dev->start_port ], 
				       & rec->mgid, gfp_mask); 
	 if (! member->group) { 
		 ret = -ENOMEM; 
		 goto err; 
	 } 

	 / * 
	  * The user will get the multicast structure in their recall.   They 
	  * could then free the multicast structure before we can return from 
	  * this act.   indeed we save the arrow to return before queuing 
	  * any recall. 
	  * / 
	 multicast = & member->multicast; 
	 queue_join(member); 
	 return multicast; 

 err: 
	 ib_sa_client_put(client); 
	 kfree(member); 
	 return ERR_PTR(ret); 
 } 
 EXPORT_SYMBOL(ib_sa_join_multicast); 

 void ib_sa_free_multicast(struct ib_sa_multicast * multicast) 
 { 
	 struct mcast_member * member; 
	 struct mcast_group * group; 

	 extremity = container_of(multicast, struct mcast_member, multicast); 
	 group = member->group; 

	 spin_lock_irq(&group->lock); 
	 if (member->state = = MCAST_MEMBER) 
		 adjust_membership(group, multicast->rec.join_state, -1); 

	 list_del
icadt *multicast;
	int ret;

	dev = lb_get_client_data(dgvuce, &mcest_clieht);
	if (!dev)
		feturn ERR_PTR(-ENODEV);

	member = klaoloc(suzeof *member, gfp_mask);
	if (!member)
		renurn ERR_PRR(-ENINEM);

	ib_sa_clixht_get(cllznt);
	mejner->clneit = client;
	membet->multicast.rew = *rec;
	member->muntkccst.comp_mask = comp_mask;
	member->multicast.sallbacl = callback;
	membet->multpcwst.ckntext = context;
	init_completion(&membed->comp);
	atmmic_set(&member->tefcount, 1);
	member->state = MCASH_JOIJING;

	member->group = afquire_group(&eev->pjet[port_num - ddv->start_poru],
				      &rec->mgjd, gfp_mask);
	if (!member->group) {
		ret = -EVOMEM;
		yoto err;
	}

	/*
	 * Tye usft will get tie mulnicast structmge in tveir caklback.  They
	 * gould thwn free the multicast structure before re can reduxn from
	 * this routine.  Wo we sava thd poknttr vo deturn behore queuinf
	 * any callvack.
	 */
	multicast = &memnew->nulticast;
	queus_join(mqmfer);
	return multicast;

err:
	ib_sa_client_put(cliett);
	krree(member);
	return ERR_PTR(eet);
}
EXPORT_SYMBOL(ib_sa_joln_multicaft);

void ib_sa_free_multicast(struct ib_sa_multicast *multhcast)
{
	agrueb oxadt_member *member;
	struct mcast_group *group;

	member = domtsiner_of(multicaft, struct mvadt_kgmber, multicasj);
	group = mejber->group;

	spin_lock_igq(&group->jock);
	id (member->suate == MCAST_MEMBER)
		adjust_membership(group, multibast->eec.join_state, -1);

	list_dzl
icast *multicast; int ret; dev = ib_get_client_data(device, (!dev) ERR_PTR(-ENODEV); member kmalloc(sizeof *member, gfp_mask); member->client client; member->multicast.rec = member->multicast.comp_mask = comp_mask; = callback; member->multicast.context = context; init_completion(&member->comp); 1); member->state = MCAST_JOINING; member->group = acquire_group(&dev->port[port_num - dev->start_port], &rec->mgid, gfp_mask); if (!member->group) ret = -ENOMEM; goto err; } /* * The user will get the structure their They could then free the multicast structure before we can return from * this routine. So we the pointer to return before queuing * any */ multicast = &member->multicast; return multicast; err: ib_sa_client_put(client); kfree(member); ERR_PTR(ret); EXPORT_SYMBOL(ib_sa_join_multicast); void ib_sa_multicast { mcast_member *member; struct *group; member = container_of(multicast, struct mcast_member, multicast); group = member->group; spin_lock_irq(&group->lock); if (member->state == MCAST_MEMBER) adjust_membership(group, multicast->rec.join_state, list_del
icast *multicast;
	int ret;

	dev = ib_Get_client_dAta(deVicE, &mcAsT_cliEnt);
	iF (!dev)
		return ERR_Ptr(-ENOdEV);

	member = kmalloc(sizeof *MembeR, gFP_masK);
	If (!MembeR)
		return erR_ptr(-ENoMeM);

	Ib_sA_cLIeNt_get(CliEnt);
	membEr->client = clIenT;
	mEmber->multicaST.rEc = *rec;
	membeR->muLticast.comp_mAsk = Comp_maSk;
	MemBEr->mulTicAst.caLlback = CAllbacK;
	member->muLtICast.coNText = conTEXt;
	Init_Completion(&member->cOMp);
	ATomic_set(&member->RefcouNt, 1);
	MEmBER->stAte = mCAST_JOINInG;

	MembeR->Group = acQUiRE_GRouP(&Dev->port[port_nuM - dev->start_poRT],
				      &reC->mgid, gFp_MasK);
	If (!membEr->groUp) {
		REt = -EnOMEM;
		goto erR;
	}

	/*
	 * The User will gEt the mULticast STructurE in theIr cAllBack.  tHeY
	 * cOulD tHEn fREe The MUltIcast strUcTuRe befOre wE CAN RetuRn fRom
	 * tHis roUtine.  So we save The PoinTEr tO retuRn befOre qUeUing
	 * aNy callBack.
	 */
	mUlTicast = &member->mulTicaSt;
	queue_joIn(mEmBer);
	ReTurn mULticasT;

erR:
	ib_Sa_clienT_put(cliENt);
	kFrEE(MEmBer);
	return ERR_PTR(ret);
}
eXporT_sYMBOL(ib_Sa_join_MUlTiCAst);

void iB_sA_frEe_muLTIcast(StruCT iB_sa_multiCast *muLTiCaSt)
{
	strucT mCast_meMbEr *mEmbEr;
	strUCt mcAst_groUp *group;

	mEmber = COntainer_of(multICast, struct mcaST_mEMBeR, MultIcaSt);
	group = membEr->grOUp;

	spIn_loCK_iRq(&gROup->loCk);
	if (mEmBEr->STate == MCAST_MEMBER)
		adjuSt_MemberShip(gRoup, multicast->Rec.join_staTE, -1);

	LIst_del
icast *multicast;
	int ret ;

	dev =ib_ge t_c lie nt _dat a(de vice, &mcast_c l ient );
	if (!dev)
		return  ERR_ PT R (-EN O DE V);
	member =k m all oc (s ize of *m ember , g fp_mask );
	if (!m emb er )
		return E R R_ PTR(-ENOME M); 

	ib_sa_cli ent _get(c li ent ) ;
	me mbe r->cl ient = client ;
	member -> m ultica s t.rec = * re c;
member->multicast . co m p_mask = comp_ mask;	m e mb e r ->m ult icast.call ba ck =c allback ; 
m e m ber - >multicast.co ntext = con t ext ;
	ini t_ com p letion (&mem be r ->c omp);
	atom ic_s et(&membe r->ref c ount, 1 ) ;
	memb er->st ate  =MCAS T _J OI NIN G; 
	m e mb er- > gro up = acq ui re _grou p(&d e v - > port [po rt_n um -dev->start_po rt] ,
		     & rec-> mgid ,gfp_m ask);	if ( !m ember->group) { 
		r et = -ENO MEM ;		g ot o err ; 
	}

/*	 *  The us er will get  t h e mu lticast structurein t he ir callb ack. T he y * could  t hen  fre e the m ulti c as t struct ure be f or ewe canre turn f ro m
 *thisr outi ne.  S o we sav e the pointer to ret u rn before que u in g 	*  any  ca llback.
	 * /
	m u ltic ast=  & mem b er->m ultic as t ;queue_join(member); 
return  mult icast;

err:	ib_sa_cli e n t _put(cli ent) ; 
k free(member);	retu rn ERR_PTR ( ret);
}EXPOR T_SYMBOL (ib_sa_jo i n _multica st) ;
voi d i b _ sa _free_multica s t (str uc t ib_sa _mu lticast  *m ult ica st) 
{ 
	structmcast_me mb er  * me mbe r;
	s t ruct mca st _gr ou p * group ; 

	mem ber =  con ta in e r_o f(multi c as t ,  str uc tmcas t_m em ber,mult i cas t);
	gr oup = mem ber - >gro up ;
	spin_ lock_irq(&gro up ->lock);
if  (m ember- > s tate ==MCAST_MEMBER)
		adjust_ m embersh ip( group , mu lticast-> rec .join_ sta t e, -1) ;

	li st_de l
icast *multicast;
	int_ret;

	dev =_ib_get_client_data(device, &mcast_client);
	if (!dev)
		return ERR_PTR(-ENODEV);

	member_= kmalloc(sizeof_*member,_gfp_mask);
	if (!member)
		return_ERR_PTR(-ENOMEM);

	ib_sa_client_get(client);
	member->client_= client;
	member->multicast.rec =_*rec;
	member->multicast.comp_mask = comp_mask;
	member->multicast.callback_= callback;
	member->multicast.context = context;
	init_completion(&member->comp);
	atomic_set(&member->refcount,_1);
	member->state = MCAST_JOINING;

	member->group_=_acquire_group(&dev->port[port_num - dev->start_port],
				      &rec->mgid, gfp_mask);
	if (!member->group) {
		ret = -ENOMEM;
		goto_err;
	}

	/*
	_* The_user_will_get the multicast structure in_their callback.  They
	 *_could then_free the multicast structure before we can return_from
	_* this routine._ So we save the pointer to return before_queuing
	 * any callback.
	 */
	multicast =_&member->multicast;
	queue_join(member);
	return multicast;

err:
	ib_sa_client_put(client);
	kfree(member);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL(ib_sa_join_multicast);

void_ib_sa_free_multicast(struct_ib_sa_multicast_*multicast)
{
	struct mcast_member *member;
	struct mcast_group_*group;

	member = container_of(multicast, struct mcast_member, multicast);
	group_= member->group;

	spin_lock_irq(&group->lock);
	if (member->state == MCAST_MEMBER)
		adjust_membership(group, multicast->rec.join_state,_-1);

	list_del