Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (84 commits) [SCSI] be2iscsi: SGE Len == 64K [SCSI] be2iscsi: Remove premature free of cid [SCSI] be2iscsi: More time for FW [SCSI] libsas: fix bug for vacant phy [SCSI] sd: Fix overflow with big physical blocks [SCSI] st: add MTWEOFI to write filemarks without flushing drive buffer [SCSI] libsas: Don't issue commands to devices that have been hot-removed [SCSI] megaraid_sas: Add Online Controller Reset to MegaRAID SAS drive [SCSI] lpfc 8.3.17: Update lpfc driver version to 8.3.17 [SCSI] lpfc 8.3.17: Replace function reset methodology [SCSI] lpfc 8.3.17: SCSI fixes [SCSI] lpfc 8.3.17: BSG fixes [SCSI] lpfc 8.3.17: SLI Additions and Fixes [SCSI] lpfc 8.3.17: Code Cleanup and Locking fixes [SCSI] zfcp: Remove scsi_cmnd->serial_number from debug traces [SCSI] ipr: fix array error logging [SCSI] aha152x: enable PCMCIA on 64bit [SCSI] scsi_dh_alua: Handle all states correctly [SCSI] cxgb4i: connection and ddp setting update [SCSI] cxgb3i: fixed connection over vlan ...
This commit is contained in:
@@ -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;
|
||||
}
|
||||
@@ -1554,7 +1554,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;
|
||||
@@ -1567,7 +1567,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 */
|
||||
@@ -1635,7 +1635,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;
|
||||
}
|
||||
|
||||
@@ -1756,10 +1756,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1773,7 +1773,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;
|
||||
}
|
||||
|
||||
@@ -2039,14 +2040,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)
|
||||
@@ -2087,6 +2098,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)
|
||||
{
|
||||
/*
|
||||
@@ -2138,6 +2174,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);
|
||||
}
|
||||
@@ -2250,11 +2287,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;
|
||||
@@ -2344,6 +2380,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;
|
||||
|
Reference in New Issue
Block a user