日本免费全黄少妇一区二区三区-高清无码一区二区三区四区-欧美中文字幕日韩在线观看-国产福利诱惑在线网站-国产中文字幕一区在线-亚洲欧美精品日韩一区-久久国产精品国产精品国产-国产精久久久久久一区二区三区-欧美亚洲国产精品久久久久

FreeBSD 5 內(nèi)核源代碼分析之中斷處理( 三 )


int ih_flags;
const char *ih_name; /* Name of handler. */
struct ithd *ih_ithread; /* Ithread we are connected to. */
int ih_need; /* Needs service. */
TAILQ_ENTRY(intrhand) ih_next; /* Next handler for this vector. */
u_char ih_pri; /* Priority of this handler. */
};

/* Interrupt handle flags kept in ih_flags */
#define IH_FAST 0x00000001 /* Fast interrupt. */
#define IH_EXCLUSIVE 0x00000002 /* Exclusive interrupt. */
#define IH_ENTROPY 0x00000004 /* Device is a good entropy source. */
#define IH_DEAD 0x00000008 /* Handler should be removed. */
#define IH_MPSAFE 0x80000000 /* Handler does not need Giant. */

這里有幾個(gè)flag值值得一提 。
IH_FAST指示該中斷是快速中斷,系統(tǒng)將盡快執(zhí)行該處理函數(shù),
并不將它調(diào)度到中斷線程的上下文中運(yùn)行,也就是說(shuō)這種函數(shù)的運(yùn)行是在中斷環(huán)境下運(yùn)行,
沒有線程的上下文,是為歷史遺留的還未遷移到新中斷模式下的驅(qū)動(dòng)程序提供的 。
IH_EXCLUSIVE指示該中斷是獨(dú)占IRQ的,即不能和其他設(shè)備共享IRQ
IH_MPSAFE表明該中斷處理函數(shù)是SMP安全的 。
代碼:
int
intr_add_handler(const char *name, int vector, driver_intr_t handler,
void *arg, enum intr_type flags, void **cookIEp)
{
struct intsrc *isrc;
int error;

isrc = https://www.rkxy.com.cn/dnjc/intr_lookup_source(vector);
if (isrc =https://www.rkxy.com.cn/dnjc/= NULL)
return (EINVAL);
error = ithread_add_handler(isrc->is_ithread, name, handler, arg,
ithread_priority(flags), flags, cookiep);
if (error == 0) {
intrcnt_updatename(isrc);
isrc->is_pic->pic_enable_intr(isrc);
isrc->is_pic->pic_enable_source(isrc);
}
return (error);
}

int
ithread_add_handler(struct ithd* ithread, const char *name,
driver_intr_t handler, void *arg, u_char pri, enum intr_type flags,
void **cookiep)
{
struct intrhand *ih, *temp_ih;

if (ithread == NULL || name == NULL || handler == NULL)
return (EINVAL);

ih = malloc(sizeof(struct intrhand), M_ITHREAD, M_WAITOK | M_ZERO);
ih->ih_handler = handler;
ih->ih_argument = arg;
ih->ih_name = name;
ih->ih_ithread = ithread;
ih->ih_pri = pri;
if (flags & INTR_FAST)
ih->ih_flags = IH_FAST;
else if (flags & INTR_EXCL)
ih->ih_flags = IH_EXCLUSIVE;
if (flags & INTR_MPSAFE)
ih->ih_flags |= IH_MPSAFE;
if (flags & INTR_ENTROPY)
ih->ih_flags |= IH_ENTROPY;

mtx_lock(&ithread->it_lock);
if ((flags & INTR_EXCL) != 0 && !TAILQ_EMPTY(&ithread->it_handlers))
goto fail;
if (!TAILQ_EMPTY(&ithread->it_handlers)) {
temp_ih = TAILQ_FIRST(&ithread->it_handlers);
if (temp_ih->ih_flags & IH_EXCLUSIVE)
goto fail;
if ((ih->ih_flags & IH_FAST) && !(temp_ih->ih_flags & IH_FAST))
goto fail;
if (!(ih->ih_flags & IH_FAST) && (temp_ih->ih_flags & IH_FAST))
goto fail;
}

TAILQ_FOREACH(temp_ih, &ithread->it_handlers, ih_next)
if (temp_ih->ih_pri > ih->ih_pri)
break;
if (temp_ih == NULL)
TAILQ_INSERT_TAIL(&ithread->it_handlers, ih, ih_next);
else
TAILQ_INSERT_BEFORE(temp_ih, ih, ih_next);
ithread_update(ithread);
mtx_unlock(&ithread->it_lock);

if (cookiep != NULL)
*cookiep = ih;
CTR3(KTR_INTR, "%s: added %s to %s", __func__, ih->ih_name,
ithread->it_name);
return (0);

fail:
mtx_unlock(&ithread->it_lock);
free(ih, M_ITHREAD);
return (EINVAL);
}

1.2 8259A的登記過(guò)程

下面我們以8259A為例,看看系統(tǒng)是如何為其注冊(cè)中斷源的,即注冊(cè)INTSRC(0)~INTSRC(15) 。
描述8259A中斷控制器的數(shù)據(jù)結(jié)構(gòu)是struct atpic_intsrc,其第一個(gè)成員是一個(gè)中斷源結(jié)構(gòu),
這種類型定義方法是BSD中常用的方法,起到了面向?qū)ο缶幊讨欣^承的作用 。

由于兩個(gè)級(jí)連的8259A中斷控制器可以控制16個(gè)中斷,因此系統(tǒng)注冊(cè)16個(gè)struct atpic_intsrc 。
這些中斷響應(yīng)程序的的入口地址是IDTVEC(atpic_intr ## irq ) 。IDTVEC在.c文件中將擴(kuò)展成

推薦閱讀