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