diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1997-02-23 02:31:44 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1997-02-23 02:31:44 +0000 |
commit | 9d4d0019c2c899ecb1ab16e096c43fa15e7360da (patch) | |
tree | dd8dff99dfd079cc15e5b2757bc7557c97b1c0ba /sys/dev | |
parent | 0c6458d3ad2d42ec941dbff89ed7d2abdfdbf951 (diff) |
Audio CDs were read as data CDs before, which broke audio.
This change fixes that and tries to make sane disklabels for audio disks,
however it fails at that, but I think the fix is good enough to go in.
Hopefully the disklabel will be really fixed tomorrow.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/atapi/acd.c | 101 |
1 files changed, 87 insertions, 14 deletions
diff --git a/sys/dev/atapi/acd.c b/sys/dev/atapi/acd.c index 7d4bbc93b7a..8ee530b2090 100644 --- a/sys/dev/atapi/acd.c +++ b/sys/dev/atapi/acd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acd.c,v 1.18 1996/12/24 01:33:38 deraadt Exp $ */ +/* $OpenBSD: acd.c,v 1.19 1997/02/23 02:31:43 niklas Exp $ */ /* * Copyright (c) 1996 Manuel Bouyer. All rights reserved. @@ -37,10 +37,10 @@ #include <sys/file.h> #include <sys/stat.h> #include <sys/ioctl.h> +#include <sys/malloc.h> #include <sys/mtio.h> #include <sys/buf.h> #include <sys/uio.h> -#include <sys/malloc.h> #include <sys/errno.h> #include <sys/device.h> #include <sys/disklabel.h> @@ -64,6 +64,16 @@ struct cd_toc { struct cd_toc_entry tab[MAXTRACK+1]; /* One extra for the leadout */ }; +#define TOC_HEADER_LEN 0 +#define TOC_HEADER_STARTING_TRACK 2 +#define TOC_HEADER_ENDING_TRACK 3 +#define TOC_HEADER_SZ 4 + +#define TOC_ENTRY_CONTROL_ADDR_TYPE 1 +#define TOC_ENTRY_TRACK 2 +#define TOC_ENTRY_MSF_LBA 4 +#define TOC_ENTRY_SZ 8 + #ifdef ACD_DEBUG #define ACD_DEBUG_PRINT(args) printf args #else @@ -960,13 +970,18 @@ acdgetdisklabel(acd) { struct disklabel *lp = acd->sc_dk.dk_label; char *errstring; + u_int8_t hdr[TOC_HEADER_SZ], *toc, *ent, *lent; + u_int32_t lba, nlba; + int i, n, len; bzero(lp, sizeof(struct disklabel)); bzero(acd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel)); lp->d_secsize = acd->params.blksize; +#if 0 if (lp->d_secsize > 2048) lp->d_secsize = 2048; +#endif lp->d_ntracks = 1; lp->d_nsectors = 100; lp->d_ncylinders = (acd->params.disksize / 100) + 1; @@ -976,7 +991,6 @@ acdgetdisklabel(acd) /* as long as it's not 0 - readdisklabel divides by it (?) */ } - strncpy(lp->d_typename, "ATAPI CD-ROM", 16); lp->d_type = DTYPE_SCSI; /* XXX */ strncpy(lp->d_packname, "fictitious", 16); lp->d_secperunit = acd->params.disksize; @@ -984,24 +998,83 @@ acdgetdisklabel(acd) lp->d_interleave = 1; lp->d_flags = D_REMOVABLE; - lp->d_partitions[RAW_PART].p_offset = 0; - lp->d_partitions[RAW_PART].p_size = - lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); - lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; - lp->d_npartitions = RAW_PART + 1; - lp->d_magic = DISKMAGIC; lp->d_magic2 = DISKMAGIC; lp->d_checksum = dkcksum(lp); /* - * Call the generic disklabel extraction routine + * Call the generic disklabel extraction routine if we have a data CD */ - errstring = readdisklabel(MAKECDDEV(0, acd->sc_dev.dv_unit, RAW_PART), - acdstrategy, lp, acd->sc_dk.dk_cpulabel); - if (errstring) { - printf("%s: %s\n", acd->sc_dev.dv_xname, errstring); + if (acd_read_toc(acd, 0, 0, hdr, TOC_HEADER_SZ)) return; + n = ((acd->ad_link->quirks & AQUIRK_LITTLETOC) ? + (hdr[TOC_HEADER_LEN] | hdr[TOC_HEADER_LEN + 1] << 8) : + (hdr[TOC_HEADER_LEN] << 8 | hdr[TOC_HEADER_LEN + 1])) + 1; + len = TOC_HEADER_SZ + n * TOC_ENTRY_SZ; + MALLOC(toc, u_int8_t *, len, M_TEMP, M_WAITOK); + if (acd_read_toc (acd, 0, 0, toc, len)) + return; + + if (toc[TOC_HEADER_SZ + TOC_ENTRY_CONTROL_ADDR_TYPE] & 4) { + strncpy(lp->d_typename, "ATAPI CD-ROM", 16); + lp->d_partitions[RAW_PART].p_offset = 0; + lp->d_partitions[RAW_PART].p_size = + lp->d_secperunit * (lp->d_secsize / DEV_BSIZE); + lp->d_partitions[RAW_PART].p_fstype = FS_UNUSED; + lp->d_npartitions = RAW_PART + 1; + + errstring = + readdisklabel(MAKECDDEV(0, acd->sc_dev.dv_unit, RAW_PART), + acdstrategy, lp, acd->sc_dk.dk_cpulabel); + if (errstring) { + printf("%s: %s\n", acd->sc_dev.dv_xname, errstring); + return; + } + } else { + strncpy(lp->d_typename, "ATAPI audio CD", 16); + lp->d_npartitions = n + 1; + ent = toc + TOC_HEADER_SZ; + lba = + (ent[TOC_ENTRY_CONTROL_ADDR_TYPE] >> 4) == CD_LBA_FORMAT ? + (acd->ad_link->quirks & AQUIRK_LITTLETOC) ? + ent[TOC_ENTRY_MSF_LBA] | ent[TOC_ENTRY_MSF_LBA + 1] << 8 : + ent[TOC_ENTRY_MSF_LBA] << 8 | ent[TOC_ENTRY_MSF_LBA + 1] : + msf2lba(ent[TOC_ENTRY_MSF_LBA + 1], + ent[TOC_ENTRY_MSF_LBA + 2], ent[TOC_ENTRY_MSF_LBA + 3]); + for (i = 0; i < min(n + 1, MAXPARTITIONS); i++) { + if (i == RAW_PART) { + lp->d_partitions[i].p_offset = 0; + lent = toc + TOC_HEADER_SZ + n * TOC_ENTRY_SZ; + lp->d_partitions[i].p_size = + (lent[TOC_ENTRY_CONTROL_ADDR_TYPE] >> + 4) == CD_LBA_FORMAT ? + (acd->ad_link->quirks & AQUIRK_LITTLETOC) ? + lent[TOC_ENTRY_MSF_LBA] | + lent[TOC_ENTRY_MSF_LBA + 1] << 8 : + lent[TOC_ENTRY_MSF_LBA] << 8 | + lent[TOC_ENTRY_MSF_LBA + 1] : + msf2lba(lent[TOC_ENTRY_MSF_LBA + 1], + lent[TOC_ENTRY_MSF_LBA + 2], + lent[TOC_ENTRY_MSF_LBA + 3]); + lp->d_partitions[i].p_fstype = FS_UNUSED; + } else { + lp->d_partitions[i].p_fstype = FS_OTHER; + ent += TOC_ENTRY_SZ; + nlba = (ent[TOC_ENTRY_CONTROL_ADDR_TYPE] >> + 4) == CD_LBA_FORMAT ? + (acd->ad_link->quirks & AQUIRK_LITTLETOC) ? + ent[TOC_ENTRY_MSF_LBA] | + ent[TOC_ENTRY_MSF_LBA + 1] << 8 : + ent[TOC_ENTRY_MSF_LBA] << 8 | + ent[TOC_ENTRY_MSF_LBA + 1] : + msf2lba(ent[TOC_ENTRY_MSF_LBA + 1], + ent[TOC_ENTRY_MSF_LBA + 2], + ent[TOC_ENTRY_MSF_LBA + 3]); + lp->d_partitions[i].p_offset = lba; + lp->d_partitions[i].p_size = nlba - lba; + lba = nlba; + } + } } } |