diff options
author | scottl <scottl@FreeBSD.org> | 2007-04-15 08:49:19 +0000 |
---|---|---|
committer | scottl <scottl@FreeBSD.org> | 2007-04-15 08:49:19 +0000 |
commit | 7605c12c0f2bf784960d36288b7cb6e451b99a15 (patch) | |
tree | 010146772b36d16e6f98671b4bed7ce094acd633 /sys/cam/scsi/scsi_ses.c | |
parent | 3e3198a9661d5d1c3e35abc313ad0d4688c6eea6 (diff) | |
download | FreeBSD-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.c | 53 |
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); |