Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 25 Jun 2009 22:38:11 GMT
From:      Alexander Motin <mav@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 165221 for review
Message-ID:  <200906252238.n5PMcBmn097926@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=165221

Change 165221 by mav@mav_mavbook on 2009/06/25 22:37:55

	Implement ATA disk cache flushing same way as for SCSI.

Affected files ...

.. //depot/projects/scottl-camlock/src/sys/cam/ata/ata_da.c#14 edit

Differences ...

==== //depot/projects/scottl-camlock/src/sys/cam/ata/ata_da.c#14 (text+ko) ====

@@ -256,6 +256,7 @@
 {
 	struct	cam_periph *periph;
 	struct	ada_softc *softc;
+	union ccb *ccb;
 	int error;
 
 	periph = (struct cam_periph *)dp->d_drv1;
@@ -270,6 +271,37 @@
 	}
 
 	softc = (struct ada_softc *)periph->softc;
+	/* We only sync the cache if the drive is capable of it. */
+	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
+
+		ccb = cam_periph_getccb(periph, /*priority*/1);
+		ccb->ccb_h.ccb_state = ADA_CCB_DUMP;
+		cam_fill_ataio(&ccb->ataio,
+				    1,
+				    adadone,
+				    CAM_DIR_NONE,
+				    0,
+				    NULL,
+				    0,
+				    ada_default_timeout*1000);
+
+		if (softc->flags & ADA_FLAG_CAN_48BIT)
+			ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE48, 0, 0, 0);
+		else
+			ata_48bit_cmd(&ccb->ataio, ATA_FLUSHCACHE, 0, 0, 0);
+		xpt_polled_action(ccb);
+
+		if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+			xpt_print(periph->path, "Synchronize cache failed\n");
+
+		if ((ccb->ccb_h.status & CAM_DEV_QFRZN) != 0)
+			cam_release_devq(ccb->ccb_h.path,
+					 /*relsim_flags*/0,
+					 /*reduction*/0,
+					 /*timeout*/0,
+					 /*getcount_only*/0);
+		xpt_release_ccb(ccb);
+	}
 
 	softc->flags &= ~ADA_FLAG_OPEN;
 	cam_periph_unhold(periph);
@@ -340,7 +372,7 @@
 	struct	    cam_periph *periph;
 	struct	    ada_softc *softc;
 	u_int	    secsize;
-	struct	    ccb_ataio ataio;
+	union	    ccb ccb;
 	struct	    disk *dp;
 	uint64_t    lba;
 	uint16_t    count;
@@ -362,9 +394,9 @@
 
 	if (length > 0) {
 		periph->flags |= CAM_PERIPH_POLLED;
-		xpt_setup_ccb(&ataio.ccb_h, periph->path, /*priority*/1);
-		ataio.ccb_h.ccb_state = ADA_CCB_DUMP;
-		cam_fill_ataio(&ataio,
+		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
+		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
+		cam_fill_ataio(&ccb.ataio,
 		    0,
 		    adadone,
 		    CAM_DIR_OUT,
@@ -375,15 +407,15 @@
 		if ((softc->flags & ADA_FLAG_CAN_48BIT) &&
 		    (lba + count >= ATA_MAX_28BIT_LBA ||
 		    count >= 256)) {
-			ata_48bit_cmd(&ataio, ATA_WRITE_DMA48,
+			ata_48bit_cmd(&ccb.ataio, ATA_WRITE_DMA48,
 			    0, lba, count);
 		} else {
-			ata_36bit_cmd(&ataio, ATA_WRITE_DMA,
+			ata_36bit_cmd(&ccb.ataio, ATA_WRITE_DMA,
 			    0, lba, count);
 		}
-		xpt_polled_action((union ccb *)&ataio);
+		xpt_polled_action(&ccb);
 
-		if ((ataio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
+		if ((ccb.ataio.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
 			printf("Aborting dump due to I/O error.\n");
 			cam_periph_unlock(periph);
 			return(EIO);
@@ -391,6 +423,36 @@
 		cam_periph_unlock(periph);
 		return(0);
 	}
+
+	if (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) {
+		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
+
+		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
+		cam_fill_ataio(&ccb.ataio,
+				    1,
+				    adadone,
+				    CAM_DIR_NONE,
+				    0,
+				    NULL,
+				    0,
+				    ada_default_timeout*1000);
+
+		if (softc->flags & ADA_FLAG_CAN_48BIT)
+			ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0);
+		else
+			ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
+		xpt_polled_action(&ccb);
+
+		if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+			xpt_print(periph->path, "Synchronize cache failed\n");
+
+		if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
+			cam_release_devq(ccb.ccb_h.path,
+					 /*relsim_flags*/0,
+					 /*reduction*/0,
+					 /*timeout*/0,
+					 /*getcount_only*/0);
+	}
 	periph->flags &= ~CAM_PERIPH_POLLED;
 	cam_periph_unlock(periph);
 	return (0);
@@ -1026,17 +1088,16 @@
 	struct ada_softc *softc;
 
 	TAILQ_FOREACH(periph, &adadriver.units, unit_links) {
-//		union ccb ccb;
+		union ccb ccb;
 
 		cam_periph_lock(periph);
 		softc = (struct ada_softc *)periph->softc;
-#if 0
 		/*
 		 * We only sync the cache if the drive is still open, and
 		 * if the drive is capable of it..
 		 */
-		if (((softc->flags & ADA_FLAG_OPEN) == 0)
-		 || (softc->quirks & ADA_Q_NO_SYNC_CACHE)) {
+		if (((softc->flags & ADA_FLAG_OPEN) == 0) ||
+		    (softc->flags & ADA_FLAG_CAN_FLUSHCACHE) == 0) {
 			cam_periph_unlock(periph);
 			continue;
 		}
@@ -1044,44 +1105,30 @@
 		xpt_setup_ccb(&ccb.ccb_h, periph->path, /*priority*/1);
 
 		ccb.ccb_h.ccb_state = ADA_CCB_DUMP;
-		scsi_synchronize_cache(&ccb.csio,
-				       /*retries*/1,
-				       /*cbfcnp*/adadone,
-				       0,//MSG_SIMPLE_Q_TAG,
-				       /*begin_lba*/0, /* whole disk */
-				       /*lb_count*/0,
-				       SSD_FULL_SIZE,
-				       60 * 60 * 1000);
+		cam_fill_ataio(&ccb.ataio,
+				    1,
+				    adadone,
+				    CAM_DIR_NONE,
+				    0,
+				    NULL,
+				    0,
+				    ada_default_timeout*1000);
 
+		if (softc->flags & ADA_FLAG_CAN_48BIT)
+			ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE48, 0, 0, 0);
+		else
+			ata_48bit_cmd(&ccb.ataio, ATA_FLUSHCACHE, 0, 0, 0);
 		xpt_polled_action(&ccb);
 
-		if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) {
-			if (((ccb.ccb_h.status & CAM_STATUS_MASK) ==
-			     CAM_SCSI_STATUS_ERROR)
-			 && (ccb.csio.scsi_status == SCSI_STATUS_CHECK_COND)){
-				int error_code, sense_key, asc, ascq;
+		if ((ccb.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP)
+			xpt_print(periph->path, "Synchronize cache failed\n");
 
-				scsi_extract_sense(&ccb.csio.sense_data,
-						   &error_code, &sense_key,
-						   &asc, &ascq);
-
-				if (sense_key != SSD_KEY_ILLEGAL_REQUEST)
-					scsi_sense_print(&ccb.csio);
-			} else {
-				xpt_print(periph->path, "Synchronize "
-				    "cache failed, status == 0x%x, scsi status "
-				    "== 0x%x\n", ccb.ccb_h.status,
-				    ccb.csio.scsi_status);
-			}
-		}
-
 		if ((ccb.ccb_h.status & CAM_DEV_QFRZN) != 0)
 			cam_release_devq(ccb.ccb_h.path,
 					 /*relsim_flags*/0,
 					 /*reduction*/0,
 					 /*timeout*/0,
 					 /*getcount_only*/0);
-#endif
 		cam_periph_unlock(periph);
 	}
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906252238.n5PMcBmn097926>