Lines Matching full:cd
5 This is a high-level driver for parallel port ATAPI CD-ROM
9 port ATAPI CD-ROM drive, but if their individual parameters are
41 <slv> ATAPI CD-ROMs can be jumpered to master or slave.
97 1.05 GRG 1998.08.16 Conformed to "Uniform CD-ROM" standard
211 static int pcd_bufblk = -1; /* block in buffer, in CD units,
233 struct pcd_unit *cd = bdev->bd_disk->private_data; in pcd_block_open() local
239 ret = cdrom_open(&cd->info, bdev, mode); in pcd_block_open()
247 struct pcd_unit *cd = disk->private_data; in pcd_block_release() local
249 cdrom_release(&cd->info, mode); in pcd_block_release()
256 struct pcd_unit *cd = bdev->bd_disk->private_data; in pcd_block_ioctl() local
260 ret = cdrom_ioctl(&cd->info, bdev, mode, cmd, arg); in pcd_block_ioctl()
269 struct pcd_unit *cd = disk->private_data; in pcd_block_check_events() local
270 return cdrom_check_events(&cd->info, clearing); in pcd_block_check_events()
307 struct pcd_unit *cd; in pcd_init_units() local
311 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { in pcd_init_units()
317 disk->queue = blk_mq_init_sq_queue(&cd->tag_set, &pcd_mq_ops, in pcd_init_units()
325 INIT_LIST_HEAD(&cd->rq_list); in pcd_init_units()
326 disk->queue->queuedata = cd; in pcd_init_units()
328 cd->disk = disk; in pcd_init_units()
329 cd->pi = &cd->pia; in pcd_init_units()
330 cd->present = 0; in pcd_init_units()
331 cd->last_sense = 0; in pcd_init_units()
332 cd->changed = 1; in pcd_init_units()
333 cd->drive = (*drives[unit])[D_SLV]; in pcd_init_units()
337 cd->name = &cd->info.name[0]; in pcd_init_units()
338 snprintf(cd->name, sizeof(cd->info.name), "%s%d", name, unit); in pcd_init_units()
339 cd->info.ops = &pcd_dops; in pcd_init_units()
340 cd->info.handle = cd; in pcd_init_units()
341 cd->info.speed = 0; in pcd_init_units()
342 cd->info.capacity = 1; in pcd_init_units()
343 cd->info.mask = 0; in pcd_init_units()
346 strcpy(disk->disk_name, cd->name); /* umm... */ in pcd_init_units()
355 struct pcd_unit *cd = cdi->handle; in pcd_open() local
356 if (!cd->present) in pcd_open()
365 static inline int status_reg(struct pcd_unit *cd) in status_reg() argument
367 return pi_read_regr(cd->pi, 1, 6); in status_reg()
370 static inline int read_reg(struct pcd_unit *cd, int reg) in read_reg() argument
372 return pi_read_regr(cd->pi, 0, reg); in read_reg()
375 static inline void write_reg(struct pcd_unit *cd, int reg, int val) in write_reg() argument
377 pi_write_regr(cd->pi, 0, reg, val); in write_reg()
380 static int pcd_wait(struct pcd_unit *cd, int go, int stop, char *fun, char *msg) in pcd_wait() argument
385 while ((((r = status_reg(cd)) & go) || (stop && (!(r & stop)))) in pcd_wait()
390 s = read_reg(cd, 7); in pcd_wait()
391 e = read_reg(cd, 1); in pcd_wait()
392 p = read_reg(cd, 2); in pcd_wait()
398 cd->name, fun, msg, r, s, e, j, p); in pcd_wait()
404 static int pcd_command(struct pcd_unit *cd, char *cmd, int dlen, char *fun) in pcd_command() argument
406 pi_connect(cd->pi); in pcd_command()
408 write_reg(cd, 6, 0xa0 + 0x10 * cd->drive); in pcd_command()
410 if (pcd_wait(cd, IDE_BUSY | IDE_DRQ, 0, fun, "before command")) { in pcd_command()
411 pi_disconnect(cd->pi); in pcd_command()
415 write_reg(cd, 4, dlen % 256); in pcd_command()
416 write_reg(cd, 5, dlen / 256); in pcd_command()
417 write_reg(cd, 7, 0xa0); /* ATAPI packet command */ in pcd_command()
419 if (pcd_wait(cd, IDE_BUSY, IDE_DRQ, fun, "command DRQ")) { in pcd_command()
420 pi_disconnect(cd->pi); in pcd_command()
424 if (read_reg(cd, 2) != 1) { in pcd_command()
425 printk("%s: %s: command phase error\n", cd->name, fun); in pcd_command()
426 pi_disconnect(cd->pi); in pcd_command()
430 pi_write_block(cd->pi, cmd, 12); in pcd_command()
435 static int pcd_completion(struct pcd_unit *cd, char *buf, char *fun) in pcd_completion() argument
443 if (!pcd_wait(cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, in pcd_completion()
446 while (read_reg(cd, 7) & IDE_DRQ) { in pcd_completion()
447 d = read_reg(cd, 4) + 256 * read_reg(cd, 5); in pcd_completion()
449 p = read_reg(cd, 2) & 3; in pcd_completion()
452 pi_read_block(cd->pi, buf, n); in pcd_completion()
455 cd->name, fun, n); in pcd_completion()
462 cd->name, fun, p, d, k); in pcd_completion()
466 cd->name); in pcd_completion()
470 printk("%s: Stuck DRQ\n", cd->name); in pcd_completion()
474 (cd, IDE_BUSY, IDE_DRQ | IDE_READY | IDE_ERR, fun, in pcd_completion()
482 pi_disconnect(cd->pi); in pcd_completion()
487 static void pcd_req_sense(struct pcd_unit *cd, char *fun) in pcd_req_sense() argument
493 r = pcd_command(cd, rs_cmd, 16, "Request sense"); in pcd_req_sense()
496 pcd_completion(cd, buf, "Request sense"); in pcd_req_sense()
498 cd->last_sense = -1; in pcd_req_sense()
503 cd->name, fun, buf[2] & 0xf, buf[12], buf[13]); in pcd_req_sense()
505 cd->last_sense = in pcd_req_sense()
509 cd->changed = 1; in pcd_req_sense()
512 static int pcd_atapi(struct pcd_unit *cd, char *cmd, int dlen, char *buf, char *fun) in pcd_atapi() argument
516 r = pcd_command(cd, cmd, dlen, fun); in pcd_atapi()
519 r = pcd_completion(cd, buf, fun); in pcd_atapi()
521 pcd_req_sense(cd, fun); in pcd_atapi()
537 struct pcd_unit *cd = cdi->handle; in pcd_check_events() local
538 int res = cd->changed; in pcd_check_events()
540 cd->changed = 0; in pcd_check_events()
565 static int pcd_reset(struct pcd_unit *cd) in pcd_reset() argument
570 pi_connect(cd->pi); in pcd_reset()
571 write_reg(cd, 6, 0xa0 + 0x10 * cd->drive); in pcd_reset()
572 write_reg(cd, 7, 8); in pcd_reset()
577 while ((k++ < PCD_RESET_TMO) && (status_reg(cd) & IDE_BUSY)) in pcd_reset()
582 flg &= (read_reg(cd, i + 1) == expect[i]); in pcd_reset()
585 printk("%s: Reset (%d) signature = ", cd->name, k); in pcd_reset()
587 printk("%3x", read_reg(cd, i + 1)); in pcd_reset()
593 pi_disconnect(cd->pi); in pcd_reset()
602 static int pcd_ready_wait(struct pcd_unit *cd, int tmo) in pcd_ready_wait() argument
609 cd->last_sense = 0; in pcd_ready_wait()
610 pcd_atapi(cd, tr_cmd, 0, NULL, DBMSG("test unit ready")); in pcd_ready_wait()
611 p = cd->last_sense; in pcd_ready_wait()
625 struct pcd_unit *cd = cdi->handle; in pcd_drive_status() local
627 if (pcd_ready_wait(cd, PCD_READY_TMO)) in pcd_drive_status()
629 if (pcd_atapi(cd, rc_cmd, 8, pcd_scratch, DBMSG("check media"))) in pcd_drive_status()
634 static int pcd_identify(struct pcd_unit *cd, char *id) in pcd_identify() argument
641 s = pcd_atapi(cd, id_cmd, 36, pcd_buffer, "identify"); in pcd_identify()
647 printk("%s: %s is not a CD-ROM\n", in pcd_identify()
648 cd->name, cd->drive ? "Slave" : "Master"); in pcd_identify()
659 printk("%s: %s: %s\n", cd->name, cd->drive ? "Slave" : "Master", id); in pcd_identify()
668 static int pcd_probe(struct pcd_unit *cd, int ms, char *id) in pcd_probe() argument
671 for (cd->drive = 0; cd->drive <= 1; cd->drive++) in pcd_probe()
672 if (!pcd_reset(cd) && !pcd_identify(cd, id)) in pcd_probe()
675 cd->drive = ms; in pcd_probe()
676 if (!pcd_reset(cd) && !pcd_identify(cd, id)) in pcd_probe()
687 struct pcd_unit *cd; in pcd_probe_capabilities() local
689 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { in pcd_probe_capabilities()
690 if (!cd->present) in pcd_probe_capabilities()
692 r = pcd_atapi(cd, cmd, 18, buffer, "mode sense capabilities"); in pcd_probe_capabilities()
697 cd->info.mask |= CDC_CD_R; in pcd_probe_capabilities()
699 cd->info.mask |= CDC_CD_RW; in pcd_probe_capabilities()
701 cd->info.mask |= CDC_PLAY_AUDIO; in pcd_probe_capabilities()
703 cd->info.mask |= CDC_LOCK; in pcd_probe_capabilities()
705 cd->info.mask |= CDC_OPEN_TRAY; in pcd_probe_capabilities()
707 cd->info.mask |= CDC_CLOSE_TRAY; in pcd_probe_capabilities()
715 struct pcd_unit *cd; in pcd_detect() local
728 cd = pcd; in pcd_detect()
729 if (cd->disk && pi_init(cd->pi, 1, -1, -1, -1, -1, -1, in pcd_detect()
730 pcd_buffer, PI_PCD, verbose, cd->name)) { in pcd_detect()
731 if (!pcd_probe(cd, -1, id)) { in pcd_detect()
732 cd->present = 1; in pcd_detect()
735 pi_release(cd->pi); in pcd_detect()
738 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { in pcd_detect()
742 if (!cd->disk) in pcd_detect()
744 if (!pi_init(cd->pi, 0, conf[D_PRT], conf[D_MOD], in pcd_detect()
746 pcd_buffer, PI_PCD, verbose, cd->name)) in pcd_detect()
748 if (!pcd_probe(cd, conf[D_SLV], id)) { in pcd_detect()
749 cd->present = 1; in pcd_detect()
752 pi_release(cd->pi); in pcd_detect()
758 printk("%s: No CD-ROM drive found\n", name); in pcd_detect()
759 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { in pcd_detect()
760 if (!cd->disk) in pcd_detect()
762 blk_cleanup_queue(cd->disk->queue); in pcd_detect()
763 cd->disk->queue = NULL; in pcd_detect()
764 blk_mq_free_tag_set(&cd->tag_set); in pcd_detect()
765 put_disk(cd->disk); in pcd_detect()
776 struct pcd_unit *cd; in set_next_request() local
780 cd = &pcd[pcd_queue]; in set_next_request()
783 if (cd->present && !list_empty(&cd->rq_list)) { in set_next_request()
784 pcd_req = list_first_entry(&cd->rq_list, struct request, in set_next_request()
797 struct pcd_unit *cd; in pcd_request() local
805 cd = pcd_req->rq_disk->private_data; in pcd_request()
806 if (cd != pcd_current) in pcd_request()
808 pcd_current = cd; in pcd_request()
819 struct pcd_unit *cd = hctx->queue->queuedata; in pcd_queue_rq() local
827 list_add_tail(&bd->rq->queuelist, &cd->rq_list); in pcd_queue_rq()
927 struct pcd_unit *cd = cdi->handle; in pcd_audio_ioctl() local
942 r = pcd_atapi(cd, cmd, 12, buffer, "read toc header"); in pcd_audio_ioctl()
966 r = pcd_atapi(cd, cmd, 12, buffer, "read toc entry"); in pcd_audio_ioctl()
1007 struct pcd_unit *cd; in pcd_init() local
1022 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { in pcd_init()
1023 if (!cd->disk) in pcd_init()
1026 blk_cleanup_queue(cd->disk->queue); in pcd_init()
1027 blk_mq_free_tag_set(&cd->tag_set); in pcd_init()
1028 put_disk(cd->disk); in pcd_init()
1033 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { in pcd_init()
1034 if (cd->present) { in pcd_init()
1035 register_cdrom(cd->disk, &cd->info); in pcd_init()
1036 cd->disk->private_data = cd; in pcd_init()
1037 add_disk(cd->disk); in pcd_init()
1046 struct pcd_unit *cd; in pcd_exit() local
1049 for (unit = 0, cd = pcd; unit < PCD_UNITS; unit++, cd++) { in pcd_exit()
1050 if (!cd->disk) in pcd_exit()
1053 if (cd->present) { in pcd_exit()
1054 del_gendisk(cd->disk); in pcd_exit()
1055 pi_release(cd->pi); in pcd_exit()
1056 unregister_cdrom(&cd->info); in pcd_exit()
1058 blk_cleanup_queue(cd->disk->queue); in pcd_exit()
1059 blk_mq_free_tag_set(&cd->tag_set); in pcd_exit()
1060 put_disk(cd->disk); in pcd_exit()