setup enviroment for compilation
[linux-2.4.21-pre4.git] / drivers / iseries / viotape.c
1 /* -*- linux-c -*-
2  *  drivers/char/viotape.c
3  *
4  *  iSeries Virtual Tape
5  ***************************************************************************
6  *
7  *  Authors: Dave Boutcher <boutcher@us.ibm.com>
8  *           Ryan Arnold <ryanarn@us.ibm.com>
9  *           Colin Devilbiss <devilbis@us.ibm.com>
10  *
11  * (C) Copyright 2000 IBM Corporation
12  * 
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.
17  *
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.  
22  *
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
26  *
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.
30  *
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
33  * iSeries/vio.h
34  * 
35  */
36
37
38 #undef VIOT_DEBUG
39
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>
55
56 #include "vio.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>
61
62 extern struct pci_dev * iSeries_vio_dev;
63
64 static int viotape_major = 230;
65 static int viotape_numdev = 0;
66
67 #define VIOTAPE_MAXREQ 1
68
69 /* version number for viotape driver */
70 static unsigned int version_major = 1;
71 static unsigned int version_minor = 0;
72
73 static u64 sndMsgSeq;
74 static u64 sndMsgAck;
75 static u64 rcvMsgSeq;
76 static u64 rcvMsgAck;
77
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
81  * them out
82  ***************************************************************************/
83 struct viot_devinfo_struct {
84         int major;
85         int minor;
86         int devno;
87         int mode;
88         int rewind;
89 };
90
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
106
107 struct viotapelpevent {
108         struct HvLpEvent event;
109         u32 mReserved1;
110         u16 mVersion;
111         u16 mSubTypeRc;
112         u16 mTape;
113         u16 mFlags;
114         u32 mToken;
115         u64 mLen;
116         union {
117                 struct {
118                         u32 mTapeOp;
119                         u32 mCount;
120                 } tapeOp;
121                 struct {
122                         u32 mType;
123                         u32 mResid;
124                         u32 mDsreg;
125                         u32 mGstat;
126                         u32 mErreg;
127                         u32 mFileNo;
128                         u32 mBlkNo;
129                 } getStatus;
130                 struct {
131                         u32 mBlkNo;
132                 } getPos;
133         } u;
134 };
135 enum viotapesubtype {
136         viotapeopen = 0x0001,
137         viotapeclose = 0x0002,
138         viotaperead = 0x0003,
139         viotapewrite = 0x0004,
140         viotapegetinfo = 0x0005,
141         viotapeop = 0x0006,
142         viotapegetpos = 0x0007,
143         viotapesetpos = 0x0008,
144         viotapegetstatus = 0x0009
145 };
146
147 enum viotapeRc {
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,
156
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
185 };
186
187 /* Maximum # tapes we support
188  */
189 #define VIOTAPE_MAX_TAPE 8
190 #define MAX_PARTITIONS 4
191
192 /* defines for current tape state */
193 #define VIOT_IDLE 0
194 #define VIOT_READING 1
195 #define VIOT_WRITING 2
196
197 /* Our info on the tapes
198  */
199 struct tape_descr {
200         char rsrcname[10];
201         char type[4];
202         char model[3];
203 };
204
205 static struct tape_descr *viotape_unitinfo = NULL;
206
207 static char *lasterr[VIOTAPE_MAX_TAPE];
208
209 static struct mtget viomtget[VIOTAPE_MAX_TAPE];
210
211 /* maintain the current state of each tape (and partition)
212    so that we know when to write EOF marks.
213 */
214 static struct {
215         unsigned char cur_part;
216         devfs_handle_t dev_handle;
217         struct {
218                 unsigned char rwi;
219         } part_stat[MAX_PARTITIONS];
220 } state[VIOTAPE_MAX_TAPE];
221
222 /* We single-thread
223  */
224 static struct semaphore reqSem;
225
226 /* When we send a request, we use this struct to get the response back
227  * from the interrupt handler
228  */
229 struct opStruct {
230         void *buffer;
231         dma_addr_t dmaaddr;
232         size_t count;
233         int rc;
234         struct semaphore *sem;
235         struct opStruct *free;
236 };
237
238 static spinlock_t opStructListLock;
239 static struct opStruct *opStructList;
240
241 /* forward declaration to resolve interdependence */
242 static int chg_state(int index, unsigned char new_state,
243                      struct file *file);
244
245 /* Decode the kdev_t into its parts
246  */
247 void getDevInfo(kdev_t dev, struct viot_devinfo_struct *devi)
248 {
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);
255 }
256
257
258 /* Allocate an op structure from our pool
259  */
260 static struct opStruct *getOpStruct(void)
261 {
262         struct opStruct *newOpStruct;
263         spin_lock(&opStructListLock);
264
265         if (opStructList == NULL) {
266                 newOpStruct = kmalloc(sizeof(struct opStruct), GFP_KERNEL);
267         } else {
268                 newOpStruct = opStructList;
269                 opStructList = opStructList->free;
270         }
271
272         if (newOpStruct)
273                 memset(newOpStruct, 0x00, sizeof(struct opStruct));
274
275         spin_unlock(&opStructListLock);
276
277         return newOpStruct;
278 }
279
280 /* Return an op structure to our pool
281  */
282 static void freeOpStruct(struct opStruct *opStruct)
283 {
284         spin_lock(&opStructListLock);
285         opStruct->free = opStructList;
286         opStructList = opStruct;
287         spin_unlock(&opStructListLock);
288 }
289
290 /* Map our tape return codes to errno values
291  */
292 int tapeRcToErrno(int tapeRc, char *operation, int tapeno)
293 {
294         int terrno;
295         char *tmsg;
296
297         switch (tapeRc) {
298         case 0:
299                 return 0;
300         case viotape_InvalidRange:
301                 terrno = EIO;
302                 tmsg = "Internal error";
303                 break;
304         case viotape_InvalidToken:
305                 terrno = EIO;
306                 tmsg = "Internal error";
307                 break;
308         case viotape_DMAError:
309                 terrno = EIO;
310                 tmsg = "DMA error";
311                 break;
312         case viotape_UseError:
313                 terrno = EIO;
314                 tmsg = "Internal error";
315                 break;
316         case viotape_ReleaseError:
317                 terrno = EIO;
318                 tmsg = "Internal error";
319                 break;
320         case viotape_InvalidTape:
321                 terrno = EIO;
322                 tmsg = "Invalid tape device";
323                 break;
324         case viotape_InvalidOp:
325                 terrno = EIO;
326                 tmsg = "Invalid operation";
327                 break;
328         case viotape_TapeErr:
329                 terrno = EIO;
330                 tmsg = "Tape error";
331                 break;
332
333         case viotape_AllocTimedOut:
334                 terrno = EBUSY;
335                 tmsg = "Allocate timed out";
336                 break;
337         case viotape_BOTEnc:
338                 terrno = EIO;
339                 tmsg = "Beginning of tape encountered";
340                 break;
341         case viotape_BlankTape:
342                 terrno = EIO;
343                 tmsg = "Blank tape";
344                 break;
345         case viotape_BufferEmpty:
346                 terrno = EIO;
347                 tmsg = "Buffer empty";
348                 break;
349         case viotape_CleanCartFound:
350                 terrno = ENOMEDIUM;
351                 tmsg = "Cleaning cartridge found";
352                 break;
353         case viotape_CmdNotAllowed:
354                 terrno = EIO;
355                 tmsg = "Command not allowed";
356                 break;
357         case viotape_CmdNotSupported:
358                 terrno = EIO;
359                 tmsg = "Command not supported";
360                 break;
361         case viotape_DataCheck:
362                 terrno = EIO;
363                 tmsg = "Data check";
364                 break;
365         case viotape_DecompressErr:
366                 terrno = EIO;
367                 tmsg = "Decompression error";
368                 break;
369         case viotape_DeviceTimeout:
370                 terrno = EBUSY;
371                 tmsg = "Device timeout";
372                 break;
373         case viotape_DeviceUnavail:
374                 terrno = EIO;
375                 tmsg = "Device unavailable";
376                 break;
377         case viotape_DeviceBusy:
378                 terrno = EBUSY;
379                 tmsg = "Device busy";
380                 break;
381         case viotape_EndOfMedia:
382                 terrno = ENOSPC;
383                 tmsg = "End of media";
384                 break;
385         case viotape_EndOfTape:
386                 terrno = ENOSPC;
387                 tmsg = "End of tape";
388                 break;
389         case viotape_EquipCheck:
390                 terrno = EIO;
391                 tmsg = "Equipment check";
392                 break;
393         case viotape_InsufficientRs:
394                 terrno = EOVERFLOW;
395                 tmsg = "Insufficient tape resources";
396                 break;
397         case viotape_InvalidLogBlk:
398                 terrno = EIO;
399                 tmsg = "Invalid logical block location";
400                 break;
401         case viotape_LengthError:
402                 terrno = EOVERFLOW;
403                 tmsg = "Length error";
404                 break;
405         case viotape_LibDoorOpen:
406                 terrno = EBUSY;
407                 tmsg = "Door open";
408                 break;
409         case viotape_LoadFailure:
410                 terrno = ENOMEDIUM;
411                 tmsg = "Load failure";
412                 break;
413         case viotape_NotCapable:
414                 terrno = EIO;
415                 tmsg = "Not capable";
416                 break;
417         case viotape_NotOperational:
418                 terrno = EIO;
419                 tmsg = "Not operational";
420                 break;
421         case viotape_NotReady:
422                 terrno = EIO;
423                 tmsg = "Not ready";
424                 break;
425         case viotape_OpCancelled:
426                 terrno = EIO;
427                 tmsg = "Operation cancelled";
428                 break;
429         case viotape_PhyLinkErr:
430                 terrno = EIO;
431                 tmsg = "Physical link error";
432                 break;
433         case viotape_RdyNotBOT:
434                 terrno = EIO;
435                 tmsg = "Ready but not beginning of tape";
436                 break;
437         case viotape_TapeMark:
438                 terrno = EIO;
439                 tmsg = "Tape mark";
440                 break;
441         case viotape_WriteProt:
442                 terrno = EROFS;
443                 tmsg = "Write protection error";
444                 break;
445         default:
446                 terrno = EIO;
447                 tmsg = "I/O error";
448         }
449
450         printk(KERN_WARNING_VIO "tape error on Device %d (%10.10s): %s\n",
451                tapeno, viotape_unitinfo[tapeno].rsrcname, tmsg);
452
453         lasterr[tapeno] = tmsg;
454
455         return -terrno;
456 }
457
458 /* Handle reads from the proc file system.  
459  */
460 static int proc_read(char *buf, char **start, off_t offset,
461                      int blen, int *eof, void *data)
462 {
463         int len = 0;
464         int i;
465
466         len += sprintf(buf + len, "viotape driver version %d.%d\n",
467                        version_major, version_minor);
468
469         for (i = 0; i < viotape_numdev; i++) {
470
471                 len +=
472                     sprintf(buf + len,
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);
477                 if (lasterr[i])
478                         len +=
479                             sprintf(buf + len, "   last error: %s\n",
480                                     lasterr[i]);
481         }
482
483         *eof = 1;
484         return len;
485 }
486
487 /* setup our proc file system entries
488  */
489 void viotape_proc_init(struct proc_dir_entry *iSeries_proc)
490 {
491         struct proc_dir_entry *ent;
492         ent =
493             create_proc_entry("viotape", S_IFREG | S_IRUSR, iSeries_proc);
494         if (!ent)
495                 return;
496         ent->nlink = 1;
497         ent->data = NULL;
498         ent->read_proc = proc_read;
499 }
500
501 /* clean up our proc file system entries
502  */
503 void viotape_proc_delete(struct proc_dir_entry *iSeries_proc)
504 {
505         remove_proc_entry("viotape", iSeries_proc);
506 }
507
508
509 /* Get info on all tapes from OS/400
510  */
511 static void get_viotape_info(void)
512 {
513         dma_addr_t dmaaddr;
514         HvLpEvent_Rc hvrc;
515         int i;
516         struct opStruct *op = getOpStruct();
517         DECLARE_MUTEX_LOCKED(Semaphore);
518         if (op == NULL)
519                 return;
520
521         if (viotape_unitinfo == NULL) {
522                 viotape_unitinfo =
523                     kmalloc(sizeof(struct tape_descr) * VIOTAPE_MAX_TAPE,
524                             GFP_KERNEL);
525         }
526         memset(viotape_unitinfo, 0x00,
527                sizeof(struct tape_descr) * VIOTAPE_MAX_TAPE);
528         memset(lasterr, 0x00, sizeof(lasterr));
529
530         op->sem = &Semaphore;
531
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");
537                 return;
538         }
539
540         hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
541                                              HvLpEvent_Type_VirtualIo,
542                                              viomajorsubtype_tape |
543                                              viotapegetinfo,
544                                              HvLpEvent_AckInd_DoAck,
545                                              HvLpEvent_AckType_ImmediateAck,
546                                              viopath_sourceinst
547                                              (viopath_hostLp),
548                                              viopath_targetinst
549                                              (viopath_hostLp),
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);
556         }
557
558         down(&Semaphore);
559
560         freeOpStruct(op);
561
562
563         for (i = 0;
564              ((i < VIOTAPE_MAX_TAPE) && (viotape_unitinfo[i].rsrcname[0]));
565              i++) {
566                 printk("found a tape %10.10s\n",
567                        viotape_unitinfo[i].rsrcname);
568                 viotape_numdev++;
569         }
570 }
571
572
573 /* Write
574  */
575 static ssize_t viotap_write(struct file *file, const char *buf,
576                             size_t count, loff_t * ppos)
577 {
578         HvLpEvent_Rc hvrc;
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);
583         int err;
584         struct viot_devinfo_struct devi;
585         DECLARE_MUTEX_LOCKED(Semaphore);
586
587         if (op == NULL)
588                 return -ENOMEM;
589
590         getDevInfo(dev, &devi);
591
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 
595          * semaphore
596          */
597         if (noblock) {
598                 if (down_trylock(&reqSem)) {
599                         freeOpStruct(op);
600                         return -EWOULDBLOCK;
601                 }
602         } else {
603                 down(&reqSem);
604         }
605
606         /* Allocate a DMA buffer */
607         op->buffer = pci_alloc_consistent(iSeries_vio_dev, count, &op->dmaaddr);
608
609         if ((op->dmaaddr == 0xFFFFFFFF) || (op->buffer == NULL)) {
610                 printk(KERN_WARNING_VIO 
611                        "tape error allocating dma buffer for len %ld\n",
612                        (long)count);
613                 freeOpStruct(op);
614                 up(&reqSem);
615                 return -EFAULT;
616         }
617
618         op->count = count;
619
620         /* Copy the data into the buffer */
621         err = copy_from_user(op->buffer, (const void *) buf, count);
622         if (err) {
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);
626                 freeOpStruct(op);
627                 up(&reqSem);
628                 return -EFAULT;
629         }
630
631         if (noblock) {
632                 op->sem = NULL;
633         } else {
634                 op->sem = &Semaphore;
635         }
636
637         hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
638                                              HvLpEvent_Type_VirtualIo,
639                                              viomajorsubtype_tape |
640                                              viotapewrite,
641                                              HvLpEvent_AckInd_DoAck,
642                                              HvLpEvent_AckType_ImmediateAck,
643                                              viopath_sourceinst
644                                              (viopath_hostLp),
645                                              viopath_targetinst
646                                              (viopath_hostLp),
647                                              (u64) (unsigned long) op,
648                                              VIOVERSION << 16,
649                                              ((u64) devi.
650                                               devno << 48) | op->dmaaddr,
651                                              count, 0, 0);
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);
655                 freeOpStruct(op);
656                 up(&reqSem);
657                 return -EIO;
658         }
659
660         if (noblock)
661                 return count;
662
663         down(&Semaphore);
664
665         err = op->rc;
666
667         /* Free the buffer */
668         pci_free_consistent(iSeries_vio_dev, count, op->buffer, op->dmaaddr);
669
670         count = op->count;
671
672         freeOpStruct(op);
673         up(&reqSem);
674         if (err)
675                 return tapeRcToErrno(err, "write", devi.devno);
676         else {
677                 chg_state(devi.devno, VIOT_WRITING, file);
678                 return count;
679         }
680 }
681
682 /* read
683  */
684 static ssize_t viotap_read(struct file *file, char *buf, size_t count,
685                            loff_t * ptr)
686 {
687         HvLpEvent_Rc hvrc;
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);
692         int err;
693         struct viot_devinfo_struct devi;
694         DECLARE_MUTEX_LOCKED(Semaphore);
695
696         if (op == NULL)
697                 return -ENOMEM;
698
699         getDevInfo(dev, &devi);
700
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 
704          * semaphore
705          */
706         if (noblock) {
707                 if (down_trylock(&reqSem)) {
708                         freeOpStruct(op);
709                         return -EWOULDBLOCK;
710                 }
711         } else {
712                 down(&reqSem);
713         }
714
715         chg_state(devi.devno, VIOT_READING, file);
716
717         /* Allocate a DMA buffer */
718         op->buffer = pci_alloc_consistent(iSeries_vio_dev, count, &op->dmaaddr);
719
720         if ((op->dmaaddr == 0xFFFFFFFF) || (op->buffer == NULL)) {
721                 freeOpStruct(op);
722                 up(&reqSem);
723                 return -EFAULT;
724         }
725
726         op->count = count;
727
728         op->sem = &Semaphore;
729
730         hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
731                                              HvLpEvent_Type_VirtualIo,
732                                              viomajorsubtype_tape |
733                                              viotaperead,
734                                              HvLpEvent_AckInd_DoAck,
735                                              HvLpEvent_AckType_ImmediateAck,
736                                              viopath_sourceinst
737                                              (viopath_hostLp),
738                                              viopath_targetinst
739                                              (viopath_hostLp),
740                                              (u64) (unsigned long) op,
741                                              VIOVERSION << 16,
742                                              ((u64) devi.
743                                               devno << 48) | op->dmaaddr,
744                                              count, 0, 0);
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);
749                 freeOpStruct(op);
750                 up(&reqSem);
751                 return -EIO;
752         }
753
754         down(&Semaphore);
755
756         if (op->rc == 0) {
757                 /* If we got data back        */
758                 if (op->count) {
759                         /* Copy the data into the buffer */
760                         err = copy_to_user(buf, op->buffer, count);
761                         if (err) {
762                                 printk("error on copy_to_user\n");
763                                 pci_free_consistent(iSeries_vio_dev, count,
764                                                     op->buffer,
765                                                     op->dmaaddr);
766                                 freeOpStruct(op);
767                                 up(&reqSem);
768                                 return -EFAULT;
769                         }
770                 }
771         }
772
773         err = op->rc;
774
775         /* Free the buffer */
776         pci_free_consistent(iSeries_vio_dev, count, op->buffer, op->dmaaddr);
777         count = op->count;
778
779         freeOpStruct(op);
780         up(&reqSem);
781         if (err)
782                 return tapeRcToErrno(err, "read", devi.devno);
783         else
784                 return count;
785 }
786
787 /* read
788  */
789 static int viotap_ioctl(struct inode *inode, struct file *file,
790                         unsigned int cmd, unsigned long arg)
791 {
792         HvLpEvent_Rc hvrc;
793         int err;
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;
798         if (op == NULL)
799                 return -ENOMEM;
800
801         getDevInfo(dev, &devi);
802
803         down(&reqSem);
804
805         switch (cmd) {
806         case MTIOCTOP:{
807                         struct mtop mtc;
808                         u32 myOp;
809
810                         /* inode is null if and only if we (the kernel) made the request */
811                         if (inode == NULL)
812                                 memcpy(&mtc, (void *) arg,
813                                        sizeof(struct mtop));
814                         else if (copy_from_user
815                                  ((char *) &mtc, (char *) arg,
816                                   sizeof(struct mtop))) {
817                                 freeOpStruct(op);
818                                 up(&reqSem);
819                                 return -EFAULT;
820                         }
821
822                         switch (mtc.mt_op) {
823                         case MTRESET:
824                                 myOp = VIOTAPOP_RESET;
825                                 break;
826                         case MTFSF:
827                                 myOp = VIOTAPOP_FSF;
828                                 break;
829                         case MTBSF:
830                                 myOp = VIOTAPOP_BSF;
831                                 break;
832                         case MTFSR:
833                                 myOp = VIOTAPOP_FSR;
834                                 break;
835                         case MTBSR:
836                                 myOp = VIOTAPOP_BSR;
837                                 break;
838                         case MTWEOF:
839                                 myOp = VIOTAPOP_WEOF;
840                                 break;
841                         case MTREW:
842                                 myOp = VIOTAPOP_REW;
843                                 break;
844                         case MTNOP:
845                                 myOp = VIOTAPOP_NOP;
846                                 break;
847                         case MTEOM:
848                                 myOp = VIOTAPOP_EOM;
849                                 break;
850                         case MTERASE:
851                                 myOp = VIOTAPOP_ERASE;
852                                 break;
853                         case MTSETBLK:
854                                 myOp = VIOTAPOP_SETBLK;
855                                 break;
856                         case MTSETDENSITY:
857                                 myOp = VIOTAPOP_SETDENSITY;
858                                 break;
859                         case MTTELL:
860                                 myOp = VIOTAPOP_GETPOS;
861                                 break;
862                         case MTSEEK:
863                                 myOp = VIOTAPOP_SETPOS;
864                                 break;
865                         case MTSETPART:
866                                 myOp = VIOTAPOP_SETPART;
867                                 break;
868                         default:
869                                 return -EIO;
870                         }
871
872 /* if we moved the head, we are no longer reading or writing */
873                         switch (mtc.mt_op) {
874                         case MTFSF:
875                         case MTBSF:
876                         case MTFSR:
877                         case MTBSR:
878                         case MTTELL:
879                         case MTSEEK:
880                         case MTREW:
881                                 chg_state(devi.devno, VIOT_IDLE, file);
882                         }
883
884                         op->sem = &Semaphore;
885                         hvrc =
886                             HvCallEvent_signalLpEventFast(viopath_hostLp,
887                                                           HvLpEvent_Type_VirtualIo,
888                                                           viomajorsubtype_tape
889                                                           | viotapeop,
890                                                           HvLpEvent_AckInd_DoAck,
891                                                           HvLpEvent_AckType_ImmediateAck,
892                                                           viopath_sourceinst
893                                                           (viopath_hostLp),
894                                                           viopath_targetinst
895                                                           (viopath_hostLp),
896                                                           (u64) (unsigned
897                                                                  long) op,
898                                                           VIOVERSION << 16,
899                                                           ((u64) devi.
900                                                            devno << 48), 0,
901                                                           (((u64) myOp) <<
902                                                            32) | mtc.
903                                                           mt_count, 0);
904                         if (hvrc != HvLpEvent_Rc_Good) {
905                                 printk("viotape hv error on op %d\n",
906                                        (int) hvrc);
907                                 freeOpStruct(op);
908                                 up(&reqSem);
909                                 return -EIO;
910                         }
911                         down(&Semaphore);
912                         if (op->rc) {
913                                 freeOpStruct(op);
914                                 up(&reqSem);
915                                 return tapeRcToErrno(op->rc,
916                                                      "tape operation",
917                                                      devi.devno);
918                         } else {
919                                 freeOpStruct(op);
920                                 up(&reqSem);
921                                 return 0;
922                         }
923                         break;
924                 }
925
926         case MTIOCGET:
927                 op->sem = &Semaphore;
928                 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
929                                                      HvLpEvent_Type_VirtualIo,
930                                                      viomajorsubtype_tape |
931                                                      viotapegetstatus,
932                                                      HvLpEvent_AckInd_DoAck,
933                                                      HvLpEvent_AckType_ImmediateAck,
934                                                      viopath_sourceinst
935                                                      (viopath_hostLp),
936                                                      viopath_targetinst
937                                                      (viopath_hostLp),
938                                                      (u64) (unsigned long)
939                                                      op, VIOVERSION << 16,
940                                                      ((u64) devi.
941                                                       devno << 48), 0, 0,
942                                                      0);
943                 if (hvrc != HvLpEvent_Rc_Good) {
944                         printk("viotape hv error on op %d\n", (int) hvrc);
945                         freeOpStruct(op);
946                         up(&reqSem);
947                         return -EIO;
948                 }
949                 down(&Semaphore);
950                 up(&reqSem);
951                 if (op->rc) {
952                         freeOpStruct(op);
953                         return tapeRcToErrno(op->rc, "get status",
954                                              devi.devno);
955                 } else {
956                         freeOpStruct(op);
957                         err =
958                             copy_to_user((void *) arg, &viomtget[dev],
959                                          sizeof(viomtget[0]));
960                         if (err) {
961                                 freeOpStruct(op);
962                                 return -EFAULT;
963                         }
964                         return 0;
965                 }
966                 break;
967         case MTIOCPOS:
968                 printk("Got an MTIOCPOS\n");
969         default:
970                 return -ENOSYS;
971         }
972         return 0;
973 }
974
975 /* Open
976  */
977 static int viotap_open(struct inode *inode, struct file *file)
978 {
979         DECLARE_MUTEX_LOCKED(Semaphore);
980         kdev_t dev = file->f_dentry->d_inode->i_rdev;
981         HvLpEvent_Rc hvrc;
982         struct opStruct *op = getOpStruct();
983         struct viot_devinfo_struct devi;
984         if (op == NULL)
985                 return -ENOMEM;
986
987         getDevInfo(dev, &devi);
988
989 // Note: We currently only support one mode!
990         if ((devi.devno >= viotape_numdev) || (devi.mode)) {
991                 freeOpStruct(op);
992                 return -ENODEV;
993         }
994
995         op->sem = &Semaphore;
996
997         hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
998                                              HvLpEvent_Type_VirtualIo,
999                                              viomajorsubtype_tape |
1000                                              viotapeopen,
1001                                              HvLpEvent_AckInd_DoAck,
1002                                              HvLpEvent_AckType_ImmediateAck,
1003                                              viopath_sourceinst
1004                                              (viopath_hostLp),
1005                                              viopath_targetinst
1006                                              (viopath_hostLp),
1007                                              (u64) (unsigned long) op,
1008                                              VIOVERSION << 16,
1009                                              ((u64) devi.devno << 48), 0,
1010                                              0, 0);
1011
1012
1013         if (hvrc != 0) {
1014                 printk("viotape bad rc on signalLpEvent %d\n", (int) hvrc);
1015                 freeOpStruct(op);
1016                 return -EIO;
1017         }
1018
1019         down(&Semaphore);
1020
1021         if (op->rc) {
1022                 freeOpStruct(op);
1023                 return tapeRcToErrno(op->rc, "open", devi.devno);
1024         } else {
1025                 freeOpStruct(op);
1026                 MOD_INC_USE_COUNT;
1027                 return 0;
1028         }
1029 }
1030
1031
1032 /* Release
1033  */
1034 static int viotap_release(struct inode *inode, struct file *file)
1035 {
1036         DECLARE_MUTEX_LOCKED(Semaphore);
1037         kdev_t dev = file->f_dentry->d_inode->i_rdev;
1038         HvLpEvent_Rc hvrc;
1039         struct viot_devinfo_struct devi;
1040         struct opStruct *op = getOpStruct();
1041
1042         if (op == NULL)
1043                 return -ENOMEM;
1044         op->sem = &Semaphore;
1045
1046         getDevInfo(dev, &devi);
1047
1048         if (devi.devno >= viotape_numdev) {
1049                 freeOpStruct(op);
1050                 return -ENODEV;
1051         }
1052
1053         chg_state(devi.devno, VIOT_IDLE, file);
1054
1055         if (devi.rewind) {
1056                 hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
1057                                                      HvLpEvent_Type_VirtualIo,
1058                                                      viomajorsubtype_tape |
1059                                                      viotapeop,
1060                                                      HvLpEvent_AckInd_DoAck,
1061                                                      HvLpEvent_AckType_ImmediateAck,
1062                                                      viopath_sourceinst
1063                                                      (viopath_hostLp),
1064                                                      viopath_targetinst
1065                                                      (viopath_hostLp),
1066                                                      (u64) (unsigned long)
1067                                                      op, VIOVERSION << 16,
1068                                                      ((u64) devi.
1069                                                       devno << 48), 0,
1070                                                      ((u64) VIOTAPOP_REW)
1071                                                      << 32, 0);
1072                 down(&Semaphore);
1073
1074                 if (op->rc) {
1075                         tapeRcToErrno(op->rc, "rewind", devi.devno);
1076                 }
1077         }
1078
1079         hvrc = HvCallEvent_signalLpEventFast(viopath_hostLp,
1080                                              HvLpEvent_Type_VirtualIo,
1081                                              viomajorsubtype_tape |
1082                                              viotapeclose,
1083                                              HvLpEvent_AckInd_DoAck,
1084                                              HvLpEvent_AckType_ImmediateAck,
1085                                              viopath_sourceinst
1086                                              (viopath_hostLp),
1087                                              viopath_targetinst
1088                                              (viopath_hostLp),
1089                                              (u64) (unsigned long) op,
1090                                              VIOVERSION << 16,
1091                                              ((u64) devi.devno << 48), 0,
1092                                              0, 0);
1093
1094
1095         if (hvrc != 0) {
1096                 printk("viotape: bad rc on signalLpEvent %d\n",
1097                        (int) hvrc);
1098                 return -EIO;
1099         }
1100
1101         down(&Semaphore);
1102
1103         if (op->rc) {
1104                 printk("viotape: close failed\n");
1105         }
1106         MOD_DEC_USE_COUNT;
1107         return 0;
1108 }
1109
1110 struct file_operations viotap_fops = {
1111         owner:THIS_MODULE,
1112         read:viotap_read,
1113         write:viotap_write,
1114         ioctl:viotap_ioctl,
1115         open:viotap_open,
1116         release:viotap_release,
1117 };
1118
1119 /* Handle interrupt events for tape
1120  */
1121 static void vioHandleTapeEvent(struct HvLpEvent *event)
1122 {
1123         int tapeminor;
1124         struct opStruct *op;
1125         struct viotapelpevent *tevent = (struct viotapelpevent *) event;
1126
1127         if (event == NULL) {
1128           /* Notification that a partition went away! */
1129           if (!viopath_isactive(viopath_hostLp)) {
1130             /* TODO! Clean up */
1131           }
1132           return;
1133         }
1134
1135         tapeminor = event->xSubtype & VIOMINOR_SUBTYPE_MASK;
1136         switch (tapeminor) {
1137         case viotapegetinfo:
1138         case viotapeopen:
1139         case viotapeclose:
1140                 op = (struct opStruct *) (unsigned long) event->
1141                     xCorrelationToken;
1142                 op->rc = tevent->mSubTypeRc;
1143                 up(op->sem);
1144                 break;
1145         case viotaperead:
1146         case viotapewrite:
1147                 op = (struct opStruct *) (unsigned long) event->
1148                     xCorrelationToken;
1149                 op->rc = tevent->mSubTypeRc;;
1150                 op->count = tevent->mLen;
1151
1152                 if (op->sem) {
1153                         up(op->sem);
1154                 } else {
1155                         freeOpStruct(op);
1156                         up(&reqSem);
1157                 }
1158                 break;
1159         case viotapeop:
1160         case viotapegetpos:
1161         case viotapesetpos:
1162         case viotapegetstatus:
1163                 op = (struct opStruct *) (unsigned long) event->
1164                     xCorrelationToken;
1165                 if (op) {
1166                         op->count = tevent->u.tapeOp.mCount;
1167                         op->rc = tevent->mSubTypeRc;;
1168
1169                         if (op->sem) {
1170                                 up(op->sem);
1171                         }
1172                 }
1173                 break;
1174         default:
1175                 printk("viotape: wierd ack\n");
1176         }
1177 }
1178
1179
1180 /* Do initialization
1181  */
1182 int __init viotap_init(void)
1183 {
1184         DECLARE_MUTEX_LOCKED(Semaphore);
1185         int rc;
1186         char tapename[32];
1187         int i;
1188
1189         printk("viotape driver version %d.%d\n", version_major,
1190                version_minor);
1191
1192         sndMsgSeq = sndMsgAck = 0;
1193         rcvMsgSeq = rcvMsgAck = 0;
1194         opStructList = NULL;
1195         spin_lock_init(&opStructListLock);
1196
1197         sema_init(&reqSem, VIOTAPE_MAXREQ);
1198
1199         if (viopath_hostLp == HvLpIndexInvalid)
1200                 vio_set_hostlp();
1201
1202         /*
1203          * Open to our hosting lp
1204          */
1205         if (viopath_hostLp == HvLpIndexInvalid)
1206                 return -1;
1207
1208         printk("viotape: init - open path to hosting (%d)\n",
1209                viopath_hostLp);
1210
1211         rc = viopath_open(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1212         if (rc) {
1213                 printk("viotape: error on viopath_open to hostlp %d\n",
1214                        rc);
1215         }
1216
1217         vio_setHandler(viomajorsubtype_tape, vioHandleTapeEvent);
1218
1219         printk("viotape major is %d\n", viotape_major);
1220
1221         get_viotape_info();
1222
1223         if (devfs_register_chrdev(viotape_major, "viotape", &viotap_fops)) {
1224                 printk("Error registering viotape device\n");
1225                 return -1;
1226         }
1227
1228         for (i = 0; i < viotape_numdev; i++) {
1229                 int j;
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,
1236                                    viotape_major, i,
1237                                    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
1238                                    S_IWGRP, &viotap_fops, NULL);
1239                 printk
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);
1243         }
1244
1245         /* 
1246          * Create the proc entry
1247          */
1248         iSeries_proc_callback(&viotape_proc_init);
1249
1250         return 0;
1251 }
1252
1253 /* Give a new state to the tape object
1254  */
1255 static int chg_state(int index, unsigned char new_state, struct file *file)
1256 {
1257         unsigned char *cur_state =
1258             &state[index].part_stat[state[index].cur_part].rwi;
1259         int rc = 0;
1260
1261         /* if the same state, don't bother */
1262         if (*cur_state == new_state)
1263                 return 0;
1264
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);
1270         }
1271         *cur_state = new_state;
1272         return rc;
1273 }
1274
1275 /* Cleanup
1276  */
1277 static void __exit viotap_exit(void)
1278 {
1279         int i, ret;
1280         for (i = 0; i < viotape_numdev; ++i)
1281                 devfs_unregister(state[i].dev_handle);
1282         ret = devfs_unregister_chrdev(viotape_major, "viotape");
1283         if (ret < 0)
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;
1289         }
1290         viopath_close(viopath_hostLp, viomajorsubtype_tape, VIOTAPE_MAXREQ + 2);
1291         vio_clearHandler(viomajorsubtype_tape);
1292 }
1293
1294 module_init(viotap_init);
1295 module_exit(viotap_exit);