X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/blobdiff_plain/f51e7baf0227138fa23a601d3e0f6958ec17ee69..b13267a5123f6a14e47d788c4a8a2a8692e2a119:/sys/bus/cam/scsi/scsi_pass.c diff --git a/sys/bus/cam/scsi/scsi_pass.c b/sys/bus/cam/scsi/scsi_pass.c index b268aac3f2..4084f3910f 100644 --- a/sys/bus/cam/scsi/scsi_pass.c +++ b/sys/bus/cam/scsi/scsi_pass.c @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * $FreeBSD: src/sys/cam/scsi/scsi_pass.c,v 1.19 2000/01/17 06:27:37 mjacob Exp $ - * $DragonFly: src/sys/bus/cam/scsi/scsi_pass.c,v 1.12 2004/05/19 22:52:38 dillon Exp $ + * $DragonFly: src/sys/bus/cam/scsi/scsi_pass.c,v 1.18 2006/09/10 01:26:32 dillon Exp $ */ #include @@ -43,6 +43,7 @@ #include #include #include +#include #include "../cam.h" #include "../cam_ccb.h" @@ -72,13 +73,13 @@ typedef enum { } pass_ccb_types; #define ccb_type ppriv_field0 -#define ccb_bp ppriv_ptr1 +#define ccb_bio ppriv_ptr1 struct pass_softc { pass_state state; pass_flags flags; u_int8_t pd_type; - struct buf_queue_head buf_queue; + struct bio_queue_head bio_queue; union ccb saved_ccb; struct devstat device_stats; }; @@ -112,23 +113,14 @@ static struct periph_driver passdriver = DATA_SET(periphdriver_set, passdriver); -static struct cdevsw pass_cdevsw = { - /* name */ "pass", - /* maj */ PASS_CDEV_MAJOR, - /* flags */ 0, - /* port */ NULL, - /* clone */ NULL, - - /* open */ passopen, - /* close */ passclose, - /* read */ physread, - /* write */ physwrite, - /* ioctl */ passioctl, - /* poll */ nopoll, - /* mmap */ nommap, - /* strategy */ passstrategy, - /* dump */ nodump, - /* psize */ nopsize +static struct dev_ops pass_ops = { + { "pass", PASS_CDEV_MAJOR, 0 }, + .d_open = passopen, + .d_close = passclose, + .d_read = physread, + .d_write = physwrite, + .d_ioctl = passioctl, + .d_strategy = passstrategy, }; static struct extend_array *passperiphs; @@ -178,9 +170,9 @@ passinit(void) static void passoninvalidate(struct cam_periph *periph) { - int s; struct pass_softc *softc; struct buf *q_bp; + struct bio *q_bio; struct ccb_setasync csa; softc = (struct pass_softc *)periph->softc; @@ -199,25 +191,25 @@ passoninvalidate(struct cam_periph *periph) softc->flags |= PASS_FLAG_INVALID; /* - * Although the oninvalidate() routines are always called at - * splsoftcam, we need to be at splbio() here to keep the buffer + * We need to be in a critical section here to keep the buffer * queue from being modified while we traverse it. */ - s = splbio(); + crit_enter(); /* * Return all queued I/O with ENXIO. * XXX Handle any transactions queued to the card * with XPT_ABORT_CCB. */ - while ((q_bp = bufq_first(&softc->buf_queue)) != NULL){ - bufq_remove(&softc->buf_queue, q_bp); + while ((q_bio = bioq_first(&softc->bio_queue)) != NULL){ + bioq_remove(&softc->bio_queue, q_bio); + q_bp = q_bio->bio_buf; q_bp->b_resid = q_bp->b_bcount; q_bp->b_error = ENXIO; q_bp->b_flags |= B_ERROR; - biodone(q_bp); + biodone(q_bio); } - splx(s); + crit_exit(); if (bootverbose) { xpt_print_path(periph->path); @@ -241,8 +233,8 @@ passcleanup(struct cam_periph *periph) xpt_print_path(periph->path); printf("removing device entry\n"); } - cdevsw_remove(&pass_cdevsw, -1, periph->unit_number); - free(softc, M_DEVBUF); + dev_ops_remove(&pass_ops, -1, periph->unit_number); + kfree(softc, M_DEVBUF); } static void @@ -302,10 +294,10 @@ passregister(struct cam_periph *periph, void *arg) return(CAM_REQ_CMP_ERR); } - softc = malloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO); + softc = kmalloc(sizeof(*softc), M_DEVBUF, M_INTWAIT | M_ZERO); softc->state = PASS_STATE_NORMAL; softc->pd_type = SID_TYPE(&cgd->inq_data); - bufq_init(&softc->buf_queue); + bioq_init(&softc->bio_queue); periph->softc = softc; @@ -323,8 +315,8 @@ passregister(struct cam_periph *periph, void *arg) DEVSTAT_PRIORITY_PASS); /* Register the device */ - cdevsw_add(&pass_cdevsw, -1, periph->unit_number); - make_dev(&pass_cdevsw, periph->unit_number, UID_ROOT, + dev_ops_add(&pass_ops, -1, periph->unit_number); + make_dev(&pass_ops, periph->unit_number, UID_ROOT, GID_OPERATOR, 0600, "%s%d", periph->periph_name, periph->unit_number); @@ -346,12 +338,12 @@ passregister(struct cam_periph *periph, void *arg) } static int -passopen(dev_t dev, int flags, int fmt, struct thread *td) +passopen(struct dev_open_args *ap) { + cdev_t dev = ap->a_head.a_dev; struct cam_periph *periph; struct pass_softc *softc; int unit, error; - int s; error = 0; /* default to no error */ @@ -366,9 +358,9 @@ passopen(dev_t dev, int flags, int fmt, struct thread *td) softc = (struct pass_softc *)periph->softc; - s = splsoftcam(); + crit_enter(); if (softc->flags & PASS_FLAG_INVALID) { - splx(s); + crit_exit(); return(ENXIO); } @@ -376,34 +368,34 @@ passopen(dev_t dev, int flags, int fmt, struct thread *td) * Don't allow access when we're running at a high securelvel. */ if (securelevel > 1) { - splx(s); + crit_exit(); return(EPERM); } /* * Only allow read-write access. */ - if (((flags & FWRITE) == 0) || ((flags & FREAD) == 0)) { - splx(s); + if (((ap->a_oflags & FWRITE) == 0) || ((ap->a_oflags & FREAD) == 0)) { + crit_exit(); return(EPERM); } /* * We don't allow nonblocking access. */ - if ((flags & O_NONBLOCK) != 0) { + if ((ap->a_oflags & O_NONBLOCK) != 0) { xpt_print_path(periph->path); printf("can't do nonblocking accesss\n"); - splx(s); + crit_exit(); return(EINVAL); } if ((error = cam_periph_lock(periph, PCATCH)) != 0) { - splx(s); + crit_exit(); return (error); } - splx(s); + crit_exit(); if ((softc->flags & PASS_FLAG_OPEN) == 0) { if (cam_periph_acquire(periph) != CAM_REQ_CMP) @@ -417,8 +409,9 @@ passopen(dev_t dev, int flags, int fmt, struct thread *td) } static int -passclose(dev_t dev, int flag, int fmt, struct thread *td) +passclose(struct dev_close_args *ap) { + cdev_t dev = ap->a_head.a_dev; struct cam_periph *periph; struct pass_softc *softc; int unit, error; @@ -449,13 +442,15 @@ passclose(dev_t dev, int flag, int fmt, struct thread *td) * can understand. The transfer is described by a buf and will include * only one physical transfer. */ -static void -passstrategy(struct buf *bp) +static int +passstrategy(struct dev_strategy_args *ap) { + cdev_t dev = ap->a_head.a_dev; + struct bio *bio = ap->a_bio; + struct buf *bp = bio->bio_buf; struct cam_periph *periph; struct pass_softc *softc; u_int unit; - int s; /* * The read/write interface for the passthrough driver doesn't @@ -465,9 +460,9 @@ passstrategy(struct buf *bp) bp->b_error = EINVAL; goto bad; - /* unit = dkunit(bp->b_dev); */ + /* unit = dkunit(dev); */ /* XXX KDM fix this */ - unit = minor(bp->b_dev) & 0xff; + unit = minor(dev) & 0xff; periph = cam_extend_get(passperiphs, unit); if (periph == NULL) { @@ -480,7 +475,7 @@ passstrategy(struct buf *bp) * Odd number of bytes or negative offset */ /* valid request? */ - if (bp->b_blkno < 0) { + if (bio->bio_offset < 0) { bp->b_error = EINVAL; goto bad; } @@ -490,18 +485,16 @@ passstrategy(struct buf *bp) * after we are in the queue. Otherwise, we might not properly * clean up one of the buffers. */ - s = splbio(); - - bufq_insert_tail(&softc->buf_queue, bp); - - splx(s); + crit_enter(); + bioq_insert_tail(&softc->bio_queue, bio); + crit_exit(); /* * Schedule ourselves for performing the work. */ xpt_schedule(periph, /* XXX priority */1); - return; + return(0); bad: bp->b_flags |= B_ERROR; @@ -509,15 +502,14 @@ bad: * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; - biodone(bp); - return; + biodone(bio); + return(0); } static void passstart(struct cam_periph *periph, union ccb *start_ccb) { struct pass_softc *softc; - int s; softc = (struct pass_softc *)periph->softc; @@ -525,22 +517,24 @@ passstart(struct cam_periph *periph, union ccb *start_ccb) case PASS_STATE_NORMAL: { struct buf *bp; + struct bio *bio; - s = splbio(); - bp = bufq_first(&softc->buf_queue); + crit_enter(); + bio = bioq_first(&softc->bio_queue); if (periph->immediate_priority <= periph->pinfo.priority) { start_ccb->ccb_h.ccb_type = PASS_CCB_WAITING; SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, periph_links.sle); periph->immediate_priority = CAM_PRIORITY_NONE; - splx(s); + crit_exit(); wakeup(&periph->ccb_list); - } else if (bp == NULL) { - splx(s); + } else if (bio == NULL) { + crit_exit(); xpt_release_ccb(start_ccb); } else { - bufq_remove(&softc->buf_queue, bp); + bioq_remove(&softc->bio_queue, bio); + bp = bio->bio_buf; devstat_start_transaction(&softc->device_stats); @@ -555,14 +549,14 @@ passstart(struct cam_periph *periph, union ccb *start_ccb) bp->b_error = EIO; bp->b_flags |= B_ERROR; bp->b_resid = bp->b_bcount; - biodone(bp); - bp = bufq_first(&softc->buf_queue); - splx(s); + biodone(bio); + bio = bioq_first(&softc->bio_queue); + crit_exit(); xpt_action(start_ccb); } - if (bp != NULL) { + if (bio != NULL) { /* Have more work to do, so ensure we stay scheduled */ xpt_schedule(periph, /* XXX priority */1); } @@ -581,6 +575,7 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) switch (csio->ccb_h.ccb_type) { case PASS_CCB_BUFFER_IO: { + struct bio *bio; struct buf *bp; cam_status status; u_int8_t scsi_status; @@ -588,7 +583,9 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) status = done_ccb->ccb_h.status; scsi_status = done_ccb->csio.scsi_status; - bp = (struct buf *)done_ccb->ccb_h.ccb_bp; + bio = (struct bio *)done_ccb->ccb_h.ccb_bio; + bp = bio->bio_buf; + /* XXX handle errors */ if (!(((status & CAM_STATUS_MASK) == CAM_REQ_CMP) && (scsi_status == SCSI_STATUS_OK))) { @@ -618,7 +615,7 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) ds_flags = DEVSTAT_NO_DATA; devstat_end_transaction_buf(&softc->device_stats, bp); - biodone(bp); + biodone(bio); break; } case PASS_CCB_WAITING: @@ -632,8 +629,10 @@ passdone(struct cam_periph *periph, union ccb *done_ccb) } static int -passioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td) +passioctl(struct dev_ioctl_args *ap) { + cdev_t dev = ap->a_head.a_dev; + caddr_t addr = ap->a_data; struct cam_periph *periph; struct pass_softc *softc; u_int8_t unit; @@ -653,7 +652,7 @@ passioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td) error = 0; - switch (cmd) { + switch (ap->a_cmd) { case CAMIOCOMMAND: { @@ -712,7 +711,7 @@ passioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct thread *td) break; } default: - error = cam_periph_ioctl(periph, cmd, addr, passerror); + error = cam_periph_ioctl(periph, ap->a_cmd, addr, passerror); break; }