📄 mptsas.c
字号:
return 1;}static int mptsas_phy_reset(struct sas_phy *phy, int hard_reset){ MPT_ADAPTER *ioc = phy_to_ioc(phy); SasIoUnitControlRequest_t *req; SasIoUnitControlReply_t *reply; MPT_FRAME_HDR *mf; MPIHeader_t *hdr; unsigned long timeleft; int error = -ERESTARTSYS; /* not implemented for expanders */ if (phy->identify.target_port_protocols & SAS_PROTOCOL_SMP) return -ENXIO; if (mutex_lock_interruptible(&ioc->sas_mgmt.mutex)) goto out; mf = mpt_get_msg_frame(mptsasMgmtCtx, ioc); if (!mf) { error = -ENOMEM; goto out_unlock; } hdr = (MPIHeader_t *) mf; req = (SasIoUnitControlRequest_t *)mf; memset(req, 0, sizeof(SasIoUnitControlRequest_t)); req->Function = MPI_FUNCTION_SAS_IO_UNIT_CONTROL; req->MsgContext = hdr->MsgContext; req->Operation = hard_reset ? MPI_SAS_OP_PHY_HARD_RESET : MPI_SAS_OP_PHY_LINK_RESET; req->PhyNum = phy->identify.phy_identifier; mpt_put_msg_frame(mptsasMgmtCtx, ioc, mf); timeleft = wait_for_completion_timeout(&ioc->sas_mgmt.done, 10 * HZ); if (!timeleft) { /* On timeout reset the board */ mpt_free_msg_frame(ioc, mf); mpt_HardResetHandler(ioc, CAN_SLEEP); error = -ETIMEDOUT; goto out_unlock; } /* a reply frame is expected */ if ((ioc->sas_mgmt.status & MPT_IOCTL_STATUS_RF_VALID) == 0) { error = -ENXIO; goto out_unlock; } /* process the completed Reply Message Frame */ reply = (SasIoUnitControlReply_t *)ioc->sas_mgmt.reply; if (reply->IOCStatus != MPI_IOCSTATUS_SUCCESS) { printk("%s: IOCStatus=0x%X IOCLogInfo=0x%X\n", __FUNCTION__, reply->IOCStatus, reply->IOCLogInfo); error = -ENXIO; goto out_unlock; } error = 0; out_unlock: mutex_unlock(&ioc->sas_mgmt.mutex); out: return error;}static struct sas_function_template mptsas_transport_functions = { .get_linkerrors = mptsas_get_linkerrors, .phy_reset = mptsas_phy_reset,};static struct scsi_transport_template *mptsas_transport_template;static intmptsas_sas_io_unit_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info){ ConfigExtendedPageHeader_t hdr; CONFIGPARMS cfg; SasIOUnitPage0_t *buffer; dma_addr_t dma_handle; int error, i; hdr.PageVersion = MPI_SASIOUNITPAGE0_PAGEVERSION; hdr.ExtPageLength = 0; hdr.PageNumber = 0; hdr.Reserved1 = 0; hdr.Reserved2 = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_IO_UNIT; cfg.cfghdr.ehdr = &hdr; cfg.physAddr = -1; cfg.pageAddr = 0; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; /* read */ cfg.timeout = 10; error = mpt_config(ioc, &cfg); if (error) goto out; if (!hdr.ExtPageLength) { error = -ENXIO; goto out; } buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, &dma_handle); if (!buffer) { error = -ENOMEM; goto out; } cfg.physAddr = dma_handle; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; error = mpt_config(ioc, &cfg); if (error) goto out_free_consistent; port_info->num_phys = buffer->NumPhys; port_info->phy_info = kcalloc(port_info->num_phys, sizeof(struct mptsas_phyinfo),GFP_KERNEL); if (!port_info->phy_info) { error = -ENOMEM; goto out_free_consistent; } for (i = 0; i < port_info->num_phys; i++) { mptsas_print_phy_data(&buffer->PhyData[i]); port_info->phy_info[i].phy_id = i; port_info->phy_info[i].port_id = buffer->PhyData[i].Port; port_info->phy_info[i].negotiated_link_rate = buffer->PhyData[i].NegotiatedLinkRate; } out_free_consistent: pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, buffer, dma_handle); out: return error;}static intmptsas_sas_phy_pg0(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, u32 form, u32 form_specific){ ConfigExtendedPageHeader_t hdr; CONFIGPARMS cfg; SasPhyPage0_t *buffer; dma_addr_t dma_handle; int error; hdr.PageVersion = MPI_SASPHY0_PAGEVERSION; hdr.ExtPageLength = 0; hdr.PageNumber = 0; hdr.Reserved1 = 0; hdr.Reserved2 = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_PHY; cfg.cfghdr.ehdr = &hdr; cfg.dir = 0; /* read */ cfg.timeout = 10; /* Get Phy Pg 0 for each Phy. */ cfg.physAddr = -1; cfg.pageAddr = form + form_specific; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; error = mpt_config(ioc, &cfg); if (error) goto out; if (!hdr.ExtPageLength) { error = -ENXIO; goto out; } buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, &dma_handle); if (!buffer) { error = -ENOMEM; goto out; } cfg.physAddr = dma_handle; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; error = mpt_config(ioc, &cfg); if (error) goto out_free_consistent; mptsas_print_phy_pg0(buffer); phy_info->hw_link_rate = buffer->HwLinkRate; phy_info->programmed_link_rate = buffer->ProgrammedLinkRate; phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle); phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle); out_free_consistent: pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, buffer, dma_handle); out: return error;}static intmptsas_sas_device_pg0(MPT_ADAPTER *ioc, struct mptsas_devinfo *device_info, u32 form, u32 form_specific){ ConfigExtendedPageHeader_t hdr; CONFIGPARMS cfg; SasDevicePage0_t *buffer; dma_addr_t dma_handle; __le64 sas_address; int error; hdr.PageVersion = MPI_SASDEVICE0_PAGEVERSION; hdr.ExtPageLength = 0; hdr.PageNumber = 0; hdr.Reserved1 = 0; hdr.Reserved2 = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_DEVICE; cfg.cfghdr.ehdr = &hdr; cfg.pageAddr = form + form_specific; cfg.physAddr = -1; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; /* read */ cfg.timeout = 10; error = mpt_config(ioc, &cfg); if (error) goto out; if (!hdr.ExtPageLength) { error = -ENXIO; goto out; } buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, &dma_handle); if (!buffer) { error = -ENOMEM; goto out; } cfg.physAddr = dma_handle; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; error = mpt_config(ioc, &cfg); if (error) goto out_free_consistent; mptsas_print_device_pg0(buffer); device_info->handle = le16_to_cpu(buffer->DevHandle); device_info->handle_parent = le16_to_cpu(buffer->ParentDevHandle); device_info->phy_id = buffer->PhyNum; device_info->port_id = buffer->PhysicalPort; device_info->id = buffer->TargetID; device_info->channel = buffer->Bus; memcpy(&sas_address, &buffer->SASAddress, sizeof(__le64)); device_info->sas_address = le64_to_cpu(sas_address); device_info->device_info = le32_to_cpu(buffer->DeviceInfo); out_free_consistent: pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, buffer, dma_handle); out: return error;}static intmptsas_sas_expander_pg0(MPT_ADAPTER *ioc, struct mptsas_portinfo *port_info, u32 form, u32 form_specific){ ConfigExtendedPageHeader_t hdr; CONFIGPARMS cfg; SasExpanderPage0_t *buffer; dma_addr_t dma_handle; int error; hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; hdr.ExtPageLength = 0; hdr.PageNumber = 0; hdr.Reserved1 = 0; hdr.Reserved2 = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER; cfg.cfghdr.ehdr = &hdr; cfg.physAddr = -1; cfg.pageAddr = form + form_specific; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; /* read */ cfg.timeout = 10; error = mpt_config(ioc, &cfg); if (error) goto out; if (!hdr.ExtPageLength) { error = -ENXIO; goto out; } buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, &dma_handle); if (!buffer) { error = -ENOMEM; goto out; } cfg.physAddr = dma_handle; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; error = mpt_config(ioc, &cfg); if (error) goto out_free_consistent; /* save config data */ port_info->num_phys = buffer->NumPhys; port_info->handle = le16_to_cpu(buffer->DevHandle); port_info->phy_info = kcalloc(port_info->num_phys, sizeof(struct mptsas_phyinfo),GFP_KERNEL); if (!port_info->phy_info) { error = -ENOMEM; goto out_free_consistent; } out_free_consistent: pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, buffer, dma_handle); out: return error;}static intmptsas_sas_expander_pg1(MPT_ADAPTER *ioc, struct mptsas_phyinfo *phy_info, u32 form, u32 form_specific){ ConfigExtendedPageHeader_t hdr; CONFIGPARMS cfg; SasExpanderPage1_t *buffer; dma_addr_t dma_handle; int error; hdr.PageVersion = MPI_SASEXPANDER0_PAGEVERSION; hdr.ExtPageLength = 0; hdr.PageNumber = 1; hdr.Reserved1 = 0; hdr.Reserved2 = 0; hdr.PageType = MPI_CONFIG_PAGETYPE_EXTENDED; hdr.ExtPageType = MPI_CONFIG_EXTPAGETYPE_SAS_EXPANDER; cfg.cfghdr.ehdr = &hdr; cfg.physAddr = -1; cfg.pageAddr = form + form_specific; cfg.action = MPI_CONFIG_ACTION_PAGE_HEADER; cfg.dir = 0; /* read */ cfg.timeout = 10; error = mpt_config(ioc, &cfg); if (error) goto out; if (!hdr.ExtPageLength) { error = -ENXIO; goto out; } buffer = pci_alloc_consistent(ioc->pcidev, hdr.ExtPageLength * 4, &dma_handle); if (!buffer) { error = -ENOMEM; goto out; } cfg.physAddr = dma_handle; cfg.action = MPI_CONFIG_ACTION_PAGE_READ_CURRENT; error = mpt_config(ioc, &cfg); if (error) goto out_free_consistent; mptsas_print_expander_pg1(buffer); /* save config data */ phy_info->phy_id = buffer->PhyIdentifier; phy_info->port_id = buffer->PhysicalPort; phy_info->negotiated_link_rate = buffer->NegotiatedLinkRate; phy_info->programmed_link_rate = buffer->ProgrammedLinkRate; phy_info->hw_link_rate = buffer->HwLinkRate; phy_info->identify.handle = le16_to_cpu(buffer->OwnerDevHandle); phy_info->attached.handle = le16_to_cpu(buffer->AttachedDevHandle); out_free_consistent: pci_free_consistent(ioc->pcidev, hdr.ExtPageLength * 4, buffer, dma_handle); out: return error;}/* * Returns true if there is a scsi end device */static inline intmptsas_is_end_device(struct mptsas_devinfo * attached){ if ((attached->handle) && (attached->device_info & MPI_SAS_DEVICE_INFO_END_DEVICE) && ((attached->device_info & MPI_SAS_DEVICE_INFO_SSP_TARGET) | (attached->device_info & MPI_SAS_DEVICE_INFO_STP_TARGET) | (attached->device_info & MPI_SAS_DEVICE_INFO_SATA_DEVICE))) return 1; else return 0;}static voidmptsas_parse_device_info(struct sas_identify *identify, struct mptsas_devinfo *device_info){ u16 protocols; identify->sas_address = device_info->sas_address; identify->phy_identifier = device_info->phy_id; /* * Fill in Phy Initiator Port Protocol. * Bits 6:3, more than one bit can be set, fall through cases. */ protocols = device_info->device_info & 0x78; identify->initiator_port_protocols = 0; if (protocols & MPI_SAS_DEVICE_INFO_SSP_INITIATOR) identify->initiator_port_protocols |= SAS_PROTOCOL_SSP; if (protocols & MPI_SAS_DEVICE_INFO_STP_INITIATOR) identify->initiator_port_protocols |= SAS_PROTOCOL_STP; if (protocols & MPI_SAS_DEVICE_INFO_SMP_INITIATOR) identify->initiator_port_protocols |= SAS_PROTOCOL_SMP; if (protocols & MPI_SAS_DEVICE_INFO_SATA_HOST) identify->initiator_port_protocols |= SAS_PROTOCOL_SATA; /* * Fill in Phy Target Port Protocol. * Bits 10:7, more than one bit can be set, fall through cases. */ protocols = device_info->device_info & 0x780; identify->target_port_protocols = 0; if (protocols & MPI_SAS_DEVICE_INFO_SSP_TARGET) identify->target_port_protocols |= SAS_PROTOCOL_SSP; if (protocols & MPI_SAS_DEVICE_INFO_STP_TARGET) identify->target_port_protocols |= SAS_PROTOCOL_STP; if (protocols & MPI_SAS_DEVICE_INFO_SMP_TARGET) identify->target_port_protocols |= SAS_PROTOCOL_SMP; if (protocols & MPI_SAS_DEVICE_INFO_SATA_DEVICE) identify->target_port_protocols |= SAS_PROTOCOL_SATA; /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -