Deleted Added
full compact
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; retry1179 {
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 */