2 pf.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU public license.
5 This is the high-level driver for parallel port ATAPI disk
6 drives based on chips supported by the paride module.
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.
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:
16 drive0 These four arguments can be arrays of
17 drive1 1-7 integers as follows:
19 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<lun>,<dly>
23 <prt> is the base of the parallel port address for
24 the corresponding drive. (required)
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)
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.
37 <mod> this can be -1 to choose the best mode, or one
38 of the mode numbers supported by the adapter.
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
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
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)
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
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).
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.
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
84 nice This parameter controls the driver's use of
85 idle CPU time, at the expense of some speed.
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:
98 In addition, you can use the parameter pf.disable to disable
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
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
116 #define PF_VERSION "1.04"
121 /* Here are things one can override from the insmod command.
122 Most are autoprobed by paride unless set here. Verbose is off
127 static int verbose
= 0;
128 static int major
= PF_MAJOR
;
129 static char *name
= PF_NAME
;
130 static int cluster
= 64;
132 static int disable
= 0;
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};
139 static int (*drives
[4])[7] = {&drive0
,&drive1
,&drive2
,&drive3
};
140 static int pf_drive_count
;
150 #define DU (*drives[unit])
152 /* end of parameters */
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>
165 #include <asm/uaccess.h>
171 static STT pf_stt
[7] = {{"drive0",7,drive0
},
175 {"disable",1,&disable
},
176 {"cluster",1,&cluster
},
179 void pf_setup( char *str
, int *ints
)
181 { generic_setup(pf_stt
,7,str
);
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");
198 /* set up defines for blk.h, why don't all drivers do it this way ? */
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)
207 #include <linux/blk.h>
208 #include <linux/blkpg.h>
212 /* constants for faking geometry numbers */
214 #define PF_FD_MAX 8192 /* use FD geometry under this size */
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 */
224 #define PF_SPIN (1000000*PF_TMO)/(HZ*PF_SPIN_DEL)
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
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
246 void cleanup_module( void );
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
);
253 static int pf_release (struct inode
*inode
, struct file
*file
);
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 );
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
);
268 static int pf_blocksizes
[PF_UNITS
];
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 */
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, ... */
289 struct pf_unit pf
[PF_UNITS
];
291 /* 'unit' must be defined in all functions - either as a local or a param */
296 static char pf_scratch
[512]; /* scratch block buffer */
298 /* the variables below are used mainly in the I/O request engine, which
299 processes only one request at a time.
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 */
312 /* kernel glue structures */
314 static struct block_device_operations pf_fops
= {
318 check_media_change
: pf_check_media
,
321 void pf_init_units( void )
326 for (unit
=0;unit
<PF_UNITS
;unit
++) {
329 PF
.media_status
= PF_NM
;
332 PF
.drive
= DU
[D_SLV
];
335 while ((j
< PF_NAMELEN
-2) && (PF
.name
[j
]=name
[j
])) j
++;
336 PF
.name
[j
++] = '0' + unit
;
338 if (DU
[D_PRT
]) pf_drive_count
++;
342 int pf_init (void) /* preliminary initialisation */
346 if (disable
) return -1;
350 if (pf_detect()) return -1;
353 if (register_blkdev(MAJOR_NR
,name
,&pf_fops
)) {
354 printk("pf_init: unable to get major number %d\n",
358 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR
), DEVICE_REQUEST
);
359 read_ahead
[MAJOR_NR
] = 8; /* 8 sector (4kB) read ahead */
361 for (i
=0;i
<PF_UNITS
;i
++) pf_blocksizes
[i
] = 1024;
362 blksize_size
[MAJOR_NR
] = pf_blocksizes
;
367 static int pf_open (struct inode
*inode
, struct file
*file
)
369 { int unit
= DEVICE_NR(inode
->i_rdev
);
371 if ((unit
>= PF_UNITS
) || (!PF
.present
)) return -ENODEV
;
377 if (PF
.media_status
== PF_NM
) {
382 if ((PF
.media_status
== PF_RO
) && (file
->f_mode
& 2)) {
388 if (PF
.removable
) pf_lock(unit
,1);
393 static int pf_ioctl(struct inode
*inode
,struct file
*file
,
394 unsigned int cmd
, unsigned long arg
)
397 struct hd_geometry
*geo
= (struct hd_geometry
*) arg
;
399 if ((!inode
) || (!inode
->i_rdev
)) return -EINVAL
;
400 unit
= DEVICE_NR(inode
->i_rdev
);
401 if (unit
>= PF_UNITS
) return -EINVAL
;
402 if (!PF
.present
) return -ENODEV
;
406 if (PF
.access
== 1) {
411 if (!geo
) return -EINVAL
;
412 err
= verify_area(VERIFY_WRITE
,geo
,sizeof(*geo
));
414 if (PF
.capacity
< PF_FD_MAX
) {
415 put_user(PF
.capacity
/(PF_FD_HDS
*PF_FD_SPT
),
416 (short *) &geo
->cylinders
);
417 put_user(PF_FD_HDS
, (char *) &geo
->heads
);
418 put_user(PF_FD_SPT
, (char *) &geo
->sectors
);
420 put_user(PF
.capacity
/(PF_HD_HDS
*PF_HD_SPT
),
421 (short *) &geo
->cylinders
);
422 put_user(PF_HD_HDS
, (char *) &geo
->heads
);
423 put_user(PF_HD_SPT
, (char *) &geo
->sectors
);
425 put_user(0,(long *)&geo
->start
);
428 if (!arg
) return -EINVAL
;
429 err
= verify_area(VERIFY_WRITE
,(long *) arg
,sizeof(long));
430 if (err
) return (err
);
431 put_user(PF
.capacity
,(long *) arg
);
438 return blk_ioctl(inode
->i_rdev
, cmd
, arg
);
445 static int pf_release (struct inode
*inode
, struct file
*file
)
450 devp
= inode
->i_rdev
;
451 unit
= DEVICE_NR(devp
);
453 if ((unit
>= PF_UNITS
) || (PF
.access
<= 0))
458 if (!PF
.access
&& PF
.removable
)
467 static int pf_check_media( kdev_t dev
)
474 /* Glue for modules ... */
476 void cleanup_module(void);
478 int init_module(void)
483 { extern paride_init();
493 void cleanup_module(void)
497 unregister_blkdev(MAJOR_NR
,name
);
499 for (unit
=0;unit
<PF_UNITS
;unit
++)
500 if (PF
.present
) pi_release(PI
);
505 #define WR(c,r,v) pi_write_regr(PI,c,r,v)
506 #define RR(c,r) (pi_read_regr(PI,c,r))
508 #define LUN (0x20*PF.lun)
509 #define DRIVE (0xa0+0x10*PF.drive)
511 static int pf_wait( int unit
, int go
, int stop
, char * fun
, char * msg
)
516 while ((((r
=RR(1,6))&go
)||(stop
&&(!(r
&stop
))))&&(j
++<PF_SPIN
))
519 if ((r
&(STAT_ERR
&stop
))||(j
>=PF_SPIN
)) {
523 if (j
>= PF_SPIN
) e
|= 0x100;
524 if (fun
) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
525 " loop=%d phase=%d\n",
526 PF
.name
,fun
,msg
,r
,s
,e
,j
,p
);
532 static int pf_command( int unit
, char * cmd
, int dlen
, char * fun
)
538 if (pf_wait(unit
,STAT_BUSY
|STAT_DRQ
,0,fun
,"before command")) {
545 WR(0,7,0xa0); /* ATAPI packet command */
547 if (pf_wait(unit
,STAT_BUSY
,STAT_DRQ
,fun
,"command DRQ")) {
553 printk("%s: %s: command phase error\n",PF
.name
,fun
);
558 pi_write_block(PI
,cmd
,12);
563 static int pf_completion( int unit
, char * buf
, char * fun
)
567 r
= pf_wait(unit
,STAT_BUSY
,STAT_DRQ
|STAT_READY
|STAT_ERR
,
570 if ((RR(0,2)&2) && (RR(0,7)&STAT_DRQ
)) {
571 n
= (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
572 pi_read_block(PI
,buf
,n
);
575 s
= pf_wait(unit
,STAT_BUSY
,STAT_READY
|STAT_ERR
,fun
,"data done");
582 static void pf_req_sense( int unit
, int quiet
)
584 { char rs_cmd
[12] = { ATAPI_REQ_SENSE
,LUN
,0,0,16,0,0,0,0,0,0,0 };
588 r
= pf_command(unit
,rs_cmd
,16,"Request sense");
590 if (!r
) pf_completion(unit
,buf
,"Request sense");
593 printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
594 PF
.name
,buf
[2]&0xf,buf
[12],buf
[13]);
597 static int pf_atapi( int unit
, char * cmd
, int dlen
, char * buf
, char * fun
)
601 r
= pf_command(unit
,cmd
,dlen
,fun
);
603 if (!r
) r
= pf_completion(unit
,buf
,fun
);
604 if (r
) pf_req_sense(unit
,!fun
);
609 #define DBMSG(msg) ((verbose>1)?(msg):NULL)
611 static void pf_lock(int unit
, int func
)
613 { char lo_cmd
[12] = { ATAPI_LOCK
,LUN
,0,0,func
,0,0,0,0,0,0,0 };
615 pf_atapi(unit
,lo_cmd
,0,pf_scratch
,func
?"unlock":"lock");
619 static void pf_eject( int unit
)
621 { char ej_cmd
[12] = { ATAPI_DOOR
,LUN
,0,0,2,0,0,0,0,0,0,0 };
624 pf_atapi(unit
,ej_cmd
,0,pf_scratch
,"eject");
627 #define PF_RESET_TMO 30 /* in tenths of a second */
629 static void pf_sleep( int cs
)
631 { current
->state
= TASK_INTERRUPTIBLE
;
632 schedule_timeout(cs
);
636 static int pf_reset( int unit
)
638 /* the ATAPI standard actually specifies the contents of all 7 registers
639 after a reset, but the specification is ambiguous concerning the last
640 two bytes, and different drives interpret the standard differently.
644 int expect
[5] = {1,1,1,0x14,0xeb};
650 pf_sleep(20*HZ
/1000);
653 while ((k
++ < PF_RESET_TMO
) && (RR(1,6)&STAT_BUSY
))
657 for(i
=0;i
<5;i
++) flg
&= (RR(0,i
+1) == expect
[i
]);
660 printk("%s: Reset (%d) signature = ",PF
.name
,k
);
661 for (i
=0;i
<5;i
++) printk("%3x",RR(0,i
+1));
662 if (!flg
) printk(" (incorrect)");
670 static void pf_mode_sense( int unit
)
672 { char ms_cmd
[12] = { ATAPI_MODE_SENSE
,LUN
,0,0,0,0,0,0,8,0,0,0};
675 pf_atapi(unit
,ms_cmd
,8,buf
,DBMSG("mode sense"));
676 PF
.media_status
= PF_RW
;
677 if (buf
[3] & 0x80) PF
.media_status
= PF_RO
;
680 static void xs( char *buf
, char *targ
, int offs
, int len
)
686 if((buf
[k
+offs
]!=0x20)||(buf
[k
+offs
]!=l
))
687 l
=targ
[j
++]=buf
[k
+offs
];
688 if (l
==0x20) j
--; targ
[j
]=0;
691 static int xl( char *buf
, int offs
)
696 for(k
=0;k
<4;k
++) v
=v
*256+(buf
[k
+offs
]&0xff);
700 static void pf_get_capacity( int unit
)
702 { char rc_cmd
[12] = { ATAPI_CAPACITY
,LUN
,0,0,0,0,0,0,0,0,0,0};
706 if (pf_atapi(unit
,rc_cmd
,8,buf
,DBMSG("get capacity"))) {
707 PF
.media_status
= PF_NM
;
710 PF
.capacity
= xl(buf
,0) + 1;
714 if (verbose
) printk("%s: Drive %d, LUN %d,"
715 " unsupported block size %d\n",
716 PF
.name
,PF
.drive
,PF
.lun
,bs
);
720 static int pf_identify( int unit
)
723 char *ms
[2] = {"master","slave"};
725 char id_cmd
[12] = { ATAPI_IDENTIFY
,LUN
,0,0,36,0,0,0,0,0,0,0};
728 s
= pf_atapi(unit
,id_cmd
,36,buf
,"identify");
732 if ((dt
!= 0) && (dt
!= 7)) {
734 printk("%s: Drive %d, LUN %d, unsupported type %d\n",
735 PF
.name
,PF
.drive
,PF
.lun
,dt
);
742 PF
.removable
= (buf
[1] & 0x80);
748 pf_get_capacity(unit
);
750 printk("%s: %s %s, %s LUN %d, type %d",
751 PF
.name
,mf
,id
,ms
[PF
.drive
],PF
.lun
,dt
);
752 if (PF
.removable
) printk(", removable");
753 if (PF
.media_status
== PF_NM
)
754 printk(", no media\n");
755 else { if (PF
.media_status
== PF_RO
) printk(", RO");
756 printk(", %d blocks\n",PF
.capacity
);
762 static int pf_probe( int unit
)
764 /* returns 0, with id set if drive is detected
765 -1, if drive detection failed
768 { if (PF
.drive
== -1) {
769 for (PF
.drive
=0;PF
.drive
<=1;PF
.drive
++)
770 if (!pf_reset(unit
)) {
771 if (PF
.lun
!= -1) return pf_identify(unit
);
772 else for (PF
.lun
=0;PF
.lun
<8;PF
.lun
++)
773 if (!pf_identify(unit
)) return 0;
776 if (pf_reset(unit
)) return -1;
777 if (PF
.lun
!= -1) return pf_identify(unit
);
778 for (PF
.lun
=0;PF
.lun
<8;PF
.lun
++)
779 if (!pf_identify(unit
)) return 0;
784 static int pf_detect( void )
788 printk("%s: %s version %s, major %d, cluster %d, nice %d\n",
789 name
,name
,PF_VERSION
,major
,cluster
,nice
);
792 if (pf_drive_count
== 0) {
794 if (pi_init(PI
,1,-1,-1,-1,-1,-1,pf_scratch
,
795 PI_PF
,verbose
,PF
.name
)) {
796 if (!pf_probe(unit
)) {
799 } else pi_release(PI
);
802 } else for (unit
=0;unit
<PF_UNITS
;unit
++) if (DU
[D_PRT
])
803 if (pi_init(PI
,0,DU
[D_PRT
],DU
[D_MOD
],DU
[D_UNI
],
804 DU
[D_PRO
],DU
[D_DLY
],pf_scratch
,PI_PF
,verbose
,
806 if (!pf_probe(unit
)) {
809 } else pi_release(PI
);
814 printk("%s: No ATAPI disk detected\n",name
);
818 /* The i/o request engine */
820 static int pf_start( int unit
, int cmd
, int b
, int c
)
823 char io_cmd
[12] = {cmd
,LUN
,0,0,0,0,0,0,0,0,0,0};
826 io_cmd
[5-i
] = b
& 0xff;
830 io_cmd
[8] = c
& 0xff;
831 io_cmd
[7] = (c
>> 8) & 0xff;
833 i
= pf_command(unit
,io_cmd
,c
*512,"start i/o");
840 static int pf_ready( void )
842 { int unit
= pf_unit
;
844 return (((RR(1,6)&(STAT_BUSY
|pf_mask
)) == pf_mask
));
847 static void do_pf_request (request_queue_t
* q
)
849 { struct buffer_head
* bh
;
850 struct request
* req
;
855 if ((!CURRENT
) || (CURRENT
->rq_status
== RQ_INACTIVE
)) return;
858 pf_unit
= unit
= DEVICE_NR(CURRENT
->rq_dev
);
859 pf_block
= CURRENT
->sector
;
860 pf_count
= CURRENT
->nr_sectors
;
865 printk("%s: OUCH: b_reqnext != NULL\n",PF
.name
);
867 if ((pf_unit
>= PF_UNITS
) || (pf_block
+pf_count
> PF
.capacity
)) {
872 pf_cmd
= CURRENT
->cmd
;
874 while ((pf_run
<= cluster
) &&
876 (pf_block
+pf_run
== req
->sector
) &&
877 (pf_cmd
== req
->cmd
) &&
878 (pf_unit
== DEVICE_NR(req
->rq_dev
)))
879 pf_run
+= req
->nr_sectors
;
881 pf_buf
= CURRENT
->buffer
;
885 if (pf_cmd
== READ
) pi_do_claimed(PI
,do_pf_read
);
886 else if (pf_cmd
== WRITE
) pi_do_claimed(PI
,do_pf_write
);
893 static void pf_next_buf( int unit
)
897 spin_lock_irqsave(&io_request_lock
,saved_flags
);
899 if (!pf_run
) { spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
906 (CURRENT
->cmd
!= pf_cmd
) ||
907 (DEVICE_NR(CURRENT
->rq_dev
) != pf_unit
) ||
908 (CURRENT
->rq_status
== RQ_INACTIVE
) ||
909 (CURRENT
->sector
!= pf_block
))
910 printk("%s: OUCH: request list changed unexpectedly\n",
913 pf_count
= CURRENT
->nr_sectors
;
914 pf_buf
= CURRENT
->buffer
;
915 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
918 static void do_pf_read( void )
920 /* detach from the calling context - in case the spinlock is held */
922 { ps_set_intr(do_pf_read_start
,0,0,nice
);
925 static void do_pf_read_start( void )
927 { int unit
= pf_unit
;
932 if (pf_start(unit
,ATAPI_READ_10
,pf_block
,pf_run
)) {
934 if (pf_retries
< PF_MAX_RETRIES
) {
936 pi_do_claimed(PI
,do_pf_read_start
);
939 spin_lock_irqsave(&io_request_lock
,saved_flags
);
943 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
947 ps_set_intr(do_pf_read_drq
,pf_ready
,PF_TMO
,nice
);
950 static void do_pf_read_drq( void )
952 { int unit
= pf_unit
;
956 if (pf_wait(unit
,STAT_BUSY
,STAT_DRQ
|STAT_ERR
,
957 "read block","completion") & STAT_ERR
) {
959 if (pf_retries
< PF_MAX_RETRIES
) {
960 pf_req_sense(unit
,0);
962 pi_do_claimed(PI
,do_pf_read_start
);
965 spin_lock_irqsave(&io_request_lock
,saved_flags
);
969 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
972 pi_read_block(PI
,pf_buf
,512);
973 pf_count
--; pf_run
--;
977 if (!pf_count
) pf_next_buf(unit
);
980 spin_lock_irqsave(&io_request_lock
,saved_flags
);
984 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
987 static void do_pf_write( void )
989 { ps_set_intr(do_pf_write_start
,0,0,nice
);
992 static void do_pf_write_start( void )
994 { int unit
= pf_unit
;
999 if (pf_start(unit
,ATAPI_WRITE_10
,pf_block
,pf_run
)) {
1001 if (pf_retries
< PF_MAX_RETRIES
) {
1003 pi_do_claimed(PI
,do_pf_write_start
);
1006 spin_lock_irqsave(&io_request_lock
,saved_flags
);
1009 do_pf_request(NULL
);
1010 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
1015 if (pf_wait(unit
,STAT_BUSY
,STAT_DRQ
|STAT_ERR
,
1016 "write block","data wait") & STAT_ERR
) {
1018 if (pf_retries
< PF_MAX_RETRIES
) {
1020 pi_do_claimed(PI
,do_pf_write_start
);
1023 spin_lock_irqsave(&io_request_lock
,saved_flags
);
1026 do_pf_request(NULL
);
1027 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
1030 pi_write_block(PI
,pf_buf
,512);
1031 pf_count
--; pf_run
--;
1035 if (!pf_count
) pf_next_buf(unit
);
1038 ps_set_intr(do_pf_write_done
,pf_ready
,PF_TMO
,nice
);
1041 static void do_pf_write_done( void )
1043 { int unit
= pf_unit
;
1046 if (pf_wait(unit
,STAT_BUSY
,0,"write block","done") & STAT_ERR
) {
1048 if (pf_retries
< PF_MAX_RETRIES
) {
1050 pi_do_claimed(PI
,do_pf_write_start
);
1053 spin_lock_irqsave(&io_request_lock
,saved_flags
);
1056 do_pf_request(NULL
);
1057 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);
1061 spin_lock_irqsave(&io_request_lock
,saved_flags
);
1064 do_pf_request(NULL
);
1065 spin_unlock_irqrestore(&io_request_lock
,saved_flags
);