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