2 * drivers/char/viotape.c
5 ***************************************************************************
7 * Authors: Dave Boutcher <boutcher@us.ibm.com>
8 * Ryan Arnold <ryanarn@us.ibm.com>
9 * Colin Devilbiss <devilbis@us.ibm.com>
11 * (C) Copyright 2000 IBM Corporation
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation; either version 2 of the
16 * License, or (at your option) anyu later version.
18 * This program is distributed in the hope that it will be useful, but
19 * WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 * General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software Foundation,
25 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 ***************************************************************************
28 * This routine provides access to tape drives owned and managed by an OS/400
29 * partition running on the same box as this Linux partition.
31 * All tape operations are performed by sending messages back and forth to
32 * the OS/400 partition. The format of the messages is defined in
40 #include <linux/config.h>
41 #include <linux/version.h>
42 #include <linux/module.h>
43 #include <linux/kernel.h>
44 #include <linux/proc_fs.h>
45 #include <linux/errno.h>
46 #include <linux/init.h>
47 #include <linux/wait.h>
48 #include <linux/spinlock.h>
49 #include <asm/ioctls.h>
50 #include <linux/mtio.h>
51 #include <linux/pci.h>
52 #include <linux/devfs_fs.h>
53 #include <linux/devfs_fs_kernel.h>
54 #include <asm/uaccess.h>
57 #include <asm/iSeries/HvLpEvent.h>
58 #include "asm/iSeries/HvCallEvent.h"
59 #include "asm/iSeries/HvLpConfig.h"
60 #include <asm/iSeries/iSeries_proc.h>
62 extern struct pci_dev * iSeries_vio_dev;
64 static int viotape_major = 230;
65 static int viotape_numdev = 0;
67 #define VIOTAPE_MAXREQ 1
69 /* version number for viotape driver */
70 static unsigned int version_major = 1;
71 static unsigned int version_minor = 0;
78 /***************************************************************************
79 * The minor number follows the conventions of the SCSI tape drives. The
80 * rewind and mode are encoded in the minor #. We use this struct to break
82 ***************************************************************************/
83 struct viot_devinfo_struct {
91 #define VIOTAPOP_RESET 0
92 #define VIOTAPOP_FSF 1
93 #define VIOTAPOP_BSF 2
94 #define VIOTAPOP_FSR 3
95 #define VIOTAPOP_BSR 4
96 #define VIOTAPOP_WEOF 5
97 #define VIOTAPOP_REW 6
98 #define VIOTAPOP_NOP 7
99 #define VIOTAPOP_EOM 8
100 #define VIOTAPOP_ERASE 9
101 #define VIOTAPOP_SETBLK 10
102 #define VIOTAPOP_SETDENSITY 11
103 #define VIOTAPOP_SETPOS 12
104 #define VIOTAPOP_GETPOS 13
105 #define VIOTAPOP_SETPART 14
107 struct viotapelpevent {
108 struct HvLpEvent event;
135 enum viotapesubtype {
136 viotapeopen = 0x0001,
137 viotapeclose = 0x0002,
138 viotaperead = 0x0003,
139 viotapewrite = 0x0004,
140 viotapegetinfo = 0x0005,
142 viotapegetpos = 0x0007,
143 viotapesetpos = 0x0008,
144 viotapegetstatus = 0x0009
148 viotape_InvalidRange = 0x0601,
149 viotape_InvalidToken = 0x0602,
150 viotape_DMAError = 0x0603,
151 viotape_UseError = 0x0604,
152 viotape_ReleaseError = 0x0605,
153 viotape_InvalidTape = 0x0606,
154 viotape_InvalidOp = 0x0607,
155 viotape_TapeErr = 0x0608,
157 viotape_AllocTimedOut = 0x0640,
158 viotape_BOTEnc = 0x0641,
159 viotape_BlankTape = 0x0642,
160 viotape_BufferEmpty = 0x0643,
161 viotape_CleanCartFound = 0x0644,
162 viotape_CmdNotAllowed = 0x0645,
163 viotape_CmdNotSupported = 0x0646,
164 viotape_DataCheck = 0x0647,
165 viotape_DecompressErr = 0x0648,
166 viotape_DeviceTimeout = 0x0649,
167 viotape_DeviceUnavail = 0x064a,
168 viotape_DeviceBusy = 0x064b,
169 viotape_EndOfMedia = 0x064c,
170 viotape_EndOfTape = 0x064d,
171 viotape_EquipCheck = 0x064e,
172 viotape_InsufficientRs = 0x064f,
173 viotape_InvalidLogBlk = 0x0650,
174 viotape_LengthError = 0x0651,
175 viotape_LibDoorOpen = 0x0652,
176 viotape_LoadFailure = 0x0653,
177 viotape_NotCapable = 0x0654,
178 viotape_NotOperational = 0x0655,
179 viotape_NotReady = 0x0656,
180 viotape_OpCancelled = 0x0657,
181 viotape_PhyLinkErr = 0x0658,
182 viotape_RdyNotBOT = 0x0659,
183 viotape_TapeMark = 0x065a,
184 viotape_WriteProt = 0x065b
187 /* Maximum # tapes we support
189 #define VIOTAPE_MAX_TAPE 8
190 #define MAX_PARTITIONS 4
192 /* defines for current tape state */
194 #define VIOT_READING 1
195 #define VIOT_WRITING 2
197 /* Our info on the tapes
205 static struct tape_descr *viotape_unitinfo = NULL;
207 static char *lasterr[VIOTAPE_MAX_TAPE];
209 static struct mtget viomtget[VIOTAPE_MAX_TAPE];
211 /* maintain the current state of each tape (and partition)
212 so that we know when to write EOF marks.
215 unsigned char cur_part;
216 devfs_handle_t dev_handle;
219 } part_stat[MAX_PARTITIONS];
220 } state[VIOTAPE_MAX_TAPE];
224 static struct semaphore reqSem;
226 /* When we send a request, we use this struct to get the response back
227 * from the interrupt handler
234 struct semaphore *sem;
235 struct opStruct *free;
238 static spinlock_t opStructListLock;
239 static struct opStruct *opStructList;
241 /* forward declaration to resolve interdependence */
242 static int chg_state(int index, unsigned char new_state,
245 /* Decode the kdev_t into its parts
247 void getDevInfo(kdev_t dev, struct viot_devinfo_struct *devi)
249 devi->major = MAJOR(dev);
250 devi->minor = MINOR(dev);
251 devi->devno = devi->minor & 0x1F;
252 devi->mode = (devi->minor & 0x60) >> 5;
253 /* if bit is set in the minor, do _not_ rewind automatically */
254 devi->rewind = !(devi->minor & 0x80);
258 /* Allocate an op structure from our pool
260 static struct opStruct *getOpStruct(void)
262 struct opStruct *newOpStruct;
263 spin_lock(&opStructListLock);
265 if (opStructList == NULL) {
266 newOpStruct = kmalloc(sizeof(struct opStruct), GFP_KERNEL);
268 newOpStruct = opStructList;
269 opStructList = opStructList->free;
273 memset(newOpStruct, 0x00, sizeof(struct opStruct));
275 spin_unlock(&opStructListLock);
280 /* Return an op structure to our pool
282 static void freeOpStruct(struct opStruct *opStruct)
284 spin_lock(&opStructListLock);
285 opStruct->free = opStructList;
286 opStructList = opStruct;
287 spin_unlock(&opStructListLock);
290 /* Map our tape return codes to errno values
292 int tapeRcToErrno(int tapeRc, char *operation, int tapeno)
300 case viotape_InvalidRange:
302 tmsg = "Internal error";
304 case viotape_InvalidToken:
306 tmsg = "Internal error";
308 case viotape_DMAError:
312 case viotape_UseError:
314 tmsg = "Internal error";
316 case viotape_ReleaseError:
318 tmsg = "Internal error";
320 case viotape_InvalidTape:
322 tmsg = "Invalid tape device";
324 case viotape_InvalidOp:
326 tmsg = "Invalid operation";
328 case viotape_TapeErr:
333 case viotape_AllocTimedOut:
335 tmsg = "Allocate timed out";
339 tmsg = "Beginning of tape encountered";
341 case viotape_BlankTape:
345 case viotape_BufferEmpty:
347 tmsg = "Buffer empty";
349 case viotape_CleanCartFound:
351 tmsg = "Cleaning cartridge found";
353 case viotape_CmdNotAllowed:
355 tmsg = "Command not allowed";
357 case viotape_CmdNotSupported:
359 tmsg = "Command not supported";
361 case viotape_DataCheck:
365 case viotape_DecompressErr:
367 tmsg = "Decompression error";
369 case viotape_DeviceTimeout:
371 tmsg = "Device timeout";
373 case viotape_DeviceUnavail:
375 tmsg = "Device unavailable";
377 case viotape_DeviceBusy:
379 tmsg = "Device busy";
381 case viotape_EndOfMedia:
383 tmsg = "End of media";
385 case viotape_EndOfTape:
387 tmsg = "End of tape";
389 case viotape_EquipCheck:
391 tmsg = "Equipment check";
393 case viotape_InsufficientRs:
395 tmsg = "Insufficient tape resources";
397 case viotape_InvalidLogBlk:
399 tmsg = "Invalid logical block location";
401 case viotape_LengthError:
403 tmsg = "Length error";
405 case viotape_LibDoorOpen:
409 case viotape_LoadFailure:
411 tmsg = "Load failure";
413 case viotape_NotCapable:
415 tmsg = "Not capable";
417 case viotape_NotOperational:
419 tmsg = "Not operational";
421 case viotape_NotReady:
425 case viotape_OpCancelled:
427 tmsg = "Operation cancelled";
429 case viotape_PhyLinkErr:
431 tmsg = "Physical link error";
433 case viotape_RdyNotBOT:
435 tmsg = "Ready but not beginning of tape";
437 case viotape_TapeMark:
441 case viotape_WriteProt:
443 tmsg = "Write protection error";
450 printk(KERN_WARNING_VIO "tape error on Device %d (%10.10s): %s\n",
451 tapeno, viotape_unitinfo[tapeno].rsrcname, tmsg);
453 lasterr[tapeno] = tmsg;
458 /* Handle reads from the proc file system.
460 static int proc_read(char *buf, char **start, off_t offset,
461 int blen, int *eof, void *data)
466 len += sprintf(buf + len, "viotape driver version %d.%d\n",
467 version_major, version_minor);
469 for (i = 0; i < viotape_numdev; i++) {
473 "viotape device %d is iSeries resource %10.10s type %4.4s, model %3.3s\n",
474 i, viotape_unitinfo[i].rsrcname,
475 viotape_unitinfo[i].type,
476 viotape_unitinfo[i].model);
479 sprintf(buf + len, " last error: %s\n",
487 /* setup our proc file system entries
489 void viotape_proc_init(struct proc_dir_entry *iSeries_proc)
491 struct proc_dir_entry *ent;
493 create_proc_entry("viotape", S_IFREG | S_IRUSR, iSeries_proc);
498 ent->read_proc = proc_read;
501 /* clean up our proc file system entries
503 void viotape_proc_delete(struct proc_dir_entry *iSeries_proc)
505 remove_proc_entry("viotape", iSeries_proc);
509 /* Get info on all tapes from OS/400
511 static void get_viotape_info(void)
516 struct opStruct *op = getOpStruct();
517 DECLARE_MUTEX_LOCKED(Semaphore);
521 if (viotape_unitinfo == NULL) {
523 kmalloc(sizeof(struct tape_descr) * VIOTAPE_MAX_TAPE,
526 memset(viotape_unitinfo, 0x00,
527 sizeof(struct tape_descr) * VIOTAPE_MAX_TAPE);
528 memset(lasterr, 0x00, sizeof(lasterr));
530 op->sem = &Semaphore;
532 dmaaddr = pci_map_single(iSeries_vio_dev, viotape_unitinfo,
533 sizeof(struct tape_descr) *
534 VIOTAPE_MAX_TAPE, PCI_DMA_FROMDEVICE);
535 if (dmaaddr == 0xFFFFFFFF) {
536 printk(KERN_WARNING_VIO "viotape error allocating tce\n");
540 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
541 HvLpEvent_Type_VirtualIo,
542 viomajorsubtype_tape |
544 HvLpEvent_AckInd_DoAck,
545 HvLpEvent_AckType_ImmediateAck,
550 (u64) (unsigned long) op,
551 VIOVERSION << 16, dmaaddr,
552 sizeof(struct tape_descr) *
553 VIOTAPE_MAX_TAPE, 0, 0);
554 if (hvrc != HvLpEvent_Rc_Good) {
555 printk("viotape hv error on op %d\n", (int) hvrc);
564 ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
566 printk("found a tape %10.10s\n",
567 viotape_unitinfo[i].rsrcname);
575 static ssize_t viotap_write(struct file *file, const char *buf,
576 size_t count, loff_t * ppos)
579 kdev_t dev = file->f_dentry->d_inode->i_rdev;
580 unsigned short flags = file->f_flags;
581 struct opStruct *op = getOpStruct();
582 int noblock = ((flags & O_NONBLOCK) != 0);
584 struct viot_devinfo_struct devi;
585 DECLARE_MUTEX_LOCKED(Semaphore);
590 getDevInfo(dev, &devi);
592 /* We need to make sure we can send a request. We use
593 * a semaphore to keep track of # requests in use. If
594 * we are non-blocking, make sure we don't block on the
598 if (down_trylock(&reqSem)) {
606 /* Allocate a DMA buffer */
607 op->buffer = pci_alloc_consistent(iSeries_vio_dev, count, &op->dmaaddr);
609 if ((op->dmaaddr == 0xFFFFFFFF) || (op->buffer == NULL)) {
610 printk(KERN_WARNING_VIO
611 "tape error allocating dma buffer for len %ld\n",
620 /* Copy the data into the buffer */
621 err = copy_from_user(op->buffer, (const void *) buf, count);
623 printk(KERN_WARNING_VIO
624 "tape: error on copy from user\n");
625 pci_free_consistent(iSeries_vio_dev, count, op->buffer, op->dmaaddr);
634 op->sem = &Semaphore;
637 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
638 HvLpEvent_Type_VirtualIo,
639 viomajorsubtype_tape |
641 HvLpEvent_AckInd_DoAck,
642 HvLpEvent_AckType_ImmediateAck,
647 (u64) (unsigned long) op,
650 devno << 48) | op->dmaaddr,
652 if (hvrc != HvLpEvent_Rc_Good) {
653 printk("viotape hv error on op %d\n", (int) hvrc);
654 pci_free_consistent(iSeries_vio_dev, count, op->buffer, op->dmaaddr);
667 /* Free the buffer */
668 pci_free_consistent(iSeries_vio_dev, count, op->buffer, op->dmaaddr);
675 return tapeRcToErrno(err, "write", devi.devno);
677 chg_state(devi.devno, VIOT_WRITING, file);
684 static ssize_t viotap_read(struct file *file, char *buf, size_t count,
688 kdev_t dev = file->f_dentry->d_inode->i_rdev;
689 unsigned short flags = file->f_flags;
690 struct opStruct *op = getOpStruct();
691 int noblock = ((flags & O_NONBLOCK) != 0);
693 struct viot_devinfo_struct devi;
694 DECLARE_MUTEX_LOCKED(Semaphore);
699 getDevInfo(dev, &devi);
701 /* We need to make sure we can send a request. We use
702 * a semaphore to keep track of # requests in use. If
703 * we are non-blocking, make sure we don't block on the
707 if (down_trylock(&reqSem)) {
715 chg_state(devi.devno, VIOT_READING, file);
717 /* Allocate a DMA buffer */
718 op->buffer = pci_alloc_consistent(iSeries_vio_dev, count, &op->dmaaddr);
720 if ((op->dmaaddr == 0xFFFFFFFF) || (op->buffer == NULL)) {
728 op->sem = &Semaphore;
730 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
731 HvLpEvent_Type_VirtualIo,
732 viomajorsubtype_tape |
734 HvLpEvent_AckInd_DoAck,
735 HvLpEvent_AckType_ImmediateAck,
740 (u64) (unsigned long) op,
743 devno << 48) | op->dmaaddr,
745 if (hvrc != HvLpEvent_Rc_Good) {
746 printk(KERN_WARNING_VIO
747 "tape hv error on op %d\n", (int) hvrc);
748 pci_free_consistent(iSeries_vio_dev, count, op->buffer, op->dmaaddr);
757 /* If we got data back */
759 /* Copy the data into the buffer */
760 err = copy_to_user(buf, op->buffer, count);
762 printk("error on copy_to_user\n");
763 pci_free_consistent(iSeries_vio_dev, count,
775 /* Free the buffer */
776 pci_free_consistent(iSeries_vio_dev, count, op->buffer, op->dmaaddr);
782 return tapeRcToErrno(err, "read", devi.devno);
789 static int viotap_ioctl(struct inode *inode, struct file *file,
790 unsigned int cmd, unsigned long arg)
794 DECLARE_MUTEX_LOCKED(Semaphore);
795 kdev_t dev = file->f_dentry->d_inode->i_rdev;
796 struct opStruct *op = getOpStruct();
797 struct viot_devinfo_struct devi;
801 getDevInfo(dev, &devi);
810 /* inode is null if and only if we (the kernel) made the request */
812 memcpy(&mtc, (void *) arg,
813 sizeof(struct mtop));
814 else if (copy_from_user
815 ((char *) &mtc, (char *) arg,
816 sizeof(struct mtop))) {
824 myOp = VIOTAPOP_RESET;
839 myOp = VIOTAPOP_WEOF;
851 myOp = VIOTAPOP_ERASE;
854 myOp = VIOTAPOP_SETBLK;
857 myOp = VIOTAPOP_SETDENSITY;
860 myOp = VIOTAPOP_GETPOS;
863 myOp = VIOTAPOP_SETPOS;
866 myOp = VIOTAPOP_SETPART;
872 /* if we moved the head, we are no longer reading or writing */
881 chg_state(devi.devno, VIOT_IDLE, file);
884 op->sem = &Semaphore;
886 HvCallEvent_signalLpEventFast(viopath_hostLp,
887 HvLpEvent_Type_VirtualIo,
890 HvLpEvent_AckInd_DoAck,
891 HvLpEvent_AckType_ImmediateAck,
904 if (hvrc != HvLpEvent_Rc_Good) {
905 printk("viotape hv error on op %d\n",
915 return tapeRcToErrno(op->rc,
927 op->sem = &Semaphore;
928 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
929 HvLpEvent_Type_VirtualIo,
930 viomajorsubtype_tape |
932 HvLpEvent_AckInd_DoAck,
933 HvLpEvent_AckType_ImmediateAck,
938 (u64) (unsigned long)
939 op, VIOVERSION << 16,
943 if (hvrc != HvLpEvent_Rc_Good) {
944 printk("viotape hv error on op %d\n", (int) hvrc);
953 return tapeRcToErrno(op->rc, "get status",
958 copy_to_user((void *) arg, &viomtget[dev],
959 sizeof(viomtget[0]));
968 printk("Got an MTIOCPOS\n");
977 static int viotap_open(struct inode *inode, struct file *file)
979 DECLARE_MUTEX_LOCKED(Semaphore);
980 kdev_t dev = file->f_dentry->d_inode->i_rdev;
982 struct opStruct *op = getOpStruct();
983 struct viot_devinfo_struct devi;
987 getDevInfo(dev, &devi);
989 // Note: We currently only support one mode!
990 if ((devi.devno >= viotape_numdev) || (devi.mode)) {
995 op->sem = &Semaphore;
997 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
998 HvLpEvent_Type_VirtualIo,
999 viomajorsubtype_tape |
1001 HvLpEvent_AckInd_DoAck,
1002 HvLpEvent_AckType_ImmediateAck,
1007 (u64) (unsigned long) op,
1009 ((u64) devi.devno << 48), 0,
1014 printk("viotape bad rc on signalLpEvent %d\n", (int) hvrc);
1023 return tapeRcToErrno(op->rc, "open", devi.devno);
1034 static int viotap_release(struct inode *inode, struct file *file)
1036 DECLARE_MUTEX_LOCKED(Semaphore);
1037 kdev_t dev = file->f_dentry->d_inode->i_rdev;
1039 struct viot_devinfo_struct devi;
1040 struct opStruct *op = getOpStruct();
1044 op->sem = &Semaphore;
1046 getDevInfo(dev, &devi);
1048 if (devi.devno >= viotape_numdev) {
1053 chg_state(devi.devno, VIOT_IDLE, file);
1056 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
1057 HvLpEvent_Type_VirtualIo,
1058 viomajorsubtype_tape |
1060 HvLpEvent_AckInd_DoAck,
1061 HvLpEvent_AckType_ImmediateAck,
1066 (u64) (unsigned long)
1067 op, VIOVERSION << 16,
1070 ((u64) VIOTAPOP_REW)
1075 tapeRcToErrno(op->rc, "rewind", devi.devno);
1079 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
1080 HvLpEvent_Type_VirtualIo,
1081 viomajorsubtype_tape |
1083 HvLpEvent_AckInd_DoAck,
1084 HvLpEvent_AckType_ImmediateAck,
1089 (u64) (unsigned long) op,
1091 ((u64) devi.devno << 48), 0,
1096 printk("viotape: bad rc on signalLpEvent %d\n",
1104 printk("viotape: close failed\n");
1110 struct file_operations viotap_fops = {
1116 release:viotap_release,
1119 /* Handle interrupt events for tape
1121 static void vioHandleTapeEvent(struct HvLpEvent *event)
1124 struct opStruct *op;
1125 struct viotapelpevent *tevent = (struct viotapelpevent *) event;
1127 if (event == NULL) {
1128 /* Notification that a partition went away! */
1129 if (!viopath_isactive(viopath_hostLp)) {
1130 /* TODO! Clean up */
1135 tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
1136 switch (tapeminor) {
1137 case viotapegetinfo:
1140 op = (struct opStruct *) (unsigned long) event->
1142 op->rc = tevent->mSubTypeRc;
1147 op = (struct opStruct *) (unsigned long) event->
1149 op->rc = tevent->mSubTypeRc;;
1150 op->count = tevent->mLen;
1162 case viotapegetstatus:
1163 op = (struct opStruct *) (unsigned long) event->
1166 op->count = tevent->u.tapeOp.mCount;
1167 op->rc = tevent->mSubTypeRc;;
1175 printk("viotape: wierd ack\n");
1180 /* Do initialization
1182 int __init viotap_init(void)
1184 DECLARE_MUTEX_LOCKED(Semaphore);
1189 printk("viotape driver version %d.%d\n", version_major,
1192 sndMsgSeq = sndMsgAck = 0;
1193 rcvMsgSeq = rcvMsgAck = 0;
1194 opStructList = NULL;
1195 spin_lock_init(&opStructListLock);
1197 sema_init(&reqSem, VIOTAPE_MAXREQ);
1199 if (viopath_hostLp == HvLpIndexInvalid)
1203 * Open to our hosting lp
1205 if (viopath_hostLp == HvLpIndexInvalid)
1208 printk("viotape: init - open path to hosting (%d)\n",
1211 rc = viopath_open(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1213 printk("viotape: error on viopath_open to hostlp %d\n",
1217 vio_setHandler(viomajorsubtype_tape, vioHandleTapeEvent);
1219 printk("viotape major is %d\n", viotape_major);
1223 if (devfs_register_chrdev(viotape_major, "viotape", &viotap_fops)) {
1224 printk("Error registering viotape device\n");
1228 for (i = 0; i < viotape_numdev; i++) {
1230 state[i].cur_part = 0;
1231 for (j = 0; j < MAX_PARTITIONS; ++j)
1232 state[i].part_stat[j].rwi = VIOT_IDLE;
1233 sprintf(tapename, "viotape%d", i);
1234 state[i].dev_handle =
1235 devfs_register(NULL, tapename, DEVFS_FL_DEFAULT,
1237 S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
1238 S_IWGRP, &viotap_fops, NULL);
1240 ("viotape device %s is iSeries resource %10.10s type %4.4s, model %3.3s\n",
1241 tapename, viotape_unitinfo[i].rsrcname,
1242 viotape_unitinfo[i].type, viotape_unitinfo[i].model);
1246 * Create the proc entry
1248 iSeries_proc_callback(&viotape_proc_init);
1253 /* Give a new state to the tape object
1255 static int chg_state(int index, unsigned char new_state, struct file *file)
1257 unsigned char *cur_state =
1258 &state[index].part_stat[state[index].cur_part].rwi;
1261 /* if the same state, don't bother */
1262 if (*cur_state == new_state)
1265 /* write an EOF if changing from writing to some other state */
1266 if (*cur_state == VIOT_WRITING) {
1267 struct mtop write_eof = { MTWEOF, 1 };
1268 rc = viotap_ioctl(NULL, file, MTIOCTOP,
1269 (unsigned long) &write_eof);
1271 *cur_state = new_state;
1277 static void __exit viotap_exit(void)
1280 for (i = 0; i < viotape_numdev; ++i)
1281 devfs_unregister(state[i].dev_handle);
1282 ret = devfs_unregister_chrdev(viotape_major, "viotape");
1284 printk("Error unregistering device: %d\n", ret);
1285 iSeries_proc_callback(&viotape_proc_delete);
1286 if (viotape_unitinfo != NULL) {
1287 kfree(viotape_unitinfo);
1288 viotape_unitinfo = NULL;
1290 viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1291 vio_clearHandler(viomajorsubtype_tape);
1294 module_init(viotap_init);
1295 module_exit(viotap_exit);