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