drivers/scsi/megaraid/megaraid_sas_fusion.c

Source file repositories/reference/linux-study-clean/drivers/scsi/megaraid/megaraid_sas_fusion.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/megaraid/megaraid_sas_fusion.c
Extension
.c
Size
159289 bytes
Lines
5389
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 (cur_max_fw_cmds < instance->max_fw_cmds) {
			instance->cur_can_queue =
				cur_max_fw_cmds - (MEGASAS_FUSION_INTERNAL_CMDS +
						MEGASAS_FUSION_IOCTL_CMDS);
			instance->host->can_queue = instance->cur_can_queue;
			instance->ldio_threshold = ldio_threshold;
		}
	} else {
		instance->max_fw_cmds = cur_max_fw_cmds;
		instance->ldio_threshold = ldio_threshold;

		if (reset_devices)
			instance->max_fw_cmds = min(instance->max_fw_cmds,
						(u16)MEGASAS_KDUMP_QUEUE_DEPTH);
		/*
		* Reduce the max supported cmds by 1. This is to ensure that the
		* reply_q_sz (1 more than the max cmd that driver may send)
		* does not exceed max cmds that the FW can support
		*/
		instance->max_fw_cmds = instance->max_fw_cmds-1;
	}
}

static inline void
megasas_get_msix_index(struct megasas_instance *instance,
		       struct scsi_cmnd *scmd,
		       struct megasas_cmd_fusion *cmd,
		       u8 data_arms)
{
	if (instance->perf_mode == MR_BALANCED_PERF_MODE &&
	    (megasas_sdev_busy_read(instance, scmd) >
	     (data_arms * MR_DEVICE_HIGH_IOPS_DEPTH))) {
		cmd->request_desc->SCSIIO.MSIxIndex =
			mega_mod64((atomic64_add_return(1, &instance->high_iops_outstanding) /
					MR_HIGH_IOPS_BATCH_COUNT), instance->low_latency_index_start);
	} else if (instance->msix_load_balance) {
		cmd->request_desc->SCSIIO.MSIxIndex =
			(mega_mod64(atomic64_add_return(1, &instance->total_io_count),
				instance->msix_vectors));
	} else if (instance->host->nr_hw_queues > 1) {
		u32 tag = blk_mq_unique_tag(scsi_cmd_to_rq(scmd));

		cmd->request_desc->SCSIIO.MSIxIndex = blk_mq_unique_tag_to_hwq(tag) +
			instance->low_latency_index_start;
	} else {
		cmd->request_desc->SCSIIO.MSIxIndex =
			instance->reply_map[raw_smp_processor_id()];
	}
}

/**
 * megasas_free_cmds_fusion -	Free all the cmds in the free cmd pool
 * @instance:		Adapter soft state
 */
void
megasas_free_cmds_fusion(struct megasas_instance *instance)
{
	int i;
	struct fusion_context *fusion = instance->ctrl_context;
	struct megasas_cmd_fusion *cmd;

	if (fusion->sense)
		dma_pool_free(fusion->sense_dma_pool, fusion->sense,
			      fusion->sense_phys_addr);

	/* SG */
	if (fusion->cmd_list) {
		for (i = 0; i < instance->max_mpt_cmds; i++) {
			cmd = fusion->cmd_list[i];
			if (cmd) {
				if (cmd->sg_frame)
					dma_pool_free(fusion->sg_dma_pool,
						      cmd->sg_frame,
						      cmd->sg_frame_phys_addr);
			}
			kfree(cmd);
		}
		kfree(fusion->cmd_list);
	}

	if (fusion->sg_dma_pool) {
		dma_pool_destroy(fusion->sg_dma_pool);
		fusion->sg_dma_pool = NULL;
	}
	if (fusion->sense_dma_pool) {
		dma_pool_destroy(fusion->sense_dma_pool);
		fusion->sense_dma_pool = NULL;
	}

Annotation

Implementation Notes