From owner-svn-src-all@FreeBSD.ORG Tue Mar 30 11:46:44 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3AD5D106566C; Tue, 30 Mar 2010 11:46:44 +0000 (UTC) (envelope-from attilio@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 28B188FC13; Tue, 30 Mar 2010 11:46:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o2UBkiTK069162; Tue, 30 Mar 2010 11:46:44 GMT (envelope-from attilio@svn.freebsd.org) Received: (from attilio@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o2UBkiqH069160; Tue, 30 Mar 2010 11:46:44 GMT (envelope-from attilio@svn.freebsd.org) Message-Id: <201003301146.o2UBkiqH069160@svn.freebsd.org> From: Attilio Rao Date: Tue, 30 Mar 2010 11:46:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org X-SVN-Group: stable-8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r205876 - stable/8/sys/dev/aac X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 30 Mar 2010 11:46:44 -0000 Author: attilio Date: Tue Mar 30 11:46:43 2010 New Revision: 205876 URL: http://svn.freebsd.org/changeset/base/205876 Log: MFC r205160: Checkin a facility for specifying a passthrough FIB from userland. arcconf tool by Adaptec already seems to use for identifying the Serial Number of the devices. Sponsored by: Sandvine Incorporated Modified: stable/8/sys/dev/aac/aac.c Directory Properties: stable/8/sys/ (props changed) stable/8/sys/amd64/include/xen/ (props changed) stable/8/sys/cddl/contrib/opensolaris/ (props changed) stable/8/sys/contrib/dev/acpica/ (props changed) stable/8/sys/contrib/pf/ (props changed) stable/8/sys/dev/xen/xenpci/ (props changed) Modified: stable/8/sys/dev/aac/aac.c ============================================================================== --- stable/8/sys/dev/aac/aac.c Tue Mar 30 11:19:29 2010 (r205875) +++ stable/8/sys/dev/aac/aac.c Tue Mar 30 11:46:43 2010 (r205876) @@ -3063,7 +3063,147 @@ out: static int aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg) { - return (EINVAL); + struct aac_command *cm; + struct aac_event *event; + struct aac_fib *fib; + struct aac_srb *srbcmd, *user_srb; + struct aac_sg_entry *sge; + struct aac_sg_entry64 *sge64; + void *srb_sg_address, *ureply; + uint32_t fibsize, srb_sg_bytecount; + int error, transfer_data; + + fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, ""); + + cm = NULL; + transfer_data = 0; + fibsize = 0; + user_srb = (struct aac_srb *)arg; + + mtx_lock(&sc->aac_io_lock); + if (aac_alloc_command(sc, &cm)) { + event = malloc(sizeof(struct aac_event), M_AACBUF, + M_NOWAIT | M_ZERO); + if (event == NULL) { + error = EBUSY; + mtx_unlock(&sc->aac_io_lock); + goto out; + } + event->ev_type = AAC_EVENT_CMFREE; + event->ev_callback = aac_ioctl_event; + event->ev_arg = &cm; + aac_add_event(sc, event); + msleep(cm, &sc->aac_io_lock, 0, "aacraw", 0); + } + mtx_unlock(&sc->aac_io_lock); + + cm->cm_data = NULL; + fib = cm->cm_fib; + srbcmd = (struct aac_srb *)fib->data; + error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t)); + if (error != 0) + goto out; + if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) { + error = EINVAL; + goto out; + } + error = copyin(user_srb, srbcmd, fibsize); + if (error != 0) + goto out; + srbcmd->function = 0; + srbcmd->retry_limit = 0; + if (srbcmd->sg_map.SgCount > 1) { + error = EINVAL; + goto out; + } + + /* Retrieve correct SG entries. */ + if (fibsize == (sizeof(struct aac_srb) + + srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) { + sge = srbcmd->sg_map.SgEntry; + sge64 = NULL; + srb_sg_bytecount = sge->SgByteCount; +#ifdef __amd64__ + srb_sg_address = (void *)(uint64_t)sge->SgAddress; +#else + srb_sg_address = (void *)sge->SgAddress; +#endif + } +#ifdef __amd64__ + else if (fibsize == (sizeof(struct aac_srb) + + srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) { + sge = NULL; + sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry; + srb_sg_bytecount = sge64->SgByteCount; + srb_sg_address = (void *)sge64->SgAddress; + if (sge64->SgAddress > 0xffffffffull && + (sc->flags & AAC_FLAGS_SG_64BIT) == 0) { + error = EINVAL; + goto out; + } + } +#endif + else { + error = EINVAL; + goto out; + } + ureply = (char *)arg + fibsize; + srbcmd->data_len = srb_sg_bytecount; + if (srbcmd->sg_map.SgCount == 1) + transfer_data = 1; + + cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map; + if (transfer_data) { + cm->cm_datalen = srb_sg_bytecount; + cm->cm_data = malloc(cm->cm_datalen, M_AACBUF, M_NOWAIT); + if (cm->cm_data == NULL) { + error = ENOMEM; + goto out; + } + if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) + cm->cm_flags |= AAC_CMD_DATAIN; + if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) { + cm->cm_flags |= AAC_CMD_DATAOUT; + error = copyin(srb_sg_address, cm->cm_data, + cm->cm_datalen); + if (error != 0) + goto out; + } + } + + fib->Header.Size = sizeof(struct aac_fib_header) + + sizeof(struct aac_srb); + fib->Header.XferState = + AAC_FIBSTATE_HOSTOWNED | + AAC_FIBSTATE_INITIALISED | + AAC_FIBSTATE_EMPTY | + AAC_FIBSTATE_FROMHOST | + AAC_FIBSTATE_REXPECTED | + AAC_FIBSTATE_NORM | + AAC_FIBSTATE_ASYNC | + AAC_FIBSTATE_FAST_RESPONSE; + fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ? + ScsiPortCommandU64 : ScsiPortCommand; + + mtx_lock(&sc->aac_io_lock); + aac_wait_command(cm); + mtx_unlock(&sc->aac_io_lock); + + if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) { + error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen); + if (error != 0) + goto out; + } + error = copyout(fib->data, ureply, sizeof(struct aac_srb_response)); +out: + if (cm != NULL) { + if (cm->cm_data != NULL) + free(cm->cm_data, M_AACBUF); + mtx_lock(&sc->aac_io_lock); + aac_release_command(cm); + mtx_unlock(&sc->aac_io_lock); + } + return(error); } /*