diff options
author | joerg <joerg@FreeBSD.org> | 1997-05-04 15:24:23 +0000 |
---|---|---|
committer | joerg <joerg@FreeBSD.org> | 1997-05-04 15:24:23 +0000 |
commit | 8cea5b917d62db9701a7fe2a45c9032aec48325d (patch) | |
tree | a2408a8a297df1fa5ba68bcc7ee4bc36c2fc2521 /sys/i386/isa/mcd.c | |
parent | 60343a746abd65c1fe9040ea648287d56be4b871 (diff) | |
download | FreeBSD-src-8cea5b917d62db9701a7fe2a45c9032aec48325d.zip FreeBSD-src-8cea5b917d62db9701a7fe2a45c9032aec48325d.tar.gz |
This mega-commit brings the following:
. It makes cd9660 root f/s working again.
. It makes CD9660 a new-style option.
. It adds support to mount an ISO9660 multi-session CD-ROM as the root
filesystem (the last session actually, but that's what is expected
behaviour).
Sigh. The CDIOREADTOCENTRYS did a copyout() of its own, and thus has
been unusable for me for this work. Too bad it didn't simply stuff
the max 100 entries into the struct ioc_read_toc_entry, but relied on
a user supplied data buffer instead. :-( I now had to reinvent the
wheel, and created a CDIOREADTOCENTRY ioctl command that can be used
in a kernel context.
While doing this, i noticed the following bogosities in existing CD-ROM
drivers:
wcd: This driver is likely to be totally bogus when someone tries
two succeeding CDIOREADTOCENTRYS (or now CDIOREADTOCENTRY)
commands with requesting MSF format, since it apparently
operates on an internal table.
scd: This driver apparently returns just a single TOC entry only for
the CDIOREADTOCENTRYS command.
I have only been able to test the CDIOREADTOCENTRY command with the
cd(4) driver. I hereby request the respective maintainers of the
other CD-ROM drivers to verify my code for their driver. When it
comes to merging this CD-ROM multisession stuff into RELENG_2_2 i will
only consider drivers where i've got a confirmation that it actually
works.
Diffstat (limited to 'sys/i386/isa/mcd.c')
-rw-r--r-- | sys/i386/isa/mcd.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/sys/i386/isa/mcd.c b/sys/i386/isa/mcd.c index 6a7adb3..f7eecb8 100644 --- a/sys/i386/isa/mcd.c +++ b/sys/i386/isa/mcd.c @@ -40,7 +40,7 @@ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: mcd.c,v 1.87 1997/03/24 11:23:55 bde Exp $ + * $Id: mcd.c,v 1.88 1997/04/20 17:26:54 bde Exp $ */ static const char COPYRIGHT[] = "mcd-driver (C)1993 by H.Veit & B.Moore"; @@ -195,6 +195,7 @@ static int mcd_subchan(int unit, struct ioc_read_subchannel *sc); static int mcd_toc_header(int unit, struct ioc_toc_header *th); static int mcd_read_toc(int unit); static int mcd_toc_entrys(int unit, struct ioc_read_toc_entry *te); +static int mcd_toc_entry(int unit, struct ioc_read_toc_single_entry *te); static int mcd_stop(int unit); static int mcd_eject(int unit); static int mcd_inject(int unit); @@ -1427,6 +1428,57 @@ mcd_read_toc(int unit) } static int +mcd_toc_entry(int unit, struct ioc_read_toc_single_entry *te) +{ + struct mcd_data *cd = mcd_data + unit; + struct ioc_toc_header th; + int rc, trk; + + if (te->address_format != CD_MSF_FORMAT + && te->address_format != CD_LBA_FORMAT) + return EINVAL; + + /* Copy the toc header */ + if ((rc = mcd_toc_header(unit, &th)) != 0) + return rc; + + /* verify starting track */ + trk = te->track; + if (trk == 0) + trk = th.starting_track; + else if (trk == MCD_LASTPLUS1) + trk = th.ending_track + 1; + else if (trk < th.starting_track || trk > th.ending_track + 1) + return EINVAL; + + /* Make sure we have a valid toc */ + if ((rc=mcd_read_toc(unit)) != 0) + return rc; + + /* Copy the TOC data. */ + if (cd->toc[trk].idx_no == 0) + return EIO; + + te->entry.control = cd->toc[trk].control; + te->entry.addr_type = cd->toc[trk].addr_type; + te->entry.track = + cd->toc[trk].idx_no > 0x99 ? cd->toc[trk].idx_no : + bcd2bin(cd->toc[trk].idx_no); + switch (te->address_format) { + case CD_MSF_FORMAT: + te->entry.addr.msf.unused = 0; + te->entry.addr.msf.minute = bcd2bin(cd->toc[trk].hd_pos_msf[0]); + te->entry.addr.msf.second = bcd2bin(cd->toc[trk].hd_pos_msf[1]); + te->entry.addr.msf.frame = bcd2bin(cd->toc[trk].hd_pos_msf[2]); + break; + case CD_LBA_FORMAT: + te->entry.addr.lba = htonl(msf2hsg(cd->toc[trk].hd_pos_msf, 0)); + break; + } + return 0; +} + +static int mcd_toc_entrys(int unit, struct ioc_read_toc_entry *te) { struct mcd_data *cd = mcd_data + unit; |