summaryrefslogtreecommitdiffstats
path: root/sys/cam/scsi/scsi_ses.c
diff options
context:
space:
mode:
authorscottl <scottl@FreeBSD.org>2007-04-15 08:49:19 +0000
committerscottl <scottl@FreeBSD.org>2007-04-15 08:49:19 +0000
commit7605c12c0f2bf784960d36288b7cb6e451b99a15 (patch)
tree010146772b36d16e6f98671b4bed7ce094acd633 /sys/cam/scsi/scsi_ses.c
parent3e3198a9661d5d1c3e35abc313ad0d4688c6eea6 (diff)
downloadFreeBSD-src-7605c12c0f2bf784960d36288b7cb6e451b99a15.zip
FreeBSD-src-7605c12c0f2bf784960d36288b7cb6e451b99a15.tar.gz
Remove Giant from CAM. Drivers (SIMs) now register a mutex that CAM will
use to synchornize and protect all data objects that are used for that SIM. Drivers that are not yet MPSAFE register Giant and operate as usual. RIght now, no drivers are MPSAFE, though a few will be changed in the coming week as this work settles down. The driver API has changed, so all CAM drivers will need to be recompiled. The userland API has not changed, so tools like camcontrol do not need to be recompiled.
Diffstat (limited to 'sys/cam/scsi/scsi_ses.c')
-rw-r--r--sys/cam/scsi/scsi_ses.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/sys/cam/scsi/scsi_ses.c b/sys/cam/scsi/scsi_ses.c
index 2af83ce..8e0b572 100644
--- a/sys/cam/scsi/scsi_ses.c
+++ b/sys/cam/scsi/scsi_ses.c
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <cam/cam_periph.h>
#include <cam/cam_xpt_periph.h>
#include <cam/cam_debug.h>
+#include <cam/cam_sim.h>
#include <cam/scsi/scsi_all.h>
#include <cam/scsi/scsi_message.h>
@@ -182,7 +183,7 @@ static struct cdevsw ses_cdevsw = {
.d_close = sesclose,
.d_ioctl = sesioctl,
.d_name = "ses",
- .d_flags = D_NEEDGIANT,
+ .d_flags = 0,
};
static void
@@ -363,9 +364,11 @@ sesregister(struct cam_periph *periph, void *arg)
return (CAM_REQ_CMP_ERR);
}
+ cam_periph_unlock(periph);
softc->ses_dev = make_dev(&ses_cdevsw, unit2minor(periph->unit_number),
UID_ROOT, GID_OPERATOR, 0600, "%s%d",
periph->periph_name, periph->unit_number);
+ cam_periph_lock(periph);
softc->ses_dev->si_drv1 = periph;
/*
@@ -409,25 +412,20 @@ sesopen(struct cdev *dev, int flags, int fmt, struct thread *td)
{
struct cam_periph *periph;
struct ses_softc *softc;
- int error, s;
+ int error = 0;
- s = splsoftcam();
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL) {
- splx(s);
return (ENXIO);
}
- if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0) {
- splx(s);
- return (error);
- }
- splx(s);
if (cam_periph_acquire(periph) != CAM_REQ_CMP) {
cam_periph_unlock(periph);
return (ENXIO);
}
+ cam_periph_lock(periph);
+
softc = (struct ses_softc *)periph->softc;
if (softc->ses_flags & SES_FLAG_INVALID) {
@@ -453,10 +451,10 @@ sesopen(struct cdev *dev, int flags, int fmt, struct thread *td)
}
out:
+ cam_periph_unlock(periph);
if (error) {
cam_periph_release(periph);
}
- cam_periph_unlock(periph);
return (error);
}
@@ -473,11 +471,9 @@ sesclose(struct cdev *dev, int flag, int fmt, struct thread *td)
if (periph == NULL)
return (ENXIO);
- softc = (struct ses_softc *)periph->softc;
-
- if ((error = cam_periph_lock(periph, PRIBIO)) != 0)
- return (error);
+ cam_periph_lock(periph);
+ softc = (struct ses_softc *)periph->softc;
softc->ses_flags &= ~SES_FLAG_OPEN;
cam_periph_unlock(periph);
@@ -489,13 +485,11 @@ sesclose(struct cdev *dev, int flag, int fmt, struct thread *td)
static void
sesstart(struct cam_periph *p, union ccb *sccb)
{
- int s = splbio();
if (p->immediate_priority <= p->pinfo.priority) {
SLIST_INSERT_HEAD(&p->ccb_list, &sccb->ccb_h, periph_links.sle);
p->immediate_priority = CAM_PRIORITY_NONE;
wakeup(&p->ccb_list);
}
- splx(s);
}
static void
@@ -539,14 +533,17 @@ sesioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag, struct thread
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering sesioctl\n"));
+ cam_periph_lock(periph);
ssc = (struct ses_softc *)periph->softc;
/*
* Now check to see whether we're initialized or not.
*/
if ((ssc->ses_flags & SES_FLAG_INITIALIZED) == 0) {
+ cam_periph_unlock(periph);
return (ENXIO);
}
+ cam_periph_lock(periph);
error = 0;
@@ -576,22 +573,34 @@ sesioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag, struct thread
break;
case SESIOC_GETOBJMAP:
+ /*
+ * XXX Dropping the lock while copying multiple segments is
+ * bogus.
+ */
+ cam_periph_lock(periph);
for (uobj = addr, i = 0; i != ssc->ses_nobjects; i++, uobj++) {
obj.obj_id = i;
obj.subencid = ssc->ses_objmap[i].subenclosure;
obj.object_type = ssc->ses_objmap[i].enctype;
+ cam_periph_lock(periph);
error = copyout(&obj, uobj, sizeof (ses_object));
+ cam_periph_lock(periph);
if (error) {
break;
}
}
+ cam_periph_lock(periph);
break;
case SESIOC_GETENCSTAT:
+ cam_periph_lock(periph);
error = (*ssc->ses_vec.get_encstat)(ssc, 1);
- if (error)
+ if (error) {
+ cam_periph_unlock(periph);
break;
+ }
tmp = ssc->ses_encstat & ~ENCI_SVALID;
+ cam_periph_unlock(periph);
error = copyout(&tmp, addr, sizeof (ses_encstat));
ssc->ses_encstat = tmp;
break;
@@ -600,7 +609,9 @@ sesioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag, struct thread
error = copyin(addr, &tmp, sizeof (ses_encstat));
if (error)
break;
+ cam_periph_lock(periph);
error = (*ssc->ses_vec.set_encstat)(ssc, tmp, 1);
+ cam_periph_unlock(periph);
break;
case SESIOC_GETOBJSTAT:
@@ -611,7 +622,9 @@ sesioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag, struct thread
error = EINVAL;
break;
}
+ cam_periph_lock(periph);
error = (*ssc->ses_vec.get_objstat)(ssc, &objs, 1);
+ cam_periph_unlock(periph);
if (error)
break;
error = copyout(&objs, addr, sizeof (ses_objstat));
@@ -630,7 +643,9 @@ sesioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag, struct thread
error = EINVAL;
break;
}
+ cam_periph_lock(periph);
error = (*ssc->ses_vec.set_objstat)(ssc, &objs, 1);
+ cam_periph_unlock(periph);
/*
* Always (for now) invalidate entry.
@@ -640,11 +655,15 @@ sesioctl(struct cdev *dev, u_long cmd, caddr_t arg_addr, int flag, struct thread
case SESIOC_INIT:
+ cam_periph_lock(periph);
error = (*ssc->ses_vec.init_enc)(ssc);
+ cam_periph_unlock(periph);
break;
default:
+ cam_periph_lock(periph);
error = cam_periph_ioctl(periph, cmd, arg_addr, seserror);
+ cam_periph_unlock(periph);
break;
}
return (error);
OpenPOWER on IntegriCloud