1/*
2        pf.c    (c) 1997-8  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 disk
6        drives based on chips supported by the paride module.
7
8        By default, the driver will autoprobe for a single parallel
9        port ATAPI disk drive, but if their individual parameters are
10        specified, the driver can handle up to 4 drives.
11
12        The behaviour of the pf driver can be altered by setting
13        some parameters from the insmod command line.  The following
14        parameters are adjustable:
15
16            drive0      These four arguments can be arrays of
17            drive1      1-7 integers as follows:
18            drive2
19            drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<lun>,<dly>
20
21                        Where,
22
23                <prt>   is the base of the parallel port address for
24                        the corresponding drive.  (required)
25
26                <pro>   is the protocol number for the adapter that
27                        supports this drive.  These numbers are
28                        logged by 'paride' when the protocol modules
29                        are initialised.  (0 if not given)
30
31                <uni>   for those adapters that support chained
32                        devices, this is the unit selector for the
33                        chain of devices on the given port.  It should
34                        be zero for devices that don't support chaining.
35                        (0 if not given)
36
37                <mod>   this can be -1 to choose the best mode, or one
38                        of the mode numbers supported by the adapter.
39                        (-1 if not given)
40
41                <slv>   ATAPI CDroms can be jumpered to master or slave.
42                        Set this to 0 to choose the master drive, 1 to
43                        choose the slave, -1 (the default) to choose the
44                        first drive found.
45
46		<lun>   Some ATAPI devices support multiple LUNs.
47                        One example is the ATAPI PD/CD drive from
48                        Matshita/Panasonic.  This device has a
49                        CD drive on LUN 0 and a PD drive on LUN 1.
50                        By default, the driver will search for the
51                        first LUN with a supported device.  Set
52                        this parameter to force it to use a specific
53                        LUN.  (default -1)
54
55                <dly>   some parallel ports require the driver to
56                        go more slowly.  -1 sets a default value that
57                        should work with the chosen protocol.  Otherwise,
58                        set this to a small integer, the larger it is
59                        the slower the port i/o.  In some cases, setting
60                        this to zero will speed up the device. (default -1)
61
62	    major	You may use this parameter to overide the
63			default major number (47) that this driver
64			will use.  Be sure to change the device
65			name as well.
66
67	    name	This parameter is a character string that
68			contains the name the kernel will use for this
69			device (in /proc output, for instance).
70			(default "pf").
71
72            cluster     The driver will attempt to aggregate requests
73                        for adjacent blocks into larger multi-block
74                        clusters.  The maximum cluster size (in 512
75                        byte sectors) is set with this parameter.
76                        (default 64)
77
78            verbose     This parameter controls the amount of logging
79                        that the driver will do.  Set it to 0 for
80                        normal operation, 1 to see autoprobe progress
81                        messages, or 2 to see additional debugging
82                        output.  (default 0)
83
84	    nice        This parameter controls the driver's use of
85			idle CPU time, at the expense of some speed.
86
87        If this driver is built into the kernel, you can use the
88        following command line parameters, with the same values
89        as the corresponding module parameters listed above:
90
91            pf.drive0
92            pf.drive1
93            pf.drive2
94            pf.drive3
95	    pf.cluster
96            pf.nice
97
98        In addition, you can use the parameter pf.disable to disable
99        the driver entirely.
100
101*/
102
103/* Changes:
104
105	1.01	GRG 1998.05.03  Changes for SMP.  Eliminate sti().
106				Fix for drives that don't clear STAT_ERR
107			        until after next CDB delivered.
108				Small change in pf_completion to round
109				up transfer size.
110	1.02    GRG 1998.06.16  Eliminated an Ugh
111	1.03    GRG 1998.08.16  Use HZ in loop timings, extra debugging
112	1.04    GRG 1998.09.24  Added jumbo support
113
114*/
115
116#define PF_VERSION      "1.04"
117#define PF_MAJOR	47
118#define PF_NAME		"pf"
119#define PF_UNITS	4
120
121/* Here are things one can override from the insmod command.
122   Most are autoprobed by paride unless set here.  Verbose is off
123   by default.
124
125*/
126
127static int	verbose = 0;
128static int	major = PF_MAJOR;
129static char	*name = PF_NAME;
130static int      cluster = 64;
131static int      nice = 0;
132static int      disable = 0;
133
134static int drive0[7] = {0,0,0,-1,-1,-1,-1};
135static int drive1[7] = {0,0,0,-1,-1,-1,-1};
136static int drive2[7] = {0,0,0,-1,-1,-1,-1};
137static int drive3[7] = {0,0,0,-1,-1,-1,-1};
138
139static int (*drives[4])[7] = {&drive0,&drive1,&drive2,&drive3};
140static int pf_drive_count;
141
142#define D_PRT   0
143#define D_PRO   1
144#define D_UNI   2
145#define D_MOD   3
146#define D_SLV   4
147#define D_LUN   5
148#define D_DLY   6
149
150#define DU              (*drives[unit])
151
152/* end of parameters */
153
154
155#include <linux/module.h>
156#include <linux/errno.h>
157#include <linux/fs.h>
158#include <linux/kernel.h>
159#include <linux/delay.h>
160#include <linux/genhd.h>
161#include <linux/hdreg.h>
162#include <linux/cdrom.h>
163#include <linux/spinlock.h>
164
165#include <asm/uaccess.h>
166
167#ifndef MODULE
168
169#include "setup.h"
170
171static STT pf_stt[7] = {{"drive0",7,drive0},
172                        {"drive1",7,drive1},
173                        {"drive2",7,drive2},
174                        {"drive3",7,drive3},
175			{"disable",1,&disable},
176                        {"cluster",1,&cluster},
177                        {"nice",1,&nice}};
178
179void pf_setup( char *str, int *ints)
180
181{       generic_setup(pf_stt,7,str);
182}
183
184#endif
185
186MODULE_PARM(verbose,"i");
187MODULE_PARM(major,"i");
188MODULE_PARM(name,"s");
189MODULE_PARM(cluster,"i");
190MODULE_PARM(nice,"i");
191MODULE_PARM(drive0,"1-7i");
192MODULE_PARM(drive1,"1-7i");
193MODULE_PARM(drive2,"1-7i");
194MODULE_PARM(drive3,"1-7i");
195
196#include "paride.h"
197
198/* set up defines for blk.h,  why don't all drivers do it this way ? */
199
200#define MAJOR_NR   major
201#define DEVICE_NAME "PF"
202#define DEVICE_REQUEST do_pf_request
203#define DEVICE_NR(device) MINOR(device)
204#define DEVICE_ON(device)
205#define DEVICE_OFF(device)
206
207#include <linux/blk.h>
208#include <linux/blkpg.h>
209
210#include "pseudo.h"
211
212/* constants for faking geometry numbers */
213
214#define PF_FD_MAX	8192		/* use FD geometry under this size */
215#define PF_FD_HDS	2
216#define PF_FD_SPT	18
217#define PF_HD_HDS	64
218#define PF_HD_SPT	32
219
220#define PF_MAX_RETRIES  5
221#define PF_TMO          800             /* interrupt timeout in jiffies */
222#define PF_SPIN_DEL     50              /* spin delay in micro-seconds  */
223
224#define PF_SPIN         (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
225
226#define STAT_ERR        0x00001
227#define STAT_INDEX      0x00002
228#define STAT_ECC        0x00004
229#define STAT_DRQ        0x00008
230#define STAT_SEEK       0x00010
231#define STAT_WRERR      0x00020
232#define STAT_READY      0x00040
233#define STAT_BUSY       0x00080
234
235#define ATAPI_REQ_SENSE		0x03
236#define ATAPI_LOCK		0x1e
237#define ATAPI_DOOR		0x1b
238#define ATAPI_MODE_SENSE	0x5a
239#define ATAPI_CAPACITY		0x25
240#define ATAPI_IDENTIFY		0x12
241#define ATAPI_READ_10		0x28
242#define ATAPI_WRITE_10		0x2a
243
244int pf_init(void);
245#ifdef MODULE
246void cleanup_module( void );
247#endif
248static int pf_open(struct inode *inode, struct file *file);
249static void do_pf_request(request_queue_t * q);
250static int pf_ioctl(struct inode *inode,struct file *file,
251                    unsigned int cmd, unsigned long arg);
252
253static int pf_release (struct inode *inode, struct file *file);
254
255static int pf_detect(void);
256static void do_pf_read(void);
257static void do_pf_read_start(void);
258static void do_pf_write(void);
259static void do_pf_write_start(void);
260static void do_pf_read_drq( void );
261static void do_pf_write_done( void );
262
263static int pf_identify (int unit);
264static void pf_lock(int unit, int func);
265static void pf_eject(int unit);
266static int pf_check_media(kdev_t dev);
267
268static int pf_blocksizes[PF_UNITS];
269
270#define PF_NM           0
271#define PF_RO           1
272#define PF_RW           2
273
274#define PF_NAMELEN      8
275
276struct pf_unit {
277	struct pi_adapter pia;    /* interface to paride layer */
278	struct pi_adapter *pi;
279	int removable;		  /* removable media device  ?  */
280	int media_status;	  /* media present ?  WP ? */
281	int drive;		  /* drive */
282	int lun;
283	int access;               /* count of active opens ... */
284	int capacity;             /* Size of this volume in sectors */
285	int present;		  /* device present ? */
286	char name[PF_NAMELEN];	  /* pf0, pf1, ... */
287	};
288
289struct pf_unit pf[PF_UNITS];
290
291/*  'unit' must be defined in all functions - either as a local or a param */
292
293#define PF pf[unit]
294#define PI PF.pi
295
296static char pf_scratch[512];            /* scratch block buffer */
297
298/* the variables below are used mainly in the I/O request engine, which
299   processes only one request at a time.
300*/
301
302static int pf_retries = 0;              /* i/o error retry count */
303static int pf_busy = 0;                 /* request being processed ? */
304static int pf_block;                    /* address of next requested block */
305static int pf_count;                    /* number of blocks still to do */
306static int pf_run;			/* sectors in current cluster */
307static int pf_cmd;			/* current command READ/WRITE */
308static int pf_unit;			/* unit of current request */
309static int pf_mask;			/* stopper for pseudo-int */
310static char * pf_buf;                   /* buffer for request in progress */
311
312/* kernel glue structures */
313
314static struct block_device_operations pf_fops = {
315	owner:			THIS_MODULE,
316	open:			pf_open,
317	release:		pf_release,
318	ioctl:			pf_ioctl,
319	check_media_change:	pf_check_media,
320};
321
322void pf_init_units( void )
323
324{       int     unit, j;
325
326        pf_drive_count = 0;
327        for (unit=0;unit<PF_UNITS;unit++) {
328                PF.pi = & PF.pia;
329                PF.access = 0;
330                PF.media_status = PF_NM;
331                PF.capacity = 0;
332                PF.present = 0;
333		PF.drive = DU[D_SLV];
334		PF.lun = DU[D_LUN];
335                j = 0;
336                while ((j < PF_NAMELEN-2) && (PF.name[j]=name[j])) j++;
337                PF.name[j++] = '0' + unit;
338                PF.name[j] = 0;
339                if (DU[D_PRT]) pf_drive_count++;
340        }
341}
342
343static inline int pf_new_segment(request_queue_t *q, struct request *req, int max_segments)
344{
345	if (max_segments > cluster)
346		max_segments = cluster;
347
348	if (req->nr_segments < max_segments) {
349		req->nr_segments++;
350		return 1;
351	}
352	return 0;
353}
354
355static int pf_back_merge_fn(request_queue_t *q, struct request *req,
356			    struct buffer_head *bh, int max_segments)
357{
358	if (req->bhtail->b_data + req->bhtail->b_size == bh->b_data)
359		return 1;
360	return pf_new_segment(q, req, max_segments);
361}
362
363static int pf_front_merge_fn(request_queue_t *q, struct request *req,
364			     struct buffer_head *bh, int max_segments)
365{
366	if (bh->b_data + bh->b_size == req->bh->b_data)
367		return 1;
368	return pf_new_segment(q, req, max_segments);
369}
370
371static int pf_merge_requests_fn(request_queue_t *q, struct request *req,
372				struct request *next, int max_segments)
373{
374	int total_segments = req->nr_segments + next->nr_segments;
375	int same_segment;
376
377	if (max_segments > cluster)
378		max_segments = cluster;
379
380	same_segment = 0;
381	if (req->bhtail->b_data + req->bhtail->b_size == next->bh->b_data) {
382		total_segments--;
383		same_segment = 1;
384	}
385
386	if (total_segments > max_segments)
387		return 0;
388
389	req->nr_segments = total_segments;
390	return 1;
391}
392
393int pf_init (void)      /* preliminary initialisation */
394
395{       int i;
396	request_queue_t * q;
397
398	if (disable) return -1;
399
400	pf_init_units();
401
402	if (pf_detect()) return -1;
403	pf_busy = 0;
404
405        if (register_blkdev(MAJOR_NR,name,&pf_fops)) {
406                printk("pf_init: unable to get major number %d\n",
407                        major);
408                return -1;
409        }
410	q = BLK_DEFAULT_QUEUE(MAJOR_NR);
411	blk_init_queue(q, DEVICE_REQUEST);
412	q->back_merge_fn = pf_back_merge_fn;
413	q->front_merge_fn = pf_front_merge_fn;
414	q->merge_requests_fn = pf_merge_requests_fn;
415        read_ahead[MAJOR_NR] = 8;       /* 8 sector (4kB) read ahead */
416
417	for (i=0;i<PF_UNITS;i++) pf_blocksizes[i] = 1024;
418	blksize_size[MAJOR_NR] = pf_blocksizes;
419	for (i=0;i<PF_UNITS;i++)
420		register_disk(NULL, MKDEV(MAJOR_NR, i), 1, &pf_fops, 0);
421
422        return 0;
423}
424
425static int pf_open (struct inode *inode, struct file *file)
426
427{       int	unit = DEVICE_NR(inode->i_rdev);
428
429        if ((unit >= PF_UNITS) || (!PF.present)) return -ENODEV;
430
431	pf_identify(unit);
432
433	if (PF.media_status == PF_NM)
434		return -ENODEV;
435
436	if ((PF.media_status == PF_RO) && (file ->f_mode & 2))
437		return -EROFS;
438
439        PF.access++;
440        if (PF.removable) pf_lock(unit,1);
441
442        return 0;
443}
444
445static int pf_ioctl(struct inode *inode,struct file *file,
446                    unsigned int cmd, unsigned long arg)
447
448{       int err, unit;
449	struct hd_geometry *geo = (struct hd_geometry *) arg;
450
451        if ((!inode) || (!inode->i_rdev)) return -EINVAL;
452        unit = DEVICE_NR(inode->i_rdev);
453        if (unit >= PF_UNITS) return -EINVAL;
454        if (!PF.present) return -ENODEV;
455
456        switch (cmd) {
457	    case CDROMEJECT:
458		if (PF.access == 1) {
459			pf_eject(unit);
460			return 0;
461			}
462	    case HDIO_GETGEO:
463                if (!geo) return -EINVAL;
464                err = verify_area(VERIFY_WRITE,geo,sizeof(*geo));
465                if (err) return err;
466                if (PF.capacity < PF_FD_MAX) {
467                    put_user(PF.capacity/(PF_FD_HDS*PF_FD_SPT),
468                                (short *) &geo->cylinders);
469                    put_user(PF_FD_HDS, (char *) &geo->heads);
470                    put_user(PF_FD_SPT, (char *) &geo->sectors);
471                } else {
472                    put_user(PF.capacity/(PF_HD_HDS*PF_HD_SPT),
473				(short *) &geo->cylinders);
474                    put_user(PF_HD_HDS, (char *) &geo->heads);
475                    put_user(PF_HD_SPT, (char *) &geo->sectors);
476                }
477                put_user(0,(long *)&geo->start);
478                return 0;
479            case BLKGETSIZE:
480                return put_user(PF.capacity,(long *) arg);
481            case BLKGETSIZE64:
482                return put_user((u64)PF.capacity << 9,(u64 *)arg);
483	    case BLKROSET:
484	    case BLKROGET:
485	    case BLKRASET:
486	    case BLKRAGET:
487	    case BLKFLSBUF:
488		return blk_ioctl(inode->i_rdev, cmd, arg);
489            default:
490                return -EINVAL;
491        }
492}
493
494
495static int pf_release (struct inode *inode, struct file *file)
496
497{       kdev_t devp;
498	int	unit;
499
500        devp = inode->i_rdev;
501        unit = DEVICE_NR(devp);
502
503        if ((unit >= PF_UNITS) || (PF.access <= 0))
504                return -EINVAL;
505
506	PF.access--;
507
508	if (!PF.access && PF.removable)
509		pf_lock(unit,0);
510
511	return 0;
512
513}
514
515static int pf_check_media( kdev_t dev)
516
517{       return 1;
518}
519
520#ifdef MODULE
521
522/* Glue for modules ... */
523
524void    cleanup_module(void);
525
526int     init_module(void)
527
528{       int     err;
529
530#ifdef PARIDE_JUMBO
531       { extern paride_init();
532         paride_init();
533       }
534#endif
535
536        err = pf_init();
537
538        return err;
539}
540
541void    cleanup_module(void)
542
543{       int unit;
544
545        unregister_blkdev(MAJOR_NR,name);
546
547	for (unit=0;unit<PF_UNITS;unit++)
548	  if (PF.present) pi_release(PI);
549}
550
551#endif
552
553#define	WR(c,r,v)	pi_write_regr(PI,c,r,v)
554#define	RR(c,r)		(pi_read_regr(PI,c,r))
555
556#define LUN             (0x20*PF.lun)
557#define DRIVE           (0xa0+0x10*PF.drive)
558
559static int pf_wait( int unit, int go, int stop, char * fun, char * msg )
560
561{       int j, r, e, s, p;
562
563        j = 0;
564        while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PF_SPIN))
565                udelay(PF_SPIN_DEL);
566
567        if ((r&(STAT_ERR&stop))||(j>=PF_SPIN)) {
568           s = RR(0,7);
569           e = RR(0,1);
570           p = RR(0,2);
571           if (j >= PF_SPIN) e |= 0x100;
572           if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
573                           " loop=%d phase=%d\n",
574                            PF.name,fun,msg,r,s,e,j,p);
575           return (e<<8)+s;
576        }
577        return 0;
578}
579
580static int pf_command( int unit, char * cmd, int dlen, char * fun )
581
582{       pi_connect(PI);
583
584        WR(0,6,DRIVE);
585
586        if (pf_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) {
587                pi_disconnect(PI);
588                return -1;
589        }
590
591        WR(0,4,dlen % 256);
592        WR(0,5,dlen / 256);
593        WR(0,7,0xa0);          /* ATAPI packet command */
594
595        if (pf_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) {
596                pi_disconnect(PI);
597                return -1;
598        }
599
600        if (RR(0,2) != 1) {
601           printk("%s: %s: command phase error\n",PF.name,fun);
602           pi_disconnect(PI);
603           return -1;
604        }
605
606        pi_write_block(PI,cmd,12);
607
608        return 0;
609}
610
611static int pf_completion( int unit, char * buf, char * fun )
612
613{       int r, s, n;
614
615        r = pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
616			fun,"completion");
617
618        if ((RR(0,2)&2) && (RR(0,7)&STAT_DRQ)) {
619                n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
620                pi_read_block(PI,buf,n);
621        }
622
623        s = pf_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done");
624
625        pi_disconnect(PI);
626
627        return (r?r:s);
628}
629
630static void pf_req_sense( int unit, int quiet )
631
632{       char    rs_cmd[12] = { ATAPI_REQ_SENSE,LUN,0,0,16,0,0,0,0,0,0,0 };
633        char    buf[16];
634        int     r;
635
636        r = pf_command(unit,rs_cmd,16,"Request sense");
637        mdelay(1);
638        if (!r) pf_completion(unit,buf,"Request sense");
639
640        if ((!r)&&(!quiet))
641                printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
642                       PF.name,buf[2]&0xf,buf[12],buf[13]);
643}
644
645static int pf_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
646
647{       int r;
648
649        r = pf_command(unit,cmd,dlen,fun);
650        mdelay(1);
651        if (!r) r = pf_completion(unit,buf,fun);
652        if (r) pf_req_sense(unit,!fun);
653
654        return r;
655}
656
657#define DBMSG(msg)      ((verbose>1)?(msg):NULL)
658
659static void pf_lock(int unit, int func)
660
661{	char	lo_cmd[12] = { ATAPI_LOCK,LUN,0,0,func,0,0,0,0,0,0,0 };
662
663        pf_atapi(unit,lo_cmd,0,pf_scratch,func?"unlock":"lock");
664}
665
666
667static void pf_eject( int unit )
668
669{	char	ej_cmd[12] = { ATAPI_DOOR,LUN,0,0,2,0,0,0,0,0,0,0 };
670
671	pf_lock(unit,0);
672	pf_atapi(unit,ej_cmd,0,pf_scratch,"eject");
673}
674
675#define PF_RESET_TMO   30              /* in tenths of a second */
676
677static void pf_sleep( int cs )
678
679{       current->state = TASK_INTERRUPTIBLE;
680        schedule_timeout(cs);
681}
682
683
684static int pf_reset( int unit )
685
686/* the ATAPI standard actually specifies the contents of all 7 registers
687   after a reset, but the specification is ambiguous concerning the last
688   two bytes, and different drives interpret the standard differently.
689*/
690
691{	int	i, k, flg;
692	int	expect[5] = {1,1,1,0x14,0xeb};
693
694	pi_connect(PI);
695	WR(0,6,DRIVE);
696	WR(0,7,8);
697
698	pf_sleep(20*HZ/1000);
699
700        k = 0;
701        while ((k++ < PF_RESET_TMO) && (RR(1,6)&STAT_BUSY))
702                pf_sleep(HZ/10);
703
704	flg = 1;
705	for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
706
707	if (verbose) {
708		printk("%s: Reset (%d) signature = ",PF.name,k);
709		for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
710		if (!flg) printk(" (incorrect)");
711		printk("\n");
712	}
713
714	pi_disconnect(PI);
715	return flg-1;
716}
717
718static void pf_mode_sense( int unit )
719
720{       char    ms_cmd[12] = { ATAPI_MODE_SENSE,LUN,0,0,0,0,0,0,8,0,0,0};
721	char	buf[8];
722
723        pf_atapi(unit,ms_cmd,8,buf,DBMSG("mode sense"));
724	PF.media_status = PF_RW;
725	if (buf[3] & 0x80) PF.media_status = PF_RO;
726}
727
728static void xs( char *buf, char *targ, int offs, int len )
729
730{	int	j,k,l;
731
732	j=0; l=0;
733	for (k=0;k<len;k++)
734	   if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
735		l=targ[j++]=buf[k+offs];
736	if (l==0x20) j--;
737	targ[j]=0;
738}
739
740static int xl( char *buf, int offs )
741
742{	int	v,k;
743
744	v=0;
745	for(k=0;k<4;k++) v=v*256+(buf[k+offs]&0xff);
746	return v;
747}
748
749static void pf_get_capacity( int unit )
750
751{	char    rc_cmd[12] = { ATAPI_CAPACITY,LUN,0,0,0,0,0,0,0,0,0,0};
752	char	buf[8];
753        int 	bs;
754
755	if (pf_atapi(unit,rc_cmd,8,buf,DBMSG("get capacity"))) {
756		PF.media_status = PF_NM;
757		return;
758	}
759	PF.capacity = xl(buf,0) + 1;
760	bs = xl(buf,4);
761	if (bs != 512) {
762		PF.capacity = 0;
763		if (verbose) printk("%s: Drive %d, LUN %d,"
764		       		    " unsupported block size %d\n",
765			            PF.name,PF.drive,PF.lun,bs);
766		}
767}
768
769static int pf_identify( int unit )
770
771{	int 	dt, s;
772	char	*ms[2] = {"master","slave"};
773	char	mf[10], id[18];
774	char    id_cmd[12] = { ATAPI_IDENTIFY,LUN,0,0,36,0,0,0,0,0,0,0};
775	char	buf[36];
776
777        s = pf_atapi(unit,id_cmd,36,buf,"identify");
778	if (s) return -1;
779
780	dt = buf[0] & 0x1f;
781	if ((dt != 0) && (dt != 7)) {
782	  	if (verbose)
783		   printk("%s: Drive %d, LUN %d, unsupported type %d\n",
784				PF.name,PF.drive,PF.lun,dt);
785	  	return -1;
786       	}
787
788	xs(buf,mf,8,8);
789	xs(buf,id,16,16);
790
791	PF.removable = (buf[1] & 0x80);
792
793	pf_mode_sense(unit);
794	pf_mode_sense(unit);
795	pf_mode_sense(unit);
796
797	pf_get_capacity(unit);
798
799        printk("%s: %s %s, %s LUN %d, type %d",
800		PF.name,mf,id,ms[PF.drive],PF.lun,dt);
801        if (PF.removable) printk(", removable");
802        if (PF.media_status == PF_NM)
803                printk(", no media\n");
804        else {  if (PF.media_status == PF_RO) printk(", RO");
805                printk(", %d blocks\n",PF.capacity);
806        }
807
808	return 0;
809}
810
811static int pf_probe( int unit )
812
813/*	returns  0, with id set if drive is detected
814	        -1, if drive detection failed
815*/
816
817{	if (PF.drive == -1) {
818	   for (PF.drive=0;PF.drive<=1;PF.drive++)
819		if (!pf_reset(unit)) {
820		   if (PF.lun != -1) return pf_identify(unit);
821		   else for (PF.lun=0;PF.lun<8;PF.lun++)
822                           if (!pf_identify(unit)) return 0;
823		}
824	} else {
825	   if (pf_reset(unit)) return -1;
826	   if (PF.lun != -1) return pf_identify(unit);
827	   for (PF.lun=0;PF.lun<8;PF.lun++)
828	      if (!pf_identify(unit)) return 0;
829	}
830        return -1;
831}
832
833static int pf_detect( void )
834
835{	int	k, unit;
836
837	printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
838		name,name,PF_VERSION,major,cluster,nice);
839
840	k = 0;
841	if (pf_drive_count == 0) {
842	    unit = 0;
843	    if (pi_init(PI,1,-1,-1,-1,-1,-1,pf_scratch,
844                        PI_PF,verbose,PF.name)) {
845	        if (!pf_probe(unit)) {
846			PF.present = 1;
847			k++;
848	        } else pi_release(PI);
849	    }
850
851	} else for (unit=0;unit<PF_UNITS;unit++) if (DU[D_PRT])
852	    if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
853			DU[D_PRO],DU[D_DLY],pf_scratch,PI_PF,verbose,
854			PF.name)) {
855                if (!pf_probe(unit)) {
856                        PF.present = 1;
857                        k++;
858                } else pi_release(PI);
859            }
860
861	if (k) return 0;
862
863	printk("%s: No ATAPI disk detected\n",name);
864	return -1;
865}
866
867/* The i/o request engine */
868
869static int pf_start( int unit, int cmd, int b, int c )
870
871{	int	i;
872	char	io_cmd[12] = {cmd,LUN,0,0,0,0,0,0,0,0,0,0};
873
874	for(i=0;i<4;i++) {
875	   io_cmd[5-i] = b & 0xff;
876	   b = b >> 8;
877	}
878
879	io_cmd[8] = c & 0xff;
880	io_cmd[7] = (c >> 8) & 0xff;
881
882	i = pf_command(unit,io_cmd,c*512,"start i/o");
883
884        mdelay(1);
885
886	return i;
887}
888
889static int pf_ready( void )
890
891{	int	unit = pf_unit;
892
893	return (((RR(1,6)&(STAT_BUSY|pf_mask)) == pf_mask));
894}
895
896static void do_pf_request (request_queue_t * q)
897
898{       struct buffer_head * bh;
899	int unit;
900
901        if (pf_busy) return;
902repeat:
903        if (QUEUE_EMPTY || (CURRENT->rq_status == RQ_INACTIVE)) return;
904        INIT_REQUEST;
905
906        pf_unit = unit = DEVICE_NR(CURRENT->rq_dev);
907        pf_block = CURRENT->sector;
908        pf_run = CURRENT->nr_sectors;
909        pf_count = CURRENT->current_nr_sectors;
910
911	bh = CURRENT->bh;
912
913        if ((pf_unit >= PF_UNITS) || (pf_block+pf_count > PF.capacity)) {
914                end_request(0);
915                goto repeat;
916        }
917
918	pf_cmd = CURRENT->cmd;
919        pf_buf = CURRENT->buffer;
920        pf_retries = 0;
921
922	pf_busy = 1;
923        if (pf_cmd == READ) pi_do_claimed(PI,do_pf_read);
924        else if (pf_cmd == WRITE) pi_do_claimed(PI,do_pf_write);
925        else {  pf_busy = 0;
926		end_request(0);
927                goto repeat;
928        }
929}
930
931static void pf_next_buf( int unit )
932
933{	unsigned long	saved_flags;
934
935	spin_lock_irqsave(&io_request_lock,saved_flags);
936	end_request(1);
937	if (!pf_run) { spin_unlock_irqrestore(&io_request_lock,saved_flags);
938		       return;
939	}
940
941/* paranoia */
942
943	if (QUEUE_EMPTY ||
944	    (CURRENT->cmd != pf_cmd) ||
945	    (DEVICE_NR(CURRENT->rq_dev) != pf_unit) ||
946	    (CURRENT->rq_status == RQ_INACTIVE) ||
947	    (CURRENT->sector != pf_block))
948		printk("%s: OUCH: request list changed unexpectedly\n",
949			PF.name);
950
951	pf_count = CURRENT->current_nr_sectors;
952	pf_buf = CURRENT->buffer;
953	spin_unlock_irqrestore(&io_request_lock,saved_flags);
954}
955
956static void do_pf_read( void )
957
958/* detach from the calling context - in case the spinlock is held */
959
960{	ps_set_intr(do_pf_read_start,0,0,nice);
961}
962
963static void do_pf_read_start( void )
964
965{       int	unit = pf_unit;
966	unsigned long	saved_flags;
967
968	pf_busy = 1;
969
970	if (pf_start(unit,ATAPI_READ_10,pf_block,pf_run)) {
971                pi_disconnect(PI);
972                if (pf_retries < PF_MAX_RETRIES) {
973                        pf_retries++;
974                        pi_do_claimed(PI,do_pf_read_start);
975			return;
976                }
977		spin_lock_irqsave(&io_request_lock,saved_flags);
978                end_request(0);
979                pf_busy = 0;
980		do_pf_request(NULL);
981		spin_unlock_irqrestore(&io_request_lock,saved_flags);
982                return;
983        }
984	pf_mask = STAT_DRQ;
985        ps_set_intr(do_pf_read_drq,pf_ready,PF_TMO,nice);
986}
987
988static void do_pf_read_drq( void )
989
990{       int	unit = pf_unit;
991	unsigned long	saved_flags;
992
993	while (1) {
994            if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR,
995			"read block","completion") & STAT_ERR) {
996                pi_disconnect(PI);
997                if (pf_retries < PF_MAX_RETRIES) {
998			pf_req_sense(unit,0);
999                        pf_retries++;
1000                        pi_do_claimed(PI,do_pf_read_start);
1001                        return;
1002                }
1003		spin_lock_irqsave(&io_request_lock,saved_flags);
1004                end_request(0);
1005                pf_busy = 0;
1006		do_pf_request(NULL);
1007		spin_unlock_irqrestore(&io_request_lock,saved_flags);
1008                return;
1009            }
1010            pi_read_block(PI,pf_buf,512);
1011            pf_count--; pf_run--;
1012            pf_buf += 512;
1013	    pf_block++;
1014	    if (!pf_run) break;
1015	    if (!pf_count) pf_next_buf(unit);
1016        }
1017        pi_disconnect(PI);
1018	spin_lock_irqsave(&io_request_lock,saved_flags);
1019        end_request(1);
1020        pf_busy = 0;
1021	do_pf_request(NULL);
1022	spin_unlock_irqrestore(&io_request_lock,saved_flags);
1023}
1024
1025static void do_pf_write( void )
1026
1027{	ps_set_intr(do_pf_write_start,0,0,nice);
1028}
1029
1030static void do_pf_write_start( void )
1031
1032{       int	unit = pf_unit;
1033	unsigned long	saved_flags;
1034
1035	pf_busy = 1;
1036
1037	if (pf_start(unit,ATAPI_WRITE_10,pf_block,pf_run)) {
1038                pi_disconnect(PI);
1039                if (pf_retries < PF_MAX_RETRIES) {
1040                        pf_retries++;
1041                        pi_do_claimed(PI,do_pf_write_start);
1042			return;
1043                }
1044		spin_lock_irqsave(&io_request_lock,saved_flags);
1045                end_request(0);
1046                pf_busy = 0;
1047		do_pf_request(NULL);
1048		spin_unlock_irqrestore(&io_request_lock,saved_flags);
1049                return;
1050        }
1051
1052	while (1) {
1053            if (pf_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR,
1054			"write block","data wait") & STAT_ERR) {
1055                pi_disconnect(PI);
1056                if (pf_retries < PF_MAX_RETRIES) {
1057                        pf_retries++;
1058                        pi_do_claimed(PI,do_pf_write_start);
1059                        return;
1060                }
1061		spin_lock_irqsave(&io_request_lock,saved_flags);
1062                end_request(0);
1063                pf_busy = 0;
1064		do_pf_request(NULL);
1065		spin_unlock_irqrestore(&io_request_lock,saved_flags);
1066                return;
1067            }
1068            pi_write_block(PI,pf_buf,512);
1069	    pf_count--; pf_run--;
1070	    pf_buf += 512;
1071	    pf_block++;
1072	    if (!pf_run) break;
1073	    if (!pf_count) pf_next_buf(unit);
1074	}
1075	pf_mask = 0;
1076        ps_set_intr(do_pf_write_done,pf_ready,PF_TMO,nice);
1077}
1078
1079static void do_pf_write_done( void )
1080
1081{       int	unit = pf_unit;
1082	unsigned long	saved_flags;
1083
1084        if (pf_wait(unit,STAT_BUSY,0,"write block","done") & STAT_ERR) {
1085                pi_disconnect(PI);
1086                if (pf_retries < PF_MAX_RETRIES) {
1087                        pf_retries++;
1088			pi_do_claimed(PI,do_pf_write_start);
1089                        return;
1090                }
1091		spin_lock_irqsave(&io_request_lock,saved_flags);
1092                end_request(0);
1093                pf_busy = 0;
1094		do_pf_request(NULL);
1095		spin_unlock_irqrestore(&io_request_lock,saved_flags);
1096                return;
1097        }
1098        pi_disconnect(PI);
1099	spin_lock_irqsave(&io_request_lock,saved_flags);
1100        end_request(1);
1101        pf_busy = 0;
1102	do_pf_request(NULL);
1103	spin_unlock_irqrestore(&io_request_lock,saved_flags);
1104}
1105
1106/* end of pf.c */
1107
1108MODULE_LICENSE("GPL");
1109