void cam_extend_release(struct extend_array *ea, int index) { void *p = cam_extend_get(ea, index); if (p) { ea->ps[index] = 0; } }
/* * Actually translate the requested transfer into one the physical driver * can understand. The transfer is described by a buf and will include * only one physical transfer. */ static void ptstrategy(struct buf *bp) { struct cam_periph *periph; struct pt_softc *softc; u_int unit; int s; unit = minor(bp->b_dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) { bp->b_error = ENXIO; goto bad; } softc = (struct pt_softc *)periph->softc; /* * 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. */ s = splbio(); /* * If the device has been made invalid, error out */ if ((softc->flags & PT_FLAG_DEVICE_INVALID)) { splx(s); bp->b_error = ENXIO; goto bad; } /* * Place it in the queue of disk activities for this disk */ bufq_insert_tail(&softc->buf_queue, bp); splx(s); /* * Schedule ourselves for performing the work. */ xpt_schedule(periph, /* XXX priority */1); return; bad: bp->b_flags |= B_ERROR; /* * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; biodone(bp); }
static int ptioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) { struct cam_periph *periph; struct pt_softc *softc; int unit; int error; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) return(ENXIO); softc = (struct pt_softc *)periph->softc; if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) { return (error); /* error code from tsleep */ } switch(cmd) { case PTIOCGETTIMEOUT: if (softc->io_timeout >= 1000) *(int *)addr = softc->io_timeout / 1000; else *(int *)addr = 0; break; case PTIOCSETTIMEOUT: { int s; if (*(int *)addr < 1) { error = EINVAL; break; } s = splsoftcam(); softc->io_timeout = *(int *)addr * 1000; splx(s); break; } default: error = cam_periph_ioctl(periph, cmd, addr, pterror); break; } cam_periph_unlock(periph); return(error); }
/* * Actually translate the requested transfer into one the physical driver * can understand. The transfer is described by a buf and will include * only one physical transfer. */ static int ptstrategy(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 pt_softc *softc; u_int unit; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) { bp->b_error = ENXIO; goto bad; } cam_periph_lock(periph); softc = (struct pt_softc *)periph->softc; /* * If the device has been made invalid, error out */ if ((softc->flags & PT_FLAG_DEVICE_INVALID)) { cam_periph_unlock(periph); bp->b_error = ENXIO; goto bad; } /* * Place it in the queue of disk activities for this disk */ bioq_insert_tail(&softc->bio_queue, bio); /* * Schedule ourselves for performing the work. */ xpt_schedule(periph, /* XXX priority */1); cam_periph_unlock(periph); return(0); bad: bp->b_flags |= B_ERROR; /* * Correctly set the buf to indicate a completed xfer */ bp->b_resid = bp->b_bcount; biodone(bio); return(0); }
static int ptioctl(struct dev_ioctl_args *ap) { cdev_t dev = ap->a_head.a_dev; caddr_t addr = ap->a_data; struct cam_periph *periph; struct pt_softc *softc; int unit; int error = 0; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) return(ENXIO); softc = (struct pt_softc *)periph->softc; cam_periph_lock(periph); switch(ap->a_cmd) { case PTIOCGETTIMEOUT: if (softc->io_timeout >= 1000) *(int *)addr = softc->io_timeout / 1000; else *(int *)addr = 0; break; case PTIOCSETTIMEOUT: if (*(int *)addr < 1) { error = EINVAL; break; } softc->io_timeout = *(int *)addr * 1000; break; default: error = cam_periph_ioctl(periph, ap->a_cmd, addr, pterror); break; } cam_periph_unlock(periph); return(error); }
static int ptopen(dev_t dev, int flags, int fmt, struct proc *p) { struct cam_periph *periph; struct pt_softc *softc; int unit; int error; int s; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) return (ENXIO); softc = (struct pt_softc *)periph->softc; s = splsoftcam(); if (softc->flags & PT_FLAG_DEVICE_INVALID) { splx(s); return(ENXIO); } CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ptopen: dev=%s (unit %d)\n", devtoname(dev), unit)); if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) { splx(s); return (error); /* error code from tsleep */ } splx(s); if ((softc->flags & PT_FLAG_OPEN) == 0) { if (cam_periph_acquire(periph) != CAM_REQ_CMP) error = ENXIO; else softc->flags |= PT_FLAG_OPEN; } else error = EBUSY; cam_periph_unlock(periph); return (error); }
static int ptclose(struct dev_close_args *ap) { cdev_t dev = ap->a_head.a_dev; struct cam_periph *periph; struct pt_softc *softc; int unit; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) return (ENXIO); softc = (struct pt_softc *)periph->softc; cam_periph_lock(periph); softc->flags &= ~PT_FLAG_OPEN; cam_periph_unlock(periph); cam_periph_release(periph); return (0); }
static int ptclose(dev_t dev, int flag, int fmt, struct proc *p) { struct cam_periph *periph; struct pt_softc *softc; int unit; int error; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (periph == NULL) return (ENXIO); softc = (struct pt_softc *)periph->softc; if ((error = cam_periph_lock(periph, PRIBIO)) != 0) return (error); /* error code from tsleep */ softc->flags &= ~PT_FLAG_OPEN; cam_periph_unlock(periph); cam_periph_release(periph); return (0); }
static int ptopen(struct dev_open_args *ap) { cdev_t dev = ap->a_head.a_dev; struct cam_periph *periph; struct pt_softc *softc; int unit; int error = 0; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); if (cam_periph_acquire(periph) != CAM_REQ_CMP) return (ENXIO); softc = (struct pt_softc *)periph->softc; cam_periph_lock(periph); if (softc->flags & PT_FLAG_DEVICE_INVALID) { cam_periph_unlock(periph); cam_periph_release(periph); return(ENXIO); } if ((softc->flags & PT_FLAG_OPEN) == 0) softc->flags |= PT_FLAG_OPEN; else { error = EBUSY; cam_periph_release(periph); } CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ptopen: dev=%s\n", devtoname(dev))); cam_periph_unlock(periph); return (error); }