1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
122
123
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
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
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
213
214#define PF_FD_MAX 8192
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
222#define PF_SPIN_DEL 50
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;
278 struct pi_adapter *pi;
279 int removable;
280 int media_status;
281 int drive;
282 int lun;
283 int access;
284 int capacity;
285 int present;
286 char name[PF_NAMELEN];
287 };
288
289struct pf_unit pf[PF_UNITS];
290
291
292
293#define PF pf[unit]
294#define PI PF.pi
295
296static char pf_scratch[512];
297
298
299
300
301
302static int pf_retries = 0;
303static int pf_busy = 0;
304static int pf_block;
305static int pf_count;
306static int pf_run;
307static int pf_cmd;
308static int pf_unit;
309static int pf_mask;
310static char * pf_buf;
311
312
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)
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;
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
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);
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
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
687
688
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
814
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
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
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
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
1107
1108MODULE_LICENSE("GPL");
1109