diff options
Diffstat (limited to 'drivers/scsi/sd.c')
| -rw-r--r-- | drivers/scsi/sd.c | 37 | 
1 files changed, 26 insertions, 11 deletions
| diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 11c1738c2100..d175c5c5ccf8 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -715,13 +715,21 @@ static void sd_config_discard(struct scsi_disk *sdkp, unsigned int mode)  		break;  	case SD_LBP_WS16: -		max_blocks = min_not_zero(sdkp->max_ws_blocks, -					  (u32)SD_MAX_WS16_BLOCKS); +		if (sdkp->device->unmap_limit_for_ws) +			max_blocks = sdkp->max_unmap_blocks; +		else +			max_blocks = sdkp->max_ws_blocks; + +		max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS16_BLOCKS);  		break;  	case SD_LBP_WS10: -		max_blocks = min_not_zero(sdkp->max_ws_blocks, -					  (u32)SD_MAX_WS10_BLOCKS); +		if (sdkp->device->unmap_limit_for_ws) +			max_blocks = sdkp->max_unmap_blocks; +		else +			max_blocks = sdkp->max_ws_blocks; + +		max_blocks = min_not_zero(max_blocks, (u32)SD_MAX_WS10_BLOCKS);  		break;  	case SD_LBP_ZERO: @@ -2915,8 +2923,6 @@ static void sd_read_block_limits(struct scsi_disk *sdkp)  				sd_config_discard(sdkp, SD_LBP_WS16);  			else if (sdkp->lbpws10)  				sd_config_discard(sdkp, SD_LBP_WS10); -			else if (sdkp->lbpu && sdkp->max_unmap_blocks) -				sd_config_discard(sdkp, SD_LBP_UNMAP);  			else  				sd_config_discard(sdkp, SD_LBP_DISABLE);  		} @@ -3101,8 +3107,6 @@ static int sd_revalidate_disk(struct gendisk *disk)  		sd_read_security(sdkp, buffer);  	} -	sdkp->first_scan = 0; -  	/*  	 * We now have all cache related info, determine how we deal  	 * with flush requests. @@ -3117,7 +3121,7 @@ static int sd_revalidate_disk(struct gendisk *disk)  	q->limits.max_dev_sectors = logical_to_sectors(sdp, dev_max);  	/* -	 * Use the device's preferred I/O size for reads and writes +	 * Determine the device's preferred I/O size for reads and writes  	 * unless the reported value is unreasonably small, large, or  	 * garbage.  	 */ @@ -3131,8 +3135,19 @@ static int sd_revalidate_disk(struct gendisk *disk)  		rw_max = min_not_zero(logical_to_sectors(sdp, dev_max),  				      (sector_t)BLK_DEF_MAX_SECTORS); -	/* Combine with controller limits */ -	q->limits.max_sectors = min(rw_max, queue_max_hw_sectors(q)); +	/* Do not exceed controller limit */ +	rw_max = min(rw_max, queue_max_hw_sectors(q)); + +	/* +	 * Only update max_sectors if previously unset or if the current value +	 * exceeds the capabilities of the hardware. +	 */ +	if (sdkp->first_scan || +	    q->limits.max_sectors > q->limits.max_dev_sectors || +	    q->limits.max_sectors > q->limits.max_hw_sectors) +		q->limits.max_sectors = rw_max; + +	sdkp->first_scan = 0;  	set_capacity(disk, logical_to_sectors(sdp, sdkp->capacity));  	sd_config_write_same(sdkp); |