From owner-p4-projects@FreeBSD.ORG Tue Dec 5 22:05:50 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id C323616A40F; Tue, 5 Dec 2006 22:05:49 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 7A43116A403 for ; Tue, 5 Dec 2006 22:05:49 +0000 (UTC) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.FreeBSD.org (Postfix) with ESMTP id E4A4243C9D for ; Tue, 5 Dec 2006 22:05:07 +0000 (GMT) (envelope-from mjacob@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.6/8.13.6) with ESMTP id kB5M5nZD092172 for ; Tue, 5 Dec 2006 22:05:49 GMT (envelope-from mjacob@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.6/8.13.4/Submit) id kB5M5mES092169 for perforce@freebsd.org; Tue, 5 Dec 2006 22:05:48 GMT (envelope-from mjacob@freebsd.org) Date: Tue, 5 Dec 2006 22:05:48 GMT Message-Id: <200612052205.kB5M5mES092169@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to mjacob@freebsd.org using -f From: Matt Jacob To: Perforce Change Reviews Cc: Subject: PERFORCE change 111162 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 05 Dec 2006 22:05:50 -0000 http://perforce.freebsd.org/chv.cgi?CH=111162 Change 111162 by mjacob@newisp on 2006/12/05 22:04:59 Begin another process of cleanup where we try to follow the Fusion spec a bit more closely and be a bit more generic in our endian cleanliness. Affected files ... .. //depot/projects/newisp/dev/mpt/mpt.c#6 edit .. //depot/projects/newisp/dev/mpt/mpt.h#8 edit .. //depot/projects/newisp/dev/mpt/mpt_cam.c#19 edit .. //depot/projects/newisp/dev/mpt/mpt_cam.h#2 edit .. //depot/projects/newisp/dev/mpt/mpt_debug.c#2 edit .. //depot/projects/newisp/dev/mpt/mpt_raid.c#6 edit Differences ... ==== //depot/projects/newisp/dev/mpt/mpt.c#6 (text+ko) ==== @@ -128,7 +128,7 @@ static int mpt_send_event_request(struct mpt_softc *mpt, int onoff); static int mpt_soft_reset(struct mpt_softc *mpt); static void mpt_hard_reset(struct mpt_softc *mpt); -static int mpt_configure_ioc(struct mpt_softc *mpt); +static int mpt_configure_ioc(struct mpt_softc *mpt, int, int); static int mpt_enable_ioc(struct mpt_softc *mpt, int); /************************* Personality Module Support *************************/ @@ -1484,25 +1484,27 @@ f_req.Function = MPI_FUNCTION_IOC_FACTS; f_req.MsgContext = htole32(MPT_REPLY_HANDLER_HANDSHAKE); error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req); - if (error) + if (error) { return(error); + } error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp); return (error); } static int -mpt_get_portfacts(struct mpt_softc *mpt, MSG_PORT_FACTS_REPLY *freplp) +mpt_get_portfacts(struct mpt_softc *mpt, U8 port, MSG_PORT_FACTS_REPLY *freplp) { MSG_PORT_FACTS f_req; int error; - /* XXX: Only getting PORT FACTS for Port 0 */ memset(&f_req, 0, sizeof f_req); f_req.Function = MPI_FUNCTION_PORT_FACTS; + f_req.PortNumber = port; f_req.MsgContext = htole32(MPT_REPLY_HANDLER_HANDSHAKE); error = mpt_send_handshake_cmd(mpt, sizeof f_req, &f_req); - if (error) + if (error) { return(error); + } error = mpt_recv_handshake_reply(mpt, sizeof (*freplp), freplp); return (error); } @@ -1523,8 +1525,8 @@ memset(&init, 0, sizeof init); init.WhoInit = who; init.Function = MPI_FUNCTION_IOC_INIT; - init.MaxDevices = mpt->mpt_max_devices; - init.MaxBuses = 1; + init.MaxDevices = 0; /* at least 256 devices per bus */ + init.MaxBuses = 16; /* at least 16 busses */ init.MsgVersion = htole16(MPI_VERSION); init.HeaderVersion = htole16(MPI_HEADER_VERSION); @@ -1759,17 +1761,10 @@ return (rv); } -#if __FreeBSD_version >= 500000 - mpt_lprt(mpt, MPT_PRT_DEBUG, "IOC Page 2 Header: ver %x, len %zx, " - "num %x, type %x\n", hdr.PageVersion, - hdr.PageLength * sizeof(uint32_t), - hdr.PageNumber, hdr.PageType); -#else - mpt_lprt(mpt, MPT_PRT_DEBUG, "IOC Page 2 Header: ver %x, len %z, " - "num %x, type %x\n", hdr.PageVersion, - hdr.PageLength * sizeof(uint32_t), - hdr.PageNumber, hdr.PageType); -#endif + mpt_lprt(mpt, MPT_PRT_DEBUG, + "IOC Page 2 Header: Version %x len %x PageNumber %x PageType %x\n", + hdr.PageVersion, hdr.PageLength << 2, + hdr.PageNumber, hdr.PageType); len = hdr.PageLength * sizeof(uint32_t); mpt->ioc_page2 = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); @@ -1786,6 +1781,7 @@ mpt_raid_free_mem(mpt); return (EIO); } + mpt2host_config_page_ioc2(mpt->ioc_page2); if (mpt->ioc_page2->CapabilitiesFlags != 0) { uint32_t mask; @@ -2107,11 +2103,8 @@ mpt_core_attach(struct mpt_softc *mpt) { int val; - int error; - LIST_INIT(&mpt->ack_frames); - /* Put all request buffers on the free list */ TAILQ_INIT(&mpt->request_pending_list); TAILQ_INIT(&mpt->request_free_list); @@ -2121,24 +2114,17 @@ req->state = REQ_STATE_ALLOCATED; mpt_free_request(mpt, req); } - for (val = 0; val < MPT_MAX_LUNS; val++) { STAILQ_INIT(&mpt->trt[val].atios); STAILQ_INIT(&mpt->trt[val].inots); } STAILQ_INIT(&mpt->trt_wildcard.atios); STAILQ_INIT(&mpt->trt_wildcard.inots); - mpt->scsi_tgt_handler_id = MPT_HANDLER_ID_NONE; - mpt_sysctl_attach(mpt); - mpt_lprt(mpt, MPT_PRT_DEBUG, "doorbell req = %s\n", mpt_ioc_diag(mpt_read(mpt, MPT_OFFSET_DOORBELL))); - - error = mpt_configure_ioc(mpt); - - return (error); + return (mpt_configure_ioc(mpt, 0, 0)); } int @@ -2197,6 +2183,9 @@ void mpt_core_detach(struct mpt_softc *mpt) { + /* + * XXX: FREE MEMORY + */ mpt_disable_ints(mpt); } @@ -2337,226 +2326,239 @@ * once at instance startup. */ static int -mpt_configure_ioc(struct mpt_softc *mpt) +mpt_configure_ioc(struct mpt_softc *mpt, int tn, int needreset) { - MSG_PORT_FACTS_REPLY pfp; - MSG_IOC_FACTS_REPLY facts; - int try; - int needreset; - uint32_t max_chain_depth; + PTR_MSG_PORT_FACTS_REPLY pfp; + int error, port; + size_t len; - needreset = 0; - for (try = 0; try < MPT_MAX_TRYS; try++) { + if (tn == MPT_MAX_TRYS) { + return (-1); + } - /* - * No need to reset if the IOC is already in the READY state. - * - * Force reset if initialization failed previously. - * Note that a hard_reset of the second channel of a '929 - * will stop operation of the first channel. Hopefully, if the - * first channel is ok, the second will not require a hard - * reset. - */ - if (needreset || MPT_STATE(mpt_rd_db(mpt)) != - MPT_DB_STATE_READY) { - if (mpt_reset(mpt, FALSE) != MPT_OK) { - continue; - } + /* + * No need to reset if the IOC is already in the READY state. + * + * Force reset if initialization failed previously. + * Note that a hard_reset of the second channel of a '929 + * will stop operation of the first channel. Hopefully, if the + * first channel is ok, the second will not require a hard + * reset. + */ + if (needreset || MPT_STATE(mpt_rd_db(mpt)) != MPT_DB_STATE_READY) { + if (mpt_reset(mpt, FALSE) != MPT_OK) { + return (mpt_configure_ioc(mpt, tn++, 1)); } needreset = 0; + } - if (mpt_get_iocfacts(mpt, &facts) != MPT_OK) { - mpt_prt(mpt, "mpt_get_iocfacts failed\n"); - needreset = 1; - continue; - } + if (mpt_get_iocfacts(mpt, &mpt->ioc_facts) != MPT_OK) { + mpt_prt(mpt, "mpt_get_iocfacts failed\n"); + return (mpt_configure_ioc(mpt, tn++, 1)); + } + mpt2host_iocfacts_reply(&mpt->ioc_facts); - mpt->mpt_global_credits = le16toh(facts.GlobalCredits); - mpt->request_frame_size = le16toh(facts.RequestFrameSize); - mpt->ioc_facts_flags = facts.Flags; - mpt_prt(mpt, "MPI Version=%d.%d.%d.%d\n", - le16toh(facts.MsgVersion) >> 8, - le16toh(facts.MsgVersion) & 0xFF, - le16toh(facts.HeaderVersion) >> 8, - le16toh(facts.HeaderVersion) & 0xFF); + mpt_prt(mpt, "MPI Version=%d.%d.%d.%d\n", + mpt->ioc_facts.MsgVersion >> 8, + mpt->ioc_facts.MsgVersion & 0xFF, + mpt->ioc_facts.HeaderVersion >> 8, + mpt->ioc_facts.HeaderVersion & 0xFF); - /* - * Now that we know request frame size, we can calculate - * the actual (reasonable) segment limit for read/write I/O. - * - * This limit is constrained by: - * - * + The size of each area we allocate per command (and how - * many chain segments we can fit into it). - * + The total number of areas we've set up. - * + The actual chain depth the card will allow. - * - * The first area's segment count is limited by the I/O request - * at the head of it. We cannot allocate realistically more - * than MPT_MAX_REQUESTS areas. Therefore, to account for both - * conditions, we'll just start out with MPT_MAX_REQUESTS-2. - * - */ - max_chain_depth = facts.MaxChainDepth; + /* + * Now that we know request frame size, we can calculate + * the actual (reasonable) segment limit for read/write I/O. + * + * This limit is constrained by: + * + * + The size of each area we allocate per command (and how + * many chain segments we can fit into it). + * + The total number of areas we've set up. + * + The actual chain depth the card will allow. + * + * The first area's segment count is limited by the I/O request + * at the head of it. We cannot allocate realistically more + * than MPT_MAX_REQUESTS areas. Therefore, to account for both + * conditions, we'll just start out with MPT_MAX_REQUESTS-2. + * + */ + /* total number of request areas we (can) allocate */ + mpt->max_seg_cnt = MPT_MAX_REQUESTS(mpt) - 2; - /* total number of request areas we (can) allocate */ - mpt->max_seg_cnt = MPT_MAX_REQUESTS(mpt) - 2; + /* converted to the number of chain areas possible */ + mpt->max_seg_cnt *= MPT_NRFM(mpt); - /* converted to the number of chain areas possible */ - mpt->max_seg_cnt *= MPT_NRFM(mpt); + /* limited by the number of chain areas the card will support */ + if (mpt->max_seg_cnt > mpt->ioc_facts.MaxChainDepth) { + mpt_lprt(mpt, MPT_PRT_DEBUG, + "chain depth limited to %u (from %u)\n", + mpt->ioc_facts.MaxChainDepth, mpt->max_seg_cnt); + mpt->max_seg_cnt = mpt->ioc_facts.MaxChainDepth; + } - /* limited by the number of chain areas the card will support */ - if (mpt->max_seg_cnt > max_chain_depth) { - mpt_lprt(mpt, MPT_PRT_DEBUG, - "chain depth limited to %u (from %u)\n", - max_chain_depth, mpt->max_seg_cnt); - mpt->max_seg_cnt = max_chain_depth; - } + /* converted to the number of simple sges in chain segments. */ + mpt->max_seg_cnt *= (MPT_NSGL(mpt) - 1); - /* converted to the number of simple sges in chain segments. */ - mpt->max_seg_cnt *= (MPT_NSGL(mpt) - 1); + mpt_lprt(mpt, MPT_PRT_DEBUG, "Maximum Segment Count: %u\n", + mpt->max_seg_cnt); + mpt_lprt(mpt, MPT_PRT_DEBUG, "MsgLength=%u IOCNumber = %d\n", + mpt->ioc_facts.MsgLength, mpt->ioc_facts.IOCNumber); + mpt_lprt(mpt, MPT_PRT_DEBUG, + "IOCFACTS: GlobalCredits=%d BlockSize=%u bytes " + "Request Frame Size %u bytes Max Chain Depth %u\n", + mpt->ioc_facts.GlobalCredits, mpt->ioc_facts.BlockSize, + mpt->ioc_facts.RequestFrameSize << 2, + mpt->ioc_facts.MaxChainDepth); + mpt_lprt(mpt, MPT_PRT_DEBUG, "IOCFACTS: Num Ports %d, FWImageSize %d, " + "Flags=%#x\n", mpt->ioc_facts.NumberOfPorts, + mpt->ioc_facts.FWImageSize, mpt->ioc_facts.Flags); - mpt_lprt(mpt, MPT_PRT_DEBUG, - "Maximum Segment Count: %u\n", mpt->max_seg_cnt); - mpt_lprt(mpt, MPT_PRT_DEBUG, - "MsgLength=%u IOCNumber = %d\n", - facts.MsgLength, facts.IOCNumber); - mpt_lprt(mpt, MPT_PRT_DEBUG, - "IOCFACTS: GlobalCredits=%d BlockSize=%u bytes " - "Request Frame Size %u bytes Max Chain Depth %u\n", - mpt->mpt_global_credits, facts.BlockSize, - mpt->request_frame_size << 2, max_chain_depth); - mpt_lprt(mpt, MPT_PRT_DEBUG, - "IOCFACTS: Num Ports %d, FWImageSize %d, " - "Flags=%#x\n", facts.NumberOfPorts, - le32toh(facts.FWImageSize), facts.Flags); + len = mpt->ioc_facts.NumberOfPorts * sizeof (MSG_PORT_FACTS_REPLY); + mpt->port_facts = malloc(len, M_DEVBUF, M_NOWAIT | M_ZERO); + if (mpt->port_facts == NULL) { + mpt_prt(mpt, "unable to allocate memory for port facts\n"); + return (ENOMEM); + } - if ((facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) != 0) { - struct mpt_map_info mi; - int error; + if ((mpt->ioc_facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) && + (mpt->fw_uploaded == 0)) { + struct mpt_map_info mi; - /* - * In some configurations, the IOC's firmware is - * stored in a shared piece of system NVRAM that - * is only accessable via the BIOS. In this - * case, the firmware keeps a copy of firmware in - * RAM until the OS driver retrieves it. Once - * retrieved, we are responsible for re-downloading - * the firmware after any hard-reset. - */ - mpt->fw_image_size = le32toh(facts.FWImageSize); - error = mpt_dma_tag_create(mpt, mpt->parent_dmat, - /*alignment*/1, /*boundary*/0, - /*lowaddr*/BUS_SPACE_MAXADDR_32BIT, - /*highaddr*/BUS_SPACE_MAXADDR, /*filter*/NULL, - /*filterarg*/NULL, mpt->fw_image_size, - /*nsegments*/1, /*maxsegsz*/mpt->fw_image_size, - /*flags*/0, &mpt->fw_dmat); - if (error != 0) { - mpt_prt(mpt, "cannot create fw dma tag\n"); - return (ENOMEM); - } - error = bus_dmamem_alloc(mpt->fw_dmat, - (void **)&mpt->fw_image, BUS_DMA_NOWAIT, - &mpt->fw_dmap); - if (error != 0) { - mpt_prt(mpt, "cannot allocate fw mem.\n"); - bus_dma_tag_destroy(mpt->fw_dmat); - return (ENOMEM); - } - mi.mpt = mpt; - mi.error = 0; - bus_dmamap_load(mpt->fw_dmat, mpt->fw_dmap, - mpt->fw_image, mpt->fw_image_size, mpt_map_rquest, - &mi, 0); - mpt->fw_phys = mi.phys; - - error = mpt_upload_fw(mpt); - if (error != 0) { - mpt_prt(mpt, "fw upload failed.\n"); - bus_dmamap_unload(mpt->fw_dmat, mpt->fw_dmap); - bus_dmamem_free(mpt->fw_dmat, mpt->fw_image, - mpt->fw_dmap); - bus_dma_tag_destroy(mpt->fw_dmat); - mpt->fw_image = NULL; - return (EIO); - } + /* + * In some configurations, the IOC's firmware is + * stored in a shared piece of system NVRAM that + * is only accessable via the BIOS. In this + * case, the firmware keeps a copy of firmware in + * RAM until the OS driver retrieves it. Once + * retrieved, we are responsible for re-downloading + * the firmware after any hard-reset. + */ + mpt->fw_image_size = mpt->ioc_facts.FWImageSize; + error = mpt_dma_tag_create(mpt, mpt->parent_dmat, 1, 0, + BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, + mpt->fw_image_size, 1, mpt->fw_image_size, 0, + &mpt->fw_dmat); + if (error != 0) { + mpt_prt(mpt, "cannot create firmwarew dma tag\n"); + return (ENOMEM); + } + error = bus_dmamem_alloc(mpt->fw_dmat, + (void **)&mpt->fw_image, BUS_DMA_NOWAIT, &mpt->fw_dmap); + if (error != 0) { + mpt_prt(mpt, "cannot allocate firmware memory\n"); + bus_dma_tag_destroy(mpt->fw_dmat); + return (ENOMEM); } + mi.mpt = mpt; + mi.error = 0; + bus_dmamap_load(mpt->fw_dmat, mpt->fw_dmap, + mpt->fw_image, mpt->fw_image_size, mpt_map_rquest, &mi, 0); + mpt->fw_phys = mi.phys; - if (mpt_get_portfacts(mpt, &pfp) != MPT_OK) { - mpt_prt(mpt, "mpt_get_portfacts failed\n"); - needreset = 1; - continue; + error = mpt_upload_fw(mpt); + if (error != 0) { + mpt_prt(mpt, "firmware upload failed.\n"); + bus_dmamap_unload(mpt->fw_dmat, mpt->fw_dmap); + bus_dmamem_free(mpt->fw_dmat, mpt->fw_image, + mpt->fw_dmap); + bus_dma_tag_destroy(mpt->fw_dmat); + mpt->fw_image = NULL; + return (EIO); } + mpt->fw_uploaded = 1; + } - mpt_lprt(mpt, MPT_PRT_DEBUG, - "PORTFACTS: Type %x PFlags %x IID %d MaxDev %d\n", - pfp.PortType, pfp.ProtocolFlags, pfp.PortSCSIID, - pfp.MaxDevices); - - mpt->mpt_port_type = pfp.PortType; - mpt->mpt_proto_flags = le16toh(pfp.ProtocolFlags); - if (pfp.PortType != MPI_PORTFACTS_PORTTYPE_SCSI && - pfp.PortType != MPI_PORTFACTS_PORTTYPE_SAS && - pfp.PortType != MPI_PORTFACTS_PORTTYPE_FC) { - mpt_prt(mpt, "Unsupported Port Type (%x)\n", - pfp.PortType); - return (ENXIO); + for (port = 0; port < mpt->ioc_facts.NumberOfPorts; port++) { + pfp = &mpt->port_facts[port]; + error = mpt_get_portfacts(mpt, 0, pfp); + if (error != MPT_OK) { + mpt_prt(mpt, + "mpt_get_portfacts on port %d failed\n", port); + free(mpt->port_facts, M_DEVBUF); + mpt->port_facts = NULL; + return (mpt_configure_ioc(mpt, tn++, 1)); } - mpt->mpt_max_tgtcmds = le16toh(pfp.MaxPostedCmdBuffers); + mpt2host_portfacts_reply(pfp); - if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_FC) { - mpt->is_fc = 1; - mpt->is_sas = 0; - mpt->is_spi = 0; - } else if (pfp.PortType == MPI_PORTFACTS_PORTTYPE_SAS) { - mpt->is_fc = 0; - mpt->is_sas = 1; - mpt->is_spi = 0; + if (port > 0) { + error = MPT_PRT_INFO; } else { - mpt->is_fc = 0; - mpt->is_sas = 0; - mpt->is_spi = 1; + error = MPT_PRT_DEBUG; } - mpt->mpt_ini_id = pfp.PortSCSIID; - mpt->mpt_max_devices = pfp.MaxDevices; + mpt_lprt(mpt, error, + "PORTFACTS[%d]: Type %x PFlags %x IID %d MaxDev %d\n", + port, pfp->PortType, pfp->ProtocolFlags, pfp->PortSCSIID, + pfp->MaxDevices); + + } + + /* + * XXX: Not yet supporting more than port 0 + */ + pfp = &mpt->port_facts[0]; + if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_FC) { + mpt->is_fc = 1; + mpt->is_sas = 0; + mpt->is_spi = 0; + } else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_SAS) { + mpt->is_fc = 0; + mpt->is_sas = 1; + mpt->is_spi = 0; + } else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_SCSI) { + mpt->is_fc = 0; + mpt->is_sas = 0; + mpt->is_spi = 1; + } else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_ISCSI) { + mpt_prt(mpt, "iSCSI not supported yet\n"); + return (ENXIO); + } else if (pfp->PortType == MPI_PORTFACTS_PORTTYPE_INACTIVE) { + mpt_prt(mpt, "Inactive Port\n"); + return (ENXIO); + } else { + mpt_prt(mpt, "unknown Port Type %#x\n", pfp->PortType); + return (ENXIO); + } - /* - * Set our role with what this port supports. - * - * Note this might be changed later in different modules - * if this is different from what is wanted. - */ - mpt->role = MPT_ROLE_NONE; - if (mpt->mpt_proto_flags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { - mpt->role |= MPT_ROLE_INITIATOR; - } - if (mpt->mpt_proto_flags & MPI_PORTFACTS_PROTOCOL_TARGET) { - mpt->role |= MPT_ROLE_TARGET; - } - if (mpt_enable_ioc(mpt, 0) != MPT_OK) { - mpt_prt(mpt, "unable to initialize IOC\n"); - return (ENXIO); - } + if (pfp->ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LAN) { + mpt_prt(mpt, "not supporting LAN protocol\n"); + return (ENXIO); + } - /* - * Read IOC configuration information. - * - * We need this to determine whether or not we have certain - * settings for Integrated Mirroring (e.g.). - */ - mpt_read_config_info_ioc(mpt); + if (pfp->ProtocolFlags & MPI_PORTFACTS_PROTOCOL_LOGBUSADDR) { + mpt_prt(mpt, "not supporting Logical Bus Address protocol\n"); + return (ENXIO); + } - /* Everything worked */ - break; + /* + * Set our role with what this port supports. + * + * Note this might be changed later in different modules + * if this is different from what is wanted. + */ + mpt->role = MPT_ROLE_NONE; + if (pfp->ProtocolFlags & MPI_PORTFACTS_PROTOCOL_INITIATOR) { + mpt->role |= MPT_ROLE_INITIATOR; + } + if (pfp->ProtocolFlags & MPI_PORTFACTS_PROTOCOL_TARGET) { + mpt->role |= MPT_ROLE_TARGET; } - if (try >= MPT_MAX_TRYS) { - mpt_prt(mpt, "failed to initialize IOC"); - return (EIO); + /* + * Enable the IOC + */ + if (mpt_enable_ioc(mpt, 0) != MPT_OK) { + mpt_prt(mpt, "unable to initialize IOC\n"); + return (ENXIO); } + /* + * Read IOC configuration information. + * + * We need this to determine whether or not we have certain + * settings for Integrated Mirroring (e.g.). + */ + mpt_read_config_info_ioc(mpt); + return (0); } @@ -2588,7 +2590,7 @@ (pptr + MPT_REPLY_SIZE) < (mpt->reply_phys + PAGE_SIZE); pptr += MPT_REPLY_SIZE) { mpt_free_reply(mpt, pptr); - if (++val == mpt->mpt_global_credits - 1) + if (++val == mpt->ioc_facts.GlobalCredits - 1) break; } @@ -2610,3 +2612,92 @@ } return (MPT_OK); } + +/* + * Endian Conversion Functions- only used on Big Endian machines + */ +#if _BYTE_ORDER == _BIG_ENDIAN +void +mpt2host_sge_simple_union(SGE_SIMPLE_UNION *sge) +{ + MPT_2_HOST32(sge, FlagsLength); + MPT_2_HOST64(sge, u.Address64); +}; + +void +mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *rp) +{ + MPT_2_HOST16(rp, MsgVersion); + MPT_2_HOST16(rp, HeaderVersion); + MPT_2_HOST32(rp, MsgContext); + MPT_2_HOST16(rp, IOCExceptions); + MPT_2_HOST16(rp, IOCStatus); + MPT_2_HOST32(rp, IOCLogInfo); + MPT_2_HOST16(rp, ReplyQueueDepth); + MPT_2_HOST16(rp, RequestFrameSize); + MPT_2_HOST16(rp, Reserved_0101_FWVersion); + MPT_2_HOST16(rp, ProductID); + MPT_2_HOST32(rp, CurrentHostMfaHighAddr); + MPT_2_HOST16(rp, GlobalCredits); + MPT_2_HOST32(rp, CurrentSenseBufferHighAddr); + MPT_2_HOST16(rp, CurReplyFrameSize); + MPT_2_HOST32(rp, FWImageSize); + MPT_2_HOST32(rp, IOCCapabilities); + MPT_2_HOST32(rp, FWVersion.Word); + MPT_2_HOST16(rp, HighPriorityQueueDepth); + MPT_2_HOST16(rp, Reserved2); + mpt2host_sge_simple_union(&rp->HostPageBufferSGE); + MPT_2_HOST32(rp, ReplyFifoHostSignalingAddr); +} + +void +mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *pfp) +{ + MPT_2_HOST16(pfp, Reserved); + MPT_2_HOST16(pfp, Reserved1); + MPT_2_HOST32(pfp, MsgContext); + MPT_2_HOST16(pfp, Reserved2); + MPT_2_HOST16(pfp, IOCStatus); + MPT_2_HOST32(pfp, IOCLogInfo); + MPT_2_HOST16(pfp, MaxDevices); + MPT_2_HOST16(pfp, PortSCSIID); + MPT_2_HOST16(pfp, ProtocolFlags); + MPT_2_HOST16(pfp, MaxPostedCmdBuffers); + MPT_2_HOST16(pfp, MaxPersistentIDs); + MPT_2_HOST16(pfp, MaxLanBuckets); + MPT_2_HOST16(pfp, Reserved4); + MPT_2_HOST32(pfp, Reserved5); +} +void +mpt2host_config_page_ioc2(CONFIG_PAGE_IOC_2 *ioc2) +{ + int i; + ioc2->CapabilitiesFlags = htole32(ioc2->CapabilitiesFlags); + for (i = 0; i < MPI_IOC_PAGE_2_RAID_VOLUME_MAX; i++) { + MPT_2_HOST16(ioc2->RaidVolume[i].Reserved3); + } +} + +void +mpt2host_config_page_raid_vol_0(CONFIG_PAGE_RAID_VOL_0 *volp) +{ + int i; + MPT_2_HOST16(volp, VolumeStatus.Reserved); + MPT_2_HOST16(volp, VolumeSettings.Settings); + MPT_2_HOST32(volp, MaxLBA); + MPT_2_HOST32(volp, Reserved1); + MPT_2_HOST32(volp, StripeSize); + MPT_2_HOST32(volp, Reserved2); + MPT_2_HOST32(volp, Reserved3); + for (i = 0; i < MPI_RAID_VOL_PAGE_0_PHYSDISK_MAX; i++) { + MPT_2_HOST16(volpd, PhysDisk[i].Reserved); + } +} + +void +mpt2host_mpi_raid_vol_indicator(MPI_RAID_VOL_INDICATOR *vi) +{ + MPT_2_HOST16(vi, TotalBlocks); + MPT_2_HOST16(vi, BlocksRemaining); +} +#endif ==== //depot/projects/newisp/dev/mpt/mpt.h#8 (text+ko) ==== @@ -155,6 +155,9 @@ /* XXX For mpt_debug.c */ #include +#define MPT_S64_2_SCALAR(y) ((((int64_t)y.High) << 32) | (y.Low)) +#define MPT_U64_2_SCALAR(y) ((((uint64_t)y.High) << 32) | (y.Low)) + /****************************** Misc Definitions ******************************/ #define MPT_OK (0) #define MPT_FAIL (0x10000) @@ -272,15 +275,29 @@ #endif /********************************** Endianess *********************************/ -static __inline uint64_t -u64toh(U64 s) -{ - uint64_t result; +#define MPT_2_HOST64(ptr, tag) ptr->tag = le64toh(ptr->tag) +#define MPT_2_HOST32(ptr, tag) ptr->tag = le32toh(ptr->tag) +#define MPT_2_HOST16(ptr, tag) ptr->tag = le16toh(ptr->tag) + +#define HOST_2_MPT64(ptr, tag) ptr->tag = htole64(ptr->tag) +#define HOST_2_MPT32(ptr, tag) ptr->tag = htole32(ptr->tag) +#define HOST_2_MPT16(ptr, tag) ptr->tag = htole16(ptr->tag) - result = le32toh(s.Low); - result |= ((uint64_t)le32toh(s.High)) << 32; - return (result); -} +#if _BYTE_ORDER == _LITTLE_ENDIAN +#define mpt2host_sge_simple_union(x) do { ; } while (0) +#define mpt2host_iocfacts_reply(x) do { ; } while (0) +#define mpt2host_portfacts_reply(x) do { ; } while (0) +#define mpt2host_config_page_ioc2(x) do { ; } while (0) +#define mpt2host_config_page_raid_vol_0(x) do { ; } while (0) +#define mpt2host_mpi_raid_vol_indicator(x) do { ; } while (0) +#else +void mpt2host_sge_simple_union(SGE_SIMPLE_UNION *); +void mpt2host_iocfacts_reply(MSG_IOC_FACTS_REPLY *); +void mpt2host_portfacts_reply(MSG_PORT_FACTS_REPLY *); +void mpt2host_config_page_ioc2(CONFIG_PAGE_IOC_2 *); +void mpt2host_config_page_raid_vol_0(CONFIG_PAGE_RAID_VOL_0 *); +void mpt2host_mpi_raid_vol_indicator(MPI_RAID_VOL_INDICATOR *); +#endif /**************************** MPI Transaction State ***************************/ typedef enum { @@ -495,8 +512,10 @@ #endif uint32_t mpt_pers_mask; uint32_t + : 8, unit : 8, - : 2, + : 1, + fw_uploaded : 1, msi_enable : 1, twildcard : 1, tenabled : 1, @@ -520,20 +539,14 @@ /* * IOC Facts */ - uint16_t mpt_global_credits; - uint16_t request_frame_size; - uint16_t mpt_max_devices; - uint8_t mpt_max_buses; - uint8_t ioc_facts_flags; + MSG_IOC_FACTS_REPLY ioc_facts; /* * Port Facts - * XXX - Add multi-port support!. */ - uint16_t mpt_ini_id; - uint16_t mpt_port_type; - uint16_t mpt_proto_flags; - uint16_t mpt_max_tgtcmds; + MSG_PORT_FACTS_REPLY * port_facts; +#define mpt_ini_id port_facts[0].PortSCSIID +#define mpt_max_tgtcmds port_facts[0].MaxPostedCmdBuffers /* * Device Configuration Information @@ -930,7 +943,7 @@ /************************** Scatter Gather Managment **************************/ /* MPT_RQSL- size of request frame, in bytes */ -#define MPT_RQSL(mpt) (mpt->request_frame_size << 2) +#define MPT_RQSL(mpt) (mpt->ioc_facts.RequestFrameSize << 2) /* MPT_NSGL- how many SG entries can fit in a request frame size */ #define MPT_NSGL(mpt) (MPT_RQSL(mpt) / sizeof (SGE_IO_UNION)) ==== //depot/projects/newisp/dev/mpt/mpt_cam.c#19 (text+ko) ==== @@ -211,8 +211,8 @@ int error; TAILQ_INIT(&mpt->request_timeout_list); - maxq = (mpt->mpt_global_credits < MPT_MAX_REQUESTS(mpt))? - mpt->mpt_global_credits : MPT_MAX_REQUESTS(mpt); + maxq = (mpt->ioc_facts.GlobalCredits < MPT_MAX_REQUESTS(mpt))? + mpt->ioc_facts.GlobalCredits : MPT_MAX_REQUESTS(mpt); handler.reply_handler = mpt_scsi_reply_handler; error = mpt_register_handler(mpt, MPT_HANDLER_REPLY, handler, @@ -3136,7 +3136,7 @@ cpi->version_num = 1; cpi->target_sprt = 0; cpi->hba_eng_cnt = 0; - cpi->max_target = mpt->mpt_max_devices - 1; + cpi->max_target = mpt->port_facts[0].MaxDevices - 1; /* * FC cards report MAX_DEVICES of 512, but * the MSG_SCSI_IO_REQUEST target id field ==== //depot/projects/newisp/dev/mpt/mpt_cam.h#2 (text+ko) ==== ==== //depot/projects/newisp/dev/mpt/mpt_debug.c#2 (text+ko) ==== @@ -819,7 +819,7 @@ mpt_dump_request(struct mpt_softc *mpt, request_t *req) { uint32_t *pReq = req->req_vbuf; - int offset; + int o; #if __FreeBSD_version >= 500000 mpt_prt(mpt, "Send Request %d (%jx):", req->index, (uintmax_t) req->req_pbuf); @@ -827,12 +827,12 @@ mpt_prt(mpt, "Send Request %d (%llx):", req->index, (unsigned long long) req->req_pbuf); #endif - for (offset = 0; offset < mpt->request_frame_size; offset++) { - if ((offset & 0x7) == 0) { + for (o = 0; o < mpt->ioc_facts.RequestFrameSize; o++) { + if ((o & 0x7) == 0) { mpt_prtc(mpt, "\n"); mpt_prt(mpt, " "); } - mpt_prtc(mpt, " %08x", pReq[offset]); + mpt_prtc(mpt, " %08x", pReq[o]); } mpt_prtc(mpt, "\n"); } ==== //depot/projects/newisp/dev/mpt/mpt_raid.c#6 (text+ko) ==== @@ -1229,7 +1229,7 @@ static void mpt_refresh_raid_vol(struct mpt_softc *mpt, struct mpt_raid_volume *mpt_vol, - CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol) + CONFIG_PAGE_IOC_2_RAID_VOL *ioc_vol) { CONFIG_PAGE_RAID_VOL_0 *vol_pg; struct mpt_raid_action_result *ar; @@ -1239,31 +1239,31 @@ vol_pg = mpt_vol->config_page; mpt_vol->flags &= ~MPT_RVF_UP2DATE; - rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_VOLUME, - /*PageNumber*/0, ioc_vol->VolumePageNumber, - &vol_pg->Header, /*sleep_ok*/TRUE, - /*timeout_ms*/5000); + + rv = mpt_read_cfg_header(mpt, MPI_CONFIG_PAGETYPE_RAID_VOLUME, 0, + ioc_vol->VolumePageNumber, &vol_pg->Header, TRUE, 5000); if (rv != 0) { - mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: " - "Failed to read RAID Vol Hdr(%d)\n", - ioc_vol->VolumePageNumber); + mpt_vol_prt(mpt, mpt_vol, + "mpt_refresh_raid_vol: Failed to read RAID Vol Hdr(%d)\n", + ioc_vol->VolumePageNumber); return; } + rv = mpt_read_cur_cfg_page(mpt, ioc_vol->VolumePageNumber, - &vol_pg->Header, mpt->raid_page0_len, - /*sleep_ok*/TRUE, /*timeout_ms*/5000); + &vol_pg->Header, mpt->raid_page0_len, TRUE, 5000); if (rv != 0) { - mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: " - "Failed to read RAID Vol Page(%d)\n", - ioc_vol->VolumePageNumber); + mpt_vol_prt(mpt, mpt_vol, + "mpt_refresh_raid_vol: Failed to read RAID Vol Page(%d)\n", + ioc_vol->VolumePageNumber); return; } + mpt2host_config_page_raid_vol_0(vol_pg); + mpt_vol->flags |= MPT_RVF_ACTIVE; /* Update disk entry array data. */ for (i = 0; i < vol_pg->NumPhysDisks; i++) { struct mpt_raid_disk *mpt_disk; - mpt_disk = mpt->raid_disks + vol_pg->PhysDisk[i].PhysDiskNum; mpt_disk->volume = mpt_vol; mpt_disk->member_number = vol_pg->PhysDisk[i].PhysDiskMap; @@ -1276,19 +1276,18 @@ & MPI_RAIDVOL0_STATUS_FLAG_RESYNC_IN_PROGRESS) == 0) return; - req = mpt_get_request(mpt, /*sleep_ok*/TRUE); + req = mpt_get_request(mpt, TRUE); if (req == NULL) { mpt_vol_prt(mpt, mpt_vol, - "mpt_refresh_raid_vol: Get request failed!\n"); + "mpt_refresh_raid_vol: Get request failed!\n"); return; } - rv = mpt_issue_raid_req(mpt, mpt_vol, /*disk*/NULL, req, - MPI_RAID_ACTION_INDICATOR_STRUCT, - /*ActionWord*/0, /*addr*/0, /*len*/0, - /*write*/FALSE, /*wait*/TRUE); + rv = mpt_issue_raid_req(mpt, mpt_vol, NULL, req, + MPI_RAID_ACTION_INDICATOR_STRUCT, 0, 0, 0, FALSE, TRUE); if (rv == ETIMEDOUT) { - mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: " - "Progress indicator fetch timedout!\n"); + mpt_vol_prt(mpt, mpt_vol, + "mpt_refresh_raid_vol: Progress Indicator fetch timeout\n"); + mpt_free_request(mpt, req); return; } @@ -1299,9 +1298,10 @@ memcpy(&mpt_vol->sync_progress, &ar->action_data.indicator_struct, sizeof(mpt_vol->sync_progress)); + mpt2host_mpi_raid_vol_indicator(&mpt_vol->sync_progress); } else { - mpt_vol_prt(mpt, mpt_vol, "mpt_refresh_raid_vol: " - "Progress indicator fetch failed!\n"); + mpt_vol_prt(mpt, mpt_vol, + "mpt_refresh_raid_vol: Progress indicator fetch failed!\n"); } mpt_free_request(mpt, req); } @@ -1414,8 +1414,9 @@ mpt_vol = &mpt->raid_volumes[i]; - if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) + if ((mpt_vol->flags & MPT_RVF_ACTIVE) == 0) { continue; + } vol_pg = mpt_vol->config_page; if ((mpt_vol->flags & (MPT_RVF_REFERENCED|MPT_RVF_ANNOUNCED)) @@ -1426,7 +1427,6 @@ } if ((mpt_vol->flags & MPT_RVF_ANNOUNCED) == 0) { - mpt_announce_vol(mpt, mpt_vol); mpt_vol->flags |= MPT_RVF_ANNOUNCED; } @@ -1440,11 +1440,12 @@ mpt_vol->flags |= MPT_RVF_UP2DATE; mpt_vol_prt(mpt, mpt_vol, "%s - %s\n", - mpt_vol_type(mpt_vol), mpt_vol_state(mpt_vol)); + mpt_vol_type(mpt_vol), mpt_vol_state(mpt_vol)); mpt_verify_mwce(mpt, mpt_vol); - if (vol_pg->VolumeStatus.Flags == 0) + if (vol_pg->VolumeStatus.Flags == 0) { continue; + } mpt_vol_prt(mpt, mpt_vol, "Status ("); for (m = 1; m <= 0x80; m <<= 1) { @@ -1473,8 +1474,8 @@ mpt_verify_resync_rate(mpt, mpt_vol); - left = u64toh(mpt_vol->sync_progress.BlocksRemaining); - total = u64toh(mpt_vol->sync_progress.TotalBlocks); + left = MPT_U64_2_SCALAR(mpt_vol->sync_progress.BlocksRemaining); + total = MPT_U64_2_SCALAR(mpt_vol->sync_progress.TotalBlocks); if (vol_pg->ResyncRate != 0) { prio = ((u_int)vol_pg->ResyncRate * 100000) / 0xFF;