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