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

📄 tape.c

📁 该文件是rt_linux
💻 C
📖 第 1 页 / 共 3 页
字号:
/*********************************************************************** *  drivers/s390/char/tape.c *    tape device driver for S/390 and zSeries tapes. * *  S390 and zSeries version *    Copyright (C) 2001 IBM Corporation *    Author(s): Carsten Otte <cotte@de.ibm.com> *               Tuan Ngo-Anh <ngoanh@de.ibm.com> * *********************************************************************** */#include "tapedefs.h"#include <linux/config.h>#include <linux/stddef.h>#include <linux/kernel.h>#include <linux/version.h>#include <linux/proc_fs.h>#include <linux/init.h>#include <asm/types.h>#include <asm/ccwcache.h>#include <asm/idals.h>#include <asm/ebcdic.h>#include <linux/compatmac.h>#ifdef MODULE#include <linux/module.h>#endif   #include <asm/debug.h>#ifdef CONFIG_S390_TAPE_DYNAMIC#include <asm/s390dyn.h>#endif#include "tape.h"#ifdef CONFIG_S390_TAPE_3490#include "tape3490.h"#endif#ifdef CONFIG_S390_TAPE_3480#include "tape3480.h"#endif#ifdef CONFIG_S390_TAPE_BLOCK#include "tapeblock.h"#endif#ifdef CONFIG_S390_TAPE_CHAR#include "tapechar.h"#endif#ifdef CONFIG_PROC_FS#include <linux/vmalloc.h>#endif#define PRINTK_HEADER "T390:"/* state handling routines */inline void tapestate_set (tape_info_t * ti, int newstate);inline int tapestate_get (tape_info_t * ti);void tapestate_event (tape_info_t * ti, int event);/* our globals */tape_info_t *first_tape_info = NULL;tape_discipline_t *first_discipline = NULL;tape_frontend_t *first_frontend = NULL;devreg_t* tape_devreg[128];int devregct=0;#ifdef TAPE_DEBUGdebug_info_t *tape_debug_area = NULL;#endifchar* state_verbose[TS_SIZE]={    "TS_UNUSED",  "TS_IDLE", "TS_DONE", "TS_FAILED",    "TS_BLOCK_INIT",    "TS_BSB_INIT",    "TS_BSF_INIT",    "TS_DSE_INIT",    "TS_EGA_INIT",    "TS_FSB_INIT",    "TS_FSF_INIT",    "TS_LDI_INIT",    "TS_LBL_INIT",    "TS_MSE_INIT",    "TS_NOP_INIT",    "TS_RBA_INIT",    "TS_RBI_INIT",    "TS_RBU_INIT",    "TS_RBL_INIT",    "TS_RDC_INIT",    "TS_RFO_INIT",    "TS_RSD_INIT",    "TS_REW_INIT",    "TS_REW_RELEASE_INIT",    "TS_RUN_INIT",    "TS_SEN_INIT",    "TS_SID_INIT",    "TS_SNP_INIT",    "TS_SPG_INIT",    "TS_SWI_INIT",    "TS_SMR_INIT",    "TS_SYN_INIT",    "TS_TIO_INIT",    "TS_UNA_INIT",    "TS_WRI_INIT",    "TS_WTM_INIT",    "TS_NOT_OPER"};char* event_verbose[TE_SIZE]= {    "TE_START", "TE_DONE", "TE_FAILED", "TE_ERROR", "TE_OTHER"};/* our root devfs handle */#ifdef CONFIG_DEVFS_FSdevfs_handle_t tape_devfs_root_entry;inline voidtape_mkdevfsroots (tape_info_t* ti) {    char devno [5];    sprintf (devno,"%04x",ti->devinfo.devno);    ti->devfs_dir=devfs_mk_dir (tape_devfs_root_entry, devno, ti);}inline voidtape_rmdevfsroots (tape_info_t* ti){    devfs_unregister (ti->devfs_dir);}#endif#ifdef CONFIG_PROC_FS/* our proc tapedevices entry */static struct proc_dir_entry *tape_devices_entry;typedef struct {	char *data;	int len;} tempinfo_t;static inttape_devices_open (struct inode *inode, struct file *file){    int size=80;    tape_info_t* ti;    tempinfo_t* tempinfo;    char* data;    int pos=0;    tempinfo = kmalloc (sizeof(tempinfo_t),GFP_KERNEL);    if (!tempinfo)        return -ENOMEM;    for (ti=first_tape_info;ti!=NULL;ti=ti->next)        size+=80; // FIXME: Guess better!    data=vmalloc(size);    if (!data) {        kfree (tempinfo);        return -ENOMEM;    }    pos+=sprintf(data+pos,"TapeNo\tDevNo\tCuType\tCuModel\tDevType\tDevModel\tState\n");    for (ti=first_tape_info;ti!=NULL;ti=ti->next) {        pos+=sprintf(data+pos,"%d\t%04X\t%04X\t%02X\t%04X\t%02X\t\t%s\n",ti->rew_minor/2,                     ti->devinfo.devno,ti->devinfo.sid_data.cu_type,                     ti->devinfo.sid_data.cu_model,ti->devinfo.sid_data.dev_type,                     ti->devinfo.sid_data.dev_model,((tapestate_get(ti) >= 0) &&                                                       (tapestate_get(ti) < TS_SIZE)) ?                     state_verbose[tapestate_get (ti)] : "TS UNKNOWN");    }    tempinfo->len=pos;    tempinfo->data=data;    file->private_data= (void*) tempinfo;#ifdef MODULE    MOD_INC_USE_COUNT;#endif    return 0;}static ssize_ttape_devices_read (struct file *file, char *user_buf, size_t user_len, loff_t * offset){	loff_t len;	tempinfo_t *p_info = (tempinfo_t *) file->private_data;	if (*offset >= p_info->len) {		return 0;	/* EOF */	} else {		len =  user_len<(p_info->len - *offset)?user_len:(p_info->len - *offset);		if (copy_to_user (user_buf, &(p_info->data[*offset]), len))			return -EFAULT;		(*offset) += len;		return len;	/* number of bytes "read" */	}}static inttape_devices_release (struct inode *inode, struct file *file){	int rc = 0;	tempinfo_t *p_info = (tempinfo_t *) file->private_data;	if (p_info) {		if (p_info->data)			vfree (p_info->data);		kfree (p_info);	}#ifdef MODULE        MOD_DEC_USE_COUNT;#endif	return rc;}static struct file_operations tape_devices_file_ops ={	read:tape_devices_read,	/* read */	open:tape_devices_open,	/* open */	release:tape_devices_release,	/* close */};static struct inode_operations tape_devices_inode_ops ={#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))	default_file_ops:&tape_devices_file_ops		/* file ops */#endif				/* LINUX_IS_24 */};#endif /* CONFIG_PROC_FS *//* SECTION: Parameters for tape */char *tape[256] = { NULL, };#ifndef MODULEstatic char tape_parm_string[1024] __initdata = { 0, };static voidtape_split_parm_string (char *str){	char *tmp = str;	int count = 0;	while (tmp != NULL && *tmp != '\0') {		char *end;		int len;		end = strchr (tmp, ',');		if (end == NULL) {			len = strlen (tmp) + 1;		} else {			len = (long) end - (long) tmp + 1;			*end = '\0';			end++;		}		tape[count] = kmalloc (len * sizeof (char), GFP_ATOMIC);		if (tape[count] == NULL) {			printk (KERN_WARNING PRINTK_HEADER				"can't store tape= parameter no %d\n",				count + 1);			break;		}		memset (tape[count], 0, len * sizeof (char));		memcpy (tape[count], tmp, len * sizeof (char));		count++;		tmp = end;	};}void __inittape_parm_setup (char *str, int *ints){	int len = strlen (tape_parm_string);	if (len != 0) {		strcat (tape_parm_string, ",");	}	strcat (tape_parm_string, str);}int __inittape_parm_call_setup (char *str){	int dummy;	tape_parm_setup (str, &dummy);	return 1;}#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,2,16))__setup("tape=", tape_parm_call_setup);#endif   /* kernel <2.2.19 */#endif   /* not defined MODULE */static inline inttape_parm_strtoul (char *str, char **stra){	char *temp = str;	int val;	if (*temp == '0') {		temp++;		/* strip leading zero */		if (*temp == 'x')			temp++;	/* strip leading x */	}	val = simple_strtoul (temp, &temp, 16);	/* interpret anything as hex */	*stra = temp;	return val;}static inline devreg_t *tape_create_devreg (int devno){	devreg_t *devreg = kmalloc (sizeof (devreg_t), GFP_KERNEL);	if (devreg != NULL) {		memset (devreg, 0, sizeof (devreg_t));		devreg->ci.devno = devno;		devreg->flag = DEVREG_TYPE_DEVNO;		devreg->oper_func = tape_oper_handler;	}	return devreg;}static inline voidtape_parm_parse (char **str){	char *temp;	int from, to,i,irq=0,rc,retries=0,tape_num=0;        s390_dev_info_t dinfo;        tape_info_t* ti,*tempti;        tape_discipline_t* disc;        long lockflags;	if (*str==NULL) {            /* no params present -> leave */            return;	}	while (*str) {		temp = *str;		from = 0;		to = 0;                /* turn off autodetect mode, if any range is present */                from = tape_parm_strtoul (temp, &temp);                to = from;                if (*temp == '-') {                    temp++;                    to = tape_parm_strtoul (temp, &temp);                }                for (i=from;i<=to;i++) {                    retries=0;                    // register for attch/detach of a devno                    tape_devreg[devregct]=tape_create_devreg(i);                    if (tape_devreg[devregct]==NULL) {                        PRINT_WARN ("Could not create devreg for devno %04x, dyn. attach for this devno deactivated.\n",i);                    } else {                        s390_device_register (tape_devreg[devregct++]);                    }                    // we are activating a device if it is present                    for (irq = get_irq_first(); irq!=-ENODEV; irq=get_irq_next(irq)) {                        rc = get_dev_info_by_irq (irq, &dinfo);                                             disc = first_discipline;                        while ((dinfo.devno == i) && (disc != NULL) && (disc->cu_type != dinfo.sid_data.cu_type))                            disc = (tape_discipline_t *) (disc->next);                        if ((disc == NULL) || (rc == -ENODEV) || (i!=dinfo.devno)) {                            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");

⌨️ 快捷键说明

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