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 + -
显示快捷键?