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