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

📄 tape34xx.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
/*************************************************************************** * *  drivers/s390/char/tape34xx.c *    common tape device discipline for 34xx 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/version.h>#include <linux/stddef.h>#include <linux/kernel.h>#include <asm/types.h>#include <asm/uaccess.h>#include <linux/stat.h>#include <linux/proc_fs.h>#include <asm/ccwcache.h> #include <asm/idals.h>  #ifdef CONFIG_S390_TAPE_DYNAMIC#include <asm/s390dyn.h>#endif#include <asm/debug.h>#include <linux/compatmac.h>#include "tape.h"#include "tape34xx.h"#define PRINTK_HEADER "T34xx:"tape_event_handler_t tape34xx_event_handler_table[TS_SIZE][TE_SIZE] ={    /* {START , DONE, FAILED, ERROR, OTHER } */	{NULL, tape34xx_unused_done, NULL, NULL, NULL},	/* TS_UNUSED */	{NULL, tape34xx_idle_done, NULL, NULL, NULL},	/* TS_IDLE */	{NULL, NULL, NULL, NULL, NULL},		/* TS_DONE */	{NULL, NULL, NULL, NULL, NULL},		/* TS_FAILED */	{NULL, tape34xx_block_done, NULL, NULL, NULL},		/* TS_BLOCK_INIT */	{NULL, tape34xx_bsb_init_done, NULL, NULL, NULL},	/* TS_BSB_INIT */	{NULL, tape34xx_bsf_init_done, NULL, NULL, NULL},	/* TS_BSF_INIT */	{NULL, tape34xx_dse_init_done, NULL, NULL, NULL},	/* TS_DSE_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_EGA_INIT */	{NULL, tape34xx_fsb_init_done, NULL, NULL, NULL},	/* TS_FSB_INIT */	{NULL, tape34xx_fsf_init_done, NULL, NULL, NULL},	/* TS_FSF_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_LDI_INIT */	{NULL, tape34xx_lbl_init_done, NULL, NULL, NULL},	/* TS_LBL_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_MSE_INIT */	{NULL, tape34xx_nop_init_done, NULL, NULL, NULL},	/* TS_NOP_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_RBA_INIT */	{NULL, tape34xx_rbi_init_done, NULL, NULL, NULL},	/* TS_RBI_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_RBU_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_RBL_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_RDC_INIT */	{NULL, tape34xx_rfo_init_done, NULL, NULL, NULL},	/* TS_RFO_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_RSD_INIT */	{NULL, tape34xx_rew_init_done, NULL, NULL, NULL},	/* TS_REW_INIT */	{NULL, tape34xx_rew_release_init_done, NULL, NULL, NULL},	/* TS_REW_RELEASE_IMIT */	{NULL, tape34xx_run_init_done, NULL, NULL, NULL},	/* TS_RUN_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_SEN_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_SID_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_SNP_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_SPG_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_SWI_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_SMR_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_SYN_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_TIO_INIT */	{NULL, NULL, NULL, NULL, NULL},		/* TS_UNA_INIT */	{NULL, tape34xx_wri_init_done, NULL, NULL, NULL},	/* TS_WRI_INIT */	{NULL, tape34xx_wtm_init_done, NULL, NULL, NULL},	/* TS_WTM_INIT */	{NULL, NULL, NULL, NULL, NULL}};        /* TS_NOT_OPER */inttape34xx_ioctl_overload (struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg){	return -EINVAL;		// no additional ioctls}ccw_req_t *tape34xx_write_block (const char *data, size_t count, tape_info_t * ti){	long lockflags;	ccw_req_t *cqr;	ccw1_t *ccw;	void *mem;	cqr = tape_alloc_ccw_req (ti, 2, 0);	if (!cqr) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xwbl nomem");#endif /* TAPE_DEBUG */		return NULL;	}	mem = kmalloc (count, GFP_KERNEL);	if (!mem) {		tape_free_request (cqr);#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xwbl nomem");#endif /* TAPE_DEBUG */		return NULL;	}	if (copy_from_user (mem, data, count)) {		kfree (mem);		tape_free_request (cqr);#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xwbl segf.");#endif /* TAPE_DEBUG */		return NULL;	}	ccw = cqr->cpaddr;	ccw->cmd_code = MODE_SET_DB;	ccw->flags = CCW_FLAG_CC;	ccw->count = 1;	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));	ccw++;	ccw->cmd_code = WRITE_CMD;	ccw->flags = 0;	ccw->count = count;	set_normalized_cda (ccw, (unsigned long) mem);	if ((ccw->cda) == 0) {		kfree (mem);		tape_free_request (cqr);		return NULL;	}	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	ti->kernbuf = mem;	ti->userbuf = (void *) data;	tapestate_set (ti, TS_WRI_INIT);	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xwbl ccwg");#endif /* TAPE_DEBUG */	return cqr;}void tape34xx_free_write_block (ccw_req_t * cqr, tape_info_t * ti){	unsigned long lockflags;	ccw1_t *ccw;	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	ccw = cqr->cpaddr;	ccw++;	clear_normalized_cda (ccw);	kfree (ti->kernbuf);	tape_free_request (cqr);	ti->kernbuf = ti->userbuf = NULL;	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xfwb free");#endif /* TAPE_DEBUG */}ccw_req_t *tape34xx_read_block (const char *data, size_t count, tape_info_t * ti){	long lockflags;	ccw_req_t *cqr;	ccw1_t *ccw;	void *mem;	cqr = tape_alloc_ccw_req (ti, 2, 0);	if (!cqr) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xrbl nomem");#endif /* TAPE_DEBUG */		return NULL;	}	mem = kmalloc (count, GFP_KERNEL);	if (!mem) {		tape_free_request (cqr);#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xrbl nomem");#endif /* TAPE_DEBUG */		return NULL;	}	ccw = cqr->cpaddr;	ccw->cmd_code = MODE_SET_DB;	ccw->flags = CCW_FLAG_CC;	ccw->count = 1;	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));	ccw++;	ccw->cmd_code = READ_FORWARD;	ccw->flags = 0;	ccw->count = count;	set_normalized_cda (ccw, (unsigned long) mem);	if ((ccw->cda) == 0) {		kfree (mem);		tape_free_request (cqr);		return NULL;	}	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	ti->kernbuf = mem;	ti->userbuf = (void *) data;	tapestate_set (ti, TS_RFO_INIT);	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xrbl ccwg");#endif /* TAPE_DEBUG */	return cqr;}ccw_req_t *tape34xx_read_opposite (tape_info_t * ti,int novalue){	ccw_req_t *cqr;	ccw1_t *ccw;	size_t count;	// first, retrieve the count from the old cqr.	cqr = ti->cqr;	ccw = cqr->cpaddr;	ccw++;	count=ccw->count;	// free old cqr.	clear_normalized_cda (ccw);	tape_free_request (cqr);	// build new cqr	cqr = tape_alloc_ccw_req (ti, 3, 0);	if (!cqr) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xrop nomem");#endif /* TAPE_DEBUG */		return NULL;	}	ccw = cqr->cpaddr;	ccw->cmd_code = MODE_SET_DB;	ccw->flags = CCW_FLAG_CC;	ccw->count = 1;	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));	ccw++;	ccw->cmd_code = READ_BACKWARD;	ccw->flags = CCW_FLAG_CC;	ccw->count = count;	set_normalized_cda (ccw, (unsigned long) ti->kernbuf);	if ((ccw->cda) == 0) {		tape_free_request (cqr);		return NULL;	}	ccw++;	ccw->cmd_code = FORSPACEBLOCK;	ccw->flags = CCW_FLAG_CC;	ccw->count = 1;	ccw->cda = (unsigned long)ccw;	ccw++;	ccw->cmd_code = NOP;	ccw->flags = 0;	ccw->count = 1;	ccw->cda = (unsigned long)ccw;	tapestate_set (ti, TS_RBA_INIT);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xrop ccwg");#endif /* TAPE_DEBUG */	return cqr;}void tape34xx_free_read_block (ccw_req_t * cqr, tape_info_t * ti){	unsigned long lockflags;	size_t cpysize;	ccw1_t *ccw;	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	ccw = cqr->cpaddr;	ccw++;	cpysize = ccw->count - ti->devstat.rescnt;	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);	if (copy_to_user (ti->userbuf, ti->kernbuf, cpysize)) {#ifdef TAPE_DEBUG	    debug_text_exception (tape_debug_area,6,"xfrb segf.");#endif /* TAPE_DEBUG */	}	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	clear_normalized_cda (ccw);	kfree (ti->kernbuf);	tape_free_request (cqr);	ti->kernbuf = ti->userbuf = NULL;	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xfrb free");#endif /* TAPE_DEBUG */}/* * The IOCTL interface is implemented in the following section, * excepted the MTRESET, MTSETBLK which are handled by tapechar.c *//* * MTFSF: Forward space over 'count' file marks. The tape is positioned * at the EOT (End of Tape) side of the file mark. */ccw_req_t *tape34xx_mtfsf (tape_info_t * ti, int count){	long lockflags;	int i;	ccw_req_t *cqr;	ccw1_t *ccw;	if ((count == 0) || (count > 510)) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xfsf parm");#endif /* TAPE_DEBUG */		return NULL;	}	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);	if (!cqr) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xfsf nomem");#endif /* TAPE_DEBUG */		return NULL;	}	ccw = cqr->cpaddr;	ccw->cmd_code = MODE_SET_DB;	ccw->flags = CCW_FLAG_CC;	ccw->count = 1;	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));	ccw++;	for (i = 0; i < count; i++) {		ccw->cmd_code = FORSPACEFILE;		ccw->flags = CCW_FLAG_CC;		ccw->count = 0;		ccw->cda = (unsigned long) (&(ccw->cmd_code));		ccw++;	}	ccw->cmd_code = NOP;	ccw->flags = 0;	ccw->count = 0;	ccw->cda = (unsigned long) (&(ccw->cmd_code));	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	ti->kernbuf = NULL;	ti->userbuf = NULL;	tapestate_set (ti, TS_FSF_INIT);	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xfsf ccwg");#endif /* TAPE_DEBUG */	return cqr;}/* * MTBSF: Backward space over 'count' file marks. The tape is positioned at * the EOT (End of Tape) side of the last skipped file mark. */ccw_req_t *tape34xx_mtbsf (tape_info_t * ti, int count){	long lockflags;	int i;	ccw_req_t *cqr;	ccw1_t *ccw;	if ((count == 0) || (count > 510)) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xbsf parm");#endif /* TAPE_DEBUG */	        return NULL;	}	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);	if (!cqr) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xbsf nomem");#endif /* TAPE_DEBUG */		return NULL;	}	ccw = cqr->cpaddr;	ccw->cmd_code = MODE_SET_DB;	ccw->flags = CCW_FLAG_CC;	ccw->count = 1;	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));	ccw++;	for (i = 0; i < count; i++) {		ccw->cmd_code = BACKSPACEFILE;		ccw->flags = CCW_FLAG_CC;		ccw->count = 0;		ccw->cda = (unsigned long) (&(ccw->cmd_code));		ccw++;	}	ccw->cmd_code = NOP;	ccw->flags = 0;	ccw->count = 0;	ccw->cda = (unsigned long) (&(ccw->cmd_code));	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	ti->kernbuf = NULL;	ti->userbuf = NULL;	tapestate_set (ti, TS_BSF_INIT);	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xbsf ccwg");#endif /* TAPE_DEBUG */	return cqr;}/* * MTFSR: Forward space over 'count' tape blocks (blocksize is set * via MTSETBLK. */ccw_req_t *tape34xx_mtfsr (tape_info_t * ti, int count){	long lockflags;	int i;	ccw_req_t *cqr;	ccw1_t *ccw;	if ((count == 0) || (count > 510)) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xfsr parm");#endif /* TAPE_DEBUG */		return NULL;	}	cqr = tape_alloc_ccw_req (ti, 2 + count, 0);	if (!cqr) {#ifdef TAPE_DEBUG	        debug_text_exception (tape_debug_area,6,"xfsr nomem");#endif /* TAPE_DEBUG */		return NULL;	}	ccw = cqr->cpaddr;	ccw->cmd_code = MODE_SET_DB;	ccw->flags = CCW_FLAG_CC;	ccw->count = 1;	set_normalized_cda (ccw, (unsigned long) (&(((tape34xx_disc_data_t *) ti->discdata)->modeset_byte)));	ccw++;	for (i = 0; i < count; i++) {		ccw->cmd_code = FORSPACEBLOCK;		ccw->flags = CCW_FLAG_CC;		ccw->count = 0;		ccw->cda = (unsigned long) (&(ccw->cmd_code));		ccw++;	}	ccw->cmd_code = NOP;	ccw->flags = 0;	ccw->count = 0;	ccw->cda = (unsigned long) (&(ccw->cmd_code));	s390irq_spin_lock_irqsave (ti->devinfo.irq, lockflags);	ti->kernbuf = NULL;	ti->userbuf = NULL;	tapestate_set (ti, TS_FSB_INIT);	s390irq_spin_unlock_irqrestore (ti->devinfo.irq, lockflags);#ifdef TAPE_DEBUG	debug_text_event (tape_debug_area,6,"xfsr ccwgen");#endif /* TAPE_DEBUG */	return cqr;}/* * MTBSR: Backward space over 'count' tape blocks.

⌨️ 快捷键说明

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