2 pcd.c (c) 1997-8 Grant R. Guenther <grant@torque.net>
3 Under the terms of the GNU General Public License.
5 This is a high-level driver for parallel port ATAPI CD-ROM
6 drives based on chips supported by the paride module.
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.
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:
16 drive0 These four arguments can be arrays of
17 drive1 1-6 integers as follows:
19 drive3 <prt>,<pro>,<uni>,<mod>,<slv>,<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 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
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)
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
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).
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
69 nice This parameter controls the driver's use of
70 idle CPU time, at the expense of some speed.
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:
82 In addition, you can use the parameter pcd.disable to disable
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
103 #define PCD_VERSION "1.07"
105 #define PCD_NAME "pcd"
108 /* Here are things one can override from the insmod command.
109 Most are autoprobed by paride unless set here. Verbose is off
114 static int verbose = 0;
115 static int major = PCD_MAJOR;
116 static char *name = PCD_NAME;
118 static int disable = 0;
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};
125 static int (*drives[4])[6] = {&drive0,&drive1,&drive2,&drive3};
126 static int pcd_drive_count;
135 #define DU (*drives[unit])
137 /* end of parameters */
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>
147 #include <asm/uaccess.h>
153 static STT pcd_stt[6] = {{"drive0",6,drive0},
157 {"disable",1,&disable},
160 void pcd_setup( char *str, int *ints)
162 { generic_setup(pcd_stt,6,str);
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");
178 /* set up defines for blk.h, why don't all drivers do it this way ? */
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)
187 #include <linux/blk.h>
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 */
197 #define PCD_SPIN (1000000*PCD_TMO)/(HZ*PCD_DELAY)
201 #define IDE_READY 0x40
202 #define IDE_BUSY 0x80
205 void cleanup_module( void );
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);
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);
226 static int pcd_blocksizes[PCD_UNITS];
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 */
239 struct pcd_unit pcd[PCD_UNITS];
241 /* 'unit' must be defined in all functions - either as a local or a param */
243 #define PCD pcd[unit]
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
253 /* the variables below are used mainly in the I/O request engine, which
254 processes only one request at a time.
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 */
264 static int pcd_warned = 0; /* Have we logged a phase warning ? */
266 /* kernel glue structures */
268 static struct block_device_operations pcd_bdops = {
271 release: cdrom_release,
273 check_media_change: cdrom_media_changed,
276 static struct cdrom_device_ops pcd_dops = {
283 0, /* select speed */
285 0, /* get last session */
304 static void pcd_init_units( void )
309 for (unit=0;unit<PCD_UNITS;unit++) {
314 PCD.drive = DU[D_SLV];
315 if (DU[D_PRT]) pcd_drive_count++;
318 while ((j < (sizeof(PCD.info.name)-2)) &&
319 (PCD.info.name[j]=name[j])) j++;
320 PCD.info.name[j++] = '0' + unit;
321 PCD.info.name[j] = 0;
322 PCD.name = &PCD.info.name[0];
324 PCD.info.ops = &pcd_dops;
325 PCD.info.handle = NULL;
326 PCD.info.dev = MKDEV(major,unit);
328 PCD.info.capacity = 1;
333 int pcd_init (void) /* preliminary initialisation */
337 if (disable) return -1;
341 if (pcd_detect()) return -1;
343 /* get the atapi capabilities page */
344 pcd_probe_capabilities();
346 if (register_blkdev(MAJOR_NR,name,&pcd_bdops)) {
347 printk("pcd: unable to get major number %d\n",MAJOR_NR);
351 for (unit=0;unit<PCD_UNITS;unit++) {
353 register_cdrom(&PCD.info);
354 devfs_plain_cdrom(&PCD.info, &pcd_bdops);
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<PCD_UNITS;i++) pcd_blocksizes[i] = 1024;
362 blksize_size[MAJOR_NR] = pcd_blocksizes;
367 static int pcd_open(struct cdrom_device_info *cdi, int purpose)
369 { int unit = DEVICE_NR(cdi->dev);
371 if ((unit >= PCD_UNITS) || (!PCD.present)) return -ENODEV;
376 static void pcd_release(struct cdrom_device_info *cdi)
383 /* Glue for modules ... */
385 int init_module(void)
390 { extern paride_init();
400 void cleanup_module(void)
404 for (unit=0;unit<PCD_UNITS;unit++)
407 unregister_cdrom(&PCD.info);
410 unregister_blkdev(MAJOR_NR,name);
415 #define WR(c,r,v) pi_write_regr(PI,c,r,v)
416 #define RR(c,r) (pi_read_regr(PI,c,r))
418 static int pcd_wait( int unit, int go, int stop, char * fun, char * msg )
423 while ((((r=RR(1,6))&go)||(stop&&(!(r&stop))))&&(j++<PCD_SPIN))
426 if ((r&(IDE_ERR&stop))||(j>=PCD_SPIN)) {
430 if (j >= PCD_SPIN) e |= 0x100;
431 if (fun) printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
432 " loop=%d phase=%d\n",
433 PCD.name,fun,msg,r,s,e,j,p);
439 static int pcd_command( int unit, char * cmd, int dlen, char * fun )
443 WR(0,6,0xa0 + 0x10*PCD.drive);
445 if (pcd_wait(unit,IDE_BUSY|IDE_DRQ,0,fun,"before command")) {
452 WR(0,7,0xa0); /* ATAPI packet command */
454 if (pcd_wait(unit,IDE_BUSY,IDE_DRQ,fun,"command DRQ")) {
460 printk("%s: %s: command phase error\n",PCD.name,fun);
465 pi_write_block(PI,cmd,12);
470 static int pcd_completion( int unit, char * buf, char * fun )
472 { int r, d, p, n, k, j;
474 r = -1; k = 0; j = 0;
476 if (!pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
479 while (RR(0,7)&IDE_DRQ) {
480 d = (RR(0,4)+256*RR(0,5));
484 if ((p == 2) && (n > 0) && (j == 0)) {
485 pi_read_block(PI,buf,n);
487 printk("%s: %s: Read %d bytes\n",PCD.name,fun,n);
491 printk("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
493 if ((verbose < 2) && !pcd_warned) {
495 printk("%s: WARNING: ATAPI phase errors\n",PCD.name);
500 printk("%s: Stuck DRQ\n",PCD.name);
503 if (pcd_wait(unit,IDE_BUSY,IDE_DRQ|IDE_READY|IDE_ERR,
516 static void pcd_req_sense( int unit, char *fun )
518 { char rs_cmd[12] = { 0x03,0,0,0,16,0,0,0,0,0,0,0 };
522 r = pcd_command(unit,rs_cmd,16,"Request sense");
524 if (!r) pcd_completion(unit,buf,"Request sense");
526 PCD.last_sense = -1; c = 2;
528 if (fun) printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
529 PCD.name,fun,buf[2]&0xf,buf[12],buf[13]);
531 PCD.last_sense = c | ((buf[12]&0xff)<<8) | ((buf[13]&0xff)<<16);
533 if ((c == 2) || (c == 6)) PCD.changed = 1;
536 static int pcd_atapi( int unit, char * cmd, int dlen, char * buf, char * fun )
540 r = pcd_command(unit,cmd,dlen,fun);
542 if (!r) r = pcd_completion(unit,buf,fun);
543 if (r) pcd_req_sense(unit,fun);
548 static int pcd_packet(struct cdrom_device_info *cdi,
549 struct cdrom_generic_command *cgc)
552 int unit = DEVICE_NR(cdi->dev);
555 return pcd_atapi(unit,un_cmd,cgc->buflen,cgc->buffer, "generic packet");
558 #define DBMSG(msg) ((verbose>1)?(msg):NULL)
560 static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
563 int unit = DEVICE_NR(cdi->dev);
571 static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
573 { char un_cmd[12] = { 0x1e,0,0,0,lock,0,0,0,0,0,0,0 };
574 int unit = DEVICE_NR(cdi->dev);
576 return pcd_atapi(unit,un_cmd,0,pcd_scratch,
577 lock?"lock door":"unlock door");
580 static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
582 { char ej_cmd[12] = { 0x1b,0,0,0,3-position,0,0,0,0,0,0,0 };
583 int unit = DEVICE_NR(cdi->dev);
585 return pcd_atapi(unit,ej_cmd,0,pcd_scratch,
586 position?"eject":"close tray");
589 static void pcd_sleep( int cs )
591 { current->state = TASK_INTERRUPTIBLE;
592 schedule_timeout(cs);
595 static int pcd_reset( int unit )
598 int expect[5] = {1,1,1,0x14,0xeb};
601 WR(0,6,0xa0 + 0x10*PCD.drive);
604 pcd_sleep(20*HZ/1000); /* delay a bit */
607 while ((k++ < PCD_RESET_TMO) && (RR(1,6)&IDE_BUSY))
611 for(i=0;i<5;i++) flg &= (RR(0,i+1) == expect[i]);
614 printk("%s: Reset (%d) signature = ",PCD.name,k);
615 for (i=0;i<5;i++) printk("%3x",RR(0,i+1));
616 if (!flg) printk(" (incorrect)");
624 static int pcd_drive_reset(struct cdrom_device_info *cdi)
626 { return pcd_reset(DEVICE_NR(cdi->dev));
629 static int pcd_ready_wait( int unit, int tmo )
631 { char tr_cmd[12] = {0,0,0,0,0,0,0,0,0,0,0,0};
637 pcd_atapi(unit,tr_cmd,0,NULL,DBMSG("test unit ready"));
640 if (!(((p & 0xffff) == 0x0402)||((p & 0xff) == 6))) return p;
644 return 0x000020; /* timeout */
647 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
649 { char rc_cmd[12] = { 0x25,0,0,0,0,0,0,0,0,0,0,0};
650 int unit = DEVICE_NR(cdi->dev);
652 if (pcd_ready_wait(unit,PCD_READY_TMO))
653 return CDS_DRIVE_NOT_READY;
654 if (pcd_atapi(unit,rc_cmd,8,pcd_scratch,DBMSG("check media")))
659 static int pcd_identify( int unit, char * id )
662 char id_cmd[12] = {0x12,0,0,0,36,0,0,0,0,0,0,0};
666 s = pcd_atapi(unit,id_cmd,36,pcd_buffer,"identify");
669 if ((pcd_buffer[0] & 0x1f) != 5) {
670 if (verbose) printk("%s: %s is not a CD-ROM\n",
671 PCD.name,PCD.drive?"Slave":"Master");
674 for (k=0;k<16;k++) id[k] = pcd_buffer[16+k]; id[16] = 0;
675 k = 16; while ((k >= 0) && (id[k] <= 0x20)) { id[k] = 0; k--; }
677 printk("%s: %s: %s\n",PCD.name,PCD.drive?"Slave":"Master",id);
682 static int pcd_probe( int unit, int ms, char * id )
684 /* returns 0, with id set if drive is detected
685 -1, if drive detection failed
689 for (PCD.drive=0;PCD.drive<=1;PCD.drive++)
690 if (!pcd_reset(unit) && !pcd_identify(unit,id))
694 if (!pcd_reset(unit) && !pcd_identify(unit,id))
700 static void pcd_probe_capabilities( void )
704 char cmd[12]={0x5a,1<<3,0x2a,0,0,0,0,18,0,0,0,0};
706 for (unit=0;unit<PCD_UNITS;unit++) {
707 if (!PCD.present) continue;
708 r = pcd_atapi(unit,cmd,18, buffer,"mode sense capabilities");
710 /* we should now have the cap page */
711 if ((buffer[11] & 1) == 0)
712 PCD.info.mask |= CDC_CD_R;
713 if ((buffer[11] & 2) == 0)
714 PCD.info.mask |= CDC_CD_RW;
715 if ((buffer[12] & 1) == 0)
716 PCD.info.mask |= CDC_PLAY_AUDIO;
717 if ((buffer[14] & 1) == 0)
718 PCD.info.mask |= CDC_LOCK;
719 if ((buffer[14] & 8) == 0)
720 PCD.info.mask |= CDC_OPEN_TRAY;
721 if ((buffer[14] >> 6) == 0)
722 PCD.info.mask |= CDC_CLOSE_TRAY;
726 static int pcd_detect( void )
731 printk("%s: %s version %s, major %d, nice %d\n",
732 name,name,PCD_VERSION,major,nice);
735 if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
737 if (pi_init(PI,1,-1,-1,-1,-1,-1,pcd_buffer,
738 PI_PCD,verbose,PCD.name)) {
739 if (!pcd_probe(unit,-1,id)) {
742 } else pi_release(PI);
745 } else for (unit=0;unit<PCD_UNITS;unit++) if (DU[D_PRT])
746 if (pi_init(PI,0,DU[D_PRT],DU[D_MOD],DU[D_UNI],
747 DU[D_PRO],DU[D_DLY],pcd_buffer,PI_PCD,verbose,
749 if (!pcd_probe(unit,DU[D_SLV],id)) {
752 } else pi_release(PI);
757 printk("%s: No CD-ROM drive found\n",name);
761 /* I/O request processing */
763 static void do_pcd_request (request_queue_t * q)
767 if (pcd_busy) return;
769 if (QUEUE_EMPTY || (CURRENT->rq_status == RQ_INACTIVE)) return;
771 if (CURRENT->cmd == READ) {
772 unit = MINOR(CURRENT->rq_dev);
773 if (unit != pcd_unit) {
777 pcd_sector = CURRENT->sector;
778 pcd_count = CURRENT->current_nr_sectors;
779 pcd_buf = CURRENT->buffer;
781 ps_set_intr(do_pcd_read,0,0,nice);
788 static int pcd_ready( void )
790 { int unit = pcd_unit;
792 return (((RR(1,6)&(IDE_BUSY|IDE_DRQ))==IDE_DRQ)) ;
795 static void pcd_transfer( void )
799 while (pcd_count && (pcd_sector/4 == pcd_bufblk)) {
800 o = (pcd_sector % 4) * 512;
801 for(k=0;k<512;k++) pcd_buf[k] = pcd_buffer[o+k];
808 static void pcd_start( void )
810 { int unit = pcd_unit;
812 char rd_cmd[12] = {0xa8,0,0,0,0,0,0,0,0,1,0,0};
813 unsigned long saved_flags;
815 pcd_bufblk = pcd_sector / 4;
818 rd_cmd[5-i] = b & 0xff;
822 if (pcd_command(unit,rd_cmd,2048,"read block")) {
824 spin_lock_irqsave(&io_request_lock,saved_flags);
827 do_pcd_request(NULL);
828 spin_unlock_irqrestore(&io_request_lock,saved_flags);
834 ps_set_intr(do_pcd_read_drq,pcd_ready,PCD_TMO,nice);
838 static void do_pcd_read( void )
841 { int unit = pcd_unit;
842 unsigned long saved_flags;
848 spin_lock_irqsave(&io_request_lock,saved_flags);
851 do_pcd_request(NULL);
852 spin_unlock_irqrestore(&io_request_lock,saved_flags);
856 pi_do_claimed(PI,pcd_start);
859 static void do_pcd_read_drq( void )
861 { int unit = pcd_unit;
862 unsigned long saved_flags;
864 if (pcd_completion(unit,pcd_buffer,"read block")) {
865 if (pcd_retries < PCD_RETRIES) {
868 pi_do_claimed(PI,pcd_start);
871 spin_lock_irqsave(&io_request_lock,saved_flags);
875 do_pcd_request(NULL);
876 spin_unlock_irqrestore(&io_request_lock,saved_flags);
881 spin_lock_irqsave(&io_request_lock,saved_flags);
882 do_pcd_request(NULL);
883 spin_unlock_irqrestore(&io_request_lock,saved_flags);
886 /* the audio_ioctl stuff is adapted from sr_ioctl.c */
888 static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
889 unsigned int cmd, void *arg)
891 { int unit = DEVICE_NR(cdi->dev);
895 case CDROMREADTOCHDR:
897 { char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,0,0,0,0,0,0,0,12,0,0,0};
898 struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg;
902 r = pcd_atapi(unit,cmd,12,buffer,"read toc header");
904 tochdr->cdth_trk0 = buffer[2];
905 tochdr->cdth_trk1 = buffer[3];
910 case CDROMREADTOCENTRY:
912 { char cmd[12]={GPCMD_READ_TOC_PMA_ATIP,0,0,0,0,0,0,0,12,0,0,0};
914 struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg;
915 unsigned char buffer[32];
918 cmd[1] = (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
919 cmd[6] = tocentry->cdte_track;
921 r = pcd_atapi(unit,cmd,12,buffer,"read toc entry");
923 tocentry->cdte_ctrl = buffer[5] & 0xf;
924 tocentry->cdte_adr = buffer[5] >> 4;
925 tocentry->cdte_datamode = (tocentry->cdte_ctrl & 0x04)?1:0;
926 if (tocentry->cdte_format == CDROM_MSF) {
927 tocentry->cdte_addr.msf.minute = buffer[9];
928 tocentry->cdte_addr.msf.second = buffer[10];
929 tocentry->cdte_addr.msf.frame = buffer[11];
931 tocentry->cdte_addr.lba =
932 (((((buffer[8] << 8) + buffer[9]) << 8)
933 + buffer[10]) << 8) + buffer[11];
944 static int pcd_get_mcn (struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
946 { char cmd[12]={GPCMD_READ_SUBCHANNEL,0,0x40,2,0,0,0,0,24,0,0,0};
949 int unit = DEVICE_NR(cdi->dev);
951 if (pcd_atapi(unit,cmd,24,buffer,"get mcn")) return -EIO;
953 for (k=0;k<13;k++) mcn->medium_catalog_number[k] = buffer[k+9];
954 mcn->medium_catalog_number[13] = 0;
961 MODULE_LICENSE("GPL");