Merge git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/usb-2.6
[sfrench/cifs-2.6.git] / drivers / scsi / sd.c
index ff4c9a3aa5b26396935fc8927a378d3e4ed5e1fd..57d1e3e1bd4478548f89ef9f3a472ee4418c71b3 100644 (file)
@@ -477,7 +477,7 @@ static int scsi_setup_discard_cmnd(struct scsi_device *sdp, struct request *rq)
 
 static int scsi_setup_flush_cmnd(struct scsi_device *sdp, struct request *rq)
 {
-       rq->timeout = SD_TIMEOUT;
+       rq->timeout = SD_FLUSH_TIMEOUT;
        rq->retries = SD_MAX_RETRIES;
        rq->cmd[0] = SYNCHRONIZE_CACHE;
        rq->cmd_len = 10;
@@ -1072,7 +1072,7 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
                 * flush everything.
                 */
                res = scsi_execute_req(sdp, cmd, DMA_NONE, NULL, 0, &sshdr,
-                                      SD_TIMEOUT, SD_MAX_RETRIES, NULL);
+                                      SD_FLUSH_TIMEOUT, SD_MAX_RETRIES, NULL);
                if (res == 0)
                        break;
        }
@@ -1557,7 +1557,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
        }
 
        /* Logical blocks per physical block exponent */
-       sdkp->hw_sector_size = (1 << (buffer[13] & 0xf)) * sector_size;
+       sdkp->physical_block_size = (1 << (buffer[13] & 0xf)) * sector_size;
 
        /* Lowest aligned logical block */
        alignment = ((buffer[14] & 0x3f) << 8 | buffer[15]) * sector_size;
@@ -1570,7 +1570,7 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp,
                struct request_queue *q = sdp->request_queue;
 
                sdkp->thin_provisioning = 1;
-               q->limits.discard_granularity = sdkp->hw_sector_size;
+               q->limits.discard_granularity = sdkp->physical_block_size;
                q->limits.max_discard_sectors = 0xffffffff;
 
                if (buffer[14] & 0x40) /* TPRZ */
@@ -1634,7 +1634,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
                   0xffffffff when the want to report a size of 0 (with
                   which they really mean no media is present) */
                sdkp->capacity = 0;
-               sdkp->hw_sector_size = sector_size;
+               sdkp->physical_block_size = sector_size;
                return sector_size;
        }
 
@@ -1647,7 +1647,7 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp,
        }
 
        sdkp->capacity = lba + 1;
-       sdkp->hw_sector_size = sector_size;
+       sdkp->physical_block_size = sector_size;
        return sector_size;
 }
 
@@ -1768,10 +1768,10 @@ got_data:
                                  (unsigned long long)sdkp->capacity,
                                  sector_size, cap_str_10, cap_str_2);
 
-                       if (sdkp->hw_sector_size != sector_size)
+                       if (sdkp->physical_block_size != sector_size)
                                sd_printk(KERN_NOTICE, sdkp,
                                          "%u-byte physical blocks\n",
-                                         sdkp->hw_sector_size);
+                                         sdkp->physical_block_size);
                }
        }
 
@@ -1785,7 +1785,8 @@ got_data:
        else if (sector_size == 256)
                sdkp->capacity >>= 1;
 
-       blk_queue_physical_block_size(sdp->request_queue, sdkp->hw_sector_size);
+       blk_queue_physical_block_size(sdp->request_queue,
+                                     sdkp->physical_block_size);
        sdkp->device->sector_size = sector_size;
 }
 
@@ -2051,14 +2052,24 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)
                lba_count = get_unaligned_be32(&buffer[20]);
                desc_count = get_unaligned_be32(&buffer[24]);
 
-               if (lba_count) {
-                       q->limits.max_discard_sectors =
-                               lba_count * sector_sz >> 9;
-
-                       if (desc_count)
+               if (lba_count && desc_count) {
+                       if (sdkp->tpvpd && !sdkp->tpu)
+                               sdkp->unmap = 0;
+                       else
                                sdkp->unmap = 1;
                }
 
+               if (sdkp->tpvpd && !sdkp->tpu && !sdkp->tpws) {
+                       sd_printk(KERN_ERR, sdkp, "Thin provisioning is " \
+                                 "enabled but neither TPU, nor TPWS are " \
+                                 "set. Disabling discard!\n");
+                       goto out;
+               }
+
+               if (lba_count)
+                       q->limits.max_discard_sectors =
+                               lba_count * sector_sz >> 9;
+
                granularity = get_unaligned_be32(&buffer[28]);
 
                if (granularity)
@@ -2099,6 +2110,31 @@ static void sd_read_block_characteristics(struct scsi_disk *sdkp)
        kfree(buffer);
 }
 
+/**
+ * sd_read_thin_provisioning - Query thin provisioning VPD page
+ * @disk: disk to query
+ */
+static void sd_read_thin_provisioning(struct scsi_disk *sdkp)
+{
+       unsigned char *buffer;
+       const int vpd_len = 8;
+
+       if (sdkp->thin_provisioning == 0)
+               return;
+
+       buffer = kmalloc(vpd_len, GFP_KERNEL);
+
+       if (!buffer || scsi_get_vpd_page(sdkp->device, 0xb2, buffer, vpd_len))
+               goto out;
+
+       sdkp->tpvpd = 1;
+       sdkp->tpu   = (buffer[5] >> 7) & 1;     /* UNMAP */
+       sdkp->tpws  = (buffer[5] >> 6) & 1;     /* WRITE SAME(16) with UNMAP */
+
+ out:
+       kfree(buffer);
+}
+
 static int sd_try_extended_inquiry(struct scsi_device *sdp)
 {
        /*
@@ -2121,7 +2157,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;
+       unsigned flush = 0;
 
        SCSI_LOG_HLQUEUE(3, sd_printk(KERN_INFO, sdkp,
                                      "sd_revalidate_disk\n"));
@@ -2150,6 +2186,7 @@ static int sd_revalidate_disk(struct gendisk *disk)
                sd_read_capacity(sdkp, buffer);
 
                if (sd_try_extended_inquiry(sdp)) {
+                       sd_read_thin_provisioning(sdkp);
                        sd_read_block_limits(sdkp);
                        sd_read_block_characteristics(sdkp);
                }
@@ -2163,17 +2200,15 @@ static int sd_revalidate_disk(struct gendisk *disk)
 
        /*
         * 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.
+        * with flush requests.
         */
-       if (sdkp->WCE)
-               ordered = sdkp->DPOFUA
-                       ? QUEUE_ORDERED_DRAIN_FUA : QUEUE_ORDERED_DRAIN_FLUSH;
-       else
-               ordered = QUEUE_ORDERED_DRAIN;
+       if (sdkp->WCE) {
+               flush |= REQ_FLUSH;
+               if (sdkp->DPOFUA)
+                       flush |= REQ_FUA;
+       }
 
-       blk_queue_ordered(sdkp->disk->queue, ordered);
+       blk_queue_flush(sdkp->disk->queue, flush);
 
        set_capacity(disk, sdkp->capacity);
        kfree(buffer);
@@ -2264,11 +2299,10 @@ static void sd_probe_async(void *data, async_cookie_t cookie)
        index = sdkp->index;
        dev = &sdp->sdev_gendev;
 
-       if (index < SD_MAX_DISKS) {
-               gd->major = sd_major((index & 0xf0) >> 4);
-               gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
-               gd->minors = SD_MINORS;
-       }
+       gd->major = sd_major((index & 0xf0) >> 4);
+       gd->first_minor = ((index & 0xf) << 4) | (index & 0xfff00);
+       gd->minors = SD_MINORS;
+
        gd->fops = &sd_fops;
        gd->private_data = &sdkp->driver;
        gd->queue = sdkp->device->request_queue;
@@ -2358,6 +2392,12 @@ static int sd_probe(struct device *dev)
        if (error)
                goto out_put;
 
+       if (index >= SD_MAX_DISKS) {
+               error = -ENODEV;
+               sdev_printk(KERN_WARNING, sdp, "SCSI disk (sd) name space exhausted.\n");
+               goto out_free_index;
+       }
+
        error = sd_format_disk_name("sd", index, gd->disk_name, DISK_NAME_LEN);
        if (error)
                goto out_free_index;