return BLKPREP_KILL;
}
+static int scsi_issue_flush_fn(request_queue_t *q, struct gendisk *disk,
+ sector_t *error_sector)
+{
+ struct scsi_device *sdev = q->queuedata;
+ struct scsi_driver *drv;
+
+ if (sdev->sdev_state != SDEV_RUNNING)
+ return -ENXIO;
+
+ drv = *(struct scsi_driver **) disk->private_data;
+ if (drv->issue_flush)
+ return drv->issue_flush(&sdev->sdev_gendev, error_sector);
+
+ return -EOPNOTSUPP;
+}
+
static int scsi_prep_fn(struct request_queue *q, struct request *req)
{
struct scsi_device *sdev = q->queuedata;
blk_queue_max_sectors(q, shost->max_sectors);
blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
blk_queue_segment_boundary(q, shost->dma_boundary);
-
+ blk_queue_issue_flush_fn(q, scsi_issue_flush_fn);
+
if (!shost->use_clustering)
clear_bit(QUEUE_FLAG_CLUSTER, &q->queue_flags);
return q;
return ret;
}
+int
+scsi_test_unit_ready(struct scsi_device *sdev, int timeout, int retries)
+{
+ struct scsi_request *sreq;
+ char cmd[] = {
+ TEST_UNIT_READY, 0, 0, 0, 0, 0,
+ };
+ int result;
+
+ sreq = scsi_allocate_request(sdev, GFP_KERNEL);
+ if (!sreq)
+ return -ENOMEM;
+
+ sreq->sr_data_direction = DMA_NONE;
+ scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
+
+ if ((driver_byte(sreq->sr_result) & DRIVER_SENSE) &&
+ (sreq->sr_sense_buffer[2] & 0x0f) == UNIT_ATTENTION &&
+ sdev->removable) {
+ sdev->changed = 1;
+ sreq->sr_result = 0;
+ }
+ result = sreq->sr_result;
+ scsi_release_request(sreq);
+ return result;
+}
+EXPORT_SYMBOL(scsi_test_unit_ready);
+
/**
* scsi_device_set_state - Take the given device through the device
* state model.