void * mpt_read_extended_config_page(int fd, U8 ExtPageType, U8 PageVersion, U8 PageNumber, U32 PageAddress, U16 *IOCStatus) { struct mpt_ext_cfg_page_req req; void *buf; int error; if (IOCStatus != NULL) *IOCStatus = MPI_IOCSTATUS_SUCCESS; bzero(&req, sizeof(req)); req.header.PageVersion = PageVersion; req.header.PageNumber = PageNumber; req.header.ExtPageType = ExtPageType; req.page_address = PageAddress; if (ioctl(fd, MPTIO_READ_EXT_CFG_HEADER, &req) < 0) return (NULL); if (!IOC_STATUS_SUCCESS(req.ioc_status)) { if (IOCStatus != NULL) *IOCStatus = req.ioc_status; else warnx("Reading extended config page header failed: %s", mpt_ioc_status(req.ioc_status)); errno = EIO; return (NULL); } req.len = req.header.ExtPageLength * 4; buf = malloc(req.len); req.buf = buf; bcopy(&req.header, buf, sizeof(req.header)); if (ioctl(fd, MPTIO_READ_EXT_CFG_PAGE, &req) < 0) { error = errno; free(buf); errno = error; return (NULL); } if (!IOC_STATUS_SUCCESS(req.ioc_status)) { if (IOCStatus != NULL) *IOCStatus = req.ioc_status; else warnx("Reading extended config page failed: %s", mpt_ioc_status(req.ioc_status)); free(buf); errno = EIO; return (NULL); } return (buf); }
int mpt_write_config_page(int fd, void *buf, U16 *IOCStatus) { CONFIG_PAGE_HEADER *hdr; struct mpt_cfg_page_req req; if (IOCStatus != NULL) *IOCStatus = MPI_IOCSTATUS_SUCCESS; bzero(&req, sizeof(req)); req.buf = buf; hdr = buf; req.len = hdr->PageLength * 4; if (ioctl(fd, MPTIO_WRITE_CFG_PAGE, &req) < 0) return (errno); if (!IOC_STATUS_SUCCESS(req.ioc_status)) { if (IOCStatus != NULL) { *IOCStatus = req.ioc_status; return (0); } warnx("Writing config page failed: %s", mpt_ioc_status(req.ioc_status)); return (EIO); } return (0); }
int mpt_read_config_page_header(int fd, U8 PageType, U8 PageNumber, U32 PageAddress, CONFIG_PAGE_HEADER *header, U16 *IOCStatus) { struct mpt_cfg_page_req req; if (IOCStatus != NULL) *IOCStatus = MPI_IOCSTATUS_SUCCESS; bzero(&req, sizeof(req)); req.header.PageType = PageType; req.header.PageNumber = PageNumber; req.page_address = PageAddress; if (ioctl(fd, MPTIO_READ_CFG_HEADER, &req) < 0) return (errno); if (!IOC_STATUS_SUCCESS(req.ioc_status)) { if (IOCStatus != NULL) *IOCStatus = req.ioc_status; else warnx("Reading config page header failed: %s", mpt_ioc_status(req.ioc_status)); return (EIO); } *header = req.header; return (0); }
static void mpt_print_reply_hdr(MSG_DEFAULT_REPLY *msg) { printf("%s Reply @ %p\n", mpt_ioc_function(msg->Function), msg); printf("\tIOC Status %s\n", mpt_ioc_status(le16toh(msg->IOCStatus))); printf("\tIOCLogInfo 0x%08x\n", msg->IOCLogInfo); printf("\tMsgLength 0x%02x\n", msg->MsgLength); printf("\tMsgFlags 0x%02x\n", msg->MsgFlags); printf("\tMsgContext 0x%08x\n", le32toh(msg->MsgContext)); }
int mpt_raid_action(int fd, U8 Action, U8 VolumeBus, U8 VolumeID, U8 PhysDiskNum, U32 ActionDataWord, void *buf, int len, RAID_VOL0_STATUS *VolumeStatus, U32 *ActionData, int datalen, U16 *IOCStatus, U16 *ActionStatus, int write) { struct mpt_raid_action raid_act; if (IOCStatus != NULL) *IOCStatus = MPI_IOCSTATUS_SUCCESS; if (datalen < 0 || (unsigned)datalen > sizeof(raid_act.action_data)) return (EINVAL); bzero(&raid_act, sizeof(raid_act)); raid_act.action = Action; raid_act.volume_bus = VolumeBus; raid_act.volume_id = VolumeID; raid_act.phys_disk_num = PhysDiskNum; raid_act.action_data_word = ActionDataWord; if (buf != NULL && len != 0) { raid_act.buf = buf; raid_act.len = len; raid_act.write = write; } if (ioctl(fd, MPTIO_RAID_ACTION, &raid_act) < 0) return (errno); if (!IOC_STATUS_SUCCESS(raid_act.ioc_status)) { if (IOCStatus != NULL) { *IOCStatus = raid_act.ioc_status; return (0); } warnx("RAID action failed: %s", mpt_ioc_status(raid_act.ioc_status)); return (EIO); } if (ActionStatus != NULL) *ActionStatus = raid_act.action_status; if (raid_act.action_status != MPI_RAID_ACTION_ASTATUS_SUCCESS) { if (ActionStatus != NULL) return (0); warnx("RAID action failed: %s", mpt_raid_status(raid_act.action_status)); return (EIO); } if (VolumeStatus != NULL) *((U32 *)VolumeStatus) = raid_act.volume_status; if (ActionData != NULL) bcopy(raid_act.action_data, ActionData, datalen); return (0); }
static int show_physdisks(int ac, char **av) { CONFIG_PAGE_RAID_PHYS_DISK_0 *pinfo; U16 IOCStatus; int error, fd, i; if (ac != 1) { warnx("show drives: extra arguments"); return (EINVAL); } fd = mpt_open(mpt_unit); if (fd < 0) { error = errno; warn("mpt_open"); return (error); } /* Try to find each possible phys disk page. */ for (i = 0; i <= 0xff; i++) { pinfo = mpt_pd_info(fd, i, &IOCStatus); if (pinfo == NULL) { if ((IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_CONFIG_INVALID_PAGE) warnx("mpt_pd_info(%d): %s", i, mpt_ioc_status(IOCStatus)); continue; } printf("%3u ", i); print_pd(pinfo, -1, 1); printf("\n"); } close(fd); return (0); }
static int show_adapter(int ac, char **av) { CONFIG_PAGE_MANUFACTURING_0 *man0; CONFIG_PAGE_IOC_2 *ioc2; CONFIG_PAGE_IOC_6 *ioc6; U16 IOCStatus; int comma, error, fd; if (ac != 1) { warnx("show adapter: extra arguments"); return (EINVAL); } fd = mpt_open(mpt_unit); if (fd < 0) { error = errno; warn("mpt_open"); return (error); } man0 = mpt_read_man_page(fd, 0, NULL); if (man0 == NULL) { error = errno; warn("Failed to get controller info"); return (error); } if (man0->Header.PageLength < sizeof(*man0) / 4) { warnx("Invalid controller info"); return (EINVAL); } printf("mpt%d Adapter:\n", mpt_unit); printf(" Board Name: %.16s\n", man0->BoardName); printf(" Board Assembly: %.16s\n", man0->BoardAssembly); printf(" Chip Name: %.16s\n", man0->ChipName); printf(" Chip Revision: %.16s\n", man0->ChipRevision); free(man0); ioc2 = mpt_read_ioc_page(fd, 2, &IOCStatus); if (ioc2 != NULL) { printf(" RAID Levels:"); comma = 0; if (ioc2->CapabilitiesFlags & MPI_IOCPAGE2_CAP_FLAGS_IS_SUPPORT) { printf(" RAID0"); comma = 1; } if (ioc2->CapabilitiesFlags & MPI_IOCPAGE2_CAP_FLAGS_IM_SUPPORT) { printf("%s RAID1", comma ? "," : ""); comma = 1; } if (ioc2->CapabilitiesFlags & MPI_IOCPAGE2_CAP_FLAGS_IME_SUPPORT) { printf("%s RAID1E", comma ? "," : ""); comma = 1; } if (ioc2->CapabilitiesFlags & MPI_IOCPAGE2_CAP_FLAGS_RAID_5_SUPPORT) { printf("%s RAID5", comma ? "," : ""); comma = 1; } if (ioc2->CapabilitiesFlags & MPI_IOCPAGE2_CAP_FLAGS_RAID_6_SUPPORT) { printf("%s RAID6", comma ? "," : ""); comma = 1; } if (ioc2->CapabilitiesFlags & MPI_IOCPAGE2_CAP_FLAGS_RAID_10_SUPPORT) { printf("%s RAID10", comma ? "," : ""); comma = 1; } if (ioc2->CapabilitiesFlags & MPI_IOCPAGE2_CAP_FLAGS_RAID_50_SUPPORT) { printf("%s RAID50", comma ? "," : ""); comma = 1; } if (!comma) printf(" none"); printf("\n"); free(ioc2); } else if ((IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_CONFIG_INVALID_PAGE) warnx("mpt_read_ioc_page(2): %s", mpt_ioc_status(IOCStatus)); ioc6 = mpt_read_ioc_page(fd, 6, &IOCStatus); if (ioc6 != NULL) { display_stripe_map(" RAID0 Stripes", ioc6->SupportedStripeSizeMapIS); display_stripe_map(" RAID1E Stripes", ioc6->SupportedStripeSizeMapIME); printf(" RAID0 Drives/Vol: %u", ioc6->MinDrivesIS); if (ioc6->MinDrivesIS != ioc6->MaxDrivesIS) printf("-%u", ioc6->MaxDrivesIS); printf("\n"); printf(" RAID1 Drives/Vol: %u", ioc6->MinDrivesIM); if (ioc6->MinDrivesIM != ioc6->MaxDrivesIM) printf("-%u", ioc6->MaxDrivesIM); printf("\n"); printf("RAID1E Drives/Vol: %u", ioc6->MinDrivesIME); if (ioc6->MinDrivesIME != ioc6->MaxDrivesIME) printf("-%u", ioc6->MaxDrivesIME); printf("\n"); free(ioc6); } else if ((IOCStatus & MPI_IOCSTATUS_MASK) != MPI_IOCSTATUS_CONFIG_INVALID_PAGE) warnx("mpt_read_ioc_page(6): %s", mpt_ioc_status(IOCStatus)); /* TODO: Add an ioctl to fetch IOC_FACTS and print firmware version. */ close(fd); return (0); }