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

📄 irlap.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
#ifdef CONFIG_IRDA_ULTRAvoid irlap_unitdata_indication(struct irlap_cb *self, struct sk_buff *skb){	IRDA_DEBUG(1, __FUNCTION__ "()\n"); 	ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);	ASSERT(skb != NULL, return;);	/* Hide LAP header from IrLMP layer */	skb_pull(skb, LAP_ADDR_HEADER+LAP_CTRL_HEADER);	skb_get(skb); /*LEVEL4*/	irlmp_link_unitdata_indication(self->notify.instance, skb);}#endif /* CONFIG_IRDA_ULTRA *//* * Function irlap_disconnect_request (void) * *    Request to disconnect connection by service user */void irlap_disconnect_request(struct irlap_cb *self) {	IRDA_DEBUG(3, __FUNCTION__ "()\n");	ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);		/* Don't disconnect until all data frames are successfully sent */	if (skb_queue_len(&self->txq) > 0) {		self->disconnect_pending = TRUE;				return;	}	/* Check if we are in the right state for disconnecting */	switch (self->state) {	case LAP_XMIT_P:        /* FALLTROUGH */	case LAP_XMIT_S:        /* FALLTROUGH */ 	case LAP_CONN:          /* FALLTROUGH */ 	case LAP_RESET_WAIT:    /* FALLTROUGH */ 	case LAP_RESET_CHECK:   		irlap_do_event(self, DISCONNECT_REQUEST, NULL, NULL);		break;	default:		IRDA_DEBUG(2, __FUNCTION__ "(), disconnect pending!\n");		self->disconnect_pending = TRUE;		break;	}}/* * Function irlap_disconnect_indication (void) * *    Disconnect request from other device * */void irlap_disconnect_indication(struct irlap_cb *self, LAP_REASON reason) {	IRDA_DEBUG(1, __FUNCTION__ "(), reason=%s\n", lap_reasons[reason]); 	ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);#ifdef CONFIG_IRDA_COMPRESSION	irda_free_compression(self);#endif	/* Flush queues */	irlap_flush_all_queues(self);		switch (reason) {	case LAP_RESET_INDICATION:		IRDA_DEBUG(1, __FUNCTION__ "(), Sending reset request!\n");		irlap_do_event(self, RESET_REQUEST, NULL, NULL);		break;	case LAP_NO_RESPONSE:	   /* FALLTROUGH */		case LAP_DISC_INDICATION:  /* FALLTROUGH */	case LAP_FOUND_NONE:       /* FALLTROUGH */	case LAP_MEDIA_BUSY:		irlmp_link_disconnect_indication(self->notify.instance, self, 						 reason, NULL);		break;	default:		ERROR(__FUNCTION__ "(), Unknown reason %d\n", reason);	}}/* * Function irlap_discovery_request (gen_addr_bit) * *    Start one single discovery operation. * */void irlap_discovery_request(struct irlap_cb *self, discovery_t *discovery) {	struct irlap_info info;		ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);	ASSERT(discovery != NULL, return;);		IRDA_DEBUG(4, __FUNCTION__ "(), nslots = %d\n", discovery->nslots);	ASSERT((discovery->nslots == 1) || (discovery->nslots == 6) ||	       (discovery->nslots == 8) || (discovery->nslots == 16), 	       return;);	  	/* Discovery is only possible in NDM mode */	if (self->state != LAP_NDM) {		IRDA_DEBUG(4, __FUNCTION__ 			   "(), discovery only possible in NDM mode\n");		irlap_discovery_confirm(self, NULL);		return;	}	/* Check if last discovery request finished in time */	if (self->discovery_log != NULL) {		hashbin_delete(self->discovery_log, (FREE_FUNC) kfree);		self->discovery_log = NULL;	}		self->discovery_log= hashbin_new(HB_LOCAL);		info.S = discovery->nslots; /* Number of slots */	info.s = 0; /* Current slot */		self->discovery_cmd = discovery;	info.discovery = discovery;		/* Check if the slot timeout is within limits */	if (sysctl_slot_timeout < 20) {		ERROR(__FUNCTION__ 		      "(), to low value for slot timeout!\n");		sysctl_slot_timeout = 20;	}	/* 	 * Highest value is actually 8, but we allow higher since	 * some devices seems to require it.	 */	if (sysctl_slot_timeout > 160) {		ERROR(__FUNCTION__ 		      "(), to high value for slot timeout!\n");		sysctl_slot_timeout = 160;	}		self->slot_timeout = sysctl_slot_timeout * HZ / 1000;		irlap_do_event(self, DISCOVERY_REQUEST, NULL, &info);}/* * Function irlap_discovery_confirm (log) * *    A device has been discovered in front of this station, we *    report directly to LMP. */void irlap_discovery_confirm(struct irlap_cb *self, hashbin_t *discovery_log) {	ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);		ASSERT(self->notify.instance != NULL, return;);		/* 	 * Check for successful discovery, since we are then allowed to clear 	 * the media busy condition (irlap p.94). This should allow us to make 	 * connection attempts much easier.	 */	if (discovery_log && HASHBIN_GET_SIZE(discovery_log) > 0)		irda_device_set_media_busy(self->netdev, FALSE);		/* Inform IrLMP */	irlmp_link_discovery_confirm(self->notify.instance, discovery_log);}/* * Function irlap_discovery_indication (log) * *    Somebody is trying to discover us! * */void irlap_discovery_indication(struct irlap_cb *self, discovery_t *discovery) {	IRDA_DEBUG(4, __FUNCTION__ "()\n");	ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);	ASSERT(discovery != NULL, return;);	ASSERT(self->notify.instance != NULL, return;);		irlmp_link_discovery_indication(self->notify.instance, discovery);}/* * Function irlap_status_indication (quality_of_link) * *     * */void irlap_status_indication(struct irlap_cb *self, int quality_of_link) {	switch (quality_of_link) {	case STATUS_NO_ACTIVITY:		MESSAGE("IrLAP, no activity on link!\n");		break;	case STATUS_NOISY:		MESSAGE("IrLAP, noisy link!\n");		break;	default:		break;	}	irlmp_status_indication(self->notify.instance,				quality_of_link, LOCK_NO_CHANGE);}/* * Function irlap_reset_indication (void) * *     * */void irlap_reset_indication(struct irlap_cb *self){	IRDA_DEBUG(1, __FUNCTION__ "()\n");	ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);		if (self->state == LAP_RESET_WAIT)		irlap_do_event(self, RESET_REQUEST, NULL, NULL);	else		irlap_do_event(self, RESET_RESPONSE, NULL, NULL);}/* * Function irlap_reset_confirm (void) * *     * */void irlap_reset_confirm(void){ 	IRDA_DEBUG(1, __FUNCTION__ "()\n");}/* * Function irlap_generate_rand_time_slot (S, s) * *    Generate a random time slot between s and S-1 where *    S = Number of slots (0 -> S-1) *    s = Current slot */int irlap_generate_rand_time_slot(int S, int s) {	static int rand;	int slot;		ASSERT((S - s) > 0, return 0;);	rand += jiffies;	rand ^= (rand << 12);	rand ^= (rand >> 20);	slot = s + rand % (S-s);		ASSERT((slot >= s) || (slot < S), return 0;);		return slot;}/* * Function irlap_update_nr_received (nr) * *    Remove all acknowledged frames in current window queue. This code is  *    not intuitive and you should not try to change it. If you think it *    contains bugs, please mail a patch to the author instead. */void irlap_update_nr_received(struct irlap_cb *self, int nr) {	struct sk_buff *skb = NULL;	int count = 0;	/*         * Remove all the ack-ed frames from the window queue.         */	/* 	 *  Optimize for the common case. It is most likely that the receiver	 *  will acknowledge all the frames we have sent! So in that case we	 *  delete all frames stored in window.	 */	if (nr == self->vs) {		while ((skb = skb_dequeue(&self->wx_list)) != NULL) {			dev_kfree_skb(skb);		}		/* The last acked frame is the next to send minus one */		self->va = nr - 1;	} else {		/* Remove all acknowledged frames in current window */		while ((skb_peek(&self->wx_list) != NULL) && 		       (((self->va+1) % 8) != nr)) 		{			skb = skb_dequeue(&self->wx_list);			dev_kfree_skb(skb);						self->va = (self->va + 1) % 8;			count++;		}	}		/* Advance window */	self->window = self->window_size - skb_queue_len(&self->wx_list);}/* * Function irlap_validate_ns_received (ns) * *    Validate the next to send (ns) field from received frame. */int irlap_validate_ns_received(struct irlap_cb *self, int ns) {	/*  ns as expected?  */	if (ns == self->vr)		return NS_EXPECTED;	/*	 *  Stations are allowed to treat invalid NS as unexpected NS	 *  IrLAP, Recv ... with-invalid-Ns. p. 84	 */	return NS_UNEXPECTED;		/* return NR_INVALID; */}/* * Function irlap_validate_nr_received (nr) * *    Validate the next to receive (nr) field from received frame. * */int irlap_validate_nr_received(struct irlap_cb *self, int nr) {	/*  nr as expected?  */	if (nr == self->vs) {		IRDA_DEBUG(4, __FUNCTION__ "(), expected!\n");		return NR_EXPECTED;	}	/*	 *  unexpected nr? (but within current window), first we check if the 	 *  ns numbers of the frames in the current window wrap.	 */	if (self->va < self->vs) {		if ((nr >= self->va) && (nr <= self->vs))			return NR_UNEXPECTED;	} else {		if ((nr >= self->va) || (nr <= self->vs)) 			return NR_UNEXPECTED;	}		/* Invalid nr!  */	return NR_INVALID;}/* * Function irlap_initiate_connection_state () * *    Initialize the connection state parameters * */void irlap_initiate_connection_state(struct irlap_cb *self) {	IRDA_DEBUG(4, __FUNCTION__ "()\n");		ASSERT(self != NULL, return;);	ASSERT(self->magic == LAP_MAGIC, return;);	/* Next to send and next to receive */	self->vs = self->vr = 0;	/* Last frame which got acked (0 - 1) % 8 */	self->va = 7;	self->window = 1;	self->remote_busy = FALSE;	self->retry_count = 0;}/* * Function irlap_wait_min_turn_around (self, qos) * *    Wait negotiated minimum turn around time, this function actually sets *    the number of BOS's that must be sent before the next transmitted *    frame in order to delay for the specified amount of time. This is *    done to avoid using timers, and the forbidden udelay! */void irlap_wait_min_turn_around(struct irlap_cb *self, struct qos_info *qos) {	__u32 min_turn_time;	__u32 speed;		/* Get QoS values.  */	speed = qos->baud_rate.value;	min_turn_time = qos->min_turn_time.value;	/* No need to calculate XBOFs for speeds over 115200 bps */	if (speed > 115200) {		self->mtt_required = min_turn_time;		return;	}		/*  	 *  Send additional BOF's for the next frame for the requested	 *  min turn time, so now we must calculate how many chars (XBOF's) we 	 *  must send for the requested time period (min turn time)	 */	self->xbofs_delay = irlap_min_turn_time_in_bytes(speed, min_turn_time);

⌨️ 快捷键说明

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