Import 2.1.118
[davej-history.git] / drivers / block / paride / pt.c
blob44c4dadfbe6ebe150537f1b33763034cf8e5dc5c
1 /*
2 pt.c (c) 1998 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 tape
6 drives based on chips supported by the paride module.
8 The driver implements both rewinding and non-rewinding
9 devices, filemarks, and the rewind ioctl. It allocates
10 a small internal "bounce buffer" for each open device, but
11 otherwise expects buffering and blocking to be done at the
12 user level. As with most block-structured tapes, short
13 writes are padded to full tape blocks, so reading back a file
14 may return more data than was actually written.
16 By default, the driver will autoprobe for a single parallel
17 port ATAPI tape drive, but if their individual parameters are
18 specified, the driver can handle up to 4 drives.
20 The rewinding devices are named /dev/pt0, /dev/pt1, ...
21 while the non-rewinding devices are /dev/npt0, /dev/npt1, etc.
23 The behaviour of the pt driver can be altered by setting
24 some parameters from the insmod command line. The following
25 parameters are adjustable:
27 drive0 These four arguments can be arrays of
28 drive1 1-6 integers as follows:
29 drive2
30 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
32 Where,
34 <prt> is the base of the parallel port address for
35 the corresponding drive. (required)
37 <pro> is the protocol number for the adapter that
38 supports this drive. These numbers are
39 logged by 'paride' when the protocol modules
40 are initialised. (0 if not given)
42 <uni> for those adapters that support chained
43 devices, this is the unit selector for the
44 chain of devices on the given port. It should
45 be zero for devices that don't support chaining.
46 (0 if not given)
48 <mod> this can be -1 to choose the best mode, or one
49 of the mode numbers supported by the adapter.
50 (-1 if not given)
52 <slv> ATAPI devices can be jumpered to master or slave.
53 Set this to 0 to choose the master drive, 1 to
54 choose the slave, -1 (the default) to choose the
55 first drive found.
57 <dly> some parallel ports require the driver to
58 go more slowly. -1 sets a default value that
59 should work with the chosen protocol. Otherwise,
60 set this to a small integer, the larger it is
61 the slower the port i/o. In some cases, setting
62 this to zero will speed up the device. (default -1)
64 major You may use this parameter to overide the
65 default major number (96) that this driver
66 will use. Be sure to change the device
67 name as well.
69 name This parameter is a character string that
70 contains the name the kernel will use for this
71 device (in /proc output, for instance).
72 (default "pt").
74 verbose This parameter controls the amount of logging
75 that the driver will do. Set it to 0 for
76 normal operation, 1 to see autoprobe progress
77 messages, or 2 to see additional debugging
78 output. (default 0)
80 If this driver is built into the kernel, you can use
81 the following command line parameters, with the same values
82 as the corresponding module parameters listed above:
84 pt.drive0
85 pt.drive1
86 pt.drive2
87 pt.drive3
89 In addition, you can use the parameter pt.disable to disable
90 the driver entirely.
94 /* Changes:
96 1.01 GRG 1998.05.06 Round up transfer size, fix ready_wait,
97 loosed interpretation of ATAPI standard
98 for clearing error status.
99 Eliminate sti();
100 1.02 GRG 1998.06.16 Eliminate an Ugh.
101 1.03 GRG 1998.08.15 Adjusted PT_TMO, use HZ in loop timing,
102 extra debugging
106 #define PT_VERSION "1.03"
107 #define PT_MAJOR 96
108 #define PT_NAME "pt"
109 #define PT_UNITS 4
111 /* Here are things one can override from the insmod command.
112 Most are autoprobed by paride unless set here. Verbose is on
113 by default.
117 static int verbose = 0;
118 static int major = PT_MAJOR;
119 static char *name = PT_NAME;
120 static int disable = 0;
122 static int drive0[6] = {0,0,0,-1,-1,-1};
123 static int drive1[6] = {0,0,0,-1,-1,-1};
124 static int drive2[6] = {0,0,0,-1,-1,-1};
125 static int drive3[6] = {0,0,0,-1,-1,-1};
127 static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
128 static int pt_drive_count;
130 #define D_PRT 0
131 #define D_PRO 1
132 #define D_UNI 2
133 #define D_MOD 3
134 #define D_SLV 4
135 #define D_DLY 5
137 #define DU (*drives[unit])
139 /* end of parameters */
142 #include <linux/module.h>
143 #include <linux/errno.h>
144 #include <linux/fs.h>
145 #include <linux/kernel.h>
146 #include <linux/delay.h>
147 #include <linux/malloc.h>
148 #include <linux/mtio.h>
150 #include <asm/uaccess.h>
152 #ifndef MODULE
154 #include "setup.h"
156 static STT pt_stt[5] = {{"drive0",6,drive0},
157 {"drive1",6,drive1},
158 {"drive2",6,drive2},
159 {"drive3",6,drive3},
160 {"disable",1,&disable}};
162 void pt_setup( char *str, int *ints)
164 { generic_setup(pt_stt,5,str);
167 #endif
169 MODULE_PARM(verbose,"i");
170 MODULE_PARM(major,"i");
171 MODULE_PARM(name,"s");
172 MODULE_PARM(drive0,"1-6i");
173 MODULE_PARM(drive1,"1-6i");
174 MODULE_PARM(drive2,"1-6i");
175 MODULE_PARM(drive3,"1-6i");
177 #include "paride.h"
179 #define PT_MAX_RETRIES 5
180 #define PT_TMO 3000 /* interrupt timeout in jiffies */
181 #define PT_SPIN_DEL 50 /* spin delay in micro-seconds */
182 #define PT_RESET_TMO 30 /* 30 seconds */
183 #define PT_READY_TMO 60 /* 60 seconds */
184 #define PT_REWIND_TMO 1200 /* 20 minutes */
186 #define PT_SPIN ((1000000/(HZ*PT_SPIN_DEL))*PT_TMO)
188 #define STAT_ERR 0x00001
189 #define STAT_INDEX 0x00002
190 #define STAT_ECC 0x00004
191 #define STAT_DRQ 0x00008
192 #define STAT_SEEK 0x00010
193 #define STAT_WRERR 0x00020
194 #define STAT_READY 0x00040
195 #define STAT_BUSY 0x00080
196 #define STAT_SENSE 0x1f000
198 #define ATAPI_TEST_READY 0x00
199 #define ATAPI_REWIND 0x01
200 #define ATAPI_REQ_SENSE 0x03
201 #define ATAPI_READ_6 0x08
202 #define ATAPI_WRITE_6 0x0a
203 #define ATAPI_WFM 0x10
204 #define ATAPI_IDENTIFY 0x12
205 #define ATAPI_MODE_SENSE 0x1a
206 #define ATAPI_LOG_SENSE 0x4d
208 int pt_init(void);
209 #ifdef MODULE
210 void cleanup_module( void );
211 #endif
213 static int pt_open(struct inode *inode, struct file *file);
214 static int pt_ioctl(struct inode *inode,struct file *file,
215 unsigned int cmd, unsigned long arg);
216 static int pt_release (struct inode *inode, struct file *file);
217 static ssize_t pt_read(struct file * filp, char * buf,
218 size_t count, loff_t *ppos);
219 static ssize_t pt_write(struct file * filp, const char * buf,
220 size_t count, loff_t *ppos);
221 static int pt_detect(void);
223 static int pt_identify (int unit);
225 /* bits in PT.flags */
227 #define PT_MEDIA 1
228 #define PT_WRITE_OK 2
229 #define PT_REWIND 4
230 #define PT_WRITING 8
231 #define PT_READING 16
232 #define PT_EOF 32
234 #define PT_NAMELEN 8
235 #define PT_BUFSIZE 16384
237 struct pt_unit {
238 struct pi_adapter pia; /* interface to paride layer */
239 struct pi_adapter *pi;
240 int flags; /* various state flags */
241 int last_sense; /* result of last request sense */
242 int drive; /* drive */
243 int access; /* count of active opens ... */
244 int bs; /* block size */
245 int capacity; /* Size of tape in KB */
246 int present; /* device present ? */
247 char *bufptr;
248 char name[PT_NAMELEN]; /* pf0, pf1, ... */
251 struct pt_unit pt[PT_UNITS];
253 /* 'unit' must be defined in all functions - either as a local or a param */
255 #define PT pt[unit]
256 #define PI PT.pi
258 static char pt_scratch[512]; /* scratch block buffer */
260 /* kernel glue structures */
262 static struct file_operations pt_fops = {
263 NULL, /* lseek - default */
264 pt_read, /* read */
265 pt_write, /* write */
266 NULL, /* readdir - bad */
267 NULL, /* select */
268 pt_ioctl, /* ioctl */
269 NULL, /* mmap */
270 pt_open, /* open */
271 NULL, /* flush */
272 pt_release, /* release */
273 NULL, /* fsync */
274 NULL, /* fasync */
275 NULL, /* media change ? */
276 NULL /* revalidate new media */
279 void pt_init_units( void )
281 { int unit, j;
283 pt_drive_count = 0;
284 for (unit=0;unit<PT_UNITS;unit++) {
285 PT.pi = & PT.pia;
286 PT.access = 0;
287 PT.flags = 0;
288 PT.last_sense = 0;
289 PT.present = 0;
290 PT.bufptr = NULL;
291 PT.drive = DU[D_SLV];
292 j = 0;
293 while ((j < PT_NAMELEN-2) && (PT.name[j]=name[j])) j++;
294 PT.name[j++] = '0' + unit;
295 PT.name[j] = 0;
296 if (DU[D_PRT]) pt_drive_count++;
300 int pt_init (void) /* preliminary initialisation */
302 { int unit;
304 if (disable) return -1;
306 pt_init_units();
308 if (pt_detect()) return -1;
310 if (register_chrdev(major,name,&pt_fops)) {
311 printk("pt_init: unable to get major number %d\n",
312 major);
313 for (unit=0;unit<PT_UNITS;unit++)
314 if (PT.present) pi_release(PI);
315 return -1;
318 return 0;
321 #ifdef MODULE
323 /* Glue for modules ... */
325 void cleanup_module(void);
327 int init_module(void)
329 { int err;
331 err = pt_init();
333 return err;
336 void cleanup_module(void)
338 { int unit;
340 unregister_chrdev(major,name);
342 for (unit=0;unit<PT_UNITS;unit++)
343 if (PT.present) pi_release(PI);
346 #endif
348 #define WR(c,r,v) pi_write_regr(PI,c,r,v)
349 #define RR(c,r) (pi_read_regr(PI,c,r))
351 #define DRIVE (0xa0+0x10*PT.drive)
353 static int pt_wait( int unit, int go, int stop, char * fun, char * msg )
355 { int j, r, e, s, p;
357 j = 0;
358 while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PT_SPIN))
359 udelay(PT_SPIN_DEL);
361 if ((r&(STAT_ERR&stop))||(j>=PT_SPIN)) {
362 s = RR(0,7);
363 e = RR(0,1);
364 p = RR(0,2);
365 if (j >= PT_SPIN) e |= 0x100;
366 if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
367 " loop=%d phase=%d\n",
368 PT.name,fun,msg,r,s,e,j,p);
369 return (e<<8)+s;
371 return 0;
374 static int pt_command( int unit, char * cmd, int dlen, char * fun )
376 { pi_connect(PI);
378 WR(0,6,DRIVE);
380 if (pt_wait(unit,STAT_BUSY|STAT_DRQ,0,fun,"before command")) {
381 pi_disconnect(PI);
382 return -1;
385 WR(0,4,dlen % 256);
386 WR(0,5,dlen / 256);
387 WR(0,7,0xa0); /* ATAPI packet command */
389 if (pt_wait(unit,STAT_BUSY,STAT_DRQ,fun,"command DRQ")) {
390 pi_disconnect(PI);
391 return -1;
394 if (RR(0,2) != 1) {
395 printk("%s: %s: command phase error\n",PT.name,fun);
396 pi_disconnect(PI);
397 return -1;
400 pi_write_block(PI,cmd,12);
402 return 0;
405 static int pt_completion( int unit, char * buf, char * fun )
407 { int r, s, n, p;
409 r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_READY|STAT_ERR,
410 fun,"completion");
412 if (RR(0,7)&STAT_DRQ) {
413 n = (((RR(0,4)+256*RR(0,5))+3)&0xfffc);
414 p = RR(0,2)&3;
415 if (p == 0) pi_write_block(PI,buf,n);
416 if (p == 2) pi_read_block(PI,buf,n);
419 s = pt_wait(unit,STAT_BUSY,STAT_READY|STAT_ERR,fun,"data done");
421 pi_disconnect(PI);
423 return (r?r:s);
426 static void pt_req_sense( int unit, int quiet )
428 { char rs_cmd[12] = { ATAPI_REQ_SENSE,0,0,0,16,0,0,0,0,0,0,0 };
429 char buf[16];
430 int r;
432 r = pt_command(unit,rs_cmd,16,"Request sense");
433 mdelay(1);
434 if (!r) pt_completion(unit,buf,"Request sense");
436 PT.last_sense = -1;
437 if (!r) {
438 if (!quiet) printk("%s: Sense key: %x, ASC: %x, ASQ: %x\n",
439 PT.name,buf[2]&0xf,buf[12],buf[13]);
440 PT.last_sense = (buf[2]&0xf) | ((buf[12]&0xff)<<8)
441 | ((buf[13]&0xff)<<16) ;
445 static int pt_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
447 { int r;
449 r = pt_command(unit,cmd,dlen,fun);
450 mdelay(1);
451 if (!r) r = pt_completion(unit,buf,fun);
452 if (r) pt_req_sense(unit,!fun);
454 return r;
457 static void pt_sleep( int cs )
459 { current->state = TASK_INTERRUPTIBLE;
460 current->timeout = jiffies + cs;
461 schedule();
464 static int pt_poll_dsc( int unit, int pause, int tmo, char *msg )
466 { int k, e, s;
468 k = 0;
469 while (k < tmo) {
470 pt_sleep(pause);
471 k++;
472 pi_connect(PI);
473 WR(0,6,DRIVE);
474 s = RR(0,7);
475 e = RR(0,1);
476 pi_disconnect(PI);
477 if (s & (STAT_ERR|STAT_SEEK)) break;
479 if ((k >= tmo) || (s & STAT_ERR)) {
480 if (k >= tmo) printk("%s: %s DSC timeout\n",PT.name,msg);
481 else printk("%s: %s stat=0x%x err=0x%x\n",PT.name,msg,s,e);
482 pt_req_sense(unit,0);
483 return 0;
485 return 1;
488 static void pt_media_access_cmd( int unit, int tmo, char *cmd, char *fun)
490 { if (pt_command(unit,cmd,0,fun)) {
491 pt_req_sense(unit,0);
492 return;
494 pi_disconnect(PI);
495 pt_poll_dsc(unit,100,tmo,fun);
498 static void pt_rewind( int unit )
500 { char rw_cmd[12] = {ATAPI_REWIND,0,0,0,0,0,0,0,0,0,0,0};
502 pt_media_access_cmd(unit,PT_REWIND_TMO,rw_cmd,"rewind");
505 static void pt_write_fm( int unit )
507 { char wm_cmd[12] = {ATAPI_WFM,0,0,0,1,0,0,0,0,0,0,0};
509 pt_media_access_cmd(unit,PT_TMO,wm_cmd,"write filemark");
512 #define DBMSG(msg) ((verbose>1)?(msg):NULL)
514 static int pt_reset( int unit )
516 { int i, k, flg;
517 int expect[5] = {1,1,1,0x14,0xeb};
519 pi_connect(PI);
520 WR(0,6,DRIVE);
521 WR(0,7,8);
523 pt_sleep(2);
525 k = 0;
526 while ((k++ < PT_RESET_TMO) && (RR(1,6)&STAT_BUSY))
527 pt_sleep(10);
529 flg = 1;
530 for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
532 if (verbose) {
533 printk("%s: Reset (%d) signature = ",PT.name,k);
534 for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
535 if (!flg) printk(" (incorrect)");
536 printk("\n");
539 pi_disconnect(PI);
540 return flg-1;
543 static int pt_ready_wait( int unit, int tmo )
545 { char tr_cmd[12] = {ATAPI_TEST_READY,0,0,0,0,0,0,0,0,0,0,0};
546 int k, p;
548 k = 0;
549 while (k < tmo) {
550 PT.last_sense = 0;
551 pt_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
552 p = PT.last_sense;
553 if (!p) return 0;
554 if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
555 k++;
556 pt_sleep(100);
558 return 0x000020; /* timeout */
561 static void xs( char *buf, char *targ, int offs, int len )
563 { int j,k,l;
565 j=0; l=0;
566 for (k=0;k<len;k++)
567 if((buf[k+offs]!=0x20)||(buf[k+offs]!=l))
568 l=targ[j++]=buf[k+offs];
569 if (l==0x20) j--; targ[j]=0;
572 static int xn( char *buf, int offs, int size )
574 { int v,k;
576 v=0;
577 for(k=0;k<size;k++) v=v*256+(buf[k+offs]&0xff);
578 return v;
581 static int pt_identify( int unit )
583 { int dt, s;
584 char *ms[2] = {"master","slave"};
585 char mf[10], id[18];
586 char id_cmd[12] = { ATAPI_IDENTIFY,0,0,0,36,0,0,0,0,0,0,0};
587 char ms_cmd[12] = { ATAPI_MODE_SENSE,0,0x2a,0,128,0,0,0,0,0,0,0};
588 char ls_cmd[12] = { ATAPI_LOG_SENSE,0,0x71,0,0,0,0,0,128,0,0,0};
589 char buf[36];
591 s = pt_atapi(unit,id_cmd,36,buf,"identify");
592 if (s) return -1;
594 dt = buf[0] & 0x1f;
595 if (dt != 1) {
596 if (verbose)
597 printk("%s: Drive %d, unsupported type %d\n",
598 PT.name,PT.drive,dt);
599 return -1;
602 xs(buf,mf,8,8);
603 xs(buf,id,16,16);
605 PT.flags = 0;
606 PT.capacity = 0;
607 PT.bs = 0;
609 if (!pt_ready_wait(unit,PT_READY_TMO)) PT.flags |= PT_MEDIA;
611 if (!pt_atapi(unit,ms_cmd,36,buf,"mode sense")) {
612 if (!(buf[2] & 0x80)) PT.flags |= PT_WRITE_OK;
613 PT.bs = xn(buf,10,2);
616 if (!pt_atapi(unit,ls_cmd,36,buf,"log sense"))
617 PT.capacity = xn(buf,24,4);
619 printk("%s: %s %s, %s",
620 PT.name,mf,id,ms[PT.drive]);
621 if (!(PT.flags & PT_MEDIA))
622 printk(", no media\n");
623 else { if (!(PT.flags & PT_WRITE_OK)) printk(", RO");
624 printk(", blocksize %d, %d MB\n",
625 PT.bs,PT.capacity/1024);
628 return 0;
631 static int pt_probe( int unit )
633 /* returns 0, with id set if drive is detected
634 -1, if drive detection failed
637 { if (PT.drive == -1) {
638 for (PT.drive=0;PT.drive<=1;PT.drive++)
639 if (!pt_reset(unit)) return pt_identify(unit);
640 } else {
641 if (!pt_reset(unit)) return pt_identify(unit);
643 return -1;
646 static int pt_detect( void )
648 { int k, unit;
650 printk("%s: %s version %s, major %d\n",
651 name,name,PT_VERSION,major);
653 k = 0;
654 if (pt_drive_count == 0) {
655 unit = 0;
656 if (pi_init(PI,1,-1,-1,-1,-1,-1,pt_scratch,
657 PI_PT,verbose,PT.name)) {
658 if (!pt_probe(unit)) {
659 PT.present = 1;
660 k++;
661 } else pi_release(PI);
664 } else for (unit=0;unit<PT_UNITS;unit++) if (DU[D_PRT])
665 if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
666 DU[D_PRO],DU[D_DLY],pt_scratch,PI_PT,verbose,
667 PT.name)) {
668 if (!pt_probe(unit)) {
669 PT.present = 1;
670 k++;
671 } else pi_release(PI);
674 if (k) return 0;
676 printk("%s: No ATAPI tape drive detected\n",name);
677 return -1;
680 #define DEVICE_NR(dev) (MINOR(dev) % 128)
682 static int pt_open (struct inode *inode, struct file *file)
684 { int unit = DEVICE_NR(inode->i_rdev);
686 if ((unit >= PT_UNITS) || (!PT.present)) return -ENODEV;
688 PT.access++;
690 if (PT.access > 1) {
691 PT.access--;
692 return -EBUSY;
695 MOD_INC_USE_COUNT;
697 pt_identify(unit);
699 if (!PT.flags & PT_MEDIA) {
700 PT.access--;
701 MOD_DEC_USE_COUNT;
702 return -ENODEV;
705 if ((!PT.flags & PT_WRITE_OK) && (file ->f_mode & 2)) {
706 PT.access--;
707 MOD_DEC_USE_COUNT;
708 return -EROFS;
711 if (!(MINOR(inode->i_rdev) & 128))
712 PT.flags |= PT_REWIND;
714 PT.bufptr = kmalloc(PT_BUFSIZE,GFP_KERNEL);
715 if (PT.bufptr == NULL) {
716 PT.access--;
717 MOD_DEC_USE_COUNT;
718 printk("%s: buffer allocation failed\n",PT.name);
719 return -ENOMEM;
722 return 0;
725 static int pt_ioctl(struct inode *inode,struct file *file,
726 unsigned int cmd, unsigned long arg)
728 int unit;
729 struct mtop mtop;
731 if (!inode || !inode->i_rdev)
732 return -EINVAL;
733 unit = DEVICE_NR(inode->i_rdev);
734 if (unit >= PT_UNITS)
735 return -EINVAL;
736 if (!PT.present)
737 return -ENODEV;
739 switch (cmd) {
740 case MTIOCTOP:
741 if (copy_from_user((char *)&mtop, (char *)arg,
742 sizeof(struct mtop))) return -EFAULT;
744 switch (mtop.mt_op) {
746 case MTREW:
747 pt_rewind(unit);
748 return 0;
750 default:
751 printk("%s: Unimplemented mt_op %d\n",PT.name,
752 mtop.mt_op);
753 return -EINVAL;
756 default:
757 printk("%s: Unimplemented ioctl 0x%x\n",PT.name,cmd);
758 return -EINVAL;
764 static int pt_release (struct inode *inode, struct file *file)
766 int unit = DEVICE_NR(inode->i_rdev);
768 if ((unit >= PT_UNITS) || (PT.access <= 0))
769 return -EINVAL;
771 if (PT.flags & PT_WRITING) pt_write_fm(unit);
773 if (PT.flags & PT_REWIND) pt_rewind(unit);
775 PT.access--;
777 kfree(PT.bufptr);
778 PT.bufptr = NULL;
780 MOD_DEC_USE_COUNT;
782 return 0;
786 static ssize_t pt_read(struct file * filp, char * buf,
787 size_t count, loff_t *ppos)
789 struct inode *ino = filp->f_dentry->d_inode;
790 int unit = DEVICE_NR(ino->i_rdev);
791 char rd_cmd[12] = {ATAPI_READ_6,1,0,0,0,0,0,0,0,0,0,0};
792 int k, n, r, p, s, t, b;
794 if (!(PT.flags & (PT_READING|PT_WRITING))) {
795 PT.flags |= PT_READING;
796 if (pt_atapi(unit,rd_cmd,0,NULL,"start read-ahead"))
797 return -EIO;
798 } else if (PT.flags & PT_WRITING) return -EIO;
800 if (PT.flags & PT_EOF) return 0;
802 t = 0;
804 while (count > 0) {
806 if (!pt_poll_dsc(unit,1,PT_TMO,"read")) return -EIO;
808 n = count;
809 if (n > 32768) n = 32768; /* max per command */
810 b = (n-1+PT.bs)/PT.bs;
811 n = b*PT.bs; /* rounded up to even block */
813 rd_cmd[4] = b;
815 r = pt_command(unit,rd_cmd,n,"read");
817 mdelay(1);
819 if (r) {
820 pt_req_sense(unit,0);
821 return -EIO;
824 while (1) {
826 r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
827 DBMSG("read DRQ"),"");
829 if (r & STAT_SENSE) {
830 pi_disconnect(PI);
831 pt_req_sense(unit,0);
832 return -EIO;
835 if (r) PT.flags |= PT_EOF;
837 s = RR(0,7);
839 if (!(s & STAT_DRQ)) break;
841 n = (RR(0,4)+256*RR(0,5));
842 p = (RR(0,2)&3);
843 if (p != 2) {
844 pi_disconnect(PI);
845 printk("%s: Phase error on read: %d\n",PT.name,p);
846 return -EIO;
849 while (n > 0) {
850 k = n;
851 if (k > PT_BUFSIZE) k = PT_BUFSIZE;
852 pi_read_block(PI,PT.bufptr,k);
853 n -= k;
854 b = k;
855 if (b > count) b = count;
856 copy_to_user(buf+t,PT.bufptr,b);
857 t += b;
858 count -= b;
862 pi_disconnect(PI);
863 if (PT.flags & PT_EOF) break;
866 return t;
870 static ssize_t pt_write(struct file * filp, const char * buf,
871 size_t count, loff_t *ppos)
873 struct inode *ino = filp->f_dentry->d_inode;
874 int unit = DEVICE_NR(ino->i_rdev);
875 char wr_cmd[12] = {ATAPI_WRITE_6,1,0,0,0,0,0,0,0,0,0,0};
876 int k, n, r, p, s, t, b;
878 if (!(PT.flags & PT_WRITE_OK)) return -EROFS;
880 if (!(PT.flags & (PT_READING|PT_WRITING))) {
881 PT.flags |= PT_WRITING;
882 if (pt_atapi(unit,wr_cmd,0,NULL,"start buffer-available mode"))
883 return -EIO;
884 } else if (PT.flags&PT_READING) return -EIO;
886 if (PT.flags & PT_EOF) return -ENOSPC;
888 t = 0;
890 while (count > 0) {
892 if (!pt_poll_dsc(unit,1,PT_TMO,"write")) return -EIO;
894 n = count;
895 if (n > 32768) n = 32768; /* max per command */
896 b = (n-1+PT.bs)/PT.bs;
897 n = b*PT.bs; /* rounded up to even block */
899 wr_cmd[4] = b;
901 r = pt_command(unit,wr_cmd,n,"write");
903 mdelay(1);
905 if (r) { /* error delivering command only */
906 pt_req_sense(unit,0);
907 return -EIO;
910 while (1) {
912 r = pt_wait(unit,STAT_BUSY,STAT_DRQ|STAT_ERR|STAT_READY,
913 DBMSG("write DRQ"),NULL);
915 if (r & STAT_SENSE) {
916 pi_disconnect(PI);
917 pt_req_sense(unit,0);
918 return -EIO;
921 if (r) PT.flags |= PT_EOF;
923 s = RR(0,7);
925 if (!(s & STAT_DRQ)) break;
927 n = (RR(0,4)+256*RR(0,5));
928 p = (RR(0,2)&3);
929 if (p != 0) {
930 pi_disconnect(PI);
931 printk("%s: Phase error on write: %d \n",PT.name,p);
932 return -EIO;
935 while (n > 0) {
936 k = n;
937 if (k > PT_BUFSIZE) k = PT_BUFSIZE;
938 b = k;
939 if (b > count) b = count;
940 copy_from_user(PT.bufptr,buf+t,b);
941 pi_write_block(PI,PT.bufptr,k);
942 t += b;
943 count -= b;
944 n -= k;
948 pi_disconnect(PI);
949 if (PT.flags & PT_EOF) break;
952 return t;
955 /* end of pt.c */