Merge git://git.infradead.org/mtd-2.6
[pandora-kernel.git] / drivers / block / paride / pcd.c
1 /* 
2         pcd.c   (c) 1997-8  Grant R. Guenther <grant@torque.net>
3                             Under the terms of the GNU General Public License.
4
5         This is a high-level driver for parallel port ATAPI CD-ROM
6         drives based on chips supported by the paride module.
7
8         By default, the driver will autoprobe for a single parallel
9         port ATAPI CD-ROM drive, but if their individual parameters are
10         specified, the driver can handle up to 4 drives.
11
12         The behaviour of the pcd driver can be altered by setting
13         some parameters from the insmod command line.  The following
14         parameters are adjustable:
15
16             drive0      These four arguments can be arrays of       
17             drive1      1-6 integers as follows:
18             drive2
19             drive3      <prt>,<pro>,<uni>,<mod>,<slv>,<dly>
20
21                         Where,
22
23                 <prt>   is the base of the parallel port address for
24                         the corresponding drive.  (required)
25
26                 <pro>   is the protocol number for the adapter that
27                         supports this drive.  These numbers are
28                         logged by 'paride' when the protocol modules
29                         are initialised.  (0 if not given)
30
31                 <uni>   for those adapters that support chained
32                         devices, this is the unit selector for the
33                         chain of devices on the given port.  It should
34                         be zero for devices that don't support chaining.
35                         (0 if not given)
36
37                 <mod>   this can be -1 to choose the best mode, or one
38                         of the mode numbers supported by the adapter.
39                         (-1 if not given)
40
41                 <slv>   ATAPI CD-ROMs can be jumpered to master or slave.
42                         Set this to 0 to choose the master drive, 1 to
43                         choose the slave, -1 (the default) to choose the
44                         first drive found.
45
46                 <dly>   some parallel ports require the driver to 
47                         go more slowly.  -1 sets a default value that
48                         should work with the chosen protocol.  Otherwise,
49                         set this to a small integer, the larger it is
50                         the slower the port i/o.  In some cases, setting
51                         this to zero will speed up the device. (default -1)
52                         
53             major       You may use this parameter to overide the
54                         default major number (46) that this driver
55                         will use.  Be sure to change the device
56                         name as well.
57
58             name        This parameter is a character string that
59                         contains the name the kernel will use for this
60                         device (in /proc output, for instance).
61                         (default "pcd")
62
63             verbose     This parameter controls the amount of logging
64                         that the driver will do.  Set it to 0 for
65                         normal operation, 1 to see autoprobe progress
66                         messages, or 2 to see additional debugging
67                         output.  (default 0)
68   
69             nice        This parameter controls the driver's use of
70                         idle CPU time, at the expense of some speed.
71  
72         If this driver is built into the kernel, you can use kernel
73         the following command line parameters, with the same values
74         as the corresponding module parameters listed above:
75
76             pcd.drive0
77             pcd.drive1
78             pcd.drive2
79             pcd.drive3
80             pcd.nice
81
82         In addition, you can use the parameter pcd.disable to disable
83         the driver entirely.
84
85 */
86
87 /* Changes:
88
89         1.01    GRG 1998.01.24  Added test unit ready support
90         1.02    GRG 1998.05.06  Changes to pcd_completion, ready_wait,
91                                 and loosen interpretation of ATAPI
92                                 standard for clearing error status.
93                                 Use spinlocks. Eliminate sti().
94         1.03    GRG 1998.06.16  Eliminated an Ugh
95         1.04    GRG 1998.08.15  Added extra debugging, improvements to
96                                 pcd_completion, use HZ in loop timing
97         1.05    GRG 1998.08.16  Conformed to "Uniform CD-ROM" standard
98         1.06    GRG 1998.08.19  Added audio ioctl support
99         1.07    GRG 1998.09.24  Increased reset timeout, added jumbo support
100
101 */
102
103 #define PCD_VERSION     "1.07"
104 #define PCD_MAJOR       46
105 #define PCD_NAME        "pcd"
106 #define PCD_UNITS       4
107
108 /* Here are things one can override from the insmod command.
109    Most are autoprobed by paride unless set here.  Verbose is off
110    by default.
111
112 */
113
114 static int verbose = 0;
115 static int major = PCD_MAJOR;
116 static char *name = PCD_NAME;
117 static int nice = 0;
118 static int disable = 0;
119
120 static int drive0[6] = { 0, 0, 0, -1, -1, -1 };
121 static int drive1[6] = { 0, 0, 0, -1, -1, -1 };
122 static int drive2[6] = { 0, 0, 0, -1, -1, -1 };
123 static int drive3[6] = { 0, 0, 0, -1, -1, -1 };
124
125 static int (*drives[4])[6] = {&drive0, &drive1, &drive2, &drive3};
126 static int pcd_drive_count;
127
128 enum {D_PRT, D_PRO, D_UNI, D_MOD, D_SLV, D_DLY};
129
130 /* end of parameters */
131
132 #include <linux/module.h>
133 #include <linux/init.h>
134 #include <linux/errno.h>
135 #include <linux/fs.h>
136 #include <linux/kernel.h>
137 #include <linux/delay.h>
138 #include <linux/cdrom.h>
139 #include <linux/spinlock.h>
140 #include <linux/blkdev.h>
141 #include <linux/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         int ret;
229
230         lock_kernel();
231         ret = cdrom_open(&cd->info, bdev, mode);
232         unlock_kernel();
233
234         return ret;
235 }
236
237 static int pcd_block_release(struct gendisk *disk, fmode_t mode)
238 {
239         struct pcd_unit *cd = disk->private_data;
240         lock_kernel();
241         cdrom_release(&cd->info, mode);
242         unlock_kernel();
243         return 0;
244 }
245
246 static int pcd_block_ioctl(struct block_device *bdev, fmode_t mode,
247                                 unsigned cmd, unsigned long arg)
248 {
249         struct pcd_unit *cd = bdev->bd_disk->private_data;
250         int ret;
251
252         lock_kernel();
253         ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg);
254         unlock_kernel();
255
256         return ret;
257 }
258
259 static int pcd_block_media_changed(struct gendisk *disk)
260 {
261         struct pcd_unit *cd = disk->private_data;
262         return cdrom_media_changed(&cd->info);
263 }
264
265 static const struct block_device_operations pcd_bdops = {
266         .owner          = THIS_MODULE,
267         .open           = pcd_block_open,
268         .release        = pcd_block_release,
269         .ioctl          = pcd_block_ioctl,
270         .media_changed  = pcd_block_media_changed,
271 };
272
273 static struct cdrom_device_ops pcd_dops = {
274         .open           = pcd_open,
275         .release        = pcd_release,
276         .drive_status   = pcd_drive_status,
277         .media_changed  = pcd_media_changed,
278         .tray_move      = pcd_tray_move,
279         .lock_door      = pcd_lock_door,
280         .get_mcn        = pcd_get_mcn,
281         .reset          = pcd_drive_reset,
282         .audio_ioctl    = pcd_audio_ioctl,
283         .generic_packet = pcd_packet,
284         .capability     = CDC_CLOSE_TRAY | CDC_OPEN_TRAY | CDC_LOCK |
285                           CDC_MCN | CDC_MEDIA_CHANGED | CDC_RESET |
286                           CDC_PLAY_AUDIO | CDC_GENERIC_PACKET | CDC_CD_R |
287                           CDC_CD_RW,
288 };
289
290 static void pcd_init_units(void)
291 {
292         struct pcd_unit *cd;
293         int unit;
294
295         pcd_drive_count = 0;
296         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
297                 struct gendisk *disk = alloc_disk(1);
298                 if (!disk)
299                         continue;
300                 cd->disk = disk;
301                 cd->pi = &cd->pia;
302                 cd->present = 0;
303                 cd->last_sense = 0;
304                 cd->changed = 1;
305                 cd->drive = (*drives[unit])[D_SLV];
306                 if ((*drives[unit])[D_PRT])
307                         pcd_drive_count++;
308
309                 cd->name = &cd->info.name[0];
310                 snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit);
311                 cd->info.ops = &pcd_dops;
312                 cd->info.handle = cd;
313                 cd->info.speed = 0;
314                 cd->info.capacity = 1;
315                 cd->info.mask = 0;
316                 disk->major = major;
317                 disk->first_minor = unit;
318                 strcpy(disk->disk_name, cd->name);      /* umm... */
319                 disk->fops = &pcd_bdops;
320         }
321 }
322
323 static int pcd_open(struct cdrom_device_info *cdi, int purpose)
324 {
325         struct pcd_unit *cd = cdi->handle;
326         if (!cd->present)
327                 return -ENODEV;
328         return 0;
329 }
330
331 static void pcd_release(struct cdrom_device_info *cdi)
332 {
333 }
334
335 static inline int status_reg(struct pcd_unit *cd)
336 {
337         return pi_read_regr(cd->pi, 1, 6);
338 }
339
340 static inline int read_reg(struct pcd_unit *cd, int reg)
341 {
342         return pi_read_regr(cd->pi, 0, reg);
343 }
344
345 static inline void write_reg(struct pcd_unit *cd, int reg, int val)
346 {
347         pi_write_regr(cd->pi, 0, reg, val);
348 }
349
350 static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg)
351 {
352         int j, r, e, s, p;
353
354         j = 0;
355         while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop))))
356                && (j++ < PCD_SPIN))
357                 udelay(PCD_DELAY);
358
359         if ((r & (IDE_ERR & stop)) || (j > PCD_SPIN)) {
360                 s = read_reg(cd, 7);
361                 e = read_reg(cd, 1);
362                 p = read_reg(cd, 2);
363                 if (j > PCD_SPIN)
364                         e |= 0x100;
365                 if (fun)
366                         printk("%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
367                                " loop=%d phase=%d\n",
368                                cd->name, fun, msg, r, s, e, j, p);
369                 return (s << 8) + r;
370         }
371         return 0;
372 }
373
374 static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun)
375 {
376         pi_connect(cd->pi);
377
378         write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
379
380         if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) {
381                 pi_disconnect(cd->pi);
382                 return -1;
383         }
384
385         write_reg(cd, 4, dlen % 256);
386         write_reg(cd, 5, dlen / 256);
387         write_reg(cd, 7, 0xa0); /* ATAPI packet command */
388
389         if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) {
390                 pi_disconnect(cd->pi);
391                 return -1;
392         }
393
394         if (read_reg(cd, 2) != 1) {
395                 printk("%s: %s: command phase error\n", cd->name, fun);
396                 pi_disconnect(cd->pi);
397                 return -1;
398         }
399
400         pi_write_block(cd->pi, cmd, 12);
401
402         return 0;
403 }
404
405 static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun)
406 {
407         int r, d, p, n, k, j;
408
409         r = -1;
410         k = 0;
411         j = 0;
412
413         if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR,
414                       fun, "completion")) {
415                 r = 0;
416                 while (read_reg(cd, 7) & IDE_DRQ) {
417                         d = read_reg(cd, 4) + 256 * read_reg(cd, 5);
418                         n = (d + 3) & 0xfffc;
419                         p = read_reg(cd, 2) & 3;
420
421                         if ((p == 2) && (n > 0) && (j == 0)) {
422                                 pi_read_block(cd->pi, buf, n);
423                                 if (verbose > 1)
424                                         printk("%s: %s: Read %d bytes\n",
425                                                cd->name, fun, n);
426                                 r = 0;
427                                 j++;
428                         } else {
429                                 if (verbose > 1)
430                                         printk
431                                             ("%s: %s: Unexpected phase %d, d=%d, k=%d\n",
432                                              cd->name, fun, p, d, k);
433                                 if (verbose < 2)
434                                         printk_once(
435                                             "%s: WARNING: ATAPI phase errors\n",
436                                             cd->name);
437                                 mdelay(1);
438                         }
439                         if (k++ > PCD_TMO) {
440                                 printk("%s: Stuck DRQ\n", cd->name);
441                                 break;
442                         }
443                         if (pcd_wait
444                             (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun,
445                              "completion")) {
446                                 r = -1;
447                                 break;
448                         }
449                 }
450         }
451
452         pi_disconnect(cd->pi);
453
454         return r;
455 }
456
457 static void pcd_req_sense(struct pcd_unit *cd, char *fun)
458 {
459         char rs_cmd[12] = { 0x03, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0 };
460         char buf[16];
461         int r, c;
462
463         r = pcd_command(cd, rs_cmd, 16, "Request sense");
464         mdelay(1);
465         if (!r)
466                 pcd_completion(cd, buf, "Request sense");
467
468         cd->last_sense = -1;
469         c = 2;
470         if (!r) {
471                 if (fun)
472                         printk("%s: %s: Sense key: %x, ASC: %x, ASQ: %x\n",
473                                cd->name, fun, buf[2] & 0xf, buf[12], buf[13]);
474                 c = buf[2] & 0xf;
475                 cd->last_sense =
476                     c | ((buf[12] & 0xff) << 8) | ((buf[13] & 0xff) << 16);
477         }
478         if ((c == 2) || (c == 6))
479                 cd->changed = 1;
480 }
481
482 static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun)
483 {
484         int r;
485
486         r = pcd_command(cd, cmd, dlen, fun);
487         mdelay(1);
488         if (!r)
489                 r = pcd_completion(cd, buf, fun);
490         if (r)
491                 pcd_req_sense(cd, fun);
492
493         return r;
494 }
495
496 static int pcd_packet(struct cdrom_device_info *cdi, struct packet_command *cgc)
497 {
498         return pcd_atapi(cdi->handle, cgc->cmd, cgc->buflen, cgc->buffer,
499                          "generic packet");
500 }
501
502 #define DBMSG(msg)      ((verbose>1)?(msg):NULL)
503
504 static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr)
505 {
506         struct pcd_unit *cd = cdi->handle;
507         int res = cd->changed;
508         if (res)
509                 cd->changed = 0;
510         return res;
511 }
512
513 static int pcd_lock_door(struct cdrom_device_info *cdi, int lock)
514 {
515         char un_cmd[12] = { 0x1e, 0, 0, 0, lock, 0, 0, 0, 0, 0, 0, 0 };
516
517         return pcd_atapi(cdi->handle, un_cmd, 0, pcd_scratch,
518                          lock ? "lock door" : "unlock door");
519 }
520
521 static int pcd_tray_move(struct cdrom_device_info *cdi, int position)
522 {
523         char ej_cmd[12] = { 0x1b, 0, 0, 0, 3 - position, 0, 0, 0, 0, 0, 0, 0 };
524
525         return pcd_atapi(cdi->handle, ej_cmd, 0, pcd_scratch,
526                          position ? "eject" : "close tray");
527 }
528
529 static void pcd_sleep(int cs)
530 {
531         schedule_timeout_interruptible(cs);
532 }
533
534 static int pcd_reset(struct pcd_unit *cd)
535 {
536         int i, k, flg;
537         int expect[5] = { 1, 1, 1, 0x14, 0xeb };
538
539         pi_connect(cd->pi);
540         write_reg(cd, 6, 0xa0 + 0x10 * cd->drive);
541         write_reg(cd, 7, 8);
542
543         pcd_sleep(20 * HZ / 1000);      /* delay a bit */
544
545         k = 0;
546         while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY))
547                 pcd_sleep(HZ / 10);
548
549         flg = 1;
550         for (i = 0; i < 5; i++)
551                 flg &= (read_reg(cd, i + 1) == expect[i]);
552
553         if (verbose) {
554                 printk("%s: Reset (%d) signature = ", cd->name, k);
555                 for (i = 0; i < 5; i++)
556                         printk("%3x", read_reg(cd, i + 1));
557                 if (!flg)
558                         printk(" (incorrect)");
559                 printk("\n");
560         }
561
562         pi_disconnect(cd->pi);
563         return flg - 1;
564 }
565
566 static int pcd_drive_reset(struct cdrom_device_info *cdi)
567 {
568         return pcd_reset(cdi->handle);
569 }
570
571 static int pcd_ready_wait(struct pcd_unit *cd, int tmo)
572 {
573         char tr_cmd[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
574         int k, p;
575
576         k = 0;
577         while (k < tmo) {
578                 cd->last_sense = 0;
579                 pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready"));
580                 p = cd->last_sense;
581                 if (!p)
582                         return 0;
583                 if (!(((p & 0xffff) == 0x0402) || ((p & 0xff) == 6)))
584                         return p;
585                 k++;
586                 pcd_sleep(HZ);
587         }
588         return 0x000020;        /* timeout */
589 }
590
591 static int pcd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
592 {
593         char rc_cmd[12] = { 0x25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
594         struct pcd_unit *cd = cdi->handle;
595
596         if (pcd_ready_wait(cd, PCD_READY_TMO))
597                 return CDS_DRIVE_NOT_READY;
598         if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media")))
599                 return CDS_NO_DISC;
600         return CDS_DISC_OK;
601 }
602
603 static int pcd_identify(struct pcd_unit *cd, char *id)
604 {
605         int k, s;
606         char id_cmd[12] = { 0x12, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 0 };
607
608         pcd_bufblk = -1;
609
610         s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify");
611
612         if (s)
613                 return -1;
614         if ((pcd_buffer[0] & 0x1f) != 5) {
615                 if (verbose)
616                         printk("%s: %s is not a CD-ROM\n",
617                                cd->name, cd->drive ? "Slave" : "Master");
618                 return -1;
619         }
620         memcpy(id, pcd_buffer + 16, 16);
621         id[16] = 0;
622         k = 16;
623         while ((k >= 0) && (id[k] <= 0x20)) {
624                 id[k] = 0;
625                 k--;
626         }
627
628         printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id);
629
630         return 0;
631 }
632
633 /*
634  * returns  0, with id set if drive is detected
635  *          -1, if drive detection failed
636  */
637 static int pcd_probe(struct pcd_unit *cd, int ms, char *id)
638 {
639         if (ms == -1) {
640                 for (cd->drive = 0; cd->drive <= 1; cd->drive++)
641                         if (!pcd_reset(cd) && !pcd_identify(cd, id))
642                                 return 0;
643         } else {
644                 cd->drive = ms;
645                 if (!pcd_reset(cd) && !pcd_identify(cd, id))
646                         return 0;
647         }
648         return -1;
649 }
650
651 static void pcd_probe_capabilities(void)
652 {
653         int unit, r;
654         char buffer[32];
655         char cmd[12] = { 0x5a, 1 << 3, 0x2a, 0, 0, 0, 0, 18, 0, 0, 0, 0 };
656         struct pcd_unit *cd;
657
658         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
659                 if (!cd->present)
660                         continue;
661                 r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities");
662                 if (r)
663                         continue;
664                 /* we should now have the cap page */
665                 if ((buffer[11] & 1) == 0)
666                         cd->info.mask |= CDC_CD_R;
667                 if ((buffer[11] & 2) == 0)
668                         cd->info.mask |= CDC_CD_RW;
669                 if ((buffer[12] & 1) == 0)
670                         cd->info.mask |= CDC_PLAY_AUDIO;
671                 if ((buffer[14] & 1) == 0)
672                         cd->info.mask |= CDC_LOCK;
673                 if ((buffer[14] & 8) == 0)
674                         cd->info.mask |= CDC_OPEN_TRAY;
675                 if ((buffer[14] >> 6) == 0)
676                         cd->info.mask |= CDC_CLOSE_TRAY;
677         }
678 }
679
680 static int pcd_detect(void)
681 {
682         char id[18];
683         int k, unit;
684         struct pcd_unit *cd;
685
686         printk("%s: %s version %s, major %d, nice %d\n",
687                name, name, PCD_VERSION, major, nice);
688
689         k = 0;
690         if (pcd_drive_count == 0) { /* nothing spec'd - so autoprobe for 1 */
691                 cd = pcd;
692                 if (pi_init(cd->pi, 1, -1, -1, -1, -1, -1, pcd_buffer,
693                             PI_PCD, verbose, cd->name)) {
694                         if (!pcd_probe(cd, -1, id) && cd->disk) {
695                                 cd->present = 1;
696                                 k++;
697                         } else
698                                 pi_release(cd->pi);
699                 }
700         } else {
701                 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
702                         int *conf = *drives[unit];
703                         if (!conf[D_PRT])
704                                 continue;
705                         if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD],
706                                      conf[D_UNI], conf[D_PRO], conf[D_DLY],
707                                      pcd_buffer, PI_PCD, verbose, cd->name)) 
708                                 continue;
709                         if (!pcd_probe(cd, conf[D_SLV], id) && cd->disk) {
710                                 cd->present = 1;
711                                 k++;
712                         } else
713                                 pi_release(cd->pi);
714                 }
715         }
716         if (k)
717                 return 0;
718
719         printk("%s: No CD-ROM drive found\n", name);
720         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
721                 put_disk(cd->disk);
722         return -1;
723 }
724
725 /* I/O request processing */
726 static struct request_queue *pcd_queue;
727
728 static void do_pcd_request(struct request_queue * q)
729 {
730         if (pcd_busy)
731                 return;
732         while (1) {
733                 if (!pcd_req) {
734                         pcd_req = blk_fetch_request(q);
735                         if (!pcd_req)
736                                 return;
737                 }
738
739                 if (rq_data_dir(pcd_req) == READ) {
740                         struct pcd_unit *cd = pcd_req->rq_disk->private_data;
741                         if (cd != pcd_current)
742                                 pcd_bufblk = -1;
743                         pcd_current = cd;
744                         pcd_sector = blk_rq_pos(pcd_req);
745                         pcd_count = blk_rq_cur_sectors(pcd_req);
746                         pcd_buf = pcd_req->buffer;
747                         pcd_busy = 1;
748                         ps_set_intr(do_pcd_read, NULL, 0, nice);
749                         return;
750                 } else {
751                         __blk_end_request_all(pcd_req, -EIO);
752                         pcd_req = NULL;
753                 }
754         }
755 }
756
757 static inline void next_request(int err)
758 {
759         unsigned long saved_flags;
760
761         spin_lock_irqsave(&pcd_lock, saved_flags);
762         if (!__blk_end_request_cur(pcd_req, err))
763                 pcd_req = NULL;
764         pcd_busy = 0;
765         do_pcd_request(pcd_queue);
766         spin_unlock_irqrestore(&pcd_lock, saved_flags);
767 }
768
769 static int pcd_ready(void)
770 {
771         return (((status_reg(pcd_current) & (IDE_BUSY | IDE_DRQ)) == IDE_DRQ));
772 }
773
774 static void pcd_transfer(void)
775 {
776
777         while (pcd_count && (pcd_sector / 4 == pcd_bufblk)) {
778                 int o = (pcd_sector % 4) * 512;
779                 memcpy(pcd_buf, pcd_buffer + o, 512);
780                 pcd_count--;
781                 pcd_buf += 512;
782                 pcd_sector++;
783         }
784 }
785
786 static void pcd_start(void)
787 {
788         int b, i;
789         char rd_cmd[12] = { 0xa8, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 };
790
791         pcd_bufblk = pcd_sector / 4;
792         b = pcd_bufblk;
793         for (i = 0; i < 4; i++) {
794                 rd_cmd[5 - i] = b & 0xff;
795                 b = b >> 8;
796         }
797
798         if (pcd_command(pcd_current, rd_cmd, 2048, "read block")) {
799                 pcd_bufblk = -1;
800                 next_request(-EIO);
801                 return;
802         }
803
804         mdelay(1);
805
806         ps_set_intr(do_pcd_read_drq, pcd_ready, PCD_TMO, nice);
807 }
808
809 static void do_pcd_read(void)
810 {
811         pcd_busy = 1;
812         pcd_retries = 0;
813         pcd_transfer();
814         if (!pcd_count) {
815                 next_request(0);
816                 return;
817         }
818
819         pi_do_claimed(pcd_current->pi, pcd_start);
820 }
821
822 static void do_pcd_read_drq(void)
823 {
824         unsigned long saved_flags;
825
826         if (pcd_completion(pcd_current, pcd_buffer, "read block")) {
827                 if (pcd_retries < PCD_RETRIES) {
828                         mdelay(1);
829                         pcd_retries++;
830                         pi_do_claimed(pcd_current->pi, pcd_start);
831                         return;
832                 }
833                 pcd_bufblk = -1;
834                 next_request(-EIO);
835                 return;
836         }
837
838         do_pcd_read();
839         spin_lock_irqsave(&pcd_lock, saved_flags);
840         do_pcd_request(pcd_queue);
841         spin_unlock_irqrestore(&pcd_lock, saved_flags);
842 }
843
844 /* the audio_ioctl stuff is adapted from sr_ioctl.c */
845
846 static int pcd_audio_ioctl(struct cdrom_device_info *cdi, unsigned int cmd, void *arg)
847 {
848         struct pcd_unit *cd = cdi->handle;
849
850         switch (cmd) {
851
852         case CDROMREADTOCHDR:
853
854                 {
855                         char cmd[12] =
856                             { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
857                          0, 0, 0 };
858                         struct cdrom_tochdr *tochdr =
859                             (struct cdrom_tochdr *) arg;
860                         char buffer[32];
861                         int r;
862
863                         r = pcd_atapi(cd, cmd, 12, buffer, "read toc header");
864
865                         tochdr->cdth_trk0 = buffer[2];
866                         tochdr->cdth_trk1 = buffer[3];
867
868                         return r ? -EIO : 0;
869                 }
870
871         case CDROMREADTOCENTRY:
872
873                 {
874                         char cmd[12] =
875                             { GPCMD_READ_TOC_PMA_ATIP, 0, 0, 0, 0, 0, 0, 0, 12,
876                          0, 0, 0 };
877
878                         struct cdrom_tocentry *tocentry =
879                             (struct cdrom_tocentry *) arg;
880                         unsigned char buffer[32];
881                         int r;
882
883                         cmd[1] =
884                             (tocentry->cdte_format == CDROM_MSF ? 0x02 : 0);
885                         cmd[6] = tocentry->cdte_track;
886
887                         r = pcd_atapi(cd, cmd, 12, buffer, "read toc entry");
888
889                         tocentry->cdte_ctrl = buffer[5] & 0xf;
890                         tocentry->cdte_adr = buffer[5] >> 4;
891                         tocentry->cdte_datamode =
892                             (tocentry->cdte_ctrl & 0x04) ? 1 : 0;
893                         if (tocentry->cdte_format == CDROM_MSF) {
894                                 tocentry->cdte_addr.msf.minute = buffer[9];
895                                 tocentry->cdte_addr.msf.second = buffer[10];
896                                 tocentry->cdte_addr.msf.frame = buffer[11];
897                         } else
898                                 tocentry->cdte_addr.lba =
899                                     (((((buffer[8] << 8) + buffer[9]) << 8)
900                                       + buffer[10]) << 8) + buffer[11];
901
902                         return r ? -EIO : 0;
903                 }
904
905         default:
906
907                 return -ENOSYS;
908         }
909 }
910
911 static int pcd_get_mcn(struct cdrom_device_info *cdi, struct cdrom_mcn *mcn)
912 {
913         char cmd[12] =
914             { GPCMD_READ_SUBCHANNEL, 0, 0x40, 2, 0, 0, 0, 0, 24, 0, 0, 0 };
915         char buffer[32];
916
917         if (pcd_atapi(cdi->handle, cmd, 24, buffer, "get mcn"))
918                 return -EIO;
919
920         memcpy(mcn->medium_catalog_number, buffer + 9, 13);
921         mcn->medium_catalog_number[13] = 0;
922
923         return 0;
924 }
925
926 static int __init pcd_init(void)
927 {
928         struct pcd_unit *cd;
929         int unit;
930
931         if (disable)
932                 return -EINVAL;
933
934         pcd_init_units();
935
936         if (pcd_detect())
937                 return -ENODEV;
938
939         /* get the atapi capabilities page */
940         pcd_probe_capabilities();
941
942         if (register_blkdev(major, name)) {
943                 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
944                         put_disk(cd->disk);
945                 return -EBUSY;
946         }
947
948         pcd_queue = blk_init_queue(do_pcd_request, &pcd_lock);
949         if (!pcd_queue) {
950                 unregister_blkdev(major, name);
951                 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++)
952                         put_disk(cd->disk);
953                 return -ENOMEM;
954         }
955
956         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
957                 if (cd->present) {
958                         register_cdrom(&cd->info);
959                         cd->disk->private_data = cd;
960                         cd->disk->queue = pcd_queue;
961                         add_disk(cd->disk);
962                 }
963         }
964
965         return 0;
966 }
967
968 static void __exit pcd_exit(void)
969 {
970         struct pcd_unit *cd;
971         int unit;
972
973         for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) {
974                 if (cd->present) {
975                         del_gendisk(cd->disk);
976                         pi_release(cd->pi);
977                         unregister_cdrom(&cd->info);
978                 }
979                 put_disk(cd->disk);
980         }
981         blk_cleanup_queue(pcd_queue);
982         unregister_blkdev(major, name);
983 }
984
985 MODULE_LICENSE("GPL");
986 module_init(pcd_init)
987 module_exit(pcd_exit)