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

📄 commsup.c

📁 h内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		hw_fib->header.XferState |= cpu_to_le32(HighPriority);		qid = AdapHighCmdQueue;	} else {		hw_fib->header.XferState |= cpu_to_le32(NormalPriority);		qid = AdapNormCmdQueue;	}	q = &dev->queues->queue[qid];	if(wait)		spin_lock_irqsave(&fibptr->event_lock, flags);	if(aac_queue_get( dev, &index, qid, hw_fib, 1, fibptr, &nointr)<0)		return -EWOULDBLOCK;	dprintk((KERN_DEBUG "fib_send: inserting a queue entry at index %d.\n",index));	dprintk((KERN_DEBUG "Fib contents:.\n"));	dprintk((KERN_DEBUG "  Command =               %d.\n", hw_fib->header.Command));	dprintk((KERN_DEBUG "  XferState  =            %x.\n", hw_fib->header.XferState));	dprintk((KERN_DEBUG "  hw_fib va being sent=%p\n",fibptr->hw_fib));	dprintk((KERN_DEBUG "  hw_fib pa being sent=%lx\n",(ulong)fibptr->hw_fib_pa));	dprintk((KERN_DEBUG "  fib being sent=%p\n",fibptr));	/*	 *	Fill in the Callback and CallbackContext if we are not	 *	going to wait.	 */	if (!wait) {		fibptr->callback = callback;		fibptr->callback_data = callback_data;	}	FIB_COUNTER_INCREMENT(aac_config.FibsSent);	list_add_tail(&fibptr->queue, &q->pendingq);	q->numpending++;	fibptr->done = 0;	fibptr->flags = 0;	if(aac_insert_entry(dev, index, qid, (nointr & aac_config.irq_mod)) < 0)		return -EWOULDBLOCK;	/*	 *	If the caller wanted us to wait for response wait now. 	 */    	if (wait) {		spin_unlock_irqrestore(&fibptr->event_lock, flags);		down(&fibptr->event_wait);		if(fibptr->done == 0)			BUG();					if((fibptr->flags & FIB_CONTEXT_FLAG_TIMED_OUT)){			return -ETIMEDOUT;		} else {			return 0;		}	}	/*	 *	If the user does not want a response than return success otherwise	 *	return pending	 */	if (reply)		return -EINPROGRESS;	else		return 0;}/**  *	aac_consumer_get	-	get the top of the queue *	@dev: Adapter *	@q: Queue *	@entry: Return entry * *	Will return a pointer to the entry on the top of the queue requested that * 	we are a consumer of, and return the address of the queue entry. It does *	not change the state of the queue.  */int aac_consumer_get(struct aac_dev * dev, struct aac_queue * q, struct aac_entry **entry){	u32 index;	int status;	if (le32_to_cpu(*q->headers.producer) == le32_to_cpu(*q->headers.consumer)) {		status = 0;	} else {		/*		 *	The consumer index must be wrapped if we have reached		 *	the end of the queue, else we just use the entry		 *	pointed to by the header index		 */		if (le32_to_cpu(*q->headers.consumer) >= q->entries) 			index = 0;				else		        index = le32_to_cpu(*q->headers.consumer);		*entry = q->base + index;		status = 1;	}	return(status);}int aac_consumer_avail(struct aac_dev *dev, struct aac_queue * q){	return (le32_to_cpu(*q->headers.producer) != le32_to_cpu(*q->headers.consumer));}/** *	aac_consumer_free	-	free consumer entry *	@dev: Adapter *	@q: Queue *	@qid: Queue ident * *	Frees up the current top of the queue we are a consumer of. If the *	queue was full notify the producer that the queue is no longer full. */void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid){	int wasfull = 0;	u32 notify;	if ((le32_to_cpu(*q->headers.producer)+1) == le32_to_cpu(*q->headers.consumer))		wasfull = 1;        	if (le32_to_cpu(*q->headers.consumer) >= q->entries)		*q->headers.consumer = cpu_to_le32(1);	else		*q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1);        	if (wasfull) {		switch (qid) {		case HostNormCmdQueue:			notify = HostNormCmdNotFull;			break;		case HostHighCmdQueue:			notify = HostHighCmdNotFull;			break;		case HostNormRespQueue:			notify = HostNormRespNotFull;			break;		case HostHighRespQueue:			notify = HostHighRespNotFull;			break;		default:			BUG();			return;		}		aac_adapter_notify(dev, notify);	}}        /** *	fib_adapter_complete	-	complete adapter issued fib *	@fibptr: fib to complete *	@size: size of fib * *	Will do all necessary work to complete a FIB that was sent from *	the adapter. */int fib_adapter_complete(struct fib * fibptr, unsigned short size){	struct hw_fib * hw_fib = fibptr->hw_fib;	struct aac_dev * dev = fibptr->dev;	unsigned long nointr = 0;	if (le32_to_cpu(hw_fib->header.XferState) == 0)        	return 0;	/*	 *	If we plan to do anything check the structure type first.	 */ 	if ( hw_fib->header.StructType != FIB_MAGIC ) {        	return -EINVAL;	}	/*	 *	This block handles the case where the adapter had sent us a	 *	command and we have finished processing the command. We	 *	call completeFib when we are done processing the command 	 *	and want to send a response back to the adapter. This will 	 *	send the completed cdb to the adapter.	 */	if (hw_fib->header.XferState & cpu_to_le32(SentFromAdapter)) {	        hw_fib->header.XferState |= cpu_to_le32(HostProcessed);	        if (hw_fib->header.XferState & cpu_to_le32(HighPriority)) {        		u32 index;       			if (size) 			{				size += sizeof(struct aac_fibhdr);				if (size > le16_to_cpu(hw_fib->header.SenderSize))					return -EMSGSIZE;				hw_fib->header.Size = cpu_to_le16(size);			}			if(aac_queue_get(dev, &index, AdapHighRespQueue, hw_fib, 1, NULL, &nointr) < 0) {				return -EWOULDBLOCK;			}			if (aac_insert_entry(dev, index, AdapHighRespQueue,  (nointr & (int)aac_config.irq_mod)) != 0) {			}		}		else if (hw_fib->header.XferState & NormalPriority) 		{			u32 index;			if (size) {				size += sizeof(struct aac_fibhdr);				if (size > le16_to_cpu(hw_fib->header.SenderSize)) 					return -EMSGSIZE;				hw_fib->header.Size = cpu_to_le16(size);			}			if (aac_queue_get(dev, &index, AdapNormRespQueue, hw_fib, 1, NULL, &nointr) < 0) 				return -EWOULDBLOCK;			if (aac_insert_entry(dev, index, AdapNormRespQueue, (nointr & (int)aac_config.irq_mod)) != 0) 			{			}		}	}	else 	{        	printk(KERN_WARNING "fib_adapter_complete: Unknown xferstate detected.\n");        	BUG();	}   	return 0;}/** *	fib_complete	-	fib completion handler *	@fib: FIB to complete * *	Will do all necessary work to complete a FIB. */ int fib_complete(struct fib * fibptr){	struct hw_fib * hw_fib = fibptr->hw_fib;	/*	 *	Check for a fib which has already been completed	 */	if (hw_fib->header.XferState == cpu_to_le32(0))        	return 0;	/*	 *	If we plan to do anything check the structure type first.	 */ 	if (hw_fib->header.StructType != FIB_MAGIC)	        return -EINVAL;	/*	 *	This block completes a cdb which orginated on the host and we 	 *	just need to deallocate the cdb or reinit it. At this point the	 *	command is complete that we had sent to the adapter and this	 *	cdb could be reused.	 */	if((hw_fib->header.XferState & cpu_to_le32(SentFromHost)) &&		(hw_fib->header.XferState & cpu_to_le32(AdapterProcessed)))	{		fib_dealloc(fibptr);	}	else if(hw_fib->header.XferState & cpu_to_le32(SentFromHost))	{		/*		 *	This handles the case when the host has aborted the I/O		 *	to the adapter because the adapter is not responding		 */		fib_dealloc(fibptr);	} else if(hw_fib->header.XferState & cpu_to_le32(HostOwned)) {		fib_dealloc(fibptr);	} else {		BUG();	}   	return 0;}/** *	aac_printf	-	handle printf from firmware *	@dev: Adapter *	@val: Message info * *	Print a message passed to us by the controller firmware on the *	Adaptec board */void aac_printf(struct aac_dev *dev, u32 val){	int length = val & 0xffff;	int level = (val >> 16) & 0xffff;	char *cp = dev->printfbuf;		/*	 *	The size of the printfbuf is set in port.c	 *	There is no variable or define for it	 */	if (length > 255)		length = 255;	if (cp[length] != 0)		cp[length] = 0;	if (level == LOG_AAC_HIGH_ERROR)		printk(KERN_WARNING "aacraid:%s", cp);	else		printk(KERN_INFO "aacraid:%s", cp);	memset(cp, 0,  256);}/** *	aac_command_thread	-	command processing thread *	@dev: Adapter to monitor * *	Waits on the commandready event in it's queue. When the event gets set *	it will pull FIBs off it's queue. It will continue to pull FIBs off *	until the queue is empty. When the queue is empty it will wait for *	more FIBs. */ int aac_command_thread(struct aac_dev * dev){	struct hw_fib *hw_fib, *hw_newfib;	struct fib *fib, *newfib;	struct aac_queue_block *queues = dev->queues;	struct aac_fib_context *fibctx;	unsigned long flags;	DECLARE_WAITQUEUE(wait, current);	/*	 *	We can only have one thread per adapter for AIF's.	 */	if (dev->aif_thread)		return -EINVAL;	/*	 *	Set up the name that will appear in 'ps'	 *	stored in  task_struct.comm[16].	 */	daemonize("aacraid");	allow_signal(SIGKILL);	/*	 *	Let the DPC know it has a place to send the AIF's to.	 */	dev->aif_thread = 1;	add_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);	set_current_state(TASK_INTERRUPTIBLE);	while(1) 	{		spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);		while(!list_empty(&(queues->queue[HostNormCmdQueue].cmdq))) {			struct list_head *entry;			struct aac_aifcmd * aifcmd;			set_current_state(TASK_RUNNING);					entry = queues->queue[HostNormCmdQueue].cmdq.next;			list_del(entry);						spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);			fib = list_entry(entry, struct fib, fiblink);			/*			 *	We will process the FIB here or pass it to a 			 *	worker thread that is TBD. We Really can't 			 *	do anything at this point since we don't have			 *	anything defined for this thread to do.			 */			hw_fib = fib->hw_fib;			memset(fib, 0, sizeof(struct fib));			fib->type = FSAFS_NTC_FIB_CONTEXT;			fib->size = sizeof( struct fib );			fib->hw_fib = hw_fib;			fib->data = hw_fib->data;			fib->dev = dev;			/*			 *	We only handle AifRequest fibs from the adapter.			 */			aifcmd = (struct aac_aifcmd *) hw_fib->data;			if (aifcmd->command == cpu_to_le32(AifCmdDriverNotify)) {				/* Handle Driver Notify Events */				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);				fib_adapter_complete(fib, sizeof(u32));			} else {				struct list_head *entry;				/* The u32 here is important and intended. We are using				   32bit wrapping time to fit the adapter field */				   				u32 time_now, time_last;				unsigned long flagv;								time_now = jiffies/HZ;				spin_lock_irqsave(&dev->fib_lock, flagv);				entry = dev->fib_list.next;				/*				 * For each Context that is on the 				 * fibctxList, make a copy of the				 * fib, and then set the event to wake up the				 * thread that is waiting for it.				 */				while (entry != &dev->fib_list) {					/*					 * Extract the fibctx					 */					fibctx = list_entry(entry, struct aac_fib_context, next);					/*					 * Check if the queue is getting					 * backlogged					 */					if (fibctx->count > 20)					{						/*						 * It's *not* jiffies folks,						 * but jiffies / HZ so do not						 * panic ...						 */						time_last = fibctx->jiffies;						/*						 * Has it been > 2 minutes 						 * since the last read off						 * the queue?						 */						if ((time_now - time_last) > 120) {							entry = entry->next;							aac_close_fib_context(dev, fibctx);							continue;						}					}					/*					 * Warning: no sleep allowed while					 * holding spinlock					 */					hw_newfib = kmalloc(sizeof(struct hw_fib), GFP_ATOMIC);					newfib = kmalloc(sizeof(struct fib), GFP_ATOMIC);					if (newfib && hw_newfib) {						/*						 * Make the copy of the FIB						 */						memcpy(hw_newfib, hw_fib, sizeof(struct hw_fib));						memcpy(newfib, fib, sizeof(struct fib));						newfib->hw_fib = hw_newfib;						/*						 * Put the FIB onto the						 * fibctx's fibs						 */						list_add_tail(&newfib->fiblink, &fibctx->fib_list);						fibctx->count++;						/* 						 * Set the event to wake up the						 * thread that will waiting.						 */						up(&fibctx->wait_sem);					} else {						printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");						if(newfib)							kfree(newfib);						if(hw_newfib)							kfree(hw_newfib);					}					entry = entry->next;				}				/*				 *	Set the status of this FIB				 */				*(u32 *)hw_fib->data = cpu_to_le32(ST_OK);				fib_adapter_complete(fib, sizeof(u32));				spin_unlock_irqrestore(&dev->fib_lock, flagv);			}			spin_lock_irqsave(queues->queue[HostNormCmdQueue].lock, flags);			kfree(fib);		}		/*		 *	There are no more AIF's		 */		spin_unlock_irqrestore(queues->queue[HostNormCmdQueue].lock, flags);		schedule();		if(signal_pending(current))			break;		set_current_state(TASK_INTERRUPTIBLE);	}	remove_wait_queue(&queues->queue[HostNormCmdQueue].cmdready, &wait);	dev->aif_thread = 0;	complete_and_exit(&dev->aif_completion, 0);}

⌨️ 快捷键说明

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