Skip to content

Commit

Permalink
scsi: aacraid: Retrieve and update the device types
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Raghava Aditya Renukunta authored and Martin K. Petersen committed Feb 3, 2017
1 parent d503e2f commit c83b11e
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 2 deletions.
144 changes: 143 additions & 1 deletion drivers/scsi/aacraid/aachba.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
60 changes: 59 additions & 1 deletion drivers/scsi/aacraid/aacraid.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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
*
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
};
Expand Down Expand Up @@ -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);
Expand Down

0 comments on commit c83b11e

Please sign in to comment.