if (hw_fib_pool) kfree(hw_fib_pool); if (fib_pool) kfree(fib_pool); 
kfree(hw_fib_pool); kfree(fib_pool); 
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 if (hw_fib_pool) {					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]) {					if (*hw_fib_p)						kfree(*hw_fib_p);					if (*fib_p)						kfree(*fib_p);					++fib_p;					++hw_fib_p;				}				if (hw_fib_pool)					kfree(hw_fib_pool);				if (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;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/c9475cb0c358ff0dd473544280d92482df491913/commsup.c/clean/drivers/scsi/aacraid/commsup.c