File: /usr/src/linux/drivers/block/paride/pcd.c

1     /* 
2     	pcd.c	(c) 1997-8  Grant R. Guenther <grant@torque.net>
3     		            Under the terms of the GNU General Public License.
4     
5     	This is a high-level driver for parallel port ATAPI CD-ROM
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 CD-ROM drive, but if their individual parameters are
10             specified, the driver can handle up to 4 drives.
11     
12             The behaviour of the pcd 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-6 integers as follows:
18                 drive2
19                 drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<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 CD-ROMs 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                     <dly>   some parallel ports require the driver to 
47                             go more slowly.  -1 sets a default value that
48                             should work with the chosen protocol.  Otherwise,
49                             set this to a small integer, the larger it is
50                             the slower the port i/o.  In some cases, setting
51                             this to zero will speed up the device. (default -1)
52                             
53                 major       You may use this parameter to overide the
54                             default major number (46) that this driver
55                             will use.  Be sure to change the device
56                             name as well.
57     
58                 name        This parameter is a character string that
59                             contains the name the kernel will use for this
60                             device (in /proc output, for instance).
61                             (default "pcd")
62     
63                 verbose     This parameter controls the amount of logging
64                             that the driver will do.  Set it to 0 for
65                             normal operation, 1 to see autoprobe progress
66                             messages, or 2 to see additional debugging
67                             output.  (default 0)
68       
69                 nice        This parameter controls the driver's use of
70                             idle CPU time, at the expense of some speed.
71      
72     	If this driver is built into the kernel, you can use kernel
73             the following command line parameters, with the same values
74             as the corresponding module parameters listed above:
75     
76     	    pcd.drive0
77     	    pcd.drive1
78     	    pcd.drive2
79     	    pcd.drive3
80     	    pcd.nice
81     
82             In addition, you can use the parameter pcd.disable to disable
83             the driver entirely.
84     
85     */
86     
87     /* Changes:
88     
89     	1.01	GRG 1998.01.24	Added test unit ready support
90     	1.02    GRG 1998.05.06  Changes to pcd_completion, ready_wait,
91     				and loosen interpretation of ATAPI
92     			        standard for clearing error status.
93     				Use spinlocks. Eliminate sti().
94     	1.03    GRG 1998.06.16  Eliminated an Ugh
95     	1.04	GRG 1998.08.15  Added extra debugging, improvements to
96     				pcd_completion, use HZ in loop timing
97     	1.05	GRG 1998.08.16	Conformed to "Uniform CD-ROM" standard
98     	1.06    GRG 1998.08.19  Added audio ioctl support
99     	1.07    GRG 1998.09.24  Increased reset timeout, added jumbo support
100     
101     */
102     
103     #define	PCD_VERSION	"1.07"
104     #define PCD_MAJOR	46
105     #define PCD_NAME	"pcd"
106     #define PCD_UNITS	4
107     
108     /* Here are things one can override from the insmod command.
109        Most are autoprobed by paride unless set here.  Verbose is off
110        by default.
111     
112     */
113     
114     static int      verbose = 0;
115     static int      major = PCD_MAJOR;
116     static char     *name = PCD_NAME;
117     static int      nice = 0;
118     static int      disable = 0;
119     
120     static int drive0[6] = {0,0,0,-1,-1,-1};
121     static int drive1[6] = {0,0,0,-1,-1,-1};
122     static int drive2[6] = {0,0,0,-1,-1,-1};
123     static int drive3[6] = {0,0,0,-1,-1,-1};
124     
125     static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
126     static int pcd_drive_count;
127     
128     #define D_PRT   0
129     #define D_PRO   1
130     #define D_UNI   2
131     #define D_MOD   3
132     #define D_SLV   4
133     #define D_DLY   5
134     
135     #define DU              (*drives[unit])
136     
137     /* end of parameters */
138     
139     #include <linux/module.h>
140     #include <linux/errno.h>
141     #include <linux/fs.h>
142     #include <linux/kernel.h>
143     #include <linux/delay.h>
144     #include <linux/cdrom.h>
145     #include <linux/spinlock.h>
146     
147     #include <asm/uaccess.h>
148     
149     #ifndef MODULE
150     
151     #include "setup.h"
152     
153     static STT pcd_stt[6] = {{"drive0",6,drive0},
154                              {"drive1",6,drive1},
155                              {"drive2",6,drive2},
156                              {"drive3",6,drive3},
157     			 {"disable",1,&disable},
158                              {"nice",1,&nice}};
159     
160     void pcd_setup( char *str, int *ints)
161     
162     {       generic_setup(pcd_stt,6,str);
163     }
164     
165     #endif
166     
167     MODULE_PARM(verbose,"i");
168     MODULE_PARM(major,"i");
169     MODULE_PARM(name,"s");
170     MODULE_PARM(nice,"i");
171     MODULE_PARM(drive0,"1-6i");
172     MODULE_PARM(drive1,"1-6i");
173     MODULE_PARM(drive2,"1-6i");
174     MODULE_PARM(drive3,"1-6i");
175     
176     #include "paride.h"
177     
178     /* set up defines for blk.h,  why don't all drivers do it this way ? */
179     
180     #define MAJOR_NR	major
181     #define DEVICE_NAME "PCD"
182     #define DEVICE_REQUEST do_pcd_request
183     #define DEVICE_NR(device) (MINOR(device))
184     #define DEVICE_ON(device)
185     #define DEVICE_OFF(device)
186     
187     #include <linux/blk.h>
188     
189     #include "pseudo.h"
190     
191     #define PCD_RETRIES	     5
192     #define PCD_TMO		   800		/* timeout in jiffies */
193     #define PCD_DELAY           50          /* spin delay in uS */
194     #define PCD_READY_TMO	    20		/* in seconds */
195     #define PCD_RESET_TMO	   100		/* in tenths of a second */
196     
197     #define PCD_SPIN	(1000000*PCD_TMO)/(HZ*PCD_DELAY)
198     
199     #define IDE_ERR		0x01
200     #define IDE_DRQ         0x08
201     #define IDE_READY       0x40
202     #define IDE_BUSY        0x80
203     
204     int pcd_init(void);
205     void cleanup_module( void );
206     
207     static int pcd_open(struct cdrom_device_info *cdi, int purpose);
208     static void pcd_release(struct cdrom_device_info *cdi);
209     static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
210     static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr);
211     static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
212     static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
213     static int pcd_drive_reset(struct cdrom_device_info *cdi);
214     static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
215     static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
216     				unsigned int cmd, void *arg);
217     static int pcd_packet(struct cdrom_device_info *cdi,
218     				struct cdrom_generic_command *cgc);
219     
220     static int 	pcd_detect(void);
221     static void 	pcd_probe_capabilities(void);
222     static void     do_pcd_read_drq(void);
223     static void 	do_pcd_request(request_queue_t * q);
224     static void 	do_pcd_read(void);
225     
226     static int pcd_blocksizes[PCD_UNITS];
227     
228     struct pcd_unit {
229     	struct pi_adapter pia;		/* interface to paride layer */
230     	struct pi_adapter *pi;
231     	int drive;			/* master/slave */
232     	int last_sense;			/* result of last request sense */
233     	int changed;			/* media change seen */
234     	int present;			/* does this unit exist ? */
235     	char *name;			/* pcd0, pcd1, etc */
236     	struct cdrom_device_info info;	/* uniform cdrom interface */
237     	};
238     
239     struct pcd_unit pcd[PCD_UNITS];
240     
241     /*  'unit' must be defined in all functions - either as a local or a param */
242     
243     #define PCD pcd[unit]
244     #define PI PCD.pi
245     
246     static char pcd_scratch[64];
247     static char pcd_buffer[2048];           /* raw block buffer */
248     static int pcd_bufblk = -1;             /* block in buffer, in CD units,
249                                                -1 for nothing there. See also
250     					   pd_unit.
251     					 */
252     
253     /* the variables below are used mainly in the I/O request engine, which
254        processes only one request at a time.
255     */
256     
257     static int pcd_unit = -1;		/* unit of current request & bufblk */
258     static int pcd_retries;			/* retries on current request */
259     static int pcd_busy = 0;		/* request being processed ? */
260     static int pcd_sector;			/* address of next requested sector */
261     static int pcd_count;			/* number of blocks still to do */
262     static char * pcd_buf;			/* buffer for request in progress */
263     
264     static int pcd_warned = 0;		/* Have we logged a phase warning ? */
265     
266     /* kernel glue structures */
267     
268     static struct cdrom_device_ops pcd_dops = {
269     	pcd_open,
270     	pcd_release,
271     	pcd_drive_status,
272     	pcd_media_changed,
273     	pcd_tray_move,
274     	pcd_lock_door,
275     	0,			/* select speed */
276     	0,			/* select disk  */
277     	0, 			/* get last session */
278     	pcd_get_mcn,
279     	pcd_drive_reset,
280     	pcd_audio_ioctl,
281     	0,			/* dev_ioctl */
282     	CDC_CLOSE_TRAY	   |
283     	CDC_OPEN_TRAY	   |
284     	CDC_LOCK	   |
285     	CDC_MCN		   |
286     	CDC_MEDIA_CHANGED  |
287     	CDC_RESET	   |
288     	CDC_PLAY_AUDIO	   |
289     	CDC_GENERIC_PACKET |
290     	CDC_CD_R	   |
291     	CDC_CD_RW,
292     	0,
293     	pcd_packet,
294     };
295     
296     static void pcd_init_units( void )
297     
298     {       int     unit, j;
299     
300             pcd_drive_count = 0;
301             for (unit=0;unit<PCD_UNITS;unit++) {
302                     PCD.pi = & PCD.pia;
303                     PCD.present = 0;
304     		PCD.last_sense = 0;
305     		PCD.changed = 1;
306                     PCD.drive = DU[D_SLV];
307                     if (DU[D_PRT]) pcd_drive_count++;
308      
309                     j = 0;
310                     while ((j < (sizeof(PCD.info.name)-2)) && 
311     		       (PCD.info.name[j]=name[j])) j++;
312                     PCD.info.name[j++] = '0' + unit;
313                     PCD.info.name[j] = 0;
314     		PCD.name = &PCD.info.name[0];
315     
316     		PCD.info.ops = &pcd_dops;
317     		PCD.info.handle = NULL;
318     		PCD.info.dev = MKDEV(major,unit);
319     		PCD.info.speed = 0;
320     		PCD.info.capacity = 1;
321     		PCD.info.mask = 0;
322             }
323     }
324     
325     int pcd_init (void)	/* preliminary initialisation */
326     
327     {       int 	i, unit;
328     
329     	if (disable) return -1;
330     
331     	pcd_init_units();
332     
333     	if (pcd_detect()) return -1;
334     
335     	/* get the atapi capabilities page */
336     	pcd_probe_capabilities();
337     
338     	if (register_blkdev(MAJOR_NR,name,&cdrom_fops)) {
339     		printk("pcd: unable to get major number %d\n",MAJOR_NR);
340     		return -1;
341     	}
342     
343     	for (unit=0;unit<PCD_UNITS;unit++)
344     		if (PCD.present) register_cdrom(&PCD.info);
345     
346     	blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
347     	read_ahead[MAJOR_NR] = 8;	/* 8 sector (4kB) read ahead */
348     
349     	for (i=0;i<PCD_UNITS;i++) pcd_blocksizes[i] = 1024;
350             blksize_size[MAJOR_NR] = pcd_blocksizes;
351     
352     	return 0;
353     }
354     
355     static int pcd_open(struct cdrom_device_info *cdi, int purpose)
356     
357     {	int unit = DEVICE_NR(cdi->dev);
358     
359     	if  ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
360     
361     	MOD_INC_USE_COUNT;
362     
363     	return 0;
364     }
365     
366     static void pcd_release(struct cdrom_device_info *cdi)
367     
368     {	MOD_DEC_USE_COUNT;
369     }
370     
371     #ifdef MODULE
372     
373     /* Glue for modules ... */
374     
375     int	init_module(void)
376     
377     {	int	err;
378     
379     #ifdef PARIDE_JUMBO
380            { extern paride_init();
381              paride_init();
382            } 
383     #endif
384     
385     	err = pcd_init();
386     
387     	return err;
388     }
389     
390     void	cleanup_module(void)
391     
392     {	int unit;
393     	
394             for (unit=0;unit<PCD_UNITS;unit++) 
395                if (PCD.present) {
396     		pi_release(PI);
397     		unregister_cdrom(&PCD.info);
398     	   }
399     
400     	unregister_blkdev(MAJOR_NR,name);
401     }
402     
403     #endif
404     
405     #define WR(c,r,v)       pi_write_regr(PI,c,r,v)
406     #define RR(c,r)         (pi_read_regr(PI,c,r))
407     
408     static int pcd_wait( int unit, int go, int stop, char * fun, char * msg )
409     
410     {	int j, r, e, s, p;
411     
412     	j = 0;
413     	while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PCD_SPIN))
414     		udelay(PCD_DELAY);
415     
416     	if ((r&(IDE_ERR&stop))||(j>=PCD_SPIN)) {
417     	   s = RR(0,7);
418     	   e = RR(0,1);
419     	   p = RR(0,2);
420            	   if (j >= PCD_SPIN) e |= 0x100;
421                if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
422     			   " loop=%d phase=%d\n",
423     			    PCD.name,fun,msg,r,s,e,j,p);
424     	   return (s<<8)+r;
425     	}
426     	return 0;
427     }
428     
429     static int pcd_command( int unit, char * cmd, int dlen, char * fun )
430     
431     {	pi_connect(PI);
432     
433             WR(0,6,0xa0 + 0x10*PCD.drive);
434     
435     	if (pcd_wait(unit,IDE_BUSY|IDE_DRQ,0,fun,"before command")) {
436     		pi_disconnect(PI);
437     		return -1;
438     	}
439     
440             WR(0,4,dlen % 256);
441             WR(0,5,dlen / 256);
442             WR(0,7,0xa0);          /* ATAPI packet command */
443     
444             if (pcd_wait(unit,IDE_BUSY,IDE_DRQ,fun,"command DRQ")) {
445     		pi_disconnect(PI);
446     		return -1;
447     	}
448     
449             if (RR(0,2) != 1) {
450                printk("%s: %s: command phase error\n",PCD.name,fun);
451     	   pi_disconnect(PI);
452                return -1;
453             }
454     
455     	pi_write_block(PI,cmd,12);
456     
457     	return 0;
458     }
459     
460     static int pcd_completion( int unit, char * buf,  char * fun )
461     
462     {	int r, d, p, n, k, j;
463     
464     	r = -1; k = 0; j = 0;
465     
466     	if (!pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
467     						fun,"completion")) {
468     	    r = 0;
469     	    while (RR(0,7)&IDE_DRQ) {
470     	        d = (RR(0,4)+256*RR(0,5));
471     	        n = ((d+3)&0xfffc);
472     	        p = RR(0,2)&3;
473     
474     	        if ((p == 2) && (n > 0) && (j == 0)) {
475     		    pi_read_block(PI,buf,n);
476     	            if (verbose > 1) 
477     			printk("%s: %s: Read %d bytes\n",PCD.name,fun,n);
478     		    r = 0; j++;
479     	        } else {
480     		    if (verbose > 1) 
481     		        printk("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
482     					PCD.name,fun,p,d,k);
483     		    if ((verbose < 2) && !pcd_warned) {
484     	               	pcd_warned = 1;
485     			printk("%s: WARNING: ATAPI phase errors\n",PCD.name);
486     			}
487     		    mdelay(1);
488     	        } 
489     		if (k++ > PCD_TMO) {
490     			printk("%s: Stuck DRQ\n",PCD.name);
491     			break;
492     		}
493     	        if (pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
494     				fun,"completion")) { 
495     			r = -1;
496     			break;
497     		}
498     	    }
499     	}
500     	
501     	pi_disconnect(PI); 
502     
503     	return r;
504     }
505     
506     static void pcd_req_sense( int unit, char *fun )
507     
508     {	char	rs_cmd[12] = { 0x03,0,0,0,16,0,0,0,0,0,0,0 };
509     	char	buf[16];
510     	int 	r, c;
511     
512     	r = pcd_command(unit,rs_cmd,16,"Request sense");
513     	mdelay(1);
514     	if (!r) pcd_completion(unit,buf,"Request sense");
515     
516     	PCD.last_sense = -1;  c = 2;
517     	if (!r) {
518                 if (fun) printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
519     	                       PCD.name,fun,buf[2]&0xf,buf[12],buf[13]);
520     	    c = buf[2]&0xf;
521     	    PCD.last_sense = c | ((buf[12]&0xff)<<8) | ((buf[13]&0xff)<<16);
522             } 
523     	if ((c == 2) || (c == 6)) PCD.changed = 1;
524     }
525     
526     static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
527     
528     {	int r;
529     
530     	r = pcd_command(unit,cmd,dlen,fun);
531     	mdelay(1);
532     	if (!r) r = pcd_completion(unit,buf,fun);
533     	if (r) pcd_req_sense(unit,fun);
534     	
535     	return r;
536     }
537     
538     static int pcd_packet(struct cdrom_device_info *cdi,
539     				struct cdrom_generic_command *cgc)
540     {
541     	char	*un_cmd;
542     	int	unit = DEVICE_NR(cdi->dev);
543     
544     	un_cmd = cgc->cmd;
545     	return pcd_atapi(unit,un_cmd,cgc->buflen,cgc->buffer, "generic packet");
546     }
547     
548     #define DBMSG(msg)	((verbose>1)?(msg):NULL)
549     
550     static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
551     
552     {	int 	r;
553     	int	unit = DEVICE_NR(cdi->dev);
554     
555     	r = PCD.changed;
556     	PCD.changed = 0;
557     
558     	return r;    
559     }
560     
561     static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
562     
563     {	char	un_cmd[12] = { 0x1e,0,0,0,lock,0,0,0,0,0,0,0 };
564             int     unit = DEVICE_NR(cdi->dev);
565     
566     	return pcd_atapi(unit,un_cmd,0,pcd_scratch,
567     				lock?"lock door":"unlock door");
568     }
569     
570     static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
571     
572     {	char	ej_cmd[12] = { 0x1b,0,0,0,3-position,0,0,0,0,0,0,0 };
573     	int	unit = DEVICE_NR(cdi->dev);
574     
575     	return pcd_atapi(unit,ej_cmd,0,pcd_scratch,
576     				position?"eject":"close tray");
577     }
578     
579     static void pcd_sleep( int cs )
580     
581     {       current->state = TASK_INTERRUPTIBLE;
582             schedule_timeout(cs);
583     }
584     
585     static int pcd_reset( int unit )
586     
587     {	int	i, k, flg;
588     	int	expect[5] = {1,1,1,0x14,0xeb};
589     
590     	pi_connect(PI);
591     	WR(0,6,0xa0 + 0x10*PCD.drive);
592     	WR(0,7,8);
593     
594     	pcd_sleep(20*HZ/1000);  		/* delay a bit */
595     
596     	k = 0;
597     	while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
598     		pcd_sleep(HZ/10);
599     
600     	flg = 1;
601     	for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
602     
603     	if (verbose) {
604     		printk("%s: Reset (%d) signature = ",PCD.name,k);
605     		for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
606     		if (!flg) printk(" (incorrect)");
607     		printk("\n");
608     	}
609     	
610     	pi_disconnect(PI);
611     	return flg-1;	
612     }
613     
614     static int pcd_drive_reset(struct cdrom_device_info *cdi)
615     
616     {	return pcd_reset(DEVICE_NR(cdi->dev));
617     }
618     
619     static int pcd_ready_wait( int unit, int tmo )
620     
621     {       char    tr_cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
622             int     k, p;
623     
624             k = 0;
625             while (k < tmo) {
626               PCD.last_sense = 0;
627               pcd_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
628               p = PCD.last_sense;
629               if (!p) return 0;
630     	  if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
631               k++;
632               pcd_sleep(HZ);
633             }
634             return 0x000020;        /* timeout */
635     }
636     
637     static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
638     
639     {	char    rc_cmd[12] = { 0x25,0,0,0,0,0,0,0,0,0,0,0};
640     	int	unit = DEVICE_NR(cdi->dev);
641     
642     	if (pcd_ready_wait(unit,PCD_READY_TMO)) 
643     		return CDS_DRIVE_NOT_READY;
644     	if (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")))
645     		return CDS_NO_DISC;
646     	return CDS_DISC_OK;
647     }
648     
649     static int pcd_identify( int unit, char * id )
650     
651     {	int k, s;
652     	char   id_cmd[12] = {0x12,0,0,0,36,0,0,0,0,0,0,0};
653     
654     	pcd_bufblk = -1;
655     
656             s = pcd_atapi(unit,id_cmd,36,pcd_buffer,"identify");
657     
658     	if (s) return -1;
659     	if ((pcd_buffer[0] & 0x1f) != 5) {
660     	  if (verbose) printk("%s: %s is not a CD-ROM\n",
661     			PCD.name,PCD.drive?"Slave":"Master");
662     	  return -1;
663     	}
664     	for (k=0;k<16;k++) id[k] = pcd_buffer[16+k]; id[16] = 0;
665     	k = 16; while ((k >= 0) && (id[k] <= 0x20)) { id[k] = 0; k--; }
666     
667     	printk("%s: %s: %s\n",PCD.name,PCD.drive?"Slave":"Master",id);
668     
669     	return 0;
670     }
671     
672     static int pcd_probe( int unit, int ms, char * id )
673     
674     /*	returns  0, with id set if drive is detected
675     	        -1, if drive detection failed
676     */
677     
678     {	if (ms == -1) {
679                 for (PCD.drive=0;PCD.drive<=1;PCD.drive++)
680     	       if (!pcd_reset(unit) && !pcd_identify(unit,id)) 
681     		  return 0;
682     	} else {
683     	    PCD.drive = ms;
684                 if (!pcd_reset(unit) && !pcd_identify(unit,id)) 
685     		return 0;
686     	}
687     	return -1;
688     }
689     
690     static void pcd_probe_capabilities( void )
691     
692     {	int	unit, r;
693     	char	buffer[32];
694     	char 	cmd[12]={0x5a,1<<3,0x2a,0,0,0,0,18,0,0,0,0};
695     
696     	for (unit=0;unit<PCD_UNITS;unit++) {
697     		if (!PCD.present) continue;
698     		r = pcd_atapi(unit,cmd,18, buffer,"mode sense capabilities");
699     		if (r) continue;
700     		/* we should now have the cap page */
701     		if ((buffer[11] & 1) == 0)
702     			PCD.info.mask |= CDC_CD_R;
703     		if ((buffer[11] & 2) == 0)
704     			PCD.info.mask |= CDC_CD_RW;
705     		if ((buffer[12] & 1) == 0)
706     			PCD.info.mask |= CDC_PLAY_AUDIO;
707     		if ((buffer[14] & 1) == 0)
708     			PCD.info.mask |= CDC_LOCK;
709     		if ((buffer[14] & 8) == 0)
710     			PCD.info.mask |= CDC_OPEN_TRAY;
711     		if ((buffer[14] >> 6) == 0)
712     			PCD.info.mask |= CDC_CLOSE_TRAY;
713     	}
714     }
715     
716     static int pcd_detect( void )
717     
718     {	char    id[18];
719     	int	k, unit;
720     
721     	printk("%s: %s version %s, major %d, nice %d\n",
722     		name,name,PCD_VERSION,major,nice);
723     
724     	k = 0;
725     	if (pcd_drive_count == 0) {  /* nothing spec'd - so autoprobe for 1 */
726     	    unit = 0;
727     	    if (pi_init(PI,1,-1,-1,-1,-1,-1,pcd_buffer,
728                          PI_PCD,verbose,PCD.name)) {
729     		if (!pcd_probe(unit,-1,id)) {
730     			PCD.present = 1;
731     			k++;
732     		} else pi_release(PI);
733     	    }
734     
735     	} else for (unit=0;unit<PCD_UNITS;unit++) if (DU[D_PRT])
736     	    if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
737                             DU[D_PRO],DU[D_DLY],pcd_buffer,PI_PCD,verbose,
738                             PCD.name)) {
739     		if (!pcd_probe(unit,DU[D_SLV],id)) {
740                             PCD.present = 1;
741                             k++;
742                     } else pi_release(PI);
743                 }
744     
745     	if (k) return 0;
746     	
747     	printk("%s: No CD-ROM drive found\n",name);
748     	return -1;
749     }
750     
751     /* I/O request processing */
752     
753     static void do_pcd_request (request_queue_t * q)
754     
755     {       int unit;
756     
757     	if (pcd_busy) return;
758             while (1) {
759     	    if (QUEUE_EMPTY || (CURRENT->rq_status == RQ_INACTIVE)) return;
760     	    INIT_REQUEST;
761     	    if (CURRENT->cmd == READ) {
762     		unit = MINOR(CURRENT->rq_dev);
763     		if (unit != pcd_unit) {
764     			pcd_bufblk = -1;
765     			pcd_unit = unit;
766     		}
767     	        pcd_sector = CURRENT->sector;
768     	        pcd_count = CURRENT->current_nr_sectors;
769     	        pcd_buf = CURRENT->buffer;
770     		pcd_busy = 1;
771     	        ps_set_intr(do_pcd_read,0,0,nice); 
772     		return;
773     	    } 
774     	    else end_request(0);
775     	}
776     }
777     
778     static int pcd_ready( void )
779     
780     {	int	unit = pcd_unit;
781     
782     	return (((RR(1,6)&(IDE_BUSY|IDE_DRQ))==IDE_DRQ)) ;
783     }
784     
785     static void pcd_transfer( void )
786     
787     {	int	k, o;
788     
789     	while (pcd_count && (pcd_sector/4 == pcd_bufblk)) {
790     		o = (pcd_sector % 4) * 512;
791     		for(k=0;k<512;k++) pcd_buf[k] = pcd_buffer[o+k];
792     		pcd_count--;
793     		pcd_buf += 512;
794     		pcd_sector++;
795     	}
796     }
797     
798     static void pcd_start( void )
799     
800     {	int	unit = pcd_unit;
801     	int	b, i;
802     	char	rd_cmd[12] = {0xa8,0,0,0,0,0,0,0,0,1,0,0};
803     	long    saved_flags;
804     
805     	pcd_bufblk = pcd_sector / 4;
806             b = pcd_bufblk;
807     	for(i=0;i<4;i++) { 
808     	   rd_cmd[5-i] = b & 0xff;
809     	   b = b >> 8;
810     	}
811     
812     	if (pcd_command(unit,rd_cmd,2048,"read block")) {
813     		pcd_bufblk = -1; 
814     		spin_lock_irqsave(&io_request_lock,saved_flags);
815     		pcd_busy = 0;
816     		end_request(0);
817     		do_pcd_request(NULL);
818     		spin_unlock_irqrestore(&io_request_lock,saved_flags);
819     		return;
820     	}
821     
822     	mdelay(1);
823     
824     	ps_set_intr(do_pcd_read_drq,pcd_ready,PCD_TMO,nice);
825     
826     }
827     
828     static void do_pcd_read( void )
829     
830     
831     {	int	unit = pcd_unit;
832     	long    saved_flags;
833     
834     	pcd_busy = 1;
835     	pcd_retries = 0;
836     	pcd_transfer();
837     	if (!pcd_count) {
838     		spin_lock_irqsave(&io_request_lock,saved_flags);
839     		end_request(1);
840     		pcd_busy = 0;
841     		do_pcd_request(NULL);
842     		spin_unlock_irqrestore(&io_request_lock,saved_flags);
843     		return;
844     	}
845     
846     	pi_do_claimed(PI,pcd_start);
847     }
848     
849     static void do_pcd_read_drq( void )
850     
851     {	int	unit = pcd_unit;
852     	long    saved_flags;
853     
854     	if (pcd_completion(unit,pcd_buffer,"read block")) {
855                     if (pcd_retries < PCD_RETRIES) {
856                             mdelay(1); 
857                             pcd_retries++;
858     			pi_do_claimed(PI,pcd_start);
859                             return;
860                             }
861     		spin_lock_irqsave(&io_request_lock,saved_flags);
862     		pcd_busy = 0;
863     		pcd_bufblk = -1;
864     		end_request(0);
865     		do_pcd_request(NULL);
866     		spin_unlock_irqrestore(&io_request_lock,saved_flags);
867     		return;
868     	}
869     
870     	do_pcd_read();
871     	spin_lock_irqsave(&io_request_lock,saved_flags);
872     	do_pcd_request(NULL);
873     	spin_unlock_irqrestore(&io_request_lock,saved_flags); 
874     }
875     
876     /* the audio_ioctl stuff is adapted from sr_ioctl.c */
877     
878     static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
879                                     unsigned int cmd, void *arg)
880     
881     {	int	unit = DEVICE_NR(cdi->dev);
882      
883         	switch (cmd) { 
884         
885         	case CDROMREADTOCHDR:
886         
887     	{	char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,0,0,0,0,0,0,0,12,0,0,0};
888     		struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
889     		char buffer[32];
890     		int r;
891     	
892     		r = pcd_atapi(unit,cmd,12,buffer,"read toc header");
893     
894     		tochdr->cdth_trk0 = buffer[2];
895     		tochdr->cdth_trk1 = buffer[3];
896     	
897     		return r * EIO;
898         	}
899     	
900         	case CDROMREADTOCENTRY:
901     
902         	{	char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,0,0,0,0,0,0,0,12,0,0,0};
903     
904     		struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
905     		unsigned char buffer[32];
906     		int	r;
907     	
908     		cmd[1] = (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
909     		cmd[6] = tocentry->cdte_track;
910     	
911     		r = pcd_atapi(unit,cmd,12,buffer,"read toc entry");
912     
913             	tocentry->cdte_ctrl = buffer[5] & 0xf;	
914             	tocentry->cdte_adr = buffer[5] >> 4;
915             	tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04)?1:0;
916     		if (tocentry->cdte_format == CDROM_MSF) {
917     		    tocentry->cdte_addr.msf.minute = buffer[9];
918     	    	    tocentry->cdte_addr.msf.second = buffer[10];
919     	            tocentry->cdte_addr.msf.frame = buffer[11];
920     	        } else
921     	            tocentry->cdte_addr.lba = 
922     				(((((buffer[8] << 8) + buffer[9]) << 8)
923                                            + buffer[10]) << 8) + buffer[11];
924     	
925                     return r * EIO;
926             }
927     
928         	default:
929     
930             	return -ENOSYS;
931         	}
932     }
933     	
934     static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
935     
936     {	char 	cmd[12]={GPCMD_READ_SUBCHANNEL,0,0x40,2,0,0,0,0,24,0,0,0};
937             char 	buffer[32];
938     	int	k;
939     	int	unit = DEVICE_NR(cdi->dev);
940     
941             if (pcd_atapi(unit,cmd,24,buffer,"get mcn")) return -EIO;
942     
943     	for (k=0;k<13;k++) mcn->medium_catalog_number[k] = buffer[k+9];
944     	mcn->medium_catalog_number[13] = 0;
945     	
946     	return 0;
947     }
948     
949     /* end of pcd.c */
950     
951