Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 71a91ca4 authored by Raghava Aditya Renukunta's avatar Raghava Aditya Renukunta Committed by Martin K. Petersen
Browse files

scsi: aacraid: Retrieve Queue Depth from Adapter FW



Retrieved queue depth from fw and saved it for future use.
Only applicable for HBA1000 drives.

Signed-off-by: default avatarRaghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: default avatarDave Carroll <David.Carroll@microsemi.com>
Reviewed-by: default avatarJohannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 3d77d840
Loading
Loading
Loading
Loading
+77 −1
Original line number Diff line number Diff line
@@ -1516,6 +1516,77 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
	return aac_scsi_32(fib, cmd);
}

int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target)
{
	struct fib *fibptr;
	struct aac_srb *srbcmd;
	struct sgmap64 *sg64;
	struct aac_ciss_identify_pd *identify_resp;
	dma_addr_t addr;
	u32 vbus, vid;
	u16 fibsize, datasize;
	int rcode = -ENOMEM;

	fibptr = aac_fib_alloc(dev);
	if (!fibptr)
		goto out;

	fibsize = sizeof(struct aac_srb) -
			sizeof(struct sgentry) + sizeof(struct sgentry64);
	datasize = sizeof(struct aac_ciss_identify_pd);

	identify_resp =  pci_alloc_consistent(dev->pdev, datasize, &addr);

	if (!identify_resp)
		goto fib_free_ptr;

	vbus = (u32)le16_to_cpu(dev->supplement_adapter_info.VirtDeviceBus);
	vid = (u32)le16_to_cpu(dev->supplement_adapter_info.VirtDeviceTarget);

	aac_fib_init(fibptr);

	srbcmd = (struct aac_srb *) fib_data(fibptr);
	srbcmd->function = cpu_to_le32(SRBF_ExecuteScsi);
	srbcmd->channel  = cpu_to_le32(vbus);
	srbcmd->id       = cpu_to_le32(vid);
	srbcmd->lun      = 0;
	srbcmd->flags    = cpu_to_le32(SRB_DataIn);
	srbcmd->timeout  = cpu_to_le32(10);
	srbcmd->retry_limit = 0;
	srbcmd->cdb_size = cpu_to_le32(12);
	srbcmd->count = cpu_to_le32(datasize);

	memset(srbcmd->cdb, 0, sizeof(srbcmd->cdb));
	srbcmd->cdb[0] = 0x26;
	srbcmd->cdb[2] = (u8)((AAC_MAX_LUN + target) & 0x00FF);
	srbcmd->cdb[6] = CISS_IDENTIFY_PHYSICAL_DEVICE;

	sg64 = (struct sgmap64 *)&srbcmd->sg;
	sg64->count = cpu_to_le32(1);
	sg64->sg[0].addr[1] = cpu_to_le32((u32)(((addr) >> 16) >> 16));
	sg64->sg[0].addr[0] = cpu_to_le32((u32)(addr & 0xffffffff));
	sg64->sg[0].count = cpu_to_le32(datasize);

	rcode = aac_fib_send(ScsiPortCommand64,
		fibptr, fibsize, FsaNormal, 1, 1, NULL, NULL);

	if (identify_resp->current_queue_depth_limit <= 0 ||
		identify_resp->current_queue_depth_limit > 32)
		dev->hba_map[bus][target].qd_limit = 32;
	else
		dev->hba_map[bus][target].qd_limit =
			identify_resp->current_queue_depth_limit;

	pci_free_consistent(dev->pdev, datasize, (void *)identify_resp, addr);

	aac_fib_complete(fibptr);

fib_free_ptr:
	aac_fib_free(fibptr);
out:
	return rcode;
}

/**
 *	aac_update hba_map()-	update current hba map with data from FW
 *	@dev:	aac_dev structure
@@ -1565,6 +1636,9 @@ void aac_update_hba_map(struct aac_dev *dev,
		if (devtype != AAC_DEVTYPE_NATIVE_RAW)
			goto update_devtype;

		if (aac_issue_bmic_identify(dev, bus, target) < 0)
			dev->hba_map[bus][target].qd_limit = 32;

update_devtype:
		dev->hba_map[bus][target].devtype = devtype;
	}
@@ -1711,8 +1785,10 @@ int aac_get_adapter_info(struct aac_dev* dev)

	/* reset all previous mapped devices (i.e. for init. after IOP_RESET) */
	for (bus = 0; bus < AAC_MAX_BUSES; bus++) {
		for (target = 0; target < AAC_MAX_TARGETS; target++)
		for (target = 0; target < AAC_MAX_TARGETS; target++) {
			dev->hba_map[bus][target].devtype = 0;
			dev->hba_map[bus][target].qd_limit = 0;
		}
	}

	/*
+80 −1
Original line number Diff line number Diff line
@@ -74,7 +74,7 @@ enum {
#define AAC_NUM_IO_FIB		(1024 - AAC_NUM_MGT_FIB)
#define AAC_NUM_FIB		(AAC_NUM_IO_FIB + AAC_NUM_MGT_FIB)

#define AAC_MAX_LUN		(8)
#define AAC_MAX_LUN		(256)

#define AAC_MAX_HOSTPHYSMEMPAGES (0xfffff)
#define AAC_MAX_32BIT_SGBCOUNT	((unsigned short)256)
@@ -89,6 +89,7 @@ enum {

#define CISS_REPORT_PHYSICAL_LUNS	0xc3
#define WRITE_HOST_WELLNESS		0xa5
#define CISS_IDENTIFY_PHYSICAL_DEVICE	0x15
#define BMIC_IN			0x26
#define BMIC_OUT			0x27

@@ -110,6 +111,82 @@ struct aac_ciss_phys_luns_resp {
 */
#define AAC_MAX_HRRQ		64

struct aac_ciss_identify_pd {
	u8 scsi_bus;			/* SCSI Bus number on controller */
	u8 scsi_id;			/* SCSI ID on this bus */
	u16 block_size;			/* sector size in bytes */
	u32 total_blocks;		/* number for sectors on drive */
	u32 reserved_blocks;		/* controller reserved (RIS) */
	u8 model[40];			/* Physical Drive Model */
	u8 serial_number[40];		/* Drive Serial Number */
	u8 firmware_revision[8];	/* drive firmware revision */
	u8 scsi_inquiry_bits;		/* inquiry byte 7 bits */
	u8 compaq_drive_stamp;		/* 0 means drive not stamped */
	u8 last_failure_reason;

	u8  flags;
	u8  more_flags;
	u8  scsi_lun;			/* SCSI LUN for phys drive */
	u8  yet_more_flags;
	u8  even_more_flags;
	u32 spi_speed_rules;		/* SPI Speed :Ultra disable diagnose */
	u8  phys_connector[2];		/* connector number on controller */
	u8  phys_box_on_bus;		/* phys enclosure this drive resides */
	u8  phys_bay_in_box;		/* phys drv bay this drive resides */
	u32 rpm;			/* Drive rotational speed in rpm */
	u8  device_type;		/* type of drive */
	u8  sata_version;		/* only valid when drive_type is SATA */
	u64 big_total_block_count;
	u64 ris_starting_lba;
	u32 ris_size;
	u8  wwid[20];
	u8  controller_phy_map[32];
	u16 phy_count;
	u8  phy_connected_dev_type[256];
	u8  phy_to_drive_bay_num[256];
	u16 phy_to_attached_dev_index[256];
	u8  box_index;
	u8  spitfire_support;
	u16 extra_physical_drive_flags;
	u8  negotiated_link_rate[256];
	u8  phy_to_phy_map[256];
	u8  redundant_path_present_map;
	u8  redundant_path_failure_map;
	u8  active_path_number;
	u16 alternate_paths_phys_connector[8];
	u8  alternate_paths_phys_box_on_port[8];
	u8  multi_lun_device_lun_count;
	u8  minimum_good_fw_revision[8];
	u8  unique_inquiry_bytes[20];
	u8  current_temperature_degreesC;
	u8  temperature_threshold_degreesC;
	u8  max_temperature_degreesC;
	u8  logical_blocks_per_phys_block_exp;	/* phyblocksize = 512 * 2^exp */
	u16 current_queue_depth_limit;
	u8  switch_name[10];
	u16 switch_port;
	u8  alternate_paths_switch_name[40];
	u8  alternate_paths_switch_port[8];
	u16 power_on_hours;		/* valid only if gas gauge supported */
	u16 percent_endurance_used;	/* valid only if gas gauge supported. */
	u8  drive_authentication;
	u8  smart_carrier_authentication;
	u8  smart_carrier_app_fw_version;
	u8  smart_carrier_bootloader_fw_version;
	u8  SanitizeSecureEraseSupport;
	u8  DriveKeyFlags;
	u8  encryption_key_name[64];
	u32 misc_drive_flags;
	u16 dek_index;
	u16 drive_encryption_flags;
	u8  sanitize_maximum_time[6];
	u8  connector_info_mode;
	u8  connector_info_number[4];
	u8  long_connector_name[64];
	u8  device_unique_identifier[16];
	u8  padto_2K[17];
} __packed;

/*
 * These macros convert from physical channels to virtual channels
 */
@@ -1032,6 +1109,7 @@ struct aac_hba_map_info {
	u8		devtype;	/* device type */
	u8		reset_state;	/* 0 - no reset, 1..x - */
					/* after xth TM LUN reset */
	u16		qd_limit;
	u8		expose;		/*checks if to expose or not*/
};

@@ -2240,6 +2318,7 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor)
int aac_acquire_irq(struct aac_dev *dev);
void aac_free_irq(struct aac_dev *dev);
int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr);
int aac_issue_bmic_identify(struct aac_dev *dev, u32 bus, u32 target);
const char *aac_driverinfo(struct Scsi_Host *);
void aac_fib_vector_assign(struct aac_dev *dev);
struct fib *aac_fib_alloc(struct aac_dev *dev);