Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 282257
b: refs/heads/master
c: ba96bd0
h: refs/heads/master
i:
  282255: 263a1fb
v: v3
  • Loading branch information
nagalakshmi.nandigama@lsi.com authored and James Bottomley committed Dec 15, 2011
1 parent 08f0c57 commit 6b9e195
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 44 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 7509d6bb955d08c4125bcf44650b2df839470bf8
refs/heads/master: ba96bd0b1d4a4e11f23671e1f375a5c8f46b0fe7
2 changes: 2 additions & 0 deletions trunk/drivers/scsi/mpt2sas/mpt2sas_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -374,6 +374,7 @@ struct _sas_device {
* @percent_complete: resync percent complete
* @direct_io_enabled: Whether direct io to PDs are allowed or not
* @stripe_exponent: X where 2powX is the stripe sz in blocks
* @block_exponent: X where 2powX is the block sz in bytes
* @max_lba: Maximum number of LBA in the volume
* @stripe_sz: Stripe Size of the volume
* @device_info: Device info of the volume member disk
Expand All @@ -395,6 +396,7 @@ struct _raid_device {
u8 percent_complete;
u8 direct_io_enabled;
u8 stripe_exponent;
u8 block_exponent;
u64 max_lba;
u32 stripe_sz;
u32 device_info;
Expand Down
115 changes: 72 additions & 43 deletions trunk/drivers/scsi/mpt2sas/mpt2sas_scsih.c
Original file line number Diff line number Diff line change
Expand Up @@ -1780,11 +1780,9 @@ _scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
Mpi2ConfigReply_t mpi_reply;
u16 sz;
u8 num_pds, count;
u64 mb = 1024 * 1024;
u64 tb_2 = 2 * mb * mb;
u64 capacity;
u32 stripe_sz;
u8 i, stripe_exp;
unsigned long stripe_sz, block_sz;
u8 stripe_exp, block_exp;
u64 dev_max_lba;

if (!ioc->is_warpdrive)
return;
Expand Down Expand Up @@ -1848,51 +1846,57 @@ _scsih_init_warpdrive_properties(struct MPT2SAS_ADAPTER *ioc,
vol_pg0->PhysDisk[count].PhysDiskNum);
goto out_error;
}
/* Disable direct I/O if member drive lba exceeds 4 bytes */
dev_max_lba = le64_to_cpu(pd_pg0.DeviceMaxLBA);
if (dev_max_lba >> 32) {
printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is "
"disabled for the drive with handle(0x%04x) member"
"handle (0x%04x) unsupported max lba 0x%016llx\n",
ioc->name, raid_device->handle,
le16_to_cpu(pd_pg0.DevHandle),
(unsigned long long)dev_max_lba);
goto out_error;
}

raid_device->pd_handle[count] = le16_to_cpu(pd_pg0.DevHandle);
}

/*
* Assumption for WD: Direct I/O is not supported if the volume is
* not RAID0, if the stripe size is not 64KB, if the block size is
* not 512 and if the volume size is >2TB
* not RAID0
*/
if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0 ||
le16_to_cpu(vol_pg0->BlockSize) != 512) {
if (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) {
printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
"for the drive with handle(0x%04x): type=%d, "
"s_sz=%uK, blk_size=%u\n", ioc->name,
raid_device->handle, raid_device->volume_type,
le32_to_cpu(vol_pg0->StripeSize)/2,
(le32_to_cpu(vol_pg0->StripeSize) *
le16_to_cpu(vol_pg0->BlockSize)) / 1024,
le16_to_cpu(vol_pg0->BlockSize));
goto out_error;
}

capacity = (u64) le16_to_cpu(vol_pg0->BlockSize) *
(le64_to_cpu(vol_pg0->MaxLBA) + 1);

if (capacity > tb_2) {
stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
stripe_exp = find_first_bit(&stripe_sz, 32);
if (stripe_exp == 32) {
printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
"for the drive with handle(0x%04x) since drive sz > 2TB\n",
ioc->name, raid_device->handle);
"for the drive with handle(0x%04x) invalid stripe sz %uK\n",
ioc->name, raid_device->handle,
(le32_to_cpu(vol_pg0->StripeSize) *
le16_to_cpu(vol_pg0->BlockSize)) / 1024);
goto out_error;
}

stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
stripe_exp = 0;
for (i = 0; i < 32; i++) {
if (stripe_sz & 1)
break;
stripe_exp++;
stripe_sz >>= 1;
}
if (i == 32) {
raid_device->stripe_exponent = stripe_exp;
block_sz = le16_to_cpu(vol_pg0->BlockSize);
block_exp = find_first_bit(&block_sz, 16);
if (block_exp == 16) {
printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is disabled "
"for the drive with handle(0x%04x) invalid stripe sz %uK\n",
"for the drive with handle(0x%04x) invalid block sz %u\n",
ioc->name, raid_device->handle,
le32_to_cpu(vol_pg0->StripeSize)/2);
le16_to_cpu(vol_pg0->BlockSize));
goto out_error;
}
raid_device->stripe_exponent = stripe_exp;
raid_device->block_exponent = block_exp;
raid_device->direct_io_enabled = 1;

printk(MPT2SAS_INFO_FMT "WarpDrive : Direct IO is Enabled for the drive"
Expand Down Expand Up @@ -3808,8 +3812,9 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
{
u32 v_lba, p_lba, stripe_off, stripe_unit, column, io_size;
u32 stripe_sz, stripe_exp;
u8 num_pds, *cdb_ptr, *tmp_ptr, *lba_ptr1, *lba_ptr2;
u8 num_pds, *cdb_ptr, i;
u8 cdb0 = scmd->cmnd[0];
u64 v_llba;

/*
* Try Direct I/O to RAID memeber disks
Expand All @@ -3820,15 +3825,11 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,

if ((cdb0 < READ_16) || !(cdb_ptr[2] | cdb_ptr[3] | cdb_ptr[4]
| cdb_ptr[5])) {
io_size = scsi_bufflen(scmd) >> 9;
io_size = scsi_bufflen(scmd) >>
raid_device->block_exponent;
i = (cdb0 < READ_16) ? 2 : 6;
/* get virtual lba */
lba_ptr1 = lba_ptr2 = (cdb0 < READ_16) ? &cdb_ptr[2] :
&cdb_ptr[6];
tmp_ptr = (u8 *)&v_lba + 3;
*tmp_ptr-- = *lba_ptr1++;
*tmp_ptr-- = *lba_ptr1++;
*tmp_ptr-- = *lba_ptr1++;
*tmp_ptr = *lba_ptr1;
v_lba = be32_to_cpu(*(__be32 *)(&cdb_ptr[i]));

if (((u64)v_lba + (u64)io_size - 1) <=
(u32)raid_device->max_lba) {
Expand All @@ -3847,11 +3848,39 @@ _scsih_setup_direct_io(struct MPT2SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
mpi_request->DevHandle =
cpu_to_le16(raid_device->
pd_handle[column]);
tmp_ptr = (u8 *)&p_lba + 3;
*lba_ptr2++ = *tmp_ptr--;
*lba_ptr2++ = *tmp_ptr--;
*lba_ptr2++ = *tmp_ptr--;
*lba_ptr2 = *tmp_ptr;
(*(__be32 *)(&cdb_ptr[i])) =
cpu_to_be32(p_lba);
/*
* WD: To indicate this I/O is directI/O
*/
_scsih_scsi_direct_io_set(ioc, smid, 1);
}
}
} else {
io_size = scsi_bufflen(scmd) >>
raid_device->block_exponent;
/* get virtual lba */
v_llba = be64_to_cpu(*(__be64 *)(&cdb_ptr[2]));

if ((v_llba + (u64)io_size - 1) <=
raid_device->max_lba) {
stripe_sz = raid_device->stripe_sz;
stripe_exp = raid_device->stripe_exponent;
stripe_off = (u32) (v_llba & (stripe_sz - 1));

/* Check whether IO falls within a stripe */
if ((stripe_off + io_size) <= stripe_sz) {
num_pds = raid_device->num_pds;
p_lba = (u32)(v_llba >> stripe_exp);
stripe_unit = p_lba / num_pds;
column = p_lba % num_pds;
p_lba = (stripe_unit << stripe_exp) +
stripe_off;
mpi_request->DevHandle =
cpu_to_le16(raid_device->
pd_handle[column]);
(*(__be64 *)(&cdb_ptr[2])) =
cpu_to_be64((u64)p_lba);
/*
* WD: To indicate this I/O is directI/O
*/
Expand Down

0 comments on commit 6b9e195

Please sign in to comment.