Add BUF_CMD_FLUSH support - issue flush command to mass storage device.
authorMatthew Dillon <dillon@dragonflybsd.org>
Fri, 29 Aug 2008 20:08:40 +0000 (20:08 +0000)
committerMatthew Dillon <dillon@dragonflybsd.org>
Fri, 29 Aug 2008 20:08:40 +0000 (20:08 +0000)
sys/bus/cam/scsi/scsi_da.c
sys/dev/disk/nata/ata-disk.c
sys/kern/subr_diskslice.c
sys/sys/buf.h

index 7ba29fb..61949fb 100644 (file)
@@ -26,7 +26,7 @@
  * SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/cam/scsi/scsi_da.c,v 1.42.2.46 2003/10/21 22:18:19 thomas Exp $
- * $DragonFly: src/sys/bus/cam/scsi/scsi_da.c,v 1.58 2008/07/18 00:07:23 dillon Exp $
+ * $DragonFly: src/sys/bus/cam/scsi/scsi_da.c,v 1.59 2008/08/29 20:08:40 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -1470,6 +1470,7 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
                /* Pull a buffer from the queue and get going on it */          
                struct bio *bio;
                struct buf *bp;
+               u_int8_t tag_code;
 
                /*
                 * See if there is a buf with work for us to do..
@@ -1483,66 +1484,102 @@ dastart(struct cam_periph *periph, union ccb *start_ccb)
                                          periph_links.sle);
                        periph->immediate_priority = CAM_PRIORITY_NONE;
                        wakeup(&periph->ccb_list);
-               } else if (bio == NULL) {
+                       if (bio != NULL) {
+                               /*
+                                * Have more work to do, so ensure we stay
+                                * scheduled
+                                */
+                               xpt_schedule(periph, /* XXX priority */1);
+                       }
+                       break;
+               }
+               if (bio == NULL) {
                        xpt_release_ccb(start_ccb);
-               } else {
-                       u_int8_t tag_code;
-
-                       bioq_remove(&softc->bio_queue, bio);
-                       bp = bio->bio_buf;
-
-                       devstat_start_transaction(&softc->device_stats);
+                       break;
+               }
 
-                       if ((bp->b_flags & B_ORDERED) != 0
-                        || (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
-                               softc->flags &= ~DA_FLAG_NEED_OTAG;
-                               softc->ordered_tag_count++;
-                               tag_code = MSG_ORDERED_Q_TAG;
-                       } else {
-                               tag_code = MSG_SIMPLE_Q_TAG;
-                       }
+               /*
+                * We can queue new work.
+                */
+               bioq_remove(&softc->bio_queue, bio);
+               bp = bio->bio_buf;
 
-                       KKASSERT(bio->bio_offset % softc->params.secsize == 0);
+               devstat_start_transaction(&softc->device_stats);
 
-                       scsi_read_write(&start_ccb->csio,
-                                       /*retries*/da_retry_count,
-                                       dadone,
-                                       tag_code,
-                                       (bp->b_cmd == BUF_CMD_READ),
-                                       /*byte2*/0,
-                                       softc->minimum_cmd_size,
-                                       bio->bio_offset / softc->params.secsize,
-                                       bp->b_bcount / softc->params.secsize,
-                                       bp->b_data,
-                                       bp->b_bcount,
-                                       /*sense_len*/SSD_FULL_SIZE,
-                                       da_default_timeout * 1000);
-                       start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
+               if ((bp->b_flags & B_ORDERED) != 0 ||
+                   (softc->flags & DA_FLAG_NEED_OTAG) != 0) {
+                       softc->flags &= ~DA_FLAG_NEED_OTAG;
+                       softc->ordered_tag_count++;
+                       tag_code = MSG_ORDERED_Q_TAG;
+               } else {
+                       tag_code = MSG_SIMPLE_Q_TAG;
+               }
 
+               switch(bp->b_cmd) {
+               case BUF_CMD_READ:
+               case BUF_CMD_WRITE:
                        /*
-                        * Block out any asyncronous callbacks
-                        * while we touch the pending ccb list.
+                        * Block read/write op
                         */
-                       LIST_INSERT_HEAD(&softc->pending_ccbs,
-                                        &start_ccb->ccb_h, periph_links.le);
-
-                       softc->outstanding_cmds++;
-                       /* We expect a unit attention from this device */
-                       if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
-                               start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
-                               softc->flags &= ~DA_FLAG_RETRY_UA;
-                       }
+                       KKASSERT(bio->bio_offset % softc->params.secsize == 0);
 
-                       start_ccb->ccb_h.ccb_bio = bio;
-                       bio = bioq_first(&softc->bio_queue);
+                       scsi_read_write(
+                               &start_ccb->csio,
+                               da_retry_count,         /* retries */
+                               dadone,
+                               tag_code,
+                               (bp->b_cmd == BUF_CMD_READ),
+                               0,                      /* byte2 */
+                               softc->minimum_cmd_size,
+                               bio->bio_offset / softc->params.secsize,
+                               bp->b_bcount / softc->params.secsize,
+                               bp->b_data,
+                               bp->b_bcount,
+                               SSD_FULL_SIZE,          /* sense_len */
+                               da_default_timeout * 1000
+                       );
+                       break;
+               case BUF_CMD_FLUSH:
+                       scsi_synchronize_cache(
+                               &start_ccb->csio,
+                               1,                      /* retries */
+                               dadone,                 /* cbfcnp */
+                               MSG_SIMPLE_Q_TAG,
+                               0,                      /* lba */
+                               0,                      /* count (whole disk) */
+                               SSD_FULL_SIZE,
+                               da_default_timeout*1000 /* timeout */
+                       );
+                       break;
+               default:
+                       panic("dastart: unrecognized bio cmd %d", bp->b_cmd);
+                       break; /* NOT REACHED */
+               }
 
-                       xpt_action(start_ccb);
+               /*
+                * Block out any asyncronous callbacks
+                * while we touch the pending ccb list.
+                */
+               start_ccb->ccb_h.ccb_state = DA_CCB_BUFFER_IO;
+               LIST_INSERT_HEAD(&softc->pending_ccbs,
+                                &start_ccb->ccb_h, periph_links.le);
+               softc->outstanding_cmds++;
+
+               /* We expect a unit attention from this device */
+               if ((softc->flags & DA_FLAG_RETRY_UA) != 0) {
+                       start_ccb->ccb_h.ccb_state |= DA_CCB_RETRY_UA;
+                       softc->flags &= ~DA_FLAG_RETRY_UA;
                }
+
+               start_ccb->ccb_h.ccb_bio = bio;
+               xpt_action(start_ccb);
                
-               if (bio != NULL) {
-                       /* Have more work to do, so ensure we stay scheduled */
-                       xpt_schedule(periph, /* XXX priority */1);
-               }
+               /*
+                * Be sure we stay scheduled if we have more work to do.
+                */
+               bio = bioq_first(&softc->bio_queue);
+               if (bio != NULL)
+                       xpt_schedule(periph, 1);
                break;
        }
        case DA_STATE_PROBE:
index 3d2d748..adaf063 100644 (file)
@@ -24,7 +24,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * $FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.199 2006/09/14 19:12:29 sos Exp $
- * $DragonFly: src/sys/dev/disk/nata/ata-disk.c,v 1.8 2008/06/27 01:24:46 dillon Exp $
+ * $DragonFly: src/sys/dev/disk/nata/ata-disk.c,v 1.9 2008/08/29 20:08:38 dillon Exp $
  */
 
 #include "opt_ata.h"
@@ -330,7 +330,6 @@ ad_strategy(struct dev_strategy_args *ap)
        else
            request->u.ata.command = ATA_WRITE;
        break;
-#if 0  /* NOT YET */
     case BUF_CMD_FLUSH:
        request->u.ata.lba = 0;
        request->u.ata.count = 0;
@@ -340,7 +339,6 @@ ad_strategy(struct dev_strategy_args *ap)
        request->flags = ATA_R_CONTROL;
        request->u.ata.command = ATA_FLUSHCACHE;
        break;
-#endif
     default:
        device_printf(dev, "FAILURE - unknown BUF operation\n");
        ata_free_request(request);
index 9500b44..3cd99c0 100644 (file)
@@ -44,7 +44,7 @@
  *     from: @(#)ufs_disksubr.c        7.16 (Berkeley) 5/4/91
  *     from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $
  * $FreeBSD: src/sys/kern/subr_diskslice.c,v 1.82.2.6 2001/07/24 09:49:41 dd Exp $
- * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.50 2008/04/20 13:44:25 swildner Exp $
+ * $DragonFly: src/sys/kern/subr_diskslice.c,v 1.51 2008/08/29 20:08:36 dillon Exp $
  */
 
 #include <sys/param.h>
@@ -222,7 +222,7 @@ doshift:
         * Disallow writes to reserved areas unless ds_wlabel allows it.
         */
        if (slicerel_secno < sp->ds_reserved && nsec &&
-           bp->b_cmd != BUF_CMD_READ && sp->ds_wlabel == 0) {
+           bp->b_cmd == BUF_CMD_WRITE && sp->ds_wlabel == 0) {
                bp->b_error = EROFS;
                goto error;
        }
index 882d8e1..9d2fd2d 100644 (file)
@@ -37,7 +37,7 @@
  *
  *     @(#)buf.h       8.9 (Berkeley) 3/30/95
  * $FreeBSD: src/sys/sys/buf.h,v 1.88.2.10 2003/01/25 19:02:23 dillon Exp $
- * $DragonFly: src/sys/sys/buf.h,v 1.53 2008/08/10 20:03:15 dillon Exp $
+ * $DragonFly: src/sys/sys/buf.h,v 1.54 2008/08/29 20:08:37 dillon Exp $
  */
 
 #ifndef _SYS_BUF_H_
@@ -93,7 +93,8 @@ typedef enum buf_cmd {
        BUF_CMD_READ,
        BUF_CMD_WRITE,
        BUF_CMD_FREEBLKS,
-       BUF_CMD_FORMAT
+       BUF_CMD_FORMAT,
+       BUF_CMD_FLUSH
 } buf_cmd_t;
 
 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)