summaryrefslogtreecommitdiffstats
path: root/sys/cam
diff options
context:
space:
mode:
Diffstat (limited to 'sys/cam')
-rw-r--r--sys/cam/ata/ata_da.c17
-rw-r--r--sys/cam/scsi/scsi_da.c17
2 files changed, 24 insertions, 10 deletions
diff --git a/sys/cam/ata/ata_da.c b/sys/cam/ata/ata_da.c
index 6e9c462..3dac0ac 100644
--- a/sys/cam/ata/ata_da.c
+++ b/sys/cam/ata/ata_da.c
@@ -86,7 +86,8 @@ typedef enum {
ADA_FLAG_SCTX_INIT = 0x0200,
ADA_FLAG_CAN_CFA = 0x0400,
ADA_FLAG_CAN_POWERMGT = 0x0800,
- ADA_FLAG_CAN_DMA48 = 0x1000
+ ADA_FLAG_CAN_DMA48 = 0x1000,
+ ADA_FLAG_DIRTY = 0x2000
} ada_flags;
typedef enum {
@@ -602,6 +603,7 @@ adaclose(struct disk *dp)
struct cam_periph *periph;
struct ada_softc *softc;
union ccb *ccb;
+ int error;
periph = (struct cam_periph *)dp->d_drv1;
cam_periph_lock(periph);
@@ -617,7 +619,8 @@ adaclose(struct disk *dp)
("adaclose\n"));
/* We only sync the cache if the drive is capable of it. */
- if ((softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
+ if ((softc->flags & ADA_FLAG_DIRTY) != 0 &&
+ (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) != 0 &&
(periph->flags & CAM_PERIPH_INVALID) == 0) {
ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
@@ -634,11 +637,13 @@ adaclose(struct disk *dp)
ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
else
ata_28bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
- cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
+ error = cam_periph_runccb(ccb, adaerror, /*cam_flags*/0,
/*sense_flags*/0, softc->disk->d_devstat);
- if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+ if (error != 0)
xpt_print(periph->path, "Synchronize cache failed\n");
+ else
+ softc->flags &= ~ADA_FLAG_DIRTY;
xpt_release_ccb(ccb);
}
@@ -1479,8 +1484,10 @@ adastart(struct cam_periph *periph, union ccb *start_ccb)
tag_code = 1;
}
switch (bp->bio_cmd) {
- case BIO_READ:
case BIO_WRITE:
+ softc->flags |= ADA_FLAG_DIRTY;
+ /* FALLTHROUGH */
+ case BIO_READ:
{
uint64_t lba = bp->bio_pblkno;
uint16_t count = bp->bio_bcount / softc->params.secsize;
diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c
index ae80b65..8d0f35e 100644
--- a/sys/cam/scsi/scsi_da.c
+++ b/sys/cam/scsi/scsi_da.c
@@ -89,7 +89,8 @@ typedef enum {
DA_FLAG_OPEN = 0x100,
DA_FLAG_SCTX_INIT = 0x200,
DA_FLAG_CAN_RC16 = 0x400,
- DA_FLAG_PROBED = 0x800
+ DA_FLAG_PROBED = 0x800,
+ DA_FLAG_DIRTY = 0x1000
} da_flags;
typedef enum {
@@ -1237,6 +1238,7 @@ daclose(struct disk *dp)
{
struct cam_periph *periph;
struct da_softc *softc;
+ int error;
periph = (struct cam_periph *)dp->d_drv1;
cam_periph_lock(periph);
@@ -1251,8 +1253,9 @@ daclose(struct disk *dp)
CAM_DEBUG(periph->path, CAM_DEBUG_TRACE | CAM_DEBUG_PERIPH,
("daclose\n"));
- if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0
- && (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
+ if ((softc->flags & DA_FLAG_DIRTY) != 0 &&
+ (softc->quirks & DA_Q_NO_SYNC_CACHE) == 0 &&
+ (softc->flags & DA_FLAG_PACK_INVALID) == 0) {
union ccb *ccb;
ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL);
@@ -1266,9 +1269,11 @@ daclose(struct disk *dp)
SSD_FULL_SIZE,
5 * 60 * 1000);
- cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
+ error = cam_periph_runccb(ccb, daerror, /*cam_flags*/0,
/*sense_flags*/SF_RETRY_UA | SF_QUIET_IR,
softc->disk->d_devstat);
+ if (error == 0)
+ softc->flags &= ~DA_FLAG_DIRTY;
xpt_release_ccb(ccb);
}
@@ -2240,8 +2245,10 @@ skipstate:
}
switch (bp->bio_cmd) {
- case BIO_READ:
case BIO_WRITE:
+ softc->flags |= DA_FLAG_DIRTY;
+ /* FALLTHROUGH */
+ case BIO_READ:
scsi_read_write(&start_ccb->csio,
/*retries*/da_retry_count,
/*cbfcnp*/dadone,
OpenPOWER on IntegriCloud