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

📄 commsup.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
		    container < dev->maximum_num_containers; ++container) {			if (dev->fsa_dev[container].config_waiting_on ==			    le32_to_cpu(*(u32 *)aifcmd->data))				dev->fsa_dev[container].config_waiting_on = 0;		}		break;	case AifCmdEventNotify:		switch (le32_to_cpu(((u32 *)aifcmd->data)[0])) {		/*		 *	Add an Array.		 */		case AifEnAddContainer:			container = le32_to_cpu(((u32 *)aifcmd->data)[1]);			if (container >= dev->maximum_num_containers)				break;			dev->fsa_dev[container].config_needed = ADD;			dev->fsa_dev[container].config_waiting_on =				AifEnConfigChange;			break;		/*		 *	Delete an Array.		 */		case AifEnDeleteContainer:			container = le32_to_cpu(((u32 *)aifcmd->data)[1]);			if (container >= dev->maximum_num_containers)				break;			dev->fsa_dev[container].config_needed = DELETE;			dev->fsa_dev[container].config_waiting_on =				AifEnConfigChange;			break;		/*		 *	Container change detected. If we currently are not		 * waiting on something else, setup to wait on a Config Change.		 */		case AifEnContainerChange:			container = le32_to_cpu(((u32 *)aifcmd->data)[1]);			if (container >= dev->maximum_num_containers)				break;			if (dev->fsa_dev[container].config_waiting_on)				break;			dev->fsa_dev[container].config_needed = CHANGE;			dev->fsa_dev[container].config_waiting_on =				AifEnConfigChange;			break;		case AifEnConfigChange:			break;		}		/*		 *	If we are waiting on something and this happens to be		 * that thing then set the re-configure flag.		 */		if (container != (u32)-1) {			if (container >= dev->maximum_num_containers)				break;			if (dev->fsa_dev[container].config_waiting_on ==			    le32_to_cpu(*(u32 *)aifcmd->data))				dev->fsa_dev[container].config_waiting_on = 0;		} else for (container = 0;		    container < dev->maximum_num_containers; ++container) {			if (dev->fsa_dev[container].config_waiting_on ==			    le32_to_cpu(*(u32 *)aifcmd->data))				dev->fsa_dev[container].config_waiting_on = 0;		}		break;	case AifCmdJobProgress:		/*		 *	These are job progress AIF's. When a Clear is being		 * done on a container it is initially created then hidden from		 * the OS. When the clear completes we don't get a config		 * change so we monitor the job status complete on a clear then		 * wait for a container change.		 */		if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))		 && ((((u32 *)aifcmd->data)[6] == ((u32 *)aifcmd->data)[5])		  || (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsSuccess)))) {			for (container = 0;			    container < dev->maximum_num_containers;			    ++container) {				/*				 * Stomp on all config sequencing for all				 * containers?				 */				dev->fsa_dev[container].config_waiting_on =					AifEnContainerChange;				dev->fsa_dev[container].config_needed = ADD;			}		}		if ((((u32 *)aifcmd->data)[1] == cpu_to_le32(AifJobCtrZero))		 && (((u32 *)aifcmd->data)[6] == 0)		 && (((u32 *)aifcmd->data)[4] == cpu_to_le32(AifJobStsRunning))) {			for (container = 0;			    container < dev->maximum_num_containers;			    ++container) {				/*				 * Stomp on all config sequencing for all				 * containers?				 */				dev->fsa_dev[container].config_waiting_on =					AifEnContainerChange;				dev->fsa_dev[container].config_needed = DELETE;			}		}		break;	}	device_config_needed = NOTHING;	for (container = 0; container < dev->maximum_num_containers;	    ++container) {		if ((dev->fsa_dev[container].config_waiting_on == 0)		 && (dev->fsa_dev[container].config_needed != NOTHING)) {			device_config_needed =				dev->fsa_dev[container].config_needed;			dev->fsa_dev[container].config_needed = NOTHING;			break;		}	}	if (device_config_needed == NOTHING)		return;	/*	 *	If we decided that a re-configuration needs to be done,	 * schedule it here on the way out the door, please close the door	 * behind you.	 */	busy = 0;	/*	 *	Find the scsi_device associated with the SCSI address,	 * and mark it as changed, invalidating the cache. This deals	 * with changes to existing device IDs.	 */	if (!dev || !dev->scsi_host_ptr)		return;	/*	 * force reload of disk info via probe_container	 */	if ((device_config_needed == CHANGE)	 && (dev->fsa_dev[container].valid == 1))		dev->fsa_dev[container].valid = 2;	if ((device_config_needed == CHANGE) ||			(device_config_needed == ADD))		probe_container(dev, container);	device = scsi_device_lookup(dev->scsi_host_ptr, 		CONTAINER_TO_CHANNEL(container), 		CONTAINER_TO_ID(container), 		CONTAINER_TO_LUN(container));	if (device) {		switch (device_config_needed) {		case DELETE:			scsi_remove_device(device);			break;		case CHANGE:			if (!dev->fsa_dev[container].valid) {				scsi_remove_device(device);				break;			}			scsi_rescan_device(&device->sdev_gendev);		default:			break;		}		scsi_device_put(device);	}	if (device_config_needed == ADD) {		scsi_add_device(dev->scsi_host_ptr,		  CONTAINER_TO_CHANNEL(container),		  CONTAINER_TO_ID(container),		  CONTAINER_TO_LUN(container));	}}/** *	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_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(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);	set_current_state(TASK_INTERRUPTIBLE);	dprintk ((KERN_INFO "aac_command_thread start\n"));	while(1) 	{		spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);		while(!list_empty(&(dev->queues->queue[HostNormCmdQueue].cmdq))) {			struct list_head *entry;			struct aac_aifcmd * aifcmd;			set_current_state(TASK_RUNNING);				entry = dev->queues->queue[HostNormCmdQueue].cmdq.next;			list_del(entry);					spin_unlock_irqrestore(dev->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 */				aac_handle_aif(dev, fib);				*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);				fib_adapter_complete(fib, (u16)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;				unsigned num;				struct hw_fib ** hw_fib_pool, ** hw_fib_p;				struct fib ** fib_pool, ** fib_p;							/* Sniff events */				if ((aifcmd->command == 				     cpu_to_le32(AifCmdEventNotify)) ||				    (aifcmd->command == 				     cpu_to_le32(AifCmdJobProgress))) {					aac_handle_aif(dev, fib);				} 								time_now = jiffies/HZ;				/*				 * Warning: no sleep allowed while				 * holding spinlock. We take the estimate				 * and pre-allocate a set of fibs outside the				 * lock.				 */				num = le32_to_cpu(dev->init->AdapterFibsSize)				    / sizeof(struct hw_fib); /* some extra */				spin_lock_irqsave(&dev->fib_lock, flagv);				entry = dev->fib_list.next;				while (entry != &dev->fib_list) {					entry = entry->next;					++num;				}				spin_unlock_irqrestore(&dev->fib_lock, flagv);				hw_fib_pool = NULL;				fib_pool = NULL;				if (num				 && ((hw_fib_pool = kmalloc(sizeof(struct hw_fib *) * num, GFP_KERNEL)))				 && ((fib_pool = kmalloc(sizeof(struct fib *) * num, GFP_KERNEL)))) {					hw_fib_p = hw_fib_pool;					fib_p = fib_pool;					while (hw_fib_p < &hw_fib_pool[num]) {						if (!(*(hw_fib_p++) = kmalloc(sizeof(struct hw_fib), GFP_KERNEL))) {							--hw_fib_p;							break;						}						if (!(*(fib_p++) = kmalloc(sizeof(struct fib), GFP_KERNEL))) {							kfree(*(--hw_fib_p));							break;						}					}					if ((num = hw_fib_p - hw_fib_pool) == 0) {						kfree(fib_pool);						fib_pool = NULL;						kfree(hw_fib_pool);						hw_fib_pool = NULL;					}				} else {					kfree(hw_fib_pool);					hw_fib_pool = NULL;				}				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.				 */				hw_fib_p = hw_fib_pool;				fib_p = fib_pool;				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					 */					if (hw_fib_p < &hw_fib_pool[num]) {						hw_newfib = *hw_fib_p;						*(hw_fib_p++) = NULL;						newfib = *fib_p;						*(fib_p++) = NULL;						/*						 * 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 is waiting.						 */						up(&fibctx->wait_sem);					} else {						printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");					}					entry = entry->next;				}				/*				 *	Set the status of this FIB				 */				*(__le32 *)hw_fib->data = cpu_to_le32(ST_OK);				fib_adapter_complete(fib, sizeof(u32));				spin_unlock_irqrestore(&dev->fib_lock, flagv);				/* Free up the remaining resources */				hw_fib_p = hw_fib_pool;				fib_p = fib_pool;				while (hw_fib_p < &hw_fib_pool[num]) {					kfree(*hw_fib_p);					kfree(*fib_p);					++fib_p;					++hw_fib_p;				}				kfree(hw_fib_pool);				kfree(fib_pool);			}			kfree(fib);			spin_lock_irqsave(dev->queues->queue[HostNormCmdQueue].lock, flags);		}		/*		 *	There are no more AIF's		 */		spin_unlock_irqrestore(dev->queues->queue[HostNormCmdQueue].lock, flags);		schedule();		if(signal_pending(current))			break;		set_current_state(TASK_INTERRUPTIBLE);	}	if (dev->queues)		remove_wait_queue(&dev->queues->queue[HostNormCmdQueue].cmdready, &wait);	dev->aif_thread = 0;	complete_and_exit(&dev->aif_completion, 0);	return 0;}

⌨️ 快捷键说明

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