⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 um_idi.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
								*) data)->hdr.features));			((diva_um_idi_ind_hdr_t *) data)->type =			    DIVA_UM_IDI_IND_FEATURES;			((diva_um_idi_ind_hdr_t *) data)->data_length = 0;			diva_data_q_ack_segment4write(&e->data,						      sizeof(diva_um_idi_ind_hdr_t));			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");			diva_os_wakeup_read(e->os_context);		}		break;	case DIVA_UM_IDI_REQ:	case DIVA_UM_IDI_REQ_MAN:	case DIVA_UM_IDI_REQ_SIG:	case DIVA_UM_IDI_REQ_NET:		DBG_TRC(("A(%d) REQ(%02d)-(%02d)-(%08x)", a->adapter_nr,			 req->Req, req->ReqCh,			 req->type & DIVA_UM_IDI_REQ_TYPE_MASK));		switch (process_idi_request(e, req)) {		case -1:			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");			return (-1);		case -2:			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");			diva_os_wakeup_read(e->os_context);			break;		default:			diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");			break;		}		break;	default:		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "write");		return (-1);	}	DBG_TRC(("A(%d) E(%08x) write=%d", a->adapter_nr, e, ret));	return (ret);}/* --------------------------------------------------------------------------			CALLBACK FROM XDI	 -------------------------------------------------------------------------- */static void diva_um_idi_xdi_callback(ENTITY * entity){	divas_um_idi_entity_t *e = DIVAS_CONTAINING_RECORD(entity,							   divas_um_idi_entity_t,							   e);	diva_os_spin_lock_magic_t old_irql;	int call_wakeup = 0;	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "xdi_callback");	if (e->e.complete == 255) {		if (!(e->status & DIVA_UM_IDI_REMOVE_PENDING)) {			diva_um_idi_stop_wdog(e);		}		if ((call_wakeup = process_idi_rc(e, e->e.Rc))) {			if (e->rc_count) {				e->rc_count--;			}		}		e->e.Rc = 0;		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "xdi_callback");		if (call_wakeup) {			diva_os_wakeup_read(e->os_context);			diva_os_wakeup_close(e->os_context);		}	} else {		if (e->status & DIVA_UM_IDI_REMOVE_PENDING) {			e->e.RNum = 0;			e->e.RNR = 2;		} else {			call_wakeup = process_idi_ind(e, e->e.Ind);		}		e->e.Ind = 0;		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "xdi_callback");		if (call_wakeup) {			diva_os_wakeup_read(e->os_context);		}	}}static int process_idi_request(divas_um_idi_entity_t * e,			       const diva_um_idi_req_hdr_t * req){	int assign = 0;	byte Req = (byte) req->Req;	dword type = req->type & DIVA_UM_IDI_REQ_TYPE_MASK;	if (!e->e.Id || !e->e.callback) {	/* not assigned */		if (Req != ASSIGN) {			DBG_ERR(("A: A(%d) E(%08x) not assigned",				 e->adapter->adapter_nr, e));			return (-1);	/* NOT ASSIGNED */		} else {			switch (type) {			case DIVA_UM_IDI_REQ_TYPE_MAN:				e->e.Id = MAN_ID;				DBG_TRC(("A(%d) E(%08x) assign MAN",					 e->adapter->adapter_nr, e));				break;			case DIVA_UM_IDI_REQ_TYPE_SIG:				e->e.Id = DSIG_ID;				DBG_TRC(("A(%d) E(%08x) assign SIG",					 e->adapter->adapter_nr, e));				break;			case DIVA_UM_IDI_REQ_TYPE_NET:				e->e.Id = NL_ID;				DBG_TRC(("A(%d) E(%08x) assign NET",					 e->adapter->adapter_nr, e));				break;			default:				DBG_ERR(("A: A(%d) E(%08x) unknown type=%08x",					 e->adapter->adapter_nr, e,					 type));				return (-1);			}		}		e->e.XNum = 1;		e->e.RNum = 1;		e->e.callback = diva_um_idi_xdi_callback;		e->e.X = &e->XData;		e->e.R = &e->RData;		assign = 1;	}	e->status |= DIVA_UM_IDI_RC_PENDING;	e->e.Req = Req;	e->e.ReqCh = (byte) req->ReqCh;	e->e.X->PLength = (word) req->data_length;	e->e.X->P = (byte *) & req[1];	/* Our buffer is safe */	DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))",		 e->adapter->adapter_nr, e, e->e.Id, e->e.Req,		 e->e.ReqCh, e->e.X->PLength));	e->rc_count++;	if (e->adapter && e->adapter->d.request) {		diva_um_idi_start_wdog(e);		(*(e->adapter->d.request)) (&e->e);	}	if (assign) {		if (e->e.Rc == OUT_OF_RESOURCES) {			/*			   XDI has no entities more, call was not forwarded to the card,			   no callback will be scheduled			 */			DBG_ERR(("A: A(%d) E(%08x) XDI out of entities",				 e->adapter->adapter_nr, e));			e->e.Id = 0;			e->e.ReqCh = 0;			e->e.RcCh = 0;			e->e.Ind = 0;			e->e.IndCh = 0;			e->e.XNum = 0;			e->e.RNum = 0;			e->e.callback = NULL;			e->e.X = NULL;			e->e.R = NULL;			write_return_code(e, ASSIGN_RC | OUT_OF_RESOURCES);			return (-2);		} else {			e->status |= DIVA_UM_IDI_ASSIGN_PENDING;		}	}	return (0);}static int process_idi_rc(divas_um_idi_entity_t * e, byte rc){	DBG_TRC(("A(%d) E(%08x) rc(%02x-%02x-%02x)",		 e->adapter->adapter_nr, e, e->e.Id, rc, e->e.RcCh));	if (e->status & DIVA_UM_IDI_ASSIGN_PENDING) {		e->status &= ~DIVA_UM_IDI_ASSIGN_PENDING;		if (rc != ASSIGN_OK) {			DBG_ERR(("A: A(%d) E(%08x) ASSIGN failed",				 e->adapter->adapter_nr, e));			e->e.callback = NULL;			e->e.Id = 0;			e->e.Req = 0;			e->e.ReqCh = 0;			e->e.Rc = 0;			e->e.RcCh = 0;			e->e.Ind = 0;			e->e.IndCh = 0;			e->e.X = NULL;			e->e.R = NULL;			e->e.XNum = 0;			e->e.RNum = 0;		}	}	if ((e->e.Req == REMOVE) && e->e.Id && (rc == 0xff)) {		DBG_ERR(("A: A(%d) E(%08x)  discard OK in REMOVE",			 e->adapter->adapter_nr, e));		return (0);	/* let us do it in the driver */	}	if ((e->e.Req == REMOVE) && (!e->e.Id)) {	/* REMOVE COMPLETE */		e->e.callback = NULL;		e->e.Id = 0;		e->e.Req = 0;		e->e.ReqCh = 0;		e->e.Rc = 0;		e->e.RcCh = 0;		e->e.Ind = 0;		e->e.IndCh = 0;		e->e.X = NULL;		e->e.R = NULL;		e->e.XNum = 0;		e->e.RNum = 0;		e->rc_count = 0;	}	if ((e->e.Req == REMOVE) && (rc != 0xff)) {	/* REMOVE FAILED */		DBG_ERR(("A: A(%d) E(%08x)  REMOVE FAILED",			 e->adapter->adapter_nr, e));	}	write_return_code(e, rc);	return (1);}static int process_idi_ind(divas_um_idi_entity_t * e, byte ind){	int do_wakeup = 0;	if (e->e.complete != 0x02) {		diva_um_idi_ind_hdr_t *pind =		    (diva_um_idi_ind_hdr_t *)		    diva_data_q_get_segment4write(&e->data);		if (pind) {			e->e.RNum = 1;			e->e.R->P = (byte *) & pind[1];			e->e.R->PLength =			    (word) (diva_data_q_get_max_length(&e->data) -				    sizeof(*pind));			DBG_TRC(("A(%d) E(%08x) ind_1(%02x-%02x-%02x)-[%d-%d]",				 e->adapter->adapter_nr, e, e->e.Id, ind,				 e->e.IndCh, e->e.RLength,				 e->e.R->PLength));		} else {			DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-RNR",				 e->adapter->adapter_nr, e, e->e.Id, ind,				 e->e.IndCh));			e->e.RNum = 0;			e->e.RNR = 1;			do_wakeup = 1;		}	} else {		diva_um_idi_ind_hdr_t *pind =		    (diva_um_idi_ind_hdr_t *) (e->e.R->P);		DBG_TRC(("A(%d) E(%08x) ind(%02x-%02x-%02x)-[%d]",			 e->adapter->adapter_nr, e, e->e.Id, ind,			 e->e.IndCh, e->e.R->PLength));		pind--;		pind->type = DIVA_UM_IDI_IND;		pind->hdr.ind.Ind = ind;		pind->hdr.ind.IndCh = e->e.IndCh;		pind->data_length = e->e.R->PLength;		diva_data_q_ack_segment4write(&e->data,					      (int) (sizeof(*pind) +						     e->e.R->PLength));		do_wakeup = 1;	}	if ((e->status & DIVA_UM_IDI_RC_PENDING) && !e->rc.count) {		do_wakeup = 0;	}	return (do_wakeup);}/* --------------------------------------------------------------------------		Write return code to the return code queue of entity	 -------------------------------------------------------------------------- */static int write_return_code(divas_um_idi_entity_t * e, byte rc){	diva_um_idi_ind_hdr_t *prc;	if (!(prc =	     (diva_um_idi_ind_hdr_t *) diva_data_q_get_segment4write(&e->rc)))	{		DBG_ERR(("A: A(%d) E(%08x) rc(%02x) lost",			 e->adapter->adapter_nr, e, rc));		e->status &= ~DIVA_UM_IDI_RC_PENDING;		return (-1);	}	prc->type = DIVA_UM_IDI_IND_RC;	prc->hdr.rc.Rc = rc;	prc->hdr.rc.RcCh = e->e.RcCh;	prc->data_length = 0;	diva_data_q_ack_segment4write(&e->rc, sizeof(*prc));	return (0);}/* --------------------------------------------------------------------------		Return amount of entries that can be bead from this entity or		-1 if adapter was removed	 -------------------------------------------------------------------------- */int diva_user_mode_idi_ind_ready(void *entity, void *os_handle){	divas_um_idi_entity_t *e;	diva_um_idi_adapter_t *a;	diva_os_spin_lock_magic_t old_irql;	int ret;	if (!entity)		return (-1);	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "ind_ready");	e = (divas_um_idi_entity_t *) entity;	a = e->adapter;	if ((!a) || (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {		/*		   Adapter was unloaded		 */		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");		return (-1);	/* adapter was removed */	}	if (e->status & DIVA_UM_IDI_REMOVED) {		/*		   entity was removed as result of adapter removal		   user should assign this entity again		 */		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");		return (-1);	}	ret = e->rc.count + e->data.count;	if ((e->status & DIVA_UM_IDI_RC_PENDING) && !e->rc.count) {		ret = 0;	}	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "ind_ready");	return (ret);}void *diva_um_id_get_os_context(void *entity){	return (((divas_um_idi_entity_t *) entity)->os_context);}int divas_um_idi_entity_assigned(void *entity){	divas_um_idi_entity_t *e;	diva_um_idi_adapter_t *a;	int ret;	diva_os_spin_lock_magic_t old_irql;	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "assigned?");	e = (divas_um_idi_entity_t *) entity;	if (!e || (!(a = e->adapter)) ||	    (e->status & DIVA_UM_IDI_REMOVED) ||	    (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?");		return (0);	}	e->status |= DIVA_UM_IDI_REMOVE_PENDING;	ret = (e->e.Id || e->rc_count	       || (e->status & DIVA_UM_IDI_ASSIGN_PENDING));	DBG_TRC(("Id:%02x, rc_count:%d, status:%08x", e->e.Id, e->rc_count,		 e->status))	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "assigned?");	return (ret);}int divas_um_idi_entity_start_remove(void *entity){	divas_um_idi_entity_t *e;	diva_um_idi_adapter_t *a;	diva_os_spin_lock_magic_t old_irql;	diva_os_enter_spin_lock(&adapter_lock, &old_irql, "start_remove");	e = (divas_um_idi_entity_t *) entity;	if (!e || (!(a = e->adapter)) ||	    (e->status & DIVA_UM_IDI_REMOVED) ||	    (a->status & DIVA_UM_IDI_ADAPTER_REMOVED)) {		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");		return (0);	}	if (e->rc_count) {		/*		   Entity BUSY		 */		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");		return (1);	}	if (!e->e.Id) {		/*		   Remove request was already pending, and arrived now		 */		diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");		return (0);	/* REMOVE was pending */	}	/*	   Now send remove request	 */	e->e.Req = REMOVE;	e->e.ReqCh = 0;	e->rc_count++;	DBG_TRC(("A(%d) E(%08x) request(%02x-%02x-%02x (%d))",		 e->adapter->adapter_nr, e, e->e.Id, e->e.Req,		 e->e.ReqCh, e->e.X->PLength));	if (a->d.request)		(*(a->d.request)) (&e->e);	diva_os_leave_spin_lock(&adapter_lock, &old_irql, "start_remove");	return (0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -