Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
[linux-2.6-microblaze.git] / drivers / scsi / sd.c
index 610ebba..cbd9999 100644 (file)
@@ -110,6 +110,7 @@ static void sd_shutdown(struct device *);
 static int sd_suspend_system(struct device *);
 static int sd_suspend_runtime(struct device *);
 static int sd_resume(struct device *);
+static int sd_resume_runtime(struct device *);
 static void sd_rescan(struct device *);
 static blk_status_t sd_init_command(struct scsi_cmnd *SCpnt);
 static void sd_uninit_command(struct scsi_cmnd *SCpnt);
@@ -605,7 +606,7 @@ static const struct dev_pm_ops sd_pm_ops = {
        .poweroff               = sd_suspend_system,
        .restore                = sd_resume,
        .runtime_suspend        = sd_suspend_runtime,
-       .runtime_resume         = sd_resume,
+       .runtime_resume         = sd_resume_runtime,
 };
 
 static struct scsi_driver sd_template = {
@@ -776,8 +777,9 @@ static unsigned int sd_prot_flag_mask(unsigned int prot_op)
 static unsigned char sd_setup_protect_cmnd(struct scsi_cmnd *scmd,
                                           unsigned int dix, unsigned int dif)
 {
-       struct bio *bio = scmd->request->bio;
-       unsigned int prot_op = sd_prot_op(rq_data_dir(scmd->request), dix, dif);
+       struct request *rq = scsi_cmd_to_rq(scmd);
+       struct bio *bio = rq->bio;
+       unsigned int prot_op = sd_prot_op(rq_data_dir(rq), dix, dif);
        unsigned int protect = 0;
 
        if (dix) {                              /* DIX Type 0, 1, 2, 3 */
@@ -868,7 +870,7 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)
 static blk_status_t sd_setup_unmap_cmnd(struct scsi_cmnd *cmd)
 {
        struct scsi_device *sdp = cmd->device;
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
        u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
        u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
@@ -904,7 +906,7 @@ static blk_status_t sd_setup_write_same16_cmnd(struct scsi_cmnd *cmd,
                bool unmap)
 {
        struct scsi_device *sdp = cmd->device;
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
        u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
        u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
@@ -936,7 +938,7 @@ static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd,
                bool unmap)
 {
        struct scsi_device *sdp = cmd->device;
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
        u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
        u32 nr_blocks = sectors_to_logical(sdp, blk_rq_sectors(rq));
@@ -966,7 +968,7 @@ static blk_status_t sd_setup_write_same10_cmnd(struct scsi_cmnd *cmd,
 
 static blk_status_t sd_setup_write_zeroes_cmnd(struct scsi_cmnd *cmd)
 {
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
        struct scsi_device *sdp = cmd->device;
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
        u64 lba = sectors_to_logical(sdp, blk_rq_pos(rq));
@@ -1063,7 +1065,7 @@ out:
  **/
 static blk_status_t sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
 {
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
        struct scsi_device *sdp = cmd->device;
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
        struct bio *bio = rq->bio;
@@ -1112,7 +1114,7 @@ static blk_status_t sd_setup_write_same_cmnd(struct scsi_cmnd *cmd)
 
 static blk_status_t sd_setup_flush_cmnd(struct scsi_cmnd *cmd)
 {
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
 
        /* flush requests don't perform I/O, zero the S/G table */
@@ -1210,7 +1212,7 @@ static blk_status_t sd_setup_rw6_cmnd(struct scsi_cmnd *cmd, bool write,
 
 static blk_status_t sd_setup_read_write_cmnd(struct scsi_cmnd *cmd)
 {
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
        struct scsi_device *sdp = cmd->device;
        struct scsi_disk *sdkp = scsi_disk(rq->rq_disk);
        sector_t lba = sectors_to_logical(sdp, blk_rq_pos(rq));
@@ -1324,7 +1326,7 @@ fail:
 
 static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
 {
-       struct request *rq = cmd->request;
+       struct request *rq = scsi_cmd_to_rq(cmd);
 
        switch (req_op(rq)) {
        case REQ_OP_DISCARD:
@@ -1370,7 +1372,7 @@ static blk_status_t sd_init_command(struct scsi_cmnd *cmd)
 
 static void sd_uninit_command(struct scsi_cmnd *SCpnt)
 {
-       struct request *rq = SCpnt->request;
+       struct request *rq = scsi_cmd_to_rq(SCpnt);
        u8 *cmnd;
 
        if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
@@ -1530,11 +1532,11 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
 }
 
 /**
- *     sd_ioctl_common - process an ioctl
+ *     sd_ioctl - process an ioctl
  *     @bdev: target block device
  *     @mode: FMODE_* mask
  *     @cmd: ioctl command number
- *     @p: this is third argument given to ioctl(2) system call.
+ *     @arg: this is third argument given to ioctl(2) system call.
  *     Often contains a pointer.
  *
  *     Returns 0 if successful (some ioctls return positive numbers on
@@ -1543,20 +1545,20 @@ static int sd_getgeo(struct block_device *bdev, struct hd_geometry *geo)
  *     Note: most ioctls are forward onto the block subsystem or further
  *     down in the scsi subsystem.
  **/
-static int sd_ioctl_common(struct block_device *bdev, fmode_t mode,
-                          unsigned int cmd, void __user *p)
+static int sd_ioctl(struct block_device *bdev, fmode_t mode,
+                   unsigned int cmd, unsigned long arg)
 {
        struct gendisk *disk = bdev->bd_disk;
        struct scsi_disk *sdkp = scsi_disk(disk);
        struct scsi_device *sdp = sdkp->device;
+       void __user *p = (void __user *)arg;
        int error;
     
        SCSI_LOG_IOCTL(1, sd_printk(KERN_INFO, sdkp, "sd_ioctl: disk=%s, "
                                    "cmd=0x%x\n", disk->disk_name, cmd));
 
-       error = scsi_verify_blk_ioctl(bdev, cmd);
-       if (error < 0)
-               return error;
+       if (bdev_is_partition(bdev) && !capable(CAP_SYS_RAWIO))
+               return -ENOIOCTLCMD;
 
        /*
         * If we are in the middle of error recovery, don't let anyone
@@ -1567,27 +1569,11 @@ static int sd_ioctl_common(struct block_device *bdev, fmode_t mode,
        error = scsi_ioctl_block_when_processing_errors(sdp, cmd,
                        (mode & FMODE_NDELAY) != 0);
        if (error)
-               goto out;
+               return error;
 
        if (is_sed_ioctl(cmd))
                return sed_ioctl(sdkp->opal_dev, cmd, p);
-
-       /*
-        * Send SCSI addressing ioctls directly to mid level, send other
-        * ioctls to block level and then onto mid level if they can't be
-        * resolved.
-        */
-       switch (cmd) {
-               case SCSI_IOCTL_GET_IDLUN:
-               case SCSI_IOCTL_GET_BUS_NUMBER:
-                       error = scsi_ioctl(sdp, cmd, p);
-                       break;
-               default:
-                       error = scsi_cmd_blk_ioctl(bdev, mode, cmd, p);
-                       break;
-       }
-out:
-       return error;
+       return scsi_ioctl(sdp, disk, mode, cmd, p);
 }
 
 static void set_media_not_present(struct scsi_disk *sdkp)
@@ -1770,34 +1756,6 @@ static void sd_rescan(struct device *dev)
        sd_revalidate_disk(sdkp->disk);
 }
 
-static int sd_ioctl(struct block_device *bdev, fmode_t mode,
-                   unsigned int cmd, unsigned long arg)
-{
-       void __user *p = (void __user *)arg;
-       int ret;
-
-       ret = sd_ioctl_common(bdev, mode, cmd, p);
-       if (ret != -ENOTTY)
-               return ret;
-
-       return scsi_ioctl(scsi_disk(bdev->bd_disk)->device, cmd, p);
-}
-
-#ifdef CONFIG_COMPAT
-static int sd_compat_ioctl(struct block_device *bdev, fmode_t mode,
-                          unsigned int cmd, unsigned long arg)
-{
-       void __user *p = compat_ptr(arg);
-       int ret;
-
-       ret = sd_ioctl_common(bdev, mode, cmd, p);
-       if (ret != -ENOTTY)
-               return ret;
-
-       return scsi_compat_ioctl(scsi_disk(bdev->bd_disk)->device, cmd, p);
-}
-#endif
-
 static char sd_pr_type(enum pr_type type)
 {
        switch (type) {
@@ -1898,9 +1856,7 @@ static const struct block_device_operations sd_fops = {
        .release                = sd_release,
        .ioctl                  = sd_ioctl,
        .getgeo                 = sd_getgeo,
-#ifdef CONFIG_COMPAT
-       .compat_ioctl           = sd_compat_ioctl,
-#endif
+       .compat_ioctl           = blkdev_compat_ptr_ioctl,
        .check_events           = sd_check_events,
        .unlock_native_capacity = sd_unlock_native_capacity,
        .report_zones           = sd_zbc_report_zones,
@@ -1921,7 +1877,7 @@ static const struct block_device_operations sd_fops = {
  **/
 static void sd_eh_reset(struct scsi_cmnd *scmd)
 {
-       struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk);
+       struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->rq_disk);
 
        /* New SCSI EH run, reset gate variable */
        sdkp->ignore_medium_access_errors = false;
@@ -1941,7 +1897,7 @@ static void sd_eh_reset(struct scsi_cmnd *scmd)
  **/
 static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
 {
-       struct scsi_disk *sdkp = scsi_disk(scmd->request->rq_disk);
+       struct scsi_disk *sdkp = scsi_disk(scsi_cmd_to_rq(scmd)->rq_disk);
        struct scsi_device *sdev = scmd->device;
 
        if (!scsi_device_online(sdev) ||
@@ -1982,7 +1938,7 @@ static int sd_eh_action(struct scsi_cmnd *scmd, int eh_disp)
 
 static unsigned int sd_completed_bytes(struct scsi_cmnd *scmd)
 {
-       struct request *req = scmd->request;
+       struct request *req = scsi_cmd_to_rq(scmd);
        struct scsi_device *sdev = scmd->device;
        unsigned int transferred, good_bytes;
        u64 start_lba, end_lba, bad_lba;
@@ -2037,8 +1993,8 @@ static int sd_done(struct scsi_cmnd *SCpnt)
        unsigned int sector_size = SCpnt->device->sector_size;
        unsigned int resid;
        struct scsi_sense_hdr sshdr;
-       struct scsi_disk *sdkp = scsi_disk(SCpnt->request->rq_disk);
-       struct request *req = SCpnt->request;
+       struct request *req = scsi_cmd_to_rq(SCpnt);
+       struct scsi_disk *sdkp = scsi_disk(req->rq_disk);
        int sense_valid = 0;
        int sense_deferred = 0;
 
@@ -2181,8 +2137,10 @@ sd_spinup_disk(struct scsi_disk *sdkp)
                         * doesn't have any media in it, don't bother
                         * with any more polling.
                         */
-                       if (media_not_present(sdkp, &sshdr))
+                       if (media_not_present(sdkp, &sshdr)) {
+                               sd_printk(KERN_NOTICE, sdkp, "Media removed, stopped polling\n");
                                return;
+                       }
 
                        if (the_result)
                                sense_valid = scsi_sense_valid(&sshdr);
@@ -3718,6 +3676,25 @@ static int sd_resume(struct device *dev)
        return ret;
 }
 
+static int sd_resume_runtime(struct device *dev)
+{
+       struct scsi_disk *sdkp = dev_get_drvdata(dev);
+       struct scsi_device *sdp = sdkp->device;
+
+       if (sdp->ignore_media_change) {
+               /* clear the device's sense data */
+               static const u8 cmd[10] = { REQUEST_SENSE };
+
+               if (scsi_execute(sdp, cmd, DMA_NONE, NULL, 0, NULL,
+                                NULL, sdp->request_queue->rq_timeout, 1, 0,
+                                RQF_PM, NULL))
+                       sd_printk(KERN_NOTICE, sdkp,
+                                 "Failed to clear sense data\n");
+       }
+
+       return sd_resume(dev);
+}
+
 /**
  *     init_sd - entry point for this driver (both when built in or when
  *     a module).