* success as well). Returns a negated errno value in case of error.
*
* Note: most ioctls are forward onto the block subsystem or further
- * down in the scsi subsytem.
+ * down in the scsi subsystem.
**/
static int sd_ioctl(struct inode * inode, struct file * filp,
unsigned int cmd, unsigned long arg)
* can deal with it then. It is only because of unrecoverable errors
* that we would ever take a device offline in the first place.
*/
- if (!scsi_device_online(sdp))
- goto not_present;
+ if (!scsi_device_online(sdp)) {
+ set_media_not_present(sdkp);
+ retval = 1;
+ goto out;
+ }
/*
* Using TEST_UNIT_READY enables differentiation between drive with
* sd_revalidate() is called.
*/
retval = -ENODEV;
+
if (scsi_block_when_processing_errors(sdp))
retval = scsi_test_unit_ready(sdp, SD_TIMEOUT, SD_MAX_RETRIES);
* and we will figure it out later once the drive is
* available again.
*/
- if (retval)
- goto not_present;
+ if (retval) {
+ set_media_not_present(sdkp);
+ retval = 1;
+ goto out;
+ }
/*
* For removable scsi disk we have to recognise the presence
retval = sdp->changed;
sdp->changed = 0;
-
+out:
+ if (retval != sdkp->previous_state)
+ sdev_evt_send_simple(sdp, SDEV_EVT_MEDIA_CHANGE, GFP_KERNEL);
+ sdkp->previous_state = retval;
return retval;
-
-not_present:
- set_media_not_present(sdkp);
- return 1;
}
static int sd_sync_cache(struct scsi_disk *sdkp)
return 0;
}
-static int sd_issue_flush(struct request_queue *q, struct gendisk *disk,
- sector_t *error_sector)
-{
- int ret = 0;
- 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;
-
- if (sdkp->WCE)
- ret = sd_sync_cache(sdkp);
- scsi_disk_put(sdkp);
- return ret;
-}
-
static void sd_prepare_flush(struct request_queue *q, struct request *rq)
{
memset(rq->cmd, 0, sizeof(rq->cmd));
sd_revalidate_disk(gd);
blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
- blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
gd->driverfs_dev = &sdp->sdev_gendev;
gd->flags = GENHD_FL_DRIVERFS;