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