1/*
2        pt.c    (c) 1998  Grant R. Guenther <grant@torque.net>
3                          Under the terms of the GNU General Public License.
4
5        This is the high-level driver for parallel port ATAPI tape
6        drives based on chips supported by the paride module.
7
8	The driver implements both rewinding and non-rewinding
9	devices, filemarks, and the rewind ioctl.  It allocates
10	a small internal "bounce buffer" for each open device, but
11        otherwise expects buffering and blocking to be done at the
12        user level.  As with most block-structured tapes, short
13	writes are padded to full tape blocks, so reading back a file
14        may return more data than was actually written.
15
16        By default, the driver will autoprobe for a single parallel
17        port ATAPI tape drive, but if their individual parameters are
18        specified, the driver can handle up to 4 drives.
19
20	The rewinding devices are named /dev/pt0, /dev/pt1, ...
21	while the non-rewinding devices are /dev/npt0, /dev/npt1, etc.
22
23        The behaviour of the pt driver can be altered by setting
24        some parameters from the insmod command line.  The following
25        parameters are adjustable:
26
27            drive0      These four arguments can be arrays of
28            drive1      1-6 integers as follows:
29            drive2
30            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
31
32                        Where,
33
34                <prt>   is the base of the parallel port address for
35                        the corresponding drive.  (required)
36
37                <pro>   is the protocol number for the adapter that
38                        supports this drive.  These numbers are
39                        logged by 'paride' when the protocol modules
40                        are initialised.  (0 if not given)
41
42                <uni>   for those adapters that support chained
43                        devices, this is the unit selector for the
44                        chain of devices on the given port.  It should
45                        be zero for devices that don't support chaining.
46                        (0 if not given)
47
48                <mod>   this can be -1 to choose the best mode, or one
49                        of the mode numbers supported by the adapter.
50                        (-1 if not given)
51
52                <slv>   ATAPI devices can be jumpered to master or slave.
53                        Set this to 0 to choose the master drive, 1 to
54                        choose the slave, -1 (the default) to choose the
55                        first drive found.
56
57                <dly>   some parallel ports require the driver to
58                        go more slowly.  -1 sets a default value that
59                        should work with the chosen protocol.  Otherwise,
60                        set this to a small integer, the larger it is
61                        the slower the port i/o.  In some cases, setting
62                        this to zero will speed up the device. (default -1)
63
64	    major	You may use this parameter to overide the
65			default major number (96) that this driver
66			will use.  Be sure to change the device
67			name as well.
68
69	    name	This parameter is a character string that
70			contains the name the kernel will use for this
71			device (in /proc output, for instance).
72			(default "pt").
73
74            verbose     This parameter controls the amount of logging
75                        that the driver will do.  Set it to 0 for
76                        normal operation, 1 to see autoprobe progress
77                        messages, or 2 to see additional debugging
78                        output.  (default 0)
79
80        If this driver is built into the kernel, you can use
81        the following command line parameters, with the same values
82        as the corresponding module parameters listed above:
83
84            pt.drive0
85            pt.drive1
86            pt.drive2
87            pt.drive3
88
89        In addition, you can use the parameter pt.disable to disable
90        the driver entirely.
91
92*/
93
94/*   Changes:
95
96	1.01	GRG 1998.05.06	Round up transfer size, fix ready_wait,
97			        loosed interpretation of ATAPI standard
98				for clearing error status.
99				Eliminate sti();
100	1.02    GRG 1998.06.16  Eliminate an Ugh.
101	1.03    GRG 1998.08.15  Adjusted PT_TMO, use HZ in loop timing,
102				extra debugging
103	1.04    GRG 1998.09.24  Repair minor coding error, added jumbo support
104
105*/
106
107#define PT_VERSION      "1.04"
108#define PT_MAJOR	96
109#define PT_NAME		"pt"
110#define PT_UNITS	4
111
112/* Here are things one can override from the insmod command.
113   Most are autoprobed by paride unless set here.  Verbose is on
114   by default.
115
116*/
117
118static int	verbose = 0;
119static int	major = PT_MAJOR;
120static char	*name = PT_NAME;
121static int      disable = 0;
122
123static int drive0[6] = {0,0,0,-1,-1,-1};
124static int drive1[6] = {0,0,0,-1,-1,-1};
125static int drive2[6] = {0,0,0,-1,-1,-1};
126static int drive3[6] = {0,0,0,-1,-1,-1};
127
128static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
129static int pt_drive_count;
130
131#define D_PRT   0
132#define D_PRO   1
133#define D_UNI   2
134#define D_MOD   3
135#define D_SLV   4
136#define D_DLY   5
137
138#define DU              (*drives[unit])
139
140/* end of parameters */
141
142
143#include <linux/module.h>
144#include <linux/errno.h>
145#include <linux/fs.h>
146#include <linux/devfs_fs_kernel.h>
147#include <linux/kernel.h>
148#include <linux/delay.h>
149#include <linux/slab.h>
150#include <linux/mtio.h>
151#include <linux/wait.h>
152#include <linux/smp_lock.h>
153
154#include <asm/uaccess.h>
155
156#ifndef MODULE
157
158#include "setup.h"
159
160static STT pt_stt[5] = {{"drive0",6,drive0},
161                        {"drive1",6,drive1},
162                        {"drive2",6,drive2},
163                        {"drive3",6,drive3},
164			{"disable",1,&disable}};
165
166void pt_setup( char *str, int *ints)
167
168{       generic_setup(pt_stt,5,str);
169}
170
171#endif
172
173MODULE_PARM(verbose,"i");
174MODULE_PARM(major,"i");
175MODULE_PARM(name,"s");
176MODULE_PARM(drive0,"1-6i");
177MODULE_PARM(drive1,"1-6i");
178MODULE_PARM(drive2,"1-6i");
179MODULE_PARM(drive3,"1-6i");
180
181#include "paride.h"
182
183#define PT_MAX_RETRIES  5
184#define PT_TMO          3000            /* interrupt timeout in jiffies */
185#define PT_SPIN_DEL     50              /* spin delay in micro-seconds  */
186#define PT_RESET_TMO    30		/* 30 seconds */
187#define PT_READY_TMO	60		/* 60 seconds */
188#define PT_REWIND_TMO	1200		/* 20 minutes */
189
190#define PT_SPIN         ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
191
192#define STAT_ERR        0x00001
193#define STAT_INDEX      0x00002
194#define STAT_ECC        0x00004
195#define STAT_DRQ        0x00008
196#define STAT_SEEK       0x00010
197#define STAT_WRERR      0x00020
198#define STAT_READY      0x00040
199#define STAT_BUSY       0x00080
200#define STAT_SENSE	0x1f000
201
202#define ATAPI_TEST_READY	0x00
203#define ATAPI_REWIND		0x01
204#define ATAPI_REQ_SENSE		0x03
205#define ATAPI_READ_6		0x08
206#define ATAPI_WRITE_6		0x0a
207#define ATAPI_WFM		0x10
208#define ATAPI_IDENTIFY		0x12
209#define ATAPI_MODE_SENSE	0x1a
210#define ATAPI_LOG_SENSE		0x4d
211
212int pt_init(void);
213#ifdef MODULE
214void cleanup_module( void );
215#endif
216
217static int pt_open(struct inode *inode, struct file *file);
218static int pt_ioctl(struct inode *inode,struct file *file,
219                    unsigned int cmd, unsigned long arg);
220static int pt_release (struct inode *inode, struct file *file);
221static ssize_t pt_read(struct file * filp, char * buf,
222                       size_t count, loff_t *ppos);
223static ssize_t pt_write(struct file * filp, const char * buf,
224                        size_t count, loff_t *ppos);
225static int pt_detect(void);
226
227static int pt_identify (int unit);
228
229/* bits in PT.flags */
230
231#define PT_MEDIA	1
232#define PT_WRITE_OK	2
233#define PT_REWIND	4
234#define PT_WRITING      8
235#define PT_READING     16
236#define PT_EOF	       32
237
238#define PT_NAMELEN      8
239#define PT_BUFSIZE  16384
240
241struct pt_unit {
242	struct pi_adapter pia;    /* interface to paride layer */
243	struct pi_adapter *pi;
244	int flags;        	  /* various state flags */
245	int last_sense;		  /* result of last request sense */
246	int drive;		  /* drive */
247	int access;               /* count of active opens ... */
248	int bs;			  /* block size */
249	int capacity;             /* Size of tape in KB */
250	int present;		  /* device present ? */
251	char *bufptr;
252	char name[PT_NAMELEN];	  /* pf0, pf1, ... */
253	};
254
255struct pt_unit pt[PT_UNITS];
256
257/*  'unit' must be defined in all functions - either as a local or a param */
258
259#define PT pt[unit]
260#define PI PT.pi
261
262static char pt_scratch[512];            /* scratch block buffer */
263
264/* kernel glue structures */
265
266static struct file_operations pt_fops = {
267	owner:		THIS_MODULE,
268	read:		pt_read,
269	write:		pt_write,
270	ioctl:		pt_ioctl,
271	open:		pt_open,
272	release:	pt_release,
273};
274
275void pt_init_units( void )
276
277{       int     unit, j;
278
279        pt_drive_count = 0;
280        for (unit=0;unit<PT_UNITS;unit++) {
281                PT.pi = & PT.pia;
282                PT.access = 0;
283                PT.flags = 0;
284		PT.last_sense = 0;
285                PT.present = 0;
286		PT.bufptr = NULL;
287		PT.drive = DU[D_SLV];
288                j = 0;
289                while ((j < PT_NAMELEN-2) && (PT.name[j]=name[j])) j++;
290                PT.name[j++] = '0' + unit;
291                PT.name[j] = 0;
292                if (DU[D_PRT]) pt_drive_count++;
293        }
294}
295
296static devfs_handle_t devfs_handle;
297
298int pt_init (void)      /* preliminary initialisation */
299
300{       int unit;
301
302	if (disable) return -1;
303
304	pt_init_units();
305
306	if (pt_detect()) return -1;
307
308	if (devfs_register_chrdev(major,name,&pt_fops)) {
309                printk("pt_init: unable to get major number %d\n",
310                        major);
311	        for (unit=0;unit<PT_UNITS;unit++)
312        	  if (PT.present) pi_release(PI);
313                return -1;
314        }
315
316	devfs_handle = devfs_mk_dir (NULL, "pt", NULL);
317	devfs_register_series (devfs_handle, "%u", 4, DEVFS_FL_DEFAULT,
318			       major, 0, S_IFCHR | S_IRUSR | S_IWUSR,
319			       &pt_fops, NULL);
320	devfs_register_series (devfs_handle, "%un", 4, DEVFS_FL_DEFAULT,
321			       major, 128, S_IFCHR | S_IRUSR | S_IWUSR,
322			       &pt_fops, NULL);
323        return 0;
324}
325
326#ifdef MODULE
327
328/* Glue for modules ... */
329
330void    cleanup_module(void);
331
332int     init_module(void)
333
334{       int     err;
335
336#ifdef PARIDE_JUMBO
337       { extern paride_init();
338         paride_init();
339       }
340#endif
341
342        err = pt_init();
343
344        return err;
345}
346
347void    cleanup_module(void)
348
349{	int unit;
350
351	devfs_unregister (devfs_handle);
352	devfs_unregister_chrdev(major,name);
353
354	for (unit=0;unit<PT_UNITS;unit++)
355	  if (PT.present) pi_release(PI);
356}
357
358#endif
359
360#define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
361#define	RR(c,r)		(pi_read_regr(PI,c,r))
362
363#define DRIVE           (0xa0+0x10*PT.drive)
364
365static int pt_wait( int unit, int go, int stop, char * fun, char * msg )
366
367{       int j, r, e, s, p;
368
369        j = 0;
370        while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PT_SPIN))
371                udelay(PT_SPIN_DEL);
372
373        if ((r&(STAT_ERR&stop))||(j>=PT_SPIN)) {
374           s = RR(0,7);
375           e = RR(0,1);
376           p = RR(0,2);
377           if (j >= PT_SPIN) e |= 0x100;
378           if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
379                           " loop=%d phase=%d\n",
380                            PT.name,fun,msg,r,s,e,j,p);
381           return (e<<8)+s;
382        }
383        return 0;
384}
385
386static int pt_command( int unit, char * cmd, int dlen, char * fun )
387
388{       pi_connect(PI);
389
390        WR(0,6,DRIVE);
391
392        if (pt_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) {
393                pi_disconnect(PI);
394                return -1;
395        }
396
397        WR(0,4,dlen % 256);
398        WR(0,5,dlen / 256);
399        WR(0,7,0xa0);          /* ATAPI packet command */
400
401        if (pt_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) {
402                pi_disconnect(PI);
403                return -1;
404        }
405
406        if (RR(0,2) != 1) {
407           printk("%s: %s: command phase error\n",PT.name,fun);
408           pi_disconnect(PI);
409           return -1;
410        }
411
412        pi_write_block(PI,cmd,12);
413
414        return 0;
415}
416
417static int pt_completion( int unit, char * buf, char * fun )
418
419{       int r, s, n, p;
420
421        r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
422			fun,"completion");
423
424        if (RR(0,7)&STAT_DRQ) {
425           n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
426	   p = RR(0,2)&3;
427	   if (p == 0) pi_write_block(PI,buf,n);
428	   if (p == 2) pi_read_block(PI,buf,n);
429        }
430
431        s = pt_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done");
432
433        pi_disconnect(PI);
434
435        return (r?r:s);
436}
437
438static void pt_req_sense( int unit, int quiet )
439
440{       char    rs_cmd[12] = { ATAPI_REQ_SENSE,0,0,0,16,0,0,0,0,0,0,0 };
441        char    buf[16];
442        int     r;
443
444        r = pt_command(unit,rs_cmd,16,"Request sense");
445        mdelay(1);
446        if (!r) pt_completion(unit,buf,"Request sense");
447
448	PT.last_sense = -1;
449        if (!r) {
450	    if (!quiet) printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
451                                    PT.name,buf[2]&0xf,buf[12],buf[13]);
452	    PT.last_sense = (buf[2]&0xf) | ((buf[12]&0xff)<<8)
453					 | ((buf[13]&0xff)<<16) ;
454	}
455}
456
457static int pt_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
458
459{       int r;
460
461        r = pt_command(unit,cmd,dlen,fun);
462        mdelay(1);
463        if (!r) r = pt_completion(unit,buf,fun);
464        if (r) pt_req_sense(unit,!fun);
465
466        return r;
467}
468
469static void pt_sleep( int cs )
470
471{       current->state = TASK_INTERRUPTIBLE;
472        schedule_timeout(cs);
473}
474
475static int pt_poll_dsc( int unit, int pause, int tmo, char *msg )
476
477{	int	k, e, s;
478
479	k = 0; e = 0; s = 0;
480	while (k < tmo) {
481		pt_sleep(pause);
482		k++;
483		pi_connect(PI);
484		WR(0,6,DRIVE);
485		s = RR(0,7);
486		e = RR(0,1);
487		pi_disconnect(PI);
488		if (s & (STAT_ERR|STAT_SEEK)) break;
489	}
490	if ((k >= tmo) || (s & STAT_ERR)) {
491	   if (k >= tmo) printk("%s: %s DSC timeout\n",PT.name,msg);
492	     else printk("%s: %s stat=0x%x err=0x%x\n",PT.name,msg,s,e);
493	   pt_req_sense(unit,0);
494	   return 0;
495	}
496	return 1;
497}
498
499static void pt_media_access_cmd( int unit, int tmo, char *cmd, char *fun)
500
501{	if (pt_command(unit,cmd,0,fun)) {
502		pt_req_sense(unit,0);
503		return;
504	}
505	pi_disconnect(PI);
506	pt_poll_dsc(unit,HZ,tmo,fun);
507}
508
509static void pt_rewind( int unit )
510
511{	char	rw_cmd[12] = {ATAPI_REWIND,0,0,0,0,0,0,0,0,0,0,0};
512
513	pt_media_access_cmd(unit,PT_REWIND_TMO,rw_cmd,"rewind");
514}
515
516static void pt_write_fm( int unit )
517
518{	char	wm_cmd[12] = {ATAPI_WFM,0,0,0,1,0,0,0,0,0,0,0};
519
520        pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark");
521}
522
523#define DBMSG(msg)      ((verbose>1)?(msg):NULL)
524
525static int pt_reset( int unit )
526
527{	int	i, k, flg;
528	int	expect[5] = {1,1,1,0x14,0xeb};
529
530	pi_connect(PI);
531	WR(0,6,DRIVE);
532	WR(0,7,8);
533
534	pt_sleep(20*HZ/1000);
535
536        k = 0;
537        while ((k++ < PT_RESET_TMO) && (RR(1,6)&STAT_BUSY))
538                pt_sleep(HZ/10);
539
540	flg = 1;
541	for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
542
543	if (verbose) {
544		printk("%s: Reset (%d) signature = ",PT.name,k);
545		for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
546		if (!flg) printk(" (incorrect)");
547		printk("\n");
548	}
549
550	pi_disconnect(PI);
551	return flg-1;
552}
553
554static int pt_ready_wait( int unit, int tmo )
555
556{	char	tr_cmd[12] = {ATAPI_TEST_READY,0,0,0,0,0,0,0,0,0,0,0};
557	int	k, p;
558
559	k = 0;
560	while (k < tmo) {
561	  PT.last_sense = 0;
562	  pt_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
563	  p = PT.last_sense;
564	  if (!p) return 0;
565	  if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
566	  k++;
567          pt_sleep(HZ);
568	}
569	return 0x000020;	/* timeout */
570}
571
572static void xs( char *buf, char *targ, int offs, int len )
573
574{	int	j,k,l;
575
576	j=0; l=0;
577	for (k=0;k<len;k++)
578	   if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
579		l=targ[j++]=buf[k+offs];
580	if (l==0x20) j--;
581	targ[j]=0;
582}
583
584static int xn( char *buf, int offs, int size )
585
586{	int	v,k;
587
588	v=0;
589	for(k=0;k<size;k++) v=v*256+(buf[k+offs]&0xff);
590	return v;
591}
592
593static int pt_identify( int unit )
594
595{	int 	dt, s;
596	char	*ms[2] = {"master","slave"};
597	char	mf[10], id[18];
598	char    id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
599        char    ms_cmd[12] = { ATAPI_MODE_SENSE,0,0x2a,0,36,0,0,0,0,0,0,0};
600	char    ls_cmd[12] = { ATAPI_LOG_SENSE,0,0x71,0,0,0,0,0,36,0,0,0};
601	char	buf[36];
602
603        s = pt_atapi(unit,id_cmd,36,buf,"identify");
604	if (s) return -1;
605
606	dt = buf[0] & 0x1f;
607	if (dt != 1) {
608	  	if (verbose)
609		   printk("%s: Drive %d, unsupported type %d\n",
610				PT.name,PT.drive,dt);
611	  	return -1;
612       	}
613
614	xs(buf,mf,8,8);
615	xs(buf,id,16,16);
616
617	PT.flags = 0;
618	PT.capacity = 0;
619	PT.bs = 0;
620
621	if (!pt_ready_wait(unit,PT_READY_TMO)) PT.flags |= PT_MEDIA;
622
623        if (!pt_atapi(unit,ms_cmd,36,buf,"mode sense")) {
624          if (!(buf[2] & 0x80)) PT.flags |= PT_WRITE_OK;
625	  PT.bs = xn(buf,10,2);
626	}
627
628        if (!pt_atapi(unit,ls_cmd,36,buf,"log sense"))
629		PT.capacity = xn(buf,24,4);
630
631        printk("%s: %s %s, %s",
632		PT.name,mf,id,ms[PT.drive]);
633        if (!(PT.flags & PT_MEDIA))
634                printk(", no media\n");
635        else {  if (!(PT.flags & PT_WRITE_OK)) printk(", RO");
636                printk(", blocksize %d, %d MB\n",
637		       PT.bs,PT.capacity/1024);
638        }
639
640	return 0;
641}
642
643static int pt_probe( int unit )
644
645/*	returns  0, with id set if drive is detected
646	        -1, if drive detection failed
647*/
648
649{	if (PT.drive == -1) {
650	   for (PT.drive=0;PT.drive<=1;PT.drive++)
651		if (!pt_reset(unit)) return pt_identify(unit);
652	} else {
653	   if (!pt_reset(unit)) return pt_identify(unit);
654	}
655        return -1;
656}
657
658static int pt_detect( void )
659
660{	int	k, unit;
661
662	printk("%s: %s version %s, major %d\n",
663		name,name,PT_VERSION,major);
664
665	k = 0;
666	if (pt_drive_count == 0) {
667	    unit = 0;
668	    if (pi_init(PI,1,-1,-1,-1,-1,-1,pt_scratch,
669                        PI_PT,verbose,PT.name)) {
670	        if (!pt_probe(unit)) {
671			PT.present = 1;
672			k++;
673	        } else pi_release(PI);
674	    }
675
676	} else for (unit=0;unit<PT_UNITS;unit++) if (DU[D_PRT])
677	    if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
678			DU[D_PRO],DU[D_DLY],pt_scratch,PI_PT,verbose,
679			PT.name)) {
680                if (!pt_probe(unit)) {
681                        PT.present = 1;
682                        k++;
683                } else pi_release(PI);
684            }
685
686	if (k) return 0;
687
688	printk("%s: No ATAPI tape drive detected\n",name);
689	return -1;
690}
691
692#define DEVICE_NR(dev)	(MINOR(dev) % 128)
693
694static int pt_open (struct inode *inode, struct file *file)
695
696{       int	unit = DEVICE_NR(inode->i_rdev);
697
698        if ((unit >= PT_UNITS) || (!PT.present)) return -ENODEV;
699
700        PT.access++;
701
702	if (PT.access > 1) {
703		PT.access--;
704		return -EBUSY;
705	}
706
707	pt_identify(unit);
708
709	if (!PT.flags & PT_MEDIA) {
710		PT.access--;
711		return -ENODEV;
712		}
713
714	if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) {
715		PT.access--;
716		return -EROFS;
717		}
718
719	if (!(MINOR(inode->i_rdev) & 128))
720		PT.flags |= PT_REWIND;
721
722	PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL);
723	if (PT.bufptr == NULL) {
724		PT.access--;
725		printk("%s: buffer allocation failed\n",PT.name);
726		return -ENOMEM;
727	}
728
729        return 0;
730}
731
732static int pt_ioctl(struct inode *inode,struct file *file,
733                    unsigned int cmd, unsigned long arg)
734{
735	int unit;
736	struct mtop mtop;
737
738        if (!inode || !inode->i_rdev)
739		return -EINVAL;
740        unit = DEVICE_NR(inode->i_rdev);
741        if (unit >= PT_UNITS)
742		return -EINVAL;
743        if (!PT.present)
744		return -ENODEV;
745
746        switch (cmd) {
747	    case MTIOCTOP:
748		if (copy_from_user((char *)&mtop, (char *)arg,
749			           sizeof(struct mtop))) return -EFAULT;
750
751		switch (mtop.mt_op) {
752
753		    case MTREW:
754			pt_rewind(unit);
755			return 0;
756
757		    case MTWEOF:
758			pt_write_fm(unit);
759			return 0;
760
761		    default:
762			printk("%s: Unimplemented mt_op %d\n",PT.name,
763					mtop.mt_op);
764			return -EINVAL;
765		}
766
767            default:
768		printk("%s: Unimplemented ioctl 0x%x\n",PT.name,cmd);
769                return -EINVAL;
770
771        }
772}
773
774
775static int pt_release (struct inode *inode, struct file *file)
776{
777        int	unit = DEVICE_NR(inode->i_rdev);
778
779        if ((unit >= PT_UNITS) || (PT.access <= 0))
780                return -EINVAL;
781
782	lock_kernel();
783	if (PT.flags & PT_WRITING) pt_write_fm(unit);
784
785	if (PT.flags & PT_REWIND) pt_rewind(unit);
786
787	PT.access--;
788
789	kfree(PT.bufptr);
790	PT.bufptr = NULL;
791	unlock_kernel();
792
793	return 0;
794
795}
796
797static ssize_t pt_read(struct file * filp, char * buf,
798                       size_t count, loff_t *ppos)
799{
800  	struct 	inode *ino = filp->f_dentry->d_inode;
801	int	unit = DEVICE_NR(ino->i_rdev);
802	char	rd_cmd[12] = {ATAPI_READ_6,1,0,0,0,0,0,0,0,0,0,0};
803	int	k, n, r, p, s, t, b;
804
805	if (!(PT.flags & (PT_READING|PT_WRITING))) {
806	    PT.flags |= PT_READING;
807	    if (pt_atapi(unit,rd_cmd,0,NULL,"start read-ahead"))
808			return -EIO;
809	} else if (PT.flags & PT_WRITING) return -EIO;
810
811	if (PT.flags & PT_EOF) return 0;
812
813	t = 0;
814
815	while (count > 0) {
816
817	    if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"read")) return -EIO;
818
819	    n = count;
820	    if (n > 32768) n = 32768;   /* max per command */
821	    b = (n-1+PT.bs)/PT.bs;
822	    n = b*PT.bs;		/* rounded up to even block */
823
824	    rd_cmd[4] = b;
825
826	    r = pt_command(unit,rd_cmd,n,"read");
827
828	    mdelay(1);
829
830	    if (r) {
831	        pt_req_sense(unit,0);
832	        return -EIO;
833	    }
834
835	    while (1) {
836
837	        r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
838                                           DBMSG("read DRQ"),"");
839
840	        if (r & STAT_SENSE) {
841	            pi_disconnect(PI);
842		    pt_req_sense(unit,0);
843		    return -EIO;
844	        }
845
846	        if (r) PT.flags |= PT_EOF;
847
848	        s = RR(0,7);
849
850	        if (!(s & STAT_DRQ)) break;
851
852	    	n = (RR(0,4)+256*RR(0,5));
853	    	p = (RR(0,2)&3);
854	    	if (p != 2) {
855		    pi_disconnect(PI);
856		    printk("%s: Phase error on read: %d\n",PT.name,p);
857		    return -EIO;
858	    	}
859
860	        while (n > 0) {
861		    k = n;
862		    if (k > PT_BUFSIZE) k = PT_BUFSIZE;
863		    pi_read_block(PI,PT.bufptr,k);
864		    n -= k;
865		    b = k;
866		    if (b > count) b = count;
867		    if (copy_to_user(buf + t, PT.bufptr, b)) {
868	    		pi_disconnect(PI);
869			return -EFAULT;
870		    }
871		    t += b;
872		    count -= b;
873	        }
874
875	    }
876	    pi_disconnect(PI);
877	    if (PT.flags & PT_EOF) break;
878	}
879
880	return t;
881
882}
883
884static ssize_t pt_write(struct file * filp, const char * buf,
885                        size_t count, loff_t *ppos)
886{
887        struct inode *ino = filp->f_dentry->d_inode;
888        int unit = DEVICE_NR(ino->i_rdev);
889        char    wr_cmd[12] = {ATAPI_WRITE_6,1,0,0,0,0,0,0,0,0,0,0};
890        int     k, n, r, p, s, t, b;
891
892	if (!(PT.flags & PT_WRITE_OK)) return -EROFS;
893
894        if (!(PT.flags & (PT_READING|PT_WRITING))) {
895            PT.flags |= PT_WRITING;
896            if (pt_atapi(unit,wr_cmd,0,NULL,"start buffer-available mode"))
897                        return -EIO;
898        } else if (PT.flags&PT_READING) return -EIO;
899
900	if (PT.flags & PT_EOF) return -ENOSPC;
901
902	t = 0;
903
904	while (count > 0) {
905
906	    if (!pt_poll_dsc(unit,HZ/100,PT_TMO,"write")) return -EIO;
907
908            n = count;
909            if (n > 32768) n = 32768;	/* max per command */
910            b = (n-1+PT.bs)/PT.bs;
911            n = b*PT.bs;                /* rounded up to even block */
912
913            wr_cmd[4] = b;
914
915            r = pt_command(unit,wr_cmd,n,"write");
916
917            mdelay(1);
918
919            if (r) {			/* error delivering command only */
920                pt_req_sense(unit,0);
921                return -EIO;
922            }
923
924	    while (1) {
925
926                r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
927			                        DBMSG("write DRQ"),NULL);
928
929                if (r & STAT_SENSE) {
930                    pi_disconnect(PI);
931                    pt_req_sense(unit,0);
932                    return -EIO;
933                }
934
935                if (r) PT.flags |= PT_EOF;
936
937	        s = RR(0,7);
938
939	        if (!(s & STAT_DRQ)) break;
940
941                n = (RR(0,4)+256*RR(0,5));
942                p = (RR(0,2)&3);
943                if (p != 0) {
944                    pi_disconnect(PI);
945                    printk("%s: Phase error on write: %d \n",PT.name,p);
946                    return -EIO;
947                }
948
949                while (n > 0) {
950		    k = n;
951		    if (k > PT_BUFSIZE) k = PT_BUFSIZE;
952		    b = k;
953		    if (b > count) b = count;
954		    if (copy_from_user(PT.bufptr, buf + t, b)) {
955			pi_disconnect(PI);
956			return -EFAULT;
957		    }
958                    pi_write_block(PI,PT.bufptr,k);
959		    t += b;
960		    count -= b;
961		    n -= k;
962                }
963
964	    }
965	    pi_disconnect(PI);
966	    if (PT.flags & PT_EOF) break;
967	}
968
969	return t;
970}
971
972/* end of pt.c */
973
974MODULE_LICENSE("GPL");
975