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

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

scsi: aacraid: Retrieve and update the device types



This patch adds support to retrieve the type of each adapter connected
device. Applicable to HBA1000 and SmartIOC2000 products

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 d503e2fd
Loading
Loading
Loading
Loading
+143 −1
Original line number Diff line number Diff line
@@ -1509,11 +1509,141 @@ static int aac_scsi_32_64(struct fib * fib, struct scsi_cmnd * cmd)
	return aac_scsi_32(fib, cmd);
}

/**
 *	aac_update hba_map()-	update current hba map with data from FW
 *	@dev:	aac_dev structure
 *	@phys_luns: FW information from report phys luns
 *
 *	Update our hba map with the information gathered from the FW
 */
void aac_update_hba_map(struct aac_dev *dev,
		struct aac_ciss_phys_luns_resp *phys_luns)
{
	/* ok and extended reporting */
	u32 lun_count, nexus;
	u32 i, bus, target;
	u8 expose_flag, attribs;
	u8 devtype;

	lun_count = ((phys_luns->list_length[0] << 24)
			+ (phys_luns->list_length[1] << 16)
			+ (phys_luns->list_length[2] << 8)
			+ (phys_luns->list_length[3])) / 24;

	for (i = 0; i < lun_count; ++i) {

		bus = phys_luns->lun[i].level2[1] & 0x3f;
		target = phys_luns->lun[i].level2[0];
		expose_flag = phys_luns->lun[i].bus >> 6;
		attribs = phys_luns->lun[i].node_ident[9];
		nexus = *((u32 *) &phys_luns->lun[i].node_ident[12]);

		if (bus >= AAC_MAX_BUSES || target >= AAC_MAX_TARGETS)
			continue;

		dev->hba_map[bus][target].expose = expose_flag;

		if (expose_flag != 0) {
			devtype = AAC_DEVTYPE_RAID_MEMBER;
			goto update_devtype;
		}

		if (nexus != 0 && (attribs & 8)) {
			devtype = AAC_DEVTYPE_NATIVE_RAW;
			dev->hba_map[bus][target].rmw_nexus =
					nexus;
		} else
			devtype = AAC_DEVTYPE_ARC_RAW;

		if (devtype != AAC_DEVTYPE_NATIVE_RAW)
			goto update_devtype;

update_devtype:
		dev->hba_map[bus][target].devtype = devtype;
	}
}

/**
 *	aac_report_phys_luns()	Process topology change
 *	@dev:		aac_dev structure
 *	@fibptr:	fib pointer
 *
 *	Execute a CISS REPORT PHYS LUNS and process the results into
 *	the current hba_map.
 */
int aac_report_phys_luns(struct aac_dev *dev, struct fib *fibptr)
{
	int fibsize, datasize;
	struct aac_ciss_phys_luns_resp *phys_luns;
	struct aac_srb *srbcmd;
	struct sgmap64 *sg64;
	dma_addr_t addr;
	u32 vbus, vid;
	u32 rcode = 0;

	/* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */
	fibsize = sizeof(struct aac_srb) - sizeof(struct sgentry)
			+ sizeof(struct sgentry64);
	datasize = sizeof(struct aac_ciss_phys_luns_resp)
			+ (AAC_MAX_TARGETS - 1) * sizeof(struct _ciss_lun);

	phys_luns = (struct aac_ciss_phys_luns_resp *) pci_alloc_consistent(
			dev->pdev, datasize, &addr);

	if (phys_luns == NULL) {
		rcode = -ENOMEM;
		goto err_out;
	}

	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] = CISS_REPORT_PHYSICAL_LUNS;
	srbcmd->cdb[1] = 2; /* extended reporting */
	srbcmd->cdb[8] = (u8)(datasize >> 8);
	srbcmd->cdb[9] = (u8)(datasize);

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

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

	/* analyse data */
	if (rcode >= 0 && phys_luns->resp_flag == 2) {
		/* ok and extended reporting */
		aac_update_hba_map(dev, phys_luns);
	}

	pci_free_consistent(dev->pdev, datasize, (void *) phys_luns, addr);
err_out:
	return rcode;
}

int aac_get_adapter_info(struct aac_dev* dev)
{
	struct fib* fibptr;
	int rcode;
	u32 tmp;
	u32 tmp, bus, target;
	struct aac_adapter_info *info;
	struct aac_bus_info *command;
	struct aac_bus_info_response *bus_info;
@@ -1544,6 +1674,7 @@ int aac_get_adapter_info(struct aac_dev* dev)
	}
	memcpy(&dev->adapter_info, info, sizeof(*info));

	dev->supplement_adapter_info.VirtDeviceBus = 0xffff;
	if (dev->adapter_info.options & AAC_OPT_SUPPLEMENT_ADAPTER_INFO) {
		struct aac_supplement_adapter_info * sinfo;

@@ -1571,6 +1702,11 @@ 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++)
			dev->hba_map[bus][target].devtype = 0;
	}

	/*
	 * GetBusInfo
@@ -1603,6 +1739,12 @@ int aac_get_adapter_info(struct aac_dev* dev)
		dev->maximum_num_channels = le32_to_cpu(bus_info->BusCount);
	}

	if (!dev->sync_mode && dev->sa_firmware &&
			dev->supplement_adapter_info.VirtDeviceBus != 0xffff) {
		/* Thor SA Firmware -> CISS_REPORT_PHYSICAL_LUNS */
		rcode = aac_report_phys_luns(dev, fibptr);
	}

	if (!dev->in_reset) {
		char buffer[16];
		tmp = le32_to_cpu(dev->adapter_info.kernelrev);
+59 −1
Original line number Diff line number Diff line
@@ -81,6 +81,27 @@ enum {

#define AAC_DEBUG_INSTRUMENT_AIF_DELETE

#define AAC_MAX_NATIVE_TARGETS		1024
/* Thor: 5 phys. buses: #0: empty, 1-4: 256 targets each */
#define AAC_MAX_BUSES			5
#define AAC_MAX_TARGETS		256
#define AAC_MAX_NATIVE_SIZE		2048

#define CISS_REPORT_PHYSICAL_LUNS	0xc3

struct aac_ciss_phys_luns_resp {
	u8	list_length[4];		/* LUN list length (N-7, big endian) */
	u8	resp_flag;		/* extended response_flag */
	u8	reserved[3];
	struct _ciss_lun {
		u8	tid[3];		/* Target ID */
		u8	bus;		/* Bus, flag (bits 6,7) */
		u8	level3[2];
		u8	level2[2];
		u8	node_ident[16];	/* phys. node identifier */
	} lun[1];			/* List of phys. devices */
};

/*
 * Interrupts
 */
@@ -993,6 +1014,20 @@ struct fib {
	dma_addr_t		hw_fib_pa;		/* physical address of hw_fib*/
};

#define AAC_DEVTYPE_RAID_MEMBER	1
#define AAC_DEVTYPE_ARC_RAW		2
#define AAC_DEVTYPE_NATIVE_RAW		3
#define AAC_EXPOSE_DISK		0
#define AAC_HIDE_DISK			3

struct aac_hba_map_info {
	__le32	rmw_nexus;		/* nexus for native HBA devices */
	u8		devtype;	/* device type */
	u8		reset_state;	/* 0 - no reset, 1..x - */
					/* after xth TM LUN reset */
	u8		expose;		/*checks if to expose or not*/
};

/*
 *	Adapter Information Block
 *
@@ -1056,7 +1091,28 @@ struct aac_supplement_adapter_info
	/* StructExpansion == 1 */
	__le32	FeatureBits3;
	__le32	SupportedPerformanceModes;
	__le32	ReservedForFutureGrowth[80];
	u8	HostBusType;		/* uses HOST_BUS_TYPE_xxx defines */
	u8	HostBusWidth;		/* actual width in bits or links */
	u16	HostBusSpeed;		/* actual bus speed/link rate in MHz */
	u8	MaxRRCDrives;		/* max. number of ITP-RRC drives/pool */
	u8	MaxDiskXtasks;		/* max. possible num of DiskX Tasks */

	u8	CpldVerLoaded;
	u8	CpldVerInFlash;

	__le64	MaxRRCCapacity;
	__le32	CompiledMaxHistLogLevel;
	u8	CustomBoardName[12];
	u16	SupportedCntlrMode;	/* identify supported controller mode */
	u16	ReservedForFuture16;
	__le32	SupportedOptions3;	/* reserved for future options */

	__le16	VirtDeviceBus;		/* virt. SCSI device for Thor */
	__le16	VirtDeviceTarget;
	__le16	VirtDeviceLUN;
	__le16	Unused;
	__le32	ReservedForFutureGrowth[68];

};
#define AAC_FEATURE_FALCON	cpu_to_le32(0x00000010)
#define AAC_FEATURE_JBOD	cpu_to_le32(0x08000000)
@@ -1287,6 +1343,7 @@ struct aac_dev
	u32			vector_cap;	/* MSI-X vector capab.*/
	int			msi_enabled;	/* MSI/MSI-X enabled */
	struct aac_msix_ctx	aac_msix[AAC_MAX_MSIX]; /* context */
	struct aac_hba_map_info	hba_map[AAC_MAX_BUSES][AAC_MAX_TARGETS];
	u8			adapter_shutdown;
	u32			handle_pci_error;
};
@@ -2171,6 +2228,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);
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);