[SCSI] sd: disentangle barriers in SCSI

Our current implementation has a generic set of barrier functions that
go through the SCSI driver model.  Realistically, this is unnecessary,
because the only device that can use barriers (sd) can set the flush
functions up at probe or revalidate time.  This patch pulls the barrier
functions out of the mid layer and scsi driver model and relocates them
directly in sd.

Acked-by: Tejun Heo <htejun@gmail.com>
Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index e21c714..2c6116f 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -241,7 +241,6 @@
 	},
 	.rescan			= sd_rescan,
 	.init_command		= sd_init_command,
-	.issue_flush		= sd_issue_flush,
 };
 
 /*
@@ -800,10 +799,17 @@
 	return 0;
 }
 
-static int sd_issue_flush(struct device *dev, sector_t *error_sector)
+static int sd_issue_flush(struct request_queue *q, struct gendisk *disk,
+			  sector_t *error_sector)
 {
 	int ret = 0;
-	struct scsi_disk *sdkp = scsi_disk_get_from_dev(dev);
+	struct scsi_device *sdp = q->queuedata;
+	struct scsi_disk *sdkp;
+
+	if (sdp->sdev_state != SDEV_RUNNING)
+		return -ENXIO;
+
+	sdkp = scsi_disk_get_from_dev(&sdp->sdev_gendev);
 
 	if (!sdkp)
                return -ENODEV;
@@ -1663,6 +1669,8 @@
 
 	sd_revalidate_disk(gd);
 
+	blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
+
 	gd->driverfs_dev = &sdp->sdev_gendev;
 	gd->flags = GENHD_FL_DRIVERFS;
 	if (sdp->removable)