summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/cam/cam_periph.c23
-rw-r--r--sys/cam/cam_periph.h10
-rw-r--r--sys/cam/cam_xpt.c6
-rw-r--r--sys/cam/scsi/scsi_cd.c146
-rw-r--r--sys/cam/scsi/scsi_ch.c87
-rw-r--r--sys/cam/scsi/scsi_da.c123
-rw-r--r--sys/cam/scsi/scsi_pass.c127
-rw-r--r--sys/cam/scsi/scsi_pt.c120
-rw-r--r--sys/cam/scsi/scsi_sa.c127
-rw-r--r--sys/cam/scsi/scsi_target.c4
10 files changed, 438 insertions, 335 deletions
diff --git a/sys/cam/cam_periph.c b/sys/cam/cam_periph.c
index 6d6fe29..70ab1b1 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 <sys/param.h>
@@ -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 8e81526..9bad491 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 fdd0de5..e3f86c0 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 <sys/param.h>
#include <sys/systm.h>
@@ -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 d1f0a4c..dfe86fc 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);
@@ -352,14 +353,74 @@ 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 1f16eb3..32bb92d 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,
@@ -286,13 +287,43 @@ 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;
+
+ softc = (struct ch_softc *)periph->softc;
- cam_extend_release(chperiphs, periph->unit_number);
- xpt_print_path(periph->path);
- printf("removing device entry\n");
- free(periph->softc, M_DEVBUF);
+ 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 30f88dd..541e64c 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 */
{
@@ -789,12 +794,67 @@ 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 8d861c2..7e9055a7 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 <sys/param.h>
@@ -42,7 +42,6 @@
#include <sys/conf.h>
#include <sys/buf.h>
#include <sys/proc.h>
-#include <sys/cdio.h>
#include <sys/errno.h>
#include <sys/devicestat.h>
@@ -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,
@@ -197,15 +197,72 @@ 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 b225d76..deace7d 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 <sys/param.h>
@@ -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));
@@ -384,12 +393,67 @@ ptctor(struct cam_periph *periph, void *arg)
}
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 59b213f..07f992d 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 <sys/param.h>
@@ -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
*/
@@ -707,12 +723,66 @@ 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 4c50f14..a1960de 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 <stddef.h> /* 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,
OpenPOWER on IntegriCloud