forked from Minki/linux
[SCSI] mptfusion: Added sysfs expander manufacture information at the time of expander add.
Added new function mptsas_exp_manufacture_info, which will obtain the REPORT_MANUFACTURING, and fill the details into the sas_expander_device object when the expander port is created. Signed-off-by: Kashyap Desai <kashyap.desai@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@suse.de>
This commit is contained in:
parent
65f89c2396
commit
e0f553ab58
@ -2686,6 +2686,187 @@ mptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info,
|
||||
return error;
|
||||
}
|
||||
|
||||
struct rep_manu_request{
|
||||
u8 smp_frame_type;
|
||||
u8 function;
|
||||
u8 reserved;
|
||||
u8 request_length;
|
||||
};
|
||||
|
||||
struct rep_manu_reply{
|
||||
u8 smp_frame_type; /* 0x41 */
|
||||
u8 function; /* 0x01 */
|
||||
u8 function_result;
|
||||
u8 response_length;
|
||||
u16 expander_change_count;
|
||||
u8 reserved0[2];
|
||||
u8 sas_format:1;
|
||||
u8 reserved1:7;
|
||||
u8 reserved2[3];
|
||||
u8 vendor_id[SAS_EXPANDER_VENDOR_ID_LEN];
|
||||
u8 product_id[SAS_EXPANDER_PRODUCT_ID_LEN];
|
||||
u8 product_rev[SAS_EXPANDER_PRODUCT_REV_LEN];
|
||||
u8 component_vendor_id[SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN];
|
||||
u16 component_id;
|
||||
u8 component_revision_id;
|
||||
u8 reserved3;
|
||||
u8 vendor_specific[8];
|
||||
};
|
||||
|
||||
/**
|
||||
* mptsas_exp_repmanufacture_info -
|
||||
* @ioc: per adapter object
|
||||
* @sas_address: expander sas address
|
||||
* @edev: the sas_expander_device object
|
||||
*
|
||||
* Fills in the sas_expander_device object when SMP port is created.
|
||||
*
|
||||
* Returns 0 for success, non-zero for failure.
|
||||
*/
|
||||
static int
|
||||
mptsas_exp_repmanufacture_info(MPT_ADAPTER *ioc,
|
||||
u64 sas_address, struct sas_expander_device *edev)
|
||||
{
|
||||
MPT_FRAME_HDR *mf;
|
||||
SmpPassthroughRequest_t *smpreq;
|
||||
SmpPassthroughReply_t *smprep;
|
||||
struct rep_manu_reply *manufacture_reply;
|
||||
struct rep_manu_request *manufacture_request;
|
||||
int ret;
|
||||
int flagsLength;
|
||||
unsigned long timeleft;
|
||||
char *psge;
|
||||
unsigned long flags;
|
||||
void *data_out = NULL;
|
||||
dma_addr_t data_out_dma = 0;
|
||||
u32 sz;
|
||||
|
||||
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
|
||||
if (ioc->ioc_reset_in_progress) {
|
||||
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
|
||||
printk(MYIOC_s_INFO_FMT "%s: host reset in progress!\n",
|
||||
__func__, ioc->name);
|
||||
return -EFAULT;
|
||||
}
|
||||
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
|
||||
|
||||
ret = mutex_lock_interruptible(&ioc->sas_mgmt.mutex);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc);
|
||||
if (!mf) {
|
||||
ret = -ENOMEM;
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
smpreq = (SmpPassthroughRequest_t *)mf;
|
||||
memset(smpreq, 0, sizeof(*smpreq));
|
||||
|
||||
sz = sizeof(struct rep_manu_request) + sizeof(struct rep_manu_reply);
|
||||
|
||||
data_out = pci_alloc_consistent(ioc->pcidev, sz, &data_out_dma);
|
||||
if (!data_out) {
|
||||
printk(KERN_ERR "Memory allocation failure at %s:%d/%s()!\n",
|
||||
__FILE__, __LINE__, __func__);
|
||||
ret = -ENOMEM;
|
||||
goto put_mf;
|
||||
}
|
||||
|
||||
manufacture_request = data_out;
|
||||
manufacture_request->smp_frame_type = 0x40;
|
||||
manufacture_request->function = 1;
|
||||
manufacture_request->reserved = 0;
|
||||
manufacture_request->request_length = 0;
|
||||
|
||||
smpreq->Function = MPI_FUNCTION_SMP_PASSTHROUGH;
|
||||
smpreq->PhysicalPort = 0xFF;
|
||||
*((u64 *)&smpreq->SASAddress) = cpu_to_le64(sas_address);
|
||||
smpreq->RequestDataLength = sizeof(struct rep_manu_request);
|
||||
|
||||
psge = (char *)
|
||||
(((int *) mf) + (offsetof(SmpPassthroughRequest_t, SGL) / 4));
|
||||
|
||||
flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
|
||||
MPI_SGE_FLAGS_SYSTEM_ADDRESS |
|
||||
MPI_SGE_FLAGS_HOST_TO_IOC |
|
||||
MPI_SGE_FLAGS_END_OF_BUFFER;
|
||||
flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
|
||||
flagsLength |= sizeof(struct rep_manu_request);
|
||||
|
||||
ioc->add_sge(psge, flagsLength, data_out_dma);
|
||||
psge += ioc->SGE_size;
|
||||
|
||||
flagsLength = MPI_SGE_FLAGS_SIMPLE_ELEMENT |
|
||||
MPI_SGE_FLAGS_SYSTEM_ADDRESS |
|
||||
MPI_SGE_FLAGS_IOC_TO_HOST |
|
||||
MPI_SGE_FLAGS_END_OF_BUFFER;
|
||||
flagsLength = flagsLength << MPI_SGE_FLAGS_SHIFT;
|
||||
flagsLength |= sizeof(struct rep_manu_reply);
|
||||
ioc->add_sge(psge, flagsLength, data_out_dma +
|
||||
sizeof(struct rep_manu_request));
|
||||
|
||||
INITIALIZE_MGMT_STATUS(ioc->sas_mgmt.status)
|
||||
mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf);
|
||||
|
||||
timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ);
|
||||
if (!(ioc->sas_mgmt.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
|
||||
ret = -ETIME;
|
||||
mpt_free_msg_frame(ioc, mf);
|
||||
mf = NULL;
|
||||
if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_DID_IOCRESET)
|
||||
goto out_free;
|
||||
if (!timeleft)
|
||||
mpt_HardResetHandler(ioc, CAN_SLEEP);
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
mf = NULL;
|
||||
|
||||
if (ioc->sas_mgmt.status & MPT_MGMT_STATUS_RF_VALID) {
|
||||
u8 *tmp;
|
||||
|
||||
smprep = (SmpPassthroughReply_t *)ioc->sas_mgmt.reply;
|
||||
if (le16_to_cpu(smprep->ResponseDataLength) !=
|
||||
sizeof(struct rep_manu_reply))
|
||||
goto out_free;
|
||||
|
||||
manufacture_reply = data_out + sizeof(struct rep_manu_request);
|
||||
strncpy(edev->vendor_id, manufacture_reply->vendor_id,
|
||||
SAS_EXPANDER_VENDOR_ID_LEN);
|
||||
strncpy(edev->product_id, manufacture_reply->product_id,
|
||||
SAS_EXPANDER_PRODUCT_ID_LEN);
|
||||
strncpy(edev->product_rev, manufacture_reply->product_rev,
|
||||
SAS_EXPANDER_PRODUCT_REV_LEN);
|
||||
edev->level = manufacture_reply->sas_format;
|
||||
if (manufacture_reply->sas_format) {
|
||||
strncpy(edev->component_vendor_id,
|
||||
manufacture_reply->component_vendor_id,
|
||||
SAS_EXPANDER_COMPONENT_VENDOR_ID_LEN);
|
||||
tmp = (u8 *)&manufacture_reply->component_id;
|
||||
edev->component_id = tmp[0] << 8 | tmp[1];
|
||||
edev->component_revision_id =
|
||||
manufacture_reply->component_revision_id;
|
||||
}
|
||||
} else {
|
||||
printk(MYIOC_s_ERR_FMT
|
||||
"%s: smp passthru reply failed to be returned\n",
|
||||
ioc->name, __func__);
|
||||
ret = -ENXIO;
|
||||
}
|
||||
out_free:
|
||||
if (data_out_dma)
|
||||
pci_free_consistent(ioc->pcidev, sz, data_out, data_out_dma);
|
||||
put_mf:
|
||||
if (mf)
|
||||
mpt_free_msg_frame(ioc, mf);
|
||||
out_unlock:
|
||||
CLEAR_MGMT_STATUS(ioc->sas_mgmt.status)
|
||||
mutex_unlock(&ioc->sas_mgmt.mutex);
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void
|
||||
mptsas_parse_device_info(struct sas_identify *identify,
|
||||
struct mptsas_devinfo *device_info)
|
||||
@ -2967,6 +3148,11 @@ static int mptsas_probe_one_phy(struct device *dev,
|
||||
goto out;
|
||||
}
|
||||
mptsas_set_rphy(ioc, phy_info, rphy);
|
||||
if (identify.device_type == SAS_EDGE_EXPANDER_DEVICE ||
|
||||
identify.device_type == SAS_FANOUT_EXPANDER_DEVICE)
|
||||
mptsas_exp_repmanufacture_info(ioc,
|
||||
identify.sas_address,
|
||||
rphy_to_expander_device(rphy));
|
||||
}
|
||||
|
||||
out:
|
||||
|
Loading…
Reference in New Issue
Block a user