亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? ncr5380.c

?? 內核是系統的心臟
?? C
?? 第 1 頁 / 共 5 頁
字號:
 * 1.  The mutex flag, main_running, can only be set when the main 
 *     routine can actually process data, otherwise SCSI commands
 *     will never get issued.
 *
 * 2.  NCR5380_main() shouldn't be called before it has exited, because
 *     other drivers have had kernel stack overflows in similar
 *     situations.
 *
 * 3.  We don't want to inline NCR5380_main() because of space concerns,
 *     even though it is only called in two places.
 *
 * So, the solution is to set the mutex in an inline wrapper for the 
 * main corroutine, and have the main corroutine exit with interrupts 
 * disabled after the final search through the queues so that no race 
 * conditions are possible.
 */

static volatile int main_running = 0;

/* 
 * Function : run_main(void)
 * 
 * Purpose : insure that the coroutine is running and will process our 
 * 	request.  main_running is checked/set here (in an inline function)
 *	rather than in NCR5380_main itself to reduce the chances of stack
 *	overflow.
 *
 */

static __inline__ void run_main(void) {
    cli();
    if (!main_running) {
	main_running = 1;
        NCR5380_main();
	/* 
         * main_running is cleared in NCR5380_main once it can't do 
	 * more work, and NCR5380_main exits with interrupts disabled.
	 */
	sti();
    } else 
	sti();
}

#ifdef USLEEP
#ifndef NCR5380_TIMER
#error "NCR5380_TIMER must be defined so that this type of NCR5380 driver gets a unique timer."
#endif

/*
 * These need tweaking, and would probably work best as per-device 
 * flags initialized differently for disk, tape, cd, etc devices.
 * People with broken devices are free to experiment as to what gives
 * the best results for them.
 *
 * USLEEP_SLEEP should be a minimum seek time.
 *
 * USLEEP_POLL should be a maximum rotational latency.
 */
#ifndef USLEEP_SLEEP
/* 20 ms (reasonable hard disk speed) */
#define USLEEP_SLEEP 2
#endif
/* 300 RPM (floppy speed) */
#ifndef USLEEP_POLL
#define USLEEP_POLL 20
#endif

static struct Scsi_Host * expires_first = NULL;

/* 
 * Function : int should_disconnect (unsigned char cmd)
 *
 * Purpose : decide weather a commmand would normally disconnect or 
 *	not, since if it won't disconnect we should go to sleep.
 *
 * Input : cmd - opcode of SCSI command
 *
 * Returns : DISCONNECT_LONG if we should disconnect for a really long 
 * 	time (ie always, sleep, look for REQ active, sleep), 
 *	DISCONNECT_TIME_TO_DATA if we would only disconnect for a normal
 * 	time-to-data dealy, DISCONNECT_NONE if this command would return
 * 	immediately.
 *
 *      Future sleep algorithms based on time to data can exploit 
 *      something like this so they can differentiate between "normal" 
 *	(ie, read, write, seek) and unusual commands (ie, * format).
 *
 * Note : We don't deal with commands that handle an immediate disconnect,
 *        
 */

static int should_disconnect (unsigned char cmd) {
    switch (cmd) {
    case READ_6:
    case WRITE_6:
    case SEEK_6:
    case READ_10:
    case WRITE_10:
    case SEEK_10:
	return DISCONNECT_TIME_TO_DATA;
    case FORMAT_UNIT:
    case SEARCH_HIGH:
    case SEARCH_LOW:
    case SEARCH_EQUAL:
	return DISCONNECT_LONG;
    default:
	return DISCONNECT_NONE;
    }
}

/*
 * Assumes instance->time_expires has been set in higher level code.
 */

static int NCR5380_set_timer (struct Scsi_Host *instance) {
    struct Scsi_Host *tmp, **prev;
    
    cli();
    if (((struct NCR5380_hostdata *) (instance->host_data))->next_timer) {
	sti();
	return -1;
    }

    for (prev = &expires_first, tmp = expires_first; tmp; 
	prev = &(((struct NCR5380_hostdata *) tmp->host_data)->next_timer), 
	tmp = ((struct NCR5380_hostdata *) tmp->host_data)->next_timer)
	if (instance->time_expires < tmp->time_expires) 
	    break;
	   
    instance->next_timer = tmp;
    *prev = instance;
    timer_table[NCR5380_TIMER].expires = expires_first->time_expires;
    timer_active |= 1 << NCR5380_TIMER;
    sti;
    return 0;
}    

/* Doing something about unwanted rentrancy here might be useful */
void NCR5380_timer_fn(void) {
    struct Scsi_Host *instance;
    cli();
    for (; expires_first && expires_first->time_expires >= jiffies; ) {
	instance = ((NCR5380_hostdata *) expires_first->host_data)->
	    expires_next;
	((NCR5380_hostdata *) expires_first->host_data)->expires_next = 
	    NULL;
	((NCR5380_hostdata *) expires_first->host_data)->time_expires = 
	    0;
	expires_first = instance;
    }

    if (expires_first) {
	timer_table[NCR5380_TIMER].expires = ((NCR5380_hostdata *) 
	    expires_first->host_data)->time_expires;
	timer_active |= (1 << NCR5380_TIMER);
    } else {
	timer_table[NCR5380_TIMER].expires = 0;
	timer_active &= ~(1 << MCR5380_TIMER);
    }
    sti();

    run_main();
}
#endif /* def USLEEP */

static void NCR5380_all_init (void) {
    static int done = 0;
    if (!done) {
#if (NDEBUG & NDEBUG_INIT)
	printk("scsi : NCR5380_all_init()\n");
#endif
	done = 1;
#ifdef USLEEP
	timer_table[NCR5380_TIMER].expires = 0;
	timer_table[NCR5380_TIMER].fn = NCR5380_timer_fn;
#endif
    }
}

#ifdef AUTOPROBE_IRQ
/*
 * Function : int NCR5380_probe_irq (struct Scsi_Host *instance, int possible)
 * 
 * Purpose : autoprobe for the IRQ line used by the NCR5380.  
 *
 * Inputs : instance - pointer to this instance of the NCR5380 driver,
 *          possible - bitmask of permissable interrupts.
 *
 * Returns : number of the IRQ selected, IRQ_NONE if no interrupt fired.
 * 
 * XXX no effort is made to deal with spurious interrupts. 
 */


static int probe_irq;
static void probe_intr (int sig) {
    probe_irq = sig;
};
static struct sigaction probe_sigaction = { probe_intr, 0, SA_INTERRUPT,
    NULL};

static int NCR5380_probe_irq (struct Scsi_Host *instance, int possible) {
    NCR5380_local_declare();
    struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
	 instance->hostdata;
    unsigned long timeout;
    int trying_irqs, i, mask;
    NCR5380_setup(instance);

    for (trying_irqs = i = 0, mask = 1; i < 16; ++i, mask <<= 1) 
	if ((mask & possible) &&  (irqaction (i, &probe_sigaction) 
	    == 0)) 
	    trying_irqs |= mask;

    timeout = jiffies + 25;
    probe_irq = IRQ_NONE;

/*
 * A interrupt is triggered whenever BSY = false, SEL = true
 * and a bit set in the SELECT_ENABLE_REG is asserted on the 
 * SCSI bus.
 *
 * Note that the bus is only driven when the phase control signals
 * (I/O, C/D, and MSG) match those in the TCR, so we must reset that
 * to zero.
 */

    NCR5380_write(TARGET_COMMAND_REG, 0);
    NCR5380_write(SELECT_ENABLE_REG, hostdata->id_mask);
    NCR5380_write(OUTPUT_DATA_REG, hostdata->id_mask);
    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE | ICR_ASSERT_DATA | 
	ICR_ASSERT_SEL);

    while (probe_irq == IRQ_NONE && jiffies < timeout);

    NCR5380_write(SELECT_ENABLE_REG, 0);
    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);

    for (i = 0, mask = 1; i < 16; ++i, mask <<= 1)
	if (trying_irqs & mask) 
	    free_irq(i);

    return probe_irq;
}
#endif /* AUTOPROBE_IRQ */
 
/*
 * Function : void NCR58380_print_options (struct Scsi_Host *instance)
 *
 * Purpose : called by probe code indicating the NCR5380 driver
 *	     options that were selected.
 *
 * Inputs : instance, pointer to this instance.  Unused.
 */

static void NCR5380_print_options (struct Scsi_Host *instance) {
    printk(" generic options"
#ifdef AUTOPROBE_IRQ
    " AUTOPROBE_IRQ"
#endif
#ifdef AUTOSENSE 
    " AUTOSENSE"
#endif
#ifdef DIFFERENTIAL
    " DIFFERENTIAL"
#endif
#ifdef REAL_DMA
    " REAL DMA"
#endif
#ifdef REAL_DMA_POLL
    " REAL DMA POLL"
#endif
#ifdef PARITY
    " PARITY"
#endif
#ifdef PSEUDO_DMA
    " PSEUDO DMA"
#endif
#ifdef SCSI2
    " SCSI-2"
#endif
#ifdef UNSAFE
    " UNSAFE "
#endif
    );
#ifdef USLEEP
    printk(" USLEEP, USLEEP_POLL=%d USLEEP_SLEEP=%d", USLEEP_POLL, USLEEP_SLEEP);
#endif
    printk(" generic release=%d", NCR5380_PUBLIC_RELEASE);
}


/* 
 * Function : void NCR5380_init (struct Scsi_Host *instance)
 *
 * Purpose : initializies *instance and corresponding 5380 chip.
 *
 * Inputs : instance - instantiation of the 5380 driver.  
 *
 * Notes : I assume that the host, hostno, and id bits have been
 * 	set correctly.  I don't care about the irq and other fields. 
 * 
 */

static void NCR5380_init (struct Scsi_Host *instance) {
    NCR5380_local_declare();
    int i;
    struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) 
	instance->hostdata;
    NCR5380_setup(instance);

    NCR5380_all_init();

    hostdata->id_mask = 1 << instance->this_id;
    for (i = hostdata->id_mask; i <= 0x80; i <<= 1)
	if (i > hostdata->id_mask)
	    hostdata->id_higher_mask |= i;
    for (i = 0; i < 8; ++i)
	hostdata->busy[i] = 0;
#ifdef REAL_DMA
    hostdata->dmalen = 0;
#endif
    hostdata->connected = NULL;
    hostdata->issue_queue = NULL;
    hostdata->disconnected_queue = NULL;
    hostdata->flags = FLAG_CHECK_LAST_BYTE_SENT;

    if (!the_template) {
	the_template = instance->hostt;
	first_instance = instance;
    }
	

#ifdef USLEEP
    hostdata->time_expires = 0;
    hostdata->next_timer = NULL;
#endif

#ifndef AUTOSENSE
    if ((instance->cmd_per_lun > 1) || instance->can_queue > 1)) 
	 printk("scsi%d : WARNING : support for multiple outstanding commands enabled\n"
	        "         without AUTOSENSE option, contigent alligence conditions may\n"
	        "         be incorrectly cleared.\n", instance->host_no);
#endif /* def AUTOSENSE */

    NCR5380_write(INITIATOR_COMMAND_REG, ICR_BASE);
    NCR5380_write(MODE_REG, MR_BASE);
    NCR5380_write(TARGET_COMMAND_REG, 0);
    NCR5380_write(SELECT_ENABLE_REG, 0);
}

/* 
 * Function : int NCR5380_queue_command (Scsi_Cmnd *cmd, 
 *	void (*done)(Scsi_Cmnd *)) 
 *
 * Purpose :  enqueues a SCSI command
 *
 * Inputs : cmd - SCSI command, done - function called on completion, with
 *	a pointer to the command descriptor.
 * 
 * Returns : 0
 *
 * Side effects : 
 *      cmd is added to the per instance issue_queue, with minor 
 *	twiddling done to the host specific fields of cmd.  If the 
 *	main coroutine is not running, it is restarted.
 *
 */

/* Only make static if a wrapper function is used */
#ifndef NCR5380_queue_command
static
#endif
int NCR5380_queue_command (Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *)) {
    struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *)
	cmd->host->hostdata;
    Scsi_Cmnd *tmp;

#if (NDEBUG & NDEBUG_NO_WRITE)
    switch (cmd->cmnd[0]) {
    case WRITE:
    case WRITE_10:
	printk("scsi%d : WRITE attempted with NO_WRITE debugging flag set\n",
	    instance->host_no);
	cmd->result = (DID_ERROR << 16);
	done(cmd);
	return 0;
    }
#endif /* (NDEBUG & NDEBUG_NO_WRITE) */


    /* 
     * We use the host_scribble field as a pointer to the next command  
     * in a queue 
     */

    cmd->host_scribble = NULL;
    cmd->scsi_done = done;

    cmd->result = 0;

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产片一区二区三区| 精品国产伦理网| 国产成人亚洲精品青草天美| 洋洋成人永久网站入口| 国产精品久久久久一区| 精品日韩一区二区| 3d动漫精品啪啪1区2区免费 | 五月婷婷色综合| 久久精品视频免费| 一本大道av一区二区在线播放 | 日日夜夜免费精品视频| 亚洲乱码国产乱码精品精可以看| 日本一区二区三区高清不卡| 精品99久久久久久| 精品久久五月天| 欧美精品一区二区久久久| 久久综合色天天久久综合图片| 亚洲精品一区二区三区影院| 欧美精品xxxxbbbb| 欧美精品国产精品| 日韩欧美在线不卡| 久久综合五月天婷婷伊人| 久久色.com| 国产精品久久久久久久久久久免费看| 日本一区二区在线不卡| 国产精品不卡在线观看| 夜夜嗨av一区二区三区中文字幕| 亚洲观看高清完整版在线观看| 亚洲二区在线观看| 国产在线精品免费av| 国产99久久精品| 欧美亚洲一区二区在线| 欧美成人女星排行榜| 欧美韩国一区二区| 亚洲影视在线播放| 精品一区二区日韩| 91色九色蝌蚪| 26uuuu精品一区二区| 亚洲欧洲日本在线| 日本美女视频一区二区| 成人av网站免费观看| 欧美日韩成人综合| 国产精品美日韩| 青草av.久久免费一区| 粉嫩aⅴ一区二区三区四区| 欧美精品1区2区3区| 国产精品久久久久一区二区三区| 亚洲自拍偷拍九九九| 粉嫩欧美一区二区三区高清影视| 欧美日韩三级在线| 久久久夜色精品亚洲| 丝袜亚洲另类欧美综合| 色狠狠桃花综合| 国产精品私房写真福利视频| 蜜臀精品一区二区三区在线观看| 在线一区二区视频| 亚洲欧洲三级电影| 国产成人av福利| 日韩一区二区三区三四区视频在线观看| 亚洲欧洲成人精品av97| 大尺度一区二区| 国产精品视频你懂的| 国产米奇在线777精品观看| 欧美va亚洲va国产综合| 蜜臀久久久久久久| 4438成人网| 久久疯狂做爰流白浆xx| 日韩一区二区三区免费看| 免费人成精品欧美精品| 91精品国产免费久久综合| 日韩免费性生活视频播放| 亚洲伦理在线精品| 91在线精品一区二区| 亚洲精品一卡二卡| 欧美日韩的一区二区| 久久精品国产亚洲高清剧情介绍| 日韩精品一区二区三区在线播放| 毛片av一区二区| 欧美国产一区在线| 91同城在线观看| 日韩在线一区二区| 久久久av毛片精品| 在线一区二区视频| 捆绑调教一区二区三区| 亚洲国产精品国自产拍av| 99在线精品一区二区三区| 一区二区在线观看免费视频播放 | 国产毛片精品一区| 中文字幕一区二区三区不卡 | 日本91福利区| 国产精品情趣视频| 欧美一级生活片| caoporn国产一区二区| 奇米综合一区二区三区精品视频| 国产欧美一二三区| 3d动漫精品啪啪1区2区免费 | 亚洲免费观看高清完整版在线观看 | 91亚洲精品久久久蜜桃| 久久精品99国产精品| 亚洲乱码国产乱码精品精可以看| 亚洲精品一区二区在线观看| 欧美最新大片在线看| 成人深夜在线观看| 久久激情综合网| 天堂av在线一区| 日韩久久一区二区| 欧美激情一区三区| 亚洲精品在线一区二区| 欧美日韩日日夜夜| 色网综合在线观看| gogo大胆日本视频一区| 国产一区视频导航| 首页国产欧美久久| 婷婷综合另类小说色区| 亚洲免费资源在线播放| 欧美高清在线一区| 国产精品成人免费在线| 亚洲国产精品t66y| 中文字幕+乱码+中文字幕一区| 2019国产精品| 国产亚洲人成网站| 中文字幕巨乱亚洲| 亚洲乱码一区二区三区在线观看| 亚洲欧美偷拍卡通变态| 亚洲美女免费视频| 亚洲一级二级三级| 蜜桃精品在线观看| 国产精品一区二区黑丝| av成人动漫在线观看| 91福利在线免费观看| 欧美精品乱码久久久久久按摩| 在线电影欧美成精品| 久久精品欧美一区二区三区不卡| 亚洲欧洲国产专区| 久久人人97超碰com| 欧美精品一区男女天堂| 国产日产欧美一区二区视频| 亚洲精品一二三四区| 亚洲超碰精品一区二区| 国产在线播放一区| 91丨国产丨九色丨pron| 欧美在线播放高清精品| 日韩精品资源二区在线| 亚洲欧美在线高清| 日本免费新一区视频| 99视频超级精品| 日韩欧美视频在线| 夜色激情一区二区| 国产成人精品1024| 精品久久久久久亚洲综合网| 日韩毛片精品高清免费| 久久99久久99| 欧美日韩一区成人| 国产精品女上位| 国产成人在线影院 | 91麻豆精品91久久久久久清纯| 国产女同性恋一区二区| 无码av免费一区二区三区试看| 成人综合婷婷国产精品久久蜜臀| 欧美精品一卡两卡| 亚洲线精品一区二区三区八戒| 成人黄色在线看| 日本一区二区三区四区在线视频| 日产欧产美韩系列久久99| 欧美喷水一区二区| 亚洲va韩国va欧美va精品| 日本高清不卡一区| 一区二区在线观看不卡| 成人黄动漫网站免费app| 国产精品嫩草久久久久| 成人一区二区视频| 国产精品国产三级国产aⅴ无密码| 国产一区二三区| 国产亚洲欧美中文| 国产成人在线网站| 国产精品福利电影一区二区三区四区| 成人一区二区三区| 成人欧美一区二区三区小说| 91福利国产精品| 天天综合色天天综合| 日韩一区二区电影网| 国产一区二区三区精品视频| 久久精品夜色噜噜亚洲aⅴ| 成人av电影在线网| 亚洲精品久久久蜜桃| 91精品国产综合久久精品图片| 美女视频黄 久久| 国产精品国产精品国产专区不蜜| 91丨porny丨在线| 日本中文字幕一区二区有限公司| 欧美一区二区三区四区视频| 成人综合婷婷国产精品久久蜜臀| 一区二区三区中文在线观看| 欧美mv日韩mv国产网站app| 99re热视频这里只精品| 日本vs亚洲vs韩国一区三区二区| 亚洲国产精品激情在线观看| 欧美日韩中文一区| 成人黄色综合网站| 美女视频黄a大片欧美|