mcd.c (1120) | mcd.c (1197) |
---|---|
1/* 2 * Copyright 1993 by Holger Veit (data part) 3 * Copyright 1993 by Brian Moore (audio part) | 1/* 2 * Copyright 1993 by Holger Veit (data part) 3 * Copyright 1993 by Brian Moore (audio part) |
4 * Changes Copyright 1993 by Gary Clark II | 4 * Changes Copyright 1993 by Gary Clark II 5 * 6 * Rewrote probe routine to work on newer Mitsumi drives. 7 * Additional changes (C) 1994 by Jordan K. Hubbard 8 * |
5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This software was developed by Holger Veit and Brian Moore | 9 * All rights reserved. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. Redistributions in binary form must reproduce the above copyright 17 * notice, this list of conditions and the following disclaimer in the 18 * documentation and/or other materials provided with the distribution. 19 * 3. All advertising materials mentioning features or use of this software 20 * must display the following acknowledgement: 21 * This software was developed by Holger Veit and Brian Moore |
18 * for use with "386BSD" and similar operating systems. | 22 * for use with "386BSD" and similar operating systems. |
19 * "Similar operating systems" includes mainly non-profit oriented 20 * systems for research and education, including but not restricted to 21 * "NetBSD", "FreeBSD", "Mach" (by CMU). 22 * 4. Neither the name of the developer(s) nor the name "386BSD" 23 * may be used to endorse or promote products derived from this 24 * software without specific prior written permission. 25 * 26 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``AS IS'' AND ANY 27 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER(S) BE 30 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 31 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 32 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 33 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 34 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 35 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 36 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 * | 23 * "Similar operating systems" includes mainly non-profit oriented 24 * systems for research and education, including but not restricted to 25 * "NetBSD", "FreeBSD", "Mach" (by CMU). 26 * 4. Neither the name of the developer(s) nor the name "386BSD" 27 * may be used to endorse or promote products derived from this 28 * software without specific prior written permission. 29 * 30 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPER(S) ``AS IS'' AND ANY 31 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 32 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 33 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE DEVELOPER(S) BE 34 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 35 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 36 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 37 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 38 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 39 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 40 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 41 * |
38 * $Id: mcd.c,v 1.8 1994/02/06 11:33:25 rgrimes Exp $ | 42 * $Id: mcd.c,v 1.9 1994/02/07 15:46:22 davidg Exp $ |
39 */ 40static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; 41 42#include "mcd.h" 43#if NMCD > 0 44#include "types.h" 45#include "param.h" 46#include "systm.h" --- 474 unchanged lines hidden (view full) --- 521 return -1; 522} 523 524/*************************************************************** 525 * lower level of driver starts here 526 **************************************************************/ 527 528#ifdef NOTDEF | 43 */ 44static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; 45 46#include "mcd.h" 47#if NMCD > 0 48#include "types.h" 49#include "param.h" 50#include "systm.h" --- 474 unchanged lines hidden (view full) --- 525 return -1; 526} 527 528/*************************************************************** 529 * lower level of driver starts here 530 **************************************************************/ 531 532#ifdef NOTDEF |
529static char irqs[] = { | 533static char 534irqs[] = { |
530 0x00,0x00,0x10,0x20,0x00,0x30,0x00,0x00, 531 0x00,0x10,0x40,0x50,0x00,0x00,0x00,0x00 532}; 533 | 535 0x00,0x00,0x10,0x20,0x00,0x30,0x00,0x00, 536 0x00,0x10,0x40,0x50,0x00,0x00,0x00,0x00 537}; 538 |
534static char drqs[] = { | 539static char 540drqs[] = { |
535 0x00,0x01,0x00,0x03,0x00,0x05,0x06,0x07, 536}; 537#endif 538 | 541 0x00,0x01,0x00,0x03,0x00,0x05,0x06,0x07, 542}; 543#endif 544 |
539static void mcd_configure(struct mcd_data *cd) | 545static void 546mcd_configure(struct mcd_data *cd) |
540{ 541 outb(cd->iobase+mcd_config,cd->config); 542} 543 | 547{ 548 outb(cd->iobase+mcd_config,cd->config); 549} 550 |
551/* Wait for non-busy - return 0 on timeout */ 552static int 553twiddle_thumbs(int port, int unit, int count, char *whine) 554{ 555 int i; 556 557 for (i = 0; i < count; i++) { 558 if (!(inb(port+MCD_FLAGS) & MCD_ST_BUSY)) { 559 return 1; 560 } 561 } 562#ifdef MCD_TO_WARNING_ON 563 printf("mcd%d: timeout %s\n", unit, whine); 564#endif 565 return 0; 566} 567 |
|
544/* check to see if a Mitsumi CD-ROM is attached to the ISA bus */ 545 | 568/* check to see if a Mitsumi CD-ROM is attached to the ISA bus */ 569 |
546int mcd_probe(struct isa_device *dev) | 570int 571mcd_probe(struct isa_device *dev) |
547{ 548 int port = dev->id_iobase; 549 int unit = dev->id_unit; | 572{ 573 int port = dev->id_iobase; 574 int unit = dev->id_unit; |
550 int i,j; 551 int st; 552 int check; 553 int junk; | 575 int i, j; 576 int status; 577 unsigned char stbytes[3]; |
554 555 mcd_data[unit].flags = MCDPROBING; 556 557#ifdef NOTDEF 558 /* get irq/drq configuration word */ 559 mcd_data[unit].config = irqs[dev->id_irq]; /* | drqs[dev->id_drq];*/ 560#else 561 mcd_data[unit].config = 0; 562#endif 563 564 /* send a reset */ | 578 579 mcd_data[unit].flags = MCDPROBING; 580 581#ifdef NOTDEF 582 /* get irq/drq configuration word */ 583 mcd_data[unit].config = irqs[dev->id_irq]; /* | drqs[dev->id_drq];*/ 584#else 585 mcd_data[unit].config = 0; 586#endif 587 588 /* send a reset */ |
565 outb(port+MCD_FLAGS,M_RESET); 566 DELAY(3000); | 589 outb(port+MCD_FLAGS, M_RESET); |
567 | 590 |
568 for (j=3; j != 0; j--) { | 591 /* 592 * delay awhile by getting any pending garbage (old data) and 593 * throwing it away. 594 */ 595 for (i = 1000000; i != 0; i--) { 596 inb(port+MCD_FLAGS); 597 } |
569 | 598 |
570 /* get any pending garbage (old data) and throw away...*/ 571 for (i=10; i != 0; i--) { 572 inb(port+MCD_DATA); 573 } | 599 /* Get status */ 600 outb(port+MCD_DATA, MCD_CMDGETSTAT); 601 if (!twiddle_thumbs(port, unit, 1000000, "getting status")) { 602 return 0; /* Timeout */ 603 } 604 status = inb(port+MCD_DATA); |
574 | 605 |
575 DELAY (2000); 576 outb(port+MCD_DATA,MCD_CMDCONTINFO); 577 for (i = 0; i < 30000; i++) { 578 if ((inb(port+MCD_FLAGS) & M_STATUS_AVAIL) == M_STATUS_AVAIL) 579 { 580 DELAY (600); 581 st = inb(port+MCD_DATA); 582 DELAY (500); 583 check = inb(port+MCD_DATA); 584 DELAY (500); 585 junk = inb(port+MCD_DATA); /* What is byte used for?!?!? */ 586 587 if (check == 'M') { 588#ifdef DEBUG 589 printf("Mitsumi drive detected\n"); 590#endif 591 return 4; 592 } else { 593 printf("Mitsumi drive NOT detected\n"); 594 return 0; 595 } 596 } 597 } 598 } 599 return 0; | 606 /* Get version information */ 607 outb(port+MCD_DATA, MCD_CMDCONTINFO); 608 for (j = 0; j < 3; j++) { 609 if (!twiddle_thumbs(port, unit, 3000, "getting version info")) { 610 return 0; 611 } 612 stbytes[j] = (inb(port+MCD_DATA) & 0xFF); 613 } 614 printf("mcd%d: version information is %x %c %x\n", unit, 615 stbytes[0], stbytes[1], stbytes[2]); 616 if (stbytes[1] >= 4) { 617 outb(port+MCD_CTRL, M_PICKLE); 618 printf("mcd%d: Adjusted for newer drive model\n", unit); 619 } 620 return 4; |
600} 601 602 | 621} 622 623 |
603static int mcd_waitrdy(int port,int dly) | 624static int 625mcd_waitrdy(int port,int dly) |
604{ 605 int i; 606 607 /* wait until xfer port senses data ready */ 608 for (i=0; i<dly; i++) { 609 if ((inb(port+mcd_xfer) & MCD_ST_BUSY)==0) 610 return 0; 611 mcd_delay(1); 612 } 613 return -1; 614} 615 | 626{ 627 int i; 628 629 /* wait until xfer port senses data ready */ 630 for (i=0; i<dly; i++) { 631 if ((inb(port+mcd_xfer) & MCD_ST_BUSY)==0) 632 return 0; 633 mcd_delay(1); 634 } 635 return -1; 636} 637 |
616static int mcd_getreply(int unit,int dly) | 638static int 639mcd_getreply(int unit,int dly) |
617{ 618 int i; 619 struct mcd_data *cd = mcd_data + unit; 620 int port = cd->iobase; 621 622 /* wait data to become ready */ 623 if (mcd_waitrdy(port,dly)<0) { 624#ifdef MCD_TO_WARNING_ON 625 printf("mcd%d: timeout getreply\n",unit); 626#endif 627 return -1; 628 } 629 630 /* get the data */ 631 return inb(port+mcd_status) & 0xFF; 632} 633 | 640{ 641 int i; 642 struct mcd_data *cd = mcd_data + unit; 643 int port = cd->iobase; 644 645 /* wait data to become ready */ 646 if (mcd_waitrdy(port,dly)<0) { 647#ifdef MCD_TO_WARNING_ON 648 printf("mcd%d: timeout getreply\n",unit); 649#endif 650 return -1; 651 } 652 653 /* get the data */ 654 return inb(port+mcd_status) & 0xFF; 655} 656 |
634static int mcd_getstat(int unit,int sflg) | 657static int 658mcd_getstat(int unit,int sflg) |
635{ 636 int i; 637 struct mcd_data *cd = mcd_data + unit; 638 int port = cd->iobase; 639 640 /* get the status */ 641 if (sflg) 642 outb(port+mcd_command, MCD_CMDGETSTAT); 643 i = mcd_getreply(unit,DELAY_GETREPLY); 644 if (i<0) return -1; 645 646 cd->status = i; 647 648 mcd_setflags(unit,cd); 649 return cd->status; 650} 651 | 659{ 660 int i; 661 struct mcd_data *cd = mcd_data + unit; 662 int port = cd->iobase; 663 664 /* get the status */ 665 if (sflg) 666 outb(port+mcd_command, MCD_CMDGETSTAT); 667 i = mcd_getreply(unit,DELAY_GETREPLY); 668 if (i<0) return -1; 669 670 cd->status = i; 671 672 mcd_setflags(unit,cd); 673 return cd->status; 674} 675 |
652static void mcd_setflags(int unit, struct mcd_data *cd) | 676static void 677mcd_setflags(int unit, struct mcd_data *cd) |
653{ 654 /* check flags */ 655 if (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) { 656 MCD_TRACE("getstat: sensed DSKCHNG or DOOROPEN\n",0,0,0,0); 657 cd->flags &= ~MCDVALID; 658 } 659 660#ifndef MCDMINI 661 if (cd->status & MCDAUDIOBSY) 662 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 663 else if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) 664 cd->audio_status = CD_AS_PLAY_COMPLETED; 665#endif 666} 667 | 678{ 679 /* check flags */ 680 if (cd->status & (MCDDSKCHNG|MCDDOOROPEN)) { 681 MCD_TRACE("getstat: sensed DSKCHNG or DOOROPEN\n",0,0,0,0); 682 cd->flags &= ~MCDVALID; 683 } 684 685#ifndef MCDMINI 686 if (cd->status & MCDAUDIOBSY) 687 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 688 else if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) 689 cd->audio_status = CD_AS_PLAY_COMPLETED; 690#endif 691} 692 |
668static int mcd_get(int unit, char *buf, int nmax) | 693static int 694mcd_get(int unit, char *buf, int nmax) |
669{ 670 int port = mcd_data[unit].iobase; 671 int i,k; 672 673 for (i=0; i<nmax; i++) { | 695{ 696 int port = mcd_data[unit].iobase; 697 int i,k; 698 699 for (i=0; i<nmax; i++) { |
674 | |
675 /* wait for data */ 676 if ((k = mcd_getreply(unit,DELAY_GETREPLY)) < 0) { 677#ifdef MCD_TO_WARNING_ON 678 printf("mcd%d: timeout mcd_get\n",unit); 679#endif 680 return -1; 681 } 682 buf[i] = k; 683 } 684 return i; 685} 686 | 700 /* wait for data */ 701 if ((k = mcd_getreply(unit,DELAY_GETREPLY)) < 0) { 702#ifdef MCD_TO_WARNING_ON 703 printf("mcd%d: timeout mcd_get\n",unit); 704#endif 705 return -1; 706 } 707 buf[i] = k; 708 } 709 return i; 710} 711 |
687static int mcd_send(int unit, int cmd,int nretrys) | 712static int 713mcd_send(int unit, int cmd,int nretrys) |
688{ 689 int i,k; 690 int port = mcd_data[unit].iobase; 691 692/*MCD_TRACE("mcd_send: command = 0x%x\n",cmd,0,0,0);*/ 693 for (i=0; i<nretrys; i++) { 694 outb(port+mcd_command, cmd); | 714{ 715 int i,k; 716 int port = mcd_data[unit].iobase; 717 718/*MCD_TRACE("mcd_send: command = 0x%x\n",cmd,0,0,0);*/ 719 for (i=0; i<nretrys; i++) { 720 outb(port+mcd_command, cmd); |
695 if ((k=mcd_getstat(unit,0)) != -1) | 721 if ((k=mcd_getstat(unit,0)) != -1) { |
696 break; | 722 break; |
723 } |
|
697 } 698 if (i == nretrys) { 699 printf("mcd%d: mcd_send retry cnt exceeded\n",unit); 700 return -1; 701 } 702/*MCD_TRACE("mcd_send: status = 0x%x\n",k,0,0,0);*/ 703 return 0; 704} 705 | 724 } 725 if (i == nretrys) { 726 printf("mcd%d: mcd_send retry cnt exceeded\n",unit); 727 return -1; 728 } 729/*MCD_TRACE("mcd_send: status = 0x%x\n",k,0,0,0);*/ 730 return 0; 731} 732 |
706static int bcd2bin(bcd_t b) | 733static int 734bcd2bin(bcd_t b) |
707{ 708 return (b >> 4) * 10 + (b & 15); 709} 710 | 735{ 736 return (b >> 4) * 10 + (b & 15); 737} 738 |
711static bcd_t bin2bcd(int b) | 739static bcd_t 740bin2bcd(int b) |
712{ 713 return ((b / 10) << 4) | (b % 10); 714} 715 | 741{ 742 return ((b / 10) << 4) | (b % 10); 743} 744 |
716static void hsg2msf(int hsg, bcd_t *msf) | 745static void 746hsg2msf(int hsg, bcd_t *msf) |
717{ 718 hsg += 150; 719 M_msf(msf) = bin2bcd(hsg / 4500); 720 hsg %= 4500; 721 S_msf(msf) = bin2bcd(hsg / 75); 722 F_msf(msf) = bin2bcd(hsg % 75); 723} 724 | 747{ 748 hsg += 150; 749 M_msf(msf) = bin2bcd(hsg / 4500); 750 hsg %= 4500; 751 S_msf(msf) = bin2bcd(hsg / 75); 752 F_msf(msf) = bin2bcd(hsg % 75); 753} 754 |
725static int msf2hsg(bcd_t *msf) | 755static int 756msf2hsg(bcd_t *msf) |
726{ 727 return (bcd2bin(M_msf(msf)) * 60 + 728 bcd2bin(S_msf(msf))) * 75 + 729 bcd2bin(F_msf(msf)) - 150; 730} 731 | 757{ 758 return (bcd2bin(M_msf(msf)) * 60 + 759 bcd2bin(S_msf(msf))) * 75 + 760 bcd2bin(F_msf(msf)) - 150; 761} 762 |
732static int mcd_volinfo(int unit) | 763static int 764mcd_volinfo(int unit) |
733{ 734 struct mcd_data *cd = mcd_data + unit; 735 int i; 736 737/*MCD_TRACE("mcd_volinfo: enter\n",0,0,0,0);*/ 738 739 /* Get the status, in case the disc has been changed */ 740 if (mcd_getstat(unit, 1) < 0) return EIO; --- 37 unchanged lines hidden (view full) --- 778/* state machine to process read requests 779 * initialize with MCD_S_BEGIN: calculate sizes, and read status 780 * MCD_S_WAITSTAT: wait for status reply, set mode 781 * MCD_S_WAITMODE: waits for status reply from set mode, set read command 782 * MCD_S_WAITREAD: wait for read ready, read data 783 */ 784static struct mcd_mbx *mbxsave; 785 | 765{ 766 struct mcd_data *cd = mcd_data + unit; 767 int i; 768 769/*MCD_TRACE("mcd_volinfo: enter\n",0,0,0,0);*/ 770 771 /* Get the status, in case the disc has been changed */ 772 if (mcd_getstat(unit, 1) < 0) return EIO; --- 37 unchanged lines hidden (view full) --- 810/* state machine to process read requests 811 * initialize with MCD_S_BEGIN: calculate sizes, and read status 812 * MCD_S_WAITSTAT: wait for status reply, set mode 813 * MCD_S_WAITMODE: waits for status reply from set mode, set read command 814 * MCD_S_WAITREAD: wait for read ready, read data 815 */ 816static struct mcd_mbx *mbxsave; 817 |
786static void mcd_doread(int state, struct mcd_mbx *mbxin) | 818static void 819mcd_doread(int state, struct mcd_mbx *mbxin) |
787{ 788 struct mcd_mbx *mbx = (state!=MCD_S_BEGIN) ? mbxsave : mbxin; 789 int unit = mbx->unit; 790 int port = mbx->port; 791 struct buf *bp = mbx->bp; 792 struct mcd_data *cd = mcd_data + unit; 793 794 int rm,i,k; --- 5 unchanged lines hidden (view full) --- 800 switch (state) { 801 case MCD_S_BEGIN: 802 mbx = mbxsave = mbxin; 803 804 case MCD_S_BEGIN1: 805 /* get status */ 806 outb(port+mcd_command, MCD_CMDGETSTAT); 807 mbx->count = RDELAY_WAITSTAT; | 820{ 821 struct mcd_mbx *mbx = (state!=MCD_S_BEGIN) ? mbxsave : mbxin; 822 int unit = mbx->unit; 823 int port = mbx->port; 824 struct buf *bp = mbx->bp; 825 struct mcd_data *cd = mcd_data + unit; 826 827 int rm,i,k; --- 5 unchanged lines hidden (view full) --- 833 switch (state) { 834 case MCD_S_BEGIN: 835 mbx = mbxsave = mbxin; 836 837 case MCD_S_BEGIN1: 838 /* get status */ 839 outb(port+mcd_command, MCD_CMDGETSTAT); 840 mbx->count = RDELAY_WAITSTAT; |
808 timeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITSTAT,hz/100); /* XXX */ | 841 timeout((timeout_func_t)mcd_doread, 842 (caddr_t)MCD_S_WAITSTAT,hz/100); /* XXX */ |
809 return; 810 case MCD_S_WAITSTAT: 811 untimeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITSTAT); 812 if (mbx->count-- >= 0) { 813 if (inb(port+mcd_xfer) & MCD_ST_BUSY) { | 843 return; 844 case MCD_S_WAITSTAT: 845 untimeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITSTAT); 846 if (mbx->count-- >= 0) { 847 if (inb(port+mcd_xfer) & MCD_ST_BUSY) { |
814 timeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITSTAT,hz/100); /* XXX */ | 848 timeout((timeout_func_t)mcd_doread, 849 (caddr_t)MCD_S_WAITSTAT,hz/100); /* XXX */ |
815 return; 816 } 817 mcd_setflags(unit,cd); | 850 return; 851 } 852 mcd_setflags(unit,cd); |
818 MCD_TRACE("got WAITSTAT delay=%d\n",RDELAY_WAITSTAT-mbx->count,0,0,0); | 853 MCD_TRACE("got WAITSTAT delay=%d\n", 854 RDELAY_WAITSTAT-mbx->count,0,0,0); |
819 /* reject, if audio active */ 820 if (cd->status & MCDAUDIOBSY) { 821 printf("mcd%d: audio is active\n",unit); 822 goto readerr; 823 } 824 825 /* to check for raw/cooked mode */ 826 if (cd->flags & MCDREADRAW) { 827 rm = MCD_MD_RAW; 828 mbx->sz = MCDRBLK; 829 } else { 830 rm = MCD_MD_COOKED; 831 mbx->sz = cd->blksize; 832 } 833 834 mbx->count = RDELAY_WAITMODE; 835 836 mcd_put(port+mcd_command, MCD_CMDSETMODE); 837 mcd_put(port+mcd_command, rm); | 855 /* reject, if audio active */ 856 if (cd->status & MCDAUDIOBSY) { 857 printf("mcd%d: audio is active\n",unit); 858 goto readerr; 859 } 860 861 /* to check for raw/cooked mode */ 862 if (cd->flags & MCDREADRAW) { 863 rm = MCD_MD_RAW; 864 mbx->sz = MCDRBLK; 865 } else { 866 rm = MCD_MD_COOKED; 867 mbx->sz = cd->blksize; 868 } 869 870 mbx->count = RDELAY_WAITMODE; 871 872 mcd_put(port+mcd_command, MCD_CMDSETMODE); 873 mcd_put(port+mcd_command, rm); |
838 timeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITMODE,hz/100); /* XXX */ | 874 timeout((timeout_func_t)mcd_doread, 875 (caddr_t)MCD_S_WAITMODE,hz/100); /* XXX */ |
839 return; 840 } else { 841#ifdef MCD_TO_WARNING_ON 842 printf("mcd%d: timeout getstatus\n",unit); 843#endif 844 goto readerr; 845 } 846 --- 5 unchanged lines hidden (view full) --- 852#endif 853 goto readerr; 854 } 855 if (inb(port+mcd_xfer) & MCD_ST_BUSY) { 856 timeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITMODE,hz/100); 857 return; 858 } 859 mcd_setflags(unit,cd); | 876 return; 877 } else { 878#ifdef MCD_TO_WARNING_ON 879 printf("mcd%d: timeout getstatus\n",unit); 880#endif 881 goto readerr; 882 } 883 --- 5 unchanged lines hidden (view full) --- 889#endif 890 goto readerr; 891 } 892 if (inb(port+mcd_xfer) & MCD_ST_BUSY) { 893 timeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITMODE,hz/100); 894 return; 895 } 896 mcd_setflags(unit,cd); |
860 MCD_TRACE("got WAITMODE delay=%d\n",RDELAY_WAITMODE-mbx->count,0,0,0); | 897 MCD_TRACE("got WAITMODE delay=%d\n", 898 RDELAY_WAITMODE-mbx->count,0,0,0); |
861 /* for first block */ 862 mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; 863 mbx->skip = 0; 864 865nextblock: 866 blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) 867 + mbx->p_offset + mbx->skip/mbx->sz; 868 | 899 /* for first block */ 900 mbx->nblk = (bp->b_bcount + (mbx->sz-1)) / mbx->sz; 901 mbx->skip = 0; 902 903nextblock: 904 blknum = (bp->b_blkno / (mbx->sz/DEV_BSIZE)) 905 + mbx->p_offset + mbx->skip/mbx->sz; 906 |
869 MCD_TRACE("mcd_doread: read blknum=%d for bp=0x%x\n",blknum,bp,0,0); | 907 MCD_TRACE("mcd_doread: read blknum=%d for bp=0x%x\n", 908 blknum,bp,0,0); |
870 871 /* build parameter block */ 872 hsg2msf(blknum,rbuf.start_msf); 873 874 /* send the read command */ 875 mcd_put(port+mcd_command,MCD_CMDREAD2); 876 mcd_put(port+mcd_command,rbuf.start_msf[0]); 877 mcd_put(port+mcd_command,rbuf.start_msf[1]); 878 mcd_put(port+mcd_command,rbuf.start_msf[2]); 879 mcd_put(port+mcd_command,0); 880 mcd_put(port+mcd_command,0); 881 mcd_put(port+mcd_command,1); 882 mbx->count = RDELAY_WAITREAD; | 909 910 /* build parameter block */ 911 hsg2msf(blknum,rbuf.start_msf); 912 913 /* send the read command */ 914 mcd_put(port+mcd_command,MCD_CMDREAD2); 915 mcd_put(port+mcd_command,rbuf.start_msf[0]); 916 mcd_put(port+mcd_command,rbuf.start_msf[1]); 917 mcd_put(port+mcd_command,rbuf.start_msf[2]); 918 mcd_put(port+mcd_command,0); 919 mcd_put(port+mcd_command,0); 920 mcd_put(port+mcd_command,1); 921 mbx->count = RDELAY_WAITREAD; |
883 timeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITREAD,hz/100); /* XXX */ | 922 timeout((timeout_func_t)mcd_doread, 923 (caddr_t)MCD_S_WAITREAD,hz/100); /* XXX */ |
884 return; 885 case MCD_S_WAITREAD: 886 untimeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITREAD); 887 if (mbx->count-- > 0) { 888 k = inb(port+mcd_xfer); 889 if ((k & 2)==0) { | 924 return; 925 case MCD_S_WAITREAD: 926 untimeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITREAD); 927 if (mbx->count-- > 0) { 928 k = inb(port+mcd_xfer); 929 if ((k & 2)==0) { |
890 MCD_TRACE("got data delay=%d\n",RDELAY_WAITREAD-mbx->count,0,0,0); | 930 MCD_TRACE("got data delay=%d\n", 931 RDELAY_WAITREAD-mbx->count,0,0,0); |
891 /* data is ready */ 892 addr = bp->b_un.b_addr + mbx->skip; 893 outb(port+mcd_ctl2,0x04); /* XXX */ 894 for (i=0; i<mbx->sz; i++) 895 *addr++ = inb(port+mcd_rdata); 896 outb(port+mcd_ctl2,0x0c); /* XXX */ 897 898 if (--mbx->nblk > 0) { --- 6 unchanged lines hidden (view full) --- 905 biodone(bp); 906 907 cd->flags &= ~MCDMBXBSY; 908 mcd_start(mbx->unit); 909 return; 910 } 911 if ((k & 4)==0) 912 mcd_getstat(unit,0); | 932 /* data is ready */ 933 addr = bp->b_un.b_addr + mbx->skip; 934 outb(port+mcd_ctl2,0x04); /* XXX */ 935 for (i=0; i<mbx->sz; i++) 936 *addr++ = inb(port+mcd_rdata); 937 outb(port+mcd_ctl2,0x0c); /* XXX */ 938 939 if (--mbx->nblk > 0) { --- 6 unchanged lines hidden (view full) --- 946 biodone(bp); 947 948 cd->flags &= ~MCDMBXBSY; 949 mcd_start(mbx->unit); 950 return; 951 } 952 if ((k & 4)==0) 953 mcd_getstat(unit,0); |
913 timeout((timeout_func_t)mcd_doread,(caddr_t)MCD_S_WAITREAD,hz/100); /* XXX */ | 954 timeout((timeout_func_t)mcd_doread, 955 (caddr_t)MCD_S_WAITREAD,hz/100); /* XXX */ |
914 return; 915 } else { 916#ifdef MCD_TO_WARNING_ON 917 printf("mcd%d: timeout read data\n",unit); 918#endif 919 goto readerr; 920 } 921 } --- 23 unchanged lines hidden (view full) --- 945 /*cd->status &= ~MCDDSKCHNG; */ 946 cd->debug = 1; /* preventive set debug mode */ 947 948#endif 949 950} 951 952#ifndef MCDMINI | 956 return; 957 } else { 958#ifdef MCD_TO_WARNING_ON 959 printf("mcd%d: timeout read data\n",unit); 960#endif 961 goto readerr; 962 } 963 } --- 23 unchanged lines hidden (view full) --- 987 /*cd->status &= ~MCDDSKCHNG; */ 988 cd->debug = 1; /* preventive set debug mode */ 989 990#endif 991 992} 993 994#ifndef MCDMINI |
953static int mcd_setmode(int unit, int mode) | 995static int 996mcd_setmode(int unit, int mode) |
954{ 955 struct mcd_data *cd = mcd_data + unit; 956 int port = cd->iobase; 957 int retry; 958 959 printf("mcd%d: setting mode to %d\n", unit, mode); 960 for(retry=0; retry<MCD_RETRYS; retry++) 961 { 962 outb(port+mcd_command, MCD_CMDSETMODE); 963 outb(port+mcd_command, mode); 964 if (mcd_getstat(unit, 0) != -1) return 0; 965 } 966 967 return -1; 968} 969 | 997{ 998 struct mcd_data *cd = mcd_data + unit; 999 int port = cd->iobase; 1000 int retry; 1001 1002 printf("mcd%d: setting mode to %d\n", unit, mode); 1003 for(retry=0; retry<MCD_RETRYS; retry++) 1004 { 1005 outb(port+mcd_command, MCD_CMDSETMODE); 1006 outb(port+mcd_command, mode); 1007 if (mcd_getstat(unit, 0) != -1) return 0; 1008 } 1009 1010 return -1; 1011} 1012 |
970static int mcd_toc_header(int unit, struct ioc_toc_header *th) | 1013static int 1014mcd_toc_header(int unit, struct ioc_toc_header *th) |
971{ 972 struct mcd_data *cd = mcd_data + unit; 973 | 1015{ 1016 struct mcd_data *cd = mcd_data + unit; 1017 |
974 if (mcd_volinfo(unit) < 0) | 1018 if (mcd_volinfo(unit) < 0) { |
975 return ENXIO; | 1019 return ENXIO; |
1020 } |
|
976 977 th->len = msf2hsg(cd->volinfo.vol_msf); 978 th->starting_track = bcd2bin(cd->volinfo.trk_low); 979 th->ending_track = bcd2bin(cd->volinfo.trk_high); 980 981 return 0; 982} 983 | 1021 1022 th->len = msf2hsg(cd->volinfo.vol_msf); 1023 th->starting_track = bcd2bin(cd->volinfo.trk_low); 1024 th->ending_track = bcd2bin(cd->volinfo.trk_high); 1025 1026 return 0; 1027} 1028 |
984static int mcd_read_toc(int unit) | 1029static int 1030mcd_read_toc(int unit) |
985{ 986 struct mcd_data *cd = mcd_data + unit; 987 struct ioc_toc_header th; 988 struct mcd_qchninfo q; 989 int rc, trk, idx, retry; 990 991 /* Only read TOC if needed */ | 1031{ 1032 struct mcd_data *cd = mcd_data + unit; 1033 struct ioc_toc_header th; 1034 struct mcd_qchninfo q; 1035 int rc, trk, idx, retry; 1036 1037 /* Only read TOC if needed */ |
992 if (cd->flags & MCDTOC) return 0; | 1038 if (cd->flags & MCDTOC) { 1039 return 0; 1040 } |
993 994 printf("mcd%d: reading toc header\n", unit); | 1041 1042 printf("mcd%d: reading toc header\n", unit); |
995 if (mcd_toc_header(unit, &th) != 0) | 1043 if (mcd_toc_header(unit, &th) != 0) { |
996 return ENXIO; | 1044 return ENXIO; |
1045 } |
|
997 998 printf("mcd%d: stopping play\n", unit); | 1046 1047 printf("mcd%d: stopping play\n", unit); |
999 if ((rc=mcd_stop(unit)) != 0) | 1048 if ((rc=mcd_stop(unit)) != 0) { |
1000 return rc; | 1049 return rc; |
1050 } |
|
1001 1002 /* try setting the mode twice */ | 1051 1052 /* try setting the mode twice */ |
1003 if (mcd_setmode(unit, MCD_MD_TOC) != 0) | 1053 if (mcd_setmode(unit, MCD_MD_TOC) != 0) { |
1004 return EIO; | 1054 return EIO; |
1005 if (mcd_setmode(unit, MCD_MD_TOC) != 0) | 1055 } 1056 if (mcd_setmode(unit, MCD_MD_TOC) != 0) { |
1006 return EIO; | 1057 return EIO; |
1058 } |
|
1007 1008 printf("mcd%d: get_toc reading qchannel info\n",unit); 1009 for(trk=th.starting_track; trk<=th.ending_track; trk++) 1010 cd->toc[trk].idx_no = 0; 1011 trk = th.ending_track - th.starting_track + 1; 1012 for(retry=0; retry<300 && trk>0; retry++) 1013 { 1014 if (mcd_getqchan(unit, &q) < 0) break; 1015 idx = bcd2bin(q.idx_no); | 1059 1060 printf("mcd%d: get_toc reading qchannel info\n",unit); 1061 for(trk=th.starting_track; trk<=th.ending_track; trk++) 1062 cd->toc[trk].idx_no = 0; 1063 trk = th.ending_track - th.starting_track + 1; 1064 for(retry=0; retry<300 && trk>0; retry++) 1065 { 1066 if (mcd_getqchan(unit, &q) < 0) break; 1067 idx = bcd2bin(q.idx_no); |
1016 if (idx>0 && idx < MCD_MAXTOCS && q.trk_no==0) 1017 if (cd->toc[idx].idx_no == 0) 1018 { | 1068 if (idx>0 && idx < MCD_MAXTOCS && q.trk_no==0) { 1069 if (cd->toc[idx].idx_no == 0) { |
1019 cd->toc[idx] = q; 1020 trk--; 1021 } | 1070 cd->toc[idx] = q; 1071 trk--; 1072 } |
1073 } |
|
1022 } 1023 | 1074 } 1075 |
1024 if (mcd_setmode(unit, MCD_MD_COOKED) != 0) | 1076 if (mcd_setmode(unit, MCD_MD_COOKED) != 0) { |
1025 return EIO; | 1077 return EIO; |
1078 } |
|
1026 | 1079 |
1027 if (trk != 0) return ENXIO; | 1080 if (trk != 0) { 1081 return ENXIO; 1082 } |
1028 1029 /* add a fake last+1 */ 1030 idx = th.ending_track + 1; 1031 cd->toc[idx].ctrl_adr = cd->toc[idx-1].ctrl_adr; 1032 cd->toc[idx].trk_no = 0; 1033 cd->toc[idx].idx_no = 0xAA; 1034 cd->toc[idx].hd_pos_msf[0] = cd->volinfo.vol_msf[0]; 1035 cd->toc[idx].hd_pos_msf[1] = cd->volinfo.vol_msf[1]; 1036 cd->toc[idx].hd_pos_msf[2] = cd->volinfo.vol_msf[2]; 1037 1038 cd->flags |= MCDTOC; 1039 1040 return 0; 1041} 1042 | 1083 1084 /* add a fake last+1 */ 1085 idx = th.ending_track + 1; 1086 cd->toc[idx].ctrl_adr = cd->toc[idx-1].ctrl_adr; 1087 cd->toc[idx].trk_no = 0; 1088 cd->toc[idx].idx_no = 0xAA; 1089 cd->toc[idx].hd_pos_msf[0] = cd->volinfo.vol_msf[0]; 1090 cd->toc[idx].hd_pos_msf[1] = cd->volinfo.vol_msf[1]; 1091 cd->toc[idx].hd_pos_msf[2] = cd->volinfo.vol_msf[2]; 1092 1093 cd->flags |= MCDTOC; 1094 1095 return 0; 1096} 1097 |
1043static int mcd_toc_entry(int unit, struct ioc_read_toc_entry *te) | 1098static int 1099mcd_toc_entry(int unit, struct ioc_read_toc_entry *te) |
1044{ 1045 struct mcd_data *cd = mcd_data + unit; | 1100{ 1101 struct mcd_data *cd = mcd_data + unit; |
1046 struct ret_toc 1047 { | 1102 struct ret_toc { |
1048 struct ioc_toc_header th; 1049 struct cd_toc_entry rt; 1050 } ret_toc; 1051 struct ioc_toc_header th; 1052 int rc, i; 1053 1054 /* Make sure we have a valid toc */ | 1103 struct ioc_toc_header th; 1104 struct cd_toc_entry rt; 1105 } ret_toc; 1106 struct ioc_toc_header th; 1107 int rc, i; 1108 1109 /* Make sure we have a valid toc */ |
1055 if ((rc=mcd_read_toc(unit)) != 0) | 1110 if ((rc=mcd_read_toc(unit)) != 0) { |
1056 return rc; | 1111 return rc; |
1112 } |
|
1057 1058 /* find the toc to copy*/ 1059 i = te->starting_track; | 1113 1114 /* find the toc to copy*/ 1115 i = te->starting_track; |
1060 if (i == MCD_LASTPLUS1) | 1116 if (i == MCD_LASTPLUS1) { |
1061 i = bcd2bin(cd->volinfo.trk_high) + 1; | 1117 i = bcd2bin(cd->volinfo.trk_high) + 1; |
1118 } |
|
1062 1063 /* verify starting track */ 1064 if (i < bcd2bin(cd->volinfo.trk_low) || | 1119 1120 /* verify starting track */ 1121 if (i < bcd2bin(cd->volinfo.trk_low) || |
1065 i > bcd2bin(cd->volinfo.trk_high)+1) | 1122 i > bcd2bin(cd->volinfo.trk_high)+1) { |
1066 return EINVAL; | 1123 return EINVAL; |
1124 } |
|
1067 1068 /* do we have room */ 1069 if (te->data_len < sizeof(struct ioc_toc_header) + | 1125 1126 /* do we have room */ 1127 if (te->data_len < sizeof(struct ioc_toc_header) + |
1070 sizeof(struct cd_toc_entry)) return EINVAL; | 1128 sizeof(struct cd_toc_entry)) { 1129 return EINVAL; 1130 } |
1071 1072 /* Copy the toc header */ | 1131 1132 /* Copy the toc header */ |
1073 if (mcd_toc_header(unit, &th) < 0) return EIO; | 1133 if (mcd_toc_header(unit, &th) < 0) { 1134 return EIO; 1135 } |
1074 ret_toc.th = th; 1075 1076 /* copy the toc data */ 1077 ret_toc.rt.control = cd->toc[i].ctrl_adr; 1078 ret_toc.rt.addr_type = te->address_format; 1079 ret_toc.rt.track = i; | 1136 ret_toc.th = th; 1137 1138 /* copy the toc data */ 1139 ret_toc.rt.control = cd->toc[i].ctrl_adr; 1140 ret_toc.rt.addr_type = te->address_format; 1141 ret_toc.rt.track = i; |
1080 if (te->address_format == CD_MSF_FORMAT) 1081 { | 1142 if (te->address_format == CD_MSF_FORMAT) { |
1082 ret_toc.rt.addr.addr[1] = cd->toc[i].hd_pos_msf[0]; 1083 ret_toc.rt.addr.addr[2] = cd->toc[i].hd_pos_msf[1]; 1084 ret_toc.rt.addr.addr[3] = cd->toc[i].hd_pos_msf[2]; 1085 } 1086 1087 /* copy the data back */ 1088 copyout(&ret_toc, te->data, sizeof(struct cd_toc_entry) 1089 + sizeof(struct ioc_toc_header)); 1090 1091 return 0; 1092} 1093 | 1143 ret_toc.rt.addr.addr[1] = cd->toc[i].hd_pos_msf[0]; 1144 ret_toc.rt.addr.addr[2] = cd->toc[i].hd_pos_msf[1]; 1145 ret_toc.rt.addr.addr[3] = cd->toc[i].hd_pos_msf[2]; 1146 } 1147 1148 /* copy the data back */ 1149 copyout(&ret_toc, te->data, sizeof(struct cd_toc_entry) 1150 + sizeof(struct ioc_toc_header)); 1151 1152 return 0; 1153} 1154 |
1094static int mcd_stop(int unit) | 1155static int 1156mcd_stop(int unit) |
1095{ 1096 struct mcd_data *cd = mcd_data + unit; 1097 | 1157{ 1158 struct mcd_data *cd = mcd_data + unit; 1159 |
1098 if (mcd_send(unit, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0) | 1160 if (mcd_send(unit, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0) { |
1099 return ENXIO; | 1161 return ENXIO; |
1162 } |
|
1100 cd->audio_status = CD_AS_PLAY_COMPLETED; 1101 return 0; 1102} 1103 | 1163 cd->audio_status = CD_AS_PLAY_COMPLETED; 1164 return 0; 1165} 1166 |
1104static int mcd_getqchan(int unit, struct mcd_qchninfo *q) | 1167static int 1168mcd_getqchan(int unit, struct mcd_qchninfo *q) |
1105{ 1106 struct mcd_data *cd = mcd_data + unit; 1107 | 1169{ 1170 struct mcd_data *cd = mcd_data + unit; 1171 |
1108 if (mcd_send(unit, MCD_CMDGETQCHN, MCD_RETRYS) < 0) | 1172 if (mcd_send(unit, MCD_CMDGETQCHN, MCD_RETRYS) < 0) { |
1109 return -1; | 1173 return -1; |
1110 if (mcd_get(unit, (char *) q, sizeof(struct mcd_qchninfo)) < 0) | 1174 } 1175 if (mcd_get(unit, (char *) q, sizeof(struct mcd_qchninfo)) < 0) { |
1111 return -1; | 1176 return -1; |
1112 if (cd->debug) 1113 printf("mcd%d: qchannel ctl=%d, t=%d, i=%d, ttm=%d:%d.%d dtm=%d:%d.%d\n", | 1177 } 1178 if (cd->debug) { 1179 printf("mcd%d: qchannel ctl=%d, t=%d, i=%d, ttm=%d:%d.%d dtm=%d:%d.%d\n", |
1114 unit, 1115 q->ctrl_adr, q->trk_no, q->idx_no, 1116 q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2], 1117 q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2]); | 1180 unit, 1181 q->ctrl_adr, q->trk_no, q->idx_no, 1182 q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2], 1183 q->trk_size_msf[0], q->trk_size_msf[1], q->trk_size_msf[2]); |
1184 } |
|
1118 return 0; 1119} 1120 | 1185 return 0; 1186} 1187 |
1121static int mcd_subchan(int unit, struct ioc_read_subchannel *sc) | 1188static int 1189mcd_subchan(int unit, struct ioc_read_subchannel *sc) |
1122{ 1123 struct mcd_data *cd = mcd_data + unit; 1124 struct mcd_qchninfo q; 1125 struct cd_sub_channel_info data; 1126 1127 printf("mcd%d: subchan af=%d, df=%d\n", unit, 1128 sc->address_format, 1129 sc->data_format); | 1190{ 1191 struct mcd_data *cd = mcd_data + unit; 1192 struct mcd_qchninfo q; 1193 struct cd_sub_channel_info data; 1194 1195 printf("mcd%d: subchan af=%d, df=%d\n", unit, 1196 sc->address_format, 1197 sc->data_format); |
1130 if (sc->address_format != CD_MSF_FORMAT) return EIO; 1131 if (sc->data_format != CD_CURRENT_POSITION) return EIO; | 1198 if (sc->address_format != CD_MSF_FORMAT) { 1199 return EIO; 1200 } 1201 if (sc->data_format != CD_CURRENT_POSITION) { 1202 return EIO; 1203 } 1204 if (mcd_getqchan(unit, &q) < 0) { 1205 return EIO; 1206 } |
1132 | 1207 |
1133 if (mcd_getqchan(unit, &q) < 0) return EIO; 1134 | |
1135 data.header.audio_status = cd->audio_status; 1136 data.what.position.data_format = CD_MSF_FORMAT; 1137 data.what.position.track_number = bcd2bin(q.trk_no); 1138 | 1208 data.header.audio_status = cd->audio_status; 1209 data.what.position.data_format = CD_MSF_FORMAT; 1210 data.what.position.track_number = bcd2bin(q.trk_no); 1211 |
1139 if (copyout(&data, sc->data, sizeof(struct cd_sub_channel_info))!=0) | 1212 if (copyout(&data, sc->data, sizeof(struct cd_sub_channel_info))!=0) { |
1140 return EFAULT; | 1213 return EFAULT; |
1214 } |
|
1141 return 0; 1142} 1143 | 1215 return 0; 1216} 1217 |
1144static int mcd_playtracks(int unit, struct ioc_play_track *pt) | 1218static int 1219mcd_playtracks(int unit, struct ioc_play_track *pt) |
1145{ 1146 struct mcd_data *cd = mcd_data + unit; 1147 struct mcd_read2 pb; 1148 int a = pt->start_track; 1149 int z = pt->end_track; 1150 int rc; 1151 | 1220{ 1221 struct mcd_data *cd = mcd_data + unit; 1222 struct mcd_read2 pb; 1223 int a = pt->start_track; 1224 int z = pt->end_track; 1225 int rc; 1226 |
1152 if ((rc = mcd_read_toc(unit)) != 0) return rc; 1153 | 1227 if ((rc = mcd_read_toc(unit)) != 0) { 1228 return rc; 1229 } |
1154 printf("mcd%d: playtracks from %d:%d to %d:%d\n", unit, 1155 a, pt->start_index, z, pt->end_index); 1156 1157 if (a < cd->volinfo.trk_low || a > cd->volinfo.trk_high || a > z || | 1230 printf("mcd%d: playtracks from %d:%d to %d:%d\n", unit, 1231 a, pt->start_index, z, pt->end_index); 1232 1233 if (a < cd->volinfo.trk_low || a > cd->volinfo.trk_high || a > z || |
1158 z < cd->volinfo.trk_low || z > cd->volinfo.trk_high) | 1234 z < cd->volinfo.trk_low || z > cd->volinfo.trk_high) { |
1159 return EINVAL; | 1235 return EINVAL; |
1236 } |
|
1160 1161 pb.start_msf[0] = cd->toc[a].hd_pos_msf[0]; 1162 pb.start_msf[1] = cd->toc[a].hd_pos_msf[1]; 1163 pb.start_msf[2] = cd->toc[a].hd_pos_msf[2]; 1164 pb.end_msf[0] = cd->toc[z+1].hd_pos_msf[0]; 1165 pb.end_msf[1] = cd->toc[z+1].hd_pos_msf[1]; 1166 pb.end_msf[2] = cd->toc[z+1].hd_pos_msf[2]; 1167 1168 return mcd_play(unit, &pb); 1169} 1170 | 1237 1238 pb.start_msf[0] = cd->toc[a].hd_pos_msf[0]; 1239 pb.start_msf[1] = cd->toc[a].hd_pos_msf[1]; 1240 pb.start_msf[2] = cd->toc[a].hd_pos_msf[2]; 1241 pb.end_msf[0] = cd->toc[z+1].hd_pos_msf[0]; 1242 pb.end_msf[1] = cd->toc[z+1].hd_pos_msf[1]; 1243 pb.end_msf[2] = cd->toc[z+1].hd_pos_msf[2]; 1244 1245 return mcd_play(unit, &pb); 1246} 1247 |
1171static int mcd_play(int unit, struct mcd_read2 *pb) | 1248static int 1249mcd_play(int unit, struct mcd_read2 *pb) |
1172{ 1173 struct mcd_data *cd = mcd_data + unit; 1174 int port = cd->iobase; 1175 int retry, st; 1176 1177 cd->lastpb = *pb; | 1250{ 1251 struct mcd_data *cd = mcd_data + unit; 1252 int port = cd->iobase; 1253 int retry, st; 1254 1255 cd->lastpb = *pb; |
1178 for(retry=0; retry | 1256 for(retry=0; retry<MCD_RETRYS; retry++) { |
1180 outb(port+mcd_command, MCD_CMDREAD2); 1181 outb(port+mcd_command, pb->start_msf[0]); 1182 outb(port+mcd_command, pb->start_msf[1]); 1183 outb(port+mcd_command, pb->start_msf[2]); 1184 outb(port+mcd_command, pb->end_msf[0]); 1185 outb(port+mcd_command, pb->end_msf[1]); 1186 outb(port+mcd_command, pb->end_msf[2]); | 1257 outb(port+mcd_command, MCD_CMDREAD2); 1258 outb(port+mcd_command, pb->start_msf[0]); 1259 outb(port+mcd_command, pb->start_msf[1]); 1260 outb(port+mcd_command, pb->start_msf[2]); 1261 outb(port+mcd_command, pb->end_msf[0]); 1262 outb(port+mcd_command, pb->end_msf[1]); 1263 outb(port+mcd_command, pb->end_msf[2]); |
1187 if ((st=mcd_getstat(unit, 0)) != -1) break; | 1264 if ((st=mcd_getstat(unit, 0)) != -1) { 1265 break; 1266 } |
1188 } 1189 | 1267 } 1268 |
1190 if (cd->debug) 1191 printf("mcd%d: mcd_play retry=%d, status=%d\n", unit, retry, st); 1192 if (st == -1) return ENXIO; | 1269 if (cd->debug) { 1270 printf("mcd%d: mcd_play retry=%d, status=%d\n", unit, retry, st); 1271 } 1272 if (st == -1) { 1273 return ENXIO; 1274 } |
1193 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 1194 return 0; 1195} 1196 | 1275 cd->audio_status = CD_AS_PLAY_IN_PROGRESS; 1276 return 0; 1277} 1278 |
1197static int mcd_pause(int unit) | 1279static int 1280mcd_pause(int unit) |
1198{ 1199 struct mcd_data *cd = mcd_data + unit; 1200 struct mcd_qchninfo q; 1201 int rc; 1202 1203 /* Verify current status */ | 1281{ 1282 struct mcd_data *cd = mcd_data + unit; 1283 struct mcd_qchninfo q; 1284 int rc; 1285 1286 /* Verify current status */ |
1204 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) 1205 { | 1287 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) { |
1206 printf("mcd%d: pause attempted when not playing\n", unit); 1207 return EINVAL; 1208 } 1209 1210 /* Get the current position */ | 1288 printf("mcd%d: pause attempted when not playing\n", unit); 1289 return EINVAL; 1290 } 1291 1292 /* Get the current position */ |
1211 if (mcd_getqchan(unit, &q) < 0) return EIO; | 1293 if (mcd_getqchan(unit, &q) < 0) { 1294 return EIO; 1295 } |
1212 1213 /* Copy it into lastpb */ 1214 cd->lastpb.start_msf[0] = q.hd_pos_msf[0]; 1215 cd->lastpb.start_msf[1] = q.hd_pos_msf[1]; 1216 cd->lastpb.start_msf[2] = q.hd_pos_msf[2]; 1217 1218 /* Stop playing */ | 1296 1297 /* Copy it into lastpb */ 1298 cd->lastpb.start_msf[0] = q.hd_pos_msf[0]; 1299 cd->lastpb.start_msf[1] = q.hd_pos_msf[1]; 1300 cd->lastpb.start_msf[2] = q.hd_pos_msf[2]; 1301 1302 /* Stop playing */ |
1219 if ((rc=mcd_stop(unit)) != 0) return rc; | 1303 if ((rc=mcd_stop(unit)) != 0) { 1304 return rc; 1305 } |
1220 1221 /* Set the proper status and exit */ 1222 cd->audio_status = CD_AS_PLAY_PAUSED; 1223 return 0; 1224} 1225 | 1306 1307 /* Set the proper status and exit */ 1308 cd->audio_status = CD_AS_PLAY_PAUSED; 1309 return 0; 1310} 1311 |
1226static int mcd_resume(int unit) | 1312static int 1313mcd_resume(int unit) |
1227{ 1228 struct mcd_data *cd = mcd_data + unit; 1229 | 1314{ 1315 struct mcd_data *cd = mcd_data + unit; 1316 |
1230 if (cd->audio_status != CD_AS_PLAY_PAUSED) return EINVAL; | 1317 if (cd->audio_status != CD_AS_PLAY_PAUSED) { 1318 return EINVAL; 1319 } |
1231 return mcd_play(unit, &cd->lastpb); 1232} 1233#endif /*!MCDMINI*/ 1234 1235#endif /* NMCD > 0 */ | 1320 return mcd_play(unit, &cd->lastpb); 1321} 1322#endif /*!MCDMINI*/ 1323 1324#endif /* NMCD > 0 */ |