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 
127 static int	verbose = 0;
128 static int	major = PF_MAJOR;
129 static char	*name = PF_NAME;
130 static int      cluster = 64;
131 static int      nice = 0;
132 static int      disable = 0;
133 
134 static int drive0[7] = {0,0,0,-1,-1,-1,-1};
135 static int drive1[7] = {0,0,0,-1,-1,-1,-1};
136 static int drive2[7] = {0,0,0,-1,-1,-1,-1};
137 static int drive3[7] = {0,0,0,-1,-1,-1,-1};
138 
139 static int (*drives[4])[7] = {&drive0,&drive1,&drive2,&drive3};
140 static 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 
171 static 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 
pf_setup(char * str,int * ints)179 void pf_setup( char *str, int *ints)
180 
181 {       generic_setup(pf_stt,7,str);
182 }
183 
184 #endif
185 
186 MODULE_PARM(verbose,"i");
187 MODULE_PARM(major,"i");
188 MODULE_PARM(name,"s");
189 MODULE_PARM(cluster,"i");
190 MODULE_PARM(nice,"i");
191 MODULE_PARM(drive0,"1-7i");
192 MODULE_PARM(drive1,"1-7i");
193 MODULE_PARM(drive2,"1-7i");
194 MODULE_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 
244 int pf_init(void);
245 #ifdef MODULE
246 void cleanup_module( void );
247 #endif
248 static int pf_open(struct inode *inode, struct file *file);
249 static void do_pf_request(request_queue_t * q);
250 static int pf_ioctl(struct inode *inode,struct file *file,
251                     unsigned int cmd, unsigned long arg);
252 
253 static int pf_release (struct inode *inode, struct file *file);
254 
255 static int pf_detect(void);
256 static void do_pf_read(void);
257 static void do_pf_read_start(void);
258 static void do_pf_write(void);
259 static void do_pf_write_start(void);
260 static void do_pf_read_drq( void );
261 static void do_pf_write_done( void );
262 
263 static int pf_identify (int unit);
264 static void pf_lock(int unit, int func);
265 static void pf_eject(int unit);
266 static int pf_check_media(kdev_t dev);
267 
268 static 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 
276 struct 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 
289 struct 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 
296 static 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 
302 static int pf_retries = 0;              /* i/o error retry count */
303 static int pf_busy = 0;                 /* request being processed ? */
304 static int pf_block;                    /* address of next requested block */
305 static int pf_count;                    /* number of blocks still to do */
306 static int pf_run;			/* sectors in current cluster */
307 static int pf_cmd;			/* current command READ/WRITE */
308 static int pf_unit;			/* unit of current request */
309 static int pf_mask;			/* stopper for pseudo-int */
310 static char * pf_buf;                   /* buffer for request in progress */
311 
312 /* kernel glue structures */
313 
314 static 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 
pf_init_units(void)322 void 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 
pf_new_segment(request_queue_t * q,struct request * req,int max_segments)343 static 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 
pf_back_merge_fn(request_queue_t * q,struct request * req,struct buffer_head * bh,int max_segments)355 static 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 
pf_front_merge_fn(request_queue_t * q,struct request * req,struct buffer_head * bh,int max_segments)363 static 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 
pf_merge_requests_fn(request_queue_t * q,struct request * req,struct request * next,int max_segments)371 static 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 
pf_init(void)393 int 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 
pf_open(struct inode * inode,struct file * file)425 static 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 
pf_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)445 static 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 
pf_release(struct inode * inode,struct file * file)495 static 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 
pf_check_media(kdev_t dev)515 static int pf_check_media( kdev_t dev)
516 
517 {       return 1;
518 }
519 
520 #ifdef MODULE
521 
522 /* Glue for modules ... */
523 
524 void    cleanup_module(void);
525 
init_module(void)526 int     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 
cleanup_module(void)541 void    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 
pf_wait(int unit,int go,int stop,char * fun,char * msg)559 static 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 
pf_command(int unit,char * cmd,int dlen,char * fun)580 static 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 
pf_completion(int unit,char * buf,char * fun)611 static 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 
pf_req_sense(int unit,int quiet)630 static 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 
pf_atapi(int unit,char * cmd,int dlen,char * buf,char * fun)645 static 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 
pf_lock(int unit,int func)659 static 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 
pf_eject(int unit)667 static 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 
pf_sleep(int cs)677 static void pf_sleep( int cs )
678 
679 {       current->state = TASK_INTERRUPTIBLE;
680         schedule_timeout(cs);
681 }
682 
683 
pf_reset(int unit)684 static 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 
pf_mode_sense(int unit)718 static 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 
xs(char * buf,char * targ,int offs,int len)728 static 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 
xl(char * buf,int offs)740 static 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 
pf_get_capacity(int unit)749 static 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 
pf_identify(int unit)769 static 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 
pf_probe(int unit)811 static 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 
pf_detect(void)833 static 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 
pf_start(int unit,int cmd,int b,int c)869 static 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 
pf_ready(void)889 static int pf_ready( void )
890 
891 {	int	unit = pf_unit;
892 
893 	return (((RR(1,6)&(STAT_BUSY|pf_mask)) == pf_mask));
894 }
895 
do_pf_request(request_queue_t * q)896 static void do_pf_request (request_queue_t * q)
897 
898 {       struct buffer_head * bh;
899 	int unit;
900 
901         if (pf_busy) return;
902 repeat:
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 
pf_next_buf(int unit)931 static 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 
do_pf_read(void)956 static 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 
do_pf_read_start(void)963 static 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 
do_pf_read_drq(void)988 static 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 
do_pf_write(void)1025 static void do_pf_write( void )
1026 
1027 {	ps_set_intr(do_pf_write_start,0,0,nice);
1028 }
1029 
do_pf_write_start(void)1030 static 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 
do_pf_write_done(void)1079 static 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 
1108 MODULE_LICENSE("GPL");
1109