mcd.c (13743) | mcd.c (13770) |
---|---|
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 5 * Changes Copyright (C) 1994-1995 by Andrey A. Chernov, Moscow, Russia 6 * 7 * Rewrote probe routine to work on newer Mitsumi drives. 8 * Additional changes (C) 1994 by Jordan K. Hubbard --- 26 unchanged lines hidden (view full) --- 35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 36 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 37 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 38 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * | 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 5 * Changes Copyright (C) 1994-1995 by Andrey A. Chernov, Moscow, Russia 6 * 7 * Rewrote probe routine to work on newer Mitsumi drives. 8 * Additional changes (C) 1994 by Jordan K. Hubbard --- 26 unchanged lines hidden (view full) --- 35 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, 36 * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 37 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 38 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 39 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 40 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 41 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 42 * |
43 * $Id: mcd.c,v 1.61 1996/01/30 12:07:06 ache Exp $ | 43 * $Id: mcd.c,v 1.62 1996/01/30 13:15:22 ache Exp $ |
44 */ 45static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; 46 47#include "mcd.h" 48#if NMCD > 0 49#include <sys/types.h> 50#include <sys/param.h> 51#include <sys/systm.h> --- 129 unchanged lines hidden (view full) --- 181#ifdef NOTYET 182static void mcd_configure(struct mcd_data *cd); 183#endif 184static int mcd_get(int unit, char *buf, int nmax); 185static int mcd_setflags(int unit,struct mcd_data *cd); 186static int mcd_getstat(int unit,int sflg); 187static int mcd_send(int unit, int cmd,int nretrys); 188static void hsg2msf(int hsg, bcd_t *msf); | 44 */ 45static char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; 46 47#include "mcd.h" 48#if NMCD > 0 49#include <sys/types.h> 50#include <sys/param.h> 51#include <sys/systm.h> --- 129 unchanged lines hidden (view full) --- 181#ifdef NOTYET 182static void mcd_configure(struct mcd_data *cd); 183#endif 184static int mcd_get(int unit, char *buf, int nmax); 185static int mcd_setflags(int unit,struct mcd_data *cd); 186static int mcd_getstat(int unit,int sflg); 187static int mcd_send(int unit, int cmd,int nretrys); 188static void hsg2msf(int hsg, bcd_t *msf); |
189static int msf2hsg(bcd_t *msf); | 189static int msf2hsg(bcd_t *msf, int relative); |
190static int mcd_volinfo(int unit); 191static int mcd_waitrdy(int port,int dly); 192static void mcd_doread(int state, struct mcd_mbx *mbxin); 193static void mcd_soft_reset(int unit); 194static int mcd_hard_reset(int unit); 195static int mcd_setmode(int unit, int mode); 196static int mcd_getqchan(int unit, struct mcd_qchninfo *q); 197static int mcd_subchan(int unit, struct ioc_read_subchannel *sc); --- 498 unchanged lines hidden (view full) --- 696int mcdsize(dev_t dev) 697{ 698 int size; 699 int unit = mcd_unit(dev); 700 struct mcd_data *cd = mcd_data + unit; 701 702 if (mcd_volinfo(unit) == 0) { 703 cd->blksize = MCDBLK; | 190static int mcd_volinfo(int unit); 191static int mcd_waitrdy(int port,int dly); 192static void mcd_doread(int state, struct mcd_mbx *mbxin); 193static void mcd_soft_reset(int unit); 194static int mcd_hard_reset(int unit); 195static int mcd_setmode(int unit, int mode); 196static int mcd_getqchan(int unit, struct mcd_qchninfo *q); 197static int mcd_subchan(int unit, struct ioc_read_subchannel *sc); --- 498 unchanged lines hidden (view full) --- 696int mcdsize(dev_t dev) 697{ 698 int size; 699 int unit = mcd_unit(dev); 700 struct mcd_data *cd = mcd_data + unit; 701 702 if (mcd_volinfo(unit) == 0) { 703 cd->blksize = MCDBLK; |
704 size = msf2hsg(cd->volinfo.vol_msf); | 704 size = msf2hsg(cd->volinfo.vol_msf, 0); |
705 cd->disksize = size * (MCDBLK/DEV_BSIZE); 706 return 0; 707 } 708 return -1; 709} 710 711/*************************************************************** 712 * lower level of driver starts here --- 224 unchanged lines hidden (view full) --- 937/*MCD_TRACE("mcd_send: done\n",0,0,0,0);*/ 938 return 0; 939} 940 941static void 942hsg2msf(int hsg, bcd_t *msf) 943{ 944 hsg += 150; | 705 cd->disksize = size * (MCDBLK/DEV_BSIZE); 706 return 0; 707 } 708 return -1; 709} 710 711/*************************************************************** 712 * lower level of driver starts here --- 224 unchanged lines hidden (view full) --- 937/*MCD_TRACE("mcd_send: done\n",0,0,0,0);*/ 938 return 0; 939} 940 941static void 942hsg2msf(int hsg, bcd_t *msf) 943{ 944 hsg += 150; |
945 M_msf(msf) = bin2bcd(hsg / 4500); 946 hsg %= 4500; 947 S_msf(msf) = bin2bcd(hsg / 75); | |
948 F_msf(msf) = bin2bcd(hsg % 75); | 945 F_msf(msf) = bin2bcd(hsg % 75); |
946 hsg /= 75; 947 S_msf(msf) = bin2bcd(hsg % 60); 948 hsg /= 60; 949 M_msf(msf) = bin2bcd(hsg); |
|
949} 950 951static int | 950} 951 952static int |
952msf2hsg(bcd_t *msf) | 953msf2hsg(bcd_t *msf, int relative) |
953{ | 954{ |
954 return (bcd2bin(M_msf(msf)) * 60 + 955 bcd2bin(S_msf(msf))) * 75 + 956 bcd2bin(F_msf(msf)) - 150; | 955 return (bcd2bin(M_msf(msf)) * 60 + bcd2bin(S_msf(msf))) * 75 + 956 bcd2bin(F_msf(msf)) - (!relative) * 150; |
957} 958 959static int 960mcd_volinfo(int unit) 961{ 962 struct mcd_data *cd = mcd_data + unit; 963 964 /* Just return if we already have it */ --- 373 unchanged lines hidden (view full) --- 1338mcd_toc_header(int unit, struct ioc_toc_header *th) 1339{ 1340 struct mcd_data *cd = mcd_data + unit; 1341 int r; 1342 1343 if ((r = mcd_volinfo(unit)) != 0) 1344 return r; 1345 | 957} 958 959static int 960mcd_volinfo(int unit) 961{ 962 struct mcd_data *cd = mcd_data + unit; 963 964 /* Just return if we already have it */ --- 373 unchanged lines hidden (view full) --- 1338mcd_toc_header(int unit, struct ioc_toc_header *th) 1339{ 1340 struct mcd_data *cd = mcd_data + unit; 1341 int r; 1342 1343 if ((r = mcd_volinfo(unit)) != 0) 1344 return r; 1345 |
1346 th->len = msf2hsg(cd->volinfo.vol_msf); | 1346 th->len = msf2hsg(cd->volinfo.vol_msf, 0); |
1347 th->starting_track = bcd2bin(cd->volinfo.trk_low); 1348 th->ending_track = bcd2bin(cd->volinfo.trk_high); 1349 1350 return 0; 1351} 1352 1353static int 1354mcd_read_toc(int unit) --- 121 unchanged lines hidden (view full) --- 1476 switch (te->address_format) { 1477 case CD_MSF_FORMAT: 1478 entries[n].addr.msf.unused = 0; 1479 entries[n].addr.msf.minute = bcd2bin(cd->toc[trk].hd_pos_msf[0]); 1480 entries[n].addr.msf.second = bcd2bin(cd->toc[trk].hd_pos_msf[1]); 1481 entries[n].addr.msf.frame = bcd2bin(cd->toc[trk].hd_pos_msf[2]); 1482 break; 1483 case CD_LBA_FORMAT: | 1347 th->starting_track = bcd2bin(cd->volinfo.trk_low); 1348 th->ending_track = bcd2bin(cd->volinfo.trk_high); 1349 1350 return 0; 1351} 1352 1353static int 1354mcd_read_toc(int unit) --- 121 unchanged lines hidden (view full) --- 1476 switch (te->address_format) { 1477 case CD_MSF_FORMAT: 1478 entries[n].addr.msf.unused = 0; 1479 entries[n].addr.msf.minute = bcd2bin(cd->toc[trk].hd_pos_msf[0]); 1480 entries[n].addr.msf.second = bcd2bin(cd->toc[trk].hd_pos_msf[1]); 1481 entries[n].addr.msf.frame = bcd2bin(cd->toc[trk].hd_pos_msf[2]); 1482 break; 1483 case CD_LBA_FORMAT: |
1484 entries[n].addr.lba = msf2hsg(cd->toc[trk].hd_pos_msf); | 1484 entries[n].addr.lba = htonl(msf2hsg(cd->toc[trk].hd_pos_msf, 0)); |
1485 break; 1486 } 1487 len -= sizeof(struct cd_toc_entry); 1488 n++; 1489 } 1490 1491 /* copy the data back */ 1492 return copyout(entries, te->data, n * sizeof(struct cd_toc_entry)); 1493} 1494 1495static int 1496mcd_stop(int unit) 1497{ 1498 struct mcd_data *cd = mcd_data + unit; 1499 1500 /* Verify current status */ 1501 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS && | 1485 break; 1486 } 1487 len -= sizeof(struct cd_toc_entry); 1488 n++; 1489 } 1490 1491 /* copy the data back */ 1492 return copyout(entries, te->data, n * sizeof(struct cd_toc_entry)); 1493} 1494 1495static int 1496mcd_stop(int unit) 1497{ 1498 struct mcd_data *cd = mcd_data + unit; 1499 1500 /* Verify current status */ 1501 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS && |
1502 cd->audio_status != CD_AS_PLAY_PAUSED) { | 1502 cd->audio_status != CD_AS_PLAY_PAUSED && 1503 cd->audio_status != CD_AS_PLAY_COMPLETED) { |
1503 if (cd->debug) | 1504 if (cd->debug) |
1504 printf("mcd%d: stop attempted when not playing\n", unit); | 1505 printf("mcd%d: stop attempted when not playing, audio status %d\n", 1506 unit, cd->audio_status); |
1505 return EINVAL; 1506 } 1507 if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) 1508 if (mcd_send(unit, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0) 1509 return EIO; 1510 cd->audio_status = CD_AS_PLAY_COMPLETED; 1511 return 0; 1512} --- 21 unchanged lines hidden (view full) --- 1534} 1535 1536static int 1537mcd_subchan(int unit, struct ioc_read_subchannel *sc) 1538{ 1539 struct mcd_data *cd = mcd_data + unit; 1540 struct mcd_qchninfo q; 1541 struct cd_sub_channel_info data; | 1507 return EINVAL; 1508 } 1509 if (cd->audio_status == CD_AS_PLAY_IN_PROGRESS) 1510 if (mcd_send(unit, MCD_CMDSTOPAUDIO, MCD_RETRYS) < 0) 1511 return EIO; 1512 cd->audio_status = CD_AS_PLAY_COMPLETED; 1513 return 0; 1514} --- 21 unchanged lines hidden (view full) --- 1536} 1537 1538static int 1539mcd_subchan(int unit, struct ioc_read_subchannel *sc) 1540{ 1541 struct mcd_data *cd = mcd_data + unit; 1542 struct mcd_qchninfo q; 1543 struct cd_sub_channel_info data; |
1544 int lba; |
|
1542 1543 if (cd->debug) 1544 printf("mcd%d: subchan af=%d, df=%d\n", unit, 1545 sc->address_format, 1546 sc->data_format); 1547 1548 if (sc->address_format != CD_MSF_FORMAT && 1549 sc->address_format != CD_LBA_FORMAT) --- 4 unchanged lines hidden (view full) --- 1554 1555 if (mcd_setmode(unit, MCD_MD_COOKED) != 0) 1556 return EIO; 1557 1558 if (mcd_getqchan(unit, &q) < 0) 1559 return EIO; 1560 1561 data.header.audio_status = cd->audio_status; | 1545 1546 if (cd->debug) 1547 printf("mcd%d: subchan af=%d, df=%d\n", unit, 1548 sc->address_format, 1549 sc->data_format); 1550 1551 if (sc->address_format != CD_MSF_FORMAT && 1552 sc->address_format != CD_LBA_FORMAT) --- 4 unchanged lines hidden (view full) --- 1557 1558 if (mcd_setmode(unit, MCD_MD_COOKED) != 0) 1559 return EIO; 1560 1561 if (mcd_getqchan(unit, &q) < 0) 1562 return EIO; 1563 1564 data.header.audio_status = cd->audio_status; |
1562 data.what.position.data_format = CD_CURRENT_POSITION; | 1565 data.what.position.data_format = sc->data_format; |
1563 data.what.position.control = q.control; 1564 data.what.position.addr_type = q.addr_type; 1565 data.what.position.track_number = bcd2bin(q.trk_no); 1566 data.what.position.index_number = bcd2bin(q.idx_no); 1567 switch (sc->address_format) { 1568 case CD_MSF_FORMAT: 1569 data.what.position.reladdr.msf.unused = 0; 1570 data.what.position.reladdr.msf.minute = bcd2bin(q.trk_size_msf[0]); 1571 data.what.position.reladdr.msf.second = bcd2bin(q.trk_size_msf[1]); 1572 data.what.position.reladdr.msf.frame = bcd2bin(q.trk_size_msf[2]); 1573 data.what.position.absaddr.msf.unused = 0; 1574 data.what.position.absaddr.msf.minute = bcd2bin(q.hd_pos_msf[0]); 1575 data.what.position.absaddr.msf.second = bcd2bin(q.hd_pos_msf[1]); 1576 data.what.position.absaddr.msf.frame = bcd2bin(q.hd_pos_msf[2]); 1577 break; 1578 case CD_LBA_FORMAT: | 1566 data.what.position.control = q.control; 1567 data.what.position.addr_type = q.addr_type; 1568 data.what.position.track_number = bcd2bin(q.trk_no); 1569 data.what.position.index_number = bcd2bin(q.idx_no); 1570 switch (sc->address_format) { 1571 case CD_MSF_FORMAT: 1572 data.what.position.reladdr.msf.unused = 0; 1573 data.what.position.reladdr.msf.minute = bcd2bin(q.trk_size_msf[0]); 1574 data.what.position.reladdr.msf.second = bcd2bin(q.trk_size_msf[1]); 1575 data.what.position.reladdr.msf.frame = bcd2bin(q.trk_size_msf[2]); 1576 data.what.position.absaddr.msf.unused = 0; 1577 data.what.position.absaddr.msf.minute = bcd2bin(q.hd_pos_msf[0]); 1578 data.what.position.absaddr.msf.second = bcd2bin(q.hd_pos_msf[1]); 1579 data.what.position.absaddr.msf.frame = bcd2bin(q.hd_pos_msf[2]); 1580 break; 1581 case CD_LBA_FORMAT: |
1579 data.what.position.reladdr.lba = msf2hsg(q.trk_size_msf); 1580 data.what.position.absaddr.lba = msf2hsg(q.hd_pos_msf); | 1582 lba = msf2hsg(q.trk_size_msf, 1); 1583 /* 1584 * Pre-gap has index number of 0, and decreasing MSF 1585 * address. Must be converted to negative LBA, per 1586 * SCSI spec. 1587 */ 1588 if (data.what.position.index_number == 0) 1589 lba = -lba; 1590 data.what.position.reladdr.lba = htonl(lba); 1591 data.what.position.absaddr.lba = htonl(msf2hsg(q.hd_pos_msf, 0)); |
1581 break; 1582 } 1583 1584 return copyout(&data, sc->data, min(sizeof(struct cd_sub_channel_info), sc->data_len)); 1585} 1586 1587static int 1588mcd_playmsf(int unit, struct ioc_play_msf *pt) --- 87 unchanged lines hidden (view full) --- 1676static int 1677mcd_pause(int unit) 1678{ 1679 struct mcd_data *cd = mcd_data + unit; 1680 struct mcd_qchninfo q; 1681 int rc; 1682 1683 /* Verify current status */ | 1592 break; 1593 } 1594 1595 return copyout(&data, sc->data, min(sizeof(struct cd_sub_channel_info), sc->data_len)); 1596} 1597 1598static int 1599mcd_playmsf(int unit, struct ioc_play_msf *pt) --- 87 unchanged lines hidden (view full) --- 1687static int 1688mcd_pause(int unit) 1689{ 1690 struct mcd_data *cd = mcd_data + unit; 1691 struct mcd_qchninfo q; 1692 int rc; 1693 1694 /* Verify current status */ |
1684 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS) { | 1695 if (cd->audio_status != CD_AS_PLAY_IN_PROGRESS && 1696 cd->audio_status != CD_AS_PLAY_PAUSED) { |
1685 if (cd->debug) | 1697 if (cd->debug) |
1686 printf("mcd%d: pause attempted when not playing\n", unit); | 1698 printf("mcd%d: pause attempted when not playing, audio status %d\n", 1699 unit, cd->audio_status); |
1687 return EINVAL; 1688 } 1689 1690 /* Get the current position */ 1691 if (mcd_getqchan(unit, &q) < 0) 1692 return EIO; 1693 1694 /* Copy it into lastpb */ --- 43 unchanged lines hidden --- | 1700 return EINVAL; 1701 } 1702 1703 /* Get the current position */ 1704 if (mcd_getqchan(unit, &q) < 0) 1705 return EIO; 1706 1707 /* Copy it into lastpb */ --- 43 unchanged lines hidden --- |