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:
Родитель
d503e2fde2
Коммит
c83b11e31c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче