From 15d53d32307fc595687f9d646d82566d3fc640cb Mon Sep 17 00:00:00 2001 From: niklas Date: Sun, 23 Feb 1997 13:08:49 +0000 Subject: [PATCH] Some KNF, but more important: fix disklabels for audio CDs + preliminary support for multi-session CDs although the ISO9660 spoofing must be remade for that to really work. --- sys/dev/atapi/acd.c | 190 ++++++++++++++++++++++++-------------------- 1 file changed, 106 insertions(+), 84 deletions(-) diff --git a/sys/dev/atapi/acd.c b/sys/dev/atapi/acd.c index a31bc506a06..64ad3f3f88a 100644 --- a/sys/dev/atapi/acd.c +++ b/sys/dev/atapi/acd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: acd.c,v 1.20 1997/02/23 03:08:27 niklas Exp $ */ +/* $OpenBSD: acd.c,v 1.21 1997/02/23 13:08:49 niklas Exp $ */ /* * Copyright (c) 1996 Manuel Bouyer. All rights reserved. @@ -218,9 +218,9 @@ acdattach(parent, self, aux) } if (acd_get_mode(acd, &acd->mode_page, ATAPI_CAP_PAGE, CAPPAGESIZE, - A_POLLED) != 0) { + A_POLLED) != 0) { printf("%s: can't MODE SENSE: acd_get_mode failed\n", - self->dv_xname); + self->dv_xname); return; } @@ -358,7 +358,7 @@ acdopen(dev, flag, fmt) /* Check that the partition exists. */ if (part != RAW_PART && (part >= acd->sc_dk.dk_label->d_npartitions || - acd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { + acd->sc_dk.dk_label->d_partitions[part].p_fstype == FS_UNUSED)) { error = ENXIO; goto bad; } @@ -612,14 +612,14 @@ acdstart(vp) blkno = bp->b_blkno / (acd->sc_dk.dk_label->d_secsize / DEV_BSIZE); if (CDPART(bp->b_dev) != RAW_PART) { - p = - &acd->sc_dk.dk_label->d_partitions[CDPART(bp->b_dev)]; + p = &acd->sc_dk.dk_label->d_partitions[ + CDPART(bp->b_dev)]; blkno += p->p_offset; } nblks = howmany(bp->b_bcount, acd->sc_dk.dk_label->d_secsize); - ACD_DEBUG_PRINT(("acdstart: blkno %d nblk %d\n", - blkno, nblks)); + ACD_DEBUG_PRINT(("acdstart: blkno %d nblk %d\n", blkno, + nblks)); /* * Fill out the atapi command @@ -636,7 +636,7 @@ acdstart(vp) * Call the routine that chats with the adapter. * Note: we cannot sleep as we may be an interrupt */ - if (atapi_exec_io(ad_link, &cmd, sizeof(cmd), bp, A_NOSLEEP)) { + if (atapi_exec_io(ad_link, &cmd, sizeof(cmd), bp, A_NOSLEEP)) { disk_unbusy(&acd->sc_dk, 0); printf("%s: not queued", acd->sc_dev.dv_xname); } @@ -749,16 +749,14 @@ acdioctl(dev, cmd, addr, flag, p) struct ioc_play_track *args = (struct ioc_play_track *)addr; return acd_play_tracks(acd, args->start_track, - args->start_index, args->end_track, - args->end_index); + args->start_index, args->end_track, args->end_index); } case CDIOCPLAYMSF: { struct ioc_play_msf *args = (struct ioc_play_msf *)addr; return acd_play_msf(acd, args->start_m, args->start_s, - args->start_f, args->end_m, args->end_s, - args->end_f); + args->start_f, args->end_m, args->end_s, args->end_f); } case CDIOCPLAYBLOCKS: { @@ -768,8 +766,8 @@ acdioctl(dev, cmd, addr, flag, p) } case CDIOCREADSUBCHANNEL: { - struct ioc_read_subchannel *args - = (struct ioc_read_subchannel *)addr; + struct ioc_read_subchannel *args = + (struct ioc_read_subchannel *)addr; struct cd_sub_channel_info data; int len = args->data_len; @@ -778,7 +776,7 @@ acdioctl(dev, cmd, addr, flag, p) return EINVAL; error = acd_read_subchannel(acd, args->address_format, - args->data_format, args->track, &data, len); + args->data_format, args->track, &data, len); if (error) return error; return copyout(&data, args->data, len); @@ -804,7 +802,7 @@ acdioctl(dev, cmd, addr, flag, p) /* XXX Remove endian dependency */ case CDIOREADTOCENTRYS: { struct ioc_read_toc_entry *te = - (struct ioc_read_toc_entry *)addr; + (struct ioc_read_toc_entry *)addr; struct cd_toc toc; struct ioc_toc_header *th = &toc.hdr; int len = te->data_len; @@ -821,20 +819,25 @@ acdioctl(dev, cmd, addr, flag, p) return error; if (te->address_format == CD_LBA_FORMAT) { - for (ntracks = th->ending_track - th->starting_track + 1; - ntracks >= 0; ntracks--) { - toc.tab[ntracks].addr_type = CD_LBA_FORMAT; - if (acd->ad_link->quirks & AQUIRK_LITTLETOC) { + for (ntracks = + th->ending_track - th->starting_track + 1; + ntracks >= 0; ntracks--) { + toc.tab[ntracks].addr_type = CD_LBA_FORMAT; + if (acd->ad_link->quirks & AQUIRK_LITTLETOC) { #if BYTE_ORDER == BIG_ENDIAN - bswap((u_int8_t*)&toc.tab[ntracks].addr.addr, sizeof(toc.tab[ntracks].addr.addr)); + bswap((u_int8_t*) + &toc.tab[ntracks].addr.addr, + sizeof(toc.tab[ntracks].addr.addr) + ); #endif - } else - (u_int32_t)(*toc.tab[ntracks].addr.addr) = ntohl((u_int32_t)(*toc.tab[ntracks].addr.addr)); - } + } else + toc.tab[ntracks].addr.lba = + ntohl(toc.tab[ntracks].addr.lba); + } } if (acd->ad_link->quirks & AQUIRK_LITTLETOC) { #if BYTE_ORDER == BIG_ENDIAN - bswap((u_int8_t*)&th->len, sizeof(th->len)); + bswap((u_int8_t*)&th->len, sizeof(th->len)); #endif } else th->len = ntohs(th->len); @@ -847,12 +850,13 @@ acdioctl(dev, cmd, addr, flag, p) struct ioc_patch *arg = (struct ioc_patch *)addr; return acd_setchan(acd, arg->patch[0], arg->patch[1], - arg->patch[2], arg->patch[3]); + arg->patch[2], arg->patch[3]); } case CDIOCGETVOL: { struct ioc_vol *arg = (struct ioc_vol *)addr; struct atapi_mode_data data; + error = acd_get_mode(acd, &data, ATAPI_AUDIO_PAGE, AUDIOPAGESIZE, 0); if (error) @@ -892,27 +896,27 @@ acdioctl(dev, cmd, addr, flag, p) case CDIOCSETMONO: { return acd_setchan(acd, BOTH_CHANNEL, BOTH_CHANNEL, - MUTE_CHANNEL, MUTE_CHANNEL); + MUTE_CHANNEL, MUTE_CHANNEL); } case CDIOCSETSTEREO: { return acd_setchan(acd, LEFT_CHANNEL, RIGHT_CHANNEL, - MUTE_CHANNEL, MUTE_CHANNEL); + MUTE_CHANNEL, MUTE_CHANNEL); } case CDIOCSETMUTE: { return acd_setchan(acd, MUTE_CHANNEL, MUTE_CHANNEL, - MUTE_CHANNEL, MUTE_CHANNEL); + MUTE_CHANNEL, MUTE_CHANNEL); } case CDIOCSETLEFT: { return acd_setchan(acd, LEFT_CHANNEL, LEFT_CHANNEL, - MUTE_CHANNEL, MUTE_CHANNEL); + MUTE_CHANNEL, MUTE_CHANNEL); } case CDIOCSETRIGHT: { return acd_setchan(acd, RIGHT_CHANNEL, RIGHT_CHANNEL, - MUTE_CHANNEL, MUTE_CHANNEL); + MUTE_CHANNEL, MUTE_CHANNEL); } case CDIOCRESUME: @@ -931,6 +935,7 @@ acdioctl(dev, cmd, addr, flag, p) if (((struct mtop *)addr)->mt_op != MTOFFL) return EIO; /* FALLTHROUGH */ + case CDIOCEJECT: /* FALLTHROUGH */ case DIOCEJECT: acd->ad_link->flags |= ADEV_EJECTING; @@ -945,6 +950,7 @@ acdioctl(dev, cmd, addr, flag, p) case DIOCLOCK: return atapi_prevent(acd->ad_link, (*(int *)addr) ? PR_PREVENT : PR_ALLOW); + case CDIOCRESET: return acd_reset(acd); @@ -970,15 +976,16 @@ acdgetdisklabel(acd) { struct disklabel *lp = acd->sc_dk.dk_label; char *errstring; - u_int8_t hdr[TOC_HEADER_SZ], *toc, *ent, *lent; + u_int8_t hdr[TOC_HEADER_SZ], *toc, *ent; u_int32_t lba, nlba; - int i, n, len; + int i, n, len, is_data, data_track = -1; bzero(lp, sizeof(struct disklabel)); bzero(acd->sc_dk.dk_cpulabel, sizeof(struct cpu_disklabel)); lp->d_secsize = acd->params.blksize; #if 0 + /* I don't think this is necessary anymore. */ if (lp->d_secsize > 2048) lp->d_secsize = 2048; #endif @@ -991,6 +998,7 @@ 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; @@ -1003,66 +1011,80 @@ acdgetdisklabel(acd) lp->d_checksum = dkcksum(lp); /* - * Call the generic disklabel extraction routine if we have a data CD + * Read the TOC and loop throught the individual tracks and lay them + * out in our disklabel. If there is a data track, call the generic + * disklabel read routine. XXX should we move all data tracks up front + * before any other tracks? */ if (acd_read_toc(acd, 0, 0, hdr, TOC_HEADER_SZ)) return; - n = hdr[TOC_HEADER_ENDING_TRACK] - hdr[TOC_HEADER_STARTING_TRACK] + 1; - len = TOC_HEADER_SZ + n * TOC_ENTRY_SZ; + n = min(hdr[TOC_HEADER_ENDING_TRACK] - hdr[TOC_HEADER_STARTING_TRACK] + + 1, MAXPARTITIONS); + len = TOC_HEADER_SZ + (n + 1) * TOC_ENTRY_SZ; MALLOC(toc, u_int8_t *, len, M_TEMP, M_WAITOK); if (acd_read_toc (acd, CD_LBA_FORMAT, 0, toc, len)) goto done; - 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); - goto done; - } - } else { - strncpy(lp->d_typename, "ATAPI audio CD", 16); - lp->d_npartitions = min(n + 1, MAXPARTITIONS); - ent = toc + TOC_HEADER_SZ; - lba = - (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]; - 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 = - (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]; - lp->d_partitions[i].p_fstype = FS_UNUSED; - } else { - lp->d_partitions[i].p_fstype = FS_OTHER; - ent += TOC_ENTRY_SZ; - nlba = - (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]; - lp->d_partitions[i].p_offset = lba; - lp->d_partitions[i].p_size = nlba - lba; - lba = nlba; - } + /* The raw partition is special. */ + 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; + + /* Create the partition table. */ + lp->d_npartitions = max(RAW_PART, n) + 1; + ent = toc + TOC_HEADER_SZ; + lba = ((acd->ad_link->quirks & AQUIRK_LITTLETOC) ? + ent[TOC_ENTRY_MSF_LBA] | ent[TOC_ENTRY_MSF_LBA + 1] << 8 | + ent[TOC_ENTRY_MSF_LBA + 2] << 16 | + ent[TOC_ENTRY_MSF_LBA + 3] << 24 : + ent[TOC_ENTRY_MSF_LBA] << 24 | ent[TOC_ENTRY_MSF_LBA + 1] << 16 | + ent[TOC_ENTRY_MSF_LBA + 2] << 8 | ent[TOC_ENTRY_MSF_LBA + 3]) * + lp->d_secsize / DEV_BSIZE; + + for (i = 0; i < (n > RAW_PART + 1 ? n + 1 : n); i++) { + /* The raw partition was specially handled above. */ + if (i != RAW_PART) { + is_data = toc[TOC_HEADER_SZ + + TOC_ENTRY_CONTROL_ADDR_TYPE] & 4; + lp->d_partitions[i].p_fstype = + is_data ? FS_UNUSED : FS_OTHER; + if (is_data && data_track == -1) + data_track = i; + ent += TOC_ENTRY_SZ; + nlba = ((acd->ad_link->quirks & AQUIRK_LITTLETOC) ? + ent[TOC_ENTRY_MSF_LBA] | + ent[TOC_ENTRY_MSF_LBA + 1] << 8 | + ent[TOC_ENTRY_MSF_LBA + 2] << 16 | + ent[TOC_ENTRY_MSF_LBA + 3] << 24 : + ent[TOC_ENTRY_MSF_LBA] << 24 | + ent[TOC_ENTRY_MSF_LBA + 1] << 16 | + ent[TOC_ENTRY_MSF_LBA + 2] << 8 | + ent[TOC_ENTRY_MSF_LBA + 3]) * lp->d_secsize / + DEV_BSIZE; + lp->d_partitions[i].p_offset = lba; + lp->d_partitions[i].p_size = nlba - lba; + lba = nlba; } } + /* We have a data track, look in there for a real disklabel. */ + if (data_track != -1) { +#ifdef notyet + /* + * Reading a disklabel inside the track we setup above + * does not yet work, for unknown reasons. + */ + errstring = readdisklabel(MAKECDDEV(0, acd->sc_dev.dv_unit, + data_track), acdstrategy, lp, acd->sc_dk.dk_cpulabel); +#else + errstring = readdisklabel(MAKECDDEV(0, acd->sc_dev.dv_unit, + RAW_PART), acdstrategy, lp, acd->sc_dk.dk_cpulabel); +#endif + if (errstring) + printf("%s: %s\n", acd->sc_dev.dv_xname, errstring); + } + done: FREE(toc, M_TEMP); } -- 2.20.1