diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c index 6d6fe291cf1f..70ab1b11a1d8 100644 --- a/sys/cam/cam_periph.c +++ b/sys/cam/cam_periph.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_periph.c,v 1.4 1998/10/13 21:41:32 ken Exp $ + * $Id: cam_periph.c,v 1.5 1998/10/15 17:46:18 ken Exp $ */ #include @@ -62,10 +62,11 @@ static void camperiphdone(struct cam_periph *periph, static void camperiphfree(struct cam_periph *periph); cam_status -cam_periph_alloc(periph_ctor_t *periph_ctor, periph_dtor_t *periph_dtor, - periph_start_t *periph_start, char *name, cam_periph_type type, - struct cam_path *path, ac_callback_t *ac_callback, - ac_code code, void *arg) +cam_periph_alloc(periph_ctor_t *periph_ctor, + periph_oninv_t *periph_oninvalidate, + periph_dtor_t *periph_dtor, periph_start_t *periph_start, + char *name, cam_periph_type type, struct cam_path *path, + ac_callback_t *ac_callback, ac_code code, void *arg) { struct periph_driver **p_drv; struct cam_periph *periph; @@ -122,6 +123,7 @@ cam_periph_alloc(periph_ctor_t *periph_ctor, periph_dtor_t *periph_dtor, cam_init_pinfo(&periph->pinfo); periph->periph_start = periph_start; periph->periph_dtor = periph_dtor; + periph->periph_oninval = periph_oninvalidate; periph->type = type; periph->periph_name = name; periph->unit_number = camperiphunit(*p_drv, path_id, target_id, lun_id); @@ -372,10 +374,19 @@ cam_periph_invalidate(struct cam_periph *periph) { int s; + s = splsoftcam(); + /* + * We only call this routine the first time a peripheral is + * invalidated. The oninvalidate() routine is always called at + * splsoftcam(). + */ + if (((periph->flags & CAM_PERIPH_INVALID) == 0) + && (periph->periph_oninval != NULL)) + periph->periph_oninval(periph); + periph->flags |= CAM_PERIPH_INVALID; periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND; - s = splsoftcam(); if (periph->refcount == 0) camperiphfree(periph); else if (periph->refcount < 0) diff --git a/sys/cam/cam_periph.h b/sys/cam/cam_periph.h index 8e81526d53fd..9bad491f14a1 100644 --- a/sys/cam/cam_periph.h +++ b/sys/cam/cam_periph.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_periph.h,v 1.1 1998/09/15 06:33:23 gibbs Exp $ + * $Id: cam_periph.h,v 1.2 1998/10/13 21:41:32 ken Exp $ */ #ifndef _CAM_CAM_PERIPH_H @@ -66,11 +66,12 @@ typedef void periph_start_t (struct cam_periph *periph, union ccb *start_ccb); typedef cam_status periph_ctor_t (struct cam_periph *periph, void *arg); +typedef void periph_oninv_t (struct cam_periph *periph); typedef void periph_dtor_t (struct cam_periph *periph); - struct cam_periph { cam_pinfo pinfo; periph_start_t *periph_start; + periph_oninv_t *periph_oninval; periph_dtor_t *periph_dtor; char *periph_name; struct cam_path *path; /* Compiled path to device */ @@ -100,7 +101,10 @@ struct cam_periph_map_info { struct buf *bp[CAM_PERIPH_MAXMAPS]; }; -cam_status cam_periph_alloc(periph_ctor_t*, periph_dtor_t*, periph_start_t*, +cam_status cam_periph_alloc(periph_ctor_t *periph_ctor, + periph_oninv_t *periph_oninvalidate, + periph_dtor_t *periph_dtor, + periph_start_t *periph_start, char *name, cam_periph_type type, struct cam_path *, ac_callback_t *, ac_code, void *arg); struct cam_periph *cam_periph_find(struct cam_path *path, char *name); int cam_periph_lock(struct cam_periph *periph, int priority); diff --git a/sys/cam/cam_xpt.c b/sys/cam/cam_xpt.c index fdd0de518a46..e3f86c0ce614 100644 --- a/sys/cam/cam_xpt.c +++ b/sys/cam/cam_xpt.c @@ -26,7 +26,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: cam_xpt.c,v 1.23 1998/10/15 17:46:18 ken Exp $ + * $Id: cam_xpt.c,v 1.24 1998/10/15 19:08:52 ken Exp $ */ #include #include @@ -1161,7 +1161,7 @@ xpt_init() return; } - cam_periph_alloc(xptregister, NULL, NULL, "xpt", CAM_PERIPH_BIO, + cam_periph_alloc(xptregister, NULL, NULL, NULL, "xpt", CAM_PERIPH_BIO, path, NULL, 0, NULL); xpt_free_path(path); @@ -4777,7 +4777,7 @@ xpt_scan_lun(struct cam_periph *periph, struct cam_path *path, TAILQ_INSERT_TAIL(&softc->request_ccbs, &request_ccb->ccb_h, periph_links.tqe); } else { - status = cam_periph_alloc(proberegister, probecleanup, + status = cam_periph_alloc(proberegister, NULL, probecleanup, probestart, "probe", CAM_PERIPH_BIO, request_ccb->ccb_h.path, NULL, 0, diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index d1f0a4c52896..dfe86fc4180c 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_cd.c,v 1.6 1998/10/12 17:02:37 ken Exp $ + * $Id: scsi_cd.c,v 1.7 1998/10/15 17:46:26 ken Exp $ */ /* * Portions of this driver taken from the original FreeBSD cd driver. @@ -187,6 +187,7 @@ static periph_init_t cdinit; static periph_ctor_t cdregister; static periph_dtor_t cdcleanup; static periph_start_t cdstart; +static periph_oninv_t cdoninvalidate; static void cdasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg); static void cdshorttimeout(void *arg); @@ -351,15 +352,75 @@ cdinit(void) } } +static void +cdoninvalidate(struct cam_periph *periph) +{ + int s; + struct cd_softc *softc; + struct buf *q_bp; + struct ccb_setasync csa; + + softc = (struct cd_softc *)periph->softc; + + /* + * De-register any async callbacks. + */ + xpt_setup_ccb(&csa.ccb_h, periph->path, + /* priority */ 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = cdasync; + csa.callback_arg = periph; + xpt_action((union ccb *)&csa); + + softc->flags |= CD_FLAG_INVALID; + + /* + * Although the oninvalidate() routines are always called at + * splsoftcam, we need to be at splbio() here to keep the buffer + * queue from being modified while we traverse it. + */ + s = splbio(); + + /* + * 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); + q_bp->b_resid = q_bp->b_bcount; + q_bp->b_error = ENXIO; + q_bp->b_flags |= B_ERROR; + biodone(q_bp); + } + splx(s); + + /* + * If this device is part of a changer, and it was scheduled + * to run, remove it from the run queue since we just nuked + * all of its scheduled I/O. + */ + if ((softc->flags & CD_FLAG_CHANGER) + && (softc->pinfo.index != CAM_UNQUEUED_INDEX)) + camq_remove(&softc->changer->devq, softc->pinfo.index); + + xpt_print_path(periph->path); + printf("lost device\n"); +} + static void cdcleanup(struct cam_periph *periph) { struct cd_softc *softc; + int s; softc = (struct cd_softc *)periph->softc; xpt_print_path(periph->path); printf("removing device entry\n"); + + s = splsoftcam(); /* * In the queued, non-active case, the device in question * has already been removed from the changer run queue. Since this @@ -429,8 +490,10 @@ cdcleanup(struct cam_periph *periph) free(softc->changer, M_DEVBUF); num_changers--; } + devstat_remove_entry(&softc->device_stats); cam_extend_release(cdperiphs, periph->unit_number); - free(periph->softc, M_DEVBUF); + free(softc, M_DEVBUF); + splx(s); } static void @@ -456,9 +519,11 @@ cdasync(void *callback_arg, u_int32_t code, * this device and start the probe * process. */ - status = cam_periph_alloc(cdregister, cdcleanup, cdstart, - "cd", CAM_PERIPH_BIO, cgd->ccb_h.path, - cdasync, AC_FOUND_DEVICE, cgd); + status = cam_periph_alloc(cdregister, cdoninvalidate, + cdcleanup, cdstart, + "cd", CAM_PERIPH_BIO, + cgd->ccb_h.path, cdasync, + AC_FOUND_DEVICE, cgd); if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) @@ -468,65 +533,8 @@ cdasync(void *callback_arg, u_int32_t code, break; } case AC_LOST_DEVICE: - { - int s; - struct cd_softc *softc; - struct buf *q_bp; - struct ccb_setasync csa; - - softc = (struct cd_softc *)periph->softc; - - /* - * Insure that no other async callbacks that - * might affect this peripheral can come through. - */ - s = splcam(); - - /* - * De-register any async callbacks. - */ - xpt_setup_ccb(&csa.ccb_h, periph->path, - /* priority */ 5); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = 0; - csa.callback = cdasync; - csa.callback_arg = periph; - xpt_action((union ccb *)&csa); - - softc->flags |= CD_FLAG_INVALID; - - /* - * 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); - q_bp->b_resid = q_bp->b_bcount; - q_bp->b_error = ENXIO; - q_bp->b_flags |= B_ERROR; - biodone(q_bp); - } - - /* - * If this device is part of a changer, and it was scheduled - * to run, remove it from the run queue since we just nuked - * all of its scheduled I/O. - */ - if ((softc->flags & CD_FLAG_CHANGER) - && (softc->pinfo.index != CAM_UNQUEUED_INDEX)) - camq_remove(&softc->changer->devq, softc->pinfo.index); - - devstat_remove_entry(&softc->device_stats); - - xpt_print_path(periph->path); - printf("lost device\n"); - - splx(s); - cam_periph_invalidate(periph); break; - } case AC_SENT_BDR: case AC_BUS_RESET: { @@ -872,6 +880,7 @@ cdopen(dev_t dev, int flags, int fmt, struct proc *p) struct ccb_getdev cgd; u_int32_t size; int unit, error; + int s; unit = dkunit(dev); periph = cam_extend_get(cdperiphs, unit); @@ -881,8 +890,12 @@ cdopen(dev_t dev, int flags, int fmt, struct proc *p) softc = (struct cd_softc *)periph->softc; - if (softc->flags & CD_FLAG_INVALID) + s = splsoftcam(); + if (softc->flags & CD_FLAG_INVALID) { + splx(s); return(ENXIO); + } + splx(s); if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0) return (error); @@ -1774,17 +1787,18 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) } xpt_print_path(periph->path); printf("fatal error, failed" - " to attach to device"); + " to attach to device\n"); /* - * Free up resources. + * Invalidate this peripheral. */ cam_periph_invalidate(periph); announce_buf[0] = '\0'; } else { + /* - * Free up resources. + * Invalidate this peripheral. */ cam_periph_invalidate(periph); announce_buf[0] = '\0'; diff --git a/sys/cam/scsi/scsi_ch.c b/sys/cam/scsi/scsi_ch.c index 1f16eb389ec2..32bb92da93f5 100644 --- a/sys/cam/scsi/scsi_ch.c +++ b/sys/cam/scsi/scsi_ch.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_ch.c,v 1.3 1998/10/02 21:20:21 ken Exp $ + * $Id: scsi_ch.c,v 1.4 1998/10/15 17:46:26 ken Exp $ */ /* * Derived from the NetBSD SCSI changer driver. @@ -183,6 +183,7 @@ static d_close_t chclose; static d_ioctl_t chioctl; static periph_init_t chinit; static periph_ctor_t chregister; +static periph_oninv_t choninvalidate; static periph_dtor_t chcleanup; static periph_start_t chstart; static void chasync(void *callback_arg, u_int32_t code, @@ -285,14 +286,44 @@ chinit(void) } } +static void +choninvalidate(struct cam_periph *periph) +{ + struct ch_softc *softc; + struct ccb_setasync csa; + + softc = (struct ch_softc *)periph->softc; + + /* + * De-register any async callbacks. + */ + xpt_setup_ccb(&csa.ccb_h, periph->path, + /* priority */ 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = chasync; + csa.callback_arg = periph; + xpt_action((union ccb *)&csa); + + softc->flags |= CH_FLAG_INVALID; + + xpt_print_path(periph->path); + printf("lost device\n"); + +} + static void chcleanup(struct cam_periph *periph) { + struct ch_softc *softc; - cam_extend_release(chperiphs, periph->unit_number); - xpt_print_path(periph->path); - printf("removing device entry\n"); - free(periph->softc, M_DEVBUF); + softc = (struct ch_softc *)periph->softc; + + devstat_remove_entry(&softc->device_stats); + cam_extend_release(chperiphs, periph->unit_number); + xpt_print_path(periph->path); + printf("removing device entry\n"); + free(softc, M_DEVBUF); } static void @@ -318,8 +349,9 @@ chasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) * this device and start the probe * process. */ - status = cam_periph_alloc(chregister, chcleanup, chstart, - "ch", CAM_PERIPH_BIO, cgd->ccb_h.path, + status = cam_periph_alloc(chregister, choninvalidate, + chcleanup, chstart, "ch", + CAM_PERIPH_BIO, cgd->ccb_h.path, chasync, AC_FOUND_DEVICE, cgd); if (status != CAM_REQ_CMP @@ -331,42 +363,8 @@ chasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) } case AC_LOST_DEVICE: - { - int s; - struct ch_softc *softc; - struct ccb_setasync csa; - - softc = (struct ch_softc *)periph->softc; - - /* - * Insure that no other async callbacks that - * might affect this peripheral can come through. - */ - s = splcam(); - - /* - * De-register any async callbacks. - */ - xpt_setup_ccb(&csa.ccb_h, periph->path, - /* priority */ 5); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = 0; - csa.callback = chasync; - csa.callback_arg = periph; - xpt_action((union ccb *)&csa); - - softc->flags |= CH_FLAG_INVALID; - - devstat_remove_entry(&softc->device_stats); - - xpt_print_path(periph->path); - printf("lost device\n"); - - splx(s); - cam_periph_invalidate(periph); break; - } case AC_TRANSFER_NEG: case AC_SENT_BDR: case AC_SCSI_AEN: @@ -445,6 +443,7 @@ chopen(dev_t dev, int flags, int fmt, struct proc *p) struct cam_periph *periph; struct ch_softc *softc; int unit, error; + int s; unit = CHUNIT(dev); periph = cam_extend_get(chperiphs, unit); @@ -454,8 +453,12 @@ chopen(dev_t dev, int flags, int fmt, struct proc *p) softc = (struct ch_softc *)periph->softc; - if (softc->flags & CH_FLAG_INVALID) + s = splsoftcam(); + if (softc->flags & CH_FLAG_INVALID) { + splx(s); return(ENXIO); + } + splx(s); if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0) return (error); diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 30f88ddc5e94..541e64c5f9bb 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_da.c,v 1.10 1998/10/13 08:24:29 dg Exp $ + * $Id: scsi_da.c,v 1.11 1998/10/13 23:34:54 ken Exp $ */ #include "opt_hw_wdog.h" @@ -163,6 +163,7 @@ static void daasync(void *callback_arg, u_int32_t code, static periph_ctor_t daregister; static periph_dtor_t dacleanup; static periph_start_t dastart; +static periph_oninv_t daoninvalidate; static void dadone(struct cam_periph *periph, union ccb *done_ccb); static int daerror(union ccb *ccb, u_int32_t cam_flags, @@ -244,6 +245,7 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) int unit; int part; int error; + int s; unit = dkunit(dev); part = dkpart(dev); @@ -267,12 +269,14 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) 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); } @@ -281,6 +285,7 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) dsgone(&softc->dk_slices); softc->flags &= ~DA_FLAG_PACK_INVALID; } + splx(s); /* Do a read capacity */ { @@ -788,13 +793,68 @@ dainit(void) } } +static void +daoninvalidate(struct cam_periph *periph) +{ + int s; + struct da_softc *softc; + struct buf *q_bp; + struct ccb_setasync csa; + + softc = (struct da_softc *)periph->softc; + + /* + * De-register any async callbacks. + */ + xpt_setup_ccb(&csa.ccb_h, periph->path, + /* priority */ 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = daasync; + csa.callback_arg = periph; + xpt_action((union ccb *)&csa); + + softc->flags |= DA_FLAG_PACK_INVALID; + + /* + * Although the oninvalidate() routines are always called at + * splsoftcam, we need to be at splbio() here to keep the buffer + * queue from being modified while we traverse it. + */ + s = splbio(); + + /* + * 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); + q_bp->b_resid = q_bp->b_bcount; + q_bp->b_error = ENXIO; + q_bp->b_flags |= B_ERROR; + biodone(q_bp); + } + splx(s); + + SLIST_REMOVE(&softc_list, softc, da_softc, links); + + xpt_print_path(periph->path); + printf("lost device\n"); +} + static void dacleanup(struct cam_periph *periph) { + struct da_softc *softc; + + softc = (struct da_softc *)periph->softc; + + devstat_remove_entry(&softc->device_stats); cam_extend_release(daperiphs, periph->unit_number); xpt_print_path(periph->path); printf("removing device entry\n"); - free(periph->softc, M_DEVBUF); + free(softc, M_DEVBUF); } static void @@ -820,9 +880,11 @@ daasync(void *callback_arg, u_int32_t code, * this device and start the probe * process. */ - status = cam_periph_alloc(daregister, dacleanup, dastart, - "da", CAM_PERIPH_BIO, cgd->ccb_h.path, - daasync, AC_FOUND_DEVICE, cgd); + status = cam_periph_alloc(daregister, daoninvalidate, + dacleanup, dastart, + "da", CAM_PERIPH_BIO, + cgd->ccb_h.path, daasync, + AC_FOUND_DEVICE, cgd); if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) @@ -831,57 +893,8 @@ daasync(void *callback_arg, u_int32_t code, break; } case AC_LOST_DEVICE: - { - int s; - struct da_softc *softc; - struct buf *q_bp; - struct ccb_setasync csa; - - softc = (struct da_softc *)periph->softc; - - /* - * Insure that no other async callbacks that - * might affect this peripheral can come through. - */ - s = splcam(); - - /* - * De-register any async callbacks. - */ - xpt_setup_ccb(&csa.ccb_h, periph->path, - /* priority */ 5); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = 0; - csa.callback = daasync; - csa.callback_arg = periph; - xpt_action((union ccb *)&csa); - - softc->flags |= DA_FLAG_PACK_INVALID; - - /* - * 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); - q_bp->b_resid = q_bp->b_bcount; - q_bp->b_error = ENXIO; - q_bp->b_flags |= B_ERROR; - biodone(q_bp); - } - devstat_remove_entry(&softc->device_stats); - - SLIST_REMOVE(&softc_list, softc, da_softc, links); - - xpt_print_path(periph->path); - printf("lost device\n"); - - splx(s); - cam_periph_invalidate(periph); break; - } case AC_SENT_BDR: case AC_BUS_RESET: { @@ -1331,7 +1344,7 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) xpt_print_path(periph->path); printf("fatal error, failed" - " to attach to device"); + " to attach to device\n"); /* * Free up resources. diff --git a/sys/cam/scsi/scsi_pass.c b/sys/cam/scsi/scsi_pass.c index 8d861c276d4f..7e9055a78ccc 100644 --- a/sys/cam/scsi/scsi_pass.c +++ b/sys/cam/scsi/scsi_pass.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_pass.c,v 1.2 1998/09/16 00:11:53 ken Exp $ + * $Id: scsi_pass.c,v 1.3 1998/10/15 17:46:26 ken Exp $ */ #include @@ -42,7 +42,6 @@ #include #include #include -#include #include #include @@ -104,6 +103,7 @@ static d_strategy_t passstrategy; static periph_init_t passinit; static periph_ctor_t passregister; +static periph_oninv_t passoninvalidate; static periph_dtor_t passcleanup; static periph_start_t passstart; static void passasync(void *callback_arg, u_int32_t code, @@ -196,16 +196,73 @@ passinit(void) } +static void +passoninvalidate(struct cam_periph *periph) +{ + int s; + struct pass_softc *softc; + struct buf *q_bp; + struct ccb_setasync csa; + + softc = (struct pass_softc *)periph->softc; + + /* + * De-register any async callbacks. + */ + xpt_setup_ccb(&csa.ccb_h, periph->path, + /* priority */ 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = passasync; + csa.callback_arg = periph; + xpt_action((union ccb *)&csa); + + 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 + * queue from being modified while we traverse it. + */ + s = splbio(); + + /* + * 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); + q_bp->b_resid = q_bp->b_bcount; + q_bp->b_error = ENXIO; + q_bp->b_flags |= B_ERROR; + biodone(q_bp); + } + splx(s); + + if (bootverbose) { + xpt_print_path(periph->path); + printf("lost device\n"); + } + +} + static void passcleanup(struct cam_periph *periph) { + struct pass_softc *softc; + + softc = (struct pass_softc *)periph->softc; + + devstat_remove_entry(&softc->device_stats); + cam_extend_release(passperiphs, periph->unit_number); if (bootverbose) { xpt_print_path(periph->path); printf("removing device entry\n"); } - free(periph->softc, M_DEVBUF); + free(softc, M_DEVBUF); } static void @@ -229,10 +286,10 @@ passasync(void *callback_arg, u_int32_t code, * this device and start the probe * process. */ - status = cam_periph_alloc(passregister, passcleanup, passstart, - "pass", CAM_PERIPH_BIO, - cgd->ccb_h.path, passasync, - AC_FOUND_DEVICE, cgd); + status = cam_periph_alloc(passregister, passoninvalidate, + passcleanup, passstart, "pass", + CAM_PERIPH_BIO, cgd->ccb_h.path, + passasync, AC_FOUND_DEVICE, cgd); if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) @@ -242,57 +299,8 @@ passasync(void *callback_arg, u_int32_t code, break; } case AC_LOST_DEVICE: - { - int s; - struct pass_softc *softc; - struct buf *q_bp; - struct ccb_setasync csa; - - softc = (struct pass_softc *)periph->softc; - - /* - * Insure that no other async callbacks that - * might affect this peripheral can come through. - */ - s = splcam(); - - /* - * De-register any async callbacks. - */ - xpt_setup_ccb(&csa.ccb_h, periph->path, - /* priority */ 5); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = 0; - csa.callback = passasync; - csa.callback_arg = periph; - xpt_action((union ccb *)&csa); - - softc->flags |= PASS_FLAG_INVALID; - - /* - * 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); - q_bp->b_resid = q_bp->b_bcount; - q_bp->b_error = ENXIO; - q_bp->b_flags |= B_ERROR; - biodone(q_bp); - } - devstat_remove_entry(&softc->device_stats); - - if (bootverbose) { - xpt_print_path(periph->path); - printf("lost device\n"); - } - - splx(s); - cam_periph_invalidate(periph); break; - } case AC_TRANSFER_NEG: case AC_SENT_BDR: case AC_SCSI_AEN: @@ -371,6 +379,7 @@ passopen(dev_t dev, int flags, int fmt, struct proc *p) struct cam_periph *periph; struct pass_softc *softc; int unit, error; + int s; error = 0; /* default to no error */ @@ -385,8 +394,12 @@ passopen(dev_t dev, int flags, int fmt, struct proc *p) softc = (struct pass_softc *)periph->softc; - if (softc->flags & PASS_FLAG_INVALID) + s = splsoftcam(); + if (softc->flags & PASS_FLAG_INVALID) { + splx(s); return(ENXIO); + } + splx(s); /* * Only allow read-write access. diff --git a/sys/cam/scsi/scsi_pt.c b/sys/cam/scsi/scsi_pt.c index b225d76a8e93..deace7d8cc49 100644 --- a/sys/cam/scsi/scsi_pt.c +++ b/sys/cam/scsi/scsi_pt.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_pt.c,v 1.1 1998/09/15 06:36:34 gibbs Exp $ + * $Id: scsi_pt.c,v 1.2 1998/10/15 17:46:26 ken Exp $ */ #include @@ -90,6 +90,7 @@ static periph_init_t ptinit; static void ptasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg); static periph_ctor_t ptctor; +static periph_oninv_t ptoninvalidate; static periph_dtor_t ptdtor; static periph_start_t ptstart; static void ptdone(struct cam_periph *periph, @@ -145,6 +146,7 @@ ptopen(dev_t dev, int flags, int fmt, struct proc *p) struct pt_softc *softc; int unit; int error; + int s; unit = minor(dev); periph = cam_extend_get(ptperiphs, unit); @@ -153,6 +155,13 @@ ptopen(dev_t dev, int flags, int fmt, struct proc *p) softc = (struct pt_softc *)periph->softc; + s = splsoftcam(); + if (softc->flags & PT_FLAG_DEVICE_INVALID) { + splx(s); + return(ENXIO); + } + splx(s); + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("ptopen: dev=0x%x (unit %d)\n", dev, unit)); @@ -383,13 +392,68 @@ ptctor(struct cam_periph *periph, void *arg) return(CAM_REQ_CMP); } +static void +ptoninvalidate(struct cam_periph *periph) +{ + int s; + struct pt_softc *softc; + struct buf *q_bp; + struct ccb_setasync csa; + + softc = (struct pt_softc *)periph->softc; + + /* + * De-register any async callbacks. + */ + xpt_setup_ccb(&csa.ccb_h, periph->path, + /* priority */ 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = ptasync; + csa.callback_arg = periph; + xpt_action((union ccb *)&csa); + + softc->flags |= PT_FLAG_DEVICE_INVALID; + + /* + * Although the oninvalidate() routines are always called at + * splsoftcam, we need to be at splbio() here to keep the buffer + * queue from being modified while we traverse it. + */ + s = splbio(); + + /* + * 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); + q_bp->b_resid = q_bp->b_bcount; + q_bp->b_error = ENXIO; + q_bp->b_flags |= B_ERROR; + biodone(q_bp); + } + + splx(s); + + xpt_print_path(periph->path); + printf("lost device\n"); +} + static void ptdtor(struct cam_periph *periph) { + struct pt_softc *softc; + + softc = (struct pt_softc *)periph->softc; + + devstat_remove_entry(&softc->device_stats); + cam_extend_release(ptperiphs, periph->unit_number); xpt_print_path(periph->path); printf("removing device entry\n"); - free(periph->softc, M_DEVBUF); + free(softc, M_DEVBUF); } static void @@ -414,9 +478,10 @@ ptasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) * this device and start the probe * process. */ - status = cam_periph_alloc(ptctor, ptdtor, ptstart, - "pt", CAM_PERIPH_BIO, cgd->ccb_h.path, - ptasync, AC_FOUND_DEVICE, cgd); + status = cam_periph_alloc(ptctor, ptoninvalidate, ptdtor, + ptstart, "pt", CAM_PERIPH_BIO, + cgd->ccb_h.path, ptasync, + AC_FOUND_DEVICE, cgd); if (status != CAM_REQ_CMP && status != CAM_REQ_INPROG) @@ -426,51 +491,6 @@ ptasync(void *callback_arg, u_int32_t code, struct cam_path *path, void *arg) } case AC_LOST_DEVICE: { - int s; - struct pt_softc *softc; - struct buf *q_bp; - struct ccb_setasync csa; - - softc = (struct pt_softc *)periph->softc; - - /* - * Insure that no other async callbacks that - * might affect this peripheral can come through. - */ - s = splcam(); - - /* - * De-register any async callbacks. - */ - xpt_setup_ccb(&csa.ccb_h, periph->path, - /* priority */ 5); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = 0; - csa.callback = ptasync; - csa.callback_arg = periph; - xpt_action((union ccb *)&csa); - - softc->flags |= PT_FLAG_DEVICE_INVALID; - - /* - * 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); - q_bp->b_resid = q_bp->b_bcount; - q_bp->b_error = ENXIO; - q_bp->b_flags |= B_ERROR; - biodone(q_bp); - } - devstat_remove_entry(&softc->device_stats); - - xpt_print_path(periph->path); - printf("lost device\n"); - - splx(s); - cam_periph_invalidate(periph); break; } diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index 59b213f4659c..07f992d555f1 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_sa.c,v 1.2 1998/10/02 05:15:27 ken Exp $ + * $Id: scsi_sa.c,v 1.3 1998/10/15 17:46:26 ken Exp $ */ #include @@ -172,6 +172,7 @@ static d_strategy_t sastrategy; static d_ioctl_t saioctl; static periph_init_t sainit; static periph_ctor_t saregister; +static periph_oninv_t saoninvalidate; static periph_dtor_t sacleanup; static periph_start_t sastart; static void saasync(void *callback_arg, u_int32_t code, @@ -263,6 +264,7 @@ saopen(dev_t dev, int flags, int fmt, struct proc *p) int mode; int density; int error; + int s; unit = SAUNIT(dev); mode = SAMODE(dev); @@ -278,8 +280,12 @@ saopen(dev_t dev, int flags, int fmt, struct proc *p) ("saaopen: dev=0x%x (unit %d , mode %d, density %d)\n", dev, unit, mode, density)); - if (softc->flags & SA_FLAG_INVALID) + s = splsoftcam(); + if (softc->flags & SA_FLAG_INVALID) { + splx(s); return(ENXIO); + } + splx(s); if ((error = cam_periph_lock(periph, PRIBIO|PCATCH)) != 0) { return (error); /* error code from tsleep */ @@ -398,6 +404,16 @@ sastrategy(struct buf *bp) } softc = (struct sa_softc *)periph->softc; + s = splsoftcam(); + + if (softc->flags & SA_FLAG_INVALID) { + splx(s); + bp->b_error = ENXIO; + goto bad; + } + + splx(s); + /* * If it's a null transfer, return immediatly */ @@ -706,13 +722,67 @@ sainit(void) } } +static void +saoninvalidate(struct cam_periph *periph) +{ + struct sa_softc *softc; + struct buf *q_bp; + struct ccb_setasync csa; + int s; + + softc = (struct sa_softc *)periph->softc; + + /* + * De-register any async callbacks. + */ + xpt_setup_ccb(&csa.ccb_h, periph->path, + /* priority */ 5); + csa.ccb_h.func_code = XPT_SASYNC_CB; + csa.event_enable = 0; + csa.callback = saasync; + csa.callback_arg = periph; + xpt_action((union ccb *)&csa); + + softc->flags |= SA_FLAG_INVALID; + + /* + * Although the oninvalidate() routines are always called at + * splsoftcam, we need to be at splbio() here to keep the buffer + * queue from being modified while we traverse it. + */ + s = splbio(); + + /* + * 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); + q_bp->b_resid = q_bp->b_bcount; + q_bp->b_error = ENXIO; + q_bp->b_flags |= B_ERROR; + biodone(q_bp); + } + splx(s); + + xpt_print_path(periph->path); + printf("lost device\n"); + +} + static void sacleanup(struct cam_periph *periph) { + struct sa_softc *softc; + + softc = (struct sa_softc *)periph->softc; + + devstat_remove_entry(&softc->device_stats); cam_extend_release(saperiphs, periph->unit_number); xpt_print_path(periph->path); printf("removing device entry\n"); - free(periph->softc, M_DEVBUF); + free(softc, M_DEVBUF); } static void @@ -738,7 +808,8 @@ saasync(void *callback_arg, u_int32_t code, * this device and start the probe * process. */ - status = cam_periph_alloc(saregister, sacleanup, sastart, + status = cam_periph_alloc(saregister, saoninvalidate, + sacleanup, sastart, "sa", CAM_PERIPH_BIO, cgd->ccb_h.path, saasync, AC_FOUND_DEVICE, cgd); @@ -749,54 +820,8 @@ saasync(void *callback_arg, u_int32_t code, break; } case AC_LOST_DEVICE: - { - int s; - struct sa_softc *softc; - struct buf *q_bp; - struct ccb_setasync csa; - - softc = (struct sa_softc *)periph->softc; - - /* - * Insure that no other async callbacks that - * might affect this peripheral can come through. - */ - s = splcam(); - - /* - * De-register any async callbacks. - */ - xpt_setup_ccb(&csa.ccb_h, periph->path, - /* priority */ 5); - csa.ccb_h.func_code = XPT_SASYNC_CB; - csa.event_enable = 0; - csa.callback = saasync; - csa.callback_arg = periph; - xpt_action((union ccb *)&csa); - - softc->flags |= SA_FLAG_INVALID; - - /* - * 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); - q_bp->b_resid = q_bp->b_bcount; - q_bp->b_error = ENXIO; - q_bp->b_flags |= B_ERROR; - biodone(q_bp); - } - devstat_remove_entry(&softc->device_stats); - - xpt_print_path(periph->path); - printf("lost device\n"); - - splx(s); - cam_periph_invalidate(periph); - } + break; case AC_TRANSFER_NEG: case AC_SENT_BDR: case AC_SCSI_AEN: diff --git a/sys/cam/scsi/scsi_target.c b/sys/cam/scsi/scsi_target.c index 4c50f140e160..a1960dec6fd7 100644 --- a/sys/cam/scsi/scsi_target.c +++ b/sys/cam/scsi/scsi_target.c @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_target.c,v 1.1 1998/09/15 06:36:34 gibbs Exp $ + * $Id: scsi_target.c,v 1.2 1998/09/15 22:05:42 gibbs Exp $ */ #include /* For offsetof */ @@ -261,7 +261,7 @@ targasync(void *callback_arg, u_int32_t code, "due to status 0x%x\n", status); break; } - status = cam_periph_alloc(targctor, targdtor, targstart, + status = cam_periph_alloc(targctor, NULL, targdtor, targstart, "targ", CAM_PERIPH_BIO, new_path, targasync, AC_PATH_REGISTERED,