PERFORCE change 117938 for review
Scott Long
scottl at FreeBSD.org
Thu Apr 12 04:17:24 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=117938
Change 117938 by scottl at scottl-y1 on 2007/04/12 04:17:03
Lock the SG periph.
Affected files ...
.. //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_sg.c#3 edit
Differences ...
==== //depot/projects/scottl-camlock/src/sys/cam/scsi/scsi_sg.c#3 (text+ko) ====
@@ -410,10 +410,6 @@
if (periph == NULL)
return (ENXIO);
- softc = (struct sg_softc *)periph->softc;
- if (softc->flags & SG_FLAG_INVALID)
- return (ENXIO);
-
/*
* Don't allow access when we're running at a high securelevel.
*/
@@ -421,13 +417,19 @@
if (error)
return (error);
- if ((error = cam_periph_lock(periph, PRIBIO | PCATCH)) != 0)
- return (error);
+ cam_periph_lock(periph);
+
+ softc = (struct sg_softc *)periph->softc;
+ if (softc->flags & SG_FLAG_INVALID) {
+ cam_periph_unlock(periph);
+ return (ENXIO);
+ }
if ((softc->flags & SG_FLAG_OPEN) == 0) {
- if (cam_periph_acquire(periph) != CAM_REQ_CMP)
- return (ENXIO);
softc->flags |= SG_FLAG_OPEN;
+ } else {
+ /* Device closes aren't symmetrical, fix up the refcount. */
+ cam_periph_release(periph);
}
cam_periph_unlock(periph);
@@ -440,17 +442,14 @@
{
struct cam_periph *periph;
struct sg_softc *softc;
- int error;
periph = (struct cam_periph *)dev->si_drv1;
if (periph == NULL)
return (ENXIO);
+ cam_periph_lock(periph);
+
softc = (struct sg_softc *)periph->softc;
-
- if ((error = cam_periph_lock(periph, PRIBIO)) != 0)
- return (error);
-
softc->flags &= ~SG_FLAG_OPEN;
cam_periph_unlock(periph);
@@ -473,6 +472,8 @@
if (periph == NULL)
return (ENXIO);
+ cam_periph_lock(periph);
+
softc = (struct sg_softc *)periph->softc;
error = 0;
@@ -669,6 +670,7 @@
break;
}
+ cam_periph_unlock(periph);
return (error);
}
@@ -686,7 +688,6 @@
int error = 0, cdb_len, buf_len, dir;
periph = dev->si_drv1;
- sc = periph->softc;
rdwr = malloc(sizeof(*rdwr), M_DEVBUF, M_WAITOK | M_ZERO);
hdr = &rdwr->hdr.hdr;
@@ -699,12 +700,11 @@
if (error)
goto out_hdr;
- ccb = xpt_alloc_ccb();
+ ccb = xpt_alloc_ccb(periph->sim);
if (ccb == NULL) {
error = ENOMEM;
goto out_hdr;
}
- xpt_setup_ccb(&ccb->ccb_h, periph->path, /*priority*/5);
csio = &ccb->csio;
/*
@@ -751,6 +751,9 @@
dir = CAM_DIR_NONE;
}
+ cam_periph_lock(periph);
+ sc = periph->softc;
+ xpt_setup_ccb(&ccb->ccb_h, periph->path, /*priority*/5);
cam_fill_csio(csio,
/*retries*/1,
sgdone,
@@ -774,7 +777,9 @@
ccb->ccb_h.ccb_rdwr = rdwr;
ccb->ccb_h.ccb_type = SG_CCB_RDWR_IO;
TAILQ_INSERT_TAIL(&sc->rdwr_done, rdwr, rdwr_link);
- return (sgsendrdwr(periph, ccb));
+ error = sgsendrdwr(periph, ccb);
+ cam_periph_unlock(periph);
+ return (error);
out_buf:
free(buf, M_DEVBUF);
@@ -797,7 +802,6 @@
int error, pack_len, reply_len, pack_id;
periph = dev->si_drv1;
- sc = periph->softc;
/* XXX The pack len field needs to be updated and written out instead
* of discarded. Not sure how to do that.
@@ -811,17 +815,20 @@
return (error);
uio->uio_rw = UIO_READ;
+ cam_periph_lock(periph);
+ sc = periph->softc;
search:
TAILQ_FOREACH(rdwr, &sc->rdwr_done, rdwr_link) {
if (rdwr->tag == pack_id)
break;
}
if ((rdwr == NULL) || (rdwr->state != SG_RDWR_DONE)) {
- if (tsleep(rdwr, PCATCH, "sgread", 0) == ERESTART)
+ if (msleep(rdwr, periph->sim->mtx, PCATCH, "sgread", 0) == ERESTART)
return (EAGAIN);
goto search;
}
TAILQ_REMOVE(&sc->rdwr_done, rdwr, rdwr_link);
+ cam_periph_unlock(periph);
hdr = &rdwr->hdr.hdr;
csio = &rdwr->ccb->csio;
@@ -865,7 +872,9 @@
if ((error == 0) && (hdr->result == 0))
error = uiomove(rdwr->buf, rdwr->buf_len, uio);
+ cam_periph_lock(periph);
xpt_free_ccb(rdwr->ccb);
+ cam_periph_unlock(periph);
free(rdwr->buf, M_DEVBUF);
free(rdwr, M_DEVBUF);
return (error);
More information about the p4-projects
mailing list