* [PATCH] s390 (5/8): old tape file.
@ 2002-12-12 18:08 Martin Schwidefsky
0 siblings, 0 replies; only message in thread
From: Martin Schwidefsky @ 2002-12-12 18:08 UTC (permalink / raw)
To: linux-kernel, torvalds
Remove last remaining file of the old tape driver.
diffstat:
tape.c | 1907 -----------------------------------------------------------------
1 files changed, 1907 deletions(-)
diff -urN linux-2.5.51/drivers/s390/char/tape.c linux-2.5.51-s390/drivers/s390/char/tape.c
--- linux-2.5.51/drivers/s390/char/tape.c Tue Dec 10 03:46:11 2002
+++ linux-2.5.51-s390/drivers/s390/char/tape.c Thu Jan 1 01:00:00 1970
@@ -1,1907 +0,0 @@
-/***********************************************************************
- * 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>
- * Michael Holzheu <holzheu@de.ibm.com>
- * Tuan Ngo-Anh <ngoanh@de.ibm.com>
- *
- ***********************************************************************
- */
-
-#include "tapedefs.h" // kernel 2.2 compatibility defines
-
-#include <linux/stddef.h> // defines NULL
-#include <linux/proc_fs.h> // for /proc/tapedevices
-#include <linux/init.h> // for kernel parameters
-#include <linux/kmod.h> // for requesting modules
-#include <linux/spinlock.h> // for locks
-#include <asm/types.h> // for variable types
-#ifdef CONFIG_S390_TAPE_DYNAMIC
-#include <asm/s390dyn.h>
-#endif
-#include "tape.h"
-#ifdef CONFIG_S390_TAPE_3590
-#include "tape3590.h"
-#endif
-#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:"
-#define TAPE_MAX_DEVREGS (256 / TAPE_MINORS_PER_DEV)
-
-#define TAPE_NO_IO 0
-#define TAPE_DO_IO 1
-
-#define TAPE_CIO_PRIVATE_DATA
-
-#ifdef CONFIG_KMOD
-#define tape_request_module(a) request_module(a)
-#else
-#define tape_request_module(a)
-#endif
-
-/*******************************************************************
- * Internal Prototypes
- *******************************************************************/
-
-static void tape_do_irq (int irq, void *int_parm, struct pt_regs *regs);
-static inline int tape_halt_io(tape_dev_t* td);
-static void tape_wait(tape_ccw_req_t* treq);
-#ifdef CONFIG_S390_TAPE_DYNAMIC
-/* functions for dyn. dev. attach/detach */
-static int tape_oper_handler ( int irq, struct _devreg *dreg);
-static void tape_noper_handler ( int irq, int status );
-#endif
-static inline void tape_disable_device(tape_dev_t* td);
-static inline int tape_enable_device(tape_dev_t* td);
-
-
-/*******************************************************************
- * GLOBALS
- *******************************************************************/
-
-static devreg_t *tape_devreg[TAPE_MAX_DEVREGS];
-static int tape_devregct=0;
-static int tape_autoprobe = 1;
-static tape_discipline_t *tape_first_disc = NULL;
-tape_dev_t *tape_first_dev = NULL;
-tape_frontend_t *tape_first_front = NULL;
-char *tape[256] = { NULL, };
-
-/*
- * Lock hirarchy:
- * tape_discipline_lock > tape_dev_lock > td->lock
- */
-
-rwlock_t tape_dev_lock=RW_LOCK_UNLOCKED;
-static rwlock_t tape_discipline_lock=RW_LOCK_UNLOCKED;
-
-#ifdef TAPE_DEBUG
-debug_info_t *tape_dbf_area = NULL;
-#endif
-
-const char* tape_med_st_verbose[MS_SIZE]={
- "UNKNOWN ",
- "LOADED ",
- "UNLOADED"
-};
-
-const char* tape_state_verbose[TS_SIZE]={
- "UNUSED",
- "IN_USE",
- "INIT ",
- "NOT_OP"
-};
-
-const char* tape_op_verbose[TO_SIZE] = {
- "BLK",
- "BSB",
- "BSF",
- "DSE",
- "EGA",
- "FSB",
- "FSF",
- "LDI",
- "LBL",
- "MSE",
- "NOP",
- "RBA",
- "RBI",
- "RBU",
- "RBL",
- "RDC",
- "RFO",
- "RSD",
- "REW",
- "RUN",
- "SEN",
- "SID",
- "SNP",
- "SPG",
- "SWI",
- "SMR",
- "SYN",
- "TIO",
- "UNA",
- "WRI",
- "WTM",
- "MSN",
- "LOA",
- "RCF", /* 3590 */
- "RAT", /* 3590 */
- "NOT"
-};
-
-/*******************************************************************
- * DEVFS Functions
- *******************************************************************/
-
-#ifdef CONFIG_DEVFS_FS
-
-/*
- * Create devfs root entry (devno in hex) for device td
- */
-
-static inline devfs_handle_t
-tape_mkdevfsroot (tape_dev_t* td)
-{
- char devno [10];
- sprintf (devno,"tape/%04x",td->devinfo.devno);
- return devfs_mk_dir(NULL, devno, NULL);
-}
-
-/*
- * Remove devfs root entry for device td
- */
-
-static inline void
-tape_rmdevfsroot (tape_dev_t* td)
-{
- devfs_remove("tape/%04x", td->devinfo.devno);
-}
-
-#endif
-
-/*******************************************************************
- * PROCFS Functions
- *******************************************************************/
-
-#ifdef CONFIG_PROC_FS
-/* functions used in tape_proc_file_ops */
-static ssize_t tape_proc_devices_read (struct file *file, char *user_buf, size_t user_len, loff_t * offset);
-static int tape_proc_devices_open (struct inode *inode, struct file *file);
-static int tape_proc_devices_release (struct inode *inode, struct file *file);
-
-/* our proc tapedevices entry */
-static struct proc_dir_entry *tape_proc_devices;
-
-typedef struct {
- char *data;
- int len;
-} tape_procinfo_t;
-
-static struct file_operations tape_proc_devices_file_ops =
-{
- .owner = THIS_MODULE,
- .read = tape_proc_devices_read, /* read */
- .open = tape_proc_devices_open, /* open */
- .release = tape_proc_devices_release, /* close */
-};
-
-/*
- * Initialize procfs stuff on startup
- */
-
-static inline void
-tape_proc_init (void) {
- tape_proc_devices = create_proc_entry ("tapedevices",
- S_IFREG | S_IRUGO | S_IWUSR,
- &proc_root);
- if (tape_proc_devices == NULL)
- goto error;
- tape_proc_devices->proc_fops = &tape_proc_devices_file_ops;
- tape_proc_devices->proc_iops = &tape_proc_devices_inode_ops;
- return;
- error:
- PRINT_WARN ("tape: Cannot register procfs entry tapedevices\n");
- return;
-}
-
-/*
- * Open function for /proc/tapedevices
- */
-
-static int
-tape_proc_devices_open (struct inode *inode, struct file *file)
-{
- tape_dev_t* td;
- tape_procinfo_t* procinfo;
- char* data = NULL;
- int size=0,check_size = -1;
- int pos=0;
- int rc=0;
- long lockflags,lockflags2;
- tape_ccw_req_t *treq;
-
- procinfo = kmalloc (sizeof(tape_procinfo_t),GFP_KERNEL);
- if (!procinfo){
- rc = -ENOMEM;
- goto out_no_lock;
- }
-
- /* Find out mem size for output, ensure that after releasing lock */
- /* (vmalloc must not be called with interrupts disabled) no devices */
- /* have been added/removed */
-
- do{
- size = 100; // Headline
- read_lock_irqsave(&tape_dev_lock,lockflags);
-
- for (td=tape_first_dev;td!=NULL;td=td->next)
- size+=100; // FIXME: Guess better!
-
- if(size == check_size)
- break;
-
- read_unlock_irqrestore(&tape_dev_lock,lockflags);
-
- if(data)
- vfree(data);
- data=vmalloc(size);
- if (!data) {
- kfree (procinfo);
- rc = -ENOMEM;
- goto out_no_lock;
- }
- check_size = size;
- }while (1);
-
- // We have the tape_dev lock now
-
-#ifdef CONFIG_S390_TAPE_CHAR
- pos+=sprintf(data+pos,"TapeNo\tDevNo\tCuType\tCuModel\tDevType\tDevMod\tBlkSize\tState\tOp\tMedState\n");
-#else
- pos+=sprintf(data+pos,"TapeNo\tDevNo\tCuType\tCuModel\tDevType\tDevMod\tState\tOp\tMedState\n");
-#endif
-
- for (td=tape_first_dev;td!=NULL;td=td->next) {
- s390irq_spin_lock_irqsave (td->devinfo.irq,lockflags2);
- treq = tape_get_active_ccw_req(td);
- pos+=sprintf(data+pos,"%d\t",td->first_minor/TAPE_MINORS_PER_DEV);
- pos+=sprintf(data+pos,"%04X\t",td->devinfo.devno);
- pos+=sprintf(data+pos,"%04X\t",td->devinfo.sid_data.cu_type);
- pos+=sprintf(data+pos,"%02X\t",td->devinfo.sid_data.cu_model);
- pos+=sprintf(data+pos,"%04X\t",td->devinfo.sid_data.dev_type);
- pos+=sprintf(data+pos,"%02X\t",td->devinfo.sid_data.dev_model);
-#ifdef CONFIG_S390_TAPE_CHAR
- if(td->char_data.block_size == 0)
- pos+=sprintf(data+pos,"auto\t");
- else
- pos+=sprintf(data+pos,"%i\t",td->char_data.block_size);
-#endif
- pos+=sprintf(data+pos,"%s\t",((tape_state_get(td) >= 0) &&
- (tape_state_get(td) < TS_SIZE)) ?
- tape_state_verbose[tape_state_get (td)] : "UNKNOWN");
- pos+=sprintf(data+pos,"%s\t",(treq != NULL) ?
- tape_op_verbose[treq->op] : "---");
- pos+=sprintf(data+pos,"%s\n",tape_med_st_verbose[td->medium_state]);
- s390irq_spin_unlock_irqrestore (td->devinfo.irq,lockflags2);
- }
-
- procinfo->data=data;
- procinfo->len=pos;
- if (pos>size) BUG(); // we've overwritten some memory
- file->private_data= (void*) procinfo;
- read_unlock_irqrestore(&tape_dev_lock,lockflags);
-out_no_lock:
- return rc;
-}
-
-/*
- * Read function for /proc/tapedevices
- */
-
-static ssize_t
-tape_proc_devices_read (struct file *file, char *user_buf, size_t user_len, loff_t * offset)
-{
- loff_t len = 0;
- tape_procinfo_t *p_info = (tape_procinfo_t *) file->private_data;
-
- if (*offset >= p_info->len) {
- goto out; /* 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;
- }
-out:
- return len;
-}
-
-/*
- * Close function for /proc/tapedevices
- */
-
-static int
-tape_proc_devices_release (struct inode *inode, struct file *file)
-{
- int rc = 0;
- tape_procinfo_t *p_info = (tape_procinfo_t *) file->private_data;
- vfree(p_info->data);
- kfree (p_info);
- return rc;
-}
-
-/*
- * Cleanup all stuff registered to the procfs
- */
-static inline void
-tape_proc_cleanup (void)
-{
- if (tape_proc_devices != NULL)
- remove_proc_entry ("tapedevices", &proc_root);
-}
-
-#endif /* CONFIG_PROC_FS */
-
-/*******************************************************************
- * Wait/Wakeup Functions
- *******************************************************************/
-
-static void tape_wake_up_remove(tape_ccw_req_t* treq){
- tape_remove_ccw_req(treq->tape_dev,treq);
- tape_free_ccw_req(treq);
-}
-
-static void tape_wake_up(tape_ccw_req_t* treq){
- treq->wakeup = NULL;
- wake_up(&treq->wq);
-}
-
-static void tape_wake_up_interruptible(tape_ccw_req_t* treq){
- treq->wakeup = NULL;
- wake_up_interruptible(&treq->wq);
-}
-
-#ifdef CONFIG_S390_TAPE_BLOCK
-static void tape_schedule_tapeblock(tape_ccw_req_t* treq){
- treq->wakeup = NULL;
- tapeblock_schedule_exec_io((tape_dev_t*)(treq->tape_dev));;
-}
-#endif
-
-static void tape_wait_event(tape_ccw_req_t* treq){
- wait_event (treq->wq,(treq->wakeup == NULL));
-}
-
-static void tape_wait_event_interruptible(tape_ccw_req_t* treq){
- wait_event_interruptible(treq->wq,(treq->wakeup == NULL));
- if (signal_pending (current)) {
- treq->rc = tape_halt_io(treq->tape_dev);
- if(treq->rc == -ERESTARTSYS)
- PRINT_INFO("IO stopped on irq %d\n",treq->tape_dev->devinfo.irq); /* FIXME: only put into dbf */
- else if(treq->rc == 0)
- PRINT_INFO("could not stop IO,irq was faster on irq %d\n",treq->tape_dev->devinfo.irq); /* FIXME: only put into dbf */
- else
- PRINT_WARN("IO error while stopping IO on irq %d\n",treq->tape_dev->devinfo.irq);
- }
-}
-
-static void tape_wait_event_interruptible_nohaltio(tape_ccw_req_t* treq){
- wait_event_interruptible(treq->wq,(treq->wakeup == NULL));
-}
-
-/*******************************************************************
- * DYNAMIC ATTACH/DETACH Functions
- *******************************************************************/
-
-static inline void
-tape_init_devregs(void)
-{
- long lockflags;
- write_lock_irqsave(&tape_dev_lock,lockflags);
- memset(tape_devreg,0,sizeof(devreg_t*) * TAPE_MAX_DEVREGS);
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-
-/*
- * Alloc a devreg for a devno
- */
-
-static inline devreg_t *
-tape_create_devno_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;
-}
-
-/*
- * Alloc a devreg for a cu-type
- */
-
-static inline devreg_t *
-tape_create_cu_devreg (int cu_type)
-{
- devreg_t *devreg = kmalloc (sizeof (devreg_t), GFP_KERNEL);
- if (devreg != NULL) {
- memset (devreg, 0, sizeof (devreg_t));
- devreg->ci.hc.ctype = cu_type;
- devreg->flag = DEVREG_MATCH_CU_TYPE | DEVREG_TYPE_DEVCHARS;
- devreg->oper_func = tape_oper_handler;
- }
- return devreg;
-}
-
-/*
- * Create devregs for device numbers from "from" to "to"
- */
-
-static inline void
-tape_create_devregs_range(int from, int to)
-{
- int i;
- long lockflags;
-
- write_lock_irqsave(&tape_dev_lock,lockflags);
- for (i=from;i<=to;i++) {
- // register for attch/detach of a devno
- if(tape_devregct >= TAPE_MAX_DEVREGS){
- PRINT_WARN ("Could not create devregs for devno range %04x - %04x.\n",i,to);
- PRINT_WARN ("These devices cannot be used. Use autoprobe\n");
- PRINT_WARN ("or specify device ranges more precisely!\n");
- break;
- }
- tape_devreg[tape_devregct]=tape_create_devno_devreg(i);
- if (tape_devreg[tape_devregct]!=NULL) {
- s390_device_register (tape_devreg[tape_devregct++]);
- } else {
- PRINT_WARN ("Could not create devreg for devno %04x, dyn. attach for this devno deactivated.\n",i);
- }
- }
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
- return;
-}
-
-/*
- * Create a devreg for a discipline
- */
-
-static inline void
-tape_create_devreg_for_disc(tape_discipline_t *disc)
-{
- int devreg_nr;
- long lockflags;
-
- write_lock_irqsave(&tape_dev_lock,lockflags);
- for(devreg_nr = 0; devreg_nr < TAPE_MAX_DEVREGS; devreg_nr++){
- if(tape_devreg[devreg_nr] == NULL)
- break;
- }
- if(devreg_nr == TAPE_MAX_DEVREGS){
- PRINT_WARN ("Could not create devreg for discipline (%x), dyn. attach for this discipline deactivated.\n",disc->cu_type);
- goto out_unlock;
- }
- tape_devreg[devreg_nr] = tape_create_cu_devreg(disc->cu_type);
- if (tape_devreg[devreg_nr] != NULL) {
- s390_device_register(tape_devreg[devreg_nr]);
- } else {
- PRINT_WARN("Could not alloc devreg: Out of memory\n");
- PRINT_WARN("Dynamic attach/detach will not work!\n");
- }
-out_unlock:
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
- return;
-}
-
-/*
- * Free all devregs
- */
-
-static inline void
-tape_delete_all_devregs(void)
-{
- int i;
- long lockflags;
-
- write_lock_irqsave(&tape_dev_lock,lockflags);
-
- for(i = 0; i < TAPE_MAX_DEVREGS; i++){
- if(tape_devreg[i]){
- s390_device_unregister(tape_devreg[i]);
- kfree(tape_devreg[i]);
- }
- }
- memset(tape_devreg,0,sizeof(devreg_t*) * TAPE_MAX_DEVREGS);
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-
-/*
- * Free Devregs for a discipline
- */
-
-static inline void
-tape_delete_devreg_for_disc(tape_discipline_t* disc)
-{
- int i;
- long lockflags;
-
- write_lock_irqsave(&tape_dev_lock,lockflags);
-
- for(i = 0; i < TAPE_MAX_DEVREGS; i++){
- if(tape_devreg[i]){
- if(tape_devreg[i]->ci.hc.ctype == disc->cu_type){
- s390_device_unregister(tape_devreg[i]);
- kfree(tape_devreg[i]);
- tape_devreg[i] = NULL;
- }
- }
- }
-
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-
-/*******************************************************************
- * Module/Kernel Parameter Handling
- *******************************************************************/
-
-#ifndef MODULE
-static char tape_parm_string[1024] __initdata = { 0, };
-
-/*
- * Get Kernel parameters (str) seperated by ","
- * and store them into the tape[] array
- */
-
-static void
-tape_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;
- }
- memcpy (tape[count], tmp, len * sizeof (char));
- count++;
- tmp = end;
- };
-}
-
-/*
- * This function is called for each "tape=" Kernel parameter
- * at Kernel initialization. We need tape_parm_setup because of
- * 2.2 compatibility (At least I assume this :-))
- */
-
-void __init
-tape_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 __init
-tape_parm_call_setup (char *str)
-{
- int dummy;
- tape_parm_setup (str, &dummy);
- return 1;
-}
-
-__setup("tape=", tape_parm_call_setup);
-#endif /* not defined MODULE */
-
-
-/*
- * Convert string to int
- */
-
-static inline int
-tape_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;
-}
-
-/*
- * Parse Kernel/Module Parameters and create devregs for dynamic attach/detach
- */
-
-static inline void
-tape_parm_parse (char **str)
-{
- char *temp;
- int from, to;
-
- if (*str==NULL) {
- /* no params present -> leave */
- return;
- }
- while (*str) {
- temp = *str;
- from = 0;
- to = 0;
- from = tape_parm_strtoul (temp, &temp);
- to = from;
- if (*temp == '-') {
- temp++;
- to = tape_parm_strtoul (temp, &temp);
- }
- tape_create_devregs_range(from,to);
- str++;
- }
-}
-
-/*******************************************************************
- * Tape device (td) functions for create, free, enq, deq, enable,
- * disable, get and put
- *******************************************************************/
-
-/*
- * Enable Device
- */
-
-static inline int
-tape_enable_device(tape_dev_t* td)
-{
-#ifdef CONFIG_DEVFS_FS
- tape_frontend_t* frontend;
-#endif
- int rc = 0;
-
- if(td->discipline->setup_device(td) != 0){
- rc = -ENOMEM;
- goto out;
- }
-
- /* Register IRQ */
-
-#ifdef TAPE_CIO_PRIVATE_DATA
- #ifdef CONFIG_S390_TAPE_DYNAMIC
- rc = s390_request_irq_special (td->devinfo.irq, tape_do_irq,
- tape_noper_handler,0, TAPE_MAGIC, &(td->devstat));
- #else
- rc = s390_request_irq (td->devinfo.irq, tape_do_irq, 0, TAPE_MAGIC, &(td->devstat));
- #endif
-#else
- #ifdef CONFIG_S390_TAPE_DYNAMIC
- rc = s390_request_irq_special (td->devinfo.irq, tape_do_irq,
- tape_noper_handler,0, (char*)td, &(td->devstat));
- #else
- rc = s390_request_irq (td->devinfo.irq, tape_do_irq, 0, (char*)td, &(td->devstat));
- #endif
-#endif /* TAPE_CIO_PRIVATE_DATA */
- if (rc){
- PRINT_WARN ("Cannot register irq %d, rc=%d\n", td->devinfo.irq, rc);
- td->discipline->cleanup_device(td);
- goto out;
- }
- /* Create devfs entries */
-#ifdef CONFIG_DEVFS_FS
- if (tape_mkdevfsroot(td)==NULL){
- PRINT_WARN ("Cannot create a devfs directory for device %04x\n",td->devinfo.devno);
- goto out_undo;
- }
-
- for (frontend=tape_first_front;frontend!=NULL;frontend=frontend->next){
- if(frontend->mkdevfstree(td) == NULL){
- goto out_undo;
- }
- }
-#endif
-#ifdef TAPE_CIO_PRIVATE_DATA
- s390_set_private_data(td->devinfo.irq,td);
-#endif
-out:
- return rc;
-out_undo:
- tape_disable_device(td);
- return -ENOMEM;
-}
-
-/*
- * Disable Device
- */
-
-static inline void
-tape_disable_device(tape_dev_t* td)
-{
-#ifdef CONFIG_DEVFS_FS
- tape_frontend_t* frontend;
-#endif
- td->discipline->cleanup_device(td);
-#ifdef TAPE_CIO_PRIVATE_DATA
- s390_set_private_data(td->devinfo.irq,NULL);
-#else
- ioinfo[td->devinfo.irq]->irq_desc.name = NULL;
-#endif
-
- free_irq (td->devinfo.irq, &(td->devstat));
-#ifdef CONFIG_DEVFS_FS
- for (frontend=tape_first_front;frontend!=NULL;frontend=frontend->next)
- frontend->rmdevfstree(td);
- tape_rmdevfsroot(td);
-#endif
- tape_state_set(td,TS_NOT_OPER);
-}
-
-/*
- * Append Tape device (td) to our tape info list
- * Must be called with hold tape_dev_lock
- */
-
-static inline void
-tape_enq_device(tape_dev_t* td)
-{
- tape_dev_t *temptd = NULL;
-
- if (tape_first_dev == NULL) {
- tape_first_dev = td;
- } else {
- temptd = tape_first_dev;
- while (temptd->next != NULL)
- temptd = temptd->next;
- temptd->next = td;
- }
-}
-
-/*
- * Remove Tape device (td) from our tape info list
- * Must be called with hold tape_dev_lock
- */
-
-static inline void
-tape_deq_device(tape_dev_t* td)
-{
- tape_dev_t* lasttd;
-
- if (td==tape_first_dev) {
- tape_first_dev=td->next;
- } else {
- lasttd=tape_first_dev;
- while (lasttd->next!=td) lasttd=lasttd->next;
- lasttd->next=td->next;
- }
-}
-
-
-/*
- * Get Free minor number
- * Must be called with held tape_dev_lock
- */
-
-static inline int
-tape_get_new_minor(int devno)
-{
- int i,tape_num = -1;
- tape_dev_t* newtape;
-
- if(!tape_autoprobe){
- /* we have static device ranges, so fingure out the */
- /* tape_num of the attached tape */
- for (i=0;i<tape_devregct;i++){
- if (tape_devreg[i]->ci.devno==devno) {
- tape_num=TAPE_MINORS_PER_DEV*i;
- goto out;
- }
- }
- } else {
- /* we are running in autoprobe mode, find a free */
- /* tape_num */
- i = 0;
- newtape=tape_first_dev;
- while (newtape!=NULL) {
- if (newtape->first_minor==i) {
- /* tape num in use. try next one */
- i+=TAPE_MINORS_PER_DEV;
- newtape=tape_first_dev;
- } else {
- /* tape num not used by newtape. look at next */
- /* tape info */
- newtape=newtape->next;
- }
- }
- if(i>255) /* No more minor available */
- tape_num = -1;
- else
- tape_num = i;
- }
-out:
- return tape_num;
-}
-
-
-/*
- * Create device: Alloc, enable and enq device
- */
-
-static inline tape_dev_t*
-tape_create_device(int irq, int devno, tape_discipline_t* disc)
-{
- int rc = 0;
- int tape_num;
- tape_dev_t *td;
- long lockflags;
-
- write_lock_irqsave(&tape_dev_lock,lockflags);
-
- td = kmalloc (sizeof (tape_dev_t), GFP_ATOMIC);
- if (td == NULL) {
- tape_sprintf_exception (tape_dbf_area,2,"ti:no mem \n");
- PRINT_INFO ("tape: can't allocate memory for "
- "tape info structure\n");
- goto error;
- }
- memset(td,0,sizeof(tape_dev_t));
- tape_num = tape_get_new_minor(devno);
- if(tape_num == -1){
- PRINT_WARN("tape: could not get minor for tape %x\n",devno);
- goto error;
- }
- rc = get_dev_info_by_irq (irq, &(td->devinfo));
- if (rc == -ENODEV) { /* end of device list */
- goto error;
- }
- td->discipline = disc;
- atomic_set(&(td->use_count),1);
- td->first_minor = tape_num;
- td->medium_state = MS_UNKNOWN;
- td->next = NULL;
- td->discdata = td->treq = NULL;
- tape_state_set (td, TS_INIT);
- td->discdata=NULL;
- td->last_op = TO_NOTHING;
-
- if(td->discipline->setup_device(td) != 0)
- goto error;
- if(tape_enable_device(td) !=0)
- goto error;
- tape_enq_device(td);
- PRINT_INFO ("using devno %04x with discipline %04x on irq %d as tape device %d\n",devno,disc->cu_type,irq,tape_num/2);
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
- return td;
-error:
- tape_sprintf_event (tape_dbf_area,3,"tsetup err: %x\n",rc);
- if(td)
- kfree (td);
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
- return NULL;
-}
-
-/*
- * Free Device storage
- */
-
-static void
-tape_free_device(tape_dev_t* td)
-{
- if (TAPE_BUSY(td))
- BUG(); /* one should _not_ free the device when a request is pending */
- tape_sprintf_event (tape_dbf_area,6,"free irq: %x\n",td->devinfo.irq);
- kfree(td);
-}
-
-/*
- * Decrement use count of tape structure
- * if use count == 0 tape structure is freed
- */
-
-inline void
-tape_put_device(tape_dev_t* td)
-{
- if (td==NULL)
- BUG();
- if(atomic_dec_and_test(&(td->use_count)))
- tape_free_device(td);
-}
-
-/*
- * Find the tape_dev_t structure associated with member
- * and increase use count:
- *
- * member: TAPE_MEMB_IRQ, TAPE_MEMB_MINOR
- */
-
-tape_dev_t *
-__tape_get_device_by_member(unsigned long value, int member)
-{
- tape_dev_t *td = NULL;
- long lockflags;
-
- read_lock_irqsave(&tape_dev_lock,lockflags);
- td = tape_first_dev;
- while(td != NULL) {
- switch(member){
- case TAPE_MEMB_IRQ:
- if(td->devinfo.irq == value)
- goto out;
- break;
- case TAPE_MEMB_MINOR:
- if((value >= td->first_minor) &&
- (value < (td->first_minor + TAPE_MINORS_PER_DEV)) )
- goto out;
- break;
- case TAPE_MEMB_QUEUE:
- if(((unsigned long)(&td->blk_data.request_queue)) == value)
- goto out;
- break;
- default:
- BUG();
- }
- td = td->next;
- }
-out:
- if(td) // found!
- atomic_inc(&(td->use_count));
- read_unlock_irqrestore(&tape_dev_lock,lockflags);
- return td;
-}
-
-/*
- * Scan all irqs an create tape devices for all matching cu types
- */
-
-static inline void
-tape_create_devs_for_disc(tape_discipline_t* disc)
-{
- int irq,i;
- tape_dev_t* td = NULL;
- s390_dev_info_t dinfo;
-
- for (irq = get_irq_first(); irq!=-ENODEV; irq=get_irq_next(irq)) {
- if(get_dev_info_by_irq (irq, &dinfo) == -ENODEV)
- continue;
- if(disc->cu_type != dinfo.sid_data.cu_type)
- /* Wrong type - try next one */
- continue;
-
- tape_sprintf_event (tape_dbf_area,3,"det irq: %x\n",irq);
- tape_sprintf_event (tape_dbf_area,3,"cu : %x\n",disc->cu_type);
-
-
- if(!tape_autoprobe) {
- for( i=0; i<tape_devregct; i++ ) {
- if(tape_devreg[i]->ci.devno == dinfo.devno) {
- td = tape_create_device(irq, dinfo.devno, disc);
- if(!td) {
- PRINT_WARN( "Could not initialize tape 0x%x\n",dinfo.devno);
- continue;
- }
- if(disc->init_device)
- disc->init_device(td); /* XXX */
- tape_state_set (td, TS_UNUSED);
- break;
- }
- }
- }
- else {
- td = tape_create_device(irq,dinfo.devno,disc);
-
- if(!td){
- PRINT_WARN( "Could not initialize tape 0x%x\n",dinfo.devno);
- continue;
- }
- if(disc->init_device)
- disc->init_device(td); /* XXX */
- tape_state_set (td, TS_UNUSED);
- }
- }
-}
-
-/*
- * Go through our tape info list and disable, deq and free all devices with
- * matching cu type
- */
-
-static inline void
-tape_delete_devs_for_disc(tape_discipline_t* disc)
-{
- tape_dev_t *td;
- long lockflags;
-
- write_lock_irqsave(&tape_dev_lock,lockflags);
- td = tape_first_dev;
- while (td !=NULL){
- if(td->discipline == disc){
- tape_deq_device(td);
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
- tape_disable_device(td);
- tape_put_device(td);
- write_lock_irqsave(&tape_dev_lock,lockflags);
- td = tape_first_dev;
- } else {
- td=td->next;
- }
- }
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
-}
-
-/*******************************************************************
- * TAPE Request and IO Functions
- *******************************************************************/
-
-/*
- * Allocate a new tape ccw request
- */
-
-inline tape_ccw_req_t *
-tape_alloc_ccw_req (int cplength, int datasize,int idal_buf_size, tape_op_t operation)
-{
- tape_ccw_req_t* treq;
- int kmalloc_flags;
- if(in_interrupt())
- kmalloc_flags = GFP_ATOMIC;
- else
- kmalloc_flags = GFP_KERNEL;
-
- treq = (tape_ccw_req_t*) kmalloc(sizeof(tape_ccw_req_t),kmalloc_flags);
- if(!treq)
- goto error;
- memset(treq,0,sizeof(tape_ccw_req_t));
- treq->kernbuf_size = datasize;
- treq->userbuf_size = datasize;
- treq->op = operation;
- treq->cplength = cplength;
- init_waitqueue_head (&treq->wq);
-
- // alloc small kernel buffer
-
- if(datasize > PAGE_SIZE)
- BUG();
- if(datasize > 0){
- // the kernbuf must be below 2GB --> GFP_DMA
- treq->kernbuf = kmalloc(datasize,kmalloc_flags | GFP_DMA);
- if(!treq->kernbuf)
- goto error;
- memset(treq->kernbuf, 0, datasize);
- }
-
- // alloc idal kernel buffer
-
- if(idal_buf_size > 0){
- treq->idal_buf = idalbuf_alloc(idal_buf_size);
- if(!treq->idal_buf)
- goto error;
- }
-
- if(cplength < 0)
- BUG();
-
- // the channel program must be below 2GB --> GFP_DMA
- treq->cpaddr = kmalloc(cplength * sizeof(ccw1_t), kmalloc_flags | GFP_DMA);
- if(!treq->cpaddr)
- goto error;
- memset(treq->cpaddr, 0, cplength*sizeof(ccw1_t));
- return treq;
-error:
- tape_sprintf_exception (tape_dbf_area,1,"cqra nomem\n");
- if(treq)
- tape_free_ccw_req(treq);
- return NULL;
-}
-
-/*
- * Free tape ccw request
- */
-
-void
-tape_free_ccw_req (tape_ccw_req_t * treq)
-{
- if(!treq)
- BUG();
- if(treq->cpaddr)
- kfree(treq->cpaddr);
- if(treq->kernbuf)
- kfree(treq->kernbuf);
- if(treq->idal_buf)
- idalbuf_free(treq->idal_buf);
- kfree(treq);
-}
-
-/*
- * Add request to request queue (At the moment queue length = 1)
- */
-
-static inline int
-tape_add_ccw_req(tape_dev_t* td,tape_ccw_req_t* treq)
-{
- if(td->treq)
- return -1;
- td->treq = treq;
- treq->tape_dev = td;
- return 0;
-}
-
-/*
- * Remove request from request queue (At the moment queue length = 1)
- */
-
-int
-tape_remove_ccw_req(tape_dev_t* td,tape_ccw_req_t* treq)
-{
- if(treq != td->treq)
- BUG();
- td->last_op = treq->op;
- td->treq=NULL;
- treq->tape_dev=NULL;
- return 0;
-}
-
-/*
- * Get the active ccw request
- */
-
-tape_ccw_req_t*
-tape_get_active_ccw_req(tape_dev_t* td)
-{
- return td->treq;
-}
-
-/*
- * Stop the active ccw request
- */
-
-static inline int
-tape_halt_io(tape_dev_t* td)
-{
- int retries = 0;
- int irq = td->devinfo.irq;
- int rc = 0;
- long lockflags;
- tape_ccw_req_t* treq;
-
- s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
- treq = tape_get_active_ccw_req(td);
- /* check if interrupt has already been processed */
- if(!treq)
- goto out;
- if(treq->wakeup == NULL)
- goto out;
- while (retries < 5){
- if ( retries < 2 )
- rc = halt_IO(irq, (long)treq, treq->options);
- else
- rc = clear_IO(irq, (long)treq, treq->options);
- switch (rc) {
- case 0: /* termination successful */
- rc = -ERESTARTSYS;
- goto out;
- case -ENODEV:
- PRINT_INFO ("device gone, retry\n"); /* FIXME: s390dbf only */
- break;
- case -EIO:
- PRINT_INFO ("I/O error, retry\n"); /* FIXME: s390dbf only */
- break;
- case -EBUSY:
- PRINT_INFO ( "device busy, retry later\n"); /* FIXME: s390dbf only */
- break;
- default:
- PRINT_ERR ( "line %d unknown RC=%d, please report"
- " to linux390@de.ibm.com\n", __LINE__, rc);
- BUG ();
- }
- retries ++;
- }
-out:
- s390irq_spin_unlock_irqrestore(td->devinfo.irq, lockflags);
- return rc;
-}
-
-
-/*
- * The tape IO function:
- * tape_do_io MUST be called with locked td lock!
- */
-
-static inline int
-__tape_do_io(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type,int io)
-{
- int rc = 0;
-
- if ((td==NULL) || (treq==NULL))
- BUG();
-
- if(tape_state_get(td) == TS_NOT_OPER){
- rc = -ENODEV;
- goto out;
- }
- if(TAPE_BUSY(td)){
- tape_sprintf_event (tape_dbf_area,1,"tape: IRQ - Tape busy\n");
- rc = -EBUSY;
- goto out;
- }
- tape_add_ccw_req(td,treq);
- switch(type){
- case TAPE_REMOVE_REQ_ON_WAKEUP:
- treq->wakeup = tape_wake_up_remove;
- break;
- case TAPE_NO_WAIT:
- // needed for retry
- break;
- case TAPE_WAIT:
- treq->wakeup = tape_wake_up;
- treq->wait = tape_wait_event;
- break;
- case TAPE_WAIT_INTERRUPTIBLE:
- treq->wakeup = tape_wake_up_interruptible;
- treq->wait = tape_wait_event_interruptible;
- break;
- case TAPE_WAIT_INTERRUPTIBLE_NOHALTIO:
- // neded for dummy load
- treq->wakeup = tape_wake_up_interruptible;
- treq->wait = tape_wait_event_interruptible_nohaltio;
- break;
-#ifdef CONFIG_S390_TAPE_BLOCK
- case TAPE_SCHED_BLOCK:
- treq->wakeup = tape_schedule_tapeblock;
- treq->wait = NULL;
- break;
-#endif
- default:
- BUG();
- }
-
- if(io)
- rc = do_IO(td->devinfo.irq,treq->cpaddr,
- (unsigned long)treq, 0x00, treq->options);
-
- if(rc) {
- tape_sprintf_event (tape_dbf_area,1,"tape: DOIO failed with er = %i\n",rc);
- treq->wakeup = NULL;
- treq->wait = NULL; /*XXX ??*/
- tape_remove_ccw_req(td,treq);
- }
-out:
- return rc;
-}
-
-/*
- * Do the io request and wait for it
- */
-
-int
-tape_do_io_and_wait(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
- int rc = 0;
- long lockflags;
- if (td==NULL)
- BUG();
- s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
- rc = __tape_do_io(td,treq,type,TAPE_DO_IO);
- s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
- if(rc == 0)
- tape_wait(treq);
- return rc;
-}
-
-/*
- * Needed for MTLOAD: Just create a wait request without doing io
- */
-
-int
-tape_do_wait_req(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
- int rc = 0;
- long lockflags;
- if (td==NULL)
- BUG();
- s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
- rc = __tape_do_io(td,treq,type,TAPE_NO_IO);
- s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
- tape_wait(treq);
- return rc;
-}
-
-/*
- * Just do the io
- */
-
-int
-tape_do_io(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
- int rc = 0;
- long lockflags;
- s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
- rc = __tape_do_io(td,treq,type,TAPE_DO_IO);
- s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
- return rc;
-}
-
-/*
- * Just do the io, but we are already locked here (in irq)
- */
-
-int
-tape_do_io_irq(tape_dev_t * td,tape_ccw_req_t *treq,tape_wait_t type)
-{
- return __tape_do_io(td,treq,type,TAPE_DO_IO);
-}
-
-/*
- * Wait for an io request
- */
-
-static void
-tape_wait(tape_ccw_req_t* treq)
-{
- tape_dev_t* td;
- if(treq==NULL)
- BUG();
- td = treq->tape_dev;
- if (td==NULL)
- BUG();
- if(treq->wait==NULL)
- BUG();
- treq->wait(treq);
- tape_remove_ccw_req(td,treq);
-}
-
-/*
- * Tape interrupt routine, called from Ingo's I/O layer
- */
-
-static void
-tape_do_irq (int irq, void *int_parm, struct pt_regs *regs)
-{
- tape_dev_t *td;
-#ifdef TAPE_CIO_PRIVATE_DATA
- td = (tape_dev_t*)s390_get_private_data(irq);
-#else
- td = (tape_dev_t*)ioinfo[irq]->irq_desc.name;
-#endif
- if(!td) {
- PRINT_ERR ("tape: could not get device structure for irq %d in interrupt\n",irq);
- goto out;
- }
- if(td->devstat.dstat != 0x0c){
- tape_sprintf_event (tape_dbf_area,3,"-- Tape Interrupthandler --\n");
- tape_dump_sense_dbf(td);
- }
- if (tape_state_get(td) == TS_NOT_OPER) {
- tape_sprintf_event (tape_dbf_area,6,"tape:device is not operational\n");
- goto out;
- }
- td->discipline->irq(td);
-out:
- return;
-}
-
-/*
- * Oper Handler is called from Ingo's I/O layer when a new tape device is
- * attached. We create a new devinfo for the new device, enable and enq it.
- */
-
-static int
-tape_oper_handler ( int irq, struct _devreg *dreg) {
- tape_dev_t* td=tape_first_dev;
- int rc=0;
- s390_dev_info_t dinfo;
- tape_discipline_t* disc;
- long lockflags;
-
- td = tape_get_device_by_irq(irq);
- if (td!=NULL) {
- // irq is (still) used by tape. tell ingo to try again later
- PRINT_ERR ("tape:Oper handler for irq %d called, but irq is still (internally) used.\n",irq);
- rc = -EAGAIN;
- goto out;
- }
-
- rc = get_dev_info_by_irq (irq, &dinfo);
- if (rc == -ENODEV) {
- PRINT_ERR ("tape: Cannot get dev info for irq %d in the oper handler.\n",irq);
- rc = -EAGAIN;
- goto out;
- }
-
- read_lock_irqsave(&tape_discipline_lock,lockflags);
-
- disc = tape_first_disc;
- while ((disc != NULL) && (disc->cu_type != dinfo.sid_data.cu_type))
- disc = (tape_discipline_t *) (disc->next);
-
- if (disc == NULL){
- PRINT_WARN ("tape: No matching discipline for cu_type %x found in the oper handler, ignoring device %04x.\n",dinfo.sid_data.cu_type,dinfo.devno);
- rc = -ENODEV;
- goto out_unlock;
- }
-
- /* Allocate tape structure */
- td = tape_create_device(irq,dinfo.devno,disc);
-
- if (td == NULL) {
- PRINT_WARN( "Could not initialize tape 0x%x\n",dinfo.devno);
- rc = -ENOBUFS;
- goto out_unlock;
- } else {
- if(disc->init_device)
- disc->init_device(td);
- }
- tape_state_set (td, TS_UNUSED);
-out_unlock:
- read_unlock_irqrestore(&tape_discipline_lock,lockflags);
-out:
- return rc;
-}
-
-/*
- * Not Oper Handler is called from Ingo's IO layer, when a tape device
- * is detached. We deq, disable and free the tape info for this device
- */
-
-static void
-tape_noper_handler ( int irq, int status ) {
- tape_dev_t *td;
- long lockflags;
- tape_ccw_req_t *treq;
-
- td = tape_get_device_by_irq(irq);
- if (td==NULL) {
- PRINT_ERR("tape: not operational handler called for irq %x, but tape does not hold this irq.\n",irq);
- goto error;
- }
-
- write_lock_irqsave(&tape_dev_lock,lockflags);
- tape_deq_device(td);
- write_unlock_irqrestore(&tape_dev_lock,lockflags);
-
- tape_disable_device(td);
-
- s390irq_spin_lock_irqsave (td->devinfo.irq, lockflags);
- treq = tape_get_active_ccw_req(td);
- if (treq) {
- // device is in use!
- treq->rc= -ENODEV;
- if(treq->wakeup)
- treq->wakeup (treq);
- PRINT_WARN ("Tape #%d is detached while it was busy.\n",td->first_minor/TAPE_MINORS_PER_DEV);
- } else {
- // device is unused!
- PRINT_WARN ("Tape #%d is detached now.\n",td->first_minor/TAPE_MINORS_PER_DEV);
- }
-
- s390irq_spin_unlock_irqrestore (td->devinfo.irq, lockflags);
-
- /* decrement use count twice ! */
- tape_put_device(td);
- tape_put_device(td);
-error:
- return;
-}
-
-/*
- * Write sense data to dbf
- */
-
-void tape_dump_sense_dbf(tape_dev_t* td)
-{
- devstat_t *stat = &td->devstat;
- const char* op;
- if(TAPE_BUSY(td))
- op = tape_op_verbose[tape_get_active_ccw_req(td)->op];
- else
- op = "---";
- tape_sprintf_event (tape_dbf_area,3,"DSTAT : %02x CSTAT: %02x\n",stat->dstat,stat->cstat);
- tape_sprintf_event (tape_dbf_area,3,"DEVICE: %04x OP : %s\n",td->devinfo.devno,op);
- tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[0]),*((unsigned int*)&stat->ii.sense.data[4]));
- tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[8]),*((unsigned int*)&stat->ii.sense.data[12]));
- tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[16]),*((unsigned int*)&stat->ii.sense.data[20]));
- tape_sprintf_event (tape_dbf_area,3,"%08x %08x\n",*((unsigned int*)&stat->ii.sense.data[24]),*((unsigned int*)&stat->ii.sense.data[28]));
-}
-
-/*
- * Write sense data to console/dbf
- */
-
-void
-tape_dump_sense (tape_dev_t* td)
-{
- devstat_t *stat = &td->devstat;
-#if 1 /* XXX */
- PRINT_INFO ("-------------------------------------------------\n");
- PRINT_INFO ("DSTAT : %02x CSTAT: %02x CPA: %04x\n",stat->dstat,stat->cstat,stat->cpa);
- PRINT_INFO ("DEVICE: %04x\n",td->devinfo.devno);
- if(TAPE_BUSY(td))
- PRINT_INFO("OP : %s\n",tape_op_verbose[tape_get_active_ccw_req(td)->op]);
-
- PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
- " %02X%02X%02X%02X %02X%02X%02X%02X \n",
- stat->ii.sense.data[0], stat->ii.sense.data[1],
- stat->ii.sense.data[2], stat->ii.sense.data[3],
- stat->ii.sense.data[4], stat->ii.sense.data[5],
- stat->ii.sense.data[6], stat->ii.sense.data[7],
- stat->ii.sense.data[8], stat->ii.sense.data[9],
- stat->ii.sense.data[10], stat->ii.sense.data[11],
- stat->ii.sense.data[12], stat->ii.sense.data[13],
- stat->ii.sense.data[14], stat->ii.sense.data[15]);
- PRINT_INFO ("Sense data: %02X%02X%02X%02X %02X%02X%02X%02X "
- " %02X%02X%02X%02X %02X%02X%02X%02X \n",
- stat->ii.sense.data[16], stat->ii.sense.data[17],
- stat->ii.sense.data[18], stat->ii.sense.data[19],
- stat->ii.sense.data[20], stat->ii.sense.data[21],
- stat->ii.sense.data[22], stat->ii.sense.data[23],
- stat->ii.sense.data[24], stat->ii.sense.data[25],
- stat->ii.sense.data[26], stat->ii.sense.data[27],
- stat->ii.sense.data[28], stat->ii.sense.data[29],
- stat->ii.sense.data[30], stat->ii.sense.data[31]);
- PRINT_INFO ("--------------------------------------------------\n");
-#endif
-}
-
-/*******************************************************************
- * TAPE Discipline functions
- *******************************************************************/
-
-/*
- * Register backend discipline
- */
-
-int
-tape_register_discipline(tape_discipline_t *disc)
-{
- tape_discipline_t *disc_ptr;
- long lockflags;
-
- disc->next = NULL;
-
- write_lock_irqsave(&tape_discipline_lock,lockflags);
-
- if (tape_first_disc == NULL) {
- tape_first_disc = disc;
- } else {
- for(disc_ptr = tape_first_disc; disc_ptr->next!=NULL; disc_ptr=(tape_discipline_t*)disc_ptr->next);
- disc_ptr->next = disc;
- }
-
- tape_create_devs_for_disc(disc);
- if(tape_autoprobe)
- tape_create_devreg_for_disc(disc);
-
- write_unlock_irqrestore(&tape_discipline_lock,lockflags);
- return 0;
-}
-
-/*
- * Unregister backend discipline
- */
-
-void
-tape_unregister_discipline(tape_discipline_t* disc)
-{
- tape_discipline_t* lastdisc;
- long lockflags;
-
- write_lock_irqsave(&tape_discipline_lock,lockflags);
-
- tape_delete_devs_for_disc(disc);
- if(tape_autoprobe)
- tape_delete_devreg_for_disc(disc);
-
- if (disc==tape_first_disc) {
- tape_first_disc=disc->next;
- } else {
- lastdisc=tape_first_disc;
- while (lastdisc->next!=disc) lastdisc=lastdisc->next;
- lastdisc->next=disc->next;
- }
-
- disc->shutdown();
-
- write_unlock_irqrestore(&tape_discipline_lock,lockflags);
-}
-
-/*
- * Cleanup all registered disciplines
- */
-
-static inline void
-tape_cleanup_disciplines (void)
-{
- long lockflags;
- tape_discipline_t* disc;
- /* Unregister all backend disciplines - this also deletes the devices */
-
- write_lock_irqsave(&tape_discipline_lock,lockflags);
- disc=tape_first_disc;
- while (disc != NULL) {
- write_unlock_irqrestore(&tape_discipline_lock,lockflags);
- tape_unregister_discipline(disc);
- kfree(disc);
- write_lock_irqsave(&tape_discipline_lock,lockflags);
- disc=tape_first_disc;
- }
- write_unlock_irqrestore(&tape_discipline_lock,lockflags);
-}
-
-
-/*******************************************************************
- * TAPE Init Functions
- *******************************************************************/
-
-/*
- * tape_print_banner will be called on initialisation and print a nice banner
- */
-
-static inline void
-tape_print_banner (void)
-{
- char *opt_char,*opt_block;
-
- /* print banner */
- PRINT_WARN ("IBM zSeries Tape Device Driver (v%d.%02d).\n",TAPE_VERSION_MAJOR,TAPE_VERSION_MINOR);
- PRINT_WARN ("(C) IBM Deutschland Entwicklung GmbH, 2000 - 2001\n");
- opt_char=opt_block="not present";
-#ifdef CONFIG_S390_TAPE_CHAR
- opt_char="built in";
-#endif
-#ifdef CONFIG_S390_TAPE_BLOCK
- opt_block="built in";
-#endif
- /* print feature info */
- PRINT_WARN ("character device frontend : %s\n",opt_char);
- PRINT_WARN ("block device frontend : %s\n",opt_block);
-}
-
-/*
- * tape_init will register the driver for each tape.
- */
-
-int
-tape_init (void)
-{
- static int initialized=0;
-
- if (initialized) // Only init the devices once
- return 0;
- initialized=1;
-
- tape_init_devregs();
-#ifdef TAPE_DEBUG
- tape_dbf_area = debug_register ( "tape", 2, 2, 3*sizeof(long));
- debug_register_view(tape_dbf_area,&debug_sprintf_view);
- tape_sprintf_event (tape_dbf_area,3,"begin init\n");
-#endif /* TAPE_DEBUG */
- tape_print_banner();
-#ifndef MODULE
- tape_split_parm_string(tape_parm_string);
-#endif
-#ifdef CONFIG_DEVFS_FS
- devfs_mk_dir (NULL, "tape", NULL);
-#endif /* CONFIG_DEVFS_FS */
-
- tape_sprintf_event (tape_dbf_area,3,"dev detect\n");
- /* Allocate the tape structures */
- if (*tape!=NULL) { /* if parameters are present */
- PRINT_INFO ("Using ranges supplied in parameters, disabling autoprobe mode.\n");
- tape_parm_parse (tape);
- tape_autoprobe = 0;
- } else {
- PRINT_INFO ("No parameters supplied, enabling autoprobe mode for all supported devices.\n");
- tape_autoprobe = 1;
- }
-#ifdef CONFIG_PROC_FS
- tape_proc_init();
-#endif /* CONFIG_PROC_FS */
-#ifdef CONFIG_S390_TAPE_3480
- tape_register_discipline(tape3480_init());
-#else
-#ifndef CONFIG_S390_TAPE
- tape_request_module("tape_3480_mod");
-#endif
-#endif /* CONFIG_S390_TAPE_3480 */
-
-#ifdef CONFIG_S390_TAPE_3490
- tape_register_discipline(tape3490_init());
-#else
-#ifndef CONFIG_S390_TAPE
- tape_request_module("tape_3490_mod");
-#endif
-#endif /* CONFIG_S390_TAPE_3490 */
-
-#ifdef CONFIG_S390_TAPE_3590
- tape_register_discipline(tape3590_init());
-#else
-#ifndef CONFIG_S390_TAPE
- tape_request_module("tape_3590_mod");
-#endif
-#endif /* CONFIG_S390_TAPE_3590 */
- return 0;
-}
-
-/*******************************************************************
- * TAPE Module functions
- *******************************************************************/
-
-#ifdef MODULE
-MODULE_AUTHOR("(C) 2001 IBM Deutschland Entwicklung GmbH by Carsten Otte and Michael Holzheu (cotte@de.ibm.com,holzheu@de.ibm.com)");
-MODULE_DESCRIPTION("Linux on zSeries channel attached tape device driver");
-MODULE_PARM (tape, "1-" __MODULE_STRING (256) "s");
-
-/*
- * The famous init_module
- */
-
-int
-init_module (void)
-{
-#ifdef CONFIG_S390_TAPE_CHAR
- tapechar_init ();
-#endif
-#ifdef CONFIG_S390_TAPE_BLOCK
- tapeblock_init ();
-#endif
- return 0;
-}
-
-/*
- * Cleanup the frontends
- */
-static inline void
-tape_cleanup_frontends(void)
-{
- tape_frontend_t* frontend, *tempfe;
-
- /* Now get rid of the frontends */
-#ifdef CONFIG_S390_TAPE_CHAR
- tapechar_uninit();
-#endif
-#ifdef CONFIG_S390_TAPE_BLOCK
- tapeblock_uninit();
-#endif
- frontend=tape_first_front;
- while (frontend != NULL) {
- tempfe = frontend;
- frontend = frontend->next;
- kfree (tempfe);
- }
-}
-
-
-/*
- * Cleanup module
- */
-
-void
-cleanup_module (void)
-{
- tape_sprintf_event (tape_dbf_area,6,"cleaup mod");
- tape_cleanup_disciplines();
-#ifdef CONFIG_DEVFS_FS
- devfs_remove("tape"); /* devfs checks for NULL */
-#endif CONFIG_DEVFS_FS
-#ifdef CONFIG_PROC_FS
- tape_proc_cleanup();
-#endif
- tape_cleanup_frontends();
- /* Deallocate devregs in case of not autoprobe */
- if(!tape_autoprobe)
- tape_delete_all_devregs();
-#ifdef TAPE_DEBUG
- debug_unregister (tape_dbf_area);
-#endif /* TAPE_DEBUG */
-}
-#endif /* MODULE */
-
-
-/*******************************************************************
- * TAPE Tapestate functions
- *******************************************************************/
-
-inline void
-tape_state_set (tape_dev_t * td, tape_state_t newstate)
-{
- if (td->tape_state == TS_NOT_OPER) {
- tape_sprintf_event(tape_dbf_area,3,"ts_set err: not oper\n");
- } else {
- tape_sprintf_event(tape_dbf_area,4,"ts. dev: %x\n",td->first_minor);
- tape_sprintf_event(tape_dbf_area,4,"old ts: %s\n",(((tape_state_get (td) < TO_SIZE) && (tape_state_get (td) >=0 )) ? tape_state_verbose[tape_state_get (td)] : "UNKNOWN TS"));
- tape_sprintf_event(tape_dbf_area,4,"%s\n",
- (((tape_state_get (td) < TO_SIZE) &&
- (tape_state_get (td) >=0 )) ?
- tape_state_verbose[tape_state_get (td)] :
- "UNKNOWN TS"));
- tape_sprintf_event (tape_dbf_area,4,"new ts: \n");
- tape_sprintf_event (tape_dbf_area,4,"%s\n",(((newstate < TO_SIZE) &&
- (newstate >= 0)) ?
- tape_state_verbose[newstate] :
- "UNKNOWN TS"));
- td->tape_state = newstate;
- }
-}
-
-inline tape_state_t
-tape_state_get (tape_dev_t * td)
-{
- return (td->tape_state);
-}
-
-inline void
-tape_med_state_set(tape_dev_t * td, tape_medium_state_t newstate)
-{
- if(td->medium_state == newstate)
- goto out;
- switch(newstate){
- case MS_UNLOADED:
- PRINT_INFO("(%x): Tape is unloaded\n",td->devstat.devno);
- break;
- case MS_LOADED:
- PRINT_INFO("(%x): Tape has been mounted\n",td->devstat.devno);
- break;
- default:
- // print nothing
- break;
- }
- td->medium_state = newstate;
-out:
- return;
-}
-
-
-/*******************************************************************
- * TAPE Exported Functions
- *******************************************************************/
-
-EXPORT_SYMBOL(tape_register_discipline);
-EXPORT_SYMBOL(tape_unregister_discipline);
-EXPORT_SYMBOL(tape_dbf_area);
-EXPORT_SYMBOL(tape_alloc_ccw_req);
-EXPORT_SYMBOL(tape_free_ccw_req);
-EXPORT_SYMBOL(tape_state_set);
-EXPORT_SYMBOL(tape_state_get);
-EXPORT_SYMBOL(tape_med_state_set);
-EXPORT_SYMBOL(tape_state_verbose);
-EXPORT_SYMBOL(tape_op_verbose);
-EXPORT_SYMBOL(tape_dump_sense);
-EXPORT_SYMBOL(tape_dump_sense_dbf);
-EXPORT_SYMBOL(tape_do_io);
-EXPORT_SYMBOL(tape_do_io_irq);
-EXPORT_SYMBOL(tape_do_io_and_wait);
-EXPORT_SYMBOL(tape_remove_ccw_req);
-EXPORT_SYMBOL(tape_get_active_ccw_req);
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-12-12 18:12 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2002-12-12 18:08 [PATCH] s390 (5/8): old tape file Martin Schwidefsky
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.