/* -*- linux-c -*-
* drivers/char/viotape.c
*
* iSeries Virtual Tape
*
* Authors: Dave Boutcher <boutcher@us.ibm.com>
* Ryan Arnold <ryanarn@us.ibm.com>
* Colin Devilbiss <devilbis@us.ibm.com>
* Stephen Rothwell <sfr@au1.ibm.com>
*
* (C) Copyright 2000-2004 IBM Corporation
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) anyu later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* This routine provides access to tape drives owned and managed by an OS/400
* partition running on the same box as this Linux partition.
*
* All tape operations are performed by sending messages back and forth to
* the OS/400 partition. The format of the messages is defined in
* iSeries/vio.h
*/
#include <linux/config.h>
#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/wait.h>
#include <linux/spinlock.h>
#include <linux/mtio.h>
#include <linux/device.h>
#include <linux/dma-mapping.h>
#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/devfs_fs_kernel.h>
#include <linux/major.h>
#include <linux/completion.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <asm/uaccess.h>
#include <asm/ioctls.h>
#include <asm/vio.h>
#include <asm/iSeries/vio.h>
#include <asm/iSeries/HvLpEvent.h>
#include <asm/iSeries/HvCallEvent.h>
#include <asm/iSeries/HvLpConfig.h>
#define VIOTAPE_VERSION "1.2"
#define VIOTAPE_MAXREQ 1
#define VIOTAPE_KERN_WARN KERN_WARNING "viotape: "
#define VIOTAPE_KERN_INFO KERN_INFO "viotape: "
static int viotape_numdev;
/*
* The minor number follows the conventions of the SCSI tape drives. The
* rewind and mode are encoded in the minor #. We use this struct to break
* them out
*/
struct viot_devinfo_struct {
int devno;
int mode;
int rewind;
};
#define VIOTAPOP_RESET 0
#define VIOTAPOP_FSF 1
#define VIOTAPOP_BSF 2
#define VIOTAPOP_FSR 3
#define VIOTAPOP_BSR 4
#define VIOTAPOP_WEOF 5
#define VIOTAPOP_REW 6
#define VIOTAPOP_NOP 7
#define VIOTAPOP_EOM 8
#define VIOTAPOP_ERASE 9
#define VIOTAPOP_SETBLK 10
#define VIOTAPOP_SETDENSITY 11
#define VIOTAPOP_SETPOS 12
#define VIOTAPOP_GETPOS 13
#define VIOTAPOP_SETPART 14
#define VIOTAPOP_UNLOAD 15
struct viotapelpevent {
struct HvLpEvent event;
u32 reserved;
u16 version;
u16 sub_type_result;
u16 tape;
u16 flags;
u32 token;
u64 len;
union {
struct {
u32 tape_op;
u32 count;
} op;
struct {
u32 type;
u32 resid;
u32 dsreg;
u32 gstat;
u32 erreg;
u32 file_no;
u32 block_no;
} get_status;
struct {
u32 block_no;
} get_pos;
} u;
};
enum viotapesubtype {
viotapeopen = 0x0001,
viotapeclose = 0x0002,
viotaperead = 0x0003,
viotapewrite = 0x0004,
viotapegetinfo = 0x0005,
viotapeop = 0x0006,
viotapegetpos = 0x0007,
viotapesetpos = 0x0008,
viotapegetstatus = 0x0009
};
enum viotaperc {
viotape_InvalidRange = 0x0601,
viotape_InvalidToken = 0x0602,
viotape_DMAError = 0x0603,
viotape_UseError = 0x0604,
viotape_ReleaseError = 0x0605,
viotape_InvalidTape = 0x0606,
viotape_InvalidOp = 0x0607,
viotape_TapeErr = 0x0608,
viotape_AllocTimedOut = 0x0640,
viotape_BOTEnc = 0x0641,
viotape_BlankTape = 0x0642,
viotape_BufferEmpty = 0x0643,
viotape_CleanCartFound = 0x0644,
viotape_CmdNotAllowed = 0x0645,
viotape_CmdNotSupported = 0x0646,
viotape_DataCheck = 0x0647,
viotape_DecompressErr = 0x0648,
viotape_DeviceTimeout = 0x0649,
viotape_DeviceUnavail = 0x064a,
viotape_DeviceBusy = 0x064b,
viotape_EndOfMedia = 0x064c,
viotape_EndOfTape = 0x064d,
viotape_EquipCheck = 0x064e,
viotape_InsufficientRs = 0x064f,
viotape_InvalidLogBlk = 0x0650,
viotape_LengthError = 0x0651,
viotape_LibDoorOpen = 0x0652,
viotape_LoadFailure = 0x0653,
viotape_NotCapable = 0x0654,
viotape_NotOperational = 0x0655,
viotape_NotReady