Add DVD-RAM support.

The driver constructs a fake disklabel that makes the 'a' partition
cover the entire DVD-RAM disk. This cannot be changed from the user
side. This solution was chosen because most DVD-RAM will have a
UDF (or until we have that CD9660) filesystem on it covering the
entire disk, its not really thought as a real random access device.

This might change over time, but for now this is what we have, and
it is compatible with CDROM's etc, that makes using the minidisk
subsystem less than ideal, because of !modulo BDEV_SIZE blocks.
This commit is contained in:
Søren Schmidt 2000-02-29 22:00:53 +00:00
parent e51ec40ec8
commit 7caf73fb3c
2 changed files with 60 additions and 14 deletions

View file

@ -79,6 +79,7 @@ static int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
static void acd_start(struct acd_softc *);
static int32_t acd_done(struct atapi_request *);
static int32_t acd_read_toc(struct acd_softc *);
static void acd_contruct_label(struct acd_softc *);
static int32_t acd_setchan(struct acd_softc *, u_int8_t, u_int8_t, u_int8_t, u_int8_t);
static void acd_select_slot(struct acd_softc *);
static int32_t acd_open_track(struct acd_softc *, struct cdr_track *);
@ -472,16 +473,10 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
if (!cdp)
return ENXIO;
if (cdp->flags & F_WRITING)
return EBUSY;
if (flags & FWRITE) {
if (count_dev(dev) > 1)
return EBUSY;
else
cdp->flags |= F_WRITING;
}
if (count_dev(dev) == 1) {
acd_prevent_allow(cdp, 1);
cdp->flags |= F_LOCKED;
@ -490,6 +485,7 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
else
atapi_test_ready(cdp->atp);
}
acd_contruct_label(cdp);
return 0;
}
@ -501,12 +497,12 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
if (count_dev(dev) == 1)
acd_prevent_allow(cdp, 0);
cdp->flags &= ~(F_LOCKED | F_WRITING);
cdp->flags &= ~F_LOCKED;
return 0;
}
static int
acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p)
{
struct acd_softc *cdp = dev->si_drv1;
int32_t error = 0;
@ -1038,6 +1034,27 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
error = acd_read_structure(cdp, (struct dvd_struct *)addr);
break;
case DIOCGDINFO:
*(struct disklabel *)addr = cdp->disklabel;
break;
case DIOCWDINFO:
case DIOCSDINFO:
if ((flags & FWRITE) == 0)
error = EBADF;
else
error = setdisklabel(&cdp->disklabel, (struct disklabel *)addr, 0);
break;
case DIOCWLABEL:
error = EBADF;
break;
case DIOCGPART:
((struct partinfo *)addr)->disklab = &cdp->disklabel;
((struct partinfo *)addr)->part = &cdp->disklabel.d_partitions[0];
break;
default:
error = ENOTTY;
}
@ -1087,6 +1104,7 @@ acd_start(struct acd_softc *cdp)
}
acd_select_slot(cdp);
#ifdef NO_DVD_RAM_SUPPORT
if (!(bp->b_flags & B_READ) &&
(!(cdp->flags & F_DISK_OPEN) || !(cdp->flags & F_TRACK_OPEN))) {
printf("acd%d: sequence error (no open)\n", cdp->lun);
@ -1095,7 +1113,7 @@ acd_start(struct acd_softc *cdp)
biodone(bp);
return;
}
#endif
bzero(ccb, sizeof(ccb));
count = (bp->b_bcount + (cdp->block_size - 1)) / cdp->block_size;
if (bp->b_flags & B_PHYS)
@ -1220,6 +1238,35 @@ acd_read_toc(struct acd_softc *cdp)
return 0;
}
static void
acd_contruct_label(struct acd_softc *cdp)
{
bzero(&cdp->disklabel, sizeof(struct disklabel));
strncpy(cdp->disklabel.d_typename, " ",
sizeof(cdp->disklabel.d_typename));
strncpy(cdp->disklabel.d_typename, cdp->atp->devname,
min(strlen(cdp->atp->devname),
sizeof(cdp->disklabel.d_typename) - 1));
strncpy(cdp->disklabel.d_packname, "unknown ",
sizeof(cdp->disklabel.d_packname));
cdp->disklabel.d_secsize = cdp->info.blksize;
cdp->disklabel.d_nsectors = 100;
cdp->disklabel.d_ntracks = 1;
cdp->disklabel.d_ncylinders = (cdp->info.volsize/100)+1;
cdp->disklabel.d_secpercyl = 100;
cdp->disklabel.d_secperunit = cdp->info.volsize;
cdp->disklabel.d_rpm = 300;
cdp->disklabel.d_interleave = 1;
cdp->disklabel.d_flags = D_REMOVABLE;
cdp->disklabel.d_npartitions = 1;
cdp->disklabel.d_partitions[0].p_offset = 0;
cdp->disklabel.d_partitions[0].p_size = cdp->info.volsize;
cdp->disklabel.d_partitions[0].p_fstype = FS_BSDFFS;
cdp->disklabel.d_magic = DISKMAGIC;
cdp->disklabel.d_magic2 = DISKMAGIC;
cdp->disklabel.d_checksum = dkcksum(&cdp->disklabel);
}
static int32_t
acd_setchan(struct acd_softc *cdp,
u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3)
@ -1747,4 +1794,3 @@ acd_set_speed(struct acd_softc *cdp, int32_t speed)
return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, 30, NULL, NULL, NULL);
}

View file

@ -312,10 +312,9 @@ struct acd_softc {
int32_t lun; /* logical device unit */
int32_t flags; /* device state flags */
#define F_LOCKED 0x0001 /* this unit is locked */
#define F_WRITING 0x0002 /* this unit is writing */
#define F_WRITTEN 0x0004 /* medium has been written to */
#define F_DISK_OPEN 0x0008 /* disk open for writing */
#define F_TRACK_OPEN 0x0010 /* track open for writing */
#define F_WRITTEN 0x0002 /* medium has been written to */
#define F_DISK_OPEN 0x0004 /* disk open for writing */
#define F_TRACK_OPEN 0x0008 /* track open for writing */
struct buf_queue_head buf_queue; /* Queue of i/o requests */
struct toc toc; /* table of disc contents */
@ -340,6 +339,7 @@ struct acd_softc {
struct changer *changer_info; /* changer info */
int32_t slot; /* this lun's slot number */
u_int32_t block_size; /* blocksize currently used */
struct disklabel disklabel; /* fake disk label */
struct devstat *stats; /* devstat entry */
dev_t dev1, dev2; /* device place holders */
};