Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
[pandora-kernel.git] / drivers / scsi / sd.c
index f899ff0..84ff203 100644 (file)
@@ -32,7 +32,6 @@
  *     than the level indicated above to trigger output.       
  */
 
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/fs.h>
 #include <linux/kernel.h>
@@ -208,6 +207,23 @@ static ssize_t sd_store_cache_type(struct class_device *cdev, const char *buf,
        return count;
 }
 
+static ssize_t sd_store_allow_restart(struct class_device *cdev, const char *buf,
+                                     size_t count)
+{
+       struct scsi_disk *sdkp = to_scsi_disk(cdev);
+       struct scsi_device *sdp = sdkp->device;
+
+       if (!capable(CAP_SYS_ADMIN))
+               return -EACCES;
+
+       if (sdp->type != TYPE_DISK)
+               return -EINVAL;
+
+       sdp->allow_restart = simple_strtoul(buf, NULL, 10);
+
+       return count;
+}
+
 static ssize_t sd_show_cache_type(struct class_device *cdev, char *buf)
 {
        struct scsi_disk *sdkp = to_scsi_disk(cdev);
@@ -223,10 +239,19 @@ static ssize_t sd_show_fua(struct class_device *cdev, char *buf)
        return snprintf(buf, 20, "%u\n", sdkp->DPOFUA);
 }
 
+static ssize_t sd_show_allow_restart(struct class_device *cdev, char *buf)
+{
+       struct scsi_disk *sdkp = to_scsi_disk(cdev);
+
+       return snprintf(buf, 40, "%d\n", sdkp->device->allow_restart);
+}
+
 static struct class_device_attribute sd_disk_attrs[] = {
        __ATTR(cache_type, S_IRUGO|S_IWUSR, sd_show_cache_type,
               sd_store_cache_type),
        __ATTR(FUA, S_IRUGO, sd_show_fua, NULL),
+       __ATTR(allow_restart, S_IRUGO|S_IWUSR, sd_show_allow_restart,
+              sd_store_allow_restart),
        __ATTR_NULL,
 };
 
@@ -418,8 +443,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
                SCpnt->cmnd[0] = READ_6;
                SCpnt->sc_data_direction = DMA_FROM_DEVICE;
        } else {
-               printk(KERN_ERR "sd: Unknown command %lx\n", rq->flags);
-/* overkill    panic("Unknown sd command %lx\n", rq->flags); */
+               printk(KERN_ERR "sd: Unknown command %x\n", rq->cmd_flags);
                return 0;
        }
 
@@ -477,8 +501,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt)
                SCpnt->cmnd[4] = (unsigned char) this_count;
                SCpnt->cmnd[5] = 0;
        }
-       SCpnt->request_bufflen = SCpnt->bufflen =
-                       this_count * sdp->sector_size;
+       SCpnt->request_bufflen = this_count * sdp->sector_size;
 
        /*
         * We shouldn't disconnect in the middle of a sector, so with a dumb
@@ -816,7 +839,7 @@ static int sd_issue_flush(struct device *dev, sector_t *error_sector)
 static void sd_prepare_flush(request_queue_t *q, struct request *rq)
 {
        memset(rq->cmd, 0, sizeof(rq->cmd));
-       rq->flags |= REQ_BLOCK_PC;
+       rq->cmd_type = REQ_TYPE_BLOCK_PC;
        rq->timeout = SD_TIMEOUT;
        rq->cmd[0] = SYNCHRONIZE_CACHE;
        rq->cmd_len = 10;
@@ -1191,7 +1214,7 @@ repeat:
                /* Either no media are present but the drive didn't tell us,
                   or they are present but the read capacity command fails */
                /* sdkp->media_present = 0; -- not always correct */
-               sdkp->capacity = 0x200000; /* 1 GB - random */
+               sdkp->capacity = 0; /* unknown mapped to zero - as usual */
 
                return;
        } else if (the_result && longrc) {
@@ -1771,7 +1794,7 @@ static void sd_shutdown(struct device *dev)
  **/
 static int __init init_sd(void)
 {
-       int majors = 0, i;
+       int majors = 0, i, err;
 
        SCSI_LOG_HLQUEUE(3, printk("init_sd: sd driver entry point\n"));
 
@@ -1782,9 +1805,22 @@ static int __init init_sd(void)
        if (!majors)
                return -ENODEV;
 
-       class_register(&sd_disk_class);
+       err = class_register(&sd_disk_class);
+       if (err)
+               goto err_out;
+
+       err = scsi_register_driver(&sd_template.gendrv);
+       if (err)
+               goto err_out_class;
 
-       return scsi_register_driver(&sd_template.gendrv);
+       return 0;
+
+err_out_class:
+       class_unregister(&sd_disk_class);
+err_out:
+       for (i = 0; i < SD_MAJORS; i++)
+               unregister_blkdev(sd_major(i), "sd");
+       return err;
 }
 
 /**
@@ -1799,10 +1835,10 @@ static void __exit exit_sd(void)
        SCSI_LOG_HLQUEUE(3, printk("exit_sd: exiting sd driver\n"));
 
        scsi_unregister_driver(&sd_template.gendrv);
+       class_unregister(&sd_disk_class);
+
        for (i = 0; i < SD_MAJORS; i++)
                unregister_blkdev(sd_major(i), "sd");
-
-       class_unregister(&sd_disk_class);
 }
 
 module_init(init_sd);