drivers/scsi/mpt3sas/mpt3sas_warpdrive.c

Source file repositories/reference/linux-study-clean/drivers/scsi/mpt3sas/mpt3sas_warpdrive.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/mpt3sas/mpt3sas_warpdrive.c
Extension
.c
Size
10021 bytes
Lines
299
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (dev_max_lba >> 32) {
			ioc_info(ioc, "WarpDrive : Direct IO is disabled for the drive with handle(0x%04x) member handle (0x%04x) unsupported max lba 0x%016llx\n",
				 raid_device->handle,
				 le16_to_cpu(pd_pg0.DevHandle),
				 (u64)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 (raid_device->volume_type != MPI2_RAID_VOL_TYPE_RAID0) {
		ioc_info(ioc, "WarpDrive : Direct IO is disabled for the drive with handle(0x%04x): type=%d, s_sz=%uK, blk_size=%u\n",
			 raid_device->handle, raid_device->volume_type,
			 (le32_to_cpu(vol_pg0->StripeSize) *
			  le16_to_cpu(vol_pg0->BlockSize)) / 1024,
			 le16_to_cpu(vol_pg0->BlockSize));
		goto out_error;
	}

	stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
	stripe_exp = find_first_bit(&stripe_sz, 32);
	if (stripe_exp == 32) {
		ioc_info(ioc, "WarpDrive : Direct IO is disabled for the drive with handle(0x%04x) invalid stripe sz %uK\n",
			 raid_device->handle,
			 (le32_to_cpu(vol_pg0->StripeSize) *
			  le16_to_cpu(vol_pg0->BlockSize)) / 1024);
		goto out_error;
	}
	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) {
		ioc_info(ioc, "WarpDrive : Direct IO is disabled for the drive with handle(0x%04x) invalid block sz %u\n",
			 raid_device->handle, le16_to_cpu(vol_pg0->BlockSize));
		goto out_error;
	}
	raid_device->block_exponent = block_exp;
	raid_device->direct_io_enabled = 1;

	ioc_info(ioc, "WarpDrive : Direct IO is Enabled for the drive with handle(0x%04x)\n",
		 raid_device->handle);
	/*
	 * WARPDRIVE: Though the following fields are not used for direct IO,
	 * stored for future purpose:
	 */
	raid_device->max_lba = le64_to_cpu(vol_pg0->MaxLBA);
	raid_device->stripe_sz = le32_to_cpu(vol_pg0->StripeSize);
	raid_device->block_sz = le16_to_cpu(vol_pg0->BlockSize);


	kfree(vol_pg0);
	return;

out_error:
	raid_device->direct_io_enabled = 0;
	for (count = 0; count < num_pds; count++)
		raid_device->pd_handle[count] = 0;
	kfree(vol_pg0);
	return;
}

/**
 * mpt3sas_setup_direct_io - setup MPI request for WARPDRIVE Direct I/O
 * @ioc: per adapter object
 * @scmd: pointer to scsi command object
 * @raid_device: pointer to raid device data structure
 * @mpi_request: pointer to the SCSI_IO reqest message frame
 */
void
mpt3sas_setup_direct_io(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd,
	struct _raid_device *raid_device, Mpi25SCSIIORequest_t *mpi_request)
{
	sector_t v_lba, p_lba, stripe_off, column, io_size;
	u32 stripe_sz, stripe_exp;
	u8 num_pds, cmd = scmd->cmnd[0];
	struct scsiio_tracker *st = scsi_cmd_priv(scmd);

	if (cmd != READ_10 && cmd != WRITE_10 &&
	    cmd != READ_16 && cmd != WRITE_16)
		return;

	if (cmd == READ_10 || cmd == WRITE_10)
		v_lba = get_unaligned_be32(&mpi_request->CDB.CDB32[2]);
	else
		v_lba = get_unaligned_be64(&mpi_request->CDB.CDB32[2]);

Annotation

Implementation Notes