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: Raghava Aditya Renukunta <RaghavaAditya.Renukunta@microsemi.com>
Signed-off-by: Dave Carroll <David.Carroll@microsemi.com>
Reviewed-by: Johannes Thumshirn <jthumshirn@suse.de>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
This commit is contained in:
Raghava Aditya Renukunta 2017-02-02 15:53:19 -08:00 committed by Martin K. Petersen
parent d503e2fde2
commit c83b11e31c
2 changed files with 202 additions and 2 deletions

View file

@ -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);

View file

@ -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);