⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tape.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 3 页
字号:
#endif	/* Register IRQ */#ifdef CONFIG_S390_TAPE_DYNAMIC        rc = s390_request_irq_special (irq, tape_irq, tape_noper_handler,0, "tape", &(ti->devstat));#else	rc = s390_request_irq (irq, tape_irq, 0, "tape", &(ti->devstat));#endif	s390irq_spin_lock_irqsave (irq, lockflags);	ti->next = NULL;	if (rc)            PRINT_WARN ("Cannot register irq %d, rc=%d\n", irq, rc);	init_waitqueue_head (&ti->wq);	ti->kernbuf = ti->userbuf = ti->discdata = NULL;	tapestate_set (ti, TS_UNUSED);        ti->discdata=NULL;	ti->discipline->setup_assist (ti);        ti->wanna_wakeup=0;	s390irq_spin_unlock_irqrestore (irq, lockflags);	return rc;}/* *      tape_init will register the driver for each tape. */inttape_init (void){	long lockflags;	s390_dev_info_t dinfo;	tape_discipline_t *disc;	tape_info_t *ti = NULL, *tempti = NULL;        char *opt_char,*opt_block,*opt_3490,*opt_3480;	int irq = 0, rc, retries = 0, tape_num = 0;        static int initialized=0;        if (initialized) // Only init the devices once            return 0;        initialized=1;#ifdef TAPE_DEBUG        tape_debug_area = debug_register ( "tape", 3, 2, 10);        debug_register_view(tape_debug_area,&debug_hex_ascii_view);        debug_text_event (tape_debug_area,3,"begin init");#endif /* TAPE_DEBUG */        /* print banner */                PRINT_WARN ("IBM S/390 Tape Device Driver (v1.01).\n");        PRINT_WARN ("(C) IBM Deutschland Entwicklung GmbH, 2000\n");        opt_char=opt_block=opt_3480=opt_3490="not present";#ifdef CONFIG_S390_TAPE_CHAR        opt_char="built in";#endif#ifdef CONFIG_S390_TAPE_BLOCK        opt_block="built in";#endif#ifdef CONFIG_S390_TAPE_3480        opt_3480="built in";#endif#ifdef CONFIG_S390_TAPE_3490        opt_3490="built in";#endif        /* print feature info */        PRINT_WARN ("character device frontend   : %s\n",opt_char);        PRINT_WARN ("block device frontend       : %s\n",opt_block);        PRINT_WARN ("support for 3480 compatible : %s\n",opt_3480);        PRINT_WARN ("support for 3490 compatible : %s\n",opt_3490);        #ifndef MODULE        tape_split_parm_string(tape_parm_string);#endif        if (*tape)             PRINT_INFO ("Using ranges supplied in parameters, disabling autoprobe mode.\n");        else            PRINT_INFO ("No parameters supplied, enabling autoprobe mode for all supported devices.\n");#ifdef CONFIG_S390_TAPE_3490        if (*tape)            first_discipline = tape3490_init (0); // no autoprobe for devices        else            first_discipline = tape3490_init (1); // do autoprobe since no parm specified	first_discipline->next = NULL;#endif#ifdef CONFIG_S390_TAPE_3480        if (first_discipline == NULL) {            if (*tape)                first_discipline = tape3480_init (0); // no autoprobe for devices            else                 first_discipline = tape3480_init (1); // do autoprobe since no parm specified            first_discipline->next = NULL;        } else {            if (*tape)                first_discipline->next = tape3480_init (0); // no autoprobe for devices            else                first_discipline->next = tape3480_init (1); // do autoprobe since no parm specified            ((tape_discipline_t*) (first_discipline->next))->next=NULL;        }#endif#ifdef CONFIG_DEVFS_FS        tape_devfs_root_entry=devfs_mk_dir (NULL, "tape", NULL);#endif CONFIG_DEVFS_FS#ifdef TAPE_DEBUG        debug_text_event (tape_debug_area,3,"dev detect");#endif /* TAPE_DEBUG */	/* Allocate the tape structures */        if (*tape!=NULL) {            // we have parameters, continue with parsing the parameters and set the devices online            tape_parm_parse (tape);        } else {            // we are running in autodetect mode, search all devices for compatibles            for (irq = get_irq_first(); irq!=-ENODEV; irq=get_irq_next(irq)) {		rc = get_dev_info_by_irq (irq, &dinfo);		disc = first_discipline;		while ((disc != NULL) && (disc->cu_type != dinfo.sid_data.cu_type))                    disc = (tape_discipline_t *) (disc->next);		if ((disc == NULL) || (rc == -ENODEV))                    continue;#ifdef TAPE_DEBUG                debug_text_event (tape_debug_area,3,"det irq:  ");                debug_int_event (tape_debug_area,3,irq);                debug_text_event (tape_debug_area,3,"cu:       ");                debug_int_event (tape_debug_area,3,disc->cu_type);#endif /* TAPE_DEBUG */                PRINT_INFO ("using devno %04x with discipline %04x on irq %d as tape device %d\n",dinfo.devno,dinfo.sid_data.cu_type,irq,tape_num/2);		/* Allocate tape structure  */		ti = kmalloc (sizeof (tape_info_t), GFP_ATOMIC);		if (ti == NULL) {#ifdef TAPE_DEBUG                    debug_text_exception (tape_debug_area,3,"ti:no mem ");#endif /* TAPE_DEBUG */                    PRINT_INFO ("tape: can't allocate memory for "				    "tape info structure\n");                    continue;		}		memset(ti,0,sizeof(tape_info_t));		ti->discipline = disc;		disc->tape = ti;		rc = tape_setup (ti, irq, tape_num);		if (rc) {#ifdef TAPE_DEBUG                    debug_text_event (tape_debug_area,3,"tsetup err");                    debug_int_exception (tape_debug_area,3,rc);#endif /* TAPE_DEBUG */                    kfree (ti);		} else {                    s390irq_spin_lock_irqsave (irq, lockflags);                    if (first_tape_info == NULL) {                        first_tape_info = ti;                    } else {                        tempti = first_tape_info;                        while (tempti->next != NULL)                            tempti = tempti->next;                        tempti->next = ti;                    }                    tape_num += 2;                    s390irq_spin_unlock_irqrestore (irq, lockflags);		}            }        }            	/* Allocate local buffer for the ccwcache       */	tape_init_emergency_req ();#ifdef CONFIG_PROC_FS#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))	tape_devices_entry = create_proc_entry ("tapedevices",						S_IFREG | S_IRUGO | S_IWUSR,						&proc_root);	tape_devices_entry->proc_fops = &tape_devices_file_ops;	tape_devices_entry->proc_iops = &tape_devices_inode_ops;#else	tape_devices_entry = (struct proc_dir_entry *) kmalloc             (sizeof (struct proc_dir_entry), GFP_ATOMIC);        if (tape_devices_entry) {            memset (tape_devices_entry, 0, sizeof (struct proc_dir_entry));            tape_devices_entry->name = "tapedevices";            tape_devices_entry->namelen = strlen ("tapedevices");            tape_devices_entry->low_ino = 0;            tape_devices_entry->mode = (S_IFREG | S_IRUGO | S_IWUSR);            tape_devices_entry->nlink = 1;            tape_devices_entry->uid = 0;            tape_devices_entry->gid = 0;            tape_devices_entry->size = 0;            tape_devices_entry->get_info = NULL;            tape_devices_entry->ops = &tape_devices_inode_ops;            proc_register (&proc_root, tape_devices_entry);	}#endif#endif /* CONFIG_PROC_FS */	return 0;}#ifdef MODULEMODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte (cotte@de.ibm.com)");MODULE_DESCRIPTION("Linux for S/390 channel attached tape device driver");MODULE_PARM (tape, "1-" __MODULE_STRING (256) "s");intinit_module (void){#ifdef CONFIG_S390_TAPE_CHAR	tapechar_init ();#endif#ifdef CONFIG_S390_TAPE_BLOCK	tapeblock_init ();#endif        return 0;}voidcleanup_module (void){        tape_info_t *ti ,*temp;        tape_frontend_t* frontend, *tempfe;        tape_discipline_t* disc ,*tempdi;        int i;#ifdef TAPE_DEBUG        debug_text_event (tape_debug_area,6,"cleaup mod");#endif /* TAPE_DEBUG */        if (*tape) {            // we are running with parameters. we'll now deregister from our devno's            for (i=0;i<devregct;i++) {                s390_device_unregister(tape_devreg[devregct]);            }        }	ti = first_tape_info;	while (ti != NULL) {		temp = ti;		ti = ti->next;                //cleanup a device #ifdef TAPE_DEBUG                debug_text_event (tape_debug_area,6,"free irq:");                debug_int_event (tape_debug_area,6,temp->devinfo.irq);#endif /* TAPE_DEBUG */		free_irq (temp->devinfo.irq, &(temp->devstat));                if (temp->discdata) kfree (temp->discdata);                if (temp->kernbuf) kfree (temp->kernbuf);                if (temp->cqr) tape_free_request(temp->cqr);#ifdef CONFIG_DEVFS_FS                for (frontend=first_frontend;frontend!=NULL;frontend=frontend->next)                    frontend->rmdevfstree(temp);                tape_rmdevfsroots(temp);#endif		kfree (temp);	}#ifdef CONFIG_DEVFS_FS        devfs_unregister (tape_devfs_root_entry);#endif CONFIG_DEVFS_FS#ifdef CONFIG_PROC_FS#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))	remove_proc_entry ("tapedevices", &proc_root);#else	proc_unregister (&proc_root, tape_devices_entry->low_ino);	kfree (tape_devices_entry);#endif				/* LINUX_IS_24 */#endif #ifdef CONFIG_S390_TAPE_CHAR	tapechar_uninit();#endif#ifdef CONFIG_S390_TAPE_BLOCK        tapeblock_uninit();#endif        frontend=first_frontend;	while (frontend != NULL) {		tempfe = frontend;		frontend = frontend->next;		kfree (tempfe);	}        disc=first_discipline;	while (disc != NULL) {                if (*tape)                    disc->shutdown(0);                else                    disc->shutdown(1);		tempdi = disc;		disc = disc->next;		kfree (tempdi);	}	/* Deallocate the local buffer for the ccwcache         */	tape_cleanup_emergency_req ();#ifdef TAPE_DEBUG        debug_unregister (tape_debug_area);#endif /* TAPE_DEBUG */}#endif				/* MODULE */inline voidtapestate_set (tape_info_t * ti, int newstate){    if (ti->tape_state == TS_NOT_OPER) {#ifdef TAPE_DEBUG        debug_text_event (tape_debug_area,3,"ts_set err");        debug_text_exception (tape_debug_area,3,"dev n.oper");#endif /* TAPE_DEBUG */    } else {#ifdef TAPE_DEBUG        debug_text_event (tape_debug_area,4,"ts. dev:  ");        debug_int_event (tape_debug_area,4,ti->blk_minor);        debug_text_event (tape_debug_area,4,"old ts:   ");        debug_text_event (tape_debug_area,4,(((tapestate_get (ti) < TS_SIZE) &&                                             (tapestate_get (ti) >=0 )) ?                                            state_verbose[tapestate_get (ti)] :                                            "UNKNOWN TS"));        debug_text_event (tape_debug_area,4,"new ts:   ");        debug_text_event (tape_debug_area,4,(((newstate < TS_SIZE) &&                                              (newstate >= 0)) ?                                             state_verbose[newstate] :                                             "UNKNOWN TS"));#endif /* TAPE_DEBUG */	ti->tape_state = newstate;    }}inline inttapestate_get (tape_info_t * ti){	return (ti->tape_state);}voidtapestate_event (tape_info_t * ti, int event){#ifdef TAPE_DEBUG        debug_text_event (tape_debug_area,6,"te! dev:  ");        debug_int_event (tape_debug_area,6,ti->blk_minor);        debug_text_event (tape_debug_area,6,"event:");        debug_text_event (tape_debug_area,6,((event >=0) &&                                            (event < TE_SIZE)) ?                         event_verbose[event] : "TE UNKNOWN");        debug_text_event (tape_debug_area,6,"state:");        debug_text_event (tape_debug_area,6,((tapestate_get(ti) >= 0) &&                                            (tapestate_get(ti) < TS_SIZE)) ?                         state_verbose[tapestate_get (ti)] :                         "TS UNKNOWN");#endif /* TAPE_DEBUG */            if (event == TE_ERROR) {             ti->discipline->error_recovery(ti);        } else {            if ((event >= 0) &&                (event < TE_SIZE) &&                (tapestate_get (ti) >= 0) &&                (tapestate_get (ti) < TS_SIZE) &&                ((*(ti->discipline->event_table))[tapestate_get (ti)][event] != NULL))		((*(ti->discipline->event_table))[tapestate_get (ti)][event]) (ti);            else {#ifdef TAPE_DEBUG                debug_text_exception (tape_debug_area,3,"TE UNEXPEC");#endif /* TAPE_DEBUG */		ti->discipline->default_handler (ti);            }        }}/* * Overrides for Emacs so that we follow Linus's tabbing style. * Emacs will notice this stuff at the end of the file and automatically * adjust the settings for this buffer only.  This must remain at the end * of the file. * --------------------------------------------------------------------------- * Local variables: * c-indent-level: 4 * c-brace-imaginary-offset: 0 * c-brace-offset: -4 * c-argdecl-indent: 4 * c-label-offset: -4 * c-continued-statement-offset: 4 * c-continued-brace-offset: 0 * indent-tabs-mode: nil * tab-width: 8 * End: */

⌨️ 快捷键说明

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