GNU Linux-libre 4.4.284-gnu1
[releases.git] / 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 the
73         following kernel 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 enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
129
130 /* end of parameters */
131
132 #include <linux/module.h>
133 #include <linux/init.h>
134 #include <linux/errno.h>
135 #include <linux/fs.h>
136 #include <linux/kernel.h>
137 #include <linux/delay.h>
138 #include <linux/cdrom.h>
139 #include <linux/spinlock.h>
140 #include <linux/blkdev.h>
141 #include <linux/mutex.h>
142 #include <asm/uaccess.h>
143
144 static DEFINE_MUTEX(pcd_mutex);
145 static DEFINE_SPINLOCK(pcd_lock);
146
147 module_param(verbose, int, 0644);
148 module_param(major, int, 0);
149 module_param(name, charp, 0);
150 module_param(nice, int, 0);
151 module_param_array(drive0, int, NULL, 0);
152 module_param_array(drive1, int, NULL, 0);
153 module_param_array(drive2, int, NULL, 0);
154 module_param_array(drive3, int, NULL, 0);
155
156 #include "paride.h"
157 #include "pseudo.h"
158
159 #define PCD_RETRIES          5
160 #define PCD_TMO            800  /* timeout in jiffies */
161 #define PCD_DELAY           50  /* spin delay in uS */
162 #define PCD_READY_TMO       20  /* in seconds */
163 #define PCD_RESET_TMO      100  /* in tenths of a second */
164
165 #define PCD_SPIN        (1000000*PCD_TMO)/(HZ*PCD_DELAY)
166
167 #define IDE_ERR         0x01
168 #define IDE_DRQ         0x08
169 #define IDE_READY       0x40
170 #define IDE_BUSY        0x80
171
172 static int pcd_open(struct cdrom_device_info *cdi, int purpose);
173 static void pcd_release(struct cdrom_device_info *cdi);
174 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr);
175 static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
176                                      unsigned int clearing, int slot_nr);
177 static int pcd_tray_move(struct cdrom_device_info *cdi, int position);
178 static int pcd_lock_door(struct cdrom_device_info *cdi, int lock);
179 static int pcd_drive_reset(struct cdrom_device_info *cdi);
180 static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn);
181 static int pcd_audio_ioctl(struct cdrom_device_info *cdi,
182                            unsigned int cmd, void *arg);
183 static int pcd_packet(struct cdrom_device_info *cdi,
184                       struct packet_command *cgc);
185
186 static int pcd_detect(void);
187 static void pcd_probe_capabilities(void);
188 static void do_pcd_read_drq(void);
189 static void do_pcd_request(struct request_queue * q);
190 static void do_pcd_read(void);
191
192 struct pcd_unit {
193         struct pi_adapter pia;  /* interface to paride layer */
194         struct pi_adapter *pi;
195         int drive;              /* master/slave */
196         int last_sense;         /* result of last request sense */
197         int changed;            /* media change seen */
198         int present;            /* does this unit exist ? */
199         char *name;             /* pcd0, pcd1, etc */
200         struct cdrom_device_info info;  /* uniform cdrom interface */
201         struct gendisk *disk;
202 };
203
204 static struct pcd_unit pcd[PCD_UNITS];
205
206 static char pcd_scratch[64];
207 static char pcd_buffer[2048];   /* raw block buffer */
208 static int pcd_bufblk = -1;     /* block in buffer, in CD units,
209                                    -1 for nothing there. See also
210                                    pd_unit.
211                                  */
212
213 /* the variables below are used mainly in the I/O request engine, which
214    processes only one request at a time.
215 */
216
217 static struct pcd_unit *pcd_current; /* current request's drive */
218 static struct request *pcd_req;
219 static int pcd_retries;         /* retries on current request */
220 static int pcd_busy;            /* request being processed ? */
221 static int pcd_sector;          /* address of next requested sector */
222 static int pcd_count;           /* number of blocks still to do */
223 static char *pcd_buf;           /* buffer for request in progress */
224 static void *par_drv;           /* reference of parport driver */
225
226 /* kernel glue structures */
227
228 static int pcd_block_open(struct block_device *bdev, fmode_t mode)
229 {
230         struct pcd_unit *cd = bdev->bd_disk->private_data;
231         int ret;
232
233         check_disk_change(bdev);
234
235         mutex_lock(&pcd_mutex);
236         ret = cdrom_open(&cd->info, bdev, mode);
237         mutex_unlock(&pcd_mutex);
238
239         return ret;
240 }
241
242 static void pcd_block_release(struct gendisk *disk, fmode_t mode)
243 {
244         struct pcd_unit *cd = disk->private_data;
245         mutex_lock(&pcd_mutex);
246         cdrom_release(&cd->info, mode);
247         mutex_unlock(&pcd_mutex);
248 }
249
250 static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
251                                 unsigned cmd, unsigned long arg)
252 {
253         struct pcd_unit *cd = bdev->bd_disk->private_data;
254         int ret;
255
256         mutex_lock(&pcd_mutex);
257         ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
258         mutex_unlock(&pcd_mutex);
259
260         return ret;
261 }
262
263 static unsigned int pcd_block_check_events(struct gendisk *disk,
264                                            unsigned int clearing)
265 {
266         struct pcd_unit *cd = disk->private_data;
267         return cdrom_check_events(&cd->info, clearing);
268 }
269
270 static const struct block_device_operations pcd_bdops = {
271         .owner          = THIS_MODULE,
272         .open           = pcd_block_open,
273         .release        = pcd_block_release,
274         .ioctl          = pcd_block_ioctl,
275         .check_events   = pcd_block_check_events,
276 };
277
278 static struct cdrom_device_ops pcd_dops = {
279         .open           = pcd_open,
280         .release        = pcd_release,
281         .drive_status   = pcd_drive_status,
282         .check_events   = pcd_check_events,
283         .tray_move      = pcd_tray_move,
284         .lock_door      = pcd_lock_door,
285         .get_mcn        = pcd_get_mcn,
286         .reset          = pcd_drive_reset,
287         .audio_ioctl    = pcd_audio_ioctl,
288         .generic_packet = pcd_packet,
289         .capability     = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
290                           CDC_MCN | CDC_MEDIA_CHANGED | CDC_RESET |
291                           CDC_PLAY_AUDIO | CDC_GENERIC_PACKET | CDC_CD_R |
292                           CDC_CD_RW,
293 };
294
295 static void pcd_init_units(void)
296 {
297         struct pcd_unit *cd;
298         int unit;
299
300         pcd_drive_count = 0;
301         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
302                 struct gendisk *disk = alloc_disk(1);
303                 if (!disk)
304                         continue;
305                 cd->disk = disk;
306                 cd->pi = &cd->pia;
307                 cd->present = 0;
308                 cd->last_sense = 0;
309                 cd->changed = 1;
310                 cd->drive = (*drives[unit])[D_SLV];
311                 if ((*drives[unit])[D_PRT])
312                         pcd_drive_count++;
313
314                 cd->name = &cd->info.name[0];
315                 snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit);
316                 cd->info.ops = &pcd_dops;
317                 cd->info.handle = cd;
318                 cd->info.speed = 0;
319                 cd->info.capacity = 1;
320                 cd->info.mask = 0;
321                 disk->major = major;
322                 disk->first_minor = unit;
323                 strcpy(disk->disk_name, cd->name);      /* umm... */
324                 disk->fops = &pcd_bdops;
325                 disk->flags = GENHD_FL_BLOCK_EVENTS_ON_EXCL_WRITE;
326         }
327 }
328
329 static int pcd_open(struct cdrom_device_info *cdi, int purpose)
330 {
331         struct pcd_unit *cd = cdi->handle;
332         if (!cd->present)
333                 return -ENODEV;
334         return 0;
335 }
336
337 static void pcd_release(struct cdrom_device_info *cdi)
338 {
339 }
340
341 static inline int status_reg(struct pcd_unit *cd)
342 {
343         return pi_read_regr(cd->pi, 1, 6);
344 }
345
346 static inline int read_reg(struct pcd_unit *cd, int reg)
347 {
348         return pi_read_regr(cd->pi, 0, reg);
349 }
350
351 static inline void write_reg(struct pcd_unit *cd, int reg, int val)
352 {
353         pi_write_regr(cd->pi, 0, reg, val);
354 }
355
356 static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
357 {
358         int j, r, e, s, p;
359
360         j = 0;
361         while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop))))
362                && (j++ < PCD_SPIN))
363                 udelay(PCD_DELAY);
364
365         if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
366                 s = read_reg(cd, 7);
367                 e = read_reg(cd, 1);
368                 p = read_reg(cd, 2);
369                 if (j > PCD_SPIN)
370                         e |= 0x100;
371                 if (fun)
372                         printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
373                                " loop=%d phase=%d\n",
374                                cd->name, fun, msg, r, s, e, j, p);
375                 return (s << 8) + r;
376         }
377         return 0;
378 }
379
380 static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun)
381 {
382         pi_connect(cd->pi);
383
384         write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
385
386         if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
387                 pi_disconnect(cd->pi);
388                 return -1;
389         }
390
391         write_reg(cd, 4, dlen % 256);
392         write_reg(cd, 5, dlen / 256);
393         write_reg(cd, 7, 0xa0); /* ATAPI packet command */
394
395         if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
396                 pi_disconnect(cd->pi);
397                 return -1;
398         }
399
400         if (read_reg(cd, 2) != 1) {
401                 printk("%s: %s: command phase error\n", cd->name, fun);
402                 pi_disconnect(cd->pi);
403                 return -1;
404         }
405
406         pi_write_block(cd->pi, cmd, 12);
407
408         return 0;
409 }
410
411 static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
412 {
413         int r, d, p, n, k, j;
414
415         r = -1;
416         k = 0;
417         j = 0;
418
419         if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
420                       fun, "completion")) {
421                 r = 0;
422                 while (read_reg(cd, 7) & IDE_DRQ) {
423                         d = read_reg(cd, 4) + 256 * read_reg(cd, 5);
424                         n = (d + 3) & 0xfffc;
425                         p = read_reg(cd, 2) & 3;
426
427                         if ((p == 2) && (n > 0) && (j == 0)) {
428                                 pi_read_block(cd->pi, buf, n);
429                                 if (verbose > 1)
430                                         printk("%s: %s: Read %d bytes\n",
431                                                cd->name, fun, n);
432                                 r = 0;
433                                 j++;
434                         } else {
435                                 if (verbose > 1)
436                                         printk
437                                             ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
438                                              cd->name, fun, p, d, k);
439                                 if (verbose < 2)
440                                         printk_once(
441                                             "%s: WARNING: ATAPI phase errors\n",
442                                             cd->name);
443                                 mdelay(1);
444                         }
445                         if (k++ > PCD_TMO) {
446                                 printk("%s: Stuck DRQ\n", cd->name);
447                                 break;
448                         }
449                         if (pcd_wait
450                             (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
451                              "completion")) {
452                                 r = -1;
453                                 break;
454                         }
455                 }
456         }
457
458         pi_disconnect(cd->pi);
459
460         return r;
461 }
462
463 static void pcd_req_sense(struct pcd_unit *cd, char *fun)
464 {
465         char rs_cmd[12] = { 0x03, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
466         char buf[16];
467         int r, c;
468
469         r = pcd_command(cd, rs_cmd, 16, "Request sense");
470         mdelay(1);
471         if (!r)
472                 pcd_completion(cd, buf, "Request sense");
473
474         cd->last_sense = -1;
475         c = 2;
476         if (!r) {
477                 if (fun)
478                         printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
479                                cd->name, fun, buf[2] & 0xf, buf[12], buf[13]);
480                 c = buf[2] & 0xf;
481                 cd->last_sense =
482                     c | ((buf[12] & 0xff) << 8) | ((buf[13] & 0xff) << 16);
483         }
484         if ((c == 2) || (c == 6))
485                 cd->changed = 1;
486 }
487
488 static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun)
489 {
490         int r;
491
492         r = pcd_command(cd, cmd, dlen, fun);
493         mdelay(1);
494         if (!r)
495                 r = pcd_completion(cd, buf, fun);
496         if (r)
497                 pcd_req_sense(cd, fun);
498
499         return r;
500 }
501
502 static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc)
503 {
504         return pcd_atapi(cdi->handle, cgc->cmd, cgc->buflen, cgc->buffer,
505                          "generic packet");
506 }
507
508 #define DBMSG(msg)      ((verbose>1)?(msg):NULL)
509
510 static unsigned int pcd_check_events(struct cdrom_device_info *cdi,
511                                      unsigned int clearing, int slot_nr)
512 {
513         struct pcd_unit *cd = cdi->handle;
514         int res = cd->changed;
515         if (res)
516                 cd->changed = 0;
517         return res ? DISK_EVENT_MEDIA_CHANGE : 0;
518 }
519
520 static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
521 {
522         char un_cmd[12] = { 0x1e, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0 };
523
524         return pcd_atapi(cdi->handle, un_cmd, 0, pcd_scratch,
525                          lock ? "lock door" : "unlock door");
526 }
527
528 static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
529 {
530         char ej_cmd[12] = { 0x1b, 0, 0, 0, 3 - position, 0, 0, 0, 0, 0, 0, 0 };
531
532         return pcd_atapi(cdi->handle, ej_cmd, 0, pcd_scratch,
533                          position ? "eject" : "close tray");
534 }
535
536 static void pcd_sleep(int cs)
537 {
538         schedule_timeout_interruptible(cs);
539 }
540
541 static int pcd_reset(struct pcd_unit *cd)
542 {
543         int i, k, flg;
544         int expect[5] = { 1, 1, 1, 0x14, 0xeb };
545
546         pi_connect(cd->pi);
547         write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
548         write_reg(cd, 7, 8);
549
550         pcd_sleep(20 * HZ / 1000);      /* delay a bit */
551
552         k = 0;
553         while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY))
554                 pcd_sleep(HZ / 10);
555
556         flg = 1;
557         for (i = 0; i < 5; i++)
558                 flg &= (read_reg(cd, i + 1) == expect[i]);
559
560         if (verbose) {
561                 printk("%s: Reset (%d) signature = ", cd->name, k);
562                 for (i = 0; i < 5; i++)
563                         printk("%3x", read_reg(cd, i + 1));
564                 if (!flg)
565                         printk(" (incorrect)");
566                 printk("\n");
567         }
568
569         pi_disconnect(cd->pi);
570         return flg - 1;
571 }
572
573 static int pcd_drive_reset(struct cdrom_device_info *cdi)
574 {
575         return pcd_reset(cdi->handle);
576 }
577
578 static int pcd_ready_wait(struct pcd_unit *cd, int tmo)
579 {
580         char tr_cmd[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
581         int k, p;
582
583         k = 0;
584         while (k < tmo) {
585                 cd->last_sense = 0;
586                 pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready"));
587                 p = cd->last_sense;
588                 if (!p)
589                         return 0;
590                 if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
591                         return p;
592                 k++;
593                 pcd_sleep(HZ);
594         }
595         return 0x000020;        /* timeout */
596 }
597
598 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
599 {
600         char rc_cmd[12] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
601         struct pcd_unit *cd = cdi->handle;
602
603         if (pcd_ready_wait(cd, PCD_READY_TMO))
604                 return CDS_DRIVE_NOT_READY;
605         if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
606                 return CDS_NO_DISC;
607         return CDS_DISC_OK;
608 }
609
610 static int pcd_identify(struct pcd_unit *cd, char *id)
611 {
612         int k, s;
613         char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
614
615         pcd_bufblk = -1;
616
617         s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify");
618
619         if (s)
620                 return -1;
621         if ((pcd_buffer[0] & 0x1f) != 5) {
622                 if (verbose)
623                         printk("%s: %s is not a CD-ROM\n",
624                                cd->name, cd->drive ? "Slave" : "Master");
625                 return -1;
626         }
627         memcpy(id, pcd_buffer + 16, 16);
628         id[16] = 0;
629         k = 16;
630         while ((k >= 0) && (id[k] <= 0x20)) {
631                 id[k] = 0;
632                 k--;
633         }
634
635         printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id);
636
637         return 0;
638 }
639
640 /*
641  * returns  0, with id set if drive is detected
642  *          -1, if drive detection failed
643  */
644 static int pcd_probe(struct pcd_unit *cd, int ms, char *id)
645 {
646         if (ms == -1) {
647                 for (cd->drive = 0; cd->drive <= 1; cd->drive++)
648                         if (!pcd_reset(cd) && !pcd_identify(cd, id))
649                                 return 0;
650         } else {
651                 cd->drive = ms;
652                 if (!pcd_reset(cd) && !pcd_identify(cd, id))
653                         return 0;
654         }
655         return -1;
656 }
657
658 static void pcd_probe_capabilities(void)
659 {
660         int unit, r;
661         char buffer[32];
662         char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 };
663         struct pcd_unit *cd;
664
665         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
666                 if (!cd->present)
667                         continue;
668                 r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities");
669                 if (r)
670                         continue;
671                 /* we should now have the cap page */
672                 if ((buffer[11] & 1) == 0)
673                         cd->info.mask |= CDC_CD_R;
674                 if ((buffer[11] & 2) == 0)
675                         cd->info.mask |= CDC_CD_RW;
676                 if ((buffer[12] & 1) == 0)
677                         cd->info.mask |= CDC_PLAY_AUDIO;
678                 if ((buffer[14] & 1) == 0)
679                         cd->info.mask |= CDC_LOCK;
680                 if ((buffer[14] & 8) == 0)
681                         cd->info.mask |= CDC_OPEN_TRAY;
682                 if ((buffer[14] >> 6) == 0)
683                         cd->info.mask |= CDC_CLOSE_TRAY;
684         }
685 }
686
687 static int pcd_detect(void)
688 {
689         char id[18];
690         int k, unit;
691         struct pcd_unit *cd;
692
693         printk("%s: %s version %s, major %d, nice %d\n",
694                name, name, PCD_VERSION, major, nice);
695
696         par_drv = pi_register_driver(name);
697         if (!par_drv) {
698                 pr_err("failed to register %s driver\n", name);
699                 return -1;
700         }
701
702         k = 0;
703         if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
704                 cd = pcd;
705                 if (pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer,
706                             PI_PCD, verbose, cd->name)) {
707                         if (!pcd_probe(cd, -1, id) && cd->disk) {
708                                 cd->present = 1;
709                                 k++;
710                         } else
711                                 pi_release(cd->pi);
712                 }
713         } else {
714                 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
715                         int *conf = *drives[unit];
716                         if (!conf[D_PRT])
717                                 continue;
718                         if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD],
719                                      conf[D_UNI], conf[D_PRO], conf[D_DLY],
720                                      pcd_buffer, PI_PCD, verbose, cd->name)) 
721                                 continue;
722                         if (!pcd_probe(cd, conf[D_SLV], id) && cd->disk) {
723                                 cd->present = 1;
724                                 k++;
725                         } else
726                                 pi_release(cd->pi);
727                 }
728         }
729         if (k)
730                 return 0;
731
732         printk("%s: No CD-ROM drive found\n", name);
733         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
734                 put_disk(cd->disk);
735         pi_unregister_driver(par_drv);
736         return -1;
737 }
738
739 /* I/O request processing */
740 static struct request_queue *pcd_queue;
741
742 static void do_pcd_request(struct request_queue * q)
743 {
744         if (pcd_busy)
745                 return;
746         while (1) {
747                 if (!pcd_req) {
748                         pcd_req = blk_fetch_request(q);
749                         if (!pcd_req)
750                                 return;
751                 }
752
753                 if (rq_data_dir(pcd_req) == READ) {
754                         struct pcd_unit *cd = pcd_req->rq_disk->private_data;
755                         if (cd != pcd_current)
756                                 pcd_bufblk = -1;
757                         pcd_current = cd;
758                         pcd_sector = blk_rq_pos(pcd_req);
759                         pcd_count = blk_rq_cur_sectors(pcd_req);
760                         pcd_buf = bio_data(pcd_req->bio);
761                         pcd_busy = 1;
762                         ps_set_intr(do_pcd_read, NULL, 0, nice);
763                         return;
764                 } else {
765                         __blk_end_request_all(pcd_req, -EIO);
766                         pcd_req = NULL;
767                 }
768         }
769 }
770
771 static inline void next_request(int err)
772 {
773         unsigned long saved_flags;
774
775         spin_lock_irqsave(&pcd_lock, saved_flags);
776         if (!__blk_end_request_cur(pcd_req, err))
777                 pcd_req = NULL;
778         pcd_busy = 0;
779         do_pcd_request(pcd_queue);
780         spin_unlock_irqrestore(&pcd_lock, saved_flags);
781 }
782
783 static int pcd_ready(void)
784 {
785         return (((status_reg(pcd_current) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
786 }
787
788 static void pcd_transfer(void)
789 {
790
791         while (pcd_count && (pcd_sector / 4 == pcd_bufblk)) {
792                 int o = (pcd_sector % 4) * 512;
793                 memcpy(pcd_buf, pcd_buffer + o, 512);
794                 pcd_count--;
795                 pcd_buf += 512;
796                 pcd_sector++;
797         }
798 }
799
800 static void pcd_start(void)
801 {
802         int b, i;
803         char rd_cmd[12] = { 0xa8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
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(pcd_current, rd_cmd, 2048, "read block")) {
813                 pcd_bufblk = -1;
814                 next_request(-EIO);
815                 return;
816         }
817
818         mdelay(1);
819
820         ps_set_intr(do_pcd_read_drq, pcd_ready, PCD_TMO, nice);
821 }
822
823 static void do_pcd_read(void)
824 {
825         pcd_busy = 1;
826         pcd_retries = 0;
827         pcd_transfer();
828         if (!pcd_count) {
829                 next_request(0);
830                 return;
831         }
832
833         pi_do_claimed(pcd_current->pi, pcd_start);
834 }
835
836 static void do_pcd_read_drq(void)
837 {
838         unsigned long saved_flags;
839
840         if (pcd_completion(pcd_current, pcd_buffer, "read block")) {
841                 if (pcd_retries < PCD_RETRIES) {
842                         mdelay(1);
843                         pcd_retries++;
844                         pi_do_claimed(pcd_current->pi, pcd_start);
845                         return;
846                 }
847                 pcd_bufblk = -1;
848                 next_request(-EIO);
849                 return;
850         }
851
852         do_pcd_read();
853         spin_lock_irqsave(&pcd_lock, saved_flags);
854         do_pcd_request(pcd_queue);
855         spin_unlock_irqrestore(&pcd_lock, saved_flags);
856 }
857
858 /* the audio_ioctl stuff is adapted from sr_ioctl.c */
859
860 static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
861 {
862         struct pcd_unit *cd = cdi->handle;
863
864         switch (cmd) {
865
866         case CDROMREADTOCHDR:
867
868                 {
869                         char cmd[12] =
870                             { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
871                          0, 0, 0 };
872                         struct cdrom_tochdr *tochdr =
873                             (struct cdrom_tochdr *) arg;
874                         char buffer[32];
875                         int r;
876
877                         r = pcd_atapi(cd, cmd, 12, buffer, "read toc header");
878
879                         tochdr->cdth_trk0 = buffer[2];
880                         tochdr->cdth_trk1 = buffer[3];
881
882                         return r ? -EIO : 0;
883                 }
884
885         case CDROMREADTOCENTRY:
886
887                 {
888                         char cmd[12] =
889                             { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
890                          0, 0, 0 };
891
892                         struct cdrom_tocentry *tocentry =
893                             (struct cdrom_tocentry *) arg;
894                         unsigned char buffer[32];
895                         int r;
896
897                         cmd[1] =
898                             (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
899                         cmd[6] = tocentry->cdte_track;
900
901                         r = pcd_atapi(cd, cmd, 12, buffer, "read toc entry");
902
903                         tocentry->cdte_ctrl = buffer[5] & 0xf;
904                         tocentry->cdte_adr = buffer[5] >> 4;
905                         tocentry->cdte_datamode =
906                             (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
907                         if (tocentry->cdte_format == CDROM_MSF) {
908                                 tocentry->cdte_addr.msf.minute = buffer[9];
909                                 tocentry->cdte_addr.msf.second = buffer[10];
910                                 tocentry->cdte_addr.msf.frame = buffer[11];
911                         } else
912                                 tocentry->cdte_addr.lba =
913                                     (((((buffer[8] << 8) + buffer[9]) << 8)
914                                       + buffer[10]) << 8) + buffer[11];
915
916                         return r ? -EIO : 0;
917                 }
918
919         default:
920
921                 return -ENOSYS;
922         }
923 }
924
925 static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
926 {
927         char cmd[12] =
928             { GPCMD_READ_SUBCHANNEL, 0, 0x40, 2, 0, 0, 0, 0, 24, 0, 0, 0 };
929         char buffer[32];
930
931         if (pcd_atapi(cdi->handle, cmd, 24, buffer, "get mcn"))
932                 return -EIO;
933
934         memcpy(mcn->medium_catalog_number, buffer + 9, 13);
935         mcn->medium_catalog_number[13] = 0;
936
937         return 0;
938 }
939
940 static int __init pcd_init(void)
941 {
942         struct pcd_unit *cd;
943         int unit;
944
945         if (disable)
946                 return -EINVAL;
947
948         pcd_init_units();
949
950         if (pcd_detect())
951                 return -ENODEV;
952
953         /* get the atapi capabilities page */
954         pcd_probe_capabilities();
955
956         if (register_blkdev(major, name)) {
957                 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
958                         put_disk(cd->disk);
959                 return -EBUSY;
960         }
961
962         pcd_queue = blk_init_queue(do_pcd_request, &pcd_lock);
963         if (!pcd_queue) {
964                 unregister_blkdev(major, name);
965                 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
966                         put_disk(cd->disk);
967                 return -ENOMEM;
968         }
969
970         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
971                 if (cd->present) {
972                         register_cdrom(&cd->info);
973                         cd->disk->private_data = cd;
974                         cd->disk->queue = pcd_queue;
975                         add_disk(cd->disk);
976                 }
977         }
978
979         return 0;
980 }
981
982 static void __exit pcd_exit(void)
983 {
984         struct pcd_unit *cd;
985         int unit;
986
987         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
988                 if (cd->present) {
989                         del_gendisk(cd->disk);
990                         pi_release(cd->pi);
991                         unregister_cdrom(&cd->info);
992                 }
993                 put_disk(cd->disk);
994         }
995         blk_cleanup_queue(pcd_queue);
996         unregister_blkdev(major, name);
997         pi_unregister_driver(par_drv);
998 }
999
1000 MODULE_LICENSE("GPL");
1001 module_init(pcd_init)
1002 module_exit(pcd_exit)