summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi/scsi_cd.c
diff options
context:
space:
mode:
authorphk <phk@FreeBSD.org>1999-10-01 09:34:10 +0000
committerphk <phk@FreeBSD.org>1999-10-01 09:34:10 +0000
commit1e7bbcc7eed994d916d6b0b7a20d4ffc168576f5 (patch)
treee0be0fa28eb811324524aa1e4dd54303e0cf752f /sys/cam/scsi/scsi_cd.c
parent8e2cd16fb83ff0789444173ddfd06fd6ad45af4d (diff)
downloadFreeBSD-src-1e7bbcc7eed994d916d6b0b7a20d4ffc168576f5.zip
FreeBSD-src-1e7bbcc7eed994d916d6b0b7a20d4ffc168576f5.tar.gz
Introduce the disk mini-layer and devstat_end_transaction_buf() in cam/scsi.
Somewhat reviewed by: ken
Diffstat (limited to 'sys/cam/scsi/scsi_cd.c')
-rw-r--r--sys/cam/scsi/scsi_cd.c125
1 files changed, 36 insertions, 89 deletions
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c
index a66231e..7bb1ddc 100644
--- a/sys/cam/scsi/scsi_cd.c
+++ b/sys/cam/scsi/scsi_cd.c
@@ -52,11 +52,9 @@
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/buf.h>
-#include <sys/dkbad.h>
-#include <sys/disklabel.h>
-#include <sys/diskslice.h>
-#include <sys/malloc.h>
#include <sys/conf.h>
+#include <sys/disk.h>
+#include <sys/malloc.h>
#include <sys/cdio.h>
#include <sys/devicestat.h>
#include <sys/sysctl.h>
@@ -93,7 +91,6 @@ typedef enum {
CD_FLAG_DISC_LOCKED = 0x004,
CD_FLAG_DISC_REMOVABLE = 0x008,
CD_FLAG_TAGGED_QUEUING = 0x010,
- CD_FLAG_OPEN = 0x020,
CD_FLAG_CHANGER = 0x040,
CD_FLAG_ACTIVE = 0x080,
CD_FLAG_SCHED_ON_COMP = 0x100,
@@ -130,7 +127,7 @@ struct cd_softc {
struct buf_queue_head buf_queue;
LIST_HEAD(, ccb_hdr) pending_ccbs;
struct cd_params params;
- struct diskslices *cd_slices;
+ struct disk disk;
union ccb saved_ccb;
cd_quirks quirks;
struct devstat device_stats;
@@ -258,6 +255,7 @@ static struct cdevsw cd_cdevsw = {
/* flags */ D_DISK,
/* bmaj */ CD_BDEV_MAJOR
};
+static struct cdevsw cddisk_cdevsw;
static struct extend_array *cdperiphs;
static int num_changers;
@@ -338,9 +336,6 @@ cdinit(void)
if (status != CAM_REQ_CMP) {
printf("cd: Failed to attach master async callback "
"due to status 0x%x!\n", status);
- } else {
- /* If we were successfull, register our devsw */
- cdevsw_add(&cd_cdevsw);
}
}
@@ -620,6 +615,9 @@ cdregister(struct cam_periph *periph, void *arg)
DEVSTAT_BS_UNAVAILABLE,
DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_SCSI,
DEVSTAT_PRIORITY_CD);
+ disk_create(periph->unit_number, &softc->disk,
+ DSO_NOLABELS | DSO_ONESLICE,
+ &cd_cdevsw, &cddisk_cdevsw);
/*
* Add an async callback so that we get
@@ -862,7 +860,7 @@ cdregisterexit:
static int
cdopen(dev_t dev, int flags, int fmt, struct proc *p)
{
- struct disklabel label;
+ struct disklabel *label;
struct cam_periph *periph;
struct cd_softc *softc;
struct ccb_getdev cgd;
@@ -894,25 +892,16 @@ cdopen(dev_t dev, int flags, int fmt, struct proc *p)
splx(s);
- if ((softc->flags & CD_FLAG_OPEN) == 0) {
- if (cam_periph_acquire(periph) != CAM_REQ_CMP)
- return(ENXIO);
- softc->flags |= CD_FLAG_OPEN;
+ if (cam_periph_acquire(periph) != CAM_REQ_CMP)
+ return(ENXIO);
- cdprevent(periph, PR_PREVENT);
- }
+ cdprevent(periph, PR_PREVENT);
/* find out the size */
if ((error = cdsize(dev, &size)) != 0) {
- if (dsisopen(softc->cd_slices) == 0) {
- cdprevent(periph, PR_ALLOW);
- softc->flags &= ~CD_FLAG_OPEN;
- }
+ cdprevent(periph, PR_ALLOW);
cam_periph_unlock(periph);
-
- if ((softc->flags & CD_FLAG_OPEN) == 0)
- cam_periph_release(periph);
-
+ cam_periph_release(periph);
return(error);
}
@@ -921,8 +910,9 @@ cdopen(dev_t dev, int flags, int fmt, struct proc *p)
* Should take information about different data tracks from the
* TOC and put it in the partition table.
*/
- bzero(&label, sizeof(label));
- label.d_type = DTYPE_SCSI;
+ label = &softc->disk.d_label;
+ bzero(label, sizeof(*label));
+ label->d_type = DTYPE_SCSI;
/*
* Grab the inquiry data to get the vendor and product names.
@@ -932,14 +922,14 @@ cdopen(dev_t dev, int flags, int fmt, struct proc *p)
cgd.ccb_h.func_code = XPT_GDEV_TYPE;
xpt_action((union ccb *)&cgd);
- strncpy(label.d_typename, cgd.inq_data.vendor,
- min(SID_VENDOR_SIZE, sizeof(label.d_typename)));
- strncpy(label.d_packname, cgd.inq_data.product,
- min(SID_PRODUCT_SIZE, sizeof(label.d_packname)));
+ strncpy(label->d_typename, cgd.inq_data.vendor,
+ min(SID_VENDOR_SIZE, sizeof(label->d_typename)));
+ strncpy(label->d_packname, cgd.inq_data.product,
+ min(SID_PRODUCT_SIZE, sizeof(label->d_packname)));
- label.d_secsize = softc->params.blksize;
- label.d_secperunit = softc->params.disksize;
- label.d_flags = D_REMOVABLE;
+ label->d_secsize = softc->params.blksize;
+ label->d_secperunit = softc->params.disksize;
+ label->d_flags = D_REMOVABLE;
/*
* Make partition 'a' cover the whole disk. This is a temporary
* compatibility hack. The 'a' partition should not exist, so
@@ -947,29 +937,19 @@ cdopen(dev_t dev, int flags, int fmt, struct proc *p)
* partition (RAW_PART + 'a') cover the whole disk and fill in
* some more defaults.
*/
- label.d_partitions[0].p_size = label.d_secperunit;
- label.d_partitions[0].p_fstype = FS_OTHER;
-
- /* Initialize slice tables. */
- error = dsopen(dev, fmt, DSO_NOLABELS | DSO_ONESLICE,
- &softc->cd_slices, &label);
+ label->d_partitions[0].p_size = label->d_secperunit;
+ label->d_partitions[0].p_fstype = FS_OTHER;
- if (error == 0) {
- /*
- * We unconditionally (re)set the blocksize each time the
- * CD device is opened. This is because the CD can change,
- * and therefore the blocksize might change.
- * XXX problems here if some slice or partition is still
- * open with the old size?
- */
- if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0)
- softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE;
- softc->device_stats.block_size = softc->params.blksize;
- } else {
- if ((dsisopen(softc->cd_slices) == 0)
- && ((softc->flags & CD_FLAG_DISC_REMOVABLE) != 0))
- cdprevent(periph, PR_ALLOW);
- }
+ /*
+ * We unconditionally (re)set the blocksize each time the
+ * CD device is opened. This is because the CD can change,
+ * and therefore the blocksize might change.
+ * XXX problems here if some slice or partition is still
+ * open with the old size?
+ */
+ if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0)
+ softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE;
+ softc->device_stats.block_size = softc->params.blksize;
cam_periph_unlock(periph);
@@ -995,12 +975,6 @@ cdclose(dev_t dev, int flag, int fmt, struct proc *p)
if ((error = cam_periph_lock(periph, PRIBIO)) != 0)
return (error);
- dsclose(dev, fmt, softc->cd_slices);
- if (dsisopen(softc->cd_slices)) {
- cam_periph_unlock(periph);
- return (0);
- }
-
if ((softc->flags & CD_FLAG_DISC_REMOVABLE) != 0)
cdprevent(periph, PR_ALLOW);
@@ -1010,7 +984,6 @@ cdclose(dev_t dev, int flag, int fmt, struct proc *p)
*/
softc->device_stats.flags |= DEVSTAT_BS_UNAVAILABLE;
- softc->flags &= ~CD_FLAG_OPEN;
cam_periph_unlock(periph);
cam_periph_release(periph);
@@ -1374,12 +1347,6 @@ cdstrategy(struct buf *bp)
softc = (struct cd_softc *)periph->softc;
/*
- * Do bounds checking, adjust transfer, and set b_pbklno.
- */
- if (dscheck(bp, softc->cd_slices) <= 0)
- goto done;
-
- /*
* Mask interrupts so that the pack cannot be invalidated until
* after we are in the queue. Otherwise, we might not properly
* clean up one of the buffers.
@@ -1414,7 +1381,6 @@ cdstrategy(struct buf *bp)
return;
bad:
bp->b_flags |= B_ERROR;
-done:
/*
* Correctly set the buf to indicate a completed xfer
*/
@@ -1614,15 +1580,10 @@ cddone(struct cam_periph *periph, union ccb *done_ccb)
LIST_REMOVE(&done_ccb->ccb_h, periph_links.le);
splx(oldspl);
- devstat_end_transaction(&softc->device_stats,
- bp->b_bcount - bp->b_resid,
- done_ccb->csio.tag_action & 0xf,
- (bp->b_flags & B_READ) ? DEVSTAT_READ
- : DEVSTAT_WRITE);
-
if (softc->flags & CD_FLAG_CHANGER)
cdchangerschedule(softc);
+ devstat_end_transaction_buf(&softc->device_stats, bp);
biodone(bp);
break;
}
@@ -2438,20 +2399,6 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
error = ENOTTY;
break;
default:
- if (cmd == DIOCSBAD) {
- error = EINVAL; /* XXX */
- break;
- }
-
- /*
- * Check to see whether we've got a disk-type ioctl. If we
- * don't, dsioctl will pass back an error code of ENOIOCTL.
- */
- error = dsioctl(dev, cmd, addr, flag, &softc->cd_slices);
-
- if (error != ENOIOCTL)
- break;
-
error = cam_periph_ioctl(periph, cmd, addr, cderror);
break;
}
OpenPOWER on IntegriCloud