PERFORCE change 165221 for review
Alexander Motin
mav at FreeBSD.org
Thu Jun 25 22:38:13 UTC 2009
http://perforce.freebsd.org/chv.cgi?CH=165221
Change 165221 by mav at 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);
}
}
More information about the p4-projects
mailing list