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