summaryrefslogtreecommitdiffstats
path: root/sys/dev/scd
diff options
context:
space:
mode:
authorjoerg <joerg@FreeBSD.org>1997-05-04 15:24:23 +0000
committerjoerg <joerg@FreeBSD.org>1997-05-04 15:24:23 +0000
commit8cea5b917d62db9701a7fe2a45c9032aec48325d (patch)
treea2408a8a297df1fa5ba68bcc7ee4bc36c2fc2521 /sys/dev/scd
parent60343a746abd65c1fe9040ea648287d56be4b871 (diff)
downloadFreeBSD-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/dev/scd')
-rw-r--r--sys/dev/scd/scd.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/sys/dev/scd/scd.c b/sys/dev/scd/scd.c
index 33d77f8..acd1968 100644
--- a/sys/dev/scd/scd.c
+++ b/sys/dev/scd/scd.c
@@ -41,7 +41,7 @@
*/
-/* $Id: scd.c,v 1.28 1997/03/24 11:24:01 bde Exp $ */
+/* $Id: scd.c,v 1.29 1997/04/20 17:26:55 bde Exp $ */
/* Please send any comments to micke@dynas.se */
@@ -180,6 +180,7 @@ static int read_subcode(int unit, struct sony_subchannel_position_data *sc);
/* for xcdplayer */
static int scd_toc_header(int unit, struct ioc_toc_header *th);
static int scd_toc_entrys(int unit, struct ioc_read_toc_entry *te);
+static int scd_toc_entry(int unit, struct ioc_read_toc_single_entry *te);
#define SCD_LASTPLUS1 170 /* don't ask, xcdplayer passes this in */
static int scd_probe(struct isa_device *dev);
@@ -456,6 +457,8 @@ scdioctl(dev_t dev, int cmd, caddr_t addr, int flags, struct proc *p)
return scd_toc_header (unit, (struct ioc_toc_header *) addr);
case CDIOREADTOCENTRYS:
return scd_toc_entrys (unit, (struct ioc_read_toc_entry*) addr);
+ case CDIOREADTOCENTRY:
+ return scd_toc_entry (unit, (struct ioc_read_toc_single_entry*) addr);
case CDIOCSETPATCH:
case CDIOCGETVOL:
case CDIOCSETVOL:
@@ -1517,6 +1520,45 @@ scd_toc_entrys (int unit, struct ioc_read_toc_entry *te)
}
+static int
+scd_toc_entry (int unit, struct ioc_read_toc_single_entry *te)
+{
+ struct scd_data *cd = scd_data + unit;
+ struct cd_toc_entry toc_entry;
+ int rc, i;
+
+ if (!(cd->flags & SCDTOC) && (rc = read_toc(unit)) != 0) {
+ print_error(unit, rc);
+ return EIO;
+ }
+
+ /* find the toc to copy*/
+ i = te->track;
+ if (i == SCD_LASTPLUS1)
+ i = cd->last_track + 1;
+
+ /* verify starting track */
+ if (i < cd->first_track || i > cd->last_track+1)
+ return EINVAL;
+
+ /* copy the toc data */
+ toc_entry.control = cd->toc[i].ctl;
+ toc_entry.addr_type = te->address_format;
+ toc_entry.track = i;
+ if (te->address_format == CD_MSF_FORMAT) {
+ toc_entry.addr.msf.unused = 0;
+ toc_entry.addr.msf.minute = bcd2bin(cd->toc[i].start_msf[0]);
+ toc_entry.addr.msf.second = bcd2bin(cd->toc[i].start_msf[1]);
+ toc_entry.addr.msf.frame = bcd2bin(cd->toc[i].start_msf[2]);
+ }
+
+ /* copy the data back */
+ bcopy(&toc_entry, &te->entry, sizeof(struct cd_toc_entry));
+
+ return 0;
+}
+
+
static scd_devsw_installed = 0;
static void scd_drvinit(void *unused)
OpenPOWER on IntegriCloud