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