|
@@ -121,8 +121,7 @@ static void sd_shutdown(struct device *dev);
|
|
|
static void sd_rescan(struct device *);
|
|
|
static int sd_init_command(struct scsi_cmnd *);
|
|
|
static int sd_issue_flush(struct device *, sector_t *);
|
|
|
-static void sd_end_flush(request_queue_t *, struct request *);
|
|
|
-static int sd_prepare_flush(request_queue_t *, struct request *);
|
|
|
+static void sd_prepare_flush(request_queue_t *, struct request *);
|
|
|
static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
|
|
|
unsigned char *buffer);
|
|
|
|
|
@@ -137,8 +136,6 @@ static struct scsi_driver sd_template = {
|
|
|
.rescan = sd_rescan,
|
|
|
.init_command = sd_init_command,
|
|
|
.issue_flush = sd_issue_flush,
|
|
|
- .prepare_flush = sd_prepare_flush,
|
|
|
- .end_flush = sd_end_flush,
|
|
|
};
|
|
|
|
|
|
/*
|
|
@@ -729,42 +726,13 @@ static int sd_issue_flush(struct device *dev, sector_t *error_sector)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static void sd_end_flush(request_queue_t *q, struct request *flush_rq)
|
|
|
+static void sd_prepare_flush(request_queue_t *q, struct request *rq)
|
|
|
{
|
|
|
- struct request *rq = flush_rq->end_io_data;
|
|
|
- struct scsi_cmnd *cmd = rq->special;
|
|
|
- unsigned int bytes = rq->hard_nr_sectors << 9;
|
|
|
-
|
|
|
- if (!flush_rq->errors) {
|
|
|
- spin_unlock(q->queue_lock);
|
|
|
- scsi_io_completion(cmd, bytes, 0);
|
|
|
- spin_lock(q->queue_lock);
|
|
|
- } else if (blk_barrier_postflush(rq)) {
|
|
|
- spin_unlock(q->queue_lock);
|
|
|
- scsi_io_completion(cmd, 0, bytes);
|
|
|
- spin_lock(q->queue_lock);
|
|
|
- } else {
|
|
|
- /*
|
|
|
- * force journal abort of barriers
|
|
|
- */
|
|
|
- end_that_request_first(rq, -EOPNOTSUPP, rq->hard_nr_sectors);
|
|
|
- end_that_request_last(rq, -EOPNOTSUPP);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-static int sd_prepare_flush(request_queue_t *q, struct request *rq)
|
|
|
-{
|
|
|
- struct scsi_device *sdev = q->queuedata;
|
|
|
- struct scsi_disk *sdkp = dev_get_drvdata(&sdev->sdev_gendev);
|
|
|
-
|
|
|
- if (!sdkp || !sdkp->WCE)
|
|
|
- return 0;
|
|
|
-
|
|
|
memset(rq->cmd, 0, sizeof(rq->cmd));
|
|
|
- rq->flags |= REQ_BLOCK_PC | REQ_SOFTBARRIER;
|
|
|
+ rq->flags |= REQ_BLOCK_PC;
|
|
|
rq->timeout = SD_TIMEOUT;
|
|
|
rq->cmd[0] = SYNCHRONIZE_CACHE;
|
|
|
- return 1;
|
|
|
+ rq->cmd_len = 10;
|
|
|
}
|
|
|
|
|
|
static void sd_rescan(struct device *dev)
|
|
@@ -1462,6 +1430,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
|
|
struct scsi_disk *sdkp = scsi_disk(disk);
|
|
|
struct scsi_device *sdp = sdkp->device;
|
|
|
unsigned char *buffer;
|
|
|
+ unsigned ordered;
|
|
|
|
|
|
SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));
|
|
|
|
|
@@ -1498,7 +1467,20 @@ static int sd_revalidate_disk(struct gendisk *disk)
|
|
|
sd_read_write_protect_flag(sdkp, disk->disk_name, buffer);
|
|
|
sd_read_cache_type(sdkp, disk->disk_name, buffer);
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
+ /*
|
|
|
+ * We now have all cache related info, determine how we deal
|
|
|
+ * with ordered requests. Note that as the current SCSI
|
|
|
+ * dispatch function can alter request order, we cannot use
|
|
|
+ * QUEUE_ORDERED_TAG_* even when ordered tag is supported.
|
|
|
+ */
|
|
|
+ if (sdkp->WCE)
|
|
|
+ ordered = QUEUE_ORDERED_DRAIN_FLUSH;
|
|
|
+ else
|
|
|
+ ordered = QUEUE_ORDERED_DRAIN;
|
|
|
+
|
|
|
+ blk_queue_ordered(sdkp->disk->queue, ordered, sd_prepare_flush);
|
|
|
+
|
|
|
set_capacity(disk, sdkp->capacity);
|
|
|
kfree(buffer);
|
|
|
|
|
@@ -1598,6 +1580,7 @@ static int sd_probe(struct device *dev)
|
|
|
strcpy(gd->devfs_name, sdp->devfs_name);
|
|
|
|
|
|
gd->private_data = &sdkp->driver;
|
|
|
+ gd->queue = sdkp->device->request_queue;
|
|
|
|
|
|
sd_revalidate_disk(gd);
|
|
|
|
|
@@ -1605,7 +1588,6 @@ static int sd_probe(struct device *dev)
|
|
|
gd->flags = GENHD_FL_DRIVERFS;
|
|
|
if (sdp->removable)
|
|
|
gd->flags |= GENHD_FL_REMOVABLE;
|
|
|
- gd->queue = sdkp->device->request_queue;
|
|
|
|
|
|
dev_set_drvdata(dev, sdkp);
|
|
|
add_disk(gd);
|