aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>2011-11-30 21:21:55 -0500
committerJames Bottomley <JBottomley@Parallels.com>2011-12-15 01:57:33 -0500
commitba96bd0b1d4a4e11f23671e1f375a5c8f46b0fe7 (patch)
tree7db0fcd7efbc8b3fcf9bdb88e1ffef1fda9fc78e /drivers
parent7509d6bb955d08c4125bcf44650b2df839470bf8 (diff)
[SCSI] mpt2sas: Support for greater than 2TB capacity WarpDrive
The driver is modified to allow access to the greater than 2TB WarpDrive and properly handle direct-io mapping for WarpDrive volumes greater than 2TB. Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_base.h2
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_scsih.c115
2 files changed, 74 insertions, 43 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_base.h b/drivers/scsi/mpt2sas/mpt2sas_base.h
index b3b03bb8ab50..88ead5ed2afc 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_base.h
+++ b/drivers/scsi/mpt2sas/mpt2sas_base.h
@@ -374,6 +374,7 @@ struct _sas_device {
374 * @percent_complete: resync percent complete 374 * @percent_complete: resync percent complete
375 * @direct_io_enabled: Whether direct io to PDs are allowed or not 375 * @direct_io_enabled: Whether direct io to PDs are allowed or not
376 * @stripe_exponent: X where 2powX is the stripe sz in blocks 376 * @stripe_exponent: X where 2powX is the stripe sz in blocks
377 * @block_exponent: X where 2powX is the block sz in bytes
377 * @max_lba: Maximum number of LBA in the volume 378 * @max_lba: Maximum number of LBA in the volume
378 * @stripe_sz: Stripe Size of the volume 379 * @stripe_sz: Stripe Size of the volume
379 * @device_info: Device info of the volume member disk 380 * @device_info: Device info of the volume member disk
@@ -395,6 +396,7 @@ struct _raid_device {
395 u8 percent_complete; 396 u8 percent_complete;
396 u8 direct_io_enabled; 397 u8 direct_io_enabled;
397 u8 stripe_exponent; 398 u8 stripe_exponent;
399 u8 block_exponent;
398 u64 max_lba; 400 u64 max_lba;
399 u32 stripe_sz; 401 u32 stripe_sz;
400 u32 device_info; 402 u32 device_info;
diff --git a/drivers/scsi/mpt2sas/mpt2sas_scsih.c b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
index a9efc4551086..ba8171fe17ef 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_scsih.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_scsih.c
@@ -1780,11 +1780,9 @@ _scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
1780 Mpi2ConfigReply_t mpi_reply; 1780 Mpi2ConfigReply_t mpi_reply;
1781 u16 sz; 1781 u16 sz;
1782 u8 num_pds, count; 1782 u8 num_pds, count;
1783 u64 mb = 1024 * 1024; 1783 unsigned long stripe_sz, block_sz;
1784 u64 tb_2 = 2 * mb * mb; 1784 u8 stripe_exp, block_exp;
1785 u64 capacity; 1785 u64 dev_max_lba;
1786 u32 stripe_sz;
1787 u8 i, stripe_exp;
1788 1786
1789 if (!ioc->is_warpdrive) 1787 if (!ioc->is_warpdrive)
1790 return; 1788 return;
@@ -1848,51 +1846,57 @@ _scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
1848 vol_pg0->PhysDisk[count].PhysDiskNum); 1846 vol_pg0->PhysDisk[count].PhysDiskNum);
1849 goto out_error; 1847 goto out_error;
1850 } 1848 }
1849 /* Disable direct I/O if member drive lba exceeds 4 bytes */
1850 dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA);
1851 if (dev_max_lba >> 32) {
1852 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is "
1853 "disabled for the drive with handle(0x%04x) member"
1854 "handle (0x%04x) unsupported max lba 0x%016llx\n",
1855 ioc->name, raid_device->handle,
1856 le16_to_cpu(pd_pg0.DevHandle),
1857 (unsigned long long)dev_max_lba);
1858 goto out_error;
1859 }
1860
1851 raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle); 1861 raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
1852 } 1862 }
1853 1863
1854 /* 1864 /*
1855 * Assumption for WD: Direct I/O is not supported if the volume is 1865 * Assumption for WD: Direct I/O is not supported if the volume is
1856 * not RAID0, if the stripe size is not 64KB, if the block size is 1866 * not RAID0
1857 * not 512 and if the volume size is >2TB
1858 */ 1867 */
1859 if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0 || 1868 if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) {
1860 le16_to_cpu(vol_pg0->BlockSize) != 512) {
1861 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " 1869 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1862 "for the drive with handle(0x%04x): type=%d, " 1870 "for the drive with handle(0x%04x): type=%d, "
1863 "s_sz=%uK, blk_size=%u\n", ioc->name, 1871 "s_sz=%uK, blk_size=%u\n", ioc->name,
1864 raid_device->handle, raid_device->volume_type, 1872 raid_device->handle, raid_device->volume_type,
1865 le32_to_cpu(vol_pg0->StripeSize)/2, 1873 (le32_to_cpu(vol_pg0->StripeSize) *
1874 le16_to_cpu(vol_pg0->BlockSize)) / 1024,
1866 le16_to_cpu(vol_pg0->BlockSize)); 1875 le16_to_cpu(vol_pg0->BlockSize));
1867 goto out_error; 1876 goto out_error;
1868 } 1877 }
1869 1878
1870 capacity = (u64) le16_to_cpu(vol_pg0->BlockSize) * 1879 stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
1871 (le64_to_cpu(vol_pg0->MaxLBA) + 1); 1880 stripe_exp = find_first_bit(&stripe_sz, 32);
1872 1881 if (stripe_exp == 32) {
1873 if (capacity > tb_2) {
1874 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " 1882 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1875 "for the drive with handle(0x%04x) since drive sz > 2TB\n", 1883 "for the drive with handle(0x%04x) invalid stripe sz %uK\n",
1876 ioc->name, raid_device->handle); 1884 ioc->name, raid_device->handle,
1885 (le32_to_cpu(vol_pg0->StripeSize) *
1886 le16_to_cpu(vol_pg0->BlockSize)) / 1024);
1877 goto out_error; 1887 goto out_error;
1878 } 1888 }
1879 1889 raid_device->stripe_exponent = stripe_exp;
1880 stripe_sz = le32_to_cpu(vol_pg0->StripeSize); 1890 block_sz = le16_to_cpu(vol_pg0->BlockSize);
1881 stripe_exp = 0; 1891 block_exp = find_first_bit(&block_sz, 16);
1882 for (i = 0; i < 32; i++) { 1892 if (block_exp == 16) {
1883 if (stripe_sz & 1)
1884 break;
1885 stripe_exp++;
1886 stripe_sz >>= 1;
1887 }
1888 if (i == 32) {
1889 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled " 1893 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
1890 "for the drive with handle(0x%04x) invalid stripe sz %uK\n", 1894 "for the drive with handle(0x%04x) invalid block sz %u\n",
1891 ioc->name, raid_device->handle, 1895 ioc->name, raid_device->handle,
1892 le32_to_cpu(vol_pg0->StripeSize)/2); 1896 le16_to_cpu(vol_pg0->BlockSize));
1893 goto out_error; 1897 goto out_error;
1894 } 1898 }
1895 raid_device->stripe_exponent = stripe_exp; 1899 raid_device->block_exponent = block_exp;
1896 raid_device->direct_io_enabled = 1; 1900 raid_device->direct_io_enabled = 1;
1897 1901
1898 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive" 1902 printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive"
@@ -3808,8 +3812,9 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3808{ 3812{
3809 u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size; 3813 u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size;
3810 u32 stripe_sz, stripe_exp; 3814 u32 stripe_sz, stripe_exp;
3811 u8 num_pds, *cdb_ptr, *tmp_ptr, *lba_ptr1, *lba_ptr2; 3815 u8 num_pds, *cdb_ptr, i;
3812 u8 cdb0 = scmd->cmnd[0]; 3816 u8 cdb0 = scmd->cmnd[0];
3817 u64 v_llba;
3813 3818
3814 /* 3819 /*
3815 * Try Direct I/O to RAID memeber disks 3820 * Try Direct I/O to RAID memeber disks
@@ -3820,15 +3825,11 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3820 3825
3821 if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4] 3826 if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4]
3822 | cdb_ptr[5])) { 3827 | cdb_ptr[5])) {
3823 io_size = scsi_bufflen(scmd) >> 9; 3828 io_size = scsi_bufflen(scmd) >>
3829 raid_device->block_exponent;
3830 i = (cdb0 < READ_16) ? 2 : 6;
3824 /* get virtual lba */ 3831 /* get virtual lba */
3825 lba_ptr1 = lba_ptr2 = (cdb0 < READ_16) ? &cdb_ptr[2] : 3832 v_lba = be32_to_cpu(*(__be32 *)(&cdb_ptr[i]));
3826 &cdb_ptr[6];
3827 tmp_ptr = (u8 *)&v_lba + 3;
3828 *tmp_ptr-- = *lba_ptr1++;
3829 *tmp_ptr-- = *lba_ptr1++;
3830 *tmp_ptr-- = *lba_ptr1++;
3831 *tmp_ptr = *lba_ptr1;
3832 3833
3833 if (((u64)v_lba + (u64)io_size - 1) <= 3834 if (((u64)v_lba + (u64)io_size - 1) <=
3834 (u32)raid_device->max_lba) { 3835 (u32)raid_device->max_lba) {
@@ -3847,11 +3848,39 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
3847 mpi_request->DevHandle = 3848 mpi_request->DevHandle =
3848 cpu_to_le16(raid_device-> 3849 cpu_to_le16(raid_device->
3849 pd_handle[column]); 3850 pd_handle[column]);
3850 tmp_ptr = (u8 *)&p_lba + 3; 3851 (*(__be32 *)(&cdb_ptr[i])) =
3851 *lba_ptr2++ = *tmp_ptr--; 3852 cpu_to_be32(p_lba);
3852 *lba_ptr2++ = *tmp_ptr--; 3853 /*
3853 *lba_ptr2++ = *tmp_ptr--; 3854 * WD: To indicate this I/O is directI/O
3854 *lba_ptr2 = *tmp_ptr; 3855 */
3856 _scsih_scsi_direct_io_set(ioc, smid, 1);
3857 }
3858 }
3859 } else {
3860 io_size = scsi_bufflen(scmd) >>
3861 raid_device->block_exponent;
3862 /* get virtual lba */
3863 v_llba = be64_to_cpu(*(__be64 *)(&cdb_ptr[2]));
3864
3865 if ((v_llba + (u64)io_size - 1) <=
3866 raid_device->max_lba) {
3867 stripe_sz = raid_device->stripe_sz;
3868 stripe_exp = raid_device->stripe_exponent;
3869 stripe_off = (u32) (v_llba & (stripe_sz - 1));
3870
3871 /* Check whether IO falls within a stripe */
3872 if ((stripe_off + io_size) <= stripe_sz) {
3873 num_pds = raid_device->num_pds;
3874 p_lba = (u32)(v_llba >> stripe_exp);
3875 stripe_unit = p_lba / num_pds;
3876 column = p_lba % num_pds;
3877 p_lba = (stripe_unit << stripe_exp) +
3878 stripe_off;
3879 mpi_request->DevHandle =
3880 cpu_to_le16(raid_device->
3881 pd_handle[column]);
3882 (*(__be64 *)(&cdb_ptr[2])) =
3883 cpu_to_be64((u64)p_lba);
3855 /* 3884 /*
3856 * WD: To indicate this I/O is directI/O 3885 * WD: To indicate this I/O is directI/O
3857 */ 3886 */