hba_timer.c

来自「6440linuxDriver的源代码」· C语言 代码 · 共 207 行

C
207
字号
#include "hba_header.h"/* how long a time between which should each keeper work be done */#define KEEPER_SHIFT (HZ >> 1)static struct mv_hba_msg_queue mv_msg_queue;static struct task_struct *house_keeper_task;static int __msg_queue_state;static inline int queue_state_get(void){	return __msg_queue_state;}static inline void queue_state_set(int state){	__msg_queue_state = state;}static void hba_proc_msg(struct mv_hba_msg *pmsg){	PHBA_Extension phba;	struct scsi_device *psdev;	/* we don't do things without pmsg->data */	if (NULL == pmsg->data)		return;	phba = (PHBA_Extension) pmsg->data;		MV_DBG(DMSG_HBA, "__MV__ In hba_proc_msg.\n");	MV_ASSERT(pmsg);	switch (pmsg->msg) {	case EVENT_DEVICE_ARRIVAL:		if (scsi_add_device(phba->host, 0, pmsg->param, 0))			MV_DBG(DMSG_SCSI, 			       "__MV__ add scsi disk %d-%d-%d failed.\n",			       0, pmsg->param, 0);		else			MV_DBG(DMSG_SCSI,			       "__MV__ add scsi disk %d-%d-%d.\n",			       0, pmsg->param, 0);		break;	case EVENT_DEVICE_REMOVAL:		psdev = scsi_device_lookup(phba->host, 0, pmsg->param, 0);		if (NULL != psdev) {			MV_DBG(DMSG_SCSI, 			       "__MV__ remove scsi disk %d-%d-%d.\n",			       0, pmsg->param, 0);			scsi_remove_device(psdev);			scsi_device_put(psdev);		} else {			MV_DBG(DMSG_SCSI,			       "__MV__ no disk to remove %d-%d-%d\n",			       0, pmsg->param, 0);		}		break;	default:		break;	}}static void mv_proc_queue(void){	struct mv_hba_msg *pmsg;		/* work on queue non-stop, pre-empty me! */	queue_state_set(MSG_QUEUE_PROC);	while (1) {		MV_DBG(DMSG_HBA, "__MV__ process queue starts.\n");		spin_lock_irq(&mv_msg_queue.lock);		if (list_empty(&mv_msg_queue.tasks)) {			/* it's important we put queue_state_set here. */			queue_state_set(MSG_QUEUE_IDLE);			spin_unlock_irq(&mv_msg_queue.lock);			MV_DBG(DMSG_HBA, "__MV__ process queue ends.\n");			break;		}		pmsg = list_entry(mv_msg_queue.tasks.next, struct mv_hba_msg, msg_list);		spin_unlock_irq(&mv_msg_queue.lock);		hba_proc_msg(pmsg);				/* clean the pmsg before returning it to free?*/		pmsg->data = NULL;		spin_lock_irq(&mv_msg_queue.lock);		list_move_tail(&pmsg->msg_list, &(mv_msg_queue.free));		spin_unlock_irq(&mv_msg_queue.lock);		MV_DBG(DMSG_HBA, "__MV__ process queue ends.\n");	}}static inline MV_U32 hba_msg_queue_empty(void){	return list_empty(&(mv_msg_queue.tasks));}static int hba_house_keeper(void *data){	set_user_nice(current, -15);		while (!kthread_should_stop()) {		if (!hba_msg_queue_empty() && 		    MSG_QUEUE_IDLE == queue_state_get()) {			mv_proc_queue();		}		MV_DBG(DMSG_KERN, "house keeper goes to sleep.\n");                set_current_state(TASK_INTERRUPTIBLE);                schedule();                __set_current_state(TASK_RUNNING);		MV_DBG(DMSG_KERN, "house keeper wakes up.\n");	}		return 0;}static void hba_msg_queue_init(void){	int i;		spin_lock_init(&mv_msg_queue.lock);/* as we're in init, there should be no need to hold the spinlock*/	INIT_LIST_HEAD(&(mv_msg_queue.free));	INIT_LIST_HEAD(&(mv_msg_queue.tasks));	for (i = 0; i < MSG_QUEUE_DEPTH; i++) {		list_add_tail(&mv_msg_queue.msgs[i].msg_list, 			      &mv_msg_queue.free);	}	}void hba_house_keeper_init(void){	hba_msg_queue_init();	queue_state_set(MSG_QUEUE_IDLE);	house_keeper_task = kthread_create(hba_house_keeper, NULL, "399B4F5");	if (IS_ERR(house_keeper_task)) {		printk("Error creating kthread, out of memory?\n");		house_keeper_task = NULL;	}}void hba_house_keeper_run(void){	/* hey hey my my */}void hba_house_keeper_exit(void){	if (house_keeper_task)		kthread_stop(house_keeper_task);	house_keeper_task = NULL;}void hba_msg_insert(void *data, unsigned int msg, unsigned int param){	struct mv_hba_msg *pmsg;	unsigned long flags;	MV_DBG(DMSG_HBA, "__MV__ msg insert  %d.\n", msg);	spin_lock_irqsave(&mv_msg_queue.lock, flags);	if (list_empty(&mv_msg_queue.free)) {		/* should wreck some havoc ...*/		MV_DBG(DMSG_HBA, "-- MV -- Message queue is full.\n");		spin_unlock_irqrestore(&mv_msg_queue.lock, flags);		return;	}	pmsg = list_entry(mv_msg_queue.free.next, struct mv_hba_msg, msg_list);	pmsg->data = data;	pmsg->msg  = msg;	switch (msg) {	case EVENT_DEVICE_REMOVAL:	case EVENT_DEVICE_ARRIVAL:		pmsg->param = param;		break;	default:		pmsg->param = param;                /*(NULL==param)?0:*((unsigned int*) param);*/		break;	}	list_move_tail(&pmsg->msg_list, &mv_msg_queue.tasks);	spin_unlock_irqrestore(&mv_msg_queue.lock, flags);	if (house_keeper_task)		wake_up_process(house_keeper_task);}

⌨️ 快捷键说明

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