diff options
author | phk <phk@FreeBSD.org> | 1999-10-01 09:34:10 +0000 |
---|---|---|
committer | phk <phk@FreeBSD.org> | 1999-10-01 09:34:10 +0000 |
commit | 1e7bbcc7eed994d916d6b0b7a20d4ffc168576f5 (patch) | |
tree | e0be0fa28eb811324524aa1e4dd54303e0cf752f /sys/cam | |
parent | 8e2cd16fb83ff0789444173ddfd06fd6ad45af4d (diff) | |
download | FreeBSD-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')
-rw-r--r-- | sys/cam/scsi/scsi_cd.c | 125 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.c | 162 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_pass.c | 5 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_pt.c | 7 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_sa.c | 6 |
5 files changed, 85 insertions, 220 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; } diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 6f29732..e916728 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -35,12 +35,10 @@ #include <sys/kernel.h> #include <sys/buf.h> #include <sys/devicestat.h> -#include <sys/dkbad.h> -#include <sys/disklabel.h> -#include <sys/diskslice.h> +#include <sys/conf.h> +#include <sys/disk.h> #include <sys/eventhandler.h> #include <sys/malloc.h> -#include <sys/conf.h> #include <sys/cons.h> #include <machine/md_var.h> @@ -112,7 +110,7 @@ struct da_softc { int minimum_cmd_size; int ordered_tag_count; struct disk_params params; - struct diskslices *dk_slices; /* virtual drives */ + struct disk disk; union ccb saved_ccb; }; @@ -183,7 +181,6 @@ static d_close_t daclose; static d_strategy_t dastrategy; static d_ioctl_t daioctl; static d_dump_t dadump; -static d_psize_t dasize; static periph_init_t dainit; static void daasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg); @@ -249,11 +246,13 @@ static struct cdevsw da_cdevsw = { /* name */ "da", /* maj */ DA_CDEV_MAJOR, /* dump */ dadump, - /* psize */ dasize, + /* psize */ nopsize, /* flags */ D_DISK, /* bmaj */ DA_BDEV_MAJOR }; +static struct cdevsw dadisk_cdevsw; + static SLIST_HEAD(,da_softc) softc_list; static struct extend_array *daperiphs; @@ -262,7 +261,7 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) { struct cam_periph *periph; struct da_softc *softc; - struct disklabel label; + struct disklabel *label; int unit; int part; int error; @@ -284,26 +283,14 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) return (error); /* error code from tsleep */ } - if ((softc->flags & DA_FLAG_OPEN) == 0) { - if (cam_periph_acquire(periph) != CAM_REQ_CMP) - return(ENXIO); - softc->flags |= DA_FLAG_OPEN; - } + if (cam_periph_acquire(periph) != CAM_REQ_CMP) + return(ENXIO); + softc->flags |= DA_FLAG_OPEN; s = splsoftcam(); if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) { - /* - * If any partition is open, although the disk has - * been invalidated, disallow further opens. - */ - if (dsisopen(softc->dk_slices)) { - splx(s); - cam_periph_unlock(periph); - return (ENXIO); - } - /* Invalidate our pack information. */ - dsgone(&softc->dk_slices); + disk_invalidate(&softc->disk); softc->flags &= ~DA_FLAG_PACK_INVALID; } splx(s); @@ -345,8 +332,9 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) struct ccb_getdev cgd; /* Build label for whole disk. */ - 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. @@ -356,27 +344,23 @@ daopen(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.secsize; - label.d_nsectors = softc->params.secs_per_track; - label.d_ntracks = softc->params.heads; - label.d_ncylinders = softc->params.cylinders; - label.d_secpercyl = softc->params.heads + label->d_secsize = softc->params.secsize; + label->d_nsectors = softc->params.secs_per_track; + label->d_ntracks = softc->params.heads; + label->d_ncylinders = softc->params.cylinders; + label->d_secpercyl = softc->params.heads * softc->params.secs_per_track; - label.d_secperunit = softc->params.sectors; + label->d_secperunit = softc->params.sectors; - if ((dsisopen(softc->dk_slices) == 0) - && ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0)) { + if (((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0)) { daprevent(periph, PR_PREVENT); } - /* Initialize slice tables. */ - error = dsopen(dev, fmt, 0, &softc->dk_slices, &label); - /* * Check to see whether or not the blocksize is set yet. * If it isn't, set it and then clear the blocksize @@ -389,8 +373,7 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) } if (error != 0) { - if ((dsisopen(softc->dk_slices) == 0) - && ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0)) { + if ((softc->flags & DA_FLAG_PACK_REMOVABLE) != 0) { daprevent(periph, PR_ALLOW); } } @@ -417,12 +400,6 @@ daclose(dev_t dev, int flag, int fmt, struct proc *p) return (error); /* error code from tsleep */ } - dsclose(dev, fmt, softc->dk_slices); - if (dsisopen(softc->dk_slices)) { - cam_periph_unlock(periph); - return (0); - } - if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) { union ccb *ccb; @@ -519,12 +496,6 @@ dastrategy(struct buf *bp) #endif /* - * Do bounds checking, adjust transfer, set b_cylin and b_pbklno. - */ - if (dscheck(bp, softc->dk_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. @@ -555,7 +526,6 @@ dastrategy(struct buf *bp) return; bad: bp->b_flags |= B_ERROR; -done: /* * Correctly set the buf to indicate a completed xfer @@ -587,17 +557,11 @@ daioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("daioctl\n")); - if (cmd == DIOCSBAD) - return (EINVAL); /* XXX */ - if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) { return (error); /* error code from tsleep */ } - error = dsioctl(dev, cmd, addr, flag, &softc->dk_slices); - - if (error == ENOIOCTL) - error = cam_periph_ioctl(periph, cmd, addr, daerror); + error = cam_periph_ioctl(periph, cmd, addr, daerror); cam_periph_unlock(periph); @@ -609,16 +573,15 @@ dadump(dev_t dev) { struct cam_periph *periph; struct da_softc *softc; - struct disklabel *lp; u_int unit; u_int part; - long num; /* number of sectors to write */ - long blkoff; - long blknum; + u_int secsize; + u_int num; /* number of sectors to write */ + u_int blknum; long blkcnt; vm_offset_t addr; - static int dadoingadump = 0; struct ccb_scsiio csio; + int error; /* toss any characters present prior to dump */ while (cncheckc() != -1) @@ -632,31 +595,15 @@ dadump(dev_t dev) } softc = (struct da_softc *)periph->softc; - if ((softc->flags & DA_FLAG_PACK_INVALID) != 0 - || (softc->dk_slices == NULL) - || (lp = dsgetlabel(dev, softc->dk_slices)) == NULL) + if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) return (ENXIO); - /* Size of memory to dump, in disk sectors. */ - /* XXX Fix up for non DEV_BSIZE sectors!!! */ - num = (u_long)Maxmem * PAGE_SIZE / softc->params.secsize; - - blkoff = lp->d_partitions[part].p_offset; - blkoff += softc->dk_slices->dss_slices[dkslice(dev)].ds_offset; - - /* check transfer bounds against partition size */ - if ((dumplo < 0) || ((dumplo + num) > lp->d_partitions[part].p_size)) - return (EINVAL); - - if (dadoingadump != 0) - return (EFAULT); - - dadoingadump = 1; - - blknum = dumplo + blkoff; - blkcnt = PAGE_SIZE / softc->params.secsize; + error = disk_dumpcheck(dev, &num, &blknum, &secsize); + if (error) + return (error); addr = 0; /* starting address */ + blkcnt = howmany(PAGE_SIZE, secsize); while (num > 0) { @@ -680,7 +627,7 @@ dadump(dev_t dev) blknum, blkcnt, /*data_ptr*/CADDR1, - /*dxfer_len*/blkcnt * softc->params.secsize, + /*dxfer_len*/blkcnt * secsize, /*sense_len*/SSD_FULL_SIZE, DA_DEFAULT_TIMEOUT * 1000); xpt_polled_action((union ccb *)&csio); @@ -702,14 +649,14 @@ dadump(dev_t dev) (*wdog_tickler)(); #endif /* HW_WDOG */ /* Count in MB of data left to write */ - printf("%ld ", (num * softc->params.secsize) + printf("%d ", (num * softc->params.secsize) / (1024 * 1024)); } /* update block count */ num -= blkcnt; blknum += blkcnt; - addr += blkcnt * softc->params.secsize; + addr += PAGE_SIZE; /* operator aborting dump? */ if (cncheckc() != -1) @@ -756,21 +703,6 @@ dadump(dev_t dev) return (0); } -static int -dasize(dev_t dev) -{ - struct cam_periph *periph; - struct da_softc *softc; - - periph = cam_extend_get(daperiphs, dkunit(dev)); - if (periph == NULL) - return (ENXIO); - - softc = (struct da_softc *)periph->softc; - - return (dssize(dev, &softc->dk_slices)); -} - static void dainit(void) { @@ -812,9 +744,6 @@ dainit(void) "due to status 0x%x!\n", status); } else { - /* If we were successfull, register our devsw */ - cdevsw_add(&da_cdevsw); - /* * Schedule a periodic event to occasioanly send an * ordered tag to a device. @@ -1036,6 +965,12 @@ daregister(struct cam_periph *periph, void *arg) DEVSTAT_PRIORITY_DA); /* + * Register this media as a disk + */ + disk_create(periph->unit_number, &softc->disk, 0, + &da_cdevsw, &dadisk_cdevsw); + + /* * Add async callbacks for bus reset and * bus device reset calls. I don't bother * checking if this fails as, in most cases, @@ -1278,15 +1213,10 @@ dadone(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->device_stats.busy_count == 0) softc->flags |= DA_FLAG_WENT_IDLE; + devstat_end_transaction_buf(&softc->device_stats, bp); biodone(bp); break; } diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 4dbcabb..dc843d2 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -620,10 +620,7 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) else ds_flags = DEVSTAT_NO_DATA; - devstat_end_transaction(&softc->device_stats, bp->b_bcount, - done_ccb->csio.tag_action & 0xf, - ds_flags); - + devstat_end_transaction_buf(&softc->device_stats, bp); biodone(bp); break; } diff --git a/sys/cam/scsi/scsi_pt.c b/sys/cam/scsi/scsi_pt.c index 1c29548..efb019b 100644 --- a/sys/cam/scsi/scsi_pt.c +++ b/sys/cam/scsi/scsi_pt.c @@ -670,12 +670,7 @@ ptdone(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); - + devstat_end_transaction_buf(&softc->device_stats, bp); biodone(bp); break; } diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index cff8757..3a58ba7 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -1586,11 +1586,7 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) bp->b_resid, bp->b_bcount)); } #endif - 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); + devstat_end_transaction_buf(&softc->device_stats, bp); biodone(bp); break; } |